| // MorgenGrauen MUDlib |
| // |
| // player/moving.c -- player moving |
| // |
| // $Id: moving.c 9434 2016-01-12 12:34:05Z Zesstra $ |
| #pragma strong_types |
| #pragma save_types |
| #pragma range_check |
| #pragma no_clone |
| #pragma pedantic |
| |
| inherit "std/living/moving"; |
| |
| #define NEED_PROTOTYPES |
| #include <player/base.h> |
| #include <living/description.h> |
| #include <player/viewcmd.h> |
| #include <player.h> |
| #undef NEED_PROTOTYPES |
| |
| #include <thing/properties.h> |
| #include <properties.h> |
| #include <language.h> |
| #include <defines.h> |
| #include <moving.h> |
| #include <wizlevels.h> |
| #include <events.h> |
| #include <pathd.h> |
| |
| private nosave string *connections; |
| |
| public void create() |
| { |
| SetProp( P_MSGIN, "kommt an" ); |
| SetProp( P_MSGOUT, "geht" ); |
| SetProp( P_MMSGIN, "tritt aus einer Schwefelwolke" ); |
| SetProp( P_MMSGOUT, "verschwindet mit Knall und Schwefelduft" ); |
| Set( P_MSGIN, SAVE, F_MODE ); |
| Set( P_MSGOUT, SAVE, F_MODE ); |
| Set( P_MMSGIN, SAVE, F_MODE ); |
| Set( P_MMSGOUT, SAVE, F_MODE ); |
| connections = ({}); |
| |
| ::create(); |
| } |
| |
| |
| static mixed _to_remove( object ob ) |
| { |
| return ob->QueryProp(P_AUTOLOADOBJ) || ob->QueryProp(P_NODROP); |
| } |
| |
| |
| // autoload and nodrop object may not fall into the environment |
| static varargs int remove( int silent ) |
| { |
| object* dest_obj = filter( deep_inventory(ME) - ({0}), "_to_remove" ); |
| filter_objects( dest_obj, "remove" ); |
| filter( dest_obj - ({0}), #'destruct ); |
| |
| if ( !QueryProp(P_INVIS) && !silent ) |
| catch( say( name(WER, 1) + " verlaesst diese Welt.\n", ME );publish ); |
| |
| if ( ME && !silent ) |
| tell_object( ME, "Bis bald!\n" ); |
| |
| // Im Falle des Resets ist previous_object() == ME, aber |
| // previous_object(0) == 0. Ausserdem ist der Caller-Stack leer. Also |
| // schauen, ob es ein PO gibt, was nicht gleich dem Objekt selber ist, TI |
| // pruefen und |
| if ( this_interactive() != ME |
| && objectp(previous_object()) && previous_object() != ME |
| && object_name(previous_object())[0..7] != "/secure/" |
| && member(object_name(ME), ':') > -1 ) |
| log_file( "PLAYERDEST", |
| sprintf( "%s: %O vernichtet von PO %O, TI %O, TP %O\n", |
| dtime(time()), ME, previous_object(), |
| this_interactive(), this_player() ) ); |
| |
| // Logout-event ausloesen |
| EVENTD->TriggerEvent(EVT_LIB_LOGOUT, ([ |
| E_OBJECT: ME, |
| E_PLNAME: getuid(ME), |
| E_ENVIRONMENT: environment() ]) ); |
| |
| return ::remove(); |
| } |
| |
| public string NotifyDestruct(object caller) { |
| |
| if (previous_object() != master() |
| || object_name(this_object()) == __FILE__[..<3]) |
| return 0; |
| |
| // Das Zerstoeren von Spielern wird ggf. geloggt. |
| if ( objectp(caller) && caller != this_object() |
| && getuid(caller) != ROOTID ) { |
| log_file( "PLAYERDEST", |
| sprintf( "%s: %O VERNICHTET von PO %O, TI %O, TP %O\n", |
| dtime(time()), this_object(), caller, |
| this_interactive(), this_player() ) ); |
| } |
| // erstmal nix weiter tun, destruct gestatten. |
| return 0; |
| } |
| |
| protected int PreventMove(object dest, object oldenv, int method) { |
| string hcroom; |
| mixed res; |
| |
| // gestorbene HC-Spieler duerfen nicht mehr aus dem Nirvana, nicht umgehbar |
| // durch M_NOCHECK |
| if ( interactive(ME) && (query_hc_play()>1) ) { |
| if (objectp(dest)) |
| hcroom=object_name(dest); |
| if (sizeof(hcroom)<7 || hcroom[0..5]!="/room/") { |
| return ME_CANT_BE_INSERTED; |
| } |
| } |
| |
| // alle anderen Pruefungen sind mit M_NOCHECK egal. |
| if ( (method & M_NOCHECK) ) |
| return(::PreventMove(dest,oldenv,method)); |
| |
| // Spieler duerfen in Raeume mit gesetztem P_NO_PLAYERS nicht hinein |
| if ( dest->QueryProp(P_NO_PLAYERS) && interactive(ME) && |
| !(method & M_NOCHECK) && |
| !IS_LEARNER(ME) && (!stringp(res = QueryProp(P_TESTPLAYER)) |
| || !IS_LEARNER( lower_case(res) )) ){ |
| tell_object( ME, "Da darfst Du als Spieler nicht hin.\n" ); |
| return ME_NOT_ALLOWED; |
| } |
| |
| return ::PreventMove(dest,oldenv,method); |
| } |
| |
| // Fuck. Ausnahmsweise wegen VC brauch ich nen anderes BLUE_NAME |
| #define OLD_BLUE_NAME(ob) (explode(object_name(ob),"#")[0]) |
| // Krams nach dem Move machen und nebenbei zum Ueberschreiben. |
| protected void NotifyMove(object dest, object oldenv, int method) { |
| |
| // erstmal ggf. Rauminhalt an Spieler ausgeben. |
| if ( interactive(ME) && !(method & M_NO_SHOW) ) { |
| if (!CannotSee(1)) |
| tell_object( ME, "" + env_descr(1) ); |
| else if ( QueryProp(P_BRIEF) < 2 ) |
| tell_object( ME, "Finsternis.\n" ); |
| } |
| |
| //dann geerbten Kram machen |
| ::NotifyMove(dest,oldenv,method); |
| |
| // Schlussendlich noch fuer den PathD bewegung protokollieren. |
| // (dest nicht geprueft, da ein Spieler nicht ausserhalb jedes Env bewegt |
| // werden kann) |
| if ( interactive() && environment() && query_verb() && objectp(oldenv)) { |
| connections += ({ ({ OLD_BLUE_NAME(oldenv), OLD_BLUE_NAME(dest), |
| query_verb() + " " + (_unparsed_args(2) || ""), |
| method, dest->QueryProp(P_PARA) }) }); |
| |
| if ( sizeof(connections) > 50 |
| && find_call_out("flush_connections") == -1 ) |
| call_out( "flush_connections", 0, connections ); |
| } |
| } |
| |
| public void flush_connections() { |
| catch(PATHD->add_paths(connections);publish); |
| connections = ({}); |
| } |
| |
| /*** Query-Methoden fuer Froesche... ;^) ***/ |
| static string _query_msgin() |
| { |
| return QueryProp(P_FROG) ? "huepft herein" : Query(P_MSGIN); |
| } |
| |
| |
| static string _query_msgout() |
| { |
| return QueryProp(P_FROG) ? "huepft" : Query(P_MSGOUT); |
| } |