276 lines
8.8 KiB
C#
276 lines
8.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using GeometryTD.CustomUtility;
|
|
using GeometryTD.Definition;
|
|
using UnityEngine;
|
|
|
|
namespace GeometryTD.CustomComponent
|
|
{
|
|
internal struct PlayerInventoryMergeSummary
|
|
{
|
|
public int GainedGold;
|
|
public int GainedMuzzleCount;
|
|
public int GainedBearingCount;
|
|
public int GainedBaseCount;
|
|
public int GainedTowerCount;
|
|
|
|
public bool HasAnyGain =>
|
|
GainedGold > 0 || GainedMuzzleCount > 0 || GainedBearingCount > 0 || GainedBaseCount > 0 ||
|
|
GainedTowerCount > 0;
|
|
}
|
|
|
|
internal sealed class PlayerInventoryState
|
|
{
|
|
public BackpackInventoryData Inventory = new BackpackInventoryData();
|
|
public long NextInstanceId = 1;
|
|
public bool IsInitialized;
|
|
}
|
|
|
|
internal sealed class PlayerInventoryQueryModel
|
|
{
|
|
private readonly PlayerInventoryState _state;
|
|
|
|
public PlayerInventoryQueryModel(PlayerInventoryState state)
|
|
{
|
|
_state = state;
|
|
}
|
|
|
|
public BackpackInventoryData Inventory => _state.Inventory;
|
|
public bool IsInitialized => _state.IsInitialized;
|
|
public int Gold => _state.Inventory.Gold;
|
|
|
|
public BackpackInventoryData GetSnapshot()
|
|
{
|
|
return InventoryCloneUtility.CloneInventory(_state.Inventory);
|
|
}
|
|
|
|
public bool TryGetTowerById(long towerInstanceId, out TowerItemData tower)
|
|
{
|
|
return InventoryParticipantUtility.TryGetTowerById(_state.Inventory, towerInstanceId, out tower);
|
|
}
|
|
|
|
public bool TryGetComponentById<TComp>(List<TComp> components, long instanceId, out TComp result)
|
|
where TComp : TowerCompItemData
|
|
{
|
|
result = null;
|
|
if (components == null || instanceId <= 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
for (int i = 0; i < components.Count; i++)
|
|
{
|
|
TComp component = components[i];
|
|
if (component != null && component.InstanceId == instanceId)
|
|
{
|
|
result = component;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
internal sealed class PlayerInventoryCommandModel
|
|
{
|
|
private readonly PlayerInventoryState _state;
|
|
|
|
public PlayerInventoryCommandModel(PlayerInventoryState state)
|
|
{
|
|
_state = state;
|
|
}
|
|
|
|
public void Initialize(BackpackInventoryData sourceInventory, int maxParticipantTowerCount)
|
|
{
|
|
_state.Inventory = InventoryCloneUtility.CloneInventory(sourceInventory);
|
|
InventoryParticipantUtility.NormalizeParticipantState(_state.Inventory, maxParticipantTowerCount);
|
|
RebuildNextInstanceId();
|
|
_state.IsInitialized = true;
|
|
}
|
|
|
|
public void ReplaceInventorySnapshot(BackpackInventoryData sourceInventory, int maxParticipantTowerCount)
|
|
{
|
|
Initialize(sourceInventory, maxParticipantTowerCount);
|
|
}
|
|
|
|
public PlayerInventoryMergeSummary MergeInventory(BackpackInventoryData gainedInventory)
|
|
{
|
|
PlayerInventoryMergeSummary summary = default;
|
|
if (gainedInventory == null)
|
|
{
|
|
return summary;
|
|
}
|
|
|
|
summary.GainedGold = Mathf.Max(0, gainedInventory.Gold);
|
|
if (summary.GainedGold > 0)
|
|
{
|
|
_state.Inventory.Gold += summary.GainedGold;
|
|
}
|
|
|
|
if (gainedInventory.MuzzleComponents != null)
|
|
{
|
|
for (int i = 0; i < gainedInventory.MuzzleComponents.Count; i++)
|
|
{
|
|
MuzzleCompItemData source = gainedInventory.MuzzleComponents[i];
|
|
if (source == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
MuzzleCompItemData cloned = InventoryCloneUtility.CloneMuzzleComp(source);
|
|
cloned.InstanceId = AllocateInstanceId();
|
|
_state.Inventory.MuzzleComponents.Add(cloned);
|
|
summary.GainedMuzzleCount++;
|
|
}
|
|
}
|
|
|
|
if (gainedInventory.BearingComponents != null)
|
|
{
|
|
for (int i = 0; i < gainedInventory.BearingComponents.Count; i++)
|
|
{
|
|
BearingCompItemData source = gainedInventory.BearingComponents[i];
|
|
if (source == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
BearingCompItemData cloned = InventoryCloneUtility.CloneBearingComp(source);
|
|
cloned.InstanceId = AllocateInstanceId();
|
|
_state.Inventory.BearingComponents.Add(cloned);
|
|
summary.GainedBearingCount++;
|
|
}
|
|
}
|
|
|
|
if (gainedInventory.BaseComponents != null)
|
|
{
|
|
for (int i = 0; i < gainedInventory.BaseComponents.Count; i++)
|
|
{
|
|
BaseCompItemData source = gainedInventory.BaseComponents[i];
|
|
if (source == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
BaseCompItemData cloned = InventoryCloneUtility.CloneBaseComp(source);
|
|
cloned.InstanceId = AllocateInstanceId();
|
|
_state.Inventory.BaseComponents.Add(cloned);
|
|
summary.GainedBaseCount++;
|
|
}
|
|
}
|
|
|
|
if (gainedInventory.Towers != null)
|
|
{
|
|
for (int i = 0; i < gainedInventory.Towers.Count; i++)
|
|
{
|
|
TowerItemData source = gainedInventory.Towers[i];
|
|
if (source == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
TowerItemData cloned = InventoryCloneUtility.CloneTower(source);
|
|
cloned.InstanceId = AllocateInstanceId();
|
|
_state.Inventory.Towers.Add(cloned);
|
|
summary.GainedTowerCount++;
|
|
}
|
|
}
|
|
|
|
return summary;
|
|
}
|
|
|
|
public bool TryConsumeGold(int costGold)
|
|
{
|
|
int resolvedCost = Mathf.Max(0, costGold);
|
|
if (resolvedCost <= 0)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (_state.Inventory.Gold < resolvedCost)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
_state.Inventory.Gold -= resolvedCost;
|
|
return true;
|
|
}
|
|
|
|
public void AddGold(int gainGold)
|
|
{
|
|
int resolvedGain = Mathf.Max(0, gainGold);
|
|
if (resolvedGain <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_state.Inventory.Gold += resolvedGain;
|
|
}
|
|
|
|
public long AllocateInstanceId()
|
|
{
|
|
if (_state.NextInstanceId < 1)
|
|
{
|
|
_state.NextInstanceId = 1;
|
|
}
|
|
|
|
return _state.NextInstanceId++;
|
|
}
|
|
|
|
private void RebuildNextInstanceId()
|
|
{
|
|
long maxInstanceId = 0;
|
|
BackpackInventoryData inventory = _state.Inventory;
|
|
if (inventory.Towers != null)
|
|
{
|
|
for (int i = 0; i < inventory.Towers.Count; i++)
|
|
{
|
|
TowerItemData item = inventory.Towers[i];
|
|
if (item != null)
|
|
{
|
|
maxInstanceId = Math.Max(maxInstanceId, item.InstanceId);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (inventory.MuzzleComponents != null)
|
|
{
|
|
for (int i = 0; i < inventory.MuzzleComponents.Count; i++)
|
|
{
|
|
MuzzleCompItemData item = inventory.MuzzleComponents[i];
|
|
if (item != null)
|
|
{
|
|
maxInstanceId = Math.Max(maxInstanceId, item.InstanceId);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (inventory.BearingComponents != null)
|
|
{
|
|
for (int i = 0; i < inventory.BearingComponents.Count; i++)
|
|
{
|
|
BearingCompItemData item = inventory.BearingComponents[i];
|
|
if (item != null)
|
|
{
|
|
maxInstanceId = Math.Max(maxInstanceId, item.InstanceId);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (inventory.BaseComponents != null)
|
|
{
|
|
for (int i = 0; i < inventory.BaseComponents.Count; i++)
|
|
{
|
|
BaseCompItemData item = inventory.BaseComponents[i];
|
|
if (item != null)
|
|
{
|
|
maxInstanceId = Math.Max(maxInstanceId, item.InstanceId);
|
|
}
|
|
}
|
|
}
|
|
|
|
_state.NextInstanceId = Math.Max(1, maxInstanceId + 1);
|
|
}
|
|
}
|
|
}
|