拼ui 一些业务逻辑x实现
This commit is contained in:
@@ -9,6 +9,8 @@ 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;
|
||||
|
||||
@@ -69,7 +71,6 @@ public sealed class AllyHeroDeployLedger : MonoBehaviour
|
||||
loadedFromSave = AllyHeroDeployLedgerStorage.TryLoad(out payload);
|
||||
RebuildFromPayload(payload);
|
||||
initialized = true;
|
||||
SeedFromHeroAssetsIfNeeded();
|
||||
SyncAllMirrorFlags();
|
||||
SaveNow();
|
||||
}
|
||||
@@ -81,6 +82,20 @@ public sealed class AllyHeroDeployLedger : MonoBehaviour
|
||||
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)
|
||||
@@ -97,6 +112,38 @@ public sealed class AllyHeroDeployLedger : MonoBehaviour
|
||||
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)
|
||||
@@ -111,6 +158,8 @@ public sealed class AllyHeroDeployLedger : MonoBehaviour
|
||||
private void RebuildFromPayload(AllyHeroDeployLedgerPayload payload)
|
||||
{
|
||||
deployCountsByHeroId.Clear();
|
||||
finishCountsByHeroId.Clear();
|
||||
mvpCountsByHeroId.Clear();
|
||||
if (payload == null || payload.entries == null)
|
||||
{
|
||||
return;
|
||||
@@ -125,39 +174,8 @@ public sealed class AllyHeroDeployLedger : MonoBehaviour
|
||||
}
|
||||
|
||||
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();
|
||||
finishCountsByHeroId[entry.heroId] = Mathf.Max(0, entry.finishCount);
|
||||
mvpCountsByHeroId[entry.heroId] = Mathf.Max(0, entry.mvpCount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,25 +196,71 @@ public sealed class AllyHeroDeployLedger : MonoBehaviour
|
||||
count = 0;
|
||||
}
|
||||
|
||||
if (hero.ally_battleDeployCount == count)
|
||||
int finishCount;
|
||||
if (!finishCountsByHeroId.TryGetValue(hero.ally_heroID, out finishCount))
|
||||
{
|
||||
continue;
|
||||
finishCount = 0;
|
||||
}
|
||||
|
||||
hero.ally_battleDeployCount = count;
|
||||
MarkDirty(hero);
|
||||
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 = pair.Key,
|
||||
deployCount = Mathf.Max(0, pair.Value)
|
||||
heroId = heroId,
|
||||
deployCount = Mathf.Max(0, GetDeployCount(heroId)),
|
||||
finishCount = Mathf.Max(0, GetFinishCount(heroId)),
|
||||
mvpCount = Mathf.Max(0, GetMvpCount(heroId))
|
||||
});
|
||||
}
|
||||
|
||||
@@ -206,7 +270,7 @@ public sealed class AllyHeroDeployLedger : MonoBehaviour
|
||||
private static void MarkDirty(AllyHero_SO hero)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (hero != null)
|
||||
if (!Application.isPlaying && hero != null)
|
||||
{
|
||||
EditorUtility.SetDirty(hero);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ public class AllyHeroDeployEntry
|
||||
{
|
||||
public int heroId;
|
||||
public int deployCount;
|
||||
public int finishCount;
|
||||
public int mvpCount;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
|
||||
@@ -82,16 +82,7 @@ public sealed class DushMaterialLedger : MonoBehaviour
|
||||
|
||||
InitializeIfNeeded();
|
||||
boundPlayerData = playerData;
|
||||
|
||||
if (!loadedFromSave)
|
||||
{
|
||||
SeedFromPlayerSo(playerData, false);
|
||||
loadedFromSave = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SyncToPlayerData();
|
||||
}
|
||||
SyncToPlayerData();
|
||||
}
|
||||
|
||||
public int GetCount(DushMaterialKind kind)
|
||||
|
||||
@@ -93,16 +93,7 @@ public sealed class ExpBottleLedger : MonoBehaviour
|
||||
|
||||
InitializeIfNeeded();
|
||||
boundPlayerData = playerData;
|
||||
|
||||
if (!loadedFromSave)
|
||||
{
|
||||
SeedFromPlayerSo(playerData, false);
|
||||
loadedFromSave = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SyncToPlayerData();
|
||||
}
|
||||
SyncToPlayerData();
|
||||
}
|
||||
|
||||
public int GetCount(ExpBottleKind kind)
|
||||
|
||||
@@ -83,15 +83,8 @@ public sealed class PlayerEconomyLedger : MonoBehaviour
|
||||
InitializeIfNeeded();
|
||||
boundPlayerData = playerData;
|
||||
|
||||
if (!loadedFromSave)
|
||||
{
|
||||
payload.coins = Mathf.Max(0, playerData.Coins);
|
||||
payload.material = Mathf.Max(0, playerData.Material);
|
||||
SaveNow();
|
||||
loadedFromSave = true;
|
||||
}
|
||||
|
||||
SyncToPlayerData();
|
||||
GlobalAchievementService.EnsureInstance().ReportCurrentCoins(payload.coins);
|
||||
NotifyEconomyChanged();
|
||||
}
|
||||
|
||||
@@ -128,6 +121,7 @@ public sealed class PlayerEconomyLedger : MonoBehaviour
|
||||
InitializeIfNeeded();
|
||||
long next = (long)payload.coins + amount;
|
||||
payload.coins = next > int.MaxValue ? int.MaxValue : (int)next;
|
||||
GlobalAchievementService.EnsureInstance().ReportCoinsEarned(amount);
|
||||
SaveNow();
|
||||
}
|
||||
|
||||
@@ -175,6 +169,7 @@ public sealed class PlayerEconomyLedger : MonoBehaviour
|
||||
InitializeIfNeededForSave();
|
||||
PlayerEconomyStorage.TrySave(payload);
|
||||
SyncToPlayerData();
|
||||
GlobalAchievementService.EnsureInstance().ReportCurrentCoins(payload.coins);
|
||||
NotifyEconomyChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -5,12 +5,19 @@ using System.Collections.Generic;
|
||||
public class RecentPlayRecord
|
||||
{
|
||||
public string playedAt;
|
||||
public string playedAtUtc;
|
||||
public int songID;
|
||||
public string songName;
|
||||
public string difficultyDisplay;
|
||||
public float accuracy;
|
||||
public float srks;
|
||||
public int totalScore;
|
||||
public int chartScore;
|
||||
public int idolScore;
|
||||
public bool hasScoreBreakdown;
|
||||
public int rankIndex;
|
||||
public int rankTierCount;
|
||||
public bool hasRankMarker;
|
||||
public bool scoreReadable;
|
||||
public bool wasEarlySettlement;
|
||||
public bool wasAllPerfect;
|
||||
|
||||
@@ -14,6 +14,7 @@ public sealed class StoreOwnershipLedger : MonoBehaviour
|
||||
private readonly Dictionary<int, StoreOwnershipEntry> entriesByItemId = new Dictionary<int, StoreOwnershipEntry>();
|
||||
private readonly List<storeItemSO> cachedStoreItems = new List<storeItemSO>();
|
||||
private bool initialized;
|
||||
private int lastSaveFrame = -1;
|
||||
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||
private static void Bootstrap()
|
||||
@@ -68,13 +69,12 @@ public sealed class StoreOwnershipLedger : MonoBehaviour
|
||||
return;
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
StoreOwnershipPayload payload;
|
||||
StoreOwnershipStorage.TryLoad(out payload);
|
||||
RebuildFromPayload(payload);
|
||||
LoadStoreItems();
|
||||
SeedFromCurrentMirrorFlags();
|
||||
SyncAllMirrorFlags();
|
||||
initialized = true;
|
||||
SaveNow();
|
||||
}
|
||||
|
||||
@@ -137,6 +137,7 @@ public sealed class StoreOwnershipLedger : MonoBehaviour
|
||||
}
|
||||
|
||||
ApplyEntryToItem(itemSO, entry);
|
||||
GlobalAchievementService.EnsureInstance().RefreshDerivedMetrics();
|
||||
SaveNow();
|
||||
return true;
|
||||
}
|
||||
@@ -154,6 +155,12 @@ public sealed class StoreOwnershipLedger : MonoBehaviour
|
||||
return;
|
||||
}
|
||||
|
||||
if (Application.isPlaying && lastSaveFrame == Time.frameCount)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lastSaveFrame = Application.isPlaying ? Time.frameCount : -1;
|
||||
StoreOwnershipStorage.TrySave(CreatePayload());
|
||||
}
|
||||
|
||||
@@ -314,6 +321,8 @@ public sealed class StoreOwnershipLedger : MonoBehaviour
|
||||
|
||||
private void SyncAllMirrorFlags()
|
||||
{
|
||||
ResetAllMirrorFlags();
|
||||
|
||||
for (int i = 0; i < cachedStoreItems.Count; i++)
|
||||
{
|
||||
var item = cachedStoreItems[i];
|
||||
@@ -332,6 +341,68 @@ public sealed class StoreOwnershipLedger : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetAllMirrorFlags()
|
||||
{
|
||||
var seenHeroIds = new HashSet<int>();
|
||||
var seenSongIds = new HashSet<int>();
|
||||
var seenStoryIds = new HashSet<int>();
|
||||
|
||||
for (int i = 0; i < cachedStoreItems.Count; i++)
|
||||
{
|
||||
var item = cachedStoreItems[i];
|
||||
if (item == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (item.itemType == storeItemSO.ItemType.character && item.associatedAllyHero != null && seenHeroIds.Add(item.associatedAllyHero.ally_heroID))
|
||||
{
|
||||
if (item.associatedAllyHero.isUnlocked)
|
||||
{
|
||||
item.associatedAllyHero.isUnlocked = false;
|
||||
MarkDirty(item.associatedAllyHero);
|
||||
}
|
||||
}
|
||||
else if (item.itemType == storeItemSO.ItemType.song && item.associatedSong != null && seenSongIds.Add(item.associatedSong.songID))
|
||||
{
|
||||
if (item.associatedSong.isUnlocked)
|
||||
{
|
||||
item.associatedSong.isUnlocked = false;
|
||||
MarkDirty(item.associatedSong);
|
||||
}
|
||||
}
|
||||
else if (item.itemType == storeItemSO.ItemType.storyPassage && item.associatedStoryPassage != null && seenStoryIds.Add(item.associatedStoryPassage.class_id))
|
||||
{
|
||||
var story = item.associatedStoryPassage;
|
||||
bool changed = false;
|
||||
|
||||
if (story.isUnlocked)
|
||||
{
|
||||
story.isUnlocked = false;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (story.sonList != null)
|
||||
{
|
||||
for (int sonIndex = 0; sonIndex < story.sonList.Count; sonIndex++)
|
||||
{
|
||||
var son = story.sonList[sonIndex];
|
||||
if (son != null && son.son_isUnlocked)
|
||||
{
|
||||
son.son_isUnlocked = false;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
MarkDirty(story);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool ValidateGrantTarget(storeItemSO itemSO, out string failureMessage)
|
||||
{
|
||||
failureMessage = string.Empty;
|
||||
@@ -647,7 +718,7 @@ public sealed class StoreOwnershipLedger : MonoBehaviour
|
||||
private static void MarkDirty(UnityEngine.Object target)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (target != null)
|
||||
if (!Application.isPlaying && target != null)
|
||||
{
|
||||
EditorUtility.SetDirty(target);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user