306 lines
9.0 KiB
C#
306 lines
9.0 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
namespace GeometryTD.UI
|
|
{
|
|
public class CombatSelectFormUseCase : IUIUseCase
|
|
{
|
|
private const int BuildOptionCount = 4;
|
|
|
|
private readonly Option[] _buildOptions = new Option[BuildOptionCount];
|
|
private readonly Option _upgradeOption = new Option(CombatSelectActionType.UpgradeTower, 0, true);
|
|
private readonly Option _destroyOption = new Option(CombatSelectActionType.DestroyTower, 0, false);
|
|
|
|
private Func<int> _coinProvider;
|
|
private bool _isVisible;
|
|
private CombatSelectDisplayMode _displayMode = CombatSelectDisplayMode.Hidden;
|
|
private Vector2 _contentPosition;
|
|
|
|
public CombatSelectFormUseCase()
|
|
{
|
|
_coinProvider = DefaultCoinProvider;
|
|
|
|
for (int i = 0; i < BuildOptionCount; i++)
|
|
{
|
|
_buildOptions[i] = new Option(CombatSelectActionType.BuildTower, i, true);
|
|
}
|
|
}
|
|
|
|
public CombatSelectFormRawData CreateInitialModel()
|
|
{
|
|
return BuildModel();
|
|
}
|
|
|
|
public CombatSelectFormRawData TryRefresh()
|
|
{
|
|
return BuildModel();
|
|
}
|
|
|
|
public void SetCoinProvider(Func<int> coinProvider)
|
|
{
|
|
_coinProvider = coinProvider ?? DefaultCoinProvider;
|
|
}
|
|
|
|
public void SetBuildAction(int buildIndex, Func<bool> buildAction, int cost, Sprite icon = null)
|
|
{
|
|
if (buildIndex < 0 || buildIndex >= _buildOptions.Length)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Option option = _buildOptions[buildIndex];
|
|
option.Action = buildAction;
|
|
option.Price = Mathf.Max(0, cost);
|
|
option.Icon = icon;
|
|
option.IsGain = false;
|
|
option.IsVisible = true;
|
|
}
|
|
|
|
public void SetBuildAction(int buildIndex, Action buildAction, int cost, Sprite icon = null)
|
|
{
|
|
if (buildAction == null)
|
|
{
|
|
SetBuildAction(buildIndex, (Func<bool>)null, cost, icon);
|
|
return;
|
|
}
|
|
|
|
SetBuildAction(
|
|
buildIndex,
|
|
() =>
|
|
{
|
|
buildAction.Invoke();
|
|
return true;
|
|
},
|
|
cost,
|
|
icon);
|
|
}
|
|
|
|
public void SetUpgradeAction(Func<bool> upgradeAction, int cost, Sprite icon = null)
|
|
{
|
|
_upgradeOption.Action = upgradeAction;
|
|
_upgradeOption.Price = Mathf.Max(0, cost);
|
|
_upgradeOption.Icon = icon;
|
|
_upgradeOption.IsGain = false;
|
|
_upgradeOption.IsVisible = true;
|
|
}
|
|
|
|
public void SetUpgradeAction(Action upgradeAction, int cost, Sprite icon = null)
|
|
{
|
|
if (upgradeAction == null)
|
|
{
|
|
SetUpgradeAction((Func<bool>)null, cost, icon);
|
|
return;
|
|
}
|
|
|
|
SetUpgradeAction(
|
|
() =>
|
|
{
|
|
upgradeAction.Invoke();
|
|
return true;
|
|
},
|
|
cost,
|
|
icon);
|
|
}
|
|
|
|
public void SetDestroyAction(Func<bool> destroyAction, int gain, Sprite icon = null)
|
|
{
|
|
_destroyOption.Action = destroyAction;
|
|
_destroyOption.Price = Mathf.Max(0, gain);
|
|
_destroyOption.Icon = icon;
|
|
_destroyOption.IsGain = true;
|
|
_destroyOption.IsVisible = true;
|
|
}
|
|
|
|
public void SetDestroyAction(Action destroyAction, int gain, Sprite icon = null)
|
|
{
|
|
if (destroyAction == null)
|
|
{
|
|
SetDestroyAction((Func<bool>)null, gain, icon);
|
|
return;
|
|
}
|
|
|
|
SetDestroyAction(
|
|
() =>
|
|
{
|
|
destroyAction.Invoke();
|
|
return true;
|
|
},
|
|
gain,
|
|
icon);
|
|
}
|
|
|
|
public void SetUpgradePrice(int cost)
|
|
{
|
|
_upgradeOption.Price = Mathf.Max(0, cost);
|
|
}
|
|
|
|
public void SetUpgradeVisible(bool visible)
|
|
{
|
|
_upgradeOption.IsVisible = visible;
|
|
}
|
|
|
|
public void SetDestroyGain(int gain)
|
|
{
|
|
_destroyOption.Price = Mathf.Max(0, gain);
|
|
_destroyOption.IsGain = true;
|
|
}
|
|
|
|
public void ShowForFoundation(Vector2 contentPosition)
|
|
{
|
|
_contentPosition = contentPosition;
|
|
_displayMode = CombatSelectDisplayMode.Build;
|
|
_isVisible = true;
|
|
}
|
|
|
|
public void ShowForTower(Vector2 contentPosition)
|
|
{
|
|
_contentPosition = contentPosition;
|
|
_displayMode = CombatSelectDisplayMode.Func;
|
|
_isVisible = true;
|
|
}
|
|
|
|
public void Hide()
|
|
{
|
|
_isVisible = false;
|
|
_displayMode = CombatSelectDisplayMode.Hidden;
|
|
}
|
|
|
|
public bool TryExecuteAction(CombatSelectActionType actionType, int actionIndex)
|
|
{
|
|
if (!_isVisible)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Option option = GetOption(actionType, actionIndex);
|
|
if (option == null || !option.IsVisible)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
int currentCoin = Mathf.Max(0, _coinProvider != null ? _coinProvider.Invoke() : 0);
|
|
if (!CanExecute(option, currentCoin))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (option.Action == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool result = option.Action.Invoke();
|
|
if (result)
|
|
{
|
|
Hide();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private CombatSelectFormRawData BuildModel()
|
|
{
|
|
int currentCoin = Mathf.Max(0, _coinProvider != null ? _coinProvider.Invoke() : 0);
|
|
TowerSelectItemRawData[] buildItems = new TowerSelectItemRawData[_buildOptions.Length];
|
|
for (int i = 0; i < _buildOptions.Length; i++)
|
|
{
|
|
buildItems[i] = BuildOptionRawData(_buildOptions[i], currentCoin);
|
|
}
|
|
|
|
return new CombatSelectFormRawData
|
|
{
|
|
IsVisible = _isVisible,
|
|
ContentPosition = _contentPosition,
|
|
DisplayMode = _displayMode,
|
|
BuildItems = buildItems,
|
|
UpgradeItem = BuildOptionRawData(_upgradeOption, currentCoin),
|
|
DestroyItem = BuildOptionRawData(_destroyOption, currentCoin)
|
|
};
|
|
}
|
|
|
|
private Option GetOption(CombatSelectActionType actionType, int actionIndex)
|
|
{
|
|
switch (actionType)
|
|
{
|
|
case CombatSelectActionType.BuildTower:
|
|
if (actionIndex < 0 || actionIndex >= _buildOptions.Length)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return _buildOptions[actionIndex];
|
|
case CombatSelectActionType.UpgradeTower:
|
|
return _upgradeOption;
|
|
case CombatSelectActionType.DestroyTower:
|
|
return _destroyOption;
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private static int DefaultCoinProvider()
|
|
{
|
|
if (GameEntry.CombatNode == null)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return Mathf.Max(0, GameEntry.CombatNode.CurrentCoin);
|
|
}
|
|
|
|
private static bool CanExecute(Option option, int currentCoin)
|
|
{
|
|
if (option == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (option.RequiresAffordable && currentCoin < option.Price)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private static TowerSelectItemRawData BuildOptionRawData(Option option, int currentCoin)
|
|
{
|
|
if (option == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return new TowerSelectItemRawData
|
|
{
|
|
Icon = option.Icon,
|
|
Price = option.Price,
|
|
IsGain = option.IsGain,
|
|
IsVisible = option.IsVisible,
|
|
IsInteractable = option.Action != null && CanExecute(option, currentCoin),
|
|
ActionType = option.ActionType,
|
|
ActionIndex = option.ActionIndex
|
|
};
|
|
}
|
|
|
|
private sealed class Option
|
|
{
|
|
public readonly CombatSelectActionType ActionType;
|
|
public readonly int ActionIndex;
|
|
public readonly bool RequiresAffordable;
|
|
|
|
public int Price;
|
|
public bool IsGain;
|
|
public bool IsVisible = true;
|
|
public Sprite Icon;
|
|
public Func<bool> Action;
|
|
|
|
public Option(CombatSelectActionType actionType, int actionIndex, bool requiresAffordable)
|
|
{
|
|
ActionType = actionType;
|
|
ActionIndex = actionIndex;
|
|
RequiresAffordable = requiresAffordable;
|
|
}
|
|
}
|
|
}
|
|
}
|