Files
PRC8/nwn/nwnprc/trunk/spells/sp_enred.nss
Jaysyn904 3ebdc0ba62 2025/12/14 Update
Spellfire Channeler was missing Improved Healing at 2nd level.
Added "Crafted Vial" CWI crafting baseitem type.
Added Craft Scepter crafting feat.
Added Magical Artisan: Craft Scepter.
Adjusted Hemp Rope label in iprp_material.2da & iprp_matcost.2da
Added Aroma of Death CWI crafting item and spell to support it.
Added Beetle Elixir CWI crafting item and spells to support it.
Added Harness of Armor CWI crafting item.
Swarm Tactics was missing a heartbeat script.
Added crafted descriptions for all CWI items in craft_wondrous.2da
Updated fileends for updated crafting options.
Scepters count as clubs for feats.
Gated errant DEBUG in prc_inc_nat_hb.
Added new switches for scepter crafitng.
Updated PRC Options magic supplies store for new crafting bastitems.
2025-12-14 16:50:21 -05:00

252 lines
12 KiB
Plaintext

#include "prc_sp_func"
#include "prc_add_spell_dc"
#include "prc_effect_inc"
#include "prc_inc_size"
void DispelMonitor(object oCaster, object oTarget, int nSpellID, int nBeatsRemaining)
{
if((--nBeatsRemaining == 0) ||
PRCGetDelayedSpellEffectsExpired(nSpellID, oTarget, oCaster)
)
{
if(DEBUG) DoDebug("sp_enred: Spell expired, clearing");
// Clear the marker variables FIRST
DeleteLocalInt(oTarget, "PRC_Power_Expansion_SizeIncrease");
DeleteLocalInt(oTarget, "PRC_Power_Compression_SizeReduction");
// Remove any size effects with the new tags
effect eEffect = GetFirstEffect(oTarget);
while (GetIsEffectValid(eEffect))
{
string sTag = GetEffectTag(eEffect);
if (sTag == "PRC_SIZE_INCREASE" || sTag == "PRC_SIZE_DECREASE")
{
RemoveEffect(oTarget, eEffect);
}
eEffect = GetNextEffect(oTarget);
}
// Reset to ORIGINAL scale, not 1.0f
float fOriginalSize = GetLocalFloat(oTarget, "PRC_ORIGINAL_SIZE");
if(fOriginalSize == 0.0f) fOriginalSize = 1.0f; // fallback
SetObjectVisualTransform(oTarget, OBJECT_VISUAL_TRANSFORM_SCALE, fOriginalSize);
// DON'T delete PRC_ORIGINAL_SIZE here - keep it for future casts
// Remove remaining spell effects
PRCRemoveEffectsFromSpell(oTarget, nSpellID);
// Size has changed, evaluate PrC feats again
EvalPRCFeats(oTarget);
}
else
DelayCommand(1.0f, DispelMonitor(oCaster, oTarget, nSpellID, nBeatsRemaining));
}
void main()
{
//Declare main variables.
int nEvent = GetRunningEvent();
object oCaster;
switch(nEvent)
{
case EVENT_ONPLAYERREST_FINISHED: oCaster = GetLastBeingRested(); break;
default:
oCaster = OBJECT_SELF;
}
if(nEvent == FALSE)
{
int nCasterLevel = PRCGetCasterLevel(oCaster);
int nSpellID = PRCGetSpellId();
PRCSetSchool(GetSpellSchool(nSpellID));
if (!X2PreSpellCastCode()) return;
object oTarget = PRCGetSpellTargetObject();
int nMetaMagic = PRCGetMetaMagicFeat();
int nSaveDC = PRCGetSaveDC(oTarget, oCaster);
int nPenetr = nCasterLevel + SPGetPenetr();
float fDuration = 60.0 * nCasterLevel; //modify if necessary
if(nMetaMagic & METAMAGIC_EXTEND) fDuration *= 2;
int bMass = ((nSpellID == SPELL_ENLARGE_PERSON_MASS) ||
(nSpellID == SPELL_REDUCE_PERSON_MASS));
int bEnlarge = ((nSpellID == SPELL_ENLARGE_PERSON) ||
(nSpellID == SPELL_ENLARGE_PERSON_MASS));
//:: Attempt to fix older characters.
RemoveEventScript(oTarget, EVENT_ONPLAYERREST_FINISHED, "sp_enred", TRUE, FALSE);
RemoveEventScript(oTarget, EVENT_ONPLAYERREST_STARTED, "sp_enred", TRUE, FALSE);
AddEventScript(oTarget, EVENT_ONPLAYERREST_FINISHED, "sp_enred", TRUE, FALSE);
if(nMetaMagic & METAMAGIC_EXTEND) fDuration *= 2;
location lTarget;
if(bMass)
{
lTarget = PRCGetSpellTargetLocation();
oTarget = MyFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, lTarget, TRUE, OBJECT_TYPE_CREATURE);
}
while(GetIsObjectValid(oTarget))
{
if (PRCAmIAHumanoid(oTarget))
{
if(spellsIsTarget(oTarget, SPELL_TARGET_ALLALLIES, oCaster)) //:: Allied Branch
{
if(bEnlarge)
{
if(GetLocalInt(oTarget, "PRC_Power_Compression_SizeReduction"))
{
// Remove opposing size effect
effect eEffect = GetFirstEffect(oTarget);
while (GetIsEffectValid(eEffect))
{
string sTag = GetEffectTag(eEffect);
if (sTag == "PRC_SIZE_DECREASE")
{
RemoveEffect(oTarget, eEffect);
effect eReset = EffectSizeChange(oTarget, OBJECT_TYPE_CREATURE, TRUE, 0);
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eReset, oTarget);
DeleteLocalInt(oTarget, "PRC_Power_Compression_SizeReduction");
DispelMonitor(oCaster, oTarget, nSpellID, 0); // 0 beats for immediate cleanup
}
eEffect = GetNextEffect(oTarget);
}
}
else if(GetLocalInt(oTarget, "PRC_Power_Expansion_SizeIncrease"))
{
FloatingTextStringOnCreature("This creature's size cannot be increased further.", oTarget);
}
else
{
SetLocalInt(oTarget, "PRC_Power_Expansion_SizeIncrease", 1);
effect eSize = EffectSizeChange(oTarget, OBJECT_TYPE_CREATURE, TRUE, 1);
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eSize, oTarget, fDuration, TRUE, nSpellID, nCasterLevel);
DelayCommand(1.0f, DispelMonitor(oCaster, oTarget, nSpellID, FloatToInt(fDuration) / 6));
}
}
else // Reduce
{
if(GetLocalInt(oTarget, "PRC_Power_Expansion_SizeIncrease"))
{
// Remove opposing size effect
effect eEffect = GetFirstEffect(oTarget);
while (GetIsEffectValid(eEffect))
{
string sTag = GetEffectTag(eEffect);
if (sTag == "PRC_SIZE_INCREASE")
{
RemoveEffect(oTarget, eEffect);
effect eReset = EffectSizeChange(oTarget, OBJECT_TYPE_CREATURE, TRUE, 0);
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eReset, oTarget);
DeleteLocalInt(oTarget, "PRC_Power_Expansion_SizeIncrease");
DispelMonitor(oCaster, oTarget, nSpellID, 0);
}
eEffect = GetNextEffect(oTarget);
}
}
else if(GetLocalInt(oTarget, "PRC_Power_Compression_SizeReduction"))
{
FloatingTextStringOnCreature("This creature's size cannot be decreased further.", oTarget);
}
else
{
SetLocalInt(oTarget, "PRC_Power_Compression_SizeReduction", 1);
effect eSize = EffectSizeChange(oTarget, OBJECT_TYPE_CREATURE, FALSE, 1);
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eSize, oTarget, fDuration, TRUE, nSpellID, nCasterLevel);
DelayCommand(1.0f, DispelMonitor(oCaster, oTarget, nSpellID, FloatToInt(fDuration) / 6));
}
}
}
else if(!PRCMySavingThrow(SAVING_THROW_FORT, oTarget, nSaveDC))
{
// Same logic as above for hostile targets
if(bEnlarge)
{
if(GetLocalInt(oTarget, "PRC_Power_Compression_SizeReduction"))
{
// Remove opposing size effect (same as above)
effect eEffect = GetFirstEffect(oTarget);
while (GetIsEffectValid(eEffect))
{
string sTag = GetEffectTag(eEffect);
if (sTag == "PRC_SIZE_DECREASE")
{
RemoveEffect(oTarget, eEffect);
effect eReset = EffectSizeChange(oTarget, OBJECT_TYPE_CREATURE, TRUE, 0);
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eReset, oTarget);
DeleteLocalInt(oTarget, "PRC_Power_Compression_SizeReduction");
DispelMonitor(oCaster, oTarget, nSpellID, 0);
}
eEffect = GetNextEffect(oTarget);
}
}
else if(GetLocalInt(oTarget, "PRC_Power_Expansion_SizeIncrease"))
{
FloatingTextStringOnCreature("This creature's size cannot be increased further.", oTarget);
}
else
{
SetLocalInt(oTarget, "PRC_Power_Expansion_SizeIncrease", 1);
effect eSize = EffectSizeChange(oTarget, OBJECT_TYPE_CREATURE, TRUE, 1);
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eSize, oTarget, fDuration, TRUE, nSpellID, nCasterLevel);
DelayCommand(1.0f, DispelMonitor(oCaster, oTarget, nSpellID, FloatToInt(fDuration) / 6));
}
}
else // Reduce
{
if(GetLocalInt(oTarget, "PRC_Power_Expansion_SizeIncrease"))
{
// Remove opposing size effect (same as above)
effect eEffect = GetFirstEffect(oTarget);
while (GetIsEffectValid(eEffect))
{
string sTag = GetEffectTag(eEffect);
if (sTag == "PRC_SIZE_INCREASE")
{
RemoveEffect(oTarget, eEffect);
effect eReset = EffectSizeChange(oTarget, OBJECT_TYPE_CREATURE, TRUE, 0);
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eReset, oTarget);
DeleteLocalInt(oTarget, "PRC_Power_Expansion_SizeIncrease");
DispelMonitor(oCaster, oTarget, nSpellID, 0);
}
eEffect = GetNextEffect(oTarget);
}
}
else if(GetLocalInt(oTarget, "PRC_Power_Compression_SizeReduction"))
{
FloatingTextStringOnCreature("This creature's size cannot be reduced further.", oTarget);
}
else
{
SetLocalInt(oTarget, "PRC_Power_Compression_SizeReduction", 1);
effect eSize = EffectSizeChange(oTarget, OBJECT_TYPE_CREATURE, FALSE, 1);
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eSize, oTarget, fDuration, TRUE, nSpellID, nCasterLevel);
DelayCommand(1.0f, DispelMonitor(oCaster, oTarget, nSpellID, FloatToInt(fDuration) / 6));
}
}
}
}
if(!bMass) break;
oTarget = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, lTarget, TRUE, OBJECT_TYPE_CREATURE);
}
EvalPRCFeats(oTarget);
}
else if(nEvent == EVENT_ONPLAYERREST_FINISHED)
{
// Reset size on rest - this is where we fully clean up
float fOriginalSize = GetLocalFloat(oCaster, "PRC_ORIGINAL_SIZE");
if(fOriginalSize == 0.0f) fOriginalSize = 1.0f;
SetObjectVisualTransform(oCaster, OBJECT_VISUAL_TRANSFORM_SCALE, fOriginalSize);
// Clear ALL size state variables including original size
DeleteLocalInt(oCaster, "PRC_Power_Expansion_SizeIncrease");
DeleteLocalInt(oCaster, "PRC_Power_Compression_SizeReduction");
DeleteLocalFloat(oCaster, "PRC_ORIGINAL_SIZE");
}
PRCSetSchool();
}