4坐发射子弹 抽奖界面打开关闭
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user