public void CastEggs_Level3Spells([Range(0, 2)] int level3EggIndex) { Tuple <MagicType, string> level3EggCombo = _level3Eggs[level3EggIndex]; string spellName = level3EggCombo.Item2; MagicType spellType = level3EggCombo.Item1; int typeIndex = Globals.EggMagicTypes.ToList().IndexOf(spellType); Spell spell = SpellFactory.GetSpell(spellName); int damage = spell.Power + _chicken.MagicStrength; _hero.SetHealth(damage + 1); _hero.SetMove(_doNothingMove, 4); _hero.SetMove(_runawayMove); _hero.SetMoveTarget(_hero); _sidekick.SetMove(_doNothingMove); _sidekick.SetMoveTarget(_sidekick); //first 3 determine the egg type, the fourth is who the chicken is targetting _chanceService.PushWhichEventsOccur(typeIndex, typeIndex, typeIndex, 0); _battleManager.SuppressBattleIntroAndOutroMessages(); _battleManager.Battle(_humanTeam, _enemyTeam); var outputs = _output.GetOutputs(); Assert.AreEqual(5, outputs.Length); // 1 for each egg lay, 1 for actual attack, 1 to output how much damage the fighter took Assert.AreEqual($"{_castPrefix}{spellName}!\n", outputs[3].Message); Assert.AreEqual(1, _hero.CurrentHealth); }
public void CorrectlySetsBattleMoves_UponEnteringRegion() { BattleMove superAttack = new AttackBattleMove("foo", TargetType.SingleEnemy, 80, 20, 5); BattleMove fastAttack = new AttackBattleMove("bar", TargetType.SingleEnemy, 100, 0, 0, 2); Assert.False(_humanFighter1.AllSpecialMoves.Contains(superAttack)); Assert.False(_humanFighter1.AllSpecialMoves.Contains(fastAttack)); TeamConfiguration bossConfiguration = new TeamConfiguration(new EnemyConfiguration(FighterType.Egg, 1)); SubRegion subRegion = new SubRegion(WorldSubRegion.Fields, 1, new [] { new ChanceEvent <int>(1, 1), }, new[] { FighterType.Egg }, new BattlefieldConfiguration(bossConfiguration, null)); SubRegion[] subRegions = { subRegion }; Region fakeFieldsRegion = new Region(WorldRegion.Fields, new[] { superAttack, fastAttack }, subRegions); _regionFactory.SetRegion(WorldRegion.Fields, fakeFieldsRegion); _teamFactory.PushTeams(_oneEnemyTeam); _regionManager = GetRegionManager(); _humanFighter1.SetMove(_runawayMove); _humanFighter1.SetMoveTarget(_humanFighter1); _humanFighter2.SetMove(_doNothingMove); _regionManager.Battle(_battleManager, _humanTeam); Assert.True(_humanFighter1.AllSpecialMoves.Contains(superAttack)); Assert.True(_humanFighter1.AllSpecialMoves.Contains(fastAttack)); }
public void BattleManager_CorrectlyPrintsDamageOutput() { int damage = (_shield.MaxHealth + _shield.Defense) - 1; _enemyPlayer1.SetMove(_basicAttackMove); _enemyPlayer1.SetStrength(damage); _enemyPlayer1.SetMoveTarget(_humanPlayer1); _chanceService.PushEventsOccur(true, false); //attack hits, not crit _humanPlayer1.SetBattleShield(_shield as BattleShield); BattleShield fighterShield = _humanPlayer1.BattleShield; _humanPlayer1.SetMove(_doNothingMove, 1); _humanPlayer1.SetMove(_runawayMove); _humanPlayer1.SetMoveTarget(_humanPlayer1); _humanTeam = new Team(_menuManager, _humanPlayer1); _enemyTeam = new Team(_menuManager, _enemyPlayer1); BattleManagerBattleConfiguration config = new BattleManagerBattleConfiguration { ShowIntroAndOutroMessages = false }; _battleManager.Battle(_humanTeam, _enemyTeam, config: config); MockOutputMessage[] outputs = _output.GetOutputs(); Assert.AreEqual(2, outputs.Length); //enemy attacks and shield took damage message MockOutputMessage output = outputs[1]; Assert.AreEqual($"{fighterShield.Owner.DisplayName}'s {fighterShield.GetDisplayText(false)} took {damage} damage!\n", output.Message); }
public void MoveWithNeverMissEffect_BypassesAccuracyCheck() { _human.SetMove(_attackWithNeverMissEffect); _human.SetMoveTarget(_enemy); _chanceService.PushEventsOccur(false); //just check the crit _enemy.SetMove(_doNothingMove); //Will throw if both hit and crit chances checked Assert.DoesNotThrow(() => _battleManager.Battle(_humanTeam, _enemyTeam)); }
public void StatusTechnique_AppropriatelyAssignsStatusToTarget() { StatMultiplierStatus status = new StatMultiplierStatus(3, StatType.Strength, 1.5); StatusMove statusMove = new StatusMove("raise attack", TargetType.SingleAlly, status); TestHumanFighter fighter2 = new TestHumanFighter("foo 2", 1); _humanTeam = new TestTeam(_humanFighter, fighter2); _humanFighter.SetSpeed(1); _humanFighter.SetMove(statusMove); _chanceService.PushEventOccurs(true); _humanFighter.SetMoveTarget(fighter2); _logger.Subscribe(EventType.StatusAdded, fighter2); BattleMove attack = MoveFactory.Get(BattleMoveType.Attack); fighter2.SetStrength(2); fighter2.SetMove(attack); fighter2.SetMoveTarget(_enemy); _chanceService.PushEventOccurs(true); //attack hits _chanceService.PushEventOccurs(false); //attack is not a crit //enemy won't be killed if the status isn't assigned to _fighter2 _enemy.SetHealth(3); _enemy.SetMove(_doNothing); _enemy.SetMoveTarget(_enemy); //once Statuses are removed after battle, won't be able to _battleManager.Battle(_humanTeam, _enemyTeam); List <EventLog> logs = _logger.Logs; Assert.AreEqual(1, logs.Count); EventLog log = logs[0]; Assert.AreEqual(EventType.StatusAdded, log.Type); StatusAddedEventArgs e = log.E as StatusAddedEventArgs; Assert.NotNull(e); Assert.IsTrue(status.AreEqual(e.Status)); }
public void BlindnessStatus_CorrectlyReducesMoveAccuracy([Values(10, 60, 100)] int orignalAccuracy) { _humanFighter.AddStatus(_blindnessStatus); AttackBattleMove attack = new AttackBattleMove("foo", TargetType.SingleEnemy, orignalAccuracy, 0); _humanFighter.SetMove(attack, 1); _humanFighter.SetMoveTarget(_enemy); _chanceService.PushEventOccurs(false); //attack misses _humanFighter.SetMove(_runawayMove); _enemy.SetMove(_doNothing); _battleManager.Battle(_humanTeam, _enemyTeam); double accuracyAsPercent = orignalAccuracy / 100.0; double expectedModifiedAccuracy = accuracyAsPercent / 3; Assert.AreEqual(expectedModifiedAccuracy, _chanceService.LastChanceVals[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); }
public void TestUndoDebuffsEffect_IndividualEffect() { StatMultiplierStatus lowerAttackStatus = new StatMultiplierStatus(3, StatType.Strength, 1.0 / 3); StatusMove lowerEnemyAttackMove = new StatusMove("raise attack", TargetType.SingleEnemy, lowerAttackStatus); UndoDebuffsStatus undoDebuffStatus = new UndoDebuffsStatus(1); StatusMove undoDebuffMove = new StatusMove("reset stats", TargetType.SingleAlly, undoDebuffStatus); TestHumanFighter fighter2 = new TestHumanFighter("foo 2", 1); _humanTeam = new TestTeam(_humanFighter, fighter2); //enemy won't be killed if the status isn't assigned to _fighter2 _enemy.SetHealth(3); _enemy.SetSpeed(2); _enemy.SetMove(lowerEnemyAttackMove); _chanceService.PushEventOccurs(true); //status hits _enemy.SetMoveTarget(fighter2); _humanFighter.SetSpeed(1); _humanFighter.SetMove(undoDebuffMove); _chanceService.PushEventOccurs(true); //status hits _humanFighter.SetMoveTarget(fighter2); _logger.Subscribe(EventType.StatusAdded, fighter2); _logger.Subscribe(EventType.StatusRemoved, fighter2); BattleMove attack = MoveFactory.Get(BattleMoveType.Attack); fighter2.SetStrength(3); fighter2.SetMove(attack); fighter2.SetMoveTarget(_enemy); _chanceService.PushEventOccurs(true); //attack hits _chanceService.PushEventOccurs(false); //attack is not a crit //once Statuses are removed after battle, won't be able to _battleManager.Battle(_humanTeam, _enemyTeam); List <EventLog> logs = _logger.Logs; Assert.AreEqual(2, logs.Count); EventLog log = logs[1]; Assert.AreEqual(EventType.StatusRemoved, log.Type); StatusRemovedEventArgs e = log.E as StatusRemovedEventArgs; Assert.NotNull(e); Assert.IsTrue(lowerAttackStatus.AreEqual(e.Status)); }
public void BattleManager_CorrectlyExecutes_ShieldFortifyingMove([Values(ShieldFortifyingType.Defense, ShieldFortifyingType.Health)] ShieldFortifyingType shieldFortifyingType) { ElementalBattleShield shield = new ElementalBattleShield(10, 5, 0, MagicType.Fire); shield.DecrementHealth(5); _humanFighter.SetBattleShield(shield); IBattleShield copiedShield = _humanFighter.BattleShield; ShieldFortifyingMove shieldFortifyingMove = new ShieldFortifyingMove("foo", TargetType.Self, null, shieldFortifyingType, 5); _humanFighter.SetMove(shieldFortifyingMove, 1); _humanFighter.SetMove(_runawayMove); _humanFighter.SetMoveTarget(_humanFighter); _enemy.SetMove(_doNothing); _battleManager.Battle(_humanTeam, _enemyTeam); Assert.NotNull(copiedShield); int actualValue = shieldFortifyingType == ShieldFortifyingType.Defense ? copiedShield.Defense : copiedShield.CurrentHealth; Assert.AreEqual(10, actualValue); }
public void BattleManager_AppropriatelyDisplaysAbsorbMessage() { _humanFighter.SetStrength(_shade1.MaxHealth + _shade1.Defense); _humanFighter.SetMove(_basicAttack, 1); _humanFighter.SetMoveTarget(_shade1); _humanFighter.SetMove(_runawayMove); _chanceService.PushAttackHitsNotCrit(); //which moves will be selected by the shades _chanceService.PushWhichEventsOccur(_malevolenceChargeIndex, _malevolenceChargeIndex, _malevolenceChargeIndex); _chanceService.PushWhichEventsOccur(0, 0); //first is which remaining shade absorbs the fallen shade, second is which stat is boosted //define the expected string here, since the shade's display name will be updated after the absorption string expectedAbsorbMessage = $"{_shade1.DisplayName}'s essence was absorbed by {_shade2.DisplayName}!\n"; _battleManager.Battle(_humanTeam, _shadeTeam, null, new SilentBattleConfiguration()); MockOutputMessage[] outputs = _output.GetOutputs(); MockOutputMessage absorbOutputMessage = outputs.FirstOrDefault(o => o.Message == expectedAbsorbMessage); Assert.NotNull(absorbOutputMessage); }
public void MoveWithCannotBeEvadedEffect_HitsOpponentThatEvaded() { CannotBeEvadedBattleMoveEffect cannotBeEvadedEffect = new CannotBeEvadedBattleMoveEffect(); AttackBattleMove noEvadeAttack = new AttackBattleMove("foo", TargetType.SingleEnemy, 100, 10, effects: cannotBeEvadedEffect); _human.SetMove(noEvadeAttack, 1); _human.SetMove(_runawayMove); _human.SetMoveTarget(_enemy); _chanceService.PushAttackHitsNotCrit(); //attack hits, not a crit AutoEvadeStatus autoEvadeStatus = new AutoEvadeStatus(1, false); _enemy.AddStatus(autoEvadeStatus); _enemy.SetMove(_doNothingMove); _enemy.SetHealth(_human.Strength + 1); _battleManager.Battle(_humanTeam, _enemyTeam); Assert.AreEqual(1, _enemy.CurrentHealth, "attack should have hit even though enemy had an AutoEvade status!"); }
public void MoveWithAttackBoostEffect_CorrectlyCalculatesDamage([Values(0.25, 0.5, 2.0, 3.0)] double multiplier) { const int humanStrength = 4; AttackBoostBattleMoveEffect attackBoostEffect = new AttackBoostBattleMoveEffect(multiplier); AttackBattleMove attackBoostAttack = new AttackBattleMove("foo", TargetType.SingleEnemy, 100, 10, effects: attackBoostEffect); _human.SetStrength(humanStrength); _human.SetMove(attackBoostAttack, 1); _human.SetMove(_runawayMove); _human.SetMoveTarget(_enemy); _chanceService.PushAttackHitsNotCrit(); //attack hits, not a crit _enemy.SetMove(_doNothingMove); _enemy.SetHealth(100); _battleManager.Battle(_humanTeam, _enemyTeam); int expectedDamage = (int)(humanStrength * multiplier); int expectedRemainingHealth = 100 - expectedDamage; int actualDamage = 100 - _enemy.CurrentHealth; Assert.AreEqual(expectedRemainingHealth, _enemy.CurrentHealth, $"attack should have hit for {expectedDamage} damage, isntead of {actualDamage}!"); }
public void RestoreHealthEffect_AppropriatelyExecuted_AttackHits() { int initialHealth = 100 - _restoreHealthEffect.Percentage; _human.SetHealth(100, initialHealth); _human.SetMana(100, 0); _human.SetMove(_attackWithRestoreHealthEffect); _human.SetMoveTarget(_enemy); _chanceService.PushEventsOccur(true, false); //attack hits, not a crit _enemy.SetMove(_doNothingMove); _enemy.SetMoveTarget(_enemy); _battleManager.Battle(_humanTeam, _enemyTeam); Assert.AreEqual(_human.MaxHealth, _human.CurrentHealth, "humman player's health should have been restored when the attack hit!"); Assert.AreEqual(0, _human.CurrentMana, "humman player's mana should have been unaffected by the restore effect!"); }
public void MultipleEffects_OnlyEffectsWhoseConditionsAreMet_AreFired([Values(10, 20)] int restoreAmount) { _human.SetHealth(100, 10); _human.SetMana(100, 10); _restoreManaEffect = new RestorationBattleMoveEffect(RestorationType.Mana, restoreAmount, BattleMoveEffectActivationType.OnAttackHit, new DanceBattleCondition(DanceEffectType.Soul)); _restoreHealthEffect = new RestorationBattleMoveEffect(RestorationType.Health, restoreAmount, BattleMoveEffectActivationType.OnAttackHit, new DanceBattleCondition(DanceEffectType.Fire)); BattleMove attackWithRestoreEffects = new AttackBattleMove("", TargetType.SingleEnemy, 100, 0, effects: new BattleMoveEffect[] { _restoreManaEffect, _restoreHealthEffect }); _human.SetMove(attackWithRestoreEffects); _human.SetMoveTarget(_enemy); _chanceService.PushAttackHitsNotCrit(); //attack hits, not a crit TestHumanFighter dancer = (TestHumanFighter)TestFighterFactory.GetFighter(TestFighterType.TestHuman, 1, "dancer"); TestDanceMove danceMove = new TestDanceMove("bar", TargetType.Field, 2); danceMove.SetDanceEffect(DanceEffectType.Fire); danceMove.AddMove(_doNothingMove); dancer.SetSpeed(1); dancer.SetMove(danceMove); dancer.SetMoveTarget(dancer); _humanTeam.Add(dancer, false); _enemy.SetMove(_doNothingMove); _enemy.SetMoveTarget(_enemy); _battleManager.Battle(_humanTeam, _enemyTeam); int expectedCurrentAmount = 10 + restoreAmount; Assert.AreEqual(10, _human.CurrentMana, "humman player's mana should not have been restored, the dance condition wasn't met!"); Assert.AreEqual(expectedCurrentAmount, _human.CurrentHealth, $"humman player's health should have been restored by {restoreAmount} when the attack hit!"); }
private void PhysicalDamageEvent_Setup(int expectedDamage, bool showPhysicalDamageMessages) { Team mixedPlayerTeam = new Team(_menuManager, _humanPlayer1, _enemyPlayer1); TestEnemyFighter enemy3 = (TestEnemyFighter)TestFighterFactory.GetFighter(TestFighterType.TestEnemy, 1); Team enemyTeam = new Team(_menuManager, _enemyPlayer2, enemy3); _humanPlayer1.SetSpeed(2); _humanPlayer1.SetStrength(expectedDamage); _humanPlayer1.SetMove(_basicAttackMove, 1); _humanPlayer1.SetMove(_runawayMove); _humanPlayer1.SetMoveTarget(_enemyPlayer2); _enemyPlayer2.SetHealth(expectedDamage + 1); _enemyPlayer1.SetSpeed(1); _enemyPlayer1.SetStrength(expectedDamage); _enemyPlayer1.SetMove(_basicAttackMove); _enemyPlayer1.SetMoveTarget(enemy3); enemy3.SetHealth(expectedDamage + 1); _mockChanceService.PushEventsOccur(true, false, true, false); //both attacks hit, neither are crits _logger.Subscribe(EventType.DamageTaken, _enemyPlayer2); _logger.Subscribe(EventType.DamageTaken, enemy3); _enemyPlayer2.SetMove(_doNothingMove); enemy3.SetMove(_doNothingMove); BattleManagerBattleConfiguration config = new BattleManagerBattleConfiguration { ShowIntroAndOutroMessages = false, ShowExpAndLevelUpMessages = false, ShowDeathMessages = false, ShowAttackMessages = false, ShowPhysicalDamageMessages = showPhysicalDamageMessages }; _battleManager.Battle(mixedPlayerTeam, enemyTeam, config: config); }
public void BattleManager_AppropriatelyExecutesDanceTechnique_DoesNotThrowException() { _enemy1.SetMove(_testTechnique); _enemy1.SetSpeed(10); _enemy2.SetMove(_doNothingMove); _human1.SetMove(_basicAttack); _human1.SetMoveTarget(_enemy1); _human1.SetStrength(EnemyDefenseAfterDanceMove + _enemy1.MaxHealth); _human2.SetMove(_basicAttack); _human2.SetMoveTarget(_enemy2); _human2.SetStrength(EnemyDefenseAfterDanceMove + _enemy2.MaxHealth); _chanceService.PushEventsOccur(true, false, true, false); //set up attack hits, attack crits for both attacks Assert.DoesNotThrow(() => { _battleManager.Battle(_humanTeam, _enemyTeam); }); }
public void CastSpell_CorrectlyChecksUserHasLearnedSelectedSpell() { var spell = new Spell("foo", MagicType.Wind, SpellType.Attack, TargetType.SingleEnemy, 0, 5); _human.SetDeathOnTurnEndEvent(); _human.SetMove(spell); _human.SetMoveTarget(_enemy); Assert.False(_human.Spells.Contains(spell)); Assert.Throws <ArgumentException>(() => _battleManager.Battle(_humanTeam, _enemyTeam)); }