LoD_PRC8/_module/nss/hal_finbosspa.nss
Jaysyn904 94990edc60 Initial Upload
Initial Upload
2023-09-21 21:20:34 -04:00

175 lines
6.3 KiB
Plaintext

#include "NW_I0_SPELLS"
#include "x0_i0_match"
//::///////////////////////////////////////////////
//:: BaalMissileStorm
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
Fires a volley of missiles around the area
of the object selected.
Each missiles (nD6Dice)d6 damage.
There are casterlevel missiles (to a cap as specified)
*/
/*
Totally destroyed by Ba'alzamon on 11.8.2004.
*/
//:://////////////////////////////////////////////
//:: Created By: Brent
//:: Created On: July 31, 2002
//:://////////////////////////////////////////////
//:: Modified March 14 2003: Removed the option to hurt chests/doors
//:: was potentially causing bugs when no creature targets available.
void BaalMissileStorm(object oCaster, int nD6Dice, int nCap, int nSpell, int nMIRV = VFX_IMP_MIRV, int nVIS = VFX_IMP_MAGBLUE, int nDAMAGETYPE = DAMAGE_TYPE_MAGICAL, int nONEHIT = FALSE)
{
object oTarget = OBJECT_INVALID;
int nCasterLvl = GetCasterLevel(OBJECT_SELF);
int nDamage = 0;
int nCnt = 1;
effect eMissile = EffectVisualEffect(nMIRV);
effect eVis = EffectVisualEffect(nVIS);
float fDist = 0.0;
float fDelay = 0.0;
float fDelay2, fTime;
location lTarget = GetLocation(OBJECT_SELF); // missile spread centered around caster
int nMissiles = nCasterLvl;
if (nMissiles > nCap)
{
nMissiles = nCap;
}
/* New Algorithm
1. Count # of targets
2. Determine number of missiles
3. First target gets a missile and all Excess missiles
4. Rest of targets (max nMissiles) get one missile
*/
int nEnemies = 0;
oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_GARGANTUAN, lTarget, TRUE, OBJECT_TYPE_CREATURE);
//Cycle through the targets within the spell shape until an invalid object is captured.
while (GetIsObjectValid(oTarget) )
{
// * caster cannot be harmed by this spell
if (oTarget != OBJECT_SELF)
{
nEnemies++;
}
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_GARGANTUAN, lTarget, TRUE, OBJECT_TYPE_CREATURE);
}
if (nEnemies == 0) return; // * Exit if no enemies to hit
int nExtraMissiles = nMissiles / nEnemies;
// by default the Remainder will be 0 (if more than enough enemies for all the missiles)
int nRemainder = 0;
if (nExtraMissiles >0)
nRemainder = nMissiles % nEnemies;
// April 2003
// * if more enemies than missiles, need to make sure that at least
// * one missile will hit each of the enemies
if (nExtraMissiles <= 0)
{
nExtraMissiles = 1;
}
if (nEnemies > nMissiles)
nEnemies = nMissiles;
oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_GARGANTUAN, lTarget, TRUE, OBJECT_TYPE_CREATURE);
//Cycle through the targets within the spell shape until an invalid object is captured.
while (GetIsObjectValid(oTarget) && nCnt <= nEnemies)
{
// * caster cannot be harmed by this spell
if (oTarget != OBJECT_SELF && !GetIsDead(oTarget))
{
//Fire cast spell at event for the specified target
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, nSpell));
// * recalculate appropriate distances
fDist = GetDistanceBetween(OBJECT_SELF, oTarget);
fDelay = fDist/(3.0 * log(fDist) + 2.0);
// Firebrand.
// It means that once the target has taken damage this round from the
// spell it won't take subsequent damage
if (nONEHIT == TRUE)
{
nExtraMissiles = 1;
nRemainder = 0;
}
int i = 0;
// * first target will get excess missiles
for (i=1; i <= nExtraMissiles + nRemainder; i++)
{
//Make SR Check
if (!GetLocalInt(oTarget, "SRCheckDone"))
{
if (!MyResistSpell(OBJECT_SELF, oTarget, fDelay))
{
SetLocalInt(oTarget, "SRCheckDone", 1);
DelayCommand(1.5, SetLocalInt(oTarget, "SRCheckDone", FALSE));
}
else
{
SetLocalInt(oTarget, "SRCheckDone", 2);
DelayCommand(1.5, SetLocalInt(oTarget, "SRCheckDone", FALSE));
}
}
if(GetLocalInt(oTarget, "SRCheckDone") == 1)
{
//Roll damage
int nDam = d6(nD6Dice);
fTime = fDelay;
fDelay2 += 0.1;
fTime += fDelay2;
if (nSpell == SPELL_FIREBRAND)
nDam = GetReflexAdjustedDamage(nDam, oTarget, GetSpellSaveDC(), SAVING_THROW_TYPE_FIRE,oCaster);
//Set damage effect
effect eDam = EffectDamage(nDam, nDAMAGETYPE);
//Apply the MIRV and damage effect
DelayCommand(fTime, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oTarget));
DelayCommand(fDelay2, ApplyEffectToObject(DURATION_TYPE_INSTANT, eMissile, oTarget));
DelayCommand(fTime, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
}
else
{ // * apply a dummy visual effect
ApplyEffectToObject(DURATION_TYPE_INSTANT, eMissile, oTarget);
}
} // for
nCnt++;// * increment count of missiles fired
nRemainder = 0;
}
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_GARGANTUAN, lTarget, TRUE, OBJECT_TYPE_CREATURE);
}
}
void main()
{
ExecuteScript("nw_c2_default1", OBJECT_SELF);
int iRoll = d8(1);
if(iRoll == 4)
{
ClearAllActions(TRUE);
DelayCommand(0.2, PlayVoiceChat(VOICE_CHAT_BATTLECRY1, OBJECT_SELF));
DelayCommand(0.5, BaalMissileStorm(OBJECT_SELF, 60, 10, SPELL_ISAACS_GREATER_MISSILE_STORM, VFX_IMP_MIRV_FLAME, VFX_IMP_MAGBLUE, DAMAGE_TYPE_DIVINE, FALSE));
}
}