Introduce cost for blueprints

pull/33/head
tobspr 4 years ago
parent 955cba74aa
commit 37685d64bd

@ -0,0 +1,39 @@
#ingame_HUD_BlueprintPlacer {
position: absolute;
@include S(top, 50px);
left: 50%;
transform: translateX(-50%);
color: #333;
z-index: 9999;
background: rgba(0, 10, 20, 0.5);
@include S(padding, 5px);
display: flex;
flex-direction: column;
color: #fff;
@include S(width, 120px);
align-items: center;
justify-content: center;
.label {
@include PlainText;
text-transform: uppercase;
}
.costContainer {
display: flex;
align-items: center;
@include Heading;
> canvas {
@include S(margin-left, 5px);
@include S(width, 30px);
@include S(height, 30px);
}
}
&:not(.canAfford) {
background: rgba(98, 27, 41, 0.8);
// .costContainer {
color: rgb(255, 97, 128);
// }
}
}

@ -47,6 +47,7 @@
@import "ingame_hud/entity_debugger";
@import "ingame_hud/tutorial_hints";
@import "ingame_hud/watermark";
@import "ingame_hud/blueprint_placer";
// prettier-ignore
$elements:
@ -68,6 +69,7 @@ ingame_HUD_DebugInfo,
ingame_HUD_EntityDebugger,
ingame_HUD_TutorialHints,
ingame_HUD_buildings_toolbar,
ingame_HUD_BlueprintPlacer,
ingame_HUD_Watermark,
// Overlays

@ -83,7 +83,7 @@ export const globalConfig = {
debug: {
/* dev:start */
// fastGameEnter: true,
fastGameEnter: true,
// noArtificialDelays: true,
// disableSavegameWrite: true,
// showEntityBounds: true,

@ -8,7 +8,7 @@ import { enumItemProcessorTypes } from "./components/item_processor";
import { GameRoot } from "./root";
import { enumSubShape, ShapeDefinition } from "./shape_definition";
import { enumHubGoalRewards, tutorialGoals } from "./tutorial_goals";
import { UPGRADES } from "./upgrades";
import { UPGRADES, blueprintShape } from "./upgrades";
export class HubGoals extends BasicSerializableObject {
static getId() {
@ -53,6 +53,10 @@ export class HubGoals extends BasicSerializableObject {
}
this.upgradeImprovements[upgradeId] = totalImprovement;
}
if (G_IS_DEV) {
this.storedShapes[blueprintShape] = 1000;
}
}
/**
@ -77,6 +81,10 @@ export class HubGoals extends BasicSerializableObject {
*/
this.storedShapes = {};
if (G_IS_DEV) {
this.storedShapes[blueprintShape] = 1000;
}
/**
* Stores the levels for all upgrades
* @type {Object<string, number>}
@ -113,6 +121,19 @@ export class HubGoals extends BasicSerializableObject {
getShapesStored(definition) {
return this.storedShapes[definition.getHash()] || 0;
}
/**
* @param {string} key
* @param {number} amount
*/
takeShapeByKey(key, amount) {
assert(this.getShapesStoredByKey(key) >= amount, "Can not afford: " + key + " x " + amount);
assert(amount > 0, "Amount <= 0 for " + key);
assert(Number.isInteger(amount), "Invalid amount: " + amount);
this.storedShapes[key] -= amount;
return;
}
/**
* Returns how much of the current shape is stored
* @param {string} key

@ -4,6 +4,9 @@ import { createLogger } from "../../../core/logging";
import { Vector } from "../../../core/vector";
import { Entity } from "../../entity";
import { GameRoot } from "../../root";
import { findNiceIntegerValue } from "../../../core/utils";
import { Math_pow } from "../../../core/builtins";
import { blueprintShape } from "../../upgrades";
const logger = createLogger("blueprint");
@ -47,6 +50,13 @@ export class Blueprint {
return new Blueprint(newEntities);
}
/**
* Returns the cost of this blueprint in shapes
*/
getCost() {
return findNiceIntegerValue(4 * Math_pow(this.entities.length, 1.1));
}
/**
* Draws the blueprint at the given origin
* @param {DrawParameters} parameters
@ -147,6 +157,13 @@ export class Blueprint {
return anyPlaceable;
}
/**
* @param {GameRoot} root
*/
canAfford(root) {
return root.hubGoals.getShapesStoredByKey(blueprintShape) >= this.getCost();
}
/**
* Attempts to place the blueprint at the given tile
* @param {GameRoot} root

@ -6,9 +6,23 @@ 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) {}
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);
@ -27,6 +41,9 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
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() {
@ -37,7 +54,25 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
}
}
onBlueprintChanged(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)
);
}
/**
* @param {Blueprint} blueprint
*/
onBlueprintChanged(blueprint) {
if (blueprint) {
this.costDisplayText.innerText = "" + blueprint.getCost();
}
}
/**
* mouse down pre handler
@ -55,9 +90,17 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
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);

@ -77,7 +77,7 @@ export class HUDPinnedShapes extends BaseHUDPart {
this.internalPinShape(currentKey, currentGoal.required, false);
if (this.root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_blueprints)) {
this.internalPinShape(blueprintShape, currentGoal.required, false);
this.internalPinShape(blueprintShape, null, false);
}
for (let i = 0; i < this.pinnedShapes.length; ++i) {
@ -114,7 +114,10 @@ export class HUDPinnedShapes extends BaseHUDPart {
}
const amountLabel = makeDiv(element, null, ["amountLabel"], "");
const goalLabel = makeDiv(element, null, ["goalLabel"], "/" + formatBigNumber(goal));
if (goal) {
makeDiv(element, null, ["goalLabel"], "/" + formatBigNumber(goal));
}
this.handles.push({
key,

@ -298,6 +298,10 @@ ingame:
showHint: Show hint
hideHint: Close
# When placing a blueprint
blueprintPlacer:
cost: Cost
# All shop upgrades
shopUpgrades:
belt:

Loading…
Cancel
Save