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.
160 lines
7.9 KiB
Plaintext
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(){}
|