Aller au contenu

Photo

How do I loop through objects by type?


  • Veuillez vous connecter pour répondre
8 réponses à ce sujet

#1
Mistraven

Mistraven
  • Members
  • 14 messages

I have been playing around some more with the toolset and got stuck on an issue where I need to reset all the triggers in an area when I exit the area. I know it is possible to loop through all objects by using something like this:
 

object oObject = GetFirstObjectInArea();
while(GetIsObjectValid(oObject)) {
   // do stuff here
   oObject = GetNextObjectInArea();
}

This works, and it was the only solution I was able to come up with after searching the forums.

 

The problem with this is that it loops through every single object in the area which seems inefficient to me, so I'm wondering if it is possible to do a similar simple loop while limiting the scope by object type. Only looping through triggers (or any other object type) would make the script much more efficient in large areas.

 

Thanks in advance for helping out a newbie like me! :)



#2
rjshae

rjshae
  • Members
  • 4 478 messages

What I'd suggest is looping through them once when you set up the area, then storing them on the area as object variables with a particular prefix. Thereafter you only need to cycle through that list of objects.



#3
kevL

kevL
  • Members
  • 4 052 messages
i believe you have to use that loop, which is actually very fast, but then limit the scope inside:

object oObject = GetFirstObjectInArea();
while (GetIsObjectValid(oObject))
{
    if (GetObjectType(oObject) == OBJECT_TYPE_TRIGGER)
    {
        // do stuff here
    }
    oObject = GetNextObjectInArea();
}

note there's also the functions GetFirst/NextSubArea() but that requires a specific position, and looks like it should be used only for triggers layered on top of one another.

#4
Mistraven

Mistraven
  • Members
  • 14 messages

Thanks for your input and for trying to help me out! I didn't really understand how I can assign and loop through object variables stored in the area? I can see how that can be useful in some situations, but have no idea how it would be implemented.

 

I actually found another solution that worked very well, although it took me about an hour of testing just to make sure it worked on all my triggers. Here it is if anyone is curious about it in the future.

//loop all triggers by tag and delete local variables

int nTarget = 1; //set nTarget to the nearest object matching the scope
object oTrigger = GetObjectByTagAndType("trigger_tag", OBJECT_TYPE_TRIGGER, nTarget);

while(GetIsObjectValid(oTrigger)) {
   DeleteLocalInt(oTrigger, "int_to_delete");
   oTrigger = GetObjectByTagAndType("trigger_tag", OBJECT_TYPE_TRIGGER, nTarget++);
}

This works simply by looking for the closest trigger with a specific tag, then by increasing nTarget I move on the the second, third and fourth closest trigger until there are no remaining valid objects within the scope in the area. Obviously my code was a fair bit longer due to a quite complex area, so I cleaned it up a bit to make it easy to read.

 

This solution should ignore all objects outside the defined scope. (I think :) )



#5
kevL

kevL
  • Members
  • 4 052 messages
object variables ( SetLocalObject() ) can be.. tricky. I've seen them disappear after module transitions.

anyway your method looks good :)

#6
Mistraven

Mistraven
  • Members
  • 14 messages

Yes I read something about local variables disappearing as well, I believe any local variable is considered specific to the module,so they would not transfer to the next another module if played in single player. I think the variables are stripped to reduce overhead on the server, however local variables on items that are stored in a contained will retain their local variables due to a bug.

 

In multiplayer all local variables on items in a players inventory will be saved if the server uses a server vault, I think this is to support multiple gaming sessions between server resets.



#7
rjshae

rjshae
  • Members
  • 4 478 messages

object variables ( SetLocalObject() ) can be.. tricky. I've seen them disappear after module transitions.

 

Yeah, I guess that would be a problem. I have used the stored object technique for handling street lights in an exterior town area.



#8
kevL

kevL
  • Members
  • 4 052 messages

Yes I read something about local variables disappearing as well, I believe any local variable is considered specific to the module,


i think that was NwN1, and it changed in NwN2. Locals are pretty good - really good - it was just one case that i noticed local_objects disappear. Iirc, they were stored on PC and when PC transitioned modules or reloaded ~poof~

so, yeah Rj, if they were kept in a single area, or refreshed with an onEnter event, they ought work.

it's usually pretty obvious and easy to test if they don't ofc.

#9
Mistraven

Mistraven
  • Members
  • 14 messages

Yeah, well, I don't think I will have any problems with this area, I'm assigning variables to triggers as the player walks through the area, then when I enter a portal at the end of a long winding road I'm looping through the triggers to clear the variables connected to that player, so that the next time the player goes there, it will be a fresh start. There is only need to store the variables during the time the player is in the area which is about 3-10 minutes at a time, and no need to store information over server resets etc.

 

I also assigned each variable a name derived from the player id and a random number, this way the triggers will fire only once for each player, and it will fire even if there are more than one player in the area.