import {EquipmentSlot, world, BlockPermutation,ItemStack,BlockVolume,GameMode,MolangVariableMap,system,EnchantmentType} from '@minecraft/server';
import { updateStairsAround} from "./block_update.js";
import { StartEnabling,CheckNumberOfMobs,CheckPlayers,TpHome,Continue, UnLightColorAround, KillWaveManager, PurpleRuneStone, RestorationTables,DestroyStructure, CheckRestorationTables, SkipRestorationTables, RunicNoBreak, RedObeliskDestroy,
    RedRunicNoBreak, RedStartEnabling,RedCheckNumberOfMobs,RedCheckPlayers,RedContinue,RedDestroyStructure,RedRestoration,RedUnification,RedDivision,RedUnLightColorAround,CheckDivisionTables,SkipDivisionTables
} from './runic.js';
import { decreaseItemStack } from '../items/item_components.js';
const rotation = ["None","Rotate180","Rotate90","Rotate270"]
const armorSlots = [EquipmentSlot.Head, EquipmentSlot.Chest, EquipmentSlot.Legs, EquipmentSlot.Feet];
function isFamily(family,entity) {
    return entity?.getComponent('minecraft:type_family')?.hasTypeFamily(family)
}

system.beforeEvents.startup.subscribe(eventData => {
        eventData.blockComponentRegistry.registerCustomComponent('edx:flat_plant_random', {
        onTick({block}) {
            try {
                if(block?.permutation?.getState("edx:placed")==false) 
                {
                    const rotation = Math.random()<0.25?"north":Math.random()>=0.25 && Math.random()<0.5?"south":Math.random()>=0.5 && Math.random()<0.75?"east":"west"
                    block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),'minecraft:cardinal_direction': rotation,'edx:placed': true,'edx:count': Math.round(Math.random()*3+1)}));
                }
              } catch(e) {}
        }
    });
           eventData.blockComponentRegistry.registerCustomComponent('edx:flat_plant_place', {
        onPlace({block}) { 
                const direction = block.permutation.getState("minecraft:cardinal_direction") //plant
                block.setPermutation(BlockPermutation.resolve(block.typeId, {"minecraft:cardinal_direction": direction,"edx:placed": true}));
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:blue_flax_item_place', { 
        onPlayerInteract: ({ block, player}) => {
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if (selectedItem && (selectedItem.typeId === 'edx:blue_flax_it') && block.permutation?.getState('edx:count')<4 ) {
                const direction = block.permutation.getState("minecraft:cardinal_direction")
                 block.setPermutation(BlockPermutation.resolve(block.typeId, {"minecraft:cardinal_direction": direction,"edx:placed": true}).withState("edx:count", block.permutation.getState("edx:count")+1))
                 block.dimension.playSound('place.pink_petals', block.center());
                if (!player.matches({ gameMode: GameMode.Creative })) {
                    if (selectedItem.amount > 1) {
                        selectedItem.amount -= 1;
                        equipment.setEquipment('Mainhand', selectedItem);
                    } else {
                        equipment.setEquipment('Mainhand', undefined); // Clear the slot if only 1 item left
                    }
                    e.cancel = true;
                }
            }
        }
       });
           eventData.blockComponentRegistry.registerCustomComponent('edx:purple_coneflower_item_place', { 
        onPlayerInteract: ({ block, player}) => {
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if (selectedItem && (selectedItem.typeId === 'edx:purple_coneflower_it') && block.permutation?.getState('edx:count')<4 ) {
                const direction = block.permutation.getState("minecraft:cardinal_direction")
                 block.setPermutation(BlockPermutation.resolve(block.typeId, {"minecraft:cardinal_direction": direction,"edx:placed": true}).withState("edx:count", block.permutation.getState("edx:count")+1))
                 block.dimension.playSound('place.pink_petals', block.center());
                if (!player.matches({ gameMode: GameMode.Creative })) {
                    if (selectedItem.amount > 1) {
                        selectedItem.amount -= 1;
                        equipment.setEquipment('Mainhand', selectedItem);
                    } else {
                        equipment.setEquipment('Mainhand', undefined); // Clear the slot if only 1 item left
                    }
                }
            }
        }
       })
                  eventData.blockComponentRegistry.registerCustomComponent('edx:yellow_daisy_item_place', { 
        onPlayerInteract: ({ block, player}) => {
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if (selectedItem && (selectedItem.typeId === 'edx:yellow_daisy_it') && block.permutation?.getState('edx:count')<4 ) {
                const direction = block.permutation.getState("minecraft:cardinal_direction")
                 block.setPermutation(BlockPermutation.resolve(block.typeId, {"minecraft:cardinal_direction": direction,"edx:placed": true}).withState("edx:count", block.permutation.getState("edx:count")+1))
                 block.dimension.playSound('place.pink_petals', block.center());
                if (!player.matches({ gameMode: GameMode.Creative })) {
                    if (selectedItem.amount > 1) {
                        selectedItem.amount -= 1;
                        equipment.setEquipment('Mainhand', selectedItem);
                    } else {
                        equipment.setEquipment('Mainhand', undefined); // Clear the slot if only 1 item left
                    }
                }
            }
        }
       })
                         eventData.blockComponentRegistry.registerCustomComponent('edx:shata_daisy_item_place', { 
        onPlayerInteract: ({ block, player}) => {
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if (selectedItem && (selectedItem.typeId === 'edx:shata_daisy_it') && block.permutation?.getState('edx:count')<4 ) {
                const direction = block.permutation.getState("minecraft:cardinal_direction")
                 block.setPermutation(BlockPermutation.resolve(block.typeId, {"minecraft:cardinal_direction": direction,"edx:placed": true}).withState("edx:count", block.permutation.getState("edx:count")+1))
                 block.dimension.playSound('place.pink_petals', block.center());
                if (!player.matches({ gameMode: GameMode.Creative })) {
                    if (selectedItem.amount > 1) {
                        selectedItem.amount -= 1;
                        equipment.setEquipment('Mainhand', selectedItem);
                    } else {
                        equipment.setEquipment('Mainhand', undefined); // Clear the slot if only 1 item left
                    }
                }
            }
        }
       })
    eventData.blockComponentRegistry.registerCustomComponent('edx:division_table', {
        onPlayerInteract:({ block, player}) => {
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            const enchantList = selectedItem?.getComponent('enchantable')?.getEnchantments()
            if(enchantList==undefined || enchantList==[] )
            {
                var DisenchantMessage= {rawtext :[{ 
                translate: "message.interact.DisenchantMessage",
                }]};
                player.sendMessage(DisenchantMessage)
            }
            else if(selectedItem.typeId =='minecraft:enchanted_book')
                {   
                var CantDisenchantMessage= {rawtext :[{ 
                translate: "message.interact.CantDisenchantMessage",
                }]};
                player.sendMessage(CantDisenchantMessage)}
                
            else
            {
                const curseOfBinding = selectedItem?.getComponent('enchantable')?.getEnchantment("minecraft:binding")?.level>=1
                const curseOfVanishing = selectedItem?.getComponent('enchantable')?.getEnchantment("minecraft:vanishing")?.level>=1
                for(var enchant of enchantList)
                {
                    if(enchant.type.id != "binding" && enchant.type.id != "vanishing")
                    {
                        const book = new ItemStack('minecraft:enchanted_book',1)
                        book.getComponent('enchantable').addEnchantment(enchant)
                        if(curseOfBinding)
                            book.getComponent('enchantable').addEnchantment({ type: new EnchantmentType("minecraft:binding"), level: 0 })
                        if(curseOfVanishing)
                            book.getComponent('enchantable').addEnchantment({ type: new EnchantmentType("minecraft:vanishing"), level: 0 })
                        block.dimension.spawnItem(book, block.above().bottomCenter());
                    }
                }
                if(!curseOfVanishing)
                {
                    selectedItem?.getComponent('enchantable')?.removeAllEnchantments()
                    if(curseOfBinding)
                        selectedItem?.getComponent('enchantable')?.addEnchantment({ type: new EnchantmentType("minecraft:binding"), level: 0 })
                    block.dimension.spawnItem(selectedItem, block.above().bottomCenter());
                }
                equipment.setEquipment('Mainhand', undefined);
                block.setType('minecraft:air')
            }
        }
    })
    eventData.blockComponentRegistry.registerCustomComponent('edx:red_interpreter', {
        onTick: ({ block,dimension }) => {
            dimension.spawnParticle('edx:red_runic',block.above().bottomCenter())
        }
    })
    eventData.blockComponentRegistry.registerCustomComponent('edx:red_deterioration_interpreter', {
        onPlayerInteract:({ block, player}) => {
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if(selectedItem?.getTags()?.includes('blank_runestone'))
            {
                equipment.setEquipment('Mainhand', new ItemStack('edx:red_deterioration_runestone',1));
            }
        }
    })
    eventData.blockComponentRegistry.registerCustomComponent('edx:red_restoration_interpreter', {
        onPlayerInteract:({ block, player}) => {
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if(selectedItem?.getTags()?.includes('blank_runestone'))
            {
                equipment.setEquipment('Mainhand', new ItemStack('edx:red_restoration_runestone',1));
            }
        }
    })
    
    eventData.blockComponentRegistry.registerCustomComponent('edx:red_division_interpreter', {
        onPlayerInteract:({ block, player}) => {
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if(selectedItem?.getTags()?.includes('blank_runestone'))
            {
                equipment.setEquipment('Mainhand', new ItemStack('edx:red_division_runestone',1));
            }
        }
    })
    eventData.blockComponentRegistry.registerCustomComponent('edx:red_unification_interpreter', {
        onPlayerInteract:({ block, player}) => {
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if(selectedItem?.getTags()?.includes('blank_runestone'))
            {
                equipment.setEquipment('Mainhand', new ItemStack('edx:red_unification_runestone',1));
            }
        }
    })
    eventData.blockComponentRegistry.registerCustomComponent('edx:powered_red_runic_table', {
        onTick: ({ block,dimension }) => {
            const hasRune = block.permutation?.getState('edx:rune')
            const waveEnd = block.permutation?.getState('edx:wave_end')
            const waves = block.permutation?.getState('edx:waves')
            const division = block.permutation?.getState('edx:division')
            RedRunicNoBreak(block)
            if(!hasRune && !waveEnd)
            {
                const entityOptions = {
                    type:"minecraft:player",
                    location: {x:block.location.x-25,y:block.location.y-13,z:block.location.z-25},
                    volume:{x:51,y:19,z:51}
                }
                const entities = dimension.getEntities(entityOptions);
                if(entities!=undefined)
                    for (let i = 0; i < entities.length ; i++){
                        if(entities[i]!=undefined )
                        {
                            try{
                                const player =entities[i]
                                player.spawnParticle('edx:red_runic_table_down_particle',block.center())
                                if(block.dimension.getBlock({x:player.location.x,y:player.location.y+1,z:player.location.z}).hasTag("edx:runic"))
                                    player.teleport({x:block.center().x,y:block.center().y+1,z:block.center().z},{keepVelocity:false})
                            }
                            catch(e){}
                        }
                    }
            }
            if(waves)
            {
                block.dimension.spawnParticle('edx:red_runic_table_spawn_particle',block.above().bottomCenter())
                if(!block.permutation?.getState('edx:wave_pause'))
                {
                    RedCheckNumberOfMobs(block)
                }
                RedCheckPlayers(block)
            }
            if(division)
            {
                CheckDivisionTables(block)
            }
            
        },
        onPlayerInteract({ block, player}){
            const waveEnd = block.permutation?.getState('edx:wave_end')
            const powered = block.permutation?.getState('edx:powered')
            const hasRune = block.permutation?.getState('edx:rune')
            const can_diamond = block.permutation?.getState('edx:can_ruby')
            const division = block.permutation?.getState('edx:division')
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if (powered && selectedItem && selectedItem.typeId == 'edx:red_runestone' && !hasRune && !waveEnd )
            {
                equipment.setEquipment('Mainhand', undefined);  
                block.dimension.spawnParticle('edx:red_runic_light_shockwave_particle',block.center())
                RedStartEnabling(block)
                block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),'edx:rune': true}));
                block.dimension.spawnParticle('edx:red_runic_light_color_particle',block.center())
            }
            else if(powered && !hasRune && waveEnd && selectedItem?.getTags()?.includes('blank_runestone'))//what a dumb idea to name that tag "blank runestone" when 80% of runestones with this tag aren't blank
            {
                switch (selectedItem.typeId) {
                    case "edx:red_deterioration_runestone":
                        RedDestroyStructure(block,player)
                        break;
                    case "edx:red_restoration_runestone":
                        RedRestoration(block,player)
                        break;
                    case "edx:red_unification_runestone":
                        RedUnification(block,player)
                        break;
                    case "edx:red_division_runestone":
                        RedDivision(block,player)
                        break;
                    case "edx:red_blank_runestone":
                        RedContinue(block,player)
                        break;
                }
            }
            else if(!powered && can_diamond)
            {
                if(selectedItem?.typeId =="edx:ruby_block")
                {
                    block.dimension.playSound('respawn_anchor.charge',block.center(),{pitch:1,volume:15});
                    block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),'edx:powered': true}));
                    RedUnLightColorAround(block)
                    decreaseItemStack(player,equipment,selectedItem)
                }
                else
                {
                var RubyBlockMessage= {rawtext :[{ 
                translate: "message.interact.RubyBlockMessage",
                }]};
                    player.sendMessage(RubyBlockMessage)
                }
            }
            else if(division)
            {
                SkipDivisionTables(block)
            }
        },
        onPlayerBreak: ({ block}) => {
            KillWaveManager(block)
        }
    }); 
    eventData.blockComponentRegistry.registerCustomComponent('edx:spark_plug_block', {
        onPlace:({block}) => {
            block.dimension.spawnParticle('edx:spark_plug_block',block.above().center())
        },
        onTick:({block}) => {
            block.dimension.spawnParticle('edx:spark_plug_explode',block.center())
            
            block.setType('minecraft:air')
            for(let i = -1; i <= 1 ; i++) {
                for(let j = -1; j <= 1 ; j++) {  
                    for(let k = -1; k <= 1 ; k++) {
                        const newblock = block.dimension.getBlock({x:block.location.x+i,y:block.location.y+j,z:block.location.z+k})
                        if(newblock.typeId =="edx:polished_red_runic_stone")
                        {
                            newblock.setPermutation(BlockPermutation.resolve(newblock.typeId, {...newblock.permutation.getAllStates(),'edx:light':1}));
                        }
                    }
                }
            }
        }
    })
    eventData.blockComponentRegistry.registerCustomComponent('edx:powered_red_runic_walk', {
        onStepOn:({entity,block}) => {
            block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),'edx:apply_damage': true}));
            if(!isFamily("runic",entity) && entity.typeId != "minecraft:item" && entity.typeId != "edx:player_soul")
            {
                entity.dimension.spawnParticle('edx:red_runic',block.above().bottomCenter());
                try{
                    entity.applyDamage(1,{cause: "void",damagingEntity: undefined})
                }
                catch(e){}
            }
            
        }
    })
    eventData.blockComponentRegistry.registerCustomComponent('edx:powered_red_runic_damage', {
        onTick:({block}) => {
            const entities = block.dimension.getEntitiesAtBlockLocation(block.above())
            for (let entity of entities){
                if(!isFamily("runic",entity) && entity.typeId != "minecraft:item" && entity.typeId != "edx:player_soul")
                {
                    try{
                        entity.applyDamage(1,{cause: "void"})
                    }
                    catch(e){}
                }
            }
            if(entities.length==0)
            {
                block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),'edx:apply_damage': false}));
            }
            else
                block.dimension.spawnParticle('edx:red_runic',block.above().bottomCenter());
            
        }
    })
    eventData.blockComponentRegistry.registerCustomComponent('edx:red_runic_transmitter', {
        onPlayerInteract:({ block, player}) => {
            block.setType('minecraft:air')
                var RedRunicStructureMessage=  {rawtext :[{ 
                translate: "message.interact.RedRunicStructureMessage"
                }]};
            player.sendMessage(RedRunicStructureMessage)
            player.addEffect('slow_falling',200)
            RedObeliskDestroy(block,true)
        },
        onPlayerBreak: ({ block}) => {
            RedObeliskDestroy(block,false)
        }
    })
    eventData.blockComponentRegistry.registerCustomComponent('edx:runic_decay', {
        onRandomTick: ({ block,dimension }) => {
            try {
                block.setType('minecraft:air')
                dimension.spawnParticle('edx:runic_destroy',block.center())
            } catch(e) {}
        }
    })
    eventData.blockComponentRegistry.registerCustomComponent('edx:red_runic_decay', {
        onRandomTick: ({ block,dimension }) => {
            try {
                block.setType('minecraft:air')
                dimension.spawnParticle('edx:red_runic_destroy',block.center())
            } catch(e) {}
        }
    })
    
    eventData.blockComponentRegistry.registerCustomComponent('edx:restoration_table', {
        onPlayerInteract:({ block, player}) => {
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if(selectedItem?.getComponent("durability"))
            {
                selectedItem.getComponent('durability').damage = 0
                equipment.setEquipment('Mainhand', selectedItem);
                block.setType('minecraft:air')
            }
            else
            {
                var RepairMessage= { 
                translate: "message.interact.RepairMessage",
                };
                player.sendMessage(RepairMessage)
            }
        }
    })
    eventData.blockComponentRegistry.registerCustomComponent('edx:blue_interpreter', {
        onTick: ({ block,dimension }) => {
            dimension.spawnParticle('edx:blue_interpreter',block.above().bottomCenter())
        }
    })
    eventData.blockComponentRegistry.registerCustomComponent('edx:deterioration_interpreter', {
        onPlayerInteract:({ block, player}) => {
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if(selectedItem?.getTags()?.includes('blank_runestone'))
            {
                equipment.setEquipment('Mainhand', new ItemStack('edx:deterioration_runestone',1));
            }
        }
    })
    eventData.blockComponentRegistry.registerCustomComponent('edx:restoration_interpreter', {
        onPlayerInteract:({ block, player}) => {
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if(selectedItem?.getTags()?.includes('blank_runestone'))
            {
                equipment.setEquipment('Mainhand', new ItemStack('edx:restoration_runestone',1));
            }
        }
    })
    
    eventData.blockComponentRegistry.registerCustomComponent('edx:restful_interpreter', {
        onPlayerInteract:({ block, player}) => {
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if(selectedItem?.getTags()?.includes('blank_runestone'))
            {
                equipment.setEquipment('Mainhand', new ItemStack('edx:restful_runestone',1));
            }
        }
    })
    eventData.blockComponentRegistry.registerCustomComponent('edx:deprivation_interpreter', {
        onPlayerInteract:({ block, player}) => {
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if(selectedItem?.getTags()?.includes('blank_runestone'))
            {
                equipment.setEquipment('Mainhand', new ItemStack('edx:deprivation_runestone',1));
            }
        }
    })
    eventData.blockComponentRegistry.registerCustomComponent('edx:powered_runic_table', {
        onTick: ({ block,dimension }) => {
            const hasRune = block.permutation?.getState('edx:rune')
            const waveEnd = block.permutation?.getState('edx:wave_end')
            const waves = block.permutation?.getState('edx:waves')
            const restoration = block.permutation?.getState('edx:restoration')
            RunicNoBreak(block)
            if(!hasRune && !waveEnd)
            {
                const entityOptions = {
                    location: {x:block.location.x-10,y:block.location.y,z:block.location.z-10},
                    volume:{x:21,y:30,z:21}
                }
                const entities = dimension.getEntities(entityOptions);
                if(entities!=undefined)
                    for (let i = 0; i < entities.length ; i++){
                        if(entities[i]!=undefined )
                        {
                            try{
                                const player =entities[i]//actually work for any entity
                                if(player.location.y-block.location.y>4 && player.getVelocity().y<=0)
                                {
                                    
                                    player.spawnParticle('edx:blue_runic_down_particle',block.center())
                                    if(player.getVelocity().y<0 && Math.abs(player.location.x-block.location.x)<4 && Math.abs(player.location.z-block.location.z)<4)
                                    {
                                        player.addEffect('slow_falling',40)
                                    }
                                }
                                else 
                                {
                                    block.above().setType('minecraft:air')
                                    block.above(2).setType('minecraft:air')
                                    player.spawnParticle('edx:blue_runic_table_up_particle',block.above().bottomCenter())
                                }
                            }
                            catch(e){}
                        }
                    }
            }
            if(waves)
            {
                block.dimension.spawnParticle('edx:blue_runic_table_spawn_particle',block.above().bottomCenter())
                if(!block.permutation?.getState('edx:wave_pause'))
                {
                    CheckNumberOfMobs(block)
                }
                CheckPlayers(block)
                const entityOptions = {
                    location: {x:block.location.x-3,y:block.location.y+13,z:block.location.z-3},
                    volume:{x:7,y:5,z:7}
                }
                const entities = dimension.getEntities(entityOptions);
                if(entities!=undefined)
                    for (let i = 0; i < entities.length ; i++)
                    {
                        const player =entities[i]//actually work for any entity
                        player.addEffect('levitation',40)
                    }
            }
            if(restoration)
            {
                CheckRestorationTables(block)
            }
            
        },
        onStepOn({entity,block}) {
            const hasRune = block.permutation?.getState('edx:rune')
            const waveEnd = block.permutation?.getState('edx:wave_end')
            if(!block.permutation?.getState('edx:rune') && !hasRune && !waveEnd)
            {
                entity.addEffect('levitation',200,{amplifier: 2})
                entity.addEffect('slow_falling',280)
            }
        },
        onPlayerInteract({ block, player}){
            const waveEnd = block.permutation?.getState('edx:wave_end')
            const powered = block.permutation?.getState('edx:powered')
            const hasRune = block.permutation?.getState('edx:rune')
            const restoration = block.permutation?.getState('edx:restoration')
            const can_diamond = block.permutation?.getState('edx:can_diamond')
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if (powered && selectedItem && selectedItem.typeId == 'edx:blue_runestone' && !hasRune && !waveEnd )
            {
                equipment.setEquipment('Mainhand', undefined);  
                block.dimension.spawnParticle('edx:blue_runic_light_shockwave_particle',block.center())
                StartEnabling(block)
                block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),'edx:rune': true}));
                block.dimension.spawnParticle('edx:blue_runic_light_color_particle',block.center())
            }
            else if(powered && !hasRune && waveEnd && selectedItem?.getTags()?.includes('blank_runestone'))
            {
                switch (selectedItem.typeId) {
                    case "edx:deterioration_runestone":
                        DestroyStructure(block,player)
                        break;
                    case "edx:restoration_runestone":
                        RestorationTables(block,player)
                        break;
                    case "edx:restful_runestone":
                        TpHome(block,player)
                        break;
                    case "edx:deprivation_runestone":
                        PurpleRuneStone(block,player)
                        break;
                    case "edx:blue_blank_runestone":
                        Continue(block,player)
                        break;
                }
            }
            else if(!powered && can_diamond)
            {
                if(selectedItem?.typeId =="minecraft:diamond_block")
                {
                    block.dimension.playSound('respawn_anchor.charge',block.center(),{pitch:1,volume:15});
                    block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),'edx:powered': true}));
                    UnLightColorAround(block)
                    decreaseItemStack(player,equipment,selectedItem)
                }
                else
                {
                var DiamondBlockMessage= {rawtext :[{ 
                translate: "message.interact.DiamondBlockMessage",
                }]};
                    player.sendMessage(DiamondBlockMessage) 
                }
            }
            else if(restoration)
            {
                SkipRestorationTables(block)
            }
        },
        onPlayerBreak: ({ block}) => {
            KillWaveManager(block)
        }
    }); 
    eventData.blockComponentRegistry.registerCustomComponent('edx:powered_runic_bricks', {
        onPlace: ({ block }) => {
            block.setPermutation(BlockPermutation.resolve(block.typeId, {'edx:texture': Math.round(Math.random()*5+1)}));

        }
    }); 
    eventData.blockComponentRegistry.registerCustomComponent('edx:spore_bearer', {
         onTick({block,dimension}) {
            try {
                dimension.spawnParticle('edx:spore_bearer_particle',block.center());
                dimension.spawnParticle('edx:spore_bearer_ambient',block.center());
                } catch(e) {
            }
            
        }
    
    }); 
    eventData.blockComponentRegistry.registerCustomComponent('edx:deceitweb_liver', {
        onPlayerBreak: ({ player,block,dimension }) => {
            player.addTag('Liver_break')
            player.runCommand(`scoreboard players set @s Liver_break 480`)
            summonDeceitmorph(block,6)
         },
         onTick({block,dimension}) {
            try {
                dimension.playSound('block.deceitweb_liver.sound',block.location,{pitch:Math.random()+0.5,volume:2});
                dimension.spawnParticle('edx:deceitweb_liver_tick_particle',block.center());
                } catch(e) {
            }
            
        }
    
    }); 
    eventData.blockComponentRegistry.registerCustomComponent('edx:deceitvase', {
        onPlayerBreak: ({ block,dimension,player }) => {
            const equipment = player.getComponent('equippable');
            const selectedItem = equipment.getEquipment('Mainhand');
            if(selectedItem?.getComponent('enchantable')?.getEnchantment("silk_touch")?.level==1) return;
            dimension.spawnEntity("edx:deceitmorph_vermine",block.bottomCenter());
            dimension.spawnEntity("edx:deceitmorph_vermine",block.bottomCenter());
            dimension.spawnEntity("edx:deceitmorph_vermine",block.bottomCenter());
         } 
    }); 
    eventData.blockComponentRegistry.registerCustomComponent('edx:gastric_juice_active', {
        onTick({block,dimension}) {
            const entities = dimension.getEntitiesAtBlockLocation({x:block.x,y:block.y,z:block.z});
            if (entities.length > 0) {
                for (let i = 0; i < entities.length ; i++) {
                    try {
                        if(entities[i]?.hasComponent('minecraft:item')==undefined || entities[i].hasComponent('minecraft:item')==false)
                            entities[i].applyDamage(5,{cause: "contact"})
                      } catch(e) {
                    }
                
            }
            }
            else
            {
                block.setPermutation(BlockPermutation.resolve(block.typeId, {'edx:active': false}));
            }
            
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:gastric_juice_step', {
        onStepOn({entity,block}) {
            try {
                if(entity.hasComponent('minecraft:item')==false)
                    entity.applyDamage(5,{cause: "contact"})
                block.setPermutation(BlockPermutation.resolve(block.typeId, {'edx:active': true}));
              } catch(e) {
              }
            
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:deceitmaw_open', {
        onStepOn({entity,block}) {
            try {
                block.setPermutation(BlockPermutation.resolve(block.typeId, {'edx:open': false}));
                entity.applyDamage(15,{cause: "contact"})
              } catch(e) {
              }
            
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:deceitmaw_close', {
        onRandomTick({block,dimension}) {
            try {
                if(Math.random()<0.5)
                    block.setPermutation(BlockPermutation.resolve(block.typeId, {'edx:open': true}));
              } catch(e) {
              }
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:oozeshroom_full_particle', {
        onTick({block,dimension}) {
            if (block.above().typeId !="minecraft:air" && block?.above()?.permutation?.getState("edx:type")!="top"  && block?.permutation?.getState("edx:type")=="bottom" ) {
                block.setType('minecraft:air');
            }
            dimension.spawnParticle('edx:oozeshroom_full_particle',block.bottomCenter());
            
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:oozeshroom_full_interact', {
        onPlayerInteract({ block, player}) {
                const equipment = player.getComponent('equippable'); 
                const selectedItem = equipment.getEquipment('Mainhand');
                if (selectedItem && (selectedItem.typeId === 'minecraft:glass_bottle')) {
                    player.getComponent("inventory").container.addItem(new ItemStack('edx:oozeshroom_juice', 1))
                    block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),'edx:juice': "empty"}));
                    if(block?.permutation?.getState("edx:type")=="top")
                        block.below().setPermutation(BlockPermutation.resolve(block.typeId, {...block.below().permutation.getAllStates(),'edx:juice': "empty"}));
                    else
                        block.above().setPermutation(BlockPermutation.resolve(block.typeId, {...block.above().permutation.getAllStates(),'edx:juice': "empty"}));
                        block.dimension.playSound('bottle.fill',block.location);
                        if (!player.matches({ gameMode: GameMode.Creative })) {
                            if (selectedItem.amount > 1) {
                                selectedItem.amount -= 1;
                                equipment.setEquipment('Mainhand', selectedItem);
                            } else {
                                equipment.setEquipment('Mainhand', undefined); // Clear the slot if only 1 item left
                            }
                            
                        }
                    
                }
            
            
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:oozeshroom_grow', {
        onRandomTick({block,dimension}) {
            try {
                if (block.above().typeId !="minecraft:air" && block?.above()?.permutation?.getState("edx:type")!="top" && block?.permutation?.getState("edx:type")=="bottom" ) {
                    block.setType('minecraft:air');
                }
                if(block.above().typeId == "edx:oozeshroom" && block.below().typeId == "minecraft:warped_nylium" && Math.random()<0.1)
                { 
                    block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),'edx:juice': "full"}));
                    block.above().setPermutation(BlockPermutation.resolve(block.typeId, {...block.above().permutation.getAllStates(),'edx:juice': "full",'edx:type': "top"}));
                }
              } catch(e) {}
            
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:crimsonspire_stem_random', {
        onTick({block}) {
            try {
                if(block?.permutation?.getState("edx:placed")==false) 
                {  
                    const heightExist = block?.permutation?.getState("edx:random_height")
                    const rotation = Math.random()<0.25?"north":Math.random()>=0.25 && Math.random()<0.5?"south":Math.random()>=0.5 && Math.random()<0.75?"east":"west"
                    if(heightExist!=undefined)
                    {
                        const height = Math.random()<0.5? 1 : 2
                        block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),'minecraft:cardinal_direction': rotation,'edx:random_height': height,'edx:placed': true}));
                    }
                    else
                        block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),'minecraft:cardinal_direction': rotation,'edx:placed': true}));
                }
              } catch(e) {}
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:crimsonspire_stem_break', {
        onPlayerBreak({block}) {
            crimsonspireStemBreak(block)
            
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:crimsonspire_cap_spores', {
        onTick({block,dimension}) {
            dimension.spawnParticle('edx:crimsonspire_spores',block.bottomCenter());
            
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:shroom_fruit_tick', {
        onRandomTick({block}) {
            const direction = block.permutation.getState("minecraft:block_face")
            let randomTick = Math.random() <= 1/6; 
            if(block.permutation?.getState('edx:stage') < 2)
            { 
                if(randomTick )
                block.setPermutation(BlockPermutation.resolve(block.typeId, {"minecraft:block_face": direction,"edx:stage": block.permutation.getState("edx:stage")+1}));
            }
        } 
    });
    
    eventData.blockComponentRegistry.registerCustomComponent('edx:crimsonspire_cap_grow', {
        onRandomTick({block,dimension}) {
            try {
                if(block.above().isAir && Math.random()<0.2)
                {
                    const stillGrow = Math.random()<0.2?false:true
                    block.setType('edx:crimsonspire_stem')
                    block.above().setPermutation(BlockPermutation.resolve('edx:crimsonspire_cap', {'edx:grow': stillGrow}));
                }
              } catch(e) {}
            
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:crimsonspire_seed', {
        onRandomTick({block,dimension}) {
            try {
                if(block.above().isAir && Math.random()<0.2)
                {
                    block.setType('edx:crimsonspire_stem')
                    block.above().setPermutation(BlockPermutation.resolve('edx:crimsonspire_cap', {'edx:grow': true}));
                }
              } catch(e) {}
            
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:tall_plant', {
        beforeOnPlayerPlace: e => {
            const {block,player} = e;
            if (block.above().typeId !="minecraft:air" ) {
                e.cancel = true;
            }
            else
            {
                const equipment = player.getComponent('equippable');
                const selectedItem = equipment.getEquipment('Mainhand');
                system.runTimeout(() => { 
                    block.above().setPermutation(BlockPermutation.resolve(selectedItem.typeId, {...block.permutation.getAllStates(),'edx:type': 'top'}));
                })
            }
        }
    
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:lapis_spotter_interact', {
       onPlayerInteract({player,block}){
        var xp = block.permutation.getState("edx:xp")
        var ten_xp = block.permutation.getState("edx:ten_xp")
        player.addExperience(xp+ten_xp*10)
        block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),'edx:xp': 0,'edx:ten_xp': 0}));
       },
       onTick: ({ block,dimension }) => {
        var xp = block.permutation.getState("edx:xp")
        var ten_xp = block.permutation.getState("edx:ten_xp")
        const x =(xp+ten_xp*10)/10
        if(Math.random()<(1/(-(x+1))+1))
            dimension.spawnParticle('edx:xp_amount_spotter',block.center());
       }
    }); 
    eventData.blockComponentRegistry.registerCustomComponent('edx:spotter_interact', {
        onPlayerInteract({player,block,dimension}){
            var type = ""
            const equipment = player.getComponent('equippable');
            const selectedItem = equipment.getEquipment('Mainhand');
            if(selectedItem!=undefined)
                if(selectedItem.typeId == 'edx:fire_opal')
                {    
                    type = "fire_opal"
                }
                else if(selectedItem.typeId == 'minecraft:lapis_lazuli')
                {    
                    type = "lapis"
                }
                else if(selectedItem.typeId == 'minecraft:diamond')
                {    
                    type = "diamond"
                }
                else if(selectedItem.typeId == 'minecraft:amethyst_shard')
                {    
                    type = "amethyst"
                }
                else if(selectedItem.typeId == 'edx:ruby')
                {    
                    type = "ruby"
                }
                else if(selectedItem.typeId == 'minecraft:emerald')
                {    
                    type = "emerald"
                }
                else if(selectedItem.typeId == 'minecraft:quartz')
                {    
                    type = "quartz"
                }
            if(type!="")
            {
                if (!player.matches({ gameMode: GameMode.Creative }) ) {
                    if (selectedItem.amount > 1) {
                        selectedItem.amount -= 1;
                        equipment.setEquipment('Mainhand', selectedItem);
                    } else {
                        equipment.setEquipment('Mainhand', undefined); 
                    }
                }
                const direction = block.permutation.getState("minecraft:facing_direction")
                const enabled = block.permutation.getState("edx:enabled")
                dimension.playSound('lodestone_compass.link_compass_to_lodestone',block.location);
                block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),"minecraft:facing_direction": direction,"edx:type": type,"edx:enabled": enabled}));
            }
            
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:spotter_off', {
        onTick: ({ block,dimension }) => {
            const type = block.permutation.getState("edx:type")
            const direction = block.permutation.getState("minecraft:facing_direction")
            var dir = {x:0,y:1,z:0}
            if(direction=='up')
                dir = {x:0,y:1,z:0}
            else if(direction=='down')
                dir = {x:0,y:-1,z:0}
            else if(direction=='north')
                dir = {x:0,y:0,z:-1}
            else if(direction=='south')
                dir = {x:0,y:0,z:1}
            else if(direction=='west')
                dir = {x:-1,y:0,z:0}
            else if(direction=='east')
                dir = {x:1,y:0,z:0}
            try {
                var distance = 4
                var options = { maxDistance: 4}
                if(type==='amethyst')
                {
                    distance = 12
                    options = { maxDistance: 12}
                }
                const rayBlock = dimension.getBlockFromRay({x:block.center().x+dir.x,y:block.center().y+dir.y,z:block.center().z+dir.z},dir,options)?.block
                if(rayBlock!=undefined)
                {
                    distance = Math.sqrt(
                        Math.pow(block.x - rayBlock.x, 2) +
                        Math.pow(block.y - rayBlock.y, 2) +
                        Math.pow(block.z - rayBlock.z, 2)
                    )-1;
                }
                let entities = dimension.getEntities({location:{x:block.x+dir.x,y:block.y+dir.y,z:block.z+dir.z},volume:{x:dir.x*distance,y:dir.y*distance,z:dir.z*distance}});
                for (let i = 0; i < entities.length ; i++) {
                        if(entities[i].typeId == "minecraft:player") 
                        {
                            const direction = block.permutation.getState("minecraft:facing_direction")
                            dimension.playSound('crafter.craft',block.location);
                            block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),"minecraft:facing_direction": direction,"edx:type": type,"edx:enabled": true}));
                        }
                    
                }
              } catch(e) {}
       }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:spotter_on', {
        onTick: ({ block,dimension }) => {
            dimension.playSound('particle.soul_escape',block.location);
            const type = block.permutation.getState("edx:type")
            const direction = block.permutation.getState("minecraft:facing_direction")
            var dir = {x:0,y:1,z:0}
            var pardir = {x:0,y:1,z:0}
            if(direction=='up'){
                dir = {x:0,y:1,z:0}
                pardir = {x:0,y:1,z:-0.5}
            }
            else if(direction=='down'){
                dir = {x:0,y:-1,z:0}
                pardir = {x:0,y:-1,z:0.5}
            } 
            else if(direction=='north'){
                dir = {x:0,y:0,z:-1}
                pardir = {x:0,y:-0.5,z:-1}
            }
            else if(direction=='south'){
                dir = {x:0,y:0,z:1}
                pardir = {x:0,y:-0.5,z:1}
            }
            else if(direction=='west'){
                dir = {x:-1,y:0,z:0}
                pardir = {x:-1,y:-0.5,z:0}
            }
            else if(direction=='east'){
                dir = {x:1,y:0,z:0}
                pardir = {x:1,y:-0.5,z:0}
            }
               
            try {
                var options = { maxDistance:  4}
                const vmap = new MolangVariableMap();
                vmap.setVector3('variable.direction', {x:dir.x,y:dir.y,z:dir.z});
                
                var distance = 4
                const rayBlock = dimension.getBlockFromRay({x:block.center().x+dir.x,y:block.center().y+dir.y,z:block.center().z+dir.z},dir,options)?.block
                if(rayBlock!=undefined)
                {
                    distance = Math.sqrt(
                        Math.pow(block.x - rayBlock.x, 2) +
                        Math.pow(block.y - rayBlock.y, 2) +
                        Math.pow(block.z - rayBlock.z, 2)
                    )-1;
                }
                var enable=false;
                let entities = dimension.getEntities({location:{x:block.x+dir.x,y:block.y+dir.y,z:block.z+dir.z},volume:{x:dir.x*distance,y:dir.y*distance,z:dir.z*distance}});
                for (let i = 0; i < entities.length ; i++) {
                    if(entities[i].typeId == "minecraft:player") 
                    {
                        enable=true
                    }
                }
                if(type == 'none')
                    dimension.spawnParticle('edx:souls_spotter',{x:block.center().x+pardir.x/2,y:block.center().y+pardir.y/2,z:block.center().z+pardir.z/2},vmap);
                else if(type == 'amethyst')
                {
                    distance = 12
                    options = { maxDistance: 12}
                    let entities = dimension.getEntities({location:{x:block.x+dir.x,y:block.y+dir.y,z:block.z+dir.z},volume:{x:dir.x*distance,y:dir.y*distance,z:dir.z*distance}});
                    for (let i = 0; i < entities.length ; i++) {
                        if(entities[i].typeId == "minecraft:player") 
                        {
                            enable=true
                        }
                    }
                    dimension.spawnParticle('edx:souls_spotter',{x:block.center().x+pardir.x/2,y:block.center().y+pardir.y/2,z:block.center().z+pardir.z/2},vmap);
                }
                else if(type == 'quartz')
                {
                    
                    dimension.spawnParticle('edx:quartz_spotter',{x:block.center().x+dir.x*distance*1.2,y:block.center().y+dir.y*distance*1.2,z:block.center().z+dir.z*distance*1.2},vmap);
                    let entities = dimension.getEntities({location:{x:block.x+dir.x,y:block.y+dir.y,z:block.z+dir.z},volume:{x:dir.x*distance,y:dir.y*distance,z:dir.z*distance}});
                    for (let i = 0; i < entities.length ; i++) {
                        if(entities[i].typeId == "minecraft:player") 
                        {
                            dimension.spawnParticle('edx:souls_spotter',{x:entities[i].location.x,y:entities[i].location.y+1,z:entities[i].location.z});
                            dimension.playSound('particle.soul_escape',entities[i].location);
                            entities[i].runCommand('effect @s clear')
                        }
                    }
                } 
                else if(type == 'emerald')
                {
                    dimension.spawnParticle('edx:emerald_spotter',{x:block.center().x+dir.x*distance*1.2,y:block.center().y+dir.y*distance*1.2,z:block.center().z+dir.z*distance*1.2},vmap);
                    let entities = dimension.getEntities({location:{x:block.x+dir.x,y:block.y+dir.y,z:block.z+dir.z},volume:{x:dir.x*distance,y:dir.y*distance,z:dir.z*distance}});
                    for (let i = 0; i < entities.length ; i++) {
                        if(entities[i].typeId == "minecraft:player") 
                        {
                            const equipment = entities[i].getComponent('equippable');
                            spotterDropItem(block,equipment,'Mainhand',dir,entities[i])
                        }
                    }
                } 
                else if(type == 'ruby')
                    {
                        dimension.spawnParticle('edx:ruby_spotter',{x:block.center().x+dir.x*distance*1.2,y:block.center().y+dir.y*distance*1.2,z:block.center().z+dir.z*distance*1.2},vmap);
                        let entities = dimension.getEntities({location:{x:block.x+dir.x,y:block.y+dir.y,z:block.z+dir.z},volume:{x:dir.x*distance,y:dir.y*distance,z:dir.z*distance}});
                        for (let i = 0; i < entities.length ; i++) {
                            if(entities[i].typeId == "minecraft:player") 
                            {
                                let playerInv = entities[i].getComponent("inventory").container
                                var slotList = [9,18,27]
                                const dimension = block.dimension
                                for (const slot of slotList)
                                {
                                    var item = playerInv.getItem(slot)  
                                    if(item!=undefined)
                                    {
                                        dimension.spawnParticle('edx:souls_spotter',{x:entities[i].location.x,y:entities[i].location.y+1,z:entities[i].location.z});
                                        dimension.playSound('random.pop',entities[i].location);
                                        dimension.playSound('particle.soul_escape',entities[i].location);
                                        var blockBehind = dimension.getBlock({x:block.location.x-dir.x,y:block.location.y-dir.y,z:block.location.z-dir.z})
                                        var inventory = blockBehind?.getComponent("inventory")?.container;
                                        playerInv.setItem(slot, undefined);                                          
                                        try{
                                            if(inventory.emptySlotsCount!=0)
                                            {
                                                inventory.addItem(item);
                                            }
                                            else{ 
                                                        system.runTimeout(() => {
                                                dimension.spawnItem(item, {x:block.center().x-dir.x/2,y:block.center().y-dir.y/2,z:block.center().z-dir.z/2});
                                                dimension.playSound('mob.sniffer.drop_seed',block.location);
                                                 },2)
                                            }
                                        }
                                        catch(e)
                                        {

                                           system.runTimeout(() => {
                                            dimension.spawnItem(item, {x:block.center().x-dir.x/2,y:block.center().y-dir.y/2,z:block.center().z-dir.z/2});
                                            dimension.playSound('mob.sniffer.drop_seed',block.location);
                                                 },2)
                                        }
                                    }
                                }
                                
                            }
                        }
                    } 
                else if(type == 'fire_opal')
                {
                    dimension.playSound('fire.fire',block.location);
                    dimension.spawnParticle('edx:fire_opal_spotter',{x:block.center().x+pardir.x/2,y:block.center().y+pardir.y/2,z:block.center().z+pardir.z/2},vmap);
                    let entities = dimension.getEntities({location:{x:block.x+dir.x,y:block.y+dir.y,z:block.z+dir.z},volume:{x:dir.x*distance,y:dir.y*distance,z:dir.z*distance}});
                    for (let i = 0; i < entities.length ; i++) {
                            if(entities[i].typeId == "minecraft:player") 
                            {
                                entities[i].setOnFire(4)
                            }
                    }
                }
                else if(type == 'lapis')
                {
                    var xp = block.permutation.getState("edx:xp")
                    var ten_xp = block.permutation.getState("edx:ten_xp")
                    dimension.spawnParticle('edx:lapis_spotter',{x:block.center().x+dir.x*distance*1.2,y:block.center().y+dir.y*distance*1.2,z:block.center().z+dir.z*distance*1.2},vmap);
                    let entities = dimension.getEntities({location:{x:block.x+dir.x,y:block.y+dir.y,z:block.z+dir.z},volume:{x:dir.x*distance,y:dir.y*distance,z:dir.z*distance}});
                    var xp_value = 0
                    if(xp!=10 || ten_xp!=15)
                    {
                        for (let i = 0; i < entities.length ; i++) {
                            if(entities[i].typeId == "minecraft:player") 
                            {
                                    if(entities[i].level!=0 || entities[i].xpEarnedAtCurrentLevel!=0 )
                                    {
                                        
                                        if(entities[i].xpEarnedAtCurrentLevel==0)
                                        {
                                            entities[i].addLevels(-1)
                                            entities[i].addExperience(entities[i].totalXpNeededForNextLevel-1)
                                            xp_value +=1
                                        }
                                        else if(entities[i].xpEarnedAtCurrentLevel>0){
                                            entities[i].addExperience(-1);
                                            xp_value +=1
                                        } 
                                    }
                            }
                        }
                    }
                    if(xp_value!=0)
                        {
                            xp=xp+xp_value
                            if(xp>10 && ten_xp!=15)
                            {
                                xp-=10
                                ten_xp+=1
                            }
                            else if(xp>10 && ten_xp>=15)
                            {
                                xp=10
                                ten_xp=15
                            }
                            dimension.spawnParticle('edx:xp_orb_spotter',{x:block.center().x+pardir.x/1.9,y:block.center().y+pardir.y/1.9,z:block.center().z+pardir.z/1.9},vmap);
                            block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),'edx:xp': xp,'edx:ten_xp': ten_xp}));
                        }
                }
                else if(type == 'diamond')
                {
                    
                    dimension.spawnParticle('edx:diamond_spotter',{x:block.center().x+dir.x*distance*1.2,y:block.center().y+dir.y*distance*1.2,z:block.center().z+dir.z*distance*1.2},vmap);
                    let entities = dimension.getEntities({location:{x:block.x+dir.x,y:block.y+dir.y,z:block.z+dir.z},volume:{x:dir.x*distance,y:dir.y*distance,z:dir.z*distance}});
                    for (let i = 0; i < entities.length ; i++) {
                            if(entities[i].typeId == "minecraft:player") 
                            {
                                    const equipment = entities[i].getComponent('equippable');
                                    for (const slot of armorSlots) 
                                        {
                                            spotterDropItem(block,equipment,slot,dir,entities[i])
                                        } 
                            }
                    }
                }
                if(enable ==false)
                    {
                        const direction = block.permutation.getState("minecraft:facing_direction")
                        dimension.playSound('break.calcite',block.location);
                        block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),"minecraft:facing_direction": direction,"edx:type": type,"edx:enabled": false}));
                    }
                
              } catch(e) {}
       }
    });
    
    eventData.blockComponentRegistry.registerCustomComponent('soul_plant:on_destroy', {
        onPlayerBreak: ({ block,dimension }) => {
            if(Math.random() <= 1/4) {
                    dimension.spawnEntity("xp_orb",block.center());
            }
         } 
    });
    
    eventData.blockComponentRegistry.registerCustomComponent('soul_torchflower:on_destroy', {
        onPlayerBreak: ({ block,dimension }) => {
            if(Math.random() <= 1/4){
                    dimension.spawnEntity("xp_orb",block.center());
                    dimension.spawnEntity("xp_orb",block.center());
                    dimension.spawnEntity("xp_orb",block.center());
            }
         } ,
         onTick({block,dimension}) {
            try {
            dimension.spawnParticle('edx:soul_torchflower',block.center());
            } catch(e) {}
            
        }
    });

    eventData.blockComponentRegistry.registerCustomComponent('soul_vines:on_destroy', {
        onPlayerBreak: e => {
            const { block } = e;
            const {x,y,z} = block.location;
            var location = { x: e.block.location.x, y: e.block.location.y, z: e.block.location.z };
            system.runTimeout(() => { 
                e.dimension.runCommand(`fill ${location.x} ${location.y+1} ${location.z} ${location.x} ${location.y+1} ${location.z} edx:soul_vines_head replace edx:soul_vines`)
                 }
             )
             if(Math.random() <= 1/4) {
                     dimension.spawnEntity("xp_orb",block.center());
             }
         } 
    }); 
    eventData.blockComponentRegistry.registerCustomComponent('soul_vines:on_place', {
        beforeOnPlayerPlace: ({ block } )=> {
            system.runTimeout(() => { 
                if (block.below().typeId === 'minecraft:air') {
                        block.setType('edx:soul_vines_head');
                }
                if (block.above().typeId === 'edx:soul_vines_head') {
                    block.above().setType('edx:soul_vines');
                }
            })
                
        },
    }); 
eventData.blockComponentRegistry.registerCustomComponent('soul_vines:on_tick', {
    onRandomTick: e => {
        try {
        let randomTick = Math.random() <= 1/6;
            const { block } = e;
            const {x,y,z} = block.location;
            
            if (randomTick && block.below().typeId === 'minecraft:air') {
                system.runTimeout(() => { 
                    block.below().setType('edx:soul_vines_head');
                    block.setType('edx:soul_vines');
                    }
                 )
            }
        
        }catch(e) {}
    }
}
); 
eventData.blockComponentRegistry.registerCustomComponent('edx:eye_tick', {
    onRandomTick({block}) {
        try {
        let randomTick = Math.random() <= 1/6;
        if(block.permutation?.getState('edx:stage')<2)
        { 
            if(randomTick )
                block.setPermutation(BlockPermutation.resolve(block.typeId).withState("edx:stage", block.permutation.getState("edx:stage")+1))
        }  
        else if(block.permutation?.getState('edx:stage')==2)
        { 
            let randomBlueEye =  Math.random() < 1/200
            if(randomTick &&  randomBlueEye) 
                block.setPermutation(BlockPermutation.resolve(block.typeId).withState("edx:stage", 4))
            else if(randomTick &&  !randomBlueEye)
                block.setPermutation(BlockPermutation.resolve(block.typeId).withState("edx:stage", 3))
        } 
    } catch(e) {}

    }
});
eventData.blockComponentRegistry.registerCustomComponent('edx:organic_vase_tick', {
    onRandomTick({block}) {
        try {
        let randomTick = Math.random() <= 1/5;
        if(block.permutation?.getState('edx:stage')<4)
        { 
            if(randomTick )
                block.setPermutation(BlockPermutation.resolve(block.typeId).withState("edx:stage", block.permutation.getState("edx:stage")+1))
        }
    } catch(e) {}
    }
});
eventData.blockComponentRegistry.registerCustomComponent('edx:organic_vase_destroy', {
    onPlayerBreak: ({ block,dimension }) => {
            system.runTimeout(() => { 
                dimension.spawnEntity("xp_orb",block.bottomCenter());
                dimension.spawnEntity("xp_orb",block.bottomCenter());
                dimension.spawnEntity("xp_orb",block.bottomCenter());
                dimension.spawnEntity("xp_orb",block.bottomCenter());
                 }
             )
     } 
});
    eventData.blockComponentRegistry.registerCustomComponent('edx:stairs_update', {
        onPlayerBreak: ({ block}) => {
            updateStairsAround(block)
        }
        
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:slab_interact', {
        // Define the behavior when a player interacts with the slab
        beforeOnPlayerPlace(event) {
            const { block, player, face,dimension} = event
            const equipment = player.getComponent('equippable');
            const selectedItem = equipment.getEquipment('Mainhand');
            var slab = undefined
            if(face=='Up') 
                slab=block.below()
            if(face=='Down')
                slab=block.above()
            if (selectedItem?.typeId === slab?.typeId && !slab.permutation.getState('edx:double')) {
                const verticalHalf = slab.permutation.getState('minecraft:vertical_half');
                const isBottomUp = verticalHalf === 'bottom' && face === 'Up';
                const isTopDown = verticalHalf === 'top' && face === 'Down';
                if (isBottomUp || isTopDown) {
                    if (!player.matches({ gameMode: GameMode.Creative })) {
                        if (selectedItem.amount > 1) {
                            selectedItem.amount -= 1;
                            equipment.setEquipment('Mainhand', selectedItem);
                        } else if (selectedItem.amount === 1) {
                            equipment.setEquipment('Mainhand', undefined);
                        }
                    }
                    system.runTimeout(() => {
                        slab.setPermutation(slab.permutation.withState('edx:double', true));
                        dimension.playSound('use.stone',block.location);
                    })
                    event.cancel=true
                }
            }
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:slab_destroy', {
        // Define behavior when a player destroys the slab
        onPlayerBreak(e) {
            // Destructure event data for easier access
            const { player, dimension } = e;

            // Extract destroyed block permutation from event data
            const { destroyedBlockPermutation: perm } = e;

            // Check if player and equipment are valid
            if (!player || !player.getComponent('equippable')) {
                return;
            }

            // Get the item in the player's main hand
            const selectedItem = player.getComponent('equippable').getEquipment('Mainhand');

            // Check if the selected item is a pickaxe
            if (!selectedItem || !selectedItem.hasTag('minecraft:is_pickaxe')) {
                return;
            }

            // Use destroyedBlockPermutation to get the ItemStack directly
            const slabItem = perm.getItemStack(1);
            if (slabItem) {
                // Spawn the item at the destroyed block location

                                                           system.runTimeout(() => {
                dimension.spawnItem(slabItem, e.block.location);
                                                 },2)
            }
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:fake_geyser', {
        onRandomTick({block,dimension}) {
            try {
                block.setType('edx:geyser')
                dimension.spawnParticle('minecraft:campfire_smoke_particle',block.above().bottomCenter());
                system.runTimeout(() => {
                dimension.spawnParticle('minecraft:lava_particle',block.above().bottomCenter());
            }, 23)
              } catch(e) {}
            
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:geyser', {
        onStepOn({entity}) {
            entity.applyKnockback({x:0,z:0},0.6);
            entity.setOnFire(2)

        },
        onTick({block,dimension}) {
            try {
                let randomTick = Math.random() <= 1/3;
                if(randomTick)
                {
                    dimension.spawnParticle('minecraft:campfire_smoke_particle',block.above().bottomCenter());
                    system.runTimeout(() => {
                        try {
                        dimension.spawnParticle('minecraft:lava_particle',block.above().bottomCenter());
                    } catch(e) {}
                    }, 23)
                }
                randomTick = Math.random() <= 1/100;
                if( randomTick)
                {
                    block.setPermutation(BlockPermutation.resolve(block.typeId).withState("edx:discharge", true))
                }  
              } catch(e) {
              }
            
        }
    });
    
   
    eventData.blockComponentRegistry.registerCustomComponent('edx:geyser_discharge', {
        onTick({block,dimension}) {
            try {
                dimension.spawnParticle('edx:geyser_particle',{x:block.bottomCenter().x,y:block.location.y+1,z:block.bottomCenter().z});
                dimension.spawnParticle('edx:geyser_lava_particle',{x:block.bottomCenter().x,y:block.location.y+1.1,z:block.bottomCenter().z});

                const options = { maxDistance: 8}
                let entities = dimension.getEntitiesFromRay({x:block.bottomCenter().x,y:block.location.y+1,z:block.bottomCenter().z} /*Position de départ*/ , {x:0,y:1,z:0} /*Direction sale pute*/, options);
                for (let i = 0; i < entities.length ; i++) {
                    entities[i].entity.applyKnockback({x:0,z:0},1.2);
                    entities[i].entity.setOnFire(8)
                }
                let randomTick = Math.random() <= 1/200;
                if(randomTick)
                {
                    block.setPermutation(BlockPermutation.resolve(block.typeId).withState("edx:discharge", false))
                }  
              } catch(e) {}
            
            
        } 
    });
    
    eventData.blockComponentRegistry.registerCustomComponent('edx:blast_shroom', {
        onPlayerBreak({block,dimension}) {
            dimension.createExplosion(block.location, 3, { breaksBlocks: true, causesFire: true })
            if(Math.random() <= 1/4)
                dimension.spawnItem(new ItemStack("edx:sulfur",1), block.location);
        }
    }); 
    eventData.blockComponentRegistry.registerCustomComponent('edx:sculk_jaw_open', {
        onStepOn({block,dimension,entity}) {
            block.setType("edx:sculk_jaw_summon");
            const blockVolume = new BlockVolume({x:block.location.x-15,y:block.location.y-5,z:block.location.z-15}, {x:block.location.x+15,y:block.location.y+5,z:block.location.z+15});
            entity.addEffect('slowness', 200, {amplifier: 4})
            entity.applyDamage(5,{cause: "contact"})
            if(entity.typeId=="player")
            {
                dimension.fillBlocks(blockVolume, "edx:sculk_jaw_summon", { blockFilter: { includeTypes: ["edx:sculk_jaw_open"]} })
            }
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:sculk_jaw_summon', {
        onTick({block,dimension}) {
            try {
            dimension.spawnEntity("edx:sculkling",block.above().bottomCenter());
            block.setType("edx:sculk_jaw_closed");
        } catch(e) {}
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:sculk_jaw_closed', {
        onTick({block,dimension}) {
            try {
            let randomTick = Math.random() <= 1/20;
            if( randomTick)
            {
                block.setType("edx:sculk_jaw_open");
            }
            const entityOptions = {
                location: block.above().location,
                families: [ "player" ],
                maxDistance: 1
            }
            const entities = dimension.getEntities(entityOptions);
            for (let i = 0; i < entities.length ; i++) {
                entities[i].addEffect('slowness', 200, {amplifier: 4})
                entities[i].applyDamage(5,{cause: "contact"})
            }
        } catch(e) {}
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:spider_egg', {
        onPlayerBreak({block,dimension}) {
            dimension.spawnEntity("edx:baby_spider",block.bottomCenter());
            dimension.spawnEntity("edx:baby_spider",block.bottomCenter());
            dimension.spawnEntity("edx:baby_spider",block.bottomCenter());
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:spawner', {
        onTick({block,dimension}) {
            try {
            if(block.typeId==="edx:blaze_spawner")
                dimension.spawnEntity("blaze",block.above().location);
            if(block.typeId==="edx:creeper_spawner")
                dimension.spawnEntity("creeper",block.above().location);
            if(block.typeId==="edx:enderman_spawner")
                dimension.spawnEntity("enderman",block.above().location);
            if(block.typeId==="edx:ghast_spawner")
                dimension.spawnEntity("ghast",block.above().location);
            if(block.typeId==="edx:pig_spawner")
                dimension.spawnEntity("pig",block.above().location);
            if(block.typeId==="edx:sheep_spawner")
                dimension.spawnEntity("sheep",block.above().location);
            if(block.typeId==="edx:skeleton_spawner")
                dimension.spawnEntity("skeleton",block.above().location);
            if(block.typeId==="edx:slime_spawner")
                dimension.spawnEntity("slime",block.above().location);
            if(block.typeId==="edx:spider_spawner")
                dimension.spawnEntity("spider",block.above().location);
            if(block.typeId==="edx:vindicator_spawner")
                dimension.spawnEntity("vindicator",block.above().location);
            if(block.typeId==="edx:wither_spawner")
                dimension.spawnEntity("wither_skeleton",block.above().location);
            if(block.typeId==="edx:zombie_spawner")
                dimension.spawnEntity("zombie",block.above().location);
        } catch(e) {}
        }
    });
    
    eventData.blockComponentRegistry.registerCustomComponent('edx:runic_chest_on_interact', {
        // Define the behavior when a player interacts with the block
        onPlayerInteract(e) {
            const { block, player ,dimension} = e;
            const equipment = player.getComponent('equippable');
            const selectedItem = equipment.getEquipment('Mainhand');
            if (selectedItem?.typeId!='edx:runestone') return;
            block.setType("air");
            dimension.spawnEntity("edx:open_chest",block.bottomCenter())
            if(selectedItem.amount>1)
                selectedItem.amount-=1
            else
                equipment.setEquipment('Mainhand', new ItemStack('minecraft:air', 1));

        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:void_catalyst', {
        // Define the behavior when a player interacts with the block
        onTick({block}) {
            try {
            if(block.below().typeId!='edx:void_fossil_block')
                block.setType("edx:end_catalyst");
        } catch(e) {}
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:light_catalyst', {
        // Define the behavior when a player interacts with the block
        onTick({block}) {
            try {
            if(block.below().typeId!='minecraft:beacon')
                block.setType("edx:end_catalyst");
        } catch(e) {}
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:end_catalyst', {
        // Define the behavior when a player interacts with the block
        onTick({block}) {
            try {
            if(block.below().typeId=='edx:void_fossil_block')
                block.setType("edx:void_catalyst");
            else if(block.below().typeId=='minecraft:beacon')
                block.setType("edx:light_catalyst");
        } catch(e) {}
        },
        onPlayerInteract({player}){
                var CatalystMessage= {rawtext :[{ 
                translate: "message.CatalystMessage",
                }]};
            player.sendMessage(CatalystMessage);
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:active_shield', {
        onTick({block,dimension}) {
            var entityOptions = {
                location: block.location,
                families: ["player" ],
                maxDistance: 50
            }
            var isEntity = false
            var entities = dimension.getEntities(entityOptions);
            for (const entity of entities) {
                    if(!entity.matches({ gameMode: GameMode.Spectator }) && !entity.matches({ gameMode: GameMode.Creative }))
                    {
                        isEntity=true
                        if(world.scoreboard.getObjective("shield").getScore(entity)==0)
                        {
                entity.runCommand(`scoreboard players set @s shield 24`)
                var AreaProtectedMessage= {rawtext :[{ 
                translate: "message.AreaProtectedMessage",
                }]};
                        entity.sendMessage(AreaProtectedMessage)
                        }
                        else
                        {
                            
                            entity.spawnParticle('edx:no_build_circle',{x:block.bottomCenter().x,y:block.location.y,z:block.bottomCenter().z});
                            entity.runCommand(`scoreboard players set @s shield 12`)
                        }
                    }
            }
            if(isEntity)
            {
                dimension.spawnParticle('edx:no_build_block_particle',{x:block.bottomCenter().x,y:block.location.y,z:block.bottomCenter().z});
            }
            entityOptions = {
                location: block.location,
                families: ["creeper" ],
                maxDistance: 50
            }
            entities = dimension.getEntities(entityOptions);
            for (const entity of entities) {
                    entity.addTag('no_grief')
            }
            
        },
        onPlayerInteract({block}){
            block.setType("edx:unactive_shield");
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:unactive_shield', {
        onPlayerInteract({block}){
            block.setType("edx:active_shield");
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:trapdoor_on_interact', {
        onPlayerInteract({ block, player }) {
            const currentState = block.permutation.getState('edx:open');
            const newOpenState = !currentState;
            const newPermutation = BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),'edx:open': newOpenState});
            block.setPermutation(newPermutation);
            const sound = currentState ? 'open.wooden_trapdoor' : 'close.wooden_trapdoor';
            player.playSound(sound);
            
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:block_breaker', {
        onTick({block,dimension}) {
            try {
            const UnbreakListId = ["air","bedrock","end_portal_frame","reinforced_deepslate","edx:runic_chest","water","lava","portal","trial_spawner","vault"]
            const direction = block.permutation.getState("minecraft:block_face")
            var blockBreak = undefined
            if(direction=='up')
                blockBreak = block.above()
            else if(direction=='down')
                blockBreak = block.below()
            else if(direction=='north')
                blockBreak = block.north()
            else if(direction=='south')
                blockBreak = block.south()
            else if(direction=='west')
                blockBreak = block.west()
            else if(direction=='east')
                blockBreak = block.east()
            if(!UnbreakListId.includes(blockBreak?.typeId))
                dimension.runCommand(`setblock ${blockBreak.location.x} ${blockBreak.location.y} ${blockBreak.location.z} air destroy`)
        } catch(e) {}
        }
        
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:crab_eggs', {
        onRandomTick({block,dimension}) {
        let randomTick = Math.random() <= 1/6;
            if(randomTick ) 
                {
            dimension.spawnEntity("edx:crab_larva",block.bottomCenter());
            dimension.spawnEntity("edx:crab_larva",block.bottomCenter());
            dimension.spawnEntity("edx:crab_larva",block.bottomCenter());
            block.setType("air")
        }
        }
    });

    eventData.blockComponentRegistry.registerCustomComponent("edx:precise_rotation", {
        beforeOnPlayerPlace(event) {
          const { player } = event;
          if (!player) return; // Exit if the player is undefined 
    
          const blockFace = event.permutationToPlace.getState("minecraft:block_face");
          if (blockFace !== "up") return; // Exit if the block hasn't been placed on the top of another block
    
          // Get the rotation using the function from earlier
          const playerYRotation = player.getRotation().y;
          const rotation = getPreciseRotation(playerYRotation);
    
          // Tell Minecraft to place the correct `wiki:rotation` value
          event.permutationToPlace = event.permutationToPlace.withState("wiki:rotation", rotation);
        }
      });
      eventData.blockComponentRegistry.registerCustomComponent("edx:precise_rotation_sign", {
        beforeOnPlayerPlace(event) {
          const { player } = event;
          if (!player) return; // Exit if the player is undefined 
    
    
          // Get the rotation using the function from earlier
          const playerYRotation = player.getRotation().y;
          const rotation = getPreciseRotation(playerYRotation);
    
          // Tell Minecraft to place the correct `wiki:rotation` value
          event.permutationToPlace = event.permutationToPlace.withState("wiki:rotation", rotation);
        }
      });
      eventData.blockComponentRegistry.registerCustomComponent("edx:sign_interact",{
        onPlayerInteract({ block, player }) {
            const equipment = player.getComponent('equippable');
            const selectedItem = equipment.getEquipment('Mainhand');
            if(selectedItem?.typeId!=undefined)
            {
                if(selectedItem.typeId == 'minecraft:stick')
                    {    
                        const tilt = block.permutation.getState('wiki:tilt');
                        if(tilt==0)
                            block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),'wiki:tilt': 1}));
                        if(tilt==1)
                            block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),'wiki:tilt': 2}));
                        if(tilt==2)
                            block.setPermutation( BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),'wiki:tilt': 3}));
                        if(tilt==3)
                            block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),'wiki:tilt': 0}));
                        
                    }
            }
            else
            {
                const direction = block.permutation.getState('wiki:direction');
                if(direction == 1)
                    block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),'wiki:direction': 2}));
                else if(direction == 2 )
                    block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),'wiki:direction': 1}));


            }

        }
      });

    //mushroom! mushroom! mushroom! mushroom!
    eventData.blockComponentRegistry.registerCustomComponent('cordyceps:interact', {
        onPlayerInteract: e => {
            const { block, player,dimension } = e;
            const {x,y,z} = block.location;
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if (selectedItem && (selectedItem.typeId === 'minecraft:bone_meal')) {
                
                    player.playSound('item.bone_meal.use');
                    dimension.spawnParticle('minecraft:crop_growth_emitter',{x:block.bottomCenter().x,y:block.location.y,z:block.bottomCenter().z});
                    if(Math.random()<1/3)
                    {
                        if(treeSpaceCheck({x:0,y:1,z:0},14,dimension,block))
                        {
                            const randomRot = Math.round(Math.random()*3)
                            const randomStruct = Math.round(Math.random()*2+1)
                            const structName = 'mystructure:big_cordyceps'+randomStruct.toString()
                            world.structureManager.place(structName, dimension, { x:x-2, y:y, z:z-2 },{rotation: rotation[randomRot]}); 
                        }
                            
                    }
                    if (!player.matches({ gameMode: GameMode.Creative })) {
                        if (selectedItem.amount > 1) {
                            selectedItem.amount -= 1;
                            equipment.setEquipment('Mainhand', selectedItem);
                        } else {
                            equipment.setEquipment('Mainhand', undefined); 
                        }
                }
                
                
            }
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:yellow_mushroom', {
        onPlayerInteract: e => {
            const { block, player,dimension } = e;
            const {x,y,z} = block.location;
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if (selectedItem && (selectedItem.typeId === 'edx:yellow_spore_bag_it')) {
                
                    player.playSound('item.bone_meal.use');
                    dimension.spawnParticle('minecraft:crop_growth_emitter',{x:block.bottomCenter().x,y:block.location.y,z:block.bottomCenter().z});
                    if(Math.random()<1/5)
                    {
                        if(treeSpaceCheck({x:0,y:-1,z:0},9,dimension,block))
                        {
                            const randomRot = Math.round(Math.random()*3)
                            const randomStruct = Math.round(Math.random()*2+1)
                            const structName = 'mystructure:big_yellow_mush'+randomStruct.toString()
                            world.structureManager.place(structName, dimension, { x:x-2, y:y-8, z:z-2 },{rotation: rotation[randomRot]}); 
                        }
                            
                    }
                    if (!player.matches({ gameMode: GameMode.Creative })) {
                        if (selectedItem.amount > 1) {
                            selectedItem.amount -= 1;
                            equipment.setEquipment('Mainhand', selectedItem);
                        } else {
                            equipment.setEquipment('Mainhand', undefined); 
                        }
                }
                
                
            }
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:blue_mushroom', {
        onPlayerInteract: e => {
            const { block, player,dimension } = e;
            const {x,y,z} = block.location;
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if (selectedItem && (selectedItem.typeId === 'edx:blue_spore_bag_it')) {
                
                    player.playSound('item.bone_meal.use');
                    dimension.spawnParticle('minecraft:crop_growth_emitter',{x:block.bottomCenter().x,y:block.location.y,z:block.bottomCenter().z});
                    if(Math.random()<1/3)
                    {
                        if(treeSpaceCheck({x:0,y:1,z:0},14,dimension,block))
                        {
                            const randomRot = Math.round(Math.random()*3)
                            const randomStruct = Math.round(Math.random()*2+1)
                            const structName = 'mystructure:big_blue_mush'+randomStruct.toString()
                            world.structureManager.place(structName, dimension, { x:x-2, y:y, z:z-2 },{rotation: rotation[randomRot]}); 
                        }
                            
                    }
                    if (!player.matches({ gameMode: GameMode.Creative })) {
                        if (selectedItem.amount > 1) {
                            selectedItem.amount -= 1;
                            equipment.setEquipment('Mainhand', selectedItem);
                        } else {
                            equipment.setEquipment('Mainhand', undefined); 
                        }
                }
                
                
            }
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:white_mushroom', {
        onPlayerInteract: e => {
            const { block, player,dimension } = e;
            const {x,y,z} = block.location;
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if (selectedItem && (selectedItem.typeId === 'minecraft:bone_meal')) {
                
                    player.playSound('item.bone_meal.use');
                    dimension.spawnParticle('minecraft:crop_growth_emitter',{x:block.bottomCenter().x,y:block.location.y,z:block.bottomCenter().z});
                    if(Math.random()<1/3)
                    {
                        if(treeSpaceCheck({x:0,y:1,z:0},14,dimension,block))
                        {
                            const randomRot = Math.round(Math.random()*3)
                            const randomStruct = Math.round(Math.random()*2+1)
                            const structName = 'mystructure:big_white'+randomStruct.toString()
                            world.structureManager.place(structName, dimension, { x:x-3, y:y, z:z-3 },{rotation: rotation[randomRot]}); 
                        }
                            
                    }
                    if (!player.matches({ gameMode: GameMode.Creative })) {
                        if (selectedItem.amount > 1) {
                            selectedItem.amount -= 1;
                            equipment.setEquipment('Mainhand', selectedItem);
                        } else {
                            equipment.setEquipment('Mainhand', undefined); 
                        }
                    }
                
                
            }
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:green_mushroom', {
        onPlayerInteract: e => {
            const { block, player,dimension } = e;
            const {x,y,z} = block.location;
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if (selectedItem && (selectedItem.typeId === 'minecraft:bone_meal')) {
                
                    player.playSound('item.bone_meal.use');
                    dimension.spawnParticle('minecraft:crop_growth_emitter',{x:block.bottomCenter().x,y:block.location.y,z:block.bottomCenter().z});
                    if(Math.random()<1/3)
                    {
                        if(treeSpaceCheck({x:0,y:1,z:0},14,dimension,block))
                        {
                            const randomRot = Math.round(Math.random()*3)
                            const randomStruct = Math.round(Math.random()*2+1)
                            const structName = 'mystructure:big_green'+randomStruct.toString()
                            world.structureManager.place(structName, dimension, { x:x-4, y:y, z:z-4 },{rotation: rotation[randomRot]}); 
                        }
                            
                    }
                    if (!player.matches({ gameMode: GameMode.Creative })) {
                        if (selectedItem.amount > 1) {
                            selectedItem.amount -= 1;
                            equipment.setEquipment('Mainhand', selectedItem);
                        } else {
                            equipment.setEquipment('Mainhand', undefined); 
                        }
                }
                
                
            }
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('blue_spore_bag:destroy', {
        onPlayerBreak: e => {
            const { block,dimension } = e;
            const entityOptions = {
                location: block.location,
                families: [ "player" ],
                maxDistance: 2.5
            }
            const entities = dimension.getEntities(entityOptions);
            if(entities!=undefined)
            for (let i = 0; i < entities.length ; i++){
                if(entities[i]!=undefined)
                {
                entities[i].addEffect('speed', 200, {amplifier: 0})
                entities[i].addEffect('poison', 200, {amplifier: 0})
                }
            }
        }
       }   
    );  
    eventData.blockComponentRegistry.registerCustomComponent('blue_spore_bag:interact', {
        onPlayerInteract: e => {
            const { block ,player,dimension} = e;
            dimension.runCommand(`loot spawn  ${block.bottomCenter().x} ${block.location.y} ${block.bottomCenter().z} loot blue_spore_bag_it`)
            player.playSound('block.sweet_berry_bush.pick');
            block.setType('edx:empty_blue_spore_bag')
        }
       }   
    );
    eventData.blockComponentRegistry.registerCustomComponent('edx:yellow_spore_bag', {
        onPlayerBreak: e => {
            const { block,dimension } = e;
            const entityOptions = {
                location: block.location,
                families: [ "player" ],
                maxDistance: 2.5
            }
            const entities = dimension.getEntities(entityOptions);
            if(entities!=undefined)
            for (let i = 0; i < entities.length ; i++){
                if(entities[i]!=undefined)
                    {
                    entities[i].addEffect('haste', 200, {amplifier: 0})
                    entities[i].addEffect('poison', 200, {amplifier: 0})
                    }
            }
        },
        onPlayerInteract: e => {
            const { block ,player,dimension} = e;
            dimension.runCommand(`loot spawn  ${block.bottomCenter().x} ${block.location.y} ${block.bottomCenter().z} loot yellow_spore_bag_it`)
            player.playSound('block.sweet_berry_bush.pick');
            block.setType('edx:empty_yellow_spore_bag')
        }
       }   
    );  
    eventData.blockComponentRegistry.registerCustomComponent('big_yellow_tree_block:tick', {
        onRandomTick: e => {
            try {
            const { block ,dimension} = e;
            const {x,y,z} = block.location;
            block.setType("air")
                const randomRot = Math.round(Math.random()*3)
                const randomStruct = Math.round(Math.random()*2+1)
                const structName = 'mystructure:big_yellow_mush'+randomStruct.toString()
                world.structureManager.place(structName, dimension, { x:x-2, y:y, z:z-2 },{rotation: rotation[randomRot]});
            } catch(e) {}
        }
       }   
    );
    eventData.blockComponentRegistry.registerCustomComponent('edx:mushroom_scarecrow', {
        
        onPlayerInteract: e => {
            const { block, player } = e;
            var {x,y,z} = block.location;
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if (selectedItem && (selectedItem.typeId === 'minecraft:bone_meal')) {
                    player.playSound('item.bone_meal.use');
                    for(var i=-2; i<=2; i++) {
                        for(var p=-2; p<=2; p++) {
                        
                    if (block?.dimension?.getBlock({x:block.location.x+i, y:block.location.y, z:block.location.z })?.permutation?.getState("growth") != undefined ) {
                        block.dimension.getBlock({x:block.location.x+i, y:block.location.y, z:block.location.z }).setPermutation( BlockPermutation.resolve(block.dimension.getBlock({x:block.location.x+i, y:block.location.y, z:block.location.z }).typeId).withState("growth",7) )
                    }
                        if (block?.dimension?.getBlock({x:block.location.x, y:block.location.y, z:block.location.z+i })?.permutation?.getState("growth") != undefined ) {
                        block.dimension.getBlock({x:block.location.x, y:block.location.y, z:block.location.z+i }).setPermutation( BlockPermutation.resolve(block.dimension.getBlock({x:block.location.x, y:block.location.y, z:block.location.z+i }).typeId).withState("growth",7) )
                    }
                        if (block?.dimension?.getBlock({x:block.location.x+p, y:block.location.y, z:block.location.z+i })?.permutation?.getState("growth") != undefined ) {
                        block.dimension.getBlock({x:block.location.x+p, y:block.location.y, z:block.location.z+i }).setPermutation( BlockPermutation.resolve(block.dimension.getBlock({x:block.location.x+p, y:block.location.y, z:block.location.z+i }).typeId).withState("growth",7) )
                    }
                        if (block?.dimension?.getBlock({x:block.location.x+i, y:block.location.y, z:block.location.z+p })?.permutation?.getState("growth") != undefined ) {
                        block.dimension.getBlock({x:block.location.x+i, y:block.location.y, z:block.location.z+p }).setPermutation( BlockPermutation.resolve(block.dimension.getBlock({x:block.location.x+i, y:block.location.y, z:block.location.z+p }).typeId).withState("growth",7) )
                    }
                } 
                }
                    if (!player.matches({ gameMode: GameMode.Creative })) {
                        if (selectedItem.amount > 1) {
                            selectedItem.amount -= 1; 
                            equipment.setEquipment('Mainhand', selectedItem);
                        } else {
                            equipment.setEquipment('Mainhand', undefined); 
                        }
                }
            }
        }
       }   
    ); 
    eventData.blockComponentRegistry.registerCustomComponent('fungus_vine:on_place', {
        onPlace: e => {
            const { block } = e;
            const belowBlock = block.below();
            if (belowBlock.typeId === 'minecraft:air') {
                block.setPermutation(BlockPermutation.resolve(block.typeId).withState("propertie:connect",1))
            }
            if(block.above().typeId == "edx:fungus_vine" )
                block.above().setPermutation(BlockPermutation.resolve(block.above().typeId).withState("propertie:connect",0))
        },
    }); 
    eventData.blockComponentRegistry.registerCustomComponent('fungus_vine:on_destroy', {
        onPlayerBreak: e => {
            const { block ,dimension} = e;
            if(block.above().typeId == "edx:fungus_vine" )
                block.above().setPermutation(BlockPermutation.resolve(block.above().typeId).withState("propertie:connect",0))
         } 
    });
    eventData.blockComponentRegistry.registerCustomComponent('endermite_egg:on_destroy', {
        onPlayerBreak: ({ block,dimension }) => {
            dimension.spawnEntity("endermite",block.bottomCenter());
            dimension.spawnEntity("endermite",block.bottomCenter());
            dimension.spawnEntity("endermite",block.bottomCenter());
         } 
    }); 
    eventData.blockComponentRegistry.registerCustomComponent('blue_lycaephytus:on_destroy', {
        onPlayerBreak: e => {
            const { block ,dimension} = e;
            const entityOptions = {
                location: block.location,
                families: [ "player" ],
                maxDistance: 2.5
            }
            const entities = dimension.getEntities(entityOptions);
            for (let i = 0; i < entities.length ; i++) {
                entities[i].addEffect('levitation', 200, {amplifier: 0})
            }
         } 
    }); 
    eventData.blockComponentRegistry.registerCustomComponent('blue_lycaephytus:interact', {
        onPlayerInteract: e => {
            const { block, player} = e;
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if (selectedItem && (selectedItem.typeId === 'minecraft:glass_bottle')) {
                player.getComponent("inventory").container.addItem(new ItemStack('edx:levitation_potion', 1))
                block.setType('edx:blue_lycaephytus_no_ball' )
                if (!player.matches({ gameMode: GameMode.Creative })) {
                    if (selectedItem.amount > 1) {
                        selectedItem.amount -= 1;
                        equipment.setEquipment('Mainhand', selectedItem);
                    } else {
                        equipment.setEquipment('Mainhand', undefined); // Clear the slot if only 1 item left
                    }
                    e.cancel = true;
                }
            }
        }
       }   
    );
    eventData.blockComponentRegistry.registerCustomComponent('structure:red_right', {
        onTick: ({block,dimension}) => {
            const random = Math.round(Math.random()+1)
            const {x,y,z} = block.location
            block.setType("air")
            const structName = "mystructure:R_right"+ random 
            world.structureManager.place(structName, dimension, { x:x-9, y:y-6, z:z-22 });
        }
       }   
    );
    eventData.blockComponentRegistry.registerCustomComponent('structure:red_left', {
        onTick: ({block,dimension}) => {
            const random = Math.round(Math.random()+1)
            const {x,y,z} = block.location
            block.setType("air")
            const structName = "mystructure:R_left"+ random 
            world.structureManager.place(structName, dimension, { x:x-9, y:y-6, z:z+1 });
        }
       }   
    );
    eventData.blockComponentRegistry.registerCustomComponent('structure:orange_right', {
        onTick: ({block,dimension}) => {
            const random = Math.round(Math.random()+1)
            const {x,y,z} = block.location
            block.setType("air")
            const structName = "mystructure:O_right"+ random 
            world.structureManager.place(structName, dimension, { x:x-9, y:y-6, z:z-22 });
        }
       }   
    );
    eventData.blockComponentRegistry.registerCustomComponent('structure:orange_left', {
        onTick: ({block,dimension}) => {
            const random = Math.round(Math.random()+1)
            const {x,y,z} = block.location
            block.setType("air")
            const structName = "mystructure:O_left"+ random 
            world.structureManager.place(structName, dimension, { x:x-9, y:y-6, z:z+1 });
        }
       }   
    );
    eventData.blockComponentRegistry.registerCustomComponent('structure:green_right', {
        onTick: ({block,dimension}) => {
            const random = Math.round(Math.random()+1)
            const {x,y,z} = block.location
            block.setType("air")
            const structName = "mystructure:G_right"+ random 
            world.structureManager.place(structName, dimension, { x:x-9, y:y-6, z:z-22 });
        }
       }   
    );
    eventData.blockComponentRegistry.registerCustomComponent('structure:green_left', {
        onTick: ({block,dimension}) => {
            const random = Math.round(Math.random()+1)
            const {x,y,z} = block.location
            block.setType("air")
            const structName = "mystructure:G_left"+ random 
            world.structureManager.place(structName, dimension, { x:x-9, y:y-6, z:z+1 });
        }
       }   
    );
    eventData.blockComponentRegistry.registerCustomComponent('structure:W_right', {
        onTick: ({block,dimension}) => {
            const random = Math.round(Math.random()*8+1)
            const {x,y,z} = block.location
            block.setType("air")
            const structName = "mystructure:W"+ random + "_right"
            world.structureManager.place(structName, dimension, { x:x-9, y:y, z:z-9 });
        }
       }   
    );
    eventData.blockComponentRegistry.registerCustomComponent('structure:W_middle', {
        onTick: ({block,dimension}) => {
            const random = Math.round(Math.random()*8+1)
            const {x,y,z} = block.location
            block.setType("air")
            const structName = "mystructure:W"+ random + "_middle"
            world.structureManager.place(structName, dimension, { x:x-9, y:y, z:z-9 });
        }
       }   
    );
    eventData.blockComponentRegistry.registerCustomComponent('structure:W_left', {
        onTick: ({block,dimension}) => {
            const random = Math.round(Math.random()*8+1)
            const {x,y,z} = block.location
            block.setType("air")
            const structName = "mystructure:W"+ random + "_left"
            world.structureManager.place(structName, dimension, { x:x-9, y:y, z:z-9 });
        }
       }   
    );
    eventData.blockComponentRegistry.registerCustomComponent('structure:U_middle', {
        onTick: ({block,dimension}) => {
            const random = Math.round(Math.random()*8+1)
            const {x,y,z} = block.location
            block.setType("air")
            const structName = "mystructure:U"+ random + "_right"
            world.structureManager.place(structName, dimension, { x:x-9, y:y, z:z-9 });
        }
       }   
    );
    eventData.blockComponentRegistry.registerCustomComponent('structure:U_right', {
        onTick: ({block,dimension}) => {
            const random = Math.round(Math.random()*8+1)
            const {x,y,z} = block.location
            block.setType("air")
            const structName = "mystructure:U"+ random + "_middle"
            world.structureManager.place(structName, dimension, { x:x-9, y:y, z:z-9 });
        }
       }   
    );
    eventData.blockComponentRegistry.registerCustomComponent('structure:U_left', {
        onTick: ({block,dimension}) => {
            const random = Math.round(Math.random()*8+1)
            const {x,y,z} = block.location
            block.setType("air")
            const structName = "mystructure:U"+ random + "_left"
            world.structureManager.place(structName, dimension, { x:x-9, y:y, z:z-9 });
        }
       }   
    );
    eventData.blockComponentRegistry.registerCustomComponent('structure:L_right', {
        onTick: ({block,dimension}) => {
            const random = Math.round(Math.random()*8+1)
            const {x,y,z} = block.location
            block.setType("air")
            const structName = "mystructure:L"+ random + "_right"
            world.structureManager.place(structName, dimension, { x:x-9, y:y, z:z-9 });
        }
       }   
    );
    eventData.blockComponentRegistry.registerCustomComponent('structure:L_middle', {
        onTick: ({block,dimension}) => {
            const random = Math.round(Math.random()*8+1)
            const {x,y,z} = block.location
            block.setType("air")
            const structName = "mystructure:L"+ random + "_middle"
            world.structureManager.place(structName, dimension, { x:x-9, y:y, z:z-9 });
        }
       }   
    );
    eventData.blockComponentRegistry.registerCustomComponent('structure:L_left', {
        onTick: ({block,dimension}) => {
            const random = Math.round(Math.random()*8+1)
            const {x,y,z} = block.location
            block.setType("air")
            const structName = "mystructure:L"+ random + "_left"
            world.structureManager.place(structName, dimension, { x:x-9, y:y, z:z-9 });
        }
       }   
    );
    eventData.blockComponentRegistry.registerCustomComponent('edx:fume_fan', {
        onPlace: event => {
            const { block } = event;
            system.runTimeout(() => { 
                block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),"edx:locked": false}));
                 }
             )
            
        },
        onTick({block,dimension}) {
            const direction = block.permutation.getState("minecraft:facing_direction")
            const intensity = block.permutation.getState("edx:intensity")
            var dir = {x:0,y:1,z:0}
            if(direction=='up')
                dir = {x:0,y:1,z:0}
            else if(direction=='down')
                dir = {x:0,y:-1,z:0}
            else if(direction=='north')
                dir = {x:0,y:0,z:-1}
            else if(direction=='south')
                dir = {x:0,y:0,z:1}
            else if(direction=='west')
                dir = {x:-1,y:0,z:0}
            else if(direction=='east')
                dir = {x:1,y:0,z:0}
            try {
                const vmap = new MolangVariableMap();
                vmap.setVector3('variable.direction', {x:dir.x,y:dir.y,z:dir.z});
                vmap.setFloat('variable.intensity', intensity);
                dimension.spawnParticle('edx:fume_fan_particle',{x:block.center().x+dir.x/2,y:block.center().y+dir.y/2,z:block.center().z+dir.z/2},vmap);
                const options = { maxDistance:  intensity*8-1}
                var distance = intensity*8-1
                const rayBlock = dimension.getBlockFromRay({x:block.center().x+dir.x,y:block.center().y+dir.y,z:block.center().z+dir.z},dir,options)?.block
                if(rayBlock!=undefined)
                {
                    distance = Math.sqrt(
                        Math.pow(block.x - rayBlock.x, 2) +
                        Math.pow(block.y - rayBlock.y, 2) +
                        Math.pow(block.z - rayBlock.z, 2)
                    )-1;
                }
                let entities = dimension.getEntities({location:{x:block.x+dir.x,y:block.y+dir.y,z:block.z+dir.z},volume:{x:dir.x*distance,y:dir.y*distance,z:dir.z*distance}});
                for (let i = 0; i < entities.length ; i++) {
                        if(entities[i].hasComponent('minecraft:item')) {
                            entities[i].applyImpulse({ x: dir.x*intensity*0.2, y: dir.y*intensity*0.2, z: dir.z*intensity*0.2 })
                        }
                        else
                        {
                            const power = (0.5+intensity*0.5)*0.6*dir.z+(0.5+intensity*0.5)*0.6*dir.x
                            entities[i].applyKnockback({x:Math.abs(dir.x)*power,z:Math.abs(dir.z)*power}, (0.5+intensity*0.5)*0.6*dir.y);
                        }
                            
                    
                }
              } catch(e) {}
        },
        onPlayerInteract({ block, player}) {
            const equipment = player.getComponent('equippable');
            const selectedItem = equipment.getEquipment('Mainhand');
            const direction = block.permutation.getState("minecraft:facing_direction")
            const intensity = block.permutation.getState("edx:intensity")
            const locked = block.permutation.getState("edx:locked")
            if(selectedItem?.typeId === "edx:fire_opal" && locked!=true)
            {
                if (!player.matches({ gameMode: GameMode.Creative }) ) {
                    if (selectedItem.amount > 1) {
                        selectedItem.amount -= 1;
                        equipment.setEquipment('Mainhand', selectedItem);
                    } else {
                        equipment.setEquipment('Mainhand', undefined); 
                    }
                }
                block.dimension.playSound('lodestone_compass.link_compass_to_lodestone', block.center());
                block.setPermutation(BlockPermutation.resolve(block.typeId, {...block.permutation.getAllStates(),"edx:locked": true}));
            }
            else if(locked!=true)
            {
                block.dimension.playSound('block.click', block.center());
                block.setPermutation(BlockPermutation.resolve(block.typeId, {"minecraft:facing_direction": direction,"edx:locked": locked,"edx:intensity": intensity<3 ? intensity+1 : 0}));
            }
            
        }
    });
    
   
    eventData.blockComponentRegistry.registerCustomComponent('edx:leaves', {
        onPlayerBreak({block,player}) {
            const equipment = player.getComponent('equippable'); 
            const selectedItem = equipment.getEquipment('Mainhand');
            if (selectedItem && (selectedItem.typeId === 'minecraft:shears')){
                    const Item = perm.getItemStack(1);
                if (Item) {
                    
                                                                               system.runTimeout(() => {
                dimension.spawnItem(Item, block.bottomCenter());
                                                 },2)
                }
            }
            else if(Math.random()<1/6)
            {
              system.runTimeout(() => {
                dimension.spawnItem(new ItemStack('edx:redwood_sapling', 1), block.bottomCenter());
                },2)
            }
        },
        onRandomTick({block}) {
            if(Math.random()<=1/20 && block.permutation.getState('edx:can_despawn') )
            {
                try{
                    if (!isWithinRadiusOfAllowedBlock(block,6,["edx:redwood_log","edx:redwood_wood"])) 
                    {
              system.runTimeout(() => {
                                        block.setType('minecraft:air')
                        block.dimension.spawnItem(new ItemStack("edx:redwood_sapling_it", 1), block.bottomCenter());
                },2)                  
              }
                }
                catch(e){}
            }
            if(Math.random()<=1/25)
            {
                block.dimension.spawnParticle('edx:redwood_leaves',block.bottomCenter());
            }
        }


    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:magmroll_shell', {
        onPlayerInteract({block,dimension}) {
            
            var ent = dimension.spawnEntity("edx:magmroll_shell",block.bottomCenter());
            var rot ={x:0,y:180}
            if(block.permutation.getState('minecraft:cardinal_direction')=='south')
            {
                rot ={x:0,y:0}
            }
            if(block.permutation.getState('minecraft:cardinal_direction')=='east')
            {
                rot ={x:0,y:270}
            }
            if(block.permutation.getState('minecraft:cardinal_direction')=='west')
            {
                rot ={x:0,y:90}
            }
            block.setType("air")
            ent.setRotation(rot)
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('edx:redwood_sapling', {
        onRandomTick({block,dimension}) {
            try {
            if(Math.random()<=1/12)
            {
                if(block.south().typeId == 'edx:redwood_sapling' && block.south().east().typeId == 'edx:redwood_sapling' && block.east().typeId == 'edx:redwood_sapling')
                    dimension.runCommand(`execute if blocks ${block.location.x}-9 ${block.location.y}+2 ${block.location.z}-9 ${block.location.x}+14 ${block.location.y}+36 ${block.location.z}+14 ${block.location.x}-9 ${block.location.y}+36 ${block.location.z}-9 masked if block ${block.location.x} ${block.location.y}+1 ${block.location.z} air if block ${block.location.x} ${block.location.y}+3 ${block.location.z}+1 air if block ${block.location.x}-3 ${block.location.y}+40 ${block.location.z}+2 air run structure load Redwood_tree ${block.location.x}-9 ${block.location.y} ${block.location.z}-9`)
            }
        } catch(e) {}
        }


    });
    eventData.blockComponentRegistry.registerCustomComponent('gate:on_interact', {
        // Define the behavior when a player interacts with the fence gate
        onPlayerInteract(e) {
            // Destructure event data for easier access
            const { block, player, face } = e;

            // Get the equipment component for the player
            const equipment = player.getComponent('equippable');
            // Get the selected item from the player's mainhand
            const selectedItem = equipment.getEquipment('Mainhand');

            // Check if a player tried to place a block on top of the fence gate
            if (selectedItem && face === 'Up' && BlockTypes.get(selectedItem.typeId)) {
                // Calculate the position above the current block
                const aboveBlock = block.above();

                // If the block above is a edx:fence_gate (an equivalent of air)...
                if (aboveBlock.typeId === 'edx:redwood_gate') {
                    // ...place the selected block above the current block
                    aboveBlock.setType(selectedItem.typeId);
                    
                    // Reduce item count if not in creative mode
                    if (!player.matches({ gameMode: GameMode.Creative })) {
                        if (selectedItem.amount > 1) {
                            selectedItem.amount -= 1;
                            equipment.setEquipment('Mainhand', selectedItem);
                        } else {
                            equipment.setEquipment('Mainhand', undefined); // Clear the slot if only 1 item left
                        }
                    }
                    return; // Exit the function after placing the block
                }
            }

            // Toggle the 'edx:open' state between false and true and determine the sound effect to play
            const currentState = block.permutation.getState('edx:open');
            const newOpenState = !currentState;
            const sound = newOpenState ? 'open.fence_gate' : 'close.fence_gate';

            // Determine the new cardinal direction based on the player's rotation
            const rotationAngle = player.getRotation().y;
            const newCardinalDirection = getNewCardinalDirection(block.permutation.getState('minecraft:cardinal_direction'), rotationAngle);

            // Update the block's permutation with the new states
            const newPermutation = BlockPermutation.resolve(block.typeId, {
                ...block.permutation.getAllStates(),
                'edx:open': newOpenState,
                'minecraft:cardinal_direction': newCardinalDirection
            });

            // Apply the new permutation and play the sound
            block.setPermutation(newPermutation);
            block.dimension.playSound(sound, block.location);

            // Corrected: Remove redeclaration of aboveBlock
            const aboveBlock = block.above();
            // Checks if the block above our fence gate is an invisible fence gate (equivalent to air)
            if (aboveBlock.typeId === 'edx:redwood_gate' && aboveBlock.permutation.getState('edx:invisible')) {
                const aboveCurrentState = aboveBlock.permutation.getState('edx:open');
                // Update edx:open state of the invisible fence gate above our fence gate
                if (aboveCurrentState !== newOpenState) {
                    const newAbovePermutation = BlockPermutation.resolve(aboveBlock.typeId, {
                        ...aboveBlock.permutation.getAllStates(),
                        'edx:open': newOpenState
                    });
                    aboveBlock.setPermutation(newAbovePermutation);
                }
            }
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('gate:on_player_destroy', {
        // Define behavior when a player destroys the fence
        onPlayerBreak(e) {
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('gate:on_player_placed', {
        // Define behavior when a player places the fence
        onPlace(e) {
            // Destructure event data for easier access
            const { block } = e;

            // Get all current block states
            const currentStates = block.permutation.getAllStates();

            // Get the current state of the 'minecraft:cardinal_direction' block trait
            const cardinalDirection = currentStates['minecraft:cardinal_direction'];

            // Check if the current cardinal direction is 'south'
            if (cardinalDirection === 'south') {
                // Change the block state 'edx:direction' from false to true (remember this is the actual south rotation for our fence gate)
                const newedxDirection = true;
                currentStates['edx:direction'] = newedxDirection;

                // Update the block's permutation with the new state
                const newPermutation = BlockPermutation.resolve(block.typeId, currentStates);

                // Apply the new permutation to the block
                block.setPermutation(newPermutation);
            }
            const allowedBlocks = ['minecraft:cobblestone_wall', 'minecraft:stone_wall'];
            // Function to check if any adjacent blocks are of allowed types
            const hasAllowedBlock = (blocks) => blocks.some(adjacentBlock => allowedBlocks.includes(adjacentBlock?.typeId));

            // Check if any allowed adjacent blocks exist based on the cardinal direction
            const hasAllowedAdjacentBlock = (cardinalDirection === 'north' || cardinalDirection === 'south')
                ? hasAllowedBlock([adjacentBlocks.east, adjacentBlocks.west])
                : hasAllowedBlock([adjacentBlocks.north, adjacentBlocks.south]);

            // Update edx:in_wall_bit state based on adjacent blocks
            block.setPermutation(block.permutation.withState('edx:in_wall_bit', hasAllowedAdjacentBlock));
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('gate:on_tick', {
        onTick(e) {
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('fence:on_tick', {
        onTick(e) {
            fenceConnect(e)
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('fence:on_place', {
        onPlace(e) {
            fenceConnect(e)
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('wall:on_tick', {
        onTick(e) {
            wallConnect(e)
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('wall:on_place', {
        onPlace(e) {
            wallConnect(e)
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('door:on_interact', {
        // Define the behavior when a player interacts with the door block
        onPlayerInteract(e) {
            // Destructure event data for easier access
            const { block, player } = e;
            const isUpperBlock = block.permutation.getState('edx:upper_block_bit');

            // Get the equipment component for the player
            const equipment = player.getComponent('equippable');

            // Get the selected item from the player's mainhand
            const selectedItem = equipment.getEquipment('Mainhand');
            
            // Determine the target block to update
            const targetBlock = isUpperBlock ? block.below() : block.above();

            // Get the current state of the 'edx:open_bit' block trait for both the interacted block and the target block
            const currentOpenState = block.permutation.getState('edx:open_bit');
            const targetOpenState = targetBlock.permutation.getState('edx:open_bit');

            // Determine the new state of the 'edx:open_bit' block trait (toggle between true and false)
            const newOpenState = !currentOpenState;
            const newTargetOpenState = !targetOpenState;

            // Resolve the new block permutation based on the current block type and updated states
            const newBlockPermutation = BlockPermutation.resolve(block.typeId, {
                ...block.permutation.getAllStates(),
                'edx:open_bit': newOpenState
            });

            const newTargetBlockPermutation = BlockPermutation.resolve(targetBlock.typeId, {
                ...targetBlock.permutation.getAllStates(),
                'edx:open_bit': newTargetOpenState
            });

            // Set the block permutations to the newly resolved permutations
            block.setPermutation(newBlockPermutation);
            targetBlock.setPermutation(newTargetBlockPermutation);

            // Determine the sound effect to play based on the current state of the door
            const sound = currentOpenState ? 'close.wooden_door' : 'open.wooden_door';

            // Play the corresponding sound effect for opening or closing the door
            player.playSound(sound);
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('door:on_place', {
        // Define behavior when a player places the block
        onPlace(e) {
            const processedBlocks = new Map();
            // Destructure event data for easier access
            const { block } = e;
            const aboveBlock = block.above();
            const northBlock = block.north(); // Get the block to the east
            const southBlock = block.south(); // Get the block to the east
            const eastBlock = block.east(); // Get the block to the east
            const westBlock = block.west(); // Get the block to the east
            const { x, y, z } = block.location;

            // Check if the block has already been processed
            if (processedBlocks.has(`${x},${y},${z}`)) {
                return; // Exit early if block has already been processed
            }

            // Get all current block states
            const currentStates = block.permutation.getAllStates();

            // Get the cardinal direction of the block
            const cardinalDirection = currentStates['minecraft:cardinal_direction'];

            // Check if the block above is air
            if (aboveBlock.typeId === 'minecraft:air' ) {
                // Create a new permutation for the block above with the cardinal direction
                
                const aboveBlockPermutation = BlockPermutation.resolve(block.typeId, {
                    'edx:upper_block_bit': true,
                    'minecraft:cardinal_direction': cardinalDirection
                });
                aboveBlock.setPermutation(aboveBlockPermutation);

                // Update the block's permutation with the new state
                const newPermutation = BlockPermutation.resolve(block.typeId, currentStates);
                // Apply the new permutation to the block
                block.setPermutation(newPermutation);
            } // Check if the block above is not air and the current block is not an upper block
            
            

            // Check if the cardinal direction of the block is south
            if (cardinalDirection === 'south' && eastBlock?.typeId === block.typeId) {
                const eastBlockStates = eastBlock.permutation.getAllStates();
                // Check if the east block is a edx:redwood_door_b with edx:door_hinge_bit set to false
                if (!eastBlockStates['edx:door_hinge_bit']) {
                    // Change the edx:door_hinge_bit state of the placed block to true
                    const newPermutation = BlockPermutation.resolve(block.typeId, {
                        ...currentStates,
                        'edx:door_hinge_bit': true
                    });
                    block.setPermutation(newPermutation);
                }
                // Also, check if the block above has the same cardinal direction and if the block to the east of the above block is a edx:redwood_door_b
                const aboveBlockCardinalDirection = aboveBlock.permutation.getState('minecraft:cardinal_direction');
                const eastBlockAbove = aboveBlock.east();
                if (
                    aboveBlockCardinalDirection === 'south' &&
                    eastBlockAbove?.typeId === block.typeId
                ) {
                    const eastBlockAboveStates = eastBlockAbove.permutation.getAllStates();
                    // Check if the east block above is a edx:redwood_door_b with edx:door_hinge_bit set to false
                    if (!eastBlockAboveStates['edx:door_hinge_bit']) {
                        // Change the edx:door_hinge_bit state of the block above to true
                        const newAbovePermutation = BlockPermutation.resolve(aboveBlock.typeId, {
                            ...eastBlockAboveStates,
                            'edx:door_hinge_bit': true
                        });
                        aboveBlock.setPermutation(newAbovePermutation);
                    }
                }
            }

            // Check if the cardinal direction of the block is east
            if (cardinalDirection === 'east' && northBlock?.typeId === block.typeId) {
                const northBlockStates = northBlock.permutation.getAllStates();
                // Check if the north block is a edx:redwood_door_b with edx:door_hinge_bit set to false
                if (!northBlockStates['edx:door_hinge_bit']) {
                    // Change the edx:door_hinge_bit state of the placed block to true
                    const newPermutation = BlockPermutation.resolve(block.typeId, {
                        ...currentStates,
                        'edx:door_hinge_bit': true
                    });
                    block.setPermutation(newPermutation);
                }
                // Also, check if the block above has the same cardinal direction and if the block to the north of the above block is a edx:redwood_door_b
                const aboveBlockCardinalDirection = aboveBlock.permutation.getState('minecraft:cardinal_direction');
                const northBlockAbove = aboveBlock.north();
                if (
                    aboveBlockCardinalDirection === 'east' &&
                    northBlockAbove?.typeId === block.typeId
                ) {
                    const northBlockAboveStates = northBlockAbove.permutation.getAllStates();
                    // Check if the north block above is a edx:redwood_door_b with edx:door_hinge_bit set to false
                    if (!northBlockAboveStates['edx:door_hinge_bit']) {
                        // Change the edx:door_hinge_bit state of the block above to true
                        const newAbovePermutation = BlockPermutation.resolve(aboveBlock.typeId, {
                            ...northBlockAboveStates,
                            'edx:door_hinge_bit': true
                        });
                        aboveBlock.setPermutation(newAbovePermutation);
                    }
                }
            }

            // Check if the cardinal direction of the block is north
            if (cardinalDirection === 'north' && westBlock?.typeId === block.typeId) {
                const westBlockStates = westBlock.permutation.getAllStates();
                // Check if the west block is a edx:redwood_door_b with edx:door_hinge_bit set to false
                if (!westBlockStates['edx:door_hinge_bit']) {
                    // Change the edx:door_hinge_bit state of the placed block to true
                    const newPermutation = BlockPermutation.resolve(block.typeId, {
                        ...currentStates,
                        'edx:door_hinge_bit': true
                    });
                    block.setPermutation(newPermutation);
                }
                // Also, check if the block above has the same cardinal direction and if the block to the west of the above block is a edx:redwood_door_b
                const aboveBlockCardinalDirection = aboveBlock.permutation.getState('minecraft:cardinal_direction');
                const westBlockAbove = aboveBlock.west();
                if (
                    aboveBlockCardinalDirection === 'north' &&
                    westBlockAbove?.typeId === block.typeId
                ) {
                    const westBlockAboveStates = westBlockAbove.permutation.getAllStates();
                    // Check if the west block above is a edx:redwood_door_b with edx:door_hinge_bit set to false
                    if (!westBlockAboveStates['edx:door_hinge_bit']) {
                        // Change the edx:door_hinge_bit state of the block above to true
                        const newAbovePermutation = BlockPermutation.resolve(aboveBlock.typeId, {
                            ...westBlockAboveStates,
                            'edx:door_hinge_bit': true
                        });
                        aboveBlock.setPermutation(newAbovePermutation);
                    }
                }
            }

            // Check if the cardinal direction of the block is west
            if (cardinalDirection === 'west' && southBlock?.typeId === block.typeId) {
                const southBlockStates = southBlock.permutation.getAllStates();
                // Check if the south block is a edx:redwood_door_b with edx:door_hinge_bit set to false
                if (!southBlockStates['edx:door_hinge_bit']) {
                    // Change the edx:door_hinge_bit state of the placed block to true
                    const newPermutation = BlockPermutation.resolve(block.typeId, {
                        ...currentStates,
                        'edx:door_hinge_bit': true
                    });
                    block.setPermutation(newPermutation);
                }
                // Also, check if the block above has the same cardinal direction and if the block to the south of the above block is a edx:redwood_door_b
                const aboveBlockCardinalDirection = aboveBlock.permutation.getState('minecraft:cardinal_direction');
                const southBlockAbove = aboveBlock.south();
                if (
                    aboveBlockCardinalDirection === 'west' &&
                    southBlockAbove?.typeId === block.typeId
                ) {
                    const southBlockAboveStates = southBlockAbove.permutation.getAllStates();
                    // Check if the south block above is a edx:redwood_door_b with edx:door_hinge_bit set to false
                    if (!southBlockAboveStates['edx:door_hinge_bit']) {
                        // Change the edx:door_hinge_bit state of the block above to true
                        const newAbovePermutation = BlockPermutation.resolve(aboveBlock.typeId, {
                            ...southBlockAboveStates,
                            'edx:door_hinge_bit': true
                        });
                        aboveBlock.setPermutation(newAbovePermutation);
                    }
                }
            }

            // Mark the block as processed
            processedBlocks.set(`${x},${y},${z}`, true);
        }
    });
    eventData.blockComponentRegistry.registerCustomComponent('door:beforeOnPlayerPlace', {
        beforeOnPlayerPlace: event => {
            const { block } = event;
            const aboveBlock = block.above();
            if (aboveBlock.typeId !== 'minecraft:air') {
                event.cancel = true;
            }
         } 
    }); 
    
});
function crimsonspireStemBreak(block) {
    for(var i=1;i<30;i++)
    {
        if(['edx:crimsonspire_stem_0', 'edx:crimsonspire_stem_1','edx:crimsonspire_stem_2','edx:crimsonspire_cap'].includes(block.above(i).typeId)) 
        {
            block.dimension.runCommand(`setblock ${block.above(i).location.x} ${block.above(i).location.y} ${block.above(i).location.z} air destroy`) 
        }
        else
        {
            return;
        }
    }
}
function getNewCardinalDirection(currentDirection, angle) {
    const direction = directionDisplay(angle);
    if (['north', 'south'].includes(currentDirection)) {
        return direction.includes('south') ? 'south' : 'north';
    } else {
        return direction.includes('west') ? 'west' : 'east';
    }
}
function isWithinRadiusOfAllowedBlock(block, dist,logList) {
    const area = new BlockVolume({x:block.location.x-dist,y:block.location.y-dist,z:block.location.z-dist},{x:block.location.x+dist,y:block.location.y+dist,z:block.location.z+dist});
    const result = block.dimension.containsBlock(area,{includeTypes:logList});
    return result
}
function spotterDropItem(block,equipment,slot,dir,player) {
    const dimension = block.dimension
    const item = equipment.getEquipment(slot);
    if(item!=undefined)
    {
        dimension.spawnParticle('edx:souls_spotter',{x:player.location.x,y:player.location.y+1,z:player.location.z});
        dimension.playSound('random.pop',player.location);
        dimension.playSound('particle.soul_escape',player.location);                             
        var blockBehind = dimension.getBlock({x:block.location.x-dir.x,y:block.location.y-dir.y,z:block.location.z-dir.z})
        var inventory = blockBehind?.getComponent("inventory")?.container;
        equipment.setEquipment(slot, undefined);                                          
        try{
            if(inventory.emptySlotsCount!=0)
            {
                inventory.addItem(item);
            }
            else{

                              system.runTimeout(() => {
                dimension.spawnItem(item, {x:block.center().x-dir.x/2,y:block.center().y-dir.y/2,z:block.center().z-dir.z/2});
                dimension.playSound('mob.sniffer.drop_seed',block.location);
                },2)   
            }
        }
        catch(e)
        {
            system.runTimeout(() => {
            dimension.spawnItem(item, {x:block.center().x-dir.x/2,y:block.center().y-dir.y/2,z:block.center().z-dir.z/2});
            dimension.playSound('mob.sniffer.drop_seed',block.location);
                },2)   
        }
    }
}

// Function to calculate the direction a player is looking at
function directionDisplay(angle) {
    if (Math.abs(angle) > 112.5) return 'north';
    if (Math.abs(angle) < 67.5) return 'south';
    if (angle < 157.5 && angle > 22.5) return 'west';
    if (angle > -157.5 && angle < -22.5) return 'east';
    return '';
}

function GetLeaveValue(block)
{
    if(blockAroundHasTag(block,'minecraft:logs')) return 8;
    var value = 0
    const above = block.above()?.typeId=='edx:redwood_leaves'?block.above()?.permutation?.getState('edx:decay_tier'):0
    const below = block.below()?.typeId=='edx:redwood_leaves'?block.below()?.permutation?.getState('edx:decay_tier'):0
    const north = block.north()?.typeId=='edx:redwood_leaves'?block.north()?.permutation?.getState('edx:decay_tier'):0
    const south = block.south()?.typeId=='edx:redwood_leaves'?block.south()?.permutation?.getState('edx:decay_tier'):0
    const east = block.east()?.typeId=='edx:redwood_leaves'?block.east()?.permutation?.getState('edx:decay_tier'):0
    const west = block.west()?.typeId=='edx:redwood_leaves'?block.west()?.permutation?.getState('edx:decay_tier'):0
    const blocks = [above,below,north,south,west,east]
    for(var i=0;i<blocks.length;i++)
    {
        if(blocks[i]!=undefined)
            if(blocks[i]>value)
                value = blocks[i]
    }
    return value

}
function blockAroundHasTag(block,tag)
{
    return block.above()?.hasTag(tag) || block.below()?.hasTag(tag) || block.east()?.hasTag(tag) || block.west()?.hasTag(tag) || block.north()?.hasTag(tag) || block.south()?.hasTag(tag)
}
function treeSpaceCheck(dir,dist,dimension,block)
{
    const options = { maxDistance: dist}
    let blocks3 = dimension.getBlockFromRay({x:block.location.x,y:block.location.y+dir.y,z:block.location.z},dir, options);
    let blocks1 = dimension.getBlockFromRay({x:block.location.x-2,y:block.location.y+dir.y,z:block.location.z-2}, dir, options);
    let blocks2 = dimension.getBlockFromRay({x:block.location.x+2,y:block.location.y+dir.y,z:block.location.z+2}, dir, options);
    let blocks4 = dimension.getBlockFromRay({x:block.location.x+2,y:block.location.y+dir.y,z:block.location.z-2}, dir, options);
    let blocks5 = dimension.getBlockFromRay({x:block.location.x-2,y:block.location.y+dir.y,z:block.location.z+2}, dir, options);
    let blocks6 = dimension.getBlockFromRay({x:block.location.x-1,y:block.location.y+dir.y,z:block.location.z-1}, dir, options);
    let blocks7 = dimension.getBlockFromRay({x:block.location.x+1,y:block.location.y+dir.y,z:block.location.z+1}, dir, options);
    let blocks8 = dimension.getBlockFromRay({x:block.location.x+1,y:block.location.y+dir.y,z:block.location.z-1}, dir, options);
    let blocks9 = dimension.getBlockFromRay({x:block.location.x-1,y:block.location.y+dir.y,z:block.location.z+1}, dir, options);
    let blocks10 = dimension.getBlockFromRay({x:block.location.x-3,y:block.location.y+dir.y,z:block.location.z-3}, dir, options);
    let blocks11 = dimension.getBlockFromRay({x:block.location.x+3,y:block.location.y+dir.y,z:block.location.z+3}, dir, options);
    let blocks12 = dimension.getBlockFromRay({x:block.location.x+3,y:block.location.y+dir.y,z:block.location.z-3}, dir, options);
    let blocks13 = dimension.getBlockFromRay({x:block.location.x-3,y:block.location.y+dir.y,z:block.location.z+3}, dir, options);
    return blocks1==undefined && blocks2==undefined && blocks3==undefined && blocks4==undefined && blocks5==undefined && blocks6==undefined && blocks7==undefined && blocks8==undefined && blocks9==undefined && blocks10==undefined && blocks11==undefined && blocks12==undefined && blocks13==undefined
}
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 / 22.5);
  
    // 0 and 16 represent duplicate rotations (0 degrees and 360 degrees), so 0 is returned if the value of `rotation` is 16
    return rotation !== 16 ? rotation : 0;
  }

function summonDeceitmorph(block,number)
{
    var x=0
    var z=0
    for (var i=0;i<number;i++) {
        x=(4+Math.random()*5)
        z=(4+Math.random()*5)
        x*=Math.random()<0.5?-1:1
        z*=Math.random()<0.5?-1:1
        const newblock = block.dimension.getBlockFromRay({x:block.x+x,y:block.y+10,z:block.z+z},{x:0,y:-1,z:0},{maxDistance: 25,includePassableBlocks:false,includeTypes:["edx:deceitweb_block"]})?.block
        if(newblock!=undefined)
            block.dimension.spawnEntity("edx:deceitmorph_humanoid",newblock.above().location);
    }
}
const fenceExcludeBlocksArray = [
    'edx:deceitweb_trapdoor', 
    'edx:deceitweb_door_b', 
    'edx:redwood_trapdoor', 
    'edx:redwood_door_b', 
    'minecraft:air',
    'minecraft:wooden_door', 
    'minecraft:iron_door', 
    'minecraft:acacia_door', 
    'minecraft:birch_door', 
    'minecraft:crimson_door', 
    'minecraft:dark_oak_door', 
    'minecraft:jungle_door', 
    'minecraft:oak_door', 
    'minecraft:spruce_door', 
    'minecraft:warped_door', 
    'minecraft:mangrove_door',
    'minecraft:cherry_door',
    'minecraft:bamboo_door',
    'minecraft:iron_trapdoor', 
    'minecraft:acacia_trapdoor', 
    'minecraft:birch_trapdoor', 
    'minecraft:crimson_trapdoor', 
    'minecraft:dark_oak_trapdoor', 
    'minecraft:jungle_trapdoor', 
    'minecraft:oak_trapdoor', 
    'minecraft:spruce_trapdoor', 
    'minecraft:warped_trapdoor',
    'minecraft:mangrove_trapdoor',
    'minecraft:cherry_trapdoor',
    'minecraft:bamboo_trapdoor',
    'minecraft:trapdoor', 
    'minecraft:glass',
    'minecraft:short_grass',
    'minecraft:tall_grass',
    'minecraft:glass_pane'
    // Add other block types you want to exclude
];
const Walllist = [
    'minecraft:andesite_wall',
    'minecraft:blackstone_wall',
    'minecraft:polished_blackstone_wall',
    'minecraft:polished_blackstone_brick_wall',
    'minecraft:brick_wall',
    'minecraft:cobbled_deepslate_wall',
    'minecraft:cobblestone_wall',
    'minecraft:deepslate_brick_wall',
    'minecraft:polished_deepslate_wall',
    'minecraft:tuff_wall',
    'minecraft:tuff_brick_wall',
    'minecraft:polished_tuff_wall',
    'minecraft:mud_brick_wall',
    'minecraft:resin_brick_wall',
    'minecraft:mossy_cobblestone_wall',
    'minecraft:granite_wall',
    'minecraft:diorite_wall',
    'minecraft:sandstone_wall',
    'minecraft:red_sandstone_wall',
    'minecraft:stonebrick_wall',
    'minecraft:mossy_stonebrick_wall',
    'minecraft:nether_brick_wall',
    'minecraft:red_nether_brick_wall',
    'minecraft:endstone_brick_wall',
    'minecraft:prismarine_wall',
    'minecraft:deepslate_tile_wall',
];
function fenceConnect(e)
{
    
    const { block } = e;
            block.setPermutation(block.permutation.withState('edx:update', false));
            // Get adjacent blocks
            const north = block.north();
            const east = block.east();
            const south = block.south();
            const west = block.west();


            // Check if the adjacent block is not in the excludeBlocksArray
            const northConnects = !fenceExcludeBlocksArray.includes(north?.typeId);
            const eastConnects = !fenceExcludeBlocksArray.includes(east?.typeId);
            const southConnects = !fenceExcludeBlocksArray.includes(south?.typeId);
            const westConnects = !fenceExcludeBlocksArray.includes(west?.typeId);

            // Update block states based on the presence of adjacent blocks
            block.setPermutation(block.permutation.withState('edx:north_picket', northConnects ? 1 : 0));
            block.setPermutation(block.permutation.withState('edx:south_picket', southConnects ? 1 : 0));
            block.setPermutation(block.permutation.withState('edx:east_picket', eastConnects ? 1 : 0));
            block.setPermutation(block.permutation.withState('edx:west_picket', westConnects ? 1 : 0));
}
function wallConnect(e)
{
    const { block } = e;
            block.setPermutation(block.permutation.withState('edx:update', false));
            // Get adjacent blocks
            const above = block.above();
            const north = block.north();
            const east = block.east();
            const south = block.south();
            const west = block.west();

            // Check if the adjacent block is not in the excludeBlocksArray
            const northConnects = !fenceExcludeBlocksArray.includes(north?.typeId);
            const eastConnects = !fenceExcludeBlocksArray.includes(east?.typeId);
            const southConnects = !fenceExcludeBlocksArray.includes(south?.typeId);
            const westConnects = !fenceExcludeBlocksArray.includes(west?.typeId);
            const aboveConnects = !fenceExcludeBlocksArray.includes(above?.typeId);
            if(Walllist.includes(above?.typeId))//mur vanilla au dessus
            {
                block.setPermutation(block.permutation.withState('edx:north_picket', northConnects && above?.permutation?.getState("wall_connection_type_north")? 2 : 0));
                block.setPermutation(block.permutation.withState('edx:south_picket', southConnects && above?.permutation?.getState("wall_connection_type_south")? 2 : 0));
                block.setPermutation(block.permutation.withState('edx:east_picket', eastConnects && above?.permutation?.getState("wall_connection_type_east")? 2: 0));
                block.setPermutation(block.permutation.withState('edx:west_picket', westConnects && above?.permutation?.getState("wall_connection_type_west")? 2 : 0));
                block.setPermutation(block.permutation.withState('edx:post', above?.permutation?.getState("wall_post_bit") && ((northConnects && southConnects && !eastConnects && !westConnects) || (!northConnects && !southConnects && eastConnects && westConnects))? 1 : 0));
            }
            else if(above.hasTag("wall"))//mur moddé au dessus 
            {
                block.setPermutation(block.permutation.withState('edx:north_picket', northConnects && (above?.permutation?.getState("edx:north_picket")>=1)? 2 : northConnects?1:0));
                block.setPermutation(block.permutation.withState('edx:south_picket', southConnects && (above?.permutation?.getState("edx:south_picket")>=1)? 2 : southConnects?1:0));
                block.setPermutation(block.permutation.withState('edx:east_picket', eastConnects && (above?.permutation?.getState("edx:east_picket")>=1)? 2 : eastConnects?1:0));
                block.setPermutation(block.permutation.withState('edx:west_picket', westConnects && (above?.permutation?.getState("edx:west_picket")>=1)? 2 : westConnects?1:0));
                block.setPermutation(block.permutation.withState('edx:post', above?.permutation?.getState("edx:post") && ((northConnects && southConnects && !eastConnects && !westConnects) || (!northConnects && !southConnects && eastConnects && westConnects))? 1 : 0));
            }
            else if(aboveConnects)//block au dessus
            {
                block.setPermutation(block.permutation.withState('edx:north_picket', northConnects ? 2 : 0));
                block.setPermutation(block.permutation.withState('edx:south_picket', southConnects? 2 : 0));
                block.setPermutation(block.permutation.withState('edx:east_picket', eastConnects? 2 : 0));
                block.setPermutation(block.permutation.withState('edx:west_picket', westConnects? 2 : 0));
                block.setPermutation(block.permutation.withState('edx:post', ((northConnects && southConnects) || (eastConnects && westConnects))? 1 : 0));
            }
            else //rien
            {
                block.setPermutation(block.permutation.withState('edx:north_picket', northConnects ? 1 : 0));
                block.setPermutation(block.permutation.withState('edx:south_picket', southConnects ? 1 : 0));
                block.setPermutation(block.permutation.withState('edx:east_picket', eastConnects ? 1 : 0));
                block.setPermutation(block.permutation.withState('edx:west_picket', westConnects ? 1 : 0));
                block.setPermutation(block.permutation.withState('edx:post', !aboveConnects && ((northConnects && southConnects && !eastConnects && !westConnects) || (!northConnects && !southConnects && eastConnects && westConnects))? 1 : 0));
            }
            if(block.below().hasTag("wall"))
            {
                block.below().setPermutation(block.permutation.withState('edx:update', true));
            }
            
            

}
