
// scripts/morph-manager.ts
import {
  Container,
  EnchantmentType,
  EntityComponentTypes,
  EntityDamageCause,
  EntityEquippableComponent as EntityEquippableComponent2,
  EntityInventoryComponent as EntityInventoryComponent2,
  EquipmentSlot,
  ItemComponentTypes,
  ItemEnchantableComponent,
  ItemLockMode as ItemLockMode2,
  ItemStack as ItemStack3,
  Player as Player2,
  system as system2,
  world as world2,
} from "@minecraft/server";

// scripts/morph.ts
import { EntityInventoryComponent, ItemStack as ItemStack2, EntityEquippableComponent, ItemLockMode } from "@minecraft/server";
var MorphType = /* @__PURE__ */ ((MorphType2) => {
  MorphType2["COW"] = "cow";
  MorphType2["FOX"] = "fox";
  MorphType2["RABBIT"] = "rabbit";
  MorphType2["HORSE"] = "horse";
  MorphType2["WOLF"] = "wolf";
  MorphType2["CHICKEN"] = "chicken";
  MorphType2["CAT"] = "cat";
  MorphType2["PIG"] = "pig";
  MorphType2["SHEEP"] = "sheep";
  return MorphType2;
})(MorphType || {});
var Morph = class {
  /**
   * 
   * @param {Player2} player 
   */
  constructor(player, type) {
    this.morphed = false;
    this.missingItems = [];
    this.player = player;
    this.type = type;
    this.items = [`aria_ah:${type}_attack`, `aria_ah:${type}_ability`];
  }
  get equipment() {
    if (!this.equipmentComponent) {
      this.equipmentComponent = this.player.getComponent(EntityEquippableComponent.componentId);
    }
    return this.equipmentComponent;
  }
  get inventory() {
    if (!this.inventoryComponent) {
      this.inventoryComponent = this.player.getComponent(EntityInventoryComponent.componentId);
    }
    return this.inventoryComponent;
  }
  tick(tick2) {
    this.player.playAnimation("animation.aria_ah.player_invisible", {
      controller: "controller.animation.player.third_person",
      stopExpression: "!q.equipped_item_all_tags('slot.weapon.offhand', 'aria_ah.morph')"
    });
    this.player.playAnimation("animation.aria_ah.player_invisible", {
      controller: "controller.animation.player.first_person",
      stopExpression: "!q.equipped_item_all_tags('slot.weapon.offhand', 'aria_ah.morph')"
    });
    this.tickMissingItems();
    this.onTick?.(tick2);
  }
  morph(join) {
    this.morphed = true;
    if (!join) {
      this.missingItems = [];
      this.applyItems();
    }
    this.onMorph?.(join);
  }
  unmorph() {
    this.morphed = false;
    this.removeItems();
    this.onUnmorph?.();
  }
  leave() {
    this.onUnmorph?.();
  }
  hurt(event) {
    this.onHurt?.(event);
  }
  attack(event) {
    this.onAttack?.(event);
  }
  ability(event) {
    this.onAbility?.(event);
  }
  death(event) {
    this.onDeath?.(event);
    this.unmorph();
  }
  tickMissingItems() {
    if (!this.missingItems || this.missingItems.length === 0) {
      return;
    }
    while (this.missingItems.length > 0) {
      const item = this.missingItems.shift();
      if (!item) {
        break;
      }
      const result = this.inventory?.container?.addItem(item);
      if (result) {
        this.missingItems.unshift(result);
        break;
      }
    }
  }
  applyItems() {
    for (const id of this.items) {
      const slot = this.items.indexOf(id);
      /** @type {ItemStack2} */
      const item = this.inventory?.container?.getItem(slot);
      const newItem = new ItemStack2(id);
      newItem.lockMode = ItemLockMode2.inventory;
      newItem.keepOnDeath = true;
      /** @type {Container} */
      const container = this.inventory?.container;

      container.setItem(slot, newItem);
      if (item) {
        container.addItem(item);
      }
    }
  }
  removeItems() {
    if (!this.inventory?.container) {
      return;
    }
    const { container } = this.inventory;
    for (let slot = 0; slot < container.size; slot++) {
      const item = container.getItem(slot);
      if (!item) {
        continue;
      }
      if (this.items.includes(item.typeId)) {
        container.setItem(slot);
      }
    }
  }
};

// scripts/morph/cow-morph.ts
var CowMorph = class extends Morph {
  constructor(player) {
    super(player, "cow" /* COW */);
  }
  onAbility(event) {
    if (world2.scoreboard.getObjective("aria_ah.general").getScore("vv_active")) {
      this.player.runCommand("particle aria_ah:scream_white_vv ^^1^1");
    } else {
      this.player.runCommand("particle aria_ah:scream_white ^^1^1");
    }
    this.player.runCommand("function aria/ah/morph/ability_cow");
  }
  onAttack(event) {
    //this.player.sendMessage([this.type, "onAttack"].join(" "));
    system2.runTimeout(() => {
      this.player.runCommand("function aria/ah/morph/attack_cow");
    }, 1 * 16)
  }
  onDeath(event) {
    //this.player.sendMessage([this.type, "onDeath"].join(" "));
    this.player.runCommand("playsound aria_ah.cow_death @a[r=15] ~~~ 2 0.8");
  }
  onHurt(event) {
    //this.player.sendMessage([this.type, "onHurt"].join(" "));
    this.player.runCommand("playsound aria_ah.hit_low @a[r=15] ~~~ 1 3");
  }
  onMorph(join) {
    //this.player.sendMessage([this.type, "onMorph"].join(" "));
    this.player.runCommand("function aria/ah/morph/new_morph");
    this.player.runCommand("function aria/ah/morph/tick_effect");
    this.player.runCommand("effect @s instant_health 1 10 true");
  }
  onTick(tick2) {
    if (tick2 % 200 === 0) {
      //this.player.sendMessage([this.type, "onTick"].join(" "));
      this.player.runCommand("function aria/ah/morph/tick_effect");
    }
  }
  onUnmorph() {
    //this.player.sendMessage([this.type, "onUnmorph"].join(" "));
    this.player.runCommand("function aria/ah/morph/unmorph");
  }
};

// scripts/morph/rabbit-morph.ts
var RabbitMorph = class extends Morph {
  constructor(player) {
    super(player, "rabbit" /* RABBIT */);
  }
  onAbility(event) {
    //this.player.sendMessage([this.type, "onAbility"].join(" "));
    this.player.runCommand("function aria/ah/morph/ability_rabbit");
    if (world2.scoreboard.getObjective("aria_ah.general").getScore("vv_active")) {
      this.player.runCommand("particle aria_ah:scream_morph_vv ^^1.3^1.3");
    } else {
      if (world2.scoreboard.getObjective("aria_ah.general").getScore("vv_active")) {
        this.player.runCommand("particle aria_ah:scream_morph_vv ^^1.3^1.3");
      } else {
        this.player.runCommand("particle aria_ah:scream ^^1.3^1.3");
    }
    }
    this.player.runCommand("playsound aria_ah.rabbit_death @a[r=15] ~~~ 0.7 1");

  }
  onAttack(event) {
    //this.player.sendMessage([this.type, "onAttack"].join(" "));
    system2.runTimeout(() => {
      this.player.runCommand("function aria/ah/morph/attack_rabbit");
    }, 1 * 8)
    this.player.runCommand("playsound aria_ah.rabbit_attack @a ~~~ 0.7 1");
  }
  onDeath(event) {
    //this.player.sendMessage([this.type, "onDeath"].join(" "));
    this.player.runCommand("playsound aria_ah.rabbit_death @a[r=15] ~~~ 2 0.8");
  }
  onHurt(event) {
    //this.player.sendMessage([this.type, "onHurt"].join(" "));
    this.player.runCommand("playsound aria_ah.hit_low @a[r=15] ~~~ 1 3");
  }
  onMorph(join) {
    //this.player.sendMessage([this.type, "onMorph"].join(" "));
    this.player.runCommand("function aria/ah/morph/new_morph");
    this.player.runCommand("function aria/ah/morph/tick_effect");
    this.player.runCommand("effect @s instant_health 1 10 true");
  }
  onTick(tick2) {
    if (tick2 % 200 === 0) {
      //this.player.sendMessage([this.type, "onTick"].join(" "));
      this.player.runCommand("function aria/ah/morph/tick_effect");
    }
  }
  onUnmorph() {
    //this.player.sendMessage([this.type, "onUnmorph"].join(" "));
    this.player.runCommand("function aria/ah/morph/unmorph");
  }
};

// scripts/morph/horse-morph.ts
var HorseMorph = class extends Morph {
  constructor(player) {
    super(player, "horse" /* HORSE */);
  }
  onAbility(event) {
    //this.player.sendMessage([this.type, "onAbility"].join(" "));
    this.player.runCommand("function aria/ah/morph/ability_horse");
    if (world2.scoreboard.getObjective("aria_ah.general").getScore("vv_active")) {
      this.player.runCommand("particle aria_ah:scream_vv ^^2^1");
    } else {
      this.player.runCommand("particle aria_ah:scream ^^2^1");
    }
  }
  onAttack(event) {
    //this.player.sendMessage([this.type, "onAttack"].join(" "));
    system2.runTimeout(() => {
      this.player.runCommand("function aria/ah/morph/attack_horse");
    }, 1 * 14);
    this.player.runCommand("playsound aria_ah.horse_attack @a ~~~ 0.7 1");
  }
  onDeath(event) {
    //this.player.sendMessage([this.type, "onDeath"].join(" "));
    this.player.runCommand("playsound aria_ah.horse_death @a[r=15] ~~~ 2 0.8");
  }
  onHurt(event) {
    //this.player.sendMessage([this.type, "onHurt"].join(" "));
    this.player.runCommand("playsound aria_ah.hit_low @a[r=15] ~~~ 1 3");
  }
  onMorph(join) {
    //this.player.sendMessage([this.type, "onMorph"].join(" "));
    this.player.runCommand("function aria/ah/morph/new_morph");
    this.player.runCommand("function aria/ah/morph/tick_effect");
    this.player.runCommand("effect @s instant_health 1 10 true");
  }
  onTick(tick2) {
    if (tick2 % 200 === 0) {
      //this.player.sendMessage([this.type, "onTick"].join(" "));
      this.player.runCommand("function aria/ah/morph/tick_effect");
    }
  }
  onUnmorph() {
    //this.player.sendMessage([this.type, "onUnmorph"].join(" "));
    this.player.runCommand("function aria/ah/morph/unmorph");
  }
};

// scripts/morph/wolf-morph.ts
var WolfMorph = class extends Morph {
  constructor(player) {
    super(player, "wolf" /* WOLF */);
  }
  onAbility(event) {
    //this.player.sendMessage([this.type, "onAbility"].join(" "));
    this.player.runCommand("function aria/ah/morph/ability_wolf");
    if (world2.scoreboard.getObjective("aria_ah.general").getScore("vv_active")) {
      this.player.runCommand("particle aria_ah:scream_vv ^^1.1^1.1");
    } else {
      this.player.runCommand("particle aria_ah:scream ^^1.1^1.1");
    }
  }
  onAttack(event) {
    //this.player.sendMessage([this.type, "onAttack"].join(" "));
    system2.runTimeout(() => {
      this.player.runCommand("function aria/ah/morph/attack_wolf");
    }, 1 * 8)
    this.player.runCommand("playsound aria_ah.wolf_attack @a ~~~ 0.7 1");
  }
  onDeath(event) {
    //this.player.sendMessage([this.type, "onDeath"].join(" "));
    this.player.runCommand("playsound aria_ah.wolf_death @a[r=15] ~~~ 2 0.8");
  }
  onHurt(event) {
    //this.player.sendMessage([this.type, "onHurt"].join(" "));
    this.player.runCommand("playsound aria_ah.hit_low @a[r=15] ~~~ 1 3");
  }
  onMorph(join) {
    //this.player.sendMessage([this.type, "onMorph"].join(" "));
    this.player.runCommand("function aria/ah/morph/new_morph");
    this.player.runCommand("function aria/ah/morph/tick_effect");
    this.player.runCommand("effect @s instant_health 1 10 true");
  }
  onTick(tick2) {
    if (tick2 % 200 === 0) {
      //this.player.sendMessage([this.type, "onTick"].join(" "));
      this.player.runCommand("function aria/ah/morph/tick_effect");
    }
  }
  onUnmorph() {
    //this.player.sendMessage([this.type, "onUnmorph"].join(" "));
    this.player.runCommand("function aria/ah/morph/unmorph");
  }
};

// scripts/morph/cat-morph.ts
var CatMorph = class extends Morph {
  constructor(player) {
    super(player, "cat" /* CAT */);
  }
  onAbility(event) {
    const player = this.player;
    const objective = "aria_ah.player_cat_underground";

    // Always run these commands
    player.runCommand('function aria/ah/morph/cat/underground_1');
    player.runCommand('inputpermission set @s movement disabled');


    // Get the scoreboard objective and player score
    const scoreboard = world2.scoreboard.getObjective(objective);
    const score = scoreboard ? scoreboard.getScore(player) : undefined;

    // Play the appropriate sound based on score
    if (score === 1) {
      player.runCommand('playsound aria_ah.cat_dig_down @a[r=15] ~~~ 1 1');
      // Run tick_effect function after 1 second (20 ticks)
      system2.runTimeout(() => {
        player.runCommand('effect @s speed 30 3 true');
        player.runCommand('effect @s jump_boost 30 3 true');
      }, 20);
      system2.runTimeout(() => {
        player.runCommand('inputpermission set @s movement enabled');
      }, 30);
    } else if (score === 0) {
      player.runCommand('playsound aria_ah.cat_dig_up @a[r=15] ~~~ 1 1');
      system2.runTimeout(() => {
        player.runCommand('inputpermission set @s movement enabled');
      }, 20);
    }

    // Play the particle 4 times at intervals
    system2.runTimeout(() => {
      player.runCommand('particle aria_ah:dig');
    }, 0); // 0 seconds

    system2.runTimeout(() => {
      player.runCommand('particle aria_ah:dig');
    }, 4); // 0.2 seconds

    system2.runTimeout(() => {
      player.runCommand('particle aria_ah:dig');
    }, 8); // 0.4 seconds

    system2.runTimeout(() => {
      player.runCommand('particle aria_ah:dig');
    }, 12); // 0.6 seconds
  }
  onAttack(event) {
    const player = this.player;
    const objective = "aria_ah.player_cat_underground";
    const scoreboard = world2.scoreboard.getObjective(objective);
    const score = scoreboard ? scoreboard.getScore(player) : undefined;

    if (score === 0) {
      system2.runTimeout(() => {
        player.runCommand("function aria/ah/morph/attack_cat");
      }, 14);

      player.runCommand("playsound aria_ah.cat_attack @a ~~~ 0.8 1");

      // Increase the search distance and radius
      const look = player.getViewDirection();
      const pos = player.location;
      const maxDistance = 15;
      const searchRadius = 8; // Increased radius for better detection

      // Calculate the center point for entity search
      const center = {
        x: pos.x + look.x * maxDistance,
        y: pos.y + look.y * maxDistance,
        z: pos.z + look.z * maxDistance
      };

      // Query for entities in a larger radius
      const entities = world2.getDimension(player.dimension.id).getEntities({
        location: center,
        maxDistance: searchRadius,
        excludeTypes: ["minecraft:player", "minecraft:item"]
      });

      let foundEntity = null;
      let entityPos = null;
      for (const entity of entities) {
        if (entity.id !== player.id) {
          foundEntity = entity;
          entityPos = entity.location;
          break;
        }
      }

      const knockbackForce = {
        x: (entityPos?.x - player.location.x)/4 || look.x * 4,
        y: (entityPos?.y - player.location.y)/4 || 0.4,
        z: (entityPos?.z - player.location.z)/4 || look.z * 4
      };

      player.applyKnockback({ x: knockbackForce.x, z: knockbackForce.z }, knockbackForce.y);

      // If an entity is found, teleport player 1 block before it
      if (foundEntity && entityPos) {
        const dirX = entityPos.x - pos.x;
        const dirY = entityPos.y - pos.y;
        const dirZ = entityPos.z - pos.z;
        const length = Math.sqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
        const normX = dirX / length;
        const normY = dirY / length;
        const normZ = dirZ / length;

        const tpX = entityPos.x - normX * 1;
        const tpY = entityPos.y - normY * 1;
        const tpZ = entityPos.z - normZ * 1;

        player.runCommand("particle aria_ah:death ^^1^1");
        player.runCommand("particle aria_ah:dark_fog ^^1^1");
        player.runCommand("playsound aria_ah.whisper @a ~~~ 1 1");

        system2.runTimeout(() => {
          // Use tryTeleport for reliability, and set facingLocation

          player.tryTeleport(
            { x: tpX, y: tpY, z: tpZ },
            {
              dimension: player.dimension,
              checkForBlocks: true,
              facingLocation: entityPos
            }
          );
          player.runCommand("particle aria_ah:death ^^1^0.5");
        }, 10); // 0.25 seconds (5 ticks)
      }
    }
  }








  onDeath(event) {
    //this.player.sendMessage([this.type, "onDeath"].join(" "));
    this.player.runCommand("playsound aria_ah.cat_death @a[r=15] ~~~ 2 0.8");
  }
  onHurt(event) {
    //this.player.sendMessage([this.type, "onHurt"].join(" "));
    this.player.runCommand("playsound aria_ah.hit_low @a[r=15] ~~~ 1 3");
  }
  onMorph(join) {
    //this.player.sendMessage([this.type, "onMorph"].join(" "));
    this.player.runCommand("function aria/ah/morph/new_morph");
    this.player.runCommand("function aria/ah/morph/tick_effect");
    this.player.runCommand("effect @s instant_health 1 10 true");
    this.player.runCommand("function aria/ah/morph/cat/underground_0");
  }
  onTick(tick2) {
    if (tick2 % 200 === 0) {
      //this.player.sendMessage([this.type, "onTick"].join(" "));
      this.player.runCommand("function aria/ah/morph/cat/tick_effect");
    }
    if (tick2 % 22 === 0) {
      const player = this.player;
      const objective = "aria_ah.player_cat_underground";

      // Get the scoreboard objective and player score
      const scoreboard = world2.scoreboard.getObjective(objective);
      const score = scoreboard ? scoreboard.getScore(player) : undefined;

      if (score === 1) {
        player.runCommand("playsound aria_ah.underground_loop @a[r=15] ~~~ 1 1");
      }

      //this.player.sendMessage([this.type, "onTick"].join(" "));
      //this.player.runCommand("say hi22");
    }
  }
  onUnmorph() {
    //this.player.sendMessage([this.type, "onUnmorph"].join(" "));
    this.player.runCommand("function aria/ah/morph/unmorph");
    this.player.runCommand("function aria/ah/morph/cat/underground_0");
  }
};

// scripts/morph/pig-morph.ts
var PigMorph = class extends Morph {
  constructor(player) {
    super(player, "pig" /* PIG */);
  }
  onAbility(event) {
    const player = this.player;

    // Get inventory component properly
    const inventory = player.getComponent("minecraft:inventory").container;

    let hasDarkEye = false;
    let itemSlot = -1;

    // Check inventory slots correctly
    for (let i = 0; i < inventory.size; i++) {
      const item = inventory.getItem(i);
      if (item?.typeId === "aria_ah:eye") {
        hasDarkEye = true;
        itemSlot = i;
        break;
      }
    }

    if (hasDarkEye) {
      // Consume item properly
      const item = inventory.getItem(itemSlot);

      if (item.amount - 1 <= 0) {
        inventory.setItem(itemSlot, null);
      } else {
        item.amount--;
        inventory.setItem(itemSlot, item);
      }

      // Original ability commands
      player.runCommand("function aria/ah/morph/ability_pig");
      if (world2.scoreboard.getObjective("aria_ah.general").getScore("vv_active")) {
        player.runCommand("particle aria_ah:scream_white_vv ^^1^1");
      } else {
        player.runCommand("particle aria_ah:scream_white ^^1^1");
      }
      player.runCommand("playsound aria_ah.pig_attack_far @a ~~~ 0.7 1");

      // Use correct system reference
      system2.runTimeout(() => {
        player.runCommand("summon aria_ah:eye ~ ~1 ~ ~ ~ aria:attack_mobs");
      }, 1 * 15);
    } else {
      // Send message using proper method
      player.sendMessage({ rawtext: [{ translate: "aria_ah.morph.requires_dark_eye" }]});
    }
  }


  onAttack(event) {
    //this.player.sendMessage([this.type, "onAttack"].join(" "));
    system2.runTimeout(() => {
      this.player.runCommand("function aria/ah/morph/attack_pig");
    }, 1 * 15)
    this.player.runCommand("playsound aria_ah.pig_attack_close @a ~~~ 0.7 1");
  }
  onDeath(event) {
    //this.player.sendMessage([this.type, "onDeath"].join(" "));
    this.player.runCommand("playsound aria_ah.pig_death @a[r=15] ~~~ 2 0.8");
  }
  onHurt(event) {
    //this.player.sendMessage([this.type, "onHurt"].join(" "));
    this.player.runCommand("playsound aria_ah.hit_low @a[r=15] ~~~ 1 3");
  }
  onMorph(join) {
    //this.player.sendMessage([this.type, "onMorph"].join(" "));
    this.player.runCommand("function aria/ah/morph/new_morph");
    this.player.runCommand("function aria/ah/morph/tick_effect");
    this.player.runCommand("effect @s instant_health 1 10 true");
  }
  onTick(tick2) {
    if (tick2 % 200 === 0) {
      //this.player.sendMessage([this.type, "onTick"].join(" "));
      this.player.runCommand("function aria/ah/morph/tick_effect");
    }
  }
  onUnmorph() {
    //this.player.sendMessage([this.type, "onUnmorph"].join(" "));
    this.player.runCommand("function aria/ah/morph/unmorph");
  }
};

// scripts/morph/chicken-morph.ts
var ChickenMorph = class extends Morph {
  constructor(player) {
    super(player, "chicken" /* CHICKEN */);
  }
  onAbility(event) {
    const player = this.player;
    const objective = "aria_ah.player_chicken_mode";

    // Always run these commands
    player.runCommand('function aria/ah/morph/chicken/mode_2');
    player.runCommand('inputpermission set @s movement disabled');


    // Get the scoreboard objective and player score
    const scoreboard = world2.scoreboard.getObjective(objective);
    const score = scoreboard ? scoreboard.getScore(player) : undefined;

    // Play the appropriate sound based on score
    if (score === 1) {
      player.runCommand('playsound aria_ah.chicken_scream @a[r=15] ~~~ 1 1');
      if (world2.scoreboard.getObjective("aria_ah.general").getScore("vv_active")) {
      player.runCommand("particle aria_ah:scream_vv ^^1.1^1");
      } else {
      player.runCommand("particle aria_ah:scream ^^1.1^1");
      }
      // Run tick_effect function after 1 second (20 ticks)
      system2.runTimeout(() => {
        player.runCommand('effect @s speed 30 3 true');
        player.runCommand('effect @s jump_boost 30 2 true');
      }, 20);
      system2.runTimeout(() => {
        player.runCommand('inputpermission set @s movement enabled');
      }, 30);
    } else if (score === 0) {
      player.runCommand('playsound aria_ah.chicken.laugh @a[r=15] ~~~ 1 1');
      system2.runTimeout(() => {
        player.runCommand('inputpermission set @s movement enabled');
        player.runCommand('playsound aria_ah.chicken.laugh @a[r=15] ~~~ 1 1');
      }, 7);
      system2.runTimeout(() => {
        player.runCommand('playsound aria_ah.chicken.laugh @a[r=15] ~~~ 1 1');
      }, 22);
    }
  }
  onAttack(event) {
    const player = this.player;
    const objective = "aria_ah.player_chicken_mode";
    const scoreboard = world2.scoreboard.getObjective(objective);
    const score = scoreboard ? scoreboard.getScore(player) : undefined;

    if (score === 1) {
      // Original chicken mode behavior
      system2.runTimeout(() => {
        player.runCommand("function aria/ah/morph/attack_chicken");
      }, 3);

      player.runCommand("playsound aria_ah.hit_high @a ~~~ 1 1");

      const look = player.getViewDirection();
      const pos = player.location;
      const maxDistance = 4;
      const searchRadius = 4;

      const center = {
        x: pos.x + look.x * maxDistance,
        y: pos.y + look.y * maxDistance,
        z: pos.z + look.z * maxDistance
      };

      const entities = world2.getDimension(player.dimension.id).getEntities({
        location: center,
        maxDistance: searchRadius,
        excludeTypes: ["minecraft:player", "minecraft:item"]
      });

      let foundEntity = null;
      for (const entity of entities) {
        if (entity.id !== player.id) {
          foundEntity = entity;
          break;
        }
      }
      const entityPos = foundEntity ? foundEntity.location : null;

      const knockbackForce = {
        x: (entityPos?.x - player.location.x) || look.x * 3,
        y: (entityPos?.y - player.location.y) || 0.4,
        z: (entityPos?.z - player.location.z) || look.z * 3
      };

      player.applyKnockback({ x: knockbackForce.x, z: knockbackForce.z }, knockbackForce.y);
    } else if (score === 0) {
      // New mob knockback behavior
    const mobEntities = world2.getDimension(player.dimension.id).getEntities({
      location: player.location,
      maxDistance: 5,
      families: ["mob"],
      excludeTypes: ["minecraft:player", "minecraft:item"]
    });

    // Query aria_ah_creature
    const customEntities = world2.getDimension(player.dimension.id).getEntities({
      location: player.location,
      maxDistance: 5,
      families: ["aria_ah_creature"],
      excludeTypes: ["minecraft:player", "minecraft:item"]
    });

    // Combine and deduplicate
    const entitySet = new Set();
    for (const e of mobEntities) entitySet.add(e);
    for (const e of customEntities) entitySet.add(e);
    const allEntities = Array.from(entitySet);

    // Apply knockback to all
    const lookDirection = player.getViewDirection();
    for (const entity of allEntities) {
      entity.applyKnockback(
        {
          x: lookDirection.x * 8,
          z: lookDirection.z * 8
        },
        0.4
      );
    }

      // Optional: Add impact sound effect
      player.runCommand("playsound aria_ah.chicken.laugh");
    }
  }

  onDeath(event) {
    //this.player.sendMessage([this.type, "onDeath"].join(" "));
    this.player.runCommand("playsound aria_ah.chicken_death @a[r=15] ~~~ 2 0.8");
  }
  onHurt(event) {
    //this.player.sendMessage([this.type, "onHurt"].join(" "));
    this.player.runCommand("playsound aria_ah.hit_low @a[r=15] ~~~ 1 3");
  }
  onMorph(join) {
    //this.player.sendMessage([this.type, "onMorph"].join(" "));
    this.player.runCommand("function aria/ah/morph/new_morph");
    this.player.runCommand("function aria/ah/morph/tick_effect");
    this.player.runCommand("effect @s instant_health 1 10 true");
    this.player.runCommand("function aria/ah/morph/chicken/mode_1");
  }
  onTick(tick2) {
    if (tick2 % 200 === 0) {
      //this.player.sendMessage([this.type, "onTick"].join(" "));
      this.player.runCommand("function aria/ah/morph/tick_effect");
      if (tick2 % 200 === 0) {
        const player = this.player;
        const objective = "aria_ah.player_chicken_mode";

        // Get the scoreboard objective and player score
        const scoreboard = world2.scoreboard.getObjective(objective);
        const score = scoreboard ? scoreboard.getScore(player) : undefined;

        if (score === 1) {
          player.runCommand("function aria/ah/morph/chicken/tick_effect");
        }

        //this.player.sendMessage([this.type, "onTick"].join(" "));
        //this.player.runCommand("say hi22");
      }
    }
  }
  onUnmorph() {
    //this.player.sendMessage([this.type, "onUnmorph"].join(" "));
    this.player.runCommand("function aria/ah/morph/unmorph");
    this.player.runCommand("function aria/ah/morph/chicken/mode_1");
  }
};

// scripts/morph/cat-morph.ts
var SheepMorph = class extends Morph {
  constructor(player) {
    super(player, "sheep" /* SHEEP */);
  }
  onAbility(event) {
    const player = this.player;
    let hasTargetInView = false;

    // Helper vector functions
    function normalize(vec) {
      const length = Math.sqrt(vec.x * vec.x + vec.z * vec.z);
      return length === 0 ? { x: 0, z: 0 } : { x: vec.x / length, z: vec.z / length };
    }

    function dot(a, b) {
      return a.x * b.x + a.z * b.z;
    }

    // Get entities in view direction (40 blocks max)
    const entities = player.getEntitiesFromViewDirection({ maxDistance: 55 });

    for (const { entity: target } of entities) {
      // Skip non-entities and self
      if (target.id === player.id || target.typeId === "minecraft:player") continue;


      hasTargetInView = true;

      // Calculate facing directions
      const targetFacing = normalize(target.getViewDirection());
      const playerToTarget = normalize({
        x: player.location.x - target.location.x,
        z: player.location.z - target.location.z
      });

      // Check if target is facing away (dot product < 0)
      if (dot(targetFacing, playerToTarget) < 0) {
        // Calculate teleport position behind target
        const tpPos = {
          x: target.location.x - targetFacing.x * 1.5,
          y: target.location.y,
          z: target.location.z - targetFacing.z * 1.5
        };

        player.onScreenDisplay.setActionBar("§aTarget found!");



        // Delayed teleportation
        system2.runTimeout(() => {
          player.teleport(tpPos, {
            dimension: player.dimension,
            rotation: { x: 0, y: target.getRotation().y }
          });
        }, 9);
        system2.runTimeout(() => {
          player.runCommand("particle aria_ah:dark_fog");
          player.runCommand("playsound aria_ah.woosh @a[r=15] ~~~ 0.8 1");
          player.runCommand("function aria/ah/morph/attack_sheep");
          player.runCommand("playsound aria_ah.sheep_scream @a[r=15] ~~~ 0.7 1");
        }, 10);

        return;
      }
    }

    // Feedback messages
    if (hasTargetInView) {
      player.onScreenDisplay.setActionBar("§cTarget must be facing away!");
      player.runCommand("playsound note.bass @a ~~~ 0.5");
    } else {
      player.onScreenDisplay.setActionBar("§cNo valid target in sight!");
      player.runCommand("playsound note.bass @a ~~~ 0.5");
    }
  }


  onAttack(event) {
    const player = this.player;
    player.runCommand("playsound aria_ah.sheep_attack @a ~~~ 0.7 1");
    // Original attack logic
    system2.runTimeout(() => {
      // Run the sheep attack function


      // Find mobs within 5 blocks (excluding players and items)
      const mobEntities = player.dimension.getEntities({
        location: player.location,
        maxDistance: 5,
        families: ["mob"],
        excludeTypes: ["minecraft:player", "minecraft:item"]
      });

      const customEntities = player.dimension.getEntities({
        location: player.location,
        maxDistance: 5,
        families: ["aria_ah_creature"],
        excludeTypes: ["minecraft:player", "minecraft:item"]
      });

      // Combine and deduplicate
      const entitySet = new Set();
      for (const e of mobEntities) entitySet.add(e);
      for (const e of customEntities) entitySet.add(e);
      const allEntities = Array.from(entitySet);

      const lookDirection = player.getViewDirection();

      // Apply knockback to all nearby mobs
      for (const entity of allEntities) {
        entity.applyKnockback(
          {
            x: lookDirection.x * 8,  // X direction component
            z: lookDirection.z * 8   // Z direction component
          },
          1                          // Vertical strength (blocks)
        );
      }
      player.runCommand("function aria/ah/morph/attack_sheep");
      // Play impact sound

    }, 15);
  }
  onDeath(event) {
    //this.player.sendMessage([this.type, "onDeath"].join(" "));
    this.player.runCommand("playsound aria_ah.sheep_death @a[r=15] ~~~ 2 0.8");
  }
  onHurt(event) {
    //this.player.sendMessage([this.type, "onHurt"].join(" "));
    this.player.runCommand("playsound aria_ah.hit_low @a[r=15] ~~~ 1 3");
  }
  onMorph(join) {
    //this.player.sendMessage([this.type, "onMorph"].join(" "));
    this.player.runCommand("function aria/ah/morph/new_morph");
    this.player.runCommand("function aria/ah/morph/tick_effect");
    this.player.runCommand("effect @s instant_health 1 10 true");
  }
  onTick(tick2) {
    if (tick2 % 200 === 0) {
      //this.player.sendMessage([this.type, "onTick"].join(" "));
      this.player.runCommand("function aria/ah/morph/tick_effect");
    }
  }
  onUnmorph() {
    //this.player.sendMessage([this.type, "onUnmorph"].join(" "));
    this.player.runCommand("function aria/ah/morph/unmorph");
  }
};

// scripts/morph/fox-morph.ts
var FoxMorph = class extends Morph {
  constructor(player) {
    super(player, "fox" /* FOX */);
  }
  onAbility(event) {
    //this.player.sendMessage([this.type, "onAbility"].join(" "));
    this.player.runCommand("function aria/ah/morph/ability_fox");
    if (world2.scoreboard.getObjective("aria_ah.general").getScore("vv_active")) {
      this.player.runCommand("particle aria_ah:scream_white_vv ^^1.6^");
    } else {
      this.player.runCommand("particle aria_ah:scream_white ^^1.6^");
    }

  }
  onAttack(event) {
    //this.player.sendMessage([this.type, "onAttack"].join(" "));
    system2.runTimeout(() => {
      this.player.runCommand("function aria/ah/morph/attack_fox");
    }, 1 * 12)
    this.player.runCommand("playsound aria_ah.fox_attack @a ~~~ 0.7 1");
  }
  onDeath(event) {
    //this.player.sendMessage([this.type, "onDeath"].join(" "));
    this.player.runCommand("playsound aria_ah.fox_death @a[r=15] ~~~ 2 0.8");
  }
  onHurt(event) {
    //this.player.sendMessage([this.type, "onHurt"].join(" "));
    this.player.runCommand("playsound aria_ah.hit_low @a[r=15] ~~~ 1 3");
  }
  onMorph(join) {
    //this.player.sendMessage([this.type, "onMorph"].join(" "));
    this.player.runCommand("function aria/ah/morph/new_morph");
    this.player.runCommand("function aria/ah/morph/tick_effect");
    this.player.runCommand("effect @s instant_health 1 10 true");
  }
  onTick(tick2) {
    if (tick2 % 200 === 0) {
      //this.player.sendMessage([this.type, "onTick"].join(" "));
      this.player.runCommand("function aria/ah/morph/tick_effect");
    }
  }
  onUnmorph() {
    //this.player.sendMessage([this.type, "onUnmorph"].join(" "));
    this.player.runCommand("function aria/ah/morph/unmorph");
  }
};

// scripts/morph-manager.ts
var MorphManager = class {
  constructor() {
    this.onScriptEventReceive = (event) => {
      const { id, message } = event;
      const player = event.sourceEntity;
      if (id !== "aria_ah:morph" || !(player instanceof Player2)) {
        return;
      }
      const mobType = MorphType[message.toUpperCase()];
      const slot = this.getOffhandSlot(player);
      if (!slot) {
        return;
      }
      const oldItem = slot.hasItem() ? slot.getItem() : void 0;
      if (!mobType) {
        if (oldItem?.getTags().includes("aria_ah.morph")) {
          slot.setItem();
        }
        return;
      }
      const item = new ItemStack3(`aria_ah:${mobType}_morph`);
      item.lockMode = ItemLockMode2.slot;
      item.keepOnDeath = true;
      slot.setItem(item);
      if (!oldItem || oldItem.getTags().includes("aria_ah.morph")) {
        return;
      }
      const inventory = player.getComponent(EntityInventoryComponent2.componentId);
      if (!inventory.isValid) {
        return;
      }
      const { container } = inventory;
      if (!container?.isValid) {
        return;
      }
      const remaining = container.addItem(oldItem);
      if (remaining) {
        player.dimension.spawnItem(remaining, player.location);
      }
    };
    this.onPlayerLeave = ({ playerId }) => {
      const mob = this.players[playerId];
      if (world2.getAllPlayers().length > 0) {
        mob?.leave();
      }
      delete this.firstPlayerTick[playerId];
      delete this.players[playerId];
    };
    this.onItemStartUse = (event) => {
      const mob = this.players[event.source.id];
      if (!mob) {
        return;
      }
      const cooldown = event.itemStack.getComponent(ItemComponentTypes.Cooldown);
      if (!cooldown) {
        return;
      }
      const cooldownOffset = cooldown.getCooldownTicksRemaining(mob.player) - cooldown.cooldownTicks;
      if (cooldownOffset < -1) {
        return;
      }
      if (event.itemStack.getTags().includes("aria_ah.ability")) {
        mob.ability(event);
      }
      if (event.itemStack.getTags().includes("aria_ah.attack")) {
        mob.attack(event);
      }
    };
    this.onEntitySpawn = (event) => {
      if (event.entity.typeId !== "minecraft:item" || !event.entity.isValid) {
        return;
      }
      const item = event.entity.getComponent(EntityComponentTypes.Item)?.itemStack;
      if (!item) {
        return;
      }
      const tags = ["aria_ah.ability", "aria_ah.attack", "aria_ah.morph"];
      if (item.getTags().some((tag) => tags.includes(tag))) {
        event.entity.remove();
      }
    };
    this.onEntityHurt = (event) => {
      const mob = this.getMorph(event.hurtEntity);
      if (!mob) {
        return;
      }
      mob.hurt(event);
    };
    this.onEntityDie = (event) => {
      const mob = this.getMorph(event.deadEntity);
      if (!mob) {
        return;
      }
      console.warn(event.deadEntity.typeId, event.deadEntity.id);
      delete this.players[event.deadEntity.id];
      mob.death(event);
      mob.player.runCommand("replaceitem entity @s slot.weapon.offhand 0 air");
    };
    this.firstPlayerTick = {};
    this.players = {};
    world2.afterEvents.entitySpawn.subscribe(this.onEntitySpawn);
    world2.afterEvents.playerLeave.subscribe(this.onPlayerLeave);
    world2.afterEvents.entityHurt.subscribe(this.onEntityHurt, { entityTypes: ["minecraft:player"] });
    world2.afterEvents.entityDie.subscribe(this.onEntityDie, { entityTypes: ["minecraft:player"] });
    world2.afterEvents.itemStartUse.subscribe(this.onItemStartUse);
    system2.afterEvents.scriptEventReceive.subscribe(this.onScriptEventReceive, { namespaces: ["aria_ah"] });
    world2.afterEvents.worldLoad.subscribe(() => {
      system2.runInterval(() => {
        this.tick(system2.currentTick);
      }, 1);
    });
  }
  tick(tick2) {
    for (const player of world2.getAllPlayers()) {
      const { id } = player;
      const firstTick = this.firstPlayerTick[id] === void 0;
      if (firstTick) {
        this.firstPlayerTick[id] = system2.currentTick;
      }
      const lastMob = this.players[id];
      const mobType = this.getItemMorphType(player);
      if (!mobType) {
        if (lastMob) {
          lastMob.unmorph();
          delete this.players[id];
        }
        continue;
      }
      const same = lastMob && lastMob.type === mobType;
      if (same) {
        lastMob.tick(tick2);
      } else {
        lastMob?.unmorph();
        const mob = this.createMob(player, mobType);
        this.players[id] = mob;
        mob.morph(firstTick);
      }
    }
  }
  getMorph(entity) {
    if (!entity || !(entity instanceof Player2)) {
      return;
    }
    return this.players[entity.id];
  }
  getOffhandSlot(player) {
    const inventory = player.getComponent(EntityEquippableComponent2.componentId);
    if (!inventory.isValid) {
      return;
    }
    const slot = inventory.getEquipmentSlot(EquipmentSlot.Offhand);
    if (!slot.isValid) {
      return;
    }
    return slot;
  }
  getItemMorphType(player) {
    const slot = this.getOffhandSlot(player);
    if (!slot?.hasItem()) {
      return;
    }
    const { typeId } = slot;
    const rawId = typeId.replace("aria_ah:", "");
    if (rawId === typeId || !slot.getTags().includes("aria_ah.morph")) {
      return;
    }
    const type = rawId.replace("_morph", "");
    return MorphType[type.toUpperCase()];
  }
  createMob(player, type) {
    switch (type) {
      case "cow" /* COW */: {
        return new CowMorph(player);
      }
      case "fox" /* FOX */: {
        return new FoxMorph(player);
      }
      case "rabbit" /* RABBIT */: {
        return new RabbitMorph(player);
      }
      case "horse" /* HORSE */: {
        return new HorseMorph(player);
      }
      case "wolf" /* WOLF */: {
        return new WolfMorph(player);
      }
      case "cat" /* CAT */: {
        return new CatMorph(player);
      }
      case "pig" /* PIG */: {
        return new PigMorph(player);
      }
      case "sheep" /* SHEEP */: {
        return new SheepMorph(player);
      }
      case "chicken" /* CHICKEN */: {
        return new ChickenMorph(player);
      }
    }
  }
};

/*world2.afterEvents.entityDie.subscribe((event) => {
  //try {
  const deadEntity = event.entity;
  const damageSource = event.damageSource;
  console.warn(1, damageSource.cause, !damageSource.damagingEntity || damageSource.damagingEntity.typeId != "minecraft:player")
  // Verify the damage type and attacker
  if (damageSource.cause !== EntityDamageCause.entityAttack) return;
  if (!damageSource.damagingEntity || damageSource.damagingEntity.typeId != "minecraft:player") return;
  console.warn(2)
  const killer = damageSource.damagingEntity;

  // Verify specific player and score
  if (killer.id !== this.player.id) return;
  const score = world2.scoreboard.getObjective("aria_ah.player_chicken_mode")?.getScore(killer);
  if (score !== 1) return;
  console.warn(4)
  // Distance check (5 blocks)
  if (killer.location.distance(deadEntity.location) > 5) return;
  console.warn(5)
  // Apply effects
  killer.runCommand("effect @s regeneration 3 1");
  killer.runCommand("particle aria_ah:pixel_heal_once ~ ~1 ~ 0.5 0.5 0.5 0.1 3");
  killer.runCommand("playsound aria_ah.life_steal @s ~~~ 0.8 1.2");

  /*} catch (error) {
      console.error("Life steal error:", error);
  }*/
//);

// scripts/main.ts
new MorphManager();

//# sourceMappingURL=../debug/main.js.map


/**
 * 
 * @param {ItemStack2} itemStack 
 * @returns {string}
 */
function itemStackToJson(itemStack) {
  const result = {
    typeId: itemStack.typeId,
    amount: itemStack.amount,
    nameTag: itemStack.nameTag,
    lockMode: itemStack.lockMode,
    keepOnDeath: itemStack.keepOnDeath,
    lore: itemStack.getLore(),
    canPlaceOn: itemStack.getCanPlaceOn(),
    canDestroy: itemStack.getCanDestroy(),
    components: {},
    dynamicProperties: {}
  };

  const enchantable = itemStack.getComponent(ItemComponentTypes.Enchantable);
  if (enchantable && typeof enchantable.getEnchantments === "function") {
    result.components.enchantments = enchantable.getEnchantments().map(e => (console.log(JSON.stringify(e)), {
      type: e.type.id,
      level: e.level
    }));
  }
  const durability = itemStack.getComponent(ItemComponentTypes.Durability);
  if (durability && typeof durability.damage === "number") {
    result.components.durability = {
      damage: durability.damage,
      maxDurability: durability.maxDurability
    };
  }

  for (const id of itemStack.getDynamicPropertyIds()) {
    result.dynamicProperties[id] = itemStack.getDynamicProperty(id);
  }

  return JSON.stringify(result);
}

function jsonToItemStack(jsonString) {
  const data = JSON.parse(jsonString);

  const itemStack = new ItemStack2(data.typeId, data.amount);

  if (data.nameTag) itemStack.nameTag = data.nameTag;
  if (data.lockMode) itemStack.lockMode = data.lockMode;
  if (typeof data.keepOnDeath === "boolean") itemStack.keepOnDeath = data.keepOnDeath;
  if (Array.isArray(data.lore)) itemStack.setLore(data.lore);
  if (Array.isArray(data.canPlaceOn)) itemStack.setCanPlaceOn(data.canPlaceOn);
  if (Array.isArray(data.canDestroy)) itemStack.setCanDestroy(data.canDestroy);

  if (data.components) {
    if (Array.isArray(data.components.enchantments)) {
      /**
       * @type {ItemEnchantableComponent}
       */
      const enchantable = itemStack.getComponent(ItemComponentTypes.Enchantable);
      if (enchantable && typeof enchantable.addEnchantments === "function" && data.components.enchantments?.length > 0) {
        enchantable.addEnchantments(data.components.enchantments.map(e => ({
          type: new EnchantmentType(e.type),
          level: e.level
        })));
      }
    }
    if (data.components.durability) {
      const durability = itemStack.getComponent(ItemComponentTypes.Durability);
      if (durability) {
        durability.damage = data.components.durability.damage;
      }
    }
  }

  if (data.dynamicProperties) {
    for (const id in data.dynamicProperties) {
      itemStack.setDynamicProperty(id, data.dynamicProperties[id]);
    }
  }

  return itemStack;
}
