geometry-tower-defense/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatRunResourceStore.cs

274 lines
8.3 KiB
C#

using System.Collections.Generic;
using GeometryTD.CustomEvent;
using GeometryTD.CustomUtility;
using GeometryTD.DataTable;
using GeometryTD.Definition;
using UnityEngine;
namespace GeometryTD.CustomComponent
{
internal sealed class CombatRunResourceStore
{
private readonly List<TowerStatsData> _buildTowerStatsSnapshot = new();
private readonly List<TowerItemData> _participantTowerSnapshot = new();
private readonly BackpackInventoryData _rewardInventory = new();
private BackpackInventoryData _combatInventorySnapshot = new();
private bool _isCombatActive;
public int CurrentCoin { get; private set; }
public int CurrentGold => _isCombatActive ? GainedGold : 0;
public int CurrentBaseHp { get; private set; }
public int MaxBaseHp { get; private set; }
public int CurrentBuildTowerCount => _isCombatActive ? _buildTowerStatsSnapshot.Count : 0;
public int GainedCoin { get; private set; }
public int GainedGold { get; private set; }
public void InitializeForCombat(DRLevel level)
{
Reset();
if (level == null)
{
return;
}
MaxBaseHp = Mathf.Max(0, level.BaseHp);
CurrentBaseHp = MaxBaseHp;
CurrentCoin = Mathf.Max(0, level.StartCoin);
CacheCombatSnapshots();
_isCombatActive = true;
}
public void MarkCombatEnded()
{
_isCombatActive = false;
}
public void Reset()
{
_isCombatActive = false;
CurrentCoin = 0;
CurrentBaseHp = 0;
MaxBaseHp = 0;
GainedCoin = 0;
GainedGold = 0;
_buildTowerStatsSnapshot.Clear();
_participantTowerSnapshot.Clear();
_combatInventorySnapshot = new BackpackInventoryData();
_rewardInventory.Gold = 0;
_rewardInventory.MuzzleComponents.Clear();
_rewardInventory.BearingComponents.Clear();
_rewardInventory.BaseComponents.Clear();
_rewardInventory.Towers.Clear();
_rewardInventory.ParticipantTowerInstanceIds.Clear();
}
public BackpackInventoryData GetRewardInventorySnapshot()
{
return InventoryCloneUtility.CloneInventory(_rewardInventory);
}
public BackpackInventoryData GetCombatInventorySnapshot()
{
return InventoryCloneUtility.CloneInventory(_combatInventorySnapshot);
}
public IReadOnlyList<TowerItemData> GetParticipantTowerSnapshot()
{
List<TowerItemData> snapshot = new List<TowerItemData>(_participantTowerSnapshot.Count);
for (int i = 0; i < _participantTowerSnapshot.Count; i++)
{
TowerItemData tower = _participantTowerSnapshot[i];
if (tower != null)
{
snapshot.Add(InventoryCloneUtility.CloneTower(tower));
}
}
return snapshot;
}
public bool TryConsumeCoin(int coin)
{
int requiredCoin = Mathf.Max(0, coin);
if (requiredCoin <= 0)
{
return true;
}
if (!_isCombatActive || CurrentCoin < requiredCoin)
{
return false;
}
CurrentCoin -= requiredCoin;
FireCoinChangedEvent(-requiredCoin);
return true;
}
public void AddCoin(int coin)
{
int gainedCoin = Mathf.Max(0, coin);
if (!_isCombatActive || gainedCoin <= 0)
{
return;
}
CurrentCoin += gainedCoin;
FireCoinChangedEvent(gainedCoin);
}
public int ApplyBaseDamage(int damage)
{
int resolvedDamage = Mathf.Max(0, damage);
if (!_isCombatActive || resolvedDamage <= 0)
{
return CurrentBaseHp;
}
int previousBaseHp = CurrentBaseHp;
CurrentBaseHp = Mathf.Max(0, CurrentBaseHp - resolvedDamage);
int deltaBaseHp = CurrentBaseHp - previousBaseHp;
if (deltaBaseHp != 0)
{
FireBaseHpChangedEvent(deltaBaseHp);
}
return CurrentBaseHp;
}
public bool TryGetBuildTowerStats(int buildIndex, out TowerStatsData stats)
{
stats = null;
if (!_isCombatActive || buildIndex < 0 || buildIndex >= _buildTowerStatsSnapshot.Count)
{
return false;
}
TowerStatsData sourceStats = _buildTowerStatsSnapshot[buildIndex];
if (sourceStats == null)
{
return false;
}
stats = InventoryCloneUtility.CloneTowerStats(sourceStats);
return stats != null;
}
public void AddEnemyDefeatedReward(int gainedCoin, int gainedGold)
{
if (!_isCombatActive)
{
return;
}
int coin = Mathf.Max(0, gainedCoin);
int gold = Mathf.Max(0, gainedGold);
GainedCoin += coin;
GainedGold += gold;
if (coin > 0)
{
CurrentCoin += coin;
FireCoinChangedEvent(coin);
}
if (gold > 0)
{
_rewardInventory.Gold += gold;
}
}
public void AddSettlementGold(int gainedGold)
{
int gold = Mathf.Max(0, gainedGold);
if (gold <= 0)
{
return;
}
GainedGold += gold;
_rewardInventory.Gold += gold;
}
public void AddEnemyDefeatedLoot(TowerCompItemData droppedItem)
{
if (!_isCombatActive || droppedItem == null)
{
return;
}
AppendRewardItem(droppedItem);
}
private void CacheCombatSnapshots()
{
_buildTowerStatsSnapshot.Clear();
_participantTowerSnapshot.Clear();
_combatInventorySnapshot = GameEntry.PlayerInventory != null
? GameEntry.PlayerInventory.GetInventorySnapshot()
: new BackpackInventoryData();
if (GameEntry.PlayerInventory == null)
{
return;
}
IReadOnlyList<TowerItemData> towers = GameEntry.PlayerInventory.GetParticipantTowerSnapshot();
if (towers == null || towers.Count <= 0)
{
return;
}
for (int i = 0; i < towers.Count; i++)
{
TowerItemData tower = towers[i];
if (tower == null)
{
continue;
}
_participantTowerSnapshot.Add(InventoryCloneUtility.CloneTower(tower));
if (tower.Stats != null)
{
_buildTowerStatsSnapshot.Add(InventoryCloneUtility.CloneTowerStats(tower.Stats));
}
}
}
private void FireCoinChangedEvent(int deltaCoin)
{
if (!_isCombatActive)
{
return;
}
GameEntry.Event.Fire(this, CombatCoinChangedEventArgs.Create(CurrentCoin, deltaCoin));
}
private void FireBaseHpChangedEvent(int deltaBaseHp)
{
if (!_isCombatActive)
{
return;
}
GameEntry.Event.Fire(this, CombatBaseHpChangedEventArgs.Create(CurrentBaseHp, deltaBaseHp));
}
private void AppendRewardItem(TowerCompItemData droppedItem)
{
switch (droppedItem)
{
case MuzzleCompItemData muzzleComp:
_rewardInventory.MuzzleComponents.Add(InventoryCloneUtility.CloneMuzzleComp(muzzleComp));
break;
case BearingCompItemData bearingComp:
_rewardInventory.BearingComponents.Add(InventoryCloneUtility.CloneBearingComp(bearingComp));
break;
case BaseCompItemData baseComp:
_rewardInventory.BaseComponents.Add(InventoryCloneUtility.CloneBaseComp(baseComp));
break;
}
}
}
}