PRC8/nwn/nwnprc/trunk/users/Stratovarius/prc_add_spell_dc.nss
Jaysyn904 6ec137a24e Updated AMS marker feats
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.
2024-02-11 14:01:05 -05:00

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;
}