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