/**
* This is the handler for co-ordinates. Finds and sets co-ordinates for
* outside rooms. It works from specific fixed co-ordinate locations and
* finds the rooms as a web of relative connections for there.
* @author Pinkfish
* @started Mon Nov 3 13:57:58 PST 2003
*/
#include <dirs.h>
class room_data {
string other;
string direction;
int* coords;
int last_update;
}
private mapping _rooms = ([ ]);
private nosave mapping _dirs;
int setup_room(string path);
void create() {
mixed* bits;
int i;
bits = STD_ORDERS;
_dirs = ([ ]);
for (i = 0; i < sizeof(bits); i += 2) {
_dirs[bits[i]] = bits[i + 1];
}
}
private void setup_specific_room(string path, string new_path, string dir) {
int* delta;
int* co_ord;
int k;
class room_data data;
// Figure out all the nifty offset things.
delta = new_path->query_room_size_array() + path->query_room_size_array();
co_ord = copy( _rooms[new_path]->coords);
for ( k = 0; k < 3; k++ ) {
co_ord[ k ] += _dirs[dir][ k ] *
( delta[ k ] + delta[ k + 3 ] );
}
// Do it!
data = new(class room_data);
data->other = new_path;
data->coords = co_ord;
data->direction = dir;
data->last_update = _rooms[new_path]->last_update;
_rooms[path] = data;
}
/**
* Find the room's co-ordinates.
* @param room the room to lookup
* @return the co-ordinates
*/
int* query_room_co_ords(string path) {
class room_data data;
data = _rooms[path];
if (data) {
if (!_rooms[data->other]) {
map_delete(_rooms, path);
} else {
if (data->last_update != _rooms[data->other]->last_update) {
setup_specific_room(path, data->other, data->direction);
}
return data->coords;
}
}
if (setup_room(path)) {
data = _rooms[path];
return data->coords;
}
return 0;
}
/**
* Sets up the room, based on a room with a known co-ordinate and an
* exit direction. We search around to try and find a fixed co-ordinate
* room.
* @param path the room being setup
*/
int setup_room(string path) {
string* bits;
int i;
string new_path;
// We only work with outside rooms that are not in a terrain
if (path->query_property("location") != "outside" ||
!path->query_terrain_handler()) {
return 0;
}
bits = path->query_dest_dir();
for (i = 0; i < sizeof(bits); i += 2) {
if (find_object(bits[i+1])) {
new_path = file_name(find_object(bits[i+1]));
} else {
new_path = bits[i+1];
}
// We have a room to base it off.
if (_rooms[new_path]) {
setup_specific_room(path, new_path, bits[i]);
return 1;
}
}
return 0;
}
/**
* Sets up the specific co-ordinates for the specific room.
* @param path the path for the main room
* @param coords the coordinates to set
*/
void setup_fixed_room(string path, int* coords) {
class room_data data;
tell_creator("pinkfish", "%O %O %O\n", path, path->query_property("location"),
path->query_terrain_handler());
// We only work with outside rooms that are not in a terrain
if (path->query_property("location") != "outside" ||
!path->query_terrain_handler()) {
return 0;
}
if (_rooms[path]) {
data = _rooms[path];
if (data->coords[0] == coords[0] &&
data->coords[1] == coords[1] &&
data->coords[2] == coords[2]) {
return ;
}
} else {
data = new(class room_data);
}
data->coords = coords;
data->last_update = time();
_rooms[path] = data;
}
/**
* Returns the current list of stored rooms.
*/
mapping query_rooms() {
return _rooms;
}