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.
229 lines
8.7 KiB
Plaintext
229 lines
8.7 KiB
Plaintext
/*:://////////////////////////////////////////////
|
|
//:: Spell Name Pyrotechnics
|
|
//:: Spell FileName PHS_S_Pyrotech
|
|
//:://////////////////////////////////////////////
|
|
//:: In Game Spell desctiption
|
|
//:://////////////////////////////////////////////
|
|
Pyrotechnics
|
|
Transmutation
|
|
Level: Brd 2, Sor/Wiz 2
|
|
Components: V, S, M
|
|
Casting Time: 1 standard action
|
|
Range: Long (40M)
|
|
Target: One fire source, such as a spell or creature
|
|
Duration: 1d4+1 rounds, or 1d4+1 rounds after creatures leave the smoke
|
|
cloud; see text
|
|
Saving Throw: Will negates or Fortitude negates; see text
|
|
Spell Resistance: Yes or No; see text
|
|
|
|
Pyrotechnics turns a fire into either a burst of blinding fireworks or a
|
|
thick cloud of choking smoke, depending on the version you choose.
|
|
|
|
Fireworks: The fireworks are a flashing, fiery, momentary burst of glowing,
|
|
colored aerial lights. This effect causes creatures within 40 meters
|
|
(120 feet) of the fire source to become blinded for 1d4+1 rounds (Will
|
|
negates). These creatures must have line of sight to the fire to be
|
|
affected. Spell resistance can prevent blindness.
|
|
|
|
Smoke Cloud: A writhing stream of smoke billows out from the source, forming
|
|
a choking cloud. The cloud spreads to a 6.67M (20 feet) radius and lasts for
|
|
1 round per caster level. All sight, even darkvision, is ineffective in or
|
|
into the cloud. All within the cloud take -4 penalties to Strength and
|
|
Dexterity (Fortitude negates). These effects last for 1d4+1 rounds after
|
|
the cloud dissipates or after the creature leaves the area of the cloud.
|
|
Spell resistance does not apply, and this effect cannot be dispelled.
|
|
|
|
Material Component: The spell uses one fire source, magical or creature.
|
|
Magical fires are not extinguished, although a fire-based creature used as
|
|
a source takes 1 point of damage per caster level.
|
|
//:://////////////////////////////////////////////
|
|
//:: Spell Effects Applied / Notes
|
|
//:://////////////////////////////////////////////
|
|
Uses Darkness invisibility for the ineffective through the cloud part.
|
|
|
|
Defaults to fireworks. No sub-dial.
|
|
|
|
The impact is easy - 1d4 + 1 rounds of blindness, SR + Will negates.
|
|
|
|
The smoke cloud (1 round/level) applies the Darkness, and Darkness
|
|
invisibility.
|
|
|
|
Every HB may apply the -4 penalties to strength and dexterity.
|
|
//:://////////////////////////////////////////////
|
|
//:: Created By: Jasperre
|
|
//::////////////////////////////////////////////*/
|
|
|
|
#include "PHS_INC_SPELLS"
|
|
|
|
// If oObject is firey (Can be considered so in many cases), usually a fire
|
|
// based creature, we return TRUE. If this is so, we also do damage to it.
|
|
int GetIsFireObject(object oObject, int nCasterLevel);
|
|
// If there is a firey AOE near to this target location, we return TRUE - but
|
|
// do nothing about it mind you.
|
|
int GetIsFireLocation(location lTarget);
|
|
|
|
void main()
|
|
{
|
|
// Spell hook check.
|
|
if(!PHS_SpellHookCheck(PHS_SPELL_PYROTECHNICS)) return;
|
|
|
|
// Declare major variables
|
|
object oCaster = OBJECT_SELF;
|
|
object oTarget = GetSpellTargetObject();// Check later if firey
|
|
location lTarget = GetSpellTargetLocation();// Might target a firey AOE
|
|
int nCasterLevel = PHS_GetCasterLevel();
|
|
int nMetaMagic = PHS_GetMetaMagicFeat();
|
|
int nSpellSaveDC = PHS_GetSpellSaveDC();
|
|
int nSpell = GetLocalInt(oCaster, "PHS_SPELL_PYROTECHNICS_CHOICE");
|
|
|
|
// Must target something firey for both spells
|
|
if(GetIsFireObject(oTarget, nCasterLevel) || GetIsFireLocation(lTarget))
|
|
{
|
|
// What version of the spell are we doing?
|
|
if(nSpell == 0)
|
|
{
|
|
// Defaults to fireworks
|
|
|
|
// Duration (Blindness via. Fireworks) 1d4 + 1 rounds.
|
|
float fBlindness, fDelay;
|
|
|
|
// Declare effects
|
|
effect eBlind = EffectBlindness();
|
|
effect eBlindVis = EffectVisualEffect(VFX_IMP_BLIND_DEAF_M);
|
|
effect eBlindDur = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_NEGATIVE);
|
|
effect eBlindLink = EffectLinkEffects(eBlind, eBlindDur);
|
|
|
|
// Apply AOE visual
|
|
effect eImpact = EffectVisualEffect(PHS_VFX_FNF_PYROTECHNICS);
|
|
PHS_ApplyLocationVFX(lTarget, eImpact);
|
|
|
|
// Get all targets in a sphere, 40M radius, all creatures.
|
|
oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 40.0, lTarget, TRUE, 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_PYROTECHNICS);
|
|
|
|
// Get the distance between the explosion and the target to calculate delay
|
|
fDelay = GetDistanceBetweenLocations(lTarget, GetLocation(oTarget))/10;
|
|
|
|
// Spell resistance And immunity checking.
|
|
if(!PHS_SpellResistanceCheck(oCaster, oTarget, fDelay))
|
|
{
|
|
// Will negates
|
|
if(!PHS_SavingThrow(SAVING_THROW_WILL, oTarget, nSpellSaveDC, SAVING_THROW_TYPE_NONE, oCaster, fDelay))
|
|
{
|
|
// Get duration
|
|
fBlindness = PHS_GetRandomDuration(PHS_ROUNDS, 4, 1, nMetaMagic, 1);
|
|
|
|
// Apply blindness for the duration
|
|
DelayCommand(fDelay, PHS_ApplyDurationAndVFX(oTarget, eBlindVis, eBlindLink, fBlindness));
|
|
}
|
|
}
|
|
}
|
|
// Get Next Target
|
|
oTarget = GetNextObjectInShape(SHAPE_SPHERE, 6.67, lTarget, TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
|
|
}
|
|
|
|
}
|
|
else //if(nSpell == 1)
|
|
{
|
|
// Else, smoke cloud
|
|
|
|
// Duration (AOE) - 1 round/level
|
|
float fDuration = PHS_GetDuration(PHS_ROUNDS, nCasterLevel, nMetaMagic);
|
|
|
|
// Declare effects
|
|
effect eAOE = EffectAreaOfEffect(PHS_AOE_PER_PYROTECHNICS);
|
|
|
|
// Apply the AOE
|
|
PHS_ApplyLocationDuration(lTarget, eAOE, fDuration);
|
|
}
|
|
}
|
|
}
|
|
|
|
// If oObject is firey (Can be considered so in many cases), usually a fire
|
|
// based creature, we return TRUE. If this is so, we also do damage to it.
|
|
int GetIsFireObject(object oObject, int nCasterLevel)
|
|
{
|
|
int nType = GetObjectType(oObject);
|
|
// Check if a firey creature
|
|
if(nType == OBJECT_TYPE_CREATURE)
|
|
{
|
|
switch(GetAppearanceType(oObject))
|
|
{
|
|
// Being a bit leniant on who to have as "firey".
|
|
case APPEARANCE_TYPE_BALOR:
|
|
case APPEARANCE_TYPE_DOG_HELL_HOUND:
|
|
case APPEARANCE_TYPE_ELEMENTAL_FIRE:
|
|
case APPEARANCE_TYPE_ELEMENTAL_FIRE_ELDER:
|
|
case APPEARANCE_TYPE_GIANT_FIRE:
|
|
case APPEARANCE_TYPE_GIANT_FIRE_FEMALE:
|
|
case APPEARANCE_TYPE_MEPHIT_FIRE:
|
|
case APPEARANCE_TYPE_MEPHIT_MAGMA:
|
|
{
|
|
// Firey + Do damage
|
|
PHS_ApplyDamageToObject(oObject, nCasterLevel);
|
|
|
|
return TRUE;
|
|
}
|
|
break;
|
|
}
|
|
// Not firey
|
|
return FALSE;
|
|
}
|
|
// Placable
|
|
else if(nType == OBJECT_TYPE_PLACEABLE)
|
|
{
|
|
// We check 2 things.
|
|
// 1. A local saying "This produces fire"
|
|
// 2. GetPlaceableIllumination();
|
|
|
|
if(GetLocalInt(oObject, "PHS_FIRE") &&
|
|
GetPlaceableIllumination(oObject))
|
|
{
|
|
// Firey + Do damage
|
|
PHS_ApplyDamageToObject(oObject, nCasterLevel);
|
|
// Its ok
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
else if(nType == OBJECT_TYPE_DOOR)
|
|
{
|
|
// Doors currently have no fire version
|
|
return FALSE;
|
|
}
|
|
// Anything else
|
|
return FALSE;
|
|
}
|
|
|
|
// If there is a firey AOE near to this target location, we return TRUE - but
|
|
// do nothing about it mind you.
|
|
int GetIsFireLocation(location lTarget)
|
|
{
|
|
// Check for nearest objects which are fire AOE's
|
|
int nCnt = 1;
|
|
object oAOE = GetNearestObjectToLocation(OBJECT_TYPE_AREA_OF_EFFECT, lTarget, nCnt);
|
|
while(GetIsObjectValid(oAOE) && GetDistanceBetweenLocations(lTarget, GetLocation(oAOE)) <= 7.0)
|
|
{
|
|
// We will check the tag.
|
|
if(PHS_GetIsFireyAOE(oAOE))
|
|
{
|
|
// Firey
|
|
return TRUE;
|
|
}
|
|
// Next AOE
|
|
nCnt++;
|
|
oAOE = GetNearestObjectToLocation(OBJECT_TYPE_AREA_OF_EFFECT, lTarget, nCnt);
|
|
}
|
|
// No fire
|
|
return FALSE;
|
|
}
|