Delay first-meet UI until owner turn

This commit is contained in:
daixiawu 2026-06-28 00:54:41 +08:00
parent 08a49c1df2
commit 3c7f8fab99
3 changed files with 84 additions and 8 deletions

View File

@ -29,6 +29,7 @@ namespace TH1_Core.Managers
private static Queue<ISequencerTask> _taskNextFrameQueue = new Queue<ISequencerTask>();
private static Queue<ISequencerTask> _taskNotCurPlayList = new Queue<ISequencerTask>();
private static readonly List<ShowUIAnnounceHakureiPayment> _pendingHakureiPaymentNotices = new();
private static readonly List<PendingFirstMeetNotice> _pendingFirstMeetNotices = new();
private static bool _isBusy;
private static ISequencerTask _currentTask;
@ -75,6 +76,7 @@ namespace TH1_Core.Managers
_taskNextFrameQueue.Clear();
_taskNotCurPlayList.Clear();
_pendingHakureiPaymentNotices.Clear();
_pendingFirstMeetNotices.Clear();
_currentTask = null;
CurrentScope = null;
}
@ -91,6 +93,7 @@ namespace TH1_Core.Managers
_taskNextFrameQueue.Clear();
_taskNotCurPlayList.Clear();
_pendingHakureiPaymentNotices.Clear();
_pendingFirstMeetNotices.Clear();
_currentTask = null;
CurrentScope = null;
BusyType = null;
@ -216,6 +219,52 @@ namespace TH1_Core.Managers
_pendingHakureiPaymentNotices.Add(notice);
}
public static void AddPendingFirstMeetNotice(MapData map, PlayerData receiver, PlayerData metPlayer,
int coinAmount)
{
if (map == null || map != Main.MapData) return;
if (receiver == null || metPlayer == null) return;
if (!map.CanLocalControlPlayer(receiver.Id)) return;
var notice = new PendingFirstMeetNotice
{
ReceiverPlayerId = receiver.Id,
MetPlayerId = metPlayer.Id,
CoinAmount = coinAmount
};
if (HasPendingFirstMeetNotice(notice)) return;
_pendingFirstMeetNotices.Add(notice);
EnqueuePendingFirstMeetNotices(map, receiver);
}
public static void EnqueuePendingFirstMeetNotices(MapData map, PlayerData receiver)
{
if (map == null || receiver == null) return;
if (map != Main.MapData) return;
if (map.CurPlayer == null || map.CurPlayer.Id != receiver.Id) return;
if (!map.CanLocalControlPlayer(receiver.Id)) return;
if (map.PlayerMap?.SelfPlayerData != receiver) return;
for (var i = 0; i < _pendingFirstMeetNotices.Count;)
{
var notice = _pendingFirstMeetNotices[i];
if (notice.ReceiverPlayerId != receiver.Id)
{
i++;
continue;
}
_pendingFirstMeetNotices.RemoveAt(i);
EnqueueTask(new UISequencerTask(ViewControllerManager.UIAnnounceMajorEventController,
new ShowUIAnnounceMajorEvent
{
EventType = UIAnnounceMajorEventType.FirstMeet,
Param1 = (int)notice.MetPlayerId,
Param2 = notice.CoinAmount
}), true);
}
}
public static void EnqueuePendingHakureiPaymentNotices(MapData map, PlayerData receiver)
{
if (map == null || receiver == null) return;
@ -290,6 +339,25 @@ namespace TH1_Core.Managers
return false;
}
private static bool HasPendingFirstMeetNotice(PendingFirstMeetNotice notice)
{
foreach (var pending in _pendingFirstMeetNotices)
{
if (pending.ReceiverPlayerId == notice.ReceiverPlayerId
&& pending.MetPlayerId == notice.MetPlayerId)
return true;
}
return false;
}
private struct PendingFirstMeetNotice
{
public uint ReceiverPlayerId;
public uint MetPlayerId;
public int CoinAmount;
}
private static bool HasQueuedCityLevelUpChoice(uint cityId, int cityLevel)
{
return IsCityLevelUpChoiceTask(_currentTask, cityId, cityLevel)
@ -469,6 +537,17 @@ namespace TH1_Core.Managers
while(_taskNotCurPlayList.Count > 0)
_taskQueue.Enqueue(_taskNotCurPlayList.Dequeue());
}
private static void CheckPendingLocalPlayerNotices()
{
var mapData = Main.MapData;
var curPlayer = mapData?.CurPlayer;
if (curPlayer == null) return;
if (!mapData.CanLocalControlPlayer(curPlayer.Id)) return;
if (mapData.PlayerMap?.SelfPlayerData != curPlayer) return;
EnqueuePendingFirstMeetNotices(mapData, curPlayer);
}
@ -493,6 +572,7 @@ namespace TH1_Core.Managers
{
//如果当前是我的回合并且_taskNotCurPlayList缓存队列不为空把所有这些加入队列
CheckNotCurQueue();
CheckPendingLocalPlayerNotices();
//每帧开始前,检查“下一帧队列”的是否有内容,将所有内容加入当前的队列
CheckNextFrameQueue();
TryProcessNext();

View File

@ -3270,6 +3270,7 @@ namespace Logic.Action
&& actionParams.MapData.CanLocalControlPlayer(actionParams.PlayerData.Id);
if(canLocalControlTurnPlayer)
{
PresentationManager.EnqueuePendingFirstMeetNotices(actionParams.MapData, actionParams.PlayerData);
PresentationManager.EnqueuePendingHakureiPaymentNotices(actionParams.MapData, actionParams.PlayerData);
PresentationManager.EnqueuePendingDanegeldChoices(actionParams.MapData, actionParams.PlayerData);
PresentationManager.EnqueuePendingCityLevelUpChoices(actionParams.MapData, actionParams.PlayerData);

View File

@ -1174,14 +1174,9 @@ namespace Logic
}
//step #5
//如果是玩家出发ui提示。加钱的操作要在ui提示关闭的时候由ui来出发
//只在真实 Main.MapData 上弹,避免 AI 预测/模拟的虚假 MapData 误触发
if (map == Main.MapData && p1 == map.PlayerMap.SelfPlayerData)
{
var announcement = new ShowUIAnnounceMajorEvent { EventType = UIAnnounceMajorEventType.FirstMeet,Param1 = (int)p2.Id,Param2 = coin};
EventManager.Publish(announcement);
//UIManager.Instance.CenterMessageUI.SetCenterMessageShow(UICenterMessageID.MeetNewPlayer,player1,grid);
}
//首遇 UI 按归属玩家延后到其本机可操作回合展示,避免队友回合中的被动视野刷新阻塞后续演出。
//真实金币已在上方 AddCoin_LogicOnly 同步写入UI 关闭时只播放 ViewOnly 金币动画。
PresentationManager.AddPendingFirstMeetNotice(map, p1, p2, coin);
}
public void InitSingleTeammateMeetAndSight(MapData map)