1
This commit is contained in:
@@ -1373,6 +1373,12 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
private void FireBullet(SitPosData sit, float angle, bool isSanShe, bool isDouble, bool isLock, List<string> bullitIDs,
|
||||
List<string> fireTargetMonsterIDs = null, List<long> bulletGolds = null)
|
||||
{
|
||||
// ⭐ 防御:sit 或 bullitIDs 为空时直接返回,避免空引用
|
||||
if (sit == null || bullitIDs == null || bullitIDs.Count == 0)
|
||||
{
|
||||
Debug.LogWarning("[FireBullet] sit 或 bullitIDs 为空,跳过本次开火");
|
||||
return;
|
||||
}
|
||||
Vector2 startPos = sit.GetBulletStartPos();
|
||||
|
||||
// ⭐ 按索引取该发子弹的服务端权威扣费金额(bullets[i].gold),没有则回退到0(ConsumeGold内部用consumeGoldNum)
|
||||
@@ -1401,7 +1407,9 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
{
|
||||
if (CreateFishManager.Instance.fishDatas_hashCodekey.TryGetValue(fireTargetMonsterIDs[i], out var m)
|
||||
&& m != null && m.gameObject.activeInHierarchy
|
||||
&& IsFishPathLockable(m))
|
||||
// ⭐ 手动锁定的主目标(i==0 且是本地玩家主锁)不受路径进度限制
|
||||
&& ((i == 0 && sit == currSitData && m == currSitData.monCotl_Lock && currSitData.isManualLock)
|
||||
|| IsFishPathLockable(m)))
|
||||
{
|
||||
targetMonster = m;
|
||||
targetHitPos = ResolveLockTransform(m);
|
||||
@@ -1425,9 +1433,11 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
}
|
||||
else if (isSanShe)
|
||||
{
|
||||
CreateBullet(sit, startPos, angle - 20, isDouble, isLock, bullitIDs[0], null, null, GetBulletGold(0));
|
||||
CreateBullet(sit, startPos, angle, isDouble, isLock, bullitIDs[1], null, null, GetBulletGold(1));
|
||||
CreateBullet(sit, startPos, angle + 20, isDouble, isLock, bullitIDs[2], null, null, GetBulletGold(2));
|
||||
// ⭐ 安全取值:bullitIDs 不足3个时复用最后一个,避免越界
|
||||
string SafeBid(int i) => i < bullitIDs.Count ? bullitIDs[i] : bullitIDs[bullitIDs.Count - 1];
|
||||
CreateBullet(sit, startPos, angle - 20, isDouble, isLock, SafeBid(0), null, null, GetBulletGold(0));
|
||||
CreateBullet(sit, startPos, angle, isDouble, isLock, SafeBid(1), null, null, GetBulletGold(1));
|
||||
CreateBullet(sit, startPos, angle + 20, isDouble, isLock, SafeBid(2), null, null, GetBulletGold(2));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1624,9 +1634,9 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
#region 路径进度过滤(锁定范围控制)
|
||||
|
||||
/// <summary>bot/玩家锁定时,鱼路径进度下限:小于此值表示鱼刚出生,不锁定</summary>
|
||||
private const float BotLockPathMin = 0.2f;
|
||||
private const float BotLockPathMin = 0.1f;
|
||||
/// <summary>bot/玩家锁定时,鱼路径进度上限:大于此值表示鱼即将离场,不锁定</summary>
|
||||
private const float BotLockPathMax = 0.8f;
|
||||
private const float BotLockPathMax = 0.9f;
|
||||
|
||||
/// <summary>
|
||||
/// 计算鱼在路径上的进度 [0, 1]。
|
||||
@@ -1647,7 +1657,8 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
|
||||
/// <summary>
|
||||
/// 判断鱼的路径进度是否在可锁定范围内 [BotLockPathMin, BotLockPathMax]
|
||||
/// 刚出生(< 0.2)或即将离场(> 0.8)的鱼不能锁定,避免锁定后立即丢失目标
|
||||
/// 刚出生(< 0.1)或即将离场(> 0.9)的鱼不能锁定,避免锁定后立即丢失目标
|
||||
/// ⭐ 注意:本函数仅用于自动锁定/bot/三发查找;玩家手动锁定不调用此函数
|
||||
/// </summary>
|
||||
private bool IsFishPathLockable(MonsterContral m)
|
||||
{
|
||||
@@ -1684,10 +1695,11 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
|
||||
if (CreateFishManager.Instance == null) return result;
|
||||
|
||||
// ① 主锁目标排第一(打哪锁哪)—— 必须也满足路径可锁定,否则三发列表会被它污染
|
||||
// ① 主锁目标排第一(打哪锁哪)
|
||||
// ⭐ 手动锁定:只看鱼是否还活着;自动锁定:还要满足路径可锁定
|
||||
if (currSitData.isLock && currSitData.monCotl_Lock != null &&
|
||||
currSitData.monCotl_Lock.gameObject.activeInHierarchy &&
|
||||
IsFishPathLockable(currSitData.monCotl_Lock))
|
||||
(currSitData.isManualLock || IsFishPathLockable(currSitData.monCotl_Lock)))
|
||||
{
|
||||
Transform pos = currSitData.monCotl_Lock_Position != null && currSitData.monCotl_Lock_Position.gameObject.activeInHierarchy
|
||||
? currSitData.monCotl_Lock_Position
|
||||
@@ -1820,6 +1832,8 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
Transform lockTr = ResolveLockTransform(monster, out colliderIndex, true);
|
||||
// ⭐ lockPoint 和 colliderList 全部未激活 → 不锁定这条鱼
|
||||
if (lockTr == null) return;
|
||||
// ⭐ 标记为手动锁定:不受路径进度(0.1~0.9)限制,鱼离场前一直锁定
|
||||
currSitData.isManualLock = true;
|
||||
currSitData.SetLockTarget(monster, lockTr);
|
||||
SyncLock(new List<string> { monster?.guid }, colliderIndex);
|
||||
|
||||
@@ -1902,11 +1916,11 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
|
||||
var monster = currSitData.monCotl_Lock;
|
||||
|
||||
// ⭐ 目标无效判定:被回收/销毁 OR 路径离场(progress > 0.8)
|
||||
// 离场的鱼仍 active,但不应该继续锁定
|
||||
// ⭐ 目标无效判定:被回收/销毁
|
||||
// 路径进度检查仅对自动锁定生效;手动锁定不检查(玩家自己锁的鱼离场前一直跟)
|
||||
bool mainInvalid = monster == null
|
||||
|| !monster.gameObject.activeInHierarchy
|
||||
|| !IsFishPathLockable(monster);
|
||||
|| (!currSitData.isManualLock && !IsFishPathLockable(monster));
|
||||
|
||||
if (mainInvalid)
|
||||
{
|
||||
@@ -1955,11 +1969,13 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
// 激活后,当锁定的鱼死亡,自动转换到下一个目标
|
||||
if (!_autoLockActivated) return;
|
||||
|
||||
// 已经有锁定目标并且还活着且未离场,就不重复找
|
||||
// 已经有锁定目标并且还活着,就不重复找
|
||||
// ⭐ 手动锁定:只看鱼是否还活着,不检查路径进度(玩家自己锁的鱼离场前一直跟)
|
||||
// 自动锁定:还要检查路径进度(超出 0.1~0.9 范围视为失效,换下一条)
|
||||
if (currSitData.isLock &&
|
||||
currSitData.monCotl_Lock != null &&
|
||||
currSitData.monCotl_Lock.gameObject.activeInHierarchy &&
|
||||
IsFishPathLockable(currSitData.monCotl_Lock))
|
||||
(currSitData.isManualLock || IsFishPathLockable(currSitData.monCotl_Lock)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1973,6 +1989,8 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
Transform lockTr = ResolveLockTransform(target, out colliderIndex);
|
||||
// ⭐ lockPoint 和 colliderList 全部未激活(出场效果中) → 不锁定,等下一帧再找
|
||||
if (lockTr == null) return;
|
||||
// ⭐ 标记为自动锁定:受路径进度(0.1~0.9)限制
|
||||
currSitData.isManualLock = false;
|
||||
currSitData.SetLockTarget(target, lockTr);
|
||||
SyncLock(new List<string> { target?.guid }, colliderIndex);
|
||||
|
||||
@@ -2348,6 +2366,12 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
}
|
||||
|
||||
var data = FrameDataParser.Parse<FrameData_FireBullet>(sync.extra.frameData);
|
||||
// ⭐ 边界检查:防止 sitPos 越界导致 IndexOutOfRangeException
|
||||
if (sync.extra.sitPos < 0 || sync.extra.sitPos >= list_Sits.Count)
|
||||
{
|
||||
Debug.LogWarning($"[SyncGameData_FireBullit] sitPos 越界: {sync.extra.sitPos}");
|
||||
return;
|
||||
}
|
||||
var targetSit = list_Sits[sync.extra.sitPos];
|
||||
FireBullet(targetSit, data.angle, data.isSanShe, data.twoRTruuect, data.isSuoDing, sync.bulletIds, data.monsterIDs, bulletGolds);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user