import * as server from "@minecraft/server"
import
{
    EquipmentSlot,
    ItemStack
}
from "@minecraft/server"
const world = server.world
import * as ui from "@minecraft/server-ui"
import { DamageItem } from "./modules/Durability";
import { Oxidise } from "./modules/Oxidize";
import { Combat } from "./modules/Combat";
import "./block_trigger";
import "./item_trigger";
import {
    world,
    system,
    EntityComponentTypes
} from "@minecraft/server";
import "./modules/Deoxidize";

function durability(player, item, damage) {
  if (player.matches({ gameMode: 'creative' })) return;
  const inventory = player.getComponent("minecraft:inventory").container;
  const durability = item.getComponent("minecraft:durability");
  system.run(() => {
    if (durability.damage + damage >= durability.maxDurability) {
      inventory.setItem(player.selectedSlotIndex, null)
      player.playSound("random.break");
    } else {
      item.getComponent("minecraft:durability").damage += damage;
      inventory.setItem(player.selectedSlotIndex, item);
    }
  })
}

system.runInterval(() => {
  world.getDimension("minecraft:overworld").getPlayers().forEach(player => {
    if (world.getTimeOfDay() < 23000 && world.getTimeOfDay() > 13000 && world.getMoonPhase() == 0 && player.matches({ excludeTags: ["blood_moon"] })) {
      player.sendMessage({ "rawtext": [{ "translate": "§4The Blood Moon is rising..." }] });
      player.addTag('blood_moon');
      player.runCommandAsync(`fog @a push "minecraft:fog_crimson_forest" bloodmoon`)
      player.runCommandAsync(`effect @a clear`)
    }
    if (!(world.getTimeOfDay() < 23000 && world.getTimeOfDay() > 13000) && player.matches({ tags: ["blood_moon"] })) {
      player.sendMessage({ "rawtext": [{ "translate": "§7The §4Blood Moon §7fades away... a sense of calm and tranquility washes over the land..." }] });
      player.removeTag('blood_moon');
      player.runCommandAsync(`fog @a remove bloodmoon`)
      player.runCommandAsync(`effect @a clear`)
    }
  });
  world.getDimension("minecraft:overworld").getEntities().forEach(entity => {
    if (!(world.getTimeOfDay() < 23000 && world.getTimeOfDay() > 13000) && entity.matches({ tags: ["hell_moon_creature"] })) {
      entity.remove();
    }
  });
}, 20);

world.beforeEvents.playerInteractWithBlock.subscribe((e) => {
  const player = e.player;
  const block = e.block;
  if (block && block.typeId === "minecraft:bed") {
    const hellMoon = world.getMoonPhase() == 0;
    if (hellMoon && player.hasTag("blood_moon") && player.matches({ excludeGameModes: [GameMode.creative] })) {
      player.sendMessage({ "rawtext": [{ translate: "§cYou don't feel tired enough to sleep..." }] })
      e.cancel = true;
    }
  }
});

function getUniqueBlockProperty(block) {
    return `crafting_traps:icePlace_${block.location.x}_${block.location.y}_${block.location.z}`;
}

function onstep(data) {
    const { entity, block, dimension } = data;

    const fakeBlockEffects = {
        "crafting_traps:fake_dirt": ["dig.grass", "crafting_traps:destroy_block_dirt"],
        "crafting_traps:fake_grass": ["dig.grass", "crafting_traps:destroy_block_grass"],
        "crafting_traps:fake_stone": ["dig.stone", "crafting_traps:destroy_block_stone"],
        "crafting_traps:fake_cobblestone": ["dig.stone", "crafting_traps:destroy_block_cobblestone"],
        "crafting_traps:fake_cobblestone_mossy": ["dig.stone", "crafting_traps:destroy_block_cobblestone_mossy"]
    };

    if (block.typeId in fakeBlockEffects) {
        const [sound, particle] = fakeBlockEffects[block.typeId];
        handleFakeBlock(block, dimension, sound, particle, entity);
    }
    if (block.typeId === "crafting_traps:ice_trap") {
        placeBlocksIce(block, dimension);
    }
    if (block.typeId === "crafting_traps:underworld_trap") {
        underworld(entity, block, dimension);
    }
    if (block.typeId === "crafting_traps:lift_trap") {
        lift_trap(entity, block, dimension);
    }

    if (block.typeId === "crafting_traps:firetrap") {
        spawnParticleFire(entity, block, dimension);
    }
    if (block.typeId.startsWith("crafting_traps:mine_")) {
        explosiveMineBlock(dimension, entity);
    }
}

function onstepOff(data) {
    const { entity, block, dimension } = data;

    if (block.typeId === "crafting_traps:ice_trap") {
        breakBlocksIce(block, dimension);
    }

    if (block.typeId === "crafting_traps:lift_trap") {
        lift_trapOff(entity, block, dimension);
    }
}

function placeBlocksIce(block, dimension) {
    for (let i = 1; i < 3; i++) {
        const blockPlace = dimension.getBlock({ x: block.location.x, y: block.location.y + i, z: block.location.z });
        if (blockPlace.isAir) {
            blockPlace.setType("minecraft:powder_snow");
            world.setDynamicProperty(getUniqueBlockProperty(blockPlace), blockPlace.location);
        }
    }
}

function breakBlocksIce(block, dimension) {
    for (let i = 1; i < 3; i++) {
        const blockPlace = dimension.getBlock({ x: block.location.x, y: block.location.y + i, z: block.location.z });
        if (!blockPlace.isAir) {
            blockPlace.setType("minecraft:air");
            world.setDynamicProperty(getUniqueBlockProperty(blockPlace), null);
        }
    }
}

function replaceMissingBlocks() {
    const dynamicPropertyIds = world.getDynamicPropertyIds();
    dynamicPropertyIds.forEach(property => {
        if (property.startsWith("crafting_traps:icePlace_")) {
            const locationData = world.getDynamicProperty(property);
            if (locationData == null) return;
            const block = world.getDimension("overworld").getBlock(locationData);
            try {
                if (block.isAir) {
                    block.setType("minecraft:powder_snow");
                }

                const adjacentLocations = [
                    { x: locationData.x + 1, z: locationData.z },
                    { x: locationData.x - 1, z: locationData.z },
                    { x: locationData.x, z: locationData.z + 1 },
                    { x: locationData.x, z: locationData.z - 1 }
                ];

                adjacentLocations.forEach(adjLoc => {
                    const adjacentBlock = world.getDimension("overworld").getBlock({ x: adjLoc.x, y: locationData.y, z: adjLoc.z });
                    if (adjacentBlock.typeId === "minecraft:powder_snow") {
                        adjacentBlock.setType("minecraft:air");
                    }
                });
            } catch (error) { }
        }
    });
}

function handleFakeBlock(block, dimension, sound, particle, entity) {
    const blockPlace = dimension.getBlock({ x: block.location.x, y: block.location.y, z: block.location.z });
    if (!blockPlace.isAir) {
        blockPlace.setType("minecraft:air");
        entity.runCommand(`playsound block.fake_block.break @a[r=4] ${block.location.x} ${block.location.y} ${block.location.z}`);
        dimension.spawnParticle(particle, {
            x: block.location.x + 0.5, y: block.location.y + 1, z: block.location.z + 0.5
        });
    }
}

function spawnParticleFire(entity, block, dimension) {
    entity.runCommand(`playsound block.fire_trap.step @a[r=4] ${block.location.x} ${block.location.y} ${block.location.z} 1 1`);
    dimension.spawnParticle("crafting_traps:firestorm", {
        x: block.location.x + 0.5, y: block.location.y + 1, z: block.location.z + 0.5
    });
    let i = 1;
    const blockPlace = dimension.getBlock({ x: block.location.x, y: block.location.y + i, z: block.location.z });
    if (blockPlace.isAir) {
        system.runTimeout(() => {
            blockPlace.setType("minecraft:fire");
        }, 10);
        system.runTimeout(() => {
            blockPlace.setType("minecraft:air");
        }, 35);
    }
}

function lift_trap(entity, block, dimension) {
    entity.runCommand(`playsound block.lift_trap.step @a[r=4] ${block.location.x} ${block.location.y} ${block.location.z} 1 1`);
    block.setPermutation(block.permutation.withState("crafting_traps:boing", true));
    entity.addEffect("levitation", 10, { amplifier: 20, showParticles: false });
}

function lift_trapOff(entity, block, dimension) {
    block.setPermutation(block.permutation.withState("crafting_traps:boing", false));
}

function underworld(entity, block, dimension) {
    if (dimension.typeId === "minecraft:overworld") {
        entity.runCommand(`playsound block.underworld_trap.step @a[r=4] ${block.location.x} ${block.location.y} ${block.location.z} 1 1`);
        entity.teleport({ x: block.location.x, y: -50, z: block.location.z });
    }else {
        entity.runCommand(`playsound block.underworld_trap.step @a[r=4] ${block.location.x} ${block.location.y} ${block.location.z} 1 1`);
        entity.teleport({ x: block.location.x, y: 4, z: block.location.z });
    }
}


function gas() {
    const dimensions = ["overworld", "nether", "the_end"];
    dimensions.forEach(dimensionName => {
        const dimension = world.getDimension(dimensionName);
        dimension.getEntities().forEach(entity => {
            const y = entity.location.y;
            if ((entity.dimension.typeId === "minecraft:overworld" && y >= -63 && y <= 319) || 
                (entity.dimension.typeId !== "minecraft:overworld" && y >= 1 && y <= 125)) {
                
                const gasBlock = dimension.getBlock({ x: entity.location.x, y: y, z: entity.location.z });
                if (gasBlock && gasBlock.typeId === 'crafting_traps:gas_trap') {
                    let lastSoundTick = entity.getDynamicProperty("lastGasSoundTick") || 0;
                    let currentTick = system.currentTick;
                    if (currentTick - lastSoundTick >= 10) {
                        entity.runCommand(`playsound block.gas_trap.step @a[r=4] ${gasBlock.location.x} ${gasBlock.location.y} ${gasBlock.location.z} 1 1`);
                        entity.setDynamicProperty("lastGasSoundTick", currentTick);
                    }
                    entity.addEffect("fatal_poison", 60, { amplifier: 2, showParticles: false });
                }
            }
        });
    });
}



function crushing_trap(data) {
    const { block, dimension } = data;
    const direction = block.permutation.getState("minecraft:cardinal_direction");
    let x = 0;
    let z = 0;

    switch (direction) {
        case 'north':
            x = 0;
            z = 1;
            break;
        case 'south':
            x = 0;
            z = -1;
            break;
        case 'west':
            x = 1;
            z = 0;
            break;
        case 'east':
            x = -1;
            z = 0;
            break;
    }
    const blockAir = dimension.getBlock({ x: block.location.x + x, y: block.location.y, z: block.location.z + z });
    if (blockAir && blockAir.typeId !== 'minecraft:air' && blockAir.typeId !== 'minecraft:barrier') return;
    const location = { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 };
    const directions = [
        { x: block.location.x + 1, y: block.location.y, z: block.location.z },
        { x: block.location.x - 1, y: block.location.y, z: block.location.z },
        { x: block.location.x, y: block.location.y + 1, z: block.location.z },
        { x: block.location.x, y: block.location.y - 1, z: block.location.z },
        { x: block.location.x, y: block.location.y, z: block.location.z + 1 },
        { x: block.location.x, y: block.location.y, z: block.location.z - 1 }
    ];

    let foundActive = false;

    for (const coords of directions) {
        const adjacentBlock = dimension.getBlock(coords);
        if (adjacentBlock) {
            const typeId = adjacentBlock.typeId;

            const isActive = (
                (typeId === 'minecraft:lever' && adjacentBlock.permutation.getState("open_bit")) ||
                (typeId === 'minecraft:observer' && adjacentBlock.permutation.getState("powered_bit")) ||
                (typeId === 'minecraft:daylight_detector' && adjacentBlock.permutation.getState("redstone_signal") > 0) ||
                (typeId === 'minecraft:daylight_detector_inverted' && adjacentBlock.permutation.getState("redstone_signal") > 0) ||
                (typeId === 'minecraft:redstone_wire' && adjacentBlock.permutation.getState("redstone_signal") > 0) ||
                typeId === 'minecraft:powered_repeater' ||
                typeId === 'minecraft:powered_comparator' ||
                (typeId === 'minecraft:redstone_torch' && (coords.y === block.location.y || coords.y === block.location.y - 1)) ||
                typeId === 'minecraft:redstone_block' ||
                (typeId.endsWith('_pressure_plate') && adjacentBlock.permutation.getState("redstone_signal") > 0)
            );
            if (isActive) {
                foundActive = true;
                const crushing_trap = dimension.getEntities({
                    type: "crafting_traps:crushing_trap_entity",
                    location: location,
                    minDistance: 0,
                    maxDistance: 0
                });
                if (crushing_trap.length === 0) {
                    crushing_trapPlace({ block, dimension });
                } else {
                    crushing_trap.forEach(entity => {
                        dimension.setBlockType({ x: block.location.x + x, y: block.location.y, z: block.location.z + z }, "minecraft:barrier");
                        entity.setProperty("crafting_traps:crushing_trap", true);
                        const hasPlayedSound = block.permutation.getState("crafting_traps:played_sound");
                        if (!hasPlayedSound) {
                            entity.runCommand(`playsound block.crushing_trap.on_off @a[r=4] ${block.location.x} ${block.location.y} ${block.location.z} 1 1`);
                            block.setPermutation(block.permutation.withState("crafting_traps:played_sound", true));
                        }
                        system.runTimeout(() => {
                            for (let yOffset = 0; yOffset >= -1; yOffset--) {
                                dimension.getEntities({
                                    excludeFamilies: ['inanimate'],
                                    minDistance: 0,
                                    maxDistance: 1,
                                    location: {
                                        x: block.location.x + x + 0.5,
                                        y: block.location.y + yOffset,
                                        z: block.location.z + z + 0.5
                                    }
                                }).forEach(entityDamage => {
                                    entityDamage.applyDamage(1);
                                });
                            }
                        }, 60);
                    });
                }
            }
        }
    }
    if (!foundActive) {
        const crushing_trap = dimension.getEntities({
            type: "crafting_traps:crushing_trap_entity",
            location: location,
            minDistance: 0,
            maxDistance: 0
        });
        if (crushing_trap.length === 0) {
            crushing_trapPlace({ block, dimension });
        } else {
            crushing_trap.forEach(entity => {
                const hasPlayedSound = block.permutation.getState("crafting_traps:played_sound");
                if (hasPlayedSound) {
                    entity.runCommand(`playsound block.crushing_trap.on_off @a[r=4] ${block.location.x} ${block.location.y} ${block.location.z} 1 1`);
                    block.setPermutation(block.permutation.withState("crafting_traps:played_sound", true));
                }
                block.setPermutation(block.permutation.withState("crafting_traps:played_sound", false));
                system.runTimeout(() => {
                    const barrier = dimension.getBlock({ x: block.location.x + x, y: block.location.y, z: block.location.z + z });
                    if (barrier && barrier.typeId === "minecraft:barrier") {
                        dimension.setBlockType({ x: block.location.x + x, y: block.location.y, z: block.location.z + z }, "minecraft:air");
                    }
                }, 60);
                entity.setProperty("crafting_traps:crushing_trap", false);
            });
        }
    }
}

function crushing_trapPlace(data) {
    const { block, dimension } = data;
    block.setPermutation(block.permutation.withState("crafting_traps:place", true));
    const location = { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 }
    const direction = block.permutation.getState("minecraft:cardinal_direction");
    let rotationY = 0;
    switch (direction) {
        case 'north':
            rotationY = 0;
            break;
        case 'south':
            rotationY = 1;
            break;
        case 'west':
            rotationY = 2;
            break;
        case 'east':
            rotationY = 3;
            break;
    }

    const entity = dimension.spawnEntity(`crafting_traps:crushing_trap_entity`, location);
    entity.setProperty("crafting_traps:rotation", rotationY);
}

function thief_trap(data) {
    const { block, dimension } = data;
    const location = { x: block.location.x + 0.5, y: block.location.y + 2, z: block.location.z + 0.5 };
    const thief = dimension.getEntities({
        location: location,
        minDistance: 0,
        maxDistance: 1
    });
    thief.forEach(entity => {
        const equipmentCompPlayer = entity.getComponent(EntityComponentTypes.Equippable);
        if (!equipmentCompPlayer) return;
        const heldItem = equipmentCompPlayer.getEquipment("Mainhand");
        if (heldItem) {
            const chestLocation = { x: block.location.x, y: block.location.y - 1, z: block.location.z };
            const chest = dimension.getBlock(chestLocation);
            const inventory = chest.getComponent("minecraft:inventory");
            if (!inventory) return;
            const container = inventory.container
            container.addItem(heldItem.clone());
            equipmentCompPlayer.setEquipment("Mainhand", null);
            entity.runCommand(`playsound block.thief_trap.step @a[r=4] ${block.location.x} ${block.location.y} ${block.location.z} 1 1`);
        }
    });
}


function handleItemUseOn(event) {
    const { itemStack: item, block, source } = event;
    if (item.typeId === "minecraft:bucket" && block.typeId === "minecraft:powder_snow") {
        const itemClone = item.clone();
        const inventory = source.getComponent("minecraft:inventory");
        for (let i = 0; i < inventory.container.size; i++) {
            const slot = inventory.container.getItem(i);
            if (slot.typeId === "minecraft:powder_snow_bucket") {
                inventory.container.setItem(i, null);
                break;
            }
        }
        inventory.container.setItem(source.selectedSlotIndex, itemClone);
    }
}

function onPlayerInteract(event) {
    const { block, player, dimension } = event;
    explosiveMineBlock2(dimension, player);
}

world.beforeEvents.worldInitialize.subscribe(initEvent => {
    const registry = initEvent.blockComponentRegistry;
    if (registry) {
        registry.registerCustomComponent('crafting_traps:onuse', {
            onPlayerInteract: onPlayerInteract
        });
        registry.registerCustomComponent('crafting_traps:onstep', {
            onStepOn: onstep
        });
        registry.registerCustomComponent('crafting_traps:onstepoff', {
            onStepOff: onstepOff
        });
        registry.registerCustomComponent('crafting_traps:crushing_trap', {
            onTick: crushing_trap
        });
        registry.registerCustomComponent('crafting_traps:thief_trap', {
            onTick: thief_trap
        });
        registry.registerCustomComponent('crafting_traps:crushing_trap_place', {
            onPlace: crushing_trapPlace
        });
    }
});

world.afterEvents.itemUseOn.subscribe(handleItemUseOn);

world.afterEvents.playerBreakBlock.subscribe((event) => {
    const { player, block, brokenBlockPermutation, dimension } = event;
    if (brokenBlockPermutation.type.id !== 'crafting_traps:crushing_trap') return;
    const direction = brokenBlockPermutation.getState("minecraft:cardinal_direction");
    let x = 0;
    let z = 0;
    switch (direction) {
        case 'north':
            x = 0;
            z = 1;
            break;
        case 'south':
            x = 0;
            z = -1;
            break;
        case 'west':
            x = 1;
            z = 0;
            break;
        case 'east':
            x = -1;
            z = 0;
            break;
    }
    const barrier = dimension.getBlock({ x: block.location.x + x, y: block.location.y, z: block.location.z + z });
    if (barrier && barrier.typeId === "minecraft:barrier") {
        dimension.setBlockType({ x: block.location.x + x, y: block.location.y, z: block.location.z + z }, "minecraft:air");
    }
    const location = { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 };
    const crushing_trap_entity = dimension.getEntities({
        type: "crafting_traps:crushing_trap_entity",
        location: location,
        minDistance: 0,
        maxDistance: 0
    });
    crushing_trap_entity.forEach(entity => {
        entity.remove();
    });
});

function spike() {
    const dimensions = ["overworld", "nether", "the_end"];
    dimensions.forEach(dimensionName => {
        const dimension = world.getDimension(dimensionName);
        dimension.getEntities().forEach(entity => {
            const y = entity.location.y;

            // Verificación de altura según la dimensión
            if ((entity.dimension.typeId === "minecraft:overworld" && y >= -63 && y <= 319) || 
                (entity.dimension.typeId !== "minecraft:overworld" && y >= 1 && y <= 125)) {
                
                const spikeBlock = dimension.getBlock({ x: entity.location.x, y: y, z: entity.location.z });
                let lastSoundTick = entity.getDynamicProperty("lastSpikeSoundTick") || 0;
                let currentTick = system.currentTick;

                if (spikeBlock && spikeBlock.typeId === 'zc:wooden_spike_trap') {
                    if (currentTick - lastSoundTick >= 10) {
                        entity.runCommand(`playsound block.spike.step @a[r=4] ${spikeBlock.location.x} ${spikeBlock.location.y} ${spikeBlock.location.z} 1 1`);
                        entity.setDynamicProperty("lastSpikeSoundTick", currentTick);
                    }
                    entity.applyDamage(1, { cause: "contact" });
                }

                if (spikeBlock && spikeBlock.typeId === 'zc:stone_spike_trap') {
                    if (currentTick - lastSoundTick >= 10) {
                        entity.runCommand(`playsound block.spike_poison.step @a[r=4] ${spikeBlock.location.x} ${spikeBlock.location.y} ${spikeBlock.location.z} 1 1`);
                        entity.setDynamicProperty("lastSpikeSoundTick", currentTick);
                    }
                    entity.addEffect("slowness", 3, { amplifier: 2, showParticles: false });
                    entity.applyDamage(2, { cause: "contact" });
                }
                if (spikeBlock && spikeBlock.typeId === 'zc:iron_spike_trap') {
                    if (currentTick - lastSoundTick >= 10) {
                        entity.runCommand(`playsound block.spike_poison.step @a[r=4] ${spikeBlock.location.x} ${spikeBlock.location.y} ${spikeBlock.location.z} 1 1`);
                        entity.setDynamicProperty("lastSpikeSoundTick", currentTick);
                    }
                    entity.addEffect("slowness", 3, { amplifier: 2, showParticles: false });
                    entity.applyDamage(3, { cause: "contact" });
                }
                if (spikeBlock && spikeBlock.typeId === 'zc:golden_spike_trap') {
                    if (currentTick - lastSoundTick >= 10) {
                        entity.runCommand(`playsound block.spike_poison.step @a[r=4] ${spikeBlock.location.x} ${spikeBlock.location.y} ${spikeBlock.location.z} 1 1`);
                        entity.setDynamicProperty("lastSpikeSoundTick", currentTick);
                    }
                    entity.addEffect("slowness", 3, { amplifier: 2, showParticles: false });
                    entity.applyDamage(4, { cause: "contact" });
                }
                if (spikeBlock && spikeBlock.typeId === 'zc:diamond_spike_trap') {
                    if (currentTick - lastSoundTick >= 10) {
                        entity.runCommand(`playsound block.spike_poison.step @a[r=4] ${spikeBlock.location.x} ${spikeBlock.location.y} ${spikeBlock.location.z} 1 1`);
                        entity.setDynamicProperty("lastSpikeSoundTick", currentTick);
                    }
                    entity.addEffect("slowness", 3, { amplifier: 2, showParticles: false });
                    entity.applyDamage(5, { cause: "contact" });
                }
                if (spikeBlock && spikeBlock.typeId === 'zc:netherite_spike_trap') {
                    if (currentTick - lastSoundTick >= 10) {
                        entity.runCommand(`playsound block.spike_poison.step @a[r=4] ${spikeBlock.location.x} ${spikeBlock.location.y} ${spikeBlock.location.z} 1 1`);
                        entity.setDynamicProperty("lastSpikeSoundTick", currentTick);
                    }
                    entity.addEffect("slowness", 3, { amplifier: 2, showParticles: false });
                    entity.applyDamage(6, { cause: "contact" });
                }
                if (spikeBlock && spikeBlock.typeId === 'zc:spikes') {
                    if (currentTick - lastSoundTick >= 10) {
                        entity.runCommand(`playsound block.spike_poison.step @a[r=4] ${spikeBlock.location.x} ${spikeBlock.location.y} ${spikeBlock.location.z} 1 1`);
                        entity.setDynamicProperty("lastSpikeSoundTick", currentTick);
                    }
                    entity.addEffect("slowness", 3, { amplifier: 3, showParticles: false });
                    entity.applyDamage(3, { cause: "contact" });
                }
                if (spikeBlock && spikeBlock.typeId === 'zc:electricity_fence') {
                    if (currentTick - lastSoundTick >= 10) {
                        entity.runCommand(`playsound block.spike_poison.step @a[r=4] ${spikeBlock.location.x} ${spikeBlock.location.y} ${spikeBlock.location.z} 1 1`);
                        entity.setDynamicProperty("lastSpikeSoundTick", currentTick);
                    }
                    entity.addEffect("slowness", 4, { amplifier: 2, showParticles: false });
                    entity.applyDamage(4, { cause: "contact" });
                }
                if (spikeBlock && spikeBlock.typeId === 'zc:barbed_wire') {
                    if (currentTick - lastSoundTick >= 10) {
                        entity.runCommand(`playsound block.spike_poison.step @a[r=4] ${spikeBlock.location.x} ${spikeBlock.location.y} ${spikeBlock.location.z} 1 1`);
                        entity.setDynamicProperty("lastSpikeSoundTick", currentTick);
                    }
                    entity.addEffect("slowness", 5, { amplifier: 3, showParticles: false });
                    entity.applyDamage(3, { cause: "contact" });
                }
            }
        });
    });
}


function quicksand() {
    const dimensions = ["overworld", "nether", "the_end"];
    dimensions.forEach(dimensionName => {
        const dimension = world.getDimension(dimensionName);
        dimension.getEntities().forEach(entity => {
            if (entity.typeId === 'minecraft:player' && entity.getGameMode() !== "survival") return;
            const y = entity.location.y;

            // Verificación de altura según la dimensión
            if ((entity.dimension.typeId === "minecraft:overworld" && y >= -63 && y <= 319) || 
                (entity.dimension.typeId !== "minecraft:overworld" && y >= 1 && y <= 125)) {
                
                const headLocation = entity.getHeadLocation();
                const quicksandBlockBelow = dimension.getBlock({ x: entity.location.x, y: y - 0.02, z: entity.location.z });
                const quicksandBlockAt = dimension.getBlock({ x: entity.location.x, y: y, z: entity.location.z });

                if (quicksandBlockBelow && quicksandBlockBelow.typeId === 'crafting_traps:quicksand') {
                    const newY = y - 0.02;
                    entity.teleport({ x: entity.location.x, y: newY, z: entity.location.z });
                }

                if (quicksandBlockAt && quicksandBlockAt.typeId === 'crafting_traps:quicksand') {
                    const airBlockAboveHead = dimension.getBlock({ x: headLocation.x, y: headLocation.y, z: headLocation.z });
                    if (!airBlockAboveHead || airBlockAboveHead.typeId !== 'minecraft:air') {
                        let lastSoundTick = entity.getDynamicProperty("lastQuicksandSoundTick") || 0;
                        let currentTick = system.currentTick;
                        if (currentTick - lastSoundTick >= 10) {
                            system.runTimeout(() => {
                                if (entity) {
                                    entity.runCommand(`playsound block.quicksand.sink @a[r=4] ${entity.location.x} ${entity.location.y} ${entity.location.z} 1 1`);
                                }
                            }, 10);
                            entity.setDynamicProperty("lastQuicksandSoundTick", currentTick);
                        }
                        entity.addEffect("darkness", 20, { amplifier: 255, showParticles: false });
                        entity.addEffect("blindness", 80, { amplifier: 255, showParticles: false });
                        entity.applyDamage(1, { cause: "contact" });
                    }
                }
            }
        });
    });
}


function explosiveMine() {
    const dimensions = ["overworld", "nether", "the_end"];
    dimensions.forEach(dimensionName => {
        const dimension = world.getDimension(dimensionName);
        dimension.getEntities().forEach(entity => {
            const y = entity.location.y;

            // Verificación de altura según la dimensión
            if ((entity.dimension.typeId === "minecraft:overworld" && y >= -63 && y <= 319) || 
                (entity.dimension.typeId !== "minecraft:overworld" && y >= 1 && y <= 125)) {
                
                const mineBlock = dimension.getBlock({ x: entity.location.x, y: y, z: entity.location.z });
                if (mineBlock && mineBlock.typeId === 'zc:landmine') {
                    entity.runCommand(`playsound block.mine.beep @a[r=4] ${mineBlock.location.x} ${mineBlock.location.y} ${mineBlock.location.z} 1 1`);
                    const mineDummy = dimension.spawnEntity("zc:landmine_dummy", {
                        x: entity.location.x,
                        y: entity.location.y,
                        z: entity.location.z
                    });
                }
            }
        });
    });
}


function explosiveMineBlock2(dimension, player) {
    player.runCommand(`playsound block.mine.beep @a[r=4] ${player.location.x} ${player.location.y} ${player.location.z} 1 1`);
    const mineDummy = dimension.spawnEntity("crafting_traps:minedummy", {
        x: player.location.x,
        y: player.location.y,
        z: player.location.z
    });
}

function explosiveMineBlock(dimension, entity) {
    entity.runCommand(`playsound block.mine.beep @a[r=4] ${entity.location.x} ${entity.location.y} ${entity.location.z} 1 1`);
    const mineDummy = dimension.spawnEntity("crafting_traps:minedummy", {
        x: entity.location.x,
        y: entity.location.y,
        z: entity.location.z
    });
}

system.runInterval(() => {
    replaceMissingBlocks();
    gas();
    spike();
    quicksand();
    explosiveMine();
});

/**
 * Start oxidization process
 */
Oxidise();
world.afterEvents.entityHurt.subscribe(Combat);
world.afterEvents.playerBreakBlock.subscribe(({ player, itemStackAfterBreak }) => DamageItem(player, itemStackAfterBreak));
world.afterEvents.itemUseOn.subscribe(({ source, itemStack }) => DamageItem(source, itemStack));

const BOOMERANG_REPLACEMENTS_BLAZING = {
    "rev:diamond_boomerang_item": "rev:diamond_boomerang_blazing_item",
    "rev:diamond_boomerang_sharp_item": "rev:diamond_boomerang_blazing_item",
    "rev:diamond_boomerang_striking_item": "rev:diamond_boomerang_blazing_item",
    "rev:golden_boomerang_item": "rev:golden_boomerang_blazing_item",
    "rev:golden_boomerang_sharp_item": "rev:golden_boomerang_blazing_item",
    "rev:golden_boomerang_striking_item": "rev:golden_boomerang_blazing_item",
    "rev:netherite_boomerang_item": "rev:netherite_boomerang_blazing_item",
    "rev:netherite_boomerang_sharp_item": "rev:netherite_boomerang_blazing_item",
    "rev:netherite_boomerang_striking_item": "rev:netherite_boomerang_blazing_item",
    "rev:iron_boomerang_item": "rev:iron_boomerang_blazing_item",
    "rev:iron_boomerang_sharp_item": "rev:iron_boomerang_blazing_item",
    "rev:iron_boomerang_striking_item": "rev:iron_boomerang_blazing_item",
    "rev:stone_boomerang_item": "rev:stone_boomerang_blazing_item",
    "rev:stone_boomerang_sharp_item": "rev:stone_boomerang_blazing_item",
    "rev:stone_boomerang_striking_item": "rev:stone_boomerang_blazing_item",
    "rev:wooden_boomerang_item": "rev:wooden_boomerang_blazing_item",
    "rev:wooden_boomerang_striking_item": "rev:wooden_boomerang_blazing_item",
    "rev:wooden_boomerang_sharp_item": "rev:wooden_boomerang_blazing_item",
};

const BOOMERANG_REPLACEMENTS_SHARP = {
    "rev:diamond_boomerang_item": "rev:diamond_boomerang_sharp_item",
    "rev:diamond_boomerang_blazing_item": "rev:diamond_boomerang_sharp_item",
    "rev:diamond_boomerang_striking_item": "rev:diamond_boomerang_sharp_item",
    "rev:golden_boomerang_item": "rev:golden_boomerang_sharp_item",
    "rev:golden_boomerang_blazing_item": "rev:golden_boomerang_sharp_item",
    "rev:golden_boomerang_striking_item": "rev:golden_boomerang_sharp_item",
    "rev:netherite_boomerang_item": "rev:netherite_boomerang_sharp_item",
    "rev:netherite_boomerang_blazing_item": "rev:netherite_boomerang_sharp_item",
    "rev:netherite_boomerang_striking_item": "rev:netherite_boomerang_sharp_item",
    "rev:iron_boomerang_item": "rev:iron_boomerang_sharp_item",
    "rev:iron_boomerang_blazing_item": "rev:iron_boomerang_sharp_item",
    "rev:iron_boomerang_striking_item": "rev:iron_boomerang_sharp_item",
    "rev:stone_boomerang_item": "rev:stone_boomerang_sharp_item",
    "rev:stone_boomerang_blazing_item": "rev:stone_boomerang_sharp_item",
    "rev:stone_boomerang_striking_item": "rev:stone_boomerang_sharp_item",
    "rev:wooden_boomerang_item": "rev:wooden_boomerang_sharp_item",
    "rev:wooden_boomerang_striking_item": "rev:wooden_boomerang_sharp_item",
    "rev:wooden_boomerang_blazing_item": "rev:wooden_boomerang_sharp_item",
};

const BOOMERANG_REPLACEMENTS_STRIKING = {
    "rev:diamond_boomerang_item": "rev:diamond_boomerang_striking_item",
    "rev:diamond_boomerang_sharp_item": "rev:diamond_boomerang_striking_item",
    "rev:diamond_boomerang_blazing_item": "rev:diamond_boomerang_striking_item",
    "rev:golden_boomerang_item": "rev:golden_boomerang_striking_item",
    "rev:golden_boomerang_sharp_item": "rev:golden_boomerang_striking_item",
    "rev:golden_boomerang_blazing_item": "rev:golden_boomerang_striking_item",
    "rev:netherite_boomerang_item": "rev:netherite_boomerang_striking_item",
    "rev:netherite_boomerang_sharp_item": "rev:netherite_boomerang_striking_item",
    "rev:netherite_boomerang_blazing_item": "rev:netherite_boomerang_striking_item",
    "rev:iron_boomerang_item": "rev:iron_boomerang_striking_item",
    "rev:iron_boomerang_sharp_item": "rev:iron_boomerang_striking_item",
    "rev:iron_boomerang_blazing_item": "rev:iron_boomerang_striking_item",
    "rev:stone_boomerang_item": "rev:stone_boomerang_striking_item",
    "rev:stone_boomerang_sharp_item": "rev:stone_boomerang_striking_item",
    "rev:stone_boomerang_blazing_item": "rev:stone_boomerang_striking_item",
    "rev:wooden_boomerang_item": "rev:wooden_boomerang_striking_item",
    "rev:wooden_boomerang_blazing_item": "rev:wooden_boomerang_striking_item",
    "rev:wooden_boomerang_sharp_item": "rev:wooden_boomerang_striking_item",
};

world.afterEvents.itemUse.subscribe(result =>
{
    if (result.itemStack.typeId.includes('rev') && result.itemStack.typeId.includes('boomerang'))
    {
        const player = result.source;
        const itemName = result.itemStack.typeId;
        const projectile = itemName.split('_item')[0];
        const cooldown = result.itemStack.getComponent('minecraft:cooldown').cooldownTicks;
        const cooldownRemaining = result.itemStack.getComponent('minecraft:cooldown').getCooldownTicksRemaining(player);
        const enchant = result.itemStack?.getComponent("minecraft:enchantable");
        const level = enchant?.getEnchantment("multishot")?.level ?? 0;
        const levelPiercing = enchant?.getEnchantment("piercing")?.level ?? 0;
        const levelCharge = enchant?.getEnchantment("quick_charge")?.level ?? 0;
        let power = 4;

        if (!player.hasTag('boomTip')) { player.sendMessage(''); player.addTag('boomTip')}
        

        if (Math.abs(cooldown - cooldownRemaining) <= (1 + levelCharge * 5.4))
        {
            power += Math.round(levelPiercing * 1.4)

            const boomerang = shootProjectile(world, player, projectile, power, 0)
            boomerang.getComponent('projectile').owner = player;

            if (enchant && level > 0)
            {
                const boomerang2 = shootProjectile(world, player, projectile, power, 0.6)
                boomerang2.getComponent('projectile').owner = player;
                const boomerang3 = shootProjectile(world, player, projectile, power, -0.6)
                boomerang3.getComponent('projectile').owner = player;
            }
            damageItem(player, 1 + level + Math.floor(levelCharge / 2))
        }
       

    }
});

world.afterEvents.itemUseOn.subscribe(result =>
    {
        const block = result.block;
        const item = result.itemStack;
        const player = result.source;
       
        if (block.typeId == 'minecraft:cauldron' && item.typeId.includes('boomerang'))
        {
            const state = block.permutation.getState("cauldron_liquid")
            if(state == "lava"){
                const newForm = new ui.ActionFormData()
                        .title("§6§l- Boomerang Perks -")
                        .body('§7Select an option\n==============================\n§6Blazing:§r Your boomerang will set fire to entities and blocks it hits. Requieres 4 of Blaze Powder\n==============================\n§5Striking:§r Your boomerang will knockback entities around the area it hits. Requieres 4 of Amethyst Shard\n==============================\n§bSharp:§r Your boomerang will deal increased damage. Requieres 4 Iron Ingots\n==============================')
                        .button("§6Blazing")
                        .button("§5Striking")
                        .button("§bSharp")
                        .show(player)
                newForm.then(fulFilled => {
                let selectionNew = fulFilled.selection;
                switch (selectionNew) {
                    case 0:
                        if (player.runCommand('testfor @s[hasitem={item=blaze_powder,quantity=4..}]').successCount>0)
                        {
                            player.runCommand('clear @s blaze_powder 0 4')
                            transformItem(item,BOOMERANG_REPLACEMENTS_BLAZING,player)
                            player.playSound('bucket.fill_lava',{location:player.location})
                            player.playSound('random.anvil_use',{location:player.location})
                            player.dimension.spawnParticle('minecraft:lava_particle',block.bottomCenter())
                            player.dimension.spawnParticle('minecraft:lava_particle',block.bottomCenter())
                            player.dimension.spawnParticle('minecraft:lava_particle',block.bottomCenter())
                            player.dimension.spawnParticle('minecraft:campfire_smoke_particle',block.bottomCenter())
                        }
                        else
                        {
                            player.sendMessage(`§4You don't have enought Blaze Powder`)
                        }
                    break;
                    case 1:
                        if (player.runCommand('testfor @s[hasitem={item=amethyst_shard,quantity=4..}]').successCount>0)
                        {
                            player.runCommand('clear @s amethyst_shard 0 4')
                            transformItem(item,BOOMERANG_REPLACEMENTS_STRIKING,player)
                            player.playSound('bucket.fill_lava',{location:player.location})
                            player.playSound('random.anvil_use',{location:player.location})
                            player.dimension.spawnParticle('minecraft:lava_particle',block.bottomCenter())
                            player.dimension.spawnParticle('minecraft:lava_particle',block.bottomCenter())
                            player.dimension.spawnParticle('minecraft:lava_particle',block.bottomCenter())
                            player.dimension.spawnParticle('minecraft:campfire_smoke_particle',block.bottomCenter())
                        }
                        else
                        {
                            player.sendMessage(`§4You don't have enought Amethyst Shards`)
                        }
                    break;
                    case 2:
                        if (player.runCommand('testfor @s[hasitem={item=iron_ingot,quantity=4..}]').successCount>0)
                        {
                            player.runCommand('clear @s iron_ingot 0 4')
                            transformItem(item,BOOMERANG_REPLACEMENTS_SHARP,player)
                            player.playSound('bucket.fill_lava',{location:player.location})
                            player.playSound('random.anvil_use',{location:player.location})
                            player.dimension.spawnParticle('minecraft:lava_particle',block.bottomCenter())
                            player.dimension.spawnParticle('minecraft:lava_particle',block.bottomCenter())
                            player.dimension.spawnParticle('minecraft:lava_particle',block.bottomCenter())
                            player.dimension.spawnParticle('minecraft:campfire_smoke_particle',block.bottomCenter())
                        }
                        else
                        {
                            player.sendMessage(`§4You don't have enought Iron Ingots`)
                        }
                    break;

                }
                })
            }
            else
            {
                player.sendMessage('§4The Cauldron needs to be filled with lava')
            }
           
        }
       
    });

server.system.runInterval(() =>
{
    const dimension = world.getDimension('overworld');
    const entities = dimension.getEntities();
    entities.forEach(e =>
    {
        if (e.hasTag('returning') && e.typeId.includes('rev') && e.typeId.includes('boomerang'))
        try
        {
            if (!e.typeId.includes('dummy'))
            
            {
                const projectile = 'rev:dummy_'+e.typeId.split("rev:")[1];
                const dummy =  e.dimension.spawnEntity(projectile,e.location)
                dummy.getComponent("minecraft:projectile").owner = e.getComponent('projectile').owner;
                dummy.addTag('returning')
                dummy.setDynamicProperty('rev:power',e.getDynamicProperty('rev:power'))
                e.remove()
                return;
            }

            e.runCommand('tp @e[type=item,r=3] @s');
            e.runCommand('tp @e[type=xp_orb,r=3] @s')
            e.runCommand(`tp @s ^${1+((e.getDynamicProperty('rev:power')-3)/14)} ^ ^${1+((e.getDynamicProperty('rev:power')-3)/14)} facing ${e.getComponent('projectile').owner.nameTag}`)
            if (e.runCommand(`testfor @a[name=${e.getComponent('projectile').owner.nameTag},r=${1+((e.getDynamicProperty('rev:power')-3)/8)}]`).successCount > 0)
            {
                e.dimension.playSound('random.pop', e.location,
                {
                    volume: 0.5
                })
                e.runCommand(`tp @e[type=item,r=4] @p[name=${e.getComponent('projectile').owner.nameTag}]`)
                e.remove()
            }
        }
        catch {e.remove()}
    });
}, 1);


function damageItem(player, damage)
{
    const fakeSwing = Math.floor(Math.random() * 100)
    const equipment = player.getComponent('equippable');
    const item = equipment.getEquipment('Mainhand');
    const inventory = player.getComponent('inventory').container
    const durability = item.getComponent('durability')
    const enchant = item?.getComponent("minecraft:enchantable");
    const level = enchant?.getEnchantment("unbreaking")?.level ?? 0;

    if (item && durability)
    {
        item.setDynamicProperty('rev:swing', fakeSwing)

        if ((durability.maxDurability - durability.damage - damage) <= 0)
        {
            inventory.setItem(player.selectedSlotIndex);
            player.playSound('random.break')
        }

        if (item && level == 0)
        {
            durability.damage += damage;
            inventory.setItem(player.selectedSlotIndex, item);
        }

        if (item && level > 0)
        {
            const rng = Math.floor(Math.random() * 5)
            durability.damage += rng <= level ? 0 : 1;
            inventory.setItem(player.selectedSlotIndex, item);
        }
    }


}

function shootProjectile(world, playerData, projectile, power, multishotBonus)
{
    let projectileToShoot = playerData.dimension.spawnEntity(projectile,
    {
        x: playerData.location.x + (playerData.getViewDirection().x * 2),
        y: playerData.location.y + 1.3 + (playerData.getViewDirection().y * 2),
        z: playerData.location.z + (playerData.getViewDirection().z * 2)
    })
    let projectileComp = projectileToShoot.getComponent("minecraft:projectile");
    projectileComp.owner = playerData;
    projectileComp.shoot(
    {
        x: playerData.getViewDirection().x * power + multishotBonus,
        y: playerData.getViewDirection().y * power,
        z: playerData.getViewDirection().z * power + multishotBonus
    });
    projectileToShoot.setDynamicProperty('rev:power',power)
    playerData.playAnimation('animation.obo.fake_swing')
    return projectileToShoot;
}

function transformItem(heldItem,BOOMERANG_REPLACEMENTS,player){
    try
    {
        const inventory = player.getComponent('inventory').container
        const enchantArray = heldItem.getComponent("enchantable").getEnchantments();
        const itemReplacement = new ItemStack(BOOMERANG_REPLACEMENTS[heldItem.typeId])
        const dynamicProperties = heldItem.getDynamicPropertyIds()
        itemReplacement.getComponent("enchantable").addEnchantments(enchantArray);
        itemReplacement.getComponent('durability').damage = heldItem.getComponent("durability").damage;
        itemReplacement.nameTag = heldItem.nameTag
        itemReplacement.setLore(heldItem.getLore()) 
        for (let i = 0; i < dynamicProperties.length; i++)
        {
            const currentPropertyValue = heldItem.getDynamicProperty(dynamicProperties[i])
            itemReplacement.setDynamicProperty(dynamicProperties[i],currentPropertyValue)
        }
        inventory.setItem(player.selectedSlotIndex,itemReplacement)
    } 
    catch (ex){}        
}