200 lines
No EOL
6.3 KiB
C#
200 lines
No EOL
6.3 KiB
C#
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
|
|
{
|
|
/// <summary>
|
|
/// Manages all in-game currencies and economy statistics.
|
|
/// Handles earning, spending, and analytics updates for currency-related events.
|
|
/// </summary>
|
|
[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<IEventService>();
|
|
}
|
|
|
|
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<CurrencyType, int> 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();
|
|
}
|
|
}
|
|
} |