mirror of
https://github.com/tobspr/shapez.io.git
synced 2024-10-27 20:34:29 +00:00
Unlock all levels when having a legacy savegame
This commit is contained in:
parent
fa27d1681f
commit
7dccc1a844
@ -1,5 +1,3 @@
|
|||||||
import { queryParamOptions } from "./query_parameters";
|
|
||||||
|
|
||||||
export const IS_DEBUG =
|
export const IS_DEBUG =
|
||||||
G_IS_DEV &&
|
G_IS_DEV &&
|
||||||
typeof window !== "undefined" &&
|
typeof window !== "undefined" &&
|
||||||
@ -9,6 +7,8 @@ export const IS_DEBUG =
|
|||||||
|
|
||||||
export const SUPPORT_TOUCH = false;
|
export const SUPPORT_TOUCH = false;
|
||||||
|
|
||||||
|
export const IS_MAC = navigator.platform.toLowerCase().indexOf("mac") >= 0;
|
||||||
|
|
||||||
const smoothCanvas = true;
|
const smoothCanvas = true;
|
||||||
|
|
||||||
export const THIRDPARTY_URLS = {
|
export const THIRDPARTY_URLS = {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { Application } from "../application";
|
import { Application } from "../application";
|
||||||
|
import { IS_MAC } from "./config";
|
||||||
import { ExplainedResult } from "./explained_result";
|
import { ExplainedResult } from "./explained_result";
|
||||||
import { queryParamOptions } from "./query_parameters";
|
import { queryParamOptions } from "./query_parameters";
|
||||||
import { ReadWriteProxy } from "./read_write_proxy";
|
import { ReadWriteProxy } from "./read_write_proxy";
|
||||||
@ -9,6 +10,8 @@ export class RestrictionManager extends ReadWriteProxy {
|
|||||||
*/
|
*/
|
||||||
constructor(app) {
|
constructor(app) {
|
||||||
super(app, "restriction-flags.bin");
|
super(app, "restriction-flags.bin");
|
||||||
|
|
||||||
|
this.currentData = this.getDefaultData();
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- RW Proxy Impl
|
// -- RW Proxy Impl
|
||||||
@ -24,6 +27,7 @@ export class RestrictionManager extends ReadWriteProxy {
|
|||||||
*/
|
*/
|
||||||
getDefaultData() {
|
getDefaultData() {
|
||||||
return {
|
return {
|
||||||
|
version: this.getCurrentVersion(),
|
||||||
savegameV1119Imported: false,
|
savegameV1119Imported: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -42,17 +46,53 @@ export class RestrictionManager extends ReadWriteProxy {
|
|||||||
return ExplainedResult.good();
|
return ExplainedResult.good();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initialize() {
|
||||||
|
return this.readAsync().then(() => {
|
||||||
|
if (this.currentData.savegameV1119Imported) {
|
||||||
|
console.warn("Levelunlock is granted to current user due to past savegame");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// -- End RW Proxy Impl
|
// -- End RW Proxy Impl
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if there are any savegames from the 1.1.19 version
|
||||||
|
*/
|
||||||
|
onHasLegacySavegamesChanged(has119Savegames = false) {
|
||||||
|
if (has119Savegames && !this.currentData.savegameV1119Imported) {
|
||||||
|
this.currentData.savegameV1119Imported = true;
|
||||||
|
console.warn("Current user now has access to all levels due to 1119 savegame");
|
||||||
|
return this.writeAsync();
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns if the app is currently running as the limited version
|
* Returns if the app is currently running as the limited version
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
isLimitedVersion() {
|
isLimitedVersion() {
|
||||||
return queryParamOptions.fullVersion
|
if (IS_MAC) {
|
||||||
? false
|
// On mac, the full version is always active
|
||||||
: (!G_IS_DEV && !G_IS_STANDALONE) ||
|
return false;
|
||||||
(typeof window !== "undefined" && window.location.search.indexOf("demo") >= 0);
|
}
|
||||||
|
|
||||||
|
if (G_IS_STANDALONE) {
|
||||||
|
// Standalone is never limited
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryParamOptions.fullVersion) {
|
||||||
|
// Full version is activated via flag
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (G_IS_DEV) {
|
||||||
|
return typeof window !== "undefined" && window.location.search.indexOf("demo") >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,4 +134,20 @@ export class RestrictionManager extends ReadWriteProxy {
|
|||||||
getHasExtendedSettings() {
|
getHasExtendedSettings() {
|
||||||
return !this.isLimitedVersion();
|
return !this.isLimitedVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns if all upgrades are available
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
getHasExtendedUpgrades() {
|
||||||
|
return !this.isLimitedVersion() || this.currentData.savegameV1119Imported;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns if all levels & freeplay is available
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
getHasExtendedLevelsAndFreeplay() {
|
||||||
|
return !this.isLimitedVersion() || this.currentData.savegameV1119Imported;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { IS_DEMO } from "../../core/config";
|
|
||||||
import { findNiceIntegerValue } from "../../core/utils";
|
import { findNiceIntegerValue } from "../../core/utils";
|
||||||
import { GameMode } from "../game_mode";
|
import { GameMode } from "../game_mode";
|
||||||
import { ShapeDefinition } from "../shape_definition";
|
import { ShapeDefinition } from "../shape_definition";
|
||||||
@ -9,423 +8,442 @@ const finalGameShape = "RuCw--Cw:----Ru--";
|
|||||||
const preparementShape = "CpRpCp--:SwSwSwSw";
|
const preparementShape = "CpRpCp--:SwSwSwSw";
|
||||||
const blueprintShape = "CbCbCbRb:CwCwCwCw";
|
const blueprintShape = "CbCbCbRb:CwCwCwCw";
|
||||||
|
|
||||||
const fixedImprovements = [0.5, 0.5, 1, 1, 2, 1, 1];
|
|
||||||
|
|
||||||
// @FIXME @TODO
|
|
||||||
const numEndgameUpgrades = !IS_DEMO ? 20 - fixedImprovements.length - 1 : 0;
|
|
||||||
|
|
||||||
function generateEndgameUpgrades() {
|
|
||||||
return new Array(numEndgameUpgrades).fill(null).map((_, i) => ({
|
|
||||||
required: [
|
|
||||||
{ shape: preparementShape, amount: 30000 + i * 10000 },
|
|
||||||
{ shape: finalGameShape, amount: 20000 + i * 5000 },
|
|
||||||
{ shape: rocketShape, amount: 20000 + i * 5000 },
|
|
||||||
],
|
|
||||||
excludePrevious: true,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < numEndgameUpgrades; ++i) {
|
|
||||||
fixedImprovements.push(0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @type {Object<string, import("../game_mode").UpgradeTiers>} */
|
|
||||||
const cachedUpgrades = {
|
|
||||||
belt: [
|
|
||||||
{
|
|
||||||
required: [{ shape: "CuCuCuCu", amount: 60 }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [{ shape: "--CuCu--", amount: 500 }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [{ shape: "CpCpCpCp", amount: 1000 }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [{ shape: "SrSrSrSr:CyCyCyCy", amount: 6000 }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [{ shape: "SrSrSrSr:CyCyCyCy:SwSwSwSw", amount: 25000 }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [{ shape: preparementShape, amount: 25000 }],
|
|
||||||
excludePrevious: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [
|
|
||||||
{ shape: preparementShape, amount: 25000 },
|
|
||||||
{ shape: finalGameShape, amount: 50000 },
|
|
||||||
],
|
|
||||||
excludePrevious: true,
|
|
||||||
},
|
|
||||||
...generateEndgameUpgrades(),
|
|
||||||
],
|
|
||||||
|
|
||||||
miner: [
|
|
||||||
{
|
|
||||||
required: [{ shape: "RuRuRuRu", amount: 300 }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [{ shape: "Cu------", amount: 800 }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [{ shape: "ScScScSc", amount: 3500 }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [{ shape: "CwCwCwCw:WbWbWbWb", amount: 23000 }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [{ shape: "CbRbRbCb:CwCwCwCw:WbWbWbWb", amount: 50000 }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [{ shape: preparementShape, amount: 25000 }],
|
|
||||||
excludePrevious: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [
|
|
||||||
{ shape: preparementShape, amount: 25000 },
|
|
||||||
{ shape: finalGameShape, amount: 50000 },
|
|
||||||
],
|
|
||||||
excludePrevious: true,
|
|
||||||
},
|
|
||||||
...generateEndgameUpgrades(),
|
|
||||||
],
|
|
||||||
|
|
||||||
processors: [
|
|
||||||
{
|
|
||||||
required: [{ shape: "SuSuSuSu", amount: 500 }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [{ shape: "RuRu----", amount: 600 }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [{ shape: "CgScScCg", amount: 3500 }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [{ shape: "CwCrCwCr:SgSgSgSg", amount: 25000 }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [{ shape: "WrRgWrRg:CwCrCwCr:SgSgSgSg", amount: 50000 }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [{ shape: preparementShape, amount: 25000 }],
|
|
||||||
excludePrevious: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [
|
|
||||||
{ shape: preparementShape, amount: 25000 },
|
|
||||||
{ shape: finalGameShape, amount: 50000 },
|
|
||||||
],
|
|
||||||
excludePrevious: true,
|
|
||||||
},
|
|
||||||
...generateEndgameUpgrades(),
|
|
||||||
],
|
|
||||||
|
|
||||||
painting: [
|
|
||||||
{
|
|
||||||
required: [{ shape: "RbRb----", amount: 600 }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [{ shape: "WrWrWrWr", amount: 3800 }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [{ shape: "RpRpRpRp:CwCwCwCw", amount: 6500 }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [{ shape: "WpWpWpWp:CwCwCwCw:WpWpWpWp", amount: 25000 }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [{ shape: "WpWpWpWp:CwCwCwCw:WpWpWpWp:CwCwCwCw", amount: 50000 }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [{ shape: preparementShape, amount: 25000 }],
|
|
||||||
excludePrevious: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
required: [
|
|
||||||
{ shape: preparementShape, amount: 25000 },
|
|
||||||
{ shape: finalGameShape, amount: 50000 },
|
|
||||||
],
|
|
||||||
excludePrevious: true,
|
|
||||||
},
|
|
||||||
...generateEndgameUpgrades(),
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
// Tiers need % of the previous tier as requirement too
|
// Tiers need % of the previous tier as requirement too
|
||||||
const tierGrowth = 2.5;
|
const tierGrowth = 2.5;
|
||||||
|
|
||||||
// Automatically generate tier levels
|
/**
|
||||||
for (const upgradeId in cachedUpgrades) {
|
* Generates all upgrades
|
||||||
const upgradeTiers = cachedUpgrades[upgradeId];
|
* @returns {Object<string, import("../game_mode").UpgradeTiers>} */
|
||||||
|
function generateUpgrades(limitedVersion = false) {
|
||||||
|
const fixedImprovements = [0.5, 0.5, 1, 1, 2, 1, 1];
|
||||||
|
const numEndgameUpgrades = limitedVersion ? 0 : 1000 - fixedImprovements.length - 1;
|
||||||
|
|
||||||
let currentTierRequirements = [];
|
function generateInfiniteUnlocks() {
|
||||||
for (let i = 0; i < upgradeTiers.length; ++i) {
|
return new Array(numEndgameUpgrades).fill(null).map((_, i) => ({
|
||||||
const tierHandle = upgradeTiers[i];
|
required: [
|
||||||
tierHandle.improvement = fixedImprovements[i];
|
{ shape: preparementShape, amount: 30000 + i * 10000 },
|
||||||
const originalRequired = tierHandle.required.slice();
|
{ shape: finalGameShape, amount: 20000 + i * 5000 },
|
||||||
|
{ shape: rocketShape, amount: 20000 + i * 5000 },
|
||||||
for (let k = currentTierRequirements.length - 1; k >= 0; --k) {
|
],
|
||||||
const oldTierRequirement = currentTierRequirements[k];
|
excludePrevious: true,
|
||||||
if (!tierHandle.excludePrevious) {
|
}));
|
||||||
tierHandle.required.unshift({
|
|
||||||
shape: oldTierRequirement.shape,
|
|
||||||
amount: oldTierRequirement.amount,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
currentTierRequirements.push(
|
|
||||||
...originalRequired.map(req => ({
|
|
||||||
amount: req.amount,
|
|
||||||
shape: req.shape,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
currentTierRequirements.forEach(tier => {
|
|
||||||
tier.amount = findNiceIntegerValue(tier.amount * tierGrowth);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// VALIDATE
|
// Fill in endgame upgrades
|
||||||
if (G_IS_DEV) {
|
for (let i = 0; i < numEndgameUpgrades; ++i) {
|
||||||
for (const upgradeId in cachedUpgrades) {
|
fixedImprovements.push(0.1);
|
||||||
cachedUpgrades[upgradeId].forEach(tier => {
|
}
|
||||||
tier.required.forEach(({ shape }) => {
|
|
||||||
try {
|
const upgrades = {
|
||||||
ShapeDefinition.fromShortKey(shape);
|
belt: [
|
||||||
} catch (ex) {
|
{
|
||||||
throw new Error("Invalid upgrade goal: '" + ex + "' for shape" + shape);
|
required: [{ shape: "CuCuCuCu", amount: 60 }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [{ shape: "--CuCu--", amount: 500 }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [{ shape: "CpCpCpCp", amount: 1000 }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [{ shape: "SrSrSrSr:CyCyCyCy", amount: 6000 }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [{ shape: "SrSrSrSr:CyCyCyCy:SwSwSwSw", amount: 25000 }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [{ shape: preparementShape, amount: 25000 }],
|
||||||
|
excludePrevious: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [
|
||||||
|
{ shape: preparementShape, amount: 25000 },
|
||||||
|
{ shape: finalGameShape, amount: 50000 },
|
||||||
|
],
|
||||||
|
excludePrevious: true,
|
||||||
|
},
|
||||||
|
...generateInfiniteUnlocks(),
|
||||||
|
],
|
||||||
|
|
||||||
|
miner: [
|
||||||
|
{
|
||||||
|
required: [{ shape: "RuRuRuRu", amount: 300 }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [{ shape: "Cu------", amount: 800 }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [{ shape: "ScScScSc", amount: 3500 }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [{ shape: "CwCwCwCw:WbWbWbWb", amount: 23000 }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [{ shape: "CbRbRbCb:CwCwCwCw:WbWbWbWb", amount: 50000 }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [{ shape: preparementShape, amount: 25000 }],
|
||||||
|
excludePrevious: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [
|
||||||
|
{ shape: preparementShape, amount: 25000 },
|
||||||
|
{ shape: finalGameShape, amount: 50000 },
|
||||||
|
],
|
||||||
|
excludePrevious: true,
|
||||||
|
},
|
||||||
|
...generateInfiniteUnlocks(),
|
||||||
|
],
|
||||||
|
|
||||||
|
processors: [
|
||||||
|
{
|
||||||
|
required: [{ shape: "SuSuSuSu", amount: 500 }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [{ shape: "RuRu----", amount: 600 }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [{ shape: "CgScScCg", amount: 3500 }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [{ shape: "CwCrCwCr:SgSgSgSg", amount: 25000 }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [{ shape: "WrRgWrRg:CwCrCwCr:SgSgSgSg", amount: 50000 }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [{ shape: preparementShape, amount: 25000 }],
|
||||||
|
excludePrevious: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [
|
||||||
|
{ shape: preparementShape, amount: 25000 },
|
||||||
|
{ shape: finalGameShape, amount: 50000 },
|
||||||
|
],
|
||||||
|
excludePrevious: true,
|
||||||
|
},
|
||||||
|
...generateInfiniteUnlocks(),
|
||||||
|
],
|
||||||
|
|
||||||
|
painting: [
|
||||||
|
{
|
||||||
|
required: [{ shape: "RbRb----", amount: 600 }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [{ shape: "WrWrWrWr", amount: 3800 }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [{ shape: "RpRpRpRp:CwCwCwCw", amount: 6500 }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [{ shape: "WpWpWpWp:CwCwCwCw:WpWpWpWp", amount: 25000 }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [{ shape: "WpWpWpWp:CwCwCwCw:WpWpWpWp:CwCwCwCw", amount: 50000 }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [{ shape: preparementShape, amount: 25000 }],
|
||||||
|
excludePrevious: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: [
|
||||||
|
{ shape: preparementShape, amount: 25000 },
|
||||||
|
{ shape: finalGameShape, amount: 50000 },
|
||||||
|
],
|
||||||
|
excludePrevious: true,
|
||||||
|
},
|
||||||
|
...generateInfiniteUnlocks(),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Automatically generate tier levels
|
||||||
|
for (const upgradeId in upgrades) {
|
||||||
|
const upgradeTiers = upgrades[upgradeId];
|
||||||
|
|
||||||
|
let currentTierRequirements = [];
|
||||||
|
for (let i = 0; i < upgradeTiers.length; ++i) {
|
||||||
|
const tierHandle = upgradeTiers[i];
|
||||||
|
tierHandle.improvement = fixedImprovements[i];
|
||||||
|
const originalRequired = tierHandle.required.slice();
|
||||||
|
|
||||||
|
for (let k = currentTierRequirements.length - 1; k >= 0; --k) {
|
||||||
|
const oldTierRequirement = currentTierRequirements[k];
|
||||||
|
if (!tierHandle.excludePrevious) {
|
||||||
|
tierHandle.required.unshift({
|
||||||
|
shape: oldTierRequirement.shape,
|
||||||
|
amount: oldTierRequirement.amount,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
currentTierRequirements.push(
|
||||||
|
...originalRequired.map(req => ({
|
||||||
|
amount: req.amount,
|
||||||
|
shape: req.shape,
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
currentTierRequirements.forEach(tier => {
|
||||||
|
tier.amount = findNiceIntegerValue(tier.amount * tierGrowth);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// VALIDATE
|
||||||
|
if (G_IS_DEV) {
|
||||||
|
for (const upgradeId in upgrades) {
|
||||||
|
upgrades[upgradeId].forEach(tier => {
|
||||||
|
tier.required.forEach(({ shape }) => {
|
||||||
|
try {
|
||||||
|
ShapeDefinition.fromShortKey(shape);
|
||||||
|
} catch (ex) {
|
||||||
|
throw new Error("Invalid upgrade goal: '" + ex + "' for shape" + shape);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return upgrades;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the level definitions
|
||||||
|
* @param {boolean} limitedVersion
|
||||||
|
*/
|
||||||
|
export function generateLevelDefinitions(limitedVersion = false) {
|
||||||
|
const levelDefinitions = [
|
||||||
|
// 1
|
||||||
|
// Circle
|
||||||
|
{
|
||||||
|
shape: "CuCuCuCu", // belts t1
|
||||||
|
required: 30,
|
||||||
|
reward: enumHubGoalRewards.reward_cutter_and_trash,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 2
|
||||||
|
// Cutter
|
||||||
|
{
|
||||||
|
shape: "----CuCu", //
|
||||||
|
required: 40,
|
||||||
|
reward: enumHubGoalRewards.no_reward,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 3
|
||||||
|
// Rectangle
|
||||||
|
{
|
||||||
|
shape: "RuRuRuRu", // miners t1
|
||||||
|
required: 70,
|
||||||
|
reward: enumHubGoalRewards.reward_balancer,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 4
|
||||||
|
{
|
||||||
|
shape: "RuRu----", // processors t2
|
||||||
|
required: 70,
|
||||||
|
reward: enumHubGoalRewards.reward_rotater,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 5
|
||||||
|
// Rotater
|
||||||
|
{
|
||||||
|
shape: "Cu----Cu", // belts t2
|
||||||
|
required: 170,
|
||||||
|
reward: enumHubGoalRewards.reward_tunnel,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 6
|
||||||
|
{
|
||||||
|
shape: "Cu------", // miners t2
|
||||||
|
required: 270,
|
||||||
|
reward: enumHubGoalRewards.reward_painter,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 7
|
||||||
|
// Painter
|
||||||
|
{
|
||||||
|
shape: "CrCrCrCr", // unused
|
||||||
|
required: 300,
|
||||||
|
reward: enumHubGoalRewards.reward_rotater_ccw,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 8
|
||||||
|
{
|
||||||
|
shape: "RbRb----", // painter t2
|
||||||
|
required: 480,
|
||||||
|
reward: enumHubGoalRewards.reward_mixer,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 9
|
||||||
|
// Mixing (purple)
|
||||||
|
{
|
||||||
|
shape: "CpCpCpCp", // belts t3
|
||||||
|
required: 600,
|
||||||
|
reward: enumHubGoalRewards.reward_merger,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 10
|
||||||
|
// STACKER: Star shape + cyan
|
||||||
|
{
|
||||||
|
shape: "ScScScSc", // miners t3
|
||||||
|
required: 800,
|
||||||
|
reward: enumHubGoalRewards.reward_stacker,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 11
|
||||||
|
// Chainable miner
|
||||||
|
{
|
||||||
|
shape: "CgScScCg", // processors t3
|
||||||
|
required: 1000,
|
||||||
|
reward: enumHubGoalRewards.reward_miner_chainable,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 12
|
||||||
|
// Blueprints
|
||||||
|
{
|
||||||
|
shape: "CbCbCbRb:CwCwCwCw",
|
||||||
|
required: 1000,
|
||||||
|
reward: enumHubGoalRewards.reward_blueprints,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 13
|
||||||
|
// Tunnel Tier 2
|
||||||
|
{
|
||||||
|
shape: "RpRpRpRp:CwCwCwCw", // painting t3
|
||||||
|
required: 3800,
|
||||||
|
reward: enumHubGoalRewards.reward_underground_belt_tier_2,
|
||||||
|
},
|
||||||
|
|
||||||
|
// DEMO STOPS HERE
|
||||||
|
...(limitedVersion
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
shape: "RpRpRpRp:CwCwCwCw",
|
||||||
|
required: 0,
|
||||||
|
reward: enumHubGoalRewards.reward_demo_end,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
// 14
|
||||||
|
// Belt reader
|
||||||
|
{
|
||||||
|
shape: "--Cg----:--Cr----", // unused
|
||||||
|
required: 16, // Per second!
|
||||||
|
reward: enumHubGoalRewards.reward_belt_reader,
|
||||||
|
throughputOnly: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 15
|
||||||
|
// Storage
|
||||||
|
{
|
||||||
|
shape: "SrSrSrSr:CyCyCyCy", // unused
|
||||||
|
required: 10000,
|
||||||
|
reward: enumHubGoalRewards.reward_storage,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 16
|
||||||
|
// Quad Cutter
|
||||||
|
{
|
||||||
|
shape: "SrSrSrSr:CyCyCyCy:SwSwSwSw", // belts t4 (two variants)
|
||||||
|
required: 6000,
|
||||||
|
reward: enumHubGoalRewards.reward_cutter_quad,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 17
|
||||||
|
// Double painter
|
||||||
|
{
|
||||||
|
shape: "CbRbRbCb:CwCwCwCw:WbWbWbWb", // miner t4 (two variants)
|
||||||
|
required: 20000,
|
||||||
|
reward: enumHubGoalRewards.reward_painter_double,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 18
|
||||||
|
// Rotater (180deg)
|
||||||
|
{
|
||||||
|
shape: "Sg----Sg:CgCgCgCg:--CyCy--", // unused
|
||||||
|
required: 20000,
|
||||||
|
reward: enumHubGoalRewards.reward_rotater_180,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 19
|
||||||
|
// Compact splitter
|
||||||
|
{
|
||||||
|
shape: "CpRpCp--:SwSwSwSw",
|
||||||
|
required: 25000,
|
||||||
|
reward: enumHubGoalRewards.reward_splitter,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 20
|
||||||
|
// WIRES
|
||||||
|
{
|
||||||
|
shape: finalGameShape,
|
||||||
|
required: 25000,
|
||||||
|
reward: enumHubGoalRewards.reward_wires_painter_and_levers,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 21
|
||||||
|
// Filter
|
||||||
|
{
|
||||||
|
shape: "CrCwCrCw:CwCrCwCr:CrCwCrCw:CwCrCwCr",
|
||||||
|
required: 25000,
|
||||||
|
reward: enumHubGoalRewards.reward_filter,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 22
|
||||||
|
// Constant signal
|
||||||
|
{
|
||||||
|
shape: "Cg----Cr:Cw----Cw:Sy------:Cy----Cy",
|
||||||
|
required: 25000,
|
||||||
|
reward: enumHubGoalRewards.reward_constant_signal,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 23
|
||||||
|
// Display
|
||||||
|
{
|
||||||
|
shape: "CcSyCcSy:SyCcSyCc:CcSyCcSy",
|
||||||
|
required: 25000,
|
||||||
|
reward: enumHubGoalRewards.reward_display,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 24 Logic gates
|
||||||
|
{
|
||||||
|
shape: "CcRcCcRc:RwCwRwCw:Sr--Sw--:CyCyCyCy",
|
||||||
|
required: 25000,
|
||||||
|
reward: enumHubGoalRewards.reward_logic_gates,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 25 Virtual Processing
|
||||||
|
{
|
||||||
|
shape: "Rg--Rg--:CwRwCwRw:--Rg--Rg",
|
||||||
|
required: 25000,
|
||||||
|
reward: enumHubGoalRewards.reward_virtual_processing,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 26 Freeplay
|
||||||
|
{
|
||||||
|
shape: "CbCuCbCu:Sr------:--CrSrCr:CwCwCwCw",
|
||||||
|
required: 50000,
|
||||||
|
reward: enumHubGoalRewards.reward_freeplay,
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
];
|
||||||
|
|
||||||
|
if (G_IS_DEV) {
|
||||||
|
levelDefinitions.forEach(({ shape }) => {
|
||||||
|
try {
|
||||||
|
ShapeDefinition.fromShortKey(shape);
|
||||||
|
} catch (ex) {
|
||||||
|
throw new Error("Invalid tutorial goal: '" + ex + "' for shape" + shape);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return levelDefinitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
const levelDefinitions = [
|
const fullVersionUpgrades = generateUpgrades(false);
|
||||||
// 1
|
const demoVersionUpgrades = generateUpgrades(true);
|
||||||
// Circle
|
|
||||||
{
|
|
||||||
shape: "CuCuCuCu", // belts t1
|
|
||||||
required: 30,
|
|
||||||
reward: enumHubGoalRewards.reward_cutter_and_trash,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 2
|
const fullVersionLevels = generateLevelDefinitions(false);
|
||||||
// Cutter
|
const demoVersionLevels = generateLevelDefinitions(true);
|
||||||
{
|
|
||||||
shape: "----CuCu", //
|
|
||||||
required: 40,
|
|
||||||
reward: enumHubGoalRewards.no_reward,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 3
|
|
||||||
// Rectangle
|
|
||||||
{
|
|
||||||
shape: "RuRuRuRu", // miners t1
|
|
||||||
required: 70,
|
|
||||||
reward: enumHubGoalRewards.reward_balancer,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 4
|
|
||||||
{
|
|
||||||
shape: "RuRu----", // processors t2
|
|
||||||
required: 70,
|
|
||||||
reward: enumHubGoalRewards.reward_rotater,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 5
|
|
||||||
// Rotater
|
|
||||||
{
|
|
||||||
shape: "Cu----Cu", // belts t2
|
|
||||||
required: 170,
|
|
||||||
reward: enumHubGoalRewards.reward_tunnel,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 6
|
|
||||||
{
|
|
||||||
shape: "Cu------", // miners t2
|
|
||||||
required: 270,
|
|
||||||
reward: enumHubGoalRewards.reward_painter,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 7
|
|
||||||
// Painter
|
|
||||||
{
|
|
||||||
shape: "CrCrCrCr", // unused
|
|
||||||
required: 300,
|
|
||||||
reward: enumHubGoalRewards.reward_rotater_ccw,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 8
|
|
||||||
{
|
|
||||||
shape: "RbRb----", // painter t2
|
|
||||||
required: 480,
|
|
||||||
reward: enumHubGoalRewards.reward_mixer,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 9
|
|
||||||
// Mixing (purple)
|
|
||||||
{
|
|
||||||
shape: "CpCpCpCp", // belts t3
|
|
||||||
required: 600,
|
|
||||||
reward: enumHubGoalRewards.reward_merger,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 10
|
|
||||||
// STACKER: Star shape + cyan
|
|
||||||
{
|
|
||||||
shape: "ScScScSc", // miners t3
|
|
||||||
required: 800,
|
|
||||||
reward: enumHubGoalRewards.reward_stacker,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 11
|
|
||||||
// Chainable miner
|
|
||||||
{
|
|
||||||
shape: "CgScScCg", // processors t3
|
|
||||||
required: 1000,
|
|
||||||
reward: enumHubGoalRewards.reward_miner_chainable,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 12
|
|
||||||
// Blueprints
|
|
||||||
{
|
|
||||||
shape: "CbCbCbRb:CwCwCwCw",
|
|
||||||
required: 1000,
|
|
||||||
reward: enumHubGoalRewards.reward_blueprints,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 13
|
|
||||||
// Tunnel Tier 2
|
|
||||||
{
|
|
||||||
shape: "RpRpRpRp:CwCwCwCw", // painting t3
|
|
||||||
required: 3800,
|
|
||||||
reward: enumHubGoalRewards.reward_underground_belt_tier_2,
|
|
||||||
},
|
|
||||||
|
|
||||||
// DEMO STOPS HERE
|
|
||||||
...(IS_DEMO
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
shape: "RpRpRpRp:CwCwCwCw",
|
|
||||||
required: 0,
|
|
||||||
reward: enumHubGoalRewards.reward_demo_end,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: [
|
|
||||||
// 14
|
|
||||||
// Belt reader
|
|
||||||
{
|
|
||||||
shape: "--Cg----:--Cr----", // unused
|
|
||||||
required: 16, // Per second!
|
|
||||||
reward: enumHubGoalRewards.reward_belt_reader,
|
|
||||||
throughputOnly: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 15
|
|
||||||
// Storage
|
|
||||||
{
|
|
||||||
shape: "SrSrSrSr:CyCyCyCy", // unused
|
|
||||||
required: 10000,
|
|
||||||
reward: enumHubGoalRewards.reward_storage,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 16
|
|
||||||
// Quad Cutter
|
|
||||||
{
|
|
||||||
shape: "SrSrSrSr:CyCyCyCy:SwSwSwSw", // belts t4 (two variants)
|
|
||||||
required: 6000,
|
|
||||||
reward: enumHubGoalRewards.reward_cutter_quad,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 17
|
|
||||||
// Double painter
|
|
||||||
{
|
|
||||||
shape: "CbRbRbCb:CwCwCwCw:WbWbWbWb", // miner t4 (two variants)
|
|
||||||
required: 20000,
|
|
||||||
reward: enumHubGoalRewards.reward_painter_double,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 18
|
|
||||||
// Rotater (180deg)
|
|
||||||
{
|
|
||||||
shape: "Sg----Sg:CgCgCgCg:--CyCy--", // unused
|
|
||||||
required: 20000,
|
|
||||||
reward: enumHubGoalRewards.reward_rotater_180,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 19
|
|
||||||
// Compact splitter
|
|
||||||
{
|
|
||||||
shape: "CpRpCp--:SwSwSwSw",
|
|
||||||
required: 25000,
|
|
||||||
reward: enumHubGoalRewards.reward_splitter,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 20
|
|
||||||
// WIRES
|
|
||||||
{
|
|
||||||
shape: finalGameShape,
|
|
||||||
required: 25000,
|
|
||||||
reward: enumHubGoalRewards.reward_wires_painter_and_levers,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 21
|
|
||||||
// Filter
|
|
||||||
{
|
|
||||||
shape: "CrCwCrCw:CwCrCwCr:CrCwCrCw:CwCrCwCr",
|
|
||||||
required: 25000,
|
|
||||||
reward: enumHubGoalRewards.reward_filter,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 22
|
|
||||||
// Constant signal
|
|
||||||
{
|
|
||||||
shape: "Cg----Cr:Cw----Cw:Sy------:Cy----Cy",
|
|
||||||
required: 25000,
|
|
||||||
reward: enumHubGoalRewards.reward_constant_signal,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 23
|
|
||||||
// Display
|
|
||||||
{
|
|
||||||
shape: "CcSyCcSy:SyCcSyCc:CcSyCcSy",
|
|
||||||
required: 25000,
|
|
||||||
reward: enumHubGoalRewards.reward_display,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 24 Logic gates
|
|
||||||
{
|
|
||||||
shape: "CcRcCcRc:RwCwRwCw:Sr--Sw--:CyCyCyCy",
|
|
||||||
required: 25000,
|
|
||||||
reward: enumHubGoalRewards.reward_logic_gates,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 25 Virtual Processing
|
|
||||||
{
|
|
||||||
shape: "Rg--Rg--:CwRwCwRw:--Rg--Rg",
|
|
||||||
required: 25000,
|
|
||||||
reward: enumHubGoalRewards.reward_virtual_processing,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 26 Freeplay
|
|
||||||
{
|
|
||||||
shape: "CbCuCbCu:Sr------:--CrSrCr:CwCwCwCw",
|
|
||||||
required: 50000,
|
|
||||||
reward: enumHubGoalRewards.reward_freeplay,
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
];
|
|
||||||
|
|
||||||
if (G_IS_DEV) {
|
|
||||||
levelDefinitions.forEach(({ shape }) => {
|
|
||||||
try {
|
|
||||||
ShapeDefinition.fromShortKey(shape);
|
|
||||||
} catch (ex) {
|
|
||||||
throw new Error("Invalid tutorial goal: '" + ex + "' for shape" + shape);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export class RegularGameMode extends GameMode {
|
export class RegularGameMode extends GameMode {
|
||||||
constructor(root) {
|
constructor(root) {
|
||||||
@ -433,7 +451,13 @@ export class RegularGameMode extends GameMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getUpgrades() {
|
getUpgrades() {
|
||||||
return cachedUpgrades;
|
return this.root.app.restrictionMgr.getHasExtendedUpgrades()
|
||||||
|
? fullVersionUpgrades
|
||||||
|
: demoVersionUpgrades;
|
||||||
|
}
|
||||||
|
|
||||||
|
getIsFreeplayAvailable() {
|
||||||
|
return this.root.app.restrictionMgr.getHasExtendedLevelsAndFreeplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
getBlueprintShapeKey() {
|
getBlueprintShapeKey() {
|
||||||
@ -441,6 +465,8 @@ export class RegularGameMode extends GameMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getLevelDefinitions() {
|
getLevelDefinitions() {
|
||||||
return levelDefinitions;
|
return this.root.app.restrictionMgr.getHasExtendedLevelsAndFreeplay()
|
||||||
|
? fullVersionLevels
|
||||||
|
: demoVersionLevels;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,6 +89,14 @@ export class SavegameManager extends ReadWriteProxy {
|
|||||||
return new Savegame(this.app, { internalId, metaDataRef: metadata });
|
return new Savegame(this.app, { internalId, metaDataRef: metadata });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns if this manager has any savegame of a 1.1.19 version, which
|
||||||
|
* enables all levels
|
||||||
|
*/
|
||||||
|
getHasAnyLegacySavegames() {
|
||||||
|
return this.currentData.savegames.some(savegame => savegame.version === 1005 || savegame.level > 14);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a savegame
|
* Deletes a savegame
|
||||||
* @param {SavegameMetadata} game
|
* @param {SavegameMetadata} game
|
||||||
@ -142,7 +150,9 @@ export class SavegameManager extends ReadWriteProxy {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.currentData.savegames.push(metaData);
|
this.currentData.savegames.push(metaData);
|
||||||
this.sortSavegames();
|
|
||||||
|
// Notice: This is async and happening in the background
|
||||||
|
this.updateAfterSavegamesChanged();
|
||||||
|
|
||||||
return new Savegame(this.app, {
|
return new Savegame(this.app, {
|
||||||
internalId: id,
|
internalId: id,
|
||||||
@ -150,8 +160,16 @@ export class SavegameManager extends ReadWriteProxy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to import a savegame
|
||||||
|
* @param {object} data
|
||||||
|
*/
|
||||||
importSavegame(data) {
|
importSavegame(data) {
|
||||||
const savegame = this.createNewSavegame();
|
const savegame = this.createNewSavegame();
|
||||||
|
|
||||||
|
// Track legacy savegames
|
||||||
|
const isOldSavegame = data.version < 1006;
|
||||||
|
|
||||||
const migrationResult = savegame.migrate(data);
|
const migrationResult = savegame.migrate(data);
|
||||||
if (migrationResult.isBad()) {
|
if (migrationResult.isBad()) {
|
||||||
return Promise.reject("Failed to migrate: " + migrationResult.reason);
|
return Promise.reject("Failed to migrate: " + migrationResult.reason);
|
||||||
@ -163,7 +181,19 @@ export class SavegameManager extends ReadWriteProxy {
|
|||||||
return Promise.reject("Verification failed: " + verification.result);
|
return Promise.reject("Verification failed: " + verification.result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return savegame.writeSavegameAndMetadata().then(() => this.sortSavegames());
|
return savegame
|
||||||
|
.writeSavegameAndMetadata()
|
||||||
|
.then(() => this.updateAfterSavegamesChanged())
|
||||||
|
.then(() => this.app.restrictionMgr.onHasLegacySavegamesChanged(isOldSavegame));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook after the savegames got changed
|
||||||
|
*/
|
||||||
|
updateAfterSavegamesChanged() {
|
||||||
|
return this.sortSavegames()
|
||||||
|
.then(() => this.writeAsync())
|
||||||
|
.then(() => this.app.restrictionMgr.onHasLegacySavegamesChanged(this.getHasAnyLegacySavegames()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -212,7 +242,7 @@ export class SavegameManager extends ReadWriteProxy {
|
|||||||
if (G_IS_DEV && globalConfig.debug.disableSavegameWrite) {
|
if (G_IS_DEV && globalConfig.debug.disableSavegameWrite) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
return this.sortSavegames().then(() => this.writeAsync());
|
return this.updateAfterSavegamesChanged();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,6 +145,11 @@ export class PreloadState extends GameState {
|
|||||||
this.app.backgroundResourceLoader.startLoading();
|
this.app.backgroundResourceLoader.startLoading();
|
||||||
})
|
})
|
||||||
|
|
||||||
|
.then(() => this.setStatus("Initializing restrictions"))
|
||||||
|
.then(() => {
|
||||||
|
return this.app.restrictionMgr.initialize();
|
||||||
|
})
|
||||||
|
|
||||||
.then(() => this.setStatus("Initializing savegame"))
|
.then(() => this.setStatus("Initializing savegame"))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return this.app.savegameMgr.initialize().catch(err => {
|
return this.app.savegameMgr.initialize().catch(err => {
|
||||||
|
Loading…
Reference in New Issue
Block a user