mirror of
https://github.com/tobspr/shapez.io.git
synced 2024-10-27 20:34:29 +00:00
164 lines
5.4 KiB
JavaScript
164 lines
5.4 KiB
JavaScript
import { DrawParameters } from "../../../core/draw_parameters";
|
|
import { STOP_PROPAGATION } from "../../../core/signal";
|
|
import { TrackedState } from "../../../core/tracked_state";
|
|
import { Vector } from "../../../core/vector";
|
|
import { enumMouseButton } from "../../camera";
|
|
import { KEYMAPPINGS } from "../../key_action_mapper";
|
|
import { BaseHUDPart } from "../base_hud_part";
|
|
import { Blueprint } from "./blueprint";
|
|
import { makeDiv } from "../../../core/utils";
|
|
import { DynamicDomAttach } from "../dynamic_dom_attach";
|
|
import { blueprintShape } from "../../upgrades";
|
|
import { T } from "../../../translations";
|
|
|
|
export class HUDBlueprintPlacer extends BaseHUDPart {
|
|
createElements(parent) {
|
|
const blueprintCostShape = this.root.shapeDefinitionMgr.getShapeFromShortKey(blueprintShape);
|
|
const blueprintCostShapeCanvas = blueprintCostShape.generateAsCanvas(80);
|
|
|
|
this.costDisplayParent = makeDiv(parent, "ingame_HUD_BlueprintPlacer", [], ``);
|
|
|
|
makeDiv(this.costDisplayParent, null, ["label"], T.ingame.blueprintPlacer.cost);
|
|
const costContainer = makeDiv(this.costDisplayParent, null, ["costContainer"], "");
|
|
this.costDisplayText = makeDiv(costContainer, null, ["costText"], "");
|
|
costContainer.appendChild(blueprintCostShapeCanvas);
|
|
}
|
|
|
|
initialize() {
|
|
this.root.hud.signals.buildingsSelectedForCopy.add(this.onBuildingsSelected, this);
|
|
|
|
/** @type {TypedTrackedState<Blueprint?>} */
|
|
this.currentBlueprint = new TrackedState(this.onBlueprintChanged, this);
|
|
|
|
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);
|
|
|
|
this.root.camera.downPreHandler.add(this.onMouseDown, this);
|
|
this.root.camera.movePreHandler.add(this.onMouseMove, this);
|
|
|
|
this.root.hud.signals.selectedPlacementBuildingChanged.add(this.abortPlacement, this);
|
|
|
|
this.domAttach = new DynamicDomAttach(this.root, this.costDisplayParent);
|
|
this.trackedCanAfford = new TrackedState(this.onCanAffordChanged, this);
|
|
}
|
|
|
|
abortPlacement() {
|
|
if (this.currentBlueprint.get()) {
|
|
this.currentBlueprint.set(null);
|
|
|
|
return STOP_PROPAGATION;
|
|
}
|
|
}
|
|
|
|
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)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param {Blueprint} blueprint
|
|
*/
|
|
onBlueprintChanged(blueprint) {
|
|
if (blueprint) {
|
|
this.costDisplayText.innerText = "" + blueprint.getCost();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* mouse down pre handler
|
|
* @param {Vector} pos
|
|
* @param {enumMouseButton} button
|
|
*/
|
|
onMouseDown(pos, button) {
|
|
if (button === enumMouseButton.right) {
|
|
if (this.currentBlueprint.get()) {
|
|
this.abortPlacement();
|
|
return STOP_PROPAGATION;
|
|
}
|
|
}
|
|
|
|
const blueprint = this.currentBlueprint.get();
|
|
if (!blueprint) {
|
|
return;
|
|
}
|
|
|
|
if (!blueprint.canAfford(this.root)) {
|
|
this.root.soundProxy.playUiError();
|
|
return;
|
|
}
|
|
|
|
const worldPos = this.root.camera.screenToWorld(pos);
|
|
const tile = worldPos.toTileSpace();
|
|
if (blueprint.tryPlace(this.root, tile)) {
|
|
const cost = blueprint.getCost();
|
|
this.root.hubGoals.takeShapeByKey(blueprintShape, cost);
|
|
|
|
// This actually feels weird
|
|
// if (!this.root.keyMapper.getBinding(KEYMAPPINGS.placementModifiers.placeMultiple).isCurrentlyPressed()) {
|
|
// this.currentBlueprint.set(null);
|
|
// }
|
|
}
|
|
}
|
|
|
|
onMouseMove() {
|
|
// Prevent movement while blueprint is selected
|
|
if (this.currentBlueprint.get()) {
|
|
return STOP_PROPAGATION;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {Array<number>} uids
|
|
*/
|
|
onBuildingsSelected(uids) {
|
|
if (uids.length === 0) {
|
|
return;
|
|
}
|
|
this.currentBlueprint.set(Blueprint.fromUids(this.root, uids));
|
|
}
|
|
|
|
rotateBlueprint() {
|
|
if (this.currentBlueprint.get()) {
|
|
if (
|
|
this.root.keyMapper
|
|
.getBinding(KEYMAPPINGS.placement.rotateInverseModifier)
|
|
.isCurrentlyPressed()
|
|
) {
|
|
this.currentBlueprint.get().rotateCcw();
|
|
} else {
|
|
this.currentBlueprint.get().rotateCw();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param {DrawParameters} parameters
|
|
*/
|
|
draw(parameters) {
|
|
const blueprint = this.currentBlueprint.get();
|
|
if (!blueprint) {
|
|
return;
|
|
}
|
|
const mousePosition = this.root.app.mousePosition;
|
|
if (!mousePosition) {
|
|
// Not on screen
|
|
return;
|
|
}
|
|
|
|
const worldPos = this.root.camera.screenToWorld(mousePosition);
|
|
const tile = worldPos.toTileSpace();
|
|
blueprint.draw(parameters, tile);
|
|
}
|
|
}
|