1
This commit is contained in:
@@ -218,6 +218,16 @@ public class SitPosData : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
|
||||
public List<GameObject> lockFX_Triple = new List<GameObject>(); // 三发锁定额外2个图标
|
||||
public List<MonsterContral> tripleLockTargets = new List<MonsterContral>();
|
||||
public List<Transform> tripleLockPositions = new List<Transform>();
|
||||
/// <summary>
|
||||
/// ⭐ 三发锁位是否处于"空置等手动点击"状态(索引与 tripleLockTargets 对齐)。
|
||||
/// true = 该锁位打死后自动检测没找到鱼 → 保持空着,不再自动补位,必须玩家手动点击才锁。
|
||||
/// </summary>
|
||||
private readonly List<bool> tripleSlotIdle = new List<bool>();
|
||||
/// <summary>
|
||||
/// ⭐ 该锁位是否由玩家手动点选(索引与 tripleLockTargets 对齐)。
|
||||
/// true = 玩家自己点的鱼 → 离场前一直跟,死了才换;手动身份会跟着鱼一起移入子锁位。
|
||||
/// </summary>
|
||||
private readonly List<bool> tripleSlotManual = new List<bool>();
|
||||
|
||||
// -------------------------
|
||||
// UI
|
||||
@@ -2021,37 +2031,23 @@ public class SitPosData : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
|
||||
|
||||
// 确保 lockFX_Triple 有2个克隆的图标(+主图标=3个)
|
||||
EnsureTripleLockIcons();
|
||||
// ⭐ 固定3个锁位(不足的留空占位,下一帧由锁定系统自动尝试补一次)
|
||||
EnsureTripleLockSlots(3);
|
||||
|
||||
tripleLockTargets.Clear();
|
||||
tripleLockPositions.Clear();
|
||||
|
||||
// 第一个目标用主 lockFX
|
||||
var primary = targets[0];
|
||||
monCotl_Lock = primary.monster;
|
||||
monCotl_Lock_Position = primary.hitPos;
|
||||
isLock = true;
|
||||
lockFX.SetActive(true);
|
||||
tripleLockTargets.Add(primary.monster);
|
||||
tripleLockPositions.Add(primary.hitPos);
|
||||
|
||||
// 第二个和第三个目标用 lockFX_Triple
|
||||
for (int i = 1; i < targets.Count && i < 3; i++)
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
int idx = i - 1;
|
||||
if (idx < lockFX_Triple.Count && lockFX_Triple[idx] != null)
|
||||
{
|
||||
lockFX_Triple[idx].SetActive(true);
|
||||
tripleLockTargets.Add(targets[i].monster);
|
||||
tripleLockPositions.Add(targets[i].hitPos);
|
||||
}
|
||||
bool has = i < targets.Count;
|
||||
tripleLockTargets[i] = has ? targets[i].monster : null;
|
||||
tripleLockPositions[i] = has ? targets[i].hitPos : null;
|
||||
// ⭐ 自动建位:允许自动补位(补不到会转成"空置等手动点击"),不算玩家手动
|
||||
tripleSlotIdle[i] = false;
|
||||
tripleSlotManual[i] = false;
|
||||
}
|
||||
|
||||
// 隐藏多余的
|
||||
for (int i = targets.Count - 1; i < lockFX_Triple.Count; i++)
|
||||
{
|
||||
if (lockFX_Triple[i] != null)
|
||||
lockFX_Triple[i].SetActive(false);
|
||||
}
|
||||
monCotl_Lock = targets[0].monster;
|
||||
monCotl_Lock_Position = targets[0].hitPos;
|
||||
isLock = targets[0].monster != null;
|
||||
RefreshTripleIconVisibility();
|
||||
}
|
||||
|
||||
private void EnsureTripleLockIcons()
|
||||
@@ -2065,6 +2061,18 @@ public class SitPosData : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>把锁位列表补齐到 count 个(用 null 占位,保证三个列表索引对齐)</summary>
|
||||
public void EnsureTripleLockSlots(int count)
|
||||
{
|
||||
while (tripleLockTargets.Count < count)
|
||||
{
|
||||
tripleLockTargets.Add(null);
|
||||
tripleLockPositions.Add(null);
|
||||
tripleSlotIdle.Add(false);
|
||||
tripleSlotManual.Add(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void HideTripleLockIcons()
|
||||
{
|
||||
foreach (var icon in lockFX_Triple)
|
||||
@@ -2074,69 +2082,163 @@ public class SitPosData : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
|
||||
}
|
||||
tripleLockTargets.Clear();
|
||||
tripleLockPositions.Clear();
|
||||
tripleSlotIdle.Clear();
|
||||
tripleSlotManual.Clear();
|
||||
}
|
||||
|
||||
// ==================== 三发锁位(每个锁位独立维护) ====================
|
||||
// ⭐ index=0 是主锁位(monCotl_Lock + 主 lockFX),1..2 对应 lockFX_Triple[index-1]
|
||||
|
||||
/// <summary>取 index(1..2) 对应的额外锁定图标</summary>
|
||||
private GameObject GetTripleIcon(int index)
|
||||
/// <summary>按每个锁位是否有鱼刷新3个锁定圈显示(有目标才有圈)</summary>
|
||||
private void RefreshTripleIconVisibility()
|
||||
{
|
||||
int iconIdx = index - 1;
|
||||
if (lockFX_Triple == null || iconIdx < 0 || iconIdx >= lockFX_Triple.Count) return null;
|
||||
return lockFX_Triple[iconIdx];
|
||||
if (lockFX != null)
|
||||
lockFX.SetActive(tripleLockTargets.Count > 0 && tripleLockTargets[0] != null);
|
||||
|
||||
for (int i = 0; i < lockFX_Triple.Count; i++)
|
||||
{
|
||||
if (lockFX_Triple[i] == null) continue;
|
||||
int slot = i + 1;
|
||||
lockFX_Triple[i].SetActive(slot < tripleLockTargets.Count && tripleLockTargets[slot] != null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>替换单个三发锁位(锁位独立:某条鱼死了只补这一个锁位,其他锁位不动)</summary>
|
||||
/// <summary>替换单个三发锁位(自动补位用:锁位独立,只补这一个,其他锁位不动)</summary>
|
||||
public void SetTripleLockSlot(int index, MonsterContral monster, Transform hitPos)
|
||||
{
|
||||
if (index < 0) return;
|
||||
while (tripleLockTargets.Count <= index)
|
||||
{
|
||||
tripleLockTargets.Add(null);
|
||||
tripleLockPositions.Add(null);
|
||||
}
|
||||
EnsureTripleLockSlots(index + 1);
|
||||
tripleLockTargets[index] = monster;
|
||||
tripleLockPositions[index] = hitPos;
|
||||
tripleSlotIdle[index] = false;
|
||||
tripleSlotManual[index] = false; // 自动补的位不算玩家手动
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
monCotl_Lock = monster;
|
||||
monCotl_Lock_Position = hitPos;
|
||||
isLock = monster != null;
|
||||
if (lockFX != null) lockFX.SetActive(isLock);
|
||||
}
|
||||
else
|
||||
{
|
||||
var icon = GetTripleIcon(index);
|
||||
if (icon != null) icon.SetActive(monster != null);
|
||||
}
|
||||
RefreshTripleIconVisibility();
|
||||
}
|
||||
|
||||
/// <summary>清空单个三发锁位(该锁位暂时没鱼可补):保留槽位占位,只隐藏该锁位图标</summary>
|
||||
/// <summary>
|
||||
/// 清空单个三发锁位:该位打死后自动检测没找到鱼 → 保留占位、隐藏该位图标,
|
||||
/// 并标记"空置等手动点击"(不再自动补位,必须玩家点击才锁)。
|
||||
/// </summary>
|
||||
public void ClearTripleLockSlot(int index)
|
||||
{
|
||||
if (index < 0 || index >= tripleLockTargets.Count) return;
|
||||
tripleLockTargets[index] = null;
|
||||
if (index < tripleLockPositions.Count) tripleLockPositions[index] = null;
|
||||
tripleLockPositions[index] = null;
|
||||
tripleSlotIdle[index] = true;
|
||||
tripleSlotManual[index] = false;
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
monCotl_Lock = null;
|
||||
monCotl_Lock_Position = null;
|
||||
isLock = false;
|
||||
if (lockFX != null) lockFX.SetActive(false);
|
||||
}
|
||||
else
|
||||
RefreshTripleIconVisibility();
|
||||
}
|
||||
|
||||
/// <summary>该锁位是否处于"空置等手动点击"状态(不再自动补位)</summary>
|
||||
public bool IsTripleSlotIdle(int index)
|
||||
{
|
||||
return index >= 0 && index < tripleSlotIdle.Count && tripleSlotIdle[index];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 该锁位是否是玩家手动点选的鱼(手动身份跟着鱼一起移入子锁位)。
|
||||
/// true → 离场前一直跟,只有鱼死了才换。
|
||||
/// </summary>
|
||||
public bool IsTripleSlotManual(int index)
|
||||
{
|
||||
return index >= 0 && index < tripleSlotManual.Count && tripleSlotManual[index];
|
||||
}
|
||||
|
||||
/// <summary>三个锁位是否还有任意一个有效目标(鱼还活着)</summary>
|
||||
public bool HasAnyTripleTarget
|
||||
{
|
||||
get
|
||||
{
|
||||
var icon = GetTripleIcon(index);
|
||||
if (icon != null) icon.SetActive(false);
|
||||
foreach (var m in tripleLockTargets)
|
||||
if (m != null && m.gameObject.activeInHierarchy) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>当前三发锁位上有效的鱼 guid 列表(开火同步 monsterIDs 用)</summary>
|
||||
public List<string> GetTripleLockGuids()
|
||||
{
|
||||
var list = new List<string>();
|
||||
foreach (var m in tripleLockTargets)
|
||||
if (m != null && !m.isDead && m.gameObject.activeInHierarchy)
|
||||
list.Add(m.guid);
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>该 guid 的鱼是否已经在某个三发锁位上</summary>
|
||||
public bool IsFishInTripleSlots(string guid)
|
||||
{
|
||||
if (string.IsNullOrEmpty(guid)) return false;
|
||||
foreach (var m in tripleLockTargets)
|
||||
if (m != null && m.guid == guid) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ⭐ 手动点击锁鱼(战神+三发+锁定):新点的鱼占主锁位,原来锁位上的鱼依次排到子锁位,
|
||||
/// 最多保留3个(超过时最旧的被挤掉)。
|
||||
/// 手动身份跟着鱼一起转移(移入子锁位后依然是手动锁定,离场前不会被自动换掉);
|
||||
/// 挤位前会先"紧凑化",跳过空位/死鱼,避免有空位时误丢掉还活着的锁定目标。
|
||||
/// </summary>
|
||||
public void PushTripleLockSlot(MonsterContral monster, Transform hitPos)
|
||||
{
|
||||
EnsureTripleLockIcons();
|
||||
|
||||
// ① 收集现有锁位上还活着的鱼(跳过空位和死鱼),按 新→旧 顺序,最多留2个
|
||||
var keepMon = new List<MonsterContral>();
|
||||
var keepPos = new List<Transform>();
|
||||
var keepManual = new List<bool>();
|
||||
for (int i = 0; i < tripleLockTargets.Count && keepMon.Count < 2; i++)
|
||||
{
|
||||
var m = tripleLockTargets[i];
|
||||
if (m == null || !m.gameObject.activeInHierarchy) continue;
|
||||
if (m == monster) continue; // 同一条鱼不重复占位
|
||||
keepMon.Add(m);
|
||||
keepPos.Add(i < tripleLockPositions.Count ? tripleLockPositions[i] : null);
|
||||
keepManual.Add(i < tripleSlotManual.Count && tripleSlotManual[i]);
|
||||
}
|
||||
|
||||
// ② 新点的鱼占主锁位,其余依次排到子锁位
|
||||
EnsureTripleLockSlots(3);
|
||||
tripleLockTargets[0] = monster;
|
||||
tripleLockPositions[0] = hitPos;
|
||||
tripleSlotIdle[0] = false;
|
||||
tripleSlotManual[0] = true; // 玩家手动点的
|
||||
|
||||
for (int i = 1; i < 3; i++)
|
||||
{
|
||||
int k = i - 1;
|
||||
bool has = k < keepMon.Count;
|
||||
tripleLockTargets[i] = has ? keepMon[k] : null;
|
||||
tripleLockPositions[i] = has ? keepPos[k] : null;
|
||||
// ⭐ 空位标记"等手动点击":玩家在自己点选,空位不再自动补
|
||||
tripleSlotIdle[i] = !has;
|
||||
tripleSlotManual[i] = has && keepManual[k];
|
||||
}
|
||||
|
||||
monCotl_Lock = monster;
|
||||
monCotl_Lock_Position = hitPos;
|
||||
isLock = true;
|
||||
RefreshTripleIconVisibility();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 主锁位空缺时,把其他存活的锁位提升为主锁,避免主锁死掉导致整个三发模式中断。
|
||||
/// 提升后原锁位留空,下一帧会自动补新目标。成功返回 true。
|
||||
/// 提升后原锁位留空并允许自动补一次。成功返回 true。
|
||||
/// </summary>
|
||||
public bool PromoteTripleLockSlotToMain()
|
||||
{
|
||||
@@ -2150,13 +2252,21 @@ public class SitPosData : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
|
||||
tripleLockPositions[0] = pos;
|
||||
tripleLockTargets[i] = null;
|
||||
tripleLockPositions[i] = null;
|
||||
var icon = GetTripleIcon(i);
|
||||
if (icon != null) icon.SetActive(false);
|
||||
if (i < tripleSlotIdle.Count)
|
||||
{
|
||||
tripleSlotIdle[0] = tripleSlotIdle[i];
|
||||
tripleSlotIdle[i] = false; // 让出的位置允许自动补一次
|
||||
}
|
||||
if (i < tripleSlotManual.Count)
|
||||
{
|
||||
tripleSlotManual[0] = tripleSlotManual[i]; // 手动身份跟着鱼提升
|
||||
tripleSlotManual[i] = false;
|
||||
}
|
||||
|
||||
monCotl_Lock = mon;
|
||||
monCotl_Lock_Position = pos;
|
||||
isLock = true;
|
||||
if (lockFX != null) lockFX.SetActive(true);
|
||||
RefreshTripleIconVisibility();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -930,7 +930,7 @@ PrefabInstance:
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1361653457580592, guid: 055ba0a273a3d0c48a43f4fb3f92dc4d, type: 3}
|
||||
propertyPath: m_IsActive
|
||||
value: 0
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1361653457580592, guid: 055ba0a273a3d0c48a43f4fb3f92dc4d, type: 3}
|
||||
propertyPath: m_TagString
|
||||
|
||||
@@ -3565,6 +3565,21 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
Transform lockTr = ResolveLockTransform(monster, out colliderIndex, true);
|
||||
// ⭐ lockPoint 和 colliderList 全部未激活 → 不锁定这条鱼
|
||||
if (lockTr == null) return;
|
||||
|
||||
// ⭐⭐⭐ 战神 + 三发 + 锁定(散射三个锁定圈):手动点击 = 占主锁位,
|
||||
// 原来的主锁位自动挤到子锁位,子锁位依次后移,最多锁3个
|
||||
if (IsZhanShenTripleMode())
|
||||
{
|
||||
// 已经在锁位上的鱼 → 不重复加
|
||||
if (currSitData.IsFishInTripleSlots(monster.guid)) return;
|
||||
|
||||
currSitData.PushTripleLockSlot(monster, lockTr);
|
||||
currSitData.isManualLock = true;
|
||||
_autoLockActivated = true;
|
||||
SyncLock(currSitData.GetTripleLockGuids(), colliderIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
// ⭐ 标记为手动锁定:不受路径进度(0.1~0.9)限制,鱼离场前一直锁定
|
||||
currSitData.isManualLock = true;
|
||||
currSitData.SetLockTarget(monster, lockTr);
|
||||
@@ -3573,6 +3588,15 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
// ⭐ 手动锁定成功 → 激活自动锁定(该鱼死亡后自动转换目标)
|
||||
_autoLockActivated = true;
|
||||
}
|
||||
|
||||
/// <summary>是否处于 战神 + 三发 + 锁定 模式(散射激光 + 3个锁定圈)</summary>
|
||||
private bool IsZhanShenTripleMode()
|
||||
{
|
||||
return currSitData != null
|
||||
&& currSitData.currentZhanShenData != null
|
||||
&& toggle_Three != null && toggle_Three.isOn
|
||||
&& toggle_Lock != null && toggle_Lock.isOn;
|
||||
}
|
||||
private void UpdateLockFX()
|
||||
{
|
||||
|
||||
@@ -3650,36 +3674,42 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
}
|
||||
private void CheckLockTargetValid()
|
||||
{
|
||||
// ⭐⭐⭐ 三发模式:每个锁位独立维护 —— 鱼死了 或 路径离场时,只补那一个锁位,其他锁位不动
|
||||
// ⭐⭐⭐ 三发模式:每个锁位独立维护 —— 鱼死了/路径离场时只补那一个锁位,其他锁位不动。
|
||||
// 补位只尝试一次:补到了就锁上;补不到该锁位转"空置等手动点击"(不再自动补)。
|
||||
// (Count 由 SetTripleLockTargets 建立;HideTripleLockIcons 才清成 0)
|
||||
if (currSitData.tripleLockTargets.Count > 0)
|
||||
{
|
||||
// ⭐ 补齐到3个锁位(三发=最多3个目标):某位暂时没鱼可补就留空占位,下一帧继续尝试
|
||||
while (currSitData.tripleLockTargets.Count < 3)
|
||||
{
|
||||
currSitData.tripleLockTargets.Add(null);
|
||||
currSitData.tripleLockPositions.Add(null);
|
||||
}
|
||||
// ⭐ 固定3个锁位(三发=最多3个目标)
|
||||
currSitData.EnsureTripleLockSlots(3);
|
||||
|
||||
for (int i = currSitData.tripleLockTargets.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var t = currSitData.tripleLockTargets[i];
|
||||
|
||||
// ⭐ 鱼死了(被回收/销毁) → 补这一个锁位
|
||||
if (t == null || !t.gameObject.activeInHierarchy)
|
||||
// ---- 该锁位有鱼:判断是否需要更换 ----
|
||||
if (t != null && t.gameObject.activeInHierarchy)
|
||||
{
|
||||
RefillTripleLockSlot(i);
|
||||
// ⭐ 玩家手动点选的锁位 → 离场前一直跟,死了才换。
|
||||
// 手动身份是跟着鱼走的:被挤到子锁位后依然是手动,不会被自动换掉
|
||||
if (currSitData.IsTripleSlotManual(i)) continue;
|
||||
|
||||
// ⭐ 路径离场(超出 0.1~0.9) 或 被 SuoDing 取消勾选 → 只补这一个锁位
|
||||
if (!IsFishPathLockable(t) || !IsFishAllowedBySuoDing(t))
|
||||
RefillTripleLockSlot(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
// ⭐ 主锁位是玩家手动锁的 → 离场前一直跟,不自动更换
|
||||
if (i == 0 && currSitData.isManualLock) continue;
|
||||
// ---- 该锁位空着 ----
|
||||
// ⭐ "空置等手动点击"状态 → 不再自动补位,必须玩家点击才锁
|
||||
if (currSitData.IsTripleSlotIdle(i)) continue;
|
||||
|
||||
// ⭐ 自动锁定的锁位:路径离场(超出 0.1~0.9) 或 被 SuoDing 取消勾选
|
||||
// → 只补这一个锁位,其他锁位不动
|
||||
if (!IsFishPathLockable(t) || !IsFishAllowedBySuoDing(t))
|
||||
RefillTripleLockSlot(i);
|
||||
// ⭐ 刚打死后重新检测:只尝试这一次,成功就锁上,失败则转成"空置等手动"
|
||||
RefillTripleLockSlot(i);
|
||||
}
|
||||
|
||||
// ⭐ 三个锁位全空 → 暂时不锁定,等玩家手动点击才锁(关掉自动锁定激活标记)
|
||||
if (!currSitData.HasAnyTripleTarget)
|
||||
_autoLockActivated = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4220,13 +4250,23 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
auto = currSitData.IsAutoAttackOn
|
||||
};
|
||||
|
||||
// ⭐ 战神 三发 + 锁定:查找 3 个优先级目标,写入 monsterIDs(FireLaser 分散打三个用)
|
||||
// 正常炮台三合一打主锁目标(monCotl_Lock 已由 SyncLock/SyncBotLock 同步),不需要 monsterIDs
|
||||
// ⭐ 战神 三发 + 锁定:3个锁定目标写入 monsterIDs(FireLaser 分散打三个用)
|
||||
// ⭐ 优先用当前维护的3个锁位(玩家手动点选的目标) → 打哪锁哪
|
||||
// 锁位上没有有效目标时才按优先级现找。正常炮台三合一打主锁目标
|
||||
// (monCotl_Lock 已由 SyncLock/SyncBotLock 同步),不需要 monsterIDs
|
||||
if (isSanShe && isLock && currSitData.currentZhanShenData != null)
|
||||
{
|
||||
var targets = FindFireTargets(3);
|
||||
if (targets.Count > 0)
|
||||
fireData.monsterIDs = targets.Select(t => t.monster.guid).ToList();
|
||||
var lockedGuids = currSitData.GetTripleLockGuids();
|
||||
if (lockedGuids.Count > 0)
|
||||
{
|
||||
fireData.monsterIDs = lockedGuids;
|
||||
}
|
||||
else
|
||||
{
|
||||
var targets = FindFireTargets(3);
|
||||
if (targets.Count > 0)
|
||||
fireData.monsterIDs = targets.Select(t => t.monster.guid).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
SyncGameData sgd = new SyncGameData
|
||||
|
||||
Reference in New Issue
Block a user