147 lines
3.9 KiB
JavaScript
147 lines
3.9 KiB
JavaScript
import { REGIONS } from "../config/regions.js";
|
|
import { log } from "../core/log.js";
|
|
import { world } from "@minecraft/server";
|
|
|
|
const KEY = "tama.progress";
|
|
const VERSION = 1; //For updating the json in the save
|
|
|
|
/**
|
|
* The in-memory copy of the whole save document, so we don't re-read the
|
|
* world's dynamic properties every time something needs a value.
|
|
* Null until load() runs. saveState() writes it back out to the world save.
|
|
*
|
|
* cache = {
|
|
* version: 1,
|
|
* coins: 0,
|
|
* gates: {
|
|
* lagoon: true,
|
|
* farmland: false,
|
|
* seaside: false,
|
|
* skyland: false
|
|
* }
|
|
* }
|
|
*/
|
|
let cache = null;
|
|
|
|
/**
|
|
* Reads the save document out of the world and puts it in `cache`.
|
|
*
|
|
* Nothing stored under KEY yet means a brand-new world - getDynamicProperty
|
|
* returns undefined - so build the defaults and write them straight back,
|
|
* which is what creates the save.
|
|
*
|
|
* Otherwise the stored value is JSON text, so parse it back into an object.
|
|
*/
|
|
export function load(){
|
|
const raw = world.getDynamicProperty(KEY);
|
|
//let raw = undefined;
|
|
//good for debugging before the value is updated
|
|
//console.log(raw);
|
|
|
|
if(raw === undefined) {
|
|
cache = buildDefaults();
|
|
saveState();
|
|
} else {
|
|
//good for debugging post update
|
|
//console.log(raw);
|
|
cache = JSON.parse(raw);
|
|
}
|
|
if(cache.version < VERSION) {
|
|
//if(version < (VERSION) -> add attribute etc))
|
|
log("==================================");
|
|
log(`version: ${cache.version}, code expects ${VERSION}`);
|
|
log("==================================");
|
|
//if attribute === undefined -> set default value
|
|
cache.version = VERSION;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Builds a fresh save document for a world that has never been played.
|
|
*
|
|
* `gates` is an object (not an array) filled by looping REGIONS and copying
|
|
* each region's unlockedAtStart value, so adding a region to the config
|
|
* automatically adds its gate here with no change to this function.
|
|
*/
|
|
function buildDefaults() {
|
|
const gates = {};
|
|
const coins = 0;
|
|
for(const id in REGIONS)
|
|
{
|
|
gates[id] = REGIONS[id].unlockedAtStart;
|
|
}
|
|
return{version: VERSION, gates: gates, coins: coins};
|
|
}
|
|
|
|
/**
|
|
* Returns the cached save document.
|
|
* This is the live object, not a copy - anything that mutates what comes back
|
|
* must call saveState() afterwards, or the change is lost on world close.
|
|
*/
|
|
export function getState() {
|
|
return cache;
|
|
}
|
|
|
|
/**
|
|
* buildDefaults returns a value,
|
|
* using .gates returns just the
|
|
* gates value rather than coins
|
|
* and other default data
|
|
*/
|
|
export function resetGates() {
|
|
cache.gates = buildDefaults().gates;
|
|
saveState();
|
|
}
|
|
export function resetGate(id) {
|
|
//resets the gate from the config/region config
|
|
cache.gates[id] = REGIONS[id].unlockedAtStart;
|
|
saveState();
|
|
}
|
|
|
|
/**
|
|
* Sets a region's gate to T/F and persists the change.
|
|
* e.g. updateGate("farmland", state) ->
|
|
* cache.gates["farmland"] = state
|
|
*
|
|
* undefined will remove a gate from the cache
|
|
*/
|
|
export function unlockGate(nKey, state) {
|
|
cache.gates[nKey] = state;
|
|
saveState();
|
|
}
|
|
|
|
export function unlockGates() {
|
|
for(const id in REGIONS) {
|
|
cache.gates[id] = true;
|
|
}
|
|
saveState();
|
|
}
|
|
|
|
export function updateBalance(cost) {
|
|
cache.coins += cost;
|
|
saveState();
|
|
}
|
|
|
|
export function returnBalance(){
|
|
const value = cache.coins;
|
|
return value;
|
|
}
|
|
|
|
export function printGateState(){
|
|
log(JSON.stringify(getState().gates));
|
|
}
|
|
|
|
/**
|
|
* Writes the cache out to the world save, where it survives the world closing.
|
|
*
|
|
* Returns early if nothing has been loaded yet - writing a null cache would
|
|
* store the text "null" and corrupt the save.
|
|
*
|
|
* Objects are not a permitted dynamic property value (only boolean, number,
|
|
* string and Vector3), so the document is converted to JSON text first.
|
|
*/
|
|
export function saveState() {
|
|
if(cache === null) return;
|
|
const text = JSON.stringify(cache);
|
|
world.setDynamicProperty(KEY, text);
|
|
} |