// MorgenGrauen MUDlib
//
// unit.c -- Basisklasse fuer Mengenobjekte
//           (neue Version von Padreic)
//
// $Id: unit.c 9077 2015-01-16 23:26:00Z Zesstra $
#pragma strong_types,save_types,rtt_checks
#pragma range_check
#pragma no_clone

inherit "/std/thing";

#define NEED_PROTOTYPES
#include <unit.h>
#undef NEED_PROTOTYPES

#include <properties.h>
#include <thing/properties.h>
#include <defines.h>
#include <language.h>
#include <moving.h>
#include <wizlevels.h>
#include <debug_info.h>

// zum debuggen und extra public
public string debugmode;
public string __set_debug(string recv) {return debugmode=recv;}
#include <living/comm.h>
#define ZDEBUG(x) if (stringp(debugmode) && find_player(debugmode)) \
  find_player(debugmode)->ReceiveMsg(x,MT_DEBUG,0,object_name()+": ",ME)
//#define ZDEBUG(x)

private void _call_DoDecay(object *klone);

private nosave string lastverb;
private nosave int lastevalnumber;

protected void create()
{
  ::create();
  SetProp(U_IDS,({({}),({})}));
  SetProp(P_GENDER, 1);
  SetProp(P_AMOUNT, 1);
  // Props sollten nicht direkt manipuliert werden, nur ueber Set-Methoden
  Set(P_UNIT_DECAY_INTERVAL, PROTECTED, F_MODE_AS);
  Set(P_UNIT_DECAY_QUOTA, PROTECTED, F_MODE_AS);
} 

protected void create_super() {
  set_next_reset(-1);
}

//// Query und Set Funktionen fuer die Propertys

static void check_leave()
{  if (Query(P_AMOUNT,F_VALUE)<1) remove(1);  }

static int _query_invis()
{
  if (QueryProp(P_AMOUNT) < 1)
    return 1;
  return Query(P_INVIS, F_VALUE);
}

static int _set_amount(int am)
{
  if (am<1)
    call_out("check_leave",1);
  SetProp(U_REQ, am);
  return Set(P_AMOUNT,am, F_VALUE);
}

static int _set_u_req(int ureq)
{
  lastverb = query_verb();
  lastevalnumber = debug_info(DINFO_EVAL_NUMBER);
  return Set(U_REQ, ureq, F_VALUE);
}

static int _query_u_req()
{
  // Zwei Dinge benutzten, um zu entscheiden, ob U_REQ noch gueltig ist oder
  // besser auf P_AMOUNT zurueckgesetzt werden sollte: die DINFO_EVAL_NUMBER
  // und das Kommandoverb. Wenn eines von beiden sich geaendert hat, wird
  // U_REQ als ungueltig betrachtet. (Und dies bleibt ein uebler Hack.)
  if (lastevalnumber != debug_info(DINFO_EVAL_NUMBER)
      || lastverb != query_verb())
  {
    return SetProp(U_REQ, Query(P_AMOUNT, F_VALUE));
  }
  return Query(U_REQ, F_VALUE);
}

// Gesamtwert der gerade mit U_REQ ausgewaehlten unitobjekte
static int _query_value()
{
  mixed cpu;
  cpu=Query(U_CPU);
  if (intp(cpu)) return QueryProp(U_REQ) * cpu;
  if (!pointerp(cpu)) return 0;
  return (QueryProp(U_REQ) * cpu[0])/cpu[1];
}

static int _set_value(int num) {
// Setzt den Wert fuer die derzeitige Anzahl
  SetCoinsPerUnits(num, QueryProp(U_REQ));
  return QueryProp(P_VALUE);
}

static int _query_weight()
{
  int req = QueryProp(U_REQ);
  if (req<1)
    return 0;
  int|int* gpu=Query(U_GPU, F_VALUE);
  if (pointerp(gpu))
    return MAX(1,(req*gpu[0])/gpu[1]);
  return req * gpu;
}

static int _set_weight(int num) {
// Setzt das Gewicht fuer die derzeitige Anzahl
    SetGramsPerUnits(num, QueryProp(U_REQ));
    return QueryProp(P_WEIGHT);
}

static int _query_total_weight()
{
  int amount = Query(P_AMOUNT);
  if (amount<1)
    return 0;
  int|int* gpu=Query(U_GPU, F_VALUE);
  if (pointerp(gpu))
    return MAX(1,(amount*gpu[0])/gpu[1]);
  return amount*gpu;
}

static int _query_plural()
{
  int i = QueryProp(U_REQ);
  return (i<=1 ? 0 : i);
}

// gibt string | string* zurueck.
static string|string* _query_name()
{
  if (QueryProp(U_REQ)==1)
    return "%s%s"+Query(P_NAME)[0];
  return "%d %s"+Query(P_NAME)[1];
}

// gibt string | string* zurueck.
static string|string*  _set_name(mixed names)
{
  if(!names)
    return Set(P_NAME,({"",""}));
  if(stringp(names))
    return Set(P_NAME,({names,names}));
  if(pointerp(names))
    switch(sizeof(names)) {
      case 0:  return Set(P_NAME,({"",""}));
      case 1:  if(!stringp(names[0]))
                 names[0]="";
               return Set(P_NAME,({names[0],names[0]}));
      default: if(!stringp(names[0]))
                 names[0]="";
               if(!stringp(names[1]))
                 names[1]="";
               return Set(P_NAME,names[0..1]);
    }
  return QueryProp(P_NAME);
}

// die Funktionen

void AddSingularId(mixed str)
{
  string **ids=Query(U_IDS);
  if (!pointerp(str))
    str=({str});
  Set(U_IDS,({ids[0]+str,ids[1]}));
}

void RemoveSingularId(mixed str)
{ 
  if(stringp(str))
    str=({str});
  if(pointerp(str))
    Set(U_IDS,({Query(U_IDS)[0]-str,Query(U_IDS)[1]}));
}
 
void AddPluralId(mixed str)
{
  string **ids;
  if (!pointerp(str))
    str=({str});
  ids=Query(U_IDS);
  Set(U_IDS,({ids[0],ids[1]+str}));
}

void RemovePluralId(mixed str)
{ 
  if(stringp(str))
    str=({str});
  if(pointerp(str))
    Set(U_IDS,({Query(U_IDS)[0],Query(U_IDS)[1]-str}));
}

void SetCoinsPerUnits(int coins,int units)
{
  if (coins<0||units<=0) return;
  if (units==1)
    Set(U_CPU, coins);
  else Set(U_CPU,({coins,units}));
}

void SetGramsPerUnits(int grams, int units)
{
  if (grams<0||units<=0) return;
  if (units==1)
    Set(U_GPU, grams);
  else Set(U_GPU,({grams,units}));
}

int *QueryCoinsPerUnits()
{
  mixed cpu;
  cpu=Query(U_CPU);
  if (intp(cpu)) return ({ cpu, 1 });
  return cpu;
}

int *QueryGramsPerUnits()
{
  mixed gpu;
  gpu=Query(U_GPU);
  if (intp(gpu)) return ({ gpu, 1 });
  return gpu;
}

void AddAmount(int am) {
  SetProp(P_AMOUNT, am+Query(P_AMOUNT));
}

int IsUnit() {
  return 1;
}

int IsEqual(object ob)
// haben ob und dieses Objekte die gleiche Blueprint?
{
  if (ob==this_object()) return 0; // das ist ZU gleich :)
  return (BLUE_NAME(ME)==BLUE_NAME(ob));
}

// ueberschreiben von Standardmethoden

varargs string name(int fall, int demo)
{
  int req;
  mixed n_adj;
  string adj;

  if ((req=QueryProp(U_REQ))<1) return 0;
  if (fall!=RAW && 
      pointerp(n_adj=QueryProp(P_NAME_ADJ)) && sizeof(n_adj) )
    adj = implode(map(n_adj, #'DeclAdj, fall, demo && req==1), "");
  else
    adj = "";

  if (req==1)
    return sprintf(QueryProp(P_NAME),
                   (fall==RAW || !QueryProp(P_ARTICLE) 
                    ? "" : QueryArticle(fall,demo,1)), adj) /* +korrektur */;

  if (fall!=WEM)
    return sprintf(QueryProp(P_NAME), req, adj);
  else {
     int last;
     last=Query(P_NAME)[1][<1];
     return sprintf(QueryProp(P_NAME), req, adj)
                  +(last!='s' && last!='n' ? "n" : "");
  }
}

varargs string QueryPronoun(int casus)
{
  if (QueryProp(U_REQ)==1)
    return ::QueryPronoun(casus);
  switch(casus) {
    case WESSEN: return "ihrer";
    case WEM:    return "ihnen";
    //default:     return "sie";
  }
  return("sie"); //fall-through
}

string short()
{
  if (QueryProp(U_REQ)<1 || QueryProp(P_INVIS)) return 0;
  return capitalize(name(WER,0))+".\n";
  /*
  if (req>1) return sprintf(QueryProp(P_NAME), req)+".\n";
  return capitalize(sprintf(QueryProp(P_NAME), QueryArticle(WER,0,1)))+".\n";
  */
}

varargs string long()
{
  return (QueryProp(P_LONG) ? process_string(QueryProp(P_LONG)) : "")+
    sprintf("Du siehst %s.\n",name(WEN));
}

varargs int id(string str,int lvl)
{

  string s1,s2,**ids;
  int i;

  if (!str) return 0;
  
  // Wenn kein pos. Amount, hat dieses Objekt keine IDs mehr, damit es nicht
  // mehr ansprechbar ist.
  int amount=QueryProp(P_AMOUNT);
  if (amount < 1)
    return 0;

  if (::id(str)) {
    SetProp(U_REQ, Query(P_AMOUNT,F_VALUE));
    return 1;
  }

  ids=Query(U_IDS);
  if (!ids)
    return 0;

  if (match_item(str, ids[1] )) {
    SetProp(U_REQ, amount);
    return 1;
  }
  if (match_item(str, ids[0] )) {
    SetProp(U_REQ,1);
    return 1;
  }
  if (sscanf(str,"%s %s",s1,s2) && s1[0..3]=="alle" && 
    match_item(s2, ids[1] )) {
    SetProp(U_REQ, amount);
    return 1;
  }
  if (sscanf(str,"%d %s",i,s1)==2 && i==1 && match_item(s1, ids[0] )) {
    SetProp(U_REQ,1);
    return 1;
  }
  if (sscanf(str,"%d %s",i,s1)==2 && match_item(s1, ids[1] ) && 
      i<=amount && i>0) {
    SetProp(U_REQ,i);
    return 1;
  }
  return 0;
}

// Status fuer move... *seufz*
int _orig_amount, _move_requested;

varargs int move(object|string dest,int method)
{
  _orig_amount = QueryProp(P_AMOUNT);
  // Wenn M_MOVE_ALL gesetzt ist, wird IMMER ALLES bewegt.
  if (method & M_MOVE_ALL)
    _move_requested = _orig_amount;
  else
    _move_requested = QueryProp(U_REQ);

  ZDEBUG(sprintf("move from %O to %O: amount %d, req %d\n",environment(),dest,_orig_amount,_move_requested));
  // Wenn nicht alles bewegt werden soll, wird die Menge dieses Objektes
  // erstmal reduziert und bewegt. Erst nach der Bewegung wird der Rest dann
  // im alten Environment neu erzeugt.
  if ( _orig_amount > _move_requested )
  {
     // wenn in einem alten Paket das Gewicht noch nicht neu berechnet
     // wurde muss dies geschehn solange die Muenzen im Paket noch das
     // volle Gewicht haben...
     if ( environment() )
         environment()->query_weight_contents();
     // ab jetzt nur auf <_move_requested> Einheiten arbeiten
     Set( P_AMOUNT, _move_requested, F_VALUE);
     ZDEBUG(sprintf("move: amount set to %d\n",_move_requested));
  }

  int res = ::move( dest, method );

  if ( res != MOVE_OK )
  {
      // Fehlgeschlagene Bewegung ist doof.
      // ggf. verfruehte Aenderung (P_AMOUNT oben auf <U_REQ> Einheiten
      // reduziert) rueckgaengig machen
      Set( P_AMOUNT, _orig_amount, F_VALUE );
      ZDEBUG(sprintf("move: not OK, amount restored to %d\n",_orig_amount));
      return res;
  }

  // TODO: eigentlich sollte es nicht passieren, dass die Menge jetzt negagtiv
  // ist. Aber bei Geld kann es durch vereinigen mit Geldboerse/Geldkarten
  // passieren und das ist kein Fehler. Koennte man evtl. mal differenziert
  // pruefen.
  int finalamount= QueryProp(P_AMOUNT);
  /*if ( finalamount < 1 )
  {
    ZDEBUG(sprintf("move: zerstoerung, amount %d\n",finalamount));
    remove(1);
    return ME_WAS_DESTRUCTED;
  }
  */
  ZDEBUG(sprintf("move: OK, amount %d\n",finalamount));
  return res;
}


protected void NotifyMove(object dest, object oldenv, int method)
{
  // Erst einen evtl. nicht zu bewegenden Rest im alten Environment wieder erzeugen.
  if (oldenv && _orig_amount > _move_requested)
  {
      if ( oldenv == dest )
      {
          // Objekt wurde nur an den Anfang des inventory bewegt, sonst nichts.
          // ggf. verfruehte Aenderung (oben auf <req> Einheiten reduziert)
          // rueckgaengig machen
          ZDEBUG(sprintf("move: same env, amount restored to %d\n",_orig_amount));
          Set( P_AMOUNT, _orig_amount, F_VALUE );
      }
      else
      {
        // verbleibende Einheiten in einem neuen Objekte wieder zurueck ins
        // alte Environment zurueck bewgen
          object temp;
          temp = clone_object(BLUE_NAME(ME));
          temp->SetProp( P_AMOUNT, _orig_amount-_move_requested );
          temp->move( oldenv, M_NOCHECK );
          ZDEBUG(sprintf("move: Restmenge im alten Env erzeugt, amount %d\n",_orig_amount-_move_requested));
      }
  }

  // Und jetzt ggf. mit den anderen Units gleichen Typs im neuen Environment
  // vereinigen.
  foreach(object item: all_inventory(environment()))
  {
      if ( IS_EQUAL(item) )
      {
        // Es ist ein Feature, dass auch mit Objekten mit negativen Amount
        // vereinigt wird.
        ZDEBUG(sprintf("move: vereinige mit %O (%d)\n",
               item,item->QueryProp(P_AMOUNT)));
        int mergedamount = QueryProp(P_AMOUNT) + item->QueryProp(P_AMOUNT);
        item->Set( P_AMOUNT, 0, F_VALUE);
        item->remove(1);

        SetProp( P_AMOUNT, mergedamount);
        // U_REQ ist jetzt auch zurueckgesetzt.

        ZDEBUG(sprintf("move: nach vereinigung, amount %d\n",mergedamount));
      }
  }

  // wenn man in frisch geclonten Units die noch kein environment haben
  // per Hand U_REQ auf einen Wert != P_AMOUNT setzt, so gehen die
  // restlichen Einheiten  verloren (es gibt kein Environment, in das man die
  // Resteinheiten zurueck bewegen koennte).

  // Und jetzt mal Decaykrams machen...

  // wenn NO_DECAY_UNTIL_MOVE an ist und dieses ein Move ist, was von einem
  // Env in ein anderes Env geht, loeschen. Nicht geloescht wird
  // hingegen, wenn das move() in das allererste Env erfolgt (nach dem Clonen)
  if ( (QueryProp(P_UNIT_DECAY_FLAGS) & NO_DECAY_UNTIL_MOVE)
      && objectp(dest) && objectp(oldenv) && dest != oldenv)
    SetProp(P_UNIT_DECAY_FLAGS, 
        QueryProp(P_UNIT_DECAY_FLAGS) & ~NO_DECAY_UNTIL_MOVE );
  ::NotifyMove(dest, oldenv, method);
}


void reset() {
  if (!clonep(ME)) {
    // Blueprint ist Master fuer zerfallende Unitobjekte
    // das Decay sollte besser nicht durch manuellen Aufruf in der BP
    // ausgeloest werden, daher Pruefung hier (PO == ME, falls der Reset vom
    // Driver kommt).
    if (previous_object() && previous_object() != ME)
      return; 
    int zeit = QueryProp(P_UNIT_DECAY_INTERVAL);
    if (zeit > 0)
    {
      set_next_reset(zeit);
      // Das Callout muss auf jeden Fall gemacht werden, wenn ein Decay
      // Intervall gesetzt ist, damit die Blueprint auch den naechsten Reset
      // kriegt, auch wenn es jetzt keine Clone gibt. Wenn es kein Quota gibt,
      // kann der Callout wegfallen, beim Setzen eines Quota wird ja eine
      // Funktion an diesem Objekt gerufen.
      if (QueryProp(P_UNIT_DECAY_QUOTA) > 0)
        call_out(#'_call_DoDecay, 1, 0);
    }
  }
  else {
    // Clones
    if (Query(P_AMOUNT,F_VALUE)<1) remove(1);
    else ::reset();
  }
}

varargs int remove(int silent)
{
  int amount = QueryProp(P_AMOUNT);
  int req = QueryProp(U_REQ);
  if (amount > req)
  {
    ZDEBUG(sprintf("remove: reduziere amount %d um %d -> %d\n",
           amount, req, amount-req ));
    SetProp(P_AMOUNT, amount - req);
    return 1;
  }
  ZDEBUG(sprintf("remove: restlos weg.\n"));
  return ::remove(silent);
}

// sollte nicht von aussen gerufen werden.
private void _call_DoDecay(object *klone) {
  ZDEBUG(sprintf("call_DoDecay() in %O\n",ME));
  // Clone oder kein Decay konfiguriert?
  if (clonep()
      || QueryProp(P_UNIT_DECAY_FLAGS) & NO_DECAY)
    return;

  if (!pointerp(klone))
    klone = clones(2);
  // Klone da?
  int i=sizeof(klone);
  if (!i)
    return;

  // in allen Klonen DoDecay rufen
  while(get_eval_cost() > __MAX_EVAL_COST__/2 && i--) {
    if (objectp(klone[i]))
      catch(call_other(klone[i],"DoDecay", 0);publish);
  }
  // das i ist schon abgearbeitet.
  i--;
  // noch was uebrig?
  if (i >= 0)
    call_out(#'_call_DoDecay, 4, klone[0..i]);
}

// zerstoert quota Prozent der vorhandenen Units, liefert die Restmenge
// zurueck. Ruft ggf. DoDecayMessage()
public int DoDecay(int silent) {
  // nur fuer Clones
  if (!clonep())
    return 0;
  ZDEBUG(sprintf("DoDecay() in %O\n",ME));

  // wenn das Objekt NO_DECAY oder NO_DECAY_UNTIL_MOVE in den Flags
  // zerfaellt nix.
  int flags = QueryProp(P_UNIT_DECAY_FLAGS);
  if ((flags & NO_DECAY) || (flags & NO_DECAY_UNTIL_MOVE) )
    return QueryProp(P_AMOUNT);

  int quota = QueryProp(P_UNIT_DECAY_QUOTA);

  // Zugewinn ist nicht. Ausserdem kann nicht mehr zerfallen, als da ist...
  // Also ohne gueltiges Quota raus. Nur bei abs. Zerfall sind Zahlen > 10000
  // erlaubt, bei relativen Zerfall waere das sinnlos.
  if (quota <= 0 || 
      (quota > 10000 && !(flags & ABSOLUTE_DECAY) ) ) 
    return QueryProp(P_AMOUNT);
  
  int amount = QueryProp(P_AMOUNT);
  int minimum = QueryProp(P_UNIT_DECAY_MIN);
  // Zerfall nur, wenn man mehr als das Minimum hat.
  if (amount > minimum) {
    int zerfall;
    if (flags & ABSOLUTE_DECAY) {
      // Decay Quota soll einfach als abs. Zahl aufgefasst werden:
      zerfall = quota;
    }
    else if (flags & INACCURATE_DECAY) {
      // Rundungsfehler ignorieren und dafuer immer min. eine Einheit
      // zerfallen lassein
      zerfall = (amount * quota) / 10000;
      if (zerfall <= 0) zerfall = 1;
    }
    else {
      // Standardfall:
      // nicht-ganzzahligen Rest als Wahrscheinlichkeit fuer den Zerfall einer
      // Einheit auffassen
      float tmp = amount * quota / 10000.0;
      zerfall = to_int(tmp);
      tmp -= zerfall; // Rest in tmp
      // tmp*n ist eine Zahl zwischen 0 und n, wenn tmp*n > random(n)+1,
      // dann zerfaellt eine Einheit extra. Da das Random fuer grosse Zahlen
      // besser verteilt ist, nehm ich n = __INT_MAX__
      if (ceil(tmp * __INT_MAX__) > random(__INT_MAX__) + 1)
        zerfall++;
    }

    // nicht unter Minimum zerfallen
    if (amount - zerfall < minimum)
      zerfall = amount - minimum;

    // erst ggf. Meldung ausgeben.
    if (!silent && zerfall > 0)
      DoDecayMessage(amount, zerfall);
    // dann runtersetzen.
    SetProp(P_AMOUNT, amount - zerfall);
    ZDEBUG(sprintf("%O decayed by %d\n",ME, zerfall));
    return amount-zerfall;
  }
  else if (amount < 0)
    return 0; // neg. Anzahl gilt als "0 uebrig".
  
  // sonst ists wohl zwischen 0 und minimum, nix aendert sich.
  return amount;
}

// gibt die Zerfallsmeldung aus. Wenn man mit der Standardmeldung nicht zufrieden
// ist (duerfte der Normalfall sein), sollte man diese Funktion
// ueberschreiben. Bekommt bisherige und jetzt gerade zerfallene Menge
// uebergeben. Wichtig: zu diesem Zeitpunkt hat sich an der Unit noch nix (!)
// geaendert!
protected void DoDecayMessage(int oldamount, int zerfall) {
  if (oldamount == zerfall) {
    if (living(environment())) {
      tell_object(environment(), break_string(sprintf(
          "Auf einmal %s%s zu Staub!",
          (oldamount>1?"zerfallen Deine ":"zerfaellt D"), name(WER)),78));
    }
    // das tell_room() muss auf jeden fall sein, weil es "lebende" Raeume
    // gibt. Liegt der KRam in einem solchen wuerden die Livings in diesem Raum
    // sonst keine meldung kriegen.
    tell_room(environment(), break_string(sprintf(
          "Auf einmal %s %s zu Staub!",
          (oldamount>1?"zerfallen":"zerfaellt"), name(WER)),78),
        ({environment()}));
  }
  else {
     if (living(environment())) {
      tell_object(environment(), break_string(sprintf(
          "Auf einmal %s %d Deiner %s zu Staub!",
          (zerfall>1?"zerfallen":"zerfaellt"),
          zerfall, Query(P_NAME)[1]),78));
    }
    // das tell_room() muss auf jeden fall sein, weil es "lebende" Raeume
    // gibt. Liegt der KRam in einem solchen wuerden die Livings in diesem Raum
    // sonst keine meldung kriegen.
    tell_room(environment(), break_string(sprintf(
          "Auf einmal %s %d %s zu Staub!",
          (zerfall>1?"zerfallen":"zerfaellt"),
          zerfall, Query(P_NAME)[1]),78), ({environment()}) ); 
  }
}

static int _query_unit_decay_interval() {
  if (clonep()) {
    // fuer clones den Wert aus der BP liefern, der Wert in Clones ist eh
    // uninteressant.
    if (objectp(blueprint()))
      return blueprint()->QueryProp(P_UNIT_DECAY_INTERVAL);
    else
      return load_object(load_name())->QueryProp(P_UNIT_DECAY_INTERVAL);
  }
  return Query(P_UNIT_DECAY_INTERVAL);
}

static int _set_unit_decay_interval(int zeit) {
  // fuer Clones ist die Prop sinnlos und kann nicht gesetzt werden.
  if (clonep()) {
    if (objectp(blueprint()))
      return blueprint()->QueryProp(P_UNIT_DECAY_INTERVAL);
    else
      return load_object(load_name())->QueryProp(P_UNIT_DECAY_INTERVAL);
  }
  // ueber diese Prop liesse sich der Reset relativ beliebig veraendern,
  // verhindern, etc. Daher darf sie nur von diesem Objekt gesetzt werden, von
  // Weisen+ oder eines Objektes, das die gleiche UID hat wie dieses hier oder
  // des Programmieres dieses Objekts oder eines Magiers, der berechtigt fuer
  // die jeweilige UID ist. Letztere beiden werden ueber den Ruf von
  // QueryUIDsForWizard() ermittelt.
  // erstes fremdes Objekt finden und pruefen.
  foreach(object po: caller_stack(1)) {
    if (po != ME) {
      // fremden Aufrufer gefunden
      if (getuid(po) != getuid(ME) 
          && member(master()->QueryUIDsForWizard(getuid(po)),getuid(ME)) == -1
          && (!this_interactive() || !IS_ELDER(this_interactive()) ) )
        // unberechtigt, Abbruch
        return QueryProp(P_UNIT_DECAY_INTERVAL);
      else
        // nur das erste ext. Objekt in der Callkette wird geprueft, raus.
        break;
    }
  }
  set_next_reset(zeit);
  // falls dies aus dem create() gesetzt wird, muss zeitverzoegert eine
  // Funktion von aussen am Objekt gerufen werden, da nach einem create() das
  // Objekt als resettet gilt und sonst keinen Reset kriegt.
  call_out("_query_unit_decay_interval",1);
  return Set(P_UNIT_DECAY_INTERVAL, zeit, F_VALUE);
}

static int _query_unit_decay_quota() {
  if (clonep()) {
    // hat dieses Objekt einen eigenen wert gespeichert?
    int quota=Query(P_UNIT_DECAY_QUOTA, F_VALUE);
    if (quota)
      return quota;
    // sonst den Wert aus der Blueprint
    if (objectp(blueprint()))
      return blueprint()->QueryProp(P_UNIT_DECAY_QUOTA);
    else
      return load_object(load_name())->QueryProp(P_UNIT_DECAY_QUOTA);
  }
  return Query(P_UNIT_DECAY_QUOTA, F_VALUE);
}

static int _set_unit_decay_quota(int quota) { 
  // momentan nur quota zwischen 0 und 10000
  if (quota >= 0 && quota <=10000)
    return Set(P_UNIT_DECAY_QUOTA, quota, F_VALUE);
  else
    return Query(P_UNIT_DECAY_QUOTA, F_VALUE);
}

static int _query_unit_decay_min() {
  if (clonep()) {
    // hat dieses Objekt einen eigenen wert gespeichert?
    int minimum=Query(P_UNIT_DECAY_MIN, F_VALUE);
    if (minimum)
      return minimum;
    // sonst den Wert aus der Blueprint
    if (objectp(blueprint()))
      return blueprint()->QueryProp(P_UNIT_DECAY_MIN);
    else
      return load_object(load_name())->QueryProp(P_UNIT_DECAY_MIN);
  }
  return Query(P_UNIT_DECAY_MIN, F_VALUE);
}

static int _query_unit_decay_flags() {
  if (clonep()) {
    // hat dieses Objekt einen eigenen wert gespeichert?
    int flags=Query(P_UNIT_DECAY_FLAGS, F_VALUE);
    if (flags)
      return flags;
    // sonst den Wert aus der Blueprint
    if (objectp(blueprint()))
      return blueprint()->QueryProp(P_UNIT_DECAY_FLAGS);
    else
      return load_object(load_name())->QueryProp(P_UNIT_DECAY_FLAGS);
  }
  // Die BP liefert den Wert auf jeden Fall ohne NO_DECAY_UNTIL_MOVE zurueck,
  // weil dieses Flag im Falle der BP nicht zurueckgesetzt wird und bei Clients 
  // ohne eigene Flags der Zerfall stoppen wuerde.
  return Query(P_UNIT_DECAY_FLAGS, F_VALUE) & ~NO_DECAY_UNTIL_MOVE;
}

