// 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

#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|int> 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:
            str = o->QueryProp(P_NODROP);
            if (o && stringp(str) && sizeof(str))
                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:
            str = o->QueryProp(P_NOGET);
            if (o && stringp(str) && sizeof(str))
                return str;

            if (environment(o) &&
                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:
            if (environment(o) &&
                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 + " "
             + dest->QueryProp(P_DEST_PREPOSITION) + " "
             + dest->name(WEN, 1) + ".");
        if (environment())
            SAY(Name(WER, 1) + " steckt " + wen0 + " "
                + dest->QueryProp(P_DEST_PREPOSITION) + " "
                + 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: Kennzeichnet rekursiven Aufruf, falls Objekt bewegt
    //                 werden soll.

    // ganz am Ende von den tokens steht ggf. der vom User gewuenschte Anfang
    // der Suche nache dem Objekt (z.B. "fackel aus truhe hier" oder "seil aus
    // paket in mir".
    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--) {
        // wird fangen am Ende der Tokens an und arbeiten uns wortweise nach
        // vorne, um ein Objekt zu finden. (z.B. "... in paket 12" wuerde 2
        // Durchlaeufe brauchen)
        if (env)
            ob = present(implode(tokens[i..], " "), env);
        else
            ob = present(implode(tokens[i..], " "), environment()) ||
                 present(implode(tokens[i..], " "), this_object());

        if (!ob)
            continue;

        // aus Lebewesen darf man nix rausnehmen oder reingucken
        if (living(ob)) {
            NF("Aber " + ob->name(WER, 1) + " lebt doch!");
            continue;
        }

        // und aus geschlossenen Containern auch nicht.
        if (ob->QueryProp(P_CNT_STATUS)) {
            NF("Aber " + ob->name(WER, 1) + " ist doch geschlossen!");
            continue;
        }
        // Wenn was rausgenommen werden soll und jetzt vor dem gefundenen
        // Container die passende Praeposition steht (z.B. "aus"), wird
        // angenommen, dass der vordere Teil der Tokens zu aus diesem
        // Container zu nehmende Objekt bezeichnet und in present_objects
        // dieses Containers verzweigt.
        if (is_source != 0 &&
            tokens[i-1] == ob->QueryProp(P_SOURCE_PREPOSITION))
            return ob->present_objects(implode(tokens[..i-2], " "));

        // Wenn vor dem gefundenen Objekt dessen normale Praeposition steht
        // (z.B. "in", "auf"), wird rekursiv geschaut, ob der vordere Teil der
        // Tokens erneut einen Container bezeichnet. is_source==2 wird
        // uebergebeb, damit in der Rekursion nur Objekte vor der
        // P_SOURCE_PREPOSITION geliefert werden, aber keine aus
        // Environment/this_object() (s.u. nach der Schleife).
        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 ({});
    // wenn das for keine Container gefunden hat (auch:  wenn tokens zu kurz
    // fuers for), wird im uebergebenen env geguckt, ob der vorderste Rest von
    // tokens nen Objekt bezeichnet.
    // geguckt, ob nen pass
    if (env)
        return env->present_objects(implode(tokens, " "));

    // Und wenn kein env uebergeben und gefunden wurde, wird geguckt, ob unser
    // Environment nen passendes Objekt fuer tokens hat...
    if (environment() &&
        sizeof(obs = environment()->present_objects(implode(tokens, " "))))
        return obs;
    // oder eben wir selbst.
    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;

    last_moved_objects=({});
    last_moved_where = 0;
    foreach (object o: obs) {
        if (objectp(o))
            if (drop(o, msg) == 1)
                last_moved_objects+=({o});

        if (get_eval_cost() < 100000) {
            TME("Den Rest behaeltst Du erst mal.");
            return 1;
        }
    }
    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;
        }

        last_moved_objects = ({});
        last_moved_where = dest;

        foreach (object o: obs) {
            if (objectp(o))
                if (put(o, dest, msg) == 1)
                    last_moved_objects += ({o});

            if (get_eval_cost() < 100000) {
                TME("Den Rest laesst Du erst mal, wo er ist.");
                return 1;
            }
        }

        return 1;
    }
    
    return 0;
}

varargs int pick_objects(string str, int flag, mixed msg)
{
    object *obs;

    if (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;

    last_moved_objects = ({});
    last_moved_where = this_object();
    foreach (object o: obs) {
        if (objectp(o))
            if (pick(o, msg) == 1)
                last_moved_objects += ({o});

        if (get_eval_cost() < 100000) {
            TME("Den Rest laesst Du erst mal liegen.");
            return 1;
        }
    }

    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 (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;

    last_moved_objects = ({});
    last_moved_where = dest;
    foreach (object o: obs) {
        if (objectp(o))
            if (give(o, dest, msg) == 1)
                last_moved_objects += ({o});

        if (get_eval_cost() < 100000) {
            TME("Den Rest behaeltst Du erst mal.");
            return 1;
        }
    }
    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;
        }

        last_moved_objects = ({});
        last_moved_where = whom;
        foreach (object o: obs) {
            if (objectp(o))
                if (show(o, whom, msg) == 1)
                    last_moved_objects += ({o});

            if (get_eval_cost() < 100000) {
                TME("Das reicht erst mal.");
                return 1;
            }
        }

        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;
}
