/* eslint-disable no-continue */
import { LocationInUnloadedChunkError, LocationOutOfWorldBoundariesError, system } from '@minecraft/server';
import HeadAttack from './headAttack';
import { LONG_RANGE_SQ } from '../witherbossSettings';
import WBVector3 from '../../util/wbVector3';
export default class SpawnWitherSkeletonsAttack extends HeadAttack {
    constructor(wither, headPos) {
        super(wither, headPos);
        // The time in ticks until the head will attack again
        this.attackCooldown = 0;
        this.resetAttackCooldown();
    }
    /// Override methods
    resumeHeadAttackMode() {
    }
    tickHeadAttack() {
    }
    tickHeadAttackWhenActive() {
        // Update the properties for target yaw and pitch
        if (this.target && this.target.isValid()) {
            const headLocation = this.getApproxIdleHeadLocation(this.headPos);
            if (!headLocation) {
                return false;
            }
            const targetLocation = WBVector3.fromMC(this.target.location);
            const direction = targetLocation.subtract(headLocation).normalize().getRotation();
            const entity = this.wither.getEntity();
            if (entity) {
                entity.setProperty(this.headTargetYawPropertyName, direction.y);
                entity.setProperty(this.headTargetPitchPropertyName, direction.x);
            }
        }
        // If an attack was launched, do not do anything else
        if (this.attackCooldown < 0) {
            return true;
        }
        // Determine target
        this.target = this.getNearestTarget(this.headPos, LONG_RANGE_SQ, 360);
        if (!this.target) {
            return false;
        }
        // If the cooldown is 0, start an attack
        if (this.attackCooldown === 0) {
            this.launchAttack();
        }
        // Decrement the attack cooldown
        this.attackCooldown--;
        return this.attackCooldown < 0;
    }
    pauseHeadAttackMode() {
    }
    stopHeadAttack() {
    }
    resetAttackCooldown() {
        const cooldown = Math.random()
            // eslint-disable-next-line max-len
            * (SpawnWitherSkeletonsAttack.MAX_ATTACK_COOLDOWN - SpawnWitherSkeletonsAttack.MIN_ATTACK_COOLDOWN)
            + SpawnWitherSkeletonsAttack.MIN_ATTACK_COOLDOWN;
        this.attackCooldown = Math.floor(cooldown);
    }
    launchAttack() {
        const entity = this.wither.getEntity();
        if (!entity) {
            return;
        }
        // Spawn wither skeletons at random locations around the target
        const spawnCount = Math.floor(Math.random()
            * (SpawnWitherSkeletonsAttack.MAX_SPAWN_COUNT - SpawnWitherSkeletonsAttack.MIN_SPAWN_COUNT)
            + SpawnWitherSkeletonsAttack.MIN_SPAWN_COUNT);
        const spawnDistance = Math.random()
            // eslint-disable-next-line max-len
            * (SpawnWitherSkeletonsAttack.MAX_SPAWN_DISTANCE - SpawnWitherSkeletonsAttack.MIN_SPAWN_DISTANCE)
            + SpawnWitherSkeletonsAttack.MIN_SPAWN_DISTANCE;
        const centerRandomUnitVector = new WBVector3(Math.random() * 2 - 1, 0, Math.random() * 2 - 1)
            .normalize();
        const centerSpawnLocation = WBVector3.fromMC(entity.location)
            .add(centerRandomUnitVector.multiply(spawnDistance));
        for (let i = 0; i < spawnCount; i++) {
            const randomUnitVector = new WBVector3(Math.random() * 2 - 1, 0, Math.random() * 2 - 1)
                .normalize();
            const spawnLocation = centerSpawnLocation.add(randomUnitVector.multiply(1.3));
            const { dimension } = entity;
            for (let deltaHeight = 0; deltaHeight > -15; deltaHeight--) {
                try {
                    const block = dimension.getBlock(spawnLocation);
                    if (!block)
                        continue;
                    const below = block.below();
                    if (!below)
                        continue;
                    const belowIsSolid = !!below?.dimension.getBlockFromRay(below.location, { x: 0, y: 1, z: 0 }, { includePassableBlocks: false, maxDistance: 1 });
                    if (block.isAir && belowIsSolid) {
                        const witherSkeleton = dimension.spawnEntity('minecraft:wither_skeleton', spawnLocation);
                        system.runTimeout(() => {
                            witherSkeleton.playAnimation('animation.twb_wisu.wither_skeleton.spawn');
                            witherSkeleton.addEffect('minecraft:slowness', 3 * 20, { amplifier: 100, showParticles: false });
                        }, 1);
                        break;
                    }
                }
                catch (e) {
                    // eslint-disable-next-line max-len
                    if (e instanceof LocationInUnloadedChunkError || e instanceof LocationOutOfWorldBoundariesError) {
                        continue;
                    }
                    throw e;
                }
                spawnLocation.y--;
            }
        }
        // Reset the attack cooldown after the attack is finished
        system.runTimeout(() => {
            this.resetAttackCooldown();
        }, SpawnWitherSkeletonsAttack.TOTAL_ATTACK_TIME);
        // Play the animation
        entity.playAnimation('animation.twb_wisu.wither_wraith.base_attack_left');
        // Play the sound
        entity.dimension.playSound('twb_wisu:witherboss.attack.wither_skeleton', entity.location, {
            volume: 16
        });
    }
}
/// Static constants for the shoot head attack
SpawnWitherSkeletonsAttack.MIN_ATTACK_COOLDOWN = 10 * 20;
SpawnWitherSkeletonsAttack.MAX_ATTACK_COOLDOWN = 20 * 20;
SpawnWitherSkeletonsAttack.TOTAL_ATTACK_TIME = 100;
SpawnWitherSkeletonsAttack.MIN_SPAWN_DISTANCE = 8;
SpawnWitherSkeletonsAttack.MAX_SPAWN_DISTANCE = 18;
SpawnWitherSkeletonsAttack.MIN_SPAWN_COUNT = 3;
SpawnWitherSkeletonsAttack.MAX_SPAWN_COUNT = 5;
