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 CivForceList; public List PicList; public GameObject SelectAvatarPrefab; public GameObject SelectList; private List _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 StarList; public List GreyStarList; public GameObject SkillCircleGroup; public GameObject SkillCirclePrefab; public List SkillCircleList; [Header("中央立绘区")] public Image BG1; public Image BG2; public List 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(); foreach (var t in CivForceList) { // TODO: 暂时屏蔽第四阵营(Indian/Satori),待正式上线后移除此判断 //if (t.Civ == CivEnum.Indian) continue; var obj = Instantiate(SelectAvatarPrefab, SelectList.transform); var mono = obj.GetComponent(); 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(); if(mono == null)continue; SkillCircleList.Add(mono); } SkillCircleList = new List(); 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(); 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()); 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(); } /// /// Save the last selected empire to PlayerPrefs /// 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(); } /// /// Save the last selected map size index for CREATIVE mode /// private void SaveLastMapSize(uint mapSizeIndex) { PlayerPrefs.SetInt(LAST_MAP_SIZE_INDEX_KEY, (int)mapSizeIndex); PlayerPrefs.Save(); } /// /// Get the last selected empire from PlayerPrefs /// 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(); } } }