TH1/Unity/Assets/Scripts/TH1_UI/View/Outside/UIOutsideSelectView.cs
2026-05-14 17:25:29 +08:00

356 lines
10 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;
using System.Collections.Generic;
using Animancer;
using Logic;
using Logic.Action;
using MapWaterType = Logic.MapWaterType;
using Logic.AI;
using Logic.Audio;
using Logic.Multilingual;
using ParadoxNotion;
using RuntimeData;
using Steamworks;
using TH1_Core.Events;
using TH1_Core.Managers;
using TH1_Logic.Action;
using TH1_Logic.Core;
using TH1_Logic.MatchConfig;
using TH1_Logic.Net;
using TH1_Logic.Steam;
using TH1_UI.View.Announce;
using TH1Resource;
using TMPro;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;
namespace TH1_UI.View.Outside
{
public class UIOutsideSelectView : Base.View
{
[Header("按钮")]
public Button CloseButton;
public Button SettingButton;
[Header("选择列表")]
public List<Empire> CivForceList;
public List<GameObject> PicList;
public GameObject SelectAvatarPrefab;
public GameObject SelectList;
private List<UIOutsideSelectAvatarMono> _monoList;
private Empire _selectEmpire;
//暴露当前选中的阵营,供 Controller 在开始游戏时传给 Loading 界面
public Empire SelectedEmpire => _selectEmpire;
[Header("详细信息")]
public RectTransform InfoGroup;
public RectTransform CivBG;
public TextMeshProUGUI ForceName;
public TextMeshProUGUI CivName;
public TextMeshProUGUI LeaderDesc;
public TextMeshProUGUI EmpireDesc;
public List<GameObject> StarList;
public List<GameObject> GreyStarList;
public GameObject SkillCircleGroup;
public GameObject SkillCirclePrefab;
public List<UIOutsideSelectSkillCircleMono> SkillCircleList;
[Header("中央立绘区")]
public Image BG1;
public Image BG2;
public List<UIOutsideSelectForceGroupMono> ForceGroupList;
[Header("子界面")]
public UIOutsideSelectCheckPanelMono SelectCheckPanelMono;
//关闭时执行的委托
public ViDelegateAssisstant.Dele OnBtnCloseClick;
//开始游戏时执行的委托(目前委托内容就是执行controller的Close())
public ViDelegateAssisstant.Dele OnStartGame;
// PlayerPrefs key for saving last selected empire
private const string LAST_SELECTED_CIV_KEY = "LastSelectedCiv";
private const string LAST_SELECTED_FORCE_KEY = "LastSelectedForce";
// PlayerPrefs key for saving last selected map size in CREATIVE mode
private const string LAST_MAP_SIZE_INDEX_KEY = "LastCreativeMapSizeIndex";
protected override void OnInit()
{
base.OnInit();
//清空List下的内容
for(int i = SelectList.transform.childCount - 1;i >= 0;i --)
{
Transform child = SelectList.transform.GetChild(i);
GameObject.Destroy(child.gameObject);
}
_monoList = new List<UIOutsideSelectAvatarMono>();
foreach (var t in CivForceList)
{
// TODO: 暂时屏蔽第四阵营Indian/Satori待正式上线后移除此判断
//if (t.Civ == CivEnum.Indian) continue;
var obj = Instantiate(SelectAvatarPrefab, SelectList.transform);
var mono = obj.GetComponent<UIOutsideSelectAvatarMono>();
if (mono == null) continue;
mono.SetContent(t,OnAvatarClicked);
_monoList.Add(mono);
}
CloseButton.onClick.RemoveAllListeners();
CloseButton.onClick.AddListener(() =>
{
OnBtnCloseClick?.Invoke();
});
//处理ChekPanel
SelectCheckPanelMono.Init(OnStartClicked);
SettingButton.onClick.RemoveAllListeners();
SettingButton.onClick.AddListener(OnSettingClicked);
}
private void OnAvatarClicked(Empire playerEmpire)
{
foreach(var t in _monoList)
if(t.PlayerEmpire != playerEmpire)
t.SetHide();
SetCivForceInfo(playerEmpire);
}
public void Update()
{
}
public void SetContent(ShowUIOutsideSelect evt)
{
if (_monoList.Count == 0) return;
SelectCheckPanelMono.gameObject.SetActive(false) ;
// Try to restore last selected empire
Empire? lastSelectedEmpire = GetLastSelectedEmpire();
UIOutsideSelectAvatarMono targetMono = null;
if (lastSelectedEmpire.HasValue)
{
// Find the mono that matches the last selected empire
foreach (var mono in _monoList)
{
if (mono.PlayerEmpire.Civ == lastSelectedEmpire.Value.Civ &&
mono.PlayerEmpire.Force == lastSelectedEmpire.Value.Force)
{
targetMono = mono;
break;
}
}
}
// If no last selection found or not available, default to first
if (targetMono == null)
{
targetMono = _monoList[0];
}
targetMono.Button.onClick.Invoke();
SetCivForceInfo(targetMono.PlayerEmpire);
}
public void SetCivForceInfo(Empire playerEmpire)
{
_selectEmpire = playerEmpire;
if (!Table.Instance.PlayerDataAssets.GetPlayerInfo(playerEmpire.Civ, playerEmpire.Force, out var info)) return;
//Step #1 设置文明基础文字信息
MultilingualManager.Instance.SetUIText(ForceName,info.ForceName);
MultilingualManager.Instance.SetUIText(CivName,info.CivName);
LayoutRebuilder.ForceRebuildLayoutImmediate(CivBG);
//Step #2 设置文明的难度情况
var dif = info.Diff;
var grey = 4 - dif;
for(int i = 0;i < StarList.Count ; i++)
StarList[i].SetActive(i < dif);
for(int i = 0;i < GreyStarList.Count ; i++)
GreyStarList[i].SetActive(i < grey);
//Step #2 设置文明特色SkillGroup
//清空SkillGroup
for (int i = SkillCircleGroup.transform.childCount - 1; i >= 0; i--)
{
Transform child = SkillCircleGroup.transform.GetChild(i);
child.gameObject.SetActive(false);
}
for (int i = SkillCircleGroup.transform.childCount; i < info.TechAtomList.Count; i++)
{
var pre = Instantiate(SkillCirclePrefab, SkillCircleGroup.transform);
var mono = pre?.GetComponent<UIOutsideSelectSkillCircleMono>();
if(mono == null)continue;
SkillCircleList.Add(mono);
}
SkillCircleList = new List<UIOutsideSelectSkillCircleMono>();
for (int i = 0; i < info.TechAtomList.Count; i++)
{
Transform child = SkillCircleGroup.transform.GetChild(i);
if (child == null) break;
child.gameObject.SetActive(true);
var mono = child?.GetComponent<UIOutsideSelectSkillCircleMono>();
if(mono == null)continue;
SkillCircleList.Add(mono);
mono.SetContent(playerEmpire,info.TechAtomList[i]);
}
//Step #3 设置文明基础文字信息
MultilingualManager.Instance.SetUIText(EmpireDesc,info.EmpireDesc);
MultilingualManager.Instance.SetUIText(LeaderDesc,info.LeaderDesc);
//LayoutRebuilder.ForceRebuildLayoutImmediate(CivBG);
//LayoutRebuilder.ForceRebuildLayoutImmediate(SkillCircleGroup.GetComponent<RectTransform>());
LayoutRebuilder.ForceRebuildLayoutImmediate(InfoGroup);
//Step #4 设置立绘
foreach (var forceGroup in ForceGroupList)
{
if (forceGroup.Empire == playerEmpire)
{
forceGroup.gameObject.SetActive(true);
BG1.color = info.Color;
BG2.color = info.Color;
foreach(var heroPack in forceGroup.HeroList)
heroPack.SetContent();
}
else
forceGroup.gameObject.SetActive(false);
}
//Step #5 播放对应音乐
AudioManager.Instance.PlayMusic(info.MusicName,1f,1f,true);
}
//在Controller 调用Close的时候会先调用这个closeview
public void OnCloseView()
{
}
public void OnSettingClicked()
{
SelectCheckPanelMono.Show();
}
public void OnStartClicked()
{
GameMode gameMode = SelectCheckPanelMono.GameMode.SelectedIndex switch
{
0 => GameMode.DOMINATION,
1 => GameMode.PERFECT,
_ => GameMode.CREATIVE
};
uint playerCount = SelectCheckPanelMono.PlayerCount.SelectedIndex + 2;
uint mapSize;
mapSize = SelectCheckPanelMono.MapSize.SelectedIndex switch
{
0 => 11,
1 => 14,
2 => 16,
3 => 18,
4 => 20,
5 => 24,
6 => 30,
_ => 18
};
AIDifficult diff = SelectCheckPanelMono.Diff.SelectedIndex switch
{
0 => AIDifficult.EASY,
1 => AIDifficult.NORMAL,
2 => AIDifficult.HARD,
_ => AIDifficult.LUNATIC
};
MapWaterType waterType = (MapWaterType)(SelectCheckPanelMono.Water != null
? SelectCheckPanelMono.Water.SelectedIndex
: 2); // default Pangea
// domination => 2, perfect => 6, creative => 7
uint matchConfigId = gameMode switch
{
GameMode.PERFECT => 6,
GameMode.CREATIVE => 7,
_ => 2 // DOMINATION
};
Main.Instance.MapConfig.ChangeByMapConfig(MatchConfigManager.Instance.GetMatchConfig(matchConfigId));
Main.Instance.MapConfig.GameMode = gameMode;
Main.Instance.MapConfig.Width = mapSize;
Main.Instance.MapConfig.Height = mapSize;
Main.Instance.MapConfig.PlayerCount = playerCount;
Main.Instance.MapConfig.selfCivId = Table.Instance.TransCivEnumToCivId(_selectEmpire.Civ);
Main.Instance.MapConfig.selfForceId = Table.Instance.TransForceEnumToForceId(_selectEmpire.Force);
Main.Instance.MapConfig.AIDiff = diff;
Main.Instance.MapConfig.WaterType = waterType;
// Save the selected empire for next time
SaveLastSelectedEmpire(_selectEmpire);
// CREATIVE模式下保存MapSize选择
if (gameMode == GameMode.CREATIVE)
{
SaveLastMapSize(SelectCheckPanelMono.MapSize.SelectedIndex);
}
//设置好参数后调用Controller的委托
OnStartGame?.Invoke();
}
/// <summary>
/// Save the last selected empire to PlayerPrefs
/// </summary>
private void SaveLastSelectedEmpire(Empire empire)
{
PlayerPrefs.SetInt(LAST_SELECTED_CIV_KEY, (int)empire.Civ);
PlayerPrefs.SetInt(LAST_SELECTED_FORCE_KEY, (int)empire.Force);
PlayerPrefs.Save();
}
/// <summary>
/// Save the last selected map size index for CREATIVE mode
/// </summary>
private void SaveLastMapSize(uint mapSizeIndex)
{
PlayerPrefs.SetInt(LAST_MAP_SIZE_INDEX_KEY, (int)mapSizeIndex);
PlayerPrefs.Save();
}
/// <summary>
/// Get the last selected empire from PlayerPrefs
/// </summary>
private Empire? GetLastSelectedEmpire()
{
if (!PlayerPrefs.HasKey(LAST_SELECTED_CIV_KEY) || !PlayerPrefs.HasKey(LAST_SELECTED_FORCE_KEY))
return null;
int civValue = PlayerPrefs.GetInt(LAST_SELECTED_CIV_KEY);
int forceValue = PlayerPrefs.GetInt(LAST_SELECTED_FORCE_KEY);
// Validate the values are valid enums
if (!Enum.IsDefined(typeof(CivEnum), civValue) || !Enum.IsDefined(typeof(ForceEnum), forceValue))
return null;
return new Empire((CivEnum)civValue, (ForceEnum)forceValue);
}
public void CloseView()
{
AudioManager.Instance.StopMusic();
}
}
}