387 lines
11 KiB
C#
387 lines
11 KiB
C#
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();
|
||
}
|
||
}
|
||
|
||
}
|