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