216 lines
5.3 KiB
C#
216 lines
5.3 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 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;
|
|
SeedFromHeroAssetsIfNeeded();
|
|
SyncAllMirrorFlags();
|
|
SaveNow();
|
|
}
|
|
|
|
public int GetDeployCount(int heroId)
|
|
{
|
|
InitializeIfNeeded();
|
|
int count;
|
|
return deployCountsByHeroId.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 SaveNow()
|
|
{
|
|
if (!initialized)
|
|
{
|
|
return;
|
|
}
|
|
|
|
SyncAllMirrorFlags();
|
|
AllyHeroDeployLedgerStorage.TrySave(BuildPayload());
|
|
}
|
|
|
|
private void RebuildFromPayload(AllyHeroDeployLedgerPayload payload)
|
|
{
|
|
deployCountsByHeroId.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);
|
|
}
|
|
}
|
|
|
|
private void SeedFromHeroAssetsIfNeeded()
|
|
{
|
|
AllyHero_SO[] heroes = Resources.LoadAll<AllyHero_SO>(string.Empty);
|
|
bool changed = false;
|
|
|
|
for (int i = 0; i < heroes.Length; i++)
|
|
{
|
|
AllyHero_SO hero = heroes[i];
|
|
if (hero == null || hero.ally_heroID <= 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (deployCountsByHeroId.ContainsKey(hero.ally_heroID))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (hero.ally_battleDeployCount <= 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
deployCountsByHeroId[hero.ally_heroID] = Mathf.Max(0, hero.ally_battleDeployCount);
|
|
changed = true;
|
|
}
|
|
|
|
if (changed && !loadedFromSave)
|
|
{
|
|
SaveNow();
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
if (hero.ally_battleDeployCount == count)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
hero.ally_battleDeployCount = count;
|
|
MarkDirty(hero);
|
|
}
|
|
}
|
|
|
|
private AllyHeroDeployLedgerPayload BuildPayload()
|
|
{
|
|
AllyHeroDeployLedgerPayload payload = AllyHeroDeployLedgerStorage.CreateDefaultPayload();
|
|
foreach (KeyValuePair<int, int> pair in deployCountsByHeroId)
|
|
{
|
|
payload.entries.Add(new AllyHeroDeployEntry
|
|
{
|
|
heroId = pair.Key,
|
|
deployCount = Mathf.Max(0, pair.Value)
|
|
});
|
|
}
|
|
|
|
return payload;
|
|
}
|
|
|
|
private static void MarkDirty(AllyHero_SO hero)
|
|
{
|
|
#if UNITY_EDITOR
|
|
if (hero != null)
|
|
{
|
|
EditorUtility.SetDirty(hero);
|
|
}
|
|
#endif
|
|
}
|
|
}
|