import { world, system, ItemStack, EquipmentSlot, EntityComponentTypes, ItemCooldownComponent, BlockVolume, Block, BlockPermutation, Player } from "@minecraft/server"

system.run(() => {
    const globalscoreboard = world.scoreboard
})

// Import Subcores
import "./subcores/tick.js"
import "./subcores/weapons.js"
import "./subcores/entities.js"
import "./subcores/lore.js"
import "./subcores/charms.js"

// Detect Sneaking
system.runInterval(() => {
    for (const player of world.getAllPlayers()) {
        if (player.isSneaking) {
            player.addTag('darkw_dotv:is_sneaking');
        }
        else if (!player.isSneaking) {
            player.removeTag('darkw_dotv:is_sneaking');
        }
    }
})

// ! Runes
// !
// !
// !
system.beforeEvents.startup.subscribe(ev => {
    ev.blockComponentRegistry.registerCustomComponent("darkw_dotv:block_rune", {
        onPlace: e => {
            const block = e.block
            switch (block.typeId) {
                case "darkw_dotv:rune_alatine": {
                    e.dimension.playSound('misc.rune.generic.mobsummon', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    e.dimension.spawnParticle('darkw_dotv:alatar_r_summonblow', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    break
                }
                case "darkw_dotv:rune_valkyrie": {
                    e.dimension.spawnParticle('darkw_dotv:puppetrunesummon', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    e.dimension.playSound('misc.rune.generic', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    break
                }
                case "darkw_dotv:rune_godslayer": {
                    e.dimension.spawnParticle('darkw_dotv:puppetrunesummon', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    e.dimension.playSound('misc.rune.generic', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    break
                }
                case "darkw_dotv:rune_zappy": {
                    e.dimension.spawnParticle('darkw_dotv:puppetrunesummon', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    e.dimension.playSound('misc.rune.generic', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    e.dimension.playSound('misc.rune.generic', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    break
                }
                case "darkw_dotv:rune_zappy_alt": {
                    e.dimension.spawnParticle('darkw_dotv:puppetrunesummon_alt', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    e.dimension.playSound('misc.rune.generic', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    e.dimension.playSound('misc.rune.generic', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    break
                }
                case "darkw_dotv:rune_voidburn": {
                    e.dimension.playSound('generic.rune01', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    break
                }
                case "darkw_dotv:rune_voidburn_alt": {
                    e.dimension.playSound('generic.rune01', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    break
                }
                case "darkw_dotv:rune_purify": {
                    e.dimension.playSound('generic.rune01', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    break
                }
                case "darkw_dotv:rune_boom": {
                    e.dimension.spawnParticle('darkw_dotv:genrune_boom_boom', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    e.dimension.playSound('random.fuse', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    break
                }
            }
        },
        onTick: e => {
            const block = e.block
            let tick = block.permutation.getState('darkw_dotv:runetick')
            block.setPermutation(block.permutation.withState('darkw_dotv:runetick', tick + 1))

            switch (block.typeId) {
                // * Base Rune
                // * -
                // * Alatar Rune
                case "darkw_dotv:rune_alatine": {
                    if (tick == 10) {
                        e.dimension.spawnParticle('darkw_dotv:alatar_r_summonblow', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                        e.dimension.spawnEntity('darkw_dotv:alatine', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                        e.dimension.playSound('generic.rune02', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    }
                    break
                }
                // * Valkyrie Rune
                case "darkw_dotv:rune_valkyrie": {
                    if (tick < 10) e.dimension.spawnParticle('darkw_dotv:puppetvalkyrie_linger', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    if (tick == 10) {
                        e.dimension.spawnParticle('darkw_dotv:puppetvalk', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                        e.dimension.spawnParticle('darkw_dotv:puppetvalk_base', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                        e.dimension.spawnEntity('darkw_dotv:extorris_e', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                        e.dimension.playSound('misc.rune.generic.mobsummon', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    }
                    break
                }
                // * Godslayer Alatar Rune
                case "darkw_dotv:rune_godslayer": {
                    if (tick < 10) e.dimension.spawnParticle('darkw_dotv:puppetgod_linger', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    if (tick == 10) {
                        e.dimension.spawnParticle('darkw_dotv:puppetgod', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                        e.dimension.spawnParticle('darkw_dotv:puppetgod_base', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                        e.dimension.spawnEntity('darkw_dotv:extorris_healer', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                        e.dimension.playSound('misc.rune.generic.mobsummon', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    }
                    break
                }
                // * Zappy Rune
                case "darkw_dotv:rune_zappy": {
                    if (tick < 10) e.dimension.spawnParticle('darkw_dotv:puppetzappy_linger', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    if (tick == 10) {
                        e.dimension.spawnParticle('darkw_dotv:puppetzappy_base', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                        e.dimension.spawnParticle('darkw_dotv:puppetzappy', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                        e.dimension.playSound('misc.thepuppet.zappy', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                        block.dimension.getEntitiesAtBlockLocation(block.location).forEach(m => {
                            m.applyDamage(40)
                        })
                    }
                    break
                }
                // * Alt Zappy Rune
                case "darkw_dotv:rune_zappy_alt": {
                    if (tick < 10) e.dimension.spawnParticle('darkw_dotv:puppetzappy_linger_alt', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    if (tick == 10) {
                        e.dimension.spawnParticle('darkw_dotv:puppetzappy_base_alt', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                        e.dimension.spawnParticle('darkw_dotv:puppetzappy_alt', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                        e.dimension.playSound('misc.thepuppet.zappy', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                        block.dimension.getEntitiesAtBlockLocation(block.location).forEach(m => {
                            m.applyDamage(40)
                        })
                    }
                    break
                }
                // * Voidburn Rune
                case "darkw_dotv:rune_voidburn": {
                    e.dimension.spawnParticle('darkw_dotv:genrune_wither_place', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    e.dimension.spawnParticle('darkw_dotv:genrune_wither_linger', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    block.dimension.getEntitiesAtBlockLocation(block.location).forEach(e => {
                        e.addEffect('wither', 40, { amplifier: 1 })
                    })
                    if (tick == 10) {
                        if (tick == 10) e.dimension.spawnParticle('darkw_dotv:genrune_wither_place', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                        e.dimension.playSound('generic.rune02', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    }
                    break
                }
                // * Voidburn Rune Alt
                case "darkw_dotv:rune_voidburn_alt": {
                    e.dimension.spawnParticle('darkw_dotv:genrune_wither_ring', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    block.dimension.getEntities({ location: block.location, maxDistance: 1.5 }).forEach(e => {
                        e.addEffect('wither', 40, { amplifier: 3 })
                    })
                    if (tick == 10) {
                        if (tick == 10) e.dimension.spawnParticle('darkw_dotv:genrune_wither_place', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                        e.dimension.playSound('generic.rune02', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    }
                    break
                }
                // * Purify Rune
                case "darkw_dotv:rune_purify": {
                    e.dimension.spawnParticle('darkw_dotv:alatar_r_clearrune_instant', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    block.dimension.getEntitiesAtBlockLocation(block.location).forEach(e => {
                        e.runCommand('effect @s clear')
                    })
                    if (tick == 10) {
                        e.dimension.playSound('generic.rune02', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    }
                    break
                }
                // * Boom Rune
                case "darkw_dotv:rune_boom": {
                    e.dimension.spawnParticle('darkw_dotv:genrune_boom_linger', { x: block.location.x + 0.5, y: block.location.y, z: block.location.z + 0.5 })
                    if (tick == 10) e.block.dimension.createExplosion(block.location, 3.5, { breaksBlocks: false, source: block })
                    break
                }
            }
            if (tick == 10) e.dimension.setBlockType(block.location, 'minecraft:air')
        }
    })
})

// ! Script Events
// !
// !
// !
system.afterEvents.scriptEventReceive.subscribe(event => {
    const entity = event.sourceEntity
    const loc = event.sourceEntity.location
    switch (event.id) {
        // *
        // *
        // *
        // * Spawn Alatar Rune
        case "darkw_dotv:spawn_rune-alatar": {
            let runeList = [
                'darkw_dotv:rune_alatine',
                'darkw_dotv:rune_boom',
                'darkw_dotv:rune_purify',
                'darkw_dotv:rune_voidburn',
            ]
            let rune = runeList[Math.floor(Math.random() * runeList.length)]
            system.runTimeout(() => {loopRuneAlatar()}, 20)

            async function loopRuneAlatar() {
                for (let l = 0; l < 6; l++) {
                    await system.waitTicks(3)
                    let BV = new BlockVolume({ x: loc.x + 3, y: loc.y + 2, z: loc.z + 3 }, { x: loc.x - 9, y: loc.y - 1, z: loc.z - 9 })
                    let getBlocks = entity.dimension.getBlocks(BV, { excludeTypes: ['minecraft:air'] }, true)
                    let blockcords = []

                    for (let cords of getBlocks.getBlockLocationIterator()) {
                        const block = entity.dimension.getBlock(cords)
                        if (block.above(1).typeId != 'minecraft:air' || block.typeId.includes('rune')) continue
                        blockcords.push(cords)
                    }

                    let ranCord = blockcords[Math.floor(Math.random() * blockcords.length)]
                    entity.dimension.setBlockType({ x: ranCord.x, y: ranCord.y + 1, z: ranCord.z }, rune)
                }
            }
        break
        }
        // *
        // *
        // *
        // * Void Totem Tick
        case "darkw_dotv:void_totem_tick": {
            let offhand = entity.getComponent('equippable').getEquipment('Offhand')
            if (!offhand.getDynamicProperty('darkw_dotv:void_totem_data')) {
                offhand.setDynamicProperty('darkw_dotv:void_totem_data', entity.location)
                entity.getComponent('equippable').setEquipment(EquipmentSlot.Offhand, offhand)
                return
            }
            let sBlock = entity.getBlockStandingOn()
            if (!sBlock) return
            offhand.setDynamicProperty('darkw_dotv:void_totem_data', entity.location)
            entity.getComponent('equippable').setEquipment(EquipmentSlot.Offhand, offhand)


        }
            break
        // *
        // *
        // *
        // * Spawn Extorris Rune
        case "darkw_dotv:spawn_rune-extorris": {
            let punish = 0
            let runeList = [
                'darkw_dotv:rune_valkyrie',
                'darkw_dotv:rune_godslayer',
                'darkw_dotv:rune_zappy',
                'darkw_dotv:rune_zappy',
                'darkw_dotv:rune_zappy',
            ]
            let rune = runeList[Math.floor(Math.random() * runeList.length)]
            if (rune === 'darkw_dotv:rune_valkyrie') punish += 6

            loopRuneExtorris()
            async function loopRuneExtorris() {
                for (let l = 0; l < 9 - punish; l++) {
                    await system.waitTicks(3)
                    let BV = new BlockVolume({ x: loc.x + 4, y: loc.y + 2, z: loc.z + 4 }, { x: loc.x - 4, y: loc.y - 1, z: loc.z - 4 })
                    let getBlocks = entity.dimension.getBlocks(BV, { excludeTypes: ['minecraft:air'] }, true)
                    let blockcords = []

                    for (let cords of getBlocks.getBlockLocationIterator()) {
                        const block = entity.dimension.getBlock(cords)
                        if (block.above(1).typeId != 'minecraft:air' || block.typeId.includes('rune')) continue
                        blockcords.push(cords)
                    }

                    let ranCord = blockcords[Math.floor(Math.random() * blockcords.length)]
                    entity.dimension.setBlockType({ x: ranCord.x, y: ranCord.y + 1, z: ranCord.z }, rune)
                    if (rune === 'darkw_dotv:rune_godslayer') return
                }
            }
        }
            break
        case "darkw_dotv:agetoCastSpawn": {
            system.runTimeout(() => {
                switch (entity.getProperty('darkw_dotv:cast_type')) {
                    case 1: {
                        entity.runCommand('/scriptevent darkw_dotv:spawn_rune-agetomagala-zappy')
                        break
                    }
                    case 2: {
                        entity.runCommand('/scriptevent darkw_dotv:spawn_rune-agetomagala-boom')
                        break
                    }
                    case 3: {
                        entity.runCommand('/scriptevent darkw_dotv:spawn_rune-agetomagala-burn')
                        break
                    }
                }
            }, 30)
            break
        }
        case "darkw_dotv:puppethealer_despawn": {
            entity.dimension.spawnParticle('darkw_dotv:puppetgod', { x: entity.location.x + 0.5, y: entity.location.y, z: entity.location.z + 0.5 })
            entity.dimension.spawnParticle('darkw_dotv:puppetgod_base', { x: entity.location.x + 0.5, y: entity.location.y, z: entity.location.z + 0.5 })
            entity.dimension.playSound('misc.rune.generic.mobsummon', { x: entity.location.x + 0.5, y: entity.location.y, z: entity.location.z + 0.5 })
            entity.remove()
            break
        }
        // * Ageto-Magala Rune, Boom
        case "darkw_dotv:spawn_rune-agetomagala-boom": {
            loopRuneExtorris()
            async function loopRuneExtorris() {
                for (let l = 0; l < 12; l++) {
                    await system.waitTicks(3)
                    let BV = new BlockVolume({ x: loc.x + 4, y: loc.y + 2, z: loc.z + 5 }, { x: loc.x - 5, y: loc.y - 1, z: loc.z - 4 })
                    let getBlocks = entity.dimension.getBlocks(BV, { excludeTypes: ['minecraft:air'] }, true)
                    let blockcords = []

                    for (let cords of getBlocks.getBlockLocationIterator()) {
                        const block = entity.dimension.getBlock(cords)
                        if (block.above(1).typeId != 'minecraft:air' || block.typeId.includes('rune')) continue
                        blockcords.push(cords)
                    }

                    let ranCord = blockcords[Math.floor(Math.random() * blockcords.length)]
                    entity.dimension.setBlockType({ x: ranCord.x, y: ranCord.y + 1, z: ranCord.z }, 'darkw_dotv:rune_boom')
                }
            }
        }
            break
        // * Ageto-Magala Rune, Lightning
        case "darkw_dotv:spawn_rune-agetomagala-zappy": {
            loopRuneExtorris()
            async function loopRuneExtorris() {
                for (let l = 0; l < 17; l++) {
                    await system.waitTicks(3)
                    let BV = new BlockVolume({ x: loc.x + 3, y: loc.y + 2, z: loc.z + 4 }, { x: loc.x - 3, y: loc.y - 1, z: loc.z - 9 })
                    let getBlocks = entity.dimension.getBlocks(BV, { excludeTypes: ['minecraft:air'] }, true)
                    let blockcords = []

                    for (let cords of getBlocks.getBlockLocationIterator()) {
                        const block = entity.dimension.getBlock(cords)
                        if (block.above(1).typeId != 'minecraft:air' || block.typeId.includes('rune')) continue
                        blockcords.push(cords)
                    }

                    let ranCord = blockcords[Math.floor(Math.random() * blockcords.length)]
                    entity.dimension.setBlockType({ x: ranCord.x, y: ranCord.y + 1, z: ranCord.z }, 'darkw_dotv:rune_zappy_alt')
                }
            }
        }
            break
        // * Ageto-Magala Rune, Ash
        case "darkw_dotv:spawn_rune-agetomagala-burn": {
            loopRuneExtorris()
            async function loopRuneExtorris() {
                for (let l = 0; l < 9; l++) {
                    await system.waitTicks(3)
                    let BV = new BlockVolume({ x: loc.x + 3, y: loc.y + 2, z: loc.z + 4 }, { x: loc.x - 3, y: loc.y - 1, z: loc.z - 9 })
                    let getBlocks = entity.dimension.getBlocks(BV, { excludeTypes: ['minecraft:air'] }, true)
                    let blockcords = []

                    for (let cords of getBlocks.getBlockLocationIterator()) {
                        const block = entity.dimension.getBlock(cords)
                        if (block.above(1).typeId != 'minecraft:air' || block.typeId.includes('rune')) continue
                        blockcords.push(cords)
                    }

                    let ranCord = blockcords[Math.floor(Math.random() * blockcords.length)]
                    entity.dimension.setBlockType({ x: ranCord.x, y: ranCord.y + 1, z: ranCord.z }, 'darkw_dotv:rune_voidburn_alt')
                }
            }
        }
            break
        case "darkw_dotv:on_death_adjust": {
            const source = event.sourceEntity
            source.clearVelocity()
            break
        }
        case "darkw_dotv:deathblade_sword_victim": {
            const victim = event.sourceEntity
            victim.setOnFire(5)
            victim.addEffect('wither', 100, { amplifier: 5 })
            break
        }
        case "darkw_dotv:extorris-random_teleport": {
            let BV = new BlockVolume({ x: loc.x + 4, y: loc.y + 2, z: loc.z + 4 }, { x: loc.x - 5, y: loc.y - 1, z: loc.z - 5 })
            let getBlocks = entity.dimension.getBlocks(BV, { excludeTypes: ['minecraft:air'] }, true)
            let blockcords = []

            for (let cords of getBlocks.getBlockLocationIterator()) {
                const block = entity.dimension.getBlock(cords)
                if (block.above(1).typeId != 'minecraft:air') continue
                blockcords.push(cords)
            }

            let ran = Math.floor(Math.random() * blockcords.length)
            let ranCord = blockcords[ran]
            entity.runCommand('playsound misc.thepuppet.zappy @a[r=7] ~~~')
            entity.dimension.spawnParticle('darkw_dotv:puppetteleport', { x: entity.location.x + 0.5, y: entity.location.y, z: entity.location.z + 0.5 })
            system.runTimeout(() => {
                entity.dimension.spawnParticle('darkw_dotv:puppetteleport', { x: ranCord.x + 0.5, y: ranCord.y + 1, z: ranCord.z + 0.5 })
                entity.tryTeleport({ x: ranCord.x, y: ranCord.y + 1, z: ranCord.z })
            }, 1)
            break

        }
        case "darkw_dotv:rox-random_teleport": {
            let BV = new BlockVolume({ x: loc.x + 5, y: loc.y + 2, z: loc.z + 5 }, { x: loc.x - 5, y: loc.y - 1, z: loc.z - 5 })
            let getBlocks = entity.dimension.getBlocks(BV, { excludeTypes: ['minecraft:air'] }, true)
            let blockcords = []

            for (let cords of getBlocks.getBlockLocationIterator()) {
                const block = entity.dimension.getBlock(cords)
                if (block.above(1).typeId != 'minecraft:air') continue
                blockcords.push(cords)
            }

            let ran = Math.floor(Math.random() * blockcords.length)
            let ranCord = blockcords[ran]

            const teleBlock = entity.dimension.getBlock(ranCord)
            entity.tryTeleport({ x: ranCord.x, y: ranCord.y + 1, z: ranCord.z })
            break

        }
        case "darkw_dotv:pris-prismaticist": {
            let BV = new BlockVolume({ x: loc.x + 9, y: loc.y + 2, z: loc.z + 9 }, { x: loc.x - 9, y: loc.y - 1, z: loc.z - 9 })
            let getBlocks = entity.dimension.getBlocks(BV, { excludeTypes: ['minecraft:air'] }, true)
            let blockcords = []

            for (let cords of getBlocks.getBlockLocationIterator()) {
                const block = entity.dimension.getBlock(cords)
                if (block.above(1).typeId != 'minecraft:air') continue
                blockcords.push(cords)
            }

            let ran = Math.floor(Math.random() * blockcords.length)
            let ranCord = blockcords[ran]

            entity.dimension.spawnEntity('darkw_dotv:prismatica_e', { x: ranCord.x, y: ranCord.y + 1, z: ranCord.z })
            break

        }
        case "darkw_dotv:dubby-buff": {
            let ranBuffList = [
                "strength",
                "speed",
                "regeneration",
                "resistance"
            ]
            let ranStr = ranBuffList[Math.floor(Math.random() * ranBuffList.length)]
            entity.addEffect(ranStr, 200, {
                amplifier: 2,
                showParticles: true
            })
            entity.dimension.spawnParticle(`darkw_dotv:dubby-buff_${ranStr}`, { x: entity.location.x, y: entity.location.y, z: entity.location.z })
            break
        }
        case "darkw_dotv:faevia-dash": {
            let pn1 = Math.random() < 0.5 ? "+" : "-"
            let pn2 = Math.random() < 0.5 ? "+" : "-"
            let xGo = Math.random() * 2
            let zGo = Math.random() * 2
            let goTick = 0
            entity.dimension.spawnParticle('darkw_dotv:faevia_dashhit', entity.location)
            let dir = entity.getViewDirection()
            try {
                entity.applyImpulse({ x: parseFloat(Math.sqrt(dir.x) ** 2), y: dir.y + 0.55, z: parseFloat(Math.sqrt(dir.z) ** 2) })
            }
            catch {}
            system.runTimeout(() => {
                entity.runCommand('/playanimation @s animation.darkw_dotv-primordial_prismatica.dash default 0.2 "query.is_on_ground || query.state_time >= 4"')
                dashTick()
            }, 1)

            async function dashTick() {
                while (!entity.isOnGround) {
                    if (goTick > 40) return
                    await system.waitTicks(1)
                    entity.dimension.spawnParticle('darkw_dotv:faevia_dashtrail', entity.location)
                    goTick++
                }
                entity.dimension.spawnParticle('darkw_dotv:faevia_dashhit', entity.location)
                return
            }
            break
        }
        case "darkw_dotv:faevia-dash-weapon": {
            let goTick = 0

            let dir = entity.getViewDirection()
            const vS = 0.65;

            entity.applyKnockback({ x: dir.x * 4.5, z: dir.z * 4.5 }, vS)

            system.runTimeout(() => {
                entity.runCommand('/playanimation @s animation.darkw_dotv-primordial_prismatica.dash default 0.2 "query.is_on_ground || query.state_time >= 4"')
                dashTick()
            }, 1)

            async function dashTick() {
                while (!entity.isOnGround) {
                    if (goTick > 40) return
                    await system.waitTicks(1)
                    entity.dimension.spawnParticle('darkw_dotv:faevia_dashtrail', entity.location)
                    goTick++
                }
                entity.dimension.spawnParticle('darkw_dotv:faevia_dashhit', entity.location)
                return
            }
            break
        }
        case "darkw_dotv:ageto-dash": {
            if (entity.typeId === 'darkw_dotv:ageto') {
                entity.dimension.spawnEntity('darkw_dotv:ageto_e', entity.location)
                entity.dimension.spawnEntity('darkw_dotv:ageto_e', entity.location)
                entity.dimension.spawnEntity('darkw_dotv:ageto_e', entity.location)
                entity.dimension.spawnEntity('darkw_dotv:ageto_e', entity.location)
            }
            system.runTimeout(() => {
                try {
                    if (!entity.getProperty('darkw_dotv:phantom_mode')) {
                        entity.setProperty('darkw_dotv:phantom_mode', true)
                    }
                }
                catch {

                }
            }, 5)
            let pn1 = Math.random() < 0.5 ? "+" : "-"
            let pn2 = Math.random() < 0.5 ? "+" : "-"
            let xGo = Math.random() * 2
            let zGo = Math.random() * 2
            let goTick = 0
            entity.dimension.spawnParticle('darkw_dotv:agetopoof', entity.location)
            entity.applyImpulse({ x: parseFloat(`${pn1}${xGo}`), y: 0.7, z: parseFloat(`${pn2}${zGo}`) })
            system.runTimeout(() => {
                entity.runCommand('/playanimation @s animation.darkw_dotv-primordial_prismatica.dash default 0.2 "query.is_on_ground || query.state_time >= 4"')
                dashTick()
            }, 1)

            async function dashTick() {
                while (!entity.isOnGround) {
                    await system.waitTicks(1)
                    try {
                        entity.dimension.spawnParticle('darkw_dotv:agetotrail', entity.location)
                    }
                    catch { }
                    if (goTick > 40) return
                    goTick++
                }
                entity.dimension.spawnParticle('darkw_dotv:agetopoof', entity.location)
                return
            }
            break
        }
    }
})

// ! Disciple Defeated
world.afterEvents.entityDie.subscribe(ev => {
    if (ev.deadEntity.typeId === 'darkw_dotv:roxxane_rune_entity_fallbomb') ev.deadEntity.dimension.createExplosion(ev.deadEntity.location, 3, {breaksBlocks: false, source: ev.deadEntity, causesFire: false})
    if (ev.deadEntity.typeId === 'darkw_dotv:roxxane_rune_entity_fallbomb_final') ev.deadEntity.dimension.createExplosion(ev.deadEntity.location, 3, {breaksBlocks: false, source: ev.deadEntity, causesFire: false})
        let entity = ev.deadEntity
    if (ev.deadEntity) {
        try {
            let families = entity.getComponent('type_family').getTypeFamilies()
            if (families.includes('deathanim_disciple')) {
                entity.runCommand('function darkw/dotv/defeat/disciple');
                entity.remove();
                return
            }
            if (families.includes('deathanim_creator')) {
                entity.runCommand('function darkw/dotv/defeat/creator');
                entity.remove();
                return
            }
        }
        catch {}
    }
})

// ! Prismaticist Hurt
world.afterEvents.entityHurt.subscribe(ev => {
    let victim = ev.hurtEntity
    let attacker = ev.damageSource.damagingEntity

    // * Extorris Kunai
    if (attacker?.typeId === 'darkw_dotv:extorris_proj') {
        let hitList = ev.hurtEntity.dimension.getEntities({ maxDistance: 4, location: ev.hurtEntity.location })
        womboCombo()
        async function womboCombo() {
            for (let i = 0; i < hitList.length; i++) {
                await system.waitTicks(2)
                let mob = hitList[i]
                mob.runCommand('playsound misc.thepuppet.zappy @a[r=7] ~~~')
                mob.runCommand('particle darkw_dotv:puppetzappy ~~~')
                mob.applyDamage(5)
            }
        }
    }

    // * Void Totem
    if (ev.damageSource.cause === 'void') {
        if (!ev.hurtEntity instanceof Player) return
        if (!ev.hurtEntity.getComponent('equippable').getEquipment('Offhand')) return
        if (ev.hurtEntity.getComponent('equippable').getEquipment('Offhand').typeId === 'darkw_dotv:totem_m4rk' && ev.hurtEntity.getComponent('health').currentValue <= 5) {
            let off = ev.hurtEntity.getComponent('equippable').getEquipment('Offhand')
            ev.hurtEntity.teleport(off.getDynamicProperty('darkw_dotv:void_totem_data'))
            ev.hurtEntity.runCommand('/replaceitem entity @s slot.weapon.offhand 0 air')
            system.runTimeout(() => {
                ev.hurtEntity.dimension.spawnParticle('minecraft:totem_particle', off.getDynamicProperty('darkw_dotv:void_totem_data'))
                ev.hurtEntity.dimension.playSound('random.totem', off.getDynamicProperty('darkw_dotv:void_totem_data'))
            }, 1)
        }
    }

    // * Legatus Shield
    if (attacker?.typeId === 'darkw_dotv:legatus_rune_shield') ev.hurtEntity.addEffect('wither', 100, { amplifier: 3 })

    // * Prismatica Minion
    if (attacker?.typeId === 'darkw_dotv:prismatica_e') victim.dimension.spawnParticle('darkw_dotv:corruptdust_death', {
        x: victim.location.x,
        y: victim.location.y + 1,
        z: victim.location.z
    })
    if (attacker?.typeId === 'darkw_dotv:prismatica_e') victim.remove()
})








// ! DOTV 3 PORTING BEKLOW



system.afterEvents.scriptEventReceive.subscribe(event => {
    const id = event.id
    const source = event.sourceEntity

    if (event.id === 'darkw_dotv:roxxane_charge_tick') {
        let entity = event.sourceEntity
        let health = entity.getComponent('health')

        if (health.currentValue > 2) {
            health.setCurrentValue(health.currentValue - 1)
        }
        else if (!entity.hasTag('darkw_dotv:dead')) {
            system.runTimeout(() => {
                entity.addTag('darkw_dotv:dead')
                entity.runCommand('summon darkw_dotv:deathmusicstopper ~ ~ ~')
                entity.triggerEvent('darkw_dotv:end_phase')
            })
        }
    }
    if (event.id === 'darkw_dotv:summon_ran_rocket') {

        function getRandomInt(min, max) {
            min = Math.ceil(min);
            max = Math.floor(max);
            return Math.floor(Math.random() * (max - min + 1)) + min;
        }

        const ran1 = getRandomInt(-13, 13); // Random integer between -13 and 13 (inclusive)
        const ran2 = getRandomInt(-13, 13); // Random integer between -13 and 13 (inclusive)

        const mob = event.sourceEntity

        const ranMisx = Math.floor(Math.random() * 16);
        const ranMisz = Math.floor(Math.random() * 16);

        mob.runCommand(`/summon darkw_dotv:roxxane_rune_airstrike ~${ran1} ~ ~${ran2}`);
    }
    if (event.id === 'darkw_dotv:summon_ran_manifest') {
        const mob = event.sourceEntity

        const ranMisx = Math.floor(Math.random() * 16);
        const ranMisz = Math.floor(Math.random() * 16);

        mob.runCommand(
            `/summon darkw_dotv:legatus_manifest ~${Math.floor(
                Math.random() * 16
            )} ~ ~${Math.floor(Math.random() * 16)}`
        );
    }
    if (event.id === 'woof:mrktest') {
        const mrk = event.sourceEntity
    }
    if (event.id === 'darkw_dotv:m4rk_manual_phase_switch') {
        const mrk = event.sourceEntity
        system.runTimeout(() => {
            mrk.setProperty('darkw_dotv:attack_state', 1)
        }, 35)
    }
})

world.afterEvents.entityHitEntity.subscribe(event => {
    if (event.damagingEntity.typeId === 'darkw_dotv:m4rk') {
        const mrk = event.damagingEntity
        if (mrk.getProperty('darkw_dotv:attack_state') === 0) mrk.triggerEvent('darkw_dotv:SET_attack_random_debug')
    }
})



// ! LOOOOOOOOOOOOOOOOOOOOOOT

world.afterEvents.entitySpawn.subscribe(ev => {
    return
    if (ev.entity.typeId === 'minecraft:item') {
        let entity = ev.entity
        let item = entity.getComponent('item').itemStack
        console.warn(item.typeId)

        if (item.getTags().includes('darkw_dotv:rarity_uncommon')) {
            entity.addTag('darkw_dotv:lootbeam_uncommon')
        }
    }
})