Waypoint Script
TheTinman
Member Posts: 74
How to make a script only fire on waypoints in a certain area only.
0
Comments
Waypoints don't have events, so they don't fire scripts.
Some things you can do:
Could the PC, the script, and the spawned rat each be firing this script somehow?
Edit: the above will also work on a trigger's onEnter event.
Probably the reason why you're spawning multiple rats is because every time a rat is spawned, that counts as something "entering" the area and re-triggers the script to spawn another rat which then re-triggers the script and so on, although I'm unsure why it doesn't just keep triggering until the game crashes. Maybe there's a safety feature built into the game to prevent that, similar to the Too Many Instructions error.
If I'm correct, then doing what Meaglyn suggested will fix the problem as it will abort the script if the entering object isn't a PC.
I have added a one second delay before the rat creation actually fires. This is because it might be that the reason for multiple rats being created is that the PC hasn't fully entered the area when your code runs. In order to do this it was necessary to create a separate void function. That is because the DelayCommand() function needs a function to call, that returns a void.
Also, I noticed that your code was stepping through all the objects in an area, testing each to see if they had the right tag. This seemed to me to be inefficient. I have used the GetNearestObjectByTag() function. This does have one drawback though, in that it will return objects with the required tag even those not in the area the PC just entered. In order to stop this I have included a test in the while loop that exits the loop once the returned object is in another area.
FWIW, there is a more efficient way to do this but it requires a bit more work on your end. Instead of giving all waypoints the exact same tag, you would need to enumerate them. So instead of them all having the tag "junk1" you would instead have only one with that exact tag. So for three waypoints with tags of "junk1", "junk2" and "junk3" respectively. That would allow you to use the following function instead of the one I posted above -
Hope this is useful.
TR
TheTinman: did you add the check for it being a PC? And is this on the area enter event?
My error. According to the lexicon it's GetObjectByTag() that will search in other areas.
TR
An interesting (maybe?) note about that is that the difference between those two is essentially how cross area waypoint walking is implemented.
@TheTinman Does it still create 3 instead of a single rat and did you try any of the code I posted?
FWIW here is the code without the area check -
TR
Line 4 caused an error parsing variable list code
Still haven't tested it though.
TR
Also, if it looked at the current area first people would not hit the issues they do of getting the wrong object with a non-unique tag when they should be using GetNearest.
More recently created objects will be towards the front so those objects in the most recently added area would tend to be returned earlier.
Someone from Beamdog with access to the source code could tell us for sure though...
@Thetinman: There is an extra closing paren, ")", on that line. Remove one and try again.
void main()
{
/ The PC.
object oPC;
// Only fire once per PC.
if ( GetLocalInt(OBJECT_SELF, "DO_ONCE__" + ObjectToString(oPC)) )
return;
SetLocalInt(OBJECT_SELF, "DO_ONCE__" + ObjectToString(oPC), TRUE);
object oSP = GetFirstObjectInArea();
while(GetIsObjectValid(oSP))
{
if(GetObjectType(oSP) == OBJECT_TYPE_WAYPOINT
&& GetTag(oSP) == "junk1")
{
DelayCommand(0.1, CreatVoid( CreateObject(OBJECT_TYPE_CREATURE, "nw_rat001", GetLocation(oSP), FALSE)));
}
oSP = GetNextObjectInArea();
}
}
How about this way?
This part really wants to be
Then I'd go with GetNearestObjectByTag(oPC, OBJECT_TYPE_WAYPOINT, "junk1") to find them the waypoint. If there are multiple you can still use a loop on the nth argument (after the tag).
There should be no reason to delay the creation unless you want to. Area onEnter should not fire until the PC is actually in the area (unlike oncliententer where the PC may not be in a area when it fires).
You have the wrong parameter list there. I think you have mixed up the GetNearestObjectByTag() with GetNearestObject() here. From the lexicon -
vs.
TR
It shouldn't compile or run because you're defining variables within a loop, and in C you can only define a variable once. While it's possible that NWN scripting has "loosened" that up a bit, whenever I've tried it, it's cause an error.
Also, in these lines: You are getting an object's name and then comparing that name to the name of the same object, so "GetTag(oSP)==tNAME" will always return TRUE. All you're doing is applying the CreatVoid function to ALL waypoints in the area, not to only "spawn" waypoints.
To make it work correctly, you should be setting tNAME equal to the tag which you use for all of the spawn waypoints, before entering the loop.
As for the second part (waypoints always being selected), what's happening is that the script is attempting to create an enemy for all waypoints in the area, but because it depends on the waypoint name to find the ResRef of the enemy, it's attempting to create something which isn't in the blueprints for all waypoints which are not monster-creation waypoints. This is fragile because if you happen to accidentally name a waypoint the same as a creature ResRef which you've created, the creature will be created at that waypoint even when you didn't intend it to.
It also wastes time while your script attempts to create a non-existent creature blueprint for each waypoint which is not a monster-creation waypoint.
But then again... perhaps I'm just a perfectionist. I do tend that way with my scripting.
The summary is that the mistakes might not matter for this script since it works, but it's useful to follow good scripting habits because sooner or later, a bad habit could cause problems when it does matter.