/* /std/room/exits.c * from Nightmare IV * handles players exiting from rooms * created by Descartes of Borg 940711 */ #include <std.h> #include <rooms.h> #include "exits.h" #define MAX_TRACKS 10 #define MAX_SCENTS 10 #define TRACK_FADE_TIME 120 static private mapping __Exits, __Enters; static private mapping __Tracks, __TrackFaded, __Scents, __ScentFaded; static void create() { __Exits = ([]); __Enters = ([]); __Tracks = ([]); __TrackFaded = ([]); __Scents = ([]); __ScentFaded = ([]); } void init() { add_action("cmd_go", "go"); add_action("cmd_enter", "enter"); } int cmd_go(string str) { if((int)this_player()->query_paralyzed()) return notify_fail("You are unable to move.\n"); if(!__Exits[str]) return notify_fail("You go nowhere at all.\n"); if(__Exits[str]["pre"] && !((int)(*__Exits[str]["pre"])(str))) return 1; add_track(this_player(), str); add_scent(this_player(), str); this_player()->move_player(__Exits[str]["room"], str); if(__Exits[str]["post"]) (*__Exits[str]["post"])(str); return 1; } int cmd_enter(string str) { if((int)this_player()->query_paralyzed()) return notify_fail("You are unable to move.\n"); if(!__Enters[str]) return notify_fail("You cannot enter that.\n"); if(__Enters[str]["pre"] && !((int)(*__Enters[str]["pre"])(str))) return 1; add_track(this_player(), str); add_scent(this_player(), str); this_player()->move_player(__Enters[str]["room"], str); if(__Enters[str]["post"]) (*__Enters[str]["post"])( str); return 1; } void reinitiate() { object *obs; if(!sizeof(obs = all_inventory(this_object()))) return; obs->move(ROOM_VOID); obs->move(this_object()); } void set_exits(mapping mp) { string *cles; int i; __Exits = ([]); i = sizeof(cles = keys(mp)); while(i--) __Exits[cles[i]] = ([ "room" : mp[cles[i]] ]); } varargs void add_exit(string dir, string dest, function pre, function post) { if(!stringp(dir)) error("Bad argument 1 to add_exit().\n"); if(!stringp(dest)) error("Bad argument 2 to add_exit().\n"); __Exits[dir] = ([ "room" : dest ]); if(pre) __Exits[dir]["pre"] = pre; if(post) __Exits[dir]["post"] = post; reinitiate(); } void remove_exit(string dir) { if(__Exits[dir]) map_delete(__Exits, dir); reinitiate(); } string query_exit(string str) { if(!__Exits[str]) return 0; else return __Exits[str]["room"]; } string *query_exits() { return keys(__Exits); } void set_enters(mapping mp) { string *cles; int i; __Enters = ([]); i = sizeof(cles = keys(mp)); while(i--) __Enters[cles[i]] = ([ "room" : mp[cles[i]] ]); } varargs void add_enter(string dir, string dest, function pre, function post) { if(!stringp(dir)) error("Bad argument 1 to add_enter().\n"); if(!stringp(dest)) error("Bad argument 2 to add_enter().\n"); __Enters[dir] = ([ "room" : dest ]); if(pre) __Enters[dir]["pre"] = pre; if(post) __Enters[dir]["post"] = post; reinitiate(); } void remove_enter(string dir) { if(__Enters[dir]) map_delete(__Enters, dir); reinitiate(); } string query_enter(string dir) { if(!__Enters[dir]) return 0; else return __Enters[dir]["room"]; } string *query_enters() { return keys(__Enters); } string query_direction(string dest) { string *cles; int i; i = sizeof(cles = keys(__Exits)); while(i--) if(__Exits[cles[i]]["room"] == dest) return "go "+cles[i]; i = sizeof(cles = keys(__Enters)); while(i--) if(__Enters[cles[i]]["room"] == dest) return "enter "+cles[i]; return 0; } void add_track(object ob, string str) { string res; if(sizeof(__Tracks) > MAX_TRACKS) { __Tracks = ([]); __TrackFaded = ([]); } if(!(res = (string)ob->query_race())) return; if(!__TrackFaded[res]) __TrackFaded[res] = time(); if(!__Tracks[res]) __Tracks[res] = 0; __Tracks[res]++; } int query_track(string res) { if(!__Tracks[res]) return 0; else __Tracks[res] -= (time() - __TrackFaded[res])/TRACK_FADE_TIME; __TrackFaded[res] = time(); if(__Tracks[res] < 1) { map_delete(__Tracks, res); map_delete(__TrackFaded, res); } return __Tracks[res]; } mapping query_tracks() { mapping tmp; string *cles; int i; tmp = allocate_mapping(i = sizeof(cles = keys(__Tracks))); while(i--) tmp[cles[i]] = query_track(cles[i]); return tmp; } void add_scent(object ob, string str) { string nom; if(sizeof(__Scents) > MAX_SCENTS) { __Scents = ([]); __ScentFaded = ([]); } if(!(nom = (string)ob->query_name())) return; if(!__ScentFaded[nom]) __ScentFaded[nom] = time(); if(!__Scents[nom]) __Scents[nom] = 0; __Scents[nom] += (int)ob->query_scent(); } int query_scent(string str) { if(!__Scents[str]) return 0; else __Scents[str] -= (time() - __ScentFaded[str]); __ScentFaded[str] = time(); if(__Scents[str] < 1) map_delete(__Scents, str); return __Scents[str]; } mapping query_scents() { mapping tmp; string *cles; int i; tmp = allocate_mapping( i = sizeof( cles = keys(__Scents))); while(i--) tmp[cles[i]] = query_scent(cles[i]); return tmp; }