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 =
|
||||
G_IS_DEV &&
|
||||
typeof window !== "undefined" &&
|
||||
@ -9,6 +7,8 @@ export const IS_DEBUG =
|
||||
|
||||
export const SUPPORT_TOUCH = false;
|
||||
|
||||
export const IS_MAC = navigator.platform.toLowerCase().indexOf("mac") >= 0;
|
||||
|
||||
const smoothCanvas = true;
|
||||
|
||||
export const THIRDPARTY_URLS = {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Application } from "../application";
|
||||
import { IS_MAC } from "./config";
|
||||
import { ExplainedResult } from "./explained_result";
|
||||
import { queryParamOptions } from "./query_parameters";
|
||||
import { ReadWriteProxy } from "./read_write_proxy";
|
||||
@ -9,6 +10,8 @@ export class RestrictionManager extends ReadWriteProxy {
|
||||
*/
|
||||
constructor(app) {
|
||||
super(app, "restriction-flags.bin");
|
||||
|
||||
this.currentData = this.getDefaultData();
|
||||
}
|
||||
|
||||
// -- RW Proxy Impl
|
||||
@ -24,6 +27,7 @@ export class RestrictionManager extends ReadWriteProxy {
|
||||
*/
|
||||
getDefaultData() {
|
||||
return {
|
||||
version: this.getCurrentVersion(),
|
||||
savegameV1119Imported: false,
|
||||
};
|
||||
}
|
||||
@ -42,17 +46,53 @@ export class RestrictionManager extends ReadWriteProxy {
|
||||
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
|
||||
|
||||
/**
|
||||
* 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 {boolean}
|
||||
*/
|
||||
isLimitedVersion() {
|
||||
return queryParamOptions.fullVersion
|
||||
? false
|
||||
: (!G_IS_DEV && !G_IS_STANDALONE) ||
|
||||
(typeof window !== "undefined" && window.location.search.indexOf("demo") >= 0);
|
||||
if (IS_MAC) {
|
||||
// On mac, the full version is always active
|
||||
return false;
|
||||
}
|
||||
|
||||
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() {
|
||||
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 { GameMode } from "../game_mode";
|
||||
import { ShapeDefinition } from "../shape_definition";
|
||||
@ -9,12 +8,17 @@ const finalGameShape = "RuCw--Cw:----Ru--";
|
||||
const preparementShape = "CpRpCp--:SwSwSwSw";
|
||||
const blueprintShape = "CbCbCbRb:CwCwCwCw";
|
||||
|
||||
// Tiers need % of the previous tier as requirement too
|
||||
const tierGrowth = 2.5;
|
||||
|
||||
/**
|
||||
* Generates all upgrades
|
||||
* @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;
|
||||
|
||||
// @FIXME @TODO
|
||||
const numEndgameUpgrades = !IS_DEMO ? 20 - fixedImprovements.length - 1 : 0;
|
||||
|
||||
function generateEndgameUpgrades() {
|
||||
function generateInfiniteUnlocks() {
|
||||
return new Array(numEndgameUpgrades).fill(null).map((_, i) => ({
|
||||
required: [
|
||||
{ shape: preparementShape, amount: 30000 + i * 10000 },
|
||||
@ -25,12 +29,12 @@ function generateEndgameUpgrades() {
|
||||
}));
|
||||
}
|
||||
|
||||
// Fill in endgame upgrades
|
||||
for (let i = 0; i < numEndgameUpgrades; ++i) {
|
||||
fixedImprovements.push(0.1);
|
||||
}
|
||||
|
||||
/** @type {Object<string, import("../game_mode").UpgradeTiers>} */
|
||||
const cachedUpgrades = {
|
||||
const upgrades = {
|
||||
belt: [
|
||||
{
|
||||
required: [{ shape: "CuCuCuCu", amount: 60 }],
|
||||
@ -58,7 +62,7 @@ const cachedUpgrades = {
|
||||
],
|
||||
excludePrevious: true,
|
||||
},
|
||||
...generateEndgameUpgrades(),
|
||||
...generateInfiniteUnlocks(),
|
||||
],
|
||||
|
||||
miner: [
|
||||
@ -88,7 +92,7 @@ const cachedUpgrades = {
|
||||
],
|
||||
excludePrevious: true,
|
||||
},
|
||||
...generateEndgameUpgrades(),
|
||||
...generateInfiniteUnlocks(),
|
||||
],
|
||||
|
||||
processors: [
|
||||
@ -118,7 +122,7 @@ const cachedUpgrades = {
|
||||
],
|
||||
excludePrevious: true,
|
||||
},
|
||||
...generateEndgameUpgrades(),
|
||||
...generateInfiniteUnlocks(),
|
||||
],
|
||||
|
||||
painting: [
|
||||
@ -148,16 +152,13 @@ const cachedUpgrades = {
|
||||
],
|
||||
excludePrevious: true,
|
||||
},
|
||||
...generateEndgameUpgrades(),
|
||||
...generateInfiniteUnlocks(),
|
||||
],
|
||||
};
|
||||
|
||||
// Tiers need % of the previous tier as requirement too
|
||||
const tierGrowth = 2.5;
|
||||
|
||||
// Automatically generate tier levels
|
||||
for (const upgradeId in cachedUpgrades) {
|
||||
const upgradeTiers = cachedUpgrades[upgradeId];
|
||||
for (const upgradeId in upgrades) {
|
||||
const upgradeTiers = upgrades[upgradeId];
|
||||
|
||||
let currentTierRequirements = [];
|
||||
for (let i = 0; i < upgradeTiers.length; ++i) {
|
||||
@ -188,8 +189,8 @@ for (const upgradeId in cachedUpgrades) {
|
||||
|
||||
// VALIDATE
|
||||
if (G_IS_DEV) {
|
||||
for (const upgradeId in cachedUpgrades) {
|
||||
cachedUpgrades[upgradeId].forEach(tier => {
|
||||
for (const upgradeId in upgrades) {
|
||||
upgrades[upgradeId].forEach(tier => {
|
||||
tier.required.forEach(({ shape }) => {
|
||||
try {
|
||||
ShapeDefinition.fromShortKey(shape);
|
||||
@ -201,6 +202,14 @@ if (G_IS_DEV) {
|
||||
}
|
||||
}
|
||||
|
||||
return upgrades;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the level definitions
|
||||
* @param {boolean} limitedVersion
|
||||
*/
|
||||
export function generateLevelDefinitions(limitedVersion = false) {
|
||||
const levelDefinitions = [
|
||||
// 1
|
||||
// Circle
|
||||
@ -304,7 +313,7 @@ const levelDefinitions = [
|
||||
},
|
||||
|
||||
// DEMO STOPS HERE
|
||||
...(IS_DEMO
|
||||
...(limitedVersion
|
||||
? [
|
||||
{
|
||||
shape: "RpRpRpRp:CwCwCwCw",
|
||||
@ -427,13 +436,28 @@ if (G_IS_DEV) {
|
||||
});
|
||||
}
|
||||
|
||||
return levelDefinitions;
|
||||
}
|
||||
|
||||
const fullVersionUpgrades = generateUpgrades(false);
|
||||
const demoVersionUpgrades = generateUpgrades(true);
|
||||
|
||||
const fullVersionLevels = generateLevelDefinitions(false);
|
||||
const demoVersionLevels = generateLevelDefinitions(true);
|
||||
|
||||
export class RegularGameMode extends GameMode {
|
||||
constructor(root) {
|
||||
super(root);
|
||||
}
|
||||
|
||||
getUpgrades() {
|
||||
return cachedUpgrades;
|
||||
return this.root.app.restrictionMgr.getHasExtendedUpgrades()
|
||||
? fullVersionUpgrades
|
||||
: demoVersionUpgrades;
|
||||
}
|
||||
|
||||
getIsFreeplayAvailable() {
|
||||
return this.root.app.restrictionMgr.getHasExtendedLevelsAndFreeplay();
|
||||
}
|
||||
|
||||
getBlueprintShapeKey() {
|
||||
@ -441,6 +465,8 @@ export class RegularGameMode extends GameMode {
|
||||
}
|
||||
|
||||
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 });
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param {SavegameMetadata} game
|
||||
@ -142,7 +150,9 @@ export class SavegameManager extends ReadWriteProxy {
|
||||
});
|
||||
|
||||
this.currentData.savegames.push(metaData);
|
||||
this.sortSavegames();
|
||||
|
||||
// Notice: This is async and happening in the background
|
||||
this.updateAfterSavegamesChanged();
|
||||
|
||||
return new Savegame(this.app, {
|
||||
internalId: id,
|
||||
@ -150,8 +160,16 @@ export class SavegameManager extends ReadWriteProxy {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to import a savegame
|
||||
* @param {object} data
|
||||
*/
|
||||
importSavegame(data) {
|
||||
const savegame = this.createNewSavegame();
|
||||
|
||||
// Track legacy savegames
|
||||
const isOldSavegame = data.version < 1006;
|
||||
|
||||
const migrationResult = savegame.migrate(data);
|
||||
if (migrationResult.isBad()) {
|
||||
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 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) {
|
||||
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();
|
||||
})
|
||||
|
||||
.then(() => this.setStatus("Initializing restrictions"))
|
||||
.then(() => {
|
||||
return this.app.restrictionMgr.initialize();
|
||||
})
|
||||
|
||||
.then(() => this.setStatus("Initializing savegame"))
|
||||
.then(() => {
|
||||
return this.app.savegameMgr.initialize().catch(err => {
|
||||
|
Loading…
Reference in New Issue
Block a user