1
This commit is contained in:
@@ -183,6 +183,8 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
private Dictionary<int, string> botTargetGuid = new Dictionary<int, string>();
|
||||
// bot 锁定同步节流:记录上次广播的锁定目标 guid(null 表示未锁定),只有目标变化才广播
|
||||
private Dictionary<int, string> botLastSyncLockGuid = new Dictionary<int, string>();
|
||||
// bot 炮台状态同步节流:记录上次广播的 TurretState,只有状态变化才广播
|
||||
private Dictionary<int, TurretState> botLastSyncTurretState = new Dictionary<int, TurretState>();
|
||||
// bot 状态计时:开火后持续 Attack 动画,空闲 0.3s 切回 Idle
|
||||
private Dictionary<int, float> botIdleTimer = new Dictionary<int, float>();
|
||||
// bot 最近的 FrameData_FireBullet(给其他客户端还原技能状态)
|
||||
@@ -644,10 +646,10 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
|
||||
HandleAutoFire(); // 自动开火真正发射
|
||||
HandleLock();
|
||||
UpdateLockFX();
|
||||
HandleAutoLock(); // ⭐ 先切换锁定目标(切换后图标位置同帧更新)
|
||||
UpdateLockFX(); // 锁定图标跟随目标
|
||||
RefreshTripleLockIcons();
|
||||
|
||||
HandleAutoLock();
|
||||
LoopLaser();
|
||||
SettingClose();
|
||||
DaoJiShi();
|
||||
@@ -2116,7 +2118,11 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
{
|
||||
switch (propNumber)
|
||||
{
|
||||
case "40004": // 暴走
|
||||
case "40004": // 暴走 — 个人效果,只有使用者自己生效
|
||||
// ⭐ 狂暴是个人增益(攻速翻倍+炮台动画),不是全房间效果。
|
||||
// 服务器会把 UsePropNotice 广播给房间内所有人,必须判断 userId
|
||||
// 否则别人用狂暴,本地也开了狂暴
|
||||
if (userId != GameManager.Instance.user.id) break;
|
||||
_localBaoZouCount--;
|
||||
UpdateSkillPropsUI();
|
||||
CreateFishManager.Instance.currGameType.isFrenzy = true;
|
||||
@@ -2126,22 +2132,33 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
break;
|
||||
|
||||
case "40003": // 冰封
|
||||
_localBingFengCount--;
|
||||
UpdateSkillPropsUI();
|
||||
currBingFengTime = bingFengDuration;
|
||||
toggle_BingFeng.SetIsOnWithoutNotify(true);
|
||||
if (bingFengEffect != null)
|
||||
{
|
||||
if (_bingFengInstance == null)
|
||||
_bingFengInstance = Instantiate(bingFengEffect);
|
||||
_bingFengInstance.SetActive(true);
|
||||
// ⭐ 个人效果(数量/toggle/倒计时/广播):只有使用者自己执行
|
||||
// 服务器把 UsePropNotice 广播给房间内所有人,不判断 userId 会导致
|
||||
// 别人用冰封,本地数量也减了、toggle 也亮了、倒计时也走了
|
||||
bool isLocalSender = userId == GameManager.Instance.user.id;
|
||||
if (isLocalSender)
|
||||
{
|
||||
_localBingFengCount--;
|
||||
UpdateSkillPropsUI();
|
||||
currBingFengTime = bingFengDuration;
|
||||
toggle_BingFeng.SetIsOnWithoutNotify(true);
|
||||
// ⭐ 只有发起者广播,避免其他客户端重复广播
|
||||
SyncFreeze(true);
|
||||
}
|
||||
// ⭐ 房间效果(冻结鱼/暂停动画/冰冻特效):所有客户端都执行
|
||||
// FreezeAllFish/PauseAllFishAnimations 内部有 isFrozen 守卫,
|
||||
// 重复调用安全(不会覆盖已记录的状态)
|
||||
if (bingFengEffect != null)
|
||||
{
|
||||
if (_bingFengInstance == null)
|
||||
_bingFengInstance = Instantiate(bingFengEffect);
|
||||
_bingFengInstance.SetActive(true);
|
||||
}
|
||||
CreateFishManager.Instance.FreezeAllFish();
|
||||
PauseAllFishAnimations();
|
||||
break;
|
||||
}
|
||||
CreateFishManager.Instance.FreezeAllFish();
|
||||
PauseAllFishAnimations();
|
||||
// ⭐ 广播冰冻给其他客户端(包括人机房主代发的场景)
|
||||
// 之前只走 UsePropNotice 本地冻结,没广播 → 多人房间其他人不冻结
|
||||
SyncFreeze(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2168,6 +2185,11 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
|
||||
private void PauseAllFishAnimations()
|
||||
{
|
||||
// ⭐ 守卫:已暂停时直接返回,避免重复调用覆盖已记录的速度
|
||||
// (其他客户端会先后被 OnUsePropNotice 和 SyncGameData_FreezeFish 触发两次,
|
||||
// 第二次会记录 speed=0,解冻时恢复成 0 → 动画永远暂停)
|
||||
if (_frozenAnimSpeeds.Count > 0) return;
|
||||
|
||||
var root = CreateFishManager.Instance.fishRoot;
|
||||
if (root == null) return;
|
||||
_frozenAnimSpeeds.Clear();
|
||||
@@ -2390,10 +2412,12 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
botIdleTimer[sit.posID] = 0f;
|
||||
botIdleTimer[sit.posID] += Time.deltaTime;
|
||||
if (botIdleTimer[sit.posID] > 0.3f)
|
||||
{
|
||||
sit.ChangeState(TurretState.Idle);
|
||||
botIdleTimer[sit.posID] = 0f;
|
||||
}
|
||||
{
|
||||
sit.ChangeState(TurretState.Idle);
|
||||
// ⭐ 广播炮台闲置状态给其他客户端(节流:状态变化才广播)
|
||||
SyncBotTurretState(sit, TurretState.Idle);
|
||||
botIdleTimer[sit.posID] = 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2676,6 +2700,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
// 清理记忆
|
||||
botTargetGuid.Remove(sit.posID);
|
||||
botLastSyncLockGuid.Remove(sit.posID);
|
||||
botLastSyncTurretState.Remove(sit.posID);
|
||||
botFireTimer.Remove(sit.posID);
|
||||
botIdleTimer.Remove(sit.posID);
|
||||
botSkills.Remove(sit.posID);
|
||||
@@ -2713,6 +2738,8 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
private void BotFire(SitPosData sit, MonsterContral target, BotSkillRuntime skill, BotBehaviorMode mode, BotConfig cfg, BotBehaviorConfig behavior)
|
||||
{
|
||||
sit.ChangeState(TurretState.Attack);
|
||||
// ⭐ 广播炮台攻击状态给其他客户端(节流:状态变化才广播)
|
||||
SyncBotTurretState(sit, TurretState.Attack);
|
||||
if (!botIdleTimer.ContainsKey(sit.posID))
|
||||
botIdleTimer[sit.posID] = 0f;
|
||||
botIdleTimer[sit.posID] = 0f;
|
||||
@@ -3058,6 +3085,31 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
WebSocketSendList.SyncGameData(sgd);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 机器人炮台状态广播(房主代发,复用 changeTurretState 帧类型)。
|
||||
/// 用 bot 自己的 sitPos,接收端 SyncGameData_TurretState 会根据 sitPos
|
||||
/// 调用 sit.ChangeState(state) 切换炮台动画。
|
||||
/// 内置节流:只有状态变化才广播(避免空闲时每帧广播 Idle)。
|
||||
/// 走 LV2 队列(0.5s flush 一次),对 bot 攻击动画可接受。
|
||||
/// </summary>
|
||||
private void SyncBotTurretState(SitPosData botSit, TurretState state)
|
||||
{
|
||||
if (botSit == null) return;
|
||||
// ⭐ 节流:状态未变化不广播
|
||||
if (botLastSyncTurretState.TryGetValue(botSit.posID, out var lastSynced) && lastSynced == state)
|
||||
return;
|
||||
botLastSyncTurretState[botSit.posID] = state;
|
||||
|
||||
SyncGameData sgd = new SyncGameData
|
||||
{
|
||||
sitPos = botSit.posID,
|
||||
frameType = FrameDataType.changeTurretState,
|
||||
time = BeijingTimeManager.Instance.CurrentTimestampMs,
|
||||
frameData = new FrameData_TurretState { state = state }
|
||||
};
|
||||
WebSocketSendList.SyncGameData(sgd);
|
||||
}
|
||||
|
||||
/// <summary>人机开火同步(房主代发)</summary>
|
||||
private void SyncFire_ForBot(SitPosData botSit, float angle, long gold,
|
||||
bool isSanShe, bool isDouble, bool isLock, List<string> monsterIDs)
|
||||
|
||||
Reference in New Issue
Block a user