Making an array

Posted by Gadush on Mon 16 Feb 2004 02:55 PM — 13 posts, 37,990 views.

#0
Can anyone point me in a good direction for giving rooms an array? The array would be possible positions within a grid, xpos, ypos, zpos.
Thanks,
Gadush
#1
Sorry, that post was not very clear as to what I am asking. I want to know if there is a way to declare an array, such as
int room_array[]
and read in variables (my room sizes) to determine the size of the array.
If my room has a size of 10 x 10 x 10, and it is divided into 5 foot gridwork, it would give 8 positions. Like this:


Top down view                     Elevation View
   +----------+---------+                *|10
   |      |   |  |      |                 |
   | ---- * - |- * ---- |                 |
   |      |   |  |      |                 |
   |----------+---------|                *|5
   |      |   |  |      |                 |
   |----- * - |- * ---- |                 |
   |      |   |  |      |                 |
   +--------------------+       ----------|
   * = possible position

How would I use my specified room sizes to declare the correct size for room_array? Or am I nuts? ;P
Thanks,
Gadush
Amended on Mon 16 Feb 2004 07:55 PM by Gadush
Canada #2
I think this might work:

int coords[3];
#define XCOORD 0
#define YCOORD 1
#define ZCOORD 2

    /* added to for rsize */
    if ( !str_cmp( arg, "rsize"  ) )
    {
	char xcoord[MAX_STRING_LENGTH];
	char ycoord[MAX_STRING_LENGTH];
        char zcoord[MAX_STRING_LENGTH];
      	argument = one_argument( argument, xcoord);
      	argument = one_argument( argument, ycoord);
      	argument = one_argument( argument, zcoord);
//Putting this here to verify that what your entering is valid
      	if ( !xcoord || xcoord[0] == '\0' || !ycoord || ycoord[0] == '\0' || !zcoord ||zcoord[0] == '\0')
    	{
			send_to_char( "Set the room size: width, length, height.\n\r", ch );
			send_to_char( "Usage: redit rsize <value> <value> <value>\n\r", ch );
			return;
    	}
//Didn't realize it was location and not room
      	location->coords[XCOORD] = atoi(xcoord);
      	location->coords[YCOORD] = atoi(ycoord);
      	location->coords[ZCOORD] = atoi(zcoord);
      	ch_printf(ch, "Room size set to:\n\r\tWidth: %d\n\r\tLength %d\n\r\tHeight %d\n\r", location->x, location->y, location->z);
   		return;
    }


Something like that should work. The defines are for ease of use, just to make it really obvious if your using x, y, or z coord. You would then print it out with:
ch_printf(ch, "X: %d Y%d Z%d\n\r", room->coords[XCOORD], room->coords[YCOORD], room->coords[ZCOORD]);

Is that what you meant?
#3
Hmmm. What I want to accomplish with the array is to specify a number of coordinates, such as 0,0,0 being the northwest corner at ground level. Or 3,4,10 being three east, four south, and 10 up. I want the array to get my room size, set with the rsize function, and figure the size to make the array based on that.
I am hoping in this way each PC, Mob, or Object will hold variables, sorta like:
(ch->xpos, ch->ypos, ch->zpos)
that will determine their location 'within' a room.
Then I can use a get_distance type function to compare and base actions on proximity.
So, I wonder if I can read in the room size variables, and use that to specify the size of the array room_array.
Thanks for the response,
Gadush
#4
I have edited the post showing positions to make it a bit more clear, I hope.
Gadush.
Canada #5
Sorry, I misunderstood. Yes, you can keep your rooms in exactly the same way that you originally had them, and have ch->coord[3];. Then, when you go to print, you can refernence ch->coord[XCOORD], ch->coord[YCOORD], ch->coord[ZCOORD], or however your going to do it, to print off. You would need one for all things in the rooms, so objs and chars for SMAUG. In your print function, you reference these to print out your info.

[EDIT] Ok, you asking how to make the characters array fit inside the room? The easy answer is that you don't need to. Why would you need to? If your thinking about how they will actually move around, you can check something line:
if ( ch->room && ch->room->xcoord == ch->coords[XCOORD] )
send_to_char("Alas, you cannot go that way!", ch);
return;
This would work within the check if they are moving north/south. Hope that helps. If you need this for another reason, let us know, and we'll see what we can do.
Amended on Mon 16 Feb 2004 08:36 PM by Greven
#6
You are on the right page, Greven. Thanks for the help. If I am getting what you are saying, I would make a check each time a PC/MOB/Obj either entered, used goto, transed, or was reset, etc. to a room, and specify their starting location within the room. (Next to the direction they just came from if possible) From there, it would only be relative positions to other MOB/PC/Objects. That sounds like just what I want.
But maybe I could use some way to make sure x, y, and z never were set to out of the range of the rooms coordinates? Since rooms are built with the sizes specified, I could find some way to calculate all the possible positions and set some sort of limit to what could be used for x, y, z when within a particular room. Have to be careful, or I will confuse myself, which doesn't seem hard. Heh.
Thanks,
Gadush
#7
So I still need to declare the variable like you showed, right?

int coords[3];
#define XCOORD 0
#define YCOORD 1
#define ZCOORD 2

As an example then, if I goto a room, how would I set the coordinates on myself? I know somewhere in do_goto, but how would I define XCOORD, YCOORD, and ZCOORD to 0,0,0 or whatever?
Sorry for my lack of knowledge. It seems hard to wrap my mind around this array deal.
Gadush
Canada #8
No worries. Those declarations should go into mud.h. There are alot of defines towards the top that you can put the #define COORD stuff, and the int coords[3] needs to go into both CHAR_DATA and OBJ_DATA. If your using goto as a way to set it, if you wanted it to be random, then you could do something like:

ch->coords[XCOORD] = number_range(0, room->x);
ch->coords[YCOORD] = number_range(0, room->y);
ch->coords[ZCOORD] = number_range(0, room->z);


This shoul allow you to go to a random set of coords. If you wanted a random position anywhere on the ground:

ch->coords[XCOORD] = number_range(0, room->x);
ch->coords[YCOORD] = number_range(0, room->y);
ch->coords[ZCOORD] = 0;


Hope that helps. You may also need to set x/y/zcoords on exits, so it know where to bring people in. I dunno, thats up to you.
#9
Well, I tried modifying all the movement functions to set the coords. Here is what I tried in will_fall. I want the coordinates to be set on a character who falls out of one room, when they enter the next. I used your suggestion of making the coordinates set randomly is some cases, like fall or goto.




/*
 * Check to see if a character can fall down, checks for looping   -Thoric
 */
bool will_fall( CHAR_DATA *ch, int fall )
{
    if ( IS_SET( ch->in_room->room_flags, ROOM_NOFLOOR )
    &&   CAN_GO(ch, DIR_DOWN)
    && (!IS_AFFECTED( ch, AFF_FLYING )
    || ( ch->mount && !IS_AFFECTED( ch->mount, AFF_FLYING ) ) ) )
    {
	if ( fall > 80 )
	{
	   bug( "Falling (in a loop?) more than 80 rooms: vnum %d", ch->in_room->vnum );
	   char_from_room( ch );
	   char_to_room( ch, get_room_index( ROOM_VNUM_TEMPLE ) );
	   fall = 0;
	   return TRUE;
	}
	set_char_color( AT_FALLING, ch );
	send_to_char( "You're falling down...\n\r", ch );
	move_char( ch, get_exit(ch->in_room, DIR_DOWN), ++fall );
	ch->coords[XCOORD] = number_range(0, room->x);
	ch->coords[YCOORD] = number_range(0, room->y);  /* random location in new room */
	ch->coords[ZCOORD] = 0;
	return TRUE;
    }
    return FALSE;
}


Trouble is, I get the error that 'room' is undeclared. I get the same error for all the functions I modified. Where should I declare room? Thanks for the help.
Gadush
Canada #10
The problem with that function is that the variable room does not exist. However, you could do this:
	ch->coords[XCOORD] = number_range(0, get_exit(ch->in_room, DIR_DOWN)->to_room->x);
	ch->coords[YCOORD] = number_range(0, get_exit(ch->in_room, DIR_DOWN)->to_room->y);  /* random location in new room */
	ch->coords[ZCOORD] = 0;
Because get_exit returns an EXIT_DATA, you can reference values of the exit, like to_room, which happenes to be of type ROOM_INDEX_DATA, which is what you want. The other option is declaring the room variable and assigning it earlier in the function. A little more more, but less sloppy.
#11
Hmmm. Now it says structure has no member named 'x'

Is this because x,y, z are location, not room? I am still struggling with the whole 'tree' thing. Where it says
to_room->x should it be to_room->location->x ?
Gadush
Canada #12
No, lemme see if I can describe it. Its like a pyramid. At the top is the EXIT_DATA. One step below that is the structure for EXIT_DATA, direction, reverse direction, etc, and to_room. to_room is the chosen name for this instance of ROOM_INDEX_DATA. You can declare any name you want: location, to_room, room, dbfoothefoo, whatever you want. It is all of the same type. The name is not important, but the type is. So, back to the analogy. Most of the pyramid stops there: int and sh_int are not structures. However, there is another layer below to_room, leading to the room variables, where x,y, and z should SHOULD exist. The "to_room->x" says go down one layer from to_room to the x variable.

I may be wrong in my method, so try this:
/*
 * Check to see if a character can fall down, checks for looping   -Thoric
 */
bool will_fall( CHAR_DATA *ch, int fall )
{
    ROOM_INDEX_DATA *room;
    if ( IS_SET( ch->in_room->room_flags, ROOM_NOFLOOR )
    &&   CAN_GO(ch, DIR_DOWN)
    && (!IS_AFFECTED( ch, AFF_FLYING )
    || ( ch->mount && !IS_AFFECTED( ch->mount, AFF_FLYING ) ) ) )
    {
	if ( fall > 80 )
	{
	   bug( "Falling (in a loop?) more than 80 rooms: vnum %d", ch->in_room->vnum );
	   char_from_room( ch );
	   char_to_room( ch, get_room_index( ROOM_VNUM_TEMPLE ) );
	   fall = 0;
	   return TRUE;
	}
	set_char_color( AT_FALLING, ch );
	send_to_char( "You're falling down...\n\r", ch );
	move_char( ch, get_exit(ch->in_room, DIR_DOWN), ++fall );
	room = get_exit(ch->in_room, DIR_DOWN)->to_room;
	ch->coords[XCOORD] = number_range(0, room->x);
	ch->coords[YCOORD] = number_range(0, room->y);  /* random location in new room */
	ch->coords[ZCOORD] = 0;
	return TRUE;
    }
    return FALSE;
}


That should work, I tested it, and as long as you declared x,y, and z in the ROOM_INDEX_DATA structure in mud.h under those names, it should as well.