2026/04/03

Summon Undead now uses PRCGetSpellId().
Ectoplasmic Enhancement now doesn't quit after testing a non-undead.
Warmage no longer has infinite casts of Disrupt Undead.
Crushing Despair now respects Mind Immunity.
Incendiary Cloud now uses MyFirstObjectInShape() and MyNextObjectInShape().
Tweaked prc_s_spellb.nss to always pass oPC to GetSlotCount() since the function is OBJECT_INVALID by default.
Tweaked prc_prereq.nss to always pass oPC to GetSlotCount() since the function is OBJECT_INVALID by default.
Form of Doom's Fear Aura now respects Mind Immunity  and Fear Immunity.
Dread Necromancer's Fear Aura now respects Mind Immunity.
Summon Undead skeletons not how the correct resistances.
Enlighted Fist & Dragon Disciple can now qualify for Improved Spell Resistance.
Cerebremancer can now take Bane Magic.
This commit is contained in:
Jaysyn904
2026-04-03 14:21:10 -04:00
parent 038a4cf88d
commit d94be0fd42
16 changed files with 479 additions and 321 deletions

View File

@@ -12,13 +12,9 @@
//:: Created On: Feb 28, 2002
//:://////////////////////////////////////////////
//:: modified by mr_bumpkin Dec 4, 2003
#include "prc_inc_spells"
void main()
{
DeleteLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR");

View File

@@ -54,7 +54,8 @@ SetLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR", SPELL_SCHOOL_EVOCATION);
int EleDmg = GetLocalInt(OBJECT_SELF, "IC_Damage");
oTarget = GetFirstInPersistentObject(OBJECT_SELF,OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
//oTarget = GetFirstInPersistentObject(OBJECT_SELF,OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
oTarget = MyFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
//Declare the spell shape, size and the location.
while(GetIsObjectValid(oTarget))
{
@@ -91,7 +92,8 @@ SetLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR", SPELL_SCHOOL_EVOCATION);
}
}
//Select the next target within the spell shape.
oTarget = GetNextInPersistentObject(OBJECT_SELF,OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
//oTarget = GetNextInPersistentObject(OBJECT_SELF,OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
oTarget = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
}

View File

@@ -52,7 +52,7 @@ void main()
while(GetIsObjectValid(oTarget))
{
if(!PRCDoResistSpell(oPC, oTarget, nCasterLvl + SPGetPenetr()))
if(!PRCDoResistSpell(oPC, oTarget, nCasterLvl + SPGetPenetr())&& !GetIsImmune(oTarget, IMMUNITY_TYPE_MIND_SPELLS))
{
//Save
if(!PRCMySavingThrow(SAVING_THROW_WILL, oTarget, nDC, SAVING_THROW_TYPE_MIND_SPELLS))

View File

@@ -45,13 +45,121 @@ Created: 7/6/07
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "prc_inc_sp_tch"
#include "prc_inc_sp_tch"
#include "prc_sp_func"
int DoSpell(object oCaster, object oTarget, int nCasterLevel)
{
int nSpell = GetSpellId();
int nBeam;
int nDam;
int nMetaMagic = PRCGetMetaMagicFeat();
int nTouch = PRCDoRangedTouchAttack(oTarget);
int nType = MyPRCGetRacialType(oTarget);
if(nSpell == SPELL_DISRUPT_UNDEAD)
{
nBeam = VFX_BEAM_HOLY;
nDam = d6(1);
nDam += SpellDamagePerDice(oCaster, 1);
if(nMetaMagic & METAMAGIC_MAXIMIZE) nDam = 6;
}
if(nSpell == SPELL_GREATER_DISRUPT_UNDEAD)
{
nBeam = VFX_BEAM_BLACK;
nDam = d6(3);
nDam += SpellDamagePerDice(oCaster, 3);
if(nMetaMagic & METAMAGIC_MAXIMIZE) nDam = 18;
}
if(nMetaMagic & METAMAGIC_EMPOWER) nDam += (nDam/2);
//Beam that acts accordingly
effect eVis = EffectBeam(nBeam, oCaster, BODY_NODE_HAND, !nTouch);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
if(nTouch)
{
if(nType == RACIAL_TYPE_UNDEAD
|| (GetHasFeat(FEAT_TOMB_TAINTED_SOUL, oTarget) && GetAlignmentGoodEvil(oTarget) != ALIGNMENT_GOOD))
{
if(!PRCDoResistSpell(oCaster, oTarget, nCasterLevel + SPGetPenetr()))
{
if(nSpell == SPELL_GREATER_DISRUPT_UNDEAD)
{
//Get hp before damage
int nHP = GetCurrentHitPoints(oTarget);
//Apply Damage
SPApplyEffectToObject(DURATION_TYPE_INSTANT, PRCEffectDamage(oTarget, nDam, DAMAGE_TYPE_POSITIVE), oTarget);
//if enough to kill target, bounce
if(nDam >= nHP)
{
location lLoc = GetLocation(oTarget);
object oTarget2 = MyFirstObjectInShape(SHAPE_SPHERE, FeetToMeters(15.0), lLoc, TRUE);
while(GetIsObjectValid(oTarget2))
{
//Undead, enemy, and not the original target
if((GetRacialType(oTarget2) == RACIAL_TYPE_UNDEAD || (GetHasFeat(FEAT_TOMB_TAINTED_SOUL, oTarget2) && GetAlignmentGoodEvil(oTarget2) != ALIGNMENT_GOOD)
&& GetIsEnemy(oTarget2, oCaster) && (oTarget != oTarget2)))
{
//Black beam, origin chest of previous target
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectBeam(VFX_BEAM_BLACK, oTarget, BODY_NODE_CHEST), oTarget2);
SPApplyEffectToObject(DURATION_TYPE_INSTANT, PRCEffectDamage(oTarget, nDam/2, DAMAGE_TYPE_POSITIVE), oTarget2);
break;
}
oTarget2 = MyNextObjectInShape(SHAPE_SPHERE, FeetToMeters(15.0), lLoc, TRUE);
}
}
}
else SPApplyEffectToObject(DURATION_TYPE_INSTANT, PRCEffectDamage(oTarget, nDam, DAMAGE_TYPE_POSITIVE), oTarget);
}
}
}
return nTouch; // return TRUE if spell charges should be decremented
}
void main()
{
if (!X2PreSpellCastCode()) return;
PRCSetSchool(SPELL_SCHOOL_NECROMANCY);
object oCaster = OBJECT_SELF;
object oTarget = PRCGetSpellTargetObject();
int nCasterLevel = PRCGetCasterLevel(oCaster);
int nEvent = GetLocalInt(oCaster, PRC_SPELL_EVENT); //use bitwise & to extract flags
if(!nEvent) //normal cast
{
if(GetLocalInt(oCaster, PRC_SPELL_HOLD) && oCaster == oTarget)
{ //holding the charge, casting spell on self
SetLocalSpellVariables(oCaster, 1); //change 1 to number of charges
return;
}
DoSpell(oCaster, oTarget, nCasterLevel);
}
else
{
if(nEvent & PRC_SPELL_EVENT_ATTACK)
{
if(DoSpell(oCaster, oTarget, nCasterLevel))
DecrementSpellCharges(oCaster);
}
}
PRCSetSchool();
}
/* #include "prc_inc_sp_tch"
void main()
{
object oPC = OBJECT_SELF;
object oTarget = PRCGetSpellTargetObject();
int nSpell = GetSpellId();
int nSpell = PRCGetSpellId();
int nCasterLvl = PRCGetCasterLevel(oPC);
int nBeam;
int nDam;
@@ -124,4 +232,4 @@ void main()
}
}
PRCSetSchool();
}
} */

View File

@@ -48,7 +48,38 @@ void main()
object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_HUGE, lLoc, FALSE, OBJECT_TYPE_CREATURE);
//loop
while(GetIsObjectValid(oTarget))
while(GetIsObjectValid(oTarget))
{
nRace = MyPRCGetRacialType(oTarget);
//Check for incorporeal undead
if(nRace == RACIAL_TYPE_UNDEAD)
{
if(GetIsIncorporeal(oTarget))
{
// Apply effects to valid target
effect eLink = EffectACIncrease(nBonus, AC_DEFLECTION_BONUS);
eLink = EffectLinkEffects(eLink, EffectTurnResistanceIncrease(nBonus + 1));
eLink = EffectLinkEffects(eLink, EffectTemporaryHitpoints(d8(1) + nBonus - 1));
eLink = EffectLinkEffects(eLink, EffectAttackIncrease(nBonus));
eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_PARALYZED));
//Apply for 1 day
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, HoursToSeconds(24));
}
else
{
SendMessageToPC(oPC, "Target creature is not incorporeal.");
}
}
else
{
SendMessageToPC(oPC, "Target creature is not undead.");
}
// Always advance to next target
oTarget = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_HUGE, lLoc, FALSE, OBJECT_TYPE_CREATURE);
}
/* while(GetIsObjectValid(oTarget))
{
nRace = MyPRCGetRacialType(oTarget);
//Check for incorporeal undead
@@ -74,10 +105,10 @@ void main()
else
{
SendMessageToPC(oPC, "Target creature is not undead.");
return;
continue;
}
oTarget = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_HUGE, lLoc, FALSE, OBJECT_TYPE_CREATURE);
}
} */
//SPEvilShift(oPC);
PRCSetSchool();
}

View File

@@ -22,7 +22,7 @@ void main()
//Declare major variables
object oCaster = OBJECT_SELF;
int nSpellID = GetSpellId();
int nSpellID = PRCGetSpellId();
int nMetaMagic = PRCGetMetaMagicFeat();
int nFNF_Effect;
string sSummon;