From ee28cb84355471b6f9af878cd3c3941621efcecf Mon Sep 17 00:00:00 2001 From: TcePrepK <56453014+TcePrepK@users.noreply.github.com> Date: Mon, 26 Oct 2020 12:48:36 +0300 Subject: [PATCH] Wireless Displays!! --- src/js/core/modal_dialog_forms.js | 10 +- src/js/game/buildings/wireless_display.js | 7 +- src/js/game/components/wireless_display.js | 35 ++++- src/js/game/entity.js | 5 + src/js/game/game_system_manager.js | 4 + src/js/game/map_chunk_view.js | 1 + src/js/game/systems/constant_signal.js | 1 - src/js/game/systems/wireless_display.js | 160 +++++++++++++++++---- translations/base-en.yaml | 6 + 9 files changed, 191 insertions(+), 38 deletions(-) diff --git a/src/js/core/modal_dialog_forms.js b/src/js/core/modal_dialog_forms.js index 1c5b1986..08b67c55 100644 --- a/src/js/core/modal_dialog_forms.js +++ b/src/js/core/modal_dialog_forms.js @@ -208,7 +208,15 @@ export class FormElementItemChooser extends FormElement { canvas.width = 128; canvas.height = 128; const context = canvas.getContext("2d"); - item.drawFullSizeOnCanvas(context, 128); + if (typeof item == "string") { + context.fillStyle = "#000000"; + context.font = "64px sans-serif" + context.textAlign = "center"; + context.fillText(item, 32, 32, 128); + console.log(context); + } else { + item.drawFullSizeOnCanvas(context, 128); + } this.element.appendChild(canvas); const detector = new ClickDetector(canvas, {}); diff --git a/src/js/game/buildings/wireless_display.js b/src/js/game/buildings/wireless_display.js index a360ff1d..b74511d7 100644 --- a/src/js/game/buildings/wireless_display.js +++ b/src/js/game/buildings/wireless_display.js @@ -6,11 +6,6 @@ import { GameRoot } from "../root"; import { WirelessDisplayComponent } from "../components/wireless_display"; import { enumHubGoalRewards } from "../tutorial_goals"; import { formatItemsPerSecond, generateMatrixRotations } from "../../core/utils"; -import { ItemAcceptorComponent } from "../components/item_acceptor"; -import { ItemEjectorComponent } from "../components/item_ejector"; -import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor"; -import { T } from "../../translations"; -import { BeltUnderlaysComponent } from "../components/belt_underlays"; /** @enum {string} */ @@ -65,7 +60,7 @@ export class MetaWirelessDisplayBuilding extends MetaBuilding { * @param {Entity} entity */ setupEntityComponents(entity) { - + entity.addComponent(new WirelessDisplayComponent({})); } /** diff --git a/src/js/game/components/wireless_display.js b/src/js/game/components/wireless_display.js index e129d2e9..9e91f662 100644 --- a/src/js/game/components/wireless_display.js +++ b/src/js/game/components/wireless_display.js @@ -1,7 +1,40 @@ import { Component } from "../component"; +import { types } from "../../savegame/serialization"; +import { BaseItem } from "../base_item"; +import { typeItemSingleton } from "../item_resolver"; export class WirelessDisplayComponent extends Component { static getId() { - return "Wiresless_Display"; + return "WirelessDisplay"; + } + + static getWirelessCode() { + return 0; + } + + static getSchema() { + return { + signal: types.nullable(typeItemSingleton), + }; + } + + /** + * Copy the current state to another component + * @param {WirelessDisplayComponent} otherComponent + */ + copyAdditionalStateTo(otherComponent) { + otherComponent.signal = this.signal; + } + + /** + * + * @param {object} param0 + * @param {BaseItem=} param0.signal The signal to store + */ + constructor({ signal = null }) { + super(); + this.signal = signal; } } + + diff --git a/src/js/game/entity.js b/src/js/game/entity.js index d7dd715e..48420b72 100644 --- a/src/js/game/entity.js +++ b/src/js/game/entity.js @@ -64,6 +64,11 @@ export class Entity extends BasicSerializableObject { * @type {string} */ this.destroyReason; + /** + * Stores wireless code of this entity + */ + this.wireless_code = 0; + /* typehints:end */ } diff --git a/src/js/game/game_system_manager.js b/src/js/game/game_system_manager.js index 1047ae98..6bcc44b1 100644 --- a/src/js/game/game_system_manager.js +++ b/src/js/game/game_system_manager.js @@ -89,6 +89,9 @@ export class GameSystemManager { /** @type {DisplaySystem} */ display: null, + /** @type {WirelessDisplaySystem} */ + wirelessDisplay: null, + /** @type {ItemProcessorOverlaysSystem} */ itemProcessorOverlays: null, @@ -163,6 +166,7 @@ export class GameSystemManager { add("beltReader", BeltReaderSystem); add("display", DisplaySystem); + add("wirelessDisplay", WirelessDisplaySystem); add("itemProcessorOverlays", ItemProcessorOverlaysSystem); diff --git a/src/js/game/map_chunk_view.js b/src/js/game/map_chunk_view.js index 848afbab..9548ac0b 100644 --- a/src/js/game/map_chunk_view.js +++ b/src/js/game/map_chunk_view.js @@ -68,6 +68,7 @@ export class MapChunkView extends MapChunk { systems.staticMapEntities.drawChunk(parameters, this); systems.lever.drawChunk(parameters, this); systems.display.drawChunk(parameters, this); + systems.wirelessDisplay.drawChunk(parameters, this); systems.storage.drawChunk(parameters, this); systems.itemProcessorOverlays.drawChunk(parameters, this); } diff --git a/src/js/game/systems/constant_signal.js b/src/js/game/systems/constant_signal.js index aaf31a19..e5c8c4f9 100644 --- a/src/js/game/systems/constant_signal.js +++ b/src/js/game/systems/constant_signal.js @@ -99,7 +99,6 @@ export class ConstantSignalSystem extends GameSystemWithFilter { } if (itemInput.chosenItem) { - console.log(itemInput.chosenItem); constantComp.signal = itemInput.chosenItem; } else { constantComp.signal = this.parseSignalCode(signalValueInput.getValue()); diff --git a/src/js/game/systems/wireless_display.js b/src/js/game/systems/wireless_display.js index fcf765e1..05ed3e75 100644 --- a/src/js/game/systems/wireless_display.js +++ b/src/js/game/systems/wireless_display.js @@ -7,11 +7,23 @@ import { GameSystemWithFilter } from "../game_system_with_filter"; import { isTrueItem } from "../items/boolean_item"; import { ColorItem, COLOR_ITEM_SINGLETONS } from "../items/color_item"; import { MapChunkView } from "../map_chunk_view"; +import trim from "trim"; +import { THIRDPARTY_URLS } from "../../core/config"; +import { DialogWithForm } from "../../core/modal_dialog_elements"; +import { FormElementInput, FormElementItemChooser } from "../../core/modal_dialog_forms"; +import { fillInLinkIntoTranslation } from "../../core/utils"; +import { T } from "../../translations"; +import { Entity } from "../entity"; +import { ShapeDefinition } from "../shape_definition"; +import { BOOL_FALSE_SINGLETON, BOOL_TRUE_SINGLETON } from "../items/boolean_item"; +import { init } from "logrocket"; export class WirelessDisplaySystem extends GameSystemWithFilter { constructor(root) { super(root, [WirelessDisplayComponent]); + this.root.signals.entityManuallyPlaced.add(this.channelSignalValue, this); + /** @type {Object} */ this.displaySprites = {}; @@ -21,6 +33,88 @@ export class WirelessDisplaySystem extends GameSystemWithFilter { } this.displaySprites[colorId] = Loader.getSprite("sprites/wires/display/" + colorId + ".png"); } + this.wirelessMachineList = []; + } + + /** + * Asks the entity to enter a valid signal code + * @param {Entity} entity + */ + channelSignalValue(entity) { + if (entity.components.WirelessDisplay) { + // Ok, query, but also save the uid because it could get stale + const uid = entity.uid; + + const signalValueInput = new FormElementInput({ + id: "channelValue", + label: fillInLinkIntoTranslation(T.dialogs.editChannel.descShortKey, THIRDPARTY_URLS.shapeViewer), + placeholder: "", + defaultValue: "", + validator: val => val, + }); + + const channeldialog = new DialogWithForm({ + app: this.root.app, + title: T.dialogs.editChannel.title, + desc: T.dialogs.editChannel.descItems, + formElements: [signalValueInput], + buttons: ["cancel:bad:escape", "ok:good:enter"], + closeButton: false, + }); + this.root.hud.parts.dialogs.internalShowDialog(channeldialog); + + // When confirmed, set the signal + const closeHandler = () => { + if (!this.root || !this.root.entityMgr) { + // Game got stopped + return; + } + + const entityRef = this.root.entityMgr.findByUid(uid, false); + if (!entityRef) { + // outdated + return; + } + + const constantComp = entityRef.components.WirelessDisplay; + if (!constantComp) { + // no longer interesting + return; + } + + if (signalValueInput.getValue() && !entity.components.WiredPins){ + entity.wireless_code = signalValueInput.getValue(); + } else if (signalValueInput.getValue() && entity.components.WiredPins){ + entity.wireless_code = signalValueInput.getValue(); + this.wirelessMachineList.push(entity); + } + }; + + channeldialog.buttonSignals.ok.add(closeHandler); + channeldialog.valueChosen.add(closeHandler); + + // When cancelled, destroy the entity again + channeldialog.buttonSignals.cancel.add(() => { + if (!this.root || !this.root.entityMgr) { + // Game got stopped + return; + } + + const entityRef = this.root.entityMgr.findByUid(uid, false); + if (!entityRef) { + // outdated + return; + } + + const constantComp = entityRef.components.WirelessDisplay; + if (!constantComp) { + // no longer interesting + return; + } + + this.root.logic.tryDeleteBuilding(entityRef); + }); + } } /** @@ -60,38 +154,46 @@ export class WirelessDisplaySystem extends GameSystemWithFilter { drawChunk(parameters, chunk) { const contents = chunk.containedEntitiesByLayer.regular; for (let i = 0; i < contents.length; ++i) { - const entity = contents[i]; - if (entity && entity.components.Display) { - const pinsComp = entity.components.WiredPins; - const network = pinsComp.slots[0].linkedNetwork; + const entity_a = contents[i]; + if (entity_a && !entity_a.components.WiredPins && entity_a.components.WirelessDisplay) { + for (let j = 0; j < this.wirelessMachineList.length; ++j) { + const entity_b = this.wirelessMachineList[j]; + if (entity_a.wireless_code == entity_b.wireless_code) { + const origin = entity_a.components.StaticMapEntity.origin; + const pinsComp = entity_b.components.WiredPins; + const network = pinsComp.slots[0].linkedNetwork; + + if (!network || !network.hasValue()) { + continue; + } + + const value = this.getDisplayItem(network.currentValue); + + if (!value) { + continue; + } - if (!network || !network.hasValue()) { - continue; - } - - const value = this.getDisplayItem(network.currentValue); - - if (!value) { - continue; - } - - const origin = entity.components.StaticMapEntity.origin; - if (value.getItemType() === "color") { - this.displaySprites[/** @type {ColorItem} */ (value).color].drawCachedCentered( - parameters, - (origin.x + 0.5) * globalConfig.tileSize, - (origin.y + 0.5) * globalConfig.tileSize, - globalConfig.tileSize - ); - } else if (value.getItemType() === "shape") { - value.drawItemCenteredClipped( - (origin.x + 0.5) * globalConfig.tileSize, - (origin.y + 0.5) * globalConfig.tileSize, - parameters, - 30 - ); + if (value.getItemType()) { + if (value.getItemType() === "color") { + this.displaySprites[/** @type {ColorItem} */ (value).color].drawCachedCentered( + parameters, + (origin.x + 0.5) * globalConfig.tileSize, + (origin.y + 0.5) * globalConfig.tileSize, + globalConfig.tileSize + ); + } else if (value.getItemType() === "shape") { + value.drawItemCenteredClipped( + (origin.x + 0.5) * globalConfig.tileSize, + (origin.y + 0.5) * globalConfig.tileSize, + parameters, + 30 + ); + } + } + } } } } } } + diff --git a/translations/base-en.yaml b/translations/base-en.yaml index 89b491af..269f5478 100644 --- a/translations/base-en.yaml +++ b/translations/base-en.yaml @@ -255,6 +255,12 @@ dialogs: titleEdit: Edit Marker desc: Give it a meaningful name, you can also include a short key of a shape (Which you can generate here) + editChannel: + title: Set Channel + descItems: >- + Enter used channel name + descShortKey: or enter new channel name + editSignal: title: Set Signal descItems: >-