using System; using System.Collections.Generic; using Animancer; using Logic; using Logic.Action; 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.Config; using TH1_Logic.Core; using TH1_Logic.Net; using TH1_Logic.Steam; using TH1_UI.View.Announce; using TH1Resource; using TMPro; using Unity.VisualScripting; using UnityEngine; using UnityEngine.Serialization; using UnityEngine.UI; namespace TH1_UI.View.Outside { public enum LibrarySheetType { Hero, Wonder, Music } public class UIOutsideLibraryView : Base.View { [Header("按钮")] //public Button CloseButton; public Button CloseButton; public Button WikiButton; public UIOutsideSelectOptionGroupMono MenuBar; public Button HeroListButton; public Button WonderListButton; public Button MusicListButton; public Transform HeroList; public Transform WonderList; public Transform MusicList; public Transform HeroListContent; public Transform WonderListContent; public Transform MusicListContent; private List _heroMonoList; private List _wonderMonoList; private List _musicMonoList; public UIOutsideLibraryHeroPanelMono HeroPanel; public UIOutsideLibraryWonderPanelMono WonderPanel; public UIOutsideLibraryMusicPanelMono MusicPanel; public TextMeshProUGUI AllStarText; public GameObject GridItemPrefab; public GameObject MusicItemPrefab; [Header("猜歌模式按钮(显示互斥)")] public Button EnterGuessModeButton; public Button ExitGuessModeButton; // 当前选中的曲目MusicName,用于刷新选中态 private string _currentMusicName; // 进入Music sheet前正在播放的BGM,离开时恢复;空=不需恢复(进Music前没在播) private string _bgmBeforeMusicSheet; // 上次显示的sheet,用于判断"是否从Music切走" private LibrarySheetType _prevSheet = LibrarySheetType.Hero; // 当前是否处于猜歌模式 private bool _isGuessMode; //所有参与图鉴的herolist private readonly List _heroTypeList = new List { GiantType.EgyptianRemilia,GiantType.EgyptianPatchouli,GiantType.EgyptianSakuya,GiantType.EgyptianFlandre,GiantType.EgyptianMeiling, GiantType.FrenchKaguya,GiantType.FrenchEirin,GiantType.FrenchTewi,GiantType.FrenchReisen,GiantType.FrenchMokou, GiantType.GermanyKanako,GiantType.GermanySuwako,GiantType.GermanySanae,GiantType.GermanyAya,GiantType.GermanyMomiji, GiantType.IndianSatori,GiantType.IndianKoishi,GiantType.IndianRin,GiantType.IndianUtsuho,GiantType.IndianYuugi }; //所有参与图鉴的civlist private readonly List _empireList = new List { new Empire(CivEnum.Egyptian,ForceEnum.Remilia), new Empire(CivEnum.French,ForceEnum.Kaguya),new Empire(CivEnum.Germany,ForceEnum.Kanako),new Empire(CivEnum.Indian,ForceEnum.Satori) }; //关闭时执行的委托 public ViDelegateAssisstant.Dele OnBtnCloseClick; //Wiki按钮点击时执行的委托 public ViDelegateAssisstant.Dele OnBtnWikiClick; protected override void OnInit() { base.OnInit(); CloseButton.onClick.RemoveAllListeners(); CloseButton.onClick.AddListener(OnClose); if (WikiButton != null) { WikiButton.onClick.RemoveAllListeners(); WikiButton.onClick.AddListener(OnWiki); } if (EnterGuessModeButton != null) { EnterGuessModeButton.onClick.RemoveAllListeners(); EnterGuessModeButton.onClick.AddListener(() => SetGuessMode(true)); } if (ExitGuessModeButton != null) { ExitGuessModeButton.onClick.RemoveAllListeners(); ExitGuessModeButton.onClick.AddListener(() => SetGuessMode(false)); } _heroMonoList = new List(); _wonderMonoList = new List(); _musicMonoList = new List(); } private void SetAllWonderStars() { int sum = _empireList.Count * 7 * 3; int now = 0; for(int i = 0;i < _empireList.Count; i++) foreach (WonderTypeEnum wonderType in Enum.GetValues(typeof(WonderTypeEnum))) if(wonderType != WonderTypeEnum.None) for (uint k = 1; k <= 3; k++) if(AchievementDataManager.Instance.GetSmallIdByWonderAndEmpire(_empireList[i], wonderType, out var smallid) && AchievementDataManager.Instance.IsFinished(3, smallid, k)) now++; AllStarText.text = now + " / " + sum; } private void SetAllHeroStars() { int sum = _heroTypeList.Count * 3; int now = 0; for(int i = 0;i < _heroTypeList.Count; i++) if(AchievementDataManager.Instance.GetSmallIdByGiantType(_heroTypeList[i], out var smallid)) for (uint k = 1; k <= 3; k++) if(AchievementDataManager.Instance.IsFinished(2, smallid, k)) now++; AllStarText.text = now + " / " + sum; } private void InitHeroList() { //Step #1 判断容器是否够 int heroSum = _heroTypeList.Count; while (_heroMonoList.Count < heroSum) { var obj = Instantiate(GridItemPrefab, HeroListContent); var mono = obj.GetComponent(); _heroMonoList.Add(mono); } //Step #2 设置每个mono的内容 for (int i = 0; i < _heroMonoList.Count; i++) { _heroMonoList[i].gameObject.SetActive(i < heroSum); if (i >= heroSum) break; _heroMonoList[i].SetHeroContent(_heroTypeList[i],OnClickHeroItem); } } private void OnClickHeroItem(GiantType giantType) { HeroPanel.SetContent(giantType); HeroPanel.Show(); } private void InitWonderList() { //Step #1 判断容器是否够 int wonderSum = _empireList.Count * 7 ; while (_wonderMonoList.Count < wonderSum) { var obj = Instantiate(GridItemPrefab, WonderListContent); var mono = obj.GetComponent(); _wonderMonoList.Add(mono); } //Step #2 设置每个mono的内容 for (int i = 0; i < _wonderMonoList.Count; i++) { _wonderMonoList[i].gameObject.SetActive(i < wonderSum); int empireIdx = i / 7; int wonderIdx = i % 7 + 1; if (i >= wonderSum) break; _wonderMonoList[i].SetWonderContent(_empireList[empireIdx], (WonderTypeEnum)wonderIdx,OnClickWonderItem); } } private void OnClickWonderItem(Empire empire,WonderTypeEnum wonderType) { WonderPanel.SetContent(empire,wonderType); WonderPanel.Show(); } private void InitMusicList() { if (MusicItemPrefab == null || MusicListContent == null) return; var dataAsset = Table.Instance.MusicDataAssets; if (dataAsset == null) return; var list = dataAsset.MusicDataList; int sum = list != null ? list.Count : 0; //Step #1 容量补足 while (_musicMonoList.Count < sum) { var obj = Instantiate(MusicItemPrefab, MusicListContent); var mono = obj.GetComponent(); _musicMonoList.Add(mono); } //Step #2 填充每项 for (int i = 0; i < _musicMonoList.Count; i++) { _musicMonoList[i].gameObject.SetActive(i < sum); if (i >= sum) continue; _musicMonoList[i].SetContent(list[i], OnClickMusicItem); // SetContent 默认按非猜歌模式渲染 Name,这里同步当前模式 _musicMonoList[i].SetGuessMode(_isGuessMode); } } private void OnClickMusicItem(string musicName) { if (string.IsNullOrEmpty(musicName)) return; if (Table.Instance.MusicDataAssets == null) return; if (!Table.Instance.MusicDataAssets.GetMusicInfo(musicName, out var info)) return; if (MusicPanel == null) return; _currentMusicName = musicName; RefreshMusicSelectedHighlight(); MusicPanel.SetContent(info); MusicPanel.PlayMusic(info); } private void RefreshMusicSelectedHighlight() { foreach (var mono in _musicMonoList) { if (mono == null) continue; mono.SetSelected(mono.MusicName == _currentMusicName); } } private void InitMenuBar() { HeroListButton.onClick.RemoveAllListeners(); HeroListButton.onClick.AddListener(() => { MenuBar.Select(0); ShowList(LibrarySheetType.Hero); }); WonderListButton.onClick.RemoveAllListeners(); WonderListButton.onClick.AddListener(() => { MenuBar.Select(1); ShowList(LibrarySheetType.Wonder); }); if (MusicListButton != null) { MusicListButton.onClick.RemoveAllListeners(); MusicListButton.onClick.AddListener(() => { MenuBar.Select(2); ShowList(LibrarySheetType.Music); }); } } private void SetMenuBar(LibrarySheetType sheetType) { uint idx = sheetType switch { LibrarySheetType.Hero => 0, LibrarySheetType.Wonder => 1, LibrarySheetType.Music => 2, _ => 0, }; MenuBar.Select(idx); } private void ShowList(LibrarySheetType sheetType) { // MusicList 是音乐 sheet 整个容器(包含 MusicListTitle + ListArea + 详情区 MusicPanel) // 切 sheet 只控制顶层容器,不要单独 Hide MusicPanel(详情区随容器整体隐藏即可) WonderList.gameObject.SetActive(false); HeroList.gameObject.SetActive(false); if (MusicList != null) MusicList.gameObject.SetActive(false); // 离开 Music sheet 时,先停掉鉴赏室在播曲目并恢复进Music前的BGM if (_prevSheet == LibrarySheetType.Music && sheetType != LibrarySheetType.Music) { LeaveMusicSheet(); } if (sheetType == LibrarySheetType.Hero) { SetAllHeroStars(); HeroList.gameObject.SetActive(true); } else if (sheetType == LibrarySheetType.Wonder) { SetAllWonderStars(); WonderList.gameObject.SetActive(true); } else if (sheetType == LibrarySheetType.Music) { if (MusicList != null) MusicList.gameObject.SetActive(true); // 第一次进入Music时记下进入前的BGM,之后切回再恢复 if (_prevSheet != LibrarySheetType.Music) { _bgmBeforeMusicSheet = AudioManager.Instance.GetCurrentMusicName(); // 第一次进入Music默认非猜歌模式(确保按钮和列表显示正确初始态) SetGuessMode(false); } // 默认选中并播放列表第一首 AutoSelectFirstMusic(); } _prevSheet = sheetType; } // 离开 Music sheet 时停曲并恢复原BGM private void LeaveMusicSheet() { // 让 MusicPanel 自身处理停曲与碟片旋转停止 if (MusicPanel != null) MusicPanel.OnLeaveSheet(); // 恢复进 Music 前的 BGM(若有) if (!string.IsNullOrEmpty(_bgmBeforeMusicSheet)) { AudioManager.Instance.PlayMusic(_bgmBeforeMusicSheet, 1f, 2f, true, false); } _bgmBeforeMusicSheet = null; _currentMusicName = null; RefreshMusicSelectedHighlight(); // 离开 Music sheet 时退出猜歌模式,避免下次进来还在猜歌态 SetGuessMode(false); } // 切换猜歌模式:刷按钮互斥/列表项Name/MusicPanel信息显示 private void SetGuessMode(bool guess) { _isGuessMode = guess; // 按钮互斥 if (EnterGuessModeButton != null) EnterGuessModeButton.gameObject.SetActive(!guess); if (ExitGuessModeButton != null) ExitGuessModeButton.gameObject.SetActive(guess); // 列表项 Name 切换(?????/真实曲名) foreach (var mono in _musicMonoList) { if (mono != null) mono.SetGuessMode(guess); } // MusicPanel 同步显隐 MusicInfo / GuessArea if (MusicPanel != null) MusicPanel.SetGuessMode(guess); } // 切到Music sheet时自动选中并播放第一条曲目 private void AutoSelectFirstMusic() { var dataAsset = Table.Instance.MusicDataAssets; if (dataAsset == null) return; var list = dataAsset.MusicDataList; if (list == null || list.Count == 0) return; OnClickMusicItem(list[0].MusicName); } public void SetContent(ShowUIOutsideLibrary evt) { InitMenuBar(); InitHeroList(); InitWonderList(); InitMusicList(); SetMenuBar(LibrarySheetType.Hero); ShowList(LibrarySheetType.Hero); } //在Controller 调用Close的时候,会先调用这个closeview public void OnCloseView() { } public void OnSettingClicked() { } public void OnStartClicked() { EventManager.Publish(new ShowUIOutsideSelect()); } public void OnClose() { OnBtnCloseClick.Invoke(); } public void OnWiki() { ViDelegateAssisstant.Invoke(OnBtnWikiClick); } } }