2025/07/22 Update
Updated ruleset.2da. Drug Resistance should be able to target the caster. Changed crafting constants for better compatibility with nwn_script_comp. Made Mirror Image work better.
This commit is contained in:
94
nwn/nwnprc/trunk/scripts/mirror_image_sa.nss
Normal file
94
nwn/nwnprc/trunk/scripts/mirror_image_sa.nss
Normal file
@@ -0,0 +1,94 @@
|
||||
#include "inc_debug"
|
||||
#include "prc_inc_spells"
|
||||
|
||||
void main()
|
||||
{
|
||||
object oSummoned = OBJECT_SELF;
|
||||
|
||||
// Get the caster of the potential dispel
|
||||
object oCaster = GetLastSpellCaster();
|
||||
int nCasterLevel = GetCasterLevel(oCaster);
|
||||
|
||||
if(DEBUG) DoDebug("mirror_image_sa: EVENT_NPC_ONSPELLCASTAT triggered.");
|
||||
|
||||
// Get the spell ID
|
||||
int nSpellId = GetLastSpell();
|
||||
if(DEBUG) DoDebug("mirror_image_sa: 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("mirror_image_sa: Spell targeted at: " + GetName(oTarget));
|
||||
|
||||
// Check if the target is OBJECT_SELF
|
||||
if (oTarget == OBJECT_SELF)
|
||||
{
|
||||
// Retrieve the original caster of the Spiritual Weapon spell from oSummon
|
||||
object oSummon = OBJECT_SELF;
|
||||
object oOriginalCaster = GetLocalObject(oSummon, "oMaster");
|
||||
|
||||
// Ensure oOriginalCaster is valid
|
||||
if (GetIsObjectValid(oOriginalCaster))
|
||||
{
|
||||
if(DEBUG) DoDebug("mirror_image_sa: Original caster found. Caster level: " + IntToString(GetCasterLevel(oOriginalCaster)));
|
||||
|
||||
// Determine the DC for the dispel check
|
||||
int nDispelDC = 11 + GetCasterLevel(oOriginalCaster);
|
||||
if(DEBUG) DoDebug("mirror_image_sa: 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("mirror_image_sa: Dispel roll: " + IntToString(nDispelRoll) + " (Caster Level: " + IntToString(nCappedCasterLevel) + ", Cap: " + IntToString(nDispelCap) + ")");
|
||||
|
||||
// Compare the dispel result to the DC
|
||||
if (nDispelRoll >= nDispelDC)
|
||||
{
|
||||
if(DEBUG) DoDebug("mirror_image_sa: Dispel check succeeded.");
|
||||
|
||||
// Dispel succeeded, destroy oSummon
|
||||
if(DEBUG) DoDebug("mirror_image_sa: Dispel Magic succeeded. Destroying Mirror Image.");
|
||||
|
||||
// Set flags and destroy objects with delays
|
||||
SetPlotFlag(oSummon, FALSE);
|
||||
SetImmortal(oSummon, FALSE);
|
||||
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_DISPEL), oSummon);
|
||||
|
||||
DelayCommand(1.0f, DestroyObject(oSummon));
|
||||
|
||||
if(DEBUG) DoDebug("mirror_image_sa: Mirror Image destruction scheduled.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(DEBUG) DoDebug("mirror_image_sa: Dispel check failed.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(DEBUG) DoDebug("mirror_image_sa: Original caster not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
@@ -21,6 +21,22 @@
|
||||
#include "shd_inc_myst"
|
||||
#include "prc_inc_template"
|
||||
|
||||
void RemoveExtraImages(object oPC)
|
||||
{
|
||||
string sImage1 = "PC_IMAGE"+ObjectToString(oPC)+"mirror";
|
||||
string sImage2 = "PC_IMAGE"+ObjectToString(oPC)+"flurry";
|
||||
|
||||
object oCreature = GetFirstObjectInArea(GetArea(oPC));
|
||||
while (GetIsObjectValid(oCreature))
|
||||
{
|
||||
if(GetTag(oCreature) == sImage1 || GetTag(oCreature) == sImage2)
|
||||
{
|
||||
DestroyObject(oCreature, 0.0);
|
||||
}
|
||||
oCreature = GetNextObjectInArea(GetArea(oPC));
|
||||
}
|
||||
}
|
||||
|
||||
void PrcFeats(object oPC)
|
||||
{
|
||||
if(DEBUG) DoDebug("prc_rest: Evaluating PC feats for " + DebugObject2Str(oPC));
|
||||
@@ -349,6 +365,8 @@ void RestStarted(object oPC)
|
||||
}
|
||||
*/
|
||||
|
||||
RemoveExtraImages(oPC);
|
||||
|
||||
if (GetIsPC(oPC)) SetLocalInt(oPC, "PnP_Rest_InitialHP", GetCurrentHitPoints(oPC));
|
||||
SetLocalInt(oPC, "PnP_Rest_InitialMax", GetMaxHitPoints(oPC));
|
||||
if(DEBUG) DoDebug("prc_rest: HPs for " + DebugObject2Str(oPC)+"n/n/"+" nCurrent: "+IntToString(GetCurrentHitPoints(oPC))+" nMax: "+IntToString(GetMaxHitPoints(oPC)));
|
||||
|
Reference in New Issue
Block a user