408 lines
17 KiB
C#
408 lines
17 KiB
C#
// 文件位置: Assets/Scripts/TH1_UI/View/Announce/UIInteractionCityUpgradeItem.cs
|
||
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Net.Mime;
|
||
using System.Text;
|
||
using Logic.Action;
|
||
using Logic.CrashSight;
|
||
using Logic.Multilingual;
|
||
using Logic.Skill;
|
||
using RuntimeData;
|
||
using TH1_Logic.Action;
|
||
using TH1_Logic.Core;
|
||
using TH1_Logic.HeroTask;
|
||
using TH1_UI.HintUI;
|
||
using TH1Resource;
|
||
using TMPro;
|
||
using UI.HintUI;
|
||
using Unity.VisualScripting;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
|
||
namespace TH1_UI.View.Info
|
||
{
|
||
public class UIInfoCommonBaseActionCircleMono : MonoBehaviour
|
||
{
|
||
[Header("会响应玩家交互的模块")]
|
||
public Button ClickButton;
|
||
public HintTrigger HintTrigger;
|
||
|
||
|
||
[Header("需要每局游戏开始初始化的模块")]
|
||
public Image ActionImg;
|
||
public TextMeshProUGUI Title;
|
||
|
||
[Header("需要每次打开界面都刷新的模块")]
|
||
public Image BG;
|
||
public CanvasGroup BGCanvasGroup;
|
||
public Image CircleBG;
|
||
public GameObject CostBar;
|
||
public Image CostIcon;
|
||
public TextMeshProUGUI CostText;
|
||
public Sprite CoinCostSprite;
|
||
public Sprite CultureCostSprite;
|
||
public Sprite EinherjarCostSprite;
|
||
public GameObject TimeBar;
|
||
public TextMeshProUGUI TimeText;
|
||
public Color TextBlue;
|
||
public Color TextRed;
|
||
public Color TextGrey;
|
||
public Color CircleGray;
|
||
public Color CircleYellow;
|
||
public Color CircleRed;
|
||
public Sprite GroundBG;
|
||
public Sprite GroundGrayBG;
|
||
public Sprite BlueBG;
|
||
public Sprite GrayBG;
|
||
|
||
|
||
public void SetTreasureOptionContent(ActionOption option, Action<CommonActionId, CommonActionParams> actionClickCallback)
|
||
{
|
||
if (option?.ActionId == null || option.Param == null)
|
||
{
|
||
Debug.LogError("UIInfoCommonBaseActionCircleMono.SetTreasureOptionContent: option/action/param is null");
|
||
return;
|
||
}
|
||
|
||
var player = option.Param.PlayerData ?? Main.MapData?.PlayerMap?.SelfPlayerData;
|
||
var civ = player?.CivEnum ?? CivEnum.Egyptian;
|
||
var force = player?.ForceEnum ?? ForceEnum.Remilia;
|
||
var hasActionInfo = Table.Instance.ActionDataAssets.GetActionInfo(option.ActionId, out var info);
|
||
var title = hasActionInfo
|
||
? MultilingualManager.Instance.GetMultilingualTextSafe(info.GetActionName(civ, force, GridSpType.None), MultilingualManager.Instance.CurrentType)
|
||
: GetTreasureOptionTitle(option);
|
||
if (Title != null) Title.text = title;
|
||
var treasureOptionSprite = GetTreasureOptionSprite(option, player);
|
||
var sprite = option.RewardType == TreasureActionRewardType.Unit
|
||
? treasureOptionSprite
|
||
: hasActionInfo
|
||
? info.GetIcon(civ, force, GridSpType.None)
|
||
: treasureOptionSprite;
|
||
if (hasActionInfo && sprite == null) sprite = info.Icon;
|
||
sprite ??= treasureOptionSprite;
|
||
if (ActionImg != null && sprite != null)
|
||
{
|
||
ActionImg.sprite = sprite;
|
||
IconSizingUtility.SetIconSize(ActionImg, hasActionInfo ? info.IconViewSizeType : IconViewSizeType._256x256, true);
|
||
}
|
||
|
||
if (BG != null) BG.sprite = BlueBG;
|
||
if (BGCanvasGroup != null) BGCanvasGroup.alpha = 1f;
|
||
if (CircleBG != null) CircleBG.color = CircleYellow;
|
||
if (Title != null) Title.color = TextBlue;
|
||
if (CostBar != null) CostBar.SetActive(false);
|
||
if (TimeBar != null) TimeBar.SetActive(false);
|
||
|
||
if (ClickButton == null) return;
|
||
ClickButton.onClick.RemoveAllListeners();
|
||
var action = ActionLogicFactory.GetActionLogic(option.ActionId);
|
||
var locked = false;
|
||
if (action != null && action.CheckCan(option.Param))
|
||
{
|
||
ClickButton.onClick.AddListener(() =>
|
||
{
|
||
actionClickCallback?.Invoke(option.ActionId, option.Param);
|
||
});
|
||
}
|
||
else
|
||
{
|
||
if (CircleBG != null) CircleBG.color = CircleGray;
|
||
if (BG != null) BG.sprite = GrayBG;
|
||
if (Title != null) Title.color = TextGrey;
|
||
locked = true;
|
||
}
|
||
|
||
if (HintTrigger != null)
|
||
{
|
||
if (hasActionInfo)
|
||
{
|
||
HintTrigger.DataProvider.HintDataType = HintDataType.ActionHintData;
|
||
HintTrigger.DataProvider.ActionIdData = option.ActionId;
|
||
HintTrigger.DataProvider.locked = locked;
|
||
}
|
||
else
|
||
{
|
||
HintTrigger.DataProvider.HintDataType = HintDataType.TextData;
|
||
HintTrigger.DataProvider.Text = title;
|
||
}
|
||
}
|
||
}
|
||
|
||
public void SetContent(CommonActionId actionId,ShowType cantType, CommonActionParams param, Action<CommonActionId,CommonActionParams> actionClickCallback)
|
||
{
|
||
// 添加参数校验
|
||
if (actionId == null)
|
||
{
|
||
Debug.LogError("UIInfoCommonBaseActionCircleMono.SetContent: actionId 为 null");
|
||
return;
|
||
}
|
||
|
||
if (param == null)
|
||
{
|
||
Debug.LogError("UIInfoCommonBaseActionCircleMono.SetContent: param 为 null");
|
||
return;
|
||
}
|
||
|
||
//Step #0 基础变量设置
|
||
if (!Table.Instance.ActionDataAssets.GetActionInfo(actionId, out var info))
|
||
{
|
||
return;
|
||
}
|
||
var player = Main.MapData.PlayerMap.SelfPlayerData;
|
||
|
||
//Step #1 处理图片 名字
|
||
var civ = Main.MapData.PlayerMap.SelfPlayerData.CivEnum;
|
||
var force = Main.MapData.PlayerMap.SelfPlayerData.ForceEnum;
|
||
var gridSp = GridSpType.None;
|
||
|
||
if (actionId.ActionType == CommonActionType.Gain && param.GridData != null)
|
||
{
|
||
civ = param.GridData.CivEnum;
|
||
gridSp = param.GridData.GetOnlyOneSpType();
|
||
//吃饭回来:测试图标是否跟着环境变化,尤其要测永远亭
|
||
}
|
||
|
||
var title = info.GetActionName(civ, force, gridSp);
|
||
var actionSprite = info.GetIcon(civ,force,gridSp);
|
||
if (TryGetCityLevelUpBigGuyUnitInfo(actionId, param, out var bigGuyUnitInfo))
|
||
{
|
||
title = bigGuyUnitInfo.Name;
|
||
actionSprite = bigGuyUnitInfo.Sprite != null ? bigGuyUnitInfo.Sprite : actionSprite;
|
||
}
|
||
SetActionInfoText(Title, title);
|
||
ActionImg.sprite = actionSprite;
|
||
IconSizingUtility.SetIconSize(ActionImg,info.IconViewSizeType,true);
|
||
|
||
//Step #2 确定背景图是groundcircle还是普通circle
|
||
bool circleGround = actionId.ActionType is CommonActionType.Build or CommonActionType.TrainUnit
|
||
or CommonActionType.BuildWonder or CommonActionType.Gain;
|
||
if (actionId.GridMiscActionType is GridMiscActionType.SellMetal or GridMiscActionType.GrowForest or GridMiscActionType.GrowForestOutside or GridMiscActionType.CreateMountain)
|
||
circleGround = true;
|
||
BG.sprite = circleGround ? GroundBG : BlueBG;
|
||
|
||
//Step #2.5 预计算成本和显示状态
|
||
var action = ActionLogicFactory.GetActionLogic(actionId);
|
||
bool isEinherjarCost = actionId.ActionType == CommonActionType.HakureiEinherjarCityDevelopment;
|
||
int cost = isEinherjarCost && action is HakureiEinherjarCityDevelopmentAction einherjarAction
|
||
? einherjarAction.GetEinherjarCost(param)
|
||
: action.GetCost(param);
|
||
bool isCultureTrain = actionId.ActionType == CommonActionType.TrainUnit
|
||
&& (UnitData.IsBigGuyType(actionId.UnitType) || actionId.UnitType == UnitType.Giant);
|
||
bool isCultureCost = isCultureTrain
|
||
|| (actionId.ActionType == CommonActionType.UnitAction
|
||
&& actionId.UnitActionType == UnitActionType.CultureUnitUpgrade);
|
||
CostText.text = cost.ToString();
|
||
CostText.color = TextBlue;
|
||
if (isEinherjarCost)
|
||
{
|
||
if (CostIcon != null)
|
||
CostIcon.sprite = EinherjarCostSprite != null ? EinherjarCostSprite : CoinCostSprite;
|
||
if (HakureiEinherjarCounter.GetPlayerPoints(player) < cost)
|
||
CostText.color = Color.red;
|
||
}
|
||
else if (isCultureCost)
|
||
{
|
||
// BigGuy用文化值判断
|
||
if (CostIcon != null && CultureCostSprite != null)
|
||
CostIcon.sprite = CultureCostSprite;
|
||
if (player.PlayerCultureInfo.PlayerCulture < cost)
|
||
CostText.color = Color.red;
|
||
}
|
||
else
|
||
{
|
||
if (CostIcon != null && CoinCostSprite != null)
|
||
CostIcon.sprite = CoinCostSprite;
|
||
if (player.PlayerCoin < cost)
|
||
CostText.color = Color.red;
|
||
}
|
||
// 默认显示costBar(cost>0时),后续根据状态可能隐藏
|
||
CostBar.SetActive(cost > 0);
|
||
|
||
//Step #3 设置背景颜色,设置绑定点击执行
|
||
bool locked = false;
|
||
ClickButton.onClick.RemoveAllListeners();
|
||
Title.color = TextBlue;
|
||
TimeBar.SetActive(false);
|
||
if (cantType == ShowType.Cold)
|
||
{
|
||
var coldTime = player.GetHeroRevivePenalty(actionId.GiantType);
|
||
if (coldTime > 0)
|
||
{
|
||
TimeBar.SetActive(true);
|
||
TimeText.text = coldTime.ToString();
|
||
}
|
||
}
|
||
|
||
//如果目前无法执行
|
||
if (!action.CheckCan(param))
|
||
{
|
||
//如果是cityLevelUp,必须可执行
|
||
if (action.ActionId.ActionType == CommonActionType.CityLevelUpAction)
|
||
{
|
||
LogSystem.LogError($"CityLevelUpAction 不应该出现在无法执行的action circle里, Tyep :{cantType}");
|
||
BGCanvasGroup.alpha = 1f;
|
||
CircleBG.color = CircleYellow;
|
||
if (actionClickCallback != null)
|
||
{
|
||
ClickButton.onClick.AddListener(()=>
|
||
{
|
||
actionClickCallback.Invoke(actionId,param);
|
||
});
|
||
}
|
||
|
||
}
|
||
else
|
||
//如果是因为人口满了,灰圈 + 降低透明度
|
||
if (cantType == ShowType.Locked)
|
||
{
|
||
//BGCanvasGroup.alpha = 0.3f;
|
||
CircleBG.color = CircleGray;
|
||
CostBar.SetActive(false);
|
||
BG.sprite = circleGround ? GroundGrayBG : GrayBG;
|
||
locked = true;
|
||
Title.color = TextGrey;
|
||
}
|
||
//否则如果是在冷却时间
|
||
else if(cantType == ShowType.Cold)
|
||
{
|
||
CircleBG.color = CircleGray;
|
||
BG.sprite = circleGround ? GroundGrayBG : GrayBG;
|
||
locked = true;
|
||
Title.color = TextGrey;
|
||
|
||
if (cost > 0)
|
||
{
|
||
CostBar.SetActive(true);
|
||
CostText.text = cost.ToString();
|
||
CostText.color = player.PlayerCultureInfo.PlayerCulture < cost ? TextRed : TextBlue;
|
||
if (CostIcon != null && CultureCostSprite != null)
|
||
CostIcon.sprite = CultureCostSprite;
|
||
}
|
||
else
|
||
{
|
||
CostBar.SetActive(false);
|
||
}
|
||
}
|
||
//否则如果是因为钱/文化值不够
|
||
else if (cantType == ShowType.Cost
|
||
|| (isEinherjarCost
|
||
? HakureiEinherjarCounter.GetPlayerPoints(player) < cost
|
||
: isCultureCost
|
||
? player.PlayerCultureInfo.PlayerCulture < cost
|
||
: player.PlayerCoin < cost))
|
||
{
|
||
BGCanvasGroup.alpha = 1f;
|
||
CircleBG.color = CircleGray;
|
||
Title.color = TextRed;
|
||
}
|
||
//兜底:其他原因无法执行(如科技未解锁等),灰圈+隐藏cost
|
||
else
|
||
{
|
||
CircleBG.color = CircleGray;
|
||
CostBar.SetActive(false);
|
||
BG.sprite = circleGround ? GroundGrayBG : GrayBG;
|
||
locked = true;
|
||
Title.color = TextGrey;
|
||
}
|
||
|
||
|
||
}
|
||
//如果可以执行,那么绑定
|
||
else
|
||
{
|
||
BGCanvasGroup.alpha = 1f;
|
||
CircleBG.color = CircleYellow;
|
||
if (actionClickCallback != null)
|
||
{
|
||
ClickButton.onClick.AddListener(()=>
|
||
{
|
||
actionClickCallback.Invoke(actionId,param);
|
||
});
|
||
}
|
||
}
|
||
|
||
//Step #4 设置hint trigger
|
||
HintTrigger.DataProvider.HintDataType = HintDataType.ActionHintData;
|
||
HintTrigger.DataProvider.ActionIdData = actionId;
|
||
HintTrigger.DataProvider.locked = locked;
|
||
|
||
|
||
|
||
}
|
||
|
||
public void OnClose()
|
||
{
|
||
|
||
}
|
||
|
||
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 static bool TryGetCityLevelUpBigGuyUnitInfo(CommonActionId actionId, CommonActionParams param, out UnitTypeInfo unitInfo)
|
||
{
|
||
unitInfo = null;
|
||
if (actionId.ActionType != CommonActionType.CityLevelUpAction ||
|
||
actionId.CityLevelUpActionType != CityLevelUpActionType.BigGuy)
|
||
return false;
|
||
|
||
var player = param.PlayerData ?? param.CityData?.Player(param.MapData) ?? Main.MapData?.PlayerMap?.SelfPlayerData;
|
||
var fullType = CityLevelUpActionAction.GetBigGuyCityLevelUpUnitFullType(player);
|
||
return Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(fullType, out unitInfo);
|
||
}
|
||
|
||
private string GetTreasureOptionTitle(ActionOption option)
|
||
{
|
||
if (option == null) return "";
|
||
if (option.RewardType == TreasureActionRewardType.Coin)
|
||
return "+" + option.Value;
|
||
if (option.RewardType == TreasureActionRewardType.Culture)
|
||
return "+" + option.Value;
|
||
if (option.RewardType == TreasureActionRewardType.CityExp)
|
||
return "+" + option.Value;
|
||
if (option.RewardType == TreasureActionRewardType.Tech &&
|
||
Table.Instance.TechDataAssets.GetTechInfo(option.TechType, out var techInfo))
|
||
return MultilingualManager.Instance.GetMultilingualTextSafe(techInfo.TechName, MultilingualManager.Instance.CurrentType);
|
||
if (option.RewardType == TreasureActionRewardType.Unit &&
|
||
Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(option.UnitFullType, out var unitInfo))
|
||
return MultilingualManager.Instance.GetMultilingualTextSafe(unitInfo.Name, MultilingualManager.Instance.CurrentType);
|
||
|
||
return "";
|
||
}
|
||
|
||
private Sprite GetTreasureOptionSprite(ActionOption option, PlayerData player)
|
||
{
|
||
if (option == null) return null;
|
||
if (option.RewardType == TreasureActionRewardType.Coin)
|
||
return CoinCostSprite != null ? CoinCostSprite : ResourceCache.Instance.SpriteCache.GridVFXCoin;
|
||
if (option.RewardType == TreasureActionRewardType.Culture)
|
||
return CultureCostSprite != null ? CultureCostSprite : ResourceCache.Instance.SpriteCache.GridVFXLuxury;
|
||
if (option.RewardType == TreasureActionRewardType.CityExp)
|
||
return ResourceCache.Instance.SpriteCache.BubbleActionUpgrade;
|
||
if (option.RewardType == TreasureActionRewardType.Tech &&
|
||
Table.Instance.TechDataAssets.GetTechInfo(option.TechType, out var techInfo))
|
||
return techInfo.icon;
|
||
if (option.RewardType == TreasureActionRewardType.Unit &&
|
||
Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(option.UnitFullType, out var unitInfo))
|
||
{
|
||
if (player != null && Table.Instance.UnitTypeDataAssets.GetUnitSpriteByInfo(unitInfo, player, out var playerSprite))
|
||
return playerSprite;
|
||
return unitInfo.Sprite;
|
||
}
|
||
|
||
return ResourceCache.Instance.SpriteCache.BubbleActionTreasure;
|
||
}
|
||
}
|
||
}
|