import { BlockVolume, Direction, EquipmentSlot, ItemStack, MolangVariableMap, system, world } from "@minecraft/server";
import { containsKeyword, damageItemStack, decrementStack, getBlockState, getCardinalDirection, getEnchantmentLevel, getPlayerEquipment, getRandomInt, getRandomStructureRotation, getRelativeBlock, getRelativeBlockInDirection, hasCommonTag, isHammer, isHoe, isPickaxe, isShears, isShovel, setBlockState, setCardinalDirection } from "nps_tbe/others/my_API";
import { onHammerMining, onPickaxeMining } from "../nps_tbe/newToolSystem";
class Trapdoor {
    static initialize(event) { event.blockComponentRegistry.registerCustomComponent(this.componentName, new this()); }
    onPlayerInteract(event) {
        const block = event.block;
        const dimension = event.dimension;
        const isOpen = block.permutation.getState("nps_tbe:open_bit");
        const sound = isOpen ? "close.wooden_trapdoor" : "open.wooden_trapdoor";
        block.setPermutation(block.permutation.withState("nps_tbe:open_bit", !isOpen));
        dimension.playSound(sound, block.center(), {
            pitch: 0.9,
            volume: 0.9,
        });
    }
}
Trapdoor.componentName = "nps_tbe:5fb961e8";
class FenceGate {
    static initialize(event) { event.blockComponentRegistry.registerCustomComponent(this.componentName, new this()); }
    onPlayerInteract(event) {
        const block = event.block;
        const dimension = event.dimension;
        const isOpen = block.permutation.getState("nps_tbe:open_bit");
        const sound = isOpen ? "close.fence_gate" : "open.fence_gate";
        block.setPermutation(block.permutation.withState("nps_tbe:open_bit", !isOpen));
        dimension.playSound(sound, block.center(), {
            pitch: 0.9,
            volume: 0.9,
        });
    }
    static afterPlayerPlaceBlock(event) {
        if (!this.isFenceGate(event.block))
            return;
        setBlockState(event.block, "nps_tbe:part", 1);
    }
    static isFenceGate(block) {
        if (!block)
            return false;
        return block.getTags().includes(FenceGate.componentName);
    }
}
FenceGate.componentName = "nps_tbe:66526b71";
class Door {
    static initialize(event) { event.blockComponentRegistry.registerCustomComponent(this.componentName, new this()); }
    static afterPlayerPlaceBlock(event) {
        if (!this.isDoor(event.block))
            return;
        Door.construct(event);
    }
    static isDoor(block) {
        if (!block)
            return false;
        return block.getTags().includes(Door.componentName);
    }
    onPlayerInteract(event) {
        const block = event.block;
        const dimension = event.dimension;
        const isOpen = getBlockState(block, "nps_tbe:open_bit");
        const sound = isOpen ? "close.wooden_door" : "open.wooden_door";
        dimension.playSound(sound, block.center(), {
            pitch: 0.9,
            volume: 0.9
        });
        const doorPart = getBlockState(block, "nps_tbe:part");
        const doorBlocks = doorPart == 1 ? [block, block.above()] : [block.below(), block];
        for (const doorBlock of doorBlocks) {
            setBlockState(doorBlock, "nps_tbe:open_bit", !isOpen);
        }
    }
    onPlayerDestroy(arg) {
        const block = arg.block;
        const doorPart = arg.destroyedBlockPermutation.getState("nps_tbe:part");
        const doorBlocks = doorPart == 1 ? [block, block.above()] : [block.below(), block];
        for (const doorBlock of doorBlocks) {
            doorBlock.setType("minecraft:air");
        }
    }
    static cancel(event) {
        const player = event.player;
        const block = event.block;
    }
    static construct(event) {
        const block = event.block;
        const canBePlaced = this.checkSpace(block);
        if (!canBePlaced) {
            this.cancel(event);
        }
        else {
            this.placeBlocks(event);
        }
    }
    static checkSpace(block) {
        const neighbour = block.above();
        if (neighbour == undefined || !neighbour.isAir || neighbour.isLiquid) {
            return false;
        }
        return true;
    }
    static placeBlocks(event) {
        const block = event.block;
        setBlockState(block, "nps_tbe:part", 1);
        const neighbour = block.above();
        const cardinalDirection = getCardinalDirection(block);
        neighbour.setType(block.typeId);
        setCardinalDirection(neighbour, cardinalDirection);
        setBlockState(neighbour, "nps_tbe:part", 2);
    }
}
Door.componentName = "nps_tbe:9edb3f9a";
class Fence {
    static initialize(event) { event.blockComponentRegistry.registerCustomComponent(this.componentName, new this()); }
    beforeOnPlayerPlace(arg) {
        Fence.updateConnections(arg, 2);
    }
    ;
    onPlace(arg) {
        Fence.updateBlock(arg.block, 2);
    }
    ;
    onPlayerDestroy(arg) {
        const directions = [Direction.North, Direction.East, Direction.South, Direction.West];
        for (const direction of directions) {
            const neighbor = getRelativeBlock(arg.block, Direction.North, direction);
            if (!neighbor) {
                continue;
            }
            if (!Fence.isFence(neighbor)) {
                continue;
            }
            Fence.updateBlock(neighbor, 1);
        }
    }
    ;
    static shouldConnectWith(neighbor) {
        return !neighbor?.isAir
            && !neighbor?.isLiquid
            && neighbor?.isValid()
            && !Fence.unconnectableBlocks.includes(neighbor.typeId)
            && !hasCommonTag(neighbor.getTags(), Fence.unconnectableTags)
            && !containsKeyword(neighbor.typeId, Fence.unconnectableKeywords);
    }
    static isFence(block) {
        return block.getTags().includes(this.componentName);
    }
    static updateConnections(arg, depth) {
        if (depth <= 0)
            return;
        const directions = [Direction.North, Direction.East, Direction.South, Direction.West];
        for (const direction of directions) {
            const neighbor = getRelativeBlock(arg.block, Direction.North, direction);
            if (!neighbor) {
                continue;
            }
            if (this.shouldConnectWith(neighbor)) {
                arg.permutationToPlace = arg.permutationToPlace.withState(`nps_tbe:${direction.toLocaleLowerCase()}_connected`, true);
            }
        }
    }
    static updateBlock(fence, depth) {
        if (depth <= 0)
            return;
        const directions = [Direction.North, Direction.East, Direction.South, Direction.West];
        for (const direction of directions) {
            const neighbor = getRelativeBlock(fence, Direction.North, direction);
            if (!neighbor) {
                continue;
            }
            const shouldConnectWith = this.shouldConnectWith(neighbor);
            setBlockState(fence, `nps_tbe:${direction.toLocaleLowerCase()}_connected`, shouldConnectWith);
            if (depth > 0 && Fence.isFence(neighbor)) {
                this.updateBlock(neighbor, depth - 1);
            }
        }
    }
}
Fence.componentName = "nps_tbe:dedf8a84";
Fence.unconnectableBlocks = [
    "minecraft:short_grass",
    "minecraft:tall_grass",
    "minecraft:cactus",
    "minecraft:ladder",
    "minecraft:bed",
    "minecraft:sculk_sensor",
    "minecraft:sculk_shrieker",
    "minecraft:sculk_vein",
    "minecraft:calibrated_sculk_sensor",
];
Fence.unconnectableKeywords = [
    "_carpet",
    "_trapdoor",
    "_sapling",
    "_leaves",
    "_flower",
    "_pressure_plate",
    "_button",
    "_egg",
    "_sign",
];
Fence.unconnectableTags = [
    "nps_tbe:no_fence_attach",
    "minecraft:crop"
];
class Wall {
    static initialize(event) { event.blockComponentRegistry.registerCustomComponent(this.componentName, new this()); }
    beforeOnPlayerPlace(arg) {
        Wall.updateConnections(arg, 2);
    }
    ;
    onPlace(arg) {
        Wall.updateBlock(arg.block, 2);
    }
    ;
    onPlayerDestroy(arg) {
        const directions = [Direction.North, Direction.East, Direction.South, Direction.West];
        for (const direction of directions) {
            const neighbor = getRelativeBlock(arg.block, Direction.North, direction);
            if (!neighbor) {
                continue;
            }
            if (!Wall.isWall(neighbor)) {
                continue;
            }
            Wall.updateBlock(neighbor, 1);
        }
    }
    ;
    static shouldConnectWith(neighbor) {
        return !neighbor?.isAir
            && !neighbor?.isLiquid
            && neighbor?.isValid()
            && !Wall.unconnectableBlocks.includes(neighbor.typeId)
            && !hasCommonTag(neighbor.getTags(), Wall.unconnectableTags)
            && !containsKeyword(neighbor.typeId, Wall.unconnectableKeywords);
    }
    static isWall(block) {
        return block.getTags().includes(this.componentName);
    }
    static updateConnections(arg, depth) {
        if (depth <= 0)
            return;
        const directions = [Direction.North, Direction.East, Direction.South, Direction.West];
        for (const direction of directions) {
            const neighbor = getRelativeBlock(arg.block, Direction.North, direction);
            if (!neighbor) {
                continue;
            }
            if (this.shouldConnectWith(neighbor)) {
                arg.permutationToPlace = arg.permutationToPlace.withState(`nps_tbe:${direction.toLocaleLowerCase()}_connected`, true);
            }
        }
    }
    static updateBlock(wall, depth) {
        if (depth <= 0)
            return;
        const directions = [Direction.North, Direction.East, Direction.South, Direction.West];
        for (const direction of directions) {
            const neighbor = getRelativeBlock(wall, Direction.North, direction);
            if (!neighbor) {
                continue;
            }
            const shouldConnectWith = this.shouldConnectWith(neighbor);
            setBlockState(wall, `nps_tbe:${direction.toLocaleLowerCase()}_connected`, shouldConnectWith);
            if (depth > 0 && Wall.isWall(neighbor)) {
                this.updateBlock(neighbor, depth - 1);
            }
        }
    }
}
Wall.componentName = "nps_tbe:13b9a506";
Wall.unconnectableBlocks = [
    "minecraft:short_grass",
    "minecraft:tall_grass",
    "minecraft:cactus",
    "minecraft:ladder",
    "minecraft:bed",
    "minecraft:sculk_sensor",
    "minecraft:sculk_shrieker",
    "minecraft:sculk_vein",
    "minecraft:calibrated_sculk_sensor",
];
Wall.unconnectableKeywords = [
    "_carpet",
    "_trapdoor",
    "_sapling",
    "_leaves",
    "_flower",
    "_pressure_plate",
    "_button",
    "_egg",
    "_sign"
];
Wall.unconnectableTags = [
    "nps_tbe:no_wall_attach",
    "minecraft:crop"
];
class Step {
    static initialize(event) { event.blockComponentRegistry.registerCustomComponent(this.componentName, new this()); }
    onPlace(arg0) {
        Step.updateBlock(arg0.block, 2);
    }
    onPlayerDestroy(arg0) {
        const cardinalDirection = arg0.destroyedBlockPermutation.getState("minecraft:cardinal_direction");
        const directions = [Direction.North, Direction.East, Direction.South, Direction.West];
        for (const direction of directions) {
            const neighbor = getRelativeBlockInDirection(arg0.block, direction, cardinalDirection);
            if (!neighbor) {
                continue;
            }
            if (!Step.isStep(neighbor)) {
                continue;
            }
            Step.updateBlock(neighbor, 1);
        }
    }
    ;
    static isStep(block) {
        return block.getTags().includes(this.componentName);
    }
    static updateBlock(block, depth) {
        if (depth <= 0)
            return;
        const cardinalDirection = getCardinalDirection(block);
        const northNeighborCardinalDirection = getCardinalDirection(getRelativeBlockInDirection(block, Direction.North));
        const southNeighborCardinalDirection = getCardinalDirection(getRelativeBlockInDirection(block, Direction.South));
        const vertical_half = getBlockState(block, "minecraft:vertical_half");
        if (vertical_half == "top")
            return;
        //console.warn('cardinalDirection:', cardinalDirection, 'vertical_half:', vertical_half)
        const northNeighborRotation = Step.getRotationOffset(cardinalDirection, northNeighborCardinalDirection); //0..270 | undefined
        const southNeighborRotation = Step.getRotationOffset(cardinalDirection, southNeighborCardinalDirection); //0..270 | undefined
        const w = Step.isConnectable(block, Direction.West); //boolean
        const n = Step.isConnectable(block, Direction.North); //boolean
        const e = Step.isConnectable(block, Direction.East); //boolean
        const s = Step.isConnectable(block, Direction.South); //boolean
        //console.warn('swne, nnr, snc:', s, w, n, e, northNeighborRotation, southNeighborRotation);
        const truthTableResult = Step.evaluateTruthTable(s, w, n, e, northNeighborRotation, southNeighborRotation);
        setBlockState(block, "nps_tbe:part_0", truthTableResult[0]);
        setBlockState(block, "nps_tbe:part_1", truthTableResult[1]);
        setBlockState(block, "nps_tbe:part_2", truthTableResult[2]);
        setBlockState(block, "nps_tbe:part_3", truthTableResult[3]);
        if (w)
            this.updateBlock(getRelativeBlockInDirection(block, Direction.West), depth - 1);
        if (n)
            this.updateBlock(getRelativeBlockInDirection(block, Direction.North), depth - 1);
        if (e)
            this.updateBlock(getRelativeBlockInDirection(block, Direction.East), depth - 1);
        if (s)
            this.updateBlock(getRelativeBlockInDirection(block, Direction.South), depth - 1);
    }
    static evaluateTruthTable(s, w, n, e, northNeighborRotation, southNeighborRotation) {
        // Initialisation d'un tableau de résultats
        let result = [];
        // Lignes de la table de vérité
        if (s === false && w === false && n === false && e === false) {
            result = [true, true, false, false];
        }
        else if (s === false && w === false && n === false && e === true) {
            result = [true, true, false, false];
        }
        else if (s === false && w === false && n === true && e === false) {
            result = [northNeighborRotation !== 90, northNeighborRotation !== 270, false, false];
        }
        else if (s === false && w === false && n === true && e === true) {
            result = [northNeighborRotation !== 90, true, false, false];
        }
        else if (s === false && w === true && n === false && e === false) {
            result = [true, true, false, false];
        }
        else if (s === false && w === true && n === false && e === true) {
            result = [true, true, false, false];
        }
        else if (s === false && w === true && n === true && e === false) {
            result = [true, northNeighborRotation !== 270, false, false];
        }
        else if (s === false && w === true && n === true && e === true) {
            result = [true, true, false, false];
        }
        else if (s === true && w === false && n === false && e === false) {
            result = [true, true, southNeighborRotation === 90, southNeighborRotation === 270];
        }
        else if (s === true && w === false && n === false && e === true) {
            result = [true, true, false, southNeighborRotation === 270];
        }
        else if (s === true && w === false && n === true && e === false) {
            result = [true, true, southNeighborRotation === 90, southNeighborRotation === 270];
        }
        else if (s === true && w === false && n === true && e === true) {
            result = [true, true, true, southNeighborRotation === 270];
        }
        else if (s === true && w === true && n === false && e === false) {
            result = [true, true, southNeighborRotation === 90, false];
        }
        else if (s === true && w === true && n === false && e === true) {
            result = [true, true, false, false];
        }
        else if (s === true && w === true && n === true && e === false) {
            result = [true, true, southNeighborRotation === 90, false];
        }
        else if (s === true && w === true && n === true && e === true) {
            result = [true, true, false, false];
        }
        // Si aucune condition n'est remplie, on retourne un tableau vide
        if (result.length === 0) {
            console.error("No line in the truth table matches the conditions.");
        }
        return result;
    }
    static getRotationOffset(cardinalDirection, neighborCardinalDirection) {
        if (!cardinalDirection || !neighborCardinalDirection)
            return undefined;
        // Liste des directions cardinales dans le sens des aiguilles d'une montre
        const directions = [
            Direction.North.toLocaleLowerCase(),
            Direction.East.toLocaleLowerCase(),
            Direction.South.toLocaleLowerCase(),
            Direction.West.toLocaleLowerCase()
        ];
        // Trouver l'index de la direction donnée et de la direction voisine
        const cdIndex = directions.indexOf(cardinalDirection.toLowerCase());
        const ncdIndex = directions.indexOf(neighborCardinalDirection.toLowerCase());
        // Vérifier si l'une des directions est invalide (pas trouvée dans le tableau)
        if (cdIndex === -1 || ncdIndex === -1)
            return undefined;
        // Calculer la différence d'index, représentant la rotation en multiples de 90°
        const rotationOffset = 90 * ((ncdIndex - cdIndex + 4) % 4);
        return rotationOffset;
    }
    static isConnectable(block, direction) {
        const neighbor = getRelativeBlockInDirection(block, direction);
        if (!neighbor)
            return true;
        if (!block.getTags().includes(Step.componentName))
            return true;
        const half = getBlockState(block, "minecraft:vertical_half");
        const expectedHalf = getBlockState(neighbor, "minecraft:vertical_half");
        return half === expectedHalf;
    }
}
Step.componentName = "nps_tbe:116d981d";
class SaplingConfig {
    constructor(oneByOneStructures, // List of structure identifiers for 1x1 saplings
    twoByTwoStructures, // List of structure identifiers for 2x2 saplings
    growthChanceTime = 0.1, // Chance to grow naturally over time
    growthChanceBoneMeal = 0.05 // Chance to grow when using bone meal
    ) {
        this.oneByOneStructures = oneByOneStructures;
        this.twoByTwoStructures = twoByTwoStructures;
        this.growthChanceTime = growthChanceTime;
        this.growthChanceBoneMeal = growthChanceBoneMeal;
    }
}
class Sapling {
    static initialize(event) { event.blockComponentRegistry.registerCustomComponent(this.componentName, new this()); }
    onRandomTick(arg) {
        Sapling.tryToGrow(arg.block, false);
    }
    onPlayerInteract(arg) {
        const itemStack = getPlayerEquipment(arg.player).getEquipment(EquipmentSlot.Mainhand);
        if (!itemStack)
            return;
        if (itemStack.typeId !== "minecraft:bone_meal")
            return;
        decrementStack(arg.player);
        arg.dimension.spawnParticle("minecraft:crop_growth_emitter", arg.block.center());
        arg.dimension.playSound("item.bone_meal.use", arg.block.center());
        Sapling.tryToGrow(arg.block, true);
    }
    ;
    static getConfig(saplingType) {
        const config = this.saplingConfigs[saplingType];
        if (!config) {
            throw new Error(`Configuration not found for sapling type: ${saplingType} in class Sapling`);
        }
        return config;
    }
    static tryToGrow(block, isBoneMeal = false) {
        if (block.typeId == "minecraft:air")
            return;
        const saplingType = block.typeId;
        const config = Sapling.getConfig(saplingType);
        const growthChance = isBoneMeal ? config.growthChanceBoneMeal : config.growthChanceTime;
        if (Math.random() > growthChance)
            return;
        const saplingGroup = Sapling.getSaplingGroupOrDefault(block);
        const structures = saplingGroup.length === 1 ? config.oneByOneStructures : config.twoByTwoStructures;
        const validStructures = Sapling.getValidStructures(block, structures);
        if (validStructures.length === 0)
            return;
        const selectedStructure = validStructures[Math.floor(Math.random() * validStructures.length)];
        saplingGroup.forEach(block => { block.setType("minecraft:air"); });
        Sapling.growStructure(selectedStructure, block);
    }
    static getSaplingGroupOrDefault(block) {
        const directions = [
            { x: 0, z: 0 }, // Original block
            { x: 1, z: 0 }, // East
            { x: 0, z: 1 }, // South
            { x: 1, z: 1 } // South-East
        ];
        const saplingGroups = [
            block => directions.map(({ x, z }) => block.dimension.getBlock({
                x: block.location.x + x,
                y: block.location.y,
                z: block.location.z + z
            })),
            block => directions.map(({ x, z }) => block.dimension.getBlock({
                x: block.location.x - x,
                y: block.location.y,
                z: block.location.z + z
            })),
            block => directions.map(({ x, z }) => block.dimension.getBlock({
                x: block.location.x + x,
                y: block.location.y,
                z: block.location.z - z
            })),
            block => directions.map(({ x, z }) => block.dimension.getBlock({
                x: block.location.x - x,
                y: block.location.y,
                z: block.location.z - z
            }))
        ];
        for (const group of saplingGroups) {
            const blocks = group(block);
            if (blocks.every(b => b?.typeId === block.typeId)) {
                return blocks; // Valid sapling group found
            }
        }
        return [block]; // No valid sapling group, return original block
    }
    static getValidStructures(block, structures) {
        return structures.filter(structureId => {
            const structure = world.structureManager.get(structureId);
            if (!structure)
                return false;
            const structureSize = structure.size;
            const placementOffset = {
                x: Math.floor(structureSize.x / 2),
                z: Math.floor(structureSize.z / 2),
            };
            const placementLocation = {
                x: block.location.x - placementOffset.x,
                y: block.location.y,
                z: block.location.z - placementOffset.z,
            };
            // Check if the area for the structure is clear
            return Sapling.isAreaClear(block, structureSize, [block.typeId]);
        });
    }
    static isAreaClear(block, size, allowedBlocks = []) {
        const startLocation = block.location;
        const dimension = block.dimension;
        for (let x = startLocation.x; x < startLocation.x + size.x; x++) {
            for (let y = startLocation.y; y < startLocation.y + size.y; y++) {
                for (let z = startLocation.z; z < startLocation.z + size.z; z++) {
                    const block = dimension.getBlock({ x, y, z });
                    if (block && block.typeId !== "minecraft:air") {
                        if (!allowedBlocks.includes(block.typeId)) {
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }
    static growStructure(structureId, block) {
        const structureManager = world.structureManager;
        const dimension = block.dimension;
        const location = block.location;
        // Retrieve the structure and calculate its size
        const structure = structureManager.get(structureId);
        if (!structure)
            return;
        const structureSize = structure.size;
        const placementOffset = {
            x: Math.floor(structureSize.x / 2),
            z: Math.floor(structureSize.z / 2)
        };
        const placementLocation = {
            x: location.x - placementOffset.x,
            y: location.y,
            z: location.z - placementOffset.z
        };
        // Place the structure in the world
        structureManager.place(structureId, dimension, placementLocation, {
            rotation: getRandomStructureRotation()
        });
    }
}
Sapling.componentName = "nps_tbe:38026d53";
Sapling.saplingConfigs = {
    "nps_tbe:amanita_sapling_0": new SaplingConfig([
        "mystructure:nps_tbe/am_t_1",
        "mystructure:nps_tbe/am_t_2",
        "mystructure:nps_tbe/am_t_3",
        "mystructure:nps_tbe/am_t_4"
    ], [
        "mystructure:nps_tbe/am_t_5",
        "mystructure:nps_tbe/am_t_6",
        "mystructure:nps_tbe/am_t_7",
        "mystructure:nps_tbe/am_t_8"
    ]),
    "nps_tbe:chlorophos_sapling_0": new SaplingConfig([
        "mystructure:nps_tbe/ch_sh_1",
        "mystructure:nps_tbe/ch_sh_2"
    ], [
        "mystructure:nps_tbe/ch_t_1",
        "mystructure:nps_tbe/ch_t_2"
    ]),
    "nps_tbe:cortinarius_sapling_0": new SaplingConfig([
        "mystructure:nps_tbe/co_t_1",
        "mystructure:nps_tbe/co_t_2",
        "mystructure:nps_tbe/co_t_3",
    ], [
        "mystructure:nps_tbe/co_t_4",
        "mystructure:nps_tbe/co_t_5",
        "mystructure:nps_tbe/co_t_6"
    ]),
    "nps_tbe:end_sapling_0": new SaplingConfig([
        "mystructure:nps_tbe/end_t_1"
    ], []),
    "nps_tbe:lactarius_sapling_0": new SaplingConfig([
        "mystructure:nps_tbe/la_t_1",
        "mystructure:nps_tbe/la_t_2",
        "mystructure:nps_tbe/la_t_3",
        "mystructure:nps_tbe/la_t_4"
    ], [
        "mystructure:nps_tbe/la_t_5",
        "mystructure:nps_tbe/la_t_6",
        "mystructure:nps_tbe/la_t_7",
    ]),
    "nps_tbe:umbromycelia_sapling_0": new SaplingConfig([
        "mystructure:nps_tbe/um_t_1",
        "mystructure:nps_tbe/um_t_2",
        "mystructure:nps_tbe/um_t_3"
    ], [])
};
class Leaves {
    static initialize(event) { event.blockComponentRegistry.registerCustomComponent(this.componentName, new this()); }
    onRandomTick(event) {
        Leaves.handleLeafDecay(event.block);
        // Filtrage pour neutraliser l'effet de tickSpeed élevé
        const spawnBaseChance = 1 / world.gameRules.randomTickSpeed;
        if (Math.random() > spawnBaseChance)
            return;
        Leaves.emitFallingLeafParticles(event.block);
    }
    ;
    onPlayerDestroy(arg0) {
        const player = arg0.player;
        if (player == undefined)
            return;
        const itemStack = getPlayerEquipment(player).getEquipment(EquipmentSlot.Mainhand);
        const lootTablePath = `nps/tbe/${arg0.block.typeId.split("nps_tbe:"[1])}`;
        if (itemStack == undefined) {
            arg0.dimension.runCommand(`loot spawn ${arg0.block.x} ${arg0.block.y} ${arg0.block.z} loot "${lootTablePath}_0"`);
            return;
        }
        const isSilkTouch = getEnchantmentLevel(itemStack, "silk_touch") > 0;
        const fortuneLevel = Math.max(0, Math.min(getEnchantmentLevel(itemStack, "fortune"), 3));
        if (isShears(itemStack)) {
            arg0.dimension.spawnItem(arg0.block.getItemStack(1, false), arg0.block.center());
        }
        else if (isHoe(itemStack) && !isSilkTouch) {
            arg0.dimension.runCommand(`loot spawn ${arg0.block.x} ${arg0.block.y} ${arg0.block.z} loot "${lootTablePath}_${fortuneLevel}"`);
        }
        else {
            arg0.dimension.runCommand(`loot spawn ${arg0.block.x} ${arg0.block.y} ${arg0.block.z} loot "${lootTablePath}_0"`);
        }
    }
    ;
    beforeOnPlayerPlace(arg0) {
        const player = arg0.player;
        if (player == undefined)
            return;
        if (arg0.player.getTags().includes('nps_tbe:developer'))
            return;
        arg0.permutationToPlace = arg0.permutationToPlace.withState("nps_tbe:persistent_bit", true);
    }
    ;
    //..
    static handleLeafDecay(leafBlock) {
        const skipChance = 0.75;
        if (Math.random() <= skipChance)
            return;
        const persistentBit = getBlockState(leafBlock, "nps_tbe:persistent_bit");
        if (persistentBit === undefined || persistentBit === true)
            return;
        if (!Leaves.shouldDecay(leafBlock))
            return;
        const doTileDrops = world.gameRules.doTileDrops;
        if (doTileDrops) {
            const lootTableName = this.getLootTable(leafBlock.typeId);
            const lootTablePath = `nps/tbe/${lootTableName}`;
            const commandString = `loot spawn ${leafBlock.x} ${leafBlock.y} ${leafBlock.z} loot "${lootTablePath}_0"`;
            leafBlock.dimension.runCommand(commandString);
        }
        leafBlock.setType("minecraft:air");
    }
    static getLootTable(blockId) {
        const blockLootTables = {
            "nps_tbe:amanita_leaves_0": "amanita_leaves",
            "nps_tbe:amanita_leaves_1": "amanita_leaves",
            "nps_tbe:amanita_leaves_2": "amanita_leaves",
            "nps_tbe:chlorophos_leaves_0": "chlorophos_leaves",
            "nps_tbe:chlorophos_leaves_1": "chlorophos_leaves",
            "nps_tbe:chlorophos_leaves_2": "chlorophos_leaves",
            "nps_tbe:cortinarius_leaves_0": "cortinarius_leaves",
            "nps_tbe:cortinarius_leaves_1": "cortinarius_leaves",
            "nps_tbe:cortinarius_leaves_2": "cortinarius_leaves",
            "nps_tbe:cortinarius_leaves_3": "cortinarius_leaves",
            "nps_tbe:cortinarius_leaves_4": "cortinarius_leaves",
            "nps_tbe:dead_leaves_0": "dead_leaves",
            "nps_tbe:end_leaves_0": "end_leaves",
            "nps_tbe:end_leaves_1": "end_leaves",
            "nps_tbe:end_leaves_2": "end_leaves",
            "nps_tbe:lactarius_leaves_0": "lactarius_leaves",
            "nps_tbe:lactarius_leaves_1": "lactarius_leaves",
            "nps_tbe:lactarius_leaves_2": "lactarius_leaves",
            "nps_tbe:lactarius_leaves_3": "lactarius_leaves",
            "nps_tbe:umbromycelia_leaves_0": "umbromycelia_leaves"
        };
        return blockLootTables[blockId];
    }
    static emitFallingLeafParticles(leafBlock) {
        const palettes = {
            // 🍂 Amanita – Orange
            "nps_tbe:amanita_leaves_0": [
                { red: 0.867, green: 0.463, blue: 0.122 },
                { red: 0.945, green: 0.553, blue: 0.200 },
                { red: 1.0, green: 0.643, blue: 0.282 }
            ],
            "nps_tbe:amanita_leaves_1": [
                { red: 0.867, green: 0.463, blue: 0.122 },
                { red: 0.945, green: 0.553, blue: 0.200 },
                { red: 1.0, green: 0.643, blue: 0.282 }
            ],
            "nps_tbe:amanita_leaves_2": [
                { red: 0.867, green: 0.463, blue: 0.122 },
                { red: 0.945, green: 0.553, blue: 0.200 },
                { red: 1.0, green: 0.643, blue: 0.282 }
            ],
            // 🍃 Chlorophos – Vert
            "nps_tbe:chlorophos_leaves_0": [
                { red: 0.373, green: 0.753, blue: 0.184 },
                { red: 0.493, green: 0.863, blue: 0.204 },
                { red: 0.631, green: 1.0, blue: 0.243 }
            ],
            "nps_tbe:chlorophos_leaves_1": [
                { red: 0.373, green: 0.753, blue: 0.184 },
                { red: 0.493, green: 0.863, blue: 0.204 },
                { red: 0.631, green: 1.0, blue: 0.243 }
            ],
            "nps_tbe:chlorophos_leaves_2": [
                { red: 0.373, green: 0.753, blue: 0.184 },
                { red: 0.493, green: 0.863, blue: 0.204 },
                { red: 0.631, green: 1.0, blue: 0.243 }
            ],
            // 🟣 Cortinarius – Violet
            "nps_tbe:cortinarius_leaves_0": [
                { red: 0.471, green: 0.282, blue: 0.675 },
                { red: 0.580, green: 0.357, blue: 0.788 },
                { red: 0.710, green: 0.439, blue: 0.871 }
            ],
            "nps_tbe:cortinarius_leaves_1": [
                { red: 0.471, green: 0.282, blue: 0.675 },
                { red: 0.580, green: 0.357, blue: 0.788 },
                { red: 0.710, green: 0.439, blue: 0.871 }
            ],
            "nps_tbe:cortinarius_leaves_2": [
                { red: 0.471, green: 0.282, blue: 0.675 },
                { red: 0.580, green: 0.357, blue: 0.788 },
                { red: 0.710, green: 0.439, blue: 0.871 }
            ],
            "nps_tbe:cortinarius_leaves_3": [
                { red: 0.471, green: 0.282, blue: 0.675 },
                { red: 0.580, green: 0.357, blue: 0.788 },
                { red: 0.710, green: 0.439, blue: 0.871 }
            ],
            "nps_tbe:cortinarius_leaves_4": [
                { red: 0.471, green: 0.282, blue: 0.675 },
                { red: 0.580, green: 0.357, blue: 0.788 },
                { red: 0.710, green: 0.439, blue: 0.871 }
            ],
            // 🤎 Dead – Brun
            "nps_tbe:dead_leaves_0": [
                { red: 0.373, green: 0.263, blue: 0.153 },
                { red: 0.463, green: 0.322, blue: 0.196 },
                { red: 0.529, green: 0.392, blue: 0.239 }
            ],
            // 🌸 End – Violet rosé
            "nps_tbe:end_leaves_0": [
                { red: 0.792, green: 0.545, blue: 0.902 },
                { red: 0.902, green: 0.659, blue: 0.949 },
                { red: 1.0, green: 0.78, blue: 1.0 }
            ],
            "nps_tbe:end_leaves_1": [
                { red: 0.792, green: 0.545, blue: 0.902 },
                { red: 0.902, green: 0.659, blue: 0.949 },
                { red: 1.0, green: 0.78, blue: 1.0 }
            ],
            "nps_tbe:end_leaves_2": [
                { red: 0.792, green: 0.545, blue: 0.902 },
                { red: 0.902, green: 0.659, blue: 0.949 },
                { red: 1.0, green: 0.78, blue: 1.0 }
            ],
            // 🔵 Lactarius – Bleu
            "nps_tbe:lactarius_leaves_0": [
                { red: 0.345, green: 0.584, blue: 0.757 },
                { red: 0.463, green: 0.690, blue: 0.875 },
                { red: 0.580, green: 0.788, blue: 0.973 }
            ],
            "nps_tbe:lactarius_leaves_1": [
                { red: 0.345, green: 0.584, blue: 0.757 },
                { red: 0.463, green: 0.690, blue: 0.875 },
                { red: 0.580, green: 0.788, blue: 0.973 }
            ],
            "nps_tbe:lactarius_leaves_2": [
                { red: 0.345, green: 0.584, blue: 0.757 },
                { red: 0.463, green: 0.690, blue: 0.875 },
                { red: 0.580, green: 0.788, blue: 0.973 }
            ],
            "nps_tbe:lactarius_leaves_3": [
                { red: 0.345, green: 0.584, blue: 0.757 },
                { red: 0.463, green: 0.690, blue: 0.875 },
                { red: 0.580, green: 0.788, blue: 0.973 }
            ],
            // ⚫ Umbromycelia – Noir
            "nps_tbe:umbromycelia_leaves_0": [
                { red: 0.1, green: 0.1, blue: 0.1 },
                { red: 0.2, green: 0.2, blue: 0.2 },
                { red: 0.3, green: 0.3, blue: 0.3 }
            ]
        };
        const palette = palettes[leafBlock.typeId];
        if (!palette)
            return;
        const molangVariables = new MolangVariableMap();
        const randomColor = palette[getRandomInt(0, palette.length - 1)];
        molangVariables.setColorRGB("color", randomColor);
        leafBlock.dimension.spawnParticle("minecraft:biome_tinted_leaves_particle", leafBlock.location, molangVariables);
    }
    static shouldDecay(leaf) {
        const leafLocation = leaf.location;
        const blockVolume = new BlockVolume({
            x: leafLocation.x - Leaves.decayDistance,
            y: leafLocation.y - Leaves.decayDistance,
            z: leafLocation.z - Leaves.decayDistance
        }, {
            x: leafLocation.x + Leaves.decayDistance,
            y: leafLocation.y + Leaves.decayDistance,
            z: leafLocation.z + Leaves.decayDistance
        });
        try {
            const shouldDecay = !leaf.dimension.containsBlock(blockVolume, { includeTags: ["minecraft:log"] }, false);
            return shouldDecay;
        }
        catch {
            return false;
        }
    }
}
Leaves.componentName = "nps_tbe:a578049d";
Leaves.decayDistance = 8;
class Axe {
    static initialize(event) { event.itemComponentRegistry.registerCustomComponent(this.componentName, new this()); }
    onMineBlock(arg) {
        if (arg.source.typeId !== "minecraft:player")
            return;
        damageItemStack(arg.source);
    }
    onUseOn(arg) {
        const block = arg.block;
        const player = arg.source;
        if (player?.typeId !== "minecraft:player")
            return;
        Axe.stripWood(block, player);
    }
    ;
    static stripWood(block, player) {
        const blockTags = block.getTags();
        if (!blockTags.includes('wood') && !blockTags.includes('minecraft:wood'))
            return;
        if (block.typeId.includes('stripped_'))
            return;
        const strippedBlockIdentifier = Axe.getStrippedBlockIdentifier(block);
        if (!strippedBlockIdentifier)
            return;
        system.run(() => {
            try {
                const itemStack = new ItemStack(strippedBlockIdentifier);
            }
            catch {
                return;
            }
            player.playSound("hit.wood", { location: block.location });
            const pillar_axis = getBlockState(block, "pillar_axis");
            block.setType(strippedBlockIdentifier);
            setBlockState(block, "pillar_axis", pillar_axis);
            damageItemStack(player, 1);
        });
    }
    static getStrippedBlockIdentifier(block) {
        const identifier = block.typeId;
        const parts = identifier.split(":");
        // Vérifie que l'identifiant est bien structuré en "namespace:blockType"
        if (parts.length !== 2)
            return undefined;
        const [namespace, blockType] = parts;
        return `${namespace}:stripped_${blockType}`;
    }
}
Axe.componentName = "nps_tbe:3d799ea1";
class Pickaxe {
    static initialize(event) { event.itemComponentRegistry.registerCustomComponent(this.componentName, new this()); }
    onMineBlock(arg) {
        if (arg.source.typeId !== "minecraft:player")
            return;
        damageItemStack(arg.source);
    }
    static beforePlayerBreakBlock(event) {
        if (!isPickaxe(event.itemStack))
            return;
        onPickaxeMining(event);
    }
}
Pickaxe.componentName = "nps_tbe:d139a544";
class Sword {
    static initialize(event) { event.itemComponentRegistry.registerCustomComponent(this.componentName, new this()); }
    onMineBlock(arg) {
        if (arg.source.typeId !== "minecraft:player")
            return;
        damageItemStack(arg.source);
    }
    ;
}
Sword.componentName = "nps_tbe:d769ddef";
class Hammer {
    static initialize(event) { event.itemComponentRegistry.registerCustomComponent(this.componentName, new this()); }
    onMineBlock(arg) {
        if (arg.source.typeId !== "minecraft:player")
            return;
        damageItemStack(arg.source);
    }
    static beforePlayerBreakBlock(event) {
        if (!isHammer(event.itemStack))
            return;
        onHammerMining(event);
    }
}
Hammer.componentName = "nps_tbe:604cca3f";
class Hoe {
    static initialize(event) { event.itemComponentRegistry.registerCustomComponent(this.componentName, new this()); }
    onMineBlock(arg) {
        if (arg.source.typeId !== "minecraft:player")
            return;
        damageItemStack(arg.source);
    }
    ;
    static beforeItemUseOn(event) {
        if (!isHoe(event.itemStack))
            return;
        if (event.block.typeId == "minecraft:farmland")
            return;
        system.run(() => {
            damageItemStack(event.source);
        });
    }
}
Hoe.componentName = "nps_tbe:f7bf9820";
class Shovel {
    static initialize(event) { event.itemComponentRegistry.registerCustomComponent(this.componentName, new this()); }
    onMineBlock(arg) {
        if (arg.source.typeId !== "minecraft:player")
            return;
        damageItemStack(arg.source);
    }
    ;
    static beforeItemUseOn(event) {
        if (!isShovel(event.itemStack))
            return;
        const block = event.block;
        if (block.typeId == "minecraft:dirt_with_roots") {
            system.run(() => {
                block.setType("minecraft:grass_path");
                damageItemStack(event.source);
            });
            return;
        }
        if ([
            "minecraft:grass_path"
        ].includes(block.typeId))
            return;
        system.run(() => {
            damageItemStack(event.source);
        });
    }
}
Shovel.componentName = "nps_tbe:9e651b45";
world.beforeEvents.itemUseOn.subscribe(event => {
    Hoe.beforeItemUseOn(event);
    Shovel.beforeItemUseOn(event);
});
world.beforeEvents.worldInitialize.subscribe(event => {
    Axe.initialize(event);
    Door.initialize(event);
    Fence.initialize(event);
    FenceGate.initialize(event);
    Leaves.initialize(event);
    Hammer.initialize(event);
    Hoe.initialize(event);
    Pickaxe.initialize(event);
    Sapling.initialize(event);
    Shovel.initialize(event);
    Step.initialize(event);
    Sword.initialize(event);
    Trapdoor.initialize(event);
    Wall.initialize(event);
});
world.beforeEvents.playerBreakBlock.subscribe(event => {
    Hammer.beforePlayerBreakBlock(event);
    Pickaxe.beforePlayerBreakBlock(event);
});
world.afterEvents.playerPlaceBlock.subscribe(event => {
    Door.afterPlayerPlaceBlock(event);
    FenceGate.afterPlayerPlaceBlock(event);
});
