Further file organization
Further file organization
This commit is contained in:
214
nwn/nwnprc/trunk/spells/sp_alcspark.nss
Normal file
214
nwn/nwnprc/trunk/spells/sp_alcspark.nss
Normal file
@@ -0,0 +1,214 @@
|
||||
//////////////////////////////////////////////////////
|
||||
// Alchemist's Spark
|
||||
// sp_alcspark.nss
|
||||
//////////////////////////////////////////////////////
|
||||
/*
|
||||
Alchemist<EFBFBD>s Spark: Alchemist<73>s spark combines two substances that react violently when mixed.
|
||||
A flask of alchemist<73>s spark has two compartments that keep the two substances separate;
|
||||
throwing the flask shatters it and allows the substances to mix, releasing a powerful electrical
|
||||
discharge. Otherwise, alchemical sparl functions like alchemist<73>s fire except that it deals 1d8
|
||||
points of electricity damage on a direct hit (and 1 point of electricity damage to those it splashes),
|
||||
rather than fire damage. It deals no additional damage after the initial damage.
|
||||
*/
|
||||
|
||||
#include "prc_inc_sp_tch"
|
||||
|
||||
//::///////////////////////////////////////////////
|
||||
//:: PRCDoGrenade
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Does a damage type grenade (direct or splash on miss)
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By:
|
||||
//:: Created On:
|
||||
//:://////////////////////////////////////////////
|
||||
void PRCDoGrenade(int nDirectDamage, int nSplashDamage, int vSmallHit, int vRingHit, int nDamageType, float fExplosionRadius , int nObjectFilter, int nRacialType=RACIAL_TYPE_ALL)
|
||||
{
|
||||
//Declare major variables ( fDist / (3.0f * log( fDist ) + 2.0f) )
|
||||
object oTarget = PRCGetSpellTargetObject();
|
||||
int nCasterLvl = PRCGetCasterLevel(OBJECT_SELF);
|
||||
int nDamage = 0;
|
||||
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||
int nCnt;
|
||||
effect eMissile;
|
||||
effect eVis = EffectVisualEffect(vSmallHit);
|
||||
location lTarget = PRCGetSpellTargetLocation();
|
||||
|
||||
|
||||
float fDist = GetDistanceBetween(OBJECT_SELF, oTarget);
|
||||
int nTouch;
|
||||
|
||||
|
||||
if (GetIsObjectValid(oTarget) == TRUE)
|
||||
{
|
||||
/* // * BK September 27 2002
|
||||
// * if the object is 'far' from the original impact it
|
||||
// * will be an automatic miss too
|
||||
location lObject = GetLocation(oTarget);
|
||||
float fDistance = GetDistanceBetweenLocations(lTarget, lObject);
|
||||
// SpawnScriptDebugger();
|
||||
if (fDistance > 1.0)
|
||||
{
|
||||
nTouch = -1;
|
||||
}
|
||||
else
|
||||
This did not work. The location and object location are the same.
|
||||
For now we'll have to live with the possiblity of the 'explosion'
|
||||
happening away from where the grenade hits.
|
||||
We could convert everything to splash...
|
||||
*/
|
||||
nTouch = PRCDoRangedTouchAttack(oTarget);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
nTouch = -1; // * this means that target was the ground, so the user
|
||||
// * intended to splash
|
||||
}
|
||||
if (nTouch >= 1)
|
||||
{
|
||||
//Roll damage
|
||||
int nDam = nDirectDamage;
|
||||
|
||||
if(nTouch == 2)
|
||||
{
|
||||
nDam *= 2;
|
||||
}
|
||||
|
||||
//Set damage effect
|
||||
effect eDam = EffectDamage(nDam, nDamageType);
|
||||
//Apply the MIRV and damage effect
|
||||
|
||||
// * only damage enemies
|
||||
if(spellsIsTarget(oTarget,SPELL_TARGET_STANDARDHOSTILE,OBJECT_SELF) )
|
||||
{
|
||||
// * must be the correct racial type (only used with Holy Water)
|
||||
if ((nRacialType != RACIAL_TYPE_ALL) && (nRacialType == MyPRCGetRacialType(oTarget)))
|
||||
{
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget);
|
||||
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, PRCGetSpellId()));
|
||||
//ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oTarget); VISUALS outrace the grenade, looks bad
|
||||
}
|
||||
else
|
||||
if ((nRacialType == RACIAL_TYPE_ALL) )
|
||||
{
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget);
|
||||
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, PRCGetSpellId()));
|
||||
//ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oTarget); VISUALS outrace the grenade, looks bad
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ApplyEffectToObject(DURATION_TYPE_INSTANT, eMissile, oTarget);
|
||||
}
|
||||
|
||||
// *
|
||||
// * Splash damage always happens as well now
|
||||
// *
|
||||
{
|
||||
effect eExplode = EffectVisualEffect(vRingHit);
|
||||
//Apply the fireball explosion at the location captured above.
|
||||
|
||||
/* float fFace = GetFacingFromLocation(lTarget);
|
||||
vector vPos = GetPositionFromLocation(lTarget);
|
||||
object oArea = GetAreaFromLocation(lTarget);
|
||||
vPos.x = vPos.x - 1.0;
|
||||
vPos.y = vPos.y - 1.0;
|
||||
lTarget = Location(oArea, vPos, fFace);
|
||||
missing code looks bad because it does not jive with visual
|
||||
*/
|
||||
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eExplode, lTarget);
|
||||
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, fExplosionRadius, lTarget, TRUE, nObjectFilter);
|
||||
//Cycle through the targets within the spell shape until an invalid object is captured.
|
||||
while (GetIsObjectValid(oTarget))
|
||||
{
|
||||
if(spellsIsTarget(oTarget,SPELL_TARGET_STANDARDHOSTILE,OBJECT_SELF) )
|
||||
{
|
||||
float fDelay = GetDistanceBetweenLocations(lTarget, GetLocation(oTarget))/20;
|
||||
//Roll damage for each target
|
||||
nDamage = nSplashDamage;
|
||||
|
||||
//Set the damage effect
|
||||
effect eDam = EffectDamage(nDamage, nDamageType);
|
||||
if(nDamage > 0)
|
||||
{
|
||||
// * must be the correct racial type (only used with Holy Water)
|
||||
if ((nRacialType != RACIAL_TYPE_ALL) && (nRacialType == MyPRCGetRacialType(oTarget)))
|
||||
{
|
||||
// Apply effects to the currently selected target.
|
||||
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, PRCGetSpellId()));
|
||||
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
|
||||
//This visual effect is applied to the target object not the location as above. This visual effect
|
||||
//represents the flame that erupts on the target not on the ground.
|
||||
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
||||
}
|
||||
else
|
||||
if ((nRacialType == RACIAL_TYPE_ALL) )
|
||||
{
|
||||
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, PRCGetSpellId()));
|
||||
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
|
||||
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
//Select the next target within the spell shape.
|
||||
oTarget = GetNextObjectInShape(SHAPE_SPHERE, fExplosionRadius, lTarget, TRUE, nObjectFilter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AddSparkEffectToWeapon(object oTarget, float fDuration)
|
||||
{
|
||||
// If the spell is cast again, any previous itemproperties matching are removed.
|
||||
IPSafeAddItemProperty(oTarget, ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ELECTRICAL, IP_CONST_DAMAGEBONUS_1d8), fDuration, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
|
||||
IPSafeAddItemProperty(oTarget, ItemPropertyVisualEffect(ITEM_VISUAL_ELECTRICAL), fDuration,X2_IP_ADDPROP_POLICY_REPLACE_EXISTING,FALSE,TRUE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
effect eVis = EffectVisualEffect(VFX_IMP_PULSE_COLD);
|
||||
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
|
||||
object oTarget = PRCGetSpellTargetObject();
|
||||
object oMyWeapon;
|
||||
int nTarget = GetObjectType(oTarget);
|
||||
int nDuration = 4;
|
||||
int nCasterLvl = 1;
|
||||
|
||||
if(nTarget == OBJECT_TYPE_ITEM)
|
||||
{
|
||||
oMyWeapon = oTarget;
|
||||
int nItem = IPGetIsMeleeWeapon(oMyWeapon);
|
||||
if(nItem == TRUE)
|
||||
{
|
||||
if(GetIsObjectValid(oMyWeapon))
|
||||
{
|
||||
SignalEvent(OBJECT_SELF, EventSpellCastAt(OBJECT_SELF, GetSpellId(), FALSE));
|
||||
|
||||
if (nDuration > 0)
|
||||
{// haaaack: store caster level on item for the on hit spell to work properly
|
||||
|
||||
SetLocalInt(oMyWeapon,"X2_SPELL_CLEVEL_FLAMING_WEAPON",nCasterLvl);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, GetItemPossessor(oMyWeapon));
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDur, GetItemPossessor(oMyWeapon), RoundsToSeconds(nDuration));
|
||||
AddSparkEffectToWeapon(oMyWeapon, RoundsToSeconds(nDuration));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FloatingTextStrRefOnCreature(100944,OBJECT_SELF);
|
||||
}
|
||||
|
||||
}
|
||||
else if(nTarget == OBJECT_TYPE_CREATURE || OBJECT_TYPE_DOOR || OBJECT_TYPE_PLACEABLE)
|
||||
{
|
||||
PRCDoGrenade(d8(1),1, VFX_IMP_LIGHTNING_S, VFX_IMP_LIGHTNING_M, DAMAGE_TYPE_ELECTRICAL ,RADIUS_SIZE_HUGE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user