Files
Documentation/content/world/blocks.fr.md
2026-01-20 20:33:59 +01:00

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
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.EMPTY pour les blocs air/vides
  • Les événements étendent CancellableEcsEvent - utilisez setCancelled(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