// MorgenGrauen MUDlib
//
// armour/combat.c -- armour standard object
//
// $Id: combat.c 9092 2015-01-19 23:57:50Z Zesstra $

#pragma strict_types
#pragma save_types
#pragma no_clone
#pragma range_check

#define NEED_PROTOTYPES

#include <thing/properties.h>
#include <thing/commands.h>
#include <thing/description.h>
#include <config.h>
#include <combat.h>
#include <language.h>
#include <defines.h>
#include <new_skills.h>


// Globale Variablen
private nosave closure defend_cl;
private nosave mapping resistance_strengths=([]);

void create() {
    // Einige Grundwerte setzen
    Set(P_ARMOUR_TYPE, AT_ILLEGAL, F_VALUE);
    Set(P_LAST_USE,time(),F_VALUE);
}

// Die Funktion, die den Schutzwert berechnet, den die Ruestung bietet
int QueryDefend(string|string* dam_type, int|mapping spell, object enemy)
{
    int     prot;
    mixed   def_func;
    object  pl;
    // Zum Cachen von spell[EINFO_DEFEND], haeufiges Lookup aus dem Mapping
    // koennte unnoetig Zeit kosten.
    mapping einfo;

    // AT_MISC-Ruetungen schuetzen normalerweise gar nicht...
    if (QueryProp(P_ARMOUR_TYPE)==AT_MISC) {
        // es sei denn, sie haben eine spezielle DefendFunc
        if (!closurep(defend_cl)) return(0);
    }
    else {
        // ansonsten Ruestungsschutz ermitteln und in EINFO_DEFEND vermerken.
        // (Beides fuer AT_MISC in jedem Fall unnoetig)

        // Ruestungen schuetzen nur gegen physikalischen Schaden
        if ((!spell || (mappingp(spell) && spell[SP_PHYSICAL_ATTACK]))
            && sizeof(filter(dam_type,PHYSICAL_DAMAGE_TYPES)))
        { 
          // Schutz bestimmen, Minimum 1, aber nur wenn P_AC > 0
          int pac = QueryProp(P_AC);
          if (pac > 0)
            prot = (pac/4 + random(pac*3/4 + 1)) || 1 ;
          object stat = find_object("/d/erzmagier/zesstra/pacstat");
          if (stat)
            stat->acstat(QueryProp(P_ARMOUR_TYPE),prot,
                         random(pac)+1);

          // ruestungschutz an defendfunc weitermelden
          if (mappingp(spell) &&
              mappingp(einfo=spell[EINFO_DEFEND])) {
              // Schutz d. akt. Ruestung vermerken.
              einfo[DEFEND_CUR_ARMOUR_PROT]=prot;
              // daten der Ruestung vermerken.
              if (mappingp(einfo[DEFEND_ARMOURS])) {
                einfo[DEFEND_ARMOURS][ME,DEF_ARMOUR_PROT]=prot;
              }
          } // ende vom if (mapping(spell) ...)
        } // ende vom if (phys Schaden)

    } // ende vom else (wenn kein AT_MISC) 

    // Ist eine DefendFunc gesetzt, wird diese ausgewertet
    if (closurep(defend_cl)) {
        if (!objectp(get_type_info(defend_cl,2))) {
            // Closure gesetzt, aber nicht gueltig, schauen, ob wir sie neu
            // erstellen koennen.
            if (objectp(def_func=QueryProp(P_DEFEND_FUNC))) {
                defend_cl=symbol_function("DefendFunc",def_func);
            }
            // sonst loeschen, um spaeter diesen Zweig ganz zu sparen.
            else defend_cl=0;
        }
        // BTW: Es ist ok, wenn defend_cl jetzt 0 ist, dann liefert funcall()
        // auch 0.
        // Bei Netztoten keine (zurueckschlagende) DefendFunc
        if (objectp(pl=QueryProp(P_WORN)) && (!query_once_interactive(pl) ||
                interactive(pl)) ) {
          // Der Rueckgabewert der DefendFunc wird zum Schutz addiert
          prot += funcall(defend_cl, dam_type, spell, enemy);
          // leider kann die DefendFunc jetzt auch noch das Objekt zerstoert
          // haben...
          if (!objectp(this_object()))
            return prot;
        }
    }

    // Zeitpunkt der letzten Benutzung ausgeben
    SetProp(P_LAST_USE,time());

    // Berechneten Schutz zurueckgeben
    return prot;
}

// Es duerfen nur "legale" Ruestungstypen gesetzt werden, ansonsten
// wird AT_ILLEGAL gesetzt.
static mixed _set_armour_type(mixed type ) {
    if (!COMBAT_MASTER->valid_armour_type(type))
    {
        Set(P_ARMOUR_TYPE, (type=AT_ILLEGAL), F_VALUE);
    }
    else
    {
        Set(P_ARMOUR_TYPE, type);
    }
    AddId(type);

    resistance_strengths=([]);
    return type;
}


// Wird etwas an P_DEFEND_FUNC geaendert, muss die zugehoerige closure
// neu erstellt werden.
static object _set_defend_func(object arg) {
  if (objectp(arg) &&
      closurep(defend_cl=symbol_function("DefendFunc",arg))) {  
    return Set(P_DEFEND_FUNC, arg, F_VALUE);
  }
  defend_cl=0;
  return(Set(P_DEFEND_FUNC, 0, F_VALUE));
}

// Auch Ruestungen koennen einen Schadenstyp haben. Dieser kann als string
// oder array angegeben werden, wird aber intern auf jeden Fall als
// array gespeichert.
static 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);
}

// Ruestungen koennen Resistenzen setzen. Diese werden jedoch nicht wie
// "normale" Resistenzen gesetzt, sondern als Prozentwerte der fuer diesen
// Typ maximal zulaesigen Resistenz. Die Aenderung der Resistenzen darf
// nur durch die Ruestung selbst erfolgen.
// Beispiel: ([DT_FIRE: 100, DT_WATER: -150])
// max. Feuerresistenz, 1.5fache Anfaelligkeit
static mixed _set_resistance_strengths(mixed resmap) {
    float  max_res;
    object worn_by;

    // Es duerfen nur mappings angegeben werden
    if (!mappingp(resmap))
    {
        return -1;
    }

    // die Maxwerte muessen jeweils durch -100 geteilt sein, da hinterher
    // mit der Prozentzahl multipliziert wird und die angabe der Vorzeichen
    // hier umgekehrt wie bei den "normalen" Resistenzen ist. Der
    // Maximalwert ist vom Ruestungstyp abhaengig.
    switch (QueryProp(P_ARMOUR_TYPE))
    {
        case AT_CLOAK  :
        case AT_RING   :
        case AT_AMULET : max_res=-0.0010;
                         break;
        case AT_SHIELD :
        case AT_ARMOUR : max_res=-0.0015;
                         break;
        default        : max_res=-0.0005;
    }

    // Resistenz-Mapping aktualisieren
    resistance_strengths=([]);
    foreach(string damtype, int res: resmap)
    {
        if (!intp(res)) res=to_int(res);
        // Mehr als 100 Prozent ist nicht erlaubt
        if (res>100)
        {
            res=100;
        }
        else if (res<0)
        {
             res=(res/4)*5;
             // Man kann auch nicht beliebig negativ werden
             if (res<-1000)
             {
                 res=-1000;
             }
        }
        // Der Resistenzwert berechnet sich aus dem Produkt des
        // Maximalwertes und der Prozentzahl
        resistance_strengths[damtype]=res*max_res;
    }

    // Werden die Resistenzen bei einer getragenen Ruestung geaendert,
    // muss der Traeger davon natuerlich beeinflusst werden.
    if (objectp(worn_by=QueryProp(P_WORN)))
    {
        worn_by->AddResistanceModifier(resistance_strengths,
                                       QueryProp(P_ARMOUR_TYPE));
    }
   return resistance_strengths;
}

// Bei einem QueryProp(P_RESISTANCE_STRENGTHS) soll das aktuelle
// Resistenzen-Mapping zurueckgegeben werden
static mapping _query_resistance_strengths() {
  return (resistance_strengths||([]));
}

