A1 + A2
This commit is contained in:
@@ -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;
|
||||
|
||||
+4
-12
@@ -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);
|
||||
|
||||
+19
-15
@@ -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)
|
||||
|
||||
+1
-5
@@ -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; }
|
||||
}
|
||||
|
||||
+2
-2
@@ -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,
|
||||
|
||||
+5
-4
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user