Newer
Older
using System.Collections.Generic;
using UnityEngine;
public enum UpgradeTypes
{
ENEMY_HEALTH,
ENEMY_DAMAGE,
ENEMY_ARMOR,
MANA_COST,
}
public enum FighterTypes
ANTI_PLAYER,
ENEMY,
public struct FighterStats
{
public float healthMultiplier;
public float damageMultiplier;
public float armorMultiplier;
}
public class UpgradeData
{
public Upgrade upgrade;
public int count;
// How much it costs to purchase another one of this upgrade
public int GetNextUpgradeCost()
return StatsManager.instance.AdjustManaCost(GetUnadjustedNextUpgradeCost());
}
public float GetTotalEffectMultiplier()
{
return 1 + count * upgrade.effectMultiplier;
}
// You probably shouldn't call this outside this file.
public int GetUnadjustedNextUpgradeCost()
{
return (int)(upgrade.baseCost * Mathf.Pow(1 + upgrade.costMultiplier, count));
public interface IManaChangeCallback
{
void OnManaChanged(int oldValue, int newValue);
}
// Provides the current Statistics (buffs) for supported Fighter types as well as
// Mana storage and management. Allows scripts to buy Upgrade or otherwise spend Mana.
public class StatsManager : MonoBehaviour, IRoundCallback
{
public static StatsManager instance { get; private set; }
[SerializeField] int currentMana;
[SerializeField, Tooltip("When the AntiPlayer receives damage, how much of that damage is converted to Mana")]
float antiPlayerDamageManaMultiplier = 100f;
[SerializeField, Tooltip("When the AntiPlayer dies, how much mana to give")]
int antiPlayerDeathMana = 1000;
[SerializeField] List<Upgrade> availableUpgrades;
// The currently active statistics for each fighter type
public Dictionary<FighterTypes, FighterStats> fighterStats = new Dictionary<FighterTypes, FighterStats>();
// Information about currently available and purchased Enemy upgrades. Should only be read, not modified.
public Dictionary<UpgradeTypes, UpgradeData> upgrades = new Dictionary<UpgradeTypes, UpgradeData>();
// Want to be notified whenever the current Mana amount changes?
public List<IManaChangeCallback> manaChangeCallbacks = new List<IManaChangeCallback>();
public int GetMana()
{
return currentMana;
}
// Adjusts the given Mana cost based on the amount of Mana cost upgrades currently bought.
public int AdjustManaCost(int cost)
{
return (int)(cost * upgrades[UpgradeTypes.MANA_COST].GetTotalEffectMultiplier());
}
public int GetNextUpgradeCost(UpgradeTypes type)
{
return upgrades[type].GetNextUpgradeCost();
}
// Buys an upgrade, spending the required amount of Mana in the process. Returns false if not enough Mana is available.
public bool BuyUpgrade(UpgradeTypes type)
{
if (!ModifyMana(-GetNextUpgradeCost(type)))
{
return false;
}
upgrades[type].count++;
// Add (positive value) or spend (negative value) Mana. Returns false if not enough Mana is available to spend.
public bool ModifyMana(int delta)
{
if (!CanModifyMana(delta))
if (delta != 0)
{
manaChangeCallbacks.ForEach(c => c.OnManaChanged(previousMana, currentMana));
}
// If `delta` is negative, returns this amount of Mana can be spent. If `delta` is positive, this will always return `true`.
public bool CanModifyMana(int delta)
{
return currentMana + delta >= 0;
}
// Adds Mana based on the amount of damage the AntiPlayer has taken
public void AddDamageBasedMana(int damage, bool death = false)
{
if (death)
{
ModifyMana(antiPlayerDeathMana);
}
else
{
ModifyMana((int)(damage * antiPlayerDamageManaMultiplier));
}
}
// How much a specific Enemy stat is buffed based on how many Upgrades have already been purchased
public float GetTotalEffectMultiplier(UpgradeTypes type)
{
return upgrades[type].GetTotalEffectMultiplier();
}
public void UpgradeAntiPlayer()
{
var playerStats = fighterStats[FighterTypes.ANTI_PLAYER];
playerStats.healthMultiplier += 0.2f;
playerStats.damageMultiplier += 0.2f;
playerStats.armorMultiplier += 0.1f;
fighterStats[FighterTypes.ANTI_PLAYER] = playerStats;
}
var enemyStats = fighterStats[FighterTypes.ENEMY];
enemyStats.healthMultiplier = upgrades[UpgradeTypes.ENEMY_HEALTH].GetTotalEffectMultiplier();
enemyStats.damageMultiplier = upgrades[UpgradeTypes.ENEMY_DAMAGE].GetTotalEffectMultiplier();
enemyStats.armorMultiplier = upgrades[UpgradeTypes.ENEMY_ARMOR].GetTotalEffectMultiplier();
fighterStats[FighterTypes.ENEMY] = enemyStats;
}
void Awake()
{
if (instance == null)
{
instance = this;
}
else if (instance != this)
{
Destroy(gameObject);
}
DontDestroyOnLoad(gameObject);
foreach (Upgrade upgrade in availableUpgrades)
{
UpgradeData upgradeData = new UpgradeData();
upgradeData.upgrade = upgrade;
upgradeData.count = 0;
upgrades.Add(upgrade.type, upgradeData);
}
fighterStats.Add(FighterTypes.ANTI_PLAYER, new FighterStats()
{
healthMultiplier = 1f,
damageMultiplier = 1f,
armorMultiplier = 1f,
});
fighterStats.Add(FighterTypes.ENEMY, new FighterStats()
{
healthMultiplier = 1f,
damageMultiplier = 1f,
armorMultiplier = 1f,
});
void Start()
{
RoundController.instance.roundCallbacks.Add(this);
}
public void OnRoundStart()
{
manaAtRoundStart = currentMana;
}
public void OnRoundEnd(bool won)
{
if (!won)
{
// Reset current Mana back to start value if round was lost
var gainedMana = currentMana - manaAtRoundStart;
ModifyMana(-gainedMana);
}
}