Skip to content

Commit 50667a7

Browse files
committed
Get saving buildings in game functional
1 parent 777631c commit 50667a7

File tree

5 files changed

+79
-113
lines changed

5 files changed

+79
-113
lines changed

src/ts/buildings.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import ClickerCookie from "./clickercookie.js";
22
import { capitalize, commaify, clamp } from "./helper.js";
33
import { Game } from "./main.js";
4+
import { SaveProvider } from "./saving.js";
45
import { hideTooltip } from "./tooltip.js";
56

67
export interface BuildingData {
@@ -17,7 +18,13 @@ export interface BuildingData {
1718
upgradeCostMultiplier?: number;
1819
}
1920

20-
export class Building {
21+
export interface BuildingSave {
22+
bought: number;
23+
CPSGain: number;
24+
CPSGiven: number;
25+
}
26+
27+
export class Building extends SaveProvider {
2128
private _clickercookie: ClickerCookie;
2229

2330
name: string;
@@ -49,6 +56,8 @@ export class Building {
4956

5057
html: HTMLDivElement;
5158
constructor(clickercookie: ClickerCookie, data: BuildingData) {
59+
super();
60+
5261
this._clickercookie = clickercookie;
5362

5463
// setup HTML (uses indentation to show structure)
@@ -164,4 +173,18 @@ export class Building {
164173
destroy() {
165174
this.html.remove();
166175
}
176+
177+
getSaveData(): BuildingSave {
178+
return {
179+
bought: this.bought,
180+
CPSGain: this.CPSGain,
181+
CPSGiven: this.CPSGiven
182+
}
183+
}
184+
185+
loadSaveData(saveData: BuildingSave) {
186+
this.bought = saveData.bought;
187+
this.CPSGain = saveData.CPSGain;
188+
this.CPSGiven = saveData.CPSGiven
189+
}
167190
}

src/ts/clickercookie.ts

Lines changed: 2 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -30,36 +30,6 @@ interface ClickerCookieSaveData {
3030
totalCookies: number;
3131
cookiesPerClick: number;
3232
cookieBeenClickedTimes: number;
33-
34-
/* buildings */
35-
// keyboard
36-
keyboardsBought: number;
37-
keyboardCPSGain: number;
38-
keyboardCPSGiven: number;
39-
// grandpa
40-
grandpasBought: number;
41-
grandpaCPSGain: number;
42-
grandpaCPSGiven: number;
43-
// ranch
44-
ranchesBought: number;
45-
ranchCPSGain: number;
46-
ranchCPSGiven: number;
47-
// television
48-
televisionsBought: number;
49-
televisionCPSGain: number;
50-
televisionCPSGiven: number;
51-
// worker
52-
workersBought: number;
53-
workerCPSGain: number;
54-
workerCPSGiven: number;
55-
// wallet
56-
walletsBought: number;
57-
walletCPSGain: number;
58-
walletCPSGiven: number;
59-
// church
60-
churchesBought: number;
61-
churchCPSGain: number;
62-
churchCPSGiven: number;
6333
}
6434

6535
export default class ClickerCookie extends Mod {
@@ -643,45 +613,10 @@ export default class ClickerCookie extends Mod {
643613
cookies: this.cookies,
644614
totalCookies: this.totalCookies,
645615
cookiesPerClick: this.cookiesPerClick,
646-
cookieBeenClickedTimes: this.cookieBeenClickedTimes,
647-
/* buildings */
648-
// keyboard
649-
keyboardsBought: this.keyboard.bought,
650-
keyboardCPSGain: this.keyboard.CPSGain,
651-
keyboardCPSGiven: this.keyboard.CPSGiven,
652-
// grandpa
653-
grandpasBought: this.grandpa.bought,
654-
grandpaCPSGain: this.grandpa.CPSGain,
655-
grandpaCPSGiven: this.grandpa.CPSGiven,
656-
// ranch
657-
ranchesBought: this.ranch.bought,
658-
ranchCPSGain: this.ranch.CPSGain,
659-
ranchCPSGiven: this.ranch.CPSGiven,
660-
// television
661-
televisionsBought: this.television.bought,
662-
televisionCPSGain: this.television.CPSGain,
663-
televisionCPSGiven: this.television.CPSGiven,
664-
// worker
665-
workersBought: this.worker.bought,
666-
workerCPSGain: this.worker.CPSGain,
667-
workerCPSGiven: this.worker.CPSGiven,
668-
// wallet
669-
walletsBought: this.wallet.bought,
670-
walletCPSGain: this.wallet.CPSGain,
671-
walletCPSGiven: this.wallet.CPSGiven,
672-
// church
673-
churchesBought: this.church.bought,
674-
churchCPSGain: this.church.CPSGain,
675-
churchCPSGiven: this.church.CPSGiven
616+
cookieBeenClickedTimes: this.cookieBeenClickedTimes
676617
}
677618
}
678-
loadSaveData(saveData: ClickerCookieSaveData) {
679-
for (const i in saveData) {
680-
if (i === undefined) {
681-
console.warn("During loading a value in saveData was found undefined. Errors will likely follow...");
682-
}
683-
}
684-
619+
loadSaveData(saveData: ClickerCookieSaveData) {
685620
this.grandpa.setVisibility(false);
686621
this.ranch.setVisibility(false);
687622
this.television.setVisibility(false);
@@ -693,36 +628,5 @@ export default class ClickerCookie extends Mod {
693628
this.totalCookies = saveData.totalCookies;
694629
this.cookiesPerClick = saveData.cookiesPerClick;
695630
this.cookieBeenClickedTimes = saveData.cookieBeenClickedTimes;
696-
697-
/* buildings */
698-
// keyboard
699-
this.keyboard.bought = saveData.keyboardsBought;
700-
this.keyboard.CPSGain = saveData.keyboardCPSGain;
701-
this.keyboard.CPSGiven = saveData.keyboardCPSGiven;
702-
// grandpa
703-
this.grandpa.bought = saveData.grandpasBought;
704-
this.grandpa.CPSGain = saveData.grandpaCPSGain;
705-
this.grandpa.CPSGiven = saveData.grandpaCPSGiven;
706-
// ranch
707-
this.ranch.bought = saveData.ranchesBought;
708-
this.ranch.CPSGain = saveData.ranchCPSGain;
709-
this.ranch.CPSGiven = saveData.ranchCPSGiven;
710-
// television
711-
this.television.bought = saveData.televisionsBought;
712-
this.television.CPSGain = saveData.televisionCPSGain;
713-
this.television.CPSGiven = saveData.televisionCPSGiven;
714-
// worker
715-
this.worker.bought = saveData.workersBought;
716-
this.worker.CPSGain = saveData.workerCPSGain;
717-
this.worker.CPSGiven = saveData.workerCPSGiven;
718-
// wallet
719-
this.wallet.bought = saveData.walletsBought;
720-
this.wallet.CPSGain = saveData.walletCPSGain;
721-
this.wallet.CPSGiven = saveData.walletCPSGiven;
722-
// church
723-
this.church.bought = saveData.churchesBought;
724-
this.church.CPSGain = saveData.churchCPSGain;
725-
this.church.CPSGiven = saveData.churchCPSGiven;
726-
// ...
727631
}
728632
}

src/ts/handlers.ts

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//* Ideally I would put things like BackgroundHandler in personalization.ts but because of lexical declarations we can't do that without getting circular imports as far as I can tell. This is fine.
22

3-
import { Building } from "./buildings.js";
3+
import { Building, BuildingSave } from "./buildings.js";
44
import { Handler, Identifier, UniqueKeyHandler } from "./handler.js";
55
import { url } from "./helper.js";
66
import { Game, GameSaveData } from "./main.js";
@@ -126,6 +126,38 @@ export class BuildingHandler extends Handler<Building> {
126126
}
127127
return bought;
128128
}
129+
130+
/**
131+
* Dumps savedata for all registered buildings
132+
* @param namespace Optional: if present only dump savedata from this namespace
133+
* @returns savedata as obj in following format: `stringifiedIdentifier: BuildingSave`
134+
*/
135+
dumpSave(namespace: string=undefined) {
136+
const saveObj: Record<string, BuildingSave> = {};
137+
for (const value of (namespace === undefined) ? this : this.getValuesFromNamespace(namespace)) {
138+
saveObj[this.getKeyFromValue(value)] = value.getSaveData();
139+
}
140+
return saveObj;
141+
}
142+
143+
/**
144+
* Apply save data state to all registered buildings
145+
* @param saveObj The save object to load the data of
146+
* @param namespace Optional: if present will only load data for buildings of a given namespace.
147+
*/
148+
loadSave(saveObj: Record<string, BuildingSave>, namespace: string=undefined) {
149+
for (const stringifiedIdentifier in saveObj) {
150+
const id = Identifier.fromString(stringifiedIdentifier);
151+
152+
if (namespace !== undefined && id.namespace !== namespace) continue;
153+
154+
const building = this.getFromIdentifier(id);
155+
156+
if (building === undefined) continue; // if buildings are not registered we obviously can't load them. todo: should this warn?
157+
158+
building.loadSaveData(saveObj[stringifiedIdentifier]);
159+
}
160+
}
129161
}
130162

131163
/* Upgrades */
@@ -238,9 +270,6 @@ export class ModHandler extends UniqueKeyHandler<Mod> {
238270

239271
Game.getInstance().isModded = true;
240272

241-
// load game save data to todo: write
242-
Game.getInstance().loadSaveData(Game.getInstance().savinator5000.getLocalStorageSave().getData("game") as GameSaveData);
243-
244273
console.log("Loaded mod from URL: "+url);
245274
}
246275

@@ -265,9 +294,6 @@ export class ModHandler extends UniqueKeyHandler<Mod> {
265294

266295
Game.getInstance().isModded = true;
267296

268-
// load game save data to todo: write
269-
Game.getInstance().loadSaveData(Game.getInstance().savinator5000.getLocalStorageSave().getData("game") as GameSaveData)
270-
271297
console.log("Successfully added mod from file: "+file.name);
272298
};
273299
}
@@ -347,11 +373,15 @@ export class ModHandler extends UniqueKeyHandler<Mod> {
347373
new SimplePopup({x: 400, y: 200, title: "Error", text: `The mod namespace "${key}" is already present!`});
348374
return;
349375
}
376+
377+
if (Game.getInstance().initialized) Game.getInstance().savinator5000.save(); // save and load to save any changes made since last save and load so that buildings and upgrades will be loaded for the mod we just added
350378

351379
super.register(key, mod);
352380
this.saveHandler.register(mod.NAMESPACE, mod);
353381
document.getElementById("modsNumberLoaded")!.innerText = (Handlers.MOD.length - 1).toString(); //* subtract one so we don't show clickercookie (makes more sense to the user)
354-
mod.init();
382+
mod.init(); // register their stuff
383+
384+
if (Game.getInstance().initialized) Game.getInstance().savinator5000.load();
355385
}
356386
}
357387

src/ts/main.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { SimplePopup } from "./popup.js";
1616
import { Handlers, ModHandler } from "./handlers.js";
1717

1818
import { NewMod } from "./exmod.js"; //* note: this import is intentionally left unused so tsc can find this file and compile it
19+
import { BuildingSave } from "./buildings.js";
1920

2021
// ------------------------------------
2122
// Version Constants
@@ -76,7 +77,8 @@ export interface GameSaveData {
7677
currentlyClickedObjectKey: string;
7778
currentBackgroundKey: string;
7879

79-
upgradesSave: Record<string, UpgradeSave>
80+
upgradesSave: Record<string, UpgradeSave>;
81+
buildingsSave: Record<string, BuildingSave>;
8082
}
8183

8284
export class Game extends SaveProvider {
@@ -152,7 +154,7 @@ export class Game extends SaveProvider {
152154
y: number
153155
};
154156

155-
public theGameCanLoopBecauseTheInitializationIsCompleted: boolean;
157+
public initialized: boolean;
156158

157159
//* The following intervals will be started once init() completes!
158160
public readonly AUTOSAVE_INTERVAL = new Interval(() => {
@@ -183,7 +185,7 @@ export class Game extends SaveProvider {
183185

184186
this.savinator5000 = new Savinator(Handlers.SAVE);
185187

186-
this.theGameCanLoopBecauseTheInitializationIsCompleted = false;
188+
this.initialized = false;
187189
}
188190

189191
init() {
@@ -296,12 +298,12 @@ export class Game extends SaveProvider {
296298
this.CPS_INTERVAL.start();
297299
this.GAME_LOOP_INTERVAL.start();
298300

299-
this.theGameCanLoopBecauseTheInitializationIsCompleted = true;
301+
this.initialized= true;
300302
console.log("Successfully completed initialization.");
301303
}
302304

303305
gameLoop() {
304-
if (!this.theGameCanLoopBecauseTheInitializationIsCompleted) return;
306+
if (!this.initialized) return;
305307

306308
Handlers.UPGRADE.checkUpgradeAvailability();
307309

@@ -347,7 +349,8 @@ export class Game extends SaveProvider {
347349

348350
getSaveData(): GameSaveData {
349351
/** savedata is null on first boot */
350-
const originalUpgradeSave = (this.savinator5000.getLocalStorageSave()) ? (this.savinator5000.getLocalStorageSave().getData("game") as GameSaveData).upgradesSave : {}
352+
const originalUpgradeSave = (this.savinator5000.getLocalStorageSave()) ? (this.savinator5000.getLocalStorageSave().getData("game") as GameSaveData).upgradesSave : {};
353+
const originalBuildingSave = (this.savinator5000.getLocalStorageSave()) ? (this.savinator5000.getLocalStorageSave().getData("game") as GameSaveData).buildingsSave : {};
351354

352355
return {
353356
hasCheated: this.hasCheated,
@@ -361,6 +364,10 @@ export class Game extends SaveProvider {
361364
upgradesSave: { // merge to preserve unregistered upgrades
362365
...originalUpgradeSave,
363366
...Handlers.UPGRADE.dumpSave()
367+
},
368+
buildingsSave: {
369+
...originalBuildingSave,
370+
...Handlers.BUILDING.dumpSave()
364371
}
365372
}
366373
}
@@ -375,6 +382,7 @@ export class Game extends SaveProvider {
375382

376383
// the following doesn't have anything to do with GameSaveData but will be done here because this spot makes the most sense
377384
Handlers.UPGRADE.loadSave(saveData.upgradesSave);
385+
Handlers.BUILDING.loadSave(saveData.buildingsSave);
378386

379387
Handlers.UPGRADE.destroyAllUpgrades();
380388
Handlers.UPGRADE.showUnlockedUpgrades();

src/ts/saving.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ export class Savinator {
151151
}
152152
}
153153

154+
// todo: change the documentation of this class to reflect additional uses, such as Building
154155
export class SaveProvider {
155156
/**
156157
* If registered with a {@link SaveHandler}, it will use whatever this function returns as the savedata.

0 commit comments

Comments
 (0)