public static void CheckEmpowerSpellLikeAbilityMonster(int casterLevel, SpellData spellData, ISpellStatBlock spell, StatBlockMessageWrapper _messageXML) { if ((spellData.metaMagicPowers & StatBlockInfo.MetaMagicPowers.empowered) == StatBlockInfo.MetaMagicPowers.empowered) { int MinCasterLevelNeeded = -1; switch (spell.SLA_Level) { case 0: MinCasterLevelNeeded = 4; break; case 1: MinCasterLevelNeeded = 6; break; case 2: MinCasterLevelNeeded = 8; break; case 3: MinCasterLevelNeeded = 10; break; case 4: MinCasterLevelNeeded = 12; break; case 5: MinCasterLevelNeeded = 14; break; case 6: MinCasterLevelNeeded = 16; break; case 7: MinCasterLevelNeeded = 18; break; case 8: MinCasterLevelNeeded = 20; break; } if (casterLevel >= MinCasterLevelNeeded) { _messageXML.AddPass("Empower spell-Like Ability-" + spellData.Name); } else { _messageXML.AddFail("Empower spell-Like Ability-" + spellData.Name, MinCasterLevelNeeded.ToString(), casterLevel.ToString()); } } }
private static void ComputeRangeMod(Weapon weapon, AbilityScores.AbilityScores _abilityScores, MonSBSearch _monSBSearch, StatBlockMessageWrapper _messageXML, ref string formula, ref StatBlockInfo.HDBlockInfo damageComputed) { int rangedModUsed = _abilityScores.StrMod; string rangeModUsedString = " Str"; if (_monSBSearch.HasDefensiveAbility("incorporeal")) { rangedModUsed = 0; // _abilityScores.DexMod; rangeModUsedString = " Dex"; } if (weapon.name.Contains("composite") && weapon.CompositeBonus == 0) { _messageXML.AddFail("Composite Weapon", "Str Bonus Missing"); } if (!Utility.IsThrownWeapon(weapon.search_name.ToLower())) { if (!weapon.uses_ammunition || weapon.name == "Sling" || (weapon.name.Contains("composite") && weapon.CompositeBonus > 0)) { if (weapon.name.Contains("composite") && weapon.CompositeBonus > 0) { if (weapon.CompositeBonus >= rangedModUsed) { damageComputed.Modifier += Convert.ToInt32(rangedModUsed); formula += " +" + rangedModUsed.ToString() + " composite"; } else { damageComputed.Modifier += Convert.ToInt32(weapon.CompositeBonus); formula += " +" + weapon.CompositeBonus.ToString() + " composite"; } } else { if (!weapon.name.ToLower().Contains("cross")) { damageComputed.Modifier += Convert.ToInt32(rangedModUsed); formula += " +" + rangedModUsed.ToString() + rangeModUsedString; } } } } if (weapon.category == "Ranged Weapons" && !weapon.name.Contains("composite") && weapon.name.Contains("bow") && rangedModUsed < 0) { if (!weapon.name.ToLower().Contains("crossbow")) { damageComputed.Modifier += Convert.ToInt32(rangedModUsed); formula += " +" + rangedModUsed.ToString() + rangeModUsedString; } } }
private void CheckOneRangedOrBlock(string rangedWeapon) { List <string> Found = new List <string>(); List <string> Ranged = new List <string>(); string[] temp2 = new string[] { " and" }; if (rangedWeapon.Contains(" and ")) { Ranged = rangedWeapon.Split(temp2, StringSplitOptions.RemoveEmptyEntries).ToList <string>(); } else if (rangedWeapon.Contains(", ")) { temp2 = new string[] { ", " }; Ranged = rangedWeapon.Split(temp2, StringSplitOptions.RemoveEmptyEntries).ToList <string>(); } else { Ranged.Add(rangedWeapon); } bool SimpleOne = false; foreach (string ranged in Ranged) { Weapon weapon = null; NaturalWeapon natural_weapon = null; WeaponCommon weaponCommon = new WeaponCommon(magicInEffect, Weapons, _indvSB, _messageXML, _monSBSearch, CharacterClasses, RaceName, DontUseRacialHD, RaceBaseType, HasRaceBase, RacialHDValue); bool MagicWeapon; bool GreaterMagicWeapon; if (weaponCommon.FindWeapon(ref weapon, ref natural_weapon, ranged.Trim(), out MagicWeapon, out GreaterMagicWeapon)) { Found.Add(ranged.Trim()); CheckOneRangedWeaponFound(weapon, ranged.Trim(), MagicWeapon, GreaterMagicWeapon, ref SimpleOne, RaceWeapons); } else { _messageXML.AddFail("Ranged Attack", "Missing Weapon-" + rangedWeapon.Trim()); } } }
public static void CheckQuickenSpellLikeAbilityMonster(int CasterLevel, SpellData SD, ISpellStatBlock Spell, StatBlockMessageWrapper _messageXML) { if ((SD.metaMagicPowers & StatBlockInfo.MetaMagicPowers.quickened) == StatBlockInfo.MetaMagicPowers.quickened) { int MinCasterLevelNeeded = -1; switch (Spell.SLA_Level) { case 0: MinCasterLevelNeeded = 8; break; case 1: MinCasterLevelNeeded = 10; break; case 2: MinCasterLevelNeeded = 12; break; case 3: MinCasterLevelNeeded = 14; break; case 4: MinCasterLevelNeeded = 16; break; case 5: MinCasterLevelNeeded = 18; break; case 6: MinCasterLevelNeeded = 20; break; } if (CasterLevel >= MinCasterLevelNeeded) { _messageXML.AddPass("Quicken Spell-Like Ability-" + SD.Name); } else { _messageXML.AddFail("Quicken Spell-Like Ability-" + SD.Name, MinCasterLevelNeeded.ToString(), CasterLevel.ToString()); } } }
public void CheckSpellDC(bool IsGnome) { List <string> Names = CharacterClasses.GetClassNames(); SpellList SL = null; string formula = string.Empty; foreach (string name in Names) { formula = string.Empty; if (CharacterClasses.CanClassCastSpells(name.ToLower())) { if (ClassSpells.ContainsKey(name)) { SL = ClassSpells[name]; List <SpellData> ListOfSpells = SL.ListOfSpells; int AbilityScore = MonSB.GetAbilityScoreValue(CharacterClasses.GetSpellBonusAbility(name)); OnGoingStatBlockModifier.StatBlockModifierSubTypes subType = Utility.GetOnGoingAbilitySubTypeFromString(CharacterClasses.GetSpellBonusAbility(name)); AbilityScore += _indvSB.GetOnGoingStatBlockModValue(OnGoingStatBlockModifier.StatBlockModifierTypes.Ability, subType); int AbilityBonus = StatBlockInfo.GetAbilityModifier(AbilityScore); int Bonus = 0; foreach (SpellData SD in ListOfSpells) { try { string Temp = SD.Name; Temp = Temp.Replace("†", string.Empty); List <string> School; Temp = Utility.RemoveSuperScripts(Temp); string search = Utility.SearchMod(Temp); if (search == "empty slot") { continue; } ISpellStatBlock Spell = SpellStatBlock.GetSpellByName(search); Bonus = 0; if (Spell == null) { _messageXML.AddFail("Spell DC", "Missing spell: " + search); } else { if (_monSBSearch.HasSpellFocusFeat(out School)) { if (School.Contains(Spell.school)) { Bonus++; } List <string> School2; if (_monSBSearch.HasGreaterSpellFocusFeat(out School2)) { if (School2.Contains(Spell.school)) { Bonus++; } } if (SLA_SaveFail(SD, Spell)) { _messageXML.AddFail("SLA Save-" + SD.Name, Spell.saving_throw, SD.DC.ToString()); } } if (_monSBSearch.HasElementalSkillFocusFeat(out School)) { if (School.Contains(Spell.school)) { Bonus++; } List <string> School2; if (_monSBSearch.HasGreaterElementalSkillFocusFeat(out School2)) { if (School2.Contains(Spell.school)) { Bonus++; } } if (SLA_SaveFail(SD, Spell)) { _messageXML.AddFail("SLA Save-" + SD.Name, Spell.saving_throw, SD.DC.ToString()); } } if (SD.DC > 0) { ComputeSpellDC(IsGnome, ref formula, name, AbilityBonus, ref Bonus, SD, Spell); } } } catch (Exception ex) { _messageXML.AddFail("CheckSpellDC--" + SD.Name, ex.Message); } } } } } if (!Names.Any() && MonSB.SpellsPrepared.Length > 0) { string temp = MonSB.SpellsPrepared; temp = temp.Substring(0, temp.IndexOf(" ")); if (ClassSpells.ContainsKey(temp)) { SL = ClassSpells[temp]; List <SpellData> ListOfSpells = SL.ListOfSpells; int AbilityBonus = StatBlockInfo.GetAbilityModifier(MonSB.GetAbilityScoreValue(CharacterClasses.GetSpellBonusAbility(temp))); foreach (SpellData SD in ListOfSpells) { if (SD.DC > 0) { int computedDC = 10 + SD.Level + AbilityBonus; formula = "10 +" + SD.Level.ToString() + " spell level +" + AbilityBonus.ToString() + " ability bonus"; if (computedDC == SD.DC) { _messageXML.AddPass("Spell DC-" + SD.Name); } else { _messageXML.AddFail("Spell DC-" + SD.Name, computedDC.ToString(), SD.DC.ToString(), formula); } } } } } if (!Names.Any() && MonSB.SpellsKnown.Length > 0) { string temp = MonSB.SpellsKnown; temp = temp.Substring(0, temp.IndexOf(" ")); if (ClassSpells.ContainsKey(temp)) { SL = ClassSpells[temp]; List <SpellData> ListOfSpells = SL.ListOfSpells; if (temp == "Spells") { temp = "Sorcerer"; } int AbilityBonus = StatBlockInfo.GetAbilityModifier(MonSB.GetAbilityScoreValue(CharacterClasses.GetSpellBonusAbility(temp))); foreach (SpellData SD in ListOfSpells) { if (SD.DC > 0) { int computedDC = 10 + SD.Level + AbilityBonus; formula = "10 +" + SD.Level.ToString() + " spell level +" + AbilityBonus.ToString() + " ability bonus"; if (computedDC == SD.DC) { _messageXML.AddPass("Spell DC-" + SD.Name); } else { _messageXML.AddFail("Spell DC-" + SD.Name, computedDC.ToString(), SD.DC.ToString(), formula); } } } } } }
public void CheckFeatCount(string Feats) { string CheckName = "Feat Count"; string hold = Feats; Utility.ParenCommaFix(ref hold); List <string> MythicFeats = new List <string>(); List <string> FeatsTemp = hold.Replace("*", string.Empty).Split(',').ToList <string>(); FeatsTemp.RemoveAll(p => p == string.Empty); List <string> NewFeats = new List <string>(); FeatsTemp = RemoveSuperScripts(FeatsTemp); //not mythic M FeatsTemp.RemoveAll(p => p == " "); int Count = FeatsTemp.Count - 1; for (int a = Count; a >= 0; a--) { string feat = FeatsTemp[a]; if (feat.Contains("- ")) { _messageXML.AddFail("Feat Spelling", "hyphen space in feat name"); } if (feat.Contains("(")) { int Pos = feat.IndexOf("("); string temp3 = feat.Substring(Pos); temp3 = temp3.Replace("(", string.Empty); temp3 = temp3.Replace(")", string.Empty); int count; int.TryParse(temp3, out count); if (count > 0) { NewFeats.Add(feat); } else { if (temp3.Contains("|")) { List <string> MultipleFeats = temp3.Split('|').ToList <string>(); Pos = feat.IndexOf("("); string baseFeat = feat.Substring(0, Pos).Trim(); FeatsTemp[a] = baseFeat + " (" + MultipleFeats[0].Trim() + ")"; for (int b = 1; b <= MultipleFeats.Count - 1; b++) { NewFeats.Add(baseFeat + " (" + MultipleFeats[b].Trim() + ")"); } } } } //if (feat.EndsWith("M") || feat.Contains("M ")) if (feat.Contains("[M]")) { string temp2 = feat.Replace("[M]", string.Empty); if (temp2.EndsWith("M")) { temp2 = temp2.Substring(0, temp2.Length - 1); } string tempOld = temp2; if (temp2.Contains("(")) { int Pos = temp2.IndexOf("("); temp2 = temp2.Substring(0, Pos).Trim(); } temp2 = temp2.Trim(); MythicFeats.Add(temp2.Trim()); IFeatStatBlock tempFeat = StatBlockService.GetMythicFeatByName(temp2); if (tempFeat != null && tempFeat.prerequisite_feats == temp2) { FeatsTemp[a] = tempOld; } else { FeatsTemp[a] = string.Empty; } } } FeatsTemp.Remove(string.Empty); FeatsTemp.AddRange(NewFeats); if (_monSBSearch.IsMythic) { int value = _monSBSearch.MythicValue; int MythicFeatCount = StatBlockInfo.GetMythicFeats(value); if (MythicFeatCount == MythicFeats.Count) { _messageXML.AddPass("Mythic Feat Count"); } else { _messageXML.AddFail("Mythic Feat Count", MythicFeatCount.ToString(), MythicFeats.Count.ToString(), ""); } } int FeatCount = CharacterClasses.FindClassFeatCount(); string formula = FeatCount.ToString() + " classes"; if ((FeatsTemp.Contains("AlertnessB") || FeatsTemp.Contains("Alertness")) && _monSBSearch.HasFamiliar()) { FeatCount++; formula += " +1 Familiar bonus"; } if (_monSBSearch.HasHex("cauldron")) { FeatCount++; formula += " +1 cauldron hex"; } //if (Race_Base.RaceBaseType != RaceBase.RaceType.Race) //{ int count2 = FeatsTemp.Count; for (int a = count2 - 1; a >= 0; a--) { if (FeatsTemp[a].LastIndexOf("B") == FeatsTemp[a].Length - 1) { FeatsTemp.Remove(FeatsTemp[a]); } else if (FeatsTemp[a].Contains("(")) { string tempFeat = FeatsTemp[a].Substring(0, FeatsTemp[a].IndexOf("(")).Trim(); if (tempFeat.LastIndexOf("B") == tempFeat.Length - 1) { FeatsTemp.Remove(FeatsTemp[a]); } } else if (FeatsTemp[a].Contains("B ")) { FeatsTemp.Remove(FeatsTemp[a]); } } //} if (_monSBSearch.HasSQ("secrets")) //loremaster { if (_monSBSearch.HasSQ("secret health")) { FeatCount++; formula += " +1 secret health"; } if (_monSBSearch.HasSQ("applicable knowledge")) { FeatCount++; formula += " +1 applicable knowledge"; } } if (_monSBSearch.HasSQ("slayer talents")) { if (_monSBSearch.HasSQ("combat trick")) { FeatCount++; formula += " +1 combat trick"; } } if (_monSBSearch.HasSQ("rogue talent") || _monSBSearch.HasSQ("ninja tricks")) { if (_monSBSearch.HasSQ("combat trick")) { FeatCount++; formula += " +1 combat trick"; } if (_monSBSearch.HasSQ("finesse rogue")) { FeatCount++; //weapon finesse formula += " +1 finesse rogue"; } if (_monSBSearch.HasSQ("weapon training")) { FeatCount++; formula += " +1 weapon training"; } if (_monSBSearch.HasSQ("feat")) { FeatCount++; formula += " +1 rogue talent feat"; } if (_monSBSearch.HasSQ("card sharp")) { FeatCount++; formula += " +1 card sharp"; } if (_monSBSearch.HasSQ("grit")) { FeatCount += 2; formula += " +2 grit"; } } if (_monSBSearch.HasCavalierOrder("order of the cockatrice")) { int cavalierLevels = CharacterClasses.FindClassLevel("cavalier"); if (cavalierLevels >= 2) { FeatCount++; formula += " +1 order of the cockatrice"; } } if (_monSBSearch.HasCavalierOrder("order of the whip")) { int cavalierLevels = CharacterClasses.FindClassLevel("cavalier"); if (cavalierLevels >= 2) { FeatCount++; formula += " +1 order of the whip"; } } if (_monSBSearch.HasSQ("revelations") && _monSBSearch.HasSQ("weapon mastery")) // oracle battle mystery { int OracleLevel = CharacterClasses.FindClassLevel("oracle"); FeatCount++; formula += " +1 weapon focus"; if (OracleLevel >= 8) { FeatCount++; formula += " +1 Improved Critical"; } if (OracleLevel >= 12) { FeatCount++; formula += " +1 Greater Weapon Focus"; } } if (_monSBSearch.HasSQ("revelations") && _monSBSearch.HasSQ("stone stability")) // oracle stone mystery { int OracleLevel = CharacterClasses.FindClassLevel("oracle"); if (OracleLevel >= 5) { FeatCount++; formula += " +1 Improved Trip"; } if (OracleLevel >= 10) { FeatCount++; formula += " +1 Greater Trip"; } } if (_monSBSearch.HasSQ("revelations") && _monSBSearch.HasSQ("cinder dance")) // oracle flame mystery { int OracleLevel = CharacterClasses.FindClassLevel("oracle"); if (OracleLevel >= 5) { FeatCount++; formula += " +1 Nimble Moves"; } if (OracleLevel >= 10) { FeatCount++; formula += " +1 Acrobatic Steps"; } } #region ClassArchetypes if (_monSBSearch.HasAnyClassArchetypes()) { if (_monSBSearch.HasClassArchetype("unarmed fighter")) { FeatCount++; formula += " +1 Unarmed Style"; } if (_monSBSearch.HasClassArchetype("pirate")) { FeatCount++; formula += " +1 Sea Legs"; } if (_monSBSearch.HasClassArchetype("musketeer")) { FeatCount += 2; formula += " +2 Musketeer Instruction"; } if (_monSBSearch.HasClassArchetype("cad")) { int CadLevels = CharacterClasses.FindClassLevel("fighter"); if (CadLevels >= 3) { FeatCount++; // Catch Off Guard } formula += " +1 Catch Off Guard"; } if (_monSBSearch.HasClassArchetype("steel hound")) { int investigatorLevels = CharacterClasses.FindClassLevel("investigator"); if (investigatorLevels >= 2) { FeatCount += 2; // Amateur Gunslinger and Gunsmithing } formula += " +2 Packing Heat"; } if (_monSBSearch.HasClassArchetype("constable")) { FeatCount++; // Apprehend (Ex) formula += " +1 Apprehend"; } if (_monSBSearch.HasClassArchetype("staff magus")) { FeatCount++; // Quarterstaff Master (Ex) formula += " +1 Quarterstaff Master"; } if (_monSBSearch.HasClassArchetype("musket master")) { FeatCount++; // Rapid Reloader formula += " +1 Rapid Reloader"; } if (_monSBSearch.HasClassArchetype("weapon adept")) { int monkLevels = CharacterClasses.FindClassLevel("monk"); if (monkLevels >= 1) { FeatCount++; } formula += " +1 Perfect Strike"; if (monkLevels >= 2) { FeatCount++; formula += " +1 Weapon Focus"; } } } #endregion ClassArchetypes if (_monSBSearch.HasSpellDomians()) { int clericLevel = CharacterClasses.FindClassLevel("cleric"); if (clericLevel == 0) { clericLevel = CharacterClasses.FindClassLevel("druid"); } if (_monSBSearch.HasSpellDomain("Nobility") && clericLevel >= 8) { FeatCount++; formula += " +1 Nobility"; } if (_monSBSearch.HasSpellDomain("Rune")) { FeatCount++; formula += " +1 Rune"; } if (_monSBSearch.HasSpellDomain("Darkness")) { FeatCount++; formula += " +1 Darkness"; } if (_monSBSearch.HasSpellDomain("Persistence")) { FeatCount++; //step up formula += " +1 Persistence"; } if (_monSBSearch.HasSpellDomain("Black Powder")) { FeatCount++; //Gunsmithing inquisition formula += " +1 Black Powder"; } } if (_monSBSearch.HasTemplate("worm that walks")) { FeatCount++; //diehard formula += " +1 worm that walks"; } if (CharacterClasses.HasClass("arcanist")) { if (_monSBSearch.HasSpecialAttack("metamagic knowledge")) { FeatCount++; //Metamagic Knowledge formula += " +1 metamagic knowledge"; } } if (CharacterClasses.HasClass("slayer")) { if (_monSBSearch.HasSQ("ranger combat style")) { int slayerLevel = CharacterClasses.FindClassLevel("slayer"); int tempMod = 0; if (slayerLevel >= 2) { tempMod++; } if (slayerLevel >= 6) { tempMod++; } if (slayerLevel >= 10) { tempMod++; } if (slayerLevel >= 14) { tempMod++; } if (slayerLevel >= 18) { tempMod++; } if (tempMod > 0) { FeatCount += tempMod; formula += " +" + tempMod.ToString() + " ranger combat style"; } } if (_monSBSearch.HasSQ("weapon training")) { FeatCount += 1; formula += " +1 weapon training"; } } if (CharacterClasses.HasClass("hellknight signifer")) { int hellknightSigniferLevel = CharacterClasses.FindClassLevel("hellknight signifer"); if (hellknightSigniferLevel >= 2 && _monSBSearch.HasFeat("Arcane Armor Training")) { FeatCount++; //Arcane Armor Mastery formula += " +1 Arcane Armor Expertise"; } } if (_monSBSearch.HasSQ("investigator talent") && _monSBSearch.HasSQ("bonus feat")) // oracle battle mystery { FeatCount++; //Investigator Talents formula += " +1 Investigator Talent"; } int temp = 0; if (Race_Base != null) { if (Race_Base.RaceBaseType == RaceBase.RaceType.StatBlock && Race_Base.UseRacialHD) { if (!HasEnvirmonment) { temp = Race_Base.BonusFeatCount(); formula += " +" + temp.ToString() + " Race"; FeatCount += temp; } } //FeatCount += StatBlockInfo.GetHDFeats(CharacterClasses.FindTotalClassLevels()); temp = StatBlockInfo.GetHDFeats(HDValue); formula += " +" + temp.ToString() + " Hit Dice"; FeatCount += temp; if (Race_Base.RaceBaseType == RaceBase.RaceType.Race) { temp = Race_Base.BonusFeatCount(); formula += " +" + temp.ToString() + " Race"; FeatCount += temp; } } int SB_count = FeatsTemp.Count(); if (IntAbilityScoreValue == 0) { FeatCount = 0; formula = " Int=0"; } if (SB_count == FeatCount) { _messageXML.AddPass(CheckName, formula); } else { _messageXML.AddFail(CheckName, FeatCount.ToString(), SB_count.ToString(), formula); } }
public void CheckFortValue() { string CheckName = "Fort"; try { int ClassMod = CharacterClasses.GetFortSaveValue(); int OnGoingMods = 0; string onGoingModFormula = string.Empty; if (_indvSB != null) { OnGoingMods = _indvSB.GetOnGoingStatBlockModValue(OnGoingStatBlockModifier.StatBlockModifierTypes.SavingThrow, OnGoingStatBlockModifier.StatBlockModifierSubTypes.None, false, ref onGoingModFormula); OnGoingMods += _indvSB.GetOnGoingStatBlockModValue(OnGoingStatBlockModifier.StatBlockModifierTypes.SavingThrow, OnGoingStatBlockModifier.StatBlockModifierSubTypes.SavingThrow_Fort, false, ref onGoingModFormula); } int RaceMod = CharacterClasses.HasClass("animal companion") ? 0 : Race_Base.RaceFort(); int AbilityMod = GetAbilityScoreMod(Race_Base.FortMod()); int FortMod = ClassMod + RaceMod + AbilityMod + OnGoingMods; string formula = "+" + ClassMod.ToString() + " ClassMod " + " +" + RaceMod.ToString() + " RaceMod " + " +" + AbilityMod.ToString() + " AbilityMod "; if (OnGoingMods != 0) { formula += " +" + OnGoingMods.ToString() + " OnGoingMods(" + onGoingModFormula + ")"; } if (_monSBSearch.HasFeat("Great Fortitude")) { FortMod += 2; formula += " +2 Great Fortitude"; } if (_monSBSearch.HasTrait("Forlorn")) { FortMod += 1; formula += " +1 Forlorn"; } if (MonSB.SubType.IndexOf("nightshade") >= 0) { FortMod += 2; formula += " +2 nightshade"; } if (_monSBSearch.HasSQ("lore of true stamina")) { FortMod += 2; formula += " +2 lore of true stamina"; } if (_monSBSearch.HasSQ("spirit (champion)")) { int mediumLevel = CharacterClasses.FindClassLevel("medium"); int bonus = 1; if (mediumLevel >= 4) { bonus++; } if (mediumLevel >= 8) { bonus++; } if (mediumLevel >= 12) { bonus++; } if (mediumLevel >= 15) { bonus++; } if (mediumLevel >= 19) { bonus++; } FortMod += bonus; formula += " +" + bonus.ToString() + " spirit (champion)"; } if (_monSBSearch.HasDomain("Protection")) { int clericLevel = CharacterClasses.FindClassLevel("cleric"); if (clericLevel == 0) { clericLevel = CharacterClasses.FindClassLevel("druid"); } int tempMod = (clericLevel / 5) + 1; FortMod += tempMod; formula += " +" + tempMod.ToString() + " Protection domain"; } if (Race_Base.Name() == "Svirfneblin") { FortMod += 2; formula += " +2 Svirfneblin"; } string FamiliarString = _monSBSearch.FindFamiliarString(CharacterClasses.HasClass("witch")); if (FamiliarString == "rat") { FortMod += 2; formula += " +2 rat familiar"; } if (CharacterClasses.HasClass("Paladin")) { int level = CharacterClasses.FindClassLevel("paladin"); if (level >= 2) //Divine Grace { FortMod += _abilityScores.ChaMod; formula += " + " + _abilityScores.ChaMod.ToString() + " Divine Grace"; } } if (CharacterClasses.HasClass("Antipaladin")) { int level = CharacterClasses.FindClassLevel("Antipaladin"); if (level >= 2) //Unholy Resilience { FortMod += _abilityScores.ChaMod; formula += " + " + _abilityScores.ChaMod.ToString() + " Unholy Resilience"; } } if (CharacterClasses.HasClass("prophet of kalistrade")) { int level = CharacterClasses.FindClassLevel("prophet of kalistrade"); //Auspicious Display --assumes the bling is present int mod = 1; if (level >= 4) { mod++; } if (level >= 7) { mod++; } if (level >= 10) { mod++; } FortMod += mod; formula += " + " + mod.ToString() + " Auspicious Display"; } if (_monSBSearch.HasTemplate("graveknight")) { FortMod += 2; formula += " + 2 Sacrilegious Aura"; } if (_monSBSearch.HasGear("heartstone")) { FortMod += 2; formula += " + 2 heartstone"; } if (_monSBSearch.HasArchetype("Sharper"))//Lucky Save { int rogueLevel = CharacterClasses.FindClassLevel("rogue"); int tempMod = 0; if (rogueLevel >= 3) { tempMod++; } if (rogueLevel >= 9) { tempMod++; } if (rogueLevel >= 15) { tempMod++; } if (tempMod > 0) { FortMod += tempMod; formula += " + " + tempMod.ToString() + " Lucky Save"; } } FortMod += GetMagicItemSaveMods(ref formula); int FortSB = Convert.ToInt32(Utility.GetNonParenValue(MonSB.Fort)); if (FortMod == FortSB) { _messageXML.AddPass(CheckName, formula); } else { _messageXML.AddFail(CheckName, FortMod.ToString(), FortSB.ToString(), formula); } } catch (Exception ex) { _messageXML.AddFail("CheckFortValue", ex.Message); } }
public void CheckACValue() { string CheckName = "AC Value"; int FlatFootedMod = 0; int DexBonus = 0; int DexUsed = _monSBSearch.GetAbilityMod(AbilityScores.AbilityScores.AbilityName.Dexterity); int DexMod = DexUsed; int Duelist = 0; int OnGoingMods = 0; string formula = string.Empty; if (CharacterClasses.HasClass("duelist")) //Canny Defense { int IntMod = _monSBSearch.GetAbilityMod(AbilityScores.AbilityScores.AbilityName.Intelligence); if (IntMod > 0) { int Mod = 0; int DuelistLevel = CharacterClasses.FindClassLevel("duelist"); if (IntMod >= DuelistLevel) { Mod = DuelistLevel; } else { Mod = IntMod; } Duelist = Mod; } } if (MaxDexMod > -1) //negative number means no penalty { if (MaxDexMod < DexMod) { DexUsed = MaxDexMod; formula += " MaxDex: was " + MaxDexMod.ToString() + " even though Dex mod is " + (DexMod).ToString(); // Duelist = 0; } } if (DexMod > 0) { DexBonus = DexUsed; } if (_monSBSearch.HasFeat("Uncanny Dodge")) { FlatFootedMod = DexUsed; } switch (Race) { case "kasatha": ACMods_Computed.Dodge += 2; break; case "Svirfneblin": ACMods_Computed.Dodge += 2; break; } if (_monSBSearch.HasSQ("void form")) { ACMods_Computed.Deflection += HD / 4; } if (_monSBSearch.HasSubType("clockwork")) { ACMods_Computed.Dodge += 2; } if (CharacterClasses.HasClass("sorcerer")) //Natural Armor Increase { if (_monSBSearch.HasBloodline("draconic")) { int sorLevel = CharacterClasses.FindClassLevel("sorcerer"); if (sorLevel >= 3) { ACMods_Computed.Natural += 1; } if (sorLevel >= 9) { ACMods_Computed.Natural += 1; } if (sorLevel >= 15) { ACMods_Computed.Natural += 2; } } } if (CharacterClasses.HasClass("oracle")) { if (_monSBSearch.HasMystery("ancestor") && _monSBSearch.HasSQ("spirit shield")) { int oracleLevel = CharacterClasses.FindClassLevel("oracle"); if (oracleLevel >= 1) { ACMods_Computed.Armor += 4; } if (oracleLevel >= 7) { ACMods_Computed.Armor += 2; } if (oracleLevel >= 11) { ACMods_Computed.Armor += 2; } if (oracleLevel >= 15) { ACMods_Computed.Armor += 2; } if (oracleLevel >= 19) { ACMods_Computed.Armor += 2; } } } if (CharacterClasses.HasClass("gunslinger")) //Nimble (Ex) { int gunslingerLevel = CharacterClasses.FindClassLevel("gunslinger"); if (gunslingerLevel >= 2) { ACMods_Computed.Dodge += 1; } if (gunslingerLevel >= 6) { ACMods_Computed.Dodge += 1; } if (gunslingerLevel >= 10) { ACMods_Computed.Dodge += 1; } if (gunslingerLevel >= 14) { ACMods_Computed.Dodge += 1; } if (gunslingerLevel >= 18) { ACMods_Computed.Dodge += 1; } } if (CharacterClasses.HasClass("swashbuckler")) //Nimble (Ex) { int swashbucklerLevel = CharacterClasses.FindClassLevel("swashbuckler"); if (swashbucklerLevel >= 3) { ACMods_Computed.Dodge += 1; } if (swashbucklerLevel >= 7) { ACMods_Computed.Dodge += 1; } if (swashbucklerLevel >= 11) { ACMods_Computed.Dodge += 1; } if (swashbucklerLevel >= 15) { ACMods_Computed.Dodge += 1; } if (swashbucklerLevel >= 19) { ACMods_Computed.Dodge += 1; } } if (CharacterClasses.HasClass("stalwart defender")) //AC Bonus (Ex) { int stalwartDefenderLevel = CharacterClasses.FindClassLevel("stalwart defender"); if (stalwartDefenderLevel >= 1) { ACMods_Computed.Dodge += 1; } if (stalwartDefenderLevel >= 4) { ACMods_Computed.Dodge += 1; } if (stalwartDefenderLevel >= 7) { ACMods_Computed.Dodge += 1; } if (stalwartDefenderLevel >= 10) { ACMods_Computed.Dodge += 1; } } if (CharacterClasses.HasClass("ranger") && _monSBSearch.HasArchetype("shapeshifter")) { if (_monSBSearch.HasSQ("form of the dragon")) { ACMods_Computed.Natural += 2; } } if (_monSBSearch.HasClassArchetype("staff magus")) //Quarterstaff Defense (Ex) { int magusLevel = CharacterClasses.FindClassLevel("magus"); //TO DO } if (_monSBSearch.HasFeat("Aldori Dueling Mastery")) { ACMods_Computed.Shield += 2; //Aldori Dueling Mastery } if (CharacterClasses.HasClass("prophet of kalistrade")) { int level = CharacterClasses.FindClassLevel("prophet of kalistrade"); //Auspicious Display --assumes the bling is present int mod = 1; if (level >= 4) { mod++; } if (level >= 7) { mod++; } if (level >= 10) { mod++; } ACMods_Computed.Dodge += mod; } //should be handled SBChecker.ParseACMods() //foreach (OnGoingStatBlockModifier mod in _onGoingMods) //{ // if (mod.ModType == OnGoingStatBlockModifier.StatBlockModifierTypes.AC) // { // OnGoingMods += mod.Modifier; // } //} if (_monSBSearch.HasTemplate("worm that walks")) { int WisMod = _monSBSearch.GetAbilityMod(AbilityScores.AbilityScores.AbilityName.Wisdom); if (WisMod < 2) { WisMod = 2; } ACMods_Computed.Insight += WisMod; } int OtherBonuses = ACMods_Computed.Enhancement + ACMods_Computed.Deflection + ACMods_Computed.Natural + ACMods_Computed.Dodge + ACMods_Computed.Wis + ACMods_Computed.Defending + ACMods_Computed.Insight + SizeMod + ACMods_Computed.Monk + Duelist + OnGoingMods; formula += " AC = 10 +" + ACMods_Computed.Armor.ToString() + " Armor +" + ACMods_Computed.Shield.ToString() + " Shield +" + DexUsed.ToString() + " Dex Used +" + OtherBonuses.ToString() + " Other Bonuses +" + ACMods_Computed.Rage + " Rage +" + ACMods_Computed.BloodRage + " Bloodrage"; if (OtherBonuses != 0) { formula += " Other Bonuses ="; if (ACMods_Computed.Enhancement != 0) { formula += " +" + ACMods_Computed.Enhancement.ToString() + " Enhancement"; } if (ACMods_Computed.Deflection != 0) { formula += " +" + ACMods_Computed.Deflection.ToString() + " Deflection"; } if (ACMods_Computed.Natural != 0) { formula += " +" + ACMods_Computed.Natural.ToString() + " Natural"; } if (ACMods_Computed.Dodge != 0) { formula += " +" + ACMods_Computed.Dodge.ToString() + " Dodge"; } if (ACMods_Computed.Wis != 0) { formula += " +" + ACMods_Computed.Wis.ToString() + " Wis"; } if (ACMods_Computed.Defending != 0) { formula += " +" + ACMods_Computed.Defending.ToString() + " defending"; } formula += Utility.GetStringValue(SizeMod) + " SizeMod"; if (ACMods_Computed.Monk != 0) { formula += " +" + ACMods_Computed.Monk.ToString() + " Monk"; } if (Duelist != 0) { formula += " +" + Duelist.ToString() + " Duelist"; } if (OnGoingMods != 0) { formula += " +" + OnGoingMods.ToString() + " OnGoingMods"; } if (ACMods_Computed.Insight != 0) { formula += " +" + ACMods_Computed.Insight.ToString() + " Insight"; } } int CompAC = 10 + ACMods_Computed.Armor + ACMods_Computed.Shield + DexUsed + OtherBonuses + ACMods_Computed.Rage + ACMods_Computed.BloodRage; int CompTouchAC = 10 + DexUsed + SizeMod + ACMods_Computed.Deflection + ACMods_Computed.Defending + DodgeBonus + ACMods_Computed.Rage + ACMods_Computed.BloodRage + ACMods_Computed.Wis + ACMods_Computed.Monk + Duelist + ACMods_Computed.Insight; int CompFlatFoootedAC = CompAC - DexBonus + FlatFootedMod - DodgeBonus - Duelist; int AC_SB = 0; int Touch_SB = 0; int Flatfooted_SB = 0; if (AC.Contains(CR)) //2nd AC block { int Pos5 = AC.IndexOf(CR); AC = AC.Substring(0, Pos5).Trim(); Pos5 = AC.IndexOf(")"); AC = AC.Substring(Pos5 + 1).Trim(); } List <string> ACList_SB = AC.Split(',').ToList(); if (ACList_SB[0].IndexOf("(") >= 0) { ACList_SB[0] = ACList_SB[0].Substring(0, ACList_SB[0].IndexOf("(")).Trim(); } try { AC_SB = Convert.ToInt32(ACList_SB[0]); } catch (Exception ex) { _messageXML.AddFail(CheckName, ex.Message); return; } string temp = ACList_SB[1].Replace("touch", string.Empty); try { Touch_SB = Convert.ToInt32(temp); } catch { _messageXML.AddFail(CheckName, "Issue parsing touch AC"); return; } temp = ACList_SB[2].Replace("flat-footed", string.Empty); try { Flatfooted_SB = Convert.ToInt32(temp); } catch { _messageXML.AddFail(CheckName, "Issue parsing flat-footed AC"); return; } if (CompAC == AC_SB && CompTouchAC == Touch_SB && CompFlatFoootedAC == Flatfooted_SB) { _messageXML.AddPass(CheckName, formula); return; } if (CompAC != AC_SB) { _messageXML.AddFail(CheckName, CompAC.ToString() + " " + ACMods_Computed.ToString(), AC_SB.ToString(), formula); } if (CompTouchAC != Touch_SB) { _messageXML.AddFail(CheckName + " Touch ", CompTouchAC.ToString() + " " + ACMods_Computed.ToString(), Touch_SB.ToString(), formula); } if (CompFlatFoootedAC != Flatfooted_SB) { _messageXML.AddFail(CheckName + " Flat-Footed ", CompFlatFoootedAC.ToString() + " " + ACMods_Computed.ToString(), Flatfooted_SB.ToString(), formula); } }
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); } } } } }
private void CheckOneMeleeOrBlock(List <string> Found, string meleeWeapon) { NaturalWeapon natural_weapon = null; Weapon weapon = null; bool TwoWeaponFighting = false; bool MultipleWepons = false; bool NaturalMultipleWepons = false; bool LightWeapon = false; bool BiteAttack = false; List <string> Melee2 = new List <string>(); string[] temp2 = new string[] { " and" }; Utility.ParenCommaFix(ref meleeWeapon); if (FindNonParenAnd(meleeWeapon)) { Melee2 = meleeWeapon.Split(temp2, StringSplitOptions.RemoveEmptyEntries).ToList <string>(); } else if (meleeWeapon.IndexOf(", ") >= 0) { temp2 = new string[] { ", " }; Melee2 = meleeWeapon.Split(temp2, StringSplitOptions.RemoveEmptyEntries).ToList <string>(); } else { Melee2.Add(meleeWeapon); } LightWeapon = false; BiteAttack = false; if (Melee2.Count > 1) { MultipleWepons = true; foreach (string weap in Melee2) { if (weap.IndexOf("bite") >= 0) { BiteAttack = true; } if (FindLightWeapon(weap)) { LightWeapon = true; } } if (NonNaturalWeaponCount(Melee2) != 1) { TwoWeaponFighting = true; } } Found.Add(meleeWeapon); if (HasNonNaturalWeapon(Melee2)) { NaturalMultipleWepons = true; } int weaponIndex = 0; bool SimpleOne = false; foreach (string MW in Melee2) // loop on "and" blocks { weapon = null; natural_weapon = null; weaponIndex++; bool MagicWeapon; bool GreaterMagicWeapon; WeaponCommon weaponCommon = new WeaponCommon(magicInEffect, Weapons, _indvSB, _messageXML, _monSBSearch, CharacterClasses, RaceName, DontUseRacialHD, RaceBaseType, HasRaceBase, RacialHDValue); if (weaponCommon.FindWeapon(ref weapon, ref natural_weapon, MW.Trim(), out MagicWeapon, out GreaterMagicWeapon)) { Found.Add(MW); CheckOneMeleeWeaponFound(natural_weapon, weapon, TwoWeaponFighting, MultipleWepons, LightWeapon, BiteAttack, Melee2.Count, weaponIndex, MW, MagicWeapon, GreaterMagicWeapon, ref SimpleOne, RaceWeapons, NaturalMultipleWepons); } else { _messageXML.AddFail("Melee Attack", "Missing Weapon-" + MW.Trim()); } } }
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 CheckRangedWeaponDamage(Weapon weapon, string weaponsDamage, string size, AbilityScores.AbilityScores _abilityScores, MonSBSearch _monSBSearch, StatBlockMessageWrapper _messageXML, bool MagicWeapon, bool GreaterMagicWeapon, IndividualStatBlock_Combat _indvSB) { string formula = string.Empty; StatBlockInfo.SizeCategories MonSize = StatBlockInfo.GetSizeEnum(size); if (_monSBSearch.HasSQ("undersized weapons")) { MonSize = StatBlockInfo.ReduceSize(MonSize); } StatBlockInfo.HDBlockInfo damageComputed = new StatBlockInfo.HDBlockInfo(); if (weapon.name == "Sling" && _monSBSearch.HasGear("stones")) { damageComputed.ParseHDBlock(weapon.damage_small); } else if (MonSize == StatBlockInfo.SizeCategories.Medium) { damageComputed.ParseHDBlock(weapon.damage_medium); } else if (MonSize == StatBlockInfo.SizeCategories.Small) { damageComputed.ParseHDBlock(weapon.damage_small); } else { damageComputed.ParseHDBlock(StatBlockInfo.ChangeWeaponDamageSize(weapon.damage_medium, MonSize)); } if (!weaponsDamage.Contains("entangle")) { ComputeRangeMod(weapon, _abilityScores, _monSBSearch, _messageXML, ref formula, ref damageComputed); } if (_monSBSearch.HasSpecialAttackGeneral("weapon training")) { damageComputed.Modifier += _monSBSearch.GetWeaponsTrainingModifier(weapon.search_name, ref formula); } if (_monSBSearch.HasClassArchetype("crossbowman")) { int fighterLevel = _sbCheckerBaseInput.CharacterClasses.FindClassLevel("fighter"); if (fighterLevel >= 3) { int dexBonus = _abilityScores.DexMod / 2; if (dexBonus <= 0) { dexBonus = 1; } damageComputed.Modifier += dexBonus; formula += " +" + dexBonus.ToString() + " crossbowman deadshot"; } if (fighterLevel >= 5) { int tempBonus = 1; if (fighterLevel >= 9) { tempBonus++; } if (fighterLevel >= 13) { tempBonus++; } if (fighterLevel >= 17) { tempBonus++; } damageComputed.Modifier += tempBonus; formula += " +" + tempBonus.ToString() + " crossbowman crossbow expert"; } } if (_monSBSearch.HasClassArchetype("archer")) { int fighterLevel = _sbCheckerBaseInput.CharacterClasses.FindClassLevel("fighter"); if (fighterLevel >= 5) { int tempBonus = 1; if (fighterLevel >= 9) { tempBonus++; } if (fighterLevel >= 13) { tempBonus++; } if (fighterLevel >= 17) { tempBonus++; } damageComputed.Modifier += tempBonus; formula += " +" + tempBonus.ToString() + " Expert Archer"; } } string hold = weapon.NamedWeapon ? weapon.BaseWeaponName.ToLower() : weapon.search_name.ToLower(); 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 (weapon.WeaponSpecialMaterial == WeaponSpecialMaterials.AlchemicalSilver && (weapon.slashing || weapon.piercing)) { damageComputed.Modifier--; formula += " -1 Alchemical Silver"; } if (weapon.EnhancementBonus > 0) { damageComputed.Modifier += weapon.EnhancementBonus; formula += " +" + weapon.EnhancementBonus.ToString() + " Enhancement Bonus"; } if (_abilityScores.StrMod != 0 && Utility.IsThrownWeapon(weapon.search_name.ToLower())) { int MeleeModUsed = _abilityScores.StrMod; if (_monSBSearch.HasDefensiveAbility("incorporeal")) { MeleeModUsed = _abilityScores.DexMod; } formula += " +" + MeleeModUsed.ToString() + " Str Bonus Used- Thrown"; damageComputed.Modifier += Convert.ToInt32(MeleeModUsed); } if (weapon.name.Contains("bow") && !weapon.name.ToLower().Contains("composite") && !weapon.name.ToLower().Contains("cross") && _abilityScores.StrMod < 0) { damageComputed.Modifier += _abilityScores.StrMod; } bool ignoreEnhancement = false; WeaponCommon weaponCommon = new WeaponCommon(_sbCheckerBaseInput, _equipmentData, _naturalWeaponBusiness); weaponCommon.GetOnGoingDamageMods(MagicWeapon, GreaterMagicWeapon, _indvSB, ref formula, ref damageComputed, ref ignoreEnhancement); 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(); damageSB.ParseHDBlock(weaponsDamage.Trim()); if (weapon.name == "rock" && _monSBSearch.HasSpecialAttackGeneral("rock throwing")) { if (damageComputed.Modifier != (_abilityScores.StrMod * 1.5)) { _messageXML.AddFail("Ranged Attack Damage- Rock ", (_abilityScores.StrMod * 1.5).ToString(), damageComputed.Modifier.ToString()); } } if (weapon.name == "bomb" && _sbCheckerBaseInput.CharacterClasses.HasClass("alchemist")) { damageComputed = new StatBlockInfo.HDBlockInfo(); damageComputed.HDType = StatBlockInfo.HitDiceCategories.d6; int alchemistLevel = _sbCheckerBaseInput.CharacterClasses.FindClassLevel("alchemist"); damageComputed.Multiplier = ((alchemistLevel - 1) / 2) + 1; damageComputed.Modifier = _abilityScores.IntMod; formula = "+" + _abilityScores.IntMod.ToString() + " Int mod"; } if (damageSB.Equals(damageComputed)) { _messageXML.AddPass("Ranged Attack Damage " + weapon.Weapon_FullName(), formula); } else { _messageXML.AddFail("Ranged Attack Damage " + weapon.Weapon_FullName(), damageComputed.ToString(), damageSB.ToString(), formula); } //string tempWeaponCrit = weapon.critical.Replace("/×2", string.Empty); //tempWeaponCrit = tempWeaponCrit.Replace((char)(8211), Char.Parse("-")); //if (tempWeaponCrit == weaponCrit) //{ // _messageXML.AddPass("Ranged Attack Critical- " + weapon.Weapon_FullName()); //} //else //{ // _messageXML.AddFail("Ranged Attack Critical- " + weapon.Weapon_FullName(), weapon.critical, weaponCrit); //} }
public void CheckSpellDC(bool isGnome) { List <string> classNames = _characterClasses.GetClassNames(); SpellList SL; string formula = string.Empty; Dictionary <string, SpellList> classSpellsClone = new Dictionary <string, SpellList>(_classSpells); foreach (string className in classNames) { formula = string.Empty; if (_characterClasses.CanClassCastSpells(className.ToLower())) { if (classSpellsClone.ContainsKey(className)) { SL = CkeckClassSpellDCs(isGnome, ref formula, className); classSpellsClone.Remove(className); } } } if (!classNames.Any() && classSpellsClone.Any() && _monsterSB.SpellsPrepared.Length > 0) { string temp = _monsterSB.SpellsPrepared; temp = temp.Substring(0, temp.IndexOf(PathfinderConstants.SPACE)); if (classSpellsClone.ContainsKey(temp)) { SL = _classSpells[temp]; List <SpellData> listOfSpells = SL.ListOfSpells; int abilityBonus = StatBlockInfo.GetAbilityModifier(_monsterSB.GetAbilityScoreValue(_characterClasses.GetSpellBonusAbility(temp))); foreach (SpellData spellData in listOfSpells) { if (spellData.DC > 0) { int computedDC = 10 + spellData.Level + abilityBonus; formula = "10 +" + spellData.Level.ToString() + " spell level +" + abilityBonus.ToString() + " ability bonus"; if (computedDC == spellData.DC) { _messageXML.AddPass("Spell DC-" + spellData.Name); } else { _messageXML.AddFail("Spell DC-" + spellData.Name, computedDC.ToString(), spellData.DC.ToString(), formula); } } } classSpellsClone.Remove(temp); } } if (!classNames.Any() && classSpellsClone.Any() && _monsterSB.SpellsKnown.Length > 0) { string temp = _monsterSB.SpellsKnown; temp = temp.Substring(0, temp.IndexOf(PathfinderConstants.SPACE)); if (classSpellsClone.ContainsKey(temp)) { SL = _classSpells[temp]; List <SpellData> listOfSpells = SL.ListOfSpells; if (temp == "Spells") { temp = "Sorcerer"; } int abilityBonus = StatBlockInfo.GetAbilityModifier(_monsterSB.GetAbilityScoreValue(_characterClasses.GetSpellBonusAbility(temp))); foreach (SpellData spellData in listOfSpells) { if (spellData.DC > 0) { int computedDC = 10 + spellData.Level + abilityBonus; formula = "10 +" + spellData.Level.ToString() + " spell level +" + abilityBonus.ToString() + " ability bonus"; if (computedDC == spellData.DC) { _messageXML.AddPass("Spell DC-" + spellData.Name); } else { _messageXML.AddFail("Spell DC-" + spellData.Name, computedDC.ToString(), spellData.DC.ToString(), formula); } } } } classSpellsClone.Remove(temp); } if (classSpellsClone.Any()) { _messageXML.AddFail("Spell DC-", " Can't find Spell Block(s) for these classes: " + string.Join(", ", classSpellsClone.Keys.ToArray())); } }
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); } }