161 lines
6.5 KiB
Plaintext
161 lines
6.5 KiB
Plaintext
|
/*:://////////////////////////////////////////////
|
|||
|
//:: Spell Name Meteor Swarm
|
|||
|
//:: Spell FileName PHS_S_MeteorSwrm
|
|||
|
//:://////////////////////////////////////////////
|
|||
|
//:: In Game Spell desctiption
|
|||
|
//:://////////////////////////////////////////////
|
|||
|
Evocation [Fire]
|
|||
|
Level: Sor/Wiz 9
|
|||
|
Components: V, S
|
|||
|
Casting Time: 1 standard action
|
|||
|
Range: Long (40M)
|
|||
|
Area: Four 13.33-M.-radius spreads; see text
|
|||
|
Duration: Instantaneous
|
|||
|
Saving Throw: None or Reflex half; see text
|
|||
|
Spell Resistance: Yes
|
|||
|
|
|||
|
Meteor swarm is a very powerful and spectacular spell that is similar to
|
|||
|
fireball in many aspects. When you cast it, four flaming spheres spring from
|
|||
|
your outstretched hand and streak in straight lines to the spots you select.
|
|||
|
The meteor spheres leave a fiery trail of sparks.
|
|||
|
|
|||
|
Once cast, the other flaming spheres will be targeted at 3 different targets
|
|||
|
other then the target selected (if one is valid), in a 10-M radius sphere.
|
|||
|
|
|||
|
If you aim a sphere at a specific creature, you may make a ranged touch
|
|||
|
attack to strike the target with the meteor. Any creature struck by one of
|
|||
|
these spheres takes 2d6 points of bludgeoning damage (no save) and receives
|
|||
|
no saving throw against the sphere<72>s fire damage (see below). If a targeted
|
|||
|
sphere misses its target, it simply explodes at the location of the target.
|
|||
|
|
|||
|
Once a sphere reaches its destination, it explodes in a 13.33-meter-radius
|
|||
|
spread, dealing 6d6 points of fire damage to each creature in the area. If
|
|||
|
a creature is within the area of more than one sphere, it must save
|
|||
|
separately against each. (Fire resistance applies to each sphere<72>s damage
|
|||
|
individually.)
|
|||
|
//:://////////////////////////////////////////////
|
|||
|
//:: Spell Effects Applied / Notes
|
|||
|
//:://////////////////////////////////////////////
|
|||
|
Ok:
|
|||
|
|
|||
|
- We target one, and it explodes as normal, if a target is selected,
|
|||
|
it won't be targeted by another.
|
|||
|
- Then, 3 other "missiles" may be fired, up to 3, as long as it isn't us,
|
|||
|
or the target just targeted.
|
|||
|
//:://////////////////////////////////////////////
|
|||
|
//:: Created By: Jasperre
|
|||
|
//::////////////////////////////////////////////*/
|
|||
|
|
|||
|
#include "PHS_INC_SPELLS"
|
|||
|
|
|||
|
// Constant used just in this spell
|
|||
|
const string PHS_METEOR_SWARM_ONLY_BLAST = "PHS_METEOR_SWARM_ONLY_BLAST";
|
|||
|
|
|||
|
void main()
|
|||
|
{
|
|||
|
// Spell hook check
|
|||
|
if(!PHS_SpellHookCheck(PHS_SPELL_METEOR_SWARM)) return;
|
|||
|
|
|||
|
// Declare major variables
|
|||
|
object oCaster = OBJECT_SELF;
|
|||
|
object oSpellTarget = GetSpellTargetObject();
|
|||
|
object oTarget;
|
|||
|
location lTarget = GetSpellTargetLocation();
|
|||
|
int nSpellSaveDC = PHS_GetSpellSaveDC(); // Special - see below
|
|||
|
int nDam;
|
|||
|
float fDelay;
|
|||
|
// Compared to those in loop. If any == oTargetHit, no save!
|
|||
|
object oTargetHit;
|
|||
|
|
|||
|
// The old (and proper) stored DC is used if nOnlyBlast is > 0
|
|||
|
// It is stored to it (onyl one variable needed then)
|
|||
|
int nOnlyBlast = GetLocalInt(oCaster, PHS_METEOR_SWARM_ONLY_BLAST);
|
|||
|
if(nOnlyBlast > 0)
|
|||
|
{
|
|||
|
nSpellSaveDC = nOnlyBlast;
|
|||
|
}
|
|||
|
|
|||
|
// Declare effects
|
|||
|
effect eImpact = EffectVisualEffect(PHS_VFX_FNF_METEOR_SWARM);
|
|||
|
|
|||
|
// Apply AOE visual
|
|||
|
PHS_ApplyLocationVFX(lTarget, eImpact);
|
|||
|
|
|||
|
// If oTarget is valid, we check if we hit them for extra damage
|
|||
|
if(GetIsObjectValid(oSpellTarget))
|
|||
|
{
|
|||
|
// Make a touch attack
|
|||
|
if(PHS_SpellTouchAttack(PHS_TOUCH_RANGED, oSpellTarget))
|
|||
|
{
|
|||
|
// Do some bludgeoning damage to this target
|
|||
|
nDam = PHS_MaximizeOrEmpower(6, 2, FALSE);
|
|||
|
// No delay to this damage as it should be the impact of the spell!
|
|||
|
PHS_ApplyDamageToObject(oSpellTarget, nDam, DAMAGE_TYPE_BLUDGEONING);
|
|||
|
// This target now gets no save against this blast!
|
|||
|
oTargetHit = oSpellTarget;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Always do damage for this script - the integer below specifices if we
|
|||
|
// do more targets with it. Target all objects that can be damaged in 40ft radius.
|
|||
|
oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 13.33, lTarget, TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
|
|||
|
while(GetIsObjectValid(oTarget))
|
|||
|
{
|
|||
|
// PvP Check
|
|||
|
if(!GetIsReactionTypeFriendly(oTarget, oCaster))
|
|||
|
{
|
|||
|
//Fire cast spell at event for the specified target
|
|||
|
PHS_SignalSpellCastAt(oTarget, PHS_SPELL_METEOR_SWARM);
|
|||
|
|
|||
|
//Get the distance between the explosion and the target to calculate delay
|
|||
|
fDelay = GetDistanceBetweenLocations(lTarget, GetLocation(oTarget))/20;
|
|||
|
|
|||
|
// Spell resistance And immunity checking.
|
|||
|
if(!PHS_SpellResistanceCheck(oCaster, oTarget, fDelay))
|
|||
|
{
|
|||
|
// Roll damage for each target - 6d6
|
|||
|
nDam = PHS_MaximizeOrEmpower(6, 6, FALSE);
|
|||
|
|
|||
|
// Only do reflex save if not hit
|
|||
|
if(oTarget != oTargetHit)
|
|||
|
{
|
|||
|
// Adjust the damage based on the Reflex Save, Evasion and Improved Evasion.
|
|||
|
nDam = PHS_GetAdjustedDamage(SAVING_THROW_REFLEX, nDam, oTarget, nSpellSaveDC, SAVING_THROW_TYPE_FIRE);
|
|||
|
}
|
|||
|
// Need to do damage to apply visuals
|
|||
|
if(nDam > 0)
|
|||
|
{
|
|||
|
// Apply effects to the currently selected target.
|
|||
|
DelayCommand(fDelay, PHS_ApplyDamageToObject(oTarget, nDam, DAMAGE_TYPE_FIRE));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
// Get next target
|
|||
|
oTarget = GetNextObjectInShape(SHAPE_SPHERE, 13.33, lTarget, TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
|
|||
|
}
|
|||
|
|
|||
|
// Check if we do more blasts
|
|||
|
if(!nOnlyBlast) // PHS_METEOR_SWARM_ONLY_BLAST
|
|||
|
{
|
|||
|
// Stop what we are doing
|
|||
|
ClearAllActions();
|
|||
|
// Set so that the next 3 will only do damage, thats it.
|
|||
|
SetLocalInt(OBJECT_SELF, PHS_METEOR_SWARM_ONLY_BLAST, nSpellSaveDC);
|
|||
|
DelayCommand(2.5, DeleteLocalInt(OBJECT_SELF, PHS_METEOR_SWARM_ONLY_BLAST));
|
|||
|
|
|||
|
// Get the targets
|
|||
|
int nCnt = 0;
|
|||
|
oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 10.0, lTarget, TRUE);
|
|||
|
// Max of 3 more, up to 10M from original location.
|
|||
|
while(GetIsObjectValid(oTarget) && nCnt <= 3)
|
|||
|
{
|
|||
|
if(oTarget != OBJECT_SELF && oTarget != oSpellTarget)
|
|||
|
{
|
|||
|
nCnt++;
|
|||
|
ActionCastSpellAtObject(PHS_SPELL_METEOR_SWARM, oTarget, METAMAGIC_NONE, TRUE, FALSE, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|||
|
}
|
|||
|
oTarget = GetNextObjectInShape(SHAPE_SPHERE, 10.0, lTarget, TRUE);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|