예제 #1
0
        public void IncrementHealth_ProperlyHeals()
        {
            int returnAmount;
            IronBattleShield ironShield = IncrementHealth_Setup(10, 2, 1, out returnAmount);

            Assert.AreEqual(9, ironShield.CurrentHealth);
        }
예제 #2
0
        public void SpecialMoveFailedEvent_RaisedWhenShieldBusterFails_BusterPowerLessThanShieldBusterDefense()
        {
            _logger.Subscribe(_humanFighter, EventType.SpecialMoveFailed);

            IronBattleShield shield = new IronBattleShield(5, 5, 3, 2);

            _enemy.SetBattleShield(shield);

            Assert.NotNull(_enemy.BattleShield);

            ShieldBusterMove shieldBuster = new ShieldBusterMove("shieldBuster", TargetType.SingleEnemy, null, 1);

            _humanFighter.SetMove(shieldBuster, 1);
            _humanFighter.SetMoveTarget(_enemy);
            _humanFighter.SetMove(_runawayMove);

            _enemy.SetMove(_doNothingMove);

            _battleManager.Battle(_humanTeam, _enemyTeam);

            List <EventLog> logs = _logger.Logs;

            Assert.AreEqual(1, logs.Count);

            EventLog log = logs[0];

            Assert.AreEqual(EventType.SpecialMoveFailed, log.Type);

            SpecialMoveFailedEventArgs e = log.E as SpecialMoveFailedEventArgs;

            Assert.NotNull(e);
            Assert.AreEqual(SpecialMoveFailedReasonType.ShieldBusterDefenseHigherThanShieldBusterPower, e.Reason);
        }
예제 #3
0
        public void BattleManager_CorrectlyCalculatesDamageForShield()
        {
            int shieldDefense = 10;

            IronBattleShield shield = new IronBattleShield((shieldDefense * 2) + 1, shieldDefense, 0);

            _humanPlayer1.SetBattleShield(shield);

            _logger.SubscribeAll(_humanPlayer1.BattleShield);

            _humanPlayer1.SetDefense(shieldDefense);
            _humanPlayer1.SetStrength(_enemyPlayer1.MaxHealth + _enemyPlayer1.Defense);
            _humanPlayer1.SetMove(_basicAttackMove);
            _humanPlayer1.SetMoveTarget(_enemyPlayer1);

            _enemyPlayer1.SetSpeed(1);
            _enemyPlayer1.SetStrength(shieldDefense * 2);
            _enemyPlayer1.SetMove(_basicAttackMove);

            _chanceService.PushEventsOccur(true, false, true, false); //attacks hit, not misses

            _humanTeam = new Team(_menuManager, _humanPlayer1);
            _enemyTeam = new Team(_menuManager, _enemyPlayer1);

            _battleManager.Battle(_humanTeam, _enemyTeam);

            List <EventLog> logs = _logger.Logs;

            Assert.AreEqual(1, logs.Count);

            PhysicalDamageTakenEventArgs e = logs[0].E as PhysicalDamageTakenEventArgs;

            Assert.NotNull(e);
            Assert.AreEqual(shieldDefense, e.Damage);
        }
예제 #4
0
        public void Level1ShieldGuy_SelectsAppropriateTarget_ShieldHealingMove([Values(1, 2, 3)] int numberOfAlliesWithDamagedShields)
        {
            IronBattleShield shield = new IronBattleShield(5, 0, 0);

            _shieldGuyTeam.Fighters.ForEach(f => f.SetBattleShield(shield));

            for (int i = 0; i < numberOfAlliesWithDamagedShields; ++i)
            {
                _shieldGuyTeam.Fighters[i].BattleShield.DecrementHealth(1);
            }

            _chanceService.PushWhichEventsOccur(2);

            if (numberOfAlliesWithDamagedShields > 1)
            {
                _chanceService.PushWhichEventsOccur(numberOfAlliesWithDamagedShields - 1); //Select the target
            }
            BattleMoveWithTarget moveWithTarget = _level1ShieldGuy.SetupMove(_shieldGuyTeam, _humanTeam);

            if (numberOfAlliesWithDamagedShields > 1)
            {
                double[] lastEventOccursArgs = _chanceService.LastEventOccursArgs;

                double chance = 1.0 / numberOfAlliesWithDamagedShields;

                Assert.AreEqual(numberOfAlliesWithDamagedShields, lastEventOccursArgs.Length);
                for (int i = 0; i < numberOfAlliesWithDamagedShields; ++i)
                {
                    Assert.AreEqual(chance, lastEventOccursArgs[i]);
                }
            }

            Assert.AreEqual(_shieldGuyTeam.Fighters[numberOfAlliesWithDamagedShields - 1], moveWithTarget.Target);
        }
예제 #5
0
        public void Level1ShieldGuy_CorrectlyDeterminesViableMoves_NoShieldMove()
        {
            IronBattleShield shield = new IronBattleShield(3, 0, 0);

            _level1ShieldGuy.SetBattleShield(shield);
            _level1ShieldGuy.BattleShield.DecrementHealth(1);
            _ally1.SetBattleShield(shield);
            _ally2.SetBattleShield(shield);

            _chanceService.PushWhichEventsOccur(0);
            BattleMove returnedMove = _level1ShieldGuy.SelectMove(_shieldGuyTeam, _humanTeam);

            double[] lastEventOccursArgs = _chanceService.LastEventOccursArgs;

            Assert.AreEqual(3, lastEventOccursArgs.Length);
            Assert.AreEqual(0.2, lastEventOccursArgs[0]);
            Assert.AreEqual(0.4, lastEventOccursArgs[1]);
            Assert.AreEqual(0.4, lastEventOccursArgs[2]);

            Assert.AreEqual(BattleMoveType.Attack, returnedMove.MoveType);

            _chanceService.PushWhichEventsOccur(1);
            returnedMove = _level1ShieldGuy.SelectMove(_shieldGuyTeam, _humanTeam);
            ShieldFortifyingMove shieldFortifyingMove = returnedMove as ShieldFortifyingMove;

            Assert.NotNull(shieldFortifyingMove);
            Assert.AreEqual(ShieldFortifyingType.Defense, shieldFortifyingMove.FortifyingType);

            _chanceService.PushWhichEventsOccur(2);
            returnedMove         = _level1ShieldGuy.SelectMove(_shieldGuyTeam, _humanTeam);
            shieldFortifyingMove = returnedMove as ShieldFortifyingMove;
            Assert.NotNull(shieldFortifyingMove);
            Assert.AreEqual(ShieldFortifyingType.Health, shieldFortifyingMove.FortifyingType);
        }
예제 #6
0
        public void IncrementHealth_DoesNotExceedMaxHealth()
        {
            int returnAmount;
            IronBattleShield ironShield = IncrementHealth_Setup(10, 2, 7, out returnAmount);

            Assert.AreEqual(10, ironShield.CurrentHealth);
        }
예제 #7
0
        public void FortifyDefense_ProperlyRaisesDefense([Values(1, 3)] int fortifyAmount)
        {
            IronBattleShield shield = new IronBattleShield(5, 0, 0);

            shield.FortifyDefense(fortifyAmount);

            Assert.AreEqual(fortifyAmount, shield.Defense);
        }
예제 #8
0
        public void DefaultDisplayName_IronBattleShield()
        {
            IronBattleShield shield = new IronBattleShield(1, 0, 0);

            string displayText  = shield.GetDisplayText();
            string expectedText = "an iron battle shield";

            Assert.AreEqual(expectedText, displayText);
        }
예제 #9
0
        private IronBattleShield IncrementHealth_Setup(int maxHealth, int damageAmount, int healAmount, out int returnAmount)
        {
            IronBattleShield ironShield = new IronBattleShield(maxHealth, 0, 0);

            _logger.Subscribe(EventType.ShieldHealed, ironShield);

            ironShield.DecrementHealth(damageAmount);
            returnAmount = ironShield.IncrementHealth(healAmount);

            return(ironShield);
        }
예제 #10
0
        public void OwnerPropertySet_WhenSetToPlayer()
        {
            BattleShield shield = new IronBattleShield(1, 0, 0);

            Assert.AreEqual(null, shield.Owner);

            _humanPlayer1.SetBattleShield(shield);

            Assert.AreEqual(null, shield.Owner);
            Assert.AreEqual(_humanPlayer1, _humanPlayer1.BattleShield.Owner);
        }
예제 #11
0
        public void FortifyDefense_ThrowsFortifyEvent([Values(1, 3)] int fortifyAmount)
        {
            IronBattleShield shield = new IronBattleShield(5, 0, 0);

            _logger.Subscribe(EventType.ShieldFortified, shield);
            shield.FortifyDefense(fortifyAmount);

            List <EventLog> logs = _logger.Logs;

            Assert.AreEqual(1, logs.Count);

            ShieldFortifiedEventArgs e = logs[0].E as ShieldFortifiedEventArgs;

            Assert.NotNull(e);
            Assert.AreEqual(fortifyAmount, e.FortifyAmount);
        }
예제 #12
0
        public void Level1ShieldGuy_CorrectlyDeterminesViableMoves_AllMovesAreViable()
        {
            _chanceService.PushWhichEventsOccur(0); //have to set this up to prevent error

            const int        shieldDefense = 2;
            IronBattleShield shield        = new IronBattleShield(2, shieldDefense, 0);

            _ally1.SetBattleShield(shield);
            _ally1.BattleShield.DecrementHealth(shieldDefense + 1);

            _level1ShieldGuy.SelectMove(_shieldGuyTeam, _humanTeam);

            double[] lastEventOccursArgs = _chanceService.LastEventOccursArgs;

            Assert.AreEqual(4, lastEventOccursArgs.Length);
            Assert.AreEqual(0.2, lastEventOccursArgs[0]);
            Assert.AreEqual(0.4, lastEventOccursArgs[1]);
            Assert.AreEqual(0.2, lastEventOccursArgs[2]);
            Assert.AreEqual(0.2, lastEventOccursArgs[3]);

            _chanceService.PushWhichEventsOccur(0);
            BattleMove returnedMove = _level1ShieldGuy.SelectMove(_shieldGuyTeam, _humanTeam);

            Assert.AreEqual(BattleMoveType.Attack, returnedMove.MoveType);


            _chanceService.PushWhichEventsOccur(1);
            returnedMove = _level1ShieldGuy.SelectMove(_shieldGuyTeam, _humanTeam);
            Assert.IsTrue(returnedMove is ShieldMove);


            _chanceService.PushWhichEventsOccur(2);
            returnedMove = _level1ShieldGuy.SelectMove(_shieldGuyTeam, _humanTeam);
            ShieldFortifyingMove shieldFortifyingMove = returnedMove as ShieldFortifyingMove;

            Assert.NotNull(shieldFortifyingMove);
            Assert.AreEqual(ShieldFortifyingType.Defense, shieldFortifyingMove.FortifyingType);


            _chanceService.PushWhichEventsOccur(3);
            returnedMove         = _level1ShieldGuy.SelectMove(_shieldGuyTeam, _humanTeam);
            shieldFortifyingMove = returnedMove as ShieldFortifyingMove;
            Assert.NotNull(shieldFortifyingMove);
            Assert.AreEqual(ShieldFortifyingType.Health, shieldFortifyingMove.FortifyingType);
        }
예제 #13
0
        public void IncrementHealth_FiresHealedEvent([Values(1, 2)] int healAmount)
        {
            int returnAmount;
            IronBattleShield ironShield = IncrementHealth_Setup(10, healAmount + 1, healAmount, out returnAmount);

            List <EventLog> logs = _logger.Logs;

            Assert.AreEqual(1, logs.Count);
            EventLog log = logs[0];

            Assert.AreEqual(EventType.ShieldHealed, log.Type);
            Assert.AreEqual(ironShield, log.Sender);

            ShieldHealedEventArgs e = log.E as ShieldHealedEventArgs;

            Assert.NotNull(e);
            Assert.AreEqual(healAmount, e.HealedAmount);
        }
예제 #14
0
        public void SetBattleShieldMethod_AppropriatelyRaisesBattleShieldAddedEvent()
        {
            IBattleShield shield = new IronBattleShield(1, 0, 0);

            _fighter.SetBattleShield((BattleShield)shield);

            List <EventLog> logs = _logger.Logs;

            Assert.AreEqual(1, logs.Count);

            EventLog log = logs[0];

            Assert.AreEqual(EventType.ShieldAdded, log.Type);

            ShieldAddedEventArgs e = log.E as ShieldAddedEventArgs;

            Assert.NotNull(e);
            Assert.IsTrue(shield.AreEqual(e.BattleShield));
        }
예제 #15
0
        private static BattleShield GetShieldFromType(Type t)
        {
            BattleShield ret = null;

            if (t == typeof(IronBattleShield))
            {
                ret = new IronBattleShield(1, 0, 0);
            }
            else if (t == typeof(ElementalBattleShield))
            {
                ret = new ElementalBattleShield(1, 0, 0, MagicType.Fire);
            }
            else
            {
                throw new NotImplementedException($"GetShieldFromType() does not yet know how to handle type '{t}'");
            }

            return(ret);
        }
예제 #16
0
        public void ShieldBusterMove_CannotBustShieldsWithHigherShieldBusterDefense()
        {
            IronBattleShield shield = new IronBattleShield(5, 5, 3, 2);

            _enemy.SetBattleShield(shield);

            Assert.NotNull(_enemy.BattleShield);

            ShieldBusterMove shieldBuster = new ShieldBusterMove("shieldBuster", TargetType.SingleEnemy, null, 1);

            _humanFighter.SetMove(shieldBuster, 1);
            _humanFighter.SetMoveTarget(_enemy);
            _humanFighter.SetMove(_runawayMove);

            _enemy.SetMove(_doNothingMove);

            _battleManager.Battle(_humanTeam, _enemyTeam);

            Assert.NotNull(_enemy.BattleShield);
        }
예제 #17
0
        public void BattleManager_CorrectlyPrintsMessages_TargetHasShield([Values("eats pudding", null)] string executionMessage)
        {
            const int        shieldDefense    = 5;
            const int        shieldHealth     = 1;
            IronBattleShield shield           = new IronBattleShield(shieldHealth, shieldDefense, 0);
            ShieldBusterMove shieldBusterMove = new ShieldBusterMove("foo", TargetType.SingleEnemy, executionMessage);

            _humanFighter.SetSpeed(1);
            _humanFighter.SetMove(shieldBusterMove, 1);
            _humanFighter.SetMove(_runawayMove);
            _humanFighter.SetMoveTarget(_enemy);

            _enemy.SetBattleShield(shield);
            //_logger.SubscribeAll(_enemy.BattleShield);
            _enemy.SetMove(_doNothingMove);

            BattleManagerBattleConfiguration config = new BattleManagerBattleConfiguration
            {
                ShowIntroAndOutroMessages = false
            };

            _battleManager.Battle(_humanTeam, _enemyTeam, config: config);

            MockOutputMessage[] outputs = _output.GetOutputs();

            int expectedLength = 1;

            if (executionMessage != null)
            {
                expectedLength++;
            }
            Assert.AreEqual(expectedLength, outputs.Length);

            int i = 0;

            if (executionMessage != null)
            {
                Assert.AreEqual($"{_humanFighter.DisplayName} {executionMessage}!\n", outputs[i++].Message);
            }
            Assert.AreEqual($"{_enemy.DisplayName}'s shield was destroyed!\n", outputs[i].Message);
        }
예제 #18
0
        public void BattleManager_CorrectlyCalculatesMagicalDamageForShield([Values(MagicType.Fire, MagicType.Ice)] MagicType spellMagicType)
        {
            int shieldResistance = 10;

            IronBattleShield shield = new IronBattleShield((shieldResistance * 2) + 1, 0, shieldResistance);

            _humanPlayer1.SetBattleShield(shield);

            _logger.SubscribeAll(_humanPlayer1.BattleShield);

            _humanPlayer1.SetMagicResistance(shieldResistance);
            _humanPlayer1.SetStrength(_enemyPlayer1.MaxHealth + _enemyPlayer1.Defense);
            _humanPlayer1.SetMove(_basicAttackMove);
            _humanPlayer1.SetMoveTarget(_enemyPlayer1);

            _enemyPlayer1.SetSpeed(1);
            _enemyPlayer1.SetMagicStrength(shieldResistance * 2);
            Spell spell = new Spell("foo", spellMagicType, SpellType.Attack, TargetType.SingleEnemy, 0, 0);

            _enemyPlayer1.AddSpell(spell);
            _enemyPlayer1.SetMove(spell);

            _chanceService.PushEventsOccur(true, false); //attack hits, not misses

            _humanTeam = new Team(_menuManager, _humanPlayer1);
            _enemyTeam = new Team(_menuManager, _enemyPlayer1);

            _battleManager.Battle(_humanTeam, _enemyTeam);

            List <EventLog> logs = _logger.Logs;

            Assert.AreEqual(1, logs.Count);

            MagicalDamageTakenEventArgs e = logs[0].E as MagicalDamageTakenEventArgs;

            Assert.NotNull(e);
            Assert.AreEqual(shieldResistance, e.Damage);
            Assert.AreEqual(spellMagicType, e.MagicType);
        }
예제 #19
0
        public void Level1ShieldGuy_SelectsAppropriateTarget_ShieldFortifyingMove([Values(1, 2, 3)] int numberOfAlliesWithShield)
        {
            int selectedTargetIndex = numberOfAlliesWithShield - 1;
            IronBattleShield shield = new IronBattleShield(5, 0, 0);

            for (int i = 0; i < numberOfAlliesWithShield; ++i)
            {
                _shieldGuyTeam.Fighters[i].SetBattleShield(shield);
            }

            int selectedMoveIndex = numberOfAlliesWithShield == 3 ? 1 : 2;

            _chanceService.PushWhichEventsOccur(selectedMoveIndex);

            if (numberOfAlliesWithShield > 1)
            {
                _chanceService.PushWhichEventsOccur(selectedTargetIndex); //Select the target
            }
            BattleMoveWithTarget moveWithTarget = _level1ShieldGuy.SetupMove(_shieldGuyTeam, _humanTeam);

            if (numberOfAlliesWithShield > 1)
            {
                double[] lastEventOccursArgs = _chanceService.LastEventOccursArgs;

                double chance = 1.0 / numberOfAlliesWithShield;

                Assert.AreEqual(numberOfAlliesWithShield, lastEventOccursArgs.Length);
                for (int i = 0; i < numberOfAlliesWithShield; ++i)
                {
                    Assert.AreEqual(chance, lastEventOccursArgs[i]);
                }
            }

            IFighter expectedTarget = _shieldGuyTeam.Fighters[selectedTargetIndex];

            Assert.AreEqual(expectedTarget, moveWithTarget.Target);
        }
예제 #20
0
        public void BattleManager_CorrectlySubscribesToAddedShieldsEvents()
        {
            BattleShield shield     = new IronBattleShield(1, 0, 0);
            ShieldMove   shieldMove = new ShieldMove("foo", TargetType.Self, null, shield);

            _humanPlayer1.SetMove(shieldMove, 1);
            _humanPlayer1.SetMove(_doNothingMove);
            _humanPlayer1.SetMoveTarget(_humanPlayer1);
            _humanPlayer1.SetSpeed(1);

            _enemyPlayer1.SetMove(_basicAttackMove);
            _enemyPlayer1.SetStrength(1000);
            _enemyPlayer1.SetMoveTarget(_humanPlayer1);
            _chanceService.PushEventsOccur(true, false, true, false); //two attacks to end the battle, both hit, neither are crits

            _logger.Subscribe(EventType.ShieldAdded, _humanPlayer1);

            _humanTeam = new Team(_menuManager, _humanPlayer1);
            _enemyTeam = new Team(_menuManager, _enemyPlayer1);

            BattleManagerBattleConfiguration config = new BattleManagerBattleConfiguration
            {
                ShowIntroAndOutroMessages = false,
                ShowDeathMessages         = false,
                ShowExpAndLevelUpMessages = false,
                ShowShieldAddedMessage    = false
            };

            _battleManager.Battle(_humanTeam, _enemyTeam, config: config);

            MockOutputMessage[] outputs = _output.GetOutputs();

            int expectedOutputCount = 2 * 2 + 1; //"enemy attacks!" and "it did ____ damage" message for both attacks, as well as "shield destroyed!"

            Assert.AreEqual(expectedOutputCount, outputs.Length);
        }
예제 #21
0
        public void BattleManager_CorrectlyUnsubscribes_OnceShieldRemovedFromPlayer()
        {
            BattleShield shield     = new IronBattleShield(1, 0, 0);
            ShieldMove   shieldMove = new ShieldMove("foo", TargetType.Self, null, shield);

            _humanPlayer1.SetMove(shieldMove, 1);
            _humanPlayer1.SetMove(_doNothingMove);
            _humanPlayer1.SetMoveTarget(_humanPlayer1);
            _humanPlayer1.SetSpeed(1);

            _enemyPlayer1.SetMove(_basicAttackMove);
            _enemyPlayer1.SetStrength(1000);
            _enemyPlayer1.SetMoveTarget(_humanPlayer1);
            _chanceService.PushEventsOccur(true, false, true, false); //two attacks to end the battle, both hit, neither are crits

            _logger.Subscribe(EventType.ShieldAdded, _humanPlayer1);

            _humanTeam = new Team(_menuManager, _humanPlayer1);
            _enemyTeam = new Team(_menuManager, _enemyPlayer1);

            _battleManager.Battle(_humanTeam, _enemyTeam);

            int outputCountBefore = _output.GetOutputs().Length;

            ShieldAddedEventArgs e = _logger.Logs[0].E as ShieldAddedEventArgs;

            Assert.NotNull(e);

            BattleShield shieldCopy = e.BattleShield;

            shieldCopy.OnDamageTaken(new PhysicalDamageTakenEventArgs(7));

            int outputCountAfter = _output.GetOutputs().Length;

            Assert.AreEqual(outputCountBefore, outputCountAfter);
        }
예제 #22
0
        public static BattleMove Get(BattleMoveType type, string description = null)
        {
            BattleMove ret;
            var        notFoundException = new ArgumentException($"No move exists with type {type} and description '{description}'!");

            switch (type)
            {
            case BattleMoveType.Attack:
                switch (description)
                {
                case null:
                case "attack":
                    ret = Attack;
                    break;

                case "goblin punch":
                    ret = new AttackBattleMove(description, TargetType.SingleEnemy, 100, 75, executionText: $"throws a goblin punch at {Globals.TargetReplaceText}");
                    break;

                case "feint":
                    NotEvadedBattleCondition       notEvadedCondition   = new NotEvadedBattleCondition();
                    AttackBoostBattleMoveEffect    attackBoostEffect    = new AttackBoostBattleMoveEffect(0.25, notEvadedCondition);
                    CannotBeEvadedBattleMoveEffect cannotBeEvadedEffect = new CannotBeEvadedBattleMoveEffect();
                    BattleMoveEffect[]             effects = { attackBoostEffect, cannotBeEvadedEffect, UnconditionalNeverMissEffect };
                    ret = new AttackBattleMove(description, TargetType.SingleEnemy, 100, 0, executionText: "attacks [target] with a feint", effects: effects);
                    break;

                default:
                    throw notFoundException;
                }
                break;

            case BattleMoveType.ConditionalPowerAttack:
                ret = new ConditionalPowerAttackBattleMove("malevolence attack", TargetType.SingleEnemy, 100, 10, executionText: "unleashes their dark power!");
                break;

            case BattleMoveType.Runaway:
                ret = Runaway;
                break;

            case BattleMoveType.DoNothing:
                switch (description)
                {
                case null:
                    ret = DoNothing;
                    break;

                case "goblin punch charge":
                    ret = new DoNothingMove("prepares to unleash its fury");
                    break;

                default:
                    throw notFoundException;
                }
                break;

            case BattleMoveType.Special:
                switch (description)
                {
                case "dark energy gather":
                    ret = new SpecialMove(description, BattleMoveType.Special, TargetType.Self, "gathers dark energy");
                    break;

                default:
                    throw notFoundException;
                }
                break;

            case BattleMoveType.MultiTurn:
                if (description == "goblin punch")
                {
                    ret = new MultiTurnBattleMove(description, TargetType.SingleEnemy,
                                                  Get(BattleMoveType.DoNothing, "goblin punch charge"),
                                                  Get(BattleMoveType.Attack, description));
                }
                else
                {
                    throw notFoundException;
                }
                break;

            case BattleMoveType.Dance:
                switch (description)
                {
                default:
                    throw notFoundException;

                case "fire dance":
                    ret = new DanceMove(description, TargetType.OwnTeam, 2, DanceEffectType.Fire,
                                        new List <FieldEffect>
                    {
                        new MagicMultiplierFieldEffect(TargetType.OwnTeam, "fire dance", MagicType.Fire, (4.0 / 3.0))
                    },
                                        new DoNothingMove("performs the fire dance"),
                                        new DoNothingMove("continues to perform the fire dance"));
                    break;

                case "water dance":
                    ret = new DanceMove(description, TargetType.OwnTeam, 2, DanceEffectType.Water,
                                        new List <FieldEffect>
                    {
                        new MagicMultiplierFieldEffect(TargetType.OwnTeam, "water dance", MagicType.Water, (4.0 / 3.0))
                    },
                                        new DoNothingMove("performs the water dance"),
                                        new DoNothingMove("continues to perform the water dance"));
                    break;

                case "wind dance":
                    ret = new DanceMove(description, TargetType.OwnTeam, 2, DanceEffectType.Wind,
                                        new List <FieldEffect>
                    {
                        new MagicMultiplierFieldEffect(TargetType.OwnTeam, "wind dance", MagicType.Wind, (4.0 / 3.0))
                    },
                                        new DoNothingMove("performs the wind dance"),
                                        new DoNothingMove("continues to perform the wind dance"));
                    break;

                case "earth dance":
                    ret = new DanceMove(description, TargetType.OwnTeam, 2, DanceEffectType.Earth,
                                        new List <FieldEffect>
                    {
                        new MagicMultiplierFieldEffect(TargetType.OwnTeam, "earth dance", MagicType.Earth, (4.0 / 3.0))
                    },
                                        new DoNothingMove("performs the earth dance"),
                                        new DoNothingMove("continues to perform the earth dance"));
                    break;

                case "heart dance":
                    ret = new DanceMove(description, TargetType.OwnTeam, 2, DanceEffectType.Heart,
                                        new List <FieldEffect>
                    {
                        new StatMultiplierFieldEffect(TargetType.OwnTeam, "heart dance", StatType.Defense, (5 / 100.0))
                    },
                                        new DoNothingMove("performs the heart dance"),
                                        new DoNothingMove("continues to perform the heart dance"));
                    break;

                case "soul dance":
                    ret = new DanceMove(description, TargetType.OwnTeam, 2, DanceEffectType.Soul,
                                        new List <FieldEffect>
                    {
                        new MagicMultiplierFieldEffect(TargetType.OwnTeam, "soul dance", MagicType.All, (5 / 100.0))
                    },
                                        new DoNothingMove("performs the soul dance"),
                                        new DoNothingMove("continues to perform the soul dance"));
                    break;

                case "mind dance":
                    ret = new DanceMove(description, TargetType.OwnTeam, 2, DanceEffectType.Mind,
                                        new List <FieldEffect>
                    {
                        new StatMultiplierFieldEffect(TargetType.OwnTeam, "mind dance", StatType.Evade, (5.0 / 100.0), 1)
                    },
                                        new DoNothingMove("performs the mind dance"),
                                        new DoNothingMove("continues to perform the mind dance"));
                    break;

                case "danger dance":
                    ret = new DanceMove(description, TargetType.OwnTeam, 2, DanceEffectType.Danger,
                                        new List <FieldEffect>
                    {
                        new StatMultiplierFieldEffect(TargetType.OwnTeam, "danger dance", StatType.Strength, (5.0 / 100.0), 1)
                    },
                                        new DoNothingMove("performs the danger dance"),
                                        new DoNothingMove("continues to perform the danger dance"));
                    break;
                }
                break;

            case BattleMoveType.Status:
                Status status;
                switch (description)
                {
                default:
                    throw notFoundException;

                case "warrior's cry":
                    status = new StatMultiplierStatus(4, StatType.Strength, 2);
                    ret    = new StatusMove(description, TargetType.Self, status, "unleashes their warrior cry!");
                    break;

                case "evade":
                    status = new AutoEvadeStatus(1, false);
                    ret    = new StatusMove(description, TargetType.Self, status, "takes a ready stance", 1);
                    break;

                case "evadeAndCounter":
                    status = new AutoEvadeStatus(1, true);
                    ret    = new StatusMove(description, TargetType.Self, status, "prepares to counter", 1);
                    break;

                case "dark fog":
                    status = new BlindStatus(2);
                    ret    = new StatusMove(description, TargetType.SingleEnemy, status, $"draws a dark fog about {Globals.TargetReplaceText}", accuracy: 60);
                    break;
                }
                break;

            case BattleMoveType.Shield:
                switch (description)
                {
                case "iron shield":
                    IBattleShield shield = new IronBattleShield(5, 2, 0);
                    ret = new ShieldMove(description, TargetType.SingleAllyOrSelf, "created an iron shield", shield);
                    break;

                default:
                    throw notFoundException;
                }
                break;

            case BattleMoveType.ShieldFortifier:
                switch (description)
                {
                case "heal shield":
                    ret = new ShieldFortifyingMove(description, TargetType.SingleAllyOrSelf, $"healed {Globals.TargetReplaceText}'s shield", ShieldFortifyingType.Health, 5);
                    break;

                case "strengthen shield":
                    ret = new ShieldFortifyingMove(description, TargetType.SingleAllyOrSelf, $"strengthened {Globals.TargetReplaceText}'s shield", ShieldFortifyingType.Defense, 5);
                    break;

                default:
                    ret = null;
                    break;
                }
                break;

            case BattleMoveType.ShieldBuster:
                if (string.IsNullOrEmpty(description))
                {
                    description = "Shield buster";
                }
                switch (description)
                {
                case "Shield buster":
                    ret = new ShieldBusterMove(description, TargetType.SingleEnemy, "uses the shield buster on [target]");
                    break;

                case "Super shield buster":
                    ret = new ShieldBusterMove(description, TargetType.SingleEnemy, "uses the super shield buster on [target]", 1);
                    break;

                default:
                    throw notFoundException;
                }

                break;

            case BattleMoveType.BellMove:
                switch (description)
                {
                case "seal shade":
                default:
                    ret = Get(BellMoveType.SealMove);
                    break;

                case "control shade":
                    ret = Get(BellMoveType.ControlMove);
                    break;
                }
                break;

            case BattleMoveType.AbsorbShade:
                ret = new ShadeAbsorbingMove("absorb shade", $"has given into malice, targetting {Globals.TargetReplaceText}!");
                break;

            default:
                throw notFoundException;
            }

            return(ret);
        }