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

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


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