274 lines
8.3 KiB
C#
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 CombatInRunResourceManager
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|