geometry-tower-defense/Assets/GameMain/Scripts/UI/General/Controller/RewardSelectFormController.cs

304 lines
9.1 KiB
C#

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<RewardSelectFormContext, RewardSelectForm>
{
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>();
}
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>();
}
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<DRTag>();
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<RewardSelectForm>();
return ownerForm == Form;
}
return false;
}
}
}