From af980c7114a19e657931c9e3560e26637cdbd24b Mon Sep 17 00:00:00 2001 From: Greg Considine Date: Wed, 17 Mar 2021 20:57:20 -0400 Subject: [PATCH] Add hidden HUD elements, zone, and zoom, boundary constraints --- src/js/core/config.local.template.js | 3 + src/js/game/camera.js | 39 +++++-- src/js/game/core.js | 5 +- src/js/game/game_mode.js | 136 ++++++++++++++++++++++--- src/js/game/game_system_manager.js | 6 ++ src/js/game/hud/hud.js | 69 ++++++++----- src/js/game/hud/parts/pinned_shapes.js | 4 + src/js/game/hud/parts/waypoints.js | 12 +-- src/js/game/map_chunk_view.js | 9 +- src/js/game/modes/puzzle.js | 99 ++++++++++++++++++ src/js/game/modes/puzzle_edit.js | 12 ++- src/js/game/modes/puzzle_play.js | 14 ++- src/js/game/modes/regular.js | 42 +++----- src/js/game/systems/map_zone.js | 60 +++++++++++ src/js/game/themes/dark.json | 5 + src/js/game/themes/light.json | 5 + src/js/savegame/savegame_typedefs.js | 2 +- src/js/states/main_menu.js | 5 +- 18 files changed, 433 insertions(+), 94 deletions(-) create mode 100644 src/js/game/modes/puzzle.js create mode 100644 src/js/game/systems/map_zone.js diff --git a/src/js/core/config.local.template.js b/src/js/core/config.local.template.js index 5e3cdad6..fc71c01e 100644 --- a/src/js/core/config.local.template.js +++ b/src/js/core/config.local.template.js @@ -62,6 +62,9 @@ export default { // Allows unlocked achievements to be logged to console in the local build // testAchievements: true, // ----------------------------------------------------------------------------------- + // Enables use of (some) existing flags within the puzzle mode context + // testPuzzleMode: true, + // ----------------------------------------------------------------------------------- // Disables the automatic switch to an overview when zooming out // disableMapOverview: true, // ----------------------------------------------------------------------------------- diff --git a/src/js/game/camera.js b/src/js/game/camera.js index 107d1fb4..b6fcebb5 100644 --- a/src/js/game/camera.js +++ b/src/js/game/camera.js @@ -392,13 +392,20 @@ export class Camera extends BasicSerializableObject { return rect.containsPoint(point.x, point.y); } + getMaximumZoom() { + return this.root.gameMode.getMaximumZoom() * this.root.app.platformWrapper.getScreenScale(); + } + + getMinimumZoom() { + return this.root.gameMode.getMinimumZoom() * this.root.app.platformWrapper.getScreenScale(); + } + /** * Returns if we can further zoom in * @returns {boolean} */ canZoomIn() { - const maxLevel = this.root.app.platformWrapper.getMaximumZoom(); - return this.zoomLevel <= maxLevel - 0.01; + return this.zoomLevel <= this.getMaximumZoom() - 0.01; } /** @@ -406,8 +413,7 @@ export class Camera extends BasicSerializableObject { * @returns {boolean} */ canZoomOut() { - const minLevel = this.root.app.platformWrapper.getMinimumZoom(); - return this.zoomLevel >= minLevel + 0.01; + return this.zoomLevel >= this.getMinimumZoom() + 0.01; } // EVENTS @@ -705,6 +711,7 @@ export class Camera extends BasicSerializableObject { this.didMoveSinceTouchStart = this.didMoveSinceTouchStart || delta.length() > 0; this.center = this.center.add(delta); + this.clampPosition(this.center); this.touchPostMoveVelocity = this.touchPostMoveVelocity .multiplyScalar(velocitySmoothing) @@ -743,17 +750,31 @@ export class Camera extends BasicSerializableObject { if (G_IS_DEV && globalConfig.debug.disableZoomLimits) { return; } - const wrapper = this.root.app.platformWrapper; - assert(Number.isFinite(this.zoomLevel), "Invalid zoom level *before* clamp: " + this.zoomLevel); - this.zoomLevel = clamp(this.zoomLevel, wrapper.getMinimumZoom(), wrapper.getMaximumZoom()); + this.zoomLevel = clamp(this.zoomLevel, this.getMinimumZoom(), this.getMaximumZoom()); assert(Number.isFinite(this.zoomLevel), "Invalid zoom level *after* clamp: " + this.zoomLevel); if (this.desiredZoom) { - this.desiredZoom = clamp(this.desiredZoom, wrapper.getMinimumZoom(), wrapper.getMaximumZoom()); + this.desiredZoom = clamp(this.desiredZoom, this.getMinimumZoom(), this.getMaximumZoom()); } } + /** + * Clamps x, y position within set boundaries + * @param {Vector} vector + */ + clampPosition(vector) { + if (!this.root.gameMode.hasBoundaries()) { + return; + } + + const width = this.root.gameMode.getBoundaryWidth(); + const height = this.root.gameMode.getBoundaryHeight(); + + vector.x = clamp(vector.x, -width, width); + vector.y = clamp(vector.y, -height, height); + } + /** * Updates the camera * @param {number} dt Delta time in milliseconds @@ -921,6 +942,8 @@ export class Camera extends BasicSerializableObject { ((0.5 * dt) / this.zoomLevel) * this.root.app.settings.getMovementSpeed() ) ); + + this.clampPosition(this.center) } /** diff --git a/src/js/game/core.js b/src/js/game/core.js index 17013845..d9d73cae 100644 --- a/src/js/game/core.js +++ b/src/js/game/core.js @@ -9,7 +9,6 @@ import { registerCanvas, } from "../core/buffer_utils"; import { globalConfig } from "../core/config"; -import { gGameModeRegistry } from "./game_mode_registry"; import { getDeviceDPI, resizeHighDPICanvas } from "../core/dpi_manager"; import { DrawParameters } from "../core/draw_parameters"; import { gMetaBuildingRegistry } from "../core/global_registries"; @@ -169,6 +168,10 @@ export class GameCore { this.root.gameIsFresh = true; this.root.map.seed = randomInt(0, 100000); + if (!this.root.gameMode.hasHub()) { + return; + } + // Place the hub const hub = gMetaBuildingRegistry.findByClass(MetaHubBuilding).createEntity({ root: this.root, diff --git a/src/js/game/game_mode.js b/src/js/game/game_mode.js index 32d7298d..ece52e20 100644 --- a/src/js/game/game_mode.js +++ b/src/js/game/game_mode.js @@ -5,50 +5,160 @@ import { GameRoot } from "./root"; import { gGameModeRegistry } from "../core/global_registries"; import { types, BasicSerializableObject } from "../savegame/serialization"; +/** @enum {string} */ +export const enumGameModeIds = { + puzzleEdit: "puzzleEditMode", + puzzlePlay: "puzzlePlayMode", + regular: "regularMode", +}; + +/** @enum {string} */ +export const enumGameModeTypes = { + default: "defaultModeType", + puzzle: "puzzleModeType", +}; + export class GameMode extends BasicSerializableObject { /** @returns {string} */ static getId() { abstract; - return "Unknown"; + return "unknownMode"; } - static getSchema() { - return {}; + /** @returns {string} */ + static getType() { + abstract; + return "unknownType"; } - /** * @param {GameRoot} root * @param {string} [id=Regular] */ - static create (root, id = "Regular") { - // id = "Regular" + static create(root, id = enumGameModeIds.regular) { return new (gGameModeRegistry.findById(id))(root); } /** * @param {GameRoot} root - * @param {string} [id=Regular] */ constructor(root) { super(); this.root = root; } + /** @returns {object} */ serialize() { return { $: this.getId(), - data: super.serialize() - } + data: super.serialize(), + }; } - deserialize({ $, data }) { - const Mode = gGameModeRegistry.findById($); - - return super.deserialize(data, Mode, gGameModeRegistry.getId(), this.root); + /** @param {object} savedata */ + deserialize({ data }) { + super.deserialize(data, this.root); } + /** @returns {string} */ getId() { // @ts-ignore return this.constructor.getId(); } + + /** @returns {string} */ + getType() { + // @ts-ignore + return this.constructor.getType(); + } + + /** + * @param {string} name - Class name of HUD Part + * @returns {boolean} + */ + isHudPartHidden(name) { + return false; + } + + /** + * @param {string} name - Class name of HUD Part + * @returns {boolean} + */ + isHudPartExcluded(name) { + return false; + } + + /** @returns {boolean} */ + hasZone() { + return false; + } + + /** @returns {boolean} */ + hasHints() { + return true; + } + + /** @returns {boolean} */ + hasHub() { + return true; + } + + /** @returns {boolean} */ + hasResources() { + return true; + } + + /** @returns {boolean} */ + hasBoundaries() { + return false; + } + + /** @returns {number} */ + getMinimumZoom() { + return 0.1; + } + + /** @returns {number} */ + getMaximumZoom() { + return 3.5; + } + + /** @returns {object} */ + getUpgrades() { + return {}; + } + + /** @returns {number} */ + getZoneWidth() { + return 0; + } + + /** @returns {number} */ + getZoneHeight() { + return 0; + } + + /** @returns {number} */ + getBoundaryWidth() { + return Infinity; + } + + /** @returns {number} */ + getBoundaryHeight() { + return Infinity; + } + + /** @returns {array} */ + getLevelDefinitions() { + return []; + } + + /** @returns {boolean} */ + getIsFreeplayAvailable() { + return false; + } + + /** @returns {string} */ + getBlueprintShapeKey() { + return "CbCbCbRb:CwCwCwCw"; + } } diff --git a/src/js/game/game_system_manager.js b/src/js/game/game_system_manager.js index 74ba798f..185d2c06 100644 --- a/src/js/game/game_system_manager.js +++ b/src/js/game/game_system_manager.js @@ -6,6 +6,7 @@ import { createLogger } from "../core/logging"; import { BeltSystem } from "./systems/belt"; import { ItemEjectorSystem } from "./systems/item_ejector"; import { MapResourcesSystem } from "./systems/map_resources"; +import { MapZoneSystem } from "./systems/map_zone"; import { MinerSystem } from "./systems/miner"; import { ItemProcessorSystem } from "./systems/item_processor"; import { UndergroundBeltSystem } from "./systems/underground_belt"; @@ -46,6 +47,9 @@ export class GameSystemManager { /** @type {MapResourcesSystem} */ mapResources: null, + /** @type {MapZoneSystem} */ + mapZone: null, + /** @type {MinerSystem} */ miner: null, @@ -140,6 +144,8 @@ export class GameSystemManager { add("mapResources", MapResourcesSystem); + add("mapZone", MapZoneSystem); + add("hub", HubSystem); add("staticMapEntities", StaticMapEntitySystem); diff --git a/src/js/game/hud/hud.js b/src/js/game/hud/hud.js index d64f96a8..5f731d1f 100644 --- a/src/js/game/hud/hud.js +++ b/src/js/game/hud/hud.js @@ -74,42 +74,42 @@ export class GameHUD { unlockNotificationFinished: /** @type {TypedSignal<[]>} */ (new Signal()), }; - this.parts = { - buildingsToolbar: new HUDBuildingsToolbar(this.root), - wiresToolbar: new HUDWiresToolbar(this.root), - blueprintPlacer: new HUDBlueprintPlacer(this.root), - buildingPlacer: new HUDBuildingPlacer(this.root), - unlockNotification: new HUDUnlockNotification(this.root), - gameMenu: new HUDGameMenu(this.root), - massSelector: new HUDMassSelector(this.root), - shop: new HUDShop(this.root), - statistics: new HUDStatistics(this.root), - waypoints: new HUDWaypoints(this.root), - wireInfo: new HUDWireInfo(this.root), - leverToggle: new HUDLeverToggle(this.root), - constantSignalEdit: new HUDConstantSignalEdit(this.root), + this.initParts({ + buildingsToolbar: HUDBuildingsToolbar, + wiresToolbar: HUDWiresToolbar, + blueprintPlacer: HUDBlueprintPlacer, + buildingPlacer: HUDBuildingPlacer, + unlockNotification: HUDUnlockNotification, + gameMenu: HUDGameMenu, + massSelector: HUDMassSelector, + shop: HUDShop, + statistics: HUDStatistics, + waypoints: HUDWaypoints, + wireInfo: HUDWireInfo, + leverToggle: HUDLeverToggle, + constantSignalEdit: HUDConstantSignalEdit, // Must always exist - pinnedShapes: new HUDPinnedShapes(this.root), - notifications: new HUDNotifications(this.root), - settingsMenu: new HUDSettingsMenu(this.root), - debugInfo: new HUDDebugInfo(this.root), - dialogs: new HUDModalDialogs(this.root), - screenshotExporter: new HUDScreenshotExporter(this.root), - shapeViewer: new HUDShapeViewer(this.root), + pinnedShapes: HUDPinnedShapes, + notifications: HUDNotifications, + settingsMenu: HUDSettingsMenu, + debugInfo: HUDDebugInfo, + dialogs: HUDModalDialogs, + screenshotExporter: HUDScreenshotExporter, + shapeViewer: HUDShapeViewer, - wiresOverlay: new HUDWiresOverlay(this.root), - layerPreview: new HUDLayerPreview(this.root), + wiresOverlay: HUDWiresOverlay, + layerPreview: HUDLayerPreview, - minerHighlight: new HUDMinerHighlight(this.root), - tutorialVideoOffer: new HUDTutorialVideoOffer(this.root), + minerHighlight: HUDMinerHighlight, + tutorialVideoOffer: HUDTutorialVideoOffer, // Typing hints /* typehints:start */ /** @type {HUDChangesDebugger} */ changesDebugger: null, /* typehints:end */ - }; + }); if (!IS_MOBILE) { this.parts.keybindingOverlay = new HUDKeybindingOverlay(this.root); @@ -129,7 +129,7 @@ export class GameHUD { this.parts.changesDebugger = new HUDChangesDebugger(this.root); } - if (this.root.app.settings.getAllSettings().offerHints) { + if (this.root.gameMode.hasHints() && this.root.app.settings.getAllSettings().offerHints) { this.parts.tutorialHints = new HUDPartTutorialHints(this.root); this.parts.interactiveTutorial = new HUDInteractiveTutorial(this.root); } @@ -170,6 +170,21 @@ export class GameHUD { /* dev:end*/ } + /** @param {object} parts */ + initParts(parts) { + this.parts = {}; + + for (let key in parts) { + const Part = parts[key]; + + if (!Part || this.root.gameMode.isHudPartExcluded(Part)) { + continue; + } + + this.parts[key] = new Part(this.root); + } + } + /** * Attempts to close all overlays */ diff --git a/src/js/game/hud/parts/pinned_shapes.js b/src/js/game/hud/parts/pinned_shapes.js index 4a9fce0d..f2ab6046 100644 --- a/src/js/game/hud/parts/pinned_shapes.js +++ b/src/js/game/hud/parts/pinned_shapes.js @@ -153,6 +153,10 @@ export class HUDPinnedShapes extends BaseHUDPart { * Rerenders the whole component */ rerenderFull() { + if (this.root.gameMode.isHudPartHidden(this.constructor.name)) { + return; + } + const currentGoal = this.root.hubGoals.currentGoal; const currentKey = currentGoal.definition.getHash(); diff --git a/src/js/game/hud/parts/waypoints.js b/src/js/game/hud/parts/waypoints.js index 1a0e3739..b21eeea0 100644 --- a/src/js/game/hud/parts/waypoints.js +++ b/src/js/game/hud/parts/waypoints.js @@ -100,16 +100,16 @@ export class HUDWaypoints extends BaseHUDPart { this.directionIndicatorSprite = Loader.getSprite("sprites/misc/hub_direction_indicator.png"); - /** @type {Array} - */ - this.waypoints = [ - { + /** @type {Array} */ + this.waypoints = []; + if (this.root.gameMode.hasHub()) { + this.waypoints.push({ label: null, center: { x: 0, y: 0 }, zoomLevel: 3, layer: gMetaBuildingRegistry.findByClass(MetaHubBuilding).getLayer(), - }, - ]; + }); + } // Create a buffer we can use to measure text this.dummyBuffer = makeOffscreenBuffer(1, 1, { diff --git a/src/js/game/map_chunk_view.js b/src/js/game/map_chunk_view.js index 848afbab..8543b376 100644 --- a/src/js/game/map_chunk_view.js +++ b/src/js/game/map_chunk_view.js @@ -41,7 +41,14 @@ export class MapChunkView extends MapChunk { */ drawBackgroundLayer(parameters) { const systems = this.root.systemMgr.systems; - systems.mapResources.drawChunk(parameters, this); + if (this.root.gameMode.hasZone()) { + systems.mapZone.drawChunk(parameters, this); + } + + if (this.root.gameMode.hasResources()) { + systems.mapResources.drawChunk(parameters, this); + } + systems.beltUnderlays.drawChunk(parameters, this); systems.belt.drawChunk(parameters, this); } diff --git a/src/js/game/modes/puzzle.js b/src/js/game/modes/puzzle.js new file mode 100644 index 00000000..ed58f850 --- /dev/null +++ b/src/js/game/modes/puzzle.js @@ -0,0 +1,99 @@ +/* typehints:start */ +import { GameRoot } from "../root"; +/* typehints:end */ + +import { globalConfig } from "../../core/config"; +import { types } from "../../savegame/serialization"; +import { HUDPinnedShapes } from "../hud/parts/pinned_shapes"; +import { enumGameModeTypes, GameMode } from "../game_mode"; + +export class PuzzleGameMode extends GameMode { + static getType() { + return enumGameModeTypes.puzzle; + } + + static getSchema() { + return { + hiddenHudParts: types.keyValueMap(types.bool), + zoneHeight: types.uint, + zoneWidth: types.uint, + }; + } + + /** @param {GameRoot} root */ + constructor(root) { + super(root); + } + + initialize() { + const data = this.getSaveData(); + + this.type = this.getType(); + this.hiddenHudParts = data.hiddenHudParts || this.getDefaultHiddenHudParts(); +// this.excludedHudParts = data.hiddenHudParts || this.getDefaultHiddenHudParts(); + this.zoneHeight = data.zoneHeight || (3 * globalConfig.tileSize); + this.zoneWidth = data.zoneWidth || (4 * globalConfig.tileSize); + this.boundaryHeight = this.zoneHeight * 2; + this.boundaryWidth = this.zoneWidth * 2; + } + + getSaveData() { + const save = this.root.savegame.getCurrentDump(); + + if (!save) { + return {}; + } + + return save.gameMode.data; + } + + getDefaultHiddenHudParts() { + return { + [HUDPinnedShapes.name]: true + }; + } + + isHudPartHidden(name) { + return this.hiddenHudParts[name]; + } + + hasZone() { + return true; + } + + hasHints() { + return false; + } + + hasHub() { + return false; + } + + hasResources() { + return false; + } + + hasBoundaries() { + return true; + } + + getMinimumZoom() { + return 1; + } + + getBoundaryWidth() { + return this.boundaryWidth; + } + + getBoundaryHeight() { + return this.boundaryHeight; + } + + getZoneWidth() { + return this.zoneWidth; + } + + getZoneHeight() { + return this.zoneHeight; + } +} diff --git a/src/js/game/modes/puzzle_edit.js b/src/js/game/modes/puzzle_edit.js index 39dc24dc..5e2cf6fd 100644 --- a/src/js/game/modes/puzzle_edit.js +++ b/src/js/game/modes/puzzle_edit.js @@ -1,10 +1,16 @@ -import { GameMode } from "../game_mode"; +/* typehints:start */ +import { GameRoot } from "../root"; +/* typehints:end */ -export class PuzzleEditGameMode extends GameMode { +import { PuzzleGameMode } from "./puzzle"; +import { enumGameModeIds } from "../game_mode"; + +export class PuzzleEditGameMode extends PuzzleGameMode { static getId() { - return "PuzzleEdit"; + return enumGameModeIds.puzzleEdit; } + /** @param {GameRoot} root */ constructor(root) { super(root); } diff --git a/src/js/game/modes/puzzle_play.js b/src/js/game/modes/puzzle_play.js index 30c817c7..a4a778be 100644 --- a/src/js/game/modes/puzzle_play.js +++ b/src/js/game/modes/puzzle_play.js @@ -1,12 +1,18 @@ -import { GameMode } from "../game_mode"; +/* typehints:start */ +import { GameRoot } from "../root"; +/* typehints:end */ -export class PuzzlePlayGameMode extends GameMode { +import { PuzzleGameMode } from "./puzzle"; +import { enumGameModeIds } from "../game_mode"; + +export class PuzzlePlayGameMode extends PuzzleGameMode { static getId() { - return "PuzzlePlay"; + return enumGameModeIds.puzzlePlay; } - /** param {GameRoot} root */ + /** @param {GameRoot} root */ constructor(root) { super(root); + this.initialize(); } } diff --git a/src/js/game/modes/regular.js b/src/js/game/modes/regular.js index ed1da27e..5055ed2d 100644 --- a/src/js/game/modes/regular.js +++ b/src/js/game/modes/regular.js @@ -1,10 +1,9 @@ /* typehints:start */ -import { enumHubGoalRewards } from "../tutorial_goals"; import { GameRoot } from "../root"; /* typehints:end */ import { findNiceIntegerValue } from "../../core/utils"; -import { GameMode } from "../game_mode"; +import { enumGameModeIds, enumGameModeTypes, GameMode } from "../game_mode"; import { ShapeDefinition } from "../shape_definition"; import { enumHubGoalRewards } from "../tutorial_goals"; import { types } from "../../savegame/serialization"; @@ -32,14 +31,13 @@ import { types } from "../../savegame/serialization"; const rocketShape = "CbCuCbCu:Sr------:--CrSrCr:CwCwCwCw"; const finalGameShape = "RuCw--Cw:----Ru--"; const preparementShape = "CpRpCp--:SwSwSwSw"; -const blueprintShape = "CbCbCbRb:CwCwCwCw"; // Tiers need % of the previous tier as requirement too const tierGrowth = 2.5; /** * Generates all upgrades - * @returns {Object} */ + * @returns {Object} */ function generateUpgrades(limitedVersion = false) { const fixedImprovements = [0.5, 0.5, 1, 1, 2, 1, 1]; const numEndgameUpgrades = limitedVersion ? 0 : 1000 - fixedImprovements.length - 1; @@ -481,18 +479,16 @@ const demoVersionLevels = generateLevelDefinitions(true); export class RegularGameMode extends GameMode { static getId() { - return "Regular"; + return enumGameModeIds.regular; } - static getSchema() { - return { - test: types.string - } + static getType() { + return enumGameModeTypes.default; } + /** @param {GameRoot} root */ constructor(root) { super(root); - this.test = "test"; } /** @@ -505,23 +501,6 @@ export class RegularGameMode extends GameMode { : demoVersionUpgrades; } - /** - * Should return whether free play is available or if the game stops - * after the predefined levels - * @returns {boolean} - */ - getIsFreeplayAvailable() { - return this.root.app.restrictionMgr.getHasExtendedLevelsAndFreeplay(); - } - - /** - * Returns the blueprint shape key - * @returns {string} - */ - getBlueprintShapeKey() { - return blueprintShape; - } - /** * Returns the goals for all levels including their reward * @returns {Array} @@ -531,4 +510,13 @@ export class RegularGameMode extends GameMode { ? fullVersionLevels : demoVersionLevels; } + + /** + * Should return whether free play is available or if the game stops + * after the predefined levels + * @returns {boolean} + */ + getIsFreeplayAvailable() { + return this.root.app.restrictionMgr.getHasExtendedLevelsAndFreeplay(); + } } diff --git a/src/js/game/systems/map_zone.js b/src/js/game/systems/map_zone.js new file mode 100644 index 00000000..90e9bf26 --- /dev/null +++ b/src/js/game/systems/map_zone.js @@ -0,0 +1,60 @@ +/* typehints:start */ +import { DrawParameters } from "../../core/draw_parameters"; +import { MapChunkView } from "../map_chunk_view"; +/* typehints:end */ + +import { globalConfig } from "../../core/config"; +import { drawSpriteClipped } from "../../core/draw_utils"; +import { GameSystem } from "../game_system"; +import { THEME } from "../theme"; + +export class MapZoneSystem extends GameSystem { + /** + * Draws the map resources + * @param {DrawParameters} parameters + * @param {MapChunkView} chunk + */ + drawChunk(parameters, chunk) { + const width = this.root.gameMode.getZoneWidth(); + const height = this.root.gameMode.getZoneHeight(); + + const zoneChunkBackground = this.root.buffers.getForKey({ + key: "mapzonebg", + subKey: chunk.renderKey, + w: width, + h: height, + dpi: 1, + redrawMethod: this.generateChunkBackground.bind(this, chunk), + }); + + parameters.context.imageSmoothingEnabled = false; + drawSpriteClipped({ + parameters, + sprite: zoneChunkBackground, + x: -width, + y: -height, + w: this.root.gameMode.getBoundaryWidth(), + h: this.root.gameMode.getBoundaryHeight(), + originalW: width, + originalH: height, + }); + parameters.context.imageSmoothingEnabled = true; + } + + /** + * @param {MapChunkView} chunk + * @param {HTMLCanvasElement} canvas + * @param {CanvasRenderingContext2D} context + * @param {number} w + * @param {number} h + * @param {number} dpi + */ + generateChunkBackground(chunk, canvas, context, w, h, dpi) { + context.clearRect(0, 0, w, h); + + context.fillStyle = THEME.map.zone.background; + context.strokeStyle = THEME.map.zone.border; + context.fillRect(0, 0, w, h); + context.strokeRect(0, 0, w, h); + } +} diff --git a/src/js/game/themes/dark.json b/src/js/game/themes/dark.json index 733b7682..02ff6ae3 100644 --- a/src/js/game/themes/dark.json +++ b/src/js/game/themes/dark.json @@ -47,6 +47,11 @@ "textColor": "#fff", "textColorCapped": "#ef5072", "background": "rgba(40, 50, 60, 0.8)" + }, + + "zone": { + "background": "#3e3f47", + "border": "#667964" } }, diff --git a/src/js/game/themes/light.json b/src/js/game/themes/light.json index 0c793c26..4aa367fd 100644 --- a/src/js/game/themes/light.json +++ b/src/js/game/themes/light.json @@ -48,6 +48,11 @@ "textColor": "#fff", "textColorCapped": "#ef5072", "background": "rgba(40, 50, 60, 0.8)" + }, + + "zone": { + "background": "#fff", + "border": "#cbffc4" } }, diff --git a/src/js/savegame/savegame_typedefs.js b/src/js/savegame/savegame_typedefs.js index 6a256056..49929f99 100644 --- a/src/js/savegame/savegame_typedefs.js +++ b/src/js/savegame/savegame_typedefs.js @@ -12,7 +12,7 @@ * time: any, * entityMgr: any, * map: any, - * gameMode: any, + * gameMode: object, * hubGoals: any, * pinnedShapes: any, * waypoints: any, diff --git a/src/js/states/main_menu.js b/src/js/states/main_menu.js index 90f57e7d..24c33b5f 100644 --- a/src/js/states/main_menu.js +++ b/src/js/states/main_menu.js @@ -15,7 +15,7 @@ import { startFileChoose, waitNextFrame, } from "../core/utils"; -import { gGameModeRegistry } from "../core/global_registries"; +import { enumGameModeIds } from "../game/game_mode"; import { HUDModalDialogs } from "../game/hud/parts/modal_dialogs"; import { getApplicationSettingById } from "../profile/application_settings"; import { T } from "../translations"; @@ -360,10 +360,9 @@ export class MainMenuState extends GameState { onPuzzlePlayButtonClicked() { const savegame = this.app.savegameMgr.createNewSavegame(); - const gameModeId = gGameModeRegistry.idToEntry.PuzzlePlay.getId(); this.moveToState("InGameState", { - gameModeId, + gameModeId: enumGameModeIds.puzzlePlay, savegame, }); }