dsabp-js
Version:
DSA (drednot.io) Blueprint implementation and API for Node.js and the browser, in TypeScript.
4 lines • 142 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../../src/index.ts", "../../../src/BPCmd.ts", "../../../src/BuildBits.ts", "../../../src/constants/Enum.ts", "../../../src/constants/ItemEnum.ts", "../../../src/constants/ShapeEnum.ts", "../../../src/BuildCmd.ts", "../../../src/constants/public.ts", "../../../src/ConfigCmd.ts", "../../../src/Blueprint.ts", "../../../src/Decoder.ts", "../../../src/Encoder.ts", "../../../src/util.ts", "../../../src/injNode.ts"],
"sourcesContent": ["import { Blueprint } from \"./Blueprint.js\"\r\nimport { ConfigCmd } from \"./ConfigCmd.js\"\r\nimport { Decoder } from \"./Decoder.js\"\r\nimport { Encoder } from \"./Encoder.js\"\r\nimport { DecoderOptions } from \"./types.js\"\r\nimport * as util from \"./util.js\"\r\n\r\nexport { BPCmd } from \"./BPCmd.js\"\r\nexport { BuildBits } from \"./BuildBits.js\"\r\nexport { BuildCmd } from \"./BuildCmd.js\"\r\nexport { Enum } from \"./constants/Enum.js\"\r\nexport { FabricatorType, Item } from \"./constants/ItemEnum.js\"\r\nexport * from \"./constants/public.js\"\r\nexport { Shape } from \"./constants/ShapeEnum.js\"\r\nexport * from \"./types.js\"\r\nexport { Blueprint, ConfigCmd, Decoder, Encoder }\r\n\r\n/**\r\n * Synchronously decodes a blueprint string.\r\n * Supports the \"DSA:\" prefix (case-insensitive).\r\n * @param input The blueprint string.\r\n * @param options Decoding options.\r\n * @example\r\n * import { decodeSync } from \"dsabp-js\"\r\n * \r\n * const bp = decodeSync(str)\r\n */\r\nexport function decodeSync(input: string, options?: DecoderOptions) {\r\n\treturn new Decoder().decodeSync(input, options)\r\n}\r\n\r\n/**\r\n * Asynchronously decodes a blueprint string.\r\n * Supports the \"DSA:\" prefix (case-insensitive).\r\n * @param input The blueprint string.\r\n * @param options Decoding options.\r\n * @example\r\n * import { decode } from \"dsabp-js\"\r\n * \r\n * const bp = await decode(str)\r\n */\r\nexport async function decode(input: string, options?: DecoderOptions) {\r\n\treturn util.decodeAsync(input, options)\r\n}\r\n\r\n/**\r\n * Synchronously decodes the data of a {@link ConfigCmd} containing raw data.\r\n * See {@link DecoderOptions.ignoreConfigCmdData} for more info.\r\n * @returns The same input instance, with decoded data.\r\n */\r\nexport function decodeConfigCmdSync(cmd: ConfigCmd) {\r\n\treturn new Decoder().decodeConfigCmdSync(cmd)\r\n}\r\n\r\n/**\r\n * Asynchronously decodes the data of a {@link ConfigCmd} containing raw data.\r\n * See {@link DecoderOptions.ignoreConfigCmdData} for more info.\r\n * @returns The same input instance, with decoded data.\r\n */\r\nexport async function decodeConfigCmd(cmd: ConfigCmd) {\r\n\tif (!(cmd instanceof ConfigCmd))\r\n\t\tthrow new TypeError(`input must be a ${ConfigCmd.name}`)\r\n\tif (!cmd.isRaw) return cmd\r\n\tconst dataArr = await util.decodeConfigCmdAsync(cmd.rawData)\r\n\tcmd.rawData = undefined\r\n\treturn cmd.fillDataFromArray(dataArr)\r\n}\r\n\r\n/**\r\n * Synchronously encodes a {@link Blueprint} into a blueprint string.\r\n * Does not include the \"DSA:\" prefix, consider adding it on a public app.\r\n * @param input The blueprint to encode.\r\n * @example\r\n * import { encodeSync, PREFIX } from \"dsabp-js\"\r\n * \r\n * const str = PREFIX + encodeSync(bp)\r\n */\r\nexport function encodeSync(input: Blueprint) {\r\n\treturn new Encoder().encodeSync(input)\r\n}\r\n\r\n/**\r\n * Asynchronously encodes a {@link Blueprint} into a blueprint string.\r\n * Does not include the \"DSA:\" prefix, consider adding it on a public app.\r\n * @param input The blueprint to encode.\r\n * @example\r\n * import { encode, PREFIX } from \"dsabp-js\"\r\n * \r\n * const str = PREFIX + await encode(bp)\r\n */\r\nexport function encode(input: Blueprint) {\r\n\treturn util.encodeAsync(input)\r\n}\r\n", "export abstract class BPCmd {\r\n\r\n\tabstract clone()\r\n\r\n\tabstract toArray(): any[]\r\n}\r\n", "/**\r\n * Used to specify repeated placements along the X+ axis in a single build command.\r\n * `101` = place 2 objects with a space between. Cannot exceed 64 bits.\r\n */\r\nexport class BuildBits {\r\n\r\n\tint: bigint\r\n\r\n\r\n\tconstructor(input?: string | number | bigint) {\r\n\t\tif (input == null) {\r\n\t\t\tthis.int = 0n\r\n\t\t\treturn\r\n\t\t}\r\n\t\tif (typeof input == \"string\") {\r\n\t\t\tinput = \"0b\" + reverse(input)\r\n\t\t} else if (typeof input != \"number\" && typeof input != \"bigint\") {\r\n\t\t\tthrow new TypeError(\"input must be a number, bigint or string\")\r\n\t\t}\r\n\t\tthis.int = BigInt(input)\r\n\t}\r\n\r\n\r\n\tset(index: number): this {\r\n\t\tif (index < 0 || index > 63) throw new RangeError(\"index must be between [0,63]\")\r\n\t\tthis.int |= mask(index)\r\n\t\treturn this\r\n\t}\r\n\r\n\r\n\tclear(index: number): this {\r\n\t\tif (index < 0 || index > 63) throw new RangeError(\"index must be between [0,63]\")\r\n\t\tthis.int &= ~mask(index)\r\n\t\treturn this\r\n\t}\r\n\r\n\r\n\ttoggle(index: number, force?: boolean): this {\r\n\t\tif (index < 0 || index > 63) throw new RangeError(\"index must be between [0,63]\")\r\n\t\tif (typeof force == \"undefined\")\r\n\t\t\tthis.int ^= mask(index)\r\n\t\telse if (force === true)\r\n\t\t\tthis.set(index)\r\n\t\telse if (force === false)\r\n\t\t\tthis.clear(index)\r\n\t\treturn this\r\n\t}\r\n\r\n\r\n\tisSet(index: number): boolean {\r\n\t\tif (index < 0 || index > 63) return false\r\n\t\treturn !!(this.int & mask(index))\r\n\t}\r\n\r\n\r\n\tisZero(): boolean {\r\n\t\treturn this.int == 0n\r\n\t}\r\n\r\n\r\n\tisOne(): boolean {\r\n\t\treturn this.int == 1n\r\n\t}\r\n\r\n\r\n\ttrimLeadZeros(): this {\r\n\t\tif (this.int)\r\n\t\t\tthis.int /= -this.int & this.int\r\n\t\treturn this\r\n\t}\r\n\r\n\r\n\tget size(): number {\r\n\t\treturn this.int.toString(2).length\r\n\t}\r\n\r\n\t*[Symbol.iterator](): Iterator<boolean> {\r\n\t\tfor (const b of reverse(this.int.toString(2))) {\r\n\t\t\tyield b == \"1\"\r\n\t\t}\r\n\t}\r\n\r\n\r\n\ttoArray(): boolean[] {\r\n\t\treturn Array.from(this)\r\n\t}\r\n\r\n\r\n\ttoString(): string {\r\n\t\treturn reverse(this.int.toString(2))\r\n\t}\r\n\r\n\r\n\tget [Symbol.toStringTag]() {\r\n\t\treturn this.toString()\r\n\t}\r\n\r\n\r\n\tequals(target: BuildBits) {\r\n\t\treturn this.int === target?.int\r\n\t}\r\n\r\n\r\n\tclone(): BuildBits {\r\n\t\treturn Object.assign(Object.create(Object.getPrototypeOf(this)), this)\r\n\t}\r\n}\r\n\r\nfunction mask(i: number) {\r\n\treturn 1n << BigInt(i)\r\n}\r\n\r\nfunction reverse(str: string) {\r\n\tif (str.length < 1) return str\r\n\treturn str.split(\"\").reduce((r, c) => c + r)\r\n}\r\n", "interface C<T> {\r\n\tnew(...args: any[]): T\r\n\tmaps: any\r\n\tgetMap: any\r\n\tgetReverseMap: any\r\n}\r\n\r\n/**\r\n * An alternative to TS Enums. Simple, efficient, and compatible with IntelliSense.\r\n * \r\n * An enum constant is an instance of the derived class. References to instances are stored in maps for fast lookups.\r\n * The derived class can add static or non-static members to store more data or to have more methods on the enum.\r\n * A constant must have a \"main value\" (enumValue) that can be anything (preferably a primitive) and is used with the reverse mapping.\r\n * Easy to add NoReverseEnum and NoValueEnum if ever needed.\r\n */\r\n\r\n/** @hidden */\r\nexport class Enum<V> {\r\n\r\n\tstatic readonly maps = new Map<string, [Map<string, Enum<any>>, Map<any, string>]>()\r\n\r\n\r\n\tstatic getMap<CT>(this: C<CT>): Map<string, CT> {\r\n\t\treturn this.maps.get(this.name)[0]\r\n\t}\r\n\r\n\r\n\tstatic getReverseMap<CT extends { enumValue: any }>(this: C<CT>): Map<CT[\"enumValue\"], string> {\r\n\t\treturn this.maps.get(this.name)[1]\r\n\t}\r\n\r\n\r\n\tstatic getByName<CT>(this: C<CT>, name: string): CT | undefined {\r\n\t\treturn this.getMap().get(name)\r\n\t}\r\n\r\n\r\n\tstatic getByValue<CT extends { enumValue: any }>(this: C<CT>, value: CT[\"enumValue\"]): CT | undefined {\r\n\t\treturn this.getMap().get(\r\n\t\t\tthis.getReverseMap().get(value)\r\n\t\t)\r\n\t}\r\n\r\n\r\n\tstatic end() {\r\n\t\tthis.maps.set(this.name, [new Map(), new Map()])\r\n\t\tconst map = this.getMap()\r\n\t\tconst reverseMap = this.getReverseMap()\r\n\t\tfor (const key in this) {\r\n\t\t\tconst value = this[key]\r\n\t\t\tif (value instanceof Enum) {\r\n\t\t\t\tvalue.enumName = key\r\n\t\t\t\tmap.set(key, value)\r\n\t\t\t\treverseMap.set(value.enumValue, key)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tconstructor(value: V) {\r\n\t\tthis.enumValue = value\r\n\t}\r\n\r\n\r\n\tenumName: string\r\n\r\n\r\n\tenumValue: V\r\n\r\n\r\n\ttoString() {\r\n\t\treturn this.constructor.name + \".\" + this.enumName\r\n\t}\r\n}\r\n", "import { Enum } from \"./Enum.js\"\r\n\r\nexport type FabricatorType = \"Legacy\" | \"Starter\" | \"Munitions\" | \"Engineering\" | \"Machine_DEPRECATED\" | \"Equipment\"\r\n\r\n/**\r\n * The item names, IDs and data are taken directly from the game source.\r\n *\r\n * The item data may be unstable because it is not edited or checked, including the\r\n * property names. If you use it, it is up to you to test it and handle the game changes.\r\n * The major version won't be incremented for any breaking changes to it.\r\n *\r\n * <small>Generated using test.drednot.io version: `Sat Nov 2 23:16:10 MDT 2024 / 07f2ca2`</small>\r\n */\r\nexport class Item extends Enum<number> {\r\n\treadonly name: string\r\n\treadonly description: string\r\n\treadonly stackable: boolean\r\n\treadonly rarity: number\r\n\tdeclare readonly image?: string\r\n\tdeclare readonly recipe?: Partial<{ count: number, time: number, input: { item: number, count: number }[], built_by: FabricatorType[] }>\r\n\r\n\tdeclare readonly buildInfo?: Array<Partial<{ bounds: { x: number, y: number }, shape: { verts: { x: number, y: number }[] }, allow_non_solids: boolean, image: string, image_only: boolean, snap_y: boolean, offset: { x: number, y: number }, require_blocks: { x: number, y: number, block: \"_BUILD_SURFACE\" | \"AIR\" | \"HULL_CORNER\" | \"HULL_H\" | \"HULL_V\" | \"INTERIOR_BLOCK\" | \"LADDER\" | \"WALKWAY\" | \"ITEM_NET\" | \"RAMP_1\" | \"RAMP_2\" | \"RAMP_3\" | \"RAMP_4\" | \"COLOR_PANEL\" | \"HYPER_RUBBER\" | \"ICE_GLASS\" | \"ANNIHILATOR\" }[], allow_solids: boolean, snap_x: boolean, buildDirection: \"HORIZONTAL\" | \"VERTICAL\", allow_world: boolean, block: number, block_shaped: boolean, block_is_colored: boolean, allow_any: boolean, build_angle: \"Any\" | \"Fixed\", image_anim: string, is_lockdown_override: boolean, offset2: { x: number, y: number } }>>\r\n\tdeclare readonly blacklist_autobuild?: boolean\r\n\tdeclare readonly fab_type?: FabricatorType\r\n\r\n\tconstructor(id, name, description, stackable, rarity, image?, recipe?, buildInfo?, blacklist_autobuild?, fab_type?) {\r\n\t\tsuper(id)\r\n\t\tthis.name = name\r\n\t\tthis.description = description\r\n\t\tthis.stackable = stackable\r\n\t\tthis.rarity = rarity\r\n\t\tif (image !== undefined) this.image = image\r\n\t\tif (recipe !== undefined) this.recipe = recipe\r\n\t\tif (buildInfo !== undefined) this.buildInfo = buildInfo\r\n\t\tif (blacklist_autobuild !== undefined) this.blacklist_autobuild = blacklist_autobuild\r\n\t\tif (fab_type !== undefined) this.fab_type = fab_type\r\n\t}\r\n\r\n\tdeclare enumValue: number\r\n\r\n\tget id() { return this.enumValue }\r\n\tget isBuildable() { return !!this.buildInfo }\r\n\tget isBlock() { return !!this.buildInfo?.[0]?.block }\r\n\r\n\tstatic getById(id: number) { return Item.getByValue(id) }\r\n\r\n\tstatic NULL = new this(0, \"\", \"\", false, NaN)\r\n\r\n\tstatic RES_METAL = new this(1, \"Iron\", \"Material. Used to produce most items.\", true, 0, \"item/res_iron\")\r\n\r\n\tstatic RES_GUNPOWDER = new this(2, \"Explosives\", \"Material. Used to produce munitions.\", true, 0, \"item/res_explosives\")\r\n\r\n\tstatic RES_HYPER_RUBBER = new this(4, \"Hyper Rubber\", \"Material. High Elasticity.\", true, 2, \"item/res_hyper_rubber\")\r\n\r\n\tstatic RES_FLUX = new this(5, \"Flux Crystals\", \"Material. Used to produce advanced machinery.\", true, 2, \"item/res_flux_crystals\")\r\n\r\n\tstatic RES_FUEL = new this(6, \"Thruster Fuel\", \"Refined fuel. Powers thrusters. More efficient than explosives.\", true, 0, \"item/fuel\", {count:1,time:30,input:[{item:2,count:1}],built_by:[\"Munitions\"]})\r\n\r\n\tstatic COMPRESSED_EXPLOSIVES = new this(49, \"Compressed Explosives\", \"Explosives, compressed into a flux matrix at a 16:1 ratio. Unpack with a recycler.\", true, 2, \"item/comp_exp\")\r\n\r\n\tstatic COMPRESSED_IRON = new this(50, \"Compressed Iron\", \"Iron, compressed into a flux matrix at a 24:1 ratio. Unpack with a recycler.\", true, 2, \"item/comp_iron\")\r\n\r\n\tstatic BALL_VOLLEY = new this(51, \"Volleyball\", \"\uD83C\uDFD0\", false, 2, \"item/ball_volley\")\r\n\r\n\tstatic BALL_VOLLEY_GOLD = new this(52, \"Golden Volleyball\", \"\uD83C\uDF1F\uD83C\uDFD0\uD83C\uDF1F\", false, 2, \"item/ball_vg\")\r\n\r\n\tstatic BALL_BASKET = new this(53, \"Basketball\", \"\uD83C\uDFC0\", false, 2, \"item/ball_basket\")\r\n\r\n\tstatic BALL_BASKET_GOLD = new this(54, \"Golden Basketball\", \"\uD83C\uDF1F\uD83C\uDFC0\uD83C\uDF1F\", false, 2, \"item/ball_bg\")\r\n\r\n\tstatic BALL_BEACH = new this(55, \"Beach Ball\", \"\uD83C\uDF34\", false, 2, \"item/ball_beach\")\r\n\r\n\tstatic BALL_SOCCER = new this(56, \"Football\", \"\u26BD\", false, 2, \"item/ball_soccer\")\r\n\r\n\tstatic WRENCH = new this(100, \"Wrench\", \"Used to take stuff apart.\", false, 0, \"item/wrench\", {count:1,time:5,input:[{item:1,count:4}],built_by:[\"Starter\",\"Engineering\"]})\r\n\r\n\tstatic SHREDDER = new this(101, \"Item Shredder\", \"Destroys items.\", false, 0, \"item/item_shredder\", {count:1,time:5,input:[{item:1,count:4}],built_by:[\"Starter\",\"Engineering\"]})\r\n\r\n\tstatic SHREDDER_GOLD = new this(102, \"Golden Item Shredder\", \"Destroys items quickly, with style.\", false, 9, \"item/item_shredder_g\")\r\n\r\n\tstatic REPAIR_TOOL = new this(103, \"Repair Tool\", \"Used to repair blocks and objects.\", false, 0, \"item/repair_tool\", {count:1,time:5,input:[{item:1,count:4}],built_by:[\"Starter\",\"Engineering\"]})\r\n\r\n\tstatic HAND_PUSHER = new this(104, \"Handheld Pusher\", \"A pusher you can hold in your hand.\", false, 2, \"item/pusher_hand\", {count:1,time:5,input:[{item:1,count:4},{item:5,count:16}],built_by:[\"Engineering\"]})\r\n\r\n\tstatic SHIELD_BOOSTER = new this(105, \"Ship Shield Booster\", \"An inferior power source for shield generators.\", false, 0, \"item/repairkit\", {count:1,time:3,input:[{item:1,count:2}],built_by:[\"Engineering\",\"Munitions\"]})\r\n\r\n\tstatic SHIP_EMBIGGENER = new this(106, \"Ship Embiggener\", \"Makes your ship bigger. Press R to change axis.\", false, 0, \"item/ship_embiggener\", {count:1,time:3,input:[{item:1,count:4}],built_by:[\"Starter\",\"Engineering\"]})\r\n\r\n\tstatic SHIP_SHRINKINATOR = new this(107, \"Ship Shrinkinator\", \"Makes your ship smaller. Space must be completely empty. Press R to change axis.\", false, 0, \"item/ship_shrinkinator\", {count:1,time:3,input:[{item:1,count:4}],built_by:[\"Engineering\"]})\r\n\r\n\tstatic EQUIPMENT_BACKPACK = new this(108, \"Backpack\", \"Equipment (Back). Lets you hold more items.\", false, 1, \"item/eq_backpack\")\r\n\r\n\tstatic EQUIPMENT_SPEED_SKATES = new this(109, \"Speed Skates\", \"Equipment (Feet). SPEED.\", false, 2, \"item/eq_speed_skates\", {count:1,time:20,input:[{item:1,count:8},{item:4,count:4},{item:5,count:16}],built_by:[\"Equipment\"]})\r\n\r\n\tstatic EQUIPMENT_BOOSTER_BOOTS = new this(110, \"Booster Boots\", \"Equipment (Feet). Provides a double-jump and slightly more powerful jumps.\", false, 2, \"item/eq_booster_boots\", {count:1,time:20,input:[{item:1,count:8},{item:4,count:8},{item:5,count:16}],built_by:[\"Equipment\"]})\r\n\r\n\tstatic EQUIPMENT_LAUNCHER_GAUNTLETS = new this(111, \"Launcher Gauntlets\", \"Equipment (Hands). Throw items more powerfully.\", false, 2, \"item/eq_launcher_gauntlets\", {count:1,time:20,input:[{item:1,count:8},{item:4,count:8},{item:5,count:8}],built_by:[\"Equipment\"]})\r\n\r\n\tstatic EQUIPMENT_CONSTRUCTION_GAUNTLETS = new this(112, \"Construction Gauntlets\", \"Equipment (Hands). While in a safe zone: Doubles build/destruct/repair/use range and speed, and allows using objects through walls.\", false, 2, \"item/eq_construction_gauntlets\", {count:1,time:20,input:[{item:1,count:8},{item:4,count:4},{item:5,count:32}],built_by:[\"Equipment\"]})\r\n\r\n\tstatic EQUIPMENT_ROCKET_PACK = new this(113, \"Rocket Pack\", \"Equipment (Back). Speedy Flight.\", false, 2, \"item/eq_rocket_pack\", {count:1,time:20,input:[{item:1,count:16},{item:4,count:4},{item:5,count:32}],built_by:[\"Equipment\"]})\r\n\r\n\tstatic EQUIPMENT_HOVER_PACK = new this(114, \"Hover Pack\", \"Equipment (Back). Controlled Flight.\", false, 2, \"item/eq_hover_pack\", {count:1,time:20,input:[{item:1,count:16},{item:4,count:4},{item:5,count:32}],built_by:[\"Equipment\"]})\r\n\r\n\tstatic SCANNER_MANIFEST = new this(115, \"Manifest Scanner\", \"Generate a list of items on your ship.\", false, 2, \"item/scanner_manifest\")\r\n\r\n\tstatic SCANNER_BOM = new this(116, \"BoM Scanner\", \"Generate a list of materials used to build your ship.\", false, 2, \"item/scanner_bom\")\r\n\r\n\tstatic WRENCH_STARTER = new this(117, \"Starter Wrench\", \"Useful for getting you out of a bind. Slow. Disappears if dropped.\", false, -1, \"item/wrench_starter\")\r\n\r\n\tstatic SHREDDER_STARTER = new this(118, \"Starter Shredder\", \"Destroys items. Slow. Disappears if dropped.\", false, -1, \"item/item_shredder_starter\")\r\n\r\n\tstatic HAND_CANNON = new this(119, \"Hand Cannon\", \"[TEST EXCLUSIVE] A small, handheld cannon. Uses ammo in your inventory.\", false, 0, \"item/hand_cannon\")\r\n\r\n\tstatic SCANNER_BLUEPRINT = new this(120, \"Blueprint Scanner\", \"Generates blueprint strings, which describe how to rebuild ships or parts of ships. Click and drag to select a region.\", false, 2, \"item/scanner_blueprint\")\r\n\r\n\tstatic RCD_SANDBOX = new this(121, \"Sandbox RCD\", \"Buildable. Used for automated construction. This test-exclusive variant can spawn items and doesn't need fuel. It works faster on ships owned by patrons.\", false, -1, \"item/rcd_sandbox\", undefined, [{bounds:{x:2.5,y:2.5},shape:{verts:[{x:-1.25,y:-0.5},{x:-0.5,y:-1.25},{x:0.5,y:-1.25},{x:1.25,y:-0.5},{x:1.25,y:0.5},{x:0.5,y:1.25},{x:-0.5,y:1.25},{x:-1.25,y:0.5}]},allow_non_solids:true,image:\"rcd_sandbox\",image_only:true}], true)\r\n\r\n\tstatic RCD_FLUX = new this(122, \"Flux RCD\", \"Buildable. Used for automated construction. Consumes flux as fuel.\", false, 2, \"item/rcd_flux\", undefined, [{bounds:{x:2.5,y:2.5},shape:{verts:[{x:-1.25,y:-0.5},{x:-0.5,y:-1.25},{x:0.5,y:-1.25},{x:1.25,y:-0.5},{x:1.25,y:0.5},{x:0.5,y:1.25},{x:-0.5,y:1.25},{x:-1.25,y:0.5}]},allow_non_solids:true,image:\"rcd_flux\",image_only:true}], true)\r\n\r\n\tstatic SHIELD_CORE = new this(123, \"Shield Core\", \"A power source for shield generators.\", false, 1, \"item/shield_core\")\r\n\r\n\tstatic AMMO_STANDARD = new this(150, \"Standard Ammo\", \"Regular bullets.\", true, 0, \"item/ammo_standard\", {count:4,time:1,input:[{item:1,count:1},{item:2,count:1}],built_by:[\"Starter\",\"Munitions\"]})\r\n\r\n\tstatic AMMO_SCATTER = new this(151, \"ScatterShot Ammo\", \"Shoots multiple projectiles. Significant damage at close range, with knock-back.\", true, 0, \"item/ammo_scattershot\", {count:4,time:1,input:[{item:1,count:1},{item:2,count:1}],built_by:[\"Munitions\"]})\r\n\r\n\tstatic AMMO_FLAK = new this(152, \"Flak Ammo\", \"Explodes into more bullets in flight.\", true, 0, \"item/ammo_flak\", {count:4,time:1,input:[{item:1,count:1},{item:2,count:1}],built_by:[\"Munitions\"]})\r\n\r\n\tstatic AMMO_SNIPER = new this(153, \"Sniper Ammo\", \"Speedy. Gains power from bouncing.\", true, 0, \"item/ammo_sniper\", {count:4,time:1,input:[{item:1,count:1},{item:2,count:1}],built_by:[\"Munitions\"]})\r\n\r\n\tstatic AMMO_PUNCH = new this(154, \"Punch Ammo\", \"Pushes objects away.\", true, 0, \"item/ammo_punch\", {count:4,time:1,input:[{item:1,count:1},{item:2,count:1}],built_by:[\"Munitions\"]})\r\n\r\n\tstatic AMMO_YANK = new this(155, \"Yank Ammo\", \"Pulls objects.\", true, 0, \"item/ammo_yank\", {count:4,time:1,input:[{item:1,count:1},{item:2,count:1}],built_by:[\"Munitions\"]})\r\n\r\n\tstatic AMMO_SLUG = new this(156, \"Slug Ammo\", \"Slow bullet. Gains speed and damage as it falls.\", true, 0, \"item/ammo_slug\", {count:4,time:1,input:[{item:1,count:1},{item:2,count:1}],built_by:[\"Munitions\"]})\r\n\r\n\tstatic AMMO_TRASH = new this(157, \"Trash Box\", \"Low quality, but free! Decays over time.\", true, 0, \"item/ammo_trash\", {count:1,time:3,input:[],built_by:[\"Munitions\"]})\r\n\r\n\tstatic FUEL_BOOSTER_LOW = new this(159, \"Booster Fuel (Low Grade)\", \"Increases thruster power for a short time.\", false, 0, \"item/booster_low\", {count:1,time:30,input:[{item:2,count:16}],built_by:[\"Munitions\"]})\r\n\r\n\tstatic FUEL_BOOSTER_HIGH = new this(160, \"Booster Fuel (High Grade)\", \"Increases thruster power for a short time.\", false, 2, \"item/booster_high\", {count:4,time:30,input:[{item:2,count:64},{item:5,count:1}],built_by:[\"Munitions\"]})\r\n\r\n\tstatic VOID_ORB = new this(161, \"Void Orb\", \"DO NOT EAT!\", false, 10, \"item/void_orb\")\r\n\r\n\tstatic TURRET_BOOSTER_RAPID = new this(162, \"Turret Booster - Rapid Fire\", \"Boosts a re-configurable turret's fire rate by 50%, with reduced accuracy.\", false, 2, \"item/turret_booster_rapid\")\r\n\r\n\tstatic TURRET_BOOSTER_RAPID_USED = new this(163, \"Turret Booster - Rapid Fire (Depleted)\", \"Boosts a re-configurable turret's fire rate by 25%, with reduced accuracy. Nearly depleted!\", false, 2, \"item/turret_booster_rapid_used\")\r\n\r\n\tstatic TURRET_BOOSTER_PRESERVATION = new this(164, \"Turret Booster - Preservation\", \"Boosts a re-configurable turret's ammo preservation by 10%, with reduced rotational aiming limits.\", false, 2, \"item/turret_booster_preservation\")\r\n\r\n\tstatic TURRET_BOOSTER_PRESERVATION_USED = new this(165, \"Turret Booster - Preservation (Depleted)\", \"Boosts a re-configurable turret's ammo preservation by 5%, with reduced rotational aiming limits. Nearly depleted!\", false, 2, \"item/turret_booster_preservation_used\")\r\n\r\n\tstatic COOLING_CELL = new this(166, \"Cooling Cell\", \"Prevents machine cannons from damaging themselves.\", false, 0, \"item/cooling_cell\", {count:1,time:1,input:[{item:234,count:4}],built_by:[\"Munitions\"]})\r\n\r\n\tstatic COOLING_CELL_HOT = new this(167, \"Cooling Cell (Hot)\", \"Will take some time to cool back down.\", false, 0, \"item/cooling_cell_hot\")\r\n\r\n\tstatic BURST_CHARGE = new this(168, \"Burst Charge\", \"Power source for burst cannons. Overcharging cannons may result in damage!\", false, 0, \"item/burst_charge\", {count:1,time:1,input:[{item:2,count:4}],built_by:[\"Munitions\"]})\r\n\r\n\tstatic HELM = new this(215, \"Helm (Packaged)\", \"Buildable. Used to pilot your ship.\", false, 0, \"item/helm\", {count:1,time:10,input:[{item:1,count:8}],built_by:[\"Engineering\"]}, [{snap_y:true,offset:{x:0,y:0.3},bounds:{x:1.5,y:1.5},require_blocks:[{x:0,y:-1,block:\"_BUILD_SURFACE\"}],allow_solids:true,image:\"helm_wheel\",image_only:true}])\r\n\r\n\tstatic HELM_STARTER = new this(216, \"Helm (Starter, Packaged)\", \"Buildable Starter Item. Used to pilot your ship.\", false, -1, \"item/helm_starter\", undefined, [{snap_y:true,offset:{x:0,y:0.3},bounds:{x:1.5,y:1.5},require_blocks:[{x:0,y:-1,block:\"_BUILD_SURFACE\"}],allow_solids:true,image:\"helm_wheel_starter\",image_only:true}])\r\n\r\n\tstatic COMMS_STATION = new this(217, \"Comms Station (Packaged)\", \"Buildable. Used to communicate with other ships.\", false, 0, \"item/comms\", {count:1,time:10,input:[{item:1,count:8}],built_by:[\"Engineering\"]}, [{snap_y:true,offset:{x:0,y:-0.25},bounds:{x:1.25,y:2.5},require_blocks:[{x:0,y:-2,block:\"_BUILD_SURFACE\"}],allow_solids:true,image:\"comms_station\",image_only:true}])\r\n\r\n\tstatic SIGN = new this(218, \"Sign (Packaged)\", \"Buildable. Can display a short message.\", false, 0, \"item/sign\", {count:1,time:10,input:[{item:1,count:8}],built_by:[\"Engineering\"]}, [{snap_x:true,snap_y:true,bounds:{x:1,y:1},allow_solids:true,image:\"sign\"}], true)\r\n\r\n\tstatic SPAWN_POINT = new this(219, \"Spawn Point (Packaged)\", \"Buildable. Can be set to spawn a specific rank.\", false, 0, \"item/spawn\", {count:1,time:10,input:[{item:1,count:8}],built_by:[\"Engineering\"]}, [{snap_y:true,offset:{x:0,y:0.5},bounds:{x:1,y:2},require_blocks:[{x:0,y:-2,block:\"_BUILD_SURFACE\"}],allow_solids:true,image:\"spawn\"}], true)\r\n\r\n\tstatic DOOR = new this(220, \"Door (Packaged)\", \"Buildable. Can be restricted to specific ranks. Press R to rotate.\", false, 0, \"item/door\", {count:1,time:10,input:[{item:1,count:8}],built_by:[\"Engineering\"]}, [{buildDirection:\"HORIZONTAL\",snap_x:true,snap_y:true,offset:{x:0.5,y:0},bounds:{x:2,y:0.45},image:\"door_full\"},{buildDirection:\"VERTICAL\",snap_x:true,snap_y:true,offset:{x:0,y:0.5},bounds:{x:0.45,y:2},image:\"door_full\"}], true)\r\n\r\n\tstatic ITEM_HATCH = new this(221, \"Cargo Hatch (Packaged)\", \"Buildable. Drops items picked up by the ship.\", false, 0, \"item/item_hatch\", {count:1,time:10,input:[{item:1,count:8}],built_by:[\"Engineering\"]}, [{snap_x:true,snap_y:true,bounds:{x:1,y:1},allow_solids:true}])\r\n\r\n\tstatic ITEM_HATCH_STARTER = new this(222, \"Cargo Hatch (Starter, Packaged)\", \"Buildable Starter Item. Drops items picked up by the ship.\", false, -1, \"item/item_hatch_starter\", undefined, [{snap_x:true,snap_y:true,bounds:{x:1,y:1},allow_solids:true}])\r\n\r\n\tstatic ITEM_EJECTOR = new this(223, \"Cargo Ejector (Packaged)\", \"Buildable. Ejects items from the ship.\", false, 0, \"item/item_ejector\", {count:1,time:10,input:[{item:1,count:8}],built_by:[\"Engineering\"]}, [{buildDirection:\"HORIZONTAL\",snap_x:true,snap_y:true,bounds:{x:2.8,y:0.8},require_blocks:[{x:0,y:0,block:\"HULL_H\"},{x:1,y:0,block:\"HULL_H\"},{x:-1,y:0,block:\"HULL_H\"}],allow_world:true},{buildDirection:\"VERTICAL\",snap_x:true,snap_y:true,bounds:{x:0.8,y:2.8},require_blocks:[{x:0,y:0,block:\"HULL_V\"},{x:0,y:1,block:\"HULL_V\"},{x:0,y:-1,block:\"HULL_V\"}],allow_world:true},{snap_x:true,snap_y:true,bounds:{x:1,y:1},build_angle:\"Fixed\",image:\"arrow_shape\",image_only:true}])\r\n\r\n\tstatic TURRET_CONTROLLER = new this(224, \"Turret Controller (Packaged)\", \"Buildable. Controls adjacent turrets.\", false, 0, \"item/turret_controller\", {count:1,time:10,input:[{item:1,count:8}],built_by:[\"Engineering\"]}, [{buildDirection:\"HORIZONTAL\",snap_x:true,snap_y:true,bounds:{x:2.8,y:0.8},require_blocks:[{x:0,y:0,block:\"HULL_H\"},{x:1,y:0,block:\"HULL_H\"},{x:-1,y:0,block:\"HULL_H\"}],allow_world:true},{buildDirection:\"VERTICAL\",snap_x:true,snap_y:true,bounds:{x:0.8,y:2.8},require_blocks:[{x:0,y:0,block:\"HULL_V\"},{x:0,y:1,block:\"HULL_V\"},{x:0,y:-1,block:\"HULL_V\"}],allow_world:true}])\r\n\r\n\tstatic TURRET_REMOTE = new this(226, \"Cannon (Packaged)\", \"Buildable. A normal cannon that you can use to shoot at stuff.\", false, 1, \"item/turret_rc\", undefined, [{buildDirection:\"HORIZONTAL\",snap_x:true,snap_y:true,bounds:{x:2.8,y:0.8},require_blocks:[{x:0,y:0,block:\"HULL_H\"},{x:1,y:0,block:\"HULL_H\"},{x:-1,y:0,block:\"HULL_H\"}],allow_world:true},{buildDirection:\"VERTICAL\",snap_x:true,snap_y:true,bounds:{x:0.8,y:2.8},require_blocks:[{x:0,y:0,block:\"HULL_V\"},{x:0,y:1,block:\"HULL_V\"},{x:0,y:-1,block:\"HULL_V\"}],allow_world:true}])\r\n\r\n\tstatic TURRET_REMOTE_STARTER = new this(227, \"Starter Cannon (Packaged)\", \"Buildable Starter Item. Slowly re-generates ammo when empty.\", false, -1, \"item/turret_rc_starter\", undefined, [{buildDirection:\"HORIZONTAL\",snap_x:true,snap_y:true,bounds:{x:2.8,y:0.8},require_blocks:[{x:0,y:0,block:\"HULL_H\"},{x:1,y:0,block:\"HULL_H\"},{x:-1,y:0,block:\"HULL_H\"}],allow_world:true},{buildDirection:\"VERTICAL\",snap_x:true,snap_y:true,bounds:{x:0.8,y:2.8},require_blocks:[{x:0,y:0,block:\"HULL_V\"},{x:0,y:1,block:\"HULL_V\"},{x:0,y:-1,block:\"HULL_V\"}],allow_world:true}])\r\n\r\n\tstatic TURRET_BURST = new this(228, \"Burst Cannon (Packaged)\", \"Buildable. Fires a burst of shots when supplied with burst charges. May damage itself.\", false, 1, \"item/turret_burst\", undefined, [{buildDirection:\"HORIZONTAL\",snap_x:true,snap_y:true,bounds:{x:2.8,y:0.8},require_blocks:[{x:0,y:0,block:\"HULL_H\"},{x:1,y:0,block:\"HULL_H\"},{x:-1,y:0,block:\"HULL_H\"}],allow_world:true},{buildDirection:\"VERTICAL\",snap_x:true,snap_y:true,bounds:{x:0.8,y:2.8},require_blocks:[{x:0,y:0,block:\"HULL_V\"},{x:0,y:1,block:\"HULL_V\"},{x:0,y:-1,block:\"HULL_V\"}],allow_world:true}])\r\n\r\n\tstatic TURRET_AUTO = new this(229, \"Machine Cannon (Packaged)\", \"Buildable. A fully automatic gun that takes time to wind up. Requires cooling.\", false, 1, \"item/turret_auto\", undefined, [{buildDirection:\"HORIZONTAL\",snap_x:true,snap_y:true,bounds:{x:2.8,y:0.8},require_blocks:[{x:0,y:0,block:\"HULL_H\"},{x:1,y:0,block:\"HULL_H\"},{x:-1,y:0,block:\"HULL_H\"}],allow_world:true},{buildDirection:\"VERTICAL\",snap_x:true,snap_y:true,bounds:{x:0.8,y:2.8},require_blocks:[{x:0,y:0,block:\"HULL_V\"},{x:0,y:1,block:\"HULL_V\"},{x:0,y:-1,block:\"HULL_V\"}],allow_world:true}])\r\n\r\n\tstatic THRUSTER = new this(230, \"Thruster (Packaged)\", \"Buildable. Moves your ship. Fuelled with explosives.\", false, 0, \"item/thruster\", {count:1,time:10,input:[{item:1,count:8}],built_by:[\"Engineering\"]}, [{buildDirection:\"HORIZONTAL\",snap_x:true,snap_y:true,bounds:{x:2.8,y:0.8},require_blocks:[{x:0,y:0,block:\"HULL_H\"},{x:1,y:0,block:\"HULL_H\"},{x:-1,y:0,block:\"HULL_H\"}],allow_world:true},{buildDirection:\"VERTICAL\",snap_x:true,snap_y:true,bounds:{x:0.8,y:2.8},require_blocks:[{x:0,y:0,block:\"HULL_V\"},{x:0,y:1,block:\"HULL_V\"},{x:0,y:-1,block:\"HULL_V\"}],allow_world:true}])\r\n\r\n\tstatic THRUSTER_STARTER = new this(231, \"Thruster (Starter, Packaged)\", \"Buildable Starter Item. Moves your ship. Doesn't need fuel.\", false, -1, \"item/thruster_starter\", undefined, [{snap_x:true,snap_y:true,bounds:{x:0.8,y:0.8},require_blocks:[{x:0,y:0,block:\"HULL_CORNER\"}],allow_world:true}])\r\n\r\n\tstatic BLOCK = new this(232, \"Iron Block\", \"Buildable. Used for interior walls/floors.\", true, 0, \"item/block\", {count:1,time:1,input:[{item:1,count:2}],built_by:[\"Starter\",\"Engineering\"]}, [{snap_x:true,snap_y:true,bounds:{x:1,y:1},block:4,block_shaped:true}])\r\n\r\n\tstatic BLOCK_HYPER_RUBBER = new this(233, \"Hyper Rubber Block\", \"Buildable. Bouncy.\", true, 2, \"item/block_hrubber\", {count:1,time:1,input:[{item:4,count:2}],built_by:[\"Engineering\"]}, [{snap_x:true,snap_y:true,bounds:{x:1,y:1},block:13,block_shaped:true}])\r\n\r\n\tstatic BLOCK_ICE_GLASS = new this(234, \"Hyper Ice Block\", \"Buildable. Low-friction ice that can't melt for some reason.\", true, 0, \"item/block_sglass\", undefined, [{snap_x:true,snap_y:true,bounds:{x:1,y:1},block:14,block_shaped:true}])\r\n\r\n\tstatic BLOCK_LADDER = new this(235, \"Ladder\", \"Buildable. You can climb them.\", true, 0, \"item/ladder\", {count:1,time:1,input:[{item:1,count:2}],built_by:[\"Starter\",\"Engineering\"]}, [{snap_x:true,snap_y:true,bounds:{x:1,y:1},block:5}])\r\n\r\n\tstatic BLOCK_WALKWAY = new this(236, \"Walkway\", \"Buildable. Blocks players but not items.\", true, 0, \"item/walkway\", {count:1,time:1,input:[{item:1,count:2}],built_by:[\"Engineering\"]}, [{snap_x:true,snap_y:true,bounds:{x:1,y:1},block:6,block_shaped:true}])\r\n\r\n\tstatic BLOCK_ITEM_NET = new this(237, \"Item Net\", \"Buildable. Blocks items but not players.\", true, 0, \"item/item_net\", {count:1,time:1,input:[{item:1,count:2}],built_by:[\"Engineering\"]}, [{snap_x:true,snap_y:true,bounds:{x:1,y:1},block:7,block_shaped:true}])\r\n\r\n\tstatic PAINT = new this(239, \"Paint\", \"Used to paint your ship's background. Hold R to select color.\", true, 0, \"item/color_panel\", {count:1,time:1,input:[{item:1,count:2}],built_by:[\"Engineering\"]}, [{snap_x:true,snap_y:true,bounds:{x:1,y:1},block_is_colored:true,allow_world:true,allow_any:true}], true)\r\n\r\n\tstatic EXPANDO_BOX = new this(240, \"Expando Box (Packaged)\", \"Buildable. Flexible bulk storage.\", false, 0, \"item/exbox\", {count:1,time:10,input:[{item:1,count:8}],built_by:[\"Engineering\"]}, [{bounds:{x:2,y:2},shape:{verts:[{x:-0.95,y:-0.75},{x:-0.75,y:-0.95},{x:0.75,y:-0.95},{x:0.95,y:-0.75},{x:0.95,y:0.75},{x:0.75,y:0.95},{x:-0.75,y:0.95},{x:-0.95,y:0.75}]},allow_non_solids:true,build_angle:\"Any\",image:\"exbox_base\",image_only:true}])\r\n\r\n\tstatic FREEPORT_ANCHOR = new this(241, \"Safety Anchor\", \"Buildable. Prevents teleports out of safe zones while placed.\", false, 0, \"item/anchor\", {count:1,time:20,input:[{item:1,count:16}],built_by:[\"Engineering\"]}, [{bounds:{x:3,y:3},snap_x:true,snap_y:true,image:\"anchor\"}])\r\n\r\n\tstatic PUSHER = new this(242, \"Pusher (Packaged)\", \"Buildable. Pushes things.\", false, 2, \"item/pusher\", {count:1,time:10,input:[{item:1,count:8},{item:5,count:4}],built_by:[\"Engineering\"]}, [{snap_x:true,snap_y:true,bounds:{x:1,y:1},image:\"loader_base\",image_anim:\"pusher\",image_only:true}])\r\n\r\n\tstatic ITEM_LAUNCHER = new this(243, \"Item Launcher (Packaged)\", \"Buildable. Launches items at a configurable speed and angle.\", false, 2, \"item/item_launcher\", {count:1,time:10,input:[{item:1,count:8},{item:4,count:8},{item:5,count:8}],built_by:[\"Engineering\"]}, [{snap_x:true,snap_y:true,bounds:{x:1,y:1},image:\"item_launcher\",image_only:true}], true)\r\n\r\n\tstatic LOADER = new this(244, \"DEPRECATED ITEM\", \"DEPRECATED ITEM\", false, 2, \"item/loader_old\")\r\n\r\n\tstatic RECYCLER = new this(245, \"Recycler (Packaged)\", \"Buildable. Converts items back into resources.\", false, 0, \"item/recycler\", {count:1,time:10,input:[{item:1,count:8}],built_by:[\"Engineering\"]}, [{snap_y:true,offset:{x:0,y:0.25},bounds:{x:2.25,y:3.5},require_blocks:[{x:0,y:-2,block:\"_BUILD_SURFACE\"}],allow_solids:true,image:\"recycler\",image_only:true}])\r\n\r\n\tstatic FABRICATOR_GOLD = new this(246, \"Fabricator (Legacy, Packaged)\", \"Buildable. It doesn't do anything.\", false, 9, \"item/fabricator_legacy\", undefined, [{snap_y:true,bounds:{x:2.5,y:3},require_blocks:[{x:0,y:-2,block:\"_BUILD_SURFACE\"}],allow_solids:true,image:\"fab_lod\",image_only:true}], undefined, \"Legacy\")\r\n\r\n\tstatic FABRICATOR_STARTER = new this(247, \"Fabricator (Starter, Packaged)\", \"Buildable Starter Item. Used to craft basic items.\", false, -1, \"item/fabricator_starter\", undefined, [{snap_y:true,bounds:{x:2.5,y:3},require_blocks:[{x:0,y:-2,block:\"_BUILD_SURFACE\"}],allow_solids:true,image:\"fab_lod\",image_only:true}], undefined, \"Starter\")\r\n\r\n\tstatic FABRICATOR_MUNITIONS = new this(248, \"Fabricator (Munitions, Packaged)\", \"Buildable. Used to craft ammo and other consumables.\", false, 0, \"item/fabricator_munitions\", {count:1,time:20,input:[{item:1,count:16}],built_by:[\"Starter\",\"Engineering\"]}, [{snap_y:true,bounds:{x:2.5,y:3},require_blocks:[{x:0,y:-2,block:\"_BUILD_SURFACE\"}],allow_solids:true,image:\"fab_lod\",image_only:true}], undefined, \"Munitions\")\r\n\r\n\tstatic FABRICATOR_ENGINEERING = new this(249, \"Fabricator (Engineering, Packaged)\", \"Buildable. Used to craft tools, blocks, and security items.\", false, 0, \"item/fabricator_engineering\", {count:1,time:20,input:[{item:1,count:16}],built_by:[\"Starter\",\"Engineering\"]}, [{snap_y:true,bounds:{x:2.5,y:3},require_blocks:[{x:0,y:-2,block:\"_BUILD_SURFACE\"}],allow_solids:true,image:\"fab_lod\",image_only:true}], undefined, \"Engineering\")\r\n\r\n\tstatic FABRICATOR_MACHINE_DEPRECATED = new this(250, \"Fabricator (DEPRECATED, Packaged)\", \"DEPRECATED ITEM\", false, 0, \"item/fabricator_machine\", {count:1,time:20,input:[{item:1,count:16}],built_by:[]}, [{snap_y:true,bounds:{x:2.5,y:3},require_blocks:[{x:0,y:-2,block:\"_BUILD_SURFACE\"}],allow_solids:true,image:\"fab_lod\",image_only:true}], undefined, \"Engineering\")\r\n\r\n\tstatic FABRICATOR_EQUIPMENT = new this(251, \"Fabricator (Equipment, Packaged)\", \"Buildable. Used to craft wearable equipment.\", false, 0, \"item/fabricator_equipment\", {count:1,time:20,input:[{item:1,count:16}],built_by:[\"Engineering\"]}, [{snap_y:true,bounds:{x:2.5,y:3},require_blocks:[{x:0,y:-2,block:\"_BUILD_SURFACE\"}],allow_solids:true,image:\"fab_lod\",image_only:true}], undefined, \"Equipment\")\r\n\r\n\tstatic LOADER_NEW = new this(252, \"Loader (Packaged)\", \"Buildable. Loads items into machines.\", false, 2, \"item/loader\", {count:1,time:10,input:[{item:1,count:8},{item:5,count:2}],built_by:[\"Engineering\"]}, [{snap_x:true,snap_y:true,bounds:{x:1,y:1},image:\"loader_base\",image_anim:\"loader\",image_only:true}])\r\n\r\n\tstatic LOCKDOWN_OVERRIDE_GREEN = new this(253, \"Lockdown Override Unit\", \"Buildable. Allows a limited number of green rarity items to be removed from a ship while in lockdown mode.\", false, 2, \"item/lockdown_override_green\", {count:1,time:20,input:[{item:5,count:64}],built_by:[\"Engineering\"]}, [{bounds:{x:1,y:1},snap_x:true,snap_y:true,image:\"lockdown_override_green\",is_lockdown_override:true}], true)\r\n\r\n\tstatic BLOCK_ANNIHILATOR = new this(254, \"Annihilator Tile\", \"[TEST EXCLUSIVE] Buildable. Destroys objects.\", true, 0, \"item/annihilator_tile\", undefined, [{snap_x:true,snap_y:true,bounds:{x:1,y:1},block:15}])\r\n\r\n\tstatic FLUID_TANK = new this(255, \"Fluid Tank\", \"Buildable. Stores fluids.\", false, 0, \"item/tank\", {count:1,time:20,input:[{item:1,count:64}],built_by:[\"Engineering\"]}, [{bounds:{x:2,y:2},snap_x:true,snap_y:true,offset:{x:0.5,y:0.5},offset2:{x:-0.5,y:-0.5},image:\"tank\"}])\r\n\r\n\tstatic SHIELD_GENERATOR = new this(256, \"Shield Generator\", \"Buildable. Generates shield fluid.\", false, 2, \"item/shield_generator\", undefined, [{bounds:{x:4,y:2},snap_x:true,snap_y:true,offset:{x:0.5,y:0.5},offset2:{x:-0.5,y:-0.5},image:\"shield_generator\",build_angle:\"Fixed\",image_only:true}])\r\n\r\n\tstatic SHIELD_PROJECTOR = new this(257, \"Shield Projector\", \"Buildable. Used to activate an adjacent bank of shield tanks.\", false, 2, \"item/shield_projector\", undefined, [{bounds:{x:1,y:1},snap_x:true,snap_y:true,image:\"shield_projector_1\"}])\r\n\r\n\tstatic TURRET_CONTROLLER_NEW = new this(258, \"Enhanced Turret Controller\", \"Buildable. Used to control turrets remotely.\", false, 2, \"item/turret_controller_new\", undefined, [{bounds:{x:1,y:1},snap_x:true,snap_y:true}])\r\n\r\n\tstatic BULK_EJECTOR = new this(259, \"Bulk Ejector (Packaged)\", \"Buildable. WIP / UNOBTAINABLE\", false, 2, \"item/bulk_ejector\", undefined, [{bounds:{x:2,y:2},snap_x:true,snap_y:true,offset:{x:0.5,y:0.5},offset2:{x:-0.5,y:-0.5},build_angle:\"Fixed\"}])\r\n\r\n\tstatic BULK_BAY_MARKER = new this(260, \"Bulk Loading Bay Designator (Packaged)\", \"Buildable. WIP / UNOBTAINABLE\", false, 2, \"item/bulk_bay_marker\", undefined, [{bounds:{x:1,y:1},snap_x:true,snap_y:true}])\r\n\r\n\tstatic NAV_UNIT = new this(261, \"Navigation Unit (Starter, Packaged)\", \"Buildable Starter Item. Used to select a destination zone and initiate emergency warps. Also functions as a simple shield projector.\", false, -1, \"item/nav_unit\", undefined, [{bounds:{x:1,y:1},snap_x:true,snap_y:true}])\r\n\r\n\tstatic BLOCK_LOGISTICS_RAIL = new this(262, \"Logistics Rail\", \"Buildable. Used by munitions supply units to deliver munitions.\", true, 0, \"item/logistics_rail\", {count:1,time:1,input:[{item:1,count:2}],built_by:[\"Engineering\"]}, [{snap_x:true,snap_y:true,bounds:{x:1,y:1},block:16}])\r\n\r\n\tstatic TURRET_ACUTE = new this(263, \"Acute Cannon (Packaged)\", \"Buildable. A gun with a limited firing angle, and a slightly improved fire-rate.\", false, 1, \"item/turret_acute\", undefined, [{buildDirection:\"HORIZONTAL\",snap_x:true,snap_y:true,bounds:{x:2.8,y:0.8},require_blocks:[{x:0,y:0,block:\"HULL_H\"},{x:1,y:0,block:\"HULL_H\"},{x:-1,y:0,block:\"HULL_H\"}],allow_world:true},{buildDirection:\"VERTICAL\",snap_x:true,snap_y:true,bounds:{x:0.8,y:2.8},require_blocks:[{x:0,y:0,block:\"HULL_V\"},{x:0,y:1,block:\"HULL_V\"},{x:0,y:-1,block:\"HULL_V\"}],allow_world:true}])\r\n\r\n\tstatic MUNITIONS_SUPPLY_UNIT = new this(264, \"Munitions Supply Unit (Packaged)\", \"Buildable. Sends munitions to turrets via logistics rails.\", false, 1, \"item/msu\", undefined, [{bounds:{x:2,y:2},snap_x:true,snap_y:true,offset:{x:0.5,y:0.5},offset2:{x:-0.5,y:-0.5}}])\r\n\r\n\tstatic TURRET_OBTUSE = new this(265, \"Obtuse Cannon (Packaged)\", \"Buildable. A gun which preserves ammo, and has a slightly reduced fire-rate.\", false, 1, \"item/turret_obtuse\", undefined, [{buildDirection:\"HORIZONTAL\",snap_x:true,snap_y:true,bounds:{x:2.8,y:0.8},require_blocks:[{x:0,y:0,block:\"HULL_H\"},{x:1,y:0,block:\"HULL_H\"},{x:-1,y:0,block:\"HULL_H\"}],allow_world:true},{buildDirection:\"VERTICAL\",snap_x:true,snap_y:true,bounds:{x:0.8,y:2.8},require_blocks:[{x:0,y:0,block:\"HULL_V\"},{x:0,y:1,block:\"HULL_V\"},{x:0,y:-1,block:\"HULL_V\"}],allow_world:true}])\r\n\r\n\tstatic ETERNAL_WRENCH_BRONZE = new this(300, \"Eternal Bronze Wrench\", \"Patron reward. Will not despawn. Thank you for your support! \uD83D\uDE00\", false, -1, \"item/wrench_bronze_et\")\r\n\r\n\tstatic ETERNAL_WRENCH_SILVER = new this(301, \"Eternal Silver Wrench\", \"Patron reward. Will not despawn. Thank you for your support! \uD83D\uDE00\", false, -1, \"item/wrench_silver_et\")\r\n\r\n\tstatic ETERNAL_WRENCH_GOLD = new this(302, \"Eternal Gold Wrench\", \"Patron reward. Will not despawn. Thank you for your support! \uD83D\uDE00\", false, -1, \"item/wrench_gold_et\")\r\n\r\n\tstatic ETERNAL_WRENCH_FLUX = new this(303, \"Eternal Flux Wrench\", \"Patron reward. Will not despawn. Thank you for your support! \uD83D\uDE00\", false, -1, \"item/wrench_flux_et\")\r\n\r\n\tstatic ETERNAL_WRENCH_PLATINUM = new this(304, \"Eternal Platinum Wrench\", \"Patron reward. Will not despawn. Thank you for your support! \uD83D\uDE00\", false, -1, \"item/wrench_platinum_et\")\r\n\r\n\tstatic TROPHY_NULL = new this(305, \"Gold Null Trophy\", \"RIP 0x items.\", false, 9, \"item/trophy_null\")\r\n\r\n\tstatic TROPHY_BUG_HUNTER = new this(306, \"Bug Hunter Trophy\", \"Rewarded for reporting a serious problem.\", false, -1, \"item/trophy_bug\")\r\n\r\n\tstatic TROPHY_NULL_SILVER = new this(307, \"Silver Null Trophy\", \"RIP 0x items.\", false, 9, \"item/trophy_null_silver\")\r\n\r\n\tstatic PAT_WRENCH_BRONZE = new this(308, \"Bronze Wrench\", \"Patron reward. Thank you for your support! \uD83D\uDE00\", false, 0, \"item/wrench_bronze\", {count:1,time:5,input:[{item:1,count:4}],built_by:[\"Starter\",\"Engineering\"]})\r\n\r\n\tstatic PAT_WRENCH_SILVER = new this(309, \"Silver Wrench\", \"Patron reward. Thank you for your support! \uD83D\uDE00\", false, 0, \"item/wrench_silver\", {count:1,time:5,input:[{item:1,count:4}],built_by:[\"Starter\",\"Engineering\"]})\r\n\r\n\tstatic PAT_WRENCH_GOLD = new this(310, \"Gold Wrench\", \"Patron reward. Thank you for your support! \uD83D\uDE00\", false, 0, \"item/wrench_gold\", {count:1,time:5,input:[{item:1,count:4}],built_by:[\"Starter\",\"Engineering\"]})\r\n\r\n\tstatic PAT_WRENCH_PLATINUM = new this(311, \"Platinum Wrench\", \"Patron reward. Thank you for your support! \uD83D\uDE00\", false, 0, \"item/wrench_platinum\", {count:1,time:5,input:[{item:1,count:4}],built_by:[\"Starter\",\"Engineering\"]})\r\n\r\n\tstatic PAT_WRENCH_FLUX = new this(312, \"Flux Wrench\", \"Patron reward. Thank you for your support! \uD83D\uDE00\", false, 0, \"item/wrench_flux\", {count:1,time:5,input:[{item:1,count:4}],built_by:[\"Starter\",\"Engineering\"]})\r\n\r\n\tstatic COS_LESSER_CAP = new this(313, \"Lesser Cap\", \"Cosmetic Equipment (Head). Patron reward.\", false, 0, \"item/cap\", {count:1,time:5,input:[{item:1,count:4}],built_by:[\"Equipment\"]})\r\n\r\n\tstatic COS_GOOFY_GLASSES = new this(314, \"Goofy Glasses\", \"Cosmetic Equipment (Face). Patron reward.\", false, 0, \"item/glasses\", {count:1,time:5,input:[{item:1,count:4}],built_by:[\"Equipment\"]})\r\n\r\n\tstatic COS_SHADES = new this(315, \"Shades\", \"Cosmetic Equipment (Face). Patron reward.\", false, 0, \"item/shades\", {count:1,time:5,input:[{item:1,count:4}],built_by:[\"Equipment\"]})\r\n\r\n\tstatic COS_TOP_HAT = new this(316, \"Top Hat\", \"Cosmetic Equipment (Head). Patron reward.\", false, 0, \"item/top_hat\", {count:1,time:5,input:[{item:1,count:4}],built_by:[\"Equipment\"]})\r\n\r\n\tstatic COS_HORNS = new this(317, \"Demon Horns\", \"Cosmetic Equipment (Head). Patron reward.\", false, 0, \"item/horns\", {count:1,time:5,input:[{item:1,count:4}],built_by:[\"Equipment\"]})\r\n\r\n\tstatic COS_MASK_ALIEN = new this(318, \"Alien Mask\", \"Cosmetic Equipment (Face). Patron reward.\", false, 0, \"item/mask_alien\", {count:1,time:5,input:[{item:1,count:4}],built_by:[\"Equipment\"]})\r\n\r\n\tstatic COS_MASK_CLOWN = new this(319, \"Clown Mask\", \"Cosmetic Equipment (Face). Patron reward.\", false, 0, \"item/mask_clown\", {count:1,time:5,input:[{item:1,count:4}],built_by:[\"Equipment\"]})\r\n\r\n\tstatic COS_MASK_GOBLIN = new this(320, \"Goblin Mask\", \"Cosmetic Equipment (Face). Patron reward.\", false, 0, \"item/mask_goblin\", {count:1,time:5,input:[{item:1,count:4}],built_by:[\"Equipment\"]})\r\n\r\n\tstatic COS_PUMPKIN = new this(321, \"Pumpkin\", \"Cosmetic Equipment (Face). Patron reward.\", false, 0, \"item/mask_pumpkin\", {count:1,time:5,input:[{item:1,count:4}],built_by:[\"Equipment\"]})\r\n\r\n\tstatic COS_WITCH_HAT = new this(322, \"Witch Hat\", \"Cosmetic Equipment (Head). Patron reward.\", false, 0, \"item/witch_hat\", {count:1,time:5,input:[{item:1,count:4}],built_by:[\"Equipment\"]})\r\n\r\n\tstatic GREMLIN_RED = new this(323, \"Wild Gremlin (Red)\", \"It looks upset.\", false, 0, \"item/gremlin_red\")\r\n\r\n\tstatic GREMLIN_ORANGE = new this(324, \"Wild Gremlin (Orange)\", \"It looks upset.\", false, 0, \"item/gremlin_orange\")\r\n\r\n\tstatic GREMLIN_YELLOW = new this(325, \"Wild Gremlin (Yellow)\", \"It looks upset.\", false, 0, \"item/gremlin_yellow\")\r\n\r\n\tstatic ELIMINATION_LOOT_BOX = new this(326, \"Elimination Loot Box\", \"Recycle in a safe zone to unbox.\", true, 2, \"item/loot_box\")\r\n\r\n\tstatic ELIMINATION_LOOT_BOX_LOCKED = new this(327, \"Elimination Loot Box (Locked)\", \"Recycle in a safe zone to unbox.\", true, 2, \"item/loot_box_locked\")\r\n\tstatic { this.end() }\r\n}\r\n", "/* eslint-disable no-irregular-whitespace */\r\nimport { Enum } from \"./Enum.js\"\r\n\r\n/**\r\n * The shape names and vertices are taken directly from the game source. The names may not be\r\n * descriptive, but you don't usually need to refer to them by name. Additionally, the constants\r\n * have a comment that visually represents the shape with braille ascii art, generated from the vertices.\r\n *\r\n * The {@link vertices} are sorted to prevent them from overlapping.\r\n *\r\n * <small>Generated using test.drednot.io version: `Sat Nov 2 23:16:10 MDT 2024 / 07f2ca2`</small>\r\n */\r\nexport class Shape extends Enum<number> {\r\n\tconstructor(v: number, readonly vertices: { x: number, y: number }[]) {\r\n\t\tsuper(v)\r\n\t}\r\n\r\n\tget isBuildSurface() { return Shape.buildSurfaceShapes.has(this) }\r\n\r\n\tstatic BLOCK = new this(0, [{x:-0.5,y:-0.5},{x:0.5,y:-0.5},{x:0.5,y:0.5},{x:-0.5,y:0.5}])\r\n\r\n\tstatic RAMP_UR = new this(1, [{x:-0.5,y:-0.5},{x:0.5,y:-0.5},{x:-0.5,y:0.5}])\r\n\r\n\tstatic RAMP_DR = new this(2, [{x:-0.5,y:-0.5},{x:0.5,y:0.5},{x:-0.5,y:0.5}])\r\n\r\n\tstatic RAMP_DL = new this(3, [{x:0.5,y:-0.5},{x:0.5,y:0.5},{x:-0.5,y:0.5}])\r\n\r\n\tstatic RAMP_UL = new this(4, [{x:-0.5,y:-0.5},{x:0.5,y:-0.5},{x:0.5,y:0.5}])\r\n\r\n\tstatic SLAB_U = new this(5, [{x:-0.5,y:-0.5},{x:0.5,y:-0.5},{x:0.5,y:0},{x:-0.5,y:0}])\r\n\r\n\tstatic SLAB_R = new this(6, [{x:-0.5,y:-0.5},{x:0,y:-0.5},{x:0,y:0.5},{x:-0.5,y:0.5}])\r\n\r\n\tstatic SLAB_D = new this(7, [{x:-0.5,y:0},{x:0.5,y:0},{x:0.5,y:0.5},{x:-0.5,y:0.5}])\r\n\r\n\tstatic SLAB_L = new this(8, [{x:0,y:-0.5},{x:0.5,y:-0.5},{x:0.5,y:0.5},{x:0,y:0.5}])\r\n\r\n\tstatic HALF_RAMP_1_U = new this(9, [{x:-0.5,y:-0.5},{x:0.5,y:-0.5},{x:-0.5,y:0}])\r\n\r\n\tstatic HALF_RAMP_1_R = new this(10, [{x:-0.5,y:-0.5},{x:0,y:0.5},{x:-0.5,y:0.5}])\r\n\r\n\tstatic HALF_RAMP_1_D = new this(11, [{x:0.5,y:0},{x:0.5,y:0.5},{x:-0.5,y:0.5}])\r\n\r\n\tstatic HALF_RAMP_1_L = new this(12, [{x:0,y:-0.5},{x:0.5,y:-0.5},{x:0.5,y:0.5}])\r\n\r\n\tstatic HALF_RAMP_2_U = new this(13, [{x:-0.5,y:-0.5},{x:0.5,y:-0.5},{x:0.5,y:0},{x:-0.5,y:0.5}])\r\n\r\n\tstatic HALF_RAMP_2_R = new this(14, [{x:-0.5,y:-0.5},{x:0,y:-0.5},{x:0.5,y:0.5},{x:-0.5,y:0.5}])\r\n\r\n\tstatic HALF_RAMP_2_D = new this(15, [{x:-0.5,y:0},{x:0.5,y:-0.5},{x:0.5,y:0.5},{x:-0.5,y:0.5}])\r\n\r\n\tstatic HALF_RAMP_2_L = new this(16, [{x:-0.5,y:-0.5},{x:0.5,y:-0.5},{x:0.5,y:0.5},{x:0,y:0.5}])\r\n\r\n\tstatic HALF_RAMP_1_UI = new this(17, [{x:-0.5,y:-0.5},{x:0.5,y:-0.5},{x:0.5,y:0}])\r\n\r\n\tstatic HALF_RAMP_1_RI = new this(18, [{x:-0.5,y:-0.5},{x:0,y:-0.5},{x:-0.5,y:0.5}])\r\n\r\n\tstatic HALF_RAMP_1_DI = new this(19, [{x:-0.5,y:0},{x:0.5,y:0.5},{x:-0.5,y:0.5}])\r\n\r\n\tstatic HALF_RAMP_1_LI = new this(20, [{x:0.5,y:-0.5},{x:0.5,y:0.5},{x:0,y:0.5}])\r\n\r\n\tstatic HALF_RAMP_2_UI = new this(21, [{x:-0.5,y:-0.5},{x:0.5,y:-0.5},{x:0.5,y:0.5},{x:-0.5,y:0}])\r\n\r\n\tstatic HALF_RAMP_2_RI = new this(22, [{x:-0.5,y:-0.5},{x:0.5,y:-0.5},{x:0,y:0.5},{x:-0.5,y:0.5}])\r\n\r\n\tstatic HALF_RAMP_2_DI = new this(23, [{x:-0.5,y:-0.5},{x:0.5,y:0},{x:0.5,y:0.5},{x:-0.5,y:0.5}])\r\n\r\n\tstatic HALF_RAMP_2_LI = new this(24, [{x:0,y:-0.5},{x:0.5,y:-0.5},{x:0.5,y:0.5},{x:-0.5,y:0.5}])\r\n\r\n\tstatic HALF_RAMP_3_U = new this(25, [{x:-0.5,y:0},{x:0.5,y:0},{x:-0.5,y:0.5}])\r\n\r\n\tstatic HALF_RAMP_3_R = new this(26, [{x:0,y:-0.5},{x:0.5,y:0.5},{x:0,y:0.5}])\r\n\r\n\tstatic HALF_RAMP_3_D = n