装备系统做了很多
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public static class EquipmentConsumableCatalog
|
||||
{
|
||||
private static readonly EquipmentConsumableDescriptor[] Descriptors =
|
||||
{
|
||||
new EquipmentConsumableDescriptor(EquipmentConsumableKind.Material78101, "eqc_78101", "装备升级材料78101"),
|
||||
new EquipmentConsumableDescriptor(EquipmentConsumableKind.Material78111, "eqc_78111", "装备突破材料78111")
|
||||
};
|
||||
|
||||
private static readonly Dictionary<EquipmentConsumableKind, EquipmentConsumableDescriptor> ByKind = BuildByKind();
|
||||
private static readonly Dictionary<string, EquipmentConsumableDescriptor> ByKey = BuildByKey();
|
||||
|
||||
public static IReadOnlyList<EquipmentConsumableDescriptor> All => Descriptors;
|
||||
|
||||
public static string GetKey(EquipmentConsumableKind kind)
|
||||
{
|
||||
return ByKind[kind].Key;
|
||||
}
|
||||
|
||||
public static string GetDisplayName(EquipmentConsumableKind kind)
|
||||
{
|
||||
return ByKind[kind].DisplayName;
|
||||
}
|
||||
|
||||
public static bool TryGetKind(string key, out EquipmentConsumableKind kind)
|
||||
{
|
||||
kind = default;
|
||||
if (string.IsNullOrEmpty(key))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ByKey.TryGetValue(key, out EquipmentConsumableDescriptor descriptor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
kind = descriptor.Kind;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Dictionary<EquipmentConsumableKind, EquipmentConsumableDescriptor> BuildByKind()
|
||||
{
|
||||
var map = new Dictionary<EquipmentConsumableKind, EquipmentConsumableDescriptor>();
|
||||
for (int i = 0; i < Descriptors.Length; i++)
|
||||
{
|
||||
map[Descriptors[i].Kind] = Descriptors[i];
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
private static Dictionary<string, EquipmentConsumableDescriptor> BuildByKey()
|
||||
{
|
||||
var map = new Dictionary<string, EquipmentConsumableDescriptor>(StringComparer.Ordinal);
|
||||
for (int i = 0; i < Descriptors.Length; i++)
|
||||
{
|
||||
map[Descriptors[i].Key] = Descriptors[i];
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class EquipmentConsumableDescriptor
|
||||
{
|
||||
public EquipmentConsumableDescriptor(EquipmentConsumableKind kind, string key, string displayName)
|
||||
{
|
||||
Kind = kind;
|
||||
Key = key;
|
||||
DisplayName = displayName;
|
||||
}
|
||||
|
||||
public EquipmentConsumableKind Kind { get; }
|
||||
public string Key { get; }
|
||||
public string DisplayName { get; }
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0fc8afc632ac0b94685b585bfdc387d9
|
||||
@@ -0,0 +1,5 @@
|
||||
public enum EquipmentConsumableKind
|
||||
{
|
||||
Material78101,
|
||||
Material78111
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b2eb15fea2aeb9141873f6e710224887
|
||||
@@ -0,0 +1,252 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public sealed class EquipmentConsumableLedger : MonoBehaviour
|
||||
{
|
||||
public static EquipmentConsumableLedger Instance { get; private set; }
|
||||
|
||||
public event Action<EquipmentConsumableKind, int> OnCountChanged;
|
||||
|
||||
private readonly Dictionary<string, int> countsByKey = new Dictionary<string, int>(StringComparer.Ordinal);
|
||||
private bool initialized;
|
||||
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||
private static void Bootstrap()
|
||||
{
|
||||
EnsureInstance();
|
||||
}
|
||||
|
||||
public static EquipmentConsumableLedger EnsureInstance()
|
||||
{
|
||||
if (Instance != null)
|
||||
{
|
||||
return Instance;
|
||||
}
|
||||
|
||||
var host = new GameObject("__runtime_equipment_consumable_bridge");
|
||||
host.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector;
|
||||
DontDestroyOnLoad(host);
|
||||
Instance = host.AddComponent<EquipmentConsumableLedger>();
|
||||
return Instance;
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
|
||||
Instance = this;
|
||||
DontDestroyOnLoad(gameObject);
|
||||
InitializeIfNeeded();
|
||||
}
|
||||
|
||||
private void OnApplicationPause(bool pauseStatus)
|
||||
{
|
||||
if (pauseStatus)
|
||||
{
|
||||
SaveNow();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnApplicationQuit()
|
||||
{
|
||||
SaveNow();
|
||||
}
|
||||
|
||||
public void InitializeIfNeeded()
|
||||
{
|
||||
if (initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EquipmentConsumableLedgerPayload payload;
|
||||
EquipmentConsumableLedgerStorage.TryLoad(out payload);
|
||||
RebuildFromPayload(payload);
|
||||
initialized = true;
|
||||
SyncMirrorCounts();
|
||||
SaveNow();
|
||||
}
|
||||
|
||||
public int GetCount(EquipmentConsumableKind kind)
|
||||
{
|
||||
return GetCountByKey(EquipmentConsumableCatalog.GetKey(kind));
|
||||
}
|
||||
|
||||
public void Add(EquipmentConsumableKind kind, int amount)
|
||||
{
|
||||
if (amount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ChangeCount(EquipmentConsumableCatalog.GetKey(kind), amount);
|
||||
}
|
||||
|
||||
public bool TryConsume(EquipmentConsumableKind kind, int amount)
|
||||
{
|
||||
if (amount <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string key = EquipmentConsumableCatalog.GetKey(kind);
|
||||
int current = GetCountByKey(key);
|
||||
if (current < amount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ChangeCount(key, -amount);
|
||||
DailyTaskEventHub.ReportUseItem(amount);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ResetAllToZero()
|
||||
{
|
||||
InitializeIfNeeded();
|
||||
|
||||
for (int i = 0; i < EquipmentConsumableCatalog.All.Count; i++)
|
||||
{
|
||||
countsByKey[EquipmentConsumableCatalog.All[i].Key] = 0;
|
||||
}
|
||||
|
||||
SaveNow();
|
||||
NotifyAllCountsChanged();
|
||||
}
|
||||
|
||||
public void SaveNow()
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
InitializeIfNeeded();
|
||||
}
|
||||
|
||||
SyncMirrorCounts();
|
||||
EquipmentConsumableLedgerStorage.TrySave(BuildPayload());
|
||||
}
|
||||
|
||||
private void SyncMirrorCounts()
|
||||
{
|
||||
equipmentConsumableSO[] definitions = Resources.FindObjectsOfTypeAll<equipmentConsumableSO>();
|
||||
for (int i = 0; i < definitions.Length; i++)
|
||||
{
|
||||
equipmentConsumableSO definition = definitions[i];
|
||||
if (definition == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
definition.runtimeOwnedCount = GetCount(definition.consumableKind);
|
||||
}
|
||||
}
|
||||
|
||||
private int GetCountByKey(string key)
|
||||
{
|
||||
InitializeIfNeeded();
|
||||
|
||||
if (!countsByKey.TryGetValue(key, out int count))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
private void ChangeCount(string key, int delta)
|
||||
{
|
||||
InitializeIfNeeded();
|
||||
|
||||
int current = GetCountByKey(key);
|
||||
long next = (long)current + delta;
|
||||
if (next < 0)
|
||||
{
|
||||
next = 0;
|
||||
}
|
||||
else if (next > int.MaxValue)
|
||||
{
|
||||
next = int.MaxValue;
|
||||
}
|
||||
|
||||
SetCountByKey(key, (int)next);
|
||||
}
|
||||
|
||||
private void SetCountByKey(string key, int value)
|
||||
{
|
||||
int safeValue = Mathf.Max(0, value);
|
||||
int current = GetCountByKey(key);
|
||||
if (current == safeValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
countsByKey[key] = safeValue;
|
||||
SaveNow();
|
||||
|
||||
if (EquipmentConsumableCatalog.TryGetKind(key, out EquipmentConsumableKind kind) && OnCountChanged != null)
|
||||
{
|
||||
OnCountChanged(kind, safeValue);
|
||||
}
|
||||
}
|
||||
|
||||
private void RebuildFromPayload(EquipmentConsumableLedgerPayload payload)
|
||||
{
|
||||
countsByKey.Clear();
|
||||
for (int i = 0; i < EquipmentConsumableCatalog.All.Count; i++)
|
||||
{
|
||||
countsByKey[EquipmentConsumableCatalog.All[i].Key] = 0;
|
||||
}
|
||||
|
||||
if (payload == null || payload.entries == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < payload.entries.Count; i++)
|
||||
{
|
||||
var entry = payload.entries[i];
|
||||
if (entry == null || string.IsNullOrEmpty(entry.key))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
countsByKey[entry.key] = Mathf.Max(0, entry.count);
|
||||
}
|
||||
}
|
||||
|
||||
private EquipmentConsumableLedgerPayload BuildPayload()
|
||||
{
|
||||
var payload = EquipmentConsumableLedgerStorage.CreateDefaultPayload();
|
||||
payload.entries.Clear();
|
||||
|
||||
for (int i = 0; i < EquipmentConsumableCatalog.All.Count; i++)
|
||||
{
|
||||
var descriptor = EquipmentConsumableCatalog.All[i];
|
||||
payload.entries.Add(new EquipmentConsumableEntry
|
||||
{
|
||||
key = descriptor.Key,
|
||||
count = GetCountByKey(descriptor.Key)
|
||||
});
|
||||
}
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
private void NotifyAllCountsChanged()
|
||||
{
|
||||
if (OnCountChanged == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < EquipmentConsumableCatalog.All.Count; i++)
|
||||
{
|
||||
var descriptor = EquipmentConsumableCatalog.All[i];
|
||||
OnCountChanged(descriptor.Kind, GetCountByKey(descriptor.Key));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 164e32ce0a98c6840943dda5f15d02a8
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
[Serializable]
|
||||
public class EquipmentConsumableEntry
|
||||
{
|
||||
public string key;
|
||||
public int count;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class EquipmentConsumableLedgerPayload
|
||||
{
|
||||
public int version = 1;
|
||||
public long lastUpdatedUtcTicks;
|
||||
public List<EquipmentConsumableEntry> entries = new List<EquipmentConsumableEntry>();
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class EquipmentConsumableLedgerEnvelope
|
||||
{
|
||||
public string payload;
|
||||
public string signature;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e5c6f1d972017041a0a3f4c7c44723f
|
||||
@@ -0,0 +1,187 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
public static class EquipmentConsumableLedgerStorage
|
||||
{
|
||||
private const string SecretSeed = "ban_total.equipment_consumable_ledger.v1";
|
||||
private const string VaultDirectoryName = ".cache_bridge";
|
||||
private const string MainFileName = ".eqc.dat";
|
||||
private const string BackupFileName = ".eqc.bak";
|
||||
private const string TempFileName = ".eqc.tmp";
|
||||
|
||||
private static string VaultDirectoryPath => Path.Combine(Application.persistentDataPath, VaultDirectoryName);
|
||||
private static string MainFilePath => Path.Combine(VaultDirectoryPath, MainFileName);
|
||||
private static string BackupFilePath => Path.Combine(VaultDirectoryPath, BackupFileName);
|
||||
private static string TempFilePath => Path.Combine(VaultDirectoryPath, TempFileName);
|
||||
|
||||
public static bool TryLoad(out EquipmentConsumableLedgerPayload payload)
|
||||
{
|
||||
payload = CreateDefaultPayload();
|
||||
|
||||
if (TryReadPayload(MainFilePath, out payload))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (TryReadPayload(BackupFilePath, out payload))
|
||||
{
|
||||
TrySave(payload);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TrySave(EquipmentConsumableLedgerPayload payload)
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(VaultDirectoryPath);
|
||||
TryHidePath(VaultDirectoryPath);
|
||||
|
||||
var envelopeJson = BuildEnvelopeJson(payload);
|
||||
File.WriteAllText(TempFilePath, envelopeJson, Encoding.UTF8);
|
||||
TryHidePath(TempFilePath);
|
||||
|
||||
if (File.Exists(MainFilePath))
|
||||
{
|
||||
File.Copy(MainFilePath, BackupFilePath, true);
|
||||
TryHidePath(BackupFilePath);
|
||||
}
|
||||
|
||||
File.Copy(TempFilePath, MainFilePath, true);
|
||||
TryHidePath(MainFilePath);
|
||||
File.Delete(TempFilePath);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[EquipmentConsumableLedgerStorage] Save failed: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static EquipmentConsumableLedgerPayload CreateDefaultPayload()
|
||||
{
|
||||
return new EquipmentConsumableLedgerPayload
|
||||
{
|
||||
version = 1,
|
||||
lastUpdatedUtcTicks = DateTime.UtcNow.Ticks,
|
||||
entries = new System.Collections.Generic.List<EquipmentConsumableEntry>()
|
||||
};
|
||||
}
|
||||
|
||||
private static bool TryReadPayload(string path, out EquipmentConsumableLedgerPayload payload)
|
||||
{
|
||||
payload = CreateDefaultPayload();
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var envelopeJson = File.ReadAllText(path, Encoding.UTF8);
|
||||
var envelope = JsonUtility.FromJson<EquipmentConsumableLedgerEnvelope>(envelopeJson);
|
||||
if (envelope == null || string.IsNullOrEmpty(envelope.payload) || string.IsNullOrEmpty(envelope.signature))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var expectedSignature = ComputeSignature(envelope.payload);
|
||||
if (!string.Equals(expectedSignature, envelope.signature, StringComparison.Ordinal))
|
||||
{
|
||||
Debug.LogWarning("[EquipmentConsumableLedgerStorage] Save signature mismatch. Possible tampering detected.");
|
||||
return false;
|
||||
}
|
||||
|
||||
var encryptedBytes = Convert.FromBase64String(envelope.payload);
|
||||
var plainBytes = XorTransform(encryptedBytes, BuildKeyBytes());
|
||||
var payloadJson = Encoding.UTF8.GetString(plainBytes);
|
||||
var loadedPayload = JsonUtility.FromJson<EquipmentConsumableLedgerPayload>(payloadJson);
|
||||
if (loadedPayload == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
payload = loadedPayload;
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[EquipmentConsumableLedgerStorage] Load failed from '{path}': {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static string BuildEnvelopeJson(EquipmentConsumableLedgerPayload payload)
|
||||
{
|
||||
payload.lastUpdatedUtcTicks = DateTime.UtcNow.Ticks;
|
||||
var payloadJson = JsonUtility.ToJson(payload, false);
|
||||
var plainBytes = Encoding.UTF8.GetBytes(payloadJson);
|
||||
var encryptedBytes = XorTransform(plainBytes, BuildKeyBytes());
|
||||
var payloadBase64 = Convert.ToBase64String(encryptedBytes);
|
||||
|
||||
var envelope = new EquipmentConsumableLedgerEnvelope
|
||||
{
|
||||
payload = payloadBase64,
|
||||
signature = ComputeSignature(payloadBase64)
|
||||
};
|
||||
|
||||
return JsonUtility.ToJson(envelope, false);
|
||||
}
|
||||
|
||||
private static string ComputeSignature(string payloadBase64)
|
||||
{
|
||||
var signText = payloadBase64 + "|" + Application.identifier + "|" + SecretSeed + "|" + SystemInfo.deviceUniqueIdentifier;
|
||||
using (var sha = SHA256.Create())
|
||||
{
|
||||
var bytes = Encoding.UTF8.GetBytes(signText);
|
||||
var hash = sha.ComputeHash(bytes);
|
||||
return Convert.ToBase64String(hash);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] BuildKeyBytes()
|
||||
{
|
||||
using (var sha = SHA256.Create())
|
||||
{
|
||||
var seed = Application.identifier + "|" + SystemInfo.deviceUniqueIdentifier + "|" + SecretSeed;
|
||||
return sha.ComputeHash(Encoding.UTF8.GetBytes(seed));
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] XorTransform(byte[] source, byte[] key)
|
||||
{
|
||||
var result = new byte[source.Length];
|
||||
for (int i = 0; i < source.Length; i++)
|
||||
{
|
||||
result[i] = (byte)(source[i] ^ key[i % key.Length]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void TryHidePath(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Application.platform != RuntimePlatform.WindowsEditor && Application.platform != RuntimePlatform.WindowsPlayer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var attributes = File.GetAttributes(path);
|
||||
if ((attributes & FileAttributes.Hidden) == 0)
|
||||
{
|
||||
File.SetAttributes(path, attributes | FileAttributes.Hidden);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d400833b3a18409458680f66c6f6e18e
|
||||
@@ -111,6 +111,17 @@ public sealed class PlayerEconomyLedger : MonoBehaviour
|
||||
return payload.coins >= amount;
|
||||
}
|
||||
|
||||
public bool HasEnoughMaterial(long amount)
|
||||
{
|
||||
if (amount <= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
InitializeIfNeeded();
|
||||
return payload.material >= amount;
|
||||
}
|
||||
|
||||
public void AddCoins(int amount)
|
||||
{
|
||||
if (amount <= 0)
|
||||
@@ -157,6 +168,24 @@ public sealed class PlayerEconomyLedger : MonoBehaviour
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TrySpendMaterial(int amount)
|
||||
{
|
||||
if (amount <= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
InitializeIfNeeded();
|
||||
if (payload.material < amount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
payload.material -= amount;
|
||||
SaveNow();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetCoins(int value)
|
||||
{
|
||||
InitializeIfNeeded();
|
||||
|
||||
@@ -7,7 +7,8 @@ public static class StoreExpBottlePurchaseService
|
||||
{
|
||||
None,
|
||||
ExpBottle,
|
||||
GrowthMaterial
|
||||
GrowthMaterial,
|
||||
EquipmentConsumable
|
||||
}
|
||||
|
||||
public static bool TryPurchase(Player_SO playerData, storeItemSO itemSO, int packageCount, out string failureMessage, out int grantedCount)
|
||||
@@ -137,7 +138,8 @@ public static class StoreExpBottlePurchaseService
|
||||
ConsumableGrantType grantType;
|
||||
ExpBottleKind bottleKind;
|
||||
DushMaterialKind materialKind;
|
||||
if (!TryResolveConsumableGrant(itemSO, out grantType, out bottleKind, out materialKind))
|
||||
EquipmentConsumableKind equipmentConsumableKind;
|
||||
if (!TryResolveConsumableGrant(itemSO, out grantType, out bottleKind, out materialKind, out equipmentConsumableKind))
|
||||
{
|
||||
failureMessage = "当前未配置发放逻辑";
|
||||
return false;
|
||||
@@ -170,7 +172,8 @@ public static class StoreExpBottlePurchaseService
|
||||
ConsumableGrantType grantType;
|
||||
ExpBottleKind bottleKind;
|
||||
DushMaterialKind materialKind;
|
||||
if (!TryResolveConsumableGrant(itemSO, out grantType, out bottleKind, out materialKind))
|
||||
EquipmentConsumableKind equipmentConsumableKind;
|
||||
if (!TryResolveConsumableGrant(itemSO, out grantType, out bottleKind, out materialKind, out equipmentConsumableKind))
|
||||
{
|
||||
failureMessage = "当前未配置发放逻辑";
|
||||
return false;
|
||||
@@ -190,6 +193,12 @@ public static class StoreExpBottlePurchaseService
|
||||
return true;
|
||||
}
|
||||
|
||||
if (grantType == ConsumableGrantType.EquipmentConsumable)
|
||||
{
|
||||
EquipmentConsumableLedger.EnsureInstance().Add(equipmentConsumableKind, grantedCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
failureMessage = "当前未配置发放逻辑";
|
||||
return false;
|
||||
|
||||
@@ -224,7 +233,8 @@ public static class StoreExpBottlePurchaseService
|
||||
ConsumableGrantType grantType;
|
||||
ExpBottleKind bottleKind;
|
||||
DushMaterialKind materialKind;
|
||||
if (!TryResolveConsumableGrant(itemSO, out grantType, out bottleKind, out materialKind))
|
||||
EquipmentConsumableKind equipmentConsumableKind;
|
||||
if (!TryResolveConsumableGrant(itemSO, out grantType, out bottleKind, out materialKind, out equipmentConsumableKind))
|
||||
{
|
||||
Debug.Log(builder.ToString());
|
||||
return;
|
||||
@@ -240,6 +250,16 @@ public static class StoreExpBottlePurchaseService
|
||||
return;
|
||||
}
|
||||
|
||||
if (grantType == ConsumableGrantType.EquipmentConsumable)
|
||||
{
|
||||
builder.Append(" | 装备材料库存=");
|
||||
builder.Append(EquipmentConsumableCatalog.GetDisplayName(equipmentConsumableKind));
|
||||
builder.Append(":");
|
||||
builder.Append(EquipmentConsumableLedger.EnsureInstance().GetCount(equipmentConsumableKind));
|
||||
Debug.Log(builder.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
var snapshot = ExpBottleLedger.EnsureInstance().GetSnapshot();
|
||||
builder.Append(" | 经验瓶库存:");
|
||||
|
||||
@@ -267,11 +287,12 @@ public static class StoreExpBottlePurchaseService
|
||||
Debug.Log(builder.ToString());
|
||||
}
|
||||
|
||||
private static bool TryResolveConsumableGrant(storeItemSO itemSO, out ConsumableGrantType grantType, out ExpBottleKind bottleKind, out DushMaterialKind materialKind)
|
||||
private static bool TryResolveConsumableGrant(storeItemSO itemSO, out ConsumableGrantType grantType, out ExpBottleKind bottleKind, out DushMaterialKind materialKind, out EquipmentConsumableKind equipmentConsumableKind)
|
||||
{
|
||||
grantType = ConsumableGrantType.None;
|
||||
bottleKind = default(ExpBottleKind);
|
||||
materialKind = default(DushMaterialKind);
|
||||
equipmentConsumableKind = default(EquipmentConsumableKind);
|
||||
|
||||
if (itemSO == null)
|
||||
{
|
||||
@@ -292,6 +313,13 @@ public static class StoreExpBottlePurchaseService
|
||||
return true;
|
||||
}
|
||||
|
||||
if (itemSO.associatedEquipmentConsumable != null)
|
||||
{
|
||||
grantType = ConsumableGrantType.EquipmentConsumable;
|
||||
equipmentConsumableKind = itemSO.associatedEquipmentConsumable.consumableKind;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (StoreExpBottleGrantResolver.TryResolve(itemSO, out bottleKind))
|
||||
{
|
||||
grantType = ConsumableGrantType.ExpBottle;
|
||||
|
||||
Reference in New Issue
Block a user