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.
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));
|
|
}
|
|
}
|