11 Feb, 2007, grif wrote in the 1st comment:
Votes: 0
I'm new to the forums here so go easy on me :-)
Anyrate, I'm recoding an Emlen style mud, but that should have little bearing.
I have the mud generating the map and there is a command called "z_assign" which recursively assigns coordinates to every room.
This works correctly, but I want it to go through the rooms in a different order, because while it is assigning coordinates, I'm having it also keep track of any rooms that have the same coordinates. IE: I want to know which rooms overlap or collide.
What I want to have happen is for it to assign coordinates to every room in the area, then move onto the next area, however if 2 areas connect, then their coordinates must match up.
What I currently have checks all the links from a room with the same area first and then checks all links from the room that are not the same area.
While it does work, it's not good enough.
Without further ado, the code:
void go_mdisplay (ROOM_DATA * rid, short x, short y, short z, short came_from)
{
if (disp_already[rid->vnum])
return;

rid->x = x;
rid->y = y;
rid->z = z;
static int i;
static char j;
static ROOM_DATA *tempRoom;

i = ((rid->x * 100) + (rid->y * 5) + (rid->z)) % 6028;
if (i < 0)
i *= -1;
// check for collisions.
for (j = 0; j < 100; ++j)
{
if(collision[i][j])
{
if (collision[i][j]->x == rid->x && collision[i][j]->y == rid->y && collision[i][j]->z == rid->z)
{
// Store colliding room.
collision[i][j]->collision = rid;
rid->collision = collision[i][j];
++collisions;
break;
}
}
else
{
collision[i][j] = rid;
break;
}
if (j >= 99)
collisions = -10000;
}

// check rooms in the same area first
if (rid->exit[DIR_WEST] && rid->exit[DIR_WEST]->to_room != NULL
&& rid->exit[DIR_WEST]->to_room->area == rid->area
&& rid->exit[DIR_WEST]->to_room->exit[DIR_EAST] != NULL
&& rid->exit[DIR_WEST]->to_room->exit[DIR_EAST]->to_room == rid)
{
disp_already[rid->vnum] = TRUE;
go_mdisplay (rid->exit[DIR_WEST]->to_room, (x - 1), y, z, DIR_EAST);
}
/* ———————————————- */
/* same if-statement for e,s,w,u,d */
/* ———————————————- */

// check rooms in *not* in the same area
if (rid->exit[DIR_WEST] && rid->exit[DIR_WEST]->to_room != NULL
&& rid->exit[DIR_WEST]->to_room->area != rid->area
&& rid->exit[DIR_WEST]->to_room->exit[DIR_EAST] != NULL
&& rid->exit[DIR_WEST]->to_room->exit[DIR_EAST]->to_room == rid)
{
disp_already[rid->vnum] = TRUE;
go_mdisplay (rid->exit[DIR_WEST]->to_room, (x - 1), y, z, DIR_EAST);
}
/* ——————————————— */
/* same if-statement for e,s,w,u,d */
/* ——————————————— */
return;
}

// typing "z_assign" once will assign coordinates to the map. Typing it again will remove all coordinates
void assign_coordinates (CHAR_DATA * ch, char *argy)
{
ROOM_DATA *r;
int hash;
int i = 0;
short j;
char buf[256];
DEFINE_COMMAND ("z_assign", assign_coordinates, POSITION_DEAD, 110, LOG_NORMAL, "blah2")
if (get_room_index (3001)->x != 0 || get_room_index (3001)->y != 0 || get_room_index (3001)->z != 0)
{
for (hash = 0; hash < HASH_MAX; hash++)
{
for (r = room_hash[hash]; r != NULL; r = r->next)
{
r->x = 0;
r->y = 0;
r->z = 0;
r->collision = NULL;
}
}
send_to_char ("Coordinates Reset to 0, 0, 0\n\r", ch);
return;
}
for (i = 0; i < 6028; ++i)
for (j = 0; j < 100; ++j)
collision[i][j] = NULL;

reset_data ();
i = 0;
for (hash = 0; hash < HASH_MAX; hash++)
{
/* vnum 3000 is the vnum of the first real area */
for (r = get_room_index(3000); r != NULL; r->next)
{
if (r && !disp_already[r->vnum] && r->vnum >= 3000)
{
go_mdisplay (r, 0, 0, i, -9);
// make sure unconnected portions don't collide.
// each unconnected portion adds 40 to their starting "z" coordinate
i += 40;
}
}
}
// start at the first room and goto the center of Kalindaar
for (hash = 0; hash <= 10088 % HASH_MAX; hash++)
{
for (r = room_hash[hash]; r != NULL; r = r->next)
{
if (r && !disp_already[r->vnum] && r->vnum >= 3000)
{
go_mdisplay (r, 0, 0, i, -9);
i += 40;
}
}
}
sprintf (buf, "There are %d collisions\n\r", collisions);
send_to_char (buf, ch);
return;
}
11 Feb, 2007, Justice wrote in the 2nd comment:
Votes: 0
Okay, just trying to figure out exactly what you're trying to do.

Basically, you want each room to have a coordinate to find overlaps and to check how areas are linked to each other?

I don't know if your source will support C++, but my ranged search code can handle this type of thing easily. Each frame of the search contains a relative coordinate from the start room. It would be easy to implement a callback that stores rooms in a std::multimap which would store a list of each room at a given coordinate.
12 Feb, 2007, grif wrote in the 3rd comment:
Votes: 0
My code doesn't support c++.
I was just trying to change the order of assigning XYZ coordinates.
It would assign them all at once and I wanted it to assign coordinates to an entire area first before moving onto the next area.
I ended up comming up with a solution. When I'm evaluating the XYZ coordinates, if the room I would evaluate next is part of a different area, I instead put it into a stack.
In my helper function, I'm looping through that stack until it is empty.

Thanks for looking at my problem.
0.0/3