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.
241 lines
9.0 KiB
Plaintext
241 lines
9.0 KiB
Plaintext
/*:://////////////////////////////////////////////
|
|
//:: Spell Name Earthquake
|
|
//:: Spell FileName PHS_S_Earthquake
|
|
//:://////////////////////////////////////////////
|
|
//:: In Game Spell desctiption
|
|
//:://////////////////////////////////////////////
|
|
Evocation [Earth]
|
|
Level: Clr 8, Destruction 8, Drd 8, Earth 7
|
|
Components: V, S, DF
|
|
Casting Time: 1 standard action
|
|
Range: Long (40M)
|
|
Area: 26.67-M.-radius spread (S)
|
|
Duration: 1 round
|
|
Saving Throw: See text
|
|
Spell Resistance: No
|
|
|
|
When you cast earthquake, an intense but highly localized tremor rips the
|
|
ground. The shock knocks creatures down, collapses structures, opens cracks
|
|
in the ground, and more. The specific effect of an earthquake spell depends
|
|
on the nature of the terrain where it is cast.
|
|
|
|
Natural Interior (cave) Man-Made interior (building): The spell collapses
|
|
the roof or bring down supports and stonework, dealing 8d6 points of
|
|
bludgeoning damage to any creature caught under the cave-in (Reflex DC 15
|
|
half, and no pinning) and pinning that creature beneath the rubble (see
|
|
below).
|
|
|
|
Open Ground: Each creature standing in the area must make a DC 15 Reflex
|
|
save or fall down for the round. Fissures open in the earth, and every
|
|
creature on the ground has a 25% chance to fall into one (Reflex DC 20 to
|
|
avoid a fissure). At the end of the spell, all fissures grind shut, killing
|
|
any creatures still trapped within.
|
|
|
|
Pinned beneath Rubble: Any creature pinned beneath rubble takes 1d6 points
|
|
of bludgeoning damage per minute while pinned. A pinned creature is
|
|
effectivly knocked down, and requires a DC 25 Strength Check to escape,
|
|
each round.
|
|
//:://////////////////////////////////////////////
|
|
//:: Spell Effects Applied / Notes
|
|
//:://////////////////////////////////////////////
|
|
A massive AOE, and requires several saves.
|
|
|
|
The effect depends on the status of the area - and if it can be collapsed
|
|
at all! (no collapse = no damage, pinning or fissures, but the 1 round
|
|
of being stopped still applies)
|
|
|
|
The pinning is done via. delay command.
|
|
//:://////////////////////////////////////////////
|
|
//:: Created By: Jasperre
|
|
//::////////////////////////////////////////////*/
|
|
|
|
#include "PHS_INC_SPELLS"
|
|
|
|
// Call this to start pin checks
|
|
void WrapperDelayRemoval(float fDelay, object oTarget);
|
|
// This is called from WrapperDelayRemoval
|
|
// Does damage when nLastRound + 1 (the current round) is 10.
|
|
void PinCheck(int nSpellId, int nTimesCast, int nLastRound, object oTarget);
|
|
|
|
void main()
|
|
{
|
|
// Spell Hook Check.
|
|
if(!PHS_SpellHookCheck(PHS_SPELL_EARTHQUAKE)) return;
|
|
|
|
// Declare major variables
|
|
object oCaster = OBJECT_SELF;
|
|
object oTarget;
|
|
location lTarget = GetSpellTargetLocation();
|
|
object oArea = GetArea(oCaster);
|
|
int nSpellSaveDC = PHS_GetSpellSaveDC();
|
|
int nMetaMagic = PHS_GetMetaMagicFeat();
|
|
int bIndoors = GetIsAreaInterior(oArea);
|
|
int bNatural = GetIsAreaNatural(oArea);
|
|
//int bAboveGround = GetIsAreaAboveGround(oArea);
|
|
int nEffect;
|
|
int nDam;
|
|
float fDelay;
|
|
// 1 Round of duration
|
|
float f1Round = 6.0;
|
|
|
|
// Check if area can be earthquaked
|
|
if(GetLocalInt(oArea, "PHS_EARTHQUAKE_IMMUNE")) return;
|
|
|
|
// Declare Effects
|
|
effect eVis;// = EffectVisualEffect(VFX_IMP_ROCKEXPLODE);
|
|
effect eImpact;// = EffectVisualEffect(nVFX);
|
|
effect eDeath = EffectDeath();
|
|
effect ePin = EffectKnockdown();
|
|
effect eDur = EffectVisualEffect(VFX_DUR_STONEHOLD);
|
|
|
|
// Link effects
|
|
effect eLink = EffectLinkEffects(ePin, eDur);
|
|
|
|
// Get the right VFX based on indoors/outdoors
|
|
if(bIndoors == TRUE)
|
|
{
|
|
// Declare indoor visual effects
|
|
eVis = EffectVisualEffect(VFX_IMP_ROCKEXPLODE);
|
|
if(bNatural == TRUE)
|
|
{
|
|
eImpact = EffectVisualEffect(PHS_VFX_FNF_EARTHQUAKE_INSIDE_NATURAL);
|
|
}
|
|
else
|
|
{
|
|
eImpact = EffectVisualEffect(PHS_VFX_FNF_EARTHQUAKE_INSIDE_NOT_NATURAL);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Declare outdoor visual effects
|
|
eVis = EffectVisualEffect(PHS_VFX_IMP_EARTHQUAKE_FISSURE);
|
|
eImpact = EffectVisualEffect(PHS_VFX_FNF_EARTHQUAKE_OUTSIDE);
|
|
}
|
|
|
|
// Apply AOE visual
|
|
PHS_ApplyLocationVFX(lTarget, eImpact);
|
|
|
|
// Get all targets in a sphere, 26.67M radius, creature objects.
|
|
// - No LOS needed. This affects anyone in the AOE.
|
|
oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 26.67, lTarget, FALSE, OBJECT_TYPE_CREATURE);
|
|
// Loop targets
|
|
while(GetIsObjectValid(oTarget))
|
|
{
|
|
// PvP Check
|
|
if(!GetIsReactionTypeFriendly(oTarget, oCaster) &&
|
|
// Make sure they are not immune to spells
|
|
!PHS_TotalSpellImmunity(oTarget))
|
|
{
|
|
// Fire cast spell at event for the specified target
|
|
PHS_SignalSpellCastAt(oTarget, PHS_SPELL_EARTHQUAKE);
|
|
|
|
// Get a random small delay
|
|
fDelay = PHS_GetRandomDelay(0.2, 1.6)/10;
|
|
|
|
// If interior, we do damage and pinning
|
|
if(bIndoors)
|
|
{
|
|
// Roll damage for each target. 8d6
|
|
nDam = PHS_MaximizeOrEmpower(6, 8, nMetaMagic);
|
|
|
|
// Adjust the damage based on the Reflex Save, Evasion and Improved Evasion.
|
|
nDam = PHS_GetAdjustedDamage(SAVING_THROW_REFLEX, nDam, oTarget, nSpellSaveDC, SAVING_THROW_TYPE_NONE, oCaster, fDelay);
|
|
|
|
// Need to do damage to apply visuals and pinning.
|
|
if(nDam > 0)
|
|
{
|
|
// Apply effects to the currently selected target.
|
|
DelayCommand(fDelay, PHS_ApplyDamageVFXToObject(oTarget, eVis, nDam, DAMAGE_TYPE_BLUDGEONING));
|
|
|
|
// Apply the pinning
|
|
DelayCommand(fDelay, PHS_ApplyPermanent(oTarget, eDur));
|
|
|
|
// Delay a pin check
|
|
WrapperDelayRemoval(fDelay + f1Round, oTarget);
|
|
}
|
|
}
|
|
// Else, exterior, special fissures.
|
|
else
|
|
{
|
|
// Open Ground: Each creature standing in the area must make a DC 15 Reflex
|
|
// save or fall down for the round. Fissures open in the earth, and every
|
|
// creature on the ground has a 25% chance to fall into one (Reflex DC 20 to
|
|
// avoid a fissure). At the end of the spell, all fissures grind shut, killing
|
|
// any creatures still trapped within.
|
|
|
|
// First: 25% of a fissure. If they die, they die!
|
|
if(d100() <= 25)
|
|
{
|
|
// Fissure!
|
|
PHS_ApplyLocationVFX(GetLocation(oTarget), eVis);
|
|
|
|
// Reflex save DC 20 or die
|
|
if(!PHS_SavingThrow(SAVING_THROW_REFLEX, oTarget, 20, SAVING_THROW_TYPE_NONE, oCaster, fDelay))
|
|
{
|
|
// Apply knockdown for 6 seconds, then do the death.
|
|
DelayCommand(fDelay, PHS_ApplyDuration(oTarget, ePin, f1Round - fDelay));
|
|
|
|
// Delay death
|
|
DelayCommand(f1Round, PHS_ApplyInstant(oTarget, eDeath));
|
|
}
|
|
}
|
|
// Failing that, we will do a reflex save just to stay upright
|
|
else if(!PHS_SavingThrow(SAVING_THROW_REFLEX, oTarget, 15, SAVING_THROW_TYPE_NONE, oCaster, fDelay))
|
|
{
|
|
// Apply knockdown for 6 seconds
|
|
DelayCommand(fDelay, PHS_ApplyDuration(oTarget, ePin, f1Round - fDelay));
|
|
}
|
|
}
|
|
}
|
|
// Get Next Target
|
|
oTarget = GetNextObjectInShape(SHAPE_SPHERE, 26.67, lTarget, FALSE, OBJECT_TYPE_CREATURE);
|
|
}
|
|
}
|
|
|
|
void WrapperDelayRemoval(float fDelay, object oTarget)
|
|
{
|
|
int nSpell = GetSpellId();
|
|
int nCastTimes = GetLocalInt(OBJECT_SELF, "PHS_TIMES_CAST" + IntToString(nSpell));
|
|
nCastTimes++; // Add one to cast times
|
|
SetLocalInt(OBJECT_SELF, "TIMES_CAST" + IntToString(nSpell), nCastTimes);
|
|
DelayCommand(fDelay, PinCheck(nSpell, nCastTimes, 0, oTarget));
|
|
}
|
|
|
|
void PinCheck(int nSpellId, int nTimesCast, int nLastRound, object oTarget)
|
|
{
|
|
// Add one to current rounds
|
|
int nThisRound = nLastRound + 1;
|
|
|
|
if(!GetHasSpellEffect(nSpellId, oTarget) ||
|
|
GetLocalInt(oTarget, "PHS_TIMES_CAST" + IntToString(nSpellId)) != nTimesCast ||
|
|
PHS_AbilityCheck(oTarget, ABILITY_STRENGTH, 25))
|
|
{
|
|
effect eCheck = GetFirstEffect(oTarget);
|
|
while(GetIsEffectValid(eCheck))
|
|
{
|
|
if(GetEffectSpellId(eCheck) == nSpellId)
|
|
{
|
|
RemoveEffect(oTarget, eCheck);
|
|
}
|
|
eCheck = GetNextEffect(oTarget);
|
|
}
|
|
}
|
|
// Every 10th round, we do damage
|
|
else if(nThisRound == 10)
|
|
{
|
|
// reset it to 0
|
|
nThisRound = 0;
|
|
|
|
// Do damage
|
|
PHS_ApplyDamageToObject(oTarget, d6(), DAMAGE_TYPE_BLUDGEONING);
|
|
|
|
// Another delay
|
|
DelayCommand(6.0, PinCheck(nSpellId, nTimesCast, nThisRound, oTarget));
|
|
}
|
|
else
|
|
{
|
|
// Another delay
|
|
DelayCommand(6.0, PinCheck(nSpellId, nTimesCast, nThisRound, oTarget));
|
|
}
|
|
}
|