// 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 + " "
             + 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 (((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;

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

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