// 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)});
}

