diff --git a/std/thing/description.c b/std/thing/description.c
new file mode 100644
index 0000000..47bfb0e
--- /dev/null
+++ b/std/thing/description.c
@@ -0,0 +1,851 @@
+// MorgenGrauen MUDlib
+//
+// thing/description.c -- description handling for standard objects
+//
+// $Id: description.c 9561 2016-05-25 19:33:22Z Zesstra $
+
+#pragma strict_types
+#pragma save_types
+#pragma range_check
+#pragma no_clone
+#pragma pedantic
+
+#include <tls.h>
+#include <thing/description.h>
+#include <thing/material.h>
+#include <thing/lighttypes.h>
+#include <exploration.h>                  // wegen EPMASTER
+#include <class.h>
+
+#define NEED_PROTOTYPES
+#include <thing/properties.h>
+#include <thing/language.h>
+
+#undef NEED_PROTOTYPES
+#include <properties.h>
+
+// Variable um den FP abzuspeichern 
+private nosave mixed *explore;
+
+// Prototypen
+public string short();
+public varargs string long(int mode);
+
+//                       #####################
+//######################## System-Funktionen ############################
+//                       #####################
+
+// Objekt erzeugen
+protected void create()
+{
+  string poid, tpid;
+  object tp;
+
+  SetProp( P_NAME, "Ding" );
+  SetProp( P_SHORT, "Nichts besonderes" );
+  SetProp( P_LONG, 0 );
+
+  Set( P_ADJECTIVES, ({}) );
+  Set( P_NAME_ADJ, ({}) );
+  Set( P_IDS, ({}) );
+  Set( P_CLASS, ({}) );
+
+  Set( P_READ_DETAILS, ([]), F_VALUE);
+  Set( P_READ_DETAILS, SECURED|NOSETMETHOD, F_MODE_AS);
+
+  Set( P_DETAILS, ([]), F_VALUE);
+  Set( P_DETAILS, SECURED|NOSETMETHOD, F_MODE_AS );
+
+  Set( P_SMELLS, ([]), F_VALUE);
+  Set( P_SMELLS, SECURED|NOSETMETHOD, F_MODE_AS );
+
+  Set( P_SOUNDS, ([]), F_VALUE);
+  Set( P_SOUNDS, SECURED|NOSETMETHOD, F_MODE_AS );
+
+  Set( P_TOUCH_DETAILS, ([]), F_VALUE);
+  Set( P_TOUCH_DETAILS, SECURED|NOSETMETHOD, F_MODE_AS );
+
+  // Aenderungen an dieser Prop sind tabu.
+  Set( P_CLONE_TIME, NOSETMETHOD|SECURED, F_MODE_AS );
+
+  // Id des Cloners und des Besitzers kommen nach P_CLONER
+  if (objectp( tp=this_interactive()||this_player() ))
+  {
+    tpid=geteuid(tp);
+    if (!(tpid=geteuid(tp))) tpid=getuid(tp);
+  }
+  else
+    tpid="UNKNOWN";
+
+  if (previous_object())
+  {
+    if (!(poid = geteuid(previous_object())))
+      poid = getuid(previous_object());
+  }
+  else
+    poid="UNKNOWN";
+
+  Set( P_CLONER, (poid != tpid ? poid+":"+tpid: tpid) );
+  Set( P_CLONER, NOSETMETHOD|SECURED, F_MODE_AS );
+
+  // Gibt es FPs ?
+  explore = (mixed *)EPMASTER->QueryExplore();
+
+  return;
+}
+
+protected void create_super() {
+  set_next_reset(-1);
+}
+
+//                        ##################
+//######################### Forscherpunkte ##############################
+//                        ##################
+
+// FP vergeben
+static void GiveEP( int type, string key )
+{
+  //Abbruch, wenn vergebendes Objekt schon zerstoert ist. ACHTUNG: Auch
+  //diese Abfrage wuerde kein FP vergeben werden, wenn sich das Objekt im
+  //vergebenden Kommando zerstoert, da der Driver call_other() von zerstoerten
+  //Objekten ignoriert!
+  if (!objectp(this_object())) return;
+  if (this_player()) this_player()->countCmds( type, key );
+  
+  if (explore&&!extern_call()&&
+      (explore[0] == type) && (member(explore[1], key) >= 0) )
+    EPMASTER->GiveExplorationPoint(key);
+  return;
+}
+
+// Manche Objekte koennen mit rename_object einen neuen Filenamen bekommen.
+// Danach sollte der EPMASTER neu nach den Details befragt werden.
+void __reload_explore()
+{
+  explore = (mixed *)EPMASTER->QueryExplore();
+  return;
+}
+
+//                         #################
+//########################## ID-Management ##############################
+//                         #################
+
+// Gibt eine ID zurueck, die den Ladenamen, die aktuelle Kurzbeschreibung und
+// die aktuelle Langbeschreibung beruecksichtigt. Diese ID ist ein Hashwert.
+public string description_id() {
+  return hash(TLS_HASH_MD5, load_name() + short() + long());
+}
+
+/* Ids muessen uebergeben werden, da unit machmal mit plural-Ids, */
+/* also anderen als den normalen arbeiten muss. */
+int match_item( string str, string *ids )
+{
+  string *obj,*ads;
+  int len, i;
+  
+  // Parameter falsch? Passt nicht ...
+  if(!str)           return 0;
+  if(!pointerp(ids)) return 0;
+  if(!sizeof(ids))   return 0;
+  
+  // Ist schon so dabei? Na Klasse :-)
+  if(member(ids,str)>-1) return 1;
+  
+  // Keine Adjektive vorhanden ... passt nicht.
+  if (!(ads=QueryProp(P_ADJECTIVES))) return 0;
+  if (!sizeof(ads))                   return 0;
+  
+  // Nur ein Wort? Dann passt es nicht
+  obj=explode(str," ");
+  if (!(len=sizeof(obj)-1)) return 0;
+  
+  // Adjektive stehen am Anfang. Sobald es nicht mehr passt,
+  // muss es das Objektiv sein.
+  while(i<len&&member(ads,obj[i])>-1) i++;
+
+  return (member(ids,implode(obj[i..len]," "))>-1);
+}
+
+// Wird vom Gamedriver aufgerufen (present)
+// Hat dieser Gegenstand die ID str?
+// lvl wird ignoriert
+varargs int id( string str, int lvl ) 
+{ 
+  string str2, tmp;
+  int count;	
+  string|string* ids;
+
+  // Kein Argument? Dann passt es nicht ...
+  if (!stringp(str)) return 0;
+
+  // Keine IDs? Auch nicht gut ...
+  if (!pointerp(ids=QueryProp(P_IDS))) return 0;
+  if (!sizeof(ids)) return 0;
+
+  ids += ({ ("\n" + object_name()),
+            ("\n" + explode(object_name(),"#")[0]) });
+
+  // Id passt? Alles klar :-)
+  if (match_item( str, ids )) return 1;
+
+  // Die id hat eine Zahl drin. Wenn Zahl die Rohid passt,
+  // dann gucken, ob man selber das nte Element ist.
+  if (sscanf( str, "%s %d%s", str2, count, tmp)<2) return 0;
+  if (count<1) return 0;
+  if (sizeof(tmp)) return 0;
+  if (!match_item( str2, ids )) return 0;
+  if (!environment()) return 0;
+  return present(str2,count,environment())==this_object();
+}
+
+// Gleich eine ganze Liste von ids testen
+int match_ids(string *list)
+{
+  string *ids;
+
+  // Ungueltige Parameter? Weg hier ...  
+  if (!pointerp(list)) return 0;
+  if (!pointerp(ids=QueryProp(P_IDS))) return 0;
+
+  ids += ({ ("\n" + object_name()),
+            ("\n" + explode(object_name(),"#")[0]) });
+
+  return sizeof( list & ids );
+}
+
+// ID hinzufuegen
+void AddId( string|string* str )
+{
+  if (stringp(str)) str = ({ str });
+  if (pointerp(str))
+    // Doppelte eliminieren
+    Set( P_IDS, Query(P_IDS, F_VALUE)-str+str, F_VALUE);
+  return;
+}
+
+// ID entfernen
+void RemoveId(string|string* str)
+{
+  if (stringp(str)) str = ({ str });
+  if (pointerp(str))
+    Set(P_IDS,Query(P_IDS, F_VALUE)-str, F_VALUE);
+  return;
+}
+
+// Alle Ids auf einmal setzen
+static string* _set_ids( string* ids )
+{
+    Set( P_IDS,({}));
+    AddId(ids);
+    return Query(P_IDS, F_VALUE);
+}
+
+// Adjektiv hinzufuegen
+void AddAdjective(string|string* str)
+{
+  if (stringp(str)) str = ({ str });
+  if (pointerp(str))
+    // Doppelte eliminieren
+      Set( P_ADJECTIVES, Query(P_ADJECTIVES, F_VALUE)-str+str, F_VALUE );
+  return;
+}
+
+// Adjektiv entfernen
+void RemoveAdjective(string|string* str)
+{
+  if (stringp(str)) str = ({ str });
+  if (pointerp(str))
+    Set( P_ADJECTIVES, Query(P_ADJECTIVES, F_VALUE) - str, F_VALUE );
+  return;
+}
+
+// Alle Adjektive auf einmal setzen
+static string* _set_adjectives(string* adjectives)
+{
+  Set( P_ADJECTIVES,({}), F_VALUE);
+  AddAdjective(adjectives);
+  return Query(P_ADJECTIVES, F_VALUE);
+}
+
+
+//                         ################
+//########################## Namensgebung ###############################
+//                         ################
+
+// Im Fall von mehreren Adjektiven muessen diese mit komma
+// zusamengebaut werden, dazu muss ich das leerzeichen aber erstmal
+// abschneiden und so weiter ...
+private string depointer_adj( string* adj, int casus, int demon ) {
+  string msg;
+  int start;
+  string res,a;
+	adj = map( adj, #'DeclAdj, casus, demon );
+  start = 1;
+  res = "";
+  foreach( a: adj ) {
+    res += (start ? "" : ", ") + a[0..<2];
+    start = 0;
+  }
+  return res + " ";
+}
+
+// Wie lautet der Name des Objekts?
+varargs string name(int casus,int demon)
+{
+  mixed sh, adj;
+  int art, plural;
+
+  art = QueryProp(P_ARTICLE);
+
+  // RAW: direkt zurueckgeben ohne Verarbeitung
+  if (casus == RAW )
+  {
+    if(pointerp(QueryProp(P_NAME)))
+      return QueryProp(P_NAME)[WER];
+    return QueryProp(P_NAME);
+  }
+
+  // Unsichtbar: Etwas
+  if (QueryProp(P_INVIS))
+    return ({ "etwas", "von etwas", "etwas", "etwas" })[casus];
+
+  // Kein Name? Schade ...
+  if (!(sh=QueryProp(P_NAME)) ||
+      (stringp(sh) && !sizeof(sh))) return 0;
+
+  // P_NAME pruefen.
+  if (pointerp(sh) && sizeof(sh) != 4)
+      raise_error(sprintf("Ungueltige Arraygroesse in P_NAME: %d\n",
+            sizeof(sh)));
+
+  // Plural .. Namen verwursten
+  if (plural = QueryProp(P_PLURAL))
+  {
+    // Selber Artikel suchen ist nicht ...
+    if (demon==2||!art) demon = 0;
+
+    // falls P_NAME ein Array mit Faellen enthaelt, den richtigen
+    // extrahieren...
+    if (pointerp(sh)) {
+        sh = sh[casus];
+    }
+    else {
+        // sonst versuchen, zu deklinieren.
+        int last = sh[<1];
+        if (casus == WEM&&last!='s'&&last!='n') sh = sh + "n";
+    }
+
+    // Sind Adjektive vorhanden?
+    if ( pointerp(adj = QueryProp(P_NAME_ADJ)) && sizeof(adj))
+        adj = depointer_adj(adj,casus,demon);
+    if (!stringp(adj)) adj = "";
+
+    return sprintf("%s%s%s%s",QueryArticle(casus,demon,0),adj,
+                   (plural < 2 ? "":(plural < 8 ?
+                    ({ "zwei ", "drei ", "vier ", "fuenf ", "sechs ",
+                       "sieben " })[plural-2] : to_string(plural)+" ")),sh);
+  }
+
+  // Name ist Pointer: Einfach den richtigen auswaehlen
+  if (pointerp(sh))
+    sh = sh[casus];
+
+  // Ansonsten doch wieder verwursten ...
+  else if (stringp(sh))
+  {
+    int last = sh[<1];
+
+    switch(casus)
+    {
+      case WEM:
+      case WEN:
+        if ( art && last=='e'&&QueryProp(P_GENDER) == MALE)
+          sh = (string)sh + "n";
+        break;
+
+      case WESSEN:
+        if( !art )
+        {
+          switch(last)
+          {
+            case 'x':
+            case 's':
+            case 'z':
+              sh = (string)sh + "'";
+              break;
+
+          default:
+            sh = (string)sh + "s";
+          }
+        } 
+        else
+        {
+          switch(last)
+          {
+            default:
+              if (QueryProp(P_GENDER)!=FEMALE)
+                sh=(string)sh+"s";
+              break;
+            case 'e':
+              if (QueryProp(P_GENDER)==MALE)
+                sh=(string)sh+"n";
+            case 'x':
+            case 's':
+            case 'z':
+              break;
+          } /* switch (last) */
+        } /* if( !art ) else */
+    } /* switch( casus ) */
+  } /* pointerp(sh) */
+
+  // RAW? Dann mal zurueck
+  if (demon == RAW) return (string)sh;
+
+  // Selber Artikel suchen ...
+  if (demon==2)
+  {
+    if (art)
+      demon = SuggestArticle();
+    else
+      demon=0; // Kein Artikel: egal (SuggestArticle ist zeitaufwendig)
+  }
+
+  if (pointerp(adj = QueryProp(P_NAME_ADJ)) && sizeof(adj))
+    adj = depointer_adj(adj,casus,demon);
+
+  if (!stringp(adj))  adj = "";
+
+  return QueryArticle( casus, demon )+adj+sh;
+}
+
+// Grossgeschriebenen Namen zurueckgeben
+varargs string Name( int casus, int demon )
+{
+    return capitalize(name( casus, demon )||"");
+}
+
+// Langbeschreibung anzeigen
+public varargs string long(int mode)
+{
+    return process_string( QueryProp(P_LONG) );
+}
+
+// Kurzbeschreibung anzeigen, falls nicht unsichtbar
+public string short()
+{
+  string sh;
+
+  // Unsichtbar? Dann gibts nichts zu sehen ...
+  if (QueryProp(P_INVIS)||!(sh=QueryProp(P_SHORT)))
+    return 0;
+  
+  return process_string(sh)+".\n";
+}
+
+// Namens-Adjektive setzen
+static string* _set_name_adj(string|string* adjectives)
+{
+  if (!adjectives)
+      adjectives=({});
+  // In Array umwandeln
+  else if ( !pointerp(adjectives)) 
+      adjectives = ({ to_string(adjectives) });
+  return Set( P_NAME_ADJ, adjectives );
+}
+
+//                   ############################
+//#################### Details, Gerueche, Laerm #########################
+//                   ############################
+
+// Low-level Funktion zum Ergaenzen von Details, wird von den div. Add...()
+// gerufen, die das richtige Mapping uebergeben.
+// Aendert das Mapping <details> direkt.
+private void _add_details(string|string* keys,
+                          string|string*|mapping|closure descr,
+                          mapping details )
+{
+  if (stringp(keys))
+    details[keys]=descr;
+  else if (pointerp(keys))
+  {
+    foreach(string key : keys)
+      details[lower_case(key)]=descr;
+  }
+  else
+    raise_error("Wrong type to argument 1, expected string|string*.\n");
+}
+
+// Low-level Funktion zum Entfernen von Details, wird von den div. Remove...()
+// gerufen, die das richtige Mapping uebergeben.
+// Aendert das Mapping <details> direkt.
+private void _remove_details(string|string* keys, mapping details )
+{
+  if (stringp(keys))
+    details -= ([keys]);
+  else if (pointerp(keys))
+    details -= mkmapping(keys);
+  else
+    raise_error("Wrong type to argument 1, expected string|string*.\n");
+}
+
+// Detail(s) hinzufuegen
+void AddDetail(string|string* keys, string|string*|mapping|closure descr)
+{
+    int i;
+    mapping details;
+
+    details = Query(P_DETAILS, F_VALUE);
+
+    // _add_details() aendern das Mapping direkt, Set etc. nicht noetig.
+    return _add_details(keys, descr, details);
+}
+
+// Detail(s) entfernen
+varargs void RemoveDetail(string|string* keys )
+{
+  // Alle loeschen geht direkt ...
+  if (!keys )
+    Set(P_DETAILS, ([]), F_VALUE);
+  else
+    // _remove_details() aendern das Mapping direkt, Set etc. nicht noetig.
+    _remove_details(keys, Query(P_DETAILS, F_VALUE));
+}
+
+// SpecialDetail hinzufuegen
+void AddSpecialDetail(string|string* keys, string functionname )
+{
+    closure cl;
+
+    // Absichern! Sonst koennte jeder interne Funktionen aufrufen
+    if (extern_call() &&
+        (geteuid(previous_object()) != geteuid() || process_call()) &&
+        !(object_name(previous_object()) == "/obj/doormaster" &&
+          functionname == "special_detail_doors") )
+      raise_error( "Illegal use of AddSpecialDetail!\n" );
+
+    // Closure generieren
+    if ( !stringp(functionname)||
+         !(cl = symbol_function( functionname, this_object())) )
+      return;
+
+    // Detail hinzufuegen
+    AddDetail( keys, cl );
+    return;
+}
+
+// SpecialDetail(s) entfernen
+void RemoveSpecialDetail(string|string* keys )
+{
+  // RemoveSpecialDetail(0) wuerde sonst ALLE Details (auch die
+  // 'normalen') loeschen
+  if (pointerp(keys)||stringp(keys))
+    RemoveDetail(keys);
+  return;
+}
+
+// Lesbares Detail einfuegen
+void AddReadDetail(string|string* keys,
+                   string|string*|mapping|closure descr )
+{
+  // _add_details() aendern das Mapping direkt, Set etc. nicht noetig.
+  return _add_details(keys, descr, Query(P_READ_DETAILS, F_VALUE));
+}
+
+// Lesbare(s) Detail(s) entfernen
+varargs void RemoveReadDetail(string|string* keys )
+{
+  // Alle loeschen geht direkt ...
+  if (!keys )
+    Set(P_READ_DETAILS, ([]), F_VALUE);
+  else
+    // _remove_details() aendern das Mapping direkt, Set etc. nicht noetig.
+    _remove_details(keys, Query(P_READ_DETAILS, F_VALUE));
+}
+
+// Geraeusch(e) dazufuegen
+void AddSounds(string|string* keys,
+               string|string*|mapping|closure descr )
+{
+  // _add_details() aendern das Mapping direkt, Set etc. nicht noetig.
+  return _add_details(keys, descr, Query(P_SOUNDS, F_VALUE));
+}
+
+// Geraeusch(e) entfernen
+varargs void RemoveSounds(string|string* keys )
+{
+  // Alle loeschen geht direkt ...
+  if (!keys )
+    Set(P_SOUNDS, ([]), F_VALUE);
+  else
+    // _remove_details() aendern das Mapping direkt, Set etc. nicht noetig.
+    _remove_details(keys, Query(P_SOUNDS, F_VALUE));
+}
+
+// Geru(e)ch(e) hinzufuegen
+void AddSmells(string|string* keys,
+               string|string*|mapping|closure descr )
+{
+  // _add_details() aendern das Mapping direkt, Set etc. nicht noetig.
+  return _add_details(keys, descr, Query(P_SMELLS, F_VALUE));
+}
+
+// Geru(e)ch(e) entfernen
+varargs void RemoveSmells(string|string* keys )
+{
+  // Alle loeschen geht direkt ...
+  if (!keys )
+    Set(P_SMELLS, ([]), F_VALUE);
+  else
+    // _remove_details() aendern das Mapping direkt, Set etc. nicht noetig.
+    _remove_details(keys, Query(P_SMELLS, F_VALUE));
+}
+
+// Tastbare(s) Detail(s) hinzufuegen
+void AddTouchDetail(string|string* keys,
+                    string|string*|mapping|closure descr )
+{
+  // _add_details() aendern das Mapping direkt, Set etc. nicht noetig.
+  return _add_details(keys, descr, Query(P_TOUCH_DETAILS, F_VALUE));
+}
+
+// Tastbare(s) Detail(s) entfernen
+varargs void RemoveTouchDetails(string|string* keys )
+{
+  // Alle loeschen geht direkt ...
+  if (!keys )
+    Set(P_TOUCH_DETAILS, ([]), F_VALUE);
+  else
+    // _remove_details() aendern das Mapping direkt, Set etc. nicht noetig.
+    _remove_details(keys, Query(P_TOUCH_DETAILS, F_VALUE));
+}
+
+// Detailinfos fuer Detail key, Spieler hat die Rasse race
+// und benutzt seinen Sinn sense
+varargs string GetDetail(string key, string race, int sense)
+{
+  string|string*|mapping|closure detail;
+  
+  if (stringp(race)) race = lower_case(race);
+  
+  switch(sense)
+  {
+    case SENSE_SMELL: detail=Query(P_SMELLS, F_VALUE)[key];
+                      sense=EP_SMELL; break;
+    case SENSE_SOUND: detail=Query(P_SOUNDS, F_VALUE)[key];
+                      sense=EP_SOUND; break;
+    case SENSE_TOUCH: detail=Query(P_TOUCH_DETAILS, F_VALUE)[key];
+                      sense=EP_TOUCH; break;
+    case SENSE_READ:  detail=Query(P_READ_DETAILS, F_VALUE)[key];
+                      sense=EP_RDET;
+                      break;
+
+    default:          detail=Query(P_DETAILS, F_VALUE)[key];
+                      sense=EP_DETAIL; break;
+  }
+
+  if (!stringp(detail))
+  {
+    if (closurep(detail))
+      detail = (string)funcall(detail,key);
+    else if (mappingp(detail))
+      detail = (string)(detail[race]||detail[0]);
+    else if (pointerp(detail))
+      detail = (string)(detail[random(sizeof(detail))]);
+  }
+
+  // FP vergeben (so vorhanden ;-) )
+  if (detail) GiveEP(sense,key);
+
+  return detail;
+}
+
+// TODO: OBSOLET (Libgrep notwendig)
+void read( string str ) {
+  raise_error("Diese Funktion existiert nicht mehr.\n");
+}
+
+
+//                      ######################
+//####################### Zugriffsfunktionen ############################
+//                      ######################
+
+// Dienen dazu, die direkte Manipulation der Props von aussen zu erschweren.
+
+// Filter, um Specialdetails zu eliminieren
+// erstellt ausserdem ne Kopie vom Mapping. (Wichtig!)
+// Wird vor allem benoetigt, um P_DETAILS in P_DETAILS und 
+// P_SPECIAL_DETAILS zu treffen.
+private int _closures(string x, mapping details, int yes ) 
+{ 
+    return yes ? closurep(details[x]) : !closurep(details[x]); 
+}
+
+static mapping _query_details()
+{
+  return filter_indices(Query(P_DETAILS, F_VALUE), #'_closures,
+      Query(P_DETAILS, F_VALUE),0);
+}
+
+static mapping _query_special_details()
+{
+  return filter_indices(Query(P_DETAILS, F_VALUE),#'_closures,
+      Query(P_DETAILS, F_VALUE),1);
+}
+
+static mapping _query_read_details() {
+  return deep_copy(Query(P_READ_DETAILS, F_VALUE));
+}
+
+static mapping _query_sound_details() {
+  return deep_copy(Query(P_SOUNDS, F_VALUE));
+}
+
+static mapping _query_smell_details() {
+  return deep_copy(Query(P_SMELLS, F_VALUE));
+}
+
+
+//                    ##########################
+//##################### Klassen-Mitgliedschaft ##########################
+//                    ##########################
+
+// Klasse hinzufuegen
+public void AddClass(string|string* str)
+{
+  if (stringp(str)) 
+      str = ({ str });
+  // Aliase aufloesen und implizite Klassen addieren.
+  str = (string*)CLASSDB->AddImplicitClasses(str);
+  // Summe mit alten Klassen bilden und Doppelte eliminieren
+  str = str + Query(P_CLASS, F_VALUE);
+  Set( P_CLASS, m_indices(mkmapping(str)), F_VALUE);
+
+  return;
+}
+
+// Klasse entfernen
+void RemoveClass(string|string* str)
+{
+ if (stringp(str)) 
+      str = ({ str });
+
+  // Aliase aufloesen und implizite Klassen addieren.
+  str = (string*)CLASSDB->AddImplicitClasses(str);
+
+  // Und alle - inklusive impliziter Klassen - entfernen
+  // TODO: Pruefen, ob dies die richtige Entscheidung ist.
+  Set( P_CLASS, Query(P_CLASS, F_VALUE)-str, F_VALUE);
+
+  return;
+}
+
+// Ist das Objekt Mitglied der Klasse str?
+int is_class_member(string|string* str)
+{
+  // Keine Klasse, keine Mitgliedschaft ...
+  if (!str || str=="") 
+      return 0;
+
+  // Es sollte schon ein Array sein
+  if (stringp(str)) 
+      str = ({ str });
+
+  // Klassen und Ids ins Array
+  string *classes=QueryProp(P_CLASS);
+  if (!pointerp(classes))
+    return 0;
+
+  // .. und testen
+  foreach(string class : str)
+    if (member(classes,class) > -1 ) return 1;
+
+  return 0;
+}
+
+// Klasse direkt setzen abfangen
+static string* _set_class(string* classes )
+{
+  Set( P_CLASS, ({}), F_VALUE );
+  AddClass(classes);
+  return QueryProp(P_CLASS);
+}
+
+//                       #####################
+//######################## Material-Handling ############################
+//                       #####################
+
+// Material setzen
+static mapping _set_material(mapping|string|string* mat )
+{
+  mapping mats = ([]);
+  
+  if (mappingp(mat)) 
+  {
+    if( !sizeof(mat) || !widthof(mat) )
+      raise_error(sprintf("P_MATERIAL: expected mapping with at least one "
+        "key and one value, got %.50O\n",mat));
+    else 
+      mats = mat;
+  }
+  else if (stringp(mat))
+    mats[mat]=100;
+  else
+  {
+    int sz = sizeof(mat);
+    // Kommt dann vor, wenn <mat> 0 oder ({}) ist.
+    if ( !sz )
+      raise_error(sprintf("P_MATERIAL: expected string or non-empty "
+        "mapping|string*, got %.50O.\n", mat));
+    mats = mkmapping(mat, allocate(sz, 100/sz));
+  } 
+  return Set( P_MATERIAL, mats, F_VALUE );
+}
+
+// Woraus besteht das Objekt?
+static mapping _query_material()
+{
+  mixed res;
+  
+  if ( !mappingp(res = Query(P_MATERIAL, F_VALUE)) )
+    return ([MAT_MISC:100]);
+  
+  return res;
+}
+
+// Anteil von mat am Objekt?
+int QueryMaterial( string mat )
+{
+  mapping mats;
+  
+  if ( !mappingp(mats = QueryProp(P_MATERIAL)) )
+    return 0;
+  
+  return mats[mat];
+}
+
+// Anteil der Gruppe am Objekt
+int QueryMaterialGroup( string matgroup )
+{
+  return (int)call_other( MATERIALDB, "MaterialGroup",
+                          QueryProp(P_MATERIAL), matgroup );
+}
+
+
+string MaterialList( int casus, mixed idinf )
+{
+  return (string)call_other( MATERIALDB, "ConvMaterialList",
+                             QueryProp(P_MATERIAL), casus, idinf );
+}
+
+static int _set_size(int sz) {
+//Groesse muss > 0 sein, alles andere ist unsinnig! (0 und neg. Groessen
+//haben keine phys. Relevanz und machen u.U. Probleme mit Objekten, die
+//Schaden in Abhaengigkeit der Groesse machen)
+  if (sz>0)
+    Set(P_SIZE,sz,F_VALUE);
+  return(Query(P_SIZE,F_VALUE));
+}
+
+// P_CLONE_TIME
+static int _query_clone_time() { return object_time(); }
+
