2026/01/2 Update
Sun Domain power actually destroys undead. Fixed BCM's Pouncing Strike. Monkey Grip only applies penalty when appropriate. Forsaker should stack all sources of Spell Resistance. Hexblade's Dark Companion retains the sanctuary effect across game saves. Ottiluke's Resilient Sphere is a Reflex save, not a WIll save.
This commit is contained in:
@@ -1,7 +1,50 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Sun Domain Power
|
||||
//:: prc_dom_sun.nss
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Type of Feat: Domain.
|
||||
|
||||
Specifics: Once per day, you can perform a greater turning
|
||||
against undead in place of a regular turning. The greater
|
||||
turning destroys undead instead of turning them.
|
||||
|
||||
Use: Selected.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
#include "inc_newspellbook"
|
||||
#include "prc_inc_domain"
|
||||
#include "prc_inc_spells"
|
||||
|
||||
void main()
|
||||
{
|
||||
object oPC = OBJECT_SELF;
|
||||
|
||||
// Used by the uses per day check code for bonus domains
|
||||
if(!DecrementDomainUses(PRC_DOMAIN_SUN, oPC)) return;
|
||||
|
||||
if(!CheckTurnUndeadUses(oPC, 1))
|
||||
{
|
||||
SpeakStringByStrRef(40550);
|
||||
return;
|
||||
}
|
||||
|
||||
// Mystics with sun domain can turn undead, but can't use greater turning
|
||||
int bMystic = GetLevelByClass(CLASS_TYPE_MYSTIC, oPC) && GetHasFeat(FEAT_BONUS_DOMAIN_SUN, oPC);
|
||||
|
||||
void main()
|
||||
if(bMystic)
|
||||
{
|
||||
if(!GetHasFeat(FEAT_TURN_UNDEAD, oPC))
|
||||
return;
|
||||
}
|
||||
|
||||
ActionDoCommand(SetLocalInt(oPC, "UsingSunDomain", TRUE));
|
||||
ActionCastSpellAtObject(SPELLABILITY_TURN_UNDEAD, oPC, METAMAGIC_ANY, TRUE);
|
||||
ActionDoCommand(DelayCommand(0.1f, DeleteLocalInt(oPC, "UsingSunDomain")));
|
||||
}
|
||||
|
||||
|
||||
/* void main()
|
||||
{
|
||||
object oPC = OBJECT_SELF;
|
||||
|
||||
@@ -20,4 +63,4 @@ void main()
|
||||
ActionCastSpell(SPELLABILITY_TURN_UNDEAD);
|
||||
ActionDoCommand(DecrementRemainingFeatUses(oPC, FEAT_TURN_UNDEAD));
|
||||
ActionDoCommand(DeleteLocalInt(oPC, "UsingSunDomain"));
|
||||
}
|
||||
} */
|
||||
@@ -9,6 +9,101 @@
|
||||
#include "prc_inc_combat"
|
||||
#include "inc_dynconv"
|
||||
#include "prc_alterations"
|
||||
|
||||
int PRCStackSpellResistance(object oPC)
|
||||
{
|
||||
int nTotalSR = 0;
|
||||
|
||||
// Racial Spell Resistance
|
||||
int nRacialSR = 0;
|
||||
if(GetHasFeat(FEAT_SPELL27, oPC)) nRacialSR = 27;
|
||||
else if(GetHasFeat(FEAT_SPELL25, oPC)) nRacialSR = 25;
|
||||
else if(GetHasFeat(FEAT_SPELL23, oPC)) nRacialSR = 23;
|
||||
else if(GetHasFeat(FEAT_SPELL22, oPC)) nRacialSR = 22;
|
||||
else if(GetHasFeat(FEAT_SPELL21, oPC)) nRacialSR = 21;
|
||||
else if(GetHasFeat(FEAT_SPELL20, oPC)) nRacialSR = 20;
|
||||
else if(GetHasFeat(FEAT_SPELL19, oPC)) nRacialSR = 19;
|
||||
else if(GetHasFeat(FEAT_SPELL18, oPC)) nRacialSR = 18;
|
||||
else if(GetHasFeat(FEAT_SPELL17, oPC)) nRacialSR = 17;
|
||||
else if(GetHasFeat(FEAT_SPELL16, oPC)) nRacialSR = 16;
|
||||
else if(GetHasFeat(FEAT_SPELL15, oPC)) nRacialSR = 15;
|
||||
else if(GetHasFeat(FEAT_SPELL14, oPC)) nRacialSR = 14;
|
||||
else if(GetHasFeat(FEAT_SPELL13, oPC)) nRacialSR = 13;
|
||||
else if(GetHasFeat(FEAT_SPELL11, oPC)) nRacialSR = 11;
|
||||
else if(GetHasFeat(FEAT_SPELL10, oPC)) nRacialSR = 10;
|
||||
else if(GetHasFeat(FEAT_SPELL8, oPC)) nRacialSR = 8;
|
||||
else if(GetHasFeat(FEAT_SPELL5, oPC)) nRacialSR = 5;
|
||||
|
||||
if(nRacialSR > 0)
|
||||
{
|
||||
nTotalSR += nRacialSR + GetHitDice(oPC); // Base SR + 1 per level
|
||||
}
|
||||
|
||||
// Improved Spell Resistance feats (epic feats, +2 SR each, stackable)
|
||||
int nImprovedSR = 0;
|
||||
if(GetHasFeat(FEAT_EPIC_IMPROVED_SPELL_RESISTANCE_1, oPC)) nImprovedSR += 2;
|
||||
if(GetHasFeat(FEAT_EPIC_IMPROVED_SPELL_RESISTANCE_2, oPC)) nImprovedSR += 2;
|
||||
if(GetHasFeat(FEAT_EPIC_IMPROVED_SPELL_RESISTANCE_3, oPC)) nImprovedSR += 2;
|
||||
if(GetHasFeat(FEAT_EPIC_IMPROVED_SPELL_RESISTANCE_4, oPC)) nImprovedSR += 2;
|
||||
if(GetHasFeat(FEAT_EPIC_IMPROVED_SPELL_RESISTANCE_5, oPC)) nImprovedSR += 2;
|
||||
if(GetHasFeat(FEAT_EPIC_IMPROVED_SPELL_RESISTANCE_6, oPC)) nImprovedSR += 2;
|
||||
if(GetHasFeat(FEAT_EPIC_IMPROVED_SPELL_RESISTANCE_7, oPC)) nImprovedSR += 2;
|
||||
if(GetHasFeat(FEAT_EPIC_IMPROVED_SPELL_RESISTANCE_8, oPC)) nImprovedSR += 2;
|
||||
if(GetHasFeat(FEAT_EPIC_IMPROVED_SPELL_RESISTANCE_9, oPC)) nImprovedSR += 2;
|
||||
if(GetHasFeat(FEAT_EPIC_IMPROVED_SPELL_RESISTANCE_10, oPC)) nImprovedSR += 2;
|
||||
|
||||
nTotalSR += nImprovedSR;
|
||||
|
||||
// Class-based Spell Resistance
|
||||
int nMonkLvl = GetLevelByClass(CLASS_TYPE_MONK, oPC);
|
||||
int nForsakerLvl = GetLevelByClass(CLASS_TYPE_FORSAKER, oPC);
|
||||
int nEnlightenedFistLvl = GetLevelByClass(CLASS_TYPE_ENLIGHTENEDFIST, oPC);
|
||||
int nDraconicMysteriesLvl = GetLevelByClass(CLASS_TYPE_INITIATE_DRACONIC, oPC);
|
||||
int nSanctifiedMindLvl = GetLevelByClass(CLASS_TYPE_SANCTIFIED_MIND, oPC);
|
||||
int nUrPriestLvl = GetLevelByClass(CLASS_TYPE_UR_PRIEST, oPC);
|
||||
|
||||
// Monk Diamond Soul (level 13+)
|
||||
if(nMonkLvl >= 13)
|
||||
{
|
||||
nTotalSR += (nMonkLvl + 10);
|
||||
}
|
||||
|
||||
// Forsaker SR
|
||||
if(nForsakerLvl > 0)
|
||||
{
|
||||
nTotalSR += (10 + nForsakerLvl);
|
||||
}
|
||||
|
||||
// Enlightened Fist Diamond Soul (level 9+)
|
||||
if(nEnlightenedFistLvl >= 9)
|
||||
{
|
||||
nTotalSR += (10 + nMonkLvl + nEnlightenedFistLvl);
|
||||
}
|
||||
|
||||
// Initiate of Draconic Mysteries (level 7+)
|
||||
if(nDraconicMysteriesLvl >= 7)
|
||||
{
|
||||
nTotalSR += (15 + nDraconicMysteriesLvl);
|
||||
}
|
||||
|
||||
// Sanctified Mind Power Resistance (level 6+)
|
||||
if(nSanctifiedMindLvl >= 6)
|
||||
{
|
||||
nTotalSR += (5 + GetHitDice(oPC));
|
||||
}
|
||||
|
||||
// Ur-Priest Divine Spell Resistance
|
||||
if(nUrPriestLvl >= 8)
|
||||
{
|
||||
nTotalSR += 20; // SR 20 at level 8+
|
||||
}
|
||||
else if(nUrPriestLvl >= 4)
|
||||
{
|
||||
nTotalSR += 15; // SR 15 at level 4-7
|
||||
}
|
||||
|
||||
return nTotalSR;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
@@ -37,7 +132,13 @@ void main()
|
||||
int nForsakerLvlCheck;
|
||||
int nBonus = nForsakerLvl/2;
|
||||
int nRegen = 1 + nForsakerLvl/4;
|
||||
int nSR = 10 + nForsakerLvl;
|
||||
int nSR = 10 + nForsakerLvl;
|
||||
|
||||
// Calculate stacked spell resistance for Forsaker special case
|
||||
int nTotalSR = PRCStackSpellResistance(oPC);
|
||||
|
||||
// Apply combined SR as single property
|
||||
IPSafeAddItemProperty(oSkin, ItemPropertyBonusSpellResistance(GetSRByValue(nTotalSR)), 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
|
||||
|
||||
if(nEvent == FALSE)
|
||||
{
|
||||
|
||||
@@ -34,7 +34,9 @@ void main()
|
||||
eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_GLOW_GREY));//VFX_DUR_PROT_PRC_SHADOW_ARMOR
|
||||
eLink = EffectLinkEffects(eLink, EffectCutsceneGhost());
|
||||
eLink = EffectLinkEffects(eLink, EffectEthereal());
|
||||
eLink = TagEffect(eLink, "DARK_COMPANION");
|
||||
eLink = UnyieldingEffect(eLink);
|
||||
|
||||
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oCompanion);
|
||||
}
|
||||
@@ -10,31 +10,75 @@
|
||||
* This just tells it to follow the master and do nothing else.
|
||||
*/
|
||||
|
||||
#include "inc_debug"
|
||||
|
||||
void main()
|
||||
{
|
||||
object oMaster = GetMaster();
|
||||
|
||||
if(!GetIsObjectValid(oMaster))
|
||||
{
|
||||
SetIsDestroyable(TRUE, FALSE, FALSE);
|
||||
DestroyObject(OBJECT_SELF, 0.2);
|
||||
}
|
||||
|
||||
// Forces it to move to the master's attack target so it take the penalty.
|
||||
if(GetIsInCombat(oMaster))
|
||||
{
|
||||
object oMove = GetAttackTarget(oMaster);
|
||||
if(GetIsObjectValid(oMove))
|
||||
{
|
||||
ClearAllActions(TRUE);
|
||||
ActionForceFollowObject(GetAttackTarget(oMaster), 1.0f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearAllActions(TRUE);
|
||||
ActionForceFollowObject(oMaster, 4.0f);
|
||||
}
|
||||
#include "inc_debug"
|
||||
#include "prc_misc_const"
|
||||
|
||||
void main()
|
||||
{
|
||||
object oMaster = GetMaster();
|
||||
|
||||
if(!GetIsObjectValid(oMaster))
|
||||
{
|
||||
SetIsDestroyable(TRUE, FALSE, FALSE);
|
||||
DestroyObject(OBJECT_SELF, 0.2);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for missing DARK_COMPANION effects and reapply if needed
|
||||
int bHasAOE = FALSE;
|
||||
int bHasGhost = FALSE;
|
||||
int bHasEthereal = FALSE;
|
||||
|
||||
effect eCheck = GetFirstEffect(OBJECT_SELF);
|
||||
while(GetIsEffectValid(eCheck))
|
||||
{
|
||||
if(GetEffectTag(eCheck) == "DARK_COMPANION")
|
||||
{
|
||||
int nType = GetEffectType(eCheck);
|
||||
if(nType == EFFECT_TYPE_AREA_OF_EFFECT) bHasAOE = TRUE;
|
||||
if(nType == EFFECT_TYPE_CUTSCENEGHOST) bHasGhost = TRUE;
|
||||
if(nType == EFFECT_TYPE_ETHEREAL) bHasEthereal = TRUE;
|
||||
}
|
||||
eCheck = GetNextEffect(OBJECT_SELF);
|
||||
}
|
||||
|
||||
// Reapply all effects if any are missing
|
||||
if(!bHasAOE || !bHasGhost || !bHasEthereal)
|
||||
{
|
||||
// Remove any existing DARK_COMPANION effects first
|
||||
eCheck = GetFirstEffect(OBJECT_SELF);
|
||||
while(GetIsEffectValid(eCheck))
|
||||
{
|
||||
if(GetEffectTag(eCheck) == "DARK_COMPANION")
|
||||
{
|
||||
RemoveEffect(OBJECT_SELF, eCheck);
|
||||
}
|
||||
eCheck = GetNextEffect(OBJECT_SELF);
|
||||
}
|
||||
|
||||
// Reapply the complete effect package
|
||||
effect eLink = EffectAreaOfEffect(VFX_PER_10_FT_INVIS, "prc_hexbl_comp_a", "prc_hexbl_comp_c", "");
|
||||
eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_GLOW_GREY));
|
||||
eLink = EffectLinkEffects(eLink, EffectCutsceneGhost());
|
||||
eLink = EffectLinkEffects(eLink, EffectEthereal());
|
||||
eLink = TagEffect(eLink, "DARK_COMPANION");
|
||||
eLink = SupernaturalEffect(eLink);
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, OBJECT_SELF);
|
||||
}
|
||||
|
||||
// Movement logic
|
||||
if(GetIsInCombat(oMaster))
|
||||
{
|
||||
object oMove = GetAttackTarget(oMaster);
|
||||
if(GetIsObjectValid(oMove))
|
||||
{
|
||||
ClearAllActions(TRUE);
|
||||
ActionForceFollowObject(GetAttackTarget(oMaster), 1.0f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearAllActions(TRUE);
|
||||
ActionForceFollowObject(oMaster, 4.0f);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user