private ChallengeRating CalculateOffensiveCR(Creature creature) { int DPR = creature.CalculateDamagePerRound(); ChallengeRating DmgPerRndCR = CRs.Single(c => c.minDmgPerRnd <= DPR && DPR <= c.maxDmgPerRnd); List <ChallengeRating> atkBnsCR = ((List <ChallengeRating>)CRs.Where(c => c.attackBonus <= Int32.Parse(creature.attackBonus) && Int32.Parse(creature.attackBonus) <= c.attackBonus)); List <ChallengeRating> saveDCCR = ((List <ChallengeRating>)CRs.Where(c => c.saveDC <= Int32.Parse(creature.saveDC) && Int32.Parse(creature.saveDC) <= c.saveDC)); List <ChallengeRating> secondaryCR; if (UseAtkBnsOverSaveDC(creature)) { secondaryCR = atkBnsCR; } else { secondaryCR = saveDCCR; } if (secondaryCR.Contains(DmgPerRndCR) || CRWithin2(DmgPerRndCR, secondaryCR)) { return(DmgPerRndCR); } else { return(AdjustCR(DmgPerRndCR, secondaryCR)); } }
private ChallengeRating CalculateDefensiveCR(Creature creature) { ChallengeRating DefensiveCR = CRs.Single(c => c.minHP <= Int32.Parse(creature.hp) && Int32.Parse(creature.hp) <= c.maxHP); List <ChallengeRating> acCR = ((List <ChallengeRating>)CRs.Where(c => c.AC <= Int32.Parse(creature.ac) && Int32.Parse(creature.ac) <= c.AC)); if (acCR.Contains(DefensiveCR) || CRWithin2(DefensiveCR, acCR)) { return(DefensiveCR); } else { return(AdjustCR(DefensiveCR, acCR)); } }
public Creature ScaleCreature(Creature baseCreature, int targetCR) { //var newCreature = baseCreature.Clone(); baseCreature.ChallengeRating = ChallengeRating.Create(targetCR); baseCreature.Actions.Add(new Models.Action() { Name = "Damage Enemy", RulesText = new RulesText() { Text = $"The {baseCreature.Name.ToLowerInvariant()} does damage to one creature equal to half of its maximum hit points." } }); return(baseCreature); }
public ChallengeRating CalculateCreatureCR(Creature creature) { ChallengeRating DefensiveCR = CalculateDefensiveCR(creature); ChallengeRating OffensiveCR = CalculateOffensiveCR(creature); if (DefensiveCR.CR == OffensiveCR.CR) { return(DefensiveCR); } int defCRIndex = CRs.FindIndex(x => x.CR == DefensiveCR.CR); int offCRIndex = CRs.FindIndex(x => x.CR == OffensiveCR.CR); Double avgOfCR = (defCRIndex + offCRIndex) / 2; int finalCRIndex = Convert.ToInt32(Math.Round(avgOfCR, 0)); return(CRs[finalCRIndex]); }
public IActionResult Statblock() { var creature = Creature.Create("Thomas the Tank Engine", Size.Medium, ChallengeRating.Create(5), AbilityScore.CreateStandard(16, 9, 13, 1, 3, 25), 10); creature.Type = CreatureType.Construct; creature.ArmorClass = new ArmorClass(18, "Natural Armor"); creature.Speeds = new List <Speed>() { new Speed(MovementMode.Walk, 60), new Speed(MovementMode.Swim, 120), new Speed(MovementMode.Burrow, 75) }; creature.DamageImmunities = new List <DamageType>() { DamageType.Fire, DamageType.Lightning, DamageType.Acid }; creature.ConditionImmunities = new List <Condition>() { Condition.Blinded, Condition.Deafened, Condition.Prone }; var ramAttack = new Models.Action { Name = "Ram" }; ramAttack.RulesText = new RulesText() { Text = "Melee weapon attack. {attack:str+p} to hit {dmg:2d8+str} {type:bludgeoning} damage" }; creature.Actions.Add(ramAttack); var chooChooAttack = new Models.Action() { Name = "Choo Choo" }; chooChooAttack.RulesText = new RulesText() { Text = "Thomas does a big ol choo-choo thing. every targer in a 30 foot cone centered on him takes {dmg:2d8+str} {type:bludgeoning} damage and {dmg:1d8} {type:fire} damage" }; creature.Actions.Add(chooChooAttack); creature.Actions.Add(new Models.Action() { Name = "Steam Whistle", Recharge = "Recharge 5-6", RulesText = new RulesText() { Text = "Thomas blows hot steam in a 60-foot sphere centered on Thomas. Each creature in that area other than Thomas must make a DC 18 Dexterity saving throw, taking 35 (10d6) fire damage on a failed save, or half as much damage on a successful one." } }); creature.Features.Add(new Feature() { Name = "Antimagic Susceptibility", Description = "Thomas is incapacitated while in the area of an anitmagic-field. If targeted by dispel magic, Thomas must suceed on a Constitution saving throw agains that caster's spell save DC or fall unconscious for 1 minute" }); creature.Features.Add(new Feature() { Name = "False Appearance", Description = "While Thomas remains motionless, it is indistinguishable from a normal tank engine." }); creature.Senses.Add(new Sense(SenseType.Truesight, 60)); creature.Senses.Add(new Sense(SenseType.Tremorsense, 120)); creature.Languages.Add(Language.Abyssal); creature.Languages.Add(Language.Celestial); creature.Languages.Add(Language.DeepSpeech); return(View("StatBlockView", new List <ViewModels.CreatureViewModel>() { new ViewModels.CreatureViewModel(creature) })); }
public override void WritePropertyXML(XmlWriter xmlWriter) { base.WritePropertyXML(xmlWriter); xmlWriter.WriteStartElement("Type"); xmlWriter.WriteString(Methods.GetCreatureTypeString(Type)); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("ChallengeRating"); xmlWriter.WriteString(ChallengeRating.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("AttackSets"); foreach (AttackSet attackSet in AttackSets) { attackSet.WriteXML(xmlWriter); } xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Strength"); xmlWriter.WriteString(Strength.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Dexterity"); xmlWriter.WriteString(Dexterity.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Constitution"); xmlWriter.WriteString(Constitution.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Intelligence"); xmlWriter.WriteString(Intelligence.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Wisdom"); xmlWriter.WriteString(Wisdom.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Charisma"); xmlWriter.WriteString(Charisma.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("BaseAttackBonus"); xmlWriter.WriteString(BaseAttackBonus.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("GrappleModifier"); xmlWriter.WriteString(GrappleModifier.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("HitPoints"); xmlWriter.WriteString(HitPoints.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("HitDice"); xmlWriter.WriteString(HitDice.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("HitDieType"); xmlWriter.WriteString(Methods.GetDieTypeString(HitDieType)); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("ArmorClass"); xmlWriter.WriteString(ArmorClass.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("TouchArmorClass"); xmlWriter.WriteString(TouchArmorClass.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("FlatFootedArmorClass"); xmlWriter.WriteString(FlatFootedArmorClass.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Speed"); Speed.WriteXML(xmlWriter); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("FortitudeSave"); xmlWriter.WriteString(FortitudeSave.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("ReflexSave"); xmlWriter.WriteString(ReflexSave.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("WillSave"); xmlWriter.WriteString(WillSave.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Feats"); foreach (string feat in Feats) { xmlWriter.WriteStartElement("Feat"); xmlWriter.WriteString(feat); xmlWriter.WriteEndElement(); } xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Space"); xmlWriter.WriteString(Space.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Reach"); xmlWriter.WriteString(Reach.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Size"); xmlWriter.WriteString(Methods.GetSizeString(Size)); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("DamageReductions"); foreach (DamageReduction dr in DamageReductions) { dr.WriteXML(xmlWriter); } xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Immunities"); Immunities.WriteXML(xmlWriter); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("EnergyResistances"); foreach (EnergyResistance er in EnergyResistances) { er.WriteXML(xmlWriter); } xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("SpellResistance"); xmlWriter.WriteString(SpellResistance.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("FastHealing"); xmlWriter.WriteString(FastHealing.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("SpecialAttacks"); xmlWriter.WriteString(SpecialAttacks); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("SpecialQualities"); xmlWriter.WriteString(String.Join(", ", SpecialQualities)); xmlWriter.WriteEndElement(); }
public Creature ScaleCreature(Creature creature, ChallengeRating desiredRating) { return(creature); }
public Creature ScaleCreature(Creature creature, ChallengeRating desiredRating, CreatureScalingOptions scalingOptions) { return(creature); }