683 lines
22 KiB
C#
683 lines
22 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using DataTable;
|
||
using Definition;
|
||
using Definition.Enum;
|
||
using Event;
|
||
using GameFramework.DataTable;
|
||
using GameFramework.Event;
|
||
using UI;
|
||
using UnityEngine;
|
||
using UnityGameFramework.Runtime;
|
||
|
||
namespace CustomComponent
|
||
{
|
||
[DisallowMultipleComponent]
|
||
public class DialogComponent : GameFrameworkComponent
|
||
{
|
||
[Serializable]
|
||
private sealed class SpeakerPortraitBinding
|
||
{
|
||
[SerializeField] private string _speakerId = string.Empty;
|
||
[SerializeField] private List<Sprite> _portraits = new List<Sprite>();
|
||
|
||
public string SpeakerId => _speakerId;
|
||
public List<Sprite> Portraits => _portraits;
|
||
}
|
||
|
||
#region Property
|
||
|
||
private const int DialogChapterDivisor = 1000;
|
||
private const int LineChapterDivisor = 100000000;
|
||
private const int LineDialogDivisor = 100000;
|
||
|
||
[Header("角色立绘配置(拖拽 Sprite)")]
|
||
[SerializeField] private List<SpeakerPortraitBinding> _speakerPortraitBindings = new List<SpeakerPortraitBinding>();
|
||
|
||
private readonly Dictionary<int, DRDialog> _dialogMap = new();
|
||
|
||
private readonly Dictionary<int, List<DRDialogLine>> _dialogLinesMap = new();
|
||
|
||
private readonly Dictionary<int, int> _dialogFirstLineIdMap = new();
|
||
private static readonly HashSet<string> NonPortraitSpeakerIds = new(System.StringComparer.OrdinalIgnoreCase)
|
||
{
|
||
"Other",
|
||
"Subtitle",
|
||
"Time"
|
||
};
|
||
|
||
private IDataTable<DRDialog> _dtDialog;
|
||
private IDataTable<DRDialogLine> _dtDialogLine;
|
||
private DialogFormController _formController;
|
||
private DialogFormContext _formContext;
|
||
private int _pendingStartDialogId;
|
||
private int _activeChapterTitleRequestId;
|
||
private int _nextChapterTitleRequestId = 1;
|
||
private bool _chapterTitleShownAfterInit;
|
||
|
||
[Header("章节标题过场")]
|
||
[SerializeField] [Min(0f)] private float _chapterTitleDimFadeInDuration = 0.2f;
|
||
[SerializeField] [Min(0f)] private float _chapterTitlePreBlackDuration = 0.25f;
|
||
[SerializeField] [Min(0f)] private float _chapterTitleTitleFadeInDelay = 0f;
|
||
[SerializeField] [Min(0f)] private float _chapterTitleFadeInDuration = 0.3f;
|
||
[SerializeField] [Min(0f)] private float _chapterTitleHoldDuration = 1.2f;
|
||
[SerializeField] [Min(0f)] private float _chapterTitleFadeOutDuration = 0.3f;
|
||
[SerializeField] [Min(0f)] private float _chapterTitleDimFadeOutDuration = 0.2f;
|
||
|
||
private int _currentChapterId;
|
||
private int _currentLineIndex = -1;
|
||
private bool _isInitialized;
|
||
private bool _isPlaying;
|
||
|
||
public bool IsInitialized => _isInitialized;
|
||
|
||
public bool IsPlaying => _isPlaying;
|
||
|
||
public int CurrentChapterId => _currentChapterId;
|
||
|
||
public int CurrentDialogId => _formContext != null ? _formContext.DialogId : 0;
|
||
|
||
public int CurrentLineId => _formContext != null ? _formContext.CurrentLineId : 0;
|
||
|
||
public int GetSpeakerPortraitCount(string speakerId)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(speakerId))
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
SpeakerPortraitBinding binding = FindSpeakerPortraitBinding(speakerId);
|
||
if (binding == null || binding.Portraits == null)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
int validCount = 0;
|
||
for (int i = 0; i < binding.Portraits.Count; i++)
|
||
{
|
||
if (binding.Portraits[i] != null)
|
||
{
|
||
validCount++;
|
||
}
|
||
}
|
||
|
||
return validCount;
|
||
}
|
||
|
||
#endregion
|
||
|
||
|
||
private void Start()
|
||
{
|
||
GameEntry.Event.Subscribe(DialogNextLineRequestEventArgs.EventId, OnDialogNextLineRequest);
|
||
GameEntry.Event.Subscribe(DialogSkipRequestEventArgs.EventId, OnDialogSkipRequest);
|
||
GameEntry.Event.Subscribe(DialogStopRequestEventArgs.EventId, OnDialogStopRequest);
|
||
GameEntry.Event.Subscribe(ChapterTitleCompletedEventArgs.EventId, OnChapterTitleCompleted);
|
||
}
|
||
|
||
private void OnDestroy()
|
||
{
|
||
GameEntry.Event.Unsubscribe(DialogNextLineRequestEventArgs.EventId, OnDialogNextLineRequest);
|
||
GameEntry.Event.Unsubscribe(DialogSkipRequestEventArgs.EventId, OnDialogSkipRequest);
|
||
GameEntry.Event.Unsubscribe(DialogStopRequestEventArgs.EventId, OnDialogStopRequest);
|
||
GameEntry.Event.Unsubscribe(ChapterTitleCompletedEventArgs.EventId, OnChapterTitleCompleted);
|
||
}
|
||
|
||
public bool Init(int chapterId)
|
||
{
|
||
if (chapterId <= 0)
|
||
{
|
||
Log.Warning("Dialog init failed. chapterId must be positive.");
|
||
return false;
|
||
}
|
||
|
||
if (!EnsureDataTables())
|
||
{
|
||
return false;
|
||
}
|
||
|
||
StopDialog();
|
||
_dialogMap.Clear();
|
||
_dialogLinesMap.Clear();
|
||
_dialogFirstLineIdMap.Clear();
|
||
|
||
DRDialog[] dialogRows = _dtDialog.GetDataRows((a, b) => a.Id.CompareTo(b.Id));
|
||
for (int i = 0; i < dialogRows.Length; i++)
|
||
{
|
||
DRDialog dialogRow = dialogRows[i];
|
||
if (dialogRow == null)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
if (ParseChapterIdFromDialogId(dialogRow.Id) != chapterId)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
_dialogMap[dialogRow.Id] = dialogRow;
|
||
}
|
||
|
||
if (_dialogMap.Count == 0)
|
||
{
|
||
Log.Warning("Dialog init failed. No dialog rows found for chapter '{0}'.", chapterId.ToString());
|
||
return false;
|
||
}
|
||
|
||
DRDialogLine[] lineRows = _dtDialogLine.GetDataRows((a, b) => a.Id.CompareTo(b.Id));
|
||
foreach (var lineRow in lineRows)
|
||
{
|
||
if (lineRow == null)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
if (ParseChapterIdFromLineId(lineRow.Id) != chapterId)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
int dialogId = ParseDialogIdFromLineId(lineRow.Id);
|
||
if (!_dialogMap.ContainsKey(dialogId))
|
||
{
|
||
continue;
|
||
}
|
||
|
||
if (!_dialogLinesMap.TryGetValue(dialogId, out List<DRDialogLine> dialogLines))
|
||
{
|
||
dialogLines = new List<DRDialogLine>();
|
||
_dialogLinesMap.Add(dialogId, dialogLines);
|
||
}
|
||
|
||
dialogLines.Add(lineRow);
|
||
}
|
||
|
||
List<int> invalidDialogIds = new List<int>();
|
||
foreach (var dialogPair in _dialogMap)
|
||
{
|
||
if (!_dialogLinesMap.TryGetValue(dialogPair.Key, out List<DRDialogLine> dialogLines) ||
|
||
dialogLines.Count == 0)
|
||
{
|
||
Log.Warning("Dialog init warning. Dialog '{0}' has no lines and will be ignored.",
|
||
dialogPair.Key.ToString());
|
||
invalidDialogIds.Add(dialogPair.Key);
|
||
continue;
|
||
}
|
||
|
||
dialogLines.Sort((a, b) => a.Id.CompareTo(b.Id));
|
||
_dialogFirstLineIdMap[dialogPair.Key] = dialogLines[0].Id;
|
||
}
|
||
|
||
foreach (var id in invalidDialogIds)
|
||
{
|
||
_dialogMap.Remove(id);
|
||
}
|
||
|
||
if (_dialogMap.Count == 0)
|
||
{
|
||
Log.Warning("Dialog init failed. No valid dialog remains for chapter '{0}'.", chapterId.ToString());
|
||
return false;
|
||
}
|
||
|
||
PreloadChapterPortraitSprites();
|
||
EnsureFormController();
|
||
_formContext = null;
|
||
_currentChapterId = chapterId;
|
||
_currentLineIndex = -1;
|
||
_pendingStartDialogId = 0;
|
||
_activeChapterTitleRequestId = 0;
|
||
_chapterTitleShownAfterInit = false;
|
||
_isInitialized = true;
|
||
_isPlaying = false;
|
||
return true;
|
||
}
|
||
|
||
public bool StartDialog(int dialogId)
|
||
{
|
||
if (!_isInitialized)
|
||
{
|
||
Log.Warning("Start dialog failed. Dialog component is not initialized.");
|
||
return false;
|
||
}
|
||
|
||
if (ParseChapterIdFromDialogId(dialogId) != _currentChapterId)
|
||
{
|
||
Log.Warning("Start dialog failed. Dialog '{0}' does not belong to chapter '{1}'.", dialogId.ToString(),
|
||
_currentChapterId.ToString());
|
||
return false;
|
||
}
|
||
|
||
if (!_dialogMap.TryGetValue(dialogId, out DRDialog dialogRow))
|
||
{
|
||
Log.Warning("Start dialog failed. Dialog '{0}' was not found in current chapter cache.",
|
||
dialogId.ToString());
|
||
return false;
|
||
}
|
||
|
||
if (!_dialogLinesMap.TryGetValue(dialogId, out List<DRDialogLine> dialogLines) || dialogLines.Count == 0)
|
||
{
|
||
Log.Warning("Start dialog failed. Dialog '{0}' has no playable lines.", dialogId.ToString());
|
||
return false;
|
||
}
|
||
|
||
if (_activeChapterTitleRequestId > 0)
|
||
{
|
||
_pendingStartDialogId = dialogId;
|
||
return true;
|
||
}
|
||
|
||
if (!_chapterTitleShownAfterInit)
|
||
{
|
||
_chapterTitleShownAfterInit = true;
|
||
_pendingStartDialogId = dialogId;
|
||
if (TryOpenChapterTitle(dialogRow))
|
||
{
|
||
return true;
|
||
}
|
||
|
||
_pendingStartDialogId = 0;
|
||
}
|
||
|
||
if (_isPlaying)
|
||
{
|
||
StopDialog();
|
||
}
|
||
|
||
EnsureFormController();
|
||
if (_formContext == null)
|
||
{
|
||
_formContext = new DialogFormContext();
|
||
}
|
||
|
||
_formContext.ChapterId = _currentChapterId;
|
||
_formContext.DialogId = dialogRow.Id;
|
||
_formContext.DialogTitle = dialogRow.Title;
|
||
_formContext.DialogUIMode = dialogRow.UIMode;
|
||
_formContext.PlayingSpeed =
|
||
(DialogPlayingSpeed)GameEntry.Setting.GetInt(Constant.Setting.DialogPlayingSpeed);
|
||
_formContext.DialogWindowAlpha =
|
||
(DialogWindowAlpha)GameEntry.Setting.GetInt(Constant.Setting.DialogWindowAlpha);
|
||
|
||
_currentLineIndex = 0;
|
||
ApplyLineToContext(dialogLines[_currentLineIndex], _currentLineIndex, dialogLines.Count);
|
||
_isPlaying = true;
|
||
|
||
_formController.OpenUI(_formContext);
|
||
_formController.OnDialogStarted(_formContext);
|
||
_formController.OnDialogLineChanged(_formContext);
|
||
return true;
|
||
}
|
||
|
||
public bool NextLine()
|
||
{
|
||
if (!_isPlaying)
|
||
{
|
||
Log.Warning("Next line failed. No dialog is playing.");
|
||
return false;
|
||
}
|
||
|
||
if (!TryGetCurrentDialogLines(out List<DRDialogLine> dialogLines))
|
||
{
|
||
StopDialog();
|
||
return false;
|
||
}
|
||
|
||
int nextLineIndex = _currentLineIndex + 1;
|
||
if (nextLineIndex >= dialogLines.Count)
|
||
{
|
||
EndDialogInternal();
|
||
return true;
|
||
}
|
||
|
||
_currentLineIndex = nextLineIndex;
|
||
ApplyLineToContext(dialogLines[_currentLineIndex], _currentLineIndex, dialogLines.Count);
|
||
_formController.OnDialogLineChanged(_formContext);
|
||
return true;
|
||
}
|
||
|
||
public bool SkipDialog()
|
||
{
|
||
if (!_isPlaying)
|
||
{
|
||
Log.Warning("Skip dialog failed. No dialog is playing.");
|
||
return false;
|
||
}
|
||
|
||
EndDialogInternal();
|
||
return true;
|
||
}
|
||
|
||
public void StopDialog()
|
||
{
|
||
_pendingStartDialogId = 0;
|
||
|
||
if (_activeChapterTitleRequestId > 0)
|
||
{
|
||
_activeChapterTitleRequestId = 0;
|
||
if (GameEntry.UI != null)
|
||
{
|
||
UGuiForm chapterTitleForm = GameEntry.UI.GetUIForm(UIFormId.ChapterTitleForm);
|
||
if (chapterTitleForm != null)
|
||
{
|
||
GameEntry.UI.CloseUIForm(chapterTitleForm.UIForm);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (!_isPlaying)
|
||
{
|
||
return;
|
||
}
|
||
|
||
EndDialogInternal();
|
||
}
|
||
|
||
public void ClearRuntimeContext()
|
||
{
|
||
StopDialog();
|
||
|
||
_dialogMap.Clear();
|
||
_dialogLinesMap.Clear();
|
||
_dialogFirstLineIdMap.Clear();
|
||
|
||
_formContext = null;
|
||
_currentChapterId = 0;
|
||
_currentLineIndex = -1;
|
||
_pendingStartDialogId = 0;
|
||
_activeChapterTitleRequestId = 0;
|
||
_chapterTitleShownAfterInit = false;
|
||
_isInitialized = false;
|
||
_isPlaying = false;
|
||
}
|
||
|
||
private bool EnsureDataTables()
|
||
{
|
||
_dtDialog = GameEntry.DataTable.GetDataTable<DRDialog>();
|
||
if (_dtDialog == null)
|
||
{
|
||
Log.Warning("Dialog init failed. Data table DRDialog is missing.");
|
||
return false;
|
||
}
|
||
|
||
_dtDialogLine = GameEntry.DataTable.GetDataTable<DRDialogLine>();
|
||
if (_dtDialogLine == null)
|
||
{
|
||
Log.Warning("Dialog init failed. Data table DRDialogLine is missing.");
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
private void EnsureFormController()
|
||
{
|
||
if (_formController == null)
|
||
{
|
||
_formController = new DialogFormController();
|
||
}
|
||
}
|
||
|
||
private bool TryGetCurrentDialogLines(out List<DRDialogLine> dialogLines)
|
||
{
|
||
dialogLines = null;
|
||
if (_formContext == null)
|
||
{
|
||
Log.Warning("Dialog state invalid. Form context is null.");
|
||
return false;
|
||
}
|
||
|
||
if (!_dialogLinesMap.TryGetValue(_formContext.DialogId, out dialogLines))
|
||
{
|
||
Log.Warning("Dialog state invalid. Dialog lines are missing for dialog '{0}'.",
|
||
_formContext.DialogId.ToString());
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
private void EndDialogInternal()
|
||
{
|
||
int chapterId = _formContext != null ? _formContext.ChapterId : _currentChapterId;
|
||
int dialogId = _formContext != null ? _formContext.DialogId : 0;
|
||
int lineId = _formContext != null ? _formContext.CurrentLineId : 0;
|
||
|
||
_isPlaying = false;
|
||
_currentLineIndex = -1;
|
||
|
||
_formController.OnDialogEnded(_formContext);
|
||
_formController.CloseUI(() =>
|
||
{
|
||
if (dialogId > 0)
|
||
{
|
||
GameEntry.Event.Fire(this, DialogCompletedEventArgs.Create(chapterId, dialogId, lineId));
|
||
}
|
||
});
|
||
}
|
||
|
||
private void ApplyLineToContext(DRDialogLine lineRow, int lineIndex, int totalLines)
|
||
{
|
||
_formContext.CurrentLineId = lineRow.Id;
|
||
_formContext.SpeakerId = lineRow.SpeakerId;
|
||
_formContext.SpeakerName = lineRow.SpeakerName;
|
||
_formContext.Direction = lineRow.Direction;
|
||
_formContext.Text = lineRow.Text;
|
||
_formContext.Emphasis = lineRow.Emphasis;
|
||
_formContext.LineIndex = lineIndex;
|
||
_formContext.TotalLines = totalLines;
|
||
_formContext.IsLastLine = lineIndex >= totalLines - 1;
|
||
}
|
||
|
||
private void PreloadChapterPortraitSprites()
|
||
{
|
||
if (GameEntry.SpriteCache == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
HashSet<string> speakerIds = new HashSet<string>(System.StringComparer.OrdinalIgnoreCase);
|
||
foreach (KeyValuePair<int, List<DRDialogLine>> pair in _dialogLinesMap)
|
||
{
|
||
List<DRDialogLine> lines = pair.Value;
|
||
if (lines == null)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
for (int i = 0; i < lines.Count; i++)
|
||
{
|
||
DRDialogLine line = lines[i];
|
||
if (line == null || !IsHumanSpeakerId(line.SpeakerId))
|
||
{
|
||
continue;
|
||
}
|
||
|
||
speakerIds.Add(line.SpeakerId);
|
||
}
|
||
}
|
||
|
||
if (speakerIds.Count == 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
foreach (string speakerId in speakerIds)
|
||
{
|
||
RegisterSpeakerPortraitsToCache(speakerId);
|
||
}
|
||
}
|
||
|
||
private void RegisterSpeakerPortraitsToCache(string speakerId)
|
||
{
|
||
SpeakerPortraitBinding binding = FindSpeakerPortraitBinding(speakerId);
|
||
if (binding == null || binding.Portraits == null || binding.Portraits.Count == 0)
|
||
{
|
||
Log.Warning("Portrait preload skipped. Missing speaker portrait binding. speakerId='{0}'.", speakerId);
|
||
return;
|
||
}
|
||
|
||
int portraitIndex = 1;
|
||
for (int i = 0; i < binding.Portraits.Count; i++)
|
||
{
|
||
Sprite portrait = binding.Portraits[i];
|
||
if (portrait == null)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
string cacheKey = $"Characters/{speakerId}-{portraitIndex}.png";
|
||
GameEntry.SpriteCache.RegisterSprite(cacheKey, portrait, true);
|
||
portraitIndex++;
|
||
}
|
||
}
|
||
|
||
private SpeakerPortraitBinding FindSpeakerPortraitBinding(string speakerId)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(speakerId) || _speakerPortraitBindings == null)
|
||
{
|
||
return null;
|
||
}
|
||
|
||
for (int i = 0; i < _speakerPortraitBindings.Count; i++)
|
||
{
|
||
SpeakerPortraitBinding binding = _speakerPortraitBindings[i];
|
||
if (binding == null || string.IsNullOrWhiteSpace(binding.SpeakerId))
|
||
{
|
||
continue;
|
||
}
|
||
|
||
if (string.Equals(binding.SpeakerId.Trim(), speakerId.Trim(), StringComparison.OrdinalIgnoreCase))
|
||
{
|
||
return binding;
|
||
}
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
private static bool IsHumanSpeakerId(string speakerId)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(speakerId))
|
||
{
|
||
return false;
|
||
}
|
||
|
||
return !NonPortraitSpeakerIds.Contains(speakerId);
|
||
}
|
||
|
||
private bool TryOpenChapterTitle(DRDialog dialogRow)
|
||
{
|
||
if (GameEntry.UI == null)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
int requestId = _nextChapterTitleRequestId++;
|
||
string subtitle = dialogRow == null || string.IsNullOrWhiteSpace(dialogRow.Title)
|
||
? string.Empty
|
||
: dialogRow.Title.Trim();
|
||
ChapterTitleFormContext context = new ChapterTitleFormContext
|
||
{
|
||
ChapterId = _currentChapterId,
|
||
RequestId = requestId,
|
||
Title = BuildChapterTitle(_currentChapterId),
|
||
Subtitle = subtitle,
|
||
DimFadeInDuration = _chapterTitleDimFadeInDuration,
|
||
PreBlackDuration = _chapterTitlePreBlackDuration,
|
||
TitleFadeInDelay = _chapterTitleTitleFadeInDelay,
|
||
TitleFadeInDuration = _chapterTitleFadeInDuration,
|
||
HoldDuration = _chapterTitleHoldDuration,
|
||
TitleFadeOutDuration = _chapterTitleFadeOutDuration,
|
||
DimFadeOutDuration = _chapterTitleDimFadeOutDuration
|
||
};
|
||
|
||
int? formSerialId = GameEntry.UI.OpenUIForm(UIFormId.ChapterTitleForm, context);
|
||
if (!formSerialId.HasValue)
|
||
{
|
||
Log.Warning("Open chapter title form failed. chapterId='{0}'.", _currentChapterId.ToString());
|
||
return false;
|
||
}
|
||
|
||
_activeChapterTitleRequestId = requestId;
|
||
return true;
|
||
}
|
||
|
||
private static string BuildChapterTitle(int chapterId)
|
||
{
|
||
return chapterId > 0 ? $"第{chapterId}章" : string.Empty;
|
||
}
|
||
|
||
private static int ParseChapterIdFromDialogId(int dialogId)
|
||
{
|
||
return dialogId / DialogChapterDivisor;
|
||
}
|
||
|
||
private static int ParseChapterIdFromLineId(int lineId)
|
||
{
|
||
return lineId / LineChapterDivisor;
|
||
}
|
||
|
||
private static int ParseDialogIdFromLineId(int lineId)
|
||
{
|
||
return lineId / LineDialogDivisor;
|
||
}
|
||
|
||
#region Event Handlers
|
||
|
||
private void OnDialogNextLineRequest(object sender, GameEventArgs e)
|
||
{
|
||
if (!(e is DialogNextLineRequestEventArgs))
|
||
{
|
||
return;
|
||
}
|
||
|
||
NextLine();
|
||
}
|
||
|
||
private void OnDialogSkipRequest(object sender, GameEventArgs e)
|
||
{
|
||
if (!(e is DialogSkipRequestEventArgs))
|
||
{
|
||
return;
|
||
}
|
||
|
||
SkipDialog();
|
||
}
|
||
|
||
private void OnDialogStopRequest(object sender, GameEventArgs e)
|
||
{
|
||
if (!(e is DialogStopRequestEventArgs))
|
||
{
|
||
return;
|
||
}
|
||
|
||
StopDialog();
|
||
}
|
||
|
||
private void OnChapterTitleCompleted(object sender, GameEventArgs e)
|
||
{
|
||
if (!(e is ChapterTitleCompletedEventArgs args))
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (args.RequestId <= 0 || args.RequestId != _activeChapterTitleRequestId)
|
||
{
|
||
return;
|
||
}
|
||
|
||
_activeChapterTitleRequestId = 0;
|
||
int pendingDialogId = _pendingStartDialogId;
|
||
_pendingStartDialogId = 0;
|
||
if (pendingDialogId <= 0 || !_isInitialized)
|
||
{
|
||
return;
|
||
}
|
||
|
||
StartDialog(pendingDialogId);
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
}
|