mirror of
https://github.com/tobspr/shapez.io.git
synced 2025-06-13 13:04:03 +00:00
[WIP] Add mode menu. Add factory-based gameMode creation
This commit is contained in:
parent
5ccb2dbd0a
commit
6f0a32f054
@ -5,6 +5,7 @@ import { Factory } from "./factory";
|
||||
* @typedef {import("../game/time/base_game_speed").BaseGameSpeed} BaseGameSpeed
|
||||
* @typedef {import("../game/component").Component} Component
|
||||
* @typedef {import("../game/base_item").BaseItem} BaseItem
|
||||
* @typedef {import("../game/game_mode").GameMode} GameMode
|
||||
* @typedef {import("../game/meta_building").MetaBuilding} MetaBuilding
|
||||
|
||||
|
||||
@ -19,6 +20,9 @@ export let gBuildingsByCategory = null;
|
||||
/** @type {FactoryTemplate<Component>} */
|
||||
export let gComponentRegistry = new Factory("component");
|
||||
|
||||
/** @type {FactoryTemplate<GameMode>} */
|
||||
export let gGameModeRegistry = new Factory("gameMode");
|
||||
|
||||
/** @type {FactoryTemplate<BaseGameSpeed>} */
|
||||
export let gGameSpeedRegistry = new Factory("gamespeed");
|
||||
|
||||
|
@ -9,6 +9,7 @@ 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";
|
||||
@ -31,7 +32,7 @@ import { KeyActionMapper } from "./key_action_mapper";
|
||||
import { GameLogic } from "./logic";
|
||||
import { MapView } from "./map_view";
|
||||
import { defaultBuildingVariant } from "./meta_building";
|
||||
import { RegularGameMode } from "./modes/regular";
|
||||
import { GameMode } from "./game_mode";
|
||||
import { ProductionAnalytics } from "./production_analytics";
|
||||
import { GameRoot } from "./root";
|
||||
import { ShapeDefinitionManager } from "./shape_definition_manager";
|
||||
@ -104,7 +105,7 @@ export class GameCore {
|
||||
root.dynamicTickrate = new DynamicTickrate(root);
|
||||
|
||||
// Init game mode
|
||||
root.gameMode = new RegularGameMode(root);
|
||||
root.gameMode = GameMode.create(root);
|
||||
|
||||
// Init classes
|
||||
root.camera = new Camera(root);
|
||||
|
@ -1,8 +1,10 @@
|
||||
/* typehints:start */
|
||||
import { enumHubGoalRewards } from "./tutorial_goals";
|
||||
import { GameRoot } from "./root";
|
||||
/* typehints:end */
|
||||
|
||||
import { GameRoot } from "./root";
|
||||
import { gGameModeRegistry } from "../core/global_registries";
|
||||
import { types, BasicSerializableObject } from "../savegame/serialization";
|
||||
|
||||
/** @typedef {{
|
||||
* shape: string,
|
||||
@ -24,13 +26,43 @@ import { GameRoot } from "./root";
|
||||
* throughputOnly?: boolean
|
||||
* }} LevelDefinition */
|
||||
|
||||
export class GameMode {
|
||||
/**
|
||||
*
|
||||
* @param {GameRoot} root
|
||||
*/
|
||||
export class GameMode extends BasicSerializableObject {
|
||||
/** @returns {string} */
|
||||
static getId() {
|
||||
abstract;
|
||||
return "unknown-mode";
|
||||
}
|
||||
|
||||
static getSchema() {
|
||||
return {
|
||||
id: types.string
|
||||
}
|
||||
}
|
||||
|
||||
static create (root) {
|
||||
let id;
|
||||
|
||||
if (!root.savegame.gameMode || !root.savegame.gameMode.id) {
|
||||
id = "Regular";
|
||||
} else {
|
||||
id = root.savegame.gameMode.id
|
||||
}
|
||||
|
||||
const Mode = gGameModeRegistry.findById(id);
|
||||
|
||||
return new Mode(root);
|
||||
}
|
||||
|
||||
/** @param {GameRoot} root */
|
||||
constructor(root) {
|
||||
super();
|
||||
this.root = root;
|
||||
this.id = this.getId();
|
||||
}
|
||||
|
||||
getId() {
|
||||
// @ts-ignore
|
||||
return this.constructor.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
|
10
src/js/game/game_mode_registry.js
Normal file
10
src/js/game/game_mode_registry.js
Normal file
@ -0,0 +1,10 @@
|
||||
import { gGameModeRegistry } from "../core/global_registries";
|
||||
import { PuzzleEditGameMode } from "./modes/puzzle_edit";
|
||||
import { PuzzlePlayGameMode } from "./modes/puzzle_play";
|
||||
import { RegularGameMode } from "./modes/regular";
|
||||
|
||||
export function initGameModeRegistry() {
|
||||
gGameModeRegistry.register(PuzzleEditGameMode);
|
||||
gGameModeRegistry.register(PuzzlePlayGameMode);
|
||||
gGameModeRegistry.register(RegularGameMode);
|
||||
}
|
11
src/js/game/modes/puzzle_edit.js
Normal file
11
src/js/game/modes/puzzle_edit.js
Normal file
@ -0,0 +1,11 @@
|
||||
import { GameMode } from "../game_mode";
|
||||
|
||||
export class PuzzleEditGameMode extends GameMode {
|
||||
static getId() {
|
||||
return "PuzzleEdit";
|
||||
}
|
||||
|
||||
constructor(root) {
|
||||
super(root);
|
||||
}
|
||||
}
|
11
src/js/game/modes/puzzle_play.js
Normal file
11
src/js/game/modes/puzzle_play.js
Normal file
@ -0,0 +1,11 @@
|
||||
import { GameMode } from "../game_mode";
|
||||
|
||||
export class PuzzlePlayGameMode extends GameMode {
|
||||
static getId() {
|
||||
return "PuzzlePlay";
|
||||
}
|
||||
|
||||
constructor(root) {
|
||||
super(root);
|
||||
}
|
||||
}
|
@ -454,6 +454,10 @@ const fullVersionLevels = generateLevelDefinitions(false);
|
||||
const demoVersionLevels = generateLevelDefinitions(true);
|
||||
|
||||
export class RegularGameMode extends GameMode {
|
||||
static getId() {
|
||||
return "Regular";
|
||||
}
|
||||
|
||||
constructor(root) {
|
||||
super(root);
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import { initComponentRegistry } from "./game/component_registry";
|
||||
import { initDrawUtils } from "./core/draw_utils";
|
||||
import { initItemRegistry } from "./game/item_registry";
|
||||
import { initMetaBuildingRegistry } from "./game/meta_building_registry";
|
||||
import { initGameModeRegistry } from "./game/game_mode_registry";
|
||||
import { initGameSpeedRegistry } from "./game/game_speed_registry";
|
||||
|
||||
const logger = createLogger("main");
|
||||
@ -81,6 +82,7 @@ initDrawUtils();
|
||||
initComponentRegistry();
|
||||
initItemRegistry();
|
||||
initMetaBuildingRegistry();
|
||||
initGameModeRegistry();
|
||||
initGameSpeedRegistry();
|
||||
|
||||
let app = null;
|
||||
|
@ -33,6 +33,7 @@ export class SavegameSerializer {
|
||||
camera: root.camera.serialize(),
|
||||
time: root.time.serialize(),
|
||||
map: root.map.serialize(),
|
||||
gameMode: root.gameMode.serialize(),
|
||||
entityMgr: root.entityMgr.serialize(),
|
||||
hubGoals: root.hubGoals.serialize(),
|
||||
pinnedShapes: root.hud.parts.pinnedShapes.serialize(),
|
||||
|
@ -207,6 +207,11 @@ export class MainMenuState extends GameState {
|
||||
const qs = this.htmlElement.querySelector.bind(this.htmlElement);
|
||||
|
||||
if (G_IS_DEV && globalConfig.debug.fastGameEnter) {
|
||||
if (globalConfig.debug.testPuzzleMode) {
|
||||
this.onPuzzlePlayButtonClicked();
|
||||
return;
|
||||
}
|
||||
|
||||
const games = this.app.savegameMgr.getSavegamesMetaData();
|
||||
if (games.length > 0 && globalConfig.debug.resumeGameOnFastEnter) {
|
||||
this.resumeGame(games[0]);
|
||||
@ -308,21 +313,65 @@ export class MainMenuState extends GameState {
|
||||
buttonContainer.appendChild(importButtonElement);
|
||||
}
|
||||
|
||||
const modeButtonContainer = this.htmlElement.querySelector(".bottomContainer .buttons");
|
||||
removeAllChildren(modeButtonContainer);
|
||||
const bottomButtonContainer = this.htmlElement.querySelector(".bottomContainer .buttons");
|
||||
removeAllChildren(bottomButtonContainer);
|
||||
|
||||
const puzzleModeButton = makeButton(
|
||||
modeButtonContainer,
|
||||
bottomButtonContainer,
|
||||
["styledButton"],
|
||||
T.mainMenu.puzzleMode
|
||||
);
|
||||
|
||||
modeButtonContainer.appendChild(puzzleModeButton);
|
||||
bottomButtonContainer.appendChild(puzzleModeButton);
|
||||
this.trackClicks(puzzleModeButton, this.onPuzzleModeButtonClicked);
|
||||
}
|
||||
|
||||
renderPuzzleModeMenu() {
|
||||
const savegames = this.htmlElement.querySelector(".mainContainer .savegames");
|
||||
|
||||
if (savegames) {
|
||||
savegames.remove();
|
||||
}
|
||||
|
||||
const buttonContainer = this.htmlElement.querySelector(".mainContainer .buttons");
|
||||
removeAllChildren(buttonContainer);
|
||||
|
||||
const playButtonElement = makeButtonElement(
|
||||
["playButton", "styledButton"],
|
||||
T.mainMenu.play
|
||||
);
|
||||
|
||||
buttonContainer.appendChild(playButtonElement);
|
||||
this.trackClicks(playButtonElement, this.onPuzzlePlayButtonClicked);
|
||||
|
||||
const bottomButtonContainer = this.htmlElement.querySelector(".bottomContainer .buttons");
|
||||
removeAllChildren(bottomButtonContainer);
|
||||
|
||||
const backButton = makeButton(
|
||||
bottomButtonContainer,
|
||||
["styledButton"],
|
||||
T.mainMenu.back
|
||||
);
|
||||
|
||||
bottomButtonContainer.appendChild(backButton);
|
||||
this.trackClicks(backButton, this.onBackButtonClicked);
|
||||
}
|
||||
|
||||
onPuzzlePlayButtonClicked() {
|
||||
const savegame = this.app.savegameMgr.createNewSavegame();
|
||||
|
||||
this.moveToState("InGameState", {
|
||||
savegame,
|
||||
});
|
||||
}
|
||||
|
||||
onPuzzleModeButtonClicked() {
|
||||
this.moveToState("InGameState");
|
||||
this.renderPuzzleModeMenu();
|
||||
}
|
||||
|
||||
onBackButtonClicked() {
|
||||
this.renderMainMenu();
|
||||
this.renderSavegames();
|
||||
}
|
||||
|
||||
onSteamLinkClicked() {
|
||||
|
@ -117,6 +117,7 @@ mainMenu:
|
||||
savegameLevelUnknown: Unknown Level
|
||||
savegameUnnamed: Unnamed
|
||||
puzzleMode: Puzzle Mode
|
||||
back: Back
|
||||
|
||||
dialogs:
|
||||
buttons:
|
||||
|
Loading…
Reference in New Issue
Block a user