Added missing Force Missiles spell script
Added missing Force Missiles spell script. Fixed a few minor typos.
This commit is contained in:
parent
1408647e37
commit
31a0ccbf16
@ -249,4 +249,9 @@
|
||||
245 Crystallize 16823673 14202 6
|
||||
246 BasiliskMask 16836737 18708 8
|
||||
247 GorgonMask 16836803 18729 8
|
||||
248 SPELL_FORCE_MISSILES 16790488 2480 4
|
||||
248 Bigbys_Interposing_Hand 2683 459 5
|
||||
249 Illithid_Mindblast 83865 789 3
|
||||
250 Psionic_Mass_Concussion 84464 763 5
|
||||
251 MONSTER_MindBlast 3891 551 3
|
||||
252 MONSTER_CharmMonster 3893 552 3
|
||||
253 SPELL_FORCE_MISSILES 16790488 2480 4
|
||||
|
@ -148,7 +148,7 @@ int GetIsElementalSpell(int nSpellID, int nDescriptor = -1);
|
||||
int GetIsOfSubschool(int nSpellID, int nSubschoolFlag);
|
||||
|
||||
/**
|
||||
* Returns an integer value containing the bitflags of descriptors set in prc_splls.2da
|
||||
* Returns an integer value containing the bitflags of descriptors set in prc_spells.2da
|
||||
* for a given SpellID
|
||||
*
|
||||
* @param nSpellID row number of tested spell in spells.2da
|
||||
@ -157,7 +157,7 @@ int GetIsOfSubschool(int nSpellID, int nSubschoolFlag);
|
||||
int GetDescriptorFlags(int nSpellID);
|
||||
|
||||
/**
|
||||
* Returns an integer value containing the bitflags of subschools set in prc_splls.2da
|
||||
* Returns an integer value containing the bitflags of subschools set in prc_spells.2da
|
||||
* for a given SpellID
|
||||
*
|
||||
* @param nSpellID row number of tested spell in spells.2da
|
||||
|
194
nwn/nwnprc/trunk/spells/sp_forcemissiles.nss
Normal file
194
nwn/nwnprc/trunk/spells/sp_forcemissiles.nss
Normal file
@ -0,0 +1,194 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Force Missiles
|
||||
//:: sp_forcemissiles
|
||||
//:: Copyright (c) 2022 PRC
|
||||
//:://////////////////////////////////////////////
|
||||
/*/
|
||||
Force Missiles
|
||||
(Spell Compendium, p. 98)
|
||||
|
||||
Evocation [Force]
|
||||
Level: Sorcerer 4, Wizard 4,
|
||||
Components: V, S,
|
||||
Casting Time: 1 Standard Action
|
||||
Range: Medium (100 ft. + 10 ft./level)
|
||||
Target: Up to four creatures, no two of which are more than 30 ft. apart
|
||||
Duration: Instantaneous
|
||||
Saving Throw: None
|
||||
Spell Resistance: Yes
|
||||
|
||||
Sparking bolts of blue magic, like giant magic missiles, streak from your
|
||||
outstretched hand to strike your foes and explode in sparkling bursts.
|
||||
|
||||
You create powerful missiles of magical force, each of which darts from your
|
||||
fingertips and unerringly strikes its target, dealing 2d6 points of damage.
|
||||
The missile then explodes in a burst of force that deals half this amount of
|
||||
damage to any creatures adjacent to the primary target.
|
||||
|
||||
The missile strikes unerringly, even if the target is in melee or has anything
|
||||
less than total cover or concealment. A caster cannot single out specific parts
|
||||
of a creature.
|
||||
|
||||
You gain one missile for every four caster levels. You can make more than one
|
||||
missile strike a single target, if desired. However,you must designate targets
|
||||
before rolling for spell resistance or damage.
|
||||
|
||||
/*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Tsurani Nevericy
|
||||
//:: Created On: 05/15/2024
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Last Updated By: Tsurani Nevericy
|
||||
//:: Last Updated On: 05/15/2024
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
#include "prc_sp_func"
|
||||
#include "prc_inc_spells"
|
||||
#include "x2_inc_spellhook"
|
||||
|
||||
void SendMissileBomb(object oCaster, object oTarget, float fDelay=0.0, float fTime=0.0)
|
||||
{
|
||||
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_MIRV), oTarget);
|
||||
location lLoc = GetLocation(oTarget);
|
||||
object oLoop = GetFirstObjectInShape(SHAPE_SPHERE, 5.0, lLoc, TRUE);
|
||||
while (GetIsObjectValid(oLoop))
|
||||
{
|
||||
SignalEvent(oLoop, EventSpellCastAt(oCaster, PRCGetSpellId()));
|
||||
if (oLoop == oTarget)
|
||||
{
|
||||
int nDam = d6(2);
|
||||
if (nMetaMagic == METAMAGIC_MAXIMIZE)
|
||||
nDam = 12;
|
||||
if (nMetaMagic == METAMAGIC_EMPOWER)
|
||||
nDam += nDam/2;
|
||||
DelayCommand(fTime, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDam, DAMAGE_TYPE_MAGICAL), oLoop));
|
||||
DelayCommand(fTime, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_IMP_MAGBLUE, FALSE, 4.0f), oLoop));
|
||||
}
|
||||
else if (!PRCDoResistSpell(oCaster, oLoop, FloatToInt(fDelay)))
|
||||
{
|
||||
int nDam = d6(1);
|
||||
if (nMetaMagic == METAMAGIC_MAXIMIZE)
|
||||
nDam = 6;
|
||||
if (nMetaMagic == METAMAGIC_EMPOWER)
|
||||
nDam += nDam/2;
|
||||
DelayCommand(fTime, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDam, DAMAGE_TYPE_MAGICAL), oLoop));
|
||||
DelayCommand(fTime, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_IMP_MAGBLUE), oLoop));
|
||||
}
|
||||
oLoop = GetNextObjectInShape(SHAPE_SPHERE, 5.0, lLoc, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
//Implements the spell impact, put code here
|
||||
// if called in many places, return TRUE if
|
||||
// stored charges should be decreased
|
||||
// eg. touch attack hits
|
||||
//
|
||||
// Variables passed may be changed if necessary
|
||||
int DoSpell(object oCaster, object oTarget, int nCasterLevel, int nEvent)
|
||||
{
|
||||
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||
int nSaveDC = PRCGetSaveDC(oTarget, oCaster);
|
||||
int nPenetr = nCasterLevel + SPGetPenetr();
|
||||
int i;
|
||||
int nTargets;
|
||||
int nCnt = 1;
|
||||
float fDist, fDelay, fDelay2, fTime;
|
||||
|
||||
if (nCasterLevel > 40) nCasterLevel = 40;
|
||||
int nMissiles = nCasterLevel/4;
|
||||
if (nMissiles < 1) nMissiles = 1;
|
||||
|
||||
location lTarget = PRCGetSpellTargetLocation();
|
||||
|
||||
oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 9.144, lTarget, TRUE, OBJECT_TYPE_CREATURE);
|
||||
while (GetIsObjectValid(oTarget))
|
||||
{
|
||||
if (spellsIsTarget(oTarget, SPELL_TARGET_SELECTIVEHOSTILE, oCaster) && oTarget != oCaster)
|
||||
{
|
||||
nTargets++;
|
||||
}
|
||||
oTarget = GetNextObjectInShape(SHAPE_SPHERE, 9.144, lTarget, TRUE, OBJECT_TYPE_CREATURE);
|
||||
}
|
||||
if (!nTargets)
|
||||
return FALSE;
|
||||
|
||||
int nExtraMissiles = nMissiles / nTargets;
|
||||
|
||||
if (nExtraMissiles <= 0)
|
||||
nExtraMissiles = 1;
|
||||
|
||||
int nRemainder = 0;
|
||||
|
||||
if (nTargets > nMissiles) nTargets = nMissiles;
|
||||
|
||||
nRemainder = nMissiles % nTargets;
|
||||
|
||||
oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 9.144, lTarget, TRUE, OBJECT_TYPE_CREATURE);
|
||||
while (GetIsObjectValid(oTarget) && nCnt <= nTargets)
|
||||
{
|
||||
if (spellsIsTarget(oTarget, SPELL_TARGET_SELECTIVEHOSTILE, oCaster) && oTarget != oCaster)
|
||||
{
|
||||
if (!PRCDoResistSpell(oCaster, oTarget, FloatToInt(fDelay)))
|
||||
{
|
||||
int i;
|
||||
for (i=1; i <= nExtraMissiles + nRemainder; i++)
|
||||
{
|
||||
fDist = GetDistanceBetween(oCaster, oTarget);
|
||||
fDelay = fDist/(3.0 * log(fDist) + 2.0);
|
||||
fTime = fDelay;
|
||||
fDelay2 += 0.1;
|
||||
fTime += fDelay2;
|
||||
DelayCommand(fDelay2, SendMissileBomb(oCaster, oTarget, fDelay, fTime));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_MIRV), oTarget);
|
||||
}
|
||||
nCnt++;
|
||||
nRemainder = 0;
|
||||
}
|
||||
oTarget = GetNextObjectInShape(SHAPE_SPHERE, 9.144, lTarget, TRUE, OBJECT_TYPE_CREATURE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
object oCaster = OBJECT_SELF;
|
||||
object oTarget = PRCGetSpellTargetObject();
|
||||
|
||||
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||
int i;
|
||||
int nTargets;
|
||||
int nCnt = 1;
|
||||
float fDist, fDelay, fDelay2, fTime;
|
||||
|
||||
PRCSetSchool(GetSpellSchool(PRCGetSpellId()));
|
||||
|
||||
if (!X2PreSpellCastCode()) return;
|
||||
|
||||
int nEvent = GetLocalInt(oCaster, PRC_SPELL_EVENT); //use bitwise & to extract flags
|
||||
if(!nEvent) //normal cast
|
||||
{
|
||||
if(GetLocalInt(oCaster, PRC_SPELL_HOLD) && oCaster == oTarget)
|
||||
{ //holding the charge, casting spell on self
|
||||
SetLocalSpellVariables(oCaster, 1); //change 1 to number of charges
|
||||
return;
|
||||
}
|
||||
DoSpell(oCaster, oTarget, nCasterLevel, nEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(nEvent & PRC_SPELL_EVENT_ATTACK)
|
||||
{
|
||||
if(DoSpell(oCaster, oTarget, nCasterLevel, nEvent))
|
||||
DecrementSpellCharges(oCaster);
|
||||
}
|
||||
}
|
||||
PRCSetSchool();
|
||||
}
|
||||
|
||||
//::///////////////////////////////////////////////////////////////////
|
@ -72975,4 +72975,4 @@ Use: Activated</entry>
|
||||
<entry id="77190" lang="en" sex="m">Spellcasting isn't required to take the Talon of Tiamat prestige class. If you currently have an arcane spellcasting, shadowcasting or invoking class, do not pick this marker feat.</entry>
|
||||
<entry id="77191" lang="en" sex="m">Spellcasting isn't required to take the Dragonsong Lyrist prestige class. If you currently have an arcane spellcasting or shadowcasting class, do not pick this marker feat.</entry>
|
||||
<entry id="77192" lang="en" sex="m">Spellcasting isn't required to take the Ollam prestige class. If you currently have an arcane spellcasting or shadowcasting class, do not pick this marker feat.</entry>
|
||||
</tlk>
|
||||
</tlk>
|
Loading…
x
Reference in New Issue
Block a user