Playvoi/Assets/ShiroginSDK/Runtime/Modules/IAP/Scripts/SO/StoreItem.cs

284 lines
No EOL
9.4 KiB
C#

using System.Collections.Generic;
using ShiroginSDK.Runtime.Modules.Data.Scripts;
using ShiroginSDK.Runtime.Modules.Data.Scripts.Enums;
using ShiroginSDK.Runtime.Modules.Events;
using ShiroginSDK.Runtime.Modules.IAP.Enums;
using ShiroginSDK.Runtime.Modules.IAP.Scripts.Definitions;
using ShiroginSDK.Runtime.Services.Base;
using ShiroginSDK.Runtime.Services.Interfaces;
using UnityEngine;
#if SHIROGIN_IAP
using UnityEngine.Purchasing;
#endif
namespace ShiroginSDK.Runtime.Modules.IAP.Scripts.SO
{
#if SHIROGIN_IAP
[CreateAssetMenu(fileName = "StoreItem", menuName = "ShiroginSDK/IAP/Store Item", order = 1)]
public class StoreItem : ScriptableObject
{
[Header("🧾 Product Info")]
public string productId;
public ProductType productType = ProductType.Consumable;
public StoreCategory category = StoreCategory.UnknownPacks;
public StoreItemLayoutType layoutType = StoreItemLayoutType.Default;
[Header("📋 Display Info")]
public string displayName;
[TextArea] public string description;
public Sprite icon;
[Header("💰 Purchase Settings")]
public bool useCurrency;
public CurrencyType currencyType = CurrencyType.Gems;
public int price;
public bool canBeRewardedAd;
[Header("🎁 Reward Settings")]
public List<RewardDefinition> rewards = new();
public float adCooldownSeconds = 60f;
public bool IsIAP => !useCurrency && !canBeRewardedAd;
public bool IsCurrencyPurchase => useCurrency && price > 0;
public bool IsRewardedAd => canBeRewardedAd;
public void GiveReward(string source = "store")
{
foreach (var reward in rewards)
{
if (reward == null) continue;
reward.Give();
}
var dataService = ServiceLocator.Get<IDataService>();
var economy = dataService?.Get<EconomyData>();
economy?.AddPurchase();
var eventService = ServiceLocator.Get<IEventService>();
eventService?.Invoke(new ShiroginEvents.Rewards.RewardGivenEvent(this));
Debug.Log($"[StoreItem] Rewards granted for '{productId}' via {source}");
}
public void GiveRandomReward(int rewardCount = 3, string source = "store")
{
if (rewards == null || rewards.Count == 0)
{
Debug.LogWarning("[StoreItem] No rewards available.");
return;
}
rewardCount = Mathf.Clamp(rewardCount, 1, rewards.Count);
var randomRewards = new List<RewardDefinition>();
var availableRewards = new List<RewardDefinition>(rewards);
for (var i = 0; i < rewardCount; i++)
{
if (availableRewards.Count == 0) break;
var randomIndex = Random.Range(0, availableRewards.Count);
var selected = availableRewards[randomIndex];
if (selected != null)
{
selected.Give();
randomRewards.Add(selected);
}
availableRewards.RemoveAt(randomIndex);
}
var dataService = ServiceLocator.Get<IDataService>();
var economy = dataService?.Get<EconomyData>();
economy?.AddPurchase();
var eventService = ServiceLocator.Get<IEventService>();
eventService?.Invoke(new ShiroginEvents.Rewards.RewardGivenEvent(this));
eventService?.Invoke(new ShiroginEvents.Shop.Shop_UIStoreItem_Rewarded(randomRewards));
Debug.Log($"[StoreItem] {rewardCount} random rewards granted for '{productId}' via {source}");
foreach (var randomReward in randomRewards)
Debug.Log($"[ehm] Given random reward: {randomReward.rewardType}");
}
public List<RewardDefinition> GetRewards()
{
return rewards;
}
public string GetDisplayPrice()
{
if (IsIAP)
return "REAL MONEY";
if (IsCurrencyPurchase)
return $"{price} {currencyType.ToString().ToUpper()}";
if (IsRewardedAd)
return "WATCH AD";
return "FREE";
}
public bool TryPurchaseWithCurrency()
{
if (!IsCurrencyPurchase) return false;
var dataService = ServiceLocator.Get<IDataService>();
var economy = dataService?.Get<EconomyData>();
if (economy == null)
{
Debug.LogError("[StoreItem] EconomyData not available.");
return false;
}
if (!economy.HasEnough(currencyType, price))
{
Debug.LogWarning($"[StoreItem] Not enough {currencyType} to buy '{displayName}'.");
return false;
}
economy.SpendCurrency(currencyType, price);
GiveReward("currency");
return true;
}
}
#else
[CreateAssetMenu(fileName = "StoreItem", menuName = "ShiroginSDK/IAP/Store Item", order = 1)]
public class StoreItem : ScriptableObject
{
[Header("🧾 Product Info")]
public string productId;
public DummyProductType productType = DummyProductType.Consumable;
public StoreCategory category = StoreCategory.UnknownPacks;
public StoreItemLayoutType layoutType = StoreItemLayoutType.Default;
[Header("📋 Display Info")]
public string displayName;
[TextArea] public string description;
public Sprite icon;
[Header("💰 Purchase Settings")]
public bool useCurrency;
public CurrencyType currencyType = CurrencyType.Gems;
public int price;
public bool canBeRewardedAd;
[Header("🎁 Reward Settings")]
public List<RewardDefinition> rewards = new();
public float adCooldownSeconds = 60f;
public bool IsIAP => !useCurrency && !canBeRewardedAd;
public bool IsCurrencyPurchase => useCurrency && price > 0;
public bool IsRewardedAd => canBeRewardedAd;
public void GiveReward(string source = "store")
{
foreach (var reward in rewards)
{
if (reward == null) continue;
reward.Give();
}
var dataService = ServiceLocator.Get<IDataService>();
var economy = dataService?.Get<EconomyData>();
economy?.AddPurchase();
var eventService = ServiceLocator.Get<IEventService>();
eventService?.Invoke(new ShiroginEvents.Rewards.RewardGivenEvent(this));
Debug.Log($"[StoreItem] Rewards granted for '{productId}' via {source}");
}
public void GiveRandomReward(int rewardCount = 3, string source = "store")
{
if (rewards == null || rewards.Count == 0)
{
Debug.LogWarning("[StoreItem] No rewards available.");
return;
}
rewardCount = Mathf.Clamp(rewardCount, 1, rewards.Count);
var randomRewards = new List<RewardDefinition>();
var availableRewards = new List<RewardDefinition>(rewards);
for (var i = 0; i < rewardCount; i++)
{
if (availableRewards.Count == 0) break;
var randomIndex = Random.Range(0, availableRewards.Count);
var selected = availableRewards[randomIndex];
if (selected != null)
{
selected.Give();
randomRewards.Add(selected);
}
availableRewards.RemoveAt(randomIndex);
}
var dataService = ServiceLocator.Get<IDataService>();
var economy = dataService?.Get<EconomyData>();
economy?.AddPurchase();
var eventService = ServiceLocator.Get<IEventService>();
eventService?.Invoke(new ShiroginEvents.Rewards.RewardGivenEvent(this));
eventService?.Invoke(new ShiroginEvents.Shop.Shop_UIStoreItem_Rewarded(randomRewards));
Debug.Log($"[StoreItem] {rewardCount} random rewards granted for '{productId}' via {source}");
foreach (var randomReward in randomRewards)
Debug.Log($"[ehm] Given random reward: {randomReward.rewardType}");
}
public List<RewardDefinition> GetRewards()
{
return rewards;
}
public string GetDisplayPrice()
{
if (IsIAP)
return "REAL MONEY";
if (IsCurrencyPurchase)
return $"{price} {currencyType.ToString().ToUpper()}";
if (IsRewardedAd)
return "WATCH AD";
return "FREE";
}
public bool TryPurchaseWithCurrency()
{
if (!IsCurrencyPurchase) return false;
var dataService = ServiceLocator.Get<IDataService>();
var economy = dataService?.Get<EconomyData>();
if (economy == null)
{
Debug.LogError("[StoreItem] EconomyData not available.");
return false;
}
if (!economy.HasEnough(currencyType, price))
{
Debug.LogWarning($"[StoreItem] Not enough {currencyType} to buy '{displayName}'.");
return false;
}
economy.SpendCurrency(currencyType, price);
GiveReward("currency");
return true;
}
}
#endif
}