TH1/Unity/Assets/Scripts/TH1_UI/View/Info/UIInfoDiplomacyView.cs
2026-06-24 20:24:00 +08:00

770 lines
25 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.Collections.Generic;
using Logic;
using Logic.Action;
using Logic.Audio;
using Logic.CrashSight;
using Logic.Multilingual;
using RuntimeData;
using TH1_Core.Events;
using TH1_Core.Managers;
using TH1_Logic.Action;
using TH1_Logic.Core;
using TH1_UI.Components;
using TH1_UI.HintUI;
using TMPro;
using UI.HintUI;
using UnityEngine;
using UnityEngine.UI;
namespace TH1_UI.View.Info
{
public class UIInfoDiplomacyView : Base.View
{
public Button closeButton;
public Button BlockButton;
public RectTransform VerticalGroup;
// Avatar部分
public TextMeshProUGUI ForceTitle;
public RectTransform ForceTitleRect;
public Image LeaderAvatar;
public RectTransform BubbleChat;
public TextMeshProUGUI BubbleChatText;
public Image TopStripeBG2;
public Image TopStripeBG;
public Image ForceTitleBG;
// Status部分
public Transform StatusArea;
public GameObject Status;
public Image StateIcon;
public TextMeshProUGUI StateText;
public RectTransform Title_Status;
//态度条
public GameObject AttitudeArea;
public TextMeshProUGUI AttitudeNoMeetText;
public RectTransform RelationHandle;
public GameObject AttitudeBar;
public HintTrigger AttitudeBarHint;
//ActionArea
public Transform ActionArea;
public Image AllyActionCircleBGOutside;
public Image AllyActionCircleBG;
public GameObject AllyActionSend;
public Button AllyActionButton;
public Image EmbassyActionCircleBGOutside;
public Image EmbassyActionCircleBG;
public Image EmbassyActionCost;
public TextMeshProUGUI EmbassyActionCostText;
public Button EmbassyActionButton;
public GameObject BreakAllyAction;
public Button BreakAllyActionButton;
private GameObject _robAction;
private Image _robActionCircleBGOutside;
private Image _robActionCircleBG;
private GameObject _robActionSend;
private Button _robActionButton;
private Image _robActionIcon;
private TextMeshProUGUI _robActionTitle;
private HintTrigger _robActionHint;
private Image _robActionCost;
private TextMeshProUGUI _robActionCostText;
private GameObject _robActionTime;
private TextMeshProUGUI _robActionTimeText;
//RelationArea
// 动态池:根据敌方数量按需 Instantiate复用已有实例
public GameObject UIInfoDiplomacyAvatarPrefab; // 拖入 UIInfoDiplomacyAvatar.prefab
public RectTransform RelationAvatarContainer; // Avatar 的父容器(带 LayoutGroup
private List<UIInfoDiplomacyAvatarMono> _relationAvatarPool = new List<UIInfoDiplomacyAvatarMono>();
public ViDelegateAssisstant.Dele OnBtnCloseClick;
public GameObject RelationNoMeetHint;
public Sprite BlueBG;
public Sprite GrayBG;
public Sprite GreenBG;
public Color GrayColor;
public Color GreenColor;
public Color BlueColor;
public Color RedColor;
public Color BlueTextColor;
public Color RedTextColor;
protected override void OnInit()
{
base.OnInit();
closeButton.onClick.RemoveAllListeners();
BlockButton.onClick.RemoveAllListeners();
closeButton.onClick.AddListener(() => { OnBtnCloseClick.Invoke(); });
BlockButton.onClick.AddListener(() => { OnBtnCloseClick.Invoke(); });
}
public void SetContent(uint pid)
{
if (!Main.MapData.PlayerMap.GetPlayerDataByPlayerID(pid, out var player)) return;
if (!Table.Instance.PlayerDataAssets.GetPlayerInfo(player, out var info)) return;
var selfp = Main.MapData.PlayerMap.SelfPlayerData;
player.GetCountryDiplomacyInfo(selfp.Id, out var dipInfo);
//step #1 设置AvatarArea和chatBubble
SetContentAvatarArea(player);
//Step #2 设置StatusAcrea
SetContentStatusArea(player);
//Step #3 设置AttitudeArea
SetContentAttitudeArea(player);
//Step #4
SetContentActionArea(player);
//Step #5 设置该玩家和其他玩家的关系
SetContentRelationArea(player);
//Step #6 设置BGM
AudioManager.Instance.PlayMusic(info.MusicName,1f,2f,true);
//Step #7 重新排布:子元素先 rebuild父容器 VerticalGroup 再整体 rebuild
if (Title_Status != null)
LayoutRebuilder.ForceRebuildLayoutImmediate(Title_Status);
LayoutRebuilder.ForceRebuildLayoutImmediate(VerticalGroup);
}
private void SetContentAvatarArea(PlayerData player)
{
bool isSelf = (player.Id == Main.MapData.PlayerMap.SelfPlayerData.Id);
var titleText = isSelf ? Table.Instance.DiplomacyDataAssets.DiplomacyUITitleSelf:Table.Instance.DiplomacyDataAssets.DiplomacyUITitle;
if (!Table.Instance.PlayerDataAssets.GetPlayerInfo(player, out var info)) return;
var forceName = Logic.PlayerLogic.GetDisplayForceName(Main.MapData, player);
MultilingualManager.Instance.SetUIText(ForceTitle,titleText,new List<string>{forceName});
LayoutRebuilder.ForceRebuildLayoutImmediate(ForceTitleRect);
LeaderAvatar.sprite = info.LeaderAvatar;
//设置color
var color2 = info.Color;
color2.a = 0.4f;
TopStripeBG2.color = color2;
TopStripeBG.color = info.Color;
ForceTitleBG.color = info.Color;
if (isSelf)
{
BubbleChat.gameObject.SetActive(false);
return;
}
player.GetCountryDiplomacyInfo(Main.MapData.PlayerMap.SelfPlayerId, out var dipInfo);
bool meetus = dipInfo.DiplomacyState != DiplomacyState.NoDiplomacy;
if (!meetus)
{
BubbleChat.gameObject.SetActive(false);
return;
}
var chatText = Table.Instance.DiplomacyDataAssets.GetDiplomacyTextByFeeling((Forces)(player.PlayerForceId),dipInfo.FeelingState);
if (string.IsNullOrEmpty(chatText) || chatText == "0")
{
BubbleChat.gameObject.SetActive(false);
return;
}
BubbleChat.gameObject.SetActive(true);
MultilingualManager.Instance.SetUIText(BubbleChatText, chatText);
LayoutRebuilder.ForceRebuildLayoutImmediate(BubbleChat);
}
private void SetContentStatusArea(PlayerData player)
{
bool isSelf = (player.Id == Main.MapData.PlayerMap.SelfPlayerData.Id);
StatusArea.gameObject.SetActive(!isSelf);
if (isSelf) return;
if (!player.GetCountryDiplomacyInfo(Main.MapData.PlayerMap.SelfPlayerId, out var dipInfo)) return;
if (!Table.Instance.DiplomacyDataAssets.GetStateInfo(dipInfo.DiplomacyState, out var stateInfo)) return;
bool meetus = dipInfo.DiplomacyState != DiplomacyState.NoDiplomacy;
Status.gameObject.SetActive(meetus);
StateIcon.color = stateInfo.StateColor;
StateIcon.sprite = stateInfo.StateIcon;
MultilingualManager.Instance.SetUIText(StateText,stateInfo.StateText);
}
private void SetContentAttitudeArea(PlayerData player)
{
bool isSelf = (player.Id == Main.MapData.PlayerMap.SelfPlayerData.Id);
AttitudeArea.gameObject.SetActive(!isSelf);
if (isSelf) return;
if (!player.GetCountryDiplomacyInfo(Main.MapData.PlayerMap.SelfPlayerId, out var dipInfo)) return;
bool meetus = dipInfo.DiplomacyState != DiplomacyState.NoDiplomacy;
AttitudeNoMeetText.gameObject.SetActive(!meetus);
AttitudeBar.SetActive(meetus);
if(!meetus) return;
RelationHandle.anchoredPosition = new Vector2(Mathf.Lerp(13f, 585f, dipInfo.FeelingValue/100f),RelationHandle.anchoredPosition.y);
var text = $"<color=yellow>" + MultilingualManager.Instance.GetMultilingualTextSafe(Table.Instance.TextDataAssets.PresentationUIDiplomacyThinkYouText) +"</color><br>";
foreach (var op in dipInfo.FeelingStrategyList)
{
if (!Table.Instance.DiplomacyDataAssets.GetFeelingStragegyInfo(op, out var stgInfo)) continue;
text += $"<color=#{ColorUtility.ToHtmlStringRGB(stgInfo.FeelingStrategyColor)}>";
text += MultilingualManager.Instance.GetMultilingualTextSafe(stgInfo.FeelingStrategyTitle);
text += "</color>:";
text += MultilingualManager.Instance.GetMultilingualTextSafe(stgInfo.FeelingStrategyDesc);
text += "<br>";
}
AttitudeBarHint.DataProvider.HintDataType = HintDataType.TextData;
AttitudeBarHint.DataProvider.Text = text;
}
private void SetContentActionArea(PlayerData player)
{
bool isSelf = (player.Id == Main.MapData.PlayerMap.SelfPlayerData.Id);
ActionArea.gameObject.SetActive(!isSelf);
if (isSelf) return;
HideRobActionIfBound();
if (!player.GetCountryDiplomacyInfo(Main.MapData.PlayerMap.SelfPlayerId, out var dipInfo)) return;
SetAllyAction(player);
SetEmbassyAction(player);
SetBreakAllyAction(player);
SetRobAction(player);
}
private void SetAllyAction(PlayerData player)
{
if (player == null)
{
LogSystem.LogError("SetAllyAction Error: player is null");
return;
}
var actionId = new CommonActionId()
{ ActionType = CommonActionType.PlayerAction, PlayerActionType = PlayerActionType.OfferAlly};
var actionParams = new CommonActionParams(
mapData: Main.MapData,
playerData: Main.MapData.PlayerMap.SelfPlayerData,
targetPlayer:player,
mainObjectType: MainObjectType.Player);
var action = ActionLogicFactory.GetActionLogic(actionId);
// 检查 action 是否为 null
if (action == null)
{
LogSystem.LogError("SetAllyAction Error: action is null");
return;
}
// 检查 UI 组件
if (AllyActionButton == null || AllyActionCircleBGOutside == null || AllyActionCircleBG == null || AllyActionSend == null)
{
LogSystem.LogError($"SetAllyAction Error: UI Component is null. AllyActionButton={AllyActionButton}, AllyActionCircleBGOutside={AllyActionCircleBGOutside}, AllyActionCircleBG={AllyActionCircleBG}, AllyActionSend={AllyActionSend}");
return;
}
if (!action.CheckShow(actionParams, out var actionCantType)) return;
AllyActionButton.onClick.RemoveAllListeners();
switch (actionCantType)
{
case ShowType.Locked:
AllyActionCircleBGOutside.color = GrayColor;
AllyActionCircleBG.sprite = GrayBG;
AllyActionSend.gameObject.SetActive(false);
break;
case ShowType.None:
AllyActionCircleBGOutside.color = BlueColor;
AllyActionCircleBG.sprite = BlueBG;
AllyActionSend.gameObject.SetActive(false);
AllyActionButton.onClick.AddListener(() =>
{
//只有轮到我行动的时候,点击才生效
if (actionParams.MapData?.CurPlayer != null &&
actionParams.MapData.CurPlayer == Main.MapData?.PlayerMap?.SelfPlayerData)
{
action.CompleteExecute(actionParams);
//EventManager.Publish(new HideUIInfoDiplomacy(){non = 0});
//TODO 莫名其妙的bug publish Hide 不生效, 强制Close才生效
OnBtnCloseClick?.Invoke();
}
});
break;
case ShowType.Send:
AllyActionCircleBGOutside.color = BlueColor;
AllyActionCircleBG.sprite = BlueBG;
AllyActionSend.gameObject.SetActive(true);
break;
case ShowType.Done:
AllyActionCircleBGOutside.color = GreenColor;
AllyActionCircleBG.sprite = GreenBG;
AllyActionSend.gameObject.SetActive(false);
break;
}
}
private void SetEmbassyAction(PlayerData player)
{
if (player == null)
{
LogSystem.LogError($"SetEmbassyAction Error player is null");
return;
}
var actionId = new CommonActionId()
{ ActionType = CommonActionType.PlayerAction, PlayerActionType = PlayerActionType.Embassy};
var actionParams = new CommonActionParams(
mapData: Main.MapData,
playerData: Main.MapData.PlayerMap.SelfPlayerData,
targetPlayer:player,
mainObjectType: MainObjectType.Player);
var action = ActionLogicFactory.GetActionLogic(actionId);
if (action == null)
{
LogSystem.LogError($"SetEmbassyAction Error Action is null");
return;
}
if (!action.CheckShow(actionParams, out var actionCantType)) return;
if (!EmbassyActionButton || !EmbassyActionCircleBGOutside || !EmbassyActionCircleBG || !EmbassyActionCost ||
!EmbassyActionCostText || OnBtnCloseClick == null)
{
LogSystem.LogError($"SetEmbassyAction Error UI Component is null " +
$"{EmbassyActionButton} {EmbassyActionCircleBGOutside} {EmbassyActionCircleBG} " +
$"{EmbassyActionCost} {EmbassyActionCostText} {OnBtnCloseClick}");
return;
}
EmbassyActionButton.onClick.RemoveAllListeners();
switch (actionCantType)
{
case ShowType.Locked:
EmbassyActionCircleBGOutside.color = GrayColor;
EmbassyActionCircleBG.sprite = GrayBG;
EmbassyActionCost.gameObject.SetActive(false);
break;
case ShowType.None:
EmbassyActionCircleBGOutside.color = BlueColor;
EmbassyActionCircleBG.sprite = BlueBG;
EmbassyActionCost.gameObject.SetActive(true);
EmbassyActionCostText.color = BlueTextColor;
EmbassyActionButton.onClick.AddListener(() =>
{
//只有轮到我行动的时候,点击才生效
if (actionParams.MapData.CurPlayer != null &&
actionParams.MapData.CurPlayer == Main.MapData.PlayerMap.SelfPlayerData)
{
action.CompleteExecute(actionParams);
//EventManager.Publish(new HideUIInfoDiplomacy(){non =0});
//TODO 莫名其妙的bug publish Hide 不生效, 强制Close才生效
OnBtnCloseClick?.Invoke();
}
});
break;
case ShowType.Cost:
EmbassyActionCircleBGOutside.color = RedColor;
EmbassyActionCircleBG.sprite = BlueBG;
EmbassyActionCost.gameObject.SetActive(true);
EmbassyActionCostText.color = RedTextColor;
break;
case ShowType.Done:
EmbassyActionCircleBGOutside.color = GreenColor;
EmbassyActionCircleBG.sprite = GreenBG;
EmbassyActionCost.gameObject.SetActive(false);
break;
}
}
private void SetBreakAllyAction(PlayerData player)
{
if (player == null)
{
LogSystem.LogError("SetBreakAllyAction Error: player is null");
return;
}
var actionId = new CommonActionId()
{ ActionType = CommonActionType.PlayerAction, PlayerActionType = PlayerActionType.BreakAlly};
var actionParams = new CommonActionParams(
mapData: Main.MapData,
playerData: Main.MapData.PlayerMap.SelfPlayerData,
targetPlayer:player,
mainObjectType: MainObjectType.Player);
var action = ActionLogicFactory.GetActionLogic(actionId);
// 检查 action 是否为 null
if (action == null)
{
LogSystem.LogError("SetBreakAllyAction Error: action is null");
return;
}
// 检查 UI 组件
if (BreakAllyAction == null || BreakAllyActionButton == null)
{
LogSystem.LogError($"SetBreakAllyAction Error: UI Component is null. BreakAllyAction={BreakAllyAction}, BreakAllyActionButton={BreakAllyActionButton}");
return;
}
bool canShow = action.CheckShow(actionParams, out var actionCantType);
BreakAllyAction.gameObject.SetActive(canShow);
BreakAllyActionButton.onClick.RemoveAllListeners();
if (!canShow) return;
BreakAllyActionButton.onClick.AddListener(() =>
{
//只有轮到我行动的时候,点击才生效
if (actionParams.MapData.CurPlayer != null && actionParams.MapData.CurPlayer == Main.MapData.PlayerMap.SelfPlayerData)
{
action.CompleteExecute(actionParams);
//TODO 莫名其妙的bug publish Hide 不生效, 强制Close才生效 _task居然=空 导致无法关闭
//EventManager.Publish(new HideUIInfoDiplomacy());
OnBtnCloseClick?.Invoke();
}
});
}
private void HideRobActionIfBound()
{
if (_robAction == null && ActionArea != null)
{
_robAction = ActionArea.Find("RobAction")?.gameObject;
}
if (_robAction != null) _robAction.SetActive(false);
}
private void SetRobAction(PlayerData player)
{
if (player == null)
{
LogSystem.LogError("SetRobAction Error: player is null");
return;
}
var actionId = new CommonActionId()
{ ActionType = CommonActionType.PlayerAction, PlayerActionType = PlayerActionType.DanegeldDemand };
var actionParams = new CommonActionParams(
mapData: Main.MapData,
playerData: Main.MapData.PlayerMap.SelfPlayerData,
targetPlayer: player,
mainObjectType: MainObjectType.Player);
var action = ActionLogicFactory.GetActionLogic(actionId);
if (action == null)
{
LogSystem.LogError("SetRobAction Error: action is null");
return;
}
if (!BindRobActionObject()) return;
bool canShow = action.CheckShow(actionParams, out var actionCantType);
if (!canShow)
{
_robAction.SetActive(false);
return;
}
_robAction.SetActive(true);
_robActionButton.onClick.RemoveAllListeners();
if (_robActionSend != null) _robActionSend.SetActive(false);
var cost = action.GetCost(actionParams);
SetRobActionCost(cost, BlueTextColor, false);
SetRobActionCooldown(0, false);
SetRobActionInfo(actionId);
bool locked = !action.CheckCan(actionParams);
switch (actionCantType)
{
case ShowType.None:
SetRobActionVisual(BlueColor, BlueBG);
SetRobActionCost(cost, BlueTextColor, true);
if (!locked && CanLocalExecuteAction(actionParams))
{
_robActionButton.onClick.AddListener(() =>
{
if (!action.CheckCan(actionParams)) return;
if (!CanLocalExecuteAction(actionParams)) return;
if (action.CompleteExecute(actionParams))
OnBtnCloseClick?.Invoke();
});
}
break;
case ShowType.Send:
SetRobActionVisual(BlueColor, BlueBG);
if (_robActionSend != null) _robActionSend.SetActive(true);
break;
case ShowType.Done:
SetRobActionVisual(GreenColor, GreenBG);
break;
case ShowType.Cost:
SetRobActionVisual(RedColor, BlueBG);
SetRobActionCost(cost, RedTextColor, true);
break;
case ShowType.Cold:
locked = true;
SetRobActionVisual(GrayColor, GrayBG);
SetRobActionCost(cost,
actionParams.PlayerData != null && actionParams.PlayerData.PlayerCoin < cost
? RedTextColor
: BlueTextColor,
true);
SetRobActionCooldown(GetDanegeldCooldownTurns(actionParams), true);
break;
default:
SetRobActionVisual(GrayColor, GrayBG);
break;
}
SetRobActionHint(actionId, locked);
}
private bool BindRobActionObject()
{
if (ActionArea == null)
{
LogSystem.LogError("SetRobAction Error: ActionArea is null");
return false;
}
if (_robAction == null)
{
_robAction = ActionArea.Find("RobAction")?.gameObject;
}
if (_robAction == null)
{
LogSystem.LogError("SetRobAction Error: RobAction is not found under ActionArea");
return false;
}
var root = _robAction.transform;
var bg = FindChildRecursive(root, "BG");
var bg2 = FindChildRecursive(root, "BG2");
var icon = bg != null ? FindChildRecursive(bg, "Icon") : FindChildRecursive(root, "Icon");
var title = FindChildRecursive(root, "Title");
var cost = FindChildRecursive(root, "Cost");
var time = FindChildRecursive(root, "Time");
_robActionCircleBGOutside = bg2?.GetComponent<Image>();
_robActionCircleBG = bg?.GetComponent<Image>();
_robActionButton = bg?.GetComponent<Button>() ?? root.GetComponent<Button>();
_robActionHint = bg?.GetComponent<HintTrigger>() ?? root.GetComponent<HintTrigger>();
_robActionSend = bg != null ? FindChildRecursive(bg, "Send")?.gameObject : FindChildRecursive(root, "Send")?.gameObject;
_robActionIcon = icon?.GetComponent<Image>();
_robActionTitle = title?.GetComponent<TextMeshProUGUI>();
_robActionCost = cost?.GetComponent<Image>();
_robActionCostText = cost?.GetComponentInChildren<TextMeshProUGUI>(true);
_robActionTime = time?.gameObject;
_robActionTimeText = time?.GetComponentInChildren<TextMeshProUGUI>(true);
SetRobActionCost(0, BlueTextColor, false);
if (_robActionCircleBGOutside == null || _robActionCircleBG == null ||
_robActionButton == null || _robActionIcon == null || _robActionTitle == null)
{
LogSystem.LogError($"SetRobAction Error: UI Component is null. " +
$"BGOutside={_robActionCircleBGOutside}, BG={_robActionCircleBG}, " +
$"Button={_robActionButton}, Icon={_robActionIcon}, Title={_robActionTitle}");
return false;
}
return true;
}
private static Transform FindChildRecursive(Transform root, string childName)
{
if (root == null) return null;
if (root.name == childName) return root;
for (int i = 0; i < root.childCount; i++)
{
var found = FindChildRecursive(root.GetChild(i), childName);
if (found != null) return found;
}
return null;
}
private void SetRobActionInfo(CommonActionId actionId)
{
if (!Table.Instance.ActionDataAssets.GetActionInfo(actionId, out var info)) return;
var selfPlayer = Main.MapData.PlayerMap.SelfPlayerData;
var civ = selfPlayer.CivEnum;
var force = selfPlayer.ForceEnum;
SetActionInfoText(_robActionTitle, info.GetActionName(civ, force, GridSpType.None));
}
private void SetRobActionVisual(Color circleColor, Sprite bgSprite)
{
if (_robActionCircleBGOutside != null) _robActionCircleBGOutside.color = circleColor;
if (_robActionCircleBG != null) _robActionCircleBG.sprite = bgSprite;
}
private void SetRobActionCost(int cost, Color textColor, bool visible)
{
if (_robActionCost == null) return;
_robActionCost.gameObject.SetActive(visible && cost > 0);
if (_robActionCostText == null) return;
_robActionCostText.text = cost.ToString();
_robActionCostText.color = textColor;
}
private void SetRobActionCooldown(int turnCount, bool visible)
{
if (_robActionTime == null) return;
_robActionTime.SetActive(visible);
if (_robActionTimeText != null)
{
_robActionTimeText.text = Mathf.Max(1, turnCount).ToString();
_robActionTimeText.alignment = TextAlignmentOptions.Center;
_robActionTimeText.color = Color.white;
_robActionTimeText.fontSize = Mathf.Max(_robActionTimeText.fontSize, 20f);
}
}
private static int GetDanegeldCooldownTurns(CommonActionParams actionParams)
{
var player = actionParams?.PlayerData;
var targetPlayer = actionParams?.TargetPlayerData;
if (player == null || targetPlayer == null) return 0;
if (!player.GetCountryDiplomacyInfo(targetPlayer.Id, out var info) || info == null) return 0;
if (info.LastDanegeldDemandTurn == 0) return 0;
var cooldownEndTurn = (long)info.LastDanegeldDemandTurn + 2;
return Mathf.Max(0, (int)(cooldownEndTurn - player.Turn));
}
private void SetRobActionHint(CommonActionId actionId, bool locked)
{
if (_robActionHint == null || _robActionHint.DataProvider == null) return;
_robActionHint.DataProvider.HintDataType = HintDataType.ActionHintData;
_robActionHint.DataProvider.ActionIdData = actionId;
_robActionHint.DataProvider.locked = locked;
}
private static bool CanLocalExecuteAction(CommonActionParams actionParams)
{
return actionParams?.MapData?.CurPlayer != null
&& actionParams.PlayerData != null
&& actionParams.MapData.CurPlayer.Id == actionParams.PlayerData.Id
&& actionParams.MapData.CanLocalControlPlayer(actionParams.PlayerData.Id);
}
private static void SetActionInfoText(TextMeshProUGUI text, string value)
{
if (text == null) return;
if (uint.TryParse(value, out _))
{
MultilingualManager.Instance.SetUIText(text, value);
return;
}
var multilingual = text.GetComponent<MultilingualTextMono>();
if (multilingual != null) multilingual.ID = 0;
text.text = value ?? "";
}
private void SetContentRelationArea(PlayerData player)
{
if (UIInfoDiplomacyAvatarPrefab == null || RelationAvatarContainer == null)
{
LogSystem.LogError($"[UIInfoDiplomacyView] RelationArea 配置缺失: prefab={UIInfoDiplomacyAvatarPrefab}, container={RelationAvatarContainer}");
return;
}
//先全部隐藏,确保即使中途异常或跳过也不会残留上次的显示
for (int i = 0; i < _relationAvatarPool.Count; i++)
{
if (_relationAvatarPool[i] != null)
_relationAvatarPool[i].gameObject.SetActive(false);
}
int rk = 0;
//依次设置pid对她的每一个pid2的外交关系
foreach (var pid2 in player.MeetPlayers)
{
if (pid2 == player.Id) continue;
if(!Main.MapData.PlayerMap.GetPlayerDataByPlayerID(pid2,out var player2))continue;
if (!player2.IsSurvival) continue;
//双向 meet 状态可能不一致A.MeetPlayers 包含 X但 A.DiplomacyData 里还没 X 的外交项
//此时 dipInfo2=null必须 continue 否则 NRE
if (!player.GetCountryDiplomacyInfo(pid2, out var dipInfo2) || dipInfo2 == null) continue;
if(!Table.Instance.DiplomacyDataAssets.GetStateInfo(dipInfo2.DiplomacyState, out var stateInfo2))continue;
var avatar = GetOrCreateRelationAvatar(rk);
if (avatar == null) continue;
avatar.gameObject.SetActive(true);
//设置名字、头像、外交状态
avatar.SetContent(player2, stateInfo2.DiplomacyState,
!Main.MapData.PlayerMap.SelfPlayerData.MeetPlayers.Contains(pid2));
rk++;
}
RelationNoMeetHint.SetActive(rk == 0);
}
// 池容量不足时扩容;返回指定索引位置的 Avatar 实例
private UIInfoDiplomacyAvatarMono GetOrCreateRelationAvatar(int index)
{
while (_relationAvatarPool.Count <= index)
{
var go = Instantiate(UIInfoDiplomacyAvatarPrefab, RelationAvatarContainer);
var mono = go.GetComponent<UIInfoDiplomacyAvatarMono>();
if (mono == null)
{
LogSystem.LogError($"[UIInfoDiplomacyView] UIInfoDiplomacyAvatarPrefab 缺少 UIInfoDiplomacyAvatarMono 组件");
Destroy(go);
return null;
}
_relationAvatarPool.Add(mono);
}
return _relationAvatarPool[index];
}
public void CloseView()
{
AudioManager.Instance.StopMusic();
Logic.Audio.AudioManager.Instance.ResumeBgmRotationIfEnabled();
}
}
}