PRC8/nwn/nwnprc/trunk/include/spinc_burst.nss
Jaysyn904 6ec137a24e Updated AMS marker feats
Updated AMS marker feats.  Removed arcane & divine marker feats.  Updated Dread Necromancer for epic progression. Updated weapon baseitem models.  Updated new weapons for crafting & npc equip.
 Updated prefix.  Updated release archive.
2024-02-11 14:01:05 -05:00

160 lines
7.9 KiB
Plaintext

////////////////////////////////////////////////////////////////////////////////////
//
// DoBurst() - Do a damaging burst at the spell's target location.
// nDieSize - size of die to roll.
// nBonusDam - bonus damage per die.
// nDice - number of dice to roll
// nBurstEffect - VFX_xxx or AOE_xxx of burst vfx.
// nVictimEffect - VFX_xxx of target impact.
// nDamageType - DAMAGE_TYPE_xxx of the type of damage dealt
// nSaveType - SAVING_THROW_xxx of type of save to use
// bCasterImmune - Indicates whether the caster is immune to the spell
// nSchool - SPELL_SCHOOL_xxx of the spell's school
// nSpellID - ID # of the spell, if -1 PRCGetSpellId() is used
// fAOEDuration - if > 0, then nBurstEffect should be an AOE_xxx vfx, it
// will be played at the target location for this duration. If this is
// 0 then nBurstEffect should be a VFX_xxx vfx.
//
////////////////////////////////////////////////////////////////////////////////////
#include "prc_inc_spells"
#include "prc_add_spell_dc"
void DoBurst (int nCasterLvl, int nDieSize, int nBonusDam, int nDice, int nBurstEffect,
int nVictimEffect, float fRadius, int nDamageType, int nBonusDamageType, int nSaveType,
int bCasterImmune = FALSE,
int nSchool = SPELL_SCHOOL_EVOCATION, int nSpellID = -1,
float fAOEDuration = 0.0f)
{
PRCSetSchool(nSchool);
// Get the spell ID if it was not given.
if (-1 == nSpellID) nSpellID = PRCGetSpellId();
// Get the spell target location as opposed to the spell target.
location lTarget = PRCGetSpellTargetLocation();
int nPenetr = nCasterLvl + SPGetPenetr();
// Get the effective caster level and hand it to the SR engine.
// Adjust the damage type of necessary, if the damage & bonus damage types are the
// same we need to copy the adjusted damage type to the bonus damage type.
int nSameDamageType = nDamageType == nBonusDamageType;
nDamageType = PRCGetElementalDamageType(nDamageType, OBJECT_SELF);
if (nSameDamageType) nBonusDamageType = nDamageType;
// Apply the specified vfx to the location. If we were given an aoe vfx then
// fAOEDuration will be > 0.
if (fAOEDuration > 0.0)
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY,
EffectAreaOfEffect(nBurstEffect, "****", "****", "****"), lTarget, fAOEDuration);
else
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(nBurstEffect), lTarget);
effect eVis = EffectVisualEffect(nVictimEffect);
effect eDamage, eBonusDamage;
float fDelay;
// Declare the spell shape, size and the location. Capture the first target object in the shape.
// Cycle through the targets within the spell shape until an invalid object is captured.
object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, fRadius, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
while (GetIsObjectValid(oTarget))
{
// Filter out the caster if he is supposed to be immune to the burst.
if (!(bCasterImmune && OBJECT_SELF == oTarget))
{
if(spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, OBJECT_SELF))
{
//Fire cast spell at event for the specified target
PRCSignalSpellEvent(oTarget, TRUE, nSpellID);
fDelay = PRCGetSpellEffectDelay(lTarget, oTarget);
if (!PRCDoResistSpell(OBJECT_SELF, oTarget,nPenetr, fDelay))
{
int nSaveDC = PRCGetSaveDC(oTarget, OBJECT_SELF);
int nDam = 0;
int nDam2 = 0;
if (nSameDamageType)
{
// Damage damage type is the simple case, just get the total damage
// of the spell's type, apply metamagic and roll the save.
// Roll damage for each target
nDam = PRCGetMetaMagicDamage(nDamageType, nDice, nDieSize, nBonusDam);
// Acid Sheath adds +1 damage per die to acid descriptor spells
if (GetHasDescriptor(nSpellID, DESCRIPTOR_ACID) && GetHasSpellEffect(SPELL_MESTILS_ACID_SHEATH, OBJECT_SELF))
nDam += nDice;
nDam += SpellDamagePerDice(OBJECT_SELF, nDice);
// Adjust damage for reflex save / evasion / imp evasion
nDam = PRCGetReflexAdjustedDamage(nDam, oTarget, nSaveDC, nSaveType);
}
else
{
// Damage of different types is a bit more complicated, we need to
// calculate the bonus damage ourselves, figure out if the save was
// 1/2 or no damage, and apply appropriately to the secondary damage
// type.
// Calculate base and bonus damage.
nDam = PRCGetMetaMagicDamage(nDamageType, nDice, nDieSize, 0);
// Acid Sheath adds +1 damage per die to acid descriptor spells
if (GetHasDescriptor(nSpellID, DESCRIPTOR_ACID) && GetHasSpellEffect(SPELL_MESTILS_ACID_SHEATH, OBJECT_SELF))
nDam += nDice;
nDam += SpellDamagePerDice(OBJECT_SELF, nDice);
nDam2 = nDice * nBonusDam;
// Adjust damage for reflex save / evasion / imp evasion. We need to
// deal with damage being constant, damage being 0, and damage being
// some percentage of the total (should be 1/2).
int nAdjustedDam = PRCGetReflexAdjustedDamage(nDam, oTarget, nSaveDC, nSaveType);
if (0 == nAdjustedDam)
{
// Evasion zero'ed out the damage, clear both damage values.
nDam = 0;
nDam2 = 0;
}
else if (nAdjustedDam < nDam)
{
// Assume 1/2 damage, and half the bonus damage.
nDam = nAdjustedDam;
nDam2 /= 2;
}
}
//Set the damage effect
if (nDam > 0)
{
eDamage = PRCEffectDamage(oTarget, nDam, nDamageType);
// Apply effects to the currently selected target.
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget));
PRCBonusDamage(oTarget);
// This visual effect is applied to the target object not the location as above.
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
}
// Apply bonus damage if it is a different type.
if (nDam2 > 0)
{
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT,
PRCEffectDamage(oTarget, nDam2, nBonusDamageType), oTarget));
}
}
}
}
oTarget = MyNextObjectInShape(SHAPE_SPHERE, fRadius, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
}
// Let the SR engine know that we are done and clear out school local var.
PRCSetSchool();
}
// Test main
//void main(){}