diff --git a/std/room/shop.c b/std/room/shop.c
new file mode 100644
index 0000000..c429127
--- /dev/null
+++ b/std/room/shop.c
@@ -0,0 +1,1110 @@
+#pragma strong_types
+#pragma save_types
+#pragma pedantic
+#pragma range_check
+#pragma no_clone
+
+inherit "/std/trading_price";
+
+#define NEED_PROTOTYPES
+#include <thing/commands.h>
+#include <thing/description.h>
+#undef NEED_PROTOTYPES
+
+#include <defines.h>
+#include <properties.h>
+#include <rooms.h>
+#include <language.h>
+#include <moving.h>
+#include <routingd.h>
+#include <bank.h>
+#include <combat.h>
+#include <input_to.h>
+#include <unit.h>
+#include <money.h>
+
+// TODO: pruefen, um die Variablen private sein koennen.
+
+// allgemein benoetige Variablen
+nosave string storage; // Filename des Stores in dem die Objekte lagern...
+nosave mapping ob_anz; // wie oft ist ein Objekt im Laden vorhanden?
+
+// Jetzt Variablen fuer staendig verfuegbare Objekte:
+nosave string *fixed_obj; // Liste der staendig verfuegbaren Objekte
+nosave mapping fixed_value; // Preise bei Sonderangeboten
+nosave mapping fixed_ids;   // Ids
+
+varargs void AddFixedObject(string str, int val, string|string* ids)
+{
+  int i;
+
+  // Achtung, bei solchen Objekten muss die Blueprint initialisiert werden!
+  if (!str) return;
+  if (!val) val=str->QueryProp(P_VALUE);
+  if (!ids)
+  {
+    if (str->QueryProp("u_ids")) // units haben keine P_IDS
+      ids=str->QueryProp("u_ids")[0];
+    else
+      ids=str->QueryProp(P_IDS);
+  }
+  if (!pointerp(ids))
+  {
+    if (stringp(ids))
+      ids=({ids});
+    else
+      ids=({});
+  }
+
+  fixed_obj += ({str});
+  fixed_value[str] = val;
+  // Alle IDs entfernen, die Sonderzeichen enthalten. Die koennte ein Spieler
+  // bei "kaufe" ohnehin nicht eingeben.
+  ids -= regexp(ids, "[\b\n\r\t]");
+  foreach(string id : ids)
+  {
+    // Nur IDs aufnehmen, die keine Grossbuchstaben enthalten, da Spieler
+    // diese ebenfalls nicht eingeben koennte.
+    if ( lowerstring(id) == id )
+      fixed_ids[id]=str;
+  }
+}
+
+void RemoveFixedObject(string filename)
+{
+  if( !stringp(filename) || !sizeof(fixed_obj))
+    return;
+  if( member(fixed_obj, filename)==-1 )
+    return;
+
+  fixed_obj -= ({ filename });
+  m_delete(fixed_value, filename);
+
+  foreach(string id, string file : fixed_ids)
+  {
+    if ( file == filename )
+      m_delete(fixed_ids, id);
+  }
+}
+
+static string SetStorageRoom(string str)
+{
+  if (str && stringp(str)) return storage=str;
+  return 0;
+}
+
+string QueryStorageRoom()
+{   return storage;   }
+
+protected void create()
+{
+  object router;
+  
+  if (object_name(this_object()) == __FILE__[0..<3])
+  {
+    set_next_reset(-1);
+    return;
+  }
+
+  trading_price::create();
+
+  SetProp( P_NAME, "Haendler" );
+  SetProp( P_GENDER, MALE );
+  SetProp( P_ROOM_TYPE, QueryProp(P_ROOM_TYPE) | RT_SHOP );
+
+  AddCmd("zeige","list");
+  AddCmd(({"kauf","kaufe","bestell","bestelle"}),"buy");
+  AddCmd(({"verkauf","verkaufe","verk"}),"sell");
+  AddCmd(({"versetz","versetze"}),"force_sell");
+  AddCmd(({"schaetz","schaetze"}),"evaluate");
+  AddCmd(({"untersuche","unt"}), "show_obj");
+
+  SetTradingData(50000,300,3);
+
+  ob_anz=([]);
+  fixed_obj=({});fixed_value=([]);fixed_ids=([]);
+
+  AddFixedObject(BOERSE, 80,({ "boerse","geldboerse"}));
+
+  if (!clonep(ME) && objectp(router=find_object(ROUTER)))
+    router->RegisterTarget(TARGET_SHOP,object_name(ME));
+}
+
+protected void create_super() {
+  set_next_reset(-1);
+}
+
+// Legacy-Version von GetShopItems() fuer die erbenden Laeden, die auf
+// die Funktion in dieser Form angewiesen sind.
+static mixed *GetList()
+{
+  object store = load_object(storage);
+  store->_register_shop(ME);
+
+  mixed *output=({});
+  if (!objectp(store))
+    return output;
+
+  mixed tmp = map(fixed_obj, #'load_object)+all_inventory(store);
+  mapping tmp2 = ([]);
+  mixed str;
+  string comp;
+  int i;
+  int s=1;
+
+  for (i=sizeof(tmp)-1 ; i>=0 ; i--)
+  {
+    str = ({ ({ sprintf("%-25.25s%7.7d",
+                        (tmp[i]->short()||"???")[0..<3],
+                        QueryBuyValue(tmp[i], PL)),
+                tmp[i] }) });
+    comp=str[0][0][0..25];
+    if (!tmp2[comp])
+    {
+      tmp2[comp] = s++;
+      output += str;
+    }
+    else output[tmp2[comp]-1][0] = str[0][0];
+  }
+  return output;
+}
+
+// Legacy-Version von PrintList() fuer die erbenden Laeden, die auf
+// die Funktion in dieser Form angewiesen sind.
+static int DoList(string query_fun)
+{
+  mixed* output=GetList();
+  int si = sizeof(output);
+  if (!si)
+  {
+    write("Im Moment sind wir leider VOELLIG ausverkauft!\n");
+    return 1;
+  }
+  string out="";
+  int i;
+  int indent;
+  for (i=0; i<si; i++)
+  {
+    if (call_other(ME, query_fun, output[i][1]))
+    {
+      indent = !indent;
+      out += sprintf("%3d. %s", i+1, output[i][0]);
+      if (!indent)
+        out += "\n";
+      else out += " | ";
+    }
+  }
+  if (indent)
+    out+="\n";
+  PL->More(out);
+  return 1;
+}
+
+// Liefert eine Liste der Objekte zurueck, die gerade im Storage liegen,
+// pro Blueprint jeweils eins.
+protected object* GetShopItems()
+{
+  object store = load_object(storage);
+  store->_register_shop(ME);
+  object* output = ({});
+  object* all_items = all_inventory(store);
+
+  // Wir brauchen eine Liste, die von jeder Blueprint nur einen Clone
+  // enthaelt. Daher werden die Ladenamen der Objekte als Keys im Mapping
+  // <items> verwendet und jeweils der aktuelle Clone als Value zugeordnet.
+  mapping items = m_allocate(sizeof(all_items));
+  foreach(object ob: all_items)
+  {
+    items[load_name(ob)] = ob;
+  }
+  // Die Fixed Objects werden ans Ende angehaengt, damit in dem Fall, dass
+  // ein Clone eines solchen Objektes im Lager liegt, dieser zuerst verkauft
+  // wird und nicht immer wieder ein neuer erstellt wird.
+  return m_values(items) + map(fixed_obj, #'load_object);
+}
+
+#define LIST_LONG  1
+#define LIST_SHORT 0
+
+// Kuemmert sich um die Listenausgabe fuer den Befehl "zeige"
+varargs protected int PrintList(string filter_fun, int liststyle)
+{
+  // Alle Items im Lager holen. Wenn keine vorhanden, tut uns das leid.
+  object *items_in_store = GetShopItems();
+  if ( !sizeof(items_in_store) ) {
+    write("Im Moment sind wir leider VOELLIG ausverkauft!\n");
+    return 1;
+  }
+
+  // Das Listenformat ist von der Spielereingabe abhaengig. Wurde "lang"
+  // angefordert, geben wir einspaltig aus mit groesserer Spaltenbreite.
+  // Die Spaltenbreite wird dabei von dem Item mit dem laengsten Namen im
+  // gesamten Shop-Inventar bestimmt, damit nicht bei jeder Teilliste
+  // (Waffen, Ruestungen, Verschiedenes) unterschiedliche Breiten rauskommen.
+  //
+  // Der erste Parameter enthaelt die Katalognummer des Items, der zweite
+  // die Kurzbeschreibung, der dritte den Preis.
+  string listformat = "%3d. %-25.25s %6.6d";
+  if ( liststyle == LIST_LONG )
+  {
+    string* names = sort_array(
+                      items_in_store->short(),
+                      function int (string s1, string s2) {
+                        return (sizeof(s1) < sizeof(s2));
+                      });
+    // Wenn einspaltig ausgegeben wird, soll die Liste nicht beliebig breit
+    // werden. Daher wird die Short auf 65 Zeichen limitiert.
+    int len = 65;
+    if ( sizeof(names) )
+      len = min(len, sizeof(names[0]));
+    listformat = "%3d. %-"+len+"."+len+"s %6.6d";
+  }
+
+  string out="";
+  // Variablen, die innerhalb der Schleife benoetigt werden.
+  string kurz;
+  int indent, preis;
+  object item;
+  // Ueber die Liste laufen. <i> wird benoetigt, um die ausgegebene Liste
+  // konsistent numerieren zu koennen, damit kaufe <nr> funktioniert.
+  foreach(int i : sizeof(items_in_store))
+  {
+    item = items_in_store[i];
+    if ( call_other(ME, filter_fun, item) )
+    {
+      // Kurzbeschreibung und Preis ermitteln. Items ohne Short werden
+      // als "?" angezeigt.
+      kurz = (item->short() || "???")[0..<3];
+      preis = QueryBuyValue(item, PL);
+      // Beschreibung des Items anfuegen.
+      out += sprintf(listformat, i+1, kurz, preis);
+      indent = !indent;
+      // Wenn indent gesetzt ist, handelt es sich um das linke Item in der
+      // zweispaltigen Liste, dann fuegen wir einen Spaltentrenner an,
+      // ansonsten ist es das rechte, dann brechen wir um.
+      // Gilt natuerlich nur fuer kurze Listen.
+      out += ((indent && liststyle==LIST_SHORT)? " | " : "\n");
+    }
+  }
+  // Wenn die Liste eine ungerade Zahl Items enthaelt, ist in der letzten
+  // Zeile links ein Item aufgefuehrt, daher muss danach umbrochen werden.
+  // Gilt natuerlich nur fuer kurze Listen
+  if (indent && liststyle==LIST_SHORT)
+    out+="\n";
+
+  // Vor den Listen wird eine Info-Zeile ausgegeben, um gefilterte Listen
+  // kenntlich zu machen. Wird nach der Filterung des Inventars erzeugt,
+  // um eine leere Meldung ausgeben zu koennen, wenn nach Filterung nichts
+  // mehr uebrigbleibt.
+  string was;
+  switch(filter_fun)
+  {
+    case "IsArmour": was = "Ruestungen"; break;
+    case "IsWeapon": was = "Waffen"; break;
+    case "NoWeaponNoArmour":
+         was = (out==""?"sonstigen Waren":"sonstige Waren"); break;
+    default: was = "Waren"; break;
+  }
+  // <out> ist ein Leerstring, wenn keine Waren da sind, die dem Filterkri-
+  // terium entsprechen. Dann gibt's eine entsprechende Meldung.
+  if ( out == "" )
+    out = sprintf("Leider sind momentan keine %s im Angebot.\n", was);
+  else
+    out = sprintf("Folgende %s kannst Du hier kaufen:\n",was) + out;
+
+  PL->More(out);
+  return 1;
+}
+
+// Hilfsfunktionen zum Filtern des Ladeninventars fuer den "zeige"-Befehl
+static int AlwaysTrue(object ob)
+{   return 1;   }
+
+static string IsWeapon(object ob)
+{  return ob->QueryProp(P_WEAPON_TYPE);  }
+
+static string IsArmour(object ob)
+{  return ob->QueryProp(P_ARMOUR_TYPE);  }
+
+static int NoWeaponNoArmour(object ob)
+{ return (!ob->QueryProp(P_WEAPON_TYPE) && !ob->QueryProp(P_ARMOUR_TYPE)); }
+
+
+// Diese Funktion ist oeffentlich, falls Magier abfragen wollen, ob ein laden
+// ein Objekt zerstoeren wuerde. Aber: Benutzung auf eigenes Risiko! Es wird
+// nicht garantiert, dass diese Funktion bzw. ihr Interface sich nicht
+// aendert.
+public int CheckForDestruct(object ob) // Pruefen, ob zerstoert werden soll
+{
+  string str;
+  /*
+   * P_NOBUY - Objekte auf jeden Fall zerstoeren
+   */
+  if(ob->QueryProp(P_NOBUY)) return 1;
+  /*
+   * Beschaedigte Objekte werden ebenfalls zerstoert
+   */
+  if(ob->QueryProp(P_DAMAGED)) return 1;
+  /*
+   * Ruestungen wenn sie a) eine DefendFunc definiert haben oder
+   *                     b) ueber der in KEEP_ARMOUR_CLASS definierten AC
+   *                        liegen (siehe /sys/combat.h)
+   */
+  if(str = IsArmour(ob))
+  {
+    if(objectp(ob->QueryProp(P_DEFEND_FUNC))) return 1;
+    if(ob->QueryProp(P_AC) >= KEEP_ARMOUR_CLASS[str]) return 1;
+    return 0;
+  }
+  /*
+   * Waffen wenn sie a) 1-haendig sind und eine WC > 120 besitzen oder
+   *                 b) 2-haendig sind und eine WC > 150 besitzen oder aber
+   *                 c) eine HitFunc definiert haben
+   */
+  if(str = IsWeapon(ob))
+  {
+    if(ob->QueryProp(P_NR_HANDS) > 1 && ob->QueryProp(P_WC) > 150) return 1;
+    if(ob->QueryProp(P_NR_HANDS) < 2 && ob->QueryProp(P_WC) > 120) return 1;
+    if(objectp(ob->QueryProp(P_HIT_FUNC))) return 1;
+    return 0;
+  }
+  return 0;
+}
+
+static int list(string str)
+{
+  _notify_fail(
+    "Bitte 'zeige', 'zeige waffen', 'zeige ruestungen' oder\n"
+    "'zeige verschiedenes' eingeben. Wenn Du das Schluesselwort 'lang'\n"
+    "oder '-1' anhaengst, wird die Liste einspaltig ausgegeben.\n");
+
+  if (!stringp(str) || !sizeof(str) )
+    return PrintList("AlwaysTrue");
+  if ( str == "lang" || str == "-1" )
+    return PrintList("AlwaysTrue", LIST_LONG);
+
+  string *params = explode(str," ");
+  if (sizeof(params[0])<3)
+    return 0;
+
+  int liststyle = LIST_SHORT;
+  if ( sizeof(params)>1 && params[1] == "lang" )
+    liststyle = LIST_LONG;
+
+  str=params[0][0..2];
+  if (str=="waf")
+    return PrintList("IsWeapon", liststyle);
+  if (str=="ver")
+    return PrintList("NoWeaponNoArmour", liststyle);
+  if (str=="rue")
+    return PrintList("IsArmour", liststyle);
+  return 0;
+}
+/*
+static varargs int QueryBuyValue(mixed ob, object client)
+{
+  if (objectp(ob))
+    return trading_price::QueryBuyValue(ob, client);
+  return (fixed_value[ob]*QueryBuyFact(client))/100;
+}
+*/
+
+static varargs int QueryBuyValue(object ob, object client)
+{
+  int fprice = fixed_value[load_name(ob)];
+
+  return (fprice>0) ? 
+         fprice*QueryBuyFact(client)/100 : 
+         trading_price::QueryBuyValue(ob, client);
+}
+
+static void UpdateCounter(object ob, int num)
+{
+  string tmp;
+
+  if (!num || !objectp(ob)) return;
+  tmp=BLUE_NAME(ob);
+  if (tmp[0..2]!="/d/" && tmp[0..8]!="/players/")
+    tmp=ob->short()+tmp;
+  ob_anz[tmp] += num;
+  if (ob_anz[tmp] <= 0)
+    m_delete(ob_anz,tmp);
+}
+
+protected object FindInStore(string|int x)
+{
+  object* list = GetShopItems();
+  if ( intp(x) && x>0 && x<=sizeof(list) ) {
+    return list[x-1];
+  }
+  if (stringp(x))
+  {
+    if ( fixed_ids[x] )
+      return load_object(fixed_ids[x]);
+    list = filter_objects(list, "id", x);
+    if ( sizeof(list) )
+      return list[0];
+    // Wenn nix im Store gefunden (das schliesst eigentlicht schon die BPs der
+    // fixen Objekte ein, aber nicht, wenn diese nicht konfiguriert sind. D.h.
+    // diese Pruefung ist fuer nicht-konfigurierte BPs), Liste der
+    // FixedObjects pruefen unde so die eventuell manuell in
+    // AddFixedObject() angegebene Liste von IDs beruecksichtigen.
+    else if ( fixed_ids[x] )
+      return load_object(fixed_ids[x]);
+  }
+  return 0;
+}
+
+static string buy_obj(mixed ob, int short)
+{ return 0; }
+
+private void really_buy(int val, object pl, object ob, int u_req)
+{
+  // Staendig verfuegbare Objekte (fixed_obj) sind daran erkennbar, dass sie
+  // nicht im Lager liegen. Daher hier einen Clone erstellen, der dann 
+  // stattdessen rausgegeben wird.
+  if ( !present(ob, find_object(storage)) )
+    ob = clone_object(ob);
+
+  // In Unitobjekten U_REQ (wieder) setzen (wegen input_to (bei dem sich das
+  // Kommandoverb aendert und deswegen U_REQ geloescht wird), und wegen
+  // Kaufens von Fixed-Objekt-Unitobjekten (bei diesen muss U_REQ _nach_ dem
+  // Clonen im Clone gesetzt werden, nicht automagisch in der BP durch den
+  // Aufruf von id() weiter vorher).
+  if (u_req>0)
+  {
+    // Das QueryProp() ist nicht unnoetig. Bei der Abfrage von U_REQ wird
+    // U_REQ genullt, wenn das aktuelle query_verb() != dem letzten ist.
+    // Bei der ersten Abfrage wuerde als das hier gesetzt U_REQ wieder
+    // geloescht. Daher muss das jetzt hier als erstes einmal abgefragt
+    // werden...
+      ob->QueryProp(U_REQ);
+      ob->SetProp(U_REQ, u_req);
+  }
+
+  pl->AddMoney(-val);
+  _add_money(val);
+
+  if (ob->move(pl,M_GET) != MOVE_OK) // Kann der Spieler das Objekt tragen?
+  {
+    write(break_string("Du kannst "+ob->name(WEN,1)+" nicht mehr tragen. "
+     "Ich lege "+ob->QueryPronoun(WEN)+" hier auf den Boden.",78,
+     Name(WER)+" sagt: "));
+    ob->move(ME,M_NOCHECK);                         // Nein :-)
+  }
+  else
+  {
+    // Falls das Objekt sich vereinigt hat, muss jetzt wieder U_REQ
+    // restauriert werden.
+    ob->SetProp(U_REQ, u_req);
+    write(break_string("Du kaufst "+ob->name(WEN,1)+".", 78));
+  }
+
+  say(break_string(PL->Name(WER)+" kauft "+ob->name(WEN)+".",78), ({PL}));
+  UpdateCounter(ob,-1);
+}
+
+static void ask_buy(string str, int val, object pl, object ob, int u_req)
+{
+  _notify_fail(break_string("Gut, Du kannst es Dir ja jederzeit "
+   "noch anders ueberlegen.",78,Name(WER)+" sagt: "));
+
+  if(!str || !stringp(str) || str == "nein" || str == "n")
+  {
+    return;
+  }
+  if(str != "ja" && str != "j")
+  {
+    return;
+  }
+  really_buy(val, pl, ob, u_req);
+}
+
+static int buy(string str)
+{
+  int i, val, par, dex;
+  mixed ob, res;
+  string dummy;
+
+  if (!str) {
+    write("Was willst Du kaufen?\n");
+    return 1;
+  }
+
+  if (stringp(QueryProp(P_KEEPER)) && !present(QueryProp(P_KEEPER), ME)) {
+    write("Es ist niemand da, der Dich bedienen koennte.\n");
+    return 1;
+  }
+
+  _notify_fail(break_string("Das kann ich in meinem Lager nicht finden.",78,
+   Name(WER)+" sagt: "));
+
+  // Um auch Teile von Unit-Stacks kaufen zu koennen, z.B. "kaufe 5 phiolen",
+  // darf hier zusaetzlich <dummy> nur ein Leerstring sein, sonst verzweigt
+  // die Syntaxpruefung hierhin und es wird das 5. Item der Liste gekauft.
+  if (sscanf(str,"%d%s",i,dummy)>0 && i>0 && !sizeof(dummy)) {
+    ob=FindInStore(i);
+  }
+  else ob=FindInStore(str);
+
+  if (!ob) return 0;
+
+  if (str = buy_obj(ob,0)) 
+  {
+    write(break_string(str,78,Name(WER)+" sagt: "));
+    return 1;
+  }
+
+  val = QueryBuyValue(ob,PL);
+
+  if (PL->QueryMoney() < val)
+  {
+    write(break_string(capitalize(ob->QueryPronoun(WER))+" wuerde "+val+
+     " Muenzen kosten, und Du hast nur "+PL->QueryMoney()+".",78,
+     Name(WER)+" bedauert: "));
+    return 1;
+  }
+
+  // Anzahl der angeforderten Einheiten vor dem Bewegen zwischenspeichern.
+  // Weil dabei im Fall von Units eine Vereinigung mit bereits im Inventar
+  // befindlichen Einheiten stattfindet, muss das ggf. nach Bewegen
+  // zurueckgesetzt werden.
+  int u_req = ob->QueryProp(U_REQ);
+
+  if ((res = ob->QueryProp(P_RESTRICTIONS)) && mappingp(res) &&
+      (res = call_other("/std/restriction_checker",
+                        "check_restrictions",PL,res)) &&
+      stringp(res))
+  {
+    _notify_fail(break_string("Du koenntest "+ob->name(WEN,2)+" nicht "
+     "verwenden. Grund: "+res+"Moechtest Du "+ob->QueryPronoun(WEN)+
+     " dennoch kaufen?",78,Name(WER)+" sagt: "));
+
+    input_to("ask_buy",INPUT_PROMPT, "(ja/nein) ", val,PL,ob,u_req);
+    return 0;
+  }
+
+  par = (int)ob->QueryProp(P_PARRY);
+  dex = (int)PL->QueryAttribute(A_DEX);
+
+  if ((((par < PARRY_ONLY) && ((dex + 8) * 10) < ob->QueryProp(P_WC)) ||
+       ((par > PARRY_NOT)  && ((dex + 5) *  2) < ob->QueryProp(P_AC))) &&
+      VALID_WEAPON_TYPE(ob))
+  {
+    _notify_fail(break_string("Du koenntest "+ob->name(WEN,2)+" nicht "
+     "zuecken, da Deine Geschicklichkeit dafuer nicht ausreicht. Moechtest "
+     "Du "+ob->QueryPronoun(WEN)+" dennoch kaufen?",78,
+     Name(WER)+" sagt: "));
+
+    input_to("ask_buy",INPUT_PROMPT, "(ja/nein) ", val,PL,ob,u_req);
+    return 0;
+  }
+
+  really_buy(val, PL, ob, u_req);
+
+  return 1;
+}
+
+private void give_money(int value)
+// Geld gutschreiben...
+{
+  if (!value) return;
+  write(break_string(Name(WER, 1)+" zahlt Dir "+value+" Goldstueck"
+                    +(value==1?".":"e."), 78));
+  if ((PL->AddMoney(value))<=0) {
+     object mon;
+
+     write("Du kannst das Geld nicht mehr tragen!\n");
+     mon=clone_object(GELD);
+     mon->SetProp(P_AMOUNT,value);
+     mon->move(ME,M_MOVE_ALL|M_NOCHECK);
+  }
+}
+
+static int make_to_money(object ob, int value)
+// Interne Funktion, die ob versucht in das Lager zu ueberfuehren und das
+// Geld das dabei fuer den Spieler abfaellt zurueckliefert.
+{
+  string str;
+  int ret;
+
+  if (!objectp(ob) || environment(ob)==find_object(storage)) {
+    write(break_string(Name(WER, 1)+" wundert sich ueber Dich.", 78));
+    return 0;
+  }
+  if (value>QueryProp(P_CURRENT_MONEY)) {
+    write(break_string("Ich hab das Geld leider nicht mehr.", 78,
+                       Name(WER, 1)+" sagt: "));
+    return 0;
+  }
+  // U_REQ merken, falls sich Objekte vereinigen. Sonst stimmt nicht nur der
+  // Name, sondern es werden ggf. auch die falsche Anzahl zerstoert.
+  //TOOO: Oder Units entsorgen und als Feature deklarieren?
+  int req = ob->QueryProp(U_REQ);
+  if (CheckForDestruct(ob) > 0)  // soll ob zerstoert werden?
+  {
+    ret = ob->move(storage,M_PUT|M_GET);
+    // Falls das Objekt sich vereinigt hat (Units), muessen die gewuenschten
+    // Einheiten restauriert werden.
+    // Problem: falls das verkaufte Objekt Units hat, beschaedigt ist und sich
+    // vereinigt hat, sind jetzt leider alle Einheiten im Lager beschaedigt.
+    // Das ist unschoen - aber mir jetzt zuviel AUfwand, das korrekt zu bauen,
+    // weil es nur sehr selten vorkommt. (Hint: separater Muellraum)
+    ob->SetProp(U_REQ, req);
+    if (ret > 0) // Sonst werden auch Sachen zerstoert, die man nicht
+    {                 // weglegen kann
+      say(break_string(PL->Name()+" verkauft "+ob->name(WEN)+".", 78));
+      if(ob->QueryProp(P_DAMAGED))  // Andere Meldung bei beschaedigten
+      {                             // Objekten ...
+        write(break_string(Name(WER,1)+" findet zwar keinen Gefallen an "
+         +ob->name(WEM,1)+", nimmt "+ob->QueryPronoun(WEN)+" Dir zuliebe "
+         "aber trotzdem.",78));
+      }
+      else
+      {
+        write(break_string(Name(WER, 1)+" findet Gefallen an "
+           +ob->name(WEM, 1) + " und legt "+ob->QueryPronoun(WEN)
+           +" zu "+(QueryProp(P_GENDER)==FEMALE?"ihren":"seinen")
+           +" Privatsachen.", 78));
+      }
+      /* Er zahlt Dir "+value+" Muenze"+(value==1?"":"n")+" dafuer.", 78)); */
+      _add_money(-value);
+      _add_money(value*QueryProp(P_SHOP_PERCENT_LEFT)/100); // Wegen Zerstoerung des Objektes
+      UpdateCounter(ob,1);
+      ob->remove(1);
+      return value;
+    }
+    else if (ret == ME_CANT_BE_DROPPED) {
+      if ((str=ob->QueryProp(P_NODROP)) && stringp(str)) {
+        write(str);
+        return 0;
+      }
+      write(break_string("Du kannst "+ob->name(WEN,1)+" nicht verkaufen!", 78));
+      return 0;
+    }
+    else
+      write(break_string(ob->Name(WER)+" interessiert mich nicht.", 78,
+               Name(WER, 1)+" sagt: "));
+  }
+  else if ((ret=(ob->move(storage,M_PUT|M_GET)))>0)
+  {
+    // Falls das Objekt sich vereinigt hat (Units), muessen die gewuenschten
+    // Einheiten restauriert werden.
+    ob->SetProp(U_REQ, req);
+    say(break_string(PL->Name(WER)+" verkauft "+ob->name(WEN)+".", 78));
+    _add_money(-value);
+    UpdateCounter(ob,1);
+    return value;
+  }
+  else if (ret == ME_CANT_BE_DROPPED) {
+    if ((str=ob->QueryProp(P_NODROP)) && stringp(str))
+       write(str);
+    else write(break_string("Du kannst "+ob->name(WEN,1)+" nicht verkaufen!", 78));
+  }
+  else write(break_string("Du kannst "+ob->name(WEN,1)+" nicht verkaufen!", 78));
+  return 0;
+}
+
+static void ask_sell(string str, object ob, int val, int u_req)
+// Wenn ein einzelnen Stueck unter Wert verkauft werden soll, wird nachgefragt
+// u_req ist bei Unitobjekten die Anzahl an zu verkaufenden Einheiten. Bei
+// normalen Objekten ist u_req 0.
+{
+  str=lower_case(str||"");
+  if (str=="ja"||str=="j")
+  {
+     // In Unitobjekten U_REQ (wieder) setzen.
+     if (u_req>0)
+     {
+       // Das QueryProp() ist nicht unnoetig. Bei der Abfrage von U_REQ wird
+       // U_REQ genullt, wenn das aktuelle query_verb() != dem letzten ist.
+       // Bei der ersten Abfrage wuerde als das hier gesetzt U_REQ wieder
+       // geloescht. Daher muss das jetzt hier als erstes einmal abgefragt
+       // werden...
+         ob->QueryProp(U_REQ);
+         ob->SetProp(U_REQ, u_req);
+     }
+     give_money(make_to_money(ob,val));
+  }
+  else
+     write(break_string("Ok, dann behalts!", 78,
+             Name(WER, 1)+" sagt: "));
+}
+
+static string sell_obj(object ob, int short)
+// Ist der Haendler bereit ob zu kaufen? wenn nein, Rueckgabe einer Meldung,
+// die der Haendler sagen soll.
+{  mixed nosell;
+
+   if (BLUE_NAME(ob)==GELD)
+      return "Das waere ja wohl Unsinn, oder ...?";
+   if (nosell=ob->QueryProp(P_NOSELL))
+   {
+     if (stringp(nosell))
+       return nosell;
+     return ("Du kannst "+ob->name(WEN,1)+" nicht verkaufen!");
+   }
+   if (ob->QueryProp(P_CURSED))
+     return ob->Name(WER,1)
+         +" ist mir irgendwie ungeheuer! Das kannst Du nicht verkaufen!";
+   // man sollte keine COntainer mit Inhalt verkaufen koennen, ggf. kauft sie
+   // dann ein anderer Spieler.
+   if (first_inventory(ob))
+   {
+     return ob->Name(WER, 1) + " ist nicht leer!";
+   }
+   return 0;
+}
+
+static varargs int sell(string str, int f)
+{
+  int i, val, oval, tmp;
+  object *obs;
+
+  if (stringp(QueryProp(P_KEEPER)) && !present(QueryProp(P_KEEPER),ME)) {
+     write("Es ist niemand da, der Dich bedienen koennte.\n");
+     return 1;
+  }
+  
+  if (!str) {
+     notify_fail("Was moechtest Du denn verkaufen?\n");
+     return 0;
+  }
+  
+  /* Ergebnis von find_obs() sollte unifiziert werden, damit ein mehrfach
+     gefundenes Objekt nicht mehrfach versucht wird zu verkaufen.
+     Beispiel: Objekt hat P_NOBUY gesetzt und mehrere IDs gesetzt. Wenn
+     ein Spieler es mit "verkaufe ID1 und ID2" versucht zu verkaufen,
+     wuerde das einen Bug ausloesen. Derselbe Bug entsteht, wenn man mit
+     "verkaufe ID1 und ID1" verkauft. */
+  obs = PL->find_obs(str, PUT_GET_DROP);
+  /* Erst im Inventar schauen, dann im Environment. find_obs() ohne 2.
+     Parameter macht das standardmaessig andersherum.
+     TODO: Aenderung ueberpruefen, sobald das neue put_and_get.c 
+     eingebaut wurde. */
+  if ( !sizeof(obs) )
+    obs = PL->find_obs(str, PUT_GET_TAKE) || ({});
+  obs = m_indices(mkmapping(obs));
+  if (!i=sizeof(obs)) {
+     notify_fail("Was moechtest Du denn verkaufen?\n");
+     return 0;
+  }
+  call_other(storage, "_register_shop", ME);
+  if (i==1) {
+     if (str=sell_obj(obs[0], 0)) {
+        write(break_string(str, 78, Name(WER, 1)+" sagt: "));
+        return 1;
+     }
+     if ((oval=obs[0]->QueryProp(P_VALUE))<=0) {
+        write(break_string(obs[0]->Name(WER)
+              +(obs[0]->QueryProp(P_PLURAL) ? " haben" : " hat")
+              +" keinen materiellen Wert, tut mir leid.", 78,
+              Name(WER, 1)+" sagt: "));
+        return 1;
+     }
+     val=QuerySellValue(obs[0], PL);
+     if (!val) {
+        write(break_string("Ich bin absolut pleite. Tut mir aufrichtig leid.",
+              78, Name(WER, 1)+" sagt: "));
+        return 1;
+     }
+     if (val==oval || f) {
+        give_money(make_to_money(obs[0], val));
+        return 1;
+     }
+     if (str=obs[0]->QueryProp(P_NODROP)) {
+        if (stringp(str))
+           write(str);
+        else write(break_string("Du kannst "+obs[0]->name(WEN,1)
+                               +" nicht verkaufen!", 78));
+        return 1;
+     }
+
+     if (obs[0]->QueryProp(P_DAMAGED))  // Bei beschaedigten Objekten gibt
+     {                                  // es auch hier eine andere Meldung
+       write(break_string("Da "+obs[0]->name(WER)+" beschaedigt "
+        +(obs[0]->QueryProp(P_PLURAL)?"sind":"ist")+", kann ich Dir "
+        "nur "+val+" Muenze"+(val == 1?"":"n")+" dafuer bieten. Und "
+        "damit mache ich noch Verlust! Nimmst Du mein Angebot an? "
+        "(ja/nein)",78,Name(WER,1)+" sagt: "));
+     }
+     else                              // Default
+     {
+       write(break_string(Name(WER, 1)+" sagt: "
+          +"Nach der aktuellen Marktlage kann ich Dir dafuer nur "
+          +val+" Muenze"+(val==1?"":"n")+" bieten, obwohl "
+          +obs[0]->name(WER)+" eigentlich "+oval+" Muenze"
+          +(oval==1?"":"n")+" wert waere. Willst Du "
+          +(QueryProp(P_PLURAL) ? "sie" : "es")
+          +" mir dafuer ueberlassen?", 78));
+     }
+     // in ask_sell() gibt es das query_verb() nicht mehr, weswegen U_REQ in
+     // Unitobjekten zurueckgesetzt wird. Damit geht die info verloren,
+     // wieviele Objekte der Spieler angegeben hat. Diese muss gerettet und
+     // via ask_sell() in make_to_money() ankommen. In normalen Objekten ist
+     // U_REQ 0.
+     input_to("ask_sell",INPUT_PROMPT, "(ja/nein) ",obs[0], val,
+              (obs[0])->QueryProp(U_REQ) );
+     return 1;
+  }
+  for (--i; i>=0 && get_eval_cost()>50000; i--) {
+     if (oval=obs[i]->QueryProp(P_VALUE)) {
+        if (obs[i]->QueryProp(P_KEEP_ON_SELL)==getuid(PL)
+            || obs[i]->QueryProp(P_WORN) || obs[i]->QueryProp(P_WIELDED))
+           write(break_string(obs[i]->Name(WER)+": Du behaeltst "
+                +obs[i]->name(WEN)+".", 78));
+        else if (str=sell_obj(obs[i], 1))
+           write(break_string(obs[i]->Name(WER)+": "+str, 78));
+        else {
+           tmp=QuerySellValue(obs[i], PL);
+           if (!tmp) {
+              write(break_string(
+                    "Ich bin absolut pleite. Tut mir aufrichtig leid.", 78,
+                    Name(WER, 1)+" sagt: "));
+              break;
+           }
+           else if (!f && tmp*10<oval)
+              write(break_string(obs[i]->Name(WER)+": "+Name(WER, 1)
+                    +" bietet Dir aber nur "+tmp+" Goldstueck"
+                    +(tmp>1 ? "e" : "")+" dafuer.", 78));
+           else {
+              str=(obs[i]->Name(WER));
+              if (tmp=make_to_money(obs[i], tmp)) {
+                 write(break_string(str+": "+Name(WER, 1)
+                      +" gibt Dir dafuer "+tmp+" Goldstueck"
+                      +(tmp==1?".":"e."), 78));
+                 val+=tmp;
+              }
+           }
+        }
+     }
+  }
+  if (!val)
+     write(break_string("Hmmm, Du hast aber nicht besonders viel zu bieten...",
+                        78, Name(WER)+" sagt: "));
+  else give_money(val);
+  return 1;
+}
+
+static int force_sell(string str)
+{  return sell(str, 1);  }
+
+static int evaluate(string str)
+{
+  object ob;
+  int val,rval;
+
+  if (!str) return 0;
+  if(stringp(QueryProp(P_KEEPER)) && !present(QueryProp(P_KEEPER), ME)) {
+    write("Es ist niemand da, der Dich bedienen koennte.\n");
+    return 1;
+  }
+
+  ob=present(str, ME);
+  if (!ob) ob=deep_present(str,PL);
+  if (!ob) {
+    write("Hm? "+capitalize(str)+"? Wovon redest Du?\n");
+    return 1;
+  }
+  if (living(ob)) {
+    _notify_fail("Nanu, seit wann werden hier Lebewesen verkauft?\n");
+    return 0;
+  }
+  if (str=sell_obj(ob, 0)) {
+    write(break_string(str, 78, Name(WER)+" sagt: "));
+    return 1;
+  }
+  rval=ob->QueryProp(P_VALUE);
+  if (rval) {
+    val=QuerySellValue(ob, PL);
+    if (rval==val) {
+      tell_object(this_player(),break_string(
+         "Naja, ich denke, " +val+ " Muenze"
+         + (val==1 ? "" : "n")
+         + " waere"+(ob->QueryProp(P_AMOUNT)>1?"n ":" ")
+         + (ob->QueryPronoun(WER))+" schon wert.\n",78));
+    }
+    else if (val) {
+        tell_object(this_player(),break_string(
+          "Oh, nach der aktuellen Marktlage kann ich nur "+val+" Muenze"+
+          (val==1?"":"n")+" bezahlen, obwohl "
+          + (QueryProp(P_PLURAL) ? "sie" : "es")
+          + " eigentlich "+rval
+          + " Muenze"+(rval==1?"":"n")+" wert ist.\n",78));
+    }
+    else write("Ich bin vollkommen pleite. Tut mir leid.\n");
+  }
+  else write("Das ist voellig wertlos.\n");
+  return 1;
+}
+
+static int show_obj(string str)
+{
+  int i;
+  string was;
+  mixed ob;
+
+  if (!str) return 0;
+  if (sscanf(str,"%s im laden",was)>0 || sscanf(str,"%s in laden",was)>0) {
+    _notify_fail("Das kann ich im Lager nicht finden.\n");
+    ob=FindInStore(was);
+  } else if (sscanf(str,"%d",i)>0 && i>0) {
+    _notify_fail("Das kann ich im Lager nicht finden.\n");
+    ob=FindInStore(i);
+  }
+  if (!ob) return 0;
+  write(ob->Name(WER)+":\n"+ob->long()+capitalize(ob->QueryPronoun())
+       +" kostet "+QueryBuyValue(ob,PL)+" Muenzen.\n");
+  return 1;
+}
+
+// benutzt von trading_price::QueryValue(object, int, object)
+static int ObjectCount(object ob)
+{
+  string tmp;
+
+  if (!objectp(ob)) return 0;
+  tmp = BLUE_NAME(ob);
+  if (tmp[0..2]!="/d/" && tmp[0..8]!="/players/") tmp=ob->short()+tmp;
+  return ob_anz[tmp];
+}
+
+// benutzt von trading_price::QuerySellValue(object, object)
+static varargs int QueryValue(object ob, int value, object client)
+{
+  int new_value, mymoney;
+
+  if (!objectp(ob)) return 0;
+  if (Query("laden::compat")) {
+    new_value=(value>1000?1000:value);
+    mymoney = QueryProp(P_CURRENT_MONEY);
+    if (new_value>mymoney)
+      return (mymoney>0?mymoney:0);
+    else return new_value;
+  }
+  return ::QueryValue(ob, value, client);
+}
+
+void reset()
+{
+  mixed *keys;
+  int i;
+
+  trading_price::reset();
+
+  if (!mappingp(ob_anz))
+    return;
+  keys=m_indices(ob_anz);
+  for (i=sizeof(keys)-1;i>=0;i--) {
+    ob_anz[keys[i]]=ob_anz[keys[i]]*7/8;
+    if (!ob_anz[keys[i]])
+       m_delete(ob_anz,keys[i]);
+  }
+}
+
+varargs int CheckFindRestrictions(object ob, mixed restr, closure qp) {
+  return 0;
+}
+
+int EvalWeapon(object ob, closure qp) {
+  int wc,val;
+
+  wc=funcall(qp,P_WC);
+  val=funcall(qp,P_EFFECTIVE_WC);
+  if (val>wc) wc=val;
+  return wc;
+}
+
+varargs object FindBestWeapon(mixed type, int maxmon, int maxw, int hands,
+                              int bestwc, mixed restr) {
+  object bestob,ob;
+  string otype;
+  int wc,bestval,val,w,bestw;
+  closure qp;
+
+  if (!stringp(storage) || !objectp(ob=find_object(storage))) return 0;
+  if (!maxmon) maxmon=100000;
+  if (!maxw) maxw=75000;
+  if (!hands) hands=2;
+  if (val=QueryBuyFact()) maxmon=(maxmon*100)/val;
+  if (type && !pointerp(type) && !mappingp(type)) type=({type});
+
+  for (ob=first_inventory(ob);ob;ob=next_inventory(ob)) {
+    qp=symbol_function("QueryProp",ob);
+    if (!otype=funcall(qp,P_WEAPON_TYPE)) continue;
+    if (type && member(type,otype)<0) continue;
+    wc=EvalWeapon(ob,qp);
+    if (wc<bestwc) continue;
+    if (funcall(qp,P_NR_HANDS)>hands) continue;
+    w=funcall(qp,P_WEIGHT);
+    if (w>maxw) continue;
+    val=funcall(qp,P_VALUE);
+    if (val>maxmon) continue;
+    if (bestob && wc<=bestwc) {
+      if (val>bestval) continue;
+      else if (val==bestval && w>bestw) continue;
+    }
+    if (val>bestval && bestob && wc<=bestwc) continue;
+    if (CheckFindRestrictions(ob,restr,qp)) continue;
+    bestob=ob;
+    bestwc=wc;
+    bestval=val;
+    bestw=w;
+  }
+  return bestob;
+}
+
+int EvalArmour(object ob,closure qp) {
+  int ac,val;
+
+  ac=funcall(qp,P_AC);
+  val=funcall(qp,P_EFFECTIVE_AC);
+  if (val>ac) ac=val;
+  return ac;
+}
+
+varargs mapping FindBestArmoursT(mixed type, int maxmon, int maxw,
+                                 mapping bestac, mixed restr) {
+  object ob;
+  string otype;
+  int ac,val,sum,w,wsum;
+  mapping bestob,bestval,bestw;
+  closure qp;
+
+  if (!stringp(storage) || !objectp(ob=find_object(storage))) return ([]);
+  if (!maxmon) maxmon=100000;
+  if (!maxw) maxw=75000;
+  if (val=QueryBuyFact()) maxmon=(maxmon*100)/val;
+  if (type && !pointerp(type) && !mappingp(type)) type=({type});
+  if (!mappingp(bestac)) bestac=([]);
+  bestob=([]);bestval=([]);bestw=([]);
+
+  for (ob=first_inventory(ob);ob;ob=next_inventory(ob)) {
+    qp=symbol_function("QueryProp",ob);
+    if (!otype=funcall(qp,P_ARMOUR_TYPE)) continue;
+    if (type && member(type,otype)<0) continue;
+    ac=EvalArmour(ob,qp);
+    if (ac<bestac[otype]) continue;
+    w=funcall(qp,P_WEIGHT);
+    if (wsum-bestw[otype]+w>maxw) continue;
+    val=funcall(qp,P_VALUE);
+    if (sum-bestval[otype]+val>maxmon) continue;
+    if (bestob[otype] && ac<=bestac[otype]) {
+      if (val>bestval[otype]) continue;
+      else if (val==bestval[otype] && w>bestw[otype]) continue;
+    }
+    if (CheckFindRestrictions(ob,restr,qp)) continue;
+    sum=sum-bestval[otype]+val;
+    wsum=wsum-bestw[otype]+w;
+    bestob[otype]=ob;
+    bestac[otype]=ac;
+    bestval[otype]=val;
+    bestw[otype]=w;
+  }
+  return bestob;
+}
+
+varargs object *FindBestArmours(mixed type, int maxmon, int maxw,
+                                                mapping bestac, mixed restr) {
+  return m_values(FindBestArmoursT(type,maxmon,maxw,bestac,restr));
+}
