From bf2d5f333cba4f53154cf16e96c495aaa0411afc Mon Sep 17 00:00:00 2001 From: Exund Date: Sat, 12 Sep 2020 22:11:25 +0200 Subject: [PATCH] Custom wire processor + building variants fixes --- src/js/GeoZ/main.js | 19 ++- src/js/GeoZ/mod_wireprocessor.js | 24 +++ src/js/GeoZ/mods/test/test.mod.js | 238 +++++++++++++++++++++++++++++- src/js/game/systems/logic_gate.js | 6 + 4 files changed, 282 insertions(+), 5 deletions(-) create mode 100644 src/js/GeoZ/mod_wireprocessor.js diff --git a/src/js/GeoZ/main.js b/src/js/GeoZ/main.js index 8e4069e2..d7e8f617 100644 --- a/src/js/GeoZ/main.js +++ b/src/js/GeoZ/main.js @@ -1,9 +1,13 @@ +//Mod imports import { MetaModBuilding } from "./mod_building"; import { ModComponent } from "./mod_component"; import { ModItem } from "./mod_item"; import { ModProcessor } from "./mod_processor"; +import { ModWireProcessor } from "./mod_wireprocessor"; import { ModSystem, ModSystemWithFilter } from "./mod_system"; import { keyCodeOf } from "./mod_utils"; + +//Game imports import { gComponentRegistry, gItemRegistry, gMetaBuildingRegistry } from "../core/global_registries"; import { GameSystemManager } from "../game/game_system_manager"; import { GameCore } from "../game/core"; @@ -19,6 +23,7 @@ export { MetaModBuilding } from "./mod_building"; export { ModComponent } from "./mod_component"; export { ModItem } from "./mod_item"; export { ModProcessor } from "./mod_processor"; +export { ModWireProcessor } from "./mod_wireprocessor"; export { ModSystem, ModSystemWithFilter } from "./mod_system"; /** @@ -28,6 +33,7 @@ export { ModSystem, ModSystemWithFilter } from "./mod_system"; * @property {Array=} components * @property {Array=} items * @property {Array=} processors + * @property {Array=} wireProcessors * @property {Array=} systems * @property {Array=} shapes */ @@ -46,6 +52,9 @@ export const ModSystems = []; /** @type {Object.} */ export const ModProcessors = {}; +/** @type {Object.} */ +export const ModWireProcessors = {}; + /** @type {Array} */ export const ModItems = []; @@ -202,6 +211,14 @@ export async function initMods() { } } + if (mod.wireProcessors) { + mod_infos += `${mod.wireProcessors.length} wire processors, `; + for (const wireProcessor of mod.wireProcessors) { + const type = wireProcessor.getType(); + ModWireProcessors[type] = wireProcessor; + } + } + if (mod.items) { mod_infos += `${mod.items.length} items, `; for (const item of mod.items) { @@ -219,7 +236,7 @@ export async function initMods() { registerBuildingVariant(base_id, building); for (const variant of building.getVariants()) { - registerBuildingVariant(`${base_id}-${variant}`, building); + registerBuildingVariant(`${base_id}-${variant}`, building, variant); } supportedBuildings.push(building); diff --git a/src/js/GeoZ/mod_wireprocessor.js b/src/js/GeoZ/mod_wireprocessor.js new file mode 100644 index 00000000..690ecda5 --- /dev/null +++ b/src/js/GeoZ/mod_wireprocessor.js @@ -0,0 +1,24 @@ +import { BaseItem } from "../game/base_item"; +import { LogicGateSystem } from "../game/systems/logic_gate"; + +/** + * Custom wire processor (logic gate/virtual processor) + */ +export class ModWireProcessor { + /** + * @returns {String} + */ + static getType() { + return this.prototype.constructor.name; + } + + /** + * @param {Array} parameters + * @param {LogicGateSystem} system + * @returns {Array|BaseItem} + */ + static compute(system, parameters) { + abstract; + return []; + } +} diff --git a/src/js/GeoZ/mods/test/test.mod.js b/src/js/GeoZ/mods/test/test.mod.js index 6d70e3a9..a7c43be0 100644 --- a/src/js/GeoZ/mods/test/test.mod.js +++ b/src/js/GeoZ/mods/test/test.mod.js @@ -7,6 +7,13 @@ import { ShapeDefinition } from "../../../game/shape_definition"; import { ItemProcessorComponent } from "../../../game/components/item_processor"; import { ItemEjectorComponent } from "../../../game/components/item_ejector"; import { ItemAcceptorComponent } from "../../../game/components/item_acceptor"; +import { ModWireProcessor } from "../../mod_wireprocessor"; +import { BaseItem } from "../../../game/base_item"; +import { LogicGateSystem } from "../../../game/systems/logic_gate"; +import { BOOL_FALSE_SINGLETON, BOOL_TRUE_SINGLETON, isTruthyItem } from "../../../game/items/boolean_item"; +import { enumPinSlotType, WiredPinsComponent } from "../../../game/components/wired_pins"; +import { LogicGateComponent } from "../../../game/components/logic_gate"; +import { defaultBuildingVariant } from "../../../game/meta_building"; class MetaTestBuilding extends GeoZ.MetaModBuilding { static getId() { @@ -46,7 +53,8 @@ class MetaTestBuilding extends GeoZ.MetaModBuilding { */ getSpriteMetas() { const normal = { - url: "https://raw.githubusercontent.com/Exund/shapez.io/master/res_raw/sprites/wires/boolean_false.png", + url: + "https://raw.githubusercontent.com/Exund/shapez.io/master/res_raw/sprites/wires/boolean_false.png", width: 64, height: 64, }; @@ -92,9 +100,168 @@ class MetaTestBuilding extends GeoZ.MetaModBuilding { } } +class MetaInvertedGatesBuilding extends GeoZ.MetaModBuilding { + static getId() { + return "NANDGate"; + } + + static getKeybinding() { + return "0"; + } + + static getTranslations() { + return { + variants: { + default: { + name: "NAND Gate", + description: "Test GeoZ building for custom wire processor", + }, + NORGate: { + name: "NOR Gate", + description: "Test GeoZ building for custom wire processor", + }, + XNORGate: { + name: "XNOR Gate", + description: "Test GeoZ building for custom wire processor", + }, + }, + keybinding: "NAND Gate", + }; + } + + static getVariants() { + return ["NORGate", "XNORGate"]; + } + + constructor() { + super("NANDGate"); + } + + getSilhouetteColor() { + return "#89dc60"; + } + + getDimensions() { + return new Vector(1, 1); + } + + getAvailableVariants() { + return [...super.getAvailableVariants(null), ...MetaInvertedGatesBuilding.getVariants()]; + } + + /** + * @returns {Layer} + */ + getLayer() { + return "wires"; + } + + /** + * @returns {import("../../mod_building").BuildingSpriteMetas} + */ + getSpriteMetas() { + return { + default: [ + { + normal: { + url: + "https://raw.githubusercontent.com/Exund/shapez.io/master/res_raw/sprites/buildings/logic_gate.png", + width: 192, + height: 192, + }, + blueprint: { + url: + "https://raw.githubusercontent.com/Exund/shapez.io/master/res_raw/sprites/blueprints/logic_gate.png", + width: 192, + height: 192, + }, + }, + ], + NORGate: [ + { + normal: { + url: + "https://raw.githubusercontent.com/Exund/shapez.io/master/res_raw/sprites/buildings/logic_gate-or.png", + width: 192, + height: 192, + }, + blueprint: { + url: + "https://raw.githubusercontent.com/Exund/shapez.io/master/res_raw/sprites/blueprints/logic_gate-or.png", + width: 192, + height: 192, + }, + }, + ], + XNORGate: [ + { + normal: { + url: + "https://raw.githubusercontent.com/Exund/shapez.io/master/res_raw/sprites/buildings/logic_gate-xor.png", + width: 192, + height: 192, + }, + blueprint: { + url: + "https://raw.githubusercontent.com/Exund/shapez.io/master/res_raw/sprites/blueprints/logic_gate-xor.png", + width: 192, + height: 192, + }, + }, + ], + }; + } + + /** + * @param {Entity} entity + * @param {string} variant + */ + updateVariants(entity, rotationVariant, variant) { + entity.components.LogicGate.type = enumInvertedGatesVariants[variant]; + } + + /** + * Creates the entity at the given location + * @param {Entity} entity + */ + setupEntityComponents(entity) { + entity.addComponent( + new WiredPinsComponent({ + slots: [ + { + pos: new Vector(0, 0), + direction: enumDirection.top, + type: enumPinSlotType.logicalEjector, + }, + { + pos: new Vector(0, 0), + direction: enumDirection.left, + type: enumPinSlotType.logicalAcceptor, + }, + { + pos: new Vector(0, 0), + direction: enumDirection.right, + type: enumPinSlotType.logicalAcceptor, + }, + ], + }) + ); + + entity.addComponent(new LogicGateComponent({ type: NANDGate.getType() })); + } +} + +const enumInvertedGatesVariants = { + [defaultBuildingVariant]: "NANDGate", +}; + +for (const v of MetaInvertedGatesBuilding.getVariants()) { + enumInvertedGatesVariants[v] = v; +} + class SquareConverter extends ModProcessor { /** - * @returns {Number} + * @returns {Number} */ static getBaseSpeed() { return 0.5; @@ -108,14 +275,77 @@ class SquareConverter extends ModProcessor { static process({ outItems }) { outItems.push({ item: new ShapeItem(ShapeDefinition.fromShortKey("SuSuSuSu")) }); return true; - } + } +} + +class NANDGate extends ModWireProcessor { + /** + * @param {Array} parameters + * @param {LogicGateSystem} system + * @returns {Array|BaseItem} + */ + static compute(system, parameters) { + assert(parameters.length === 2, "bad parameter count for NAND"); + return isTruthyItem(parameters[0]) && isTruthyItem(parameters[1]) + ? BOOL_FALSE_SINGLETON + : BOOL_TRUE_SINGLETON; + } +} + +class NORGate extends ModWireProcessor { + /** + * @param {Array} parameters + * @param {LogicGateSystem} system + * @returns {Array|BaseItem} + */ + static compute(system, parameters) { + assert(parameters.length === 2, "bad parameter count for NOR"); + return isTruthyItem(parameters[0]) || isTruthyItem(parameters[1]) + ? BOOL_FALSE_SINGLETON + : BOOL_TRUE_SINGLETON; + } +} + +class XNORGate extends ModWireProcessor { + /** + * @param {Array} parameters + * @param {LogicGateSystem} system + * @returns {Array|BaseItem} + */ + static compute(system, parameters) { + assert(parameters.length === 2, "bad parameter count for XNOR"); + return isTruthyItem(parameters[0]) !== isTruthyItem(parameters[1]) + ? BOOL_FALSE_SINGLETON + : BOOL_TRUE_SINGLETON; + } +} + +class VirtualStacker extends ModWireProcessor { + /** + * @param {Array} parameters + * @param {LogicGateSystem} system + * @returns {Array|BaseItem} + */ + static compute(system, parameters) { + const item1 = parameters[0]; + const item2 = parameters[0]; + if (!item1 || !item2 || item1.getItemType() !== "shape" || item2.getItemType() !== "shape") { + return null; + } + + const definition1 = /** @type {ShapeItem} */ (item1).definition; + const definition2 = /** @type {ShapeItem} */ (item2).definition; + const result = system.root.shapeDefinitionMgr.shapeActionStack(definition1, definition2); + return system.root.shapeDefinitionMgr.getShapeItemFromDefinition(result); + } } /**@type {GeoZ.Mod}*/ const test = { name: "test", - buildings: [MetaTestBuilding], + buildings: [MetaTestBuilding, MetaInvertedGatesBuilding], processors: [SquareConverter], + wireProcessors: [NANDGate, NORGate, XNORGate, VirtualStacker], shapes: [ { id: "leaf", diff --git a/src/js/game/systems/logic_gate.js b/src/js/game/systems/logic_gate.js index 3bfc20cd..a8440418 100644 --- a/src/js/game/systems/logic_gate.js +++ b/src/js/game/systems/logic_gate.js @@ -25,6 +25,12 @@ export class LogicGateSystem extends GameSystemWithFilter { [enumLogicGateType.unstacker]: this.compute_UNSTACK.bind(this), [enumLogicGateType.shapecompare]: this.compute_SHAPECOMPARE.bind(this), }; + + const { ModWireProcessors } = require("../../GeoZ/main"); + for (const type in ModWireProcessors) { + //@ts-ignore + this.boundOperations[type] = ModWireProcessors[type].compute.bind(null, this); + } } update() {