210 lines
6.9 KiB
C#
210 lines
6.9 KiB
C#
using System.Collections.Generic;
|
|
using GeometryTD.CustomComponent;
|
|
using GeometryTD.CustomUtility;
|
|
using GeometryTD.Definition;
|
|
|
|
namespace GeometryTD.UI
|
|
{
|
|
public class RepoFormUseCase : IUIUseCase
|
|
{
|
|
private const int MaxParticipantCount = 4;
|
|
private BackpackInventoryData _fallbackInventory;
|
|
private readonly HashSet<long> _selectedSellItemIds = new HashSet<long>();
|
|
private RepoFormState _state = RepoFormState.Assemble;
|
|
|
|
public RepoFormRawData CreateInitialModel()
|
|
{
|
|
BackpackInventoryData sample = GameEntry.PlayerInventory != null
|
|
? GameEntry.PlayerInventory.GetInventorySnapshot()
|
|
: GetOrCreateFallbackInventory();
|
|
return new RepoFormRawData
|
|
{
|
|
Inventory = sample,
|
|
State = _state,
|
|
SelectedSellItemIds = BuildSelectedSellItemArray(),
|
|
SelectedSellItemCount = _selectedSellItemIds.Count,
|
|
SelectedSellTotalPrice = ResolveSelectedSellTotalPrice()
|
|
};
|
|
}
|
|
|
|
public RepoFormState State => _state;
|
|
|
|
public bool TryAssembleTower(long muzzleItemId, long bearingItemId, long baseItemId)
|
|
{
|
|
if (_state == RepoFormState.Sell)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (GameEntry.PlayerInventory == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return GameEntry.PlayerInventory.TryAssembleTower(
|
|
muzzleItemId,
|
|
bearingItemId,
|
|
baseItemId,
|
|
out _);
|
|
}
|
|
|
|
public ParticipantTowerAssignResult TryAddParticipantTower(long towerItemId)
|
|
{
|
|
if (_state == RepoFormState.Sell)
|
|
{
|
|
return new ParticipantTowerAssignResult
|
|
{
|
|
TowerInstanceId = towerItemId,
|
|
FailureReason = ParticipantTowerAssignFailureReason.ParticipantAreaFull
|
|
};
|
|
}
|
|
|
|
if (GameEntry.PlayerInventory == null)
|
|
{
|
|
BackpackInventoryData fallbackInventory = GetOrCreateFallbackInventory();
|
|
return InventoryParticipantUtility.TryAddParticipantTower(
|
|
fallbackInventory,
|
|
towerItemId,
|
|
MaxParticipantCount);
|
|
}
|
|
|
|
return GameEntry.PlayerInventory.TryAddParticipantTower(towerItemId, MaxParticipantCount);
|
|
}
|
|
|
|
public bool TryRemoveParticipantTower(long towerItemId)
|
|
{
|
|
if (_state == RepoFormState.Sell)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (GameEntry.PlayerInventory == null)
|
|
{
|
|
BackpackInventoryData fallbackInventory = GetOrCreateFallbackInventory();
|
|
return InventoryParticipantUtility.TryRemoveParticipantTower(
|
|
fallbackInventory,
|
|
towerItemId,
|
|
MaxParticipantCount);
|
|
}
|
|
|
|
return GameEntry.PlayerInventory.TryRemoveParticipantTower(towerItemId);
|
|
}
|
|
|
|
public RepoFormRawData EnterSellState()
|
|
{
|
|
_state = RepoFormState.Sell;
|
|
_selectedSellItemIds.Clear();
|
|
return CreateInitialModel();
|
|
}
|
|
|
|
public RepoFormRawData ExitSellState()
|
|
{
|
|
_state = RepoFormState.Assemble;
|
|
_selectedSellItemIds.Clear();
|
|
return CreateInitialModel();
|
|
}
|
|
|
|
public bool TryToggleSellSelection(
|
|
long itemId,
|
|
out RepoFormRawData rawData,
|
|
out PlayerInventorySaleFailureReason failureReason)
|
|
{
|
|
rawData = null;
|
|
failureReason = PlayerInventorySaleFailureReason.None;
|
|
if (_state != RepoFormState.Sell || itemId <= 0 || GameEntry.PlayerInventory == null)
|
|
{
|
|
failureReason = PlayerInventorySaleFailureReason.InvalidSelection;
|
|
return false;
|
|
}
|
|
|
|
if (_selectedSellItemIds.Contains(itemId))
|
|
{
|
|
_selectedSellItemIds.Remove(itemId);
|
|
rawData = CreateInitialModel();
|
|
return true;
|
|
}
|
|
|
|
if (!GameEntry.PlayerInventory.TryGetSaleCandidate(itemId, out PlayerInventorySaleCandidate candidate) ||
|
|
candidate == null)
|
|
{
|
|
failureReason = PlayerInventorySaleFailureReason.ItemNotFound;
|
|
return false;
|
|
}
|
|
|
|
if (!candidate.IsSellable)
|
|
{
|
|
failureReason = candidate.FailureReason;
|
|
return false;
|
|
}
|
|
|
|
_selectedSellItemIds.Add(itemId);
|
|
rawData = CreateInitialModel();
|
|
return true;
|
|
}
|
|
|
|
public bool TryConfirmSellSelection(out RepoFormRawData rawData, out PlayerInventorySaleResult result)
|
|
{
|
|
rawData = null;
|
|
result = null;
|
|
if (_state != RepoFormState.Sell || _selectedSellItemIds.Count <= 0 || GameEntry.PlayerInventory == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!GameEntry.PlayerInventory.TrySellItems(_selectedSellItemIds, out PlayerInventorySaleResult saleResult) ||
|
|
saleResult == null ||
|
|
!saleResult.IsSuccess)
|
|
{
|
|
result = saleResult;
|
|
rawData = CreateInitialModel();
|
|
return false;
|
|
}
|
|
|
|
_selectedSellItemIds.Clear();
|
|
result = saleResult;
|
|
rawData = CreateInitialModel();
|
|
return true;
|
|
}
|
|
|
|
private BackpackInventoryData GetOrCreateFallbackInventory()
|
|
{
|
|
_fallbackInventory ??= InventorySeedUtility.CreateSampleInventory();
|
|
InventoryParticipantUtility.NormalizeParticipantState(_fallbackInventory, MaxParticipantCount);
|
|
return _fallbackInventory;
|
|
}
|
|
|
|
private long[] BuildSelectedSellItemArray()
|
|
{
|
|
if (_selectedSellItemIds.Count <= 0)
|
|
{
|
|
return System.Array.Empty<long>();
|
|
}
|
|
|
|
long[] itemIds = new long[_selectedSellItemIds.Count];
|
|
_selectedSellItemIds.CopyTo(itemIds);
|
|
return itemIds;
|
|
}
|
|
|
|
private int ResolveSelectedSellTotalPrice()
|
|
{
|
|
if (_state != RepoFormState.Sell || _selectedSellItemIds.Count <= 0 || GameEntry.PlayerInventory == null)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int total = 0;
|
|
foreach (long itemId in _selectedSellItemIds)
|
|
{
|
|
if (GameEntry.PlayerInventory.TryGetSaleCandidate(itemId, out PlayerInventorySaleCandidate candidate) &&
|
|
candidate != null &&
|
|
candidate.IsSellable)
|
|
{
|
|
total += candidate.Price;
|
|
}
|
|
}
|
|
|
|
return total;
|
|
}
|
|
}
|
|
}
|