import { world,ItemStack,MolangVariableMap,BlockPermutation,GameMode,system,EntityDamageCause} from "@minecraft/server";
import { getScore } from "../utils/score";


const wood = ["edx:redwood_log","edx:redwood_wood"]
const strippedWood = ["edx:redwood_stripped_log","edx:redwood_stripped_wood"]

function isFamily(family,entity) {
    return entity?.getComponent('minecraft:type_family')?.hasTypeFamily(family)
  }

//rebel459 template <3
export function Damage(player,itemUsed)
{
    if (!itemUsed || player.matches({ gameMode: GameMode.Creative })) return;

        // This retrieves the player's equippable component.
        const playerEquippableComp = player.getComponent("equippable");

        // This returns if playerEquippableComp is undefined.
        if (!playerEquippableComp) return;

        // This retrieves the enchantable component of the item.
        const itemEnchantmentComp = itemUsed.getComponent("minecraft:enchantable");
        const unbreakingLevel = itemEnchantmentComp?.getEnchantment("unbreaking")?.level ?? 0;

        // Calculates the chance of an item breaking based on its unbreaking level. This is the vanilla unbreaking formula.
        const breakChance = 100 / (unbreakingLevel + 1);
        // Generates a random chance value between 0 and 100.
        const randomizeChance = Math.random() * 100;

        // This returns if breakChance is less than randomizeChance.
        if (breakChance < randomizeChance) return;

        // This retrieves the durability component of the item.
        const itemUsedDurabilityComp = itemUsed.getComponent("durability");

        // This returns if itemUsedDurabilityComp is undefined.
        if (!itemUsedDurabilityComp) return;

        // This will set the new durability value.
        itemUsedDurabilityComp.damage += 1;

        // Declares and checks if the item is out of durability
        const maxDurability = itemUsedDurabilityComp.maxDurability
        const currentDamage = itemUsedDurabilityComp.damage
        const newItem = player.getComponent("equippable").getEquipment('Mainhand');
        if (currentDamage >= maxDurability && newItem.typeId == itemUsed.typeId) {

            // If the item is out of durability, plays the item breaking sound and removes the item
            player.playSound('random.break', { pitch: 1, location: player.location, volume: 1 })
            playerEquippableComp.setEquipment("Mainhand", new ItemStack('minecraft:air', 1));
        }
        else if (currentDamage < maxDurability) {

            // This sets the item in the player's selected slot.
            playerEquippableComp.setEquipment("Mainhand", itemUsed);
        }
    
}
system.beforeEvents.startup.subscribe(eventData => {
    eventData.itemComponentRegistry.registerCustomComponent('edx:deceit_sword1', {
        onHitEntity(event) {
            const mob = event.hitEntity ;
            const item = event.itemStack
            const playerEquippableComp = event.attackingEntity.getComponent("equippable");
            const itemEnchantmentComp = item.getComponent("minecraft:enchantable");
            const enchant = itemEnchantmentComp.getEnchantments()
            if ((isFamily('mob', mob) === true)) {
            let health = mob.getComponent("health")
            if (health.currentValue === 0)
            {
                if (item?.getDynamicProperty("kill") === undefined) 
                {
                    item.setDynamicProperty("kill", 1)
                    item.setLore([
                        `${item.getDynamicProperty("kill")}/16`
                    ]);
                    item.nameTag = "§rBaby Deceit Sword"
                }
                else
                {
                    item.setDynamicProperty("kill", item.getDynamicProperty("kill")+1);
                    item.setLore([
                        `${item.getDynamicProperty("kill")}/16`
                    ]);
                }
                const dura = item.getComponent("durability");
                if(dura.damage<=25 )
                {
                    dura.damage -= dura.damage
                }
                else 
                {
                    dura.damage -= 25;
                }
                event.attackingEntity.addEffect('regeneration', 100, {amplifier: 0})
            }
            }
            playerEquippableComp.setEquipment("Mainhand", item);
            
            if (item.getDynamicProperty("kill") > 15)
            {
                var itemStack = new ItemStack ("edx:deceit_sword2",1)
                itemStack.getComponent("minecraft:enchantable").addEnchantments(enchant)
                playerEquippableComp.setEquipment("Mainhand", itemStack);
                world.getDimension(event.attackingEntity.dimension.id).spawnParticle('edx:burper_grow',event.attackingEntity.getHeadLocation());
                event.attackingEntity.dimension.playSound('mob.burper.grow',event.attackingEntity.location,{pitch: 1 ,});
            }
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:deceit_sword2', {
        onHitEntity(event) {
            const mob = event.hitEntity ;
            const item = event.itemStack
            const playerEquippableComp = event.attackingEntity.getComponent("equippable");
            const itemEnchantmentComp = item.getComponent("minecraft:enchantable");
            const enchant = itemEnchantmentComp.getEnchantments()
            if ((isFamily('mob', mob) === true)) {
            let health = mob.getComponent("health")
            if (health.currentValue === 0)
            {
                if (item?.getDynamicProperty("kill2") === undefined) 
                    {
                    item.setDynamicProperty("kill2", 1)
                    item.setLore([
                        `${item.getDynamicProperty("kill2")}/32`
                    ]);
                    item.nameTag = "§rKid Deceit Sword"
                    }
                else
                {
                    item.setDynamicProperty("kill2", item.getDynamicProperty("kill2")+1);
                    item.setLore([
                        `${item.getDynamicProperty("kill2")}/32`
                    ]);
                }
        
                const dura = item.getComponent("durability");
                if(dura.damage<=25 )
                {
                    dura.damage -= dura.damage
                }
                else {
                    dura.damage -= 25;
                }
                event.attackingEntity.addEffect('regeneration', 150, {amplifier: 0})
            }
            }
            playerEquippableComp.setEquipment("Mainhand", item);
            
            if (item.getDynamicProperty("kill2") > 31)
            {   
                var itemStack = new ItemStack ("edx:deceit_sword3",1)
                itemStack.getComponent("minecraft:enchantable").addEnchantments(enchant)
                playerEquippableComp.setEquipment("Mainhand", itemStack);
                world.getDimension(event.attackingEntity.dimension.id).spawnParticle('edx:burper_grow',event.attackingEntity.getHeadLocation());
                event.attackingEntity.dimension.playSound('mob.burper.grow',event.attackingEntity.location,{pitch: 1 ,});
            }
    
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:deceit_sword3', {
        onHitEntity(event) {
            const mob = event.hitEntity ;
            const item = event.itemStack
            const playerEquippableComp = event.attackingEntity.getComponent("equippable");
            const itemEnchantmentComp = item.getComponent("minecraft:enchantable");
            const enchant = itemEnchantmentComp.getEnchantments()
            if ((isFamily('mob', mob) === true)) {
            let health = mob.getComponent("health")
            if (health.currentValue === 0)
            {
                if (item?.getDynamicProperty("kill3") === undefined) 
                {
                    item.setDynamicProperty("kill3", 1)
                    item.setLore([
                        `${item.getDynamicProperty("kill3")}/64`
                    ]);
                    item.nameTag = "§rAdult Deceit Sword"
                }
                else
                {
                    item.setDynamicProperty("kill3", item.getDynamicProperty("kill3")+1);
                    item.setLore([
                        `${item.getDynamicProperty("kill3")}/64`
                    ]);
                }
                const dura = item.getComponent("durability");
                if(dura.damage<=25 )
                {
                    dura.damage -= dura.damage
                }
                else {
                    dura.damage -= 25;
                }
            event.attackingEntity.addEffect('regeneration', 200, {amplifier: 0})
            }
            }
            playerEquippableComp.setEquipment("Mainhand", item);
                
            if (item.getDynamicProperty("kill3") > 63)
            {   
                var itemStack = new ItemStack ("edx:deceit_sword4",1)
                itemStack.getComponent("minecraft:enchantable").addEnchantments(enchant)
                playerEquippableComp.setEquipment("Mainhand", itemStack);
                world.getDimension(event.attackingEntity.dimension.id).spawnParticle('edx:burper_grow',event.attackingEntity.getHeadLocation());
                event.attackingEntity.dimension.playSound('mob.burper.grow',event.attackingEntity.location,{pitch: 1 ,});
            }
        
        }
    })
        eventData.itemComponentRegistry.registerCustomComponent('edx:deceit_sword4', {
        onHitEntity(event) {
            const mob = event.hitEntity ;
            const item = event.itemStack
            const playerEquippableComp = event.attackingEntity.getComponent("equippable");
            if ((isFamily('mob', mob) === true)) {
            let health = mob.getComponent("health")
            if (health.currentValue === 0)
            {
                const dura = item.getComponent("durability");
                if(dura.damage<=25 )
                {
                    dura.damage -= dura.damage
                }
                else {
                    dura.damage -= 25;
                }
            event.attackingEntity.addEffect('regeneration', 250, {amplifier: 0})
            playerEquippableComp.setEquipment("Mainhand", item);
            }
            }
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:personal_vender_place', {
        onUseOn: ({source,itemStack,block,blockFace}) => {
            const rotation = source.getRotation();
            const equipment = source.getComponent('equippable');
            var trueBlock=blockFace=='Down'?block.below():blockFace=='Up'?block.above():blockFace=='East'?block.east():blockFace=='West'?block.west():blockFace=='North'?block.north():block.south()
            let entity = world.getDimension(block.dimension.id).spawnEntity("edx:personal_vender",trueBlock.bottomCenter());
            entity.setDynamicProperty("owner", source.name);
            entity.setDynamicProperty("welcome_text", "Boredom");
            entity.setDynamicProperty("open", false);
            entity.setDynamicProperty("price", 1);
            entity.setDynamicProperty("coin_type", 0);
            entity.setDynamicProperty("item_amount", 0);
            entity.setDynamicProperty("item_id", "edx:boredom");
            entity.setDynamicProperty("item_name", "Boredom");
            entity.setDynamicProperty("item_type", "Item");//block ou item
            entity.setDynamicProperty("coin_amount", 0);
            entity.setRotation({x:Math.round(rotation.x/ 45)*45,y:Math.round(rotation.y/ 45)*45})
            decreaseItemStack(source,equipment,itemStack)
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:training_dummy', {
        onUseOn: ({source,itemStack,block,blockFace}) => {
            const rotation = source.getRotation();
            const equipment = source.getComponent('equippable');
            var trueBlock=blockFace=='Down'?block.below():blockFace=='Up'?block.above():blockFace=='East'?block.east():blockFace=='West'?block.west():blockFace=='North'?block.north():block.south()
            let entity = world.getDimension(block.dimension.id).spawnEntity("edx:training_dummy",trueBlock.bottomCenter());
            entity.setRotation({x:Math.round(rotation.x/ 45)*45,y:Math.round(rotation.y/ 45)*45})
            decreaseItemStack(source,equipment,itemStack)
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:durability', {
        onMineBlock: ({source,itemStack}) => {
            Damage(source,itemStack)
        }
    })
        eventData.itemComponentRegistry.registerCustomComponent('edx:dashing_stick', {
        onUse: ({source,itemStack}) => {
        if (source.isOnGround && getScore(source,'dash') === 0 ) {
            if (source.hasTag("void_socks")) {
            var power =Math.sqrt(source.getViewDirection().x ** 2 + source.getViewDirection().z ** 2)*9
            source.applyKnockback({x:source.getViewDirection().x*power,z: source.getViewDirection().z*power}, source.getViewDirection().y*1.3)
            source.runCommand(`playanimation @s animation.player.dashing_stick_use `)
            Damage(source,itemStack)
            source.runCommand(`scoreboard players set @s dash 30`)
            }
            else {
        source.runCommand(`scoreboard players set @s dash 40`)
        var power =Math.sqrt(source.getViewDirection().x ** 2 + source.getViewDirection().z ** 2)*6
        source.applyKnockback({x:source.getViewDirection().x*power,z: source.getViewDirection().z*power}, source.getViewDirection().y*1.3)
        source.runCommand(`playanimation @s animation.player.dashing_stick_use `)
         Damage(source,itemStack)
            }
        }
        else { 
            if (source.isOnGround===false)
            {source.runCommand(`titleraw @s actionbar  { "rawtext": [ { "translate": "action.interact.dashing_stick" }]}`)}
        }
        }
    })
        eventData.itemComponentRegistry.registerCustomComponent('edx:soul_dashing_stick', {
        onUse: ({source,itemStack}) => {
        if (source.isOnGround && getScore(source,'dash') === 0 ) {
            if (source.hasTag("void_socks")) {
            var power =Math.sqrt(source.getViewDirection().x ** 2 + source.getViewDirection().z ** 2)*14
            source.applyKnockback({x:source.getViewDirection().x*power,z: source.getViewDirection().z*power}, source.getViewDirection().y*1.3)
            source.runCommand(`playanimation @s animation.player.dashing_stick_use `)
            Damage(source,itemStack)
                    const vmap = new MolangVariableMap(); 
        vmap.setVector3('variable.direction', source.getViewDirection());
        source.dimension.spawnParticle('edx:soul_fire_breath',{x:source.getHeadLocation().x+source.getViewDirection().x/4,y:source.getHeadLocation().y+source.getViewDirection().y/4,z:source.getHeadLocation().z+source.getViewDirection().z/4},vmap);
        const entityOptions = {
        location: ({x:source.location.x-source.getViewDirection().x*2 ,y:source.location.y-source.getViewDirection().y*2 ,z:source.location.z-source.getViewDirection().z*2 }),
        families: [ "mob" ],
        excludeFamilies: [ "player","summoned","tamed" ],
        maxDistance: 3
                }
                const entities = source.dimension.getEntities(entityOptions);
                for (let i = 0; i < entities.length ; i++) {
                    if(entities[i]!=source )
                        entities[i]?.applyDamage(15,{cause: "fire"})
                        entities[i]?.setOnFire(10);
                entities[i]?.applyKnockback({x:source.getViewDirection().x*-power,z: source.getViewDirection().z*-power}, source.getViewDirection().y*-1.3)
                }
            source.runCommand(`scoreboard players set @s dash 15`)
            }
            else {
        source.runCommand(`scoreboard players set @s dash 20`)
        var power =Math.sqrt(source.getViewDirection().x ** 2 + source.getViewDirection().z ** 2)*11
        source.applyKnockback({x:source.getViewDirection().x*power,z: source.getViewDirection().z*power}, source.getViewDirection().y*1.3)
        source.runCommand(`playanimation @s animation.player.dashing_stick_use `)
        Damage(source,itemStack)
        const vmap = new MolangVariableMap(); 
        vmap.setVector3('variable.direction', source.getViewDirection());
        source.dimension.spawnParticle('edx:soul_fire_breath',{x:source.getHeadLocation().x+source.getViewDirection().x/4,y:source.getHeadLocation().y+source.getViewDirection().y/4,z:source.getHeadLocation().z+source.getViewDirection().z/4},vmap);
        const entityOptions = {
        location: ({x:source.location.x-source.getViewDirection().x*2 ,y:source.location.y-source.getViewDirection().y*2 ,z:source.location.z-source.getViewDirection().z*2 }),
        families: [ "mob" ],
        excludeFamilies: [ "player","summoned","tamed" ],
        maxDistance: 3
                }
                const entities = source.dimension.getEntities(entityOptions);
                for (let i = 0; i < entities.length ; i++) {
                    if(entities[i]!=source )
                        entities[i]?.applyDamage(15,{cause: "fire"})
                        entities[i]?.setOnFire(10);
                entities[i]?.applyKnockback({x:source.getViewDirection().x*-power,z: source.getViewDirection().z*-power}, source.getViewDirection().y*-1.3)
                }
            }
        }
        else { 
            if (source.isOnGround===false)
            {source.runCommand(`titleraw @s actionbar  { "rawtext": [ { "translate": "action.interact.dashing_stick" }]}`)}
        }
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:axe_stripping', {
        onUseOn: ({source,itemStack,block}) => {
            if(wood.includes(block.typeId))
            {
                const permutations = block.permutation.getAllStates()
                block.setType(strippedWood[wood.indexOf(block.typeId)])
                block.setPermutation(BlockPermutation.resolve(block.typeId,{...permutations}))
                Damage(source,itemStack)
                source.playSound('step.wood');
            }
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:pickaxe_tier1', {
        onUse: ({source}) => {
            if(source.isSneaking)
            source.runCommand(`function change_mode1`)
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:pickaxe_tier2', {
        onUse: ({source}) => {
            if(source.isSneaking)
            source.runCommand(`function change_mode2`)
        },
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:hoe_use', {
        onUseOn: ({source,itemStack}) => {
                    Damage(source,itemStack)
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:pickaxe_tier3_light', {
        onUse: ({source}) => {
            if(source.isSneaking)
            source.runCommand(`function change_mode3_light`)
        },
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:pickaxe_tier3_void', {
        onUse: ({source}) => {
            if(source.isSneaking)
            source.runCommand(`function change_mode3_void`)
        },
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:axe_tier1', {
        onUse: ({source}) => {
            if(source.isSneaking)
            source.runCommand(`function change_mode1_axe`)
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:axe_tier2', {
        onUse: ({source}) => { 
            if(source.isSneaking)
            source.runCommand(`function change_mode2_axe`)
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:axe_tier3_void', {
        onUse: ({source}) => {
            if(source.isSneaking)
            source.runCommand(`function change_mode3_axe_void`)
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:axe_tier3_light', {
        onUse: ({source}) => {
            if(source.isSneaking)
            source.runCommand(`function change_mode3_axe_light`)
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:tree_bark', {
        onUseOn: ({source,itemStack,block}) => {
            if(strippedWood.includes(block.typeId))
            {
                const permutations = block.permutation.getAllStates()
                block.setType(wood[strippedWood.indexOf(block.typeId)])
                block.setPermutation(BlockPermutation.resolve(block.typeId,{...permutations}))
                source.playSound('step.wood');
            }
            
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:soul_in_bottle', {
        onUseOn: ({source,blockFace,block}) => {
            const equipment = source.getComponent('equippable')
            var trueBlock=blockFace=='Down'?block.below():blockFace=='Up'?block.above():blockFace=='East'?block.east():blockFace=='West'?block.west():blockFace=='North'?block.north():block.south()
            {
                world.getDimension(source.dimension.id).spawnEntity("edx:soul",trueBlock.center());
            }
            if (source.matches({ gameMode: GameMode.Creative })) return;
            equipment.setEquipment('Mainhand', new ItemStack('glass_bottle', 1))
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:allay_bottle', {
        onUse: ({source}) => {
            const equipment = source.getComponent('equippable');
            {
                world.getDimension(source.dimension.id).spawnEntity("allay",source.location);
            }
            if (source.matches({ gameMode: GameMode.Creative })) return;
            equipment.setEquipment('Mainhand', new ItemStack('glass_bottle', 1))
            
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:void_allay_bottle', {
        onUse: ({source}) => {
            const equipment = source.getComponent('equippable');
            {
                world.getDimension(source.dimension.id).spawnEntity("edx:void_allay",source.location);
            }
            if (source.matches({ gameMode: GameMode.Creative })) return;
                equipment.setEquipment('Mainhand', new ItemStack('glass_bottle', 1))
            
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:light_allay_bottle', {
        onUse: ({source}) => {
            const equipment = source.getComponent('equippable');
            {
                world.getDimension(source.dimension.id).spawnEntity("edx:light_allay",source.location);
            }
            if (source.matches({ gameMode: GameMode.Creative })) return;
                equipment.setEquipment('Mainhand', new ItemStack('glass_bottle', 1))
            
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:light1', {
        onUse: ({source,itemStack}) => {
            if (getScore(source,'void')==1) return;
            itemStack.getComponent('cooldown').startCooldown(source);
            source.addEffect('regeneration', 300, {amplifier: 0})
            world.getDimension(source.dimension.id).spawnParticle('edx:light_particle',source.getHeadLocation());
            Damage(source,itemStack)
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:light2', {
        onUse: ({source,itemStack}) => {
            if (getScore(source,'void')==1) return;
            itemStack.getComponent('cooldown').startCooldown(source);
            if (!source.isSneaking) {
                const entityOptions = {
                    location: source.location, 
                    families: [ "player" ],
                    maxDistance: 15
                }
                const entities = source.dimension.getEntities(entityOptions);
                for (let i = 0; i < entities.length ; i++) {
                    entities[i]?.addEffect('regeneration', 200, {amplifier: 0})
                }
                world.getDimension(source.dimension.id).spawnParticle('edx:light_particle',source.getHeadLocation());
            }
            else {
                source.addEffect('regeneration', 300, {amplifier: 1})
                world.getDimension(source.dimension.id).spawnParticle('edx:light_particle',source.getHeadLocation());
            }
            Damage(source,itemStack)
            
            
            
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:light3', {
        onUse: ({source,itemStack}) => {
            if (getScore(source,'void')==1) return;
            itemStack.getComponent('cooldown').startCooldown(source);
            if ( !source.isSneaking) {
                const entityOptions = {
                    location: source.location,
                    families: [ "player" ],
                    maxDistance: 15
                }
                const entities = source.dimension.getEntities(entityOptions);
                for (let i = 0; i < entities.length ; i++) {
                    entities[i]?.addEffect('regeneration', 200, {amplifier: 2})
                }
                world.getDimension(source.dimension.id).spawnParticle('edx:light_particle',source.getHeadLocation());
            }
            else {
                source.addEffect('regeneration', 300, {amplifier: 3})
                world.getDimension(source.dimension.id).spawnParticle('edx:light_particle',source.getHeadLocation());
            }
            Damage(source,itemStack)
            
            
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:void1', {
        onUse: ({source,itemStack}) => {
            if (getScore(source,'light')==1) return;
            itemStack.getComponent('cooldown').startCooldown(source);
            if ( !source.isSneaking) {
                const entityOptions = {
                    location: source.location,
                    families: [ "monster" ],
                    maxDistance: 10
                }
                const entities = source.dimension.getEntities(entityOptions);
                for (let i = 0; i < entities.length ; i++) {
                    entities[i]?.applyDamage(20,{cause: "magic"})
                }
                world.getDimension(source.dimension.id).spawnParticle('edx:void_particle',source.getHeadLocation());
            }
            else {
                const entityOptions = {
                    location: source.location,
                    families: [ "player" ],
                    maxDistance: 10
                }
                const entities = source.dimension.getEntities(entityOptions);
                for (let i = 0; i < entities.length ; i++) {
                    if(entities[i]!=source)
                        entities[i]?.applyDamage(5,{cause: "magic"})
                }
                world.getDimension(source.dimension.id).spawnParticle('edx:void_particle',source.getHeadLocation());
            }
            Damage(source,itemStack)
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:void2', {
        onUse: ({source,itemStack}) => {
            if (getScore(source,'light')==1) return;
            itemStack.getComponent('cooldown').startCooldown(source);
            if ( !source.isSneaking) {
                const entityOptions = {
                    location: source.location,
                    families: [ "monster" ],
                    maxDistance: 10
                }
                const entities = source.dimension.getEntities(entityOptions);
                for (let i = 0; i < entities.length ; i++) {
                    entities[i]?.applyDamage(35,{cause: "magic"})
                }
                world.getDimension(source.dimension.id).spawnParticle('edx:void_particle',source.getHeadLocation());
            }
            else {
                const entityOptions = {
                    location: source.location,
                    families: [ "player" ],
                    maxDistance: 10
                }
                const entities = source.dimension.getEntities(entityOptions);
                for (let i = 0; i < entities.length ; i++) {
                    if(entities[i]!=source)
                        entities[i].applyDamage(10,{cause: "magic"})
                }
                world.getDimension(source.dimension.id).spawnParticle('edx:void_particle',source.getHeadLocation());
            }
            Damage(source,itemStack)
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:void3', {
        onUse: ({source,itemStack}) => {
            if (getScore(source,'light')==1) return;
            itemStack.getComponent('cooldown').startCooldown(source);
            if ( !source.isSneaking) {
                const entityOptions = {
                    location: source.location,
                    families: [ "monster" ],
                    maxDistance: 10
                }
                const entities = source.dimension.getEntities(entityOptions);
                for (let i = 0; i < entities.length ; i++) {
                    entities[i]?.applyDamage(50,{cause: "magic"})
                }
                world.getDimension(source.dimension.id).spawnParticle('edx:void_particle',source.getHeadLocation());
            }
            else {
                const entityOptions = {
                    location: source.location,
                    families: [ "player" ],
                    maxDistance: 10
                }
                const entities = source.dimension.getEntities(entityOptions);
                for (let i = 0; i < entities.length ; i++) {
                    if(entities[i]!=source)
                        entities[i]?.applyDamage(15,{cause: "magic"})
                }
                world.getDimension(source.dimension.id).spawnParticle('edx:void_particle',source.getHeadLocation());
            }
            Damage(source,itemStack)
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:yellow_spore_bag', {
        onUseOn: ({source,itemStack,block}) => {
            const equipment = source.getComponent('equippable');
            if(block.typeId=="minecraft:stone")
            {
                world.getDimension(block.dimension.id).spawnParticle('edx:yellow_spore_particles',block.below().location);
                source.dimension.playSound('item.bone_meal.use', block.location)
                block.setType("edx:cave_mycelium")
                decreaseItemStack(source,equipment,itemStack)
            }
            else if(block.typeId == "edx:cave_mycelium")
            {
                world.getDimension(block.dimension.id).spawnParticle('edx:yellow_spore_particles',block.below().location);
                source.dimension.playSound('item.bone_meal.use', block.location)
                spreadCaveMycelium(block)
                spreadYellowSporeBag(block)
                decreaseItemStack(source,equipment,itemStack)
            }
            else if(block.typeId == "edx:mycelium_vine" && block.below().isAir)
            {
                world.getDimension(block.dimension.id).spawnParticle('edx:yellow_spore_particles',block.location);
                source.dimension.playSound('item.bone_meal.use', block.location)
                block.below().setType("edx:mycelium_vine")
                decreaseItemStack(source,equipment,itemStack)
            }
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:blue_spore_bag', {
        onUseOn: ({source,itemStack,block}) => {
            const equipment = source.getComponent('equippable');
            if(block.typeId=="minecraft:stone")
            {
                world.getDimension(block.dimension.id).spawnParticle('edx:blue_spore_particles',block.above().location);
                source.dimension.playSound('item.bone_meal.use', block.location)
                block.setType("edx:cave_mycelium")
                decreaseItemStack(source,equipment,itemStack)
            }
            else if(block.typeId == "edx:cave_mycelium")
            {
                world.getDimension(block.dimension.id).spawnParticle('edx:blue_spore_particles',block.above().location);
                source.dimension.playSound('item.bone_meal.use', block.location)
                spreadCaveMycelium(block)
                spreadBlueSporeBag(block)
                decreaseItemStack(source,equipment,itemStack)
            }
            else if(block.typeId == "edx:mycelium_vine" && block.above().isAir)
            {
                world.getDimension(block.dimension.id).spawnParticle('edx:blue_spore_particles',block.location);
                source.dimension.playSound('item.bone_meal.use', block.location)
                block.above().setType("edx:mycelium_vine")
                decreaseItemStack(source,equipment,itemStack)
            }
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:crab_larva_bucket', {
        onUseOn: ({source,itemStack,block,blockFace}) => {
            const equipment = source.getComponent('equippable');
            source.playSound('bucket.empty_fish');
            equipment.setEquipment('Mainhand', new ItemStack('bucket', 1));
            var trueBlock=blockFace=='Down'?block.below():blockFace=='Up'?block.above():blockFace=='East'?block.east():blockFace=='West'?block.west():blockFace=='North'?block.north():block.south()
            world.getDimension(block.dimension.id).spawnEntity("edx:crab_larva",trueBlock.location);
            if(trueBlock.isAir)
                trueBlock.setType('water')
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:treasure_chest', {
        onUse: ({source,itemStack}) => {
            const equipment = source.getComponent('equippable');
            decreaseItemStack(source,equipment,itemStack)
            source.runCommand(`loot give @s loot "chests/treasure_chest"`)
        }
    })
    eventData.itemComponentRegistry.registerCustomComponent('edx:coin', {
        onUse: ({source,itemStack}) => {
            const equipment = source.getComponent('equippable');
            if(!source.isSneaking && itemStack.amount > 9)
            {
                if(coins.indexOf(itemStack.typeId)<6)
                {
                    var nextCoin = new ItemStack(coins[coins.indexOf(itemStack.typeId)+1],1)
                    if (itemStack.amount > 10) {
                        itemStack.amount -= 10;
                        equipment.setEquipment('Mainhand',itemStack);
                    } else if (itemStack.amount == 10) {
                        equipment.setEquipment('Mainhand', undefined);
                    }
                                                        system.runTimeout(() => {
           source.dimension.spawnItem(nextCoin,source.location)
                            },2)   
                }
            }
            else if(source.isSneaking)
            {
                const inventory = source.getComponent('inventory').container;
                if(coins.indexOf(itemStack.typeId)>0)
                {
                    var nextCoin = new ItemStack(coins[coins.indexOf(itemStack.typeId)-1],10)
                    inventory.addItem(nextCoin)
                    if (itemStack.amount > 1) {
                        itemStack.amount -= 1;
                        equipment.setEquipment('Mainhand', itemStack);
                    } else if (itemStack.amount === 1) {
                        equipment.setEquipment('Mainhand', undefined);
                    }

                }
            }

        }
    })

})

const coins = ["edx:copper_coin","edx:tin_coin","edx:iron_coin","edx:platinium_coin","edx:nickel_coin","edx:netherite_coin","edx:void_coin"]







function getPreciseRotation(playerYRotation) {
    // Transform player's head Y rotation to a positive
    if (playerYRotation < 0) playerYRotation += 360;
    // How many 16ths of 360 is the head rotation? - rounded
    const rotation = Math.round(playerYRotation / 45);
  
    // 0 and 16 represent duplicate rotations (0 degrees and 360 degrees), so 0 is returned if the value of `rotation` is 16
    return rotation !== 8 ? rotation : 0;
  }

export function decreaseItemStack(source,equipment,itemStack)
{
    if (source.matches({ gameMode: GameMode.Creative })) return;
    if (itemStack.amount > 1) {
        itemStack.amount -= 1;
        equipment.setEquipment('Mainhand', itemStack);
    } else if (itemStack.amount === 1) {
        equipment.setEquipment('Mainhand', undefined);
    }
    
}
function spreadCaveMycelium(block)
{
    for (var i=0; i<2;i++)
    {
        const x= Math.round(Math.random()*2)-1
        const z= Math.round(Math.random()*2)-1
        var newBlock = world.getDimension(block.dimension.id).getBlock({x:block.location.x+x,y:block.location.y,z:block.location.z+z})
        if(newBlock.typeId == "minecraft:stone")
        {
            newBlock.setType("edx:cave_mycelium")
        }
    }
}
const yellowSporelist = ["edx:mycelium_grass","edx:mycelium_vine","edx:yellow_mushroom","edx:yellow_spore_bag"]
function spreadYellowSporeBag(block)
{
    for (var i=0; i<30;i++)
    {
        const x= Math.random()<=0.5?-1:1 * Math.round(Math.random()*7)
        const z= Math.random()<=0.5?-1:1 * Math.round(Math.random()*7)
        var newBlock = block.dimension.getBlock({x:block.location.x+x,y:block.location.y,z:block.location.z+z})
        if(newBlock.typeId=="edx:cave_mycelium" && newBlock.below().isAir)
        {
            const plantIndex= Math.round(Math.random()*3)
            newBlock.below().setType(yellowSporelist[plantIndex])
            
        }
    }
    
}
const blueSporelist = ["edx:mycelium_grass","edx:mycelium_vine","edx:blue_mushroom","edx:blue_spore_bag"]

function spreadBlueSporeBag(block)
{
    for (var i=0; i<30;i++)
    {
        const x= Math.random()<=0.5?-1:1 * Math.round(Math.random()*7)
        const z= Math.random()<=0.5?-1:1 * Math.round(Math.random()*7)
        var newBlock = block.dimension.getBlock({x:block.location.x+x,y:block.location.y,z:block.location.z+z})
        if(newBlock.typeId=="edx:cave_mycelium" && newBlock.above().isAir)
        {
            const plantIndex= Math.round(Math.random()*3)
            newBlock.above().setType(blueSporelist[plantIndex])
            
        }
    }
    
}