This commit is contained in:
2026-10-04 18:59:57 +08:00
parent 3bb60ab41c
commit d3d160518b
3 changed files with 525 additions and 7 deletions
@@ -969,6 +969,16 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
RestoreFrozenDirectors();
}
/// <summary>
/// ⭐ 长按锁定键(0.6秒)打开的"锁定设置"面板。
/// 默认 = 通用 SuoDing 面板;XJMH 覆写为原版 PW_SetLock 面板(其白名单通过覆写 IsFishAllowedBySuoDing 提供)。
/// </summary>
protected virtual void OpenLockSettingPanel()
{
subUIManager.ShowAsync(UIPanel.GameSuoDing);
}
public virtual void Start()
{
btn_SettingList.onClick.AddListener(() =>
@@ -1013,9 +1023,10 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
if (lockLongPress == null) lockLongPress = toggle_Lock.gameObject.AddComponent<ToggleLongPress>();
lockLongPress.onLongPress += () =>
{
subUIManager.ShowAsync(UIPanel.GameSuoDing);
OpenLockSettingPanel();
};
}
toggle_BaoZou.onValueChanged.AddListener(on =>
{
if (!on)
@@ -3804,8 +3815,9 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
/// - 非"图鉴锁定"模式 → 不限制(正常锁定想锁什么就锁什么)
/// - 图鉴锁定模式:一个都没勾 → 不限制;勾了至少一条 → 只允许锁勾选的鱼
/// 手动锁定(玩家点击选鱼)不受此限制。
/// ⭐ XJMH 覆写本方法改用原版 PW_SetLock 面板的勾选列表。
/// </summary>
private bool IsFishAllowedBySuoDing(MonsterContral m)
protected virtual bool IsFishAllowedBySuoDing(MonsterContral m)
{
// ⭐ 只有走"长按图鉴"那条路才启用白名单,避免图鉴勾选干扰正常锁定
if (!_suoDingMode) return true;
@@ -4149,6 +4149,7 @@ RectTransform:
- {fileID: 6208906429163189928}
- {fileID: 8927348487773343547}
- {fileID: 1425888953497163554}
- {fileID: 6781559484914116352}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
@@ -4280,6 +4281,9 @@ MonoBehaviour:
type: 3}
helpItem2Template: {fileID: 1945686605193428, guid: 4a2156dc91c438048ae799db55c7113d,
type: 3}
lockSetPanel: {fileID: 6702752155659137683}
lockSetItemTemplate: {fileID: 1136181874444908, guid: 53ed3608912462847bc3c8795cdbdb50,
type: 3}
nukeItemStagger: 0.1
nukeItemPopTime: 0.1
popupOpenTime: 0.2
@@ -17761,6 +17765,155 @@ RectTransform:
type: 3}
m_PrefabInstance: {fileID: 6189131244199501401}
m_PrefabAsset: {fileID: 0}
--- !u!1001 &6702469639535777356
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 245637205031072731}
m_Modifications:
- target: {fileID: 1971641677849823, guid: 664565cc384b89c41ac1e44c5ece078a, type: 3}
propertyPath: m_Name
value: PW_SetLock
objectReference: {fileID: 0}
- target: {fileID: 224268524126657739, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 224268524126657739, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 224442425200591311, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 224442425200591311, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_Pivot.x
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_Pivot.y
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_AnchorMax.x
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_AnchorMax.y
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_AnchorMin.x
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_AnchorMin.y
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_SizeDelta.x
value: 969
objectReference: {fileID: 0}
- target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_SizeDelta.y
value: 593
objectReference: {fileID: 0}
- target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: -0
objectReference: {fileID: 0}
- target: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: -0
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 664565cc384b89c41ac1e44c5ece078a, type: 3}
--- !u!1 &6702752155659137683 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 1971641677849823, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
m_PrefabInstance: {fileID: 6702469639535777356}
m_PrefabAsset: {fileID: 0}
--- !u!224 &6781559484914116352 stripped
RectTransform:
m_CorrespondingSourceObject: {fileID: 224903780194480460, guid: 664565cc384b89c41ac1e44c5ece078a,
type: 3}
m_PrefabInstance: {fileID: 6702469639535777356}
m_PrefabAsset: {fileID: 0}
--- !u!1001 &6807194459827413149
PrefabInstance:
m_ObjectHideFlags: 0
@@ -94,6 +94,14 @@ public class GameMainPanel_XJMH : GameMainPanel_FishBase
[Tooltip("操作/玩法条目模板:拖 Assets/Art/XJMH/pw/pw_prefab/item/PW_HelpItem2.prefab(内含 _textName / _textDes1~11 / _imgIcon1~5);留空则这两个页签只切换、不生成条目")]
public GameObject helpItem2Template;
// ==================== 锁定设置面板(长按锁定键打开,原版 PW_SetLock) ====================
[Header("锁定设置面板(长按锁定键打开,原版 PW_SetLock)")]
[Tooltip("原版 PW_SetLock 面板:拖 Assets/Art/XJMH/pw/pw_prefab/msgbox/PW_SetLock.prefab 的实例(初始自动隐藏);留空则长按锁定退回通用 SuoDing 面板")]
public GameObject lockSetPanel;
[Tooltip("锁定条目模板:拖 Assets/Art/XJMH/pw/pw_prefab/item/PW_SetLockItem.prefab;留空则只开关面板、不生成条目")]
public GameObject lockSetItemTemplate;
[Header("核弹列表动画(照原版 Rocket 逐项弹出)")]
[Tooltip("相邻条目的弹出/收缩间隔(秒),原版 0.1")]
public float nukeItemStagger = 0.1f;
@@ -113,11 +121,22 @@ public class GameMainPanel_XJMH : GameMainPanel_FishBase
InitNukeProp();
InitSettingPopup();
InitHelpPanel();
InitLockSetPanel();
}
public override void Start()
{
base.Start();
// ⭐ 关掉锁定开关 → 退出"锁定面板锁定"模式(与父类通用版语义一致):
// 下次再开锁定开关 = 正常锁定,不受锁定面板勾选约束
if (toggle_Lock != null)
{
toggle_Lock.onValueChanged.AddListener(on =>
{
if (!on) _xjLockWhiteOn = false;
});
}
}
protected override void OnShow(object args = null)
@@ -212,6 +231,14 @@ public class GameMainPanel_XJMH : GameMainPanel_FishBase
helpPanel.transform.localScale = Vector3.one;
helpPanel.SetActive(false);
}
// 锁定设置面板:离场立即收起
if (lockSetPanel != null)
{
lockSetPanel.transform.DOKill();
lockSetPanel.transform.localScale = Vector3.one;
lockSetPanel.SetActive(false);
}
}
/// <summary>
@@ -1163,15 +1190,22 @@ public class GameMainPanel_XJMH : GameMainPanel_FishBase
return dic.TryGetValue(fishNumber, out var sprite) ? sprite : null;
}
/// <summary>
/// 设置条目里某个文本节点的位置与内容。
/// ⭐ PW_HelpItem2.prefab 里的文本挂的是 UGUI 老版 Text(原版组件,PW_CN_Font 中文字体),
/// 不是 TMP → 两种都要兼容(TMP 优先,找不到再写老版 Text)。
/// </summary>
/// <summary>设置条目里某个文本节点的位置与内容(帮助/锁定条目通用:先摆位置再写文本)</summary>
private static void SetHelpText(Transform tf, float x, float y, string text)
{
if (tf == null) return;
tf.localPosition = new Vector3(x, y, 0f);
SetTextContent(tf, text);
}
/// <summary>
/// 写文本内容(不动位置)。
/// ⭐ 原版 pw 预制体(PW_HelpItem2 / PW_SetLockItem)里的文本挂的是 UGUI 老版 Text
/// (原版组件,PW_CN_Font 中文字体),不是 TMP → 两种都要兼容(TMP 优先,找不到再写老版 Text)。
/// </summary>
private static void SetTextContent(Transform tf, string text)
{
if (tf == null) return;
var tmp = tf.GetComponent<TextMeshProUGUI>();
if (tmp == null) tmp = tf.GetComponentInChildren<TextMeshProUGUI>(true);
@@ -1573,6 +1607,325 @@ public class GameMainPanel_XJMH : GameMainPanel_FishBase
},
};
// ==================== 锁定设置面板(原版 PW_SetLock,长按锁定键打开) ====================
// 移植自原版 PW_SetLock.txt:
// - 列表 = 原版 PW_Config.Enemy 里 canAutoLock=true 的敌人(奇数进"1"行、偶数进"2"行,两行横向排列)
// - 点条目切换勾选(_choose 标记);mBtnAll 全选 / mBtnNone 全不选(mGOAllFlag/mGONoneFlag 指示)
// - 关闭(mBtnBack)时应用:有勾选 → 开锁定 + 激活自动锁定,且之后的自动锁定只锁勾选的鱼
// - 白名单通过覆写父类 IsFishAllowedBySuoDing 提供,父类通用流程不动
// - 鱼图与图鉴页同源:直接取 FishResourcesData.fishResourcesSpritesDic(不需要额外注册)
/// <summary>锁定条目配置(对应原版 canAutoLock 敌人;编号为本项目鱼表编号)</summary>
private sealed class XjmhLockCfg
{
public string name; // 仅日志用
public int fishNumber;
public string score; // 原版 PW_Config.Enemy[].score 原样(富文本)
}
/// <summary>
/// 原版 PW_Config.Enemy 中 canAutoLock=true 的敌人(按原版顺序),编号映射到本项目鱼表:
/// 12031=幸运轮、12030=破坏球、12029=星际巡航、12028=机械蝎、12026=爆裂金鲨、
/// 12034=烈焰风暴、12023=小丑扑克、12022=幸运飞碟。
/// ⚠️ 原版还有 type=2000 女王龙,本项目鱼表还没有它,先不加;接进鱼表后在这里补一行即可。
/// 这里加/删一行就会自动多/少一个锁定条目和勾选项(列表、全选/全不选、白名单都按这份配置走)。
/// </summary>
private static readonly XjmhLockCfg[] XjmhLockCfgList =
{
new XjmhLockCfg { name = "幸运轮", fishNumber = 12031, score = "<size=21>特殊奖励</size>" },
new XjmhLockCfg { name = "破坏球", fishNumber = 12030, score = "<size=21>特殊奖励</size>" },
new XjmhLockCfg { name = "星际巡航", fishNumber = 12029, score = "<size=21>特殊奖励</size>" },
new XjmhLockCfg { name = "机械蝎", fishNumber = 12028, score = "<size=21>特殊奖励</size>" },
new XjmhLockCfg { name = "爆裂金鲨", fishNumber = 12026, score = "<size=21>特殊奖励</size>" },
new XjmhLockCfg { name = "烈焰风暴", fishNumber = 12034, score = "<size=21>特殊奖励</size>" },
new XjmhLockCfg { name = "小丑扑克", fishNumber = 12023, score = "<size=21>特殊玩法</size>" },
new XjmhLockCfg { name = "幸运飞碟", fishNumber = 12022, score = "<size=21>特殊玩法</size>" },
};
/// <summary>原版 PW_Config.Text.SetLockDes(面板底部说明)</summary>
private const string LockSetDesText = "<color=#EEB548>勾选锁定敌机, 设定锁定范围</color>勾选敌机将会自动锁定勾选的敌机进行射击; 若不勾选, 则需手动点击敌机进行预订射击自动开启后, <color=#EEB548>点击敌机切换锁定目标</color>";
/// <summary>锁定面板内部节点(按原版 PW_SetLock 预制体名字找)</summary>
private Button _lockBtnBack; // mBtnBack(关闭并应用)
private Button _lockBtnAll; // mBtnAll(全选)
private Button _lockBtnNone; // mBtnNone(全不选)
private GameObject _lockAllFlag; // mGOAllFlag(全选指示)
private GameObject _lockNoneFlag; // mGONoneFlag(全不选指示)
private Transform _lockRow1; // ScrollView/Viewport/Content/1(横向第一行)
private Transform _lockRow2; // ScrollView/Viewport/Content/2(横向第二行)
private RectTransform _lockContent; // ScrollView/Viewport/Content(照原版按条数调宽度)
/// <summary>已生成条目的勾选标记(全选/全不选/单点后统一刷新用)</summary>
private sealed class LockSetItemRef
{
public string key; // fishNumber 字符串(与锁定白名单判断一致)
public GameObject choose; // _choose 标记
}
private readonly List<LockSetItemRef> _lockSetItems = new List<LockSetItemRef>();
/// <summary>勾选的锁定鱼号(对应原版 LockEnemyList,跨开关面板保留;空 = 不限制)</summary>
private readonly HashSet<string> _xjLockSelected = new HashSet<string>();
/// <summary>是否处于"锁定面板白名单"模式(面板勾选后开启;关掉锁定开关即退出,与通用版语义一致)</summary>
private bool _xjLockWhiteOn;
/// <summary>
/// 锁定面板初始化:抓内部节点、绑按钮(照原版 PW_SetLock:InitUI)、写固定文案。
/// 未拖面板时全部跳过(长按退回父类通用 SuoDing 面板,玩法不受影响)。
/// </summary>
private void InitLockSetPanel()
{
if (lockSetPanel == null) return;
lockSetPanel.SetActive(false); // 初始收起
// 背景遮挡:原版打开时禁用射击(SetCanShoot(false)),本项目等价做法 = 让面板根图挡射线,
// 避免调锁定时点到后面的打鱼输入
var rootImg = lockSetPanel.GetComponent<Image>();
if (rootImg != null) rootImg.raycastTarget = true;
// 返回(照原版:关闭即保存并应用勾选)
_lockBtnBack = FindButton(lockSetPanel.transform, "mBtnBack");
if (_lockBtnBack != null)
{
_lockBtnBack.onClick.RemoveAllListeners();
_lockBtnBack.onClick.AddListener(OnLockSetBackClicked);
}
// 全选 / 全不选
_lockBtnAll = FindButton(lockSetPanel.transform, "mBtnAll");
if (_lockBtnAll != null)
{
_lockBtnAll.onClick.RemoveAllListeners();
_lockBtnAll.onClick.AddListener(SelectAllLockItems);
}
_lockBtnNone = FindButton(lockSetPanel.transform, "mBtnNone");
if (_lockBtnNone != null)
{
_lockBtnNone.onClick.RemoveAllListeners();
_lockBtnNone.onClick.AddListener(SelectNoneLockItems);
}
// 两行条目容器(ScrollView/Viewport/Content 下的 1 / 2)
var content = FindChildByName(lockSetPanel.transform, "Content");
_lockContent = content as RectTransform;
_lockRow1 = content != null ? content.Find("1") : null;
_lockRow2 = content != null ? content.Find("2") : null;
_lockAllFlag = FindChildByName(lockSetPanel.transform, "mGOAllFlag")?.gameObject;
_lockNoneFlag = FindChildByName(lockSetPanel.transform, "mGONoneFlag")?.gameObject;
// 固定文案(照原版 InitView)
SetTextContent(FindChildByName(lockSetPanel.transform, "mTextDes"), LockSetDesText);
SetTextContent(_lockBtnAll != null ? FindChildByName(_lockBtnAll.transform, "Text") : null, "全选");
SetTextContent(_lockBtnNone != null ? FindChildByName(_lockBtnNone.transform, "Text") : null, "全不选");
}
/// <summary>按名字找节点上的按钮(节点上没有就往子节点找)</summary>
private static Button FindButton(Transform root, string name)
{
var tf = FindChildByName(root, name);
if (tf == null) return null;
var btn = tf.GetComponent<Button>();
return btn != null ? btn : tf.GetComponentInChildren<Button>(true);
}
/// <summary>
/// ⭐ 覆写父类:XJMH 长按锁定键打开原版 PW_SetLock 面板。
/// (星际迷航的可锁定敌机是固定的一批 boss/特殊鱼 —— 原版 canAutoLock 配置,
/// 而不是通用版按房间出鱼列表;通用版 SuoDing 不适用这里。)
/// 未拖面板时退回父类通用实现。
/// </summary>
protected override void OpenLockSettingPanel()
{
if (lockSetPanel == null)
{
base.OpenLockSettingPanel();
return;
}
if (lockSetPanel.activeSelf) return;
BuildLockSetList();
OpenScalePanel(lockSetPanel);
}
/// <summary>
/// 生成锁定条目(照原版 PW_SetLock:InitUI):
/// 第 i 条按奇偶交替放进 1/2 两行,条目 = 克隆 PW_SetLockItem 模板后填图、分值、标记;
/// 列表宽度照原版公式(≤10 条 = 60,之后每多 2 条再加 181)。
/// </summary>
private void BuildLockSetList()
{
if (_lockRow1 == null || _lockRow2 == null || lockSetItemTemplate == null)
{
Debug.LogWarning("[XJMH] 锁定面板缺少行容器(1/2)或条目模板,条目无法生成");
return;
}
ClearLockRow(_lockRow1);
ClearLockRow(_lockRow2);
_lockSetItems.Clear();
for (int i = 0; i < XjmhLockCfgList.Length; i++)
{
var cfg = XjmhLockCfgList[i];
var row = (i % 2 == 0) ? _lockRow1 : _lockRow2; // 原版 1-based 奇数进"1",这里 0-based 偶数进"1",等价
var go = Instantiate(lockSetItemTemplate, row);
go.SetActive(true);
FillLockSetItem(go, cfg);
_lockSetItems.Add(new LockSetItemRef
{
key = cfg.fishNumber.ToString(),
choose = FindChildByName(go.transform, "_choose")?.gameObject,
});
}
// 照原版调列表宽度(横向滚动范围)
if (_lockContent != null)
{
int count = XjmhLockCfgList.Length;
float extra = count <= 10 ? 0f : Mathf.Ceil((count - 10) * 0.5f);
_lockContent.sizeDelta = new Vector2(60f + extra * 181f, _lockContent.sizeDelta.y);
}
RefreshLockSetChecks();
Debug.Log($"[XJMH] 锁定面板条目: {XjmhLockCfgList.Length} 条");
}
/// <summary>清空一行旧条目(条目模板自身/同名跳过,避免把模板删掉)</summary>
private void ClearLockRow(Transform row)
{
for (int i = row.childCount - 1; i >= 0; i--)
{
var child = row.GetChild(i).gameObject;
if (lockSetItemTemplate != null
&& (child == lockSetItemTemplate || child.name == lockSetItemTemplate.name)) continue;
Destroy(child);
}
}
/// <summary>填一条锁定条目(照原版:_imgIcon/_textScore/_flag/_choose/_bonus;点击切换勾选)</summary>
private void FillLockSetItem(GameObject item, XjmhLockCfg cfg)
{
if (item == null || cfg == null) return;
// 图标:读"图鉴"同款鱼图(进房时已按 TuJian 标签加载好;没有就保持隐藏)
var iconTf = FindChildByName(item.transform, "_imgIcon");
if (iconTf != null)
{
var img = iconTf.GetComponent<Image>();
if (img == null) img = iconTf.GetComponentInChildren<Image>(true);
var sprite = GetTuJianFishSprite(cfg.fishNumber);
if (img != null && sprite != null)
{
img.sprite = sprite;
img.enabled = true;
}
}
// 分值文本(原版富文本原样,如"<size=21>特殊奖励</size>")
SetTextContent(FindChildByName(item.transform, "_textScore"), cfg.score);
// 特殊标记(原版 setActive(v.special);这批锁定敌人全部为 special)
var flagTf = FindChildByName(item.transform, "_flag");
if (flagTf != null) flagTf.gameObject.SetActive(true);
// 奖金飞机标记:原版锁定的敌人没有 isBonus,恒隐藏
var bonusTf = FindChildByName(item.transform, "_bonus");
if (bonusTf != null) bonusTf.gameObject.SetActive(false);
// 勾选标记(保留上次勾选结果)
var chooseTf = FindChildByName(item.transform, "_choose");
if (chooseTf != null) chooseTf.gameObject.SetActive(_xjLockSelected.Contains(cfg.fishNumber.ToString()));
// 点击切换勾选(照原版 AddClick(helpItem))
var btn = item.GetComponent<Button>();
if (btn == null) btn = item.GetComponentInChildren<Button>(true);
if (btn != null)
{
string key = cfg.fishNumber.ToString();
btn.onClick.RemoveAllListeners();
btn.onClick.AddListener(() =>
{
if (_xjLockSelected.Contains(key)) _xjLockSelected.Remove(key);
else _xjLockSelected.Add(key);
RefreshLockSetChecks();
});
}
}
/// <summary>刷新所有条目的勾选标记 + 全选/全不选指示(照原版 CheckLock)</summary>
private void RefreshLockSetChecks()
{
for (int i = 0; i < _lockSetItems.Count; i++)
{
var it = _lockSetItems[i];
if (it.choose != null) it.choose.SetActive(_xjLockSelected.Contains(it.key));
}
RefreshLockSetFlags();
}
/// <summary>全选/全不选指示:一个没勾 → mGONoneFlag;全勾 → mGOAllFlag(照原版 CheckLock)</summary>
private void RefreshLockSetFlags()
{
int sel = CountLockSelected();
if (_lockNoneFlag != null) _lockNoneFlag.SetActive(sel == 0);
if (_lockAllFlag != null) _lockAllFlag.SetActive(sel == XjmhLockCfgList.Length);
}
/// <summary>当前勾选条数(只数列表里存在的敌人,与全选框联动)</summary>
private int CountLockSelected()
{
int sel = 0;
for (int i = 0; i < XjmhLockCfgList.Length; i++)
if (_xjLockSelected.Contains(XjmhLockCfgList[i].fishNumber.ToString())) sel++;
return sel;
}
/// <summary>全选:勾上列表里的所有敌人(照原版 mBtnAll)</summary>
private void SelectAllLockItems()
{
for (int i = 0; i < XjmhLockCfgList.Length; i++)
_xjLockSelected.Add(XjmhLockCfgList[i].fishNumber.ToString());
RefreshLockSetChecks();
}
/// <summary>全不选:清空勾选(照原版 mBtnNone)</summary>
private void SelectNoneLockItems()
{
_xjLockSelected.Clear();
RefreshLockSetChecks();
}
/// <summary>
/// 返回键(照原版 mBtnBack):收起面板并应用勾选——
/// 有勾选 → 开锁定 + 激活自动锁定(之后自动锁定只锁勾选的鱼);没勾 → 正常锁定不限制。
/// </summary>
private void OnLockSetBackClicked()
{
int sel = CountLockSelected();
CloseScalePanel(lockSetPanel);
// 与通用 SuoDing 面板同一套应用流程(开锁定开关 + 激活自动锁定);
// 勾选结果是否限制锁定,由 XJMH 自己的白名单标记 + 覆写的 IsFishAllowedBySuoDing 决定
_xjLockWhiteOn = sel > 0;
ApplySuoDingSelection();
}
/// <summary>
/// ⭐ 覆写父类白名单:XJMH 用原版 PW_SetLock 面板的勾选列表(而不是通用 SuoDingPanel)。
/// 语义与父类一致:只有"锁定面板勾选过至少一条"才进入白名单模式,之后自动锁定只允许锁勾选的鱼;
/// 关掉锁定开关即退出该模式;未进入该模式 / 一个都没勾 → 不限制(正常锁定)。
/// </summary>
protected override bool IsFishAllowedBySuoDing(MonsterContral m)
{
if (!_xjLockWhiteOn) return true;
if (m == null) return false;
if (_xjLockSelected.Count == 0) return true;
return _xjLockSelected.Contains(m.monsterData?.fishTypeConfig?.fishNumber);
}
// ==================== 缩放弹窗工具 ====================
/// <summary>缩放弹出:面板激活 + 从 0 放大到 1(OutBack,轻微回弹)</summary>