Rayon prismatiques mis a jour par Olblach dans son hak.
Grace a SoU, ca devient ce que ca devait etre (gestion de la petrification) Mais il y'a aussi une gestion pour l'envoi dans des plans divers et variés
//::///////////////////////////////////////////////
//:: Prismatic Spray
//:: [NW_S0_PrisSpray.nss]
//:: Copyright (c) 2000 Bioware Corp.
//:://////////////////////////////////////////////
//:: Sends out a prismatic cone that has a random
//:: effect for each target struck.
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 19, 2000
//:://////////////////////////////////////////////
//:: Last Updated By: Preston Watamaniuk, On: April 11, 2001
//:: Last Updated By: Aidan Scanlan On: April 11, 2001
//:: Last Updated By: Preston Watamaniuk, On: June 11, 2001
// Modified by Olblach to conform 3rd Ed. PHB October, 9, 2003
// Update: October, 21, 2003 Changed the poison death part, the 2 rays hit and added more than one plane teleporting
int ApplyPrismaticEffect(int nEffect, object oTarget);
#include "X0_I0_SPELLS"
// Change the NUMPLANES value to the number of planes in your module
// They Waypoints will have to be named WP_PLANE, WP_PLANE1, and so on...
// for 3 planes:
// const int NUMPLANES = 3 ;
// and create 3 waypoints WP_PLANE, WP_PLANE1, WP_PLANE2
// for 5 planes:
// const int NUMPLANES = 5 ;
// and create 5 waypoints WP_PLANE, WP_PLANE1, WP_PLANE2, WP_PLANE3, WP_PLANE4
const int NUMPLANES = 4 ;
void main()
{
//Declare major variables
object oTarget;
int nCasterLevel = GetCasterLevel(OBJECT_SELF);
int nMetaMagic = GetMetaMagicFeat();
int nRandom;
int nHD;
int nVisual, nVisual2 ;
effect eVisual;
int bTwoEffects;
//Set the delay to apply to effects based on the distance to the target
float fDelay = 0.5 + GetDistanceBetween(OBJECT_SELF, oTarget)/20;
//Get first target in the spell area
oTarget = GetFirstObjectInShape(SHAPE_SPELLCONE, 11.0, GetSpellTargetLocation());
while (GetIsObjectValid(oTarget))
{
if (spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, OBJECT_SELF))
{
//Fire cast spell at event for the specified target
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_PRISMATIC_SPRAY));
//Make an SR check
if (!MyResistSpell(OBJECT_SELF, oTarget, fDelay) && (oTarget != OBJECT_SELF))
{
//Blind the target if they are less than 9 HD
nHD = GetHitDice(oTarget);
if (nHD <= 8)
{
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBlindness(), oTarget, RoundsToSeconds(d4()+d4()));
}
//Determine if 1 or 2 effects are going to be applied
nRandom = d8();
if(nRandom == 8)
{
nRandom = Random(7)+1 ;
int nRandom2 ;
do {
nRandom2 = Random(7)+1;
} while (nRandom2 == nRandom) ;
//Get the visual effect
nVisual = ApplyPrismaticEffect(nRandom, oTarget);
nVisual2 = ApplyPrismaticEffect(nRandom2, oTarget);
}
else
{
//Get the visual effect
nVisual = ApplyPrismaticEffect(nRandom, oTarget);
}
//Set the visual effect
if(nVisual != 0)
{
eVisual = EffectVisualEffect(nVisual);
//Apply the visual effect
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVisual, oTarget));
}
if(nVisual2 != 0)
{
eVisual = EffectVisualEffect(nVisual2);
//Apply the visual effect
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVisual, oTarget));
}
}
}
//Get next target in the spell area
oTarget = GetNextObjectInShape(SHAPE_SPELLCONE, 11.0, GetSpellTargetLocation());
}
}
///////////////////////////////////////////////////////////////////////////////
// ApplyPrismaticEffect
///////////////////////////////////////////////////////////////////////////////
/* Given a reference integer and a target, this function will apply the effect
of corresponding prismatic cone to the target. To have any effect the
reference integer (nEffect) must be from 1 to 7.*/
///////////////////////////////////////////////////////////////////////////////
// Created By: Aidan Scanlan On: April 11, 2001
///////////////////////////////////////////////////////////////////////////////
int ApplyPrismaticEffect(int nEffect, object oTarget)
{
int nDamage;
effect ePrism;
effect eVis;
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE);
effect eLink;
int nVis;
float fDelay = 0.5 + GetDistanceBetween(OBJECT_SELF, oTarget)/20;
//Based on the random number passed in, apply the appropriate effect and set the visual to
//the correct constant
// Uncomment the line below if you want to test the teleport to plane only feature (and don't forget to comment it back when done ;))
// nEffect=7 ;
switch(nEffect)
{
case 1://fire
nDamage = 20;
nVis = VFX_IMP_FLAME_S;
nDamage = GetReflexAdjustedDamage(nDamage, oTarget, GetSpellSaveDC(),SAVING_THROW_TYPE_FIRE);
ePrism = EffectDamage(nDamage, DAMAGE_TYPE_FIRE);
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, ePrism, oTarget));
break;
case 2: //Acid
nDamage = 40;
nVis = VFX_IMP_ACID_L;
nDamage = GetReflexAdjustedDamage(nDamage, oTarget, GetSpellSaveDC(),SAVING_THROW_TYPE_ACID);
ePrism = EffectDamage(nDamage, DAMAGE_TYPE_ACID);
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, ePrism, oTarget));
break;
case 3: //Electricity
nDamage = 80;
nVis = VFX_IMP_LIGHTNING_S;
nDamage = GetReflexAdjustedDamage(nDamage, oTarget, GetSpellSaveDC(),SAVING_THROW_TYPE_ELECTRICITY);
ePrism = EffectDamage(nDamage, DAMAGE_TYPE_ELECTRICAL);
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, ePrism, oTarget));
break;
case 4: //Poison
{
if (MySavingThrow(SAVING_THROW_FORT, oTarget, GetSpellSaveDC(), SAVING_THROW_TYPE_POISON) == 0)
{
if (GetIsImmune(oTarget, IMMUNITY_TYPE_POISON)) {
ePrism = EffectPoison(POISON_BEBILITH_VENOM);
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, ePrism, oTarget));
}
else {
ePrism = ExtraordinaryEffect(EffectDeath());
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, ePrism, oTarget));
}
}
else {
nDamage = 20 ;
effect ePoison = EffectDamage(nDamage, DAMAGE_TYPE_MAGICAL); //poison
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, ePoison, oTarget));
}
}
break;
case 5: //Paralyze
{
effect eDur2 = EffectVisualEffect(VFX_DUR_PARALYZED);
if (MySavingThrow(SAVING_THROW_FORT, oTarget, GetSpellSaveDC()) == 0)
{
ePrism = EffectParalyze();
eLink = EffectLinkEffects(eDur, ePrism);
eLink = EffectLinkEffects(eLink, eDur2);
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oTarget));
}
}
break;
case 6: //Feeblemind
{
effect eMind = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_DISABLED);
ePrism = EffectConfused();
eLink = EffectLinkEffects(eMind, ePrism);
eLink = EffectLinkEffects(eLink, eDur);
if (!/*Will Save*/ MySavingThrow(SAVING_THROW_WILL, oTarget, GetSpellSaveDC(), SAVING_THROW_TYPE_MIND_SPELLS, OBJECT_SELF, fDelay))
{
nVis = VFX_IMP_CONFUSION_S;
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oTarget));
}
}
break;
case 7: //Sent to outer plane
{
if (!/*Will Save*/ MySavingThrow(SAVING_THROW_WILL, oTarget, GetSpellSaveDC(), SAVING_THROW_TYPE_NONE, OBJECT_SELF, fDelay))
{
//nVis = VFX_IMP_DEATH;
nVis = VFX_IMP_UNSUMMON ;
if (!GetIsPC(oTarget))
DestroyObject(oTarget, fDelay+0.3) ;
else {
object oPlane = GetWaypointByTag("WP_PLANE") ;
int nPlane = Random(NUMPLANES) ;
if (nPlane == 0)
oPlane = GetWaypointByTag("WP_PLANE") ;
else
oPlane = GetWaypointByTag("WP_PLANE"+IntToString(Random(NUMPLANES)+1)) ;
DelayCommand(fDelay, AssignCommand(oTarget, ActionJumpToObject(oPlane)));
}
}
}
break;
}
return nVis;
}