// MorgenGrauen MUDlib
//
// living/description.c -- description for living objects
//
// $Id: description.c 9395 2015-12-08 23:04:38Z Zesstra $
#pragma strong_types
#pragma save_types
#pragma range_check
#pragma no_clone

inherit "/std/container/description";

#define NEED_PROTOTYPES

#include <living/skills.h>
#include <living/clothing.h>
#include <thing/properties.h>
#include <wizlevels.h>
#include <new_skills.h>
#include <properties.h>
#include <language.h>
#include <defines.h>
#include <class.h>
#include <sys_debug.h>

#define XL_DURATION "xlduration"
#define XL_LOOKSTR  "xllook"
#define XL_FUN      "xlfun"
#define XL_ENDMSG   "xlende"
#define XL_ENDFUN   "xlendefun"
#define XL_OBJNAME  "xlobjectname"

public string _query_internal_extralook() {
  mixed xl;
  int zeit;
  string res, look="";

  xl=Query(P_INTERNAL_EXTRA_LOOK,F_VALUE);
  if (!mappingp(xl))
    return(0);

  foreach(string key, mapping xld: xl) {
    if (intp(zeit=xld[XL_DURATION])) {
      //hat offenbar nen Ablaufdatum
      if ( (zeit > 0 && zeit < time()) ||
           (zeit < 0 && abs(zeit) < object_time(ME)) ) {
        // Zeit abgelaufen oder
        // negative "Ablaufzeit" und das Objekt ist neuer als die
        // Eintragzeit, also loeschen und weiter (ja, das geht. ;-) und xld
        // hat das Eintragsmapping ja noch, weitere Benutzung also moeglich.)
        m_delete(xl,key);
        // ggf. Meldung ausgeben
        if (interactive(ME)) {
          if (sizeof(xld[XL_ENDMSG])) {
            tell_object(ME,xld[XL_ENDMSG]);
          }
          //kein einfacher String, aber Objekt+Funktion gegeben?
          else if (sizeof(xld[XL_ENDFUN]) && sizeof(xld[XL_OBJNAME]) &&
            (!catch(res=call_other(xld[XL_OBJNAME],xld[XL_ENDFUN],ME)
                    ;publish))) {
              if (stringp(res) && sizeof(res))
                tell_object(ME,res);
            }
        }
        continue;
      }
    }
    // Der Eintrag ist offenbar noch gueltig, Meldung anhaengen, bzw. via
    // Funktionsaufruf beschaffen.
    if (sizeof(xld[XL_LOOKSTR]))
      look+=xld[XL_LOOKSTR];
    else if (sizeof(xld[XL_FUN]) && sizeof(xld[XL_OBJNAME])) {
      closure cl;
      if (catch(cl=symbol_function(xld[XL_FUN],xld[XL_OBJNAME]);publish)
          || !cl) {
          // wenn Fehler beim Laden/Closure erstellen, dann Eintrag loeschen
          // -> Annahme, dass dieser Fehler permanent sein wird, z.B. Eintrag
          // von Clonen
          m_delete(xl,key);
          continue;
      }
      else if (!catch(res=funcall(cl, ME); publish)) {
        if (!stringp(res) || !sizeof(res)) {
          // keinen String oder leeren String gekriegt -> ueberspringen.
          continue;
        }
        else
          look+=res;
      }
    }
  }
  // fertig. Wenn look nicht leer ist, zurueckgeben, sonst 0.
  if (sizeof(look))
    return(look);
  else
    return(0);
}


public varargs int AddExtraLook(string look, int duration, string key, 
                                string lookende, object ob) {
  mapping xl;
  string oname;
  if (!stringp(key) || !sizeof(key)) {
    // Automatisch erzeugen, wenn moeglich
    if (!objectp(previous_object()) || 
        !stringp(key=object_name(previous_object())) || !sizeof(key))
      return XL_NOKEY;
  }

  if (!stringp(look) || !sizeof(look))
    return XL_INVALIDEXTRALOOK;
  if (!intp(duration))
    return XL_INVALIDDURATION;;

  xl=Query(P_INTERNAL_EXTRA_LOOK,F_VALUE); // dran denken: liefert referenz zurueck
  if (!mappingp(xl)) {
    Set(P_INTERNAL_EXTRA_LOOK, xl=([]));
  }

  // kein Automatisches Ueberschreiben.
  if (member(xl,key))
    return XL_KEYEXISTS;

  // neg. Werte: "bis Ende/reboot", abs(duration) == Eintragzeit
  // 0: "fuer ewig", >0: Zeitdauer in Sekunden
  if (duration > 0)
    duration+=time();  // hoffentlich gibt es reichtzeitig 64bit-Ints
  else if (duration < 0)
    duration=negate(time());
  // 0 bleibt, wie es ist.

  if (objectp(ob)) {
    // Funktionsname und Objektname (als Name, damit es auch noch geht, wenn
    // das Objekt entladen wurde, Crash/reboot war etc.) speichern
    // Clone werden auch gespeichert, aber es wird direkt ein harter Fehler
    // ausgeloest, wenn ein permanenter Xlook fuer einen Clone registriert
    // werden soll: das kann nicht gehen.
    if (!duration && clonep(ob))
        raise_error(sprintf(
           "AddExtraLook(): Fehlerhaftes Argument <duration>: %d, "
           "permanente Extralooks durch Clone (%s) nicht registrierbar.\n",
           duration, object_name(ob)));

    xl[key]=([XL_OBJNAME:object_name(ob),
              XL_FUN: look,
             ]);
    // ggf. Name der Funktion speichern, die bei Ablauf aufgerufen wird.
    if (stringp(lookende) && sizeof(lookende))
        xl[key][XL_ENDFUN]=lookende;
  }
  else {
    // Einfacher Eintrag, nur den bearbeiteten String merken. ;-)
    xl[key]=([XL_LOOKSTR: break_string(replace_personal(look,({ME}),1),78,
                                     "",BS_LEAVE_MY_LFS),
             ]);
    // ggf. Meldung speichern, die bei Ablauf ausgegeben werden soll.
    if (stringp(lookende) && sizeof(lookende)) {
      xl[key][XL_ENDMSG]=break_string(replace_personal(lookende,({ME}),1),78,
                                     "",BS_LEAVE_MY_LFS);
    }
  }
  // Endezeit vermerken.
  if (duration != 0)
    xl[key][XL_DURATION]=duration;

  // Kein Set noetig, weil Query das Mapping ja als Referenz lieferte.
  return XL_OK;
}

public int RemoveExtraLook(string key) {
  mapping xl;
  if (!stringp(key) || !sizeof(key)) {
    // Automatisch erzeugen, wenn moeglich
    if (!objectp(previous_object()) ||
        !stringp(key=object_name(previous_object())) || !sizeof(key))
      return XL_NOKEY;
  }
  xl=Query(P_INTERNAL_EXTRA_LOOK,F_VALUE); // dran denken: liefert referenz zurueck
  if (!mappingp(xl))
    return XL_KEYDOESNOTEXIST;
  if (!member(xl,key))
    return XL_KEYDOESNOTEXIST;

  m_delete(xl,key);
  // Kein Set noetig, weil Query das Mapping ja als Referenz lieferte.
  return XL_OK;
}

// Ist ein bestimmter, nicht bereits abgelaufener Eintrag in den
// Extralooks vorhanden?
public int HasExtraLook(string key) {
  // abgelaufene Extralooks austragen
  QueryProp(P_INTERNAL_EXTRA_LOOK);
  return member(Query(P_INTERNAL_EXTRA_LOOK) || ([]), key);
}

void create()
{ 
  ::create();
  Set(P_GENDER, SAVE, F_MODE);
  // Extralook-Property speichern und vor manueller Aenderung schuetzen
  // EMs duerfen, die wissen hoffentlich, was sie tun.
  Set(P_INTERNAL_EXTRA_LOOK, SAVE|PROTECTED, F_MODE_AS);
  SetProp(P_EXTRA_LOOK_OBS,({}));
  Set(P_EXTRA_LOOK, PROTECTED, F_MODE_AS);
  SetProp(P_CLOTHING,({}));
  AddId("Living");
}

string condition()
{
  int hpnt, max_hpnt, perc;

  hpnt        = QueryProp( P_HP );
  max_hpnt    = QueryProp( P_MAX_HP );

  if(max_hpnt>0 && hpnt>0)
    perc=100*hpnt/max_hpnt;
 
  switch(perc) {
    case 0..9:
        return capitalize(QueryPronoun(WER))+" steht auf der Schwelle des Todes.\n";
    case 10..19:
        return capitalize(QueryPronoun(WER))+" braucht dringend einen Arzt.\n";
    case 20..29:
        return capitalize(QueryPronoun(WER))+" ist in keiner guten Verfassung.\n";
    case 30..39:
        return capitalize(QueryPronoun(WER))+" wankt bereits bedenklich.\n";
    case 40..49:
        return capitalize(QueryPronoun(WER))+" macht einen mitgenommenen Eindruck.\n";
    case 50..59:
        return capitalize(QueryPronoun(WER))+" sieht nicht mehr taufrisch aus.\n";
    case 60..69:
        return capitalize(QueryPronoun(WER))+" ist leicht angeschlagen.\n";
    case 70..79:
        return capitalize(QueryPronoun(WER))+" fuehlte sich heute schon besser.\n";
    case 80..89:
        return capitalize(QueryPronoun(WER))+" ist schon etwas geschwaecht.\n";
  }
  //fall-through
  return capitalize(QueryPronoun(WER))+" ist absolut fit.\n";
}

varargs string long() {
  string str, cap_pronoun;
  string descr, invl,tmp,exl;
  int hpnt, max_hpnt;
  mixed filter_ldfied;
  object ob;

  str = process_string( QueryProp(P_LONG) );
  if(!stringp(str)) str = "";

  str += condition();

  // Extralook
  if(stringp(tmp = QueryProp(P_EXTRA_LOOK)))
    str += tmp;
  if (stringp(tmp = QueryProp(P_INTERNAL_EXTRA_LOOK)))
    str += tmp;
  foreach(ob : QueryProp(P_EXTRA_LOOK_OBS))
  {
    if(objectp(ob) && environment(ob)==ME)
    {
      exl=ob->QueryProp(P_EXTRA_LOOK);
      if(stringp(exl) && sizeof(exl))
      {
        exl=replace_personal(exl, ({ME}), 1);
        // Ist das letzte Zeichen kein \n, brechen wir um.
        if(exl[<1]!='\n')
        {
          exl=break_string(exl,78);
        }
        str += exl;
      }
      else if(stringp(exl = ob->extra_look()))
      {
        str += exl; // TO BE REMOVED
      }
    }
    else
    {
      // Bereinigen
      SetProp(P_EXTRA_LOOK_OBS,QueryProp(P_EXTRA_LOOK_OBS)-({ob}));
    }
  }
  
  if(filter_ldfied = QueryProp(P_TRANSPARENT))
  {
    invl = make_invlist(PL, all_inventory(ME));
    if(invl != "")
      str += capitalize(QueryPronoun(WER))+" traegt bei sich:\n" + invl;
  }
  return str;
}

varargs string name(int casus, int demonst)
{ 
  if( QueryProp( P_INVIS ) )
  {
    if( casus == RAW ) return "Jemand";
    return ({"Jemand","Jemands","Jemandem","Jemanden"})[casus];
  }
  if (QueryProp(P_FROG) && casus != RAW )
  {
    string s=QueryArticle(casus, 0, 1)+"Frosch";
    if (casus==WESSEN) s += "es";
    return s;
  }
  return ::name( casus, demonst );
}

static int _query_gender()
{
  if (QueryProp(P_FROG)) return 1;
  return Query(P_GENDER);
}

// NPC sollen aus Kompatibilitaetsgruenden auch eine "echte" Rasse haben.
// Default ist hier die Rasse, man kann aber hiermit auch einen NPC faken,
// der sich tarnt, indem man P_REAL_RACE per Hand setzt.
static string _query_real_race()
{
  return Query(P_REAL_RACE,F_VALUE)||QueryProp(P_RACE);
}

static <string|string*> _set_name(<string|string*> nm )
{
  string lvnam;
  if (pointerp(nm))
    lvnam = nm[WER];
  else
    lvnam = nm;
  set_living_name(lower_case(lvnam));
  return Set(P_NAME, nm, F_VALUE);
}

int _query_container()
{
  return 0;
}

int is_class_member(<string|string*> str) {
  // Keine Klasse, keine Mitgliedschaft ...
  if (!str || (!stringp(str) && !pointerp(str)) || str=="") 
      return 0;

  if (::is_class_member(str))
    return 1;

  if (stringp(str))
    str = ({str});

  // Rassen werden als implizite Klassen aufgefasst.
  // TODO: Pruefen, ob das unbedingt hart-kodiert sein muss.
  string race = QueryProp(P_RACE);
  if ( stringp(race) && member( str, lower_case(race) ) > -1 )
    return 1;
  else
    return 0;
}

mapping _query_material() {
  mixed res;

  if (mappingp(res=Query(P_MATERIAL)))
    return res;
  return ([MAT_MISC_LIVING:100]);
}

public void NotifyInsert(object ob, object oldenv)
{
  // Unterstuetzung dyn. Querymethoden (z.B. bei Kleidung, welche nur in
  // getragenem Zustand nen Extralook hat).
  if(stringp(ob->QueryProp(P_EXTRA_LOOK))
     || ob->Query(P_EXTRA_LOOK, F_QUERY_METHOD))
  {
    SetProp(P_EXTRA_LOOK_OBS,QueryProp(P_EXTRA_LOOK_OBS)+({ob}));
  }

  // Muss leider auch beachtet werden, sollte aber mal raus fliegen ...
  if(function_exists("extra_look",ob))
  {
    SetProp(P_EXTRA_LOOK_OBS,QueryProp(P_EXTRA_LOOK_OBS)+({ob}));
    catch(raise_error(
      "Obsolete lfun extra_look() in "+load_name(ob));
      publish);
  }
}

public void NotifyLeave(object ob, object dest)
{
  object *els=QueryProp(P_EXTRA_LOOK_OBS);
  if(member(els,ob)!=-1)
  {
    SetProp(P_EXTRA_LOOK_OBS, els-({ob}) );
  }
}
