biography-of-lijie/Assets/GameMain/Scripts/Procedure/ProcedureMain.cs

166 lines
5.0 KiB
C#

using DataTable;
using Definition.Enum;
using Event;
using GameFramework.DataTable;
using GameFramework.Event;
using GameFramework.Fsm;
using GameFramework.Procedure;
using UI;
using UnityGameFramework.Runtime;
namespace Procedure
{
public class ProcedureMain : ProcedureBase
{
private const int InitialChapterId = 1;
private const int InitialDialogId = 1001;
private const int DialogChapterDivisor = 1000;
private IDataTable<DRDialog> _dtDialog;
private bool _pendingSceneChange;
private int _pendingSceneId;
public override bool UseNativeDialog => false;
protected override void OnEnter(IFsm<IProcedureManager> procedureOwner)
{
base.OnEnter(procedureOwner);
AIChatEntryRuntime.EnsureOpen();
GameEntry.Event.Subscribe(StoryChapterEndedEventArgs.EventId, OnStoryChapterEnded);
_pendingSceneChange = false;
_pendingSceneId = 0;
GameEntry.Dialog.Init(InitialChapterId);
GameEntry.Dialog.StartDialog(InitialDialogId);
}
protected override void OnLeave(IFsm<IProcedureManager> procedureOwner, bool isShutdown)
{
GameEntry.Event.Unsubscribe(StoryChapterEndedEventArgs.EventId, OnStoryChapterEnded);
base.OnLeave(procedureOwner, isShutdown);
}
protected override void OnUpdate(IFsm<IProcedureManager> procedureOwner, float elapseSeconds,
float realElapseSeconds)
{
base.OnUpdate(procedureOwner, elapseSeconds, realElapseSeconds);
if (!_pendingSceneChange)
{
return;
}
_pendingSceneChange = false;
procedureOwner.SetData<VarInt32>("NextSceneId", _pendingSceneId);
ChangeState<ProcedureChangeScene>(procedureOwner);
}
private void OnStoryChapterEnded(object sender, GameEventArgs e)
{
if (!(e is StoryChapterEndedEventArgs args))
{
return;
}
int currentChapterId = args.ChapterId > 0
? args.ChapterId
: (GameEntry.Dialog != null ? GameEntry.Dialog.CurrentChapterId : 0);
int nextChapterId = currentChapterId + 1;
if (nextChapterId <= 0)
{
return;
}
if (!TryResolveFirstDialogId(nextChapterId, out int nextDialogId))
{
Log.Info(
"ProcedureMain chapter '{0}' ended and no next chapter found. Return to menu scene.",
currentChapterId.ToString());
CloseBgFormIfOpened();
_pendingSceneId = (int)SceneId.Menu;
_pendingSceneChange = true;
return;
}
if (GameEntry.Dialog == null)
{
Log.Warning("ProcedureMain chapter switch failed. Dialog component is missing.");
return;
}
if (!GameEntry.Dialog.Init(nextChapterId))
{
Log.Warning("ProcedureMain chapter switch failed. Init chapter '{0}' failed.",
nextChapterId.ToString());
return;
}
if (!GameEntry.Dialog.StartDialog(nextDialogId))
{
Log.Warning("ProcedureMain chapter switch failed. Start dialog '{0}' failed.",
nextDialogId.ToString());
}
}
private bool TryResolveFirstDialogId(int chapterId, out int dialogId)
{
dialogId = 0;
if (chapterId <= 0)
{
return false;
}
if (_dtDialog == null)
{
_dtDialog = GameEntry.DataTable.GetDataTable<DRDialog>();
}
if (_dtDialog == null)
{
Log.Warning("ProcedureMain chapter switch failed. Data table DRDialog is missing.");
return false;
}
DRDialog[] dialogRows = _dtDialog.GetDataRows((a, b) => a.Id.CompareTo(b.Id));
for (int i = 0; i < dialogRows.Length; i++)
{
DRDialog row = dialogRows[i];
if (row == null)
{
continue;
}
if (ParseChapterIdFromDialogId(row.Id) != chapterId)
{
continue;
}
dialogId = row.Id;
return dialogId > 0;
}
return false;
}
private static int ParseChapterIdFromDialogId(int dialogId)
{
return dialogId / DialogChapterDivisor;
}
private static void CloseBgFormIfOpened()
{
if (GameEntry.UI == null)
{
return;
}
UGuiForm bgForm = GameEntry.UI.GetUIForm(UIFormId.BgForm);
if (bgForm != null)
{
GameEntry.UI.CloseUIForm(bgForm.UIForm);
}
}
}
}