/* Do not remove the headers from this file! see /USAGE for more info. */ inherit M_EXIT; private nosave mixed def_dest = 0; private nosave mixed def_exit_msg = 0; private nosave mixed def_enter_msg = 0; private nosave mixed def_check = 0; private nosave mixed default_desc = 0; private nosave mapping prep_dest = ([]); private nosave mapping prep_exit_msg = ([ ]); private nosave mapping prep_enter_msg = ([ ]); private nosave mapping prep_check = ([ ]); private nosave mapping prep_desc = ([ ]); private nosave string go_verb = "go"; private nosave string base = 0; private nosave mapping prep_aliases = ([ ]); string query_go_method(); void set_default_enter_msg(mixed); void set_default_exit_msg(mixed); void alias_prep(string src, string dest) { if (!prep_dest[src]) { error(sprintf("***Preposition doesn't exist to alias from: %O", src)); } prep_dest[dest] = prep_dest[src]; prep_exit_msg[dest] = prep_exit_msg[src]; prep_enter_msg[dest] = prep_enter_msg[src]; prep_check[dest] = prep_check[src]; prep_desc[dest] = prep_desc[src]; } void setup_default_prep_aliases() { foreach (string k, string value in prep_aliases) { if (prep_dest[k] && !prep_dest[value]) { alias_prep(k, value); } } } mixed prep_default_msg(string prep) { if (stringp(prep)) return "$N $v" + query_go_method() + " " + prep + " " + this_object()->the_short() + "."; else return "$N $v" + query_go_method() + " " + this_object()->the_short() + "."; } string query_go_method() { return go_verb; } void set_go_method(string g) { go_verb = g; } mixed query_default_destination() { mixed dirs = keys(prep_dest) + query_exit_directions(0); if (def_dest == 0) if (member_array(dirs[0], query_exit_directions(0)) != -1) return query_exit_destination(dirs[0], base); else return eval_dest(prep_dest[dirs[0]], 0, base); return eval_dest(def_dest, 0, base); } mixed query_default_exit_msg() { return evaluate(def_exit_msg); } mixed query_default_enter_msg() { return evaluate(def_enter_msg); } void set_default_destination(mixed arg) { def_dest = arg; def_check = 1; if ( def_exit_msg == 0 ) set_default_exit_msg( (: prep_default_msg :) ); if ( def_enter_msg == 0 ) set_default_enter_msg( (: prep_default_msg :) ); } void set_default_exit_msg(mixed arg) { def_exit_msg = arg; } void set_default_enter_msg(mixed arg) { def_enter_msg = arg; } void set_default_check(mixed arg) { def_check = arg; } void set_prep_exit_msg(string prep, mixed msg) { prep_exit_msg[prep] = msg; } void set_prep_enter_msg(string prep, mixed msg) { prep_enter_msg[prep] = msg; } void set_prep_check(string prep, mixed check) { prep_check[prep] = check; } //needed so that "enter door" calls the exit check in direct_go_word_obj() void set_exit_check(string dir, function f) { ::set_exit_check(dir, f); set_prep_check(dir, f); } void set_prep_description(string prep, mixed desc) { prep_desc[prep] = desc; } void add_prep(string prep, mixed dest) { if (stringp(dest) && dest[0] == '#') prep_check[prep] = dest[1..]; else prep_check[prep] = 1; prep_dest[prep] = dest; prep_desc[prep] = default_desc; prep_exit_msg[prep] = (: prep_default_msg :); prep_enter_msg[prep] = (: prep_default_msg :); } void set_preps(mapping p) { mixed key; if (mapp(p)) { prep_dest += p; foreach (key in keys(p)) { if (stringp(p[key]) && p[key][0] == '#') prep_check[key] = p[key][1..]; else prep_check[key] = 1; prep_desc[key] = default_desc; prep_exit_msg[key] = (: prep_default_msg :); prep_enter_msg[key] = prep_exit_msg[key]; } } } mixed query_prep_exit_msg(string prep) { prep = PREPOSITION_D->translate_preposition(prep); return evaluate(prep_exit_msg[prep], prep); } mixed query_prep_enter_msg(string prep) { prep = PREPOSITION_D->translate_preposition(prep); return evaluate(prep_enter_msg[prep], prep); } mixed query_prep_description(string prep) { prep = PREPOSITION_D->translate_preposition(prep); return evaluate(prep_desc[prep]); } mixed query_prep_destination(string prep) { prep = PREPOSITION_D->translate_preposition(prep); return eval_dest(prep_dest[prep], 0, base); } // prep_only only adds the direction to the object, // and NOT to the room.. // i.e. ("up","blah.c", 1) means that just "up"/"go up" won't work // you have to say "go up id" varargs void add_exit(mixed dir, mixed dest, int prep_only) { add_prep(dir, dest); if (!prep_only) ::add_exit(dir, dest); } mixed direct_go_word_obj(string prep) { prep = PREPOSITION_D->translate_preposition(prep); if (undefinedp(prep_dest[prep])) return "You can't " + query_go_method() + " " + prep + " that, only " + format_list(keys(prep_dest), "or") + "."; //prep and this_body() are needed because of set_exit_check() return evaluate(prep_check[prep], prep, this_body()); } mixed direct_go_wrd_obj(string prep) { // The driver calls this instead of direct_go_word_obj() for WRD // OBJ rules.. bizarre... return direct_go_word_obj(prep); } mixed direct_go_obj() { mixed dirs = keys(prep_dest); if (def_dest == 0) { switch (sizeof(dirs)) { case 0: return environment(this_object())->get_default_exit(); case 1: return direct_go_word_obj(dirs[0]); default: return "Do you want to " + query_go_method() + " " + format_list(keys(prep_dest), "or") + " that?"; } } return evaluate(def_check); } mixed direct_enter_obj() { if(query_go_method() != "enter") return 0; return direct_go_obj(); } mixed direct_climb_obj() { if(query_go_method() != "climb") return 0; return direct_go_obj(); } mixed direct_climb_wrd_obj(string prep) { if(query_go_method() != "climb") return 0; return direct_go_word_obj(prep); } mixed direct_board_obj() { if(query_go_method() != "board") return 0; return direct_go_obj(); } mixed direct_dismount_obj() { if(query_go_method() != "mount") return 0; return 1; } void propogate_exits_up() { string array dirs = query_exit_directions(1); string dir; foreach (dir in dirs) { if (member_array(dir, environment(this_object())->query_exit_directions()) == -1) environment(this_object())->add_exit(dir, this_object()); else error("*Exit already exists in room: " + dir); } dirs = query_hidden_exits(); foreach (dir in dirs) { environment(this_object())->add_hidden_exit(dir, this_object()); } } void delete_exits_up() { string array dirs = query_exit_directions(0); string dir; foreach (dir in dirs) { environment(this_object())->delete_exit(dir); } dirs = query_hidden_exits(); foreach (dir in dirs) { environment(this_object())->remove_hidden_exit(dir); environment(this_object())->delete_exit(dir); } } varargs void on_clone() { propogate_exits_up(); base = environment(this_object())->query_base(); setup_default_prep_aliases(); } void remove() { delete_exits_up(); }