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

// Die alten durch die neuen Platzhalter ersetzen
private string replace_dummy(string str)
{
  switch(str)
  {
    case "&&": return "@WERU1";
    case "&1&": return "@WERU1";
    case "&2&": return "@WESSENU1";
    case "&3&": return "@WEMU1";
    case "&4& ": return "@WENU1";
    case "&1#": return "@WERU1";
    case "&2#": return "@WESSENU1";
    case "&3#": return "@WEMU1";
    case "&4# ": return "@WENU1";
    case "&!": return "@WERQP1";
    case "&5&": return "@WERQP1";
    case "&6&": return "@WESSENQP1";
    case "&7&": return "@WEMQP1";
    case "&8&": return "@WENQP1";
    case "&5#": return "@WERQP1";
    case "&6#": return "@WESSENQP1";
    case "&7#": return "@WEMQP1";
    case "&8#": return "@WENQP1";
    default: return str;
  }
  return str;
}

/* 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(pointerp(msg) && sizeof(msg)>=2)
  {
    msg[0]=regreplace(msg[0],"[&][1-8,&,#,!]*", #'replace_dummy, 1);
    msg[1]=regreplace(msg[1],"[&][1-8,&,#,!]*", #'replace_dummy, 1);
  }

  if(pointerp(d_msg) && sizeof(d_msg)>=2)
  {
    d_msg[0]=regreplace(d_msg[0],"[&][1-8,&,#,!]*", #'replace_dummy, 1);
    d_msg[1]=regreplace(d_msg[1],"[&][1-8,&,#,!]*", #'replace_dummy, 1);
  }    
  
  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!!!
deprecated 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!!!
deprecated 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;
}


string mess(string str,object pl)
{
  if ( !pl )
    pl=PL;

  if ( !stringp(str) || str=="" )
    return str;

  str=replace_personal(str,({pl}),1);

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