1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2025-12-14 02:31:51 +00:00

Lazy Load mods to make sure all dependencies are loaded

This commit is contained in:
tobspr 2022-01-14 07:37:26 +01:00
parent 16ecbf9c6d
commit bc5eff84f6
7 changed files with 46 additions and 26 deletions

View File

@ -35,6 +35,8 @@ import { PuzzleMenuState } from "./states/puzzle_menu";
import { ClientAPI } from "./platform/api"; import { ClientAPI } from "./platform/api";
import { LoginState } from "./states/login"; import { LoginState } from "./states/login";
import { WegameSplashState } from "./states/wegame_splash"; import { WegameSplashState } from "./states/wegame_splash";
import { MODS } from "./mods/modloader";
import { MOD_SIGNALS } from "./mods/mod_signals";
/** /**
* @typedef {import("./platform/achievement_provider").AchievementProviderInterface} AchievementProviderInterface * @typedef {import("./platform/achievement_provider").AchievementProviderInterface} AchievementProviderInterface
@ -128,6 +130,8 @@ export class Application {
// Store the mouse position, or null if not available // Store the mouse position, or null if not available
/** @type {Vector|null} */ /** @type {Vector|null} */
this.mousePosition = null; this.mousePosition = null;
MODS.initMods();
} }
/** /**
@ -148,6 +152,8 @@ export class Application {
this.analytics = new GoogleAnalyticsImpl(this); this.analytics = new GoogleAnalyticsImpl(this);
this.gameAnalytics = new ShapezGameAnalytics(this); this.gameAnalytics = new ShapezGameAnalytics(this);
this.achievementProvider = new NoAchievementProvider(this); this.achievementProvider = new NoAchievementProvider(this);
MOD_SIGNALS.platformInstancesInitialized.dispatch();
} }
/** /**

View File

@ -69,10 +69,16 @@ const tierGrowth = 2.5;
const chinaShapes = G_WEGAME_VERSION || G_CHINA_VERSION; const chinaShapes = G_WEGAME_VERSION || G_CHINA_VERSION;
const upgradesCache = {};
/** /**
* Generates all upgrades * Generates all upgrades
* @returns {Object<string, UpgradeTiers>} */ * @returns {Object<string, UpgradeTiers>} */
function generateUpgrades(limitedVersion = false) { function generateUpgrades(limitedVersion = false) {
if (upgradesCache[limitedVersion]) {
return upgradesCache[limitedVersion];
}
const fixedImprovements = [0.5, 0.5, 1, 1, 2, 1, 1]; const fixedImprovements = [0.5, 0.5, 1, 1, 2, 1, 1];
const numEndgameUpgrades = limitedVersion ? 0 : 1000 - fixedImprovements.length - 1; const numEndgameUpgrades = limitedVersion ? 0 : 1000 - fixedImprovements.length - 1;
@ -265,6 +271,8 @@ function generateUpgrades(limitedVersion = false) {
} }
} }
MOD_SIGNALS.modifyUpgrades.dispatch(upgrades);
// VALIDATE // VALIDATE
if (G_IS_DEV) { if (G_IS_DEV) {
for (const upgradeId in upgrades) { for (const upgradeId in upgrades) {
@ -280,14 +288,20 @@ function generateUpgrades(limitedVersion = false) {
} }
} }
upgradesCache[limitedVersion] = upgrades;
return upgrades; return upgrades;
} }
const levelDefinitionsCache = {};
/** /**
* Generates the level definitions * Generates the level definitions
* @param {boolean} limitedVersion * @param {boolean} limitedVersion
*/ */
export function generateLevelDefinitions(limitedVersion = false) { export function generateLevelDefinitions(limitedVersion = false) {
if (levelDefinitionsCache[limitedVersion]) {
return levelDefinitionsCache[limitedVersion];
}
const levelDefinitions = [ const levelDefinitions = [
// 1 // 1
// Circle // Circle
@ -524,15 +538,11 @@ export function generateLevelDefinitions(limitedVersion = false) {
}); });
} }
levelDefinitionsCache[limitedVersion] = levelDefinitions;
return levelDefinitions; return levelDefinitions;
} }
const fullVersionUpgrades = generateUpgrades(false);
const demoVersionUpgrades = generateUpgrades(true);
const fullVersionLevels = generateLevelDefinitions(false);
const demoVersionLevels = generateLevelDefinitions(true);
export class RegularGameMode extends GameMode { export class RegularGameMode extends GameMode {
static getId() { static getId() {
return enumGameModeIds.regular; return enumGameModeIds.regular;
@ -603,9 +613,7 @@ export class RegularGameMode extends GameMode {
* @returns {Object<string, UpgradeTiers>} * @returns {Object<string, UpgradeTiers>}
*/ */
getUpgrades() { getUpgrades() {
return this.root.app.restrictionMgr.getHasExtendedUpgrades() return generateUpgrades(!this.root.app.restrictionMgr.getHasExtendedUpgrades());
? fullVersionUpgrades
: demoVersionUpgrades;
} }
/** /**
@ -613,9 +621,7 @@ export class RegularGameMode extends GameMode {
* @returns {Array<LevelDefinition>} * @returns {Array<LevelDefinition>}
*/ */
getLevelDefinitions() { getLevelDefinitions() {
return this.root.app.restrictionMgr.getHasExtendedLevelsAndFreeplay() return generateLevelDefinitions(!this.root.app.restrictionMgr.getHasExtendedLevelsAndFreeplay());
? fullVersionLevels
: demoVersionLevels;
} }
/** /**

View File

@ -20,8 +20,9 @@ export default function ({ Mod, MetaBuilding }) {
} }
return class ModImpl extends Mod { return class ModImpl extends Mod {
constructor(modLoader) { constructor(app, modLoader) {
super( super(
app,
{ {
authorContact: "tobias@tobspr.io", authorContact: "tobias@tobspr.io",
authorName: "tobspr", authorName: "tobspr",
@ -37,7 +38,7 @@ export default function ({ Mod, MetaBuilding }) {
// Add some custom css // Add some custom css
this.modInterface.registerCss(` this.modInterface.registerCss(`
* { * {
color: red !important; font-family: "Comic Sans", "Comic Sans MS", Tahoma !important;
} }
`); `);

View File

@ -1,4 +1,5 @@
/* typehints:start */ /* typehints:start */
import { Application } from "../application";
import { ModLoader } from "./modloader"; import { ModLoader } from "./modloader";
/* typehints:end */ /* typehints:end */
@ -7,6 +8,7 @@ import { MOD_SIGNALS } from "./mod_signals";
export class Mod { export class Mod {
/** /**
* *
* @param {Application} app
* @param {object} metadata * @param {object} metadata
* @param {string} metadata.name * @param {string} metadata.name
* @param {string} metadata.version * @param {string} metadata.version
@ -16,7 +18,8 @@ export class Mod {
* *
* @param {ModLoader} modLoader * @param {ModLoader} modLoader
*/ */
constructor(metadata, modLoader) { constructor(app, metadata, modLoader) {
this.app = app;
this.metadata = metadata; this.metadata = metadata;
this.modLoader = modLoader; this.modLoader = modLoader;

View File

@ -15,7 +15,7 @@ import {
import { Loader } from "../core/loader"; import { Loader } from "../core/loader";
import { LANGUAGES } from "../languages"; import { LANGUAGES } from "../languages";
import { matchDataRecursive, T } from "../translations"; import { matchDataRecursive, T } from "../translations";
import { registerBuildingVariant } from "../game/building_codes"; import { gBuildingVariants, registerBuildingVariant } from "../game/building_codes";
import { gMetaBuildingRegistry } from "../core/global_registries"; import { gMetaBuildingRegistry } from "../core/global_registries";
import { MODS_ADDITIONAL_SHAPE_MAP_WEIGHTS } from "../game/map_chunk"; import { MODS_ADDITIONAL_SHAPE_MAP_WEIGHTS } from "../game/map_chunk";
@ -126,11 +126,15 @@ export class ModInterface {
throw new Error("Tried to register building twice: " + id); throw new Error("Tried to register building twice: " + id);
} }
gMetaBuildingRegistry.register(metaClass); gMetaBuildingRegistry.register(metaClass);
const metaInstance = gMetaBuildingRegistry.findByClass(metaClass);
T.buildings[id] = {}; T.buildings[id] = {};
variantsAndRotations.forEach(payload => { variantsAndRotations.forEach(payload => {
const actualVariant = payload.variant || defaultBuildingVariant; const actualVariant = payload.variant || defaultBuildingVariant;
registerBuildingVariant(id, metaClass, actualVariant, payload.rotationVariant || 0); registerBuildingVariant(id, metaClass, actualVariant, payload.rotationVariant || 0);
gBuildingVariants[id].metaInstance = metaInstance;
T.buildings[id][actualVariant] = { T.buildings[id][actualVariant] = {
name: payload.name, name: payload.name,
description: payload.description, description: payload.description,

View File

@ -7,9 +7,12 @@ import { BaseHUDPart } from "../game/hud/base_hud_part";
export const MOD_SIGNALS = { export const MOD_SIGNALS = {
postInit: new Signal(), postInit: new Signal(),
platformInstancesInitialized: new Signal(),
injectSprites: new Signal(), injectSprites: new Signal(),
preprocessTheme: /** @type {TypedSignal<[Object]>} */ (new Signal()), preprocessTheme: /** @type {TypedSignal<[Object]>} */ (new Signal()),
modifyLevelDefinitions: /** @type {TypedSignal<[Array[Object]]>} */ (new Signal()), modifyLevelDefinitions: /** @type {TypedSignal<[Array[Object]]>} */ (new Signal()),
modifyUpgrades: /** @type {TypedSignal<[Object]>} */ (new Signal()),
hudElementInitialized: /** @type {TypedSignal<[BaseHUDPart]>} */ (new Signal()), hudElementInitialized: /** @type {TypedSignal<[BaseHUDPart]>} */ (new Signal()),
hudElementFinalized: /** @type {TypedSignal<[BaseHUDPart]>} */ (new Signal()), hudElementFinalized: /** @type {TypedSignal<[BaseHUDPart]>} */ (new Signal()),

View File

@ -15,20 +15,14 @@ export class ModLoader {
this.modInterface = new ModInterface(this); this.modInterface = new ModInterface(this);
/** @type {(new (ModLoader) => Mod)[]} */ /** @type {((Object) => (new (Application, ModLoader) => Mod))[]} */
this.modLoadQueue = []; this.modLoadQueue = [];
this.initialized = false; this.initialized = false;
this.signals = MOD_SIGNALS; this.signals = MOD_SIGNALS;
this.registerMod( this.registerMod(/** @type {any} */ (require("./demo_mod").default));
/** @type {any} */ (require("./demo_mod").default({
Mod,
MetaBuilding,
}))
);
this.initMods();
} }
linkApp(app) { linkApp(app) {
@ -39,7 +33,10 @@ export class ModLoader {
LOG.log("hook:init"); LOG.log("hook:init");
this.initialized = true; this.initialized = true;
this.modLoadQueue.forEach(modClass => { this.modLoadQueue.forEach(modClass => {
const mod = new modClass(this); const mod = new (modClass({
Mod,
MetaBuilding,
}))(this.app, this);
mod.init(); mod.init();
this.mods.push(mod); this.mods.push(mod);
}); });
@ -49,7 +46,7 @@ export class ModLoader {
/** /**
* *
* @param {new (ModLoader) => Mod} mod * @param {(Object) => (new (Application, ModLoader) => Mod)} mod
*/ */
registerMod(mod) { registerMod(mod) {
if (this.initialized) { if (this.initialized) {