// 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
#pragma pedantic

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 string magic_attack;
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;
private nosave mapping peace_tries;
// 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, ({}));
  attack_busy=100;
  att2_time=0;
  enemies=([]);
  peace_tries=([]);
  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+((float)resimap[old[i]]))*2.0-1.0;

  for ( i=sizeof(arg)-1 ; i>=0 ; i-- )
    resimap[arg[i]]=(1.0+((float)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+((float)resimap[old[i]]))*0.5-1.0;

  for ( i=sizeof(arg)-1 ; i>=0 ; i-- )
    resimap[arg[i]]=(1.0+((float)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, arena;
  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 = (int)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 = (mixed)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 = (int)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 "+(string)funcall(cl,WEM,0));
    ainfo[SI_SKILLDAMAGE_MSG2] = (" mit "+(string)funcall(cl,WEM,1));

    ainfo[SI_SKILLDAMAGE] = (int)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] = (string)funcall(cl,P_WEAPON_TYPE);
    ainfo[P_NR_HANDS] = (int)funcall(cl,P_NR_HANDS);
    ainfo[P_WC] = (int)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]=((int)(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]=(int)res[SI_SKILLDAMAGE];
      ainfo[SI_SKILLDAMAGE_TYPE]=res[SI_SKILLDAMAGE_TYPE];

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

      if ( stringp(res[SI_SKILLDAMAGE_MSG2]) )
        ainfo[SI_SKILLDAMAGE_MSG2] = " mit "+(string)res[SI_SKILLDAMAGE_MSG2];
      else
        ainfo[SI_SKILLDAMAGE_MSG2] = (string)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(((int)res[1])+1)
                              + 10*(QueryAttribute(A_STR)) )/3);
      ainfo[SI_SKILLDAMAGE_TYPE] = res[2];
      ainfo[SI_SKILLDAMAGE_MSG] = ainfo[SI_SKILLDAMAGE_MSG2]
                                = ((string)res[0]);
      ainfo[P_WEAPON_TYPE] = WT_HANDS;
      ainfo[P_WC] = (int)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   : ([ ])  ]);
  }

  // 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)
{ object *defs;

  if ( !objectp(friend) )
    return;

  if ( !pointerp(defs=QueryProp(P_DEFENDERS)) )
    defs=({});

  if ( member(defs,friend)>=0 )
    return;

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

public void RemoveDefender(object friend)
{ object *defs;

  if ( !objectp(friend) )
    return;

  if ( !pointerp(defs=QueryProp(P_DEFENDERS)) )
    defs=({});

  if ( member(defs,friend)==-1 )
    return;

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

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,x;
  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   : ([ ]),
               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]);
    }
    if ( !mappingp(spell[SP_REDUCE_ARMOUR]) )
      spell[SP_REDUCE_ARMOUR] = ([]);
  }
  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)
{
  int     i,k;
  mixed   res,res2;
  object  *armours,tmp;
  mixed hookData;
  mixed hookRes;

  //  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
  if ( res=QueryProp(P_DEFENDERS) )
  { object *defs,*defs_here;

    defs=({});
    defs_here=({});
    if ( !pointerp(res) )
      res=({res});
    // erst alle anwesenden finden.
    foreach(object defender: res) {
      if ( objectp(defender) && (member(defs,defender)<0) )
      {
        defs+=({defender});
        //  Verteidiger muessen im gleichen Raum oder im Living selber
        //  enthalten sein.
        if ( environment(defender) == environment()
            || environment(defender) == ME)
        {
          call_other(defender,"InformDefend",enemy);
          if (defender)
            defs_here += ({ defender });
        }
      }
    }
    //Anwesende Verteidiger eintragen.
    spell[EINFO_DEFEND][PRESENT_DEFENDERS]=defs_here;

    // P_DEFENDERS auch gleich aktualisieren
    if ( sizeof(defs)<1 )
      defs=0;
    SetProp(P_DEFENDERS,defs);

    if ( spell[SP_PHYSICAL_ATTACK] ) {
      // Bei physischen Angriffen nur Verteidiger aus Reihe 1
      // nehmen (z.B. fuer Rueckendeckung)
      foreach(object defender: defs_here) {
        if ( (defender->PresentPosition())>1 ) {
          defs_here-=({defender});
        }
      }
    }
 
    if ( (i=sizeof(defs_here)) )
    {
      mixed edefendtmp=({defs_here[random(i)],0,0,0}); 
      res=call_other(edefendtmp[DEF_DEFENDER],"DefendOther",
                     dam,dam_type,spell,enemy);
      if ( pointerp(res) && (sizeof(res)>=3) && intp(res[0])
          && pointerp(res[1]))
      {
        // Helfer koennen den Schaden oder Schadenstyp aendern,
        // z.B. Umwandlung von Feuer nach Eis oder so...
        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]);
        }
        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)) )
  {
    res2=tmp->QueryDefend(dam_type, spell, enemy);

    // Reduzierbare Wirksamkeit der Parierwaffe?
    if ( member(spell[SP_REDUCE_ARMOUR],P_PARRY_WEAPON)
        && intp(res=spell[SP_REDUCE_ARMOUR][P_PARRY_WEAPON]) && (res>=0) )
    {
      res2=(res2*res)/100;
    }

    dam-=res2;
    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=(string)armour->QueryProp(P_ARMOUR_TYPE);

        if ( member(spell[SP_REDUCE_ARMOUR],aty)
            && intp(res2=spell[SP_REDUCE_ARMOUR][aty]) && (res2>=0) )
          dam -= (res2*armour->QueryDefend(dam_type, spell, enemy))/100;
        else
          dam -= (int)(armour->QueryDefend(dam_type, spell, enemy));
        // 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=(int)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] )
  {
    // Minimum ist auch hier 1.
    int body = QueryProp(P_BODY)+QueryAttribute(A_DEX);
    res2 = (body/4 + random(body*3/4 + 1)) || 1;
    if (stat)
      stat->bodystat(body, res2, random(body)+1);

    // Reduzierbare Wirksamkeit des Bodies?
    if ( member(spell[SP_REDUCE_ARMOUR], P_BODY)
        && intp(res=spell[SP_REDUCE_ARMOUR][P_BODY]) && (res>=0) )
      res2=(res2*res)/100;

    dam-=res2;
  }
  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;
  int     i;

  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 = ((int)(res->QueryProp(P_WC)));
  else if ( pointerp(res=QueryProp(P_HANDS)) && sizeof(res)>1
           && intp(res[1]) )
    totwc=((int)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 += ((int)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
  mixed ph = (mixed)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;
}

