2026/06/05 Update
Added Sanctified damage type. Added Holy damage type. Added Unholy damage type. Added Falling damage type. Added Ballistic damage type. Added Desiccation damage type. Fixed Major Missile's LABEL in spells.2da. Fixed Major Missile's LABEL in des_cft_spells.2da. Fixed Major Missile's LABEL in des_cft_scrolls.2da. Disabled incomplete PnP version of Shades spell. Astaroth's free crafting feats should drop off onRest, when expelling a vestige & when rebinding a vestige. Re-enabled caster level override variable clearing in GetInvokerLevel(). Change Piercing Cold's damagetype to Untyped. Constanted new damagetypes correctly for scripting (@lightbeard) Changed all force spells damagetype to force. Fixed issue with Initiators using Shadows Blade, Ironheart Aura and Shadow Trickster with dual-stances. Changed Eldritch Blast to Untyped damage. Fixed Path of Shadow screwing up caster levels. Changed Sanctify Martial strike to be Holy damage. Changed Vile Martial strike to be Vile damage. Updated Forsaker to work with Warforged "Armor". Added a SignalEvent() to Invisible Needle so it would break Invisibility when it should. Fixed equip exploit with Shou Disciple and monk weapons. Changed Saint template's Holy Touch to do Holy Damage. Changed Horrid Wilting to do Desiccation damage. Fixed Break Enchantment's targeting. Fixed the Command spell to obey mind immunity. Changed Damning Darkness to do Unholy damage. Change the Necrotic spells to do Vile damage. Made Persistent Blade more like PnP and made it dispellable.
This commit is contained in:
@@ -103,7 +103,7 @@ SetLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR", SPELL_SCHOOL_NECROMANCY);
|
||||
}
|
||||
//nDamage += ApplySpellBetrayalStrikeDamage(oTarget, OBJECT_SELF, FALSE);
|
||||
//Set the damage effect
|
||||
eDam = PRCEffectDamage(oTarget, nDamage, DAMAGE_TYPE_MAGICAL);
|
||||
eDam = PRCEffectDamage(oTarget, nDamage, DAMAGE_TYPE_DESSICATION);
|
||||
// Apply effects to the currently selected target.
|
||||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget);
|
||||
PRCBonusDamage(oTarget);
|
||||
|
||||
@@ -80,7 +80,7 @@ SetLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR", SPELL_SCHOOL_EVOCATION);
|
||||
|
||||
//Apply the MIRV and damage effect
|
||||
nDam += SpellDamagePerDice(OBJECT_SELF, 1);
|
||||
effect eDam = PRCEffectDamage(oTarget, nDam, DAMAGE_TYPE_MAGICAL);
|
||||
effect eDam = PRCEffectDamage(oTarget, nDam, DAMAGE_TYPE_FORCE);
|
||||
DelayCommand(fTime, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
|
||||
DelayCommand(fTime, SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oTarget,0.0f,FALSE));
|
||||
DelayCommand(fDelay2, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eMissile, oTarget));
|
||||
|
||||
@@ -66,7 +66,7 @@ int DoSpell(object oCaster, object oTarget, int nCasterLevel, int nEvent)
|
||||
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eKnock, oTarget, 3.0);
|
||||
}
|
||||
|
||||
effect eDam = PRCEffectDamage(oTarget, nDam, DAMAGE_TYPE_MAGICAL);
|
||||
effect eDam = PRCEffectDamage(oTarget, nDam, DAMAGE_TYPE_FORCE);
|
||||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget);
|
||||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_DESTRUCTION), oTarget);
|
||||
}
|
||||
|
||||
@@ -50,7 +50,19 @@ void main()
|
||||
|
||||
|
||||
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpact, PRCGetSpellTargetLocation());
|
||||
oTarget = MyFirstObjectInShape(SHAPE_SPHERE, 9.14f, lLocal, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE );
|
||||
|
||||
int nTargetsAffected = 0;
|
||||
oTarget = MyFirstObjectInShape(SHAPE_SPHERE, 9.14f, lLocal, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
|
||||
|
||||
while (GetIsObjectValid(oTarget) && nTargetsAffected < nCasterLevel)
|
||||
{
|
||||
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_REMOVE_CURSE));
|
||||
DispelLoop(oTarget, nCasterLevel);
|
||||
nTargetsAffected++;
|
||||
oTarget = MyNextObjectInShape(SHAPE_SPHERE, 9.14f, lLocal, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
|
||||
}
|
||||
|
||||
/* oTarget = MyFirstObjectInShape(SHAPE_SPHERE, 9.14f, lLocal, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE );
|
||||
|
||||
//Set up for loop
|
||||
int i = nCasterLevel;
|
||||
@@ -61,7 +73,7 @@ void main()
|
||||
DispelLoop(oTarget, nCasterLevel);
|
||||
i--;
|
||||
oTarget = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE,lLocal, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_AREA_OF_EFFECT | OBJECT_TYPE_PLACEABLE);
|
||||
}
|
||||
} */
|
||||
PRCSetSchool();
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,9 @@ Halt - The target stands in place and takes no action for one round.
|
||||
|
||||
Author: Stratovarius
|
||||
Created: 29/4/06
|
||||
|
||||
Fixed by: Jaysyn
|
||||
Date: 2026-05-29 00:57:05
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:://////////////////////////////////////////////
|
||||
@@ -61,12 +64,15 @@ void main()
|
||||
|
||||
if (!PRCDoResistSpell(OBJECT_SELF, oTarget, nCaster+SPGetPenetr()) && PRCGetIsAliveCreature(oTarget))
|
||||
{
|
||||
if(!PRCMySavingThrow(SAVING_THROW_WILL, oTarget, nDC, SAVING_THROW_TYPE_MIND_SPELLS))
|
||||
{
|
||||
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, RoundsToSeconds(nDuration), TRUE,-1,nCaster);
|
||||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||
DoCommandSpell(oCaster, oTarget, nSpellId, nDuration, nCaster);
|
||||
}
|
||||
if(!GetIsImmune(oTarget, IMMUNITY_TYPE_MIND_SPELLS))
|
||||
{
|
||||
if(!PRCMySavingThrow(SAVING_THROW_WILL, oTarget, nDC, SAVING_THROW_TYPE_MIND_SPELLS))
|
||||
{
|
||||
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, RoundsToSeconds(nDuration), TRUE,-1,nCaster);
|
||||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||
DoCommandSpell(oCaster, oTarget, nSpellId, nDuration, nCaster);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PRCSetSchool();
|
||||
|
||||
@@ -133,13 +133,13 @@ void DarkLoop(object oTarget, object oPC, int nMetaMagic)
|
||||
if(GetAlignmentGoodEvil(oTarget) == ALIGNMENT_GOOD)
|
||||
{
|
||||
int nDam = PRCMaximizeOrEmpower(6, 2, nMetaMagic) + SpellDamagePerDice(oPC, 2);
|
||||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, PRCEffectDamage(oTarget, nDam, DAMAGE_TYPE_DIVINE), oTarget);
|
||||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, PRCEffectDamage(oTarget, nDam, DAMAGE_TYPE_UNHOLY), oTarget);
|
||||
}
|
||||
|
||||
else if(GetAlignmentGoodEvil(oTarget) == ALIGNMENT_NEUTRAL)
|
||||
{
|
||||
int nDam = PRCMaximizeOrEmpower(6, 1, nMetaMagic) + SpellDamagePerDice(oPC, 1);
|
||||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, PRCEffectDamage(oTarget, nDam, DAMAGE_TYPE_DIVINE), oTarget);
|
||||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, PRCEffectDamage(oTarget, nDam, DAMAGE_TYPE_UNHOLY), oTarget);
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
@@ -11,7 +11,7 @@ void main()
|
||||
int nDice = nCasterLevel > 10 ? 10 : nCasterLevel;
|
||||
|
||||
DoBolt (nCasterLevel,4, 0, nDice, VFX_BEAM_MIND, VFX_IMP_MAGBLUE,
|
||||
DAMAGE_TYPE_MAGICAL, SAVING_THROW_TYPE_SPELL,
|
||||
DAMAGE_TYPE_FORCE, SAVING_THROW_TYPE_SPELL,
|
||||
SPELL_SCHOOL_EVOCATION, TRUE, GetSpellId());
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ void SendMissileBomb(object oCaster, object oTarget, float fDelay=0.0, float fTi
|
||||
if (nMetaMagic == METAMAGIC_EMPOWER)
|
||||
nDam += nDam/2;
|
||||
|
||||
DelayCommand(fTime, SPApplyEffectToObject(DURATION_TYPE_INSTANT, PRCEffectDamage(oLoop, nDam, DAMAGE_TYPE_MAGICAL), oLoop));
|
||||
DelayCommand(fTime, SPApplyEffectToObject(DURATION_TYPE_INSTANT, PRCEffectDamage(oLoop, nDam, DAMAGE_TYPE_FORCE), oLoop));
|
||||
DelayCommand(fTime, SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_IMP_MAGBLUE, FALSE, 4.0f), oLoop));
|
||||
}
|
||||
else if (!PRCDoResistSpell(oCaster, oLoop, nPenetr, fDelay))
|
||||
|
||||
@@ -29,7 +29,7 @@ void main()
|
||||
PRCSignalSpellEvent(oTarget, TRUE, nSpellId);
|
||||
|
||||
//Roll damage for each target
|
||||
int nDamage = PRCGetMetaMagicDamage(DAMAGE_TYPE_MAGICAL, nDice, 6);
|
||||
int nDamage = PRCGetMetaMagicDamage(DAMAGE_TYPE_FORCE, nDice, 6);
|
||||
nDamage += SpellDamagePerDice(oCaster, nDice);
|
||||
// Succeeded on the save
|
||||
if (PRCMySavingThrow(SAVING_THROW_FORT, oTarget, PRCGetSaveDC(oTarget, oCaster)))
|
||||
|
||||
@@ -94,7 +94,7 @@ SetLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR", SPELL_SCHOOL_EVOCATION);
|
||||
fTime += fDelay2;
|
||||
|
||||
//Set damage effect
|
||||
effect eDam = PRCEffectDamage(oTarget, nDam, DAMAGE_TYPE_MAGICAL);
|
||||
effect eDam = PRCEffectDamage(oTarget, nDam, DAMAGE_TYPE_FORCE);
|
||||
//Apply the MIRV and damage effect
|
||||
DelayCommand(fTime, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
|
||||
|
||||
|
||||
@@ -85,8 +85,7 @@ void main()
|
||||
int nVile = nDam/2;
|
||||
int nNorm = (nDam - nVile);
|
||||
|
||||
//Vile damage is currently being applied as Positive damage
|
||||
effect eVileDam = PRCEffectDamage(oTarget, nVile, DAMAGE_TYPE_POSITIVE);
|
||||
effect eVileDam = PRCEffectDamage(oTarget, nVile, DAMAGE_TYPE_VILE);
|
||||
effect eNormDam = PRCEffectDamage(oTarget, nNorm, DAMAGE_TYPE_MAGICAL);
|
||||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVileDam, oTarget);
|
||||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eNormDam, oTarget);
|
||||
|
||||
@@ -96,8 +96,8 @@ void main()
|
||||
nDam += SpellDamagePerDice(oPC, nLevel);
|
||||
int nVile = nDam/2;
|
||||
int nNorm = (nDam - nVile);
|
||||
//Vile damage is currently being applied as Positive damage
|
||||
effect eVileDam = PRCEffectDamage(oTarget, nVile, DAMAGE_TYPE_POSITIVE);
|
||||
|
||||
effect eVileDam = PRCEffectDamage(oTarget, nVile, DAMAGE_TYPE_VILE);
|
||||
effect eNormDam = PRCEffectDamage(oTarget, nNorm, DAMAGE_TYPE_MAGICAL);
|
||||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVileDam, oTarget);
|
||||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eNormDam, oTarget);
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "prc_inc_switch"
|
||||
#include "inc_utility"
|
||||
#include "prc_add_spell_dc"
|
||||
#include "prc_misc_const"
|
||||
|
||||
|
||||
void main()
|
||||
@@ -110,8 +111,8 @@ void main()
|
||||
nDam += SpellDamagePerDice(oPC, nLevel);
|
||||
int nVile = nDam/2;
|
||||
int nNorm = (nDam - nVile);
|
||||
//Vile damage is currently being applied as Positive damage
|
||||
effect eVileDam = PRCEffectDamage(oTarget, nVile, DAMAGE_TYPE_POSITIVE);
|
||||
|
||||
effect eVileDam = PRCEffectDamage(oTarget, nVile, DAMAGE_TYPE_VILE);
|
||||
effect eNormDam = PRCEffectDamage(oTarget, nNorm, DAMAGE_TYPE_MAGICAL);
|
||||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVileDam, oTarget);
|
||||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eNormDam, oTarget);
|
||||
|
||||
@@ -51,7 +51,7 @@ void main()
|
||||
if(nTouch)
|
||||
{
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_PULSE_BOMB), oTarget);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, PRCEffectDamage(oTarget, nDam, DAMAGE_TYPE_MAGICAL), oTarget);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, PRCEffectDamage(oTarget, nDam, DAMAGE_TYPE_FORCE), oTarget);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Shelgarn's Persistent Blade
|
||||
//:: X2_S0_PersBlde
|
||||
//:: x2_s0_persblde
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
@@ -13,6 +13,7 @@
|
||||
//:: Last Updated By: Georg Zoeller, Aug 2003
|
||||
//:: altered by mr_bumpkin Dec 4, 2003 for prc stuff
|
||||
#include "prc_inc_spells"
|
||||
#include "inc_spirit_weapn"
|
||||
|
||||
//Creates the weapon that the creature will be using.
|
||||
void spellsCreateItemForSummoned(object oCaster, float fDuration, int nClass)
|
||||
@@ -29,7 +30,8 @@ void spellsCreateItemForSummoned(object oCaster, float fDuration, int nClass)
|
||||
nStat = 1;
|
||||
|
||||
object oWeapon;
|
||||
string sWeapon = "NW_WSWDG001";
|
||||
//string sWeapon = "NW_WSWDG001";
|
||||
string sWeapon = "PRC_PERBLADE01";
|
||||
object oSummon = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oCaster);
|
||||
int i = 1;
|
||||
while(GetIsObjectValid(oSummon))
|
||||
@@ -54,7 +56,118 @@ void spellsCreateItemForSummoned(object oCaster, float fDuration, int nClass)
|
||||
|
||||
void main()
|
||||
{
|
||||
if(!X2PreSpellCastCode()) return;
|
||||
//:: Check the Spellhook
|
||||
if (!X2PreSpellCastCode()) return;
|
||||
|
||||
//:: Set the Spell School
|
||||
PRCSetSchool(GetSpellSchool(PRCGetSpellId()));
|
||||
|
||||
int nRunEvent = GetRunningEvent();
|
||||
|
||||
if (nRunEvent == EVENT_NPC_ONSPELLCASTAT)
|
||||
{
|
||||
// Get the caster of the spell
|
||||
object oCaster = GetLastSpellCaster();
|
||||
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||
|
||||
if(DEBUG) DoDebug("x2_s0_persblde: EVENT_NPC_ONSPELLCASTAT triggered.");
|
||||
|
||||
// Get the spell ID
|
||||
int nSpellId = GetLastSpell();
|
||||
if(DEBUG) DoDebug("x2_s0_persblde: Dispel spell ID: " + IntToString(nSpellId));
|
||||
|
||||
// Check if the spell ID is a dispel spell
|
||||
if (nSpellId == SPELL_DISPEL_MAGIC || nSpellId == SPELL_LESSER_DISPEL || nSpellId == SPELL_GREATER_DISPELLING || nSpellId == SPELL_MORDENKAINENS_DISJUNCTION
|
||||
|| nSpellId == SPELL_SLASHING_DISPEL || nSpellId == SPELL_DISPELLING_TOUCH || nSpellId == SPELL_PIXIE_DISPEL || nSpellId == SPELL_GREAT_WALL_OF_DISPEL)
|
||||
{
|
||||
// Get the target of the spell
|
||||
object oTarget = OBJECT_SELF;
|
||||
if(DEBUG) DoDebug("x2_s0_persblde: Spell targeted at: " + GetName(oTarget));
|
||||
|
||||
// Check if the target is OBJECT_SELF
|
||||
if (oTarget == OBJECT_SELF)
|
||||
{
|
||||
// Retrieve the original caster of the Persistent Blade spell from oSummon
|
||||
object oSummon = OBJECT_SELF;
|
||||
object oOriginalCaster = GetLocalObject(oSummon, "MY_CASTER");
|
||||
|
||||
// Ensure oOriginalCaster is valid
|
||||
if (GetIsObjectValid(oOriginalCaster))
|
||||
{
|
||||
if(DEBUG) DoDebug("x2_s0_persblde: Original caster found. Caster level: " + IntToString(GetCasterLevel(oOriginalCaster)));
|
||||
|
||||
// Determine the DC for the dispel check
|
||||
int nDispelDC = 11 + GetCasterLevel(oOriginalCaster);
|
||||
if(DEBUG) DoDebug("x2_s0_persblde: Dispel DC: " + IntToString(nDispelDC));
|
||||
|
||||
// Determine the maximum cap for the dispel check
|
||||
int nDispelCap = 0;
|
||||
if (nSpellId == SPELL_LESSER_DISPEL)
|
||||
nDispelCap = 5;
|
||||
else if (nSpellId == SPELL_DISPEL_MAGIC || nSpellId == SPELL_SLASHING_DISPEL || nSpellId == SPELL_DISPELLING_TOUCH || nSpellId == SPELL_PIXIE_DISPEL || nSpellId == INVOKE_VORACIOUS_DISPELLING)
|
||||
nDispelCap = 10;
|
||||
else if (nSpellId == SPELL_GREATER_DISPELLING || nSpellId == SPELL_GREAT_WALL_OF_DISPEL)
|
||||
nDispelCap = 15;
|
||||
else if (nSpellId == SPELL_MORDENKAINENS_DISJUNCTION)
|
||||
nDispelCap = 0; // No cap for Disjunction
|
||||
|
||||
// Roll for the dispel check
|
||||
int nDispelRoll = d20();
|
||||
int nCappedCasterLevel = nCasterLevel;
|
||||
|
||||
if (nDispelCap > 0 && nCasterLevel > nDispelCap)
|
||||
nCappedCasterLevel = nDispelCap;
|
||||
|
||||
nDispelRoll += nCappedCasterLevel;
|
||||
|
||||
if(DEBUG) DoDebug("x2_s0_persblde: Dispel roll: " + IntToString(nDispelRoll) + " (Caster Level: " + IntToString(nCappedCasterLevel) + ", Cap: " + IntToString(nDispelCap) + ")");
|
||||
|
||||
// Compare the dispel result to the DC
|
||||
if (nDispelRoll >= nDispelDC)
|
||||
{
|
||||
if(DEBUG) DoDebug("x2_s0_persblde: Dispel check succeeded.");
|
||||
|
||||
// Dispel succeeded, destroy oSummon and the item in its right hand
|
||||
object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oSummon);
|
||||
|
||||
if(DEBUG) DoDebug("x2_s0_persblde: Dispel Magic succeeded. Destroying Persistent Blade and its right hand item.");
|
||||
|
||||
// Set flags and destroy objects with delays
|
||||
SetPlotFlag(oWeapon, FALSE);
|
||||
SetPlotFlag(oSummon, FALSE);
|
||||
SetImmortal(oSummon, FALSE);
|
||||
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_DISPEL), oSummon);
|
||||
|
||||
// Destroy the weapon and summon with delays
|
||||
if (GetIsObjectValid(oWeapon))
|
||||
{
|
||||
DelayCommand(0.5f, DestroyObject(oWeapon));
|
||||
if(DEBUG) DoDebug("x2_s0_persblde: Persistent Blade destruction scheduled.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(DEBUG) DoDebug("x2_s0_persblde: No weapon found in right hand.");
|
||||
}
|
||||
|
||||
DelayCommand(1.0f, DestroyObject(oSummon));
|
||||
if(DEBUG) DoDebug("x2_s0_persblde: Persistent Blade Summon destruction scheduled.");
|
||||
}
|
||||
else
|
||||
{
|
||||
RegisterSummonEvents(oSummon);
|
||||
if(DEBUG) DoDebug("x2_s0_persblde: Dispel check failed.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(DEBUG) DoDebug("x2_s0_persblde: Original caster not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
PRCSetSchool(SPELL_SCHOOL_CONJURATION);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user