diff --git a/std/living/combat.c b/std/living/combat.c
new file mode 100644
index 0000000..880f3f6
--- /dev/null
+++ b/std/living/combat.c
@@ -0,0 +1,2311 @@
+// 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;
+}
+
+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;
+
+  // this_player(), wenn kein enemy bekannt...
+  enemy ||= this_player();
+  // Testen, ob dieses Lebewesen ueberhaupt angegriffen werden darf
+  if ( !this_object() || !enemy || QueryProp(P_NO_ATTACK)
+      || ( query_once_interactive(enemy) && ! interactive(enemy) ) )
+    return 0;
+
+  if ( intp(spell) )
+    spell = ([ SP_PHYSICAL_ATTACK : !spell,
+               SP_SHOW_DAMAGE     : !spell,
+               SP_REDUCE_ARMOUR   : ([ ])  ]);
+  else if ( !mappingp(spell) ) // Illegaler spell-Parameter
+    return 0;
+
+  // testen ob eine erweiterte defendinfo vorhanden ist
+  if(!member(spell,EINFO_DEFEND))
+  {
+          //spell+=([EINFO_DEFEND:([])]); // ggf hinzufuegen
+        // use a temporary mapping to avoid recursive
+        // val[x][y] = deep_copy(val);
+        mapping tmpdefend = ([
+                ORIGINAL_AINFO:deep_copy(spell),
+                ORIGINAL_DAM:dam,
+                  ORIGINAL_DAMTYPE:dam_type,
+        ]);
+          spell[EINFO_DEFEND]=tmpdefend;
+  }
+
+  // Schadenstyp ueberpruefen
+  if ( !pointerp(dam_type) )
+    dam_type = ({ dam_type });
+
+  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
+
+  if ( !member(spell,SP_REDUCE_ARMOUR) || !mappingp(spell[SP_REDUCE_ARMOUR]) )
+        spell[SP_REDUCE_ARMOUR] = ([]);
+
+  // 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;
+}
+
