import { system, TicksPerSecond, world } from "@minecraft/server";
class ProjectileHandler {
    constructor(entity_types) {
        this.entitySpawnEvent = world.afterEvents.entitySpawn;
        this.projectileHitBlockEvent = world.afterEvents.projectileHitBlock;
        this.projectileHitEntityEvent = world.afterEvents.projectileHitEntity;
        this.entity_types = entity_types;
        this.on_entity_spawned = this.on_entity_spawned.bind(this);
        this.on_projectile_hit_block = this.on_projectile_hit_block.bind(this);
        this.on_projectile_hit_entity = this.on_projectile_hit_entity.bind(this);
        this.handle_subscriptions();
    }
    handle_subscriptions() {
        this.entitySpawnEvent.subscribe(this.on_entity_spawned);
        this.projectileHitBlockEvent.subscribe(this.on_projectile_hit_block);
        this.projectileHitEntityEvent.subscribe(this.on_projectile_hit_entity);
    }
    on_entity_spawned(event) {
        if (!this.entity_types.includes(event.entity.typeId))
            return;
        system.runTimeout(() => {
            try {
                event.entity.addEffect("levitation", 5, {
                    "amplifier": 1,
                    "showParticles": false
                });
            }
            catch (error) {
            }
        }, TicksPerSecond / 3);
    }
    on_projectile_hit_block(event) {
        if (!this.entity_types.includes(event.projectile.typeId))
            return;
        const entity = event.projectile;
        this.play_impact_sound(entity);
        this.remove_entity_delayed(entity);
    }
    on_projectile_hit_entity(event) {
        if (!this.entity_types.includes(event.projectile.typeId))
            return;
        const entity = event.projectile;
        this.play_impact_sound(entity);
        this.remove_entity_delayed(entity);
    }
    get_closest_player(entity) {
        const players = world.getDimension(entity.dimension.id).getEntities({
            type: 'minecraft:player',
            location: entity.location,
            minDistance: 1.0,
            maxDistance: 32.0,
            closest: 1
        });
        return players[0];
    }
    calculate_velocity(entity) {
        const location = entity.location;
        const target = this.get_closest_player(entity);
        const target_location = target.location;
        // Calculate the difference vector
        const diff_x = target_location.x - location.x;
        const diff_y = target_location.y - location.y;
        const diff_z = target_location.z - location.z;
        // Compute the magnitude of the vector
        const magnitude = Math.sqrt(diff_x * diff_x + diff_y * diff_y + diff_z * diff_z);
        // Normalize the vector to create a unit vector
        const norm_x = diff_x / magnitude;
        const norm_y = diff_y / magnitude;
        const norm_z = diff_z / magnitude;
        // Scale the vector by the desired speed (e.g., speed = 1 for unit speed)
        const speed = 5;
        const velocity_x = norm_x * speed;
        const velocity_y = norm_y * speed;
        const velocity_z = norm_z * speed;
        // Return the velocity vector
        const velocity = { x: velocity_x, y: velocity_y, z: velocity_z };
        return velocity;
    }
    apply_velocity(entity) {
        const velocity = this.calculate_velocity(entity);
        entity.applyImpulse(velocity);
    }
    play_impact_sound(entity) {
        try {
            if (!entity)
                return;
            if (!entity.typeId || !entity.location)
                return;
            let sound_string = '';
            if (entity.typeId === 'ss_hyd:fire_projectile')
                sound_string = 'ss_hyd.fire_impact';
            else if (entity.typeId === 'ss_hyd:poison_projectile')
                sound_string = 'ss_hyd.water_impact';
            else if (entity.typeId === 'ss_hyd:skeletal_projectile')
                sound_string = 'ss_hyd.skeleton_impact';
            else if (entity.typeId === 'ss_hyd:warden_projectile')
                sound_string = 'ss_hyd.warden_impact';
            else if (entity.typeId === 'ss_hyd:water_projectile')
                sound_string = 'ss_hyd.water_impact';
            world.playSound(sound_string, entity.location);
        }
        catch (error) {
        }
    }
    remove_entity_delayed(entity) {
        if (!entity)
            return;
        system.runTimeout(() => {
            try {
                entity.remove();
            }
            catch (error) { }
        }, TicksPerSecond);
    }
}
export { ProjectileHandler };
