diff --git a/std/living/put_and_get.c b/std/living/put_and_get.c
new file mode 100644
index 0000000..4e1a97f
--- /dev/null
+++ b/std/living/put_and_get.c
@@ -0,0 +1,1243 @@
+// MorgenGrauen MUDlib
+//
+// living/put_and_get.c -- taking and putting things
+//
+// $Id: put_and_get.c 8755 2014-04-26 13:13:40Z Zesstra $
+
+/*
+  Grundlegend neu strukturiert von Amynthor im April-Juni 2007
+
+Die eigentlichen Funktionen:
+
+  private string put_or_get(object o, object dest)
+    Bewegt ein einzelnes Objekt mit automatisch bestimmter Method. Gibt im
+    Erfolgsfall 0 zurueck, sonst die auszugebende Fehlermeldung.
+
+  varargs int drop(object o, mixed msg)
+  varargs int put(object o, object dest, mixed msg)
+  varargs int pick(object o, mixed msg)
+  varargs int give(object o, object dest, mixed msg)
+  varargs int show(object o, object dest, mixed msg)
+    Der Spieler nimmt/legt/gibt/zeigt/laesst ein Objekt fallen, wobei die
+    entsprechenden oder optional abweichende (im Format von P_XXX_MSG) oder
+    gar keine (msg == 1) Meldungen ausgegeben werden. Es liegt in der
+    Verantwortung des Rufenden, sinnvolle Werte zu uebergeben; insbesondere
+    wird nicht geprueft, ob sich die Objekte in der Reichweite des Spielers
+    befinden. Gibt 1 zurueck, wenn das Objekt bewegt wurde, sonst 0.
+
+Hilfsfunktionen:
+
+  private object *__find_objects(string *tokens, object env, int is_source)
+  object *find_objects(string what, object env, int is_source)
+    Sucht im Raum und im Spieler (oder alternativ in der angegebenen Umgebung)
+    nach den in tokens/what bezeichneten Objekten. is_source bestimmt die
+    erwartete grammatische Form (0 fuer "topf auf herd" und 1 fuer "topf von
+    herd", siehe Manpage).
+
+  varargs int drop_objects(string str, mixed msg)
+  varargs int put_objects(string str, int casus, string verb, mixed msg)
+  varargs int pick_objects(string str, mixed msg, int flag)
+  varargs int give_objects(string str, mixed msg)
+  varargs int show_objects(string str, mixed msg)
+    Ein Befehl wie "wirf waffen weg" resultiert in einem Aufruf von
+    drop_objects("waffen"). Diese Funktionen sind hauptsaechlich fuer die
+    Behandlung der jeweiligen Kommandos vorgesehen, koennen jedoch auch fuer
+    eigene Befehle verwendet werden. put_objects() erwartet ausserdem den
+    Kasus ("Du kannst nichts an DER Pinwand befestigen.") und das verwendete
+    Verb in der Gundform ("befestigen"). Das Flag fuer pick_objects() gibt
+    an, ob das Objekt auch einfach herumliegen darf ("nimm ...") oder nicht
+    ("hole ..."). Gibt bei Erfolg 1, sonst 0 zurueck.
+
+  object *moved_objects()
+  object moved_where()
+    Gibt die eben fallengelassenen/gesteckten/... Objekte zurueck und wohin
+    sie gesteckt/wem sie gegeben/gezeigt wurden. Fuer den Fall, dass man
+    anschliessend noch etwas mit ihnen machen moechte.
+
+Die einzelnen Kommandos:
+  static int fallenlassen(string str)
+  static int werfen(string str)
+  static int legen(string str)
+  static int stecken(string str)
+  static int holen(string str)
+  static int nehmen(string str)
+  static int geben(string str)
+    Minimale Wrapper fuer XXX_objects(), entfernen "fallen", "weg" bzw. "ab"
+    aus den Argumenten und setzen entsprechende Standard-Fehlermeldungen.
+    
+  protected void add_put_and_get_commands()
+    Registriert obige Funktionen per add_action().
+
+Aus reinen Kompatibilitaetsgruenden weiterhin enthalten:
+
+  object* find_obs(string str, int meth)
+  int pick_obj(object ob)
+  int drop_obj(object ob)
+  int put_obj(object ob, object where)
+  int give_obj(object ob, object where)
+    siehe Manpages
+
+*/
+
+/*
+  21. Okt 1998 komplette neu programmierung von put_and_get.c (Padreic)
+- die Gruppenauswahlen alles, waffen und ruestungen sind jetzt immer moeglich
+  die Gruppen sind sehr leicht erweiterbar und man sollte sich nicht scheuen
+  davon gebrauch zu machen...
+- mit "in mir" und "im raum" kann man den abzusuchenden Raum selbst eingrenzen
+- mit "alle|jede|jeden|jedes <id>" kann man auch ganze objektgruppen auswaehlen
+*/
+
+#pragma strong_types
+#pragma save_types
+#pragma range_check
+#pragma no_clone
+#pragma pedantic
+
+#define NEED_PROTOTYPES
+#include <language.h>
+#include <thing/description.h>
+#include <thing/properties.h>
+#include <moving.h>
+#include <container.h>
+#undef NEED_PROTOTYPES
+
+#include <defines.h>
+#include <properties.h>
+#include <wizlevels.h>
+
+#define TME(str) tell_object(this_object(), \
+    break_string(str, 78, 0, BS_LEAVE_MY_LFS))
+#define TOB(ob,str) tell_object(ob, break_string(str, 78, 0, BS_LEAVE_MY_LFS))
+#define SAY(str) tell_room(environment(), \
+    break_string(str, 78, 0, BS_LEAVE_MY_LFS), ({this_object()}))
+#define SAY2(obs, str) tell_room(environment(), \
+    break_string(str, 78, 0, BS_LEAVE_MY_LFS), ({this_object()}) + obs)
+#define NF(str) _notify_fail(break_string(str, 78, 0, BS_LEAVE_MY_LFS))
+
+private nosave closure cl;
+private nosave string wen0, wen1, wer0;
+private nosave object *last_moved_objects;
+private nosave object last_moved_where;
+
+
+/*********************** Die eigentlichen Funktionen ************************/
+
+private string put_or_get(object o, object dest)
+
+/* Bewegt ein einzelnes Objekt <o> in das Zielobjekt <dest>. Verwendet dazu
+ * je nach Umstaenden (Ziel ist der Spieler, die Umgebung, ein Lebewesen) den
+ * entsprechenden Wert fuer <method>. Gibt im Erfolgsfall 0 zurueck, erstellt
+ * sonst die auszugebende Fehlermeldung und gibt diese zurueck.
+ */
+
+{
+    int method, ret;
+    string str;
+
+    //if (living(o))
+    //    raise_error(sprintf("Lebendes Argument fuer put_or_get: %O\n", o));
+
+    if (dest == this_object())          /* pick */
+        method = M_GET;
+    else if (dest == environment())     /* drop */
+        method = M_PUT;
+    else if (living(dest))              /* give */
+        method = M_GIVE;
+    else {                              /* put */
+        method = M_PUT | M_GET;
+        if (first_inventory(o))
+            return o->Name(WER, 1) + " ist nicht leer!";
+    }
+
+    if ((ret = o->move(dest, method)) > 0)
+        return 0;
+
+    switch (ret) {
+        case ME_TOO_HEAVY:
+            if (dest == this_object())
+                if (QueryProp(P_GHOST))
+                    return "Als Geist kannst Du nichts mitnehmen.";
+                else
+                    return "Du kannst " + wen1 + " nicht mehr tragen.";
+
+            if (stringp(str = dest->QueryProp(P_TOO_HEAVY_MSG)))
+                return capitalize(replace_personal(str, ({o, dest}), 1));
+
+            if (living(dest)) {
+                if (dest->QueryProp(P_GHOST))
+                    return "Als Geist kann " + dest->name(WER, 1) +
+                           " nichts mitnehmen.";
+                else
+                    return dest->Name(WER, 1) + " kann " +
+                           wen0 + " nicht mehr tragen.";
+            }
+
+            if (dest == environment())
+                return (stringp(str = dest->Name(WER, 1)) && sizeof(str) ?
+                        str : "Der Raum") + " wuerde dann zu schwer werden.";
+
+            return capitalize(wer0 + " passt in " + dest->name(WEN, 1) +
+                              " nicht mehr rein.");
+
+        case ME_CANT_BE_DROPPED:
+            if (o && stringp(str = o->QueryProp(P_NODROP)))
+                return str;
+
+            if (dest == environment())
+                return "Du kannst " + wen1 + " nicht wegwerfen!";
+
+            if (living(dest))
+                return "Du kannst " + wen1 + " nicht weggeben.";
+
+            return "So wirst Du " + wen1 + " nicht los...";
+
+        case ME_CANT_BE_TAKEN:
+            if (o && stringp(str = o->QueryProp(P_NOGET)))
+                return str;
+
+            if (stringp(str = environment(o)->QueryProp(P_NOLEAVE_MSG)))
+                return capitalize(
+                    replace_personal(str, ({o, environment(o)}), 1));
+
+            //if (dest != environment())
+            //    return "Du kannst " + wen1 + " nicht einmal nehmen.";
+
+            return "Du kannst " + wen1 + " nicht nehmen.";
+
+        case ME_CANT_BE_INSERTED:
+            if (stringp(str = dest->QueryProp(P_NOINSERT_MSG)))
+                return capitalize(replace_personal(str, ({o, dest}), 1));
+
+            if (dest == environment())
+                return "Das darfst Du hier nicht ablegen.";
+
+            if (dest == this_object())
+                return "Du kannst " + wen1 + " nicht nehmen.";
+
+            if (living(dest))
+                return "Das kannst Du " + dest->name(WEM, 1) + " nicht geben.";
+
+            return capitalize(wen0 + " kannst Du dort nicht hineinstecken.");
+
+        case ME_CANT_LEAVE_ENV:
+            // ME_CANT_LEAVE_ENV kann nur auftreten, wenn o ein Environment
+            // hat, deshalb kein Check dadrauf
+            if (stringp(str = environment(o)->QueryProp(P_NOLEAVE_MSG)))
+                return capitalize(
+                    replace_personal(str, ({o, environment(o)}), 1));
+
+            if (environment(o) != this_object())
+                return "Du kannst " + wen1 + " nicht nehmen.";
+
+            if (dest == environment())
+                return "Du kannst " + wen1 + " nicht wegwerfen!";
+
+            if (living(dest))
+                return "Du kannst " + wen1 + " nicht weggeben.";
+
+            return "So wirst Du " + wen1 + " nicht los...";
+
+        case ME_TOO_HEAVY_FOR_ENV:
+            if (stringp(str = dest->QueryProp(P_ENV_TOO_HEAVY_MSG)))
+                return capitalize(replace_personal(str, ({o, dest}), 1));
+
+            if (environment(dest) == this_object())
+                return dest->Name(WER, 1) +
+                       " wuerde Dir dann zu schwer werden.";
+
+            return (stringp(str = environment(dest)->Name(WER, 1))
+                        && sizeof(str) ? str : "Der Raum") +
+                    " wuerde dann zu schwer werden.";
+
+        case TOO_MANY_OBJECTS:
+            if (stringp(str = dest->QueryProp(P_TOO_MANY_MSG)))
+                return capitalize(replace_personal(str, ({o, dest}), 1));
+
+            if (dest == this_object())
+                return "Soviele Gegenstaende kannst Du unmoeglich tragen!";
+
+            if (dest == environment())
+                return "Dafuer ist hier nicht mehr genug Platz.";
+
+            if (living(dest))
+                return dest->Name(WER, 1) + " kann "  + wen0 +
+                       " nicht mehr tragen.";
+
+            return "Dafuer ist nicht mehr genug Platz in " +
+                   dest->name(WEM, 1) + ".";
+
+        default:
+            if (dest == this_object())
+                return "Du kannst " + wen1 + " nicht nehmen.";
+
+            if (dest == environment())
+                return "Du kannst " + wen1 + " nicht wegwerfen!";
+
+            if (living(dest))
+                return "Du kannst " + wen1 + " nicht weggeben.";
+
+            return capitalize(wen0 + " kannst Du dort nicht hineinstecken.");
+    }
+    return 0; // NOT REACHED
+}
+
+
+/* varargs int drop(object o, mixed msg)
+ * varargs int put(object o, object dest, mixed msg)
+ * varargs int pick(object o, mixed msg)
+ * varargs int give(object o, object dest, mixed msg)
+ * varargs int show(object o, object dest, mixed msg)
+ *
+ * Der Spieler nimmt/legt/gibt/zeigt/laesst ein Objekt fallen, wobei die
+ * entsprechenden oder optional abweichende (im Format von P_XXX_MSG) oder
+ * gar keine (msg == 1) Meldungen ausgegeben werden. Es liegt in der
+ * Verantwortung des Rufenden, sinnvolle Werte zu uebergeben; insbesondere
+ * wird nicht geprueft, ob sich die Objekte in der Reichweite des Spielers
+ * befinden. Gibt 1 zurueck, wenn das Objekt bewegt wurde, sonst 0.
+ */
+
+varargs int drop(object o, mixed msg)
+{
+    string str;
+
+    // vorher speichern, falls das Objekt zerstoert wird
+    cl = symbol_function("name", o);
+    wen0 = funcall(cl, WEN, 0);
+    wen1 = funcall(cl, WEN, 1);
+    wer0 = 0;
+
+    if (!msg)
+        msg = o->QueryProp(P_DROP_MSG);
+
+    if (str = put_or_get(o, environment())) {
+        TME(str);
+        return 0;
+    }
+
+    if (!msg) {
+        TME("Du laesst " + wen1 + " fallen.");
+        SAY(Name(WER,1) + " laesst " + wen0 + " fallen.");
+    } else if (pointerp(msg))
+        switch (sizeof(msg)) {
+          // Wenn es zwei Strings gibt, geht die 2. ans Environment
+          case 2:
+            SAY(replace_personal(msg[1], ({this_object(), o||wen0}), 1));
+          case 1:
+            TME(replace_personal(msg[0], ({this_object(), o||wen1}), 1));
+            break;
+          default:
+            raise_error(sprintf(
+                "Falsches Format fuer P_DROP_MSG: %O\n", o||wen1));
+        }
+
+    return 1;
+}
+
+varargs int put(object o, object dest, mixed msg)
+{
+    string str;
+
+    // Falls das jemand von aussen ruft und Schrott uebergibt...
+    //if (living(dest))
+    //    raise_error(sprintf("Lebendes Ziel fuer put(): %O\n", dest));
+    if (dest == environment())
+        raise_error("Ziel fuer put() ist Umgebung des Spielers\n");
+
+    // vorher speichern, falls das Objekt zerstoert wird
+    cl = symbol_function("name", o);
+    wen0 = funcall(cl, WEN, 0);
+    wen1 = funcall(cl, WEN, 1);
+    wer0 = funcall(cl, WER, 0);
+
+    if (!msg)
+        msg = o->QueryProp(P_PUT_MSG);
+
+    if (str = put_or_get(o, dest)) {
+        TME(str);
+        return 0;
+    }
+
+  
+    if (!msg) {
+        TME("Du steckst " + wen1 + " in " + dest->name(WEN, 1) + ".");
+        if (environment())
+	  SAY(Name(WER, 1) + " steckt " + wen0 +
+	      " in " + dest->name(WEN, 0) + ".");
+    }
+    else if (pointerp(msg)) {
+        switch (sizeof(msg)) {
+          case 2:
+            if (environment())
+	      SAY(replace_personal(msg[1], ({this_object(), o||wen0, dest}), 1));
+          case 1:
+            TME(replace_personal(msg[0], ({this_object(), o||wen1, dest}), 1));
+            break;
+          default:
+            raise_error(sprintf(
+                "Falsches Format fuer P_PUT_MSG: %O\n",o||wen1));
+        }
+    }
+
+    return 1;
+}
+
+varargs int pick(object o, mixed msg)
+{
+    string str;
+
+    // vorher speichern, falls das Objekt zerstoert wird
+    cl = symbol_function("name", o);
+    wen0 = 0;
+    wen1 = funcall(cl, WEN, 1);
+    wer0 = 0;
+
+    if (!msg)
+        msg = o->QueryProp(P_PICK_MSG);
+
+    if (str = put_or_get(o, this_object())) {
+        TME(str);
+        return 0;
+    }
+
+    if (!msg) {
+        TME("Du nimmst " + wen1 + ".");
+        SAY(Name(WER, 1) + " nimmt " + wen1 + ".");
+    } else if (pointerp(msg))
+        switch (sizeof(msg)) {
+          case 2:
+            SAY(replace_personal(msg[1], ({this_object(), o||wen1}), 1));
+          case 1:
+            TME(replace_personal(msg[0], ({this_object(), o||wen1}), 1));
+            break;
+          default:
+            raise_error(sprintf(
+                "Falsches Format fuer P_PICK_MSG: %O\n", o||wen1));
+        }
+
+    return 1;
+}
+
+varargs int give(object o, object dest, mixed msg)
+{
+    string zname, gname;
+    string str;
+
+    // Falls das jemand von aussen ruft und Schrott uebergibt...
+    if (!living(dest))
+        raise_error(sprintf("Totes Ziel fuer give(): %O\n", dest));
+
+    zname = dest->name(WEM, 1);
+    gname = Name(WER, 1);
+
+    // vorher speichern, falls das Objekt zerstoert wird
+    cl = symbol_function("name", o);
+    wen0 = funcall(cl, WEN, 0);
+    wen1 = funcall(cl, WEN, 1);
+    wer0 = 0;
+
+    if (!msg)
+        msg = o->QueryProp(P_GIVE_MSG);
+
+    if (str = put_or_get(o, dest)) {
+        TME(str);
+        return 0;
+    }
+
+    if (!msg) {
+        TME("Du gibst " + zname + " " + wen1 + ".");
+        TOB(dest, gname + " gibt Dir " + wen0 + ".");
+        SAY2(({dest}), gname + " gibt " + zname + " " + wen0 + ".");
+    } else if (pointerp(msg))
+        switch (sizeof(msg)) {
+          case 3:
+            TOB(dest, replace_personal(
+                msg[2], ({this_object(), o||wen0, dest||zname}), 1));
+          case 2:
+            SAY2(({dest, this_object()}), replace_personal(
+                 msg[1], ({this_object(), o||wen0, dest||zname}), 1));
+          case 1:
+            TME(replace_personal(
+                msg[0], ({this_object(), o||wen1, dest||zname}), 1));
+            break;
+          default:
+            raise_error(sprintf(
+                "Falsches Format fuer P_GIVE_MSG: %O\n", o||wen1));
+        }
+
+    if (!query_once_interactive(dest))
+        dest->give_notify(o);
+
+    return 1;
+}
+
+varargs int show(object o, object whom, mixed msg)
+{
+    string zname, gname;
+    string wen0, wen2, long;
+
+    zname = whom ? whom->name(WEM, 1) : "allen";
+    gname = Name(WER, 1);
+
+    if (!msg)
+        msg = o->QueryProp(P_SHOW_MSG);
+
+    if (environment(o) == this_object() ||
+        environment(environment(o)) == this_object()) {
+        wen0 = o->name(WEN, 0);
+
+        /* Der Akkusativ muss mit dem unbestimmten Artikel gebildet werden,
+         * damit eventuelle Adjektive die richtige Endung besitzen.
+         * (ein kleines Schwert -> kleines Schwert -> Dein kleines Schwert)
+         */
+
+        if (o->QueryProp(P_ARTICLE) && member(wen0, ' ') >= 0) {
+            int obgender = o->QueryProp(P_GENDER);
+            int obnum = o->QueryProp(P_AMOUNT) > 1 ? PLURAL : SINGULAR;
+
+            // Wichtig: P_AMOUNT ist 0 fuer Objekte, die nicht von unit erben.
+            // Da unit.c kein P_AMOUNT==0 zulaesst, nehmen wir diesen Fall als
+            // singular an. *Rumata
+
+            wen2 = wen0[member(wen0, ' ')..];
+            wen0 = QueryPossPronoun(o, WEN, obnum) + wen2;
+
+            if (obnum == PLURAL || obgender == FEMALE)
+                wen2 = "Deine" + wen2;
+            else if (obgender == MALE)
+                wen2 = "Deinen" + wen2;
+            else
+                wen2 = "Dein" + wen2;
+        } else
+            wen2 = wen0;
+    } else
+        wen2 = wen0 = o->name(WEN, 1);
+
+    // vorher speichern, falls das Objekt im catch_tell() zerstoert wird
+    long = o->long(4);
+
+    if (!msg) {
+        TME("Du zeigst " + zname + " " + wen2 + ".");
+        if (!whom)
+            SAY(gname + " zeigt Dir " + wen0 + ".");
+        else {
+            TOB(whom, gname + " zeigt Dir " + wen0 + ".");
+            SAY2(({whom}), gname + " zeigt " + zname + " " + wen0 + ".");
+        }
+    } else if (pointerp(msg))
+        switch (sizeof(msg)) {
+          case 3:
+            if (whom)
+                TOB(whom, replace_personal(
+                    msg[2], ({this_object(), o||wen0, whom||zname}), 1));
+            else
+                SAY(replace_personal(
+                    msg[2], ({this_object(), o||wen0, whom||zname}), 1));
+          case 2:
+            if (whom)
+                SAY2(({whom, this_object()}), replace_personal(
+                     msg[1], ({this_object(), o||wen0, whom||zname}), 1));
+          case 1:
+            TME(replace_personal(
+                msg[0], ({this_object(), o||wen2, whom||zname}), 1));
+            break;
+          default:
+            raise_error(sprintf(
+                "Falsches Format fuer P_SHOW_MSG: %O\n", o||wen0));
+        }
+
+    if (!whom)
+        SAY(long);
+    else {
+        TOB(whom, long);
+        if (!query_once_interactive(whom))
+            whom->show_notify(o);
+    }
+
+    return 1;
+}
+
+
+/***************************** Hilfsfunktionen *****************************/
+
+/* private object *__find_objects(string *tokens, object env, int is_source);
+ * object *find_objects(string what, object env, int is_source);
+ *
+ * Sucht im Raum und im Spieler (oder alternativ in der angegebenen Umgebung)
+ * nach den in tokens/what bezeichneten Objekten. is_source bestimmt die
+ * erwartete grammatische Form (0 fuer "topf auf herd" und 1 fuer "topf von
+ * herd", siehe Manpage).
+ */
+ 
+private object *__find_objects(string *tokens, object env, int is_source)
+{
+    object ob, *obs;
+
+    // is_source == 0: Objekt soll nicht bewegt werden ("topf auf herd")
+    //              1: Objekt soll bewegt werden ("topf von herd")
+    //              2: intern
+
+    if (!env && sizeof(tokens) > 1 && tokens[<1] == "hier") {
+        tokens = tokens[..<2];
+        env = environment();
+    }
+    else if (!env && sizeof(tokens) > 2 && tokens[<2] == "in")
+    {
+        if (tokens[<1] == "mir" ||
+            tokens[<1] == "dir") {
+            tokens = tokens[..<3];
+            env = this_object();
+        }
+        else if (tokens[<1] == "raum") {
+            tokens = tokens[..<3];
+            env = environment();
+        }
+    }
+
+    for (int i = sizeof(tokens)-1; i > 1; i--) {
+        if (env)
+            ob = present(implode(tokens[i..], " "), env);
+        else
+            ob = present(implode(tokens[i..], " "), environment()) ||
+                 present(implode(tokens[i..], " "), this_object());
+
+        if (!ob)
+            continue;
+
+        if (living(ob)) {
+            NF("Aber " + ob->name(WER, 1) + " lebt doch!");
+            continue;
+        }
+
+        if (ob->QueryProp(P_CNT_STATUS)) {
+            NF("Aber " + ob->name(WER, 1) + " ist doch geschlossen!");
+            continue;
+        }
+
+        if (is_source != 0 &&
+            tokens[i-1] == ob->QueryProp(P_SOURCE_PREPOSITION))
+            return ob->present_objects(implode(tokens[..i-2], " "));
+
+        if (tokens[i-1] == ob->QueryProp(P_PREPOSITION))
+            return __find_objects(tokens[..i-2], ob, is_source ? 2 : 0);
+
+        NF("Du kannst nichts " + tokens[i-1] + " " +
+           ob->name(WEM, 1) + " nehmen.");
+    }
+
+    if (is_source == 2)
+        return ({});
+
+    if (env)
+        return env->present_objects(implode(tokens, " "));
+
+    if (environment() &&
+        sizeof(obs = environment()->present_objects(implode(tokens, " "))))
+        return obs;
+
+    return present_objects(implode(tokens, " "));
+}
+
+object *find_objects(string what, object env, int is_source)
+{
+  if (!stringp(what) || !sizeof(what))
+    return ({});
+  return __find_objects(explode(what, " "), env, is_source);
+}
+
+
+/* varargs int drop_objects(string str, mixed msg);
+ * varargs int put_objects(string str, int casus, string verb, mixed msg);
+ * varargs int pick_objects(string str, int flag, mixed msg);
+ * varargs int give_objects(string str, mixed msg);
+ * varargs int show_objects(string str, mixed msg);
+ *
+ * Ein Befehl wie "wirf waffen weg" resultiert in einem Aufruf von
+ * drop_objects("waffen"). Diese Funktionen sind hauptsaechlich fuer die
+ * Behandlung der jeweiligen Kommandos vorgesehen, koennen jedoch auch fuer
+ * eigene Befehle verwendet werden. put_objects() erwartet ausserdem den
+ * Kasus ("Du kannst nichts an DER Pinwand befestigen.") und das verwendete
+ * Verb in der Gundform ("befestigen"). Das Flag fuer pick_objects() gibt
+ * an, ob das Objekt auch einfach herumliegen darf ("nimm ...") oder nicht
+ * ("hole ..."). Gibt bei Erfolg 1, sonst 0 zurueck.
+ */
+
+varargs int drop_objects(string str, mixed msg)
+{
+    object *obs;
+
+    if (!sizeof(obs = find_objects(str, this_object(), 1)))
+        return 0;
+
+    foreach (object o: obs) {
+        if (objectp(o))
+            drop(o, msg);
+
+        if (get_eval_cost() < 100000) {
+            TME("Den Rest behaeltst Du erst mal.");
+            last_moved_objects = obs[..member(obs, o)];
+            last_moved_where = 0;
+            return 1;
+        }
+    }
+
+    last_moved_objects = obs;
+    last_moved_where = 0;
+    return 1;
+}
+
+varargs int put_objects(string str, int casus, string verb, mixed msg)
+{
+    object *obs, dest, *no_move;
+    
+    if (!stringp(str) || !sizeof(str)) return 0;
+
+    string *tokens = explode(str, " ");
+    int allow_room = 1;
+    int allow_me = 1;
+
+    if (sizeof(tokens) > 1 && tokens[<1] == "hier") {
+        tokens = tokens[..<2];
+        allow_me = 0;
+    } else if (sizeof(tokens) > 2 && tokens[<2] == "in")
+        if (tokens[<1] == "mir" ||
+            tokens[<1] == "dir") {
+            tokens = tokens[..<3];
+            allow_room = 0;
+        } else if (tokens[<1] == "raum") {
+            tokens = tokens[..<3];
+            allow_me = 0;
+        }
+
+    for (int i = sizeof(tokens)-1; i > 1; i--) {
+        if (!(dest = allow_room && present(implode(tokens[i..], " "),
+                                           environment())) &&
+            !(dest = allow_me && present(implode(tokens[i..], " "),
+                                         this_object())))
+            continue;
+
+        if (living(dest)) {
+            NF("Aber " + dest->name(WER, 1) + " lebt doch!");
+            continue;
+        }
+/*
+        if (verb == "legen" && !dest->QueryProp(P_TRAY)) {
+            NF("Du kannst nichts auf " + dest->name(WEN, 1) + " legen.");
+            continue;
+        }
+*/
+        if (verb == "stecken" && !dest->QueryProp(P_CONTAINER)) {
+            NF("Du kannst in " + dest->name(WEN, 1) + " nichts reinstecken.");
+            continue;
+        }
+
+        if (dest->QueryProp(P_CNT_STATUS)) {
+            NF("Aber " + dest->name(WER, 1) + " ist doch geschlossen!");
+            continue;
+        }
+
+        if (tokens[i-1] != dest->QueryProp(P_DEST_PREPOSITION)) {
+            NF("Du kannst nichts " + tokens[i-1] + " " +
+               dest->name(casus, 1) + " " + verb + ".");
+            continue;
+        }
+
+        if (!sizeof(obs = __find_objects(tokens[..i-2], 0, 1) - ({ dest }))) {
+            NF("WAS moechtest Du " + tokens[i-1] + " " +
+               dest->name(casus, 1) + " " + verb + "?");
+            return 0;
+        }
+
+        if (sizeof(no_move = obs & all_inventory(dest))) {
+            TME(capitalize(CountUp(map_objects(no_move, "name", WER, 1))) +
+                (sizeof(no_move) == 1 ? " ist" : " sind") +
+                " doch bereits in " + dest->name(WEM,1) + ".");
+            if (!sizeof(obs -= no_move))
+                return 0;
+        }
+
+        foreach (object o: obs) {
+            if (objectp(o))
+                put(o, dest, msg);
+
+            if (get_eval_cost() < 100000) {
+                TME("Den Rest laesst Du erst mal, wo er ist.");
+                last_moved_objects = obs[..member(obs, o)];
+                last_moved_where = dest;
+                return 1;
+            }
+        }
+
+        last_moved_objects = obs;
+        last_moved_where = dest;
+        return 1;
+    }
+    
+    return 0;
+}
+
+varargs int pick_objects(string str, int flag, mixed msg)
+{
+    object *obs;
+
+    if (((int)QueryProp(P_MAX_HANDS)) < 1){
+        NF("Ohne Haende kannst Du nichts nehmen.");
+        return 0;
+    }
+
+    if (!sizeof(obs = find_objects(str, 0, 1) - all_inventory()
+	  - (flag ? all_inventory(environment()) : ({}))))
+        return 0;
+
+    foreach (object o: obs) {
+        if (objectp(o))
+            pick(o, msg);
+
+        if (get_eval_cost() < 100000) {
+            TME("Den Rest laesst Du erst mal liegen.");
+            last_moved_objects = obs[..member(obs, o)];
+            last_moved_where = 0;
+            return 1;
+        }
+    }
+
+    last_moved_objects = obs;
+    last_moved_where = 0;
+    return 1;
+}
+
+varargs int give_objects(string str, mixed msg)
+{
+    object *obs, dest;
+    
+    if (!stringp(str) || !sizeof(str)) return 0;
+
+    string *tokens = explode(str, " ");
+
+    if (((int)QueryProp(P_MAX_HANDS)) < 1){
+        NF("Ohne Haende kannst Du nichts weggeben.");
+        return 0;
+    }
+
+    for (int i = 0; i < sizeof(tokens)-1; i++) {
+        if (!(dest = present(implode(tokens[..i], " "), environment())))
+            continue;
+
+        if (!living(dest)) {
+            NF("Aber " + dest->name(WER, 1) + " lebt doch gar nicht!");
+            dest = 0;
+            continue;
+        }
+
+        if (!sizeof(obs = __find_objects(tokens[i+1..], 0, 1))) {
+            NF("WAS moechtest Du " + dest->name(WEM, 1)+" geben?");
+            dest = 0;
+        } else
+            break;
+    }
+
+    if (!dest) {
+        int pos;
+
+        if ((pos = strrstr(str, " an ")) >= 0) {
+            dest = present(str[pos+4..], environment());
+            // zu gebende Objekte in Env + Living suchen
+            obs = find_objects(str[..pos-1], 0, 1);
+        }
+    }
+
+    if (!dest || !living(dest) || !sizeof(obs))
+        return 0;
+
+    foreach (object o: obs) {
+        if (objectp(o))
+            give(o, dest, msg);
+
+        if (get_eval_cost() < 100000) {
+            TME("Den Rest behaeltst Du erst mal.");
+            last_moved_objects = obs[..member(obs, o)];
+            last_moved_where = dest;
+            return 1;
+        }
+    }
+
+    last_moved_objects = obs;
+    last_moved_where = dest;
+    return 1;
+}
+
+varargs int show_objects(string str, mixed msg)
+{
+    object *obs, whom;
+    
+    if (!stringp(str) || !sizeof(str))
+      return 0;
+
+    string *tokens = explode(str, " ");
+
+    for (int i = 0; i < sizeof(tokens)-1; i++) {
+        if (whom = present(implode(tokens[..i], " "), environment())) {
+            if (!living(whom)) {
+                NF("Aber " + whom->name(WER, 1) + " lebt doch gar nicht!");
+                continue;
+            }
+        } else {
+            if (i != 0 || tokens[0] != "allen")
+                continue;
+
+            if (!sizeof(filter(all_inventory(environment()) -
+                    ({ this_object() }), #'living))) {
+                NF("Hier ist niemand, dem Du etwas zeigen koenntest!");
+                continue;
+            }
+        }
+
+        if (whom == this_object()) {
+            NF("Dazu solltest Du dann besser 'schau' benutzen!\n");
+            continue;
+        }
+
+        if (!sizeof(obs = __find_objects(tokens[i+1..], this_object(), 0)) &&
+            !sizeof(obs = __find_objects(tokens[i+1..], 0, 0)
+                            - ({ this_object(), whom }))) {
+            NF("WAS moechtest Du " + (whom ? whom->name(WEM, 1) : "allen") +
+               " zeigen?");
+            continue;
+        }
+
+        foreach (object o: obs) {
+            if (objectp(o))
+                show(o, whom, msg);
+
+            if (get_eval_cost() < 100000) {
+                TME("Das reicht erst mal.");
+                last_moved_objects = obs[..member(obs, o)];
+                last_moved_where = whom;
+                return 1;
+            }
+        }
+
+        last_moved_objects = obs;
+        last_moved_where = whom;
+        return 1;
+    }
+
+    return 0;
+}
+
+object *moved_objects(void)
+{
+    return last_moved_objects;
+}
+
+object moved_where(void)
+{
+    return last_moved_where;
+}
+
+
+/************************* Die einzelnen Kommandos **************************/
+
+/* static int fallenlassen(string str)
+ * static int werfen(string str)
+ * static int legen(string str)
+ * static int stecken(string str)
+ * static int holen(string str)
+ * static int nehmen(string str)
+ * static int geben(string str)
+ *   Minimale Wrapper fuer XXX_objects(), entfernen "fallen", "weg" bzw. "ab"
+ *   aus den Argumenten und setzen entsprechende Standard-Fehlermeldungen.
+ *   
+ * protected void add_put_and_get_commands()
+ *   Registriert obige Funktionen per add_action().
+ */
+
+static int fallenlassen(string str)
+{
+    if (QueryProp(P_GHOST)) {
+        _notify_fail("Als Geist kannst Du nichts fallenlassen.\n");
+        return 0;
+    }
+
+    if (!str || str[<7..] != " fallen") {
+        _notify_fail("Lass etwas FALLEN, oder was meinst Du?\n");
+        return 0;
+    }
+
+    _notify_fail("WAS moechtest Du fallenlassen?\n");
+    return drop_objects(str[0..<8]);
+}
+
+static int werfen(string str)
+{
+    if (QueryProp(P_GHOST)) {
+        _notify_fail("Als Geist kannst Du nichts wegwerfen.\n");
+        return 0;
+    }
+
+    if (!str || str[<4..] != " weg") {
+        _notify_fail("Wirf etwas WEG, oder was meinst Du?\n");
+        return 0;
+    }
+
+    _notify_fail("WAS moechtest Du loswerden?\n");
+    return drop_objects(str[0..<5]);
+}
+
+static int legen(string str)
+{
+    if (QueryProp(P_GHOST)) {
+        _notify_fail("Als Geist kannst Du nichts weglegen.\n");
+        return 0;
+    }
+
+    if (!str) {
+        _notify_fail("Lege etwas AB, oder was meinst Du?\n");
+        return 0;
+    }
+
+    if (str[<3..] == " ab") {
+        _notify_fail("WAS moechtest Du ablegen?\n");
+        return drop_objects(str[0..<4]);
+    }
+
+    if (str[<4..] == " weg") {
+        _notify_fail("WAS moechtest Du weglegen?\n");
+        return drop_objects(str[0..<5]);
+    }
+
+    _notify_fail("WAS moechtest Du WOHIN legen?\n");
+    return put_objects(str, WEN, "legen");
+}
+
+static int stecken(string str)
+{
+    if (QueryProp(P_GHOST)) {
+        _notify_fail("Das kannst Du in Deinem immateriellen Zustand nicht.\n");
+        return 0;
+    }
+
+    _notify_fail("WAS moechtest Du WOHIN stecken?\n");
+    return put_objects(str, WEN, "stecken");
+}
+
+static int holen(string str)
+{
+    if (QueryProp(P_GHOST)) {
+        _notify_fail("Als Geist kannst Du nichts nehmen.\n");
+        return 0;
+    }
+
+    _notify_fail("WAS moechtest Du aus WAS holen?\n");
+    return pick_objects(str, 1);
+}
+
+static int nehmen(string str)
+{
+    if (QueryProp(P_GHOST)) {
+        _notify_fail("Als Geist kannst Du nichts nehmen.\n");
+        return 0;
+    }
+
+    _notify_fail("WAS moechtest Du nehmen?\n");
+    return pick_objects(str, 0);
+}
+
+static int geben(string str)
+{
+    if (QueryProp(P_GHOST)) {
+        _notify_fail("Als Geist kannst Du nichts weggeben.\n");
+        return 0;
+    }
+
+    _notify_fail("WEM moechtest Du WAS geben?\n");
+    return give_objects(str);
+}
+
+static int zeigen(string str)
+{
+    if (QueryProp(P_GHOST)) {
+        _notify_fail("Als Geist kannst Du niemandem etwas zeigen.\n");
+        return 0;
+    }
+
+    _notify_fail("WEM moechtest Du WAS zeigen?\n");
+    return show_objects(str);
+}
+
+protected void add_put_and_get_commands(void)
+{
+    add_action("fallenlassen", "lass");
+    add_action("fallenlassen", "lasse");
+    add_action("werfen",       "wirf");
+    add_action("werfen",       "werf");
+    add_action("werfen",       "werfe");
+    add_action("legen",        "leg");
+    add_action("legen",        "lege");
+    add_action("stecken",      "steck");
+    add_action("stecken",      "stecke");
+    add_action("holen",        "hol");
+    add_action("holen",        "hole");
+    add_action("nehmen",       "nimm");
+    add_action("nehmen",       "nehm");
+    add_action("nehmen",       "nehme");
+    add_action("geben",        "gebe");
+    add_action("geben",        "gib");
+    add_action("zeigen",       "zeig");
+    add_action("zeigen",       "zeige");
+}
+
+
+/********** Aus reinen Kompatibilitaetsgruenden weiterhin enthalten *********/
+
+object* find_obs(string str, int meth)
+// gibt ein array zurueck mit allen Objekten die mit str angesprochen werden
+{
+   object inv;
+   if (!str) return 0;
+   if (str[<7..]==" in mir") {
+     inv=ME;
+     str=str[0..<8];
+   }
+   else if (str[<8..]==" in raum") {
+     if (meth & PUT_GET_DROP) { // man kann nichts aus dem Raum wegwerfen
+       _notify_fail("Du kannst nichts wegwerfen, das Du gar nicht hast.\n");
+       return 0;
+     }
+     inv=environment();
+     str=str[0..<9];
+   }
+   else if (meth & PUT_GET_DROP) inv=ME; // Raum bei drop uninteressant
+   // else kein besonderes inv ausgewaehlt also inv=0
+   if (!sizeof(str))
+     return 0; // hier passt die bereits gesetzte _notify_fail
+   else {
+     object *obs;
+     string con;
+     if (sscanf(str, "%s aus %s", str, con)==2 ||
+         sscanf(str, "%s in %s", str, con)==2 ||
+         sscanf(str, "%s von %s", str, con)==2 ||
+         sscanf(str, "%s vom %s", str, con)==2) {
+       if (!inv) {
+         if (!environment() || !(inv=present(con, environment())))
+            inv=present(con, ME); // sowohl im env als auch im inv suchen
+       }
+       else inv=present(con, inv); // nur in ausgewaehltem inv suchen
+       if (inv==ME) inv=0;
+       if (!inv || !(inv->short())) {
+         _notify_fail(break_string("Du hast hier aber kein '"+capitalize(con)
+                                 +"'.",78));
+         return 0;
+       }
+       if (living(inv)) {
+         _notify_fail(break_string("Aber "+inv->name(WER,1)+" lebt doch!",78));
+         return 0;
+       }
+       // wieso man aus Objekten die von std/tray abgeleitet werden etwas
+       // nehmen koennen soll, versteh ich zwar nicht so ganz...
+       if (!(inv->QueryProp(P_CONTAINER)) && !(inv->QueryProp(P_TRAY))) {
+         _notify_fail(break_string("Du kannst nichts aus "+inv->name(WEM,1)
+                                 +" nehmen.",78));
+         return 0;
+       }
+       if (inv->QueryProp(P_CNT_STATUS)) { // Container ist geschlossen
+         _notify_fail(break_string("Aber "+inv->name(WER,1)
+                                 +" ist doch geschlossen.", 78));
+         return 0;
+       }
+     }
+     else if (inv==ME && (meth & PUT_GET_TAKE)) { // nichts aus sich nehmen
+       _notify_fail("Du kannst nichts nehmen, "
+                    "was Du schon bei Dir traegst.\n");
+       return 0;
+     }
+     if (!inv && (meth & PUT_GET_TAKE))
+       inv=environment(); // nichts nehmen was man schon hat
+
+     if (!inv) {
+       if (environment()) {
+         obs=(environment()->present_objects(str)||({}));
+         if (!sizeof(obs)) obs+=(ME->present_objects(str)||({}));
+       }
+       else obs=(ME->present_objects(str) || ({}));
+     }
+     else obs=(inv->present_objects(str) || ({}));
+     return obs-({ ME });
+   }
+   return(0);
+}
+
+int pick_obj(object ob)
+{
+  object env;
+
+  if (!ob || ob == this_object() || environment(ob) == this_object()) return 0;
+  if ((env=environment(ob)) != environment()) {
+    if (!env->QueryProp(P_CONTAINER) && !env->QueryProp(P_TRAY)) {
+      TME("Du kannst nichts aus " + env->name(WEM,1) + " nehmen.");
+      return 1;
+    }
+    else if (env->QueryProp(P_CNT_STATUS)) {  // Container ist geschlossen
+      TME("Aber " + env->name(WER, 1) + " ist doch geschlossen.");
+      return 1;
+    }
+  }
+  if (ob->IsUnit() && ob->QueryProp(P_AMOUNT)<0) {
+    TME("Du kannst nicht mehr nehmen als da ist.");
+    return 1;
+  }
+  pick(ob);
+  return 1;
+}
+
+int drop_obj(object ob)
+{
+  if (!ob || ob==this_object() || environment(ob)!=this_object()) return 0;
+  drop(ob);
+  return 1;
+}
+
+int put_obj(object ob, object where)
+{
+  object env;
+
+  if (ob == this_object() || ob == where || environment(ob) == where) return 0;
+  env=environment(ob);
+  if (!where->QueryProp(P_CONTAINER)) {
+    TME("Du kannst in " + where->name(WEN,1) + " nix reinstecken.");
+    return 1;
+  }
+  if (where->QueryProp(P_CNT_STATUS)) {  // Container ist geschlossen
+    TME("Aber " + where->name(WER, 1) + " ist doch geschlossen.");
+    return 1;
+  }
+  if (env!=environment(this_object()) && env!=this_object()) {
+    _notify_fail("Da kommst du so nicht ran.\n");
+    return 0;
+  }
+  put(ob, where);
+  return 1;
+}
+
+int give_obj(object ob, object where)
+{
+  object env;
+
+  if (environment(ob)!=this_object()) {
+    TME("Das solltest Du erstmal nehmen.");
+    return 1;
+  }
+  if (!ob || ob == this_object() || ob == where ||
+      environment(where)!=environment())
+    return 0;
+  if (environment(ob) == where) {
+    _notify_fail("Das Ziel ist in dem zu gebenden Object enthalten!\n");
+    return 0;
+  }
+  if (environment(ob)!=this_object()) {
+    TME("Das hast Du nicht.");
+    return 1;
+  }
+  give(ob, where);
+  return 1;
+}
