This commit is contained in:
2026-03-13 17:58:09 +08:00
parent 777c58b812
commit c76fd85a2c
25 changed files with 1214 additions and 360 deletions
@@ -177,11 +177,7 @@ namespace GeometryTD.CustomComponent
public void StartCombat(
int levelId = 0,
string runId = null,
int runSeed = 0,
int nodeId = 0,
RunNodeType nodeType = RunNodeType.None,
int sequenceIndex = -1)
RunNodeExecutionContext context = null)
{
if (!EnsureCombatRuntimeInitialized())
{
@@ -232,11 +228,7 @@ namespace GeometryTD.CustomComponent
selectedLevel,
phaseList,
_selectedSpawnEntriesByPhaseId,
runId,
runSeed,
nodeId,
nodeType,
sequenceIndex))
context))
{
CurrentLevel = null;
return;
@@ -69,11 +69,7 @@ namespace GeometryTD.CustomComponent
DRLevel level,
IReadOnlyList<DRLevelPhase> phases,
IReadOnlyDictionary<int, IReadOnlyList<DRLevelSpawnEntry>> spawnEntriesByPhaseId,
string runId = null,
int runSeed = 0,
int nodeId = 0,
RunNodeType nodeType = RunNodeType.None,
int sequenceIndex = -1)
RunNodeExecutionContext context = null)
{
if (!_initialized || _runtime.Entity == null)
{
@@ -95,11 +91,7 @@ namespace GeometryTD.CustomComponent
_runtime.DidCombatWin = true;
_runtime.CurrentLevel = level;
_runtime.RunId = runId;
_runtime.RunSeed = runSeed;
_runtime.NodeId = nodeId;
_runtime.NodeType = nodeType;
_runtime.SequenceIndex = sequenceIndex;
_runtime.NodeContext = context != null ? context.Clone() : null;
_runtime.NextDropOrdinal = 0;
_runtime.NextRewardOrdinal = 0;
_runtime.CombatRunResourceStore.InitializeForCombat(level);
@@ -205,8 +197,8 @@ namespace GeometryTD.CustomComponent
int nextDropOrdinal = _runtime.NextDropOrdinal;
EnemyDropResult result = GameEntry.InventoryGeneration.ResolveEnemyDrop(
context,
_runtime.RunSeed,
_runtime.SequenceIndex,
_runtime.NodeContext != null ? _runtime.NodeContext.RunSeed : 0,
_runtime.NodeContext != null ? _runtime.NodeContext.SequenceIndex : -1,
ref nextDropOrdinal);
_runtime.NextDropOrdinal = nextDropOrdinal;
_runtime.CombatRunResourceStore.AddEnemyDefeatedReward(result.Coin, result.Gold);
@@ -55,11 +55,7 @@ namespace GeometryTD.CustomComponent
_runtime.DidCombatWin = true;
_runtime.IsCompleted = false;
_runtime.NodeEnterFired = false;
_runtime.RunId = null;
_runtime.RunSeed = 0;
_runtime.NodeId = 0;
_runtime.NodeType = RunNodeType.None;
_runtime.SequenceIndex = -1;
_runtime.NodeContext = null;
_runtime.NextDropOrdinal = 0;
_runtime.NextRewardOrdinal = 0;
}
@@ -203,16 +199,20 @@ namespace GeometryTD.CustomComponent
public void CompleteNormalCombatAndNotify(bool didCombatWin)
{
CompleteCombat(didCombatWin);
RunNodeExecutionContext nodeContext = _runtime.NodeContext;
GameEntry.Event.Fire(
this,
NodeCompleteEventArgs.Create(
_runtime.RunId,
_runtime.NodeId,
_runtime.NodeType,
_runtime.SequenceIndex,
nodeContext?.RunId,
nodeContext?.NodeId ?? 0,
nodeContext?.NodeType ?? RunNodeType.None,
nodeContext?.SequenceIndex ?? -1,
RunNodeCompletionStatus.Completed,
didCombatWin,
GameEntry.PlayerInventory != null ? GameEntry.PlayerInventory.GetInventorySnapshot() : null));
nodeContext != null
? nodeContext.CreateCompletionSnapshot(
GameEntry.PlayerInventory != null ? GameEntry.PlayerInventory.GetInventorySnapshot() : null)
: null));
}
public void CompleteFailureCombatAndNotify()
@@ -222,16 +222,20 @@ namespace GeometryTD.CustomComponent
CloseRewardSelectForm();
CloseDialogForm();
CompleteCombat(false);
RunNodeExecutionContext nodeContext = _runtime.NodeContext;
GameEntry.Event.Fire(
this,
NodeCompleteEventArgs.Create(
_runtime.RunId,
_runtime.NodeId,
_runtime.NodeType,
_runtime.SequenceIndex,
nodeContext?.RunId,
nodeContext?.NodeId ?? 0,
nodeContext?.NodeType ?? RunNodeType.None,
nodeContext?.SequenceIndex ?? -1,
RunNodeCompletionStatus.Exception,
false,
GameEntry.PlayerInventory != null ? GameEntry.PlayerInventory.GetInventorySnapshot() : null));
nodeContext != null
? nodeContext.CreateCompletionSnapshot(
GameEntry.PlayerInventory != null ? GameEntry.PlayerInventory.GetInventorySnapshot() : null)
: null));
}
public bool HandleStartFailure(string errorMessage)
@@ -29,11 +29,7 @@ namespace GeometryTD.CustomComponent
public bool IsCompleted { get; set; }
public bool NodeEnterFired { get; set; }
public CombatSettlementContext SettlementContext { get; set; }
public string RunId { get; set; }
public int RunSeed { get; set; }
public int NodeId { get; set; }
public RunNodeType NodeType { get; set; }
public int SequenceIndex { get; set; }
public RunNodeExecutionContext NodeContext { get; set; }
public int NextDropOrdinal { get; set; }
public int NextRewardOrdinal { get; set; }
}
@@ -21,8 +21,8 @@ namespace GeometryTD.CustomComponent
Runtime.SettlementContext,
Runtime.PhaseLoopRuntime.DisplayPhaseIndex,
Coordinator.ResolveCurrentThemeType(),
Runtime.RunSeed,
Runtime.SequenceIndex,
Runtime.NodeContext != null ? Runtime.NodeContext.RunSeed : 0,
Runtime.NodeContext != null ? Runtime.NodeContext.SequenceIndex : -1,
ref nextRewardOrdinal,
Runtime.RewardSelectFormUseCase,
Coordinator.OnFullBaseHpRewardSelected,
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using GeometryTD.CustomEvent;
using GeometryTD.DataTable;
using GeometryTD.Procedure;
using UnityGameFramework.Runtime;
namespace GeometryTD.CustomComponent
@@ -41,10 +42,10 @@ namespace GeometryTD.CustomComponent
GameEntry.Event.Fire(
Coordinator,
NodeEnterEventArgs.Create(
Runtime.RunId,
Runtime.NodeId,
Runtime.NodeType,
Runtime.SequenceIndex));
Runtime.NodeContext?.RunId,
Runtime.NodeContext?.NodeId ?? 0,
Runtime.NodeContext?.NodeType ?? RunNodeType.None,
Runtime.NodeContext?.SequenceIndex ?? -1));
}
Log.Info(
@@ -14,10 +14,7 @@ namespace GeometryTD.CustomComponent
{
public class EventNodeComponent : GameFrameworkComponent
{
private string _activeRunId;
private int _activeNodeId;
private RunNodeType _activeNodeType = RunNodeType.None;
private int _activeSequenceIndex = -1;
private RunNodeExecutionContext _activeContext;
private readonly List<EventItem> _eventItems = new List<EventItem>();
@@ -54,7 +51,7 @@ namespace GeometryTD.CustomComponent
Log.Info("EventNodeComponent initialized with {0} events.", _eventItems.Count);
}
public void StartEvent(string runId = null, int nodeId = 0, RunNodeType nodeType = RunNodeType.None, int sequenceIndex = -1)
public void StartEvent(RunNodeExecutionContext context = null)
{
if (!_initialized)
{
@@ -76,13 +73,16 @@ namespace GeometryTD.CustomComponent
return;
}
_activeRunId = runId;
_activeNodeId = nodeId;
_activeNodeType = nodeType;
_activeSequenceIndex = sequenceIndex;
_activeContext = context != null ? context.Clone() : null;
_eventFormUseCase.SetCurrentEvent(randomEvent);
GameEntry.UIRouter.OpenUI(UIFormType.EventForm);
GameEntry.Event.Fire(this, NodeEnterEventArgs.Create(runId, nodeId, nodeType, sequenceIndex));
GameEntry.Event.Fire(
this,
NodeEnterEventArgs.Create(
_activeContext?.RunId,
_activeContext?.NodeId ?? 0,
_activeContext?.NodeType ?? RunNodeType.None,
_activeContext?.SequenceIndex ?? -1));
}
public void EndEvent()
@@ -91,22 +91,22 @@ namespace GeometryTD.CustomComponent
GameEntry.Event.Fire(
this,
NodeCompleteEventArgs.Create(
_activeRunId,
_activeNodeId,
_activeNodeType,
_activeSequenceIndex,
_activeContext?.RunId,
_activeContext?.NodeId ?? 0,
_activeContext?.NodeType ?? RunNodeType.None,
_activeContext?.SequenceIndex ?? -1,
RunNodeCompletionStatus.Completed,
true,
GameEntry.PlayerInventory != null ? GameEntry.PlayerInventory.GetInventorySnapshot() : null));
_activeContext != null
? _activeContext.CreateCompletionSnapshot(
GameEntry.PlayerInventory != null ? GameEntry.PlayerInventory.GetInventorySnapshot() : null)
: null));
ClearActiveNodeContext();
}
private void ClearActiveNodeContext()
{
_activeRunId = null;
_activeNodeId = 0;
_activeNodeType = RunNodeType.None;
_activeSequenceIndex = -1;
_activeContext = null;
}
private static EventOption[] ParseOptions(string optionsRaw)
@@ -171,9 +171,9 @@ namespace GeometryTD.CustomComponent
}
float totalWeight = 0f;
for (int rarityIndex = 0; rarityIndex < _rarityWeightBuffer.Length; rarityIndex++)
foreach (var weight in _rarityWeightBuffer)
{
totalWeight += Mathf.Max(0f, _rarityWeightBuffer[rarityIndex]);
totalWeight += Mathf.Max(0f, weight);
}
if (totalWeight <= 0f)
@@ -8,11 +8,7 @@ namespace GeometryTD.CustomComponent
{
public class ShopNodeComponent : GameFrameworkComponent
{
private string _activeRunId;
private int _activeRunSeed;
private int _activeNodeId;
private RunNodeType _activeNodeType = RunNodeType.None;
private int _activeSequenceIndex = -1;
private RunNodeExecutionContext _activeContext;
private ShopFormUseCase _shopFormUseCase;
private bool _initialized;
@@ -29,26 +25,30 @@ namespace GeometryTD.CustomComponent
_initialized = true;
}
public void StartShop(string runId = null, int runSeed = 0, int nodeId = 0, RunNodeType nodeType = RunNodeType.None, int sequenceIndex = -1)
public void StartShop(RunNodeExecutionContext context = null)
{
if (!_initialized)
{
OnInit();
}
int runSeed = context?.RunSeed ?? 0;
int sequenceIndex = context?.SequenceIndex ?? -1;
if (_shopFormUseCase == null || !_shopFormUseCase.PrepareForOpen(runSeed, sequenceIndex))
{
Log.Warning("ShopNodeComponent.StartShop() failed. Shop use case is unavailable or goods generation failed.");
return;
}
_activeRunId = runId;
_activeRunSeed = runSeed;
_activeNodeId = nodeId;
_activeNodeType = nodeType;
_activeSequenceIndex = sequenceIndex;
_activeContext = context != null ? context.Clone() : null;
GameEntry.UIRouter.OpenUI(UIFormType.ShopForm);
GameEntry.Event.Fire(this, NodeEnterEventArgs.Create(runId, nodeId, nodeType, sequenceIndex));
GameEntry.Event.Fire(
this,
NodeEnterEventArgs.Create(
_activeContext?.RunId,
_activeContext?.NodeId ?? 0,
_activeContext?.NodeType ?? RunNodeType.None,
_activeContext?.SequenceIndex ?? -1));
}
public void EndShop()
@@ -57,23 +57,22 @@ namespace GeometryTD.CustomComponent
GameEntry.Event.Fire(
this,
NodeCompleteEventArgs.Create(
_activeRunId,
_activeNodeId,
_activeNodeType,
_activeSequenceIndex,
_activeContext?.RunId,
_activeContext?.NodeId ?? 0,
_activeContext?.NodeType ?? RunNodeType.None,
_activeContext?.SequenceIndex ?? -1,
RunNodeCompletionStatus.Completed,
true,
GameEntry.PlayerInventory != null ? GameEntry.PlayerInventory.GetInventorySnapshot() : null));
_activeContext != null
? _activeContext.CreateCompletionSnapshot(
GameEntry.PlayerInventory != null ? GameEntry.PlayerInventory.GetInventorySnapshot() : null)
: null));
ClearActiveNodeContext();
}
private void ClearActiveNodeContext()
{
_activeRunId = null;
_activeRunSeed = 0;
_activeNodeId = 0;
_activeNodeType = RunNodeType.None;
_activeSequenceIndex = -1;
_activeContext = null;
}
}
}
@@ -1,7 +1,5 @@
using GameFramework;
using GameFramework.Event;
using GeometryTD.CustomUtility;
using GeometryTD.Definition;
using GeometryTD.Procedure;
namespace GeometryTD.CustomEvent
@@ -24,7 +22,7 @@ namespace GeometryTD.CustomEvent
public bool CombatWon { get; private set; }
public BackpackInventoryData InventorySnapshotAfterNode { get; private set; }
public RunNodeCompletionSnapshot CompletionSnapshot { get; private set; }
public NodeCompleteEventArgs()
{
@@ -42,7 +40,7 @@ namespace GeometryTD.CustomEvent
int sequenceIndex,
RunNodeCompletionStatus completionStatus,
bool combatWon,
BackpackInventoryData inventorySnapshotAfterNode)
RunNodeCompletionSnapshot completionSnapshot)
{
var args = ReferencePool.Acquire<NodeCompleteEventArgs>();
args.RunId = runId;
@@ -51,7 +49,7 @@ namespace GeometryTD.CustomEvent
args.SequenceIndex = sequenceIndex;
args.CompletionStatus = completionStatus;
args.CombatWon = combatWon;
args.InventorySnapshotAfterNode = InventoryCloneUtility.CloneInventory(inventorySnapshotAfterNode);
args.CompletionSnapshot = completionSnapshot != null ? completionSnapshot.Clone() : null;
return args;
}
@@ -64,7 +62,7 @@ namespace GeometryTD.CustomEvent
SequenceIndex = -1;
CompletionStatus = RunNodeCompletionStatus.None;
CombatWon = false;
InventorySnapshotAfterNode = null;
CompletionSnapshot = null;
}
}
}
@@ -194,23 +194,36 @@ namespace GeometryTD.Procedure
args.CompletionStatus,
args.CombatWon);
BackpackInventoryData snapshot = args.InventorySnapshotAfterNode;
if (snapshot == null && GameEntry.PlayerInventory != null)
RunNodeCompletionSnapshot completionSnapshot = args.CompletionSnapshot != null
? args.CompletionSnapshot.Clone()
: _currentRunState?.CreateCurrentNodeContext()?.CreateCompletionSnapshot(null);
BackpackInventoryData inventorySnapshot = completionSnapshot?.InventorySnapshot;
if (inventorySnapshot == null && GameEntry.PlayerInventory != null)
{
snapshot = GameEntry.PlayerInventory.GetInventorySnapshot();
inventorySnapshot = GameEntry.PlayerInventory.GetInventorySnapshot();
}
if (completionSnapshot != null)
{
completionSnapshot.InventorySnapshot = inventorySnapshot;
}
ProcedureMainParticipantTowerCleanupResult cleanupResult =
ProcedureMainParticipantTowerCleanupService.RemoveBrokenParticipantTowers(
snapshot,
inventorySnapshot,
MaxParticipantTowerCount);
if (cleanupResult.HasAnyRemovedTower && GameEntry.PlayerInventory != null)
{
GameEntry.PlayerInventory.ReplaceInventorySnapshot(snapshot);
GameEntry.PlayerInventory.ReplaceInventorySnapshot(inventorySnapshot);
}
if (completionSnapshot != null)
{
completionSnapshot.InventorySnapshot = inventorySnapshot;
}
ProcedureMainRunAdvanceResult advanceResult =
ProcedureMainRunFlowService.TryAdvanceRun(_currentRunState, args.CompletionStatus, snapshot);
ProcedureMainRunFlowService.TryAdvanceRun(_currentRunState, args.CompletionStatus, completionSnapshot);
HandleRunAdvanceResult(advanceResult);
if (cleanupResult.HasAnyRemovedTower &&
advanceResult != ProcedureMainRunAdvanceResult.RunCompleted)
@@ -266,28 +279,20 @@ namespace GeometryTD.Procedure
return;
}
if (GameEntry.CombatNode.CurrentThemeType != currentNode.ThemeType)
{
GameEntry.CombatNode.OnInit(currentNode.ThemeType);
}
GameEntry.CombatNode.StartCombat(
currentNode.LinkedLevelId,
_currentRunState.RunId,
_currentRunState.RunSeed,
currentNode.NodeId,
currentNode.NodeType,
currentNode.SequenceIndex);
_currentRunState.CreateCurrentNodeContext());
return;
case RunNodeType.Event:
GameEntry.EventNode.StartEvent(
_currentRunState.RunId,
currentNode.NodeId,
currentNode.NodeType,
currentNode.SequenceIndex);
GameEntry.EventNode.StartEvent(_currentRunState.CreateCurrentNodeContext());
return;
case RunNodeType.Shop:
GameEntry.ShopNode.StartShop(
_currentRunState.RunId,
_currentRunState.RunSeed,
currentNode.NodeId,
currentNode.NodeType,
currentNode.SequenceIndex);
GameEntry.ShopNode.StartShop(_currentRunState.CreateCurrentNodeContext());
return;
default:
Log.Warning("ProcedureMain.OnNodeMapNodeEnterRequested() encountered unsupported node type: {0}.",
@@ -7,9 +7,9 @@ namespace GeometryTD.Procedure
public static ProcedureMainRunAdvanceResult TryAdvanceRun(
RunState runState,
RunNodeCompletionStatus completionStatus,
BackpackInventoryData snapshot)
RunNodeCompletionSnapshot completionSnapshot)
{
if (!RunStateAdvanceService.TryCompleteCurrentNode(runState, completionStatus, snapshot))
if (!RunStateAdvanceService.TryCompleteCurrentNode(runState, completionStatus, completionSnapshot))
{
return ProcedureMainRunAdvanceResult.NoChange;
}
@@ -24,4 +24,4 @@ namespace GeometryTD.Procedure
: ProcedureMainRunAdvanceResult.AdvancedToNextNode;
}
}
}
}
@@ -65,6 +65,96 @@ namespace GeometryTD.Procedure
}
}
[Serializable]
public sealed class RunItemState
{
public int ItemId { get; set; }
public int StackCount { get; set; }
internal RunItemState Clone()
{
return new RunItemState
{
ItemId = ItemId,
StackCount = StackCount
};
}
}
[Serializable]
public sealed class RunNodeExecutionContext
{
public string RunId { get; set; }
public int RunSeed { get; set; }
public int NodeId { get; set; }
public RunNodeType NodeType { get; set; }
public int SequenceIndex { get; set; }
public LevelThemeType ThemeType { get; set; }
public int ThemeStageIndex { get; set; }
public List<LevelThemeType> CurrentThemePool { get; set; } = new List<LevelThemeType>();
public List<LevelThemeType> ThemeHistory { get; set; } = new List<LevelThemeType>();
public int CurrentNodeContinueChallengeLayer { get; set; }
public List<RunItemState> RunItems { get; set; } = new List<RunItemState>();
internal RunNodeExecutionContext Clone()
{
return new RunNodeExecutionContext
{
RunId = RunId,
RunSeed = RunSeed,
NodeId = NodeId,
NodeType = NodeType,
SequenceIndex = SequenceIndex,
ThemeType = ThemeType,
ThemeStageIndex = ThemeStageIndex,
CurrentThemePool = RunStateCloneUtility.CloneThemeList(CurrentThemePool),
ThemeHistory = RunStateCloneUtility.CloneThemeList(ThemeHistory),
CurrentNodeContinueChallengeLayer = CurrentNodeContinueChallengeLayer,
RunItems = RunStateCloneUtility.CloneRunItems(RunItems)
};
}
public RunNodeCompletionSnapshot CreateCompletionSnapshot(BackpackInventoryData inventorySnapshot)
{
return new RunNodeCompletionSnapshot
{
InventorySnapshot = InventoryCloneUtility.CloneInventory(inventorySnapshot),
ThemeType = ThemeType,
ThemeStageIndex = ThemeStageIndex,
CurrentThemePool = RunStateCloneUtility.CloneThemeList(CurrentThemePool),
ThemeHistory = RunStateCloneUtility.CloneThemeList(ThemeHistory),
CurrentNodeContinueChallengeLayer = CurrentNodeContinueChallengeLayer,
RunItems = RunStateCloneUtility.CloneRunItems(RunItems)
};
}
}
[Serializable]
public sealed class RunNodeCompletionSnapshot
{
public BackpackInventoryData InventorySnapshot { get; set; }
public LevelThemeType ThemeType { get; set; }
public int ThemeStageIndex { get; set; }
public List<LevelThemeType> CurrentThemePool { get; set; } = new List<LevelThemeType>();
public List<LevelThemeType> ThemeHistory { get; set; } = new List<LevelThemeType>();
public int CurrentNodeContinueChallengeLayer { get; set; }
public List<RunItemState> RunItems { get; set; } = new List<RunItemState>();
internal RunNodeCompletionSnapshot Clone()
{
return new RunNodeCompletionSnapshot
{
InventorySnapshot = InventoryCloneUtility.CloneInventory(InventorySnapshot),
ThemeType = ThemeType,
ThemeStageIndex = ThemeStageIndex,
CurrentThemePool = RunStateCloneUtility.CloneThemeList(CurrentThemePool),
ThemeHistory = RunStateCloneUtility.CloneThemeList(ThemeHistory),
CurrentNodeContinueChallengeLayer = CurrentNodeContinueChallengeLayer,
RunItems = RunStateCloneUtility.CloneRunItems(RunItems)
};
}
}
[Serializable]
public sealed class RunState
{
@@ -82,6 +172,11 @@ namespace GeometryTD.Procedure
ThemeType = themeType;
_nodes = nodes ?? new List<RunNodeState>();
RunInventorySnapshot = InventoryCloneUtility.CloneInventory(runInventorySnapshot);
ThemeStageIndex = 0;
CurrentThemePool = CreateDefaultThemeList(themeType);
ThemeHistory = CreateDefaultThemeList(themeType);
CurrentNodeContinueChallengeLayer = 0;
RunItems = new List<RunItemState>();
CurrentNodeIndex = _nodes.Count > 0 ? 0 : -1;
IsCompleted = _nodes.Count <= 0;
}
@@ -98,6 +193,16 @@ namespace GeometryTD.Procedure
public BackpackInventoryData RunInventorySnapshot { get; internal set; }
public int ThemeStageIndex { get; internal set; }
public List<LevelThemeType> CurrentThemePool { get; internal set; }
public List<LevelThemeType> ThemeHistory { get; internal set; }
public int CurrentNodeContinueChallengeLayer { get; internal set; }
public List<RunItemState> RunItems { get; internal set; }
public IReadOnlyList<RunNodeState> Nodes => _nodes;
public int NodeCount => _nodes.Count;
@@ -161,5 +266,90 @@ namespace GeometryTD.Procedure
{
RunInventorySnapshot = InventoryCloneUtility.CloneInventory(inventorySnapshot);
}
public RunNodeExecutionContext CreateCurrentNodeContext()
{
RunNodeState currentNode = CurrentNode;
if (currentNode == null)
{
return null;
}
return new RunNodeExecutionContext
{
RunId = RunId,
RunSeed = RunSeed,
NodeId = currentNode.NodeId,
NodeType = currentNode.NodeType,
SequenceIndex = currentNode.SequenceIndex,
ThemeType = ThemeType,
ThemeStageIndex = ThemeStageIndex,
CurrentThemePool = RunStateCloneUtility.CloneThemeList(CurrentThemePool),
ThemeHistory = RunStateCloneUtility.CloneThemeList(ThemeHistory),
CurrentNodeContinueChallengeLayer = CurrentNodeContinueChallengeLayer,
RunItems = RunStateCloneUtility.CloneRunItems(RunItems)
};
}
public void ApplyCompletionSnapshot(RunNodeCompletionSnapshot completionSnapshot)
{
RunInventorySnapshot = InventoryCloneUtility.CloneInventory(completionSnapshot.InventorySnapshot);
ThemeType = completionSnapshot.ThemeType;
ThemeStageIndex = completionSnapshot.ThemeStageIndex;
CurrentThemePool = RunStateCloneUtility.CloneThemeList(completionSnapshot.CurrentThemePool);
ThemeHistory = RunStateCloneUtility.CloneThemeList(completionSnapshot.ThemeHistory);
CurrentNodeContinueChallengeLayer = completionSnapshot.CurrentNodeContinueChallengeLayer;
RunItems = RunStateCloneUtility.CloneRunItems(completionSnapshot.RunItems);
}
private static List<LevelThemeType> CreateDefaultThemeList(LevelThemeType themeType)
{
List<LevelThemeType> themes = new List<LevelThemeType>();
if (themeType != LevelThemeType.None)
{
themes.Add(themeType);
}
return themes;
}
}
internal static class RunStateCloneUtility
{
internal static List<LevelThemeType> CloneThemeList(IReadOnlyList<LevelThemeType> source)
{
List<LevelThemeType> cloned = new List<LevelThemeType>();
if (source == null)
{
return cloned;
}
for (int i = 0; i < source.Count; i++)
{
cloned.Add(source[i]);
}
return cloned;
}
internal static List<RunItemState> CloneRunItems(IReadOnlyList<RunItemState> source)
{
List<RunItemState> cloned = new List<RunItemState>();
if (source == null)
{
return cloned;
}
for (int i = 0; i < source.Count; i++)
{
RunItemState item = source[i];
if (item != null)
{
cloned.Add(item.Clone());
}
}
return cloned;
}
}
}
@@ -1,5 +1,3 @@
using GeometryTD.Definition;
namespace GeometryTD.Procedure
{
public static class RunStateAdvanceService
@@ -7,7 +5,7 @@ namespace GeometryTD.Procedure
public static bool TryCompleteCurrentNode(
RunState runState,
RunNodeCompletionStatus completionStatus,
BackpackInventoryData inventorySnapshotAfterNode)
RunNodeCompletionSnapshot completionSnapshot)
{
if (runState == null || runState.IsCompleted)
{
@@ -20,7 +18,7 @@ namespace GeometryTD.Procedure
return false;
}
runState.ReplaceInventorySnapshot(inventorySnapshotAfterNode);
runState.ApplyCompletionSnapshot(completionSnapshot);
if (completionStatus == RunNodeCompletionStatus.Exception)
{
@@ -38,12 +36,14 @@ namespace GeometryTD.Procedure
int nextIndex = runState.CurrentNodeIndex + 1;
if (nextIndex >= runState.Nodes.Count)
{
runState.CurrentNodeContinueChallengeLayer = 0;
runState.CurrentNodeIndex = runState.Nodes.Count;
runState.IsCompleted = true;
return true;
}
runState.CurrentNodeIndex = nextIndex;
runState.CurrentNodeContinueChallengeLayer = 0;
RunNodeState nextNode = runState.CurrentNode;
if (nextNode != null && nextNode.Status == RunNodeStatus.Locked)
{