diff --git a/res/ui/building_icons/portable_hub.png b/res/ui/building_icons/portable_hub.png new file mode 100644 index 00000000..b6a34ae6 Binary files /dev/null and b/res/ui/building_icons/portable_hub.png differ diff --git a/res/ui/building_tutorials/portable_hub.png b/res/ui/building_tutorials/portable_hub.png new file mode 100644 index 00000000..3d69bb53 Binary files /dev/null and b/res/ui/building_tutorials/portable_hub.png differ diff --git a/src/css/icons.scss b/src/css/icons.scss index 841fccd9..42074acb 100644 --- a/src/css/icons.scss +++ b/src/css/icons.scss @@ -1,6 +1,5 @@ $buildings: belt, cutter, miner, mixer, painter, rotater, splitter, stacker, trash, underground_belt, wire, - constant_signal, logic_gate, lever, filter, wire_tunnel, display, virtual_processor, reader; - + constant_signal, logic_gate, lever, filter, wire_tunnel, display, virtual_processor, reader, portable_hub; @each $building in $buildings { [data-icon="building_icons/#{$building}.png"] { background-image: uiResource("res/ui/building_icons/#{$building}.png") !important; @@ -9,7 +8,7 @@ $buildings: belt, cutter, miner, mixer, painter, rotater, splitter, stacker, tra $buildingsAndVariants: belt, splitter, splitter-compact, splitter-compact-inverse, underground_belt, underground_belt-tier2, miner, miner-chainable, cutter, cutter-quad, rotater, rotater-ccw, rotater-fl, - stacker, mixer, painter, painter-double, painter-quad, trash, trash-storage; + stacker, mixer, painter, painter-double, painter-quad, trash, trash-storage, portable_hub; @each $building in $buildingsAndVariants { [data-icon="building_tutorials/#{$building}.png"] { background-image: uiResource("res/ui/building_tutorials/#{$building}.png") !important; diff --git a/src/js/game/buildings/portable_hub.js b/src/js/game/buildings/portable_hub.js new file mode 100644 index 00000000..59a76ff4 --- /dev/null +++ b/src/js/game/buildings/portable_hub.js @@ -0,0 +1,56 @@ +import { MetaBuilding } from "../meta_building"; +import {ItemAcceptorComponent} from "../components/item_acceptor"; +import {enumDirection, Vector} from "../../core/vector"; +import {enumItemProcessorTypes, ItemProcessorComponent} from "../components/item_processor"; +import {enumPinSlotType, WiredPinsComponent} from "../components/wired_pins"; + +export class MetaPortableHubBuilding extends MetaBuilding { + constructor() { + super("portable_hub"); + } + + getIsRotateable(variant) { + return false; + } + + getSilhouetteColor() { + return "#eb5555"; + } + + setupEntityComponents(entity, root) { + entity.addComponent( + new ItemAcceptorComponent({ + slots: [ + { + pos: new Vector(0, 0), + directions: [ + enumDirection.top, + enumDirection.right, + enumDirection.bottom, + enumDirection.left, + ], + }, + ], + }) + ); + + entity.addComponent( + new WiredPinsComponent({ + slots: [ + { + pos: new Vector(0, 0), + type: enumPinSlotType.logicalEjector, + direction: enumDirection.left, + }, + ], + }) + ); + + entity.addComponent( + new ItemProcessorComponent({ + inputsPerCharge: 1, + processorType: enumItemProcessorTypes.hub, + }) + ); + } +} diff --git a/src/js/game/components/item_processor.js b/src/js/game/components/item_processor.js index 5d51b4a3..8fb180a1 100644 --- a/src/js/game/components/item_processor.js +++ b/src/js/game/components/item_processor.js @@ -1,7 +1,6 @@ import { types } from "../../savegame/serialization"; import { BaseItem } from "../base_item"; import { Component } from "../component"; -import { typeItemSingleton } from "../item_resolver"; /** @enum {string} */ export const enumItemProcessorTypes = { diff --git a/src/js/game/hud/parts/buildings_toolbar.js b/src/js/game/hud/parts/buildings_toolbar.js index f8953204..f4c064b5 100644 --- a/src/js/game/hud/parts/buildings_toolbar.js +++ b/src/js/game/hud/parts/buildings_toolbar.js @@ -13,6 +13,7 @@ import { MetaLeverBuilding } from "../../buildings/lever"; import { MetaFilterBuilding } from "../../buildings/filter"; import { MetaDisplayBuilding } from "../../buildings/display"; import { MetaReaderBuilding } from "../../buildings/reader"; +import {MetaPortableHubBuilding} from "../../buildings/portable_hub"; const supportedBuildings = [ MetaBeltBaseBuilding, @@ -29,6 +30,7 @@ const supportedBuildings = [ MetaFilterBuilding, MetaDisplayBuilding, MetaReaderBuilding, + MetaPortableHubBuilding, ]; export class HUDBuildingsToolbar extends HUDBaseToolbar { diff --git a/src/js/game/key_action_mapper.js b/src/js/game/key_action_mapper.js index d5a758a5..13438505 100644 --- a/src/js/game/key_action_mapper.js +++ b/src/js/game/key_action_mapper.js @@ -65,6 +65,8 @@ export const KEYMAPPINGS = { constant_signal: { keyCode: key("3") }, logic_gate: { keyCode: key("4") }, virtual_processor: { keyCode: key("5") }, + + portable_hub: { keyCode: key("P") }, }, placement: { diff --git a/src/js/game/meta_building_registry.js b/src/js/game/meta_building_registry.js index 647e55f5..11e0cc20 100644 --- a/src/js/game/meta_building_registry.js +++ b/src/js/game/meta_building_registry.js @@ -23,6 +23,7 @@ import { MetaWireTunnelBuilding, enumWireTunnelVariants } from "./buildings/wire import { MetaDisplayBuilding } from "./buildings/display"; import { MetaVirtualProcessorBuilding, enumVirtualProcessorVariants } from "./buildings/virtual_processor"; import { MetaReaderBuilding } from "./buildings/reader"; +import {MetaPortableHubBuilding} from "./buildings/portable_hub"; const logger = createLogger("building_registry"); @@ -47,6 +48,7 @@ export function initMetaBuildingRegistry() { gMetaBuildingRegistry.register(MetaDisplayBuilding); gMetaBuildingRegistry.register(MetaVirtualProcessorBuilding); gMetaBuildingRegistry.register(MetaReaderBuilding); + gMetaBuildingRegistry.register(MetaPortableHubBuilding); // Belt registerBuildingVariant(1, MetaBeltBaseBuilding, defaultBuildingVariant, 0); @@ -137,6 +139,9 @@ export function initMetaBuildingRegistry() { // Reader registerBuildingVariant(49, MetaReaderBuilding); + // Portable hub + registerBuildingVariant(50, MetaPortableHubBuilding); + // Propagate instances for (const key in gBuildingVariants) { gBuildingVariants[key].metaInstance = gMetaBuildingRegistry.findByClass( diff --git a/src/js/game/systems/item_processor.js b/src/js/game/systems/item_processor.js index d58aa697..5bfddf5e 100644 --- a/src/js/game/systems/item_processor.js +++ b/src/js/game/systems/item_processor.js @@ -116,10 +116,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter { // Check the network value at the given slot const network = pinsComp.slots[slotIndex - 1].linkedNetwork; const slotIsEnabled = network && isTruthyItem(network.currentValue); - if (!slotIsEnabled) { - return false; - } - return true; + return slotIsEnabled; + } case enumItemProcessorRequirements.filter: { @@ -524,9 +522,6 @@ export class ItemProcessorSystem extends GameSystemWithFilter { case enumItemProcessorTypes.hub: { trackProduction = false; - const hubComponent = entity.components.Hub; - assert(hubComponent, "Hub item processor has no hub component"); - for (let i = 0; i < items.length; ++i) { const item = /** @type {ShapeItem} */ (items[i].item); this.root.hubGoals.handleDefinitionDelivered(item.definition); diff --git a/translations/base-en.yaml b/translations/base-en.yaml index 28fef7e2..5a372487 100644 --- a/translations/base-en.yaml +++ b/translations/base-en.yaml @@ -637,6 +637,11 @@ buildings: name: Compare description: Returns true if both items are exactly equal. Can compare shapes, items and booleans. + portable_hub: + default: + name: &portable_hub Portable hub + description: Like the hub but mini + storyRewards: # Those are the rewards gained from completing the store reward_cutter_and_trash: @@ -956,6 +961,7 @@ keybindings: wire_tunnel: *wire_tunnel display: *display reader: *reader + portable_hub: *portable_hub # --- pipette: Pipette