first commit
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
/**
|
||||
* 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;
|
||||
Reference in New Issue
Block a user