// MorgenGrauen MUDlib
//
// living/combat.c -- Basis-Kampfmodul
//
// $Id: combat.c 9568 2016-06-05 18:53:10Z Zesstra $
#pragma strong_types
#pragma save_types
#pragma range_check
#pragma no_clone

inherit "/std/living/skill_utils";
inherit "/std/living/inventory";
inherit "/std/living/team";

#include <sys_debug.h>
#include <debug_message.h>

#define NEED_PROTOTYPES
#include <hook.h>
#include <living/skills.h>
#include <thing/properties.h>
#include <player/comm.h>
#include <living/skill_attributes.h>
#include <combat.h>
#include <living.h>
#undef NEED_PROTOTYPES

#include <config.h>
#include <properties.h>
#include <language.h>
#include <wizlevels.h>
#include <attributes.h>
#include <new_skills.h>

#include <defines.h>

#include <sensitive.h>

#define HUNTTIME 300 //300 HBs sind 10 Minuten
#define RNAME(x) capitalize(getuid(x))

// 'private'-Prototypes
private string _kill_alias( string str );

// globale Variablen
nosave mapping enemies;
private nosave int attack_busy;
nosave int no_more_attacks;
private nosave int remaining_heart_beats;
private nosave int att2_time;
private nosave string last_attack_msg;
private nosave object *missing_attacks;
// Cache fuer QueryArmourByType()
private nosave mapping QABTCache;

protected void create()
{
  Set(P_WIMPY, SAVE, F_MODE_AS);
  Set(P_TOTAL_AC, PROTECTED, F_MODE_AS);
  Set(P_HANDS, SAVE, F_MODE_AS);
  Set(P_SHOW_ATTACK_MSG,SAVE,F_MODE_AS);
  Set(P_RESISTANCE, ({}));
  Set(P_VULNERABILITY, ({}));
  Set(P_GUILD_PREPAREBLOCK, SAVE, F_MODE_AS);
  // Kein Setzen von P_ARMOURS von aussen per Set(). (Per SetProp() geht es
  // durch die Setmethode).
  Set(P_ARMOURS,PROTECTED,F_MODE_AS);
  SetProp(P_ARMOURS, ({}));
  // Kein direktes Setzen von P_DEFENDERS, Setzen nur ueber
  // die Zugriffsmethoden.
  Set(P_DEFENDERS, PROTECTED, F_MODE_AS);
  SetProp(P_DEFENDERS, ({}));
  attack_busy=100;
  att2_time=0;
  enemies=([]);
  team::create(); 
  offerHook(H_HOOK_DEFEND,1);
  offerHook(H_HOOK_ATTACK,1);
  offerHook(H_HOOK_ATTACK_MOD,1);
}

#undef DEBUG
#define DEBUG(x) if (find_object("zesstra")) \
  tell_object(find_player("zesstra"),x)

public void UpdateResistanceStrengths() { 
  mapping resmods, strmap;

  if ( !mappingp(resmods=Query(P_RESISTANCE_MODIFIER)) )
    return;

  //erstmal die alte Aufsummation loeschen
  m_delete(resmods,"me");

  //wenn jetzt leer: Abbruch, keine Res-Modifier da.
  if (!sizeof(resmods))
      return(Set(P_RESISTANCE_MODIFIER,0));

  strmap = ([]);

  // ueber alle gesetzten ResModifier gehen
  foreach(string mod, mapping resmap, object ob: resmods) {
    if ( !mappingp(resmap) || !sizeof(resmap)
        || !objectp(ob) ) {
      m_delete(resmods, mod);
      continue; // Resi ungueltig, weg damit.
    }
    // jetzt noch ueber die Submappings laufen, die die Resis der Objekte
    // beinhalten.
    foreach(string reskey, float resi: resmap) {
        strmap[reskey] = ((strmap[reskey]+1.0)*(resi+1.0))-1.0;
    }
  }

  if ( !sizeof(strmap) )
    Set(P_RESISTANCE_MODIFIER, 0);
  else
    Set(P_RESISTANCE_MODIFIER, resmods+([ "me" : strmap; 0 ]) );
}

public varargs int AddResistanceModifier(mapping mod, string add)
{ string  key;
  mapping res;

  if ( !mappingp(mod) || !sizeof(mod) || !previous_object() )
    return 0;

  key = explode(object_name(previous_object()),"#")[0];

  if ( add )
    key += ("#"+add);

  res = Query(P_RESISTANCE_MODIFIER);
  mod = deep_copy(mod);

  if ( !mappingp(res) )
    res = ([ key : mod; previous_object() ]);
  else
    res += ([ key : mod; previous_object() ]);

  Set(P_RESISTANCE_MODIFIER, res);
  UpdateResistanceStrengths();

  return 1;
}

public varargs void RemoveResistanceModifier(string add)
{ string  key;
  mapping res;

  if ( !previous_object() )
    return;

  key = explode(object_name(previous_object()),"#")[0];

  if ( add )
    key += ("#"+add);

  if ( !mappingp(res = Query(P_RESISTANCE_MODIFIER)) )
    return;

  m_delete(res, key);
  Set(P_RESISTANCE_MODIFIER, res);
  UpdateResistanceStrengths();
}

// veraltete Prop, aus Kompatibilitaetsgruenden noch vorhanden.
static mixed _set_resistance(mixed arg)
{ int     i;
  mapping resimap;
  mixed   old;

  if ( !pointerp(arg) )
    arg=({arg});

  if ( !mappingp(resimap=Query(P_RESISTANCE_STRENGTHS)) )
    resimap=([]);

  if ( pointerp(old=QueryProp(P_RESISTANCE)) )
    for ( i=sizeof(old)-1 ; i>=0 ; i-- )
      resimap[old[i]]=(1.0+resimap[old[i]])*2.0-1.0;

  for ( i=sizeof(arg)-1 ; i>=0 ; i-- )
    resimap[arg[i]]=(1.0+resimap[arg[i]])*0.5-1.0;

  SetProp(P_RESISTANCE_STRENGTHS,resimap);

  return Set(P_RESISTANCE,arg);
}

// veraltete Prop, aus Kompatibilitaetsgruenden noch vorhanden.
static mixed _set_vulnerability(mixed arg)
{ int     i;
  mapping resimap;
  mixed   old;

  if ( !pointerp(arg) )
    arg=({arg});

  if ( !mappingp(resimap=Query(P_RESISTANCE_STRENGTHS)) )
    resimap=([]);

  if ( pointerp(old=QueryProp(P_VULNERABILITY)) )
    for ( i=sizeof(old)-1 ; i>=0 ; i-- )
      resimap[old[i]]=(1.0+resimap[old[i]])*0.5-1.0;

  for ( i=sizeof(arg)-1 ; i>=0 ; i-- )
    resimap[arg[i]]=(1.0+resimap[arg[i]])*2.0-1.0;

  SetProp(P_RESISTANCE_STRENGTHS,resimap);

  return Set(P_VULNERABILITY,arg);
}


/** kill - Kampf starten.
 * Fuegt ob der Feindesliste hinzu.
 */
public int Kill(object ob)
{ int   res;
  int|string no_attack;

  if ( !objectp(ob) )
    return 0;

  if ( ob->QueryProp(P_GHOST) )
  {
    tell_object(ME,ob->Name(WER)+" ist doch schon tot!\n");
    return -1;
  }

  if ( no_attack = ob->QueryProp(P_NO_ATTACK) )
  {
    if ( stringp(no_attack) )
      tell_object(ME, no_attack);
    else
      tell_object(ME, ob->Name(WER,1)+" laesst sich nicht angreifen!\n");

    return -2;
  }

  if ( QueryProp(P_NO_ATTACK) )
    return -3;

  res=InsertEnemy(ob);
  if (res)
    tell_object(ME, "Ok.\n");
  else if (IsEnemy(ob))
    tell_object(ME, "Jajaja, machst Du doch schon!\n");
  //else //kein gueltiger Feind, ob wurde nicht eingetragen.

  if ( !res )
    return -4;  // nicht aendern ohne Kill in player/combat.c

  return 1;
}

public int InsertSingleEnemy(object ob)
{
    if ( !living(ob) )
        return 0;

    // Wie lange verfolgt dieses Living? Wenn Prop nicht gesetzt oder 
    // ungueltig, d.h. kein int oder <= 0, dann wird die Defaultzeit genommen.
    int hunttime = QueryProp(P_HUNTTIME);
    hunttime = (intp(hunttime) && hunttime > 0) ? 
                 hunttime / __HEART_BEAT_INTERVAL__ : HUNTTIME;

    // Auch wenn ein Objekt schon als Gegner eingetragen ist, trotzdem die
    // HUNTTIME erneuern. Das "return 0;" muss aber bleiben, da der Gegner
    // ja nicht neu ist.
    //
    // 09.12.2000, Tiamak
    if ( member( enemies, ob ) ) {
        enemies[ob,ENEMY_HUNTTIME] = hunttime;
        return 0;
    }

    if ( (ob==ME) || QueryProp(P_NO_ATTACK)
         || !objectp(ob) || (ob->QueryProp(P_NO_ATTACK))
         || (ob->QueryProp(P_GHOST)) )
        return 0;

    object team;
    if ( ( query_once_interactive(ME) || query_once_interactive(ob) )
         && objectp(team=Query(P_TEAM)) && (team==(ob->Query(P_TEAM))) )
        return 0;

    set_heart_beat(1);

    last_attack_msg=0;

    enemies[ob,ENEMY_HUNTTIME] = hunttime;
    Set(P_LAST_COMBAT_TIME,time());

    return 1;
}

public int InsertEnemy(object ob)
{ int res;

  if ( res=InsertSingleEnemy(ob) )
    InsertEnemyTeam(ob);

  return res;
}

public object QueryPreferedEnemy()
{ int    sz,r;
  <int|object>*  pref;
  object enemy;

  enemy=0;
  if ( pointerp(pref=QueryProp(P_PREFERED_ENEMY)) && ((sz=sizeof(pref))>1)
      && intp(r=pref[0]) && (random(100)<r) )
  {
    enemy=pref[1+random(sz-1)];

    if ( !objectp(enemy) )
    {
      pref-=({enemy});

      if ( sizeof(pref)<2 )
        pref=0;

      SetProp(P_PREFERED_ENEMY,pref);

      return 0;
    }

    if ( !IsEnemy(enemy) )
      return 0;
  }

  return enemy;
}

public object *PresentEnemies() {

  object *here=({});
  object *netdead=({});
  mixed no_attack;
  foreach(object pl: enemies) {
    if (no_attack = pl->QueryProp(P_NO_ATTACK)) {
      m_delete(enemies,pl);
      // Und auch im Gegner austragen, sonst haut der weiter zu und dieses
      // Living wehrt sich nicht. (Zesstra, 26.11.2006)
      if (stringp(no_attack)) {
        tell_object(ME, no_attack);
        pl->StopHuntFor(ME, 1);
      }
      else pl->StopHuntFor(ME, 0);
    }
    else if ( environment()==environment(pl) )
    {
      if ( interactive(pl) || !query_once_interactive(pl) )
        here+=({pl});
      else
        netdead+=({pl});
    }
  }

  if ( !sizeof(here) ) // Netztote sind nur Feinde, falls keine anderen da sind
    return netdead;

  return here;
}

public varargs object SelectEnemy(object *here)
{ object enemy;

  if ( !pointerp(here) )
    here=PresentEnemies();

  if ( !sizeof(here) )
    return 0;

  if ( !objectp(enemy=QueryPreferedEnemy())
      || (environment(enemy)!=environment()) )
    enemy=here[random(sizeof(here))];

  return enemy;
}

protected void heart_beat() {
  int hbs; 
  // leider rufen viele Leute einfach das geerbte heart_beat() obwohl sie
  // schon tot sind und damit das Objekt zerstoert ist.
  if (!living(this_object()))
      return;

  // Paralyse pruefen, ggf. reduzieren
  int dis_attack = QueryProp(P_DISABLE_ATTACK);
  if ( intp(dis_attack) && (dis_attack > 0) )
  {
      SetProp(P_DISABLE_ATTACK, --dis_attack);
  }

  // Attacken ermitteln: SA_SPEED + Rest aus dem letzten HB
  hbs = remaining_heart_beats + QuerySkillAttribute(SA_SPEED);
  if ( hbs <= 0 )
    hbs = 100; 

  // P_ATTACK_BUSY bestimmen
  if ( attack_busy > 99) 
   attack_busy = 100 + hbs;
  else
    attack_busy += 100 + hbs;
  // mehr fuer Seher...
  if ( IS_SEER(ME) )
    attack_busy+=(100+QueryProp(P_LEVEL)); 
  // max. 500, d.h. 5 Attacken
  if ( attack_busy>500 )
    attack_busy=500;

  // unganzzahligen Rest fuer naechsten HB speichern
  remaining_heart_beats = hbs % 100;
  hbs /= 100; // ganze Attacken. ;-)

  if ( hbs > 10 ) // nicht mehr als 10 Attacken.
    hbs = 10; 

  // Falls jemand seit dem letzten HB in diesem Living von aussen Attack()
  // gerufen hat (nicht ExtraAttack()), wird jetzt was abgezogen.
  hbs -= no_more_attacks;
  no_more_attacks = 0;

  // Wie lange verfolgt dieser NPC? Wenn Prop nicht gesetzt oder ungueltig,
  // d.h. kein int oder <= 0, dann wird die Defaultzeit genommen.
  int hunttime = QueryProp(P_HUNTTIME);
  hunttime = (intp(hunttime) && hunttime > 0) ? 
              hunttime / __HEART_BEAT_INTERVAL__ : HUNTTIME;
  // erstmal die Hunttimes der Gegner aktualisieren und nebenbei die
  // anwesenden Feinde merken. Ausserdem ggf. Kampf abbrechen, wenn
  // P_NO_ATTACK gesetzt ist.
  // eigentlich ist diese ganze Schleife fast das gleiche wie
  // PresentEnemies(), aber leider muessen ja die Hunttimes aktulisiert werde,
  // daher kann man nicht direkt PresentEnemies() nehmen.
  // TODO: Diese Schleife und PresentEnmies() irgendwie vereinigen.
  object *netdead=({});
  object *here=({});
  object enemy;
  mixed no_attack;
  foreach(enemy, int htime: &enemies) { // Keys in enemy
    // ggf. Meldungen ausgeben und Gegner austragen und dieses Living beim
    // Gegner austragen.
    if (no_attack=enemy->QueryProp(P_NO_ATTACK)) {
      m_delete(enemies,enemy);
        if ( stringp(no_attack) ) {
            write( no_attack );
            enemy->StopHuntFor( ME, 1 );
        }
        else
            enemy->StopHuntFor( ME, 0 );
    }
    else if ( environment()==environment(enemy) ) {
      // Gegner anwesend, als Feind merken...
      if ( interactive(enemy) || !query_once_interactive(enemy) )
        here+=({enemy});
      else
        netdead+=({enemy});
      // ... und Hunttime erneuern.
      htime = hunttime;
    }
    // Feind nicht anwesend. Timer dekrementieren und Feind austragen, wenn
    // Jagdzeit abgelaufen.
    else if ( (--htime) <= 0 )
      StopHuntFor(enemy);
  }
  // Netztote sind nur Feinde, wenn sonst keine da sind.
  if ( !sizeof(here) )
    here=netdead;

  // schonmal abfragen, ob ein Spell vorbereitet wird.
  mixed pspell=QueryProp(P_PREPARED_SPELL);

  //Da hbs 0 und no_more_attacks durch einen manuellen Aufruf von Attack() im
  //Spieler >0 sein kann, kann jetzt hbs <0 sein. (s.o.)
  if (hbs > 0 && sizeof(here)) {
    foreach(int i: hbs) {
      // Feind in Nahkampfreichweite finden
      if ( objectp(enemy=SelectNearEnemy(here)) ) {
        // Flucht erwuenscht?
        if ( QueryProp(P_WIMPY) > QueryProp(P_HP) ) {
          Flee();
          // Flucht gelungen?
          if ( enemy && (environment(enemy)!=environment()) ) {
            here = 0; // naechste Runde neue Feinde suchen
            enemy = 0;
            continue; // kein Kampf, Runde ueberspringen
          }
        }
      }
      else {
        // keine Feinde gefunden... Abbrechen.
        break;
      }
      // Paralyse gesetzt? -> Abbrechen. Dieses Pruefung muss hier passieren,
      // damit ggf. die automatische Flucht des Lebewesens durchgefuehrt wird,
      // auch wenn es paralysiert ist.
      if (dis_attack > 0) break;

      // Kampf durch Spell-Prepare blockiert?
      // Keine genaue Abfrage, wird spaeter noch genau geprueft.
      if ( pspell && QueryProp(P_GUILD_PREPAREBLOCK) )
        break; // keine Angriffe in diesem HB.
      // wenn Feind da: hit'em hard.
      if ( objectp(enemy) )
        Attack(enemy);
      // ggf. hat Attack() no_more_attacks gesetzt. Zuruecksetzen
      no_more_attacks = 0;
      // naechste Kampfrunde neue Feinde suchen
      here = 0;
    }  // foreach
  }

  no_more_attacks=0;

  // Ist ein Spell in Vorbereitung und evtl. jetzt fertig vorbereitet?
  if ( pointerp(pspell)
      && (sizeof(pspell)>=3) && intp(pspell[0]) && stringp(pspell[1]) ) {
    if ( time()>=pspell[0] ) // Kann der Spruch jetzt ausgefuehrt werden?
    {
      UseSpell(pspell[2],pspell[1]); // Dann los
      SetProp(P_PREPARED_SPELL,0);
    }
  }
  else if ( pspell ) // Unbrauchbarer Wert, loeschen
    SetProp(P_PREPARED_SPELL,0);

} // Ende heart_beat

// wird von NPC gerufen, die Heartbeats nachholen und dabei die Hunttimes um
// die Anzahl verpasster Heartbeats reduzieren muessen.
// Wird von Spielerobjekten gerufen, wenn sie nach 'schlafe ein' aufwachen, um
// die notwendige Anzahl an HB hier abzuziehen und ggf. die Feinde zu expiren,
// da Spieler ja netztot keinen Heartbeat haben.
protected void update_hunt_times(int beats) {
  if (!mappingp(enemies)) return;
  foreach(object en, int htime: &enemies) { // Mapping-Keys in en
    htime -= beats;
    if ( htime <= 0 )
      StopHuntFor(en);
  }
}

public int IsEnemy(object wer)
{
  return (member(enemies,wer));
}

public void StopHuntText(object arg)
{
  tell_object(arg,
    Name(WER,1)+" "+(QueryProp(P_PLURAL)?"jagen ":"jagt ")+
               (arg->QueryProp(P_PLURAL)?"Euch":"Dich")+" nicht mehr.\n");
  tell_object(ME,(QueryProp(P_PLURAL)?"Ihr jagt ":"Du jagst ")+
                 arg->name(WEN,1)+" nicht mehr.\n");
}

public varargs int StopHuntFor(object arg, int silent)
{
  if ( !objectp(arg) || !IsEnemy(arg) )
    return 0;

  if (!silent)
    StopHuntText(arg);

  m_delete(enemies,arg);
  last_attack_msg=0;

  return 1;
}

// Begruessungsschlag nur einmal pro HB
public void Attack2(object enemy)
{
  if ( att2_time > time() )
    return;

  att2_time=time() + __HEART_BEAT_INTERVAL__;
  Attack(enemy);
}

// Fuer evtl. Attack-Aenderungen, ohne dass man gleich das ganze
// Attack ueberlagern muss:
protected void InternalModifyAttack(mapping ainfo)
{
  return; // Vorerst!
/*
  int   fac;
  mixed res;

  fac=100;

  if (CannotSee(1))
    fac -= 50;

  // Weitere Mali?

  if (fac<100)
    ainfo[SI_SKILLDAMAGE] = ainfo[SI_SKILLDAMAGE]*fac/100;
  // Fertig
*/
}

// Ausfuehren Eines Angriffs auch wenn es bereits einen Angriff
// in dieser Runde gegeben hat. Dieser Angriff wird auch nicht
// gezaehlt. Die Nutzung dieser Funktion ist nur fuer Spezialfaelle
// gedacht und immer BALANCEPFLICHTIG!
varargs public void ExtraAttack(object enemy, int ignore_previous)
{
  int saved_no_more_attacks;

  // Erstschlagsinfo speichern.
  saved_no_more_attacks = no_more_attacks;

  // Bei Bedarf bisher schon durchgefuehrte Erstschlaege ignorieren
  if (ignore_previous) no_more_attacks=0;

  // Normalen Angriff durchfuehren
  Attack (enemy);

  // Gespeicherten Wert zuruecksetzen
  no_more_attacks = saved_no_more_attacks;

  return;
}

public void Attack(object enemy)
{
  closure cl;
  mixed   res;
  mapping ainfo;
  mapping edefendinfo; // erweiterte Defend-Infos
  mixed hookData;
  mixed hookRes;

  if ( no_more_attacks || QueryProp(P_GHOST) || 
      !objectp(enemy) || !objectp(this_object()) || 
      (QueryProp(P_DISABLE_ATTACK) > 0) || enemy->QueryProp(P_NO_ATTACK) || 
      (query_once_interactive(this_object()) && !interactive(this_object())) )
    return;

  edefendinfo=([]);

  Set(P_LAST_COMBAT_TIME,time());

  // inkrementieren. Diese Variable wird im HB nach den Angriffen genullt.
  // Diese Variable wird im naechsten Heartbeat von der Anzahl an verfuegbaren
  // Angriffen des Livings abgezogen. Dies beruecksichtigt also zwischen den
  // HBs (z.B. extern) gerufene Attacks().
  no_more_attacks++;

  // Wird das Attack durch einen temporaeren Attack-Hook ersetzt?
  if ( res=QueryProp(P_TMP_ATTACK_HOOK) )
  {
    if ( pointerp(res) && (sizeof(res)>=3) && intp(res[0]) && (time()<res[0])
        && objectp(res[1]) && stringp(res[2]) )
    {
      if ( !(res=call_other(res[1],res[2],enemy)) )
        return;
    }
    else
      SetProp(P_TMP_ATTACK_HOOK,0);
  }

  // trigger attack hook
  hookData=({enemy});
  hookRes=HookFlow(H_HOOK_ATTACK,hookData);
  if(hookRes && pointerp(hookRes) && sizeof(hookRes)>H_RETDATA){
    if(hookRes[H_RETCODE]==H_CANCELLED){
      return;
    }
  }

  ainfo = ([ SI_ENEMY : enemy,
             SI_SPELL : 0,
           ]);

  if ( objectp(ainfo[P_WEAPON]=QueryProp(P_WEAPON)) )
  {
    ainfo[P_WEAPON]->TakeFlaw(enemy);

    // Abfrage fuer den Fall, dass Waffe durch das TakeFlaw() zerstoert
    // wurde. Dann wird das Attack abgebrochen.
    if ( !objectp(ainfo[P_WEAPON]) )
      return;

    cl=symbol_function("name",ainfo[P_WEAPON]);
    ainfo[SI_SKILLDAMAGE_MSG] = (" mit "+funcall(cl,WEM,0));
    ainfo[SI_SKILLDAMAGE_MSG2] = (" mit "+funcall(cl,WEM,1));

    ainfo[SI_SKILLDAMAGE] = ainfo[P_WEAPON]->QueryDamage(enemy);

    cl=symbol_function("QueryProp",ainfo[P_WEAPON]);
    ainfo[SI_SKILLDAMAGE_TYPE] = funcall(cl,P_DAM_TYPE);
    ainfo[P_WEAPON_TYPE] = funcall(cl,P_WEAPON_TYPE);
    ainfo[P_NR_HANDS] = funcall(cl,P_NR_HANDS);
    ainfo[P_WC] = funcall(cl,P_WC);

    // Zweihaendige Waffe?
    if ( ainfo[P_NR_HANDS]==2
        && mappingp(res=UseSkill(SK_TWOHANDED,deep_copy(ainfo)))
        && member(res,SI_SKILLDAMAGE) )
    {
      // Nur den neuen Schadenswert uebernehmen.
      ainfo[SI_SKILLDAMAGE]=res[SI_SKILLDAMAGE];
    }
  }
  else // Keine Waffe gezueckt
  {
    /* Check if there is a magical attack */
    if ( mappingp(res=UseSkill(SK_MAGIC_ATTACK,([SI_ENEMY:enemy]))) )
    {
      ainfo[SI_SKILLDAMAGE]=res[SI_SKILLDAMAGE];
      ainfo[SI_SKILLDAMAGE_TYPE]=res[SI_SKILLDAMAGE_TYPE];

      if ( stringp(res[SI_SKILLDAMAGE_MSG]) )
        ainfo[SI_SKILLDAMAGE_MSG] = " mit "+res[SI_SKILLDAMAGE_MSG];
      else
        ainfo[SI_SKILLDAMAGE_MSG] = " mit magischen Faehigkeiten";

      if ( stringp(res[SI_SKILLDAMAGE_MSG2]) )
        ainfo[SI_SKILLDAMAGE_MSG2] = " mit "+res[SI_SKILLDAMAGE_MSG2];
      else
        ainfo[SI_SKILLDAMAGE_MSG2] = ainfo[SI_SKILLDAMAGE_MSG];

      if ( !(ainfo[P_WEAPON_TYPE]=res[P_WEAPON_TYPE]) )
        ainfo[P_WEAPON_TYPE]=WT_MAGIC;

      if ( member(res,SI_SPELL) )
        ainfo[SI_SPELL]=res[SI_SPELL];
    }
    else
    {
      /* Ohne (freie) Haende wird auch nicht angegriffen */
      if ( interactive(this_object())
          && (QueryProp(P_USED_HANDS) >= QueryProp(P_MAX_HANDS)) )
        return ;

      if ( !pointerp(res=QueryProp(P_HANDS)) || (sizeof(res)<2) )
        return;

      ainfo[SI_SKILLDAMAGE] = (( 2*random(res[1]+1)
                              + 10*(QueryAttribute(A_STR)) )/3);
      ainfo[SI_SKILLDAMAGE_TYPE] = res[2];
      ainfo[SI_SKILLDAMAGE_MSG] = ainfo[SI_SKILLDAMAGE_MSG2]
                                = res[0];
      ainfo[P_WEAPON_TYPE] = WT_HANDS;
      ainfo[P_WC] = res[1];
    }
  }  // besondere Faehigkeiten mit diesem Waffentyp?
  if ( mappingp(res=UseSkill(FIGHT(ainfo[P_WEAPON_TYPE]),
                             deep_copy(ainfo))) )
    SkillResTransfer(res,ainfo);

  // besondere allgemeine Kampffaehigkeiten?
  if ( mappingp(res=UseSkill(SK_FIGHT,deep_copy(ainfo))) )
    SkillResTransfer(res,ainfo);

  // Veraenderungen durch einen Attack-Modifier?
  if ( (res=QueryProp(P_TMP_ATTACK_MOD)) )
  {
    if ( pointerp(res) && (sizeof(res)>=3) && intp(res[0])
        && (time()<res[0]) && objectp(res[1]) && stringp(res[2]) )
    {
      if ( !(res=call_other(res[1],res[2],deep_copy(ainfo)))
          || !mappingp(res) )
        return;
      else
        SkillResTransfer(res,ainfo);
    }
    else
      SetProp(P_TMP_ATTACK_MOD,0);
  }

  // trigger attack mod hook
  hookData=deep_copy(ainfo);
  hookRes=HookFlow(H_HOOK_ATTACK_MOD,hookData);
  if(hookRes && pointerp(hookRes) && sizeof(hookRes)>H_RETDATA){
    if(hookRes[H_RETCODE]==H_CANCELLED){
      return;
    }
    else if(hookRes[H_RETCODE]==H_ALTERED && hookRes[H_RETDATA] &&
             mappingp(hookRes[H_RETDATA])){
        SkillResTransfer(hookRes[H_RETDATA],ainfo);
    }
  }

  // Interne Modifikationen der Angriffswerte
  InternalModifyAttack(ainfo);

  if ( !objectp(enemy) )
    return;

  // hier mal bewusst nicht auf P_PLURAL zuerst testen. in 90% der Faelle
  // wird eh keine Angriffsmeldung mehr ausgegeben, also pruefen wir das
  // lieber zuerst. Plural testen zieht schon genug Rechenzeit :/
  // Nicht meine Idee! Nicht meine Idee! Nachtwind 7.7.2001
  if ( ainfo[SI_SKILLDAMAGE_MSG2]!=last_attack_msg )
  {
    last_attack_msg = ainfo[SI_SKILLDAMAGE_MSG2];
    if (QueryProp(P_PLURAL))
    {
      tell_object( ME, "  Ihr greift " + enemy->name(WEN,1)
                   + ainfo[SI_SKILLDAMAGE_MSG2] + " an.\n" );
      say("  "+(Name(WER,1))+" greifen "+(enemy->name(WEN,1))+
          ainfo[SI_SKILLDAMAGE_MSG]+" an.\n", enemy );
      tell_object( enemy, "  "+(Name(WER,1))+" greifen "+
                  (enemy->QueryProp(P_PLURAL)?"Euch":"Dich")+
                   ainfo[SI_SKILLDAMAGE_MSG2]+" an.\n" );
    }
    else
    {
      tell_object( ME, "  Du greifst " + enemy->name(WEN,1)
                   + ainfo[SI_SKILLDAMAGE_MSG2] + " an.\n" );
      say("  "+(Name(WER,2))+" greift "+(enemy->name(WEN,1))+
          ainfo[SI_SKILLDAMAGE_MSG]+" an.\n", enemy );
      tell_object( enemy, "  "+(Name(WER,1))+" greift "+
                  (enemy->QueryProp(P_PLURAL)?"Euch":"Dich")+
                   ainfo[SI_SKILLDAMAGE_MSG2]+" an.\n" );    }
  }
  else if ( Query(P_SHOW_ATTACK_MSG) )
    if (QueryProp(P_PLURAL))
      tell_object( ME, "  Ihr greift " + enemy->name(WEN,1)
                   + ainfo[SI_SKILLDAMAGE_MSG2] + " an.\n" );
    else
      tell_object( ME, "  Du greifst " + enemy->name(WEN,1)
                   + ainfo[SI_SKILLDAMAGE_MSG2] + " an.\n" );

  // ainfo in defendinfo merken
  edefendinfo[ ORIGINAL_AINFO]= deep_copy(ainfo);
  edefendinfo[ ORIGINAL_DAM]= ainfo[SI_SKILLDAMAGE];
  edefendinfo[ ORIGINAL_DAMTYPE]= ainfo[SI_SKILLDAMAGE_TYPE];
  edefendinfo[ CURRENT_DAM]= ainfo[SI_SKILLDAMAGE];
  edefendinfo[ CURRENT_DAMTYPE]= ainfo[SI_SKILLDAMAGE_TYPE];

  // ainfo[SI_SPELL] auf ein mapping normieren
  if ( intp(ainfo[SI_SPELL]) )
  {
    ainfo[SI_SPELL] = ([ SP_PHYSICAL_ATTACK : !ainfo[SI_SPELL],
               SP_SHOW_DAMAGE     : !ainfo[SI_SPELL],
               SP_REDUCE_ARMOUR   : ([ AT_DEFAULT_REDUCE: 100 ])  ]);
  }

  // defendinfo anhaengen, falls ainfo[SI_SPELL] ein mapping ist
  if( mappingp(ainfo[SI_SPELL]))
  {
    ainfo[SI_SPELL][EINFO_DEFEND]=edefendinfo;
  }


  enemy->Defend(ainfo[SI_SKILLDAMAGE], ainfo[SI_SKILLDAMAGE_TYPE],
                ainfo[SI_SPELL],       this_object());


  //edefendinfo=([]);

  /* Done attacking */
}

public void AddDefender(object friend)
{
  if(!objectp(friend))
    return;

  object* defs = QueryProp(P_DEFENDERS) || ({});
  defs -= ({0});

  if(friend in defs)
    return;

  defs += ({friend});
  SetProp(P_DEFENDERS, defs);
}

public void RemoveDefender(object friend)
{
  if ( !objectp(friend) )
    return;

  object* defs = QueryProp(P_DEFENDERS);
  defs -= ({0});

  if(!(friend in defs))
    return;

  defs -= ({friend});
  SetProp(P_DEFENDERS, defs);
}

public object* QueryDefenders()
{
  return filter(QueryProp(P_DEFENDERS), #'objectp);
}

public object* QueryPresentDefenders(object* defenders =
    QueryProp(P_DEFENDERS) || ({}))
{
  // Alles selbst pruefen, um Durchlaeufe zu sparen.
  return filter(defenders,
    function int(object o)
    {
      return (objectp(o) && 
        (environment(o) == environment(ME) || environment(o) == ME));
    });
}

public object* QueryNearDefenders(object* defenders =
    QueryProp(P_DEFENDERS) || ({}))
{
  // alles selbst pruefen, um Durchlaeufe zu sparen.
  return filter(defenders,
    function int(object o)
    {
      // Nahe sind: Objekte im eigenen Inventar oder Objekt im Environment,
      // welche in Teamreihe 1 oder 0 (haben einfach keine Teamreihe) sind.
      return (objectp(o) &&
        ( environment(o) == ME ||
          (environment(o) == environment(ME) && o->PresentPosition() <= 1) )
        );
    }
    );
}

public void InformDefend(object enemy)
{
  UseSkill(SK_INFORM_DEFEND,([ SI_ENEMY  : enemy,
                               SI_FRIEND : previous_object() ]));
  // Oh, oh - ich hoffe mal, dass InformDefend wirklich NUR aus Defend
  // eines befreundeten livings aufgerufen wird... (Silvana)
  // This is only experimental... ;)
}

public <int|string*|mapping>* DefendOther(int dam, string|string* dam_type,
                                          int|mapping spell, object enemy)
{
  <int|string*|mapping>* res;

  if ( (res=UseSkill(SK_DEFEND_OTHER,([ SI_SKILLDAMAGE : dam,
                                        SI_SKILLDAMAGE_TYPE : dam_type,
                                        SI_SPELL : spell,
                                        SI_FRIEND : previous_object(),
                                        SI_ENEMY : enemy ])))
      && pointerp(res) )
    return res;

  return 0;
}

public void CheckWimpyAndFlee()
{
  if ( (QueryProp(P_WIMPY)>QueryProp(P_HP)) && !TeamFlee()
      && find_call_out("Flee")<0 )
    call_out(#'Flee,0,environment());
}

protected string mess(string msg,object me,object enemy)
{ closure mname, ename;
  string  *parts;
  int     i;

  mname = symbol_function("name", me);
  ename = symbol_function("name", enemy);

  parts=regexplode(msg,"@WE[A-Z]*[12]");
  for ( i=sizeof(parts)-2 ; i>=1 ; i-=2 )
  {
    switch(parts[i])
    {
      case "@WER1":    parts[i]=funcall(mname,WER,1);    break;
      case "@WESSEN1": parts[i]=funcall(mname,WESSEN,1); break;
      case "@WEM1":    parts[i]=funcall(mname,WEM,1);    break;
      case "@WEN1":    parts[i]=funcall(mname,WEN,1);    break;
      case "@WER2":    parts[i]=funcall(ename,WER,1);    break;
      case "@WESSEN2": parts[i]=funcall(ename,WESSEN,1); break;
      case "@WEM2":    parts[i]=funcall(ename,WEM,1);    break;
      case "@WEN2":    parts[i]=funcall(ename,WEN,1);    break;
      default: ;
    }
  }

  return break_string(capitalize(implode(parts,"")),78,"  ",1);
}

// Fuer evtl. Defend-Aenderungen, ohne dass man gleich das ganze
// Attack ueberlagern muss:
protected void InternalModifyDefend(int dam, string* dt, mapping spell, object enemy)
{
  return;
}

protected nomask void normalize_defend_args(int dam, string|string* dam_type,
                                            int|mapping spell, object enemy)
{
  // this_player(), wenn kein enemy bekannt...
  enemy ||= this_player();

  // Schadenstyp ueberpruefen
  if ( !pointerp(dam_type) )
    dam_type = ({ dam_type });

  // Und das Spellmapping pruefen, erzeugen, ergaenzen etc.
  if ( intp(spell) )
    spell = ([ SP_PHYSICAL_ATTACK : !spell,
               SP_SHOW_DAMAGE     : !spell,
               SP_REDUCE_ARMOUR   : ([ AT_DEFAULT_REDUCE: 100 ]),
               EINFO_DEFEND       : ([ORIGINAL_DAM:dam,
                                      ORIGINAL_DAMTYPE:dam_type ])
             ]);
  else if ( mappingp(spell) )
  {
    // testen ob eine erweiterte defendinfo vorhanden ist
    if(!member(spell,EINFO_DEFEND))
    {
      // wenn nicht, koennen wir an den fehlenden Infos wenig machen, aber
      // zumindest ergaenzen wir es und schreiben die (hier) initialen dam und
      // dam_type rein.
      spell[EINFO_DEFEND] = ([ORIGINAL_DAM:dam,
                              ORIGINAL_DAMTYPE:dam_type]);
    }
    // SP_REDUCE_ARMOUR muss auch mit zumindest dem Defaultwert
    // AT_DEFAULT_REDUCE vorhanden sein.
    if ( !mappingp(spell[SP_REDUCE_ARMOUR]) )
      spell[SP_REDUCE_ARMOUR] = ([AT_DEFAULT_REDUCE: 100]);
    else if (!(AT_DEFAULT_REDUCE in spell[SP_REDUCE_ARMOUR])
             || !intp(spell[SP_REDUCE_ARMOUR][AT_DEFAULT_REDUCE]) )
    {
      spell[SP_REDUCE_ARMOUR][AT_DEFAULT_REDUCE] = 100;
    }
  }
  else // Illegaler spell-Parameter
    raise_error(sprintf("Ungueltiger Typ des spell-Arguments: %d\n",
                        get_type_info(spell,0)));
}

public int Defend(int dam, string|string* dam_type, int|mapping spell, object enemy)
{
  mixed   res,res2;
  object  *armours,tmp;
  mixed hookData;
  mixed hookRes;
  int i;

  //  string  what, how;
  string enname, myname;

  normalize_defend_args(&dam, &dam_type, &spell, &enemy);

  // Testen, ob dieses Lebewesen ueberhaupt angegriffen werden darf
  if ( !this_object() || !enemy || QueryProp(P_NO_ATTACK)
      || ( query_once_interactive(enemy) && ! interactive(enemy) ) )
    return 0;

  spell[EINFO_DEFEND][CURRENT_DAMTYPE]=dam_type;
  spell[EINFO_DEFEND][CURRENT_DAM]=dam;

  // Testen, ob der Angreifer schon als Feind registriert worden ist.
  // Wenn nein, registrieren.
  if ( !IsEnemy(enemy) && !spell[SP_NO_ENEMY] )
  {
    spell[EINFO_DEFEND][ENEMY_INSERTED]=1;
    InsertEnemy(enemy);
  }

  // RFR-Taktik abfangen
  if ( !QueryProp(P_ENABLE_IN_ATTACK_OUT) )
  {
    i=time()-(enemy->QueryProp(P_LAST_MOVE));
    // Gegner hat sich bewegt, man selbst nicht
    if ( (i<3) && (time()-QueryProp(P_LAST_MOVE)>=5) )
    {
      // Bei Erster Kampfrunde wenige Schaden
      dam/=(4-i);
      spell[EINFO_DEFEND][RFR_REDUCE]=dam;
      spell[EINFO_DEFEND][CURRENT_DAM]=dam;
    }
  }

  // Man kann Verteidiger haben. Diese kommen als erste zum Zuge, falls sie
  // anwesend sind.
  object* defs_here = QueryPresentDefenders();
  if (sizeof(defs_here))
  {
    // Die werden erstmal alle informiert.
    defs_here->InformDefend(enemy);
    // Leider koennten dabei Objekte zerstoert worden sein. *seufz*
    defs_here -= ({0});

    // Anwesende Verteidiger eintragen.
    spell[EINFO_DEFEND][PRESENT_DEFENDERS] = defs_here;

    // Bei physischen Angriffen koennen nur Verteidiger aus Reihe 1 helfen
    // (z.B. fuer Rueckendeckung der Kaempfer)
    if(spell[SP_PHYSICAL_ATTACK])
    {
      defs_here = QueryNearDefenders(defs_here);
    }
 
    if(sizeof(defs_here))
    {
      // Wenn in Frage kommende Verteidiger anwesend sind, einen davon
      // auswaehlen...
      <object|int|string*|mapping>* edefendtmp = ({defs_here[random(sizeof(defs_here))], 0, 0, 0}); 
      // ... und DefendOther() darin rufen. Das wirkt wie ein Defend-Hook-Light
      res = call_other(edefendtmp[DEF_DEFENDER], "DefendOther",
                       dam, dam_type, spell, enemy);
      // Wenn das Defender valide Daten geliefert hat und den Schaden oder
      // Schadenstyp geaendert hat (z.B. Umwandlung von Feuer nach Eis),
      // werden die neuen Daten uebernommen.
      if(pointerp(res) && (sizeof(res)>=3) && intp(res[0])
          && pointerp(res[1]))
      {
        dam = res[0];
        edefendtmp[DEF_DAM] = dam;
        dam_type = res[1];
        edefendtmp[DEF_DAMTYPE] = dam_type;
        if(mappingp(res[2]))
        {
          spell = res[2];
          // teuer, aber geht nicht anders (Rekursion vermeiden)
          edefendtmp[DEF_SPELL] = deep_copy(res[2]);
        }
        // Die Werte sind jetzt auch die aktuell wirksamen Werte.
        spell[EINFO_DEFEND][CURRENT_DAMTYPE] = dam_type;
        spell[EINFO_DEFEND][CURRENT_DAM] = dam;
      }
      spell[EINFO_DEFEND][DEFENDING_DEFENDER] = edefendtmp;
    }
  } // Ende Defender-Verarbeitung


  // Ueber einen P_TMP_DEFEND_HOOK werden z.B. Schutzzauber gehandhabt
  spell[EINFO_DEFEND][DEFEND_HOOK]=DI_NOHOOK;
  if ( res=QueryProp(P_TMP_DEFEND_HOOK) )
  {
    if ( pointerp(res) && (sizeof(res)>=3) && intp(res[0]) && (time()<res[0])
        && objectp(res[1]) && stringp(res[2]) )
    {
      if ( !(res=call_other(res[1],res[2],dam,dam_type,spell,enemy)) )
      {
        // Ein P_TMP_DEFEND_HOOK kann den Schaden vollstaendig abfangen,
        // das Defend wird dann hier abgebrochen *SICK* und es wird nur
        // noch getestet, ob man in die Flucht geschlagen wurde
        spell[EINFO_DEFEND][DEFEND_HOOK]=DI_HOOKINTERRUPT;
        CheckWimpyAndFlee();
        return 0;
      }
      else
      {
        spell[EINFO_DEFEND][DEFEND_HOOK]=DI_HOOK;
        if ( pointerp(res) && (sizeof(res)>=3)
            && intp(res[0] && pointerp(res[1])) )
        {
          mixed edefendtmp=({0,0,0});
          // Der P_TMP_DEFEND_HOOK kann ebenfalls Schadenshoehe und
          // -art sowie die Spell-Infos veraendern
          dam=res[0];
          edefendtmp[HOOK_DAM]=dam;
          dam_type=res[1];
          edefendtmp[HOOK_DAMTYPE]=dam_type;

          if ( mappingp(res[2]) )
          {
            spell=res[2];
            // Waeh. Teuer. Aber geht nicht anders.
            edefendtmp[HOOK_SPELL]=deep_copy(spell);
          }
          spell[EINFO_DEFEND][DEFEND_HOOK]=edefendtmp;
          spell[EINFO_DEFEND][CURRENT_DAMTYPE]=dam_type;
          spell[EINFO_DEFEND][CURRENT_DAM]=dam;
        }
      }
    }
    else
      SetProp(P_TMP_DEFEND_HOOK,0);
  } // P_TMP_DEFEND_HOOK

  // trigger defend hook
  hookData=({dam,dam_type,spell,enemy});
  hookRes=HookFlow(H_HOOK_DEFEND,hookData);
  if(hookRes && pointerp(hookRes) && sizeof(hookRes)>H_RETDATA){
    if(hookRes[H_RETCODE]==H_CANCELLED){
        spell[EINFO_DEFEND][DEFEND_HOOK]=DI_HOOKINTERRUPT;
        CheckWimpyAndFlee();
        return 0;
    }
    else if(hookRes[H_RETCODE]==H_ALTERED && hookRes[H_RETDATA]){
        spell[EINFO_DEFEND][DEFEND_HOOK]=DI_HOOK;
        if ( pointerp(hookRes[H_RETDATA]) && (sizeof(hookRes[H_RETDATA])>=3)
            && intp(hookRes[H_RETDATA][0] && pointerp(hookRes[H_RETDATA][1])) )
        {
          mixed edefendtmp=({0,0,0});
          // Der P_TMP_DEFEND_HOOK kann ebenfalls Schadenshoehe und
          // -art sowie die Spell-Infos veraendern
          dam=hookRes[H_RETDATA][0];
          edefendtmp[HOOK_DAM]=dam;
          dam_type=hookRes[H_RETDATA][1];
          edefendtmp[HOOK_DAMTYPE]=dam_type;

          if ( mappingp(hookRes[H_RETDATA][2]) )
          {
            spell=hookRes[H_RETDATA][2];
            // Teuer, teuer... :-(
            edefendtmp[HOOK_SPELL]=deep_copy(spell);
          }
          spell[EINFO_DEFEND][DEFEND_HOOK]=edefendtmp;
          spell[EINFO_DEFEND][CURRENT_DAMTYPE]=dam_type;
          spell[EINFO_DEFEND][CURRENT_DAM]=dam;
        }
    }
  } // Ende Hook-Behandlung

  // Es gibt auch Parierwaffen,
  if ( objectp(tmp=QueryProp(P_PARRY_WEAPON)) )
  {
    int schutz=tmp->QueryDefend(dam_type, spell, enemy);
    // Reduzierbare Wirksamkeit der Parierwaffe?
    int gewicht;
    if ( (P_PARRY_WEAPON in spell[SP_REDUCE_ARMOUR])
        && intp(gewicht=spell[SP_REDUCE_ARMOUR][P_PARRY_WEAPON])
        && (gewicht>=0) )
    {
      schutz=(schutz*gewicht)/100;
    }
    else
      schutz=(schutz*spell[SP_REDUCE_ARMOUR][AT_DEFAULT_REDUCE])/100;

    dam-=schutz;
    spell[EINFO_DEFEND][CURRENT_DAM]=dam;
  }

  // Jetzt kommen die Ruestungen des Lebewesens ins Spiel (wenn es denn
  // welche traegt)

  armours=QueryProp(P_ARMOURS)-({0});
  if ( (i=sizeof(armours))>0 ) { 
    string aty;

    tmp=armours[random(i)];

    if ( objectp(tmp) )
      //Uebergabe des Mappings eh als Pointer/Referenz, daher billig
      tmp->TakeFlaw(dam_type,spell[EINFO_DEFEND]);

    // pro Ruestung ein Key an Platz reservieren
    spell[EINFO_DEFEND][DEFEND_ARMOURS]=m_allocate(i,2);
    foreach(object armour : armours) {
      if ( objectp(armour) )
      {
        aty=armour->QueryProp(P_ARMOUR_TYPE);
        int schutz=armour->QueryDefend(dam_type, spell, enemy);
        int gewicht;
        if ( (aty in spell[SP_REDUCE_ARMOUR])
            && intp(gewicht=spell[SP_REDUCE_ARMOUR][aty]) && (gewicht>=0) )
          dam -= (gewicht*schutz)/100;
        else
          dam -= (schutz*spell[SP_REDUCE_ARMOUR][AT_DEFAULT_REDUCE])/100;
        // Schaden NACH DefendFunc vermerken. 
        // Schutzwirkung VOR DefendFunc (DEF_ARMOUR_PROT) vermerkt
        // das QueryDefend() selber.
        spell[EINFO_DEFEND][DEFEND_ARMOURS][armour,DEF_ARMOUR_DAM]=dam;
        // akt. Schaden vermerken und Schutz der aktuellen Ruestung (vor
        // DefendFunc) wieder auf 0 setzen fuer den naechsten Durchlauf.
        spell[EINFO_DEFEND][CURRENT_DAM]=dam;
        spell[EINFO_DEFEND][DEFEND_CUR_ARMOUR_PROT]=0;
      }
    }
  }

  // Manche Gilden haben einen Verteidigungsskill. Der kommt jetzt zum
  // tragen. Der Skill kann die Schadenshoehe und -art beeinflussen.
  spell[EINFO_DEFEND]+=([DEFEND_GUILD:({})]);
  if ( mappingp(res=UseSkill(SK_MAGIC_DEFENSE,
                            ([ SI_ENEMY            : enemy,
                               SI_SKILLDAMAGE      : dam,
                               SI_SKILLDAMAGE_TYPE : dam_type,
                               SI_SPELL            : spell     ]))) )
  {
    dam=res[SI_SKILLDAMAGE];

    if ( pointerp(res[SI_SKILLDAMAGE_TYPE]) )
        dam_type=res[SI_SKILLDAMAGE_TYPE];

    spell[EINFO_DEFEND][CURRENT_DAMTYPE]=dam_type;
    spell[EINFO_DEFEND][CURRENT_DAM]=dam;
    spell[EINFO_DEFEND][DEFEND_GUILD]=({dam,dam_type});
  }

  // Evtl. interne Modifikationen
  InternalModifyDefend(&dam, &dam_type, &spell, &enemy);

  spell[EINFO_DEFEND][CURRENT_DAMTYPE]=dam_type;
  spell[EINFO_DEFEND][CURRENT_DAM]=dam;

  // Testen, ob irgendwas im Inventory des Lebewesen auf den Angriff
  // "reagiert"
  CheckSensitiveAttack(dam,dam_type,spell,enemy);

  if ( !objectp(enemy) )
    return 0;

  // Angriffszeit im Gegner setzen
  enemy->SetProp(P_LAST_COMBAT_TIME,time());

  // Die Resistenzen des Lebewesens (natuerliche und durch Ruestungen
  // gesetzte) beruecksichtigen
  dam = to_int(CheckResistance(dam_type)*dam);
  spell[EINFO_DEFEND][DEFEND_RESI]=dam;

  spell[EINFO_DEFEND][CURRENT_DAM]=dam;

  // Bei physikalischen Angriffen wird die natuerliche Panzerung und die
  // Geschicklichkeit des Lebewesens beruecksichtigt
  object stat = find_object("/d/erzmagier/zesstra/pacstat"); // TODO: remove
  if ( spell[SP_PHYSICAL_ATTACK] )
  {
    // Schutz bestimmen, Minimum 1, aber nur wenn P_BODY > 0
    // Um Rundungsverluste zu reduzieren, wird P_BODY anfangs mit 10000
    // skaliert. Beim runterskalieren wird aufgerundet (Addition von
    // 5000 vor Division).
    int body = (QueryProp(P_BODY)+QueryAttribute(A_DEX)) * 10000;
    int schutz = ((body/4 + random(body*3/4 + 1) + 5000)/10000) || 1;
    if (stat)
      stat->bodystat(body, schutz, (random(body)+1)/10000);

    // Reduzierbare Wirksamkeit des Bodies?
    int gewicht;
    if ( (P_BODY in spell[SP_REDUCE_ARMOUR])
        && intp(gewicht=spell[SP_REDUCE_ARMOUR][P_BODY]) && (gewicht>=0) )
      schutz=(schutz*gewicht)/100;
    else
      schutz=(schutz*spell[SP_REDUCE_ARMOUR][AT_DEFAULT_REDUCE])/100;

    dam-=schutz;
  }
  spell[EINFO_DEFEND][DEFEND_BODY]=dam;
  spell[EINFO_DEFEND][CURRENT_DAM]=dam;

  // Ist ueberhaupt noch etwas vom Schaden uebrig geblieben?
  if ( dam<0 )
    dam = 0;
  spell[EINFO_DEFEND][CURRENT_DAM]=dam;

  // fuer die Statistik
  // TODO: entfernen nach Test-Uptime
  if (stat)
    stat->damagestat(spell[EINFO_DEFEND]);

  // Die Anzahl der abzuziehenden Lebenspunkte ist der durch 10 geteilte
  // Schadenswert
  dam = dam / 10;
  spell[EINFO_DEFEND][DEFEND_LOSTLP]=dam;

  // evtl. hat entweder der Aufrufer oder das Lebewesen selber eigene
  // Schadensmeldungen definiert. Die vom Aufrufer haben Prioritaet.
  mixed dam_msg = spell[SP_SHOW_DAMAGE];
  // Wenn != 0 (d.h. Treffermeldungen grundsaetzlich erwuenscht), aber kein
  // Array, hier im Living fragen.
  if (dam_msg && !pointerp(dam_msg))
    dam_msg = QueryProp(P_DAMAGE_MSG);

  // In den meisten Faellen soll auch eine Schadensmeldung ausgegeben
  // werden, die die Hoehe des Schadens (grob) anzeigt
  if (spell[SP_SHOW_DAMAGE] && !pointerp(dam_msg)) {
    myname=name(WEN);
    enname=enemy->Name(WER);
    if (enemy->QueryProp(P_PLURAL)) {
      switch (dam) {
      case 0:
        tell_object(enemy,sprintf("  Ihr verfehlt %s.\n",myname));
        tell_object(this_object(),sprintf("  %s verfehlen Dich.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
           sprintf("  %s verfehlen %s.\n",enname,myname),
                  ({ enemy, this_object() }));
        break;
      case 1:
        tell_object(enemy,sprintf("  Ihr kitzelt %s am Bauch.\n",myname));
        tell_object(this_object(),
          sprintf("  %s kitzeln Dich am Bauch.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s kitzeln %s am Bauch.\n",enname,myname),
                  ({ enemy, this_object() }));
        break;
      case 2..3:
        tell_object(enemy,sprintf("  Ihr kratzt %s.\n",myname));
        tell_object(this_object(),sprintf("  %s kratzen Dich.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s kratzen %s.\n",enname,myname),
                  ({ enemy, this_object() }));
        break;
      case 4..5:
        tell_object(enemy,sprintf("  Ihr trefft %s.\n",myname));
        tell_object(this_object(),sprintf("  %s treffen Dich.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s treffen %s.\n",enname,myname),
                  ({ enemy, this_object() }));
        break;
      case 6..10:
        tell_object(enemy,sprintf("  Ihr trefft %s hart.\n",myname));
        tell_object(this_object(),sprintf("  %s treffen Dich hart.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s treffen %s hart.\n",enname,myname),
                  ({ enemy, this_object() }));
        break;
      case 11..20:
        tell_object(enemy,sprintf("  Ihr trefft %s sehr hart.\n",myname));
        tell_object(this_object(),
          sprintf("  %s treffen Dich sehr hart.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s treffen %s sehr hart.\n",enname,myname),
                  ({ enemy, this_object() }));
        break;
      case 21..30:
        tell_object(enemy,
          sprintf("  Ihr schlagt %s mit dem Krachen brechender Knochen.\n",
                  myname));
        tell_object(this_object(),
          sprintf("  %s schlagen Dich mit dem Krachen brechender Knochen.\n",
                  enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s schlagen %s mit dem Krachen brechender Knochen.\n",
                  enname,myname), ({ enemy, this_object() }));
        break;
      case 31..50:
        tell_object(enemy,
          sprintf("  Ihr zerschmettert %s in kleine Stueckchen.\n",myname));
        tell_object(this_object(),
          sprintf("  %s zerschmettern Dich in kleine Stueckchen.\n",
                                          enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s zerschmettern %s in kleine Stueckchen.\n",
                  enname,myname), ({ enemy, this_object() }));
        break;
      case 51..75:
        tell_object(enemy,sprintf("  Ihr schlagt %s zu Brei.\n",myname));
        tell_object(this_object(),
          sprintf("  %s schlagen Dich zu Brei.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s schlagen %s zu Brei.\n",enname,myname),
                  ({ enemy, this_object() }));
        break;
      case 76..100:
        tell_object(enemy,sprintf("  Ihr pulverisiert %s.\n",myname));
        tell_object(this_object(),sprintf("  %s pulverisieren Dich.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s pulverisieren %s.\n",enname,myname),
                  ({ enemy, this_object() }));
        break;
      case 101..150:
        tell_object(enemy,sprintf("  Ihr zerstaeubt %s.\n",myname));
        tell_object(this_object(),sprintf("  %s zerstaeuben Dich.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s zerstaeuben %s.\n",enname,myname),
                  ({ enemy, this_object() }));
        break;
      case 151..200:
        tell_object(enemy,sprintf("  Ihr atomisiert %s.\n",myname));
        tell_object(this_object(),sprintf("  %s atomisieren Dich.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s atomisieren %s.\n",enname,myname),
                  ({ enemy, this_object() }));
        break;
      default:
        tell_object(enemy,sprintf("  Ihr vernichtet %s.\n",myname));
        tell_object(this_object(),sprintf("  %s vernichten Dich.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s vernichten %s.\n",enname,myname),
                  ({ enemy, this_object() }));
        break;
      }

    }
    else {
      switch (dam) {
      case 0:
        tell_object(enemy,sprintf("  Du verfehlst %s.\n",myname));
        tell_object(this_object(),sprintf("  %s verfehlt Dich.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s verfehlt %s.\n",enname,myname),
                  ({ enemy, this_object() }));
        break;
      case 1:
        tell_object(enemy,sprintf("  Du kitzelst %s am Bauch.\n",myname));
        tell_object(this_object(),
          sprintf("  %s kitzelt Dich am Bauch.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s kitzelt %s am Bauch.\n",enname,myname),
                  ({ enemy, this_object() }));
        break;
      case 2..3:
        tell_object(enemy,sprintf("  Du kratzt %s.\n",myname));
        tell_object(this_object(),sprintf("  %s kratzt Dich.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s kratzt %s.\n",enname,myname),
                  ({ enemy, this_object() }));
        break;
      case 4..5:
        tell_object(enemy,sprintf("  Du triffst %s.\n",myname));
        tell_object(this_object(),sprintf("  %s trifft Dich.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s trifft %s.\n",enname,myname),
                  ({ enemy, this_object() }));
        break;
      case 6..10:
        tell_object(enemy,sprintf("  Du triffst %s hart.\n",myname));
        tell_object(this_object(),sprintf("  %s trifft Dich hart.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s trifft %s hart.\n",enname,myname),
            ({ enemy, this_object() }));
        break;
      case 11..20:
        tell_object(enemy,sprintf("  Du triffst %s sehr hart.\n",myname));
        tell_object(this_object(),
          sprintf("  %s trifft Dich sehr hart.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s trifft %s sehr hart.\n",enname,myname),
                  ({ enemy, this_object() }));
        break;
      case 21..30:
        tell_object(enemy,
          sprintf("  Du schlaegst %s mit dem Krachen brechender Knochen.\n",
                  myname));
        tell_object(this_object(),
          sprintf("  %s schlaegt Dich mit dem Krachen brechender Knochen.\n",
                  enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s schlaegt %s mit dem Krachen brechender Knochen.\n",
                  enname,myname), ({ enemy, this_object() }));
        break;
      case 31..50:
        tell_object(enemy,
          sprintf("  Du zerschmetterst %s in kleine Stueckchen.\n",myname));
        tell_object(this_object(),
          sprintf("  %s zerschmettert Dich in kleine Stueckchen.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s zerschmettert %s in kleine Stueckchen.\n",
                  enname,myname), ({ enemy, this_object() }));
        break;
      case 51..75:
        tell_object(enemy,sprintf("  Du schlaegst %s zu Brei.\n",myname));
        tell_object(this_object(),
          sprintf("  %s schlaegt Dich zu Brei.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s schlaegt %s zu Brei.\n",enname,myname),
                  ({ enemy, this_object() }));
        break;
      case 76..100:
        tell_object(enemy,sprintf("  Du pulverisierst %s.\n",myname));
        tell_object(this_object(),sprintf("  %s pulverisiert Dich.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s pulverisiert %s.\n",enname,myname),
                  ({ enemy, this_object() }));
        break;
      case 101..150:
        tell_object(enemy,sprintf("  Du zerstaeubst %s.\n",myname));
        tell_object(this_object(),sprintf("  %s zerstaeubt Dich.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s zerstaeubt %s.\n",enname,myname),
                  ({ enemy, this_object() }));
        break;
      case 151..200:
        tell_object(enemy,sprintf("  Du atomisierst %s.\n",myname));
        tell_object(this_object(),sprintf("  %s atomisiert Dich.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s atomisiert %s.\n",enname,myname),
                  ({ enemy, this_object() }));
        break;
      default:
        tell_object(enemy,sprintf("  Du vernichtest %s.\n",myname));
        tell_object(this_object(),sprintf("  %s vernichtet Dich.\n",enname));
        tell_room(environment(enemy)||environment(this_object()),
          sprintf("  %s vernichtet %s.\n",enname,myname),
                  ({ enemy, this_object() }));
        break;
      }
    }
  }

  // Man kann auch selbst-definierte Schadensmeldungen ausgeben lassen
  else if( spell[SP_SHOW_DAMAGE] && pointerp(dam_msg) )
  {
    for( i=sizeof(dam_msg) ; --i >= 0 ; )
    {
      if ( dam>dam_msg[i][0] )
      {
        tell_object(ME,mess(dam_msg[i][1],ME,enemy));
        tell_object(enemy,mess(dam_msg[i][2],ME,enemy));
        say(mess(dam_msg[i][3],ME,enemy), enemy);
        break;
      }
    }
  }
  // else (!spell[SP_SHOW_DAMAGE]) keine Schadensmeldung.

  // Informationen ueber den letzten Angriff festhalten
  Set(P_LAST_DAMTYPES, dam_type);
  Set(P_LAST_DAMTIME,  time());
  Set(P_LAST_DAMAGE,   dam);

  // Bei Angriffen mit SP_NO_ENEMY-Flag kann man nicht sterben ...
  if ( spell[SP_NO_ENEMY] )
    reduce_hit_points(dam);
  // ... bei allen anderen natuerlich schon
  else
    do_damage(dam,enemy);

  // evtl. ist dies Objekt hier tot...
  if (!objectp(ME)) return dam;

  // Testen, ob man in die Fucht geschlagen wird
  CheckWimpyAndFlee();

  // Verursachten Schaden (in LP) zurueckgeben
  return dam;
}

public float CheckResistance(string *dam_type) {
    //funktion kriegt die schadensarten uebergeben, schaut sich dieses
    //sowie P_RESISTENCE_STRENGTH und P_RESITENCE_MODFIFIER an und berechnet
    //einen Faktor, mit dem die urspruengliche Schadensmenge multipliziert
    //wird, um den Schaden nach Beruecksichtigung der Resis/Anfaelligkeiten zu
    //erhalten. Rueckgabewert normalerweise (s.u.) >=0.
  mapping rstren, mod;
  float   faktor,n;
  int     i;

  mod = Query(P_RESISTANCE_MODIFIER);
  if ( mappingp(mod) )
    mod = mod["me"];

  if ( !mappingp(rstren=Query(P_RESISTANCE_STRENGTHS)) )
  {
    if (!mappingp(mod))
      return 1.0;
    else
      rstren = ([]);
  }

  if ( !mappingp(mod) )
    mod = ([]);

  if ( (i=sizeof(dam_type))<1 )
    return 1.0;

  n=to_float(i);
  faktor=0.0;

  //dies hier tut nicht mehr das gewuenschte, wenn in P_RESISTENCE_STRENGTHS
  //Faktoren <-1.0 angegeben werden. Rueckgabewerte <0 sind dann moeglich und
  //leider werden die Schadensarten ohne Resis nicht mehr richtig verwurstet. :-/
  foreach(string dt: dam_type) {
    faktor = faktor + (1.0 + to_float(rstren[dt]))
           * (1.0 + to_float(mod[dt]))-1.0;
  }
  return 1.0+(faktor/n);
}

public varargs mapping StopHuntingMode(int silent)
{ mapping save_enemy;

  save_enemy=enemies;
  if ( !silent )
    walk_mapping(enemies, #'StopHuntText); //#');

  enemies=m_allocate(0,1);
  last_attack_msg=0;

  return save_enemy;
}

public <object*|int*>* QueryEnemies()
{
  return ({m_indices(enemies),m_values(enemies)});
}

public mapping GetEnemies()
{
  return enemies;
}

public mapping SetEnemies(<object*|int*>* myenemies)
{
  enemies=mkmapping(myenemies[0],myenemies[1]);
  return enemies;
}

private string _kill_alias( string str )
{
    return "\\" + str;
}

public varargs void Flee( object oldenv, int force )
{ mixed   *exits, exit, dex;
  mapping tmp;
  int     i;
  object  env;

  if ( !environment() )
    return;

  // mit 'force' kann man die Checks umgehen, damit der Spieler auf jeden
  // Fall fluechtet ...
  if ( !force && ( oldenv && (oldenv != environment()) ||
                   query_once_interactive(ME) && (!EnemyPresent() ||
                   (QueryProp(P_HP) >= QueryProp(P_WIMPY))) ) )
    return;

  // ... aber Magier fluechten zu lassen ist nicht ganz so einfach ;-)
  if ( query_once_interactive(this_object()) && IS_LEARNING(this_object()) )
    return;

  // Geister brauchen nicht um ihr Leben zu fuerchten
  if ( QueryProp(P_GHOST) )
    return;

  tell_object( ME, "Die Angst ist staerker als Du ... "+
                   "Du willst nur noch weg hier.\n");

  if ( TeamFlee() ) // Erfolgreiche Flucht in hintere Kampfreihe?
    return;

  env = environment();
  tmp = environment()->QueryProp(P_EXITS);
  exits = m_indices(tmp);
  tmp = environment()->QueryProp(P_SPECIAL_EXITS);
  exits += m_indices(tmp);

  if ( query_once_interactive(ME) )
        exits = map( exits, #'_kill_alias/*'*/ );

  // die Fluchtrichtung von Magiern wird aus Sicherheitsgruenden
  // nicht ausgewertet
  if ( interactive(ME) && IS_SEER(ME) && !IS_LEARNER(ME)
      && (dex=QueryProp(P_WIMPY_DIRECTION)) )
  {
    i = 60 + 4 * (QueryProp(P_LEVEL) - 30) / 3;
    exits += ({dex}); // bevorzugte Fluchtrichtung mindestens einmal
  }

  if ( !sizeof(exits) )
  {
    tell_object( ME, "Du versuchst zu fliehen, schaffst es aber nicht.\n" );

    return;
  }

  while ( sizeof(exits) && (environment()==env) )
  {
    if ( dex                         // Vorzugsweise Fluchtrichtung?
        && (member(exits,dex) >= 0)  // moeglich?
        && (random(100) <= i))       // und Wahrscheinlichkeit gross genug?
      exit = dex;
    else
      exit = exits[random(sizeof(exits))];

    catch(command(exit);publish);
    exits -= ({exit});
  }

  if ( environment()==env )
    tell_object( ME, "Dein Fluchtversuch ist gescheitert.\n" );
}

public object EnemyPresent()
{
  foreach(object en: enemies) {
    if (environment()==environment(en))
      return en;
  }
  return 0;
}

public object InFight()
{
  return EnemyPresent();
}

public varargs int StopHuntID(string str, int silent) { 

  if ( !stringp(str) )
    return 0;

  int j;
  foreach(object en: enemies) {
    if (en->id(str)) {
      StopHuntFor(en,silent);
      j++;
    }
  }

  return j;
}

public int SpellDefend(object caster, mapping sinfo)
{ int    re;
  mixed  res;
  string *ind;

  re = UseSkill(SK_SPELL_DEFEND,([ SI_SKILLARG : sinfo ,
                                   SI_ENEMY    : caster ]) );

  if ( (res=QueryProp(P_MAGIC_RESISTANCE_OFFSET)) && mappingp(res)
      && pointerp(sinfo[SI_MAGIC_TYPE]))
  {
    ind = m_indices(res) & sinfo[SI_MAGIC_TYPE];

    if (pointerp(ind) && sizeof(ind) ) {
      foreach(string index : ind)
        re+=res[index];
    }
  }
  else if(res && intp(res))
    re+=res;

  if ( (re>3333) && query_once_interactive(this_object()) )
    re=3333; /* Maximal 33% Abwehrchance bei Spielern */
  return re;
}

// **** this is property-like

static int _set_attack_busy(mixed val)
{
  if ( ((to_int(val))>5) && previous_object(1)
      && query_once_interactive(previous_object(1)) )
    log_file("ATTACKBUSY",sprintf("%s %d Taeter: %O Opfer: %O\n",
             dtime(time()),to_int(val),previous_object(1),this_object()));

  attack_busy-=to_int(val*100.0);

  if ( attack_busy<-2000 )
    attack_busy=-2000;

  return attack_busy;
}

static int _query_attack_busy()
{
  if (IS_LEARNING(ME))
    return 0;

  return (attack_busy<100);
}

// **** local property methods
static int _set_wimpy(int i)
{
  if ( !intp(i) || (i>QueryProp(P_MAX_HP)) || (i<0) )
    return 0;

  // ggf. Statusreport ausgeben
  if (interactive(ME))
    status_report(DO_REPORT_WIMPY, i);

  return Set(P_WIMPY, i);
}

static string _set_wimpy_dir(string s) {
  // ggf. Statusreport ausgeben
  if (interactive(ME))
    status_report(DO_REPORT_WIMPY_DIR, s);
  return Set(P_WIMPY_DIRECTION, s, F_VALUE);
}

static mixed _set_hands(mixed h)
{ 
  if ( sizeof(h)==2 )
    h += ({ ({DT_BLUDGEON}) });
  if (!pointerp(h[2]))
    h[2] = ({h[2]});
  return Set(P_HANDS, h, F_VALUE);
}

//TODO normalisieren/korrigieren in updates_after_restore().
static mixed _query_hands()
{
  mixed *hands = Query(P_HANDS);
  if ( !hands )
    return Set(P_HANDS, ({ " mit blossen Haenden", 30, ({DT_BLUDGEON})}));
  else if ( sizeof(hands)<3 )
    return Set(P_HANDS, ({hands[0], hands[1], ({DT_BLUDGEON})}));
  else if ( !pointerp(hands[2]) )
    return Set(P_HANDS, ({hands[0], hands[1], ({ hands[2] })}));

  return Query(P_HANDS);
}

static int _query_total_wc()
{ mixed res;
  int   totwc;

  if ( objectp(res=QueryProp(P_WEAPON)) )
    totwc = res->QueryProp(P_WC);
  else if ( pointerp(res=QueryProp(P_HANDS)) && sizeof(res)>1
           && intp(res[1]) )
    totwc=res[1];
  else
    totwc=30;

  totwc = ((2*totwc)+(10*QueryAttribute(A_STR)))/3;

  return Set(P_TOTAL_WC, totwc, F_VALUE);
}

static int _query_total_ac() {

  int totac = 0;
  object *armours = QueryProp(P_ARMOURS);
  object parry = QueryProp(P_PARRY_WEAPON);

  if ( member(armours,0)>=0 ) {
    armours -= ({ 0 }); 
  }

  foreach(object armour: armours)
    totac += armour->QueryProp(P_AC);

  if ( objectp(parry) )
    totac += parry->QueryProp(P_AC);

  totac += (QueryProp(P_BODY)+QueryAttribute(A_DEX));

  return Set(P_TOTAL_AC, totac, F_VALUE);
}

static mapping _query_resistance_strengths() {

  UpdateResistanceStrengths();

  mapping rstren = copy(Query(P_RESISTANCE_STRENGTHS, F_VALUE));
  mapping mod = Query(P_RESISTANCE_MODIFIER, F_VALUE);

  if ( !mappingp(rstren) )
    rstren = ([]);

  if ( !mappingp(mod) || !mappingp(mod=mod["me"]) || !sizeof(mod) )
    return rstren;

  foreach(string modkey, float modvalue : mod)
    rstren[modkey] = ((1.0+rstren[modkey])*(1.0+modvalue))-1.0;

  return rstren;
}

static int _set_disable_attack(int val)
{
  if (val<-100000)
           {
                  log_file("PARALYSE_TOO_LOW",
                          sprintf("Wert zu klein: %s, Wert: %d, "
                                  "Aufrufer: %O, Opfer: %O",
                                  ctime(time()),
                                          val,previous_object(1),
                                          this_object()));
           }
  if ( val>30 )
    val=30;
  if ( (val>=20) && previous_object(1)!=ME && query_once_interactive(ME) )
    log_file("PARALYSE",sprintf("%s %d Taeter: %O Opfer: %O\n",
                                ctime(time())[4..15],
                                val,previous_object(1),this_object()));
 
  if (time()<QueryProp(P_NEXT_DISABLE_ATTACK))
  {
    // gueltige Zeitsperre existiert.
    // Erhoehen von P_DISABLE_ATTACK geht dann nicht. (Ja, auch nicht erhoehen
    // eines negativen P_DISABLE_ATTACK)
    if (val >= QueryProp(P_DISABLE_ATTACK))
      return DISABLE_TOO_EARLY;
    // val ist kleiner als aktuelles P_DISABLE_ATTACK - das ist erlaubt, ABER es
    // darf die bestehende Zeitsperre nicht verringern, daher wird sie nicht
    // geaendert.
    return Set(P_DISABLE_ATTACK,val,F_VALUE);
  }
  // es existiert keine gueltige Zeitsperre - dann wird sie nun gesetzt.
  // (Sollte val < 0 sein, wird eine Zeitsperre in der Vergangenheit gesetzt,
  // die schon abgelaufen ist. Das ist ueberfluessig, schadet aber auch
  // nicht.)
  SetProp(P_NEXT_DISABLE_ATTACK,time()+val*2*__HEART_BEAT_INTERVAL__);
  return Set(P_DISABLE_ATTACK,val);
}

// Neue Verwaltung der Haende:

// P_HANDS_USED_BY enhaelt ein Array mit allen Objekten, die Haende
// belegen, jedes kommt so oft vor wie Haende belegt werden.

static mixed *_query_hands_used_by()
{
  return ((Query(P_HANDS_USED_BY, F_VALUE) || ({}) ) - ({0}));
}

static int _query_used_hands()
{
  return sizeof(QueryProp(P_HANDS_USED_BY));
}

static int _query_free_hands()
{
  return (QueryProp(P_MAX_HANDS)-QueryProp(P_USED_HANDS));
}

public varargs int UseHands(object ob, int num)
{ mixed *h;

  if ( !ob && !(ob=previous_object(1)) )
    return 0;

  if ( (num<=0) && ((num=ob->QueryProp(P_HANDS))<=0) )
    return 0;

  h=QueryProp(P_HANDS_USED_BY)-({ob});

  if ( (sizeof(h)+num)>QueryProp(P_MAX_HANDS) )
    return 0;

  foreach(int i: num)
    h+=({ob});

  SetProp(P_HANDS_USED_BY,h);

  return 1;
}

public varargs int FreeHands(object ob)
{
  if ( !ob && !(ob=previous_object(1)) )
    return 0;

  SetProp(P_HANDS_USED_BY,QueryProp(P_HANDS_USED_BY)-({ob}));

  return 1;
}

// Kompatiblitaetsfunktionen:

static int _set_used_hands(int new_num)
{ int    old_num, dif;
  object ob;

  old_num=QueryProp(P_USED_HANDS);

  if ( !objectp(ob=previous_object(1)) )
    return old_num;

  // Meldung ins Debuglog schreiben. Aufrufer sollte gefixt werden.
  debug_message(sprintf("P_USED_HANDS in %O wird gesetzt durch %O\n",
        this_object(), ob), DMSG_LOGFILE|DMSG_STAMP);

  if ( !(dif=new_num-old_num) )
    return new_num;

  if ( dif>0 )
    UseHands(ob,dif);
  else
    FreeHands(ob);

  return QueryProp(P_USED_HANDS);
}

// Funktionen fuer Begruessungsschlag / Nackenschlag:

public int CheckEnemy(object ob)
{
  return (living(ob) && IsEnemy(ob));
}

public varargs void ExecuteMissingAttacks(object *remove_attackers)
{
  if ( !pointerp(missing_attacks) )
    missing_attacks=({});

  if ( pointerp(remove_attackers) )
    missing_attacks-=remove_attackers;

  foreach(object ob : missing_attacks) {
    if ( objectp(ob) && (environment(ob)==environment()) )
      ob->Attack2(ME);
  }
  missing_attacks=({});
}

public void InitAttack()
{ object ob,next;
  closure cb;

  if ( !living(ME) )
    return;

  ExecuteMissingAttacks();
  //EMA kann das Living zerstoeren oder toeten...
  if (!living(ME) || QueryProp(P_GHOST)) return;

  if ( objectp(ob=IsTeamMove()) )
    cb=symbol_function("InitAttack_Callback",ob);
  else
    cb=0;

  for ( ob=first_inventory(environment()) ; objectp(ob) ; ob=next)
  {
    next=next_inventory(ob);

    if ( !living(ob) )
      continue;

    if (ob->IsEnemy(ME))
    {
      // Das ist nicht so sinnlos wie es aussieht. a) werden die Hunttimes
      // aktualisiert und b) werden Teammitglieder von mir bei diesem
      // InsertEnemy() ggf. erfasst.
      ob->InsertEnemy(ME);

      if ( closurep(cb) && funcall(cb,ob) ) // Wird ganzes Team gemoved?
        missing_attacks += ({ ob }); // Dann erstmal warten bis alle da sind
      else
        ob->Attack2(ME);

    }
    else if ( IsEnemy(ob) )
    {
      // Das ist nicht so sinnlos wie es aussieht. a) werden die Hunttimes
      // aktualisiert und b) werden Teammitglieder von ob bei diesem 
      // InsertEnemy() ggf. erfasst.
      InsertEnemy(ob);
      Attack2(ob);
    }
    //Attack2 kann dieses Objekt zerstoeren oder toeten. Wenn ja: abbruch
    if ( !living(ME) || QueryProp(P_GHOST)) break;
  }
}

public void ExitAttack()
{
  if ( !living(ME) )
    return;

  // Noch nachzuholende Begruessungsschlaege:
  ExecuteMissingAttacks();
}

public object|object*|mapping QueryArmourByType(string type)
{
  // Rueckgabewert:
  // DIE Ruestung vom Typ <type>, falls <type> nicht AT_MISC,
  // Array aller AT_MISC-Ruestungen falls <type> AT_MISC (auch leer),
  // Mapping mit allen oben genannten Infos, falls <type> Null

  object *armours;
  string typ2;

  // Wenn Cache vorhanden, dann Cache liefern.
  if (mappingp(QABTCache)) {
    if (type == AT_MISC)
      return QABTCache[AT_MISC] - ({0});
    else if (type)
      return QABTCache[type];
    else
      return copy(QABTCache);
  }

  if ( !pointerp(armours=QueryProp(P_ARMOURS)) )
    armours=({});

  // Cache erzeugen
  QABTCache = ([ AT_MISC: ({}) ]);
  foreach(object ob: armours - ({0}) ) {
    if ( !stringp(typ2=ob->QueryProp(P_ARMOUR_TYPE)) )
      continue;
    if ( typ2==AT_MISC )
      QABTCache[AT_MISC] += ({ob});
    else
      QABTCache[typ2] = ob;
  }
  // Und gewuenschtes Datum liefern.
  if (type)
    return QABTCache[type];
  else
    return copy(QABTCache);
}

//TODO: langfristig waers besser, wenn hier nicht jeder per SetProp() drauf
//los schreiben wuerde.
static object *_set_armours(object *armours) {
  if (pointerp(armours)) {
    // Cache wegwerfen
    QABTCache = 0;
    // armours ggf. unifizieren. Ausserdem Kopie reinschreiben.
    return Set(P_ARMOURS, m_indices(mkmapping(armours)), F_VALUE);
  }
  return QueryProp(P_ARMOURS);
}

/** Reduziert die Befriedezaehler pro Reset im Durchschnitt um 2.5.
  Berechnet ganzzahlige durchschnittliche Resets seit dem letzten Expire und
  erhoeht die letzte Expirezeit um Resets*__RESET_TIME__ (Standard Intervall
  fuer Reset ist momentan 3600s, im Durchschnitt kommen dann 2700 zwischen 2
  Resets bei raus). So wird der unganzzahlige Rest beim naechsten Aufruf
  beruecksichtigt.
  Diese Variante des Expires wurde gewaehlt, um zu vermeiden, combat.c einen
  reset() zu geben und in jedem Reset in jedem Lebewesen ein Expire machen zu
  muessen, auch wenn nur in sehr wenigen Lebewesen was gemacht werden muss.
  @param[in,out] ph Mapping aus P_PEACE_HISTORY. Wird direkt aktualisiert.
  @attention Muss ein gueltiges P_PEACE_HISTORY uebergeben bekommen, anderem
  Datentyp inkl. 0 wird die Funktion buggen.
  */
private void _decay_peace_history(mixed ph) {
  // Ganzzahlige resets seit letztem Expire ermitteln. (Durchschnitt)
  int resets = (time() - ph[0]) / (__RESET_TIME__*75/100);
  // auf Zeitstempel draufrechnen, damit der unganzzahlige Rest nicht
  // verlorengeht, der wird beim naechsten Expire dann beruecksichtigt.
  ph[0] += resets * (__RESET_TIME__ * 75 / 100);
  // pro Reset werden im Durchschnitt 2.5 Versuche abgezogen. (Hier werden
  // beim Expire mal 2 und mal 3 Versuche pro Reset gerechnet. Aber falls hier
  // viele Resets vergangen sind, ist es vermutlich eh egal, weil die Counter
  // auf 0 fallen.)
  int expire = resets * (random(2) + 2);
  // ueber alle Gilden
  mapping tmp=ph[1];
  foreach(string key, int count: &tmp ) {
    count-=expire;
    if (count < 0) count = 0;
  }
}

/** Pacify() dient zur Bestimmung, ob sich ein Lebewesen gerade 
 * befrieden lassen will.
 * Berechnet eine Wahrscheinlichkeit nach unten stehender Formel, welche die
 * Intelligenz dieses Lebenwesens, die Intelligenz des Casters und die
 * bisherige Anzahl erfolgreicher Befriedungsversuche dieser Gilde eingeht.
 * Anschliessend wird aus der Wahrscheinlichkeit und random() bestimmt, ob
 * dieser Versuch erfolgreich ist.
Formel: w = (INT_CASTER + 10 - ANZ*4) / (INT_ME + 10)
INT_CASTER: Caster-Intelligenz, INT_ME: Intelligenz dieses Livings
ANZ: Anzahl erfolgreicher Befriedungsversuche

Annahme: INT_CASTER === 22, alle Wahrscheinlichkeiten * 100

INT_ME   Erfolgswahrscheinlichkeiten je nach Anzahl erfolgreicher Versuche
              1       2       3       4       5       6       7       8
      0     280     240     200     160     120      80      40       0
      2  233,33     200  166,67  133,33     100   66,67   33,33       0
      4     200  171,43  142,86  114,29   85,71   57,14   28,57       0
      6     175     150     125     100      75      50      25       0
      8  155,56  133,33  111,11   88,89   66,67   44,44   22,22       0
     10     140     120     100      80      60      40      20       0
     12  127,27  109,09   90,91   72,73   54,55   36,36   18,18       0
     14  116,67     100   83,33   66,67      50   33,33   16,67       0
     16  107,69   92,31   76,92   61,54   46,15   30,77   15,38       0
     18     100   85,71   71,43   57,14   42,86   28,57   14,29       0
     20   93,33      80   66,67   53,33      40   26,67   13,33       0
     22    87,5      75    62,5      50    37,5      25    12,5       0
     24   82,35   70,59   58,82   47,06   35,29   23,53   11,76       0
     26   77,78   66,67   55,56   44,44   33,33   22,22   11,11       0
     28   73,68   63,16   52,63   42,11   31,58   21,05   10,53       0
     30      70      60      50      40      30      20      10       0
     32   66,67   57,14   47,62    38,1   28,57   19,05    9,52       0
     34   63,64   54,55   45,45   36,36   27,27   18,18    9,09       0
     35   62,22   53,33   44,44   35,56   26,67   17,78    8,89       0
     36   60,87   52,17   43,48   34,78   26,09   17,39     8,7       0
     38   58,33      50   41,67   33,33      25   16,67    8,33       0
     40      56      48      40      32      24      16       8       0
     42   53,85   46,15   38,46   30,77   23,08   15,38    7,69       0
     44   51,85   44,44   37,04   29,63   22,22   14,81    7,41       0
     46      50   42,86   35,71   28,57   21,43   14,29    7,14       0
     48   48,28   41,38   34,48   27,59   20,69   13,79     6,9       0
     50   46,67      40   33,33   26,67      20   13,33    6,67       0
     52   45,16   38,71   32,26   25,81   19,35    12,9    6,45       0
     54   43,75    37,5   31,25      25   18,75    12,5    6,25       0
     56   42,42   36,36    30,3   24,24   18,18   12,12    6,06       0
     58   41,18   35,29   29,41   23,53   17,65   11,76    5,88       0
     60      40   34,29   28,57   22,86   17,14   11,43    5,71       0
     62   38,89   33,33   27,78   22,22   16,67   11,11    5,56       0
     64   37,84   32,43   27,03   21,62   16,22   10,81    5,41       0
     66   36,84   31,58   26,32   21,05   15,79   10,53    5,26       0
     68    35,9   30,77   25,64   20,51   15,38   10,26    5,13       0
     70      35      30      25      20      15      10       5       0
     72   34,15   29,27   24,39   19,51   14,63    9,76    4,88       0
     74   33,33   28,57   23,81   19,05   14,29    9,52    4,76       0
     76   32,56   27,91   23,26    18,6   13,95     9,3    4,65       0
     78   31,82   27,27   22,73   18,18   13,64    9,09    4,55       0
     80   31,11   26,67   22,22   17,78   13,33    8,89    4,44       0
     82   30,43   26,09   21,74   17,39   13,04     8,7    4,35       0
     84   29,79   25,53   21,28   17,02   12,77    8,51    4,26       0
     86   29,17      25   20,83   16,67    12,5    8,33    4,17       0
     88   28,57   24,49   20,41   16,33   12,24    8,16    4,08       0
     90      28      24      20      16      12       8       4       0
     92   27,45   23,53   19,61   15,69   11,76    7,84    3,92       0
     94   26,92   23,08   19,23   15,38   11,54    7,69    3,85       0
     96   26,42   22,64   18,87   15,09   11,32    7,55    3,77       0
     98   25,93   22,22   18,52   14,81   11,11    7,41     3,7       0
    100   25,45   21,82   18,18   14,55   10,91    7,27    3,64       0
 * @return 1, falls Befrieden erlaubt ist, 0 sonst.
 * @param[in] caster Derjenige, der den Spruch ausfuehrt.
 * @attention Wenn acify() 1 zurueckliefert, zaehlt dies als
 * erfolgreicher Befriedungsversuch und in diesem Lebewesen wurde
 * StopHuntingMode(1) aufgerufen.
*/
public int Pacify(object caster) {
  
  // wenn das Viech keine Gegner hat, dann witzlos. ;-) Ohne Caster gehts auch
  // direkt raus.
  if (!mappingp(enemies) || !sizeof(enemies)
      || !objectp(caster)) {
    return 0;
  }

  // Wenn P_ACCEPT_PEACE gesetzt ist, altes Verhalten wiederspiegeln
  // -> der NPC ist einfach immer befriedbar. Gleiches gilt fuer den Caster
  // selber, der wird sich ja nicht gegen das eigene Befriede wehren. Und auch
  // im team wehrt man sich nicht gegen das Befriede eines Teamkollegen
  if (QueryProp(P_ACCEPT_PEACE)==1 || caster==ME
      || member(TeamMembers(), caster) > -1) {
    StopHuntingMode(1); // Caster/Gilde sollte eigene Meldung ausgeben
    return 1;
  }

  string gilde = caster->QueryProp(P_GUILD) || "ANY";

  // ggf. P_PEACE_HISTORY initialisieren
  <int|mapping>* ph = QueryProp(P_PEACE_HISTORY);
  if (!pointerp(ph))
    SetProp(P_PEACE_HISTORY, ph=({time(), ([]) }) );
  
  // ggf. die Zaehler reduzieren.
  if ( ph[0] + __RESET_TIME__ * 75/100 < time()) {
    _decay_peace_history(&ph);
  }
  
  float w = (caster->QueryAttribute(A_INT) + 10 - ph[1][gilde] * 4.0) / 
             (QueryAttribute(A_INT) + 10);
  // auf [0,1] begrenzen.
  if (w<0) w=0.0;
  else if (w>1) w=1.0;
  // w * n ist eine Zahl zwischen 0 und n, wenn w * n > random(n)+1,
  // darf befriedet werden. Da das Random fuer grosse Zahlen
  // besser verteilt ist, nehm ich n = __INT_MAX__ und vernachlaessige
  // ausserdem die +1 beim random().
  if (ceil(w * __INT_MAX__) > random(__INT_MAX__) ) {
    ph[1][gilde]++;
    StopHuntingMode(1);
    return 1;
  }
  // ein SetProp(P_PEACE_HISTORY) kann entfallen, da das Mapping direkt
  // geaendert wird. Sollte die Prop allerdings mal ne Querymethode haben,
  // welche eine Kopie davon liefert, muss das hier geaendert oder die
  // Prop per Query() abgefragt werden.
  return 0;
}

