import * as mc from "@minecraft/server";
import * as utils from "../utils/index";
// any extra mobs that should be targeted that do not have the mob family type
const BEAM_WHITELIST = [
    'monster',
    'undead',
    'animal',
    'dragon',
    'hoglin',
    'panda',
    'goat',
    'fish'
];
// mobs that should never be targeted; excluded by family type
const BEAM_BLACKLIST = [
    'inanimate',
];
export const ignoreEntities = [
    "minecraft:painting",
    "minecraft:item",
    "minecraft:xp_orb",
    "minecraft:ender_dragon",
    "minecraft:arrow",
    "minecraft:fishing_hook",
    "minecraft:thrown_trident",
    "minecraft:armor_stand",
    "minecraft:boat",
    "minecraft:chest_boat",
    "minecraft:ender_pearl",
    "minecraft:snowball",
    "minecraft:egg",
    "minecraft:fireworks_rocket",
    "minecraft:leash_knot",
    "minecraft:lightning_bolt",
    "minecraft:chest_minecart",
    "minecraft:minecart",
    "minecraft:tnt",
];
mc.world.afterEvents.itemReleaseUse.subscribe(event => {
    if (!event.itemStack || !event.source)
        return;
    let player = new utils.SafetyCheckedPlayer(event.source);
    if (event.itemStack.typeId === 'ldz_240409:weapon_guardian') {
        cancelBeam(player);
    }
});
mc.world.afterEvents.itemStopUse.subscribe(event => {
    if (!event.itemStack || !event.source)
        return;
    let player = new utils.SafetyCheckedPlayer(event.source);
    if (event.itemStack.typeId === 'ldz_240409:weapon_guardian') {
        cancelBeam(player);
    }
});
async function cancelBeam(player) {
    var _a;
    utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian', 0);
    utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian.uses', 0);
    utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian.cancel', true);
    await utils.waitForTicks(1);
    utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian', 0);
    utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian.uses', 0);
    utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian.cancel', true);
    const beam_id = utils.readDynamicProperty(player, "beam_id");
    (_a = mc.world.getEntity(beam_id)) === null || _a === void 0 ? void 0 : _a.remove();
}
export function onGuardianUse(player) {
    const beamEntity = player.dimension.spawnEntity("ldz_240409:guardian_beam", player.location);
    utils.writeDynamicProperty(player, "beam_id", beamEntity.id);
    if (utils.readDynamicProperty(player, 'ldz_240409.weapon_guardian') === 2) {
        utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian', 0), utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian.cancel', true);
        return;
    }
    ;
    utils.mclog(`${player.nameTag} Used Guardian Weapon`);
    utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian', 1);
    utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian.cancel', false);
    player.playSound('ldz_240409:guardian_weapon.beam');
    activateBeam(player, new utils.SafetyCheckedEntity(beamEntity));
}
async function activateBeam(player, beamEntity) {
    beamEntity.teleport(player.location, { rotation: player.getRotation() });
    const playerRot = player.getRotation();
    beamEntity.setProperty("ldz_240409:rot_x", playerRot.x);
    beamEntity.setProperty("ldz_240409:rot_y", playerRot.y);
    beamEntity.triggerEvent("delay_despawn");
    let totalUses = utils.readDynamicProperty(player, 'ldz_240409.weapon_guardian.uses');
    if (utils.readDynamicProperty(player, 'ldz_240409.weapon_guardian') === 0 && totalUses != 0) {
        utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian', 0);
        utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian.cancel', true);
        return;
    }
    ;
    if (utils.readDynamicProperty(player, 'ldz_240409.weapon_guardian.cancel') === true) {
        utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian', 0), utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian.cancel', true);
        return;
    }
    ;
    utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian', 2);
    totalUses = totalUses + 1;
    utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian.uses', totalUses);
    const location = player.location.add(new utils.Vector3({ x: 0, y: 1, z: 0 }));
    let targetEntities = utils.getEntitiesFromRaySafe(player.dimension, location, player.getViewDirection(), { maxDistance: 15, families: ['mob'], excludeFamilies: BEAM_BLACKLIST }).filter(entity => entity.entity.id !== player.id);
    BEAM_WHITELIST.forEach(family => {
        targetEntities = targetEntities.concat(utils.getEntitiesFromRaySafe(player.dimension, location, player.getViewDirection(), { maxDistance: 15, families: [family], excludeFamilies: BEAM_BLACKLIST }).filter(entity => entity.entity.id !== player.id));
    });
    if (mc.world.gameRules.pvp) {
        targetEntities = targetEntities.concat(utils.getEntitiesFromRaySafe(player.dimension, location, player.getViewDirection(), { maxDistance: 15, families: ["player"], excludeFamilies: BEAM_BLACKLIST }).filter(entity => entity.entity.id !== player.id));
    }
    ;
    ignoreEntities.forEach(target => {
        targetEntities = targetEntities.filter(entity => entity.entity.typeId !== target);
    });
    const rotation = player.getRotation().y;
    let molang = new mc.MolangVariableMap();
    molang.setFloat("rotation", rotation * -1);
    if (targetEntities.length > 0) {
        if (targetEntities[0].entity.isValid()) {
            targetEntities[0].entity.addTag('GuardianTarget');
            player.runCommand('function ldz/240409/guardian/target_loop');
            targetEntities[0].entity.applyDamage(4, { cause: mc.EntityDamageCause.entityAttack, damagingEntity: player.UnsafeEntity });
            const facingOffset = new utils.Vector3({ x: 0, y: 1.5, z: 0 });
            const facingLocation = new utils.Vector3({ x: targetEntities[0].entity.location.x, y: (targetEntities[0].entity.getHeadLocation().subtract(facingOffset)).y, z: targetEntities[0].entity.location.z });
            player.teleport(player.location, { facingLocation: facingLocation });
        }
        if (totalUses > 10) {
            totalUses = 0;
            player.playSound('ldz_240409:guardian_weapon.beam');
            utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian.uses', totalUses);
            utils.modifyEquipmentDurability(player, mc.EquipmentSlot.Mainhand, -1);
        }
    }
    else {
        if (totalUses > 10) {
            totalUses = 0;
            player.playSound('ldz_240409:guardian_weapon.beam');
            utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian.uses', totalUses);
        }
    }
    await utils.waitForTicks(0);
    if (utils.readDynamicProperty(player, 'ldz_240409.weapon_guardian') === 0) {
        utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian', 0), utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian.cancel', true);
        return;
    }
    ;
    if (utils.readDynamicProperty(player, 'ldz_240409.weapon_guardian.cancel') === true) {
        utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian', 0), utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian.cancel', true);
        return;
    }
    ;
    if (!player.isValid()) {
        utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian', 0), utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian.cancel', true);
        return;
    }
    ;
    const equipment = player.getComponent(mc.EntityEquippableComponent.componentId);
    if (!equipment) {
        utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian', 0), utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian.cancel', true);
        return;
    }
    ;
    const item = equipment.getEquipment(mc.EquipmentSlot.Mainhand);
    if (!item || item.typeId !== 'ldz_240409:weapon_guardian') {
        utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian', 0), utils.writeDynamicProperty(player, 'ldz_240409.weapon_guardian.cancel', true);
        return;
    }
    ;
    activateBeam(player, beamEntity);
}
