moving.c-Dateireferenz

#include <hook.h>
#include <living/moving.h>
#include <living/skills.h>
#include <thing/properties.h>
#include <thing/description.h>
#include <moving.h>
#include <new_skills.h>
#include <living.h>
#include <config.h>
#include <language.h>
#include <wizlevels.h>
#include <defines.h>
Include-Abhängigkeitsdiagramm für moving.c:

gehe zum Quellcode dieser Datei

Makrodefinitionen

#define NEED_PROTOTYPES

Funktionen

public void create ()
public void AddPursuer (object ob)
public void RemovePursuer (object ob)
public void _SetPursued (object ob)
public void _RemovePursued (object ob)
private void kampfende (object en)
private int _is_learner (object pl)
protected int PreventMove (object dest, object oldenv, int method)
protected void NotifyMove (object dest, object oldenv, int method)
varargs public int move (mixed dest, int method, string direction, string textout, string textin)
public void TakeFollowers ()
varargs public int remove ()

Makro-Dokumentation

#define NEED_PROTOTYPES

Definiert in Zeile 12 der Datei moving.c.


Dokumentation der Funktionen

private int _is_learner ( object  pl  ) 

Definiert in Zeile 102 der Datei moving.c.

Benutzt IS_LEARNER.

00102                                    {
00103   return IS_LEARNER(pl); 
00104 }

public void _RemovePursued ( object  ob  ) 

Definiert in Zeile 80 der Datei moving.c.

Benutzt P_PURSUERS, Query() und Set().

00081 {
00082   mixed *pur;
00083 
00084   if (!pointerp(pur=Query(P_PURSUERS)) || pur[0]!=ob)
00085     return;
00086   pur[0]=0;
00087   pur[1]-=({0});
00088   if (!sizeof(pur[1]))
00089     pur=0;
00090   Set(P_PURSUERS,pur);
00091 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

public void _SetPursued ( object  ob  ) 

Definiert in Zeile 66 der Datei moving.c.

Benutzt ME, P_PURSUERS, Query(), RemovePursuer() und Set().

00067 {
00068   mixed *pur;
00069 
00070   if (!pointerp(pur=Query(P_PURSUERS)))
00071     pur=({0,({})});
00072   else
00073     if (objectp(pur[0]))
00074       pur[0]->RemovePursuer(ME);
00075   pur[0]=ob;
00076   pur[1]-=({0});
00077   Set(P_PURSUERS,pur);
00078 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

public void AddPursuer ( object  ob  ) 

Definiert in Zeile 36 der Datei moving.c.

Benutzt ME, P_PURSUERS, Query() und SetProp().

00037 {
00038   mixed *pur;
00039 
00040   if (!objectp(ob))
00041     return;
00042 
00043   if (!pointerp(pur=Query(P_PURSUERS)))
00044     pur=({0,({})});
00045   else
00046     if (member(pur[1],ob)!=-1)
00047       return;
00048   SetProp(P_PURSUERS,({ pur[0], pur[1]+({ob})-({0}) }));
00049   ob->_SetPursued(ME);
00050 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

public void create (  ) 

Definiert in Zeile 31 der Datei moving.c.

Benutzt H_HOOK_MOVE und offerHook().

00031                      { 
00032     offerHook(H_HOOK_MOVE,1);
00033 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

private void kampfende ( object  en  ) 

Definiert in Zeile 94 der Datei moving.c.

Benutzt ME, name und WEN.

00094                                     {
00095   if (!objectp(en)) return;
00096   tell_object( ME, capitalize(en->name()) +
00097       " ist jetzt hinter Dir her.\n" );
00098   tell_object( en, "Du verfolgst jetzt " + name(WEN) + ".\n" );      
00099   en->InsertSingleEnemy(ME);
00100 }

varargs public int move ( mixed  dest,
int  method,
string  direction,
string  textout,
string  textin 
)

Definiert in Zeile 178 der Datei moving.c.

Benutzt ExitAttack(), H_ALTERED, H_CANCELLED, H_HOOK_MOVE, H_RETCODE, H_RETDATA, HookFlow(), inv(), invis, IS_LEARNER, M_NO_ATTACK, M_NOCHECK, M_SILENT, M_TPORT, ME, ME_CANT_LEAVE_ENV, ME_DONT_WANT_TO_BE_MOVED, ME_WAS_DESTRUCTED, mout, name, Name(), P_MMSGOUT, P_MSGOUT, P_NO_PLAYERS, P_PARA, P_TESTPLAYER, P_TMP_MOVE_HOOK, PreventMove(), QueryEnemies(), QueryProp(), SetProp(), VALID_MOVE_ERROR und WER.

00180 {
00181     int para, nightvis, invis, tmp;
00182     object oldenv, *inv;
00183     string fn,vc;
00184     mixed res;
00185     mixed hookData, hookRes;
00186 
00187     if (!objectp(dest) && !stringp(dest))
00188       raise_error(sprintf("Wrong argument 1 to move(). 'dest' must be a "
00189                     "string or object! Argument was: %.100O\n",
00190                     dest));
00191 
00192     // altes Env erstmal merken.
00193     oldenv = environment();
00194     
00195     //erstmal den richtigen Zielraum suchen, bevor irgendwelche Checks gemacht
00196     //werden...
00197     // Ist der Spieler in einer Parallelwelt?
00198     if ( (para = QueryProp(P_PARA)) && intp(para) ) {
00199         fn = objectp(dest) ? object_name(dest) : dest;
00200 
00201         // Falls der Zielraum nicht schon explizit in der Parallelwelt ist,
00202         // neuen Zielraum suchen. Aber nur, wenn fn kein # enthaelt (also kein
00203                 // Clone ist), sonst wuerde eine Bewegung nach raum#42^para versucht,
00204                 // was dann buggt. ;-) Problem wird offenbar, wenn ein Para-Lebewesen
00205                 // im create() eines VC-Raums in Para in den Raum bewegt wird, da
00206                 // dieser dann noch nicht vom Driver umbenannt wurde und raum#42
00207                 // heisst.
00208         if ( !sizeof(regexp( ({ fn }), "\\^[1-9][0-9]*$" )) &&
00209                     strrstr(fn,"#")==-1 ) {
00210             fn += "^" + para;
00211 
00212           // Der Parallelwelt-Raum muss existieren und fuer Spieler
00213           // freigegeben sein, damit er zum neuen Ziel wird. Ansonsten
00214           // duerfen nur NPCs, Testspieler und Magier herein.
00215           if ( (find_object(fn) 
00216                                 || ((file_size(fn+".c")>0 ||
00217                     (file_size(vc=implode(explode(fn,"/")[0..<2],"/")+
00218                           "/virtual_compiler.c")>0 &&
00219                     !catch(tmp=(int)call_other(vc,"QueryValidObject",fn);
00220                                            publish) && tmp>0)) &&
00221                     !catch(load_object(fn);publish) )) &&
00222                   (!interactive(ME) || !fn->QueryProp(P_NO_PLAYERS) || 
00223                   (method & M_NOCHECK) || IS_LEARNER(ME) ||
00224                   (stringp(res = QueryProp(P_TESTPLAYER)) &&
00225                    IS_LEARNER( lower_case(res) ))) )
00226                 dest = fn;
00227             else
00228                 // Wir bleiben in der Normalwelt.
00229                 para = 0;
00230         }
00231     }
00232 
00233     // jetzt erstmal Hooks abpruefen, da sie ggf. die Daten aendern.
00234     // alten P_TMP_MOVE_HOOK pruefen.
00235     if ( res = QueryProp(P_TMP_MOVE_HOOK) ){
00236         if ( pointerp(res) && sizeof(res) >= 3
00237              && intp(res[0]) && time()<res[0]
00238              && objectp(res[1]) && stringp(res[2]) ){
00239             if ( res = call_other( res[1], res[2], dest, method, direction,
00240                                    textout, textin ) ){
00241                 if ( pointerp(res) && sizeof(res) == 5 ){
00242                     dest = res[0];
00243                     method = res[1];
00244                     direction = res[2];
00245                     textout = res[3];
00246                     textin = res[4];
00247                 }
00248                 else if ( intp(res) && res == -1 )
00249                     return ME_CANT_LEAVE_ENV;
00250             }
00251         } else
00252             SetProp( P_TMP_MOVE_HOOK, 0 );
00253     }
00254     // move hook nach neuem Hooksystem triggern.
00255     hookData=({dest,method,direction,textout,textin});
00256     hookRes=HookFlow(H_HOOK_MOVE,hookData);
00257     if(hookRes && pointerp(hookRes) && sizeof(hookRes)>H_RETDATA) {
00258       if(hookRes[H_RETCODE]==H_CANCELLED) {
00259                 return ME_CANT_LEAVE_ENV;
00260       }
00261     else if(hookRes[H_RETCODE]==H_ALTERED && hookRes[H_RETDATA] &&
00262           pointerp(hookRes[H_RETDATA]) && sizeof(hookRes[H_RETDATA])>=5 ){
00263       dest = hookRes[H_RETDATA][0];
00264       method = hookRes[H_RETDATA][1];
00265       direction = hookRes[H_RETDATA][2];
00266       textout = hookRes[H_RETDATA][3];
00267       textin = hookRes[H_RETDATA][4];
00268       }
00269     }
00270 
00271     // dest auf Object normieren
00272     if (stringp(dest)) dest=load_object(dest);
00273 
00274     // jetzt Checks durchfuehren, ob das Move durchgefuehrt werden darf.
00275     if (tmp=PreventMove(dest, oldenv, method)) {
00276       // auf gueltigen Fehler pruefen, wer weiss, was Magier da evtl.
00277       // versehentlich zurueckgeben.
00278       if (VALID_MOVE_ERROR(tmp))
00279                 return(tmp);
00280       else
00281                 return(ME_DONT_WANT_TO_BE_MOVED);
00282     }
00283   
00284     if ( invis = QueryProp(P_INVIS) )
00285         method |= M_SILENT;
00286 
00287     if ( objectp(oldenv) ) {
00288         if ( !(method & M_SILENT) ) {
00289             string *mout;
00290             if ( !textout ){
00291                 if ( method & M_TPORT )
00292                     textout = (string) QueryProp(P_MMSGOUT) ||
00293                         (string) QueryProp(P_MSGOUT);
00294                 else 
00295                                     textout = (mout = explode( (string)
00296                                                                                                 QueryProp(P_MSGOUT) || "",
00297                                                       "#" ))[0]
00298                          || (string)QueryProp(P_MMSGOUT);
00299             }
00300 
00301             if ( !strlen(direction) )
00302                 direction = 0;
00303 
00304             inv = all_inventory(environment()) - ({ this_object() });
00305             inv = filter( inv, #'living/*'*/ );
00306             inv -= filter_objects( inv, "CannotSee", 1 );
00307 
00308             filter( inv, #'tell_object/*'*/,
00309                           Name( WER, 2 ) + " " + textout +
00310                           (direction ? " " + direction : "") +
00311                           (sizeof(mout) > 1 ? mout[1] : "") + ".\n" );
00312         }
00313         // Magier sehen auch Bewegungen, die M_SILENT sind
00314         else if ( interactive(ME) ){
00315             inv = (all_inventory(environment()) & users())
00316                 - ({ this_object() });
00317             inv = filter( inv, #'_is_learner/*'*/ );
00318 
00319             if ( invis )
00320                 fn = "(" + capitalize(getuid(ME)) + ") verschwindet "
00321                     "unsichtbar.\n";
00322             else
00323                 fn = capitalize(getuid(ME)) + " verschwindet ganz leise.\n";
00324             
00325             filter( inv, #'tell_object/*'*/, fn );
00326         }
00327         
00328         // Nackenschlag beim Fluechten:
00329         if ( !(method & M_NO_ATTACK) && objectp(ME) )
00330             ExitAttack();
00331         //falls nach ExitAttack() das Living nicht mehr existiert, muss das
00332         //move() auch nicht mehr fortgesetzt werden. Weiter unten gibt es auch
00333         //min. eine Stelle, die nicht prueft und ggf. buggt. Daher erfolgt
00334         //hier ggf. ein Abbruch. 15.11.06 Zesstra
00335         if (!objectp(ME)) return(ME_WAS_DESTRUCTED);
00336 
00337         // Nackenschlag kann ME in den Todesraum bewegt haben...
00338         if ( oldenv == environment() ) {
00339                     // Fuer alle anwesenden gegner kampfende() aufrufen
00340                     filter((QueryEnemies()[0] & all_inventory(oldenv))-({0}),
00341                                 #'kampfende);
00342                     // Bugs im exit() sind ohne catch() einfach mist.
00343                     catch(environment()->exit(ME, dest);publish);
00344         }
00345     }
00346 
00347     // irgendwas kann das Objekt zerstoert haben, z.B. env->exit().
00348     if (!objectp(ME)) return(ME_WAS_DESTRUCTED);
00349 
00350     if ( oldenv != environment() )
00351         // Der Nackenschlag oder exit() koennen einen schon bewegt haben.
00352         // Und wenn es in den Todesraum ist. ;^)
00353         return MOVE_OK;
00354     
00355     SetProp( P_PREPARED_SPELL, 0 ); // Spruchvorbereitung abgebrochen
00356     SetProp( P_LAST_MOVE, time() ); // Zeitpunkt der letzten Bewegung
00357     
00358     move_object(ME, dest);
00359     if (!objectp(ME))
00360       return(ME_WAS_DESTRUCTED);
00361 
00362     dest = environment();
00363     
00364     nightvis = UseSkill(SK_NIGHTVISION);
00365     // Meldungen an nicht-Blinde ausgeben, falls keine 'stille' Bewegung
00366     if ( !(method & M_SILENT) ) {
00367       if ( !textin ) {        
00368                 if ( method & M_TPORT )
00369               textin = (string) QueryProp(P_MMSGIN);
00370         else
00371               textin = (string) QueryProp(P_MSGIN);
00372       }
00373             
00374       inv = all_inventory(environment()) - ({ this_object() });
00375       inv = filter( inv, #'living/*'*/ );
00376             inv -= filter_objects( inv, "CannotSee", 1 );
00377             filter( inv, #'tell_object/*'*/,
00378                           capitalize(name( WER, 0 )) + " " + textin + ".\n" );
00379     }
00380     // sonst: Magier sehen auch M_SILENT-Bewegungen, hier also nur an Magier
00381     // ausgeben, alle anderen sehen eh nix.
00382     else if ( interactive(ME) ) {  
00383       inv = (all_inventory(environment()) & users()) - ({this_object()});        
00384       inv = filter( inv, #'_is_learner/*'*/ );        
00385       if ( invis )
00386                 fn = "(" + capitalize(getuid(ME)) + ") taucht unsichtbar auf.\n";
00387       else
00388         fn = capitalize(getuid(ME)) + " schleicht leise herein.\n";        
00389       filter( inv, #'tell_object, fn );    
00390     }
00391 
00392     // "Objekt" ueber das Move informieren.
00393     NotifyMove(dest, oldenv, method);
00394 
00395     // InitAttack() in NotifyMove() kann das Objekt zerstoert haben.
00396     if (!objectp(ME))
00397       return(ME_WAS_DESTRUCTED);
00398 
00399     //scheint wohl geklappt zu haben.
00400     return MOVE_OK;
00401 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

protected void NotifyMove ( object  dest,
object  oldenv,
int  method 
)

Definiert in Zeile 152 der Datei moving.c.

Benutzt call_out(), InitAttack(), IsTeamLeader(), M_NO_ATTACK, ME, P_PURSUERS, P_TEAM_AUTOFOLLOW, Query() und QueryProp().

00152                                                                   {
00153   mixed res;
00154   object enem;
00155 
00156   // Begruessungsschlag fuer die Gegener
00157   if ( !(method & M_NO_ATTACK) )
00158       InitAttack();
00159 
00160   if (!objectp(ME)) return;
00161 
00162   // Verfolger nachholen.
00163   if ( pointerp(res = Query(P_PURSUERS)) && sizeof(res[1]) ) {
00164       while ( remove_call_out( "TakeFollowers" ) >= 0 );
00165 
00166       call_out( "TakeFollowers", 0 );
00167   }
00168 
00169   // und noch das Team nachholen.
00170   if ( oldenv != dest
00171       && objectp(ME)
00172       && QueryProp(P_TEAM_AUTOFOLLOW)
00173       && objectp( enem = IsTeamLeader() ) )
00174       enem->StartFollow(oldenv); // Teamverfolgung
00175 
00176 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

protected int PreventMove ( object  dest,
object  oldenv,
int  method 
)

Definiert in Zeile 109 der Datei moving.c.

Benutzt M_GO, M_NOCHECK, M_TPORT, ME_CANT_BE_INSERTED, ME_CANT_LEAVE_ENV, ME_CANT_TPORT_IN, ME_CANT_TPORT_OUT, ME_PLAYER, NO_TPORT, NO_TPORT_IN, NO_TPORT_OUT, P_NO_TPORT und QueryProp().

00109                                                                   {
00110 
00111   // M_NOCHECK? -> Bewegung eh erlaubt (und Rueckgabewert wuerde ignoriert),
00112   // aber PreventInsert/PreventLeave() rufen und ignorieren.
00113   if ((method&M_NOCHECK)) {
00114       // erst PreventLeaveLiving() rufen...
00115       if(environment())         
00116                   environment()->PreventLeaveLiving(this_object(), dest);
00117       // dann PreventInsertLiving() im Ziel-Env.
00118       dest->PreventInsertLiving(this_object());
00119       // und raus...
00120       return(0);
00121   }
00122 
00123   // bei Lebewesen muss die Bewegungsmethode M_GO und M_TPORT sein. Dies ist
00124   // gleichzeigt die Restriktion gegen das Nehmen von Lebewesen, da dort
00125   // M_GET/M_GIVE/M_PUT etc. verwendet wuerde. Bei M_GO und M_TPORT findet
00126   // keine Pruefung statt, ob das Objekt ins Ziel 'reinpasst' (Gewicht, Anzahl
00127   // Objekte usw.).
00128   // Ich finde es etwas merkwuerdig gebaut (Zesstra).
00129   if ( !(method & (M_GO | M_TPORT)) )
00130       return ME_PLAYER;
00131   
00132   // alte und neue Umgebung auf NO_TPORT pruefen.
00133   if ( (method & M_TPORT) ) {
00134     if ( environment() &&
00135         (environment()->QueryProp(P_NO_TPORT) & (NO_TPORT_OUT|NO_TPORT)) )
00136           return ME_CANT_TPORT_OUT;
00137     else if ( dest->QueryProp(P_NO_TPORT) & (NO_TPORT_IN|NO_TPORT) )
00138           return ME_CANT_TPORT_IN;
00139   }
00140 
00141   // erst PreventLeaveLiving() testen...
00142   if( environment() && environment()->PreventLeaveLiving(this_object(), dest))
00143       return ME_CANT_LEAVE_ENV;
00144   // dann PreventInsertLiving() im Ziel-Env
00145   if (dest->PreventInsertLiving(this_object())) 
00146       return ME_CANT_BE_INSERTED;
00147 
00148   return 0;
00149 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

varargs public int remove (  ) 

Definiert in Zeile 431 der Datei moving.c.

00432 { object team;
00433 
00434   if ( objectp(team=Query(P_TEAM)) )
00435     catch(team->RemoveMember(ME);publish);
00436 
00437   if( environment() ) environment()->NotifyRemove(ME);
00438   destruct(ME);
00439   return 1;
00440 }

public void RemovePursuer ( object  ob  ) 

Definiert in Zeile 52 der Datei moving.c.

Benutzt ME, P_PURSUERS, Query() und SetProp().

Wird benutzt von _SetPursued().

00053 {
00054   mixed *pur;
00055 
00056   if (pointerp(pur=Query(P_PURSUERS)) && member(pur[1],ob)!=-1)
00057   {
00058     pur[1]-=({ob,0});
00059     ob->_RemovePursued(ME);
00060     if (!pur[0]&&!sizeof(pur[1]))
00061       pur=0;
00062     SetProp(P_PURSUERS,pur);
00063   }
00064 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

public void TakeFollowers (  ) 

Definiert in Zeile 403 der Datei moving.c.

Wird benutzt von modify_command().

00404 {
00405   mixed *f,env;
00406   int meth,i,r;
00407 
00408   f=Query(P_PURSUERS);
00409   if (!pointerp(f))
00410     return;
00411   env=environment();
00412   if(object_name(env) == "/room/netztot") return;
00413   foreach(object follower: f[1]-({0}) ) {
00414     // die pruefung auf objectp ist nicht verrueckt, es kann theo. sein, dass
00415     // Verfolger im PreventFollow() oder in ihrem move/init andere Verfolger
00416     // zerstoeren.
00417     if (objectp(follower) && environment(follower)!=env) {
00418       //meth=M_NOCHECK;
00419       meth=M_GO;
00420       if (follower->Query(P_FOLLOW_SILENT))
00421                   meth|=M_SILENT|M_NO_SHOW;
00422       catch(r=follower->PreventFollow(env);publish);
00423       if (!r)
00424                   follower->move(env,meth);
00425       else if (r==2)
00426                   RemovePursuer(follower);
00427     }
00428   }
00429 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

Erzeugt am Thu Jun 3 14:40:57 2010 für MorgenGrauen Mudlib von  doxygen 1.6.3