215 lines
8.2 KiB
C#
215 lines
8.2 KiB
C#
using Assets.MyGame.Scripts.Net.API.GameConfig_SubClass;
|
|
using Assets.MyGame.Scripts.Net.APIResponses.Enum;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
/// <summary>
|
|
/// 单独锁定面板(SuoDing.prefab)。
|
|
/// ⭐ 本阶段只做界面:
|
|
/// - 单列表不分类,只显示 黄金鱼/特殊鱼/Boss鱼/特殊Boss(不含普通鱼)
|
|
/// - 每个 item 带 Toggle(勾选=作为锁定目标),按锁定优先级排序显示
|
|
/// - 全选/取消全选 两个按钮
|
|
/// - GetSelectedFishNumbers() 暴露选中列表,后续锁定功能从这里对接
|
|
/// </summary>
|
|
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;
|
|
|
|
/// <summary>fishNumber → 条目(TuJianItem 显示 + Toggle 勾选)</summary>
|
|
private readonly Dictionary<string, Entry> entries = new Dictionary<string, Entry>();
|
|
|
|
/// <summary>当前勾选的鱼编号集合(Toggle 的 onValueChanged 实时维护,锁定系统 O(1) 查询)</summary>
|
|
private readonly HashSet<string> selectedSet = new HashSet<string>();
|
|
|
|
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<string>();
|
|
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<string> set, string fishNumber)
|
|
{
|
|
if (!string.IsNullOrEmpty(fishNumber))
|
|
set.Add(fishNumber);
|
|
}
|
|
|
|
/// <summary>显示排序:特殊Boss(0) > Boss鱼(1) > 特殊鱼(2) > 黄金鱼(3),与自动锁定优先级一致</summary>
|
|
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<TuJianItem>(true);
|
|
var toggle = go.GetComponentInChildren<Toggle>(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;
|
|
}
|
|
|
|
// ==================== 选中列表(锁定对接入口) ====================
|
|
|
|
/// <summary>是否至少勾选了一条(白名单是否生效)。锁定系统每帧查询,用 O(1) 属性</summary>
|
|
public bool HasSelection => selectedSet.Count > 0;
|
|
|
|
/// <summary>当前勾选的鱼编号列表(锁定系统从这里读取)</summary>
|
|
public List<string> GetSelectedFishNumbers()
|
|
{
|
|
return new List<string>(selectedSet);
|
|
}
|
|
|
|
/// <summary>某条鱼是否被勾选(未创建条目视为未选中)。O(1),锁定系统逐鱼查询用</summary>
|
|
public bool IsFishSelected(string fishNumber)
|
|
{
|
|
return !string.IsNullOrEmpty(fishNumber) && selectedSet.Contains(fishNumber);
|
|
}
|
|
}
|