Posted February 10, 2017
I am scripting a spell that performs ranged touch attacks to a set number of opponents much like how chain lightning targets a number of opponents. There is only one problem, when it fires it is attacking the caster and not the opponents. Can someone take a look and offer some advise?
#include "x0_I0_SPELLS"
#include "x2_inc_spellhook"
const int SPELL_SPIRIT_LASH = 1647;
void main()
{
/*
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
//Declare major variables
object oCaster = OBJECT_SELF;
int nCasterLevel = GetLevelByClass(64, oCaster);
int nDamStrike;
effect eSpirit = EffectBeam(VFX_BEAM_MAGIC, oCaster, BODY_NODE_HAND);;
effect eVis = EffectVisualEffect(VFX_HIT_SPELL_MAGIC);
object oFirstTarget = GetSpellTargetObject();
object oHolder;
object oTarget;
location lSpellLocation;
int nDamMod = (nCasterLevel/2);
int nDamage = (d4(2))+(d4(nDamMod));
effect eDamage = EffectDamage(nDamage, DAMAGE_TYPE_MAGICAL);
//Damage the initial target
if (spellsIsTarget(oFirstTarget, SPELL_TARGET_SELECTIVEHOSTILE, OBJECT_SELF))
{
//Fire cast spell at event for the specified target
SignalEvent(oFirstTarget, EventSpellCastAt(OBJECT_SELF, 1647));
//Make an SR Check
int iTouch = TouchAttackRanged(oFirstTarget);
if (iTouch != TOUCH_ATTACK_RESULT_MISS && MyResistSpell(OBJECT_SELF, oFirstTarget) == FALSE)
{
if (nDamage > 0)
{
if (iTouch == TOUCH_ATTACK_RESULT_CRITICAL && !GetIsImmune(oFirstTarget, IMMUNITY_TYPE_CRITICAL_HIT))
{
nDamage *= 2;
}
ApplyEffectToObject(DURATION_TYPE_INSTANT,eDamage,oFirstTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oFirstTarget);
}
}
}
//Apply the beams stream effect to the first target, connecting it with the caster
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eSpirit,oFirstTarget,0.5);
//Reinitialize the beam effect so that it travels from the first target to the next target
eSpirit = EffectBeam(VFX_BEAM_MAGIC, oFirstTarget, BODY_NODE_CHEST);
float fDelay = 0.2;
int nCnt = 0;
int nWis = GetAbilityModifier(ABILITY_WISDOM, oCaster);
int nLevel = nCasterLevel/4;
int nMaxCnt = nWis + nLevel;
// *
// * Secondary Targets
// *
//Get the first target in the spell shape
oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, GetLocation(oFirstTarget), TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
while (GetIsObjectValid(oTarget) && nCnt < nMaxCnt)
{
//Make sure the caster's faction is not hit and the first target is not hit
if (oTarget != oTarget && spellsIsTarget(oTarget, SPELL_TARGET_SELECTIVEHOSTILE, OBJECT_SELF) && oTarget != OBJECT_SELF)
{
//Connect the new lightning stream to the older target and the new target
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eSpirit,oTarget,0.5));
//Fire cast spell at event for the specified target
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, 1647));
//Do an SR check
int iTouch = TouchAttackRanged(oTarget);
if (iTouch != TOUCH_ATTACK_RESULT_MISS && MyResistSpell(OBJECT_SELF, oTarget) == FALSE)
{
if (nDamage > 0)
{
if (iTouch == TOUCH_ATTACK_RESULT_CRITICAL && !GetIsImmune(oTarget, IMMUNITY_TYPE_CRITICAL_HIT))
{
nDamage *= 2;
}
ApplyEffectToObject(DURATION_TYPE_INSTANT,eDamage,oTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oTarget);
}
}
oHolder = oTarget;
//change the currect holder of the lightning stream to the current target
if (GetObjectType(oTarget) == OBJECT_TYPE_CREATURE)
{
eSpirit = EffectBeam(VFX_BEAM_MAGIC, oHolder, BODY_NODE_CHEST);
}
else
{
// * April 2003 trying to make sure beams originate correctly
effect eNewLash = EffectBeam(VFX_BEAM_MAGIC, oHolder, BODY_NODE_CHEST);
if(GetIsEffectValid(eNewLash))
{
eSpirit = eNewLash;
}
}
fDelay = fDelay + 0.1f;
//}
//Count the number of targets that have been hit.
if(GetObjectType(oTarget) == OBJECT_TYPE_CREATURE)
{
nCnt++;
}
} //FIX: Now only counts those that pass faction check
// Setting the new origin for the beam
// oFirstTarget = oTarget;
//Get the next target in the shape.
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, GetLocation(oFirstTarget), TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
}
}
Thank you in advance
#include "x0_I0_SPELLS"
#include "x2_inc_spellhook"
const int SPELL_SPIRIT_LASH = 1647;
void main()
{
/*
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
//Declare major variables
object oCaster = OBJECT_SELF;
int nCasterLevel = GetLevelByClass(64, oCaster);
int nDamStrike;
effect eSpirit = EffectBeam(VFX_BEAM_MAGIC, oCaster, BODY_NODE_HAND);;
effect eVis = EffectVisualEffect(VFX_HIT_SPELL_MAGIC);
object oFirstTarget = GetSpellTargetObject();
object oHolder;
object oTarget;
location lSpellLocation;
int nDamMod = (nCasterLevel/2);
int nDamage = (d4(2))+(d4(nDamMod));
effect eDamage = EffectDamage(nDamage, DAMAGE_TYPE_MAGICAL);
//Damage the initial target
if (spellsIsTarget(oFirstTarget, SPELL_TARGET_SELECTIVEHOSTILE, OBJECT_SELF))
{
//Fire cast spell at event for the specified target
SignalEvent(oFirstTarget, EventSpellCastAt(OBJECT_SELF, 1647));
//Make an SR Check
int iTouch = TouchAttackRanged(oFirstTarget);
if (iTouch != TOUCH_ATTACK_RESULT_MISS && MyResistSpell(OBJECT_SELF, oFirstTarget) == FALSE)
{
if (nDamage > 0)
{
if (iTouch == TOUCH_ATTACK_RESULT_CRITICAL && !GetIsImmune(oFirstTarget, IMMUNITY_TYPE_CRITICAL_HIT))
{
nDamage *= 2;
}
ApplyEffectToObject(DURATION_TYPE_INSTANT,eDamage,oFirstTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oFirstTarget);
}
}
}
//Apply the beams stream effect to the first target, connecting it with the caster
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eSpirit,oFirstTarget,0.5);
//Reinitialize the beam effect so that it travels from the first target to the next target
eSpirit = EffectBeam(VFX_BEAM_MAGIC, oFirstTarget, BODY_NODE_CHEST);
float fDelay = 0.2;
int nCnt = 0;
int nWis = GetAbilityModifier(ABILITY_WISDOM, oCaster);
int nLevel = nCasterLevel/4;
int nMaxCnt = nWis + nLevel;
// *
// * Secondary Targets
// *
//Get the first target in the spell shape
oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, GetLocation(oFirstTarget), TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
while (GetIsObjectValid(oTarget) && nCnt < nMaxCnt)
{
//Make sure the caster's faction is not hit and the first target is not hit
if (oTarget != oTarget && spellsIsTarget(oTarget, SPELL_TARGET_SELECTIVEHOSTILE, OBJECT_SELF) && oTarget != OBJECT_SELF)
{
//Connect the new lightning stream to the older target and the new target
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eSpirit,oTarget,0.5));
//Fire cast spell at event for the specified target
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, 1647));
//Do an SR check
int iTouch = TouchAttackRanged(oTarget);
if (iTouch != TOUCH_ATTACK_RESULT_MISS && MyResistSpell(OBJECT_SELF, oTarget) == FALSE)
{
if (nDamage > 0)
{
if (iTouch == TOUCH_ATTACK_RESULT_CRITICAL && !GetIsImmune(oTarget, IMMUNITY_TYPE_CRITICAL_HIT))
{
nDamage *= 2;
}
ApplyEffectToObject(DURATION_TYPE_INSTANT,eDamage,oTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oTarget);
}
}
oHolder = oTarget;
//change the currect holder of the lightning stream to the current target
if (GetObjectType(oTarget) == OBJECT_TYPE_CREATURE)
{
eSpirit = EffectBeam(VFX_BEAM_MAGIC, oHolder, BODY_NODE_CHEST);
}
else
{
// * April 2003 trying to make sure beams originate correctly
effect eNewLash = EffectBeam(VFX_BEAM_MAGIC, oHolder, BODY_NODE_CHEST);
if(GetIsEffectValid(eNewLash))
{
eSpirit = eNewLash;
}
}
fDelay = fDelay + 0.1f;
//}
//Count the number of targets that have been hit.
if(GetObjectType(oTarget) == OBJECT_TYPE_CREATURE)
{
nCnt++;
}
} //FIX: Now only counts those that pass faction check
// Setting the new origin for the beam
// oFirstTarget = oTarget;
//Get the next target in the shape.
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, GetLocation(oFirstTarget), TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
}
}
Thank you in advance