10 KiB
title, type, weight
| title | type | weight |
|---|---|---|
| Blocs | docs | 3 |
La manipulation des blocs est une partie centrale de la modification du monde dans les plugins Hytale. La classe World fournit l'accès aux blocs via l'interface IChunkAccessorSync, tandis que WorldChunk implémente l'interface complète BlockAccessor pour le placement avec rotation.
{{< callout type="warning" >}}
Important : World n'implémente PAS BlockAccessor directement. Pour placeBlock() avec rotation, vous devez d'abord obtenir le chunk avec world.getChunk().
{{< /callout >}}
Obtenir des Blocs
import com.hypixel.hytale.server.core.universe.Universe;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
import com.hypixel.hytale.math.vector.Vector3i;
World world = Universe.get().getWorld("default");
// Obtenir l'ID du bloc (index int) à une position
int blockId = world.getBlock(x, y, z);
int blockId = world.getBlock(new Vector3i(x, y, z));
// Obtenir le BlockType à une position
BlockType blockType = world.getBlockType(x, y, z);
BlockType blockType = world.getBlockType(new Vector3i(x, y, z));
// Vérifier si le bloc est vide
if (blockType == BlockType.EMPTY) {
// Air ou espace vide
}
Définir des Blocs
La méthode setBlock prend une clé de type bloc String, pas un objet BlockType ou un int ID :
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
World world = player.getWorld();
// Définir un bloc par clé de type (ID string)
world.setBlock(x, y, z, "stone");
world.setBlock(x, y, z, "oak_planks", 0); // avec settings
// Utiliser BlockType - obtenir d'abord la chaîne ID
BlockType stone = BlockType.getAssetMap().getAsset("stone");
if (stone != null) {
world.setBlock(x, y, z, stone.getId()); // Utiliser getId() pour obtenir la clé string
}
// Index d'ID de bloc (pour usage interne)
int stoneIndex = BlockType.getAssetMap().getIndex("stone");
// Note : setBlock prend String, pas int - utilisez la clé directement
Placement de Blocs avec Rotation
{{< callout type="info" >}} placeBlock() est sur WorldChunk, pas World ! Vous devez d'abord obtenir le chunk pour placer des blocs avec rotation. {{< /callout >}}
import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.Rotation;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.RotationTuple;
import com.hypixel.hytale.math.util.ChunkUtil;
// Obtenir le chunk contenant cette position de bloc
WorldChunk chunk = world.getChunk(ChunkUtil.indexChunkFromBlock(x, z));
if (chunk != null) {
// Placer un bloc avec rotation
// Valeurs de Rotation : None, Ninety, OneEighty, TwoSeventy
chunk.placeBlock(x, y, z, "oak_log",
Rotation.Ninety, // yaw (90 degrés)
Rotation.None, // pitch
Rotation.None // roll
);
// Placer avec tuple de rotation et options
chunk.placeBlock(x, y, z, "oak_log",
RotationTuple.of(Rotation.Ninety, Rotation.None, Rotation.None),
0, // settings
true // validatePlacement
);
}
Valeurs de Rotation
L'enum Rotation a ces valeurs (PAS les directions cardinales) :
| Rotation | Degrés |
|---|---|
Rotation.None |
0° |
Rotation.Ninety |
90° |
Rotation.OneEighty |
180° |
Rotation.TwoSeventy |
270° |
Casser des Blocs
// Casser un bloc à une position (nécessite le paramètre settings)
world.breakBlock(x, y, z, 0); // 0 = settings par défaut
Assets BlockType
Les assets BlockType définissent les propriétés des blocs :
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
import com.hypixel.hytale.protocol.BlockMaterial;
// Obtenir le type de bloc par ID
BlockType blockType = BlockType.getAssetMap().getAsset("stone");
if (blockType != null) {
// Obtenir la chaîne ID du bloc
String blockId = blockType.getId();
// Obtenir le matériau
BlockMaterial material = blockType.getMaterial();
}
// Obtenir l'index d'ID du bloc (pour usage interne)
int blockIndex = BlockType.getAssetMap().getIndex("stone");
// Obtenir le bloc depuis l'index
BlockType fromIndex = BlockType.getAssetMap().getAsset(blockIndex);
Événements de Blocs
BreakBlockEvent
Déclenché quand un bloc est cassé :
import com.hypixel.hytale.server.core.event.events.ecs.BreakBlockEvent;
import com.hypixel.hytale.math.vector.Vector3i;
import java.util.logging.Level;
getEventRegistry().register(BreakBlockEvent.class, event -> {
// Obtenir les infos de destruction
Vector3i position = event.getTargetBlock();
BlockType blockType = event.getBlockType();
getLogger().at(Level.INFO).log("Bloc cassé à " + position);
// Annuler si protégé
event.setCancelled(true);
});
PlaceBlockEvent
Déclenché quand un bloc est placé :
import com.hypixel.hytale.server.core.event.events.ecs.PlaceBlockEvent;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.RotationTuple;
getEventRegistry().register(PlaceBlockEvent.class, event -> {
// Obtenir les infos de placement
Vector3i position = event.getTargetBlock();
RotationTuple rotation = event.getRotation();
getLogger().at(Level.INFO).log("Bloc placé à " + position);
// Annuler si non autorisé
event.setCancelled(true);
});
DamageBlockEvent
Déclenché quand un bloc est endommagé (avant d'être cassé) :
import com.hypixel.hytale.server.core.event.events.ecs.DamageBlockEvent;
getEventRegistry().register(DamageBlockEvent.class, event -> {
Vector3i position = event.getTargetBlock();
BlockType blockType = event.getBlockType();
// Annuler pour empêcher les dégâts
event.setCancelled(true);
});
État d'Interaction de Bloc
Les blocs peuvent avoir des états d'interaction (comme portes ouvertes/fermées) :
BlockType currentBlock = world.getBlockType(x, y, z);
if (currentBlock != null) {
// Définir le bloc à un état différent
world.setBlockInteractionState(
new Vector3i(x, y, z),
currentBlock,
"open" // nom de l'état
);
}
Travailler avec les Blocs
Vérifier une Zone pour un Type de Bloc
public boolean containsBlockType(World world, Vector3i min, Vector3i max, String blockTypeKey) {
// Note : Vector3i utilise getX(), getY(), getZ() - PAS x(), y(), z()
for (int x = min.getX(); x <= max.getX(); x++) {
for (int y = min.getY(); y <= max.getY(); y++) {
for (int z = min.getZ(); z <= max.getZ(); z++) {
BlockType block = world.getBlockType(x, y, z);
if (block != null && block.getId().equals(blockTypeKey)) {
return true;
}
}
}
}
return false;
}
Remplir une Zone
public void fillArea(World world, Vector3i min, Vector3i max, String blockTypeKey) {
for (int x = min.getX(); x <= max.getX(); x++) {
for (int y = min.getY(); y <= max.getY(); y++) {
for (int z = min.getZ(); z <= max.getZ(); z++) {
world.setBlock(x, y, z, blockTypeKey);
}
}
}
}
Remplacer des Blocs
public void replaceBlocks(World world, Vector3i min, Vector3i max,
String fromBlock, String toBlock) {
for (int x = min.getX(); x <= max.getX(); x++) {
for (int y = min.getY(); y <= max.getY(); y++) {
for (int z = min.getZ(); z <= max.getZ(); z++) {
BlockType current = world.getBlockType(x, y, z);
if (current != null && current.getId().equals(fromBlock)) {
world.setBlock(x, y, z, toBlock);
}
}
}
}
}
Positions de Blocs
import com.hypixel.hytale.math.vector.Vector3i;
// Vector3i pour les positions de blocs entières
Vector3i blockPos = new Vector3i(100, 64, 200);
// Obtenir les coordonnées individuelles - utiliser getX(), getY(), getZ()
int x = blockPos.getX();
int y = blockPos.getY();
int z = blockPos.getZ();
// Positions adjacentes
Vector3i above = new Vector3i(x, y + 1, z);
Vector3i below = new Vector3i(x, y - 1, z);
Vector3i north = new Vector3i(x, y, z - 1);
Vector3i south = new Vector3i(x, y, z + 1);
Vector3i east = new Vector3i(x + 1, y, z);
Vector3i west = new Vector3i(x - 1, y, z);
Bonnes Pratiques
{{< callout type="info" >}} Conseils pour la Manipulation de Blocs :
- Les opérations sur les blocs doivent s'exécuter sur le thread de tick du monde
- Utilisez
getBlockType()pour vérifier les types,getBlock()pour les IDs bruts - Vérifiez
BlockType.EMPTYpour les blocs air/vides - Les événements étendent
CancellableEcsEvent- utilisezsetCancelled(true)pour empêcher - Considérez les limites de chunks lors du traitement de grandes zones
- Pour
placeBlock()avec rotation, obtenez d'abord le chunk {{< /callout >}}
// Modification sécurisée de bloc depuis un contexte asynchrone
world.execute(() -> {
world.setBlock(x, y, z, "stone");
});
Référence API
Méthodes World (IChunkAccessorSync)
| Méthode | Retour | Description |
|---|---|---|
getBlock(int, int, int) |
int |
Obtenir l'ID du bloc à la position |
getBlock(Vector3i) |
int |
Obtenir l'ID du bloc à la position |
getBlockType(int, int, int) |
BlockType? |
Obtenir le BlockType à la position |
getBlockType(Vector3i) |
BlockType? |
Obtenir le BlockType à la position |
setBlock(x, y, z, String) |
void |
Définir bloc par clé de type |
setBlock(x, y, z, String, int) |
void |
Définir bloc avec settings |
breakBlock(x, y, z, int) |
boolean |
Casser bloc avec settings |
setBlockInteractionState(...) |
void |
Définir état du bloc |
Méthodes WorldChunk (BlockAccessor)
| Méthode | Retour | Description |
|---|---|---|
placeBlock(x, y, z, String, Rotation, Rotation, Rotation) |
boolean |
Placer avec rotation |
placeBlock(x, y, z, String, RotationTuple, int, boolean) |
boolean |
Placer avec options |
testPlaceBlock(...) |
boolean |
Tester si placement valide |