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