mirror of
https://github.com/tobspr/shapez.io.git
synced 2024-10-27 20:34:29 +00:00
Introduce cost for blueprints
This commit is contained in:
parent
955cba74aa
commit
37685d64bd
39
src/css/ingame_hud/blueprint_placer.scss
Normal file
39
src/css/ingame_hud/blueprint_placer.scss
Normal file
@ -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/entity_debugger";
|
||||||
@import "ingame_hud/tutorial_hints";
|
@import "ingame_hud/tutorial_hints";
|
||||||
@import "ingame_hud/watermark";
|
@import "ingame_hud/watermark";
|
||||||
|
@import "ingame_hud/blueprint_placer";
|
||||||
|
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
$elements:
|
$elements:
|
||||||
@ -68,6 +69,7 @@ ingame_HUD_DebugInfo,
|
|||||||
ingame_HUD_EntityDebugger,
|
ingame_HUD_EntityDebugger,
|
||||||
ingame_HUD_TutorialHints,
|
ingame_HUD_TutorialHints,
|
||||||
ingame_HUD_buildings_toolbar,
|
ingame_HUD_buildings_toolbar,
|
||||||
|
ingame_HUD_BlueprintPlacer,
|
||||||
ingame_HUD_Watermark,
|
ingame_HUD_Watermark,
|
||||||
|
|
||||||
// Overlays
|
// Overlays
|
||||||
|
@ -83,7 +83,7 @@ export const globalConfig = {
|
|||||||
|
|
||||||
debug: {
|
debug: {
|
||||||
/* dev:start */
|
/* dev:start */
|
||||||
// fastGameEnter: true,
|
fastGameEnter: true,
|
||||||
// noArtificialDelays: true,
|
// noArtificialDelays: true,
|
||||||
// disableSavegameWrite: true,
|
// disableSavegameWrite: true,
|
||||||
// showEntityBounds: true,
|
// showEntityBounds: true,
|
||||||
|
@ -8,7 +8,7 @@ import { enumItemProcessorTypes } from "./components/item_processor";
|
|||||||
import { GameRoot } from "./root";
|
import { GameRoot } from "./root";
|
||||||
import { enumSubShape, ShapeDefinition } from "./shape_definition";
|
import { enumSubShape, ShapeDefinition } from "./shape_definition";
|
||||||
import { enumHubGoalRewards, tutorialGoals } from "./tutorial_goals";
|
import { enumHubGoalRewards, tutorialGoals } from "./tutorial_goals";
|
||||||
import { UPGRADES } from "./upgrades";
|
import { UPGRADES, blueprintShape } from "./upgrades";
|
||||||
|
|
||||||
export class HubGoals extends BasicSerializableObject {
|
export class HubGoals extends BasicSerializableObject {
|
||||||
static getId() {
|
static getId() {
|
||||||
@ -53,6 +53,10 @@ export class HubGoals extends BasicSerializableObject {
|
|||||||
}
|
}
|
||||||
this.upgradeImprovements[upgradeId] = totalImprovement;
|
this.upgradeImprovements[upgradeId] = totalImprovement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (G_IS_DEV) {
|
||||||
|
this.storedShapes[blueprintShape] = 1000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,6 +81,10 @@ export class HubGoals extends BasicSerializableObject {
|
|||||||
*/
|
*/
|
||||||
this.storedShapes = {};
|
this.storedShapes = {};
|
||||||
|
|
||||||
|
if (G_IS_DEV) {
|
||||||
|
this.storedShapes[blueprintShape] = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the levels for all upgrades
|
* Stores the levels for all upgrades
|
||||||
* @type {Object<string, number>}
|
* @type {Object<string, number>}
|
||||||
@ -113,6 +121,19 @@ export class HubGoals extends BasicSerializableObject {
|
|||||||
getShapesStored(definition) {
|
getShapesStored(definition) {
|
||||||
return this.storedShapes[definition.getHash()] || 0;
|
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
|
* Returns how much of the current shape is stored
|
||||||
* @param {string} key
|
* @param {string} key
|
||||||
|
@ -4,6 +4,9 @@ import { createLogger } from "../../../core/logging";
|
|||||||
import { Vector } from "../../../core/vector";
|
import { Vector } from "../../../core/vector";
|
||||||
import { Entity } from "../../entity";
|
import { Entity } from "../../entity";
|
||||||
import { GameRoot } from "../../root";
|
import { GameRoot } from "../../root";
|
||||||
|
import { findNiceIntegerValue } from "../../../core/utils";
|
||||||
|
import { Math_pow } from "../../../core/builtins";
|
||||||
|
import { blueprintShape } from "../../upgrades";
|
||||||
|
|
||||||
const logger = createLogger("blueprint");
|
const logger = createLogger("blueprint");
|
||||||
|
|
||||||
@ -47,6 +50,13 @@ export class Blueprint {
|
|||||||
return new Blueprint(newEntities);
|
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
|
* Draws the blueprint at the given origin
|
||||||
* @param {DrawParameters} parameters
|
* @param {DrawParameters} parameters
|
||||||
@ -147,6 +157,13 @@ export class Blueprint {
|
|||||||
return anyPlaceable;
|
return anyPlaceable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {GameRoot} root
|
||||||
|
*/
|
||||||
|
canAfford(root) {
|
||||||
|
return root.hubGoals.getShapesStoredByKey(blueprintShape) >= this.getCost();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to place the blueprint at the given tile
|
* Attempts to place the blueprint at the given tile
|
||||||
* @param {GameRoot} root
|
* @param {GameRoot} root
|
||||||
|
@ -6,9 +6,23 @@ import { enumMouseButton } from "../../camera";
|
|||||||
import { KEYMAPPINGS } from "../../key_action_mapper";
|
import { KEYMAPPINGS } from "../../key_action_mapper";
|
||||||
import { BaseHUDPart } from "../base_hud_part";
|
import { BaseHUDPart } from "../base_hud_part";
|
||||||
import { Blueprint } from "./blueprint";
|
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 {
|
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() {
|
initialize() {
|
||||||
this.root.hud.signals.buildingsSelectedForCopy.add(this.onBuildingsSelected, this);
|
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.camera.movePreHandler.add(this.onMouseMove, this);
|
||||||
|
|
||||||
this.root.hud.signals.selectedPlacementBuildingChanged.add(this.abortPlacement, 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() {
|
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
|
* mouse down pre handler
|
||||||
@ -55,9 +90,17 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!blueprint.canAfford(this.root)) {
|
||||||
|
this.root.soundProxy.playUiError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const worldPos = this.root.camera.screenToWorld(pos);
|
const worldPos = this.root.camera.screenToWorld(pos);
|
||||||
const tile = worldPos.toTileSpace();
|
const tile = worldPos.toTileSpace();
|
||||||
if (blueprint.tryPlace(this.root, tile)) {
|
if (blueprint.tryPlace(this.root, tile)) {
|
||||||
|
const cost = blueprint.getCost();
|
||||||
|
this.root.hubGoals.takeShapeByKey(blueprintShape, cost);
|
||||||
|
|
||||||
// This actually feels weird
|
// This actually feels weird
|
||||||
// if (!this.root.keyMapper.getBinding(KEYMAPPINGS.placementModifiers.placeMultiple).isCurrentlyPressed()) {
|
// if (!this.root.keyMapper.getBinding(KEYMAPPINGS.placementModifiers.placeMultiple).isCurrentlyPressed()) {
|
||||||
// this.currentBlueprint.set(null);
|
// this.currentBlueprint.set(null);
|
||||||
|
@ -77,7 +77,7 @@ export class HUDPinnedShapes extends BaseHUDPart {
|
|||||||
this.internalPinShape(currentKey, currentGoal.required, false);
|
this.internalPinShape(currentKey, currentGoal.required, false);
|
||||||
|
|
||||||
if (this.root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_blueprints)) {
|
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) {
|
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 amountLabel = makeDiv(element, null, ["amountLabel"], "");
|
||||||
const goalLabel = makeDiv(element, null, ["goalLabel"], "/" + formatBigNumber(goal));
|
|
||||||
|
if (goal) {
|
||||||
|
makeDiv(element, null, ["goalLabel"], "/" + formatBigNumber(goal));
|
||||||
|
}
|
||||||
|
|
||||||
this.handles.push({
|
this.handles.push({
|
||||||
key,
|
key,
|
||||||
|
@ -298,6 +298,10 @@ ingame:
|
|||||||
showHint: Show hint
|
showHint: Show hint
|
||||||
hideHint: Close
|
hideHint: Close
|
||||||
|
|
||||||
|
# When placing a blueprint
|
||||||
|
blueprintPlacer:
|
||||||
|
cost: Cost
|
||||||
|
|
||||||
# All shop upgrades
|
# All shop upgrades
|
||||||
shopUpgrades:
|
shopUpgrades:
|
||||||
belt:
|
belt:
|
||||||
|
Loading…
Reference in New Issue
Block a user