// MorgenGrauen MUDlib
//
// living/life.c -- life variables
//
// $Id: life.c 9426 2016-01-03 10:02:57Z Zesstra $

// living object life variables
//
//  P_ALIGN         -- alignment value
//  P_NPC           -- if living is an NPC
//  P_HP            -- HitPoints
//  P_SP            -- SpellPoints
//  P_ALCOHOL       -- value of intoxication
//  P_DRINK         -- value of soakness
//  P_FOOD          -- value of stuffness
//  P_XP            -- experience
//  P_POISON        -- level of poison
//  P_CORPSE        -- corpse-object
//  P_DEAF          -- if living is deaf
#pragma strict_types,save_types,rtt_checks
#pragma range_check
#pragma no_clone

#define NEED_PROTOTYPES
#include <hook.h>
#include <living/skills.h>
#include <thing/properties.h>
#include <living/life.h>
#include <living/moving.h>
#include <living/combat.h>
#include <living/attributes.h>
#include <thing/description.h>
#include <thing/language.h>
#undef NEED_PROTOTYPES
#include <health.h>
#include <defines.h>
#include <new_skills.h>
#include <scoremaster.h>
#include <defuel.h>
#include <properties.h>
#include <events.h>
#include <wizlevels.h>

#define ALCOHOL_VALUE(n) n

#include <debug_info.h> //voruebergehend


// 'private'-Prototypen
private void DistributeExp(object enemy, int exp_to_give);

// Variablen
nosave int delay_alcohol; /* time until next alcohol effect */
nosave int delay_drink;   /* time until next drink effect */
nosave int delay_food;    /* time until next food effect */
nosave int delay_heal;    /* time until next heal effect */
nosave int delay_sp;      /* time until next sp regeneration */
nosave int delay_poison;  /* time until next poison effect */
nosave int drop_poison;
nosave mapping enemy_damage;
nosave mapping hp_buffer;
nosave mapping sp_buffer;
nosave int remove_me;
int nextdefueltimefood;
int nextdefueltimedrink;


protected void create()
{
  Set(P_GHOST, SAVE, F_MODE);
  Set(P_FROG, SAVE, F_MODE);
  Set(P_ALIGN, SAVE, F_MODE);
  Set(P_HP, SAVE, F_MODE);
  Set(P_SP, SAVE, F_MODE);
  Set(P_XP, SAVE, F_MODE);
  Set( P_LAST_XP, ({ "", 0 }) );
  Set( P_LAST_XP, PROTECTED, F_MODE_AS );

  Set(P_ALCOHOL, SAVE, F_MODE);
  Set(P_DRINK, SAVE, F_MODE);
  Set(P_FOOD, SAVE, F_MODE);
  Set(P_POISON, SAVE, F_MODE);
  Set(P_DEAF, SAVE, F_MODE);

  SetProp(P_FOOD_DELAY, FOOD_DELAY);
  SetProp(P_DRINK_DELAY, DRINK_DELAY);
  SetProp(P_ALCOHOL_DELAY, ALCOHOL_DELAY);
  SetProp(P_HP_DELAY,HEAL_DELAY);
  SetProp(P_SP_DELAY,HEAL_DELAY);
  SetProp(P_POISON_DELAY,POISON_DELAY);
  // default fuer alle Lebewesen (NPC + Spieler):
  SetProp(P_MAX_POISON, 10);
  SetProp(P_CORPSE, "/std/corpse");

  nextdefueltimefood=time()+QueryProp(P_DEFUEL_TIME_FOOD);
  nextdefueltimedrink=time()+QueryProp(P_DEFUEL_TIME_DRINK);

  enemy_damage=([:2 ]);
  hp_buffer=([]);
  sp_buffer=([]);

  SetProp(P_DEFUEL_LIMIT_FOOD,1);
  SetProp(P_DEFUEL_LIMIT_DRINK,1);
  SetProp(P_DEFUEL_TIME_FOOD,1);
  SetProp(P_DEFUEL_TIME_DRINK,1);
  SetProp(P_DEFUEL_AMOUNT_FOOD,1);
  SetProp(P_DEFUEL_AMOUNT_DRINK,1);

  offerHook(H_HOOK_DIE,1);

  offerHook(H_HOOK_FOOD,1);
  offerHook(H_HOOK_DRINK,1);
  offerHook(H_HOOK_ALCOHOL,1);
  offerHook(H_HOOK_POISON,1);
  offerHook(H_HOOK_CONSUME,1);
}

// Wenn der letzte Kampf lang her ist und das Lebewesen wieder vollgeheilt
// ist, wird P_ENEMY_DAMAGE zurueckgesetzt.
protected void ResetEnemyDamage() {
  if (time() > QueryProp(P_LAST_COMBAT_TIME) + __RESET_TIME__ * 4
      && QueryProp(P_HP) == QueryProp(P_MAX_HP))
    enemy_damage=([:2 ]);
}

private void DistributeExp(object enemy, int exp_to_give) {
  int total_damage, tmp, ex;
  mapping present_enemies;

  if ( exp_to_give<=0 )
    return;

  mapping endmg=deep_copy(enemy_damage);

  // Mitglieder im Team des Killers bekommen:
  //
  //                  Gesamtanteil des Teams
  // Eigenen Anteil + ----------------------
  //                  Anzahl  Teammitglieder
  // ---------------------------------------
  //                2
  //
  object *inv = ({object*})enemy->TeamMembers();
  if ( pointerp(inv) )
  {
    present_enemies=m_allocate(sizeof(inv), 1);
    foreach(object ob: inv)
    {
      if ( objectp(ob) && (environment(ob)==environment()) )
      {
        tmp=endmg[object_name(ob)];
        total_damage+=tmp;
        present_enemies[ob] = tmp/2;
        m_delete(endmg,object_name(ob)); //s.u.
      }
    }
    int mitglieder = sizeof(present_enemies);
    if ( mitglieder )
    {
      tmp=total_damage/(2*mitglieder);
      foreach(object ob, int punkte: &present_enemies)
        punkte += tmp;
    }
  }
  else {
    // ohne Team wird trotzdem ein Mapping gebraucht. Da Groessenveraenderung
    // rel. teuer sind, kann einfach mal fuer 3 Eintraege Platz reservieren.
    present_enemies=m_allocate(3, 1);
  }
  // Und noch die Lebewesen im Raum ohne Team.
  foreach(object ob: all_inventory(environment()))
  {
    if ( tmp=endmg[object_name(ob)] )
    {
      total_damage += tmp;
      present_enemies[ob] = tmp;
      m_delete(endmg,object_name(ob)); // Nur einmal pro Leben Punkte :)
    }
  }
  if ( !total_damage )
  {
    ({int})enemy->AddExp(exp_to_give);
  }
  else
  {
    foreach(object ob, int damage: present_enemies)
    {
      if ( !objectp(ob) )
        continue;
      if ( query_once_interactive(ob) && ( !interactive(ob)
              || (query_idle(ob)>600) ) )
        continue;
      //exp_to_give*present_enemies[i][1]/total_damage gibt bei viel Schaden
      //einen numerical overflow. Daher muessen wir hier wohl doch
      //zwischenzeitlich mit floats rechnen, auch wenn das 0-1 XP Verlust
      //durch float->int-Konversion gibt. (ceil() lohnt sich IMHO nicht.)
      ex = (int)(exp_to_give*((float)damage/(float)total_damage));
      ob->AddExp(ex);
    }
  }
}

/*
 * This function is called from other players when they want to make
 * damage to us. But it will only be called indirectly.
 * We return how much damage we received, which will
 * change the attackers score. This routine is probably called from
 * heart_beat() from another player.
 * Compare this function to reduce_hit_points(dam).
 */
public int do_damage(int dam, object enemy)
{ int hit_point,al;

  if ( extern_call()
      && objectp(enemy)
      && living(enemy)
      && !QueryProp(P_ENABLE_IN_ATTACK_OUT))
  {
    al=time()-({int})enemy->QueryProp(P_LAST_MOVE);
    if (al<3)      // Erste Kampfrunde nach Betreten des Raumes?
      dam/=(4-al); // Gegen Rein-Feuerball-Raus-Taktik
  }

  if ( QueryProp(P_GHOST) || QueryProp(P_NO_ATTACK) || (dam<=0)
      || ( objectp(enemy)
          && ( ({int})enemy->QueryProp(P_GHOST)
              || ({int|string})enemy->QueryProp(P_NO_ATTACK) ) ) )
    return 0;

  hit_point = QueryProp(P_HP)-dam;

  if ( QueryProp(P_XP) && objectp(enemy) )
  {
    if ( !QueryProp(P_NO_XP) )
      ({int})enemy->AddExp(dam*({int})QueryProp(P_TOTAL_WC)/10);
  }

  if (living(enemy)) {
      string enname = object_name(enemy);
      // Hmpf. Blueprints sind doof. Die Chance ist zwar gering, aber koennte
      // sein, dass ein Unique-NPC mit zwei verschiedenen Spielern am gleichen
      // NPC metzelt.
      // TODO: MHmm. wie gross ist das Risiko wirklich?
      //if (!clonep(enemy))
      //    enname = enname + "_" + to_string(object_time(enemy));
      // nur wenn gegner NPC ist und noch nicht drinsteht: Daten aus
      // P_HELPER_NPC auswerten
      if (!member(enemy_damage,enemy) && !query_once_interactive(enemy)) {
          mixed helper = ({mixed})enemy->QueryProp(P_HELPER_NPC);
          if (pointerp(helper) && objectp(helper[0]))
              enemy_damage[enname,1] = helper[0];
      }
      enemy_damage[enname,0]+=dam;
  }

  SetProp(P_HP, hit_point);

  if ( hit_point<0 )
  {
    //TODO: Warum nicht das ganze Zeug ins die() verlegen?
    if ( enemy )
    {
      ({int})enemy->StopHuntFor(ME,1);
      if ( !QueryProp(P_NO_XP) )
        DistributeExp(enemy,QueryProp(P_XP)/100);
      if ( !query_once_interactive(ME) )
        log_file ("NPC_XP", sprintf(
	    "[%s] %s, XP: %d, HP*WC: %d, Killer: %s\n",
	    dtime(time()), object_name(ME), (QueryProp(P_XP)/100),
                  QueryProp(P_TOTAL_WC)*QueryProp(P_MAX_HP)/10,
                  ({string})enemy->name()||"NoName" ));
      al = QueryProp(P_ALIGN)/50 + ({int})enemy->QueryProp(P_ALIGN)/200;
      if (al>20)
        al=20;
      else if(al<-20)
        al=-20;
      ({int})enemy->SetProp(P_ALIGN,({int})enemy->QueryProp(P_ALIGN)-al);
    }
    SetProp(P_KILLER, enemy);
    
    die();
  }
  return dam;
}


private void _transfer( object *obs, string|object dest, int flag )
{   int i;

    i = sizeof(obs);

    // Eine Schleife ist zwar langsamer als filter() o.ae., aber
    // selbst mit einer noch so schnellen Loesung kann leider nicht
    // ausgeschlossen werden, dass irgendwo ein too-long-eval-Bug dazwischen
    // kommt. Dazu sind die Kaempfe mit Gilden-NPCs etc. einfach zu teuer ...
    // Pruefung auf zerstoerte Objekte, da einige sich evtl. im NotifyPlayerDeath() 
    // zerstoeren.
   while ( i && get_eval_cost() > 300000 )
        if ( objectp(obs[--i]) && !({int})obs[i]->QueryProp(P_NEVERDROP) )
        // Jetzt wird's noch etwas teurer mit catch() - aber manche Sachen
        // duerfen einfach nicht buggen
            catch( ({int})obs[i]->move( dest, flag );publish );

    if ( i > 0 )
        // Zuviel Rechenzeit verbraten, es muessen noch Objekte bewegt werden
        call_out( #'_transfer, 0, obs[0..i-1], dest, flag );
    else {
        if ( remove_me )
            remove();
    }
}


public varargs void transfer_all_to( string|object dest, int isnpc ) {
    int flags;
    object *obs;

    if ( !objectp(ME) )
        return;

    // Das Flag "isnpc" ist fuer NPCs gedacht. Deren Ausruestung darf nicht
    // mit M_NOCHECK bewegt werden, da Spieler das bei Nicht-Standard-Leichen
    // sonst u.U. ausnutzen koennten.
    if ( isnpc )
        flags = M_SILENT;
    else
        flags = M_SILENT|M_NOCHECK;

    obs = all_inventory(ME) || ({});

    // unnoetig, weil _transfer() auch auf P_NEVERDROP prueft. Zesstra
    //obs -= filter_objects( obs, "QueryProp", P_NEVERDROP );

    _transfer( obs, dest, flags );
}


protected varargs void create_kill_log_entry(string killer, object enemy) {
  int level,lost_exp;

  if ( (level=QueryProp(P_LEVEL))<20 || !IS_SEER(ME) )
    lost_exp = QueryProp(P_XP)/3;
  else
    lost_exp = QueryProp(P_XP)/(level-17);
  
  log_file("KILLS",sprintf("%s %s (%d,%d) %s\n", strftime("%e %b %H:%M"),
               capitalize(REAL_UID(ME)), level, lost_exp/1000, killer)); 
}

// Liefert im Tod (nach dem toetenden do_damage()) das Spielerobjekt, was den
// Tod wohl zu verantworten hat, falls es ermittelt werden kann. Es werden vor
// allem registrierte Helfer-NPC und einige Sonderobjekte beruecksichtigt.
protected object get_killing_player()
{
  object killer=QueryProp(P_KILLER);
  // koennte sein, wenn ausserhalb des Todes gerufen oder eine Vergiftung uns
  // umgebracht hat.
  if (!objectp(killer))
    return 0;

  while (killer && !query_once_interactive(killer))
    killer = ({object})killer->QueryUser();

  return killer;
}

protected object GiveKillScore(object pl, int npcnum)
{
  // Stufenpunkt fuer den Kill vergeben.
  // Falls der Killer den Punkt schon hat, wird
  // zufaellig ein Mitglied seines Teams ausgewaehlt
  // und diesem der Punkt gegeben.
  object *obs,ob;
  mixed *fr;
  int i,j,sz;

  if ( pointerp(obs=({object*})pl->TeamMembers()) && (member(obs,pl)>=0) )
  {
    if ( !pointerp(fr=({mixed})pl->PresentTeamRows())
        || !sizeof(fr)
        || !pointerp(fr=fr[0])) // Erste Reihe des Teams
      fr=({});
    fr-=({pl,0});
    obs-=({pl,0});
    obs-=fr;
    i=sz=sizeof(obs); // restliche Teammitglieder in zufaelliger Reihenfolge:
    for ( --i ; i>=0 ; i-- )
    {
      j=random(sz);
      ob=obs[j];
      obs[j]=obs[0];
      obs[0]=ob;
    }
    i=sz=sizeof(fr);  // Erste Reihe in zufaelliger Reihenfolge:
    for ( --i ; i>=0 ; i-- )
    {
      j=random(sz);
      ob=fr[j];
      fr[j]=fr[0];
      fr[0]=ob;
    }

    obs+=fr;     // Erste Reihe wird vor Rest getestet
    obs+=({pl}); // Killer wird als erstes getestet
  }
  else
  {
    obs=({pl});
  }
  for ( i=sizeof(obs)-1 ; i>=0 ; i-- )
    if ( objectp(ob=obs[i] )
        && interactive(ob)     // Nur netztot dabei stehen gilt nicht :)
        && query_idle(ob)<600  // gegen Leute die sich nur mitschleppen lassen
        && environment(ob)==environment(pl) // Nur anwesende Teammitglieder
        && !IS_LEARNER(ob)
//        && !({int|string})ob->QueryProp(P_TESTPLAYER)
        && !(({int})SCOREMASTER->HasKill(ob,ME)) )
      return ({int})SCOREMASTER->GiveKill(ob,npcnum),ob;

  return ({int})SCOREMASTER->GiveKill(pl,npcnum),pl;
}

// zum ueberschreiben in Spielern
public int death_suffering() {
  return 0; // NPC haben keine Todesfolgen
}

// kein 2. Leben fuer Nicht-Spieler. ;-)
varargs protected int second_life( object corpse ) {
    return 0;
}

public varargs void die( int poisondeath, int extern )
{   object corpse;
    string die_msg, tmp;
    mixed res;
    mixed hookData;
    mixed hookRes;

    if ( !objectp(this_object()) || QueryProp(P_GHOST) )
        return; // Ghosts dont die ...

    // direkt von extern aufgerufen und nicht ueber heart_beat() oder
    // do_damage() hierher gelangt?
    if (extern_call() && previous_object() != this_object()) {
      extern=1;
      SetProp(P_KILLER, previous_object());
    }

    if ( res = QueryProp(P_TMP_DIE_HOOK) ){
        if ( pointerp(res) && sizeof(res)>=3
            && intp(res[0]) && time()<res[0]
            && objectp(res[1]) && stringp(res[2]) )
        {
            if ( res = ({mixed})call_other( res[1], res[2], poisondeath ) ) {
              SetProp(P_KILLER,0);
              return;
            }
        }
        else
            SetProp(P_TMP_DIE_HOOK,0);
    }

    // trigger die hook
    hookData=poisondeath;
    hookRes=HookFlow(H_HOOK_DIE,hookData);
    if (pointerp(hookRes) && sizeof(hookRes)>H_RETDATA){
      if(hookRes[H_RETCODE]==H_CANCELLED) {
        SetProp(P_KILLER,0);
        return;
      }
      else if (hookRes[H_RETCODE]==H_ALTERED)
          poisondeath = hookRes[H_RETDATA];
    }

    if ( IS_LEARNING(ME) && query_once_interactive(ME) ){
       tell_object( ME, "Sei froh dass Du unsterblich bist, sonst waere es "
                        "eben Dein Ende gewesen.\n");
       SetProp(P_KILLER,0);
       return;
    }

    // Gegner befrieden.
    map_objects( QueryEnemies()[0], "StopHuntFor", ME, 1 );
    StopHuntingMode(1);

    // Falls die() direkt aufgerufen wurde und dies ein Spieler ist, muss das
    // die() noch Eintraege in /log/KILLS via create_kill_log_entry bzw. in
    // /log/KILLER erstellen.
    if ( query_once_interactive(ME) && extern )
    {
      object killer = QueryProp(P_KILLER) 
                     || previous_object() || this_interactive() || this_player();
      if ( killer && !query_once_interactive(killer) )
      {
          tmp = explode( object_name(killer), "#")[0] + " (direkt !)";

          create_kill_log_entry( tmp + " (" + REAL_UID(killer) + ")", killer );
      }
      else if ( killer && !QueryProp(P_TESTPLAYER) && !IS_LEARNER(ME) )
      {
          log_file( "KILLER", sprintf( "%s %s (%d/%d) toetete %s (%d/%d)\n",
                                       ctime(time()),
                                       capitalize(getuid(killer)),
                                       query_wiz_level(killer),
                                       ({int})killer->QueryProp(P_LEVEL),
                                       capitalize(getuid(ME)),
                                       query_wiz_level(ME),
                                       QueryProp(P_LEVEL) ) );

          ({int})killer->SetProp( P_KILLS, -1 );
      }
    }

  // Bei NPC EKs vergeben und ggf. in der Gilde des Killers und im Raum
  // NPC_Killed_By() rufen.
  if ( !query_once_interactive(ME) )
  {
    object killer = (({object}) QueryProp(P_KILLER)) || previous_object() ||
      this_interactive() || this_player();

    if ( killer && query_once_interactive(killer) )
    {
      if (stringp(res=({string})killer->QueryProp(P_GUILD))
          && objectp(res=find_object("/gilden/"+res)))
        ({void})res->NPC_Killed_By(killer);

      if (environment())
          ({void})environment()->NPC_Killed_By(killer);

      res = QueryProp(P_XP);
      res = (res < SCORE_LOW_MARK) ? 0 : ((res > SCORE_HIGH_MARK) ? 2 : 1);
      if ( !QueryProp(P_NO_SCORE) && !IS_LEARNER(killer) &&
           // !killer->QueryProp(P_TESTPLAYER) &&
           pointerp( res = ({mixed})SCOREMASTER->QueryNPC(res)) )
        GiveKillScore( killer, res[0] );
    }
  }

  if( !(die_msg = QueryProp(P_DIE_MSG)) )
    if (QueryProp(P_PLURAL))
      die_msg = " fallen tot zu Boden.\n";
    else
      die_msg = " faellt tot zu Boden.\n";

  if ( poisondeath )
  {
      Set( P_LAST_DAMTYPES, ({ DT_POISON }) );
      Set( P_LAST_DAMTIME, time() );
      Set( P_LAST_DAMAGE, 1 );
      die_msg = " wird von Gift hinweggerafft und kippt um.\n";
  }

  say( capitalize(name(WER,1)) + die_msg );

  // Wenn keine Leiche, dann Kram ins Env legen.
  if ( QueryProp(P_NOCORPSE) || !(tmp = QueryProp(P_CORPSE))
      || catch(corpse = clone_object(tmp);publish) 
      || !objectp(corpse) )
  {
      // Magier oder Testspieler behalten ihre Ausruestung.
      // Sonst kaemen u.U. Spieler an Magiertools etc. heran
      if ( !(IS_LEARNER(ME) || (tmp = Query(P_TESTPLAYER)) &&
             (!stringp(tmp) || IS_LEARNER( lower_case(tmp) ))) )
          transfer_all_to( environment(), 0 );
      else
          // Aber sie ziehen sich aus.
          filter_objects(QueryProp(P_ARMOURS),"DoUnwear",M_NOCHECK,0);
  }
  else
  // sonst in die Leiche legen.
  {
      ({void})corpse->Identify(ME);
      ({int})corpse->move( environment(), M_NOCHECK|M_SILENT );
      // Magier oder Testspieler behalten ihre Ausruestung.
      // Sonst kaemen u.U. Spieler an Magiertools etc. heran
      if ( !(IS_LEARNER(ME) || (tmp = Query(P_TESTPLAYER)) &&
             (!stringp(tmp) || IS_LEARNER( lower_case(tmp) ))) )
          transfer_all_to( corpse, !query_once_interactive(ME) );
      else
          // Aber sie ziehen sich aus.
          filter_objects(QueryProp(P_ARMOURS),"DoUnwear",M_NOCHECK,0);
  }

  if ( query_once_interactive(ME) ) {
      Set( P_DEADS, Query(P_DEADS) + 1 );
      // Spieler-Tod-event ausloesen
      ({int})EVENTD->TriggerEvent(EVT_LIB_PLAYER_DEATH, ([
      E_OBJECT: ME, E_PLNAME: getuid(ME),
      E_ENVIRONMENT: environment(), E_TIME: time(),
      P_KILLER: QueryProp(P_KILLER),
      P_LAST_DAMAGE: QueryProp(P_LAST_DAMAGE),
      P_LAST_DAMTYPES: copy(QueryProp(P_LAST_DAMTYPES)),
      E_EXTERNAL_DEATH: extern,
      E_POISON_DEATH: poisondeath, 
      E_CORPSE: (objectp(corpse)?corpse:0) ]) );
  }
  else {
      // NPC-Todes-Event ausloesen. Div. Mappings/Arrays werden nicht kopiert,
      // weil der NPC ja jetzt eh zerstoert wird.
      mapping data = ([
            E_OBNAME: object_name(ME),
            E_ENVIRONMENT: environment(), E_TIME: time(),
            P_NAME: QueryProp(P_NAME),
            P_KILLER: QueryProp(P_KILLER),
            P_ENEMY_DAMAGE: QueryProp(P_ENEMY_DAMAGE),
            P_LAST_DAMAGE: QueryProp(P_LAST_DAMAGE),
            P_LAST_DAMTYPES: QueryProp(P_LAST_DAMTYPES),
            E_EXTERNAL_DEATH: extern,
            E_POISON_DEATH: poisondeath,
            E_CORPSE: (objectp(corpse)?corpse:0),
            P_XP: QueryProp(P_XP),
            P_ATTRIBUTES: QueryProp(P_ATTRIBUTES),
            P_MAX_HP: QueryProp(P_MAX_HP),
            P_HANDS: QueryProp(P_HANDS),
            P_ALIGN: QueryProp(P_ALIGN),
            P_RACE: QueryProp(P_RACE),
            P_CLASS: QueryProp(P_CLASS),
            ]);
      ({int})EVENTD->TriggerEvent(EVT_LIB_NPC_DEATH(""), data);
      ({int})EVENTD->TriggerEvent(
          EVT_LIB_NPC_DEATH(load_name(ME)), data);
  }

  // transfer_all_to() ist evtl. (wenn zuviele Objekte bewegt werden mussten)
  // noch nicht ganz fertig und wird per call_out() den Rest erledigen.
  // Sollte die Leiche dann nicht mehr existieren, verbleiben die restlichen
  // Objekte im Spieler.
  // Es bleiben aber auf jeden Fall noch rund 300k Eval-Ticks ueber, damit
  // kein Spieler dank "evalcost too high" ungeschoren davon kommt.
  if ( !(second_life(corpse)) )
  {
      Set( P_GHOST, 1 ); // Fuer korrekte Ausgabe auf Teamkanal.

      if ( find_call_out(#'_transfer) == -1 )
          // Falls kein call_out() mehr laeuft, sofort destructen ...
          remove();
      else
          // ... ansonsten vormerken
          remove_me = 1;
  }
  else
  {
    // In Spielern den Reg-Buffer fuer HP/SP loeschen
    hp_buffer=([]);
    sp_buffer=([]);
  }
}

public void heal_self(int h)
{
  if ( h<=0 )
    return;
  SetProp(P_HP, QueryProp(P_HP)+h);
  SetProp(P_SP, QueryProp(P_SP)+h);
}


//--------------------------------------------------------------------------
//
//   int defuel_food( /* void */ )
//
//   Enttankt den Spieler um einen gewissen Essens-Wert.
//   Sollte nur von Toiletten aufgerufen werden.
//
//--------------------------------------------------------------------------
public int defuel_food()
{
  int food;

  food=QueryProp(P_FOOD);

// wenn spieler kein food hat: return 0
  if ( !food )
   return NO_DEFUEL;

// wenn spieler unter enttank-grenze: return -1
  if ( food < QueryProp(P_DEFUEL_LIMIT_FOOD) )
   return DEFUEL_TOO_LOW;

// wenn letztes enttanken nicht lange genug zurueckliegt: return -2
  if ( time() < nextdefueltimefood )
   return DEFUEL_TOO_SOON;

  food=to_int(((food*QueryProp(P_DEFUEL_AMOUNT_FOOD))/2));
  food+=random(food);

// sicherheitshalber
  if ( food > QueryProp(P_FOOD) )
   food=QueryProp(P_FOOD);

  SetProp(P_FOOD,(QueryProp(P_FOOD)-food));

  nextdefueltimefood=time()+QueryProp(P_DEFUEL_TIME_FOOD);

  return food;
}


//--------------------------------------------------------------------------
//
//   int defuel_drink( /* void */ )
//
//   Enttankt den Spieler um einen gewissen Fluessigkeits-Wert.
//   Gleichzeitig wird eine gewisse Menge Alkohol reduziert.
//   Sollte nur von Toiletten aufgerufen werden.
//
//--------------------------------------------------------------------------
public int defuel_drink()
{
  int alc, drink;

  drink=QueryProp(P_DRINK);

// wenn spieler kein drink hat: return 0
  if ( !drink )
   return NO_DEFUEL;

// wenn spieler unter enttank-grenze: return -1
  if ( drink < QueryProp(P_DEFUEL_LIMIT_DRINK) )
   return DEFUEL_TOO_LOW;

// wenn letztes enttanken nicht lange genug zurueckliegt: return -2
  if ( time() < nextdefueltimedrink )
   return DEFUEL_TOO_SOON;
    
  drink=to_int(((drink*QueryProp(P_DEFUEL_AMOUNT_DRINK))/2));
  drink+=random(drink);

// sicherheitshalber
  if ( drink > QueryProp(P_DRINK) )
   drink=QueryProp(P_DRINK);

  SetProp(P_DRINK,(QueryProp(P_DRINK)-drink));

// jedes fluessige Enttanken macht auch etwas nuechterner :^)
// bei sehr kleinen Mengen enttankt man keinen Alkohol
// ansonsten in Abhaengigkeit von enttankter Menge, P_ALCOHOL und P_WEIGHT

  if ( drink > 9 && QueryProp(P_ALCOHOL) > 0 )
   {
    alc=(to_int(exp(log(1.1)*(drink)))*
         to_int(exp(log(0.67)*(QueryProp(P_ALCOHOL)))))/
         (QueryProp(P_MAX_DRINK)*QueryProp(P_MAX_ALCOHOL))*
         (to_int(QueryProp(P_WEIGHT)/1000));

     SetProp(P_ALCOHOL,QueryProp(P_ALCOHOL)-(alc+random(alc)));
   }

  nextdefueltimedrink=time()+QueryProp(P_DEFUEL_TIME_DRINK);
 
  return drink;
}


public void reduce_spell_points(int h)
{
  SetProp(P_SP, QueryProp(P_SP)-h);
}

public void restore_spell_points(int h)
{
  SetProp(P_SP, QueryProp(P_SP)+h);
}

/* Reduce hitpoints. Log who is doing it. */
public int reduce_hit_points(int dam)
{
  int i;

#ifdef LOG_REDUCE_HP
  if (this_player()!=ME)
  {
    log_file("REDUCE_HP", name()+" by ");
    if(!this_player()) log_file("REDUCE_HP","?\n");
    else {
      log_file("REDUCE_HP",({string})this_player()->name());
      o=previous_object();
      if (o)
        log_file("REDUCE_HP", " " + object_name(o) + ", " +
                 ({string})o->name(WER,0) + " (" + creator(o) + ")\n");
      else
        log_file("REDUCE_HP", " ??\n");
    }
  }
#endif
  if ((i=QueryProp(P_HP)) <= dam)
    return SetProp(P_HP,1);
  return SetProp(P_HP, i - dam);
}

public int restore_hit_points(int heal)
{
  return reduce_hit_points(-heal);
}

public varargs int drink_alcohol(int strength,int testonly, string mytext)
{ int alc,add,res;

  add=ALCOHOL_VALUE(strength);
  res=UseSkill(SK_BOOZE,([
      SI_SKILLARG : add,
      SI_TESTFLAG : 1])); // Kann der Spieler gut saufen?
  if (intp(res) && res>0) add=res;
  alc=QueryProp(P_ALCOHOL)+add;
  if ((alc >= QueryProp(P_MAX_ALCOHOL)) && !IS_LEARNING(this_object())){
    if(!testonly)
      tell_object(ME,mytext||"So ein Pech, Du hast alles verschuettet.\n");
    return 0;
  }
  if(testonly)return 1;
  UseSkill(SK_BOOZE,([ SI_SKILLARG : ALCOHOL_VALUE(strength) ]));
  if(alc < 0) alc = 0;
  if(!alc) tell_object(ME, "Du bist stocknuechtern.\n");
  SetProp(P_ALCOHOL, alc);
  return 1;
}

public varargs int drink_soft(int strength, int testonly, string mytext)
{ int soaked;

  soaked = QueryProp(P_DRINK);
  if((soaked + strength > QueryProp(P_MAX_DRINK)) &&
     !IS_LEARNING(this_object())){
    if(!testonly)
     tell_object(ME, mytext||
       "Nee, so viel kannst Du momentan echt nicht trinken.\n" );
    return 0;
  }
  if(testonly)return 1;
  if((soaked += DRINK_VALUE(strength)) < 0) soaked = 0;
  if(!soaked) tell_object(ME, "Dir klebt die Zunge am Gaumen.\n");
  SetProp(P_DRINK, soaked);
  return 1;
}

public varargs int eat_food(int strength, int testonly, string mytext)
{ int stuffed;

  stuffed = QueryProp(P_FOOD);
  if ((stuffed + strength > QueryProp(P_MAX_FOOD)) &&
      !IS_LEARNING(this_object()))
  {
    if(!testonly)
        tell_object(ME,
            mytext || "Das ist viel zu viel fuer Dich! Wie waers mit etwas "
            "leichterem?\n");
    return 0;
  }
  if(testonly)return 1;
  stuffed += FOOD_VALUE(strength);
  if(stuffed < 0) stuffed = 0;
  if(!stuffed) tell_object(ME, "Was rumpelt denn da in Deinem Bauch?\n");
  SetProp(P_FOOD, stuffed);
  return 1;
}

public int buffer_hp(int val,int rate)
{
  int dif;

  if(val<=0 || rate<=0)return 0;
  if(val < rate)rate = val;
  if(rate>20) rate=20;

  /* Check for BufferOverflow */
  if((dif=(hp_buffer[0]+val)-QueryProp(P_MAX_HP)) > 0)val-=dif;
  if(val<=0)return 0;

  hp_buffer[0] += val;
  hp_buffer[1+rate] += val;
  if(rate > hp_buffer[1])hp_buffer[1] = rate;

  return hp_buffer[0];
}

public int buffer_sp(int val,int rate)
{
  int dif;

  if(val<=0 || rate<=0)return 0;
  if(val < rate)rate = val;
  if(rate>20) rate=20;

  /* Check for BufferOverflow */
  if((dif=(sp_buffer[0]+val)-QueryProp(P_MAX_SP)) > 0)val-=dif;
  if(val<=0)return 0;

  sp_buffer[0] += val;
  sp_buffer[1+rate] += val;
  if(rate > sp_buffer[1])sp_buffer[1] = rate;

  return sp_buffer[0];
}

protected void update_buffers()
{ int i, rate, max;

  rate=0;
  max=0;
  for(i=1;i<=20;i++){
    if(member(hp_buffer, i+1))
      if(hp_buffer[i+1]<=0)
        hp_buffer = m_delete(hp_buffer,i+1);
      else{
        max+=hp_buffer[i+1];
        rate=i;
      }
  }

  hp_buffer[0]=max;
  hp_buffer[1]=rate;
  rate=0;
  max=0;
  for(i=1;i<=20;i++){
    if(member(sp_buffer, i+1))
      if(sp_buffer[i+1]<=0)
        sp_buffer = m_delete(sp_buffer,i+1);
      else{
        max+=sp_buffer[i+1];
        rate=i;
      }
  }
  sp_buffer[0]=max;
  sp_buffer[1]=rate;
}

public int check_timed_key(string key) {

  // keine 0 als key (Typ wird per RTTC geprueft)
  if (!key)
    return 0;
  mapping tmap=Query(P_TIMING_MAP, F_VALUE);
  if (!mappingp(tmap)) {
    tmap=([]);
    Set(P_TIMING_MAP, tmap, F_VALUE);
  }
  // Wenn key noch nicht abgelaufen, Ablaufzeitpunkt zurueckgeben.
  // Sonst 0 (key frei)
  return (time() < tmap[key]) && tmap[key];
}

public int check_and_update_timed_key(int duration,string key) {

  // wenn key noch gesperrt, die zeit der naechsten Verfuegbarkeit
  // zurueckgeben.
  int res = check_timed_key(key);
  if (res) {
    return res;
  }

  // duration <= 0 ist unsinnig. Aber key ist nicht mehr gesperrt, d.h. time()
  // ist ein sinnvoller Rueckgabewert.
  if (duration <= 0)
    return time();
 
  mapping tmap = Query(P_TIMING_MAP,F_VALUE);
  tmap[key]=time()+duration;
  
  // speichern per SetProp() unnoetig, da man das Mapping direkt aendert,
  // keine Kopie.
  //SetProp(P_TIMING_MAP, tmap);
  
  return -1; // Erfolg.
}

protected void expire_timing_map() {
  
  mapping tmap = Query(P_TIMING_MAP, F_VALUE);
  if (!mappingp(tmap) || !sizeof(tmap))
    return;
  foreach(string key, int endtime: tmap) {
    if (endtime < time())
      m_delete(tmap, key);
  }
  // speichern per SetProp() unnoetig, da man das Mapping direkt aendert,
  // keine Kopie.
}

protected void heart_beat()
{
    if ( !this_object() )
        return;

    attribute_hb();

    // Als Geist leidet man nicht unter so weltlichen Dingen wie
    // Alkohol, Gift&Co ...
    if ( QueryProp(P_GHOST) )
        return;

    int hpoison = QueryProp(P_POISON);
    int rlock = QueryProp(P_NO_REGENERATION);
    int hp = QueryProp(P_HP);
    int sp = QueryProp(P_SP);
    int alc;

    // Wenn Alkohol getrunken: Alkoholauswirkungen?
    if ( (alc = QueryProp(P_ALCOHOL)) && !random(40) ){
        int n;
        string gilde;
        object ob;

        n = random( 5 * (alc - 1)/QueryProp(P_MAX_ALCOHOL) );

        switch (n){
        case ALC_EFFECT_HICK:
            say( capitalize(name( WER, 1 )) + " sagt: <Hick>!\n" );
            write( "<Hick>! Oh, Tschuldigung.\n" );
            break;
            
        case ALC_EFFECT_STUMBLE:
            say( capitalize(name( WER, 1 )) + " stolpert ueber " +
                 QueryPossPronoun( FEMALE, WEN ) + " Fuesse.\n" );
            write( "Du stolperst.\n" );
            break;
            
        case ALC_EFFECT_LOOKDRUNK:
            say( capitalize(name( WER, 1 )) + " sieht betrunken aus.\n" );
            write( "Du fuehlst Dich benommen.\n" );
            break;
            
        case ALC_EFFECT_RUELPS:
            say( capitalize(name( WER, 1 )) + " ruelpst.\n" );
            write( "Du ruelpst.\n" );
            break;
        }
       
        // Gilde und Environment informieren ueber Alkoholauswirkung.
        if ( stringp(gilde = QueryProp(P_GUILD))
             && objectp(ob = find_object( "/gilden/" + gilde )) )
            ({void})ob->InformAlcoholEffect( ME, n, ALC_EFFECT_AREA_GUILD );
        
        if ( environment() )
            ({void})environment()->InformAlcoholEffect( ME, n, ALC_EFFECT_AREA_ENV );
    }
    
    // Alkohol abbauen und etwas extra heilen, falls erlaubt.
    if ( alc && (--delay_alcohol < 0)
         && !(rlock & NO_REG_ALCOHOL) ){

        SetProp( P_ALCOHOL, alc - 1 );
        
        if ( !hpoison ){
            hp++;
            sp++;
        }
        
        delay_alcohol = QueryProp(P_ALCOHOL_DELAY);
    }

    // P_DRINK reduzieren, falls erlaubt.
    if ( (--delay_drink < 0) && !(rlock & NO_REG_DRINK) ){
        delay_drink = QueryProp(P_DRINK_DELAY);
        SetProp( P_DRINK, QueryProp(P_DRINK) - 1 );
    }

    // P_FOOD reduzieren, falls erlaubt.
    if ( (--delay_food < 0) && !(rlock & NO_REG_FOOD) ){
        delay_food = QueryProp(P_FOOD_DELAY);
        SetProp( P_FOOD, QueryProp(P_FOOD) - 1 );
    }

    // Regeneration aus dem HP-Puffer
    // Hierbei wird zwar nur geheilt, wenn das erlaubt ist, aber der Puffer
    // muss trotzdem abgearbeitet/reduziert werden, da Delfen sonst eine
    // mobile Tanke kriegen. (Keine Heilung im Hellen, Puffer bleibt sonst
    // konstant und kann bei Bedarf ueber dunkelmachende Items abgerufen
    // werden.)
    int val;
    if (hp_buffer[0]) {
        int rate = hp_buffer[1];
        val = hp_buffer[rate + 1];
    
        if ( val > rate )
            val = rate;
        hp_buffer[0] -= val;
        hp_buffer[rate + 1] -= val;
        if ( hp_buffer[rate + 1] <= 0 )
            update_buffers();
    }
    // Jetzt Regeneration aus dem Puffer durchfuehren, aber nur wenn erlaubt.
    if ( val && !(rlock & NO_REG_BUFFER_HP) )
        hp += val; 
    // normales Heilen, falls keine Regeneration aus dem Puffer erfolgte und
    // es erlaubt ist.
    else if ( (--delay_heal < 0) && !(rlock & NO_REG_HP) ){
        delay_heal = QueryProp(P_HP_DELAY);
        if ( !hpoison )
            hp++;
    }

    // Gleiches Spiel jetzt fuer den SP-Puffer (s.o.)
    val=0;
    if ( sp_buffer[0] ) {
        int rate = sp_buffer[1];
        val = sp_buffer[rate + 1];
        
        if ( val > rate )
            val = rate;
        
        sp_buffer[0] -= val;
        sp_buffer[rate + 1] -= val;
 
        if ( sp_buffer[rate + 1] <= 0 )
            update_buffers();
    }
    // Regeneration erlaubt?
    if ( val && !(rlock & NO_REG_BUFFER_SP) )
         sp += val;
    // Wenn nicht, normales Hochideln versuchen.
    else if ( (--delay_sp < 0) && !(rlock & NO_REG_SP) ){
        delay_sp = QueryProp(P_SP_DELAY);
        if ( !hpoison )
            sp++;
    }

    if ( hpoison && (interactive(ME) || !query_once_interactive(ME)) ){
        // Vanion, 26.10.03
        // Wenn _set_poison() per SET_METHOD ueberschrieben wird, kann
        // nicht sichergestellt werden, dass poison immer groesser 0 ist
        // Daher muss hier ein Test rein, so teuer das auch ist :(
        if (--hpoison < 0)
          hpoison=0;
        
        if ( --delay_poison < 0 ){
            delay_poison = QueryProp(P_POISON_DELAY)
                + random(POISON_MERCY_DELAY);
            hp -= hpoison;

            if ( hp < 0 ){
                tell_object( ME, "Oh weh - das Gift war zuviel fuer Dich!\n"
                             + "Du stirbst.\n" );
                
                if ( query_once_interactive(ME) ){
                    create_kill_log_entry( "Vergiftung", 0 );
                    
                    // Beim Gifttod gibt es keinen Killer. Aber auf diese Art
                    // erkennt der Todesraum die Ursache korrekt und gibt die
                    // richtige Meldung aus.
                    SetProp( P_KILLER, "gift" );
                }
                
                die(1);
                return;
            }
            
            if ( (hpoison < 3 || !query_once_interactive(ME) )
                 && --drop_poison < 0)
            {
                // Giftlevel eins reduzieren. hpoison wurde oben schon
                // reduziert, d.h. einfach hpoison in P_POISON schreiben.
                // dabei wird dann auch ggf. drop_poison richtig gesetzt.
                SetProp( P_POISON, hpoison );
                if ( !hpoison )
                    tell_object( ME, "Du scheinst die Vergiftung "
                                     "ueberwunden zu haben.\n" );  
            }
        }
        
        if ( hpoison && !random(15) )
            switch ( hp*100/QueryProp(P_MAX_HP) ){
            case 71..100 :
                write( "Du fuehlst Dich nicht gut.\n" );
                say( capitalize(name(WER)) +
                     " sieht etwas benommen aus.\n" );
                break;
                
            case 46..70 :
                write( "Dir ist schwindlig und Dein Magen revoltiert.\n" );
                say( capitalize(name(WER)) + " taumelt ein wenig.\n" );
                break;
                
            case 26..45 :
                write( "Dir ist heiss. Du fuehlst Dich schwach. Kopfweh "
                       "hast Du auch.\n" );
                say( capitalize(name(WER)) + " glueht direkt und scheint "
                     "grosse Schwierigkeiten zu haben.\n" );
                break;
                
            case 11..25 :
                write( "Du fuehlst Dich beschissen. Alles tut weh, und Du "
                       "siehst nur noch unscharf.\n" );
                say( capitalize(name(WER)) + " taumelt und stoehnt und "
                     "kann gerade noch vermeiden hinzufallen.\n" );
                break;
                
            case 0..10 :
                write( break_string( "Du siehst fast nichts mehr und kannst "
                                     "Dich nur noch unter groessten Schmerzen "
                                     "bewegen. Aber bald tut nichts mehr weh"
                                     "...", 78 ) );
                say( break_string( capitalize(name(WER)) + " glueht wie "
                                   "im Fieber, kann sich kaum noch ruehren "
                                   "und hat ein schmerzverzerrtes Gesicht.\n",
                                   78 ) );
                break;
            }
    }

    SetProp( P_HP, hp );
    SetProp( P_SP, sp );
}

public int AddExp( int e )
{
  int experience;
  string fn;
  mixed last;

  experience = QueryProp(P_XP);

  if ( QueryProp(P_KILLS) > 1 && e > 0 )
      return experience;

  fn = implode( explode( object_name( environment() || this_object() ),
                               "/" )[0..<2], "/" );

  if ( pointerp(last = Query(P_LAST_XP)) && sizeof(last) == 2 && last[0] == fn )
      Set( P_LAST_XP, ({ fn, last[1]+e }) );
  else
      Set( P_LAST_XP, ({ fn, e }) );

  if ( (experience += e) < 0 )
      experience = 0;

  return SetProp( P_XP, experience );
}

static <string|int>* _set_last_xp( <int|string>* last )
{
    if ( !pointerp(last) || sizeof(last) != 2 || !stringp(last[0]) ||
         !intp(last[1]) )
        return Query(P_LAST_XP);
    else
        return Set( P_LAST_XP, last );
}


static int _set_align(int a)
{
  if (a<-1000) a = -1000;
  if (a>1000) a = 1000;
  return Set(P_ALIGN, a);
}


static int _set_hp( int hp )
{
    if ( QueryProp(P_GHOST) )
        return QueryProp(P_HP);

    if ( hp < 0 )
        return Set( P_HP, 0 );

    if ( hp > QueryProp(P_MAX_HP) )
        return Set( P_HP, QueryProp(P_MAX_HP), F_VALUE );

    return Set( P_HP, hp, F_VALUE );
}

static int _set_sp( int sp )
{
    if ( QueryProp(P_GHOST) )
        QueryProp(P_SP);

    if ( sp < 0 )
        return Set( P_SP, 0 );

    if ( sp > QueryProp(P_MAX_SP) )
        return Set( P_SP, QueryProp(P_MAX_SP), F_VALUE );

    return Set( P_SP, sp, F_VALUE );
}

static int _set_alcohol(int n)
{
  if (QueryProp(P_GHOST))
    return Query(P_ALCOHOL, F_VALUE);

  // nur Aenderungen und Werte >=0 werden gesetzt...
  n = n < 0 ? 0 : n;
  int old = Query(P_ALCOHOL, F_VALUE);
  if ( old == n)
    return old;

  // Hooks aufrufen
  int *ret = HookFlow(H_HOOK_ALCOHOL, n);
  // Bei Abbruch alten Wert zurueckgeben
  switch (ret[H_RETCODE]) {
    case H_CANCELLED:
      return old;
    case H_ALTERED:
      // sonst neuen Wert setzen
      if(!intp(ret[H_RETDATA]))
          raise_error(sprintf(
            "_set_alcohol(): data from HookFlow() != <int>: %.50O\n",
            ret[H_RETDATA]));
      n = ret[H_RETDATA];
      n = n < 0 ? 0 : n;

    // H_NO_MOD is fallthrough
  }

  return Set(P_ALCOHOL, n, F_VALUE);
}

static int _set_drink(int n)
{
  if (QueryProp(P_GHOST))
    return Query(P_DRINK, F_VALUE);

  // nur Aenderungen und Werte >=0 werden gesetzt...
  n = n < 0 ? 0 : n;
  int old = Query(P_DRINK, F_VALUE);
  if ( old == n)
    return old;

  // Hooks aufrufen
  int *ret = HookFlow(H_HOOK_DRINK, n);
  // Bei Abbruch alten Wert zurueckgeben
  switch (ret[H_RETCODE]) {
    case H_CANCELLED:
      return old;
    case H_ALTERED:
      // sonst neuen Wert setzen
      if(!intp(ret[H_RETDATA]))
          raise_error(sprintf(
            "_set_drink(): data from HookFlow() != <int>: %.50O\n",
            ret[H_RETDATA]));
      n = ret[H_RETDATA];
      n = n < 0 ? 0 : n;

    // H_NO_MOD is fallthrough
  }

  return Set(P_DRINK, n, F_VALUE);
}

static int _set_food(int n)
{
  if (QueryProp(P_GHOST))
    return Query(P_FOOD, F_VALUE);

  // nur Aenderungen und Werte >=0 werden gesetzt...
  n = n < 0 ? 0 : n;
  int old = Query(P_FOOD, F_VALUE);
  if ( old == n)
    return old;

  // Hooks aufrufen
  int *ret = HookFlow(H_HOOK_FOOD, n);
  // Bei Abbruch alten Wert zurueckgeben
  switch (ret[H_RETCODE]) {
    case H_CANCELLED:
      return old;
    case H_ALTERED:
      // sonst neuen Wert setzen
      if(!intp(ret[H_RETDATA]))
          raise_error(sprintf(
            "_set_food(): data from HookFlow() != <int>: %.50O\n",
            ret[H_RETDATA]));
      n = ret[H_RETDATA];
      n = n < 0 ? 0 : n;

    // H_NO_MOD is fallthrough
  }

  return Set(P_FOOD, n, F_VALUE);
}

static int _set_poison(int n)
{
  if (QueryProp(P_GHOST))
    return Query(P_POISON, F_VALUE);

  int mp = QueryProp(P_MAX_POISON);
  n = (n<0 ? 0 : (n>mp ? mp : n));

  // nur >=0 zulassen.
  n = n < 0 ? 0 : n;

  int old = Query(P_POISON, F_VALUE);
  if ( old == 0 && n == 0)
    return old;

  // Hooks aufrufen
  int *ret = HookFlow(H_HOOK_POISON, n);
  // Bei Abbruch alten Wert zurueckgeben
  switch (ret[H_RETCODE]) {
    case H_CANCELLED:
      return old;
    case H_ALTERED:
      // sonst neuen Wert setzen
      if(!intp(ret[H_RETDATA]))
          raise_error(sprintf(
            "_set_poison(): data from HookFlow() != <int>: %.50O\n",
            ret[H_RETDATA]));
      n = ret[H_RETDATA];
      n = n < 0 ? 0 : n;

    // H_NO_MOD is fallthrough
  }

  // Fuer die Selbstheilung.
  switch(n) {
  case 1:
    drop_poison = 40+random(16);
    break;
  case 2:
    drop_poison = 25+random(8);
    break;
  case 3:
    drop_poison = 18+random(4);
    break;
  default:
    // nur relevant fuer NPC, da Spieler bei >3 Gift nicht mehr regegenieren.
    drop_poison = 22 - 2*n + random(43 - 3*n);
    break;
  }

  // fuer Setzen der Prop von aussen ein Log schreiben
  if (previous_object(1) != ME)
    log_file("POISON", sprintf("%s - %s: %d von %O (%s)\n",
           dtime(time())[5..],
           (query_once_interactive(this_object()) ?
             capitalize(geteuid(this_object())) :
             capitalize(name(WER))),
           n,
           (previous_object(2) ? previous_object(2) : previous_object(1)),
           (this_player() ? capitalize(geteuid(this_player())) : "???")));

  return Set(P_POISON, n, F_VALUE);
}

static int _set_xp(int xp) { return Set(P_XP, xp < 0 ? 0 : xp, F_VALUE); }

static mixed _set_die_hook(mixed hook)
{
  if(hook && query_once_interactive(this_object()))
    log_file("DIE_HOOK",
             sprintf("%s : DIE_HOOK gesetzt von %O in %O (%s)\n",
                     dtime(time())[5..],
                     (previous_object(2) ? previous_object(2):previous_object(1)),
                     this_object(),getuid(this_object())));
  return Set(P_TMP_DIE_HOOK,hook, F_VALUE);
}

static mapping _query_enemy_damage()
{
  return copy(enemy_damage);
}

// nur ne Kopie liefern, sonst kann das jeder von aussen aendern.
static mapping _query_timing_map() {
  return copy(Query(P_TIMING_MAP));
}

/****************************************************************************
 * Consume-Funktion, um zentral durch konsumierbare Dinge ausgeloeste
 * Aenderungen des Gesundheitszustandes herbeizufuehren.
 ***************************************************************************/

/* Konsumiert etwas
 *
 * Rueckgabewert
 *      1       erfolgreich konsumiert
 *      0       fehlende oder falsche Parameter
 *     <0       Bedingung fuer konsumieren nicht erfuellt, Bitset aus:
 *      1       Kann nichts mehr essen
 *      2       Kann nichts mehr trinken
 *      4       Kann nichts mehr saufen
 *      8       Abgebrochen durch Hook H_HOOK_CONSUME
 */
public varargs int consume(mapping cinfo, int testonly)
{
  int retval = 0;
  // nur was tun, wenn auch Infos reinkommen
  if (mappingp(cinfo) && sizeof(cinfo)) {
    // Hooks aufrufen, sie aendern ggf. noch was in cinfo.
    mixed *hret = HookFlow(H_HOOK_CONSUME, ({cinfo, testonly}) );
    switch(hret[H_RETCODE])
    {
        case H_CANCELLED:
          return -HC_HOOK_CANCELLATION;
        case H_ALTERED:
          // testonly kann nicht geaendert werden.
          cinfo = hret[H_RETDATA][0];
    }
    // Legacy-Mappings (flache) neben strukturierten Mappings zulassen
    // flache Kopien erzeugen (TODO?: und fuer Teilmappings nicht relevante
    // Eintraege loeschen)
    mapping conditions;
    if (mappingp(cinfo[H_CONDITIONS])) {
      conditions = copy(cinfo[H_CONDITIONS]);
    } else {
      conditions = copy(cinfo);
    }
    mapping effects;
    if (mappingp(cinfo[H_EFFECTS])) {
      effects = filter(cinfo[H_EFFECTS], (: member(H_ALLOWED_EFFECTS, $1) > -1 :));
    } else {
      effects = filter(cinfo, (: member(H_ALLOWED_EFFECTS, $1) > -1 :));
    }

    // Bedingungen pruefen
    if (mappingp(conditions) && sizeof(conditions)) {
      // Bedingungen fuer Konsum auswerten
      if (conditions[P_FOOD] && !eat_food(conditions[P_FOOD], 1))
        retval |= HC_MAX_FOOD_REACHED;
      else if (conditions[P_DRINK] && !drink_soft(conditions[P_DRINK], 1))
        retval |= HC_MAX_DRINK_REACHED;
      else if (conditions[P_ALCOHOL] && !drink_alcohol(conditions[P_ALCOHOL], 1))
        retval |= HC_MAX_ALCOHOL_REACHED;
      // retval negativ machen, damit Fehler leicht erkennbar ist
      retval = -retval;
    }
    // Bedingungen wurden abgearbeitet, jetzt die Heilung durchfuehren
    if (!retval) {
      if (!testonly) {
        // Bedingungen erfuellen, wenn alles passt und kein Test
        if (conditions[P_ALCOHOL])
          drink_alcohol(conditions[P_ALCOHOL]);
        if (conditions[P_DRINK])
          drink_soft(conditions[P_DRINK]);
        if (conditions[P_FOOD])
          eat_food(conditions[P_FOOD]);
        // Und jetzt die Wirkungen
        if (effects[P_POISON])
          SetProp(P_POISON, QueryProp(P_POISON) + effects[P_POISON]);
        // Und nun wirklich heilen
        switch (cinfo[H_DISTRIBUTION]) {
        case HD_INSTANT:
          map(effects, (: SetProp($1, QueryProp($1) + $2) :));
          break;
        case 1..50:
          buffer_hp(effects[P_HP], cinfo[H_DISTRIBUTION]);
          buffer_sp(effects[P_SP], cinfo[H_DISTRIBUTION]);
          break;
        default:
          buffer_hp(effects[P_HP], HD_STANDARD);
          buffer_sp(effects[P_SP], HD_STANDARD);
          break;
        }
      }
      retval = 1;
    }
  }
  return retval;
}
