拼ui 一些业务逻辑x实现

This commit is contained in:
FloatGaming
2026-03-19 06:15:09 +08:00
parent f5c6f143c0
commit 49e45ac464
1118 changed files with 246518 additions and 5368 deletions
@@ -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);
}