/** * 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; }