using System; using System.Collections; 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 * (1 + count * upgrade.costMultiplier)); } } public class StatsManager : MonoBehaviour { 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 upgrades. Should only be read, not modified. public Dictionary<UpgradeTypes, UpgradeData> upgrades = new Dictionary<UpgradeTypes, UpgradeData>(); 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++; RecalculateStatMultipliers(); return true; } // 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)) { return false; } currentMana += delta; return true; } // 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)); } } void RecalculateStatMultipliers() { 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; } public float GetTotalEffectMultiplier(UpgradeTypes type) { return upgrades[type].GetTotalEffectMultiplier(); } 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, }); } }