A1 + A2
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user