From 0b31ad0c7bb77cb6d393901428ef793dd3bef97f Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 21:44:53 +0200 Subject: [PATCH] Pipette --- src/css/states/ingame.scss | 2 +- src/js/game/hud/hud.js | 2 ++ src/js/game/hud/parts/blueprint_placer.js | 34 +++++++++++++++---- .../game/hud/parts/building_placer_logic.js | 4 +-- src/js/game/hud/parts/keybinding_overlay.js | 9 ++++- src/js/game/hud/parts/pipette_blueprint.js | 23 +++++++++++++ src/js/game/key_action_mapper.js | 4 +-- translations/base-en.yaml | 3 +- 8 files changed, 66 insertions(+), 15 deletions(-) create mode 100644 src/js/game/hud/parts/pipette_blueprint.js diff --git a/src/css/states/ingame.scss b/src/css/states/ingame.scss index 614cdf6a..3f220a5d 100644 --- a/src/css/states/ingame.scss +++ b/src/css/states/ingame.scss @@ -31,7 +31,7 @@ @include DarkThemeOverride { .gameLoadingOverlay { - background: #56565c; + background: $darkModeGameBackground; } } } diff --git a/src/js/game/hud/hud.js b/src/js/game/hud/hud.js index 40338600..5d99194e 100644 --- a/src/js/game/hud/hud.js +++ b/src/js/game/hud/hud.js @@ -34,6 +34,7 @@ import { HUDPartTutorialHints } from "./parts/tutorial_hints"; import { HUDWaypoints } from "./parts/waypoints"; import { HUDInteractiveTutorial } from "./parts/interactive_tutorial"; import { HUDScreenshotExporter } from "./parts/screenshot_exporter"; +import { Entity } from "../entity"; export class GameHUD { /** @@ -75,6 +76,7 @@ export class GameHUD { shapeUnpinRequested: /** @type {TypedSignal<[string]>} */ (new Signal()), notification: /** @type {TypedSignal<[string, enumNotificationType]>} */ (new Signal()), buildingsSelectedForCopy: /** @type {TypedSignal<[Array]>} */ (new Signal()), + pipetteExecuted: /** @type {TypedSignal<[Entity]>} */ (new Signal()), pasteBlueprintRequested: new Signal(), }; diff --git a/src/js/game/hud/parts/blueprint_placer.js b/src/js/game/hud/parts/blueprint_placer.js index fa9faca2..3831af99 100644 --- a/src/js/game/hud/parts/blueprint_placer.js +++ b/src/js/game/hud/parts/blueprint_placer.js @@ -10,6 +10,7 @@ import { makeDiv } from "../../../core/utils"; import { DynamicDomAttach } from "../dynamic_dom_attach"; import { blueprintShape } from "../../upgrades"; import { T } from "../../../translations"; +import { PipetteBlueprint } from "./pipette_blueprint"; export class HUDBlueprintPlacer extends BaseHUDPart { createElements(parent) { @@ -34,11 +35,9 @@ export class HUDBlueprintPlacer extends BaseHUDPart { const keyActionMapper = this.root.keyMapper; keyActionMapper.getBinding(KEYMAPPINGS.general.back).add(this.abortPlacement, this); - keyActionMapper - .getBinding(KEYMAPPINGS.placement.abortBuildingPlacement) - .add(this.abortPlacement, this); keyActionMapper.getBinding(KEYMAPPINGS.placement.rotateWhilePlacing).add(this.rotateBlueprint, this); keyActionMapper.getBinding(KEYMAPPINGS.massSelect.pasteLastBlueprint).add(this.pasteBlueprint, this); + keyActionMapper.getBinding(KEYMAPPINGS.placement.pipette).add(this.startPipette, this); this.root.camera.downPreHandler.add(this.onMouseDown, this); this.root.camera.movePreHandler.add(this.onMouseMove, this); @@ -57,15 +56,36 @@ export class HUDBlueprintPlacer extends BaseHUDPart { } } + /** + * Starts the pipette function + */ + startPipette() { + const mousePosition = this.root.app.mousePosition; + if (!mousePosition) { + // Not on screen + return; + } + + const worldPos = this.root.camera.screenToWorld(mousePosition); + const tile = worldPos.toTileSpace(); + const contents = this.root.map.getTileContent(tile); + if (contents) { + const blueprint = PipetteBlueprint.fromEntity(contents); + + // Notice: Order here matters, since pipetteExecuted clears the blueprint + this.root.hud.signals.pipetteExecuted.dispatch(contents); + this.currentBlueprint.set(blueprint); + } + } + onCanAffordChanged(canAfford) { this.costDisplayParent.classList.toggle("canAfford", canAfford); } update() { - this.domAttach.update(this.currentBlueprint.get()); - this.trackedCanAfford.set( - this.currentBlueprint.get() && this.currentBlueprint.get().canAfford(this.root) - ); + const currentBlueprint = this.currentBlueprint.get(); + this.domAttach.update(currentBlueprint && currentBlueprint.getCost() > 0); + this.trackedCanAfford.set(currentBlueprint && currentBlueprint.canAfford(this.root)); } /** diff --git a/src/js/game/hud/parts/building_placer_logic.js b/src/js/game/hud/parts/building_placer_logic.js index 15564e4d..3a41a3f2 100644 --- a/src/js/game/hud/parts/building_placer_logic.js +++ b/src/js/game/hud/parts/building_placer_logic.js @@ -97,15 +97,13 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { keyActionMapper .getBinding(KEYMAPPINGS.placement.switchDirectionLockSide) .add(this.switchDirectionLockSide, this); - keyActionMapper - .getBinding(KEYMAPPINGS.placement.abortBuildingPlacement) - .add(this.abortPlacement, this); keyActionMapper.getBinding(KEYMAPPINGS.general.back).add(this.abortPlacement, this); this.root.gameState.inputReciever.keyup.add(this.checkForDirectionLockSwitch, this); // BINDINGS TO GAME EVENTS this.root.hud.signals.buildingsSelectedForCopy.add(this.abortPlacement, this); this.root.hud.signals.pasteBlueprintRequested.add(this.abortPlacement, this); + this.root.hud.signals.pipetteExecuted.add(this.abortPlacement, this); this.root.signals.storyGoalCompleted.add(() => this.signals.variantChanged.dispatch()); this.root.signals.upgradePurchased.add(() => this.signals.variantChanged.dispatch()); diff --git a/src/js/game/hud/parts/keybinding_overlay.js b/src/js/game/hud/parts/keybinding_overlay.js index 7aca3722..633dfcef 100644 --- a/src/js/game/hud/parts/keybinding_overlay.js +++ b/src/js/game/hud/parts/keybinding_overlay.js @@ -164,10 +164,17 @@ export class HUDKeybindingOverlay extends BaseHUDPart { condition: () => this.mapOverviewActive && !this.blueprintPlacementActive, }, + { + // Pipette + label: T.ingame.keybindingsOverlay.pipette, + keys: [k.placement.pipette], + condition: () => !this.mapOverviewActive, + }, + { // Cancel placement label: T.ingame.keybindingsOverlay.stopPlacement, - keys: [KEYCODE_RMB, DIVIDER_TOKEN, k.placement.abortBuildingPlacement], + keys: [KEYCODE_RMB], condition: () => this.anyPlacementActive, }, diff --git a/src/js/game/hud/parts/pipette_blueprint.js b/src/js/game/hud/parts/pipette_blueprint.js new file mode 100644 index 00000000..3be8a207 --- /dev/null +++ b/src/js/game/hud/parts/pipette_blueprint.js @@ -0,0 +1,23 @@ +import { Vector } from "../../../core/vector"; +import { Entity } from "../../entity"; +import { Blueprint } from "./blueprint"; + +export class PipetteBlueprint extends Blueprint { + /** + * @see Blueprint.getCost + */ + getCost() { + // Its free + return 0; + } + + /** + * Creates a new pipetted blueprint from a given entity + * @param {Entity} entity + */ + static fromEntity(entity) { + const clone = entity.duplicateWithoutContents(); + clone.components.StaticMapEntity.origin = new Vector(0, 0); + return new PipetteBlueprint([clone]); + } +} diff --git a/src/js/game/key_action_mapper.js b/src/js/game/key_action_mapper.js index 659f01e6..c514446d 100644 --- a/src/js/game/key_action_mapper.js +++ b/src/js/game/key_action_mapper.js @@ -24,7 +24,7 @@ export const KEYMAPPINGS = { menuOpenStats: { keyCode: key("G") }, toggleHud: { keyCode: 113 }, // F2 - exportScreenshot: { keyCode: 114 }, // F3 + exportScreenshot: { keyCode: 114 }, // F3PS toggleFPSInfo: { keyCode: 115 }, // F4 }, @@ -56,7 +56,7 @@ export const KEYMAPPINGS = { }, placement: { - abortBuildingPlacement: { keyCode: key("Q") }, + pipette: { keyCode: key("Q") }, rotateWhilePlacing: { keyCode: key("R") }, rotateInverseModifier: { keyCode: 16 }, // SHIFT cycleBuildingVariants: { keyCode: key("T") }, diff --git a/translations/base-en.yaml b/translations/base-en.yaml index 52f4ab3c..0b754e4b 100644 --- a/translations/base-en.yaml +++ b/translations/base-en.yaml @@ -288,6 +288,7 @@ ingame: cutSelection: Cut copySelection: Copy clearSelection: Clear Selection + pipette: Pipette # Everything related to placing buildings (I.e. as soon as you selected a building # from the toolbar) @@ -738,7 +739,7 @@ keybindings: painter: *painter trash: *trash - abortBuildingPlacement: Abort Placement + pipette: Pipette rotateWhilePlacing: Rotate rotateInverseModifier: >- Modifier: Rotate CCW instead