Jaysyn904 0f43e5cbd2 2025-04-15 Update
Added Elven blades to Weaponmaster prereqs
Fixed Beckon the Frozen
Fixed bug with Fire Brand
Fixed duration bug with Improved Invisibility
Added Soul Eater to Shifter prereqs
Fixed ability based class prereqs in prc_prereq.nss
Update Eye of Gruumsh for epic levels
Update Ur-Priest for epic levels
Update Forsaker for epic levels
Update Anima Mage for epic levels
Update Serene Guardian for epic levels
Bladesinger abilities can use chain shirts
Fixed Elemental Abjuration
Fixed bug with prc cache creature.
Forsakers can use non-magic items (heal kits, alchemy, etc)
Updated ruleset.2da for NWNEE update
Updated AotS bonus feats

-Notes
Added 3.5e Template index
Added 3.5e update booklet

Removed release archive
2025-04-15 18:10:14 -04:00

258 lines
9.6 KiB
Plaintext

//::///////////////////////////////////////////////
//:: Firebrand
//:: x0_x0_Firebrand
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
Evocation [Fire]
Level: Sorcerer 5, Wizard 5,
Components: V, S, M,
Casting Time: 1 standard action
Range: Medium (100 ft. + 10 ft./level)
Area: One 5-ft.-radius burst/level (S)
Duration: Instantaneous
Saving Throw: Reflex half
Spell Resistance: Yes
The flask of alchemist's fire vanishes from you hand and the
ground erupts beneath your foes, shooting multiple fountains
of fiery liquid upward.
Each burst deals 1d6 points of damage per caster level
(maximum 10d6) to all creatures within the area. All
subjects hit by the burst in the round the spell is
cast or within the area in the following round take 1d6
points of fire damage per two caster levels (maximum 5d6).
A character struck in the round the spell is cast can
attempt to extinguish the flames on itself as a
full-round action with a successful DC 15 Reflex
save.
Burst effects that overlap do not deal additional
damage (a creature can be affected by only one burst).
Material Component: A flask of alchemist's fire
(worth 20 gp).
// * Fires a flame arrow to every target in a
// * colossal area
// * Each target explodes into a small fireball for
// * 1d6 damage / level (max = 15 levels)
// * Only nLevel targets can be affected
*/
//:://////////////////////////////////////////////
//:: Created By: Brent
//:: Created On: July 29 2002
//:://////////////////////////////////////////////
//:: Last Updated By:
//
// Altered to give targets reflex saves per pnp.
//
//:: altered by mr_bumpkin Dec 4, 2003 for prc stuff
#include "prc_inc_spells"
#include "prc_add_spell_dc"
void DoFirebrand(int CasterLvl,int nD6Dice, int nCap, int nSpell,
int nMIRV = VFX_IMP_MIRV, int nVIS = VFX_IMP_MAGBLUE,
int nDAMAGETYPE = DAMAGE_TYPE_MAGICAL, int nONEHIT = FALSE);
void main()
{
DeleteLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR");
SetLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR", SPELL_SCHOOL_EVOCATION);
/*
Spellcast Hook Code
Added 2003-06-20 by Georg
If you want to make changes to all spells,
check x2_inc_spellhook.nss to find out more
*/
if (!X2PreSpellCastCode())
{
// If code within the PreSpellCastHook (i.e. UMD) reports FALSE, do not run this spell
return;
}
// End of Spell Cast Hook
int CasterLvl = PRCGetCasterLevel(OBJECT_SELF);
int nDamage = CasterLvl;
if (nDamage > 15)
nDamage = 15;
// Changed to local function to add reflex save.
DoFirebrand(CasterLvl,nDamage, 15, SPELL_FIREBRAND, VFX_IMP_MIRV_FLAME, VFX_IMP_FLAME_M, ChangedElementalDamage(OBJECT_SELF, DAMAGE_TYPE_FIRE), TRUE);
DeleteLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR");
// Erasing the variable used to store the spell's spell school
}
//:://////////////////////////////////////////////
//:: 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.
//:://////////////////////////////////////////////
//:: 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 DoFirebrand(int CasterLvl,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 nDamage = 0;
int nMetaMagic = PRCGetMetaMagicFeat();
int nCnt = 1;
effect eMissile = EffectVisualEffect(nMIRV);
effect eVis = EffectVisualEffect(nVIS);
float fDist = 0.0;
float fDelay = 0.0;
float fDelay2, fTime;
location lTarget = PRCGetSpellTargetLocation(); // missile spread centered around caster
int nMissiles = CasterLvl;
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;
int nCasterlvl = CasterLvl +SPGetPenetr();
oTarget = MyFirstObjectInShape(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 (spellsIsTarget(oTarget, SPELL_TARGET_SELECTIVEHOSTILE, OBJECT_SELF) && (oTarget != OBJECT_SELF))
{
// GZ: You can only fire missiles on visible targets
if (GetObjectSeen(oTarget,OBJECT_SELF))
{
nEnemies++;
}
}
oTarget = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_GARGANTUAN, lTarget, TRUE, OBJECT_TYPE_CREATURE);
}
if (nEnemies == 0) return; // * Exit if no enemies to hit
int nExtraMissiles = 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;
}
// 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;
if (nEnemies > nMissiles)
nEnemies = nMissiles;
oTarget = MyFirstObjectInShape(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 (spellsIsTarget(oTarget, SPELL_TARGET_SELECTIVEHOSTILE, OBJECT_SELF) && (oTarget != OBJECT_SELF) && (GetObjectSeen(oTarget,OBJECT_SELF)))
{
//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;
//--------------------------------------------------------------
// GZ: Moved SR check out of loop to have 1 check per target
// not one check per missile, which would rip spell mantels
// apart
//--------------------------------------------------------------
if (!PRCDoResistSpell(OBJECT_SELF, oTarget,nCasterlvl, fDelay))
{
int nDC = PRCGetSaveDC(oTarget,OBJECT_SELF);
for (i=1; i <= nExtraMissiles + nRemainder; i++)
{
//Roll damage
int nDam = d6(nD6Dice);
//Enter Metamagic conditions
if ((nMetaMagic & METAMAGIC_MAXIMIZE))
{
nDam = nD6Dice*6;//Damage is at max
}
if ((nMetaMagic & METAMAGIC_EMPOWER))
{
nDam = nDam + nDam/2; //Damage/Healing is +50%
}
nDam += SpellDamagePerDice(OBJECT_SELF, nD6Dice);
if(i == 1) //nDam += ApplySpellBetrayalStrikeDamage(oTarget, OBJECT_SELF);
fTime = fDelay;
fDelay2 += 0.1;
fTime += fDelay2;
// Adjust damage for reflex save / evasion / imp evasion
nDam = PRCGetReflexAdjustedDamage(nDam, oTarget,
nDC, SAVING_THROW_TYPE_FIRE);
// Always apply missle but only apply impact/damage if we really have damage.
DelayCommand(fDelay2, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eMissile, oTarget));
if (nDam > 0)
{
//Set damage effect
effect eDam = PRCEffectDamage(oTarget, nDam, nDAMAGETYPE);
//Apply the MIRV and damage effect
DelayCommand(fTime, SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oTarget,0.0f,TRUE,-1,CasterLvl));
DelayCommand(fTime, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
}
}
} // for
else
{ // * apply a dummy visual effect
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eMissile, oTarget);
}
nCnt++;// * increment count of missiles fired
nRemainder = 0;
}
oTarget = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_GARGANTUAN, lTarget, TRUE, OBJECT_TYPE_CREATURE);
}
}