diff --git a/std/weapon/combat.c b/std/weapon/combat.c
new file mode 100644
index 0000000..cb10ff5
--- /dev/null
+++ b/std/weapon/combat.c
@@ -0,0 +1,819 @@
+// MorgenGrauen MUDlib
+//
+// weapon/combat.c -- combat part of the weapon standard object
+//
+// $Id: combat.c 9425 2016-01-02 18:19:40Z Zesstra $
+
+#include <sys_debug.h>
+
+#pragma strict_types
+#pragma save_types
+#pragma no_clone
+#pragma pedantic
+#pragma range_check
+
+#define NEED_PROTOTYPES
+
+#include <thing/properties.h>
+#include <thing/commands.h>
+#include <thing/description.h>
+#include <properties.h>
+#include <language.h>
+#include <combat.h>
+#include <attributes.h>
+#include <defines.h>
+#include <moving.h>
+#include <new_skills.h>
+
+// Globale Variablen
+               int     ftime, flaw;
+private nosave int     logged;
+private nosave closure defend_cl, hit_cl;
+
+void create() 
+{
+    // Variablen initialisieren
+    logged=ftime=flaw=0;
+    defend_cl=0;
+    hit_cl=0;
+
+    // Einige Grundwerte setzen
+    SetProp(P_WEAPON_TYPE, WT_CLUB);
+    SetProp(P_DAM_TYPE, ({DT_BLUDGEON}));
+    SetProp(P_NR_HANDS, 2);
+    SetProp(P_PARRY,PARRY_NOT);
+    SetProp(P_AC,0);
+    Set(P_RESTRICTIONS,([]),F_VALUE);
+    Set(P_LAST_USE,time(),F_VALUE);
+
+    // Einige Properties sollten nicht von aussen gesetzt werden koennen
+    Set(P_PARRY,   PROTECTED, F_MODE_AS);
+    Set(P_WIELDED, PROTECTED, F_MODE_AS);
+    Set(P_LAST_USE,PROTECTED, F_MODE_AS);
+    
+    // Diese kann von aussen gesetzt werden (noch), aber bitte nur ueber die
+    // hier definierte Setmethode.
+    Set(P_DAMAGED, PROTECTED, F_MODE_AS);
+
+    // Eine Waffe benoetigt Kommandos, mit denen man sie zuecken 
+    // und wegstecken kann
+    AddCmd( ({"zueck","zuecke","zieh","ziehe"}), "wield" );
+    AddCmd( ({"steck","stecke"}), "unwield" );
+}
+
+// aktuelles Lebewesen, was diese Waffe zur Zeit gezueckt hat.
+public object QueryUser()
+{
+  return QueryProp(P_WIELDED);
+}
+
+/*
+ * Ausgabe einer Meldung beim Zuecken geht nur an Spieler, nicht an NPC.
+ * Die Umgebung bekommt natuerlich immer eine Meldung.
+ */
+void doWieldMessage()
+{
+  string *str, s1;
+  
+  if(QueryProp(P_WIELD_MSG))  // Ist eine WieldMsg gesetzt?
+  {
+    if(closurep(QueryProp(P_WIELD_MSG)))  // Sogar als eigene Fkt.?
+    {
+      str = funcall(QueryProp(P_WIELD_MSG),this_player());
+
+      if(interactive(this_player()))
+      {
+        this_player()->ReceiveMsg(str[0],
+            MT_NOTIFICATION|MSG_BS_LEAVE_LFS, MA_WIELD, 0,
+            this_player());
+      }
+    
+      if ( objectp(environment()) && objectp(environment(environment())) )
+          send_room(environment(environment()),
+              str[1],
+              MT_LOOK|MSG_BS_LEAVE_LFS,
+              MA_WIELD, 0, ({this_player()}), environment());
+      return;
+    }
+    else if(interactive(this_player()))
+    {
+      s1 = replace_personal(sprintf(QueryProp(P_WIELD_MSG)[0],"@WEN2"),
+		      ({this_player(),this_object()}), 1);
+
+      this_player()->ReceiveMsg(s1,
+          MT_NOTIFICATION|MSG_BS_LEAVE_LFS, MA_WIELD, 0,
+          this_player()); 
+    }
+
+    // Abwaertskompatibel: Das erste %s wird zu WEN1, das zweite zu WEN2
+    s1 = replace_personal(sprintf(QueryProp(P_WIELD_MSG)[1],"@WEN1","@WEN2"),
+		    ({this_player(), this_object()}), 1);
+        
+    if ( objectp(environment()) && objectp(environment(environment())) )
+        send_room(environment(environment()),
+              s1,
+              MT_LOOK|MSG_BS_LEAVE_LFS,
+              MA_WIELD, 0, ({this_player()}), environment());
+    return;
+  }
+  /*
+   * Keine WieldMsg gesetzt, Ausgabe der Default-Meldungen.
+   */
+  else if(interactive(this_player()))
+  {
+    this_player()->ReceiveMsg(
+        "Du zueckst "+name(WEN,1)+".",
+        MT_NOTIFICATION, MA_WIELD, 0, this_player());
+  }
+  
+  //s.o. ersetzt durch tell_room()
+  //say(break_string(this_player()->Name(WER)+" zueckt "
+  // +name(WEN,0)+".",78),({ this_player() }));
+  if ( objectp(environment()) && objectp(environment(environment())) )
+      send_room(environment(environment()),    
+          this_player()->Name(WER)+" zueckt "+name(WEN,0)+".",
+          MT_LOOK,
+          MA_WIELD, 0, ({this_player()}), environment());
+}
+
+/*
+ * Ausgabe einer Meldung beim Wegstecken geht nur an Spieler, nicht an NPC.
+ * Die Umgebung bekommt immer eine Meldung.
+ */
+void doUnwieldMessage(object wielded_by)
+{
+  string *str,s1;
+
+  if(!objectp(wielded_by))  // Hoops! Gar nicht gezueckt? Abbruch!
+  {
+    return;
+  }
+
+  if(QueryProp(P_UNWIELD_MSG))  // Hier gibt es eine UnwieldMsg.
+  {
+    if(closurep(QueryProp(P_UNWIELD_MSG)))  // Sogar als Closure, wow :-)
+    {
+      str = funcall(QueryProp(P_UNWIELD_MSG),wielded_by);
+
+      if(interactive(wielded_by))
+      { 
+        wielded_by->ReceiveMsg(str[0],
+          MT_NOTIFICATION|MSG_BS_LEAVE_LFS, MA_UNWIELD, 0, wielded_by);
+      }
+      if ( objectp(environment()) && objectp(environment(environment())) )
+          send_room(environment(environment()),
+              str[1],
+              MT_LOOK|MSG_BS_LEAVE_LFS,
+              MA_UNWIELD, 0, ({wielded_by}), environment());
+      return;
+    }
+  
+    else if(interactive(wielded_by))
+    {
+      s1 = replace_personal(sprintf(QueryProp(P_UNWIELD_MSG)[0],"@WEN2"),
+		      ({this_player(),this_object()}), 1); 
+      wielded_by->ReceiveMsg(s1,
+          MT_NOTIFICATION|MSG_BS_LEAVE_LFS, MA_UNWIELD, 0, wielded_by);
+    }
+
+    s1 = replace_personal(sprintf(QueryProp(P_UNWIELD_MSG)[1],"@WEN1","@WEN2"),
+		    ({wielded_by, this_object()}), 1);
+    
+    if ( objectp(environment()) && objectp(environment(environment())) )
+          send_room(environment(environment()),
+              s1,
+              MT_LOOK|MSG_BS_LEAVE_LFS,
+              MA_UNWIELD, 0, ({wielded_by}), environment());
+    return;
+  }
+  /*
+   * Keine UnwieldMsg, also Default-Meldungen ausgeben.
+   */
+  else if(interactive(wielded_by))
+  {
+    wielded_by->ReceiveMsg(
+        "Du steckst "+name(WEN,1)+" zurueck.",
+        MT_NOTIFICATION, MA_UNWIELD, 0, wielded_by);
+  }
+  if ( objectp(environment()) && objectp(environment(environment())) )
+      send_room(environment(environment()),
+              wielded_by->Name(WER) +" steckt "+name(WEN,0)+" zurueck.",
+              MT_LOOK,
+              MA_UNWIELD, 0, ({wielded_by}), environment()); 
+}
+
+// Diese Funktion wird aufgerufen, wenn die Waffe wirklich gezueckt wird
+protected void InformWield(object pl, int silent)
+{
+    return;
+}
+     
+// Diese Funktion wird aufgerufen, wenn die Waffe wirklich weggesteckt
+// wird
+protected void InformUnwield(object pl, int silent) 
+{
+    return;
+}
+
+
+// wield_me soll knallen. 
+varargs int wield_me(int silent) 
+{
+  raise_error("wield_me() ist veraltet. Bitte nutze DoWield()\n");
+  return 1;
+}
+
+// Die Funktion, die das eigentliche Zuecken durchfuehrt.
+varargs int DoWield(int silent) 
+{   int     dex, parry;
+    closure cl;
+    mixed   res;
+  
+    // Man kann nur Waffen zuecken, die man auch im Inventory hat.
+    if (environment()!=PL) 
+    {
+        _notify_fail( break_string(
+            "Du musst "+name(WEN,1)+" schon erst nehmen!",78) );
+        return 0;
+    }
+
+    // Eine gezueckte Waffe kann man natuerlich nicht nochmal zuecken
+    if (QueryProp(P_WIELDED)) 
+    {
+        notify_fail("Das hast Du schon gemacht!\n");
+        return 0;
+    }
+
+    // Waffen, die ein oder mehrere Attribut veraendern und gegen
+    // das gesetzte Limit verstossen, haben keine Wirkung bezueglich der
+    // Attribute.
+    if ( mappingp(res=QueryProp(P_M_ATTR_MOD)) && PL->TestLimitViolation(res) )
+    {
+        write(break_string(
+            "Irgendetwas an Deiner Ausruestung verhindert, dass Du Dich mit "+
+            name(WEM,1)+" so richtig wohl fuehlst.",78));
+    }
+
+    // Ueber P_RESTRICTIONS kann man einige Restriktionen definieren, ohne
+    // gleich auf eine WieldFunc zurueckgreifen zu muessen.
+    // Die Auswertung erfolgt ueber den RestrictionChecker
+    if ( (res=QueryProp(P_RESTRICTIONS)) && mappingp(res) &&
+         (res=(string)call_other("/std/restriction_checker","check_restrictions",
+             PL,res)) && stringp(res) ) 
+    {
+        notify_fail(res);
+        return 0;
+    }
+
+    parry=(int)QueryProp(P_PARRY);
+    dex=(int)PL->QueryAttribute(A_DEX);
+
+    // Testen, ob der Spieler die noetige Geschicklichkeit besitzt, um
+    // mit dieser (Parier)Waffe umgehen zu koennen
+    if ( ((parry<PARRY_ONLY) && ((dex+8)*10)<QueryProp(P_WC)) || 
+         ((parry>PARRY_NOT)  && ((dex+5)*2 )<QueryProp(P_AC)) )
+    {
+        notify_fail(
+            "Du bist nicht geschickt genug, um mit dieser Waffe umzugehen.\n");
+        return 0;
+    }
+
+    // Eine Gezueckte Waffe muss natuerlich erst mal weggesteckt werden.
+    if ( (parry<PARRY_ONLY) && objectp(res=(object)PL->QueryProp(P_WEAPON)) )
+    {
+        if ( (res->DoUnwield(silent)) && !((object)PL->QueryProp(P_WEAPON)) )
+        {
+            // Wenn die alte Waffe weggesteckt werden konnte, nochmal
+            // versuchen zu zuecken
+            return DoWield(silent);
+        }
+        else 
+        {
+            // Sonst Meldung ausgeben
+            notify_fail("Das geht nicht, solange Du noch eine andere "+
+                 "Waffe gezueckt hast.\n");
+            return 0;
+        }
+    }
+    // Das gleiche gilt natuerlich fuer Parierwaffen
+    if ( (parry>PARRY_NOT) && objectp(res=(object)PL->QueryProp(P_PARRY_WEAPON)) )
+    {
+        if ( (res->DoUnwield(silent)) && !(PL->QueryProp(P_PARRY_WEAPON)) )
+        {
+            // Wenn die alte Parierwaffe weggesteckt werden konnte, nochmal
+            // versuchen zu zuecken
+            return DoWield(silent);
+        }
+        else 
+        {
+            // Sonst Meldung ausgeben
+            notify_fail("Das geht nicht, solange Du noch eine andere "+
+                 "Paierwaffe gezueckt hast.\n");
+            return 0;
+        }
+    }
+
+    // Ist eine WieldFunc gesetzt, wird diese aufgerufen.
+    if (objectp(res=QueryProp(P_WIELD_FUNC)) 
+	&& !(res->WieldFunc(ME,silent,environment())))
+    {
+        // Eine Meldung sollte schon von der WieldFunc ausgegeben werden.
+        return 1;
+    }
+
+    // Die zulaessigen Hoechstwerte duerfen natuerlich nicht
+    // ueberschritten werden.
+    if ( (parry<PARRY_ONLY) && (QueryProp(P_WC)>MAX_WEAPON_CLASS) )
+    {
+        notify_fail(
+            "Ungueltige Waffenklasse, bitte Erzmagier verstaendigen.\n");
+        return 0;
+    }
+    if ( (parry>PARRY_NOT) && (QueryProp(P_AC)>MAX_PARRY_CLASS) )
+    {
+        notify_fail(
+            "Ungueltige Parierklasse, bitte Erzmagier verstaendigen.\n");
+        return 0;
+    }
+
+    // Testen, ob der Zuecker genug Haende frei hat.  
+    if (!(PL->UseHands(ME,QueryProp(P_NR_HANDS))))
+    {
+        notify_fail("Du hast keine Hand mehr frei.\n");
+        return 0;
+    }
+
+    // Ok, jetzt ist alles klar, die (Parier)Waffe wird gezueckt
+    SetProp(P_WIELDED, PL);
+    SetProp(P_EQUIP_TIME,time());
+
+    cl=symbol_function("SetProp",PL);
+
+    if (parry<PARRY_ONLY)
+    {
+        // Dieses Objekt als Waffe setzen
+        funcall(cl,P_WEAPON, ME );
+    }
+    if (parry>PARRY_NOT)
+    {
+        // Dieses Objekt als Parierwaffe setzen
+        funcall(cl,P_PARRY_WEAPON, ME );
+    }
+
+    // Waffen koennen Attribute aendern/blockieren. Also muessen diese
+    // nach dem Zuecken aktualisiert werden
+    PL->register_modifier(ME);
+    PL->UpdateAttributes();
+
+    // P_TOTAL_AC/P_TOTAL_WC im Spieler aktualisieren. Da dort Attribute
+    // eingehen, kann das erst hier gemacht werden.
+    if (parry<PARRY_ONLY)
+    {
+        PL->QueryProp(P_TOTAL_WC);
+    }
+    if (parry>PARRY_NOT)
+    {
+        PL->QueryProp(P_TOTAL_AC);
+    }
+
+    // Zueck-Meldung ausgeben, wenn das silent-Flag nicht gesetzt ist
+    if (!silent)
+    {
+        doWieldMessage();
+    }
+
+    // Alle Waffen werden im awmaster registriert, sobald sie von einem
+    // Spieler gezueckt werden
+    if (!logged && query_once_interactive(PL)) 
+    {
+        call_other("/secure/awmaster","RegisterWeapon",ME);
+        logged=1;
+    }
+
+    // Inform-Funktion aufrufen
+    InformWield(PL,silent);
+
+    // Fertig mit dem Zuecken
+    return 1;
+}
+
+// Die Funktion, die das eigentliche Wegstecken durchfuehrt.
+varargs int DoUnwield(int silent) 
+{   closure cl;
+    int     parry;
+    mixed   res;
+    object  wielded_by;
+
+    // Waffen, die nicht gezueckt sind, kann man natuerlich nicht
+    // wegstecken
+    if (!objectp(wielded_by=QueryProp(P_WIELDED)))
+    {
+        return 0;
+    }
+
+    // Ist eine UnwieldFunc gesetzt, wird diese aufgerufen
+    if ( objectp(res=QueryProp(P_UNWIELD_FUNC)) &&
+         !(res->UnwieldFunc(ME,silent,wielded_by)) ) 
+    {
+        // Eine Meldung muss die UnwieldFunc schon selbst ausgeben.
+        return 1;
+    }
+
+    // Eine verfluchte Waffe kann man natuerlich nicht wegstecken - aber
+    // auch da gibts Ausnahmefaelle, wie z.B. den Tod eines Spielers
+    if ((res=QueryProp(P_CURSED)) && !(silent&M_NOCHECK)) 
+    {
+        if (stringp(res))
+        {
+            // Stand in P_CURSED ein String? Dann diesen ausgeben
+            tell_object(wielded_by, 
+                (res[<1]=='\n' ? res : break_string(res,78)));
+        }
+        else
+        {
+            // Sonst eine Standard-Meldung ausgeben
+            tell_object(wielded_by, break_string(
+                "Du kannst "+name(WEN)+" nicht wegstecken.",78));
+        }
+        return 1;
+    }
+
+    // Ok, jetzt ist alles klar, die (Parier)Waffe wird weggesteckt
+    parry=QueryProp(P_PARRY);
+    cl=symbol_function("SetProp",wielded_by);
+
+    if (parry<PARRY_ONLY)
+    {
+        // Eintrag als Waffe im Spieler loeschen
+        funcall(cl,P_WEAPON, 0);
+    }
+    if (parry>PARRY_NOT)
+    {
+        // Eintrag als Parierwaffe im Spieler loeschen
+        funcall(cl,P_PARRY_WEAPON, 0);
+    }
+
+    // Im Spieler die Zeit setzen, zu der er zuletzt eine Waffe weggesteckt
+    // hat.
+    funcall(cl,P_UNWIELD_TIME,time());
+
+    // Meldung ausgeben, wenn silent-Flag nicht gesetzt ist
+    if (!silent) 
+    {
+        doUnwieldMessage(wielded_by);
+    } 
+
+    // Die Haende, die bisher von der Waffe benutzt wurden, freigeben
+    wielded_by->FreeHands(ME);
+    SetProp(P_WIELDED, 0);
+
+    // Waffen koennen Attribute aendern/blockieren. Also muessen diese
+    // nach dem Wegstecken aktualisiert werden
+    wielded_by->deregister_modifier(ME);
+    wielded_by->UpdateAttributes();
+
+    // P_TOTAL_AC/P_TOTAL_WC im Spieler aktualisieren. Da dort Attribute
+    // eingehen, kann das erst hier gemacht werden.
+    if (parry<PARRY_ONLY)
+    {
+        wielded_by->QueryProp(P_TOTAL_WC);
+    }
+    if (parry>PARRY_NOT)
+    {
+        wielded_by->QueryProp(P_TOTAL_AC);
+    }
+
+    // Inform-Funktion aufrufen
+    InformUnwield(wielded_by, silent);
+
+    // Fertig mit dem Wegstecken
+    return 1;
+}
+
+// Die Funktion, die das "zuecken"-Kommando auswertet
+varargs int wield(string str, int silent) 
+{
+    if ( !stringp(str) ||
+         (query_verb()[0..3]=="zieh" && sscanf(str,"%s hervor",str)!=1) )
+    {
+        return 0;
+    }
+
+    if (!id(str)) 
+    {
+        _notify_fail("Du hast sowas nicht.\n");
+        return 0;
+    }
+
+    return DoWield(silent);
+}
+
+// Die Funktion, die das "wegstecken"-Kommando auswertet
+int unwield(string str) 
+{   int    parry;
+    string dummy;
+
+    // Erstmal die Eingabe auswerten. Ist dies wirklich ein Kommando
+    // zum Wegstecken?
+    if ( !stringp(str) || (sscanf(str,"%s weg",     dummy)!=1  && 
+                           sscanf(str,"%s ein",     dummy)!=1  &&
+                           sscanf(str,"%s zurueck", dummy)!=1 ) )
+    {
+        return 0;
+    }
+
+    str = dummy;
+    parry=QueryProp(P_PARRY);
+
+    // Ist wirklich diese Waffe gemeint?
+    if ( !stringp(str) || !id(str) ||
+         ((parry<PARRY_ONLY)&&((object)PL->QueryProp(P_WEAPON)!=ME)) ||
+         ((parry>PARRY_NOT)&&((object)PL->QueryProp(P_PARRY_WEAPON)!=ME)) )
+    {
+        return 0;
+    }
+
+    // Man kann nur Waffen wegstecken, die man auch bei sich hat
+    if (environment() != PL) 
+    {
+        _notify_fail("Diese Waffe gehoert Dir nicht!\n");
+        return 0;
+    }
+
+    // Und natuerlich geht das auch nur, wenn die Waffe gezueckt ist.
+    if (!QueryProp(P_WIELDED)) 
+    {
+        _notify_fail("Diese Waffe hast Du gar nicht gezueckt ...\n");
+        return 0;
+    }
+
+    return DoUnwield();
+}
+
+// Die Funktion, die den Schaden berechnet, den die Waffe verursacht
+int QueryDamage(object enemy)
+{   int    dam;
+    mixed  hit_func;
+    object wielder;
+
+    // Nur gezueckte Waffen machen Schaden
+    if (!objectp(wielder=QueryProp(P_WIELDED)))
+        return 0;
+
+    // Den Basis-Schaden berechnen. Die Staerke des Benutzers wird
+    // hier beruecksichtigt.
+    dam = (2*QueryProp(P_WC)+10*((int)wielder->QueryAttribute(A_STR)))/3;
+
+    // Wie gut man getroffen hat, wird ueber ein random() simuliert
+    dam = random(1+dam);
+
+    // Ist eine HitFunc gesetzt, dann wird diese ausgewertet. Der 
+    // Rueckgabe-Wert wird zum Schaden addiert
+    if (!hit_cl || !get_type_info(hit_cl,2))
+    {
+        if (objectp(hit_func=QueryProp(P_HIT_FUNC)))
+        {
+            hit_cl=symbol_function("HitFunc",hit_func);
+        }
+    }
+    if (hit_cl && get_type_info(hit_cl,2))
+    {
+        dam += funcall(hit_cl,enemy);
+    }
+
+    // Zeitpunkt der letzten Benutzung ausgeben
+    SetProp(P_LAST_USE,time());
+
+    // Berechneten Schaden zurueckgeben
+    return dam;
+}
+
+// Die Funktion, die bei Parierwaffen den Schutzwert berechnet.
+int QueryDefend(string* dam_type, mixed spell, object enemy) 
+{   int     prot;
+    mixed   def_func;
+    object  pl;
+
+    prot = 0;
+
+    // Ruestungen schuetzen nur gegen physikalischen Schaden
+    if (!spell || (mappingp(spell) && spell[SP_PHYSICAL_ATTACK]))
+    {
+        if (sizeof(filter(dam_type,PHYSICAL_DAMAGE_TYPES)))
+        {
+            prot = random(1+QueryProp(P_AC));
+        }
+    }
+
+    // Ist eine DefendFunc gesetzt, wird diese ausgewertet
+    if (!defend_cl || !get_type_info(defend_cl,2))
+    {
+        if (objectp(def_func=QueryProp(P_DEFEND_FUNC))) 
+        {
+            defend_cl=symbol_function("DefendFunc",def_func);
+        }
+    }
+    //Bei Netztoten keine (zurueckschlagende) DefendFunc
+    if (defend_cl && get_type_info(defend_cl,2) &&
+        objectp(pl=QueryProp(P_WIELDED)) && (!query_once_interactive(pl) ||
+        interactive(pl)) )
+    {
+        // Der Rueckgabewert der DefendFunc wird zum Schutz addiert
+        prot += funcall(defend_cl, dam_type, spell, enemy);
+    }
+
+    // Zeitpunkt der letzten Benutzung ausgeben
+    SetProp(P_LAST_USE,time());
+
+    // Berechneten Schutz zurueckgeben
+    return prot;
+}
+
+// Die Anzahl der von einer Waffe benoetigten Haende darf natuerlich nicht
+// kleiner als 1 sein.
+int _set_nr_hands(int arg)
+{
+    if (!intp(arg) || (arg<1) )
+        return Query(P_NR_HANDS, F_VALUE);
+    return Set(P_NR_HANDS, arg, F_VALUE);
+}
+
+// Der Schadenstyp einer Waffe darf zwar als string angegeben werden, wird
+// intern aber immer als array gespeichert
+mixed _set_dam_type(mixed arg)
+{
+    if (pointerp(arg))
+    {
+        return Set(P_DAM_TYPE, arg, F_VALUE);
+    }
+    else if (stringp(arg))
+    {
+        return Set(P_DAM_TYPE, ({ arg }), F_VALUE);
+    }
+    return Query(P_DAM_TYPE, F_VALUE);
+}
+
+// Objekte, die die Beschaedigung einer Waffe durch direktes Setzen von
+// P_DAMAGED durchfuehren, werden im awmaster geloggt
+mixed _set_item_damaged(mixed arg)
+{
+    if (arg && !intp(arg))
+    {
+        return Query(P_DAMAGED, F_VALUE);
+    }
+
+    if (previous_object(1))
+      call_other("/secure/awmaster","RegisterDamager",
+            previous_object(1),QueryProp(P_DAMAGED),arg);
+    
+    return Set(P_DAMAGED,arg,F_VALUE);
+}
+
+// Wird etwas an P_HIT_FUNC geaendert, muss die zugehoerige closure
+// erstmal geloescht werden.
+mixed _set_hit_func(mixed arg)
+{
+    hit_cl=0;
+    return Set(P_HIT_FUNC, arg, F_VALUE);
+}
+
+// Wird etwas an P_DEFEND_FUNC geaendert, muss die zugehoerige closure
+// erstmal geloescht werden.
+mixed _set_defend_func(mixed arg)
+{
+    defend_cl=0;
+    return Set(P_DEFEND_FUNC, arg, F_VALUE);
+}
+
+// Die maximale Waffenklasse einer Waffe berechnet sich natuerlich aus
+// der aktuellen Waffenklasse und der Beschaedigung. Eine Ausnahme bilden
+// hier Waffen, deren effektive Waffenklasse groesser ist als diese Summe
+int  _query_max_wc() 
+{   int a,b;
+
+    a=QueryProp(P_WC)+QueryProp(P_DAMAGED);
+    b=QueryProp(P_EFFECTIVE_WC);
+    if (b>a)
+        return b;
+    return a;
+}
+
+// Will man eine Waffe beschaedigen oder reparieren, so macht man das
+// am besten ueber die Funktion Damage(argument). Positive Argumente
+// bedeuten eine Beschaedigung, negative eine Reparatur. Der Rueckgabewert
+// ist die wirklich durchgefuehrte Aenderung des Beschaedigungswertes
+int Damage(int new_dam)
+{   int    wc,old_dam;
+    object w;
+
+    // Uebergebenes Argument pruefen
+    if (!new_dam || !intp(new_dam))
+    {
+        return 0;
+    }
+
+    // Bei Waffen, die nicht ausschliesslich zur Parade eingesetzt werden,
+    // geht die Beschaedigung auf die Kampfkraft, sprich: P_WC
+    if (QueryProp(P_PARRY)<PARRY_ONLY)
+    {
+        if ((wc=QueryProp(P_WC))<=MIN_WEAPON_CLASS && new_dam>0)
+        {
+            // Sonst wuerde Beschaedigung zur Reparatur fuehren
+            return 0;
+        }
+
+        // Min-WC und Max-WC beachten
+        if ((wc-new_dam) < MIN_WEAPON_CLASS)
+        {
+            new_dam = wc-MIN_WEAPON_CLASS;
+        }
+        else if ((wc-new_dam) > MAX_WEAPON_CLASS)
+        {
+            new_dam = wc-MAX_WEAPON_CLASS;
+        }
+
+        // Nie mehr als 100% reparieren
+        if (((old_dam=QueryProp(P_DAMAGED))<-new_dam) && new_dam<0)
+        {
+            new_dam=-old_dam;
+        }
+
+        // Aenderungen an der Waffenklasse und der dem Beschaedigungswert
+        // durchfuehren
+        SetProp(P_WC,(wc-new_dam));
+        // Ausnahmeweise Set, um die loggende Setmethode zu umgehen.
+	// TODO: SetProp, sobald direktes Beschaedigen raus ist.
+	Set(P_DAMAGED, old_dam+new_dam, F_VALUE);
+
+        // P_TOTAL_WC im Traeger updaten, so vorhanden
+        if (objectp(w=QueryProp(P_WIELDED)))
+            w->QueryProp(P_TOTAL_WC);
+
+        // Rueckgabewert: Durchgefuehrte Aenderung an P_DAMAGE
+        return new_dam;
+    }
+
+    // Bei reinen Parierwaffen geht die Beschaedigung auf die
+    // Schutzwirkung, sprich: P_AC
+
+    if ((wc=QueryProp(P_AC))<=0 && new_dam>0)
+    {
+        // Sonst wuerde Beschaedigung zur Reparatur fuehren
+        return 0;
+    }
+    
+    // Min-AC=0 und Max-AC beachten
+    if ((wc-new_dam) < MIN_PARRY_CLASS)
+    {
+        new_dam = wc-MIN_PARRY_CLASS;
+    }
+    else if ((wc-new_dam) > MAX_PARRY_CLASS)
+    {
+        new_dam = wc-MAX_PARRY_CLASS;
+    }
+ 
+    // Nie mehr als 100% reparieren
+    if (((old_dam=QueryProp(P_DAMAGED))<-new_dam) && new_dam<0)
+    {
+        new_dam=-old_dam;
+    }
+
+    // Aenderungen an der Ruestungsklasse und dem Beschaedigungswert
+    // durchfuehren
+    SetProp(P_AC,wc-new_dam);
+    // Ausnahmeweise Set, um die loggende Setmethode zu umgehen.
+    // TODO: SetProp, sobald direktes Beschaedigen raus ist.
+    Set(P_DAMAGED,old_dam+new_dam, F_VALUE);
+
+    // P_TOTAL_AC im Traeger updaten, so vorhanden
+    if (objectp(w=QueryProp(P_WIELDED)))
+        w->QueryProp(P_TOTAL_AC);
+    
+    // Rueckgabewert: Durchgefuehrte Aenderung an P_DAMAGE
+    return new_dam;
+}
+
+// Wird die Waffe einer Belastung ausgesetzt (z.B. wenn man damit
+// zuschlaegt), dann wird TakeFlaw() aufgerufen.
+varargs void TakeFlaw(object enemy)
+{   int c;
+
+    // Flaw-Wert erhoehen
+    flaw++;
+
+    // Ist der Waffe eine Qualitaet gesetzt worden, so kann es zu einer
+    // allmaehlichen Beschaedigung der Waffe kommen
+    if ((c=QueryProp(P_QUALITY)) && !(flaw%c))
+        Damage(1);
+
+    // Zeitpunkt des ersten Aufrufes festhalten
+    if (!ftime)
+        ftime=time();
+}
+
+// Die Flaw-Daten koennen natuerlich auch abgerufen werden
+mixed *QueryFlaw()
+{
+    return({flaw,ftime,dtime(ftime)});
+}
+
