From 388f7888ee9a97659fea0ff59ff8de330cc911e1 Mon Sep 17 00:00:00 2001 From: tobspr Date: Thu, 20 Jan 2022 17:55:53 +0100 Subject: [PATCH 01/14] Prettier fixes --- src/js/mods/modloader.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/js/mods/modloader.js b/src/js/mods/modloader.js index dc64eb6c..96743038 100644 --- a/src/js/mods/modloader.js +++ b/src/js/mods/modloader.js @@ -103,21 +103,17 @@ export class ModLoader { mods = await ipcRenderer.invoke("get-mods"); } if (G_IS_DEV && globalConfig.debug.externalModUrl) { - let modURLs = Array.isArray(globalConfig.debug.externalModUrl) ? - globalConfig.debug.externalModUrl : [globalConfig.debug.externalModUrl]; - - for(let i = 0; i < modURLs.length; i++) { + const modURLs = Array.isArray(globalConfig.debug.externalModUrl) + ? globalConfig.debug.externalModUrl + : [globalConfig.debug.externalModUrl]; + + for (let i = 0; i < modURLs.length; i++) { const response = await fetch(modURLs[i], { method: "GET", }); if (response.status !== 200) { throw new Error( - "Failed to load " + - modURLs[i] + - ": " + - response.status + - " " + - response.statusText + "Failed to load " + modURLs[i] + ": " + response.status + " " + response.statusText ); } mods.push(await response.text()); From 7a1dedd2c8474d137baab070d7b42774ca7ed2bd Mon Sep 17 00:00:00 2001 From: "Thomas (DJ1TJOO)" <44841260+DJ1TJOO@users.noreply.github.com> Date: Thu, 20 Jan 2022 17:56:09 +0100 Subject: [PATCH 02/14] Added link to create-shapezio-mod npm page (#1339) Added link to create-shapezio-mod npm page: https://www.npmjs.com/package/create-shapezio-mod --- mod_examples/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod_examples/README.md b/mod_examples/README.md index 1545a46b..c918a9ed 100644 --- a/mod_examples/README.md +++ b/mod_examples/README.md @@ -5,7 +5,7 @@ Currently there are two options to develop mods for shapez.io: 1. Writing single file mods, which doesn't require any additional tools and can be loaded directly in the game -2. Using the `create-shapezio-mod` package. This package is still in development but allows you to pack multiple files and images into a single mod file, so you don't have to base64 encode your images etc. +2. Using the [create-shapezio-mod](https://www.npmjs.com/package/create-shapezio-mod) package. This package is still in development but allows you to pack multiple files and images into a single mod file, so you don't have to base64 encode your images etc. Since the `create-shapezio-mod` package is still in development, the current recommended way is to write single file mods, which I'll explain now. From 839d2037371c0a9927f612d0f42cacc97c53e68d Mon Sep 17 00:00:00 2001 From: Emerald Block <69981203+EmeraldBlock@users.noreply.github.com> Date: Thu, 20 Jan 2022 10:56:26 -0600 Subject: [PATCH 03/14] allow command line switch to load more than one mod (#1342) --- electron/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/electron/index.js b/electron/index.js index 18943589..f1de906f 100644 --- a/electron/index.js +++ b/electron/index.js @@ -361,7 +361,8 @@ ipcMain.handle("get-mods", async () => { if (externalMod) { console.log("Adding external mod source:", externalMod); - modFiles.push(externalMod); + const externalModPaths = externalMod.split(","); + modFiles = modFiles.concat(externalModPaths); } if (modFiles.length > 0 && !isDev) { From 0718f6cf802bb5397bc7c43606740ef2558c8f69 Mon Sep 17 00:00:00 2001 From: "Thomas (DJ1TJOO)" <44841260+DJ1TJOO@users.noreply.github.com> Date: Thu, 20 Jan 2022 17:57:04 +0100 Subject: [PATCH 04/14] Fixed class handle type (#1345) * Fixed class handle type * Fixed import game state --- src/js/mods/mod_interface.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/js/mods/mod_interface.js b/src/js/mods/mod_interface.js index 949e4301..e3b9e59b 100644 --- a/src/js/mods/mod_interface.js +++ b/src/js/mods/mod_interface.js @@ -369,7 +369,7 @@ export class ModInterface { /** * Registers a new state class, should be a GameState derived class - * @param {typeof GameState} stateClass + * @param {typeof import("../core/game_state").GameState} stateClass */ registerGameState(stateClass) { this.modLoader.app.stateMgr.register(stateClass); @@ -470,7 +470,7 @@ export class ModInterface { /** * - * @param {typeof Object} classHandle + * @param {Class} classHandle * @param {({ $super, $old }) => any} extender */ extendClass(classHandle, extender) { From 2ab4f3ba9adf965e14c502efc99c5aca366af8d3 Mon Sep 17 00:00:00 2001 From: tobspr Date: Thu, 20 Jan 2022 22:18:25 +0100 Subject: [PATCH 05/14] Minor adjustments --- mod_examples/README.md | 4 ++++ src/js/core/config.js | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/mod_examples/README.md b/mod_examples/README.md index 1545a46b..579eb34d 100644 --- a/mod_examples/README.md +++ b/mod_examples/README.md @@ -50,3 +50,7 @@ To get into shapez.io modding, I highly recommend checking out all of the exampl | [usage_statistics.js](usage_statistics.js) | Displays a percentage on every building showing its utilization | Adding a new component, Adding a new GameSystem, Drawing within a GameSystem, Modifying builtin buildings, Adding custom game logic | | [new_item_type.js](new_item_type.js) | Adds a new type of items to the map (fluids) | Adding a new item type, modifying map generation | | [buildings_have_cost.js](buildings_have_cost.js) | Adds a new currency, and belts cost 1 of that currency | Extending and replacing builtin methods, Adding CSS and custom sprites | + +### Creating new sprites + +If you want to add new buildings and create sprites for them, you can download the original Photoshop PSD files here: https://static.shapez.io/building-psds.zip diff --git a/src/js/core/config.js b/src/js/core/config.js index d64791c8..773295ed 100644 --- a/src/js/core/config.js +++ b/src/js/core/config.js @@ -58,7 +58,7 @@ export const globalConfig = { // Map mapChunkSize: 16, chunkAggregateSize: 4, - mapChunkOverviewMinZoom: 0, + mapChunkOverviewMinZoom: 0.9, mapChunkWorldSize: null, // COMPUTED maxBeltShapeBundleSize: 20, From 7741d1590ef532460566d80ef390bb8a57d972a2 Mon Sep 17 00:00:00 2001 From: tobspr Date: Fri, 21 Jan 2022 09:43:21 +0100 Subject: [PATCH 06/14] Refactor item acceptor to allow only single direction slots --- mod_examples/add_building_flipper.js | 2 +- src/js/game/buildings/balancer.js | 11 +-- src/js/game/buildings/cutter.js | 2 +- src/js/game/buildings/filter.js | 2 +- src/js/game/buildings/goal_acceptor.js | 2 +- src/js/game/buildings/hub.js | 86 +++-------------- src/js/game/buildings/mixer.js | 4 +- src/js/game/buildings/painter.js | 25 +++-- src/js/game/buildings/reader.js | 2 +- src/js/game/buildings/rotater.js | 2 +- src/js/game/buildings/stacker.js | 4 +- src/js/game/buildings/storage.js | 4 +- src/js/game/buildings/trash.js | 19 ++-- src/js/game/buildings/underground_belt.js | 2 +- src/js/game/components/belt.js | 2 +- src/js/game/components/item_acceptor.js | 27 +++--- src/js/game/entity.js | 26 +++--- src/js/game/hub_goals.js | 2 +- src/js/game/hud/parts/building_placer.js | 108 +++++++++++----------- src/js/game/logic.js | 30 +++--- src/js/game/systems/belt_underlays.js | 10 +- src/js/game/systems/item_ejector.js | 6 +- 22 files changed, 159 insertions(+), 219 deletions(-) diff --git a/mod_examples/add_building_flipper.js b/mod_examples/add_building_flipper.js index b3b746f3..c04354bf 100644 --- a/mod_examples/add_building_flipper.js +++ b/mod_examples/add_building_flipper.js @@ -80,7 +80,7 @@ class MetaModFlipperBuilding extends shapez.ModMetaBuilding { slots: [ { pos: new shapez.Vector(0, 0), - directions: [shapez.enumDirection.bottom], + direction: shapez.enumDirection.bottom, filter: "shape", }, ], diff --git a/src/js/game/buildings/balancer.js b/src/js/game/buildings/balancer.js index 0948338c..ce685a9a 100644 --- a/src/js/game/buildings/balancer.js +++ b/src/js/game/buildings/balancer.js @@ -179,11 +179,11 @@ export class MetaBalancerBuilding extends MetaBuilding { entity.components.ItemAcceptor.setSlots([ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, }, { pos: new Vector(1, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, }, ]); @@ -204,15 +204,14 @@ export class MetaBalancerBuilding extends MetaBuilding { entity.components.ItemAcceptor.setSlots([ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, }, { pos: new Vector(0, 0), - directions: [ + direction: variant === enumBalancerVariants.mergerInverse ? enumDirection.left : enumDirection.right, - ], }, ]); @@ -231,7 +230,7 @@ export class MetaBalancerBuilding extends MetaBuilding { entity.components.ItemAcceptor.setSlots([ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, }, ]); diff --git a/src/js/game/buildings/cutter.js b/src/js/game/buildings/cutter.js index 4950f786..21acdaa0 100644 --- a/src/js/game/buildings/cutter.js +++ b/src/js/game/buildings/cutter.js @@ -96,7 +96,7 @@ export class MetaCutterBuilding extends MetaBuilding { slots: [ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "shape", }, ], diff --git a/src/js/game/buildings/filter.js b/src/js/game/buildings/filter.js index bf4c5f19..f8c29b1f 100644 --- a/src/js/game/buildings/filter.js +++ b/src/js/game/buildings/filter.js @@ -78,7 +78,7 @@ export class MetaFilterBuilding extends MetaBuilding { slots: [ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, }, ], }) diff --git a/src/js/game/buildings/goal_acceptor.js b/src/js/game/buildings/goal_acceptor.js index cb51a6d2..463798ad 100644 --- a/src/js/game/buildings/goal_acceptor.js +++ b/src/js/game/buildings/goal_acceptor.js @@ -45,7 +45,7 @@ export class MetaGoalAcceptorBuilding extends MetaBuilding { slots: [ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "shape", }, ], diff --git a/src/js/game/buildings/hub.js b/src/js/game/buildings/hub.js index 3a543cf0..a0a9227e 100644 --- a/src/js/game/buildings/hub.js +++ b/src/js/game/buildings/hub.js @@ -70,80 +70,22 @@ export class MetaHubBuilding extends MetaBuilding { }) ); + /** + * @type {Array} + */ + const slots = []; + for (let i = 0; i < 4; ++i) { + slots.push( + { pos: new Vector(i, 0), direction: enumDirection.top, filter: "shape" }, + { pos: new Vector(i, 3), direction: enumDirection.bottom, filter: "shape" }, + { pos: new Vector(0, i), direction: enumDirection.left, filter: "shape" }, + { pos: new Vector(3, i), direction: enumDirection.right, filter: "shape" } + ); + } + entity.addComponent( new ItemAcceptorComponent({ - slots: [ - { - pos: new Vector(0, 0), - directions: [enumDirection.top, enumDirection.left], - filter: "shape", - }, - { - pos: new Vector(1, 0), - directions: [enumDirection.top], - filter: "shape", - }, - { - pos: new Vector(2, 0), - directions: [enumDirection.top], - filter: "shape", - }, - { - pos: new Vector(3, 0), - directions: [enumDirection.top, enumDirection.right], - filter: "shape", - }, - { - pos: new Vector(0, 3), - directions: [enumDirection.bottom, enumDirection.left], - filter: "shape", - }, - { - pos: new Vector(1, 3), - directions: [enumDirection.bottom], - filter: "shape", - }, - { - pos: new Vector(2, 3), - directions: [enumDirection.bottom], - filter: "shape", - }, - { - pos: new Vector(3, 3), - directions: [enumDirection.bottom, enumDirection.right], - filter: "shape", - }, - { - pos: new Vector(0, 1), - directions: [enumDirection.left], - filter: "shape", - }, - { - pos: new Vector(0, 2), - directions: [enumDirection.left], - filter: "shape", - }, - { - pos: new Vector(0, 3), - directions: [enumDirection.left], - filter: "shape", - }, - { - pos: new Vector(3, 1), - directions: [enumDirection.right], - filter: "shape", - }, - { - pos: new Vector(3, 2), - directions: [enumDirection.right], - filter: "shape", - }, - { - pos: new Vector(3, 3), - directions: [enumDirection.right], - filter: "shape", - }, - ], + slots, }) ); } diff --git a/src/js/game/buildings/mixer.js b/src/js/game/buildings/mixer.js index db8d867a..de1665c4 100644 --- a/src/js/game/buildings/mixer.js +++ b/src/js/game/buildings/mixer.js @@ -73,12 +73,12 @@ export class MetaMixerBuilding extends MetaBuilding { slots: [ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "color", }, { pos: new Vector(1, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "color", }, ], diff --git a/src/js/game/buildings/painter.js b/src/js/game/buildings/painter.js index 79ae86ac..432973d0 100644 --- a/src/js/game/buildings/painter.js +++ b/src/js/game/buildings/painter.js @@ -128,12 +128,12 @@ export class MetaPainterBuilding extends MetaBuilding { slots: [ { pos: new Vector(0, 0), - directions: [enumDirection.left], + direction: enumDirection.left, filter: "shape", }, { pos: new Vector(1, 0), - directions: [enumDirection.top], + direction: enumDirection.top, filter: "color", }, ], @@ -160,14 +160,13 @@ export class MetaPainterBuilding extends MetaBuilding { entity.components.ItemAcceptor.setSlots([ { pos: new Vector(0, 0), - directions: [enumDirection.left], + direction: enumDirection.left, filter: "shape", }, { pos: new Vector(1, 0), - directions: [ + direction: variant === defaultBuildingVariant ? enumDirection.top : enumDirection.bottom, - ], filter: "color", }, ]); @@ -193,17 +192,17 @@ export class MetaPainterBuilding extends MetaBuilding { entity.components.ItemAcceptor.setSlots([ { pos: new Vector(0, 0), - directions: [enumDirection.left], + direction: enumDirection.left, filter: "shape", }, { pos: new Vector(0, 1), - directions: [enumDirection.left], + direction: enumDirection.left, filter: "shape", }, { pos: new Vector(1, 0), - directions: [enumDirection.top], + direction: enumDirection.top, filter: "color", }, ]); @@ -251,27 +250,27 @@ export class MetaPainterBuilding extends MetaBuilding { entity.components.ItemAcceptor.setSlots([ { pos: new Vector(0, 0), - directions: [enumDirection.left], + direction: enumDirection.left, filter: "shape", }, { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "color", }, { pos: new Vector(1, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "color", }, { pos: new Vector(2, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "color", }, { pos: new Vector(3, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "color", }, ]); diff --git a/src/js/game/buildings/reader.js b/src/js/game/buildings/reader.js index 951c7e8a..5c9307c3 100644 --- a/src/js/game/buildings/reader.js +++ b/src/js/game/buildings/reader.js @@ -84,7 +84,7 @@ export class MetaReaderBuilding extends MetaBuilding { slots: [ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, }, ], }) diff --git a/src/js/game/buildings/rotater.js b/src/js/game/buildings/rotater.js index 428ab08a..e1080767 100644 --- a/src/js/game/buildings/rotater.js +++ b/src/js/game/buildings/rotater.js @@ -128,7 +128,7 @@ export class MetaRotaterBuilding extends MetaBuilding { slots: [ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "shape", }, ], diff --git a/src/js/game/buildings/stacker.js b/src/js/game/buildings/stacker.js index ad1a7bc7..f36ef248 100644 --- a/src/js/game/buildings/stacker.js +++ b/src/js/game/buildings/stacker.js @@ -73,12 +73,12 @@ export class MetaStackerBuilding extends MetaBuilding { slots: [ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "shape", }, { pos: new Vector(1, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "shape", }, ], diff --git a/src/js/game/buildings/storage.js b/src/js/game/buildings/storage.js index b63adc01..78f398be 100644 --- a/src/js/game/buildings/storage.js +++ b/src/js/game/buildings/storage.js @@ -74,11 +74,11 @@ export class MetaStorageBuilding extends MetaBuilding { slots: [ { pos: new Vector(0, 1), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, }, { pos: new Vector(1, 1), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, }, ], }) diff --git a/src/js/game/buildings/trash.js b/src/js/game/buildings/trash.js index 3085bc55..fcf7f11f 100644 --- a/src/js/game/buildings/trash.js +++ b/src/js/game/buildings/trash.js @@ -76,12 +76,19 @@ export class MetaTrashBuilding extends MetaBuilding { slots: [ { pos: new Vector(0, 0), - directions: [ - enumDirection.top, - enumDirection.right, - enumDirection.bottom, - enumDirection.left, - ], + direction: enumDirection.top, + }, + { + pos: new Vector(0, 0), + direction: enumDirection.right, + }, + { + pos: new Vector(0, 0), + direction: enumDirection.bottom, + }, + { + pos: new Vector(0, 0), + direction: enumDirection.left, }, ], }) diff --git a/src/js/game/buildings/underground_belt.js b/src/js/game/buildings/underground_belt.js index 0f02863f..7009ebd7 100644 --- a/src/js/game/buildings/underground_belt.js +++ b/src/js/game/buildings/underground_belt.js @@ -277,7 +277,7 @@ export class MetaUndergroundBeltBuilding extends MetaBuilding { entity.components.ItemAcceptor.setSlots([ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, }, ]); return; diff --git a/src/js/game/components/belt.js b/src/js/game/components/belt.js index 3144ad96..81d2c65c 100644 --- a/src/js/game/components/belt.js +++ b/src/js/game/components/belt.js @@ -8,7 +8,7 @@ export const curvedBeltLength = /* Math.PI / 4 */ 0.78; /** @type {import("./item_acceptor").ItemAcceptorSlot} */ export const FAKE_BELT_ACCEPTOR_SLOT = { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, }; /** @type {Object} */ diff --git a/src/js/game/components/item_acceptor.js b/src/js/game/components/item_acceptor.js index 354f9024..d3df3763 100644 --- a/src/js/game/components/item_acceptor.js +++ b/src/js/game/components/item_acceptor.js @@ -3,9 +3,10 @@ import { types } from "../../savegame/serialization"; import { BaseItem } from "../base_item"; import { Component } from "../component"; -/** @typedef {{ +/** + * @typedef {{ * pos: Vector, - * directions: enumDirection[], + * direction: enumDirection, * filter?: ItemType * }} ItemAcceptorSlot */ @@ -14,12 +15,12 @@ import { Component } from "../component"; * @typedef {{ * slot: ItemAcceptorSlot, * index: number, - * acceptedDirection: enumDirection * }} ItemAcceptorLocatedSlot */ -/** @typedef {{ +/** + * @typedef {{ * pos: Vector, - * directions: enumDirection[], + * direction: enumDirection, * filter?: ItemType * }} ItemAcceptorSlotConfig */ @@ -64,7 +65,7 @@ export class ItemAcceptorComponent extends Component { const slot = slots[i]; this.slots.push({ pos: slot.pos, - directions: slot.directions, + direction: slot.direction, // Which type of item to accept (shape | color | all) @see ItemType filter: slot.filter, @@ -122,15 +123,11 @@ export class ItemAcceptorComponent extends Component { } // Check if the acceptor slot accepts items from our direction - for (let i = 0; i < slot.directions.length; ++i) { - // const localDirection = targetStaticComp.localDirectionToWorld(slot.directions[l]); - if (desiredDirection === slot.directions[i]) { - return { - slot, - index: slotIndex, - acceptedDirection: desiredDirection, - }; - } + if (desiredDirection === slot.direction) { + return { + slot, + index: slotIndex, + }; } } diff --git a/src/js/game/entity.js b/src/js/game/entity.js index d7dd715e..3010f067 100644 --- a/src/js/game/entity.js +++ b/src/js/game/entity.js @@ -197,20 +197,18 @@ export class Entity extends BasicSerializableObject { for (let i = 0; i < acceptorComp.slots.length; ++i) { const slot = acceptorComp.slots[i]; const slotTile = staticComp.localTileToWorld(slot.pos); - for (let k = 0; k < slot.directions.length; ++k) { - const direction = staticComp.localDirectionToWorld(slot.directions[k]); - const directionVector = enumDirectionToVector[direction]; - const angle = Math.radians(enumDirectionToAngle[direction] + 180); - context.globalAlpha = 0.4; - drawRotatedSprite({ - parameters, - sprite: acceptorSprite, - x: (slotTile.x + 0.5 + directionVector.x * 0.37) * globalConfig.tileSize, - y: (slotTile.y + 0.5 + directionVector.y * 0.37) * globalConfig.tileSize, - angle, - size: globalConfig.tileSize * 0.25, - }); - } + const direction = staticComp.localDirectionToWorld(slot.direction); + const directionVector = enumDirectionToVector[direction]; + const angle = Math.radians(enumDirectionToAngle[direction] + 180); + context.globalAlpha = 0.4; + drawRotatedSprite({ + parameters, + sprite: acceptorSprite, + x: (slotTile.x + 0.5 + directionVector.x * 0.37) * globalConfig.tileSize, + y: (slotTile.y + 0.5 + directionVector.y * 0.37) * globalConfig.tileSize, + angle, + size: globalConfig.tileSize * 0.25, + }); } } diff --git a/src/js/game/hub_goals.js b/src/js/game/hub_goals.js index 854ef2ae..9f9c63be 100644 --- a/src/js/game/hub_goals.js +++ b/src/js/game/hub_goals.js @@ -435,7 +435,7 @@ export class HubGoals extends BasicSerializableObject { } const randomColor = () => rng.choice(colors); - const randomShape = () => rng.choice(Object.values(enumSubShape)); + const randomShape = () => rng.choice(availableShapes); let anyIsMissingTwo = false; diff --git a/src/js/game/hud/parts/building_placer.js b/src/js/game/hud/parts/building_placer.js index e4ecfe7e..ca9c128b 100644 --- a/src/js/game/hud/parts/building_placer.js +++ b/src/js/game/hud/parts/building_placer.js @@ -530,7 +530,13 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic { const offsetShift = 10; + /** + * @type {Array} + */ let acceptorSlots = []; + /** + * @type {Array} + */ let ejectorSlots = []; if (ejectorComp) { @@ -548,71 +554,65 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic { acceptorSlots.push(fakeAcceptorSlot); } - for (let acceptorSlotIndex = 0; acceptorSlotIndex < acceptorSlots.length; ++acceptorSlotIndex) { - const slot = acceptorSlots[acceptorSlotIndex]; + // Go over all slots + for (let i = 0; i < acceptorSlots.length; ++i) { + const slot = acceptorSlots[i]; const acceptorSlotWsTile = staticComp.localTileToWorld(slot.pos); const acceptorSlotWsPos = acceptorSlotWsTile.toWorldSpaceCenterOfTile(); - // Go over all slots - for ( - let acceptorDirectionIndex = 0; - acceptorDirectionIndex < slot.directions.length; - ++acceptorDirectionIndex - ) { - const direction = slot.directions[acceptorDirectionIndex]; - const worldDirection = staticComp.localDirectionToWorld(direction); + const direction = slot.direction; + const worldDirection = staticComp.localDirectionToWorld(direction); - // Figure out which tile ejects to this slot - const sourceTile = acceptorSlotWsTile.add(enumDirectionToVector[worldDirection]); + // Figure out which tile ejects to this slot + const sourceTile = acceptorSlotWsTile.add(enumDirectionToVector[worldDirection]); - let isBlocked = false; - let isConnected = false; + let isBlocked = false; + let isConnected = false; - // Find all entities which are on that tile - const sourceEntities = this.root.map.getLayersContentsMultipleXY(sourceTile.x, sourceTile.y); + // Find all entities which are on that tile + const sourceEntities = this.root.map.getLayersContentsMultipleXY(sourceTile.x, sourceTile.y); - // Check for every entity: - for (let i = 0; i < sourceEntities.length; ++i) { - const sourceEntity = sourceEntities[i]; - const sourceEjector = sourceEntity.components.ItemEjector; - const sourceBeltComp = sourceEntity.components.Belt; - const sourceStaticComp = sourceEntity.components.StaticMapEntity; - const ejectorAcceptLocalTile = sourceStaticComp.worldToLocalTile(acceptorSlotWsTile); + // Check for every entity: + for (let j = 0; j < sourceEntities.length; ++j) { + const sourceEntity = sourceEntities[j]; + const sourceEjector = sourceEntity.components.ItemEjector; + const sourceBeltComp = sourceEntity.components.Belt; + const sourceStaticComp = sourceEntity.components.StaticMapEntity; + const ejectorAcceptLocalTile = sourceStaticComp.worldToLocalTile(acceptorSlotWsTile); - // If this entity is on the same layer as the slot - if so, it can either be - // connected, or it can not be connected and thus block the input - if (sourceEjector && sourceEjector.anySlotEjectsToLocalTile(ejectorAcceptLocalTile)) { - // This one is connected, all good - isConnected = true; - } else if ( - sourceBeltComp && - sourceStaticComp.localDirectionToWorld(sourceBeltComp.direction) === - enumInvertedDirections[worldDirection] - ) { - // Belt connected - isConnected = true; - } else { - // This one is blocked - isBlocked = true; - } + // If this entity is on the same layer as the slot - if so, it can either be + // connected, or it can not be connected and thus block the input + if (sourceEjector && sourceEjector.anySlotEjectsToLocalTile(ejectorAcceptLocalTile)) { + // This one is connected, all good + isConnected = true; + } else if ( + sourceBeltComp && + sourceStaticComp.localDirectionToWorld(sourceBeltComp.direction) === + enumInvertedDirections[worldDirection] + ) { + // Belt connected + isConnected = true; + } else { + // This one is blocked + isBlocked = true; } - - const alpha = isConnected || isBlocked ? 1.0 : 0.3; - const sprite = isBlocked ? badArrowSprite : goodArrowSprite; - - parameters.context.globalAlpha = alpha; - drawRotatedSprite({ - parameters, - sprite, - x: acceptorSlotWsPos.x, - y: acceptorSlotWsPos.y, - angle: Math.radians(enumDirectionToAngle[enumInvertedDirections[worldDirection]]), - size: 13, - offsetY: offsetShift + 13, - }); - parameters.context.globalAlpha = 1; } + + const alpha = isConnected || isBlocked ? 1.0 : 0.3; + const sprite = isBlocked ? badArrowSprite : goodArrowSprite; + + parameters.context.globalAlpha = alpha; + drawRotatedSprite({ + parameters, + sprite, + x: acceptorSlotWsPos.x, + y: acceptorSlotWsPos.y, + angle: Math.radians(enumDirectionToAngle[enumInvertedDirections[worldDirection]]), + size: 13, + offsetY: offsetShift + 13, + }); + parameters.context.globalAlpha = 1; } // Go over all slots diff --git a/src/js/game/logic.js b/src/js/game/logic.js index c7306dfc..0e915fea 100644 --- a/src/js/game/logic.js +++ b/src/js/game/logic.js @@ -395,7 +395,14 @@ export class GameLogic { const entity = this.root.map.getLayerContentXY(tile.x + dx, tile.y + dy, "regular"); if (entity) { + /** + * @type {Array} + */ let ejectorSlots = []; + + /** + * @type {Array} + */ let acceptorSlots = []; const staticComp = entity.components.StaticMapEntity; @@ -436,19 +443,16 @@ export class GameLogic { for (let acceptorSlot = 0; acceptorSlot < acceptorSlots.length; ++acceptorSlot) { const slot = acceptorSlots[acceptorSlot]; const wsTile = staticComp.localTileToWorld(slot.pos); - for (let k = 0; k < slot.directions.length; ++k) { - const direction = slot.directions[k]; - const wsDirection = staticComp.localDirectionToWorld(direction); - - const sourceTile = wsTile.add(enumDirectionToVector[wsDirection]); - if (sourceTile.equals(tile)) { - acceptors.push({ - entity, - slot, - toTile: wsTile, - fromDirection: wsDirection, - }); - } + const direction = slot.direction; + const wsDirection = staticComp.localDirectionToWorld(direction); + const sourceTile = wsTile.add(enumDirectionToVector[wsDirection]); + if (sourceTile.equals(tile)) { + acceptors.push({ + entity, + slot, + toTile: wsTile, + fromDirection: wsDirection, + }); } } } diff --git a/src/js/game/systems/belt_underlays.js b/src/js/game/systems/belt_underlays.js index 02707525..ddbe051a 100644 --- a/src/js/game/systems/belt_underlays.js +++ b/src/js/game/systems/belt_underlays.js @@ -113,12 +113,10 @@ export class BeltUnderlaysSystem extends GameSystem { continue; } - // Step 2: Check if any of the directions matches - for (let j = 0; j < slot.directions.length; ++j) { - const slotDirection = staticComp.localDirectionToWorld(slot.directions[j]); - if (slotDirection === fromDirection) { - return true; - } + // Step 2: Check if the direction matches + const slotDirection = staticComp.localDirectionToWorld(slot.direction); + if (slotDirection === fromDirection) { + return true; } } } diff --git a/src/js/game/systems/item_ejector.js b/src/js/game/systems/item_ejector.js index 4eef11aa..8c7468ad 100644 --- a/src/js/game/systems/item_ejector.js +++ b/src/js/game/systems/item_ejector.js @@ -203,11 +203,7 @@ export class ItemEjectorSystem extends GameSystemWithFilter { if (this.tryPassOverItem(item, destEntity, destSlot.index)) { // Handover successful, clear slot if (!this.root.app.settings.getAllSettings().simplifiedBelts) { - targetAcceptorComp.onItemAccepted( - destSlot.index, - destSlot.acceptedDirection, - item - ); + targetAcceptorComp.onItemAccepted(destSlot.index, destSlot.slot.direction, item); } sourceSlot.item = null; continue; From 1287bc9bf18c614e937b93ef075920977a7daf0c Mon Sep 17 00:00:00 2001 From: tobspr Date: Sat, 22 Jan 2022 09:03:42 +0100 Subject: [PATCH 07/14] Allow specifying minimumGameVersion --- mod_examples/add_building_basic.js | 1 + mod_examples/add_building_flipper.js | 1 + mod_examples/base.js | 1 + mod_examples/buildings_have_cost.js | 1 + mod_examples/class_extensions.js | 1 + mod_examples/custom_css.js | 1 + mod_examples/custom_drawing.js | 1 + mod_examples/custom_keybinding.js | 1 + mod_examples/custom_sub_shapes.js | 1 + mod_examples/custom_theme.js | 1 + mod_examples/mod_settings.js | 1 + mod_examples/modify_existing_building.js | 1 + mod_examples/modify_theme.js | 1 + mod_examples/modify_ui.js | 1 + mod_examples/new_item_type.js | 1 + mod_examples/notification_blocks.js | 2 ++ mod_examples/pasting.js | 1 + mod_examples/replace_builtin_sprites.js | 1 + mod_examples/translations.js | 1 + mod_examples/usage_statistics.js | 2 ++ package.json | 1 + src/js/mods/modloader.js | 25 ++++++++++++++++++++++++ yarn.lock | 19 ++++++++++++++++++ 23 files changed, 67 insertions(+) diff --git a/mod_examples/add_building_basic.js b/mod_examples/add_building_basic.js index 97e0a358..4f834bc2 100644 --- a/mod_examples/add_building_basic.js +++ b/mod_examples/add_building_basic.js @@ -6,6 +6,7 @@ const METADATA = { version: "1", id: "add-building-basic", description: "Shows how to add a new basic building", + minimumGameVersion: "^1.5.0", }; class MetaDemoModBuilding extends shapez.ModMetaBuilding { diff --git a/mod_examples/add_building_flipper.js b/mod_examples/add_building_flipper.js index c04354bf..670f012a 100644 --- a/mod_examples/add_building_flipper.js +++ b/mod_examples/add_building_flipper.js @@ -7,6 +7,7 @@ const METADATA = { id: "add-building-extended", description: "Shows how to add a new building with logic, in this case it flips/mirrors shapez from top to down", + minimumGameVersion: "^1.5.0", }; // Declare a new type of item processor diff --git a/mod_examples/base.js b/mod_examples/base.js index 6dc8df8f..9810e823 100644 --- a/mod_examples/base.js +++ b/mod_examples/base.js @@ -6,6 +6,7 @@ const METADATA = { version: "1", id: "base", description: "The most basic mod", + minimumGameVersion: "^1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/buildings_have_cost.js b/mod_examples/buildings_have_cost.js index 79061d35..04d1e14e 100644 --- a/mod_examples/buildings_have_cost.js +++ b/mod_examples/buildings_have_cost.js @@ -6,6 +6,7 @@ const METADATA = { version: "1", id: "patch-methods", description: "Shows how to patch existing methods to change the game by making the belts cost shapes", + minimumGameVersion: "^1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/class_extensions.js b/mod_examples/class_extensions.js index c5b5b95e..904a5a03 100644 --- a/mod_examples/class_extensions.js +++ b/mod_examples/class_extensions.js @@ -6,6 +6,7 @@ const METADATA = { version: "1", id: "class-extensions", description: "Shows how to extend builtin classes", + minimumGameVersion: "^1.5.0", }; const BeltExtension = ({ $super, $old }) => ({ diff --git a/mod_examples/custom_css.js b/mod_examples/custom_css.js index 74d19057..2df83afd 100644 --- a/mod_examples/custom_css.js +++ b/mod_examples/custom_css.js @@ -6,6 +6,7 @@ const METADATA = { version: "1", id: "custom-css", description: "Shows how to add custom css", + minimumGameVersion: "^1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/custom_drawing.js b/mod_examples/custom_drawing.js index 6ba49454..f491b94b 100644 --- a/mod_examples/custom_drawing.js +++ b/mod_examples/custom_drawing.js @@ -6,6 +6,7 @@ const METADATA = { version: "1", id: "base", description: "Displays an indicator on every item processing building when its working", + minimumGameVersion: "^1.5.0", }; class ItemProcessorStatusGameSystem extends shapez.GameSystem { diff --git a/mod_examples/custom_keybinding.js b/mod_examples/custom_keybinding.js index 650065f0..46ef71a6 100644 --- a/mod_examples/custom_keybinding.js +++ b/mod_examples/custom_keybinding.js @@ -6,6 +6,7 @@ const METADATA = { version: "1", id: "base", description: "Shows how to add a new keybinding", + minimumGameVersion: "^1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/custom_sub_shapes.js b/mod_examples/custom_sub_shapes.js index afb901c0..906e3c9b 100644 --- a/mod_examples/custom_sub_shapes.js +++ b/mod_examples/custom_sub_shapes.js @@ -6,6 +6,7 @@ const METADATA = { version: "1", id: "custom-sub-shapes", description: "Shows how to add custom sub shapes", + minimumGameVersion: "^1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/custom_theme.js b/mod_examples/custom_theme.js index a596799c..400e3b7c 100644 --- a/mod_examples/custom_theme.js +++ b/mod_examples/custom_theme.js @@ -6,6 +6,7 @@ const METADATA = { version: "1", id: "custom-theme", description: "Shows how to add a custom game theme", + minimumGameVersion: "^1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/mod_settings.js b/mod_examples/mod_settings.js index bbcfe3fd..8f8e20de 100644 --- a/mod_examples/mod_settings.js +++ b/mod_examples/mod_settings.js @@ -6,6 +6,7 @@ const METADATA = { version: "1", id: "mod-settings", description: "Shows how to add settings to your mod", + minimumGameVersion: "^1.5.0", settings: { timesLaunched: 0, diff --git a/mod_examples/modify_existing_building.js b/mod_examples/modify_existing_building.js index 1264b2c3..c88fad7e 100644 --- a/mod_examples/modify_existing_building.js +++ b/mod_examples/modify_existing_building.js @@ -6,6 +6,7 @@ const METADATA = { version: "1", id: "modify-existing-building", description: "Shows how to modify an existing building", + minimumGameVersion: "^1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/modify_theme.js b/mod_examples/modify_theme.js index dfdfb6e9..8a7f4318 100644 --- a/mod_examples/modify_theme.js +++ b/mod_examples/modify_theme.js @@ -6,6 +6,7 @@ const METADATA = { version: "1", id: "modify-theme", description: "Shows how to modify builtin themes", + minimumGameVersion: "^1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/modify_ui.js b/mod_examples/modify_ui.js index 749e191e..ef8d2455 100644 --- a/mod_examples/modify_ui.js +++ b/mod_examples/modify_ui.js @@ -6,6 +6,7 @@ const METADATA = { version: "1", id: "modify-ui", description: "Shows how to modify a builtin game state, in this case the main menu", + minimumGameVersion: "^1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/new_item_type.js b/mod_examples/new_item_type.js index ee06538d..3c8dad5c 100644 --- a/mod_examples/new_item_type.js +++ b/mod_examples/new_item_type.js @@ -6,6 +6,7 @@ const METADATA = { version: "1", id: "new-item-type", description: "Shows how to add a new item type (fluid)", + minimumGameVersion: "^1.5.0", }; // Define which fluid types there are diff --git a/mod_examples/notification_blocks.js b/mod_examples/notification_blocks.js index a8116849..4d8cf476 100644 --- a/mod_examples/notification_blocks.js +++ b/mod_examples/notification_blocks.js @@ -7,6 +7,8 @@ const METADATA = { id: "notification-blocks", description: "Adds a new building to the wires layer, 'Notification Blocks' which show a custom notification when they get a truthy signal.", + + minimumGameVersion: "^1.5.0", }; //////////////////////////////////////////////////////////////////////// diff --git a/mod_examples/pasting.js b/mod_examples/pasting.js index edd4952c..de253910 100644 --- a/mod_examples/pasting.js +++ b/mod_examples/pasting.js @@ -6,6 +6,7 @@ const METADATA = { version: "1", id: "pasting", description: "Shows how to properly receive paste events ingame", + minimumGameVersion: "^1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/replace_builtin_sprites.js b/mod_examples/replace_builtin_sprites.js index 9865121e..1d93a36c 100644 --- a/mod_examples/replace_builtin_sprites.js +++ b/mod_examples/replace_builtin_sprites.js @@ -6,6 +6,7 @@ const METADATA = { version: "1", id: "replace-builtin-sprites", description: "Shows how to replace builtin sprites", + minimumGameVersion: "^1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/translations.js b/mod_examples/translations.js index 8a3e07da..080be45c 100644 --- a/mod_examples/translations.js +++ b/mod_examples/translations.js @@ -6,6 +6,7 @@ const METADATA = { version: "1", id: "translations", description: "Shows how to add and modify translations", + minimumGameVersion: "^1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/usage_statistics.js b/mod_examples/usage_statistics.js index 36bb81f5..1412e4dd 100644 --- a/mod_examples/usage_statistics.js +++ b/mod_examples/usage_statistics.js @@ -7,6 +7,8 @@ const METADATA = { id: "usage-statistics", description: "Shows how to add a new component to the game, how to save additional data and how to add custom logic and drawings", + + minimumGameVersion: "^1.5.0", }; /** diff --git a/package.json b/package.json index 4ee134b7..ef752aac 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "promise-polyfill": "^8.1.0", "query-string": "^6.8.1", "rusha": "^0.8.13", + "semver": "^7.3.5", "serialize-error": "^3.0.0", "strictdom": "^1.0.1", "string-replace-webpack-plugin": "^0.1.3", diff --git a/src/js/mods/modloader.js b/src/js/mods/modloader.js index 96743038..48911abd 100644 --- a/src/js/mods/modloader.js +++ b/src/js/mods/modloader.js @@ -10,6 +10,9 @@ import { Mod } from "./mod"; import { ModInterface } from "./mod_interface"; import { MOD_SIGNALS } from "./mod_signals"; +import semverValidRange from "semver/ranges/valid"; +import semverSatisifies from "semver/functions/satisfies"; + const LOG = createLogger("mods"); /** @@ -20,6 +23,7 @@ const LOG = createLogger("mods"); * website: string; * description: string; * id: string; + * minimumGameVersion?: string; * settings: [] * }} ModMetadata */ @@ -158,6 +162,27 @@ export class ModLoader { const { modClass, meta } = this.modLoadQueue[i]; const modDataFile = "modsettings_" + meta.id + "__" + meta.version + ".json"; + if (meta.minimumGameVersion) { + console.warn(meta.minimumGameVersion, G_BUILD_VERSION); + const minimumGameVersion = meta.minimumGameVersion; + if (!semverValidRange(minimumGameVersion)) { + alert("Mod " + meta.id + " has invalid minimumGameVersion: " + minimumGameVersion); + continue; + } + if (!semverSatisifies(G_BUILD_VERSION, minimumGameVersion)) { + alert( + "Mod '" + + meta.id + + "' is incompatible with this version of the game: \n\n" + + "Mod requires version " + + minimumGameVersion + + " but this game has version " + + G_BUILD_VERSION + ); + continue; + } + } + let settings = meta.settings; if (meta.settings) { diff --git a/yarn.lock b/yarn.lock index cdcdd19e..27552f93 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5245,6 +5245,13 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + lz-string@^1.4.4: version "1.4.4" resolved "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz" @@ -7496,6 +7503,13 @@ semver@^7.2.1, semver@^7.3.2: resolved "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz" integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== +semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + send@0.17.1: version "0.17.1" resolved "https://registry.npmjs.org/send/-/send-0.17.1.tgz" @@ -8800,6 +8814,11 @@ yallist@^3.0.2: resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + yaml-js@^0.1.3: version "0.1.5" resolved "https://registry.npmjs.org/yaml-js/-/yaml-js-0.1.5.tgz" From ade7176dba0f37d3478d380fc11cf452b43738e3 Mon Sep 17 00:00:00 2001 From: tobspr Date: Sat, 22 Jan 2022 09:34:38 +0100 Subject: [PATCH 08/14] Add sandbox example --- mod_examples/README.md | 1 + mod_examples/sandbox.js | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 mod_examples/sandbox.js diff --git a/mod_examples/README.md b/mod_examples/README.md index 25b1d75e..e38d5834 100644 --- a/mod_examples/README.md +++ b/mod_examples/README.md @@ -41,6 +41,7 @@ To get into shapez.io modding, I highly recommend checking out all of the exampl | [modify_existing_building.js](modify_existing_building.js) | Makes the rotator building always unlocked and adds a new statistic to the building panel | Modifying a builtin building, replacing builtin methods | | [modify_ui.js](modify_ui.js) | Shows how to add custom IU elements to builtin game states (the Main Menu in this case) | Extending builtin UI states, Adding CSS | | [pasting.js](pasting.js) | Shows a dialog when pasting text in the game | Listening to paste events | +| [sandbox.js](sandbox.js) | Makes blueprints free and always unlocked | Overriding builtin methods | ### Advanced Examples diff --git a/mod_examples/sandbox.js b/mod_examples/sandbox.js new file mode 100644 index 00000000..d57e1e0e --- /dev/null +++ b/mod_examples/sandbox.js @@ -0,0 +1,21 @@ +// @ts-nocheck +const METADATA = { + website: "https://tobspr.io", + author: "tobspr", + name: "Sandbox", + version: "1", + id: "sandbox", + description: "Blueprints are always unlocked and cost no money, also all buildings are unlocked", + minimumGameVersion: "^1.5.0", +}; + +class Mod extends shapez.Mod { + init() { + this.modInterface.replaceMethod(shapez.Blueprint, "getCost", function () { + return 0; + }); + this.modInterface.replaceMethod(shapez.HubGoals, "isRewardUnlocked", function () { + return true; + }); + } +} From a3dfe6f5fb2cba520c72a495ddea16abd7fb34be Mon Sep 17 00:00:00 2001 From: saile515 <63782477+saile515@users.noreply.github.com> Date: Sat, 22 Jan 2022 09:50:02 +0100 Subject: [PATCH 09/14] Replaced concatenated strings with template literals (#1347) --- mod_examples/mod_settings.js | 2 +- mod_examples/new_item_type.js | 4 ++-- mod_examples/pasting.js | 2 +- mod_examples/replace_builtin_sprites.js | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mod_examples/mod_settings.js b/mod_examples/mod_settings.js index 8f8e20de..873468c4 100644 --- a/mod_examples/mod_settings.js +++ b/mod_examples/mod_settings.js @@ -24,7 +24,7 @@ class Mod extends shapez.Mod { if (state instanceof shapez.MainMenuState) { this.dialogs.showInfo( "Welcome back", - "You have launched this mod " + this.settings.timesLaunched + " times" + `You have launched this mod ${this.settings.timesLaunched} times` ); } }); diff --git a/mod_examples/new_item_type.js b/mod_examples/new_item_type.js index 3c8dad5c..a9fa30ca 100644 --- a/mod_examples/new_item_type.js +++ b/mod_examples/new_item_type.js @@ -76,7 +76,7 @@ class FluidItem extends shapez.BaseItem { */ drawFullSizeOnCanvas(context, size) { if (!this.cachedSprite) { - this.cachedSprite = shapez.Loader.getSprite("sprites/fluids/" + this.fluidType + ".png"); + this.cachedSprite = shapez.Loader.getSprite(`sprites/fluids/${this.fluidType}.png`); } this.cachedSprite.drawCentered(context, size / 2, size / 2, size); } @@ -90,7 +90,7 @@ class FluidItem extends shapez.BaseItem { drawItemCenteredClipped(x, y, parameters, diameter = globalConfig.defaultItemDiameter) { const realDiameter = diameter * 0.6; if (!this.cachedSprite) { - this.cachedSprite = shapez.Loader.getSprite("sprites/fluids/" + this.fluidType + ".png"); + this.cachedSprite = shapez.Loader.getSprite(`sprites/fluids/${this.fluidType}.png`); } this.cachedSprite.drawCachedCentered(parameters, x, y, realDiameter); } diff --git a/mod_examples/pasting.js b/mod_examples/pasting.js index de253910..b514f137 100644 --- a/mod_examples/pasting.js +++ b/mod_examples/pasting.js @@ -16,7 +16,7 @@ class Mod extends shapez.Mod { event.preventDefault(); const data = event.clipboardData.getData("text"); - this.dialogs.showInfo("Pasted", "You pasted: '" + data + "'"); + this.dialogs.showInfo("Pasted", `You pasted: '${data}'`); }); }); } diff --git a/mod_examples/replace_builtin_sprites.js b/mod_examples/replace_builtin_sprites.js index 1d93a36c..d0407692 100644 --- a/mod_examples/replace_builtin_sprites.js +++ b/mod_examples/replace_builtin_sprites.js @@ -13,7 +13,7 @@ class Mod extends shapez.Mod { init() { // Replace a builtin sprite ["red", "green", "blue", "yellow", "purple", "cyan", "white"].forEach(color => { - this.modInterface.registerSprite("sprites/colors/" + color + ".png", RESOURCES[color + ".png"]); + this.modInterface.registerSprite(`sprites/colors/${color}.png`, RESOURCES[color + ".png"]); }); } } From 408d1a7dcacc44700c5cb3749e2868fe298cfdfb Mon Sep 17 00:00:00 2001 From: tobspr Date: Sat, 22 Jan 2022 10:03:42 +0100 Subject: [PATCH 10/14] Mod improvements --- src/css/states/main_menu.scss | 43 +++++++++++++++++++++++------------ src/css/states/mods.scss | 9 ++++++++ src/js/core/config.js | 2 ++ src/js/states/main_menu.js | 10 ++++++-- src/js/states/mods.js | 17 +++++++++++++- translations/base-en.yaml | 1 + 6 files changed, 65 insertions(+), 17 deletions(-) diff --git a/src/css/states/main_menu.scss b/src/css/states/main_menu.scss index 2458350e..9027d8a8 100644 --- a/src/css/states/main_menu.scss +++ b/src/css/states/main_menu.scss @@ -199,10 +199,6 @@ transform: translateX(50%) rotate(-7deg) scale(1.1); } } - - @include DarkThemeOverride { - color: $colorBlueBright; - } } } @@ -326,6 +322,7 @@ /* @load-async */ background-image: uiResource("icons/edit_key.png") !important; } + @include DarkThemeInvert; } } @@ -354,13 +351,14 @@ box-sizing: border-box; @include PlainText; @include S(margin-bottom, 5px); - display: grid; - grid-template-columns: 1fr auto auto; - @include S(grid-gap, 5px); + display: flex; + flex-direction: column; .author, .version { @include SuperSmallText; + align-self: end; + opacity: 0.4; } .name { overflow: hidden; @@ -457,19 +455,19 @@ .newGameButton { @include IncreasedClickArea(0px); - @include S(margin-left, 15px); + @include S(margin-left, 10px); } .modsButton { @include IncreasedClickArea(0px); - @include S(margin-left, 15px); + @include S(margin-left, 10px); - @include S(width, 20px); + // @include S(width, 20px); - & { - /* @load-async */ - background-image: uiResource("res/ui/icons/mods_white.png") !important; - } + // & { + // /* @load-async */ + // background-image: uiResource("res/ui/icons/mods_white.png") !important; + // } background-position: center center; background-size: D(15px); background-color: $modsColor !important; @@ -837,6 +835,23 @@ } } + .modsOverview { + background: $darkModeControlsBackground; + + .modsList { + border-color: darken($darkModeControlsBackground, 5); + + .mod { + background: darken($darkModeControlsBackground, 5); + color: white; + } + } + + .dlcHint { + color: $accentColorBright; + } + } + .footer { > a, .sidelinks > a { diff --git a/src/css/states/mods.scss b/src/css/states/mods.scss index 54d8422b..acec41fb 100644 --- a/src/css/states/mods.scss +++ b/src/css/states/mods.scss @@ -62,6 +62,11 @@ @include S(margin-top, 100px); color: lighten($accentColorDark, 15); + button { + @include S(margin-top, 10px); + @include S(padding, 10px, 20px); + } + &::before { @include S(margin-bottom, 15px); content: ""; @@ -94,6 +99,10 @@ display: grid; grid-template-columns: 1fr D(100px) D(80px) D(50px); + @include DarkThemeOverride { + background: darken($darkModeControlsBackground, 5); + } + .checkbox { align-self: center; justify-self: center; diff --git a/src/js/core/config.js b/src/js/core/config.js index 773295ed..b451e848 100644 --- a/src/js/core/config.js +++ b/src/js/core/config.js @@ -28,6 +28,8 @@ export const THIRDPARTY_URLS = { 25: "https://www.youtube.com/watch?v=7OCV1g40Iew&", 26: "https://www.youtube.com/watch?v=gfm6dS1dCoY", }, + + modBrowser: "https://shapez.mod.io/?preview=f55f6304ca4873d9a25f3b575571b948", }; // export const A_B_TESTING_LINK_TYPE = Math.random() > 0.95 ? "steam_1_pr" : "steam_2_npr"; diff --git a/src/js/states/main_menu.js b/src/js/states/main_menu.js index b23a15f3..4d62f2ce 100644 --- a/src/js/states/main_menu.js +++ b/src/js/states/main_menu.js @@ -161,7 +161,10 @@ export class MainMenuState extends GameState { ${MODS.mods .map(mod => { return ` -
${mod.metadata.name} @ v${mod.metadata.version}
+
+
${mod.metadata.name}
+
by ${mod.metadata.author}
+
`; }) .join("")} @@ -413,7 +416,10 @@ export class MainMenuState extends GameState { } // Mods - this.trackClicks(makeButton(outerDiv, ["modsButton", "styledButton"], " "), this.onModsClicked); + this.trackClicks( + makeButton(outerDiv, ["modsButton", "styledButton"], T.mods.title), + this.onModsClicked + ); buttonContainer.appendChild(outerDiv); } diff --git a/src/js/states/mods.js b/src/js/states/mods.js index c3cbce52..42add8bd 100644 --- a/src/js/states/mods.js +++ b/src/js/states/mods.js @@ -18,6 +18,11 @@ export class ModsState extends TextualGameState {

${this.getStateHeaderTitle()}

+ ${ + (G_IS_STANDALONE || G_IS_DEV) && MODS.mods.length > 0 + ? `` + : "" + } ${ G_IS_STANDALONE || G_IS_DEV ? `` @@ -53,8 +58,9 @@ export class ModsState extends TextualGameState { return `
- ${T.mods.modsInfo} + +
`; @@ -100,6 +106,10 @@ export class ModsState extends TextualGameState { if (openModsFolder) { this.trackClicks(openModsFolder, this.openModsFolder); } + const browseMods = this.htmlElement.querySelector(".browseMods"); + if (browseMods) { + this.trackClicks(browseMods, this.openBrowseMods); + } const checkboxes = this.htmlElement.querySelectorAll(".checkbox"); Array.from(checkboxes).forEach(checkbox => { @@ -119,6 +129,11 @@ export class ModsState extends TextualGameState { ipcRenderer.invoke("open-mods-folder"); } + openBrowseMods() { + this.app.analytics.trackUiClick("mods_sbrowse_link"); + this.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.modBrowser); + } + onSteamLinkClicked() { this.app.analytics.trackUiClick("mods_steam_link"); this.app.platformWrapper.openExternalLink( diff --git a/translations/base-en.yaml b/translations/base-en.yaml index 2f76c00f..7070c318 100644 --- a/translations/base-en.yaml +++ b/translations/base-en.yaml @@ -1098,6 +1098,7 @@ mods: version: Version openFolder: Open Mods Folder folderOnlyStandalone: Opening the mod folder is only possible when running the standalone. + browseMods: Browse Mods modsInfo: >- To install and manage mods, copy them to the mods folder within the game directory. You can also use the 'Open Mods Folder' button on the top right. From 0540a010a618f3149275df28f6c3985d1a30bcfb Mon Sep 17 00:00:00 2001 From: tobspr Date: Sat, 22 Jan 2022 18:23:05 +0100 Subject: [PATCH 11/14] Make wired pins component optional on the storage --- src/js/game/systems/storage.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/js/game/systems/storage.js b/src/js/game/systems/storage.js index cd204448..20204a89 100644 --- a/src/js/game/systems/storage.js +++ b/src/js/game/systems/storage.js @@ -50,8 +50,13 @@ export class StorageSystem extends GameSystemWithFilter { let targetAlpha = storageComp.storedCount > 0 ? 1 : 0; storageComp.overlayOpacity = lerp(storageComp.overlayOpacity, targetAlpha, 0.05); - pinsComp.slots[0].value = storageComp.storedItem; - pinsComp.slots[1].value = storageComp.getIsFull() ? BOOL_TRUE_SINGLETON : BOOL_FALSE_SINGLETON; + // a wired pins component is not guaranteed, but if its there, set the value + if (pinsComp) { + pinsComp.slots[0].value = storageComp.storedItem; + pinsComp.slots[1].value = storageComp.getIsFull() + ? BOOL_TRUE_SINGLETON + : BOOL_FALSE_SINGLETON; + } } } From 509c01f64280aef587633590102cbe55bcfe2e7e Mon Sep 17 00:00:00 2001 From: tobspr Date: Sat, 22 Jan 2022 22:04:49 +0100 Subject: [PATCH 12/14] Fix mod examples --- mod_examples/add_building_basic.js | 2 +- mod_examples/add_building_flipper.js | 2 +- mod_examples/base.js | 2 +- mod_examples/buildings_have_cost.js | 2 +- mod_examples/class_extensions.js | 2 +- mod_examples/custom_css.js | 2 +- mod_examples/custom_drawing.js | 2 +- mod_examples/custom_keybinding.js | 2 +- mod_examples/custom_sub_shapes.js | 2 +- mod_examples/custom_theme.js | 2 +- mod_examples/mod_settings.js | 2 +- mod_examples/modify_existing_building.js | 2 +- mod_examples/modify_theme.js | 2 +- mod_examples/modify_ui.js | 2 +- mod_examples/new_item_type.js | 2 +- mod_examples/notification_blocks.js | 2 +- mod_examples/pasting.js | 2 +- mod_examples/replace_builtin_sprites.js | 2 +- mod_examples/sandbox.js | 2 +- mod_examples/translations.js | 2 +- mod_examples/usage_statistics.js | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) diff --git a/mod_examples/add_building_basic.js b/mod_examples/add_building_basic.js index 4f834bc2..6b92e769 100644 --- a/mod_examples/add_building_basic.js +++ b/mod_examples/add_building_basic.js @@ -6,7 +6,7 @@ const METADATA = { version: "1", id: "add-building-basic", description: "Shows how to add a new basic building", - minimumGameVersion: "^1.5.0", + minimumGameVersion: ">=1.5.0", }; class MetaDemoModBuilding extends shapez.ModMetaBuilding { diff --git a/mod_examples/add_building_flipper.js b/mod_examples/add_building_flipper.js index 670f012a..03442499 100644 --- a/mod_examples/add_building_flipper.js +++ b/mod_examples/add_building_flipper.js @@ -7,7 +7,7 @@ const METADATA = { id: "add-building-extended", description: "Shows how to add a new building with logic, in this case it flips/mirrors shapez from top to down", - minimumGameVersion: "^1.5.0", + minimumGameVersion: ">=1.5.0", }; // Declare a new type of item processor diff --git a/mod_examples/base.js b/mod_examples/base.js index 9810e823..09e12f61 100644 --- a/mod_examples/base.js +++ b/mod_examples/base.js @@ -6,7 +6,7 @@ const METADATA = { version: "1", id: "base", description: "The most basic mod", - minimumGameVersion: "^1.5.0", + minimumGameVersion: ">=1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/buildings_have_cost.js b/mod_examples/buildings_have_cost.js index 04d1e14e..3dae84ae 100644 --- a/mod_examples/buildings_have_cost.js +++ b/mod_examples/buildings_have_cost.js @@ -6,7 +6,7 @@ const METADATA = { version: "1", id: "patch-methods", description: "Shows how to patch existing methods to change the game by making the belts cost shapes", - minimumGameVersion: "^1.5.0", + minimumGameVersion: ">=1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/class_extensions.js b/mod_examples/class_extensions.js index 904a5a03..8647fd45 100644 --- a/mod_examples/class_extensions.js +++ b/mod_examples/class_extensions.js @@ -6,7 +6,7 @@ const METADATA = { version: "1", id: "class-extensions", description: "Shows how to extend builtin classes", - minimumGameVersion: "^1.5.0", + minimumGameVersion: ">=1.5.0", }; const BeltExtension = ({ $super, $old }) => ({ diff --git a/mod_examples/custom_css.js b/mod_examples/custom_css.js index 2df83afd..dce316c5 100644 --- a/mod_examples/custom_css.js +++ b/mod_examples/custom_css.js @@ -6,7 +6,7 @@ const METADATA = { version: "1", id: "custom-css", description: "Shows how to add custom css", - minimumGameVersion: "^1.5.0", + minimumGameVersion: ">=1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/custom_drawing.js b/mod_examples/custom_drawing.js index f491b94b..e1c25b30 100644 --- a/mod_examples/custom_drawing.js +++ b/mod_examples/custom_drawing.js @@ -6,7 +6,7 @@ const METADATA = { version: "1", id: "base", description: "Displays an indicator on every item processing building when its working", - minimumGameVersion: "^1.5.0", + minimumGameVersion: ">=1.5.0", }; class ItemProcessorStatusGameSystem extends shapez.GameSystem { diff --git a/mod_examples/custom_keybinding.js b/mod_examples/custom_keybinding.js index 46ef71a6..0a6b11fc 100644 --- a/mod_examples/custom_keybinding.js +++ b/mod_examples/custom_keybinding.js @@ -6,7 +6,7 @@ const METADATA = { version: "1", id: "base", description: "Shows how to add a new keybinding", - minimumGameVersion: "^1.5.0", + minimumGameVersion: ">=1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/custom_sub_shapes.js b/mod_examples/custom_sub_shapes.js index 906e3c9b..3aea03cf 100644 --- a/mod_examples/custom_sub_shapes.js +++ b/mod_examples/custom_sub_shapes.js @@ -6,7 +6,7 @@ const METADATA = { version: "1", id: "custom-sub-shapes", description: "Shows how to add custom sub shapes", - minimumGameVersion: "^1.5.0", + minimumGameVersion: ">=1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/custom_theme.js b/mod_examples/custom_theme.js index 400e3b7c..cc4c9de8 100644 --- a/mod_examples/custom_theme.js +++ b/mod_examples/custom_theme.js @@ -6,7 +6,7 @@ const METADATA = { version: "1", id: "custom-theme", description: "Shows how to add a custom game theme", - minimumGameVersion: "^1.5.0", + minimumGameVersion: ">=1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/mod_settings.js b/mod_examples/mod_settings.js index 873468c4..b87c138b 100644 --- a/mod_examples/mod_settings.js +++ b/mod_examples/mod_settings.js @@ -6,7 +6,7 @@ const METADATA = { version: "1", id: "mod-settings", description: "Shows how to add settings to your mod", - minimumGameVersion: "^1.5.0", + minimumGameVersion: ">=1.5.0", settings: { timesLaunched: 0, diff --git a/mod_examples/modify_existing_building.js b/mod_examples/modify_existing_building.js index c88fad7e..b09f5a20 100644 --- a/mod_examples/modify_existing_building.js +++ b/mod_examples/modify_existing_building.js @@ -6,7 +6,7 @@ const METADATA = { version: "1", id: "modify-existing-building", description: "Shows how to modify an existing building", - minimumGameVersion: "^1.5.0", + minimumGameVersion: ">=1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/modify_theme.js b/mod_examples/modify_theme.js index 8a7f4318..4bc9be34 100644 --- a/mod_examples/modify_theme.js +++ b/mod_examples/modify_theme.js @@ -6,7 +6,7 @@ const METADATA = { version: "1", id: "modify-theme", description: "Shows how to modify builtin themes", - minimumGameVersion: "^1.5.0", + minimumGameVersion: ">=1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/modify_ui.js b/mod_examples/modify_ui.js index ef8d2455..0b2d1341 100644 --- a/mod_examples/modify_ui.js +++ b/mod_examples/modify_ui.js @@ -6,7 +6,7 @@ const METADATA = { version: "1", id: "modify-ui", description: "Shows how to modify a builtin game state, in this case the main menu", - minimumGameVersion: "^1.5.0", + minimumGameVersion: ">=1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/new_item_type.js b/mod_examples/new_item_type.js index a9fa30ca..3cd52cef 100644 --- a/mod_examples/new_item_type.js +++ b/mod_examples/new_item_type.js @@ -6,7 +6,7 @@ const METADATA = { version: "1", id: "new-item-type", description: "Shows how to add a new item type (fluid)", - minimumGameVersion: "^1.5.0", + minimumGameVersion: ">=1.5.0", }; // Define which fluid types there are diff --git a/mod_examples/notification_blocks.js b/mod_examples/notification_blocks.js index 4d8cf476..23f95943 100644 --- a/mod_examples/notification_blocks.js +++ b/mod_examples/notification_blocks.js @@ -8,7 +8,7 @@ const METADATA = { description: "Adds a new building to the wires layer, 'Notification Blocks' which show a custom notification when they get a truthy signal.", - minimumGameVersion: "^1.5.0", + minimumGameVersion: ">=1.5.0", }; //////////////////////////////////////////////////////////////////////// diff --git a/mod_examples/pasting.js b/mod_examples/pasting.js index b514f137..698edeff 100644 --- a/mod_examples/pasting.js +++ b/mod_examples/pasting.js @@ -6,7 +6,7 @@ const METADATA = { version: "1", id: "pasting", description: "Shows how to properly receive paste events ingame", - minimumGameVersion: "^1.5.0", + minimumGameVersion: ">=1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/replace_builtin_sprites.js b/mod_examples/replace_builtin_sprites.js index d0407692..885846e7 100644 --- a/mod_examples/replace_builtin_sprites.js +++ b/mod_examples/replace_builtin_sprites.js @@ -6,7 +6,7 @@ const METADATA = { version: "1", id: "replace-builtin-sprites", description: "Shows how to replace builtin sprites", - minimumGameVersion: "^1.5.0", + minimumGameVersion: ">=1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/sandbox.js b/mod_examples/sandbox.js index d57e1e0e..f405ab59 100644 --- a/mod_examples/sandbox.js +++ b/mod_examples/sandbox.js @@ -6,7 +6,7 @@ const METADATA = { version: "1", id: "sandbox", description: "Blueprints are always unlocked and cost no money, also all buildings are unlocked", - minimumGameVersion: "^1.5.0", + minimumGameVersion: ">=1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/translations.js b/mod_examples/translations.js index 080be45c..2f3a4015 100644 --- a/mod_examples/translations.js +++ b/mod_examples/translations.js @@ -6,7 +6,7 @@ const METADATA = { version: "1", id: "translations", description: "Shows how to add and modify translations", - minimumGameVersion: "^1.5.0", + minimumGameVersion: ">=1.5.0", }; class Mod extends shapez.Mod { diff --git a/mod_examples/usage_statistics.js b/mod_examples/usage_statistics.js index 1412e4dd..64da102b 100644 --- a/mod_examples/usage_statistics.js +++ b/mod_examples/usage_statistics.js @@ -8,7 +8,7 @@ const METADATA = { description: "Shows how to add a new component to the game, how to save additional data and how to add custom logic and drawings", - minimumGameVersion: "^1.5.0", + minimumGameVersion: ">=1.5.0", }; /** From 8dcb5faf5f7562ed646c1bcec8f74e44f9427c9a Mon Sep 17 00:00:00 2001 From: Bagel03 <70449196+Bagel03@users.noreply.github.com> Date: Sun, 23 Jan 2022 11:14:03 -0500 Subject: [PATCH 13/14] Bind `this` for method overriding JSDoc (#1352) --- src/js/mods/mod_interface.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/js/mods/mod_interface.js b/src/js/mods/mod_interface.js index e3b9e59b..195c005b 100644 --- a/src/js/mods/mod_interface.js +++ b/src/js/mods/mod_interface.js @@ -31,6 +31,12 @@ import { BaseHUDPart } from "../game/hud/base_hud_part"; * @typedef {{new(...args: any[]): any, prototype: any}} constructable */ +/** + * @template {(...args: any) => any} F The function + * @template {object} T The value of this + * @typedef {(this: T, ...args: Parameters) => ReturnType} bindThis + */ + /** * @template {(...args: any[]) => any} F * @template P @@ -400,7 +406,7 @@ export class ModInterface { * @template {extendsPrams} O the method that will override the old one * @param {C} classHandle * @param {M} methodName - * @param {beforePrams} override + * @param {bindThis, InstanceType>} override */ replaceMethod(classHandle, methodName, override) { const oldMethod = classHandle.prototype[methodName]; @@ -418,7 +424,7 @@ export class ModInterface { * @template {extendsPrams} O the method that will run before the old one * @param {C} classHandle * @param {M} methodName - * @param {O} executeBefore + * @param {bindThis>} executeBefore */ runBeforeMethod(classHandle, methodName, executeBefore) { const oldHandle = classHandle.prototype[methodName]; @@ -437,7 +443,7 @@ export class ModInterface { * @template {extendsPrams} O the method that will run before the old one * @param {C} classHandle * @param {M} methodName - * @param {O} executeAfter + * @param {bindThis>} executeAfter */ runAfterMethod(classHandle, methodName, executeAfter) { const oldHandle = classHandle.prototype[methodName]; From 431453f1a2db1977bd5b50ffc6c9cdb366111d4e Mon Sep 17 00:00:00 2001 From: Emerald Block <69981203+EmeraldBlock@users.noreply.github.com> Date: Sun, 23 Jan 2022 10:14:24 -0600 Subject: [PATCH 14/14] fix entity debugger reaching HTML elements (#1353) --- src/js/game/hud/parts/entity_debugger.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/js/game/hud/parts/entity_debugger.js b/src/js/game/hud/parts/entity_debugger.js index 640ad4d6..debd456d 100644 --- a/src/js/game/hud/parts/entity_debugger.js +++ b/src/js/game/hud/parts/entity_debugger.js @@ -94,11 +94,12 @@ export class HUDEntityDebugger extends BaseHUDPart {
`; for (const property in val) { - const isRoot = val[property] == this.root; - const isRecursive = recursion.includes(val[property]); - - let hiddenValue = isRoot ? "" : null; - if (isRecursive) { + let hiddenValue = null; + if (val[property] == this.root) { + hiddenValue = ""; + } else if (val[property] instanceof Node) { + hiddenValue = `<${val[property].constructor.name}>`; + } else if (recursion.includes(val[property])) { // Avoid recursion by not "expanding" object more than once hiddenValue = ""; }