diff --git a/src/js/core/sprites.js b/src/js/core/sprites.js index 4251bee1..2140bad4 100644 --- a/src/js/core/sprites.js +++ b/src/js/core/sprites.js @@ -144,9 +144,9 @@ export class AtlasSprite extends BaseSprite { */ drawCached(parameters, x, y, w = null, h = null, clipping = true) { if (G_IS_DEV) { - assertAlways(parameters instanceof DrawParameters, "Not a valid context"); - assertAlways(!!w && w > 0, "Not a valid width:" + w); - assertAlways(!!h && h > 0, "Not a valid height:" + h); + assert(parameters instanceof DrawParameters, "Not a valid context"); + assert(!!w && w > 0, "Not a valid width:" + w); + assert(!!h && h > 0, "Not a valid height:" + h); } const visibleRect = parameters.visibleRect; diff --git a/src/js/game/base_item.js b/src/js/game/base_item.js index e70263df..7f01d6ce 100644 --- a/src/js/game/base_item.js +++ b/src/js/game/base_item.js @@ -1,6 +1,11 @@ import { DrawParameters } from "../core/draw_parameters"; -import { BasicSerializableObject, types } from "../savegame/serialization"; -import { THEME } from "./theme"; +import { BasicSerializableObject } from "../savegame/serialization"; + +/** @enum {string} */ +export const enumItemType = { + shape: "shape", + color: "color", +}; /** * Class for items on belts etc. Not an entity for performance reasons @@ -19,6 +24,12 @@ export class BaseItem extends BasicSerializableObject { return {}; } + /** @returns {enumItemType} */ + getItemType() { + abstract; + return ""; + } + /** * Draws the item at the given position * @param {number} x diff --git a/src/js/game/belt_path.js b/src/js/game/belt_path.js index 9cc2c88d..4e984606 100644 --- a/src/js/game/belt_path.js +++ b/src/js/game/belt_path.js @@ -82,7 +82,9 @@ export class BeltPath extends BasicSerializableObject { this.init(); - this.debug_checkIntegrity("constructor"); + if (G_IS_DEV && globalConfig.debug.checkBeltPaths) { + this.debug_checkIntegrity("constructor"); + } } /** * Initializes the path by computing the properties which are not saved @@ -168,6 +170,9 @@ export class BeltPath extends BasicSerializableObject { } } + // Following code will be compiled out outside of dev versions + /* dev:start */ + /** * Helper to throw an error on mismatch * @param {string} change @@ -181,10 +186,6 @@ export class BeltPath extends BasicSerializableObject { * Checks if this path is valid */ debug_checkIntegrity(currentChange = "change") { - if (!G_IS_DEV) { - return; - } - const fail = (...args) => this.debug_failIntegrity(currentChange, ...args); // Check for empty path @@ -319,6 +320,8 @@ export class BeltPath extends BasicSerializableObject { } } + /* dev:end */ + /** * Extends the belt path by the given belt * @param {Entity} entity @@ -368,7 +371,9 @@ export class BeltPath extends BasicSerializableObject { // Update bounds this.worldBounds = this.computeBounds(); - this.debug_checkIntegrity("extend-on-end"); + if (G_IS_DEV && globalConfig.debug.checkBeltPaths) { + this.debug_checkIntegrity("extend-on-end"); + } } /** @@ -398,7 +403,9 @@ export class BeltPath extends BasicSerializableObject { // Update bounds this.worldBounds = this.computeBounds(); - this.debug_checkIntegrity("extend-on-begin"); + if (G_IS_DEV && globalConfig.debug.checkBeltPaths) { + this.debug_checkIntegrity("extend-on-begin"); + } } /** @@ -574,8 +581,10 @@ export class BeltPath extends BasicSerializableObject { // Update bounds this.worldBounds = this.computeBounds(); - this.debug_checkIntegrity("split-two-first"); - secondPath.debug_checkIntegrity("split-two-second"); + if (G_IS_DEV && globalConfig.debug.checkBeltPaths) { + this.debug_checkIntegrity("split-two-first"); + secondPath.debug_checkIntegrity("split-two-second"); + } return secondPath; } @@ -683,7 +692,9 @@ export class BeltPath extends BasicSerializableObject { // Update bounds this.worldBounds = this.computeBounds(); - this.debug_checkIntegrity("delete-on-end"); + if (G_IS_DEV && globalConfig.debug.checkBeltPaths) { + this.debug_checkIntegrity("delete-on-end"); + } } /** @@ -810,7 +821,9 @@ export class BeltPath extends BasicSerializableObject { // Update bounds this.worldBounds = this.computeBounds(); - this.debug_checkIntegrity("delete-on-start"); + if (G_IS_DEV && globalConfig.debug.checkBeltPaths) { + this.debug_checkIntegrity("delete-on-start"); + } } /** @@ -882,7 +895,9 @@ export class BeltPath extends BasicSerializableObject { this.onPathChanged(); - this.debug_checkIntegrity("extend-by-path"); + if (G_IS_DEV && globalConfig.debug.checkBeltPaths) { + this.debug_checkIntegrity("extend-by-path"); + } } /** @@ -901,7 +916,9 @@ export class BeltPath extends BasicSerializableObject { * Performs one tick */ update() { - this.debug_checkIntegrity("pre-update"); + if (G_IS_DEV && globalConfig.debug.checkBeltPaths) { + this.debug_checkIntegrity("pre-update"); + } // Divide by item spacing on belts since we use throughput and not speed let beltSpeed = @@ -945,7 +962,9 @@ export class BeltPath extends BasicSerializableObject { } } - this.debug_checkIntegrity("post-update"); + if (G_IS_DEV && globalConfig.debug.checkBeltPaths) { + this.debug_checkIntegrity("post-update"); + } } /** diff --git a/src/js/game/buildings/cutter.js b/src/js/game/buildings/cutter.js index a9433390..bfe142d5 100644 --- a/src/js/game/buildings/cutter.js +++ b/src/js/game/buildings/cutter.js @@ -1,14 +1,14 @@ -import { globalConfig } from "../../core/config"; +import { formatItemsPerSecond } from "../../core/utils"; import { enumDirection, Vector } from "../../core/vector"; -import { enumItemAcceptorItemFilter, ItemAcceptorComponent } from "../components/item_acceptor"; +import { T } from "../../translations"; +import { ItemAcceptorComponent } from "../components/item_acceptor"; import { ItemEjectorComponent } from "../components/item_ejector"; import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor"; import { Entity } from "../entity"; -import { MetaBuilding, defaultBuildingVariant } from "../meta_building"; +import { defaultBuildingVariant, MetaBuilding } from "../meta_building"; import { GameRoot } from "../root"; import { enumHubGoalRewards } from "../tutorial_goals"; -import { T } from "../../translations"; -import { formatItemsPerSecond } from "../../core/utils"; +import { enumItemType } from "../base_item"; /** @enum {string} */ export const enumCutterVariants = { quad: "quad" }; @@ -82,7 +82,7 @@ export class MetaCutterBuilding extends MetaBuilding { { pos: new Vector(0, 0), directions: [enumDirection.bottom], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, ], }) diff --git a/src/js/game/buildings/energy_generator.js b/src/js/game/buildings/energy_generator.js index 47502ce6..24c6f90c 100644 --- a/src/js/game/buildings/energy_generator.js +++ b/src/js/game/buildings/energy_generator.js @@ -1,11 +1,12 @@ import { enumDirection, Vector } from "../../core/vector"; -import { ItemAcceptorComponent, enumItemAcceptorItemFilter } from "../components/item_acceptor"; +import { ItemAcceptorComponent } from "../components/item_acceptor"; import { Entity } from "../entity"; import { MetaBuilding } from "../meta_building"; import { GameRoot } from "../root"; import { enumHubGoalRewards } from "../tutorial_goals"; import { EnergyGeneratorComponent } from "../components/energy_generator"; import { WiredPinsComponent, enumPinSlotType } from "../components/wired_pins"; +import { enumItemType } from "../base_item"; export class MetaEnergyGenerator extends MetaBuilding { constructor() { @@ -52,23 +53,23 @@ export class MetaEnergyGenerator extends MetaBuilding { { pos: new Vector(0, 0), directions: [enumDirection.top], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(1, 0), directions: [enumDirection.top], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(0, 1), directions: [enumDirection.bottom], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(1, 1), directions: [enumDirection.bottom], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, ], }) diff --git a/src/js/game/buildings/hub.js b/src/js/game/buildings/hub.js index 49d95005..61a61f27 100644 --- a/src/js/game/buildings/hub.js +++ b/src/js/game/buildings/hub.js @@ -1,11 +1,11 @@ import { enumDirection, Vector } from "../../core/vector"; -import { enumItemAcceptorItemFilter, ItemAcceptorComponent } from "../components/item_acceptor"; +import { enumItemType } from "../base_item"; +import { HubComponent } from "../components/hub"; +import { ItemAcceptorComponent } from "../components/item_acceptor"; +import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor"; +import { UnremovableComponent } from "../components/unremovable"; import { Entity } from "../entity"; import { MetaBuilding } from "../meta_building"; -import { ItemProcessorComponent, enumItemProcessorTypes } from "../components/item_processor"; -import { globalConfig } from "../../core/config"; -import { UnremovableComponent } from "../components/unremovable"; -import { HubComponent } from "../components/hub"; export class MetaHubBuilding extends MetaBuilding { constructor() { @@ -51,72 +51,72 @@ export class MetaHubBuilding extends MetaBuilding { { pos: new Vector(0, 0), directions: [enumDirection.top, enumDirection.left], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(1, 0), directions: [enumDirection.top], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(2, 0), directions: [enumDirection.top], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(3, 0), directions: [enumDirection.top, enumDirection.right], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(0, 3), directions: [enumDirection.bottom, enumDirection.left], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(1, 3), directions: [enumDirection.bottom], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(2, 3), directions: [enumDirection.bottom], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(3, 3), directions: [enumDirection.bottom, enumDirection.right], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(0, 1), directions: [enumDirection.left], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(0, 2), directions: [enumDirection.left], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(0, 3), directions: [enumDirection.left], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(3, 1), directions: [enumDirection.right], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(3, 2), directions: [enumDirection.right], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(3, 3), directions: [enumDirection.right], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, ], }) diff --git a/src/js/game/buildings/mixer.js b/src/js/game/buildings/mixer.js index a20bff82..a2b35280 100644 --- a/src/js/game/buildings/mixer.js +++ b/src/js/game/buildings/mixer.js @@ -1,14 +1,14 @@ -import { globalConfig } from "../../core/config"; +import { formatItemsPerSecond } from "../../core/utils"; import { enumDirection, Vector } from "../../core/vector"; -import { ItemAcceptorComponent, enumItemAcceptorItemFilter } from "../components/item_acceptor"; +import { T } from "../../translations"; +import { enumItemType } from "../base_item"; +import { ItemAcceptorComponent } from "../components/item_acceptor"; import { ItemEjectorComponent } from "../components/item_ejector"; import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor"; import { Entity } from "../entity"; import { MetaBuilding } from "../meta_building"; import { GameRoot } from "../root"; import { enumHubGoalRewards } from "../tutorial_goals"; -import { T } from "../../translations"; -import { formatItemsPerSecond } from "../../core/utils"; export class MetaMixerBuilding extends MetaBuilding { constructor() { @@ -63,12 +63,12 @@ export class MetaMixerBuilding extends MetaBuilding { { pos: new Vector(0, 0), directions: [enumDirection.bottom], - filter: enumItemAcceptorItemFilter.color, + filter: enumItemType.color, }, { pos: new Vector(1, 0), directions: [enumDirection.bottom], - filter: enumItemAcceptorItemFilter.color, + filter: enumItemType.color, }, ], }) diff --git a/src/js/game/buildings/painter.js b/src/js/game/buildings/painter.js index 835dde1e..61e77a7c 100644 --- a/src/js/game/buildings/painter.js +++ b/src/js/game/buildings/painter.js @@ -1,14 +1,14 @@ -import { globalConfig } from "../../core/config"; +import { formatItemsPerSecond } from "../../core/utils"; import { enumDirection, Vector } from "../../core/vector"; -import { enumItemAcceptorItemFilter, ItemAcceptorComponent } from "../components/item_acceptor"; +import { T } from "../../translations"; +import { ItemAcceptorComponent } from "../components/item_acceptor"; import { ItemEjectorComponent } from "../components/item_ejector"; import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor"; import { Entity } from "../entity"; -import { MetaBuilding, defaultBuildingVariant } from "../meta_building"; -import { enumHubGoalRewards } from "../tutorial_goals"; +import { defaultBuildingVariant, MetaBuilding } from "../meta_building"; import { GameRoot } from "../root"; -import { T } from "../../translations"; -import { formatItemsPerSecond } from "../../core/utils"; +import { enumHubGoalRewards } from "../tutorial_goals"; +import { enumItemType } from "../base_item"; /** @enum {string} */ export const enumPainterVariants = { mirrored: "mirrored", double: "double", quad: "quad" }; @@ -98,12 +98,12 @@ export class MetaPainterBuilding extends MetaBuilding { { pos: new Vector(0, 0), directions: [enumDirection.left], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(1, 0), directions: [enumDirection.top], - filter: enumItemAcceptorItemFilter.color, + filter: enumItemType.color, }, ], }) @@ -124,14 +124,14 @@ export class MetaPainterBuilding extends MetaBuilding { { pos: new Vector(0, 0), directions: [enumDirection.left], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(1, 0), directions: [ variant === defaultBuildingVariant ? enumDirection.top : enumDirection.bottom, ], - filter: enumItemAcceptorItemFilter.color, + filter: enumItemType.color, }, ]); @@ -147,17 +147,17 @@ export class MetaPainterBuilding extends MetaBuilding { { pos: new Vector(0, 0), directions: [enumDirection.left], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(0, 1), directions: [enumDirection.left], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(1, 0), directions: [enumDirection.top], - filter: enumItemAcceptorItemFilter.color, + filter: enumItemType.color, }, ]); @@ -174,27 +174,27 @@ export class MetaPainterBuilding extends MetaBuilding { { pos: new Vector(0, 0), directions: [enumDirection.left], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(0, 0), directions: [enumDirection.bottom], - filter: enumItemAcceptorItemFilter.color, + filter: enumItemType.color, }, { pos: new Vector(1, 0), directions: [enumDirection.bottom], - filter: enumItemAcceptorItemFilter.color, + filter: enumItemType.color, }, { pos: new Vector(2, 0), directions: [enumDirection.bottom], - filter: enumItemAcceptorItemFilter.color, + filter: enumItemType.color, }, { pos: new Vector(3, 0), directions: [enumDirection.bottom], - filter: enumItemAcceptorItemFilter.color, + filter: enumItemType.color, }, ]); diff --git a/src/js/game/buildings/rotater.js b/src/js/game/buildings/rotater.js index abd3f2c2..56c0c87d 100644 --- a/src/js/game/buildings/rotater.js +++ b/src/js/game/buildings/rotater.js @@ -1,14 +1,14 @@ -import { globalConfig } from "../../core/config"; +import { formatItemsPerSecond } from "../../core/utils"; import { enumDirection, Vector } from "../../core/vector"; -import { ItemAcceptorComponent, enumItemAcceptorItemFilter } from "../components/item_acceptor"; +import { T } from "../../translations"; +import { ItemAcceptorComponent } from "../components/item_acceptor"; import { ItemEjectorComponent } from "../components/item_ejector"; import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor"; import { Entity } from "../entity"; -import { MetaBuilding, defaultBuildingVariant } from "../meta_building"; -import { enumHubGoalRewards } from "../tutorial_goals"; +import { defaultBuildingVariant, MetaBuilding } from "../meta_building"; import { GameRoot } from "../root"; -import { T } from "../../translations"; -import { formatItemsPerSecond } from "../../core/utils"; +import { enumHubGoalRewards } from "../tutorial_goals"; +import { enumItemType } from "../base_item"; /** @enum {string} */ export const enumRotaterVariants = { ccw: "ccw" }; @@ -77,7 +77,7 @@ export class MetaRotaterBuilding extends MetaBuilding { { pos: new Vector(0, 0), directions: [enumDirection.bottom], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, ], }) diff --git a/src/js/game/buildings/stacker.js b/src/js/game/buildings/stacker.js index 9b6f5ef3..91ac3f62 100644 --- a/src/js/game/buildings/stacker.js +++ b/src/js/game/buildings/stacker.js @@ -1,14 +1,14 @@ -import { globalConfig } from "../../core/config"; +import { formatItemsPerSecond } from "../../core/utils"; import { enumDirection, Vector } from "../../core/vector"; -import { ItemAcceptorComponent, enumItemAcceptorItemFilter } from "../components/item_acceptor"; +import { T } from "../../translations"; +import { ItemAcceptorComponent } from "../components/item_acceptor"; import { ItemEjectorComponent } from "../components/item_ejector"; import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor"; import { Entity } from "../entity"; import { MetaBuilding } from "../meta_building"; import { GameRoot } from "../root"; import { enumHubGoalRewards } from "../tutorial_goals"; -import { formatItemsPerSecond } from "../../core/utils"; -import { T } from "../../translations"; +import { enumItemType } from "../base_item"; export class MetaStackerBuilding extends MetaBuilding { constructor() { @@ -63,12 +63,12 @@ export class MetaStackerBuilding extends MetaBuilding { { pos: new Vector(0, 0), directions: [enumDirection.bottom], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, { pos: new Vector(1, 0), directions: [enumDirection.bottom], - filter: enumItemAcceptorItemFilter.shape, + filter: enumItemType.shape, }, ], }) diff --git a/src/js/game/components/energy_generator.js b/src/js/game/components/energy_generator.js index 37e5dd6a..41b6ec35 100644 --- a/src/js/game/components/energy_generator.js +++ b/src/js/game/components/energy_generator.js @@ -37,12 +37,7 @@ export class EnergyGeneratorComponent extends Component { * @param {BaseItem} item */ tryTakeItem(item) { - if (!(item instanceof ShapeItem)) { - // Not a shape - return false; - } - - if (item.definition.getHash() !== this.requiredKey) { + if (/** @type {ShapeItem} */ (item).definition.getHash() !== this.requiredKey) { // Not our shape return false; } diff --git a/src/js/game/components/item_acceptor.js b/src/js/game/components/item_acceptor.js index 6f3895aa..72680e08 100644 --- a/src/js/game/components/item_acceptor.js +++ b/src/js/game/components/item_acceptor.js @@ -1,23 +1,12 @@ -import { Component } from "../component"; -import { Vector, enumDirection, enumInvertedDirections } from "../../core/vector"; -import { BaseItem } from "../base_item"; -import { ShapeItem } from "../items/shape_item"; -import { ColorItem } from "../items/color_item"; +import { enumDirection, enumInvertedDirections, Vector } from "../../core/vector"; import { types } from "../../savegame/serialization"; - -/** - * @enum {string?} - */ -export const enumItemAcceptorItemFilter = { - shape: "shape", - color: "color", - none: null, -}; +import { BaseItem, enumItemType } from "../base_item"; +import { Component } from "../component"; /** @typedef {{ * pos: Vector, * directions: enumDirection[], - * filter?: enumItemAcceptorItemFilter + * filter?: enumItemType * }} ItemAcceptorSlot */ /** @@ -39,7 +28,7 @@ export class ItemAcceptorComponent extends Component { types.structured({ pos: types.vector, directions: types.array(types.enum(enumDirection)), - filter: types.nullable(types.enum(enumItemAcceptorItemFilter)), + filter: types.nullable(types.enum(enumItemType)), }) ), animated: types.bool, @@ -49,16 +38,6 @@ export class ItemAcceptorComponent extends Component { direction: types.enum(enumDirection), }) ), - - // We don't actually need to store the animations - // itemConsumptionAnimations: types.array( - // types.structured({ - // item: types.obj(gItemRegistry), - // slotIndex: types.uint, - // animProgress: types.float, - // direction: types.enum(enumDirection), - // }) - // ), }; } @@ -92,7 +71,7 @@ export class ItemAcceptorComponent extends Component { /** * * @param {object} param0 - * @param {Array<{pos: Vector, directions: enumDirection[], filter?: enumItemAcceptorItemFilter}>} param0.slots The slots from which we accept items + * @param {Array<{pos: Vector, directions: enumDirection[], filter?: enumItemType}>} param0.slots The slots from which we accept items * @param {boolean=} param0.animated Whether to animate item consumption * @param {Array<{pos: Vector, direction: enumDirection}>=} param0.beltUnderlays Where to render belt underlays */ @@ -115,10 +94,10 @@ export class ItemAcceptorComponent extends Component { /** * - * @param {Array<{pos: Vector, directions: enumDirection[], filter?: enumItemAcceptorItemFilter}>} slots + * @param {Array<{pos: Vector, directions: enumDirection[], filter?: enumItemType}>} slots */ setSlots(slots) { - /** @type {Array<{pos: Vector, directions: enumDirection[], filter?: enumItemAcceptorItemFilter}>} */ + /** @type {Array<{pos: Vector, directions: enumDirection[], filter?: enumItemType}>} */ this.slots = []; for (let i = 0; i < slots.length; ++i) { const slot = slots[i]; @@ -126,7 +105,7 @@ export class ItemAcceptorComponent extends Component { pos: slot.pos, directions: slot.directions, - // Which type of item to accept (shape | color | all) @see enumItemAcceptorItemFilter + // Which type of item to accept (shape | color | all) @see enumItemType filter: slot.filter, }); } @@ -139,16 +118,7 @@ export class ItemAcceptorComponent extends Component { */ canAcceptItem(slotIndex, item) { const slot = this.slots[slotIndex]; - switch (slot.filter) { - case enumItemAcceptorItemFilter.shape: { - return item instanceof ShapeItem; - } - case enumItemAcceptorItemFilter.color: { - return item instanceof ColorItem; - } - default: - return true; - } + return slot.filter === null || slot.filter === item.getItemType(); } /** diff --git a/src/js/game/components/storage.js b/src/js/game/components/storage.js index 69f4e367..e7b40a77 100644 --- a/src/js/game/components/storage.js +++ b/src/js/game/components/storage.js @@ -1,7 +1,7 @@ import { Component } from "../component"; import { types } from "../../savegame/serialization"; import { gItemRegistry } from "../../core/global_registries"; -import { BaseItem } from "../base_item"; +import { BaseItem, enumItemType } from "../base_item"; import { ColorItem } from "../items/color_item"; import { ShapeItem } from "../items/shape_item"; @@ -60,17 +60,23 @@ export class StorageComponent extends Component { return true; } - if (item instanceof ColorItem) { - return this.storedItem instanceof ColorItem && this.storedItem.color === item.color; + const itemType = item.getItemType(); + + // Check type matches + if (itemType !== this.storedItem.getItemType()) { + return false; } - if (item instanceof ShapeItem) { + if (itemType === enumItemType.color) { + return /** @type {ColorItem} */ (this.storedItem).color === /** @type {ColorItem} */ (item).color; + } + + if (itemType === enumItemType.shape) { return ( - this.storedItem instanceof ShapeItem && - this.storedItem.definition.getHash() === item.definition.getHash() + /** @type {ShapeItem} */ (this.storedItem).definition.getHash() === + /** @type {ShapeItem} */ (item).definition.getHash() ); } - return false; } diff --git a/src/js/game/hud/parts/color_blind_helper.js b/src/js/game/hud/parts/color_blind_helper.js index 7e79fa1e..2eaca6a9 100644 --- a/src/js/game/hud/parts/color_blind_helper.js +++ b/src/js/game/hud/parts/color_blind_helper.js @@ -7,6 +7,7 @@ import { DrawParameters } from "../../../core/draw_parameters"; import { THEME } from "../../theme"; import { globalConfig } from "../../../core/config"; import { T } from "../../../translations"; +import { enumItemType } from "../../base_item"; export class HUDColorBlindHelper extends BaseHUDPart { createElements(parent) { @@ -49,8 +50,8 @@ export class HUDColorBlindHelper extends BaseHUDPart { // Check if the belt has a color item if (beltComp) { const item = beltComp.assignedPath.findItemAtTile(tile); - if (item && item instanceof ColorItem) { - return item.color; + if (item && item.getItemType() === enumItemType.color) { + return /** @type {ColorItem} */ (item).color; } } @@ -59,16 +60,16 @@ export class HUDColorBlindHelper extends BaseHUDPart { if (ejectorComp) { for (let i = 0; i < ejectorComp.slots.length; ++i) { const slot = ejectorComp.slots[i]; - if (slot.item && slot.item instanceof ColorItem) { - return slot.item.color; + if (slot.item && slot.item.getItemType() === enumItemType.color) { + return /** @type {ColorItem} */ (slot.item).color; } } } } else { // We hovered a lower layer, show the color there const lowerLayer = this.root.map.getLowerLayerContentXY(tile.x, tile.y); - if (lowerLayer && lowerLayer instanceof ColorItem) { - return lowerLayer.color; + if (lowerLayer && lowerLayer.getItemType() === enumItemType.color) { + return /** @type {ColorItem} */ (lowerLayer).color; } } diff --git a/src/js/game/items/color_item.js b/src/js/game/items/color_item.js index b2a3cd74..d1b9a217 100644 --- a/src/js/game/items/color_item.js +++ b/src/js/game/items/color_item.js @@ -2,7 +2,7 @@ import { globalConfig } from "../../core/config"; import { smoothenDpi } from "../../core/dpi_manager"; import { DrawParameters } from "../../core/draw_parameters"; import { types } from "../../savegame/serialization"; -import { BaseItem } from "../base_item"; +import { BaseItem, enumItemType } from "../base_item"; import { enumColors, enumColorsToHexCode } from "../colors"; import { THEME } from "../theme"; @@ -23,6 +23,10 @@ export class ColorItem extends BaseItem { this.color = data; } + getItemType() { + return enumItemType.color; + } + /** * @param {enumColors} color */ diff --git a/src/js/game/items/shape_item.js b/src/js/game/items/shape_item.js index cfdb9830..2aca63f6 100644 --- a/src/js/game/items/shape_item.js +++ b/src/js/game/items/shape_item.js @@ -1,6 +1,6 @@ import { DrawParameters } from "../../core/draw_parameters"; import { types } from "../../savegame/serialization"; -import { BaseItem } from "../base_item"; +import { BaseItem, enumItemType } from "../base_item"; import { ShapeDefinition } from "../shape_definition"; import { THEME } from "../theme"; @@ -21,6 +21,10 @@ export class ShapeItem extends BaseItem { this.definition = ShapeDefinition.fromShortKey(data); } + getItemType() { + return enumItemType.shape; + } + /** * @param {ShapeDefinition} definition */ diff --git a/src/js/game/production_analytics.js b/src/js/game/production_analytics.js index 1abac940..41ec31ae 100644 --- a/src/js/game/production_analytics.js +++ b/src/js/game/production_analytics.js @@ -1,7 +1,7 @@ import { GameRoot } from "./root"; import { ShapeDefinition } from "./shape_definition"; import { globalConfig } from "../core/config"; -import { BaseItem } from "./base_item"; +import { BaseItem, enumItemType } from "./base_item"; import { ShapeItem } from "./items/shape_item"; import { BasicSerializableObject } from "../savegame/serialization"; @@ -53,8 +53,8 @@ export class ProductionAnalytics extends BasicSerializableObject { * @param {BaseItem} item */ onItemProduced(item) { - if (item instanceof ShapeItem) { - const definition = item.definition; + if (item.getItemType() === enumItemType.shape) { + const definition = /** @type {ShapeItem} */ (item).definition; const key = definition.getHash(); const entry = this.history[enumAnalyticsDataSource.produced]; entry[entry.length - 1][key] = (entry[entry.length - 1][key] || 0) + 1; diff --git a/src/js/game/systems/belt.js b/src/js/game/systems/belt.js index 75d777f0..5af34ef2 100644 --- a/src/js/game/systems/belt.js +++ b/src/js/game/systems/belt.js @@ -102,7 +102,9 @@ export class BeltSystem extends GameSystemWithFilter { logger.warn("Restored", this.beltPaths.length, "belt paths"); } - this.verifyBeltPaths(); + if (G_IS_DEV && globalConfig.debug.checkBeltPaths) { + this.debug_verifyBeltPaths(); + } } /** @@ -171,12 +173,16 @@ export class BeltSystem extends GameSystemWithFilter { this.addEntityToPaths(targetEntity); // Sanity - this.verifyBeltPaths(); + if (G_IS_DEV && globalConfig.debug.checkBeltPaths) { + this.debug_verifyBeltPaths(); + } } } } - this.verifyBeltPaths(); + if (G_IS_DEV && globalConfig.debug.checkBeltPaths) { + this.debug_verifyBeltPaths(); + } } /** @@ -195,7 +201,9 @@ export class BeltSystem extends GameSystemWithFilter { const assignedPath = entity.components.Belt.assignedPath; assert(assignedPath, "Entity has no belt path assigned"); this.deleteEntityFromPath(assignedPath, entity); - this.verifyBeltPaths(); + if (G_IS_DEV && globalConfig.debug.checkBeltPaths) { + this.debug_verifyBeltPaths(); + } } /** @@ -281,7 +289,9 @@ export class BeltSystem extends GameSystemWithFilter { } this.addEntityToPaths(entity); - this.verifyBeltPaths(); + if (G_IS_DEV && globalConfig.debug.checkBeltPaths) { + this.debug_verifyBeltPaths(); + } } /** @@ -297,21 +307,19 @@ export class BeltSystem extends GameSystemWithFilter { /** * Verifies all belt paths */ - verifyBeltPaths() { - if (G_IS_DEV && true) { - for (let i = 0; i < this.beltPaths.length; ++i) { - this.beltPaths[i].debug_checkIntegrity("general-verify"); - } + debug_verifyBeltPaths() { + for (let i = 0; i < this.beltPaths.length; ++i) { + this.beltPaths[i].debug_checkIntegrity("general-verify"); + } - const belts = this.root.entityMgr.getAllWithComponent(BeltComponent); - for (let i = 0; i < belts.length; ++i) { - const path = belts[i].components.Belt.assignedPath; - if (!path) { - throw new Error("Belt has no path: " + belts[i].uid); - } - if (this.beltPaths.indexOf(path) < 0) { - throw new Error("Path of entity not contained: " + belts[i].uid); - } + const belts = this.root.entityMgr.getAllWithComponent(BeltComponent); + for (let i = 0; i < belts.length; ++i) { + const path = belts[i].components.Belt.assignedPath; + if (!path) { + throw new Error("Belt has no path: " + belts[i].uid); + } + if (this.beltPaths.indexOf(path) < 0) { + throw new Error("Path of entity not contained: " + belts[i].uid); } } } @@ -450,13 +458,17 @@ export class BeltSystem extends GameSystemWithFilter { * Updates all belts */ update() { - this.verifyBeltPaths(); + if (G_IS_DEV && globalConfig.debug.checkBeltPaths) { + this.debug_verifyBeltPaths(); + } for (let i = 0; i < this.beltPaths.length; ++i) { this.beltPaths[i].update(); } - this.verifyBeltPaths(); + if (G_IS_DEV && globalConfig.debug.checkBeltPaths) { + this.debug_verifyBeltPaths(); + } } /** diff --git a/src/js/game/systems/item_acceptor.js b/src/js/game/systems/item_acceptor.js index 6647ee9a..04f3d12c 100644 --- a/src/js/game/systems/item_acceptor.js +++ b/src/js/game/systems/item_acceptor.js @@ -21,20 +21,23 @@ export class ItemAcceptorSystem extends GameSystemWithFilter { } update() { + const progress = + this.root.dynamicTickrate.deltaSeconds * + this.root.hubGoals.getBeltBaseSpeed() * + 2 * // * 2 because its only a half tile + globalConfig.itemSpacingOnBelts; + for (let i = 0; i < this.allEntities.length; ++i) { const entity = this.allEntities[i]; const aceptorComp = entity.components.ItemAcceptor; + const animations = aceptorComp.itemConsumptionAnimations; // Process item consumption animations to avoid items popping from the belts - for (let animIndex = 0; animIndex < aceptorComp.itemConsumptionAnimations.length; ++animIndex) { - const anim = aceptorComp.itemConsumptionAnimations[animIndex]; - anim.animProgress += - this.root.dynamicTickrate.deltaSeconds * - this.root.hubGoals.getBeltBaseSpeed() * - 2 * - globalConfig.itemSpacingOnBelts; + for (let animIndex = 0; animIndex < animations.length; ++animIndex) { + const anim = animations[animIndex]; + anim.animProgress += progress; if (anim.animProgress > 1) { - aceptorComp.itemConsumptionAnimations.splice(animIndex, 1); + animations.splice(animIndex, 1); animIndex -= 1; } } diff --git a/src/js/game/systems/item_ejector.js b/src/js/game/systems/item_ejector.js index b2ebf30d..851e3739 100644 --- a/src/js/game/systems/item_ejector.js +++ b/src/js/game/systems/item_ejector.js @@ -193,18 +193,19 @@ export class ItemEjectorSystem extends GameSystemWithFilter { if (!sourceEjectorComp.cachedConnectedSlots) { continue; } - for (let j = 0; j < sourceEjectorComp.cachedConnectedSlots.length; j++) { - const sourceSlot = sourceEjectorComp.cachedConnectedSlots[j]; - const destSlot = sourceSlot.cachedDestSlot; - const targetEntity = sourceSlot.cachedTargetEntity; + const slots = sourceEjectorComp.cachedConnectedSlots; + for (let j = 0; j < slots.length; ++j) { + const sourceSlot = slots[j]; const item = sourceSlot.item; - if (!item) { // No item available to be ejected continue; } + const destSlot = sourceSlot.cachedDestSlot; + const targetEntity = sourceSlot.cachedTargetEntity; + // Advance items on the slot sourceSlot.progress = Math_min(1, sourceSlot.progress + progressGrowth); @@ -248,15 +249,8 @@ export class ItemEjectorSystem extends GameSystemWithFilter { if (path.tryAcceptItem(item)) { return true; } - } - - const storageComp = receiver.components.Storage; - if (storageComp) { - // It's a storage - if (storageComp.canAcceptItem(item)) { - storageComp.takeItem(item); - return true; - } + // Belt can have nothing else + return false; } const itemProcessorComp = receiver.components.ItemProcessor; @@ -265,6 +259,8 @@ export class ItemEjectorSystem extends GameSystemWithFilter { if (itemProcessorComp.tryTakeItem(item, slotIndex)) { return true; } + // Item processor can have nothing else + return false; } const undergroundBeltComp = receiver.components.UndergroundBelt; @@ -278,6 +274,21 @@ export class ItemEjectorSystem extends GameSystemWithFilter { ) { return true; } + + // Underground belt can have nothing else + return false; + } + + const storageComp = receiver.components.Storage; + if (storageComp) { + // It's a storage + if (storageComp.canAcceptItem(item)) { + storageComp.takeItem(item); + return true; + } + + // Storage can't have anything else + return false; } const energyGeneratorComp = receiver.components.EnergyGenerator; @@ -286,6 +297,9 @@ export class ItemEjectorSystem extends GameSystemWithFilter { // Passed it over return true; } + + // Energy generator comp can't have anything else + return false; } return false; diff --git a/src/js/game/systems/underground_belt.js b/src/js/game/systems/underground_belt.js index a1e3855e..1f9977e1 100644 --- a/src/js/game/systems/underground_belt.js +++ b/src/js/game/systems/underground_belt.js @@ -30,21 +30,21 @@ export class UndergroundBeltSystem extends GameSystemWithFilter { } update() { + const delta = this.root.dynamicTickrate.deltaSeconds; + for (let i = 0; i < this.allEntities.length; ++i) { const entity = this.allEntities[i]; - const undergroundComp = entity.components.UndergroundBelt; + const pendingItems = undergroundComp.pendingItems; // Decrease remaining time of all items in belt - for (let k = 0; k < undergroundComp.pendingItems.length; ++k) { - const item = undergroundComp.pendingItems[k]; - item[1] = Math_max(0, item[1] - this.root.dynamicTickrate.deltaSeconds); - + for (let k = 0; k < pendingItems.length; ++k) { + const item = pendingItems[k]; + item[1] = Math_max(0, item[1] - delta); if (G_IS_DEV && globalConfig.debug.instantBelts) { item[1] = 0; } } - if (undergroundComp.mode === enumUndergroundBeltMode.sender) { this.handleSender(entity); } else {