TH1/Unity/Assets/Scripts/TH1_UI/View/Info/UIInfoHeroView.cs
2026-05-14 17:11:52 +08:00

387 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Logic.Action;
using Logic.Audio;
using Logic.Multilingual;
using NUnit.Framework.Constraints;
using RuntimeData;
using TH1_Core.Events;
using TH1_Core.Managers;
using TH1_Logic.Action;
using TH1_Logic.Core;
using TH1_Logic.MatchConfig;
using TMPro;
using Unity.Collections;
using UnityEngine;
using UnityEngine.UI;
namespace TH1_UI.View.Info
{
public class UIInfoHeroView : Base.View
{
public ViDelegateAssisstant.Dele OnBtnCloseClick;
public GameObject PoolGroup;
[Header("已出战的格子")]
public List<UIInfoHeroPickedRowMono> PickedList;
[Header("选择池的格子")]
public List<UIInfoHeroAvatarMono> Pool;
//确认选择出战英雄的按钮
public Button CloseButton;
public Button CheckButton;
public Button ReturnButton;
public Button BlockButton;
public RectTransform TwoPanelTransform;
[Header("市政卡区域")]
public GameObject CultureCardArea;
public GameObject UIInfoCultureCardMonoPrefab;
private List<UIInfoCultureCardMono> _cultureCardList = new List<UIInfoCultureCardMono>();
[Header("文化任务区域")]
public GameObject CultureTaskArea;
public GameObject UIInfoCultureTaskMonoPrefab;
private List<UIInfoCultureTaskMono> _cultureTaskList = new List<UIInfoCultureTaskMono>();
private GiantType _choiceGiantType;
private bool _alreadyMatchStart;
protected override void OnInit()
{
base.OnInit();
if (CloseButton == null || CheckButton == null || ReturnButton == null || BlockButton == null) return;
//绑定各个关键按钮的功能
CloseButton.onClick.RemoveAllListeners();
CloseButton.onClick.AddListener(() => { OnBtnCloseClick.Invoke(); });
BlockButton.onClick.RemoveAllListeners();
BlockButton.onClick.AddListener(() => { OnBtnCloseClick.Invoke(); });
ReturnButton.onClick.RemoveAllListeners();
ReturnButton.onClick.AddListener(() => { OnBtnCloseClick.Invoke(); });
CheckButton.onClick.RemoveAllListeners();
CheckButton.onClick.AddListener(OnCheckChoice);
_alreadyMatchStart = false;
}
public void OnMatchStart()
{
SetupPool();
SetupPickedList();
SetupCultureCards();
SetupCultureTasks();
_alreadyMatchStart = true;
}
private void SetupPickedList()
{
if (PickedList == null || PickedList.Count < 3 ) return;
var player = Main.MapData?.PlayerMap?.SelfPlayerData;
var heroData = player?.PlayerHeroData;
var heroList = heroData?.HeroList;
if (heroList == null) return;
if (Table.Instance?.UnitTypeDataAssets == null) return;
var pool = Pool ?? new List<UIInfoHeroAvatarMono>();
// 收集可用的未被pick的Pool英雄第一个blank槽位优先使用当前选中的英雄
var availablePool = new List<GiantType>();
if (_choiceGiantType != GiantType.None)
availablePool.Add(_choiceGiantType);
foreach (var t in pool)
{
if (t == null) continue;
if (!t.Picked && t.GiantType != _choiceGiantType) availablePool.Add(t.GiantType);
}
int availableIdx = 0;
for (int i = 0; i < 3; i++)
{
if (PickedList[i] == null) continue;
var unitFullType = new UnitFullType(){UnitType = UnitType.Giant,GiantType = GiantType.None};
bool locked = false;
bool blank = false;
//判定上锁
if (i >= heroData.MaxHeroCount) locked = true;
//判定为blank
else if (i >= heroList.Count)
{
if (availableIdx < availablePool.Count)
unitFullType.GiantType = availablePool[availableIdx++];
blank = true;
}
//判定为已出战
else unitFullType = heroList[i];
PickedList[i].SetupContent(unitFullType,blank,locked,OnForceUpgrade,i);
}
}
private void SetupPool()
{
if (Pool.Count < 5 ) return;
if (Main.MapData?.PlayerMap?.SelfPlayerData == null) return;
var player = Main.MapData.PlayerMap.SelfPlayerData;
if (Table.Instance?.UnitTypeDataAssets == null) return;
//Step #1 先设置Pool的对象图样
bool firstSelect = true;
for (int i = 0; i < 5; i++)
{
ChessType ch = Pool[i].ChessType;
var giantType = Table.Instance.UnitTypeDataAssets.GetGiantType(player.CivEnum, player.ForceEnum, ch);
bool picked = player.PlayerHeroData.HasHero(giantType);
bool selected = !picked && firstSelect;
Pool[i].SetupContent(player.CivEnum,player.ForceEnum,ch,OnPoolSelect,picked,selected);
if (selected)
{
firstSelect = false;
_choiceGiantType = giantType;
}
}
}
private void OnPoolSelect(GiantType giantType)
{
//Step #1 取消其他选项的选中状态
for(int i = 0;i < Pool.Count;i++)
if(Pool[i].GiantType != giantType && !Pool[i].Picked)
Pool[i].SetDeselected();
//Step #2 更新缓存
_choiceGiantType = giantType;
//Step #3 更新PickedList
UpdatePickedList();
}
public void OnForceUpgrade()
{
SetContent(false);
OnBtnCloseClick.Invoke();
}
public void SetContent(bool firstOpen = true)
{
if (!_alreadyMatchStart) OnMatchStart();
//Step #1 设置选择英雄框
UpdatePool();
//Step #2 设置出战框
UpdatePickedList();
//Step #3 通知bottombar 刷新英雄头像
EventManager.Publish(new UpdateUIBottomBottomBarHeroButtonAvatar());
//Step #4 处理音乐
if (firstOpen && Table.Instance.PlayerDataAssets.GetPlayerInfo(Main.MapData.PlayerMap.SelfPlayerData, out var info))
{
AudioManager.Instance.PlayMusic(info.MusicName, 1f, 2f, true);
}
//Step #5 更新市政卡
UpdateCultureCards();
//Step #6 更新文化任务
UpdateCultureTasks();
//Step #7 强制递归重建布局修复首次打开时Layout错乱
RebuildLayoutRecursive(TwoPanelTransform);
}
private void RebuildLayoutRecursive(RectTransform root)
{
if (root == null) return;
// 先从子节点开始重建保证子Layout先计算完毕
foreach (RectTransform child in root)
RebuildLayoutRecursive(child);
LayoutRebuilder.ForceRebuildLayoutImmediate(root);
}
public void UpdatePickedList()
{
if (PickedList == null || PickedList.Count < 3 ) return;
var player = Main.MapData?.PlayerMap?.SelfPlayerData;
var heroData = player?.PlayerHeroData;
var heroList = heroData?.HeroList;
if (heroList == null) return;
if (Table.Instance?.UnitTypeDataAssets == null) return;
var pool = Pool ?? new List<UIInfoHeroAvatarMono>();
// 收集可用的未被pick的Pool英雄第一个blank槽位优先使用当前选中的英雄
var availablePool = new List<GiantType>();
if (_choiceGiantType != GiantType.None)
availablePool.Add(_choiceGiantType);
foreach (var t in pool)
{
if (t == null) continue;
if (!t.Picked && t.GiantType != _choiceGiantType) availablePool.Add(t.GiantType);
}
int availableIdx = 0;
for (int i = 0; i < 3; i++)
{
if (PickedList[i] == null) continue;
var unitFullType = new UnitFullType(){UnitType = UnitType.Giant,GiantType = GiantType.None};
bool locked = false;
bool blank = false;
//判定上锁
if (i >= heroData.MaxHeroCount) locked = true;
//判定为blank
else if (i >= heroList.Count)
{
if (availableIdx < availablePool.Count)
unitFullType.GiantType = availablePool[availableIdx++];
blank = true;
}
//判定为已出战
else unitFullType = heroList[i];
PickedList[i].UpdateContent(unitFullType,blank,locked,i);
}
}
public void UpdatePool()
{
var heroData = Main.MapData.PlayerMap.SelfPlayerData.PlayerHeroData;
//_choiceGiantType = GiantType.None;
//确认是否要pick是否显示相关的模块
bool needPick = heroData.HeroCount != heroData.MaxHeroCount;
PoolGroup.SetActive(needPick);
if (!needPick) return;
var player = Main.MapData.PlayerMap.SelfPlayerData;
bool firstSelect = true;
for (int i = 0; i < 5; i++)
{
ChessType ch = Pool[i].ChessType;
var giantType = Table.Instance.UnitTypeDataAssets.GetGiantType(player.CivEnum, player.ForceEnum, ch);
bool picked = player.PlayerHeroData.HasHero(giantType);
bool selected = !picked && firstSelect;
Pool[i].UpdateContent(picked,selected);
if (selected)
{
firstSelect = false;
_choiceGiantType = giantType;
}
}
}
public void OnCheckChoice()
{
if (_choiceGiantType == GiantType.None) return;
if (Main.MapData.CurPlayer != Main.MapData.PlayerMap.SelfPlayerData) return;
var heroData = Main.MapData.PlayerMap.SelfPlayerData.PlayerHeroData;
var actionId = new CommonActionId()
{ ActionType = CommonActionType.PlayerAction, PlayerActionType = PlayerActionType.SelectHero,GiantType = _choiceGiantType };
var action = ActionLogicFactory.GetActionLogic(actionId);
if (action == null) return;
var actionParams = new CommonActionParams(mapData:Main.MapData,playerData:Main.MapData.PlayerMap.SelfPlayerData);
if (action.CompleteExecute(actionParams))
{
SetContent();
EventManager.Publish(new UpdateUIBottomBottomBarHeroButtonAvatar());
//UIManager.Instance.BottomBarUI.UpdateHeroButtonSprite();
OnBtnCloseClick();
}
//heroData.AddHero(_choiceGiantType);
}
public void SetupCultureCards()
{
if (CultureCardArea == null || UIInfoCultureCardMonoPrefab == null) return;
var cultureCardDataAssets = Table.Instance.CultureCardDataAssets;
if (cultureCardDataAssets == null) return;
// 清除旧的实例
foreach (var old in _cultureCardList)
if (old != null) Destroy(old.gameObject);
_cultureCardList.Clear();
var player = Main.MapData.PlayerMap.SelfPlayerData;
var activeCards = cultureCardDataAssets.CultureCardDataList
.Where(c => c.IsActive && !c.NotShow)
.OrderBy(c => c.Priority)
.ToList();
foreach (var cardInfo in activeCards)
{
var go = Instantiate(UIInfoCultureCardMonoPrefab, CultureCardArea.transform);
var mono = go.GetComponent<UIInfoCultureCardMono>();
if (mono == null) continue;
mono.Init(cardInfo, player.CivEnum, player.ForceEnum);
_cultureCardList.Add(mono);
}
}
public void UpdateCultureCards()
{
if (CultureCardArea == null) return;
var player = Main.MapData.PlayerMap.SelfPlayerData;
foreach (var card in _cultureCardList)
{
if (card != null && card.gameObject.activeSelf)
card.UpdateInfo(player);
}
}
public void SetupCultureTasks()
{
if (CultureTaskArea == null || UIInfoCultureTaskMonoPrefab == null) return;
// 清除旧的实例
foreach (var old in _cultureTaskList)
if (old != null) Destroy(old.gameObject);
_cultureTaskList.Clear();
var player = Main.MapData.PlayerMap.SelfPlayerData;
var cultureMoments = player.MomentData.GetCultureMoment();
foreach (var momentItem in cultureMoments)
{
var go = Instantiate(UIInfoCultureTaskMonoPrefab, CultureTaskArea.transform);
var mono = go.GetComponent<UIInfoCultureTaskMono>();
if (mono == null) continue;
mono.Init(momentItem);
mono.UpdateInfo(player);
_cultureTaskList.Add(mono);
}
}
public void UpdateCultureTasks()
{
if (CultureTaskArea == null) return;
var player = Main.MapData.PlayerMap.SelfPlayerData;
foreach (var task in _cultureTaskList)
{
if (task != null && task.gameObject.activeSelf)
task.UpdateInfo(player);
}
}
public void CloseView()
{
AudioManager.Instance.StopMusic();
AudioManager.Instance.ResumeBgmRotationIfEnabled();
}
}
}