public void TestBarbarianMeleeRageExpiration() { AllPlayers.Invalidate(); AllFeatures.Invalidate(); History.TimeClock = new DndTimeClock(); Character fred = AllPlayers.GetFromId(PlayerID.Fred); DndGame game = DndGame.Instance; game.GetReadyToPlay(); game.AddPlayer(fred); game.Start(); fred.StartTurnResetState(); AssignedFeature barbarianMelee = fred.GetFeature("BarbarianMelee"); Assert.IsFalse(barbarianMelee.ShouldActivateNow()); fred.ActivateFeature("WildSurgeRage"); PlayerActionShortcut greataxe = fred.GetShortcut("Greataxe"); fred.Use(greataxe); Assert.IsTrue(barbarianMelee.ShouldActivateNow()); // Now test alarm system to turn off rage after one minute.... History.TimeClock.Advance(DndTimeSpan.FromSeconds(59)); Assert.IsTrue(barbarianMelee.ShouldActivateNow()); History.TimeClock.Advance(DndTimeSpan.FromSeconds(1)); Assert.IsFalse(barbarianMelee.ShouldActivateNow()); }
public void TestBarbarianMeleeConditionsWithFinesseWeapons() { History.TimeClock = new DndTimeClock(); Character fred = AllPlayers.GetFromId(PlayerID.Fred); DndGame game = DndGame.Instance; game.GetReadyToPlay(); game.AddPlayer(fred); game.Start(); fred.StartTurnResetState(); AssignedFeature barbarianMelee = fred.GetFeature("BarbarianMelee"); Assert.IsFalse(barbarianMelee.ShouldActivateNow()); fred.ActivateFeature("WildSurgeRage"); Assert.IsFalse(barbarianMelee.ShouldActivateNow()); // Not yet. We need to be using the right weapon. PlayerActionShortcut dagger = fred.GetShortcut("Dagger"); Assert.IsNotNull(dagger); fred.Use(dagger); Assert.IsTrue(barbarianMelee.ShouldActivateNow()); fred.baseDexterity = 18; fred.baseStrength = 10; dagger.UpdatePlayerAttackingAbility(fred); fred.Use(dagger); Assert.IsFalse(barbarianMelee.ShouldActivateNow()); // Should not be satisfied because dexterity is now the ability of choice to use with this finesse weapon. }
public void TestBarbarianMeleeConditionsWithVariousWeapons() { AllPlayers.Invalidate(); History.TimeClock = new DndTimeClock(); Character fred = AllPlayers.GetFromId(PlayerID.Fred); DndGame game = DndGame.Instance; game.GetReadyToPlay(); game.AddPlayer(fred); game.Start(); fred.StartTurnResetState(); AssignedFeature barbarianMelee = fred.GetFeature("BarbarianMelee"); Assert.IsFalse(barbarianMelee.ShouldActivateNow()); fred.ActivateFeature("WildSurgeRage"); Assert.IsFalse(barbarianMelee.ShouldActivateNow()); // Not yet. We need to be using the right weapon. PlayerActionShortcut greataxe = fred.GetShortcut("Greataxe"); Assert.IsNotNull(greataxe); fred.Use(greataxe); Assert.IsTrue(Expressions.GetBool("InRage", fred)); Assert.IsTrue(Expressions.GetBool("AttackIsMelee", fred)); Assert.IsTrue(Expressions.GetBool("AttackingWith(strength)", fred)); Assert.IsTrue(barbarianMelee.ShouldActivateNow()); PlayerActionShortcut longbow = fred.GetShortcut("Longbow"); fred.Use(longbow); Assert.IsFalse(barbarianMelee.ShouldActivateNow()); }
public void TestSaveSpellEvents() { AllPlayers.Invalidate(); History.TimeClock = new DndTimeClock(); Character merkin = AllPlayers.GetFromId(PlayerID.Merkin); Monster joeTheVineBlight = MonsterBuilder.BuildVineBlight("Joe"); Spell zzzSaveSpell = AllSpells.Get("ZZZ Test Save Spell", merkin, 3); DndGame game = DndGame.Instance; game.GetReadyToPlay(); game.AddPlayer(merkin); game.AddCreature(joeTheVineBlight); merkin.CastTest(zzzSaveSpell, joeTheVineBlight); merkin.ReadyRollDice(DiceRollType.DamageOnly, "3d6(fire)", 12); List <CastedSpell> activeSpells = merkin.GetActiveSpells(); Assert.IsNotNull(activeSpells); Assert.AreEqual(1, activeSpells.Count); Assert.AreEqual("onCast", Expressions.GetStr("Get(_spellState)", merkin)); game.AdvanceClock(DndTimeSpan.FromMinutes(1)); Assert.AreEqual("onDispel", Expressions.GetStr("Get(_spellState)", merkin)); activeSpells = merkin.GetActiveSpells(); Assert.IsNotNull(activeSpells); Assert.AreEqual(0, activeSpells.Count); }
public void TestAttackSpellEventsTimeout() { AllPlayers.Invalidate(); Character merkin = AllPlayers.GetFromId(PlayerID.Merkin); Monster joeTheVineBlight = MonsterBuilder.BuildVineBlight("Joe"); Spell zzzRangeSpell = AllSpells.Get("ZZZ Test Range Spell", merkin, 3); DndGame game = DndGame.Instance; game.GetReadyToPlay(); game.AddPlayer(merkin); game.AddCreature(joeTheVineBlight); game.EnteringCombat(); merkin.CastTest(zzzRangeSpell, joeTheVineBlight); List <CastedSpell> activeSpells = merkin.GetActiveSpells(); Assert.IsNotNull(activeSpells); Assert.AreEqual(0, activeSpells.Count); Assert.AreEqual("onCasting", Expressions.GetStr("Get(_spellState)", merkin)); const int hiddenThreshold = 12; merkin.ReadyRollDice(DiceRollType.Attack, "1d20(:score),2d8(:damage),1d6(:damage)", hiddenThreshold); Assert.AreEqual("onCast", Expressions.GetStr("Get(_spellState)", merkin)); const int damage = 7; merkin.DieRollStoppedForTestCases(hiddenThreshold, damage); game.AdvanceClock(DndTimeSpan.FromMinutes(1)); Assert.AreEqual("onDispel", Expressions.GetStr("Get(_spellState)", merkin)); activeSpells = merkin.GetActiveSpells(); Assert.IsNotNull(activeSpells); Assert.AreEqual(0, activeSpells.Count); game.ExitingCombat(); }
public void TestAttackSpellEventsOnPlayerAttacks() { AllPlayers.Invalidate(); Character merkin = AllPlayers.GetFromId(PlayerID.Merkin); Monster joeVineBlight = MonsterBuilder.BuildVineBlight("Joe"); Spell zzzSaveSpell = AllSpells.Get("ZZZ Test Save Spell", merkin, 3); DndGame game = DndGame.Instance; game.GetReadyToPlay(); game.AddPlayer(merkin); game.AddCreature(joeVineBlight); game.EnteringCombat(); merkin.CastTest(zzzSaveSpell, joeVineBlight); const int hiddenThreshold = 12; const int damage = 7; Assert.AreEqual("onCasting", Expressions.GetStr("Get(_spellState)", merkin)); merkin.ReadyRollDice(DiceRollType.DamageOnly, "1d6(fire)"); Assert.AreEqual("onCast", Expressions.GetStr("Get(_spellState)", merkin)); merkin.PrepareAttack(joeVineBlight, Attack.Melee("Unarmed Strike", 5, 5)); Assert.AreEqual("onPlayerAttacks", Expressions.GetStr("Get(_spellState)", merkin)); merkin.ReadyRollDice(DiceRollType.Attack, "1d20(:score),2d8(:damage),1d6(:damage)", hiddenThreshold); merkin.DieRollStoppedForTestCases(hiddenThreshold, damage); Assert.AreEqual("onPlayerHitsTarget", Expressions.GetStr("Get(_spellState)", merkin)); List <CastedSpell> activeSpells = merkin.GetActiveSpells(); Assert.IsNotNull(activeSpells); game.ExitingCombat(); }
public void TestAutoAdvanceRound() { DndGame game = DndGame.Instance; game.GetReadyToPlay(); Character merkin = AllPlayers.GetFromId(PlayerID.Merkin); Monster joeTheVineBlight = MonsterBuilder.BuildVineBlight("Joe"); game.AddPlayer(merkin); game.AddMonster(joeTheVineBlight); game.EnteringCombat(); DateTime enterCombatTime = game.Time; Assert.AreEqual(1, game.RoundNumber); Spell zzzSaveSpell = AllSpells.Get("ZZZ Test Save Spell", merkin, 3); merkin.CastTest(zzzSaveSpell, joeTheVineBlight); joeTheVineBlight.PrepareAttack(merkin, joeTheVineBlight.GetAttack(AttackNames.Constrict)); merkin.CastTest(zzzSaveSpell, joeTheVineBlight); Assert.AreEqual(2, game.RoundNumber); DateTime exitCombatTime = game.Time; TimeSpan totalCombatTime = exitCombatTime - enterCombatTime; Assert.AreEqual((game.RoundNumber - 1) * 6 /*seconds*/, totalCombatTime.TotalSeconds); game.ExitingCombat(); Assert.AreEqual(1, game.RoundNumber); }
public void TestAllFeatureExpressions() { void Expressions_ExceptionThrown(object sender, DndCoreExceptionEventArgs ea) { throw ea.Ex; } DndGame game = DndGame.Instance; game.GetReadyToPlay(); Character merkin = AllPlayers.GetFromId(PlayerID.Merkin); Character ava = AllPlayers.GetFromId(PlayerID.LilCutie); Character willy = AllPlayers.GetFromId(PlayerID.Willy); Character lady = AllPlayers.GetFromId(PlayerID.Lady); Character fred = AllPlayers.GetFromId(PlayerID.Fred); game.AddPlayer(merkin); game.AddPlayer(ava); game.AddPlayer(willy); game.AddPlayer(lady); Expressions.ExceptionThrown += Expressions_ExceptionThrown; merkin.TestEvaluateAllExpressions(); ava.TestEvaluateAllExpressions(); willy.TestEvaluateAllExpressions(); lady.TestEvaluateAllExpressions(); fred.TestEvaluateAllExpressions(); // TODO: Test shortcut AvailableWhen expression. // TODO: Test spell events. // TODO: Test all data-driven Properties and Functions. }
private static void AddSinglePlayerToGame(Character player) { player.playerID = AllPlayers.Players.Count; AllPlayers.Players.Add(player); DndGame game = DndGame.Instance; game.GetReadyToPlay(); game.AddPlayer(player); AllActionShortcuts.AddShortcutsFor(player); }
public void TestBarbarianMeleeDeactivate() { AllPlayers.Invalidate(); AllFeatures.Invalidate(); DndGame game = DndGame.Instance; game.GetReadyToPlay(); Character fred = AllPlayers.GetFromId(PlayerID.Fred); game.AddPlayer(fred); game.Start(); PlayerActionShortcut greataxe = fred.GetShortcut("Greataxe"); fred.Use(greataxe); CharacterClass barbarianClass = fred.Classes.FirstOrDefault(x => x.Name == "Barbarian"); Assert.IsNotNull(barbarianClass); barbarianClass.Level = 16; fred.ResetPlayerActionBasedState(); Assert.AreEqual(0, fred.damageOffsetThisRoll); fred.ActivateFeature("WildSurgeRage"); Assert.AreEqual(0, fred.damageOffsetThisRoll); fred.Use(greataxe); Assert.AreEqual(4, fred.damageOffsetThisRoll); AssignedFeature rageFeature = fred.GetFeature("WildSurgeRage"); Assert.IsTrue(rageFeature.Feature.IsActive); Expressions.Do("Set(_rage,false)", fred); Assert.IsFalse(rageFeature.Feature.IsActive); Assert.IsFalse(fred.GetFeature("BarbarianMelee").Feature.IsActive); fred.Use(greataxe); Assert.IsFalse(fred.GetFeature("BarbarianMelee").Feature.IsActive); Assert.AreEqual(0, fred.damageOffsetThisRoll); fred.ActivateFeature("WildSurgeRage"); Assert.IsTrue(fred.GetFeature("BarbarianMelee").Feature.IsActive); Assert.AreEqual(4, fred.damageOffsetThisRoll); fred.DeactivateFeature("WildSurgeRage"); Assert.IsFalse(fred.GetFeature("BarbarianMelee").Feature.IsActive); Assert.AreEqual(0, fred.damageOffsetThisRoll); }
public void TestProperties() { Character fred = AllPlayers.Get("Fred"); DndGame game = DndGame.Instance; game.GetReadyToPlay(); game.AddPlayer(fred); game.Start(); Expressions.Do("Set(_rage,true)", fred); Assert.IsTrue(Expressions.GetBool("_rage", fred)); Assert.IsTrue(Expressions.GetBool("InRage", fred)); Expressions.Do("Set(_rage,false)", fred); Assert.IsFalse(Expressions.GetBool("_rage", fred)); Assert.IsFalse(Expressions.GetBool("InRage", fred)); }
public void TestBarbarianMeleeConditions() { Character fred = AllPlayers.GetFromId(PlayerID.Fred); DndGame game = DndGame.Instance; game.GetReadyToPlay(); game.AddPlayer(fred); game.Start(); fred.StartTurnResetState(); AssignedFeature barbarianMelee = fred.GetFeature("BarbarianMelee"); Assert.IsFalse(barbarianMelee.ShouldActivateNow()); Expressions.Do("Set(_rage,true)", fred); fred.GetAttackingAbilityModifier(WeaponProperties.Melee, AttackType.Melee); Assert.IsTrue(barbarianMelee.ShouldActivateNow()); }
private static Character StartNewGame(string playerClass, int level, string weapon = null) { AllPlayers.Invalidate(); AllFeatures.Invalidate(); DndGame game = DndGame.Instance; game.GetReadyToPlay(); Character player = PlayerHelper.GetPlayerAtLevel(playerClass, level); game.AddPlayer(player); if (weapon != null) { player.AddWeapon(weapon); } game.Start(); return(player); }
public void TestMapAndRoomActivation() { DndGame game = DndGame.Instance; game.GetReadyToPlay(); DndMap map = game.AddMap(new DndMap("Caves of the Wandering Winds")); DndRoom wizardsWorkshop = map.AddRoom(new DndRoom("Wizard's Workshop")); Assert.IsNull(game.ActiveMap); game.ActivateMap(map); Assert.IsNull(game.ActiveRoom); Assert.IsNull(map.ActiveRoom); game.ActivateRoom(wizardsWorkshop); Assert.AreEqual(map, game.ActiveMap); Assert.AreEqual(wizardsWorkshop, game.ActiveRoom); Assert.AreEqual(wizardsWorkshop, map.ActiveRoom); }
public void TestChaosBoltDamageDieAndType() { AllPlayers.Invalidate(); DndGame game = DndGame.Instance; game.GetReadyToPlay(); Character merkin = AllPlayers.GetFromName("Merkin"); game.AddPlayer(merkin); List <PlayerActionShortcut> actionShortcuts = AllActionShortcuts.Get(merkin.playerID, "Chaos Bolt"); Assert.AreEqual(3, actionShortcuts.Count); // This will fail when Merkin levels up. DiceRoll chaosBoltLevel3 = DiceRoll.GetFrom(actionShortcuts[2]); Assert.IsTrue(chaosBoltLevel3.IsMagic); Assert.AreEqual(DiceRollType.ChaosBolt, chaosBoltLevel3.Type); Assert.AreEqual("2d8(),3d6()", chaosBoltLevel3.DamageHealthExtraDice); }
public void TestPositionCreatures() { DndGame game = DndGame.Instance; game.GetReadyToPlay(); Character alice = game.AddPlayer(CharacterBuilder.BuildTestBarbarian("a")); Character betty = game.AddPlayer(CharacterBuilder.BuildTestDruid("b")); Character charlie = game.AddPlayer(CharacterBuilder.BuildTestElf("c")); Character david = game.AddPlayer(CharacterBuilder.BuildTestWizard("d")); DndMap map = game.AddMap(new DndMap("Caves of the Wandering Winds")); DndRoom dndRoom = map.AddRoom(new DndRoom("Wizard's Workshop")); Assert.AreEqual(new Vector(0, 0), alice.Location); Assert.AreEqual(Vector.zero, betty.Location); dndRoom.PositionCreatures(@" ┌───────────────┐ │ │ │ │ │ a │ │ c │ │ └───────────────┐ │ b │ │ │ │ │ │ │ │ ┌───────────────┘ │ d │ │ │ │ e │ │ │ │ │ └───────────────┘"); game.ActivateMap(map); game.ActivateRoom(dndRoom); Assert.AreEqual(new Vector(DndMap.SquareSide * 5, DndMap.SquareSide * 3), alice.Location); Assert.AreEqual(new Vector(DndMap.SquareSide * 8, DndMap.SquareSide * 6), betty.Location); Assert.AreEqual(new Vector(DndMap.SquareSide * 13, DndMap.SquareSide * 4), charlie.Location); Assert.AreEqual(new Vector(DndMap.SquareSide * 12, DndMap.SquareSide * 11), david.Location); //dndGame.EnterCombat(true); //ergo.QueueAction(new ActionAttack(alice, AttackNames.Constrict)); }
public void TestTurnEvents() { AllPlayers.Invalidate(); DndGame game = DndGame.Instance; game.GetReadyToPlay(); Character ava = game.AddPlayer(AllPlayers.GetFromId(PlayerID.LilCutie)); Creature joe = game.AddCreature(MonsterBuilder.BuildVineBlight("Joe")); PlayerActionShortcut greatsword = ava.GetShortcut("Greatsword"); game.EnteringCombat(); Assert.IsNull(game.ActiveCreature); ava.TestStartTurn(); Assert.AreEqual(ava, game.ActiveCreature); ava.PrepareAttack(joe, greatsword); game.SetHiddenThreshold(ava, 12, DiceRollType.Attack); //DiceRoll diceRoll = ava.GetRoll(); game.ExitingCombat(); }
public void TestLoad() { AllPlayers.Invalidate(); Feature barbarianMelee = AllFeatures.Get("BarbarianMelee"); Assert.IsNotNull(barbarianMelee); Character fred = AllPlayers.GetFromId(PlayerID.Fred); DndGame game = DndGame.Instance; game.GetReadyToPlay(); game.AddPlayer(fred); game.Start(); fred.StartTurnResetState(); Assert.IsFalse(Expressions.GetBool("BarbarianMelee(strength)", fred)); //Expressions.LogHistory = true; Expressions.Do("Set(_rage,true)", fred); Assert.IsFalse(Expressions.GetBool("BarbarianMelee(strength)", fred)); fred.GetAttackingAbilityModifier(WeaponProperties.Melee, AttackType.Melee); Assert.IsTrue(Expressions.GetBool("BarbarianMelee(strength)", fred)); }
public void TestAlwaysOnFeatureActivation() { AllPlayers.Invalidate(); DndGame game = DndGame.Instance; game.GetReadyToPlay(); Character lady = game.AddPlayer(AllPlayers.GetFromId(PlayerID.Lady)); Assert.IsNotNull(lady); Assert.IsFalse(lady.IsResistantTo(DamageType.Lightning, AttackKind.Any)); Assert.IsFalse(lady.IsResistantTo(DamageType.Thunder, AttackKind.Any)); Assert.IsFalse(lady.IsResistantTo(DamageType.Lightning, AttackKind.Magical)); Assert.IsFalse(lady.IsResistantTo(DamageType.Thunder, AttackKind.Magical)); Assert.IsFalse(lady.IsResistantTo(DamageType.Lightning, AttackKind.NonMagical)); Assert.IsFalse(lady.IsResistantTo(DamageType.Thunder, AttackKind.NonMagical)); game.Start(); Assert.IsTrue(lady.IsResistantTo(DamageType.Lightning, AttackKind.Any)); Assert.IsTrue(lady.IsResistantTo(DamageType.Thunder, AttackKind.Any)); Assert.IsTrue(lady.IsResistantTo(DamageType.Lightning, AttackKind.Magical)); Assert.IsTrue(lady.IsResistantTo(DamageType.Thunder, AttackKind.Magical)); Assert.IsTrue(lady.IsResistantTo(DamageType.Lightning, AttackKind.NonMagical)); Assert.IsTrue(lady.IsResistantTo(DamageType.Thunder, AttackKind.NonMagical)); }
public void TestWrathfulSmite() { AllPlayers.Invalidate(); AllSpells.Invalidate(); AllActionShortcuts.Invalidate(); Character ava = AllPlayers.GetFromId(PlayerID.LilCutie); PlayerActionShortcut greatsword = ava.GetShortcut("Greatsword"); Assert.IsNotNull(greatsword); Monster joeVineBlight = MonsterBuilder.BuildVineBlight("Joe"); List <PlayerActionShortcut> wrathfulSmites = AllActionShortcuts.Get(ava.playerID, SpellNames.WrathfulSmite); Assert.AreEqual(1, wrathfulSmites.Count); PlayerActionShortcut wrathfulSmite = wrathfulSmites[0]; Assert.IsNotNull(wrathfulSmite); DndGame game = DndGame.Instance; game.GetReadyToPlay(); game.AddPlayer(ava); game.AddCreature(joeVineBlight); DateTime gameStartTime = game.Time; game.EnteringCombat(); ava.Hits(joeVineBlight, greatsword); // Action. Ava is first to fight. ava.CastTest(wrathfulSmite.Spell); // Bonus Action - Wrathful Smite lasts for one minute. Assert.IsTrue(ava.SpellIsActive(SpellNames.WrathfulSmite)); joeVineBlight.Misses(ava, AttackNames.Constrict); AvaMeleeMissesJoe(); // Round 2 Assert.AreEqual(6, game.SecondsSince(gameStartTime)); joeVineBlight.Misses(ava, AttackNames.Constrict); Assert.AreEqual(6, game.SecondsSince(gameStartTime)); AvaMeleeMissesJoe(); // Round 3 Assert.AreEqual(12, game.SecondsSince(gameStartTime)); joeVineBlight.Misses(ava, AttackNames.Constrict); Assert.AreEqual(12, game.SecondsSince(gameStartTime)); AvaMeleeMissesJoe(); Assert.AreEqual(18, game.SecondsSince(gameStartTime)); joeVineBlight.Misses(ava, AttackNames.Constrict); Assert.AreEqual(18, game.SecondsSince(gameStartTime)); //`+++NOW THE HIT.... ava.Hits(joeVineBlight, greatsword); Assert.AreEqual(24, game.SecondsSince(gameStartTime)); Assert.IsTrue(ava.SpellIsActive(SpellNames.WrathfulSmite)); // Wrathful Smite spell is not yet dispelled, however its impact on attack rolls is done. Assert.AreEqual($"Target must make a Wisdom saving throw or be frightened of {ava.name} until the spell ends. As an action, the creature can make a Wisdom check against {ava.name}'s spell save DC ({ava.GetSpellSaveDC()}) to steel its resolve and end this {wrathfulSmite.Spell.Name} spell.", game.lastMessageSentToDungeonMaster); joeVineBlight.Misses(ava, AttackNames.Constrict); Assert.AreEqual(24, game.SecondsSince(gameStartTime)); ava.Misses(joeVineBlight, greatsword); // Advancing Round (Ava's turn again). Assert.AreEqual("", ava.additionalDiceThisRoll); // No more die roll effects. Assert.AreEqual("", ava.trailingEffectsThisRoll); Assert.AreEqual("", ava.dieRollEffectsThisRoll); Assert.AreEqual("", ava.dieRollMessageThisRoll); Assert.AreEqual(30, game.SecondsSince(gameStartTime)); game.AdvanceClock(DndTimeSpan.FromSeconds(30)); Assert.IsFalse(ava.SpellIsActive(SpellNames.WrathfulSmite)); // Wrathful Smite spell should finally be dispelled. void AvaMeleeMissesJoe() { Assert.AreEqual("", ava.additionalDiceThisRoll); Assert.AreEqual("", ava.trailingEffectsThisRoll); Assert.AreEqual("", ava.dieRollEffectsThisRoll); Assert.AreEqual("", ava.dieRollMessageThisRoll); ava.Misses(joeVineBlight, greatsword); // Advancing Round (Ava's turn again). Assert.AreEqual("1d6(psychic)", ava.additionalDiceThisRoll); Assert.AreEqual("Ravens;Spirals", ava.trailingEffectsThisRoll); Assert.AreEqual("PaladinSmite", ava.dieRollEffectsThisRoll); Assert.AreEqual("Wrathful Smite", ava.dieRollMessageThisRoll); Assert.IsTrue(ava.SpellIsActive(SpellNames.WrathfulSmite)); } }
public void TestSpellRangeTest() { Spell chaosBolt = AllSpells.Get(SpellNames.ChaosBolt); AllPlayers.Invalidate(); AllFeatures.Invalidate(); DndGame game = DndGame.Instance; game.GetReadyToPlay(); Character sorcerer = PlayerHelper.GetPlayerAtLevel("Sorcerer", 6); sorcerer.name = "Mark"; game.AddPlayer(sorcerer); Monster joe = MonsterBuilder.BuildVineBlight("Joe"); game.AddCreature((Creature)joe); game.Start(); PositionCreatures(@" ┌───────────────┐ │ │ │ │ │ M │ │ │ │ └───────────────┐ │ │ │ │ │ │ │ │ │ ┌───────────────┘ │ J │ │ │ │ │ │ │ │ │ └───────────────┘", game.AllCreatures); Assert.AreEqual(40, sorcerer.CanCast(chaosBolt).DistanceTo(joe)); Assert.IsTrue(sorcerer.CanCast(chaosBolt).At(joe)); PositionCreatures(@" ┌───────────────┐ │ │ │ │ │ M │ │ │ │ └───────────────┐ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ┌───────────────┘ │ J │ │ │ │ │ │ │ │ │ └───────────────┘", game.AllCreatures); Assert.AreEqual(125, sorcerer.CanCast(chaosBolt).DistanceTo(joe)); Assert.IsFalse(sorcerer.CanCast(chaosBolt).At(joe)); }