任务系统一半多,商城筛选功能,一些细节和免费包
This commit is contained in:
@@ -0,0 +1,291 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public sealed class DushMaterialLedger : MonoBehaviour
|
||||
{
|
||||
public static DushMaterialLedger Instance { get; private set; }
|
||||
|
||||
public event Action<DushMaterialKind, int> OnMaterialCountChanged;
|
||||
|
||||
private readonly Dictionary<string, int> countsByKey = new Dictionary<string, int>(StringComparer.Ordinal);
|
||||
private bool initialized;
|
||||
private bool loadedFromSave;
|
||||
private Player_SO boundPlayerData;
|
||||
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||
private static void Bootstrap()
|
||||
{
|
||||
EnsureInstance();
|
||||
}
|
||||
|
||||
public static DushMaterialLedger EnsureInstance()
|
||||
{
|
||||
if (Instance != null)
|
||||
{
|
||||
return Instance;
|
||||
}
|
||||
|
||||
var host = new GameObject("__runtime_dush_material_bridge");
|
||||
host.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector;
|
||||
DontDestroyOnLoad(host);
|
||||
Instance = host.AddComponent<DushMaterialLedger>();
|
||||
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;
|
||||
}
|
||||
|
||||
DushMaterialLedgerPayload payload;
|
||||
loadedFromSave = DushMaterialLedgerStorage.TryLoad(out payload);
|
||||
RebuildFromPayload(payload);
|
||||
initialized = true;
|
||||
SaveNow();
|
||||
}
|
||||
|
||||
public void AttachPlayerData(Player_SO playerData)
|
||||
{
|
||||
if (playerData == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InitializeIfNeeded();
|
||||
boundPlayerData = playerData;
|
||||
|
||||
if (!loadedFromSave)
|
||||
{
|
||||
SeedFromPlayerSo(playerData, false);
|
||||
loadedFromSave = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SyncToPlayerData();
|
||||
}
|
||||
}
|
||||
|
||||
public int GetCount(DushMaterialKind kind)
|
||||
{
|
||||
return GetCountByKey(DushMaterialCatalog.GetKey(kind));
|
||||
}
|
||||
|
||||
public void Add(DushMaterialKind kind, int amount)
|
||||
{
|
||||
if (amount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ChangeCount(DushMaterialCatalog.GetKey(kind), amount);
|
||||
}
|
||||
|
||||
public bool SeedFromPlayerSo(Player_SO playerData, bool overwriteExistingCounts)
|
||||
{
|
||||
if (playerData == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
InitializeIfNeeded();
|
||||
bool changed = false;
|
||||
for (int i = 0; i < DushMaterialCatalog.All.Count; i++)
|
||||
{
|
||||
var descriptor = DushMaterialCatalog.All[i];
|
||||
if (string.IsNullOrEmpty(descriptor.LegacyPlayerFieldName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int legacyValue = Mathf.Max(0, playerData.GetLegacyDushMaterialCount(descriptor.LegacyPlayerFieldName));
|
||||
int currentValue = GetCountByKey(descriptor.Key);
|
||||
if (!overwriteExistingCounts && currentValue > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (currentValue == legacyValue)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
countsByKey[descriptor.Key] = legacyValue;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (!changed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SaveNow();
|
||||
NotifyAllCountsChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SaveNow()
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
InitializeIfNeeded();
|
||||
}
|
||||
|
||||
DushMaterialLedgerStorage.TrySave(BuildPayload());
|
||||
SyncToPlayerData();
|
||||
}
|
||||
|
||||
private int GetCountByKey(string key)
|
||||
{
|
||||
InitializeIfNeeded();
|
||||
|
||||
int count;
|
||||
if (!countsByKey.TryGetValue(key, out 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();
|
||||
|
||||
DushMaterialKind kind;
|
||||
if (DushMaterialCatalog.TryGetKind(key, out kind) && OnMaterialCountChanged != null)
|
||||
{
|
||||
OnMaterialCountChanged(kind, safeValue);
|
||||
}
|
||||
}
|
||||
|
||||
private void RebuildFromPayload(DushMaterialLedgerPayload payload)
|
||||
{
|
||||
countsByKey.Clear();
|
||||
for (int i = 0; i < DushMaterialCatalog.All.Count; i++)
|
||||
{
|
||||
countsByKey[DushMaterialCatalog.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 DushMaterialLedgerPayload BuildPayload()
|
||||
{
|
||||
var payload = DushMaterialLedgerStorage.CreateDefaultPayload();
|
||||
payload.entries.Clear();
|
||||
|
||||
for (int i = 0; i < DushMaterialCatalog.All.Count; i++)
|
||||
{
|
||||
var descriptor = DushMaterialCatalog.All[i];
|
||||
payload.entries.Add(new DushMaterialEntry
|
||||
{
|
||||
key = descriptor.Key,
|
||||
count = GetCountByKey(descriptor.Key)
|
||||
});
|
||||
}
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
private void SyncToPlayerData()
|
||||
{
|
||||
if (boundPlayerData == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < DushMaterialCatalog.All.Count; i++)
|
||||
{
|
||||
var descriptor = DushMaterialCatalog.All[i];
|
||||
if (string.IsNullOrEmpty(descriptor.LegacyPlayerFieldName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
boundPlayerData.SetLegacyDushMaterialCount(descriptor.LegacyPlayerFieldName, GetCountByKey(descriptor.Key));
|
||||
}
|
||||
}
|
||||
|
||||
private void NotifyAllCountsChanged()
|
||||
{
|
||||
if (OnMaterialCountChanged == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < DushMaterialCatalog.All.Count; i++)
|
||||
{
|
||||
var descriptor = DushMaterialCatalog.All[i];
|
||||
OnMaterialCountChanged(descriptor.Kind, GetCountByKey(descriptor.Key));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user