using System; using System.Collections.Generic; using ShiroginSDK.Runtime.Modules.Data.Scripts.Enums; using ShiroginSDK.Runtime.Modules.Events; using ShiroginSDK.Runtime.Services.Base; using ShiroginSDK.Runtime.Services.Interfaces; using UnityEngine; namespace ShiroginSDK.Runtime.Modules.Data.Scripts { /// /// Manages all in-game currencies and economy statistics. /// Handles earning, spending, and analytics updates for currency-related events. /// [Serializable] public class EconomyData : BaseData { // ---- Currencies ---- public int Gold; public int Gems; public int RewardedTicket; public int Keys; public int Energy; public int Hearts; // ---- Economy Stats ---- public long TotalGoldEarned; public long TotalGoldSpent; public int TotalAdsWatched; public int TotalPurchases; // Cached service reference private IEventService _eventService; public EconomyData() { _eventService = ServiceLocator.Get(); } protected override string PrefsKey => "ECONOMY_DATA"; // ---- Currency Accessors ---- public int GetCurrency(CurrencyType type) { return type switch { CurrencyType.Gold => Gold, CurrencyType.Gems => Gems, CurrencyType.RewardedTicket => RewardedTicket, CurrencyType.Keys => Keys, CurrencyType.Energy => Energy, CurrencyType.Hearts => Hearts, _ => 0 }; } // ---- Reward Granting ---- public void GrantReward(CurrencyType type, int amount) { if (amount <= 0) return; var oldValue = GetCurrency(type); AddCurrency(type, amount); var newValue = GetCurrency(type); // 🔔 Event dispatch _eventService?.Invoke(new ShiroginEvents.Economy.CurrencyChangedEvent(type, oldValue, newValue)); Debug.Log($"[EconomyData] {type} +{amount} granted (old: {oldValue}, new: {newValue})"); } public void GrantReward(CurrencyType type, int amount, string source = "unknown") { if (amount <= 0) return; var oldValue = GetCurrency(type); AddCurrency(type, amount); var newValue = GetCurrency(type); // 🔔 Event dispatch _eventService?.Invoke(new ShiroginEvents.Economy.CurrencyChangedEvent(type, oldValue, newValue)); _eventService?.Invoke(new ShiroginEvents.Rewards.RewardClaimedEvent(type.ToString(), source)); // 📊 Analytics tracking if (source == "iap" || source == "bundle") AddPurchase(); else if (source == "ad") AddAdWatch(); Debug.Log($"[EconomyData] +{amount} {type} granted from [{source}] → new total: {newValue}"); } // ---- Currency Management ---- public void SetCurrency(CurrencyType type, int value) { value = Mathf.Max(0, value); switch (type) { case CurrencyType.Gold: Gold = value; break; case CurrencyType.Gems: Gems = value; break; case CurrencyType.RewardedTicket: RewardedTicket = value; break; case CurrencyType.Keys: Keys = value; break; case CurrencyType.Energy: Energy = value; break; case CurrencyType.Hearts: Hearts = value; break; } Save(); } public void AddCurrency(CurrencyType type, int amount) { if (amount <= 0) return; switch (type) { case CurrencyType.Gold: Gold += amount; TotalGoldEarned += amount; break; case CurrencyType.Gems: Gems += amount; break; case CurrencyType.RewardedTicket: RewardedTicket += amount; break; case CurrencyType.Keys: Keys += amount; break; case CurrencyType.Energy: Energy += amount; break; case CurrencyType.Hearts: Hearts += amount; break; } Save(); } public bool HasEnough(CurrencyType type, int amount) { if (amount <= 0) return true; return GetCurrency(type) >= amount; } public bool SpendCurrency(CurrencyType type, int amount) { if (!HasEnough(type, amount)) return false; switch (type) { case CurrencyType.Gold: Gold -= amount; TotalGoldSpent += amount; break; case CurrencyType.Gems: Gems -= amount; break; case CurrencyType.RewardedTicket: RewardedTicket -= amount; break; case CurrencyType.Keys: Keys -= amount; break; case CurrencyType.Energy: Energy -= amount; break; case CurrencyType.Hearts: Hearts -= amount; break; } Save(); return true; } // ---- Multi-Currency Purchase ---- public bool TryMultiPurchase(Dictionary cost, Action onSuccess = null, Action onFail = null) { foreach (var kv in cost) if (!HasEnough(kv.Key, kv.Value)) { onFail?.Invoke(); return false; } foreach (var kv in cost) SpendCurrency(kv.Key, kv.Value); onSuccess?.Invoke(); return true; } public bool TryPurchase(int price, CurrencyType currency, Action onSuccess = null, Action onFail = null) { if (SpendCurrency(currency, price)) { onSuccess?.Invoke(); return true; } onFail?.Invoke(); return false; } // ---- Analytics Tracking ---- public void AddAdWatch() { TotalAdsWatched++; Save(); } public void AddPurchase() { TotalPurchases++; Save(); } } }