diff --git a/std/room/pub.c b/std/room/pub.c
new file mode 100644
index 0000000..c15e33e
--- /dev/null
+++ b/std/room/pub.c
@@ -0,0 +1,989 @@
+//
+// pub.c -- Alles, was eine Kneipe braucht.
+//
+// $Id: pub.c 8778 2014-04-30 23:04:06Z Zesstra $
+// spendiere ueberarbeitet, 22.05.2007 - Miril
+#pragma strong_types
+#pragma save_types
+#pragma pedantic
+#pragma range_check
+#pragma no_clone
+
+#define NEED_PROTOTYPES
+#include <thing/commands.h>
+#include <thing/properties.h>
+
+#include <defines.h>
+#include <rooms.h>
+#include <properties.h>
+#include <routingd.h>
+#include <bank.h>
+#include <exploration.h>
+#include <wizlevels.h>
+#include <pub.h>
+
+// Alle nicht-privaten werden in erbenen Objekten verwendet.
+private nosave int     max_list;
+private nosave int     refresh_count;
+private nosave int     sum;
+private nosave mapping refresh_list;
+nosave mapping id_list;
+nosave mapping menu_list;
+nosave object  *waiting;
+
+#define PM_RATE_PUBMASTER  "rate"
+#define PM_DELAY_PUBMASTER "delay"
+
+protected void create()
+{ object router;
+
+  SetProp( P_ROOM_TYPE, QueryProp(P_ROOM_TYPE) | RT_PUB );
+
+  SetProp( P_PUB_NOT_ON_MENU,
+    "Tut mir leid, das fuehren wir nicht! Wir sind ein anstaendiges "+
+    "Lokal!\n" );
+  SetProp( P_PUB_UNAVAILABLE,
+    "Davon ist leider nichts mehr da.\n" );
+  SetProp(P_PUB_NO_MONEY,
+    "Das kostet %d Goldstuecke, und Du hast nicht so viel!\n" );
+  SetProp(P_PUB_NO_KEEPER,
+    "Es ist niemand anwesend, der Dich bedienen koennte.\n");
+
+  AddCmd( "menue","menue" );
+  AddCmd( ({"kauf","kaufe","bestell","bestelle"}),"bestelle" );
+  AddCmd( ({"spendier","spendiere"}),"spendiere" );
+  AddCmd( "pubinit","pubinit" );
+
+  max_list=0;
+  refresh_count=0;
+  waiting = ({ });
+  id_list=([]);
+  menu_list=([]);
+  refresh_list=([]);
+
+  if ( !clonep(ME) && objectp(router=find_object(ROUTER)) )
+    router->RegisterTarget(TARGET_PUB,object_name(ME));
+
+  call_out("add_std_drinks",1);
+}
+
+protected void create_super() {
+  set_next_reset(-1);
+}
+
+/* Zur Syntax:
+ *
+ * menuetext - Der Text steht im Menue
+ *
+ * ids       - Array der Namen, mit denen bestellt werden kann
+ *
+ * minfo     - Mapping mit Eintraegen fuer:
+ *                 P_HP (HP-Heilung),
+ *                 P_SP (SP-Heilung),
+ *                 P_FOOD (Saettigung),
+ *                 P_DRINK (Fluessigkeit)
+ *                 P_ALCOHOL (Alkoholisierung)
+ *                 P_VALUE (Preis)
+ *             Die Eintraege werden ueber eval_anything ausgewertet
+ *             (siehe da)
+ *
+ * rate      - Heilrate (auch ueber eavl_anything) in Punkte / heart_beat()
+ *
+ * msg       - Meldung beim Essen.
+ *             a) closure (wird mit funcall(msg,zahler,empfaenger)
+ *                ausgewertet)
+ *             b) string (wie closure: call_other(this_object...))
+ *             c) array mit 2 strings: 1) fuer Essenden, 2) fuer andere
+ *                siehe auch mess()
+ *
+ * refresh   - Mapping mit den moeglichen Eintraegen:
+ *                 PR_USER : <Kontingent> ; <Update> (pro Spieler)
+ *                 PR_ALL  : <Kontingent> ; <Update> (fuer alle)
+ *             Es wird zunaechst geprueft, ob noch etwas fuer den
+ *             (zahlenden!) Spieler selbst vorhanden ist wenn nein wird
+ *             geschaut, ob das Kontingent fuer alle schon erschoepft ist.
+ *             Sind beide Kontingente erschoepft, kann der Spieler das
+ *             Bestellte nicht bekommen.
+ *             Die Kontingente wird alle <Update> reset()s "aufgefrischt".
+ *             <Kontingent> wird ueber eval_anything() ausgewertet.
+ *             Alternativ kann man einen Int-Wert angeben. Dieser wird wie
+ *             ([ PR_ALL : <wert> ; 1 ]) behandelt.
+ *
+ * delay     - Zahl der Sekunden, um die verzoegert die Heilung eintritt
+ *             z.B. weil das Essen erst zubereitet werden muss.
+ *             Ebenfalls ueber eval_anything()
+ *
+ * d_msg     - Meldung beim bestellen, falls Delay. Wie msg.
+ */
+varargs string AddToMenu(string menuetext, mixed ids, mapping minfo,
+                         mixed rate, mixed msg, mixed refresh,
+                         mixed delay, mixed d_msg)
+{ string ident;
+  int i;
+
+  if ( !stringp(menuetext) || !ids || !mappingp(minfo) )
+    return 0;
+
+  if ( stringp(ids) )
+    ids = ({ ids });
+  else if ( !pointerp(ids) )
+    return 0;
+
+  ident = sprintf("menuentry%d",max_list);
+  max_list++;
+
+  /* Fuer schnelles Nachschlagen ein eigenes Mapping fuer Ids */
+  for( i=sizeof(ids)-1;i>=0;i-- )
+    id_list += ([ ids[i] : ident ]);
+
+  if ( intp(refresh) && (refresh>0) )
+    refresh = ([ PR_ALL : refresh; 1 ]);
+  else if ( !mappingp(refresh) )
+    refresh = 0;
+
+  menu_list += ([ ident : menuetext; minfo; rate; msg; refresh;
+                   delay; d_msg; ids ]);
+  return ident;
+}
+
+// Diese Methode ist nur noch aus Kompatibilitaetsgruenden vorhanden und darf
+// nicht mehr verwendet werden!!!
+void AddFood(string nameOfFood, mixed ids, int price, int heal,
+             mixed myFunction)
+{
+  if ( !nameOfFood || !ids || !price)
+    return; /* Food not healing is ok ! */
+
+  AddToMenu( nameOfFood,ids,
+             ([ P_VALUE : price, P_FOOD : heal, P_HP : heal, P_SP : heal ]),
+             ((heal>5)?5:heal), myFunction, 0,0,0);
+}
+
+// Diese Methode ist nur noch aus Kompatibilitaetsgruenden vorhanden und darf
+// nicht mehr verwendet werden!!!
+void AddDrink(string nameOfDrink, mixed ids, int price, int heal,
+              int strength, int soak, mixed myFunction)
+{
+  if ( !nameOfDrink || !ids || !price )
+    return;
+
+  heal=heal/2;
+  /* Kleine Korrektur, damit man in alten Pubs ueberhaupt trinken kann */
+  AddToMenu(nameOfDrink,ids,
+             ([ P_VALUE : price, P_DRINK : soak, P_ALCOHOL : strength,
+                P_HP : heal, P_SP : heal ]),
+             ((heal>5)?5:heal), myFunction,0,0,0);
+}
+
+int RemoveFromMenu(mixed ids) {
+  int ret;
+
+  if (stringp(ids))
+    ids = ({ids});
+
+  if (pointerp(ids)) {
+    foreach (string id: ids) {
+      // look if the id has a matching ident
+      string ident = id_list[id];
+      if (stringp(ident)) {
+        // remove this ident-entry from the id-list ...
+        m_delete(id_list, id);
+        // ... and remove all others now too (so it won't bug later, if
+        //     the wizard calling this method forgot an id)
+        foreach (string listid: m_indices(id_list))
+          if (id_list[listid] == ident)
+            m_delete(id_list, listid);
+
+        // now remove the ident from the menu_list
+        if (member(menu_list, ident)) {
+          ret++;
+          m_delete(menu_list, ident);
+
+          // decrease the ident-counter, if this entry was the last one
+          int oldnum;
+          if (sscanf(ident, "menuentry%d", oldnum) == 1 &&
+              oldnum == (max_list-1))
+            max_list--;
+        }
+      }
+    }
+  }
+  // return removed entries
+  return ret;
+}
+
+/* Zum Auswerten der Eintraege fuer Preis, Rate, HP...
+ * a) integer-Wert    -> wird direkt uebernommen
+ * b) mapping         -> Wird als RaceModifiere verstanden. Es wird der
+ *                       Eintrag gewaehlt, der der Rasse des Spielers
+ *                       entspricht, falls vorhanden, ansonsten der Eintrag
+ *                       fuer 0.
+ * c) Array           -> In erstem Element (muss Objekt oder dessen Filename
+ *                       sein) wird die Funktion mit dem Namen im 2.Element
+ *                       aufgerufen.
+ * d) String          -> Die genannte Funktion wird in der Kneipe selbst
+ *                       aufgerufen.
+ * e) Closure         -> Die Closure wird ausgewertet.
+ * Alle Funktionsaufrufe bekommen den essenden Spieler (bei Price und Delay
+ * den bestellenden Spieler) als Argument uebergeben. Die Auswertung erfolgt
+ * in der angegebenen Reihenfolge. Am Ende muss ein Intergerwert herauskommen
+ */
+int eval_anything(mixed what, object pl)
+{ mixed re;
+
+  if (intp(what))
+    return what;
+
+  if (mappingp(what) && pl)
+  {
+    re = what[pl->QueryProp(P_RACE)]||what[0];
+  }
+
+  if (re)
+    what=re;
+
+  if ( pointerp(what) && (sizeof(what)>=2)
+      && ( objectp(what[0]) || stringp(what[0]) )
+      && stringp(what[1]) )
+    what = call_other(what[0],what[1],pl);
+
+  if ( stringp(what) && function_exists(what,ME) )
+    what = call_other(ME,what,pl);
+
+  if ( closurep(what) )
+    what = funcall(what,pl);
+
+  if ( intp(what) )
+    return what;
+
+  return 0;
+}
+
+/* Diese Funktion ueberprueft, ob das Kontingent eines Menueeintrags
+ * fuer einen Spieler erschoepft ist.
+ */
+string CheckAvailability(string ident, object zahler)
+{ string uid;
+
+  if ( !stringp(ident) || !member(menu_list,ident) || !objectp(zahler) )
+    return 0;
+  if ( !mappingp(menu_list[ident,PM_REFRESH]) )
+    return PR_NONE;
+
+  if ( !member(refresh_list,ident) )
+    refresh_list += ([ ident : ([ ]) ]);
+
+  if ( query_once_interactive(zahler) )
+    uid=getuid(zahler);
+  else
+    uid=object_name(zahler);
+
+  if ( member(menu_list[ident,PM_REFRESH],PR_USER) )
+  {
+    if ( !member(refresh_list[ident],uid) )
+    {
+      refresh_list[ident] += ([ uid : 0 ; refresh_count ]);
+    }
+
+    /* Kontingent des Zahlenden pruefen */
+    if ( refresh_list[ident][uid,PRV_AMOUNT] <
+          eval_anything(menu_list[ident,PM_REFRESH][PR_USER,PRV_AMOUNT],
+                        zahler) )
+      return uid;
+  }
+
+  if ( member(menu_list[ident,PM_REFRESH],PR_ALL) )
+  {
+    if ( !member(refresh_list[ident],PR_DEFAULT) )
+    {
+      refresh_list[ident] += ([ PR_DEFAULT : 0 ; refresh_count ]);
+    }
+
+    /* Kontingent der Allgemeinheit pruefen */
+    if ( refresh_list[ident][PR_DEFAULT,PRV_AMOUNT] <
+          eval_anything(menu_list[ident,PM_REFRESH][PR_ALL,PRV_AMOUNT],
+                        zahler) )
+      return PR_DEFAULT;
+  }
+
+  return 0;
+}
+
+/* Diese Funktion reduziert das Kontingent des Lebewesens uid beim
+ * Menueeintrag ident um 1
+ */
+void DecreaseAvailability(string ident, string uid)
+{
+  if ( !stringp(ident) || !stringp(uid) )
+    return;
+  refresh_list[ident][uid,PRV_AMOUNT]++;
+}
+
+/* Diese Funktion sorgt dafuer, dass die Kontingente an limitierten
+ * Sachen in regelmaessigen Abstaenden wiederhergestellt werden.
+ */
+static void UpdateAvailability()
+{ int    i1,i2;
+  string *ind1,*ind2,chk;
+
+  /* Keine Refresh-Eintraege, kein Update */
+  if ( !mappingp(refresh_list)
+      || (i1=sizeof(ind1=m_indices(refresh_list)))<1 )
+    return;
+
+  /* Es muss jeder Menueeintrag, der in der refresh_list steht,
+   * durchgegangen werden.
+   */
+  for ( --i1 ; i1>=0 ; i1-- )
+  {
+    if ( !mappingp(refresh_list[ind1[i1]])
+        || (i2=sizeof(ind2=m_indices(refresh_list[ind1[i1]])))<1 )
+      continue;
+
+    /* Fuer jeden Menueeintrag muss jeder Spielereintrag durchgegangen
+     * werden, der in dem entspr. mapping steht.
+     */
+    for ( --i2 ; i2>=0 ; i2-- ) // Alle Spieler
+    {
+      if ( ind2[i2]==PR_DEFAULT )
+        chk = PR_ALL;
+      else
+        chk = PR_USER;
+
+      if ( ( refresh_list[ind1[i1]][ind2[i2],PRV_REFRESH]
+            + menu_list[ind1[i1],PM_REFRESH][chk,PRV_REFRESH] )
+          <= refresh_count )
+      {
+        refresh_list[ind1[i1]][ind2[i2],PRV_AMOUNT]=0;
+        refresh_list[ind1[i1]][ind2[i2],PRV_REFRESH]=refresh_count;
+      }
+    }
+  }
+}
+
+mixed DBG(mixed o) {
+  if(find_player("rumata"))
+    tell_object(
+        find_player("rumata"),
+        sprintf("DBG: %O\n", o)
+    );
+  return 0;
+}
+
+/* Erweitert um die Moeglichkeit, Speise- oder Getraenke-Karte zu sehen. */
+string menue_text(string str)
+{ int i,sdr,sfo;
+  string ident,res;
+  string *fo=({}),*dr=({});
+
+  if ( !max_list )
+    return "Hier scheint es derzeit nichts zu geben.\n";
+
+  if ( !stringp(str) || str=="" )
+    str="alles";
+
+  /* Fuers Menue entscheiden ob Drink oder Food */
+  foreach(string id, string menuetext, mapping minfo: menu_list)
+  {
+    if (eval_anything(minfo[P_FOOD],this_player()))
+      fo+=({ id });
+    else
+      dr+=({ id });
+  }
+
+  sdr = sizeof(dr);
+  sfo = sizeof(fo);
+
+  if ( member(({"alle","alles"}),str)!=-1)
+  {
+    if ( !sfo )
+      str="drinks";
+    else if ( !sdr )
+      str="speise";
+    else
+    {
+      /* Gemischte Karte */
+      res = "Getraenke                    Preis alc | "+
+            "Speisen                          Preis\n"+
+            "---------------------------------------+-"+
+            "--------------------------------------\n";
+
+      for ( i=0 ; ( i<sdr || i<sfo ) ; i++ )
+      {
+        if ( i<sdr )
+          res += sprintf("%-29.29s%5.5d  %c  | ",
+                   menu_list[dr[i],PM_TEXT],
+                   eval_anything(menu_list[dr[i],PM_INFO][P_VALUE],PL),
+                   (eval_anything(menu_list[dr[i],PM_INFO][P_ALCOHOL],PL)>0) ? 'J' : 'N');
+        else
+          res += "                                       | ";
+
+        if ( i<sfo )
+          res += sprintf("%-33.33s%5.5d",
+                   menu_list[fo[i],PM_TEXT],
+                   eval_anything(menu_list[fo[i],PM_INFO][P_VALUE],PL));
+
+        res += "\n";
+      }
+
+      return res;
+    }
+  }
+
+  /* Reine Getraenkekarte */
+  if ( member(({"getraenke","drinks","getraenk","trinken"}),str)!=-1 )
+  {
+    if ( !sdr )
+      return "Hier gibt es leider nichts zu trinken.\n";
+
+    res = "Getraenke                    Preis alc | "+
+          "Getraenke                    Preis alc\n"+
+          "---------------------------------------+-"+
+          "--------------------------------------\n";
+
+    for ( i=0 ; i<sdr ; i++ )
+    {
+      ident = dr[i];
+
+      if ( !eval_anything(menu_list[ident,PM_INFO][P_FOOD], PL) )
+        res += sprintf("%-29.29s%5.5d  %c%s",
+                 menu_list[ident,PM_TEXT],
+                 eval_anything(menu_list[ident,PM_INFO][P_VALUE],PL),
+                 (eval_anything(menu_list[ident,PM_INFO][P_ALCOHOL],PL)>0) ? 'J' : 'N',
+                 ((i%2)?"\n":"  | "));
+    }
+
+    if ( res[<1..<1]!="\n" )
+      res += "\n";
+
+    return res;
+  }
+
+  /* Reine Speisekarte */
+  if ( member(({"speise","speisen","essen"}),str)!=-1 )
+  {
+    if ( !sfo )
+      return "Hier gibt es leider nichts zu essen.\n";
+
+    res = "Speisen                          Preis | "+
+          "Speisen                          Preis\n"+
+          "---------------------------------------+-"+
+          "--------------------------------------\n";
+
+    for ( i=0 ; i<sfo ; i++ )
+    {
+      ident = fo[i];
+      if (eval_anything(menu_list[ident,PM_INFO][P_FOOD],PL) )
+        res += sprintf("%-33.33s%5.5d%s",
+                 menu_list[ident,PM_TEXT],
+                 eval_anything(menu_list[ident,PM_INFO][P_VALUE],PL),
+                 ((i%2)?"\n":" | "));
+    }
+
+    if ( res[<1..<1]!="\n" )
+      res += "\n";
+
+    return res;
+  }
+
+  return 0;
+}
+
+int menue(string str)
+{ string txt;
+
+  _notify_fail("Welchen Teil des Menues moechtest Du sehen?\n");
+  if ( !stringp(txt=menue_text(str)) || sizeof(txt)<1 )
+    return 0;
+  write(txt);
+  return 1;
+}
+
+/* Diese Funktion kann/soll bei Bedarf ueberladen werden, um simultane
+ * Aenderungen des Mappings zu ermoeglichen (zu Beispiel wie es in guten
+ * Tagen groesser Portionen gib, Hobbits per se mehr kriegen, ...
+ */
+mapping adjust_info(string ident, mapping minfo, object zahler,
+                    object empfaenger)
+{
+  return 0;
+}
+
+/* Hier hats jede Menge neue Platzhalter */
+string mess(string str,object pl)
+{
+  string dummy1, dummy2;
+
+  if ( !pl )
+    pl=PL;
+
+  if ( !stringp(str) || str=="" )
+    return str;
+
+  str=implode(explode(str,"&&"),pl->name(WER,2));
+  str=implode(explode(str,"&1&"),pl->name(WER,2));
+  str=implode(explode(str,"&2&"),pl->name(WESSEN,2));
+  str=implode(explode(str,"&3&"),pl->name(WEM,2));
+  str=implode(explode(str,"&4&"),pl->name(WEN,2));
+  str=implode(explode(str,"&1#"),capitalize(pl->name(WER,2)));
+  str=implode(explode(str,"&2#"),capitalize(pl->name(WESSEN,2)));
+  str=implode(explode(str,"&3#"),capitalize(pl->name(WEM,2)));
+  str=implode(explode(str,"&4#"),capitalize(pl->name(WEN,2)));
+  str=implode(explode(str,"&!"),pl->QueryPronoun(WER));
+  str=implode(explode(str,"&5&"),pl->QueryPronoun(WER));
+  str=implode(explode(str,"&6&"),pl->QueryPronoun(WESSEN));
+  str=implode(explode(str,"&7&"),pl->QueryPronoun(WEM));
+  str=implode(explode(str,"&8&"),pl->QueryPronoun(WEN));
+  str=implode(explode(str,"&5#"),capitalize(pl->QueryPronoun(WER)));
+  str=implode(explode(str,"&6#"),capitalize(pl->QueryPronoun(WESSEN)));
+  str=implode(explode(str,"&7#"),capitalize(pl->QueryPronoun(WEM)));
+  str=implode(explode(str,"&8#"),capitalize(pl->QueryPronoun(WEN)));
+
+  return break_string(capitalize(str),78,"", BS_LEAVE_MY_LFS);
+}
+
+protected void _copy_menulist_values(mapping entryinfo, string ident) {
+  /* Kopieren aller Werte ins minfo-Mapping, um Problemen bei Loeschung
+     aus dem Weg zu gehen. Slow and dirty */
+  entryinfo[PM_TEXT]      = deep_copy(menu_list[ident, PM_TEXT]);
+  // PM_INFO is already flat in entryinfo
+  entryinfo[PM_RATE_PUBMASTER]
+                          = deep_copy(menu_list[ident, PM_RATE]);
+  entryinfo[PM_SERVE_MSG] = deep_copy(menu_list[ident, PM_SERVE_MSG]);
+  entryinfo[PM_REFRESH]   = deep_copy(menu_list[ident, PM_REFRESH]);
+  // PM_DELAY is already evaluated in entryinfo
+  entryinfo[PM_DELAY_MSG] = deep_copy(menu_list[ident, PM_DELAY_MSG]);
+  entryinfo[PM_IDS]       = deep_copy(menu_list[ident, PM_IDS]);
+}
+
+int do_deliver(string ident, object zahler, object empfaenger,
+               mapping entryinfo) {
+  waiting -= ({ empfaenger,0 });
+
+  /* Empfaenger muss natuerlich noch da sein */
+  if ( !objectp(empfaenger) || !present(empfaenger) )
+    return 0;
+
+  /* Zahler wird nur wegen der Abwaertskompatibilitaet gebraucht */
+  if ( !objectp(zahler) )
+    zahler = empfaenger;
+
+  // alte Pubs, die do_deliver irgendwie selbst aufrufen, sollten
+  // mit der Zeit korrigiert werden
+  if(!mappingp(entryinfo))
+    raise_error("Pub ruft do_deliver() ohne sinnvolle Argumente auf.\n");
+  if(!member(entryinfo, PM_RATE_PUBMASTER)) {
+    if(!member(menu_list, ident))
+      raise_error("Pub ruft do_deliver() mit geloeschtem Getraenk und "
+                  "teilweisen Argumenten auf!\n");
+
+    _copy_menulist_values(entryinfo, ident);
+    call_out(#'raise_error, 1,
+             "Pub ruft do_deliver() nur mit teilweisen Argumenten auf.\n");
+  }
+
+  entryinfo[PM_RATE_PUBMASTER] = eval_anything(entryinfo[PM_RATE_PUBMASTER],
+                                               empfaenger);
+  entryinfo[P_HP]              = eval_anything(entryinfo[P_HP], empfaenger);
+  entryinfo[P_SP]              = eval_anything(entryinfo[P_SP], empfaenger);
+
+  /* Ueberpruefen, ob Heilmoeglichkeit legal */
+  if ( query_once_interactive(empfaenger)
+      && ((PUBMASTER->RegisterItem(entryinfo[PM_TEXT], entryinfo))<1) ) {
+     tell_object(empfaenger,
+       "Mit diesem Getraenk/Gericht scheint etwas nicht in Ordnung "+
+       "zu sein.\nVerstaendige bitte den Magier, der fuer diesen "+
+       "Raum verantwortlich ist.\n");
+     return -4;
+  }
+
+  if ( QueryProp(P_NPC_FASTHEAL) && !query_once_interactive(empfaenger) ) {
+    entryinfo[H_DISTRIBUTION] = HD_INSTANT;
+  }
+  else {
+    entryinfo[H_DISTRIBUTION] = entryinfo[PM_RATE_PUBMASTER];
+  }
+  empfaenger->consume(entryinfo);
+
+  /* Meldung ausgeben */
+  /* Hinweis: Da die ausfuehrenden Funktionen auch ident und minfo
+   * uebergeben bekommen, kann man hier auch ueber adjust_info oder
+   * an anderer Stelle zusaetzliche Informationen uebergeben...
+   */
+  if (closurep(entryinfo[PM_SERVE_MSG]) )
+    funcall(entryinfo[PM_SERVE_MSG], zahler, empfaenger, ident, entryinfo);
+  else if (stringp(entryinfo[PM_SERVE_MSG]) &&
+           function_exists(entryinfo[PM_SERVE_MSG],ME))
+    call_other(ME, entryinfo[PM_SERVE_MSG], zahler, empfaenger, ident,
+                   entryinfo);
+  else if (pointerp(entryinfo[PM_SERVE_MSG]) &&
+           sizeof(entryinfo[PM_SERVE_MSG])>=2)  {
+    if (stringp(entryinfo[PM_SERVE_MSG][0]) &&
+        sizeof(entryinfo[PM_SERVE_MSG][0]))
+      tell_object(empfaenger,
+        mess(entryinfo[PM_SERVE_MSG][0]+"\n", empfaenger));
+    if (stringp(entryinfo[PM_SERVE_MSG][1]) &&
+        sizeof(entryinfo[PM_SERVE_MSG][1]))
+      tell_room(environment(empfaenger)||ME,
+        mess(entryinfo[PM_SERVE_MSG][1]+"\n",empfaenger),
+        ({empfaenger}) );
+  }
+
+  return 1;
+}
+
+/* Testet, ob genug Geld zur Verfuegung steht.
+ * Falls die Bonitaet anderen Beschraenkungen unterliegt, als
+ * dass der Zahler genug Geld dabei hat, muss diese Methode
+ * ueberschrieben werden.
+ * Rueckgabewerte:
+ * -2 : Out of Money
+ *  0 : Alles OK.
+ * Rueckgabewerte != 0 fuehren zu einem Abbruch der Bestellung
+ */
+int CheckSolvency(string ident, object zahler, object empfaenger,
+                   mapping entryinfo)
+{
+  if ( (zahler->QueryMoney())<entryinfo[P_VALUE] )
+  {
+    string res;
+    if ( !stringp(res=QueryProp(P_PUB_NO_MONEY)) )
+      res = "Das kostet %d Goldstuecke, und Du hast nicht so viel!\n";
+    tell_object(zahler,sprintf(res, entryinfo[P_VALUE]));
+    return -2;
+  }
+  return 0;
+}
+
+/* Fuehrt die Bezahlung durch.
+ * Falls die Bezahlung anders erfolgt, als durch Abzug des Geldes vom Zahler,
+ * muss diese Methode ueberschrieben werden
+ * Rueckgabewerte:
+ * Anzahl der Muenzen, die im Pub landen und bei Reset in die Zentralbank
+ * eingezahlt werden
+ */
+int DoPay(string ident, object zahler, object empfaenger, mapping entryinfo)
+{
+  zahler->AddMoney(-entryinfo[P_VALUE]);
+  return entryinfo[P_VALUE];
+}
+
+/* Rueckgabewerte:
+ * -6 : Nicht vorraetig
+ * -5 : Wirt nicht anwesend
+ * -4 : Illegales Getraenk/Gericht. Ausgabe verweigert.
+ *      Nur bei sofortiger Lieferung...
+ * -3 : Empfaenger bereits voll
+ * -2 : Out of Money
+ * -1 : spendieren ignoriert
+ *  0 : Empfaenger ausgeflogen (sollte eigentlich nicht passieren)
+ *  1 : Alles OK.
+ */
+int consume_something(string ident, object zahler, object empfaenger) {
+  if ( !objectp(zahler) )
+    zahler=PL;
+
+  if ( !objectp(empfaenger) )
+    empfaenger=PL;
+
+  /* Die Abfrage auf anwesenden Wirt erfolgt NUR an dieser Stelle, damit */
+  /* kein Spieler darunter leiden muss, wenn jemand anderes zwischen     */
+  /* Bestellung und Lieferung den Wirt meuchelt.                         */
+  if ( stringp(QueryProp(P_KEEPER)) && !present(QueryProp(P_KEEPER), ME))
+  {
+    string res = QueryProp(P_PUB_NO_KEEPER);
+    if ( !stringp(res) ) {
+      res = "Es ist niemand anwesend, der Dich bedienen koennte.\n";
+    }
+    tell_object(zahler,res);
+    return -5;
+  }
+
+  /* Spendiert und ignoriert? */
+  if ( zahler!=empfaenger )
+  {
+    mixed res = ({"spendiere"});
+    if ( eval_anything(menu_list[ident,PM_INFO][P_DRINK],empfaenger) )
+      res += ({"spendiere.getraenke"});
+    if ( eval_anything(menu_list[ident,PM_INFO][P_FOOD],empfaenger) )
+      res += ({"spendiere.essen"});
+    if ( eval_anything(menu_list[ident,PM_INFO][P_ALCOHOL],empfaenger) )
+      res += ({"spendiere.alkohol"});
+    if ( empfaenger->TestIgnoreSimple(res) )
+    {
+      tell_object(zahler,
+        empfaenger->Name(WER)+" will das nicht.\n");
+      return -1;
+    }
+  }
+
+  /* Hier kann das Info-Mapping erst mal als ganzes angepasst werden. */
+  mapping xinfo;
+  mapping entryinfo = deep_copy(menu_list[ident, PM_INFO]);
+  if ( (xinfo=adjust_info(ident,entryinfo,zahler,empfaenger)) &&
+       mappingp(xinfo) )
+    entryinfo += xinfo;
+
+  /* Genug Geld vorhanden? */
+  entryinfo[P_VALUE] = eval_anything(entryinfo[P_VALUE], zahler);
+  {
+    int res = CheckSolvency(ident, zahler, empfaenger, entryinfo);
+    if (res != 0) return res;
+  }
+
+  string avb;
+  if ( !stringp(avb=CheckAvailability(ident, zahler)) )
+  {
+    string res = QueryProp(P_PUB_UNAVAILABLE);
+    if ( !stringp(res) )
+      res = "Davon ist leider nichts mehr da.\n";
+    tell_object(zahler,res);
+    return -6;
+  }
+
+  /* Textausgabe beim spendieren */
+  if ( empfaenger!=zahler)
+  {
+    tell_room(environment(empfaenger)||ME,
+      zahler->Name(WER)+" spendiert "+empfaenger->name(WEM)+" etwas.\n",
+      ({zahler, empfaenger}) );
+    tell_object(empfaenger,
+      zahler->Name(WER)+" spendiert Dir etwas.\n");
+    tell_object(zahler,
+      "Du spendierst "+empfaenger->name(WEM)+" etwas.\n");
+  }
+
+  /* Testen, ob mans noch essen / trinken kann */
+  /* Die int-Werte werden in minfo uebernommen fuer die Auswertung */
+  /* im Pubmaster. */
+  entryinfo[P_FOOD]    = eval_anything(entryinfo[P_FOOD],   empfaenger);
+  entryinfo[P_ALCOHOL] = eval_anything(entryinfo[P_ALCOHOL],empfaenger);
+  entryinfo[P_DRINK]   = eval_anything(entryinfo[P_DRINK],  empfaenger);
+
+  int result = empfaenger->consume(entryinfo, 1);
+  if (result < 0) {
+    if (result & HC_MAX_FOOD_REACHED)
+      tell_object(empfaenger,
+                  "Du bist zu satt, das schaffst Du nicht mehr.\n");
+    else if (result & HC_MAX_DRINK_REACHED)
+      tell_object(empfaenger,
+                  "So viel kannst Du im Moment nicht trinken.\n");
+    else if (result & HC_MAX_ALCOHOL_REACHED)
+      tell_object(empfaenger,
+                  "Soviel Alkohol vertraegst Du nicht mehr.\n");
+    return -3;
+  }
+
+  /* Gezahlt wird auch sofort */
+  sum += DoPay(ident, zahler, empfaenger, entryinfo);
+
+  /* FPs gibts auch sofort */
+  if (zahler == empfaenger)
+    GiveEP(EP_PUB,menu_list[ident,PM_IDS][0]);
+
+  /* Falls die Anzahl des Bestellten beschraenkt ist, muss diese natuerlich
+   * angepasst werden.
+   */
+  if ( avb!=PR_NONE )
+    DecreaseAvailability(ident,avb);
+
+  /* Gibt es eine Zeitverzoegerung zwischen Bestellen und Servieren? */
+  entryinfo[PM_DELAY_PUBMASTER] = eval_anything(menu_list[ident, PM_DELAY], zahler);
+
+  // alle fuer einen Drink notwendigen Werte kopieren
+  _copy_menulist_values(entryinfo, ident);
+
+  if (entryinfo[PM_DELAY_PUBMASTER]<=0)
+    return do_deliver(ident,zahler,empfaenger,entryinfo);
+
+  /* Bestell-Meldung ausgeben */
+  if (closurep(entryinfo[PM_DELAY_MSG]))
+    funcall(entryinfo[PM_DELAY_MSG], zahler, empfaenger,ident, entryinfo);
+  else if (stringp(entryinfo[PM_DELAY_MSG]) &&
+           function_exists(entryinfo[PM_DELAY_MSG],ME))
+    call_other(ME, entryinfo[PM_DELAY_MSG], zahler, empfaenger, ident,
+               entryinfo);
+  else if (pointerp(entryinfo[PM_DELAY_MSG]) &&
+           sizeof(entryinfo[PM_DELAY_MSG])>=2) {
+    if (stringp(entryinfo[PM_DELAY_MSG][0]) &&
+       sizeof(entryinfo[PM_DELAY_MSG][0]))
+      tell_object(empfaenger,
+        mess(entryinfo[PM_DELAY_MSG][0]+"\n",empfaenger));
+    if (stringp(entryinfo[PM_DELAY_MSG][1]) &&
+        sizeof(entryinfo[PM_DELAY_MSG][1]))
+      tell_room(environment(empfaenger)||ME,
+        mess(entryinfo[PM_DELAY_MSG][1]+"\n",empfaenger),
+        ({empfaenger}) );
+  }
+
+  waiting += ({ empfaenger });
+  call_out("do_deliver", entryinfo[PM_DELAY_PUBMASTER],
+           ident, zahler, empfaenger, entryinfo);
+
+  return 1;
+}
+
+/* Rueckgabewere: 0: Nicht im Menue gefunde, 1 sonst */
+int search_what(string str,object zahler,object empfaenger)
+{ string ident;
+
+  if ( member(waiting,empfaenger)!=-1 )
+  {
+    if ( PL==empfaenger )
+      write("Du wartest doch noch auf etwas!\n");
+    else
+      write(empfaenger->Name(WER,2)+" wartet noch auf etwas.\n");
+    return 1;
+  }
+
+  str = lower_case(str);
+  if ( ident=id_list[str] )
+  {
+    consume_something(ident,zahler,empfaenger);
+    return 1;
+  }
+
+  return 0;
+}
+
+// Neue Version von Mesi:
+int spendiere(string str)
+{
+   _notify_fail("spendiere <spieler> <drink>\n");
+
+   if ( !stringp(str) || str=="" )
+     return 0;
+
+   string who,what;
+   int whoidx;
+
+   if (sscanf(str,"%s %d %s",who,whoidx,what)!=3
+    && sscanf(str,"%s %s",who,what)!=2)
+      return 0;
+  object target=present(who, whoidx);
+  if(!target && this_player()) target=present(who, whoidx, this_player());
+   if ( !target || !living(target) )
+   {
+     write("Das Lebewesen ist nicht hier...\n");
+     return 1;
+   }
+
+   notify_fail((string)QueryProp(P_PUB_NOT_ON_MENU)||"So etwas gibt es hier nicht!\n");
+
+   return search_what(what,PL,target);
+}
+
+int bestelle(string str)
+{
+  notify_fail((string)QueryProp(P_PUB_NOT_ON_MENU));
+
+  if ( !stringp(str) )
+    return 0;
+
+  return search_what(str,PL,PL);
+}
+
+int pubinit()
+{ string  *liste,ident,fn;
+  int     si,erg,max;
+  mapping minfo,xinfo;
+
+  if ( !PL || !IS_WIZARD(PL) )
+    return 0;
+
+  si=sizeof(liste=sort_array(m_indices(menu_list),#'<));
+  if ( si<1 )
+    return notify_fail("Keine Gerichte/Getraenke vorhanden.\n"),0;
+
+  fn=old_explode(object_name(ME),"#")[0];
+  printf("\n%'_'|30s %3s %3s %3s %5s %2s %2s %3s %3s %4s %3s\n",
+    "ITEM","ALC","DRI","FOO","VALUE","RT","DL","_HP","_SP","TEST","MAX");
+  for ( --si ; si>=0 ; si-- )
+  {
+    ident=liste[si];
+    minfo=deep_copy(menu_list[ident,PM_INFO]);
+
+    if ( (xinfo=adjust_info(ident,minfo,PL,PL)) && mappingp(xinfo) )
+      minfo+=xinfo;
+
+    minfo[P_VALUE]   = eval_anything(minfo[P_VALUE],            PL);
+    minfo[P_FOOD]    = eval_anything(minfo[P_FOOD],             PL);
+    minfo[P_ALCOHOL] = eval_anything(minfo[P_ALCOHOL],          PL);
+    minfo[P_DRINK]   = eval_anything(minfo[P_DRINK],            PL);
+    minfo[PM_DELAY_PUBMASTER]
+                     = eval_anything(menu_list[ident,PM_DELAY], PL);
+    minfo[PM_RATE_PUBMASTER]
+                     = eval_anything(menu_list[ident,PM_RATE],  PL);
+    minfo[P_HP]      = eval_anything(minfo[P_HP],               PL);
+    minfo[P_SP]      = eval_anything(minfo[P_SP],               PL);
+    erg=PUBMASTER->RegisterItem(menu_list[ident,0],minfo);
+    max=PUBMASTER->CalcMax(minfo,fn);
+
+    printf("%-'..'30.30s %3d %3d %3d %5d %2d %2d %3d %3d %|4s %3d\n",
+      menu_list[ident,PM_TEXT],
+      minfo[P_ALCOHOL], minfo[P_DRINK], minfo[P_FOOD],
+      minfo[P_VALUE],
+      minfo[PM_RATE_PUBMASTER],
+      minfo[PM_DELAY_PUBMASTER],
+      minfo[P_HP], minfo[P_SP],
+      ( erg ? "OK" : "FAIL" ),max);
+  }
+  write("Done.\n");
+  return 1;
+}
+
+void reset()
+{
+  if ( sum>0 )
+    ZENTRALBANK->PayIn(sum);
+  sum=0;
+  refresh_count++;
+  UpdateAvailability();
+}
+
+void add_gluehwein()
+{
+  if ( ctime(time())[4..6]=="Dec" )
+    AddToMenu( "Gluehwein",({"gluehwein"}),([
+      P_VALUE   : 80,
+      P_DRINK   :  5,
+      P_ALCOHOL : 20,
+      P_HP      : 15,
+      P_SP      : 15 ]),2,({
+      ("Du trinkst ein Glas Gluehwein, an dem Du Dir beinahe die Zunge "+
+       "verbrennst.\n"),
+      ("&& bestellt ein Glas Gluehwein und verbrennt sich beim\n"+
+       "Trinken beinahe die Zunge.\n") }), 0, 0, 0);
+}
+
+void add_std_drinks()
+{
+  if ( QueryProp(P_NO_STD_DRINK) )
+    return ;
+  add_gluehwein();
+}
+
+mapping query_menulist()
+{
+  return deep_copy(menu_list);
+}
+
+string *query_drinks()
+{
+  string *dr=({});
+  foreach( string ident, string menuetext, mapping minfo: menu_list) {
+    if (eval_anything(minfo[P_DRINK], 0))
+      dr += ({ ident });
+  }
+  return dr;
+}
+
+string *query_food()
+{
+  string *fo=({});
+  foreach( string ident, string menuetext, mapping minfo: menu_list) {
+    if (eval_anything(minfo[P_FOOD], 0))
+      fo += ({ ident });
+  }
+  return fo;
+}
