diff --git a/src/css/ingame_hud/sandbox_controller.scss b/src/css/ingame_hud/sandbox_controller.scss new file mode 100644 index 00000000..78e68cb2 --- /dev/null +++ b/src/css/ingame_hud/sandbox_controller.scss @@ -0,0 +1,47 @@ +#ingame_HUD_SandboxController { + position: absolute; + background: $ingameHudBg; + @include S(padding, 5px); + @include S(bottom, 10px); + @include S(left, 10px); + + @include SuperSmallText; + color: #eee; + display: flex; + flex-direction: column; + + > label { + text-transform: uppercase; + } + + .hint { + color: #aaa; + } + + .plusMinus { + @include S(margin-top, 4px); + display: grid; + grid-template-columns: 1fr auto auto; + align-items: center; + @include S(grid-gap, 4px); + + button { + @include PlainText; + @include S(padding, 0); + display: flex; + align-items: center; + justify-content: center; + @include S(width, 15px); + @include S(height, 15px); + @include IncreasedClickArea(0px); + } + } + + .additionalOptions { + @include S(margin-top, 10px); + button { + @include IncreasedClickArea(0px); + @include SuperSmallText; + } + } +} diff --git a/src/css/main.scss b/src/css/main.scss index 6b758e80..36010e35 100644 --- a/src/css/main.scss +++ b/src/css/main.scss @@ -51,6 +51,7 @@ @import "ingame_hud/interactive_tutorial"; @import "ingame_hud/color_blind_helper"; @import "ingame_hud/shape_viewer"; +@import "ingame_hud/sandbox_controller"; // prettier-ignore $elements: @@ -77,6 +78,7 @@ ingame_HUD_BlueprintPlacer, ingame_HUD_Waypoints_Hint, ingame_HUD_Watermark, ingame_HUD_ColorBlindBelowTileHelper, +ingame_HUD_SandboxController, // Overlays ingame_HUD_BetaOverlay, diff --git a/src/js/core/query_parameters.js b/src/js/core/query_parameters.js index 8a27801f..7837acb5 100644 --- a/src/js/core/query_parameters.js +++ b/src/js/core/query_parameters.js @@ -4,6 +4,7 @@ const options = queryString.parse(location.search); export let queryParamOptions = { embedProvider: null, fullVersion: false, + sandboxMode: false, }; if (options.embed) { @@ -14,3 +15,8 @@ if (options.embed) { if (options.fullVersion && !G_IS_RELEASE) { queryParamOptions.fullVersion = true; } + +// Allow testing full version outside of standalone +if (options.sandboxMode && !G_IS_RELEASE) { + queryParamOptions.sandboxMode = true; +} diff --git a/src/js/game/hud/hud.js b/src/js/game/hud/hud.js index 74cc1727..fd82c2eb 100644 --- a/src/js/game/hud/hud.js +++ b/src/js/game/hud/hud.js @@ -38,6 +38,8 @@ import { HUDColorBlindHelper } from "./parts/color_blind_helper"; import { HUDShapeViewer } from "./parts/shape_viewer"; import { HUDWiresOverlay } from "./parts/wires_overlay"; import { HUDChangesDebugger } from "./parts/debug_changes"; +import { queryParamOptions } from "../../core/query_parameters"; +import { HUDSandboxController } from "./parts/sandbox_controller"; export class GameHUD { /** @@ -123,6 +125,10 @@ export class GameHUD { this.parts.colorBlindHelper = new HUDColorBlindHelper(this.root); } + if (queryParamOptions.sandboxMode || G_IS_DEV) { + this.parts.sandboxController = new HUDSandboxController(this.root); + } + const frag = document.createDocumentFragment(); for (const key in this.parts) { this.parts[key].createElements(frag); diff --git a/src/js/game/hud/parts/sandbox_controller.js b/src/js/game/hud/parts/sandbox_controller.js new file mode 100644 index 00000000..e5158790 --- /dev/null +++ b/src/js/game/hud/parts/sandbox_controller.js @@ -0,0 +1,133 @@ +import { BaseHUDPart } from "../base_hud_part"; +import { makeDiv } from "../../../core/utils"; +import { DynamicDomAttach } from "../dynamic_dom_attach"; +import { blueprintShape, UPGRADES } from "../../upgrades"; +import { enumNotificationType } from "./notifications"; + +export class HUDSandboxController extends BaseHUDPart { + createElements(parent) { + this.element = makeDiv( + parent, + "ingame_HUD_SandboxController", + [], + ` + + Use F6 to toggle this overlay + +
+
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ +
+
+ ` + ); + + const bind = (selector, handler) => this.trackClicks(this.element.querySelector(selector), handler); + + bind(".giveBlueprints", this.giveBlueprints); + bind(".levelToggle .minus", () => this.modifyLevel(-1)); + bind(".levelToggle .plus", () => this.modifyLevel(1)); + + bind(".upgradesBelt .minus", () => this.modifyUpgrade("belt", -1)); + bind(".upgradesBelt .plus", () => this.modifyUpgrade("belt", 1)); + + bind(".upgradesExtraction .minus", () => this.modifyUpgrade("miner", -1)); + bind(".upgradesExtraction .plus", () => this.modifyUpgrade("miner", 1)); + + bind(".upgradesProcessing .minus", () => this.modifyUpgrade("processors", -1)); + bind(".upgradesProcessing .plus", () => this.modifyUpgrade("processors", 1)); + + bind(".upgradesPainting .minus", () => this.modifyUpgrade("painting", -1)); + bind(".upgradesPainting .plus", () => this.modifyUpgrade("painting", 1)); + } + + giveBlueprints() { + this.root.hubGoals.storedShapes[blueprintShape] += 1e4; + } + + modifyUpgrade(id, amount) { + const handle = UPGRADES[id]; + const maxLevel = handle.tiers.length; + + this.root.hubGoals.upgradeLevels[id] = Math.max( + 0, + Math.min(maxLevel, (this.root.hubGoals.upgradeLevels[id] || 0) + amount) + ); + + // Compute improvement + let improvement = 1; + for (let i = 0; i < this.root.hubGoals.upgradeLevels[id]; ++i) { + improvement += handle.tiers[i].improvement; + } + this.root.hubGoals.upgradeImprovements[id] = improvement; + this.root.signals.upgradePurchased.dispatch(id); + this.root.hud.signals.notification.dispatch( + "Upgrade '" + id + "' is now at level " + this.root.hubGoals.upgradeLevels[id], + enumNotificationType.upgrade + ); + } + + modifyLevel(amount) { + this.root.hubGoals.level = Math.max(1, this.root.hubGoals.level + amount); + this.root.hubGoals.createNextGoal(); + + // Clear all shapes of this level + this.root.hubGoals.storedShapes[this.root.hubGoals.currentGoal.definition.getHash()] = 0; + + this.root.hud.signals.notification.dispatch( + "Changed level to " + this.root.hubGoals.level, + enumNotificationType.upgrade + ); + } + + initialize() { + // Allow toggling the controller overlay + this.root.gameState.inputReciever.keydown.add(key => { + if (key.keyCode === 117) { + // F6 + this.toggle(); + } + }); + + this.visible = true; + this.domAttach = new DynamicDomAttach(this.root, this.element); + } + + toggle() { + this.visible = !this.visible; + } + + update() { + this.domAttach.update(this.visible); + } +} diff --git a/src/js/game/root.js b/src/js/game/root.js index 6178691a..e8808317 100644 --- a/src/js/game/root.js +++ b/src/js/game/root.js @@ -133,10 +133,6 @@ export class GameRoot { /** @type {enumEditMode} */ this.editMode = enumEditMode.regular; - if (G_IS_DEV) { - this.editMode = enumEditMode.wires; - } - this.signals = { // Entities entityManuallyPlaced: /** @type {TypedSignal<[Entity]>} */ (new Signal()),