202/05/24 Evening Update

Archivist should use INT for epic spell DCs, not WIS.
Fixed Sublime Chord epic spell DCs.
This commit is contained in:
Jaysyn904
2026-05-24 20:44:14 -04:00
parent 282b336321
commit 49a89f5055
2 changed files with 77 additions and 56 deletions

View File

@@ -823,41 +823,54 @@ int GetDCSchoolFocusAdjustment(object oPC, string sChool)
return nNewDC; return nNewDC;
} }
int GetEpicSpellSaveDC(object oCaster = OBJECT_SELF, object oTarget = OBJECT_INVALID, int nSpellID = -1) int GetEpicSpellSaveDC(object oCaster = OBJECT_SELF, object oTarget = OBJECT_INVALID, int nSpellID = -1)
{ {
int iDiv = GetPrCAdjustedCasterLevelByType(TYPE_DIVINE, oCaster); // ie. wisdom determines DC int iDiv = GetPrCAdjustedCasterLevelByType(TYPE_DIVINE, oCaster); // ie. wisdom determines DC
int iWiz = GetPrCAdjustedCasterLevel(CLASS_TYPE_WIZARD, oCaster); // int determines DC int iWiz = GetPrCAdjustedCasterLevel(CLASS_TYPE_WIZARD, oCaster); // int determines DC
int iWMa = GetPrCAdjustedCasterLevel(CLASS_TYPE_WARMAGE, oCaster); // cha determines DC int iWMa = GetPrCAdjustedCasterLevel(CLASS_TYPE_WARMAGE, oCaster); // cha determines DC
int iDNc = GetPrCAdjustedCasterLevel(CLASS_TYPE_DREAD_NECROMANCER, oCaster); // cha determines DC int iDNc = GetPrCAdjustedCasterLevel(CLASS_TYPE_DREAD_NECROMANCER, oCaster); // cha determines DC
int iSor = GetPrCAdjustedCasterLevel(CLASS_TYPE_SORCERER, oCaster); // cha determines DC int iSor = GetPrCAdjustedCasterLevel(CLASS_TYPE_SORCERER, oCaster); // cha determines DC
int iWit = GetPrCAdjustedCasterLevel(CLASS_TYPE_WITCH, oCaster); // wis determines DC int iWit = GetPrCAdjustedCasterLevel(CLASS_TYPE_WITCH, oCaster); // wis determines DC
int iArc = GetPrCAdjustedCasterLevel(CLASS_TYPE_ARCHIVIST, oCaster); // int determines DC int iArc = GetPrCAdjustedCasterLevel(CLASS_TYPE_ARCHIVIST, oCaster); // int determines DC
int iBeg = GetPrCAdjustedCasterLevel(CLASS_TYPE_BEGUILER, oCaster); // int determines DC int iBeg = GetPrCAdjustedCasterLevel(CLASS_TYPE_BEGUILER, oCaster); // int determines DC
int iTpl = GetPrCAdjustedCasterLevel(CLASS_TYPE_TEMPLAR, oCaster); // cha determines DC int iTpl = GetPrCAdjustedCasterLevel(CLASS_TYPE_TEMPLAR, oCaster); // cha determines DC
int iBest = 0; // Sublime Chord uses the primary arcane class for caster level calculation
int iAbility; int iSCh;
if(nSpellID == -1) if(GetLevelByClass(CLASS_TYPE_SUBLIME_CHORD, oCaster) > 0)
nSpellID = PRCGetSpellId(); {
int nPrimaryArcane = GetPrimaryArcaneClass(oCaster);
if (iArc > iBest) { iAbility = ABILITY_INTELLIGENCE; iBest = iWit; } iSCh = GetPrCAdjustedCasterLevel(nPrimaryArcane, oCaster);
if (iTpl > iBest) { iAbility = ABILITY_CHARISMA; iBest = iTpl; } }
if (iWiz > iBest) { iAbility = ABILITY_INTELLIGENCE; iBest = iWiz; } else
if (iWMa > iBest) { iAbility = ABILITY_CHARISMA; iBest = iWMa; } {
if (iDNc > iBest) { iAbility = ABILITY_CHARISMA; iBest = iDNc; } iSCh = 0;
if (iSor > iBest) { iAbility = ABILITY_CHARISMA; iBest = iSor; } }
if (iWit > iBest) { iAbility = ABILITY_WISDOM; iBest = iWit; }
if (iBeg > iBest) { iAbility = ABILITY_INTELLIGENCE; iBest = iBeg; } int iBest = 0;
if (iDiv > iBest) { iAbility = ABILITY_WISDOM; iBest = iDiv; } int iAbility;
if(nSpellID == -1)
int nDC; nSpellID = PRCGetSpellId();
if (iBest) nDC = 20 + GetAbilityModifier(iAbility, oCaster);
else nDC = 20; // DC = 20 if the epic spell is cast some other way. if (iArc > iBest) { iAbility = ABILITY_INTELLIGENCE; iBest = iArc; }
if (iTpl > iBest) { iAbility = ABILITY_CHARISMA; iBest = iTpl; }
nDC += GetDCSchoolFocusAdjustment(oCaster, Get2DACache("spells", "school", nSpellID)); if (iWiz > iBest) { iAbility = ABILITY_INTELLIGENCE; iBest = iWiz; }
nDC += GetChangesToSaveDC(oTarget, oCaster, nSpellID, GetSpellSchool(nSpellID)); if (iWMa > iBest) { iAbility = ABILITY_CHARISMA; iBest = iWMa; }
if (iDNc > iBest) { iAbility = ABILITY_CHARISMA; iBest = iDNc; }
return nDC; if (iSor > iBest) { iAbility = ABILITY_CHARISMA; iBest = iSor; }
if (iWit > iBest) { iAbility = ABILITY_WISDOM; iBest = iWit; }
if (iBeg > iBest) { iAbility = ABILITY_INTELLIGENCE; iBest = iBeg; }
if (iDiv > iBest) { iAbility = ABILITY_WISDOM; iBest = iDiv; }
if (iSCh > iBest) { iAbility = ABILITY_CHARISMA; iBest = iSCh; }
int nDC;
if (iBest) nDC = 20 + GetAbilityModifier(iAbility, oCaster);
else nDC = 20; // DC = 20 if the epic spell is cast some other way.
nDC += GetDCSchoolFocusAdjustment(oCaster, Get2DACache("spells", "school", nSpellID));
nDC += GetChangesToSaveDC(oTarget, oCaster, nSpellID, GetSpellSchool(nSpellID));
return nDC;
} }
// Test main // Test main

View File

@@ -702,38 +702,46 @@ int PRCGetCasterLevel(object oCaster = OBJECT_SELF)
return iReturnLevel; return iReturnLevel;
} }
int PRCGetLastSpellCastClass(object oCaster = OBJECT_SELF) int PRCGetLastSpellCastClass(object oCaster = OBJECT_SELF)
{ {
// note that a barbarian has a class type constant of zero. So nClass == 0 could in principle mean // note that a barbarian has a class type constant of zero. So nClass == 0 could in principle mean
// that a barbarian cast the spell, However, barbarians cannot cast spells, so it doesn't really matter // that a barbarian cast the spell, However, barbarians cannot cast spells, so it doesn't really matter
// beware of Barbarians with UMD, though. Also watch out for spell like abilities // beware of Barbarians with UMD, though. Also watch out for spell like abilities
// might have to provide a fix for these (for instance: if(nClass == -1) nClass = 0; // might have to provide a fix for these (for instance: if(nClass == -1) nClass = 0;
int nClass = GetLocalInt(oCaster, PRC_CASTERCLASS_OVERRIDE); int nClass = GetLocalInt(oCaster, PRC_CASTERCLASS_OVERRIDE);
if(nClass) if(nClass)
{ {
if(DEBUG) DoDebug("PRCGetLastSpellCastClass: found override caster class = "+IntToString(nClass)+", original class = "+IntToString(GetLastSpellCastClass())); if(DEBUG) DoDebug("PRCGetLastSpellCastClass: found override caster class = "+IntToString(nClass)+", original class = "+IntToString(GetLastSpellCastClass()));
return nClass; return nClass;
} }
nClass = GetLastSpellCastClass(); nClass = GetLastSpellCastClass();
int NSB_Class = GetLocalInt(oCaster, "NSB_Class"); int NSB_Class = GetLocalInt(oCaster, "NSB_Class");
if(nClass == CLASS_TYPE_INVALID && GetSpellCastItem() == OBJECT_INVALID && NSB_Class) if(nClass == CLASS_TYPE_INVALID && GetSpellCastItem() == OBJECT_INVALID && NSB_Class)
nClass = NSB_Class; nClass = NSB_Class;
// If caster has Sublime Chord levels, check if the spell // If caster has Sublime Chord levels and is casting an epic spell, always use Sublime Chord
// is outside the base class's native range.
if(GetLevelByClass(CLASS_TYPE_SUBLIME_CHORD, oCaster) > 0 && nClass != CLASS_TYPE_INVALID) if(GetLevelByClass(CLASS_TYPE_SUBLIME_CHORD, oCaster) > 0 && nClass != CLASS_TYPE_INVALID)
{ {
int nSpellID = PRCGetSpellId(oCaster); int nSpellID = PRCGetSpellId(oCaster);
// If the spell is NOT found in the base class's spell list (returns -1), // Epic spells are rows 4000-4172 in spells.2da
// it must be a Sublime Chord spell (Level 4-9 or Epic). if(nSpellID >= 4000 && nSpellID <= 4172)
if(PRCGetSpellLevelForClass(nSpellID, nClass) == -1 && nSpellID != -1)
{ {
nClass = CLASS_TYPE_SUBLIME_CHORD; nClass = CLASS_TYPE_SUBLIME_CHORD;
} }
} }
return nClass; // If caster has Sublime Chord levels, check if the spell
// is outside the base class's native range.
if(GetLevelByClass(CLASS_TYPE_SUBLIME_CHORD, oCaster) > 0 && nClass != CLASS_TYPE_INVALID)
{
int nSpellID = PRCGetSpellId(oCaster);
if(PRCGetSpellLevelForClass(nSpellID, nClass) == -1 && nSpellID != -1)
{
nClass = CLASS_TYPE_SUBLIME_CHORD;
}
}
return nClass;
} }
/* int PRCGetLastSpellCastClass(object oCaster = OBJECT_SELF) /* int PRCGetLastSpellCastClass(object oCaster = OBJECT_SELF)