// MorgenGrauen MUDlib
//
// living/moving.c -- moving of living objects
//
// $Id: moving.c 9448 2016-01-22 17:52:28Z Zesstra $
#pragma strong_types
#pragma save_types
#pragma range_check
#pragma no_clone
#pragma pedantic

inherit "/std/thing/moving";

#define NEED_PROTOTYPES
#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>

#undef NEED_PROTOTYPES

#include <config.h>
#include <properties.h>
#include <language.h>
#include <wizlevels.h>
#include <defines.h>


protected void create()
{
    if (object_name(this_object()) == __FILE__[0..<3])
    {
      return;
    }
    offerHook(H_HOOK_MOVE,1);
}

public void AddPursuer(object ob)
{
  mixed *pur;

  if (!objectp(ob))
    return;

  if (!pointerp(pur=Query(P_PURSUERS)))
    pur=({0,({})});
  else if (member(pur[1],ob)!=-1)
    return;
  
  SetProp(P_PURSUERS,({ pur[0], pur[1]+({ob})-({0}) }));
  ob->_SetPursued(ME);
}

public void RemovePursuer(object ob)
{
  mixed *pur;

  if (pointerp(pur=Query(P_PURSUERS,F_VALUE)) 
      && member(pur[1],ob)!=-1)
  {
    pur[1]-=({ob,0});
    if (ob)
      ob->_RemovePursued(ME);
    if (!pur[0]&&!sizeof(pur[1]))
      pur=0;
    SetProp(P_PURSUERS,pur);
  }
}

public void _SetPursued(object ob)
{
  mixed *pur;

  if (!pointerp(pur=Query(P_PURSUERS)))
    pur=({0,({})});
  else
    if (objectp(pur[0]))
      pur[0]->RemovePursuer(ME);
  pur[0]=ob;
  pur[1]-=({0});
  Set(P_PURSUERS,pur);
}

public void _RemovePursued(object ob)
{
  mixed *pur;

  if (!pointerp(pur=Query(P_PURSUERS)) || pur[0]!=ob)
    return;
  pur[0]=0;
  pur[1]-=({0});
  if (!sizeof(pur[1]))
    pur=0;
  Set(P_PURSUERS,pur);
}


private void kampfende( object en ) {
  if (!objectp(en)) return;
  tell_object( ME, capitalize(en->name()) +
      " ist jetzt hinter Dir her.\n" );
  tell_object( en, "Du verfolgst jetzt " + name(WEN) + ".\n" );      
  en->InsertSingleEnemy(ME);
}

private int _is_learner(object pl) {
  return IS_LEARNER(pl); 
}


// a) Pruefungen, ob das move erlaubt ist.
// b) zum Ueberschreiben
protected int PreventMove(object dest, object oldenv, int method) {

  // M_NOCHECK? -> Bewegung eh erlaubt (und Rueckgabewert wuerde ignoriert),
  // aber PreventInsert/PreventLeave() rufen und ignorieren.
  if ((method&M_NOCHECK)) {
      // erst PreventLeaveLiving() rufen...
      if(environment())        
          environment()->PreventLeaveLiving(this_object(), dest);
      // dann PreventInsertLiving() im Ziel-Env.
      dest->PreventInsertLiving(this_object());
      // und raus...
      return(0);
  }

  // bei Lebewesen muss die Bewegungsmethode M_GO und M_TPORT sein. Dies ist
  // gleichzeigt die Restriktion gegen das Nehmen von Lebewesen, da dort
  // M_GET/M_GIVE/M_PUT etc. verwendet wuerde. Bei M_GO und M_TPORT findet
  // keine Pruefung statt, ob das Objekt ins Ziel 'reinpasst' (Gewicht, Anzahl
  // Objekte usw.).
  // Ich finde es etwas merkwuerdig gebaut (Zesstra).
  if ( !(method & (M_GO | M_TPORT)) )
      return ME_PLAYER;
  
  // alte und neue Umgebung auf NO_TPORT pruefen.
  if ( (method & M_TPORT) ) {
    if ( environment() &&
        (environment()->QueryProp(P_NO_TPORT) & (NO_TPORT_OUT|NO_TPORT)) )
          return ME_CANT_TPORT_OUT;
    else if ( dest->QueryProp(P_NO_TPORT) & (NO_TPORT_IN|NO_TPORT) )
          return ME_CANT_TPORT_IN;
  }

  // erst PreventLeaveLiving() testen...
  if( environment() && environment()->PreventLeaveLiving(this_object(), dest))
      return ME_CANT_LEAVE_ENV;
  // dann PreventInsertLiving() im Ziel-Env
  if (dest->PreventInsertLiving(this_object())) 
      return ME_CANT_BE_INSERTED;

  return 0;
}

// Krams nach dem Move machen und nebenbei zum Ueberschreiben.
protected void NotifyMove(object dest, object oldenv, int method) {
  mixed res;
  object enem;

  // Begruessungsschlag fuer die Gegener
  if ( !(method & M_NO_ATTACK) )
      InitAttack();

  if (!objectp(ME)) return;

  // Verfolger nachholen.
  if ( pointerp(res = Query(P_PURSUERS)) && sizeof(res[1]) ) {
      while ( remove_call_out( "TakeFollowers" ) >= 0 );

      call_out( "TakeFollowers", 0 );
  }

  // und noch das Team nachholen.
  if ( oldenv != dest
      && objectp(ME)
      && QueryProp(P_TEAM_AUTOFOLLOW)
      && objectp( enem = IsTeamLeader() ) )
      enem->StartFollow(oldenv); // Teamverfolgung

}

varargs public int move( object|string dest, int method, string direction,
                         string textout, string textin )
{
    int para, nightvis, invis, tmp;
    object oldenv, *inv;
    string fn,vc;
    mixed res;
    mixed hookData, hookRes;

    if (!objectp(dest) && !stringp(dest))
      raise_error(sprintf("Wrong argument 1 to move(). 'dest' must be a "
            "string or object! Argument was: %.100O\n",
            dest));

    // altes Env erstmal merken.
    oldenv = environment();
    
    //erstmal den richtigen Zielraum suchen, bevor irgendwelche Checks gemacht
    //werden...
    // Ist der Spieler in einer Parallelwelt?
    if ( (para = QueryProp(P_PARA)) && intp(para) ) {
        fn = objectp(dest) ? object_name(dest) : dest;

        // Falls der Zielraum nicht schon explizit in der Parallelwelt ist,
        // neuen Zielraum suchen. Aber nur, wenn fn kein # enthaelt (also kein
        // Clone ist), sonst wuerde eine Bewegung nach raum#42^para versucht,
        // was dann buggt. ;-) Problem wird offenbar, wenn ein Para-Lebewesen
        // im create() eines VC-Raums in Para in den Raum bewegt wird, da
        // dieser dann noch nicht vom Driver umbenannt wurde und raum#42
        // heisst.
        if ( !sizeof(regexp( ({ fn }), "\\^[1-9][0-9]*$" )) &&
            strrstr(fn,"#")==-1 )
        {
            fn += "^" + para;

          // Der Parallelwelt-Raum muss existieren und fuer Spieler
          // freigegeben sein, damit er zum neuen Ziel wird. Ansonsten
          // duerfen nur NPCs, Testspieler und Magier herein.
          if ( (find_object(fn) 
                || ((file_size(fn+".c")>0 ||
                    (file_size(vc=implode(explode(fn,"/")[0..<2],"/")+
                          "/virtual_compiler.c")>0 &&
                    !catch(tmp=(int)call_other(vc,"QueryValidObject",fn);
                           publish) && tmp>0)) &&
                    !catch(load_object(fn);publish) )) &&
                  (!interactive(ME) || !fn->QueryProp(P_NO_PLAYERS) || 
                  (method & M_NOCHECK) || IS_LEARNER(ME) ||
                  (stringp(res = QueryProp(P_TESTPLAYER)) &&
                   IS_LEARNER( lower_case(res) ))) )
          {
              dest = fn;
          }
          else
          {
              // Wir bleiben in der Normalwelt.
              para = 0;
          }
        }
    }

    // jetzt erstmal Hooks abpruefen, da sie ggf. die Daten aendern.
    // alten P_TMP_MOVE_HOOK pruefen.
    if ( res = QueryProp(P_TMP_MOVE_HOOK) ){
        if ( pointerp(res) && sizeof(res) >= 3
             && intp(res[0]) && time()<res[0]
             && objectp(res[1]) && stringp(res[2]) ){
            if ( res = call_other( res[1], res[2], dest, method, direction,
                                   textout, textin ) ){
                if ( pointerp(res) && sizeof(res) == 5 ){
                    dest = res[0];
                    method = res[1];
                    direction = res[2];
                    textout = res[3];
                    textin = res[4];
                }
                else if ( intp(res) && res == -1 )
                    return ME_CANT_LEAVE_ENV;
            }
        } else
            SetProp( P_TMP_MOVE_HOOK, 0 );
    }
    // move hook nach neuem Hooksystem triggern.
    hookData=({dest,method,direction,textout,textin});
    hookRes=HookFlow(H_HOOK_MOVE,hookData);
    if(hookRes && pointerp(hookRes) && sizeof(hookRes)>H_RETDATA) {
      if(hookRes[H_RETCODE]==H_CANCELLED) {
        return ME_CANT_LEAVE_ENV;
      }
    else if(hookRes[H_RETCODE]==H_ALTERED && hookRes[H_RETDATA] &&
          pointerp(hookRes[H_RETDATA]) && sizeof(hookRes[H_RETDATA])>=5 ){
      dest = hookRes[H_RETDATA][0];
      method = hookRes[H_RETDATA][1];
      direction = hookRes[H_RETDATA][2];
      textout = hookRes[H_RETDATA][3];
      textin = hookRes[H_RETDATA][4];
      }
    }

    // dest auf Object normieren
    if (stringp(dest)) dest=load_object(dest);

    // jetzt Checks durchfuehren, ob das Move durchgefuehrt werden darf.
    if (tmp=PreventMove(dest, oldenv, method)) {
      // auf gueltigen Fehler pruefen, wer weiss, was Magier da evtl.
      // versehentlich zurueckgeben.
      if (VALID_MOVE_ERROR(tmp))
        return(tmp);
      else
        return(ME_DONT_WANT_TO_BE_MOVED);
    }
  
    if ( invis = QueryProp(P_INVIS) )
        method |= M_SILENT;

    if ( objectp(oldenv) ) {
        if ( !(method & M_SILENT) ) {
            string *mout;
            if ( !textout ){
                if ( method & M_TPORT )
                    textout = (string) QueryProp(P_MMSGOUT) ||
                        (string) QueryProp(P_MSGOUT);
                else 
                    textout = (mout = explode( (string)
                                                QueryProp(P_MSGOUT) || "",
                                                      "#" ))[0]
                         || (string)QueryProp(P_MMSGOUT);
            }

            if ( !sizeof(direction) )
                direction = 0;

            inv = all_inventory(environment()) - ({ this_object() });
            inv = filter( inv, #'living/*'*/ );
            inv -= filter_objects( inv, "CannotSee", 1 );

            filter( inv, #'tell_object/*'*/,
                          Name( WER, 2 ) + " " + textout +
                          (direction ? " " + direction : "") +
                          (sizeof(mout) > 1 ? mout[1] : "") + ".\n" );
        }
        // Magier sehen auch Bewegungen, die M_SILENT sind
        else if ( interactive(ME) ){
            inv = (all_inventory(environment()) & users())
                - ({ this_object() });
            inv = filter( inv, #'_is_learner/*'*/ );

            if ( invis )
                fn = "(" + capitalize(getuid(ME)) + ") verschwindet "
                    "unsichtbar.\n";
            else
                fn = capitalize(getuid(ME)) + " verschwindet ganz leise.\n";
            
            filter( inv, #'tell_object/*'*/, fn );
        }
        
        // Nackenschlag beim Fluechten:
        if ( !(method & M_NO_ATTACK) && objectp(ME) )
            ExitAttack();
        //falls nach ExitAttack() das Living nicht mehr existiert, muss das
        //move() auch nicht mehr fortgesetzt werden. Weiter unten gibt es auch
        //min. eine Stelle, die nicht prueft und ggf. buggt. Daher erfolgt
        //hier ggf. ein Abbruch. 15.11.06 Zesstra
        if (!objectp(ME)) return(ME_WAS_DESTRUCTED);

        // Nackenschlag kann ME in den Todesraum bewegt haben...
        if ( oldenv == environment() ) {
            // Fuer alle anwesenden gegner kampfende() aufrufen
            filter((QueryEnemies()[0] & all_inventory(oldenv))-({0}),
                #'kampfende);
            // Bugs im exit() sind ohne catch() einfach mist.
            catch(environment()->exit(ME, dest);publish);
        }
    }

    // irgendwas kann das Objekt zerstoert haben, z.B. env->exit().
    if (!objectp(ME)) return(ME_WAS_DESTRUCTED);

    if ( oldenv != environment() )
        // Der Nackenschlag oder exit() koennen einen schon bewegt haben.
        // Und wenn es in den Todesraum ist. ;^)
        return MOVE_OK;
    
    SetProp( P_PREPARED_SPELL, 0 ); // Spruchvorbereitung abgebrochen
    SetProp( P_LAST_MOVE, time() ); // Zeitpunkt der letzten Bewegung
    
    move_object(ME, dest);
    if (!objectp(ME))
      return(ME_WAS_DESTRUCTED);

    dest = environment();
    
    nightvis = UseSkill(SK_NIGHTVISION);
    // Meldungen an nicht-Blinde ausgeben, falls keine 'stille' Bewegung
    if ( !(method & M_SILENT) ) {
      if ( !textin ) {        
        if ( method & M_TPORT )
              textin = (string) QueryProp(P_MMSGIN);
        else
              textin = (string) QueryProp(P_MSGIN);
      }
            
      inv = all_inventory(environment()) - ({ this_object() });
      inv = filter( inv, #'living/*'*/ );
            inv -= filter_objects( inv, "CannotSee", 1 );
            filter( inv, #'tell_object/*'*/,
                          capitalize(name( WER, 0 )) + " " + textin + ".\n" );
    }
    // sonst: Magier sehen auch M_SILENT-Bewegungen, hier also nur an Magier
    // ausgeben, alle anderen sehen eh nix.
    else if ( interactive(ME) ) {  
      inv = (all_inventory(environment()) & users()) - ({this_object()});        
      inv = filter( inv, #'_is_learner/*'*/ );        
      if ( invis )
        fn = "(" + capitalize(getuid(ME)) + ") taucht unsichtbar auf.\n";
      else
        fn = capitalize(getuid(ME)) + " schleicht leise herein.\n";        
      filter( inv, #'tell_object, fn );    
    }

    // "Objekt" ueber das Move informieren.
    NotifyMove(dest, oldenv, method);

    // InitAttack() in NotifyMove() kann das Objekt zerstoert haben.
    if (!objectp(ME))
      return(ME_WAS_DESTRUCTED);

    //scheint wohl geklappt zu haben.
    return MOVE_OK;
}

public void TakeFollowers()
{
  mixed *f,env;
  int meth,i,r;

  f=Query(P_PURSUERS);
  if (!pointerp(f))
    return;
  env=environment();
  if(object_name(env) == "/room/netztot") return;
  foreach(object follower: f[1]-({0}) ) {
    // die pruefung auf objectp ist nicht verrueckt, es kann theo. sein, dass
    // Verfolger im PreventFollow() oder in ihrem move/init andere Verfolger
    // zerstoeren.
    if (objectp(follower) && environment(follower)!=env) {
      //meth=M_NOCHECK;
      meth=M_GO;
      if (follower->Query(P_FOLLOW_SILENT))
          meth|=M_SILENT|M_NO_SHOW;
      catch(r=follower->PreventFollow(env);publish);
      if (!r)
          follower->move(env,meth);
      else if (r==2)
          RemovePursuer(follower);
    }
  }
}

varargs public int remove()
{ object team;

  if (environment())
  {
    if ( objectp(team=Query(P_TEAM)) )
      catch(team->RemoveMember(ME);publish);

    environment()->NotifyRemove(ME);
  }
  destruct(ME);
  return 1;
}

