View previous topic :: View next topic |
Author |
Message |
Ne0nx3r0
Joined: 29 Nov 2006 Posts: 36
|
Posted: Fri Feb 13, 2009 1:53 Post subject: Referencing objects |
|
|
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 |
|
|
Disco
Joined: 06 Dec 2006 Posts: 152
|
Posted: Fri Feb 13, 2009 12:31 Post subject: |
|
|
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 |
|
|
Fireboar
Joined: 17 Feb 2008 Posts: 323
|
Posted: Fri Feb 13, 2009 16:13 Post subject: |
|
|
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 |
|
|
Ne0nx3r0
Joined: 29 Nov 2006 Posts: 36
|
Posted: Fri Feb 13, 2009 20:13 Post subject: |
|
|
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 |
|
|
Fireboar
Joined: 17 Feb 2008 Posts: 323
|
Posted: Fri Feb 13, 2009 22:31 Post subject: |
|
|
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 |
|
|
Ne0nx3r0
Joined: 29 Nov 2006 Posts: 36
|
Posted: Fri Feb 13, 2009 23:36 Post subject: |
|
|
*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 |
|
|
Ne0nx3r0
Joined: 29 Nov 2006 Posts: 36
|
Posted: Sat Feb 14, 2009 6:32 Post subject: |
|
|
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
*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 |
|
|
|
|
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
|