You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tobspr_shapez.io/src/js/game/root.js

243 lines
8.1 KiB

/* eslint-disable no-unused-vars */
import { Signal } from "../core/signal";
import { RandomNumberGenerator } from "../core/rng";
import { createLogger } from "../core/logging";
// Type hints
/* typehints:start */
import { GameTime } from "./time/game_time";
import { EntityManager } from "./entity_manager";
import { GameSystemManager } from "./game_system_manager";
Achievements (#1087) * [WIP] Add boilerplate for achievement implementation * Add config.local.template.js and rm cached copy of config.local.js * [WIP] Implement painting, cutting, rotating achievements (to log only) * [WIP] Refactor achievements, jsdoc fixes, add npm script - Refactor achievements to make use of Signals - Move implemented achievement interfaces to appropriate platform folders (SteamAchievements in currently in use in browser wrapper for testing) - Fix invalid jsdocs - Add dev-standalone script to package.json scripts * Add steam/greenworks IPC calls and optional private-artifact dependency * Include private artifacts in standalone builds * Uncomment appid include * [WIP] Add steam overlay fix, add hash to artifact dependency * Update electron, greenworks. Add task to add local config if not present * Add more achievements, refactor achievement code * Add receiver flexibility and more achievements - Add check to see if necessary to create achievement and add receiver - Add remove receiver functionality when achievement is unlocked * Add achievements and accommodations for switching states - Fix startup code to avoid clobbering achievements on state switch - Add a few more achievements * Add achievements, ids. Update names, keys for consistency * Add play time achievements * [WIP] Add more achievements * Add more achievements. Add bulk achievement check signal * [WIP] Add achievements. Start savefile migration * Add achievements. Add savefile migration * Remove superfluous achievement stat * Update lock files, fix merge conflict
3 years ago
import { AchievementProxy } from "./achievement_proxy";
import { GameHUD } from "./hud/hud";
import { MapView } from "./map_view";
import { Camera } from "./camera";
import { InGameState } from "../states/ingame";
import { AutomaticSave } from "./automatic_save";
import { Application } from "../application";
import { SoundProxy } from "./sound_proxy";
import { Savegame } from "../savegame/savegame";
import { GameLogic } from "./logic";
import { ShapeDefinitionManager } from "./shape_definition_manager";
import { HubGoals } from "./hub_goals";
import { BufferMaintainer } from "../core/buffer_maintainer";
import { ProductionAnalytics } from "./production_analytics";
import { Entity } from "./entity";
import { ShapeDefinition } from "./shape_definition";
import { BaseItem } from "./base_item";
import { DynamicTickrate } from "./dynamic_tickrate";
import { KeyActionMapper } from "./key_action_mapper";
import { Vector } from "../core/vector";
import { GameMode } from "./game_mode";
/* typehints:end */
const logger = createLogger("game/root");
/** @type {Array<Layer>} */
export const layers = ["regular", "wires"];
/**
* The game root is basically the whole game state at a given point,
* combining all important classes. We don't have globals, but this
* class is passed to almost all game classes.
*/
export class GameRoot {
/**
* Constructs a new game root
* @param {Application} app
*/
constructor(app) {
this.app = app;
/** @type {Savegame} */
this.savegame = null;
/** @type {InGameState} */
this.gameState = null;
/** @type {KeyActionMapper} */
this.keyMapper = null;
// Store game dimensions
this.gameWidth = 500;
this.gameHeight = 500;
// Stores whether the current session is a fresh game (true), or was continued (false)
/** @type {boolean} */
this.gameIsFresh = true;
// Stores whether the logic is already initialized
/** @type {boolean} */
this.logicInitialized = false;
// Stores whether the game is already initialized, that is, all systems etc have been created
/** @type {boolean} */
this.gameInitialized = false;
/**
* Whether a bulk operation is running
*/
this.bulkOperationRunning = false;
Puzzle DLC (#1172) * Puzzle mode (#1135) * Add mode button to main menu * [WIP] Add mode menu. Add factory-based gameMode creation * Add savefile migration, serialize, deserialize * Add hidden HUD elements, zone, and zoom, boundary constraints * Clean up lint issues * Add building, HUD exclusion, building exclusion, and refactor - [WIP] Add ConstantProducer building that combines ConstantSignal and ItemProducer functionality. Currently using temp assets. - Add pre-placement check to the zone - Use Rectangles for zone and boundary - Simplify zone drawing - Account for exclusion in savegame data - [WIP] Add puzzle play and edit buttons in puzzle mode menu * [WIP] Add building, component, and systems for producing and accepting user-specified items and checking goal criteria * Add ingame puzzle mode UI elements - Add minimal menus in puzzle mode for back, next navigation - Add lower menu for changing zone dimenensions Co-authored-by: Greg Considine <gconsidine@users.noreply.github.com> * Performance optimizations (#1154) * 1.3.1 preparations * Minor fixes, update translations * Fix achievements not working * Lots of belt optimizations, ~15% performance boost * Puzzle mode, part 1 * Puzzle mode, part 2 * Fix missing import * Puzzle mode, part 3 * Fix typo * Puzzle mode, part 4 * Puzzle Mode fixes: Correct zone restrictions and more (#1155) * Hide Puzzle Editor Controls in regular game mode, fix typo * Disallow shrinking zone if there are buildings * Fix multi-tile buildings for shrinking * Puzzle mode, Refactor hud * Puzzle mode * Fixed typo in latest puzzle commit (#1156) * Allow completing puzzles * Puzzle mode, almost done * Bump version to 1.4.0 * Fixes * [puzzle] Prevent pipette cheats (miners, emitters) (#1158) * Puzzle mode, almost done * Allow clearing belts with 'B' * Multiple users for the puzzle dlc * Bump api key * Minor adjustments * Update * Minor fixes * Fix throughput * Fix belts * Minor puzzle adjustments * New difficulty * Minor puzzle improvements * Fix belt path * Update translations * Added a button to return to the menu after a puzzle is completed (#1170) * added another button to return to the menu * improved menu return * fixed continue button to not go back to menu * [Puzzle] Added ability to lock buildings in the puzzle editor! (#1164) * initial test * tried to get it to work * added icon * added test exclusion * reverted css * completed flow for building locking * added lock option * finalized look and changed locked building to same sprite * removed unused art * added clearing every goal acceptor on lock to prevent creating impossible puzzles * heavily improved validation and prevented autocompletion * validation only checks every 100 ticks to improve performance * validation only checks every 100 ticks to improve performance * removed clearing goal acceptors as it isn't needed because of validation * Add soundtrack, puzzle dlc fixes Co-authored-by: Greg Considine <gconsidine@users.noreply.github.com> Co-authored-by: dengr1065 <dengr1065@gmail.com> Co-authored-by: Sense101 <67970865+Sense101@users.noreply.github.com>
3 years ago
/**
* Whether a immutable operation is running
*/
this.immutableOperationRunning = false;
//////// Other properties ///////
/** @type {Camera} */
this.camera = null;
/** @type {HTMLCanvasElement} */
this.canvas = null;
/** @type {CanvasRenderingContext2D} */
this.context = null;
/** @type {MapView} */
this.map = null;
/** @type {GameLogic} */
this.logic = null;
/** @type {EntityManager} */
this.entityMgr = null;
/** @type {GameHUD} */
this.hud = null;
/** @type {GameSystemManager} */
this.systemMgr = null;
/** @type {GameTime} */
this.time = null;
/** @type {HubGoals} */
this.hubGoals = null;
/** @type {BufferMaintainer} */
this.buffers = null;
/** @type {AutomaticSave} */
this.automaticSave = null;
/** @type {SoundProxy} */
this.soundProxy = null;
Achievements (#1087) * [WIP] Add boilerplate for achievement implementation * Add config.local.template.js and rm cached copy of config.local.js * [WIP] Implement painting, cutting, rotating achievements (to log only) * [WIP] Refactor achievements, jsdoc fixes, add npm script - Refactor achievements to make use of Signals - Move implemented achievement interfaces to appropriate platform folders (SteamAchievements in currently in use in browser wrapper for testing) - Fix invalid jsdocs - Add dev-standalone script to package.json scripts * Add steam/greenworks IPC calls and optional private-artifact dependency * Include private artifacts in standalone builds * Uncomment appid include * [WIP] Add steam overlay fix, add hash to artifact dependency * Update electron, greenworks. Add task to add local config if not present * Add more achievements, refactor achievement code * Add receiver flexibility and more achievements - Add check to see if necessary to create achievement and add receiver - Add remove receiver functionality when achievement is unlocked * Add achievements and accommodations for switching states - Fix startup code to avoid clobbering achievements on state switch - Add a few more achievements * Add achievements, ids. Update names, keys for consistency * Add play time achievements * [WIP] Add more achievements * Add more achievements. Add bulk achievement check signal * [WIP] Add achievements. Start savefile migration * Add achievements. Add savefile migration * Remove superfluous achievement stat * Update lock files, fix merge conflict
3 years ago
/** @type {AchievementProxy} */
this.achievementProxy = null;
/** @type {ShapeDefinitionManager} */
this.shapeDefinitionMgr = null;
/** @type {ProductionAnalytics} */
this.productionAnalytics = null;
/** @type {DynamicTickrate} */
this.dynamicTickrate = null;
/** @type {Layer} */
this.currentLayer = "regular";
/** @type {GameMode} */
this.gameMode = null;
this.signals = {
// Entities
entityManuallyPlaced: /** @type {TypedSignal<[Entity]>} */ (new Signal()),
entityAdded: /** @type {TypedSignal<[Entity]>} */ (new Signal()),
entityChanged: /** @type {TypedSignal<[Entity]>} */ (new Signal()),
entityGotNewComponent: /** @type {TypedSignal<[Entity]>} */ (new Signal()),
entityComponentRemoved: /** @type {TypedSignal<[Entity]>} */ (new Signal()),
entityQueuedForDestroy: /** @type {TypedSignal<[Entity]>} */ (new Signal()),
entityDestroyed: /** @type {TypedSignal<[Entity]>} */ (new Signal()),
// Global
resized: /** @type {TypedSignal<[number, number]>} */ (new Signal()),
readyToRender: /** @type {TypedSignal<[]>} */ (new Signal()),
aboutToDestruct: /** @type {TypedSignal<[]>} */ new Signal(),
// Game Hooks
gameSaved: /** @type {TypedSignal<[]>} */ (new Signal()), // Game got saved
gameRestored: /** @type {TypedSignal<[]>} */ (new Signal()), // Game got restored
gameFrameStarted: /** @type {TypedSignal<[]>} */ (new Signal()), // New frame
storyGoalCompleted: /** @type {TypedSignal<[number, string]>} */ (new Signal()),
upgradePurchased: /** @type {TypedSignal<[string]>} */ (new Signal()),
// Called right after game is initialized
postLoadHook: /** @type {TypedSignal<[]>} */ (new Signal()),
shapeDelivered: /** @type {TypedSignal<[ShapeDefinition]>} */ (new Signal()),
itemProduced: /** @type {TypedSignal<[BaseItem]>} */ (new Signal()),
bulkOperationFinished: /** @type {TypedSignal<[]>} */ (new Signal()),
Puzzle DLC (#1172) * Puzzle mode (#1135) * Add mode button to main menu * [WIP] Add mode menu. Add factory-based gameMode creation * Add savefile migration, serialize, deserialize * Add hidden HUD elements, zone, and zoom, boundary constraints * Clean up lint issues * Add building, HUD exclusion, building exclusion, and refactor - [WIP] Add ConstantProducer building that combines ConstantSignal and ItemProducer functionality. Currently using temp assets. - Add pre-placement check to the zone - Use Rectangles for zone and boundary - Simplify zone drawing - Account for exclusion in savegame data - [WIP] Add puzzle play and edit buttons in puzzle mode menu * [WIP] Add building, component, and systems for producing and accepting user-specified items and checking goal criteria * Add ingame puzzle mode UI elements - Add minimal menus in puzzle mode for back, next navigation - Add lower menu for changing zone dimenensions Co-authored-by: Greg Considine <gconsidine@users.noreply.github.com> * Performance optimizations (#1154) * 1.3.1 preparations * Minor fixes, update translations * Fix achievements not working * Lots of belt optimizations, ~15% performance boost * Puzzle mode, part 1 * Puzzle mode, part 2 * Fix missing import * Puzzle mode, part 3 * Fix typo * Puzzle mode, part 4 * Puzzle Mode fixes: Correct zone restrictions and more (#1155) * Hide Puzzle Editor Controls in regular game mode, fix typo * Disallow shrinking zone if there are buildings * Fix multi-tile buildings for shrinking * Puzzle mode, Refactor hud * Puzzle mode * Fixed typo in latest puzzle commit (#1156) * Allow completing puzzles * Puzzle mode, almost done * Bump version to 1.4.0 * Fixes * [puzzle] Prevent pipette cheats (miners, emitters) (#1158) * Puzzle mode, almost done * Allow clearing belts with 'B' * Multiple users for the puzzle dlc * Bump api key * Minor adjustments * Update * Minor fixes * Fix throughput * Fix belts * Minor puzzle adjustments * New difficulty * Minor puzzle improvements * Fix belt path * Update translations * Added a button to return to the menu after a puzzle is completed (#1170) * added another button to return to the menu * improved menu return * fixed continue button to not go back to menu * [Puzzle] Added ability to lock buildings in the puzzle editor! (#1164) * initial test * tried to get it to work * added icon * added test exclusion * reverted css * completed flow for building locking * added lock option * finalized look and changed locked building to same sprite * removed unused art * added clearing every goal acceptor on lock to prevent creating impossible puzzles * heavily improved validation and prevented autocompletion * validation only checks every 100 ticks to improve performance * validation only checks every 100 ticks to improve performance * removed clearing goal acceptors as it isn't needed because of validation * Add soundtrack, puzzle dlc fixes Co-authored-by: Greg Considine <gconsidine@users.noreply.github.com> Co-authored-by: dengr1065 <dengr1065@gmail.com> Co-authored-by: Sense101 <67970865+Sense101@users.noreply.github.com>
3 years ago
immutableOperationFinished: /** @type {TypedSignal<[]>} */ (new Signal()),
editModeChanged: /** @type {TypedSignal<[Layer]>} */ (new Signal()),
// Called to check if an entity can be placed, second parameter is an additional offset.
// Use to introduce additional placement checks
prePlacementCheck: /** @type {TypedSignal<[Entity, Vector]>} */ (new Signal()),
// Called before actually placing an entity, use to perform additional logic
// for freeing space before actually placing.
freeEntityAreaBeforeBuild: /** @type {TypedSignal<[Entity]>} */ (new Signal()),
Achievements (#1087) * [WIP] Add boilerplate for achievement implementation * Add config.local.template.js and rm cached copy of config.local.js * [WIP] Implement painting, cutting, rotating achievements (to log only) * [WIP] Refactor achievements, jsdoc fixes, add npm script - Refactor achievements to make use of Signals - Move implemented achievement interfaces to appropriate platform folders (SteamAchievements in currently in use in browser wrapper for testing) - Fix invalid jsdocs - Add dev-standalone script to package.json scripts * Add steam/greenworks IPC calls and optional private-artifact dependency * Include private artifacts in standalone builds * Uncomment appid include * [WIP] Add steam overlay fix, add hash to artifact dependency * Update electron, greenworks. Add task to add local config if not present * Add more achievements, refactor achievement code * Add receiver flexibility and more achievements - Add check to see if necessary to create achievement and add receiver - Add remove receiver functionality when achievement is unlocked * Add achievements and accommodations for switching states - Fix startup code to avoid clobbering achievements on state switch - Add a few more achievements * Add achievements, ids. Update names, keys for consistency * Add play time achievements * [WIP] Add more achievements * Add more achievements. Add bulk achievement check signal * [WIP] Add achievements. Start savefile migration * Add achievements. Add savefile migration * Remove superfluous achievement stat * Update lock files, fix merge conflict
3 years ago
// Called with an achievement key and necessary args to validate it can be unlocked.
achievementCheck: /** @type {TypedSignal<[string, any]>} */ (new Signal()),
bulkAchievementCheck: /** @type {TypedSignal<(string|any)[]>} */ (new Signal()),
Puzzle DLC (#1172) * Puzzle mode (#1135) * Add mode button to main menu * [WIP] Add mode menu. Add factory-based gameMode creation * Add savefile migration, serialize, deserialize * Add hidden HUD elements, zone, and zoom, boundary constraints * Clean up lint issues * Add building, HUD exclusion, building exclusion, and refactor - [WIP] Add ConstantProducer building that combines ConstantSignal and ItemProducer functionality. Currently using temp assets. - Add pre-placement check to the zone - Use Rectangles for zone and boundary - Simplify zone drawing - Account for exclusion in savegame data - [WIP] Add puzzle play and edit buttons in puzzle mode menu * [WIP] Add building, component, and systems for producing and accepting user-specified items and checking goal criteria * Add ingame puzzle mode UI elements - Add minimal menus in puzzle mode for back, next navigation - Add lower menu for changing zone dimenensions Co-authored-by: Greg Considine <gconsidine@users.noreply.github.com> * Performance optimizations (#1154) * 1.3.1 preparations * Minor fixes, update translations * Fix achievements not working * Lots of belt optimizations, ~15% performance boost * Puzzle mode, part 1 * Puzzle mode, part 2 * Fix missing import * Puzzle mode, part 3 * Fix typo * Puzzle mode, part 4 * Puzzle Mode fixes: Correct zone restrictions and more (#1155) * Hide Puzzle Editor Controls in regular game mode, fix typo * Disallow shrinking zone if there are buildings * Fix multi-tile buildings for shrinking * Puzzle mode, Refactor hud * Puzzle mode * Fixed typo in latest puzzle commit (#1156) * Allow completing puzzles * Puzzle mode, almost done * Bump version to 1.4.0 * Fixes * [puzzle] Prevent pipette cheats (miners, emitters) (#1158) * Puzzle mode, almost done * Allow clearing belts with 'B' * Multiple users for the puzzle dlc * Bump api key * Minor adjustments * Update * Minor fixes * Fix throughput * Fix belts * Minor puzzle adjustments * New difficulty * Minor puzzle improvements * Fix belt path * Update translations * Added a button to return to the menu after a puzzle is completed (#1170) * added another button to return to the menu * improved menu return * fixed continue button to not go back to menu * [Puzzle] Added ability to lock buildings in the puzzle editor! (#1164) * initial test * tried to get it to work * added icon * added test exclusion * reverted css * completed flow for building locking * added lock option * finalized look and changed locked building to same sprite * removed unused art * added clearing every goal acceptor on lock to prevent creating impossible puzzles * heavily improved validation and prevented autocompletion * validation only checks every 100 ticks to improve performance * validation only checks every 100 ticks to improve performance * removed clearing goal acceptors as it isn't needed because of validation * Add soundtrack, puzzle dlc fixes Co-authored-by: Greg Considine <gconsidine@users.noreply.github.com> Co-authored-by: dengr1065 <dengr1065@gmail.com> Co-authored-by: Sense101 <67970865+Sense101@users.noreply.github.com>
3 years ago
// Puzzle mode
puzzleComplete: /** @type {TypedSignal<[]>} */ (new Signal()),
};
// RNG's
/** @type {Object.<string, Object.<string, RandomNumberGenerator>>} */
this.rngs = {};
// Work queue
this.queue = {
requireRedraw: false,
};
}
/**
* Destructs the game root
*/
destruct() {
logger.log("destructing root");
this.signals.aboutToDestruct.dispatch();
this.reset();
}
/**
* Resets the whole root and removes all properties
*/
reset() {
if (this.signals) {
// Destruct all signals
for (let i = 0; i < this.signals.length; ++i) {
this.signals[i].removeAll();
}
}
if (this.hud) {
this.hud.cleanup();
}
if (this.camera) {
this.camera.cleanup();
}
// Finally free all properties
for (let prop in this) {
if (this.hasOwnProperty(prop)) {
delete this[prop];
}
}
}
}