173 lines
3.9 KiB
JavaScript
173 lines
3.9 KiB
JavaScript
/**
|
|
* CurrencyManager.js
|
|
* Manages the single in-game currency: Gold.
|
|
* Simplified from the original multi-currency system (monetization-lite).
|
|
* Provides add/spend/get operations with EventBus notifications,
|
|
* StorageManager persistence, and overflow protection.
|
|
*/
|
|
|
|
/** Maximum gold cap to prevent overflow. */
|
|
const MAX_GOLD = 999999;
|
|
|
|
class CurrencyManager {
|
|
constructor() {
|
|
this._gold = 0;
|
|
this._load();
|
|
}
|
|
|
|
// ============================================================
|
|
// Persistence
|
|
// ============================================================
|
|
|
|
/**
|
|
* Load currency data from StorageManager.
|
|
* @private
|
|
*/
|
|
_load() {
|
|
try {
|
|
if (GameGlobal && GameGlobal.storageManager) {
|
|
const data = GameGlobal.storageManager.get('currency', null);
|
|
if (data) {
|
|
this._gold = data.gold || 0;
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.warn('[CurrencyManager] Failed to load currency data:', e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save currency data to StorageManager.
|
|
* @private
|
|
*/
|
|
_save() {
|
|
try {
|
|
if (GameGlobal && GameGlobal.storageManager) {
|
|
GameGlobal.storageManager.set('currency', {
|
|
gold: this._gold,
|
|
});
|
|
}
|
|
} catch (e) {
|
|
console.warn('[CurrencyManager] Failed to save currency data:', e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Emit a currency change event via EventBus.
|
|
* @private
|
|
*/
|
|
_emitGoldChanged() {
|
|
try {
|
|
if (GameGlobal && GameGlobal.eventBus) {
|
|
GameGlobal.eventBus.emit('currency:gold:changed', this._gold);
|
|
}
|
|
} catch (e) {}
|
|
}
|
|
|
|
// ============================================================
|
|
// Gold
|
|
// ============================================================
|
|
|
|
/**
|
|
* Get current gold amount.
|
|
* @returns {number}
|
|
*/
|
|
getGold() {
|
|
return this._gold;
|
|
}
|
|
|
|
/**
|
|
* Add gold (capped at MAX_GOLD).
|
|
* @param {number} amount - Must be positive.
|
|
* @returns {number} Actual amount added (may be less if capped).
|
|
*/
|
|
addGold(amount) {
|
|
if (amount <= 0) return 0;
|
|
const before = this._gold;
|
|
this._gold = Math.min(this._gold + Math.floor(amount), MAX_GOLD);
|
|
const added = this._gold - before;
|
|
if (added > 0) {
|
|
this._save();
|
|
this._emitGoldChanged();
|
|
}
|
|
return added;
|
|
}
|
|
|
|
/**
|
|
* Spend gold.
|
|
* @param {number} amount - Must be positive.
|
|
* @returns {boolean} True if successful, false if insufficient.
|
|
*/
|
|
spendGold(amount) {
|
|
if (amount <= 0) return true;
|
|
if (this._gold < amount) {
|
|
// Emit insufficient event for UI to handle
|
|
try {
|
|
if (GameGlobal && GameGlobal.eventBus) {
|
|
GameGlobal.eventBus.emit('currency:gold:insufficient', { required: amount, current: this._gold });
|
|
}
|
|
} catch (e) {}
|
|
return false;
|
|
}
|
|
this._gold -= Math.floor(amount);
|
|
this._save();
|
|
this._emitGoldChanged();
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check if player has enough gold.
|
|
* @param {number} amount
|
|
* @returns {boolean}
|
|
*/
|
|
hasGold(amount) {
|
|
return this._gold >= amount;
|
|
}
|
|
|
|
/**
|
|
* Check if gold is at maximum cap.
|
|
* @returns {boolean}
|
|
*/
|
|
isGoldFull() {
|
|
return this._gold >= MAX_GOLD;
|
|
}
|
|
|
|
/**
|
|
* Get the maximum gold cap.
|
|
* @returns {number}
|
|
*/
|
|
getMaxGold() {
|
|
return MAX_GOLD;
|
|
}
|
|
|
|
// ============================================================
|
|
// Cloud Sync
|
|
// ============================================================
|
|
|
|
/**
|
|
* Get currency data for cloud sync.
|
|
* @returns {object}
|
|
*/
|
|
getCloudSyncData() {
|
|
return {
|
|
gold: this._gold,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Restore currency data from cloud (merge: keep higher values).
|
|
* @param {object} cloudData
|
|
*/
|
|
restoreFromCloud(cloudData) {
|
|
if (!cloudData) return;
|
|
|
|
if (cloudData.gold !== undefined && cloudData.gold > this._gold) {
|
|
this._gold = Math.min(cloudData.gold, MAX_GOLD);
|
|
this._save();
|
|
this._emitGoldChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = CurrencyManager;
|