Added public files

Roughly added all public files. Probably missed some, though.
diff --git a/doc/beispiele/master/access_rights.c b/doc/beispiele/master/access_rights.c
new file mode 100644
index 0000000..367e909
--- /dev/null
+++ b/doc/beispiele/master/access_rights.c
@@ -0,0 +1,13 @@
+// Wenn ein Verzeichnis fuer ein Objekt nicht schreibbar ist, kann der
+// Besitzer des Verzeichnisses eine Datei access_rights anlegen, die
+// dieses Recht vergibt.
+// Da DOC hier eigentlich nicht schreiben darf, war das hier noetig.
+// Ein Magier wird das fuer die eigenen Verz. idR nicht brauchen.
+
+int access_rights( string user, string pfad ) {
+  if( user=="DOC" && pfad=="opferstocklog" ) {
+  	// DOC darf opferstocklog schreiben
+	return 1;
+  }
+  return 0;
+}
diff --git a/doc/beispiele/master/opferstock.c b/doc/beispiele/master/opferstock.c
new file mode 100644
index 0000000..048a461
--- /dev/null
+++ b/doc/beispiele/master/opferstock.c
@@ -0,0 +1,142 @@
+#include <defines.h>
+#include <properties.h>
+#include <moving.h>
+//
+// By Rumata@MorgenGrauen 3/99
+//
+// Beispieldatei fuer die Benutzung von Mastern und Klienten.
+//
+// Ich gehe hier nicht auf die "normalen" Funktionen ein.
+
+inherit "/std/thing";
+
+#define OS_MASTER "/doc/beispiele/master/opferstockmaster"
+
+void create()
+{
+	if(IS_BLUE(ME)) return;
+	::create();
+	SetProp( P_NAME, "Opferstock" );
+	SetProp( P_GENDER, MALE );
+	SetProp( P_VALUE, 1000 + random(2000) );
+	AddId( ({"stock","inschrift","opferstock"}) );
+	SetProp( P_SHORT, "In einer Ecke steht ein Opferstock" );
+	SetProp( P_LONG,
+		"Der Opferstock besteht aus solidem Holz. Vorne auf dem Kasten ist eine\n"
+	+	"Inschrift zu sehen, die Du lesen kannst.\n"
+	+	"@@contents@@"
+	);
+	SetProp( P_READ_MSG,
+		">>>>>>>>>>>> Fuer den Aufbau eines Orkwaisenhauses <<<<<<<<<<<<\n"
+	+	"In den letzten Jahren wurden immer wieder unschuldige Orkkinder\n"
+	+	"durch brutale Abenteurer ihrer Eltern beraubt. Bitte unter-\n"
+	+	"stuetzen Sie mit einer kleinen Spende den Aufbau eines Waisen-\n"
+	+	"hauses fuer diese bemitleidenswerten Kreaturen.\n"
+	);
+	AddDetail( "holz", "Solide und so gut wie unzerbrechlich.\n" );
+	SetProp( P_NOGET,
+		"Der Opferstock ist nicht ohne Grund am Boden festgenagelt.\n" );
+	AddCmd( "spende","spende" );
+	AddCmd( ({"stecke","steck"}), "stecken" );
+	AddCmd( "oeffne","oeffne" );
+	AddCmd( ({"brich","breche"}),"breche" );
+}
+
+contents()
+{
+	switch(QueryProp(P_VALUE))
+	{
+	case 0:
+		return "Er ist leer.\n";
+	case 1:
+		return "Er enthaelt:\nEine Muenze.\n";
+	default:
+		return "Er enthaelt:\n"+QueryProp(P_VALUE)+" Muenzen.\n";
+	}
+}
+
+stecken( str )
+{
+	string was, worein;
+	if( !str || sscanf(str,"%s in %s",was,worein)!=2 || !id(worein) ) return 0;
+	return spende( str );
+}
+
+spende( str )
+{
+	int anz, newAl;
+	string arg;
+	
+	notify_fail( "Wieviele Muenzen willst Du denn spenden?\n" );
+	if( !str || str=="" )
+		return 0;
+	if( sscanf(str,"%d %s",anz,arg)== 2 )
+		str = arg;
+	else
+	{
+		if( str=="eine muenze" || str=="ein goldstueck" )
+		{
+			anz = 1;
+			str = "muenze";
+		}
+		else
+			return 0;
+	}
+	if( anz<=0 || 
+		member(({"muenze","goldstueck","muenzen","goldstuecke"}), str)==-1
+	)
+		return 0;
+	if( anz>PL->QueryMoney() )
+	{
+		write( "So viel Geld hast Du nicht.\n" );
+		return 1;
+	}
+	PL->AddMoney(-anz);
+	SetProp(P_VALUE,QueryProp(P_VALUE)+anz);
+
+	// Hier wird der Master aufgerufen, der das Alignment der Spieler
+	// dann aendert.
+	if( OS_MASTER->addAlignment( PL, anz/3 ) > 0 ) {
+		// Eigentlich könnte man hier auch die Meldung ausgeben, aber
+		// der Spieler soll den Unterschied zwischen Alignment geaendert
+		// unt Alignment nicht geaendert sehen koennen.
+	}
+	write( "Du hast wahrhaft das Gefuehl, etwas Gutes getan zu haben.\n" );
+
+	say( capitalize(PL->name(WER))+" spendet "+anz
+		+ ((anz==1)?" Muenze.\n":" Muenzen.\n") );
+	return 1;
+}
+
+oeffne( str )
+{
+	int newAl;
+	
+	notify_fail( "WAS willst Du oeffnen?\n" );
+	if( !id(str) )
+		return 0;
+	OS_MASTER->addAlignment( PL, -30 );
+	write( "Allein schon der Gedanke....\n" );
+	return 1;
+}
+
+breche( str )
+{
+	string arg;
+	notify_fail( "WAS willst Du aufbrechen?\n" );
+	if( !str )
+		return 0;
+	if( sscanf(str,"%s auf",arg)==1 )
+		str = arg;
+	if( !id(str) )
+		return 0;
+	write( "Dein lautes Getoese ruft einen Teufel herbei, der Dich gleich\n"
+	+	"mit in die Hoelle nimmt.\n"
+	);
+	say( capitalize(PL->name(WER))+" versucht, den Opferstock aufzubrechen.\n"
+	+ "Gleich erscheint ein Teufel, um "+PL->QueryPronoun(WEN)
+	+	" in die Hoelle zu reissen.\n" );
+	PL->move("/d/unterwelt/raeume/qualenraum",M_GO,"zur Hoelle","faehrt");
+	OS_MASTER->addAlignment( PL, -200 );
+	return 1;
+}
diff --git a/doc/beispiele/master/opferstockmaster.c b/doc/beispiele/master/opferstockmaster.c
new file mode 100644
index 0000000..33a081f
--- /dev/null
+++ b/doc/beispiele/master/opferstockmaster.c
@@ -0,0 +1,120 @@
+/*
+ * Beispieldatei fuer einen einfachen Master, der Spielerdaten auch
+ * ueber reboots, resets und updates hinweg speichert, und gleichzeitg
+ * dafuer sorgt, dass die Datenmengen nicht immer groesser werden.
+ *
+ * By: Rumata@MorgenGrauen 3/99
+ *
+ */
+
+// Von diesem Objekt gibt es keine Clones, sondern nur die Blueprint.
+// Das Konstrukt if( clonep(ME) ) destruct(this_object()); ist dadurch
+// obsolet.
+#pragma no_clone
+
+#include <properties.h>
+#include <defines.h>
+
+// Ort, an dem die Daten gespeichert werden koennen. Die Endung .o
+// wird vom System angehaengt.
+#define SAVEFILE "/doc/beispiele/master/opferstocklog"
+
+// Dieses ist der Klient, der diesen Master benutzt. Dieser Wert wird
+// in diesem Programm zwar nicht benutzt, steht hier aber, damit man
+// weiss, wofuer dieser Master gut ist.
+#define CLIENT "/doc/beispiele/master/opferstock"
+
+// Es braucht kein Objekt inheritet werden, da wir keinerlei Spiel-
+// Funktionitaet brauchen. Der Master kann nicht genommen, bewegt oder
+// sonstwie innherlab des Muds benutzt werden. Insbesondere sollen
+// im savefile zum Master keine Properties oder so auftauchen.
+// inhert "/std/thing";
+
+// Um diese Daten geht es.
+// Das Mapping speichert zu jedem Spieler, wann das letzte Mal durch einen
+// der Klienten das Alignment geaendert wurde. Alte Daten werden bei
+// Gelegenheit geloescht.
+mapping data;
+
+void purge();
+
+void create() {
+
+  // Damit Schreibzugriff auf Savefile moeglich.
+  seteuid(getuid());
+
+  if( restore_object( SAVEFILE ) ) {
+    purge();
+  } else {
+    data = ([]);
+    save_object( SAVEFILE ); // Damit Savefile und Daten immer synchron sind.
+  }
+}
+
+// Diese Funktion testet einen einzelnen Eintrag, ob er veraltet ist.
+// (ist nicht Jahr 2038-fest :-)
+int notExpired( string name, int date ) {
+  return time() - date < 86400;
+}
+
+// Das Mapping untersuchen, ob Eintraege vorhanden sind, die nicht
+// mehr benoetigt werden.
+// (In diesem Fall sind das Eintraege, die aelter als einen Tag sind.)
+// Es reicht uns, diese Funktion einmal pro reboot auszufuehren. Bei
+// anderen Anwendungen koennte das natuerlich haeufiger noetig sein.
+void purge() {
+  data = filter_indices( data, #'notExpired );
+  save_object( SAVEFILE );
+}
+
+// Diese Funktion ist die eingetliche Funktion, die "gemastert" werden
+// soll, also für mehrere Opferstoecke gemeinsam benutzt wird.
+// Der Opferstock uebergibt das Spielerobjekt und die gewuenschte
+// Alignmentaenderung, als Ergebnis wird 1 geliefert, wenn eine Aenderung
+// vorgenommen wurde (0 sonst) und das Alignment des Spielers entsprechend
+// gesetzt.
+int addAlignment( object player, int align ) {
+  int newAlign;
+  string name;
+
+  /*
+  // Falls man verhindern will, dass nur der Klient auf die Daten zugreift,
+  // kann man hier noch Abfragen einbauen, typischerweise sieht das dann so
+  // aus:
+  if( object_name(previous_object())[0..xxx] != CLIENT ) return -1;
+  // oder
+  if( geteuid(previous_object()) != geteuid() ) return -1;
+  // etc. etc.
+  */
+
+  name = geteuid(player);
+
+  // Nur eine Aenderung pro Tag.
+  // Wir benutzen hier, dass data[name] == 0 ist, falls data den Namen nicht
+  // enthaelt!
+  if( notExpired( name, data[name] ) ) return 0;
+
+  // Daten setzen und speichern.
+  data[name] = time();
+  save_object( SAVEFILE );
+
+  // Maximale Aenderung: 200
+  if( align < -200 ) align = -200;
+  if( align > 200 ) align = 200;
+
+  newAlign = player->QueryProp( P_ALIGN ) + align;
+
+  // Kappung bei +-1000
+  if( newAlign < -1000 ) newAlign = -1000;
+  if( newAlign > 1000 ) newAlign = 1000;
+ 
+  player->SetProp( P_ALIGN, newAlign );
+  return 1;
+}
+
+// Schlussbemerkung:
+//
+// Gewitzte Programmierer koennten den Klient und den Master in einer
+// Datei zusammen ablegen. Die Blueprint wird als Master, die Clones werden
+// als Klienten benutzt. Ich habe das hier bewusst anders gemacht und empfehle
+// das auch als Vorbild, weil so der Code wesentlich besser zu verstehen ist.