1
0
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:
Greg Considine 2021-03-14 17:22:14 -04:00
parent 5ccb2dbd0a
commit 6f0a32f054
11 changed files with 139 additions and 13 deletions

View File

@ -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");

View File

@ -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);

View File

@ -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();
}
/**

View 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);
}

View File

@ -0,0 +1,11 @@
import { GameMode } from "../game_mode";
export class PuzzleEditGameMode extends GameMode {
static getId() {
return "PuzzleEdit";
}
constructor(root) {
super(root);
}
}

View File

@ -0,0 +1,11 @@
import { GameMode } from "../game_mode";
export class PuzzlePlayGameMode extends GameMode {
static getId() {
return "PuzzlePlay";
}
constructor(root) {
super(root);
}
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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(),

View File

@ -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() {

View File

@ -117,6 +117,7 @@ mainMenu:
savegameLevelUnknown: Unknown Level
savegameUnnamed: Unnamed
puzzleMode: Puzzle Mode
back: Back
dialogs:
buttons: