UNPKG

@magikcraft/mct1

Version:

Minecraft for Type 1 Diabetes

909 lines (862 loc) 27.4 kB
import * as utils from 'utils' export interface JSONloc { x: number y: number z: number pitch: number yaw: number world: string } export interface iVector3 { // Vars ------------------------------------------------------------------- x: number // Def of x variable y: number // Def of y variable z: number // Def of z variable world: string // Def of world variable // Type Conversions / Constructors ---------------------------------------- FromJSON(JSONlocation: JSONloc) // Scriptcraft Location JSON -> Vector3 toJSON(): JSONloc // Vector3 -> Scriptcraft Location JSON FromLocation(location) // bkLocation -> Vector3 toLocation(): JSONloc // Vector3 -> bkLocation FromArray(array: Array<number>) // Array -> Vector3 toArray(): Array<number | string> // Vector3 -> Array // Methods ---------------------------------------------------------------- magnitude(): number // Will return hypotenuse of vector // Uses Pythagorean Theorem to calculate this normalized(): Vector3 // Will scale the vector so that its magnitude is 1. // Clamps the vector into a unit circle getWorld(worldObj?: boolean): string | any // Will return various instances of the world // If given: worldObj = true, then returns a bukkit world object // worldObj = false/null, then returns a string set(x: number, y: number, z: number, world: string) // Allows you to set values of the vector, without accessing // the core x,y,z,world elements toString(): string // A custom function that outputs a string // Will ommit world if this.world is not set exportWorld(): any // Will return a bukkit world object of the this.world value setWorldHeight(): Vector3 // Will set the vector.y to world top (128) setWorldBottom(): Vector3 // Will set the vector.y to world bottom (256) // Operands --------------------------------------------------------------- Subtract(vector: Vector3): Vector3 // this - vector Times(number: number): Vector3 // this * number Multiply(number: number): Vector3 // this * number Divide(number: number): Vector3 // this / number Add(vector: Vector3): Vector3 // this + vector Equals(vector: Vector3): Boolean // Compares this and vector to see if they are identical // x,y,z,world are used in this calculation NotEquals(vector: Vector3): Boolean // !equals() EqualsComponent(vector: Vector3): Boolean // equals(), but ommits world NotEqualsComponent(vector: Vector3): Boolean // !equals(), but ommits world // Statics (Dont use -> this) --------------------------------------------- // return a new Vector3|number|string etc, vs alters -> this Angle(vectorA: Vector3, vectorB: Vector3): number // Returns the angle between the two vectors ClampMagnitude(vector: Vector3, maxLength: number): number // Returns a copy of vector with its magnitude clamped to maxLength Cross(vectorA: Vector3, vectorB: Vector3): Vector3 // Cross Product of two vectors Minus(vectorA: Vector3, vectorB: Vector3): Vector3 // Minus one vector from another component wise (vectorA - vectorB) Distance(vectorA: Vector3, vectorB: Vector3): number // Returns the distance between vectorA and vectorB Dot(vectorA: Vector3, vectorB: Vector3): number // Dot Product of two vectors Lerp(vectorA: Vector3, vectorB: Vector3, percent: number): Vector3 // Linearly interpolates between two vectors LerpUnclamped(vectorA: Vector3, vectorB: Vector3, percent: number): Vector3 // Linearly interpolates between two vectors // without 0-1 percent sample clamp Max(vectorA: Vector3, vectorB: Vector3): Vector3 // Returns the largest of two vectors Min(vectorA: Vector3, vectorB: Vector3): Vector3 // Returns the smallest of two vectors Normalize(vectorA: Vector3): Vector3 // Will scale the vector so that its magnitude is 1. // Clamps the vector into a unit circle Scale(vectorA: Vector3, vectorB: Vector3): Vector3 // Multiplies two vectors component-wise. Average(vectors: Array<Vector3>): Vector3 // Averages a array of vectors to find the center GetWorlds(vectorA: Vector3, vectorB: Vector3) // Will come to a consensus on which world to use // Then apply that world to the two vectors // Used as a precaution of someone makes a vector with no world GetWorldsArray(vectors: Array<Vector3>): string // Will come to a consensus on which world to use // Then apply that world to all of vectors // Used as a precaution of someone makes a vector with no world } /** * Vector3 * @constructor * @param {number} x - The x component axis * @param {number} y - The y component axis * @param {number} z - The z component axis * @param {string} [world] - World setter */ export class Vector3 { x: number = 0 y: number = 0 z: number = 0 world: string = '' constructor(x = 0, y = 0, z = 0, world = '') { this.x = x this.y = y this.z = z this.world = world } // Inits // ---------------------------------------------------------------------------- /** * FromJSON * @param {object} JSONlocation - A JSON object containing the scriptcraft/util made JSON Location * @returns {Vector3} - The resultant vector * * Will create a Vector3 object based on the JSON Location */ static FromJSON(JSONlocation: JSONloc): Vector3 { return new Vector3( JSONlocation.x, JSONlocation.y, JSONlocation.z, JSONlocation.world ) } /** * toJSON * @return {object} - JSON Location * * Will return a JSON object based of the objects values * If no world as been assigned previously, it will default to 'world' */ toJSON(): JSONloc { var loc: JSONloc = { world: this.world || '', x: this.x, y: this.y, z: this.z, yaw: 0.0, pitch: 0.0, } return loc } /** * FromLocation * @param {object} location - Minecraft/Scriptcrat location object * @return {Vector3} - Generated Vector3 from location * * Will create a Vector3 object based on a location object */ static FromLocation(location): Vector3 { var JSONloc = utils.locationToJSON(location) return new Vector3(JSONloc.x, JSONloc.y, JSONloc.z, JSONloc.world) } /** * toLocation * @return {object} - location * * Will create a location object based from the vector */ toLocation() { var loc: JSONloc = { world: this.world, x: this.x, y: this.y, z: this.z, yaw: 0.0, pitch: 0.0, } return utils.locationFromJSON(loc) } /** * FromArray * @param {Array} array - Vector Array * * Will take a vector array and return a Vector3 */ static FromArray(array) { if (array[3]) { return new Vector3(array[0], array[1], array[2]) } else { return new Vector3(array[0], array[1], array[2]) } } /** * toArray * @return {Array} - Vector Array * * Will return an array from a Vector3 object */ toArray() { if (this.world == '') { return [this.x, this.y, this.z] } else { return [this.x, this.y, this.z, this.world] } } /** * back * @return {Vector3} - Vector3(0,0,-1) * * Will return a new Vector3(0,0,-1) */ static back() { return new Vector3(0, 0, -1) } /** * forward * @return {Vector3} - Vector3(0,0,1) * * Will return a new Vector3(0,0,1) */ static forward() { return new Vector3(0, 0, 1) } /** * right * @return {Vector3} - Vector3(1,0,0) * * Will return a new Vector3(1,0,0) */ static right() { return new Vector3(1, 0, 0) } /** * left * @return {Vector3} - Vector3(-1,0,0) * * Will return a new Vector3(-1,0,0) */ static left() { return new Vector3(-1, 0, 0) } /** * up * @return {Vector3} - Vector3(0,1,0) * * Will return a new Vector3(0,1,0) */ static up() { return new Vector3(0, 1, 0) } /** * down * @return {Vector3} - Vector3(0,-1,0) * * Will return a new Vector3(0,-1,0) */ static down() { return new Vector3(0, -1, 0) } /** * unit * @return {Vector3} - Vector3(1,1,1) * @alias one * * Will return a new Vector3(1,1,1) */ static unit() { return new Vector3(1, 1, 1) } /** * one * @return {Vector3} - Vector3(1,1,1) * @alias unit * * Will return a new Vector3(1,1,1) */ static one = Vector3.unit() /** * zero * @return {Vector3} - Vector3(0,0,0) * * Will return a new Vector3(0,0,0) * Same as calling the constructor without parameters */ static zero = function() { return new Vector3(0, 0, 0) } /** * negativeInfinity * @return {Vector3} - Vector3(-Infinity,-Infinity,-Infinity) * * Will return a new Vector3(-Infinity,-Infinity,-Infinity) */ static negativeInfinity = function() { return new Vector3(-Infinity, -Infinity, -Infinity) } /** * infinity * @return {Vector3} - Vector3(Infinity,Infinity,Infinity) * * Will return a new Vector3(Infinity,Infinity,Infinity) */ static infinity = function() { return new Vector3(Infinity, Infinity, Infinity) } // Properties // ---------------------------------------------------------------------------- // If this is made as a class, these will return based on its own values /** * magnitude * @return {number} - Magnitude of the vector * * Will calculate the magnitude of the vector using Pythagorean Theorem */ magnitude(): number { return Math.sqrt( Math.pow(this.x, 2) + Math.pow(this.y, 2) + Math.pow(this.z, 2) ) } /** * normalized * @return {Vector3} - Normalized Vector * * Will scale the vector so that its magnitude is 1. * Clamps the vector into a unit circle */ normalized() { var ratio = 1 / this.magnitude() return new Vector3(this.x * ratio, this.y * ratio, this.z * ratio) } /** * getWorld * @param {boolean} worldObj * * Will return various instances of the world * If given: worldObj = true, then returns a bukkit world object * worldObj = false/null, then returns a string */ getWorld(worldObj?: boolean): string | any { worldObj = worldObj || false if (worldObj) { return utils.world(this.world) } else { return this.world } } /** * set * @param {number} x - X axis value * @param {number} y - X axis value * @param {number} z - X axis value * @param {string} [world] - world axis value * * Allows you to reassign the vector from its core components */ set(x: number, y: number, z: number, world?: string) { this.x = x this.y = y this.z = z this.world = world || '' } /** * toString * @return {string} - Stringified vector object * * A custom function that outputs a string * Will ommit world if this.world is not set */ toString(): string { if (this.world == '') { return '[' + this.x + ', ' + this.y + ', ' + this.z + ']' } else { return ( '[' + this.x + ', ' + this.y + ', ' + this.z + ', ' + this.world + ']' ) } } /** * exportWorld * @return {string|any}- Returns the world */ exportWorld(): any { if (typeof this.world != 'string') { return this.world } else { return utils.world(this.world) } } /** * setWorldHeight * @return {Vector3} * * Will set the vector.y to world top (128) */ setWorldHeight(): Vector3 { return new Vector3(this.x || 0, 128, this.z || 0, this.world) } /** * setWorldBottom * @return {Vector3} * * Will set the vector.y to world bottom (0) */ setWorldBottom(): Vector3 { return new Vector3(this.x || 0, 0, this.z || 0, this.world) } // Operands // ---------------------------------------------------------------------------- // /** // * subtract // * @alias Minus // * @param {Vector3} vector - Vector to subtract with // * @return {Vector3} - Subtracted vector // * // * Minus one vector from another // */ // subtract(vector :Vector3): Vector3 { // return this.minus(this, vector); // } /** * subtract * @alias minus * @static * @param {Vector3} vectorA - Vector to be subtracted * @param {Vector3} vectorB - Vector to subtract with * @return {Vector3} - Subtracted vector * * Minus one vector from another */ static Subtract(vectorA: Vector3, vectorB: Vector3): Vector3 { return Vector3.Minus(vectorA, vectorB) } // /** // * times // * @param {number} number - Amount to multiply by // * // * Times a vector by a number // */ // times(number: number): Vector3 { // return this.multiply(number); // } /** * Times * @static * @param {Vector3} vectorA - Vector to be multiplied * @param {number} number - Amount to multiply by * * Times a vector by a number */ static Times(vectorA: Vector3, number: number): Vector3 { return Vector3.Multiply(vectorA, number) } // /** // * multiply // * @param {number} number - Amount to multiply by // * @return {Vector3} - Resultant Vector // * // * Times a vector by a number // */ // multiply(number :number): Vector3 { // return new Vector3( // this.x * number, // this.y * number, // this.x * number, // this.world // ); // } /** * multiply * @static * @param {Vector3} vectorA - Vector to be multiplied * @param {number} number - Amount to multiply by * @return {Vector3} - Resultant Vector * * Times a vector by a number */ static Multiply(vector: Vector3, number: number): Vector3 { return new Vector3( vector.x * number, vector.y * number, vector.x * number, vector.world ) } // /** // * divide // * @param {number} number - Amount to multiply by // * // * Divides a vector by a number // */ // divide(number: number): Vector3 { // return new Vector3( // this.x / number, // this.y / number, // this.z / number, // this.world // ); // } /** * Divide * @static * @param {Vector3} vectorA - Vector to be multiplied * @param {number} number - Amount to multiply by * @return {Vector3} - Resultant Vector * * Divides a vector by a number */ static Divide(vectorA: Vector3, number: number): Vector3 { return new Vector3( vectorA.x / number, vectorA.y / number, vectorA.z / number, vectorA.world ) } // /** // * add // * @param {Vector3} vector - Given Vector // * // * Adds a vector to another vector // */ // add(vector: Vector3): Vector3 { // return new Vector3( // this.x + vector.x, // this.y + vector.y, // this.z + vector.z, // this.world // ); // } /** * Add * @static * @param {Vector3} vectorA - First Vector * @param {Vector3} vectorB - Second Vector * @return {Vector3} - Resultant Vector * * Adds a vector to another vector */ static Add(vectorA: Vector3, vectorB: Vector3): Vector3 { return new Vector3( vectorA.x + vectorB.x, vectorA.y + vectorB.y, vectorA.z + vectorB.z, vectorA.world ) } /** * EqualsComponent * @static * @param {Vector3} vectorA - First Vector * @param {Vector3} vectorB - Second Vector * @return {boolean} - Resultant * * Checks if vectorA is the same as vectorB, not including world */ static EqualsComponent(vectorA: Vector3, vectorB: Vector3): boolean { if ( vectorA.x == vectorB.x && vectorA.y == vectorB.y && vectorA.z == vectorB.z ) { return true } else { return false } } static NotEqualsComponent = (vectorA, vectorB) => !Vector3.EqualsComponent(vectorA, vectorB) /** * Equals * @static * @param {Vector3} vectorA - First Vector * @param {Vector3} vectorB - Second Vector * @return {boolean} - Resultant * * Checks if vectorA is the same as vectorB, including world */ static Equals(vectorA: Vector3, vectorB: Vector3): boolean { if ( vectorA.x == vectorB.x && vectorA.y == vectorB.y && vectorA.z == vectorB.z && vectorA.world == vectorB.world ) { return true } else { return false } } static NotEquals = (vectorA, vectorB) => !Vector3.Equals(vectorA, vectorB) // Static Methods // ---------------------------------------------------------------------------- // These dont require a new 'class' to be made /** * Angle * @param {Vector3} vectorA - First Vector * @param {Vector3} vectorB - Second Vector * @return {number} - Angle between the vectors * * Returns the angle between the two vectors */ static Angle(vectorA, vectorB) { return ( Vector3.Dot(vectorA, vectorB) / (vectorA.magnitude() * vectorB.magnitude()) ) } /** * ClampMagnitude * @param {Vector3} vector - Arbitary Vector * @param {number} maxLength - Max length (number) * @return {number} - Angle between the vectors * * Returns a copy of vector with its magnitude clamped to maxLength */ static ClampMagnitude(vector, maxLength) { return Math.min(vector.magnitude(), maxLength) } /** * Cross * @param {Vector3} vectorA - First Vector * @param {Vector3} vectorB - Second Vector * @return {Vector3} - Vector cross product * * Cross Product of two vectors */ static Cross(vectorA, vectorB) { return new Vector3( vectorA.y * vectorB.z - vectorA.z * vectorB.y, vectorA.z * vectorB.x - vectorA.x * vectorB.z, vectorA.z * vectorB.y - vectorA.y * vectorB.x, this.GetWorlds(vectorA, vectorB) ) } /** * Minus * @param {Vector3} vectorA - First Vector * @param {Vector3} vectorB - Second Vector * @return {Vector3} - Minused vector * * Minus one vector from another component wise (vectorA - vectorB) */ static Minus(vectorA, vectorB) { return new Vector3( vectorA.x - vectorB.x, vectorA.y - vectorB.y, vectorA.z - vectorB.z, this.GetWorlds(vectorA, vectorB) ) } /** * Distance * @param {Vector3} vectorA - First Vector * @param {Vector3} vectorB - Second Vector * @return {number} - Distance between the vectors * * Returns the distance between vectorA and vectorB */ static Distance(vectorA, vectorB) { var vector = new Vector3( Math.abs(vectorA.x - vectorB.x), Math.abs(vectorA.y - vectorB.y), Math.abs(vectorA.z - vectorB.z) // World dose not matter, converted to single // number in the next step ) return vector.magnitude() } /** * Dot * @param {Vector3} vectorA - First Vector * @param {Vector3} vectorB - Second Vector * @return {number} - Dot product * * Dot Product of two vectors */ static Dot(vectorA, vectorB) { return ( vectorA.x * vectorB.x + vectorA.y * vectorB.y + vectorA.z * vectorB.z ) } /** * Lerp * @param {Vector3} vectorA - First Vector * @param {Vector3} vectorB - Second Vector * @param {number} percent - 0-1 Value for sampling * @return {Vector3} - Vector postion between the two at the sampled percentage * * Linearly interpolates between two vectors */ static Lerp(vectorA, vectorB, percent) { percent = Math.max(0, Math.min(1, percent || 0.5)) return this.LerpUnclamped(vectorA, vectorB, percent) } /** * LerpUnclamped * @param {Vector3} vectorA - First Vector * @param {Vector3} vectorB - Second Vector * @param {number} percent - 0-1 Value for sampling * @return {Vector3} - Vector postion between the two at the sampled percentage * * Linearly interpolates between two vectors, without 0-1 percent sample clamp */ static LerpUnclamped(vectorA, vectorB, percent) { // Gets point inbetween the two vectors based on a float var vectorBetween = Vector3.Subtract(vectorA, vectorB) return vectorA.add(Vector3.Times(vectorBetween, percent || 0.5)) } /** * Max * @param {Vector3} vectorA - First Vector * @param {Vector3} vectorB - Second Vector * @return {Vector3} - The larger of the two vectors * * Returns a vector that is made from the largest components of two vectors */ static Max(vectorA, vectorB) { if (vectorA.magnitude() > vectorB.magnitude()) { return vectorA } else { return vectorB } } /** * Min * @param {Vector3} vectorA - First Vector * @param {Vector3} vectorB - Second Vector * @return {Vector3} - The smaller of the two vectors * * Returns a vector that is made from the smallest components of two vectors */ static Min(vectorA, vectorB) { if (vectorA.magnitude() < vectorB.magnitude()) { return vectorA } else { return vectorB } } // MoveTowards TODO /** * Normalize * @param {Vector3} vector - Vector to Normalize * * Returns a vector that is made from the smallest components of two vectors */ static Normalize(vector) { return vector.normalized() } // OrthoNormalize TODO // Project TODO // ProjectOnPlane TODO // Reflect TODO // RotateTowards TODO /** * Scale * @param {Vector3} vectorA - First Vector * @param {Vector3} vectorB - Second Vector * * Multiplies two vectors component-wise. */ static Scale(vectorA, vectorB) { return new Vector3( vectorA.x * vectorB.x, vectorA.y * vectorB.y, vectorA.z * vectorB.z, Vector3.GetWorlds(vectorA, vectorB) ) } // SignedAngle TODO // Slerp TODO // SlerpUnclamped TODO // SmoothDamp TODO // -------------------------------------- static Average(vectors: Array<Vector3>): Vector3 { if (vectors.length == 0) { return vectors[0] } else { var vector = new Vector3(0, 0, 0, this.GetWorldsArray(vectors)) for (let i = 0; i < vectors.length; i++) { vector = Vector3.Add(vector, vectors[i]) } return Vector3.Divide(vector, vectors.length) } } static GetWorlds(vectorA: Vector3, vectorB: Vector3) { var worldA = vectorA.world || '' var worldB = vectorA.world || '' if (worldA == '' && worldB == '') { // No world is given return '' } else if (worldA == '') { // World B as the given world return worldB } else if (worldB == '') { // World A as the given world return worldA } else if (worldB == worldA) { // Both worlds have the same name return worldA } } static GetWorldsArray(vectors: Array<Vector3>): string { // var worlds: Array<string> = []; // vectors.forEach(function(v) { worlds.push(v.world) }); // var uWorlds = worlds.filter(function(item, i, ar){ return ar.indexOf(item) === i; }); // var fWorlds = uWorlds.filter(function(x){ return (x !== (undefined || null || '')); }); // return fWorlds.length == 0 ? '' : fWorlds.length == 1 ? fWorlds[0] : fWorlds[Math.round(Math.random() * fWorlds.length)] // Old code var uniqueWorlds: Array<string> = [] for (var i = 0; i < vectors.length; i++) { if (uniqueWorlds.length == 0) { // If no worlds exist yet uniqueWorlds.push(vectors[i].world || '') // Add it } else { // If worlds exist for (var j = 0; j < uniqueWorlds.length; i++) { // For every unique word if (uniqueWorlds[i] != (vectors[i].world || '')) { // If the dose not exist yet in the array uniqueWorlds.push(vectors[i].world || '') } } } // vectors[i].world || ''; } // Due to the way the logic works, remove blank strings ('') var finalWorlds: Array<string> = [] for (var k = 0; k < uniqueWorlds.length; k++) { if (uniqueWorlds[k] !== (undefined || null || '')) { finalWorlds.push(uniqueWorlds[k]) } } if (uniqueWorlds.length == 0) { // No worlds were in the array return '' } else if (uniqueWorlds.length == 1) { // Only one world was found return uniqueWorlds[0] } else { return uniqueWorlds[Math.round(Math.random() * uniqueWorlds.length)] } } static GetRandomPointAround(point: Vector3, radius: number) { const randAngleHoz = Math.round(Math.random() * 360) const randAngleVert = Math.round(Math.random() * 360) const randDist = Math.random() * radius const x = Math.cos(randAngleHoz) * randDist const y = Math.cos(randAngleVert) * randDist const z = Math.sin(randAngleHoz) * randDist const finalPoint = Vector3.Add(point, new Vector3(x, y, z)) return finalPoint } }