logo logo

 Back to main page

The NWNX Community Forum

 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
 
Referencing objects

 
Post new topic   Reply to topic    nwnx.org Forum Index -> Database related
View previous topic :: View next topic  
Author Message
Ne0nx3r0



Joined: 29 Nov 2006
Posts: 36

PostPosted: Fri Feb 13, 2009 1:53    Post subject: Referencing objects Reply with quote

I'm working on a random area system that first tries to select 3 areas of 3 different and specific tilesets (desert, crypt(normal), crypt(boss), for example) from a list of 'open' areas...

To mark the areas, I've dropped a waypoint (three types) into each keyword, then I can use getobjectbytag() to grab the tags and cycle through them...

The issue is how do you /randomly/ get the area?

I thought maybe if I saved a total for each type someplace, then picked a random number between 1-Total, then started counting from that spot to the max, then started over at one again that might work, but honestly it just got very complex very fast...

This is where I thought nwnx might come in handy. If I setup a mysql database using something like:
id
objRef
tileset
inUse

So then you can do queries to find one random & open area of X tileset type, and have an ID to work with later on... Finally (sorry!) getting to the question... How can I store a reference to an object with nwnx instead of the object itself?

And if anyone has time, is there a better scheme to make this happen?
Back to top
View user's profile Send private message
Disco



Joined: 06 Dec 2006
Posts: 152

PostPosted: Fri Feb 13, 2009 12:31    Post subject: Reply with quote

Use ONE type of waypoint. There's no real need for unique types as the resref of your area is unique by default.

What you do is this (in pseudoNWNcode):

Put a waypoint called "is_area" in each area

In OnModLoad
Code:

int i=1;

while ( GetIsObjectValid( GetWaypointByTag( "is_area", i ) ) ){

    ++i;
}

SetLocalInt( GetModule(), "areas", i );


This function gets a random area. You can use sCheckResRef to force it to take a random area out of a subset, based on some part of your area resrefs. For example: sCheckResRef="desert" would skip an area with the resref "mm_hold_2" but return areas called "dd_desert" and "desert_1".

Code:
object GetRandomArea( string sCheckResRef="" ){

    int nAreas = GetLocalInt( GetModule(), "areas" );
    int nArea   = 1 + Random( nAreas );

    object oArea = GetArea( GetWaypointByTag( "is_area", nArea ) );

    if ( sCheckResRef != "" ){

          while ( FindSubString( GetResRef( oArea, sCheckResRef ) ) == -1 ){

                 nArea   = 1 + Random( nAreas );
                 oArea = GetArea( GetWaypointByTag( "is_area", nArea ) );     
          }
    }

    return oArea;
}


I am not entirely sure what you want to do, but I guess this could help or give you some hints in the right direction.

ps. I am not sure if GetWaypointByTag() has an index. If not you should use GetObjectByTag(), and check if the index starts at 1 or 0.
Back to top
View user's profile Send private message
Fireboar



Joined: 17 Feb 2008
Posts: 323

PostPosted: Fri Feb 13, 2009 16:13    Post subject: Reply with quote

Hi Disco, that function's all very well except it will TMI if there are no matching areas. Which is Not Good. I'd be more tempted to loop round the whole set, set some module variables based on the matched subset (with the option to delete it immediately afterwards to save memory) and then randomly pick from that set.
Back to top
View user's profile Send private message
Ne0nx3r0



Joined: 29 Nov 2006
Posts: 36

PostPosted: Fri Feb 13, 2009 20:13    Post subject: Reply with quote

That is a good starting point though, thank you...

One question I have is, why use one area instead of three? The areas wont ever have any reason to overlap, as each of the 3 types are specific, so would it make sense to use one or three types of markers?
Back to top
View user's profile Send private message
Fireboar



Joined: 17 Feb 2008
Posts: 323

PostPosted: Fri Feb 13, 2009 22:31    Post subject: Reply with quote

Oh, so you're trying to get one area from one of three possible groups? Fair enough. It would be slightly more efficient in that case to use 3 different types of marker.
Back to top
View user's profile Send private message
Ne0nx3r0



Joined: 29 Nov 2006
Posts: 36

PostPosted: Fri Feb 13, 2009 23:36    Post subject: Reply with quote

*sigh* Well I think I'm getting it, I'll post the script if anyone wants it once it works! lol.

So far the main concept is to create a total, then pick a random number between 0-total, then count to the total, go back, and count to -1 of the total... fun stuff XD
Back to top
View user's profile Send private message
Ne0nx3r0



Joined: 29 Nov 2006
Posts: 36

PostPosted: Sat Feb 14, 2009 6:32    Post subject: Reply with quote

This seems to have worked alright:
Code:

//valid marker types are:
//cg - outdoor keyword area (chaos gate)
//dn - dungeon area
//bs - boss area
//example:
//object oChosenKeyword = GetRandomArea("cg",TILESET_RESREF_DESERT);
object GetRandomAreaMarker(string sMarkerType,string sTilesetResref);

object GetRandomAreaMarker(string sMarkerType,string sTilesetResref)
{
    //index starts at 0
    int iTotal = GetLocalInt(oModule,sMarkerType+sTilesetResref+"total");
    int iStart   = Random(iTotal);
    int iCounter = iStart;
    int iLooped = 0;

//first we try to find an area of the right tileset
    object oCurrentMarker;
    while(iCounter != iStart || iLooped == 0)
    {
        SendMessageToAllDMs("First Loop iStart was "+ IntToString(iStart));
        SendMessageToAllDMs("test was"+ IntToString(GetLocalInt(oModule,sMarkerType+TILESET_RESREF_DESERT+"total")));


        oCurrentMarker = GetLocalObject(oModule,sMarkerType+sTilesetResref+IntToString(iCounter));

        if(GetLocalInt(oCurrentMarker,"taken") == 0)
        {
            return oCurrentMarker;
        }

        iCounter++;
        if(iCounter > iTotal)
        {
            iLooped = 1;
            iCounter = 0;
        }
    }


The markers for the individual tilesets are counted and put in as totals onmodload, then a total of all of each area type is added in as well. Reserving/releasing areas is done elsewhere, but at least this does the job. Thanks for your help Smile

*edit* Actually that code is very outdated, and may have some isssues... If per chance someone actually runs into a need for this feel free to let me know XD.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    nwnx.org Forum Index -> Database related All times are GMT + 2 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group