/* Do not remove the headers from this file! see /USAGE for more info. */ /* ** openable.c (M_OPENABLE) ** ** This object provides base open/close capabilities for an OBJ ** ** //### doc forthcoming... */ #include <hooks.h> #include <flags.h> /* ** From OBJ::description */ void set_in_room_desc(string arg); string the_short(); varargs void add_adj(); varargs void remove_adj(); private string open_msg = "$N $vopen a $o."; private string close_msg = "$N $vclose a $o."; private string open_desc; private string closed_desc; mixed call_hooks(string, int); void add_hook(string, function); void resync_visibility(); int test_flag(int which); void assign_flag(int which, int state); //:FUNCTION do_on_open // Called from open_with() so modules that inherit from M_OPENABLE // Don't have to catch the "open" hook. void do_on_open() { /* Overload this later */ } //:FUNCTION do_on_close // Called from close() so modules that inherit from M_OPENABLE // Don't have to catch the "close" hook. void do_on_close() { /* Overload this later */ } string opened_attributes() { return "(open)"; } int openable() { return 1; } int query_closed() { return !test_flag(F_OPEN); /* closed; */ } void set_closed(int x) { assign_flag(F_OPEN, !x); /* Commenting this out for now -- Marroc remove_adj("closed", "open"); if (x) add_adj("closed"); else add_adj("open"); */ if (open_desc && !x) set_in_room_desc(open_desc); if (closed_desc && x) set_in_room_desc(closed_desc); /* our inventory visibility probably just changed. */ resync_visibility(); } void set_open_desc( string desc ) { open_desc = desc; if (!query_closed()) set_in_room_desc(desc); } void set_closed_desc( string desc ) { closed_desc = desc; if (query_closed()) set_in_room_desc(desc); } string query_closed_desc() { return closed_desc; } string query_open_desc() { return open_desc; } void set_open_msg(string new_msg) { open_msg = new_msg; } void set_close_msg(string new_msg) { close_msg = new_msg; } varargs int open_with(object with) { string ex; if (!query_closed()) { write("It is already open.\n"); return 1; } //:HOOK prevent_open //A yes/no/error hook which can prevent an object from being opened. ex = call_hooks("prevent_open", HOOK_YES_NO_ERROR); if (!ex) ex = capitalize(the_short() + " doesn't seem to want to open.\n"); if (stringp(ex)) { write(ex); return 1; } this_body()->simple_action(open_msg, this_object()); set_closed(0); if (ex = inv_list(all_inventory())) { write("Inside, you find:\n"+ex); } do_on_open(); //:HOOK open //called when an object is opened. The return value is ignored. call_hooks("open", HOOK_IGNORE); return 1; } mixed do_close() { mixed tmp; if (query_closed()) { write("It is already closed.\n"); return 1; } //:HOOK prevent_close //A yes/no/error hook that can prevent an object from being closed tmp = call_hooks("prevent_close", HOOK_YES_NO_ERROR); if (!tmp) tmp = capitalize(the_short()) + " doesn't seem to want to close.\n"; if (stringp(tmp)) return tmp; this_body()->simple_action(close_msg, this_object()); set_closed(1); do_on_close(); //:HOOK close //called when an object is closed. The return value is ignored. call_hooks("close", HOOK_IGNORE); return 1; } int is_open() { return !query_closed(); } /* Verb interaction */ mixed direct_open_obj(object ob) { object where = environment(this_object()); if(where != this_body() && where != environment(this_body()) ) return "#You do not have that.\n"; if (!query_closed()) return "It is already open.\n"; return 1; } mixed direct_close_obj(object ob) { object where = environment(this_object()); if (where != this_body() && where!= environment(this_body()) ) return "#You do not have that.\n"; if (query_closed()) return "It is already closed.\n"; return 1; } string extra_long_stuff() { return capitalize(the_short()) + " is " + (query_closed() ? "closed" : "open") + ".\n"; } // You should do this, or call set_closed() when you create an openable, // so that the proper adjective gets initialized. void internal_setup() { set_closed(1); add_hook("extra_long", (: extra_long_stuff :)); add_hook("prevent_look_in", (: query_closed() ? "It is closed.\n" : (mixed)1 :)); } mapping lpscript_attributes() { return ([ "closed" : ({ LPSCRIPT_INT, "setup", "set_closed" }), ]); }