Neue Optionen fuer goto

Mit -l wird nur zu Livings gegangen, mit -r nur zu Raeumen.

Change-Id: Ie529b2e9e854d113d6c5a5f99e97fa7dd9c6680a
diff --git a/doc/mcmd/goto b/doc/mcmd/goto
index cc3cfa1..523239d 100644
--- a/doc/mcmd/goto
+++ b/doc/mcmd/goto
@@ -3,7 +3,7 @@
 ----
 
  MAGIERKOMMANDO:
-    goto <ziel>
+    goto [-r] | [ -l ] <ziel>
     +<magier>
 
  ARGUMENTE:
@@ -21,6 +21,9 @@
     Ist <ziel> dagegen der Name eines (eingeloggten) Spielers oder eines NPCs,
     so wirst Du in den Raum teleportiert, in dem sich das entsprechende
     Lebewesen aufhaelt.
+
+    -l sorgt dafuer, dass du nur zu einem Living teleportierst, -r dafuer,
+    dass du nur in einen Raum teleportierst.
     
     Wenn mehere NPCs des Namens existieren, kann man mit 'goto name nr' den
     gewuenschten auswaehlen.
diff --git a/std/shells/magier/moving.c b/std/shells/magier/moving.c
index bb42718..4f756b9 100644
--- a/std/shells/magier/moving.c
+++ b/std/shells/magier/moving.c
@@ -135,22 +135,38 @@
   dest = _unparsed_args();
   if(!sizeof(dest))
     return USAGE("goto [lebewesen|filename]\n");
-  // Zuerst nur Spieler suchen, wenn keine existieren auch andere Livings.
-  target = (find_player(dest) || find_living_nr(dest));
-  if(objectp(target) && environment(target))
+  int flags;
+  dest = parseargs(dest, &flags, GOTO_OPTS, 0)[0];
+  if((flags & GOTO_L) && (flags & GOTO_R))
   {
-    target = environment(target);
+    notify_fail(
+      "goto: -r und -l koennen nicht gleichzeitig verwendet werden.\n");
+    return 0;
   }
-  else
+  if(!(flags & GOTO_R))
+  {
+    // Zuerst nur Spieler suchen, wenn keine existieren auch andere Livings.
+    object lv = (find_player(dest) || find_living_nr(dest));
+    if(objectp(lv) && environment(lv))
+    {
+      target = environment(lv);
+    }
+    else
+    {
+      notify_fail(
+        "goto: Kein Lebewesen mit dem Namen " + dest + " gefunden.\n");
+    }
+  }
+  if(!(flags & GOTO_L) && !target)
   {
     // Kein passendes Living, jetzt Raeume suchen.
-    string target2;
-    target2 = target = normalize_path(dest, getuid(), 1);
-    if (!find_object(target))
+    string path = normalize_path(dest, getuid(), 1);
+    target = find_object(path);
+    if(!target)
     {
+      notify_fail(sprintf("goto: Datei %O nicht vorhanden.\n",path));
       // ggf. .c dranhaengen
-      if (target2[<2..<1]!=".c") target2+=".c";
-      notify_fail(sprintf("goto: Datei %O nicht vorhanden.\n",target));
+      if (path[<2..<1]!=".c") path+=".c";
       // Erst schauen, ob die Datei existiert, falls nicht pruefen, ob im
       // gleichen Verzeichnis ein VC vorhanden ist, der sie liefern koennte.
       // Die Ueberpruefung ob das File moeglicherweise Ladbar sein koennte
@@ -158,12 +174,12 @@
       // Die Variable vc dient nur dazu, weniger Zeilenumbrueche in
       // der if-Abfrage zu haben und sie damit besser lesbar zu machen.
       string vc;
-      vc = implode(explode(target, "/")[0..<2], "/") + "/virtual_compiler.c";
-      if(file_size(target2) > FSIZE_NOFILE ||
+      vc = implode(explode(path, "/")[0..<2], "/") + "/virtual_compiler.c";
+      if(file_size(path) > FSIZE_NOFILE ||
         (file_size(vc) > FSIZE_NOFILE) &&
-        ({int})vc->QueryValidObject(target2))
+        ({int})vc->QueryValidObject(path))
       {
-        string err = catch(load_object(target));
+        string err = catch(target = load_object(path));
         if(stringp(err))
         {
            notify_fail(sprintf("goto: Fehler beim Teleport nach %O:\n%s\n",
diff --git a/sys/magier.h b/sys/magier.h
index bcea30b..74c4057 100644
--- a/sys/magier.h
+++ b/sys/magier.h
@@ -134,6 +134,10 @@
 #define SNOOP_F         2            // Snoope snoopenden Magier, wenn der
                                      // Charakter schon gesnoopt wird
 
+#define GOTO_OPTS       "rl"
+#define GOTO_R          1            // Nur Raeume
+#define GOTO_L          2            // Nur Livings
+
 #define NO_CHECK        M_GO|M_SILENT|M_NO_SHOW|M_NO_ATTACK|M_NOCHECK
 
 #define INV_SAVE        "/room/void.c"