MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame^] | 1 | // MorgenGrauen MUDlib |
| 2 | // |
| 3 | // player/moving.c -- player moving |
| 4 | // |
| 5 | // $Id: moving.c 9434 2016-01-12 12:34:05Z Zesstra $ |
| 6 | #pragma strong_types |
| 7 | #pragma save_types |
| 8 | #pragma range_check |
| 9 | #pragma no_clone |
| 10 | #pragma pedantic |
| 11 | |
| 12 | inherit "std/living/moving"; |
| 13 | |
| 14 | #define NEED_PROTOTYPES |
| 15 | #include <player/base.h> |
| 16 | #include <living/description.h> |
| 17 | #include <player/viewcmd.h> |
| 18 | #include <player.h> |
| 19 | #undef NEED_PROTOTYPES |
| 20 | |
| 21 | #include <thing/properties.h> |
| 22 | #include <properties.h> |
| 23 | #include <language.h> |
| 24 | #include <defines.h> |
| 25 | #include <moving.h> |
| 26 | #include <wizlevels.h> |
| 27 | #include <events.h> |
| 28 | #include <pathd.h> |
| 29 | |
| 30 | private nosave string *connections; |
| 31 | |
| 32 | public void create() |
| 33 | { |
| 34 | SetProp( P_MSGIN, "kommt an" ); |
| 35 | SetProp( P_MSGOUT, "geht" ); |
| 36 | SetProp( P_MMSGIN, "tritt aus einer Schwefelwolke" ); |
| 37 | SetProp( P_MMSGOUT, "verschwindet mit Knall und Schwefelduft" ); |
| 38 | Set( P_MSGIN, SAVE, F_MODE ); |
| 39 | Set( P_MSGOUT, SAVE, F_MODE ); |
| 40 | Set( P_MMSGIN, SAVE, F_MODE ); |
| 41 | Set( P_MMSGOUT, SAVE, F_MODE ); |
| 42 | connections = ({}); |
| 43 | |
| 44 | ::create(); |
| 45 | } |
| 46 | |
| 47 | |
| 48 | static mixed _to_remove( object ob ) |
| 49 | { |
| 50 | return ob->QueryProp(P_AUTOLOADOBJ) || ob->QueryProp(P_NODROP); |
| 51 | } |
| 52 | |
| 53 | |
| 54 | // autoload and nodrop object may not fall into the environment |
| 55 | static varargs int remove( int silent ) |
| 56 | { |
| 57 | object* dest_obj = filter( deep_inventory(ME) - ({0}), "_to_remove" ); |
| 58 | filter_objects( dest_obj, "remove" ); |
| 59 | filter( dest_obj - ({0}), #'destruct ); |
| 60 | |
| 61 | if ( !QueryProp(P_INVIS) && !silent ) |
| 62 | catch( say( name(WER, 1) + " verlaesst diese Welt.\n", ME );publish ); |
| 63 | |
| 64 | if ( ME && !silent ) |
| 65 | tell_object( ME, "Bis bald!\n" ); |
| 66 | |
| 67 | // Im Falle des Resets ist previous_object() == ME, aber |
| 68 | // previous_object(0) == 0. Ausserdem ist der Caller-Stack leer. Also |
| 69 | // schauen, ob es ein PO gibt, was nicht gleich dem Objekt selber ist, TI |
| 70 | // pruefen und |
| 71 | if ( this_interactive() != ME |
| 72 | && objectp(previous_object()) && previous_object() != ME |
| 73 | && object_name(previous_object())[0..7] != "/secure/" |
| 74 | && member(object_name(ME), ':') > -1 ) |
| 75 | log_file( "PLAYERDEST", |
| 76 | sprintf( "%s: %O vernichtet von PO %O, TI %O, TP %O\n", |
| 77 | dtime(time()), ME, previous_object(), |
| 78 | this_interactive(), this_player() ) ); |
| 79 | |
| 80 | // Logout-event ausloesen |
| 81 | EVENTD->TriggerEvent(EVT_LIB_LOGOUT, ([ |
| 82 | E_OBJECT: ME, |
| 83 | E_PLNAME: getuid(ME), |
| 84 | E_ENVIRONMENT: environment() ]) ); |
| 85 | |
| 86 | return ::remove(); |
| 87 | } |
| 88 | |
| 89 | public string NotifyDestruct(object caller) { |
| 90 | |
| 91 | if (previous_object() != master() |
| 92 | || object_name(this_object()) == __FILE__[..<3]) |
| 93 | return 0; |
| 94 | |
| 95 | // Das Zerstoeren von Spielern wird ggf. geloggt. |
| 96 | if ( objectp(caller) && caller != this_object() |
| 97 | && getuid(caller) != ROOTID ) { |
| 98 | log_file( "PLAYERDEST", |
| 99 | sprintf( "%s: %O VERNICHTET von PO %O, TI %O, TP %O\n", |
| 100 | dtime(time()), this_object(), caller, |
| 101 | this_interactive(), this_player() ) ); |
| 102 | } |
| 103 | // erstmal nix weiter tun, destruct gestatten. |
| 104 | return 0; |
| 105 | } |
| 106 | |
| 107 | protected int PreventMove(object dest, object oldenv, int method) { |
| 108 | string hcroom; |
| 109 | mixed res; |
| 110 | |
| 111 | // gestorbene HC-Spieler duerfen nicht mehr aus dem Nirvana, nicht umgehbar |
| 112 | // durch M_NOCHECK |
| 113 | if ( interactive(ME) && (query_hc_play()>1) ) { |
| 114 | if (objectp(dest)) |
| 115 | hcroom=object_name(dest); |
| 116 | if (sizeof(hcroom)<7 || hcroom[0..5]!="/room/") { |
| 117 | return ME_CANT_BE_INSERTED; |
| 118 | } |
| 119 | } |
| 120 | |
| 121 | // alle anderen Pruefungen sind mit M_NOCHECK egal. |
| 122 | if ( (method & M_NOCHECK) ) |
| 123 | return(::PreventMove(dest,oldenv,method)); |
| 124 | |
| 125 | // Spieler duerfen in Raeume mit gesetztem P_NO_PLAYERS nicht hinein |
| 126 | if ( dest->QueryProp(P_NO_PLAYERS) && interactive(ME) && |
| 127 | !(method & M_NOCHECK) && |
| 128 | !IS_LEARNER(ME) && (!stringp(res = QueryProp(P_TESTPLAYER)) |
| 129 | || !IS_LEARNER( lower_case(res) )) ){ |
| 130 | tell_object( ME, "Da darfst Du als Spieler nicht hin.\n" ); |
| 131 | return ME_NOT_ALLOWED; |
| 132 | } |
| 133 | |
| 134 | return ::PreventMove(dest,oldenv,method); |
| 135 | } |
| 136 | |
| 137 | // Fuck. Ausnahmsweise wegen VC brauch ich nen anderes BLUE_NAME |
| 138 | #define OLD_BLUE_NAME(ob) (explode(object_name(ob),"#")[0]) |
| 139 | // Krams nach dem Move machen und nebenbei zum Ueberschreiben. |
| 140 | protected void NotifyMove(object dest, object oldenv, int method) { |
| 141 | |
| 142 | // erstmal ggf. Rauminhalt an Spieler ausgeben. |
| 143 | if ( interactive(ME) && !(method & M_NO_SHOW) ) { |
| 144 | if (!CannotSee(1)) |
| 145 | tell_object( ME, "" + env_descr(1) ); |
| 146 | else if ( QueryProp(P_BRIEF) < 2 ) |
| 147 | tell_object( ME, "Finsternis.\n" ); |
| 148 | } |
| 149 | |
| 150 | //dann geerbten Kram machen |
| 151 | ::NotifyMove(dest,oldenv,method); |
| 152 | |
| 153 | // Schlussendlich noch fuer den PathD bewegung protokollieren. |
| 154 | // (dest nicht geprueft, da ein Spieler nicht ausserhalb jedes Env bewegt |
| 155 | // werden kann) |
| 156 | if ( interactive() && environment() && query_verb() && objectp(oldenv)) { |
| 157 | connections += ({ ({ OLD_BLUE_NAME(oldenv), OLD_BLUE_NAME(dest), |
| 158 | query_verb() + " " + (_unparsed_args(2) || ""), |
| 159 | method, dest->QueryProp(P_PARA) }) }); |
| 160 | |
| 161 | if ( sizeof(connections) > 50 |
| 162 | && find_call_out("flush_connections") == -1 ) |
| 163 | call_out( "flush_connections", 0, connections ); |
| 164 | } |
| 165 | } |
| 166 | |
| 167 | public void flush_connections() { |
| 168 | catch(PATHD->add_paths(connections);publish); |
| 169 | connections = ({}); |
| 170 | } |
| 171 | |
| 172 | /*** Query-Methoden fuer Froesche... ;^) ***/ |
| 173 | static string _query_msgin() |
| 174 | { |
| 175 | return QueryProp(P_FROG) ? "huepft herein" : Query(P_MSGIN); |
| 176 | } |
| 177 | |
| 178 | |
| 179 | static string _query_msgout() |
| 180 | { |
| 181 | return QueryProp(P_FROG) ? "huepft" : Query(P_MSGOUT); |
| 182 | } |