Script not moving to next target
#1
Posté 09 février 2012 - 05:23
object oTarget;
int nElf;
effect eVis = EffectVisualEffect(VFX_COM_SPECIAL_RED_WHITE);
oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, GetLocation(OBJECT_SELF));
while(GetIsObjectValid(oTarget))
{
nElf = GetRacialType (oTarget);
if(nElf == RACIAL_TYPE_ELF)
{
FloatingTextStringOnCreature ("Test",oTarget);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oTarget, 3.0);
}
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, GetLocation(OBJECT_SELF));
}
Where have I gone wrong? Should I be using something other than OBJECT_SELF to define the center of the sphere?
Thank you,
Kurziel
#2
Posté 09 février 2012 - 01:21
GetFirstObjectInArea() and GetNextObjectInArea()
That will let you know if you are using the function improperly or perhaps one of your arguments does not fit.
It also may help if you posted the entire script.
You also could try to change the location to GetLocation(GetLastCaster()); That should not be any different than OBJECT_SELF, but you could check.
I have also heard that there are sometimes problems with using OBJECT_SELF. Some of the more experienced scripters recommend that you define a variable object oSelf=OBJECT_SELF;
and use oSelf instead of OBJECT_SELF. You could try that.
Nothing serious popped out at me though.
#3
Posté 09 février 2012 - 01:22
#4
Posté 09 février 2012 - 02:11
#5
Posté 09 février 2012 - 02:33
That is the entire script for the spell at this point, I've only removed the commented out lines and the FloatingText lines I've been using for debugging.
I will try setting the center to a variable and not rely on OBJECT_SELF in the check itself. If that doesn't work I will try the GetFirstOjectInArea.
The GetLocation(OBJECT_SELF) does seem to be where I think it is, the caster of the spell. What seems to be happening is the GetFirstObjectInShape pulls the caster of the spell, that processes. Then the GetNextObjectInShape pulls the caster of the spell again, processes it again, then exits the loop.
I have tried adjusting the size of the radius. It hasn't made any difference, even while standing right next to other targets (valid and invalid targets). The other targets are never getting selected as oTarget, so they never get processed by the RacialType check.
I will do some testing to make sure GetRacialType is working the way I think it is. But, the truth is, the GetRacialType portion of the script is just a placeholder for what I will be using once I have the "checking everybody in range" portion of it working right.
--Kurziel
edit: The more I think about it, I bet what's happening is the OBJECT_SELF in the GetNextObject is referring to the object that was just checked, not the original caster of the spell. I'll let you guys know how it turns out after I get home this evening.
Modifié par Kurziel, 09 février 2012 - 02:48 .
#6
Posté 09 février 2012 - 04:55
Kurziel wrote...
Thank you for the suggestions,
That is the entire script for the spell at this point, I've only removed the commented out lines and the FloatingText lines I've been using for debugging.
I will try setting the center to a variable and not rely on OBJECT_SELF in the check itself. If that doesn't work I will try the GetFirstOjectInArea.
The GetLocation(OBJECT_SELF) does seem to be where I think it is, the caster of the spell. What seems to be happening is the GetFirstObjectInShape pulls the caster of the spell, that processes. Then the GetNextObjectInShape pulls the caster of the spell again, processes it again, then exits the loop.
I have tried adjusting the size of the radius. It hasn't made any difference, even while standing right next to other targets (valid and invalid targets). The other targets are never getting selected as oTarget, so they never get processed by the RacialType check.
I will do some testing to make sure GetRacialType is working the way I think it is. But, the truth is, the GetRacialType portion of the script is just a placeholder for what I will be using once I have the "checking everybody in range" portion of it working right.
--Kurziel
edit: The more I think about it, I bet what's happening is the OBJECT_SELF in the GetNextObject is referring to the object that was just checked, not the original caster of the spell. I'll let you guys know how it turns out after I get home this evening.
I think your edit comment is correct. Set lTarget to the location of the caster at the top of the script and use that rather than GetLocation(OBJECT_SELF) inside the loop.
If you want to see a working script I have one here from my Harvest of Chaos campaign:
// i_bb_it_bswd_chaotic_ac
// by Brendan Bellina
// May, 2010
// bb_it_bswd_chaotic OnActivate handler
// This script is executed automatically when the item is activated
// To trigger properly the name of the script MUST be "i_" + itemtag + "_ac"
// Also to make the item usable set Item Property to Cast Spell: Unique Power Self Only
// This will cause all goblinoids within a colossal radius to be charmed for 12 rounds.
// Note: this script runs on the module object, an important consideration for assigning actions.
#include "NW_I0_SPELLS"
#include "x2_inc_spellhook"
void main()
{
object oPC = GetItemActivator();
object oItem = GetItemActivated();
location lTarget = GetLocation(oPC);
object oTarget;
effect eCharm = EffectCharmed();
effect eMind = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_NEGATIVE);
// effect eImpact = EffectVisualEffect(VFX_FNF_LOS_NORMAL_20);
effect eMagExplosion = EffectNWN2SpecialEffectFile("fx_magical_explosion.sef");
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE);
effect eLink = EffectLinkEffects(eMind, eCharm);
eLink = EffectLinkEffects(eLink, eDur);
effect eVis = EffectVisualEffect(VFX_IMP_CHARM);
int nRacial;
float fDelay;
int nDuration = 8;
// ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpact, lTarget);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eMagExplosion, lTarget);
// Declare the spell shape, size and the location. Capture the first target object in the shape.
oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, lTarget);
while (GetIsObjectValid(oTarget))
{
if (GetIsEnemy(oTarget, oPC))
{
nRacial = GetRacialType(oTarget);
//Check that the target is a goblin
if (nRacial == RACIAL_TYPE_HUMANOID_GOBLINOID)
{
fDelay = GetDistanceBetweenLocations(lTarget, GetLocation(oTarget))/20;
//Fire cast spell at event for the specified target
SignalEvent(oTarget, EventSpellCastAt(oPC, SPELL_CHARM_PERSON, FALSE));
// NO SPELL RESISTANCE POSSIBLE - Make an SR check
//if (!MyResistSpell(oPC, oTarget))
//{
// NO WILL SAVE POSSIBLE - Make a Will save to negate
//if (!MySavingThrow(SAVING_THROW_WILL, oTarget, GetSpellSaveDC(), SAVING_THROW_TYPE_MIND_SPELLS))
//{
//Apply the linked effects and the VFX impact
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, RoundsToSeconds(nDuration)));
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
//}
//}
}
}
//Get next target in spell area
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, lTarget);
}
}
Regards
Modifié par Kaldor Silverwand, 09 février 2012 - 04:55 .
#7
Posté 10 février 2012 - 02:39
Something I realized, based off of my FloatingText debugging comments, it looks like nothing is getting processed through the script until it does the GetNextOjectInShape. Then it marks the caster as the next object, processes him, then drops out of the loop and the script.
I copied and pasted Kaldor's script in place of mine, and that did not function either.
This weekend I'm going to strip everything out of my override directory and retest to make sure I don't have something else causing changes in functionality. My override is mostly models and Racial changes, so I wouldn't think it should be affecting it.
Kurziel
#8
Posté 10 février 2012 - 07:45
So maybe your 'OBJECT_SELF', whatever that might be, is causing some problem under the hood, so to speak. Try testing it with a more standard object, and see if that works.
#9
Posté 11 février 2012 - 01:05
//////////////////////////////
#include "nwn2_inc_spells"
#include "X0_I0_SPELLS"
#include "x2_inc_spellhook"
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 nCasterLvl = GetCasterLevel(oCaster);
int nMaxLvl;
if ( nCasterLvl > 5 )
{
nMaxLvl = 5;
}
else
{
nMaxLvl = nCasterLvl;
}
int nDamage;
int nDamage2;
float fDelay;
effect eVis = EffectVisualEffect(VFX_HIT_SPELL_FIRE);
effect eDam,eDam2, eDam3;
//Get the spell target location as opposed to the spell target.
location lTarget = GetSpellTargetLocation();
//Apply the ice storm VFX at the location captured above.
//Declare the spell shape, size and the location. Capture the first target object in the shape.
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, lTarget, TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
//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) && oTarget != oCaster) //Additional target check to make sure that the caster cannot be harmed by this spell
{
fDelay = GetRandomDelay(0.15, 0.35);
//Fire cast spell at event for the specified target
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_FIREBURST));
if (!MyResistSpell(OBJECT_SELF, oTarget, fDelay))
{
nDamage = d8(nMaxLvl);
nDamage = ApplyMetamagicVariableMods(nDamage, nMaxLvl * 8);
nDamage = GetReflexAdjustedDamage(nDamage, oTarget, GetSpellSaveDC(), SAVING_THROW_TYPE_FIRE);
/*int nSave = ReflexSave(oTarget, GetSpellSaveDC(), SAVING_THROW_TYPE_FIRE, OBJECT_SELF);
if (nSave == 2)
{
return;
}
else if (nSave == 1)
{
nDamage = nDamage/2;
}
else
{
nDamage = nDamage;
}*/
if ( nDamage > 0 )
{
//Set the damage effect
eDam = EffectDamage(nDamage, DAMAGE_TYPE_FIRE);
// Apply effects to the currently selected target.
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 impact that erupts on the target not on the ground.
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
}
/*//Roll damage for each target
nDamage = d8(nMaxLvl);
//Resolve metamagic
nDamage = ApplyMetamagicVariableMods(nDamage, nMaxLvl * 8);
nDamage2 = nDamage;
nDamage2 = GetReflexAdjustedDamage(nDamage/2, oTarget, GetSpellSaveDC(), SAVING_THROW_TYPE_FIRE);
nDamage = nDamage/2 + nDamage2;
if ( nDamage > 0 )
{
//Set the damage effect
eDam = EffectDamage(nDamage, DAMAGE_TYPE_FIRE);
// Apply effects to the currently selected target.
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 impact that erupts on the target not on the ground.
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
} */
}
}
//Select the next target within the spell shape.
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, lTarget, TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
}
}
#10
Posté 12 février 2012 - 12:20
Well, I feel like a ****** now. While going over everything with a fine tooth comb, I found part of my problem. I completely spaced out that the FloatingTextStringOnCreature I was using as a debug aid, by default is only visible to the same faction.
So, my while loop, location definition, target choices, and use of GetFirst/NextObjectInShape is all working as intended. I just have to figure out why it's not applying the effect I want.
Thanks for the help and suggestions everybody offered.
--Kurziel
Modifié par Kurziel, 12 février 2012 - 12:22 .
#11
Posté 12 février 2012 - 01:18
#12
Posté 12 février 2012 - 04:05
Thank you very much.





Retour en haut






