public void StatusMove_AppropriatelyChecksAccuracy([Values(10, 25, 50, 90)] int accuracy) { //Arrange Status status = new BlindStatus(2); StatusMove move = new StatusMove("foo", TargetType.SingleEnemy, status, accuracy: accuracy); _team1Fighter.SetMove(move, 1); _team1Fighter.SetMoveTarget(_team2Fighter); _team1Fighter.SetMove(_runawayMove); _team2Fighter.SetMove(_doNothingMove); _chanceService.PushEventOccurs(false); BattleManagerBattleConfiguration config = new SilentBattleConfiguration(); //Act _battleManager.Battle(_team1, _team2, config: config); //Assert Assert.Null(_team2Fighter.Statuses.FirstOrDefault(s => s.AreEqual(status))); double expectedChance = accuracy / 100.0; Assert.AreEqual(expectedChance, _chanceService.LastChanceVals[0]); }
protected void PrintStatusAddedMessage(object sender, StatusAddedEventArgs e) { Status status = e.Status; IFighter senderAsFighter = sender as IFighter; if (senderAsFighter == null) { throw new InvalidOperationException("BattleManager.PrintStatusAddedMessage() should only subscribe to instances of IFighter"); } CriticalChanceMultiplierStatus criticalChanceStatus = status as CriticalChanceMultiplierStatus; StatMultiplierStatus statMultiplierStatus = status as StatMultiplierStatus; MagicMultiplierStatus magicMultiplierStatus = status as MagicMultiplierStatus; MagicResistanceMultiplierStatus resistanceMultiplierStatus = status as MagicResistanceMultiplierStatus; ReflectStatus reflectStatus = status as ReflectStatus; SpellCostMultiplierStatus spellCostMultiplierStatus = status as SpellCostMultiplierStatus; AutoEvadeStatus autoEvadeStatus = status as AutoEvadeStatus; CounterAttackStatus counterAttackStatus = status as CounterAttackStatus; BlindStatus blindStatus = status as BlindStatus; if (criticalChanceStatus != null) { PrintStatusAddedMessage(senderAsFighter, criticalChanceStatus); } if (statMultiplierStatus != null) { PrintStatusAddedMessage(senderAsFighter, statMultiplierStatus); } if (magicMultiplierStatus != null) { PrintStatusAddedMessage(senderAsFighter, magicMultiplierStatus); } if (resistanceMultiplierStatus != null) { PrintStatusAddedMessage(senderAsFighter, resistanceMultiplierStatus); } if (reflectStatus != null) { PrintStatusAddedMessage(senderAsFighter, reflectStatus); } if (spellCostMultiplierStatus != null) { PrintStatusAddedMessage(senderAsFighter, spellCostMultiplierStatus); } if (autoEvadeStatus != null) { PrintStatusAddedMessage(senderAsFighter, autoEvadeStatus); } if (counterAttackStatus != null) { PrintStatusAddedMessage(senderAsFighter, counterAttackStatus); } if (blindStatus != null) { PrintStatusAddedMessage(senderAsFighter, blindStatus); } }
public void Setup() { _logger = new EventLogger(); _input = new MockInput(); _output = new MockOutput(); _menuManager = new TestMenuManager(_input, _output); _chanceService = new MockChanceService(); _battleManager = new TestBattleManager(_chanceService, _input, _output); _blindnessStatus = new BlindStatus(2); _humanFighter = new TestHumanFighter("foo", 1); _humanTeam = new TestTeam(_humanFighter); _enemy = (TestEnemyFighter)TestFighterFactory.GetFighter(TestFighterType.TestEnemy, 1); _enemyTeam = new Team(_menuManager, _enemy); _doNothing = new DoNothingMove(); }
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); }
protected void PrintStatusAddedMessage(IFighter fighter, BlindStatus status) { _output.WriteLine($"{fighter.DisplayName} has been afflicted with blindness for {GetDurationString(status)}!"); }