409 lines
13 KiB
C#
409 lines
13 KiB
C#
using System;
|
|
using GeometryTD.Definition;
|
|
using GeometryTD.UI;
|
|
using UnityEngine;
|
|
using UnityGameFramework.Runtime;
|
|
|
|
namespace GeometryTD.CustomComponent
|
|
{
|
|
public class PlayerInventoryComponent : GameFrameworkComponent
|
|
{
|
|
private BackpackInventoryData _inventory = new BackpackInventoryData();
|
|
private long _nextInstanceId = 1;
|
|
private bool _initialized;
|
|
|
|
public int Gold
|
|
{
|
|
get
|
|
{
|
|
EnsureInitialized();
|
|
return _inventory.Gold;
|
|
}
|
|
}
|
|
|
|
public void OnInit()
|
|
{
|
|
_inventory = CloneInventory(RepoFormUseCase.SampleInventory());
|
|
RebuildNextInstanceId();
|
|
_initialized = true;
|
|
Log.Info(
|
|
"PlayerInventory initialized. Gold={0}, Tower={1}, Muzzle={2}, Bearing={3}, Base={4}.",
|
|
_inventory.Gold,
|
|
_inventory.Towers.Count,
|
|
_inventory.MuzzleComponents.Count,
|
|
_inventory.BearingComponents.Count,
|
|
_inventory.BaseComponents.Count);
|
|
}
|
|
|
|
public BackpackInventoryData GetInventorySnapshot()
|
|
{
|
|
EnsureInitialized();
|
|
return CloneInventory(_inventory);
|
|
}
|
|
|
|
public void MergeInventory(BackpackInventoryData gainedInventory)
|
|
{
|
|
EnsureInitialized();
|
|
if (gainedInventory == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int gainedGold = Mathf.Max(0, gainedInventory.Gold);
|
|
int gainedMuzzleCount = 0;
|
|
int gainedBearingCount = 0;
|
|
int gainedBaseCount = 0;
|
|
int gainedTowerCount = 0;
|
|
|
|
if (gainedGold > 0)
|
|
{
|
|
_inventory.Gold += 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 = CloneMuzzleComp(source);
|
|
cloned.InstanceId = AllocateInstanceId();
|
|
_inventory.MuzzleComponents.Add(cloned);
|
|
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 = CloneBearingComp(source);
|
|
cloned.InstanceId = AllocateInstanceId();
|
|
_inventory.BearingComponents.Add(cloned);
|
|
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 = CloneBaseComp(source);
|
|
cloned.InstanceId = AllocateInstanceId();
|
|
_inventory.BaseComponents.Add(cloned);
|
|
gainedBaseCount++;
|
|
}
|
|
}
|
|
|
|
if (gainedInventory.Towers != null)
|
|
{
|
|
for (int i = 0; i < gainedInventory.Towers.Count; i++)
|
|
{
|
|
DefenseTowerItemData source = gainedInventory.Towers[i];
|
|
if (source == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
DefenseTowerItemData cloned = CloneTower(source);
|
|
cloned.InstanceId = AllocateInstanceId();
|
|
_inventory.Towers.Add(cloned);
|
|
gainedTowerCount++;
|
|
}
|
|
}
|
|
|
|
if (gainedGold > 0 || gainedMuzzleCount > 0 || gainedBearingCount > 0 || gainedBaseCount > 0 ||
|
|
gainedTowerCount > 0)
|
|
{
|
|
Log.Info(
|
|
"PlayerInventory merged reward. Gold+{0}, Tower+{1}, Muzzle+{2}, Bearing+{3}, Base+{4}.",
|
|
gainedGold,
|
|
gainedTowerCount,
|
|
gainedMuzzleCount,
|
|
gainedBearingCount,
|
|
gainedBaseCount);
|
|
}
|
|
}
|
|
|
|
public bool TryConsumeGold(int costGold)
|
|
{
|
|
EnsureInitialized();
|
|
int resolvedCost = Mathf.Max(0, costGold);
|
|
if (resolvedCost <= 0)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (_inventory.Gold < resolvedCost)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
_inventory.Gold -= resolvedCost;
|
|
return true;
|
|
}
|
|
|
|
public void AddGold(int gainGold)
|
|
{
|
|
EnsureInitialized();
|
|
int resolvedGain = Mathf.Max(0, gainGold);
|
|
if (resolvedGain <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_inventory.Gold += resolvedGain;
|
|
}
|
|
|
|
private void EnsureInitialized()
|
|
{
|
|
if (_initialized)
|
|
{
|
|
return;
|
|
}
|
|
|
|
OnInit();
|
|
}
|
|
|
|
private long AllocateInstanceId()
|
|
{
|
|
if (_nextInstanceId < 1)
|
|
{
|
|
_nextInstanceId = 1;
|
|
}
|
|
|
|
return _nextInstanceId++;
|
|
}
|
|
|
|
private void RebuildNextInstanceId()
|
|
{
|
|
long maxInstanceId = 0;
|
|
if (_inventory.Towers != null)
|
|
{
|
|
for (int i = 0; i < _inventory.Towers.Count; i++)
|
|
{
|
|
DefenseTowerItemData 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);
|
|
}
|
|
}
|
|
}
|
|
|
|
_nextInstanceId = Math.Max(1, maxInstanceId + 1);
|
|
}
|
|
|
|
private static BackpackInventoryData CloneInventory(BackpackInventoryData source)
|
|
{
|
|
BackpackInventoryData cloned = new BackpackInventoryData();
|
|
if (source == null)
|
|
{
|
|
return cloned;
|
|
}
|
|
|
|
cloned.Gold = Mathf.Max(0, source.Gold);
|
|
|
|
if (source.MuzzleComponents != null)
|
|
{
|
|
for (int i = 0; i < source.MuzzleComponents.Count; i++)
|
|
{
|
|
MuzzleCompItemData item = source.MuzzleComponents[i];
|
|
if (item != null)
|
|
{
|
|
cloned.MuzzleComponents.Add(CloneMuzzleComp(item));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (source.BearingComponents != null)
|
|
{
|
|
for (int i = 0; i < source.BearingComponents.Count; i++)
|
|
{
|
|
BearingCompItemData item = source.BearingComponents[i];
|
|
if (item != null)
|
|
{
|
|
cloned.BearingComponents.Add(CloneBearingComp(item));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (source.BaseComponents != null)
|
|
{
|
|
for (int i = 0; i < source.BaseComponents.Count; i++)
|
|
{
|
|
BaseCompItemData item = source.BaseComponents[i];
|
|
if (item != null)
|
|
{
|
|
cloned.BaseComponents.Add(CloneBaseComp(item));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (source.Towers != null)
|
|
{
|
|
for (int i = 0; i < source.Towers.Count; i++)
|
|
{
|
|
DefenseTowerItemData item = source.Towers[i];
|
|
if (item != null)
|
|
{
|
|
cloned.Towers.Add(CloneTower(item));
|
|
}
|
|
}
|
|
}
|
|
|
|
return cloned;
|
|
}
|
|
|
|
private static MuzzleCompItemData CloneMuzzleComp(MuzzleCompItemData source)
|
|
{
|
|
return new MuzzleCompItemData
|
|
{
|
|
InstanceId = source.InstanceId,
|
|
ConfigId = source.ConfigId,
|
|
Name = source.Name,
|
|
Rarity = source.Rarity,
|
|
Endurance = source.Endurance,
|
|
Constraint = source.Constraint,
|
|
Tags = CloneTags(source.Tags),
|
|
AttackDamage = CloneIntArray(source.AttackDamage),
|
|
DamageRandomRate = source.DamageRandomRate,
|
|
AttackMethodType = source.AttackMethodType
|
|
};
|
|
}
|
|
|
|
private static BearingCompItemData CloneBearingComp(BearingCompItemData source)
|
|
{
|
|
return new BearingCompItemData
|
|
{
|
|
InstanceId = source.InstanceId,
|
|
ConfigId = source.ConfigId,
|
|
Name = source.Name,
|
|
Rarity = source.Rarity,
|
|
Endurance = source.Endurance,
|
|
Constraint = source.Constraint,
|
|
Tags = CloneTags(source.Tags),
|
|
RotateSpeed = CloneFloatArray(source.RotateSpeed),
|
|
AttackRange = CloneFloatArray(source.AttackRange)
|
|
};
|
|
}
|
|
|
|
private static BaseCompItemData CloneBaseComp(BaseCompItemData source)
|
|
{
|
|
return new BaseCompItemData
|
|
{
|
|
InstanceId = source.InstanceId,
|
|
ConfigId = source.ConfigId,
|
|
Name = source.Name,
|
|
Rarity = source.Rarity,
|
|
Endurance = source.Endurance,
|
|
Constraint = source.Constraint,
|
|
Tags = CloneTags(source.Tags),
|
|
AttackSpeed = CloneFloatArray(source.AttackSpeed),
|
|
AttackPropertyType = source.AttackPropertyType
|
|
};
|
|
}
|
|
|
|
private static DefenseTowerItemData CloneTower(DefenseTowerItemData source)
|
|
{
|
|
return new DefenseTowerItemData
|
|
{
|
|
InstanceId = source.InstanceId,
|
|
Name = source.Name,
|
|
Rarity = source.Rarity,
|
|
Endurance = source.Endurance,
|
|
MuzzleComponentInstanceId = source.MuzzleComponentInstanceId,
|
|
BearingComponentInstanceId = source.BearingComponentInstanceId,
|
|
BaseComponentInstanceId = source.BaseComponentInstanceId,
|
|
Stats = CloneTowerStats(source.Stats)
|
|
};
|
|
}
|
|
|
|
private static DefenseTowerStatsData CloneTowerStats(DefenseTowerStatsData source)
|
|
{
|
|
if (source == null)
|
|
{
|
|
return new DefenseTowerStatsData();
|
|
}
|
|
|
|
return new DefenseTowerStatsData
|
|
{
|
|
AttackDamage = source.AttackDamage,
|
|
DamageRandomRate = source.DamageRandomRate,
|
|
RotateSpeed = source.RotateSpeed,
|
|
AttackRange = source.AttackRange,
|
|
AttackSpeed = source.AttackSpeed,
|
|
AttackMethodType = source.AttackMethodType,
|
|
AttackPropertyType = source.AttackPropertyType,
|
|
Tags = CloneTags(source.Tags)
|
|
};
|
|
}
|
|
|
|
private static int[] CloneIntArray(int[] source)
|
|
{
|
|
return source != null ? (int[])source.Clone() : Array.Empty<int>();
|
|
}
|
|
|
|
private static float[] CloneFloatArray(float[] source)
|
|
{
|
|
return source != null ? (float[])source.Clone() : Array.Empty<float>();
|
|
}
|
|
|
|
private static TagType[] CloneTags(TagType[] source)
|
|
{
|
|
return source != null ? (TagType[])source.Clone() : Array.Empty<TagType>();
|
|
}
|
|
}
|
|
}
|