using System.Collections.Generic;
using Logic.Skill;
using RuntimeData;
using TH1_Logic.Core;
using UnityEngine;
namespace TH1_Renderer
{
internal class UnitStatusIcon
{
public int Level;
public StatusIconMono IconMono;
public GameObject IconObject;
}
///
/// 单位状态管理器 - 管理单位的所有重要负面状态显示
///
public class UnitStatusArea
{
private readonly Dictionary _statusIcons = new();
private readonly Dictionary _statusLevels = new();
private readonly Transform _statusContainer;
private readonly GameObject _statusIconPrefab;
private readonly UnityEngine.RectTransform _infoGroup;
// private const string KOMEIJI_FEAR_PATH = "TH1UI/Icon/SkillIcon/Komeiji/Skill_KomeijiFear";
// private const string KOMEIJI_FEAR2_PATH = "TH1UI/Icon/SkillIcon/Komeiji/Skill_KomeijiFear2";
///
/// 当前显示的状态数量
///
public int Count => _statusIcons.Count;
///
/// 获取所有当前显示的状态
///
internal IEnumerable AllIcons => _statusIcons.Values;
public UnitStatusArea(Transform statusContainer, GameObject statusIconPrefab, UnityEngine.RectTransform infoGroup = null)
{
_statusContainer = statusContainer;
_statusIconPrefab = statusIconPrefab;
_infoGroup = infoGroup;
}
///
/// 添加或更新状态显示
///
/// 技能类型
/// 单位完整类型
/// 是否有层数机制
/// 技能等级/层数
/// 是否成功添加或更新
public bool AddOrUpdateStatus(SkillType skillType, UnitFullType unitFullType, bool hasLevel, int level)
{
if (_statusIconPrefab == null || _statusContainer == null)
return false;
if (!_statusIcons.TryGetValue(skillType, out var existingIcon))
{
var newIconObj = GameObject.Instantiate(_statusIconPrefab, _statusContainer);
var iconMono = newIconObj.GetComponent();
if (iconMono == null)
{
iconMono = newIconObj.AddComponent();
}
existingIcon = new UnitStatusIcon
{
IconObject = newIconObj,
IconMono = iconMono,
Level = 0
};
_statusIcons.Add(skillType, existingIcon);
}
existingIcon.Level = level;
existingIcon.IconMono.SetContent(skillType, unitFullType, hasLevel, level);
// if (skillType == SkillType.KomeijiFear)
// {
// string targetPath = level >= 2 ? KOMEIJI_FEAR2_PATH : KOMEIJI_FEAR_PATH;
// var specialSprite = TH1Resource.ResourceLoader.Load(targetPath);
// if (specialSprite != null)
// {
// existingIcon.IconMono.SetIcon(specialSprite);
// }
// existingIcon.IconMono.SetColor(Color.green);
// }
// else
// {
// existingIcon.IconMono.SetColor(Color.white);
// }
existingIcon.IconMono.SetColor(Color.white);
_statusLevels[skillType] = level;
RefreshLayout();
return true;
}
///
/// 移除指定状态
///
/// 技能类型
/// 是否成功移除
public bool RemoveStatus(SkillType skillType)
{
if (!_statusIcons.TryGetValue(skillType, out var icon))
return false;
if (icon.IconObject != null)
{
// GameObject.Destroy 是延迟销毁;先 SetActive(false) 让 LayoutGroup 在本帧
// 重建时立即忽略此节点,否则 StatusAreaContainer 的尺寸测量仍会包含它,
// 导致父节点(InfoGroup/背景板)的尺寸无法收缩。
icon.IconObject.SetActive(false);
GameObject.Destroy(icon.IconObject);
}
_statusIcons.Remove(skillType);
_statusLevels.Remove(skillType);
// 移除后强制刷新布局
RefreshLayout();
return true;
}
///
/// 检查是否包含指定状态
///
public bool HasStatus(SkillType skillType)
{
return _statusIcons.ContainsKey(skillType);
}
///
/// 获取指定状态的层数
///
public int GetStatusLevel(SkillType skillType)
{
return _statusLevels.TryGetValue(skillType, out var level) ? level : 0;
}
///
/// 清除所有状态
///
public void ClearAllStatus()
{
foreach (var icon in _statusIcons.Values)
{
if (icon.IconObject != null)
{
// 先 SetActive(false) 让 LayoutGroup 立即忽略,再 Destroy(延迟销毁)。
icon.IconObject.SetActive(false);
GameObject.Destroy(icon.IconObject);
}
}
_statusIcons.Clear();
_statusLevels.Clear();
// 清除后强制刷新布局
RefreshLayout();
}
///
/// 同步单位技能数据到状态显示区域
/// 仅显示 SkillInfo.ShowOnUnitMono = true 且当前单位拥有的技能
///
public void SyncWithUnitSkills(UnitData unitData)
{
if (unitData == null || unitData.Skills == null) return;
var showSkills = new HashSet();
foreach (var skill in unitData.Skills)
{
if (skill == null) continue;
var skillType = skill.GetSkillType();
if (!Table.Instance.SkillDataAssets.GetSkillInfo(skillType, out var skillInfo)) continue;
if (skillInfo.ShowOnUnitMono)
{
showSkills.Add(skillType);
}
}
var toRemove = new List();
foreach (var skillType in _statusIcons.Keys)
{
if (!showSkills.Contains(skillType))
toRemove.Add(skillType);
}
bool hasChanged = false;
foreach (var skillType in toRemove)
{
RemoveStatus(skillType);
hasChanged = true;
}
foreach (var skillType in showSkills)
{
if (!unitData.GetSkill(skillType, out var skill))
{
if (HasStatus(skillType))
{
RemoveStatus(skillType);
hasChanged = true;
}
continue;
}
if (skill.HasLevel && skill.NoShow)
{
if (HasStatus(skillType))
{
RemoveStatus(skillType);
hasChanged = true;
}
continue;
}
bool hasLevel = skill.HasLevel;
int level = hasLevel ? skill.Level : 1;
if (!HasStatus(skillType) || GetStatusLevel(skillType) != level)
{
AddOrUpdateStatus(skillType, unitData.UnitFullType, hasLevel, level);
hasChanged = true;
}
else if (_statusIcons.TryGetValue(skillType, out var existingIcon))
{
existingIcon.IconMono.SetContent(skillType, unitData.UnitFullType, hasLevel, level);
}
}
if (hasChanged)
{
RefreshLayout();
}
}
///
/// 刷新所有状态的显示位置(用于自动布局更新)
///
public void RefreshLayout()
{
if (_statusContainer == null) return;
// 强制刷新布局
if (_statusContainer is UnityEngine.RectTransform rectTransform)
{
UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(rectTransform);
}
// 图标增减后同时重排 InfoGroup,让背景板等父级 LayoutGroup 感知尺寸变化
if (_infoGroup != null)
{
UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(_infoGroup);
}
}
///
/// 设置整个状态区域是否可见
///
public void SetAreaVisible(bool visible)
{
if (_statusContainer != null)
_statusContainer.gameObject.SetActive(visible);
}
}
}