234 lines
6.7 KiB
C#
234 lines
6.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using GeometryTD.Definition;
|
|
using UnityEngine;
|
|
|
|
namespace GeometryTD.UI
|
|
{
|
|
public class RewardSelectFormUseCase : IUIUseCase
|
|
{
|
|
private readonly List<RewardSelectItemRawData> _rewardPool = new List<RewardSelectItemRawData>();
|
|
|
|
private RewardSelectFormRawData _currentModel;
|
|
private Action<RewardSelectItemRawData> _onRewardSelected;
|
|
private Action _onGiveUp;
|
|
|
|
private int _displayCount = 3;
|
|
private int _refreshCost;
|
|
private bool _allowRefreshOnce = true;
|
|
private bool _allowGiveUp = true;
|
|
private bool _hasRefreshed;
|
|
private int _selectionOffset;
|
|
private string _tipText = "Select one reward";
|
|
|
|
public void ConfigureRewardPool(
|
|
IReadOnlyList<RewardSelectItemRawData> rewardPool,
|
|
int displayCount = 3,
|
|
int refreshCost = 0,
|
|
bool allowRefreshOnce = true,
|
|
bool allowGiveUp = true,
|
|
string tipText = null)
|
|
{
|
|
_rewardPool.Clear();
|
|
if (rewardPool != null)
|
|
{
|
|
foreach (var item in rewardPool)
|
|
{
|
|
if (item == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
_rewardPool.Add(item);
|
|
}
|
|
}
|
|
|
|
_displayCount = Mathf.Max(1, displayCount);
|
|
_refreshCost = Mathf.Max(0, refreshCost);
|
|
_allowRefreshOnce = allowRefreshOnce;
|
|
_allowGiveUp = allowGiveUp;
|
|
_tipText = string.IsNullOrWhiteSpace(tipText) ? "Select one reward" : tipText;
|
|
_hasRefreshed = false;
|
|
_selectionOffset = 0;
|
|
_currentModel = null;
|
|
}
|
|
|
|
public void ConfigureRewardCandidates(
|
|
IReadOnlyList<TowerCompItemData> rewardCandidates,
|
|
int displayCount = 3,
|
|
int refreshCost = 0,
|
|
bool allowRefreshOnce = true,
|
|
bool allowGiveUp = true,
|
|
string tipText = null)
|
|
{
|
|
_rewardPool.Clear();
|
|
if (rewardCandidates != null)
|
|
{
|
|
foreach (var item in rewardCandidates)
|
|
{
|
|
if (item == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
_rewardPool.Add(RewardSelectItemRawDataBuilder.Build(item));
|
|
}
|
|
}
|
|
|
|
_displayCount = Mathf.Max(1, displayCount);
|
|
_refreshCost = Mathf.Max(0, refreshCost);
|
|
_allowRefreshOnce = allowRefreshOnce;
|
|
_allowGiveUp = allowGiveUp;
|
|
_tipText = string.IsNullOrWhiteSpace(tipText) ? "Select one reward" : tipText;
|
|
_hasRefreshed = false;
|
|
_selectionOffset = 0;
|
|
_currentModel = null;
|
|
}
|
|
|
|
public void SetCallbacks(Action<RewardSelectItemRawData> onRewardSelected, Action onGiveUp = null)
|
|
{
|
|
_onRewardSelected = onRewardSelected;
|
|
_onGiveUp = onGiveUp;
|
|
}
|
|
|
|
public RewardSelectFormRawData CreateInitialModel()
|
|
{
|
|
_hasRefreshed = false;
|
|
_currentModel = BuildModel();
|
|
return _currentModel;
|
|
}
|
|
|
|
public RewardSelectFormRawData TryRefresh()
|
|
{
|
|
if (_currentModel == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (!CanRefreshInternal())
|
|
{
|
|
return _currentModel;
|
|
}
|
|
|
|
if (!TryConsumeRefreshCost())
|
|
{
|
|
_currentModel.CanRefresh = false;
|
|
return _currentModel;
|
|
}
|
|
|
|
_hasRefreshed = true;
|
|
if (_rewardPool.Count > 0)
|
|
{
|
|
_selectionOffset = (_selectionOffset + _displayCount) % _rewardPool.Count;
|
|
}
|
|
|
|
_currentModel = BuildModel();
|
|
return _currentModel;
|
|
}
|
|
|
|
public RewardSelectFormRawData SelectReward(int selectedIndex)
|
|
{
|
|
if (_currentModel?.RewardItems == null || _currentModel.RewardItems.Length <= 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (selectedIndex < 0 || selectedIndex >= _currentModel.RewardItems.Length)
|
|
{
|
|
return _currentModel;
|
|
}
|
|
|
|
RewardSelectItemRawData selectedReward = _currentModel.RewardItems[selectedIndex];
|
|
_onRewardSelected?.Invoke(selectedReward);
|
|
|
|
_currentModel = null;
|
|
return null;
|
|
}
|
|
|
|
public bool TryGiveUp()
|
|
{
|
|
if (!_allowGiveUp)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
_onGiveUp?.Invoke();
|
|
_currentModel = null;
|
|
return true;
|
|
}
|
|
|
|
private RewardSelectFormRawData BuildModel()
|
|
{
|
|
RewardSelectItemRawData[] selectedRewards = SelectRewards();
|
|
|
|
return new RewardSelectFormRawData
|
|
{
|
|
TipText = _tipText,
|
|
RewardItems = selectedRewards,
|
|
RefreshCost = _refreshCost,
|
|
CanRefresh = selectedRewards.Length > 0 && CanRefreshInternal(),
|
|
CanGiveUp = _allowGiveUp
|
|
};
|
|
}
|
|
|
|
private RewardSelectItemRawData[] SelectRewards()
|
|
{
|
|
if (_rewardPool.Count <= 0)
|
|
{
|
|
return Array.Empty<RewardSelectItemRawData>();
|
|
}
|
|
|
|
int finalCount = Mathf.Clamp(_displayCount, 1, _rewardPool.Count);
|
|
RewardSelectItemRawData[] results = new RewardSelectItemRawData[finalCount];
|
|
for (int i = 0; i < finalCount; i++)
|
|
{
|
|
int sourceIndex = (_selectionOffset + i) % _rewardPool.Count;
|
|
RewardSelectItemRawData source = _rewardPool[sourceIndex];
|
|
results[i] = source;
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
private bool CanRefreshInternal()
|
|
{
|
|
if (!_allowRefreshOnce || _hasRefreshed)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return CanPayRefreshCost();
|
|
}
|
|
|
|
private bool CanPayRefreshCost()
|
|
{
|
|
if (_refreshCost <= 0)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (GameEntry.PlayerInventory == null)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return GameEntry.PlayerInventory.Gold >= _refreshCost;
|
|
}
|
|
|
|
private bool TryConsumeRefreshCost()
|
|
{
|
|
if (_refreshCost <= 0)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (GameEntry.PlayerInventory == null)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return GameEntry.PlayerInventory.TryConsumeGold(_refreshCost);
|
|
}
|
|
}
|
|
}
|