Files
bansonic_beta_main/Assets/scripts/_runtimecache/StoreExpBottlePurchaseService.cs
T

304 lines
9.5 KiB
C#

using System.Text;
using UnityEngine;
public static class StoreExpBottlePurchaseService
{
private enum ConsumableGrantType
{
None,
ExpBottle,
GrowthMaterial
}
public static bool TryPurchase(Player_SO playerData, storeItemSO itemSO, int packageCount, out string failureMessage, out int grantedCount)
{
failureMessage = string.Empty;
grantedCount = 0;
if (playerData == null)
{
failureMessage = "玩家数据丢失";
return false;
}
if (itemSO == null)
{
failureMessage = "商品数据丢失";
return false;
}
if (!itemSO.isOnShelf || !itemSO.canbepurchased)
{
failureMessage = "物品未上架";
return false;
}
if (packageCount <= 0)
{
failureMessage = "本店禁止无实物交易";
return false;
}
if (RequiresSinglePurchase(itemSO) && packageCount > 1)
{
failureMessage = "该物品仅支持单份购买";
return false;
}
if (itemSO.costRequirements == null || itemSO.costRequirements.Count == 0)
{
failureMessage = "不可购买";
return false;
}
var primaryCost = itemSO.costRequirements[0];
if (primaryCost.currencyType != storeItemSO.CurrencyType.coins)
{
failureMessage = "不可购买";
return false;
}
long longGrantedCount = (long)Mathf.Max(1, itemSO.itemSinglePurchaseQty) * packageCount;
if (longGrantedCount > int.MaxValue)
{
failureMessage = "达到单次购买限额";
return false;
}
grantedCount = (int)longGrantedCount;
if (itemSO.itemPurchaseQuota >= 0 && itemSO.purchasedCount + grantedCount > itemSO.itemPurchaseQuota)
{
failureMessage = "超过限购额度";
return false;
}
long totalCostLong = (long)primaryCost.amount * packageCount;
if (totalCostLong > int.MaxValue)
{
failureMessage = "达到单次购买限额";
return false;
}
int totalCost = (int)totalCostLong;
if (!ValidateGrantTarget(itemSO, out failureMessage))
{
return false;
}
PlayerEconomyLedger.EnsureInstance().AttachPlayerData(playerData);
StoreOwnershipLedger.EnsureInstance().InitializeIfNeeded();
if (!PlayerEconomyLedger.EnsureInstance().HasEnoughCoins(totalCost))
{
failureMessage = "货币不足";
return false;
}
if (!PlayerEconomyLedger.EnsureInstance().TrySpendCoins(totalCost))
{
failureMessage = "货币不足";
return false;
}
if (!GrantPurchasedItem(playerData, itemSO, grantedCount, out failureMessage))
{
PlayerEconomyLedger.EnsureInstance().AddCoins(totalCost);
return false;
}
DebugPurchaseSuccess(itemSO, totalCost, grantedCount);
return true;
}
private static bool RequiresSinglePurchase(storeItemSO itemSO)
{
if (itemSO == null)
{
return false;
}
return itemSO.itemType == storeItemSO.ItemType.character
|| itemSO.itemType == storeItemSO.ItemType.song
|| itemSO.itemType == storeItemSO.ItemType.storyPassage;
}
private static bool ValidateGrantTarget(storeItemSO itemSO, out string failureMessage)
{
failureMessage = string.Empty;
if (itemSO == null)
{
failureMessage = "商品数据丢失";
return false;
}
switch (itemSO.itemType)
{
case storeItemSO.ItemType.consumable:
ConsumableGrantType grantType;
ExpBottleKind bottleKind;
DushMaterialKind materialKind;
if (!TryResolveConsumableGrant(itemSO, out grantType, out bottleKind, out materialKind))
{
failureMessage = "当前未配置发放逻辑";
return false;
}
return true;
case storeItemSO.ItemType.character:
case storeItemSO.ItemType.song:
case storeItemSO.ItemType.storyPassage:
return StoreOwnershipLedger.EnsureInstance().TryGrantOwnershipPreview(itemSO, out failureMessage);
default:
failureMessage = "当前未配置发放逻辑";
return false;
}
}
private static bool GrantPurchasedItem(Player_SO playerData, storeItemSO itemSO, int grantedCount, out string failureMessage)
{
failureMessage = string.Empty;
if (itemSO == null)
{
failureMessage = "商品数据丢失";
return false;
}
switch (itemSO.itemType)
{
case storeItemSO.ItemType.consumable:
ConsumableGrantType grantType;
ExpBottleKind bottleKind;
DushMaterialKind materialKind;
if (!TryResolveConsumableGrant(itemSO, out grantType, out bottleKind, out materialKind))
{
failureMessage = "当前未配置发放逻辑";
return false;
}
if (grantType == ConsumableGrantType.ExpBottle)
{
ExpBottleLedger.EnsureInstance().AttachPlayerData(playerData);
ExpBottleLedger.EnsureInstance().Add(bottleKind, grantedCount);
return true;
}
if (grantType == ConsumableGrantType.GrowthMaterial)
{
DushMaterialLedger.EnsureInstance().AttachPlayerData(playerData);
DushMaterialLedger.EnsureInstance().Add(materialKind, grantedCount);
return true;
}
failureMessage = "当前未配置发放逻辑";
return false;
case storeItemSO.ItemType.character:
case storeItemSO.ItemType.song:
case storeItemSO.ItemType.storyPassage:
return StoreOwnershipLedger.EnsureInstance().TryGrantOwnership(itemSO, out failureMessage);
default:
failureMessage = "当前未配置发放逻辑";
return false;
}
}
private static void DebugPurchaseSuccess(storeItemSO itemSO, int totalCost, int grantedCount)
{
var builder = new StringBuilder();
builder.Append("[StorePurchase] 已成功购买:");
builder.Append(itemSO != null ? itemSO.itemName : "未知物品");
builder.Append(" | 花费Coins=");
builder.Append(totalCost);
builder.Append(" | 发放数量=");
builder.Append(grantedCount);
if (itemSO != null && itemSO.itemType != storeItemSO.ItemType.consumable)
{
builder.Append(" | 已写入OwnershipSave");
Debug.Log(builder.ToString());
return;
}
ConsumableGrantType grantType;
ExpBottleKind bottleKind;
DushMaterialKind materialKind;
if (!TryResolveConsumableGrant(itemSO, out grantType, out bottleKind, out materialKind))
{
Debug.Log(builder.ToString());
return;
}
if (grantType == ConsumableGrantType.GrowthMaterial)
{
builder.Append(" | 突破材料库存=");
builder.Append(DushMaterialCatalog.GetDisplayName(materialKind));
builder.Append(":");
builder.Append(DushMaterialLedger.EnsureInstance().GetCount(materialKind));
Debug.Log(builder.ToString());
return;
}
var snapshot = ExpBottleLedger.EnsureInstance().GetSnapshot();
builder.Append(" | 经验瓶库存:");
bool appendedAny = false;
for (int i = 0; i < snapshot.Count; i++)
{
var entry = snapshot[i];
ExpBottleKind kind;
if (!ExpBottleCatalog.TryGetKind(entry.key, out kind))
{
continue;
}
if (appendedAny)
{
builder.Append(" ; ");
}
builder.Append(ExpBottleCatalog.GetDisplayName(kind));
builder.Append("=");
builder.Append(entry.count);
appendedAny = true;
}
Debug.Log(builder.ToString());
}
private static bool TryResolveConsumableGrant(storeItemSO itemSO, out ConsumableGrantType grantType, out ExpBottleKind bottleKind, out DushMaterialKind materialKind)
{
grantType = ConsumableGrantType.None;
bottleKind = default(ExpBottleKind);
materialKind = default(DushMaterialKind);
if (itemSO == null)
{
return false;
}
if (itemSO.associatedExpBottle != null)
{
grantType = ConsumableGrantType.ExpBottle;
bottleKind = itemSO.associatedExpBottle.bottleKind;
return true;
}
if (itemSO.associatedGrowthMaterial != null)
{
grantType = ConsumableGrantType.GrowthMaterial;
materialKind = itemSO.associatedGrowthMaterial.materialKind;
return true;
}
if (StoreExpBottleGrantResolver.TryResolve(itemSO, out bottleKind))
{
grantType = ConsumableGrantType.ExpBottle;
return true;
}
return false;
}
}