using Assets.MyGame.Scripts.Net.API.GameConfig_SubClass;
using Assets.MyGame.Scripts.Net.APIResponses.Enum;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
///
/// 单独锁定面板(SuoDing.prefab)。
/// ⭐ 本阶段只做界面:
/// - 单列表不分类,只显示 黄金鱼/特殊鱼/Boss鱼/特殊Boss(不含普通鱼)
/// - 每个 item 带 Toggle(勾选=作为锁定目标),按锁定优先级排序显示
/// - 全选/取消全选 两个按钮
/// - GetSelectedFishNumbers() 暴露选中列表,后续锁定功能从这里对接
///
public class SuoDingPanel : SubUIBase
{
[Header("Item 模板(TuJianItem+Toggle,可挂在模板自身或子节点;模板未激活也行,克隆后会自动激活)")]
public GameObject prefab_Item;
[Header("列表父节点(不分类,所有条目都放这里)")]
public Transform parent_List;
[Header("按钮")]
public Button btn_SelectAll; // 全选
public Button btn_DeselectAll; // 取消全选
[Header("滚动视图")]
public ScrollRect scrollRect;
/// fishNumber → 条目(TuJianItem 显示 + Toggle 勾选)
private readonly Dictionary entries = new Dictionary();
/// 当前勾选的鱼编号集合(Toggle 的 onValueChanged 实时维护,锁定系统 O(1) 查询)
private readonly HashSet selectedSet = new HashSet();
private class Entry
{
public string fishNumber;
public FishTypeEnum fishType;
public TuJianItem item;
public Toggle toggle;
}
public override void Awake()
{
base.Awake();
if (btn_SelectAll != null) btn_SelectAll.onClick.AddListener(SelectAll);
if (btn_DeselectAll != null) btn_DeselectAll.onClick.AddListener(DeselectAll);
BuildList();
// ⭐ 默认全选:锁定目标=全部高价值鱼(和当前自动锁定行为一致),玩家在面板里再手动调整
SelectAll();
}
protected override void OnShow(object args = null)
{
base.OnShow(args);
// 打开时滚动到最上方
// ⭐ 只重置纵向(verticalNormalizedPosition):
// normalizedPosition 会同时写 x 轴(=0 横向滚到最左),ScrollRect 会直接改写
// content(列表父对象)的 anchoredPosition.x,导致父对象 X 从 0 被移走
if (scrollRect != null)
scrollRect.verticalNormalizedPosition = 1f;
}
protected override void OnHide()
{
base.OnHide();
// ⭐ 关闭面板 = 应用勾选结果:通知主面板打开锁定并按勾选白名单自动锁定
// (parentUIBase 就是挂着本面板的主面板,各游戏主面板都继承 GameMainPanel_FishBase)
if (uIManager != null && uIManager.parentUIBase is GameMainPanel_FishBase main)
main.ApplySuoDingSelection();
}
// ==================== 列表构建 ====================
private void BuildList()
{
if (prefab_Item == null || parent_List == null) return;
// ① 收集本房间可出鱼编号(鱼阵条目解析出阵内实际鱼),去重
var fishNumbers = new HashSet();
var spawnList = CreateFishManager.Instance != null ? CreateFishManager.Instance.spawnList : null;
if (spawnList != null)
{
foreach (var spawn in spawnList)
{
if (spawn.type == 2)
{
// 鱼阵条目:fishNumber 存的是鱼阵编号,解析出阵内实际生成的鱼
if (CreateFishManager.Instance.FishArrayDatas.TryGetValue(spawn.fishNumber, out var yz))
TryAddFishNumber(fishNumbers, yz.fishNumber);
}
else
{
TryAddFishNumber(fishNumbers, spawn.fishNumber);
}
}
}
// ② 过滤:只保留 黄金鱼/特殊鱼/Boss鱼/特殊Boss(不显示普通鱼)
var filtered = new List<(string fishNumber, FishTypeEnum fishType)>();
foreach (var fn in fishNumbers)
{
if (!GameManager.Instance.dic_fishTypeConfigs.TryGetValue(fn, out var cfg)) continue;
var t = (FishTypeEnum)cfg.fishType;
if (t == FishTypeEnum.普通鱼) continue;
filtered.Add((fn, t));
}
// ③ 排序:与自动锁定优先级一致 特殊Boss > Boss鱼 > 特殊鱼 > 黄金鱼,同类型按编号
filtered.Sort((a, b) =>
{
int pa = GetTypeSortOrder(a.fishType);
int pb = GetTypeSortOrder(b.fishType);
if (pa != pb) return pa.CompareTo(pb);
return CompareFishNumber(a.fishNumber, b.fishNumber);
});
// ④ 实例化条目
foreach (var (fishNumber, fishType) in filtered)
CreateItem(fishNumber, fishType);
}
private void TryAddFishNumber(HashSet set, string fishNumber)
{
if (!string.IsNullOrEmpty(fishNumber))
set.Add(fishNumber);
}
/// 显示排序:特殊Boss(0) > Boss鱼(1) > 特殊鱼(2) > 黄金鱼(3),与自动锁定优先级一致
private static int GetTypeSortOrder(FishTypeEnum t)
{
switch (t)
{
case FishTypeEnum.特殊Boss: return 0;
case FishTypeEnum.Boss鱼: return 1;
case FishTypeEnum.特殊鱼: return 2;
case FishTypeEnum.黄金鱼: return 3;
default: return int.MaxValue;
}
}
private static int CompareFishNumber(string a, string b)
{
if (int.TryParse(a, out var na) && int.TryParse(b, out var nb))
return na.CompareTo(nb);
return string.CompareOrdinal(a, b);
}
private void CreateItem(string fishNumber, FishTypeEnum fishType)
{
// 模板是面板下的未激活场景对象,克隆后要手动激活
var go = Instantiate(prefab_Item, parent_List);
go.SetActive(true);
go.name = $"SuoDingItem_{fishNumber}";
// TuJianItem / Toggle 可挂在模板自身或子节点(两种摆法都兼容)
var item = go.GetComponentInChildren(true);
var toggle = go.GetComponentInChildren(true);
if (item == null) return;
// 黄金鱼显示固定倍数,特殊鱼/Boss/特殊Boss显示"最高X倍"(与图鉴一致)
item.InItItem(new RoomFishDetailConfig { fishNumber = fishNumber }, fishType == FishTypeEnum.黄金鱼);
if (toggle != null)
{
// ⭐ 多选:清掉可能误挂的排他 ToggleGroup(注册进组后全选会被组吞成单选)
if (toggle.group != null) toggle.group = null;
// ⭐ 勾选状态实时同步到 selectedSet(全选/取消全选/手动点击都会触发 onValueChanged)
toggle.onValueChanged.AddListener(on =>
{
if (on) selectedSet.Add(fishNumber);
else selectedSet.Remove(fishNumber);
});
if (toggle.isOn) selectedSet.Add(fishNumber);
}
entries[fishNumber] = new Entry { fishNumber = fishNumber, fishType = fishType, item = item, toggle = toggle };
}
// ==================== 全选/取消全选 ====================
public void SelectAll()
{
foreach (var e in entries.Values)
if (e.toggle != null) e.toggle.isOn = true;
}
public void DeselectAll()
{
foreach (var e in entries.Values)
if (e.toggle != null) e.toggle.isOn = false;
}
// ==================== 选中列表(锁定对接入口) ====================
/// 是否至少勾选了一条(白名单是否生效)。锁定系统每帧查询,用 O(1) 属性
public bool HasSelection => selectedSet.Count > 0;
/// 当前勾选的鱼编号列表(锁定系统从这里读取)
public List GetSelectedFishNumbers()
{
return new List(selectedSet);
}
/// 某条鱼是否被勾选(未创建条目视为未选中)。O(1),锁定系统逐鱼查询用
public bool IsFishSelected(string fishNumber)
{
return !string.IsNullOrEmpty(fishNumber) && selectedSet.Contains(fishNumber);
}
}