diff --git a/src/js/game/components/item_ejector.js b/src/js/game/components/item_ejector.js index 719925af..4ba4d27b 100644 --- a/src/js/game/components/item_ejector.js +++ b/src/js/game/components/item_ejector.js @@ -11,6 +11,7 @@ import { typeItemSingleton } from "../item_resolver"; * pos: Vector, * direction: enumDirection, * item: BaseItem, + * lastItem: BaseItem, * progress: number?, * cachedDestSlot?: import("./item_acceptor").ItemAcceptorLocatedSlot, * cachedBeltPath?: BeltPath, @@ -67,6 +68,7 @@ export class ItemEjectorComponent extends Component { pos: slot.pos, direction: slot.direction, item: null, + lastItem: null, progress: 0, cachedDestSlot: null, cachedTargetEntity: null, @@ -131,6 +133,7 @@ export class ItemEjectorComponent extends Component { return false; } this.slots[slotIndex].item = item; + this.slots[slotIndex].lastItem = item; this.slots[slotIndex].progress = 0; return true; } diff --git a/src/js/game/hud/hud.js b/src/js/game/hud/hud.js index f35fe018..e3ce76e6 100644 --- a/src/js/game/hud/hud.js +++ b/src/js/game/hud/hud.js @@ -189,6 +189,7 @@ export class GameHUD { "colorBlindHelper", "changesDebugger", "minerHighlight", + "shapeTooltip", ]; for (let i = 0; i < partsOrder.length; ++i) { diff --git a/src/js/game/hud/parts/shape_tooltip.js b/src/js/game/hud/parts/shape_tooltip.js new file mode 100644 index 00000000..e84edcef --- /dev/null +++ b/src/js/game/hud/parts/shape_tooltip.js @@ -0,0 +1,129 @@ +import { DrawParameters } from "../../../core/draw_parameters"; +import { createLogger } from "../../../core/logging"; +import { Vector } from "../../../core/vector"; +import { enumMouseButton } from "../../camera"; +import { Entity } from "../../entity"; +import { KEYMAPPINGS } from "../../key_action_mapper"; +import { BaseHUDPart } from "../base_hud_part"; + +const logger = createLogger("hud/mass_selector"); + +export class HUDShapeTooltip extends BaseHUDPart { + createElements(parent) {} + + initialize() { + /** @type {Vector} */ + this.currentTile = null; + + /** @type {Entity} */ + this.currentEntity = null; + + /** @type {Array} */ + this.cachedItems = null; + + this.isPlacingBuilding = false; + this.active = false; + + this.root.camera.movePreHandler.add(this.onMouseMove, this); + + const keyActionMapper = this.root.keyMapper; + + keyActionMapper.getBinding(KEYMAPPINGS.placement.pipette).add(this.clear, this); + + this.root.hud.signals.pasteBlueprintRequested.add(this.clear, this); + this.root.hud.signals.selectedPlacementBuildingChanged.add( + this.onSelectedPlacementBuildingChanged, + this + ); + this.root.hud.signals.buildingsSelectedForCopy.add(this.clear, this); + this.root.signals.entityQueuedForDestroy.add(this.clear, this); + this.root.signals.editModeChanged.add(this.clear, this); + } + + update() { + // need to make sure not to show when anything else is active + + this.active = + this.currentTile && + !this.isPlacingBuilding && + this.root.keyMapper.getBinding(KEYMAPPINGS.ingame.showShapeTooltip).pressed && + !this.root.hud.parts.massSelector.currentSelectionStartWorld && + this.root.hud.parts.massSelector.selectedUids.size < 1; + } + + /** + * Called when the selected meta building was changed + * @param {import("../../../core/global_registries").MetaBuilding} metaBuilding + */ + onSelectedPlacementBuildingChanged(metaBuilding) { + if (metaBuilding) { + this.isPlacingBuilding = true; + this.clear(); + } else { + this.isPlacingBuilding = false; + } + } + + /** + * Clears everything + */ + clear() { + this.currentTile = null; + this.currentEntity = null; + this.cachedItems = null; + } + + /** + * mouse move pre handler + * @param {Vector} pos + */ + onMouseMove(pos) { + const newTile = this.root.camera.screenToWorld(pos.copy()).toTileSpace(); + + if (!(this.currentTile && newTile.equals(this.currentTile))) { + this.currentTile = newTile; + + const entity = this.root.map.getLayerContentXY( + this.currentTile.x, + this.currentTile.y, + this.root.currentLayer + ); + + if (!(entity && entity.components.ItemProcessor && entity.components.ItemEjector)) { + this.clear(); + return; + } + + this.currentEntity = entity; + } + } + + /** + * + * @param {DrawParameters} parameters + */ + draw(parameters) { + if (this.active && this.currentEntity) { + const ejectorComp = this.currentEntity.components.ItemEjector; + const staticComp = this.currentEntity.components.StaticMapEntity; + + for (let i = 0; i < ejectorComp.slots.length; ++i) { + const slot = ejectorComp.slots[i]; + + if (!slot.lastItem || slot.lastItem._type != "shape") { + continue; + } + + /** @type {Vector} */ + let drawPos = null; + if (ejectorComp.slots.length == 1) { + drawPos = staticComp.getTileSpaceBounds().getCenter().toWorldSpace(); + } else { + drawPos = staticComp.localTileToWorld(slot.pos).toWorldSpaceCenterOfTile(); + } + + slot.lastItem.drawItemCenteredClipped(drawPos.x, drawPos.y, parameters, 25); + } + } + } +} diff --git a/src/js/game/key_action_mapper.js b/src/js/game/key_action_mapper.js index 41208d13..090b8b83 100644 --- a/src/js/game/key_action_mapper.js +++ b/src/js/game/key_action_mapper.js @@ -32,6 +32,8 @@ export const KEYMAPPINGS = { toggleFPSInfo: { keyCode: 115 }, // F4 switchLayers: { keyCode: key("E") }, + + showShapeTooltip: { keyCode: 18 }, // ALT }, navigation: { diff --git a/src/js/game/modes/puzzle.js b/src/js/game/modes/puzzle.js index c953b0a6..cdbc16cc 100644 --- a/src/js/game/modes/puzzle.js +++ b/src/js/game/modes/puzzle.js @@ -8,6 +8,7 @@ import { enumGameModeTypes, GameMode } from "../game_mode"; import { HUDPuzzleBackToMenu } from "../hud/parts/puzzle_back_to_menu"; import { HUDPuzzleDLCLogo } from "../hud/parts/puzzle_dlc_logo"; import { HUDMassSelector } from "../hud/parts/mass_selector"; +import { HUDShapeTooltip } from "../hud/parts/shape_tooltip"; export class PuzzleGameMode extends GameMode { static getType() { @@ -32,6 +33,7 @@ export class PuzzleGameMode extends GameMode { puzzleBackToMenu: HUDPuzzleBackToMenu, puzzleDlcLogo: HUDPuzzleDLCLogo, massSelector: HUDMassSelector, + shapeTooltip: HUDShapeTooltip, }; this.zoneWidth = data.zoneWidth || 8; diff --git a/translations/base-en.yaml b/translations/base-en.yaml index 02d8e948..cc4d5e94 100644 --- a/translations/base-en.yaml +++ b/translations/base-en.yaml @@ -1363,6 +1363,8 @@ keybindings: placeMultiple: Stay in placement mode placeInverse: Invert automatic belt orientation + showShapeTooltip: Show shape output tooltip + about: title: About this Game body: >-