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 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); } }
public void CheckCMD() { string CheckName = "CMD"; int MonkBonus = 0; int MonkLevel = 0; int WisBonus = 0; int StrModUsed = _monSBSearch.GetAbilityMod(AbilityScores.AbilityScores.AbilityName.Strength); int BAB = Convert.ToInt32(Utility.GetNonParenValue(BaseAtk)); if (HasMonk) { MonkBonus += _monSBSearch.GetAbilityMod(AbilityScores.AbilityScores.AbilityName.Wisdom); MonkLevel = CharacterClasses.FindClassLevel("Monk"); if (MonkLevel >= 4) { MonkBonus += 1; } if (MonkLevel >= 8) { MonkBonus += 1; } if (MonkLevel >= 12) { MonkBonus += 1; } if (MonkLevel >= 16) { MonkBonus += 1; } if (MonkLevel >= 20) { MonkBonus += 1; } } if (CharacterClasses.HasClass("psychic") && _monSBSearch.MonSB.PsychicDiscipline == "self-perfection") { WisBonus = _monSBSearch.GetAbilityMod(AbilityScores.AbilityScores.AbilityName.Wisdom); } if (_monSBSearch.HasFeat("Defensive Combat Training")) { BAB = TotalHD; } //Certain AC bonuses improve CMD int ACBonus = GetACModValue("deflection"); //until we can parse magic items fully ACBonus += GetACModValue("sacred"); ACBonus += GetACModValue("profane"); ACBonus += GetACModValue("circumstance"); ACBonus += GetACModValue("morale"); ACBonus += GetACModValue("insight"); int DexMod = _monSBSearch.GetAbilityMod(AbilityScores.AbilityScores.AbilityName.Dexterity); int CMD = 10 + BAB + StrModUsed + DexMod + (SizeMod * -1) + DodgeBonus + MonkBonus + ACBonus + WisBonus; string formula = "10 +" + BAB.ToString() + " BAB +" + StrModUsed.ToString() + " StrModUsed +" + DexMod.ToString() + " DexMod +" + (SizeMod * -1).ToString() + " SizeMod"; if (DodgeBonus != 0) { formula += " +" + DodgeBonus.ToString() + " DodgeBonus"; } if (MonkBonus != 0) { formula += " +" + MonkBonus.ToString() + " MonkBonus"; } if (ACBonus != 0) { formula += " +" + ACBonus.ToString() + " ACBonus"; } if (WisBonus != 0) { formula += " +" + WisBonus.ToString() + " WisBonus"; } //shown in CMD mod // if (_monSBSearch.HasFeat("Improved Grapple")) //{ // CMD += 2; // calculation += " + 2"; // formula += " + Improved Grapple"; //} //all AC penalties affect CMD int negativeACMods = GetAllNegativeACMods(); if (negativeACMods != 0) { CMD += GetAllNegativeACMods(); formula += negativeACMods + " negative AC mods"; } if (SizeMod < 0) { CMD += SizeMod * -1; // don't count more than once } if (DexMod < 0) { CMD += DexMod * -1; // don't count more than once } if (_monSBSearch.HasSubType("swarm")) { CMD = 0; formula = "+0 swarm"; } string holdCMD = Utility.GetNonParenValue(CMDString); if (holdCMD == "-") { holdCMD = "0"; } if (CMD == Convert.ToInt32(holdCMD)) { _messageXML.AddPass(CheckName); } else { _messageXML.AddFail(CheckName, CMD.ToString(), holdCMD, formula); } }