public void Test() { bool firstAlarmFired = false; bool secondAlarmFired = false; DateTime firstAlarmTime = DateTime.MinValue; DateTime secondAlarmTime = DateTime.MinValue; void First_AlarmFired(object sender, DndTimeEventArgs ea) { firstAlarmTime = ea.TimeClock.Time; firstAlarmFired = true; } void Second_AlarmFired(object sender, DndTimeEventArgs ea) { secondAlarmTime = ea.TimeClock.Time; secondAlarmFired = true; } DndTimeClock dndTimeClock = new DndTimeClock(); DateTime startTime = new DateTime(2000, 1, 1); dndTimeClock.SetTime(startTime); DndAlarm first = dndTimeClock.CreateAlarm(TimeSpan.FromSeconds(5), "First"); first.AlarmFired += First_AlarmFired; DndAlarm second = dndTimeClock.CreateAlarm(TimeSpan.FromSeconds(15), "Second"); second.AlarmFired += Second_AlarmFired; Assert.IsFalse(firstAlarmFired); Assert.IsFalse(secondAlarmFired); Assert.AreEqual(firstAlarmTime, DateTime.MinValue); Assert.AreEqual(secondAlarmTime, DateTime.MinValue); dndTimeClock.Advance(DndTimeSpan.FromSeconds(10)); Assert.IsTrue(firstAlarmFired); Assert.AreEqual(firstAlarmTime, startTime + TimeSpan.FromSeconds(5)); Assert.IsFalse(secondAlarmFired); dndTimeClock.Advance(DndTimeSpan.FromSeconds(10)); Assert.IsTrue(secondAlarmFired); Assert.AreEqual(secondAlarmTime, startTime + TimeSpan.FromSeconds(15)); }
public static Monster BuildVrock(string name = "") { Monster vrock = new Monster(); if (string.IsNullOrEmpty(name)) { vrock.name = "Clyde"; } else { vrock.name = name; } vrock.race = "Vrock"; vrock.creatureSize = CreatureSize.Large; vrock.alignmentStr = AlignmentNames.ChaoticEvil; vrock.kind = CreatureKinds.Fiend; vrock.baseArmorClass = 15; vrock.naturalArmor = true; vrock.HitPoints = 104; vrock.hitPointsDice = Dice.d10x11.Plus(44);; vrock.baseWalkingSpeed = 40; vrock.flyingSpeed = 60; vrock.SetAbilities(17, +3, 15, +2, 18, +4, 8, -1, 13, +1, 8, -1); vrock.savingDexterityMod = +5; vrock.savingWisdomMod = +4; vrock.savingCharismaMod = +2; vrock.advantages = Against.spellsAndMagicalEffects; vrock.AddDamageResistance(DamageType.Cold | DamageType.Fire | DamageType.Lightning | DamageType.Bludgeoning | DamageType.Piercing | DamageType.Slashing, AttackKind.NonMagical); vrock.AddDamageImmunity(DamageType.Poison); vrock.conditionImmunities = Conditions.Poisoned; vrock.darkvisionRadius = 120; vrock.passivePerception = 11; vrock.AddLanguages(Languages.Abyssal); vrock.telepathyRadius = 120; vrock.challengeRating = 6; vrock.experiencePoints = 2300; vrock.AddAttack(Attack.Melee(AttackNames.Beak, +6, 5, 1).AddDamage(DamageType.Piercing, Dice.d6x2.Plus(3), AttackKind.NonMagical)); vrock.AddAttack(Attack.Melee(AttackNames.Talons, +6, 5, 1).AddDamage(DamageType.Slashing, Dice.d10x2.Plus(3), AttackKind.NonMagical)); Attack sporesAttack = Attack.Area(AttackNames.Spores, 15).AddDamage(DamageType.Poison, Dice.d10x1, AttackKind.NonMagical, TimePoint.StartOfTurn, TimePoint.EndOfTurn, Conditions.Poisoned, 14, Ability.constitution); sporesAttack.description = "A 15-foot-radius cloud of toxic spores extends out from the vrock. The spores spread around corners. Each creature in that area must succeed on a DC 14 Constitution saving throw or become poisoned. While poisoned in this way, a target takes 5 (1d10) poison damage at the start of each of its turns. A target can repeat the saving throw at the end of each of its turns, ending the effect on itself on a success. Emptying a vial of holy water on the target also ends the effect on it."; //sporesAttack.releaseTrigger = new ReleaseTrigger("Target receives splashes of holy water."); sporesAttack.AddRecharge(RechargeOdds.OneInSix); vrock.AddAttack(sporesAttack); Attack screech = Attack.Area(AttackNames.StunningScreech, 20).AddCondition(Conditions.Stunned, 14, Ability.constitution); screech.LastDamage.IncludeTargetSenses = Senses.Hearing; // TODO: Add test to determine if an attack hits a player using screech.includeTargetSenses. screech.LastDamage.ExcludeCreatureKinds(CreatureKinds.Fiend); screech.recharges = DndTimeSpan.FromDays(1); vrock.AddAttack(screech); vrock.AddMultiAttack(AttackNames.Beak, AttackNames.Talons); vrock.traits.Add("Magic Resistance. The vrock has advantage on saving throws against spells and other magical effects."); return(vrock); }
private void BtnAddMonth_Click(object sender, RoutedEventArgs e) { dndTimeClock.Advance(DndTimeSpan.FromDays(30), ShiftKeyDown); }
private void BtnAdvanceTurn_Click(object sender, RoutedEventArgs e) { dndTimeClock.Advance(DndTimeSpan.FromSeconds(6)); }
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)); } }
private void BtnAdd10Minutes_Click(object sender, RoutedEventArgs e) { dndTimeClock.Advance(DndTimeSpan.FromMinutes(10), ShiftKeyDown); }
private void BtnAddHour_Click(object sender, RoutedEventArgs e) { dndTimeClock.Advance(DndTimeSpan.FromHours(1), ShiftKeyDown); }