TinTin++ Mud Client The TinTin++ message board

 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
TinTin++ Mud Client

Accessing #MAP LIST / #MAP INFO?

 
Post new topic   Reply to topic    The TinTin++ message board Forum Index -> Feature Requests
View previous topic :: View next topic  
Author Message
Slysven



Joined: 10 Apr 2011
Posts: 365
Location: As "Jomin al'Bara" in WoTMUD or Wiltshire, UK

PostPosted: Wed Jun 15, 2011 12:19 pm    Post subject: Accessing #MAP LIST / #MAP INFO? Reply with quote

I've found that the infomation that the above things return very useful for finding rooms and debugging respectively. The LIST one is much faster to produce information than any script I can come up with - BUT - I cannot see anyway to grab that information to process it in my scripts? For example if I want to check that I havn't got a duplicated room (possibly caused by a non-linear/odd room placement or linkage in the MUD) or if I am moved to another room by automatic MUD action e.g. by following another character - the data that I can see from the #MAP LIST is brillient. It's just a pain that I cannot, for instance, count the number of matching rooms and warn when there is more than one.

Would it be feasible, as a minimal solution, to hang a sixth(?) argument to #MAP LIST for a variable to receive a result of the form {{vnum1}{vnum2}{...}{vnumn}} where each is a vnum of a room matching the first 5 argument which I think are: {name} {exits} {description} {area} {notes}? [An update to #HELP MAP for these would also save me some headscratching whilst trying to remember the details! Smile ] I guess supplying a variable would probably also need to silence the on-screen display of the information?

I just hope I haven't been bogging you, Scandum, down with requests that no one else thinks are useful... your work though should be appreciated by those who value software that they can actually see (and get to hold onto the pieces of if they break it!) Embarassed
Back to top
View user's profile Send private message
Scandum
Site Admin


Joined: 03 Dec 2004
Posts: 3770

PostPosted: Wed Jun 15, 2011 2:27 pm    Post subject: Reply with quote

You can use #loop in combination with '#map at' to visit all the rooms, and grab whatever you need. For example: #loop 1 100 vnum #map at $vnum #map get roomname name.

Finding matches is probably easiest by using a table:

Code:

#if {&room_names[$name] == 0}
{
  #var room_names[$name] $vnum
}
{
  #showme: room $vnum has the same name as room $room_names[$name] ($name)
}


I think the 5 fields are listed under #map find, but I'll add it to #map list as well.
Back to top
View user's profile Send private message Send e-mail
Slysven



Joined: 10 Apr 2011
Posts: 365
Location: As "Jomin al'Bara" in WoTMUD or Wiltshire, UK

PostPosted: Mon Jun 20, 2011 7:47 pm    Post subject: Reply with quote

Sorry but I don't think what you suggest will work in a practical way:
* The idea of using the roomname as the index into a table with the room vnum as the content seems attractive, but the roomname is often not unique and I (will) have thousands of rooms.
* To overcome the problem of non-unique roomnames I would combine them with room descriptions which are ARE unique to each room. For the MUD I'm playing though, those description can be several lines of text and I had already worked out that concatination with the room names is not going to fly. However, appending to the room name in the above an integer hash value derived from the description showed promise until I hit a limit. Using a table as you suggest, I find that wintin (in Windoze environment) and tintin (in cygwin bash, in windows) both die horribly with between 500 and 4000 rooms.

I tested this with the following, which take a single numeric argument N and creates that many table entries each with a numeric value, the fixed string "ABCDEFGH" represents the Room name (I originally tried this with a longer string with even worse results) and the number $data_item representing an integer hash value derived from the room description, I wrote stuff to a file as well as to the screen so that I could save the information before tintin crashed or otherwise died:
Code:
#ALIAS {testn}
{
   #MATH limit {%1};
   #LIST data {CLEAR};
   #SHOWME {Testing $limit\n};
   #LINE LOG {test.log} {Testing $limit};
   #LINE LOG {test.log} { };
   #LOOP {1} {$limit} {data_item}
   {
      #MATH data[ABCDEFGH$data_item] {1d65536};
      #SHOWME {$limit: $data_item: data[ABCDEFGH$data_item]: $data[ABCDEFGH$data_item]\n};
      #LINE LOG {test.log} {$limit: $data_item: data[ABCDEFGH$data_item]: $data[ABCDEFGH$data_item]\n};
   };
   #LINE LOG {test.log} { };
   #LINE LOG {test.log} {&data[]};
   #SHOWME {&data[]};
   #VARIABLE ;
}

Note that the exact failure point varies, at low numbers in WinTin I could retrive individual data entries up to about 700 entries - but if I just used a '#variable' to show all variable the screen then gets filled with data and crashes; with smaller values of N that don't cause death the screen display is problematic trying to scroll back and forward through it with PageUp/Down. May I suggest that display of ACTION/ALIAS/VARIABLE at least perhaps should be limited to a few lines for each item, with an ellipsis "..." indicating a large/long item that would have to be specified to be fully shown (if that is even possible???)

The reason I am pursuing this interest in using room name and description to find out room numbers is that when building maps for a MUD I need to know whether I've been to a room before. Also, although moving around with #MAP FLAG NOFOLLOW set off so that the map display follows entered movement command does work if your character is under your control, in the MUD I'm currently on, auto-fleeing sometimes occurs if you get to a low hit point level in a fight. Finally, if you are part of a group or following another character you get moved around the MUD but not under movement commands from the keyboard. All of these cases mean that the ability to work out where you are from the data from the MUD of room name and description is essential to keeping the map display updated - ideally in a fraction of a second which isn't going to happen with a script solution.

As I previously hinted, the answer to this is right on the edge of implimentation: the #MAP LIST command neatly and speedily returns the information needed (to the screen) at a rate far faster that anything availible from a good script. All it needs is the data to be placed in a variable INSTEAD of on-screen. I experiemented with the code around line 971 of mapper.c in the 2.00.6 code but I could not grasp quite enough understanding of the code to work out how to output to a new, sixth argument, a result of the form {{vnum1}{vnum2}{..}{vnumN}} where each {vnum#} is one roomnumber that matches the first five supplied arguments. The set_nest_node() and add_nest_node() functions would seem to be required but I kept getting a trailing '{}' after {vnumN}. Ideally, the result could be sorted in ascending order from the current room (as held in 'ses->map->room_list[room]->size' for each match) but that would just be a cherry on the top of a very useful tweak if you can fit it in! Thumbs Up
Back to top
View user's profile Send private message
Scandum
Site Admin


Joined: 03 Dec 2004
Posts: 3770

PostPosted: Mon Jun 20, 2011 9:31 pm    Post subject: Reply with quote

Fixing the limited string buffer cap is on my todo list, probably will be a while till I get around to it as it's rather involved.


You can use #map set roomdesc to set a room description.

Then if you have the room name, room exits, and room description you can use #map goto with those arguments to be more accurate, for example:

#map goto {A tiny house} {s;e;d} {You're inside a tiny house.}

Additional arguments are the area, room note, and the room's terrain type is planned to be added for the next release.

To find out if a specific room exists is a little more involved:

Code:

#var result 0;
#map find {<name>} {<exits>} {<etc>}
#path save forward result
#if {"$result" != "0"}
{
  #showme room exits
}
Back to top
View user's profile Send private message Send e-mail
Slysven



Joined: 10 Apr 2011
Posts: 365
Location: As "Jomin al'Bara" in WoTMUD or Wiltshire, UK

PostPosted: Tue Jun 21, 2011 10:02 am    Post subject: Reply with quote

I don't necessarily need to automatically jump to a specified room as your indicated #MAP GOTO... would do. I've already used #MAP SET ROOMDESC et al. to build up a map of about 2500 rooms so far (a few of those being void...!) Please, please, please just modify the following function in the code {which impliments #MAP LIST} to stuff the indicated data into a variable - you've already got 95-98% of the code in place already!

Code:
'mapper.c' lines 954-974:
DO_MAP(map_list)
{
   char arg3[BUFFER_SIZE], arg4[BUFFER_SIZE], arg5[BUFFER_SIZE];
   int room;

   arg = sub_arg_in_braces(ses, arg, arg1, GET_ALL, SUB_VAR|SUB_FUN);
   arg = sub_arg_in_braces(ses, arg, arg2, GET_ALL, SUB_VAR|SUB_FUN);
   arg = sub_arg_in_braces(ses, arg, arg3, GET_ALL, SUB_VAR|SUB_FUN);
   arg = sub_arg_in_braces(ses, arg, arg4, GET_ALL, SUB_VAR|SUB_FUN);
   arg = sub_arg_in_braces(ses, arg, arg5, GET_ALL, SUB_VAR|SUB_FUN);

   fill_map(ses);

   for (room = 0 ; room < ses->map->size ; room++)
   {
      if (match_room(ses, room, arg1, arg2, arg3, arg4, arg5))
      {
         tintin_printf2(ses, "vnum: %5d distance: %5d name: %s", ses->map->room_list[room]->vnum, ses->map->room_list[room]->size, ses->map->room_list[room]->name);
      }
   }
}

I've tried but my attempt had to use ';' between room numbers because I cannot get them wrapped in braces correctly Sad :
Code:

DO_MAP(map_list)
{
   char arg3[BUFFER_SIZE], arg4[BUFFER_SIZE], arg5[BUFFER_SIZE], arg6[BUFFER_SIZE], buff[BUFFER_SIZE];
   int room;

   arg = sub_arg_in_braces(ses, arg, arg1, GET_ALL, SUB_VAR|SUB_FUN);
   arg = sub_arg_in_braces(ses, arg, arg2, GET_ALL, SUB_VAR|SUB_FUN);
   arg = sub_arg_in_braces(ses, arg, arg3, GET_ALL, SUB_VAR|SUB_FUN);
   arg = sub_arg_in_braces(ses, arg, arg4, GET_ALL, SUB_VAR|SUB_FUN);
   arg = sub_arg_in_braces(ses, arg, arg5, GET_ALL, SUB_VAR|SUB_FUN);
   arg = sub_arg_in_braces(ses, arg, arg6, GET_ALL, SUB_VAR|SUB_FUN);

   fill_map(ses);
   buff[0]='\0';

   for (room = 0 ; room < ses->map->size ; room++)
   {
      if (match_room(ses, room, arg1, arg2, arg3, arg4, arg5))
      {
         if (*arg6 == 0)
         {
            tintin_printf2(ses, "vnum: %5d distance: %5d name: %s", ses->map->room_list[room]->vnum, ses->map->room_list[room]->size, ses->map->room_list[room]->name);
         }
         else
         {
            if (*buff==0)
            {
               snprintf(buff, BUFFER_SIZE, "%d", ses->map->room_list[room]->vnum);
               }
            else
            {
               snprintf(buff, BUFFER_SIZE, "%s;%d", buff, ses->map->room_list[room]->vnum);
            }
         }
      }
   }
   if (*arg6!=0)
   {
      if (*buff!=0)
      {
         add_nest_node(ses->list[LIST_VARIABLE], arg6, "%s", buff);
      }
   }
}

This works (and works much, much faster than I could iterate though all the rooms with a script) for me in a Cygwin inside Windows setup Cool - I can use a #FOREACH to iterate through the returned results (if any, as no matching rooms will not affect the supplied variable as per other tintin commands.) and converting to a nest variable with a #FOREACH, I can even count the number of matches! For some simple examples Coffee

Code:
#MAP LIST {%*Queen's Blessing%*} {} {} {} {} {result}
#LIST {results} {clear}
#FOREACH {$result} {item} {#LIST {results} {ADD} {$item}}
#SHOWME {&results[] rooms were found!}
3 rooms were found!

#FOREACH {$result} {item} {#MAP GET {ROOMNAME} {rname} {$item}; #SHOWME {Room number:$item has name:"$rname"}}
Room number:1192 has name:"The Queen's Blessing"
Room number:1194 has name:"The Queen's Blessing"
Room number:1196 has name:"Reception of the Queen's Blessing"
Back to top
View user's profile Send private message
Slysven



Joined: 10 Apr 2011
Posts: 365
Location: As "Jomin al'Bara" in WoTMUD or Wiltshire, UK

PostPosted: Wed Feb 01, 2012 12:44 pm    Post subject: Reply with quote

I've updated this for the latest (2.00.8) release, pop this function in the mapper.c source code to replace the existing DO_MAP(map_list) function. As per ixle's request in http://tintin.sourceforge.net/board/viewtopic.php?t=1671 it also returns the area in the on-screen listing
Code:
DO_MAP(map_list)
{
   int room;
   char arg7[BUFFER_SIZE], temp[BUFFER_SIZE], buff[BUFFER_SIZE], *temparg;

   //Need to see if have got a 7th(?) argument - variable to store result in!
   buff[0] = '\0';
   temparg = arg;
   temparg = sub_arg_in_braces(ses, temparg, arg7, GET_ALL, SUB_VAR|SUB_FUN); // roomname
   temparg = sub_arg_in_braces(ses, temparg, arg7, GET_ALL, SUB_VAR|SUB_FUN); // exits
   temparg = sub_arg_in_braces(ses, temparg, arg7, GET_ALL, SUB_VAR|SUB_FUN); // roomdesc
   temparg = sub_arg_in_braces(ses, temparg, arg7, GET_ALL, SUB_VAR|SUB_FUN); // roomarea
   temparg = sub_arg_in_braces(ses, temparg, arg7, GET_ALL, SUB_VAR|SUB_FUN); // roomnote
   temparg = sub_arg_in_braces(ses, temparg, arg7, GET_ALL, SUB_VAR|SUB_FUN); // roomterrain
   temparg = sub_arg_in_braces(ses, temparg, arg7, GET_ALL, SUB_VAR|SUB_FUN); // a variable name?

   searchgrid_find(ses, ses->map->in_room, "0");
   for (room = 0 ; room < ses->map->size ; room++)
   {
      if (match_room(ses, room, arg))
      {
         if (*arg7 == 0)
            tintin_printf2(ses, "vnum: %5d   distance: %8.3f   area: %20s   name: %s",
               ses->map->room_list[room]->vnum,
               ses->map->search_stamp == ses->map->room_list[room]->search_stamp ? ses->map->room_list[room]->length - ses->map->room_list[room]->weight : -1,
               ses->map->room_list[room]->area, ses->map->room_list[room]->name);
         else
         {
            if (*buff=='\0')
            {
               snprintf(buff, BUFFER_SIZE, "%d", ses->map->room_list[room]->vnum);
            }
            else
            {
               snprintf(temp, BUFFER_SIZE, "%s;%d", buff, ses->map->room_list[room]->vnum);
               strcpy(buff, temp); /*Have to use two buffers because string functions don't like destination and source memory areas overlapping!*/
            }
         }
      }
   }
   
   if (*arg7!=0)
   {
      if (*buff!=0)
      {
         add_nest_node(ses->list[LIST_VARIABLE], arg7, "%s", buff);
      }
   }
}
You may want to update the single line help on line 84 of the mapper.c code:
Code:
      tintin_printf2(ses, "#map list     <l> <e> <d> <a> <n> <t> <var> (show/store list of matching rooms)");
and replace the relevent help text at line 911 of help.c:
Code:

      "         #map list <name> <exits> <desc> <area> <note> <terrain> <variable>\n"
      "                  Given one or more arguments, using empty {} for don't cares up to\n"
      "                  roomterrain, lists all matching rooms, their area and distance.\n"
      "                  If a variable name is supplied in the last position, stores a\n"
      "                  semicolon separated list of matching room vnumbs in that\n"
      "                  variable instead."
      "                  "
Enjoy!

Edit (Wed Feb 01, 2012 5:44 pm): Forgot to put "20" as a width specifier in bit now written as "area: %20s ".
Edit: Fixed a gotcha where C string functions do not behave predictably if asked to put a string in the same variable that they use as a source for that function.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    The TinTin++ message board Forum Index -> Feature Requests All times are GMT - 5 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
Get TinTin++ Mud Client at SourceForge.net. Fast, secure and Free Open Source software downloads Get TinTin++ Mud Client at SourceForge.net. Fast, secure and Free Open Source software downloads
TinTin++ Homepage

Powered by phpBB © 2001, 2002 phpBB Group