Beispiel #1
0
        public void HealingEffectExpiresWhenCurrentRoundExceedsMaxRoundUnitTest()
        {
            Player player = new Player("test", PlayerClassType.Warrior)
            {
                MaxHitPoints = 100
            };
            const int initialPlayerHealth = 50;

            player.HitPoints = initialPlayerHealth;
            EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                AmountOverTime = 25,
                EffectHolder   = player,
                MaxRound       = 3,
                Name           = "healing test"
            };
            IEffect healEffect = new HealingEffect(effectOverTimeSettings);

            player.Effects.Add(healEffect);

            healEffect.ProcessRound();
            healEffect.ProcessRound();
            healEffect.ProcessRound();

            Assert.AreEqual(player.MaxHitPoints, player.HitPoints);
            Assert.AreEqual(4, healEffect.CurrentRound);
            Assert.AreEqual(true, healEffect.IsEffectExpired);
        }
Beispiel #2
0
        public void PlayerIsHealedWhenEffectAmountMoreThanMaxPlayerHealthUnitTest()
        {
            OutputHelper.Display.ClearUserOutput();
            Player player = new Player("test", PlayerClassType.Warrior)
            {
                MaxHitPoints = 100
            };
            const int initialPlayerHealth        = 80;
            int       maxAmountPlayerCanBeHealed = player.MaxHitPoints - initialPlayerHealth;

            player.HitPoints = initialPlayerHealth;
            EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                AmountOverTime = 25,
                EffectHolder   = player,
                MaxRound       = 3,
                Name           = "healing test"
            };
            IEffect healEffect = new HealingEffect(effectOverTimeSettings);

            player.Effects.Add(healEffect);
            string healMessage = $"You have been healed for {maxAmountPlayerCanBeHealed} health.";

            healEffect.ProcessRound();

            Assert.AreEqual(player.MaxHitPoints, player.HitPoints);
            Assert.AreEqual(healMessage, OutputHelper.Display.Output[0][2]);
        }
Beispiel #3
0
        public HealingEffect(EffectOverTimeSettings effectOverTimeSettings)
        {
            effectOverTimeSettings.ValidateSettings();

            EffectHolder       = effectOverTimeSettings.EffectHolder;
            Name               = effectOverTimeSettings.Name;
            MaxRound           = (int)effectOverTimeSettings.MaxRound;
            HealOverTimeAmount = (int)effectOverTimeSettings.AmountOverTime;
        }
Beispiel #4
0
        public BleedingEffect(EffectOverTimeSettings effectSettings)
        {
            effectSettings.ValidateSettings();

            BleedDamageOverTime = (int)effectSettings.AmountOverTime;
            EffectHolder        = effectSettings.EffectHolder;
            MaxRound            = (int)effectSettings.MaxRound;
            Name = effectSettings.Name;
        }
Beispiel #5
0
        public BurningEffect(EffectOverTimeSettings effectOverTimeSettings)
        {
            effectOverTimeSettings.ValidateSettings();

            EffectHolder       = effectOverTimeSettings.EffectHolder;
            FireDamageOverTime = (int)effectOverTimeSettings.AmountOverTime;
            MaxRound           = (int)effectOverTimeSettings.MaxRound;
            Name = effectOverTimeSettings.Name;
        }
Beispiel #6
0
        public void AddDamageOverTimeEffect(Player player)
        {
            EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                AmountOverTime = DamageOverTimeAmount,
                EffectHolder   = player,
                MaxRound       = MaxDamageRounds,
                Name           = Name
            };

            player.Effects.Add(new BurningEffect(effectOverTimeSettings));
        }
Beispiel #7
0
        public void EffectOverTimeSettingsWithAllSettingsDoesNotThrowException()
        {
            Player player = new Player("test", PlayerClassType.Mage);
            EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                AmountOverTime = 5,
                EffectHolder   = player,
                MaxRound       = 3,
                Name           = "test"
            };

            Assert.DoesNotThrow(() => effectOverTimeSettings.ValidateSettings());
        }
Beispiel #8
0
        public void EffectOverTimeSettingsMissingEffectHolderThrowsException()
        {
            EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                AmountOverTime = 5,
                MaxRound       = 3,
                Name           = "test"
            };
            const string expectedErrorMessage = "EffectOverTimeSettings: EffectHolder has not been set.";

            Exception exception = Assert.Throws <Exception>(() => effectOverTimeSettings.ValidateSettings());

            Assert.AreEqual(expectedErrorMessage, exception.Message);
        }
Beispiel #9
0
        public void EffectOverTimeSettingsMissingAmountOverTimeThrowsException()
        {
            Player player = new Player("test", PlayerClassType.Mage);
            EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                EffectHolder = player,
                MaxRound     = 3,
                Name         = "test"
            };
            const string expectedErrorMessage = "EffectOverTimeSettings: AmountOverTime has not been set.";

            Exception exception = Assert.Throws <Exception>(() => effectOverTimeSettings.ValidateSettings());

            Assert.AreEqual(expectedErrorMessage, exception.Message);
        }
Beispiel #10
0
        public void UseOffenseDamageAbility(Monster monster, Player player, int index)
        {
            monster.EnergyPoints -= monster.Abilities[index].EnergyCost;

            string attackString = monster.MonsterCategory == MonsterType.Spider
                                ? $"The {monster.Name} tries to bite you!"
                                : $"The {monster.Name} swings its tail at you!";

            OutputHelper.Display.StoreUserOutput(
                Settings.FormatAttackSuccessText(),
                Settings.FormatDefaultBackground(),
                attackString);

            int attackDamage = monster.Abilities[index].Offensive.Amount;

            attackDamage = AdjustAbilityDamageFromPlayerEffects(player, monster, attackDamage);

            string attackSuccessString = monster.MonsterCategory == MonsterType.Spider
                                ? $"The {monster.Name} bites you for {attackDamage} physical damage."
                                : $"The {monster.Name} strikes you with its tail for {attackDamage} physical damage.";

            OutputHelper.Display.StoreUserOutput(
                Settings.FormatAttackSuccessText(),
                Settings.FormatDefaultBackground(),
                attackSuccessString);

            player.HitPoints -= attackDamage;

            if (monster.Abilities[index].Offensive.AmountOverTime <= 0)
            {
                return;
            }

            if (monster.Abilities[index].Offensive.OffensiveGroup is OffensiveType.Bleed)
            {
                string bleedString = $"You are bleeding from {monster.Name}'s attack!";
                OutputHelper.Display.StoreUserOutput(
                    Settings.FormatAttackSuccessText(),
                    Settings.FormatDefaultBackground(),
                    bleedString);

                EffectOverTimeSettings effectSettings = new EffectOverTimeSettings {
                    AmountOverTime = monster.Abilities[index].Offensive.AmountOverTime,
                    EffectHolder   = player,
                    Name           = monster.Abilities[index].Name,
                    MaxRound       = monster.Abilities[index].Offensive.AmountMaxRounds
                };
                player.Effects.Add(new BleedingEffect(effectSettings));
            }
        }
Beispiel #11
0
        public void MonsterHasBurningEffectUnitTest()
        {
            Monster monster = new Monster(5, MonsterType.Skeleton);
            EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                AmountOverTime = 20,
                EffectHolder   = monster,
                MaxRound       = 3,
                Name           = "burning test"
            };

            monster.Effects.Add(new BurningEffect(effectOverTimeSettings));

            Assert.AreEqual(1, monster.Effects.Count);
            Assert.AreEqual(true, monster.Effects[0] is BurningEffect);
        }
Beispiel #12
0
        public void CastFireOffense(Monster monster, Player player, int index)
        {
            monster.EnergyPoints -= monster.Spellbook[index].EnergyCost;

            string attackString = monster.MonsterCategory == MonsterType.Dragon
                                ? $"The {monster.Name} breathes a pillar of fire at you!"
                                : $"The {monster.Name} casts a fireball and launches it at you!";

            OutputHelper.Display.StoreUserOutput(
                Settings.FormatAttackSuccessText(),
                Settings.FormatDefaultBackground(),
                attackString);

            int fireSpellDamage = MonsterHelper.CalculateSpellDamage(player, monster, index);

            fireSpellDamage = CombatHelper.GetMonsterAttackDamageUpdatedFromPlayerEffects(player, monster, fireSpellDamage);

            if (fireSpellDamage == 0)
            {
                return;
            }

            player.HitPoints -= fireSpellDamage;

            string attackSuccessString = $"The {monster.Name} hits you for {fireSpellDamage} fire damage.";

            OutputHelper.Display.StoreUserOutput(
                Settings.FormatAttackSuccessText(),
                Settings.FormatDefaultBackground(),
                attackSuccessString);

            if (monster.Spellbook[index].Offensive.AmountOverTime > 0)
            {
                const string onFireString = "You burst into flame!";
                OutputHelper.Display.StoreUserOutput(
                    Settings.FormatOnFireText(),
                    Settings.FormatDefaultBackground(),
                    onFireString);

                EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                    AmountOverTime = monster.Spellbook[index].Offensive.AmountOverTime,
                    EffectHolder   = player,
                    MaxRound       = monster.Spellbook[index].Offensive.AmountMaxRounds,
                    Name           = monster.Spellbook[index].Name
                };
                player.Effects.Add(new BurningEffect(effectOverTimeSettings));
            }
        }
Beispiel #13
0
        public void HealingEffectCanBeSetAsExpired()
        {
            Player player = new Player("test", PlayerClassType.Warrior);
            EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                AmountOverTime = 25,
                EffectHolder   = player,
                MaxRound       = 3,
                Name           = "healing test"
            };
            IEffect healEffect = new HealingEffect(effectOverTimeSettings);

            player.Effects.Add(healEffect);

            healEffect.SetEffectAsExpired();

            Assert.AreEqual(true, healEffect.IsEffectExpired);
        }
Beispiel #14
0
        public void PlayerHasBurningEffectUnitTest()
        {
            Player player = new Player("test", PlayerClassType.Mage);
            EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                AmountOverTime = 20,
                EffectHolder   = player,
                MaxRound       = 3,
                Name           = "burning test"
            };
            BurningEffect burningEffect = new BurningEffect(effectOverTimeSettings);

            player.Effects.Add(burningEffect);

            Assert.AreEqual(1, player.Effects.Count);
            Assert.AreEqual(effectOverTimeSettings.Name, burningEffect.Name);
            Assert.AreEqual(true, player.Effects[0] is BurningEffect);
        }
Beispiel #15
0
        public static void CastFireOffense(Monster monster, Player player, int index)
        {
            player.ManaPoints -= player.Spellbook[index].ManaCost;

            int fireSpellDamage = PlayerHelper.CalculateSpellDamage(player, monster, index);

            foreach (FrozenEffect effect in monster.Effects)
            {
                fireSpellDamage = effect.GetIncreasedDamageFromFrozen(fireSpellDamage);
                effect.ProcessRound();
                effect.IsEffectExpired = true;
            }

            string attackSuccessString = $"You hit the {monster.Name} for {fireSpellDamage} fire damage.";

            OutputHelper.Display.StoreUserOutput(
                Settings.FormatAttackSuccessText(),
                Settings.FormatDefaultBackground(),
                attackSuccessString);

            monster.HitPoints -= fireSpellDamage;

            if (player.Spellbook[index].Offensive.AmountOverTime <= 0)
            {
                return;
            }

            string onFireString = $"The {monster.Name} bursts into flame!";

            OutputHelper.Display.StoreUserOutput(
                Settings.FormatOnFireText(),
                Settings.FormatDefaultBackground(),
                onFireString);

            EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                AmountOverTime = player.Spellbook[index].Offensive.AmountOverTime,
                EffectHolder   = monster,
                MaxRound       = player.Spellbook[index].Offensive.AmountMaxRounds,
                Name           = player.Spellbook[index].Name
            };

            monster.Effects.Add(new BurningEffect(effectOverTimeSettings));
        }
Beispiel #16
0
        public void EffectUserOutputUnitTest()
        {
            OutputHelper.Display.ClearUserOutput();
            Player player = new Player("placeholder", PlayerClassType.Mage);

            RoomHelper.Rooms = new Dictionary <Coordinate, IRoom> {
                { new Coordinate(1, 1, 1), new DungeonRoom(1, 1) }
            };
            player.Spellbook.Add(new PlayerSpell(
                                     "reflect", 100, 1, SpellType.Reflect, 1));
            UserOutput defaultEffectOutput = OutputHelper.ShowEffects(player);

            Assert.AreEqual("Player _Effects:", defaultEffectOutput.Output[0][2]);
            Assert.AreEqual("None.", defaultEffectOutput.Output[1][2]);
            player.CastSpell("reflect");
            OutputHelper.Display.ClearUserOutput();
            defaultEffectOutput = OutputHelper.ShowEffects(player);
            Assert.AreEqual("Player _Effects:", defaultEffectOutput.Output[0][2]);
            Assert.AreEqual(Settings.FormatGeneralInfoText(), defaultEffectOutput.Output[1][0]);
            Assert.AreEqual("(30 seconds) Reflect", defaultEffectOutput.Output[1][2]);
            for (int i = 0; i < 10; i++)
            {
                GameHelper.CheckStatus(player);
            }
            EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                AmountOverTime = 5,
                EffectHolder   = player,
                MaxRound       = 3,
                Name           = "burning"
            };

            player.Effects.Add(new BurningEffect(effectOverTimeSettings));
            Assert.AreEqual("Your spell reflect is slowly fading away.", OutputHelper.Display.Output[0][2]);
            player.CastSpell("rejuvenate");
            defaultEffectOutput = OutputHelper.ShowEffects(player);
            Assert.AreEqual("Player _Effects:", defaultEffectOutput.Output[0][2]);
            Assert.AreEqual(Settings.FormatGeneralInfoText(), defaultEffectOutput.Output[1][0]);
            Assert.AreEqual("(20 seconds) Reflect", defaultEffectOutput.Output[1][2]);
            Assert.AreEqual(Settings.FormatGeneralInfoText(), defaultEffectOutput.Output[2][0]);
            Assert.AreEqual("(30 seconds) Rejuvenate", defaultEffectOutput.Output[2][2]);
            Assert.AreEqual(Settings.FormatAttackFailText(), defaultEffectOutput.Output[3][0]);
            Assert.AreEqual("(30 seconds) Burning", defaultEffectOutput.Output[3][2]);
        }
Beispiel #17
0
        public void PlayerHasHealingEffectUnitTest()
        {
            Player player = new Player("test", PlayerClassType.Warrior);
            EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                AmountOverTime = 25,
                EffectHolder   = player,
                MaxRound       = 3,
                Name           = "healing test"
            };
            IEffect healEffect = new HealingEffect(effectOverTimeSettings);

            player.Effects.Add(healEffect);

            Assert.AreEqual(1, player.Effects.Count);
            Assert.AreEqual(true, player.Effects[0] is HealingEffect);
            Assert.AreEqual(1, player.Effects[0].CurrentRound);
            Assert.AreEqual(effectOverTimeSettings.MaxRound, player.Effects[0].MaxRound);
            Assert.AreEqual(false, player.Effects[0].IsHarmful);
            Assert.AreEqual(false, healEffect.IsEffectExpired);
            Assert.AreEqual(healEffect.EffectHolder, player);
        }
Beispiel #18
0
        public void MonsterBleedingEffectDoesNotExpireWhenCurrentRoundEqualsMaxRoundUnitTest()
        {
            Monster monster = new Monster(5, MonsterType.Skeleton);
            EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                AmountOverTime = 20,
                EffectHolder   = monster,
                MaxRound       = 3,
                Name           = "bleed test"
            };
            BleedingEffect bleedEffect = new BleedingEffect(effectOverTimeSettings);

            monster.Effects.Add(bleedEffect);

            for (int i = 0; i < effectOverTimeSettings.MaxRound - 1; i++)
            {
                bleedEffect.ProcessRound();
            }

            Assert.AreEqual(3, bleedEffect.CurrentRound);
            Assert.AreEqual(false, bleedEffect.IsEffectExpired);
        }
Beispiel #19
0
        public void PlayerBleedingEffectExpiresWhenCurrentRoundGreaterThanMaxRoundUnitTest()
        {
            Player player = new Player("test", PlayerClassType.Mage);
            EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                AmountOverTime = 20,
                EffectHolder   = player,
                MaxRound       = 3,
                Name           = "bleed test"
            };
            BleedingEffect bleedEffect = new BleedingEffect(effectOverTimeSettings);

            player.Effects.Add(bleedEffect);

            for (int i = 0; i < effectOverTimeSettings.MaxRound; i++)
            {
                bleedEffect.ProcessRound();
            }

            Assert.AreEqual(4, bleedEffect.CurrentRound);
            Assert.AreEqual(true, bleedEffect.IsEffectExpired);
        }
Beispiel #20
0
        public void PlayerBurningEffectDoesNotExpireWhenCurrentRoundEqualsMaxRoundUnitTest()
        {
            Player player = new Player("test", PlayerClassType.Mage);
            EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                AmountOverTime = 20,
                EffectHolder   = player,
                MaxRound       = 3,
                Name           = "burning test"
            };
            BurningEffect burningEffect = new BurningEffect(effectOverTimeSettings);

            player.Effects.Add(burningEffect);

            for (int i = 0; i < effectOverTimeSettings.MaxRound - 1; i++)
            {
                burningEffect.ProcessRound();
            }

            Assert.AreEqual(3, burningEffect.CurrentRound);
            Assert.AreEqual(false, burningEffect.IsEffectExpired);
        }
Beispiel #21
0
        public void MonsterBurningEffectExpiresWhenCurrentRoundGreaterThanMaxRoundUnitTest()
        {
            Monster monster = new Monster(5, MonsterType.Skeleton);
            EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                AmountOverTime = 20,
                EffectHolder   = monster,
                MaxRound       = 3,
                Name           = "burning test"
            };
            BurningEffect burningEffect = new BurningEffect(effectOverTimeSettings);

            monster.Effects.Add(burningEffect);

            for (int i = 0; i < effectOverTimeSettings.MaxRound; i++)
            {
                burningEffect.ProcessRound();
            }

            Assert.AreEqual(4, burningEffect.CurrentRound);
            Assert.AreEqual(true, burningEffect.IsEffectExpired);
        }
Beispiel #22
0
        public void ProcessBurningEffectRoundMonsterUnitTest()
        {
            OutputHelper.Display.ClearUserOutput();
            Monster monster = new Monster(5, MonsterType.Skeleton);
            EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                AmountOverTime = 20,
                EffectHolder   = monster,
                MaxRound       = 3,
                Name           = "burning test"
            };
            BurningEffect burningEffect = new BurningEffect(effectOverTimeSettings);

            monster.Effects.Add(burningEffect);
            string burningMessage = $"The {monster.Name} burns for {effectOverTimeSettings.AmountOverTime} fire damage.";

            burningEffect.ProcessRound();

            Assert.AreEqual(monster.MaxHitPoints - effectOverTimeSettings.AmountOverTime, monster.HitPoints);
            Assert.AreEqual(burningMessage, OutputHelper.Display.Output[0][2]);
            Assert.AreEqual(2, burningEffect.CurrentRound);
            Assert.AreEqual(false, burningEffect.IsEffectExpired);
        }
Beispiel #23
0
        public void ProcessBurningEffectRoundPlayerUnitTest()
        {
            OutputHelper.Display.ClearUserOutput();
            Player player = new Player("test", PlayerClassType.Mage);
            EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                AmountOverTime = 20,
                EffectHolder   = player,
                MaxRound       = 3,
                Name           = "burning test"
            };
            BurningEffect burningEffect = new BurningEffect(effectOverTimeSettings);

            player.Effects.Add(burningEffect);
            string burningMessage = $"You burn for {effectOverTimeSettings.AmountOverTime} fire damage.";

            burningEffect.ProcessRound();

            Assert.AreEqual(player.MaxHitPoints - effectOverTimeSettings.AmountOverTime, player.HitPoints);
            Assert.AreEqual(burningMessage, OutputHelper.Display.Output[0][2]);
            Assert.AreEqual(2, burningEffect.CurrentRound);
            Assert.AreEqual(false, burningEffect.IsEffectExpired);
        }
Beispiel #24
0
        public static void UseBandageAbility(Player player, int index)
        {
            DeductAbilityCost(player, index);

            int healAmount = player.Abilities[index].Healing.HealAmount;

            string healString = $"You heal yourself for {healAmount} health.";

            OutputHelper.Display.StoreUserOutput(
                Settings.FormatSuccessOutputText(),
                Settings.FormatDefaultBackground(),
                healString);

            if (player.HitPoints + healAmount > player.MaxHitPoints)
            {
                player.HitPoints = player.MaxHitPoints;
            }
            else
            {
                player.HitPoints += healAmount;
            }

            if (player.Abilities[index].Healing.HealOverTime <= 0)
            {
                return;
            }

            EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                AmountOverTime = player.Abilities[index].Healing.HealOverTime,
                EffectHolder   = player,
                MaxRound       = player.Abilities[index].Healing.HealMaxRounds,
                Name           = player.Abilities[index].Name
            };

            player.Effects.Add(new HealingEffect(effectOverTimeSettings));
        }
Beispiel #25
0
        public void PlayerIsHealedWhenEffectAmountEqualToMaxPlayerHealthUnitTest()
        {
            OutputHelper.Display.ClearUserOutput();
            Player player = new Player("test", PlayerClassType.Warrior)
            {
                MaxHitPoints = 100
            };
            const int initialPlayerHealth = 75;

            player.HitPoints = initialPlayerHealth;
            EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                AmountOverTime = 25,
                EffectHolder   = player,
                MaxRound       = 3,
                Name           = "healing test"
            };
            IEffect healEffect = new HealingEffect(effectOverTimeSettings);

            player.Effects.Add(healEffect);

            healEffect.ProcessRound();

            Assert.AreEqual(initialPlayerHealth + effectOverTimeSettings.AmountOverTime, player.HitPoints);
        }
Beispiel #26
0
        public static void CastHealing(Player player, int index)
        {
            player.ManaPoints -= player.Spellbook[index].ManaCost;

            int healAmount = player.Spellbook[index].Healing.HealAmount;

            string healString = $"You heal yourself for {healAmount} health.";

            OutputHelper.Display.StoreUserOutput(
                Settings.FormatAttackSuccessText(),
                Settings.FormatDefaultBackground(),
                healString);

            if (player.HitPoints + healAmount > player.MaxHitPoints)
            {
                player.HitPoints = player.MaxHitPoints;
            }
            else
            {
                player.HitPoints += healAmount;
            }

            if (player.Spellbook[index].Healing.HealOverTime <= 0)
            {
                return;
            }

            EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                AmountOverTime = player.Spellbook[index].Healing.HealOverTime,
                EffectHolder   = player,
                MaxRound       = player.Spellbook[index].Healing.HealMaxRounds,
                Name           = player.Spellbook[index].Name
            };

            player.Effects.Add(new HealingEffect(effectOverTimeSettings));
        }
Beispiel #27
0
        public static void UseOffenseDamageAbility(Monster monster, Player player, int index)
        {
            if (player.PlayerClass == PlayerClassType.Archer && PlayerHelper.OutOfArrows(player))
            {
                /* If quiver is empty, player can only do a normal attack, and attack() also checks for
                 * arrow count and informs player that they are out of arrows */
                player.PhysicalAttack(monster);
                return;
            }

            DeductAbilityCost(player, index);

            if (player.PlayerClass == PlayerClassType.Archer)
            {
                player.PlayerQuiver.UseArrow();
            }

            int abilityDamage = PlayerHelper.CalculateAbilityDamage(player, monster, index);

            monster.HitPoints -= abilityDamage;

            string abilitySuccessString = $"Your {player.Abilities[index].Name} hit the {monster.Name} for {abilityDamage} physical damage.";

            OutputHelper.Display.StoreUserOutput(
                Settings.FormatAttackSuccessText(),
                Settings.FormatDefaultBackground(),
                abilitySuccessString);

            if (player.Abilities[index].Offensive.AmountOverTime <= 0)
            {
                return;
            }

            switch (player.Abilities[index].Offensive.OffensiveGroup)
            {
            case OffensiveType.Normal:
                break;

            case OffensiveType.Bleed:
                string bleedString = $"The {monster.Name} is bleeding!";
                OutputHelper.Display.StoreUserOutput(
                    Settings.FormatAttackSuccessText(),
                    Settings.FormatDefaultBackground(),
                    bleedString);

                EffectOverTimeSettings effectSettings = new EffectOverTimeSettings {
                    AmountOverTime = player.Abilities[index].Offensive.AmountOverTime,
                    EffectHolder   = monster,
                    MaxRound       = player.Abilities[index].Offensive.AmountMaxRounds,
                    Name           = player.Abilities[index].Name
                };
                monster.Effects.Add(new BleedingEffect(effectSettings));
                break;

            case OffensiveType.Fire:
                string onFireString = $"The {monster.Name} bursts into flame!";
                OutputHelper.Display.StoreUserOutput(
                    Settings.FormatOnFireText(),
                    Settings.FormatDefaultBackground(),
                    onFireString);

                EffectOverTimeSettings effectOverTimeSettings = new EffectOverTimeSettings {
                    AmountOverTime = player.Abilities[index].Offensive.AmountOverTime,
                    EffectHolder   = monster,
                    MaxRound       = player.Abilities[index].Offensive.AmountMaxRounds,
                    Name           = player.Abilities[index].Name
                };
                monster.Effects.Add(new BurningEffect(effectOverTimeSettings));
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }