Nwn script for object to cast spell

Could someone help me to get an object (placeable) to fire greater missile storm? I’m sure it is a simple script but I am no scripter.

It would be cool to put this on a pillar that has that effect of eyes floating around the top of the pillar. Call the pillar “sentry”. If you know what I mean.

Help anyone?

Thanks

Sure. Do you know under which circumstances you want the placeable to fire?

The function for this is ActionCastSpellAtObject, or it’s counterpart ActionCastSpellAtLocation, depending on which you want. Which function you need to use to get the right target depends on the event that is triggering the attack.

    object oPlaceable = !!!DEFINE WHICH OBJECT IS THE PLACEABLE!!;
    object oTarget    = !!!DEFINE WHICH OBJECT IS THE TARGET!!!;

    AssignCommand(oPlaceable, ActionCastSpellAtObject(SPELL_ISAACS_GREATER_MISSILE_STORM, oTarget, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE));

You can apply visual effects with ApplyEffectToObject. VFX_DUR_PROT_PREMONITION has floating eyes, I think. :thinking: There are pages for the VFX constants on the Lexicon; see VFX_DUR here.

    ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_DUR_PROT_PREMONITION), oPlaceable);

The way to define who oPlaceable and oTarget are will vary depending on the event that is triggering the attack. As an example, you could set it up in the heartbeat event, and target living creatures that get close to the pillar, while aborting the script at the start if there are no players in the area.

1 Like

Hey thanks for the reply : :grinning:

The placeable is the Pillar placeable (the object)

The target is any PC or NPC that walks into set trigger? or area.

Everything you said sounds good…lol…only thing is how do you script it? Not a scripter here. Yes that visual effect sounds perfect floating above the pillar.

And yes on heartbeat would be perfect for any PCs coming into view.

I think Greater Missile Storm can be cast at a location, spreading out at targets within the impact zone. :thinking: If the sentry pillars are only meant to be active while somebody is within a floor trigger, then a recursive loop that registers entering objects and deactivates itself when all registered objects either left the trigger or died, and keeps casting on repeat at the location of the trigger itself, might do the trick, too.

OK, scripting time. :smiley:

At the very most basic form, you’d create a new script in the OnEnter event of the trigger, find the right objects for the target and the sentry pillar placeable, and then order the sentry pillar to fire a volley at the target. Like this:

void main()
{
    object oEnter  = GetEnteringObject();
    object oPillar = GetNearestObjectByTag("SENTRY_PILLAR");

    AssignCommand(oPillar, ActionCastSpellAtObject(SPELL_ISAACS_GREATER_MISSILE_STORM, oEnter, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE));
    ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_MAGICAL_VISION), GetLocation(oPillar));

}

Edited for VFX.

This will only result in a single volley, when the target first enters the trigger, however. That’s where the heartbeat or recursive loop fun comes in.

:thinking: Is this supposed to work with a single sentry pillar per trigger, or should floor triggers evoke a response from all sentry pillars that are within a defined range to the trigger?

1 Like

Cool thanks man…going to try this out now. Is there the eye visual effect on this too…it doesn’t seem to be one…just wondering.

Thanks again :slight_smile:

The VFX is not included in this example, no. :smiley: Hold up, I’ll change it to a variant with a location-based impact one, so you can see the VFX happen.

1 Like

Hmm doesn’t seem to work. The visual effect works just for a few seconds (doesn’ stay on) and no missiles fire from the pillar. The Visual effect also appeared at the bottom of the pillar not at the top of the pillar too. Edit: I also put it on the ONENTER script of the trigger.

So I set the tag of the trigger to : SENTRY_PILLAR
I also set the tag of the Pillar to : SENTRY_PILLAR

Am I doing something wrong?

Maybe try it out on your module …see if it works for you.

I want to thank you for trying…thanks “TheBarbarian”

I will tinker around some more tomorrow with it…maybe do a rebuild too of my module…might help.

Let me know if it works for you. It is almost 1am here. I’m off to bed. I will check back here tomorrow. Let me know if it worked for you.

1 Like

It’s working for me. :thinking:

image
image

@ The VFX appearing at the bottom of the pillar - yes; that’s currently being applied instantly, at the location of the pillar, and using an impact VFX rather than a duration-based one. :slight_smile: It’s for showing you how to work with this stuff, so you’ll become able to adjust scripts as you like, in the long run.

You can apply VFX either to objects (ApplyEffectToObject), or at locations (ApplyEffectAtLocation). If the impact VFX is showing up at the location of the correct pillar, then that would suggest that the pillar is at least being “found”; the script is finding the right object.

I’d recommend not having the tag of the trigger be SENTRY_PILLAR, if the sentry pillar scripts work by identifying pillars (volley sources) via their tag, or under circumstances the trigger itself might fire missile volleys. :thinking: If it can. I’ve never actually tried to make a floor trigger cast spells.

Here, try this variant:

void main()
{
    object oEnter  = GetEnteringObject();
    object oPillar = GetNearestObjectByTag("SENTRY_PILLAR");

    // Assigning commands to speak strings:
    AssignCommand(oEnter,  SpeakString("I am oEnter."));
    AssignCommand(oPillar, SpeakString("I am oPillar."));

    // Assigning a command to cast a spell:
    AssignCommand(oPillar, ActionCastSpellAtObject(SPELL_ISAACS_GREATER_MISSILE_STORM, oEnter, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE));

    // Applying an effect at a location, instantly:
    ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_MAGICAL_VISION), GetLocation(oPillar));

    // Applying an effect to an object, temporarily:
    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_PROT_PREMONITION), oPillar, 5.0);
}
2 Likes

I honestly do not know what I am doing wrong. The script fires off. The Visual effects work as do the speaking strings, but still no Issacs Greater Missile storm firing out at the PC.

Sigh…

I even took away the trap (Trigger) and just set up the script on the on heartbeat event. Everything works but no missile storm…sigh.

Maybe I’m just retarded…lol…

You took out the trigger so what are you using as the target of the spell? In Barbarians code it’s using the entering object. The spell won’t do anything without a valid target.

1 Like

Also, if the script is triggering within a heartbeat event on the pillar placeable now, then IIRC GetNearestObjectByTag shouldn’t recognize the pillar itself either. :thinking: That’s odd.

Did you copypaste the script, or did you try to write it anew and might have accidentally modified it, @Imtherealthing? If it’s modified, you can post your version without an ounce of shame, or take screenshots of your placeable setup so we can take a look at it, too. We do not make fun of newbie mistakes here; we’ve all been there, and we’ve been doing this for years and we still muck stuff up all the time even so. :slight_smile: It’s just about the most normal thing in the history of normal things.

Put code into brackets in your posts, like this, to keep the formatting:

[code]
Insert the code here.
[/code]

Info: You can define an object variable as OBJECT_SELF to stand for the caller (think the source of the script; the thing that is causing it to run) of the script. Who the caller is can vary from script to script. In a placeable heartbeat event, it’s the placeable whose heartbeat it is.

Defining an object variable for OBJECT_SELF is not usually necessary; you can use OBJECT_SELF directly in most cases. I’ll leave it in here, though. Copypaste this one into the placeable heartbeat event script, and give it a try:

void main()
{
    // The placeable whose heartbeat event is ticking.
    object oPillar = OBJECT_SELF;

    // Find the nearest living player to oPillar.
    object oTarget = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oPillar, 1, CREATURE_TYPE_IS_ALIVE, TRUE);

    // Abort the script at this point if the nearest living PC is nonexistent or too far away.
    if (oTarget == OBJECT_INVALID || GetDistanceBetween(oPillar, oTarget) > 15.0)
        return;

    // Assigning commands to speak strings:
    AssignCommand(oTarget, SpeakString("I am oTarget."));
    AssignCommand(oPillar, SpeakString("I am oPillar."));

    // Assigning a command to cast a spell:
    AssignCommand(oPillar, ActionCastSpellAtObject(SPELL_ISAACS_GREATER_MISSILE_STORM, oTarget, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE));

    // Applying an effect at a location, instantly:
    ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_MAGICAL_VISION), GetLocation(oPillar));

    // Applying an effect to an object, temporarily:
    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_PROT_PREMONITION), oPillar, 5.0);
}
2 Likes

Sorry I was away for a bit. I copied exactly what you posted above. No change…just copy and pasted it into my on heartbeat event of the pillar. Same thing…the visual works and speak strings work…but no greater missiles fire…what the hell am I doing wrong? Crap…I have a good working module…lots of scripts I have copied and pasted from the vault over the years and used and they work…but for some reason this is not working.

That is really weird. :open_mouth: Could you give it a try with a newly-created module? No haks, no other scripts. Maybe it’s conflicting with something.

Ok…will do

[EDIT]…so to make sure…

Just using this script on the pillar on heartbeat event and no trigger should work right?

1 Like

Yes. The placeable also needs to be non-static, mind.

Yes I know…it is non-static

It’s not working in a fresh module, either, then? :open_mouth:

Do you happen to have anything in your Override folder at the moment, or do you have any patch haks installed? :thinking: That’d be my next best guess - default spell script overrides could interfere with this stuff, too.

Yes I’m thinking the same thing.

Just to clarify too…is the tag on the pillar still : SENTRY_PILLAR?

Because looking through your script I do not see the reference to this tag…but I think that was only because before we used a trigger that this mattered correct?

Maybe lets try using the minor missile spell

2 Likes

Going to dig around in my override folder

1 Like