/*::////////////////////////////////////////////// //:: 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; }