PRC8/nwn/nwnprc/trunk/smp/phs_s_pyrotech.nss
Jaysyn904 6ec137a24e Updated AMS marker feats
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.
2024-02-11 14:01:05 -05:00

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