geometry-tower-defense/Assets/GameMain/Scripts/CustomComponent/PlayerInventoryComponent.cs

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>();
}
}
}