// minecraft-module-proxy:@minecraft/server
import { EntityDamageCause } from "@minecraft/server";
import { EquipmentSlot } from "@minecraft/server";
import { GameMode } from "@minecraft/server";
import { EntityEquippableComponent } from "@minecraft/server";
import { ItemStack } from "@minecraft/server";
import { MolangVariableMap } from "@minecraft/server";
import { Player } from "@minecraft/server";
import { TicksPerSecond } from "@minecraft/server";
import { system } from "@minecraft/server";
import { world } from "@minecraft/server";

// src/runtime/systems/guidebook/guidebook.ts
var Guidebook;
((Guidebook2) => {
  const overworld = world.getDimension("overworld");
  const nether = world.getDimension("nether");
  const end = world.getDimension("the_end");
  const guideBookQuery = { type: `${"spark_amm2"}:guide_book` };
  const bookSpawnActionBarRange = 8;
  let bookItemId, projectLangName;
  let playerJoinTag;
  var queuedSpawns = [];
  function init({ entityId, itemId, tag, projectName }) {
    guideBookQuery.type = entityId;
    bookItemId = itemId;
    playerJoinTag = tag;
    projectLangName = projectName;
    system.run(tick3);
  }
  Guidebook2.init = init;
  function tick3() {
    system.run(tick3);
    for (const book of overworld.getEntities(guideBookQuery)) {
      checkForSpawn(book);
      checkInteraction(book);
    }
    for (const book of nether.getEntities(guideBookQuery)) {
      checkForSpawn(book);
      checkInteraction(book);
    }
    for (const book of end.getEntities(guideBookQuery)) {
      checkForSpawn(book);
      checkInteraction(book);
    }
    for (let i = queuedSpawns.length - 1; i > -1; i--) {
      let q = queuedSpawns[i];
      let dim = q.player.dimension;
      let entity = dim.spawnEntity(guideBookQuery.type, q.location);
      entity.teleport(entity.location, { facingLocation: q.player.location });
      if (q.item.amount > 1) {
        let inventory = q.player.getComponent("minecraft:inventory");
        let container = inventory.container;
        for (let i2 = 0; i2 < 10; i2++) {
          let item = container.getItem(i2);
          if (item == void 0)
            continue;
          if (item.typeId === q.item.typeId) {
            let cloned = q.item.clone();
            cloned.amount = cloned.amount - 1;
            container.setItem(i2, cloned);
            break;
          }
        }
      }
      if (q.item.amount == 1) {
        let inventory = q.player.getComponent("minecraft:inventory");
        let container = inventory.container;
        for (let i2 = 0; i2 < 10; i2++) {
          let item = container.getItem(i2);
          if (item == void 0)
            continue;
          if (item.typeId === q.item.typeId) {
            container.setItem(i2, void 0);
            break;
          }
        }
      }
      queuedSpawns.splice(i, 1);
    }
  }
  function checkForSpawn(book) {
    if (book.hasTag(`spark.${projectLangName}:action_bar_sent`))
      return;
    for (const player of book.dimension.getPlayers({ location: book.location, maxDistance: bookSpawnActionBarRange })) {
      player.onScreenDisplay.setActionBar({
        rawtext: [
          {
            translate: `spark.${projectLangName}.book.open`
          }
        ]
      });
    }
    book.addTag(`spark.${projectLangName}:action_bar_sent`);
  }
  function checkInteraction(book) {
    const prop = book.getProperty(`${"spark_amm2"}:waiting_for_process`);
    if (prop === void 0)
      return;
    let isWaiting = prop;
    if (isWaiting) {
      processInteraction(book);
    }
  }
  function processInteraction(book) {
    for (const player of book.dimension.getPlayers()) {
      if (distanceSquared(book.location, player.location) > 34)
        continue;
      if (!bookWithinFov(book, player))
        return;
      let plyLoc = player.location;
      let globY = plyLoc.y;
      let bk = book.location;
      bk.y = globY;
      let dist = distance(plyLoc, bk);
      let normal = normalized(player.getViewDirection());
      let scaled = scale(normal, dist);
      let point = add(plyLoc, scaled);
      point.y = globY;
      let vec = subtract(plyLoc, bk);
      let dir = subtract(plyLoc, point);
      let angle = angleToSigned(vec, dir, { x: 0, y: 1, z: 0 });
      if (angle > 0) {
        book.triggerEvent(`${"spark_amm2"}:trigger_back_animation`);
        book.setProperty(`${"spark_amm2"}:waiting_for_process`, false);
        system.runTimeout(() => {
          book.triggerEvent(`${"spark_amm2"}:guide_book_back`);
        }, 7);
        continue;
      }
      book.triggerEvent(`${"spark_amm2"}:trigger_forward_animation`);
      book.setProperty(`${"spark_amm2"}:waiting_for_process`, false);
      system.runTimeout(() => {
        book.triggerEvent(`${"spark_amm2"}:guide_book_forward`);
      }, 7);
      continue;
    }
  }
  function bookWithinFov(book, player) {
    let EP = normalized(subtract(player.getHeadLocation(), book.location));
    let pdot = dot(EP, player.getViewDirection());
    if (pdot < -0.5) {
      return true;
    }
    return false;
  }
  function angleToSigned(a, b, n) {
    let pcross = cross(a, b);
    let dot1 = dot(n, pcross);
    let dot2 = dot(a, b);
    let atan2 = Math.atan2(dot1, dot2);
    return atan2;
  }
  world.afterEvents.playerSpawn.subscribe((event) => {
    if (event.initialSpawn) {
      if (event.player.hasTag(playerJoinTag))
        return;
      event.player.addTag(playerJoinTag);
      event.player.runCommandAsync("gamerule sendcommandfeedback false");
      event.player.runCommandAsync(`give @s ${bookItemId}`);
      event.player.runCommandAsync("gamerule sendcommandfeedback true");
      system.runTimeout(() => {
        event.player.sendMessage({
          rawtext: [
            {
              translate: `spark.${projectLangName}.chat.is_active`
            }
          ]
        });
      }, 100);
    }
  });
  world.beforeEvents.itemUse.subscribe((event) => {
    if (event.itemStack.typeId != bookItemId)
      return;
    let player = event.source;
    let dir = player.getViewDirection();
    dir.y = 0;
    let blockRaycastResult = event.source.dimension.getBlockFromRay(player.location, player.getViewDirection(), { maxDistance: 2 });
    if (blockRaycastResult == void 0) {
      let pos = player.location;
      let dist = scale(dir, 2);
      let newPos = add(pos, dist);
      queuedSpawns.push({
        location: newPos,
        player: event.source,
        item: event.itemStack
      });
      event.cancel = true;
    }
  });
  function distance(a, b) {
    return Math.sqrt(distanceSquared(a, b));
  }
  function distanceSquared(a, b) {
    const dx = a.x - b.x;
    const dy = a.y - b.y;
    const dz = a.z - b.z;
    return dx * dx + dy * dy + dz * dz;
  }
  function length(a) {
    return Math.sqrt(lengthSquared(a));
  }
  function lengthSquared(a) {
    return a.x * a.x + a.y * a.y + a.z * a.z;
  }
  function normalized(a) {
    return scale(a, 1 / (length(a) || 1));
  }
  function scale(a, b) {
    return {
      x: a.x * b,
      y: a.y * b,
      z: a.z * b
    };
  }
  function add(a, b) {
    return {
      x: a.x + b.x,
      y: a.y + b.y,
      z: a.z + b.z
    };
  }
  function subtract(a, b) {
    return {
      x: a.x - b.x,
      y: a.y - b.y,
      z: a.z - b.z
    };
  }
  function dot(a, b) {
    return a.x * b.x + a.y * b.y + a.z * b.z;
  }
  function cross(a, b) {
    const ax = a.x, ay = a.y, az = a.z;
    const bx = b.x, by = b.y, bz = b.z;
    return { x: ay * bz - az * by, y: az * bx - ax * bz, z: ax * by - ay * bx };
  }
})(Guidebook || (Guidebook = {}));

// src/runtime/configs/guidebook.ts
var config = {
  entityId: `${"spark_amm2"}:guide_book`,
  tag: `${"spark_amm2"}:player_joined_already`,
  itemId: `${"spark_amm2"}:guide_book_spawn_egg`,
  projectName: "amm2"
};

// src/runtime/systems/guidebook/main.ts
Guidebook.init(config);

// src/runtime/utils/vec2.ts
var Vec2 = class _Vec2 {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
  static withX(v, x) {
    return new _Vec2(x, v.y);
  }
  withX(x) {
    return new _Vec2(x, this.y);
  }
  static withY(v, y) {
    return new _Vec2(v.x, y);
  }
  withY(y) {
    return new _Vec2(this.x, y);
  }
  min(v) {
    return new _Vec2(this.x < v.x ? this.x : v.x, this.y < v.y ? this.y : v.y);
  }
  static min(v1, v22) {
    return new _Vec2(v1.x < v22.x ? v1.x : v22.x, v1.y < v22.y ? v1.y : v22.y);
  }
  max(v) {
    return new _Vec2(this.x > v.x ? this.x : v.x, this.y > v.y ? this.y : v.y);
  }
  static max(v1, v22) {
    return new _Vec2(v1.x > v22.x ? v1.x : v22.x, v1.y > v22.y ? v1.y : v22.y);
  }
  static abs(v) {
    return new _Vec2(Math.abs(v.x), Math.abs(v.y));
  }
  abs() {
    return new _Vec2(Math.abs(this.x), Math.abs(this.y));
  }
  static add(v1, v22) {
    return new _Vec2(v1.x + v22.x, v1.y + v22.y);
  }
  add(v) {
    return new _Vec2(this.x + v.x, this.y + v.y);
  }
  static subtract(v1, v22) {
    return new _Vec2(v1.x - v22.x, v1.y - v22.y);
  }
  subtract(v) {
    return new _Vec2(this.x - v.x, this.y - v.y);
  }
  static multiply(v1, v22) {
    return new _Vec2(v1.x * v22.x, v1.y * v22.y);
  }
  multiply(v) {
    return new _Vec2(this.x * v.x, this.y * v.y);
  }
  static equals(v1, v22) {
    return v1.x === v22.x && v1.y === v22.y;
  }
  equals(v) {
    return this.x === v.x && this.y === v.y;
  }
  static scale(v, scalar) {
    return new _Vec2(v.x * scalar, v.y * scalar);
  }
  scale(scalar) {
    return new _Vec2(this.x * scalar, this.y * scalar);
  }
  static normal(v) {
    const length = Math.sqrt(v.x * v.x + v.y * v.y);
    return new _Vec2(v.x / length, v.y / length);
  }
  normal() {
    const length = this.mag();
    return new _Vec2(this.x / length, this.y / length);
  }
  static mag(v) {
    return Math.sqrt(v.x * v.x + v.y * v.y);
  }
  mag() {
    return Math.sqrt(this.x * this.x + this.y * this.y);
  }
  static distance(v1, v22) {
    return _Vec2.subtract(v1, v22).mag();
  }
  distance(v) {
    return this.subtract(v).mag();
  }
  static dot(v1, v22) {
    return v1.x * v22.x + v1.y * v22.y;
  }
  dot(v) {
    return this.x * v.x + this.y * v.y;
  }
  static lerp(i1, i2, alpha) {
    return v2.wrap(i1).lerp(i2, alpha);
  }
  lerp(v, alpha) {
    return this.scale(1 - alpha).add(v2.wrap(v).scale(alpha));
  }
  static floor(v) {
    return new _Vec2(Math.floor(v.x), Math.floor(v.y));
  }
  static rotate(v, angle) {
    const x = v.x * Math.cos(angle) - v.y * Math.sin(angle);
    const y = v.x * Math.sin(angle) + v.y * Math.cos(angle);
    return new _Vec2(x, y);
  }
  rotate(angle) {
    const x = this.x * Math.cos(angle) - this.y * Math.sin(angle);
    const y = this.x * Math.sin(angle) + this.y * Math.cos(angle);
    return new _Vec2(x, y);
  }
  round() {
    return new _Vec2(Math.round(this.x), Math.round(this.y));
  }
  static round(v) {
    return new _Vec2(Math.round(v.x), Math.round(v.y));
  }
  floor() {
    return new _Vec2(Math.floor(this.x), Math.floor(this.y));
  }
  clone() {
    return new _Vec2(this.x, this.y);
  }
  toString() {
    return `Vector2<${this.x}, ${this.y}>`;
  }
  unwrap() {
    return { x: this.x, y: this.y };
  }
};
var v2 = (x, y) => {
  return new Vec2(x, y);
};
v2.wrap = (v) => new Vec2(v.x, v.y);
v2.north = v2(0, -1);
v2.south = v2(0, 1);
v2.east = v2(1, 0);
v2.west = v2(-1, 0);
v2.zero = v2(0, 0);
v2.one = v2(1, 1);

// src/runtime/utils/math.ts
function radianToDegree(rad) {
  return rad / Math.PI * 180;
}
function degreeToRadian(deg) {
  return Math.PI / (180 / deg);
}

// src/runtime/utils/vec3.ts
var Vec3 = class _Vec3 {
  constructor(x, y, z) {
    this.x = x;
    this.y = y;
    this.z = z;
  }
  static withX(v, x) {
    return new _Vec3(x, v.y, v.z);
  }
  withX(x) {
    return new _Vec3(x, this.y, this.z);
  }
  static withY(v, y) {
    return new _Vec3(v.x, y, v.z);
  }
  withY(y) {
    return new _Vec3(this.x, y, this.z);
  }
  static withZ(v, z) {
    return new _Vec3(v.x, v.y, z);
  }
  withZ(z) {
    return new _Vec3(this.x, this.y, z);
  }
  min(v) {
    return new _Vec3(this.x < v.x ? this.x : v.x, this.y < v.y ? this.y : v.y, this.z < v.z ? this.z : v.z);
  }
  static min(v1, v22) {
    return new _Vec3(v1.x < v22.x ? v1.x : v22.x, v1.y < v22.y ? v1.y : v22.y, v1.z < v22.z ? v1.z : v22.z);
  }
  max(v) {
    return new _Vec3(this.x > v.x ? this.x : v.x, this.y > v.y ? this.y : v.y, this.z > v.z ? this.z : v.z);
  }
  static max(v1, v22) {
    return new _Vec3(v1.x > v22.x ? v1.x : v22.x, v1.y > v22.y ? v1.y : v22.y, v1.z > v22.z ? v1.z : v22.z);
  }
  static abs(v) {
    return new _Vec3(Math.abs(v.x), Math.abs(v.y), Math.abs(v.z));
  }
  abs() {
    return new _Vec3(Math.abs(this.x), Math.abs(this.y), Math.abs(this.z));
  }
  static add(v1, v22) {
    return new _Vec3(v1.x + v22.x, v1.y + v22.y, v1.z + v22.z);
  }
  add(v) {
    return new _Vec3(this.x + v.x, this.y + v.y, this.z + v.z);
  }
  static subtract(v1, v22) {
    return new _Vec3(v1.x - v22.x, v1.y - v22.y, v1.z - v22.z);
  }
  subtract(v) {
    return new _Vec3(this.x - v.x, this.y - v.y, this.z - v.z);
  }
  static multiply(v1, v22) {
    return new _Vec3(v1.x * v22.x, v1.y * v22.y, v1.z * v22.z);
  }
  multiply(v) {
    return new _Vec3(this.x * v.x, this.y * v.y, this.z * v.z);
  }
  static equals(v1, v22) {
    return v1.x === v22.x && v1.y === v22.y && v1.z === v22.z;
  }
  equals(v) {
    return this.x === v.x && this.y === v.y && this.z === v.z;
  }
  static scale(v, scalar) {
    return new _Vec3(v.x * scalar, v.y * scalar, v.z * scalar);
  }
  scale(scalar) {
    return new _Vec3(this.x * scalar, this.y * scalar, this.z * scalar);
  }
  static normal(v) {
    const length = Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
    return new _Vec3(v.x / length, v.y / length, v.z / length);
  }
  normal() {
    const length = this.mag();
    return new _Vec3(this.x / length, this.y / length, this.z / length);
  }
  static mag(v) {
    return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
  }
  mag() {
    return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
  }
  static distance(v1, v22) {
    return _Vec3.subtract(v1, v22).mag();
  }
  distance(v) {
    return this.subtract(v).mag();
  }
  static dot(v1, v22) {
    return v1.x * v22.x + v1.y * v22.y + v1.z * v22.z;
  }
  dot(v) {
    return this.x * v.x + this.y * v.y + this.z * v.z;
  }
  static cross(v1, v22) {
    return new _Vec3(v1.y * v22.z - v1.z * v22.y, v1.z * v22.x - v1.x * v22.z, v1.x * v22.y - v1.y * v22.x);
  }
  cross(v) {
    return new _Vec3(this.y * v.z - this.z * v.y, this.z * v.x - this.x * v.z, this.x * v.y - this.y * v.x);
  }
  static lerp(v1, v22, alpha) {
    return v3.wrap(v1).lerp(v22, alpha);
  }
  lerp(v, alpha) {
    return this.scale(1 - alpha).add(v3.wrap(v).scale(alpha));
  }
  static floor(v) {
    return new _Vec3(Math.floor(v.x), Math.floor(v.y), Math.floor(v.z));
  }
  static rotateY(v, angle) {
    const x = v.x * Math.cos(angle) - v.z * Math.sin(angle);
    const z = v.x * Math.sin(angle) + v.z * Math.cos(angle);
    return new _Vec3(x, v.y, z);
  }
  rotateY(angle) {
    const x = this.x * Math.cos(angle) - this.z * Math.sin(angle);
    const z = this.x * Math.sin(angle) + this.z * Math.cos(angle);
    return new _Vec3(x, this.y, z);
  }
  round() {
    return new _Vec3(Math.round(this.x), Math.round(this.y), Math.round(this.z));
  }
  static round(v) {
    return new _Vec3(Math.round(v.x), Math.round(v.y), Math.round(v.z));
  }
  floor() {
    return new _Vec3(Math.floor(this.x), Math.floor(this.y), Math.floor(this.z));
  }
  static spherical(dist, rot) {
    rot.y = degreeToRadian(-rot.y), rot.x = degreeToRadian(rot.x + 90);
    return new _Vec3(
      dist * Math.sin(rot.y) * Math.sin(rot.x),
      dist * Math.cos(rot.x),
      dist * Math.cos(rot.y) * Math.sin(rot.x)
    );
  }
  clone() {
    return new _Vec3(this.x, this.y, this.z);
  }
  toString() {
    return `Vector3<${this.x}, ${this.y}, ${this.z}>`;
  }
  unwrap() {
    return { x: this.x, y: this.y, z: this.z };
  }
  length() {
    return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
  }
  get xy() {
    return new Vec2(this.x, this.y);
  }
  static Up() {
    return new _Vec3(0, 1, 0);
  }
  static Down() {
    return new _Vec3(0, -1, 0);
  }
  static North() {
    return new _Vec3(0, 0, -1);
  }
  static South() {
    return new _Vec3(0, 0, 1);
  }
  static East() {
    return new _Vec3(1, 0, 0);
  }
  static West() {
    return new _Vec3(-1, 0, 0);
  }
  static Zero() {
    return new _Vec3(0, 0, 0);
  }
  static One() {
    return new _Vec3(1, 1, 1);
  }
};
var v3 = (x, y, z) => {
  return new Vec3(x, y, z);
};
v3.wrap = (v) => new Vec3(v.x, v.y, v.z);
v3.up = v3(0, 1, 0);
v3.down = v3(0, -1, 0);
v3.north = v3(0, 0, -1);
v3.south = v3(0, 0, 1);
v3.east = v3(1, 0, 0);
v3.west = v3(-1, 0, 0);
v3.zero = v3(0, 0, 0);
v3.one = v3(1, 1, 1);

// src/runtime/configs/mobs.ts
var config2 = {
  hammer_piglin: {
    attackDamage: 8,
    attackRadius: 5,
    knockbackStrength: 4,
    ignoredEntities: [
      "minecraft:item",
      "minecraft:xp_orb"
    ]
  },
  drum_piglin: {
    // @config: the range of the buff
    range: 10,
    buff: "strength",
    amplifier: 1,
    duration: 8,
    families: ["piglin"],
    anim_duration: 5,
    effect_anim: "spark_amm2:heal_effect"
  },
  piglin_general: {
    specialAttackDamage: 2,
    specialAttackRadius: 4,
    knockbackPower: 3,
    powerAttackCooldown: 5,
    powerAttackDamage: 5,
    powerAttackKnockback: 2,
    spinDuration: 4
  },
  malgosha: {
    minion_spawn_amount: [8, 10],
    minion_spawn_range: [3, 14],
    minion_spawn_pool: [
      "minecraft:piglin",
      `${"spark_amm2"}:torch_piglin`,
      `${"spark_amm2"}:piglin_general`,
      `${"spark_amm2"}:hammer_piglin`,
      `${"spark_amm2"}:spear_piglin`,
      `${"spark_amm2"}:drum_piglin`,
      `${"spark_amm2"}:warrior_piglin`,
      `${"spark_amm2"}:chef_piglin`,
      `${"spark_amm2"}:pickaxe_piglin`
    ],
    sweap_fov: 0.2,
    sweap_range: 5,
    sweap_trigger_range: 4,
    sweap_damage: 7,
    sweap_cooldown: 3 * 20,
    sweap_knockback_horizontal: 4,
    sweap_knockback_veritcal: 1
  }
};

// src/runtime/systems/mobs/hammer_piglin/main.ts
system.afterEvents.scriptEventReceive.subscribe(
  piglinSpecialAttack,
  { namespaces: ["spark_amm2"] }
);
function piglinSpecialAttack(e) {
  if (e.id !== "spark_amm2:hammer_piglin_special_attack")
    return;
  const { dimension, location, id: myId } = e.sourceEntity;
  e.sourceEntity?.addEffect("slowness", 60, {
    amplifier: 100,
    showParticles: false
  });
  e.sourceEntity?.addEffect("weakness", 60, {
    amplifier: 100,
    showParticles: false
  });
  system.runTimeout(function performHammerAttack() {
    const entities = dimension.getEntities({
      location,
      excludeTypes: config2.hammer_piglin.ignoredEntities,
      maxDistance: config2.hammer_piglin.attackRadius
    });
    for (const entity of entities) {
      if (entity.id === myId)
        continue;
      let offset = Vec3.subtract(
        entity.location,
        location
      ).normal();
      try {
        entity.applyKnockback(
          offset.x,
          offset.z,
          config2.hammer_piglin.knockbackStrength,
          0.2
        );
      } catch (e2) {
      }
      try {
        entity.applyDamage(config2.hammer_piglin.attackDamage, {
          damagingEntity: e.initiator,
          cause: EntityDamageCause.entityAttack
        });
      } catch (e2) {
      }
    }
  }, 30);
}

// src/runtime/systems/mobs/drum_piglin/main.ts
system.afterEvents.scriptEventReceive.subscribe(
  function processDrumBuff(arg) {
    if (arg.id !== "spark_amm2:drum_piglin_buff")
      return;
    arg.sourceEntity.triggerEvent("spark_amm2:stop_moving");
    const { dimension, location } = arg.sourceEntity;
    try {
      arg.sourceEntity.setProperty(
        "spark_amm2:trigger_buff_animation",
        true
      );
    } catch {
      return;
    }
    let map = new MolangVariableMap();
    map.setFloat("radius", config2.drum_piglin.range);
    arg.sourceEntity.dimension.spawnParticle(
      "spark_amm2:aoe",
      arg.sourceEntity.location,
      map
    );
    system.runTimeout(() => {
      try {
        arg.sourceEntity.setProperty(
          "spark_amm2:trigger_buff_animation",
          false
        );
      } catch {
        return;
      }
      arg.sourceEntity.triggerEvent("spark_amm2:start_moving");
      const entitiesToBuff = dimension.getEntities({
        location,
        maxDistance: config2.drum_piglin.range,
        families: config2.drum_piglin.families
      });
      try {
        entitiesToBuff.forEach((e) => {
          e.addEffect(
            config2.drum_piglin.buff,
            config2.drum_piglin.duration * 20,
            {
              amplifier: config2.drum_piglin.amplifier,
              showParticles: true
            }
          );
          e.dimension.spawnParticle(
            "spark_amm2:heal_effect",
            e.location
          );
        });
      } catch {
      }
    }, config2.drum_piglin.anim_duration * 20);
  },
  {
    namespaces: ["spark_amm2"]
  }
);

// src/runtime/configs/projectiles.ts
var config3 = {
  "spark_amm2:malgosha_fireball": {
    gravity: 0,
    velocity: 2,
    on_hit: {
      impact_damage: 0
    }
  },
  "spark_amm2:great_hog_projectile": {
    gravity: 0,
    velocity: 0.8,
    on_hit: {
      impact_damage: 4
    }
  },
  "spark_amm2:tater_tot_projectile": {
    gravity: 0.2,
    velocity: 1.1,
    on_hit: {
      impact_damage: 4
    }
  },
  "spark_amm2:enderpearl_potate_projectile": {
    gravity: 0.4,
    velocity: 1.8,
    alt_velocity: 2.8,
    on_hit: {
      impact_damage: 2,
      teleport: true
    }
  },
  "spark_amm2:projectile_of_dominance": {
    gravity: 0,
    velocity: 3,
    alt_velocity: 3,
    on_hit: {
      impact_damage: 0
    },
    preserve: true
  },
  "spark_amm2:wooden_spear_throwable": {
    gravity: 1.7,
    velocity: 4,
    on_hit: {
      impact_damage: 7
    },
    preserve: true
  },
  "spark_amm2:stone_spear_throwable": {
    gravity: 1.7,
    velocity: 4,
    on_hit: {
      impact_damage: 8
    },
    preserve: true
  },
  "spark_amm2:iron_spear_throwable": {
    gravity: 1.7,
    velocity: 4,
    on_hit: {
      impact_damage: 10
    },
    preserve: true
  },
  "spark_amm2:golden_spear_throwable": {
    gravity: 1.7,
    velocity: 4,
    on_hit: {
      impact_damage: 8
    },
    preserve: true
  },
  "spark_amm2:diamond_spear_throwable": {
    gravity: 1.7,
    velocity: 4,
    on_hit: {
      impact_damage: 14
    },
    preserve: true
  },
  "spark_amm2:netherite_spear_throwable": {
    gravity: 1.7,
    velocity: 4,
    on_hit: {
      impact_damage: 16
    },
    preserve: true
  }
};

// src/runtime/utils/event.ts
var Subscribable = class {
  constructor() {
    this.listeners = /* @__PURE__ */ new Set();
  }
  subscribe(listener) {
    this.listeners.add(listener);
    return listener;
  }
  unsubscribe(listener) {
    return this.listeners.delete(listener);
  }
  emit(value) {
    for (const listener of this.listeners)
      try {
        listener(value);
      } catch (e) {
        console.warn(e, "\n" + e.stack);
      }
  }
};

// src/runtime/systems/projectiles-that-work/main.ts
var ProjectilesThatWork;
((ProjectilesThatWork2) => {
  const projectiles = [];
  const projectileData = {};
  ProjectilesThatWork2.onBlockHit = new Subscribable();
  ProjectilesThatWork2.onEntityHit = new Subscribable();
  const projectileEffectPerTick = /* @__PURE__ */ new Map();
  const normalGameProjectiles = /* @__PURE__ */ new Set();
  const entitiesToTrack = /* @__PURE__ */ new Set();
  const nonCustomParticleEffectsPerEntity = /* @__PURE__ */ new Map();
  function init() {
    system.runInterval(tick3, 1);
  }
  ProjectilesThatWork2.init = init;
  function tick3() {
    projectiles.forEach((projectile, index) => {
      try {
        processProjectile(projectile, index);
      } catch (e) {
        removeProjectile(projectile, index);
      }
    });
    normalGameProjectiles.forEach((id) => {
      processNormalProjectile(id);
    });
  }
  function tryOrNull(cb) {
    try {
      return cb();
    } catch (e) {
      return null;
    }
  }
  function processProjectile(projectile, index) {
    let configData = config3[projectile.typeId];
    if (!configData)
      return;
    const pos = { ...projectile.location };
    let data = projectileData[projectile.id];
    if (!data)
      return;
    data.age += 1 / 20;
    let delta = Vec3.scale(data.velocity, Math.exp(-data.age / 10));
    if (configData.gravity !== 0)
      delta.y -= configData.gravity * data.age;
    let target = Vec3.add(pos, delta);
    let dim = projectile.dimension;
    let mag = Vec3.mag(delta);
    let step = 1 / mag;
    let entities = dim.getEntitiesFromRay(pos, Vec3.normal(delta), { maxDistance: Math.max(1, Math.floor(mag * 1.8)) });
    if (entities.length > 0)
      for (const hitOpt of entities) {
        const entity = hitOpt.entity;
        if (entity.id == projectile.id)
          continue;
        if (entity.id == data.owner)
          continue;
        if (!data.hurtPlayers && entity.typeId == "minecraft:player")
          continue;
        let phee = {
          projectile,
          hitEntity: entity,
          shooter: data.owner ? world.getEntity(data.owner) : void 0
        };
        ProjectilesThatWork2.onEntityHit.emit(phee);
        removeProjectile(projectile, index);
        return;
      }
    for (let i = 0; i < 1; i += step) {
      let stepPoint = Vec3.scale(delta, i);
      let calcPos = Vec3.add(pos, stepPoint);
      calcPos.y -= i * configData.gravity;
      let rayResult = tryOrNull(() => dim.getBlockFromRay(
        calcPos,
        delta,
        {
          "includePassableBlocks": false,
          "includeLiquidBlocks": false,
          "maxDistance": 1
        }
      ));
      let block2 = dim.getBlock(calcPos);
      if (projectileEffectPerTick.has(projectile.id)) {
        let effect = projectileEffectPerTick.get(projectile.id);
        projectile.dimension.spawnParticle(effect, calcPos);
      }
      let block = rayResult?.block;
      if (block) {
        if (block.isAir)
          continue;
        if (block.isLiquid)
          continue;
        ProjectilesThatWork2.onBlockHit.emit({
          projectile,
          block,
          hitPos: calcPos,
          shooter: data.owner ? world.getEntity(data.owner) : void 0
        });
        if (configData.preserve)
          projectile.teleport(calcPos, {
            keepVelocity: false,
            facingLocation: pos
          });
        removeProjectile(projectile, index);
        return;
      }
    }
    projectile.teleport(target, { keepVelocity: false, facingLocation: pos });
  }
  world.afterEvents.entitySpawn.subscribe((event) => {
    const id = event.entity.typeId;
    if (entitiesToTrack.has(id)) {
      normalGameProjectiles.add(event.entity.id);
    }
  });
  world.afterEvents.entityRemove.subscribe((event) => {
    if (normalGameProjectiles.has(event.typeId)) {
      normalGameProjectiles.delete(event.typeId);
      if (projectileEffectPerTick.has(event.typeId)) {
        projectileEffectPerTick.delete(event.typeId);
      }
    }
  });
  function processNormalProjectile(id) {
    let entity = world.getEntity(id);
    if (!entity) {
      normalGameProjectiles.delete(id);
      return;
    }
    if (projectileEffectPerTick.has(id)) {
      try {
        entity.dimension.spawnParticle(projectileEffectPerTick.get(id), entity.location);
      } catch {
      }
    }
    if (nonCustomParticleEffectsPerEntity.has(entity.typeId)) {
      try {
        entity.dimension.spawnParticle(nonCustomParticleEffectsPerEntity.get(entity.typeId), entity.location);
      } catch {
      }
    }
  }
  function addEntityToTrack(id) {
    if (!entitiesToTrack.has(id)) {
      entitiesToTrack.add(id);
    }
  }
  ProjectilesThatWork2.addEntityToTrack = addEntityToTrack;
  function removeProjectile(projectile, index) {
    projectiles.splice(index, 1);
    delete projectileData[projectile.id];
    if (projectileEffectPerTick.has(projectile.id)) {
      projectileEffectPerTick.delete(projectile.id);
    }
    if (!config3[projectile.typeId]?.preserve)
      projectile.remove();
  }
  function registerEffectForEntityType(typeid, particle_effect) {
    if (particle_effect && !nonCustomParticleEffectsPerEntity.has(typeid)) {
      nonCustomParticleEffectsPerEntity.set(typeid, particle_effect);
    }
    addEntityToTrack(typeid);
  }
  ProjectilesThatWork2.registerEffectForEntityType = registerEffectForEntityType;
  function instantiateProjectile(entityID, dimension, location, velocity, shooter, particle_effect) {
    if (location.y < -64 || location.y > 320)
      return void 0;
    let prod = dimension.spawnEntity(entityID, location);
    projectiles.push(prod);
    if (particle_effect) {
      projectileEffectPerTick.set(prod.id, particle_effect);
    }
    prod.applyImpulse(velocity);
    let data = {
      velocity,
      age: 0
    };
    if (shooter) {
      data.owner = shooter.id;
    }
    projectileData[prod.id] = data;
    return prod;
  }
  ProjectilesThatWork2.instantiateProjectile = instantiateProjectile;
})(ProjectilesThatWork || (ProjectilesThatWork = {}));

// src/runtime/systems/mobs/great_hog/main.ts
world.afterEvents.entitySpawn.subscribe((arg) => {
  if (arg.entity.typeId != "spark_amm2:great_hog_shot")
    return;
  system.runTimeout(spawnGreatHogProjectile, 2);
  function spawnGreatHogProjectile() {
    let velocity = arg.entity.getVelocity();
    if (Vec3.equals(velocity, Vec3.Zero())) {
      velocity = Vec3.spherical(1, arg.entity.getRotation());
    }
    velocity = Vec3.normal(velocity).scale(config3["spark_amm2:great_hog_projectile"].velocity);
    ProjectilesThatWork.instantiateProjectile(
      "spark_amm2:great_hog_projectile",
      arg.entity.dimension,
      arg.entity.location,
      velocity
    );
    arg.entity.remove();
  }
});

// src/runtime/utils/ref.ts
function createRefOf(ref, deref) {
  return (v) => {
    let refValue = ref(v);
    let _cached = v;
    return () => {
      if (_cached && _cached.isValid()) {
        return _cached;
      }
      _cached = deref(refValue);
      return _cached;
    };
  };
}
function tryOrElse(producer, otherwise) {
  try {
    return producer();
  } catch (e) {
    return otherwise;
  }
}
var entityRef = createRefOf(({ id }) => id, (id) => tryOrElse(() => world.getEntity(id), void 0));

// src/runtime/utils/assert.ts
function assert(condition, message) {
  if (false) {
    if (!condition) {
      const stack = get_stack(2);
      if (!stack)
        throw new AssertionError(`Assertion failed (no stack): ${message}`);
      let error = new AssertionError(
        message,
        stack.map((frame) => `  at ${frame.name} (${frame.file}:${frame.line})`).join("\n")
      );
      throw error;
    }
  }
}

// src/runtime/utils/applyImpulse.ts
function applyImpulse(entity, direction, power) {
  try {
    entity.applyImpulse(direction.normal().add(v3(0, 0.2, 0)).scale(power));
  } catch (_) {
    try {
      entity.applyKnockback(direction.x, direction.z, power, direction.y + 0.2);
    } catch (_2) {
    }
  }
}

// src/runtime/systems/mobs/piglin_general/main.ts
function createResolverPromise() {
  let _resolve;
  return [
    new Promise((resolve) => {
      _resolve = resolve;
    }),
    (v) => _resolve(v)
  ];
}
function runTimes(cb, times) {
  let count = 0;
  let [promise, resolve] = createResolverPromise();
  function runTimesCallback() {
    count++;
    if (count <= times) {
      system.runTimeout(runTimesCallback, 1);
    } else {
      resolve();
    }
    cb();
  }
  system.runTimeout(runTimesCallback, 1);
  return promise;
}
system.afterEvents.scriptEventReceive.subscribe(
  (e) => {
    if (e.id === "spark_amm2:piglin_general_special_attack") {
      assert(
        e.sourceEntity,
        "spark_amm2:piglin_general_special_attack called without a sourceEntity set"
      );
      const { dimension, location, id: myId } = e.sourceEntity;
      let ref = entityRef(e.sourceEntity);
      e.sourceEntity.setProperty(`${"spark_amm2"}:is_doing_spin`, true);
      runTimes(() => {
        let sourceEntity = ref();
        if (!sourceEntity)
          return;
        let nearbyEntities = sourceEntity.dimension.getEntities({
          location: sourceEntity.location,
          maxDistance: config2.piglin_general.specialAttackRadius
        });
        for (const entity of nearbyEntities) {
          if (entity.id === sourceEntity.id)
            continue;
          let difference = Vec3.subtract(
            entity.location,
            sourceEntity.location
          );
          applyImpulse(
            entity,
            difference.normal().add({ x: 0, y: 0.2, z: 0 }),
            config2.piglin_general.knockbackPower
          );
          try {
            entity.applyDamage(
              config2.piglin_general.specialAttackDamage,
              {
                cause: EntityDamageCause.entityAttack,
                damagingEntity: sourceEntity
              }
            );
          } catch (_) {
          }
        }
      }, Math.floor(20 * config2.piglin_general.spinDuration)).then(() => {
        let ent = ref();
        if (ent) {
          ent.setProperty(`${"spark_amm2"}:is_doing_spin`, false);
        }
      });
    }
  },
  {
    namespaces: ["spark_amm2"]
  }
);
var LAST_USED_TIME = `${"spark_amm2"}:piglin_general_last_used_time`;
world.afterEvents.entityHitEntity.subscribe(
  (event) => {
    if (event.damagingEntity.typeId === `${"spark_amm2"}:piglin_general`) {
      let lastTime = event.damagingEntity.getDynamicProperty(
        LAST_USED_TIME
      );
      if (!lastTime)
        lastTime = 0;
      if (lastTime + config2.piglin_general.powerAttackCooldown * 20 < system.currentTick) {
        event.damagingEntity.setDynamicProperty(
          LAST_USED_TIME,
          system.currentTick
        );
        let difference = Vec3.subtract(
          event.hitEntity.location,
          event.damagingEntity.location
        ).withY(0).normal().withY(0.2);
        applyImpulse(
          event.hitEntity,
          difference,
          config2.piglin_general.powerAttackKnockback
        );
        try {
          event.hitEntity.applyDamage(
            config2.piglin_general.powerAttackDamage,
            {
              damagingEntity: event.damagingEntity,
              cause: EntityDamageCause.entityAttack
            }
          );
        } catch (_) {
        }
      }
    }
  },
  {
    // entityTypes: [`minecraft:player`],
  }
);
world.afterEvents.entityLoad.subscribe((e) => {
  if (e.entity.typeId === `${"spark_amm2"}:piglin_general`) {
    e.entity.setProperty(`${"spark_amm2"}:is_doing_spin`, false);
  }
});

// src/runtime/systems/mobs/torch_piglin/main.ts
world.afterEvents.entityHitEntity.subscribe((e) => {
  if (e.damagingEntity.typeId === `${"spark_amm2"}:torch_piglin`) {
    e.hitEntity.dimension.spawnEntity(`${"spark_amm2"}:player_ignitor`, Vec3.add(e.hitEntity.location, v3.up));
  }
});

// src/runtime/utils/util.ts
var lerp = function(start, end, lerp2) {
  return start + (end - start) * lerp2;
};
function randomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1) + min);
}
var Dimensions = [
  world.getDimension("minecraft:overworld"),
  world.getDimension("minecraft:nether"),
  world.getDimension("minecraft:the_end")
];
function getTickTime() {
  return Math.floor(Date.now() / 50);
}
function getHeldItem(entity) {
  try {
    let equipment = entity.getComponent(
      "minecraft:equippable"
    );
    let item = equipment.getEquipment(EquipmentSlot.Mainhand);
    return item;
  } catch (error) {
    return void 0;
  }
}
function randomRange(min, max) {
  return Math.floor(Math.random() * (max - min + 1) + min);
}
function playAnimationFactory(animation, opts) {
  let commandArgs = [
    animation,
    opts.nextState,
    opts.blendOutTime,
    opts.stopExpression ? `"${opts.stopExpression}"` : void 0,
    opts.controller
  ];
  let skipped = false;
  let lastIdx = 1;
  for (let i = 1; i < commandArgs.length; i++) {
    if (commandArgs[i] === void 0) {
      skipped = true;
    } else {
      if (skipped) {
        throw "playanimation encounterd data after a missing optional parameter";
      }
      lastIdx = i;
    }
  }
  let command = `playanimation @s ${commandArgs.join(" ")}`;
  return command;
}

// src/runtime/systems/mobs/malgosha/main.ts
var activeMobs = /* @__PURE__ */ new Set();
var sweapCooldown = /* @__PURE__ */ new Map();
system.afterEvents.scriptEventReceive.subscribe(
  function processMalgoshaEvents(arg) {
    switch (arg.id) {
      case "spark_amm2:malgosha.trigger_minion_spawn":
        spawnMinions(arg.sourceEntity);
        break;
    }
  },
  {
    namespaces: ["spark_amm2"]
  }
);
world.afterEvents.entityRemove.subscribe((arg) => {
  if (arg.typeId != "spark_amm2:malgosha")
    return;
  if (activeMobs.has(arg.removedEntityId)) {
    activeMobs.delete(arg.removedEntityId);
  }
  if (sweapCooldown.has(arg.removedEntityId)) {
    sweapCooldown.delete(arg.removedEntityId);
  }
});
world.afterEvents.entityLoad.subscribe((arg) => {
  if (arg.entity.typeId != "spark_amm2:malgosha")
    return;
  if (!activeMobs.has(arg.entity.id)) {
    activeMobs.add(arg.entity.id);
  }
  if (!sweapCooldown.has(arg.entity.id)) {
    sweapCooldown.set(arg.entity.id, 0);
  }
});
world.afterEvents.entitySpawn.subscribe((arg) => {
  if (arg.entity.typeId == "spark_amm2:malgosha") {
    if (!activeMobs.has(arg.entity.id)) {
      activeMobs.add(arg.entity.id);
    }
    if (!sweapCooldown.has(arg.entity.id)) {
      sweapCooldown.set(arg.entity.id, 0);
    }
  }
  if (arg.entity.typeId == "spark_amm2:malgosha_fireball_shot") {
    let spawnMalgoshaFireball2 = function() {
      const Malgosha = arg.entity.dimension.getEntities({
        type: "spark_amm2:malgosha",
        closest: 1
      })[0];
      let velocity = Malgosha ? Vec3.spherical(1, Malgosha.getRotation()) : arg.entity.getVelocity();
      if (Vec3.equals(velocity, Vec3.Zero())) {
        velocity = Vec3.spherical(1, arg.entity.getRotation());
      }
      velocity = Vec3.normal(velocity).scale(config3["spark_amm2:malgosha_fireball"].velocity);
      ProjectilesThatWork.instantiateProjectile(
        "spark_amm2:malgosha_fireball",
        arg.entity.dimension,
        Malgosha ? Vec3.add(Malgosha.location, { x: 0, y: 1.2, z: 0 }) : arg.entity.location,
        velocity
      );
      arg.entity.remove();
    };
    var spawnMalgoshaFireball = spawnMalgoshaFireball2;
    system.runTimeout(spawnMalgoshaFireball2, 2);
  }
});
function spawnMinions(malgosha) {
  let dimension = malgosha.dimension;
  let amount = randomInt(
    config2.malgosha.minion_spawn_amount[0],
    config2.malgosha.minion_spawn_amount[1]
  );
  for (let i = 0; i < amount; i++) {
    let spawned = dimension.spawnEntity(
      "spark_amm2:piglin_transform_entity",
      malgosha.location
    );
    spawned.addTag("malgosha_spawned");
  }
  malgosha.runCommandAsync(
    `spreadplayers ~ ~ ${config2.malgosha.minion_spawn_range[0]} ${config2.malgosha.minion_spawn_range[1]} @e[tag=malgosha_spawned]`
  );
  system.runTimeout(() => {
    let mobs = malgosha.dimension.getEntities({
      tags: ["malgosha_spawned"]
    });
    mobs.forEach((v) => {
      let randomEntity = config2.malgosha.minion_spawn_pool[randomInt(0, config2.malgosha.minion_spawn_pool.length - 1)];
      malgosha.dimension.spawnEntity(randomEntity, v.location);
      v.remove();
    });
    dimension.runCommandAsync(
      "tag @e[tag=malgosha_spawned] remove malgosha_spawned"
    );
  }, 1);
  malgosha.setProperty("spark_amm2:trigger_minion_spawn", false);
}
function triggerSweap(malgosha) {
  system.runTimeout(() => {
    let source = malgosha.location;
    let viewDirection = malgosha.getViewDirection();
    let cone = [];
    malgosha.dimension.getEntities({
      location: source,
      maxDistance: config2.malgosha.sweap_range,
      families: ["player"],
      excludeGameModes: [GameMode.creative, GameMode.spectator]
    }).forEach((e) => {
      let EP = Vec3.subtract(source, e.location);
      let EPN = Vec3.normal(EP);
      let dot = Vec3.dot(EPN, viewDirection);
      if (dot < -1 + config2.malgosha.sweap_fov)
        cone.push(e);
    });
    cone.forEach((e) => {
      if (!e.isValid())
        return;
      e.applyDamage(config2.malgosha.sweap_damage, {
        damagingEntity: malgosha,
        cause: EntityDamageCause.entityAttack
      });
      let dir = Vec3.subtract(e.location, malgosha.location);
      e.applyKnockback(
        dir.x,
        dir.z,
        config2.malgosha.sweap_knockback_horizontal,
        config2.malgosha.sweap_knockback_veritcal
      );
    });
  }, 8);
  malgosha.setProperty("spark_amm2:trigger_sweap", true);
  system.runTimeout(() => {
    malgosha.setProperty("spark_amm2:trigger_sweap", false);
  }, 2);
}
function tick() {
  let tickTime = getTickTime();
  activeMobs.forEach((e) => {
    let mob = world.getEntity(e);
    if (!mob)
      return;
    if (!mob.isValid())
      return;
    if (mob.getProperty("spark_amm2:allow_sweap") != true)
      return;
    if (!sweapCooldown.has(mob.id)) {
      sweapCooldown.set(mob.id, tickTime);
    }
    let cooldown = sweapCooldown.get(mob.id);
    if (cooldown > tickTime)
      return;
    let nearbyPlayers = mob.dimension.getPlayers({
      location: mob.location,
      excludeGameModes: [GameMode.creative, GameMode.spectator],
      maxDistance: config2.malgosha.sweap_range
    });
    if (nearbyPlayers.length == 0)
      return;
    if (!isWithinFovAndRange(
      mob,
      nearbyPlayers,
      config2.malgosha.sweap_fov,
      config2.malgosha.sweap_trigger_range
    ))
      return;
    system.runTimeout(() => {
      triggerSweap(mob);
    }, 8);
    sweapCooldown.set(
      mob.id,
      tickTime + config2.malgosha.sweap_cooldown + 10
    );
  });
}
function isWithinFovAndRange(source, checks, fov, range) {
  let viewDirection = source.getViewDirection();
  return checks.some((e) => {
    let EP = Vec3.subtract(source.location, e.location);
    let EPN = Vec3.normal(EP);
    let dot = Vec3.dot(viewDirection, EPN);
    if (dot < -1 + fov) {
      if (Vec3.distance(source.location, e.location) <= range) {
        return true;
      }
    }
  });
}
system.runInterval(tick, 1);
ProjectilesThatWork.onEntityHit.subscribe(processMalgoshaProjectileHitEntity);
function processMalgoshaProjectileHitEntity(arg) {
  if (arg.projectile.typeId != "spark_amm2:malgosha_fireball")
    return;
  if (arg.hitEntity == void 0) {
    arg.projectile.remove();
    return;
  }
  arg.hitEntity.dimension.spawnEntity(
    "spark_amm2:malgosha_fireball_explosion",
    arg.projectile.location
  );
}
ProjectilesThatWork.onBlockHit.subscribe(processMalgoshaProjectileHitBlock);
function processMalgoshaProjectileHitBlock(arg) {
  if (arg.projectile.typeId != "spark_amm2:malgosha_fireball")
    return;
  arg.projectile.dimension.spawnEntity(
    "spark_amm2:malgosha_fireball_explosion",
    arg.projectile.location
  );
}

// src/runtime/configs/items.ts
var config4 = {
  tater_tot: {
    eat_effect_amplifier: 1,
    eat_effect_duration: 2
  },
  staff_of_dominance: {
    maxChargeDuration: 40,
    maxExplosionPower: 6,
    minExplosionPower: 2,
    minSpeed: 1,
    maxSpeed: 4,
    maxUseTime: 500 * 20,
    // @config power shot time
    // search this ^^^
    // the number here and the maxChargeDuration is in ticks, in the animation controller its in seconds ticks/20
    largeShotDuration: 5
  },
  potato_launcher: {
    rate_of_fire: 5,
    charge_ticks: 20,
    cooldown: 20
  },
  buck_chuckets: {
    effect_range: 8,
    damage: 3,
    effect_duration: 2,
    effect_amplifier: 1,
    field_of_view: 0.7,
    knockback_strength: 2.5
  },
  battleaxe: {
    criticalMultiplier: 1.5,
    useCooldown: 4,
    maxAbilityAngle: 90,
    abilityForce: 0.5,
    sweepingEdgeKnockbackStrengh: 0.65,
    abilityDamageMapping: /* @__PURE__ */ new Map([
      [`${"spark_amm2"}:wooden_battle_axe`, 3],
      [`${"spark_amm2"}:stone_battle_axe`, 4],
      [`${"spark_amm2"}:iron_battle_axe`, 5],
      [`${"spark_amm2"}:golden_battle_axe`, 3],
      [`${"spark_amm2"}:diamond_battle_axe`, 6],
      [`${"spark_amm2"}:netherite_battle_axe`, 7]
    ])
  },
  player_use_animations: {
    "spark_amm2:diamond_spear": {
      animation: "animation.spark_amm2.spear.third.charge",
      mode: "while_pressing"
    },
    "spark_amm2:golden_spear": {
      animation: "animation.spark_amm2.spear.third.charge",
      mode: "while_pressing"
    },
    "spark_amm2:iron_spear": {
      animation: "animation.spark_amm2.spear.third.charge",
      mode: "while_pressing"
    },
    "spark_amm2:netherite_spear": {
      animation: "animation.spark_amm2.spear.third.charge",
      mode: "while_pressing"
    },
    "spark_amm2:stone_spear": {
      animation: "animation.spark_amm2.spear.third.charge",
      mode: "while_pressing"
    },
    "spark_amm2:wooden_spear": {
      animation: "animation.spark_amm2.spear.third.charge",
      mode: "while_pressing"
    }
  },
  player_stop_use_animations: {
    "spark_amm2:diamond_spear": {
      animation: "animation.spark_amm2.spear.third.throw",
      mode: "while_pressing"
    },
    "spark_amm2:golden_spear": {
      animation: "animation.spark_amm2.spear.third.throw",
      mode: "while_pressing"
    },
    "spark_amm2:iron_spear": {
      animation: "animation.spark_amm2.spear.third.throw",
      mode: "while_pressing"
    },
    "spark_amm2:netherite_spear": {
      animation: "animation.spark_amm2.spear.third.throw",
      mode: "while_pressing"
    },
    "spark_amm2:stone_spear": {
      animation: "animation.spark_amm2.spear.third.throw",
      mode: "while_pressing"
    },
    "spark_amm2:wooden_spear": {
      animation: "animation.spark_amm2.spear.third.throw",
      mode: "while_pressing"
    }
  },
  player_attack_animations: {
    "spark_amm2:diamond_spear": {
      first_person_animation: "animation.spark_amm2.spear.first.melee",
      animation: "animation.spark_amm2.spear.third.melee"
    },
    "spark_amm2:golden_spear": {
      first_person_animation: "animation.spark_amm2.spear.first.melee",
      animation: "animation.spark_amm2.spear.third.melee"
    },
    "spark_amm2:iron_spear": {
      first_person_animation: "animation.spark_amm2.spear.first.melee",
      animation: "animation.spark_amm2.spear.third.melee"
    },
    "spark_amm2:netherite_spear": {
      first_person_animation: "animation.spark_amm2.spear.first.melee",
      animation: "animation.spark_amm2.spear.third.melee"
    },
    "spark_amm2:stone_spear": {
      first_person_animation: "animation.spark_amm2.spear.first.melee",
      animation: "animation.spark_amm2.spear.third.melee"
    },
    "spark_amm2:wooden_spear": {
      first_person_animation: "animation.spark_amm2.spear.first.melee",
      animation: "animation.spark_amm2.spear.third.melee"
    },
    "spark_amm2:buck_chuckets": {
      animation: [
        "animation.spark_amm2.buck_chucks.third.attack1",
        "animation.spark_amm2.buck_chucks.third.attack2",
        "animation.spark_amm2.buck_chucks.third.attack3"
      ],
      first_person_animation: [
        "animation.spark_amm2.buck_chucks.first.attack1",
        "animation.spark_amm2.buck_chucks.first.attack2",
        "animation.spark_amm2.buck_chucks.first.attack3"
      ]
    }
  },
  player_hold_animations: {
    "spark_amm2:buck_chuckets": {
      animation: "animation.spark_amm2.buck_chucks.third.hold_pose"
    }
  }
};

// src/runtime/systems/items/item-particles.ts
function spawnAttachableParticle(player, particle_id, offset) {
  let loc = player.getHeadLocation();
  let view_dir = player.getViewDirection();
  let rotation = player.getRotation();
  let spawn_pos = Vec3.add(loc, Vec3.scale(view_dir, offset.z));
  let xy_offset = { x: offset.x, y: offset.y, z: 0 };
  spawn_pos = spawn_pos.add(
    Vec3.rotateY(xy_offset, rotation.y / 180 * Math.PI)
  );
  player.dimension.spawnParticle(particle_id, spawn_pos);
}
system.runInterval(() => {
  for (let player of world.getAllPlayers()) {
    let equippable = player.getComponent(
      "minecraft:equippable"
    );
    let item_id = equippable.getEquipment(EquipmentSlot.Mainhand)?.typeId;
    if (item_id == "spark_amm2:staff_of_dominance") {
    }
    let head_item_id = equippable.getEquipment(EquipmentSlot.Head)?.typeId;
    if (head_item_id == "spark_amm2:mushroom_hat") {
      if (Math.random() < 0.3) {
        player.dimension.spawnParticle(
          "spark_amm2:spores",
          player.getHeadLocation()
        );
      }
    }
  }
}, 1);

// src/runtime/systems/items/malgosha-staff.ts
var playerTimeout = /* @__PURE__ */ new Map();
function onStaffUse(source) {
  source.runCommandAsync(
    `playanimation @s animation.spark_amm2.staff_of_dominance.third.charge_player next 0 "v.is_first_person || query.main_hand_item_use_duration == 0 || q.any_animation_finished"`
  );
  let offset = { x: -0.8, y: -0.6, z: 2 };
  spawnAttachableParticle(source, "spark_amm2:staff_charge_first", offset);
  let playerId = source.id;
  source.runCommand(`camerashake add @s 0.2 2.05 positional`);
  playerTimeout.set(
    source.id,
    system.runTimeout(() => {
      const player = world.getEntity(playerId);
      player?.runCommand(`playsound sound.spark_amm2.staff_charge @s`);
      playerTimeout.set(
        source.id,
        system.runTimeout(() => {
          let player2 = world.getEntity(playerId);
          if (!player2)
            return;
          onStaffRelease({
            source: player2,
            //@ts-expect-error
            itemStack: null,
            useDuration: config4.staff_of_dominance.maxChargeDuration
          });
        }, config4.staff_of_dominance.maxChargeDuration - config4.staff_of_dominance.largeShotDuration)
      );
    }, config4.staff_of_dominance.largeShotDuration)
  );
}
function onStaffRelease(e) {
  let id = playerTimeout.get(e.source.id);
  if (id != void 0) {
    system.clearRun(id);
    playerTimeout.delete(e.source.id);
  } else
    return;
  e.source.runCommand(`camerashake stop`);
  e.source.runCommand(`stopsound @s sound.spark_amm2.staff_charge`);
  if (e.useDuration > config4.staff_of_dominance.largeShotDuration) {
    e.source.playSound("sound.spark_amm2.staff_shoot_big", {
      location: e.source.location
    });
    e.source.runCommandAsync(
      playAnimationFactory(
        `animation.spark_amm2.staff_of_dominance.third.super_shoot`,
        {
          controller: `controller.animation.spark_amm2.player_item_attack_first`,
          nextState: `next`,
          blendOutTime: 0.2,
          stopExpression: `q.all_animations_finished || !v.is_first_person`
        }
      )
    );
  } else {
    e.source.playSound("sound.spark_amm2.staff_shoot_small", {
      location: e.source.location
    });
    e.source.runCommandAsync(
      playAnimationFactory(
        `animation.spark_amm2.staff_of_dominance.third.quick_shoot`,
        {
          controller: `controller.animation.spark_amm2.player_item_attack_first`,
          nextState: `next`,
          blendOutTime: 0.2,
          stopExpression: `q.all_animations_finished || !v.is_first_person`
        }
      )
    );
  }
  let powerPercent = Math.min(
    config4.staff_of_dominance.maxUseTime - e.useDuration,
    config4.staff_of_dominance.maxChargeDuration
  ) / config4.staff_of_dominance.maxChargeDuration;
  let power = Math.floor(
    lerp(
      config4.staff_of_dominance.minExplosionPower,
      config4.staff_of_dominance.maxExplosionPower,
      powerPercent
    )
  );
  let projectile = ProjectilesThatWork.instantiateProjectile(
    "spark_amm2:projectile_of_dominance",
    e.source.dimension,
    Vec3.add(
      e.source.getHeadLocation(),
      Vec3.scale(e.source.getViewDirection(), 2)
    ),
    e.source.getViewDirection(),
    e.source
  );
  if (projectile) {
    projectile.setProperty("spark_amm2:power", power);
  }
}
function onProjectileHit(event) {
  if (event.projectile.typeId !== "spark_amm2:projectile_of_dominance")
    return;
  let invVelocity = Vec3.scale(event.projectile.getVelocity(), -1);
  const dim = event.projectile.dimension;
  let loc = event.projectile.location;
  for (let i = 0; i < 5; i++) {
    const tempLoc = Vec3.add(
      event.projectile.location,
      Vec3.scale(invVelocity, i)
    );
    let block = dim.getBlock(tempLoc);
    if (block && block.isValid() && (block.isAir || block.isLiquid)) {
      loc = tempLoc;
    }
  }
  let power = event.projectile.getProperty(`${"spark_amm2"}:power`);
  event.projectile.teleport(loc, { dimension: dim, keepVelocity: false });
  let sound = power < 3 ? `sound.spark_amm2.staff_impact_small` : `sound.spark_amm2.staff_impact_large`;
  event.projectile.dimension.runCommandAsync(
    `playsound ${sound} @a ${event.projectile.location.x.toFixed(
      2
    )} ${event.projectile.location.y.toFixed(
      2
    )} ${event.projectile.location.z.toFixed(2)}`
  );
  event.projectile.triggerEvent("spark_amm2:explode");
}
ProjectilesThatWork.onBlockHit.subscribe(onProjectileHit);
ProjectilesThatWork.onEntityHit.subscribe(onProjectileHit);
world.afterEvents.itemStartUse.subscribe(beginUsingStaff);
function beginUsingStaff(e) {
  let { typeId } = e.itemStack;
  if (typeId === `${"spark_amm2"}:staff_of_dominance`) {
    onStaffUse(e.source);
  }
}
world.afterEvents.itemReleaseUse.subscribe(endUsingStaff);
function endUsingStaff(e) {
  let typeId = e.itemStack.typeId;
  if (typeId === `${"spark_amm2"}:staff_of_dominance`) {
    onStaffRelease(e);
  }
}

// src/runtime/systems/items/spear.ts
var validItems = /* @__PURE__ */ new Set([
  "spark_amm2:diamond_spear",
  "spark_amm2:golden_spear",
  "spark_amm2:iron_spear",
  "spark_amm2:netherite_spear",
  "spark_amm2:stone_spear",
  "spark_amm2:wooden_spear"
]);
var validProjectiles = /* @__PURE__ */ new Set([
  "spark_amm2:diamond_spear_throwable",
  "spark_amm2:golden_spear_throwable",
  "spark_amm2:iron_spear_throwable",
  "spark_amm2:netherite_spear_throwable",
  "spark_amm2:stone_spear_throwable",
  "spark_amm2:wooden_spear_throwable"
]);
var itemUseTime = /* @__PURE__ */ new Map();
world.afterEvents.itemUse.subscribe(function spearStart(arg) {
  if (!validItems.has(arg.itemStack.typeId))
    return;
  let player = arg.source;
  let time = getTickTime();
  itemUseTime.set(player.id, time);
});
world.afterEvents.itemStopUse.subscribe(function spearStop(arg) {
  if (arg.itemStack == void 0)
    return;
  if (!validItems.has(arg.itemStack.typeId))
    return;
  let time = itemUseTime.get(arg.source.id);
  if (time == void 0) {
    return;
  }
  if (time + 10 > getTickTime()) {
    itemUseTime.delete(arg.source.id);
    return;
  }
  let player = arg.source;
  let direction = player.getViewDirection();
  let normal = Vec3.normal(direction);
  let velocity = Vec3.scale(normal, 4);
  let proj = ProjectilesThatWork.instantiateProjectile(
    `${arg.itemStack.typeId}_throwable`,
    player.dimension,
    player.getHeadLocation(),
    velocity,
    player
  );
  if (proj == void 0)
    return;
  player.playSound("sound.spark_amm2.spear_throw");
  itemUseTime.delete(player.id);
  const _player = player.dimension.getEntities({
    type: "minecraft:player",
    location: player.location,
    closest: 1,
    gameMode: GameMode.creative
  });
  if (_player[0]?.id == player.id)
    return;
  let inventory = player.getComponent(
    "inventory"
  );
  if (!inventory)
    return void 0;
  let container = inventory.container;
  if (!container)
    return void 0;
  for (let i = 0; i < 9; i++) {
    let itemStack = container.getItem(i);
    if (itemStack == void 0)
      continue;
    if (itemStack.typeId == arg.itemStack.typeId) {
      if (itemStack.amount > 1) {
        let newStack = itemStack.clone();
        newStack.amount -= 1;
        container.setItem(i, newStack);
        return;
      }
      container.setItem(i, void 0);
      return;
    }
  }
});
ProjectilesThatWork.onBlockHit.subscribe(function onProjectileHitBlock(v) {
  if (!validProjectiles.has(v.projectile.typeId))
    return;
  v.projectile.triggerEvent("spark_amm2:drop");
  v.projectile.triggerEvent("spark_amm2:no_physics");
  v.projectile.teleport(v.hitPos);
  v.projectile.clearVelocity();
});
ProjectilesThatWork.onEntityHit.subscribe(function onProjectileHitEntity(v) {
  if (!validProjectiles.has(v.projectile.typeId))
    return;
  let data = config3[v.projectile.typeId];
  v.hitEntity.applyDamage(data.on_hit.impact_damage, {
    cause: EntityDamageCause.entityAttack,
    damagingEntity: v.shooter
  });
  v.projectile.triggerEvent("spark_amm2:drop");
  v.projectile.teleport(
    v.hitEntity.location,
    { keepVelocity: false }
  );
  v.projectile.clearVelocity();
});

// src/runtime/systems/items/battle-axe.ts
function playAnimationOn(player, animation, blendOutTime = 0.2) {
  player.runCommandAsync(
    playAnimationFactory(animation("third"), {
      controller: `controller.animation.spark_amm2.player_item_attack_third`,
      nextState: `next`,
      blendOutTime,
      stopExpression: `q.all_animations_finished || v.is_first_person`
    })
  );
  player.runCommandAsync(
    playAnimationFactory(animation("first"), {
      controller: `controller.animation.spark_amm2.player_item_attack_first`,
      nextState: `next`,
      blendOutTime,
      stopExpression: `q.all_animations_finished || !v.is_first_person`
    })
  );
}
var AXE_IDS = /* @__PURE__ */ new Set([
  `${"spark_amm2"}:wooden_battle_axe`,
  `${"spark_amm2"}:stone_battle_axe`,
  `${"spark_amm2"}:iron_battle_axe`,
  `${"spark_amm2"}:golden_battle_axe`,
  `${"spark_amm2"}:diamond_battle_axe`,
  `${"spark_amm2"}:netherite_battle_axe`
]);
var SPIN_PROPERTY = `${"spark_amm2"}:axe_spin_attack_state`;
var IGNORED_ENTITIES = [
  "minecraft:item",
  "minecraft:xp_orb",
  ...validProjectiles
];
function playDirectionedParticle(player, id) {
  const viewDir = player.getViewDirection();
  const playerLocation = player.location;
  const spawnOffset = 1.7;
  const vars = new MolangVariableMap();
  vars.setFloat("direction", player.getRotation().y);
  const spawnLocation = v3(
    playerLocation.x + viewDir.x * spawnOffset,
    playerLocation.y + 1.2,
    playerLocation.z + viewDir.z * spawnOffset
  );
  player.dimension.spawnParticle(id, spawnLocation, vars);
}
var PlayerHitEntityMap = /* @__PURE__ */ new Map();
world.afterEvents.entityHitEntity.subscribe(function axeHit(e) {
  if (!(e.damagingEntity instanceof Player))
    return;
  let player = e.damagingEntity;
  let equipment = player.getComponent(
    EntityEquippableComponent.componentId
  );
  let item = equipment?.getEquipment(EquipmentSlot.Mainhand);
  if (!item)
    return;
  if (!AXE_IDS.has(item.typeId))
    return;
  let recentHitsMap = PlayerHitEntityMap.get(player.id);
  if (recentHitsMap == void 0) {
    recentHitsMap = /* @__PURE__ */ new WeakMap();
    PlayerHitEntityMap.set(player.id, recentHitsMap);
  }
  if (system.currentTick <= (recentHitsMap.get(e.hitEntity) ?? -Infinity))
    return;
  recentHitsMap.set(e.hitEntity, system.currentTick + 10);
  playAnimationOn(
    player,
    (mode) => `animation.spark_amm2.battle_axe.${mode}.melee`,
    0
  );
  playDirectionedParticle(player, "spark_amm2:battle_axe_swing");
  if (!e.hitEntity.isValid())
    return;
  let { location, id, dimension } = e.hitEntity;
  const entitiesNearby = dimension.getEntities({
    location,
    maxDistance: 3,
    excludeTypes: IGNORED_ENTITIES
  });
  for (const entity of entitiesNearby) {
    if (entity.id === id)
      continue;
    let angle = Math.abs(
      radianToDegree(
        Math.atan2(
          entity.location.x - e.damagingEntity.location.x,
          entity.location.z - e.damagingEntity.location.z
        )
      ) + player.getRotation().y
    );
    if (angle > config4.battleaxe.maxAbilityAngle)
      continue;
    let directionFromPlayer = Vec3.subtract(
      entity.location,
      e.damagingEntity.location
    );
    applyImpulse(
      entity,
      directionFromPlayer.withY(0).normal().withY(0.33),
      config4.battleaxe.sweepingEdgeKnockbackStrengh
    );
  }
  player.playSound("sound.spark_amm2.battle_axe_knockback");
});
world.afterEvents.itemUse.subscribe((e) => {
  if (!AXE_IDS.has(e.itemStack.typeId))
    return;
  let player = e.source;
  let lastSpinTime = player.getDynamicProperty(SPIN_PROPERTY) ?? -Infinity;
  if (lastSpinTime + config4.battleaxe.useCooldown * 20 > system.currentTick) {
    if (false) {
      world.sendMessage("some sort of cooldown notificaiton?");
    }
    return;
  }
  let damageToApply = config4.battleaxe.abilityDamageMapping.get(
    e.itemStack.typeId
  );
  if (!damageToApply)
    return;
  ++damageToApply;
  playAnimationOn(
    player,
    (mode) => `animation.spark_amm2.battle_axe.${mode}.special_attack`,
    0
  );
  playDirectionedParticle(player, "spark_amm2:battle_axe_special");
  e.source.setDynamicProperty(SPIN_PROPERTY, true);
  let critical = e.source.isFalling && !e.source.isOnGround && !e.source.isClimbing && !e.source.isInWater && !e.source.isFlying && e.source.getEffects().every(
    (effect) => effect.typeId != "minecraft:blindness" && effect.typeId != "minecraft:slow_falling"
  );
  let potentialMobs = e.source.dimension.getEntities({
    location: e.source.location,
    maxDistance: 4,
    excludeTypes: IGNORED_ENTITIES
  });
  let force = config4.battleaxe.abilityForce;
  if (critical) {
    damageToApply *= config4.battleaxe.criticalMultiplier;
    force /= 2;
  }
  for (let ent of potentialMobs) {
    if (ent.id === e.source.id)
      continue;
    let angle = Math.abs(
      radianToDegree(
        Math.atan2(
          ent.location.x - e.source.location.x,
          ent.location.z - e.source.location.z
        )
      ) + player.getRotation().y
    );
    if (angle > config4.battleaxe.maxAbilityAngle)
      continue;
    if (critical) {
      ent.dimension.spawnParticle(
        "minecraft:critical_hit_emitter",
        Vec3.add(ent.location, { x: 0, y: 1.4, z: 0 })
      );
    }
    ent.applyDamage(damageToApply, {
      cause: EntityDamageCause.entityAttack,
      damagingEntity: e.source
    });
    applyImpulse(ent, v3.up, force);
  }
  e.source.setDynamicProperty(SPIN_PROPERTY, system.currentTick);
  player.playSound("sound.spark_amm2.battle_axe_swipe");
});
world.afterEvents.playerSpawn.subscribe((e) => {
  e.player.setDynamicProperty(SPIN_PROPERTY, void 0);
});
var players = world.getAllPlayers();
for (const player of players) {
  if (player.isValid()) {
    player.setDynamicProperty(SPIN_PROPERTY, void 0);
  }
}

// src/runtime/systems/items/potato_launcher.ts
var launcherHandle = /* @__PURE__ */ new Map();
var cooldownTime = /* @__PURE__ */ new Map();
var projectileItems = [
  `${"spark_amm2"}:tater_tot`,
  `minecraft:ender_pearl`
];
world.afterEvents.itemUse.subscribe(function potatoLauncherStart(arg) {
  if (arg.itemStack.typeId != `${"spark_amm2"}:potato_launcher`)
    return;
  let player = arg.source;
  if (cooldownTime.has(arg.source.id)) {
    const time = cooldownTime.get(arg.source.id);
    if (time >= getTickTime()) {
      return;
    }
  }
  cooldownTime.set(
    arg.source.id,
    getTickTime() + config4.potato_launcher.cooldown
  );
  const cTest = getClosestProjectileInInventory(player);
  if (!cTest)
    return;
  player.runCommandAsync(
    playAnimationFactory(
      "animation.spark_amm2.potato_launcher.third.charge",
      {
        nextState: `next`,
        blendOutTime: 0.2,
        stopExpression: "q.all_animations_finished || v.is_first_person",
        controller: `controller.animation.spark_amm2.potato_launcher_third`
      }
    )
  );
  let handle = system.runTimeout(function altFire() {
    let closest = getClosestProjectileInInventory(player);
    if (closest == "minecraft:ender_pearl") {
      altFirePearl(player);
      removeNearestItemInInventory(player, "minecraft:ender_pearl");
      launcherHandle.delete(arg.source.id);
      return;
    }
    if (closest == "spark_amm2:tater_tot") {
      let amount = countItemInInventory(player, "spark_amm2:tater_tot");
      if (amount > 5)
        amount = 5;
      let prodEnt = `spark_amm2:tater_tot_projectile`;
      let data = config3[prodEnt];
      let shotsFired = 0;
      let rof = 20 / (config4.potato_launcher.rate_of_fire / 1);
      let rapidHandle = system.runInterval(() => {
        if (shotsFired >= amount) {
          system.clearRun(rapidHandle);
          return;
        }
        let direction = player.getViewDirection();
        let normal = Vec3.normal(direction);
        let velocity = Vec3.scale(normal, data.velocity);
        player.runCommandAsync(
          playAnimationFactory(
            "animation.spark_amm2.potato_launcher.third.shoot",
            {
              nextState: `next`,
              blendOutTime: 0.2,
              stopExpression: "q.all_animations_finished || v.is_first_person",
              controller: `controller.animation.spark_amm2.potato_launcher_third`
            }
          )
        );
        ProjectilesThatWork.instantiateProjectile(
          prodEnt,
          player.dimension,
          player.getHeadLocation(),
          velocity,
          player
        );
        player.playSound("sound.spark_amm2.potato_launcher_shoot");
        removeNearestItemInInventory(player, "spark_amm2:tater_tot");
        shotsFired++;
      }, rof);
      launcherHandle.delete(arg.source.id);
      cooldownTime.set(arg.source.id, getTickTime() + 20);
      return;
    }
  }, config4.potato_launcher.charge_ticks);
  launcherHandle.set(arg.source.id, handle);
  player.playSound("sound.spark_amm2.potato_launcher_charge");
});
world.afterEvents.itemStopUse.subscribe(function potatoLauncherStop(arg) {
  if (!arg.itemStack) {
    if (launcherHandle.has(arg.source.id)) {
      launcherHandle.delete(arg.source.id);
      return;
    }
    return;
  }
  let item = arg.itemStack;
  if (item.typeId != `${"spark_amm2"}:potato_launcher`)
    return;
  if (!launcherHandle.has(arg.source.id)) {
    return;
  }
  let handle = launcherHandle.get(arg.source.id);
  system.clearRun(handle);
  launcherHandle.delete(arg.source.id);
  ShortUse(item, arg.source);
});
ProjectilesThatWork.onBlockHit.subscribe((event) => {
  if (event.projectile.typeId == `${"spark_amm2"}:enderpearl_potate_projectile`) {
    onEnderpearlHit(event);
  }
});
ProjectilesThatWork.onEntityHit.subscribe((event) => {
  if (event.projectile.typeId == `${"spark_amm2"}:tater_tot_projectile`) {
    onTaterTotHit(event);
  }
  if (event.projectile.typeId == `${"spark_amm2"}:enderpearl_potate_projectile`) {
    onEnderpearlHitEntity(event);
  }
});
function onTaterTotHit(event) {
  let data = config3[event.projectile.typeId];
  if (!data)
    return;
  if (event.shooter) {
    if (event.shooter.typeId == "minecraft:player") {
      event.hitEntity.runCommandAsync(
        `damage @s ${data.on_hit.impact_damage} projectile entity @a[name=${event.shooter.nameTag}]`
      );
      return;
    }
  }
  event.hitEntity.runCommandAsync(
    `damage @s ${data.on_hit.impact_damage} projectile`
  );
}
function onEnderpearlHit(event) {
  let data = config3[event.projectile.typeId];
  if (!data)
    return;
  if (data.on_hit.teleport) {
    let owner = event.shooter;
    if (!owner)
      return;
    try {
      let pos = Vec3.add(event.hitPos, Vec3.Up());
      owner?.teleport(pos);
      system.runTimeout(() => {
        owner.playSound("mob.shulker.teleport", {
          location: pos
        });
      }, 1);
    } catch {
    }
  }
}
function onEnderpearlHitEntity(event) {
  let data = config3[event.projectile.typeId];
  if (!data)
    return;
  if (data.on_hit.teleport) {
    let owner = event.shooter;
    if (!owner)
      return;
    try {
      let pos = Vec3.add(event.hitEntity.location, Vec3.Up());
      owner?.teleport(pos);
      system.runTimeout(() => {
        owner.playSound("mob.shulker.teleport", {
          location: pos
        });
      }, 1);
    } catch {
    }
  }
}
function ShortUse(item, player) {
  let closest = getClosestProjectileInInventory(player);
  if (closest == "minecraft:ender_pearl") {
    let prodEnt = `${"spark_amm2"}:enderpearl_potate_projectile`;
    let data = config3[prodEnt];
    let direction = player.getViewDirection();
    let normal = Vec3.normal(direction);
    let velocity = Vec3.scale(normal, data.velocity);
    player.runCommandAsync(
      playAnimationFactory(
        "animation.spark_amm2.potato_launcher.third.shoot",
        {
          nextState: `next`,
          blendOutTime: 0.2,
          stopExpression: "q.all_animations_finished || v.is_first_person",
          controller: `controller.animation.spark_amm2.potato_launcher_third`
        }
      )
    );
    ProjectilesThatWork.instantiateProjectile(
      prodEnt,
      player.dimension,
      player.getHeadLocation(),
      velocity,
      player
    );
    removeNearestItemInInventory(player, "minecraft:ender_pearl");
    player.playSound("sound.spark_amm2.potato_launcher_shoot_pearl");
    return;
  }
  if (closest == "spark_amm2:tater_tot") {
    let prodEnt = `spark_amm2:tater_tot_projectile`;
    let data = config3[prodEnt];
    let direction = player.getViewDirection();
    let normal = Vec3.normal(direction);
    let velocity = Vec3.scale(normal, data.velocity);
    player.runCommandAsync(
      playAnimationFactory(
        "animation.spark_amm2.potato_launcher.third.shoot",
        {
          nextState: `next`,
          blendOutTime: 0.2,
          stopExpression: "q.all_animations_finished || v.is_first_person",
          controller: `controller.animation.spark_amm2.potato_launcher_third`
        }
      )
    );
    ProjectilesThatWork.instantiateProjectile(
      prodEnt,
      player.dimension,
      player.getHeadLocation(),
      velocity,
      player
    );
    removeNearestItemInInventory(player, "spark_amm2:tater_tot");
    player.playSound("sound.spark_amm2.potato_launcher_shoot");
    return;
  }
}
function getOffhandSlot(player) {
  let equipment = player.getComponent(
    "equippable"
  );
  if (!equipment)
    return void 0;
  return equipment.getEquipment(EquipmentSlot.Offhand);
}
function altFirePearl(player) {
  let prodEnt = `${"spark_amm2"}:enderpearl_potate_projectile`;
  let data = config3[prodEnt];
  let direction = player.getViewDirection();
  let normal = Vec3.normal(direction);
  let velocity = Vec3.scale(normal, data.alt_velocity);
  player.runCommandAsync(
    playAnimationFactory(
      "animation.spark_amm2.potato_launcher.third.shoot",
      {
        nextState: `next`,
        blendOutTime: 0.2,
        stopExpression: "q.all_animations_finished || v.is_first_person",
        controller: `controller.animation.spark_amm2.potato_launcher_third`
      }
    )
  );
  ProjectilesThatWork.instantiateProjectile(
    prodEnt,
    player.dimension,
    player.getHeadLocation(),
    velocity,
    player
  );
  player.playSound("sound.spark_amm2.potato_launcher_shoot_pearl");
}
function getClosestProjectileInInventory(player) {
  let offhand = getOffhandSlot(player);
  if (offhand) {
    let exists = projectileItems.indexOf(offhand.typeId);
    if (exists > -1)
      return offhand.typeId;
  }
  let inventory = player.getComponent(
    "inventory"
  );
  if (!inventory)
    return void 0;
  let container = inventory.container;
  if (!container)
    return void 0;
  for (let i = 27; i < container.size; i++) {
    let item = container.getItem(i);
    if (item == void 0)
      continue;
    let exists = projectileItems.indexOf(item.typeId);
    if (exists > -1)
      return item.typeId;
  }
  for (let i = 0; i < 27; i++) {
    let item = container.getItem(i);
    if (item == void 0)
      continue;
    let exists = projectileItems.indexOf(item.typeId);
    if (exists > -1)
      return item.typeId;
  }
  return void 0;
}
function removeNearestItemInInventory(player, item) {
  let offhand = getOffhandSlot(player);
  if (offhand) {
    if (offhand.typeId == item) {
      let equipment = player.getComponent(
        "equippable"
      );
      if (offhand.amount > 1) {
        let newStack = offhand.clone();
        newStack.amount -= 1;
        equipment.setEquipment(EquipmentSlot.Offhand, newStack);
        return;
      }
      equipment.setEquipment(EquipmentSlot.Offhand, void 0);
      return;
    }
  }
  let inventory = player.getComponent(
    "inventory"
  );
  if (!inventory)
    return void 0;
  let container = inventory.container;
  if (!container)
    return void 0;
  for (let i = 27; i < container.size; i++) {
    let itemStack = container.getItem(i);
    if (itemStack == void 0)
      continue;
    if (itemStack.typeId == item) {
      if (itemStack.amount > 1) {
        let newStack = itemStack.clone();
        newStack.amount -= 1;
        container.setItem(i, newStack);
        return;
      }
      container.setItem(i, void 0);
      return;
    }
  }
  for (let i = 0; i < 27; i++) {
    let itemStack = container.getItem(i);
    if (itemStack == void 0)
      continue;
    if (itemStack.typeId == item) {
      if (itemStack.amount > 1) {
        let newStack = itemStack.clone();
        newStack.amount -= 1;
        container.setItem(i, newStack);
        return;
      }
      container.setItem(i, void 0);
      return;
    }
  }
}
function countItemInInventory(player, item) {
  let count = 0;
  let offhand = getOffhandSlot(player);
  if (offhand) {
    if (offhand.typeId == item) {
      count += offhand.amount;
    }
  }
  let inventory = player.getComponent(
    "inventory"
  );
  if (!inventory)
    return count;
  let container = inventory.container;
  if (!container)
    return count;
  for (let i = 0; i < container.size; i++) {
    let itemStack = container.getItem(i);
    if (itemStack == void 0)
      continue;
    if (itemStack.typeId == item) {
      count += itemStack.amount;
    }
  }
  return count;
}

// src/runtime/systems/items/item-player-animations.ts
var itemUseCache = /* @__PURE__ */ new Map();
var animationVariants = {};
world.afterEvents.itemUse.subscribe((e) => {
  playAnimationFromItem(e.source, e.itemStack);
});
world.afterEvents.entityHitEntity.subscribe(({ damagingEntity }) => {
  if (damagingEntity instanceof Player) {
    let player = damagingEntity;
    let equippable = player.getComponent(
      "minecraft:equippable"
    );
    let item_id = equippable.getEquipment(EquipmentSlot.Mainhand)?.typeId;
    let animation_config = item_id && config4.player_attack_animations[item_id];
    if (animation_config) {
      let animation_variant = Math.floor(
        Math.random() * animation_config.animation.length
      );
      animationVariants[damagingEntity.id] = animation_variant;
      let animation_id_third = animation_config.animation instanceof Array ? animation_config.animation[animation_variant] : animation_config.animation;
      let thirdPersonAnim = playAnimationFactory(animation_id_third, {
        nextState: `next`,
        blendOutTime: 0,
        stopExpression: "v.is_first_person",
        controller: `controller.animation.spark_amm2.player_item_attack_third`
      });
      player.runCommand(thirdPersonAnim);
      if (animation_config.first_person_animation) {
        let animation_id_first = animation_config.first_person_animation instanceof Array ? animation_config.first_person_animation[animation_variant % animation_config.first_person_animation.length] : animation_config.first_person_animation;
        let firstPersonAnim = playAnimationFactory(animation_id_first, {
          nextState: `next`,
          blendOutTime: 0,
          stopExpression: "q.any_animation_finished || !v.is_first_person",
          controller: `controller.animation.spark_amm2.player_item_attack_first`
        });
        player.runCommand(firstPersonAnim);
      }
    }
  }
});
world.afterEvents.itemStopUse.subscribe((e) => {
  if (!e.itemStack) {
    if (itemUseCache.has(e.source.id)) {
      playStopAnimationFromItem(e.source, itemUseCache.get(e.source.id));
      itemUseCache.delete(e.source.id);
    }
    return;
  }
  playStopAnimationFromItem(e.source, e.itemStack);
});
function playAnimationFromItem(entity, item) {
  let animation_config = config4.player_use_animations[item.typeId];
  if (animation_config) {
    if (!itemUseCache.has(entity.id)) {
      itemUseCache.set(entity.id, item.typeId);
    }
    if (animation_config.mode == `while_pressing`) {
      entity.runCommandAsync(
        playAnimationFactory(animation_config.animation, {
          controller: `controller.animation.spark_amm2.player_item_attack_third`,
          stopExpression: "!query.is_using_item",
          blendOutTime: 0.2,
          nextState: "default"
        })
      );
    } else {
      entity.runCommandAsync(
        `playanimation @s ${animation_config.animation}`
      );
    }
    if (animation_config.first_person_animation) {
      entity.runCommandAsync(
        playAnimationFactory(animation_config.first_person_animation, {
          controller: "controller.animation.spark_amm2.player_item_attack_first",
          nextState: "next",
          stopExpression: "q.any_animation_finished || !v.is_first_person",
          blendOutTime: 0.2
        })
      );
    }
  }
}
function playStopAnimationFromItem(entity, item) {
  let typeID = item instanceof ItemStack ? item.typeId : item;
  let animation_config = config4.player_stop_use_animations[typeID];
  if (animation_config) {
    if (animation_config.mode == `while_pressing`) {
      entity.runCommandAsync(
        playAnimationFactory(animation_config.animation, {
          controller: `controller.animation.spark_amm2.player_item_attack_third`,
          stopExpression: "!query.is_using_item",
          blendOutTime: 0.2,
          nextState: "default"
        })
      );
    } else {
      entity.runCommandAsync(
        `playanimation @s ${animation_config.animation}`
      );
    }
    if (animation_config.sound) {
      if (entity instanceof Player) {
        let p = entity;
        p.playSound(animation_config.sound);
      } else {
        world.playSound(animation_config.sound, entity.location);
      }
    }
    if (animation_config.first_person_animation) {
      entity.runCommandAsync(
        playAnimationFactory(animation_config.first_person_animation, {
          controller: "controller.animation.spark_amm2.player_item_attack_first",
          nextState: "next",
          stopExpression: "q.all_animations_finished || !v.is_first_person",
          blendOutTime: 0.2
        })
      );
    }
  }
}
system.runInterval(() => {
  world.getAllPlayers().forEach((player) => {
    let equippable = player.getComponent(
      "minecraft:equippable"
    );
    let item_id = equippable.getEquipment(EquipmentSlot.Mainhand)?.typeId;
    let animation_config = item_id && config4.player_hold_animations[item_id];
    if (animation_config) {
      let animation_id_third = animation_config.animation;
      let thirdPersonAnim = playAnimationFactory(animation_id_third, {
        nextState: `next`,
        blendOutTime: 0.2,
        stopExpression: `v.is_first_person || !q.is_item_name_any('slot.weapon.mainhand', '${item_id}')`
      });
      player.runCommandAsync(thirdPersonAnim);
    }
  });
}, 8);

// src/runtime/systems/items/main.ts
world.afterEvents.itemCompleteUse.subscribe(function onCompleteUse(arg) {
  let id = arg.itemStack.typeId;
  switch (id) {
    case `${"spark_amm2"}:tater_tot`:
      processTaterTot(arg.source);
  }
});
function processTaterTot(ent) {
  ent.addEffect("saturation", config4.tater_tot.eat_effect_duration, {
    amplifier: config4.tater_tot.eat_effect_amplifier,
    showParticles: false
  });
}
system.afterEvents.scriptEventReceive.subscribe(
  function processItemScriptEvents(arg) {
    switch (arg.id) {
      case "spark_amm2:spear_drop":
        processSpearDrop(arg.sourceEntity);
        break;
    }
  },
  {
    namespaces: ["spark_amm2"]
  }
);
function processSpearDrop(ent) {
  try {
    let nearest = ent.dimension.getPlayers({
      maxDistance: 1.5,
      closest: 1,
      location: ent.location
    });
    if (nearest.length == 0)
      return;
    let player = nearest[0];
    let health = player.getComponent(
      "minecraft:health"
    );
    if (health.currentValue <= 0)
      return;
    let inventory = player.getComponent(
      "inventory"
    );
    if (!inventory)
      return;
    let container = inventory.container;
    if (!container)
      return;
    if (container.emptySlotsCount == 0) {
      return;
    }
    let id = ent.typeId.replace("_throwable", "");
    let item = new ItemStack(id, 1);
    player.playSound("random.pop", {
      location: player.location,
      volume: 0.5,
      pitch: lerp(0.8, 2, Math.random())
    });
    const _player = player.dimension.getEntities({
      type: "minecraft:player",
      location: player.location,
      closest: 1,
      gameMode: GameMode.creative
    });
    if (_player[0]?.id != player.id)
      container.addItem(item);
    ent.remove();
  } catch {
  }
}
function handleBuckChucketsHit(hitEntity, damagingEntity, item, interactionDamage) {
  const data = config4.buck_chuckets;
  if (!data)
    return;
  let random = animationVariants[damagingEntity.id] ?? randomRange(0, 2);
  let effect_pos = damagingEntity.getHeadLocation();
  let view_dir = damagingEntity.getViewDirection();
  let effect_distance = random == 1 ? 0.6 : 0.8;
  effect_pos = Vec3.add(effect_pos, Vec3.scale(view_dir, effect_distance));
  let vars = new MolangVariableMap();
  vars.setFloat("direction", damagingEntity.getRotation().y);
  switch (random) {
    case 0:
      applyDamage(hitEntity, 5);
      damagingEntity.dimension.spawnParticle(
        "spark_amm2:karate_swing",
        effect_pos,
        vars
      );
      system.runTimeout(() => {
        vars.setFloat(
          "direction",
          damagingEntity.getRotation().y + 100
        );
        damagingEntity.dimension.spawnParticle(
          "spark_amm2:karate_swing",
          effect_pos,
          vars
        );
      }, 2);
      damagingEntity.runCommand(
        "playsound sound.spark_amm2.buck_chucks_critical @a[r=5] ~ ~ ~"
      );
      damagingEntity.dimension.spawnParticle(
        "spark_amm2:crit",
        hitEntity.getHeadLocation()
      );
      break;
    case 1:
      applyDamage(hitEntity, 1);
      damagingEntity.dimension.spawnParticle(
        "spark_amm2:karate_punch",
        effect_pos,
        vars
      );
      let direction = damagingEntity.getViewDirection();
      let normal = Vec3.normal(direction);
      hitEntity.applyKnockback(
        normal.x,
        normal.z,
        data.knockback_strength,
        0
      );
      damagingEntity.runCommand(
        "playsound sound.spark_amm2.buck_chucks_knockback @a[r=5] ~ ~ ~"
      );
      break;
    case 2:
      applyDamage(hitEntity, 1);
      hitEntity.addEffect(
        "slowness",
        data.effect_duration * TicksPerSecond,
        { amplifier: data.effect_amplifier }
      );
      hitEntity.addEffect(
        "weakness",
        data.effect_duration * TicksPerSecond,
        { amplifier: data.effect_amplifier }
      );
      let counter = 0;
      let handle = system.runInterval(() => {
        if (!hitEntity.isValid() || counter > data.effect_duration * 10) {
          system.clearRun(handle);
        } else {
          hitEntity.dimension.spawnParticle(
            "spark_amm2:stun_stars",
            hitEntity.getHeadLocation()
          );
        }
        counter++;
      }, 2);
      damagingEntity.dimension.spawnParticle(
        "spark_amm2:hit_poof",
        effect_pos
      );
      damagingEntity.runCommand(
        "playsound sound.spark_amm2.buck_chucks_stun @a[r=5] ~ ~ ~"
      );
      break;
  }
  damagingEntity.runCommandAsync(
    playAnimationFactory(
      "animation.spark_amm2.buck_chucks.third.attack" + (random + 1),
      {
        controller: "controller.animation.spark_amm2.player_item_attack_third",
        nextState: "next",
        blendOutTime: 0.2,
        stopExpression: "q.all_animations_finished || v.is_first_person"
      }
    )
  );
  damagingEntity.runCommandAsync(
    playAnimationFactory(
      "animation.spark_amm2.buck_chucks.first.attack" + (random + 1),
      {
        controller: "controller.animation.spark_amm2.player_item_attack_first",
        nextState: "next",
        blendOutTime: 0.2,
        stopExpression: "q.all_animations_finished || !v.is_first_person"
      }
    )
  );
}
var entityHurtMapping = /* @__PURE__ */ new Map([["spark_amm2:buck_chuckets", handleBuckChucketsHit]]);
world.afterEvents.entityHurt.subscribe((event) => {
  if (!event.damageSource.damagingEntity)
    return;
  if (event.damageSource.cause != EntityDamageCause.entityAttack)
    return;
  const damager = event.damageSource.damagingEntity;
  const item = getHeldItem(damager);
  if (!item)
    return;
  if (!entityHurtMapping.has(item.typeId))
    return;
  entityHurtMapping.get(item.typeId)(
    event.hurtEntity,
    damager,
    item,
    event.damage
  );
});
function applyDamage(hitEntity, arg1) {
  hitEntity.applyDamage(arg1, {
    cause: EntityDamageCause.entityAttack
  });
}
world.afterEvents.entitySpawn.subscribe((e) => {
  let id = e.entity.typeId;
  if (!id.startsWith(`${"spark_amm2"}`))
    return;
  if (!id.endsWith(`_spear_throwable`))
    return;
  let entity = e.entity;
  let dim = entity.dimension;
  let nearest = dim.getEntities({ location: entity.location, closest: 2 });
  if (!nearest)
    return;
  let near = nearest[0];
  if (near.typeId.endsWith(`_spear_throwable`))
    near = nearest[1];
  let rotation = near.getRotation();
  entity.setProperty("spark_amm2:rot_x", rotation.x);
  entity.setProperty("spark_amm2:rot_y", rotation.y);
});

// src/runtime/utils/binder.ts
var boundFactory = (binding) => Object.assign(
  (...args) => {
    return (...v) => {
      if (v.length === 1) {
        binding.set(v[0], ...args);
        return v[0];
      }
      return binding.get(...args);
    };
  },
  {
    cached: (...args) => {
      let value;
      let invalidatedCache = false;
      return (...v) => {
        if (v.length > 0) {
          binding.set(value = v[0], ...args);
          invalidatedCache = true;
        }
        if (value !== void 0 && !invalidatedCache)
          return value;
        invalidatedCache = false;
        return value !== void 0 ? value : value = binding.get(...args);
      };
    }
  },
  binding
);
var score = boundFactory({
  get: (name, objective, defaultValue = 0) => {
    const so = world.scoreboard.getObjective(objective) ?? world.scoreboard.addObjective(objective, objective);
    if (so.hasParticipant(name))
      return so.getScore(name);
    so.setScore(name, defaultValue);
    return defaultValue;
  },
  set: (value, name, objective, defaultValue) => {
    const so = world.scoreboard.getObjective(objective) ?? world.scoreboard.addObjective(objective, objective);
    so.setScore(name, value);
  }
});
var intProperty = boundFactory({
  get: (entity, property) => {
    return entity.getProperty(property);
  },
  set: (value, entity, property) => {
    entity.setProperty(property, value);
  }
});
var boolProperty = boundFactory({
  get: (entity, property) => {
    return entity.getProperty(property);
  },
  set: (value, entity, property) => {
    entity.setProperty(property, value);
  }
});
var stringProperty = boundFactory({
  get: (entity, property) => {
    return entity.getProperty(property);
  },
  set: (value, entity, property) => {
    entity.setProperty(property, value);
  }
});
var knownDynamicProperties = {};
var dynamicPropertyExists = (property) => {
  if (!knownDynamicProperties[property]) {
    knownDynamicProperties[property] = world.getDynamicPropertyIds().indexOf(property) !== -1;
  }
  return knownDynamicProperties[property];
};
var dynamicPropertyBaseFactory = () => boundFactory({
  get: (property, defaultValue) => {
    return dynamicPropertyExists(property) ? world.getDynamicProperty(property) : defaultValue;
  },
  set: (value, property, defaultValue) => {
    world.setDynamicProperty(property, value);
  }
});
var dynamicProperty = {
  bool: dynamicPropertyBaseFactory(),
  int: dynamicPropertyBaseFactory(),
  string: dynamicPropertyBaseFactory(),
  vector3: dynamicPropertyBaseFactory()
};
function transform(value, handler) {
  let cached;
  let hasCached = false;
  return (...v) => {
    if (v.length > 0) {
      value(handler.to(cached = v[0]));
      hasCached = true;
      return v[0];
    }
    if (hasCached)
      return cached;
    hasCached = true;
    return cached = handler.from(value());
  };
}
((transform2) => {
  function json(value) {
    return transform2(value, {
      from: (v) => JSON.parse(v),
      to: (v) => JSON.stringify(v)
    });
  }
  transform2.json = json;
})(transform || (transform = {}));

// src/runtime/configs/trader.ts
var config5 = {
  entity: `${"spark_amm2"}:wandering_trader`
};

// src/runtime/systems/trader/spawner.ts
var SURFACE_BLOCKS = [
  "minecraft:grass",
  "minecraft:dirt",
  "minecraft:podzol",
  "minecraft:mycelium",
  "minecraft:sand",
  "minecraft:gravel",
  "minecraft:stone",
  "minecraft:andesite",
  "minecraft:diorite",
  "minecraft:granite"
];
function isSurfaceBlock(dim, block) {
  if (!SURFACE_BLOCKS.some((b) => block.permutation.matches(b)))
    return false;
  const above = dim.getBlock({
    x: block.location.x,
    y: block.location.y + 1,
    z: block.location.z
  });
  if (!above || !above.isAir)
    return false;
  const above2 = dim.getBlock({
    x: block.location.x,
    y: block.location.y + 2,
    z: block.location.z
  });
  return !!(above2 && above2.isAir);
}
function isSafeGround(dim, pos) {
  const isInWorld = pos.y >= 0 && pos.y < 320;
  if (!isInWorld)
    return false;
  const block = dim.getBlock(pos);
  if (!block)
    return false;
  return isSurfaceBlock(dim, block);
}
var last_encounter_timer = score("last_encounter_timer", `${"spark_amm2"}.trader_timing`);
var MIN_DISTANCE_FROM_PLAYER = 32;
var MAX_DISTANCE_FROM_PLAYER = 64;
var SPAWN_INTERVAL_MIN = 5 * 60 * 20;
var SPAWN_INTERVAL_MAX = 15 * 60 * 20;
var spawnInterval = score(
  "spawn_interval",
  `${"spark_amm2"}.trader_timing`,
  Math.floor(Math.random() * (SPAWN_INTERVAL_MAX - SPAWN_INTERVAL_MIN)) + SPAWN_INTERVAL_MIN
);
function tick2() {
  system.run(tick2);
  const isTimeForEncounter = last_encounter_timer() >= spawnInterval();
  last_encounter_timer(last_encounter_timer() + 1);
  if (!isTimeForEncounter)
    return;
  const overworld = world.getDimension("minecraft:overworld");
  const players2 = overworld.getPlayers();
  const target = players2[Math.floor(Math.random() * players2.length)];
  if (!target)
    return;
  const targetPos = target.location;
  const offsetDir = Math.random() * Math.PI * 2;
  const offsetDist = MIN_DISTANCE_FROM_PLAYER + Math.random() * (MAX_DISTANCE_FROM_PLAYER - MIN_DISTANCE_FROM_PLAYER);
  const offset = {
    x: Math.round(Math.cos(offsetDir) * offsetDist + targetPos.x),
    y: 320,
    z: Math.round(Math.sin(offsetDir) * offsetDist + targetPos.z)
  };
  const res = overworld.getBlockFromRay(offset, { x: 0, y: -1, z: 0 }, {
    maxDistance: 320
  });
  if (!res)
    return;
  const { block } = res;
  for (let i = 0; i < 10; i++) {
    const pos = {
      x: block.location.x,
      y: block.location.y - i,
      z: block.location.z
    };
    if (isSafeGround(overworld, pos)) {
      last_encounter_timer(0);
      spawnInterval(Math.floor(Math.random() * (SPAWN_INTERVAL_MAX - SPAWN_INTERVAL_MIN)) + SPAWN_INTERVAL_MIN);
      overworld.spawnEntity(config5.entity, {
        x: pos.x,
        y: pos.y + 1,
        z: pos.z
      });
    }
  }
}
system.run(tick2);

// src/runtime/main.ts
ProjectilesThatWork.init();
