Updated Release Archive. Fixed Mage-killer prereqs. Removed old LETO & ConvoCC related files. Added organized spell scroll store. Fixed Gloura spellbook. Various TLK fixes. Reorganized Repo. Removed invalid user folders. Added DocGen back in.
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(){}
|