import { BlockComponentTypes, Direction, system, BlockVolume } from '@minecraft/server';

var w = Object.defineProperty;
var M = (r, t, n) => t in r ? w(r, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : r[t] = n;
var g = (r, t, n) => M(r, typeof t != "symbol" ? t + "" : t, n);
class m {
  /**
   * Checks if the given Vector3's locations are the same
   *
   * @param vec1 the first Vector3
   * @param vec2 the second Vector3
   * @return if the given Vector3's locations are the same
   */
  static equals(t, n) {
    return !t || !n ? !1 : t.x === n.x && t.y === n.y && t.z === n.z;
  }
  /**
   * Adds given values to the Vector3
   *
   * @param vec3 the location
   * @param x the x amount to add
   * @param y the y amount to add
   * @param z the z amount to add
   */
  static addRaw(t, n, e, a) {
    return {
      x: t.x + n,
      y: t.y + e,
      z: t.z + a
    };
  }
  /**
   * Removes given values to the Vector3
   *
   * @param vec3 the location
   * @param x the x amount to remove
   * @param y the y amount to remove
   * @param z the z amount to remove
   */
  static subtractRaw(t, n, e, a) {
    return this.addRaw(t, -n, -e, -a);
  }
  /**
   * Adds given Vector3's together
   *
   * @param vecA first Vector3 to add
   * @param vecB second Vector3 to add
   * @return a new Vector3 with the locations added together
   */
  static add(t, n) {
    return this.addRaw(t, n.x, n.y, n.z);
  }
  /**
   * Subtracts given Vector3's from each other
   *
   * @param vecA first Vector3 to subtract from
   * @param vecB second Vector3 to subtract
   *
   * @return a new Vector3 with the locations subtracted
   */
  static subtract(t, n) {
    return this.subtractRaw(t, n.x, n.y, n.z);
  }
  /**
   * Zeroes out the Vector3's locations, rounding them down to the nearest integer
   *
   * @param vec3 the Vector3 to zero out
   * @return a new Vector3 with the locations zeroed out
   */
  static floor(t) {
    return {
      x: Math.floor(t.x),
      y: Math.floor(t.y),
      z: Math.floor(t.z)
    };
  }
  /**
   * Converts the Vector3 to a string
   *
   * @param vec3 the Vector3 to convert to string
   * @param separator the separator to use between the coordinates, defaults to a space
   * @return the vec3 formatted as a string
   */
  static toString(t, n = " ") {
    return `${t.x}${n}${t.y}${n}${t.z}`;
  }
  /**
   * creates a Vector3 from a string
   *
   * @param vec3String the string to convert to a Vector3
   * @param separator the separator to use between the coordinates, defaults to a space
   * @return a Vector3 or undefined if the string is not in the correct format
   */
  static fromString(t, n = " ") {
    const e = t.split(n);
    if (e.length === 3)
      return {
        x: parseFloat(e[0]),
        y: parseFloat(e[1]),
        z: parseFloat(e[2])
      };
    throw new Error("Could not parse Vector3 from string: " + t);
  }
}
var x = /* @__PURE__ */ ((r) => (r.MINECRAFT = "minecraft", r.TINKERS = "ftb_tc", r.STORAGE_DRAWERS = "ftb_sd", r.DIRE = "ftb_dire", r.MYSTICAL = "ftb_ma", r.SIEVES = "ftb_sieves", r.BOTANIA = "ftb_botania", r))(x || {});
function u(r, t) {
  return `${r}:${t}`;
}
function E(r) {
  return u("minecraft", r);
}
function L(r) {
  return u("ftb_tc", r);
}
function N(r) {
  return u("ftb_sd", r);
}
function U(r) {
  return u("ftb_sieves", r);
}
function V(r) {
  return u("ftb_ma", r);
}
class W {
  /**
   * If the block can see the sky, check if there are blocks above it the block it from having direct sunlight (Note blocks
   * such as leaves might not count)
   *
   * @param block target player
   * @returns true if the block can see the sky
   */
  static canBlockSeeSky(t) {
    var a;
    const n = t.location, e = (a = t.dimension.getTopmostBlock(n)) == null ? void 0 : a.location;
    return n.y === (e == null ? void 0 : e.y);
  }
  static getBlockContainer(t) {
    const n = t.getComponent(BlockComponentTypes.Inventory);
    return n == null ? void 0 : n.container;
  }
  static isBlockContainer(t) {
    return this.getBlockContainer(t) !== void 0;
  }
  /**
   * Gets the block from the given direction and offset amount.
   *
   * @param block the block to start from
   * @param direction the direction to get the block from
   * @param amount the number of blocks to offset in the given direction, defaults to 1
   * @returns the block or undefined if the block cannot be found / accessed
   */
  static getBlockFromDirection(t, n, e = 1) {
    try {
      switch (n) {
        case Direction.Down:
          return t.below(e);
        case Direction.North:
          return t.north(e);
        case Direction.South:
          return t.south(e);
        case Direction.East:
          return t.east(e);
        case Direction.Up:
          return t.above(e);
        case Direction.West:
          return t.west(e);
      }
    } catch {
      return;
    }
  }
  /**
   * Gets all the blocks around the given block;
   *
   * @param block the block to get the surrounding blocks from
   * @returns the blocks around
   */
  static getConnectedBlocks(t) {
    const n = [];
    for (const e of Object.values(Direction)) {
      const a = this.getBlockFromDirection(t, e);
      a && n.push(a);
    }
    return n;
  }
  /**
   * Fake and entity breaking a block with the item in their main hand
   *
   * @param block the block to break
   * @param entity the entity to break the block
   */
  static fakeBlockBreak(t, n) {
    this.spawnBreakLoot(t, n), system.runTimeout(() => {
      t.setType(E("air"));
    }, 0);
  }
  /**
   * Spawns the loot of a block as if it was broken by an entity.
   *
   * @param block the block to break
   * @param entity the entity to break the block
   */
  static spawnBreakLoot(t, n) {
    const e = m.toString(m.floor(t.location));
    n.runCommand(`loot spawn ${e} mine ${e} mainhand`);
  }
  /**
   * Gets the block in a range of given block
   *
   * @param centerBlock block to get the block around
   * @param range how big of a range to get the blocks in
   * @param includeY should the range extend in the Y direction
   * @param filter block filter to apply
   * @returns the iterator of blocks in the range
   */
  static getBlocksInRange(t, n, e = !0, a = {}) {
    const o = Math.floor(n / 2), i = e ? n / 2 : 0, f = m.floor(m.subtractRaw(t, o, i, o)), d = m.floor(m.addRaw(t, o, i, o)), p = new BlockVolume(f, d);
    return t.dimension.getBlocks(p, a).getBlockLocationIterator();
  }
  /**
   * Updates the block to the given states.
   *
   * @param block to update
   * @param states the states with their values to update
   * @param permutation the block permutation to use, defaults to the current block permutation
   */
  static updateBlockStates(t, n, e = t.permutation) {
    for (const a in n) {
      const o = n[a];
      e = e.withState(a, o);
    }
    t.setPermutation(e);
  }
  /**
   * Updates the block to the given states.
   *
   * @param block to update
   * @param stateName the state to update
   * @param value the value to set the state to
   * @param permutation the block permutation to use, defaults to the current block permutation
   */
  static updateBlockState(t, n, e, a = t.permutation) {
    this.updateBlockStates(t, {
      [n]: e
    }, a);
  }
  static getBlockState(t, n) {
    return t.getState(n);
  }
}
class D {
  /**
   * Generates a random number between a minimum and maximum value
   * 
   * @param min 
   * @param max 
   * 
   * @returns a random number between min and max
   */
  static randomRanged(t, n) {
    if (t > n)
      throw new Error("min must be less than or equal to max");
    return Math.random() * (n - t) + t;
  }
  /**
   * Generates a random integer between 0 and Number.MAX_SAFE_INTEGER
   * 
   * @returns a random integer
   */
  static randomInt() {
    return Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
  }
  /**
   * Clamps a value between a minimum and maximum value
   * 
   * @param value input value
   * @param min minimum value
   * @param max maximum value
   * 
   * @returns the clamped value
   */
  static clamp(t, n, e) {
    return Math.min(Math.max(t, n), e);
  }
  /**
   * Checks if a number is even
   * 
   * @param value input value
   * @returns whether the value is even
   */
  static isEven(t) {
    return t % 2 === 0;
  }
  /**
   * Checks if a number is odd
   * 
   * @param value input value
   * @returns whether the value is odd
   */
  static isOdd(t) {
    return !this.isEven(t);
  }
}
g(D, "TICKS_PER_SECOND", 20);

export { W as BlockUtils, x as Keys, D as Mth, m as VecUtils, V as ma, E as mc, u as namespace, N as sd, U as sieves, L as tc };
