public void CheckSpellsLevels() { List <string> Names = CharacterClasses.GetClassNames(); List <int> Levels = new List <int>(); List <int> LevelFrequency = new List <int>(); SpellList SL = null; string spellsHold = string.Empty; string spellLevelHold = string.Empty; string CR = string.Empty; string SpellBlock = string.Empty; int overloadLevel = 0; int overloadClassLevel = 0; foreach (string name in Names) { if (CharacterClasses.CanClassCastSpells(name.ToLower())) { SL = null; if (ClassSpells.ContainsKey(name)) { SL = GetClassSpellsByClassName(name); } if (SL != null) { int casterLevel = SL.CasterLevel; int classLevel = CharacterClasses.FindClassLevel(name); switch (name.ToLower()) { case "antipaladin": classLevel -= 3; break; case "paladin": classLevel -= 3; break; case "ranger": classLevel -= 3; break; } overloadLevel = 0; CharacterClasses.GetSpellOverLoadsForPrestigeClasses(out overloadLevel, out overloadClassLevel); GetSpellOverLoads(ref overloadLevel, ref overloadClassLevel, casterLevel, classLevel); classLevel += overloadLevel; if (casterLevel != classLevel) { _messageXML.AddFail("Caster Level", "Character level not equal to caster level for " + name); } GetSpellLevels(ref Levels, name, overloadLevel); LevelFrequency = CharacterClasses.GetClassSpellsPerDay(name.ToLower(), overloadLevel); } string SpellBonusAbility = CharacterClasses.GetSpellBonusAbility(name.ToLower()); int SpellBonusAbilityValue = MonSB.GetAbilityScoreValue(SpellBonusAbility); bool IsInquisitor = name == "Inquisitor"; List <int> SpellBonus = StatBlockInfo.GetSpellBonus(SpellBonusAbilityValue, IsInquisitor); switch (name) { case "Bard": case "Skald": case "Sorcerer": case "Summoner": case "Inquisitor": case "Red Mantis Assassin": case "Arcanist": SpellBonus = new List <int>() { 0 }; break; case "Oracle": //cure or inflict bonus SpellBonus = new List <int> { 0, 1, 1, 1, 1, 1, 1, 1, 1 }; break; } if (Levels != null) { if (SL != null) { CheckSpellCount(Levels, LevelFrequency, SL, name, SpellBonusAbility, SpellBonusAbilityValue, SpellBonus, overloadClassLevel, IsInquisitor); CheckBonusSpells(SL, name, CharacterClasses.FindClassLevel(name)); } else if (Levels.Any() && SpellBonusAbilityValue <= 10) { _messageXML.AddInfo("Lacks Ability Score to cast spells with " + SpellBonusAbility + " " + SpellBonusAbilityValue.ToString()); } } else { _messageXML.AddFail("CheckSpellsLevels", "Failed to load GetSpellLevels() for " + name); } } } }
private void CheckAppliedTemplates(TemplateManager.TemplateManager TM, ref MonsterStatBlock TestMonSB) { string CheckName = "CheckAppliedTemplates"; bool stackedTemplates = false; if (MonSB.TemplatesApplied.Contains(",")) { stackedTemplates = true; //|1,2,3…@sk| } List <string> templates = MonSB.TemplatesApplied.Split('|').ToList <string>(); templates.Remove(""); List <string> stackedTemplateList = new List <string>(); string stackedTemplateBase = string.Empty; if (stackedTemplates) { FindStackTemplates(templates, ref stackedTemplateList, ref stackedTemplateBase); } foreach (string appliedTemplate in templates) { string lowerAppliedTemplate = appliedTemplate.ToLower(); if (lowerAppliedTemplate.Contains("advanced") || lowerAppliedTemplate.Contains("advanced hd")) { if (MonSB.HDValue() - CharacterClasses.FindTotalClassLevels() != Race_Base.RacialHDValue()) { TestMonSB = ApplyAdvancedHDTemplate(TM, TestMonSB); } else { if (TestMonSB != null) { List <string> Failures; if (stackedTemplates) { TestMonSB = ApplyStackedTemplates(TM, TestMonSB, stackedTemplateList, stackedTemplateBase, out Failures); } else { if (templates.Count == 1) { TestMonSB = ApplyOneTemplate(CheckName, TM, TestMonSB); } else { TestMonSB = ApplyMultipleTemplates(TM, TestMonSB, templates, stackedTemplateList); } } Race_Base.ApplyTemplatedRaceSB(TestMonSB, true); } } } else { if (TestMonSB != null) { bool Success; MonsterStatBlock tempmonSB = null; List <string> Failures; if (stackedTemplates) { TestMonSB = ApplyStackedTemplates(TM, TestMonSB, stackedTemplateList, stackedTemplateBase, out Failures); Success = !Failures.Any(); } else { TM.ApplyTemplate(TestMonSB, lowerAppliedTemplate.Trim(), out Success); } if (tempmonSB != null) { TestMonSB = tempmonSB; } if (!Success) { _messageXML.AddFail("CheckTemplates", "Template not applied for " + lowerAppliedTemplate.Trim()); } else { _messageXML.AddInfo("Template Applied - " + lowerAppliedTemplate.Trim()); Race_Base.ApplyTemplatedRaceSB(TestMonSB, true); } } } } }
public void CheckSpellsLevels() { List <string> classNames = _characterClasses.GetClassNames(); List <int> levels = new List <int>(); List <int> levelFrequency = new List <int>(); SpellList spellList; int overloadLevel = 0; int overloadClassLevel = 0; foreach (string name in classNames) { if (_characterClasses.CanClassCastSpells(name.ToLower())) { spellList = null; if (_classSpells.ContainsKey(name)) { spellList = GetClassSpellsByClassName(name); } if (spellList != null) { int casterLevel = spellList.CasterLevel; int classLevel = _characterClasses.FindClassLevel(name); switch (name.ToLower()) { case "antipaladin": classLevel -= 3; break; case "paladin": classLevel -= 3; break; case "ranger": classLevel -= 3; break; } overloadLevel = 0; _characterClasses.GetSpellOverLoadsForPrestigeClasses(out overloadLevel, out overloadClassLevel); classLevel += overloadLevel; if (casterLevel != classLevel) { _messageXML.AddFail("Caster Level", "Character level not equal to caster level for " + name); } GetSpellLevels(ref levels, name, overloadLevel); levelFrequency = _characterClasses.GetClassSpellsPerDay(name.ToLower(), overloadLevel); } string SpellBonusAbility = _characterClasses.GetSpellBonusAbility(name.ToLower()); int SpellBonusAbilityValue = _monsterSB.GetAbilityScoreValue(SpellBonusAbility); bool IsInquisitor = name == "Inquisitor"; List <int> SpellBonus = StatBlockInfo.GetSpellBonus(SpellBonusAbilityValue, IsInquisitor); switch (name) { case "Bard": case "Skald": case "Sorcerer": case "Summoner": case "Inquisitor": case "Red Mantis Assassin": case "Arcanist": SpellBonus = new List <int>() { 0 }; break; case "Oracle": //cure or inflict bonus SpellBonus = new List <int> { 0, 1, 1, 1, 1, 1, 1, 1, 1 }; break; } if (levels != null) { if (spellList != null) { CheckSpellCount(levels, levelFrequency, spellList, name, SpellBonusAbility, SpellBonusAbilityValue, SpellBonus, overloadClassLevel, IsInquisitor); CheckBonusSpells(spellList, name, _characterClasses.FindClassLevel(name)); } else if (levels.Any() && SpellBonusAbilityValue <= 10) { _messageXML.AddInfo("Lacks Ability Score to cast spells with " + SpellBonusAbility + PathfinderConstants.SPACE + SpellBonusAbilityValue.ToString()); } } else { _messageXML.AddFail("CheckSpellsLevels", "Failed to load GetSpellLevels() for " + name); } } } }
public void CheckMeleeWeaponDamage(Weapon weapon, string weaponsDamage, bool TwoWeaponFighting, bool BiteAttack, int weaponCount, int weaponIndex, string Size, AbilityScores.AbilityScores _abilityScores, MonSBSearch _monSBSearch, StatBlockMessageWrapper _messageXML, int FighterLevel, int ACDefendingMod, bool MagicWeapon, bool GreaterMagicWeapon, IndividualStatBlock_Combat _indvSB) { string formula = string.Empty; bool hasSizeDifference = false; StatBlockInfo.SizeCategories MonSize = StatBlockInfo.GetSizeEnum(Size); StatBlockInfo.SizeCategories WeaponSize = weapon.WeaponSize; if (MonSize != WeaponSize) { hasSizeDifference = true; } if (_monSBSearch.HasSQ("undersized weapons")) { MonSize = StatBlockInfo.ReduceSize(MonSize); } StatBlockInfo.HDBlockInfo damageComputed = new StatBlockInfo.HDBlockInfo(); ShieldSpecialAbilitiesEnum shieldSA = weapon.ShieldSpecialAbilities.ShieldSpecialAbilityValues; bool ShieldBashBoost = false; if ((shieldSA & ShieldSpecialAbilitiesEnum.Bashing) == ShieldSpecialAbilitiesEnum.Bashing) { ShieldBashBoost = true; MonSize = StatBlockInfo.IncreaseSize(MonSize); MonSize = StatBlockInfo.IncreaseSize(MonSize); } bool HasNewWeaponDamge = false; Weapon weaponDamage = null; if (weapon.search_name.ToLower() == "halfling sling staff") { weaponDamage = _weaponBusiness.GetWeaponByName("club"); HasNewWeaponDamge = true; } weaponsDamage = weaponsDamage.Replace(PathfinderConstants.PAREN_LEFT, string.Empty).Replace(PathfinderConstants.PAREN_RIGHT, string.Empty) .Replace("nonlethal", string.Empty); int Pos = weaponsDamage.IndexOf("/"); string weaponCrit; if (Pos >= 0) { weaponCrit = weaponsDamage.Substring(Pos + 1); weaponsDamage = weaponsDamage.Substring(0, Pos); } StatBlockInfo.HDBlockInfo damageSB = new StatBlockInfo.HDBlockInfo(); if (weaponsDamage.Contains("|")) { Pos = weaponsDamage.IndexOf("|"); weaponsDamage = weaponsDamage.Substring(0, Pos); } damageSB.ParseHDBlock(weaponsDamage.Trim()); if (weapon.@double) { //for double weapons assume the damage in the string is one of the ends if (weapon.damage_medium.Contains(damageSB.HDType.ToString())) { weapon.damage_medium = damageSB.Multiplier.ToString() + damageSB.HDType.ToString(); } if (weapon.damage_small.Contains(damageSB.HDType.ToString())) { weapon.damage_small = damageSB.Multiplier.ToString() + damageSB.HDType.ToString(); } } if (MonSize == StatBlockInfo.SizeCategories.Medium && !ShieldBashBoost && !hasSizeDifference) { if (HasNewWeaponDamge) { damageComputed.ParseHDBlock(weapon.damage_medium); } else { damageComputed.ParseHDBlock(weapon.damage_medium); } } else if (MonSize == StatBlockInfo.SizeCategories.Small && !ShieldBashBoost && !hasSizeDifference) { if (HasNewWeaponDamge) { damageComputed.ParseHDBlock(weapon.damage_small); } else { damageComputed.ParseHDBlock(weapon.damage_small); } } else if (!hasSizeDifference) { if (HasNewWeaponDamge) { damageComputed.ParseHDBlock(StatBlockInfo.ChangeWeaponDamageSize(weaponDamage.damage_medium, MonSize)); } else { damageComputed.ParseHDBlock(StatBlockInfo.ChangeWeaponDamageSize(weapon.damage_medium, MonSize)); } } else { //hasSizeDifference = true if (MonSize == StatBlockInfo.SizeCategories.Small) { damageComputed.ParseHDBlock(weapon.damage_small); } else { StatBlockInfo.SizeCategories tempSize = StatBlockInfo.SizeCategories.Medium; if (WeaponSize == tempSize) { tempSize = MonSize; } damageComputed.ParseHDBlock(StatBlockInfo.ChangeWeaponDamageSize(weapon.damage_medium, tempSize)); } } double StrBonus; bool OneHandedAsTwo; string ModUsed = ComputeStrBonus(weapon, TwoWeaponFighting, BiteAttack, weaponCount, weaponIndex, _monSBSearch, _abilityScores, out StrBonus, out OneHandedAsTwo); formula += " +" + StrBonus.ToString() + PathfinderConstants.SPACE + ModUsed + " Bonus Used"; damageComputed.Modifier += Convert.ToInt32(StrBonus); if (weapon.WeaponSpecialMaterial == WeaponSpecialMaterials.AlchemicalSilver && (weapon.slashing || weapon.piercing)) { damageComputed.Modifier--; formula += " -1 Alchemical Silver"; } if (_monSBSearch.HasSQ("hulking changeling")) { damageComputed.Modifier++; formula += " +1 hulking changeling"; } string hold2 = weapon.NamedWeapon ? weapon.BaseWeaponName : weapon.search_name; if (_monSBSearch.HasSpecialAttackGeneral("weapon training")) { damageComputed.Modifier += _monSBSearch.GetWeaponsTrainingModifier(hold2, ref formula); } damageComputed.Modifier += PoleArmTraingMods(weapon, _monSBSearch, FighterLevel, ref formula); bool ignoreEnhancement = false; if (weapon.name.ToLower() == "unarmed strike") { damageComputed.Modifier += _monSBSearch.GetOnGoingStatBlockModValue(OnGoingStatBlockModifier.StatBlockModifierTypes.NaturalDamage, OnGoingStatBlockModifier.StatBlockModifierSubTypes.None, ref formula); } else { WeaponCommon weaponCommon = new WeaponCommon(_sbCheckerBaseInput, _equipmentData, _naturalWeaponBusiness); weaponCommon.GetOnGoingDamageMods(MagicWeapon, GreaterMagicWeapon, _indvSB, ref formula, ref damageComputed, ref ignoreEnhancement); } if ((weapon.WeaponSpecialAbilities.WeaponSpecialAbilitiesValue & WeaponSpecialAbilitiesEnum.Furious) == WeaponSpecialAbilitiesEnum.Furious) { damageComputed.Modifier += 2; formula += " +1 furious"; } string hold = weapon.NamedWeapon ? weapon.BaseWeaponName.ToLower() : weapon.search_name.ToLower(); if (hold.Contains("aldori")) { hold = hold.Replace("aldori", "Aldori"); } if (_sbCheckerBaseInput.CharacterClasses.HasClass("aldori swordlord")) { if (hold.Contains("dueling sword")) { int tenpMod = _monSBSearch.GetAbilityMod(AbilityScores.AbilityScores.AbilityName.Dexterity); formula += " +" + tenpMod.ToString() + " Deft Strike"; damageComputed.Modifier += tenpMod; } } if (_monSBSearch.HasFeat("Weapon Specialization (" + hold + PathfinderConstants.PAREN_RIGHT)) { formula += " +2 Weapon Specialization"; damageComputed.Modifier += 2; } if (_monSBSearch.HasFeat("Greater Weapon Specialization (" + hold + PathfinderConstants.PAREN_RIGHT)) { formula += " +2 Greater Weapon Specialization"; damageComputed.Modifier += 2; } if (_monSBSearch.HasTemplate("graveknight")) { damageComputed.Modifier += 2; formula += " +2 Sacrilegious Aura"; } if (_monSBSearch.HasFeat("Shield Master") && weapon.name.Contains("shield")) { formula += " +" + weapon.EnhancementBonus + " Shield Master"; damageComputed.Modifier += weapon.EnhancementBonus; } //no enchantment bonus for shield bash if (weapon.EnhancementBonus > 0 && ACDefendingMod == 0 && !weapon.name.Contains("shield") && !ignoreEnhancement) { formula += " +" + weapon.EnhancementBonus.ToString() + " Enhancement Bonus"; damageComputed.Modifier += weapon.EnhancementBonus; } if (weapon.Broken) { formula += " -2 Broken"; damageComputed.Modifier -= 2; } if (damageSB.Equals(damageComputed)) { _messageXML.AddPass("Melee Attack Damage-" + weapon.Weapon_FullName(), formula); } else { int temp5 = damageComputed.Modifier - 1; if (OneHandedAsTwo && damageSB.Modifier == temp5 && !_monSBSearch.HasShield()) // not all SB use two handed weapons; not error, their choice { _messageXML.AddInfo(weapon.Weapon_FullName() + " could be used two-handed for extra damage"); _messageXML.AddPass("Melee Attack Damage-" + weapon.Weapon_FullName()); } else { _messageXML.AddFail("Melee Attack Damage-" + weapon.Weapon_FullName(), damageComputed.ToString(), damageSB.ToString(), formula); if (OneHandedAsTwo) { _messageXML.AddFail("Melee Attack Damage-", "Weapon could be used As Two-Handed?"); } } } string tempWeaponCrit = weapon.critical.Replace("/×2", string.Empty); tempWeaponCrit = tempWeaponCrit.Replace((char)(8211), char.Parse("-")); //if (tempWeaponCrit == weaponCrit) //{ // _messageXML.AddPass("Melee Attack Critical- " + weapon.Weapon_FullName()); //} //else //{ // _messageXML.AddFail("Melee Attack Critical- " + weapon.Weapon_FullName(), weapon.critical, weaponCrit); //} }
public void CheckCMB() { string CheckName = "CMB"; int CMB = 0; AbilityScores.AbilityScores.AbilityName abilityName = AbilityScores.AbilityScores.AbilityName.Strength; if (SizeCat <= StatBlockInfo.SizeCategories.Tiny) { abilityName = AbilityScores.AbilityScores.AbilityName.Dexterity; } else if (_monSBSearch.HasFeat("Agile Maneuvers")) { abilityName = AbilityScores.AbilityScores.AbilityName.Dexterity; } else if (_monSBSearch.HasDefensiveAbility("incorporeal")) { abilityName = AbilityScores.AbilityScores.AbilityName.Dexterity; } int AbilityMod = StatBlockInfo.GetAbilityModifier(_monSBSearch.GetAbilityScoreValue(abilityName)); // int BAB = Convert.ToInt32(Utility.GetNonParenValue(BaseAtk)); int BAB = CharacterClasses.GetBABValue() + (CharacterClasses.HasClass("animal companion") ? 0 : Race_Base.RaceBAB()); //was taken out before, added back in 11/8/2014 if (HasMonk) { int MonkLevel = CharacterClasses.FindClassLevel("Monk"); if (MonkLevel >= 3) { BAB = MonkLevel + CharacterClasses.GetNonMonkBABValue() + Race_Base.RaceBAB(); } } CMB = BAB + (SizeMod * -1) + AbilityMod + OnGoing; string formula = BAB.ToString() + " BAB " + Utility.GetPlusSign(SizeMod * -1) + (SizeMod * -1).ToString() + " SizeMod +" + AbilityMod.ToString() + " " + abilityName.ToString() + " AbilityMod"; if (OnGoing != 0) { formula += "+" + OnGoing.ToString() + " (" + formulaOnGoing + ") OnGoingAttackMod"; } _messageXML.AddInfo("Base BAB: " + (BAB + (SizeMod) + AbilityMod).ToString()); if (_monSBSearch.HasSubType("swarm")) { CMB = 0; formula = "0 swarm"; } string holdCMB = Utility.GetNonParenValue(CMBString); if (holdCMB == "-") { holdCMB = "0"; } if (CMB == Convert.ToInt32(holdCMB)) { _messageXML.AddPass(CheckName, formula); } else { _messageXML.AddFail(CheckName, CMB.ToString(), holdCMB, formula); } }