4坐发射子弹 抽奖界面打开关闭

This commit is contained in:
2026-09-27 18:38:28 +08:00
parent 4bc30fef04
commit 84035ac327
4 changed files with 99 additions and 11 deletions
@@ -4036,7 +4036,10 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
sitPos = SeatMirror.ToServer(currSitData.posID),
frameType = FrameDataType.rotateTurrect,
time = BeijingTimeManager.Instance.CurrentTimestampMs,
frameData = new FrameData_Rotate { angle = angle }
// ⭐ 座位镜像:网络角度统一用"源角度"(下方座位系,0=朝桌面中心)。
// 本地玩家永远显示在下方座位(IsFlipped=false),这里实际是原值;
// 保留转换以兼容未来本地座位可能在上方的情况
frameData = new FrameData_Rotate { angle = SeatMirror.WorldAngleToSource(angle, currSitData.IsFlipped) }
};
WebSocketSendList.SyncGameData(sgd);
}
@@ -4045,7 +4048,8 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
{
var fireData = new FrameData_FireBullet
{
angle = angle,
// ⭐ 座位镜像:网络角度统一用"源角度"(下方座位系),接收端按显示座位还原
angle = SeatMirror.WorldAngleToSource(angle, currSitData.IsFlipped),
gold = currSitData.goldNum,
isSanShe = isSanShe,
twoRTruuect = isDouble,
@@ -4191,7 +4195,10 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
if (sit != null && sit.isBot && currSitData == SitPosData.roomOwnerSit) return;
var data = FrameDataParser.Parse<FrameData_Rotate>(sync.frameData);
SmoothRotate(sit, data.angle);
// ⭐ 座位镜像:网络角度是"源角度"(发送方下方座位系,0=朝桌面中心),
// 按该座位在本端场景的显示位置还原成世界角度:
// 显示座位在下方 → 原样;在上方 → 180−源角度(上下翻转,左右不反)
SmoothRotate(sit, SeatMirror.SourceAngleToWorld(data.angle, sit.IsFlipped));
}
public void SyncGameData_FireBullit(FireCannonSendData sync)
@@ -4225,7 +4232,10 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
SitPosData sit = list_Sits.Find(s => s.user == sync.userId);
if (sit == null) return;
float angle = botLastAngle.TryGetValue(sync.userId, out float a) ? a : sit.currentAngle;
// ⭐ 座位镜像:botLastAngle/botLastFireData 缓存的是"源角度"(下方座位系);
// 真人兜底用 sit.currentAngle(本端世界角度,无需转换)
bool angleFromBotMemory = botLastAngle.TryGetValue(sync.userId, out float a);
float angle = angleFromBotMemory ? a : sit.currentAngle;
if (sync.bulletIds == null || sync.bulletIds.Count == 0) return;
// ⭐ 优先用服务器广播的 sync.isBot 标记判断是否机器人
@@ -4233,9 +4243,17 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
bool isBot = sync.isBot || sit.isBot;
if (isBot && botLastFireData.TryGetValue(sync.userId, out var fireData))
{
FireBullet(sit, angle, fireData.isSanShe, fireData.twoRTruuect,
// ⭐ 座位镜像:源角度按该 bot 显示座位还原成世界角度再创建子弹
FireBullet(sit, SeatMirror.SourceAngleToWorld(fireData.angle, sit.IsFlipped),
fireData.isSanShe, fireData.twoRTruuect,
fireData.isSuoDing, sync.bulletIds, fireData.monsterIDs, bulletGolds);
}
else if (angleFromBotMemory)
{
// bot 有角度缓存但无完整开火数据 → 同样按源角度转换
FireBullet(sit, SeatMirror.SourceAngleToWorld(angle, sit.IsFlipped),
false, false, false, sync.bulletIds, null, bulletGolds);
}
else
{
FireBullet(sit, angle, false, false, false, sync.bulletIds, null, bulletGolds);
@@ -4253,7 +4271,9 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
return;
}
var targetSit = list_Sits[dispPos];
FireBullet(targetSit, data.angle, data.isSanShe, data.twoRTruuect, data.isSuoDing, sync.bulletIds, data.monsterIDs, bulletGolds);
// ⭐ 座位镜像:网络角度是"源角度"(发送方下方座位系),按该座位显示位置还原成世界角度
FireBullet(targetSit, SeatMirror.SourceAngleToWorld(data.angle, targetSit.IsFlipped),
data.isSanShe, data.twoRTruuect, data.isSuoDing, sync.bulletIds, data.monsterIDs, bulletGolds);
}
/// <summary>
@@ -5076,7 +5096,8 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
botIdleTimer[sit.posID] = 0f;
float angle = sit.currentAngle;
botLastAngle[sit.user] = angle;
// ⭐ 座位镜像:bot 角度缓存统一存"源角度"(下方座位系),与网络帧格式一致
botLastAngle[sit.user] = SeatMirror.WorldAngleToSource(angle, sit.IsFlipped);
bool isSanShe = (skill != null && skill.tripleActive) || mode == BotBehaviorMode.ScatterMode || mode == BotBehaviorMode.ScatterRandom;
bool isDouble = skill != null && skill.doubleActive;
@@ -5098,7 +5119,8 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
botLastFireData[sit.user] = new FrameData_FireBullet
{
angle = angle,
// ⭐ 座位镜像:存"源角度"(下方座位系),房主自己收到广播回放时同样按源角度转换
angle = SeatMirror.WorldAngleToSource(angle, sit.IsFlipped),
gold = gold,
isSanShe = isSanShe,
twoRTruuect = isDouble,
@@ -5378,7 +5400,9 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
sitPos = SeatMirror.ToServer(botSit.posID),
frameType = FrameDataType.rotateTurrect,
time = BeijingTimeManager.Instance.CurrentTimestampMs,
frameData = new FrameData_Rotate { angle = angle }
// ⭐ 座位镜像:房主代算的 bot 角度是世界角度(按 bot 显示座位算的),
// 先转成统一的"源角度"(下方座位系)再广播,接收端按各自显示座位还原
frameData = new FrameData_Rotate { angle = SeatMirror.WorldAngleToSource(angle, botSit.IsFlipped) }
};
WebSocketSendList.SyncGameData(sgd);
}
@@ -5447,7 +5471,8 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
{
var fireData = new FrameData_FireBullet
{
angle = angle,
// ⭐ 座位镜像:网络角度统一用"源角度"(下方座位系),接收端按显示座位还原
angle = SeatMirror.WorldAngleToSource(angle, botSit.IsFlipped),
gold = gold,
isSanShe = isSanShe,
twoRTruuect = isDouble,
+45
View File
@@ -67,4 +67,49 @@ public static class SeatMirror
{
return ToDisplay(displayPos);
}
// ================================================================
// 炮台角度镜像
// ================================================================
// 角度约定(与 SitPosData.SetRotation 一致的 aim-90 世界角):
// 0=朝上, 90=朝左, 180=朝下, 270=朝右(Unity z 轴逆时针为正)。
//
// 座位镜像是"上下翻转"(0↔2、1↔3 同侧对调),不是旋转 180°,
// 所以方向向量的变换是 Y 轴翻转:(dx,dy) → (dx,−dy),
// 对应角度变换:angle' = 180 − angle(自反,与座位 XOR 2 一样互逆):
// - 垂直瞄准时(0↔180)恰好等于 +180;
// - 斜向/横向瞄准时左右侧不反(若用 +180 会把左右瞄反)。
//
// 网络帧里的炮台角度统一用"源角度":发送方永远以"自己在下方座位"
// 的坐标系发送(0 = 朝桌面中心)。每个玩家进房后自己永远显示在下方
// 座位,本地算出的就是源角度;bot 由房主代算,先转成源角度再广播。
// 接收端按该座位在自己场景里的显示位置还原成世界角度。
// ================================================================
/// <summary>角度归一化到 [0,360)</summary>
public static float NormalizeAngle(float angle)
{
angle %= 360f;
if (angle < 0f) angle += 360f;
return angle;
}
/// <summary>
/// 源角度(网络帧,下方座位坐标系)→ 本地世界角度。
/// seatFlipped = 该座位在本端场景里的显示位置在上方(SitPosData.IsFlipped)。
/// </summary>
public static float SourceAngleToWorld(float sourceAngle, bool seatFlipped)
{
return seatFlipped ? NormalizeAngle(180f - sourceAngle) : sourceAngle;
}
/// <summary>
/// 本地世界角度 → 源角度(发送网络帧时用)。
/// seatFlipped = 计算该角度的座位显示位置在上方(bot 由房主代算时可能为 true)。
/// 180−angle 自反,与 SourceAngleToWorld 互逆。
/// </summary>
public static float WorldAngleToSource(float worldAngle, bool seatFlipped)
{
return seatFlipped ? NormalizeAngle(180f - worldAngle) : worldAngle;
}
}
@@ -112,6 +112,15 @@ public class ChouJiangPanel : SubUIBase
{
if (this == null) return;
config = cfg;
// 活动未开启:提示后关闭面板
if (config != null && !config.isOpen)
{
UIManager.Instance.ShowTiShi("活动未开启");
uIManager.Hide(this);
return;
}
UpdateActivityUI();
InitToggles();
RefreshUserStatus();
+10 -1
View File
@@ -140,7 +140,16 @@ public class UIHomeMain : UIBase
});
btn_ChouJiang.onClick.AddListener(() =>
{
subUIManager.ShowAsync(UIPanel.ChouJiangPanel);
// 接收配置信息时直接判断:未开启不打开面板,避免面板先弹出又关掉的闪烁
APIRequestList.GetLotteryActivityConfig(cfg =>
{
if (cfg != null && !cfg.isOpen)
{
UIManager.Instance.ShowTiShi("活动未开启");
return;
}
subUIManager.ShowAsync(UIPanel.ChouJiangPanel);
});
});
#endregion