装备系统做了很多
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user