#include <lib.h> #include <daemons.h> #include <rooms.h> #include <save.h> #define ROOM_ZERO "/domains/campus/room/start" inherit LIB_DAEMON; mapping Workrooms = ([]); mapping WorldMap = ([]); mapping WorldGrid = ([]); static string last_exit; static int global_manual; int debugging; static string *cards = ({ "north", "south", "east", "west", "northeast", "northwest", "southeast", "southwest", "up", "down" }); static string *unsafes = ({ "/realms/", "/open/", "/estates/" }); void create(){ if(!WorldMap) WorldMap = ([]); if(!WorldGrid) WorldGrid = ([]); if( file_size( SAVE_ROOMS __SAVE_EXTENSION__ ) > 0 ) unguarded( (: restore_object, SAVE_ROOMS, 1 :) ); set_heart_beat(300); } void heart_beat(){ unguarded( (: save_object(SAVE_ROOMS, 1) :) ); } string GetRoomZero(){ return ROOM_ZERO; } mixed GenerateNames(int x){ int first, second, third; third = (x & 32767); second = (x & 536870911) - third;; first = ((x >> 29) << 29); //tc("first: "+first); //tc("second: "+second); //tc("third: "+third); //tc("total: "+(first+second+third)); return ({ first, second, third }); } int eventDestruct(){ unguarded( (: save_object(SAVE_ROOMS, 1) :) ); return daemon::eventDestruct(); } int SetDebugging(int i){ if(!this_player() || !adminp(this_player())) return 0; if(i) debugging = 1; else debugging = 0; return debugging; } mixed validate_last_room(string room, object player){ string location_str, current_room_name; object location_ob, current_room; mapping origin_room = ([]); mapping origin_room_exits = ([]); mixed tmp, ret; if(debugging) tc("validate "+room+"?","blue"); if(player) location_str=player->GetProperty("LastLocation"); if(!location_str) return 0; if(location_str) location_ob=load_object(location_str); if(location_ob) tmp = this_object()->GetCoordinates(location_ob); if(tmp) origin_room = this_object()->GetGrid(tmp); current_room = room_environment(player); current_room_name = base_name(room_environment(player)); if(debugging){ tc("Last Location: "+location_str); tc("Last Location coords: "+ tmp); if(sizeof(tmp) > 1) tc("What those coordinates grid as: "+identify(origin_room)); } if(room == ROOM_ZERO || (mapp(origin_room) && origin_room["room"] && origin_room["room"] == location_str)){ mapping exits = location_ob->GetExitMap(); if(location_ob->GetFlyRoom()){ exits["up"] = location_ob->GetFlyRoom(); } foreach(mixed key, mixed val in exits){ if(val == current_room_name){ ret = ([ opposite_dir(key) : location_str ]); } } if(debugging) tc("validation passed","blue"); if(!ret) ret = 1; } if(debugging) tc("validation failed","red"); return ret; } void zero(){ WorldMap = ([]); WorldGrid = ([]); Workrooms = ([]); ROOM_ZERO->init(); } varargs mapping GetGridMap(string str){ mapping ret; string prefix, room; object ob; if(!sizeof(str)) return copy(WorldGrid); if(catch(ob = load_object(str))){ return 0; } prefix = path_prefix(str); room = last_string_element(str, "/"); if(ob) ret = this_object()->GetGrid(this_object()->GetCoordinates(ob)); if(!ret) ret = ([]); //tc("ret: "+identify(ret),"blue"); //tc("prefix: "+prefix); //tc("room: "+room); //tc("1: "+identify(WorldMap[prefix])); if(WorldMap[prefix] && WorldMap[prefix][room]){ //tc("2: "+identify(WorldMap[prefix][room]),"red"); ret += WorldMap[prefix][room]; } return ret; } varargs mapping GetWorldMap(string str){ return copy(WorldMap); } string StrCoord(mapping TmpMap){ string ret = TmpMap["x"] + ","; ret += TmpMap["y"] + ","; ret += TmpMap["z"]; return ret; } varargs mixed SetGrid(string arg_room, string coord, object player, int unset){ string room; mixed a, b, c, d, e, f, g, h, i, j, k, l, m, n; int p, q, x, y, z; mixed xarr, yarr, zarr; //string hashed_coord = crypt(coord, "xyz"); if(this_player() && adminp(this_player())){ room = arg_room; } else { room = base_name(previous_object()); } if(!player->GetProperty("LastLocation")) return 0; if(debugging){ tc("SetGrid received: "+room+", "+coord+", "+ identify(player)+", "+unset,"blue"); } sscanf(coord,"%d,%d,%d",x,y,z); xarr = GenerateNames(x); yarr = GenerateNames(y); zarr = GenerateNames(z); a = xarr[0]; b = xarr[1]; c = xarr[2]; d = yarr[0]; e = yarr[1]; f = yarr[2]; g = zarr[0]; h = zarr[1]; i = zarr[2]; if(!WorldGrid[a]) WorldGrid[a] = ([]); if(!WorldGrid[a][b]) WorldGrid[a][b] = ([]); if(!WorldGrid[a][b][c]) WorldGrid[a][b][c] = ([]); if(!WorldGrid[a][b][c][d]) WorldGrid[a][b][c][d] = ([]); if(!WorldGrid[a][b][c][d][e]) WorldGrid[a][b][c][d][e] = ([]); if(!WorldGrid[a][b][c][d][e][f]) WorldGrid[a][b][c][d][e][f] = ([]); if(!WorldGrid[a][b][c][d][e][f][g]) WorldGrid[a][b][c][d][e][f][g] = ([]); if(!WorldGrid[a][b][c][d][e][f][g][h]) WorldGrid[a][b][c][d][e][f][g][h] = ([]); if(!WorldGrid[a][b][c][d][e][f][g][h][i]) WorldGrid[a][b][c][d][e][f][g][h][i] = ([]); if(unset && sizeof(WorldGrid[a][b][c][d][e][f][g][h][i])){ if(debugging){ tc("Unsetting: "+identify(WorldGrid[a][b][c][d][e][f][g][h][i]),"red"); } WorldGrid[a][b][c][d][e][f][g][h][i] = 0; return 1; } if(sizeof(WorldGrid[a][b][c][d][e][f][g][h][i]) || sizeof(this_object()->GetCoordinates(coord))){ if(debugging) tc("SetGrid coord "+coord+ " is already "+ identify(WorldGrid[a][b][c][d][e][f][g][h][i])); return WorldGrid[a][b][c][d][e][f][g][h][i]; } else { if(global_manual || validate_last_room(room, player)){ if(debugging) tc("Setting coord "+coord+ " as "+room, "green"); MAP_D->RemoveCache(coord); global_manual = 0; WorldGrid[a][b][c][d][e][f][g][h][i] = ([ "room" : room, "coord" : coord ]); } return WorldGrid[a][b][c][d][e][f][g][h][i]; } } mixed GetGrid(string str){ mixed room, a, b, c, d, e, f, g, h, i, j, k, l, m, n; string coord=str; int p, q,x,y,z; mixed xarr, yarr, zarr; sscanf(coord,"%d,%d,%d",x,y,z); xarr = GenerateNames(x); yarr = GenerateNames(y); zarr = GenerateNames(z); a = xarr[0]; b = xarr[1]; c = xarr[2]; d = yarr[0]; e = yarr[1]; f = yarr[2]; g = zarr[0]; h = zarr[1]; i = zarr[2]; if(!WorldGrid[a] || !WorldGrid[a][b] || !WorldGrid[a][b][c] || !WorldGrid[a][b][c][d] || !WorldGrid[a][b][c][d][e] || !WorldGrid[a][b][c][d][e][f] || !WorldGrid[a][b][c][d][e][f][g] || !WorldGrid[a][b][c][d][e][f][g][h] || !WorldGrid[a][b][c][d][e][f][g][h][i]){ if(debugging) tc("No joy for "+str,"red"); return ([]); } if(debugging) tc("Joy! "+str+" is "+ identify(WorldGrid[a][b][c][d][e][f][g][h][i]),"white"); return copy(WorldGrid[a][b][c][d][e][f][g][h][i]); } int UnSetRoom(object arg_ob){ string creator, name, prefix, room_name; string grid; object ob; if(this_player() && adminp(this_player())){ ob = arg_ob; } else{ ob = previous_object(); } name = base_name(ob); grid = this_object()->GetCoordinates(ob); if(grid && grid != "0,0,0"){ MAP_D->RemoveCache(grid); SetGrid(name, grid, this_player(), 1); } prefix = path_prefix(name); room_name = last_string_element(name, "/"); if(WorldMap[prefix] && WorldMap[prefix][room_name]){ WorldMap[prefix][room_name] = 0; } if(sscanf(name,"/realms/%s/workroom",creator)){ Workrooms[creator] = 0; } return 1; } varargs int SetRoom(object arg_ob, object player, string manual){ string last_str, creator, name, prefix, room_name, coord; mapping tmpexits, backup_direction, TmpMap = ([]); object ob; if(this_player() && adminp(this_player())){ ob = arg_ob; } else{ ob = previous_object(); } if(clonep(ob)){ return 0; } //tc("ob: "+identify(ob)); if(!(last_str = player->GetProperty("LastLocation"))){ //tc("fail 0"); return 0; } name = base_name(ob); prefix = path_prefix(name); /* Still need to figure out exclusions for * an island or continent perimeter :( */ if(prefix == "/domains/town/virtual/surface"){ return 0; } room_name = last_string_element(name, "/"); if(!sizeof(WorldMap)){ if(name == ROOM_FURNACE){ return 0; } } if(!manual && WorldMap[prefix] && WorldMap[prefix][room_name]){ //tc("hmm"); if(StrCoord(WorldMap[prefix][room_name]["coords"]) == "0,0,0" && name != ROOM_ZERO){ //tc("HMM!"); UnSetRoom(ob); } else{ //tc("fail 1"); return 0; } } sscanf(name,"/realms/%s/workroom",creator); foreach(string element in unsafes){ if(!strsrch(last_str, element)){ if(strsrch(name, element) && !creator) //tc("fail 2"); return 0; } } if(!WorldMap[prefix]){ if(debugging) tc("Creating WorldMap["+identify(prefix)+"]","yellow"); WorldMap[prefix] = ([]); } if(!WorldMap[prefix][room_name]){ if(debugging) tc("Creating WorldMap["+identify(prefix)+"]"+ "["+identify(room_name)+"]","cyan"); WorldMap[prefix][room_name] = ([ "date" : time(), "coords" : ([ "x" : 0, "y" : 0, "z" : 0 ]), "exits" : ob->GetExitMap(), ]); } if(debugging){ } if(creator){ int x,y,z,next = sizeof(Workrooms); if(Workrooms[creator]){ return 1; } x = 1000000000; y = 1000000000; z = -1000000000; x += ( next * 10000 ); manual = x+","+y+","+z; Workrooms[creator] = ([ "grid" : manual, "coords" : ([ "x" : x, "y" :y, "z" : z ]), "time" : time(), "number" : next ]); } if(manual){ int res, x, y, z; res = sscanf(manual,"%d,%d,%d",x,y,z); if(res == 3){ if(debugging) tc("Setting manually.","red"); WorldMap[prefix][room_name]["coords"] = ([ "x" : x, "y" :y, "z" : z ]); global_manual = 1; SetGrid(name, manual, player); return 1; } } if(ob->GetVirtual() && WorldMap[prefix]) TmpMap = WorldMap[prefix]; // && (!WorldMap[prefix][room_name] || //!WorldMap[prefix][room_name]["date"])) TmpMap = WorldMap[prefix]; if( !(backup_direction = validate_last_room(name, player)) || sizeof(TmpMap)){ int a,b,c; int a2,b2,c2; int x,y,z; int x2,y2,z2; int xd,yd,zd; //tc("sizeof TmpMap: "+sizeof(TmpMap)); foreach(mixed key, mixed val in TmpMap){ //tc("key: "+identify(key)+", cal: "+identify(val),"white"); if(val){ if(sscanf(key,"%d,%d,%d",a,b,c) != 3){ if(sscanf(key,"%d,%d",a,b) != 2) continue; else c = 0; } if(!val["coords"]) continue; else { x = val["coords"]["x"]; y = val["coords"]["y"]; z = val["coords"]["z"]; } if(!x && !y && !z){ map_delete(TmpMap,key); continue; } else break; } else map_delete(TmpMap,key); } if(!undefinedp(a)){ string roomname = last_string_element(base_name(ob),"/"); if(sscanf(roomname,"%d,%d,%d",a2,b2,c2) != 3){ if(sscanf(roomname,"%d,%d",a2,b2) != 2){ //tc("fail 3"); return 0; } else c2 = 0; } xd = a - a2; yd = b - b2; zd = c - c2; x2 = x - xd; y2 = y - yd; z2 = z - zd; //tc("I am "+roomname); //tc("I found "+a+","+b+","+c); //tc("which is "+x+","+y+","+z); //tc("different by "+xd+","+yd+","+zd); //tc("meaning I am "+x2+","+y2+","+z2); WorldMap[prefix][room_name] = ([]); WorldMap[prefix][room_name]["coords"] = ([ "x" : x2, "y" :y2, "z" : z2 ]); global_manual = 1; manual = x2+","+y2+","+z2; SetGrid(name, manual, player); return 1; } else { //tc(":("); } if(debugging) tc("Unknown origin. Not mapping.","red"); if(WorldMap[prefix] && WorldMap[prefix][room_name] && StrCoord(WorldMap[prefix][room_name]["coords"]) == "0,0,0"){ WorldMap[prefix][room_name] = 0; } if(!creator) return 0; } tmpexits = WorldMap[prefix][room_name]["exits"]; if(!sizeof(tmpexits) || member_array(player->GetProperty("LastLocation"), values(tmpexits)) == -1){ if(debugging) tc("USING BACKUP DIRECTION: "+identify(backup_direction),"red"); tmpexits = backup_direction; } else { if(debugging){ tc("Using tmpexits from WorldMap[\""+prefix+"\"][\""+ room_name+"\"] which is: "+identify(WorldMap[prefix][room_name]["exits"]),"white"); } } if(!mapp(tmpexits)) tmpexits = ([]); if(debugging) tc("tmpexits: "+identify(tmpexits),"white"); foreach(string key, mixed val in tmpexits){ string sub_pre = path_prefix(val); string sub_name = last_string_element(val, "/"); int breakout; if(member_array(key, cards) == -1) continue; if(debugging){ tc("sub_pre: "+sub_pre); tc("sub_name: "+sub_name); if(WorldMap[sub_pre] && WorldMap[sub_pre][sub_name]) tc("WorldMap["+identify(sub_pre)+"]["+identify(sub_name)+ "]: "+identify(WorldMap[sub_pre][sub_name])); tc("prefix: "+prefix,"yellow"); tc("room_name: "+room_name,"yellow"); if(WorldMap[prefix] && WorldMap[prefix][room_name]) tc("WorldMap["+identify(prefix)+"]["+identify(room_name)+ "]: "+identify(WorldMap[prefix][room_name]),"yellow"); } if(WorldMap[sub_pre] && WorldMap[sub_pre][sub_name]){ last_exit = key; switch(key){ case "north" : WorldMap[prefix][room_name]["coords"]["x"] = WorldMap[sub_pre][sub_name]["coords"]["x"]; WorldMap[prefix][room_name]["coords"]["y"] = WorldMap[sub_pre][sub_name]["coords"]["y"] - 1; WorldMap[prefix][room_name]["coords"]["z"] = WorldMap[sub_pre][sub_name]["coords"]["z"]; breakout = 1; break; case "south" : WorldMap[prefix][room_name]["coords"]["x"] = WorldMap[sub_pre][sub_name]["coords"]["x"]; WorldMap[prefix][room_name]["coords"]["y"] = WorldMap[sub_pre][sub_name]["coords"]["y"] + 1; WorldMap[prefix][room_name]["coords"]["z"] = WorldMap[sub_pre][sub_name]["coords"]["z"]; breakout = 1; break; case "east" : WorldMap[prefix][room_name]["coords"]["x"] = WorldMap[sub_pre][sub_name]["coords"]["x"] - 1; WorldMap[prefix][room_name]["coords"]["y"] = WorldMap[sub_pre][sub_name]["coords"]["y"]; WorldMap[prefix][room_name]["coords"]["z"] = WorldMap[sub_pre][sub_name]["coords"]["z"]; breakout = 1; break; case "west" : WorldMap[prefix][room_name]["coords"]["x"] = WorldMap[sub_pre][sub_name]["coords"]["x"] + 1; WorldMap[prefix][room_name]["coords"]["y"] = WorldMap[sub_pre][sub_name]["coords"]["y"]; WorldMap[prefix][room_name]["coords"]["z"] = WorldMap[sub_pre][sub_name]["coords"]["z"]; breakout = 1; break; case "northeast" : WorldMap[prefix][room_name]["coords"]["x"] = WorldMap[sub_pre][sub_name]["coords"]["x"] - 1; WorldMap[prefix][room_name]["coords"]["y"] = WorldMap[sub_pre][sub_name]["coords"]["y"] - 1; WorldMap[prefix][room_name]["coords"]["z"] = WorldMap[sub_pre][sub_name]["coords"]["z"]; breakout = 1; break; case "northwest" : WorldMap[prefix][room_name]["coords"]["x"] = WorldMap[sub_pre][sub_name]["coords"]["x"] + 1; WorldMap[prefix][room_name]["coords"]["y"] = WorldMap[sub_pre][sub_name]["coords"]["y"] - 1; WorldMap[prefix][room_name]["coords"]["z"] = WorldMap[sub_pre][sub_name]["coords"]["z"]; breakout = 1; break; case "southeast" : WorldMap[prefix][room_name]["coords"]["x"] = WorldMap[sub_pre][sub_name]["coords"]["x"] - 1; WorldMap[prefix][room_name]["coords"]["y"] = WorldMap[sub_pre][sub_name]["coords"]["y"] + 1; WorldMap[prefix][room_name]["coords"]["z"] = WorldMap[sub_pre][sub_name]["coords"]["z"]; breakout = 1; break; case "southwest" : WorldMap[prefix][room_name]["coords"]["x"] = WorldMap[sub_pre][sub_name]["coords"]["x"] + 1; WorldMap[prefix][room_name]["coords"]["y"] = WorldMap[sub_pre][sub_name]["coords"]["y"] + 1; WorldMap[prefix][room_name]["coords"]["z"] = WorldMap[sub_pre][sub_name]["coords"]["z"]; breakout = 1; break; case "up" : WorldMap[prefix][room_name]["coords"]["x"] = WorldMap[sub_pre][sub_name]["coords"]["x"]; WorldMap[prefix][room_name]["coords"]["y"] = WorldMap[sub_pre][sub_name]["coords"]["y"]; WorldMap[prefix][room_name]["coords"]["z"] = WorldMap[sub_pre][sub_name]["coords"]["z"] - 1; breakout = 1; break; case "down" : WorldMap[prefix][room_name]["coords"]["x"] = WorldMap[sub_pre][sub_name]["coords"]["x"]; WorldMap[prefix][room_name]["coords"]["y"] = WorldMap[sub_pre][sub_name]["coords"]["y"]; WorldMap[prefix][room_name]["coords"]["z"] = WorldMap[sub_pre][sub_name]["coords"]["z"] + 1; breakout = 1; break; } } if(breakout) break; } coord = WorldMap[prefix][room_name]["coords"]["x"]+","+ WorldMap[prefix][room_name]["coords"]["y"]+","+ WorldMap[prefix][room_name]["coords"]["z"]; if(debugging){ tc("SetRoom About to send: SetGrid("+identify(name)+", "+ identify(coord)+", "+identify(player)+")"); } SetGrid(name, coord, player); return 1; } string GetCoordinates(mixed ob){ string name, prefix, room_name, ret; int err; if(clonep(ob)){ object env = room_environment(ob); if(env && !clonep(env)) ob = env; else return ""; } name = base_name(ob); prefix = path_prefix(name); room_name = last_string_element(name, "/"); if(!WorldMap[prefix] || !WorldMap[prefix][room_name]){ return ""; } ret = WorldMap[prefix][room_name]["coords"]["x"]+","+ WorldMap[prefix][room_name]["coords"]["y"]+","+ WorldMap[prefix][room_name]["coords"]["z"]; return ret; } mapping GetCoordinateMap(mixed ob){ string name = base_name(ob); string prefix = path_prefix(name); string room_name = last_string_element(name, "/"); if(!WorldMap[prefix] || !WorldMap[prefix][room_name]){ return ([]); } return ([ "x" : WorldMap[prefix][room_name]["coords"]["x"], "y" : WorldMap[prefix][room_name]["coords"]["y"], "z" : WorldMap[prefix][room_name]["coords"]["z"], ]); } mixed GetRoom(mixed ob){ string name, prefix, room_name; if(clonep(ob)) return 0; name = base_name(ob); prefix = path_prefix(name); room_name = last_string_element(name, "/"); if(!WorldMap[prefix]) return "No such prefix."; if(!WorldMap[prefix][room_name]) return "No such room."; return ([ name : copy(WorldMap[prefix][room_name]) ]); }