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

280 lines
7.6 KiB
C#

using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
public sealed class AllyHeroDeployLedger : MonoBehaviour
{
public static AllyHeroDeployLedger Instance { get; private set; }
private readonly Dictionary<int, int> deployCountsByHeroId = new Dictionary<int, int>();
private readonly Dictionary<int, int> finishCountsByHeroId = new Dictionary<int, int>();
private readonly Dictionary<int, int> mvpCountsByHeroId = new Dictionary<int, int>();
private bool initialized;
private bool loadedFromSave;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void Bootstrap()
{
EnsureInstance();
}
public static AllyHeroDeployLedger EnsureInstance()
{
if (Instance != null)
{
return Instance;
}
GameObject host = new GameObject("__runtime_ally_deploy_bridge");
host.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector;
DontDestroyOnLoad(host);
Instance = host.AddComponent<AllyHeroDeployLedger>();
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;
}
AllyHeroDeployLedgerPayload payload;
loadedFromSave = AllyHeroDeployLedgerStorage.TryLoad(out payload);
RebuildFromPayload(payload);
initialized = true;
SyncAllMirrorFlags();
SaveNow();
}
public int GetDeployCount(int heroId)
{
InitializeIfNeeded();
int count;
return deployCountsByHeroId.TryGetValue(heroId, out count) ? count : 0;
}
public int GetFinishCount(int heroId)
{
InitializeIfNeeded();
int count;
return finishCountsByHeroId.TryGetValue(heroId, out count) ? count : 0;
}
public int GetMvpCount(int heroId)
{
InitializeIfNeeded();
int count;
return mvpCountsByHeroId.TryGetValue(heroId, out count) ? count : 0;
}
public void IncrementDeployCount(AllyHero_SO hero, int amount = 1)
{
if (hero == null || hero.ally_heroID <= 0 || amount <= 0)
{
return;
}
InitializeIfNeeded();
int current = GetDeployCount(hero.ally_heroID);
long next = (long)current + amount;
deployCountsByHeroId[hero.ally_heroID] = next > int.MaxValue ? int.MaxValue : (int)next;
hero.ally_battleDeployCount = deployCountsByHeroId[hero.ally_heroID];
MarkDirty(hero);
SaveNow();
}
public void IncrementFinishCount(AllyHero_SO hero, int amount = 1)
{
if (hero == null || hero.ally_heroID <= 0 || amount <= 0)
{
return;
}
InitializeIfNeeded();
int current = GetFinishCount(hero.ally_heroID);
long next = (long)current + amount;
finishCountsByHeroId[hero.ally_heroID] = next > int.MaxValue ? int.MaxValue : (int)next;
hero.ally_finishCount = finishCountsByHeroId[hero.ally_heroID];
MarkDirty(hero);
SaveNow();
}
public void IncrementMvpCount(AllyHero_SO hero, int amount = 1)
{
if (hero == null || hero.ally_heroID <= 0 || amount <= 0)
{
return;
}
InitializeIfNeeded();
int current = GetMvpCount(hero.ally_heroID);
long next = (long)current + amount;
mvpCountsByHeroId[hero.ally_heroID] = next > int.MaxValue ? int.MaxValue : (int)next;
hero.ally_mvpCount = mvpCountsByHeroId[hero.ally_heroID];
MarkDirty(hero);
SaveNow();
}
public void SaveNow()
{
if (!initialized)
{
return;
}
SyncAllMirrorFlags();
AllyHeroDeployLedgerStorage.TrySave(BuildPayload());
}
private void RebuildFromPayload(AllyHeroDeployLedgerPayload payload)
{
deployCountsByHeroId.Clear();
finishCountsByHeroId.Clear();
mvpCountsByHeroId.Clear();
if (payload == null || payload.entries == null)
{
return;
}
for (int i = 0; i < payload.entries.Count; i++)
{
AllyHeroDeployEntry entry = payload.entries[i];
if (entry == null || entry.heroId <= 0)
{
continue;
}
deployCountsByHeroId[entry.heroId] = Mathf.Max(0, entry.deployCount);
finishCountsByHeroId[entry.heroId] = Mathf.Max(0, entry.finishCount);
mvpCountsByHeroId[entry.heroId] = Mathf.Max(0, entry.mvpCount);
}
}
private void SyncAllMirrorFlags()
{
AllyHero_SO[] heroes = Resources.LoadAll<AllyHero_SO>(string.Empty);
for (int i = 0; i < heroes.Length; i++)
{
AllyHero_SO hero = heroes[i];
if (hero == null || hero.ally_heroID <= 0)
{
continue;
}
int count;
if (!deployCountsByHeroId.TryGetValue(hero.ally_heroID, out count))
{
count = 0;
}
int finishCount;
if (!finishCountsByHeroId.TryGetValue(hero.ally_heroID, out finishCount))
{
finishCount = 0;
}
int mvpCount;
if (!mvpCountsByHeroId.TryGetValue(hero.ally_heroID, out mvpCount))
{
mvpCount = 0;
}
bool changed = false;
if (hero.ally_battleDeployCount != count)
{
hero.ally_battleDeployCount = count;
changed = true;
}
if (hero.ally_finishCount != finishCount)
{
hero.ally_finishCount = finishCount;
changed = true;
}
if (hero.ally_mvpCount != mvpCount)
{
hero.ally_mvpCount = mvpCount;
changed = true;
}
if (changed)
{
MarkDirty(hero);
}
}
}
private AllyHeroDeployLedgerPayload BuildPayload()
{
AllyHeroDeployLedgerPayload payload = AllyHeroDeployLedgerStorage.CreateDefaultPayload();
HashSet<int> allHeroIds = new HashSet<int>();
foreach (KeyValuePair<int, int> pair in deployCountsByHeroId)
{
allHeroIds.Add(pair.Key);
}
foreach (KeyValuePair<int, int> pair in finishCountsByHeroId)
{
allHeroIds.Add(pair.Key);
}
foreach (KeyValuePair<int, int> pair in mvpCountsByHeroId)
{
allHeroIds.Add(pair.Key);
}
foreach (int heroId in allHeroIds)
{
payload.entries.Add(new AllyHeroDeployEntry
{
heroId = heroId,
deployCount = Mathf.Max(0, GetDeployCount(heroId)),
finishCount = Mathf.Max(0, GetFinishCount(heroId)),
mvpCount = Mathf.Max(0, GetMvpCount(heroId))
});
}
return payload;
}
private static void MarkDirty(AllyHero_SO hero)
{
#if UNITY_EDITOR
if (!Application.isPlaying && hero != null)
{
EditorUtility.SetDirty(hero);
}
#endif
}
}