import { world, system, ItemStack, EntityComponentTypes, ItemComponentTypes, EquipmentSlot } from "@minecraft/server"
import { ModalFormData, ActionFormData } from "@minecraft/server-ui";

system.beforeEvents.startup.subscribe(event => {
        event.itemComponentRegistry.registerCustomComponent("darkw_dotv:is_broken_legsword", {
        onUse: e => {

            const grabMob = e.source.getEntitiesFromViewDirection({maxDistance: 12})
            const player = e.source

            if (!grabMob[0]) return

            if (grabMob[0].entity.typeId == 'darkw_dotv:legatus') {
                const player = e.source
                const target = grabMob[0].entity
                const item = e.itemStack

                item.nameTag = '§r§eShatterfire\n§9+ View in inventory for Stats\nDisciples of The Void'
                let activateLore = '§r§7When Used:\n  §9Use while pointing at an entity and Legatus will attack them.\n  §9Legatus will still attack mobs you hit. This is just a faster way to give him a target.\n  §9(Only works with a tamed Legatus.)'
                item.setLore([activateLore])
                player.getComponent('equippable').setEquipment(EquipmentSlot.Mainhand, item)
                const l = target.location
                target.runCommand('summon darkw_dotv:deathmusicstopper')
                target.runCommand('/function darkw/dotviii/defeat/def_lie')
                for (let i = 0; i < 4; i++) target.runCommand('/particle minecraft:heart_particle ~ ~2 ~')
                target.dimension.spawnEntity('darkw_dotv:legatus_pet', {x: l.x, y: l.y, z: l.z}).getComponent('tameable').tame(player)
                target.remove()
                return
                
            }

            if (grabMob[0].entity.typeId != 'darkw_dotv:legatus') {
                const target = grabMob[0].entity
                player.runCommand('playsound legatus.cast @s ~ ~ ~')
                target.runCommand('particle darkw_dotv:legatus_sword_target ~ ~1 ~')
                target.runCommand('scoreboard players add @s "darkw_dotv:shatterfiretimer" 100')
                target.addTag('darkw_dotv:legatus_attackable')
                return
            }
        }
    })
    // *
    // *
    // *
    // *
    // *
    // * Eribus Sword
    event.itemComponentRegistry.registerCustomComponent("darkw_dotv:weapon_eribus", {
        onUse: e => {
            const player = e.source

            const equipment = player.getComponent('equippable');
            const mainHand = equipment.getEquipment("Mainhand");
            let durability = mainHand.getComponent('durability')


            if (!player.isSneaking && durability.damage < 1400) {
                const TeleportTest = player.getBlockFromViewDirection({maxDistance: 14})
                if (TeleportTest) {
                    player.tryTeleport(TeleportTest.block.above().location)
                    player.runCommand('particle darkw_dotv:teleport ~ ~ ~')
                    player.runCommand('playsound mob.shulker.teleport @s')
                    const gamemode = player.getGameMode()
                    if ((gamemode === 'survival' || gamemode === 'adventure')) {
                        durability.damage += 35
                        equipment.setEquipment("Mainhand", mainHand);
                    }
                }
            }
        },
        onHitEntity: e => {
            const player = e.attackingEntity
            const victim = e.hitEntity

            const equipment = player.getComponent('equippable');
            const mainHand = equipment.getEquipment("Mainhand");
            let durability = mainHand.getComponent('durability')

            if (durability.damage < 1400) {

                // Get Random Number
                const RandomNumber = Math.floor(Math.random() * 4)

                // Teleport In Random Direction
                const gamemode = player.getGameMode()
                if (gamemode === 'survival' || gamemode === 'adventure') {
                    durability.damage += 50
                    equipment.setEquipment("Mainhand", mainHand);
                }

                if (player.isSneaking) {
                    if (RandomNumber === 0) {
                        victim.runCommand('particle darkw_dotv:teleport ~ ~ ~')
                        victim.runCommand('execute as @s if block ~7 ~ ~ air run teleport ~7 ~ ~')
                        player.runCommand('playsound mob.shulker.teleport @s')
                    }
                    if (RandomNumber === 1) {
                        victim.runCommand('particle darkw_dotv:teleport ~ ~ ~')
                        victim.runCommand('execute as @s if block ~ ~ ~7 air run teleport ~ ~ ~7')
                        player.runCommand('playsound mob.shulker.teleport @s')
                    }
                    if (RandomNumber === 2) {
                        victim.runCommand('particle darkw_dotv:teleport ~ ~ ~')
                        victim.runCommand('execute as @s if block ~-7 ~ ~ air run teleport ~-7 ~ ~')
                        player.runCommand('playsound mob.shulker.teleport @s')
                    }
                    if (RandomNumber === 3) {
                        victim.runCommand('particle darkw_dotv:teleport ~ ~ ~')
                        victim.runCommand('execute as @s if block ~ ~ ~-7 air run teleport ~ ~ ~-7')
                        player.runCommand('playsound mob.shulker.teleport @s')
                    }
                }
            }
        }
    }),
        // *
        // *
        // *
        // *
        // *
        // * Command Chalk
        event.itemComponentRegistry.registerCustomComponent("darkw_dotv:weapon_alatar", {
            onUse: e => {
                const player = e.source
                const scoreboard = world.scoreboard

                const RuneSelect = scoreboard.getObjective('darkw_dotv:Alatar_RuneSelection').getScore(player)

                if (player.isSneaking) {

                    let config = new ModalFormData
                    config.title('Command Chalk')
                    config.dropdown('\nThe chalk only has access to the §e/setblock§r command, and only §ethree blocks§r.\n\n- Block Input- ', ['darkw_dotv:rune_boom', 'darkw_dotv:rune_purify', 'darkw_dotv:rune_voidburn'])
                    config.label('- Translations - \nrune_purify = Purification Rune\nrune_boom = Explosion Rune\nrune_burn = Voidburn Rune\n ')
                    config.show(player).then(r => {
                        if (r.canceled) return
                        world.scoreboard.getObjective('darkw_dotv:Alatar_RuneSelection').setScore(player, (r.formValues[0]))
                    })
                    return

                    // +1 Score
                    player.runCommand('scoreboard players add @s darkw_dotv:Alatar_RuneSelection 1')


                    switch (RuneSelect) {

                        // None
                        case 0:
                            player.runCommand('title @s actionbar Rune Selected: Clensing Rune')
                            player.playSound('misc.ping')
                            break

                        // Clensing
                        case 1:
                            player.runCommand('title @s actionbar Rune Selected: Explosion Rune')
                            player.playSound('misc.ping')
                            break


                        // Explosion
                        case 2:
                            player.runCommand('title @s actionbar Rune Selected: Voidburn Rune')
                            player.playSound('misc.ping')
                            break


                        // Voidburn
                        case 3:
                            player.runCommand('title @s actionbar No Rune Selected')
                            player.playSound('misc.ping')
                            break
                    }
                }

            },
            "onUseOn": e => {

                // Grabbing variables
                const block = e.block
                const x = e.block.x + 0.5
                const y = e.block.y + 1
                const z = e.block.z + 0.5



                const player = e.source
                const scoreboard = world.scoreboard
                const RuneSelect = scoreboard.getObjective('darkw_dotv:Alatar_RuneSelection').getScore(player)

                if (!player.isSneaking) {

                    // Get Item
                    if (!scoreboard.getObjective('darkw_dotv:Alatar_RuneSelection').getScore(player)) scoreboard.getObjective('darkw_dotv:Alatar_RuneSelection').setScore(player, 0)
                    const equipment = player.getComponent('equippable');
                    const mainHand = equipment.getEquipment("Mainhand");
                    let durability = mainHand.getComponent('durability')

                    if (durability.damage < 1400) {

                        const gamemode = player.getGameMode()
                        if ((gamemode === 'survival' || gamemode === 'adventure') && RuneSelect > 0) {
                            durability.damage += 50
                            equipment.setEquipment("Mainhand", mainHand);
                        }

                        switch (RuneSelect) {

                            // Clensing
                            case 0:
                                e.block.dimension.setBlockType({ x, y, z }, 'darkw_dotv:rune_boom')
                                break


                            // Explosion
                            case 1:
                                e.block.dimension.setBlockType({ x, y, z }, 'darkw_dotv:rune_purify')
                                break


                            // Voidburn
                            case 2:
                                e.block.dimension.setBlockType({ x, y, z }, 'darkw_dotv:rune_voidburn')
                                break
                        }
                    }

                    if (e.source.getGameMode() === 'Creative') return
                    let item = e.itemStack
                    let ran = Math.floor(Math.random() * 45)
                    let dura = item.getComponent('durability')
                    if (dura.damage + ran < dura.maxDurability) {
                        dura.damage += ran
                        e.source.getComponent('equippable').setEquipment(EquipmentSlot.Mainhand, item)
                    }
                    else {
                        e.source.getComponent('equippable').setEquipment(EquipmentSlot.Mainhand, new ItemStack('air', 1))
                    }


                }
            }
        }),
        // * 
        // * 
        // * 
        // * 
        // * 
        // * (Brawlatar) - Rotten Axe
        event.itemComponentRegistry.registerCustomComponent("darkw_dotv:weapon_brawlatar", {
            onHitEntity: e => {
                const player = e.attackingEntity
                const victim = e.hitEntity
                const TestIsSick = player.runCommand('testfor @s[scores={darkw_dotv:Brawlatar_WeaponSickness=100..}]').successCount
                if (TestIsSick) {
                    if (!victim) return
                }

                victim.applyKnockback({ x: player.getViewDirection().x * 1.65, z: player.getViewDirection().z * 1.65 }, 0.35)
                player.runCommand('scoreboard players add @s darkw_dotv:Brawlatar_WeaponSickness 35')



            },
            onUse: e => {
                const player = e.source
                const TestIsSick = player.runCommand('testfor @s[scores={darkw_dotv:Brawlatar_WeaponSickness=100..}]').successCount

                if (TestIsSick === 1) {
                    player.runCommand('scoreboard players set @s darkw_dotv:Brawlatar_WeaponSickness 0')
                    player.runCommand('effect @e[r=7, type=!player] fatal_poison 5 5')
                    player.runCommand('playsound brawlatar.throwup_ui @s')
                    player.runCommand('particle darkw_dotv:brawlypuke2 ~ ~1 ~')
                }
            }
        }),
        event.itemComponentRegistry.registerCustomComponent("darkw_dotv:weapon_puppet", {
            onHitEntity: e => {

                const player = e.attackingEntity
                const gamemode = e.attackingEntity.getGameMode()

                const equipment = player.getComponent('equippable');
                const mainHand = equipment.getEquipment("Mainhand");
                let durability = mainHand.getComponent('durability')

                const RanNum = Math.floor(Math.random() * 3)

                const victim = e.hitEntity

                if (RanNum === 0) {
                    victim.runCommand('playsound misc.thepuppet.zappy @a[r=7] ~~~')
                    victim.runCommand('particle darkw_dotv:puppetzappy ~~~')
                    victim.applyDamage(40)
                    system.run(() => {
                        if ((gamemode === 'survival' || gamemode === 'adventure')) {
                            durability.damage += 20
                            equipment.setEquipment("Mainhand", mainHand);
                        }
                    })
                }
            }
        })
    event.itemComponentRegistry.registerCustomComponent("darkw_dotv:kunai_puppet", {
        onUse: e => {
            const player = e.source
            const item = e.itemStack

            const equipment = player.getComponent('equippable');
            const mainHand = equipment.getEquipment("Mainhand");
            let d = item.getComponent('durability')
            if (d.damage > 80) return

            system.run(() => {
                system.runTimeout(() => {
                    KunaiShoot(player)
                    player.runCommand('/playsound mob.witch.throw @s ~ ~ ~')

                    if (player.getGameMode() != 'Creative') {

                        if (d.damage + 20 > d.maxDurability) {
                            player.runCommand('/playsound random.break @s ~ ~ ~')

                            d.damage == 1
                            equipment.setEquipment(EquipmentSlot.Mainhand, item)
                        }
                        else {
                            d.damage += 20
                            equipment.setEquipment(EquipmentSlot.Mainhand, item)
                        }
                    }
                }, 13)
            })
        }
    })
    // *
    // *
    // *
    // *
    // *
    // * YIN
    event.itemComponentRegistry.registerCustomComponent("darkw_dotv:weapon_yin", {
        onUse: e => {
            const player = e.source
            const item = e.itemStack

            const gamemode = player.getGameMode()

            const equipment = player.getComponent('equippable');
            const mainHand = equipment.getEquipment("Mainhand");
            let durability = mainHand.getComponent('durability')

            const CreationTest = player.runCommand('/testfor @s[scores={darkw_dotv:CREATIONCAHRGE=100..}]').successCount

            if ((CreationTest === 1 && durability.damage < 1250) || CreationTest === 1 && gamemode === 'Creative') {
                player.addEffect('resistance', 15, { amplifier: 50 })
                player.runCommand('summon darkw_dotv:alatar_r_escaton_yin')
                player.runCommand('scoreboard players set @s darkw_dotv:CREATIONCAHRGE 0')
                player.runCommand('damage @e[r=15, type=!player, family=!disciple] 45 entity_explosion')
                player.runCommand('effect @e[r=15, type=!player, family=!disciple] wither 5 5')
                player.runCommand('particle darkw_dotv:yin_one ~ ~ ~')
                player.runCommand('particle darkw_dotv:yin_two ~ ~ ~')
                player.runCommand('playsound misc.yinboom @a[r=15] ~ ~ ~')


                if (gamemode != 'Creative') {
                    durability.damage += 1250
                    equipment.setEquipment(EquipmentSlot.Mainhand, mainHand);
                }
            }
        },
        onHitEntity: e => {
            const player = e.attackingEntity
            const victim = e.hitEntity
            const item = e.itemStack
            const durability = item.getComponent('durability')

            const equipment = player.getComponent('equippable');
            const mainHand = equipment.getEquipment("Mainhand");
            player.addEffect('regeneration', 100, { amplifier: 5 })
            victim.addEffect('wither', 100, { amplifier: 5 })

                if (player.getGameMode() != 'Creative' && (durability.damage - 50) > 0) {
                    durability.damage -= 50
                    equipment.setEquipment(EquipmentSlot.Mainhand, item);
                    return
                }


        }
    })
    // *
    // *
    // *
    // *
    // *
    // * YANG
    event.itemComponentRegistry.registerCustomComponent("darkw_dotv:weapon_yang", {
        onHitEntity: e => {
            const player = e.attackingEntity
            const item = e.itemStack
            const victim = e.hitEntity
            const equipment = player.getComponent('equippable');
            const mainHand = equipment.getEquipment("Mainhand");
            let cool = item.getComponent('cooldown')

            if (cool.getCooldownTicksRemaining(player) != 0) return
            let durability = mainHand.getComponent('durability')
            let desBuild = world.scoreboard.getObjective('darkw_dotv:DESTRUCTIONCAHRGE_dmg')
            let ranBuild = Math.floor(Math.random() * 25)
            cool.startCooldown(player)
            desBuild.addScore(player, ranBuild)
            
            player.addEffect('regeneration', 10, { amplifier: 4 })
            victim.runCommand(`particle darkw_dotv:yangparticle_soultake ~~~`)
            victim.addEffect('wither', 100, { amplifier: 7 })
        },
        onUse: e => {
            const player = e.source
            const item = e.itemStack
            let cool = item.getComponent('cooldown')
            let desBuild = world.scoreboard.getObjective('darkw_dotv:DESTRUCTIONCAHRGE_dmg')

            let zSh = 3
            let ySh = 1

            if (desBuild.getScore(player) < 10 && player.getGameMode() != 'Creative') return
            let dmgBeamNum = desBuild.getScore(player)
            let dmgBeam = player.getEntitiesFromViewDirection({ maxDistance: 15 })
            dmgBeam.forEach(m => {
                m.entity.applyDamage(dmgBeamNum, {
                    cause: 'entity_attack',
                    damagingProjectile: player,
                    damagingEntity: player
                })
            })
            desBuild.setScore(player, 0)
            player.startItemCooldown('darkw_dotv:yang', 200)
            player.runCommand('playsound weapon.yang.boom @a ~~~')
            player.runCommand('camerashake add @s 0.1 1 positional')
            player.runCommand(`particle darkw_dotv:yangblast-1 ^^${ySh}^${zSh * 1}`)
            player.runCommand(`particle darkw_dotv:yangblast-1 ^^${ySh}^${zSh * 2}`)
            player.runCommand(`particle darkw_dotv:yangblast-1 ^^${ySh}^${zSh * 3}`)
            player.runCommand(`particle darkw_dotv:yangblast-1 ^^${ySh}^${zSh * 4}`)
            player.runCommand(`particle darkw_dotv:yangblast-1 ^^${ySh}^${zSh * 5}`)
            player.runCommand(`particle darkw_dotv:yangblast-1 ^^${ySh}^${zSh * 6}`)
            player.runCommand(`particle darkw_dotv:yangblast-1 ^^${ySh}^${zSh * 7}`)
            player.runCommand(`particle darkw_dotv:yangblast-2 ^^${ySh}^${zSh * 1}`)
            player.runCommand(`particle darkw_dotv:yangblast-2 ^^${ySh}^${zSh * 2}`)
            player.runCommand(`particle darkw_dotv:yangblast-2 ^^${ySh}^${zSh * 3}`)
            player.runCommand(`particle darkw_dotv:yangblast-2 ^^${ySh}^${zSh * 4}`)
            player.runCommand(`particle darkw_dotv:yangblast-2 ^^${ySh}^${zSh * 5}`)
            player.runCommand(`particle darkw_dotv:yangblast-2 ^^${ySh}^${zSh * 6}`)
            player.runCommand(`particle darkw_dotv:yangblast-2 ^^${ySh}^${zSh * 7}`)
        }
    })
    // * 
    // * 
    // * 
    // * 
    // * 
    // * Erian Knuckles
    event.itemComponentRegistry.registerCustomComponent("darkw_dotv:weapon_erian", {
        onHitEntity: e => {
            let item = e.itemStack
            let player = e.attackingEntity
            let vic = e.hitEntity
            let wombocombo = world.scoreboard.getObjective('darkw_dotv:erianknuckles')
            let combo = wombocombo.getScore(player)

            if (item.getComponent(ItemComponentTypes.Cooldown).getCooldownTicksRemaining(player) != 0) return
            
            wombocombo.addScore(player, 20)
            vic.dimension.spawnParticle('darkw_dotv:eriancrit', vic.location)
            vic.dimension.playSound('mob.generic.hit', vic.location)
            vic.applyDamage(0.5 * Math.round(combo / 10))
            item.getComponent(ItemComponentTypes.Cooldown).startCooldown(player)
        }
    })
    // * 
    // * 
    // * 
    // * 
    // * 
    // * Roxxane Bow
    // * 
    // * 
    // * 
    // * 
    // * 
    // * (Roxantria) Rouger
    event.itemComponentRegistry.registerCustomComponent("darkw_dotv:weapon_roxantria", {
        onHitEntity: e => {
            let item = e.itemStack
            let player = e.attackingEntity
            let vic = e.hitEntity
            let ticks = player.getEffect('invisibility')?.duration ?? 0

            if (ticks > 0) {
                player.playAnimation('animation.darkw_dotv-primordial_prismatica.hidetendrils')
                player.removeEffect('invisibility')
                player.removeEffect('speed')
                let bonus = 5 / ticks * 50
                vic.applyDamage(10, {
                    cause: 'entity_attack',
                    damagingEntity: player,
                    damagingProjectile: player
                })
            }
        },
        onUse: e => {
            let player = e.source
            let item = e.itemStack
            player.dimension.spawnParticle('darkw_dotv:rox_potion_slam-invis', player.location)
            player.dimension.playSound('random.glass', player.location)
            player.addEffect('invisibility', 100, { showParticles: false })
            player.addEffect('speed', 100, { showParticles: false, amplifier: 3 })
            player.playAnimation('animation.darkw_dotv-primordial_prismatica.dash_player')

        }
    }),
        // * 
        // * 
        // * 
        // * 
        // * 
        // * Ageto Magala Weapon
        event.itemComponentRegistry.registerCustomComponent("darkw_dotv:weapon_agetomagala", {
            onHitEntity: e => {
                let player = e.attackingEntity
                let victim = e.hitEntity
                let item = e.itemStack

                let ranPick = Math.floor(Math.random() * 7)
                if (ranPick === 0) {
                    victim.dimension.createExplosion(victim.location, 5, {causesFire: false, breaksBlocks: false, source: player})
                }
            }
        })
        // * 
        // * 
        // * 
        // * 
        // * 
        // * Ageto Magala Chalk
        event.itemComponentRegistry.registerCustomComponent("darkw_dotv:chalk_agetomagala", {
            onHitEntity: e => {
                e.hitEntity.runCommand('execute as @s[family=voliidisciple] run /kill @s')
                e.hitEntity.addEffect('wither', 200, { amplifier: 1 })
            },
            onUseOn: e => {
                let mainhand = e.source.getComponent('equippable').getEquipmentSlot('Mainhand')
                let item = e.itemStack
                let dura = item.getComponent('durability')
                if (e.block.typeId.includes('rune')) return
                switch (e.itemStack.typeId) {
                    case "darkw_dotv:chalk_agetomagala_boom":
                        e.block.dimension.setBlockType({ x: e.block.x + 0.5, y: e.block.y + 1, z: e.block.z + 0.5 }, 'darkw_dotv:rune_boom')
                        break
                    case "darkw_dotv:chalk_agetomagala_darkburn":
                        e.block.dimension.setBlockType({ x: e.block.x + 0.5, y: e.block.y + 1, z: e.block.z + 0.5 }, 'darkw_dotv:rune_voidburn_alt')
                        break
                    case "darkw_dotv:chalk_agetomagala_lightning":
                        e.block.dimension.setBlockType({ x: e.block.x + 0.5, y: e.block.y + 1, z: e.block.z + 0.5 }, 'darkw_dotv:rune_zappy_alt')
                        break
                }
                if (e.source.getGameMode() === 'Creative') return
                if (e.source.hasTag('darkw_dotv:agetoEmbedded')) return
                let ran = Math.floor(Math.random() * 15)
                if (dura.damage + ran < dura.maxDurability) {
                    dura.damage += ran
                    mainhand.setItem(item)
                }
                else {
                    mainhand.setItem(new ItemStack('air', 1))
                }
            }
        })
        // * 
        // * 
        // * 
        // * 
        // * 
        // * L1MB0
        event.itemComponentRegistry.registerCustomComponent("darkw_dotv:weapon_yinyang", {
            onUse: e => {
                const item = e.itemStack
                const player = e.source
                const mode = item.getDynamicProperty('darkw_dotv:limboselect')
                player.playSound('misc.ping')
                
                // * Switch Weapon Mode while sneaking.
                switch (mode) {
                    case ('limbo'): {
                        item.setDynamicProperty('darkw_dotv:limboselect', 'angel')
                        player.getComponent('equippable').setEquipment(EquipmentSlot.Mainhand, item)
                        break
                    }
                    case ('angel'): {
                        item.setDynamicProperty('darkw_dotv:limboselect', 'devil')
                        player.getComponent('equippable').setEquipment(EquipmentSlot.Mainhand, item)
                        break
                    }
                    case ('devil'): {
                        item.setDynamicProperty('darkw_dotv:limboselect', 'limbo')
                        player.getComponent('equippable').setEquipment(EquipmentSlot.Mainhand, item)
                        break
                    }
                }
            },
            onHitEntity: e => {
                const item = e.itemStack
                const player = e.attackingEntity
                const target = e.hitEntity
                const mode = item.getDynamicProperty('darkw_dotv:limboselect')
                let souls = world.scoreboard.getObjective('darkw_dotv:limbosouls')
                switch (mode) {
                    case ('limbo'): {
                        let ran = Math.floor(Math.random() * 5)
                        target.runCommand(`particle darkw_dotv:yangparticle_soultake ~~~`)
                        souls.addScore(player, ran)
                        break
                    }
                    // * On Hit, ANGEl
                    case ('angel'): {
                        player.runCommand(`particle darkw_dotv:yang_buff ~~~`)
                        break
                    }
                    // * On Hit, DEVIL
                    case ('devil'): {
                        if (souls.getScore(player) < 10) return

                                        player.runCommand('particle darkw_dotv:yang_one ~ ~ ~')
                                        player.runCommand('camerashake add @s 0.1 1 positional')
                player.runCommand('particle darkw_dotv:yang_two ~ ~ ~')
                player.runCommand('playsound misc.yinboom @a[r=15] ~ ~ ~ 1 0.85')

                        if (player.isSneaking) {
                            target.addEffect('wither', 20 + souls.getScore(player))
                            target.runCommand(`particle darkw_dotv:yangparticle_soultake ~~~`)
                            target.applyDamage(souls.getScore(player))
                            player.runCommand('/playsound weapon.yang.boom @a ~~~ 1 1.75')
                            souls.setScore(player, 0)
                            return
                        }
                        if (!player.isSneaking) {
                            let mobList = player.dimension.getEntities({maxDistance: 4, excludeNames: [player.nameTag], location: player.location})
                            target.runCommand(`particle darkw_dotv:yangparticle_soultake ~~~`)
                            player.runCommand('/playsound weapon.yang.boom @a ~~~ 1 1.75')
                            let splitDmg = souls.getScore(player) / mobList.length
                            mobList.forEach(entity => {
                                entity.addEffect('wither', 20 + souls.getScore(player))
                                entity.applyDamage(10 + splitDmg)
                            })
                            souls.setScore(player, 0)
                            return
                        }
                        break
                    }
                }
            }
        })
    // * 
    // * 
    // * 
    // * 
    // * 
    // * Faevia Sword
    event.itemComponentRegistry.registerCustomComponent("darkw_dotv:weapon_faevia", {
        onUse: e => {
            e.source.runCommand('scriptevent darkw_dotv:faevia-dash-weapon')
            e.source.dimension.playSound('mark.crack.poof', e.source.location)
        }
    })
    // * 
    // * 
    // * 
    // * 
    // * 
    // * Legatus Sword
    event.itemComponentRegistry.registerCustomComponent("darkw_dotv:weapon_legatus", {
        onUse: e => {
            let player = e.source
            let mainHand = player.getComponent('equippable')
            let item = e.itemStack

            let block = player.getBlockFromViewDirection({ maxDistance: 13 })?.block
            if (!block) return
            let l = block.location
            block.dimension.spawnEntity('darkw_dotv:legatus_rune_floor', { x: l.x + 0.5, y: l.y + 1, z: l.z + 0.5 })

            if (e.source.getGameMode() === 'Creative') return

            let ran = Math.floor(Math.random() * 45)
            let dura = item.getComponent('durability')
            if (dura.damage + ran < dura.maxDurability) {
                dura.damage += ran
                mainHand.setEquipment(EquipmentSlot.Mainhand, item)
            }
            else {
                mainHand.setEquipment(EquipmentSlot.Mainhand, new ItemStack('air', 1))
            }
        }
    })
    // * 
    // * 
    // * 
    // * 
    // * 
    // * Roxxane Jetblade Chalk
    event.itemComponentRegistry.registerCustomComponent('darkw_dotv:is_roxxane_sword', {
        onUse: e => {
            const player = e.source
            const item = e.itemStack
            const durability = e.itemStack.getComponent('durability')
            const damage = durability.damage
            const l = player.location

            system.runTimeout(() => { notOnGround() }, 2)
            // * Use, NO Tag
            if (!player.hasTag('darkw_dotv:slamcheck') && !player.hasTag('cooldown_sword_rox')) {
                player.applyKnockback({ x: 0, y: 0, z: 0 }, 1.5);
                player.addTag('darkw_dotv:slamcheck')
                player.addTag('cooldown_sword_rox')
                player.runCommand('playsound roxxane.swordslam1 @a[r=12] ~ ~ ~')
                player.runCommand('playanimation @s animation.darkw_dotv.jetblade.slam_sword_1')
                player.runCommand('particle minecraft:knockback_roar_particle_setup ~ ~ ~')
                system.runTimeout(() => {
                    if (player.hasTag('darkw_dotv:slamcheck')) player.removeTag('darkw_dotv:slamcheck')
                }, 27)

                if (player.getGameMode() === 'Creative') return
                if (durability.damage + 75 >= durability.maxDurability) {
                    let air = new ItemStack('minecraft:air', 1)
                    player.getComponent('equippable').setEquipment(EquipmentSlot.Mainhand, air)
                    player.runCommand('/playsound random.break @s ~ ~ ~')
                }
                if (durability.damage + 75 <= durability.maxDurability) {
                    durability.damage += 75
                    player.getComponent('equippable').setEquipment(EquipmentSlot.Mainhand, item)
                }
                return

            }
            // * Use, HAS tag
            else if (player.hasTag('darkw_dotv:slamcheck') && !player.isOnGround) {
                player.applyKnockback({ x: 0, y: 0, z: 0 }, -10)
                system.runTimeout(() => {


                }, 1)
                return
            }
            async function notOnGround() {
                let goTick = 0
                while (!player.isOnGround) {
                    if (goTick > 40) return
                    await system.waitTicks(1)
                    player.dimension.spawnParticle('darkw_dotv:bombpath_jetblade', player.location)
                    goTick++
                }
                if (!player.hasTag('darkw_dotv:slamcheck')) {
                    player.removeTag('cooldown_sword_rox')
                    return
                }
                player.dimension.spawnParticle('minecraft:knockback_roar_particle_setup', player.location)
                player.removeTag('cooldown_sword_rox')
                player.removeTag('darkw_dotv:slamcheck')
                player.runCommand('playsound roxxane.swordslam2 @a[r=12] ~ ~ ~')
                player.runCommand('playanimation @s animation.darkw_dotv.jetblade.slam_sword_2')
                player.dimension.getEntities({ maxDistance: 5, location: player.location, excludeNames: [player.nameTag], excludeTypes: ['minecraft:item'] }).forEach(mob => {
                    mob.applyDamage(8, {
                        cause: 'entity_attack',
                        damagingProjectile: player,
                        damagingEntity: player
                    })
                })
            }
        }
    })
    event.itemComponentRegistry.registerCustomComponent("darkw_dotv:is_m4rkblades", {
        onUse: e => {
            const player = e.source
            const item = e.itemStack
            const durability = e.itemStack.getComponent('durability')
            const location = player.location

            const equippable = player.getComponent('equippable')
            const Mainhand = equippable.getEquipment('Mainhand')

            const cooldown = world.scoreboard.getObjective('darkw_dotv:m4rkscythecooldown')
            if (!cooldown.getScore(player)) cooldown.setScore(player, 0)

            if (player.isSneaking) {
                // If no property, set
                if (item.getDynamicProperty('darkw_dotv:m4rkscythes_attack_mode') === undefined) {
                    item.setDynamicProperty('darkw_dotv:m4rkscythes_attack_mode', 1)
                    // ! INITIALIZE
                    player.runCommand(`/playsound mark.scythebind @s ~ ~ ~`)
                    player.dimension.spawnParticle('darkw_dotv:frenz_i_dust_blow', location)
                    player.dimension.spawnParticle('darkw_dotv:frenz_i_blow', location)
                    player.playSound('mark.scythebind', { location: location })
                    player.runCommand(`title @s actionbar §dYour vengeance binds to the scythes`)
                    equippable.setEquipment(EquipmentSlot.Mainhand, item)
                    equippable.setEquipment(EquipmentSlot.Mainhand, item)
                    return
                }
                // Initialize Crack Bool
                if (item.getDynamicProperty('darkw_dotv:m4rkscythes_toggle_cracks') === undefined) {
                    item.setDynamicProperty('darkw_dotv:m4rkscythes_toggle_cracks', true)
                    equippable.setEquipment(EquipmentSlot.Mainhand, item)
                }
                // Initialize Camera Bool
                if (item.getDynamicProperty('darkw_dotv:m4rkscythes_toggle_camera') === undefined) {
                    item.setDynamicProperty('darkw_dotv:m4rkscythes_toggle_camera', true)
                    equippable.setEquipment(EquipmentSlot.Mainhand, item)
                }

                switch (item.getDynamicProperty('darkw_dotv:m4rkscythes_attack_mode')) {
                    case 1: {
                        item.setDynamicProperty('darkw_dotv:m4rkscythes_attack_mode', 2)
                        equippable.setEquipment(EquipmentSlot.Mainhand, item)
                        player.runCommand(`title @s actionbar Current Attack - Wide Pinch`)
                        player.playSound('misc.ping', { location: { x: player.location.x, y: player.location.y, z: player.location.z }, volume: 1 })
                        break
                    }
                    case 2: {
                        item.setDynamicProperty('darkw_dotv:m4rkscythes_attack_mode', 3)
                        equippable.setEquipment(EquipmentSlot.Mainhand, item)
                        player.runCommand(`title @s actionbar Current Attack - Overhead Slam`)
                        player.playSound('misc.ping', { location: { x: player.location.x, y: player.location.y, z: player.location.z }, volume: 1 })
                        break
                    }
                    case 3: {
                        item.setDynamicProperty('darkw_dotv:m4rkscythes_attack_mode', 4)
                        equippable.setEquipment(EquipmentSlot.Mainhand, item)
                        player.runCommand(`title @s actionbar Current Attack - Heavy Slam`)
                        player.playSound('misc.ping', { location: { x: player.location.x, y: player.location.y, z: player.location.z }, volume: 1 })
                        break
                    }
                    case 4: {
                        item.setDynamicProperty('darkw_dotv:m4rkscythes_attack_mode', 5)
                        equippable.setEquipment(EquipmentSlot.Mainhand, item)
                        player.runCommand(`title @s actionbar Current Attack - Spin Slash`)
                        player.playSound('misc.ping', { location: { x: player.location.x, y: player.location.y, z: player.location.z }, volume: 1 })
                        break
                    }
                    case 5: {
                        item.setDynamicProperty('darkw_dotv:m4rkscythes_attack_mode', 6)
                        equippable.setEquipment(EquipmentSlot.Mainhand, item)
                        player.runCommand(`title @s actionbar §eWeapon Configuration`)
                        player.playSound('misc.ping', { location: { x: player.location.x, y: player.location.y, z: player.location.z }, volume: 1 })
                        break
                    }
                    case 6: {
                        item.setDynamicProperty('darkw_dotv:m4rkscythes_attack_mode', 1)
                        equippable.setEquipment(EquipmentSlot.Mainhand, item)
                        player.runCommand(`title @s actionbar Current Attack - Wide Swipe`)
                        player.playSound('misc.ping', { location: { x: player.location.x, y: player.location.y, z: player.location.z }, volume: 1 })
                        break
                    }
                }

                return
            }

            // * If NOT sneaking, Attack
            if (!player.isSneaking && cooldown.getScore(player) === 0) {

                // * Blah Blah, Globals
                const player = e.source
                const item = e.itemStack
                const durability = e.itemStack.getComponent('durability')
                const equippable = player.getComponent('equippable')
                const Mainhand = equippable.getEquipment('Mainhand')
                const location = player.location

                // ! If no properties, set. (Player will not have on initial use)
                if (item.getDynamicProperty('darkw_dotv:m4rkscythes_attack_mode') === undefined) {
                    item.setDynamicProperty('darkw_dotv:m4rkscythes_attack_mode', 1)
                    item.setDynamicProperty('darkw_dotv:m4rkscythes_toggle_cracks', true)
                    item.setDynamicProperty('darkw_dotv:m4rkscythes_toggle_camera', true)
                    // ! INITIALIZE
                    player.runCommand(`/playsound mark.scythebind @s ~ ~ ~`)
                    player.dimension.spawnParticle('darkw_dotv:frenz_i_dust_blow', location)
                    player.dimension.spawnParticle('darkw_dotv:frenz_i_blow', location)
                    player.playSound('mark.scythebind', { location: location })
                    player.runCommand(`title @s actionbar §dYour vengeance binds to the scythes`)
                    equippable.setEquipment(EquipmentSlot.Mainhand, item)
                    return
                }

                switch (item.getDynamicProperty('darkw_dotv:m4rkscythes_attack_mode')) {
                    case 1: {

                        // * Camera Toggle Controls
                        if (item.getDynamicProperty('darkw_dotv:m4rkscythes_toggle_camera')) {
                            attack()
                            function attack() {
                                player.camera.setCamera('minecraft:third_person')
                                system.runTimeout(() => {
                                    player.camera.clear()
                                }, 33)
                            }
                        }

                        // Play Animation, Slow player down, cooldown
                        player.runCommand('/playanimation @s animation.darkw_dotv-mrk24.attack1 default 0.2')
                        player.addEffect('slowness', 33, { amplifier: 2, showParticles: false })
                        cooldown.setScore(player, 33)

                        system.runTimeout(() => {
                            const frontMob = player.getEntitiesFromViewDirection({ maxDistance: 4 })
                            if (!frontMob) return
                            player.playSound('mark.slice', { location: { x: player.location.x, y: player.location.y, z: player.location.z }, volume: 1 })
                            frontMob.forEach((m) => {
                                m.entity.applyDamage(12, { cause: "entity_attack", damagingEntity: player, damagingProjectile: player })
                            })
                        }, 15)
                        break
                    }
                    case 2: {

                        // * Camera Toggle Controls
                        if (item.getDynamicProperty('darkw_dotv:m4rkscythes_toggle_camera')) {
                            attack()
                            function attack() {
                                player.camera.setCamera('minecraft:third_person')
                                system.runTimeout(() => {
                                    player.camera.clear()
                                }, 20)
                            }
                        }

                        player.runCommand('/playanimation @s animation.darkw_dotv-mrk24.attack2 default 0.2')
                        player.addEffect('slowness', 20, { amplifier: 2, showParticles: false })
                        cooldown.setScore(player, 20)

                        system.runTimeout(() => {
                            const frontMob = player.getEntitiesFromViewDirection({ maxDistance: 4 })
                            player.playSound('mark.slice', { location: { x: player.location.x, y: player.location.y, z: player.location.z }, volume: 1 })
                            if (!frontMob) return
                            frontMob.forEach((m) => {
                                m.entity.applyDamage(12, { cause: "entity_attack", damagingEntity: player, damagingProjectile: player })
                            })
                        }, 12)
                        break
                    }
                    case 3: {

                        // * Camera Toggle Controls
                        if (item.getDynamicProperty('darkw_dotv:m4rkscythes_toggle_camera')) {
                            attack()
                            function attack() {
                                player.camera.setCamera('minecraft:third_person')
                                system.runTimeout(() => {
                                    player.camera.clear()
                                }, 28)
                            }
                        }


                        player.runCommand('/playanimation @s animation.darkw_dotv-mrk24.attack3 default 0.2')
                        player.addEffect('slowness', 28, { amplifier: 2, showParticles: false })
                        cooldown.setScore(player, 28)

                        system.runTimeout(() => {
                            const frontMobs = player.dimension.getEntities({ maxDistance: 4, location: { x: player.location.x, y: player.location.y, z: player.location.z } })

                            // * Crack Controls
                            if (item.getDynamicProperty('darkw_dotv:m4rkscythes_toggle_cracks')) {
                                player.dimension.spawnEntity('darkw_dotv:m4rk_e', { x: player.location.x, y: player.location.y, z: player.location.z })
                            }
                            player.playSound('mark.slam_s', { location: { x: player.location.x, y: player.location.y, z: player.location.z }, volume: 1 })
                            player.dimension.spawnEntity('darkw_dotv:slamparticle', { x: player.location.x, y: player.location.y, z: player.location.z })

                            if (!frontMobs) return
                            frontMobs.forEach((m) => {
                                m.applyDamage(12, { cause: "entity_attack", damagingEntity: player, damagingProjectile: player })
                            })
                        }, 15)
                        break
                    }
                    case 4: {

                        // * Camera Toggle Controls
                        if (item.getDynamicProperty('darkw_dotv:m4rkscythes_toggle_camera')) {
                            attack()
                            function attack() {
                                player.camera.setCamera('minecraft:third_person')
                                system.runTimeout(() => {
                                    player.camera.clear()
                                }, 40)
                            }
                        }


                        player.runCommand('/playanimation @s animation.darkw_dotv-mrk24.attack4 default 0.2')
                        player.addEffect('slowness', 40, { amplifier: 2, showParticles: false })
                        cooldown.setScore(player, 40)


                        system.runTimeout(() => {
                            player.playSound('mark.slam_h', { location: { x: player.location.x, y: player.location.y, z: player.location.z }, volume: 1 })
                            const frontMobs = player.dimension.getEntities({ maxDistance: 4, location: { x: player.location.x, y: player.location.y, z: player.location.z } })
                            player.dimension.spawnEntity('darkw_dotv:slamparticle', { x: player.location.x, y: player.location.y, z: player.location.z })

                            // * Crack Controls
                            if (item.getDynamicProperty('darkw_dotv:m4rkscythes_toggle_cracks')) {
                                player.dimension.spawnEntity('darkw_dotv:m4rk_e', { x: player.location.x + 4, y: player.location.y, z: player.location.z })
                                player.dimension.spawnEntity('darkw_dotv:m4rk_e', { x: player.location.x + 8, y: player.location.y, z: player.location.z })
                                player.dimension.spawnEntity('darkw_dotv:m4rk_e', { x: player.location.x - 4, y: player.location.y, z: player.location.z })
                                player.dimension.spawnEntity('darkw_dotv:m4rk_e', { x: player.location.x - 8, y: player.location.y, z: player.location.z })
                                player.dimension.spawnEntity('darkw_dotv:m4rk_e', { x: player.location.x, y: player.location.y, z: player.location.z + 4 })
                                player.dimension.spawnEntity('darkw_dotv:m4rk_e', { x: player.location.x, y: player.location.y, z: player.location.z + 8 })
                                player.dimension.spawnEntity('darkw_dotv:m4rk_e', { x: player.location.x, y: player.location.y, z: player.location.z - 4 })
                                player.dimension.spawnEntity('darkw_dotv:m4rk_e', { x: player.location.x, y: player.location.y, z: player.location.z - 8 })
                                player.dimension.spawnEntity('darkw_dotv:m4rk_e', { x: player.location.x, y: player.location.y, z: player.location.z })
                            }

                            if (!frontMobs) return
                            frontMobs.forEach((m) => {
                                m.applyDamage(12, { cause: "entity_attack", damagingEntity: player, damagingProjectile: player })
                            })
                        }, 23)
                        break
                    }
                    case 5: {

                        // * Camera Toggle Controls
                        if (item.getDynamicProperty('darkw_dotv:m4rkscythes_toggle_camera')) {
                            attack()

                            function attack() {
                                player.camera.setCamera('minecraft:third_person')
                                system.runTimeout(() => {
                                    player.camera.clear()
                                }, 11)
                            }
                        }


                        player.runCommand('/playanimation @s animation.darkw_dotv-mrk24.attack5 default 0.2')
                        player.addEffect('speed', 11, { amplifier: 2, showParticles: false })
                        cooldown.setScore(player, 11)

                        const frontMobs = player.dimension.getEntities({ maxDistance: 4, location: { x: player.location.x, y: player.location.y, z: player.location.z } })
                        player.playSound('mark.slice', { location: { x: player.location.x, y: player.location.y, z: player.location.z }, volume: 1 })

                        if (!frontMobs) return
                        frontMobs.forEach((m) => {
                            m.applyDamage(4, { cause: "entity_attack", damagingEntity: player, damagingProjectile: player })
                        })


                        break
                    }
                    case 6: {
                        let c = new ModalFormData
                        c.title('Weapon Configuration')
                        c.label('This weapon has multiple optional settings, please pick how you would like it to behave.')
                        c.divider()
                        c.toggle('Toggle Cracks', { defaultValue: item.getDynamicProperty('darkw_dotv:m4rkscythes_toggle_cracks'), tooltip: 'Giant cracks pop out of the ground and explode when you perform a slam attack, these may be annoying in certain situations.' })
                        c.toggle('Toggle Camera Animations', { defaultValue: item.getDynamicProperty('darkw_dotv:m4rkscythes_toggle_camera'), tooltip: 'Optional toggle that shows your model performing the attacks. If this mechanic is conflicting with other Add-Ons it can be shut off here.' })
                        c.divider()
                        c.submitButton('Submit')
                        c.show(player).then(r => {
                            if (r.canceled) return

                            item.setDynamicProperty('darkw_dotv:m4rkscythes_toggle_cracks', r.formValues[2])
                            item.setDynamicProperty('darkw_dotv:m4rkscythes_toggle_camera', r.formValues[3])
                            equippable.setEquipment(EquipmentSlot.Mainhand, item)
                        })
                        break
                    }
                }
                return
            }
        }
    })
})

// ! Hit Block Weapons
world.afterEvents.entityHitBlock.subscribe(ev => {
    const player = ev.damagingEntity

    let eq = player.getComponent('equippable')
    let mh = eq.getEquipmentSlot('Mainhand')

    if (!mh.getItem()) return
    const item = mh.getItem()

    switch (item.typeId) {
        // * (Deathblade) Cryblade
        case "darkw_dotv:weapon_deathblade": {
            let d = item.getComponent('durability')

            if (item.getComponent('cooldown').getCooldownTicksRemaining(player) != 0) return

            player.runCommand('playsound deathblade.flame_player @s ~ ~ ~')
            player.runCommand('particle darkw_dotv:deathyslam2 ~ ~ ~')
            player.runCommand('particle darkw_dotv:deathyslam1 ~ ~ ~')
            player.dimension.getEntities({ maxDistance: 7, excludeNames: [player.nameTag], location: player.location }).forEach(mob => {
                mob.applyDamage(6)
                mob.setOnFire(5)
            })

            item.getComponent('cooldown').startCooldown(player)
            if (player.getGameMode() != 'Creative') {

                let r = Math.floor(Math.random() * 185)
                d.damage += r

                if (d.damage + r > d.maxDurability) {
                    player.runCommand('/playsound random.break @s ~ ~ ~')
                    mh.setItem(new ItemStack('air', 1))
                }
                else {
                    mh.setItem(item)
                }
            }
        }
    }
})

// *
// *
// *
// *
// *
// * Kunai Shot
function KunaiShoot(player) {
    const playerViewDirection = player.getViewDirection();
    const velocityMultiplier = 2.0;

    const projectile = player.dimension.spawnEntity("darkw_dotv:extorris_proj", {
        x: player.location.x + playerViewDirection.x,
        y: player.location.y + 1 + playerViewDirection.y,
        z: player.location.z + playerViewDirection.z,
    });

    const projectileComponent = projectile.getComponent(EntityComponentTypes.Projectile);
    const { x: vx, y: vy, z: vz } = player.getViewDirection();

    projectileComponent.shoot({
        x: vx * velocityMultiplier,
        y: vy * velocityMultiplier,
        z: vz * velocityMultiplier
    });
    projectileComponent.owner = player;
}


// ! Entity Hurt
world.afterEvents.entityHurt.subscribe(event => {
    if (event.damageSource.damagingEntity?.typeId === 'minecraft:player') {
        const player = event.damageSource.damagingEntity

        const equipment = player.getComponent('equippable');
        if (!equipment) return
        const mainHand = equipment.getEquipment("Mainhand");
        if (!mainHand) return
        let durability = mainHand.getComponent('durability')

        if (mainHand.typeId === 'darkw_dotv:weapon_m4rk') {
            let bonusMrkDamage = 0
            if (player.runCommand('/testfor @s[hasitem={item=darkw_dotv:m4rk_helmet, location=slot.armor.head}]').successCount) bonusMrkDamage += 2
            if (player.runCommand('/testfor @s[hasitem={item=darkw_dotv:m4rk_chestplate, location=slot.armor.chest}]').successCount) bonusMrkDamage += 2
            if (player.runCommand('/testfor @s[hasitem={item=darkw_dotv:m4rk_leggings, location=slot.armor.legs}]').successCount) bonusMrkDamage += 2
            if (player.runCommand('/testfor @s[hasitem={item=darkw_dotv:m4rk_boots, location=slot.armor.feet}]').successCount) bonusMrkDamage += 2
            event.hurtEntity.applyDamage(bonusMrkDamage, {
                cause: 'entity_attack',
                damagingEntity: player,
                damagingProjectile: player
            })
        }
        // * Chaos Armor Set Bonus
        if (player.hasTag('darkw_dotv:chaos_powerhungry')) {
            let hunger = player.getComponent('player.hunger')
            let health = player.getComponent('health')
            let bonusHunger = hunger.effectiveMax - hunger.currentValue
            event.hurtEntity.applyDamage(bonusHunger, {
                cause: 'entity_attack',
                damagingProjectile: player,
                damagingEntity: player
            })
            let lifeSteal = hunger.currentValue === 0 ? 0.050 : 0.025
            try { health.setCurrentValue(health.currentValue + (event.damage * lifeSteal)) }
            catch { }

        }
        // * Chaos Armor Set Bonus
        if (mainHand.typeId === 'darkw_dotv:weapon_yinyang' && mainHand.getDynamicProperty('darkw_dotv:limboselect') === 'angel') {
            let health = player.getComponent('health')
                            let souls = world.scoreboard.getObjective('darkw_dotv:limbosouls')
            let soulSteal = 0.01 * souls.getScore(player) / 10
            souls.setScore(player, souls.getScore(player) - Math.floor(souls.getScore(player) / 10))
            if (health.currentValue + (event.damage * soulSteal) > health.effectiveMax) {
                health.setCurrentValue(health.effectiveMax)
            }
            else health.setCurrentValue(health.currentValue + (event.damage * soulSteal))
            try {  }
            catch { }

        }
    }

})

// ! On Button Press
world.afterEvents.playerButtonInput.subscribe(ev => {
    if (ev.button === 'Crouch', ev.newButtonState === 'Pressed') {
        // YANG CROUCh
    }
})

// ! On Mob Kill
world.afterEvents.entityDie.subscribe(ev => {
    if (ev.damageSource.damagingEntity?.typeId === 'minecraft:player') {
        let player = ev.damageSource.damagingEntity
        let inv = player.getComponent('inventory')
        for (let s = 0; s < inv.inventorySize; s++) {

            // ! Regenerate Kunai on Kill.
            if (inv.container.getItem(s)?.typeId != 'darkw_dotv:kunai_puppet') continue
            let item = inv.container.getSlot(s).getItem()
            let d = item.getComponent('durability')

            if (d.damage - 20 < 0) {
                d.damage == 0
                inv.container.setItem(s, item)
            }
            else {
                d.damage -= 20
                inv.container.setItem(s, item)
            }
        }
    }
})



// ! -=======- CUSTOM BOWS -=======-
// !
// !
// !
// !
// !
world.afterEvents.itemStartUse.subscribe(ev => {
    const player = ev.source
    const item = ev.itemStack
    const ran = Math.floor(Math.random() * 8)

    let hyCheck = player.runCommand('/testfor @s[hasitem={item=arrow, quantity=1..}]').successCount
    switch (item.typeId) {
        // *
        // *
        // *
        // *
        // *
        // * Hybow
        case "darkw_dotv:bow_roxxane": {
            player.playAnimation(player.getComponent('equippable').getEquipmentSlot(EquipmentSlot.Mainhand).getItem() ? "animation.custom_bow.player.bow.left_item" : "animation.darkw_dotv.player.custom_bow", { stopExpression: "!q.is_using_item" });
            player.addTag('darkw_dotv:is_using_hyBow')

            system.runTimeout(() => {

                hyShot(player)
            }, 30)

            async function hyShot(player) {
                while (player.hasTag('darkw_dotv:is_using_hyBow') && hyCheck) {
                    const dur = item.getComponent('durability')
                    hyCheck = (player.runCommand('/testfor @s[hasitem={item=arrow, quantity=1..}]').successCount)

                    await system.waitTicks(1)

                    // * On Stop
                    if (!player.hasTag('darkw_dotv:is_using_hyBow') || !hyCheck) {
                        if (!hyCheck) {
                        }
                        return
                    }
                    player.runCommand('/clear @s arrow 0 1')

                    // * Shoot
                    const playerViewDirection = player.getViewDirection();
                    const velocityMultiplier = 2.0;

                    const projectile = player.dimension.spawnEntity("minecraft:arrow", {
                        x: player.location.x + playerViewDirection.x,
                        y: player.location.y + 1.65 + playerViewDirection.y,
                        z: player.location.z + playerViewDirection.z,
                    });

                    const projectileComponent = projectile.getComponent(EntityComponentTypes.Projectile);
                    const { x: vx, y: vy, z: vz } = player.getViewDirection();

                    projectileComponent.shoot({
                        x: vx * velocityMultiplier,
                        y: vy * velocityMultiplier,
                        z: vz * velocityMultiplier
                    });
                    projectileComponent.owner = player;

                    // * Durability
                    if (player.getGameMode() != 'Creative') {
                        if (dur.damage + ran >= dur.maxDurability) {
                            player.runCommand('/playsound random.break @s ~~~')
                            player.getComponent('equippable').setEquipment(EquipmentSlot.Mainhand, new ItemStack('air'))
                        }
                        else {
                            dur.damage += ran
                            player.getComponent('equippable').setEquipment(EquipmentSlot.Mainhand, item)
                        }
                    }
                }
            }
            break
        }
    }
})
world.afterEvents.itemStopUse.subscribe(ev => {
    const player = ev.source
    const item = ev.itemStack
    if (!item) return
    switch (item.typeId) {
        // *
        // *
        // *
        // *
        // *
        // * Hybow Stop
        case "darkw_dotv:bow_roxxane": {
            player.removeTag('darkw_dotv:is_using_hyBow')
            break
        }
    }
})