import { REGIONS } from "../config/regions.js" import { getState, updateBalance, unlockGate, returnBalance } from "../save/state.js" /** * Can this region be unlocked right now, and if not, why not? * * Returns an outcome object rather than a boolean so callers can explain the * refusal to the player. `reason` is a code, not display text - whoever shows * it is responsible for turning it into a translated message. * * { ok: true } * { ok: false, reason: "unknown_region" } developer error * { ok: false, reason: "already_unlocked" } * { ok: false, reason: "missing_prior_region", requires: "farmland" } * { ok: false, reason: "insufficient_funds", cost: 500, balance: 120 } * * @param {string} regionID - a REGIONS key, e.g. "farmland" */ export function canUnlock(regionID) { /* the region's whole config record: { nameKey, order, unlockedAtStart, unlockedCost} */ const region = REGIONS[regionID]; if (region === undefined) { return { ok: false, reason: "unknown_region" }; } // order number from the REGIONS section we keyed const order = region.order; // we return the full record. const gates = getState().gates; /* if the records value for that key's order is true: unlocked */ if (gates[regionID] === true) { return { ok: false, reason: "already_unlocked" }; } /* WE ARE KEYING FOR THE KEY VALUE'S ORDER PRIOR TO PASSED REGION{RegionID} the prior value has to be true for the passed region to unlock */ let priorRegion = null; for (const id in REGIONS) { // never pass lagoon otherwise all conditions fail if (REGIONS[id].order === order - 1) { /* again tdlr we get the key prior to the past key so for example command canUnlock("seaside"); we are retrieving farm land for comparison it's sequential you can't unlock zones non out of order */ priorRegion = id; } } // if first region is auto unlocked we will never meet this condition if (priorRegion === null) { return { ok: false, reason: "missing_prior_region", requires: null }; } /* the prior region before this one must be open first */ if (gates[priorRegion] !== true) { return { ok: false, reason: "missing_prior_region", requires: priorRegion }; } //they have to be able to pay for it. const cost = region.unlockedCost; const balance = returnBalance(); if (balance < cost) { return { ok: false, reason: "insufficient_funds", cost: cost, balance: balance }; } return { ok: true }; } /** * Unlocks a region if the rules allow it, charges the cost, and saves. * object canUnlock produced and can explain what went wrong. * * @param {string} regionID - a REGIONS key, e.g. "farmland" */ export function unlockRegion(regionID) { const result = canUnlock(regionID); if (!result.ok) { return result; } unlockGate(regionID, true); /* always make sure things that cost money are passed negative, because otherwise it would add to the balance */ updateBalance(-REGIONS[regionID].unlockedCost); return { ok: true }; }