Author Topic: GetIsInSubArea()  (Read 392 times)

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
GetIsInSubArea()
« on: March 19, 2014, 03:01:11 pm »


               

I recently ran some tests to see if the old lexicon description for GetIsInSubArea() was correct, and instead found it is misleading so I changed it.


 


I want to verify with others whether I have this correct:


It appears that a list is maintained for objects which have entered a trigger (or perhaps any enterable object), and that when they exit they are removed from the list. If this is true, then GetIsInSubArea simply checks to see if oCreature is still on the list for the given object.


 


If this is the case, then this function is indeed valuable, and I have plans for using it further.


 


 


I came to this conclusion after running some tests with triggers each containing onEnter and onExit scripts.


 


ENTER SCRIPT:





void main()
{
object oPC = GetEnteringObject();
 
string sLastArea = GetLocalString(oPC, "TEST_TRIGGER_LAST");
int bLast = GetIsInSubArea(oPC, GetObjectByTag(sLastArea));
SendMessageToPC(oPC, "ENTER("+GetTag(OBJECT_SELF)+") LAST("+sLastArea+") IN_LAST("+IntToString(bLast)+")");
}



EXIT SCRIPT:





void main()
{
object oPC = GetExitingObject();
 
string sLastArea = GetTag(OBJECT_SELF);
SetLocalString(oPC, "TEST_TRIGGER_LAST", sLastArea);
int bLast = GetIsInSubArea(oPC, OBJECT_SELF);
SendMessageToPC(oPC, "EXIT("+sLastArea+") IN_SUBAREA("+IntToString(bLast)+")");
}



               
               

               
            

Legacy_WhiZard

  • Hero Member
  • *****
  • Posts: 2149
  • Karma: +0/-0
GetIsInSubArea()
« Reply #1 on: March 19, 2014, 05:46:58 pm »


               

Looks good.  If you want confirmation, I ran a heartbeat script for a trap as follows:


 


void main()

{

SendMessageToPC(GetFirstPC(), "SUB "+ IntToString(GetIsInSubArea(GetFirstPC())));

}


 


It correctly identified whenever I was in the trap area (even when I was dead).  The trap was not set as one-shot so I could verify this a couple of times, inside and outside.


 


EDIT: Just to let you know the "old lexicon description" is really just the BioWare notes for the function.  BioWare notes are often wrong, and the lexicon doesn't always double check.  I think the default format is to keep the old description and then put in a "feature" template for the real behavior.



               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
GetIsInSubArea()
« Reply #2 on: March 19, 2014, 10:02:35 pm »


               

I don't think those notes were wrong, but rather misleading. I think what the note meant was what I spelled out more clearly: that the function does not check collision or intersection or location, but rather checks a list that is added to with OnEnter events.


 


Assuming that there is a list of objects, it would be nice to be able to iterate through it which should be possible with NWNX.


 


Confirmation of the existence of lists of creatures inside each trigger would be nice. As to the behavior in game, I think between use we've got that sorted.


 


Further investigation could be pursued to determine if this function works on areas and other enterable objects.


               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
GetIsInSubArea()
« Reply #3 on: March 20, 2014, 01:47:03 am »


               

Ah... feeling like an idiot to have made the above comments because there is a pair of functions for cycling through the list of objects that are "in" an object like a trigger or AOE:


 


GetFirstInPersistentObject()


GetNextInPersistentObject()



               
               

               
            

Legacy_Dagesh

  • Jr. Member
  • **
  • Posts: 55
  • Karma: +0/-0
GetIsInSubArea()
« Reply #4 on: March 20, 2014, 02:30:26 pm »


               


Ah... feeling like an idiot to have made the above comments because there is a pair of functions for cycling through the list of objects that are "in" an object like a trigger or AOE:


 


GetFirstInPersistentObject()


GetNextInPersistentObject()




 


Those are the ones I use.  They work perfectly.


               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
GetIsInSubArea()
« Reply #5 on: March 20, 2014, 10:22:33 pm »


               I really do not know if there is a list or not. I will take a look though whenever I get a few straight hours free.
               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
GetIsInSubArea()
« Reply #6 on: September 28, 2014, 04:11:05 pm »


               

I had a free day yesterday. First one I have had in months, and so... I spent sometime tinkering with NWN again. One thing I tried was to generate a random location inside a trigger, and I failed. Here's my function:



location GetRandomLocationInSubArea(object oSubArea, object oOrigin, float fMaxDistance)
{
    object oArea    = GetArea(oSubArea);
    if(DEBUG)
        SendMessageToPC(GetFirstPC(),"oSubArea("+GetName(oSubArea)+") oOrigin("+GetName(oOrigin)+") fDist("+FloatToString(fMaxDistance)+")");
    location lRandomLocation;
    int nIt;
    object oTemp;
    while(nIt<=5)
    {
        lRandomLocation = GetRandomLocation(oArea,oOrigin,fMaxDistance);
        oTemp    = CreateObject(OBJECT_TYPE_CREATURE,"invisible",lRandomLocation);
        if(GetIsInSubArea(oTemp,oSubArea))
        {
            if(DEBUG)
                SendMessageToPC(GetFirstPC(),"Successful Random Location in SubArea oTemp("+ObjectToString(oTemp)+")");
            DestroyObject(oTemp,0.1);
            break;
        }
        else
        {
            if(DEBUG)
                SendMessageToPC(GetFirstPC(),"Unsuccessful Random Location in SubArea oTemp("+ObjectToString(oTemp)+")");
            DestroyObject(oTemp,0.1);

        }
       ++nIt;
    }


    return lRandomLocation;
}

Some context: the trigger did not have any scripts in its events. the creature being created has no AI scripts.


 


My guess is you can't test whether a creature is in a subarea immediately after it is created, but since my time is short these days I didn't create tests to figure out the limitations.


 


What I was doing was creating farmers who work a field at random after completing predetermined tasks in the field. Rather than select random points for them inside the field, I decided to have them head back to the field once they wandered out of it.