using System; using GeometryTD.CustomEvent; using GeometryTD.DataTable; using GeometryTD.Definition; using GameFramework.Event; using GeometryTD.CustomUtility; using UnityEngine; using UnityGameFramework.Runtime; namespace GeometryTD.UI { public class RewardSelectFormController : UIFormControllerCommonBase { private RewardSelectFormUseCase _useCase; protected override UIFormType UIFormTypeId => UIFormType.RewardSelectForm; protected override void RefreshUI(RewardSelectForm form, RewardSelectFormContext context) { form.RefreshUI(context); } protected override void SubscribeCustomEvents() { GameEntry.Event.Subscribe(RewardSelectItemSelectedEventArgs.EventId, OnRewardSelected); GameEntry.Event.Subscribe(RewardSelectRefreshEventArgs.EventId, OnRefreshClicked); GameEntry.Event.Subscribe(RewardSelectGiveUpEventArgs.EventId, OnGiveUpClicked); } protected override void UnsubscribeCustomEvents() { GameEntry.Event.Unsubscribe(RewardSelectItemSelectedEventArgs.EventId, OnRewardSelected); GameEntry.Event.Unsubscribe(RewardSelectRefreshEventArgs.EventId, OnRefreshClicked); GameEntry.Event.Unsubscribe(RewardSelectGiveUpEventArgs.EventId, OnGiveUpClicked); } public override int? OpenUI(object userData = null) { if (userData is RewardSelectFormContext context) { return OpenUIInternal(context); } if (userData is RewardSelectFormRawData rawDataFromUserData) { return OpenUI(rawDataFromUserData); } if (userData != null) { Log.Warning("RewardSelectFormController.OpenUI() userData type is invalid."); return null; } if (_useCase == null) { Log.Error("RewardSelectFormController.OpenUI() useCase is null."); return null; } RewardSelectFormRawData rawData = _useCase.CreateInitialModel(); return OpenUI(rawData); } public int? OpenUI(RewardSelectFormRawData rawData) { RewardSelectFormContext context = BuildContext(rawData); return OpenUIInternal(context); } public override void BindUseCase(IUIUseCase useCase) { if (!(useCase is RewardSelectFormUseCase rewardSelectUseCase)) { Log.Error("RewardSelectFormController.BindUseCase() useCase is invalid."); return; } _useCase = rewardSelectUseCase; } private static RewardSelectFormContext BuildContext(RewardSelectFormRawData rawData) { if (rawData == null) { return null; } return new RewardSelectFormContext { TipText = string.IsNullOrWhiteSpace(rawData.TipText) ? "Select one reward" : rawData.TipText, RefreshButtonText = BuildRefreshButtonText(rawData.RefreshCost, rawData.CanRefresh), CanRefresh = rawData.CanRefresh, CanGiveUp = rawData.CanGiveUp, RewardItems = BuildRewardItemContexts(rawData.RewardItems) }; } private static string BuildRefreshButtonText(int refreshCost, bool canRefresh) { if (!canRefresh) { return "Refreshed"; } if (refreshCost <= 0) { return "Refresh"; } return $"Refresh -{refreshCost}"; } private static RewardItemContext[] BuildRewardItemContexts(RewardSelectItemRawData[] rawItems) { if (rawItems == null || rawItems.Length <= 0) { return System.Array.Empty(); } RewardItemContext[] contexts = new RewardItemContext[rawItems.Length]; for (int i = 0; i < rawItems.Length; i++) { RewardSelectItemRawData rawItem = rawItems[i]; if (rawItem == null) { continue; } contexts[i] = new RewardItemContext { Index = i, RewardId = rawItem.RewardId, IconArea = new IconAreaContext { ComponentSlotType = rawItem.SlotType, Icon = rawItem.Icon, Rarity = rawItem.Rarity, Color = ResolveIconColor(rawItem) }, Title = rawItem.Title ?? string.Empty, TypeText = ResolveTypeText(rawItem), Description = rawItem.Description ?? string.Empty, Tags = BuildTagContexts(rawItem.Tags), IsSelectable = rawItem.IsSelectable, UserData = rawItem.UserData }; } return contexts; } private static Color ResolveIconColor(RewardSelectItemRawData rawItem) { if (rawItem?.SourceItem == null) { return Color.white; } return IconColorGenerator.GenerateForComponent(rawItem.SourceItem); } private static string ResolveTypeText(RewardSelectItemRawData rawItem) { if (!string.IsNullOrWhiteSpace(rawItem.TypeText)) { return rawItem.TypeText; } return rawItem.SlotType switch { TowerCompSlotType.Muzzle => "Muzzle Component", TowerCompSlotType.Bearing => "Bearing Component", TowerCompSlotType.Base => "Base Component", TowerCompSlotType.Accessory => "Accessory", _ => "Component" }; } private static TagItemContext[] BuildTagContexts(TagType[] tags) { if (tags == null || tags.Length <= 0) { return System.Array.Empty(); } TagItemContext[] contexts = new TagItemContext[tags.Length]; for (int i = 0; i < tags.Length; i++) { TagType tagType = tags[i]; contexts[i] = new TagItemContext { TagName = ResolveTagName(tagType) }; } return contexts; } private static string ResolveTagName(TagType tagType) { if (tagType == TagType.None) { return string.Empty; } var tagTable = GameEntry.DataTable.GetDataTable(); if (tagTable != null) { DRTag tagRow = tagTable.GetDataRow((int)tagType); if (tagRow != null && !string.IsNullOrWhiteSpace(tagRow.Name)) { return tagRow.Name; } } return tagType.ToString(); } private void OnRewardSelected(object sender, GameEventArgs e) { if (!IsEventFromCurrentForm(sender) || !(e is RewardSelectItemSelectedEventArgs args)) { return; } if (_useCase == null) { return; } RewardSelectFormRawData nextRawData = _useCase.SelectReward(args.SelectedIndex); if (nextRawData == null) { CloseUI(); return; } OpenUI(nextRawData); } private void OnRefreshClicked(object sender, GameEventArgs e) { if (!IsEventFromCurrentForm(sender) || !(e is RewardSelectRefreshEventArgs)) { return; } if (_useCase == null) { return; } RewardSelectFormRawData nextRawData = _useCase.TryRefresh(); if (nextRawData == null) { CloseUI(); return; } OpenUI(nextRawData); } private void OnGiveUpClicked(object sender, GameEventArgs e) { if (!IsEventFromCurrentForm(sender) || !(e is RewardSelectGiveUpEventArgs)) { return; } if (_useCase == null) { return; } if (_useCase.TryGiveUp()) { CloseUI(); } } private bool IsEventFromCurrentForm(object sender) { if (Form == null) { return false; } if (ReferenceEquals(sender, Form)) { return true; } if (sender is Component component) { RewardSelectForm ownerForm = component.GetComponentInParent(); return ownerForm == Form; } return false; } } }