Updated AMS marker feats. Removed arcane & divine marker feats. Updated Dread Necromancer for epic progression. Updated weapon baseitem models. Updated new weapons for crafting & npc equip. Updated prefix. Updated release archive.
403 lines
15 KiB
Plaintext
403 lines
15 KiB
Plaintext
|
|
// Use this function to get the adjustments to a spell or SLAs saving throw
|
|
// from the various class effects
|
|
// Update this function if any new classes change saving throws
|
|
int PRCGetSaveDC(object oTarget, object oCaster, int nSpellID = -1);
|
|
|
|
//called just from above and from inc_epicspells
|
|
int GetChangesToSaveDC(object oTarget, object oCaster = OBJECT_SELF, int nSpellID = -1);
|
|
|
|
#include "prc_inc_spells"
|
|
#include "prc_class_const"
|
|
#include "prc_feat_const"
|
|
#include "lookup_2da_spell"
|
|
#include "prcsp_archmaginc"
|
|
#include "prc_alterations"
|
|
#include "prc_add_spl_pen"
|
|
|
|
|
|
|
|
// Check for CLASS_TYPE_HIEROPHANT > 0 in caller
|
|
int GetWasLastSpellHieroSLA(int spell_id, object oCaster = OBJECT_SELF)
|
|
{
|
|
int iAbility = PRCGetLastSpellCastClass() == CLASS_TYPE_INVALID;
|
|
int iSpell = spell_id == SPELL_HOLY_AURA ||
|
|
spell_id == SPELL_UNHOLY_AURA ||
|
|
spell_id == SPELL_BANISHMENT ||
|
|
spell_id == SPELL_BATTLETIDE ||
|
|
spell_id == SPELL_BLADE_BARRIER ||
|
|
spell_id == SPELL_CIRCLE_OF_DOOM ||
|
|
spell_id == SPELL_CONTROL_UNDEAD ||
|
|
spell_id == SPELL_CREATE_GREATER_UNDEAD ||
|
|
spell_id == SPELL_CREATE_UNDEAD ||
|
|
spell_id == SPELL_CURE_CRITICAL_WOUNDS ||
|
|
spell_id == SPELL_DEATH_WARD ||
|
|
spell_id == SPELL_DESTRUCTION ||
|
|
spell_id == SPELL_DISMISSAL ||
|
|
spell_id == SPELL_DIVINE_POWER ||
|
|
spell_id == SPELL_EARTHQUAKE ||
|
|
spell_id == SPELL_ENERGY_DRAIN ||
|
|
spell_id == SPELL_ETHEREALNESS ||
|
|
spell_id == SPELL_FIRE_STORM ||
|
|
spell_id == SPELL_FLAME_STRIKE ||
|
|
spell_id == SPELL_FREEDOM_OF_MOVEMENT ||
|
|
spell_id == SPELL_GATE ||
|
|
spell_id == SPELL_GREATER_DISPELLING ||
|
|
spell_id == SPELL_GREATER_MAGIC_WEAPON ||
|
|
spell_id == SPELL_GREATER_RESTORATION ||
|
|
spell_id == SPELL_HAMMER_OF_THE_GODS ||
|
|
spell_id == SPELL_HARM ||
|
|
spell_id == SPELL_HEAL ||
|
|
spell_id == SPELL_HEALING_CIRCLE ||
|
|
spell_id == SPELL_IMPLOSION ||
|
|
spell_id == SPELL_INFLICT_CRITICAL_WOUNDS ||
|
|
spell_id == SPELL_MASS_HEAL ||
|
|
spell_id == SPELL_MONSTROUS_REGENERATION ||
|
|
spell_id == SPELL_NEUTRALIZE_POISON ||
|
|
spell_id == SPELL_PLANAR_ALLY ||
|
|
spell_id == SPELL_POISON ||
|
|
spell_id == SPELL_RAISE_DEAD ||
|
|
spell_id == SPELL_REGENERATE ||
|
|
spell_id == SPELL_RESTORATION ||
|
|
spell_id == SPELL_RESURRECTION ||
|
|
spell_id == SPELL_SLAY_LIVING ||
|
|
spell_id == SPELL_SPELL_RESISTANCE ||
|
|
spell_id == SPELL_STORM_OF_VENGEANCE ||
|
|
spell_id == SPELL_SUMMON_CREATURE_IV ||
|
|
spell_id == SPELL_SUMMON_CREATURE_IX ||
|
|
spell_id == SPELL_SUMMON_CREATURE_V ||
|
|
spell_id == SPELL_SUMMON_CREATURE_VI ||
|
|
spell_id == SPELL_SUMMON_CREATURE_VII ||
|
|
spell_id == SPELL_SUMMON_CREATURE_VIII ||
|
|
spell_id == SPELL_SUNBEAM ||
|
|
spell_id == SPELL_TRUE_SEEING ||
|
|
spell_id == SPELL_UNDEATH_TO_DEATH ||
|
|
spell_id == SPELL_UNDEATHS_ETERNAL_FOE ||
|
|
spell_id == SPELL_WORD_OF_FAITH;
|
|
|
|
return iAbility && iSpell;
|
|
}
|
|
|
|
int GetHierophantSLAAdjustment(int spell_id, object oCaster = OBJECT_SELF)
|
|
{
|
|
int retval = 0;
|
|
|
|
if (GetLevelByClass(CLASS_TYPE_HIEROPHANT, oCaster) > 0 && GetWasLastSpellHieroSLA(spell_id, oCaster) )
|
|
{
|
|
retval = StringToInt( lookup_spell_cleric_level(spell_id) );
|
|
retval -= GetLevelByClass(CLASS_TYPE_HIEROPHANT, oCaster);
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
int GetHeartWarderDC(int spell_id, object oCaster = OBJECT_SELF)
|
|
{
|
|
// Check the curent school
|
|
if (GetLocalInt(oCaster, "X2_L_LAST_SPELLSCHOOL_VAR") != SPELL_SCHOOL_ENCHANTMENT)
|
|
return 0;
|
|
|
|
if (!GetHasFeat(FEAT_VOICE_SIREN, oCaster)) return 0;
|
|
|
|
// Bonus Requires Verbal Spells
|
|
string VS = lookup_spell_vs(PRCGetSpellId());
|
|
if (VS != "v" && VS != "vs")
|
|
return 0;
|
|
|
|
// These feats provide greater bonuses or remove the Verbal requirement
|
|
if (PRCGetMetaMagicFeat() & METAMAGIC_SILENT
|
|
|| GetHasFeat(FEAT_GREATER_SPELL_FOCUS_ENCHANTMENT, oCaster)
|
|
|| GetHasFeat(FEAT_EPIC_SPELL_FOCUS_ENCHANTMENT, oCaster))
|
|
return 0;
|
|
|
|
return 2;
|
|
}
|
|
|
|
//Elemental Savant DC boost based on elemental spell type.
|
|
int ElementalSavantDC(int spell_id, object oCaster = OBJECT_SELF)
|
|
{
|
|
int nDC = 0;
|
|
int nES;
|
|
|
|
// All Elemental Savants will have this feat
|
|
// when they first gain a DC bonus.
|
|
if (GetHasFeat(FEAT_ES_FOCUS_1, oCaster)) {
|
|
// get spell elemental type
|
|
string element = ChangedElementalType(spell_id, oCaster);
|
|
|
|
// Any value that does not match one of the enumerated feats
|
|
int feat = 0;
|
|
|
|
// Specify the elemental type rather than lookup by class?
|
|
if (element == "Fire")
|
|
{
|
|
feat = FEAT_ES_FIRE;
|
|
nES = GetLevelByClass(CLASS_TYPE_ES_FIRE,oCaster);
|
|
}
|
|
else if (element == "Cold")
|
|
{
|
|
feat = FEAT_ES_COLD;
|
|
nES = GetLevelByClass(CLASS_TYPE_ES_COLD,oCaster);
|
|
}
|
|
else if (element == "Electricity")
|
|
{
|
|
feat = FEAT_ES_ELEC;
|
|
nES = GetLevelByClass(CLASS_TYPE_ES_ELEC,oCaster);
|
|
}
|
|
else if (element == "Acid")
|
|
{
|
|
feat = FEAT_ES_ACID;
|
|
nES = GetLevelByClass(CLASS_TYPE_ES_ACID,oCaster);
|
|
}
|
|
|
|
// Now determine the bonus
|
|
if (feat && GetHasFeat(feat, oCaster))
|
|
{
|
|
|
|
if (nES > 28) nDC = 10;
|
|
else if (nES > 25) nDC = 9;
|
|
else if (nES > 22) nDC = 8;
|
|
else if (nES > 19) nDC = 7;
|
|
else if (nES > 16) nDC = 6;
|
|
else if (nES > 13) nDC = 5;
|
|
else if (nES > 10) nDC = 4;
|
|
else if (nES > 7) nDC = 3;
|
|
else if (nES > 4) nDC = 2;
|
|
else if (nES > 1) nDC = 1;
|
|
|
|
}
|
|
}
|
|
// SendMessageToPC(GetFirstPC(), "Your Elemental Focus modifier is " + IntToString(nDC));
|
|
return nDC;
|
|
}
|
|
|
|
|
|
|
|
//Red Wizard DC boost based on spell school specialization
|
|
int RedWizardDC(int spell_id, object oCaster = OBJECT_SELF)
|
|
{
|
|
int iRedWizard = GetLevelByClass(CLASS_TYPE_RED_WIZARD, oCaster);
|
|
int nDC;
|
|
|
|
if (iRedWizard > 0)
|
|
{
|
|
int nSpell = PRCGetSpellId();
|
|
string sSpellSchool = lookup_spell_school(nSpell);
|
|
int iSpellSchool;
|
|
int iRWSpec;
|
|
|
|
if (sSpellSchool == "A") iSpellSchool = SPELL_SCHOOL_ABJURATION;
|
|
else if (sSpellSchool == "C") iSpellSchool = SPELL_SCHOOL_CONJURATION;
|
|
else if (sSpellSchool == "D") iSpellSchool = SPELL_SCHOOL_DIVINATION;
|
|
else if (sSpellSchool == "E") iSpellSchool = SPELL_SCHOOL_ENCHANTMENT;
|
|
else if (sSpellSchool == "V") iSpellSchool = SPELL_SCHOOL_EVOCATION;
|
|
else if (sSpellSchool == "I") iSpellSchool = SPELL_SCHOOL_ILLUSION;
|
|
else if (sSpellSchool == "N") iSpellSchool = SPELL_SCHOOL_NECROMANCY;
|
|
else if (sSpellSchool == "T") iSpellSchool = SPELL_SCHOOL_TRANSMUTATION;
|
|
|
|
if (GetHasFeat(FEAT_RW_TF_ABJ, oCaster)) iRWSpec = SPELL_SCHOOL_ABJURATION;
|
|
else if (GetHasFeat(FEAT_RW_TF_CON, oCaster)) iRWSpec = SPELL_SCHOOL_CONJURATION;
|
|
else if (GetHasFeat(FEAT_RW_TF_DIV, oCaster)) iRWSpec = SPELL_SCHOOL_DIVINATION;
|
|
else if (GetHasFeat(FEAT_RW_TF_ENC, oCaster)) iRWSpec = SPELL_SCHOOL_ENCHANTMENT;
|
|
else if (GetHasFeat(FEAT_RW_TF_EVO, oCaster)) iRWSpec = SPELL_SCHOOL_EVOCATION;
|
|
else if (GetHasFeat(FEAT_RW_TF_ILL, oCaster)) iRWSpec = SPELL_SCHOOL_ILLUSION;
|
|
else if (GetHasFeat(FEAT_RW_TF_NEC, oCaster)) iRWSpec = SPELL_SCHOOL_NECROMANCY;
|
|
else if (GetHasFeat(FEAT_RW_TF_TRS, oCaster)) iRWSpec = SPELL_SCHOOL_TRANSMUTATION;
|
|
|
|
if (iSpellSchool == iRWSpec)
|
|
{
|
|
|
|
nDC = 1;
|
|
|
|
if (iRedWizard > 29) nDC = 16;
|
|
else if (iRedWizard > 27) nDC = 15;
|
|
else if (iRedWizard > 25) nDC = 14;
|
|
else if (iRedWizard > 23) nDC = 13;
|
|
else if (iRedWizard > 21) nDC = 12;
|
|
else if (iRedWizard > 19) nDC = 11;
|
|
else if (iRedWizard > 17) nDC = 10;
|
|
else if (iRedWizard > 15) nDC = 9;
|
|
else if (iRedWizard > 13) nDC = 8;
|
|
else if (iRedWizard > 11) nDC = 7;
|
|
else if (iRedWizard > 9) nDC = 6;
|
|
else if (iRedWizard > 7) nDC = 5;
|
|
else if (iRedWizard > 5) nDC = 4;
|
|
else if (iRedWizard > 3) nDC = 3;
|
|
else if (iRedWizard > 1) nDC = 2;
|
|
}
|
|
|
|
|
|
}
|
|
// SendMessageToPC(GetFirstPC(), "Your Spell Power modifier is " + IntToString(nDC));
|
|
return nDC;
|
|
}
|
|
|
|
|
|
//Tattoo Focus DC boost based on spell school specialization
|
|
int TattooFocus(int spell_id, object oCaster = OBJECT_SELF)
|
|
{
|
|
|
|
int nDC;
|
|
int nSpell = PRCGetSpellId();
|
|
string sSpellSchool = lookup_spell_school(nSpell);
|
|
int iSpellSchool;
|
|
int iRWSpec;
|
|
|
|
if (sSpellSchool == "A") iSpellSchool = SPELL_SCHOOL_ABJURATION;
|
|
else if (sSpellSchool == "C") iSpellSchool = SPELL_SCHOOL_CONJURATION;
|
|
else if (sSpellSchool == "D") iSpellSchool = SPELL_SCHOOL_DIVINATION;
|
|
else if (sSpellSchool == "E") iSpellSchool = SPELL_SCHOOL_ENCHANTMENT;
|
|
else if (sSpellSchool == "V") iSpellSchool = SPELL_SCHOOL_EVOCATION;
|
|
else if (sSpellSchool == "I") iSpellSchool = SPELL_SCHOOL_ILLUSION;
|
|
else if (sSpellSchool == "N") iSpellSchool = SPELL_SCHOOL_NECROMANCY;
|
|
else if (sSpellSchool == "T") iSpellSchool = SPELL_SCHOOL_TRANSMUTATION;
|
|
|
|
if (GetHasFeat(FEAT_RW_TF_ABJ, oCaster)) iRWSpec = SPELL_SCHOOL_ABJURATION;
|
|
else if (GetHasFeat(FEAT_RW_TF_CON, oCaster)) iRWSpec = SPELL_SCHOOL_CONJURATION;
|
|
else if (GetHasFeat(FEAT_RW_TF_DIV, oCaster)) iRWSpec = SPELL_SCHOOL_DIVINATION;
|
|
else if (GetHasFeat(FEAT_RW_TF_ENC, oCaster)) iRWSpec = SPELL_SCHOOL_ENCHANTMENT;
|
|
else if (GetHasFeat(FEAT_RW_TF_EVO, oCaster)) iRWSpec = SPELL_SCHOOL_EVOCATION;
|
|
else if (GetHasFeat(FEAT_RW_TF_ILL, oCaster)) iRWSpec = SPELL_SCHOOL_ILLUSION;
|
|
else if (GetHasFeat(FEAT_RW_TF_NEC, oCaster)) iRWSpec = SPELL_SCHOOL_NECROMANCY;
|
|
else if (GetHasFeat(FEAT_RW_TF_TRS, oCaster)) iRWSpec = SPELL_SCHOOL_TRANSMUTATION;
|
|
|
|
if (iSpellSchool == iRWSpec)
|
|
{
|
|
nDC = 1;
|
|
}
|
|
return nDC;
|
|
}
|
|
|
|
// Shadow Weave Feat
|
|
// DC +1 (school Ench,Illu,Necro)
|
|
int ShadowWeaveDC(int spell_id, object oCaster = OBJECT_SELF)
|
|
{
|
|
int iShadow = GetLevelByClass(CLASS_TYPE_SHADOW_ADEPT, oCaster);
|
|
int nDC;
|
|
|
|
if (iShadow > 0)
|
|
{
|
|
int nSpell = PRCGetSpellId();
|
|
string sSpellSchool = lookup_spell_school(nSpell);
|
|
int iSpellSchool;
|
|
|
|
if (sSpellSchool == "A") iSpellSchool = SPELL_SCHOOL_ABJURATION;
|
|
else if (sSpellSchool == "C") iSpellSchool = SPELL_SCHOOL_CONJURATION;
|
|
else if (sSpellSchool == "D") iSpellSchool = SPELL_SCHOOL_DIVINATION;
|
|
else if (sSpellSchool == "E") iSpellSchool = SPELL_SCHOOL_ENCHANTMENT;
|
|
else if (sSpellSchool == "V") iSpellSchool = SPELL_SCHOOL_EVOCATION;
|
|
else if (sSpellSchool == "I") iSpellSchool = SPELL_SCHOOL_ILLUSION;
|
|
else if (sSpellSchool == "N") iSpellSchool = SPELL_SCHOOL_NECROMANCY;
|
|
else if (sSpellSchool == "T") iSpellSchool = SPELL_SCHOOL_TRANSMUTATION;
|
|
|
|
if (iSpellSchool == SPELL_SCHOOL_ENCHANTMENT || iSpellSchool == SPELL_SCHOOL_NECROMANCY || iSpellSchool == SPELL_SCHOOL_ILLUSION)
|
|
{
|
|
|
|
if (iShadow > 29) nDC = 10;
|
|
else if (iShadow > 26) nDC = 9;
|
|
else if (iShadow > 23) nDC = 8;
|
|
else if (iShadow > 20) nDC = 7;
|
|
else if (iShadow > 17) nDC = 6;
|
|
else if (iShadow > 14) nDC = 5;
|
|
else if (iShadow > 11) nDC = 4;
|
|
else if (iShadow > 8) nDC = 3;
|
|
else if (iShadow > 5) nDC = 2;
|
|
else if (iShadow > 2) nDC = 1;
|
|
}
|
|
|
|
|
|
}
|
|
//SendMessageToPC(GetFirstPC(), "Your Spell DC modifier is " + IntToString(nDC));
|
|
return nDC;
|
|
}
|
|
|
|
int KOTCSpellFocusVsDemons(object oTarget, object oCaster)
|
|
{
|
|
int nDC = 0;
|
|
int iKOTC = GetLevelByClass(CLASS_TYPE_KNIGHT_CHALICE, oCaster);
|
|
|
|
if (iKOTC >= 1)
|
|
{
|
|
if (MyPRCGetRacialType(oTarget) == RACIAL_TYPE_OUTSIDER)
|
|
{
|
|
if (GetAlignmentGoodEvil(oTarget) == ALIGNMENT_EVIL)
|
|
{
|
|
nDC = 2;
|
|
}
|
|
}
|
|
}
|
|
return nDC;
|
|
}
|
|
|
|
int BloodMagusBloodComponent(object oCaster)
|
|
{
|
|
int nDC = 0;
|
|
if (GetLevelByClass(CLASS_TYPE_BLOOD_MAGUS, oCaster) > 0 && GetLocalInt(oCaster, "BloodComponent") == TRUE)
|
|
{
|
|
nDC = 1;
|
|
effect eSelfDamage = EffectDamage(1, DAMAGE_TYPE_MAGICAL);
|
|
// To make sure it doesn't cause a conc check
|
|
DelayCommand(1.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, eSelfDamage, oCaster));
|
|
}
|
|
return nDC;
|
|
}
|
|
|
|
int RunecasterRunePowerDC(object oCaster)
|
|
{
|
|
int nDC = 0;
|
|
int nClass = GetLevelByClass(CLASS_TYPE_RUNECASTER, oCaster);
|
|
if (nClass >= 2)
|
|
{
|
|
if (nClass >= 30) nDC = 10;
|
|
else if (nClass >= 27) nDC = 9;
|
|
else if (nClass >= 24) nDC = 8;
|
|
else if (nClass >= 21) nDC = 7;
|
|
else if (nClass >= 18) nDC = 6;
|
|
else if (nClass >= 15) nDC = 5;
|
|
else if (nClass >= 12) nDC = 4;
|
|
else if (nClass >= 9) nDC = 3;
|
|
else if (nClass >= 5) nDC = 2;
|
|
else if (nClass >= 2) nDC = 1;
|
|
}
|
|
return nDC;
|
|
}
|
|
|
|
int PRCGetSaveDC(object oTarget, object oCaster, int nSpellID = -1)
|
|
{
|
|
if(nSpellID == -1)
|
|
nSpellID = PRCGetSpellId();
|
|
//10+spelllevel+stat(cha default)
|
|
int nDC = GetSpellSaveDC();
|
|
// For when you want to assign the caster DC
|
|
//this does take feat/race/class into account, it only overrides the baseDC
|
|
if (GetLocalInt(oCaster, PRC_DC_BASE_OVERRIDE) != 0)
|
|
{
|
|
nDC = GetLocalInt(oCaster, PRC_DC_BASE_OVERRIDE);
|
|
SendMessageToPC(oCaster, "Forced Base-DC casting at DC " + IntToString(nDC));
|
|
}
|
|
nDC += GetChangesToSaveDC(oTarget, oCaster, nSpellID);
|
|
return nDC;
|
|
|
|
}
|
|
|
|
//called just from above and from inc_epicspells
|
|
int GetChangesToSaveDC(object oTarget, object oCaster = OBJECT_SELF, int nSpellID = -1)
|
|
{
|
|
if(nSpellID == -1)
|
|
nSpellID = PRCGetSpellId();
|
|
int nDC;
|
|
nDC += ElementalSavantDC(nSpellID, oCaster);
|
|
nDC += GetHierophantSLAAdjustment(nSpellID, oCaster);
|
|
nDC += GetHeartWarderDC(nSpellID, oCaster);
|
|
nDC += GetSpellPowerBonus(oCaster);
|
|
nDC += ShadowWeaveDC(nSpellID, oCaster);
|
|
nDC += RedWizardDC(nSpellID, oCaster);
|
|
nDC += TattooFocus(nSpellID, oCaster);
|
|
nDC += KOTCSpellFocusVsDemons(oTarget, oCaster);
|
|
nDC += BloodMagusBloodComponent(oCaster);
|
|
nDC += RunecasterRunePowerDC(oCaster);
|
|
nDC += GetLocalInt(oCaster, PRC_DC_ADJUSTMENT);//this is for builder use
|
|
return nDC;
|
|
|
|
}
|