Howdy, Stranger!

It looks like you're new here. Sign in or register to get started.


Dark Dreams of Furiae - a new module for NWN:EE! Buy now
Attention, new and old users! Please read the new rules of conduct for the forums, and we hope you enjoy your stay!

Multiple object creation / variable reassignment inside a loop

AornarAornar Member Posts: 4
Cannot get this to work for the life of me. I have a number of waypoints which all use the same tag. The idea is upon using a lever, the script cycles through these waypoints by getting each one (its location), spawning an object at that location then deleting the original waypoint. On the next iteration of the loop, it should find the -next- waypoint with that ID, repeating the process until all the waypoints have been deleted and the objects have spawned.

I currently have the following snippet:

object wp;
location loc;
int i;

for (i = 0; i < 10; i++){

wp = GetWaypointByTag("wp_flamesappear");
loc = GetLocation(wp);
//wp = GetWaypointByTag("nonsense_ref");
CreateObjectVoid(OBJECT_TYPE_PLACEABLE, "some_template", loc);


Unfortunately, the original declaration wp=GetWaypointByTag seems to cache the first waypoint object, even when it is later deleted. I have tried manually unassigning the pointer, but this doesn't seem to work. Triggering the OnUsed of the controlling object (lever, in this case) DOES retrieve the new object, but this means that I have to click the lever separately for each instance of wp_flamesappear I have.

Has anyone come across this issue before? Is there a workaround or am I missing some vital part?



  • AornarAornar Member Posts: 4
    Managed to resolve this straight after I posted - will keep this up incase anyone has encountered the same issue.

    Adding a SetTag function on the object now allows the loop to cycle through all the objects correctly.


  • SmithicusSmithicus Member Posts: 13
    Maybe just FLAG the wp as used and break from the loop when one is found / selected the next unused wp?
        object wp;
        location loc;
        int i;
        for (i = 1; i < 10; i++)
            wp = GetObjectByTag("wp_flamesappear", i);
            if(GetLocalInt(wp, "used")){}
                loc = GetLocation(wp);
                // Flag WP as used
                SetLocalInt(wp, "used", TRUE);
            // DestroyObject(wp);
            //wp = GetWaypointByTag("nonsense_ref");
            CreateObject(OBJECT_TYPE_PLACEABLE, "some_template", loc);

    Have not tested the script, but seems logical.

  • AncarionAncarion Member Posts: 155
    edited May 2020
    Often this kind of thing can be done using GetNearestObjectByTag(), in a script run by some indestructible (but NOT static) control object in the area.

    For example, if you want this function run when a PC enters an area, you could make an OnEnter script for the area that checks if the entering object is a player, and in that script SignalEvent(EventUserDefined(object oControlObject, int nEventNumber)).

    Then the control object's UserDefined event script would run the object creation function that you want to implement.

    Having seen that you want this effect achieved by using a lever, then it's even easier than I described. If your code snippet is in the lever's OnUse event, just change it to:
    int nCount=1;
    object oWP=GetNearestObjectByTag(sTag,OBJECT_SELF,nCount);
    string sTag="wp_flamesappear";
    while (GetIsObjectValid(oWP))
      DestroyObject(oWP); //Probably not really needed

  • WilliamDracoWilliamDraco Member Posts: 156
    To clarify here why OP's first script wouldn't work - DestroyObject() just schedules an object for deletion after the script is finished running. It doesn't instantaneously do so.

    Therefore, on the second and every subsequent run through the for loop, the first item still exists and is still valid to be found.

  • AncarionAncarion Member Posts: 155
    Actually, I'd just give each waypoint its own tag and eliminate all the unnecessary complexity. But everyone has his own style, so...

  • meaglynmeaglyn Member Posts: 97
    SetTag seems like a perfectly fine and non-complicated way to solve this.

Sign In or Register to comment.