import { system, world, EquipmentSlot, ItemStack } from "@minecraft/server";
import './mob/index.js'
import './settings.js'
import './start_book.js'
import { excludeFamilies } from "./mob/utils.js";
import * as lib from "./lib"
const testing = false
const textDelay = 2;
export function resetLevel() {
    const exp = 0
    const lvl = 1
    const ult = 0
    world.getPlayers().forEach(player=>{
        const wp = ['leaf_blower', 'digital_grave', 'rusty_chains', 'scary_lantern']
        wp.forEach(weapon=>{
            player.runCommand(`scoreboard players set @s ld_hw:${weapon}_exp ${exp}`)
            player.runCommand(`scoreboard players set @s ld_hw:${weapon}_lvl ${lvl}`)
            player.runCommand(`scoreboard players set @s ld_hw:${weapon}_ult ${ult}`)
        })
    })
}
{
system.afterEvents.scriptEventReceive.subscribe(data => {

    const id = data.id, entity = data.sourceEntity
    if (id === "ld_hw:level_max") {
        const weapons = [
            "leaf_blower",
            "rusty_chains",
            "scary_lantern",
            "digital_grave"
        ]
        const exp = 0
        const lvl = 10
        const ult = 10
        weapons.forEach(weapon=>{
            entity.runCommand(`scoreboard players set @s ld_hw:${weapon}_exp ${exp}`)
            entity.runCommand(`scoreboard players set @s ld_hw:${weapon}_lvl ${lvl}`)
            entity.runCommand(`scoreboard players set @s ld_hw:${weapon}_ult ${ult}`)
        })
    }
    if(id==="ld_hw:parTest") {
            for (let index = 1; index <= 6; index++) {
                entity.dimension.spawnParticle(`ld_hw:leaf_blower.ability_4_${index}`, entity.location)
            }
    }


})
//WEAPON DATA
const leaf_blower = {
    cooldown_score: 'ld_hw:leaf_blower_cd',
    level_score: 'ld_hw:leaf_blower_lvl',
    damage_multiply: 1,
    attack1: {
        attack_name: 'Angry Blow',
        attack_translate: `titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw:lb.angry_blow"}]}`,
        animation_tpp: 'animation.ld_hw.leaf_blower_tpp.angry_blow',
        attackId: 1,
        damaging_entity: 'ld_hw:leaf_blower_attack1',
        function_duration: 0,
        custom_effects: leaf_blower_Attack1Effect,
        has_animation: true,
        cd: 5,
        damage_amount:10,
        attackDuration: 3.5,
        spells: [
            {
                spell_id: 'ld_hw:leaf_blower_attack1',
                is_spell_following_subject: false,
                spawn_location: {
                    x: 1.3,
                    y: 1,
                    z: 1.3
                },
                rotation: {
                    x: 1,
                    y: 1,
                },
                spawn_duration: 0.0,
                despawn_duration: 3
            }
        ]
    },
    attack2: {
        attack_name: 'Pull Mode',
        attack_translate: `titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw:lb.pull_mode"}]}`,
        animation_tpp: 'animation.ld_hw.leaf_blower_tpp.pulling_mode',
        attackId: 2,
        damaging_entity: 'ld_hw:leaf_blower_attack2',
        function_duration: 0.79,
        custom_effects: leaf_blower_Attack2Effect,
        has_animation: true,
        cd: 5,
        attackDuration: 4.3333,
        damage_amount:8,
        spells: [
            {
                spell_id: 'ld_hw:leaf_blower_attack2',
                is_spell_following_subject: true,
                spawn_location: {
                    x: 1.3,
                    y: 1,
                    z: 1.3
                },
                rotation: {
                    x: 1,
                    y: 1,
                },
                spawn_duration: 1,
                despawn_duration: 10
            }
        ],
        damaging: [
        ]
    },
    attack3: {
        attack_name: 'Push Mode',
        attack_translate: `titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw:lb.push_mode"}]}`,
        animation_tpp: 'animation.ld_hw.leaf_blower_tpp.push_mode',
        attackId: 3,
        damaging_entity: 'ld_hw:leaf_blower_attack3',
        function_duration: 0.75,
        custom_effects: leaf_blower_Attack3Effect,
        has_animation: true,
        cd: 5,
        attackDuration: 8.25,
        titit_amount:8
    },
    attack4: {
        attack_name: 'Wrath Sucking',
        attack_translate: `titleraw @s title {"rawtext":[{"translate":"actionbar.ld_hw:lb.wrath_sucking"}]}`,
        animation_tpp: 'animation.ld_hw.leaf_blower_tpp.wrath_sucking',
        attackId: 4,
        damaging_entity: 'player',
        function_duration: 0,
        custom_effects: leaf_blower_Attack4Effect,
        has_animation: true,
        cd: 10,
        attackDuration: 8.25+textDelay,
        animation_delay: textDelay,
        spells: [
            {
                spell_id: 'ld_hw:leaf_blower_attack4',
                is_spell_following_subject: false,
                spawn_location: {
                    x: 1,
                    y: 0,
                    z: 1
                },
                rotation: {
                    x: 0,
                    y: 0,
                },
                spawn_duration: 0.0,
                despawn_duration: 15
            }
        ],
        damaging: [
            {
                subject: 'player',
                damage_type: 'loop',
                damage_amount: 15,
                radius: 10,
                start_duration: 1.75+textDelay,
                stop_duration: 3.75+textDelay
            }
        ]
    }
}
const scary_lantern = {
    cooldown_score: 'ld_hw:scary_lantern_cd',
    level_score: 'ld_hw:scary_lantern_lvl',
    damage_multiply: 1,
    attack1: {
        attack_name: 'Phantom Glow',
        attack_translate: `titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw:sl.phantom_glow"}]}`,
        animation_tpp: 'animation.ld_hw.scary_lantern_tpp.haunting_light',
        attackId: 1,
        damaging_entity: 'ld_hw:scary_lantern_attack1',
        function_duration: 0.0,
        custom_effects: scary_lantern_Attack1Effect,
        has_animation: true,
        cd: 5,
        damage_amount: 6,
        attackDuration: 2.63
    },
    attack2: {
        attack_name: 'Eerie Flash',
        attack_translate: `titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw:sl.eerie_flash"}]}`,
        animation_tpp: 'animation.ld_hw.scary_lantern_tpp.eerie_flash',
        attackId: 2,
        damaging_entity: 'ld_hw:scary_lantern_attack2',
        function_duration: 0.0,
        custom_effects: scary_lantern_Attack2Effect,
        has_animation: true,
        cd: 20,
        attackDuration: 1.5
    },
    attack3: {
        attack_name: 'Spectral Flicker',
        attack_translate: `titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw:sl.spectral_flicker"}]}`,
        animation_tpp: 'animation.ld_hw.scary_lantern_tpp.spectral_flicker',
        attackId: 3,
        damaging_entity: 'ld_hw:scary_lantern_attack3',
        function_duration: 0.0,
        custom_effects: scary_lantern_Attack3Effect,
        has_animation: true,
        cd: 5,
        attackDuration: 8.0
    },
    attack4: {
        attack_name: `wraiths Gaze`,
        attack_translate: `titleraw @s title {"rawtext":[{"translate":"actionbar.ld_hw:sl.wraiths_gaze"}]}`,
        animation_tpp: 'animation.ld_hw.scary_lantern_tpp.wraiths_gaze',
        attackId: 4,
        damaging_entity: 'ld_hw:scary_lantern_attack4',
        function_duration: 0.0,
        custom_effects: scary_lantern_Attack4Effect,
        has_animation: true,
        cd: 10,
        attackDuration: 2.25+textDelay,
        animation_delay: textDelay,
        damage_amount: 8,
        spells: [
            {
                spell_id: 'ld_hw:scary_lantern_attack4',
                is_spell_following_subject: false,
                spawn_location: {
                    x: 1,
                    y: 0,
                    z: 1
                },
                rotation: {
                    x: 1,
                    y: 1,
                },
                spawn_duration: 0.0,
                despawn_duration: 10
            }
        ]
    }
}
const digital_grave = {
    cooldown_score: 'ld_hw:digital_grave_cd',
    level_score: 'ld_hw:digital_grave_lvl',
    damage_multiply: 1,
    attack1: {
        attack_name: 'Corrupted Data Blast',
        attack_translate: `titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw:dg.corrupted_data_blast"}]}`,
        animation_tpp: 'animation.ld_hw.digital_grave_tpp.corrupted_data_blast',
        attackId: 1,
        damaging_entity: 'ld_hw:digital_grave_attack1',
        function_duration: 0.63,
        custom_effects: digital_grave_Attack1Effect,
        has_animation: true,
        cd: 5,
        attackDuration: 1.5,
        spells: [
            {
                spell_id: 'ld_hw:digital_grave_attack1',
                is_spell_following_subject: false,
                spawn_location: {
                    x: 1,
                    y: 0,
                    z: 1
                },
                rotation: {
                    x: 1,
                    y: 1,
                },
                spawn_duration: 0.63,
                despawn_duration: 1
            }
        ],
        damaging: [
            {
                subject: 'spell',
                damage_type: 'once',
                damage_amount: 12,
                duration: 0.63,
                radius: 3
            }
        ]
    },
    attack2: {
        attack_name: 'Error Reboot',
        attack_translate: `titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw:dg.error_reboot"}]}`,
        animation_tpp: 'animation.ld_hw.digital_grave_tpp.error_reboot',
        attackId: 2,
        damaging_entity: 'ld_hw:digital_grave_attack2',
        function_duration: 0.42,
        custom_effects: digital_grave_Attack2Effect,
        has_animation: true,
        cd: 5,
        attackDuration: 2.25,
        damage_amount: 8,
        spells: [
            {
                spell_id: 'ld_hw:digital_grave_attack2',
                is_spell_following_subject: false,
                spawn_location: {
                    x: 0,
                    y: 0,
                    z: 0
                },
                rotation: {
                    x: 1,
                    y: 1,
                },
                spawn_duration: 0.42,
                despawn_duration: 1
            }
        ]
    },
    attack3: {
        attack_name: 'Virus Spread',
        attack_translate: `titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw:dg.virus_spread"}]}`,
        animation_tpp: 'animation.ld_hw.digital_grave_tpp.virus_spread',
        attackId: 3,
        damaging_entity: 'ld_hw:digital_grave_attack3',
        function_duration: 0.0,
        custom_effects: digital_grave_Attack3Effect,
        has_animation: true,
        cd: 5,
        damage_amount: 1,
        attackDuration: 1.5
    },
    attack4: {
        attack_name: `Digital Resurrection`,
        attack_translate: `titleraw @s title {"rawtext":[{"translate":"actionbar.ld_hw:dg.digital_resurrection"}]}`,
        animation_tpp: 'animation.ld_hw.digital_grave_tpp.digital_resurrection',
        attackId: 4,
        damaging_entity: 'ld_hw:digital_grave_attack4',
        function_duration: 0.0,
        custom_effects: digital_grave_Attack4Effect,
        has_animation: true,
        cd: 10,
        attackDuration: 1.625+textDelay,
        animation_delay: 1+textDelay,
        damage_amount: 9,
        spells: [
            {
                spell_id: 'ld_hw:digital_grave_attack4',
                is_spell_following_subject: false,
                spawn_location: {
                    x: 1,
                    y: 0,
                    z: 1
                },
                rotation: {
                    x: 1,
                    y: 1,
                },
                spawn_duration: 0.0,
                despawn_duration: 10
            }
        ]
    }
}
const rusty_chains = {
    cooldown_score: 'ld_hw:rusty_chains_cd',
    level_score: 'ld_hw:rusty_chains_lvl',
    damage_multiply: 1,
    attack1: {
        attack_name: 'Constricting Bind',
        attack_translate: `titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw:rc.constricting_bind"}]}`,
        animation_tpp: 'animation.ld_hw.rusty_chains_tpp.constricting_bind_humanoid',
        attackId: 1,
        damaging_entity: 'ld_hw:rusty_chains_attack1',
        function_duration: 0.5,
        custom_effects: rusty_chains_Attack1Effect,
        has_animation: true,
        cd: 5,
        damage_amount: 4,
        attackDuration: 2.75,
        spells: [
            {
                spell_id: 'ld_hw:rusty_chains_attack1',
                is_spell_following_subject: false,
                spawn_location: {
                    x: 1,
                    y: 0,
                    z: 1
                },
                rotation: {
                    x: 0,
                    y: 0,
                },
                spawn_duration: 0.0,
                despawn_duration: 5
            }
        ]
    },
    attack2: {
        attack_name: 'Chain Latch',
        attack_translate: `titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw:rc.chain_latch"}]}`,
        animation_tpp: 'animation.ld_hw.rusty_chains_tpp.chain_latch_humanoid',
        attackId: 2,
        damaging_entity: 'ld_hw:rusty_chains_attack2',
        function_duration: 0.0,
        custom_effects: rusty_chains_Attack2Effect,
        has_animation: true,
        cd: 5,
        damage_amount: 10,
        attackDuration: 2.6667,
        spells: [
            {
                spell_id: 'ld_hw:rusty_chains_attack2',
                is_spell_following_subject: false,
                spawn_location: {
                    x: 1,
                    y: 0,
                    z: 1
                },
                rotation: {
                    x: 0,
                    y: 0,
                },
                spawn_duration: 0.0,
                despawn_duration: 5
            }
        ]
    },
    attack3: {
        attack_name: 'Whip Lash',
        attack_translate: `titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw:rc.whip_lash"}]}`,
        animation_tpp: 'animation.ld_hw.rusty_chains_tpp.whip_lash_humanoid',
        attackId: 3,
        damaging_entity: 'ld_hw:rusty_chains_attack3',
        function_duration: 0.0,
        custom_effects: rusty_chains_Attack3Effect,
        has_animation: true,
        cd: 5,
        damage_amount: 15,
        attackDuration: 1.25
    },
    attack4: {
        attack_name: `Hellish Shackles`,
        attack_translate: `titleraw @s title {"rawtext":[{"translate":"actionbar.ld_hw:rc.hellish_shackles"}]}`,
        animation_tpp: 'animation.ld_hw.rusty_chains_tpp.hellish_shackles_humanoid',
        attackId: 4,
        damaging_entity: 'ld_hw:rusty_chains_attack4',
        function_duration: 0.0,
        custom_effects: rusty_chains_Attack4Effect,
        has_animation: true,
        cd: 10,
        attackDuration: 4+textDelay,
        animation_delay: 1+textDelay,
        damage_amount: 8,
        spells: [
            {
                spell_id: 'ld_hw:rusty_chains_attack4',
                is_spell_following_subject: false,
                spawn_location: {
                    x: 1,
                    y: 0,
                    z: 1
                },
                rotation: {
                    x: 1,
                    y: 1,
                },
                spawn_duration: 0.0,
                despawn_duration: 10
            }
        ]
    }
}
function cinematic(cineData) {
    const subject = cineData.subject
    const tag = cineData.tag
    const pos = cineData.pos
    const face = cineData.face
    const type = cineData.type
    const duration = cineData.duration
    subject.runCommand(`camera @a[tag=ld_hw:selected_by_${tag}] set minecraft:free pos ${pos[0]} facing ${face[0]}`)
    if(type==='cinematic'){
        subject.runCommandAsync(`camera @a[tag=ld_hw:selected_by_${tag}] set minecraft:free ease ${duration} linear pos ${pos[1]} facing ${face[1]}`)
    }
}
function leaf_blower_Attack1Effect(player, damagingEntity){
    //damage var
    const levelScore = leaf_blower.level_score
    const lvl = world.scoreboard.getObjective(levelScore)
    const lvlAmount = lvl.getScore(player)
    const damageAmount = leaf_blower.attack1.damage_amount + (lvlAmount/2) * leaf_blower.damage_multiply
    //ngab
    const damage = damageAmount
    let duration = 15
    //player.addTag(`ld_hw:chainsaw_frenzy`)
    const interval = system.runInterval(()=>{
        if (player.hasTag(`ld_hw:chainsaw_frenzy`)){
            player.runCommand(`effect @s strength 1 4 true`)
        }
    })
    system.runTimeout(()=>{
        damagingEntity.dimension.getEntities({location: damagingEntity.location, maxDistance: 8, excludeTypes: ['minecraft:item','minecraft:xp_orb'], excludeFamilies: ['ld_hw']}).forEach(target=>{
        if (target != player && target != damagingEntity) {
            target.applyDamage(damage, {cause: "contact",damagingEntity: player})
            try {
            target.applyKnockback(target.location.x, target.location.z, 0, 2)
            } catch (error) {
                
            }
            //DEBUG 1 //console.warn(`your damage is ${damage}`)
        }
    })
    },0.63*20)
    system.runTimeout(()=>{
        system.clearRun(interval)
        player.removeTag(`ld_hw:chainsaw_frenzy`)
    }, duration * 20)

    //Particles
    const parRange = 5
    system.runTimeout(()=>{
        player.runCommand(`camera @s fade time 0.05 0 0.2 color 255 255 255`)
        player.runCommand(`camerashake add @a[r=5] 0.1 1 positional`)
        const parLoc = {
            x: player.location.x + player.getViewDirection().x * parRange, y: player.location.y+0.5, z: player.location.z + player.getViewDirection().z * parRange
        }
        for (let index = 1; index <= 3; index++) {
            player.dimension.spawnParticle(`ld_hw:leaf_blower.ability_1_${index}`, parLoc)
        }
    },0.5*20)
}
function leaf_blower_Attack2Effect(player, damagingEntity){
    const rotX = player.getRotation().x
    const rotY = player.getRotation().y
    //damage var
    const levelScore = leaf_blower.level_score
    const lvl = world.scoreboard.getObjective(levelScore)
    const lvlAmount = lvl.getScore(player)
    const damageAmount = leaf_blower.attack2.damage_amount + (lvlAmount/2) * leaf_blower.damage_multiply
    //ngab
    const damage = damageAmount
    const range = 5
    const sucker = player.dimension.spawnEntity('ld_hw:leaf_blower_attack2', {x: player.location.x + player.getViewDirection().x * range, y: player.location.y, z: player.location.z + player.getViewDirection().z * range })
    //let lastProjectilePos = sucker.location
    const interval = system.runInterval(()=>{
        if (sucker.isValid()==true){
            sucker.teleport({x: player.location.x + player.getViewDirection().x * range, y: player.location.y, z: player.location.z + player.getViewDirection().z * range })
            sucker.dimension.getEntities({location: sucker.location, maxDistance: 10, excludeTypes: ['minecraft:item','minecraft:xp_orb'], excludeFamilies: ['ld_hw']}).forEach(target=>{
                if (target != player && target != sucker) {
                    target.applyDamage(damage, {cause: "contact", damagingEntity: player});
                    target.teleport(sucker.location)
                    //DEBUG 1 //console.warn(`your damage is ${damage}`)
                }
            })
        } else {
            system.clearRun(interval)
        }
    })

    //Particles
    const parLoc = {
        x: sucker.location.x,
        y: sucker.location.y+1,
        z: sucker.location.z
    }
    system.runTimeout(()=>{
        player.runCommand(`camerashake add @a[r=5] 0.1 1 positional`)
        for (let index = 1; index <= 4; index++) {
            player.dimension.spawnParticle(`ld_hw:leaf_blower.ability_2_${index}`, parLoc)
        }
    },0.04*20)
}
function leaf_blower_Attack3Effect(player, damagingEntity){
    //damage var
    const levelScore = leaf_blower.level_score
    const lvl = world.scoreboard.getObjective(levelScore)
    const lvlAmount = lvl.getScore(player)
    const damageAmount = leaf_blower.attack3.titit_amount + (lvlAmount/2) * leaf_blower.damage_multiply
    //ngab
    const damage = damageAmount
    //console.warn(damageAmount)
    if(world.getDynamicProperty('ld_hw.:block_damage')===true){damagingEntity.runCommand(`fill ~-1~~-1 ~1~2~1 air destroy`)}
    system.runTimeout(()=>{
        player.runCommand(`camerashake add @a[r=5] 0.1 1 positional`)
        player.runCommand(`camera @s fade time 0.05 0 0.2 color 255 255 255`)
        player.dimension.spawnParticle(`ld_hw:chainsaw_frenzy_03`, {x: player.location.x, y: player.location.y, z: player.location.z})
        player.dimension.spawnParticle(`ld_hw:chainsaw_frenzy_04`, {x: player.location.x, y: player.location.y, z: player.location.z})
        player.dimension.spawnParticle(`ld_hw:chainsaw_frenzy_05`, {x: player.location.x, y: player.location.y, z: player.location.z})
        player.runCommand(`summon ld_hw:locator1 ~~~ ~~ grind_through`)
    })
    const range = 5
    const blower = player.dimension.spawnEntity('ld_hw:leaf_blower_attack3', {x: player.location.x + player.getViewDirection().x * range, y: player.location.y, z: player.location.z + player.getViewDirection().z * range })
    //let lastProjectilePos = blower.location
    const interval = system.runInterval(()=>{
        if (blower.isValid()==true){
            blower.teleport({x: player.location.x + player.getViewDirection().x * range, y: player.location.y, z: player.location.z + player.getViewDirection().z * range }, {rotation:player.getRotation()})
            blower.dimension.getEntities({location: blower.location, maxDistance: 10, excludeTypes: ['minecraft:item','minecraft:xp_orb'], excludeFamilies: ['ld_hw']}).forEach(target=>{
                if (target != player && target != blower) {
                    target.applyDamage(damage, {cause: "contact", damagingEntity: player});
                    try {
                    target.applyKnockback((target.location.x-player.location.x), (target.location.z-player.location.z), 4, 1)
                    } catch (error) {
                        
                    }
                }
            })
        } else {
            system.clearRun(interval)
        }
    })
}
function leaf_blower_Attack4Effect(player, damagingEntity){
    //Damage Positioning
    const range = 5
    const parRange = 5
    player.addEffect('resistance', leaf_blower.attack4.attackDuration * 20, {amplifier:255})
    damagingEntity.teleport(player.location, {rotation: {x: 0, y: player.getRotation().y}})
    damagingEntity.teleport({x:damagingEntity.location.x+damagingEntity.getViewDirection().x*range, y:damagingEntity.location.y, z:damagingEntity.location.z+damagingEntity.getViewDirection().z*range})

    if(world.getDynamicProperty('ld_hw.:sound')){
        system.runTimeout(()=>{
            player.runCommand(`playsound ld_hw:orchestral_riser @s`)
        })
        system.runTimeout(()=>{
            player.runCommand(`playsound ld_hw:laugh @s`)
        },3*20)
        system.runTimeout(()=>{
            player.runCommand(`playsound ld_hw:orchestral_stab @s`)
        },5.5*20)
    }
    //Camera Setup
    //runCommand(`camera @p set minecraft:free pos ^2 ^1 ^3 facing @s`) STATIC
	//runCommandAsync(`camera @p set minecraft:free ease 1.0 linear pos ^2 ^1 ^5 facing @s`) DYNAMIC
    //getEntities({excludeTypes: 'minecraft:item'})
    const dunia = world.getDimension(`overworld`)
    let slotIndex = player.selectedSlotIndex
    damagingEntity.dimension.getEntities({location: damagingEntity.location, maxDistance: 10, excludeTypes: ['minecraft:item','minecraft:xp_orb']}).forEach(target=>{
        if (target.typeId==='minecraft:player'){
        target.addTag(`ld_hw:selected_by_${damagingEntity.id}`)
        target.addTag(`ld_hw:in_ability`)
        dunia.runCommand(`inputpermission set @a[tag=ld_hw:in_ability] camera disabled`)
        dunia.runCommand(`inputpermission set @a[tag=ld_hw:in_ability] movement disabled`)
        dunia.runCommand(`hud @a[tag=ld_hw:in_ability] hide`)
        
        system.runTimeout(()=>{
            damagingEntity.runCommand(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] fade time 0.5 ${textDelay-0.5} 0 color 119 32 177`)
        })
        if(world.getDynamicProperty('ld_hw.:camera')){
            system.runTimeout(()=>{
                system.runTimeout(()=>{
                    const cineData = {
                        subject: damagingEntity,
                        tag: damagingEntity.id,
                        pos: [`^-2^1^-3`],
                        face: [`${player.location.x} ${player.location.y+1} ${player.location.z}`],
                        type: `static`,
                        duration: 0.2
                    }
                    cinematic(cineData)
                })
                system.runTimeout(()=>{
                    const cineData = {
                        subject: damagingEntity,
                        tag: damagingEntity.id,
                        pos: [`^-2^1^-3`, `^-4^3^-1`],
                        face: [`${player.location.x} ${player.location.y+1} ${player.location.z}`, `${player.location.x} ${player.location.y+1} ${player.location.z}`],
                        type: `cinematic`,
                        duration: 0.2
                    }
                    cinematic(cineData)
                },0.2*20)
                system.runTimeout(()=>{
                    const cineData = {
                        subject: damagingEntity,
                        tag: damagingEntity.id,
                        pos: [`^8^3^-2`, `^8^3^2`],
                        face: [`~~~`, `~~~`],
                        type: `cinematic`,
                        duration: 2.3
                    }
                    cinematic(cineData)
                },1.2*20)
                system.runTimeout(()=>{
                    const cineData = {
                        subject: damagingEntity,
                        tag: damagingEntity.id,
                        pos: [`^^0.5^-2`, `^^0.5^-1`],
                        face: [`${player.location.x} ${player.location.y+1} ${player.location.z}`, `${player.location.x} ${player.location.y+1} ${player.location.z}`],
                        type: `cinematic`,
                        duration: 1.0
                    }
                    cinematic(cineData)
                },3.5*20)
            },textDelay*20)
        }
        system.runTimeout(()=>{
            player.runCommand(`title @s clear`)
        },textDelay*20)
        system.runTimeout(()=>{
            player.removeTag('ld_hw:using_ability')
            damagingEntity.runCommand(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] clear`)
            dunia.runCommand(`inputpermission set @a[tag=ld_hw:selected_by_${damagingEntity.id}] camera enabled`)
            dunia.runCommand(`inputpermission set @a[tag=ld_hw:selected_by_${damagingEntity.id}] movement enabled`)
            dunia.runCommand(`hud @a[tag=ld_hw:selected_by_${damagingEntity.id}] reset`)
            dunia.runCommand(`tag @a[tag=ld_hw:selected_by_${damagingEntity.id}] remove ld_hw:in_ability`)
            dunia.runCommand(`tag @a[tag=ld_hw:selected_by_${damagingEntity.id}] remove ld_hw:selected_by_${damagingEntity.id}`)
            player.runCommand('scoreboard players set @s ld_hw:leaf_blower_ult 0')
            player.addEffect('strength', 15*20, {amplifier:5})
            player.addEffect('speed', 15*20, {amplifier:3})
            player.getComponent("minecraft:inventory").container.setItem(slotIndex, new ItemStack('ld_hw:leaf_blower'));
            player.runCommand(`titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw:cc.frenzied_rampage_run"}]}`)
            const madness = system.runInterval(()=>{
                if(!player.hasTag('ld_hw:madness')){player.addTag('ld_hw:madness')}
                player.dimension.getEntities({location:player.location, maxDistance: 5, excludeTypes: ['minecraft:item','minecraft:xp_orb'], excludeFamilies: ['ld_hw']}).forEach(madTarget=>{
                    if(madTarget===player)return
                    madTarget.applyDamage(6, {cause:'contact',damagingEntity:player})
                })
                if(world.getDynamicProperty('ld_hw.:block_damage')===true){
                    player.runCommand(`fill ~-2~~-2 ~2~5~2 air destroy`)
                }
            })
            system.runTimeout(()=>{
                system.clearRun(madness)
                player.removeTag('ld_hw:madness')
                //player.runCommand(`replaceitem entity @s slot.hotbar ${slotIndex} ld_hw:leaf_blower`)
            },15*20)
            if(target===player) return
            const weapon = 'ld_hw:leaf_blower'
            ultimate_attack_jumpscare(weapon,target)
        },(leaf_blower.attack4.attackDuration)*20)
        }
        if (target === player) return;
        target.runCommand(leaf_blower.attack4.attack_translate)
        system.runTimeout(()=>{
            target.runCommand(`title @s clear`)
        },textDelay*20)
        target.addEffect('slowness', leaf_blower.attack4.attackDuration * 20, {amplifier: 255})
    })
    system.runTimeout(()=>{
        system.runTimeout(()=>{
            player.runCommand(`particle ld_hw:chainsaw_frenzy_01 ^-0.2^2^1`)
            player.runCommand(`particle ld_hw:chainsaw_frenzy_02 ^-0.2^2^1`)
    
            player.dimension.spawnParticle(`ld_hw:chainsaw_frenzy_03`, { x: player.location.x + player.getViewDirection().x * parRange, y: player.location.y, z: player.location.z + player.getViewDirection().z * parRange })
            player.dimension.spawnParticle(`ld_hw:chainsaw_frenzy_04`, { x: player.location.x + player.getViewDirection().x * parRange, y: player.location.y, z: player.location.z + player.getViewDirection().z * parRange })
            player.dimension.spawnParticle(`ld_hw:chainsaw_frenzy_05`, { x: player.location.x + player.getViewDirection().x * parRange, y: player.location.y, z: player.location.z + player.getViewDirection().z * parRange })
            player.dimension.spawnParticle(`ld_hw:chainsaw_frenzy_06`, { x: player.location.x + player.getViewDirection().x * parRange, y: player.location.y, z: player.location.z + player.getViewDirection().z * parRange })
            player.dimension.spawnParticle(`ld_hw:chainsaw_frenzy_07`, { x: player.location.x + player.getViewDirection().x * parRange, y: player.location.y, z: player.location.z + player.getViewDirection().z * parRange })
            player.dimension.spawnParticle(`ld_hw:chainsaw_frenzy_08`, { x: player.location.x + player.getViewDirection().x * parRange, y: player.location.y, z: player.location.z + player.getViewDirection().z * parRange })
            //player.dimension.spawnParticle(`ld_hw:frenzied_rampage_2`, { x: player.location.x + player.getViewDirection().x * parRange, y: player.location.y, z: player.location.z + player.getViewDirection().z * parRange })
    
            // player.dimension.spawnParticle(`ld_hw:frenzied_rampage_1`, { x: player.location.x + player.getViewDirection().x * parRange, y: player.location.y, z: player.location.z + player.getViewDirection().z * parRange })
            // player.dimension.spawnParticle(`ld_hw:frenzied_rampage_2`, { x: player.location.x + player.getViewDirection().x * parRange, y: player.location.y, z: player.location.z + player.getViewDirection().z * parRange })
            // player.dimension.spawnParticle(`ld_hw:frenzied_rampage_3`, { x: player.location.x + player.getViewDirection().x * parRange, y: player.location.y, z: player.location.z + player.getViewDirection().z * parRange })
            player.dimension.spawnParticle(`ld_hw:chainsaw_frenzy_04`, { x: player.location.x + player.getViewDirection().x * parRange, y: player.location.y, z: player.location.z + player.getViewDirection().z * parRange })
        }, 1.5*20)
        const par = player.dimension.spawnEntity('ld_hw:leaf_blower_par4', player.location)
        par.setRotation(player.getRotation())
    },textDelay*20)
}

function scary_lantern_Attack1Effect(player, damagingEntity){
    //damage var
    const levelScore = scary_lantern.level_score
    const lvl = world.scoreboard.getObjective(levelScore)
    const lvlAmount = lvl.getScore(player)
    const duration = 3
    const damageAmount = scary_lantern.attack1.damage_amount + (lvlAmount/2) * scary_lantern.damage_multiply
    //ngab
    const damage = damageAmount
    system.runTimeout(()=>{
        player.dimension.getEntities({maxDistance: 10, location: player.location, excludeTypes: ['minecraft:item','minecraft:xp_orb']}).forEach(target=>{
            if (target === player)
                return;
            target.addTag('ld_hw:target_scary_lantern1')
            tagsUtilities(player, target, damage, duration)
            if (target.typeId==='minecraft:player'){
                target.runCommand('/camera @s fade time 0.3 0 1 color 255 255 255')
            }
        })
        player.runCommand('/camera @s fade time 0.3 0 1 color 255 255 255')
    }, 0.42 * 20)
    system.runTimeout(()=>{
        player.runCommand(`particle ld_hw:haunting_light_1 ^-0.5^1.8^1`)
        player.runCommand(`particle ld_hw:haunting_light_2 ^-0.5^1.8^1`)
    },0.58*20)
}
function scary_lantern_Attack2Effect(player, damagingEntity){
    system.runTimeout(()=>{
        player.dimension.getEntities({maxDistance: 10, location: player.location, excludeTypes: ['minecraft:item','minecraft:xp_orb']}).forEach(target=>{
            if (target === player)
                return;
            target.runCommand(`camera @s fade time 0.3 8 4 color 240 255 240`)
            target.addEffect(`slowness`, 8*20, {amplifier:3})
        })
    }, 0.6 * 20)
    system.runTimeout(()=>{
        player.runCommand('/camera @s fade time 0.3 0 1 color 255 255 255')
        player.runCommand(`particle ld_hw:ghostly_energy_1 ~~3~`)
        player.runCommand(`particle ld_hw:ghostly_energy_2 ^-0.4^1^1`)
        player.runCommand(`particle ld_hw:ghostly_energy_3 ^-0.4^1^1`)
    }, 0.46 * 20)
}
function scary_lantern_Attack3Effect(player, damagingEntity){
    const levelScore = scary_lantern.level_score
    const lvl = world.scoreboard.getObjective(levelScore)
    const lvlAmount = lvl.getScore(player)
    const effectAmpli = 1+(lvlAmount-3)
    system.runTimeout(()=>{
        player.runCommand(`effect @s invisibility 5 0 true`)
        player.runCommand(`effect @s speed 5 ${effectAmpli} true`)
    }, 1.21*20)
    system.runTimeout(()=>{
        player.dimension.getPlayers({location:player.location, maxDistance:10}).forEach(players=>{
            if (players===player){players.runCommand('/camera @s fade time 0.3 0 1 color 255 255 255')} else {players.runCommand('/camera @s fade time 0.3 1 3 color 255 255 255')}
        })
    },2.13*20)
    system.runTimeout(()=>{
        player.runCommand(`effect @s invisibility 1 0 true`)
    }, 5.79*20)
    
    const locator = player.dimension.spawnEntity('ld_hw:locator1', player.location)
    system.runTimeout(()=>{locator.runCommand(`event entity @s spectral_flicker`)},1.25*20)
    const interval = system.runInterval(()=>{
        if (locator.isValid===false)
            return;
        locator.teleport(player.location)
        locator.dimension.getEntities({location:locator.location,maxDistance:6,excludeFamilies,excludeTypes:['minecraft:item','minecraft:xp_orb'],excludeFamilies:['ld_hw']}).forEach(target=>{
            if(target===player)return
            target.applyDamage(6,{cause:'contact',damagingEntity:player})
        })
    })
    system.runTimeout(()=>{
        system.clearRun(interval)
    },8*20)
}
function scary_lantern_Attack4Effect(player, damagingEntity){
    //Damage Positioning
    const range = 4
    //damage var
    const levelScore = scary_lantern.level_score
    const lvl = world.scoreboard.getObjective(levelScore)
    const lvlAmount = lvl.getScore(player)
    const duration = 6
    const damageAmount = scary_lantern.attack4.damage_amount + (lvlAmount/2) * scary_lantern.damage_multiply
    //ngab
    const damage = damageAmount
    player.addEffect('resistance', scary_lantern.attack4.attackDuration * 20, {amplifier:255})
    damagingEntity.teleport(player.location, {rotation: {x: 0, y: player.getRotation().y}})
    damagingEntity.teleport({x:damagingEntity.location.x+damagingEntity.getViewDirection().x*range, y:damagingEntity.location.y, z:damagingEntity.location.z+damagingEntity.getViewDirection().z*range})

    if(world.getDynamicProperty('ld_hw.:sound')){
        system.runTimeout(()=>{
            player.runCommand(`playsound ld_hw:orchestral_riser @s`)
        })
        system.runTimeout(()=>{
            player.runCommand(`playsound ld_hw:laugh @s`)
        },3*20)
        system.runTimeout(()=>{
            player.runCommand(`playsound ld_hw:orchestral_stab @s`)
        },5.8*20)
    }
    //Camera Setup
    //runCommand(`camera @p set minecraft:free pos ^2 ^1 ^3 facing @s`) STATIC
	//runCommandAsync(`camera @p set minecraft:free ease 1.0 linear pos ^2 ^1 ^5 facing @s`) DYNAMIC
    //getEntities({excludeTypes: 'minecraft:item'})
    const dunia = world.getDimension(`overworld`)
    damagingEntity.dimension.getEntities({location: damagingEntity.location, maxDistance: 10, excludeTypes: ['minecraft:item','minecraft:xp_orb']}).forEach(target=>{
        if (target.typeId==='minecraft:player'){
        target.addTag(`ld_hw:selected_by_${damagingEntity.id}`)
        target.addTag(`ld_hw:in_ability`)
        dunia.runCommand(`inputpermission set @a[tag=ld_hw:in_ability] camera disabled`)
        dunia.runCommand(`inputpermission set @a[tag=ld_hw:in_ability] movement disabled`)
        dunia.runCommand(`hud @a[tag=ld_hw:in_ability] hide`)
        system.runTimeout(()=>{
            damagingEntity.runCommand(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] fade time 0.5 ${textDelay-0.5} 0 color 34 82 0`)
        })
        if(world.getDynamicProperty('ld_hw.:camera')){
            system.runTimeout(()=>{
                system.runTimeout(()=>{
                    damagingEntity.runCommand(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] set minecraft:free pos ^-1 ^1 ^-2 facing ${player.location.x} ${player.location.y} ${player.location.z}`)
                    damagingEntity.runCommandAsync(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] set minecraft:free ease 0.5 linear pos ^-1 ^1 ^-1 facing ${player.location.x} ${player.location.y} ${player.location.z}`)
                })
                system.runTimeout(()=>{
                    damagingEntity.runCommand(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] set minecraft:free pos ^7 ^4 ^3 facing ${damagingEntity.location.x} ${damagingEntity.location.y} ${damagingEntity.location.z}`)
                    damagingEntity.runCommandAsync(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] set minecraft:free ease 3.25 linear pos ^8 ^4 ^4 facing ${damagingEntity.location.x} ${damagingEntity.location.y} ${damagingEntity.location.z}`)
                }, 0.5 * 20)
                system.runTimeout(()=>{
                    damagingEntity.runCommand(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] set minecraft:free pos ^ ^0.5 ^-1 facing ${player.location.x} ${player.location.y+1} ${player.location.z}`)
                    damagingEntity.runCommandAsync(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] set minecraft:free ease 1.0 linear pos ^ ^1 ^-2 facing ${player.location.x} ${player.location.y+1} ${player.location.z}`)
                }, 3.75*20)
            },textDelay*20)
        }
        system.runTimeout(()=>{
            player.runCommand(`title @s clear`)
        },textDelay*20)
        system.runTimeout(()=>{
            damagingEntity.runCommand(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] clear`)
            dunia.runCommand(`inputpermission set @a[tag=ld_hw:selected_by_${damagingEntity.id}] camera enabled`)
            dunia.runCommand(`inputpermission set @a[tag=ld_hw:selected_by_${damagingEntity.id}] movement enabled`)
            dunia.runCommand(`hud @a[tag=ld_hw:selected_by_${damagingEntity.id}] reset`)
            dunia.runCommand(`tag @a[tag=ld_hw:selected_by_${damagingEntity.id}] remove ld_hw:in_ability`)
            dunia.runCommand(`tag @a[tag=ld_hw:selected_by_${damagingEntity.id}] remove ld_hw:selected_by_${damagingEntity.id}`)
            player.runCommand('scoreboard players set @s ld_hw:scary_lantern_ult 0')
            if(target===player) return
            const weapon = 'ld_hw:scary_lantern'
            ultimate_attack_jumpscare(weapon,target)
        }, (textDelay+5.75)*20)
        }
        if (target === player) return
        target.runCommand(scary_lantern.attack4.attack_translate)
        system.runTimeout(()=>{
            target.runCommand(`title @s clear`)
        },textDelay*20)
        target.addEffect('slowness', scary_lantern.attack4.attackDuration * 20, {amplifier: 255})
    })
    system.runTimeout(()=>{
        system.runTimeout(()=>{
            player.dimension.spawnParticle('ld_hw:wraiths_gaze_5', {x:player.location.x,y:player.location.y+0.1,z:player.location.z})
            player.runCommand(`particle ld_hw:wraiths_gaze_1 ^-1^2^0.3`)
            player.runCommand(`particle ld_hw:wraiths_gaze_2 ^-1^2^0.3`)
            player.runCommand(`particle ld_hw:wraiths_gaze_3 ^-1^2^0.3`)
            player.runCommand(`particle ld_hw:wraiths_gaze_4 ^-1^2^0.3`)
            damagingEntity.dimension.getEntities({location: damagingEntity.location, maxDistance: 10, excludeTypes: ['minecraft:item','minecraft:xp_orb'], excludeFamilies: ['ld_hw']}).forEach(target=>{
                if (target===player)return;
                target.addTag('ld_hw:target_scary_lantern4')
                tagsUtilities(player,target,damage,duration)
                //DEBUG 1 //console.warn(`your damage is ${damage}`)
            })
        },0.5*20)
    },(textDelay)*20)
}

function digital_grave_Attack1Effect(player, damagingEntity) {
    const range = 1;
    
    // Calculate damage
    const levelScore = digital_grave.level_score;
    const lvl = world.scoreboard.getObjective(levelScore);
    const lvlAmount = lvl.getScore(player);
    const damageAmount = digital_grave.attack1.damaging[0].damage_amount + (lvlAmount / 2) * digital_grave.damage_multiply;
    const damage = damageAmount;
    damagingEntity.teleport(player.location, {rotation: {x: 0, y: player.getRotation().y}});
    damagingEntity.teleport({
        x: damagingEntity.location.x + damagingEntity.getViewDirection().x * range,
        y: damagingEntity.location.y,
        z: damagingEntity.location.z + damagingEntity.getViewDirection().z * range
    });


    // Apply teleportation and damage in multiple stages
    for (let i = 0; i < 10; i++) {
        // Deal damage to entities in range and spawn particles
        damagingEntity.dimension.getEntities({location: damagingEntity.location, maxDistance: 3, excludeTypes: ['minecraft:item','minecraft:xp_orb'], excludeFamilies: ['ld_hw']}).forEach(target => {
            if (target != player && target != damagingEntity) {
                target.applyDamage(damage, {cause: 'contact', damagingEntity: player});
                // DEBUG: Display damage amount
                // //console.warn(`your damage is ${damage}`);
                target.dimension.spawnParticle('ld_hw:corrupted_energy_4', target.location);
                target.addEffect(`slowness`, 3*20, {amplifier:2})
                if(target.typeId === 'minecraft:player') {
                    target.runCommand(`playsound ld_hw:effect.glitch @s`)
                    target.runCommand(`camerashake add @s 0.8 3 rotational`)
                }
            }
        });

        // Teleport again after processing
        damagingEntity.runCommand(`tp @s ^^^1`); 
    }

    // Summon a locator after the attack
    player.runCommand(`summon ld_hw:locator1 ~~~ ~~ corrupted_data_blast`);
    player.runCommand(`camerashake add @a[r=5] 0.1 0.3 positional`)
}
function digital_grave_Attack2Effect(player, damagingEntity){
    //damage var
    const levelScore = digital_grave.level_score
    const lvl = world.scoreboard.getObjective(levelScore)
    const lvlAmount = lvl.getScore(player)
    const damageAmount = digital_grave.attack2.damage_amount + (lvlAmount/2) * digital_grave.damage_multiply
    //ngab
    const damage = damageAmount
    damagingEntity.dimension.getEntities({maxDistance: 6, location:damagingEntity.location, excludeTypes: ['minecraft:item','minecraft:xp_orb'], excludeFamilies: ['ld_hw']}).forEach(target=>{
        // if (target === player) 
        //     return
        const targetLocation = target.location
        const playerLocation = player.location
        const targetRotation = target.getRotation()
        const health = target.getComponent('minecraft:health').currentValue
        let alreadyTeleported = false
        const healthDetection = system.runInterval(()=>{
            if(player.getComponent('minecraft:health').currentValue <= 2) {
                //console.warn(`anjay`)
                player.teleport(playerLocation)
                alreadyTeleported = true
                system.clearRun(healthDetection)
            }
        })
        system.runTimeout(()=>{
            player.runCommand(`camera @s fade time 0.2 0 0.2 color 255 255 255`)
            if (target.isValid()===false){
                const newTarget = world.getDimension('overworld').spawnEntity(target.typeId, targetLocation)
                newTarget.getComponent('minecraft:health').setCurrentValue(health)
                const v3T = {x: newTarget.location.x, y: newTarget.location.y + 0.1, z: newTarget.location.z}
                newTarget.dimension.spawnParticle('ld_hw:error_reboot_1', v3T)
                newTarget.dimension.spawnParticle('ld_hw:error_reboot_2', v3T)
                newTarget.dimension.spawnParticle('ld_hw:error_reboot_3', v3T)
            }
            target.getComponent('minecraft:health').setCurrentValue(health)
            //target.applyDamage(damage,{cause:'contact',damagingEntity:player})
            //DEBUG 1 //console.warn(`your damage is ${damage}`)
            //target.runCommand(`tp @s ${targetLocation.x} ${targetLocation.y} ${targetLocation.z} ${targetRotation.y} ${targetRotation.x}`)
            if(alreadyTeleported===false){
                player.teleport(playerLocation)
            }
            player.runCommand(`camerashake add @a[r=5] 0.1 1 positional`)
            player.runCommand(`playsound ld_hw:weapon.digital_grave_hold @a ~~~`)
            const v3T = {x: target.location.x, y: target.location.y + 0.1, z: target.location.z}
            target.dimension.spawnParticle('ld_hw:error_reboot_1', v3T)
            target.dimension.spawnParticle('ld_hw:error_reboot_2', v3T)
            target.dimension.spawnParticle('ld_hw:error_reboot_3', v3T)
            
            if (target===player)
                return
            target.teleport(targetLocation, {rotation:targetRotation})
            target.runCommand(`camera @s fade time 0.2 0.3 0.2 color 255 255 255`)
            target.runCommand(`effect @s slowness 2 255 true`)
        }, 5*20)
    })
    system.runTimeout(()=>{
        player.runCommand(`camera @s fade time 0.05 0 0.2 color 255 255 255`)
        player.runCommand(`camerashake add @a[r=5] 0.1 1 positional`)
        const itemSave = player.getComponent("equippable")?.getEquipment("Offhand")
        const totem = new ItemStack("minecraft:totem_of_undying")
        totem.lockMode = "slot"
        player.getComponent("equippable").setEquipment("Offhand", totem)
        system.runTimeout(() => { player.getComponent("equippable").setEquipment("Offhand", itemSave) }, 20*6)
        player.addTag('ld_hw:reboot')
        const health = player.getComponent('minecraft:health').currentValue
        player.setDynamicProperty('ld_hw:health_saved',health)
        player.setDynamicProperty('ld_hw:reboot_x',player.location.x)
        player.setDynamicProperty('ld_hw:reboot_y',player.location.y)
        player.setDynamicProperty('ld_hw:reboot_z',player.location.z)
        const v3 = {x: player.location.x, y: player.location.y + 0.1, z: player.location.z}
        player.dimension.spawnParticle('ld_hw:error_reboot_1', v3)
        player.dimension.spawnParticle('ld_hw:error_reboot_2', v3)
        player.dimension.spawnParticle('ld_hw:error_reboot_3', v3)
        player.dimension.spawnParticle('ld_hw:error_reboot_4', v3)
        player.dimension.spawnParticle('ld_hw:error_reboot_5', v3)
        player.dimension.spawnParticle('ld_hw:error_reboot_6', v3)
        player.dimension.spawnParticle('ld_hw:error_reboot_7', v3)
    },0*20)
    // system.runTimeout(()=>{
    //     player.removeTag('ld_hw:reboot')
    // },10*20)
}
function digital_grave_Attack3Effect(player, damagingEntity){
    //damage var
    const levelScore = digital_grave.level_score
    const lvl = world.scoreboard.getObjective(levelScore)
    const lvlAmount = lvl.getScore(player)
    const damageAmount = digital_grave.attack3.damage_amount + (lvlAmount/3) * digital_grave.damage_multiply
    //ngab
    const damage = damageAmount
    system.runTimeout(()=>{
        player.runCommand(`camerashake add @a[r=5] 0.1 1 positional`)
        player.dimension.getEntities({maxDistance: 10, location:player.location, excludeTypes: ['minecraft:item','minecraft:xp_orb'], excludeFamilies: ['ld_hw']}).forEach(target=>{
            if (target === player)
                return;
            target.addTag(`ld_hw:infected`)
        })
        world.getDimension('overworld').getEntities({tags: ['ld_hw:infected']}).forEach(subject=>{
            infection(subject, player, damage)
        })
        player.dimension.spawnParticle('ld_hw:virus_spread_1', {x:player.location.x,y:player.location.y+0.1,z:player.location.z})
        player.dimension.spawnParticle('ld_hw:virus_spread_2', {x:player.location.x,y:player.location.y+0.1,z:player.location.z})
        player.dimension.spawnParticle('ld_hw:virus_spread_3', {x:player.location.x,y:player.location.y+0.1,z:player.location.z})
        player.dimension.spawnParticle('ld_hw:virus_spread_4', {x:player.location.x,y:player.location.y+0.1,z:player.location.z})
        player.dimension.spawnParticle('ld_hw:virus_spread_5', {x:player.location.x,y:player.location.y+0.1,z:player.location.z})
        player.dimension.spawnParticle('ld_hw:virus_spread_6', {x:player.location.x,y:player.location.y+0.1,z:player.location.z})
        player.dimension.spawnParticle('ld_hw:virus_spread_7', {x:player.location.x,y:player.location.y+0.1,z:player.location.z})
        player.dimension.spawnParticle('ld_hw:virus_spread_8', {x:player.location.x,y:player.location.y+0.1,z:player.location.z})
        player.dimension.spawnParticle('ld_hw:virus_spread_9', {x:player.location.x,y:player.location.y+0.1,z:player.location.z})
    },0.46*20)
}
function digital_grave_Attack4Effect(player, damagingEntity){
    //damage var
    const levelScore = digital_grave.level_score
    const lvl = world.scoreboard.getObjective(levelScore)
    const lvlAmount = lvl.getScore(player)
    const damageAmount = digital_grave.attack4.damage_amount + (lvlAmount/2) * digital_grave.damage_multiply
    //ngab
    const damage = damageAmount
    //Damage Positioning
    const range = 4
    const duration = 15
    player.addEffect('resistance', digital_grave.attack4.attackDuration * 20, {amplifier:255})
    damagingEntity.teleport(player.location, {rotation: {x: 0, y: player.getRotation().y}})
    damagingEntity.teleport({x:damagingEntity.location.x+damagingEntity.getViewDirection().x*range, y:damagingEntity.location.y, z:damagingEntity.location.z+damagingEntity.getViewDirection().z*range})

    if(world.getDynamicProperty('ld_hw.:sound')){
        system.runTimeout(()=>{
            player.runCommand(`playsound ld_hw:orchestral_riser @s`)
        })
        system.runTimeout(()=>{
            player.runCommand(`playsound ld_hw:laugh @s`)
        },3*20)
        system.runTimeout(()=>{
            player.runCommand(`playsound ld_hw:orchestral_stab @s`)
        },4.8*20)
    }
    //Camera Setup
    //runCommand(`camera @p set minecraft:free pos ^2 ^1 ^3 facing @s`) STATIC
	//runCommandAsync(`camera @p set minecraft:free ease 1.0 linear pos ^2 ^1 ^5 facing @s`) DYNAMIC
    //getEntities({excludeTypes: 'minecraft:item'})
    const dunia = world.getDimension(`overworld`)
    damagingEntity.dimension.getEntities({location: damagingEntity.location, maxDistance: 10, excludeTypes: ['minecraft:item','minecraft:xp_orb'], excludeFamilies: ['ld_hw']}).forEach(target=>{
        if (target.typeId==='minecraft:player'){
        target.addTag(`ld_hw:selected_by_${damagingEntity.id}`)
        target.addTag(`ld_hw:in_ability`)
        dunia.runCommand(`inputpermission set @a[tag=ld_hw:in_ability] camera disabled`)
        dunia.runCommand(`inputpermission set @a[tag=ld_hw:in_ability] movement disabled`)
        dunia.runCommand(`hud @a[tag=ld_hw:in_ability] hide`)
        damagingEntity.runCommand(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] fade time 0.5 ${textDelay-0.5} 0 color 20 0 80`)
        if(world.getDynamicProperty('ld_hw.:camera')){
        system.runTimeout(()=>{
            system.runTimeout(()=>{
                damagingEntity.runCommand(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] set minecraft:free pos ^-1 ^1 ^-2 facing ${player.location.x} ${player.location.y} ${player.location.z}`)
                damagingEntity.runCommandAsync(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] set minecraft:free ease 0.5 linear pos ^-1 ^1 ^-1 facing ${player.location.x} ${player.location.y} ${player.location.z}`)
            }, 0 * 20)
            system.runTimeout(()=>{
                damagingEntity.runCommand(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] set minecraft:free pos ^-1 ^1 ^-1 facing ${player.location.x} ${player.location.y} ${player.location.z}`)
                damagingEntity.runCommandAsync(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] set minecraft:free ease 0.1 linear pos ^ ^1 ^-1 facing ${player.location.x} ${player.location.y+1} ${player.location.z}`)
            }, 0.5 * 20)
            system.runTimeout(()=>{
                damagingEntity.runCommand(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] set minecraft:free pos ^7 ^4 ^3 facing ${damagingEntity.location.x} ${damagingEntity.location.y} ${damagingEntity.location.z}`)
                damagingEntity.runCommandAsync(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] set minecraft:free ease 2.25 linear pos ^8 ^4 ^4 facing ${damagingEntity.location.x} ${damagingEntity.location.y} ${damagingEntity.location.z}`)
            }, 0.75 * 20)
            system.runTimeout(()=>{
                damagingEntity.runCommand(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] set minecraft:free pos ^ ^3 ^-8 facing ${damagingEntity.location.x} ${damagingEntity.location.y+1} ${damagingEntity.location.z}`)
                damagingEntity.runCommandAsync(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] set minecraft:free ease 1.0 linear pos ^ ^5 ^-6 facing ${damagingEntity.location.x} ${damagingEntity.location.y+1} ${damagingEntity.location.z}`)
            }, 2.75*20)
        },textDelay*20)
        }
        system.runTimeout(()=>{
            damagingEntity.runCommand(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] clear`)
            dunia.runCommand(`inputpermission set @a[tag=ld_hw:selected_by_${damagingEntity.id}] camera enabled`)
            dunia.runCommand(`inputpermission set @a[tag=ld_hw:selected_by_${damagingEntity.id}] movement enabled`)
            dunia.runCommand(`hud @a[tag=ld_hw:selected_by_${damagingEntity.id}] reset`)
            dunia.runCommand(`tag @a[tag=ld_hw:selected_by_${damagingEntity.id}] remove ld_hw:in_ability`)
            dunia.runCommand(`tag @a[tag=ld_hw:selected_by_${damagingEntity.id}] remove ld_hw:selected_by_${damagingEntity.id}`)
            player.runCommand('scoreboard players set @s ld_hw:digital_grave_ult 0')
            if(target===player) return
            const weapon = 'ld_hw:digital_grave'
            ultimate_attack_jumpscare(weapon,target)
        }, (textDelay+4.75)*20)
        }
        if (target===player) return
        target.runCommand(digital_grave.attack4.attack_translate)
        system.runTimeout(()=>{
            target.runCommand(`title @s clear`)
        },textDelay*20)
        target.addEffect('slowness', digital_grave.attack4.attackDuration * 20, {amplifier: 255})
        system.runTimeout(()=>{target.addTag('ld_hw:target_digital_grave4')
        tagsUtilities(player,target,damage,duration)},textDelay*20)
    })
    system.runTimeout(()=>{
        player.runCommand(`title @s clear`)
    },textDelay*20)
    system.runTimeout(()=>{
        system.runTimeout(()=>{
            player.dimension.spawnParticle('ld_hw:digital_resurrection_1', { x: player.location.x, y: player.location.y+0.1, z: player.location.z})
            player.dimension.spawnParticle('ld_hw:digital_resurrection_2', { x: player.location.x, y: player.location.y+0.1, z: player.location.z})
            player.dimension.spawnParticle('ld_hw:digital_resurrection_3', { x: player.location.x, y: player.location.y+0.1, z: player.location.z})
            player.dimension.spawnParticle('ld_hw:digital_resurrection_4', { x: player.location.x, y: player.location.y+0.1, z: player.location.z})
            player.dimension.spawnParticle('ld_hw:digital_resurrection_9', { x: player.location.x, y: player.location.y+0.1, z: player.location.z})
        },0.83*20)
    }, (textDelay+1)*20)
}

function rusty_chains_Attack1Effect(player, damagingEntity) {
    const range = 2;
    const duration = 10;

    // Damage variables
    const levelScore = rusty_chains.level_score;
    const lvl = world.scoreboard.getObjective(levelScore);
    const lvlAmount = lvl.getScore(player);
    const damageAmount = rusty_chains.attack1.damage_amount + (lvlAmount / 2) * rusty_chains.damage_multiply;

    // Apply the damage
    const damage = damageAmount;

    // Move the damaging entity towards the player and apply damage to surrounding entities
    damagingEntity.teleport(player.location, { rotation: { x: 0, y: player.getRotation().y } });
    damagingEntity.teleport({
        x: damagingEntity.location.x + damagingEntity.getViewDirection().x * range,
        y: damagingEntity.location.y,
        z: damagingEntity.location.z + damagingEntity.getViewDirection().z * range
    });

    system.runTimeout(()=>{
        player.runCommand(`camerashake add @a[r=5] 0.1 0.5 positional`)
    },0.1*20)
    // Loop to apply damage to nearby entities up to 3 times
    for (let i = 0; i < 3; i++) {  // Repeat the process 4 times
        damagingEntity.dimension.getEntities({
            location: damagingEntity.location,
            maxDistance: 3,
            excludeTypes: ['minecraft:item', 'minecraft:xp_orb'],
            excludeFamilies: ['ld_hw']
        }).forEach(target => {
            if (target !== player) {
                target.teleport(damagingEntity.location)
                if(target.typeId=='minecraft:player'){target.runCommand(`inputpermission set @s movement disabled`)}else{target.addEffect('slowness',5*20,{amplifier:255})}
                target.addTag('ld_hw:target_rusty_chains1');
                tagsUtilities(player, target, damage, duration);
                target.applyDamage(damage, { cause: "contact", damagingEntity: player });
                //DEBUG 1 //console.warn(`your damage is ${damage}`);
                system.runTimeout(()=>{
                    if(!target.isValid())return
                    if(target.typeId=='minecraft:player'){target.runCommand(`inputpermission set @s movement enabled`)}
                },5*20)
            }
        });

        // Teleport the damaging entity to a new location
        damagingEntity.runCommand(`tp @s ^^^1`);
    }
}
function rusty_chains_Attack2Effect(player, damagingEntity) {
    const range = 10;
    const duration = 10;

    // Damage calculation
    const levelScore = rusty_chains.level_score;
    const lvl = world.scoreboard.getObjective(levelScore);
    const lvlAmount = lvl.getScore(player);
    const damageAmount = rusty_chains.attack2.damage_amount + (lvlAmount / 2) * rusty_chains.damage_multiply;
    const damage = damageAmount;

    // Use interval to apply effect
    system.runTimeout(() => {
        // Teleport damagingEntity close to player and move forward
        const spawnLoc = {
            x:player.location.x,
            y:player.location.y+1,
            z:player.location.z
        }
        damagingEntity.teleport(spawnLoc, { rotation: { x: player.getRotation().x, y: player.getRotation().y } });
        const facing = {
            y:player.getRotation().y,
            x:player.getRotation().x
        }
        
        // Apply teleport and hook effect 10 times (based on original pattern)
        for (let i = 0; i < 50*10; i++) {
            damagingEntity.runCommand(`tp @s ^^^0.1 ${facing.y} ${facing.x} true`)

            // Add the "hooked" tag to entities around the damagingEntity
            damagingEntity.dimension.getEntities({
                maxDistance: 3,
                location: damagingEntity.location,
                excludeTypes: ['minecraft:item', 'minecraft:xp_orb'],
                excludeFamilies: ['ld_hw'],
                excludeTags: [`ld_hw:${damagingEntity.id}`]
            }).forEach(target => {
                if (target === player) return;
                rusty_chains_hook(player, target, damagingEntity, damage)
            });
        }

        

    }, 0.42 * 20);

    // Handle teleportation of hooked entities and remove the "hooked" tag
    system.runTimeout(() => {
        player.runCommand(`camerashake add @a[r=5] 0.1 1 positional`)
        system.runTimeout(() => {
            damagingEntity.runCommand(`tag @e[tag=ld_hw:${damagingEntity.id}] remove ld_hw:${damagingEntity.id}`);
        }, 1 * 20);
    }, 1 * 20);
}
function rusty_chains_Attack3Effect(player, damagingEntity){
    const parRange = 5
    //damage var
    const levelScore = rusty_chains.level_score
    const lvl = world.scoreboard.getObjective(levelScore)
    const lvlAmount = lvl.getScore(player)
    const damageAmount = rusty_chains.attack3.damage_amount + (lvlAmount/2) * rusty_chains.damage_multiply
    //ngab
    const damage = damageAmount
    system.runTimeout(()=>{
        player.dimension.getEntities({maxDistance: 10, location: player.location, excludeTypes: ['minecraft:item','minecraft:xp_orb'], excludeFamilies: ['ld_hw']}).forEach(target=>{
            if (target===player)
                return;
            target.applyDamage(damage,{cause:'contact',damagingEntity:player})
            //DEBUG 1 //console.warn(`your damage is ${damage}`)
            try {
            target.applyKnockback(-(player.location.x - target.location.x), -(player.location.z - target.location.z),3,0.5)
            } catch (error) {
                
            }
        })
        player.runCommand(`camerashake add @a[r=5] 0.1 0.5 positional`)
        player.dimension.spawnParticle('ld_hw:whip_lash_1', {x:player.location.x + player.getViewDirection().x * parRange,y:player.location.y + 1,z:player.location.z + player.getViewDirection().z * parRange})
        player.dimension.spawnParticle('ld_hw:whip_lash_2', {x:player.location.x + player.getViewDirection().x * parRange,y:player.location.y + 1,z:player.location.z + player.getViewDirection().z * parRange})
        player.dimension.spawnParticle('ld_hw:whip_lash_3', {x:player.location.x + player.getViewDirection().x * parRange,y:player.location.y + 1,z:player.location.z + player.getViewDirection().z * parRange})
    },0.42*20)
}
function rusty_chains_Attack4Effect(player, damagingEntity){
    //Damage Positioning
    const range = 4
    const parRange = 4

    //damage var
    const levelScore = rusty_chains.level_score
    const lvl = world.scoreboard.getObjective(levelScore)
    const lvlAmount = lvl.getScore(player)
    const damageAmount = rusty_chains.attack4.damage_amount + (lvlAmount/2) * rusty_chains.damage_multiply
    //ngab
    const damage = damageAmount
    player.addEffect('resistance', rusty_chains.attack4.attackDuration * 20, {amplifier:255})
    damagingEntity.teleport(player.location, {rotation: {x: 0, y: player.getRotation().y}})
    damagingEntity.teleport({x:damagingEntity.location.x+damagingEntity.getViewDirection().x*range, y:damagingEntity.location.y, z:damagingEntity.location.z+damagingEntity.getViewDirection().z*range})

    if(world.getDynamicProperty('ld_hw.:sound')){
        system.runTimeout(()=>{
            player.runCommand(`playsound ld_hw:orchestral_riser @s`)
        })
        system.runTimeout(()=>{
            player.runCommand(`playsound ld_hw:laugh @s`)
        },3*20)
        system.runTimeout(()=>{
            player.runCommand(`playsound ld_hw:orchestral_stab @s`)
        },4.8*20)
    }
    //Camera Setup
    //runCommand(`camera @p set minecraft:free pos ^2 ^1 ^3 facing @s`) STATIC
	//runCommandAsync(`camera @p set minecraft:free ease 1.0 linear pos ^2 ^1 ^5 facing @s`) DYNAMIC
    //getEntities({excludeTypes: 'minecraft:item'})
    const dunia = world.getDimension(`overworld`)
    damagingEntity.dimension.getEntities({location: damagingEntity.location, maxDistance: 10, excludeTypes: ['minecraft:item','minecraft:xp_orb'], excludeFamilies: ['ld_hw']}).forEach(target=>{
        if (target.typeId==='minecraft:player'){
        target.addTag(`ld_hw:selected_by_${damagingEntity.id}`)
        target.addTag(`ld_hw:in_ability`)
        dunia.runCommand(`inputpermission set @a[tag=ld_hw:in_ability] camera disabled`)
        dunia.runCommand(`inputpermission set @a[tag=ld_hw:in_ability] movement disabled`)
        dunia.runCommand(`hud @a[tag=ld_hw:in_ability] hide`)
        damagingEntity.runCommand(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] fade time 0.5 ${textDelay-0.5} 0 color 64 42 24`)
        if(world.getDynamicProperty('ld_hw.:camera')){
            system.runTimeout(()=>{
                system.runTimeout(()=>{
                    damagingEntity.runCommand(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] set minecraft:free pos ^-1 ^1 ^-2 facing ${player.location.x} ${player.location.y} ${player.location.z}`)
                    damagingEntity.runCommandAsync(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] set minecraft:free ease 0.38 linear pos ^-1 ^1 ^-1 facing ${player.location.x} ${player.location.y} ${player.location.z}`)
                }, 0 * 20)
                system.runTimeout(()=>{
                    damagingEntity.runCommand(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] set minecraft:free pos ^7 ^4 ^3 facing ${damagingEntity.location.x} ${damagingEntity.location.y} ${damagingEntity.location.z}`)
                    damagingEntity.runCommandAsync(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] set minecraft:free ease 2.25 linear pos ^8 ^4 ^4 facing ${damagingEntity.location.x} ${damagingEntity.location.y} ${damagingEntity.location.z}`)
                }, 0.38 * 20)
                system.runTimeout(()=>{
                    damagingEntity.runCommand(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] set minecraft:free pos ^-3 ^0.5 ^-1 facing ${player.location.x} ${player.location.y+1} ${player.location.z}`)
                    damagingEntity.runCommandAsync(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] set minecraft:free ease 1.0 linear pos ^-5 ^1 ^-1 facing ${player.location.x} ${player.location.y+1} ${player.location.z}`)
                }, 2.75*20)
            },textDelay*20)
        }
        system.runTimeout(()=>{
            damagingEntity.runCommand(`camera @a[tag=ld_hw:selected_by_${damagingEntity.id}] clear`)
            dunia.runCommand(`inputpermission set @a[tag=ld_hw:selected_by_${damagingEntity.id}] camera enabled`)
            dunia.runCommand(`inputpermission set @a[tag=ld_hw:selected_by_${damagingEntity.id}] movement enabled`)
            dunia.runCommand(`hud @a[tag=ld_hw:selected_by_${damagingEntity.id}] reset`)
            dunia.runCommand(`tag @a[tag=ld_hw:selected_by_${damagingEntity.id}] remove ld_hw:in_ability`)
            dunia.runCommand(`tag @a[tag=ld_hw:selected_by_${damagingEntity.id}] remove ld_hw:selected_by_${damagingEntity.id}`)
            player.runCommand('scoreboard players set @s ld_hw:rusty_chains_ult 0')
            if(target===player) return
            const weapon = 'ld_hw:rusty_chains'
            ultimate_attack_jumpscare(weapon,target)
        }, (textDelay+4.75)*20)
        }
        if (target === player) return
        target.runCommand(rusty_chains.attack4.attack_translate)
        system.runTimeout(()=>{
            target.runCommand(`title @s clear`)
        },textDelay*20)
        target.addEffect('slowness', rusty_chains.attack4.attackDuration * 20, {amplifier: 255})
        system.runTimeout(()=>{
            target.dimension.spawnParticle('ld_hw:hellish_shackles_1', target.location)
            target.dimension.spawnParticle('ld_hw:hellish_shackles_2', target.location)
            target.dimension.spawnParticle('ld_hw:hellish_shackles_3', target.location)
            target.dimension.spawnParticle('ld_hw:hellish_shackles_6', target.location)
            target.runCommand(`effect @s slowness 2 255 true`)
            const damaging = system.runInterval(()=>{
                if (target.isValid()===false) return
                target.applyDamage(damage,{cause:'contact',damagingEntity:player})
            })
            system.runTimeout(()=>{
                system.clearRun(damaging)
            },3*20)
        },(textDelay+1.42)*20)
    })
    system.runTimeout(()=>{
        player.runCommand(`title @s clear`)
    },textDelay*20)
    system.runTimeout(()=>{
        system.runTimeout(()=>{
            player.dimension.spawnParticle('ld_hw:hellish_shackles_4', { x: player.location.x, y: player.location.y + 0.1, z: player.location.z})
        },0.42*20)
        system.runTimeout(()=>{
            player.runCommand(`particle ld_hw:hellish_shackles_5 ^^1^4`)
            player.runCommand(`particle ld_hw:hellish_shackles_7 ^^1^4`)
        },0.79*20)
    },(textDelay+1)*20)
}

function rusty_chains_hook(player, target, damagingEntity, damage){
    target.addTag(`ld_hw:${damagingEntity.id}`);
    // Apply damage and effects to hooked entities
    system.runTimeout(() => {
        target.applyDamage(damage, { cause: 'contact', damagingEntity: player });
        target.addEffect('slowness', 1, { amplifier: 255 });
    }, 0.42 * 20);
    system.runTimeout(()=>{
        const loc = {
            x:player.location.x+player.getViewDirection().x*-5,
            y:player.location.y,
            z:player.location.z+player.getViewDirection().z*-5
        }
        target.applyDamage(damage, { cause: 'contact', damagingEntity: player });
        target.teleport(loc);
    },1*20)
}

function ultimate_attack_jumpscare(weapon, target){
    if(world.getDynamicProperty('ld_hw.:jumpscare')==false) return
    const delay = Math.round(Math.random() * testing ? 5 : (25-10) + 10)
    const delayJumpscare = Math.round(Math.random() * (7-1) + 1)
    const range = 2
    const range2 = 3
    let jumpscare_sound = null
    let jumpscare_type = null
    let height = 2;
    switch(weapon) {
        case 'ld_hw:leaf_blower':
            jumpscare_sound = 'ld_hw:the_butcher';
            jumpscare_type = 1;
            break;
        case 'ld_hw:digital_grave':
            jumpscare_sound = 'ld_hw:the_corruptor';
            jumpscare_type = 2;
            break;
        case 'ld_hw:rusty_chains':
            jumpscare_sound = 'ld_hw:the_chain_warden';
            jumpscare_type = 3;
            break;
        case 'ld_hw:scary_lantern':
            jumpscare_sound = 'ld_hw:the_wraith_keeper';
            jumpscare_type = 4;
            height = 1;
            break;
        default:
            jumpscare_sound = null;
            jumpscare_type = 0;
            break;
    }
    system.runTimeout(()=>{
        target.runCommand(`playsound ld_hw:pre_jumpscare.${jumpscare_sound} @s`)
        target.addEffect('darkness',10*20)
        system.runTimeout(()=>{
            const loc = {x:target.location.x+target.getViewDirection().x*range,y:target.location.y,z:target.location.z+target.getViewDirection().z*range}
            const loc2 = {x:target.location.x+target.getViewDirection().x*range2,y:target.location.y,z:target.location.z+target.getViewDirection().z*range2}
            const jsEntity = target.dimension.spawnEntity('ld_hw:player_jumpscare', loc)
            target.addEffect('slowness', 1*20, {amplifier:3, showParticles:false})
            target.runCommand(`inputpermission set @s camera disabled`)
            target.runCommand(`inputpermission set @s movement disabled`)
            const facingLocation = {x:jsEntity.location.x,y:jsEntity.location.y+height,z:jsEntity.location.z}
            target.teleport(target.location, {facingLocation:facingLocation})
            // jsEntity.runCommand(`tp @s ~~~ facing ${target.location.x} ${target.location.y+1} ${target.location.z}`)
            // system.runTimeout(()=>{jsEntity.teleport(loc2)})
            jsEntity.setProperty(`ld_hw:jumpscare_type`, jumpscare_type)
            target.runCommand(`playsound ld_hw:jumpscare.${jumpscare_sound} @s`)
            system.runTimeout(()=>{
                jsEntity.dimension.spawnParticle('ld_hw:phase_shift_1',jsEntity.location)
                jsEntity.dimension.spawnParticle('ld_hw:phase_shift_2',jsEntity.location)
                jsEntity.runCommand(`playsound ld_hw:mob.the_wraith_keeper.hurt @p ~~~`)
                target.runCommand(`inputpermission set @s camera enabled`)
                target.runCommand(`inputpermission set @s movement enabled`)
                jsEntity.remove()
            },3*20)
        },2*20)
    },delay*20)
}
//TAG UTIL
function tagsUtilities(player, target, damage, duration) {
    if (target.hasTag('ld_hw:target_scary_lantern1')) {
        target.runCommand(`effect @s nausea 10 1 true`)
            target.runCommand(`effect @s slowness 10 2 true`)
            const interval = system.runInterval(()=>{
                if (target.isValid()===false)
                    return
                target.applyDamage(damage, {cause: 'contact', damagingEntity: player})
                if (!target.hasTag('ld_hw:target_scary_lantern1')) {system.clearRun(interval)}
                //DEBUG 1 //console.warn(`your damage is ${damage}`)
            }, 2 * 20)
            system.runTimeout(()=>{
                system.clearRun(interval)
                if(target.isValid()){target.removeTag('ld_hw:target_scary_lantern1')}
            }, duration * 20)
    }
    if (target.hasTag('ld_hw:target_rusty_chains1')) {
        const interval = system.runInterval(()=>{
            if (target.isValid()===false)
                return
            target.applyDamage(damage, {cause: "contact", damagingEntity: player})
            if (!target.hasTag('ld_hw:target_rusty_chains1')) {system.clearRun(interval)}
        },1.5*20)
        system.runTimeout(()=>{
            system.clearRun(interval)
            if(target.isValid()){target.removeTag('ld_hw:target_rusty_chains1')}
        },duration*20)
    }
    if (target.hasTag('ld_hw:target_digital_grave4')) {
        let ranInterval = Math.random() * (1.5-1) + 1
        const interval = system.runInterval(()=>{
            if (target.isValid()===false)return;
            target.dimension.spawnEntity(`ld_hw:glitch_mob`,target.location)
            system.runTimeout(()=>{
                if (target.isValid()===false)return;
                target.runCommand(`playsound ld_hw:effect.glitch @a ~~~`)
                target.applyDamage(damage,{cause:'contact',damagingEntity:player})
                //DEBUG 1 //console.warn(`your damage is ${damage}`)
            },0.5*20)
            ranInterval = Math.random(0,2)
            if (!target.hasTag('ld_hw:target_digital_grave4')) {system.clearRun(interval)}
        },ranInterval*20)
        system.runTimeout(()=>{
            system.clearRun(interval)
            if(target.isValid()){target.removeTag('ld_hw:target_digital_grave4')}
        },duration*20)
        if(target.isValid()===false){system.clearRun(interval)}
    }
    if (target.hasTag('ld_hw:target_scary_lantern4')) {
        let ranInterval = Math.random() * (1-0.5) + 0.5
        let pitch = Math.random() * (2-0.5) + 0.5
        const interval = system.runInterval(()=>{
            if (target.isValid()===false)return;
            const spirit = target.dimension.spawnEntity(`ld_hw:spirit2`,target.location)
            spirit.runCommand(`playsound ld_hw:effect.scream @a ~~~ 1 ${pitch}`)
            pitch = Math.random() * (2-0.5) + 0.5
            ranInterval = Math.random() * (1-0.5) + 0.5
            system.runTimeout(()=>{
                if(!target.isValid())return
                target.applyDamage(damage,{cause:'contact',damagingEntity:player})
                //DEBUG 1 //console.warn(`your damage is ${damage}`)
            },1.5*20)
            if (!target.hasTag('ld_hw:target_scary_lantern4')) {system.clearRun(interval)}
        },ranInterval*20)
        system.runTimeout(()=>{
            system.clearRun(interval)
            if(target.isValid()){target.removeTag('ld_hw:target_scary_lantern4')}
        },duration*20)
        if(target.isValid()===false){system.clearRun(interval)}
    }
}
function infection(subject,player,damage){
    ////console.warn(player.name)
    if(!subject.hasTag('ld_hw:infected'))return
    subject.addTag(subject.id)
    subject.setDynamicProperty('ld_hw:infector', player.name)
    const findVictim = system.runInterval(()=>{
        if(!subject.isValid()||!subject.hasTag('ld_hw:infected')) {
            system.clearRun(findVictim)
            system.clearRun(particle)
            system.clearRun(text)
            system.clearRun(heightControl)
            return
        }
        ////console.warn('Finding Victim')
        const victims = subject.dimension.getEntities({closest:1,location:subject.location, excludeTypes: ['minecraft:item','minecraft:xp_orb'],excludeFamilies:['ld_hw'],excludeTags:[subject.id],excludeNames:[player.name]})
        if(victims.length > 0){
            system.clearRun(findVictim)
            const chaseVictim = system.runInterval(()=>{
                if(!subject.isValid()) return
                victims.forEach(victim=>{
                    if(!victim.isValid() || victim==player){
                        system.clearRun(chaseVictim)
                        system.clearRun(particle)
                        system.clearRun(text)
                        system.clearRun(heightControl)
                        infection(subject,player,damage)
                        return
                    }
                    if(!subject.hasTag('ld_hw:infected')){
                        system.clearRun(chaseVictim)
                        system.clearRun(particle)
                        system.clearRun(text)
                        system.clearRun(heightControl)
                        return
                    }
                    ////console.warn("Victim found: "+victim.typeId)
                    const speed = 0.3
                    const move = {x:subject.location.x+subject.getViewDirection().x*speed,y:subject.location.y,z:subject.location.z+subject.getViewDirection().z*speed}
                    //GETBLOCK
                    // const currentBlock = subject.dimension.getBlock(subject.location);
                    // // Check if the block is not air, meaning the subject is standing on a solid block
                    // if (!currentBlock.isAir) {
                    //     // Teleport subject up by 1 block
                    //     subject.teleport({x: subject.location.x, y: subject.location.y + 1, z: subject.location.z}, {facingLocation: victim.location, checkForBlocks: false});
                    // } else {
                    //     // Teleport subject down by 1 block (since it's air)
                    //     subject.teleport({x: subject.location.x, y: subject.location.y - 1, z: subject.location.z}, {facingLocation: victim.location, checkForBlocks: true});
                    // }
                    
                    if(checkDistance(subject,victim)<2){
                    victim.applyDamage(damage,{cause:'contact',damagingEntity:subject});
                    if(!victim.hasTag('ld_hw:infected')){
                        //console.warn('infected')
                        victim.addTag('ld_hw:infected')
                        infection(victim,player,damage)
                    }} else {
                        subject.teleport(move,{facingLocation:victim.location,checkForBlocks:true})
                        //subject.runCommandAsync(`tp @s ^^^${speed} facing ${victim.location.x} ${victim.location.y+1} ${victim.location.z}`)
                    }
                })
            })
        }
    })
    const particle = system.runInterval(()=>{
        if(!subject.isValid())return
        try {
            const loc = {x:subject.location.x,y:subject.location.y+1,z:subject.location.z}
            subject.dimension.spawnParticle(`ld_hw:corrupted_energy_4`, loc)
        } catch (error) {
            
        }
    },1*20)
    const text = system.runInterval(()=>{
        if(!subject.isValid())return
        try {
            subject.runCommand(`title @s title §k0100010101001001010101`)
            subject.runCommand(`title @s subtitle §4CONTROL ERROR`)
            subject.runCommand(`title @s actionbar §4You are infected!`)
        } catch (error) {
            
        }
    },2*20)
    const heightControl = system.runInterval(()=>{
        if(!subject.isValid()) return
        try {
            const currentBlock = subject.dimension.getBlock(subject.location);
            if (!currentBlock.isAir) {
                subject.teleport({x: subject.location.x, y: subject.location.y + 0.1, z: subject.location.z}, {checkForBlocks: false});
            } else if (currentBlock.isAir) {
                subject.teleport({x: subject.location.x, y: subject.location.y - 0.1, z: subject.location.z}, {checkForBlocks: true});
            }
        } catch (error) {
            
        }
    })
    system.runTimeout(()=>{
        if(!subject.isValid())return
        subject.removeTag('ld_hw:infected')
    },10*20)
}
world.afterEvents.worldInitialize.subscribe((arg)=>{
    world.getDimension('overworld').runCommand(`scoreboard objectives add ld_hw:scary_lantern_cd dummy`)
    world.getDimension('overworld').runCommand(`scoreboard objectives add ld_hw:scary_lantern_lvl dummy`)
    world.getDimension('overworld').runCommand(`scoreboard objectives add ld_hw:scary_lantern_exp dummy`)
    world.getDimension('overworld').runCommand(`scoreboard objectives add ld_hw:scary_lantern_ult dummy`)
    
    world.getDimension('overworld').runCommand(`scoreboard objectives add ld_hw:digital_grave_cd dummy`)
    world.getDimension('overworld').runCommand(`scoreboard objectives add ld_hw:digital_grave_lvl dummy`)
    world.getDimension('overworld').runCommand(`scoreboard objectives add ld_hw:digital_grave_exp dummy`)
    world.getDimension('overworld').runCommand(`scoreboard objectives add ld_hw:digital_grave_ult dummy`)
    
    world.getDimension('overworld').runCommand(`scoreboard objectives add ld_hw:leaf_blower_cd dummy`)
    world.getDimension('overworld').runCommand(`scoreboard objectives add ld_hw:leaf_blower_lvl dummy`)
    world.getDimension('overworld').runCommand(`scoreboard objectives add ld_hw:leaf_blower_exp dummy`)
    world.getDimension('overworld').runCommand(`scoreboard objectives add ld_hw:leaf_blower_ult dummy`)
    
    world.getDimension('overworld').runCommand(`scoreboard objectives add ld_hw:rusty_chains_cd dummy`)
    world.getDimension('overworld').runCommand(`scoreboard objectives add ld_hw:rusty_chains_lvl dummy`)
    world.getDimension('overworld').runCommand(`scoreboard objectives add ld_hw:rusty_chains_exp dummy`)
    world.getDimension('overworld').runCommand(`scoreboard objectives add ld_hw:rusty_chains_ult dummy`)

    world.getDimension('overworld').getEntities({families: ['ld_hw:mob']}).forEach(mob=>{
        mob.triggerEvent("ld_hw:remove_attack")
        mob.setProperty('ld_hw:jumpscare', false)
    })
})
const weapons = [
    'ld_hw:leaf_blower',
    'ld_hw:digital_grave',
    'ld_hw:rusty_chains',
    'ld_hw:scary_lantern'
]
world.afterEvents.playerSpawn.subscribe((arg)=>{
    weapons.forEach(weapon=>{
        arg.player.runCommand(`scoreboard players set @s[tag=!ld_hw] ${weapon}_cd 0`)
        arg.player.runCommand(`scoreboard players set @s[tag=!ld_hw] ${weapon}_lvl 1`)
        arg.player.runCommand(`scoreboard players set @s[tag=!ld_hw] ${weapon}_exp 0`)
        arg.player.runCommand(`scoreboard players set @s[tag=!ld_hw] ${weapon}_ult 0`)
        arg.player.runCommand(`give @s[tag=!ld_hw, hasitem={item=ld_hw:start_book, quantity=0}] ld_hw:start_book`)
    })
    arg.player.runCommand(`tag @s[tag=!ld_hw] add ld_hw`)
    arg.player.setDynamicProperty('ld_hw:night_js_available', true)
    arg.player.runCommand(`inputpermission set @s camera enabled`)
    arg.player.runCommand(`inputpermission set @s movement enabled`)
    arg.player.runCommand(`camera @s clear`)
    arg.player.runCommand(`hud @s reset`)
    arg.player.removeTag('ld_hw:hooked')
    arg.player.removeTag('ld_hw:rusty')
    arg.player.removeTag('ld_hw:butcher_hooked')
    arg.player.removeTag('ld_hw:chain_hooked')
    arg.player.removeTag('ld_hw:infected')
    arg.player.removeTag('ld_hw:madness')
    if(arg.player.hasTag('ld_hw:infected')) {
        ////console.warn(`STILL INFECTED`)
    } else {
        ////console.warn(`NO LONGER INFECTED`)
    }
    arg.player.setDynamicProperty('ld_hw:jumpscare_delay',0)
})
const bannedItems = [
    'ld_hw:leaf_blower_skill1',
    'ld_hw:leaf_blower_skill2',
    'ld_hw:leaf_blower_skill3',
    'ld_hw:leaf_blower_skill4',
    
    'ld_hw:scary_lantern_skill1',
    'ld_hw:scary_lantern_skill2',
    'ld_hw:scary_lantern_skill3',
    'ld_hw:scary_lantern_skill4',

    'ld_hw:digital_grave_skill1',
    'ld_hw:digital_grave_skill2',
    'ld_hw:digital_grave_skill3',
    'ld_hw:digital_grave_skill4',
    
    'ld_hw:rusty_chains_skill1',
    'ld_hw:rusty_chains_skill2',
    'ld_hw:rusty_chains_skill3',
    'ld_hw:rusty_chains_skill4'
];
system.runInterval(() => {
    world.getPlayers().forEach(player => {
        if (!player.hasTag('ld_hw:using_ability')) {
            bannedItems.forEach(item => {
                const bannedItem = getItemOnInventory(player, item);
                if (bannedItem) {
                    // Remove the banned item from the player's inventory
                    const inventory = player.getComponent("minecraft:inventory");
                    inventory.container.setItem(bannedItem.slot, new ItemStack(`${item.split("_skill")[0]}`)); // Set the slot to null
                }
            });
        }
    });
});

//LEVELING SYSTEMinventory
let defaultEXP = 10;
const attackTypeId = [
    'ld_hw:scary_lantern_attack1',
    'ld_hw:scary_lantern_attack2',
    'ld_hw:scary_lantern_attack3',
    'ld_hw:scary_lantern_attack4',
    
    'ld_hw:digital_grave_attack1',
    'ld_hw:digital_grave_attack2',
    'ld_hw:digital_grave_attack3',
    'ld_hw:digital_grave_attack4',
    
    'ld_hw:leaf_blower_attack1',
    'ld_hw:leaf_blower_attack2',
    'ld_hw:leaf_blower_attack3',
    'ld_hw:leaf_blower_attack4',
    
    'ld_hw:rusty_chains_attack1',
    'ld_hw:rusty_chains_attack2',
    'ld_hw:rusty_chains_attack3',
    'ld_hw:rusty_chains_attack4'
];
const entitiesTypes = [
    {
        entities: new Set([
            "minecraft:cave_spider",
            "minecraft:drowned",
            "minecraft:endermite",
            "minecraft:husk",
            "minecraft:magma_cube",
            "minecraft:silverfish",
            "minecraft:skeleton",
            "minecraft:slime",
            "minecraft:spider",
            "minecraft:stray",
            "minecraft:zombie",
            "minecraft:zombie_pigman",
            "minecraft:zombie_villager",
            "minecraft:zombie_villager_v2"
        ]),
        xp: 1
    },
    {
        entities: new Set([
            "minecraft:blaze",
            "minecraft:creeper",
            "minecraft:enderman",
            "minecraft:ghast",
            "minecraft:hoglin",
            "minecraft:phantom",
            "minecraft:shulker",
            "minecraft:guardian",
            "minecraft:vex",
            "minecraft:zoglin"
        ]),
        xp: 3
    },
    {
        entities: new Set([
            "minecraft:evocation_illager",
            "minecraft:piglin",
            "minecraft:piglin_brute",
            "minecraft:pillager",
            "minecraft:ravager",
            "minecraft:vindicator",
            "minecraft:witch",
            "minecraft:wither_skeleton",
            "minecraft:elder_guardian"
        ]),
        xp: 4
    },
    { 
        entities: new Set([ 
        ]),
        xp: 50
    },
    { 
        entities: new Set([
            "minecraft:ender_dragon",
            "minecraft:wither",
            "minecraft:warden"
        ]),
        xp: 150
    }
];
world.afterEvents.entityDie.subscribe((arg) => {
    const killer = arg.damageSource.damagingEntity
    const victim = arg.deadEntity
    //DEBUG 1 //console.warn('ada yang modar')
    entitiesTypes.forEach(entityType => {
        try {
        if (entityType.entities.has(victim.typeId) && killer.typeId==='minecraft:player') {
        //DEBUG 1 //console.warn(`MASOK PAK EKOOO (${entityType.xp})`)
        const scary_lantern_item = [
            'ld_hw:scary_lantern',
            'ld_hw:scary_lantern_skill1',
            'ld_hw:scary_lantern_skill2',
            'ld_hw:scary_lantern_skill3',
            'ld_hw:scary_lantern_skill4'
        ];
        const digital_grave_item = [
            'ld_hw:digital_grave',
            'ld_hw:digital_grave_skill1',
            'ld_hw:digital_grave_skill2',
            'ld_hw:digital_grave_skill3',
            'ld_hw:digital_grave_skill4'
        ];
        const leaf_blower_item = [
            'ld_hw:leaf_blower',
            'ld_hw:leaf_blower_skill1',
            'ld_hw:leaf_blower_skill2',
            'ld_hw:leaf_blower_skill3',
            'ld_hw:leaf_blower_skill4'
        ];
        const rusty_chains_item = [
            'ld_hw:rusty_chains',
            'ld_hw:rusty_chains_skill1',
            'ld_hw:rusty_chains_skill2',
            'ld_hw:rusty_chains_skill3',
            'ld_hw:rusty_chains_skill4'
        ];
        if (leaf_blower_item.some(item => checkItemInMainHand(killer, item))){
            const lvl = world.scoreboard.getObjective('ld_hw:leaf_blower_lvl')
            const ult = world.scoreboard.getObjective('ld_hw:leaf_blower_ult')
            //DEBUG 1 //console.warn('MEGANG GERGAJI')
            if(lvl.getScore(killer) <10 ){
            world.getDynamicProperty("ld_hw.:boost_time") > 0
            ? killer.runCommandAsync(`scoreboard players add @s ld_hw:leaf_blower_exp ${entityType.xp * 2}`)
            : killer.runCommandAsync(`scoreboard players add @s ld_hw:leaf_blower_exp ${entityType.xp}`)}
            if (lvl.getScore(killer) >= 5 && ult.getScore(killer) < 10) {
                killer.runCommandAsync(`scoreboard players add @s ld_hw:leaf_blower_ult 1`)
            } 
            system.runTimeout(()=>{
                const player = killer
                const lvl = world.scoreboard.getObjective('ld_hw:leaf_blower_lvl')
                const exp = world.scoreboard.getObjective('ld_hw:leaf_blower_exp')
                const ult = world.scoreboard.getObjective('ld_hw:leaf_blower_ult')
                const xpl = defaultEXP * (lvl.getScore(player)) * 0.8
                if (exp.getScore(player) >= xpl) 
                    {levelUp(player,lvl,exp)}
                const ultBar = `§a${'|'.repeat(ult.getScore(player))}§c${'|'.repeat(10 - ult.getScore(player))}`
                const actionBarText = `{
                    "rawtext": [
                        { "translate": "actionbar.ld_hw.weapon.lvl" },
                        { "text": "${lvl.getScore(player)}" },
                        { "text": "\n" }
                        `+
                        (lvl.getScore(player)<10
                        ? `, { "translate": "actionbar.ld_hw.weapon.exp" },
                        { "text": "${exp.getScore(player)}/${xpl}" },
                        { "text": "\n" }`
                        : '')
                        +
                        (lvl.getScore(player) >= 5 && ult.getScore(player) < 10
                        ? `, { "text": "\n" },
                        { "translate": "actionbar.ld_hw.weapon.ult" },
                        { "text": "${ultBar}" }`
                        : lvl.getScore(player) >= 5 && ult.getScore(player) >= 10
                        ? `, { "text": "\n" },
                        { "translate": "actionbar.ld_hw.weapon.ult_full" },
                        { "text": "\n" }`
                        : '')+
                        `
                    ]
                }`
                player.runCommand(`titleraw @s actionbar ${actionBarText}`)
            }, 0.5 * 20)
        }
        if (digital_grave_item.some(item => checkItemInMainHand(killer, item))){
            const lvl = world.scoreboard.getObjective('ld_hw:digital_grave_lvl')
            const ult = world.scoreboard.getObjective('ld_hw:digital_grave_ult')
            //DEBUG 1 //console.warn('MEGANG KUBURAN')
            if(lvl.getScore(killer) <10 ){
            world.getDynamicProperty("ld_hw.:boost_time") > 0
            ? killer.runCommandAsync(`scoreboard players add @s ld_hw:digital_grave_exp ${entityType.xp * 2}`)
            : killer.runCommandAsync(`scoreboard players add @s ld_hw:digital_grave_exp ${entityType.xp}`)}
            if (lvl.getScore(killer) >= 5 && ult.getScore(killer) < 10) {
                killer.runCommandAsync(`scoreboard players add @s ld_hw:digital_grave_ult 1`)
            } 
            system.runTimeout(()=>{
                const player = killer
                const lvl = world.scoreboard.getObjective('ld_hw:digital_grave_lvl')
                const exp = world.scoreboard.getObjective('ld_hw:digital_grave_exp')
                const ult = world.scoreboard.getObjective('ld_hw:digital_grave_ult')
                const xpl = defaultEXP * (lvl.getScore(player)) * 0.8
                if (exp.getScore(player) >= xpl) 
                    {levelUp(player,lvl,exp)}
                const ultBar = `§a${'|'.repeat(ult.getScore(player))}§c${'|'.repeat(10 - ult.getScore(player))}`
                const actionBarText = `{
                    "rawtext": [
                        { "translate": "actionbar.ld_hw.weapon.lvl" },
                        { "text": "${lvl.getScore(player)}" },
                        { "text": "\n" }
                        `+
                        (lvl.getScore(player)<10
                        ? `, { "translate": "actionbar.ld_hw.weapon.exp" },
                        { "text": "${exp.getScore(player)}/${xpl}" },
                        { "text": "\n" }`
                        : '')
                        +
                        (lvl.getScore(player) >= 5 && ult.getScore(player) < 10
                        ? `, { "text": "\n" },
                        { "translate": "actionbar.ld_hw.weapon.ult" },
                        { "text": "${ultBar}" }`
                        : lvl.getScore(player) >= 5 && ult.getScore(player) >= 10
                        ? `, { "text": "\n" },
                        { "translate": "actionbar.ld_hw.weapon.ult_full" },
                        { "text": "\n" }`
                        : '')+
                        `
                    ]
                }`
                player.runCommand(`titleraw @s actionbar ${actionBarText}`)
            }, 0.5 * 20)
        }
        if (rusty_chains_item.some(item => checkItemInMainHand(killer, item))){
            const lvl = world.scoreboard.getObjective('ld_hw:rusty_chains_lvl')
            const ult = world.scoreboard.getObjective('ld_hw:rusty_chains_ult')
            //DEBUG 1 //console.warn('MEGANG RANTE')
            if(lvl.getScore(killer) <10 ){
            world.getDynamicProperty("ld_hw.:boost_time") > 0
            ? killer.runCommandAsync(`scoreboard players add @s ld_hw:rusty_chains_exp ${entityType.xp * 2}`)
            : killer.runCommandAsync(`scoreboard players add @s ld_hw:rusty_chains_exp ${entityType.xp}`)}
            if (lvl.getScore(killer) >= 5 && ult.getScore(killer) < 10) {
                killer.runCommandAsync(`scoreboard players add @s ld_hw:rusty_chains_ult 1`)
            } 
            system.runTimeout(()=>{
                const player = killer
                const lvl = world.scoreboard.getObjective('ld_hw:rusty_chains_lvl')
                const exp = world.scoreboard.getObjective('ld_hw:rusty_chains_exp')
                const ult = world.scoreboard.getObjective('ld_hw:rusty_chains_ult')
                const xpl = defaultEXP * (lvl.getScore(player)) * 0.8
                if (exp.getScore(player) >= xpl) 
                    {levelUp(player,lvl,exp)}
                const ultBar = `§a${'|'.repeat(ult.getScore(player))}§c${'|'.repeat(10 - ult.getScore(player))}`
                const actionBarText = `{
                    "rawtext": [
                        { "translate": "actionbar.ld_hw.weapon.lvl" },
                        { "text": "${lvl.getScore(player)}" },
                        { "text": "\n" }
                        `+
                        (lvl.getScore(player)<10
                        ? `, { "translate": "actionbar.ld_hw.weapon.exp" },
                        { "text": "${exp.getScore(player)}/${xpl}" },
                        { "text": "\n" }`
                        : '')
                        +
                        (lvl.getScore(player) >= 5 && ult.getScore(player) < 10
                        ? `, { "text": "\n" },
                        { "translate": "actionbar.ld_hw.weapon.ult" },
                        { "text": "${ultBar}" }`
                        : lvl.getScore(player) >= 5 && ult.getScore(player) >= 10
                        ? `, { "text": "\n" },
                        { "translate": "actionbar.ld_hw.weapon.ult_full" },
                        { "text": "\n" }`
                        : '')+
                        `
                    ]
                }`
                player.runCommand(`titleraw @s actionbar ${actionBarText}`)
            }, 0.5 * 20)
        }
        if (scary_lantern_item.some(item => checkItemInMainHand(killer, item))){
            const lvl = world.scoreboard.getObjective('ld_hw:scary_lantern_lvl')
            const ult = world.scoreboard.getObjective('ld_hw:scary_lantern_ult')
            //DEBUG 1 //console.warn('MEGANG LAMPU')
            if(lvl.getScore(killer) <10 ){
            world.getDynamicProperty("ld_hw.:boost_time") > 0
            ? killer.runCommandAsync(`scoreboard players add @s ld_hw:scary_lantern_exp ${entityType.xp * 2}`)
            : killer.runCommandAsync(`scoreboard players add @s ld_hw:scary_lantern_exp ${entityType.xp}`)}
            if (lvl.getScore(killer) >= 5 && ult.getScore(killer) < 10) {
                killer.runCommandAsync(`scoreboard players add @s ld_hw:scary_lantern_ult 1`)
            } 
            system.runTimeout(()=>{
                const player = killer
                const lvl = world.scoreboard.getObjective('ld_hw:scary_lantern_lvl')
                const exp = world.scoreboard.getObjective('ld_hw:scary_lantern_exp')
                const ult = world.scoreboard.getObjective('ld_hw:scary_lantern_ult')
                const xpl = defaultEXP * (lvl.getScore(player)) * 0.8
                if (exp.getScore(player) >= xpl) 
                    {levelUp(player,lvl,exp)}
                const ultBar = `§a${'|'.repeat(ult.getScore(player))}§c${'|'.repeat(10 - ult.getScore(player))}`
                const actionBarText = `{
                    "rawtext": [
                        { "translate": "actionbar.ld_hw.weapon.lvl" },
                        { "text": "${lvl.getScore(player)}" },
                        { "text": "\n" }
                        `+
                        (lvl.getScore(player)<10
                        ? `, { "translate": "actionbar.ld_hw.weapon.exp" },
                        { "text": "${exp.getScore(player)}/${xpl}" },
                        { "text": "\n" }`
                        : '')
                        +
                        (lvl.getScore(player) >= 5 && ult.getScore(player) < 10
                        ? `, { "text": "\n" },
                        { "translate": "actionbar.ld_hw.weapon.ult" },
                        { "text": "${ultBar}" }`
                        : lvl.getScore(player) >= 5 && ult.getScore(player) >= 10
                        ? `, { "text": "\n" },
                        { "translate": "actionbar.ld_hw.weapon.ult_full" },
                        { "text": "\n" }`
                        : '')+
                        `
                    ]
                }`
                player.runCommand(`titleraw @s actionbar ${actionBarText}`)
            }, 0.5 * 20)
        }
        }
        } catch (error) {

        }
    })
    entitiesTypes.forEach(entityType=>{
        try {
        if(entityType.entities.has(victim.typeId) && victim.hasTag('ld_hw:infected')){
            //console.warn('VICTIM IS INFECTED')
            const infector = victim.getDynamicProperty('ld_hw:infector')
            //console.warn(`the infector is ${infector}`)
            world.getPlayers().forEach(player=>{
                if(player.name===infector){
                    //console.warn('THE INFECTOR IS FOUND!!')
                    const digital_grave_item = [
                        'ld_hw:digital_grave',
                        'ld_hw:digital_grave_skill1',
                        'ld_hw:digital_grave_skill2',
                        'ld_hw:digital_grave_skill3'
                    ];
                    if (digital_grave_item.some(item => checkItemInMainHand(player, item))){
                        const lvl = world.scoreboard.getObjective('ld_hw:digital_grave_lvl')
                        const ult = world.scoreboard.getObjective('ld_hw:digital_grave_ult')
                        //DEBUG 1 //console.warn('MEGANG KUBURAN')
                        if(lvl.getScore(player) <10 ){
                        world.getDynamicProperty("ld_hw.:boost_time") > 0
                        ? player.runCommandAsync(`scoreboard players add @s ld_hw:digital_grave_exp ${entityType.xp * 2}`)
                        : player.runCommandAsync(`scoreboard players add @s ld_hw:digital_grave_exp ${entityType.xp}`)}
                        if (lvl.getScore(player) >= 5 && ult.getScore(player) < 10) {
                            player.runCommandAsync(`scoreboard players add @s ld_hw:digital_grave_ult 1`)
                        } 
                        system.runTimeout(()=>{
                            
                            const lvl = world.scoreboard.getObjective('ld_hw:digital_grave_lvl')
                            const exp = world.scoreboard.getObjective('ld_hw:digital_grave_exp')
                            const ult = world.scoreboard.getObjective('ld_hw:digital_grave_ult')
                            const xpl = defaultEXP * (lvl.getScore(player)) * 0.8
                            if (exp.getScore(player) >= xpl) 
                                {levelUp(player,lvl,exp)}
                            const ultBar = `§a${'|'.repeat(ult.getScore(player))}§c${'|'.repeat(10 - ult.getScore(player))}`
                            const actionBarText = `{
                                "rawtext": [
                                    { "translate": "actionbar.ld_hw.weapon.lvl" },
                                    { "text": "${lvl.getScore(player)}" },
                                    { "text": "\n" }
                                    `+
                                    (lvl.getScore(player)<10
                                    ? `, { "translate": "actionbar.ld_hw.weapon.exp" },
                                    { "text": "${exp.getScore(player)}/${xpl}" },
                                    { "text": "\n" }`
                                    : '')
                                    +
                                    (lvl.getScore(player) >= 5 && ult.getScore(player) < 10
                                    ? `, { "text": "\n" },
                                    { "translate": "actionbar.ld_hw.weapon.ult" },
                                    { "text": "${ultBar}" }`
                                    : lvl.getScore(player) >= 5 && ult.getScore(player) >= 10
                                    ? `, { "text": "\n" },
                                    { "translate": "actionbar.ld_hw.weapon.ult_full" },
                                    { "text": "\n" }`
                                    : '')+
                                    `
                                ]
                            }`
                            player.runCommand(`titleraw @s actionbar ${actionBarText}`)
                        }, 0.5 * 20)
                    }
                }
            })
        }
        } catch (error) {
            
        }
    })
    const rmTag = [
        'ld_hw:target_scary_lantern1',
        'ld_hw:target_rusty_chains1',
        'ld_hw:target_digital_grave4',
        'ld_hw:target_scary_lantern4',
        "ld_hw:infected",
        "ld_hw:chainsaw_frenzy",
        "ld_hw:grind_through"
    ];
    rmTag.forEach(tag => {
        try {
            if (victim.hasTag(tag)) {
                victim.removeTag(tag);
            }
        } catch (error) {
            
        }
    });
    
    
});
world.afterEvents.playerSpawn.subscribe((arg)=>{
    const player = arg.player
    player.removeTag('ld_hw:using_ability')
    if (player.hasTag('ld_hw:reboot')){
        const healthSaved = player.getDynamicProperty('ld_hw:health_saved')
        const spawnLoc = {x:player.getDynamicProperty('ld_hw:reboot_x'),y:player.getDynamicProperty('ld_hw:reboot_y'),z:player.getDynamicProperty('ld_hw:reboot_z')}
        player.getComponent('minecraft:health').setCurrentValue(healthSaved)
        player.teleport(spawnLoc)
        const v3 = {x: player.location.x, y: player.location.y + 0.1, z: player.location.z}
        player.dimension.spawnParticle('ld_hw:error_reboot_1', v3)
        player.dimension.spawnParticle('ld_hw:error_reboot_2', v3)
        player.dimension.spawnParticle('ld_hw:error_reboot_3', v3)
        player.removeTag('ld_hw:reboot')
    }
})
function levelUp(player,lvl,exp){
    lvl.addScore(player,1)
    exp.setScore(player,0)
}
//TICK MANAGEMENT
system.runInterval(()=>{
    world.getPlayers().forEach(player=>{
        if (player.getDynamicProperty('ld_hw:jumpscare_delay') > 0) {player.setDynamicProperty('ld_hw:jumpscare_delay', player.getDynamicProperty('ld_hw:jumpscare_delay')-1)}
        ////console.warn(`${player.getDynamicProperty('ld_hw:jumpscare_delay')}`)
        player.runCommand(`scoreboard players remove @s[scores={ld_hw:prototype_cd=1..}]         ld_hw:prototype_cd 1`)
        player.runCommand(`scoreboard players remove @s[scores={ld_hw:scary_lantern_cd=1..}]     ld_hw:scary_lantern_cd 1`)
        player.runCommand(`scoreboard players remove @s[scores={ld_hw:digital_grave_cd=1..}]     ld_hw:digital_grave_cd 1`)
        player.runCommand(`scoreboard players remove @s[scores={ld_hw:leaf_blower_cd=1..}]   ld_hw:leaf_blower_cd 1`)
        player.runCommand(`scoreboard players remove @s[scores={ld_hw:rusty_chains_cd=1..}]      ld_hw:rusty_chains_cd 1`)

        // player.runCommand(`titleraw @s[scores={ld_hw:scary_lantern_cd=1..}] actionbar {"rawtext":[{"text":"§9Cooldown: "}, {"score":{"name":"@s","objective":"ld_hw:scary_lantern_cd"}}]}`)
        // player.runCommand(`titleraw @s[scores={ld_hw:digital_grave_cd=1..}] actionbar {"rawtext":[{"text":"§9Cooldown: "}, {"score":{"name":"@s","objective":"ld_hw:digital_grave_cd"}}]}`)
        // player.runCommand(`titleraw @s[scores={ld_hw:leaf_blower_cd=1..}] actionbar {"rawtext":[{"text":"§9Cooldown: "}, {"score":{"name":"@s","objective":"ld_hw:leaf_blower_cd"}}]}`)
        // player.runCommand(`titleraw @s[scores={ld_hw:rusty_chains_cd=1..}] actionbar {"rawtext":[{"text":"§9Cooldown: "}, {"score":{"name":"@s","objective":"ld_hw:rusty_chains_cd"}}]}`)
    })
    world.getDimension('overworld').getEntities().forEach(entity=>{
        entity.runCommand(`scoreboard players remove @s[scores={ld_hw:rusty=1..}] ld_hw:rusty 1`)
    })
}, 1*20)
system.runTimeout(()=>{
    system.runInterval(() => {
        world.getPlayers().forEach(player => {
            weaponsAndSounds.forEach(weapon => {
                try {
                const itemName = `ld_hw:${weapon.name}`;
                const itemBuff = `${itemName}_buff`;
                const lvl = world.scoreboard.getObjective(`${itemName}_lvl`);
                const exp = world.scoreboard.getObjective(`${itemName}_exp`);
                const ult = world.scoreboard.getObjective(`${itemName}_ult`);
                const xpl = defaultEXP * (lvl.getScore(player)) * 0.8;
    
                if (checkItemInMainHand(player, itemName) || checkItemInMainHand(player, itemBuff)) {
                    if (ult.getScore(player) > 10) { ult.setScore(player, 10); }
                    const ultBar = `§a${'|'.repeat(ult.getScore(player))}§c${'|'.repeat(10 - ult.getScore(player))}`;
                    const actionBarText = `{
                        "rawtext": [
                            { "translate": "actionbar.ld_hw.weapon.lvl" },
                            { "text": "(${lvl.getScore(player)}) " }
                            ` +
                            (lvl.getScore(player) < 10
                                ? `,
                                { "text": "& " },
                                { "translate": "actionbar.ld_hw.weapon.exp" },
                                { "text": "(${exp.getScore(player)}/${xpl})" }`
                                : '') +
                            (lvl.getScore(player) >= 5 && ult.getScore(player) < 10
                                ? `,
                                { "text": "\n" },
                                { "translate": "actionbar.ld_hw.weapon.ult" },
                                { "text": "${ultBar}" }`
                                : lvl.getScore(player) >= 5 && ult.getScore(player) >= 10
                                    ? `,
                                    { "text": "\n" },
                                    { "translate": "actionbar.ld_hw.weapon.ult_full" }`
                                    : '') +
                            `
                        ]
                    }`;
                    player.runCommand(`titleraw @s[tag=!${itemName}_data] actionbar ${actionBarText}`);
                    if (world.getDynamicProperty('ld_hw.:sound')) {
                        player.runCommand(`playsound ${weapon.sound} @s[tag=!${itemName}_data]`);
                    }
                    player.addTag(`${itemName}_data`);
                } else {
                    player.removeTag(`${itemName}_data`);
                }
                } catch (error) {
                    
                }
            });
        });
    
        world.getDimension('overworld').getEntities({ families: ['ld_hw:mob'] }).forEach(mob => {
            if (world.getDynamicProperty('ld_hw.:sound') == true && mob.getProperty('ld_hw:sound') == false) {
                mob.setProperty('ld_hw:sound', true);
            } else if (world.getDynamicProperty('ld_hw.:sound') == false && mob.getProperty('ld_hw:sound') == true) {
                mob.setProperty('ld_hw:sound', false);
            }
        });
    });
},1*20)
const weaponsAndSounds = [
    { name: 'leaf_blower', sound: 'ld_hw:weapon.chainsaw_hold' },
    { name: 'digital_grave', sound: 'ld_hw:weapon.digital_grave_hold' },
    { name: 'rusty_chains', sound: 'ld_hw:weapon.rusty_chains_hold' },
    { name: 'scary_lantern', sound: 'ld_hw:weapon.scary_lantern_hold' },
];
//Controller
world.afterEvents.itemUse.subscribe((arg) => {
    const player = arg.source;
    const item = arg.itemStack;
    // Creepy Chainsaw
    if ((item.typeId === 'ld_hw:leaf_blower')) {
        const levelScore = leaf_blower.level_score;
        const lvl = world.scoreboard.getObjective(levelScore);
        const lvlAmount = lvl.getScore(player);

        const ultScore = world.scoreboard.getObjective('ld_hw:leaf_blower_ult')
        const ult = ultScore.getScore(player)
        const cooldown_score = leaf_blower.cooldown_score;
        const selected_data = leaf_blower;
        let currentWeapon = null;
        const weaponNum = 1
        let itemTypeId = item.typeId
        {
            if (player.isOnGround && !player.isSneaking) {
                currentWeapon = leaf_blower.attack1;
                attacking(player, currentWeapon, null, cooldown_score, itemTypeId, selected_data, weaponNum);
            } else if (player.isOnGround && player.isSneaking) {
                if (lvlAmount >= 2) {
                    currentWeapon = leaf_blower.attack2;
                    attacking(player, currentWeapon, null, cooldown_score, itemTypeId, selected_data, weaponNum);
                } else {
                    player.playSound("note.bass")
                    player.runCommand(`titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw.weapon.skill2"},{"text":"${leaf_blower.attack2.attack_name}"}]}`);
                }
            } else if (!player.isOnGround && !player.isSneaking) {
                if (lvlAmount >= 3) {
                    currentWeapon = leaf_blower.attack3;
                    attacking(player, currentWeapon, null, cooldown_score, itemTypeId, selected_data, weaponNum);
                } else {
                    player.playSound("note.bass")
                    player.runCommand(`titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw.weapon.skill3"},{"text":"${leaf_blower.attack3.attack_name}"}]}`);
                }
            } else if (!player.isOnGround && player.isSneaking) {
                if (lvlAmount >= 5) {
                    if (ult >= 10) {
                        currentWeapon = leaf_blower.attack4;
                        attacking(player, currentWeapon, null, cooldown_score, itemTypeId, selected_data, weaponNum);
                    } else {
                    player.playSound("note.bass")
                        player.runCommand(`titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw.weapon.ult_failed"}]}`);
                    }
                } else {
                    player.playSound("note.bass")
                    player.runCommand(`titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw.weapon.skill4"},{"text":"${leaf_blower.attack4.attack_name}"}]}`);
                }
            }
        }
    }
    // Scary Lantern
    if (item.typeId === 'ld_hw:scary_lantern') {
        const levelScore = scary_lantern.level_score;
        const lvl = world.scoreboard.getObjective(levelScore);

        const ultScore = world.scoreboard.getObjective('ld_hw:scary_lantern_ult')
        const ult = ultScore.getScore(player)
        
        const lvlAmount = lvl.getScore(player);
        const cooldown_score = scary_lantern.cooldown_score;
        const selected_data = scary_lantern;
        let currentWeapon = null;
        const weaponNum = 4

        {
            if (player.isOnGround && !player.isSneaking) {
                currentWeapon = scary_lantern.attack1;
                attacking(player, currentWeapon, null, cooldown_score, item.typeId, selected_data, weaponNum);
            } else if (player.isOnGround && player.isSneaking) {
                if (lvlAmount >= 2) {
                    currentWeapon = scary_lantern.attack2;
                    attacking(player, currentWeapon, null, cooldown_score, item.typeId, selected_data, weaponNum);
                } else {
                    player.playSound("note.bass")
                    player.runCommand(`titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw.weapon.skill2"},{"text":"${scary_lantern.attack2.attack_name}"}]}`);
                }
            } else if (!player.isOnGround && !player.isSneaking) {
                if (lvlAmount >= 3) {
                    currentWeapon = scary_lantern.attack3;
                    attacking(player, currentWeapon, null, cooldown_score, item.typeId, selected_data, weaponNum);
                } else {
                    player.playSound("note.bass")
                    player.runCommand(`titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw.weapon.skill3"},{"text":"${scary_lantern.attack3.attack_name}"}]}`);
                }
            } else if (!player.isOnGround && player.isSneaking) {
                if (lvlAmount >= 5) {
                    if (ult >= 10) {
                        currentWeapon = scary_lantern.attack4;
                        attacking(player, currentWeapon, null, cooldown_score, item.typeId, selected_data, weaponNum);
                    } else {
                        player.playSound("note.bass")
                        player.runCommand(`titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw.weapon.ult_failed"}]}`);
                    }
                } else {
                    player.playSound("note.bass")
                    player.runCommand(`titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw.weapon.skill4"},{"text":"${scary_lantern.attack4.attack_name}"}]}`);
                }
            }
        }
    }
    // Digital Grave
    if (item.typeId === 'ld_hw:digital_grave') {
        const levelScore = digital_grave.level_score;
        const lvl = world.scoreboard.getObjective(levelScore);
        const lvlAmount = lvl.getScore(player);

        const ultScore = world.scoreboard.getObjective('ld_hw:digital_grave_ult')
        const ult = ultScore.getScore(player)
        
        const cooldown_score = digital_grave.cooldown_score;
        const selected_data = digital_grave;
        let currentWeapon = null;
        const weaponNum = 2

        {
            if (player.isOnGround && !player.isSneaking) {
                currentWeapon = digital_grave.attack1;
                attacking(player, currentWeapon, null, cooldown_score, item.typeId, selected_data, weaponNum);
            } else if (player.isOnGround && player.isSneaking) {
                if (lvlAmount >= 2) {
                    currentWeapon = digital_grave.attack2;
                    attacking(player, currentWeapon, null, cooldown_score, item.typeId, selected_data, weaponNum);
                } else {
                    player.playSound("note.bass")
                    player.runCommand(`titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw.weapon.skill2"},{"text":"${digital_grave.attack2.attack_name}"}]}`);
                }
            } else if (!player.isOnGround && !player.isSneaking) {
                if (lvlAmount >= 3) {
                    currentWeapon = digital_grave.attack3;
                    attacking(player, currentWeapon, null, cooldown_score, item.typeId, selected_data, weaponNum);
                } else {
                    player.playSound("note.bass")
                    player.runCommand(`titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw.weapon.skill3"},{"text":"${digital_grave.attack3.attack_name}"}]}`);
                }
            } else if (!player.isOnGround && player.isSneaking) {
                if (lvlAmount >= 5) {
                    if (ult >= 10) {
                        currentWeapon = digital_grave.attack4;
                        attacking(player, currentWeapon, null, cooldown_score, item.typeId, selected_data, weaponNum);
                    } else {
                        player.playSound("note.bass")
                        player.runCommand(`titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw.weapon.ult_failed"}]}`);
                    }
                } else {
                    player.playSound("note.bass")
                    player.runCommand(`titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw.weapon.skill4"},{"text":"${digital_grave.attack4.attack_name}"}]}`);
                }
            }
        }
    }
    // Rusty Chains
    if (item.typeId === 'ld_hw:rusty_chains') {
        const levelScore = rusty_chains.level_score;
        const lvl = world.scoreboard.getObjective(levelScore);
        const lvlAmount = lvl.getScore(player);

        const ultScore = world.scoreboard.getObjective('ld_hw:rusty_chains_ult')
        const ult = ultScore.getScore(player)
        
        const cooldown_score = rusty_chains.cooldown_score;
        const selected_data = rusty_chains;
        let currentWeapon = null;
        const weaponNum = 3

        {
            if (player.isOnGround && !player.isSneaking) {
                currentWeapon = rusty_chains.attack1;
                attacking(player, currentWeapon, null, cooldown_score, item.typeId, selected_data, weaponNum);
            } else if (player.isOnGround && player.isSneaking) {
                if (lvlAmount >= 2) {
                    currentWeapon = rusty_chains.attack2;
                    attacking(player, currentWeapon, null, cooldown_score, item.typeId, selected_data, weaponNum);
                } else {
                    player.playSound("note.bass")
                    player.runCommand(`titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw.weapon.skill2"},{"text":"${rusty_chains.attack2.attack_name}"}]}`);
                }
            } else if (!player.isOnGround && !player.isSneaking) {
                if (lvlAmount >= 3) {
                    currentWeapon = rusty_chains.attack3;
                    attacking(player, currentWeapon, null, cooldown_score, item.typeId, selected_data, weaponNum);
                } else {
                    player.playSound("note.bass")
                    player.runCommand(`titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw.weapon.skill3"},{"text":"${rusty_chains.attack3.attack_name}"}]}`);
                }
            } else if (!player.isOnGround && player.isSneaking) {
                if (lvlAmount >= 5) {
                    if (ult >= 10) {
                        currentWeapon = rusty_chains.attack4;
                        attacking(player, currentWeapon, null, cooldown_score, item.typeId, selected_data, weaponNum);
                    } else {
                        player.playSound("note.bass")
                        player.runCommand(`titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw.weapon.ult_failed"}]}`);
                    }
                } else {
                    player.playSound("note.bass")
                    player.runCommand(`titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw.weapon.skill4"},{"text":"${rusty_chains.attack4.attack_name}"}]}`);
                }
            }
        }
    }
    // Uncursed
    const uncursedWeapons = [
        'ld_hw:noncursed_leaf_blower',
        'ld_hw:noncursed_digital_grave',
        'ld_hw:noncursed_scary_lantern',
        'ld_hw:noncursed_rusty_chains'
    ]
    uncursedWeapons.forEach(wp=>{
        if(item.typeId===wp){
            player.runCommand(`titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw:uncursed_ewapon"}]}`);
            player.playSound("note.bass")
        }
    })
    if(testing){
        const wp = ['leaf_blower', 'digital_grave', 'rusty_chains', 'scary_lantern']
        if (item.typeId === 'minecraft:stick') {
            const exp = 79
            const lvl = 10
            const ult = 10
            wp.forEach(weapon=>{
                player.runCommand(`scoreboard players set @s ld_hw:${weapon}_exp ${exp}`)
                player.runCommand(`scoreboard players set @s ld_hw:${weapon}_lvl ${lvl}`)
                player.runCommand(`scoreboard players set @s ld_hw:${weapon}_ult ${ult}`)
            })
        }
        if (item.typeId === 'minecraft:iron_ingot') {
            const lvl = 5
            const ult = 10
            wp.forEach(weapon=>{
                player.runCommand(`scoreboard players set @s ld_hw:${weapon}_lvl ${lvl}`)
                player.runCommand(`scoreboard players set @s ld_hw:${weapon}_ult ${ult}`)
            })
        }
        if (item.typeId === 'minecraft:gold_ingot') {
            const weapon = 'ld_hw:'+wp[3]
            ultimate_attack_jumpscare(weapon,player)
        }
        if (item.typeId === 'minecraft:blaze_rod') {
            player.addTag('ld_hw:reboot')
            const health = player.getComponent('minecraft:health').currentValue
            player.setDynamicProperty('ld_hw:health_saved',health)
            player.setDynamicProperty('ld_hw:reboot_x',player.location.x)
            player.setDynamicProperty('ld_hw:reboot_y',player.location.y)
            player.setDynamicProperty('ld_hw:reboot_z',player.location.z)
        }
        if (item.typeId === 'minecraft:netherite_sword') {
            player.setDynamicProperty('ld_hw:jumpscare_delay',10)
        }
        if (item.typeId === 'minecraft:iron_sword') {
            const equippable = player.getComponent("minecraft:equippable");
            const mainhand = equippable.getEquipmentSlot(EquipmentSlot.Mainhand);
            mainhand.setItem(new ItemStack(`ld_hw:leaf_blower_skill4`));
        }
    }
});
function checkDistance(subject, target) {
    const deltaX = target.location.x - subject.location.x;
    const deltaY = target.location.y - subject.location.y;
    const deltaZ = target.location.z - subject.location.z;
    const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);
    return distance;
}
//UTIL FUNCTION
function attacking(player, currentWeapon, damageFilter, cooldown_score, itemId, selected_data, weaponNum) {
    const multiplier = selected_data.damage_multiply
    const levelScore = selected_data.level_score
    const lvl = world.scoreboard.getObjective(levelScore)
    const lvlAmount = lvl.getScore(player)
    //DEBUG 1 //console.warn(`your level is ${lvlAmount}`)
    const cd = world.scoreboard.getObjective(cooldown_score);
    if (cd.getScore(player)===0 && !player.hasTag('ld_hw:using_ability')){
        player.runCommand(currentWeapon.attack_translate)
        const delay = currentWeapon.animation_delay ? currentWeapon.animation_delay * 20 : 0;
        if (currentWeapon.has_animation === true) {
            system.runTimeout(()=>{
                player.playAnimation(currentWeapon.animation_tpp, {
                    nextState: `none`,
                    blendOutTime: 1,
                    stopExpression: `query.any_animation_finished`,
                    controller: `controller_name2`
                });
            }, delay)
        } 
        const equippable = player.getComponent("minecraft:equippable");
        if (!equippable) return;
		let slotIndex = player.selectedSlotIndex
        let damagingEntity = null
        let spellV = null
        const mainhand = equippable.getEquipmentSlot(EquipmentSlot.Mainhand);
        system.runTimeout(()=>{
            const frontPlayer={x:player.location.x+player.getViewDirection().x*2,y:player.location.y,z:player.location.z+player.getViewDirection().z*2}
            player.getComponent("minecraft:inventory").container.setItem(slotIndex,new ItemStack(`${itemId}_skill${currentWeapon.attackId}`));
            if(world.getDynamicProperty('ld_hw.:sound')){const soundEntity = player.dimension.spawnEntity('ld_hw:sound_entity',frontPlayer)
            soundEntity.setProperty('ld_hw:weapon', weaponNum)
            soundEntity.setProperty('ld_hw:ability', currentWeapon.attackId)
            system.runInterval(()=>{
                if(!soundEntity.isValid()) return
                soundEntity.teleport(frontPlayer)
            })}
        }, delay)
        if (Array.isArray(currentWeapon.spells) && currentWeapon.spells.length > 0) {
            currentWeapon.spells.forEach(spell=>{
                system.runTimeout(()=>{
                    const spellEntity = player.dimension.spawnEntity(spell.spell_id, {
                        x: player.location.x + (spell.spawn_location.x > 0 ? player.getViewDirection().x * spell.spawn_location.x : 0),
                        y: player.location.y + spell.spawn_location.y,
                        z: player.location.z + (spell.spawn_location.z > 0 ? player.getViewDirection().z * spell.spawn_location.z : 0)
                    });
                    spellEntity.setRotation({
                        x: player.getRotation().x * spell.rotation.x,
                        y: player.getRotation().y * spell.rotation.y
                    });
                    if (spell.is_spell_following_subject === true) {
                        const interval = system.runInterval(()=>{
                            if (spellEntity.isValid()===true){
                                spellEntity.runCommandAsync(`tp @s ${player.location.x} ${player.location.y} ${player.location.z}`)
                                spellEntity.setRotation({
                                    x: player.getRotation().x,
                                    y: player.getRotation().y
                                });
                            } else {
                                system.clearRun(interval)
                            }
                        })
                    }
                    damagingEntity = spellEntity
                    spellV = spellEntity
                    system.runTimeout(()=>{
                        spellEntity.remove()
                    }, spell.despawn_duration * 20)
                },spell.spawn_duration * 20)
            })
        }
        if (Array.isArray(currentWeapon.damaging) && currentWeapon.damaging.length > 0) {
            currentWeapon.damaging.forEach(damage=>{
                if (damage.damage_type === 'once') {
                    system.runTimeout(()=>{
                        let subject = player
                        if (damage.subject==='spell'){subject = spellV;}
                        subject.dimension.getEntities({location: subject.location, maxDistance: damage.radius, excludeTypes: ['minecraft:item','minecraft:xp_orb'], excludeFamilies: ['ld_hw']}).forEach(target=>{
                            if (target != player && target != spellV){
                                const damageAmount = damage.damage_amount + (lvlAmount/2) * multiplier
                                //DEBUG 1 //console.warn(`your damage is ${damageAmount}`)
                                target.applyDamage(damageAmount, {cause: 'contact', damagingEntity: player})
                            }
                        })
                        if (damage && typeof damage.effect === 'object' && damage.effect !== null) {
                            subject.runCommand(`effect @e[${damage.effect.target}] ${damage.effect.name} ${damage.effect.duration} ${damage.effect.amplifier}`)
                        }
                    },damage.duration * 20)
                } else if (damage.damage_type === 'loop') {
                    system.runTimeout(()=>{
                        const interval = system.runInterval(()=>{
                            let subject = player
                            if (damage.subject==='spell'){subject = spellV;}
                            subject.dimension.getEntities({location: subject.location, maxDistance: damage.radius, excludeTypes: ['minecraft:item','minecraft:xp_orb'], excludeFamilies: ['ld_hw']}).forEach(target=>{
                                if (target != player && target != spellV){
                                    ////console.warn(`your damager is ${subject.name}`)
                                    const damageAmount = damage.damage_amount + (lvlAmount/2) * multiplier
                                    //DEBUG 1 //console.warn(`your damage is ${damageAmount}`)
                                    target.applyDamage(damageAmount, {cause: 'contact', damagingEntity: player})
                                }
                            })
                            if (damage && typeof damage.effect === 'object' && damage.effect !== null) {
                                player.runCommand(`effect @e[${damage.effect.target}] ${damage.effect.name} ${damage.effect.duration} ${damage.effect.amplifier}`)
                            }
                        })
                        system.runTimeout(()=>{
                            system.clearRun(interval)
                        }, (damage.stop_duration - damage.start_duration) * 20)
                    },damage.start_duration * 20)
                }
            });
        }
        system.runTimeout(()=>{
            if(currentWeapon.attack_name!=`Frenzied Rampage`){
                player.getComponent("minecraft:inventory").container.setItem(slotIndex, new ItemStack(itemId));
                player.removeTag('ld_hw:using_ability')
            }
            //player.runCommand(`replaceitem entity @s slot.hotbar ${slotIndex} ${itemId}`)
            player.startItemCooldown(itemId, currentWeapon.cd * 20)
            player.runCommand(`scoreboard players set @s ${cooldown_score} ${currentWeapon.cd}`)
        }, currentWeapon.attackDuration * 20)
        system.runTimeout(()=>{
            currentWeapon.custom_effects(player, damagingEntity)
        }, currentWeapon.function_duration * 20)
        player.addTag('ld_hw:using_ability')
    } else if (cd.getScore(player) > 0) {
        player.runCommand(`titleraw @s actionbar {"rawtext":[{"translate":"actionbar.ld_hw:on_cooldown"}]}`)
    }
}
function getItemOnInventory(player, item) {
    /** @type { mc.EntityInventoryComponent } */
    const inventory = player.getComponent("minecraft:inventory");
    for (let i = 0; i < inventory.container?.size; i++) {
        const itemI = inventory.container.getItem(i);
        if (itemI && itemI.typeId === item) {
            return { slot: i }; // Return only the slot index
        }
    }
    return null; // Return null if not found
}
function checkItemInMainHand(player, itemId) {
    if (player.getComponent("equippable")?.getEquipment("Mainhand")?.typeId === itemId) {
        return true
    } else {
        return false
    }
}
world.getPlayers().forEach(player=>{
    player.runCommand(`inputpermission set @s camera enabled`)
    player.runCommand(`inputpermission set @s movement enabled`)
    player.runCommand(`camera @s clear`)
    player.runCommand(`hud @s reset`)
    player.removeTag('ld_hw:hooked')
    player.removeTag('ld_hw:rusty')
    player.removeTag('ld_hw:butcher_hooked')
    player.removeTag('ld_hw:chain_hooked')
    player.removeTag('ld_hw:chainsaw_frenzy')
    player.removeTag('ld_hw:grind_through')
    player.removeTag('ld_hw:infected')
    player.removeTag('ld_hw:madness')
    player.setDynamicProperty('ld_hw:jumpscare_delay',0)
    if (player.hasTag('ld_hw:reboot')){
        system.runTimeout(()=>{
            player.removeTag('ld_hw:reboot')
        },10*20)
    }
})
world.afterEvents.dataDrivenEntityTrigger.subscribe((arg)=>{
    const entity = arg.entity
    const event = arg.eventId
    const mobs = ['ld_hw:the_butcher','ld_hw:the_chain_warden','ld_hw:the_corruptor','ld_hw:the_wraith_keeper']
    if (event==="ld_hw:remove_entity" && mobs.includes(entity.typeId)) {
        entity.dimension.spawnParticle('ld_hw:phase_shift_1',entity.location)
        entity.dimension.spawnParticle('ld_hw:phase_shift_2',entity.location)
        entity.runCommand(`playsound ld_hw:mob.the_wraith_keeper.hurt @a ~~~`)
    }
    if (event==="ld_hw:remove_entity" && entity.typeId==='ld_hw:decimal_skeleton') {
        entity.runCommand(`playsound ld_hw:effect.glitch @a ~~~`)
        entity.dimension.spawnParticle('ld_hw:glitch_teleport_1',entity.location)
        entity.dimension.spawnParticle('ld_hw:glitch_teleport_2',entity.location)
        entity.dimension.spawnParticle('ld_hw:glitch_teleport_3',entity.location)
        entity.dimension.spawnParticle('ld_hw:glitch_teleport_4',entity.location)
    }
})
const anyWeapons = [
            'ld_hw:scary_lantern',
            'ld_hw:scary_lantern_skill1',
            'ld_hw:scary_lantern_skill2',
            'ld_hw:scary_lantern_skill3',
            'ld_hw:scary_lantern_skill4',
            'ld_hw:digital_grave',
            'ld_hw:digital_grave_skill1',
            'ld_hw:digital_grave_skill2',
            'ld_hw:digital_grave_skill3',
            'ld_hw:digital_grave_skill4',
            'ld_hw:leaf_blower',
            'ld_hw:leaf_blower_skill1',
            'ld_hw:leaf_blower_skill2',
            'ld_hw:leaf_blower_skill3',
            'ld_hw:leaf_blower_skill4',
            'ld_hw:rusty_chains',
            'ld_hw:rusty_chains_skill1',
            'ld_hw:rusty_chains_skill2',
            'ld_hw:rusty_chains_skill3',
            'ld_hw:rusty_chains_skill4'
]
world.afterEvents.entityHurt.subscribe((arg)=>{
    const attacker = arg.damageSource.damagingEntity;
    const victim = arg.hurtEntity;
    const damage = arg.damage;
    anyWeapons.forEach(weapon=>{
        if(attacker==null) return
        if(attacker.typeId==="minecraft:player"&&checkItemInMainHand(attacker, weapon)){
            const damageDisplay = victim.dimension.spawnEntity("ld_hw:damage", {
                x: victim.location.x + lib.calculate.random(10, -10) / 10,
                y: victim.location.y + lib.calculate.random(12, 20) / 10,
                z: victim.location.z + lib.calculate.random(10, -10) / 10
            
            })
            damageDisplay.setProperty("ld_hw:value", Math.ceil(damage / 2))
            damageDisplay.triggerEvent("scale." + lib.calculate.random(1.3, 1.8))
        }
    })
    weapons.forEach(weapon=>{
        if(attacker==null) return
        if(attacker.typeId==="minecraft:player"&&arg.damageSource.cause==='entityAttack'&&checkItemInMainHand(attacker, weapon)){
            const lvl = world.scoreboard.getObjective(weapon+"_lvl").getScore(attacker)
            victim.applyDamage((6+lvl), {damagingEntity:attacker,cause:'contact'})
            ////console.warn(`damage: ${6+lvl/2} Heart`)
        }
    })
})
}