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