214 lines
7.7 KiB
C#
214 lines
7.7 KiB
C#
using GameFramework.Event;
|
|
using GameFramework.Fsm;
|
|
using GameFramework.Procedure;
|
|
using GeometryTD.CustomEvent;
|
|
using GeometryTD.Definition;
|
|
using GeometryTD.UI;
|
|
using UnityGameFramework.Runtime;
|
|
|
|
namespace GeometryTD.Procedure
|
|
{
|
|
public class ProcedureMain : ProcedureBase
|
|
{
|
|
public override bool UseNativeDialog => false;
|
|
|
|
private RepoFormUseCase _repoFormUseCase;
|
|
private NodeMapFormUseCase _nodeMapFormUseCase;
|
|
private RunState _currentRunState;
|
|
|
|
#region FSM
|
|
|
|
protected override void OnEnter(IFsm<IProcedureManager> procedureOwner)
|
|
{
|
|
base.OnEnter(procedureOwner);
|
|
|
|
GameEntry.Event.Subscribe(CombatFailureReturnEventArgs.EventId, OnCombatFailureReturn);
|
|
GameEntry.Event.Subscribe(NodeCompleteEventArgs.EventId, OnNodeComplete);
|
|
GameEntry.Event.Subscribe(NodeEnterEventArgs.EventId, OnNodeEnter);
|
|
GameEntry.Event.Subscribe(NodeMapNodeEnterRequestedEventArgs.EventId, OnNodeMapNodeEnterRequested);
|
|
|
|
GameEntry.EventNode.OnInit();
|
|
GameEntry.CombatNode.OnInit(LevelThemeType.Plain);
|
|
GameEntry.ShopNode.OnInit();
|
|
GameEntry.PlayerInventory?.OnInit();
|
|
|
|
_currentRunState = RunStateFactory.CreateFixedRun(
|
|
LevelThemeType.Plain,
|
|
GameEntry.PlayerInventory != null
|
|
? GameEntry.PlayerInventory.GetInventorySnapshot()
|
|
: null);
|
|
|
|
_repoFormUseCase = new RepoFormUseCase();
|
|
GameEntry.UIRouter.BindUIUseCase(UIFormType.RepoForm, _repoFormUseCase);
|
|
|
|
_nodeMapFormUseCase = new NodeMapFormUseCase();
|
|
_nodeMapFormUseCase.SetRunState(_currentRunState);
|
|
GameEntry.UIRouter.BindUIUseCase(UIFormType.NodeMapForm, _nodeMapFormUseCase);
|
|
|
|
OpenHubUI();
|
|
}
|
|
|
|
protected override void OnUpdate(IFsm<IProcedureManager> procedureOwner, float elapseSeconds,
|
|
float realElapseSeconds)
|
|
{
|
|
base.OnUpdate(procedureOwner, elapseSeconds, realElapseSeconds);
|
|
|
|
GameEntry.CombatNode.OnUpdate(elapseSeconds, realElapseSeconds);
|
|
}
|
|
|
|
protected override void OnLeave(IFsm<IProcedureManager> procedureOwner, bool isShutdown)
|
|
{
|
|
GameEntry.CombatNode.OnShutdown();
|
|
GameEntry.Event.Unsubscribe(NodeMapNodeEnterRequestedEventArgs.EventId, OnNodeMapNodeEnterRequested);
|
|
GameEntry.Event.Unsubscribe(CombatFailureReturnEventArgs.EventId, OnCombatFailureReturn);
|
|
GameEntry.Event.Unsubscribe(NodeEnterEventArgs.EventId, OnNodeEnter);
|
|
GameEntry.Event.Unsubscribe(NodeCompleteEventArgs.EventId, OnNodeComplete);
|
|
GameEntry.UIRouter.CloseUI(UIFormType.RepoForm);
|
|
GameEntry.UIRouter.CloseUI(UIFormType.NodeMapForm);
|
|
GameEntry.UIRouter.CloseUI(UIFormType.MainForm);
|
|
_repoFormUseCase = null;
|
|
_nodeMapFormUseCase = null;
|
|
_currentRunState = null;
|
|
|
|
base.OnLeave(procedureOwner, isShutdown);
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
private void OnNodeEnter(object sender, GameEventArgs e)
|
|
{
|
|
if (!(e is NodeEnterEventArgs))
|
|
{
|
|
return;
|
|
}
|
|
|
|
GameEntry.UIRouter.CloseUI(UIFormType.NodeMapForm);
|
|
GameEntry.UIRouter.CloseUI(UIFormType.MainForm);
|
|
}
|
|
|
|
private void OnNodeComplete(object sender, GameEventArgs e)
|
|
{
|
|
if (!(e is NodeCompleteEventArgs args))
|
|
{
|
|
return;
|
|
}
|
|
|
|
BackpackInventoryData snapshot = args.InventorySnapshotAfterNode;
|
|
if (snapshot == null && GameEntry.PlayerInventory != null)
|
|
{
|
|
snapshot = GameEntry.PlayerInventory.GetInventorySnapshot();
|
|
}
|
|
|
|
AdvanceRunState(true, snapshot);
|
|
OpenHubUI();
|
|
}
|
|
|
|
private void OnCombatFailureReturn(object sender, GameEventArgs e)
|
|
{
|
|
if (!(e is CombatFailureReturnEventArgs))
|
|
{
|
|
return;
|
|
}
|
|
|
|
BackpackInventoryData snapshot = GameEntry.PlayerInventory != null
|
|
? GameEntry.PlayerInventory.GetInventorySnapshot()
|
|
: null;
|
|
AdvanceRunState(false, snapshot);
|
|
OpenHubUI();
|
|
}
|
|
|
|
private void OnNodeMapNodeEnterRequested(object sender, GameEventArgs e)
|
|
{
|
|
if (!(sender is NodeMapForm) || !(e is NodeMapNodeEnterRequestedEventArgs args))
|
|
{
|
|
return;
|
|
}
|
|
|
|
RunNodeState currentNode = _currentRunState?.CurrentNode;
|
|
if (_currentRunState == null || !_currentRunState.CanEnterCurrentNode || currentNode == null)
|
|
{
|
|
Log.Warning("ProcedureMain.OnNodeMapNodeEnterRequested() ignored. Current run has no enterable node.");
|
|
return;
|
|
}
|
|
|
|
if (args.SequenceIndex != currentNode.SequenceIndex || args.NodeType != currentNode.NodeType)
|
|
{
|
|
Log.Warning(
|
|
"ProcedureMain.OnNodeMapNodeEnterRequested() ignored. Requested={0}#{1}, CurrentNode={2}#{3}.",
|
|
args.NodeType,
|
|
args.SequenceIndex,
|
|
currentNode.NodeType,
|
|
currentNode.SequenceIndex);
|
|
return;
|
|
}
|
|
|
|
switch (currentNode.NodeType)
|
|
{
|
|
case RunNodeType.Combat:
|
|
case RunNodeType.BossCombat:
|
|
if (!HasAvailableParticipantTower())
|
|
{
|
|
Log.Warning("ProcedureMain blocked combat start. No participant tower is available.");
|
|
return;
|
|
}
|
|
|
|
GameEntry.CombatNode.StartCombat(currentNode.LinkedLevelId);
|
|
return;
|
|
case RunNodeType.Event:
|
|
GameEntry.EventNode.StartEvent();
|
|
return;
|
|
case RunNodeType.Shop:
|
|
GameEntry.ShopNode.StartShop();
|
|
return;
|
|
default:
|
|
Log.Warning("ProcedureMain.OnNodeMapNodeEnterRequested() encountered unsupported node type: {0}.", currentNode.NodeType);
|
|
return;
|
|
}
|
|
}
|
|
|
|
private void AdvanceRunState(bool succeeded, BackpackInventoryData snapshot)
|
|
{
|
|
if (_currentRunState == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!RunStateAdvanceService.TryCompleteCurrentNode(_currentRunState, succeeded, snapshot))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (_currentRunState.IsCompleted)
|
|
{
|
|
Log.Info("ProcedureMain run completed. RunId={0}", _currentRunState.RunId);
|
|
return;
|
|
}
|
|
|
|
RunNodeState nextNode = _currentRunState.CurrentNode;
|
|
if (nextNode != null)
|
|
{
|
|
Log.Info(
|
|
"ProcedureMain advanced run. RunId={0}, NextNodeType={1}, SequenceIndex={2}, LevelId={3}.",
|
|
_currentRunState.RunId,
|
|
nextNode.NodeType,
|
|
nextNode.SequenceIndex,
|
|
nextNode.LinkedLevelId);
|
|
}
|
|
}
|
|
|
|
private static bool HasAvailableParticipantTower()
|
|
{
|
|
return GameEntry.PlayerInventory != null &&
|
|
GameEntry.PlayerInventory.GetParticipantTowerSnapshot().Count > 0;
|
|
}
|
|
|
|
private void OpenHubUI()
|
|
{
|
|
_nodeMapFormUseCase?.SetRunState(_currentRunState);
|
|
GameEntry.UIRouter.OpenUI(UIFormType.MainForm);
|
|
GameEntry.UIRouter.OpenUI(UIFormType.NodeMapForm);
|
|
}
|
|
}
|
|
}
|