Added public files

Roughly added all public files. Probably missed some, though.
diff --git a/std/living/attributes.c b/std/living/attributes.c
new file mode 100644
index 0000000..90027a4
--- /dev/null
+++ b/std/living/attributes.c
@@ -0,0 +1,671 @@
+// MorgenGrauen MUDlib
+//
+// living/attributes.c -- attributes for living objects
+//
+// $Id: attributes.c 8375 2013-02-12 21:52:58Z Zesstra $
+
+#include <sys_debug.h>
+
+// attribute handling
+//
+//   filter_ldfied: str, dex, con, int
+//
+// In den Attributen und Abilites werden Rassenspzifische und erworbene
+// Faehigkeiten (mit autoload-Eigenschaft) abgepseichert.
+//
+// Funktionen:
+//   SetAttribute( attr, val ) (Erzeuge und) setze das Attribut auf val.
+//   QueryAttribute( attr )    Gebe den Wert des Attributes zurueck.
+//
+//   Wenn ein Objekt eine Funktion _filterattr_<name> beitzt, wird beim Setzen
+//   des Attributes <name>, der vorgeschlagene Wert uebergeben und der von
+//   dieser Funktion zurueckgegebene gesetzt. (fuer ueberpruefungszwecke)
+//   Gleiches gilt fuer _filterabil_<name>.
+
+#pragma strict_types
+#pragma save_types
+#pragma range_check
+#pragma no_clone
+#pragma pedantic
+
+#define NEED_PROTOTYPES
+#include <thing/properties.h>
+#include <attributes.h>
+#include <player/gmcp.h>
+#undef NEED_PROTOTYPES
+
+#include <config.h>
+#include <properties.h>
+
+mapping attributes; // Dies sind die mit ZTs veraenderbaren Attribute
+mapping attributes_modifier; // Modifier sollen gespeichert werden
+nosave mixed* attributes_timed_mods; //P_TIMED_ATTR_MOD
+nosave mapping attributes_offsets; // Offsets NICHT speichern!
+nosave mapping used_attributes_offsets; // Zur Beschleunigung der Berechnung
+nosave object* all_modifiers; // objekte mit P_X/M_ATTR_MOD, P_X/M_HEALTH_MOD
+nosave object* invalid_modifiers; // objekte welche das limit ueberschreiten
+nosave int cumulative_mod; // bilanz der P_X/M_ATTR_MOD
+nosave int hp_off;
+nosave int sp_off;
+
+
+nomask public int SetTimedAttrModifier(string key, mapping modifier, 
+    int outdated, object dependent, mixed notify) {
+  if(!key || key=="" || !modifier || (outdated>0 && outdated<time()) || 
+      (notify && !stringp(notify) && !objectp(notify)) ) {
+    return TATTR_INVALID_ARGS;
+  }
+  
+  
+  if(member(attributes_timed_mods[TATTR_ENTRIES],key)) {
+    // change entry
+    attributes_timed_mods[TATTR_ENTRIES][key,TATTR_MOD]=modifier;
+    attributes_timed_mods[TATTR_ENTRIES][key,TATTR_OUTDATED]=outdated;
+    attributes_timed_mods[TATTR_ENTRIES][key,TATTR_DEPENDENT]=dependent;
+    attributes_timed_mods[TATTR_ENTRIES][key,TATTR_NOTIFY]=notify;
+  }
+  else {
+    // add entry
+    attributes_timed_mods[TATTR_ENTRIES]+=([key:modifier;outdated;dependent;notify]);
+  }
+  
+  // add outdate
+  if(outdated>0 && member(attributes_timed_mods[TATTR_OUTDATE],outdated)==-1)
+  {
+    attributes_timed_mods[TATTR_OUTDATE]+=({outdated});
+    attributes_timed_mods[TATTR_OUTDATE]=
+      sort_array(attributes_timed_mods[TATTR_OUTDATE],#'<);
+  }
+  
+  // add dependent
+  if(objectp(dependent))
+  {
+  	if(member(attributes_timed_mods[TATTR_DEPENDENTS],key))
+  	{
+	  attributes_timed_mods[TATTR_DEPENDENTS][key]=dependent;
+  	}
+  	else
+  	{
+          attributes_timed_mods[TATTR_DEPENDENTS]+=([key:dependent]);
+  	}
+  }
+  else
+  {
+  	// remove previously set dependent
+  	if(member(attributes_timed_mods[TATTR_DEPENDENTS],key))
+  	{
+	  attributes_timed_mods[TATTR_DEPENDENTS]-=([key]);
+  	}
+  }
+  
+  UpdateAttributes();
+
+  return TATTR_OK;
+}
+
+nomask public mapping QueryTimedAttrModifier(string key)
+{
+  int outdated;
+  object dependent;
+  mixed notify;
+  mapping mod;
+  
+  if(!key || key=="")
+  {
+    return ([]);
+  }
+
+  if(!member(attributes_timed_mods[TATTR_ENTRIES],key))
+  { 
+    return ([]);
+  }
+
+  mod=deep_copy(attributes_timed_mods[TATTR_ENTRIES][key,TATTR_MOD]);
+  outdated=attributes_timed_mods[TATTR_ENTRIES][key,TATTR_OUTDATED];
+  dependent=attributes_timed_mods[TATTR_ENTRIES][key,TATTR_DEPENDENT];
+  notify=attributes_timed_mods[TATTR_ENTRIES][key,TATTR_NOTIFY];
+  
+  return ([key:mod;outdated;dependent;notify ]);
+}
+
+nomask public int DeleteTimedAttrModifier(string key)
+{
+  if(!key || key=="")
+  {
+    return TATTR_INVALID_ARGS;
+  }
+
+  if(!member(attributes_timed_mods[TATTR_ENTRIES],key))
+  { 
+    return TATTR_NO_SUCH_MODIFIER;
+  }
+  
+  attributes_timed_mods[TATTR_DEPENDENTS]-=([key]);
+  attributes_timed_mods[TATTR_ENTRIES]-=([key]);
+  UpdateAttributes();
+  
+  return TATTR_OK;
+}
+
+nomask protected void attribute_hb()
+{
+  int now,i,k,update,outdated;
+  string* keys;
+  mapping tonotify;
+	
+  // initialize
+  now=time();
+  tonotify=([]);
+
+  keys=m_indices(attributes_timed_mods[TATTR_ENTRIES]);
+  
+  // delete outdated 
+  for(i=sizeof(attributes_timed_mods[TATTR_OUTDATE])-1;i>=0;i--)
+  {
+  	outdated=attributes_timed_mods[TATTR_OUTDATE][i];
+  	if(outdated>now)
+  	{
+  	  break;
+  	}
+  	
+  	for(k=sizeof(keys)-1;k>=0;k--)
+  	{
+  	  if(attributes_timed_mods[TATTR_ENTRIES][keys[k],TATTR_OUTDATED]==outdated)
+  	  {
+  	    // bei fehlendem notifier wurde das zum verhaengnis
+  	    // dank an gloinson
+  	    /*
+  	    if(objectp(attributes_timed_mods[TATTR_ENTRIES][keys[k],TATTR_NOTIFY]))
+  	    {
+  	    */
+  	    tonotify+=([keys[k]:attributes_timed_mods[TATTR_ENTRIES][keys[k],TATTR_NOTIFY]]);
+  	    //}
+  	    
+	    attributes_timed_mods[TATTR_DEPENDENTS]-=([keys[k]]);
+ 	    attributes_timed_mods[TATTR_ENTRIES]-=([keys[k]]);
+  	    keys-=({keys[k]});
+  	  }
+  	}
+  	
+  	attributes_timed_mods[TATTR_OUTDATE]-=({outdated});
+  }
+  
+  // delete depending
+  keys=m_indices(attributes_timed_mods[TATTR_DEPENDENTS]);
+  for(i=sizeof(keys)-1;i>=0;i--)
+  {
+  	if(!objectp(attributes_timed_mods[TATTR_DEPENDENTS][keys[i]]))
+  	{
+  	    // siehe oben
+  	    /*
+  	    if(objectp(attributes_timed_mods[TATTR_ENTRIES][keys[i],TATTR_NOTIFY]))
+  	    {
+  	    */
+  	    tonotify+=([keys[i]:attributes_timed_mods[TATTR_ENTRIES][keys[i],TATTR_NOTIFY]]);
+  	    //}
+
+	    attributes_timed_mods[TATTR_DEPENDENTS]-=([keys[i]]);
+ 	    attributes_timed_mods[TATTR_ENTRIES]-=([keys[i]]);
+  	    keys-=({keys[i]});
+  	}
+  }
+  
+  
+  // update
+  if(sizeof(tonotify))
+  {
+    UpdateAttributes();
+    call_out(#'notifyExpiredModifiers,0,tonotify);
+  }
+}
+
+nomask protected void notifyExpiredModifiers(mapping nots)
+{
+  int i;
+  string* keys;
+  while(remove_call_out(#'notifyExpiredModifiers)!=-1);
+  
+  if(!nots)
+  {
+    return;
+  }
+  
+  keys=m_indices(nots);
+  for(i=sizeof(nots)-1;i>=0;i--)
+  {
+  	if(nots[keys[i]] && 
+	    ( objectp(nots[keys[i]])||stringp(nots[keys[i]]) ) )
+  	{
+  	   call_other(nots[keys[i]],"NotifyTimedAttrModExpired",keys[i]);
+  	}
+  }
+}
+
+
+// invalide modifier benachrichtigen
+nomask protected void notifyInvalidModifiers() {
+
+  while(remove_call_out(#'notifyInvalidModifiers)!=-1);
+  
+  if(!invalid_modifiers) {
+    invalid_modifiers=({});
+  }
+  
+  call_other(invalid_modifiers,"NotifyXMAttrModLimitViolation");
+
+}
+
+
+// welche Modifier / modif. Objekte wirken nun?
+protected nomask void calculate_valid_modifiers() {
+  closure qp;
+  mapping res;	
+  string key;	
+  int wert;
+  // Unterscheidung Bonus <-> Malus, weil der Malus voll eingehen soll	
+  int hp_malus, sp_malus;
+ 
+  used_attributes_offsets=([]);
+  cumulative_mod=0;
+  hp_off=sp_off=0;
+  invalid_modifiers=({});
+
+  // rassenspezifische boni P_ATTRIBUTES_OFFSETS  
+  if ( mappingp(attributes_offsets) )
+    used_attributes_offsets+=attributes_offsets;
+
+  if (!pointerp(all_modifiers) || !sizeof(all_modifiers)) {
+    // in diesem Fall koennen wir hier direkt mit dieser Funktion Schluss
+    // machen. ;-)
+    return;
+  }
+  else
+    all_modifiers-=({0}); //zerstoerte Objekte rauswerfen.
+    
+  // einmal ueber alle modifizierenden Objekt iterieren und aufaddieren
+  foreach(object ob: all_modifiers) {
+    qp = symbol_function("QueryProp",ob);
+ 
+    if (!objectp(ob) || environment(ob)!=this_object()) {
+      all_modifiers-=({ob});
+      continue;
+    }
+ 		
+    // ext. Attribut-Modifier
+    if ( mappingp(res=funcall(qp,P_X_ATTR_MOD)) ) {		
+      foreach(key, wert: res) {
+        cumulative_mod+=wert;
+      }
+    }
+
+    // magic Attribut-Modifier
+    if ( mappingp(res=funcall(qp,P_M_ATTR_MOD))
+        && ( funcall(qp,P_WORN)
+            || funcall(qp,P_WIELDED) ) ) {		
+      foreach(key, wert: res) {
+        cumulative_mod+=wert;
+      }
+    }
+    // Magic Health-Modifier 		
+    if ( mappingp(res=funcall(qp,P_M_HEALTH_MOD))
+        && ( funcall(qp,P_WORN)
+            || funcall(qp,P_WIELDED) ) ) {
+      if (res[P_HP] < 0)
+        hp_malus += res[P_HP];
+      else
+        hp_off+=res[P_HP];
+
+      if (res[P_SP] < 0)
+        sp_malus += res[P_SP];
+      else
+        sp_off+=res[P_SP];
+      }
+	      
+    // external Health Modifier
+    if ( mappingp(res=funcall(qp,P_X_HEALTH_MOD)) ) {
+      if (res[P_HP] < 0)
+        hp_malus += res[P_HP];
+      else
+        hp_off+=res[P_HP];
+
+      if (res[P_SP] < 0)
+        sp_malus += res[P_SP];
+      else
+        sp_off+=res[P_SP];	    
+    }	
+  
+  } // Ende 1. foreach()
+  
+ 
+  // und nochmal, soviele Objekt wieder rausschmeissen, bis das Limit wieder
+  // unterschritten wird. (Verbesserungsvorschlaege erwuenscht.) :-(
+  foreach(object ob: all_modifiers) {
+
+    qp = symbol_function("QueryProp",ob);
+ 
+    if ( mappingp(res=funcall(qp,P_X_ATTR_MOD)) ) {
+      if(cumulative_mod>CUMULATIVE_ATTR_LIMIT) { 
+        invalid_modifiers+=({ob});	  
+	foreach(key, wert: res) {
+          cumulative_mod-=wert;
+        }
+      }
+      else {
+        add_offsets(res);
+      }
+    }
+
+    if ( mappingp(res=funcall(qp,P_M_ATTR_MOD))
+        && ( funcall(qp,P_WORN)
+            || funcall(qp,P_WIELDED) ) ) {
+      if(cumulative_mod>CUMULATIVE_ATTR_LIMIT) {     
+        if(member(invalid_modifiers,ob)==-1) {
+          invalid_modifiers+=({ob});
+        }			
+	foreach(key, wert: res) {
+          cumulative_mod-=wert;
+        }
+      }
+      else {
+        add_offsets(res);
+      }
+    }
+  }
+
+  // HEALTH_MOD werden durch eine Formel 'entschaerft', damit man nur schwer
+  // das Maximum von 150 erreichen kann. (Formel von Humni, beschlossen auf 3.
+  // EM-Treffen)
+  // Mali gehen aber voll ein
+  hp_off = (int)(150 - (150*150.0/(150 + hp_off))) + hp_malus;
+  sp_off = (int)(150 - (150*150.0/(150 + sp_off))) + sp_malus;
+
+  /* alte Version
+    hp_off += hp_malus;
+    sp_off += sp_malus;
+  */
+ 
+  // notify invalid modifiers
+  if(sizeof(invalid_modifiers)>0) {
+    call_out(#'notifyInvalidModifiers,0);
+  }
+}
+
+// abmelden eines modifiers 
+nomask public void deregister_modifier(object modifier)
+{ 
+  if (!pointerp(all_modifiers)) {
+    return;
+  }
+
+  // valid object?
+  if (!objectp(modifier) || member(all_modifiers,modifier)==-1) {
+    return;
+  }
+  
+  all_modifiers-=({modifier});
+  if (invalid_modifiers) {
+    invalid_modifiers-=({modifier});
+  }
+}
+
+// anmelden eines modifiers 
+nomask public void register_modifier(object modifier) { 
+  closure qp;
+  
+  if (!pointerp(all_modifiers)) {
+    all_modifiers=({});
+  }
+
+  // valid object?
+  if (!objectp(modifier) || environment(modifier)!=this_object() || 
+      member(all_modifiers,modifier)!=-1) {
+    return;
+  }
+  
+  qp = symbol_function("QueryProp",modifier);
+  // modifier after all? Die P_M_* muessen getragen/gezueckt sein.
+  if(mappingp(funcall(qp,P_X_ATTR_MOD)) ||
+     mappingp(funcall(qp,P_X_HEALTH_MOD)) ||
+    ((mappingp(funcall(qp,P_M_ATTR_MOD)) ||
+       mappingp(funcall(qp,P_M_HEALTH_MOD))) &&
+      (funcall(qp,P_WORN) || funcall(qp,P_WIELDED)) ) ) {
+    all_modifiers+=({modifier});
+  }
+}
+
+protected void add_offsets(mapping arr) {
+  mixed *ind;
+  int i;
+  
+  if ( !mappingp(arr) )
+    return;
+
+  foreach(string key, int wert: arr) {
+    used_attributes_offsets[key]+=wert;
+  }
+}
+
+public void UpdateAttributes() {
+  mixed   *ind;
+  int     i;
+  
+  // alle gueltigen Modifier ermitteln aus Objekten im Inventar.
+  calculate_valid_modifiers();
+
+  // persistente modifier drauf (frosch zb)
+  // aus P_ATTRIBUTES_MODIFIERS
+  if ( mappingp(attributes_modifier) ) {
+    foreach(mixed key, mapping wert: attributes_modifier) {
+      add_offsets(wert); // Modifier addieren...		
+    }
+  }
+  // timed modifier drauf aus P_TIMED_ATTR_MOD
+  ind=m_indices(attributes_timed_mods[TATTR_ENTRIES]);
+  for ( i=sizeof(ind)-1 ; i>=0 ; i-- ) {
+    // Modifier addieren...
+    add_offsets(attributes_timed_mods[TATTR_ENTRIES][ind[i],0]);
+  }
+  // Bei Monstern werden die HP/SP ueblicherweise selbst gesetzt
+  if ( !query_once_interactive(this_object()))
+    return;
+
+  SetProp(P_MAX_HP, QueryAttribute(A_CON)*8+42+hp_off);
+  SetProp(P_MAX_SP, QueryAttribute(A_INT)*8+42+sp_off);
+  
+  if(QueryProp(P_HP)>QueryProp(P_MAX_HP)) {
+    SetProp(P_HP,QueryProp(P_MAX_HP));
+  }
+  
+  if(QueryProp(P_SP)>QueryProp(P_MAX_SP)) {
+    SetProp(P_SP,QueryProp(P_MAX_SP));
+  }
+
+  GMCP_Char( ([ A_INT: QueryAttribute(A_INT),
+                A_DEX: QueryAttribute(A_DEX),
+                A_STR: QueryAttribute(A_STR),
+                A_CON: QueryAttribute(A_CON) ]) );
+}
+
+
+protected void create() {
+  hp_off=sp_off=0;
+  used_attributes_offsets=([]);
+  all_modifiers=({});
+  invalid_modifiers=({});
+  cumulative_mod=0;
+  
+  Set(P_ATTRIBUTES_MODIFIER, attributes_modifier=([])); // nicht geschuetzt
+  Set(P_ATTRIBUTES_OFFSETS, attributes_offsets=([]));
+  Set(P_ATTRIBUTES_OFFSETS, PROTECTED, F_MODE);
+  Set(P_ATTRIBUTES, attributes=([]));
+  Set(P_ATTRIBUTES, PROTECTED, F_MODE);
+
+  Set(P_TIMED_ATTR_MOD, attributes_timed_mods=({ ({}),([]),([]) }));
+  Set(P_TIMED_ATTR_MOD, NOSETMETHOD|SECURED, F_MODE_AS);
+}
+
+static mixed _query_timed_attr_mod() {
+  mixed ret;
+  return Set(P_TIMED_ATTR_MOD,	    
+      ({attributes_timed_mods[0],
+	deep_copy(attributes_timed_mods[1]),
+	deep_copy(attributes_timed_mods[2])}));
+}
+
+static mapping _set_attributes(mapping arr) 
+{
+  Set(P_ATTRIBUTES, attributes=arr);
+  UpdateAttributes();
+  return arr;
+}
+
+static mapping _query_attributes() 
+{
+  return deep_copy(Set(P_ATTRIBUTES, attributes)); 
+}
+
+static mapping _set_attributes_offsets(mapping arr) 
+{
+  Set(P_ATTRIBUTES_OFFSETS, attributes_offsets=arr);
+  UpdateAttributes();
+  return attributes_offsets;
+}
+
+static mapping _query_attributes_offsets() 
+{ 
+  return deep_copy(Set(P_ATTRIBUTES_OFFSETS, attributes_offsets));
+}
+
+static mixed _set_attributes_modifier(mixed arr) 
+{ string fn;
+  mixed pre;
+  mapping map_ldfied;
+  
+  if ( pointerp(arr) && (sizeof(arr)>=2) )
+  {
+    pre=arr[0];
+    map_ldfied=arr[1];
+  }
+  else 
+  {
+    pre=previous_object();
+    map_ldfied=arr;
+  }
+
+  if ( objectp(pre) )
+    fn=old_explode(object_name(pre),"#")[0];
+  else
+    fn=pre;
+
+  if ( !stringp(fn) )
+    return 0;
+
+  // wenn Modifier kein mapping oder ein leeres Mapping: loeschen
+  if ( !mappingp(map_ldfied) || !sizeof(map_ldfied))
+    m_delete(attributes_modifier,fn);
+  else
+    attributes_modifier[fn]=map_ldfied;
+
+  Set(P_ATTRIBUTES_MODIFIER, attributes_modifier);
+  UpdateAttributes();
+  return attributes_modifier[fn];
+}
+
+static mapping _query_attributes_modifier() 
+{
+  return deep_copy(attributes_modifier);  
+}
+
+public int SetAttr(string attr, int val) 
+{ closure filter_ldfied;
+
+  if ( filter_ldfied = symbol_function("_filterattr_"+attr, this_object()) ) 
+    val = funcall(filter_ldfied, val );
+
+  attributes[attr] = val;
+  UpdateAttributes();
+  return val;
+}
+
+public int SetAttribute(string attr, int val) 
+{
+  return SetAttr(attr, val-used_attributes_offsets[attr]);
+}
+
+// Diese Funktion sollte zum Abfragen verwendet werden:
+public int QueryAttribute(string attr) 
+{ int re;
+
+  re=attributes[attr]+used_attributes_offsets[attr];
+
+  if ( query_once_interactive(this_object()) && (re>30) )
+    re=30;
+
+  return re;
+}
+
+public int QueryRealAttribute(string attr) 
+{
+  return attributes[attr];
+}
+
+public int SetRealAttribute(string attr, int val) 
+{
+  return SetAttr(attr, val);
+}
+
+public int QueryAttributeOffset(string attr) 
+{
+  return used_attributes_offsets[attr];
+}
+
+public status TestLimitViolation(mapping check)
+{
+  int k,test;
+  mixed* ind;
+    
+  if(!check || !mappingp(check))
+  {
+    return 0;
+  }
+
+  test=0;
+  ind=m_indices(check);
+  for( k=sizeof(ind)-1 ; k>=0 ; k-- )
+  {
+    test+=check[ind[k]];
+  }
+  
+  test+=cumulative_mod;
+  if(test>CUMULATIVE_ATTR_LIMIT)
+  {
+    return 1;
+  }
+  
+  return 0;
+}
+
+/*
+ *------------------------------------------------------------
+ * attributes compatibility functions
+ */
+
+protected int _filterattr_str(int val)
+{
+  return ( (val<0) ? 0 : (val>20) ? 20 : val );
+}
+
+protected int _filterattr_dex(int val)
+{
+  return ( (val<0) ? 0 : (val>20) ? 20 : val );
+}
+
+protected int _filterattr_int(int val)
+{
+  return ( (val<0) ? 0 : (val>20) ? 20 : val );
+}
+
+protected int _filterattr_con(int val)
+{
+  return ( (val<0) ? 0 : (val>20) ? 20 : val );
+}