TH1/Unity/Assets/Scripts/TH1_UI/View/Outside/UIOutsideSelectCheckPanelMono.cs

733 lines
27 KiB
C#

using System;
using System.Collections.Generic;
using Animancer;
using Logic.AI;
using Logic.Multilingual;
using RuntimeData;
using TH1_Logic.Core;
using TH1_Logic.Net;
using TH1_UI.View.Outside;
using TH1Resource;
using UnityEngine;
using UnityEngine.UI;
public class UIOutsideSelectCheckPanelMono : MonoBehaviour
{
public UIOutsideSelectOptionGroupMono GameMode;
public UIOutsideSelectOptionGroupMono PlayerCount;
public UIOutsideSelectOptionGroupMono MapSize;
public UIOutsideSelectOptionGroupMono Diff;
public UIOutsideSelectOptionGroupMono Water;
public GameObject WinTitle;
public UIOutsideSelectOptionGroupMono WinGroup;
public GameObject AISettingTitle;
public GameObject AISettingGroup;
public GameObject AISettingRowPrefab;
public GameObject TestTitle;
public GameObject TestGroup;
public Toggle ResumeToggle;
public Toggle NearToggle;
public Button StartButton;
public Button CloseButton;
public Button BlockerButton;
public AnimancerComponent Animancer;
private const string LAST_MAP_SIZE_INDEX_KEY = "LastCreativeMapSizeIndex";
private const string DISABLE_NEARBY_SPAWN_POINTS_PREFS_KEY = "DisableNearbySpawnPoints";
private static readonly uint[] CreativeWinMatchConfigIds = { 7, 9, 10 };
private static readonly List<(CivEnum Civ, ForceEnum Force)> FallbackForceOptions = new List<(CivEnum Civ, ForceEnum Force)>
{
(CivEnum.Egyptian, ForceEnum.Remilia),
(CivEnum.French, ForceEnum.Kaguya),
(CivEnum.Germany, ForceEnum.Kanako),
(CivEnum.Indian, ForceEnum.Satori),
};
private Action _onStartClick;
private Empire _playerEmpire;
private bool _playerEmpireIsRandom;
private readonly List<AISettingData> _aiSettings = new List<AISettingData>();
private readonly List<UIOutsideSelectAISettingRowMono> _aiSettingRows = new List<UIOutsideSelectAISettingRowMono>();
private bool _aiSettingRowsCached;
public uint WinSelectedIndex => WinGroup != null ? WinGroup.SelectedIndex : 0;
public bool IsTestMode => GameMode != null && GameMode.SelectedIndex == 2 && ResumeToggle != null && ResumeToggle.isOn;
public bool DisableNearbySpawnPoints => GameMode != null
&& GameMode.SelectedIndex == 2
&& NearToggle != null
&& NearToggle.isOn;
public IReadOnlyList<AISettingData> AISettings => _aiSettings;
public class AISettingData
{
public int SlotIndex;
public uint CivId;
public uint ForceId;
public bool IsRandom;
public int TeamId;
public bool IsForceUserEdited;
public bool IsTeamUserEdited;
}
public void Init(Action onStartClick)
{
InitSetting();
_onStartClick = onStartClick;
StartButton.onClick.RemoveAllListeners();
StartButton.onClick.AddListener(() => _onStartClick?.Invoke());
CloseButton.onClick.RemoveAllListeners();
CloseButton.onClick.AddListener(Hide);
BlockerButton.onClick.RemoveAllListeners();
BlockerButton.onClick.AddListener(Hide);
}
public void SetPlayerEmpire(Empire playerEmpire, bool isRandom = false)
{
_playerEmpire = playerEmpire;
_playerEmpireIsRandom = isRandom;
uint playerCount = PlayerCount != null
? PlayerCount.SelectedIndex + 2
: Main.Instance.MapConfig?.PlayerCount ?? 2;
var preserveUserEdits = GameMode != null && GameMode.SelectedIndex == 2;
InitAISettings(playerCount, preserveUserEdits, preserveUserEdits);
RefreshAISettingRows();
}
public void PrepareAISettingsForStart(uint playerCount, bool preserveUserEdits)
{
InitAISettings(playerCount, preserveUserEdits, preserveUserEdits);
RefreshAISettingRows();
}
public void InitSetting()
{
Main.Instance.MapConfig?.ResetTransientMatchOptions();
uint playerCount = 2;
AIDifficult diff = AIDifficult.HARD;
GameMode gameMode = RuntimeData.GameMode.PERFECT;
uint matchConfigId = 7;
if (Main.Instance.MapConfig != null)
{
playerCount = Main.Instance.MapConfig.PlayerCount;
diff = Main.Instance.MapConfig.AIDiff;
gameMode = Main.Instance.MapConfig.GameMode;
matchConfigId = Main.Instance.MapConfig.Id;
}
uint playerCountIdx = playerCount >= 2 ? playerCount - 2 : 0;
uint mapSizeIdx = gameMode == RuntimeData.GameMode.CREATIVE
? (uint)PlayerPrefs.GetInt(LAST_MAP_SIZE_INDEX_KEY, 3)
: playerCount switch
{
2 => 0,
3 => 1,
4 => 2,
_ => 3
};
uint diffIdx = diff switch
{
AIDifficult.EASY => 0,
AIDifficult.NORMAL => 1,
AIDifficult.HARD => 2,
_ => 3
};
uint gameModeIdx = gameMode switch
{
RuntimeData.GameMode.DOMINATION => 0,
RuntimeData.GameMode.PERFECT => 1,
RuntimeData.GameMode.CREATIVE => 2,
_ => 2
};
uint waterIdx = gameMode == RuntimeData.GameMode.CREATIVE && Main.Instance.MapConfig != null
? (uint)Main.Instance.MapConfig.WaterType
: 2;
GameMode.OnOptionClicked = OnGameModeOptionClicked;
PlayerCount.OnOptionClicked = OnPlayerOptionClicked;
if (WinGroup != null) WinGroup.OnOptionClicked = OnWinOptionClicked;
if (ResumeToggle != null)
{
ResumeToggle.onValueChanged.RemoveAllListeners();
ResumeToggle.onValueChanged.AddListener(OnTestModeChanged);
}
if (NearToggle != null)
{
NearToggle.onValueChanged.RemoveAllListeners();
NearToggle.onValueChanged.AddListener(OnNearToggleChanged);
}
SetNearToggleSavedValue(gameMode == RuntimeData.GameMode.CREATIVE);
GameMode.Init(gameModeIdx);
PlayerCount.Init(playerCountIdx);
MapSize.Init(mapSizeIdx);
Diff.Init(diffIdx);
if (Water != null) Water.Init(waterIdx);
if (WinGroup != null) WinGroup.Init(GetWinIndexByMatchConfigId(matchConfigId));
InitAISettings(playerCount, false, false);
OnGameModeOptionClicked(gameModeIdx);
}
public void OnPlayerOptionClicked(uint idx)
{
var preserveUserEdits = GameMode != null && GameMode.SelectedIndex == 2;
InitAISettings(idx + 2, preserveUserEdits, preserveUserEdits);
RefreshAISettingRows();
if (GameMode.SelectedIndex == 2) return;
uint mapSizeIdx = idx switch
{
0 => 0,
1 => 1,
2 => 2,
_ => 3
};
MapSize.Select(mapSizeIdx);
}
public void OnGameModeOptionClicked(uint idx)
{
bool isCreative = idx == 2;
if (WinTitle != null) WinTitle.SetActive(isCreative);
if (WinGroup != null)
{
WinGroup.gameObject.SetActive(isCreative);
WinGroup.Init(WinGroup.SelectedIndex);
}
if (AISettingTitle != null) AISettingTitle.SetActive(isCreative);
if (AISettingGroup != null) AISettingGroup.SetActive(isCreative);
if (TestTitle != null) TestTitle.SetActive(isCreative);
if (TestGroup != null) TestGroup.SetActive(isCreative);
RefreshNearToggleVisibility(isCreative);
RefreshAISettingRows();
if (isCreative)
{
MapSize.Passive = false;
MapSize.Init(MapSize.SelectedIndex);
if (Water != null)
{
Water.Passive = false;
Water.Init(Water.SelectedIndex);
}
}
else
{
MapSize.Passive = true;
MapSize.Init(MapSize.SelectedIndex);
OnPlayerOptionClicked(PlayerCount.SelectedIndex);
if (Water != null)
{
Water.Passive = true;
Water.Init(2);
}
}
}
public uint GetSelectedCreativeMatchConfigId()
{
return GetCreativeMatchConfigIdByWinIndex(WinSelectedIndex);
}
private void SetNearToggleSavedValue(bool isCreative)
{
if (NearToggle == null) return;
NearToggle.SetIsOnWithoutNotify(isCreative && PlayerPrefs.GetInt(DISABLE_NEARBY_SPAWN_POINTS_PREFS_KEY, 0) == 1);
}
private void RefreshNearToggleVisibility(bool isCreative)
{
if (NearToggle == null) return;
NearToggle.gameObject.SetActive(isCreative);
NearToggle.interactable = isCreative;
NearToggle.SetIsOnWithoutNotify(isCreative && PlayerPrefs.GetInt(DISABLE_NEARBY_SPAWN_POINTS_PREFS_KEY, 0) == 1);
}
private void OnNearToggleChanged(bool selected)
{
if (GameMode == null || GameMode.SelectedIndex != 2) return;
SaveDisableNearbySpawnPointsPreference(selected);
}
public void SaveDisableNearbySpawnPointsPreference()
{
if (GameMode == null || GameMode.SelectedIndex != 2) return;
SaveDisableNearbySpawnPointsPreference(NearToggle != null && NearToggle.isOn);
}
private static void SaveDisableNearbySpawnPointsPreference(bool selected)
{
PlayerPrefs.SetInt(DISABLE_NEARBY_SPAWN_POINTS_PREFS_KEY, selected ? 1 : 0);
PlayerPrefs.Save();
}
public void Show()
{
InitSetting();
gameObject.SetActive(true);
Animancer.Play(ResourceCache.Instance.AnimCache.UICommonPanelFadeIn);
Timer.Instance.TimerRegister(this, () =>
{
GameMode.OnShow();
PlayerCount.OnShow();
MapSize.OnShow();
Diff.OnShow();
if (Water != null) Water.OnShow();
if (WinGroup != null && WinGroup.gameObject.activeInHierarchy) WinGroup.OnShow();
}, 0.01f, "");
}
public void Hide()
{
var state = Animancer.Play(ResourceCache.Instance.AnimCache.UICommonPanelFadeOut);
state.Events.OnEnd = () => { gameObject.SetActive(false); };
}
private void InitAISettings(uint playerCount, bool preserveUserTeamEdits, bool preserveUserForceEdits)
{
int targetCount = Mathf.Max(0, (int)playerCount - 1);
var usedPlayerOptions = new HashSet<(uint CivId, uint ForceId)>();
AddPlayerEmpireToUsedOptions(usedPlayerOptions);
var nextSettings = new List<AISettingData>();
for (int slotIndex = 1; slotIndex <= targetCount; slotIndex++)
{
var existingData = GetAISettingData(slotIndex);
var slot = GetExistingPlayerSlot(slotIndex);
var setting = CreateAISettingData(slotIndex, playerCount, usedPlayerOptions, existingData, slot, preserveUserTeamEdits, preserveUserForceEdits);
nextSettings.Add(setting);
if (!setting.IsRandom) usedPlayerOptions.Add((setting.CivId, setting.ForceId));
}
_aiSettings.Clear();
_aiSettings.AddRange(nextSettings);
}
private AISettingData CreateAISettingData(
int slotIndex,
uint playerCount,
HashSet<(uint CivId, uint ForceId)> usedPlayerOptions,
AISettingData existingData,
MemberCiv slot,
bool preserveUserTeamEdits,
bool preserveUserForceEdits)
{
if (preserveUserForceEdits
&& existingData != null
&& existingData.IsForceUserEdited
&& (existingData.IsRandom || IsValidPlayerOption(existingData.CivId, existingData.ForceId)))
{
return new AISettingData
{
SlotIndex = slotIndex,
CivId = existingData.CivId,
ForceId = existingData.ForceId,
IsRandom = existingData.IsRandom,
TeamId = GetPreferredTeamId(existingData, slotIndex, (int)playerCount, preserveUserTeamEdits),
IsForceUserEdited = existingData.IsForceUserEdited,
IsTeamUserEdited = preserveUserTeamEdits && existingData.IsTeamUserEdited
};
}
var playerOption = PickDefaultPlayerOption(Mathf.Max(0, slotIndex - 1), usedPlayerOptions);
return new AISettingData
{
SlotIndex = slotIndex,
CivId = playerOption.CivId,
ForceId = playerOption.ForceId,
IsRandom = false,
TeamId = GetPreferredTeamId(existingData, slotIndex, (int)playerCount, preserveUserTeamEdits),
IsForceUserEdited = false,
IsTeamUserEdited = preserveUserTeamEdits && existingData?.IsTeamUserEdited == true
};
}
private void RefreshAISettingRows()
{
CacheExistingAISettingRows();
bool show = GameMode != null && GameMode.SelectedIndex == 2 && AISettingGroup != null;
if (AISettingGroup != null) AISettingGroup.SetActive(show);
if (!show)
{
for (int i = 0; i < _aiSettingRows.Count; i++)
if (_aiSettingRows[i] != null) _aiSettingRows[i].gameObject.SetActive(false);
RefreshAISettingLayout();
return;
}
var sameCountDict = BuildForceSameCountDict();
int maxTeamId = Mathf.Max(1, (int)(PlayerCount.SelectedIndex + 2));
int visibleRowCount = 0;
RenderSelfPlayerRow(sameCountDict, maxTeamId);
visibleRowCount++;
for (int i = 0; i < _aiSettings.Count; i++)
{
int rowIndex = i + 1;
var row = GetAISettingRow(rowIndex);
if (row == null) continue;
row.gameObject.SetActive(true);
row.transform.SetSiblingIndex(rowIndex);
var data = _aiSettings[i];
if (data.IsRandom)
{
row.SetRandomContent(data.TeamId, maxTeamId,
direction => OnAIRowForceChanged(data.SlotIndex, direction),
direction => OnAIRowTeamChanged(data.SlotIndex, direction));
visibleRowCount++;
continue;
}
var civ = Table.Instance.TransCivIdToCivEnum(data.CivId);
var force = Table.Instance.TransForceIdToForceEnum(data.ForceId);
var forceNameOverride = GetForceNameOverride(data, civ, force, sameCountDict);
row.SetContent(civ, force, data.TeamId, maxTeamId, forceNameOverride,
direction => OnAIRowForceChanged(data.SlotIndex, direction),
direction => OnAIRowTeamChanged(data.SlotIndex, direction));
visibleRowCount++;
}
for (int i = visibleRowCount; i < _aiSettingRows.Count; i++)
{
if (_aiSettingRows[i] == null) continue;
_aiSettingRows[i].gameObject.SetActive(false);
_aiSettingRows[i].transform.SetSiblingIndex(i);
}
RefreshAISettingLayout();
}
private void RenderSelfPlayerRow(Dictionary<(CivEnum, ForceEnum), int> sameCountDict, int maxTeamId)
{
var row = GetAISettingRow(0);
if (row == null) return;
row.gameObject.SetActive(true);
row.transform.SetSiblingIndex(0);
if (_playerEmpireIsRandom)
{
row.SetRandomSelfContent(1, maxTeamId);
return;
}
var playerEmpire = GetCurrentPlayerEmpire();
var forceNameOverride = GetSelfForceNameOverride(playerEmpire.Civ, playerEmpire.Force, sameCountDict);
row.SetContent(playerEmpire.Civ, playerEmpire.Force, 1, maxTeamId, forceNameOverride, null, null, false, false);
}
private UIOutsideSelectAISettingRowMono GetAISettingRow(int index)
{
CacheExistingAISettingRows();
if (AISettingRowPrefab == null || AISettingGroup == null) return null;
while (_aiSettingRows.Count <= index)
{
var item = Instantiate(AISettingRowPrefab, AISettingGroup.transform);
item.SetActive(true);
_aiSettingRows.Add(item.GetComponent<UIOutsideSelectAISettingRowMono>());
}
return _aiSettingRows[index];
}
private void CacheExistingAISettingRows()
{
if (_aiSettingRowsCached || AISettingGroup == null) return;
_aiSettingRowsCached = true;
for (int i = 0; i < AISettingGroup.transform.childCount; i++)
{
var row = AISettingGroup.transform.GetChild(i).GetComponent<UIOutsideSelectAISettingRowMono>();
if (row != null && !_aiSettingRows.Contains(row)) _aiSettingRows.Add(row);
}
}
private void RefreshAISettingLayout()
{
if (AISettingGroup == null) return;
var groupRect = AISettingGroup.GetComponent<RectTransform>();
if (groupRect == null) return;
Canvas.ForceUpdateCanvases();
LayoutRebuilder.ForceRebuildLayoutImmediate(groupRect);
var parentRect = groupRect.parent as RectTransform;
if (parentRect != null) LayoutRebuilder.ForceRebuildLayoutImmediate(parentRect);
Canvas.ForceUpdateCanvases();
}
private Dictionary<(CivEnum, ForceEnum), int> BuildForceSameCountDict()
{
var sameCountDict = new Dictionary<(CivEnum, ForceEnum), int>();
if (!_playerEmpireIsRandom)
{
var playerEmpire = GetCurrentPlayerEmpire();
AddSameCount(playerEmpire.Civ, playerEmpire.Force);
}
foreach (var data in _aiSettings)
{
if (data.IsRandom) continue;
AddSameCount(Table.Instance.TransCivIdToCivEnum(data.CivId), Table.Instance.TransForceIdToForceEnum(data.ForceId));
}
return sameCountDict;
void AddSameCount(CivEnum civ, ForceEnum force)
{
if (civ == CivEnum.Common || force == ForceEnum.Common) return;
var key = (civ, force);
sameCountDict.TryGetValue(key, out var prevCnt);
sameCountDict[key] = prevCnt + 1;
}
}
private string GetForceNameOverride(AISettingData data, CivEnum civ, ForceEnum force, Dictionary<(CivEnum, ForceEnum), int> sameCountDict)
{
if (data != null && data.IsRandom) return null;
if (!sameCountDict.TryGetValue((civ, force), out var sameCnt) || sameCnt < 2) return null;
if (!Table.Instance.PlayerDataAssets.GetPlayerInfo(civ, force, out var pi)) return null;
var raw = MultilingualManager.Instance.GetMultilingualTextSafe(pi.ForceName);
return $"{raw} {data.SlotIndex + 1}P";
}
private string GetSelfForceNameOverride(CivEnum civ, ForceEnum force, Dictionary<(CivEnum, ForceEnum), int> sameCountDict)
{
if (!sameCountDict.TryGetValue((civ, force), out var sameCnt) || sameCnt < 2) return null;
if (!Table.Instance.PlayerDataAssets.GetPlayerInfo(civ, force, out var pi)) return null;
var raw = MultilingualManager.Instance.GetMultilingualTextSafe(pi.ForceName);
return $"{raw} 1P";
}
private void OnAIRowForceChanged(int slotIndex, int direction)
{
var data = GetAISettingData(slotIndex);
if (data == null) return;
var next = GetNextAIForce(data.CivId, data.ForceId, direction);
data.IsRandom = next.Civ == CivEnum.Common && next.Force == ForceEnum.Common;
if (data.IsRandom)
{
data.CivId = MapConfig.RandomCivId;
data.ForceId = MapConfig.RandomForceId;
}
else
{
data.CivId = Table.Instance.TransCivEnumToCivId(next.Civ);
data.ForceId = Table.Instance.TransForceEnumToForceId(next.Force);
}
data.IsForceUserEdited = true;
RefreshAISettingRows();
}
private void OnAIRowTeamChanged(int slotIndex, int direction)
{
var data = GetAISettingData(slotIndex);
if (data == null) return;
data.TeamId = GetNextTeamId(data.TeamId, direction);
data.IsTeamUserEdited = true;
RefreshAISettingRows();
}
private AISettingData GetAISettingData(int slotIndex)
{
for (int i = 0; i < _aiSettings.Count; i++)
if (_aiSettings[i].SlotIndex == slotIndex) return _aiSettings[i];
return null;
}
private int GetNextTeamId(int teamId, int direction)
{
int maxTeamId = Mathf.Max(1, (int)(PlayerCount.SelectedIndex + 2));
teamId += direction;
if (teamId < 1) return maxTeamId;
if (teamId > maxTeamId) return 1;
return teamId;
}
private (CivEnum Civ, ForceEnum Force) GetNextAIForce(uint civId, uint forceId, int direction)
{
var options = GetAIForceOptionsWithRandom();
var isRandom = MapConfig.IsRandomPlayerSlotCiv(civId, forceId, false);
var civ = isRandom ? CivEnum.Common : Table.Instance.TransCivIdToCivEnum(civId);
var force = isRandom ? ForceEnum.Common : Table.Instance.TransForceIdToForceEnum(forceId);
int index = 0;
for (int i = 0; i < options.Count; i++)
{
if (options[i].Civ == civ && options[i].Force == force)
{
index = i;
break;
}
}
index = (index + direction + options.Count) % options.Count;
return options[index];
}
private IReadOnlyList<(CivEnum Civ, ForceEnum Force)> GetAIForceOptionsWithRandom()
{
var options = new List<(CivEnum Civ, ForceEnum Force)> { (CivEnum.Common, ForceEnum.Common) };
options.AddRange(GetAIForceOptions());
return options;
}
private IReadOnlyList<(CivEnum Civ, ForceEnum Force)> GetAIForceOptions()
{
var assets = Table.Instance.PlayerDataAssets;
var options = new List<(CivEnum Civ, ForceEnum Force)>();
var optionSet = new HashSet<(CivEnum Civ, ForceEnum Force)>();
if (assets?.PlayerDataList != null)
{
foreach (var info in assets.PlayerDataList)
{
if (info == null) continue;
var civ = Table.Instance.TransCivIdToCivEnum(info.CivId);
var force = Table.Instance.TransForceIdToForceEnum(info.ForceId);
if (civ == CivEnum.Common || force == ForceEnum.Common) continue;
if (!ContentGate.CanUseEmpire(new Empire(civ, force))) continue;
if (!optionSet.Add((civ, force))) continue;
options.Add((civ, force));
}
}
if (options.Count > 0) return options;
foreach (var fallback in FallbackForceOptions)
{
if (ContentGate.CanUseEmpire(new Empire(fallback.Civ, fallback.Force))) options.Add(fallback);
}
if (options.Count == 0) options.Add((CivEnum.Egyptian, ForceEnum.Remilia));
return options;
}
private bool IsValidPlayerOption(uint civId, uint forceId)
{
var civ = Table.Instance.TransCivIdToCivEnum(civId);
var force = Table.Instance.TransForceIdToForceEnum(forceId);
if (civ == CivEnum.Common || force == ForceEnum.Common) return false;
if (!ContentGate.CanUseEmpire(new Empire(civ, force))) return false;
return Table.Instance.PlayerDataAssets.GetPlayerInfo(civ, force, out _);
}
private static int GetPreferredTeamId(AISettingData existingData, int slotIndex, int playerCount, bool preserveUserTeamEdits)
{
if (preserveUserTeamEdits && existingData != null && existingData.IsTeamUserEdited)
return GetValidTeamId(existingData.TeamId, slotIndex, playerCount);
return GetDefaultTeamId(slotIndex, playerCount);
}
private static int GetValidTeamId(int teamId, int slotIndex, int playerCount)
{
int maxTeamId = Mathf.Max(1, playerCount);
if (teamId >= 1 && teamId <= maxTeamId) return teamId;
return GetDefaultTeamId(slotIndex, playerCount);
}
private static int GetDefaultTeamId(int slotIndex, int playerCount)
{
return Mathf.Clamp(slotIndex + 1, 1, Mathf.Max(1, playerCount));
}
private void AddPlayerEmpireToUsedOptions(HashSet<(uint CivId, uint ForceId)> usedPlayerOptions)
{
if (_playerEmpireIsRandom) return;
var playerEmpire = GetCurrentPlayerEmpire();
if (playerEmpire.Civ != CivEnum.Common && playerEmpire.Force != ForceEnum.Common)
{
var civId = Table.Instance.TransCivEnumToCivId(playerEmpire.Civ);
var forceId = Table.Instance.TransForceEnumToForceId(playerEmpire.Force);
if (IsValidPlayerOption(civId, forceId))
{
usedPlayerOptions.Add((civId, forceId));
return;
}
}
var selfSlot = GetExistingPlayerSlot(0);
if (selfSlot != null && IsValidPlayerOption(selfSlot.CivId, selfSlot.ForceId))
{
usedPlayerOptions.Add((selfSlot.CivId, selfSlot.ForceId));
}
}
private Empire GetCurrentPlayerEmpire()
{
if (_playerEmpire.Civ != CivEnum.Common && _playerEmpire.Force != ForceEnum.Common
&& ContentGate.CanUseEmpire(_playerEmpire))
return _playerEmpire;
var selfSlot = GetExistingPlayerSlot(0);
if (selfSlot != null)
{
var civ = Table.Instance.TransCivIdToCivEnum(selfSlot.CivId);
var force = Table.Instance.TransForceIdToForceEnum(selfSlot.ForceId);
var empire = new Empire(civ, force);
if (civ != CivEnum.Common && force != ForceEnum.Common && ContentGate.CanUseEmpire(empire)) return empire;
}
var options = GetAIForceOptions();
var fallback = options[0];
return new Empire(fallback.Civ, fallback.Force);
}
private (uint CivId, uint ForceId) PickDefaultPlayerOption(int preferredIndex, HashSet<(uint CivId, uint ForceId)> usedPlayerOptions)
{
var options = GetAIForceOptions();
for (int offset = 0; offset < options.Count; offset++)
{
int index = (preferredIndex + offset) % options.Count;
var option = options[index];
var ids = (
Table.Instance.TransCivEnumToCivId(option.Civ),
Table.Instance.TransForceEnumToForceId(option.Force));
if (!usedPlayerOptions.Contains(ids)) return ids;
}
var fallback = options[preferredIndex % options.Count];
return (
Table.Instance.TransCivEnumToCivId(fallback.Civ),
Table.Instance.TransForceEnumToForceId(fallback.Force));
}
private static MemberCiv GetExistingPlayerSlot(int slotIndex)
{
var slots = Main.Instance.MapConfig?.MultiCivs;
if (slots == null || slotIndex < 0 || slotIndex >= slots.Count) return null;
return slots[slotIndex];
}
private void OnWinOptionClicked(uint idx)
{
}
private void OnTestModeChanged(bool isOn)
{
}
private static uint GetWinIndexByMatchConfigId(uint matchConfigId)
{
for (int i = 0; i < CreativeWinMatchConfigIds.Length; i++)
{
if (CreativeWinMatchConfigIds[i] == matchConfigId) return (uint)i;
}
return 0;
}
private static uint GetCreativeMatchConfigIdByWinIndex(uint idx)
{
return idx < CreativeWinMatchConfigIds.Length ? CreativeWinMatchConfigIds[(int)idx] : CreativeWinMatchConfigIds[0];
}
}