Added public files
Roughly added all public files. Probably missed some, though.
diff --git a/d/seher/haeuser/abstellraum.c b/d/seher/haeuser/abstellraum.c
new file mode 100644
index 0000000..2f71d75
--- /dev/null
+++ b/d/seher/haeuser/abstellraum.c
@@ -0,0 +1,13 @@
+inherit "/std/room";
+#include "/d/unterwelt/wurzel/wurzel.h" //noch zu aendern...
+
+create() {
+ ::create();
+ SetProp(P_HAUS_ERLAUBT,1);
+ SetProp(P_INT_SHORT,"Der Abstellraum fuer heimatlose Seherhaeuser");
+ SetProp(P_INT_LONG,BS("Hier landen Seherhaeuser, die keinen Platz mehr haben. Wenn "
+ +"Dein Haus hier steht, wende Dich am besten bald an den zustaendigen Magier fuer die "
+ +"Haeuser.\n"));
+ AddDetail("magier","Wurzel oder Wargon kuemmern sich momentan um die Haeuser.\n");
+ AddExit("norden","/gilden/abenteurer");
+}
diff --git a/d/seher/haeuser/access_rights.c b/d/seher/haeuser/access_rights.c
new file mode 100755
index 0000000..1f6097d
--- /dev/null
+++ b/d/seher/haeuser/access_rights.c
@@ -0,0 +1,13 @@
+/* 15.03.2008, Arathorn
+ - Wargon und Wurzel ausgetragen in Abstimmung mit Zook */
+#include "haus.h"
+
+int access_rights(string euid, string file)
+{
+ // return ( euid == "vanion" );
+
+ // Die Maintainer dieses Pakets sind im Define MAINTAINER
+ // in /d/seher/haeuser/haus.h zentral gepflegt
+ return ( member(MAINTAINER, euid) !=-1);
+}
+
diff --git a/d/seher/haeuser/bausparvertrag.c b/d/seher/haeuser/bausparvertrag.c
new file mode 100644
index 0000000..44d9976
--- /dev/null
+++ b/d/seher/haeuser/bausparvertrag.c
@@ -0,0 +1,155 @@
+/*
+ * bausparvertrag.c -- Wir geben unsern Sehern ein Zuhause...
+ *
+ * Grundversion von Jof, weiterbearbeitet von Wargon.
+ *
+ * $Date: 1994/12/17 15:56:11 $
+ * $Revision: 1.4 $
+ * $Log: bausparvertrag.c,v $
+ * Revision 1.4 1994/12/17 15:56:11 Wargon
+ * Etwas mehr Sicherheit gegen Zugriffe von aussen.
+ *
+ * Revision 1.3 1994/10/21 09:52:03 Wargon
+ * zerreissen eingebaut.
+ *
+ * Revision 1.2 1994/10/09 21:00:59 Wargon
+ * Laufzeit etc. ausgebaut, da das ueber den Block abgewickelt
+ * wird.
+ * Funktion Einzahlung() eingebaut (wird von der Bank aufgerufen).
+ *
+ * Revision 1.1 1994/10/09 20:49:28 Wargon
+ * Initial revision
+ *
+ */
+#pragma strong_types,rtt_checks
+
+#include "haus.h"
+#include <properties.h>
+#include <moving.h>
+
+inherit "/std/thing";
+
+protected void create()
+{
+ if (!clonep(this_object())) return;
+ ::create();
+ SetProp(P_SHORT,"Ein Bausparvertrag");
+ SetProp(P_NAME,"Bausparvertrag");
+ Set(P_AUTOLOADOBJ, ({0, V_EP}) );
+ Set(P_AUTOLOADOBJ, SECURED, F_MODE); // Sicher ist sicher...
+ SetProp(P_NODROP,1);
+ SetProp(P_NEVERDROP,1);
+ SetProp(P_ARTICLE,1);
+ SetProp(P_WEIGHT, 0);
+ SetProp(P_GENDER,1);
+ AddId( ({"bausparvertrag", "vertrag", "sehe\rvertrag"}) );
+ AddCmd("lies","lesen");
+ AddCmd( ({ "unterschreibe", "unterschreib" }), lambda( ({}),
+ ({#',, ({#'notify_fail, "Hier kannst Du den Vertrag nicht unterschreiben!\n" }),
+ ({#'return, 0})
+ }) ) );
+ AddCmd( ({ "zerreiss", "zerreisse" }), lambda( ({ 'str }),
+ ({#',, ({#'notify_fail, "Was willst Du zerreissen?\n"}),
+ ({#'?!, ({#'id, 'str}), ({#'return, 0}) }),
+ ({#'=, 'blk, ({#'present, "\n block", ({#'this_player}) }) }),
+ ({#'write, "Du zerreisst Deinen Vertrag.\n"}),
+ ({#'write_file, PATH+"log/BANK.LOG", ({#'sprintf, "%s - Vertrag: %s zerriss ihn.\n",
+ ({#'dtime, ({#'time}) }), ({#'getuid, ({#'this_player})})})}),
+ ({#'?, 'blk, ({#'call_other, 'blk, "remove", 1}) }),
+ ({#'remove, 1}),
+ ({#'return, 1})
+ }) ) );
+}
+
+string _query_long()
+{
+ int max;
+
+ max = (Query(P_AUTOLOADOBJ)[1] & V_FAST) ? SUMME_S : SUMME_L;
+ if (Query(P_AUTOLOADOBJ)[1] & V_RAUM)
+ max = max * 4/10;
+ return sprintf(
+ "Dies ist ein Bausparvertrag. Du hast bisher %d (von %d) Punkten eingezahlt.\n",
+ QueryProp(P_AUTOLOADOBJ)[0], max);
+}
+
+#if 0
+int query_prevent_shadow(object ob)
+{
+ HLOG("SHADOW", sprintf("%s, von %O im Vertrag.\n", dtime(time())[5..], ob));
+ return 1;
+}
+#endif
+
+int lesen(string str)
+{
+ if (id(str))
+ {
+ if (Query(P_AUTOLOADOBJ)[1] & V_RAUM)
+ this_player()->More(PATH+"txt/vertrag_raum.txt",1);
+ else
+ this_player()->More(PATH+"txt/vertrag.txt",1);
+ return 1;
+ }
+ return 0;
+}
+
+int Einzahlung()
+{
+ int *al;
+ object env, po;
+
+ if (old_explode(object_name(po=previous_object()),"#")[0] != PATH+"sb_einzahlung") {
+ env = environment();
+ HLOG( (env ? getuid(env) : "BANK.LOG"), sprintf("Vertrag: Einzahlung von aussen! TI = %O, PO = %O\n", this_interactive(), previous_object()));
+ }
+ al = Query(P_AUTOLOADOBJ);
+ return Set(P_AUTOLOADOBJ, ({ al[0]+RATENHOEHE, al[1] }) )[0];
+}
+
+void Sign(int flag)
+{
+ Set(P_AUTOLOADOBJ, ({ Query(P_AUTOLOADOBJ)[0], flag }) );
+}
+
+public int move(mixed dest, int meth)
+{
+ object penv;
+ int ret;
+
+ penv = environment();
+ ret = ::move(dest, meth);
+
+ if (ret == 1 && (penv || (object_name(previous_object()) != PATH+"sb_antrag" &&
+ object_name(previous_object()) != (stringp(dest) ? dest : object_name(dest)))))
+ HLOG("MOVING", sprintf("Vertrag: von %O -> %O mit %O (%O)\n", environment(), dest, previous_object(), getuid(previous_object())));
+ return ret;
+}
+
+mixed _set_autoloadobj(mixed al)
+{
+ // Loggen, wenn nicht vom Spielerobjekt selber via den
+ // Autoloader-Mechanismus gesetzt.
+ if (previous_object(1)
+ && strstr(load_name(previous_object(1)),"/std/shells") != 0)
+ HLOG("SET_AL",sprintf("Vertrag: TP = %O, PO = %O, ENV = %O\n",
+ this_player(), previous_object(), environment()));
+
+ /* Kompatibilitaet zu alten Vertraegen */
+ if (pointerp(al) && !(al[1] & V_EP)) {
+ al[0] *= 4;
+ al[1] |= V_EP;
+ call_out("notifyChange", 0, this_player());
+ }
+ return Set(P_AUTOLOADOBJ, al);
+}
+
+void notifyChange(object wem)
+{
+ tell_object(wem,
+ "\nNACHRICHT VON DER SEHERBANK:\n"
+ +"Die Vertragsmodalitaeten haben sich geaendert! Bitte lesen Sie den\n"
+ +"Vertrag noch einmal genau durch (insbes. Art. 4)!\n"
+ +"Statt Geld haben Sie jetzt Erfahrungspunkte zu zahlen!\n\n" );
+}
+
diff --git a/d/seher/haeuser/block.c b/d/seher/haeuser/block.c
new file mode 100644
index 0000000..8f011ed
--- /dev/null
+++ b/d/seher/haeuser/block.c
@@ -0,0 +1,324 @@
+// block.c -- Hier sammeln sich die Raten fuer das Seherhaus
+//
+// (c) 1994 Wargon@MorgenGrauen
+//
+// $Id: block.c,v 1.2 2003/11/15 13:56:01 mud Exp $
+//
+#include <properties.h>
+#include <language.h>
+#include <moving.h>
+#include <combat.h>
+#include "haus.h"
+
+inherit "std/clothing";
+
+private nosave int shadowing;
+
+create()
+{
+ if (!clonep(this_object())) return;
+
+ ::create();
+
+ SetProp( P_SHORT, "Der MG MASTER-BLOCK" );
+ SetProp( P_NAME, "MASTERBLOCK" );
+ SetProp( P_WEIGHT, 100 );
+ SetProp( P_GENDER, MALE );
+ SetProp( P_NODROP, 1 );
+ SetProp( P_NEVERDROP, 1 );
+ // wenn es keinen TP gibt, muss das Ding per SetProp(P_AUTOLOADOBJ)
+ // konfiguriert werden, nicht hier. Zesstra, 20.10.2007
+ if (objectp(this_player()))
+ Set( P_AUTOLOADOBJ, ({ 0, this_player()->QueryProp(P_AGE) + MAX_TIME,
+ MAX_TIME/2, B_EP }) );
+ Set( P_AUTOLOADOBJ, SECURED, F_MODE );
+ SetProp( P_NOBUY, 1 );
+ SetProp(P_MATERIAL, MAT_MARBLE);
+
+ SetProp(P_WEAR_FUNC, this_object());
+ SetProp(P_REMOVE_FUNC, this_object());
+
+ AddId( ({ "block", "masterblock", "master-block", "MG MASTER-BLOCK", "mg master-block", "\n block" }) );
+
+ AddCmd( "", "remindMe", 1);
+}
+
+int query_prevent_shadow(object ob)
+{
+ HLOG("SHADOW", sprintf("%s, von %O im Block.\n",dtime(time())[5..], ob));
+ return 1;
+}
+
+int
+WearFunc(object me)
+{
+ if (!shadowing && (Query(P_AUTOLOADOBJ)[V_FLAGS] & B_ACTIVE) ) {
+ clone_object("/std/player/shadows/block_shadow");
+ shadowing = 1;
+ }
+ return 1;
+}
+
+int
+RemoveFunc(object me)
+{
+ // manchmal gibts keinen TP und machmal ist TP nicht der Spieler, der den
+ // Block traegt.
+ if (this_player() && this_player() == environment()) {
+ shadowing = 0;
+ this_player()->SeherHatGenug();
+ return 1;
+ }
+ return 0;
+}
+
+static int
+_query_value()
+{
+ return( Query(P_AUTOLOADOBJ)[0] );
+}
+
+static int
+_query_cursed()
+{
+ return 0;
+}
+
+static int
+_set_schwer(int schwer)
+{
+ int *al;
+
+ al = Query(P_AUTOLOADOBJ);
+ if (schwer && !(al[V_FLAGS] & B_FAST)) {
+ al[V_DLINE] -= MAX_TIME/2;
+ al[V_WTIME] /= 2;
+ al[V_FLAGS] |= B_FAST;
+ }
+ else if (!schwer && (al[V_FLAGS] & B_FAST)) {
+ al[V_DLINE] += MAX_TIME/2;
+ al[V_WTIME] *= 2;
+ al[V_FLAGS] &= ~B_FAST;
+ }
+ Set( P_AUTOLOADOBJ, al[0..]);
+ return al[V_FLAGS] & B_FAST;
+}
+
+static int
+_query_schwer()
+{
+ return (Query(P_AUTOLOADOBJ)[V_FLAGS] & B_FAST);
+}
+
+static mixed
+_set_autoloadobj(mixed al)
+{
+ object ti;
+
+ if ((ti = this_interactive()) && old_explode(object_name(ti),"#")[0] != "/secure/login")
+ HLOG("SET_AL",sprintf("Block: TI = %O, ENV = %O\n",this_interactive(), environment()));
+
+ /* Kompatibilitaet... */
+ if (pointerp(al) && !(al[V_FLAGS] & B_EP)) {
+ al[V_MONEY] *= 4;
+ al[V_FLAGS] |= B_EP;
+ }
+ return Set(P_AUTOLOADOBJ, al);
+}
+
+static string
+_query_long()
+{
+ int *al;
+ int laufzeit, einzahlung;
+ int ratenhoehe;
+ string ret;
+
+ al = Query(P_AUTOLOADOBJ);
+ ret = "Dies ist der MG MASTER-BLOCK. Er besteht aus massivem Marmor, um die Sicher-\n"
+ +"heit der eingezahlten Rate zu gewaehrleisten. Mit einem Goldkettchen versehen,\n"
+ +"kann man ihn tragen wie ein Amulett. Dies ist auch noetig, wenn auf den Block\n"
+ +"eingezahlt werden soll.\n";
+
+ ratenhoehe = RATENHOEHE;
+ if (al[V_FLAGS] & B_EXTEND)
+ ratenhoehe += (RATENHOEHE*6)/10;
+ laufzeit = 2*(al[V_DLINE]-this_player()->QueryProp(P_AGE));
+ einzahlung = al[V_MONEY];
+
+ if (laufzeit < 0)
+ ret += "Leider hast Du die Zahlung dieser Rate verpasst!\n";
+ else {
+ if (einzahlung >= ratenhoehe)
+ ret += "Er ist vollstaendig mit der Rate gefuellt.\n";
+ else
+ ret += sprintf( "Du hast bis jetzt %d (von %d) Punkten eingezahlt.\n", einzahlung, ratenhoehe );
+
+ ret += time2string("Diese Rate muss bis in %h %H, %m %M und %s %S abbezahlt sein!\n", laufzeit);
+ }
+ return ret;
+}
+
+static int
+remindMe()
+{
+ int noch, next, *al, ratenhoehe;
+ object vertrag;
+
+ al = Query(P_AUTOLOADOBJ);
+ next = al[V_WTIME];
+ ratenhoehe = RATENHOEHE;
+ if (al[V_FLAGS] & B_EXTEND)
+ ratenhoehe += (RATENHOEHE*6)/10;
+
+ if (al[V_MONEY] < ratenhoehe) {
+ noch = al[V_DLINE]-this_player()->QueryProp(P_AGE);
+ if (noch >= 0) {
+ if (next > noch) {
+ call_out("doRemind", 0, this_player(), time2string( "Die naechste Rate wird in %h %H, %m %M und %s %S faellig!\n", 2*noch));
+ do next -= WARN_TIME; while (next>0 && next>noch);
+ if (next < 0)
+ next = 0;
+ al[V_WTIME] = next;
+ Set(P_AUTOLOADOBJ, al[0..]);
+ }
+ }
+ else {
+ if (al[V_FLAGS] & B_EXTEND) {
+ string s;
+
+ write( "Du hast die Strafrate nicht bezahlt!\n" );
+ if (vertrag = present( "sehe\rvertrag", this_player())) {
+ write( "Damit verfaellt auch Dein Bausparvertrag! Und das im wahrsten Sinne des\nWortes...\n" );
+ vertrag->remove();
+ }
+ s = "Block: "+getuid(this_player())+" hat ueberzogen... ;)\n";
+ HLOG(getuid(this_player()), s);
+ HLOG("BANK.LOG", s);
+ remove(1);
+ }
+ else {
+ write( "Du hast die letzte Ratenzahlung verpasst!\n"
+ +"Die Ratenhoehe erhoeht sich um die Strafgebuehr.\n" );
+ al[V_FLAGS] |= B_EXTEND;
+ if (al[V_FLAGS] & B_FAST) {
+ al[V_DLINE] += MAX_TIME/4;
+ al[V_WTIME] = MAX_TIME/8;
+ }
+ else {
+ al[V_DLINE] += MAX_TIME/2;
+ al[V_WTIME] = MAX_TIME/4;
+ }
+ Set( P_AUTOLOADOBJ, al[0..]);
+ }
+ }
+ }
+
+ return 0;
+}
+
+int
+Gutschreiben(int money)
+{
+ int back, ratenhoehe;
+ mixed al;
+
+ if (!QueryProp(P_WORN)) // Zum Gutschreiben muss der Block getragen werden!
+ return money;
+
+ al = Query(P_AUTOLOADOBJ);
+ back = 0;
+
+ ratenhoehe = RATENHOEHE;
+ if (al[V_FLAGS] & B_EXTEND)
+ ratenhoehe += (RATENHOEHE*6)/10;
+
+ if (old_explode(object_name(previous_object()),"#")[0] != "/std/player/shadows/block_shadow") {
+ mixed env;
+
+ env = environment();
+ if (env)
+ env = getuid(env);
+ else
+ env = "BANK.LOG";
+ HLOG(env, sprintf("Block: Gutschrift von aussen (%d EP), TI = %O)!\n", money, this_interactive()));
+ }
+ al[V_MONEY] += money;
+ if (al[V_MONEY] >= ratenhoehe) { // genug eingezahlt...
+ back = al[V_MONEY]-ratenhoehe;
+ al[V_MONEY] = ratenhoehe;
+ al[V_FLAGS] &= ~B_ACTIVE;
+ money -= back;
+ call_out("blockVoll",0,environment());
+ }
+
+ Set(P_AUTOLOADOBJ, al[0..]);
+
+ return back;
+}
+
+void
+blockVoll(object pl)
+{
+ tell_object(pl, "Der Block fuer diese Rate ist jetzt voll!\n");
+ pl->SeherHatGenug(); // shadow entfernen
+}
+
+void
+doRemind(object pl, string str)
+{
+ tell_object(pl, str);
+}
+
+protected int PreventMove(object dest, object oldenv, int method) {
+ if (previous_object() && previous_object()->QueryBuyFact()) // Im Laden...
+ return ME_CANT_BE_DROPPED;
+ return ::PreventMove(dest, oldenv, method);
+}
+
+protected void NotifyMove(object dest, object oldenv, int method) {
+
+ if (oldenv || (object_name(previous_object()) != PATH+"sb_antrag" &&
+ object_name(previous_object()) != PATH+"sb_einzahlung" &&
+ object_name(previous_object()) != object_name(dest)))
+ HLOG("MOVING", sprintf("Block: von %O -> %O mit %O (%O)\n",
+ environment(), dest,
+ previous_object(), getuid(previous_object())));
+
+ return ::NotifyMove(dest, oldenv, method);
+}
+
+int
+remove(int silent)
+{
+ if (clonep(this_object()) && environment())
+ environment()->SeherHatGenug();
+
+ return ::remove(silent);
+}
+
+// $Log: block.c,v $
+// Revision 1.2 2003/11/15 13:56:01 mud
+// MAT_MARBLE
+//
+// Revision 1.1.1.1 2000/08/20 20:22:42 mud
+// Ins CVS eingecheckt
+//
+// Revision 1.4 1994/12/17 15:56:58 Wargon
+// Etwas mehr Sicherheit gegen Zugriffe von aussen.
+//
+// Revision 1.3 1994/10/21 09:50:20 Wargon
+// long()->_query_long()
+// Shadow wird nur aktiv, wenn der Block gezueckt ist.
+//
+// Revision 1.2 1994/10/09 21:04:27 Wargon
+// Man kann jetzt einstellen, ob der Block zu einem leichten, aber
+// teureren oder zu einem schweren, aber billigeren Vertrag gehoert.
+// Falls man eine Rate verpasst hat, verfaellt damit auch der Ver-
+// trag.
+// Gutgeschrieben wird nur, wenn der Block gezueckt ist.
+// Gutschreiben() liefert ueberzaehliges Geld zurueck.
+//
+// Revision 1.1 1994/10/07 14:35:34 Wargon
+// Initial revision
+//
diff --git a/d/seher/haeuser/haeuser.txt b/d/seher/haeuser/haeuser.txt
new file mode 100644
index 0000000..1945157
--- /dev/null
+++ b/d/seher/haeuser/haeuser.txt
@@ -0,0 +1,633 @@
+Inhaltsverzeichnis:
+
+1.. Kurzuebersicht der Files
+2.. Der Hausverwalter
+3.. Sonderrechte
+4.. Die Tools
+4a... Der Hausmeister
+4b... liste.c
+4c... haustool.c
+5.. Das Haus
+5a... Aussenansicht - haus.c
+5b... Die Raeume - raum.c
+5c... Der Eingangsraum - raum0.c
+5d... Die Truhe - truhe.c
+6.. Seherbank/Hauserwerb
+7.. Beschreibungen
+7a... Details/ReadDetails/Lang- und Kurzbeschreibung
+7b... Ausgaenge
+7c... Licht
+7d... Befehle
+8.. Rueckmeldungen
+9.. Hilfeseiten
+
+1. Kurzuebersicht der Files
+===========================
+
+/d/seher/haeuser/
+
+ /* Am allerwichtigsten: */
+ haus.h .................... Definitionen, die ueberall benutzt werden
+ access_rights.c ........... Die Leute mit Hauszugriff
+
+ /* Keine Haeuser ohne Verwaltung */
+ hausverwalter.c ........... Die Zentralstelle der Seherhaeuser
+ HAEUSER ................... Infos ueber Hausbesitzer (Wer, wo, wie gross)
+
+ save/
+ haeuser.o ................. Das Savefile des Hausverwalters
+
+ tools/ .................... Sammelplatz fuer Tools zu den Haeusern
+ hausmeister.c ............. Verlegen, Abreissen, .c-Files erstellen
+ haus.apx .................. Fuer .c-File eines Hauses
+ liste.c ................... Zeigt geloeschte und ge-Wiz-te Hausbesitzer
+ haustool.c ................ (obsolete)
+
+ /* Erwerb eines Hauses/Raumes */
+ seherbank.c ............... Das Bankgebaeude
+
+ queue.c ................... Die Schlangen vor den Schaltern
+ queue.h
+
+ sb_antrag.c ............... Schalter zum Beantragen eines Vertrages
+ sb_einzahlung.c ........... Schalter zum Einzahlen einer Rate
+ sb_ausgabe.c .............. Schalter zum Abholen eines Hauses
+
+ bausparvertrag.c .......... Auf dem Vertrag werden die Raten vermerkt
+ kommentar.c ............... Kommentare zum unklaren Vertragstext
+
+ txt/ ...................... Hier stehen die eigentlichen Vertragstexte
+ vertrag.txt ............... a) fuer einen Haus-Vertrag
+ vertrag_raum.txt .......... b) fuer einen Ausbauvertrag
+ kommentar.txt ............. c) erklaerende Bemerkungen zu den Texten
+
+ block.c ................... Der Block verwaltet die laufende Rate
+ /std/player/shadows/block_shadow.c
+
+ traghaus.c ................ Das bekommt man am Ausgabeschalter
+
+ log/ ...................... Logging der Bank, des Blocks, des Vertrages
+
+ /* Die Haeuser selbst */
+ virtual_compiler.c ........ Ordnet die Haeuser passend zu
+ haus.c .................... Die Aussenansicht des Hauses
+ raum.c .................... Allgemeine Funktionen der Raeume
+ raum0.c ................... Der Eingangsraum hat einige Zusatzfeatures
+ modules/ .................. Hilfsmodule:
+ haustuer.c ................ Beschreibung der Haustuer, Oeffnen/Schliessen
+ losa.c .................... Erweitertes Laden und Speichern der Raeume
+ usercmd.c ................. Alles fuer benutzerdefinierte Befehle
+ truhe.c ................... Die Truhe
+
+ save/
+ name.o .................... Savefile der Aussenansicht des Hauses
+ name0.o ................... Savefile von Raum 0
+ usw.
+ name9.o ................... Savefile von Raum 9
+ nametruhe.o ............... Savefile der Truhe
+
+ special/ .................. Besondere Objekte
+ rj.c ...................... "Romeo und Julia" von Etain
+ rom_jul/ .................. Hier liegen die Seiten der Geschichte
+ seherfaq.c ................ Die Seher-FAQ von Ryne
+ faq/ ...................... Die Seiten der FAQ
+
+ rep/ ...................... Hier landen die 'typo'-Meldungen der Haeuser
+
+ doc/ ...................... Hilfeseiten (nach /doc/scmd kopieren)
+ hausbau ................... Allgemeine Informationen
+ seherhaus ...........
+ instanthaus ........
+
+ aendere .......
+ ausgang ........
+ befehl ..........
+ beschreibe .......
+ erlaube ...........
+ kopiere ............
+ licht ...............
+ loesche ................... Seiten zu den einzelnen Befehlen
+ meldungen ...........
+ notiz ..............
+ schiebe ...........
+ sperre ...........
+ spion ...........
+ uebersicht .....
+ verbiete ......
+ werfe ........
+
+/sys/player/base.h .......... Hier ist "HAUSVERWALTER" definiert
+
+2. Der Hausverwalter
+====================
+
+Dies ist die Zentralstelle der Seherhaeuser. Hier werden wichtige Daten
+der Hausbesitzer verwaltet, naemlich:
+- der Ort, an dem das Haus steht
+- die Zahl der zusaetzlichen Raeume, ueber die das Haus verfuegt
+- die Leute, die im Haus Sonderrechte besitzen
+
+Die Funktionen des Hausverwalters werden von diversen Objekten aus auf-
+gerufen. Im Einzelnen waeren da:
+
+secure() - intern
+ Sicherheitsabfrage fuer einige Funktionen des Hausverwalters. Zugelassen
+ sind EMs und die Leute, die im access_rights.c stehen, ausserdem das
+ Instanthaus (fuer NeuesHaus()) und der Ausgabeschalter (fuer NeuerRaum()).
+
+dump() - intern
+ Bringt die Datei "HAEUSER" auf den neuesten Stand (nachdem ein neues Haus
+ oder ein neuer Raum dazugekommen ist oder ein Haus verlegt bzw. geloescht
+ wurde).
+
+check_exits() - intern
+ Beim Verlegen und Abreissen von Haeusern ist es noetig, dass Ausgaenge in
+ Nachbarhaeuser entfernt werden. Dafuer sorgt diese Funktion.
+
+NeuesHaus() - traghaus.c
+ Ein neues Seherhaus wird geschaffen: es wird im ObjectDaemon angemeldet,
+ die Truhe wird im Eingangsraum plaziert, und die "HAEUSER"-Datei wird auf
+ den neuesten Stand gebracht.
+ Wenn Du zu Testzwecken ein Haus haben willst, kannst Du die Funktion auch
+ von Hand aufrufen.
+
+NeuerRaum() - sb_ausgabe.c
+ Einem Haus wird ein neuer Raum hinzgefuegt.
+ Maximal sind 10 Raeume (raum0-raum9) erlaubt.
+
+_LadeHaus() - virtual_compiler.c
+ Wenn der potentielle Besitzer wirklich ein Haus hat und sich dessen
+ Environment laden laesst, wird das Haus erstellt und zuruekgegeben.
+
+_LadeRaum() - virtual_compiler.c
+ Aehnlich wie _LadeHaus(), nur fuer den Raum mit der gewuenschten Nummer.
+ Beim Eingangsraum wird noch der Ausgang nach draussen gesetzt.
+
+FindeHaus() - hausverwalter.c, sb_antrag.c, hausmeister.c, /std/player/base.c
+ Gibt das Hausobjekt zurueck oder 0, falls der Spieler kein Haus hat.
+ Das Haus wird ggf. geladen.
+
+LoescheHaus() - hausmeister.c
+ Ein Haus wird abgerissen: Es wird im ObjectDaemon abgemeldet, saemtliche
+ Savefiles werden geloescht, ebenso das .rep-File des Hausbesitzers.
+
+ Rueckgabewerte:
+ 1 - alles OK, das Haus ist weg
+ -1 - secure() schlug fehl.
+
+VerlegeHaus() - hausmeister.c
+ Ein Haus wird an einen neuen Ort verlegt: Es wird im ObjectDaemon ab- und
+ am neuen Ort wieder angemeldet, und der Ausgang nach draussen wird
+ angepasst.
+
+ Rueckgabewerte:
+ 1 - alles Ok, das Haus steht jetzt woanders
+ -111 - secure() schlug fehl.
+ -1 - der angebliche Besitzer hat gar kein Haus
+ -2 - das Haus steht gar nicht da, wo es sein sollte
+ -3 - der Zielraum existiert nicht
+ -4 - im Zielraum kann nicht gebaut werden
+ -5 - es gibt Ausgaenge in benachbarte Seherhaeuser (diese werden beim
+ Verlegen nicht automatisch geloescht; das muss der Hausbesitzer
+ selbst machen)
+
+Unbebaubar() - hausverwalter.c, traghaus.c
+ Diese Funktion ermittelt, ob in einem Raum ein Haus gebaut werden kann, und
+ wenn nein, warum nicht.
+
+ Rueckgabewerte:
+ 0 - OK, es darf gebaut werden
+ 1 - der Zielraum ist entweder ein geclontes Objekt (und damit zumindest
+ nach dem naechsten Reboot auf immer verloren) oder ein Objekt, dass
+ von einem virtual_compiler erzeugt wurde (der ObjectDaemon wird zu
+ einem Zeitpunkt abgefragt, an dem das VC-Objekt noch nicht seinen
+ endgueltigen Namen hat).
+ 2 - Im Zielraum ist P_INDOORS gesetzt (wenn in so einem Raum trotzdem
+ gebaut werden soll, weil es zum Beispiel eine grosse Hoehle o.ae.
+ ist, kann man P_INDORRS immer noch temporaer auf 0 setzen).
+ 3 - Im Zielraum ist P_HAUS_ERLAUBT nicht gesetzt.
+
+Erlaube() - raum0.c
+ Einem oder mehreren Spielern werden Sonderrechte im Haus eingeraeumt.
+ Zurueckgegeben wird die neue erlaube-Liste.
+
+Verbiete() - raum0.c
+ Einem oder mehreren Spielern werden die Rechte entzogen.
+ Zurueckgegeben wird die neue erlaube-Liste.
+
+HausProp() - haus.c, raum.c, raum0.c, sb_antrag.c, hausmeister.c
+ Mit dieser Funktion koennen die Informationen ueber einen Hausbesitzer
+ abgefragt werden. Moeglich sind:
+ HP_ENV - der Raum, in dem das Haus steht
+ HP_ROOMS - die Zahl der zusaetzlichen Raeume, ueber die das Haus verfuegt
+ HP_ALLOWED - Array mit den Leuten, die Sonderrechte geniessen
+
+PCrunch() - raum.c, losa.c, hausmeister.c
+ Um Platz beim Speichern zu sparen, werden Details, ReadDetails und Befehle,
+ die den gleichen Text ergeben, zusammengepackt. Beim Hausmeister hat das
+ den Effekt, dass im generierten Quelltext z.B.
+ AddDetail( ({ "foo", "bar" }), "blafasel\n");
+ steht anstelle von
+ AddDetail( "foo", "blafasel\n");
+ AddDetail( "bar", "blafasel\n");
+
+3. Sonderrechte
+===============
+
+Der Hausbesitzer kann von seinem Eingangsraum aus anderen Leuten Rechte in
+seinem Haus einraeumen. Dazu dient der Befehl "erlaube". Leute mit Sonder-
+rechten koennen:
+- das Haus auf- und abschliessen
+- die Truhe oeffnen (schliessen darf sie jeder)
+- netztot im Haus bleiben
+- Rueckmeldungen aus dem Reportfile ansehen (aber nicht aendern)
+
+Ausserdem muss man Sonderrechte in einem Nachbarhaus haben, wenn man von
+seinem Haus einen Ausgang dorthin legen will.
+
+Das Array mit den Namen der Berechtigten erhaelt man vom Hausverwalter per
+HausProp(<owner>, HP_ALLOWED). In dem Array stehen die User-IDs der Leute,
+allerdings mit grossem Anfangsbuchstaben.
+
+4. Die Tools
+============
+
+4a. Der Hausmeister
+-------------------
+
+Der Hausmeister erlaubt das einfache Abreissen und Verlegen von Haeusern
+sowie das Generieren von LPC-Quelltext aus den Savefiles. Dazu stellt er
+drei Kommandos zur Verfuegung:
+
+verlege <name> nach <ziel>
+ Das Haus des Spielers <name> wird in den Raum <ziel> verlegt. <ziel> ist
+ dabei entweder der Filename des Zielraumes oder "hier", wenn das Haus
+ zu Deinem aktuellen Standort verlegt werden soll.
+ Sollte das Verlegen fehlschlagen (siehe VerlegeHaus() im Hausverwalter)
+ meldet sich der Hausmeister entsprechend.
+
+reisse <name> ab
+ Das Haus des Spielers <name> wird abgerissen.
+ ACHTUNG! Es gibt keine Sicherheitsabfrage!
+
+generiere <name> [<nr>] [soft | ganz]
+ Generiert aus dem Savefile ein LPC-File.
+ Ohne Angabe einer Nummer wird die Aussenansicht generiert, ansonsten der
+ Raum mit der entsprechenden Nummer.
+ Ausser wenn "soft" angegeben wurde, werden die Dateien in das Verzeichnis
+ "rep/" geschrieben, und zwar als "<name>haus.c", "<name>raum0.c" etc.
+ Befindet sich die Truhe in dem generierten Raum, wird auch noch eine Datei
+ "<name>truhe.c" angelegt.
+ Die Dateien sind im wesentlichen fuer Magier gedacht, die ihre Haeuser als
+ LPC-Files unter Eigenregie weiterfuehren wollen/sollen. Ausgaenge sind
+ relativ zu "/players/<name>/seherhaus".
+ Mit dem Parameter "ganz" laesst sich das gesamte Haus auf einen Schlag
+ umwandeln.
+ "soft" stammt noch aus der Zeit, als ich die Typos der Seher selber fixen
+ musste. Das Haus oder der Raum wird dabei in die Datei PATH+"fixed.c"
+ geschrieben.
+
+4b. liste.c
+-----------
+
+Ab und zu sollte man mal nachsehen, welche Seher sich geloescht haben oder
+zu Magiern wurden. Die Haeuser von geloeschten Sehern sollten ebenfalls
+geloescht werden; Magier koennen ihre Haeuser als normale LPC-Objekte
+weiterfuehren (sobald die Level 21 oder 25 haben).
+
+Die Liste zeigt an, welche Leute betroffen sind. Dazu muss sie einfach nur
+geladen werden.
+
+Zwei Ausnahmen gibt es:
+- Krigi hat sich zwar geloescht, er hat aber darum gebeten, dass sein Haus
+ weiter bestehen kann (er ist jetzt Dauergast)
+- Fraggle ist zwar Magier, hat sein Haus aber mal zu Testzwecken bekommen
+
+4c. haustool.c
+--------------
+
+Dieses Teil ist mittlerweile ueberholt; es stammt noch aus der Zeit, als
+'typo'- und aehnliche Meldungen noch in meinem eigenen .rep-File landeten
+und ich den Kram auch abarbeiten musste. Mit dem Tool konnte ich die Mel-
+dungen aus meinem .rep-File ansehen und eine Benachrichtigung an den Haus-
+besitzer generieren.
+
+
+5. Das Haus
+===========
+
+Das Haus selbst zerfaellt, was die Beschreibungen angeht, in drei grosse
+Bereiche: den von aussen sichtbaren Teil, die Raeume im Inneren, und die
+Truhe. Bei den Raeumen hat der Eingangsraum noch ein paar Sonderfunktionen.
+
+5a. Aussenansicht
+-----------------
+
+Dies ist das Objekt, das im ObjectDaemon angemeldet wird ("<name>haus").
+Der Hausbesitzer kann folgende Eigenschaften beschreiben:
+- die Langbeschreibung (P_LONG)
+- eine Zeile, wie die Haustuer aussehen soll (H_DOOR)
+- die Zustaende der Haustuer (offen, geschlossen, abgeschlossen; H_DOORLSTAT)
+
+Ausserdem stehen folgende Kommandos zur Verfuegung:
+- betritt/betrete <haus>
+ Sollte klar sein. Geht nur, wenn das Haus offen ist.
+- klopfe an <haus> an
+ Das Klopfen hoert man im ganze Haus
+- notiz <text>
+ Der Hausbesitzer kann damit eine kurze Notiz an der Haustuer anbringen.
+
+modules/haustuer.c stellt die Befehle zum Oeffnen und Schliessen des Hauses
+zur Verfuegung. Aufgeschlossen werden kann das Haus nur von Leuten mit
+spezieller Genehmigung.
+
+Wenn die Kurzbeschreibung geaendert werden soll, muss das ein Magier machen.
+Offizieller Ansprechpartner dafuer ist der Hausmaintainer (also DU :-)
+Man sollte dabei darauf achten, dass die Beschreibung a) in die Umgebung und
+b) allgemein in eine Fantasywelt passt (das ist leider nicht bei allen
+Haeusern der Fall...)
+Wenn die Kurzbeschreibung geaendert wird, sollten ggf. auch noch die IDs, der
+Name und das Geschlecht angepasst werden.
+Um ein Haus unsichtbar zu machen, muss P_SHORT auf 0 gesetzt werden.
+Wenn noch andere Seherhaeuser im gleichen Raum stehen, und in der Beschrei-
+bung des geaenderten Hauses nichts mehr auf ein "haus" hinweist, kann und
+sollte die ID "haus" entfernt werden.
+Um die Aenderungen zu sichern, muss im Haus Save() aufgerufen werden.
+
+Zwei IDs sollten nie entfernt werden: "sehe\rhaus" und "\n<name>haus"
+
+
+5b. Die Raeume
+--------------
+
+Programmtechnisch befinden sich hier hauptsaechlich Funktionen zum Beschrei-
+ben des Raumes, Hinzufuegen und Entfernen des Lichtes, An- und Abschalten
+des Lichtes und Einsehen des .rep-Files.
+Ausserdem kann man Personen, Gegenstaende oder alles aus dem Haus werfen.
+
+Auch die Raeume haben die ID "sehe\rhaus".
+
+Erwaehnenswerte Funktionen:
+
+normstr()
+ Ersetzt @@ in den Beschreibungen durch ** (damit kein process_string()
+ ausgefuehrt werden kann)
+
+brk()
+ Erzeugt aus einer durch Kommata getrennten Liste ein Array von Strings
+
+befCheck()
+ Faengt verbotene Befehle ab (Kommandos, die Leerzeichen enthalten; nicht
+ gesetzte Ausgaenge; alle Kommandos, die der Raum definiert, ausser
+ "oeffne", "schliess", "schliesse")
+
+owner_check()
+ Darf der Spieler das? Falls ohne Argument aufgerufen, ist die Aktion nur
+ erlaubt, wenn this_player() der Hausbesitzer ist.
+ Mit Argument wird auch die erlaube-Liste geprueft.
+
+arr_out()
+ Gibt ein Array von Strings aus oder zurueck, je nach Anwendung
+
+clean_up()
+ Sorgt dafuer, dass nur leere Raeume weggeraeumt werden
+
+BecomesNetDead()
+ Netztote verlassen das Haus (soweit sie nicht auf der erlaube-Liste stehen)
+
+init()/int_long()
+ Meldungen ueber unsichtbare Magier
+
+lies()
+ ReadDetails werden mit More() ausgegeben
+
+Die Befehle zur Beschreibung darf nur der Hausbesitzer benutzen. Den Befehl
+"uebersicht" koennen auch die Magier, die im access_rights.c stehen, ver-
+wenden.
+Naeheres zu den moeglichen Beschreibungen folgen unten.
+
+
+5c. Der Eingangsraum
+--------------------
+
+Der Eingangsraum stellt zusaetzlich noch folgende Befehle und Moeglichkeiten
+zur Verfuegung:
+
+- Oeffnen, Schliessen und Abschliessen des Hauses von innen
+- Einraeumen und Entziehen von Sonderrechten mit "erlaube" und "verbiete"
+- Benutzen des Gucklochs in der Tuer mit dem Befehl "spion"
+- Mitteilung ueber angesammelte 'typo'-Meldungen seit dem letzten Betreten
+- "uebersicht" zeigt zusaetzlich die Leute auf der erlaube-Liste
+
+
+5d. Die Truhe
+-------------
+
+Die Truhe kann unendlich viele Gegenstaende aufnehmen.
+Aendern lassen sich Geschlecht, Name, Adjektive (aus diesen dreien wird die
+Kurzbeschreibung zusammengesetzt), IDs, Langbeschreibung und Material.
+Die ID "\t\ruhe" ist IMMER gesetzt.
+Die Truhe laesst sich innerhalb des Hauses frei verschieben. In dem Raum,
+in dem sie steht, ist die Property H_CHEST auf 1 gesetzt.
+Typomeldungen der Truhe gehen in das Reportfile des Hausbesitzers.
+
+Problem: Ab und zu geben einige Spezialisten bei der Beschreibung der IDs
+schon die Langbeschreibung ein. Danach koennen sie die Truhe nicht mehr
+ansprechen.
+Loesung: Von Hand eine ID setzen und die Truhe mit Save() speichern.
+
+Ideen: Zustand der Truhe (geoeffnet/geschlossen) beschreibbar machen und
+optional ganz weglassen. Machbar ueber H_DOORLSTAT. In short() sind schon
+die entsprechenden Vorkehrungen getroffen; "beschreibe truhe status" wird
+auch schon abgefragt, aber noch nicht ausgewertet. Ausserdem muesste die
+Kurzbeschreibung dann explizit angegeben werden.
+
+Oeffnen koennen die Truhe nur Leute mit Erlaubnis. Schliessen kann sie
+jeder. Verschieben kann sie nur der Hausbesitzer.
+
+Die Daten der Truhe werden in _set_owner() geladen. Dieser Funktion wiederum
+wird von dem Raum aufgerufen, in dem die Truhe steht (modules/losa::Load()).
+
+
+6. Seherbank/Hauserwerb
+=======================
+
+Die Bank steht in Drachenhort. Wesentliche Bestandteile sind drei Schalter
+mit entsprechenden Warteschlangen.
+
+Der Antragsschalter - sb_antrag.c
+ Hier erhaelt man die Vertraege fuer ein Haus oder einen neuen Raum. Einen
+ Ausbauvertrag bekommt man allerdings erst dann, wenn das Haus schon steht.
+ Vertraege werden nur an Seher ausgehaendigt, die keinen PK haben.
+
+Der Vertrag - bausparvertrag.c
+ Erhaeltlich am Antragsschalter.
+ Der Vertrag muss auch am Antragsschalter unterschrieben werden. Die Unter-
+ schrift wird mit Blut bestaetigt, wodurch ein reduce_hit_point(50) faellig
+ wird. ;)
+ Auf ihm wird jede eingezahlte Rate vermerkt.
+ Will man doch kein Haus, kann man den Vertrag jederzeit zerreissen. Die
+ eingezahlten EP sind dann allerdings weg.
+ Nach der Unterschrift bekommt man den Master-Block ueberreicht.
+
+Der Master-Block - block.c
+ Der Block nimmt die aktuellen Raten auf. Dazu dient der block_shadow
+ (in /std/player/shadows/), der immer dann aktiviert wird, wenn man den
+ Block anzieht (er ist eine AT_MISC-Ruestung, schuetzt also nicht).
+ Der Shadow leitet AddExp()-Aufrufe an dem Block um. Bei mindestens
+ 30-40 EP wird alles bis auf den Mindestanteil auf den Block eingezahlt,
+ und der Mindestanteil kommt dem Spieler zugute.
+
+Der Einzahlungsschalter - sb_einzahlung.c
+ Ist die Master-Block voll, kann man ihn hier vorlegen. Die Rate wird dann
+ auf den Vertrag gebucht, und man bekommt einen neuen Block fuer die
+ naechste Rate (soweit man noch nicht fertig ist).
+
+Der Ausgabeschalter - sb_ausgabe.c
+ Hat man alle Raten eingezahlt, kann man hier nach Vorlage des Vertrags die
+ Fruechte seiner Arbeit ernten.
+ Handelte es sich um einen Hausvertrag, bekommt man ein Instanthaus ausge-
+ haendigt.
+ Handelte es sich um einen Ausbauvertrag, wird die Raumzahl des Hauses um
+ eins erhoeht (man bekommt kein Objekt in die Hand; vielmehr kann man in
+ seinem Haus jetzt einen Ausgang in den neuen Raum legen).
+ ALLERDINGS: Um Haus oder Raum auszugeben, muessen in der Zentralbank
+ mindestens 30000 Muenzen vorhanden sein (damit deckt die Seherbank die
+ Materialkosten). Solange nicht genug Geld da ist, gibts auch kein Haus.
+ Der Seher hat zwei Alternativen: a) warten, bis genug Geld da ist, oder
+ b) zum Ende der Welt reisen und das Geld in den Geldspeicher der Zentral-
+ bank werfen.
+
+Eine Rate umfasst 80000 EP.
+Es gibt zwei Vertragsvarianten: sanft und schnell.
+Bei der sanften Variante hat man 4 Stunden Zeit, um die Rate zu sammeln, bei
+der schnellen Variante sind es 2 Stunden.
+Diese Zeiten werden nach Online-Zeit gemessen, nicht nach RL-Zeit. :)
+Fuer ein Haus benoetigt man bei den sanften Variante 30 Raten, bei der
+schnellen Variante 25 Raten.
+Fuer einen Raum sind es 12 Raten bei der sanften und 10 Raten bei der
+schnellen Variante.
+Ueberzieht man die Zeit, erhoeht sich die Ratenhoehe um 60% auf 128000 EP.
+Man hat bei beiden Varianten eine Stunde Zeit, die Rate noch zu erfuellen.
+Schafft man es nicht, verfaellt der Vertrag => alles ist weg.
+Das Zeitlimit gilt nur fuer das Fuellen des Blocks. Wenn er erst man voll
+ist, braucht man nicht innerhab des Limits zur Bank, um den naechsten
+Block zu holen.
+
+7. Beschreibungen
+=================
+
+Folgende Aspekte der Raumbeschreibung lassen sich veraendern:
+
+- Details "beschreibe detail <det>" P_DETAILS
+- ReadDetails "beschreibe lesbares detail <det>" P_READ_DETAILS
+- Langbeschr. "beschreibe haus/raum lang" (auch aussen) P_(INT_)LONG
+- Kurzbeschr. "beschreibe haus/raum kurz" P_INT_SHORT
+- Ausgaenge "ausgang <richtung> <nr>" / "sperre richtung" P_EXITS
+- Licht "licht an/aus" P_LIGHT
+- Befehle "beschreibe befehl <bef>" H_COMMANDS
+
+Details, ReadDetails und Befehle lassen sich auch kopieren, allerdings immer
+nur innerhalb der jeweiligen Propertygruppe (es laesst sich also kein Detail
+zu den ReadDetails kopieren).
+
+Ausserdem lassen sich Details, ReadDetails, Befehle und die Langbeschreibung
+aendern. Das laeuft aehnlich wie beim Beschreiben, allerdings wird der
+aktuell vorhandene Text als Vorgabe verwendet.
+
+
+7a. Details/ReadDetails/Lang- und Kurzbeschreibung
+--------------------------------------------------
+
+Hier passiert nicht viel mit dem eingegebenen Text. @@ werden durch **
+ersetzt, damit nicht aus Versehen oder beabsichtigt process_string()
+ausgeloest wird.
+
+Bei der Kurzbeschreibung wird noch geprueft, ob sie laenger als 75 Zeichen
+oder eine Zeile ist (falls ja, wird sie nicht uebernommen).
+
+Moegliche Erweiterungen: Rassenspezifische Details (das muss bisher ueber
+Bfehle gemacht werden), und da AddSmells()/AddSounds() jetzt "offiziell" in
+sind, vielleicht auch die Moeglichkeit, Gerueche und Geraeusche zu
+beschreiben.
+
+7b. Ausgaenge
+-------------
+
+Moegliche Ausgaenge sind die acht Himmelsrichtungen, "oben" und "unten".
+Legt man einen Ausgang an, wird automatisch im Zielraum ein Ausgang in die
+entsprechende Rueckrichtung angelegt.
+Das Anlegen klappt nur, wenn es noch keinen Ausgang in diese Richtung gibt,
+und im Zielraum noch keinen Ausgang in die Rueckrichtung.
+Soll ein Ausgang in ein benachbartes Seherhaus gelegt werden, muss man dort
+darueberhinaus auf der erlaube-Liste stehen.
+Beim Sperren eines Ausgangs wird der entsprechende Ausgang im Zielraum
+automatisch mit entfernt.
+
+Der Grund fuer dieses symmetrische Verhalten liegt darin, dass man auf diese
+Weise keine Spieler in seinem Haus einsperren kann (Ausgang in einen Raum,
+ohne dass es zurueck geht).
+Um die Ausgaenge einander einfach zuordnen zu koennen, sind auch keine selbst
+erfundenen Richtungen moeglich (koennte man allerdings implementieren, indem
+man explizit nach der Rueckrichtung fragt).
+
+
+7c. Licht
+---------
+
+P_LIGHT wird so gesetzt, dass es im Haus mit dem momentanen Lichtlevel gerade
+dunkel oder hell wird. Hat man also nen Gesamtlichtlevel von 20 (durch
+genuegend Lichtkugeln o.ae.) und macht "licht aus", wird P_LIGHT auf -20
+gesetzt.
+
+
+7d. Befehle
+-----------
+
+Um die Auswertung zu vereinfachen, werden die Platzhalter in den Befehls-
+texten in kuerzere Token umgewandelt (Funktion preparse()).
+Die Auswertung erfolgt von modules/usercmd.c aus.
+
+In preparse() werden im wesentlichen die Faelle fuer Namen, Personal- und
+Possessivpronomina in die Zahlen umgesetzt, die den entsprechenden
+Funktionen (name(), QueryPronoun(), QueryPossPronoun()) uebergeben werden.
+Ausgewertet werden sie von usercmd::ucFilter().
+
+Die Auswertung rassenspezifischer Texte muss angepasst werden, wenn neue
+Rassen ins MG kommen. Betroffen davon ist usercmd::ucText().
+Die rassenspezifischen Texte werden durch Platzhalter der Form @RX vonein-
+ander getrennt, wobei X ein Buchstabe fuer die Rasse ist.
+Bei einer neuen Rasse muesste dieser Buchstabe in der regexplode-Zeile am
+Anfang von ucText() in den eckigen Klammern eingefuegt werden, und eine
+entsprechende Abfrage in die switch()-Anweisung rein.
+Und natuerlich sollte die Hilfeseite ("befehl") geupdated werden :)
+
+Bisher sind reine Textausgabebefehle moeglich.
+Einige Seher haben sich weitere Moeglichkeiten gewuenscht, z.B. so etwas
+wie SpecialDetails oder SpecialExits. Dafuer muesste man Zustaende setzen
+und aendern koennen (Property H_VARS oder so?). Allerdings wird dadurch
+die Beschreibung an sich wieder komplizierter.
+
+
+8. Rueckmeldungen
+=================
+
+Die Raeume, die Aussenansicht des Hauses und die Truhe haben eine Funktion
+SmartLog(). Diese Funktion wird von /std/player/base::smart_log() aus auf-
+gerufen und uebernimmt das Loggen der Typo-, Idee- und Fehlermeldungen.
+Die Meldungen werden int "rep/<name>.rep" abgelegt.
+Der Hausbesitzer wird jeweils beim Betreten des Eingangsraumes informiert,
+wie viele Rueckmeldungen sich seit dem letzten Betreten angesammelt haben.
+Ansehen kann er sich die Meldungen mit dem Befehl "meldungen", und mit
+"aendere" oder "beschreibe" kann er die Typos beheben.
+Mit "aendere meldungen" kann er die abgearbeiteten Meldungen aus seinem
+.rep-File entfernen.
+
+
+9. Hilfeseiten
+==============
+
+Die "Arbeitsversionen" der Seiten liegen in doc/, die "offiziellen" Versionen
+in /doc/scmd.
+"beschreibe befehl" hat eine Extraseite ("hilfe befehl"), weil die Seite fuer
+"beschreibe" sonst zu gross waere.
diff --git a/d/seher/haeuser/haus.c b/d/seher/haeuser/haus.c
new file mode 100644
index 0000000..d61471c
--- /dev/null
+++ b/d/seher/haeuser/haus.c
@@ -0,0 +1,361 @@
+//
+// haus.c -- Das Rohgeruest eines Seherhauses.
+//
+// Grundobjekt (c) 1994 Boing@MorgenGrauen
+// Abschliessen und Rauswerfen von Jof
+// Fuer Aenderungen ab dem 06.10.94 verantwortlich: Wargon
+//
+// $Date: 1996/02/21 18:09:55 $
+// $Revision: 2.8 $
+/* $Log: haus.c,v $
+ * Revision 2.8 1996/02/21 18:09:55 Wargon
+ * SmartLog() fuer Rueckmeldungen eingebaut.
+ *
+ * Revision 2.7 1995/07/06 11:18:07 Wargon
+ * Langbeschreibung aenderbar.
+ *
+ * Revision 2.6 1995/04/21 10:48:20 Wargon
+ * Bugfix in "beschreibe tuerstatus".
+ *
+ * Revision 2.5 1995/04/21 08:56:55 Wargon
+ * Haustuer ausgelagert.
+ * 'beschreibe tuerzustand' ist dazugekommen.
+ *
+ * Revision 2.4 1995/02/27 20:47:32 Wargon
+ * Diverse Bugs gefixed...
+ *
+ * Revision 2.2 1995/02/15 11:19:17 Wargon
+ * Die Haustuer kann jetzt auch beschrieben werden (H_DOOR).
+ *
+ * Revision 2.1 1995/02/04 14:51:14 Wargon
+ * Statt "Haus" wird weitestgehend name() verwendet.
+ *
+ * Revision 2.0 1995/02/01 20:40:26 Wargon
+ * Das Haus ist jetzt nur noch ein Objekt in einem Raum, nicht
+ * mehr ein Raum im Raum.
+ *
+ */
+#include "haus.h"
+#include <properties.h>
+#include <moving.h>
+#include <wizlevels.h>
+
+inherit "/std/thing";
+inherit HAUSTUER;
+
+private nosave string text;
+private nosave string owner;
+
+void create()
+{
+ if (!clonep(this_object())) return;
+
+ thing::create();
+ haustuer::create();
+
+ SetProp(P_NAME, ({ "Haus", "Hauses", "Haus", "Haus" }));
+ SetProp(P_IDS, ({"haus","sehe\rhaus"}));
+ SetProp(P_GENDER, NEUTER);
+ SetProp(P_NOGET,1);
+
+ Set(P_LONG, SAVE, F_MODE);
+ Set(P_SHORT, SAVE, F_MODE);
+ Set(P_IDS, SAVE, F_MODE);
+ Set(P_GENDER, SAVE, F_MODE);
+ Set(P_NAME, SAVE, F_MODE);
+
+ text = 0;
+
+ AddCmd( ({"betritt", "betrete"}), "betritt" );
+ AddCmd( ({"beschreib", "beschreibe"}), "beschreiben");
+ AddCmd( ({"aender", "aendere"}), "aendern");
+ AddCmd( ({"klopf","klopfe"}), "klopfen");
+ AddCmd("erlaube", "erlauben");
+ AddCmd("verbiete", "verbieten");
+ AddCmd("notiz", "merktext");
+}
+
+varargs void Save(int crunched)
+{
+ save_object(HAUSSAVEPATH+owner);
+}
+
+void Load()
+{
+ restore_object(HAUSSAVEPATH+owner);
+}
+
+void init()
+{
+ // statt im Haus landet man im Hauptraum Raum 0, sollte ansich nicht passieren
+ // da man nomalerweise nicht ins Haus sondern direkt in den Hauptraum gemoved wird
+ if (environment(this_player()) == this_object()) {
+ this_player()->move(RAUMNAME(owner,0), M_GO | M_NO_SHOW | M_SILENT);
+ return;
+ }
+ ::init();
+}
+
+// Extra fuer Boing! ;)
+// Setzt man P_SHORT des Hauses auf 0, so verschwindet es zwar aus
+// der Beschreibung des Raumes, ist aber immer noch ansprechbar!
+string short()
+{
+ string ret;
+
+ ret = ::short();
+ if (previous_object() != environment() && !ret)
+ ret ="";
+
+ return ret;
+}
+
+// Zustand der Haustuer und evtl. Notiz mit einbauen.
+varargs string long(int mode)
+{
+ string ret, door;
+
+ door = haustuer::long(mode);
+
+ ret = QueryProp(P_LONG)+door;
+ if (text) {
+ ret += break_string( "An "+name(WEM,1)+" befindet sich eine Notiz: '"+text+"'.", 75);
+ }
+ return break_string(ret, 75);
+}
+
+// Setze neuen Besitzer fuer dieses Haus
+// setzt Default-Short, -Long und Id fuer neuen Besitzer,
+// leitet Besitzer an Haustuer weiter und laedt den Hauptraum
+varargs string SetOwner(string o)
+{
+ SetProp(P_SHORT, "Das Haus von "+capitalize(o));
+ SetProp(P_LONG, "Das Haus von "+capitalize(o)+", es sieht sehr nach einem Rohbau aus.\n");
+ AddId( ({ "\n"+o+"haus", "haus von "+o }) );
+ haustuer::SetTuerOwner(o);
+ load_object(RAUMNAME(o,0));
+ return owner = o;
+}
+
+// liefert den Name des Haus-Besitzers
+string QueryOwner() { return owner; }
+
+private int tp_ownercheck()
+{
+ if(getuid(this_player()) != owner)
+ {
+ notify_fail( "Das ist nicht Dein Haus!\n" );
+ return 0;
+ }
+ return 1;
+}
+
+// Aktion zum Betreten
+static int betritt(string str)
+{
+ notify_fail("Was moechtest Du betreten?\n");
+
+ // Haus war nicht angesprochen
+ if (!str || !id(str))
+ return 0;
+
+ // Haustuer ist zu
+ if (Query(H_DOORSTAT) & D_CLOSED) {
+ printf("%s von %s ist zu.\n", capitalize(name(WER,1)), capitalize(owner));
+ return 1;
+ }
+ // bewege Spieler in Hauptraum
+ this_player()->move(RAUMNAME(owner,0), M_GO, 0, "betritt "+name(WEN,1), "kommt herein");
+ return 1;
+}
+
+// Aktion zum Setzen/Loeschen von Notizen am Haus
+static int
+merktext(string str)
+{
+ // darf der Spieler das, d.h. ist das sein Haus?
+ if(!tp_ownercheck())
+ {
+ notify_fail( "Du kannst keine Notiz an "+capitalize(name(WEM,1))+" von "+capitalize(owner)+" anbringen!\n" );
+ return 0;
+ }
+
+ str = this_player()->_unparsed_args();
+
+ // kein Text => Notiz loeschen, ansonsten => Text als Notiz setzen
+ if (!str || str == "") {
+ write( "OK, Notiz ist geloescht.\n" );
+ text = 0;
+ }
+ else {
+ write( "OK, Notiz lautet '"+str+"'\n");
+ text = str;
+ }
+
+ return 1;
+}
+
+// Aktion Anklopfen am Haus
+static int
+klopfen(string str)
+{
+ int i;
+ object room;
+
+ notify_fail( "Syntax: klopfe an <haus> an\n" );
+ // parsen von klopfe an <haus> an
+ if (!str || sscanf(str, "an %s an", str) != 1)
+ return 0;
+
+ if (str == "tuer" || str == "haustuer" || id(str)) {
+ // Meldungen an Spieler und Raum
+ printf( "Du klopfst an "+name(WEM,1)+" von "+capitalize(owner)+" an.\n");
+ say( capitalize(this_player()->name(WER))+" klopft an "+name(WEM,1)+" von "+capitalize(owner)+" an.\n" );
+ // in allen geladenen Raeumen Klopfen melden
+ for (i=VERWALTER->HausProp(owner,HP_ROOMS); i>=0; i--) {
+ if (room = find_object(RAUMNAME(owner,i)))
+ tell_room(room, "Du hoerst, wie jemand an der Haustuer anklopft.\n" );
+ }
+ return 1;
+ }
+ return 0;
+}
+
+// Aktion Tuer/Haus beschreiben
+static int
+beschreiben(string str)
+{
+ string *p, *ds;
+
+ // darf der Spieler das, d.h. ist das sein Haus?
+ if (!tp_ownercheck())
+ return 0;
+
+ notify_fail( "Hier draussen funktioniert nur 'beschreibe <haus> lang',\n"
+ +"'beschreibe haustuer' oder 'beschreibe tuerzustand'!\n");
+
+ // zu wenig Eingabe zum Parsen
+ if (!str || str == "")
+ return 0;
+
+ p = old_explode(str," ");
+
+ if (p[0] == "tuer" || p[0] == "haustuer") {
+ // beschreibe (haus)tuer
+ write( "Beschreibung der Haustuer angeben. Es ist nur eine Zeile moeglich.\n"
+ +"Als Platzhalter fuer den Zustand der Tuer dient %s. Falls die Tuer\n"
+ +"nicht in der Langebschreibung des Hauses auftauchen soll, bitte ein-\n"
+ +"fach nur <RETURN> druecken.\n]" );
+ input_to("doorDesc");
+ return 1;
+ }
+ else if (p[0] == "tuerzustand") {
+ // beschreibe tuerzustand
+ ds = Query(H_DOORLSTAT);
+ write( "Beschreibung des Tuerzustandes angeben. Es ist nur eine Zeile moeg-\n"
+ +"lich. Die Zustaende muessen durch Kommata getrennt in der Reihen-\n"
+ +"folge 'offen', 'geschlossen', 'abgeschlossen' angegeben werden.\n"
+ +"Momentaner Zustand:\n");
+ printf("'%s', '%s', '%s'.\n", ds[0], ds[1], ds[3]);
+ write( "(Abbruch: Einfach <RETURN> druecken!)\n]");
+ input_to("doorLDesc");
+ return 1;
+ }
+ else if (p[<1] == "lang" && id(implode(p[0..<2]," "))) {
+ object home = load_object(RAUMNAME(owner,0));
+ // beschreibe <haus> lang
+ home->beschreiben("haus lang", AUSSEN);
+ return 1;
+ }
+ // Eingabe Syntax nicht passend => notify_fail von oben
+ return 0;
+}
+
+// Aktion Haus Aendern
+static int
+aendern(string str)
+{
+ string *p, *ds;
+
+ // Darf der Spieler das, d.h. ist das sein Haus?
+ if (!tp_ownercheck())
+ return 0;
+
+ notify_fail( "Hier draussen funktioniert nur 'aendere <haus> lang'!\n");
+ // zu wenig Eingabe zum Parsen
+ if (!str || str == "")
+ return 0;
+
+ p = old_explode(str," ");
+
+ if (p[<1] == "lang" && id(implode(p[0..<2]," "))) {
+ object home = load_object(RAUMNAME(owner,0));
+ // aendere <haus> lang
+ home->aendern("haus lang", AUSSEN);
+ return 1;
+ }
+ // Eingabe Syntax nicht passend => notify_fail von oben
+ return 0;
+}
+
+// input_to zu beschreibe (haus)tuer
+static void doorDesc(string str)
+{
+ if (!str)
+ str = "";
+ if (sizeof(str))
+ str += "\n";
+
+ Set(H_DOOR, str);
+ Save();
+
+ if (str == "")
+ write("OK, Haustuer wurde geloescht.\n");
+ else
+ write("OK, Beschreibung der Haustuer wurde gesetzt.\n");
+}
+
+// input_to zu beschreibe tuerzustand
+static void doorLDesc(string str)
+{
+ string *s;
+
+ if (!str || sizeof(s=old_explode(str, ","))!=3) {
+ write("ABBRUCH!\nNichts geaendert!\n");
+ return;
+ }
+ Set(H_DOORLSTAT, ({ s[0], s[1], 0, s[2] }));
+ printf("OK, Tuerzustaende sehen wie folgt aus:\n'%s', '%s', '%s'.\n",
+ s[0], s[1], s[2]);
+ Save();
+}
+
+int SmartLog(string ofile, string typ, string msg, string date)
+{
+ object home;
+ string foo, bar;
+
+ string hn=RAUMNAME(owner,0);
+
+ write_file(REPFILE(owner), sprintf("%s von %s vor dem Haus (%s):\n%s\n",
+ typ,
+ capitalize(getuid(this_player())),
+ date,
+ break_string(msg,78)));
+
+ if (IS_LEARNER(owner)) {
+ log_file("report/"+owner+".rep",
+ sprintf("MELDUNG von %s im Seherhaus, vor dem Haus (%s):\n"
+ +"Bitte zur Kenntnis nehmen! (Mit dem Befehl 'meldungen') -Wargon\n",
+ capitalize(getuid(this_player())),
+ date));
+ }
+
+ home = load_object(hn);
+ home->Set(H_REPORT, home->Query(H_REPORT)+1);
+ home->Save();
+
+ return 1;
+}
+
+
diff --git a/d/seher/haeuser/haus.h b/d/seher/haeuser/haus.h
new file mode 100644
index 0000000..873956e
--- /dev/null
+++ b/d/seher/haeuser/haus.h
@@ -0,0 +1,156 @@
+// haus.h -- Definitionen fuer die Seherhaeuser
+//
+// Grundobjekt (c) 1994 Boing@MorgenGrauen
+// Abschliessen und Rauswerfen von Jof
+// Fuer Aenderungen ab dem 06.10.94 verantwortlich: Wargon
+//
+// $Id: haus.h,v 1.2 2003/05/03 13:09:05 mud Exp $
+//
+#ifndef __HAUS_H__
+#define __HAUS_H__
+
+// #define DEBUG(x) if (find_player("vanion")) tell_object(find_player("vanion"),x);
+//#define HDEBUG(x) if(find_player("vanion")) \
+// tell_object(find_player("vanion"),break_string((x),78,"HDBG: ",1))
+#define HDEBUG(x)
+
+// Maintainer wird u.a. benutzt, um die access_rights zu regeln
+#define MAINTAINER ({"vanion"})
+#define IS_MAINTAINER(x) (member(MAINTAINER, getuid(x))!=-1)
+
+/*** Pfade ***/
+#define HAEUSERPFAD "/d/seher/haeuser/"
+#define HAUSSAVEPATH HAEUSERPFAD+"save/"
+#define SPECIALPATH HAEUSERPFAD+"special/"
+#define VERWALTER (HAEUSERPFAD+"hausverwalter")
+#define HAUS HAEUSERPFAD+"haus"
+#define RAUM HAEUSERPFAD+"raum"
+#define SAVEFILE HAUSSAVEPATH+"haeuser"
+#define HAUSNAME(x) (HAEUSERPFAD+x+"haus")
+#define RAUMNAME(x,n) (HAEUSERPFAD+x+"raum"+to_string(n))
+#define REPFILE(x) (HAEUSERPFAD+"rep/"+x+".rep")
+#define HLOG(f,x) write_file(HAEUSERPFAD+"log/"+(f), dtime(time())+" - "+(x))
+
+/* PATH bitte nicht mehr benutzen!
+ * Dieser #define existiert nur noch aus Kompatibilitaetsgruenden.
+ */
+#ifndef PATH
+#define PATH HAEUSERPFAD
+#endif
+
+/*** Module ***/
+#define USERCMD HAEUSERPFAD+"modules/usercmd"
+#define LOSA HAEUSERPFAD+"modules/losa"
+#define HAUSTUER HAEUSERPFAD+"modules/haustuer"
+
+/*** Bausparvertrag und Ratenblock ***/
+#define SUMME_L 30*RATENHOEHE /* Soviel kostet das gute Stueck (langsam) */
+#define SUMME_S 25*RATENHOEHE /* Und soviel bei der schnellen Variante */
+#define RATENHOEHE 80000 /* Einzahlbar per Ratenblock */
+#define MAX_TIME 7200 /* Laufzeit der Raten: 4 Stunden = 7200 heart_beats */
+#define WARN_TIME 450 /* Abstand zwischen den Warnungen: 15 Minuten */
+
+#define V_MONEY 0 // Das schon eingezahlte Geld
+#define V_DLINE 1 // die Deadline
+#define V_WTIME 2 // Zeit bis zur naechsten Erinnerung
+#define V_FLAGS 3 // Diverse Flags
+
+#define V_SIGNED 1 // Vertrag schon unterschrieben
+#define V_FAST 2 // Schnelle Variante
+#define V_COMPL 4 // Vertrag erfuellt
+#define V_RAUM 8 // Ausbauvertrag
+#define V_EP 16 // EP-Vertrag
+
+#define B_FAST 1 // Block gehoert zur schweren Variante
+#define B_EXTEND 2 // Strafzeit laeuft
+#define B_ACTIVE 4 // Shadow laden
+#define B_SHADOW 8 // Shadow laeuft...
+#define B_EP 16 // EP-Vertrag
+
+/*** Tuerstatus ***/
+#define D_CLOSED 1
+#define D_LOCKED 2
+
+/*** Beschreibungsflags ***/
+#define AUSSEN 1
+#define KURZ 2
+#define LANG 4
+#define DETAIL 8
+#define RDETAIL 16
+#define BEFEHL 32 // Nur aendern
+#define REPORT 64 // Nur aendern
+
+/*** Flags fuer HausProp() ***/
+#define HP_ENV 0 // Name des Raums, in dem das Haus steht (string)
+#define HP_ROOMS 1 // Anzahl der Raeume, die das Haus besitzt (int)
+#define HP_ALLOWED 2 // Wer hat Sonderbefugnisse im Haus? (string *)
+
+/*** Vermischtes ***/
+#define H_CHEST "h_chest" // Wenn gesetzt, steht in diesem Raum die Truhe
+#define TRUHE "\t\ruhe" // Und diese ID hat die Truhe in jedem Fall.
+#define H_COMMANDS "h_commands" // Enthaelt mapping mit Befehlen.
+#define H_DOOR "h_door" // Enthaelt die Beschreibung der Tuer.
+#define H_DOORSTAT "h_doorstat" // Enthaelt den Zustand der Haustuer.
+#define H_DOORLSTAT "h_doorlstat" // Tuerzustand als Stringarray.
+#define H_REPORT "h_report" // Info ueber typo/bug/idee im Haus
+#define H_SPECIAL "h_special" // Besonderheiten im Haus
+#define H_FURNITURE "h_furniture" // Rebootfeste Sehermoebel
+
+/*** Typen fuer H_SPECIAL ***/
+#define HS_ITEM 1 // ein bestimmtes Objekt (per AddItem())
+#define HS_EXIT 2 // ein Ausgang (per AddExit())
+
+/*** Einstellungen fuer Furniture ***/
+#define MAX_FURNITURE_PER_ROOM 5
+
+/*** Last but not least... ***/
+#define UP_ARGS(o) ((o)->_unparsed_args(1))
+
+#endif // __HAUS_H__
+
+#ifdef NEED_PROTOTYPES
+
+#ifndef __HAUS_H_PROTOS__
+#define __HAUS_H_PROTOS__
+
+varargs void Save(int crunched);
+void Load();
+varargs string QueryOwner(int withNr);
+varargs string SetOwner(string o, int nr);
+protected void AddExitNoCheck(mixed cmd, mixed dest);
+void RemoveExitNoCheck(mixed cmd);
+
+#endif /* __HAUS_H_PROTOS__ */
+#endif /* NEED_PROTOTYPES */
+
+// $Log: haus.h,v $
+// Revision 1.2 2003/05/03 13:09:05 mud
+// PATH in HAEUSERPFAD umbenannt
+//
+// Revision 1.1.1.1 2000/08/20 20:22:42 mud
+// Ins CVS eingecheckt
+//
+// Revision 2.7 1995/06/28 08:58:07 Wargon
+// H_REPORT fuer Spielerrueckmeldungen.
+// Flags BEFEHL und REPORT fuer Aenderungen.
+//
+// Revision 2.6 1995/04/21 08:53:57 Wargon
+// #defines fuer Modularisierung und neue Tuerfeatures.
+//
+// Revision 2.5 1995/02/27 20:54:49 Wargon
+// UP_ARGS angepasst, da Parser jetzt auch fuer Spieler aktiv.
+//
+// Revision 2.3 1995/02/15 11:15:08 Wargon
+// H_DOOR: Enthaelt die Beschreibung der Haustuer.
+//
+// Revision 2.2 1995/02/04 17:18:39 Wargon
+// H_COMMANDS: enthaelt mapping mit selbstdefinierten Hausbefehlen.
+// CHEST in H_CHEST umbenannt.
+//
+// Revision 2.1 1995/02/04 15:06:18 Wargon
+// Definition von CHEST als Property fuer den Standort der Truhe und
+// TRUHE als feste ID der Truhe.
+//
+// Revision 2.0 1995/02/01 20:45:18 Wargon
+// UP_ARGS-Makro, liefert fuer ALLE das Ergebnis von _unparsed_args(1)
+//
diff --git a/d/seher/haeuser/hausverwalter.c b/d/seher/haeuser/hausverwalter.c
new file mode 100644
index 0000000..26643d1
--- /dev/null
+++ b/d/seher/haeuser/hausverwalter.c
@@ -0,0 +1,621 @@
+/*
+ * hausverwalter.c -- Verwaltung der Seherhaeuser
+ *
+ * Das Grundobjekt stammt von Boing, Fortfuehrung erfolgte durch Jof.
+ * Letzte Aenderungen verschuldet durch Wargon ;)
+ *
+ * $Date: 1997/09/09 17:19:29 $
+ * $Revision: 2.3 $
+ * $Log: hausverwalter.c,v $
+ * Revision 2.3 1997/09/09 17:19:29 Wargon
+ * Bugfix beim Verlegen/Loeschen eines Hauses
+ *
+ * Revision 2.2 1996/02/21 18:15:02 Wargon
+ * *** empty log message ***
+ *
+ * Revision 2.0 1994/11/17 13:48:27 Wargon
+ * Modifikationen fuer die Trennung Haus/Raum.
+ *
+ * Revision 1.5 1994/10/24 08:21:55 Wargon
+ * Parameter fuer NeuesHaus geaendert.
+ * Fuer Sicherheitscheck secure() eingebaut.
+ * VerlegeHaus() eingebaut, falls ein Haus mal verlegt werden muss.
+ *
+ * Revision 1.4 1994/10/10 21:50:59 Wargon
+ * NeuesHaus() und LoescheHaus() bedienen nun auch den OBJECTD.
+ * PruefeHaus() wurde damit hinfaellig.
+ *
+ * Revision 1.3 1994/10/09 20:11:48 Wargon
+ * Beschreibung der Haeuser vom Hausverwalter abgekoppelt!
+ * Die megamap enthaelt nur noch Besitzer und Standort des Hauses.
+ * Infolgedessen sind Save() und build() rausgeflogen...
+ *
+ * Revision 1.2 1994/10/07 22:19:48 Wargon
+ * AUFBAU DES MAPPINGS GEAENDERT! Der Filename des Raumes, in dem das
+ * Haus steht, steht jetzt als erster Eintrag im Mapping! Alle anderen
+ * Eintraege sind um 1 weitergewandert.
+ * Beim Laden des Verwalters werden nicht mehr alle Seherhaeuser ge-
+ * laden. Ein Haus wird erst geladen, wenn der Raum, in dem es steht,
+ * geladen wird (PruefeHaus(), siehe auch std/room::create()).
+ *
+ * Revision 1.1 1994/10/07 14:19:36 Wargon
+ * Initial revision
+ *
+ */
+#pragma strict_types
+#include <properties.h>
+#include <wizlevels.h>
+#include <rooms.h>
+#include <moving.h>
+#include "haus.h"
+
+#define H_MAX_ROOMS 9
+
+mapping megamap;
+
+// Haus fuer owner im Raum env erstellen. Wird i.d.R nur vom Instanthaus gemacht.
+void NeuesHaus(string owner, object env);
+
+// Haus von owner loeschen (samt Savefile!). Dieser Vorgang ist unwiderruflich!
+int LoescheHaus(string owner);
+
+// Loescht den letzten hinzugefuegten Raum im Seherhaus von 'owner'.
+void LoescheRaum(string owner);
+
+// Fuegt einen Raum zum Seherhaus von 'owner' hinzu.
+void NeuerRaum(string owner);
+
+// Haus von owner vom Raum 'von' in den Raum 'nach' verschieben.
+int VerlegeHaus(string owner, string von, string nach);
+
+// Kann in ob ein Haus gebaut werden? 0: Ja, sonst Fehler!
+int Unbebaubar(object ob);
+
+// Jemandem im Haus Zusatzrechte einraeumen/entziehen
+string *Erlaube(string owner, string *wer);
+string *Verbiete(string owner, string *wer);
+
+// Eigenschaften aus der megamap abfragen
+mixed HausProp(string owner, int prop);
+
+// Propertymapping deduplizieren
+mixed PCrunch(mapping prop);
+
+// Lade Seherhaus von Besitzer 'owner'
+object _LadeHaus(string owner);
+
+// Lade im Seherhaus von 'owner' den Raum mit der Nummer 'num'
+object _LadeRaum(string owner, int num);
+
+// returnt das Seherhaus von Besitzer 'owner'
+object FindeHaus(string owner);
+
+void create()
+{
+ if (!restore_object(SAVEFILE))
+ megamap = ([ ]);
+ seteuid(getuid(this_object()));
+}
+
+int query_prevent_shadow(object ob)
+{
+ HLOG("SHADOW",sprintf( "%s, von %O im Verwalter.\n",dtime(time())[5..], ob));
+ return 1;
+}
+
+private int
+secure()
+{
+ int ar;
+
+ if (!this_interactive())
+ return 0;
+
+ // das tragbare Instanthaus und die Hausausgabe duerfen:
+ if ((load_name(previous_object()) == PATH+"traghaus") ||
+ (load_name(previous_object()) == PATH+"sb_ausgabe")) {
+ return 1;
+ }
+
+ catch(ar = (int)(PATH+"access_rights")->access_rights(geteuid(this_interactive()), "haus.h"));
+
+ // Erzmagier und alle mit Schreibrechten auf haus.h duerfen
+ if ( (this_interactive() == this_player()) &&
+ (IS_ARCH(this_interactive()) || ar ) )
+ return 1;
+ return 0;
+}
+
+// ersetzt das HAEUSER logfile mit neuer Statistik
+private void
+dump()
+{
+ string *ind;
+ int i, hnum, rnum = 0;
+
+ // loesche logfile
+ rm(PATH+"HAEUSER");
+
+ // betrachte alle Seherhaeuser
+ ind = m_indices(megamap);
+ if (hnum=sizeof(ind)) {
+ write_file(PATH+"HAEUSER", sprintf("Es gibt %d Seherhaeuser:\n", hnum));
+ ind = sort_array(ind,#'>); //'
+ // alle Haeuser sortiert nach Besitzername durchgehen:
+ for(i = 0; i < hnum; ++i) {
+ // zaehle Raeume
+ ++rnum; // Hauptraum
+ rnum += (megamap[ind[i], HP_ROOMS]); // Nebenraeume
+ // Eine Zeile pro Haus: Besitzername (Raumanzahl) Standort-Pfad
+ write_file(PATH+"HAEUSER",
+ sprintf( "%-13s (%d) %s\n",
+ capitalize(ind[i]),
+ megamap[ind[i],HP_ROOMS],
+ megamap[ind[i],HP_ENV] ) );
+ }
+ write_file(PATH+"HAEUSER", sprintf("Es gibt insgesamt %d Raeume.\n", rnum));
+ }
+ else
+ write_file(PATH+"HAEUSER", "KEINE HAEUSER!\n");
+}
+
+// Gegenrichtungen
+#define X_EXIT (["oben":"unten", "unten":"oben",\
+ "westen":"osten", "osten":"westen",\
+ "sueden":"norden", "norden":"sueden",\
+ "nordosten":"suedwesten", "suedwesten":"nordosten",\
+ "nordwesten":"suedosten", "suedosten":"nordwesten" ])
+
+// fuer jeden Raum im Haus [max .. 0] betrachte alle Ausgaenge;
+// zaehle alle Ausgaenge ausser der Haustuer in Raeume,
+// die nicht zu diesem Seherhaus gehoeren
+// (dies sollten Uebergaenge zu anderen Seherhaeusern sein)
+// falls rem != 0 loesche die Gegenrichtung zu diesen Ausgaengen,
+// d.h. kappe alle Uebergaenge aus anderen Seherhaeusern in dieses
+private int
+check_exits(string owner, int max, int rem)
+{
+ int x, nr, bar;
+ string hname, foo;
+ object here, there;
+
+ x = 0;
+ for (nr = max; nr >= 0; --nr) {
+ // betrachte jeden Seherhausraum mit index max .. 0
+ hname = RAUMNAME(owner, nr);
+
+ if (catch(here = load_object(hname);publish)) {
+ printf("error loading %O!\n", hname);
+ continue;
+ }
+ foreach (string dir, string path : (mapping)(here->QueryProp(P_EXITS))) {
+ // betrachte alle Ausgaenge
+ if (dir == "raus") {
+ // Haustuer aus dem Hauptraum darf natuerlich rausfuehren
+ continue;
+ }
+ if ((sscanf(path, PATH+"%sraum%d", foo, bar) != 2) || (foo != owner)) {
+ // Raum in den der Ausgang fuehrt ist nicht in diesem Seherhaus
+ ++x;
+ if (rem) {
+ catch(there = load_object(path);publish);
+ if (there) {
+ // loesche die Gegenrichtung zu dem Ausgang
+ there->RemoveExit(X_EXIT[dir]);
+ there->Save();
+ }
+ }
+ }
+ }
+ }
+ return x;
+}
+
+// Haus fuer owner im Raum env erstellen.
+// Wird i.d.R nur vom Instanthaus gemacht.
+void NeuesHaus(string owner, object env)
+{
+ object h;
+
+ // keine passenden Rechte
+ if (!secure())
+ return;
+
+ // neuen Eintrag im Verwalter-Mapping fuer das Haus erstellen
+ megamap += ([ owner : object_name(env); 0; ({}) ]);
+ // Haus am Bauplatz laden, falls moeglich
+ catch(h = load_object(HAUSNAME(owner));publish);
+ if (!h)
+ return;
+
+ // Haus Speichern und als Raumautoloader eintragen
+ h->Save();
+ OBJECTD->AddObject(h, object_name(env));
+ // Bauplatz auf never clean setzen und Verwalter abspeichern
+ env->SetProp(P_NEVER_CLEAN, 1);
+ save_object(SAVEFILE);
+
+ // Hauptraum des Seherhauses laden
+ h = load_object(RAUMNAME(owner,0));
+ h->SetProp(H_CHEST,1);
+ // Hauptraum speichern
+ h->Save();
+ // Truhe laden
+ h->Load();
+ // Statistik ueber alle Seherhaeuser erneuern
+ dump();
+}
+
+// loescht den letzten hinzufuegten Raum im Seherhaus von 'owner'
+void LoescheRaum(string owner)
+{
+ object raumob;
+ int nr;
+
+ // kein passendes Seherhaus verwaltet oder kein Recht das zu tun
+ if (!member(megamap, owner) || !secure())
+ return;
+
+ nr = megamap[owner, HP_ROOMS];
+ // falls das Haus ueberhaupt zusaetzliche Raeume (neben Hauptraum) hat
+ if (nr > 0 ) {
+ // falls geladen, remove Raum-Objekt
+ raumob = find_object(RAUMNAME(owner,(megamap[owner,HP_ROOMS])));
+ if (objectp(raumob))
+ raumob->remove(1);
+
+ // loesche Raum aus Verwalter-Mapping durch Anzahl um eins erniedrigen
+ --megamap[owner, HP_ROOMS];
+
+ // savefile muss per Hand geloescht werden:
+ tell_object(this_interactive(),
+ break_string(sprintf("Vergiss nicht, das Savefile zu loeschen, "
+ "also: "+HAUSSAVEPATH+"%s%d.o\n",
+ owner, nr),
+ 78));
+ // speicher Hausverwaltung ab und erneuer Statistik ueber alle Seherhaeuser
+ save_object(SAVEFILE);
+ dump();
+ }
+}
+
+// Fuegt einen Raum zum Seherhaus von 'owner' hinzu.
+void NeuerRaum(string owner)
+{
+ object raumob;
+
+ // kein passendes Seherhaus verwaltet oder kein Recht das zu tun
+ if (!member(megamap, owner) || !secure())
+ return;
+
+ // ist die Maximalanzahl von Raeumen schon erreicht?
+ if (megamap[owner, HP_ROOMS] < H_MAX_ROOMS)
+ {
+ // erhoehe Raumzaehler in Verwalter-Mapping
+ megamap[owner, HP_ROOMS]++;
+ // lade neuen Raum, falls moeglich
+ catch(raumob = load_object((RAUMNAME(owner,(megamap[owner,
+ HP_ROOMS]))));publish);
+ if(objectp(raumob))
+ // speicher neuen Raum
+ raumob->Save();
+
+ // speicher Verwalter-Mapping und erneuer Statistik ueber alle Seherhaeuser
+ save_object(SAVEFILE);
+ dump();
+ }
+}
+
+// Lade Seherhaus von Besitzer 'owner'
+object _LadeHaus(string owner)
+{
+ object haus;
+ string o;
+
+ // es wird kein passendes Seherhaus verwaltet
+ if (!member(megamap, owner))
+ return 0;
+
+ // Haus ist bereits geladen
+ if (haus=find_object(HAUSNAME(owner)))
+ return haus;
+
+ // lade Bauplatz
+ o = megamap[owner];
+ if (catch(load_object(o);publish))
+ {
+ write_file(PATH+"hauserror", o+" konnte nicht geladen werden.\n");
+ return 0;
+ }
+ // Haus ist durch Laden des Bauplatzes nun geladen
+ if (haus = find_object(HAUSNAME(owner)))
+ return haus;
+
+ // clone Standard-Haus, setze Besitzer
+ haus = clone_object(HAUS);
+ haus->move(o, M_NOCHECK);
+ haus->SetOwner(owner, find_object(RAUMNAME(owner,0)));
+ // lade individualisiertes Haus aus dem Savefile
+ haus->Load();
+
+ return haus;
+}
+
+// Lade im Seherhaus von 'owner' den Raum mit der Nummer 'num'
+object _LadeRaum(string owner, int num)
+{
+ object raum;
+
+ // es wird kein passendes Seherhaus verwaltet
+ if (!member(megamap, owner))
+ return 0;
+
+ // Raumnummer nicht zwischen 0 und letzter Raumnummer
+ if (num < 0 || num > megamap[owner,HP_ROOMS])
+ return 0;
+
+ // Raum ist bereits geladen
+ if (raum = find_object(RAUMNAME(owner,num)))
+ return raum;
+
+ // clone passenden Raum (0: Hauptraum, X: Nebenraum X) und setze Besitzer
+ raum = clone_object(num ? (RAUM) : (PATH+"raum0"));
+ raum->SetOwner(owner, num);
+ // lade Moebel, z.B. Seherhaustruhe
+ raum->Load();
+ // Hauptraum bekommt Haustuer-Ausgang zum Bauplatz
+ if (!num)
+ raum->AddExitNoCheck("raus", megamap[owner]);
+
+ return raum;
+}
+
+// returnt das Seherhaus-Objekt von Besitzer 'ow'
+// nur zum Loeschen oder Wegbewegen daher einfacher als _LadeHaus
+object FindeHaus(string ow)
+{
+ // es wird kein passendes Seherhaus verwaltet
+ if (!member(megamap, ow))
+ return 0;
+ return load_object(HAUSNAME(ow));
+}
+
+// Haus von owner loeschen (samt Savefile!). Dieser Vorgang ist unwiderruflich!
+int LoescheHaus(string owner)
+{
+ object haus;
+ int rooms;
+ string tmp;
+
+ // keine passenden Rechte fuers Loeschen
+ if (!secure())
+ return -1;
+
+ // Haus-Objekt finden, als Raumautoloader im Bauplatz austragen und entfernen
+ haus = FindeHaus(owner);
+ if (!haus)
+ return -2;
+ OBJECTD->RemoveObject(haus, object_name(environment(haus)));
+ environment(haus)->RemoveItem(object_name(haus));
+
+ // Raumanzahl merken
+ rooms = megamap[owner,HP_ROOMS];
+
+ // Haus aus Verwalter-Mapping loeschen
+ megamap = m_delete(megamap, owner);
+
+ // Verwalter-Mapping abspeichern
+ save_object(SAVEFILE);
+
+ // Uebergaenge von anderen Seherhaeusern zu diesem entfernen
+ check_exits(owner, rooms, 1);
+
+ // Savefile fuer das Haus entfernen
+ if (file_size(HAUSSAVEPATH+owner+".o")>0)
+ rm(HAUSSAVEPATH+owner+".o");
+
+ // Savefiles fuer die Raeume entfernen
+ do {
+ if (file_size(tmp = sprintf((HAUSSAVEPATH+"%s%d.o"),owner,rooms))>0)
+ rm(tmp);
+ } while (--rooms >= 0);
+
+ // Savefile fuer die Truhe loeschen
+ if (file_size(HAUSSAVEPATH+owner+"truhe.o")>0)
+ rm(HAUSSAVEPATH+owner+"truhe.o");
+
+ // Repfile fuer das Seherhaus loeschen
+ // TODO: Eintraege aus ERRORD loeschen.
+ if (file_size(PATH+"rep/"+owner+".rep") > 0)
+ rm(PATH+"rep/"+owner+".rep");
+
+ // Statistik ueber alle Seherhaeuser erneuern
+ dump();
+ return 1;
+}
+
+// Haus von owner vom Raum 'von' in den Raum 'nach' verschieben.
+int VerlegeHaus(string owner, string von, string nach)
+{
+ object h, ziel;
+
+ // kein Recht das zu tun
+ if (!secure())
+ return -111;
+
+ // zu verlegendes Haus nicht auffindbar
+ if (!(h=FindeHaus(owner)))
+ return -1;
+
+ // aktueller Standort des Hauses ist nicht Startpunkt von
+ if (object_name(environment(h)) != von)
+ return -2;
+
+ // Ziel-Standort nicht ladbar
+ catch(ziel = load_object(nach);publish);
+ if (!ziel)
+ return -3;
+
+ // Am Zielort darf kein Haus gebaut werden
+ if (Unbebaubar(ziel))
+ return -4;
+
+ // Seherhaus ist mit anderem Seherhaus verbunden und kann daher nicht
+ // verschoben werden
+ if (check_exits(owner, megamap[owner,HP_ROOMS], 0))
+ return -5;
+
+ // neuen Standort in Verwalter-Mapping eintragen
+ megamap[owner] = nach;
+ // Raumautoloader am alten Standort austragen und am neuen eintragen
+ OBJECTD->RemoveObject(h, von);
+ OBJECTD->AddObject(h, nach);
+ // Haus bewegen
+ h->move(nach, M_NOCHECK);
+ // Haustuer-Ausgang umtragen und Hauptraum speichern
+ catch(RAUMNAME(owner,0)->AddExitNoCheck("raus", nach);publish);
+ catch(RAUMNAME(owner,0)->Save();publish);
+ // Verwalter-Mapping speichern
+ save_object(SAVEFILE);
+ // Haus als Inmventar des alten Bauplatzes austragen
+ von->RemoveItem(object_name(h));
+ // Statistik ueber alle Seherhaeuser erneuern
+ dump();
+
+ return 1;
+}
+
+// Kann in ob ein Haus gebaut werden? 0: Ja, sonst Fehler!
+int Unbebaubar(object ob)
+{
+ // Raum ist geclont oder hat kein eigenes Filet, z.B. VC
+ if (clonep(ob) || file_size(object_name(ob)+".c")<0)
+ return 1;
+
+ // Innenraum
+ if (ob->QueryProp(P_INDOORS))
+ return 2;
+
+ // Bauplatz-Property nicht gesetzt
+ if (!(ob->QueryProp(P_HAUS_ERLAUBT)))
+ return 3;
+
+ return 0;
+}
+
+// Jemandem im Haus Zusatzrechte einraeumen
+string *Erlaube(string owner, string *wer)
+{
+ string *all;
+
+ // es wird kein passendes Seherhaus verwaltet
+ if (!member(megamap, owner))
+ return 0;
+
+ all = megamap[owner, HP_ALLOWED];
+ // fuege wer zu all dazu ohne doppelte Eintraege zu erzeugen:
+ all += wer-all;
+ // aender Rechteliste in der Verwaltung
+ megamap[owner, HP_ALLOWED] = all;
+ // speicher Verwalter-Mapping
+ save_object(SAVEFILE);
+ // return Liste der aktuellen Rechteinhaber
+ return all;
+}
+
+// Jemandem im Haus Zusatzrechte entziehen
+string *Verbiete(string owner, string *wer)
+{
+ // es wird kein passendes Seherhaus verwaltet
+ if (!member(megamap, owner))
+ return 0;
+
+ // aender Rechteliste in der Verwaltung
+ megamap[owner, HP_ALLOWED] -= wer;
+ // speicher Verwalter-Mapping
+ save_object(SAVEFILE);
+ // return Liste der aktuellen Rechteinhaber
+ return megamap[owner, HP_ALLOWED];
+}
+
+// Abfrage von Property 'prop' im Haus von 'owner'
+// prop gleich HP_ENV, HP_ROOMS oder HP_ALLOWED aus haus.h
+mixed HausProp(string owner, int prop)
+{
+ // es wird kein passendes Seherhaus verwaltet
+ if (!member(megamap, owner))
+ return 0;
+
+ return megamap[owner,prop];
+}
+
+// zerlegt das mapping, fasst indices mit gleichen values zusammen
+// und packt das ganze in ein array -> Deduplizieren
+// Das Ergebnis enthaelt
+// a) fuer jedes Detail ein Array, welches als erstes Element ein Array von
+// Schluesseln und als zweites Element einen String enthaelt.
+// b) fuer jedes Kommando ein Array, welches als erstes Element ein Array von
+// Syntaxen und zwei folgende Elemente mit Strings (Meldungen) enthaelt.
+// Beides ist in einem Format, dass die Elemente unmodifiziert an die
+// entsprechenden Add...()-Aufrufe gegeben werden koennen.
+
+// ([ "key1" : A, "key2" : B, "key3" : A ])
+// => ({ ({ ({ "key1", "key3" }), A )}, ({ ({ "key2" }), B )} })
+
+// ([ "key1" : ([ "key11" : A; B, "key12" : C; B, "key13" : A, B ]),
+// "key2" : ([ "key21" : A; B, "key22" : C; A ]) ])
+// => ({ ({ ({ "key1 key11", "key1 key13", "key2 key21" }), A, B }),
+// ({ ({ "key1 key12" }), C, B }),
+// ({ ({ "key2 key22" }), C, A }) })
+mixed PCrunch(mapping prop)
+{
+ mixed ret = ({});
+ int done = 0;
+ foreach(string key, mixed entry : prop)
+ {
+ if(mappingp(entry))
+ {
+ // mapping breite 2 im mapping fuer H_COMMANDS
+ foreach(string subkey, string val1, string val2 : entry)
+ {
+ done = 0;
+ foreach(mixed retset : ret)
+ {
+ // falls es schon im ergebnis-array etwas mit den selben werten gibt,
+ // fuege den index dort dazu
+ if(sizeof(retset) == 3 && retset[1] == val1 && retset[2] == val2)
+ {
+ retset[0] += ({ key+" "+subkey });
+ done = 1;
+ break;
+ }
+ }
+ // falls es noch nix im ergebnis-array mit den selben werten gab,
+ // fuege einen neuen eintrag hinzu
+ if(!done)
+ ret += ({ ({ ({ key+" "+subkey }), val1, val2 }) });
+ }
+ }
+ else
+ {
+ // einzelne Werte im Mapping fuer P_DETAILS und P_READ_DETAILS
+ done = 0;
+ foreach(mixed retset : ret)
+ {
+ // falls es schon im ergebnis-array etwas mit dem selben wert gibt,
+ // fuege den index dort dazu
+ if(sizeof(retset) == 2 && retset[1] == entry)
+ {
+ retset[0] += ({ key });
+ done = 1;
+ break;
+ }
+ }
+ // falls es noch nix im ergebnis-array mit dem selben wert gab,
+ // fuege einen neuen eintrag hinzu
+ if(!done)
+ ret += ({ ({ ({ key }), entry }) });
+ }
+ }
+ return ret;
+}
diff --git a/d/seher/haeuser/kommentar.c b/d/seher/haeuser/kommentar.c
new file mode 100644
index 0000000..fe79fa4
--- /dev/null
+++ b/d/seher/haeuser/kommentar.c
@@ -0,0 +1,62 @@
+/*
+ * kommentar.c -- DIE Ergaenzung zum Bausparvertrag
+ *
+ * (c) 1994 Beldin@MorgenGrauen
+ *
+ * $Date: 1994/10/13 14:14:06 $
+ * $Revision: 1.2 $
+ * $Log: kommentar.c,v $
+ * Revision 1.2 1994/10/13 14:14:06 Wargon
+ * Ins Seherverzeichnis verlegt, angepasst und "reindented".
+ *
+ * Revision 1.1 1994/10/13 14:10:02 Wargon
+ * Initial revision
+ *
+ */
+
+inherit "std/thing";
+
+#include <properties.h>
+#include <language.h>
+#include "haus.h"
+
+create()
+{
+ ::create();
+ SetProp(P_GENDER,MALE);
+ SetProp(P_SHORT,"Ein Kommentar");
+ SetProp(P_WEIGHT, 500);
+ SetProp(P_VALUE, 0);
+ SetProp(P_NAME,"Kommentar");
+ SetProp(P_LONG,
+ "\nDies ist ein Kommentar. Er besteht aus 100%-recyclefaehigem Altpapier, und\n"
+ +"ist chlorfrei gebleicht. Das Papier scheint duenn zu sein.\n"
+ +"Vielleicht solltest Du ihn schnell lesen!\n\n"
+ );
+
+ AddId( ({"kommentar", "kommentierung"}));
+ AddCmd("lies","lesen");
+}
+
+rem()
+{
+ call_out("remove", 2);
+ tell_object(environment(), "\n\nDer Kommentar loest sich in Wohlgefallen auf.\n\n");
+ return 1;
+}
+
+lesen(str)
+{
+ string komment;
+ komment=PATH+"txt/kommentar.txt";
+ if (!str) return 0;
+ if (id(str)) {
+ this_player()->More(komment,1,#'rem);
+ return 1;
+ }
+ else {
+ notify_fail("Was willst Du lesen???\n");
+ return 0;
+ }
+}
+
diff --git a/d/seher/haeuser/modules/haustuer.c b/d/seher/haeuser/modules/haustuer.c
new file mode 100644
index 0000000..b9d8784
--- /dev/null
+++ b/d/seher/haeuser/modules/haustuer.c
@@ -0,0 +1,215 @@
+// haustuer.c -- Beschreibung, Oeffnen und Schliessen
+//
+// (c) 1995 Wargon@MorgenGrauen
+//
+// $Id: haustuer.c,v 1.1.1.1 2000/08/20 20:22:42 mud Exp $
+//
+
+#define NEED_PROTOTYPES
+#include "../haus.h"
+#include <properties.h>
+#include <thing/properties.h>
+#include <thing/description.h>
+#include <thing/commands.h>
+
+static int validHouse = 0;
+static string owner;
+
+void create()
+{
+ Set( H_DOOR, "Die Haustuer ist %s.\n" );
+ Set( H_DOORSTAT, 0);
+ Set( H_DOORLSTAT, ({ "geoeffnet", "geschlossen", 0, "abgeschlossen" }));
+
+ Set( H_DOOR, SAVE, F_MODE);
+ Set( H_DOORSTAT, SAVE, F_MODE);
+ Set( H_DOORLSTAT, SAVE, F_MODE);
+
+ AddCmd( ({"schliess", "schliesse"}), "schliesse");
+ AddCmd("oeffne","oeffne");
+
+ owner = getuid(this_object());
+}
+
+varargs string long(int mode)
+{
+ return sprintf(Query(H_DOOR), Query(H_DOORLSTAT)[Query(H_DOORSTAT)]);
+}
+
+static string SetTuerOwner(string o)
+{
+ validHouse=1;
+ Set( H_DOORSTAT, D_CLOSED | D_LOCKED);
+ return owner=o;
+}
+
+int oeffne(string str)
+{
+ int doorstat;
+
+ notify_fail("Was willst Du oeffnen?\n");
+ doorstat = Query(H_DOORSTAT);
+
+ if (!id(str) && str != "tuer" && str != "haustuer")
+ return 0;
+
+ if (!(doorstat & D_CLOSED)) {
+ notify_fail(capitalize(name(WER,1))+" ist gar nicht geschlossen!\n");
+ return 0;
+ }
+ if (doorstat & D_LOCKED) {
+ notify_fail(capitalize(name(WER,1))+" ist abgeschlossen.\n");
+ return 0;
+ }
+
+ doorstat &= ~D_CLOSED;
+ Set(H_DOORSTAT, doorstat & ~D_CLOSED);
+
+ write("Du oeffnest "+name(WEN,1)+" von "+capitalize(owner)+".\n");
+ tell_room(environment(this_object()),
+ sprintf("%s oeffnet %s von %s.\n",
+ this_player()->name(WER),
+ name(WEN,1),
+ capitalize(owner) ),
+ ({this_player()}));
+ if (validHouse) {
+ tell_room(find_object(RAUMNAME(owner,0))||this_object(),
+ this_player()->name(WER)+" oeffnet "+name(WEN)+".\n",
+ ({this_player()}));
+ Save();
+ }
+ return 1;
+}
+
+private int close_door()
+{
+ if (Query(H_DOORSTAT) & D_CLOSED) {
+ notify_fail(capitalize(name(WER,1))+" ist doch schon zu!\n");
+ return 0;
+ }
+ Set(H_DOORSTAT, Query(H_DOORSTAT) | D_CLOSED);
+
+ write("Du schliesst "+name(WEN,1)+" von "+capitalize(owner)+".\n");
+ tell_room(environment(this_object()),
+ sprintf( "%s schliesst %s von %s.\n",
+ capitalize(this_player()->name(WER)),
+ name(WEN,1), capitalize(owner)),
+ ({this_player()}));
+ if (validHouse) {
+ tell_room(find_object(RAUMNAME(owner,0))||this_object(),
+ capitalize(this_player()->name(WER))+" schliesst "+name(WEN)+".\n",
+ ({this_player()}));
+ Save();
+ }
+ return 1;
+}
+
+private int lock_door()
+{
+ object tp, home;
+ string nam;
+ int doorstat;
+
+ tp = this_player();
+ nam = capitalize(tp->name(WER));
+
+ if (validHouse) {
+ call_other(RAUMNAME(owner,0), "???");
+ home = find_object(RAUMNAME(owner,0));
+
+ if (!home->allowed_check(this_player())) {
+ notify_fail("Du darfst "+name(WEN,1)+" von "+capitalize(owner)+" aber nicht abschliessen.\n");
+ return 0;
+ }
+ }
+ if ((doorstat = Query(H_DOORSTAT)) & D_LOCKED) {
+ notify_fail("Die Tuer ist abgeschlossen.\n");
+ return 0;
+ }
+ doorstat |= (D_LOCKED|D_CLOSED);
+ write("Du schliesst "+name(WEN)+" ab.\n");
+ Set(H_DOORSTAT, doorstat);
+ tell_room(environment(this_object()),
+ sprintf( "%s schliesst %s ab.\n",
+ nam,
+ (getuid(tp)==owner ?
+ (tp->QueryPossPronoun(this_object(), WEN)+" "+name(RAW)) :
+ name(WEN,1) )),
+ ({tp}));
+ if (validHouse) {
+ tell_room(home, nam+" schliesst "+name(WEN)+" ab.\n",({tp}));
+ Save();
+ }
+ return 1;
+}
+
+private int unlock_door()
+{
+ object tp, home;
+ string nam;
+ int doorstat;
+
+ tp = this_player();
+ nam = capitalize(tp->name(WER));
+
+ if (validHouse) {
+ call_other(RAUMNAME(owner,0), "???");
+ home = find_object(RAUMNAME(owner,0));
+
+ if (!home->allowed_check(this_player())) {
+ notify_fail("Du darfst "+name(WEN,1)+" von "+capitalize(owner)+" aber nicht aufschliessen.\n");
+ return 0;
+ }
+ }
+
+ if (!((doorstat = Query(H_DOORSTAT)) & D_LOCKED)) {
+ notify_fail("Die Tuer ist nicht abgeschlossen.\n");
+ return 0;
+ }
+
+ Set(H_DOORSTAT, doorstat & ~D_LOCKED);
+ write("Du schliesst "+name(WEN)+" auf.\n");
+ tell_room(environment(this_object()),
+ sprintf("%s schliesst %s auf.\n",
+ nam,
+ (getuid(tp)==owner ?
+ (tp->QueryPossPronoun(this_object(), WEN)+" "+name(RAW)) :
+ name(WEN,1) )),
+ ({tp}));
+ if(validHouse) {
+ tell_room(home,nam+" schliesst "+name(WEN)+" auf.\n",({tp}));
+ Save();
+ }
+ return 1;
+}
+
+int schliesse(string str)
+{
+ string was, wen, *s;
+
+ notify_fail("Was willst Du schliessen ?\n");
+ if (!str||str=="")
+ return 0;
+ s = old_explode(str, " ");
+ if ((was = s[<1]) == "auf" || was == "ab")
+ s = s[0..<2];
+ else
+ was = 0;
+
+ wen=implode(s, " ");
+ if (!id(wen) && wen != "tuer" && wen != "haustuer")
+ return 0;
+ if (!was || was=="")
+ return close_door();
+ switch (was)
+ {
+ case "auf": return unlock_door();
+ case "ab": return lock_door();
+ }
+ return 0;
+}
+
+// $Log: haustuer.c,v $
+// Revision 1.1.1.1 2000/08/20 20:22:42 mud
+// Ins CVS eingecheckt
+//
diff --git a/d/seher/haeuser/modules/losa.c b/d/seher/haeuser/modules/losa.c
new file mode 100644
index 0000000..893ca51
--- /dev/null
+++ b/d/seher/haeuser/modules/losa.c
@@ -0,0 +1,378 @@
+// losa.c -- Modul fuer Laden und Speichern der Hausdaten
+//
+// (c) 1995 Wargon@MorgenGrauen
+// 2006 Vanion@MorgenGrauen, fuer die rebootfesten Moebel
+// $Id: losa.c,v 1.1.1.1 2000/08/20 20:22:42 mud Exp $
+//
+#pragma strong_types,rtt_checks
+
+#define NEED_PROTOTYPES
+#include "../haus.h"
+#include <container.h>
+#include <thing/properties.h>
+#include <room/exits.h>
+#include <thing/description.h>
+#undef NEED_PROTOTYPES
+#include <properties.h>
+#include <wizlevels.h>
+#include <moving.h>
+
+static void start_reload_furniture();
+
+private int csaved;
+
+// Variablen zur Verwaltung der Moebel im Raum.
+mapping furniture;
+mapping broken_furniture;
+
+protected void
+create()
+{
+ Set(H_CHEST, SAVE, F_MODE);
+ Set(H_CHEST, 0);
+
+ Set(H_FURNITURE, SAVE, F_MODE);
+ Set(H_FURNITURE, 0);
+
+// Set(H_SPECIAL, SAVE|SECURED, F_MODE);
+// Set(H_SPECIAL, ([:2]), F_VALUE);
+}
+
+/* Scheint nirgendwo benutzt zu werden...
+varargs int AddSpecial(int typ, string key, string extra)
+{
+ if (!this_interactive() || !IS_ARCH(this_interactive()) ||
+ !(PATH+"access_rights")->access_rights(geteuid(this_interactive()),""))
+ return -1;
+
+ if (typ != HS_EXIT && typ != HS_ITEM)
+ return 0;
+
+ Set(H_SPECIAL, Query(H_SPECIAL) + ([ key : typ; extra ]));
+ Save();
+ return 1;
+}
+
+void RemoveSpecial(string key)
+{
+ if (!this_interactive() || !IS_ARCH(this_interactive()) ||
+ !(PATH+"access_rights")->access_rights(geteuid(this_interactive()),""))
+ return;
+
+ Set(H_SPECIAL, m_delete(Query(H_SPECIAL), key));
+ Save();
+}
+*/
+
+void
+reset()
+{
+ if (QueryOwner() &&
+ !sizeof(filter(all_inventory(),#'interactive)) &&
+ !csaved)
+ Save(1);
+}
+
+// crunched komprimiert das Savefile
+varargs void
+Save(int crunched)
+{
+ mixed o1, o2, o3;
+ closure pc;
+ object *obs;
+ int i, found;
+
+ o3 = 0;
+
+ if (!(o1 = Query(P_DETAILS)))
+ Set(P_DETAILS, QueryProp(P_DETAILS), F_VALUE);
+
+ if (!(o2 = Query(P_READ_DETAILS)))
+ Set(P_READ_DETAILS, QueryProp(P_READ_DETAILS), F_VALUE);
+
+ if (csaved = crunched)
+ {
+ pc = symbol_function("PCrunch", VERWALTER);
+ Set(P_DETAILS, funcall(pc, Query(P_DETAILS)), F_VALUE);
+ Set(P_READ_DETAILS, funcall(pc, Query(P_READ_DETAILS)), F_VALUE);
+ o3 = Query(H_COMMANDS, F_VALUE);
+ Set(H_COMMANDS, funcall(pc, o3), F_VALUE);
+ }
+
+ // Autoload-Einrichtung identifizieren und speichern
+ // Code in Anlehnung an dem Autoload-Mechanismus fuer Spieler
+ furniture=([]);
+
+ // Alle Autoloader filtern
+ obs=filter_objects(all_inventory(this_object()), "QueryProp", H_FURNITURE);
+ found = 0;
+
+ // Ueber alle Moebel iteritieren
+ for( i=sizeof(obs)-1;i>=0;i--)
+ {
+ if( clonep(obs[i]))
+ {
+ if ( ++found <= MAX_FURNITURE_PER_ROOM )
+ furniture += ([ object_name(obs[i]):obs[i]->QueryProp(H_FURNITURE) ]);
+ }
+ }
+ if (found > MAX_FURNITURE_PER_ROOM)
+ {
+ tell_object(this_player(),
+ break_string("Du hast "+found+" Moebelstuecke im Raum stehen. "
+ "Gespeichert werden nur "+MAX_FURNITURE_PER_ROOM+". "
+ "Du solltest Dich von einigen Einrichtungsgegenstaenden "
+ "trennen.",78));
+
+ }
+ HDEBUG("Saving "+ sizeof (furniture) +" (plus "+sizeof(broken_furniture)+
+ " broken) objects in room "+
+ object_name(this_object()) + ".");
+
+ save_object( HAUSSAVEPATH+QueryOwner(1));
+
+ Set(P_DETAILS, o1, F_VALUE);
+ Set(P_READ_DETAILS, o2, F_VALUE);
+ if (o3)
+ Set(H_COMMANDS, o3, F_VALUE);
+}
+
+void
+Load()
+{
+ mixed prop;
+ int i;
+
+ restore_object( HAUSSAVEPATH+QueryOwner(1));
+
+ // Details und Kommandos werden beim Speichern de-dupliziert und in einem
+ // speziellen Format abgespeichert (s. PCrunch() im Hausverwalter). Sie
+ // muessen nach dem Laden durch die entsprechenden Add...()-Aufrufe
+ // wieder eingetragen werden.
+ prop=Query(P_DETAILS, F_VALUE);
+ RemoveDetail(0);
+ if (pointerp(prop))
+ {
+ foreach(<string*|string>* item : prop)
+ AddDetail(item[0], item[1]);
+ }
+ else if (mappingp(prop))
+ {
+ foreach(string key, mixed val : prop)
+ AddDetail(key, val);
+ }
+ else
+ SetProp(P_DETAILS, prop);
+
+ prop = Query(P_READ_DETAILS, F_VALUE);
+ RemoveReadDetail(0);
+ if (pointerp(prop))
+ {
+ foreach(<string*|string>* item : prop)
+ AddDetail(item[0], item[1]);
+ }
+ else if (mappingp(prop))
+ {
+ foreach(string key, mixed val : prop)
+ AddReadDetail(key, val);
+ }
+ else
+ SetProp(P_READ_DETAILS, prop);
+
+ prop = Query(P_EXITS, F_VALUE);
+ RemoveExitNoCheck(0);
+ if (mappingp(prop))
+ {
+ if (widthof(prop) <= 1)
+ {
+ foreach(string key, string dest : prop)
+ AddExitNoCheck(key, dest);
+ }
+ else
+ {
+ foreach(string key, string dest, string msg : prop)
+ {
+ if (stringp(msg))
+ _AddExit(key, dest, msg);
+ else if (stringp(dest) && strstr(dest,"#") != -1)
+ AddExitNoCheck(key, dest);
+ else
+ _AddExit(key, dest, 0);
+ }
+ }
+ }
+
+ prop=Query(H_COMMANDS, F_VALUE);
+ if (pointerp(prop))
+ {
+ Set(H_COMMANDS, ([]), F_VALUE);
+ for (i=sizeof(prop)-1; i>=0; i--)
+ this_object()->AddUserCmd(prop[i][0], 0, prop[i][1], prop[i][2]);
+ }
+
+ if (environment())
+ environment()->SetProp(P_NEVER_CLEAN, 1);
+
+ if (previous_object() && object_name(previous_object())==VERWALTER)
+ {
+ if (Query(H_CHEST))
+ this_object()->AddItem(PATH+"truhe",REFRESH_NONE,
+ ([ "owner" : QueryOwner() ]));
+/* Das scheint nirgendwo benutzt zu werden und in allen Seherhaeusern leer zu
+ * sein.
+ mapping special = Query(H_SPECIAL, F_VALUE);
+ if (special)
+ {
+ foreach(string key, int type, string extra : special)
+ {
+ switch(type)
+ {
+ case HS_ITEM:
+ AddItem(SPECIALPATH + extra, REFRESH_DESTRUCT);
+ break;
+ case HS_EXIT:
+ AddExitNoCheck(key, extra);
+ break;
+ }
+ }
+ }
+*/
+ }
+
+ // Das Laden der Autoloader wird erst am Ende angestossen.
+ // Dann ist es nicht schlimm, wenn alle Eval Ticks verbraucht werden.
+ start_reload_furniture();
+}
+
+// Mehrere Save-Anforderungen zusammenfassen.
+static void queued_save()
+{
+ HDEBUG("QS");
+ while (remove_call_out("Save")!=-1);
+ call_out("Save",3);
+}
+
+static int reload_error(string file, mixed data, string message)
+{
+ HDEBUG(message);
+ broken_furniture+=([file:data]);
+ log_file("seher/haeuser/autoloader_error",
+ dtime(time())+"\n"+
+ break_string(object_name(this_object())+" ("+QueryOwner(1)+")",78, " FILE: ",1)+
+ break_string(message, 78, " MSG: ",1)+
+ break_string(sprintf("%O", data),78, " DATA: ",1)+"\n");
+
+ return 0; // 0 fuer das filter, damit dieser Eintrag
+ // aus furniture geloescht wird.
+}
+
+// Laedt ein einzelnes Moebelstuecks
+static int load_furniture_object( string file, mixed data )
+{
+ object ob;
+ string error;
+ string blueprint;
+ closure pc;
+ // mixed data;
+
+ // Wenn genug Ticks frei sind, wird versucht, das Objekt zu erzeugen.
+ // Ansonsten ist die Gefahr zu gross, dass ein Erzeugungs-Prozess abbricht.
+ if (get_eval_cost() < 500000)
+ {
+ // HDEBUG("Suspending Object: "+file+". Only "+to_string(get_eval_cost())+" ticks left.");
+ return 1; // 1 bedeutet, dass dieser Eintrag es im Mapping bleibt.
+ }
+
+ // HDEBUG("Processing Object: "+file+" with Data: "+sprintf("%O",data)+".");
+
+ // Nummern der Clones sind beim Speichern noetig, um die Identitaeten
+ // der Objekte zu bestimmen (mehrere Objekte vom gleichen Blueprint
+ // speichern). Hier braucht man sie nicht mehr
+
+ blueprint = explode(file,"#")[0];
+
+ // Data aus dem Mapping holen
+ // data=furniture[file];
+
+ // Muss ich die Blueprint suchen?
+ ob = find_object(file);
+
+ // Nein.
+ if (!ob)
+ {
+ // Existiert die BP oder ein VC fuers File?
+ if (file_size(blueprint+".c")<0&&
+ file_size(implode(explode(blueprint,"/")[0..<2],"/")+
+ "/virtual_compiler.c")<0)
+ {
+ return reload_error(file, data, "Error in file: "+ file +
+ ". File does not exist.");
+
+ }
+
+ // File gefunden. Versuch, es zu laden.
+ if (error = catch(call_other( blueprint,"???")))
+ {
+ return reload_error(file, data, "Error loading file: "+file+". "+error);
+ }
+ }
+
+ // Clone erzeugen
+ if ( error = catch(ob = clone_object(blueprint)) )
+ {
+ return reload_error(file, data, "Error cloning object: "+file+". "+error);
+ }
+
+ HDEBUG(sprintf("%O",furniture));
+ // Autoload-Daten setzen
+ HDEBUG(object_name(ob)+"->SetProp("+sprintf("%O", data)+")");
+ if (ob)
+ catch(ob->SetProp( H_FURNITURE, data ));
+
+ // Furniture in das Seherhaus moven
+ if ( error = catch(ob->move( this_object(), M_NOCHECK )) ) {
+ ob->remove();
+ if(ob) destruct(ob);
+ return reload_error(file, data, "Error moving object: "+file+". "+error);
+ }
+
+ // post_create anstossen
+ pc=symbol_function("post_create", ob);
+ if (closurep(pc))
+ call_out(pc, 1);
+
+ return 0; // 0 bedeutet hier, dieses Objekt nicht noch einmal anstossen.
+}
+
+static void load_furniture()
+{
+ int i;
+ string rv;
+ string current_key;
+
+ // Abbruchbedingung ist, dass nichts mehr zu laden ist.
+ if (sizeof(furniture)==0) return;
+
+ // Anstoßen des naechsten Durchlaufs, falls die Ticks nicht reichen.
+ while (remove_call_out(#'load_furniture) != -1);
+ call_out(#'load_furniture, 1);
+
+ // Laden aller Moebel anstoßen
+ furniture=filter(furniture, #'load_furniture_object);
+}
+
+// Diese Funktion bereitet das Reloaden der Einrichtung vor
+static void start_reload_furniture()
+{
+ // Wenn es keine Moebel gibt, ist das Laden beendet.
+ if (!mappingp(furniture)) return;
+ if (broken_furniture==0) broken_furniture=([]);
+
+ // Falls ein Key von furniture 0 ist, wird dieser geloescht.
+ m_delete(furniture,0);
+
+ // Laden des Furniture anstossen
+ load_furniture();
+}
+
+
diff --git a/d/seher/haeuser/modules/usercmd.c b/d/seher/haeuser/modules/usercmd.c
new file mode 100644
index 0000000..a83b819
--- /dev/null
+++ b/d/seher/haeuser/modules/usercmd.c
@@ -0,0 +1,341 @@
+// usercmd.c -- Modul fuer benutzerdefinierte Befehle
+//
+// (c) 1995 Wargon@MorgenGrauen
+//
+// $Id: usercmd.c,v 1.4 2003/11/15 13:48:46 mud Exp $
+//
+
+#define NEED_PROTOTYPES
+#include "../haus.h"
+#include <properties.h>
+#include <wizlevels.h>
+#include <thing/properties.h>
+
+private string ucFilter(string str);
+private string ucText(string str);
+private void splitCmd(string *cmd, string *verb, string *para);
+
+create()
+{
+ Set(H_COMMANDS, SAVE, F_MODE);
+ Set(H_COMMANDS, ([]));
+
+ AddCmd("", "userCommands", 1);
+}
+
+/*
+ * AddUserCmd: eigenes Kommando hinzufuegen
+ * cmd: String oder Array von Strings. Enthaelt entweder nur die Verben oder
+ * die kompletten Befehle (Verb + Parameter). Siehe auch pa.
+ * pa: Zahl oder Array von Strings. Falls pa eine Zahl ist, so enthaelt cmd
+ * die kompletten Befehle (samt Parametern). Ansonsten enthaelt pa die
+ * Parameter fuer das entsprechende Verb in cmd.
+ * Ist pa = ({ "@NF@"}) , so handelt es sich um ein notify_fail, das an
+ * die Beschreibung des Verbs (falls vorhanden) angehaengt wird.
+ * me: Text fuer den Ausfuehrenden. Der Text muss schon geparsed worden
+ * sein!
+ * oth: Text fuer die Umstehenden oder 0. Der Text muss schon geparsed wor-
+ * den sein!
+ */
+varargs void
+AddUserCmd(mixed cmd, mixed pa, string me, string oth)
+{
+ int v,p;
+ mapping cmds, desc;
+ string *verb, *para, txt;
+
+ cmds = Query(H_COMMANDS);
+ if (stringp(cmd))
+ verb = ({ cmd });
+ else
+ verb = cmd;
+
+ if (intp(pa))
+ splitCmd(verb[0..], &verb, ¶);
+ else {
+ if (stringp(pa))
+ para = ({ pa });
+ else if (pointerp(pa))
+ para = pa;
+ for (desc = ([]), p=sizeof(para)-1; p>=0; p--)
+ desc += ([ para[p] : me; oth ]);
+ }
+
+ for (v = sizeof(verb)-1; v>= 0; v--) {
+ if (member(cmds, verb[v])) {
+ if (intp(pa))
+ cmds[verb[v]] += ([para[v] : me; oth ]);
+ else
+ cmds[verb[v]] += desc;
+ }
+ else {
+ if (intp(pa))
+ cmds += ([ verb[v] : ([para[v] : me; oth ]) ]);
+ else
+ cmds += ([ verb[v] : desc ]);
+ }
+ }
+ Set(H_COMMANDS, cmds);
+}
+
+/*
+ * RemUserCmd: Kommando(s) wieder entfernen
+ * com: String oder Array von Strings. Enthaelt das zu loeschende Kommando
+ * (Verb oder Verb + Parameter).
+ * all: Falls != 0, so werden die Verben aus com komplett mit allen Para-
+ * metern geloescht.
+ */
+varargs void
+RemUserCmd(mixed com, int all)
+{
+ mapping cmd, tmp;
+ string *verb, *para;
+ int v, p;
+
+ cmd = Query(H_COMMANDS);
+ splitCmd(stringp(com) ? ({com}) : com, &verb, ¶);
+
+ if (all)
+ for (v=sizeof(verb)-1; v>=0; v--)
+ cmd = m_copy_delete(cmd, verb[v]);
+ else {
+ for (v=sizeof(verb)-1; v>=0; v--) {
+ if (tmp = cmd[verb[v]]) {
+ for (p=sizeof(para)-1; p>=0; p--)
+ tmp = m_copy_delete(tmp, para[p]);
+ cmd[verb[v]] = tmp;
+ }
+ }
+ }
+ Set(H_COMMANDS,cmd);
+}
+
+/*
+ * userCommands: Auswertung der benutzerdefinierten Befehle.
+ */
+static int
+userCommands(string str)
+{
+ mapping ucmd, uparm;
+ string *parts, text;
+ int i;
+
+ ucmd = QueryProp(H_COMMANDS);
+ str = this_player()->_unparsed_args(1)||"";
+ if (uparm = ucmd[query_verb()]) {
+ if (member(uparm, str)) {
+ text = ucText(uparm[str,0]);
+ if (sizeof(old_explode(text, "\n")) >= this_player()->QueryProp(P_SCREENSIZE))
+ this_player()->More(capitalize(text)[0..<2]);
+ else
+ write(capitalize(text));
+
+ if (uparm[str,1])
+ say(ucText(uparm[str,1]));
+
+ if (member(m_indices(QueryProp(P_EXITS)), query_verb()) == -1)
+ return 1;
+ }
+ else {
+ if (str && str != "" && text = uparm["@NF@"])
+ notify_fail(implode(old_explode(text,"@F"),str));
+ }
+ }
+ return 0;
+}
+
+/*** Functions private to this module... ***/
+
+/*
+ * ucFilter: Ersetzen von Name, Personal- und Possessivpronomen.
+ * Gibt den ersetzten String zurueck.
+ */
+private string
+ucFilter(string str)
+{
+ int p,g;
+
+ switch(str[0..1]) {
+ case "@W": // Name in entsprechendem Fall...
+ return this_player()->name(to_int(str[2..2]));
+ case "@P": // Personalpronomen in entprechendem Fall...
+ return this_player()->QueryPronoun(to_int(str[2..2]));
+ case "@B": // Possesivpronomen in entprechendem Fall...
+ p = to_int(str[4..4]);
+ g = to_int(str[3..3]);
+ return this_player()->QueryPossPronoun(g, to_int(str[2..2]), p);
+ }
+ return str;
+}
+
+/*
+ * ucText: Rassen- und geschlechtsspezifische Teile bearbeiten sowie
+ * Namen und Pronomina einsetzen.
+ *
+ * str enthaelt den String, der beim Beschreiben des Befehls
+ * eingegeben wurde. Bis auf den Default-Text sind alle Teile
+ * optional. Der String kann folgenden Aufbau haben:
+ * ------ schnipp ------
+ * Default-Text, der ausgegeben wird, wenn die folgenden spezielleren
+ * Texte nicht auftreten oder auf den Ausfuehrenden nicht zutreffen
+ * @NAME:nameA
+ * Text, der ausgegeben wird, wenn der Spieler "nameA" das Kommando
+ * eingegeben hat
+ * @NAME:nameB
+ * Und so weiter fuer Spieler "nameB" etc...
+ * @RA
+ * Text, der ausgegeben wird, wenn der Ausfuehrende auf der Erlaube-
+ * Liste des Hauses steht.
+ * @RE
+ * Text, der ausgegeben wird, wenn der Ausfuehrende ein Elf
+ * ist. Ebenso gibt es @RD fuer Dunkelelfen, @RF fuer Felinen,
+ * @RH fuer Hobbits, @RM fuer Menschen, @RG fuer Goblins und @RZ
+ * fuer Zwerge.
+ * ------ schnapp ------
+ *
+ * Der Default-Text muss immer am Anfang stehen. Die anderen Bloecke
+ * koennen in beliebiger Reihenfolge folgen. Die Reihenfolge, in der
+ * die Bloecke betrachtet werden, ist dabei folgende:
+ * - zuerst werden @NAME-Bloecke untersucht
+ * - dann wird @RA (Erlaube-Liste) getestet
+ * - danach wird die Rasse ueberprueft (@RD/@RE/@RF/@RH/@RM/@RZ/@RG)
+ * - zuletzt wird der Default-Text betrachtet
+ *
+ * Innerhalb jedes der Bloecke kann man noch mit @G zwischen
+ * maennlichen und weiblichen Vertretern unterscheiden (bei @NAME:
+ * macht das aber wenig Sinn). Beispiel:
+ * ------ schnipp ------
+ * @RZ
+ * Der Zwerg war maennlich
+ * @G
+ * Der Zwerg war weiblich
+ * ------ schnapp ------
+ *
+ * Die Funktion gibt den fuer den Ausfuehrenden zutreffenden Text
+ * zurueck.
+ */
+private string
+ucText(string str)
+{
+ string *parts, *names, *lnames;
+ int i, n;
+
+ // Text nach Namen- und Rassentrennern aufteilen
+ parts = regexplode(str, "(@NAME:[A-Za-z1-9]*\n)|(@R[A-Z]\n)");
+ i = -1;
+
+ if (sizeof(parts) > 1) {
+
+ // Zuerst wird nach Namenstrennern gesucht
+ names = regexp(parts, "@NAME:");
+
+ if (sizeof(names) > 0) {
+ // ein kleiner Umweg, da der Name im Eingabestring nicht
+ // notwendigerweise in Kleinbuchstaben vorliegt.
+ lnames = map(names, #'lower_case);
+ n = member(lnames, "@name:"+getuid(this_player())+"\n");
+
+ if (n >= 0) {
+ i = member(parts, names[n]);
+ }
+ }
+
+ // Kein passender Namenstrenner gefunden: Erlaube-Liste
+ // ueberpruefen
+ if (i<0 && allowed_check(this_player())) {
+ i=member(parts, "@RA\n");
+ }
+
+ // Weder Namenstrenner noch Erlaube-Liste passen: Rasse
+ // ueberpruefen
+ if (i<0) {
+ switch(this_player()->QueryProp(P_RACE)) {
+ case "Zwerg":
+ i=member(parts, "@RZ\n");
+ break;
+ case "Elf":
+ i=member(parts, "@RE\n");
+ break;
+ case "Feline":
+ i=member(parts, "@RF\n");
+ break;
+ case "Hobbit":
+ i = member(parts, "@RH\n");
+ break;
+ case "Dunkelelf":
+ i = member(parts, "@RD\n");
+ break;
+ case "Goblin":
+ i = member(parts, "@RG\n");
+ break;
+ case "Ork":
+ i = member(parts, "@RO\n");
+ break;
+ default:
+ i=member(parts, "@RM\n");
+ break;
+ }
+ }
+
+ // Den richtigen Teil des Strings herauspicken
+ if (i>-1)
+ str = parts[i+1];
+ else
+ str = parts[0];
+ }
+ if (sizeof(parts = old_explode(str, "@G\n"))==2)
+ str = parts[(this_player()->QueryProp(P_GENDER) == MALE ? 0 : 1)];
+
+ parts = regexplode(str, "(@W[0-3]|@P[0-3]|@B[0-3][0-2][0-1])");
+ parts = map(parts, #'ucFilter);
+ return implode(parts, "");
+}
+
+/*
+ * splitCmd: Komplettes Kommando in Arrays von Verben und Parametern zerlegen.
+ * cmd: Array von Strings. Dieses Array enthaelt die aufzuspaltenden Befehle.
+ * verb: Referenz auf ein Array von Strings fuer die Verben.
+ * para: Referenz auf ein Array von Strings fuer die Parameter.
+ */
+private void splitCmd(string *cmd, string *verb, string *para)
+{
+ int c, sp;
+
+ for (verb = ({}), para = ({}), c = sizeof(cmd)-1; c>=0; c--) {
+ if ((sp=member(cmd[c], ' ')) >= 0) {
+ verb += ({ cmd[c][0..sp-1] });
+ para += ({ cmd[c][sp+1..] });
+ }
+ else {
+ verb += ({ cmd[c] });
+ para += ({ "" });
+ }
+ }
+}
+
+// $Log: usercmd.c,v $
+// Revision 1.4 2003/11/15 13:48:46 mud
+// @RD als Trenner fuer Dunkelelfen
+//
+// Revision 1.3 2000/12/03 17:15:40 mud
+// ucText: Neuer Trenner @NAME:foo, mit dem man in Seherhausbefehlen
+// Texte fuer bestimmte Spieler vorsehen kann.
+//
+// Revision 1.2 2000/08/20 20:38:40 mud
+// @RF als Trenner fuer Felinen
+//
+// Revision 1.1.1.1 2000/08/20 20:22:42 mud
+// Ins CVS eingecheckt
+//
+// Revision 1.4 1996/04/19 23:10:52 Wargon
+// @RA fuer Leute mit Erlaubnis
+//
+// Revision 1.3 1995/10/31 12:59:52 Wargon
+// @RH fuer Hobbits
+//
+// Revision 1.2 1995/06/22 19:48:31 Wargon
+// Bugfix in userCommands()
+//
+// Revision 1.1 1995/04/21 09:22:50 Wargon
+// Initial revision
+//
diff --git a/d/seher/haeuser/moebel/access_rights.c b/d/seher/haeuser/moebel/access_rights.c
new file mode 100644
index 0000000..255cd58
--- /dev/null
+++ b/d/seher/haeuser/moebel/access_rights.c
@@ -0,0 +1,5 @@
+int access_rights(string user, string file) {
+ if(user == "swift" && file!="autoloadertruhe.c")
+ return 1; // Swift hat auf die Moebel Zugriff.
+ return 0;
+}
diff --git a/d/seher/haeuser/moebel/autoloadertruhe.c b/d/seher/haeuser/moebel/autoloadertruhe.c
new file mode 100644
index 0000000..e22ce17
--- /dev/null
+++ b/d/seher/haeuser/moebel/autoloadertruhe.c
@@ -0,0 +1,1015 @@
+//--------------------------------------------------------------------------------
+// Name des Objects: Aufbewahrungtruhe fuer Autoload-Objekte
+//
+// Magier: Zesstra
+//--------------------------------------------------------------------------------
+#pragma strong_types,rtt_checks
+
+#include "schrankladen.h"
+inherit LADEN("swift_std_container");
+
+//#include <ansi.h>
+#include <class.h>
+#include <wizlevels.h>
+#include "/d/seher/haeuser/haus.h"
+
+#define IDS 0
+#define NAME 1
+#define ALDATA 2
+
+#define LOG(x,y) log_file(x,sprintf("%s [%s, %O, %O]: %s\n",dtime(time()),\
+ (uuid?uuid:" "),PL,object_name(ME),y))
+#define STORELOG(x) LOG("zesstra/ALTRUHE_STORE.log",x)
+#define PICKLOG(x) LOG("zesstra/ALTRUHE_PICK.log",x)
+
+#define ITEMLOG(x) log_file("zesstra/ALTRUHE_ITEMS.log",\
+ sprintf("%s [%O]: %s\n",dtime(time()),\
+ this_interactive()||PL,x))
+
+#define ERRLOG(x) LOG("zesstra/ALTRUHE.ERR",x)
+
+#undef BS
+#define BS(x) break_string(x,78)
+
+#define VERSION_OBJ "5"
+
+#ifdef MAINTAINER
+#undef MAINTAINER
+#endif
+#define MAINTAINER ({"zesstra"})
+
+// Savefile der Blueprint
+#ifdef SAVEFILE
+#undef SAVEFILE
+#endif
+#define SAVEFILE __FILE__[..<3]
+
+#define DEBUG(x) if (funcall(symbol_function('find_player),MAINTAINER[0]))\
+ tell_object(funcall(symbol_function('find_player),MAINTAINER[0]),\
+ "ALTruhe: "+x+"\n")
+
+#define ACCESS (my_secure_level() >= ARCH_LVL)
+
+// Diese 4 sind fuer die Blueprint (Master aller Truhen)
+mapping whitelist=([]); // erlaubte Autoloader, alle anderen nicht erlaubt.
+mapping blacklist=([]); // bereits explizit durch EM+ abgelehnte Autoloader
+mapping vorschlaege=m_allocate(1,2); // vorschlaege der Spieler
+mapping data=([]); // hier speichert die BP alle Daten der Truhen
+ // WICHTIG: dieses Mapping wird in /secure/memory
+ // abgelegt und muss auch beim Neuladen ggf. von dort
+ // wieder abgeholt werden. Ausserdem teilen sich alle
+ // Truhen eines Spielers und diese Blueprint die Mappings
+ // darin, damit Aenderungen sofort in allen Truhen und dem
+ // Master bekannt sind.
+
+/* die einzelnen Truhen speichern in autoloader. Format:
+ 3 Werte pro Key, Keys sind die Namen der Blueprints der Objekte:
+ ([<blueprint>: <P_IDS>; <ob->name()>; <P_AUTOLOADOBJ> ])
+ */
+nosave mapping autoloader=m_allocate(1,3);
+nosave string uuid; // UUID des Eigentuemers
+nosave object ob_in_bewegung; // uebler Hack eigentlich. :-(
+
+void NotifyInsert(object ob, object oldenv);
+static mapping QueryData();
+static mapping SetData(mixed data);
+protected void save_me();
+protected void check_content();
+
+nomask private int my_secure_level(); //Args.
+
+protected void create() {
+
+ // Ja, es is Absicht, dass das create der BP erst spaeter abgebrochen wird!
+ swift_std_container::create();
+
+ seteuid(getuid(ME));
+
+ // falls dies die BP ist:
+ // 1. das Savefile zu laden.
+ // 2. versuchen, die truhendaten von /secure/memory zu holen, damit nach dem
+ // Neuladen der Master und die Client immer nach _dieselben_ Mappings
+ // haben.
+ if (!clonep(ME))
+ {
+ // Savefile restaurieren (auch wenn data im Memory ist, muss das sein,
+ // damit die anderen Variablen wieder eingelesen sind).
+ restore_object(SAVEFILE);
+ // jetzt Daten aus Memory holen, sofern verfuegbar
+ mapping tmp = "/secure/memory"->Load("truhendaten");
+ if (mappingp(tmp))
+ {
+ // Daten aus Savefile durch die vom Memory ersetzen
+ data = tmp;
+ }
+ else
+ {
+ // Keine Daten in Memory. Jetzt in jedem Fall den Pointer auf das Mapping data in
+ // /secure/memory ablegen
+ if ("/secure/memory"->Save("truhendaten",data) != 1)
+ {
+ raise_error("Could not save memory to /secure/memory.");
+ }
+ }
+ }
+ else
+ {
+ // brauchen Clones nicht.
+ set_next_reset(-1);
+ data=0; // brauchen Clones nicht.
+ }
+
+ SetProp(P_SHORT, "Eine kleine, magische Holztruhe");
+ SetProp("cnt_version_obj", VERSION_OBJ);
+ SetProp(P_NAME, "Holztruhe");
+ SetProp(P_GENDER, FEMALE);
+ SetProp(P_NAME_ADJ,({"klein", "magisch"}));
+ SetProp(P_LONG, BS(
+ "Die kleine Holztruhe ist aus stabilem Eichenholz gefertigt. Eigentlich "
+ "saehe sie recht unscheinbar aus, waeren da nicht die vielen kunstvollen "
+ "Runen an den Seiten und auf dem Deckel.")
+ +"@@cnt_status@@");
+
+ AddId(({"autoloadertruhe", "holztruhe", "truhe"}));
+
+ // den Rest vom Create braucht die BP nicht.
+ if (!clonep(ME)) return;
+
+ SetProp(P_LOG_FILE,"zesstra/ALTRUHE.rep");
+
+ SetProp(P_WEIGHT, 3000); // Gewicht 5 Kg
+ // die drei hier sind in diesme Fall eigentlich voellig ohne Bedeutung
+ SetProp(P_MAX_WEIGHT, 1000000); // Es passen fuer 1000 kg Sachen rein.
+ SetProp(P_WEIGHT_PERCENT, 100);
+ SetProp(P_MAX_OBJECTS, 100); // sind eh immer 0 echte Objekte drin.
+
+ SetProp(P_VALUE, 0); // Kein materieller Wert. Ist eh nicht verkaufbar.
+ SetProp(P_NOBUY, 1); // Wird im Laden zerstoert, falls er verkauft wird.
+ SetProp(P_NOGET, "Das geht nicht. "+Name(WER,1)+" haftet wie magisch am Boden.\n");
+ SetProp(P_MATERIAL, ([MAT_OAK:49, MAT_MISC_MAGIC:50, MAT_JOFIUM: 1]) );
+ SetProp(P_INFO, BS("In diese stabile Truhe kannst Du bestimmte "
+ "Autoload-Objekte hineinlegen und sie lagern, wenn Du sie gerade "
+ "nicht brauchst. (Mit 'deponiere <was>' kannst Du etwas in der "
+ "Truhe zur Aufbewahrung deponieren, mit 'entnehme <was> oder "
+ "'nimm <was> aus truhe' kannst Du einen Gegenstand wieder "
+ "herausnehmen.)"));
+
+ // Prop fuer rebootfeste Moebel
+ // Der endgueltige Wert (UUID des Spielers) wird per SetBesitzer() gesetzt,
+ // sobald die Truhe das erste Mal in ein Seherhaus bewegt wurde.
+ SetProp(H_FURNITURE, 1);
+
+ AD(({"platz","groesse"}),
+ BS("Die Truhe ist recht klein, aber merkwuerdigerweise "
+ "scheint sie viel mehr an Gegenstaenden aufnehmen zu koennen, als "
+ "es von ihrer Groesse her scheint."));
+ AD(({"gegenstand","gegenstaende"}),
+ BS("Die Truhe scheint zwar vielen Gegenstaenden Platz zu bieten, aber "
+ "dafuer nimmt sie nicht jeden Gegenstand auf."));
+ AD(({"holz","eichenholz"}),
+ BS("Das Eichenholz ist sehr stabil. Es ist ganz glatt geschliffen und "
+ "traegt viele kunstvolle Runen in sich."));
+ AD(({"seiten","seite"}),
+ BS("Die Truhe hat 4 Seiten, die allesamt mit Runen verziert sind."));
+ AD(({"boden"}),
+ BS("Der Boden der Truhe traegt keinerlei Runen."));
+ AD(({"deckel"}),
+ BS("Auch der Deckel der Truhe ist mit Runen verziert."));
+ AD(({"runen","rune"}),
+ BS("Die Runen bedecken alle 4 Seiten und den Deckel der Truhe. Man "
+ "hat sie zweifellos in muehsamer Arbeit aus dem harten Holz "
+ "geschnitzt. Anschliessend wurden sie offenbar mit einem "
+ "Metall gefuellt. Du verstehst zwar ueberhaupt nicht, was "
+ "die Runen bedeuten, aber sie sind bestimmt magisch, denn wann immer "
+ "Du den Deckel oeffnest oder schliesst oder Gegenstaende hineinlegst "
+ "oder herausnimmst, leuchten die Runen hell auf."));
+ AD(({"metall"}),
+ BS("Was das wohl fuer ein Metall sein mag? Zweifellos hat es auch was "
+ "mit Magie zu tun."));
+ AD(({"magie"}),
+ BS("In dieser Truhe scheint viel Magie zu stecken, wenn selbst ein "
+ "Weltuntergang ihr nichts anhaben kann."));
+ AD(({"arbeit","fertigung"}),
+ BS("Die Fertigung dieser Truhe muss sehr aufwendig gewesen sein. "
+ "Kein Wunder, dass die Truhe so teuer ist."));
+ AD(({"wunder"}),
+ BS("Ein Wunder scheint es zu sein."));
+ AD(({"weltuntergang","armageddon"}),
+ BS("Dir schaudert beim Gedanken an den Weltuntergang."));
+ AD(({"gedanken"}),
+ BS("Denk doch lieber an was anderes..."));
+
+ AddCmd("deponier|deponiere&@PRESENT","cmd_deponiere",
+ "Was moechtest Du in der Eichenholztruhe deponieren?");
+ AddCmd("entnimm|entnehme|entnehm","cmd_entnehmen");
+
+ // bei dieser Truhe waere das Erlauben voellig sinnlos. ;-)
+ RemoveCmd(({"serlaube"}));
+
+}
+
+// keine Truhen zerstoeren, die irgendeinen INhalt haben.
+int zertruemmern(string str) {
+ // aus swift_std_container
+ string nf_str;
+ nf_str="Syntax: zertruemmer [Objekt-Id]\n"
+ +"Bsp.: zertruemmer "+QueryProp(P_IDS)[1]+"\n";
+ notify_fail("Fehler: Ohne Parameter klappt das nicht.\n"+nf_str);
+ if(!str) return 0;
+ notify_fail("Fehler: Du musst eine gueltige Objekt-Id angeben!\n"+nf_str);
+ if(present(str)!=TO) // Ueberpruefe, ob auch dieses Objekt gemeint ist!
+ return 0;
+ if( QueryHausbesitzer() != QueryTP() && !QueryProp("test") )
+ {
+ write( BS("Nur "+QueryHausbesitzer()+" darf "+name(WEN,1)+" zertruemmern!"));
+ return 1;
+ }
+ // Objekte enthalten? Wenn ja, abbruch.
+ if (sizeof(autoloader)) {
+ tell_object(PL,BS("Du willst gerade zum Schlag ausholen, um "
+ +name(WEN,1)+ " zu zertruemmern, als Dir einfaellt, dass "
+ +QueryPronoun(WER)+ " ja gar nicht leer ist! Nene, wer weiss, ob "
+ "Du das nicht noch brauchen koenntest."));
+ return 1;
+ }
+ // sonst geerbten Kram ausfuehren.
+ return ::zertruemmern(str);
+}
+
+// Zesstra, 1.7.07, fuers Hoerrohr
+string GetOwner() {return "zesstra";}
+
+// Prueft das Objekt auf Eignung fuer die Truhe, speichert seine Daten und
+// zerstoert es anschliessend. NODROP-Objekte koennen nur so in die Truhe
+// gelegt werden, alle anderen koennen auch mit "stecke ... in truhe"
+// deponiert werden, woraufhin ebenfalls PreventInsert() und NotifyInsert()
+// durchlaufen werden.
+protected int cmd_deponiere(string cmd, mixed args) {
+ if (!objectp(PL)) return 0;
+
+ notify_fail(Name(WER,1)+" ist doch geschlossen!\n");
+ if(QueryProp(P_CNT_STATUS)!=CNT_STATUS_OPEN) return 0;
+
+ notify_fail("Was moechtest Du in der Eichenholztruhe deponieren?\n");
+ if (!stringp(cmd) || !sizeof(cmd)
+ || !pointerp(args) || !sizeof(args)) return 0;
+ object ob=args[0];
+ if (!objectp(ob)) return 0;
+ // wuerde die Truhe das Objekt ueberhaupt aufnehmen? Fehlerausgabe durch
+ // PrevenInsert()
+ if (PreventInsert(ob)) return 1;
+ // Ausziehen... Schade, dass DoUnwear nix vernuenftiges an Rueckgabewert
+ // hat. :-(
+ if (objectp(ob->QueryProp(P_WORN))) {
+ ob->DoUnwear();
+ if (objectp(ob->QueryProp(P_WORN))) {
+ tell_object(PL, BS("Du musst "+ ob->name(WEN,1)+ "zunaechst einmal "
+ "ausziehen!"));
+ return 1;
+ }
+ }
+ // wegstecken
+ if (objectp(ob->QueryProp(P_WIELDED))) {
+ ob->DoUnwield();
+ if (objectp(ob->QueryProp(P_WIELDED))) {
+ tell_object(PL, BS("Du musst "+ ob->name(WEN,1)+ "zunaechst einmal "
+ "wegstecken!"));
+ return 1;
+ }
+ }
+ // NO_CHECK und Silent-Bewegung, Meldungen an den Spieler selber machen.
+ tell_object(PL, BS("Du steckst "+ ob->name(WEN,1) + " in " + name(WEN,1) +
+ "."));
+
+ tell_room(environment(),BS(PL->Name(WER) + " legt " + ob->name(WEN,0) +
+ " in " + name(WEN,1) + " hinein."),({PL}));
+ ob->move(ME, M_NOCHECK|M_SILENT);
+ return 1;
+}
+
+// alternative zum "nimm bla aus truhe". Spieler wollten was kurzes dafuer
+// haben.
+protected int cmd_entnehmen(string cmd) {
+ int res;
+ mixed noget;
+
+ if (!objectp(PL)) return 0;
+
+ notify_fail(Name(WER,1)+" ist doch geschlossen!\n");
+ if(QueryProp(P_CNT_STATUS)!=CNT_STATUS_OPEN) return 0;
+
+ notify_fail(BS("Was moechtest Du aus "+name(WEM,1)+ " entnehmen?\n"));
+ if (!stringp(cmd) || !sizeof(cmd)) return 0;
+
+ object *obs=present_objects(cmd);
+
+ if (!sizeof(obs) || !objectp(obs[0]))
+ return 0;
+
+ // NOGET ist hier bloed. So ist es zwar auch nicht richtig doll... *seufz*
+ // Die hier ist/waere aber nen uebler Hack, erstmal auskommentiert lassen.
+ // also, P_NOGET sichern.
+ /*if (!closurep(noget=ob->Query(P_NOGET,F_QUERY_METHOD))) {
+ noget=ob->Query(P_NOGET,F_VALUE);
+ ob->Set(P_NOGET,0,F_VALUE);
+ }
+ else {
+ ob->Set(P_NOGET,0,F_QUERY_METHOD);
+ }*/
+ // nehmen.
+ res=PL->pick_obj(obs[0]);
+ // P_NOGET zurueckschreiben. (Ja, wenn eine Closure als F_VALUE drinsteht,
+ // landet die jetzt als F_QUERY_METHOD im Objekt.
+ /*if (closurep(noget)) {
+ ob->Set(P_NOGET,noget,F_QUERY_METHOD);
+ }
+ else
+ ob->Set(P_NOGET,noget,F_VALUE);
+*/
+ return(res);
+}
+
+// Hier wird auch das PreventInsert() von der Blueprint gerufen. Das
+// erleichtert es, die Liste an erlaubten Objekten zu aendern, ohne dass man
+// alle Clones ersetzen muss.
+varargs int PreventInsert(object ob) {
+ string oname;
+ // Das Objekt, was die Truhe gerade selber bewegt, wird ignoriert.
+ if (!objectp(ob) || ob_in_bewegung==ob) return 0;
+
+ oname=BLUE_NAME(ob);
+
+ // Pruefung in Clonen:
+ if (clonep(ME))
+ {
+ // nur Eigentuemer
+ if (!stringp(uuid) || !sizeof(uuid)) {
+ if (objectp(PL))
+ tell_object(PL,BS(sprintf("%s gehoert Dir nicht, daher kannst Du "
+ "auch keine Gegenstaende in %s legen.",
+ Name(WER,1),QueryPronoun(WEN))));
+ return 1;
+ }
+ if (!objectp(PL) || getuuid(PL)!=uuid) {
+ if (objectp(PL))
+ tell_object(PL,BS(sprintf("Nur %s darf Gegenstaende in %s "
+ "hineinlegen.",capitalize(explode(uuid,"_")[0]),name(WEN,1))));
+ return 1;
+ }
+ // jedes Objekt nur einmal.
+ if (member(autoloader,oname)) {
+ if (objectp(PL))
+ tell_object(PL,BS(Name(WER,1)+ " kann von einem Gegenstand jeweils "
+ "nur ein Exemplar aufnehmen, es ist aber bereits "
+ +ob->name(WER,0) + " in " + QueryPronoun(WEM) + "."));
+ return 1;
+ }
+ // jetzt Erlaubnisliste der BP fragen.
+ if (objectp(blueprint(ME)))
+ return blueprint(ME)->PreventInsert(ob);
+ else
+ return load_object(load_name(ME))->PreventInsert(ob);
+ }
+ // Ende fuer Pruefung fuer Clone.
+
+ // ab hier jetzt die Pruefung durch die BP.
+ // Keine (freigegebener) Autoloader? Hat in diesem Container nix verloren!
+ if( !ob->QueryProp(P_AUTOLOADOBJ) ) {
+ if (objectp(PL))
+ tell_object(PL,BS("In "+name(WEN,1)
+ +" kannst Du nur Autoload-Objekte hineinlegen. "));
+ return 1;
+ }
+ else if (member(blacklist,oname)) {
+ if (objectp(PL))
+ tell_object(PL,BS("In "+name(WEN,1)
+ +" kannst Du nur dafuer erlaubte Autoload-Objekte hineinlegen. "
+ +ob->Name(WER,1) + " wurde explizit als nicht erwuenscht "
+ "befunden."));
+ return 1;
+ }
+ else if (!member(whitelist,oname)) {
+ if (!member(vorschlaege,oname)) {
+ vorschlaege[oname,0]=ob->name(WER,0) || "";
+ vorschlaege[oname,1]=ob->short() || "";
+ }
+ if (objectp(PL))
+ tell_object(PL,BS("In "+name(WEN,1)
+ +" kannst Du nur dafuer erlaubte Autoload-Objekte hineinlegen. "
+ +ob->Name(WER,1) + " ist momentan nicht auf der Liste. Der "
+ "Gegenstand wurde jetzt als Vorschlag gespeichert. Bitte hab "
+ "etwas Geduld, bis sich jemand den Gegenstand angeschaut hat."));
+ // ggf. reset reaktivieren und Maintainer informieren.
+ if (!query_next_reset())
+ set_next_reset(1);
+ return 1;
+ }
+ // getragenes?
+ if (ob->QueryProp(P_WORN)) {
+ ob->DoUnwear(0);
+ if (ob->QueryProp(P_WORN)) { //ARGL. GRUMMEL.
+ if (objectp(PL))
+ tell_object(PL,BS("Willst Du "+ob->name(WEN,1) + " nicht erstmal "
+ "ausziehen?"));
+ return 1;
+ }
+ }
+ // enthaelt es irgendwelche anderen Objekte?
+ if (sizeof(all_inventory(ob))) {
+ if (objectp(PL))
+ tell_object(PL,BS(ob->Name(WER,1) + " ist nicht leer."));
+ return 1;
+ }
+
+ // andere Einschraenkungen, als hier geprueft werden, gibt es nicht.
+ return 0;
+}
+
+// hier ist das Objekt jetzt in der Truhe, d.h. Daten speichern und Objekt
+// destructen. ;)
+void NotifyInsert(object ob, object oldenv) {
+
+ // Das Objekt, was die Truhe gerade selber bewegt, wird ignoriert.
+ if (!objectp(ob) || ob==ob_in_bewegung)
+ return;
+ STORELOG(sprintf("%s deponiert %s [%O], Daten: %O",getuid(PL),ob->name(WEN,0),
+ ob,ob->QueryProp(P_AUTOLOADOBJ)));
+ // noetig sind die IDs, den Namen und die AUTOLOADOBJ-Daten des Objekts.
+ // ;-)
+ autoloader[BLUE_NAME(ob),ALDATA]=ob->QueryProp(P_AUTOLOADOBJ);
+ autoloader[BLUE_NAME(ob),IDS]=ob->QueryProp(P_IDS);
+ // Objekte, die 0 als short liefern, kriegen eine Standard-Short und werden
+ // sichtbar gemacht, da sie sonst nicht wiederzufinden sind. Objekte, die
+ // unsichtbar sein sollen, duerfen nicht erlaubt werden.
+ // TODO eine ID als Short nehmen?
+ autoloader[BLUE_NAME(ob),NAME]=capitalize((ob->short()||"<Unbekannt>.\n")[..<3]);
+ // nach dem Move die realen Objekte destructen.
+ call_out(#'check_content, 0);
+ save_me();
+}
+
+// Objekt wurde entnommen, also aus der Liste der enthaltenen Autoloader
+// loeschen. Ausserdem Objekt konfigurieren. Dies wird erst hier gemacht und
+// nicht in create_object(), damit es so aehnlich wie moeglich zum clonen der
+// Autoloader beim erstellen des Spielerobjektes wird (dort wird erst bewegt,
+// dann konfiguriert).
+void NotifyLeave(object ob, object dest) {
+ string error, oname;
+
+ if (!objectp(ob))
+ return;
+
+ oname=BLUE_NAME(ob);
+ if (!member(autoloader,oname)) {
+ // Das sollte definitiv nicht passieren.
+ ERRLOG(sprintf("Gegenstand (%O) wurde entnommen, der nicht "
+ "gespeichert war!",ob));
+ return;
+ }
+
+ // wenn kein Fehler: Objekt aus Liste loeschen. Sonst wird das Objekt
+ // zerstoert. Damit bleiben die Autoloader-Daten hier erhalten und der
+ // Spieler hat kein disfunktionales Objekt im Inventar.
+ if (error) {
+ ERRLOG(sprintf("Fehler beim Konfigurieren von %O. Fehlermeldung: %O."
+ "Daten: %O",ob,error,autoloader[oname,ALDATA]));
+ ob->remove(1);
+ if (objectp(ob))
+ destruct(ob);
+ }
+ else {
+ PICKLOG(sprintf("Objekt (%O) wurde entnommen.",ob));
+ m_delete(autoloader,oname);
+ // speichern
+ save_me();
+ }
+}
+
+protected void check_content() {
+ // wenn Objekte noch in der Truhe sind, also nicht erfolgreich in
+ // einen Spieler bewegt wurden, werden zerstoert. Datenverlust gibt es
+ // hierbei nicht, weil die Daten der Autoloader nur durch NotifyLeave()
+ // geloescht werden.
+ foreach(object ob: all_inventory()) {
+ ob->remove(1);
+ if (objectp(ob)) destruct(ob);
+ }
+}
+
+// hier nochmal schauen, ob das Objekt auch in den richtigen Spieler bewegt
+// wird... Falls das move dann hier abgebrochen wird, wird das Objekt im
+// naechsten HB von der Truhe zerstoert. (chk_contents())
+varargs int PreventLeave(object ob, mixed dest) {
+ object ob2;
+
+ //DEBUG(sprintf("PreventLeave(): Ob: %O, Dest: %O (%O)",
+ // ob,dest,(objectp(dest)?"Objekt":"Non-Object")));
+
+ if (!objectp(ob)) return 0;
+ // falls string uebergeben, erstmal zug. Spieler finden.
+ if (stringp(dest) && sizeof(dest))
+ dest=find_player(dest);
+
+ // richtiges INteractive? Dann darf das Objekt raus. Sonst nicht. ;-)
+ if (!objectp(dest) || !interactive(dest) || getuuid(dest)!=uuid)
+ return 1;
+
+ // pruefen, ob der Spieler schon ein Objekt dieser Blueprint dabei hat. Wenn
+ // ja, Abbruch, das koennte sonst zuviele Probleme geben.
+ if (objectp(ob2=present_clone(ob,dest))) {
+ tell_object(dest,BS("Du hast bereits "+ob2->name(WEN,0) +
+ " dabei. Zwei Gegenstaende dieser Art kannst du nicht gleichzeitig "
+ "mit Dir herumtragen."));
+ return 1; //nicht rausnehmen.
+ }
+ return 0;
+}
+
+// Objekte ausgeben, die hier angeblich drin sind. ;-) Gibt aber nur die
+// Autoloader aus, keine echten Objekt, die Container sind. Allerdings sollte
+// sowas eh nicht vorkommen. ;-)
+// flags: 1 - return array, 2 - don't collect equal objects '
+// flags: 4 - don't append infos for wizards
+varargs mixed make_invlist(object viewer, mixed inv, int flags) {
+ int iswiz;
+ mixed objs;
+
+ iswiz = IS_LEARNER( viewer ) && viewer->QueryProp(P_WANTS_TO_LEARN);
+ // Mapping benutzen, um multiplen Overhead fuer allokation im foreach() zu
+ // vermeiden.
+ objs=m_allocate(sizeof(autoloader),1);
+ foreach(string oname, string *ids, string sh: autoloader) {
+ if (iswiz && !(flags & 4))
+ objs[oname]=sh + ". ["+oname+"]";
+ else
+ objs[oname]=sh + ".";
+ }
+ if(flags & 1) return(m_values(objs)-({""}));
+ if(!sizeof(autoloader)) return "";
+ return sprintf("%"+(sizeof(objs) > 6 ? "#" : "=")+"-78s",
+ implode(m_values(objs)-({""}), "\n")) + "\n";
+}
+
+// erzeugt das benannte Objekt und liefert es zurueck. Liefert 0 im Fehlerfall.
+// ausserdem bewegt es das Objekt in die Truhe, damit es ein Env hat und die
+// Truhe via NotifyLeave() mitkriegt, dass es tatsaechlich entnommen wurde.
+private object create_object(string oname) {
+ string error;
+ object ob;
+ mixed noget;
+ if (!member(autoloader,oname)) return 0;
+
+ //Blueprint finden (ja, das ist nicht unbedingt noetig, man koennte auch
+ //direkt clonen)
+ if (error=catch(ob=load_object(oname);publish) ||
+ !objectp(ob)) {
+ ERRLOG(sprintf("Konnte %s nicht laden/finden. Fehler: %O",
+ oname,error));
+ return 0;
+ }
+ // clonen
+ if (error=catch(ob=clone_object(oname);publish) ||
+ !objectp(ob)) {
+ ERRLOG(sprintf("Konnte %s nicht clonen. Fehler: %O",
+ oname,error));
+ return 0;
+ }
+ // konfigurieren
+ error=catch(ob->SetProp(P_AUTOLOADOBJ,autoloader[oname,ALDATA]);publish);
+
+ //Objekt bewegen, dabei Objekt in glob. Var. merken, damit PreventInsert()
+ //und NotifyInsert() es ignorieren. *seufz*
+ ob_in_bewegung=ob;
+ ob->move(ME,M_NOCHECK);
+ ob_in_bewegung=0;
+
+ // jetzt noch nen Callout starten, damit das Objekt zerstoert wird, wenn es
+ // nicht wirklich in einen Spieler bewegt wird.
+ call_out(#'check_content,1);
+
+ return(ob);
+}
+
+// Schauen, ob die truhe ein Objekt mit passender ID enthaelt. Wenn
+// ja, das Objekt erzeugen und zurueckliefern.
+// Diese Funktion hat eine Reihe von Nachteilen bzw. Defiziten ggue. der
+// normalerweise in Containern definierten Funktion:
+// - Nur das erste Objekt, auf das id passt. Ich hab erstmal keine Lust,
+// hier mehrere Objekte zu erzeugen. Mal schauen, ob es so geht. Auch waere
+// es ein Problem, wenn viele Objekt die Evalgrenze bzw. nicht alle in den
+// Spieler bewegt werden, nachdem sie erzeugt wurden.
+// - keine komplexen Ausdruecke, nur reine IDs.
+// Ich halte den Aufwand fuer nicht gerechtfertigt.
+object *present_objects( string complex_desc ) {
+ object ob;
+ if (!stringp(complex_desc) || !sizeof(complex_desc))
+ return ({});
+ // diese Funktion liefert nur Objete zurueck, wenn der richtige Interactive
+ // versucht, sie zu entnehmen. ;-)
+ if (!objectp(this_interactive()) ||
+ getuuid(this_interactive())!=uuid)
+ return ({});
+
+ // "alles" liefert das erstbeste Objekt.
+ if (complex_desc=="alles" && sizeof(autoloader))
+ {
+ string oname=m_indices(autoloader)[0];
+ ob=create_object(oname);
+ if (objectp(ob)) return ({ob});
+ }
+
+ // ueber alle Eintraege gehen, bis eine ID stimmt, erstes passendes Objekt
+ // erzeugen und in einem Array zurueckliefern.
+ foreach(string oname, string *ids: autoloader) {
+ if (member(ids,complex_desc)==-1) continue;
+ ob=create_object(oname);
+ break; //objekt gefunden, fertig hier
+ }
+ if (objectp(ob)) return ({ob});
+ return ({}); // nix gefunden
+}
+
+
+
+// ******************* Verwaltung *********************************
+
+// registriert die Truhe auf den jeweiligen Eigentuemer.
+protected void SetBesitzer(string unused, string newuuid) {
+ if (!stringp(newuuid) || !sizeof(newuuid)) return;
+ // wenn schon registriert, abbrechen
+ if (stringp(uuid) && sizeof(uuid)) return;
+
+ uuid=newuuid;
+ Set(H_FURNITURE,uuid,F_VALUE); //Setmethode umgehen, sonst Rekursion
+ // ab jetzt nur noch von der Truhe selber.
+ Set(H_FURNITURE,SECURED,F_MODE_AS);
+
+ // Daten fuer den Benutzer aus der Blueprint holen (BP liefert KEINE Kopie
+ // und es darf KEINE gemacht werden!):
+ autoloader=(mapping)load_name()->GetData(uuid);
+
+ // keine Daten gekriegt? -> Fehler loggen
+ if (!mappingp(autoloader))
+ {
+ ERRLOG(sprintf("Keine gueltigen Daten vom Truhenmaster (BP) erhalten. "
+ "initialisiere mit leerem Mapping. :-("));
+ raise_error(sprintf(
+ "Keine gueltigen Daten vom Truhenmaster (BP) fuer UUID %s "
+ "erhalten.\n",uuid));
+ }
+}
+
+// Set-Funktion
+string _set_h_furniture(mixed arg) {
+ if (stringp(arg))
+ {
+ SetBesitzer(0,arg); // bricht ab, wenn bereits registriert.
+ }
+ return(uuid);
+}
+
+// Falls das Speichern in der BP nicht klappte, rufen die Clones diese
+// Funktion. Schreiben der Daten in in Logfile zur Restaurieren per Hand.
+private void EmergencyStore(int res) {
+ ERRLOG(sprintf("EmergencyStore() called. Rueckgabewert des "
+ "Truhenmaster (BP) war: %O. Speichere Daten in Logfile. ",res));
+ write_file(__DIR__+"ALTRUHE.NOTFALLDATEN",
+ sprintf("Daten fuer %O:\n%O\n",uuid,autoloader));
+}
+
+protected void save_me() {
+ int res;
+ // nur BP speichern
+ if (!clonep(ME))
+ save_object(SAVEFILE);
+ else
+ {
+ if (objectp(blueprint(ME)))
+ res=(int)blueprint(ME)->StoreData(uuid,autoloader);
+ else
+ res=(int)load_object(load_name(ME))->StoreData(uuid,autoloader);
+
+ if (res!=1)
+ EmergencyStore(res); // Daten in einem Notfall-Logfile ablegen.
+ }
+}
+
+
+// diese Funktion wird vom Seherhausraum gerufen, sobald ein rebootfestes
+// Moebelstueck erzeugt und konfiguriert wurde.
+void post_create() {
+ if (!clonep()) return;
+
+ // wenn jetzt kein Env: destructen
+ if (!objectp(environment())) {
+ remove(1);
+ return;
+ }
+ //beim Schrankmaster registrieren
+ SCHRANKMASTER->RegisterCnt(ME, QueryProp("cnt_version_std")
+ +":"+QueryProp("cnt_version_obj"), environment()->QueryOwner(),
+ environment());
+}
+
+// diese Funktion wird vom Schrankmaster gerufen, wenn dieser meint, dass
+// dieses Objekt neu erstellt werden sollte.
+int UpdateMe()
+{
+ if (!clonep())
+ return 0;
+ if (!objectp(environment()))
+ return 1;
+ object ob=clone_object(load_name(ME));
+ if (objectp(ob)) {
+ object oldenv=environment();
+ // UUID uebertragen
+ ob->SetProp(H_FURNITURE, uuid);
+ // hierhier bewegen, dabei werden UUID und Daten von der neuen Truhe meist
+ // automatisch geholt.
+ ob->move(oldenv,M_NOCHECK);
+ // jetzt erst post_create() rufen!
+ ob->post_create();
+ // dieses Objekt rausbewegen (damit das Seherhaus es austraegt).
+ move("/room/void",M_NOCHECK);
+ // Seherhausraum speichern (koennte teuer sein!)
+ oldenv->Save(1);
+ // selbstzerstoeren
+ // __INT_MAX__ bedeutet: nicht speichern, die neue Truhe hat die daten
+ // schon aus der BP abgefragt.
+ remove(__INT_MAX__);
+ }
+ return(1);
+}
+
+// bei Selbstzerstoerung speichern bzw. Daten an die Blueprint uebermitteln
+// und beim Schrankmaster abmelden.
+varargs int remove(int silent) {
+ string uid="";
+
+ // Blueprint speichern im Savefile, Clones uebertragen die Daten hier an die
+ // Blueprint. Clones nur, wenn nicht __INT_MAX__ uebergeben wurde.
+ if (silent!=__INT_MAX__ || !clonep())
+ save_me();
+
+ if (clonep()) {
+ // Clone melden sich beim Schrankmaster ab.
+ if (objectp(environment())) {
+ uid=environment()->QueryOwner();
+ }
+ //beim Schrankmaster deregistrieren
+ SCHRANKMASTER->RemoveCnt(ME,uid);
+ }
+ return(::remove(silent));
+}
+
+// ***************** NUR BLUEPRINTS *********************************
+
+// neuen Autoloader zulassen (nur EM+!)
+varargs int AddAutoloader(string path,string nam) {
+ object ob;
+ if (clonep(ME)) return 0;
+ if (!stringp(path) || !sizeof(path)) return -1;
+ if (!ACCESS) return -2;
+ //if (!ARCH_SECURITY) return -2;
+ if (member(whitelist,path)) return -3;
+ if (catch(ob=load_object(path);publish)
+ || !objectp(ob))
+ return -4;
+ // wenn Name nicht angegeben und auch nicht aus BP ermittelbar: Abbruch.
+ if (!stringp(nam) || !sizeof(nam)) {
+ nam=ob->name(WER,0);
+ if (!stringp(nam) || !sizeof(nam)) return -5;
+ }
+ ITEMLOG(sprintf("%s erlaubt: %s (%s)\n",getuid(this_interactive()),
+ path,nam));
+ whitelist+=([path:capitalize(nam)]);
+ if (member(vorschlaege,path))
+ m_delete(vorschlaege,path);
+ save_me();
+ return(1);
+}
+
+// Autoloader aus Erlaubnisliste entfernen (nur EM+!)
+int RemoveAutoloader(string path) {
+ if (clonep(ME)) return 0;
+ if (!stringp(path) || !sizeof(path)) return -1;
+ if (!ACCESS) return -2;
+ //if (!ARCH_SECURITY) return -2;
+ if (!member(whitelist,path)) return -3;
+ ITEMLOG(sprintf("%s widerruft Erlaubnis: %s (%s)\n",getuid(this_interactive()),
+ path,whitelist[path]));
+ whitelist-=([path]);
+ save_me();
+ return(1);
+}
+
+// erlaubte Autoloader abfragen
+mapping QueryAutoloader() {
+ return(copy(whitelist));
+}
+
+// neuen Autoloader in Blacklist eintragen (nur EM+!)
+varargs int AddBlacklist(string path, string nam) {
+ object ob;
+ if (clonep(ME)) return 0;
+ if (!stringp(path) || !sizeof(path)) return -1;
+ if (!ACCESS) return -2;
+ //if (!ARCH_SECURITY) return -2;
+
+ if (member(blacklist,path)) return -3;
+
+ if (catch(ob=load_object(path);publish)
+ || !objectp(ob))
+ return -4;
+ // wenn Name nicht angegeben und auch nicht aus BP ermittelbar: Abbruch.
+ if (!stringp(nam) || !sizeof(nam)) {
+ nam=ob->name(WER,0);
+ if (!stringp(nam) || !sizeof(nam)) return -5;
+ }
+ // ggf. erlaubten entfernen.
+ if (member(whitelist,path))
+ RemoveAutoloader(path);
+ ITEMLOG(sprintf("%s verbietet: %s (%s)\n",getuid(this_interactive()),
+ path,nam));
+
+ blacklist+=([path:capitalize(nam)]);
+
+ if (member(vorschlaege,path))
+ m_delete(vorschlaege,path);
+
+ save_me();
+ return(1);
+}
+
+// Autoloader aus Blacklist entfernen (nur EM+!)
+int RemoveBlacklist(string path) {
+ if (clonep(ME)) return 0;
+ if (!stringp(path) || !sizeof(path)) return -1;
+ if (!ACCESS) return -2;
+ //if (!ARCH_SECURITY) return -2;
+ if (member(blacklist,path)==-1) return -3;
+ ITEMLOG(sprintf("%s loescht: %s (%s) von Blacklist\n",getuid(this_interactive()),
+ path,blacklist[path]));
+ blacklist-=([path]);
+ save_me();
+ return(1);
+}
+
+// gesperrte Autoloader abfragen
+mapping QueryBlacklist() {
+ return(copy(blacklist));
+}
+
+// vorschlaege abfragen
+varargs mixed QueryVorschlaege(int format) {
+ string res="\n";
+ if (!format) return(copy(vorschlaege));
+
+ foreach(string oname, string nam, string sh: vorschlaege) {
+ res+=sprintf("%.78s:\n %.37s,%.37s\n",oname,nam,sh);
+ }
+
+ if (format==2 && objectp(PL))
+ tell_object(PL,res);
+ else
+ return res;
+ return 0;
+}
+
+// Wird diese funktion in der Blueprint gerufen, liefert sie die Daten fuer
+// eine Truhe mit dieser UUID zurueck. Aber nur dann, wenn die auch von einer
+// truhe abgerufen wird und keinem beliebigen anderen Objekt oder wenn ein EM
+// abfragt.
+mapping GetData(string uid) {
+ if (clonep(ME)) return 0;
+ if (extern_call())
+ {
+ if (!objectp(previous_object())) return 0;
+ if (blueprint(previous_object()) != ME
+ && load_name(previous_object()) != __FILE__[..<3]
+ && !ACCESS)
+ return(0);
+ }
+ if (!stringp(uid)) return ([]);
+
+ if (!member(data, uid))
+ data[uid] = m_allocate(1,3);
+
+ // Absichtlich keine Kopie, damit die Truhen (falls jemand mehrere kauft)
+ // sich alle eine Kopie des Mappings teilen.
+ return data[uid];
+}
+
+// Loest die Speicherung der Daten im Savefile aus, denn irgendwelche Daten
+// haben sich in einem Clone geaendert, welche noch auf die Platte muessen.
+// Diese Funktion speicherte frueher Daten aus den Clones wieder im Mapping
+// des Masters (der Blueprint). Dies ist heute nicht mehr so, weil alle Truhen
+// (eines Benutzers) sich data[uid] teilen. Daher wird hier ein Fehler
+// ausgeloest, wenn es von einer Truhe ein Mapping kriegt, welches nicht
+// identisch (!) mit dem data[uid] ist.
+// liefert 0 im Fehlerfall!
+int StoreData(string uid, mapping tmp) {
+
+ if (clonep(ME)) return 0;
+
+ // Aber nur dann, wenn die auch von einer truhe abgerufen wird und keinem
+ // beliebigen anderen Objekt oder wenn ein EM setzt.
+ if (extern_call())
+ {
+ if (!objectp(previous_object()))
+ return 0;
+ if (blueprint(previous_object()) != ME
+ && load_name(previous_object()) != __FILE__[..<3]
+ && !ACCESS)
+ return 0;
+ }
+ if (!stringp(uid) || !mappingp(tmp))
+ return(0);
+
+ // tmp muss auf _dasselbe_ Mapping zeigen wie data[uid]. Wenn das nicht der
+ // Fall ist, ist was schiefgelaufen. Jedenfalls wird dann hier nen Fehler
+ // ausgeloest.
+ if (tmp != data[uid])
+ {
+// if(program_time(previous_object()) < 1400525694)
+// data[uid]=tmp;
+// else
+ raise_error("StoreData() gerufen und Daten sind nicht identisch "
+ "mit den bereits bekannten.\n");
+ }
+
+ // Absichtlich keine Kopie, damit sich alle Truhen das Mapping teilen.
+ //data[uid]=tmp;
+
+ // Savefile muss natuerlich geschrieben werden, fuer den naechsten Reboot.
+ if (find_call_out(#'save_me)==-1)
+ call_out(#'save_me,10); // Speichervorgaenge ggf. sammeln (upd -ar ...)
+ return(1);
+}
+
+// Maintainer ueber Truhenvorschlaege informieren
+void reset() {
+
+ if (clonep() || !sizeof(vorschlaege)) {
+ // ohne Vorschlaege ist auch kein reset noetig.
+ set_next_reset(-1);
+ return;
+ }
+ set_next_reset(12000); // alle 3-4h reicht.
+ foreach(string uid: MAINTAINER) {
+ object pl=find_player(uid);
+ if (objectp(pl) && query_idle(pl) < 1800)
+ tell_object(pl,BS("Es gibt neue Objektvorschlaege fuer die "
+ "Autoloadertruhe. Bitt schau da doch bei Gelegenheit mal drueber."));
+ }
+}
+
+
+// *************************************************************************
+
+// **************** SONSTIGES **********************************************
+
+// *seufz*
+// secure_level() aus der simul_efun ist hier momentan nicht brauchbar, weil
+// dort auch p/seher/moebel/autoloadertruhe in der Callerkette steht und das
+// ein levle von 0 hat. *seufz*
+nomask private int my_secure_level() {
+ int *level;
+ //kette der Caller durchlaufen, den niedrigsten Level in der Kette
+ //zurueckgeben. Zerstoerte Objekte (Selbstzerstoerer) fuehren zur Rueckgabe
+ //von 0.
+ //caller_stack(1) fuegt dem Rueckgabearray this_interactive() hinzu bzw. 0,
+ //wenn es keinen Interactive gibt. Die 0 fuehrt dann wie bei zerstoerten
+ //Objekten zur Rueckgabe von 0, was gewuenscht ist, da es hier einen
+ //INteractive geben muss.
+ level=map(caller_stack(1),function int (object caller)
+ {if (objectp(caller))
+ return(query_wiz_level(geteuid(caller)));
+ return(0); // kein Objekt da, 0.
+ } );
+ return(min(level)); //den kleinsten Wert im Array zurueckgeben (ggf. 0)
+}
+
+
+// debugkram
+mixed _query_content() {
+ //deep_copy, damit nicht jemand einfach so an den Daten rumbasteln kann.
+ return(deep_copy(autoloader));
+}
+
+mixed _query_owner() {
+ return(uuid);
+}
+
+int DeleteData(string uid) {
+ if (clonep(ME)) return 0;
+ if (!stringp(uid) || !sizeof(uid)) return -1;
+ if (!ACCESS) return -2;
+ //if (!ARCH_SECURITY) return -2;
+ m_delete(data,uid);
+ save_me();
+ return(1);
+}
+
+mixed testfun() {return "bin da\n";}
+
diff --git a/d/seher/haeuser/moebel/kleiderschrank.c b/d/seher/haeuser/moebel/kleiderschrank.c
new file mode 100644
index 0000000..79209b4
--- /dev/null
+++ b/d/seher/haeuser/moebel/kleiderschrank.c
@@ -0,0 +1,208 @@
+//--------------------------------------------------------------------------------
+// Name des Objects: Kleiderschrank
+// Letzte Aenderung: 17.03.2001
+// Magier: Swift
+//--------------------------------------------------------------------------------
+#pragma strong_types,rtt_checks
+
+#include "schrankladen.h"
+#include <ansi.h>
+inherit LADEN("swift_std_container");
+
+#define VERSION_OBJ "3"
+
+string strall;
+
+protected void create()
+{
+ if (!clonep(TO)) return;
+ swift_std_container::create();
+ SetProp(P_SHORT, "Ein Kleiderschrank");
+ SetProp(P_LONG, BS(
+ "In diesem massiven Holzschrank kannst Du die Ausruestung fuer eine "
+ +"halbe Armee unterbringen. Mehrere Regale sorgen dafuer, dass alles "
+ +"seinen geordneten Platz findet, damit Du es auch schnell "
+ +"wiederfindest.")+"@@cnt_status@@");
+ AddId(({"kleiderschrank", "holzschrank", "schrank"}));
+ SetProp("cnt_version_obj", VERSION_OBJ);
+ SetProp(P_NAME, "Kleiderschrank");
+ SetProp(P_GENDER, MALE);
+ SetProp(P_WEIGHT, 5000); // Gewicht 5 Kg
+ SetProp(P_MAX_WEIGHT, 1000000); // Es passen fuer 1000 kg Sachen rein.
+ SetProp(P_WEIGHT_PERCENT, 100); // Dafuer macht er auch nix leichter :)
+ SetProp(P_MAX_OBJECTS, 100); // Mehr sollte nicht sein, lt. Tiamak.
+ SetProp(P_VALUE, 0); // Kein materieller Wert. Ist eh nicht verkaufbar.
+ SetProp(P_NOBUY, 1); // Wird im Laden zerstoert, falls er verkauft wird.
+ SetProp(P_NOGET, "Das geht nicht. "+Name(WER,1)+" haftet wie magisch am Boden.\n");
+ SetProp(P_MATERIAL, ({MAT_MISC_WOOD, MAT_MISC_MAGIC}) );
+ SetProp(P_INFO, "Versuchs mal mit: \"skommandos "+QueryProp(P_IDS)[1]+"\" !\n");
+ SetProp("obj_cmd", "sliste [Objekt-Id] [Kleidungs-/Ruestungstyp|\"alles\"]\n"
+ +" Kleidungs-/Ruestungstypen: Helme, Umhaenge, Ruestungen, Hosen, Schuhe,\n"
+ +" Handschuhe, Guertel, Amulette, Ringe, Koecher,\n"
+ +" Schilde, Sonstiges\n");
+ AD(({"regal", "regale"}), BS("Durch die Regale kommt etwas Ordnung in die "
+ +"vielen Sachen, die man in den Schrank stecken kann. Du kannst Dir z.B. "
+ +"eine Liste bestimmter Kleidungs-/Ruestungstypen des Schrankinhaltes "
+ +"mit dem Befehl \"sliste\" anschauen. (Das geht natuerlich nur bei "
+ +"offenem Schrank!"));
+
+ AddCmd(({"sliste"}), "auflistung");
+}
+
+varargs int PreventInsert(object ob)
+{
+ // Nur Ruestung/Kleidung hat in diesem Container was verloren!
+ if ((ob->IsClothing() || ob->QueryProp(P_ARMOUR_TYPE))
+ && !ob->QueryProp(P_WEAPON_TYPE) )
+ {
+ return ::PreventInsert(ob);
+ }
+
+ write( BS("In "+name(WEN,1)+" kannst Du nur Ruestungs-/Kleidungsstuecke legen!"));
+ return 1;
+}
+
+int auflistung2(string was, string nf_str1, string nf_str2, int alles)
+{
+ string obshort, suche, *strs;
+ object *obs;
+ int i;
+ mapping suchobs;
+ switch(was)
+ {
+ case "helme" : suche=AT_HELMET; break;
+ case "umhaenge" : suche=AT_CLOAK; break;
+ case "ruestungen" : suche=AT_ARMOUR; break;
+ case "hosen" : suche=AT_TROUSERS; break;
+ case "schuhe" : suche=AT_BOOT; break;
+ case "handschuhe" : suche=AT_GLOVE; break;
+ case "guertel" : suche=AT_BELT; break;
+ case "amulette" : suche=AT_AMULET; break;
+ case "ringe" : suche=AT_RING; break;
+ case "koecher" : suche=AT_QUIVER; break;
+ case "schilde" : suche=AT_SHIELD; break;
+ case "sonstiges" : suche=AT_MISC; break;
+ default : write("Fehler: Ungueltiger Kleidungs-/Ruestungstyp. "
+ +"Folgende Typen gibt es:\n"+nf_str1+nf_str2);
+ return 1; break;
+ }
+ obs=all_inventory();
+ suchobs=([]);
+ for(i=0;i<sizeof(obs);i++)
+ {
+ obshort=obs[i]->QueryProp(P_SHORT);
+ if(obshort=="Nichts besonderes") // keine P_SHORT ?
+ obshort=obs[i]->Name(WER); // Hoffen wir mal dass das Obj. nen Namen hat.
+ if(obs[i]->QueryProp(P_ARMOUR_TYPE)==suche) // Gesuchter ArmourType gefunden...
+ {
+ if(suchobs[obshort]) // P_SHORT des Obj. schon im mapping?
+ {
+ if( obs[i]->QueryProp(P_AMOUNT) )
+ suchobs[obshort]+=obs[i]->QueryProp(P_AMOUNT); // Dann den Zaehler um Amount hoch!
+ else
+ suchobs[obshort]+=1; // Dann den Zaehler um 1 hoch!
+ }
+ else
+ {
+ if( obs[i]->QueryProp(P_AMOUNT) )
+ suchobs+=([obshort: obs[i]->QueryProp(P_AMOUNT)]);
+ else
+ suchobs+=([obshort: 1]);
+ }
+ }
+ }
+ strs=m_indices(suchobs);
+ if(sizeof(strs))
+ {
+ if(!alles)
+ {
+ strall+=Name(WER,1)+" enthaelt folgende "+CAP(was)+":\n";
+ strall+="------------------------------------------------------------\n";
+ }
+ else
+ strall+=ANSI_BOLD+"=== "+CAP(was)+":\n"+ANSI_NORMAL;
+ for(i=0;i<sizeof(strs);i++)
+ {
+ if(suchobs[strs[i]] > 1)
+ strall+=strs[i]+". ("+suchobs[strs[i]]+")\n";
+ else
+ strall+=strs[i]+".\n";
+ }
+ }
+ else
+ if(!alles)
+ strall+=Name(WER,1)+" enthaelt keine "+CAP(was)+"!\n";
+ return 1;
+}
+
+int auflistung(string str)
+{
+ string *strs, ob_id, was, nf_str1,nf_str2;
+ strall="";
+ nf_str1=" (Helme, Umhaenge, Ruestungen, Hosen, Schuhe, Handschuhe,\n"
+ +" Guertel, Amulette, Ringe, Koecher, Schilde, Sonstiges)\n";
+ nf_str2="Syntax: sliste [Objekt-Id] [Kleidungs-/Ruestungstyp|\"alles\"]\n"
+ +"Bsp.: sliste "+QueryProp(P_IDS)[1]+" "+"helme\n"
+ +" sliste "+QueryProp(P_IDS)[1]+" alles\n";
+ notify_fail("Fehler: Ohne Parameter klappt das nicht.\n"+nf_str2);
+ if(!str) return 0;
+ if(present(str)==TO) // Ueberpruefe, ob dieses Objekt gemeint ist!
+ {
+ write("Fehler: Es fehlt ein Kleidungs-/Ruestungstyp. Folgende Typen gibt es:\n"
+ +nf_str1+nf_str2);
+ return 1;
+ }
+ strs=old_explode(str, " ");
+ notify_fail("Fehler: Du musst eine gueltige Objekt-Id angeben!\n"
+ +nf_str2);
+ if( sizeof(strs) < 2 ) return 0; // Nur 1 Par. und der ist nicht die Objekt-Id
+ if( sizeof(strs) == 2 ) // Anzahl Par. = 2
+ {
+ ob_id=strs[0];
+ was=strs[1];
+ if( IST_ZAHL(was) ) // Objekt-Id z.B. mit "schrank 2" angesprochen?
+ if(present(ob_id+" "+was)==TO) // Falls dieses Objekt gemeint ist und kein 3. Par!
+ {
+ write("Fehler: Es fehlt ein Kleidungs-/Ruestungstyp. Folgende Typen gibt es:\n"
+ +nf_str1+nf_str2);
+ return 1;
+ }
+ else
+ return 0;
+ }
+ else if( sizeof(strs) == 3 )
+ {
+ ob_id=strs[0]+" "+strs[1];
+ was=strs[2];
+ }
+ else // Anzahl erforderlicher Parameter ueberschritten!
+ return 0;
+ if(present(ob_id)!=TO) // Ueberpruefe, ob auch dieses Objekt gemeint ist!
+ return 0;
+ if(QueryProp(P_CNT_STATUS)!=CNT_STATUS_OPEN)
+ {
+ write("Dazu muesste "+name(WER,1)+" geoeffnet sein.\n");
+ return 1;
+ }
+//--- Hier ist Parameterpruefung zu Ende.
+ was=LOWER(was);
+ if(was!="alles")
+ auflistung2(was, nf_str1, nf_str2, 0);
+ else
+ {
+ auflistung2("helme", nf_str1, nf_str2, 1);
+ auflistung2("umhaenge", nf_str1, nf_str2, 1);
+ auflistung2("ruestungen", nf_str1, nf_str2, 1);
+ auflistung2("hosen", nf_str1, nf_str2, 1);
+ auflistung2("schuhe", nf_str1, nf_str2, 1);
+ auflistung2("handschuhe", nf_str1, nf_str2, 1);
+ auflistung2("guertel", nf_str1, nf_str2, 1);
+ auflistung2("amulette", nf_str1, nf_str2, 1);
+ auflistung2("ringe", nf_str1, nf_str2, 1);
+ auflistung2("koecher", nf_str1, nf_str2, 1);
+ auflistung2("schilde", nf_str1, nf_str2, 1);
+ auflistung2("sonstiges", nf_str1, nf_str2, 1);
+ }
+ TP->More(strall);
+ return 1;
+}
diff --git a/d/seher/haeuser/moebel/kommode.c b/d/seher/haeuser/moebel/kommode.c
new file mode 100644
index 0000000..dea2b50
--- /dev/null
+++ b/d/seher/haeuser/moebel/kommode.c
@@ -0,0 +1,40 @@
+//--------------------------------------------------------------------------------
+// Name des Objects: Kommode
+// Letzte Aenderung: 17.03.2001
+// Magier: Swift
+//--------------------------------------------------------------------------------
+#pragma strong_types,rtt_checks
+
+#include "schrankladen.h"
+inherit LADEN("swift_std_container");
+
+#define VERSION_OBJ "3"
+
+protected void create()
+{
+ if (!clonep(TO)) return;
+ swift_std_container::create();
+ SetProp(P_SHORT, "Eine Kommode");
+ SetProp(P_LONG, BS(
+ "Diese robuste Kommode aus Eichenholz passt einfach in jeden Raum. "
+ +"Man kann jede Menge Zeug darin verstauen, und die vielen Schubladen "
+ +"lassen es einfach verschwinden. So ein Moebelstueck gehoert einfach "
+ +"in jedes Haus!")+"@@cnt_status@@");
+ AddId(({"kommode"}));
+ SetProp("cnt_version_obj", VERSION_OBJ);
+ SetProp(P_NAME, "Kommode");
+ SetProp(P_GENDER, FEMALE);
+ SetProp(P_WEIGHT, 5000); // Gewicht 5 Kg
+ SetProp(P_MAX_WEIGHT, 1000000); // Es passen fuer 1000 kg Sachen rein.
+ SetProp(P_WEIGHT_PERCENT, 100); // Dafuer macht er auch nix leichter :)
+ SetProp(P_MAX_OBJECTS, 100); // Mehr sollte nicht sein, lt. Tiamak.
+ SetProp(P_VALUE, 0); // Kein materieller Wert. Ist eh nicht verkaufbar.
+ SetProp(P_NOBUY, 1); // Wird im Laden zerstoert, falls er verkauft wird.
+ SetProp(P_NOGET, "Das geht nicht. "+Name(WER,1)+" haftet wie magisch am Boden.\n");
+ SetProp(P_MATERIAL, ({MAT_OAK, MAT_MISC_MAGIC}) );
+ SetProp(P_INFO, "Versuchs mal mit: \"skommandos "+QueryProp(P_IDS)[1]+"\" !\n");
+
+ AD(({"schubladen"}), BS("Es sind viele, aber zum Glueck musst Du sie nicht "
+ +"einzeln ansprechen. Du kannst einfach alles in "+name(WEN,1)+" stecken."));
+ AD(({"moebelstueck"}), BS(Name(WER,1)+" ist gemeint."));
+}
diff --git a/d/seher/haeuser/moebel/kuehlschrank.c b/d/seher/haeuser/moebel/kuehlschrank.c
new file mode 100644
index 0000000..7bf1df4
--- /dev/null
+++ b/d/seher/haeuser/moebel/kuehlschrank.c
@@ -0,0 +1,45 @@
+//--------------------------------------------------------------------------------
+// Name des Objects: Kuehlschrank
+// Letzte Aenderung: 17.03.2001
+// Magier: Swift
+//--------------------------------------------------------------------------------
+#pragma strong_types,rtt_checks
+
+#include "schrankladen.h"
+inherit LADEN("swift_std_container");
+
+#define VERSION_OBJ "3"
+
+protected void create()
+{
+ if (!clonep(TO)) return;
+ swift_std_container::create();
+ SetProp(P_SHORT, "Ein Kuehlschrank");
+ SetProp(P_LONG, BS(
+ "Dieser strahlendweisse Kuehlschrank der Firma Brosch ueberzeugt durch "
+ +"ein leises Summen von seiner Funktion, auch wenn Du nicht weisst, woher "
+ +"er den Strom dafuer nimmt. Vermutlich auf magische Weise. Aber Du kennst "
+ +"das ja, mit Magie laesst sich fast alles erklaeren. Gut dass der "
+ +"Kuehlschrank so gross ist, man koennte einen ausgewachsenen Eisbaeren "
+ +"darin unterbringen - aber der duerfte wohl was dagegen haben.")
+ +"@@cnt_status@@");
+ AddId(({"kuehlschrank", "schrank"}));
+ SetProp("cnt_version_obj", VERSION_OBJ);
+ SetProp(P_NAME, "Kuehlschrank");
+ SetProp(P_GENDER, MALE);
+ SetProp(P_WEIGHT, 5000); // Gewicht 5 Kg
+ SetProp(P_MAX_WEIGHT, 1000000); // Es passen fuer 1000 kg Sachen rein.
+ SetProp(P_WEIGHT_PERCENT, 100); // Dafuer macht er auch nix leichter :)
+ SetProp(P_MAX_OBJECTS, 100); // Mehr sollte nicht sein, lt. Tiamak.
+ SetProp(P_VALUE, 0); // Kein materieller Wert. Ist eh nicht verkaufbar.
+ SetProp(P_NOBUY, 1); // Wird im Laden zerstoert, falls er verkauft wird.
+ SetProp(P_NOGET, "Das geht nicht. "+Name(WER,1)+" haftet wie magisch am Boden.\n");
+ SetProp(P_MATERIAL, ({MAT_MISC_METAL, MAT_MISC_MAGIC}) );
+ SetProp(P_INFO, "Versuchs mal mit: \"skommandos "+QueryProp(P_IDS)[1]+"\" !\n");
+
+ AD(({"strom"}), BS("Keine Ahnung, wo "+name(WER,1)+" den hernimmt, aber "
+ +"wie gesagt, bestimmt ist Magie im Spiel."));
+
+ AddSounds(({"summen"}), BS("Das Summen des Kuehlschranks ueberzeugt Dich davon, "
+ +"dass er an ist."));
+}
diff --git a/d/seher/haeuser/moebel/lesepult.c b/d/seher/haeuser/moebel/lesepult.c
new file mode 100644
index 0000000..4eb8300
--- /dev/null
+++ b/d/seher/haeuser/moebel/lesepult.c
@@ -0,0 +1,559 @@
+// Einiger Code wurde aus dem Questtagebuch des Tempels uebernommen.
+// Da man das Buch, sobald es im aufgestellten Lesepult des Spielers
+// abgelegt wurde, auch lesen koennen muss, sind die Funktionen und
+// Details auch weiterhin sinnvoll. Kaufen kann es jeder Seher, aber
+// nutzen kann man es nur mit dem von Hels Avatar ueberreichten Buch.
+
+#include <properties.h>
+#include <moving.h>
+#include <language.h>
+#include <wizlevels.h>
+#include "/d/seher/haeuser/moebel/moebel.h"
+#include "/d/seher/haeuser/haus.h"
+#include "/d/anfaenger/ark/knochentempel/files.h"
+#pragma strong_types,rtt_checks
+
+inherit LADEN("swift_std_container");
+
+static string owner;
+string le(string key);
+string in(string key);
+int cmd_eintragen(string str);
+int cmd_lesen(string str);
+int take_page(string str);
+int drop_book(string str);
+int cmd_blaettern(string str);
+int cmd_oeffnen(string str);
+int cmd_schliessen(string str);
+void AddTheOldDetails();
+
+protected void create()
+{
+ if(!clonep(this_object()))
+ {
+ set_next_reset(-1);
+ return;
+ }
+
+ ::create();
+
+owner="Anonymus";
+
+AddDetail("finger",BS(
+"Deine Finger sollten schon vorsichtig sein, wenn sie das Zeder"+
+"nholz beruehren. Einerseits, damit Du Dich nicht verletzt, and"+
+"ererseits, damit Du nichts beschmutzt.",78));
+AddDetail(({"holz","zedernholz","zeder"}),BS(
+"Aus einem einzigen starken Stamm einer Zeder bearbeitet, ist d"+
+"ieses edle Lesepult schon etwas sehr Feines und Dekoratives.",78));
+AddDetail(({"stamm","zedernstamm","holzstamm"}),BS(
+"Der Zedernstamm ist wahrlich kunstvoll veredelt worden, sein k"+
+"raeftiges Braun wurde hervorragend zur Geltung gebracht.",78));
+AddDetail(({"braun","dunkelbraun"}),BS(
+"Der dunkelbraune Stamm glaenzt wunderschoen, wenn Licht auf ih"+
+"n faellt. Ein sehr angenehmes Holz, das fuer das Lesepult verw"+
+"endet wurde.",78));
+AddDetail("geltung",BS(
+"Ja, dieses Holz gefaellt Dir sehr, das ganze Pult ist ein beme"+
+"rkenswertes Kunstwerk.",78));
+AddDetail(({"kunst","werk","kunstwerk"}),BS(
+"Immer wieder faellt Dein bewundernder Blick auf das Lesepult.",78));
+AddDetail("blick",BS(
+"Wachsam und flink wie immer, hat er jedoch ein wenig pausiert,"+
+" indem er muessig auf dem Lesepult ruht.",78));
+AddDetail(({"feines","dekoratives"}),BS(
+"Das teilweise eckige und dann wieder sanft geschwungene, runde"+
+" Lesepult sieht schon ziemlich repraesentativ aus.",78));
+AddDetail("zeder",BS(
+"Von ihr ist nurmehr das Pult geblieben, allerdings findest Du,"+
+" dass es nicht der schlechteste Teil ist.",78));
+AddDetail("teil",BS(
+"Du siehst nur den bearbeiteten Teil der Zeder vor Dir.",78));
+AddDetail("exemplar",BS(
+"Es ist ganz klar zu sehen, dass es sich nur um eine Zeder hand"+
+"elt, aus der dieses Pult entstand.",78));
+AddDetail(({"handwerk","kunst"}),BS(
+"Tatsaechlich ist dieses Lesepult ein sehr schoenes Beispiel ho"+
+"echster handwerklicher Kunst.",78));
+AddDetail("beispiel",BS(
+"Ein weiteres steht hier dummerweise nicht herum.",78));
+
+ SetProp("cnt_version_obj","1");
+ SetProp(P_NAME,"Lesepult");
+ SetProp(P_GENDER,NEUTER);
+ SetProp(P_NEVERDROP,1);
+ SetProp(P_VALUE,10);
+ SetProp(P_WEIGHT,500000);
+ SetProp(P_NOGET,"Das Lesepult ist Dir viel zu schwer.\n");
+ SetProp(P_NOSELL,"Du behaeltst das Lesepult lieber.\n");
+ SetProp(P_MATERIAL,([MAT_CEDAR:100]));
+ SetProp(H_FURNITURE,1);
+ SetProp(P_INFO,BS(
+ "Auf dieses Lesepult kann man ein ganz bestimmtes schwarzes Bu"+
+ "ch legen. Dort liegt es perfekt, um darin zu blaettern und zu"+
+ " lesen. Ausserdem birgt es sicher noch Geheimnisse.",78));
+
+ AddId(({"pult","lesepult","\nlesepult_ark"}));
+
+ AddCmd("eintragen&quest|aufgabe|loesung|erlebnis|abenteuer",
+ #'cmd_eintragen,"Was willst Du hier denn eintragen ?\n");
+ AddCmd(({"lies","lese","les"}),#'cmd_lesen);
+ AddCmd("nimm",#'take_page);
+ AddCmd(({"lege","leg"}),#'drop_book);
+ AddCmd("blaetter|blaettre|blaettere&in&buch|tagebuch|"
+ "tempeltagebuch",#'cmd_blaettern,"Worin willst Du blaettern ?|"
+ "Willst Du im Tagebuch blaettern ?");
+ AddCmd("oeffne&@ID|buch|tagebuch|tempeltagebuch",#'cmd_oeffnen,
+ "Was willst Du oeffnen?\n");
+ AddCmd("schliesse|schliess&@ID|buch|tagebuch|tempeltagebuch",
+ #'cmd_schliessen,"Was willst Du schliessen?\n");
+
+ if (MQTBMASTER->QueryTagebuchAufPult(this_player()))
+ AddTheOldDetails();
+}
+
+void SetOwner(string str)
+{
+ owner=str;
+}
+
+string QueryOwner()
+{
+ return owner;
+}
+
+string _query_short()
+{
+ if ((owner=="Anonymus")||
+ !this_player()||
+ !(MQTBMASTER->QueryTagebuchAufPult(this_player())))
+ return "Ein wunderschoenes Lesepult aus dunkelbraunem Zedernholz";
+ if (getuid(this_player())==owner)
+ return
+ "Ein wunderschoenes Lesepult, auf dem Dein Tagebuch des Tempels ruht";
+ else return
+ "Ein wunderschoenes Lesepult, das ein gueldenes Buch traegt";
+}
+
+string _query_long()
+{
+ if ((owner=="Anonymus")||
+ !this_player()||
+ !(MQTBMASTER->QueryTagebuchAufPult(this_player())))
+ return BS(
+ "Vorsichtig faehrst Du mit den Fingern ueber das dunkelbraune Holz."+
+ " Was Du spuerst, fuehlt sich kuehl und angenehm an, die Zeder, die"+
+ " fuer dieses bestaunenswerte Lesepult herhalten musste, wurde vors"+
+ "ichtig und aeusserst kunstfertig bearbeitet. Ein wirklich schoenes"+
+ " Exemplar holzhandwerklicher Kunst.",78);
+ if (getuid(this_player())==owner)
+ {
+ if (MQTBMASTER->QueryTagebuchAufPult(this_player()))
+ return BS(
+ "Vorsichtig faehrst Du mit den Fingern ueber das dunkelbraune Holz"+
+ ". Was Du spuerst, fuehlt sich kuehl und angenehm an, die Zeder, d"+
+ "ie fuer dieses bestaunenswerte Lesepult herhalten musste, wurde v"+
+ "orsichtig und aeusserst kunstfertig bearbeitet. Ein wirklich scho"+
+ "enes Exemplar holzhandwerklicher Kunst, Du bist froh, dieses Lese"+
+ "pult erstanden zu haben. Auf dem Lesepult siehst Du Dein schwarze"+
+ "s Tagebuch des Knochentempels, in dem Du nun nur noch lesen kanns"+
+ "t, denn Deine Abenteuer dort sind vollstaendig zu Papier gebracht"+
+ ". Allerdings kannst Du auch noch ein wenig weiter drin herumblaet"+
+ "tern, wenn Du magst.",78);
+ return BS(
+ "Vorsichtig faehrst Du mit den Fingern ueber das dunkelbraune Holz"+
+ ". Was Du spuerst, fuehlt sich kuehl und angenehm an, die Zeder, d"+
+ "ie fuer dieses bestaunenswerte Lesepult herhalten musste, wurde v"+
+ "orsichtig und aeusserst kunstfertig bearbeitet. Ein wirklich scho"+
+ "enes Exemplar holzhandwerklicher Kunst, Du bist froh, dieses Lese"+
+ "pult erstanden zu haben. Ein wenig gruebeln laesst Dich die Tatsa"+
+ "che, dass das Lesepult leer ist. Was man dort wohl platzieren kan"+
+ "n ?",78);
+ }
+ return BS(
+ "Vorsichtig faehrst Du mit den Fingern ueber das dunkelbraune Holz."+
+ ". Was Du spuerst, fuehlt sich kuehl und angenehm an, die Zeder, di"+
+ "e fuer dieses bestaunenswerte Lesepult herhalten musste, wurde vor"+
+ "sichtig und aeusserst kunstfertig bearbeitet. Ein wirklich schoene"+
+ "s Exemplar holzhandwerklicher Kunst, Du bist ein wenig neidisch."+
+ ""+(MQTBMASTER->QueryTagebuchAufPult(this_player())?" Auf dem Lesep"+
+ "ult wurde ein schwarzes Buch abgelegt, das sehr wertvoll aussieht.":
+ " Das Lesepult sieht ohne dazugehoeriges Buch ein wenig einsam aus.")+".",78);
+}
+
+void AddTheOldDetails()
+{
+ AddDetail(({"buch","buechlein","tagebuch"}),BS(
+ "Dies ist ein kleines Buechlein aus Gold, auf dem ein Name in "+
+ "schwarzen Lettern steht. Ansonsten ist der Einband schlicht, "+
+ "das Papier schon ausfuehrlich beschrieben und vom vielen Blae"+
+ "ttern hier und da auch schon ein wenig geknickt.",78));
+ AddDetail("blaettern",BS(
+ "Ja, das schoene Buechlein ist von haeufigem Blaettern nicht s"+
+ "choener geworden, aber irgendetwas Magisches hat es schon an "+
+ "sich. Ab und an magst Du immer wieder einmal herumblaettern.",78));
+ AddDetail("magisches",BS(
+ "Es ist nicht so einfach zu ergruenden, indem man einmal genau"+
+ "er hinsieht.",78));
+ AddDetail("leder",BS(
+ "Das Leder ist glatt und vollkommen guelden. Nur die schwarzen"+
+ " Lettern geben einen angenehmen Kontrast ab. Irgendwie seltsa"+
+ "m, denn Du findest, dass Schwarz und Gold eigentlich umgekehr"+
+ "t mehr Sinn machen.",78));
+ AddDetail("sinn",BS(
+ "Vielleicht ist aber auch alles bestens, und nur Dein Verstand"+
+ " will das nicht nachvollziehen.",78));
+ AddDetail("verstand",BS(
+ "Ja, auch Du kannst ihm nicht immer folgen, also wundere Dich "+
+ "nicht, warum dieses Leder hier golden verfaerbt ist und die B"+
+ "uchstaben darauf schwarz.",78));
+ AddDetail(({"lettern","buchstaben"}),BS(
+ "Du kannst sie lesen.",78));
+ AddDetail(({"name","namen"}),BS(
+ "Man kann ihn genauso lesen wie die Buchstaben.",78));
+ AddDetail("kontrast",BS(
+ "Die Buchstaben heben sich wirklich deutlich vom gueldenen Led"+
+ "er des Einbands ab.",78));
+ AddDetail("einband",BS(
+ "Es ist kein aufwaendiger Einband, fuerwahr. Dennoch faszinier"+
+ "t die Pracht, die mit den schwarzen Lettern kontrastiert.",78));
+ AddDetail("pracht",BS(
+ "So muss man den goldenen Einband wohl nennen.",78));
+ AddDetail(({"papier","seiten","buchseiten","seite","buchseite"}),BS(
+ "Das Papier ist von guter Qualitaet, die Buchseiten lassen sic"+
+ "h sicher einfach beschreiben.",78));
+ AddDetail(({"schwarze buchseiten","schwarze buchseite",
+ "schwarze buchseite"}),BS(
+ "Tatsaechlich, beim Blaettern siehst Du einige schwarze Buchse"+
+ "iten, die unbeschrieben sind. Was hat dies zu bedeuten ?",78));
+ AddDetail("qualitaet",BS(
+ "Du siehst, dass das Papier fest und bluetenweiss ist.",78));
+ AddReadDetail(({"buch","buechlein","tagebuch"}),BS(
+ "Das Buch hat ein Inhaltsverzeichnis. Wenn dort etwas steht, k"+
+ "annst Du das oder die Kapitel sicher lesen.",78));
+ AddDetail("kapitel",BS(
+ "Lies nur im Inhaltsverzeichnis nach, vielleicht hat das Buch "+
+ "bereits ein oder mehrere Kapitel.",78));
+ AddReadDetail("kapitel",BS(
+ "Welches Kapitel willst Du denn lesen ? Sie sind sicher durchn"+
+ "ummeriert, wenn man schon etwas im Buch niedergeschrieben hat.",78));
+ AddReadDetail(({"name","namen","buchstaben","lettern"}),#'le);
+ AddReadDetail(({"inhalt","inhaltsverzeichnis"}),#'in);
+ SetProp(P_MATERIAL,([MAT_LEATHER:10,MAT_PAPER:15,MAT_CEDAR:75]));
+}
+
+int drop_book(string str)
+{
+ if (!stringp(str))
+ return 0;
+ if (strstr(lower_case(str),"pult",0)==-1)
+ return 0;
+ notify_fail(BS(
+ "Willst Du etwas auf das Pult legen ? Ein Buch waere passend, "+
+ "aber es sollte schon etwas Besonderes sein.",78));
+ if (strstr(lower_case(str),"buch",0)==-1&&
+ strstr(lower_case(str),"buechlein",0)==-1)
+ return 0;
+ notify_fail(BS(
+ "Das ist nicht Dein Lesepult, Du laesst es besser in Ruhe.",78));
+ if (getuid(this_player())!=owner)
+ return 0;
+ notify_fail(BS(
+ "Auf dem Pult liegt schon ein goldenes Buch.",78));
+ if (MQTBMASTER->QueryTagebuchAufPult(this_player()))
+ return 0;
+ notify_fail(BS(
+ "Entweder hast Du Dich noch nicht als wuerdig erwiesen, indem "+
+ "Du alle Aufgaben im Knochentempel erfuellt hast oder Du hast "+
+ "dem Avatar des Waechters der Nacht, Mhun'dae Hel, noch nicht "+
+ "Deine Aufwartung gemacht und ihm gezeigt, dass Du wuerdig bis"+
+ "t, ein geeignetes Buch zu empfangen. Auf alle Faelle kannst D"+
+ "u hier noch nichts auf das Pult legen.",78));
+ if (!present_clone(OBJ("buechlein_invers"),this_player()))
+ return 0;
+ MQTBMASTER->AddBuchAufPult(this_player());
+ this_player()->ReceiveMsg(BS(
+ "Vorsichtig schlaegst Du Dein gueldenes Tagebuch auf, das Dir "+
+ "Mhun'dae Hel, das Avatar des Waechters der Nacht, ueberreicht"+
+ " hat. Du legst es sachte auf das Pult und merkst, dass es sof"+
+ "ort eine magische Verbindung mit dem Lesepult eingeht. Es ist"+
+ " nun untrennbar mit diesem verbunden.",78),MT_MAGIC,MA_USE);
+ tell_room(environment(),BS(
+ this_player()->Name(WER)+" legt vorsichtig ein gueldenes Buch "+
+ "mit schwarzen Lettern aufgeschlagen auf dem Lesepult ab und b"+
+ "etrachtet dieses dann ehrfuerchtig und zutiefst zufrieden.",78),
+ ({this_player()}));
+ return 1;
+}
+
+int cmd_blaettern(string str)
+{
+ notify_fail(BS(
+ "Auf dem Lesepult liegt doch gar kein Tagebuch.",78));
+ if (!(MQTBMASTER->QueryTagebuchAufPult(find_player(owner))))
+ return 0;
+ notify_fail(BS(
+ "Das ist nicht Dein Tagebuch, Du laesst es lieber in Frieden.",78));
+ if (getuid(this_player())!=owner)
+ return 0;
+ this_player()->ReceiveMsg(BS(
+ "Du blaetterst ein wenig durch Dein Tagebuch und stoesst auf e"+
+ "inige raetselhafte schwarze Seiten. Was mag es damit auf sich"+
+ " haben ? Ob Du sie herausnehmen kannst ?",78),MT_LOOK,MA_LOOK);
+ return 1;
+}
+
+int take_page(string str)
+{
+ if (!stringp(str))
+ return 0;
+ if (present(str,environment()))
+ return 0;
+ notify_fail(BS(
+ "Wo siehst Du denn hier ein Buch ?",78));
+ if (!(MQTBMASTER->QueryTagebuchAufPult(this_player()))&&
+ strstr(lower_case(str),"buch")!=-1)
+ return 0;
+ if ((owner!=getuid(this_player()))&&
+ strstr(lower_case(str),"buch")!=-1)
+ notify_fail(BS(
+ "Dies ist nicht Dein Lesepult oder Dein Buch darauf, deshalb l"+
+ "aesst Du es vorsichtshalber liegen.",78));
+ return 0;
+ if ((owner!=getuid(this_player()))&&
+ strstr(lower_case(str),"seite")!=-1)
+ notify_fail(BS(
+ "Die Eigentuemerin oder der Eigentuemer des Lesepults haette s"+
+ "icher etwas dagegen, wenn Du das Buch zerstoerst, also laesst"+
+ " Du es lieber.",78));
+ return 0;
+ // Heilung 1x alle 6 Stunden.
+ if (this_player()->check_and_update_timed_key(21600,"Ark_Hels_Schwarzes_Buch")==-1)
+ {
+ object o;
+ this_player()->ReceiveMsg(BS(
+ "Du reisst erst vorsichtig eine schwarze Seite und dann eine"+
+ " weitere aus dem goldenen Buch. Dann ueberfaellt Dich eine "+
+ "kleine Schwaeche, die Dich vor weiterem Zerstoeren innehalt"+
+ "en laesst. Du solltest Hels Grosszuegigkeit nicht ueberscha"+
+ "etzen.",78),MT_FEEL,MA_TAKE);
+ tell_room(environment(),BS(
+ this_player()->Name(WER)+" reisst zwei Seiten aus dem Buch, "+
+ "das auf dem Pult liegt. Dann haelt "+this_player()->QueryPronoun(WER)+""+
+ " inne, wahrscheinlich folgt "+this_player()->QueryPronoun(WER)+""+
+ " einer klugen Eingebung.",78));
+ o=clone_object(OBJ("reg_seite"));
+ if (o->move(this_player())!=MOVE_OK)
+ {
+ o->remove(1);
+ this_player()->ReceiveMsg(BS(
+ "Du kannst die erste Seite nicht mehr tragen, sie loest sic"+
+ "h einfach auf.",78),MT_MAGIC,MA_REMOVE);
+ }
+ // Die erste Seite behandelt, hier, falls man auch die zweite
+ // Seite nicht tragen kann oder mit der ersten am Limit ist.
+ o=clone_object(OBJ("reg_seite"));
+ if (o->move(this_player())!=MOVE_OK)
+ {
+ o->remove(1);
+ this_player()->ReceiveMsg(BS(
+ "Du kannst die zweite Seite nicht mehr tragen, sie loest si"+
+ "ch einfach auf.",78),MT_MAGIC,MA_REMOVE);
+ }
+ return 1;
+ }
+ this_player()->ReceiveMsg(BS(
+ "Vergeblich reisst Du mehr oder weniger vorsichtig an einigen"+
+ " schwarzen Seiten im Buch herum, doch sie bleiben stoerrisch"+
+ ". Es wird wohl ein wenig dauern, bis Du das wieder versuchen"+
+ " kannst.",78),MT_MAGIC,MA_USE);
+ tell_room(environment(),BS(
+ this_player()->Name(WER)+" reisst im Buch auf dem Lesepult he"+
+ "rum.",78),({this_player()}));
+ return 1;
+}
+
+int cmd_lesen(string str)
+{
+int k;
+ if(!str) return 0;
+ if (owner=="Anonymus")
+ {
+ write (BS(
+ "Dieses Lesepult scheint niemandem zu gehoeren ... es loest s"+
+ "ich daher einfach auf, als Du darauf etwas lesen willst.",78));
+ remove(1);
+ return 1;
+ }
+ if (getuid(this_player())!=owner)
+ {
+ notify_fail(BS(
+ "Dieses Tagebuch gehoert "+capitalize(owner)+", nicht Dir, Du"+
+ " bist eigentlich nicht so recht an dem interessiert, was man"+
+ " in dem Buch niedergeschrieben hat. Sicher ist es uebertrieb"+
+ "en langatmig formuliert und stimmt nicht genau mit dem ueber"+
+ "ein, was wirklich geschah. Man kennt das ja.",78));
+ return 0;
+ }
+ if (strstr(lower_case(str),"kapitel",0)!=-1&&
+ sscanf(lower_case(str),"kapitel %d",k)!=1)
+ {
+ write (BS(
+ "Willst Du ein Kapitel aus dem Buch lesen ? Dann gib bitte ei"+
+ "ne Ziffer an.",78));
+ return 1;
+ }
+ if (k>0)
+ {
+ MQTBMASTER->LiesQuest(k,this_player());
+ return 1;
+ }
+ return 0;
+}
+
+int cmd_eintragen(string str)
+{
+int i;
+ if (!(MQTBMASTER->QueryTagebuchAufPult(this_player())))
+ {
+ notify_fail(BS(
+ "Du findest hier nichts, worin Du etwas eintragen koenntest.",78));
+ return 0;
+ }
+ if (getuid(this_player())!=owner)
+ {
+ notify_fail(BS(
+ "Dieses Tagebuch gehoert "+capitalize(owner)+", nicht Dir, Du"+
+ " kannst darin nichts eintragen.",78));
+ return 0;
+ }
+ notify_fail(BS(
+ "Deine Missionen im Knochentempel ... besser gesagt, dem Wyrmt"+
+ "empel, sie sind allesamt tapfer von Dir erfuellt worden. Du k"+
+ "annst hier nichts weiter mehr eintragen, sicher aber von der "+
+ "arkanen Macht des Buches profitieren, wenn Du es einmal durch"+
+ "blaetterst.",78));
+ return 0;
+}
+
+string calc_name()
+{
+string *nam;
+string res;
+int i,j;
+ res="";
+ if (owner=="")
+ return "";
+ nam=explode(upperstring(owner),"");
+ if (j=sizeof(nam))
+ {
+ switch(j)
+ {
+ case 3..4:
+ res=" ";
+ break;
+ case 5:
+ res=" ";
+ break;
+ case 7:
+ res=" ";
+ break;
+ case 9:
+ res=" ";
+ break;
+ default:
+ res=" ";
+ }
+ for (i=0;i<j;i++)
+ {
+ res+=nam[i]+" ";
+ }
+ }
+ return res;
+}
+
+string le(string key)
+{
+ return "\n"+
+ " De Templum Os Hel\n\n"+
+ calc_name()+"\n\n";
+}
+
+string in(string key)
+{
+ if (owner!=getuid(this_player()))
+ return "Dort steht allerdings nichts. Seltsam.\n";
+ return MQTBMASTER->LiesInhalt(find_player(owner));
+}
+
+// Das hier bezeichnet den Urheber des Moebelstuecks.
+// Nicht meine Idee!
+string GetOwner() { return "Ark"; }
+
+int cmd_oeffnen(string str)
+{
+ if (strstr(lower_case(str),"pult")!=-1)
+ {
+ this_player()->ReceiveMsg(
+ "Du kannst das Pult nicht oeffnen, nur etwas zum Lesen darauflegen.",
+ MT_LOOK,MA_FEEL);
+ return 1;
+ }
+ if (strstr(lower_case(str),"buch")!=-1)
+ {
+ if (!(MQTBMASTER->QueryTagebuchAufPult(this_player())))
+ return 0;
+ this_player()->ReceiveMsg(
+ "Das schwarze Buch ist doch schon geoeffnet.",MT_LOOK,MA_FEEL);
+ return 1;
+ }
+ // Alles andere per Default.
+ return 0;
+}
+
+int cmd_schliessen(string str)
+{
+ if (strstr(lower_case(str),"pult")!=-1)
+ {
+ this_player()->ReceiveMsg(
+ "Du kannst das Pult nicht schliessen.",MT_LOOK,MA_FEEL);
+ return 1;
+ }
+ if (strstr(lower_case(str),"buch")!=-1)
+ {
+ if (!(MQTBMASTER->QueryTagebuchAufPult(this_player())))
+ return 0;
+ this_player()->ReceiveMsg(
+ "Das Buch bleibt trotz Deiner Bemuehungen einfach offen.",MT_LOOK,MA_FEEL);
+ return 1;
+ }
+ else return 0;
+}
+
+mixed _query_noget()
+{
+ if (getuid(this_player())!=owner)
+ return BS(
+ "Dies ist offensichtlich nicht Dein Pult, deshalb laesst "+
+ "Du es auch besser liegen.",78);
+ return 0;
+}
+
+string _query_autoloadobj()
+{
+ return QueryOwner();
+}
+
+string _set_autoloadobj(string s)
+{
+ return QueryOwner();
+}
+
+// Beim Kauf setzen wir erstmal nur den Eigentuemer.
+// Ist aus Swifts Container, der diese Funktion im
+// NotifyMove() aufruft.
+protected void SetBesitzer(string uid, string uuid)
+{
+ SetOwner(uid);
+ MQTBMASTER->AddLesepult(find_player(uid)||find_netdead(uid));
+}
diff --git a/d/seher/haeuser/moebel/moebel.h b/d/seher/haeuser/moebel/moebel.h
new file mode 100644
index 0000000..debc474
--- /dev/null
+++ b/d/seher/haeuser/moebel/moebel.h
@@ -0,0 +1,13 @@
+#ifndef _SEHERMOEBEL_H_
+#define _SEHERMOEBEL_H_
+
+#define LADEN(x) "/d/seher/haeuser/moebel/"+x
+#define RAUM_VOR_LADEN "/d/unterwelt/wurzel/dorf/nstr2"
+#define IDEEN_LOG "ideen.log"
+#define SHVERWALTER "/d/seher/haeuser/hausverwalter"
+#define VERANTWORTLICHER_MAGIER "Seleven"
+// Der Erhaelt Bug-Mails der Spieler!
+#define SCHRANKMASTER load_object(LADEN("schrankmaster"))
+
+#endif // _SEHERMOEBEL_H_
+
diff --git a/d/seher/haeuser/moebel/muellcontainer.c b/d/seher/haeuser/moebel/muellcontainer.c
new file mode 100644
index 0000000..1e95d18
--- /dev/null
+++ b/d/seher/haeuser/moebel/muellcontainer.c
@@ -0,0 +1,92 @@
+//--------------------------------------------------------------------------------
+// Name des Objects: Muellcontainer
+// Letzte Aenderung: 17.03.2001
+// Magier: Swift
+//--------------------------------------------------------------------------------
+
+#include "schrankladen.h"
+inherit LADEN("swift_std_container");
+
+#define VERSION_OBJ ".003"
+
+create()
+{
+ if (!clonep(TO)) return;
+ swift_std_container::create();
+ SetProp(P_SHORT, "Ein Muellcontainer");
+ SetProp(P_LONG, BS(
+ "Ein grosser Container aus Stahl, aus dem es nicht gerade angenehm duftet. "
+ +"Offensichtlich werden dort alle Sachen entsorgt, die Seher nicht gerne in "
+ +"ihrem Haus oder auf der Strasse herumliegen sehen.")
+ +"@@cnt_status@@");
+ AddId(({"muellcontainer", "container"}));
+ SetProp("cnt_version_obj", VERSION_OBJ);
+ SetProp(P_NAME, "Muellcontainer");
+ SetProp(P_GENDER, MALE);
+ SetProp(P_WEIGHT, 5000); // Gewicht 5 Kg
+ SetProp(P_MAX_WEIGHT, 1000000); // Es passen fuer 1000 kg Sachen rein.
+ SetProp(P_WEIGHT_PERCENT, 100); // Dafuer macht er auch nix leichter :)
+ SetProp(P_MAX_OBJECTS, 100); // Mehr sollte nicht sein, lt. Tiamak.
+ SetProp(P_VALUE, 0); // Kein materieller Wert. Ist eh nicht verkaufbar.
+ SetProp(P_NOBUY, 1); // Wird im Laden zerstoert, falls er verkauft wird.
+ SetProp(P_NOGET, "Das geht nicht. "+Name(WER,1)+" haftet wie magisch am Boden.\n");
+ SetProp(P_MATERIAL, ({MAT_STEEL, MAT_MISC_MAGIC}) );
+ SetProp(P_INFO, "Versuchs mal mit: \"skommandos "+QueryProp(P_IDS)[1]+"\" !\n");
+
+ AddSmells(({"container", "duft", "gestank"}), BS("Aus "+name(WEM,1)+" stinkt es "
+ +"schon ganz schoen, aber Deine Nase ist ja allerhand gewoehnt."));
+
+ AddCmd(({"wirf", "werf", "werfe"}), "wegwerfen");
+}
+
+int wegwerfen(string str)
+{
+ string was,inwas;
+ notify_fail("Was willst Du wo hinein werfen?\n");
+ if(!str) return 0;
+ if( sscanf(str, "%s in %s", was, inwas) != 2)
+ return 0;
+ if( present(inwas)==TO ) // Dies Objekt ist gemeint!
+ {
+ TP->command_me("stecke "+str);
+ return 1;
+ }
+ return 0;
+}
+
+varargs int PreventInsert(object ob)
+{
+ if( living(ob) )
+ {
+ write( BS("Lebewesen kannst Du nicht in "+name(WEN,1)+" werfen!"));
+ return 1;
+ }
+ else if( ob->QueryProp(P_VALUE) )
+ {
+ write( BS("Nur Dinge ohne materiellen Wert lassen sich in "
+ +name(WEN,1)+" werfen."));
+ return 1;
+ }
+ else if( ob->QueryProp(P_CURSED) )
+ {
+ write( BS("Verfluchte Dinge kannst Du nicht in "+name(WEN,1)+" werfen!"));
+ return 1;
+ }
+ else
+ return ::PreventInsert(ob);
+}
+
+void reset()
+{
+ int i;
+ object *inv;
+ ::reset();
+ inv=all_inventory(TO);
+ if(inv && sizeof(inv))
+ {
+ for(i=sizeof(inv)-1;i>=0;i--)
+ destruct(inv[i]);
+ tell_room(ETO, BS("Aus "+name(WEM,1)+" ertoent kurz ein Knistern und Knacken, "
+ +"dann ist wieder Ruhe."));
+ }
+}
diff --git a/d/seher/haeuser/moebel/preisliste.txt b/d/seher/haeuser/moebel/preisliste.txt
new file mode 100644
index 0000000..05e7839
--- /dev/null
+++ b/d/seher/haeuser/moebel/preisliste.txt
@@ -0,0 +1,102 @@
+
+=====================================================
+D E R S C H R A E N K E R - P R E I S L I S T E
+=====================================================
+
+Herzlich willkommen im SCHRAENKER. Bei uns finden Sie
+das ideale Mobiliar fuer Ihr Seherhaus. Weg mit der
+Unordnung zuhaus, bringen Sie ihre Ausruestung ueber-
+sichtlich und wohlsortiert in unseren edlen Moebel-
+stuecken unter. Wir hoffen, unsere Auswahl findet
+Ihren Gefallen.
+
+ANMERKUNG: Die Waren, die hier aufgelistet sind, sind NICHT REBOOTFEST !
+ Evtl. werden wir dies zu einem spaeteren Zeitpunkt ins Auge
+ fassen, im Moment ist es nicht so, wir versuchen lieber, die
+ Moebelstuecke zu verbessern, um sie auch an die ungewoehnlichsten
+ Objekte im MorgenGrauen anzupassen.
+
+Art.-Nr. Name Beschreibung Preis
+-----------------------------------------------------------------------------
+ 1 Kommode Eine robuste Kommode aus Eichenholz. Sie 3.799
+ passt in jeden Raum und bietet jede Menge
+ Platz zum Verstauen von Dingen aller Art.
+
+ 2 Kleiderschrank Ein massiver Holzschrank, in dem Sie 5.899
+ Kleider und Ruestungen aller Art unter-
+ bringen koennen. Der Schrank verfuegt
+ ueber ein Kommando zur Auflistung von
+ Ruestungstypen.
+
+ 3 Spind Ein grosser, einfacher Stahlschrank. Darin 5.299
+ lassen sich Kleider und Ruestungen aller
+ Art unterbringen. Der Spind verfuegt ueber
+ ein Kommando zur Auflistung von Ruestungs-
+ typen.
+
+ 4 Kuehlschrank Ein strahlendweisser Kuehlschrank aus dem 3.499
+ Hause Brosch. Passt in jede Kueche. Darin
+ bleiben Ihre Speisen und Getraenke frisch!
+
+ 5 Waffenschrank Ein massiver Holzschrank mit Faechern fuer 5.899
+ Waffen aller Art. Jede Waffengattung hat
+ ihren einenen Platz, es gibt ein Kommando
+ zur Auflistung von Waffentypen.
+
+ 6 Waffentruhe Eine Stahltruhe mit verschiedenen Faechern 5.399
+ zur Aufnahme von Waffen aller Art. Die
+ Truhe verfuegt ueber ein Kommando zur
+ Auflistung von Waffentypen.
+
+ 7 Tresor Sichern Sie Ihr Vermoegen gegen Einbruch 4.499
+ und Diebstahl. Wie? Ganz einfach: Mit
+ diesem stabilen, feuersicheren Tresor
+ sind Ihre Wertsachen sicher.
+
+ 8 Zauberkiste Sind Sie Zauberer? Oder einfach nur Sammler 7.999
+ hier von Zauberer-Komponenten? Dann haben
+ wir ein Moebelstueck fuer Sie, das Sie haben
+ muessen! Aus magischem Birnbaumholz gefertigt.
+
+ 9 Muellcontainer Der Ersatz fuer den Muellschlucker. 999
+ Nie mehr brauchen Sie einen Laden aufsuchen,
+ nur um wertlosen Plunder loszuwerden.
+
+10 Schluesselbrett Sie haben durch Ihre Abenteuer einen Sack 499
+ voll Schluessel? Dieses Brett schafft
+ Ordnung.
+
+11 Duschkabine Endlich auch fuer Ihr Zuhause: 3.499
+ Eine ultramoderne Waschgelegenheit. Sie
+ koennen sogar selbst einstellen, womit Sie
+ Sich waschen wollen!
+
+12 mag. Holztruhe Haben auch Sie Probleme mit einem ueber- 74.999
+ vollen Inventar? Wir haben jetzt die
+ Loesung fuer Sie: diese kleine Holztruhe
+ nimmt ihre ewigen Objekte auf und
+ bewahrt sie sicher ueber den naechsten
+ Weltuntergang hinaus auf!
+
+13 Vitrine Gehoeren Sie auch zu den tapferen Helden, 49.999
+ die sich bereits Pokale verdient haben?
+ Dann sollten Sie sich diese Vitrine
+ zulegen, damit Ihre Pokale eine passende
+ Umgebung erhalten und auch beim Welt-
+ untergang geschuetzt sind.
+
+14 Lesepult Das hat man sich redlich verdient! Eine 60.000
+ schoene Belohnung, wenn man schliesslich
+ den knoechernen Tempel mal so richtig
+ aufgeraeumt hat. Und zwar vollstaendig,
+ so dass selbst der Totengott staunt.
+ Endlich koennen Sie, wenn er es denn dann
+ auch zufrieden ist, das Tagebuch hierauf
+ ablegen und in aller Ruhe blaettern.
+-----------------------------------------------------------------------------
+Anm. der Geschaeftsleitung:
+Wir bemuehen uns, Ihrem Geschmack und Ihren Beduerfnissen gerecht zu werden.
+Falls Sie Verbesserungsvorschlaege haben, oder falls Sie Moebelstuecke fuer Ihr
+Haus in unserem Angebot vermissen, so setzen Sie doch bitte eine entsprechende
+Idee im Laden ab.
+-----------------------------------------------------------------------------
diff --git a/d/seher/haeuser/moebel/schluesselbrett.c b/d/seher/haeuser/moebel/schluesselbrett.c
new file mode 100644
index 0000000..93bace6
--- /dev/null
+++ b/d/seher/haeuser/moebel/schluesselbrett.c
@@ -0,0 +1,679 @@
+//---------------------------------------------------------------------------
+// Name des Objects: Schluesselbrett
+// Letzte Aenderung: 02.06.2001
+// Original: Swift
+// Neue Version: Seleven
+// Übernommen: 23.01.2006
+//---------------------------------------------------------------------------
+/* Changelog
+ * 21.06.2007, Zesstra
+ im inherit abs. Pfad durch LADEN(x) ersetzt.
+ * 01.07.2007, Zesstra
+ GetOwner() definiert.
+ * 11.05.2015, Arathorn
+ weitraeumig ueberarbeitet zur Behebung von Fehlfunktionen
+*/
+#pragma strong_types, rtt_checks
+
+#include "/d/seher/haeuser/moebel/schrankladen.h"
+#include <ansi.h>
+inherit LADEN("swift_std_container");
+
+#define VERSION_OBJ "3"
+// Zur Indizierung des Mappings <haken>
+#define HOOK_OB 0
+#define HOOK_LABEL 1
+
+private varargs string KeyDescription(int keynum);
+private int IsValidKey(object ob);
+private int GetNextFreeSlot();
+private object GetKeyForLabel(string label);
+private int GetHookNumberForKey(object ob);
+private void ConsolidateInventory();
+
+// Struktur: ([ haken_nr : objekt; beschriftung ])
+private mapping haken=([:2]);
+private int hooklist_long = 0;
+
+protected void create() {
+ if (!clonep(TO)) {
+ set_next_reset(-1);
+ return;
+ }
+ ::create();
+
+ foreach(int i: 1..16) {
+ m_add(haken, i);
+ }
+
+ // DEBUG! Sonst funktioniert's ausserhalb von Seherhaeusern nicht.
+ SetProp("test",1);
+ SetProp(P_SHORT, "Ein Schluesselbrett");
+ Set(P_LONG, function string () {
+ string text = BS(
+ "Ein kleines Brett aus Holz, an dem in 2 Reihen je 8 Haken befestigt "
+ "sind, an die man insgesamt 16 Schluessel haengen kann. Um die "
+ "Uebersicht nicht zu verlieren, befindet sich ueber jedem der Haken "
+ "ein kleines Schildchen aus Schiefer, das sich beschriften laesst. "
+ "Auf diese Weise geht der Sinn und Zweck des Schluessels, der an "
+ "diesem Haken ruht, nicht verloren. Praktischerweise haengt an einer "
+ "Schnur ein Stueck Kreide von dem Brett herab, mit dem Du die "
+ "Schildchen beschriften kannst.");
+ text += KeyDescription(0);
+ return text;
+ }, F_QUERY_METHOD);
+
+ AddId(({"schluesselbrett","brett"}));
+ SetProp("cnt_version_obj", VERSION_OBJ);
+ SetProp(P_CNT_STATUS, 0);
+ SetProp(P_NAME, "Schluesselbrett");
+ SetProp(P_GENDER, NEUTER);
+ SetProp(P_WEIGHT, 1000); // Gewicht 1 Kg
+ SetProp(P_MAX_WEIGHT, 1000000); // Es passen fuer 1000 kg Sachen rein.
+ SetProp(P_WEIGHT_PERCENT, 100); // Dafuer macht er auch nix leichter :)
+ SetProp(P_MAX_OBJECTS, 16);
+ // Man soll nichts ueber den normalen Mechanismus reinstecken oder
+ // rausnehmen koennen. Wird von put_and_get.c geprueft.
+ SetProp(P_CONTAINER, 0);
+ SetProp(P_NOINSERT_MSG, BS("An das Schluesselbrett kannst Du nur "
+ "Schluessel haengen.\nSyntax: 'haenge <schluessel> an brett'."));
+ SetProp(P_NOGET, "Das geht nicht. "+Name(WER,1)+
+ " laesst sich nicht bewegen.\n");
+ SetProp(P_MATERIAL, ({MAT_OAK, MAT_MISC_MAGIC}) );
+ SetProp(P_INFO, "Versuch's mal mit: \"skommandos schluesselbrett\".\n");
+
+ AD(({"holz"}), BS("Echte, robuste Eiche."));
+
+ RemoveCmd(({"schliesse","schliess","oeffne"}));
+
+ AddCmd(({"unt", "untersuche", "betrachte", "betracht", "betr",
+ "schaue", "schau"}), "unt_haken");
+ AddCmd(({"haeng", "haenge"}), "schluessel_an_haken_haengen");
+ AddCmd(({"nimm"}), "schluessel_von_haken_nehmen");
+ AddCmd("sbeschrifte", "cmd_beschriften");
+ AddCmd("sliste", "cmd_sliste");
+}
+
+/***** KOMMANDOFUNKTIONEN *****/
+
+// Konfiguration der Schluesselliste, entweder "alle" anzeigen oder nur die
+// belegten Haken.
+static int cmd_sliste(string str) {
+ notify_fail("Syntax: 'sliste alle|belegte'.\n");
+ if ( !stringp(str) || !sizeof(str) )
+ return 0;
+
+ if ( str == "alle" ) {
+ if ( !hooklist_long ) {
+ tell_object(TP, BS("Ok, es werden jetzt immer alle Haken "
+ "aufgelistet."));
+ hooklist_long = 1;
+ }
+ else
+ tell_object(TP, BS("Die Einstellung war schon 'alle'."));
+ }
+ else if ( str == "belegte" ) {
+ if ( hooklist_long ) {
+ tell_object(TP, BS("Ok, es werden jetzt nur die belegten Haken "
+ "aufgelistet."));
+ hooklist_long =0;
+ }
+ else
+ tell_object(TP, BS("Die Einstellung war schon 'belegte'."));
+ }
+ else
+ return 0;
+ return 1;
+}
+
+// Haken untersuchen. Ohne Angabe der Nummer werden alle ausgegeben,
+// ansonsten der gewuenschte, sofern es diesen gibt.
+static int unt_haken(string str) {
+ if ( !stringp(str) || !sizeof(str) || strstr(str, "haken") == -1 )
+ return 0;
+
+ int hakennr;
+ if ( sscanf(str, "haken %d", hakennr) != 1 ) {
+ string det = KeyDescription(hakennr);
+ tell_object(TP, sizeof(det) ? det : "Die Haken sind alle leer.\n");
+ return 1;
+ }
+
+ notify_fail("Welchen Haken moechtest Du untersuchen? Es gibt nur die "
+ "Haken 1 bis 16.\n");
+ if( hakennr<1 || hakennr > 16 )
+ return 0;
+
+// ausgabe_haken(hakennr);
+ tell_object(TP, KeyDescription(hakennr));
+ return 1;
+}
+
+// Schluessel aufhaengen.
+static int schluessel_an_haken_haengen(string str) {
+ notify_fail("Was willst Du woran haengen?\n");
+ if(!stringp(str) || !sizeof(str))
+ return 0;
+
+ notify_fail("Das darfst Du nicht.\n");
+ if(!erlaubt())
+ return 0;
+
+ string was, woran;
+ notify_fail("Folgende Syntax versteht Dein Schluesselbrett:\n"
+ " \"haenge <schluesselname> an haken [nr]\" oder\n"
+ " \"haenge <schluesselname> an [schluessel]brett\".\n");
+ if ( sscanf(str, "%s an %s", was, woran) != 2 )
+ return 0;
+
+ notify_fail("Was moechtest Du an das Schluesselbrett haengen?\n");
+ if ( !stringp(was) )
+ return 0;
+
+ notify_fail("Woran willst Du das denn haengen?\n");
+ if ( strstr(woran, "haken", 0)==-1 && !id(woran) )
+ return 0;
+
+ // Test, ob es Objekte dieses Namens gibt.
+ object *obs = TP->find_obs(was, PUT_GET_NONE);
+ // Aus der Liste der gefundenen Objekte alle rausfiltern, die keine
+ // Schluessel sind. Als Schluessel gelten hier alle Objekte, die die
+ // ID "schluessel" haben oder die mittels QueryDoorKey() einer bestimmten
+ // Tuer zugeordnet sind.
+ obs = filter(obs, #'IsValidKey);
+ notify_fail("Keine(n) Schluessel mit dem Namen gefunden.\n");
+ if ( !sizeof(obs) )
+ return 0;
+
+ int nr = GetNextFreeSlot();
+ notify_fail("Am Schluesselbrett ist kein Haken mehr frei.\n");
+ if ( !nr )
+ return 0;
+
+ // Wenn nur ein Schluessel gefunden wurde, wird genauer geschaut, ob
+ // der Spieler gesagt hat, wo der hinsoll.
+ if ( sizeof(obs) == 1 ) {
+ if ( woran != "haken" || !id(woran) )
+ sscanf(woran, "haken %d", nr);
+ }
+
+ notify_fail("Es gibt nur die Haken 1 bis 16.\n");
+ if ( nr < 1 || nr > 16 )
+ return 0;
+
+ notify_fail("Der Haken ist nicht mehr frei.\n");
+ if ( objectp(haken[nr,HOOK_OB]) )
+ return 0;
+
+ // Alle gefundenen Schluesselobjekte ans Brett haengen.
+ foreach( object key : obs ) {
+ switch (key->move(ME, M_PUT)) {
+ // Die Kapazitaet ist ueber P_MAX_OBJECTS begrenzt. Alle
+ // Schleifendurchlaeufe, die die Kapazitaetsgrenze erreichen, landen
+ // in default und beenden damit die Schleife. Daher muessen sie
+ // nicht gesondert behandelt werden.
+ case MOVE_OK :
+ // Falls das Brett voll sein sollte, aber faelschlicherweise
+ // dennoch ein weiterer Schluessel hineinbewegt wurde, ist nr==0,
+ // und es wird ein Fehler ausgeloest, damit nicht hinterher ein
+ // Schluessel an Haken 0 haengt.
+ if ( !nr ) {
+ raise_error("Fehler: Haken 0 darf nicht belegt werden.");
+ break;
+ }
+ tell_object(TP, BS("Du haengst "+obs[0]->name(WEN,1)+" an Haken "+
+ nr+"."));
+ // Nur wenn ein Schluessel erfolgreich drangehaengt wurde, wird er
+ // in die Liste eingetragen. Etwaige Beschriftungen bleiben bestehen,
+ haken[nr, HOOK_OB] = key;
+ // und nur dann wird der naechste Slot probiert. Wenn nur ein
+ // Schluessel verarbeitet wird, ist das hier unschaedlich, weil es
+ // nicht nochmal ausgewertet wird.
+ nr = GetNextFreeSlot();
+ // Schluessel wurde verarbeitet und Meldung ausgegeben
+ obs -= ({key});
+ break;
+ case ME_CANT_LEAVE_ENV :
+ case ME_CANT_BE_INSERTED :
+ case ME_CANT_BE_DROPPED :
+ // Schluessel wurde nicht erfolgreich drangehaengt.
+ tell_object(TP, BS(key->Name(WER,1)+" weigert sich, ans "
+ "Schluesselbrett gehaengt zu werden."));
+ // Meldung wurde ausgegeben, nichts weiter zu tun.
+ obs -= ({key});
+ break;
+ // TOO_MANY_OBJECTS wird nicht hier behandelt, sondern weiter unten,
+ // um eine Auflistung der Schluesselnamen ausgeben zu koennen, statt
+ // eine Zeile pro Schluessel. Die anderen Rueckgabewerte von move()
+ // sind bei dieser Art der Bewegung nicht zu erwarten.
+ default: break;
+ }
+ }
+ // Fuer alle uebrigen war wohl TOO_MANY_OBJECTS der Rueckgabewert, denn
+ // das Schluesselbrett erlaubt nur P_MAX_OBJECTS = 16.
+ if ( sizeof(obs) ) {
+ tell_object(TP, BS("Fuer "+CountUp(obs->name(WEN))+" ist leider kein "
+ "Haken mehr am Schluesselbrett frei."));
+ }
+ return 1;
+}
+
+// Schluessel abnehmen
+static int schluessel_von_haken_nehmen(string str) {
+ if( !stringp(str) || !sizeof(str) )
+ return 0;
+
+ string was, woraus;
+ if ( sscanf(str, "%s aus %s", was, woraus) != 2 &&
+ sscanf(str, "%s von %s", was, woraus) != 2 )
+ return 0;
+
+ notify_fail("Das darfst Du nicht!\n");
+ if(!erlaubt())
+ return 0;
+
+ notify_fail("Woraus willst Du das denn nehmen?\n");
+ if ( !id(woraus) && strstr(woraus, "haken", 0) == -1 )
+ return 0;
+
+ notify_fail("Was willst Du denn vom Schluesselbrett nehmen?\n");
+ if( !stringp(was) )
+ return 0;
+
+ notify_fail("Das Schluesselbrett ist doch aber leer.\n");
+ if ( !sizeof(all_inventory(ME)) )
+ return 0;
+
+ int hakennr;
+ object *keys = ({});
+ // Es muessen auch Schluessel von bestimmten Haken abgenommen
+ // werden koennen, nicht nur jeweils der erste mit der angegebenen ID.
+ // Dies hat auch Prio gegenueber der allgemeinen Begriffssuche mit
+ // find_obs().
+ if ( sscanf(woraus, "haken %d", hakennr) == 1 ) {
+ notify_fail("Es gibt nur die Haken 1 bis 16.\n");
+ if ( hakennr < 1 || hakennr > 16 )
+ return 0;
+ notify_fail("An diesem Haken haengt aber doch kein Schluessel.\n");
+ if ( !objectp(haken[hakennr,HOOK_OB]) )
+ return 0;
+
+ keys += ({ haken[hakennr,HOOK_OB] });
+ }
+
+ // Keiner gefunden? Vielleicht ist ja einer mit einer bestimmten
+ // Beschriftung gemeint?
+ if ( !sizeof(keys) ) {
+ // Schluessel mit dem angegebenen Namen suchen
+ keys = TP->find_obs(was+" in brett in raum");
+ // Hakennummer ermitteln, wenn eine Beschriftung angegeben wurde.
+ string wanted_desc;
+ sscanf(was, "schluessel fuer %s", wanted_desc);
+ object wanted_key = GetKeyForLabel(wanted_desc);
+ if ( objectp(wanted_key) )
+ keys += ({wanted_key});
+ }
+ // Immer noch nix gefunden? Dann muss sich der Spieler was anderes
+ // einfallen lassen.
+ notify_fail("Am Schluesselbrett haengt kein solcher Schluessel.\n");
+ if ( !sizeof(keys) )
+ return 0;
+
+ // Alle gefundenen Schluessel verarbeiten. Alle, die nicht bewegt werden
+ // koennen, verbleiben in der Liste.
+ foreach( object key : keys ) {
+ int current_hook = GetHookNumberForKey(key);
+ if ( key->move(TP,M_GET) == MOVE_OK ) {
+ keys -= ({ key });
+ tell_object(TP, BS("Du nimmst "+key->name(WEN,1)+" von Haken "+
+ current_hook+" ab."));
+ // Schluessel austragen; bestehende Beschriftungen bleiben erhalten
+ haken[current_hook, HOOK_OB] = 0;
+ }
+ }
+ // Von allen nicht vom Haken genommenen Schluesseln die Namen ermitteln
+ // und auflisten.
+ if ( sizeof(keys) ) {
+ tell_object(TP, BS(capitalize(CountUp(keys->name(WER,1)))+" "+
+ (sizeof(keys)==1?"konnte":"konnten")+" nicht vom Schluesselbrett "
+ "abgenommen werden."));
+ }
+ return 1;
+}
+
+// Verfuegbare Kommandos auflisten.
+varargs int skommandos(string str) {
+ notify_fail( "Fehler: Dieser Befehl benoetigt eine gueltige Objekt-Id als "
+ +"Parameter.\nBeispiel: skommandos [schluessel]brett\n");
+
+ if( !id(str) ) return 0;
+
+ write(
+ "==================================================================="
+ "==========\n"
+ "Aktuelle Version: "+QueryProp("cnt_version_std")+
+ QueryProp("cnt_version_obj")+"\n"+
+ BS(Name(WER,1)+" kann nur in diesem Seherhaus verwendet werden, "
+ "da "+QueryPronoun(WER)+" speziell dafuer gekauft wurde. "+
+ CAP(QueryPronoun(WER))+" verfuegt ueber folgende Kommandos:")+
+ "----------------------------------------------------------------------"
+ "-------\n"
+ "serlaube [schluessel]brett [spielername|\"hausfreunde\"|\"zweities\"]\n"
+ " Erlaubt Personen, "+name(WEN,1)+" mitzubenutzen.\n"
+ " serlaube ohne Angabe eines Arguments listet alle Personen mit Zugriff "
+ "auf\n "+name(WEN,1)+" auf.\n\n"
+ "verschiebe [schluessel]brett nach [ausgang]\n"
+ " Damit kannst Du "+name(WEN,1)+" innerhalb Deines Seherhauses "
+ "verschieben.\n\n"
+ "sverstecke [schluessel]brett\n"
+ " Damit machst Du "+name(WEN,1)+" unsichtbar.\n"
+ "shole [schluessel]brett hervor\n"
+ " Damit machst Du "+name(WEN,1)+" wieder sichtbar.\n"
+ "zertruemmer [schluessel]brett\n"
+ " Damit zerstoerst Du das Schluesselbrett.\n"
+ "sbeschrifte haken <nr> mit <text>|nichts\n"
+ " Eine Beschriftung an einem Haken anbringen oder loeschen.\n"
+ "sliste lang|kurz\n"
+ " Schluesselanzeige konfigurieren: alle oder nur belegte auflisten.\n"
+ "haenge <schluesselname> an haken [nr]\n"
+ "haenge <schluesselname> an [schluessel]brett\n"
+ " Damit haengst Du einen Schluessel an das Brett.\n"
+ "nimm schluessel von haken <nr>\n"
+ "nimm <schluesselname> von [schluessel]brett\n"
+ "nimm schluessel fuer <beschriftung> von [schluessel]brett.\n"
+ " Damit nimmst Du einen Schluessel vom Schluesselbrett.\n"
+ "==================================================================="
+ "==========\n");
+ return 1;
+}
+
+static int erlaubnis_liste()
+{
+ if( QueryHausbesitzer() != QueryTP() && !QueryProp("test") )
+ {
+ tell_object(TP, BS("Nur "+QueryHausbesitzer()+" darf Berechtigungen "
+ +name(WESSEN,1)+" abfragen!"));
+ return 1;
+ }
+
+ string *strs;
+ string str =
+ "==================================================================="
+ "==========\n";
+ if ( hauserlaubnis ) {
+ strs = SHVERWALTER->HausProp(LOWER(QueryHausbesitzer()), 2);
+ str += "Folgende Freunde Deines Hauses duerfen "+name(WEN,1)+
+ " mitbenutzen:\n";
+ if(sizeof(strs)) {
+ str += BS(CountUp(strs));
+ }
+ else {
+ str += BS("Du hast keiner Person Zugriff auf Dein Haus gewaehrt...");
+ }
+ }
+ else {
+ str+= BS("Die Freunde Deines Hauses duerfen "+name(WEN,1)+
+ " nicht mitbenutzen.");
+ }
+
+ str +=
+ "-------------------------------------------------------------------"
+ "----------\n";
+
+ if( zweitieerlaubnis!="" ) {
+ if( zweitieerlaubnis==geteuid(TP) )
+ str += BS("Alle Deine Zweities duerfen "+name(WEN,1)+" mitbenutzen.");
+ else
+ str += BS("Alle Zweities von "+CAP(zweitieerlaubnis)+" duerfen "
+ +name(WEN,1)+" mitbenutzen.");
+ str +=
+ "-------------------------------------------------------------------"
+ "----------\n";
+ }
+
+ strs=QueryProp("cnt_erlaubnis");
+
+ if(sizeof(strs)) {
+ str += BS("Folgende sonstige Personen duerfen "+name(WEN,1)+
+ " mitbenutzen:");
+ str += CountUp(strs);
+ }
+ else {
+ str += BS("Es gibt keine sonstigen Personen, die "+name(WEN,1)+
+ " mitbenutzen duerfen.");
+ }
+ str +=
+ "==================================================================="
+ "==========\n";
+
+ return 1;
+}
+
+// Haken beschriften.
+static int cmd_beschriften(string str) {
+ string nfm = "Syntax: sbeschrifte haken <hakennummer> mit "
+ "<text>|nichts\n"
+ "Fuer <text> kannst Du einen beliebigen Text mit bis zu 30 Zeichen "
+ "angeben,\n"
+ "'nichts' loescht die Beschriftung eines Schildes.\n";
+
+ notify_fail("Das darfst Du nicht!\n");
+ if(!erlaubt())
+ return 0;
+
+ string text;
+ int hnr;
+ str = TP->_unparsed_args(0);
+ notify_fail(nfm);
+ if ( !stringp(str) || !sizeof(str) )
+ return 0;
+ if ( sscanf(str,"haken %d mit %s", hnr, text)!=2 )
+ return 0;
+
+ notify_fail("Welchen Haken moechtest Du beschriften?\n"+nfm);
+ if(!hnr)
+ return 0;
+
+ notify_fail("Es gibt nur die Haken 1 bis 16.\n");
+ if ( hnr < 1 || hnr > 16 )
+ return 0;
+
+ notify_fail("Womit moechtest Du den Haken beschriften?\n"+nfm);
+ if( !stringp(text) || !sizeof(text) )
+ return 0;
+
+ notify_fail("Der Text sollte nicht laenger als 30 Zeichen sein.\n");
+ if(sizeof(text) > 30)
+ return 0;
+
+ if ( lower_case(text) == "nichts" ) {
+ if ( stringp(haken[hnr,HOOK_LABEL]) ) {
+ tell_object(TP, BS("Sorgfaeltig wischst Du die Beschriftung des "
+ "Hakens "+hnr+" weg."));
+ haken[hnr,HOOK_LABEL]=0;
+ }
+ else {
+ tell_object(TP, BS("Du musst Dich geirrt haben. Haken "+hnr+" ist "
+ "gar nicht beschriftet."));
+ }
+ }
+ else if ( lower_case(text) == "schluessel" ) {
+ tell_object(TP, BS(
+ "Du solltest Dir etwas Aussagekraeftigeres einfallen lassen."));
+ }
+ else {
+ tell_object(TP, BS("Du beschriftest das Schildchen ueber Haken "+hnr+
+ " mit "+text+"."));
+ tell_room(environment(), BS(
+ TP->Name(WER)+" schreibt etwas ans Schluesselbrett."), ({TP}));
+ haken[hnr,HOOK_LABEL] = text;
+ }
+ return 1;
+}
+
+/***** HILFSFUNKTIONEN *****/
+
+// Beschreibung eines Hakens erzeugen. Wenn <keynum> angegeben wird,
+// wird nur der gesuchte Haken angezeigt, egal ob leer oder nicht.
+// Ansonsten werden die belegten Haken angezeigt, ausser wenn
+// <hooklist_long> gesetzt ist. Dann werden alle Haken aufgelistet.
+private varargs string KeyDescription(int keynum) {
+ string desc="";
+ mapping keylist=([:2]);
+
+ // Liste derHaken auf den/die gesuchten einschraenken.
+ // Nur ein Haken soll angeschaut werden. Dies hat immer Prioritaet,
+ // d.h. auch bei <sliste alle> wird nur ein Haken gelistet.
+ if ( keynum ) {
+ m_add(keylist, keynum, m_entry(haken, keynum)...);
+ }
+ // Wenn <sliste alle> gesetzt ist, alle ausgeben.
+ else if ( hooklist_long ) {
+ keylist = haken;
+ }
+ // Ansonster nur die belegten.
+ else {
+ keylist = filter(haken,
+ function int (int num, <string|object>* values) {
+ return objectp(values[0]);
+ });
+ }
+
+ // Ueber das Mapping mit den selektierten Haken laufen und Ausgaben
+ // erzeugen.
+ foreach(int num : 1..16) {
+ // Hier wird der aktuelle Wert uebersprungen, wenn er nicht enthalten
+ // ist, da die Zuweisung in <key> und <keydesc> auch dann eine 0 ergeben
+ // wuerde, und somit Keys mit leeren Values nicht von nicht existierenden
+ // Keys zu unterscheiden waeren.
+ if ( member(m_indices(keylist), num) == -1 )
+ continue;
+ string keydesc = keylist[num, HOOK_LABEL];
+ object key = keylist[num, HOOK_OB];
+ desc += "Haken " + num + (stringp(keydesc)?" ["+keydesc+"]: " : ": ");
+ desc += (objectp(key) ? key->short() : "leer\n");
+ }
+ return desc;
+}
+
+// Rueckgabewert: 1, wenn es sich um ein Schluesselobjekt handelt, sonst 0.
+// Schluessel werden anhand der ID "schluessel" erkannt oder daran, dass
+// QueryDoorKey() einen Wert zurueckgibt, d.h. dass dieses Objekt eine
+// Standard-Doormaster-Tuer oeffnet.
+private int IsValidKey(object ob) {
+ return (objectp(ob) && (ob->id("schluessel") || ob->QueryDoorKey()!=0));
+}
+
+// Gibt die Nummer des naechsten freien Hakens zurueck oder 0, wenn
+// keiner frei ist. Da Mappings nicht sortiert sind, muss von 1-16 numerisch
+// iteriert werden, damit immer der erste freie Haken gefunden wird und nicht
+// irgendeiner.
+// Rueckgabewert: Hakennummer von 1-16 oder 0, wenn kein Haken frei ist.
+private int GetNextFreeSlot() {
+ int slot;
+ foreach(int i : 1..16) {
+ if ( !objectp(haken[i,HOOK_OB]) ) {
+ slot = i;
+ break;
+ }
+ }
+ return slot;
+}
+
+// Gibt zu einer Schild-Beschriftung die zugehoerige Hakenposition aus.
+// Es wird die kleingeschriebene Variante gesucht, so dass Spieler zwar
+// Grossschreibung in den Beschriftungen verwenden koennen, diese aber
+// nicht beruecksichtigt wird. Ansonsten koennte es zu Schwierigkeiten mit
+// Dopplungen wie "Vesray" und "vesray" kommen.
+// Rueckgabewert: Hakennummer von 1-16 oder 0, wenn der Text nicht gefunden
+// wurde.
+private object GetKeyForLabel(string label) {
+ if ( label )
+ label = lower_case(label);
+ foreach(int i: 1..16) {
+ if ( haken[i, HOOK_LABEL] && label &&
+ lower_case(haken[i,HOOK_LABEL]) == label )
+ return haken[i,HOOK_OB];
+ }
+ return 0;
+}
+
+// Gibt zu dem uebergebenen Objekt die Nummer des Hakens zurueck, an dem
+// es haengt.
+private int GetHookNumberForKey(object ob) {
+ foreach(int num, object key : haken) {
+ if ( key == ob )
+ return num;
+ }
+ return 0;
+}
+
+// Bereinigt Datenstruktur in <haken> und das Inventar des Brettes, indem
+// a) geprueft wird, ob alle in <haken> eingetragenen Objekte sich auch im
+// Brett befinden und
+// b) geprueft wird, ob alle im Inventar befindlichen Objekte auch korrekt in
+// <haken> eingetragen sind.
+// Ueberzaehlige Objekte werden rausgeworfen.
+private void ConsolidateInventory() {
+ foreach(int i, object ob : haken) {
+ // Objekt existiert, ist aber nicht im Schluesselbrett? Dann austragen.
+ if (objectp(ob) && environment(ob) != ME) {
+ m_delete(haken, i);
+ // Wird auch vom reset() aus gerufen, dann ist TP == 0.
+ if ( objectp(TP) )
+ tell_object(TP, BS("Hoppla! "+ob->Name(WER,1)+" scheint vom "
+ "Schluesselbrett verschwunden zu sein!"));
+ }
+ }
+ object *resterampe = all_inventory(ME) - m_values(haken, HOOK_OB);
+ if (sizeof(resterampe)) {
+ resterampe->move(environment(),M_PUT);
+ tell_room(environment(), BS("Ploetzlich faellt etwas vom "
+ "Schluesselbrett zu Boden, das Du zuvor gar nicht gesehen hattest."));
+ }
+}
+
+string short() {
+ string sh=QueryProp(P_SHORT);
+
+ // Unsichtbar? Dann gibts nichts zu sehen ...
+ if ( QueryProp(P_INVIS) || !sh )
+ return 0;
+ if ( QueryProp("versteckt") == 1 )
+ sh = "";
+ else
+ sh += ".";
+
+ return process_string(sh)+"\n";
+}
+
+// Im Reset vorsichtshalber auch mal aufraeumen.
+void reset() {
+ ConsolidateInventory();
+ return ::reset();
+}
+
+varargs int PreventInsert(object ob) {
+ // Kein Schluessel? Hat in diesem Container nix verloren!
+ if( !IsValidKey(ob )) {
+ return 1;
+ }
+ ConsolidateInventory();
+ return ::PreventInsert(ob);
+}
+
+// Wenn ein Schluessel sich aufloest, muss die Liste abgeglichen werden.
+void NotifyRemove(object ob) {
+ tell_room(environment(ME), BS("Hoppla! "+ob->Name(WER,1)+" hat sich "
+ "gerade in Wohlgefallen aufgeloest."));
+ // Das Objekt <ob> zerstoert sich erst nach dem Aufruf dieser Funktion,
+ // daher per call_out() aufraeumen.
+ call_out(#'ConsolidateInventory, 1);
+}
+
+// Zesstra, 1.7.07, fuers Hoerrohr
+// Darf ich da Arathorn eintragen? ;-)
+string GetOwner() {
+ return "seleven";
+}
+
diff --git a/d/seher/haeuser/moebel/schraenker_gutschein.c b/d/seher/haeuser/moebel/schraenker_gutschein.c
new file mode 100644
index 0000000..9c89204
--- /dev/null
+++ b/d/seher/haeuser/moebel/schraenker_gutschein.c
@@ -0,0 +1,44 @@
+//--------------------------------------------------------------------------------
+// Name des Objects: Schraenger-Gutschein
+// Letzte Aenderung: 05.05.2001
+// Magier: Swift
+//--------------------------------------------------------------------------------
+
+#include "schrankladen.h"
+#include <ansi.h>
+inherit "std/thing";
+
+create()
+{
+ if (!clonep(TO)) return;
+ ::create();
+ SetProp(P_SHORT, "Ein Gutschein");
+ SetProp(P_LONG, "@@longtext@@");
+ AddId(({"gutschein"}));
+ SetProp(P_NAME, "Gutschein");
+ SetProp(P_GENDER, MALE);
+ SetProp(P_WEIGHT, 5); // Gewicht 5g
+ SetProp(P_VALUE, 0); // Kein materieller Wert. Ist eh nicht verkaufbar.
+ SetProp(P_NOBUY, 1); // Wird im Laden zerstoert, falls er verkauft wird.
+ SetProp(P_MATERIAL, ({MAT_PAPER}) );
+ SetProp(P_INFO, "Dieser Gutschein ist nur fuer einen Seher mit Eigenheim von Interesse!\n");
+ SetProp(P_AUTOLOADOBJ, 1);
+}
+
+string longtext()
+{
+ string str,aussteller,inhaber,text;
+ int wert;
+ aussteller="Seleven";
+ inhaber="Filli";
+ wert=5000;
+ text="";
+ str="***********************************************************************\n\n"
+ +" D E R S C H R A E N K E R\n\n"
+ +" E I N K A U F S - G U T S C H E I N .\n\n"
+ +" Ausgestellt von "+aussteller+" fuer "+inhaber+".\n\n"
+ +" Wert: "+to_string(wert)+" Muenzen.\n\n"
+ +text
+ +"***********************************************************************\n";
+ return str;
+}
diff --git a/d/seher/haeuser/moebel/schrankladen.c b/d/seher/haeuser/moebel/schrankladen.c
new file mode 100644
index 0000000..bcaf25c
--- /dev/null
+++ b/d/seher/haeuser/moebel/schrankladen.c
@@ -0,0 +1,436 @@
+//----------------------------------------------------------------------------
+// Name des Objects: SCHRAENKER
+// Letzte Aenderung: 06.04.2006 P_LOG_FILE (Seleven)
+// Magier: Swift
+//----------------------------------------------------------------------------
+#pragma strong_types,rtt_checks
+inherit "/std/room";
+
+#include <properties.h>
+#include <language.h>
+#include "schrankladen.h"
+
+
+protected void create()
+{
+ ::create();
+ SetProp(P_LOG_FILE,"seleven/schraenker"); // Seleven 06.04.2006
+ SP(P_INT_SHORT, "Im SCHRAENKER");
+ SP(P_INT_LONG, BS(
+ "Du stehst in einem gemuetlichen kleinen Laden. Ein flauschiger "
+ +"Teppichboden daempft Deine Schritte, und der Geruch verschiedener "
+ +"Hoelzer kitzelt angenehm in der Nase. Irgendwoher erklingt eine "
+ +"leise, beruhigende Melodie. An den Waenden haengen Bilder und "
+ +"Zeichnungen verschiedenster Art, sowie eine grosse Preisliste. "
+ +"Wenn Du nicht den Eindruck haettest, dass man hier an Deine Boerse "
+ +"moechte, koenntest Du Dich hier richtig wohl fuehlen.",78));
+
+ SP(P_LIGHT, 1);
+ SP(P_INDOORS, 1);
+
+ AD( ({"zeit"}), BS(
+ "Die aktuelle Zeit: "+ctime(time()),78));
+ AD( ({"ausgang"}), BS(
+ "Nach Osten geht's raus.",78));
+ AD( ({"ausgaenge"}), BS(
+ "So sehr Du auch suchst, mehr als den einen Ausgang findest Du "
+ +"einfach nicht.",78));
+ AD( ({"geldboerse", "boerse"}), BS(
+ "Man redet halt von Boerse, auch wenn Du keine dabeihast. Es geht "
+ +"halt um Dein Geld!",78));
+ AD( ({"geld"}), BS(
+ "Irgendwo wirst Du schon Kohle haben! :)",78));
+ AD( ({"kohle", "zaster", "moneten", "piepen", "maeuse"}), BS(
+ "Kohle, Zaster, Moneten, Piepen, Maeuse... alles dasselbe! :)",78));
+ AD( ({"boden"}), BS(
+ "Ein flauschiger, aber auch sehr strapazierfaehiger Teppich bedeckt "
+ +"den ganzen Boden des Ladens. Billig sieht er nicht aus.",78));
+ AD( ({"teppich", "teppichboden"}), BS(
+ "Es handelt sich um einen echten Vorberg-Teppich. Er wurde "
+ +"von einem Fachmann verlegt und scheint aus einem einzigen grossen "
+ +"Stueck zu sein.",78));
+ AD( ({"stueck"}), BS(
+ "Der Teppich scheint aus einem einzigen grossen Stueck zu sein. So gut "
+ +"kann das eigentlich nur ein Fachmann.",78));
+ AD( ({"fachmann"}), BS("Es ist keiner zu sehen, aber es ist anzunehmen, dass "
+ +"es sich um einen professionellen Teppichleger handelte."));
+ AD( ({"teppichleger"}), "Wie gesagt, keiner zu sehen. Der Teppich liegt ja "
+ +"schon, und der wird auch noch eine Weile halten.\n");
+ AD( ({"weile"}), "Schon noch ein paar Jaehrchen!\n");
+ AD( ({"jaehrchen"}), "Teppiche der Firma Vorberg koennen lange halten.\n");
+ AD( ({"vorberg", "vorbergteppich", "vorberg-teppich"}), BS(
+ "Die Firma Vorberg stellt, im Gegensatz zur Firma Hinterberg, sehr gute "
+ +"Teppiche her, wie jeder weiss.",78));
+ AD( ({"gegensatz"}), "Das weiss wirklich Jeder!\nDu koenntest Ihn fragen, "
+ +"waere er nicht gebanisht. :)\n");
+ AD( ({"ihn"}), BS("Wen IHN ? Meinst Du Jeder? Der ist doch gebanisht. Aus gutem "
+ +"Grund. Wenn irgendwo was wegkommt, dann koennte das Jeder gewesen sein. "
+ +"Das reicht doch, um ihn zu banishen, oder? :)"));
+ AD( ({"hinterberg", "hinterbergteppich", "hinterberg-teppich"}), BS(
+ "Das hier ist ein Teppich der Firma Vorberg. Niemand mit Geschmack wuerde "
+ +"den billigen Abklatsch der Firma Hinterberg kaufen.",78));
+ AD( ({"jeder"}), BS(
+ "Der ist nicht da. Siehst Du ihn etwa?",78));
+ AD( ({"grund", "gruende"}), BS(
+ "Gruende lassen sich immer finden, sei also vorsichtig! :)",78));
+ AD( ({"geschmack"}), BS(
+ "Ueber den laesst sich bekanntlich streiten.",78));
+ AD( ({"teppiche"}), BS(
+ "Du siehst hier einen. Der aber fuellt den ganzen Raum aus.",78));
+ AD( ({"abklatsch"}), BS(
+ "Vorberg-Teppiche sind halt das einzig Wahre!",78));
+ AD( ({"laden"}), BS(
+ "Der Laden ist bekannt unter dem Namen \"SCHRAENKER\". Aber das weisst "
+ +"Du sicher.",78));
+ AD( ({"namen"}), BS(
+ "Der Namen des Ladens ist \"SCHRAENKER\".",78));
+ AD( ({"schraenker"}), BS(
+ "Ja, schau Dich nur um!",78));
+ AD( ({"melodie"}), BS(
+ "Lausche ihr besser.",78));
+ AD( ({"geruch"}), BS(
+ "Sehen kannst Du den nicht. Vielleicht solltest Du Deine Nase benutzen?",78));
+ AD( ({"schritte"}), BS(
+ "Du gehst testweise ein paar Schritte, der Teppich daempft sie tatsaechlich "
+ +"so gut, dass Du nicht das geringste hoeren kannst.",78));
+ AD( ({"schritt"}), BS(
+ "Mach das doch irgendwo, wo es keiner sieht!",78));
+ AD( ({"nase"}), BS(
+ "Du fasst Dir an die Nase. Ein Glueck, sie ist noch da!",78));
+ AD( ({"glueck"}), BS(
+ "Ohne Nase koenntest Du hier gar nichts riechen, stell Dir das nur "
+ +"mal vor!",78));
+ AD( ({"raum", "ort"}), BS(
+ "Du stehst in einem noblen Laden. Mach einfach \"schau\".",78));
+ AD( ({"firma"}), BS(
+ "Du stehst hier in einem Laden. Natuerlich ist das eine Firma, und der "
+ +"Ladeninhaber ist ebenso natuerlich der Firmenbesitzer. Hattest Du denn "
+ +"etwas anderes erwartet?",78));
+ AD( ({"eindruck"}), BS(
+ "Es ist ein Laden. Er sieht nobel aus, Preise wie bei ALDI wird's hier also "
+ +"wohl nicht geben. Und ausserdem ist der erste Eindruck meist der richtige.",78));
+ AD( ({"aldi"}), BS(
+ "NEIN, Du bist hier NICHT bei ALDI !!!",78));
+ AD( ({"preis", "preise", "liste", "preisliste"}), BS(
+ "An der Wand haengt eine grosse Preisliste. Vielleicht solltest Du sie "
+ +"lesen?",78));
+ AD( ({"inhaber", "ladeninhaber", "besitzer", "firmenbesitzer", "verkaeufer"}), BS(
+ "Ist der denn gerade nicht da? Das ist sehr verwunderlich, echt ehrlich.",78));
+ AD( ({"elf", "elfen", "person"}), BS(
+ "Schau Dir halt das Portrait an!",78));
+ AD( ({"darstellung", "darstellungen"}), BS(
+ "Die Bilder zeigen Moebelstuecke, hauptsaechlich Schraenke.",78));
+ AD( ({"reihe"}), BS(
+ "Bei den meisten Bildern handelt es sich um Darstellung von Moebelstuecken. "
+ +"Nur ein einziges Portrait ist dabei, das eine Person zeigt.",78));
+ AD( ({"art"}), BS(
+ "Bei den meisten Bildern handelt es sich um Darstellungen von Moebelstuecken, "
+ +"zumeist von Schraenken. Ein Portrait faellt Dir allerdings auf, das nicht in "
+ +"die Reihe der anderen Bilder passt.",78));
+ AD( ({"bilder"}), BS(
+ "Es gibt mehrere Darstellungen von verschiedenen Moebelstuecken. Zumeist "
+ +"handelt es sich dabei um Schraenke verschiedener Bauweise. Ausserdem ist "
+ +"da noch ein Portrait.",78));
+ AD( ({"bauart", "bauweise", "moebelstueck", "moebelstuecke", "arten"}), BS(
+ "Es gibt Waffenschraenke, Kleiderschraenke, Kuehlschraenke (JA!), Kommoden, "
+ +"sonstige Schraenke (Du kannst ihren Zweck nicht mal erahnen) und einige "
+ +"Truhen, die zwar keine Schraenke im eigentlichen Sinne sind, aber Zeug "
+ +"bringt man darin mit Sicherheit auch unter. Sogar eine Vitrine siehst "
+ +"Du.",78));
+ AD( ({"zweck"}), BS(
+ "Stauraum fuer irgendwelches Zeugs. Das muss es sein. Was fuer einen "
+ +"Zweck koennte es sonst noch geben?",78));
+ AD( ({"vitrine"}), BS("Die Vitrine ist leer, aber das aendert sich sicher, "
+ +"sobald Du eine gekauft hast.",78));
+ AD( ({"kleiderschrank", "kleiderschraenke"}), BS(
+ "Sicher eignet sich solch ein Schrank sehr gut, um darin Ruestungen "
+ +"aufzubewahren.",78));
+ AD( ({"waffenschrank", "waffenschraenke"}), BS(
+ "In einem Waffenschrank kannst Du eine Menge verschiedener Waffen "
+ +"unterbringen, und der Vorteil dabei ist, dass sie dann auch sauber "
+ +"sortiert im Schrank haengen.",78));
+ AD( ({"kommoden"}), BS(
+ "Die kann man nicht nur in einen Flur stellen, sondern auch in jeden "
+ +"anderen Raum!",78));
+ AD( ({"flur"}), BS(
+ "Die meisten Haeuser haben einen.",78));
+ AD( ({"haeuser"}), BS(
+ "HIER ???",78));
+ AD( ({"menge"}), BS(
+ "Mehr als Du brauchst, es sei denn Du bist Sammler.",78));
+ AD( ({"zeugs", "dinge"}), BS(
+ "Dinge halt.",78));
+ AD( ({"waffen"}), BS(
+ "Du kannst sie in einem Waffenschrank unterbringen, wenn Du einen "
+ +"besitzt. Wenn nicht kannst Du ja einen kaufen.",78));
+ AD( ({"waffe"}), BS(
+ "Welche Waffe meinst Du?",78));
+ AD( ({"ruestungen"}), BS(
+ "Du kannst sie in einem Kleiderschrank unterbringen, wenn Du einen "
+ +"besitzt. Wenn nicht koenntest Du Dir einen zulegen.",78));
+ AD( ({"ruestung"}), BS(
+ "Von welcher Ruestung redest Du?",78));
+ AD( ({"vorteil"}), BS(
+ "Jeder ist doch auf seinen persoenlichen Vorteil bedacht.",78));
+ AD( ({"kuehlschrank", "kuehlschraenke"}), BS(
+ "In so einem Kuehlschrank kann man eigentlich alles reinstecken, aber "
+ +"natuerlich bietet er sich besonders fuer Getraenke und Speisen aller "
+ +"Art an. Wie z.B. Schnellhaerter, Broetchen usw.",78));
+ AD( ({"getraenke", "speisen"}), BS(
+ "Das hier ist keine Kneipe. Sowas gibt's hier nicht!",78));
+ AD( ({"kneipe"}), BS(
+ "Das hier ist KEINE Kneipe !!!",78));
+ AD( ({"truhe", "truhen"}), BS(
+ "Es gibt grosse und kleine, aus verschiedenem Material.",78));
+ AD( ({"material"}), BS(
+ "Total verschieden, wirklich.",78));
+ AD( ({"schnellhaerter", "broetchen"}), BS(
+ "Besorg Dir welche, bevor Du sie untersuchen willst!",78));
+ AD( ({"sammler"}), BS(
+ "Bist Du einer?",78));
+ AD( ({"sicherheit"}), BS(
+ "Jo, in so eine Truhe passt viel Zeug rein.",78));
+ AD( ({"zeug"}), BS(
+ "Alles, was Du so mit Dir rumschleppst. Das meiste davon brauchst "
+ +"Du sowieso nie.",78));
+ AD( ({"bild"}), BS(
+ "Es gibt mehrere Darstellungen von verschiedenen Moebelstuecken und ein "
+ +"Portrait. Welches Bild meinst Du?",78));
+ AD( ({"portrait"}), BS(
+ "Es zeigt einen Elf mit strahlend blauen Augen und den typisch spitzen "
+ +"Elfenohren, die frech aus einer beeindruckenden, silbergrauen Loewenmaehne "
+ +"hervorschauen. Der Spitzhut, der ihm auf dem Kopf sitzt, laesst darauf "
+ +"schliessen, dass es sich um einen Zauberer handelt. Unten in der rechten "
+ +"Bildecke ist eine Widmung angebracht.",78));
+ AD( ({"sinn", "sinne"}), BS(
+ "Schraenke und Truhen sehen schon etwas veschieden aus.",78));
+ AD( ({"swift"}), BS(
+ "Siehst Du ihn hier etwa gerade?",78));
+ AD( ({"bildecke"}), BS(
+ "Unten in der rechten Bildecke ist eine Widmung angebracht.",78));
+ AD( ({"augen"}), BS(
+ "Der Elf auf dem Portrait hat strahlend blaue Augen.",78));
+ AD( ({"widmung"}), BS(
+ "Sieht aus als ob man die sogar lesen kann!",78));
+ AD( ({"maehne", "loewenmaehne"}), BS(
+ "Der Elf auf dem Bild hat eine silbergraue Loewenmaehne.",78));
+ AD( ({"zauberer", "zauberhut", "zaubererhut", "spitzhut"}), BS(
+ "Der Zauberhut macht den Elfen auf dem Portrait erst zu einem waschechten "
+ +"Zauberer.",78));
+ AD( ({"ohren", "elfenohren"}), BS(
+ "Die Ohren des Elfen auf dem Portrait sind so spitz, wie man das von "
+ +"einem Elfen erwartet.",78));
+ ARD( ({"widmung"}),
+ "Dank an Geordi fuer diese grossartige Geschaeftsidee.\n"
+ +"Moegen Dir Deine Zauber gelingen und die Spellpunkte niemals ausgehen.\n"
+ +"(Darunter hat jemand unterschrieben, aber das Gekrakel kannst Du nicht "
+ +"identifizieren)\n");
+ AD( ({"unterschrift"}), BS(
+ "Meinst Du das Gekrakel?",78));
+ AD( ({"rotfaerbung", "farbe"}), BS(
+ "Das Holz hat eine leicht roetliche Farbe.",78));
+ AD( ({"ruhe"}), BS(
+ "Aaaahhhhh. Ruhe tut gut. Und dank der leisen Melodie entspannst Du "
+ +"Dich allmaehlich.",78));
+ AD( ({"chaosdaemon"}), BS(
+ "Keiner da. Weder Swift noch ein anderer. Glueck fuer Dich!",78));
+ AD( ({"sachen"}), BS(
+ "Was auch immer.",78));
+ AD( ({"klaue"}), BS(
+ "Wahrscheinlich kann Swift damit andere Sachen besser erledigen als "
+ +"schreiben. Schliesslich ist er ein Chaosdaemon.",78));
+ AD( ({"gekrakel"}), BS(
+ "Du nimmst Dir Zeit und schaust die Unterschrift doch nochmal in aller "
+ +"Ruhe an. Endlich kommt Dir die Erleuchtung. Das soll \"Swift\" heissen. "
+ +"Mann, hat der ne Klaue! (Naja, bei einem Chaosdaemonen wundert das "
+ +"eigentlich nicht)",78));
+ AD( ({"erleuchtung"}), BS(
+ "Sie fand in Deinem Kopf statt. Den muesstet Du schon oeffnen, wenn Du "
+ +"die Erleuchtung physisch untersuchen moechtest. Und das kann sich "
+ +"negativ auf Deine Gesundheit auswirken. Lass es lieber!",78));
+ AD( ({"gesundheit"}), BS(
+ "Mit Kopf bist Du gesund. Das ist gewiss.",78));
+ AD( ({"wand", "waende"}), BS(
+ "Die Waende bestehen aus einem feinen, exotischen Holz mit leichter "
+ +"Rotfaerbung. Sieht sehr edel aus. Mehrere Bilder wurden an den Waenden "
+ +"aufgehaengt und verteilen sich gleichmaessig ueber den Raum.",78));
+ AD( ({"kopf"}), BS(
+ "Ein Glueck, er ist noch dran. Genauso wie bei dem Elfen auf dem "
+ +"Portrait!",78));
+ AD( ({"schrank", "schraenke"}), BS(
+ "Es gibt verschiedene Arten von Schraenken.",78));
+ AD( ({"zeichnung"}), BS(
+ "Es gibt mehrere davon.",78));
+ AD( ({"zeichnungen"}), BS(
+ "Sie zeigen - teilweise skizzenhaft - den Aufbau verschiedener "
+ +"Moebelstuecke - vorzugsweise Schraenke.",78));
+ AD( ({"aufbau", "zusammensetzung"}), BS(
+ "Mit dem Aufbau ist die Zusammensetzung gemeint - und umgekehrt.",78));
+ AD( ({"holz", "hoelzer"}), BS(
+ "Schon hier im Raum wurde mit verschiedensten Hoelzern gearbeitet, "
+ +"ihr edler Duft vermischt sich und bietet einen erhebenden Geruch. "
+ +"Leider sind die meisten Holzarten so exotisch, dass Du beim besten "
+ +"Willen nicht sagen kannst, um was fuer einen Baum es sich da mal "
+ +"gehandelt hat.",78));
+ AD( ({"holzart", "holzarten"}), BS(
+ "Sehr exotische Holzarten. Du bist kein Experte fuer sowas, und "
+ +"vermutlich hast Du auch keine Lust, einer zu werden.",78));
+ AD( ({"experte"}), BS(
+ "Keiner da.",78));
+ AD( ({"lust"}), BS(
+ "Wenn jemand seine Lust untersucht/ueberprueft, bekundet er damit "
+ +"eigentlich schon in Wirklichkeit seine Unlust.",78));
+ AD( ({"unlust"}), BS(
+ "Tja, Unlust kennzeichnet den Faulpelz.",78));
+ AD( ({"faulpelz"}), BS(
+ "Du bist gemeint!",78));
+ AD( ({"wirklichkeit", "realitaet"}), BS(
+ "Die Wirklichkeit ist die Realitaet - und andersrum. Meistens "
+ +"jedenfalls.",78));
+ AD( ({"meistens"}), BS(
+ "Hier schon.",78));
+ AD( ({"hier"}), BS(
+ "Hier halt!",78));
+ AD( ({"baum", "baeume"}), BS(
+ "Hier gibt es keine Baeume. Die wurden bereits alle verarbeitet.",78));
+ AD( ({"duft"}), BS(
+ "Rieche halt mal!",78));
+ AD( ({"wille", "willen"}), BS(
+ "Dein Wille ist stark...",78));
+ AD( ({"decke"}), BS(
+ "Maechtige Balken bilden die Decke. Es koennte sich um Eiche handeln, aber "
+ +"genausogut koennte es irgendeine aehnliche, exotische Holzart sein. "
+ +"Ein herrlicher Kronleuchter haengt von der Mitte herab.",78));
+ AD( ({"eiche", "eichenbalken"}), BS(
+ "Es ist nicht sicher, dass es sich um Eichenbalken handelt, aber Balken "
+ +"sind's auf jeden Fall.",78));
+ AD( ({"fall"}), BS(
+ "Echt ehrlich.",78));
+ AD( ({"balken"}), BS(
+ "Sie bilden die Decke. Ein herrlich anzusehender Kronleuchter haengt "
+ +"daran herab.",78));
+ AD( ({"kronleuchter"}), BS(
+ "Er haengt von der Decke herab und muss ein Vermoegen wert sein. Reines "
+ +"Bergkristall mit einer Unzahl von Kerzen. Was das fuer ein Aufwand sein "
+ +"muss, die immer am Brennen zu halten.",78));
+ AD( ({"vermoegen"}), BS(
+ "Mehr als Du tragen kannst.",78));
+ AD( ({"bergkristall"}), BS(
+ "Nur Bergkristall hat diesen Glanz.",78));
+ AD( ({"brennen"}), BS(
+ "Die Kerzen flackern munter vor sich hin.",78));
+ AD( ({"unzahl"}), BS(
+ "1, 2, ...viele!",78));
+ AD( ({"glanz"}), BS(
+ "Herrlich!",78));
+ AD( ({"mitte"}), BS(
+ "Von der Mitte der Decke haengt ein Kronleuchter herab.",78));
+ AD( ({"kerzen"}), BS(
+ "Dir faellt auf, dass die Kerzen sich gar nicht verbrauchen. Es muss "
+ +"sich um magische Kerzen handeln.",78));
+ AD( ({"aufwand"}), BS(
+ "Entsetzt denkst Du . o O (Das schlaegt sich bestimmt auf den Preis nieder.)",78));
+ AD( ({"ecken"}), BS(
+ "In den Ecken entdeckst Du kleine, edle Lautsprecher, aus denen die "
+ +"Melodie zu kommen scheint.",78));
+ AD( ({"lautsprecher"}), BS(
+ "Du wusstest gar nicht, dass sowas im MorgenGrauen schon erfunden wurde.",78));
+ AD( ({"morgengrauen"}), BS(
+ "Tust Du das nicht schon die ganze Zeit?",78));
+
+ AddSmells(SENSE_DEFAULT, "Es riecht hier angenehm nach verschiedenen "
+ +"Hoelzern.\n");
+ AddSmells(({"hoelzer", "holz", "holzarten"}), BS("Du kannst nicht sagen, "
+ +"um was fuer Holzarten es sich handelt, aber der Geruch laesst auf viele "
+ +"verschiedene schliessen. Eine Trennung des Geruchs ist Dir nicht moeglich.") );
+ AddSmells(({"geruch", "gerueche"}), BS("Es riecht nach verschiedenen "
+ +"Holzarten.") );
+
+ AddSounds(SENSE_DEFAULT, "Ganz leise hoerst Du eine angenehme, beruhigende "
+ +"Melodie.\n");
+ AddSounds(({"melodie"}), "Sie scheint von allen Ecken des Ladens zu kommen.\n");
+
+ AddItem( LADEN("verkaeufer"), REFRESH_DESTRUCT);
+
+ AddCmd(({"oeffne"}), "kopf_oeffnen");
+ AddCmd(({"lies", "les", "lese"}), "preisliste_lesen");
+ AddCmd(({"idee"}), "idee_loggen");
+ AddCmd(({"trenn", "trenne"}), "gerueche_trennen");
+ AddCmd(({"werd", "werde"}), "experte_werden");
+ AddCmd(({"zaehl", "zaehle"}), "kerzen_zaehlen");
+
+ AddSpecialExit("osten", "rausgehen");
+}
+
+int kerzen_zaehlen(string str)
+{
+ notify_fail("Was moechtest Du zaehlen?\n");
+ if(!str) return 0;
+ if(str!="kerzen") return 0;
+ write("1..2..viele.\n");
+ return 1;
+}
+
+int rausgehen(string dir)
+{
+ return TP->move(RAUM_VOR_LADEN, M_GO, 0,
+ "verlaesst den Laden", "kommt aus dem Laden");
+}
+
+varargs string GetExits( object viewer )
+{
+ return "Der Ausgang befindet sich im Osten.\n";
+}
+
+int kopf_oeffnen(string str)
+{
+ notify_fail("Was moechtest Du oeffnen?\n");
+ if(!str) return 0;
+ if(str!="kopf" && str!="meinen kopf" && str!="deinen kopf")
+ return 0;
+ write( BS("Neugierig, wie Du bist, greifst Du Dir an den Kopf. Da faellt Dir "
+ +"ein, dass das oeffnen Deines Kopfes evtl. eine Copyright-Verletzung "
+ +"darstellen koennte, Du heisst ja schliesslich nicht Hannibal. Also laesst "
+ +"Du es dann doch bleiben."));
+ return 1;
+}
+
+int preisliste_lesen(string str)
+{
+ notify_fail("Was moechtest Du lesen?\n");
+ if(!str) return 0;
+ if(str!="preisliste" && str!="liste")
+ return 0;
+ TP->More( read_file(LADEN("preisliste.txt")) );
+ return 1;
+}
+
+int idee_loggen(string str)
+{
+ string txt;
+ str=TP->_unparsed_args();
+ txt=BS(str, 78, CAP(geteuid(TP))+"............."[0..12], BS_INDENT_ONCE);
+ write_file( LADEN(IDEEN_LOG), txt+"\n");
+ write("Vielen Dank fuer Deine Idee!\n");
+ return 1;
+}
+
+int gerueche_trennen(string str)
+{
+ notify_fail("Was willst Du trennen?\n");
+ if(!str) return 0;
+ if(str!="geruch" && str!="gerueche")
+ return 0;
+ write("Du versuchst es, aber Du schaffst es einfach nicht.\n");
+ return 1;
+}
+
+int experte_werden(string str)
+{
+ notify_fail("Was willst Du werden?\n");
+ if(!str) return 0;
+ if(str!="experte" && str!="fachmann")
+ return 0;
+ write("Tja, so einfach geht das nicht, aber das haettest Du Dir denken koennen.\n");
+ return 1;
+}
diff --git a/d/seher/haeuser/moebel/schrankladen.h b/d/seher/haeuser/moebel/schrankladen.h
new file mode 100644
index 0000000..1fc76a9
--- /dev/null
+++ b/d/seher/haeuser/moebel/schrankladen.h
@@ -0,0 +1,36 @@
+#include "moebel.h"
+
+#define SCHRANKMASTER2 "/players/swift/workroom"
+
+#include <language.h>
+#include <defines.h>
+#include <combat.h>
+#include <properties.h>
+#include <wizlevels.h>
+#include <moving.h>
+#include <rooms.h>
+
+#define BS break_string
+#define ENV(x) environment(x)
+#define ETO environment(this_object())
+#define ETP environment(this_player())
+#define TP this_player()
+#define TO this_object()
+
+#define SP SetProp
+#define QP QueryProp
+#define AD AddDetail
+#define ARD AddReadDetail
+
+#define SUID seteuid(getuid(this_object()))
+
+//#define CAP(x) capitalize(x)
+#define LOWER(x) lower_case(x)
+
+#define CLONEME(x) clone_object(x)->move(ME)
+#define CLONEOB(x) clone_object(x)
+#define CLONE(x,y) clone_object(x)->move(y)
+#define IST_ZAHL(x) (string)to_int(x)==x
+
+#define RIGHT(x,y) (y>sizeof(x)?x:extract(x,sizeof(x)-y,sizeof(x)-1))
+#define LEFT(x,y) (y>sizeof(x)?x:extract(x,0,y-1))
diff --git a/d/seher/haeuser/moebel/schrankmaster.c b/d/seher/haeuser/moebel/schrankmaster.c
new file mode 100644
index 0000000..c602ddc
--- /dev/null
+++ b/d/seher/haeuser/moebel/schrankmaster.c
@@ -0,0 +1,233 @@
+//--------------------------------------------------------------------------------
+// Name des Objects: Schrankmaster
+// Letzte Aenderung: 19.03.2001
+// Magier: wurzel
+//--------------------------------------------------------------------------------
+/* Changelog:
+ * 21.06.2007, Zesstra
+ call_out ohne Verzoegerung beim Updaten durch eines mit 2s Verzoegerung ersetzt.
+*/
+#pragma strong_types,rtt_checks
+
+inherit "/std/room";
+
+#include <properties.h>
+#include <language.h>
+#include "schrankladen.h"
+
+mapping schraenke;
+string *cnts;
+int update_laeuft;
+int reset_laeuft;
+
+protected void create()
+{
+ ::create();
+ SP(P_INT_SHORT, "Irgendwo und Nirgends");
+ SP(P_INT_LONG,
+ "Dies ist der Master-Raum fuer den SCHRAENKER.\n"
+ +"Hier merkt sich August die Anzahl der verkauften Container.\n"
+ +"Davon sind momentan @@ANZAHL@@ registrierte im Umlauf!\n"
+ +"Folgende Befehle sind verfuegbar:\n"
+ +" schrankliste.........Listet registrierte, im Spiel befindliche Container.\n"
+ +" schrankupdate........Fuehrt ein Update aller registrierten Container durch.\n");
+
+ SP(P_LIGHT, 1);
+ SP(P_INDOORS, 1);
+ if( SCHRANKMASTER2->QueryProp("schraenke") ) // Der Sicherungsraum hat Daten?
+ schraenke=SCHRANKMASTER2->QueryProp("schraenke"); // Daten holen...
+ else
+ schraenke=([]);
+ SetProp("schraenke", schraenke );
+
+ update_laeuft=0;
+
+ // unnoetig, SCHRANKMASTER2 ist jetzt schon geladen, s.o.
+ //load_object(SCHRANKMASTER2);
+ set_next_reset(3600); // Reset 1 x pro Std.
+
+ AddCmd(({"schrankliste"}), "Schrankliste");
+ AddCmd(({"schrankupdate"}), "SchrankUpdate");
+}
+
+public int clean_up(int ref) {return 0;} // verhindert Ausswappen des Raumes
+
+public varargs string GetExits( object viewer )
+{
+ return "";
+}
+
+string ANZAHL()
+{
+ return to_string( sizeof(schraenke) );
+}
+
+
+// cnt = Object des Containers
+// ver = Version des Containers (VERSION_STD+VERSION_OBJ von std.cont. + objekt...)
+// seher=Der Besitzer/Kaeufer
+// standort=Raum in dem der Container steht
+void RegisterCnt(mixed cnt, mixed ver, mixed seher, mixed standort)
+{
+ if (objectp(standort)) standort=object_name(standort);
+ if( !objectp(cnt) || !stringp(ver) || !stringp(seher) || !stringp(standort) )
+ {
+ log_file("swift/schraenker/bugs.log", "schrankmaster (RegisterCnt) *"
+ +to_string(cnt)+"*"+to_string(ver)+"*"+to_string(seher)+"*"
+ +to_string(standort)+"*\n");
+ return;
+ }
+ m_delete(schraenke,object_name(cnt));
+ schraenke+=([object_name(cnt): ver; seher; to_string(standort)]);
+ SetProp("schraenke", schraenke );
+ SCHRANKMASTER2->SetProp("schraenke", schraenke );
+}
+
+void RemoveCnt(mixed cnt, mixed seher)
+{
+ if( !objectp(cnt) || !stringp(seher) )
+ {
+ log_file("swift/schraenker/bugs.log", "schrankmaster (RemoveCnt) *"
+ +to_string(cnt)+"*"+to_string(seher)+"*\n");
+ return;
+ }
+ schraenke-=([object_name(cnt)]);
+ SetProp("schraenke", schraenke );
+ SCHRANKMASTER2->SetProp("schraenke", schraenke );
+}
+
+string fn(string was)
+{
+ string str,*strs;
+ strs=old_explode( was, "/" );
+ str=strs[sizeof(strs)-1];
+ strs=old_explode( str, "#" );
+ str=strs[0];
+ return str;
+}
+
+int Schrankliste()
+{
+ int i;
+ string str, *strs;
+ object cnt;
+ if(update_laeuft && !reset_laeuft) // Nicht waehrend eines Updates der Schraenke!
+ {
+ write("Update wird durchgefuehrt. Bitte bis zum Ende warten!\n");
+ return 1;
+ }
+ str="----------------------------------------------------------------------\n";
+ strs=m_indices(schraenke);
+ for(i=0;i<sizeof(strs);i++)
+ {
+ if( cnt=find_object(strs[i]) )
+ {
+ str+=(fn(object_name(cnt))+"....................")[0..20]+" ";
+ str+=schraenke[strs[i], 0]+" ";
+ str+=(schraenke[strs[i], 1]+"....................")[0..20]+" ";
+ str+=fn(schraenke[strs[i], 2])+"\n";
+ }
+ else
+ {
+ str+="Nicht auffindbaren Container aus Liste geloescht!\n";
+ schraenke-=([strs[i]]);
+ SetProp("schraenke", schraenke );
+ SCHRANKMASTER2->SetProp("schraenke", schraenke );
+ }
+ }
+ str+="----------------------------------------------------------------------\n";
+ if( TP && present(TP) ) //wurzel 19.03.01
+ TP->More(str);
+ return 1;
+}
+
+void Update_naechster_Schrank()
+{
+ int i;
+ object cnt, cnt_neu, *inv;
+ if( sizeof(cnts) ) // Es gibt noch Schraenke zum abarbeiten...
+ {
+ cnt=find_object(cnts[0]); // Schrank auswaehlen + Objekt suchen
+ if(cnt)
+ {
+ // Autoloadertruhe ist etwas spezieller zu updaten... Daher alternativer
+ // Mechanismus: UpdateMe() im Moebelstueck aufrufen. Wenn die Funktion
+ // etwas != 0 liefert, wird angenommen, dass diese Funktion das Update
+ // gemacht hat oder sich in Kuerze darum kuemmert. Sonst wird das alte
+ // Update gemacht.
+ // Das neue Moebelobjekt ist dafuer verantwortlich, sich beim
+ // Schrankmaster zu (de-)registrieren!
+ object oldenv=environment(cnt);
+ if (cnt->UpdateMe())
+ {
+ tell_room(TO, "...Update "+CAP(fn(cnts[0]))
+ +" in " + object_name(oldenv) + "\n" );
+ }
+ else
+ {
+ tell_room(TO, CAP(fn(cnts[0]))
+ +" in " + object_name(oldenv)
+ + " hat kein UpdateMe()!\n" );
+ }
+ }
+ else
+ {
+ tell_room(TO, "Nicht auffindbaren Container aus Liste geloescht!\n");
+ schraenke-=([cnts[0]]);
+ }
+ cnts-=({cnts[0]}); // Schrank aus Liste nehmen
+ call_out("Update_naechster_Schrank", 2); // Nur 1 Schrank-Update pro heart_beat!
+ }
+ else // Alle Schraenke abgearbeitet:
+ {
+ tell_room(TO, "*** Update abgeschlossen.\n");
+ SetProp("schraenke", schraenke );
+ SCHRANKMASTER2->SetProp("schraenke", schraenke );
+ update_laeuft=0;
+ }
+}
+
+int SchrankUpdate()
+{
+ if(update_laeuft) // Nicht waehrend eines Updates der Schraenke!
+ {
+ write("Update wird durchgefuehrt. Bitte bis zum Ende warten!\n");
+ return 1;
+ }
+ update_laeuft=1; // Ab sofort laeuft Update!
+ cnts=m_indices(schraenke);
+ tell_room(TO, "*** Update wird gestartet...\n");
+ Update_naechster_Schrank();
+ return 1;
+}
+
+
+void reset()
+{
+ reset_laeuft=1;
+ set_next_reset(3600); // Reset 1 x pro Std.
+ ::reset();
+ // Wirft Schraenke aus der Liste, die aus welchem Grund auch immer nicht mehr existieren
+ Schrankliste();
+ if( !(schraenke==QueryProp("schraenke")==SCHRANKMASTER2->QueryProp("schraenke")) )
+ log_file("swift/schraenker/reset.log", "schrankmaster (reset) "
+ +sizeof(schraenke)+" "
+ +sizeof(QueryProp("schraenke"))+" "
+ +sizeof(SCHRANKMASTER2->QueryProp("schraenke"))+"\n");
+ if( present("Interactive") )
+ tell_room(TO, "*** RESET ***\n");
+ reset_laeuft=0;
+}
+
+/*
+// Veraltete Funktionen, um Fehler abzufangen. Kann nach dem naechsten Reboot
+// geloescht werden !!!
+void AddCnt(mixed cnt, mixed ver, mixed seher, mixed standort)
+{
+ log_file("swift/schraenker/verloren.log", to_string(cnt)+"\n");
+}
+void EditCnt(mixed cnt, mixed ver, mixed seher, mixed standort)
+{
+ log_file("swift/schraenker/verloren.log", to_string(cnt)+"\n");
+}
+*/
diff --git a/d/seher/haeuser/moebel/spind.c b/d/seher/haeuser/moebel/spind.c
new file mode 100644
index 0000000..7473b10
--- /dev/null
+++ b/d/seher/haeuser/moebel/spind.c
@@ -0,0 +1,208 @@
+//--------------------------------------------------------------------------------
+// Name des Objects: Spind
+// Letzte Aenderung: 17.03.2001
+// Magier: Swift
+//--------------------------------------------------------------------------------
+#pragma strong_types,rtt_checks
+
+#include "schrankladen.h"
+#include "ansi.h"
+inherit LADEN("swift_std_container");
+
+#define VERSION_OBJ "3"
+
+string strall;
+
+protected void create()
+{
+ if (!clonep(TO)) return;
+ swift_std_container::create();
+ SetProp(P_SHORT, "Ein Spind");
+ SetProp(P_LONG, BS(
+ "Dieser Stahlschrank ist vor allem fuer spartanische Raeume gedacht. Ebenso "
+ +"wie sein Gegenstueck, der Kleiderschrank, verfuegt er ueber eine Menge "
+ +"Regale, in denen er riesige Ausruestungsmengen aufnehmen kann.")
+ +"@@cnt_status@@");
+ AddId(({"spind", "schrank", "stahlschrank"}));
+ SetProp("cnt_version_obj", VERSION_OBJ);
+ SetProp(P_NAME, "Spind");
+ SetProp(P_GENDER, MALE);
+ SetProp(P_WEIGHT, 5000); // Gewicht 5 Kg
+ SetProp(P_MAX_WEIGHT, 1000000); // Es passen fuer 1000 kg Sachen rein.
+ SetProp(P_WEIGHT_PERCENT, 100); // Dafuer macht er auch nix leichter :)
+ SetProp(P_MAX_OBJECTS, 100); // Mehr sollte nicht sein, lt. Tiamak.
+ SetProp(P_VALUE, 0); // Kein materieller Wert. Ist eh nicht verkaufbar.
+ SetProp(P_NOBUY, 1); // Wird im Laden zerstoert, falls er verkauft wird.
+ SetProp(P_NOGET, "Das geht nicht. "+Name(WER,1)+" haftet wie magisch am Boden.\n");
+ SetProp(P_MATERIAL, ({MAT_MISC_METAL, MAT_MISC_MAGIC}) );
+ SetProp(P_INFO, "Versuchs mal mit: \"skommandos "+QueryProp(P_IDS)[1]+"\" !\n");
+ SetProp("obj_cmd", "sliste [Objekt-Id] [Kleidungs-/Ruestungstyp]\n"
+ +" Kleidungs-/Ruestungstypen: Helme, Umhaenge, Ruestungen, Hosen, Schuhe,\n"
+ +" Handschuhe, Guertel, Amulette, Ringe, Koecher,\n"
+ +" Schilde, Sonstiges\n");
+ AD(({"regal", "regale"}), BS("Durch die Regale kommt etwas Ordnung in die "
+ +"vielen Sachen, die man in den Schrank stecken kann. Du kannst Dir z.B. "
+ +"eine Liste bestimmter Kleidungs-/Ruestungstypen des Schrankinhaltes "
+ +"mit dem Befehl \"sliste\" anschauen. (Das geht natuerlich nur bei "
+ +"offenem Schrank!"));
+
+ AddCmd(({"sliste"}), "auflistung");
+}
+
+varargs int PreventInsert(object ob)
+{
+ // Nur Ruestung/Kleidung hat in diesem Container was verloren!
+ if ((ob->IsClothing() || ob->QueryProp(P_ARMOUR_TYPE))
+ && !ob->QueryProp(P_WEAPON_TYPE) )
+ {
+ return ::PreventInsert(ob);
+ }
+
+ write( BS("In "+name(WEN,1)+" kannst Du nur Ruestungs-/Kleidungsstuecke legen!"));
+ return 1;
+}
+
+int auflistung2(string was, string nf_str1, string nf_str2, int alles)
+{
+ string obshort, suche, *strs;
+ object *obs;
+ int i;
+ mapping suchobs;
+ switch(was)
+ {
+ case "helme" : suche=AT_HELMET; break;
+ case "umhaenge" : suche=AT_CLOAK; break;
+ case "ruestungen" : suche=AT_ARMOUR; break;
+ case "hosen" : suche=AT_TROUSERS; break;
+ case "schuhe" : suche=AT_BOOT; break;
+ case "handschuhe" : suche=AT_GLOVE; break;
+ case "guertel" : suche=AT_BELT; break;
+ case "amulette" : suche=AT_AMULET; break;
+ case "ringe" : suche=AT_RING; break;
+ case "koecher" : suche=AT_QUIVER; break;
+ case "schilde" : suche=AT_SHIELD; break;
+ case "sonstiges" : suche=AT_MISC; break;
+ default : write("Fehler: Ungueltiger Kleidungs-/Ruestungstyp. "
+ +"Folgende Typen gibt es:\n"+nf_str1+nf_str2);
+ return 1; break;
+ }
+ obs=all_inventory();
+ suchobs=([]);
+ for(i=0;i<sizeof(obs);i++)
+ {
+ obshort=obs[i]->QueryProp(P_SHORT);
+ if(obshort=="Nichts besonderes") // keine P_SHORT ?
+ obshort=obs[i]->Name(WER); // Hoffen wir mal dass das Obj. nen Namen hat.
+ if(obs[i]->QueryProp(P_ARMOUR_TYPE)==suche) // Gesuchter ArmourType gefunden...
+ {
+ if(suchobs[obshort]) // P_SHORT des Obj. schon im mapping?
+ {
+ if( obs[i]->QueryProp(P_AMOUNT) )
+ suchobs[obshort]+=obs[i]->QueryProp(P_AMOUNT); // Dann den Zaehler um Amount hoch!
+ else
+ suchobs[obshort]+=1; // Dann den Zaehler um 1 hoch!
+ }
+ else
+ {
+ if( obs[i]->QueryProp(P_AMOUNT) )
+ suchobs+=([obshort: obs[i]->QueryProp(P_AMOUNT)]);
+ else
+ suchobs+=([obshort: 1]);
+ }
+ }
+ }
+ strs=m_indices(suchobs);
+ if(sizeof(strs))
+ {
+ if(!alles)
+ {
+ strall+=Name(WER,1)+" enthaelt folgende "+CAP(was)+":\n";
+ strall+="------------------------------------------------------------\n";
+ }
+ else
+ strall+=ANSI_BOLD+"=== "+CAP(was)+":\n"+ANSI_NORMAL;
+ for(i=0;i<sizeof(strs);i++)
+ {
+ if(suchobs[strs[i]] > 1)
+ strall+=strs[i]+". ("+suchobs[strs[i]]+")\n";
+ else
+ strall+=strs[i]+".\n";
+ }
+ }
+ else
+ if(!alles)
+ strall+=Name(WER,1)+" enthaelt keine "+CAP(was)+"!\n";
+ return 1;
+}
+
+int auflistung(string str)
+{
+ string *strs, ob_id, was, nf_str1,nf_str2;
+ strall="";
+ nf_str1=" (Helme, Umhaenge, Ruestungen, Hosen, Schuhe, Handschuhe,\n"
+ +" Guertel, Amulette, Ringe, Koecher, Schilde, Sonstiges)\n";
+ nf_str2="Syntax: sliste [Objekt-Id] [Kleidungs-/Ruestungstyp|\"alles\"]\n"
+ +"Bsp.: sliste "+QueryProp(P_IDS)[1]+" "+"helme\n"
+ +" sliste "+QueryProp(P_IDS)[1]+" alles\n";
+ notify_fail("Fehler: Ohne Parameter klappt das nicht.\n"+nf_str2);
+ if(!str) return 0;
+ if(present(str)==TO) // Ueberpruefe, ob dieses Objekt gemeint ist!
+ {
+ write("Fehler: Es fehlt ein Kleidungs-/Ruestungstyp. Folgende Typen gibt es:\n"
+ +nf_str1+nf_str2);
+ return 1;
+ }
+ strs=old_explode(str, " ");
+ notify_fail("Fehler: Du musst eine gueltige Objekt-Id angeben!\n"
+ +nf_str2);
+ if( sizeof(strs) < 2 ) return 0; // Nur 1 Par. und der ist nicht die Objekt-Id
+ if( sizeof(strs) == 2 ) // Anzahl Par. = 2
+ {
+ ob_id=strs[0];
+ was=strs[1];
+ if( IST_ZAHL(was) ) // Objekt-Id z.B. mit "schrank 2" angesprochen?
+ if(present(ob_id+" "+was)==TO) // Falls dieses Objekt gemeint ist und kein 3. Par!
+ {
+ write("Fehler: Es fehlt ein Kleidungs-/Ruestungstyp. Folgende Typen gibt es:\n"
+ +nf_str1+nf_str2);
+ return 1;
+ }
+ else
+ return 0;
+ }
+ else if( sizeof(strs) == 3 )
+ {
+ ob_id=strs[0]+" "+strs[1];
+ was=strs[2];
+ }
+ else // Anzahl erforderlicher Parameter ueberschritten!
+ return 0;
+ if(present(ob_id)!=TO) // Ueberpruefe, ob auch dieses Objekt gemeint ist!
+ return 0;
+ if(QueryProp(P_CNT_STATUS)!=CNT_STATUS_OPEN)
+ {
+ write("Dazu muesste "+name(WER,1)+" geoeffnet sein.\n");
+ return 1;
+ }
+//--- Hier ist Parameterpruefung zu Ende.
+ was=LOWER(was);
+ if(was!="alles")
+ auflistung2(was, nf_str1, nf_str2, 0);
+ else
+ {
+ auflistung2("helme", nf_str1, nf_str2, 1);
+ auflistung2("umhaenge", nf_str1, nf_str2, 1);
+ auflistung2("ruestungen", nf_str1, nf_str2, 1);
+ auflistung2("hosen", nf_str1, nf_str2, 1);
+ auflistung2("schuhe", nf_str1, nf_str2, 1);
+ auflistung2("handschuhe", nf_str1, nf_str2, 1);
+ auflistung2("guertel", nf_str1, nf_str2, 1);
+ auflistung2("amulette", nf_str1, nf_str2, 1);
+ auflistung2("ringe", nf_str1, nf_str2, 1);
+ auflistung2("koecher", nf_str1, nf_str2, 1);
+ auflistung2("schilde", nf_str1, nf_str2, 1);
+ auflistung2("sonstiges", nf_str1, nf_str2, 1);
+ }
+ TP->More(strall);
+ return 1;
+}
diff --git a/d/seher/haeuser/moebel/swift_std_container.c b/d/seher/haeuser/moebel/swift_std_container.c
new file mode 100644
index 0000000..90f4986
--- /dev/null
+++ b/d/seher/haeuser/moebel/swift_std_container.c
@@ -0,0 +1,611 @@
+//----------------------------------------------------------------------------
+// Name des Objects: Standard_Container
+// Letzte Aenderung: 21.03.2001
+// Magier: Swift
+// Dieses File wird anstelle von /std/container inherited, so dass dem Objekt
+// erweiterte Moeglichkeiten zur Verfuegung stehen.
+//
+// 07.12.2005 (Seleven): Kurzbeschreibung ausblendbar gemacht
+// 30.06.2007 (Zesstra): create der BP wird nicht mehr abgebrochen. Auf die
+// Art wird es dem Nutzer dieses Standardobjekt ueberlassen, ob er die BP
+// initialisieren will oder nicht.
+// 01.07.2007 (Zesstra): Update der Moebel ruft erstmal UpdateMe() in den
+// Moebeln auf. Wenn das != 0 liefert, ist UpdateMe() fuer das Update
+// zustaendig und muss das machen.
+// Ausserdem kleine Aenderung im Registrieren (nimmt auch Obekte als
+// Standort)
+// Weiterhin Moebel umgezogen nach /p/seher/moebel/ und in diesem File
+// GetOwner() definiert, welches "Swift" zurueckgibt. Wer hiervon erbt,
+// sollte damit also sein eigenes GetOwner() definieren.
+// glob. Variablen auf 'nosave' geaendert.
+//----------------------------------------------------------------------------
+
+
+// Fuer Testzwecke ist es moeglich, dem entsprechenden Objekt die Property
+// "test" auf 1 zu setzen, damit ist dann so ziemlich alles erlaubt.
+// Man sollte die Property aber unbedingt wieder entfernen, sonst ist es z.B.
+// moeglich, einen Schrank von Seherhaus A nach Seherhaus B oder sogar hinaus
+// zu verschieben !!!
+
+#pragma strong_types,save_types,rtt_checks
+
+#include <container.h>
+inherit "/std/container";
+
+#include "schrankladen.h"
+
+#define VERSION_STD "9"
+
+nosave int hauserlaubnis;
+nosave string zweitieerlaubnis;
+nosave string *erlaubnis;
+
+int erlaubt();
+
+protected void create()
+{
+ //if (!clonep(TO)) return;
+ ::create();
+ SetProp(P_SHORT, "Ein Standard_Container von Swift");
+ SetProp(P_CNT_STATUS,CNT_STATUS_CLOSED);
+ SetProp(P_TRANSPARENT, 0);
+ SetProp(P_LOG_FILE,"seleven/schraenker"); // Seleven 06.04.2006
+ SetProp("cnt_hausfreunde", ({}) );
+ SetProp("cnt_erlaubnis", ({}) );
+ SetProp("cnt_zweitieerlaubnis", "" );
+ SetProp("cnt_version_std", VERSION_STD);
+
+ hauserlaubnis=0;
+ zweitieerlaubnis="";
+ erlaubnis=({});
+
+ set_next_reset(3600); // 1 x pro Std. Reset!
+
+ AddCmd(({"oeffne"}), "oeffnen");
+ AddCmd(({"schliess", "schliesse"}), "schliessen");
+ AddCmd(({"serlaube"}), "erlaubnis");
+ AddCmd(({"skommandos"}), "skommandos");
+ AddCmd(({"verschieb", "verschiebe"}), "verschieben");
+ AddCmd(({"zertruemmer", "zertruemmere"}), "zertruemmern");
+ //Seleven 07.12.2005:
+ AddCmd(({"sverstecke","sversteck"}),"verstecken");
+ AddCmd(({"shole","shol"}),"zeigen");
+}
+
+// Zesstra, 1.7.07, fuers Hoerrohr
+string GetOwner() {return "swift";}
+
+static string QueryHausbesitzer()
+{
+ return CAP(to_string(ETO->QueryOwner())); // z.B.: Swift
+}
+
+
+
+static string QueryTP()
+{
+ return CAP(geteuid(TP)); // z.B.: Swift
+}
+
+int oeffnen(string str)
+{
+ notify_fail("Was moechtest Du oeffnen?\n");
+ if(!str) return 0;
+ if(present(str)!=TO) // Ueberpruefe, ob auch dieses Objekt gemeint ist!
+ return 0;
+ if(QueryProp(P_CNT_STATUS)==CNT_STATUS_OPEN)
+ {
+ write(Name(WER,1)+" ist doch schon geoeffnet!\n");
+ return 1;
+ }
+ if( !erlaubt() )
+ {
+ write("Ein magisches Kraftfeld verhindert das Oeffnen "+name(WESSEN,1)+"!\n");
+ return 1;
+ }
+ write("Du oeffnest "+name(WEN)+".\n");
+ say(TP->Name(WER)+" oeffnet "+name(WEN)+".\n", ({TP}) );
+ SetProp(P_CNT_STATUS,CNT_STATUS_OPEN);
+ SetProp(P_TRANSPARENT, 1);
+ return 1;
+}
+
+int schliessen(string str)
+{
+ notify_fail("Was moechtest Du schliessen?\n");
+ if(!str) return 0;
+ if(present(str)!=TO) // Ueberpruefe, ob auch dieses Objekt gemeint ist!
+ return 0;
+ if(QueryProp(P_CNT_STATUS)==CNT_STATUS_CLOSED)
+ {
+ write(Name(WER,1)+" ist doch schon geschlossen!\n");
+ return 1;
+ }
+ if( !erlaubt() )
+ {
+ write("Ein magisches Kraftfeld verhindert das Schliessen "+name(WESSEN,1)+"!\n");
+ return 1;
+ }
+ write("Du schliesst "+name(WEN)+".\n");
+ say(TP->Name(WER)+" schliesst "+name(WEN)+".\n", ({TP}) );
+ SetProp(P_CNT_STATUS,CNT_STATUS_CLOSED);
+ SetProp(P_TRANSPARENT, 0);
+ return 1;
+}
+
+string cnt_status()
+{
+ return Name(WER,1)+" ist "
+ +(QueryProp(P_CNT_STATUS)?"geschlossen":"geoeffnet")+".\n";
+}
+
+int erlaubt()
+{
+ if( QueryProp("test") ) return 1; // Zu Testzwecken!
+ if( QueryHausbesitzer()=="0" ) // Schrank steht nicht in einem Seherhaus!
+ {
+ tell_room(ETO, Name(WER,1)+" sollte nicht ausserhalb eines Seherhauses stehen.\n"
+ +"Bitte Mail an "+VERANTWORTLICHER_MAGIER+"!\n");
+ return 0;
+ }
+ if( QueryTP() == QueryHausbesitzer() ) // Der Besitzer des Hauses selbst
+ return 1;
+ if(hauserlaubnis)
+ {
+ if( member(SHVERWALTER->HausProp(LOWER(QueryHausbesitzer()), 2),
+ QueryTP()) != -1 ) // Hausfreunde
+ return 1;
+ }
+ if(zweitieerlaubnis!="") // Zweities
+ {
+ if( TP->QueryProp(P_SECOND) == zweitieerlaubnis )
+ return 1;
+ }
+ if( sizeof(erlaubnis) )
+ {
+ if( member(erlaubnis, QueryTP()) != -1 ) // Sonstige Personen die berechtigt sind
+ return 1;
+ }
+ return 0;
+}
+
+void cnt_open()
+{
+ SetProp(P_CNT_STATUS,CNT_STATUS_OPEN);
+ SetProp(P_TRANSPARENT, 1);
+}
+
+int erlaubnis_liste()
+{
+ int i;
+ string *strs,str;
+ if( QueryHausbesitzer() != QueryTP() && !QueryProp("test") )
+ {
+ write( BS("Nur "+QueryHausbesitzer()+" darf Berechtigungen "
+ +name(WESSEN,1)+" abfragen!"));
+ return 1;
+ }
+ write("=============================================================================\n");
+ if(hauserlaubnis)
+ {
+ strs=SHVERWALTER->HausProp(LOWER(QueryHausbesitzer()), 2);
+ write(BS("Folgende Freunde Deines Hauses duerfen "+name(WEN,1)
+ +" oeffnen/schliessen:"));
+ str="";
+ if(sizeof(strs))
+ {
+ for(i=0;i<sizeof(strs);i++)
+ {
+ str+=strs[i];
+ if(i<sizeof(strs)-1)
+ str+=", ";
+ }
+ }
+ else
+ str="Du hast keiner Person Zugriff auf Dein Haus gewaehrt...\n";
+ write(BS(str));
+ }
+ else
+ write(BS("Die Freunde Deines Hauses duerfen "+name(WEN,1)
+ +" nicht oeffnen/schliessen."));
+ write("-----------------------------------------------------------------------------\n");
+ if(zweitieerlaubnis!="")
+ {
+ if( zweitieerlaubnis==geteuid(TP) )
+ write(BS( "Alle Deine Zweities duerfen "+name(WEN,1)+" oeffnen/schliessen."));
+ else
+ write(BS( "Alle Zweities von "+CAP(zweitieerlaubnis)+" duerfen "+name(WEN,1)
+ +" oeffnen/schliessen."));
+ write("-----------------------------------------------------------------------------\n");
+ }
+ strs=QueryProp("cnt_erlaubnis");
+ if(sizeof(strs))
+ {
+ write(BS("Folgende sonstige Personen duerfen "+name(WEN,1)
+ +" oeffnen/schliessen:"));
+ str="";
+ for(i=0;i<sizeof(strs);i++)
+ {
+ str+=strs[i];
+ if(i<sizeof(strs)-1)
+ str+=", ";
+ }
+ write(BS(str));
+ }
+ else
+ write(BS("Es gibt keine sonstigen Personen, die "+name(WEN,1)
+ +" oeffnen/schliessen duerfen."));
+ write("=============================================================================\n");
+ return 1;
+}
+
+int erlaubnis(string str)
+{
+ string *strs,wen,nf_str;
+ nf_str="Syntax: serlaube [Objekt-Id] [Spielername|\"hausfreunde\"|\"zweities\"]\n"
+ +"Bsp.: serlaube "+QueryProp(P_IDS)[1]+" hausfreunde\n"
+ +" serlaube "+QueryProp(P_IDS)[1]+" zweities\n"
+ +" serlaube "+QueryProp(P_IDS)[1]+" geordi\n"
+ +" serlaube "+QueryProp(P_IDS)[1]+" (Listet Spieler mit Erlaubnis)\n";
+ notify_fail("Fehler: Ohne Parameter klappt das nicht.\n"+nf_str);
+ if(!str) return 0;
+ if(present(str)==TO) // Falls Par==Obj. und kein 2./3. Par.
+ {
+ erlaubnis_liste(); // Liste der Erlaubten ausgeben!
+ return 1;
+ }
+ notify_fail("Fehler: Du musst eine gueltige Objekt-Id angeben!\n"+nf_str);
+ strs=old_explode(str, " ");
+ if( sizeof(strs) < 2 ) // Falls nur 1 Par.
+ return 0; // Anzahl erforderlicher Parameter unterschritten!
+ else if( sizeof(strs) == 2 )
+ {
+ str=strs[0];
+ wen=strs[1];
+ if( IST_ZAHL(wen) )
+ if(present(str+" "+wen)==TO) // Falls 2 Par. und dies das Obj. ist ohne 3. Par.
+ {
+ erlaubnis_liste(); // Liste der Erlaubten ausgeben!
+ return 1;
+ }
+ else
+ return 0;
+ }
+ else if( sizeof(strs) == 3 )
+ {
+ str=strs[0]+" "+strs[1];
+ wen=strs[2];
+ }
+ else // Anzahl erforderlicher Parameter ueberschritten!
+ return 0;
+ if(present(str)!=TO) // Ueberpruefe, ob auch dieses Objekt gemeint ist!
+ return 0;
+ if( !erlaubt() && !QueryProp("test") )
+ {
+ write( BS("Nur "+QueryHausbesitzer()+" darf Berechtigungen "
+ +name(WESSEN,1)+" aendern!"));
+ return 1;
+ }
+ if(wen=="hausfreunde")
+ {
+ if(hauserlaubnis)
+ {
+ hauserlaubnis=0;
+ SetProp("cnt_hausfreunde", ({}) );
+ }
+ else
+ {
+ hauserlaubnis=1;
+ SetProp("cnt_hausfreunde", SHVERWALTER->HausProp(LOWER(QueryHausbesitzer()), 2) );
+ }
+ write( BS("Die Freunde Deines Seherhauses duerfen "+name(WEN,1)+" jetzt "
+ +(!hauserlaubnis?"nicht mehr ":"")+"oeffnen/schliessen."));
+ return 1;
+ }
+ if(wen=="zweities")
+ {
+ if(zweitieerlaubnis!="") // Zweities erlaubt?
+ zweitieerlaubnis=""; // dann verbieten!
+ else // ansonsten:
+ {
+ if( TP->QueryProp(P_SECOND) ) // Selbst ein Zweitie?
+ zweitieerlaubnis=LOWER(TP->QueryProp(P_SECOND)); // Die Zweities vom Erstie erlauben!
+ else // sonst:
+ zweitieerlaubnis=geteuid(TP); // Eigene Ersties erlauben!
+ }
+ SetProp("cnt_zweitieerlaubnis", zweitieerlaubnis );
+ if(zweitieerlaubnis!="")
+ write( BS(CAP(zweitieerlaubnis)+"'s Zweities duerfen "+name(WEN,1)+" jetzt "
+ +(zweitieerlaubnis==""?"nicht mehr ":"")+"oeffnen/schliessen."));
+ return 1;
+ }
+ wen=CAP(wen);
+ if( file_size("//save//"+LOWER(wen[0..0])+"//"+LOWER(wen)+".o") != -1 ) // Spieler gibt es auch!
+ {
+ if( member(erlaubnis, wen) != -1 ) // Spieler hat Erlaubnis -> verbieten!
+ {
+ erlaubnis-=({wen});
+ write( BS( wen+" darf "+name(WEN,1)+" jetzt nicht mehr oeffnen/schliessen."));
+ }
+ else
+ {
+ erlaubnis+=({wen});
+ write( BS( wen+" darf "+name(WEN,1)+" jetzt oeffnen/schliessen."));
+ }
+ SetProp("cnt_erlaubnis", erlaubnis);
+ return 1;
+ }
+ else
+ write("Es gibt keinen Spieler namens "+wen+"!\n");
+ return 1;
+}
+
+varargs int skommandos(string str)
+{
+ notify_fail( "Fehler: Dieser Befehl benoetigt eine gueltige Objekt-Id als Parameter.\n"
+ +"Beispiel: skommandos "+QueryProp(P_IDS)[1]+"\n");
+ if(!str) return 0;
+ if(present(str)!=TO ) // Bin ich gemeint?
+ return 0;
+ write("=============================================================================\n");
+ write("Aktuelle Version: "+QueryProp("cnt_version_std")+QueryProp("cnt_version_obj")+"\n");
+ write( BS(Name(WER,1)+" kann nur in diesem Seherhaus verwendet werden, "
+ +"da "+QueryPronoun(WER)+" speziell dafuer gekauft wurde. "+CAP(QueryPronoun(WER))
+ +" verfuegt ueber folgende Kommandos:")
+ +"-----------------------------------------------------------------------------\n"
+ +"oeffne [Objekt-Id]\n"
+ +" oeffnet "+name(WEN,1)+"\n\n"
+ +"schliesse [Objekt-Id]\n"
+ +" schliesst "+name(WEN,1)+"\n\n"
+ +"serlaube [Objekt-Id] [Spielername|\"hausfreunde\"|\"zweities\"]\n"
+ +" Erlaubt Personen, "+name(WEN,1)+" mitzubenutzen.\n"
+ +" serlaube + Objekt-Id (ohne Spielername/hausfreunde)\n"
+ +" listet alle Personen mit Zugriff auf "+name(WEN,1)+"\n\n"
+ +"verschiebe [Objekt-Id] nach [Ausgang]\n"
+ +" Damit kannst Du "+name(WEN,1)+" innerhalb Deines Seherhauses verschieben.\n\n"
+ //Seleven 07.12.2005
+ +"sverstecke [Objekt-Id]\n"
+ +" Damit machst Du "+name(WEN,1)+" unsichtbar.\n"
+ +"shole [Objekt-Id] hervor\n"
+ +" Damit machst Du "+name(WEN,1)+" wieder sichtbar.\n"
+ // Bis hier
+ +"zertruemmer [Objekt-Id]\n"
+ +" Damit zerstoerst Du "+name(WEN,1)+".\n\n");
+
+
+ if( QueryProp("obj_cmd") )
+ write( QueryProp("obj_cmd")+"\n" );
+
+ write("[Objekt-Id] muss eine gueltige Id sein, in diesem Fall z.B. "
+ +QueryProp(P_IDS)[1]+"\n");
+ write("=============================================================================\n");
+
+
+ return 1;
+}
+
+int verschieben(string str)
+{
+ string was, wohin, zielraum,nf_str;
+ nf_str="Syntax: verschiebe [Objekt-Id] nach [Richtung]\n"
+ +"Bsp.: verschiebe "+QueryProp(P_IDS)[1]+" nach osten\n";
+ notify_fail("Fehler: Ohne Parameter klappt das nicht.\n"+nf_str);
+ if(!str) return 0;
+ if(sscanf(str,"%s nach %s", was, wohin) != 2)
+ return 0;
+ notify_fail("Fehler: Du musst eine gueltige Objekt-Id angeben!\n"+nf_str);
+ if(present(was)!=TO) // Ueberpruefe, ob auch dieses Objekt gemeint ist!
+ return 0;
+ if( QueryHausbesitzer() != QueryTP() && !QueryProp("test") )
+ {
+ write( BS("Nur "+QueryHausbesitzer()+" darf "+name(WEN,1)+" verschieben!"));
+ return 1;
+ }
+ if( member(m_indices(ETO->QueryProp(P_EXITS)), wohin) != -1 ) // Ausgang vorhanden?
+ {
+ zielraum=ETO->QueryProp(P_EXITS)[wohin];
+ if( strstr(zielraum, LOWER(QueryHausbesitzer())+"raum", 0) != -1 ||
+ QueryProp("test") ) // Gleiches Seherhaus? Oder Test?
+ {
+ TO->move(zielraum, M_PUT);
+ write("Du verschiebst "+name(WEN,1)+" nach "+CAP(wohin)+".\n");
+ TP->move(zielraum, M_GO, "nach "+CAP(wohin), "schiebt "+name(WEN),
+ "schiebt "+name(WEN)+" herein");
+ if( present("Interactive", SCHRANKMASTER) )
+ tell_room(SCHRANKMASTER, TP->Name(WER)+" verschiebt "+name(WEN)+" nach "
+ +to_string(ETO)+".\n");
+ }
+ else
+ write( BS("Du kannst "+name(WEN,1)+" nicht in einen Raum ausserhalb "
+ +"Deines Hauses schieben!"));
+ }
+ else
+ write( BS("Es gibt keinen Ausgang namens \""+wohin+"\", wohin Du "
+ +name(WEN,1)+" verschieben koenntest.",78,"Fehler: ", BS_INDENT_ONCE));
+ return 1;
+}
+
+int zertruemmern(string str)
+{
+ string nf_str;
+ nf_str="Syntax: zertruemmer [Objekt-Id]\n"
+ +"Bsp.: zertruemmer "+QueryProp(P_IDS)[1]+"\n";
+ notify_fail("Fehler: Ohne Parameter klappt das nicht.\n"+nf_str);
+ if(!str) return 0;
+ notify_fail("Fehler: Du musst eine gueltige Objekt-Id angeben!\n"+nf_str);
+ if(present(str)!=TO) // Ueberpruefe, ob auch dieses Objekt gemeint ist!
+ return 0;
+ if( QueryHausbesitzer() != QueryTP() && !QueryProp("test") )
+ {
+ write( BS("Nur "+QueryHausbesitzer()+" darf "+name(WEN,1)+" zertruemmern!"));
+ return 1;
+ }
+ write( BS("Du zertruemmerst "+name(WEN)+" mit wuchtigen Schlaegen, bis "
+ +"nicht mal mehr Kruemel von "+QueryPronoun(WEM)+" uebrig sind."));
+ tell_room(ETO, BS( TP->Name(WER)+" zertruemmert "+name(WEN)+"."), ({TP}) );
+ call_other(SCHRANKMASTER,"???",0);
+ if( present("Interactive", SCHRANKMASTER) )
+ tell_room(SCHRANKMASTER, TP->Name(WER)+" zertruemmert "+name(WEN)+".\n");
+ SCHRANKMASTER->RemoveCnt(TO, geteuid(TP) );
+ remove(1);
+ if(TO) destruct(TO);
+ return 1;
+}
+
+int props2vars() // Fuer die Update-Funktion des Schrankmasters
+{
+ zweitieerlaubnis=QueryProp("cnt_zweitieerlaubnis")||"";
+ erlaubnis=QueryProp("cnt_erlaubnis")||({});
+ if( sizeof(QueryProp("cnt_hausfreunde")) )
+ hauserlaubnis=1;
+ else
+ hauserlaubnis=0;
+ if( QueryProp(P_CNT_STATUS) == CNT_STATUS_OPEN)
+ SetProp(P_TRANSPARENT, 1);
+ else
+ SetProp(P_TRANSPARENT, 0);
+ return 1;
+}
+
+void reset()
+{
+ set_next_reset(3600); // 1 x pro Std. Reset!
+ ::reset();
+}
+
+public varargs int remove(int silent)
+{
+ // Beim Schrankmaster abmelden, dann zerstoeren.
+ string uid="";
+ if (objectp(environment()))
+ {
+ uid=environment()->QueryOwner();
+ }
+ SCHRANKMASTER->RemoveCnt(TO, uid );
+ return ::remove(silent);
+}
+
+public int UpdateMe()
+{
+ if (!objectp(environment()))
+ return 0;
+ object cnt_neu=clone_object(load_name(ME)); // Neuen Schrank clonen
+ cnt_neu->move( environment(), M_NOCHECK ); // In selben Raum wie alten schieben...
+ cnt_neu->SetProp("cnt_status", QueryProp("cnt_status") );
+ cnt_neu->SetProp("cnt_hausfreunde", QueryProp("cnt_hausfreunde") );
+ cnt_neu->SetProp("cnt_erlaubnis", QueryProp("cnt_erlaubnis") );
+ cnt_neu->SetProp("cnt_zweitieerlaubnis", QueryProp("cnt_zweitieerlaubnis") );
+ cnt_neu->props2vars(); // Schrank liest gesetzte Props aus in eigene Vars
+ // Inventar bewegen
+ foreach(object inv: all_inventory(this_object()))
+ {
+ if( inv->IsUnit() ) // Units
+ inv->move(cnt_neu, M_NOCHECK|M_MOVE_ALL);
+ else // Normale Objekte
+ inv->move(cnt_neu, M_NOCHECK);
+ }
+ remove(1);
+ return 1;
+}
+
+// Eingebaut 07.12.2005 von Seleven
+// Die Kurzbeschreibung invis machen:
+static int verstecken (string str)
+{
+ string nf_str;
+ nf_str="Syntax: sverstecke [Objekt-Id]\n"
+ +"Bsp.: sverstecke "+QueryProp(P_IDS)[1]+"\n";
+ notify_fail("Fehler: Ohne Parameter klappt das nicht.\n"+nf_str);
+ if(!str || sizeof(str) == 0 || !stringp(str)) return 0;
+
+ notify_fail("Fehler: Du musst eine gueltige Objekt-Id angeben!\n"+nf_str);
+ if(present(str)!=TO) // Ueberpruefe, ob auch dieses Objekt gemeint ist!
+ return 0;
+
+ if( QueryHausbesitzer() != QueryTP() && !QueryProp("test") )
+ {
+ write( BS("Nur "+QueryHausbesitzer()+" darf "+name(WEN,1)+" verstecken!"));
+ return 1;
+ }
+ notify_fail("Du hast "+name(WEN,1)+" doch schon versteckt!\n");
+ if(QueryProp("versteckt") == 1) return 0;
+ write("Du versteckst "+name(WEN,1)+".\n");
+ SetProp("versteckt", 1);
+ return 1;
+}
+
+static int zeigen (string str)
+{
+ string nf_str;
+ nf_str="Syntax: shole [Objekt-Id] hervor\n"
+ +"Bsp.: shole "+QueryProp(P_IDS)[1]+" hervor\n";
+ notify_fail("Fehler: Ohne Parameter klappt das nicht.\n"+nf_str);
+ if(!str || sizeof(str) == 0 || !stringp(str)) return 0;
+ if(strstr(str,"hervor") != -1)
+ sscanf(str,"%s hervor",str);
+ notify_fail("Fehler: Du musst eine gueltige Objekt-Id angeben!\n"+nf_str);
+ if(present(str)!=TO) // Ueberpruefe, ob auch dieses Objekt gemeint ist!
+ return 0;
+
+ if( QueryHausbesitzer() != QueryTP() && !QueryProp("test") )
+ {
+ write( BS("Nur "+QueryHausbesitzer()+" darf "+name(WEN,1)+
+ " wieder hervorholen!"));
+ return 1;
+ }
+ notify_fail(Name(WER,1)+" ist doch gar nicht versteckt!\n");
+ if(QueryProp("versteckt") == 0) return 0;
+ write("Du holst "+name(WEN,1)+" aus dem Versteck.\n");
+ SetProp("versteckt", 0);
+ return 1;
+}
+
+
+mixed short()
+{
+ string sh;
+
+ // Unsichtbar? Dann gibts nichts zu sehen ...
+ if (QueryProp(P_INVIS)||!(sh=QueryProp(P_SHORT)))
+ return 0;
+
+ if(QueryProp(P_CNT_STATUS)==CNT_STATUS_OPEN)
+ {sh += " (geoeffnet)";}
+
+ if(QueryProp("versteckt") == 1) {sh = "";}
+ else sh += ".";
+
+ return process_string(sh)+"\n";
+}
+
+// hier nicht genutzt, zum Ueberschreiben gedacht.
+protected void SetBesitzer(string uid, string uuid) { }
+
+// nach dem move schauen, ob man in einem Seherhaus ist. Wenn ja, wird die
+// Funktion SetBesitzer() gerufen und ihr UID und UUID des Eigentuemers
+// uebergeben. Sollten UID und/oder UUID nicht bestimmbar sein, wird die
+// Funktion nicht gerufen.
+protected void NotifyMove(object dest, object oldenv, int method)
+{
+
+ ::NotifyMove(dest, oldenv, method);
+
+ if (dest
+ && strstr(object_name(dest),"/d/seher/haeuser/") == 0)
+ {
+ // (vermutlich) in einem Seherhaus
+ string uid = dest->QueryOwner();
+ // erstmal beim Schrankmaster anmelden.
+ SCHRANKMASTER->RegisterCnt(TO, QueryProp("cnt_version_std")
+ +":"+QueryProp("cnt_version_obj"), uid, dest);
+ // UUID rausfinden
+ mixed ret = (mixed)master()->get_userinfo(uid);
+ if ( pointerp(ret) && sizeof(ret) >= 5 )
+ {
+ // Username + "_" + CreationDate
+ SetBesitzer(uid, ret[0] + "_" + ret[5]);
+ }
+ // else: User unbekannt? -> jedenfalls keine initialisierung moeglich.
+ }
+}
+
diff --git a/d/seher/haeuser/moebel/tresor.c b/d/seher/haeuser/moebel/tresor.c
new file mode 100644
index 0000000..ecad6d7
--- /dev/null
+++ b/d/seher/haeuser/moebel/tresor.c
@@ -0,0 +1,78 @@
+//--------------------------------------------------------------------------------
+// Name des Objects: Tresor
+// Letzte Aenderung: 17.03.2001
+// Magier: Swift
+//--------------------------------------------------------------------------------
+#pragma strong_types,rtt_checks
+
+#include "schrankladen.h"
+inherit LADEN("swift_std_container");
+
+#define VERSION_OBJ "3"
+
+protected void create()
+{
+ if (!clonep(TO)) return;
+ swift_std_container::create();
+ SetProp(P_SHORT, "Ein Tresor");
+ SetProp(P_LONG, BS(
+ "Ein sehr stabiler und feuersicherer Tresor, an dem sich sicher schon so "
+ +"mancher Einbrecher eine Abfuhr geholt hat. Das magische Feld, das den "
+ +"Tresor umgibt, verhindert wohl auch Attacken magischer Art. So wuchtig "
+ +"und wichtig, wie dieser Klotz aussieht, vermutest Du wohl zu Recht, "
+ +"dass sich unsagbare Reichtuemer in seinem Inneren verbergen muessen.")
+ +"@@cnt_status@@");
+ AddId(({"tresor"}));
+ SetProp("cnt_version_obj", VERSION_OBJ);
+ SetProp(P_NAME, "Tresor");
+ SetProp(P_GENDER, MALE);
+ SetProp(P_WEIGHT, 5000); // Gewicht 5 Kg
+ SetProp(P_MAX_WEIGHT, 1000000); // Es passen fuer 1000 kg Sachen rein.
+ SetProp(P_WEIGHT_PERCENT, 100); // Dafuer macht er auch nix leichter :)
+ SetProp(P_MAX_OBJECTS, 100); // Mehr sollte nicht sein, lt. Tiamak.
+ SetProp(P_VALUE, 0); // Kein materieller Wert. Ist eh nicht verkaufbar.
+ SetProp(P_NOBUY, 1); // Wird im Laden zerstoert, falls er verkauft wird.
+ SetProp(P_NOGET, "Das geht nicht. "+Name(WER,1)+" haftet wie magisch am Boden.\n");
+ SetProp(P_MATERIAL, ({MAT_STEEL, MAT_MISC_MAGIC}) );
+ SetProp(P_INFO, "Versuchs mal mit: \"skommandos "+QueryProp(P_IDS)[1]+"\" !\n");
+
+ AD(({"feld"}), BS("Ein starkes magisches Feld umgibt "+name(WEN,1)+"."));
+ AD(({"klotz"}), BS(Name(WER,1)+" ist wahrlich ein Klotz, ausgesprochen wuchtig."));
+}
+
+varargs int PreventInsert(object ob)
+{
+ // Zuerst mal: Dinge, deren Wert >= 5000 Muenzen ist, duerfen rein, solange
+ // es keine Ruestungen oder Waffen sind!
+ if( ob->QueryProp(P_VALUE) >= 5000 && !ob->QueryProp(P_ARMOUR_TYPE) &&
+ !ob->QueryProp(P_WEAPON_TYPE) )
+ return ::PreventInsert(ob);
+ if( ob->id("\ngeld") || // Geld?
+ ob->QueryMaterialGroup(MATGROUP_PRECIOUS_METAL) || // Edelmetall?
+ ob->QueryMaterialGroup(MATGROUP_JEWEL) || // Edelstein?
+ ob->QueryMaterial(MAT_CRYSTAL) || // Kristall?
+ ob->QueryMaterial(MAT_IVORY) ) // Elfenbein?
+ {
+ if(!ob->QueryProp(P_WEAPON_TYPE) ) // Auf keinen Fall Waffen!
+ {
+ if( ob->QueryProp(P_ARMOUR_TYPE ) ) // Falls Ruestungsteil...
+ {
+ if( ob->QueryProp(P_ARMOUR_TYPE)==AT_RING ||
+ ob->QueryProp(P_ARMOUR_TYPE)==AT_AMULET ||
+ ob->QueryProp(P_ARMOUR_TYPE)==AT_MISC )
+ return ::PreventInsert(ob);
+ else
+ write(BS("Nur wertvolle Ringe und Amulette kannst Du in "+name(WEN,1)
+ +" stecken, evtl. noch andere wertvolle Sachen, aber auf keinen "
+ +"Fall Ruestungen oder Waffen!"));
+ }
+ else
+ return ::PreventInsert(ob);
+ }
+ else
+ write("Waffen kannst Du nicht in "+name(WEN,1)+" tun!\n");
+ }
+ write( BS("In "+name(WEN,1)+" kannst Du nur Geld und Edelsteine legen, evtl. auch "
+ +"wertvolle Objekte, z.B. aus Edelmetallen, Kristall oder Elfenbein!"));
+ return 1;
+}
diff --git a/d/seher/haeuser/moebel/verkaeufer.c b/d/seher/haeuser/moebel/verkaeufer.c
new file mode 100644
index 0000000..5143ab2
--- /dev/null
+++ b/d/seher/haeuser/moebel/verkaeufer.c
@@ -0,0 +1,311 @@
+//--------------------------------------------------------------------------------
+// Name des Objects: Verkaeufer (August vom SCHRAENKER)
+// Letzte Aenderung: 24.08.2006
+// Magier: Seleven
+//--------------------------------------------------------------------------------
+#pragma strong_types,rtt_checks
+
+#include <properties.h>
+#include <language.h>
+#include <moving.h>
+#include <wizlevels.h>
+#include <bank.h>
+
+#include "schrankladen.h"
+inherit "/std/npc";
+
+// Wenn im Laden bzw. im Environment von August die Prop "test" auf 1 gesetzt
+// wird, kostet der Kauf nichts. Jeder der ein Seherhaus besitzt, kann kaufen.
+
+// Fuer Prop im Spieler = individuellere Begruessung
+#define LASTVISIT "schrankladen_lastvisit"
+// 10% Rabatt fuer Leute, die intensiv testeten, Ideen fuer den Laden beisteuerten,
+// oder halfen, groessere Bugs zu beheben!
+#define RABATT ({"geordi","foobar","blood","lurchi", "eldaron"})
+
+// kaufe... andere im raum sollten vor der antwort sehen wer august nach was fragt
+
+protected void create()
+{
+ if(!clonep(TO)) return;
+ ::create();
+ SetProp(P_LOG_FILE,"seleven/schraenker"); // Seleven 06.04.2006
+ SP(P_SHORT, "August");
+ SP(P_LONG, BS(
+ "Das ist August, ein kleiner Zwerg und seines Zeichens Seher-Berater. "
+ +"Er versorgt Seher mit Eigenheim mit dem Mobiliar, das man braucht, "
+ +"will man sein Haus uebersichtlich halten und etwas Ordnung in die "
+ +"Sammlungen bringen, die sich in so einem Seherhaus zwangslaeufig "
+ +"anhaeufen. Im Gegensatz zu den meisten Zwergen sieht August nicht nur "
+ +"aus wie frisch geduscht, er steckt auch in einem feinen Anzug. So "
+ +"einen gepflegten Bart wie den von August hast Du vorher noch nie "
+ +"gesehen. Und dann duftet er auch noch nach irgendeinem exotischen "
+ +"Waesserchen. Waere nicht der gierige Blick in seinen Augen, koenntest "
+ +"Du wirklich zweifeln, dass es sich hier wirklich um einen Zwerg "
+ +"handelt.",78,0,1));
+ SP(P_NAME, "August");
+ SP(P_GENDER, MALE);
+ SP(P_ARTICLE, 0);
+ SP(P_RACE, "Zwerg");
+ // Arathorn, 2015-Okt-13, Zeile vor P_XP gezogen, damit auch sicher kein
+ // EK angezeigt wird.
+ create_default_npc(20);
+ SP(P_XP, 0);
+ AddId(({"august", "inhaber", "ladeninhaber", "besitzer",
+ "firmenbesitzer", "verkaeufer", "zwerg", "seher-berater"}));
+
+ SP(P_SIZE, 130);
+ SP(P_NO_ATTACK, BS("Die beruhigende Melodie scheint nicht nur zum "
+ +"Vergnuegen der Kunden zu erklingen. Du bringst es einfach "
+ +"nicht fertig, Deine Hand gegen August zu erheben!"));
+
+ AD(({"anzug"}), BS(Name(WER)+" steckt in einem feinen rotbraunen Anzug, "
+ +"in dem vermutlich auch ein Bettler koeniglich auf Dich wirken wuerde. "
+ +"Offensichtlich ist er nicht der Aermsten einer."));
+ AD(({"bettler"}), BS("Wie ein Bettler wirkt August nicht auf Dich."));
+ AD(({"waesserchen"}), BS("Es riecht koestlich. Schnupper doch mal!"));
+ AD(({"bart"}), BS("Der vermutlich weisse Bart wurde von Kuenstlerhand "
+ +"roetlich eingefaerbt und passt farblich vorzueglich zum Anzug."));
+ AD(({"kuenstlerhand"}), BS("Bestimmt hat August das nicht selbst gemacht."));
+ AD(({"mobiliar"}), BS("Das verkauft er hier."));
+ AD(({"augen"}), BS("Obwohl "+Name(WER)+" perfekte Manieren an den Tag "
+ +"legt, seine Augen verraten ihn. Die Dollarzeichen in seinem Blick "
+ +"sind nicht zu uebersehen."));
+ AD(({"dollarzeichen"}), BS("Eine Redensart. Keine Ahnung was das sein soll."));
+ AD(({"redensart"}), BS("Irgend ein Spruch, den Du irgendwo aufgeschnappt hast."));
+ AD(({"spruch"}), BS("Im Spruecheklopfen bist Du gut, oder?"));
+ AD(({"spruecheklopfen"}), BS("OK, ich geb auf. :)"));
+ AD(({"manieren"}), "Und das bei einem Zwerg!!!\n");
+
+ AddInfo(({"laden", "schraenker"}), "Der Schraenker ist mein Laden, "
+ +"und ich denke es ist ein guter Laden. Das Geschaeft laeuft, seit "
+ +"jeder Ordnung in seinem Seherhaus haben moechte. Und Seherhaeuser "
+ +"gibt es ja mehr als genug! :)", "sagt: ");
+ AddInfo(({"haeuser", "seherhaeuser"}), "Bei mir koennen Seher "
+ +"Mobiliar fuer ihr Seherhaus kaufen. Unsere Qualitaet ist weithin "
+ +"beruehmt. Ausserdem sind wir die einzigen auf dem Markt.", "grinst: ");
+ AddInfo(({"melodie"}), "lauscht vertraeumt.\n");
+ AddInfo(({"geld"}), "Sie haben doch welches?\n", "fragt besorgt: ");
+ // Seleven 01.04.2006: frage nach (schluessel)brett eingefuegt
+ AddInfo(({"mobiliar", "schrank", "schraenke", "truhe", "truhen", "kommode",
+ "kuehlschrank", "waffenschrank", "waffentruhe", "spind", "kleiderschrank","brett","schluesselbrett",
+ "muellcontainer", "zauberkiste", "tresor", "holztruhe","vitrine","pult","lesepult"}),
+ "Lesen Sie doch bitte die Preisliste an der Wand.", "sagt: ");
+ AddInfo(({"liefern", "lieferung"}), "Wir liefern sofort.", "sagt: ");
+ AddInfo(({"bart"}), "Es ist ein schoener Bart, nicht? :)", "fragt: ");
+ AddInfo(({"augen"}), "Was haben Sie an denen auszusetzen?", "fragt: ");
+ AddInfo(({"dusche"}), "Jeden Morgen. Das ist leider Pflicht. Und 364 mal "
+ +"zu oft :(", "sagt: ");
+ AddInfo(({"pflicht", "pflichten"}), "Als Ladeninhaber hat man deren "
+ +"viele!", "sagt: ");
+ AddInfo(({"anzug"}), "Ein echter Armgani!", "verkuendet stolz: ");
+ AddInfo(({"armgani"}), "Du kennst Armgani nicht?", "fragt naseruempfend: ");
+ AddInfo(({"geordi"}), "Von ihm stammt die urspruengliche Geschaeftsidee "
+ +"fuer den SCHRAENKER. Dafuer bekommt er bei uns auch Rabatt!", "erzaehlt: ");
+ AddInfo(({"august"}), "Wollen Sie sich ueber mich lustig machen?", "fragt drohend: ");
+ AddInfo(({"rabatt"}), "Nur Stammkunden, die uns schon brauchbare Ideen "
+ +"geliefert haben, oder die uns beim Aufbau des Geschaefts geholfen haben, "
+ +"gewaehren wir Rabatt.", "sagt: ");
+ AddInfo(({"ideen"}), "Es muessen brauchbare Ideen sein.", "sagt: ");
+ AddInfo(({"stammkunde", "stammkunden"}), "Einige kommen oefter vorbei.", "sagt: ");
+ AddInfo(({"aufbau"}), "Es kommt mir noch so vor, als waers gestern gewesen.", "sagt: ");
+ AddInfo(({"kunde", "kunden"}), "Ich hoffe mal, dass SIE der Kunde sind!?", "sagt: ");
+
+ AddCmd(({"kauf", "kaufe", "bestell", "bestelle"}), "container_kaufen");
+ AddCmd(({"schnupper", "schnuppere"}), "schnuppern");
+}
+
+int schnuppern()
+{
+ write(BS("Ein betoerender Duft umgibt August, und verdeckt jeglichen Geruch, "
+ +"den Du von sonstigen Zwergen gewohnt bist."));
+ return 1;
+}
+
+static string anrede()
+{
+ switch( TP->QueryProp(P_GENDER) )
+ {
+ case MALE : return "mein Herr"; break;
+ case FEMALE : return "meine Dame"; break;
+ }
+ return "mein H... D... Wasauchimmer";
+}
+
+void begruessung(object pl, string txt)
+{
+ if( objectp(pl) && present(pl) )
+ tell_room(ETO, "\n"+txt);
+}
+
+void init()
+{
+ ::init();
+ if (!interactive(TP) || TP->QueryProp(P_INVIS))
+ return 0; // Keine Meldungen wenn invis oder kein Spieler!
+ if(TP->QueryProp(LASTVISIT) < time()-3600) // laenger als 1 Std. nicht da gewesen
+ {
+ if( member(RABATT, geteuid(TP)) != -1 )
+ call_out("begruessung", 0, TP, BS("Herzlichst Willkommen in meinem "
+ +"bescheidenen Laden, "+TP->name(WER)+". Es ist jedesmal eine Freude, "
+ +"Sie zu sehen!",78, Name(WER)+" sagt: "));
+ else
+ call_out("begruessung", 0, TP, BS("Willkommen in meinem bescheidenen Laden, "
+ +anrede()+".",78, Name(WER)+" sagt: "));
+ }
+ else // schonmal innerhalb 1 Std. da gewesen?
+ {
+ if( member(RABATT, geteuid(TP)) != -1 )
+ call_out("begruessung", 0, TP, BS("Hallo, "+TP->name(WER)+". "
+ +"Sie konnten es ja nicht lange ohne mich aushalten, aber Stammkunden "
+ +"sind mir die liebsten Kunden. Womit kann ich Ihnen diesmal "
+ +"dienen?",78, Name(WER)+" sagt: "));
+ else
+ call_out("begruessung", 0, TP, BS("Guten Tag, "+anrede()+". "
+ +"Ich freue mich, dass Sie meinen Laden so bald wieder besuchen kommen! "
+ +"Womit kann ich Ihnen diesmal dienen?",78, Name(WER)+" sagt: "));
+ }
+
+ TP->SetProp(LASTVISIT, time() );
+}
+
+int container_kaufen(string str)
+{
+ string cnt_file;
+ int preis;
+ object zielraum,cnt,ob;
+ tell_room(ETO, TP->Name(WER)+" wendet sich wegen eines Kaufs an "
+ +Name(WEN)+".\n", ({TP}) );
+ if( (query_wiz_level(TP) >= SEER_LVL && query_wiz_level(TP) < LEARNER_LVL) ||
+ ETO->QueryProp("test") ) // TP ist Seher, oder Testmodus.
+ {
+ catch(call_other("/d/seher/haeuser/"+geteuid(TP)+"raum0", "???", 0));
+ if( !zielraum=find_object("/d/seher/haeuser/"+geteuid(TP)+"raum0") )
+ {
+ tell_room(ETO, BS("Tut mir leid, "+anrede()+". Voraussetzung fuer eine "
+ +"Lieferung unserer Artikel ist ein begehbares "
+ +"Seherhaus.",78, Name(WER)+" sagt: "));
+ return 1;
+ }
+ notify_fail( BS("Tut mir leid, "+anrede()+". So einen Artikel fuehren wir nicht. "
+ +"Bitte lesen Sie die Preisliste an der Wand. Dort koennen Sie sich genau "
+ +"darueber informieren, ueber welche Artikel wir zur Zeit "
+ +"verfuegen.",78, Name(WER)+" sagt: "));
+ if(!str) return 0;
+ switch(str)
+ {
+ case "1" :
+ case "kommode" : cnt_file="kommode";
+ preis=3799;
+ break;
+ case "2" :
+ case "kleiderschrank": cnt_file="kleiderschrank";
+ preis=5899;
+ break;
+ case "3" :
+ case "spind" : cnt_file="spind";
+ preis=5299;
+ break;
+ case "4" :
+ case "kuehlschrank" : cnt_file="kuehlschrank";
+ preis=3499;
+ break;
+ case "5" :
+ case "waffenschrank" : cnt_file="waffenschrank";
+ preis=5899;
+ break;
+ case "6" :
+ case "waffentruhe" : cnt_file="waffentruhe";
+ preis=5399;
+ break;
+ case "7" :
+ case "tresor" : cnt_file="tresor";
+ preis=4499;
+ break;
+ case "8" :
+ case "zauberkiste" : cnt_file="zauberkiste";
+ preis=7999;
+ break;
+ case "9" :
+ case "muellcontainer": cnt_file="muellcontainer";
+ preis=999;
+ break;
+ // Seleven 01.04.2006
+ case "10" :
+ case "schluesselbrett": cnt_file="schluesselbrett";
+ preis=499;
+ break;
+ case "11" :
+ case "duschkabine": cnt_file="wasch";
+ preis=3499;
+ break;
+ case "12":
+ case "holztruhe":
+ cnt_file="autoloadertruhe";
+ preis=74999;
+ break;
+ case "13":
+ case "vitrine":
+ cnt_file="vitrine";
+ preis=49999;
+ break;
+ case "14":
+ case "lesepult":
+ cnt_file="lesepult";
+ preis=60000;
+ break;
+ default: return 0; break;
+ }
+ if( member(RABATT, geteuid(TP)) != -1 ) // 10% Rabatt fuer bestimmte Leute,
+ preis=preis/100*90; // die Ideen fuer den Laden beisteuerten.
+ if( !ETO->QueryProp("test") )
+ {
+ if( !TP->QueryMoney() )
+ {
+ tell_room(ETO, BS("Ohne Geld bekommen Sie bei uns nichts, "+anrede()
+ +". Wir sind kein Wohlfahrtsinstitut!",78, Name(WER)+" sagt: "));
+ return 1;
+ }
+ if( TP->QueryMoney() < preis )
+ {
+ tell_room(ETO, BS( CAP(anrede())+", Sie haben zuwenig Geld dabei. "
+ +"Der Preis fuer dieses Objekt ist "+preis
+ +" Muenzen.",78, Name(WER)+" sagt: "));
+ return 1;
+ }
+ TP->AddMoney(-preis); // Spieler Geld abziehen
+ ZENTRALBANK->PayIn(preis); // Geld auf die Bank.
+ }
+ cnt=clone_object( LADEN(cnt_file) );
+ cnt->move(zielraum, M_PUT|M_SILENT);
+ tell_room(ETO, TP->Name(WER)+" kauft "+cnt->name(WEN)+".\n", ({TP}) );
+ tell_room(ETO, BS("Es ist ein Vergnuegen, mit Ihnen Geschaefte zu machen, "
+ +anrede()+"! Wenn Sie in Ihr Haus zurueckkehren, werden Sie die Ware bereits "
+ +"vorfinden, so schnell arbeiten wir.",78, Name(WER)+" sagt: "));
+ tell_room(zielraum, BS("Mit Knall und Schwefelduft erscheint ein kleines, "
+ +"verhutzeltes Maennchen. Es traegt einen gruenen Anzug und eine gruene "
+ +"Kappe, auf der in gelbem Schriftzug \"SCHRAENKER\" steht. Das Maennchen "
+ +"stellt "+cnt->name(WEN)+" ab und verschwindet auf dem gleichen Wege, wie "
+ +"es hereingekommen ist."));
+ if( present("Interactive", SCHRANKMASTER) )
+ tell_room(SCHRANKMASTER, TP->Name(WER)+" kauft "+name(WEN)+".\n");
+ SCHRANKMASTER->RegisterCnt(cnt, cnt->QueryProp("cnt_version_std")
+ +cnt->QueryProp("cnt_version_obj"), geteuid(TP),
+ "/d/seher/haeuser/"+geteuid(TP)+"raum0");
+ return 1;
+ }
+ else if(query_wiz_level(TP) >= LEARNER_LVL ) // TP ist Magier.
+ {
+ tell_room(ETO, BS("Tut mir leid, "+anrede()+". An Magier liefern wir nichts. "
+ +"Das ist ein Prinzip des Hauses, und Prinzipien sind dazu da, dass "
+ +"sie eingehalten werden. ",78, Name(WER)+" sagt: "));
+ return 1;
+ }
+ else // TP ist Spieler, kein Seher oder Magier.
+ {
+ tell_room(ETO, BS("Tut mir leid, "+anrede()+". Wir liefern nur an Seher. "
+ +"Aber da ich Sie als strebsame und erfolgreiche Person ansehe, "
+ +"bin ich sicher, dass wir uns bald wiedersehen!",78, Name(WER)+" sagt: "));
+ return 1;
+ }
+}
diff --git a/d/seher/haeuser/moebel/vitrine.c b/d/seher/haeuser/moebel/vitrine.c
new file mode 100644
index 0000000..ae5bb96
--- /dev/null
+++ b/d/seher/haeuser/moebel/vitrine.c
@@ -0,0 +1,339 @@
+/************************************************************************************
+Vitrine fuer die Pokale
+Autor: Miril
+letzte Aenderung:
+05.09.2011
+************************************************************************************/
+
+#include <properties.h>
+#include <defines.h>
+#include <wizlevels.h>
+#include "/d/ebene/miril/fraternitas/fraternitas.h"
+#include "/d/ebene/miril/fraternitas/trophy.h"
+#pragma strong_types,rtt_checks
+#include "/d/seher/haeuser/moebel/moebel.h"
+#include "/d/seher/haeuser/haus.h"
+
+inherit LADEN("swift_std_container");
+
+string besitzer;
+int staub;
+string *trophynamen;
+
+static string my_long();
+static string staub_descr();
+void GetTrophyDetails();
+string *GetAllTrophyNames();
+void NeueDetails();
+
+protected void create()
+{
+ if (!clonep(this_object())){
+ set_next_reset(-1);
+ return;
+ }
+ set_next_reset(86400);
+ ::create();
+ besitzer="";
+ staub=0;
+ SetProp(P_NAME,"Vitrine");
+ SetProp(P_SHORT,"Eine Vitrine");
+ Set(P_LONG,#'my_long,F_QUERY_METHOD);
+ SetProp(P_GENDER,FEMALE);
+ SetProp(P_MATERIAL,([MAT_GLASS:50,MAT_EBONY:50]));
+ SetProp(P_VALUE,10000);
+ SetProp(P_WEIGHT,500000);
+ SetProp(P_MAX_OBJECTS,0);
+ SetProp(P_MAX_WEIGHT,0);
+ SetProp(H_FURNITURE,1);
+ SetProp(P_NOGET,"Die Vitrine ist viel zu schwer.\n");
+ SetProp("cnt_version_obj",2);
+ GetTrophyDetails();
+ AddId(({"\nmiril_pokal_vitrine","vitrine"}));
+
+ NeueDetails();
+
+ AddCmd(({"saeubere","saeuber","reinige","reinig","mach","mache"}),
+ "saeuber_cmd");
+
+ AddCmd(({"stelle","stell"}),"stell_cmd");
+ RemoveCmd(({"serlaube"}));
+
+}
+
+void reset(){
+ ++staub;
+ set_next_reset(86400);
+ ::reset();
+ return;
+}
+
+void SetBesitzer(string uid,string uuid){
+ besitzer=uuid;
+ GetTrophyDetails();
+ return;
+}
+
+string QueryBesitzer(){
+ return besitzer;
+}
+
+void NeueDetails(){
+ AddDetail(({"holz","ebenholz"}),BS("Die Vitrine besteht teilweise "
+ "aus Ebenholz. Tueren, Deckel und Einlegeboeden sind aus Glas."));
+ AddDetail(({"tueren","tuer","glastueren","glastuer","deckel"}),BS(
+ "Durch das Glas kannst Du ins Innere der Vitrine gucken."));
+ AddDetail(({"inneres","gegenstaende","gegenstand"}),
+ BS("Dort kann man Pokale hineinstellen, aber nicht wieder "
+ "herausnehmen."));
+ AddDetail(({"glas","scheibe","scheiben"}),
+ BS("Glas ist praktisch, solange es sauber ist: "
+ "Man kann dadurch ins Innere schauen."));
+ AddDetail(({"reihe","platz","einlegeboeden","einlegeboden","boeden",
+ "boden"}),
+ BS("Die vielen Boeden bieten Platz fuer viele Pokale!"));
+ return;
+}
+
+
+static string my_long(){
+ if(staub<21)
+ return BS(
+ "Die schlichte Vitrine aus dunklem Holz eignet sich hervorragend, um "
+ "wertvolle Gegenstaende darin auszustellen. Hinter den beiden Glastueren "
+ "siehst Du eine Reihe von Einlegeboeden, die ebenfalls aus Glas bestehen. "+
+ staub_descr());
+ else return BS(staub_descr());
+}
+
+
+static string staub_descr(){
+ string text;
+ text="";
+ switch(staub){
+ case 0..1:
+ text=
+ "Die Vitrine ist hervorragend gepflegt. Du siehst keinerlei Staub "+
+ "darin, und die Scheiben sind voellig klar.\n";
+ AddDetail(({"staub"}),BS("Keiner zu sehen."));
+ break;
+ case 2..4:
+ text=
+ "Die Vitrine ist gut gepflegt. Es liegt kaum Staub darin, und die "+
+ "Tueren sind klar.\n";
+ AddDetail(({"staub"}),BS("Man sieht nur wenig davon."));
+ break;
+ case 5..7:
+ text=
+ "Die Vitrine ist in einem ordentlichen Zustand, allerdings sammelt "+
+ "sich so langsam Staub auf den Einlegeboeden.\n";
+ AddDetail(({"staub"}),BS("So langsam koennte man die "
+ "Vitrine saeubern!"));
+ AddDetail(({"zustand"}),BS("Noch ist er ordentlich."));
+ break;
+ case 8..10:
+ text=
+ "Die Vitrine wirkt schon etwas staubig. Man erkennt auch, dass "+
+ "der ein oder andere Fingerabdruck die Tueren ziert.";
+ AddDetail(({"staub","fingerabdruck","tueren","glastueren",
+ "deckel","glastuer","tuer","zustand"}),
+ BS("Es lohnt sich jetzt schon, die Vitrine zu saeubern."));
+ break;
+ case 11..15:
+ text=
+ "Du hast den Eindruck, dass die Vitrine langsam einmal gesaeubert "+
+ "werden koennte. Die Einlegeboeden sind staubig und zahlreiche "+
+ "Fingerabdruecke sind auf den Glastueren zu sehen.";
+ break;
+ case 16..20:
+ text=
+ "Die Vitrine macht einen recht ungepflegten Eindruck. Innen ist "+
+ "sie schon sehr verstaubt und auch die Tueren sind schon recht "+
+ "dreckig geworden.";
+ AddDetail(({"staub"}),BS("Nun wird es aber wirklich Zeit, die "
+ "Vitrine zu saeubern. Sonst sieht man bald nichts mehr darin."));
+ break;
+ case 21..25:
+ text=
+ "Die Vitrine ist total zugestaubt. Ueber den Glastueren sind "+
+ "erste Spinnweben zu erkennen und die Scheiben sind schon fast "+
+ "blind von all den Fingerabdruecken unaufmerksamer Gaeste.";
+ RemoveDetail(m_indices(QueryProp(P_DETAILS)));
+ AddDetail(({"spinnweben","dreck","vitrine","glastueren","glastuer",
+ "tueren","tuer","scheibe","scheiben","deckel"}),
+ "Unter dem ganzen Dreck ist leider nichts mehr zu erkennen.\n");
+ AddDetail(({"gaeste","gast","fingerabdruck","fingerabdruecke"}),
+ "Die Gaeste sind sicher schuld an dem Dreck.\n");
+ break;
+ case 26..30:
+ text=
+ "Du kannst die Vitrine unter der dicken Staubschicht kaum noch "+
+ "erkennen und die Glastueren sind blind geworden.";
+ AddDetail(({"staubschicht","schicht"}),
+ BS("Die ist verdammt dick und undurchsichtig."));
+ break;
+ default:
+ text=
+ "Dass sich unter dieser Ansammlung von Spinnweben und Staub noch "+
+ "eine Vitrine mit Glastueren verbergen soll, kannst Du kaum glauben. "+
+ "Jedenfalls kann man durch die voellig blinden Scheiben nichts "+
+ "mehr erkennen.";
+ AddDetail(({"dreck","spinnweben","staub","ansammlung"}),"Pfui Deibel!\n");
+ }
+ return text;
+}
+
+static int saeuber_cmd(string str){
+ string text;
+ if(!str) return 0;
+ if(strstr(str,"vitrine")<0) return 0;
+ switch(staub){
+ case 0:
+ write("Das ist noch nicht noetig!\n");
+ return 1;
+ break;
+ case 1..20:
+ text="Du reinigst die Vitrine gruendlich. Das wurde auch langsam "
+ "Zeit!";
+ if(getuuid(TP)!=besitzer)
+ text+="Du fragst Dich, wieso Du fremde Moebel reinigst.";
+
+ write(BS(text));
+ say(BS(TPN+" reinigt die Vitrine gruendlich. Das wurde auch langsam "
+ "Zeit!\n"),TP);
+ staub=0; //Hier darf noch jemand helfen!
+ break;
+ case 21..30:
+ text="Du beginnst die Vitrine zu reinigen. ";
+ if(getuuid(TP)!=besitzer){
+ text+="Nach einiger Zeit fragst Du Dich, ob Du eigentlich spinnst, "+
+ "denn das ist ueberhaupt nicht Deine Vitrine. Du laesst von dem "+
+ "Vorhaben wieder ab.";
+ say(BS(TPN+" faengt kurz an, die Vitrine zu reinigen, laesst es aber "
+ "schnell wieder sein."),TP);
+ }
+ else{
+ text+="Das dauert eine ganze Weile, aber dann strahlt die Vitrine "
+ "wieder.";
+ say(BS(TPN+" beginnt die Vitrine zu reinigen. Das dauert eine ganze "
+ "Weile, aber dann strahlt sie wieder."),TP);
+ staub=0;
+ }
+ write(BS(text));
+ break;
+ default:
+ if(getuuid(TP)!=besitzer)
+ write("Das dreckige Teil fasst Du nicht an!\n");
+ else{
+ write(BS(
+ "Du schrubbst und schrubbst und es scheint kein Ende zu nehmen. "
+ "Als Du schon langsam aufgeben willst, ist so langsam ein kleiner "
+ "Erfolg zu sehen. Du nimmst Dir vor, die Vitrine in Zukunft "
+ "haeufiger zu reinigen!"));
+ say(BS(
+ TPN+" schrubbt stundenlang an der Vitrine rum, bis sie endlich "
+ "wieder richtig sauber ist."),TP);
+ staub=0;
+ }
+ }
+ if(staub==0){
+ RemoveDetail(m_indices(QueryProp(P_DETAILS)));
+ GetTrophyDetails();
+ NeueDetails();
+ }
+ return 1;
+}
+
+void GetTrophyDetails(){
+ string *trophyliste,*shorts;
+ mapping trophydetails;
+
+ shorts=({});
+
+ trophyliste=MIRIL_TROPHYMASTER->GetPlacedTrophies(besitzer);
+
+ foreach( string tr : trophyliste )
+ shorts+=({ MIRIL_TROPHYMASTER->GetTrophyShort(tr) });
+
+ shorts = sort_array(shorts, #'>);
+ if(!sizeof(shorts))
+ AddDetail(({"pokale","pokal","in vitrine"}),
+ "Bislang ist die Vitrine noch leer.\n");
+ else
+ AddDetail(({"pokale","pokal","in vitrine"}),
+ "Du siehst folgende Pokale in der Vitrine:\n"
+ +implode(shorts,".\n")+".\n");
+
+ foreach( string tr : trophyliste )
+ {
+ AddDetail( MIRIL_TROPHYMASTER->GetTrophyIds(tr),
+ BS(MIRIL_TROPHYMASTER->GetTrophyLong(tr)));
+
+ trophydetails = MIRIL_TROPHYMASTER->GetTrophyDetails(tr);
+ if ( !sizeof(trophydetails) )
+ continue;
+ foreach ( mixed det, string det_desc : trophydetails )
+ AddDetail( det, BS(det_desc) );
+ }
+ return;
+}
+
+string *GetAllTrophyNames(){
+ int i,anzahl;
+ string *trophynamen;
+
+ trophynamen=({});
+
+ foreach(string bla:MIRIL_TROPHYMASTER->GetTrophyListe())
+ trophynamen+=MIRIL_TROPHYMASTER->GetTrophyIds(bla);
+
+ return trophynamen;
+}
+
+static int stell_cmd(string str){
+ string was,identifier;
+ int resultat;
+ object ob;
+ if(!str) return 0;
+ if(strstr(str,"vitrine")<0) return 0;
+ notify_fail("Das ist nicht Deine Vitrine!\n");
+ if(getuuid(TP)!=besitzer)
+ return 0;
+ notify_fail("Die Syntax ist: stelle <gegenstand> in vitrine!\n");
+ if(sscanf(str,"%s in vitrine",was)!=1)
+ return 0;
+
+ notify_fail("Die Vitrine sollte schon offen sein.\n");
+ if(QueryProp(P_CNT_STATUS)!=CNT_STATUS_OPEN && !IS_LEARNER(TP))
+ return 0;
+ notify_fail("Du solltest die Vitrine vorher erstmal saeubern!\n");
+ if(staub>20)
+ return 0;
+ notify_fail("Das kannst Du leider nicht in die Vitrine stellen!\n");
+ if(member(GetAllTrophyNames(),lower_case(was))<0
+ && lower_case(was)!="pokal")
+ return 0;
+ notify_fail("Das hast Du nicht!\n");
+ if(!ob=present(was,TP))
+ return 0;
+ notify_fail("Das kannst Du leider nicht in die Vitrine stellen!\n");
+ if(!ob->id("\nmiril_pokal"))
+ return 0;
+
+ identifier=ob->QueryIdentifier();
+ resultat=MIRIL_TROPHYMASTER->PlaceTrophy(getuuid(TP),identifier);
+
+ notify_fail("Hier stimmt etwas nicht, sag bitte einem Erzmagier Bescheid! "
+ "Resultat="+resultat+"\n");
+ if(resultat!=1)
+ return 0;
+ write(BS("Du stellst den Pokal in die Vitrine und bewunderst ihn noch ein "
+ "wenig.\n"));
+ say(TPN+" stellt einen Pokal in die Vitrine.\n",TP);
+ GetTrophyDetails();
+ ob->remove();
+ if(ob)
+ destruct(ob);
+ return 1;
+}
+
diff --git a/d/seher/haeuser/moebel/waffenschrank.c b/d/seher/haeuser/moebel/waffenschrank.c
new file mode 100644
index 0000000..e36abc9
--- /dev/null
+++ b/d/seher/haeuser/moebel/waffenschrank.c
@@ -0,0 +1,220 @@
+//--------------------------------------------------------------------------------
+// Name des Objects: Waffenschrank
+// Letzte Aenderung: 22.03.2001
+// Magier: Swift
+//--------------------------------------------------------------------------------
+/* Changelog
+ * 21.05.2007, Zesstra
+ Kampfstaebe auf Hinweis von tassram ergaenzt.
+*/
+#pragma strong_types,rtt_checks
+
+#include "schrankladen.h"
+#include <ansi.h>
+#include <class.h>
+inherit LADEN("swift_std_container");
+
+#define VERSION_OBJ "6"
+
+string strall;
+
+protected void create()
+{
+ if (!clonep(TO)) return;
+ swift_std_container::create();
+ SetProp(P_SHORT, "Ein Waffenschrank");
+ SetProp(P_LONG, BS(
+ "Mit den Waffen, die in diesen massiven Holzschrank passen, koenntest "
+ +"Du ein ganzes Soeldnerheer ausruesten. Fuer jede Waffengattung gibt "
+ +"es einen eigenen Platz, damit man auch alles gleich findet, sollte "
+ +"man es brauchen.")+"@@cnt_status@@");
+ AddId(({"waffenschrank", "holzschrank", "schrank"}));
+ SetProp("cnt_version_obj", VERSION_OBJ);
+ SetProp(P_NAME, "Waffenschrank");
+ SetProp(P_GENDER, MALE);
+ SetProp(P_WEIGHT, 5000); // Gewicht 5 Kg
+ SetProp(P_MAX_WEIGHT, 1000000); // Es passen fuer 1000 kg Sachen rein.
+ SetProp(P_WEIGHT_PERCENT, 100); // Dafuer macht er auch nix leichter :)
+ SetProp(P_MAX_OBJECTS, 100); // Mehr sollte nicht sein, lt. Tiamak.
+ SetProp(P_VALUE, 0); // Kein materieller Wert. Ist eh nicht verkaufbar.
+ SetProp(P_NOBUY, 1); // Wird im Laden zerstoert, falls er verkauft wird.
+ SetProp(P_NOGET, "Das geht nicht. "+Name(WER,1)+" haftet wie magisch am Boden.\n");
+ SetProp(P_MATERIAL, ({MAT_MISC_WOOD, MAT_MISC_MAGIC}) );
+ SetProp(P_INFO, "Versuchs mal mit: \"skommandos "+QueryProp(P_IDS)[1]+"\" !\n");
+ SetProp("obj_cmd", "sliste [Objekt-Id] [Waffentyp|\"alles\"]\n"
+ +" Waffentypen: Schwerter, Speere, Aexte, Keulen, Kampfstaebe, Messer, Peitschen,\n"
+ +" Fernwaffen, Munition, Sonstiges, Unzuordbar\n");
+
+ AD(({"platz"}), BS("Der Schrank bietet Platz fuer jede erdenkliche "
+ +"Waffengattung."));
+
+ AddCmd(({"sliste"}), "auflistung");
+}
+
+varargs int PreventInsert(object ob)
+{
+ // Keine Waffe? Hat in diesem Container nix verloren!
+ if( !ob->QueryProp(P_WEAPON_TYPE) && !ob->QueryProp(P_WC) &&
+ !ob->id("\nBumerang") && !ob->is_class_member(CL_AMMUNITION) &&
+ !ob->id("\ngorseilpfeil") )
+ {
+ write( BS("In "+name(WEN,1)+" kannst Du nur Waffen + Munition legen!"));
+ return 1;
+ }
+ else
+ return ::PreventInsert(ob);
+}
+
+int auflistung2(string was, string nf_str1, string nf_str2, int alles)
+{
+ string obshort, suche, *strs;
+ object *obs;
+ int i;
+ mapping suchobs;
+ switch(was)
+ {
+ case "munition" : suche=WT_AMMU; break;
+ case "aexte" : suche=WT_AXE; break;
+ case "keulen" : suche=WT_CLUB; break;
+ case "messer" : suche=WT_KNIFE; break;
+ case "fernwaffen" : suche=WT_RANGED_WEAPON; break;
+ case "speere" : suche=WT_SPEAR; break;
+ case "schwerter" : suche=WT_SWORD; break;
+ case "peitschen" : suche=WT_WHIP; break;
+ case "sonstiges" : suche=WT_MISC; break;
+ case "kampfstaebe": suche=WT_STAFF; break;
+ case "unzuordbar" : suche="unzuordbar"; break;
+ default : write("Fehler: Ungueltiger Waffentyp. "
+ +"Folgende Typen gibt es:\n"+nf_str1+nf_str2);
+ return 1; break;
+ }
+ obs=all_inventory();
+ suchobs=([]);
+ for(i=0;i<sizeof(obs);i++)
+ {
+ obshort=to_string(obs[i]->QueryProp(P_SHORT));
+ if(obshort=="Ein Bumerang@@fliegt@@")
+ obshort="Ein Bumerang";
+ else if(obshort=="Nichts besonderes" || obshort=="0") // keine P_SHORT ?
+ obshort=obs[i]->Name(WER); // Hoffen wir mal dass das Obj. nen Namen hat.
+ if(obs[i]->QueryProp(P_WEAPON_TYPE)==suche || // Gesuchter WeaponType gefunden...
+ (!obs[i]->QueryProp(P_WEAPON_TYPE) && suche=="unzuordbar") )
+ {
+ if(suchobs[obshort]) // P_SHORT des Obj. schon im mapping?
+ {
+ if( obs[i]->QueryProp(P_AMOUNT) )
+ suchobs[obshort]+=obs[i]->QueryProp(P_AMOUNT); // Dann den Zaehler um Amount hoch!
+ else
+ suchobs[obshort]+=1; // Dann den Zaehler um 1 hoch!
+ }
+ else
+ {
+ if( obs[i]->QueryProp(P_AMOUNT) )
+ suchobs+=([obshort: obs[i]->QueryProp(P_AMOUNT)]);
+ else
+ suchobs+=([obshort: 1]);
+ }
+ }
+ }
+ strs=m_indices(suchobs);
+ if(sizeof(strs))
+ {
+ if(!alles)
+ {
+ if(suche=="unzuordbar")
+ strall+=Name(WER,1)+" enthaelt folgende nicht zuordbare Waffen:\n";
+ else
+ strall+=Name(WER,1)+" enthaelt folgende "+CAP(was)+":\n";
+ strall+="------------------------------------------------------------\n";
+ }
+ else
+ {
+ if(suche=="unzuordbar")
+ strall+=ANSI_BOLD+"=== Nicht zuordbare Waffen:\n"+ANSI_NORMAL;
+ else
+ strall+=ANSI_BOLD+"=== "+CAP(was)+":\n"+ANSI_NORMAL;
+ }
+ for(i=0;i<sizeof(strs);i++)
+ {
+ if(suchobs[strs[i]] > 1)
+ strall+=strs[i]+". ("+suchobs[strs[i]]+")\n";
+ else
+ strall+=strs[i]+".\n";
+ }
+ }
+ else
+ if(!alles)
+ strall+=Name(WER,1)+" enthaelt keine "+CAP(was)+"!\n";
+ return 1;
+}
+
+int auflistung(string str)
+{
+ string *strs, ob_id, was, nf_str1,nf_str2;
+ strall="";
+ nf_str1=" (Schwerter, Speere, Aexte, Keulen, Kampfstaebe, Messer, Peitschen,\n"
+ +" Fernwaffen, Munition, Sonstiges, Unzuordbar)\n";
+ nf_str2="Syntax: sliste [Objekt-Id] [Waffentyp]\n"
+ +"Bsp.: sliste "+QueryProp(P_IDS)[1]+" "+"schwerter\n"
+ +" sliste "+QueryProp(P_IDS)[1]+" alles\n";
+ notify_fail("Fehler: Ohne Parameter klappt das nicht.\n"+nf_str2);
+ if(!str) return 0;
+ if(present(str)==TO) // Ueberpruefe, ob dieses Objekt gemeint ist!
+ {
+ write("Fehler: Es fehlt ein Waffentyp. Folgende Typen gibt es:\n"
+ +nf_str1+nf_str2);
+ return 1;
+ }
+ strs=old_explode(str, " ");
+ notify_fail("Fehler: Du musst eine gueltige Objekt-Id angeben!\n"
+ +nf_str2);
+ if( sizeof(strs) < 2 ) return 0; // Nur 1 Par. und der ist nicht die Objekt-Id
+ if( sizeof(strs) == 2 ) // Anzahl Par. = 2
+ {
+ ob_id=strs[0];
+ was=strs[1];
+ if( IST_ZAHL(was) ) // Objekt-Id z.B. mit "schrank 2" angesprochen?
+ if(present(ob_id+" "+was)==TO) // Falls dieses Objekt gemeint ist und kein 3. Par!
+ {
+ write("Fehler: Es fehlt ein Waffentyp. Folgende Typen gibt es:\n"
+ +nf_str1+nf_str2);
+ return 1;
+ }
+ else
+ return 0;
+ }
+ else if( sizeof(strs) == 3 )
+ {
+ ob_id=strs[0]+" "+strs[1];
+ was=strs[2];
+ }
+ else // Anzahl erforderlicher Parameter ueberschritten!
+ return 0;
+ if(present(ob_id)!=TO) // Ueberpruefe, ob auch dieses Objekt gemeint ist!
+ return 0;
+ if(QueryProp(P_CNT_STATUS)!=CNT_STATUS_OPEN)
+ {
+ write("Dazu muesste "+name(WER,1)+" geoeffnet sein.\n");
+ return 1;
+ }
+//--- Hier ist Parameterpruefung zu Ende.
+ was=LOWER(was);
+ if(was!="alles")
+ auflistung2(was, nf_str1, nf_str2, 0);
+ else
+ {
+ auflistung2("aexte", nf_str1, nf_str2, 1);
+ auflistung2("keulen", nf_str1, nf_str2, 1);
+ auflistung2("kampfstaebe", nf_str1, nf_str2, 1);
+ auflistung2("messer", nf_str1, nf_str2, 1);
+ auflistung2("speere", nf_str1, nf_str2, 1);
+ auflistung2("schwerter", nf_str1, nf_str2, 1);
+ auflistung2("peitschen", nf_str1, nf_str2, 1);
+ auflistung2("fernwaffen", nf_str1, nf_str2, 1);
+ auflistung2("munition", nf_str1, nf_str2, 1);
+ auflistung2("sonstiges", nf_str1, nf_str2, 1);
+ auflistung2("unzuordbar", nf_str1, nf_str2, 1);
+ }
+ TP->More(strall);
+ return 1;
+}
diff --git a/d/seher/haeuser/moebel/waffentruhe.c b/d/seher/haeuser/moebel/waffentruhe.c
new file mode 100644
index 0000000..098aaa7
--- /dev/null
+++ b/d/seher/haeuser/moebel/waffentruhe.c
@@ -0,0 +1,43 @@
+//--------------------------------------------------------------------------------
+// Name des Objects: Waffentruhe
+// Letzte Aenderung: 22.03.2001
+// Magier: Swift
+//--------------------------------------------------------------------------------
+/* Changelog
+ * 21.05.2007, Zesstra
+ Da Waffenschrank und Waffentruhe sich praktisch nicht unterscheiden, bis
+ auf 10 Zeilen im Create, erbt nun die Waffentruhe den Waffenschrank und
+ ueberschreibt einfach die passenden Props.
+*/
+#pragma strong_types,rtt_checks
+
+#include "schrankladen.h"
+#include <ansi.h>
+#include <class.h>
+//inherit LADEN("swift_std_container");
+inherit LADEN("waffenschrank");
+
+#define VERSION_OBJ "7"
+
+protected void create() {
+ if (!clonep(TO)) return;
+ ::create();
+ SetProp(P_SHORT, "Eine Waffentruhe");
+ SetProp(P_LONG, BS(
+ "Diese Stahltruhe ist speziell zur Aufnahme von grossen Waffenmengen "
+ "gefertigt. Verschiedene Faecher fuer die einzelnen Waffentypen erleichtern "
+ "die Suche nach Deinem bevorzugten Waffentyp.")+"@@cnt_status@@");
+ RemoveId(({"waffenschrank", "holzschrank", "schrank"}));
+ AddId(({"waffentruhe", "stahltruhe", "truhe"}));
+ SetProp("cnt_version_obj", VERSION_OBJ);
+ SetProp(P_NAME, "Waffentruhe");
+ SetProp(P_GENDER, FEMALE);
+ SetProp(P_MATERIAL, ({MAT_MISC_METAL, MAT_MISC_MAGIC}) );
+ SetProp(P_INFO, "Versuchs mal mit: \"skommandos "+QueryProp(P_IDS)[1]+
+ "\" !\n");
+ AD(({"faecher"}), BS("Fuer jeden Waffentyp gibt es ein eigenes Fach, so dass "
+ "Du eine bessere Uebersicht hast."));
+ AD(({"platz"}), BS("Die Waffentruhe bietet Platz fuer jede erdenkliche "
+ "Waffengattung."));
+}
+
diff --git a/d/seher/haeuser/moebel/wasch.c b/d/seher/haeuser/moebel/wasch.c
new file mode 100644
index 0000000..7789350
--- /dev/null
+++ b/d/seher/haeuser/moebel/wasch.c
@@ -0,0 +1,220 @@
+// Name des Objects: Waschobjekt
+// Letzte Aenderung: 01.04.2005
+// Magier: Seleven
+// Dieses File gibt dem Spieler die Moeglichkeit, eine Waschgelegenheit in
+// seinem Seherhaus aufzustellen. Das beim Kommando wasch(e), dusch(e) laesst
+// sich die Medung ueberschreiben (Test per raum->QueryProp("h_commands"))
+// 01.07.2007 (Zesstra): GetOwner() definiert.
+//----------------------------------------------------------------------------
+#pragma strong_types,rtt_checks
+
+#include "schrankladen.h"
+inherit LADEN("swift_std_container");
+
+string *wcmd;
+string *objekte =
+ (({"\nstinkobj","\nzesstra_asche","seleve\nscheisse","\npopc",
+ "\nsspbollen","seleve\nstinkobj","\nq2p_gestank","ber\tram_skot",
+ "bambi\nschmutzigehaende"}));
+/* Wurzel(Klo/Imbiss), Zesstra(Vulkan/Illuminatos), Seleven(Klo/Nebelelfen),
+ * Seleven(Popcorn/Nebelelfen), Boing(Schleimschmeisser,SSP), STANDART
+ */
+
+static void wasch_fun();
+
+protected void create()
+{
+ if (!clonep(this_object())) return;
+ ::create();
+
+ wcmd = (({"wasche","wasch","dusche","dusch"}));
+ AddId(({"duschkabine","kabine","dusche","waschgelegenheit"}));
+ SetProp(P_NAME,"Duschkabine");
+
+ SetProp("cnt_version_obj",1);
+
+ SetProp("obj_cmd",
+ "wasch(e), dusch(e)\n"+
+ " Damit laesst sich das Stinken aus dem Imbissklo beseitigen.\n"+
+ " Wenn kein Befehl 'wasch(e)' im Raum beschrieben ist, erfolgt eine\n"+
+ " Standartmeldung, selbiges gilt fuer 'dusch(e)'.\n"+
+ "ssetz(e) waschbefehl\n"+
+ " Damit kann man die Befehlsliste erweitern, die das Waschen \n"+
+ " ausloesen\n"+
+ "sloesch(e) waschbefehl\n"+
+ " Damit kann man einen Befehl aus der Liste loeschen\n"+
+ "waschbefehlslite, wbl"+
+ " Zeigt eine Liste der Befehle an, die das Waschen ausloesen.\n");
+
+ SetProp(P_SHORT,"Eine Duschkabine");
+ SetProp(P_LONG,BS("Die Duschkabine hat einen Rahmen aus hellem Holz. "
+ "Dazwischen wurden matte Scheiben eingelassen, damit man niemanden beim "
+ "Duschen beobachten kann."));
+ AddDetail("rahmen","Der Rahmen ist aus hellem Holz.\n");
+ AddDetail(({"scheiben","scheibe"}),"Die Scheiben der Duschkabine sind "+
+ "matt und absolut undurchsichtig!\n");
+ AddDetail(({"duschen","beim duschen"}),
+ "Man kann niemanden beim Duschen beobachten.\n");
+
+ SetProp(P_GENDER, FEMALE);
+ SetProp(P_WEIGHT, 5000); // Gewicht 5 Kg
+ SetProp(P_MAX_WEIGHT, 0); // Soll nur n pseudo-Container
+ SetProp(P_WEIGHT_PERCENT, 100); // Dafuer macht er auch nix leichter :)
+ SetProp(P_MAX_OBJECTS, 0); // Kein Container :)
+ SetProp(P_VALUE, 0); // Ist eh nicht verkaufbar.
+ SetProp(P_NOBUY, 1); // Fals doch: zerstoeren!
+ SetProp(P_NOGET,
+ "Das geht nicht. "+Name(WER,1)+" haftet wie magisch am Boden.\n");
+ SetProp(P_MATERIAL, ({MAT_MISC_WOOD, MAT_MISC_MAGIC}) );
+ SetProp(P_INFO, "Versuchs mal mit: \"skommandos "+QueryProp(P_IDS)[1]+"\" !\n");
+
+ AddCmd(wcmd,"cmd_waschen");
+ RemoveCmd(({"oeffne","oeffn","schliesse","schliess"}));
+ AddCmd(({"ssetze","ssetz"}),"cmd_setzen");
+ AddCmd(({"sloesche","sloesche"}),"cmd_loeschen");
+ AddCmd(({"wbl","waschbefehlsliste"}),"liste");
+}
+
+// Zesstra, 1.7.07, fuers Hoerrohr
+string GetOwner() {return "seleven";}
+
+varargs int PreventInsert(object ob) {return 1;} //Das ist kein Container :)
+
+static void wasch_fun()
+{
+ int i;
+ object ob;
+ i = sizeof(objekte);
+ i--;
+ while(i > -1)
+ {
+
+ if(!TP) return;
+ ob = present(objekte[i],TP);
+ while(ob)
+ {
+ if(query_once_interactive(ob))
+ {
+ tell_object(TP,BS("Du scheinst jemanden in Deinem Inv zu haben!\n"
+ "Das sollte sich vielleicht ein Magier anschauen."));
+ i--;
+ return;
+ }
+ ob->remove(1);
+ if(present(objekte[i],TP));
+ ob = present(objekte[i],TP);
+ }
+ i--;
+
+ }
+}
+
+int cmd_waschen(string str)
+{
+ string verb;
+ verb = query_verb();
+ if(!environment()) return 0;
+ if( !erlaubt() )
+ {
+ write("Du solltest den Besitzer vielleicht um Erlaubnis bitten.\n");
+ return 1;
+ }
+ if(member(environment()->QueryProp("h_commands"),verb) == 0)
+ {
+ write(
+ "Du springst schnell unter die Dusche und waeschst Dich gruendlich.\n");
+ say(this_player()->Name(WER)+" springt schnell unter die Dusche.\n");
+ wasch_fun();
+ return 1;
+ }
+ wasch_fun();
+ return 1;
+}
+
+
+static int cmd_setzen(string str)
+{
+ string bef;
+ notify_fail("Moechtest Du einen Waschbefehl setzen?\n"+
+ "Syntax: ssetz(e) waschbefehl [befehl]\n");
+ if(!str || !stringp(str) || sizeof(str) == 0) return 0;
+ sscanf(str,"waschbefehl %s",bef);
+ if(!bef) return 0;
+ if(bef[sizeof(bef) .. sizeof(bef)-1] == "e")
+ bef = bef[sizeof(bef) .. sizeof(bef)-2];
+ notify_fail("Der Befehl steht schon auf der Liste.\n");
+ if(member(wcmd,bef) != -1) return 0;
+ wcmd += (({bef,bef+"e"}));
+ AddCmd(wcmd,"cmd_waschen");
+ write(BS("Du hast die Befehle "+bef+" und "+bef+"e an die Liste "
+ "angefuegt."));
+ return 1;
+}
+
+static int cmd_loeschen(string str)
+{
+ string bef;
+ notify_fail("Moechtest Du einen Waschbefehl loeschen?\n"+
+ "Syntax: sloesch(e) waschbefehl [befehl]\n");
+ if(!str || !stringp(str) || sizeof(str) == 0) return 0;
+ sscanf(str,"waschbefehl %s",bef);
+ if(!bef) return 0;
+ notify_fail("Der Befehl steht gar nicht auf der Liste.\n");
+ if(member(wcmd,bef) == -1) return 0;
+ wcmd -= (({bef}));
+ RemoveCmd(bef);
+ write(BS("Du hast die Befehle "+bef+" und "+bef+"e von der Liste "
+ "entfernt."));
+ return 1;
+}
+
+static int liste(string str)
+{
+ write("Du hast folgende Befehle auf der Waschliste stehen:\n"+
+ break_string(implode(wcmd,", "),78,3));
+ return 1;
+}
+
+
+
+// oeffnen und schliessen ausbauen.
+varargs int skommandos(string str)
+{
+ notify_fail( "Fehler: Dieser Befehl benoetigt eine gueltige Objekt-Id als Parameter.\n"
+ +"Beispiel: skommandos "+QueryProp(P_IDS)[1]+"\n");
+ if(!str) return 0;
+ if(present(str)!=TO ) // Bin ich gemeint?
+ return 0;
+ write("=============================================================================\n");
+ write("Aktuelle Version: "+QueryProp("cnt_version_std")+QueryProp("cnt_version_obj")+"\n");
+ write( BS(Name(WER,1)+" kann nur in diesem Seherhaus verwendet werden, "
+ +"da "+QueryPronoun(WER)+" speziell dafuer gekauft wurde. "+CAP(QueryPronoun(WER))
+ +" verfuegt ueber folgende Kommandos:")
+ +"-----------------------------------------------------------------------------\n"
+ +"serlaube [Objekt-Id] [Spielername|\"hausfreunde\"|\"zweities\"]\n"
+ +" Erlaubt Personen, "+name(WEN,1)+" mitzubenutzen.\n"
+ +" serlaube + Objekt-Id (ohne Spielername/hausfreunde)\n"
+ +" listet alle Personen mit Zugriff auf "+name(WEN,1)+"\n\n"
+ +"verschiebe [Objekt-Id] nach [Ausgang]\n"
+ +" Damit kannst Du "+name(WEN,1)+" innerhalb Deines Seherhauses verschieben.\n\n"
+ //Seleven 07.12.2005
+ +"sverstecke [Objekt-Id]\n"
+ +" Damit machst Du "+name(WEN,1)+" unsichtbar.\n"
+ +"shole [Objekt-Id] hervor\n"
+ +" Damit machst Du "+name(WEN,1)+" wieder sichtbar.\n"
+ // Bis hier
+ +"zertruemmer [Objekt-Id]\n"
+ +" Damit zerstoerst Du "+name(WEN,1)+".\n\n");
+
+
+ if( QueryProp("obj_cmd") )
+ write( QueryProp("obj_cmd")+"\n" );
+
+ write("[Objekt-Id] muss eine gueltige Id sein, in diesem Fall z.B. "
+ +QueryProp(P_IDS)[1]+"\n");
+ write("=============================================================================\n");
+
+
+ return 1;
+}
+
diff --git a/d/seher/haeuser/moebel/zauberkiste.c b/d/seher/haeuser/moebel/zauberkiste.c
new file mode 100644
index 0000000..ecf6f74
--- /dev/null
+++ b/d/seher/haeuser/moebel/zauberkiste.c
@@ -0,0 +1,56 @@
+//--------------------------------------------------------------------------------
+// Name des Objects: Zauberkiste
+// Letzte Aenderung: 10.05.2002
+// Magier: Vanion
+// Was: Die ID fuer die Kompos der Zauberer umgestellt.
+//--------------------------------------------------------------------------------
+#pragma strong_types,rtt_checks
+
+#include "schrankladen.h"
+
+// Fuer die IDs
+#include "/p/zauberer/zauberer.h"
+
+inherit LADEN("swift_std_container");
+
+#define VERSION_OBJ "3"
+
+protected void create()
+{
+ if (!clonep(TO)) return;
+ swift_std_container::create();
+ SetProp(P_SHORT, "Eine Zauberkiste");
+ SetProp(P_LONG, BS(
+ "Eine kleine Kiste aus Birnbaumholz. Da diesem seltenen Holz selbst "
+ +"magische Faehigkeiten nachgesagt werden, ist es wohl das ideale Material, "
+ +"um die teilweise gefaehrlichen Komponenten eines Zauberers darin "
+ +"unterzubringen.")+"@@cnt_status@@");
+ AddId(({"zauberkiste", "kiste"}));
+ SetProp("cnt_version_obj", VERSION_OBJ);
+ SetProp(P_NAME, "Zauberkiste");
+ SetProp(P_GENDER, FEMALE);
+ SetProp(P_WEIGHT, 5000); // Gewicht 5 Kg
+ SetProp(P_MAX_WEIGHT, 1000000); // Es passen fuer 1000 kg Sachen rein.
+ SetProp(P_WEIGHT_PERCENT, 100); // Dafuer macht er auch nix leichter :)
+ SetProp(P_MAX_OBJECTS, 100); // Mehr sollte nicht sein, lt. Tiamak.
+ SetProp(P_VALUE, 0); // Kein materieller Wert. Ist eh nicht verkaufbar.
+ SetProp(P_NOBUY, 1); // Wird im Laden zerstoert, falls er verkauft wird.
+ SetProp(P_NOGET, "Das geht nicht. "+Name(WER,1)+" haftet wie magisch am Boden.\n");
+ SetProp(P_MATERIAL, ({MAT_PEAR_WOOD, MAT_MISC_MAGIC}) );
+ SetProp(P_INFO, "Versuchs mal mit: \"skommandos "+QueryProp(P_IDS)[1]+"\" !\n");
+
+ AD(({"holz", "birnbaumholz"}), BS("Fast koenntest Du meinen, dass "+name(WER,1)
+ +" lebt!"));
+}
+
+varargs int PreventInsert(object ob)
+{
+ // Keine Zauberkompo? Hat in diesem Container nix verloren!
+ if( !ob->id(Z_ID_ZUTAT) )
+ {
+ write( BS("In "+name(WEN,1)+" kannst Du nur Zauberer-Komponenten legen!"));
+ return 1;
+ }
+ else
+ return ::PreventInsert(ob);
+}
diff --git a/d/seher/haeuser/queue.c b/d/seher/haeuser/queue.c
new file mode 100644
index 0000000..bf2ca56
--- /dev/null
+++ b/d/seher/haeuser/queue.c
@@ -0,0 +1,433 @@
+/*
+ * queue.c -- Eine Schlange, an der man anstehen kann
+ *
+ * (c) 1994 Wargon@MorgenGrauen
+ *
+ */
+
+#include <properties.h>
+#include <defines.h>
+#include <wizlevels.h>
+#include <moving.h>
+#include "queue.h"
+
+#define TP this_player()
+
+inherit "std/thing/moving";
+inherit "std/room";
+
+static mapping peopleInQueue;
+static object lastMoved;
+
+/* Spielerkommendos */
+static int anstellen(string str);
+static int draengeln(string str);
+
+/* Spieler in Schlange einfuegen/aus Schlange entfernen */
+static void enqueue(object ob);
+private void leaveQueue(object ob, int silent);
+
+private object *queuedPeople();
+private int queueScan();
+private object adjust(int thresh);
+
+/* werden bei "schlafe ein" bzw. "ende" aufgerufen */
+void BecomesNetDead(object player);
+void PlayerQuit(object player);
+
+create()
+{
+ if (IS_BLUE(this_object())) return;
+
+ ::create();
+
+ SetProp( P_INDOORS, 1 );
+ SetProp( P_LIGHT, 1 );
+ SetProp( P_GENDER, FEMALE );
+
+ SetProp( P_SHORT, "Eine Schlange" );
+ SetProp( P_LONG, "Du siehst eine Schlange.\n" );
+ SetProp( P_INT_SHORT, "In der Schlange" );
+ SetProp( P_INT_LONG, "Du stehst in einer Schlange.\n" );
+ SetProp( P_NAME, "Schlange" );
+ SetProp( P_TRANSPARENT, 0 );
+
+// Netztote werden beim disconnecten eh aus der Schlange entfernt.
+// Hiermit wird die Ausgabe des Hinweises unterdrueckt.
+ SetProp( P_NETDEAD_INFO, 1 );
+
+ AddId( ({ "queue", "schlange" }) );
+
+ peopleInQueue = ([ ]);
+ lastMoved = 0;
+
+// Defaults setzen
+ SetProp( Q_CYCLE_TIME, 15 );
+ SetProp( Q_DEST, "/gilden/abenteurer" );
+ SetProp( Q_LENGTH, 3 );
+ SetProp( Q_SUSPEND, 0 );
+ SetProp( Q_MSGS, ({ "@@wer@@ ist an der Reihe!", "Du bist jetzt an der Reihe!",
+ "Der Naechste ist an der Reihe, und die anderen ruecken auf.",
+ "Die Schlange rueckt weiter. Sogleich stellt sich jemand neu an." }) );
+
+ AddSpecialExit( "raustreten", "raustreten" );
+
+ AddCmd( ({ "anstellen", "stell", "stelle" }), "anstellen" );
+ AddCmd( ({ "draengeln", "draengle", "draengel", "vordraengeln" }), "draengeln" );
+}
+
+int clean_up(int i) { return 0; }
+
+int
+remove()
+{
+ string *wer;
+ mixed raus;
+ int i;
+
+ while( remove_call_out( "rotate" ) != -1 );
+ while( remove_call_out( "funny" ) != -1 );
+
+ if (clonep(this_object())) {
+ if (!(raus = environment()))
+ raus = "/gilden/abenteurer";
+
+ if (i = sizeof(wer = m_indices(peopleInQueue))) {
+ tell_room(this_object(), "Die Schlange loest sich auf.\n" );
+
+ while ((--i)>0)
+ if (peopleInQueue[wer[i],1])
+ peopleInQueue[wer[i],1]->move(raus, M_GO | M_SILENT | M_NO_SHOW);
+ }
+ }
+ return ::remove();
+}
+
+string
+_query_long()
+{
+ string ret, add;
+ mixed *people, ob;
+ closure n;
+
+ people = filter(all_inventory(this_object()), #'interactive/*'*/);
+
+ ret = Query(P_LONG);
+ add = "In der Schlange stehen " + QueryProp(Q_LENGTH) + " Leute.";
+ if (sizeof(people)) {
+ n = lambda( ({ 'ob }), ({#'call_other, 'ob, "Name", WER}) );
+ people = map(people, n);
+ add += " Unter anderem steh";
+ if (sizeof(people) == 1)
+ add += ( "t dort " + people[0] + "." );
+ else {
+ add += ( "en dort " + implode(people[0..<2], ", ") +
+ " und " + people[<1] + "." );
+ }
+ }
+ return ret + break_string(add, 76);
+}
+
+string
+_query_int_long()
+{
+ string ret, add;
+ int act, cur;
+
+ ret = Query(P_INT_LONG);
+ add = "";
+ act = peopleInQueue[getuid(TP), 0];
+ cur = QueryProp(Q_LENGTH);
+
+ if (act == 0)
+ add += ( "Du bist als naechster an der Reihe. Hinter Dir"
+ +" stehen noch " + (cur - 1) +" Leute an." );
+ else {
+ if (act == 1)
+ add += "Es ist noch jemand vor Dir dran.";
+ else
+ add += ( "Es sind noch " + act + " Leute vor Dir dran." );
+
+ if ((cur = cur - act -1) > 0) {
+ if (cur == 1)
+ add += " Es steht noch jemand hinter Dir.";
+ else
+ add += ( " Hinter Dir stehen noch " + cur +" Leute an." );
+ }
+ }
+ return ret + break_string(add, 76);
+}
+
+int _query_qLength()
+{
+ return Query(Q_LENGTH) + sizeof(filter(all_inventory(this_object()), #'interactive/*'*/));
+}
+
+static int
+anstellen(string str)
+{
+ object tp;
+ string *part;
+
+ if (query_verb() != "anstellen") {
+ notify_fail( "stelle was?\n" );
+ if (!str || str == "")
+ return 0;
+
+ part = old_explode(str, " ");
+ if (part[0] != "an" && part[<1] != "an") {
+ notify_fail( "Syntax: stelle an <schlange> an\n" );
+ return 0;
+ }
+ if (!id(implode(part[1..<2], " ")))
+ return 0;
+ }
+ enqueue(TP);
+ return 1;
+}
+
+static int
+raustreten()
+{
+ if (environment(this_object())) {
+ leaveQueue(TP, 0);
+ return 1;
+ }
+ return 0;
+}
+
+static int
+draengeln(string str)
+{
+ int prob;
+ string *people;
+
+ if (environment(TP) != this_object())
+ return 0;
+
+ prob = random(11);
+
+ if (10 == prob) {
+ say( TP->Name(WER) + " will sich vordraengeln. Zur Strafe wird "
+ +TP->QueryPronoun(WER) +" von der auf-\n"
+ +"gebrachten Menge aus der Schlange hinausgeworfen. Du grinst Dir eins.\n" );
+ write( "Du draengelst Dich vor, wirst aber von der aufgebrachten "
+ +"Menge aus der\nSchlange herausgedraengt.\n" );
+ leaveQueue(TP, 0);
+ }
+ else if (prob < 8) {
+ say( TP->Name(WER) + " will sich vordraengeln.\n" );
+ write( "Du willst Dich vordraengeln.\n" );
+ tell_room(this_object(), sprintf("Es kommen Rufe auf: %s\n",
+ ({ "He! Was soll denn das? Unerhoert!",
+ "Also wirklich! Unverschaemtheit sowas!",
+ "...soll'n das? Mistbacke!",
+ "Jau, soweit kommts noch! Ich glaub' es geht los!",
+ "Wieder mal typisch "+TP->QueryProp(P_RACESTRING)[WER]+"!",
+ "Wenn sich das jeder erlauben wuerde...",
+ "Ne, ne, das geht aber nicht! Mal langsam, "+
+ (TP->QueryProp(P_GENDER)==MALE ? "Buerschchen":"Frollein")+"!",
+ "POLIZEI! HILFAEEEH!!! Also die Jugend von heute..." })[prob] ));
+ say( capitalize(TP->QueryPronoun())+" ueberlegt es sich anders.\n" );
+ write( "Du ueberlegst es Dir anders.\n" );
+ }
+ else {
+ say( TP->Name(WER) + " draengelt sich vor.\n" );
+ write( "Du draengelst Dich vor.\n" );
+ prob = peopleInQueue[getuid(TP)];
+ m_delete(peopleInQueue, getuid(TP));
+ for(people = m_indices(peopleInQueue); sizeof(people); people = people[1..] ) {
+ if(peopleInQueue[people[0],0] < prob)
+ peopleInQueue[people[0],0]++;
+ }
+ peopleInQueue += ([ getuid(TP) : 0; TP ]);
+ }
+ return 1;
+}
+
+static void
+enqueue(object ob)
+{
+ int i;
+
+ if (environment(ob) == this_object()) {
+ say(ob->Name(WER) + " stellt sich wieder hinten an.\n", ob );
+ tell_object(ob, "Du stellst Dich wieder hinten an.\n" );
+
+ i = peopleInQueue[getuid(ob),0];
+ m_delete(peopleInQueue, getuid(ob));
+ adjust(i);
+ peopleInQueue += ([ getuid(ob) : QueryProp(Q_LENGTH)-1; ob ]);
+ }
+ else {
+ peopleInQueue += ([ getuid(ob) : QueryProp(Q_LENGTH); ob ]);
+ ob->move(this_object(), M_NOCHECK, 0, "stellt sich an "+name(WEM)+" an",
+ "stellt sich hinten an");
+ }
+ if (find_call_out("rotate") == -1)
+ call_out("rotate", QueryProp(Q_CYCLE_TIME));
+}
+
+private void
+leaveQueue(object ob, int silent)
+{
+ int i;
+
+ if (silent)
+ ob->move(environment(this_object()), M_NOCHECK | M_SILENT);
+ else
+ ob->move(environment(this_object()), M_NOCHECK, 0, "verlaesst die Schlange",
+ "verlaesst "+name(WEN)+" und steht jetzt neben Dir" );
+
+ i = peopleInQueue[getuid(ob), 0];
+
+ m_delete(peopleInQueue, getuid(ob));
+
+ if (sizeof(peopleInQueue))
+ adjust(i);
+ else {
+ while(remove_call_out("rotate") != -1);
+ while(remove_call_out("funny") != -1);
+ }
+}
+
+private int
+queueScan()
+{
+ string *peop;
+ object act;
+ int i, a;
+
+ peop = m_indices(peopleInQueue);
+
+ for (i=sizeof(peop)-1; i>=0; i--) {
+ if (!objectp(act = peopleInQueue[peop[i],1]) ||
+ (environment(act) != this_object())) {
+ a = peopleInQueue[peop[i], 0];
+ m_delete(peopleInQueue, peop[i]);
+ adjust(a);
+ }
+ }
+
+ return sizeof(peopleInQueue);
+}
+
+private object
+adjust(int thresh)
+{
+ string *peop;
+ object ret;
+ int cnt, i;
+
+ ret = 0;
+ peop = m_indices(peopleInQueue);
+
+ for (i=sizeof(peop)-1; i>=0; i--) {
+ cnt = peopleInQueue[peop[i],0];
+ if (cnt > thresh)
+ cnt--;
+ if (cnt < 0)
+ ret = peopleInQueue[peop[i],1];
+ peopleInQueue[peop[i],0] = cnt;
+ }
+ return ret;
+}
+
+rotate()
+{
+ object ich;
+ string oth, *msgs;
+ int rotating, inDest;
+
+ rotating = 1;
+
+ if (QueryProp(Q_SUSPEND)) {
+ if (lastMoved) {
+ rotating = 0;
+ inDest = (object_name(environment(lastMoved)) == QueryProp(Q_DEST));
+ if (!interactive(lastMoved) || !inDest )
+ rotating = 1;
+ if (interactive(lastMoved) && inDest && environment() && query_idle(lastMoved) > 180) {
+ tell_object(lastMoved, "Du wirst rausgeworfen.\n");
+ lastMoved->move(environment(), M_GO, 0, "idlet herein");
+ rotating = 1;
+ }
+ }
+ }
+ if (rotating) {
+ queueScan();
+ msgs = QueryProp(Q_MSGS);
+ if (ich = adjust(-1)) {
+ oth = implode(explode(msgs[QMSG_OTHER], "@@wer@@"), ich->name(WER) );
+ oth = implode(explode(oth, "@@wessen@@"), ich->name(WESSEN) );
+ oth = implode(explode(oth, "@@wem@@"), ich->name(WEM) );
+ oth = implode(explode(oth, "@@wen@@"), ich->name(WEN) );
+ tell_room(this_object(), capitalize(break_string(oth, 78)), ({ ich }) );
+ tell_object(ich, break_string(msgs[QMSG_ME], 78) );
+ tell_room(environment(), break_string(msgs[QMSG_OUTSIDE], 78) );
+ ich->move(QueryProp(Q_DEST), M_GO);
+ lastMoved = ich;
+ m_delete(peopleInQueue, getuid(ich));
+ if (!sizeof(peopleInQueue))
+ return;
+ }
+ else
+ tell_room(this_object(), break_string(msgs[QMSG_DEFAULT], 78) );
+ }
+
+ if (random(100) < 20)
+ call_out("funny", random(QueryProp(Q_CYCLE_TIME)) );
+
+ call_out("rotate", QueryProp(Q_CYCLE_TIME));
+}
+
+funny()
+{
+ string m;
+
+ switch(random(7)) {
+ case 0:
+ m= "Jemand vor Dir laesst tierisch einen fahren. Seltsamerweise wirft man\n"
+ +"aber Dir missbilligende Blicke zu.\n";
+ break;
+ case 1:
+ m= "Von hinten draengelt wer! Wuetend drehst Du Dich um, schaust hoch, schaust\n"
+ +"hoeher, schaust noch hoeher... und schon ist Deine Wut verflogen!\n";
+ break;
+ case 2:
+ m= "Vor Langeweile popelt jemand vor Dir in der Nase. Das quietschende Ge-\n"
+ +"raeusch laesst Dir das Blut in den Adern gefrieren.\n";
+ break;
+ case 3:
+ m= "Ein fliegender Haendler landet neben der Schlange und bietet Kurzwaren\n"
+ +"feil. Da aber niemand etwas kaufen will, hebt er kurz darauf wieder ab\n"
+ +"und fliegt zu einer anderen Schlange, um dort sein Glueck zu versuchen.\n";
+ break;
+ case 4:
+ m= "Vom hinteren Ende der Schlange sickert das Geruecht durch, dass der\n"
+ +"Schalter heute geschlossen ist. Du hoffst instaendig, dass dies nicht\n"
+ +"wahr ist.\n";
+ break;
+ case 5:
+ m= "Fasziniert beobachtest Du, wie eine Spinne zwischen Deinem Vordermann und\n"
+ +"der Wand ein kunstvolles Netz spinnt.\n";
+ break;
+ case 6:
+ m= "Boah, iss dat langweilich...\n";
+ break;
+ }
+ tell_room(this_object(), m);
+}
+
+void
+BecomesNetDead(object player)
+{
+ if(present(player,this_object()))leaveQueue(player, 0);
+}
+
+void
+PlayerQuit(object player)
+{
+ if(present(player,this_player()))leaveQueue(player, 1);
+}
+
diff --git a/d/seher/haeuser/queue.h b/d/seher/haeuser/queue.h
new file mode 100644
index 0000000..3f2283e
--- /dev/null
+++ b/d/seher/haeuser/queue.h
@@ -0,0 +1,34 @@
+#ifndef _QUEUE_H_
+#define _QUEUE_H_
+
+// Zeit, bis der naechste dran ist (Default: 15 Sekunden)
+#define Q_CYCLE_TIME "qCycleTime"
+
+// Zielraum der Schlange (Default: "/gilden/abenteurer")
+#define Q_DEST "qDest"
+
+// Laenge der Schlange (Default: 3)
+#define Q_LENGTH "qLength"
+
+// Falls ungleich Null, wird gewartet, bis der zuletzt bewegte Spieler
+// den Zielraum verlassen hat, bevor es in der Schlange weitergeht
+#define Q_SUSPEND "qSuspend"
+
+// Meldungen, die beim Aufruecken ausgegeben werden. Vierelementiges Array:
+// 1. Meldung, wenn ein Spieler an der Reihe ist
+// 2. Meldung fuer den Spieler, der an der Reihe ist
+// 3. Meldung, wenn ein Schlangesteher an der Reihe ist
+// 4. Meldung fuer Leute ausserhalb der Schlange
+// In die erste Meldung kann mit @@wer@@, @@wessen@@, @@wem@@ und @@wen@@ der
+// Name des Spielers eingearbeitet werden.
+// (Default: ({ "@@wer@@ ist an der Reihe!", "Du bist jetzt an der Reihe!",
+// "Der Naechste ist an der Reihe, und die anderen ruecken auf.",
+// "Die Schlange rueckt weiter. Sogleich stellt sich jemand neu an." }) )
+#define Q_MSGS "qMsgs"
+
+#define QMSG_OTHER 0
+#define QMSG_ME 1
+#define QMSG_DEFAULT 2
+#define QMSG_OUTSIDE 3
+
+#endif /* _QUEUE_H_ */
diff --git a/d/seher/haeuser/raum.c b/d/seher/haeuser/raum.c
new file mode 100644
index 0000000..7fd0c55
--- /dev/null
+++ b/d/seher/haeuser/raum.c
@@ -0,0 +1,1840 @@
+// raum.c -- Das Rohgeruest eines Seherhauses.
+//
+// Grundobjekt (c) 1994 Boing@MorgenGrauen
+// Abschliessen und Rauswerfen von Jof
+// Fuer Aenderungen ab dem 06.10.94 verantwortlich: Wargon
+// Ab 03.02.98 Wurzel
+//
+// $Id: raum.c,v 1.5 2003/11/15 14:03:58 mud Exp $
+#pragma strong_types,rtt_checks
+
+#include "haus.h"
+
+inherit "/std/room";
+inherit USERCMD; // selbstdefinierte Kommandos
+inherit LOSA; // Load() und Save()
+inherit "/mail/nedit";
+
+#include <wizlevels.h>
+#include <properties.h>
+#include <defines.h>
+#include <moving.h>
+
+static mixed detail;
+static string owner;
+static int flag, csaved;
+static int raumNr;
+static string *ausgaenge = ({ "oben", "norden", "nordosten", "osten", "suedosten",
+ "unten", "sueden", "suedwesten", "westen", "nordwesten" });
+
+// Prototypes fuer Funktionen aus LOSA
+varargs void Save(int crunched);
+void Load();
+
+// Prototype
+// Falls noetig, mache einen Notausgang, falls nicht loesche vorhandenen
+void make_emergency_exit();
+
+// ersetzt @@ durch **
+private string normstr(string str)
+{
+ return implode(explode(str,"@@"),"**");
+}
+
+// liefert kommagetrennte Teile ohne zusaetzliche Leerzeichen
+// "Bla blubb , foo bar,blubber" => ({ "Bla blubb", "foo bar", "blubber" })
+private string *brk(string str)
+{
+ string *t1;
+
+ t1 = explode(str, ",");
+ map(t1, #'trim /*'*/);
+ return t1;
+}
+
+// teste Befehl
+private int befCheck(string bef)
+{
+ // Befehl enthaelt Leerzeichen => return 0
+ if (member(bef, ' ') > -1)
+ return 0;
+
+ // Befehl ist bereits Kommando (ausser Oeffnen/Schliessen)
+ // oder Richtung inclusive "raus" in die kein Ausgang fuehrt
+ // => return 0
+ if (member(m_indices(QueryProp(P_COMMANDS)) -
+ ({"oeffne","schliess","schliesse"}), bef) > -1
+ || (member(ausgaenge+({"raus"}), bef) > -1
+ && member(m_indices(QueryProp(P_EXITS)), bef) == -1))
+ return 0;
+
+ return 1;
+}
+
+// Test auf Hausbesitzer
+int tp_owner_check()
+{
+ if(getuid(this_player()) != owner)
+ {
+ notify_fail( "Das ist nicht Dein Haus!\n" );
+ return 0;
+ }
+ return 1;
+}
+
+// Test auf Hausbesitzer oder Person mit Erlaubnis
+int allowed_check(object _test)
+{
+ string *ext;
+
+ ext = VERWALTER->HausProp(owner, HP_ALLOWED) + ({ capitalize(owner) });
+ if(member(ext, capitalize(getuid(_test))) < 0)
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+// Funktion ersetzt durch tp_owner_check() und allowed_check(object _test)
+// falls allowed == 0 => test ob this_player() Hausbesitzer
+// falls allowed != 0 => test ob allowed/this_player() Hausbesitzer
+// oder Person mit Erlaubnis
+deprecated varargs int owner_check(mixed allowed)
+{
+ object test;
+
+ if(objectp(allowed) && query_once_interactive(allowed))
+ {
+ // Parameter ist Spieler
+ test = allowed;
+ }
+ else
+ {
+ // ansonsten TP
+ test = this_player();
+ }
+
+ if(allowed)
+ {
+ // Test auf Hausbesitzer oder Person mit Erlaubnis
+ if(!allowed_check(test))
+ {
+ notify_fail( "Das darfst Du in diesem Haus nicht!\n" );
+ return 0;
+ }
+ }
+ else if(getuid(test) != owner)
+ {
+ // Test auf Hausbesitzer
+ notify_fail( "Das ist nicht Dein Haus!\n" );
+ return 0;
+ }
+ // Erlaubnis OK
+ return 1;
+}
+
+// Gestaltet Meldung aus Texten in einem Array:
+// array leer -> melde Text in none
+// array hat ein Element -> melde Text in one und ersetze %s durch Element
+// array hat viele Elemente -> melde Text in many und danach
+// sortierte Aufzaehlung der Elemente
+// flag gesetztes Bit 2: Aufzaehlung nur mit Komma, kein 'und'
+// flag gesetztes Bit 1: Meldung wird als String returnt, sonst per write ausgegeben
+varargs string arr_out(mixed array, string none, string one, string many, int flag)
+{
+ string tmp, lastsep;
+ mixed arr;
+
+ switch(sizeof(array))
+ {
+ case 0:
+ tmp = none;
+ break;
+ case 1:
+ tmp = sprintf(one, array[0]);
+ break;
+ default:
+ tmp = many;
+ arr = sort_array(array, #'> /*'*/);
+ lastsep = (flag & 2) ? ", " : " und ";
+ tmp += CountUp(arr, ", ", lastsep)+".";
+ break;
+ }
+ if (flag & 1)
+ return(break_string(tmp, 75, 0, 1));
+ else
+ write(break_string(tmp, 75, 0, 1));
+
+ return 0;
+}
+
+protected void create()
+{
+ if (!clonep(this_object()) && object_name(this_object())==(RAUM)) {
+ set_next_reset(-1);
+ return;
+ }
+ room::create();
+ usercmd::create();
+ losa::create();
+
+ Set(P_INT_LONG, SAVE, F_MODE_AS);
+ Set(P_INT_SHORT, SAVE, F_MODE_AS);
+ Set(P_EXITS, SAVE, F_MODE_AS);
+ Set(P_DETAILS, SAVE, F_MODE_AS);
+ Set(P_READ_DETAILS, SAVE, F_MODE_AS);
+ Set(P_LIGHT, SAVE, F_MODE_AS);
+
+ SetProp(P_IDS, ({"raum","sehe\rhaus"}));
+ SetProp(P_NAME, "Haus");
+ SetProp(P_GENDER, 0);
+ SetProp(P_TRANSPARENT, 0);
+ SetProp(P_NOGET, 1);
+ SetProp(P_LIGHT, 1);
+ SetProp(P_INDOORS, 1);
+
+ AddCmd( ({ "beschreib", "beschreibe" }), "beschreiben" );
+ AddCmd("uebersicht", "uebersicht");
+ AddCmd("ausgang", "ausgang");
+ AddCmd( ({"loesche", "loesch"}), "loesch");
+ AddCmd( ({"wirf", "werf", "werfe" }), "wirf");
+ AddCmd( ({"sperr", "sperre"}), "sperren");
+ AddCmd( ({"kopier", "kopiere" }), "kopieren");
+ AddCmd("licht", "licht");
+ AddCmd( ({"aendere", "aender" }), "aendern");
+ AddCmd( ({"meldung", "meldungen"}), "report");
+}
+
+void init()
+{
+ object haus;
+
+ room::init();
+ nedit::init_rescue();
+
+ // Magier betritt fremdes Seherhaus
+ if (query_once_interactive(PL) && IS_LEARNER(PL) && getuid(PL) != owner) {
+ if (PL->QueryProp(P_INVIS))
+ // Magier invis => im Raum melden
+ tell_room(this_object(),
+ capitalize(getuid(PL))+" betritt unsichtbar den Raum.\n",
+ ({PL}));
+
+ if ((haus = load_object(HAUSNAME(owner))) &&
+ (haus->QueryProp(H_DOORSTAT) & D_LOCKED))
+ // Tuer ist zu => Magier einen Hinweis geben
+ tell_object(PL, " ******* ACHTUNG *********************************\n *\n * "+
+ capitalize(owner)+" moechte vielleicht ungestoert bleiben!\n *\n"
+ " ******* ACHTUNG *********************************\n");
+ }
+}
+
+int PreventInsertLiving(object ob)
+{
+ return 0;
+}
+
+// Gegenstaende kommen in den Raum
+void NotifyInsert(object ob, object oldenv)
+{
+ object *found;
+
+ if (!objectp(ob)) return;
+
+ if (ob->QueryProp(H_FURNITURE)!=0)
+ {
+ // das was reinkam ist ein autoload Moebelstueck
+ // betrachte alle schon vorhandenen autoload Moebelstuecke
+ found = filter_objects(all_inventory(this_object()),
+ "QueryProp", H_FURNITURE);
+ if (sizeof(found)>=MAX_FURNITURE_PER_ROOM)
+ {
+ // Maximal-Anzahl vorhandener autoload Seherhausmoebel ist schon
+ // erreicht
+ tell_object(this_player(), break_string(
+ "Ein Raum kann nur "+MAX_FURNITURE_PER_ROOM+" rebootfeste "
+ "Moebel speichern. Hier befinden sich schon "+
+ CountUp(map_objects(found, "name"))+"."));
+ return 0;
+ }
+
+ queued_save(); // Speichern vorbereiten (falls mehrere Objekte
+ // gedroppt werden, wird so ein overflow verhindert.
+ }
+}
+
+// Gegenstaende verlassen den Raum
+void NotifyLeave(object ob, object dest)
+{
+ if (!ob &&!objectp(ob)) return 0;
+
+ // rebootfestes Moebelstueck verlaesst den Raum
+ if (ob->QueryProp(H_FURNITURE)!=0)
+ {
+ // Speichern vorbereiten (falls mehrere Objekte
+ // gedroppt werden, wird so ein overflow verhindert.
+ queued_save();
+ }
+ return 0;
+}
+
+void
+reset()
+{
+ room::reset();
+ losa::reset();
+ // Wenn ein Notausgang vorhanden ist, checken, ob der noch noetig ist.
+ if (member(m_indices(QueryProp(P_EXITS)),"notausgang")!=-1)
+ {
+ make_emergency_exit();
+ }
+}
+
+int clean_up(int arg)
+{
+ mixed inv;
+
+ if (arg > 1)
+ return 1;
+
+ losa::reset(); // Evtl. gepackt speichern...
+
+ // nichts im Raum oder nur leere Seherhaustruhe => Raum kann weg
+ if ((sizeof(inv=all_inventory()) == 0) ||
+ (sizeof(inv) == 1 && inv[0]->id(TRUHE) &&
+ sizeof(all_inventory(inv[0]))==0))
+ remove(1);
+
+ return 0;
+}
+
+// Haeufungen von gleichen Objekten sind hier egal => nix tun
+protected varargs void remove_multiple(int limit) {}
+
+
+// Spieler wird im Raum Netztot
+void BecomesNetDead(object pl)
+{
+// Nicht erlaubte Spieler werden rausgeworfen, alle anderen bleiben drin.
+ if(!allowed_check(pl))
+ pl->move(VERWALTER->HausProp(owner, HP_ENV), M_GO, 0, "schlafwandelt heraus", "schlafwandelt herein" );
+}
+
+
+/* Ist dieser Raum ein Ausgang? */
+int is_exit(string path)
+{
+ return (sizeof(path) > 4) && (path[<5..] == "raum0");
+}
+
+/*Pruefung, ob es einen Hausausgang gibt*/
+int room_has_exit() {
+
+ string room = object_name(this_object());
+ // sind wir schon in einem Hauptraum mit Ausgang?
+ if (is_exit(room)) return 1;
+
+ mapping r_todo = ([room]);
+ mapping r_done = ([:0]);
+ /* Die Schleife hat maximal 9 * Anzahl der verb. Haeuser Durchlaeufe */
+ while (sizeof(r_todo))
+ {
+ mapping r_exits = ([]);
+
+ // naechsten Raumpfad abarbeiten, d.h. dessen Ausgaenge betrachten
+ room = m_indices(r_todo)[0];
+ // abgearbeiteten Raumpfad von r_todo nach r_done schieben
+ r_done += ([room]);
+ m_delete(r_todo, room);
+
+ // alle Ausgaenge betrachten
+ foreach(string command, string subpath : room->QueryProp(P_EXITS))
+ {
+ // Notausgaenge nicht betrachten, da 'echte' Ausgaenge gesucht sind
+ if(command != "notausgang")
+ // alle anderen Ausgaenge sammeln
+ r_exits += ([ subpath ]);
+ }
+ // nur Raumpfade die noch nicht abgearbeitet sind testen
+ r_exits -= r_done;
+ // ist da ein Hauptraum (der dann Ausgang liefert) dabei?
+ if (sizeof(filter_indices(r_exits, #'is_exit/*'*/)))
+ return 1;
+
+ // neue Raumpfade in die TODO-Liste aufnehmen
+ r_todo += r_exits;
+ }
+ return 0;
+}
+
+// damit man Spieler nicht durch Entfernen von Ausgaengen einsperren kann
+// werden bei Bedarf Notausgaenge in den Hauptraum ergaenzt
+void make_emergency_exit()
+{
+ // Ist der Raum weder Hauptraum mit Ausgang noch fuehrt ein Weg dorthin?
+ // dann Notausgang machen
+ if(!room_has_exit())
+ {
+ // tell_room(this_object(),"DEBUG: Ein Notausgang wurde angelegt.\n");
+ room::AddExit("notausgang",
+ "durch den Notausgang#"+to_string(this_object())[0..<2]+"0");
+ }
+ else
+ {
+ // nicht mehr benoetigten Notausgang entfernen
+ room::RemoveExit("notausgang");
+ }
+}
+
+// ruft direkt das geerbte AddExit auf, ohne ggf. einen Notausgang zu
+// erzeugen. Das wird vom Haus und vom Verwalter benutzt, um Ausgaenge zu
+// erzeugen. Das ist noetig, weil der Notausgangmechanismus noch nicht
+// funktoniert, wenn der Raum gerade geladen wird (hat noch nicht den
+// endgueltigen Namen) und der Check waere ohnehin unnoetig.
+public void AddExitNoCheck(mixed cmd, mixed dest)
+{
+ room::AddExit(cmd, dest);
+}
+
+// Wird benutzt beim Laden von Raeumen, um alle Ausgaenge zu loeschen. Dabei
+// darf _kein_ Notausgang erstellt werden.
+void RemoveExitNoCheck(mixed cmd)
+{
+ room::RemoveExit(cmd);
+}
+
+// beim Ausgang setzten testen ob vorhanderner Notausgang noch benoetigt wird
+void AddExit(mixed cmd, mixed dest)
+{
+ room::AddExit(cmd, dest);
+
+ if (member(m_indices(QueryProp(P_EXITS)),"notausgang")!=-1)
+ {
+ // loescht Notausgang falls nicht mehr benoetigt
+ make_emergency_exit();
+ }
+}
+
+// beim Ausgang loeschen testen ob Notausgang benoetigt wird
+void RemoveExit(mixed cmd)
+{
+ room::RemoveExit(cmd);
+ // setzt Notausgang falls benoetigt
+ make_emergency_exit();
+}
+
+// der Langbeschreibung werden alle unsichtbaren Magier
+// (ausgenommen Seherhausbesitzer) in Klammern angefuegt
+varargs string int_long(mixed viewer, mixed viewpoint, int flags)
+{
+ string ret;
+ object *inv;
+ string *tmp;
+
+ ret = ::int_long(viewer, viewpoint, flags);
+
+ // nur was machen wenn der Betrachter im Raum ist
+ if (!ret || !objectp(viewer) || environment(viewer) != this_object())
+ return ret;
+
+ if(viewpoint == 0)
+ viewpoint = ({ viewer });
+ else if(!pointerp(viewpoint))
+ viewpoint = ({ viewpoint });
+
+ // alle Lebewesen ausser denen aus deren Sicht betrachtet wird
+ inv = filter(all_inventory(this_object()),#'interactive) - viewpoint;
+ foreach(object pl : inv)
+ {
+ // raussuchen wer ausser Seherhausbesitzer unsichtbar ist
+ if(pl && IS_LEARNER(pl) && pl->QueryProp(P_INVIS) && getuid(pl)!=owner)
+ {
+ // Name in Klammer sammeln
+ tmp += ({ "("+capitalize(getuid(pl))+")" });
+ }
+ }
+ return ret + break_string(CountUp(tmp), 78);
+}
+/*
+// TODO: Testen ob das hier nicht das Standard-Verhalten ist
+int lies(string str)
+{
+ string txt;
+
+ notify_fail("Was moechtest Du lesen?\n");
+ if (!str) return 0;
+
+ if (this_player()->CannotSee())
+ return 1;
+ if (txt = QueryProp(P_READ_DETAILS)[str]) {
+ this_player()->More(txt);
+ return 1;
+ }
+ return 0;
+}
+*/
+// Aktion Lebewesen oder Gegenstaende aus dem Haus werfen
+int wirf(string str)
+{
+ string wen, args;
+ object pl, target, *list, tp, to;
+
+ tp = this_player();
+ to = this_object();
+ args = tp->_unparsed_args(1);
+
+ // klappt nur vor Ort und mit der passenden Syntax
+ if ((environment(tp)!=to) ||
+ !args || args == "" ||
+ (sscanf(args,"%s raus",wen) != 1) )
+ return 0;
+ // Raum, in dem das Haus steht, ermitteln
+ target=find_object(VERWALTER->HausProp(owner, HP_ENV));
+ if (!target) {
+ notify_fail("Dieses Haus steht leider gerade in einem "
+ "Fehler im Raum-Zeit-Gefuege.\n");
+ return 0;
+ }
+ // Rauswerfen darf nur der Besitzer
+ if (!tp_owner_check()) {
+ notify_fail("Aber Du kannst doch niemanden aus dem Haus von "+capitalize(owner)+" werfen!\n");
+ return 0;
+ }
+ if (wen=="alle") {
+ // alle Lebewesen ausser tp (== Hausbesitzer)
+ list=filter(all_inventory(to),#'living)-({tp,0});//')
+ if (sizeof(list)==0) {
+ notify_fail("Aber Du bist doch allein in Deinem Haus!\n");
+ return 0;
+ }
+ } else if (wen == "alles") {
+ // alle Gegenstaende ausser Lebewesen und Moebel
+ // (Seherhaustruhe, Autoloader-Moebel oder Seherhaus-Moebel)
+ list = filter(all_inventory(to),
+ function int(object ob)
+ {
+ return objectp(ob) &&
+ !living(ob) &&
+ !ob->id(TRUHE) &&
+ // TODO Test auf nicht Seherhausmoebel von August
+ strstr(load_name(ob),"/d/seher/haeuser/moebel/")
+ == 0;
+ } );
+
+ if (sizeof(list)==0) {
+ notify_fail("Aber hier ist nichts zum wegwerfen!\n");
+ return 0;
+ }
+ } else {
+ pl=present(wen,to);
+ if (!pl) {
+ notify_fail("So jemanden sehe ich hier nicht.\n");
+ return 0;
+ }
+ else if (pl->id(TRUHE) ||
+ // TODO Test auf Seherhausmoebel von August
+ strstr(load_name(pl),"/d/seher/haeuser/moebel/")==0
+ ) {
+ notify_fail("Du kannst "+pl->name(WEN)+" nicht wegwerfen!\n" );
+ return 0;
+ }
+ list=({pl});
+ }
+ string msg_wen = sprintf("%s wirft Dich aus %s Haus.\n",
+ tp->Name(WER),
+ tp->QueryPossPronoun(NEUTER,WEM));
+ // fuer alle rauszuwerfenden Opfer Meldungen machen und rausbewegen
+ foreach(object ob : list)
+ {
+ tell_object(ob, msg_wen);
+ tell_room(target,
+ sprintf("%s kommt in hohem Bogen aus dem Haus von %s geflogen.\n",
+ ob->Name(WER),tp->name(WEM)));
+ ob->move(target,M_SILENT|M_GO);
+ tell_room(to,sprintf("%s wirft %s aus %s Haus.\n",
+ tp->Name(WER),
+ ob->name(WEN),tp->QueryPossPronoun(NEUTER,WEM)),
+ ({tp}));
+ printf("Du wirfst %s aus Deinem Haus.\n",ob->name(WEN));
+ // Verfolger abmelden, damit sie nicht gleich zurueckkommen
+ // TODO wenn man einzelne Lebewesen rauswirft kann das ja auch
+ // ein Verfolger von einem anderen Gast sein...
+ tp->RemovePursuer(ob);
+ }
+ return 1;
+}
+
+// Besitzer und Raumnummer fuer diesen Raum setzen
+varargs string SetOwner(string o, int num)
+{
+ // Default Kurz- und Langbeschreibung setzen
+ SetProp(P_INT_SHORT, "Im Haus von "+capitalize(o));
+ SetProp(P_INT_LONG, "Ein total leerer Raum.\n");
+ // Raumnummer und Besitzer merken
+ raumNr = num;
+ return owner = o;
+}
+
+// Liefert den Besitzer
+// falls withNr != 0 mit angehaengter Raumnummer
+varargs string QueryOwner(int withNr)
+{
+ return (withNr ? owner+raumNr : owner);
+}
+
+// Prototype
+static int befEingabe(string *bef);
+
+// Aktion zum Beschreiben des Raumes
+varargs int
+beschreiben(string str, int f)
+{
+ string *parts;
+ int sp, ret;
+
+ // nur der Besitzer darf
+ if(!tp_owner_check())
+ return 0;
+
+ if (!f && (!(str=UP_ARGS(this_player())) || str == "")) {
+ notify_fail("Was willst Du denn beschreiben?\n" );
+ return 0;
+ }
+
+ sp = sizeof(parts = old_explode(str, " "));
+ // je nachdem was beschrieben wird, setze detail und flag
+ // und starte damit Editor, bzw. behandle Befehle extra
+ detail = 0;
+ flag = f;
+
+ switch(parts[0][0..3]) {
+ case "raum": // Lang- oder Kurzbeschreibung
+ case "haus":
+ if (sp == 1 || parts[1] == "lang")
+ flag |= LANG;
+ else if (parts[1] == "kurz")
+ flag |= KURZ;
+ printf("Bitte %sbeschreibung des %s eingeben.\n", (flag & LANG ? "Lang" : "Kurz"), (flag & AUSSEN ? "Hauses" : "Raumes") );
+ break;
+ case "deta": // Details
+ if (sp==1) {
+ notify_fail("Welches Detail willst Du denn beschreiben?\n");
+ return 0;
+ }
+ flag |= DETAIL;
+ str = implode(parts[1..]," ");
+ write( "Bitte Beschreibung fuer '"+str+"' eingeben.\n");
+ break;
+ case "lesb": // lesbare Details
+ notify_fail("Welches lesbare Detail willst Du denn beschreiben?\n");
+ if (sp == 1) return 0;
+ if (parts[1] == "details" || parts[1] == "detail") {
+ if (sp == 2) return 0;
+ str = implode(parts[2..]," ");
+ }
+ else
+ str = implode(parts[1..]," ");
+ flag |= RDETAIL;
+ write( "Bitte Beschreibung fuer '"+str+"' eingeben.\n");
+ break;
+ case "befe": // Befehle
+ ret = 0;
+ if (sp == 1)
+ notify_fail("Welchen Befehl willst Du denn beschreiben?\n");
+ else
+ ret = befEingabe(brk(implode(parts[1..]," ")));
+ return ret;
+ break;
+ default:
+ notify_fail("Das kannst Du nicht beschreiben! Eine Liste der Dinge, die Du hier\n"
+ +"beschreiben kannst, erhaeltst Du mit 'hilfe beschreibe'.\n" );
+ return 0;
+ break;
+ }
+ detail = brk(str);
+ write( "(Beenden mit . oder **, Abbruch mit ~q)\n" );
+ nedit( "beschreibung" );
+ return 1;
+}
+
+// nedit von beschreibe xxx
+static void beschreibung(string str)
+{
+ if (!str) {
+ write("Nichts geaendert!\n");
+ return;
+ }
+
+ str = normstr(str);
+
+ if (flag & LANG)
+ {
+ // Langbeschreibung
+ if (sizeof(explode(str,"\n")) > 100
+ || sizeof(str) > 7800)
+ {
+ // ueber 100 Zeilen oder ueber 7800 Zeichen
+ write( "Das ist fuer eine Langbeschreibung zu lang!\n"
+ "Sorry, bitte denke Dir eine andere Langbeschreibung aus.\n" );
+ return;
+ }
+ if (flag & AUSSEN) {
+ // Langbeschreibung vom Haus
+ object haus;
+ haus = find_object(HAUSNAME(owner));
+ haus->SetProp(P_LONG, str);
+ haus->Save();
+ }
+ else
+ // Langbeschreibung von diesem Raum
+ SetProp(P_INT_LONG, str);
+ }
+ else if (flag & KURZ) {
+ // Kurzbeschreibung vom Raum
+ if (sizeof(old_explode(str,"\n")) > 1 || sizeof(old_explode(str,".")) > 2 || sizeof(str) > 75) {
+ write( "Das ist fuer eine Kurzbeschreibung zu lang!\nSorry, bitte denke Dir eine andere Kurzbeschreibung aus.\n" );
+ return;
+ }
+ else
+ // Vanion, 27.07.02, Bugfix
+ // Die Zeile buggte, wenn man "." oder "\n" oder "\n." oder sowas
+ // in str hat. (also z.B. bei "beschreibe raum kurz <return> .")
+ // SetProp(P_INT_SHORT, old_explode(old_explode(str,"\n")[0],".")[0]);
+ SetProp(P_INT_SHORT, explode(explode(str,"\n")[0],".")[0]);
+ }
+ else if (flag & DETAIL)
+ // Raum-Detail
+ AddDetail(detail, str);
+ else if (flag & RDETAIL)
+ // lesbares Raum-Detail
+ AddReadDetail(detail, str);
+ else {
+ write( "Huch! Unbekanntes Flag ("+flag+")... Sag mal "
+ + CountUp(MAINTAINER, ", ", " oder ")
+ + " Bescheid...\n");
+ return;
+ }
+
+ write("OK.\n");
+ Save();
+}
+
+// wird in beschreiben(str, int) 'beschreibe befehl' aufgerufen
+static int befEingabe(string *befehle)
+{
+ string* com = ({});
+
+ notify_fail("Kein Befehl zum Beschreiben uebrig... ;)\n");
+ foreach(string bef : befehle)
+ {
+ // schon vorhandener Befehl (ausser oeffnen/schlissen),
+ // Richtung ohne zugehoerigen Ausgang,
+ // oder Befehl enthaelt Leerzeichen
+ if (!befCheck(bef))
+ write("Der Befehl '"+bef+"' kann nicht beschrieben werden!\n");
+ else
+ com += ({ bef });
+ }
+ if (!sizeof(com))
+ return 0;
+
+ arr_out(com, 0, "Zu beschreibender Befehl: %s",
+ "Zu beschreibende Befehle:\n");
+
+ write( "Bitte Parameter eingeben (evtl. durch Kommata getrennt).\n]");
+ input_to("getBefParam", 0, com);
+ return 1;
+}
+
+// input_to aus befEingabe(string) zu beschreibe befehl ...
+static void getBefParam(string param, string *bef)
+{
+ string txt = "Gib nun bitte den Text ein, der fuer diesen Befehl "
+ "ausgegeben werden soll.\n";
+
+ // Fuehrende und abschliessende Leerzeichen entfernen
+ if (param)
+ param = trim(param);
+
+ if (!param || param == "")
+ // kein Parameter, z.b. bei beschreibe befehl klopfe
+ detail = ({ bef, "" });
+ else if (param == "@NF@" || param == "@nf@") {
+ // Parameter fuer notify fail zum Ersetzen von Wie bitte?
+ // z.B. bei beschreibe befehl druecke
+ // fuer danach Du kannst hier kein @PARA druecken, nur den Knopf!
+ detail = ({ bef, 1 });
+ txt = "Gib nun bitte den Text ein, der als Fehlermeldung "
+ "ausgegeben werden soll.\n@PARA dient dabei als Platzhalter fuer "
+ "die ungueltige Eingabe.\n";
+ }
+ else
+ // sonstige Parameter
+ // z.B. knopf, klingel bei beschreibe befehl druecke
+ detail = ({ bef }) + brk(lower_case(param));
+
+ printf(txt+"(Beenden mit . oder **, Abbruch mit ~q)\n");
+ nedit("getBefText");
+}
+
+// Prototype
+private string preparse(string str, string *invalid);
+
+// nedit fuer die Eingabe der Texte (Fehlermeldung/Meldungen) fuer den Befehl
+static void getBefText(string text)
+{
+ string my, *txt, *warn;
+ mixed bef;
+
+ if (!text || text == "") {
+ write("** Abbruch! **\n");
+ detail = 0;
+ return;
+ }
+ // gemerktes Befehls-Array
+ bef = detail[0];
+
+ txt = old_explode(text, "@@\n");
+
+ warn = ({});
+
+ // Meldung an this_player() parsen und in warn falsche Platzhalter sammeln
+ my = preparse(txt[0], &warn);
+ string other = 0;
+ if (sizeof(txt) > 1)
+ // Meldung an andere parsen und in warn falsche Platzhalter sammeln
+ other = preparse(txt[1], &warn);
+
+ AddUserCmd(bef, (stringp(detail[1]) ? detail[1..] : ({ "@NF@" })), my, other);
+ Save();
+ arr_out(warn, "OK.", "WARNUNG! Ungueltiger Platzhalter: %s",
+ "WARNUNG! Ungueltige Platzhalter: ");
+
+ detail = 0;
+}
+
+// check, ob an Position pos in txt ein Buchstabe aus dem array choice steht
+// return 0 falls nicht, prefix + Position des Buchstabens in choice ansonsten
+// check_placeholder(({"R","S","M","N"}), 2, "WESSEN", "X"); -> X1
+string check_placeholder(string* choice, int pos, string txt, string prefix)
+{
+ int idx;
+
+ if(sizeof(txt) < pos+1 ||
+ ((idx=member(choice, txt[pos..pos])) < 0))
+ {
+ return 0;
+ }
+ else
+ {
+ return prefix+to_string(idx);
+ }
+}
+
+// Dann drueckt @PWER den Knopf -> Dann drueckt @P0 den Knopf
+private string preparse(string str, string *invalid)
+{
+ string *txt;
+
+ txt = explode(str, "@");
+ // fuer jeden Textteil nach einem @
+ // suche Ersatz fuer den Begriff direkt nach dem @
+ // AN: wuerde es nicht theoretisch reichen, hier nur bis i>0
+ // runterzuzaehlen? Das erste Element des Arrays ist immer irrelevant, weil
+ // entweder Leerstring oder kein zu ersetzender Ausdruck.
+ for (int i=sizeof(txt)-1; i>=0; i--) {
+ int warn = 0;
+ string rpl = 0;
+ // falls Teil zu kurz nix ersetzen
+ if (sizeof(txt[i])<3)
+ continue;
+ // anhand der ersten Buchstaben, Ersatz bestimmen
+ // warn signalisiert, ob dies schiefging:
+ switch(txt[i][0..1]) {
+ case "WE": // Name
+ // WER -> W0
+ // WES(SEN) -> W1
+ // WEM -> W2
+ // WEN -> W3
+ rpl = check_placeholder(({"R","S","M","N"}), 2, txt[i], "W");
+ warn = !rpl;
+ break;
+ case "PW": // Personalpronomen
+ // PWER -> P0
+ // PWES(SEN) -> P1
+ // PWEM -> P2
+ // PWEN -> P3
+ rpl = check_placeholder(({"R","S","M","N"}), 3, txt[i], "P");
+ warn = !rpl;
+ break;
+ case "BN": // Possessivpronomen
+ case "BM":
+ case "BF":
+ // BNSWER -> B000 BMSWER -> B010 BFSWER -> B020
+ // BNSWES(SEN) -> B100 BMSWES(SEN) -> B110 BFSWES(SEN) -> B120
+ // BNSWEM -> B200 BMSWEM -> B210 BFSWEM -> B220
+ // BNSWEN -> B300 BMSWEN -> B310 BFSWEN -> B320
+ //
+ // BNPWER -> B001 BMPWER -> B011 BFPWER -> B021
+ // BNPWES(SEN) -> B101 BMPWES(SEN) -> B111 BFPWES(SEN) -> B121
+ // BNPWEM -> B201 BMPWEM -> B211 BFPWEM -> B221
+ rpl = check_placeholder(({"R","S","M","N"}), 5, txt[i], "B");
+ warn = !rpl;
+ if(!warn)
+ {
+ rpl = check_placeholder(({"N","M","F"}), 1, txt[i], rpl);
+ warn = !rpl;
+ if(!warn)
+ {
+ rpl = check_placeholder(({"S","P"}), 2, txt[i], rpl);
+ warn = !rpl;
+ }
+ }
+ break;
+ case "PA":
+ // PARA -> F
+ // kein Ersatz, sondern Textteil hier direkt ersetzen:
+ if(sizeof(txt[i]) > 4)
+ txt[i] = "F"+txt[i][4..];
+ break;
+ default:
+ // kein Ersatz, nix aendern
+ warn = 0;
+ rpl = 0;
+ }
+
+ // falls Ersatz vorhanden, ersetze Pronomen durch ""+rpl und lasse den Rest t2[2] wie ist
+ if (rpl) {
+ string* t2;
+ warn = sizeof(t2 = regexplode(txt[i], "(WER|WESSEN|WEM|WEN)")) < 2;
+ if (!warn) {
+ t2[1] = rpl;
+ t2[0] = "";
+ txt[i] = implode(t2, "");
+ }
+ }
+ // falls es Probleme gab, diese merken
+ if (warn)
+ invalid += ({ "@"+old_explode(txt[i]," ")[0] });
+
+ } // for (i=sizeof(txt)-1; i>=0; i--)
+ // die eventuelle teilweise ersetzetn Teile wieder zusammenfuegen
+ return implode(txt, "@");
+}
+
+static void loesch_alles(string str)
+{
+ if (str == "ja" || str == "Ja") {
+ RemoveDetail(0);
+ RemoveReadDetail(0);
+ //SetProp(P_READ_DETAILS, ([]));
+ SetProp(H_COMMANDS, ([]));
+ write( "OK, alle Details, lesbaren Details und Befehle geloescht!\n" );
+ Save();
+ }
+ else
+ write( "Nichts geloescht!\n" );
+}
+
+static void loesch_etwas(string str, string prop)
+{
+ if (str == "ja" || str == "Ja") {
+ if ( prop == P_DETAILS )
+ RemoveDetail(0);
+ else if ( prop == P_READ_DETAILS )
+ RemoveReadDetail(0);
+ else
+ SetProp(prop, ([]));
+ write("OK.\n");
+ Save();
+ }
+ else
+ write( "Nichts geloescht!\n" );
+}
+
+int loesch(string str)
+{
+ string *s, *t, p, q;
+ int i, ret;
+ mapping com;
+
+ if (!tp_owner_check())
+ return 0;
+
+ if (!(str=UP_ARGS(this_player())) || str == "") {
+ notify_fail("Welches Detail oder welchen Befehl moechtest Du loeschen?\n");
+ return 0;
+ }
+
+ if (str == "alles") {
+ write( "Wirklich alles loeschen (ja/nein)?\n]");
+ input_to("loesch_alles");
+ return 1;
+ }
+
+ if(str=="meldungen") {
+ if(file_size(PATH+"rep/"+owner+".rep")>0) {
+ rm(PATH+"rep/"+owner+".rep");
+ write("Meldungen geloescht.\n");
+ }else{
+ write("Keine Meldungen gefunden.\n");
+ }
+ return 1;
+ }
+
+ s = brk(str);
+ s = ({ (t=old_explode(s[0], " "))[0] })+({ implode(t[1..]," ") })+s[1..];
+ ret = 1;
+ flag = 0;
+
+ switch(s[0]) {
+ case "detail":
+ s = s[1..];
+ flag |= DETAIL;
+ break;
+ case "lesbar":
+ flag |= RDETAIL;
+ s = s[1..];
+ break;
+ case "lesbares":
+ case "lesbare":
+ flag |= RDETAIL;
+ if (s[1][0..5] =="detail") {
+ s = ({ old_explode(s[1]," ")[<1] });
+ if (sizeof(s)>2)
+ s += s[2..];
+ }
+ else
+ s = s[1..];
+ break;
+ case "befehl":
+ s = s[1..];
+ break;
+ case "alle":
+ switch (s[1]) {
+ case "details":
+ q = "Details";
+ p = P_DETAILS;
+ break;
+ case "lesbaren details":
+ q = "lesbaren Details";
+ p = P_READ_DETAILS;
+ break;
+ case "befehle":
+ q = "Befehle";
+ p = H_COMMANDS;
+ break;
+ default:
+ write("Du kannst alle Befehle, alle Details und alle lesbaren Details loeschen!\n");
+ return 1;
+ }
+ printf("Wirklich alle %s loeschen (ja/nein)?\n]", q);
+ input_to("loesch_etwas", 0, p);
+ return 1;
+ default:
+ flag |= (DETAIL|RDETAIL);
+ ret = 0; // Koennte auch ein Artikel in der Zeitung sein...
+ break;
+ }
+ for (i=sizeof(s)-1; i>=0; i--) {
+ if (!flag) { // Befehl soll geloescht werden...
+ if (member(com=Query(H_COMMANDS), s[i])) {
+ com = m_copy_delete(com, s[i]);
+ write("Befehl '"+s[i]+"' wurde geloescht.\n");
+ }
+ else if (sizeof(t=old_explode(s[i], " ")) > 1 &&
+ member(com, t[0]) &&
+ member(com[t[0]], p=implode(t[1..], " "))) {
+ com[t[0]] = m_copy_delete(com[t[0]], p);
+ write("Befehl '"+s[i]+"' wurde geloescht.\n");
+ }
+ Set(H_COMMANDS, com);
+ }
+ else {
+ if (flag & DETAIL) {
+ if (!QueryProp(P_DETAILS)[s[i]])
+ notify_fail("Das Detail '"+s[i]+"' gibt es nicht.\n");
+ else {
+ RemoveDetail(s[i]);
+ write("Detail '"+s[i]+"' wurde geloescht.\n");
+ ret = 1;
+ }
+ }
+ if (flag & RDETAIL) {
+ if (!QueryProp(P_READ_DETAILS)[s[i]])
+ notify_fail("Das lesbare Detail '"+s[i]+"' gibt es nicht.\n");
+ else {
+ RemoveReadDetail(s[i]);
+ write("Lesbares Detail '"+s[i]+"' wurde geloescht.\n");
+ ret = 1;
+ }
+ }
+ }
+ }
+ Save();
+ return ret;
+}
+
+int ausgang(string str)
+{
+ int nr, maxNr, hin, zurueck;
+ string hier, da, ext;
+ closure hausProp;
+ mapping known_exits;
+
+ if (!tp_owner_check()) {
+ return 0;
+ }
+
+ hier = da = 0;
+ hausProp = symbol_function("HausProp",VERWALTER);
+
+ if (!(str=UP_ARGS(this_player())) ||
+ (sscanf(str, "%s %d", hier, nr) != 2 &&
+ sscanf(str, "%s %s %d",hier, ext, nr) != 3) ) {
+ notify_fail( "Syntax: ausgang <richtung> [name] <nr>\n" );
+ return 0;
+ }
+
+ if (ext) {
+ if (funcall(hausProp, ext, HP_ENV) != funcall(hausProp, owner, HP_ENV)) {
+ printf("Das Haus von %s steht nicht im gleichen Raum wie Dein Haus!\n",
+ capitalize(ext));
+ return 1;
+ }
+ else
+ da = RAUMNAME(ext, nr);
+
+ // der allowed_check() wird im Eingangsraum des Zielhauses aufgerufen,
+ // da wir von anderen Raumen noch nicht wissen, ob sie ueberhaupt
+ // existieren.
+ if (!(RAUMNAME(ext, 0)->allowed_check(this_player()))) {
+ printf("Du darfst keinen Ausgang von Deinem Haus zu dem von %s legen!\n",
+ capitalize(ext));
+ return 1;
+ }
+ }
+ else {
+ ext = owner;
+ da = RAUMNAME(ext, nr);
+ }
+
+ maxNr = funcall(hausProp, ext, HP_ROOMS);
+
+ if ( (hin = member(ausgaenge, lower_case(hier))) < 0) {
+ arr_out(ausgaenge, 0, 0, "Es sind nur folgende Ausgaenge moeglich:\n" );
+ return 1;
+ }
+ else
+ zurueck = (hin + sizeof(ausgaenge)/2) % sizeof(ausgaenge);
+
+ hier = RAUMNAME(owner, raumNr);
+
+ // Kopie des Ausgaenge-Mappings erzeugen
+ known_exits=deep_copy(QueryProp(P_EXITS));
+ // und den Notausgang entfernen. Somit bleiben nur die zu betrachtenden
+ // Ausgaenge ueber.
+ known_exits["notausgang"]=0;
+
+ if (nr < 0 || nr > maxNr)
+ printf( "Die Nummer darf sich nur im Bereich zwischen 0 und %d bewegen!\n",
+ maxNr );
+ else if ( ext == owner && nr == raumNr)
+ printf( "Aber dies IST Raum %d!\n", raumNr );
+ else if (member(m_indices(known_exits), ausgaenge[hin]) != -1)
+ write( "Aus diesem Raum fuehrt schon ein Ausgang in diese Richtung!\n" );
+ //else if (member(m_values(QueryProp(P_EXITS)), da) != -1)
+ // Notausgang wird hier zwar geloescht, aber im AddExit
+ // gibt's eh einen neuen, so das noetig ist, V*
+ else if (member(m_values(known_exits), da) != -1)
+ printf( "Es gibt hier schon einen Ausgang zu Raum %d!\n", nr );
+ else if (member(m_indices(da->QueryProp(P_EXITS)), ausgaenge[zurueck]) != -1)
+ printf( "Es fuehrt schon irgendwo ein Ausgang in Richtung '%s'\n"
+ "nach Raum %d!\n", ausgaenge[hin], nr);
+ else {
+ AddExit( ausgaenge[hin], da );
+ Save();
+ da->AddExit(ausgaenge[zurueck], hier);
+ da->Save();
+ printf( "OK, der Ausgang '%s' zum Raum %d wurde eingerichtet.\n",
+ ausgaenge[hin], nr );
+ }
+ return 1;
+}
+
+int
+sperren(string str)
+{
+ mapping ex, cmds;
+ int hin, zurueck;
+
+ if (!tp_owner_check())
+ return 0;
+
+ if (!(str=UP_ARGS(this_player())) || str == "") {
+ notify_fail( "Syntax: sperre <ausgang>\n" );
+ return 0;
+ }
+ str = lower_case(str);
+ ex = QueryProp(P_EXITS);
+
+ if (raumNr == 0 && str == "raus") {
+ write( "Du kannst doch nicht Deine Haustuer loeschen!\n" );
+ return 1;
+ }
+ if (!member(ex,str) || (hin = member(ausgaenge,str)) < 0) {
+ printf( "Es gibt hier keinen Ausgang '%s'!\n", str);
+ return 1;
+ }
+ else
+ zurueck = (hin + sizeof(ausgaenge)/2) % sizeof(ausgaenge);
+
+ ex[str]->RemoveExit(ausgaenge[zurueck]);
+ tell_room(find_object(ex[str]), sprintf("Der Ausgang '%s' verschwindet ploetzlich...\n", ausgaenge[zurueck]));
+ cmds = ex[str]->QueryProp(H_COMMANDS);
+ cmds = m_copy_delete(cmds, ausgaenge[zurueck]);
+ ex[str]->SetProp(H_COMMANDS, cmds);
+ ex[str]->Save();
+ RemoveExit(str);
+ cmds = QueryProp(H_COMMANDS);
+ cmds = m_copy_delete(cmds, str);
+ SetProp(H_COMMANDS, cmds);
+ Save();
+ printf( "OK, der Ausgang '%s' wurde entfernt.\n", str );
+
+ Save();
+
+ return 1;
+}
+
+varargs int
+uebersicht(string dummy, string pre)
+{
+ string *xc, *xd, o, raus, str;
+ mixed *com;
+ mapping tmp;
+ int i,j,k;
+
+ if ( (getuid(this_player()) != owner) &&
+ !(PATH+"access_rights")->access_rights(geteuid(this_player()), "") )
+ return 0;
+
+ i = VERWALTER->HausProp(owner, HP_ROOMS);
+
+ if (i)
+ str = sprintf( "Dein Haus verfuegt ueber %d Raeume.\nDu stehst in Raum %d (%s).\n\n", i+1, raumNr, QueryProp(P_INT_SHORT) );
+ else
+ str = sprintf( "Dein Haus verfuegt ueber einen Raum (%s)\n\n", QueryProp(P_INT_SHORT));
+
+ str += arr_out(m_indices(QueryProp(P_DETAILS)),
+ "Du hast keine Details beschrieben.",
+ "Du hast das Detail '%s' beschrieben.",
+ "Du hast folgende Details beschrieben:\n", 1 );
+
+ str += ("\n" + arr_out(m_indices(QueryProp(P_READ_DETAILS)),
+ "Du hast keine lesbaren Details beschrieben.",
+ "Du hast das lesbare Detail '%s' beschrieben.",
+ "Du hast folgende lesbaren Details beschrieben:\n", 1 ) );
+
+ tmp = Query(H_COMMANDS);
+ xc = sort_array(m_indices(tmp),#'<);
+ if (!sizeof(xc))
+ str += ("\nDu hast keine Befehle beschrieben.\n");
+ else {
+ if (sizeof(xc) == 1 && sizeof(xd=m_indices(tmp[xc[0]])) == 1)
+ str += ("\nDu hast den Befehl '"+
+ xc[0]+((xd[0] == "") ? "" : " "+xd[0])+
+ "' beschrieben.\n");
+ else {
+ str += "\nDu hast folgende Befehle beschrieben:\n";
+
+ for (com = ({}), j=sizeof(xc)-1; j >= 0; j--) {
+ xd = sort_array(m_indices(tmp[xc[j]])-({"@NF@"}),#'>);
+ if ((sizeof(xd) > 1) && (xd[0] == "")) {
+ raus = "* "+xc[j]+", "+xc[j]+" ";
+ xd = xd[1..];
+ }
+ else
+ raus = "* "+xc[j]+" ";
+
+ str += arr_out(xd, "", raus+"%s", raus, 3);
+ }
+ }
+ }
+
+ raus = (member(QueryProp(P_EXITS),"raus") ? "raus: Nach draussen.\n" : 0 );
+ tmp = m_copy_delete(QueryProp(P_EXITS), "raus");
+ m_delete(tmp, "notausgang");
+ xc = m_indices(tmp);
+ xd = m_values(tmp);
+
+ if (!sizeof(xc) && !raus)
+ str += "\nES GIBT KEINE AUSGAENGE!\n";
+ else {
+ str += "\nEs gibt folgende Ausgaenge:\n";
+ for (i=sizeof(xc)-1; i>=0; i--)
+ str += sprintf( "%s: Nach Raum %d %s(%s).\n",
+ xc[i],
+ (j=to_int(xd[i][<1..])),
+ (((o=old_explode(xd[i],"/")[<1][0..<6])==owner) ?
+ "" : "von "+capitalize(o)+" "),
+ xd[i]->QueryProp(P_INT_SHORT) );
+ }
+ str += ((raus||"")+(pre||""));
+ this_player()->More(str);
+ return 1;
+}
+
+int kopieren(string str)
+{
+ string was, alt, n, *neu, *par, err;
+ mixed das;
+ mapping com;
+
+ if (!tp_owner_check())
+ return 0;
+
+ notify_fail("'kopiere detail <von> nach <nach>' oder\n"
+ +"'kopiere lesbares detail <von> nach <nach>' oder\n"
+ +"'kopiere befehl <befehl> [<parameter>] nach <befehl> [<parameter>]'!\n");
+
+ if (!(str=UP_ARGS(this_player())) || str == "")
+ return 0;
+
+ neu = old_explode(str, " ");
+ was = neu[0][0..5];
+ if (was == "detail" || was == "befehl")
+ str = implode(neu[1..], " ");
+ else if (was == "lesbar")
+ str = implode(neu[2..], " ");
+ else
+ return 0;
+
+ if (sscanf(str, "%s nach %s", alt, n) != 2)
+ return 0;
+
+ neu = brk(n);
+ switch(was) {
+ case "detail":
+ err = "Detail";
+ if (das = GetDetail(alt)) {
+ AddDetail(neu, das);
+ Save();
+ }
+ break;
+ case "lesbar":
+ err = "lesbares Detail";
+ if (das = QueryProp(P_READ_DETAILS)[alt]) {
+ AddReadDetail(neu, das);
+ Save();
+ }
+ break;
+ case "befehl":
+ err = "Befehl";
+ was = (par=old_explode(alt, " "))[0];
+ if (member(com=QueryProp(H_COMMANDS),was)) {
+ int i;
+ if (sizeof(par) == 1) { // <bef> nach <bef1,bef2,...>
+ das = com[was];
+ for (i=sizeof(neu)-1; i>=0; i--) {
+ if (befCheck(neu[i])) {
+ if (com[neu[i]])
+ com[neu[i]] += das;
+ else
+ com += ([ neu[i] : das ]);
+ }
+ else
+ write("Ungueltiger Befehl: '"+neu[i]+"'.\n");
+ }
+ }
+ else { // <bef> <parameter> nach <bef1,bef2,...>
+ alt = implode(par[1..]-({""})," ");
+ if (das = com[was][alt]) {
+ for (i=sizeof(neu)-1; i>=0; i--) {
+ if (befCheck(neu[i])) {
+ das = ([ alt : com[was][alt];com[was][alt,1] ]);
+ if (com[neu[i]])
+ com[neu[i]] += das;
+ else
+ com += ([ neu[i] : das ]);
+ }
+ else {
+ par = old_explode(neu[i], " ");
+ n = par[0];
+ if (befCheck(n)) {
+ das = ([ implode(par[1..], " ") : com[was][alt];com[was][alt,1] ]);
+ if (com[n])
+ com[n] += das;
+ else
+ com += ([ n : das ]);
+ }
+ else
+ write("Ungueltiger Befehl: '"+neu[i]+"'.\n");
+ }
+ }
+ }
+ }
+ Save();
+ }
+ break;
+ default:
+ write( "Du kannst nur Details, lesbare Details und Befehle kopieren!\n" );
+ return 1;
+ }
+ if (!das)
+ printf( "Kann %s '%s' nicht finden!\n", err, alt);
+ else
+ write( "OK!\n" );
+
+ return 1;
+}
+
+int licht(string str)
+{
+ int ll, tl;
+
+ if (!allowed_check(this_player()))
+ return 0;
+
+ if (!str || (str != "an" && str != "aus")) {
+ notify_fail("Syntax: 'licht an' oder 'licht aus'\n");
+ return 0;
+ }
+
+ ll = QueryProp(P_LIGHT);
+ tl = PL->QueryProp(P_PLAYER_LIGHT);
+
+ switch(str) {
+ case "an":
+ if (tl > 0)
+ write("Aber es ist doch schon hell!\n");
+ else {
+ SetProp(P_LIGHT, 1);
+ tell_room(this_object(), "Es wird wieder hell.\n");
+ }
+ break;
+ case "aus":
+ if (tl <= 0)
+ write("Aber es ist doch schon dunkel!\n");
+ else {
+ SetProp(P_LIGHT, 0);
+ tell_room(this_object(), "Es wird dunkel.\n");
+ }
+ break;
+ }
+ return 1;
+}
+
+#define CASUS ({ "WER", "WESSEN", "WEM", "WEN" })
+static string rpXchg(string s)
+{
+ int c,p,g;
+
+ switch(s[0..1]) {
+ case "@W":
+ c = to_int(s[2..2]);
+ return ("@"+CASUS[c]);
+ case "@P":
+ c = to_int(s[2..2]);
+ return ("@P"+CASUS[c]);
+ case "@B":
+ c = to_int(s[2..2]);
+ g = to_int(s[3..3]);
+ p = to_int(s[4..4]);
+ return ("@B"+({"N", "M", "F"})[g]+({"S", "P"})[p]+CASUS[c]);
+ case "@F":
+ return "@PARA";
+ }
+ return s;
+}
+
+private string reParse(string s1, string s2)
+{
+ string *p;
+
+ if (s2)
+ s1 = s1+"@@\n"+s2;
+
+ p = regexplode(s1, "(@W[0-3]|@P[0-3]|@B[0-3][0-2][0-1])");
+ p = map(p, #'rpXchg);
+ return implode(p, "");
+}
+
+private string getPreText(string prop, string expr)
+{
+ mixed crunched;
+ int i;
+
+ crunched = VERWALTER->PCrunch(QueryProp(prop));
+ if (!crunched || !pointerp(crunched))
+ return 0;
+
+ if (prop == H_COMMANDS && strstr(expr, " ") < 0)
+ expr = expr+" ";
+
+ for (i=sizeof(crunched)-1; i>=0; i--)
+ if (member(crunched[i][0], expr) >= 0)
+ break;
+
+ if (i<0)
+ return 0;
+
+ detail = crunched[i][0];
+
+ if (prop == H_COMMANDS)
+ return reParse(crunched[i][1], crunched[i][2]);
+ else
+ return crunched[i][1];
+}
+
+varargs int
+aendern(string str, int f)
+{
+ string *parts, pre;
+ int sp, sr, ret;
+
+ if (!tp_owner_check())
+ return 0;
+
+ if (!f && (!(str=UP_ARGS(this_player())) || str == "")) {
+ notify_fail("Was willst Du denn aendern?\n" );
+ return 0;
+ }
+
+ sp = sizeof(parts = old_explode(str, " "));
+ sr = sizeof(brk(str));
+ detail = 0;
+ flag = f;
+
+ switch(parts[0][0..3]) {
+ case "raum": // Lang- oder Kurzbeschreibung
+ case "haus":
+ if (sp == 1 || parts[1] == "lang")
+ flag |= LANG;
+ else if (parts[1] == "kurz") {
+ write("Nimm dazu doch bitte 'beschreibe'!\n");
+ return 1;
+ }
+ pre = ((flag & AUSSEN) ? (find_object(HAUSNAME(owner)))->QueryProp(P_LONG) : QueryProp(P_INT_LONG));
+ break;
+ case "meld":
+ if (file_size(REPFILE(owner)) > 0)
+ pre = read_file(REPFILE(owner));
+ else {
+ write("Ich finde keine Meldungen aus Deinem Haus!\n");
+ return 1;
+ }
+ flag |= REPORT;
+ break;
+ case "deta": // Details
+ if (sp==1) {
+ notify_fail("Welches Detail willst Du denn aendern?\n");
+ return 0;
+ }
+ if (sr>1) {
+ notify_fail("Du kannst immer nur ein Detail aendern!\n");
+ return 0;
+ }
+ flag |= DETAIL;
+ pre = getPreText(P_DETAILS, implode(parts[1..], " "));
+ break;
+ case "lesb": // lesbare Details
+ notify_fail("Welches lesbare Detail willst Du denn aendern?\n");
+ if (sp == 1) return 0;
+ if ((parts[1] == "details" || parts[1] == "detail") && (sp==2))
+ return 0;
+ if (sr>1) {
+ notify_fail("Du kannst immer nur ein lesbares Detail aendern!\n");
+ return 0;
+ }
+ flag |= RDETAIL;
+ pre = getPreText(P_READ_DETAILS, implode(parts[1..], " "));
+ break;
+ case "befe": // Befehle
+ ret = 0;
+ if (sp == 1) {
+ notify_fail("Welchen Befehl willst Du denn aendern?\n");
+ return 0;
+ }
+ if (sr>1) {
+ notify_fail("Du kannst immer nur einen Befehl aendern!\n");
+ return 0;
+ }
+ flag |= BEFEHL;
+ pre = getPreText(H_COMMANDS, implode(parts[1..], " "));
+ break;
+ default:
+ notify_fail("Das kannst Du nicht aendern! Eine Liste der Dinge, die Du hier aendern\n"
+ +"kannst, erhaeltst Du mit 'hilfe aendere'.\n" );
+ return 0;
+ break;
+ }
+ if (!pre)
+ write("Hm, sowas ist hier noch nicht beschrieben...\n");
+ else {
+ write( "Aendere nun den Text.\n(Beenden mit . oder **, Abbruch mit ~q, Hilfe mit ~h)\n" );
+ nedit( "aenderung", pre );
+ }
+ return 1;
+}
+
+void aenderung(string str)
+{
+ string *warn;
+
+ if (!str) {
+ write("Nichts geaendert!\n");
+ return;
+ }
+
+ if (flag && !(flag & BEFEHL))
+ str = normstr(str);
+
+ warn = ({ });
+
+ if (flag & LANG) {
+ if (flag & AUSSEN) {
+ object haus;
+ haus = find_object(HAUSNAME(owner));
+ haus->SetProp(P_LONG, str);
+ haus->Save();
+ }
+ else
+ SetProp(P_INT_LONG, str);
+ }
+ else if (flag & DETAIL) {
+ if (str == "")
+ RemoveDetail(detail);
+ else
+ AddDetail(detail, str);
+ }
+ else if (flag & RDETAIL) {
+ if (str == "")
+ RemoveReadDetail(detail);
+ else
+ AddReadDetail(detail, str);
+ }
+ else if (flag & BEFEHL) {
+ if (str == "")
+ RemUserCmd(detail);
+ else {
+ string *s;
+
+ s = old_explode(preparse(str, &warn), "@@\n");
+ if (sizeof(s) > 1 && s[1] != "")
+ AddUserCmd(detail, 0, normstr(s[0]), normstr(s[1]));
+ else
+ AddUserCmd(detail, 0, normstr(s[0]), 0);
+ }
+ }
+ else if (flag & REPORT) {
+ rm(REPFILE(owner));
+ if (str != "")
+ write_file(REPFILE(owner), str);
+ }
+ else
+ write( "Huch! Unbekanntes Flag ("+flag+")... Sag mal Wargon Bescheid...\n");
+
+ arr_out(warn, "OK.", "WARNUNG! Ungueltiger Platzhalter: %s",
+ "WARNUNG! Ungueltige Platzhalter: ");
+ Save();
+}
+
+int SmartLog(string ofile, string typ, string msg, string date)
+{
+ object home;
+
+ // speichere Meldung im Rep-Log des Seherhaus-Besitzers
+ write_file(REPFILE(owner), sprintf("%s von %s in Raum %d (%s):\n%s\n",
+ typ,
+ capitalize(getuid(this_player())),
+ raumNr,
+ date,
+ break_string(msg,78)));
+
+ if (IS_LEARNER(owner)) {
+ log_file("report/"+owner+".rep",
+ sprintf("MELDUNG von %s im Seherhaus, Raum %d (%s):\n"
+ +"Bitte zur Kenntnis nehmen! (Mit dem Befehl 'meldungen') -Wargon\n",
+ capitalize(getuid(this_player())),
+ raumNr,
+ date));
+ }
+
+ // erhoehe im Hauptraum den Rep-Zaehler und speichere
+ home = load_object(RAUMNAME(owner,0));
+ home->Set(H_REPORT, home->Query(H_REPORT)+1);
+ home->Save();
+
+ return 1;
+}
+
+static int report(string str)
+{
+ string rep, *lines;
+ int rNum, l, s;
+
+ if (!allowed_check(this_player()))
+ return 0;
+
+ if (file_size(REPFILE(owner)) <= 0) {
+ write( "Keine Meldungen zu finden... Du bist wunschlos gluecklich.\n" );
+ return 1;
+ }
+ rep = read_file(REPFILE(owner));
+
+ if (!rep) {
+ write( "Oha! Die Datei mit den Meldungen ist zu gross! Sag doch bitte mal\n"
+ +"Wargon Bescheid!\n");
+ return 1;
+ }
+
+ if (str) {
+ string d, *new, *tmp, prev;
+ int nr, nextNr, m;
+
+ if (str == "hier")
+ rNum = raumNr;
+ else
+ rNum = to_int(str);
+
+ if (rNum > VERWALTER->HausProp(owner, HP_ROOMS)) {
+ write( "So viele Raeume hast Du gar nicht!\n");
+ return 1;
+ }
+
+ lines = old_explode(rep, "\n");
+ s = sizeof(lines);
+ for (l=0; prev == 0; l++)
+ if (sscanf(lines[l], "%s von %s in Raum %d %s:", d, d, nr, d)==4)
+ prev=lines[l];
+
+ for ( new = ({}), tmp=({}); l<s; l++) {
+ m=sscanf(lines[l], "%s von %s in Raum %d %s:", d, d, nextNr, d);
+ if (m != 4 && nr == rNum)
+ tmp += ({ lines[l] });
+
+ if (m==4) {
+ if (sizeof(tmp)) {
+ new = new + ({ prev }) + tmp;
+ tmp = ({});
+ }
+ nr = nextNr;
+ prev = lines[l];
+ }
+ }
+ if (sizeof(tmp))
+ new = new + ({prev}) + tmp;
+ rep = implode(new, "\n");
+ }
+
+ this_player()->More(rep);
+ return 1;
+}
+
+// $Log: raum.c,v $
+// Revision 1.5 2003/11/15 14:03:58 mud
+// Lichtaenderungen von Zook
+//
+// Revision 1.4 2003/02/17 20:00:00 mud
+// Im Reset wird nun getestet, ob der Raum einen Ausgang in einen Null-Raum
+// hat. Dies wurde notwengig, damit Spieler nicht in Seherhaeuser eingesperrt
+// werden koennen. Die Funktionen AddExit(), RemoveExit() und Reset starten
+// gegebenenfalls den Ausgangstest. Einige Funs mussten leicht angepasst
+// werden.
+// Die Funktionen room_has_exit() und is_exit() wurden von Vardion@MG
+// entwickelt und zur Verfuegung gestellt. - Vanion
+//
+// Revision 1.3 2001/02/04 21:21:34 mud
+// (brk,getBefParam): Vorkehrungen gegen fuehrende und schliessende
+// Leerzeichen in Befehlsparametern und anderen Listen.
+//
+// Revision 1.2 2001/01/01 18:17:47 mud
+// (ausgang): Wenn ein Ausgang zu einem anderen Seherhaus gelegt wird,
+// wird die Erlaubnis in dessen Eingangsraum abgefragt, und nicht in
+// dem angeforderten Zielraum (der Eingangsraum existiert auf jeden
+// Fall, der Zielraum vielleicht nicht).
+//
+// Revision 1.1.1.1 2000/08/20 20:22:42 mud
+// Ins CVS eingecheckt
+//
+// 04.02.98 Meldungen koennen geloescht werden.
+//
+// Revision 2.16 1997/11/15 19:33:23 Wargon
+// arr_out(), preparse(): kleine Bugfixes
+//
+// Revision 2.15 1997/10/06 15:24:38 Wargon
+// Unsichtbare Magier melden/anzeigen
+// Meldung beim Betreten abgeschlossener Haeuser fuer Magier
+//
+// Revision 2.14 1996/02/21 18:12:47 Wargon
+// SmartLog() rein, dafuer die eigenen Rueckmeldungsbefehle raus
+//
+// Revision 2.13 1995/10/31 12:56:16 Wargon
+// Rueckmeldungen fuer Objekte werden ans Spielerobjekt weitergegeben.
+//
+// Revision 2.12 1995/08/07 18:35:12 Wargon
+// Einige Bugs bei "aendere" behoben.
+//
+// Revision 2.11 1995/06/29 08:57:05 Wargon
+// Hausbesitzer, die schon Magier sind, bekommen bei Rueckmeldungen auch einen
+// Eintrag in ihr /log/report/xyz.rep-File
+// "licht an/aus" ist seit 2.9 drin ;)
+//
+// Revision 2.10 1995/06/28 08:59:57 Wargon
+// Neue Befehle aendere, meldungen fuer den Hausbesitzer.
+// typo, bug/fehler, idee werden dem Haus-.rep-File zugefuehrt.
+// Jetzt koennen die Seher ihre Typos selber fixen! ;^)
+//
+// Revision 2.9 1995/06/20 07:49:15 Wargon
+// *** empty log message ***
+//
+// Revision 2.8 1995/04/21 10:48:39 Wargon
+// Bugfix in beschreiben(), wenn die Hausaussenbeschreibung
+// verlangt wird (war schon seit Ewigkeiten buggy... ;)
+//
+// Revision 2.7 1995/04/21 08:55:32 Wargon
+// Load()/Save() und eigene Kommandos ausgelagert.
+// Kommandos koennen mit notify_fail() versehen werden.
+//
+// Revision 2.6 1995/03/07 13:55:36 Wargon
+// Add/RemUserCmd(), Beschreibungen werden bei reset()/clean_up()
+// gepackt gespeichert.
+// Bei Kommandos nur noch more(), wenn es auch noetig ist.
+//
+// Revision 2.5 1995/02/27 20:48:26 Wargon
+// Kleine Schoenheitsfehler in selbstdefinierten Befehlen beseitigt.
+//
+// Revision 2.4 1995/02/22 21:30:52 Wargon
+// Noch mehr Aenderungen an den Befehlen:
+// - Preparsing der Platzhalter
+// - Platzhalter fuer Possessivpronomen
+// - Meldung fuer Ausfuehrenden wird geMore()t
+// - Rassen- und Geschlechtespezifische Meldungen moeglich
+// - Auch fuer Ausgaenge koennen Befehle definiert werden
+// (nur fuer existierende; wird der Ausgang gesperrt, wird auch
+// der Befehl geloescht)
+// Im Zuge des Preparsings hat sich die Befehlauswertung etwas
+// vereinfacht.
+//
+// Revision 2.3 1995/02/20 22:15:44 Wargon
+// READ_DETAILS werden jetzt mit More() ausgegeben.
+// Selbstdefinierte Befehle: mit @PWER, ... koennen die Personalpronomina
+// eingebaut werden; Einbau jetzt auch in die Meldung fuer den Ausloeser
+// moeglich; _unparsed_args() in der Auswertung.
+//
+// Revision 2.2 1995/02/15 11:23:04 Wargon
+// NEU: Selbstdefinierbare Befehle.
+//
+// Revision 2.1 1995/02/04 15:02:36 Wargon
+// Die Truhe wird nun ueber die Property CHEST verwaltet. Der AddItem()-
+// Aufruf wurde deshalb von create() nach Load() verlegt. Geladen wird
+// sie nur, wenn das Load() von Hausverwalter erfolgte.
+// clean_up(), wenn Raum leer ist oder nur eine leere Truhe drin steht.
+//
+// Revision 2.0 1995/02/01 20:36:49 Wargon
+// Entruempelt und Massnahmen fuer _unparse_args() getroffen.
+
diff --git a/d/seher/haeuser/raum0.c b/d/seher/haeuser/raum0.c
new file mode 100644
index 0000000..0282818
--- /dev/null
+++ b/d/seher/haeuser/raum0.c
@@ -0,0 +1,173 @@
+//
+// raum0.c -- Der Eingangsraum des Hauses
+//
+// Grundobjekt (c) 1994 Boing@MorgenGrauen
+// Abschliessen und Rauswerfen von Jof
+// Fuer Aenderungen ab dem 06.10.94 verantwortlich: Wargon
+// Fuer Aenderungen ab dem 01.01.04 verantwortlich: Vanion
+//
+// $Date: 1996/02/21 18:13:41 $
+// $Revision: 2.5 $
+/* $Log: raum0.c,v $
+ * Revision 2.5 1996/02/21 18:13:41 Wargon
+ * *** empty log message ***
+ *
+ * Revision 2.4 1995/06/29 08:54:57 Wargon
+ * Neuer Befehl: "spion" zeigt, wer vor der Tuer steht.
+ *
+ * Revision 2.3 1995/06/28 08:59:25 Wargon
+ * init() meldet dem Hausbesitzer Spielerrueckmeldungen.
+ *
+ * Revision 2.2 1995/02/22 21:30:12 Wargon
+ * "uebersicht" jetzt auch fuer Wargon ueberall moeglich. ;)
+ *
+ * Revision 2.1 1995/02/04 14:31:47 Wargon
+ * AddItem(truhe) rausgenommen. Wird nun in Load() erledigt (siehe raum.c).
+ *
+ * Revision 2.0 1995/02/01 20:38:24 Wargon
+ * Von raum.c abgekoppelt.
+ *
+ */
+/*
+Letzte Aenderung: Vanion, 29. Feb 2004
+ - "uebersicht erlaubt" zeigt nun nur an, wer erlaubt ist.
+*/
+
+#include "haus.h"
+#include <wizlevels.h>
+#include <properties.h>
+#include <moving.h>
+
+inherit RAUM;
+
+void create()
+{
+ if (!clonep(this_object()) && object_name(this_object())==(PATH+"raum0")) {
+ set_next_reset(-1);
+ return;
+ }
+ ::create();
+
+ Set(H_REPORT, 0);
+ Set(H_REPORT, SAVE, F_MODE);
+
+ AddCmd( "erlaube", "erlauben" );
+ AddCmd( "verbiete", "verbieten" );
+ AddCmd( "oeffne", "oeffne" );
+ AddCmd( ({ "schliess", "schliesse" }), "schliesse" );
+ AddCmd( "spion", "spion" );
+}
+
+void notifyRep(int r)
+{
+ printf("Seit Deinem letzten Besuch gab es %s Rueckmeldung%s von anderen Spielern\nin Deinem Haus.\n", (r==1) ? "eine" : to_string(r), (r==1) ? "" : "en");
+}
+
+void init()
+{
+ int r;
+
+ ::init();
+
+ if (tp_owner_check() && r=Query(H_REPORT)) {
+ call_out("notifyRep", 0, r);
+ Set(H_REPORT, 0);
+ Save();
+ }
+}
+
+int oeffne(string str)
+{
+ return (HAUSNAME(QueryOwner()))->oeffne(str);
+}
+
+int schliesse(string str)
+{
+ return (HAUSNAME(QueryOwner()))->schliesse(str);
+}
+
+varargs int
+uebersicht(string str, string pre)
+{
+ if ( !(tp_owner_check() || IS_MAINTAINER(this_player())) )
+ return 0;
+
+ pre = "\n"+arr_out(VERWALTER->HausProp(QueryOwner(), HP_ALLOWED),
+ "Nur Du kannst Dein Haus auf- und abschliessen.\n",
+ "Du und %s koennen Dein Haus auf- und abschliessen.\n",
+ "Neben Dir koennen noch folgende Personen Dein Haus auf- und abschliessen:\n", 1 );
+
+ if (str=="erlaubt")
+ {
+ this_player()->More(pre);
+ return 1;
+ }
+
+ return ::uebersicht(str, pre);
+}
+
+int
+erlauben(string str)
+{
+ string *erlaubt;
+
+ if (!tp_owner_check()) {
+ notify_fail( "Du kannst hier gar nichts erlauben!\n" );
+ return 0;
+ }
+
+ if (!(str=UP_ARGS(this_player())) || str == "") {
+ notify_fail( "Wem willst denn das Auf- und Abschliessen Deines Hauses erlauben?\n" );
+ return 0;
+ }
+
+ erlaubt = VERWALTER->Erlaube(QueryOwner(),
+ map((regexplode(str, "[, ]")-({","," ",""})), #'capitalize));
+ arr_out(erlaubt, "Nur Du kannst Dein Haus auf- und abschliessen.\n",
+ "Du und %s koennen Dein Haus auf- und abschliessen.\n",
+ "Neben Dir koennen noch folgende Personen Dein Haus auf- und abschliessen:\n" );
+ return 1;
+}
+
+int
+verbieten(string str)
+{
+ string *erlaubt;
+
+ if (!tp_owner_check()) {
+ notify_fail( "Du kannst hier gar nichts verbieten!\n" );
+ return 0;
+ }
+
+ if (!(str=UP_ARGS(this_player())) || str == "") {
+ notify_fail( "Wem willst denn das Auf- und Abschliessen Deines Hauses verbieten?\n" );
+ return 0;
+ }
+ erlaubt = VERWALTER->Verbiete(QueryOwner(),
+ map((regexplode(str, "[, ]")-({","," ",""})), #'capitalize));
+ arr_out(erlaubt, "Nur Du kannst Dein Haus auf- und abschliessen.\n",
+ "Du und %s koennen Dein Haus auf- und abschliessen.\n",
+ "Neben Dir koennen noch folgende Personen Dein Haus auf- und abschliessen:\n" );
+ return 1;
+}
+
+int
+spion(string str)
+{
+ object env, *inv;
+ string ow;
+
+ ow = QueryOwner();
+ str = VERWALTER->HausProp(ow, HP_ENV);
+ call_other(str, "???");
+ env = find_object(str);
+ inv = all_inventory(env);
+ if (env = present("\n"+ow+"haus", env))
+ inv -= ({ env });
+ if (sizeof(inv))
+ printf( "Vor dem Haus siehst Du:\n%s", make_invlist(this_player(), inv));
+ else
+ printf( "Vor dem Haus ist nichts und niemand zu sehen.\n" );
+
+ return 1;
+}
diff --git a/d/seher/haeuser/sb_antrag.c b/d/seher/haeuser/sb_antrag.c
new file mode 100644
index 0000000..1e6dd20
--- /dev/null
+++ b/d/seher/haeuser/sb_antrag.c
@@ -0,0 +1,175 @@
+#include <properties.h>
+#include <wizlevels.h>
+#include <moving.h>
+#include "haus.h"
+
+inherit "std/room";
+
+create()
+{
+ ::create();
+
+ SetProp( P_INDOORS, 1 );
+ SetProp( P_LIGHT, 1 );
+ SetProp( P_INT_SHORT, "Am Antragsschalter" );
+ SetProp( P_INT_LONG,
+ "Du stehst am Antragsschalter der Bank. Hinter einer Rauchglasscheibe scheint\n"
+ +"sich ein Schalterbeamter zu befinden, Du kannst aber nichts genaueres er-\n"
+ +"kennen.\n"
+ +"Wenn Du Dich traust, kannst Du hier einen Bausparvertrag beantragen und einen\n"
+ +"beantragten Vertrag unterschreiben.\n"
+ +"Die Syntax dazu lautet:\n"
+ +"beantrage vertrag (fuer einen Bausparvertrag)\n"
+ +"beantrage ausbauvertrag (fuer den Ausbau des Hauses)\n"
+ +"unterschreibe vertrag (um den jeweiligen Vertrag zu unterschreiben)\n" );
+
+ AddDetail( ({ "boden" }),
+ "Der tiefschwarze Boden gibt Dir das Gefuehl, im absoluten Nichts zu stehen.\n" );
+ AddDetail( ({ "wand", "waende" }),
+ "Dunkle Schatten tanzen ueber die Waende.\n" );
+ AddDetail( ({ "decke" }),
+ "Sie scheint Dir in dieser unheimlichen Umgebung auf den Kopf fallen zu\n"
+ +"wollen.\n" );
+ AddDetail( ({ "nichts" }),
+ "Du siehst nichts.\n" );
+ AddDetail( ({ "schatten" }),
+ "Die Schatten irritieren Dich sehr.\n" );
+ AddDetail( ({ "schalter" }),
+ "An diesem Schalter kannst Du einen Bausparvertrag beantragen und unter-\n"
+ +"schreiben.\n" );
+ AddDetail( ({ "beamte", "beamter", "beamten", "schalterbeamte", "schalterbeamten", "schalterbeamter" }),
+ "Du kannst ihn nur schemenhaft hinter der Rauchglasscheibe des Schalters er-\n"
+ +"kennen. Die Umrisse scheinen allerdings zu keiner Lebensform zu gehoeren,\n"
+ +"derer Du Dich erinnern koenntest.\n" );
+ AddDetail( ({ "scheibe", "glasscheibe", "rauchglas", "rauchglasscheibe" }),
+ "Ein schemenhafter Beamter sitzt dahinter.\n" );
+ AddDetail( ({ "umrisse" }),
+ "Sie sind aeusserst beunruhigend.\n" );
+
+ AddCmd( ({ "beantrage" }), "beantragen" );
+ AddCmd( ({ "unterschreib", "unterschreibe" }), "unterschreiben" );
+ AddExit( "raus", PATH+"seherbank" );
+}
+
+void
+BecomesNetDead(object pl)
+{
+ pl->move(PATH+"seherbank", M_GO, 0, "wird rausgeworfen", "schlafwandelt herein");
+}
+
+int
+beantragen(string str)
+{
+ object tp, vertrag;
+ int haus;
+
+ tp = this_player();
+
+ if (!str || (haus = member( ({"ausbauvertrag", "vertrag", "bausparvertrag"}), str)) <0) {
+ notify_fail( "Versuch mal 'beantrage vertrag'!\n" );
+ return 0;
+ }
+
+ if (!IS_SEER(tp)) {
+ notify_fail( "Nur Seher koennen einen Bausparvertrag beantragen!\n" );
+ return 0;
+ }
+ if (tp->QueryProp(P_KILLS)) {
+ write("Verbrecher werden hier nicht bedient!\n");
+ return 1;
+ }
+ if (vertrag = present("sehe\rvertrag", tp))
+ write( "Der Beamte schnarrt: Aber Sie haben doch schon einen Vertrag!\n" );
+ else if (haus && (present("sehe\rhaus", tp) || VERWALTER->FindeHaus(getuid(tp)))) {
+ write( "Der Beamte schnarrt: Sie duerfen nur EIN Haus besitzen!\n" );
+ HLOG( "BANK.LOG", "Antrag: "+getuid(tp)+" stellte zweiten Antrag.\n" );
+ }
+ else if (!haus && !VERWALTER->FindeHaus(getuid(tp))) {
+ write( "Der Beamte faucht: Haben sie denn ueberhaupt schon ein Haus aufgestellt?\n"
+ +"Vorher koennen sie natuerlich keine Erweiterungen beantragen!\n" );
+ }
+ else {
+ if (!haus && VERWALTER->HausProp(getuid(tp),HP_ROOMS) == 9) {
+ write( "Der Beamte droehnt: Ihr Haus hat schon die hoechste Ausbaustufe erreicht!\n");
+ return 1;
+ }
+ (vertrag = clone_object(PATH+"bausparvertrag"))->move(tp, M_NOCHECK);
+
+ write( "Die Schatten verdichten sich zu einem Blatt Papier, welches in Deine Haende\n"
+ +"geweht wird. Mit droehnender Stimme erklaert der Schalterbeamte:\n"
+ +"Dies ist Ihr Bausparvertrag. Bitte lesen Sie ihn sich gruendlich durch, be-\n"
+ +"vor Sie ihn unterschreiben! Wenn Sie ihn erst einmal unterschrieben haben,\n"
+ +"koennen sie nicht wieder davon zuruecktreten (es sei denn, Sie zerreissen\n"
+ +"ihn oder ueberziehen die Ratenzahlungen)! Sie sind nicht gezwungen, den Ver-\n"
+ +"trag sofort zu unterschreiben. Im Hauptraum der Bank befindet sich ein In-\n"
+ +"formationsstand, an dem Sie Kommentare zu diesem Vertrag kaeuflich erwerben\n"
+ +"koennen. Wenn Ihnen einige Passagen des Vertrags unverstaendlich sind, wird\n"
+ +"Ihnen in den Kommentaren sicherlich geholfen.\n"
+ +"Das Leisten der Unterschrift ist jedoch nur hier an diesem Schalter\n"
+ +"moeglich!\n" );
+ if (!haus)
+ vertrag->Sign(V_RAUM);
+ HLOG( "BANK.LOG", "Antrag: "+getuid(tp)+" bekam einen "+(haus ? "Haus" : "Raum")+"vertrag.\n" );
+ }
+ return 1;
+}
+
+int
+unterschreiben(string str)
+{
+ object tp, vertrag;
+ int flag;
+
+ tp = this_player();
+
+ notify_fail( "Was willst Du denn unterschreiben?\n" );
+ if (!str || !(vertrag = present(str, tp)) || !vertrag->id("sehe\rvertrag"))
+ return 0;
+
+ if ((flag = vertrag->QueryProp(P_AUTOLOADOBJ)[1]) & V_SIGNED) {
+ write( "Der Schalterbeamte sagt: Aber der Vertrag ist doch schon unterschrieben!\n" );
+ return 1;
+ }
+
+ write( "Der Schalterbeamte sagt: Fuer welche Vertragsvariante haben sie sich\n"
+ +"entschieden? Tippen Sie 'sanft' fuer den sanften Weg zum eigenen Heim\n"
+ +"oder 'schnell' fuer den schnellen Weg.\n] " );
+ input_to("sign", 0, vertrag, flag|V_EP);
+ return 1;
+}
+
+void
+sign(string str, object vertrag, int flag)
+{
+ object block;
+ string s;
+ int *al;
+
+ if (str == "sanft" || str == "schnell") {
+ write( "Der Schalterbeamte gibt Dir einen Fuellfederhalter sowie ein Skalpell.\n"
+ +"Schwungvoll setzt Du Deine Unterschrift unter den Vertrag. Dann piekst\n"
+ +"Du Dir mit dem Skalpell in den Finger und bestaetigst die Unterschrift\n"
+ +"mit einem dunklen Tropfen Deines Blutes.\n"
+ +"Ploetzlich zucken Blitze um Dich herum auf, und der Schalterbeamte lacht\n"
+ +"droehnend auf. Du hast das Gefuehl, dass hier etwas nicht ganz mit rechten\n"
+ +"Dingen vor sich geht. Dann bestaetigt der Beamte die Unterschrift und\n"
+ +"uebergibt Dir den ersten Block, auf dem Deine Raten vermerkt werden.\n"
+ +"Der Beamte erklaert: Damit auf den Block auch eingezahlt wird, muss man\n"
+ +"ihn wie eine Ruestung anziehen!\n" );
+
+ this_player()->reduce_hit_points(50);
+ vertrag->Sign(flag | (str == "sanft" ? V_SIGNED : V_SIGNED | V_FAST));
+ (block = clone_object(PATH+"block"))->move(this_player(), M_NOCHECK);
+ block->SetProp("schwer", V_FAST & vertrag->QueryProp(P_AUTOLOADOBJ)[1]);
+ al = block->QueryProp(P_AUTOLOADOBJ);
+ al[V_FLAGS] |= B_ACTIVE;
+ block->SetProp(P_AUTOLOADOBJ, al);
+ s = "Antrag: "+getuid(this_player())+" unterschrieb den Vertrag ("+str+").\n";
+ HLOG( "BANK.LOG", s );
+ HLOG( getuid(this_player()), s );
+ }
+ else {
+ write( "Der Schalterbeamte sagt: Nur 'sanft' oder 'schnell', bitte!\n" );
+ input_to("sign", 0, vertrag, flag);
+ }
+}
diff --git a/d/seher/haeuser/sb_ausgabe.c b/d/seher/haeuser/sb_ausgabe.c
new file mode 100644
index 0000000..9fed219
--- /dev/null
+++ b/d/seher/haeuser/sb_ausgabe.c
@@ -0,0 +1,115 @@
+#include <properties.h>
+#include <wizlevels.h>
+#include <moving.h>
+#include <bank.h>
+#include "haus.h"
+
+inherit "std/room";
+
+create()
+{
+ ::create();
+
+ SetProp(P_INDOORS, 1);
+ SetProp(P_LIGHT, 1);
+ SetProp(P_INT_SHORT, "Am Ausgabeschalter" );
+ SetProp(P_INT_LONG,
+ "Am Ausgabeschalter. Wenn Du alle Raten fuer Deinen Vertrag eingezahlt hast,\n"
+ +"kannst Du nun Dein Haus abholen. Dazu musst Du einfach nur Deinen Vertrag\n"
+ +"vorlegen (mit 'lege vertrag vor').\n"
+ +"Der Schemen am Schalter koennte ein Beamter sein, aber auch etwas viel, viel\n"
+ +"Schlimmeres...\n" );
+
+ AddDetail( ({ "boden" }),
+ "Der tiefschwarze Boden gibt Dir das Gefuehl, im absoluten Nichts zu stehen.\n" );
+ AddDetail( ({ "wand", "waende" }),
+ "Dunkle Schatten tanzen ueber die Waende.\n" );
+ AddDetail( ({ "decke" }),
+ "Sie scheint Dir in dieser unheimlichen Umgebung auf den Kopf fallen zu\n"
+ +"wollen.\n" );
+ AddDetail( ({ "nichts" }),
+ "Du siehst nichts.\n" );
+ AddDetail( ({ "schatten" }),
+ "Die Schatten irritieren Dich sehr.\n" );
+ AddDetail( ({ "schalter", "ausgabeschalter" }),
+ "Du stehst direkt vor dem Ausgabeschalter.\n" );
+ AddDetail( ({ "beamte", "beamter", "beamten", "schalterbeamter", "schalterbeamte", "schalterbeamten", "schemen", "schlimmeres" }),
+ "Der Schalterbeamte schaut Dich mit aufgesetztem Laecheln an.\n" );
+
+ AddCmd( ({ "leg", "lege" }), "legen" );
+ AddExit( "raus", PATH+"seherbank" );
+}
+
+void
+BecomesNetDead(object pl)
+{
+ pl->move(PATH+"seherbank", M_GO, 0, "wird rausgeworfen", "schlafwandelt herein");
+}
+
+int
+legen(string str)
+{
+ object vertrag, tp;
+
+ tp = this_player();
+ vertrag = present("sehe\rvertrag", tp);
+
+ if (!str || str != "vertrag vor")
+ return 0;
+
+ if (!IS_SEER(tp)) {
+ write( "Der Schalterbeamte blickt Dich scharf an. Er sagt: Nur SeherInnen\n"
+ +"koennen hier ein Haus abholen!\n" );
+ HLOG( "BANK.LOG", "Ausgabe: "+getuid(tp)+" ist kein Seher.\n" );
+ }
+ else if (tp->QueryProp(P_KILLS))
+ write( "Der Schemen faucht: Verbrecher werden hier nicht bedient!\n" );
+ else if (!vertrag) {
+ write( "Der Schemen bemerkt: Sie haben doch gar keinen Vertrag!\n" );
+ HLOG( "BANK.LOG", "Ausgabe: "+getuid(tp)+" hatte keinen Vetrag.\n" );
+ }
+ else if (old_explode(object_name(vertrag),"#")[0] != PATH+"bausparvertrag") {
+ HLOG( "BANK.LOG", "Ausgabe: "+getuid(tp)+" Falscher Vertrag!\n");
+ HLOG( "SCHUMMEL", sprintf("Ausgabe: TP: %O, V: %O\n",
+ this_player(),
+ vertrag->QueryProp(P_CLONER)));
+ }
+ else if (!(vertrag->QueryProp(P_AUTOLOADOBJ)[1] & V_COMPL)) {
+ write( "Der Schalterbeamte weist Dich darauf hin, dass Du noch nicht genug\n"
+ +"auf den Vertrag eingezahlt hast!\n" );
+ HLOG( "BANK.LOG", "Ausgabe: "+getuid(tp)+" hatte zu wenig eingezahlt.\n" );
+ }
+ else if (ZENTRALBANK->_query_current_money() < 30000) {
+ write( "Der Schalterbeamte weist Dich darauf hin, dass die Zentralbank im\n"
+ +"Moment leider nicht ueber genug Bargeldreserven verfuegt, um ihren\n"
+ +"Teil der Abmachung zu erfuellen. Er vertroestet Dich auf spaeter.\n" );
+ }
+ else if (vertrag->QueryProp(P_AUTOLOADOBJ)[1] & V_RAUM) {
+ VERWALTER->NeuerRaum(getuid(this_player()));
+ write( "Der Schemen hinter dem Schalter streckt einen langen, schattigen Finger\n"
+ +"nach Deinem Vertrag aus. Wie von Geisterhand bewegt gleitet der Vertrag\n"
+ +"hinueber. Der Schemen scheint den Vertrag ausgiebig zu pruefen, dann\n"
+ +"zerreisst er ihn, wedelt einmal mit seinen schattenhaften Haenden und\n"
+ +"beginnt mit Grabesstimme zu sprechen:\n"
+ +"Der neue Raum ist in ihrem Haus installiert! Hinfort mit Ihnen!\n" );
+ HLOG( "BANK.LOG", "Ausgabe: "+getuid(tp)+" bekam einen neuen Raum.\n" );
+ HLOG( getuid(tp), "Ausgabe: "+getuid(tp)+" bekam einen neuen Raum.\n" );
+ "/p/daemon/zentralbank"->WithDraw(30000);
+ vertrag->remove();
+ }
+ else {
+ write( "Der Schemen hinter dem Schalter streckt einen langen, schattigen Finger\n"
+ +"nach Deinem Vertrag aus. Wie von Geisterhand bewegt gleitet der Vertrag\n"
+ +"hinueber. Der Schemen scheint den Vertrag ausgiebig zu pruefen, dann\n"
+ +"zerreisst er ihn, wedelt einmal mit seinen schattenhaften Haenden und\n"
+ +"vor Dir erscheint ein kleines, tragbares Haus. Zoegernd nimmst Du es in\n"
+ +"Deine Haende, da erschallt eine grollende Stimme:\n"
+ +"Das Haus gehoert Ihnen. Beehren sie uns bald wieder! Har, har, har!!!\n" );
+ clone_object(PATH+"traghaus")->move(tp, M_NOCHECK);
+ HLOG( "BANK.LOG", "Ausgabe: "+getuid(tp)+" bekam das Haus.\n" );
+ HLOG( getuid(tp), "Ausgabe: "+getuid(tp)+" bekam das Haus.\n" );
+ "/p/daemon/zentralbank"->WithDraw(30000);
+ vertrag->remove();
+ }
+ return 1;
+}
diff --git a/d/seher/haeuser/sb_einzahlung.c b/d/seher/haeuser/sb_einzahlung.c
new file mode 100644
index 0000000..1f89196
--- /dev/null
+++ b/d/seher/haeuser/sb_einzahlung.c
@@ -0,0 +1,130 @@
+#include <properties.h>
+#include <wizlevels.h>
+#include <moving.h>
+#include "haus.h"
+
+inherit "std/room";
+
+create()
+{
+ ::create();
+
+ SetProp( P_INDOORS, 1 );
+ SetProp( P_LIGHT, 1 );
+ SetProp( P_INT_SHORT, "Am Einzahlungsschalter" );
+ SetProp( P_INT_LONG,
+ "Du stehst hier am Einzahlungsschalter der Bank. Um eine Rate einzuzahlen,\n"
+ +"musst Du einfach nur Deinen MG MASTER-BLOCK vorlegen. Gib dazu einfach nur\n"
+ +"'lege block vor' ein.\n"
+ +"Der Blick eines schemenhaft erkennbaren Beamten scheint Dich selbst durch\n"
+ +"die dicke Rauchglasscheibe hindurch zu durchbohren.\n" );
+
+ AddDetail( ({ "boden" }),
+ "Der tiefschwarze Boden gibt Dir das Gefuehl, im absoluten Nichts zu stehen.\n" );
+ AddDetail( ({ "wand", "waende" }),
+ "Dunkle Schatten tanzen ueber die Waende.\n" );
+ AddDetail( ({ "decke" }),
+ "Sie scheint Dir in dieser unheimlichen Umgebung auf den Kopf fallen zu\n"
+ +"wollen.\n" );
+ AddDetail( ({ "nichts" }),
+ "Du siehst nichts.\n" );
+ AddDetail( ({ "schatten" }),
+ "Die Schatten irritieren Dich sehr.\n" );
+ AddDetail( ({ "scheibe", "rauchglas", "glas", "glasscheibe", "rauchglasscheibe" }),
+ "Hinter ihr scheint sich ein Beamter zu verbergen.\n" );
+ AddDetail( ({ "schalter" }),
+ "An diesem Schalter kannst Du eine Rate fuer Dein Haus einzahlen.\n" );
+ AddDetail( ({ "beamte", "beamter", "beamten", "schalterbeamte", "schalterbeamter", "schalterbeamten" }),
+ "Der Schalterbeamte durchbohrt Dich mit seinen Blicken.\n" );
+
+ AddCmd( ({ "leg", "lege" }), "legen" );
+
+ AddExit( "raus", PATH+"seherbank" );
+}
+
+void
+BecomesNetDead(object pl)
+{
+ pl->move(PATH+"seherbank", M_GO, 0, "wird rausgeworfen", "schlafwandelt herein");
+}
+
+int
+legen(string str)
+{
+ object tp, block, vertrag;
+ int *al, *vl, rate;
+
+ if (!str || str != "block vor")
+ return 0;
+
+ tp = this_player();
+ block = present( "\n block", tp);
+ vertrag = present( "sehe\rvertrag", tp );
+
+ if (!IS_SEER(tp))
+ write( "Der Schalterbeamte weist Dich darauf hin, dass hier nur Seher be-\n"
+ +"dient werden.\n" );
+ else if (tp->QueryProp(P_KILLS))
+ write( "Ein bohrender Blick verkuendet: Verbrecher werden hier nicht bedient!\n" );
+ else if (!block)
+ write( "Du hast keinen Block, den Du vorlegen koenntest!\n" );
+ else if (!vertrag) {
+ write( "Der Schalterbeamte sagt: Sie haben keinen Bausparvertrag! Wozu wollen\n"
+ +"Sie dann eine Rate einzahlen? Wie sind Sie ueberhaupt an den Block\n"
+ +"gekommen?\n" );
+ HLOG( "BANK.LOG", "Einzahlung: "+getuid(tp)+" Block ohne Vertrag!\n" );
+ }
+ else if (old_explode(object_name(block),"#")[0] != PATH+"block" ||
+ old_explode(object_name(vertrag),"#")[0] != PATH+"bausparvertrag") {
+ write( "Der Schalterbeamte faehrt Dich an: DU WILLST SCHUMMELN???\n" );
+ HLOG( "BANK.LOG", "Einzahlung: "+getuid(tp)+" Falscher Block/Vertrag!\n");
+ HLOG( "SCHUMMEL", sprintf("Einzahlung: TP: %O, B: %O, V: %O\n",
+ this_player(),
+ block->QueryProp(P_CLONER),
+ vertrag->QueryProp(P_CLONER)));
+ }
+ else {
+ al = block->Query(P_AUTOLOADOBJ);
+ rate = RATENHOEHE;
+ if (al[V_FLAGS] & B_EXTEND)
+ rate += (6*RATENHOEHE)/10;
+
+ if (al[V_MONEY] < rate) {
+ write( "Der Schalterbeamte weist Dich darauf hin, dass Du noch nicht genug Erfahrung\n"
+ +"fuer die Rate gelassen hast.\n" );
+ HLOG( getuid(tp), "Einzahlung: "+getuid(tp)+" hatte nicht genug ("+al[V_MONEY]+"/"+rate+").\n");
+ }
+ else {
+ vl = vertrag->Query(P_AUTOLOADOBJ);
+ rate = (al[V_FLAGS] & B_FAST) ? SUMME_S : SUMME_L;
+ if (vl[1] & V_RAUM)
+ rate = rate * 4 /10;
+ write( "Du zahlst Deine Rate ein.\n" );
+ block->remove();
+ if (vertrag->Einzahlung() >= rate) {
+ write( "Der Schalterbeamte sagt: Sie haben es geschafft! Sie haben nun genug\n"
+ +"Erfahrung eruebrigt. ");
+ if (vl[1] & V_RAUM)
+ write( "Am Ausgabeschalter koennen Sie nun den neuen Raum\n"
+ +"eintragen lassen.\n" );
+ else
+ write( "Am Hausausgabeschalter koennen Sie nun Ihr neues\n"
+ +"Heim in Empfang nehmen.\n" );
+ vertrag->Sign( vl[1] | V_COMPL );
+ }
+ else {
+ write( "Der Schalterbeamte beschwoert Blitz und Donner vom Himmel herab. Ein\n"
+ +"lauter Knall, und ein neuer Ratenblock erscheint in Deinem Inventar.\n" );
+ (block = clone_object(PATH+"block"))->move(tp, M_NOCHECK);
+ block->SetProp("schwer", vl[1] & V_FAST);
+ al = block->Query(P_AUTOLOADOBJ);
+ al[V_FLAGS] |= B_ACTIVE;
+ block->Set(P_AUTOLOADOBJ, al);
+ }
+ HLOG(getuid(tp), "Einzahlung: "+getuid(tp)+" zahlte ein.\n" );
+ tp->force_save();
+ }
+ }
+ return 1;
+}
+
diff --git a/d/seher/haeuser/sc_schalter.c b/d/seher/haeuser/sc_schalter.c
new file mode 100644
index 0000000..9f29340
--- /dev/null
+++ b/d/seher/haeuser/sc_schalter.c
@@ -0,0 +1,332 @@
+#include <properties.h>
+#include <wizlevels.h>
+#include <defines.h>
+#include <moving.h>
+#include <bank.h>
+#include "haus.h"
+#include <money.h>
+
+inherit "std/room";
+
+#define KONTO "seercard_kontostand"
+
+// Prototypes
+public void BecomesNetDead( object pl );
+static int _guthaben();
+static int _einzahlen( string str );
+static int _aufladen( string str );
+static int _kaufen( string str );
+
+
+protected void create()
+{
+ ::create();
+
+ SetProp( P_INDOORS, 1 );
+ SetProp( P_LIGHT, 1 );
+ SetProp( P_LOG_FILE, "report/tiamak.rep" );
+ SetProp( P_INT_SHORT, "Am Geldkartenschalter" );
+ SetProp( P_INT_LONG,
+ break_string( "Das ist also der Geldkartenschalter. Hinter einer "
+ "kaum durchsichtigen Rauchglasscheibe scheint ein "
+ "Beamter (oder zumindest irgendein Lebewesen) "
+ "geduldig zu warten. Neben dem Schalter haengt "
+ "eine Tafel.", 78 ) );
+
+ AddDetail( ({ "boden" }),
+ "Der tiefschwarze Boden gibt Dir das Gefuehl, im absoluten "
+ "Nichts zu stehen.\n" );
+ AddDetail( "gefuehl", "Kein schoenes Gefuehl.\n" );
+ AddDetail( ({ "schwarz", "schwaerze" }), "Tiefschwarz.\n" );
+ AddDetail( ({ "wand", "waende" }),
+ "Dunkle Schatten tanzen ueber die Waende.\n" );
+ AddDetail( ({ "decke" }),
+ "Sie scheint Dir in dieser unheimlichen Umgebung auf den "
+ "Kopf fallen zu\nwollen.\n" );
+ AddDetail( "umgebung", "Schau Dich doch um.\n" );
+ AddDetail( ({ "kopf" }), "Das ist der Gegenstand auf Deinem Hals.\n" );
+ AddDetail( "gegenstand", "Ich meine Deinen Kopf.\n" );
+ AddDetail( "hals", "Wenn Du Nachhilfe in Anatomie brauchst, such Dir "
+ "jemand anderen.\n" );
+ AddDetail( ({ "jemand" }), "Keiner da.\n" );
+ AddDetail( "nachhilfe", "Dazu musst Du wohl woanders suchen.\n" );
+ AddDetail( "anatomie", "Schlag es in einem Lexikon nach.\n" );
+ AddDetail( "lexikon", "Soetwas hast Du anscheinend noch nie gesehen.\n" );
+ AddDetail( ({ "nichts" }),
+ "Du bist blind!\n" );
+ AddDetail( ({ "schatten" }),
+ "Die Schatten sind nur dazu da, um Dich zu irritieren. "
+ "Und das machen sie gut.\n" );
+ AddDetail( ({ "beamte", "beamter", "beamten", "schalterbeamte",
+ "schalterbeamten", "schalterbeamter" }),
+ "Du kannst ihn nur schemenhaft hinter der Rauchglasscheibe "
+ "des Schalters er-\nkennen. Die Umrisse scheinen allerdings "
+ "zu keiner Lebensform zu gehoeren,\nderer Du Dich erinnern "
+ "koenntest.\n" );
+ AddDetail( ({ "scheibe", "glasscheibe", "rauchglas", "rauchglasscheibe" }),
+ "Ein schemenhafter Beamter sitzt dahinter.\n" );
+ AddDetail( ({ "umrisse" }),
+ "Sie sind aeusserst beunruhigend.\n" );
+ AddDetail( ({ "lebensform", "schemen", "lebewesen" }),
+ "Du moechtest gar nicht wissen, um was es sich dabei "
+ "handelt.\n" );
+ AddDetail( ({ "schalter", "geldkartenschalter" }),
+ "An diesem Schalter kannst Du die beruehmte"
+ " Seer-Card (TM) erwerben sowie\nDein Konto aufladen.\n" );
+ AddDetail( ({ "konto", "karte", "geldkarte", "card", "seercard",
+ "seer-card" }), "Wie das geht, steht auf der Tafel.\n" );
+ AddDetail( "tafel", "Du kannst sie lesen.\n" );
+
+ AddSmells( SENSE_DEFAULT, "Es riecht nach altem Staub.\n" );
+ AddSmells( "staub", "Hier lagern sicher viele alte Akten.\n" );
+ AddSmells( "akten", "Die riechen dann irgendwann nach Staub.\n" );
+
+ AddSounds( SENSE_DEFAULT, "Direkt vor dem Schalter ist es erstaunlich "
+ "ruhig.\nGeradezu ehrfurchtsvoll ruhig.\n" );
+ AddSounds( ({ "schalter", "ruhe", "ehrfurcht" }),
+ "Ob das am Schalterbeamten liegt?\n" );
+ AddSounds( ({ "beamter", "beamten", "schalterbeamter", "schalterbeamten" }),
+ "Ist er ueberhaupt noch da?\n" );
+
+ AddReadDetail( ({ "tafel", "preisliste" }),
+ "Preisliste:\n"
+ "================================================="
+ "=====================\n\n"
+ "Neue Geldkarte .................................."
+ "...... 10000 Muenzen\n"
+ "Syntax: kaufe geldkarte\n\n"
+ "Einzahlungen auf das Geldkarten-Konto ..........."
+ "...... 10% Gebuehren\n"
+ "Syntax: zahle <n> muenzen ein\n"
+ "oder lade karte auf\n\n" );
+
+ AddCmd( ({ "zahl", "zahle" }), "_einzahlen" );
+ AddCmd( ({ "lad", "lade" }), "_aufladen" );
+ AddCmd( ({ "kaufe", "kauf" }), "_kaufen" );
+
+ AddExit( "raus", PATH+"seherbank" );
+}
+
+
+public void BecomesNetDead( object pl )
+{
+ pl->move( PATH+"seherbank", M_GO|M_NOCHECK, 0, "wird rausgeworfen",
+ "schlafwandelt herein" );
+}
+
+
+static int _guthaben()
+{
+ mixed wert;
+
+ if ( !(this_player()->Query(KONTO, F_MODE) & SAVE) )
+ this_player()->Set( KONTO, SAVE, F_MODE_AS );
+
+ wert = this_player()->Query( KONTO, F_VALUE );
+
+ if ( !intp(wert) || wert < 0 || wert > 100000 )
+ return this_player()->Set( KONTO, 0, F_VALUE );
+
+ return wert;
+}
+
+
+static int _einzahlen( string str )
+{
+ int n, guthaben, gebuehr;
+ string dummy;
+ object ob;
+
+ if ( !this_player() || this_player() != this_interactive() )
+ return 0;
+
+ if ( !str || !stringp(str) || sscanf( str, "%d %s", n, dummy ) != 2 ||
+ dummy != "muenzen ein" )
+ return notify_fail( "Syntax: zahle <n> muenzen ein\n" ), 0;
+
+ if ( !IS_SEER(this_player()) )
+ return notify_fail( break_string("Werd doch erstmal Seher.", 78, "Der "
+ "Schalterbeamte grinst ueberheblich: "
+ ) ), 0;
+
+ if ( n < 1000 )
+ return notify_fail( break_string("Mit so kleinen Betraegen fangen "
+ "wir erst gar nicht an. Du musst "
+ "schon mindestens 1000 "
+ "Muenzen einzahlen.", 78,
+ "Der Schalterbeamte grummelt: ") ), 0;
+
+ guthaben = this_player()->QueryMoney();
+
+ // Man kann sein Konto natuerlich nicht mit dem Geld vom Konto aufladen ;-)
+ if ( ob = present( "\ngeldkarte", this_player() ) )
+ guthaben -= ob->QueryProp( P_AMOUNT );
+
+ if ( guthaben < n )
+ return notify_fail( break_string("Du hast ja gar nicht soviel Geld!",
+ 78, "Der Schalterbeamte faucht "
+ "Dich an: ") ), 0;
+
+ if ( (guthaben = _guthaben()) == 100000 )
+ return notify_fail( break_string( "Deine Seer-Card (TM) ist bereits "
+ "maximal aufgeladen. Mehr als "
+ "100.000 Muenzen koennen damit aus "
+ "technischen Gruenden nicht "
+ "verwaltet werden.", 78,
+ "Der Schalterbeamte sagt: " ) ), 0;
+
+ gebuehr = to_int(n / 11.0 + 0.5);
+ n -= gebuehr;
+
+ if ( guthaben + n > 100000 )
+ return notify_fail( break_string("Tut mir leid, aber so hohe Betraege "
+ "kann die Geldkarte nicht verwalten.\n"
+ "Du kannst die Seer-Card (TM) mit "
+ "maximal 100.000 Muenzen aufladen. "
+ "Ausgehend von Deinem momentanen "
+ "Guthaben von " +
+ to_string(guthaben) + " Muenzen "
+ "wuerde Dich das (inkl. unserer "
+ "Verwaltungsgebuehren) " +
+ to_string(to_int((100000-guthaben) *
+ 1.1 + 0.5)) +
+ " Muenzen kosten.\n"
+ "Um Dir die Rechnerei zu ersparen, "
+ "kannst Du auch einfach \"lade karte "
+ "auf\" benutzen, um Deine Geldkarte "
+ "maximal aufzuladen.", 78,
+ "Der Schalterbeamte sagt: ",
+ BS_LEAVE_MY_LFS) ), 0;
+
+ if ( objectp(ob) ){
+ write( "Du zeigst Deine Geldkarte kurz vor.\n" );
+ // notwendig, da sonst das Geld evtl. von der Karte selber abgebucht
+ // wird, falls sie als oberstes im Inv steht
+ this_player()->Set( KONTO, 0, F_VALUE );
+ }
+
+ this_player()->AddMoney( -(n + gebuehr) );
+ ZENTRALBANK->PayIn( gebuehr );
+ this_player()->Set( KONTO, guthaben + n, F_VALUE );
+
+ write( break_string( "Okay, Deine Geldkarte hat nun ein Guthaben von "
+ "insgesamt " + to_string(_guthaben()) + " Muenzen.",
+ 78, "Der Schalterbeamte sagt: " ) );
+
+ return 1;
+}
+
+
+static int _aufladen( string str )
+{
+ int n, guthaben, gebuehr;
+ string dummy;
+ object ob;
+
+ if ( !this_player() || this_player() != this_interactive() )
+ return 0;
+
+ if ( !stringp(str) || sscanf( str, "%s auf", dummy ) != 1 ||
+ dummy != "karte" && dummy != "geldkarte" && dummy != "card" &&
+ dummy != "seercard" && dummy != "seer-card" )
+ return notify_fail( "Syntax: lade geldkarte auf\n" ), 0;
+
+ if ( !IS_SEER(this_player()) )
+ return notify_fail( break_string("Werd doch erstmal Seher.", 78, "Der "
+ "Schalterbeamte grinst ueberheblich: "
+ ) ), 0;
+
+ if ( (guthaben = _guthaben()) == 100000 )
+ return notify_fail( break_string( "Deine Seer-Card (TM) ist bereits "
+ "maximal aufgeladen. Mehr als "
+ "100.000 Muenzen koennen damit aus "
+ "technischen Gruenden nicht "
+ "verwaltet werden.", 78,
+ "Der Schalterbeamte sagt: " ) ), 0;
+
+ n = this_player()->QueryMoney();
+
+ // Man kann sein Konto natuerlich nicht mit dem Geld vom Konto aufladen ;-)
+ if ( ob = present_clone( SEHERKARTE, this_player() ) )
+ n -= ob->QueryProp( P_AMOUNT );
+
+ if ( (gebuehr = to_int( (100000 - guthaben) * 1.1 + 0.5 )) < n )
+ n = gebuehr;
+
+ gebuehr = to_int( n / 11.0 + 0.5 );
+ n -= gebuehr;
+
+ if ( n + gebuehr < 1000 )
+ return notify_fail( break_string("Mit so kleinen Betraegen fangen "
+ "wir erst gar nicht an. Du musst "
+ "schon mindestens 1000 "
+ "Muenzen einzahlen.", 78,
+ "Der Schalterbeamte grummelt: ") ), 0;
+
+ if ( objectp(ob) ){
+ write( "Du zeigst Deine Geldkarte kurz vor.\n" );
+ // notwendig, da sonst das Geld evtl. von der Karte selber abgebucht
+ // wird, falls sie als oberstes im Inv steht
+ this_player()->Set( KONTO, 0, F_VALUE );
+ }
+
+ this_player()->AddMoney( -(n + gebuehr) );
+ ZENTRALBANK->PayIn( gebuehr );
+ this_player()->Set( KONTO, guthaben + n, F_VALUE );
+
+ write( break_string( "Du zahlst " + to_string(n+gebuehr) + " Muenzen ein "
+ "und erhoehst Dein Guthaben damit auf " +
+ to_string(_guthaben()) + " Muenzen insgesamt.", 78,
+ "Der Schalterbeamte sagt: " ) );
+
+ return 1;
+}
+
+
+static int _kaufen( string str )
+{
+ if ( !this_interactive() || this_player() != this_interactive() )
+ return 0;
+
+ if ( str != "geldkarte" && str != "karte" && str != "card" &&
+ str != "seercard" && str != "seer-card" )
+ return notify_fail( "Syntax: kaufe geldkarte\n" ), 0;
+
+ if ( !IS_SEER(this_player()) )
+ return notify_fail( break_string("Werd doch erstmal Seher.", 78, "Der "
+ "Schalterbeamte grinst ueberheblich: "
+ ) ), 0;
+
+ if ( this_player()->QueryMoney() < 10000 )
+ return notify_fail( break_string("Du hast nicht genug Geld bei!",
+ 78, "Der Schalterbeamte faucht "
+ "Dich an: ") ), 0;
+
+ object ob = clone_object( SEHERKARTE );
+ this_player()->AddMoney(-10000);
+ ZENTRALBANK->PayIn(10000);
+
+ if ( ob->move( this_player(), M_GIVE ) != 1 ){
+ write( "Der Schalterbeamte grummelt: Du kannst die Geldkarte nicht "
+ "mehr tragen.\nDer Schalterbeamte wirft Dir Deine Seer-Card "
+ "(TM) veraechtlich vor die Fuesse.\n" );
+ // trotzdem einmal in's Inv des Spielers bewegen, damit die Karte
+ // auf seinen Namen registriert wird
+ ob->move( this_player(), M_GIVE|M_NOCHECK );
+ // dann auf den Boden legen
+ ob->move( this_object(), M_PUT );
+ }
+ else
+ write( "Der Beamte haendigt Dir eine Seer-Card (TM) aus.\n" );
+
+ write( break_string( "Der Schalterbeamte macht Dich noch darauf "
+ "aufmerksam, dass Deine Seer-Card (TM) immer erst dann als "
+ "Zahlungsmittel in Anspruch genommen wird, wenn Deine in Boersen oder "
+ "in klingender Muenze mitgefuehrte Barschaft aufgebraucht sein "
+ "sollte - egal, was davon sich oben im Inventar befindet.\n"
+ "Was immer das auch heissen soll.", 78, 0, BS_LEAVE_MY_LFS ) );
+
+ this_player()->Set( KONTO, SAVE, F_MODE_AS );
+
+ return 1;
+}
diff --git a/d/seher/haeuser/seherbank.c b/d/seher/haeuser/seherbank.c
new file mode 100644
index 0000000..4e47265
--- /dev/null
+++ b/d/seher/haeuser/seherbank.c
@@ -0,0 +1,175 @@
+#include <moving.h>
+#include <defines.h>
+#include <rooms.h>
+#include <properties.h>
+#include "queue.h"
+#include "haus.h"
+
+inherit "/std/room";
+
+create()
+{
+ object q;
+
+ ::create();
+
+ SetProp( P_INDOORS, 1 );
+ SetProp( P_LIGHT, 1 );
+ SetProp( P_INT_SHORT, "In der MorgenGrauen-Bank" );
+ SetProp( P_INT_LONG,
+ break_string( "Dunkle Schatten erfuellen diesen Raum, nur "
+ "schemenhaft kannst Du einige Schlangen sowie einen "
+ "Informationsstand erkennen. Du beginnst zu "
+ "begreifen:\nDu befindest Dich in der "
+ "MorgenGrauen-Bank, der 'Bank in Ihrem Ruecken'.\n"
+ "Wenn Du Seher oder Seherin bist, kannst Du hier "
+ "einen Bausparvertrag fuer ein Seherhaus erwerben, "
+ "Raten fuer einen laufenden Bausparvertrag "
+ "einzahlen und ein abbezahltes Haus abholen. "
+ "Ausserdem kannst Du hier Geldkarten erwerben und "
+ "Dein Konto auffuellen. Dazu musst Du Dich nur "
+ "zu den entsprechenden Schaltern begeben. "
+ "Nach Sueden kannst Du die Bank wieder "
+ "verlassen.\n", 78, 0, BS_LEAVE_MY_LFS ) );
+
+ AddDetail( ({ "wand", "waende" }),
+ "An den Waenden treiben die Schatten unheimliche "
+ "Spielchen.\n" );
+ AddDetail( ({ "boden" }),
+ "Der Boden ist schwarz wie die Nacht.\n" );
+ AddDetail( ({ "decke" }),
+ "Schleimige Faeden scheinen von der dunklen Decke "
+ "zu haengen.\n" );
+ AddDetail( ({ "schatten" }),
+ "Die Schatten erfuellen den ganzen Raum und lassen "
+ "Dich nur schemenhafte Details\nerblicken.\n" );
+ AddDetail( ({ "details", "schemen" }),
+ "Ein Informationsstand sowie vier Schlangen von "
+ "Leuten sind als Schemen in\nden Schatten erkennbar.\n" );
+ AddDetail( ({ "schleim", "faeden", "schleimfaeden" }),
+ "Die Schleimfaeden haengen von der Decke und drohen Dir auf "
+ "den Kopf zu\ntropfen. Ein Froesteln schuettelt Dich.\n" );
+ AddDetail( ({ "schalter" }),
+ break_string( "Vor den Schaltern stehen lange Schlangen von "
+ "Leuten, die auch gerne ein Haus haetten. Es "
+ "gibt einen Antragsschalter, einen "
+ "Ratenzahlungsschalter, einen Ausgabeschalter und "
+ "einen Geldkartenschalter. Vor jedem Schalter "
+ "steht eine Schlange von mehr oder weniger "
+ "geduldig wartenden Leuten. Du wirst Dich wohl "
+ "anstellen muessen...", 78 ) );
+ AddDetail( ({ "stand", "informationsstand" }),
+ "Hier kannst Du fuer den unverschaemten Preis von 10000 "
+ "Muenzen die Kommen-\ntare zum Bausparvertrag erwerben. "
+ "Das geht mit 'kaufe kommentar', ist aber\n"
+ "angesichts des hohen Preises fast nicht anzuraten.\n" );
+ AddDetail( ({ "ausgabeschalter", "hausausgabeschalter", "hausausgabe" }),
+ "Wenn Du alle Raten fuer Dein Haus eingezahlt hast, kannst "
+ "Du es hier ab-\nholen und mitnehmen. Dafuer musst Du Dich "
+ "an die Hausausgabeschlange an-\nstellen.\n" );
+ AddDetail( ({ "ratenschalter", "ratenzahlungsschalter" }),
+ "Hier kannst Du die Raten fuer Dein Seherhaus einzahlen. "
+ "Du wirst Dich\naber erst an die Zahlungsschlange anstellen "
+ "muessen.\n" );
+ AddDetail( ({ "antragsschalter" }),
+ "An diesem Schalter kannst Du einen Bausparvertrag beantragen. "
+ "Stell Dich\ndazu an die Antragsschlange an.\n" );
+ AddDetail( ({ "geldkartenschalter", "kartenschalter" }),
+ break_string( "Am Geldkartenschalter kannst Du die beruehmte "
+ "Seer-Card (TM) erwerben und Dein Guthabenkonto "
+ "auffuellen. Allerdings haben das auch noch "
+ "andere Leute vor - Du wirst Dich also brav "
+ "hinten an die Geldkartenschlange anstellen "
+ "muessen.", 78 ) );
+
+ q=AddItem( PATH+"queue", REFRESH_NONE,
+ ([ P_SHORT : "Eine Schlange vor dem Geldkartenschalter",
+ P_LONG : "Die Seer-Card (TM) muss ja wirklich begehrt sein. "
+ "Zumindest stehen mehrere\nLeute an der Schlange zum "
+ "Geldkartenschalter an.\n"
+ "Syntax: 'stell an kartenschlange an'.\n",
+ P_INT_SHORT : "In der Schlange vor dem Geldkartenschalter",
+ P_INT_LONG : "Du steht in der langen Schlange vor dem "
+ "Geldkartenschalter. Wenigstens geht\nes halbwegs flott "
+ "vorwaerts.\n",
+ Q_LENGTH : 7,
+ Q_CYCLE_TIME : 8,
+ Q_SUSPEND : 1,
+ Q_DEST : PATH+"sc_schalter"
+ ]) );
+
+ q->AddId( ({"geldkartenschlange", "kartenschlange"}) );
+
+ q=AddItem( PATH+"queue", REFRESH_NONE,
+ ([ P_SHORT : "Eine Schlange vor dem Hausausgabeschalter",
+ P_LONG : "In dieser Schlange stehen Leute vor dem "
+ "Hausausgabeschalter an.\n"
+ +"Syntax: 'stell an ausgabeschlange an'.\n",
+ P_INT_SHORT : "In der Schlange vor dem Hausausgabeschalter",
+ P_INT_LONG : "Du wartest vor dem Hausausgabeschalter.\n",
+ Q_SUSPEND : 1,
+ Q_DEST : PATH+"sb_ausgabe"
+ ]) );
+
+ q->AddId( ({"hausausgabeschlange", "ausgabeschlange" }) );
+
+ q=AddItem( PATH+"queue", REFRESH_NONE,
+ ([ P_SHORT : "Eine Schlange vor dem Schalter zur Ratenzahlung",
+ P_LONG : "Wenn Du eine Rate bezahlen willst, solltest Du "
+ "Dich an dieser Schlange\nanstellen.\n"
+ +"Syntax: 'stell an ratenschlange an'.\n",
+ P_INT_SHORT : "In der Schlange vor dem Schalter zur "
+ "Ratenzahlung",
+ P_INT_LONG : "Du wunderst Dich ein wenig ueber die "
+ "Massen potentieller Ratenzahler.\n",
+ Q_LENGTH : 8,
+ Q_CYCLE_TIME : 10,
+ Q_DEST : PATH+"sb_einzahlung",
+ Q_SUSPEND : 1
+ ]) );
+
+ q->AddId( ({"ratenschlange", "ratenzahlungsschlange",
+ "zahlungsschlange" }) );
+
+ q=AddItem( PATH+"queue", REFRESH_NONE,
+ ([ P_SHORT : "Eine Schlange vor dem Antragsschalter",
+ P_LONG : "Die Leute in dieser Schlange wollen alle ein "
+ "eigenes Heim.\n"
+ +"Syntax: 'stell an antragsschlange an'.\n",
+ P_INT_SHORT : "In der Schlange vor dem Antragsschalter",
+ P_INT_LONG : "Du wartest inmitten anderer Antragssteller "
+ "darauf, endlich Deinen\nBausparvertrag beantragen zu "
+ "duerfen.\n",
+ Q_LENGTH : 5,
+ Q_CYCLE_TIME : 20,
+ Q_SUSPEND : 1,
+ Q_DEST : PATH+"sb_antrag"
+ ]) );
+
+ q->AddId( ({"antragsschlange"}) );
+
+ AddExit( "sueden", "/d/ebene/room/dra_str1" );
+
+ AddCmd( ({ "kauf", "kaufe" }), "kaufen" );
+}
+
+static int
+kaufen(string str)
+{
+ object tp;
+
+ if (!str || str != "kommentar") {
+ notify_fail( "Was willst Du kaufen? Hier gibt es nur Kommentare!\n" );
+ return 0;
+ }
+
+ tp = this_player();
+ if (tp->QueryMoney()<10000)
+ write( "Du hast nicht genug Geld dabei!\n" );
+ else {
+ clone_object(PATH+"kommentar")->move(tp, M_NOCHECK);
+ tp->AddMoney(-10000);
+ write( "Du zahlst 10000 Muenzen und erhaeltst dafuer einen Kommentar.\n" );
+ }
+ return 1;
+}
diff --git a/d/seher/haeuser/special/faq/0 b/d/seher/haeuser/special/faq/0
new file mode 100644
index 0000000..1b679e1
--- /dev/null
+++ b/d/seher/haeuser/special/faq/0
@@ -0,0 +1,10 @@
+0. NEUIGKEITEN
+--------------
+
+Hier aktuelle Aenderungen der SeherFAQ 3.02 (Stand Juli 2001):
+
+- Es gibt zwei neue Portale (34 und 36)
+
+- Durch einen Riss in den Dimensionen ist der Zugang zu einer
+ neuen Paralellwelt moeglich
+
diff --git a/d/seher/haeuser/special/faq/1 b/d/seher/haeuser/special/faq/1
new file mode 100644
index 0000000..a2f9c3c
--- /dev/null
+++ b/d/seher/haeuser/special/faq/1
@@ -0,0 +1,54 @@
+1. TRANSPORTMOEGLICHKEITEN
+---------------------------
+
+Als Seher kannst Du nunmehr auf einige neue Fortbewegungsmoeglichkeiten
+zugreifen, um schneller von einem Ort zum anderen zu gelangen:
+
+a) Seherportale
+---------------
+
+Als Seher kannst Du ab sofort magische Portale nutzen, um schneller
+von einem Ort zum anderen zu gelangen. Es gibt im Moment 33 Tore,
+die Du mit dem Befehl teleportiere benutzen kannst. Zur Verfuegung
+stehen Dir dann momentan folgende Moeglichkeiten (wenn du alle Portale hast):
+
+ 0. nicht teleportieren 1. Tamibar, Daribi-Dorf (10 KP)
+ 2. Drachenzinnen 3. Port Vainer Stadttor
+ 4. An einem Bach im Gebirge 5. Polargebiet
+ 6. Tundra 7. Die Feenstrasse
+ 8. Waldweg 9. Eine Ruinenstadt
+ 10. Vorplatz vor der Arena 11. Klippenpfad auf Aurora (10 KP)
+ 12. Svolvaer (10 KP) 13. Im Bergdorf
+ 14. Vorplatz der Traukapelle 15. Lash
+ 16. Dschungel 17. Ueber den Wolken
+ 18. Am Fluss Tain Wen Tai 19. Ritterdenkmal bei Orkhausen
+ 20. Rodelbahn 21. Hobbitdorf
+ 22. Ein tiefer Wald (10 KP) 23. Ueber dem Schacht
+ 24. Am Ende der Welt (10 KP) 25. Am Friedhof
+ 26. Unter Shaky Island (10 KP) 27. In der Naehe der Festung
+ 28. Tortugas Leuchtturm (10 KP) 29. Katzmandu
+ 30. In einer Hoehle der Rieseninsel 31. Auf einem kleinen Bergpfad
+ 32. Portalraum 33. In der Naehe von Umjak
+ 34. Ein Felsen am Bach 36. Innuit-Siedlung
+ 37. Bei den Werwoelfen 38. Nordstrand von Krylaios
+ 39. Bei einem schwarzen Felsen 40. Der Abgrund des Zorns
+
+Das Benutzen der Portale setzt allerdings voraus, dass Du diese Portale
+bereits gefunden hast. Du musst die Portale also zunaechst einmal
+suchen.
+Einige Portale auf den Inseln kosten KPs, die meisten jedoch nichts.
+Da danach immer wieder gefragt wird: Natuerlich kann man die Portale nur
+benutzen, wenn man sich gerade bei einem befindet.
+
+
+b) Siebenmeilenstiefel
+----------------------
+
+Diese kann man im Seherladen kaufen. Sie haben die Eigenschaft,
+ihren Traeger immer bis zur naechsten Kreuzung weiterzutragen, was bei
+langen Wegen sinnvoll sein kann, in vielen Gegenden jedoch nicht
+funktioniert, weil in jedem Raum mehr als zwei Ausgaenge vorkommen.
+Ausserdem ist das Ganze extrem gewoehnungsbeduerftig, da man bekannte
+Wege jetzt mit ganz anderen Tastenkombinationen abgeht, als wenn man die
+Wege einfach wie gewohnt 'runterrattert'. Einfach mal austesten,
+lustig ists allemal.
diff --git a/d/seher/haeuser/special/faq/10 b/d/seher/haeuser/special/faq/10
new file mode 100644
index 0000000..92ffb61
--- /dev/null
+++ b/d/seher/haeuser/special/faq/10
@@ -0,0 +1,42 @@
+10. PARALLELDIMENSION
+---------------------
+
+Warscheinlich hast Du schon immer gedacht: 'Eine Welt jenseits des
+MorgenGrauens gibt es genausowenig wie Geheimbuende!'
+Nun, bezueglich der Geheimbuende koennte das zutreffen, und natuerlich
+sollst Du auch keine Welt haben neben dem MorgenGrauen, aber es gibt
+im MUD eine Welt, die nur Seher betreten koennen:
+
+Die Paralleldimension
+
+Die Parallelwelt ist im Prinzip die genau gleiche Welt wie das
+'normale' Morgengrauen, mit dem Unterschied, dass an bestimmten Stellen,
+an denen in der 'Normalwelt' keine NPCs stehen, neue oder eben andere
+Monster stehen. In ganz seltenen Faellen (leider) ist sogar die Raum-
+beschreibung in der Parallelwelt anders als in der normalen Welt.
+
+Beispiele fuer unterschiedliche Raeume in der Parallelwelt sind z.B.:
+
+- Drachenschildkroete (w,n,n,w,w vom Sandtiger)
+- Weghier (Lichtung im Grimmswald, da, wo in der Normalwelt die F&E ist)
+
+Momentan ist die Paralleldimension schon eine relativ grosse Welt, die
+auch staendig waechst. Fuer kleinere Seher ist sie vielleicht zu hart,
+am Anfang koennen sie sich aber z.B. im Paragoblinlager bei Port Vain
+austoben. Fuer die hoeheren Seher sind eher solche Sachen wie der
+Weghier oder die Paragruft vor der Polarwueste interessant.
+
+Betreten kann man als Seher die Parallelwelt am einfachsten und
+sichersten ueber das Portal im obersten Geschoss von Mirils Turm
+(Ebene bei Drachenhort)
+Allerdings transportiert das Portal nur zu 98% Wahrscheinlichkeit, und
+man sollte aufpassen, da dort in der Naehe die Seher-Raeuber von Rochus
+im Gebuesch sitzen, die einen schnell zu sich gezogen haben, dort kommt
+man dann nur noch raus, indem man das Geld abgibt oder kaempft :)
+Ausserdem steht in der Parawelt am Portal 2 (das ist das naechste bei
+Mirils Turm) der sogenannte Huorn, das ist ein Baum, der einem Sachen
+klaut (boese zu Patryn rueberschiel :)) Deshalb sollte man da auch aufpassen.
+
+Geruechten zufolge soll es mittlerweile sogar einen neuen Riss in den
+Dimensionen geben, der Zutritt zu einer vielleicht noch gefaehrlicheren
+Welt ermoeglicht.
diff --git a/d/seher/haeuser/special/faq/11 b/d/seher/haeuser/special/faq/11
new file mode 100644
index 0000000..735fc57
--- /dev/null
+++ b/d/seher/haeuser/special/faq/11
@@ -0,0 +1,13 @@
+11. Para-Portal 8
+-----------------
+
+Viele werden sich jetzt vielleicht fragen: Warum widmet man einem
+einfachen Magischen Portal ein ganzes Unterkapitel, aber es ist meiner
+Ansicht nach notwendig. Das Portal 8 ist das bis jetzt einzige Portal, das
+in der Parawelt anders ist als in der Normalwelt. Es hat andere, zum
+groessten Teil nicht ungefaehrliche, Ziele als das in der Normalwelt.
+Welche Ziele dies nun sind, verrate ich natuerlich nicht, das solltet
+ihr schon selbst herausbekommen (entweder fragt ihr andere Seher, oder
+probiert es !SEHR vorsichtig! aus). Ihr solltet es euch auf jeden Fall mal
+anschauen, denn es hat auch seine guten Seiten...
+
diff --git a/d/seher/haeuser/special/faq/12 b/d/seher/haeuser/special/faq/12
new file mode 100644
index 0000000..a44ff5a
--- /dev/null
+++ b/d/seher/haeuser/special/faq/12
@@ -0,0 +1,13 @@
+12. FINGER-BEFEHL
+----------------
+
+Wenn Du einmal probierst, einen anderen Spieler zu fingern, wirst Du
+feststellen, dass Du nun einige zusaetzliche Informationen
+erhaelst, bei normalen Spielern ihr Alter, und bei Sehern / Magiern
+zusaetzlich die ueber Plan und Projekt eingegebenen Informationen.
+
+So, und wenn Du dann auch obendrein nicht allzu zimperlich bist, und
+gerne Leute Dich fingern laesst, so wirst Du natuerlich auch einen Plan
+und ein Projekt in Deinem 'finger' einsetzen. Dies kannst Du mit Hilfe
+des Planeditors machen, den Du im Seherladen erhaelst.
+
diff --git a/d/seher/haeuser/special/faq/13 b/d/seher/haeuser/special/faq/13
new file mode 100644
index 0000000..6763827
--- /dev/null
+++ b/d/seher/haeuser/special/faq/13
@@ -0,0 +1,17 @@
+13. ECHO & R-EMOTE
+------------------
+
+Solltest Du irgendwann die Quest "Hilf dem Architekten" geloest haben
+(was dringend zu empfehlen ist, denn das ist definitiv eines der besten
+quests hier, IMHO) - dann steht Dir als Seher hinterher der ECHO-Befehl
+zur Verfuegung, mit dessen Hilfe Du in der Lage bist, einen x-Beliebigen
+Text in dem Raum abzusetzen, in dem Du Dich befindest, so dass auch alle
+anderen Spieler diesen Text lesen koennen...
+Nette Spielerei, die leider 50 MP kostet, aber trotzdem immer zu einem
+kleinen Gag gut ist.
+
+Solltest Du die Seherquest 'Die Kristallkugel' geloest haben, so steht
+Dir auch das 'r-emote' zur Verfuegung, das es Dir ermoeglicht, das seit
+der Loesung des Amaryllis-Quests (hast Du doch wohl !!) moegliche 'emote'
+auch auf Spieler ausserhalb des Raumes anzuwenden.
+
diff --git a/d/seher/haeuser/special/faq/14 b/d/seher/haeuser/special/faq/14
new file mode 100644
index 0000000..dbd15b3
--- /dev/null
+++ b/d/seher/haeuser/special/faq/14
@@ -0,0 +1,55 @@
+14. SEHERHAEUSER
+----------------
+
+Interessantes Thema: Die Seherhauser: Sie gibt es nun seit ca. Mitte
+Oktober 94, und folgendes ist dazu anzumerken:
+
+In der Bausparkasse in Drachenhort gibt es die noetigen Informationen zu
+den Hauesern. Das Informationsblatt fuer 10.000 Muenzen sollte man sich
+eben zulegen, auch wenn nur eine Seite Infos drinstehen, und es nach dem
+ersten Lesen weg ist :((.
+
+Grundsaetzlich gibt es zwei Moeglichkeiten, zu einem Haus zu kommen:
+
+a) Der schnelle Vertrag: Kostet 2 Mio EPs, man muss alle 2 online Stunden
+eine Rate von 80.000 EPs einzahlen - insgesamt also 25 Raten. Die Zeit kann
+u.U. nach einem Crash etwas knapp werden, da man dann nicht die noetige
+Zeit hat, um sich selbst erstmal Ausruestung zu besorgen, und ja vor allem
+alle Spieler dabei sind, sich Ausruestung zu beschaffen, so dass nicht
+viel zu holen ist.
+
+b) Der langsame Vertrag: Kostet 2.4 Mio Eps - also 30 Raten, man muss alle
+4 online Stunden seine Rate von 80.000 EPs einzahlen. Sicher besser geeignet
+fuer diejenigen, die oft talken, und nicht die naechste Woche nur mit metzeln
+verbringen wollen - Geschmackssache.... natuerlich kann man bei beiden
+Vertragsarten auch schneller einzahlen, also muss man sich keine Sorge machen,
+dass man beim 4-stunden Vertrag ewig warten muss, bis man einen neuen
+Masterblock kriegt, auf dem die Guthaben gutgeschrieben werden.
+
+Welche Vertragsform man waehlt, ist einem selbst ueberlassen.... aber
+ueberlegs Dir gut, ob Du die Zeit zum talken behalten willst, denn die wird
+beim 2h - Vertrag schnell knapp - nicht zu vergessen die Tatsache, dass bei
+Ueberziehen der Einzahlungszeit fuer die einzelnen Raten zunaechst eine
+saftige Strafe faellig wird (es sei denn, der Masterblock ist voll),
+und dann sogar der ganze Vertrag floeten gehen kann....
+
+Im Seherhaus koennen auch Extra-Raeume eingebaut werden. Diese kosten pro
+Stueck entweder 1017600 EPs (2 Onlinestunden) oder 848000 EPs (1 Onlinestunde)
+Maximal koennen 9 Raeume an das Haus angebaut werden. Sofern in einem Raum
+mehrere Haeuser stehen, besteht auch die Moeglichkeit, die durch den Befehl
+Ausgang miteinander zu verbinden.
+
+In den Seherhaeusern sind seit Februar ' 95 das Beschreiben von
+Befehlen und spezifische Ausgaben moeglich. So kann man rassen- und
+geschlechtsspezifische Ausgaben machen. Ebenso ist es moeglich,
+durch Eingabe von Befehlen bestimmte Ausgaben zu erreichen, z.B.
+'druecke knopf' - ' ein Faden faellt von der Decke' usw. Wie das vor
+sich geht, waere hier zu umfassend, ausserdem hat Wargon eine
+hervorragende Hilfeseite zu den Haeusern erstellt, die sehr
+detailliert erklaert, wie man vorgehen muss.
+
+Desweiteren kann man nun die Truhe in den Seherhaeusern verschieben,
+umbenennen und ihr einen Extralook geben. Ausserdem kann die Haustuer
+mit speziellen Funktionen in die Aussenbeschreibung des Hauses eingebaut
+oder unsichtbar gemacht werden. Auch hierzu empfehle ich die Lektuere
+der Hilfe- Seite zum Seherhaus.
diff --git a/d/seher/haeuser/special/faq/15 b/d/seher/haeuser/special/faq/15
new file mode 100644
index 0000000..ccbb47c
--- /dev/null
+++ b/d/seher/haeuser/special/faq/15
@@ -0,0 +1,12 @@
+15. NACHWORT
+------------
+
+Erwaehnen will ich auch noch, dass man sich als Seher auch nicht scheuen
+sollte die hoeheren Seher zu fragen, wenn man etwas nicht weiss, die
+meisten werden dann auch antworten, solange der Umgangston in Ordnung
+ist :) Man kann aber nicht nur direkt die Seher fragen, sondern sollte
+auch _immer_ die Seher-Ebene (-h+) eingeschalten haben, da dort oft
+interessante Dinge diskutiert werden (natuerlich auch viel Stuss :)))
+Auch sollte man regelmaessig die Seher-Rubriken in der MPA lesen, wenn man
+auf dem laufenden bleiben will.
+
diff --git a/d/seher/haeuser/special/faq/16 b/d/seher/haeuser/special/faq/16
new file mode 100644
index 0000000..eed3680
--- /dev/null
+++ b/d/seher/haeuser/special/faq/16
@@ -0,0 +1,14 @@
+16. DANKSAGUNGEN
+----------------
+
+Abschliessend moechte ich noch ein GROSSES DANKESCHOEN an Ryne richten, der
+die Vorfassung dieser FAQ geschrieben hat, und von dem ich auch noch einiges
+uebernommen habe (faul wie ich bin :))
+Und auch an Zephyr noch ein grosses Dankeschoen, da sie diese FAQ fuer mich
+korrekturgelesen hat, und mich auch noch auf einiges hingewiesen hat :)
+Das letzte Dankeschoen geht an Rikus, der sich freundlicherweise die Zeit
+genommen hat, diese FAQ in den Seherladen zu bringen, und mir auch
+ermoeglicht hat, sie immer up to date zu halten :)
+
+
+Sting
diff --git a/d/seher/haeuser/special/faq/2 b/d/seher/haeuser/special/faq/2
new file mode 100644
index 0000000..1228eb2
--- /dev/null
+++ b/d/seher/haeuser/special/faq/2
@@ -0,0 +1,19 @@
+2. SEHERQUEST
+-------------
+
+Eine recht schoene Quest nur fuer Seher hat Troy im Fruehjahr 1995
+geschrieben, allerdings wurde sie erst 4 Monate spaeter
+angeschlossen, nachdem Boing eine Menge Bugs gefixt hatte. Wie auch
+immer:
+Eine lohnende Quest, mit Sicherheit die schoenste, die Troy hier
+geschrieben hat, sie ist auch sehr logisch und die
+Stimmung vor Ort wirklich gut. Also unbedingt spielen, nicht zuletzt,
+weil die Belohnung dafuer wirlich gelungen ist, besser: die Belohnungen!
+Denn a) erhaelt man eine Kristallkugel, mit der man Spieler fuer einen
+Magiepunkt finden kann (siehe auch: Kap. 6: Magische Kugel), und
+b) erhaelt man das R-Emote, mit dem man sein Emote, das man fuer die
+Amaryllis-Quest erhalten hat, auch auf Spieler ausserhalb des Raumes in
+dem man sich befindet, anwenden kann.
+
+Viel Spass beim Questen !!!
+
diff --git a/d/seher/haeuser/special/faq/3 b/d/seher/haeuser/special/faq/3
new file mode 100644
index 0000000..f3fc11a
--- /dev/null
+++ b/d/seher/haeuser/special/faq/3
@@ -0,0 +1,23 @@
+3. FLUCHTRICHTUNG
+-----------------
+
+Etwas unscheinbar, aber in meinen Augen ist dies immer noch der
+wertvollste Befehl, den man als Seher neu erhaelt:
+
+fluchtrichtung <Richtung/Befehl>
+
+Ab sofort kannst Du den Befehl 'fluchtrichtung' anwenden.
+Sollte dieser noch nicht aktiviert sein, musst du einmal Ende machen.
+Danach kannst Du selbst bestimmen, in welche Richtung du fliehst, wenn die
+Angst Dich mal ueberkommen sollte (wenn die Vorsicht zuschlaegt)
+Aber Achtung: Der Befehl funktioniert erst bei einem Spielerlevel von 50
+oder hoeher mit 100% Wahrscheinlichkeit, darunter jeweils niedriger.
+Tip: 'fluchtrichtung schlafe ein' funktioniert auch, ebenso wie:
+'fluchtrichtung teile Boing mit Du, ich sterbe gleich'
+Man muss halt die Prioritaeten richtig setzen ;)).
+
+Warum dieser Befehl in meinen Augen besonders wichtig ist? Nun, er
+befreit Spieler mit sehr hoher Wahrscheinlichkeit von dem Risiko, durch
+ein Lag zu sterben, wenn die Flucht im entscheidenden Moment in die falsche
+Richtung zu gehen droht. Man muss sie vorher nur richtig gesetzt haben.
+
diff --git a/d/seher/haeuser/special/faq/4 b/d/seher/haeuser/special/faq/4
new file mode 100644
index 0000000..148796e
--- /dev/null
+++ b/d/seher/haeuser/special/faq/4
@@ -0,0 +1,9 @@
+4. SEHERLEVEL
+-------------
+
+Die Bedeutung der Levels ist insofern hoch, als dass die Erfolgschance
+der Zaubersprueche in den meisten Gilden von dem Level des Spielers abhaengig
+ist. So ist es grundsaetzlich in einigen Gilden moeglich, die maximale
+Erfolgswahrscheinlichkeit eines Zauberspruches erst dann zu erreichen,
+wenn man z.B. Seherlevel 35 erreicht hat.
+
diff --git a/d/seher/haeuser/special/faq/5 b/d/seher/haeuser/special/faq/5
new file mode 100644
index 0000000..9067f0b
--- /dev/null
+++ b/d/seher/haeuser/special/faq/5
@@ -0,0 +1,38 @@
+5. KOMMUNIKATION
+----------------
+
+Als Seher stehen Dir neue Mittel der Kommunikation zur Verfuegung,
+mittels derer Du Nachrichten an andere Spieler senden kannst:
+
+a) Mail
+-------
+
+Ab sofort steht Dir der kostenlose Kurierdienst der MG-Post zur Verfuegung -
+durch Eingabe von 'mail' kannst du von ueberall Post verschicken und
+empfangen. Dies setzt aber voraus, dass Du eine Zeitung bei Dir traegst,
+da das 'mail' eine Zusatzfunktion der MPA ist.
+
+b) MPA
+------
+
+In der Zeitung steht Dir nun die neue Rubrik 'seher.entwicklung' zur
+Verfuegung, in der Du Deine Vorschlaege zur Verbesserung des Sehertums
+einbringen kannst, sowie die Rubrik 'seher.urlaub'.
+
+c) Kanaele
+----------
+
+Zur direkten Kommunikation mit den anderen Sehern steht Dir nun auch ein
+neuer Kanal zur Verfuegung. Er wird mit '-h' angesprochen (nein, nicht mit
+S wie Seher ;)).
+
+d) Fernschreiber
+----------------
+
+Mit dem Fernschreiber aus dem Seherladen kannst Du ganze Nachrichtenbloecke
+an andere Spieler senden. Dies ist haeufig nuetzlich, wenn man laengere
+Texte an einen anderen Spieler senden will, waehrend man z.B. mit diesem
+zusammen eine neue Region oder eine Quest erforscht. Der Einsatz kostet
+15 KP pro Spieler, an den die Nachricht gesendet wird, man kann auch an
+mehrere Spieler gleichzeitig die Meldung ausgeben lassen.
+
diff --git a/d/seher/haeuser/special/faq/6 b/d/seher/haeuser/special/faq/6
new file mode 100644
index 0000000..6620ae2
--- /dev/null
+++ b/d/seher/haeuser/special/faq/6
@@ -0,0 +1,17 @@
+6. MAGISCHE KUGEL
+-----------------
+
+Im Haus der Hexe am Friedhof findest Du eine Kugel, die Du mitnehmen
+kannst - mit ihr kannst du durch den Befehl 'finde <Spielername>'
+jeden eingeloggten Spieler lokalisieren - ein Einsatz kostet jeweils 9
+KP.
+
+Mit der Einfuehrung der Seherquest von Troy erhaelt man als Questbelohnung
+eine - der Name des Quests laesst es vermuten - Kristallkugel, die dieselbe
+Funktion wie die Seherkugel erfuellt. Allerdings kostet diese pro Einsatz
+nur 1 KP. Dafuer erhaelt allerdings der beobachtete Spieler die Meldung
+'Jemand beschwoert Dein Bild herauf.', was auf Dauer etwas aufdringlich
+wird, da der Betroffene ja nicht weiss, wer ihn da sucht.
+Welche Kugel du als Seher benutzt, kommt wohl auf die eigene Entscheidung und
+den jeweiligen Fall an.
+
diff --git a/d/seher/haeuser/special/faq/7 b/d/seher/haeuser/special/faq/7
new file mode 100644
index 0000000..1fdfc6c
--- /dev/null
+++ b/d/seher/haeuser/special/faq/7
@@ -0,0 +1,15 @@
+7. SEHERLADEN
+-------------
+
+Auf Svolvaer findest Du einen Laden, der spezielle Items nur fuer Seher
+anbietet. Interessant ist hier der Bumerang, der Wecker, die Partytroete,
+der Magische Beutel und der kleine graue Kasten.
+
+Fuer das Angebot im Seherladen ist Loco zustendig, der das Angebot
+sicher gerne erweitern wuerde, und daher fuer Ideen immer aufgeschlossen
+ist - daher schreibe ihm ruhig ein Mail, wenn Du eine Idee hast, was
+dort zukuenftig noch angeboten werden koennte.
+
+Uebrigens gibts auch in der Parawelt in Port Vain nen Seher-Laden, den
+muesst ihr allerdings suchen :))
+
diff --git a/d/seher/haeuser/special/faq/8 b/d/seher/haeuser/special/faq/8
new file mode 100644
index 0000000..8d0e537
--- /dev/null
+++ b/d/seher/haeuser/special/faq/8
@@ -0,0 +1,51 @@
+8. DESIGNER-SEHER
+-----------------
+
+Nun, vielleicht ist dieser Titel auch ein wenig uebertrieben. Aber als
+Seher kannst Du (fast) Deine gesamte Erscheinung im MUD selbst gestalten:
+Nun, Designertypen glaenzen durch ihr Aeusseres, also fangen wir mal beim
+Aussehen an: Was die Spieler sehen, wenn sie Dich untersuchen, kannst Du
+mit dem Befehl 'extralook' bestimmen. Die dort eingegebene Beschreibung
+wird der Auflistung dessen, was Du bei Dir traegst, vorangestellt.
+
+Zur Erscheinung gehoert auch das Auftreten, also designen wir mal ein
+bisschen an Deinen Meldungen herum, die erscheinen, wenn Du einen Raum
+betrittst oder verlaesst. Dies kannst Du mit:
+'setmin <TEXT>' bzw. 'setmout <TEXT>' setzen.
+Und wenn Du moechtest, kannst Du mit 'setmmout' bzw. 'setmmin'
+die Meldungen setzen, die erscheinen, wenn Du einen Ort mittels eines
+Teleports betrittst/verlaesst.
+
+Doch auch Designerseher leben unter dem Joch des Armageddon, und sind daher
+manchmal waffen- und ruestungslos. Wer es aber nicht ertragen kann, in diesen
+bitteren Stunden immer die Meldung 'greift mit blossen Haenden an' zu sehen,
+der kann sich mittels des Befehls 'sethands <TEXT>' eine martialischere
+(oder auch zaertlichere, je nach Geschmack ;)) Kampfmeldung fuer seine Haende
+setzen.
+
+Nun, ein richtiger Seher hat natuerlich auch einen interessanteren
+Namen, nicht so was oedes wie 'Wurst, die Seherin'. Und deshalb koennte
+sich Wurst einen eigenen Namen geben, mit dem Befehl 'titel <TEXT>'.
+Dann hiesse sie hinterher beispielsweise 'Wurst ist ne Wurst'.
+Und wem das noch nicht laessig genug ist, der setzt sich mit
+'presay <TEXT>' auch noch einen Namensvorsatz.
+Beispiel: 'Die Oberwurstseherin Wurst ist ne Wurst'.
+Wenngleich das vielleicht doch nicht SOOO cool ist.
+Geschmackssache halt ;).
+
+
+Ach ja, und wenn man dann bei all der Rumdesignerei vergessen haben sollte,
+was man ueberhaupt eingegeben hat, so erhaelt man mit dem Befehl 'review'
+einen Ueberblick ueber die meisten Einstellungen.
+
+Eine Anmerkung noch: Der Toeter hat vor langer Zeit eine kleine Erweiterung
+in den Befehl setmout eingebaut:
+Nunmehr ist es moeglich, den Text 'nach (Richtung)' nicht mehr nur am Ende,
+sondern irgendwo im Text erscheinen zu lassen: dann muss im Text der
+out-message ein # erscheinen, die dann durch 'nach (Richtung)' ersetzt wird.
+Unterdruecken kannst Du die Richtungsangabe allerdings nicht, wenn Du das #r
+weglaesst, wird diese Angabe einfach hinten angehaengt..
+
+Hilfe dazu liefern aber natuerlich auch wiederum die Seherhilfeseiten unter
+'hilfe seher'
+
diff --git a/d/seher/haeuser/special/faq/9 b/d/seher/haeuser/special/faq/9
new file mode 100644
index 0000000..bb5ca35
--- /dev/null
+++ b/d/seher/haeuser/special/faq/9
@@ -0,0 +1,11 @@
+9. FEHLERMELDUNG
+----------------
+
+Ein nicht besonders wichtiger, aber in seinen Auswirkungen haeufig
+angetroffener Befehl: Fehlermeldung. Wenn Dir das ewige
+'Wie bitte ?' langsam zu eintoenig wird, so kannst Du mit
+'Fehlermeldung <TEXT>' einen neuen Text fuer Deine Fehlermeldung setzen -
+uebrigens genauso wie fuer die Uhrmeldung, was allerdings schon als
+Spieler moeglich ist, was jedoch scheinbar nur recht wenige Spieler
+wissen.
+
diff --git a/d/seher/haeuser/special/faq/faq.o b/d/seher/haeuser/special/faq/faq.o
new file mode 100644
index 0000000..a6cd59a
--- /dev/null
+++ b/d/seher/haeuser/special/faq/faq.o
@@ -0,0 +1,3 @@
+#0:0
+properties ([:2])
+synonym (["level":"4","finger":"12","haus":"14","quest":"2","kugel":"6","designer-seher":"8","portal":"11","echo":"13","fehlermeldung":"9","quests":"2","remote":"13","fluchtrichtung":"3","transportmoeglichkeit":"1","test":"20","seherquest":"2","haeuser":"14","r-emote":"13","seherhaus":"14","para-portal":"11","transport":"1","seherhaeuser":"14","seherladen":"7","magische kugel":"6","transportmoeglichkeiten":"1","paralleldimension":"10","danksagung":"16","seherquests":"2","seherlevel":"4","nachwort":"15","danksagungen":"16","designerseher":"8","finger-befehl":"12","kommunikation":"5","paraportal":"11","fingerbefehl":"12",])
diff --git a/d/seher/haeuser/special/faq/inhalt b/d/seher/haeuser/special/faq/inhalt
new file mode 100644
index 0000000..40780bc
--- /dev/null
+++ b/d/seher/haeuser/special/faq/inhalt
@@ -0,0 +1,28 @@
+Inhalt der SeherFAQ 3.02:
+-------------------------
+
+ 0. Neuigkeiten
+ 1. Transportmoeglichkeiten
+ 2. Seherquests
+ 3. Fluchtrichtung
+ 4. Seherlevel
+ 5. Kommunikation
+ 6. Magische Kugel
+ 7. Seherladen
+ 8. Designer-Seher
+ 9. Fehlermeldung
+ 10. Paralleldimension
+ 11. Para-Portal 8
+ 12. Finger-Befehl
+ 13. Echo, R-Emote
+ 14. Seherhaeuser
+ 15. Nachwort
+ 16. Danksagungen
+
+Die einzelnen Kapitel liest Du einfach mit z.B. lies 12.
+Wenn Du eine Idee hast, was an der FAQ verbessert, geaendert oder
+hinzugefuegt werden sollte, dann waere ich Dir sehr dankbar,
+wenn Du mir eine kurze Mail schicken wuerdest.
+
+Sting
+
diff --git a/d/seher/haeuser/special/faq/seherfaq b/d/seher/haeuser/special/faq/seherfaq
new file mode 100644
index 0000000..1790941
--- /dev/null
+++ b/d/seher/haeuser/special/faq/seherfaq
@@ -0,0 +1 @@
+Mach mal "lies inhalt"
diff --git a/d/seher/haeuser/special/rj.c b/d/seher/haeuser/special/rj.c
new file mode 100644
index 0000000..42f3b98
--- /dev/null
+++ b/d/seher/haeuser/special/rj.c
@@ -0,0 +1,26 @@
+inherit "/std/thing";
+
+#include <properties.h>
+#include "../haus.h"
+
+create()
+{
+ if (!clonep(this_object())) return;
+ ::create();
+
+ SetProp(P_SHORT,0);
+ SetProp(P_NOGET, 1);
+ AddId("r&j");
+ AddCmd("lies", "lies");
+}
+
+static int lies(string str)
+{
+ int nr;
+
+ if (!str || sscanf(str, "seite %d", nr) != 1)
+ return notify_fail("Syntax: lies seite <nr>\n"), 0;
+
+ this_player()->More(SPECIALPATH+"rom_jul/seite"+nr, 1);
+ return 1;
+}
diff --git a/d/seher/haeuser/special/seherfaq.c b/d/seher/haeuser/special/seherfaq.c
new file mode 100644
index 0000000..9ae96e6
--- /dev/null
+++ b/d/seher/haeuser/special/seherfaq.c
@@ -0,0 +1,247 @@
+inherit "std/thing";
+inherit "std/more";
+inherit "/mail/nedit";
+
+#include <properties.h>
+#include <wizlevels.h>
+#include "../haus.h"
+
+#define FAQ(f) (SPECIALPATH+"faq/"+(f))
+#define FAQUSER ({ "ryne", "toss", "sting" })
+#define IS_USER(pl) (member(FAQUSER, getuid(pl)) >= 0)
+
+static string *seite;
+static string f,*s;
+
+mapping synonym = ([]);
+
+create()
+{
+ ::create();
+ SetProp(P_NAME,"SeherFAQ");
+ SetProp(P_GENDER,FEMALE);
+ SetProp(P_NOGET,1);
+ AddId( ({"faq","seherfaq","FAQ","SeherFAQ" }) );
+ AddCmd("lies","lesen");
+ AddCmd(({"beschreib","beschreibe"}),"beschreiben");
+ AddCmd("seiten","seiten");
+ AddCmd(({"loesch","loesche"}),"loeschen");
+ AddCmd(({"kopier","kopiere"}),"kopieren");
+ restore_object(FAQ("faq"));
+ seite = get_dir(FAQ("*"))-({".","..","faq.o"});
+}
+
+init()
+{
+ thing::init();
+ if (this_player() && IS_USER(this_player()))
+ nedit::init_rescue();
+}
+
+string
+_query_short()
+{
+ if (this_player() && IS_SEER(this_player()))
+ return "Die SeherFAQ";
+ else
+ return 0;
+}
+
+string
+_query_long()
+{
+ if (this_player() && IS_SEER(this_player()))
+ return "Dies ist Rynes SeherFAQ.\n\
+Wenn Du weitere Fragen oder Anregungen zu dieser FAQ hast,\n\
+sei so nett und schicke Ryne einen kurzen Brief\n\n\
+Zum Inhalt der FAQ kommst Du mit >lies inhalt<\n";
+ else
+ return 0;
+}
+
+int
+id(string str)
+{
+ if (!IS_SEER(this_player()))
+ return 0;
+ else
+ return ::id(str);
+}
+
+int
+seiten(string str)
+{
+ int i,j;
+ string *syn;
+ closure filter_ldfied;
+
+ if (!IS_USER(this_player()))
+ return 0;
+
+ if(!(i = sizeof(seite)))
+ write("Keine Seiten beschrieben!\n");
+ else {
+ filter_ldfied = lambda(({'ind,'page,'map_ldfied/*'*/}),
+ ({#'==,'page,({#'[/*]'*/,'map_ldfied,'ind})}));
+ for (str = "",i-=1;i>=0;i--) {
+ syn = m_indices(filter_indices(synonym,filter_ldfied,seite[i],synonym));
+ printf("Seite '%s' - ",seite[i]);
+ if (j=sizeof(syn)) {
+ for(j-=1;j>=0;j--)
+ printf("'%s' ",syn[j]);
+ write("\n");
+ }
+ else
+ write( "(keine Synonyme definiert)\n");
+ }
+ }
+ return 1;
+}
+
+int
+lesen(string str)
+{
+ if (!IS_SEER(this_player()))
+ return 0;
+
+ if (!str || str == "") {
+ notify_fail("Was willst Du denn lesen?\n");
+ return 0;
+ }
+ str = lower_case(this_player()->_unparsed_args());
+ if (member(seite,str)<0) {
+ if (!member(synonym,str)) {
+ notify_fail("Diese Seite gibt es nicht...\n");
+ return 0;
+ }
+ else
+ str = synonym[str];
+ }
+ this_player()->More(FAQ(str),1);
+ return 1;
+}
+
+int
+beschreiben(string str)
+{
+ string faq,*desc;
+ int i;
+
+ if (!IS_USER(this_player()))
+ return 0;
+
+ str = lower_case(this_player()->_unparsed_args());
+
+ if (!str || str == "") {
+ notify_fail("Was willst Du denn beschreiben?\n");
+ return 0;
+ }
+ if (sscanf(str,"%s %s",faq,str)!=2 || !id(faq)) {
+ notify_fail("Syntax: beschreibe faq <seite>\n");
+ return 0;
+ }
+ str = implode(old_explode(str," ")-({""}), " ");
+ desc = old_explode(implode(old_explode(str,", "),","),",");
+ f = 0;
+ s = 0;
+
+ for (i=sizeof(desc)-1;i>=0;i--) {
+ if (member(seite,desc[i])>=0) {
+ f = desc[i];
+ s = desc-({desc[i]});
+ break;
+ }
+ }
+ if (!f) {
+ f = desc[0];
+ s = desc[1..];
+ }
+ write("Bitte Beschreibung fuer die FAQ-Seite '"+f+"' angeben\n");
+ nedit("faq");
+ return 1;
+}
+
+static void
+faq(string str)
+{
+ int i;
+ string file;
+
+ if (!str || str == 0) {
+ write("** Abbruch! **\nNichts geaendert!\n");
+ return;
+ }
+
+ if (file_size(file=FAQ(f))>=0)
+ rm(file);
+ write_file(file, str);
+ if (member(seite,f)==-1)
+ seite += ({f});
+
+ for (i=sizeof(s)-1;i>=0;i--)
+ synonym += ([ s[i] : f ]);
+
+ save_object(FAQ("faq"));
+}
+
+int
+loeschen(string str)
+{
+ string *syn;
+ int i;
+
+ if(!IS_USER(this_player()))
+ return 0;
+
+ str = lower_case(this_player()->_unparsed_args());
+ if (!str || str == "") {
+ notify_fail("Was willst Du denn loeschen?\n");
+ return 0;
+ }
+ if (member(seite,str)>=0) {
+ syn = m_indices(filter_indices(synonym,
+ lambda(({'ind,'page,'map_ldfied/*'*/}),
+ ({#'==,'page,({#'[/*]'*/,'map_ldfied,'ind})}))
+ ,seite[i],synonym));
+ rm(FAQ(str));
+ seite -= ({str});
+ }
+ else {
+ str = implode(old_explode(str," ")-({""}), " ");
+ syn = old_explode(implode(old_explode(str,", "),","),",");
+ }
+ for (i=sizeof(syn)-1; i>=0; i--)
+ synonym = filter_indices(synonym,
+ lambda(({'key,'cmp}),
+ ({#'!=,'key,'cmp/*'*/})),
+ syn[i]);
+
+ save_object(FAQ("faq"));
+ write("OK\n");
+ return 1;
+}
+
+int
+kopieren(string str)
+{
+ string *part;
+ int i;
+
+ if (!IS_USER(this_player()))
+ return 0;
+
+ str = lower_case(this_player()->_unparsed_args());
+ part = old_explode(str," ")-({""});
+ if(sizeof(part)<4 || !id(part[0]) || part[2] != "nach" ||
+ member(seite,part[1]) == -1) {
+ notify_fail("kopiere faq <seite> nach <alias>\n");
+ return 0;
+ }
+ str = part[1];
+ part=old_explode(implode(old_explode(implode(part[3..]," "),", "),","),",");
+ for(i=sizeof(part)-1;i>=0;i--)
+ synonym += ([ part[i] : str ]);
+ save_object(FAQ("faq"));
+ write("OK.\n");
+ return 1;
+}
diff --git a/d/seher/haeuser/special/seherfaqinvis.c b/d/seher/haeuser/special/seherfaqinvis.c
new file mode 100644
index 0000000..45d3625
--- /dev/null
+++ b/d/seher/haeuser/special/seherfaqinvis.c
@@ -0,0 +1,236 @@
+inherit "std/thing";
+inherit "std/more";
+inherit "/mail/nedit";
+
+#include <properties.h>
+#include <wizlevels.h>
+#include "../haus.h"
+
+#define FAQ(f) (SPECIALPATH+"faq/"+(f))
+#define FAQUSER ({ "ryne", "toss", "sting" })
+#define IS_USER(pl) (member(FAQUSER, getuid(pl)) >= 0)
+
+static string *seite;
+static string f,*s;
+
+mapping synonym = ([]);
+
+void create()
+{
+ ::create();
+ SetProp(P_NAME,"SeherFAQ");
+ SetProp(P_GENDER,FEMALE);
+ SetProp(P_NOGET,1);
+ AddId( ({"faq","seherfaq","FAQ","SeherFAQ" }) );
+ AddCmd("lies","lesen");
+ AddCmd(({"beschreib","beschreibe"}),"beschreiben");
+ AddCmd("seiten","seiten");
+ AddCmd(({"loesch","loesche"}),"loeschen");
+ AddCmd(({"kopier","kopiere"}),"kopieren");
+ restore_object(FAQ("faq"));
+ seite = get_dir(FAQ("*"))-({".","..","faq.o"});
+}
+
+void init()
+{
+ thing::init();
+ if (this_player() && IS_USER(this_player()))
+ nedit::init_rescue();
+}
+
+string
+_query_short()
+{
+ return 0;
+}
+
+string
+_query_long()
+{
+ return 0;
+}
+
+int
+id(string str)
+{
+ return 0;
+}
+
+int
+seiten(string str)
+{
+ int i,j;
+ string *syn;
+ closure filter_ldfied;
+
+ if (!IS_USER(this_player()))
+ return 0;
+
+ if(!(i = sizeof(seite)))
+ write("Keine Seiten beschrieben!\n");
+ else {
+ filter_ldfied = lambda(({'ind,'page,'map_ldfied/*'*/}),
+ ({#'==,'page,({#'[/*]'*/,'map_ldfied,'ind})}));
+ for (str = "",i-=1;i>=0;i--) {
+ syn = m_indices(filter_indices(synonym,filter_ldfied,seite[i],synonym));
+ printf("Seite '%s' - ",seite[i]);
+ if (j=sizeof(syn)) {
+ for(j-=1;j>=0;j--)
+ printf("'%s' ",syn[j]);
+ write("\n");
+ }
+ else
+ write( "(keine Synonyme definiert)\n");
+ }
+ }
+ return 1;
+}
+
+int
+lesen(string str)
+{
+ if (!IS_USER(this_player()))
+ return 0;
+
+ if (!str || str == "") {
+ notify_fail("Was willst Du denn lesen?\n");
+ return 0;
+ }
+ str = lower_case(this_player()->_unparsed_args());
+ if (member(seite,str)<0) {
+ if (!member(synonym,str)) {
+ notify_fail("Diese Seite gibt es nicht...\n");
+ return 0;
+ }
+ else
+ str = synonym[str];
+ }
+ this_player()->More(FAQ(str),1);
+ return 1;
+}
+
+int
+beschreiben(string str)
+{
+ string faq,*desc;
+ int i;
+
+ if (!IS_USER(this_player()))
+ return 0;
+
+ if (!str || str == "") {
+ notify_fail("Was willst Du denn beschreiben?\n");
+ return 0;
+ }
+
+ str = lower_case(this_player()->_unparsed_args());
+
+ if (sscanf(str,"faq %s",str)!=1) {
+ notify_fail("Syntax: beschreibe faq <seite>\n");
+ return 0;
+ }
+ str = implode(old_explode(str," ")-({""}), " ");
+ desc = old_explode(implode(old_explode(str,", "),","),",");
+ f = 0;
+ s = 0;
+
+ for (i=sizeof(desc)-1;i>=0;i--) {
+ if (member(seite,desc[i])>=0) {
+ f = desc[i];
+ s = desc-({desc[i]});
+ break;
+ }
+ }
+ if (!f) {
+ f = desc[0];
+ s = desc[1..];
+ }
+ write("Bitte Beschreibung fuer die FAQ-Seite '"+f+"' angeben\n");
+ nedit("faq");
+ return 1;
+}
+
+static void
+faq(string str)
+{
+ int i;
+ string file;
+
+ if (!str || str == 0) {
+ write("** Abbruch! **\nNichts geaendert!\n");
+ return;
+ }
+
+ if (file_size(file=FAQ(f))>=0)
+ rm(file);
+ write_file(file, str);
+ if (member(seite,f)==-1)
+ seite += ({f});
+
+ for (i=sizeof(s)-1;i>=0;i--)
+ synonym += ([ s[i] : f ]);
+
+ save_object(FAQ("faq"));
+}
+
+int
+loeschen(string str)
+{
+ string *syn;
+ int i;
+
+ if(!IS_USER(this_player()))
+ return 0;
+
+ str = lower_case(this_player()->_unparsed_args());
+ if (!str || str == "") {
+ notify_fail("Was willst Du denn loeschen?\n");
+ return 0;
+ }
+ if (member(seite,str)>=0) {
+ syn = m_indices(filter_indices(synonym,
+ lambda(({'ind,'page,'map_ldfied/*'*/}),
+ ({#'==,'page,({#'[/*]'*/,'map_ldfied,'ind})}))
+ ,seite[i],synonym));
+ rm(FAQ(str));
+ seite -= ({str});
+ }
+ else {
+ str = implode(old_explode(str," ")-({""}), " ");
+ syn = old_explode(implode(old_explode(str,", "),","),",");
+ }
+ for (i=sizeof(syn)-1; i>=0; i--)
+ synonym = filter_indices(synonym,
+ lambda(({'key,'cmp}),
+ ({#'!=,'key,'cmp/*'*/})),
+ syn[i]);
+
+ save_object(FAQ("faq"));
+ write("OK\n");
+ return 1;
+}
+
+int
+kopieren(string str)
+{
+ string *part;
+ int i;
+
+ if (!IS_USER(this_player()))
+ return 0;
+
+ str = lower_case(this_player()->_unparsed_args());
+ part = old_explode(str," ")-({""});
+ if(sizeof(part)<4 || part[0]!="faq" || part[2] != "nach" ||
+ member(seite,part[1]) == -1) {
+ notify_fail("kopiere faq <seite> nach <alias>\n");
+ return 0;
+ }
+ str = part[1];
+ part=old_explode(implode(old_explode(implode(part[3..]," "),", "),","),",");
+ for(i=sizeof(part)-1;i>=0;i--)
+ synonym += ([ part[i] : str ]);
+ save_object(FAQ("faq"));
+ write("OK.\n");
+ return 1;
+}
diff --git a/d/seher/haeuser/special/seherfaqmobil.c b/d/seher/haeuser/special/seherfaqmobil.c
new file mode 100644
index 0000000..250db4b
--- /dev/null
+++ b/d/seher/haeuser/special/seherfaqmobil.c
@@ -0,0 +1,79 @@
+// tragbare Seher-FAQ, gibt es im Seherladen zu kaufen bzw. automatisch zur Seherwerdung
+// Rikus@mg.mud.de
+
+inherit "std/thing";
+
+#include <properties.h>
+#include <wizlevels.h>
+#include "../haus.h"
+
+#define FAQ(f) (SPECIALPATH+"faq/"+(f))
+
+static string *seite;
+
+mapping synonym = ([]);
+
+create()
+{
+// if (!clonep(this_object())) return;
+ ::create();
+ SetProp(P_SHORT,"Die SeherFAQ");
+ SetProp(P_NAME,"SeherFAQ");
+ SetProp(P_GENDER,FEMALE);
+ SetProp(P_LONG,"Dies ist die SeherFAQ. Wenn Du weitere Fragen oder "+
+ "Anregungen zu dieser FAQ\nhast, sei so nett und schicke Sting "+
+ "einen kurzen Brief. Zum Inhalt der FAQ\nkommst Du mit "+
+ ">lies inhalt<\n");
+ SetProp(P_WEIGHT,100);
+ SetProp(P_VALUE,1000);
+ AddId(({"faq","seherfaq"}));
+ AddCmd("lies","lesen");
+ restore_object(FAQ("faq"));
+ seite = get_dir(FAQ("*"))-({".","..","faq.o"});
+}
+
+init()
+{
+ object o;
+ ::init();
+ if ((o=environment()) && query_once_interactive(o) && !IS_SEER(o))
+ call_out("wech",0);
+}
+
+wech()
+{
+ write("Die Seher-FAQ lacht Dich aus und loest sich in Wohlgefallen auf.\n");
+ remove();
+}
+
+int lesen(string str)
+{
+ if (!str || str == "") {
+ notify_fail("Was willst Du denn lesen?\n");
+ return 0;
+ }
+ if (environment()!=this_player())
+ {
+ notify_fail("Du musst die FAQ schon erst nehmen!\n");
+ return 0;
+ }
+ str = lower_case(this_player()->_unparsed_args());
+ if (member(seite,str)<0) {
+ if (!member(synonym,str)) {
+ notify_fail("Diese Seite gibt es nicht...\n");
+ return 0;
+ }
+ else
+ str = synonym[str];
+ }
+ this_player()->More(FAQ(str),1);
+ return 1;
+}
+
+string _query_extralook()
+{
+ object o;
+ if ((o=environment()) && (o->QueryProp(P_GENDER)==FEMALE))
+ return "Mit ihrer Seher-FAQ outet sie sich als Wurstseherin.\n";
+ return "Mit seiner Seher-FAQ outet er sich als Wurstseher.\n";
+}
diff --git a/d/seher/haeuser/special/special/faq/0 b/d/seher/haeuser/special/special/faq/0
new file mode 100644
index 0000000..95ec97b
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/0
@@ -0,0 +1,18 @@
+0. NEUIGKEITEN
+Hier aktuelle Aenderungen der SeherFAQ 2.0 (Stand 2.11.1995):
+
+- Zunaechst einen grossen Dank an Cuchullin, der eine detaillierte
+ Beschreibung der Artikel aus dem Seherladen zur FAQ beigetragen hat.
+- Endlich die neue FAQ! Die meisten Informationen waren fast ein Jahr alt,
+ und ich hoffe, alle relevanten Informationen auf dem aktuellen Stand zu
+ haben.
+- Mehrere Seherportale wurden in letzter Zeit neu angehaengt. Welche nunmehr
+ vorhanden sind, kannst du in '1. Transportmoeglichkeiten' nachlesen.
+- Toeter hat das setmout geaendert - nunmehr kann die Richtungsangabe
+ weggelassen oder an eine beliebige Stelle im Text gesetzt werden.
+- Im Seherladen gibt es einige neue Artikel; hierzu '7. Sehrladen'.
+- Die Paralleldimension waechst staendig; einige interessante Monster hieraus
+ sind in '10. Paralleldimension' aufgefuehrt, aber wie so oft, selbst
+ schauen, und man findet was neues ;-).
+
+
diff --git a/d/seher/haeuser/special/special/faq/1 b/d/seher/haeuser/special/special/faq/1
new file mode 100644
index 0000000..c9954c0
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/1
@@ -0,0 +1,47 @@
+1. Transportmoeglichkeiten.
+
+Als Seher kannst Du nunmehr auf einige neue Fortbewegungsmoeglichkeiten
+zugreifen, um schneller von einem Ort zum anderen zu gelangen:
+
+A) Seherportale
+Als Seher kannst Du ab sofort magische Portale nutzen, um schneller
+von einem Ort zum anderen zu gelangen. es gibt im Moment 21 Tore,
+die an folgenden Stellen liegen:
+
+ 1. Tamibar Dschungel 11. Klippenpfad auf Aurora
+ 2. Bei den Drachenzinnen 12. Hauptstrase Suedende auf Svolvaer
+ 3. Port Vainer Stadttor 13. Im Bergdorf
+ 4. An einem Bach im Gebirge 14. Vorplatz Traukapelle
+ 5. Im Polargebiet 15. Lash
+ 6. Tundra 16. Im Dschungel
+ 7. Feenstrasse 17. Auf den Wolken
+ 8. Waldweg 18. Am Fluss Tain Wen Tai
+ 9. Ruinenstadt 19. Ritterdenkmal bei Orkhausen
+10. Vorplatz Arena 20. Rodelbahn
+21. Hobbitdorf
+
+Diese Tore kannst du mit dem Befehl 'teleportiere' benutzen.Dies setzt
+allerdings voraus, dass Du dieses Portal bereits gefunden hast. Du musst die
+Portale also zunaechst einmal suchen ;).Ein Teleportieren zu einem anderen
+Portal kostet 50 MP. Da danach immer wieder gefragt wird: Natuerlich kann man
+die Portale nur benutzen, wenn man sich gerade bei einem befindet ;)).
+
+B) Pegasus
+Du kannst ebenso mit Pegasus durch die Gegend fliegen - das kostet keine
+MP und geht auch recht fixe - Haltestellen: vor dem Elfendorf, im
+Polargebiet, Zwergenstadt, Svolvaer, Port Vain. Einmal mitfliegen
+kostet 222 Muenzen, und man kann als Seher einen normalen Spieler
+zum Mitfliegen einladen. Ich fluche regelmaessig ueber Pegasus, weil
+man es kaum schafft, >besteige Pferd< einzugeben, so schnell hebt
+das Tierchen wieder ab. Deshalb hab ich mir ein ali darauf gelegt, ist
+wohl empfehlenswert.
+
+C) Siebenmeilenstiefel
+Diese kann man im Seher im Seherladen kaufen; sie haben die Eigenschaft,
+ihren Traeger immer bis zur naechsten Kreuzung weiterzutragen, was bei langen
+Wegen sinnvoll sein kann, in vielen Gegenden jedoch nicht funktioniert, weil
+in jedem Raum mehr als zwei Ausgaenge vorkommen. Ausserdem ist das Ganze
+extrem gewoehnungsbeduerftig, da man bekannte Wege jetzt mit ganz anderen
+Tastenkombinationen abgeht, als wenn man die Wege einfach wie gewohnt
+'runterrattert'. Einfach mal austesten, lustig ists allemal.
+
diff --git a/d/seher/haeuser/special/special/faq/10 b/d/seher/haeuser/special/special/faq/10
new file mode 100644
index 0000000..90e96f4
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/10
@@ -0,0 +1,23 @@
+
+10. PARALLELDIMENSION
+
+Warscheinlich hast Du schon immer gedacht: 'Eine Welt jenseits des
+MorgenGrauens gibt es genausowenig wie Geheimbuende!' - Nun, bezueglich der
+Geheimbuende mag das zutreffen, und natuerlich sollst Du auch keine Welt
+haben neben dem MorgenGrauen, aber es gibt im MUD eine Welt, die nur Seher
+betreten koennen: Die Paralleldimension.
+
+Momentan ist die Paralleldimension noch eine relativ kleine Welt, die von den
+meisten Sehern eher per Zufall betreten wird; man erreicht sie naemlich nur,
+wenn beim teleportieren in einem magischen Portal etwas schief laeuft... nun,
+diesen Effekt kann man umkehren, es gibt auch ein starres Portal, das einem
+das bewusste Betreten / Verlassen der Parallelwelt ermoeglicht. Bevor man
+jedoch Hals ueber Kopf in bekannte Sphaeren zurueckkehrt, sollte man sich
+schon ein wenig in der Paralleldimension umschauen, da diese stetig ausgebaut
+wird und mittlerweile einige interessante Monster enthaelt. Diese finden sich
+Hauptsaechlich in der Ebene, wo man einmal den Weghier, den Cu Sith und den
+(den ? (DIE!)) Goblindrachen aufsuchen sollte; aber auch in und um Schrumpfis
+Gruft finden sich einige interessante Monster.
+
+Und: Have fun, schwache Nerven sollte man dort nicht mitbringen :-).
+
diff --git a/d/seher/haeuser/special/special/faq/11 b/d/seher/haeuser/special/special/faq/11
new file mode 100644
index 0000000..792b75a
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/11
@@ -0,0 +1,14 @@
+
+11.FINGER-BEFEHL
+
+Wenn Du einmal probierst, einen anderen Spieler zu fingern, wirst Du
+feststellen, dass Du nun einige zusaetzliche Informationen erhaelst, bei
+normalen Spielern ihr Alter, und bei Sehern / Magiern zusaetzlich die
+ueber Plan und Projekt eingegebenen Informationen.
+
+So, und wenn Du dann auch obendrein nicht allzu zimperlich bist, und gerne
+Leute Dich fingern laesst, so wirst Du natuerlich auch einen Plan und ein
+Projekt in Deinem 'finger' einsetzen. Dies kannst Du mit Hilfe des
+Planeditors machen, den Du im Seherladen erhaelst.
+
+
diff --git a/d/seher/haeuser/special/special/faq/12 b/d/seher/haeuser/special/special/faq/12
new file mode 100644
index 0000000..6593f64
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/12
@@ -0,0 +1,15 @@
+12. ECHO & R-EMOTE
+Solltest Du irgendwann den Archie geloest haben (was dringend zu
+empfehlen ist, denn das ist definitiv eines der besten quests hier neben
+den Pyras und Tarko - IMHO) - dann steht Dir als Seher hinterher der
+ECHO-Befehl zur Verfuegung, mit dessen Hilfe Du in der Lage bist,
+einen x-Beliebigen Text in dem Raum abzusetzen, in dem Du Dich
+befindest, so daDich auch alle anderen Spieler diesen Text lesen koennen...
+Nette Spielerei, die leider 48 MP kostet, aber trotzdem immer zu einem
+kleinen Gag gut ist (gelle, Bloodgore ???).
+
+Solltest Du das Seherquest 'Die Kristallkugel' geloest haben, so steht Dir
+auch das 'r-emote' zur Verfuegung, das es Dir ermoeglicht, das seit der
+Loesung des Amaryllis-Quests (hast Du doch wohl !!) moegliche emote auch auf
+Spieler ausserhalb des Raumes anzuwenden.
+
diff --git a/d/seher/haeuser/special/special/faq/13 b/d/seher/haeuser/special/special/faq/13
new file mode 100644
index 0000000..22866ec
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/13
@@ -0,0 +1,14 @@
+13. MAGISCHER BEUTEL
+In dem Seherladen auf Svolvaer kannst Du einen magischen Beutel kaufen, mit
+dem Du Objekte erzeugen kannst. Grundsaetzlich ist dies zwar nur ein Spass,
+aber es lassen sich damit grundsaetzlich auch Objekte erzeugen, die im Spiel
+verwendet werden koennen. Allerdings halten diese Objekte nur knappe 15
+minuten, bevor sie sich in Luft aufloesen.
+
+Da die Anwendung des Beutels oftmals daran scheitert, dass er ein wenig kom-
+pliziert zu Bedienen und schlecht dokumentiert ist, habe ich eine step-by-
+step Anleitung dazu geschrieben, die allerdings recht ausfuehrlich ist;
+solltest Du die FAQ nur fuer einen kurzen Ueberblick lesen wollen, so kannst
+Du die Anleitung natuerlich auch spaeter lesen. Ansonsten: Die Anleitung
+liest man mit 'lies Anleitung'!! ;-)
+
diff --git a/d/seher/haeuser/special/special/faq/14 b/d/seher/haeuser/special/special/faq/14
new file mode 100644
index 0000000..044850f
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/14
@@ -0,0 +1,61 @@
+14. SEHERHAEUSER
+Interessantes Thema: Die Seherhauser: Sie gibt es nun seit ca. Mitte
+Oktober 94, und folgendes ist dazu anzumerken:
+I. In der Bausparkasse in Drachenhort gibt es die noetigen Informationen
+zu den Hauesern. Das Informationsblatt fuer 10.000 Muenzen sollte man
+sich eben zulegen, auch wenn nur eine Seite Infos drinstehen, und es
+nach dem ersten Lesen weg ist :((.
+Grundsaetzlich gibt es zwei Moeglichkeiten, zu einem Haus zu kommen:
+a). Der schnelle Vertrag: Kostet 2 Mio EPs, man muss alle 2 online Stunden
+eine Rate von 80.000 EPs einzahlen - insgesamt also 25 Raten. Die
+Zeit kann u.U. nach einem Crash etwas knapp werden, da man dann
+nicht die noetige Zeit hat, um sich selbst erstmal Ausruestung zu
+besorgen, und ja vor allem alle Spieler dabei sind, sich Ausruestung zu
+beschaffen, so dass nicht viel zu holen ist.
+b). Der langsame Vertrag: Kostet 2.4 Mio Eps - also 30 Raten,
+man muss alle 4 online Stunden seine Rate von 80.000 EPs
+einzahlen. Sicher besser geeignet fuer diejenigen, die oft talken, und nicht
+die naechste Woche nur mit metzeln verbringen wollen -
+Geschmackssache.... natuerlich kann man bei beiden Vertragsarten auch
+schneller einzahlen, also muss man sich keine Sorge machen, dass man
+beim 4-stunden Vertrag ewig warten muss, bis man einen neuen
+Masterblock kriegt, auf dem die Guthaben gutgeschrieben werden.
+c) Welche Vertragsform man waehlt, ist einem selbst ueberlassen.... aber
+ueberlegs Dir gut, ob Du die Zeit zum talken behalten willst, denn die
+wird beim 2h - Vertrag schnell knapp - nicht zu vergessen die Tatsache,
+dass bei Ueberziehen der Einzahlungszeit fuer die einzelnen Raten
+zunaechst eine saftige Strafe faellig wird, und dann sogar der ganze
+Vertrag floeten gehen kann....
+d). Meine Anmerkung: Wer so richtig heiss auf ein Haus ist, metzelt eine
+nacht durch. Ich hab damals um 0.00 Uhr angefangen, und morgens um 8
+war das Haus fertig - nachts sind weniger Spieler dabei, und man hat
+mehr Opfer, die man ausschlachten kann...... Durchschnittszeit fuer eine
+Rate war laut logfile 23 minuten.... sicherlich ein Argument fuer den 2-
+Stunden- Vertrag.
+II. Seit Mitte Januar koennen in den Haeusern auch extra-Raeume eingebaut
+werden. Diese kosten pro Stueck 200.000 Muenzen, und man kann, wie
+auch beim Hausbau, zwischen einem schnellen und einem sanften Vertrag
+waehlen.
+Maximal koennen 9 Raeume an das Haus angebaut werden. Sofern in einem
+Raum mehrere Haeuser stehen, besteht auch die Moeglichkeit, die durch
+den Befehl Ausgang miteinander zu verbinden.
+III. In den Seherhaeusern sind seit Februar ' 95 das Beschreiben von Befehlen
+und spezifische Ausgaben moeglich. So kann man Rassen und - Geschlechtsspe-
+zifische Ausgaben machen. Ebenso ist es moeglich, durch Eingabe von Befehlen
+bestimmte Ausgaben zu erreichen, z.B. 'druecke knopf' - ' ein Faden faellt
+von der Decke' usw. Wie das vor sich geht, waere hier zu umfassend, ausser-
+dem hat Wargon eine hervorragende Hilfeseite zu den Haeusern erstellt, die
+sehr detailliert erklert, wie man vorgehen muss.
+IV. Desweiteren kann man nun die Truhe in den Seherhaeusern verschieben,
+umbenennen und ihr einen Extralook geben. Ausserdem kann die Haustuer mit
+speziellen Funktionen in die Aussenbeschreibung des Hauses eingebaut oder
+unsichtbar gemacht werden. Auch hierzu empfehle ich die Lektuere der Hilfe-
+Seite zum Seherhaus.
+V. Die Moeglichkeiten, die Im Seherhaus zur Verfuegung stehen, sind hier nur
+rudimentaer darstellbar, insbesondere da sie dank Wargon's toller Arbeit in
+diesem Bereich stetig wachsen. Ich plane in naeherer Zukunft einmal ein
+'Musterhaus' aufzubauen, in dem alle Moeglichkeiten, die die Seherhaeuser
+bieten, dargestellt werden, allerdings wird dieses nicht vor Januar 1996
+fertig werden; allerdings kannst Du eine Menge Hilfen auch auf den
+Hilfeseiten zum Seherhaus erhalten, die sehr ausfuehrlich und gut geschrieben
+sind.
diff --git a/d/seher/haeuser/special/special/faq/15 b/d/seher/haeuser/special/special/faq/15
new file mode 100644
index 0000000..449109c
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/15
@@ -0,0 +1,24 @@
+15. SEHERSPIELPLATZ
+
+Mit dem Seherspielplatz ist nunmehr auch eine Region eroeffnet worden,
+die ausschliesslich von den Sehern gestaltet werden soll. Einige haben
+die Insel am Ostrand der Wueste ja schon gesehen und dort schon einiges
+gebastelt.
+Zwei Sachen erscheinen mir im Zusammenhang mit der Insel
+erwaehnenswert: 1. Die Gestaltung der Insel kann wirklich nur gelingen,
+wenn alle Seher zusammenarbeiten. Dies heisst, dass man sich
+insbesondere bei den gewaehlten Ausgaengen abspricht, um ein
+entstandenes lab nicht durch einen einfachen Ausgang kaputtzumachen.
+2. Sobald die Ausgaenge gelegt sind, und die ersten
+Raumbeschreibungen geschrieben werden, heisst es auch wieder
+aufpassen. Es waere schoen, wenn benachbarte Raeume in gewisser
+Form auch zueinander passen - also schaut Euch um, wenn ihr einen
+Raum beschreibt, was dort in der Nachbarschaft fuer Raeume existieren.
+Wie funktioniert der Automat vor der Insel ?
+Naja, dazu wurden tausend Fragen gestellt - dabei ists ganz einfach:
+a) Man drueckt einen Knopf entsprechend dem item, das man kaufen
+moechte (langbeschreibung, ausgang, detail)
+b) Man wirft die entsprechende Menge von Muenzen ein - die Anzeige
+zeigt, wieviel es kostet, und wieviel noch fehlt.
+c) Man nimmt den erworbenen Gegenstand mit und setzt ihn in dem
+Raum ein, den man sich dafuer ausgesucht hat.
diff --git a/d/seher/haeuser/special/special/faq/16 b/d/seher/haeuser/special/special/faq/16
new file mode 100644
index 0000000..416a1ec
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/16
@@ -0,0 +1,43 @@
+
+Damit bei der Vielzahl von Sehern nicht der Ueberblick verloren
+geht, wo ihre ganzen Haeuser stehen, hier auch ein kleines
+Adressenverzeichnis - voellig unvollstaendig, also schreibt mir mal,
+wenn ihr von einem Haus wisst, das ich ausgelassen habe, oder
+wenn Euer Haus einen anderen Namen als den hier aufgefuehrten hat.
+
+Das Haus von Aargon auf dem Weg vor dem Zigeunerlager
+Arameas Fachwerkhaus beim Imker
+Die Blockhuette von Asmodis westlich vom Fackelladen
+Das Haus von Bambulko Trampelpfad beim Elfendorf
+Das Haus von Barak am Strand der Sonneninsel
+Das Haus von Bernhard Waldweg oestlich Glockenwald
+Bleelumpes Dreimaster am Strand noerdlich von Port Vain
+Das Haus von Dion auf der Kreuzung vor dem Friedhof
+Hoehle von Eros Ostrand des Neandertals
+Das Haus von Grimmborn auf Svolvaer
+Hardils Baumhaus auf dem Baum westlich vom Elfendorf
+Das Haus von Hawk Obstwiese beim Ostwall
+Das Haus von Helloween im SW von Moron
+Das Haus von Iolanthe beim Bernhardiner noerdlich zum Krater
+Khornes Schrein im noerdlichen Lupinental
+Der Steinbruch von Kieselstein am Strand in Port Vain
+Das Haus von Klinge beim Drachenbaby auf der HE
+Das Haus von Kotzbrocken suedlich vom zugefrorenen Weiher
+LaMuertes Felsbrocken Weg in die Wueste
+Laurins Zwergenhoehle in Valgessa
+MagicOllis Meditationstempel Waldweg oestlich Glockenwald
+Minnis Schloesschen im Glockenwald
+Mystix Wolke Eingang Schreckensspitze
+Das Haus von Rafael bei der Tanne im Hexenwald
+Das Haus von Ray auf dem Weg vor dem Zigeunerlager
+Das Haus von Rudiratter schau mal nebenan nach ;)
+Das Haus von Ryne da stehst Du drin !
+Die Strandvilla von Rxtech am Strand noerdlich von Port Vain
+Das Haus von Slyfox Kreuzung vor dem Friedhof
+Das Hau von Snooker Oestlich der Plaza in Moron
+Stahldorns Monolith beim Brunnen im Hexenwald
+Das Haus des Toeters zwischen Port Vain und Goblinlager
+Tzuiops Huette auf dem Baum westlich vom Elfendorf
+Das Haus von Woelkchen unter dem Regenbogen beim Bergdorf
+Der Eingang zu einer Hoehle beim Gletscher (immer nach N- und)
+ nicht zufaellig in eine andere Dimension)
diff --git a/d/seher/haeuser/special/special/faq/17 b/d/seher/haeuser/special/special/faq/17
new file mode 100644
index 0000000..2c3fafa
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/17
@@ -0,0 +1 @@
+Du siehst keinen Fehler im Raum-Zeit-Gefuege.
diff --git a/d/seher/haeuser/special/special/faq/18 b/d/seher/haeuser/special/special/faq/18
new file mode 100644
index 0000000..ee8b2a2
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/18
@@ -0,0 +1,239 @@
+
+
+
+Alphabetische Auflistung aller Seher im MorgenGrauen, Stand 18.09.1995
+
+(gesamt 232 Seher, zu diesem Zeitpunkt 215 Magier)
+Aargon 1690 33132039 ( 28) 44 Tage, 7 Stunden und 3 Minuten
+Aceg 905 734710 ( 20) 2 Tage, 5 Stunden und 51 Minuten
+Acrimon 1375 1906217 ( 21) 37 Tage, 19 Stunden und 46 Minuten
+Aell 1285 899016 ( 20) 21 Tage, 7 Stunden und 35 Minuten
+Alemanne 1430 3851409 ( 23) 19 Tage, 0 Stunden und 20 Minuten
+Aline 1410 1065274 ( 21) 24 Tage, 2 Stunden und 20 Minuten
+Alkuin 1615 3471392 ( 23) 4 Tage, 4 Stunden und 15 Minuten
+Almundi 1665 12045567 ( 26) 29 Tage, 9 Stunden und 33 Minuten
+Alxx 1275 210695 ( 20) 8 Tage, 10 Stunden und 58 Minuten
+Amazora 720 7620965 ( 25) 60 Tage, 14 Stunden und 59 Minuten
+Anaid 1375 283907 ( 22) 23 Tage, 2 Stunden und 50 Minuten
+Anakin 2000 91720168 ( 31) 86 Tage, 10 Stunden und 36 Minuten
+Ancalagon 1500 3203323 ( 23) 22 Tage, 5 Stunden und 31 Minuten
+Anno 1250 379677 ( 20) 20 Tage, 21 Stunden und 9 Minuten
+Aquatoll 1230 1016831 ( 20) 12 Tage, 7 Stunden und 44 Minuten
+Aragon 1235 1618754 ( 21) 13 Tage, 19 Stunden und 37 Minuten
+Aramea 1520 5634558 ( 24) 26 Tage, 0 Stunden und 12 Minuten
+Ark 1620 1612954 ( 21) 15 Tage, 3 Stunden und 8 Minuten
+Arty 1940 28051401 ( 28) 30 Tage, 6 Stunden und 37 Minuten
+Arun 1200 1002993 ( 20) 9 Tage, 18 Stunden und 25 Minuten
+Asmodina 1985 3609044 ( 23) 43 Tage, 10 Stunden und 49 Minuten
+Asmodis 1985 26038442 ( 28) 164 Tage, 1 Stunde und 35 Minuten
+Augra 1790 987087 ( 20) 32 Tage, 17 Stunden und 22 Minuten
+Aurian 1495 1565849 ( 21) 2 Tage, 13 Stunden und 40 Minuten
+Barak 1105 4313368 ( 23) 20 Tage, 22 Stunden und 8 Minuten
+Bellicus 1370 7309868 ( 24) 47 Tage, 2 Stunden und 1 Minute
+Bernhard 2060 30025276 ( 28) 59 Tage, 20 Stunden und 58 Minuten
+Bibo 1875 33001194 ( 28) 65 Tage, 2 Stunden und 8 Minuten
+Bienchen 1305 1979490 ( 21) 10 Tage, 9 Stunden und 9 Minuten
+Big 1690 2937075 ( 22) 11 Tage, 11 Stunden und 50 Minuten
+Bigfoot 1660 12667085 ( 26) 30 Tage, 20 Stunden und 53 Minuten
+Bleelumpe 1265 5256959 ( 24) 20 Tage, 21 Stunden und 14 Minuten
+Bloodgore 1570 6061450 ( 28) 56 Tage, 16 Stunden und 59 Minuten
+Bluemel 1450 1547717 ( 21) 20 Tage, 16 Stunden und 13 Minuten
+Boebbel 1675 1224533 ( 21) 28 Tage, 1 Stunde und 35 Minuten
+Bottom 1355 1062102 ( 20) 18 Tage, 19 Stunden und 57 Minuten
+Brit 1260 1973712 ( 22) 20 Tage, 6 Stunden und 1 Minute
+Brummel 1850 11779550 ( 26) 25 Tage, 1 Stunde und 15 Minuten
+Cael 1335 1536548 ( 21) 17 Tage, 7 Stunden und 27 Minuten
+Caradhras 1920 101383337 ( 32) 113 Tage, 23 Stunden und 57 Minuten
+Carefree 1280 1356967 ( 20) 8 Tage, 21 Stunden und 1 Minute
+Castaway 1220 2196508 ( 22) 43 Tage, 22 Stunden und 7 Minuten
+Celebdil 1250 11573503 ( 25) 40 Tage, 0 Stunden und 28 Minuten
+Charly 1430 3793972 ( 22) 16 Tage, 8 Stunden und 51 Minuten
+Chavez 1600 299023 ( 21) 33 Tage, 12 Stunden und 0 Minuten
+Chicola 1450 23157008 ( 27) 67 Tage, 12 Stunden und 17 Minuten
+Coven 1310 1940343 ( 22) 10 Tage, 20 Stunden und 53 Minuten
+Craig 1380 5415105 ( 24) 22 Tage, 20 Stunden und 8 Minuten
+Crolla 2060 15062412 ( 26) 32 Tage, 12 Stunden und 36 Minuten
+Cub 1340 1453817 ( 20) 4 Tage, 4 Stunden und 11 Minuten
+Cuchullin 2060 9366380 ( 25) 41 Tage, 8 Stunden und 26 Minuten
+Daniel 1420 2125614 ( 22) 18 Tage, 23 Stunden und 6 Minuten
+Data 1280 1383631 ( 20) 16 Tage, 11 Stunden und 6 Minuten
+Deimos 1550 1614972 ( 21) 4 Tage, 18 Stunden und 19 Minuten
+Desasta 1560 9822728 ( 25) 24 Tage, 15 Stunden und 27 Minuten
+Desideria 1275 1340228 ( 20) 1 Tag , 12 Stunden und 33 Minuten
+Dhojakt 1625 5612138 ( 24) 42 Tage, 16 Stunden und 57 Minuten
+Digedag 1200 817911 ( 20) 17 Tage, 21 Stunden und 8 Minuten
+Dion 1020 1396400 ( 21) 11 Tage, 8 Stunden und 29 Minuten
+Drakor 1410 973727 ( 20) 13 Tage, 16 Stunden und 25 Minuten
+Durin 1840 27000290 ( 28) 55 Tage, 4 Stunden und 45 Minuten
+Dwight 2030 7337624 ( 24) 42 Tage, 18 Stunden und 4 Minuten
+Earendil 1640 3243728 ( 22) 7 Tage, 14 Stunden und 11 Minuten
+Emil 1420 1189480 ( 20) 15 Tage, 8 Stunden und 26 Minuten
+Engywuck 1755 2485639 ( 23) 83 Tage, 14 Stunden und 51 Minuten
+Eowin 1045 1123115 ( 20) 3 Tage, 21 Stunden und 14 Minuten
+Etain 1285 1184123 ( 21) 23 Tage, 13 Stunden und 3 Minuten
+Eule 1290 534666 ( 20) 9 Tage, 10 Stunden und 3 Minuten
+Fagus 1915 1130690 ( 20) 14 Tage, 6 Stunden und 20 Minuten
+Fahnder 1595 7304188 ( 25) 32 Tage, 7 Stunden und 32 Minuten
+Fantaboy 1415 691662 ( 20) 19 Tage, 1 Stunde und 13 Minuten
+Fauli 1285 2042386 ( 22) 35 Tage, 1 Stunde und 30 Minuten
+Fels 1575 4288401 ( 23) 30 Tage, 12 Stunden und 50 Minuten
+Fipps 1325 6187204 ( 24) 27 Tage, 4 Stunden und 46 Minuten
+Flintnail 1415 1392090 ( 21) 29 Tage, 18 Stunden und 1 Minute
+Fones 1385 1695359 ( 21) 11 Tage, 23 Stunden und 43 Minuten
+Fryder 1810 20079125 ( 27) 66 Tage, 19 Stunden und 40 Minuten
+Fyt 1625 103796399 ( 32) 105 Tage, 9 Stunden und 50 Minuten
+Gabi 1985 4912832 ( 24) 14 Tage, 16 Stunden und 55 Minuten
+Gandulf 1435 2363789 ( 22) 15 Tage, 12 Stunden und 39 Minuten
+Granata 1900 8163375 ( 25) 22 Tage, 23 Stunden und 20 Minuten
+Gumpy 1650 12022713 ( 26) 23 Tage, 10 Stunden und 34 Minuten
+Hackfried 2060 7218856 ( 24) 27 Tage, 4 Stunden und 22 Minuten
+Hadra 2010 8863573 ( 25) 41 Tage, 15 Stunden und 31 Minuten
+Har 1200 1434190 ( 21) 39 Tage, 18 Stunden und 7 Minuten
+Hardil 1170 7775164 ( 25) 31 Tage, 23 Stunden und 54 Minuten
+Hasenfuss 1325 7259495 ( 24) 30 Tage, 3 Stunden und 37 Minuten
+Hawk 1230 3618526 ( 23) 31 Tage, 1 Stunde und 17 Minuten
+Helloween 1805 17742802 ( 27) 29 Tage, 19 Stunden und 32 Minuten
+Hercules 1440 2157741 ( 21) 12 Tage, 16 Stunden und 2 Minuten
+Holden 1380 218539 ( 40) 10 Tage, 3 Stunden und 7 Minuten
+Hoppla 1220 1174934 ( 20) 2 Tage, 7 Stunden und 58 Minuten
+Huor 1245 1770486 ( 21) 13 Tage, 8 Stunden und 43 Minuten
+Hurin 1460 2284648 ( 22) 22 Tage, 5 Stunden und 33 Minuten
+Idur 1965 3376840 ( 23) 5 Tage, 6 Stunden und 50 Minuten
+Ineluki 1555 1969710 ( 21) 1 Tag , 17 Stunden und 26 Minuten
+Inskipp 1585 2982790 ( 22) 12 Tage, 23 Stunden und 17 Minuten
+Iolanthe 1555 5992258 ( 24) 35 Tage, 3 Stunden und 59 Minuten
+Isabeau 2060 3380499 ( 23) 9 Tage, 0 Stunden und 14 Minuten
+Isabelle 1390 547478 ( 20) 3 Tage, 11 Stunden und 5 Minuten
+Isnogood 1775 2881018 ( 22) 27 Tage, 18 Stunden und 27 Minuten
+Issomad 1985 11020515 ( 26) 20 Tage, 5 Stunden und 10 Minuten
+Jaf 1180 429696 ( 20) 71 Tage, 5 Stunden und 4 Minuten
+Janice 2060 13511650 ( 26) 53 Tage, 19 Stunden und 37 Minuten
+Jerrico 1485 4567925 ( 24) 31 Tage, 9 Stunden und 47 Minuten
+Jimdigriz 2015 4229005 ( 23) 100 Tage, 2 Stunden und 26 Minuten
+Jiriki 1570 3858241 ( 23) 3 Tage, 15 Stunden und 41 Minuten
+Jurry 1410 7073544 ( 25) 33 Tage, 8 Stunden und 42 Minuten
+Kafka 1215 769262 ( 21) 9 Tage, 8 Stunden und 55 Minuten
+Kalliope 1385 1539329 ( 20) 1 Tag , 20 Stunden und 24 Minuten
+Kartii 1555 1746919 ( 20) 16 Tage, 13 Stunden und 1 Minute
+Kelder 1945 5109825 ( 23) 46 Tage, 17 Stunden und 44 Minuten
+Kermit 1745 6203256 ( 25) 48 Tage, 3 Stunden und 39 Minuten
+Khidar 1920 50140999 ( 29) 62 Tage, 20 Stunden und 36 Minuten
+Khorne 1640 130376 ( 24) 62 Tage, 8 Stunden und 3 Minuten
+Kieselstein 1220 7925011 ( 26) 16 Tage, 13 Stunden und 3 Minuten
+Kiwi 1495 723804 ( 20) 32 Tage, 6 Stunden und 59 Minuten
+Klausi 1750 6186382 ( 24) 16 Tage, 20 Stunden und 8 Minuten
+Konto 1195 1399690 ( 21) 5 Tage, 0 Stunden und 6 Minuten
+Kotzbrocken 1925 40103319 ( 29) 41 Tage, 8 Stunden und 16 Minuten
+Laurin 1945 4237757 ( 24) 66 Tage, 19 Stunden und 19 Minuten
+Lefty 1660 11580339 ( 26) 27 Tage, 16 Stunden und 20 Minuten
+Leia 1745 7832318 ( 25) 23 Tage, 12 Stunden und 19 Minuten
+Liutberga 1725 2369571 ( 22) 3 Tage, 5 Stunden und 29 Minuten
+Loculus 1485 13363261 ( 26) 34 Tage, 15 Stunden und 6 Minuten
+Lokar 1280 1432495 ( 20) 3 Tage, 13 Stunden und 15 Minuten
+Lug 1685 1723385 ( 21) 13 Tage, 4 Stunden und 12 Minuten
+Magicolli 2060 34924394 ( 28) 42 Tage, 7 Stunden und 10 Minuten
+Magnum 1280 1438794 ( 20) 7 Tage, 18 Stunden und 8 Minuten
+Mahatma 1575 2975612 ( 22) 16 Tage, 12 Stunden und 19 Minuten
+Majere 1215 890832 ( 20) 5 Tage, 19 Stunden und 17 Minuten
+Mars 2060 14613389 ( 26) 46 Tage, 4 Stunden und 59 Minuten
+Maru 1400 1503098 ( 21) 7 Tage, 15 Stunden und 25 Minuten
+Maxin 1365 1120899 ( 20) 17 Tage, 3 Stunden und 54 Minuten
+Mellorn 1290 1066484 ( 20) 18 Tage, 8 Stunden und 9 Minuten
+Meriad 1305 1497000 ( 20) 7 Tage, 17 Stunden und 51 Minuten
+Mesirii 1585 6124525 ( 24) 25 Tage, 3 Stunden und 47 Minuten
+Mieze 1275 2122969 ( 22) 29 Tage, 0 Stunden und 30 Minuten
+Mimo 1195 1127414 ( 20) 15 Tage, 11 Stunden und 25 Minuten
+Minni 1985 13946604 ( 26) 27 Tage, 4 Stunden und 35 Minuten
+Misselli 915 2638912 ( 22) 10 Tage, 23 Stunden und 8 Minuten
+Mith 1285 1202199 ( 21) 6 Tage, 12 Stunden und 4 Minuten
+Mogli 1075 1836066 ( 21) 10 Tage, 13 Stunden und 52 Minuten
+Morgon 1835 10402622 ( 25) 27 Tage, 6 Stunden und 19 Minuten
+Mosh 1420 2479954 ( 22) 16 Tage, 9 Stunden und 21 Minuten
+Mucks 1310 3538464 ( 23) 13 Tage, 22 Stunden und 53 Minuten
+Mumpels 1275 1190902 ( 20) 9 Tage, 10 Stunden und 16 Minuten
+Nature 1490 1632154 ( 21) 6 Tage, 10 Stunden und 49 Minuten
+Nial 1330 573524 ( 20) 8 Tage, 22 Stunden und 38 Minuten
+Nixi 1695 3395231 ( 24) 58 Tage, 10 Stunden und 25 Minuten
+Nixihou 1965 9455954 ( 25) 56 Tage, 8 Stunden und 55 Minuten
+Nok 1595 1322048 ( 20) 1 Tag , 1 Stunde und 50 Minuten
+Norweger 1555 6057459 ( 25) 32 Tage, 11 Stunden und 32 Minuten
+Nostradamus 1800 93067790 ( 31) 55 Tage, 5 Stunden und 11 Minuten
+Nullneuner 1360 5220894 ( 24) 13 Tage, 7 Stunden und 38 Minuten
+Orktoeter 1330 20274027 ( 27) 42 Tage, 11 Stunden und 31 Minuten
+Pantoffel 1625 9247568 ( 25) 27 Tage, 5 Stunden und 11 Minuten
+Penelope 1450 1696656 ( 21) 42 Tage, 12 Stunden und 59 Minuten
+Perle 1495 1549393 ( 21) 20 Tage, 20 Stunden und 12 Minuten
+Phobos 1685 1963639 ( 21) 4 Tage, 15 Stunden und 23 Minuten
+Phygos 1420 3423806 ( 23) 31 Tage, 9 Stunden und 27 Minuten
+Piff 1300 3118489 ( 22) 5 Tage, 10 Stunden und 30 Minuten
+Pippin 1415 5490342 ( 24) 19 Tage, 7 Stunden und 37 Minuten
+Plock 1500 3008084 ( 22) 21 Tage, 10 Stunden und 15 Minuten
+Pra 1190 3849602 ( 23) 33 Tage, 1 Stunde und 49 Minuten
+Priamos 1270 3415166 ( 23) 13 Tage, 1 Stunde und 56 Minuten
+Puck 1270 1353491 ( 20) 1 Tag , 0 Stunden und 44 Minuten
+Quengistu 1160 2480429 ( 22) 28 Tage, 19 Stunden und 35 Minuten
+Quillian 1330 13159680 ( 26) 56 Tage, 8 Stunden und 33 Minuten
+Rafael 2015 3556498 ( 23) 49 Tage, 10 Stunden und 13 Minuten
+Raiba 1325 1032368 ( 20) 18 Tage, 3 Stunden und 30 Minuten
+Ratz 1385 1594601 ( 21) 44 Tage, 19 Stunden und 52 Minuten
+Ray 1690 16533169 ( 27) 36 Tage, 18 Stunden und 26 Minuten
+Reinelde 1620 11760476 ( 26) 27 Tage, 2 Stunden und 4 Minuten
+Rexon 1395 3286410 ( 23) 14 Tage, 15 Stunden und 2 Minuten
+Roadrunner 1660 9025017 ( 25) 55 Tage, 17 Stunden und 21 Minuten
+Rosa 1855 4397281 ( 24) 6 Tage, 10 Stunden und 38 Minuten
+Rudiratter 2060 41244745 ( 29) 37 Tage, 19 Stunden und 14 Minuten
+Ryne 2060 193376368 ( 35) 91 Tage, 16 Stunden und 57 Minuten
+Sac 1325 1081674 ( 20) 3 Tage, 16 Stunden und 26 Minuten
+Schelm 1460 461247 ( 22) 8 Tage, 8 Stunden und 20 Minuten
+Schlawiner 1365 534648 ( 21) 29 Tage, 12 Stunden und 48 Minuten
+Scotty 1215 2245107 ( 22) 12 Tage, 3 Stunden und 29 Minuten
+Selbstmord 1260 1281392 ( 20) 2 Tage, 10 Stunden und 15 Minuten
+Semira 1710 8346293 ( 25) 38 Tage, 10 Stunden und 43 Minuten
+Siabat 1340 1342168 ( 21) 15 Tage, 20 Stunden und 21 Minuten
+Siborit 1400 1120931 ( 20) 15 Tage, 3 Stunden und 25 Minuten
+Skipper 1575 33526629 ( 28) 46 Tage, 4 Stunden und 32 Minuten
+Skywalker 1455 2760483 ( 22) 12 Tage, 5 Stunden und 19 Minuten
+Slash 1720 6218999 ( 24) 37 Tage, 12 Stunden und 42 Minuten
+Slyfox 1780 29213700 ( 28) 63 Tage, 22 Stunden und 22 Minuten
+Smaug 1185 2650121 ( 22) 18 Tage, 23 Stunden und 56 Minuten
+Smiley 1375 10534850 ( 25) 22 Tage, 10 Stunden und 45 Minuten
+Snooker 1520 30568048 ( 28) 21 Tage, 1 Stunde und 59 Minuten
+Snuggle 1525 9048493 ( 25) 31 Tage, 8 Stunden und 50 Minuten
+Sorsha 1440 1386048 ( 20) 20 Tage, 0 Stunden und 56 Minuten
+Speedy 1555 16193978 ( 27) 20 Tage, 18 Stunden und 41 Minuten
+Stahldorn 1735 54765411 ( 29) 60 Tage, 22 Stunden und 41 Minuten
+Steve 1945 6068441 ( 24) 66 Tage, 5 Stunden und 34 Minuten
+Sushi 1775 1608281 ( 21) 17 Tage, 16 Stunden und 17 Minuten
+Symbiont 1320 3504834 ( 23) 13 Tage, 8 Stunden und 54 Minuten
+Sysop 1335 1719336 ( 21) 16 Tage, 11 Stunden und 40 Minuten
+Taz 1515 765173 ( 22) 33 Tage, 3 Stunden und 51 Minuten
+Telka 1550 1357476 ( 20) 14 Tage, 19 Stunden und 14 Minuten
+Terran 1440 1094264 ( 20) 12 Tage, 1 Stunde und 17 Minuten
+Todesengel 1535 1738662 ( 21) 3 Tage, 7 Stunden und 7 Minuten
+Tommy 1605 7146906 ( 25) 35 Tage, 12 Stunden und 57 Minuten
+Torwall 1330 6124052 ( 24) 28 Tage, 11 Stunden und 46 Minuten
+Toss 1875 7830548 ( 26) 54 Tage, 4 Stunden und 22 Minuten
+Twiggy 1660 9691344 ( 25) 35 Tage, 17 Stunden und 22 Minuten
+Tyrion 1595 19220397 ( 27) 35 Tage, 16 Stunden und 51 Minuten
+Tzuiop 1165 14746734 ( 26) 80 Tage, 18 Stunden und 52 Minuten
+Urza 1485 12589713 ( 26) 29 Tage, 12 Stunden und 56 Minuten
+Vanir 2060 2933143 ( 22) 35 Tage, 4 Stunden und 11 Minuten
+Vanja 1615 16423350 ( 26) 21 Tage, 7 Stunden und 4 Minuten
+Vergon 1305 1071535 ( 20) 1 Tag , 15 Stunden und 4 Minuten
+Verwirrung 1925 4455245 ( 23) 14 Tage, 20 Stunden und 52 Minuten
+Vrumfondel 1255 447438 ( 20) 18 Tage, 16 Stunden und 48 Minuten
+Wahn 2060 3312832 ( 23) 16 Tage, 1 Stunde und 47 Minuten
+Warlord 1275 630751 ( 21) 30 Tage, 3 Stunden und 54 Minuten
+Willow 1905 28742636 ( 28) 54 Tage, 10 Stunden und 25 Minuten
+Woelkchen 1370 7929828 ( 24) 40 Tage, 3 Stunden und 11 Minuten
+Wolfendart 1415 1575308 ( 21) 11 Tage, 8 Stunden und 46 Minuten
+Xanadu 1525 1784732 ( 21) 37 Tage, 3 Stunden und 28 Minuten
+Xera 1500 1765739 ( 21) 18 Tage, 6 Stunden und 24 Minuten
+Yak 1200 1012278 ( 20) 16 Tage, 17 Stunden und 39 Minuten
+Yasmin 1335 1229340 ( 21) 9 Tage, 2 Stunden und 38 Minuten
+Yeti 1420 6010840 ( 25) 48 Tage, 14 Stunden und 25 Minuten
+Yety 1260 2387612 ( 22) 17 Tage, 23 Stunden und 55 Minuten
+Zephyr 2060 29257249 ( 28) 67 Tage, 4 Stunden und 5 Minuten
+Zorro 2060 5644687 ( 24) 33 Tage, 10 Stunden und 52 Minuten
+Zwirch 1665 9818247 ( 25) 15 Tage, 23 Stunden und 31 Minuten
+
diff --git a/d/seher/haeuser/special/special/faq/2 b/d/seher/haeuser/special/special/faq/2
new file mode 100644
index 0000000..e4b78bd
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/2
@@ -0,0 +1,18 @@
+2. SEHERQUEST
+
+Eine recht schoene quest nur fuer Seher hat Troy im Fruehjahr 1995
+geschrieben, allerdings wurde sie erst 4 Monate spaeter angeschlossen,
+nachdem Boing eine Menge Bugs gefixt hatte. Wie auch immer: Eine lohnende
+quest, mit Sicherheit die schoenste die Troy hier geschrieben hat, und
+ausnahmsweise ist sie sigar logisch und die Stimmung vor Ort nicht schlecht.
+Also unbedingt spielen, nicht zuletzt, weil die Belohnung dafuer wirlich
+gelungen ist, besser: die Belohnungen! Denn a) erhaelt man eine
+Kristallkugel, mit der man Spieler fuer einen Magiepunkt finden kann, und b)
+erhaelt man das R-Emote, mit dem man sein Emote, das man fuer die Amaryllis-
+Quest erhalten hat, auch auf Spieler ausserhalb des Raumes in dem man sich
+befindet, anwenden kann (vgl. hierzu auch Kap. 6: Magische Kugel).
+
+Viel Spass beim Questen !!!
+(aber erst hierbleiben und Faq fertiglesen ;) - und der Ballpark lohnt
+uebrigens auch mal einen kleinen Blick ;))
+
diff --git a/d/seher/haeuser/special/special/faq/3 b/d/seher/haeuser/special/special/faq/3
new file mode 100644
index 0000000..5aea5d2
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/3
@@ -0,0 +1,23 @@
+
+3. FLUCHTRICHTUNG
+
+Etwas unscheinbar, aber in meinen Augen ist dies immer noch der wertvollste
+Befehl, den man als Seher neu erhaelt: Fluchtrichtung.
+
+Ab sofort kannst Du den Befehl 'Fluchtrichtung (Richtung)' anwenden.
+Sollte dieser noch nicht aktiviert sein, musst du einmal Ende machen.
+Danach kannst Du selbst bestimmen, in welche Richtung Du fliehst,
+wenn die Angst Dich mal ueberkommen sollte .....
+Aber Achtung: Der Befehl funktioniert mit einer Warscheinlichkeit von
+80 Prozent; fuer jeden Level ueber 20 erhoeht sich die Warscheinlichkeit
+dann um weitere zwei Prozent... Tip: Fluchtrichtung >Ende< funktioniert
+auch, ebenso wie: Fluchtrichtung >teile Boing mit Du, ich sterbe gleich :(<
+Man muss halt die Prioritaeten richtig setzen ;)).
+
+Warum dieser Befehl in meinen Augen besonders wichtig ist ? Nun, er befreit
+Spieler mit sehr hoher Warscheinlichkeit von dem Risiko, durch einen Lag zu
+sterben, wenn die Flucht im entscheidenden Moment in die falsche Richtung zu
+gehen droht. Man muss sie vorher nur richtig gesetzt haben. Allerdings, ein
+kleines Risiko bleibt... denn erst ab Level 30 klappt die Fluchtrichtung zu
+100%, also wachbleiben ;).
+
diff --git a/d/seher/haeuser/special/special/faq/4 b/d/seher/haeuser/special/special/faq/4
new file mode 100644
index 0000000..6b24118
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/4
@@ -0,0 +1,34 @@
+4. SEHERLEVEL
+A propos Levels- zwar ist man nun Seher, aber dennoch kann man
+auch weiterhin seine Stufen erhoehen - allerdings mit etwas mehr
+Aufwand als frueher :(( - die Levels und ihre EP-Anforderungen:
+
+
+Stufe Erfahrung Stufe Erfahrung Stufe Erfahrung
+========================================================================
+21 1500000 26 11000000 31 80000000
+22 2250000 27 17000000 32 100000000
+23 3375000 28 25000000 33 125000000
+24 5062500 29 40000000 34 150000000
+25 7600000 30 60000000 35 175000000
+ 36 200000000
+
+Die Bedeutung der Levels ist insofern hoch, als dass die Erfolgs-
+chance der Zaubersprueche in den neuen Gilden von dem Level des
+Spielers abhaengig ist. So ist es grundsaetzlich nur moeglich, die maximale
+Erfolgswarscheinlichkeit eines Zauberspruches erst dann zu erreichen, wenn
+man Seherlevel 30 erreicht hat. Berechnet wird das ganze wie folgt:
+Bei Level 20 betraegt die Erfolgswarscheinlichkeit 80 Prozent. Pro Level
+ueber 20 steigt die Warscheinlichkeit dann um weitere 2 Prozent, erreicht
+also bei Level 30 100 Prozent.
+Dies fuehrt im Ergebnis dazu, dass ein Zauberspruch, den man an sich zu 90%
+beherrscht, in Level 25 nur mit einer Warscheinlichkeit von 81 Prozent
+gelingt (90% Beherrschen des Spruches * 90% Warscheinlichkeit aus Level 25).
+Allerdings gilt diese Formel so global nur fuer Standard-Zaubersprueche (ins-
+besondere die in der Abenteurergilde); die Magier der einzelnen Gilden
+koennen durch den Schwierigkeitsgrad eines Zauberspruches bestimmen, ob
+dieser mit hoeherer oder niedrigerer Warscheinlichkeit gelingt, als durch die
+oben angefuehrte Rechnung vorgesehen. In der Karategilde ist es sogar so
+geregelt, dass der Level an sich fuer die Erfolgswarscheinlichkeit eines
+Spruches unerheblich ist.
+
diff --git a/d/seher/haeuser/special/special/faq/5 b/d/seher/haeuser/special/special/faq/5
new file mode 100644
index 0000000..27f31a6
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/5
@@ -0,0 +1,30 @@
+5. Kommunikation
+
+Als Seher stehen Dir neue Mittel der Kommunikation zur Verfuegung, mittels
+derer Du Nachrichten an andere Spieler senden kannst:
+
+I. MAIL
+Ab sofort steht Dir der kostenlose Kurierdienst der MG-Post zur
+Verfuegung - durch Eingabe von 'mail' kannst du von ueberall Post
+verschicken und empfangen. Dies setzt aber voraus, dass Du eine Zeitung
+bei Dir traegst, da das mail eine Zusatzfunktion der MPA ist.
+
+II. MPA
+In der Zeitung steht Dir nun die neue Rubrik 'seher.entwicklung' zur
+Verfuegung, in der Du Deine Vorschlaege zur Verbesserung des
+Sehertums einbringen kannst.
+
+III. Kanaele
+Zur direkten Kommunikation mit den anderen Sehern steht Dir nun auch ein
+neuer Kanal zur Verfuegung. Er wird mit ' -h ' angesprochen
+(nein, nicht mit S wie Seher, dann knallt die Meldung zwar auch ueber
+den Seherkanal, aber ebenfalls ueber Sport und Snoop ;)).
+
+IV. Fernschreiber
+Mit dem Fernschreiber aus dem Seherladen kannst Du ganze Nachrichtenbloecke
+an andere Spieler senden. Dies ist haeufig nuetzlich, wenn man laengere Texte
+an einen anderen Spieler senden will, waehrend man z.B. mit diesem zusammen
+eine neue Region oder ein Quest erforscht. Der Einsatz kostet 15 MP pro
+Spieler, an den die Nachricht gesendet wird, man kann auch an mehrere Spieler
+gleichzeitig die Meldung ausgeben lassen.
+
diff --git a/d/seher/haeuser/special/special/faq/6 b/d/seher/haeuser/special/special/faq/6
new file mode 100644
index 0000000..0eb9dfc
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/6
@@ -0,0 +1,15 @@
+6. MAGISCHE KUGEL
+
+Im Haus der Hexe am Friedhof und in Zwackelmanns Schloss findest
+Du eine Kugel, die Du mitnehmen kannst - mit ihr kannst du durch den Befehl
+'finde (Spielername)' jeden eingeloggten Spieler lokalisieren - ein Einsatz
+kostet jeweils 9 MP.
+
+Mit der Einfuehrung des Seherquests von Troy erhaelt man als Questbelohnung
+eine - der Name des Quests laesst es Vermuten - Kristallkugel, die dieselbe
+Funktion wie die Seherkugel erfuellt. Allerdings kostet diese pro Einsatz nur
+1 MP. Dafuer erhaelt allerdings der beobachtete Spieler die Meldung 'Jemand
+beschwoert Dein Bild herauf.', was auf dauer etwas aufdringlich wird, da der
+Betroffene ja nicht weiss, wer ihn da sucht. Ich persoenlich halte den
+Einsatz der 'normalen' Seherkugel fuer diskreter, insbesondere, da sich ihre
+Kosten ja in einem vertretbaren Rahmen bewegen.
diff --git a/d/seher/haeuser/special/special/faq/7 b/d/seher/haeuser/special/special/faq/7
new file mode 100644
index 0000000..33ed2ca
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/7
@@ -0,0 +1,169 @@
+7. SEHERLADEN
+Auf Svolvaer findest Du einen Laden, der spezielle items nur fuer
+Seher anbietet. Interessant ist hier der Bumerang, dazu noch die
+Partytroete - der Rest ist mehr oder weniger brauchbares Zeugs - abraten
+wuerde ich von dem Kauf der ZT-Wuenschelrute, die zwar relativ
+verlaesslich arbeitet, allerdings pro Einsatz 45 MP kostet, und sich damit
+nur lohnt, wenn man in einem konkreten Raum einen ZT vermutet.
+Ansonsten ist natuerlich der Kauf des von BOING handgenaehten
+Kissens ein MUSS!
+
+Eine kurze Beschreibung saemtlicher Seherladenartikel findet sich hier im
+Anschluss; an dieser Stelle einen herzlichen Dank an Cuchullin, der diese
+Liste erstellt und sich damit sehr viel Muehe gegeben hat.
+
+Fuer das Angebot im Seherladen ist Loco zustendig, der das bisher etwas
+spaerliche Angebot gerne erweitern moechte, und daher fuer Ideen
+immer aufgeschlossen ist - daher schreibe ihm ruhig ein mail, wenn Du
+eine Idee hast, was dort zukuenftig angeboten werden koennte.
+
+Angebotene Artikel im Seherladen (Text von Cuchullin:)
+
+1: 15 Eine Fackel.
+ Eine ganz normale Fackel. Man kann sie anzuenden und
+ wieder loeschen.
+
+ 2: 10 Ein von Boing handgenaehtes Kissen
+ Man kann es anderen sehr gut nachwerfen ;)
+
+ 3: 1800 Ein Wecker (Luxusausgabe).
+ Zeigt die Uhrzeit an, dient als Stoppuhr und als Timer.
+ Autoload.
+
+ 4: 15 Ein Lolli.
+ Ein Lolli, so wie ihn das Partymonster gerne verteilt.
+
+ 5: 240 Ein T-Shirt.
+ Ruestungsgattung Umhang und denkbar schlecht... aber als
+ Seher kann man es mit einem Text versehen und man sieht's
+ im Extralook... Nette Sache in jedem Fall.
+
+ 6: 8 Ein Wuerfel.
+ "Du wuerfelst eine 6." Ein ganz normaler Wuerfel.
+
+ 7: 18 Ein Foermchen.
+ Ein rotes Foermchen in der Form eines Herzens.
+ Mehr allerdings nicht.
+
+ 8: 5400 Ein Bumerang.
+ Eigentlich muss man dazu nicht viel sagen, eine wirklich
+ - fast zu - gute Waffe. Wurde allerdings kuerzlich etwas
+ abgewertet, ist jedoch immer noch wertvolle Hifle im Kampf.
+ Man kann (von den insgesamt vieren pro Reset nur einen Bume-
+ rang kaufen. Dies wurde gegen die Hamsterkaeufe nach einem
+ Shutdown eingefuehrt (Es gibt Seher, die kaempfen mit vier
+ Bumerangs und haben noch drei als Ersatz im Beutel...). Nach
+ einem reboot/crash allerdings erhaelt jeder Seher mindestens
+ einen Bumerang.
+
+ 9: 60 Ein tragbarer Postkartendrucker.
+ Man kann damit sechs Postkarten erzeugen, mit Text versehen
+ und verschicken. Netter Gag.
+
+10: 1800 Die Troete des Partymonsters.
+ Ein Muss fuer Partyfans! Das Utensil zu Partymonsterrufen.
+
+11: 9999 Ein Zauberstab.
+ A la Hilbert. Ist durch den Licht-Zauberspruch relativ
+ unwichtig geworden. Ausserdem ist der gekaufte Stab nicht
+ crashfest.
+
+12: 499 Ein Planeditor.
+ Wer sein Projekt oder seinen Plan editieren will, braucht
+ einen Planeditor.
+
+13: 1200 Ein Paar Siebenmeilenstiefel.
+ Eine Erleichterung fuer diejenigen, die nicht ueber irgend-
+ welche Frontend-Programme verfuegen. Man laeuft einen Weg
+ immer bis zur naechsten Abzweigung.
+
+14: 500 Magischer Beutel.
+ Ein nettes 'Tool', um andere zu aergern. Wer hat nicht
+ schonmal vor einer Schattenruestung gestanden, und sich
+ gefragt, warum er sie nicht nehmen oder anziehen kann.
+ Autoload.
+
+15: 11111 Eine Wuenschelrute.
+ Zum Auffinden von Zaubertraenken. Eignet sich nur bei
+ konkretem Verdacht, da sie nur anzeigt, ob sich ein ZT
+ im Raum befindet.
+
+16: 3000 Ein Testroehrchen (gebrauchsfertig).
+ <hick>! Wie besoffen ist man eigentlich? Wiederverwendbar.
+
+17: 3000 Ein Schiebepuzzle.
+ Wer aergert sich nicht, wenn das Freundschaftsband aus
+ irgendwelchen Gruenden ploetzlich ganz oben im Inventory
+ steht? Hiermit kann das Inv nach Belieben umsortiert werden.
+ Autoload.
+
+18: 500 Ein Dudelsack.
+ Das komfortabelste Musikinstrument MorgenGrauens.
+ Man kann sogar die vorgefertigten Stuecke genau
+ ansprechen...
+
+19: 499 Ein handgearbeiteter Mini-Flammenwerfer (tm).
+ 'flame' Ein netter Gag.
+
+20: 199 Eine bunte Spritzpistole.
+ 'splash' Siehe Flammenwerfer.
+
+21: 900 Ein Paar feste Schuhe.
+ Das 'rtrete'! Leider werden (noch) keine Adjektive
+ akzeptiert.
+
+22: 4500 Eine Stimmgabel.
+ Ideal fuer die, die Hippe nicht moegen.
+ Ist etwas in der Richtung 'Anti-Hippe-Button'.
+
+23: 298 Ein Strandball.
+ Kann man anderen Leuten zuwerfen. Ist nicht so lustig wie
+ Boings handgenaehtes Kissen, dafuer aber auch nicht so
+ provokant.
+
+24: 798 Eine magische Bierflasche.
+ Fuer Biertrinker ein Muss! Diejenigen, die 'ihr Bier' nicht
+ auf der Liste finden, koennen ja dem entsprechenden Magier
+ ne Mail schreiben. Achja - Syntax: wuensche <sorte>
+
+25: 150 Ein Messer Marke Samthandschuh.
+ Wer mit dieser Waffe gegen einen Schmetterling kaempft, darf
+ getrost ideln, denn sie haelt, was sie verspricht.
+
+26: 3000 Ein Lag-O-Meter.
+ Ist interessant, aber leider nicht autoload. Wer wollte
+ nicht schon immer wissen, wieviel Lag man denn nun wirklich
+ hat...
+
+27: 895 Eine Diddl-Knuddel-Maus.
+ Fuer die, die sich in Moron nicht auskennen oder keine Lust
+ haben, sich an entsprechender Stelle anzustellen.
+
+28: 150 Ein 4Gewinnt-Spiel.
+ SSP leergeraeumt ? Kein Freund eingeloggt ? Ein kleines
+Spiel
+ kann die Langeweile vertreiben.
+
+29: 300 Eine Roentgenbrille.
+ Ermoeglicht tiefe und sehr interessante Blicke unter diverse
+ Schottenroecke. just for fun.
+
+30: 5052 Ein kleiner grauer Kasten.
+ Eines der besten Sehertools. Man kann mit ihm Nachrichten in
+ Form ganzer Textbloecke an andere Spieler senden. Autoload.
+
+31: 3003 Ein Ikonograph.
+ Fuer kleine Schnappschuesse zwischendurch. Haelt das P_Long
+ des betrachteten Objektes fest.
+
+
+(4/95, Cuchullin)
+
+
+Have Fun
+
+Cuchullin ()
+
+
+
+
diff --git a/d/seher/haeuser/special/special/faq/8 b/d/seher/haeuser/special/special/faq/8
new file mode 100644
index 0000000..3eceabc
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/8
@@ -0,0 +1,43 @@
+8. DESIGNER-SEHER
+
+Nun, vielleicht ist dieser Titel auch ein wenig uebertrieben. Aber als Seher
+kannst Du Deine gesamte Erscheinung im MUD selbst gestalten:
+
+Nun, Designertypen glaenzen durch ihr Aeusseres, also fangen wir mal beim
+Aussehen an: Was die Spieler sehen, wenn sie Dich untersuchen, kannst Du mit
+dem Befehl 'extralook' bestimmen. Die dort eingegebene Beschreibung wird der
+Auflistung dessen, was Du bei Dir traegst, vorangestellt.
+
+Zur Erscheinung gehoert auch das Auftreten, also designen wir mal ein bischen
+an Deinen messages herum, die erscheinen, wenn Du einen Raum betrittst oder
+verlaesst. Dies kannst Du mit setmin (text) bzw. setmout (text) setzen. Und
+wenn Du moechtest, kannst Du mit setmmout bzw. setmmin die Meldungen setzen,
+die Erscheinen, wenn Du einen Ort mittels eines teleports verlaesst/
+betrittst.
+
+Doch auch Designerseher leben unter dem Joch des Armageddon, und sind daher
+manchmal Waffen- und Ruestungslos. Wer es aber nicht ertragen kann, in diesen
+bitteren Stunden immer die Meldung 'greifft mit blossen Haenden an' zu sehen,
+der kann sich mittels des Befehls 'sethands (text)' eine martialischere (oder
+auch zaertlichere, je nach Geschmack ;)) Kampfmeldung fuer seine Haende
+setzen.
+
+Nun, son richtiger Schiggi-Miggi Seher hat natuerlich auch einen total
+laessigen Namen, nicht so was oedes wie 'Wurst, die Seherin'. Und deshalb
+koennte sich Wurst einen eigenen Namen geben, mit dem Befehl 'titel (text)'.
+Dann hiesse sie hinterher Beispielsweise 'Wurst iss ne Wurst'. Und wem das
+noch nicht laessig genug ist, der setzt sich mit 'presay (text)' auch noch
+einen Namensvorsatz. Beispiel: 'Mach ne Wurst, iss ne Wurst'. Wenngleich das
+vielleicht doch nicht SO cool ist. Geschmackssache halt ;).
+
+Ach ja, und wenn man dann bei all der Rumdesignerei vergessen haben sollte,
+was man ueberhaupt eingegeben hat, so erhaelt man mit dem Befehl 'review'
+einen Ueberblick ueber die meisten Einstellungen.
+
+Eine Anmerkung noch: Der Toeter (HAIL, HAIL ALL!) hat kuerzlich eine kleine
+Erweiterung in den Befehl setmout eingebaut: Nunmehr ist es moeglich, den
+Text 'nach (Richtung)' nicht mehr nur am Ende, sondern irgendwo im Text
+erscheinen zu lassen; dann muss im Text der out-message ein # erscheinen, die
+dann durch 'nach (Richtung)' ersetzt wird. Unterdruecken kannst Du die
+Richtungsangabe allerdings nicht, wenn Du die # weglaesst, wird diese
+Angabe einfach hinten angehaengt..
diff --git a/d/seher/haeuser/special/special/faq/9 b/d/seher/haeuser/special/special/faq/9
new file mode 100644
index 0000000..24b08d1
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/9
@@ -0,0 +1,9 @@
+
+9. FEHLERMELDUNG
+
+Ein nicht besonders wichtiger, aber in seinen Auswirkungen haeufig
+angetroffener Befehl: Fehlermeldung. Wenn Dir das ewige 'Wie bitte ?' langsam
+zu eintoenig wird, so kannst Du mit 'Fehlermeldung (Text)' einen neuen Text
+fuer Deine Fehlermeldung setzen - uebrigens genauso wie fuer die Uhrmeldung,
+was allerdings schon als Spieler meoglich ist, was jedoch scheinbar nur recht
+wenige Spieler wissen.
diff --git a/d/seher/haeuser/special/special/faq/anleitung b/d/seher/haeuser/special/special/faq/anleitung
new file mode 100644
index 0000000..cba61a7
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/anleitung
@@ -0,0 +1,219 @@
+
+ANLEITUNG MAGISCHER BEUTEL
+
+Stellen wir uns vor, Wurst, die Seherin, wollte ein Blutsaugerschwert
+herstellen, mit dem sie gierige kleine Anfenger aergern will:
+
+/ kommentare stehen immer hinter dem //...
+/ los gehts: 'erschaffe' eingeben, dann ist man im Beuteleditor, der dem
+/ bekannten editor von MPA und mail gleicht.
+/ Wurst gibt zunaechst eine ID fuer das Schwert ein:
+
+Bitte ein Schluesselwort eingeben:
+]id
+]Bitte eine neue ID eingeben:
+]schwert
+
+/ nun moechte Wurst noch eine weitere ID eingeben:
+
+Bitte ein Schluesselwort eingeben, ~h fuer Hilfe.
+]id
+
+/ nun kommen als Ausgabe auch die bisher eingegebenen IDs, in unserem Fall:
+
+Bisherige IDs:
+0 schwert
+Bitte eine neue ID eingeben
+]blutsaugerschwert
+
+/ Wurst haette hier uebrigens keine ID eingeben muessen. haette sie nur id,
+/ und danach enter eingegeben, haette dies dazu gedient, die bisher
+/ eingegebenen IDs anzuschauen.
+/ Weiter gehts mit der Langbeschreibung (das was man sieht, wenn man
+/ untersuche (id) eingibt):
+
+Bitte ein Schluesselwort eingeben:
+]lang
+Bitte die ausfuehrliche Beschreibung angeben. Beenden mit **
+]Dies ist das Schwert eines einst maechtigen Vampirs. Nun ist es
+]jedoch so wertlos geworden, dass sich jeder Seher es mit seinem
+]magischen Beutel klonen kann.
+]Es hat einen goldenen Schaft.
+]**
+
+/ Wurst moechte, dass die Spieler eine Erklaerung dafuer kriegen, dass das
+/ Schwert automatisch gezueckt ist... kein Problem, dafuer beschreibt sie den
+/ Schaft des Schwertes genauer:
+
+Bitte ein Schluesselwort eingeben:
+]detail
+Bitte den Detailnamen eingeben:
+schaft
+]Nun bitte eine Beschreibung fuer: " schaft " eingeben.
+]Dieser Schaft ist von purer Magie. Wer das Schwert besitzt, zueckt es
+]automatisch.
+]**
+Bitte ein Schluesselwort eingeben, ~h fuer Hilfe.
+]
+
+/ Das wars, schon besitzt das Schwert einen Schaft.
+/ Ebenso muss noch eine Kurzbeschreibung angegeben werden:
+
+Bitte ein Schluesselwort eingeben, ~h fuer Hilfe.
+]kurz
+Bitte die Kurzbeschreibung eingeben
+]Ein Blutsaugerschwert (gezueckt)
+
+/ Ueberrascht ? Die Kurzbeschreibung muss genau so eingegeben werden, wie sie
+/ der Spieler in seinem inventory sieht. Damit diese Beschreibung aber nicht
+/ erscheint, wenn das Schwert an das 'Opfer' uebergeben wird, muss ein Name
+/ eingegeben werden:
+
+Bitte ein Schluesselwort eingeben, ~h fuer Hilfe.
+]name
+Bitte den Namen eingeben
+]Blutsaugerschwert
+
+/ Ergo: Wird kein Name speziell eingegeben, wird erscheint, wenn das Objekt
+/ weitergegeben oder fallengelassen wird, die kurzbeschreibung dargestellt.
+/ Um die zu vermeiden, gibt es den Befehl 'name'.
+/ Allerdings wuerde beim Uebergeben des Schwertes jetzt erscheinen: 'Wurst
+/ gibt Dir den Schwert', da noch kein Geschlecht gesetzt wurde, und default-
+/ geschlecht maennlich ist. Daher folgt nun:
+
+Bitte ein Schluesselwort eingeben, ~h fuer Hilfe.
+]art
+Bitte die Kennziffer fuer das Geschlecht eingeben
+]maennlich: 1 weiblich: 2 saechlich: 0
+]0
+
+/ Nun ist mit saechlich auch das richtige Geschlecht gesetzt.
+/ Nun, so ein Schwert soll auch etwas wiegen, also gibt Wurst noch ein
+/ Gewicht mit an:
+Bitte ein Schluesselwort eingeben, ~h fuer Hilfe.
+]gewicht
+Bitte das Gewicht in Gramm eingeben (Minimum 100)
+]5000
+
+/ nun moechte sich Wurst noch vergewissern, dass ihr Plan gut vorbereitet
+/ ist. Daher laesst sie sich mit '~r' nochmal einen Ueberblick ueber das
+/ Schwert geben:
+
+Bitte ein Schluesselwort eingeben:
+]~r
+IDs:
+0 blutsaugerschwert
+1 schwert
+Kurzbeschreibung:
+Ein Blutsaugerschwert (gezueckt)
+Name:
+Blutsaugerschwert
+Gewicht: 5000 Gramm
+Geschlecht: saechlich
+Ausfuehrliche Beschreibung:
+Dies ist das Schwert eines einst maechtigen Vampirs. Nun ist es jedoch
+wertlos geworden, dass sich jeder Seher es mit seinem magischen Beutel
+klonen kann.
+Details:
+0: schaft:
+Dieser Schaft ist von purer Magie. Wer das Schwert besitzt, zueckt es
+automatisch.
+]
+
+/ Wurst ist zufrieden, und moechte nun die 'Aktion BSS fuer alle' beginnen,
+/ und benutzt den Befehl 'start', um das Schwert endgueltig zu erzeugen.
+/ Allerdings achtet sie dabei darauf, nicht im selben Raum wie ihr Opfer zu
+/ stehen, denn die Umstehenden erhalten beim Erzeugen des Objektes die
+/ Meldung:
+
+> Wurst denkt scharf nach und zieht dann etwas aus dem magischen Beutel
+
+/ Alles klar, das Objekt kann erschaffen werden:
+
+]start
+Du hast ein neues Objekt geschaffen. Es ist:
+Blutsaugerschwert
+Bitte ein Schluesselwort eingeben, ~h fuer Hilfe.
+]
+
+/ dummerweise bleibt man nach dem Erschaffen eines Objektes immer im editor
+/ des Beutels drin. Abbrechen muss man also mit '**', was zu einer etwas
+/ verwirrenden Meldung fuehrt:
+
+]Bitte ein Schluesselwort eingeben, ~h fuer Hilfe.
+]**
+Beschreibung ist abgebrochen. Die Werte wurden beibehalten.
+>
+/ Wurst haette auch ohne 'start' einzugeben den Beutel-editor verlassen
+/ koennen; sofern man dies mit '**' (und nicht mit '~q' tut kann man naemlich
+/ mit 'bearbeite' wieder in den Beutel-editor hineingehen, und uebernimmt
+/dabei die alten
+/ Werte.
+
+/ Dass die Werte beibehalten wurden, hat auch eine Auswirkung darauf, dass
+das erschaffene
+/ Objekt abgespeichert werden kann, um es spaeter nochmal zu laden. Dies
+moechte Wurst
+/ natuerlich gerne machen, da sie zu faul ist, den ganzen Kram nochmal zu
+tippen (und weil
+/ Wurst ja DIR alle Funktionen des Beutels zeigen soll;)) - ausserdem ists
+recht einfach - mit
+/ dem Befehl 'erhalte (nr.)' kann
+
+> erhalte 1
+> Das Objekt wurde auf Platz 1 abgespeichert.
+
+/ um sicherzugehen schaut Wurst nochmal mit 'speicherplaetze' nach, ob die
+Speicherung
+/ geklappt hat
+
+>speicherplaetze
+Speicherplatz 0: Nicht belegt.
+Speicherplatz 1: Ein Blutsaugerschwert (gezueckt).
+Speicherplatz 2: Nicht belegt.
+Speicherplatz 3: Nicht belegt.
+(...)
+
+/ offensichtlich hat es funktioniert, Speicherplatz 1 wurde belegt, man sieht
+die Kurzbe-
+/ schreibung des Objektes.
+
+---------
+
+/ Wochen spaeter. Wurst moechte das gespeicherte Schwert laden, um es neu zu
+erzeugen.
+/ dazu benutzt sie den Befehl 'lade (nr.)'
+
+> lade 1
+> Objekt von Speicherplatz Nr.1 wurde geladen.
+
+/ Das reicht allerdings noch nicht. Jetzt sind naemlich nur die Werte im
+Beutel geladen, aber
+/ das Objekt noch nicht erschaffen. Daher folgt zunaechst der Befehl
+bearbeite (nicht
+/ 'erschaffe', weil dieser die evtl. noch vorhandenen Werte im Beutel
+loescht!)
+
+> bearbeite
+Bitte ein Schluesselwort eingeben:
+]
+
+/ an dieser Stelle kann Wurst nun das alte Blutsaugerschwert genauso
+bearbeiten wie vorher -
+/ natuerlich kann sie die vorhandenen Daten uebernehmen, aber auch aendern
+(was durch
+/ einfaches neu eingeben geschieht). Wenn sie das Schwert nicht weiter
+bearbeiten moechte
+/ kann sie nun einfach 'start' eingeben, und den editor verlassen.
+/ So, und zu guter Letzt: Sofern Wurst das veraeppeln von Anfaengern genug
+ist, kann sie den
+/ Speicherplatz fuer das Schwert natuerlich auch freimachen, dies geschieht
+einfach durch den
+/ Befehl 'entferne (nr.)'
+
+So, das wars! Eine Menge Text fuer ein eigentlich brauchbares Sehertool, wenn
+man nur wuesste, wie es funktioniert ;))
+
+
+
+
diff --git a/d/seher/haeuser/special/special/faq/ansichten b/d/seher/haeuser/special/special/faq/ansichten
new file mode 100644
index 0000000..835ca97
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/ansichten
@@ -0,0 +1,4 @@
+Folgende Raeume sind bereits auf der Seherinsel mit langbeschreibungen
+versehen:
+(Koordinaten vert./horiz., wie in der Kurzbeschreibung auf der Insel)
+1,1: Wolpie-Raum :(
diff --git a/d/seher/haeuser/special/special/faq/faq.o b/d/seher/haeuser/special/special/faq/faq.o
new file mode 100644
index 0000000..7fc9efb
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/faq.o
@@ -0,0 +1,3 @@
+#0:0
+properties ([:2])
+synonym (["level":"4","mail":"5","finger":"11","quests":"2","echo":"12","fehlermeldung":"9","seher":"18","remote":"12","setmin":"8","titel":"8","fluchtrichtung":"3","zeitung":"9","haus":"14","sehernamen":"18","kugel":"6","pegasus":"2","portale":"1","quest":"2","looks":"8","namen":"18","beutel":"13","laden":"7","16":"karte","adressenverzeichnis":"16","neuigkeiten":"0","faq":"inhalt","magische kugel":"6","haeuser":"14","adressen":"16","seherladen":"7","roehrchen":"10","kanaele":"9","magische":"6","seherquests":"2","spielplatz":"15","levels":"4","seherquest":"2","paralleldimension":"10","19":"karte","r-emote":"12","seherlevel":"4","seherhaeuser":"14","anmerkung":"15","finger-befehl":"11","seherlevels":"4","uebersichtskarte":"karte","seherportale":"1","designer":"8","seherspielplatz":"15","seherhaus":"14","seherfaq":"inhalt","designer-seher":"8","design":"8","kommunikation":"5","transportmoeglichkeiten":"1",])
diff --git a/d/seher/haeuser/special/special/faq/files b/d/seher/haeuser/special/special/faq/files
new file mode 100644
index 0000000..9113b7b
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/files
@@ -0,0 +1,28 @@
+
+files seherfaq: alle +Path = /../morgeng/seher/faq/faq2-0
+
+
+
+0. Neuigkeiten: news.txt
+
+1. Transportmoeglichkeiten: inhalt.txt
+
+2. Seherquests: quest.txt
+3. Fluchtrichtung: flucht.txt
+4. seherlevel: level.txt
+5: Kommunikation: kommun.txt
+6: magische kugel: kugel.txt
+7: Seherladen: sladen.txt
+8: designer-seher: looks.txt
+9: fehlermeldung: errmes.txt
+10: paralleldimension.txt: para.txt
+11: finger-befehl: finger.txt
+12: echo, r-emote: echo.txt
+13: magischer beutel: beutel.txt
+anleitung magischer beutel: anleit.txt
+14: seherhaeuser: haeuser.txt
+15: Seherspielplatz: splatz.txt
+16: uebersichtskarte spielplatz: smap.txt
+18: alle seher im mg: salle.txt
+19 zusammenfassung & nachwort: zusamm.txt
+files: files.txt
diff --git a/d/seher/haeuser/special/special/faq/inhalt b/d/seher/haeuser/special/special/faq/inhalt
new file mode 100644
index 0000000..9c105de
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/inhalt
@@ -0,0 +1,26 @@
+
+Inhalt der SeherFAQ 2.0:
+
+ 0. Neuigkeiten 10. Paralleldimension
+ 1. Transportmoeglichkeiten 11. Finger-Befehl
+ 2. Seherquests 12. Echo, r-emote
+ 3. Fluchtrichtung 13. Magischer Beutel
+ 4. Seherlevel 14. Seherhaeuser
+ 5. Kommunikation 15. Seherspielplatz
+ 6. Magische Kugel 16. Uebersichtskarte Seherspielplatz
+ 7. Seherladen 17.
+ 8. Designer-Seher 18. Alle Seher im MG
+ 9. Fehlermeldung 19. Zusammenfassung & Nachwort
+
+Um die entsprechenden Inhalte zu lesen, gib bitte >lies 2< oder
+>lies seherquests< ein.
+Zu dieser Seite kommst du mit >lies inhalt< zurueck!
+
+Noch eine Anmerkung: Wenn Du eine Idee hast, was an der FAQ verbessert,
+geaendert oder hinzugefuegt werden sollte, dann waere ich Dir sehr dankbar,
+wenn Du mir eine kurze mail schicken wuerdest, oder mit dem Befehl 'idee' in
+diesem Raum absetzen wuerdest !!!
+
+RYNE
+
+
diff --git a/d/seher/haeuser/special/special/faq/karte b/d/seher/haeuser/special/special/faq/karte
new file mode 100644
index 0000000..ef5e5f9
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/karte
@@ -0,0 +1,63 @@
+ SEHERSPIELPLATZ: UEBERSICHTSKARTE
+ (Stand: 20.1.95)
+ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
+
+ X X X X X X X X--X--X--X--X--X X--X X X X--X X 1
+ \/ \ / |\ \ | | | | /
+ /\ \ / | \ \| | | | /
+ X X--X X X X--X X X X X X X X--X--X--X--X X--X 2
+ | \ / | | / \ /
+ | \ / | | / \ /
+ X X X X--X X X X X X X X X X X X X X X X 3
+ \ | \ \ / / / | |
+ \ | \ \ / / / | |
+ X X X--X X X X X X X X X X X X X X X X X 4
+ \/ \ \/ | | / / |
+ /\ \ /\ | |/ / |
+ X X X X X--X X X X X--X X X X X X X X X X 5
+ |\/ \/ \ \ | | / | |
+ |/\ /\ \ \| |/ | |
+ X X X X X--X--X--X X X X X X X X X X X X X 6
+ / \ / / / \ /|
+ / \ / / / \ / |
+ X X X X--X--X--X--X--X X X X X X X X X X X X 7
+ / |\ \ \/ \ |
+ / | \ \ /\ \ |
+ X X X X X X X X X X X X X X X--X--X--X X X 8
+ | | | | / \ \
+ | | | |/ \ \
+ X X X--X X--X X--X--X X X X X X X X X X X X 9
+ |\ | /| /| |
+ | \|/ | / | |
+ X X X X X X X--X--X--X X X X X X X X X X X 10
+
+
+ X X X X X X X X X X X X X X X X X X X X 11
+
+
+ X X X X X X X X X X X X X X X X X X X X 12
+
+
+ X X X X X X X X X X X X X X X X X X X X 13
+
+
+ X X X X X X X X X X X X X X X X X X X X 14
+
+
+ X X X X X X X X X X X X X X X X X X X X 15
+
+
+ X X X X X X X X X X X X X X X X X X X X 16
+
+
+ X X X X X X X X X X X X X X X X X X X X 17
+
+
+ X X X X X X X X X X X X X X X X X X X X 18
+
+
+ X X X X X X X X X X X X X X X X X X X X 19
+
+
+ X X X X X X X X X X X X X X X X X X X X 20
+
diff --git a/d/seher/haeuser/special/special/faq/seherfaq b/d/seher/haeuser/special/special/faq/seherfaq
new file mode 100644
index 0000000..0488959
--- /dev/null
+++ b/d/seher/haeuser/special/special/faq/seherfaq
@@ -0,0 +1,16 @@
+
+
+Hallo!
+Hier also siehst Du die aktuelle Version von Rynes SeherFAQ.
+Wenn Du weitere Fragen oder Anregungen zu dieser FAQ hast,
+se so nett und schicke mir ein kurzes mail.
+Viel Spass beim Lesen !!!
+
+Zur FAQ kommst Du mit >lies Inhalt<
+
+
+
+
+
+
+
diff --git a/d/seher/haeuser/special/special/rj.c b/d/seher/haeuser/special/special/rj.c
new file mode 100644
index 0000000..42f3b98
--- /dev/null
+++ b/d/seher/haeuser/special/special/rj.c
@@ -0,0 +1,26 @@
+inherit "/std/thing";
+
+#include <properties.h>
+#include "../haus.h"
+
+create()
+{
+ if (!clonep(this_object())) return;
+ ::create();
+
+ SetProp(P_SHORT,0);
+ SetProp(P_NOGET, 1);
+ AddId("r&j");
+ AddCmd("lies", "lies");
+}
+
+static int lies(string str)
+{
+ int nr;
+
+ if (!str || sscanf(str, "seite %d", nr) != 1)
+ return notify_fail("Syntax: lies seite <nr>\n"), 0;
+
+ this_player()->More(SPECIALPATH+"rom_jul/seite"+nr, 1);
+ return 1;
+}
diff --git a/d/seher/haeuser/special/special/rom_jul/seite1 b/d/seher/haeuser/special/special/rom_jul/seite1
new file mode 100644
index 0000000..5b870dc
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite1
@@ -0,0 +1,42 @@
+Dieser Text ist von Etains Spielerin (Lissi Paffrath) geschrieben und
+saemtliche Rechte, insbesondere die der Verbreitung und Vermarktung, liegen
+ausschliesslich bei ihr.
+Anmerkungen und konstruktive Kritik bitte per mudmail an Etain oder Snuggle.
+Viel Spass beim Lesen wuenschen Snuggle und Etain.
+
+Und hier noch eine Uebersicht ueber den Inhalt:
+
+Seite 2: Prolog
+
+Seite 3: Erster Akt, erste Szene
+Seite 4: Erster Akt, zweite Szene
+Seite 5: Erster Akt, dritte Szene
+Seite 6: Erster Akt, vierte Szene
+Seite 7: Erster Akt, fuenfte Szene
+
+Seite 8: Zweiter Akt, Einleitung
+Seite 9: Zweiter Akt, erste Szene
+Seite 10: Zweiter Akt, zweite Szene
+Seite 11: Zweiter Akt, dritte Szene
+Seite 12: Zweiter Akt, vierte Szene
+Seite 13: Zweiter Akt, fuenfte Szene
+Seite 14: Zweiter Akt, sechste Szene
+
+Seite 15: Dritter Akt, erste Szene
+Seite 16: Dritter Akt, zweite Szene
+Seite 17: Dritter Akt, dritte Szene
+Seite 18: Dritter Akt, vierte Szene
+Seite 19: Dritter Akt, fuenfte Szene
+
+Seite 20: Vierter Akt, erste Szene
+Seite 21: Vierter Akt, zweite Szene
+Seite 22: Vierter Akt, dritte Szene
+Seite 23: Vierter Akt, vierte Szene
+Seite 24: Vierter Akt, fuenfte Szene
+
+Seite 25: Fuenfter Akt, erste Szene
+Seite 26: Fuenfter Akt, zweite Szene
+Seite 27: Fuenfter Akt, dritte Szene
+
+Seite 28: Epilog
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite10 b/d/seher/haeuser/special/special/rom_jul/seite10
new file mode 100644
index 0000000..d54f51d
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite10
@@ -0,0 +1,381 @@
+DER ZWEITE AKT
+ DIE ZWEITE SZENE
+
+Azzuro, der nicht Gefahr laufen wollte, stellvertretend fuer einen
+Menschenmann von den beiden Frauen zerrissen zu werden, liess sich auf einem
+Ast neben Romeos Schulter nieder. Er betrachtete den Jungen mit einem Blick,
+der bei Menschen immer erstaunte Ausrufe provoziert, die zumeist nur die
+unertraegliche Arroganz der Menschen kundtun: _Sieht_ _er_ _nicht_ FAST
+_intelligent_ _aus_?
+
+Romeo hatte keinen Blick fuer Azzuro uebrig, denn Julia betrat den Balkon.
+Offensichtlich hatte sie noch ein wenig Luft schnappen wollen, bevor sie zu
+Bett ging, denn sie trug nicht mehr als ein Nachthemd, einen Schal und ein
+paar Tropfen Parfum.
+
+"Sieh sie dir an.", hauchte Romeo atemlos. "Ist sie nicht wunderschoen?"
+
+Azzuro verzichtete auf eine Antwort, denn ihm wurde bewusst, dass Romeo ihn
+nicht nach seiner Meinung gefragt hatte.
+
+"Julia..." Er fluesterte ihren Namen nur. "Sie geht auf wie eine Sonne, also
+muss da Osten sein.", meinte Romeo und deutete auf den Balkon.
+
+"Es ist Norden, aber ich verstehe, was du meinst.", brummte Azzuro.
+
+"Wenn sie ihren Schal fallen laesst, muss der Mond untergehen, denn dann kann
+er sich nicht mehr am Himmel halten."
+
+"Und er kann nissst mehr an sssisss halten.", kicherte Wlad.
+
+"Ich liebe sie und ich wuenschte, sie wuesste es.", murmelte Romeo. "Dann
+waeren ihre Augen Sterne am Himmel und ich ein... eine..." Er blickte Azzuro
+an. "Wie heisst denn das Tier, das im Dunkeln jagt?"
+
+"Fledermaus.", antwortete Azzuro.
+
+"Genau. Ich waere dann nur zu gerne eine spitzohrige, lederflueglige, haarige
+und mueckenfressende Fledermaus."
+
+Wlad pfiff schrill und wuetend. "Wenn er jetssst noch ssstinkend sssagt, werde
+isss ihn beissssen!"
+
+"Dann wuerde ich die Muecken fressen, die sie stechen wollen, denn niemand
+ausser mir darf in ihre Naehe kommen, auch keine Muecke. Ach, warum sagt sie
+denn nichts?"
+
+"Vielleicht, weil sie nicht weiss, dass du hier bist um sie zu hoeren?",
+vermutete Azzuro.
+
+"Ja, ich bin auch wirklich zu dreist, mich einfach hier in ihrem Garten zu
+verstecken und sie anzustarren wie ein Spanner."
+
+Julia stuetzte ihre Ellbogen auf das Gelaender des Balkons und ihr Gesicht in
+die Haende. Der Schal klaffte auf und enthuellte eine unziemliche Menge ihres
+Ausschnitts, was Romeo zu einem weiteren tiefen Seufzer veranlasste.
+
+"Ich wollte, ich waere dieser Schal!"
+
+Azzuro, der sich immer noch nicht entschliessen konnte, sein Urteil ueber
+Julias Figur zu revidieren, laechelte mitleidig. "Wenn man so etwas mag."
+
+"Ach, dumme Kraehe, was weisst du schon von Liebe!", sagte Romeo zornig und
+duckte sich vor Azzuros scharfem Schnabel. "Wenn sie doch nur etwas sagen
+wuerde."
+
+Julia tat ihm den Gefallen. "Ach, wie dumm das doch alles ist."
+
+Vor Freude ueber ihre Stimme begannen Romeos Haende zu zittern und der Inhalt
+ihrer Worte ging zum einen Ohr hinein und zum anderen hinaus, ohne den Umweg
+ueber das Gehirn zu nehmen, wie es bei Verliebten haeufig der Fall ist. "Sag
+noch etwas, meine Liebste, dann falle ich bestimmt in Ohnmacht."
+
+Azzuro grinste. "Verkneif dir das lieber, denn der Laerm wuerde bestimmt
+Aufmerksamkeit erregen."
+
+Julia sah nachdenklich zu Ulo hinueber. "Oh, Romeo."
+
+"Ich heisse Ulo, aber das macht nichts."
+
+"Koenntest du einen Moment so tun, als seist du Romeo?", fragte Julia
+hoeflich.
+
+"Sicher, wenn du dich dann besser fuehlst."
+
+"Danke. Ach, Romeo, ich wuenschte, du waerest nicht Romeo."
+
+"Warum das denn?", fragte Ulo verwirrt.
+
+"Wenn du nicht Romeo waerest, dann waerest du auch kein Montague, und dann
+koennte ich dich lieben, ohne dass mein Vater einen Herzanfall bekommt und
+meine Mutter ihre Migraene."
+
+Ulo nickte. "Hm, aber wer soll ich denn dann sein?"
+
+"Ist doch egal. Wenn du ein Buergerlicher waerest, dann wuerde ich aufhoeren,
+Capulet zu sein. Dann koennten wir einfach so zusammen sein und uns einen
+Teufel um die Konventionen scheren."
+
+"Und wenn meine Oma groesser gewesen waere, dann haettet ihr sie einen Drachen
+geschimpft.", versetzte Ulo. "Nicht, dass sie das nicht gewesen waere.",
+fuegte sie verschaemt hinzu.
+
+"Was meinst du, soll ich ihr antworten?", fragte Romeo leise.
+
+"Warte noch ein bisschen.", riet Azzuro.
+
+"Verstehst du denn nicht? Die Capulets liegen mit den Montagues in Fehde, aber
+Romeo ist Romeo ist Romeo ist Romeo, auch, wenn er nicht Romeo Montague ist."
+
+"Nein, verstehe ich nicht.", antwortete Ulo.
+
+"Der Name allein ist doch nicht der ganze Mensch. Wenn ich einen Schweissfuss
+Rose nenne, riecht er deswegen nicht besser.", erklaerte Julia.
+
+Ulo nickte. "_Das_ verstehe ich."
+
+"Ja. Und wenn Romeo nicht Romeo Montague waere, sondern..." Sie ueberlegte.
+"Hans Schmitz, so waere er immer noch der gleiche Mensch und ich koennte ihn
+ohne Probleme lieben."
+
+"Hans Schmitz?", fragte Romeo unten leise.
+
+Azzuro grinste nur.
+
+"Also, Romeo, vergiss den Namen, den brauchst du nicht. Statt des Namens
+kannst du mich haben." Julia breitete theatralisch die Arme aus.
+
+Romeo konnte sich nicht laenger zurueckhalten. "Gut, ganz wie du willst. Wenn
+du mich Hans Schmitz nennen willst, dann bin ich eben Hans Schmitz."
+
+Julia wurde feuerrot. "Spanner!", schimpfte sie.
+
+"Von mir aus auch Hans Spanner." Romeo zuckte die Schultern.
+
+Ulo fiel vor Lachen vom Ast und fing sich wenige Zentimeter ueber dem Boden
+auf.
+
+"Weiss er, was er da sagt?", fluesterte sie Azzuro zu.
+
+"Wahrscheinlich nicht.", gab Azzuro zurueck. "Ist doch auch egal, oder? So
+weggetreten, wie er im Moment ist, koennte sie ihn Hans Wurst nennen und er
+wuerde es lieben."
+
+Julia beugte sich ueber die Bruestung des Balkons und der Schal rutschte ihr
+noch weiter von den Schultern herunter. "Oh, Moment, wir haben doch heute
+abend miteinander gesprochen, nicht? Du hast mich mit einem Weihnachtsbaum
+verglichen." Sie ueberlegte. "Dann bist du Romeo Montague."
+
+Romeo gab sich alle Muehe, den Blick auf ihr Gesicht gerichtet zu halten.
+"Nein, denn du hast gerade erst beschlossen, dass ich Hans Spanner sein
+soll.", erklaerte er im Brustton der Ueberzeugung.
+
+"Wie bist du ueberhaupt hierhergekommen?"
+
+"Ueber die Mauer?" Romeo war sich seiner Sache nicht voellig sicher. "Ja,
+doch, ich bin ueber die Mauer geklettert."
+
+Julia kannte die Mauer von ihren eigenen Exkursionen. "Die ist ganz schoen
+hoch."
+
+"Die Fluegel der Liebe haben mich hinuebergetragen."
+
+"Wo hast du das denn gelesen?"
+
+"Keine Ahnung, aber es klingt huebsch, nicht?"
+
+"Ja, schon.", antwortete Julia. "Wenn meine Leute dich hier finden, reissen
+sie dir den Kopf ab."
+
+"Oder etwas, das du mehr vermissen wuerdest.", setzte Azzuro mit einem
+boshaften Grinsen hinzu.
+
+Romeo wurde blass, doch dann besann er sich Julias und der Tatsache, dass er
+bei ihr Eindruck machen wollte. "Ach, wird schon nicht so schlimm sein." Er
+zuckte mit den Schultern und versuchte, heldenhaft auszusehen. "Ich liebe
+dich, ich will dich, deine Verwandten sind mir egal."
+
+"Du bist ein Holzkopf, wenn du keine Angst vor ihnen hast." Azzuro zwickte
+Romeo spielerisch in den Oberschenkel und wich geschickt den aengstlich
+zugreifenden Haenden aus.
+
+"Du bist in grosser Gefahr, wenn du hier bleibst.", meinte auch Julia.
+
+"Ja, aber nicht deine Verwandten sind die Gefahr, sondern meine Augen." Julia
+erroetete leicht. "Hm, ich muss zugeben, dass es mir keineswegs recht waere,
+wenn sie dich hier faenden."
+
+"Waere doch ein romanreifer Tod, nicht? Wenn du mich nicht lieben willst,
+koennen sie mich haben, dann ist mir sowieso alles egal."
+
+Ulo lachte. "Mir ist auch alles egal: Ich mache Schluss mit eurem Leben und
+rufe die Verwandten."
+
+"Untersteh dich!" riefen Julia, Romeo, Azzuro und Wlad wie aus einem Mund,
+beziehungsweise Maul oder Schnabel.
+
+Julia griff beherzt zu und umfasste Ulos Schnabel. "Wirst du ruhig sein?"
+
+"Mmmmm." Ulo schlug mit den Fluegeln.
+
+"Na gut." Julia entfernte ihre Hand, bereit, sofort wieder zuzufassen, sobald
+Ulo tief Luft holte. "Woher wusstest du ueberhaupt, dass du mich hier finden
+wuerdest?", fragte sie.
+
+"Ich bin einfach der Nase nach gelaufen.", antwortete Romeo.
+
+"Nur gut, dass du Julia gefunden hast und nicht die Toilette.", fluesterte
+Azzuro ihm zu und genoss Romeos tiefrotes Gesicht, das in der Dunkelheit
+regelrecht zu leuchten schien.
+
+Auch Julia schien aehnlich Gedanken zu hegen, sprach sie allerdings nicht aus.
+"Nur gut, dass du nicht sehen kannst, wie rot ich bin."
+
+Ulo beaeugte kritisch Julias Gesicht und suchte die Roete vergeblich.
+
+"Ich bin naemlich ein anstaendiges Maedchen.", fuhr Julia fort. "Eigentlich
+stehe ich nicht nachts auf zugigen Balkonen herum und rede mit Kraehen."
+
+"Das kann ich bestaetigen." Ulo grinste boese, doch bevor sie weitersprechen
+konnte, zog Azzuro ihr heftig am Schwanz.
+
+"Ich weiss genau, dass ich eigentlich ein bisschen widerspenstiger sein
+muesste." Julia zog den Schal enger um die Schultern und erntete einen
+enttaeuschten Blick von Romeo. "Aber, wenn ich ehrlich sein soll, habe ich
+dazu ueberhaupt keine Lust. Das sind bloss Spielchen und ich mag nicht mit dir
+spielen."
+
+"Schade.", warf Romeo ein.
+
+"Nein, nicht schade. Denn dadurch kann ich dir ganz offen sagen, dass ich dich
+auch liebe. Denke ja nicht, ich sei ein Flittchen, weil ich so ehrlich bin."
+Julia drohte Romeo scherzhaft mit dem Finger.
+
+"Auch eine Art zu spielen.", murmelte Wlad vor sich hin.
+
+"Wuerde mir niemals einfallen.", antwortete Romeo und meinte es voellig
+ehrlich.
+
+"Ich muss zugeben, dass du mich ziemlich aus der Bahn geworfen hast.
+Deinetwegen tue ich Dinge, die mir sonst nicht einfielen."
+
+Romeo erroetete tief und wusste dazu nichts zu sagen.
+
+Mit strengem Gesichtsausdruck fuhr Julia fort: "Wenn du mich wirklich liebst,
+dann..."
+
+"Dann?", fragte Romeo atemlos.
+
+"Dann sag mir, was du von mir erwartest." Nun war die Reihe an Julia zu
+erroeten. "Ich will dir den Gefallen tun und mich so verhalten, wie du es von
+einem anstaendigen Maedchen erwartest."
+
+Romeo schlug sich rasch alle unanstaendigen Gedanken aus dem Kopf. "Ich
+schwoere dir..."
+
+"Nicht schwoeren!" Julia erinnerte sich nur zu gut an die vielen Schwuere, die
+sie in ihrem Leben getan hatte. Der Schwur, niemals wieder Nougatpralinen zu
+essen, von denen sie Pickel bekam, war nur einer davon - und der am
+leichtesten gebrochene.
+
+"Ja, aber..." Romeo ueberlegte angestrengt. "Wenn ich dir nicht schwoeren
+darf, dass ich dich liebe, was soll ich denn sonst tun? Ich meine..."
+
+Julia unterbrach ihn wieder. "Ich weiss, was du meinst. Aber wenn du mich
+wirklich liebst, dann kann es nur einen Schwur geben, den ich akzeptiere."
+
+Romeo schluckte. "Heirat?"
+
+"Zack, schon hat sie dich." Azzuro kicherte. "Geh jetzt, bevor es zu spaet
+ist! Oder noch besser: Renn!"
+
+Doch Romeo war schon jenseits aller guten Ratschlaege. "Ja...", sagte er
+gedehnt.
+
+"Wunderbar." Julia schenkte ihm ihr strahlendstes Laecheln. "Dann kannst du
+dir aussuchen, wann und wo die Hochzeit stattfinden soll."
+
+"Komm rein, Kindchen, da draussen holst du dir den Tod.", rief Polly von
+drinnen.
+
+Ulo lachte und stiess Wlad an. "Den Tod nicht, eher einen Ehemann."
+
+"Das kann Polly doch nicht wissen.", gab Wlad kichernd zurueck.
+
+"Warte einen Moment, ich will eben Polly beruhigen." Julia liess den Schal
+fallen und verschwand nach drinnen.
+
+"Umpf.", machte Romeo ueberwaeltigt. "Ich fasse es nicht."
+
+"Ich auch nicht.", sagte Azzuro traurig. "Wie kannst du dich nur so leicht
+einfangen lassen?"
+
+"Wer hat denn hier wen gefangen?", fragte Romeo. "Ich habe doch wohl die
+wunderbarste, schoenste, kluegste..."
+
+"Ach du lieber Himmel!" Azzuro warf Romeo einen zutiefst entsetzten Blick zu
+und verschwand in der Dunkelheit.
+
+Julia tauchte wieder auf dem Balkon auf und legte sich ihren Schal wieder um
+die Schultern. "Wenn du es allerdings nicht ernst meinst, dann bitte..."
+
+"Julia!", rief Polly wieder.
+
+"Jaja, ich komme ja schon!" Julia seufzte. "...ich dich, lass mich in Frieden.
+Morgen schicke ich jemanden zu dir, der bei dir den Termin fuer die Hochzeit
+abholen soll. Wenn du mir keinen Termin gibst, dann werde ich wohl bis an mein
+Lebensende einsam und allein weinen." Die Vorstellung allein liess eine Traene
+ueber ihre Wange laufen. "Und jetzt schlaf gut."
+
+Romeo sog die feuchte Nachtluft durch die Nase und bildete sich ein, einen
+Hauch ihres Parfums zu riechen. Bedauernd blickte er zu Julias Balkon hoch,
+der nun abgesehen von der Kraehe auf der Bruestung leer war. "Ach, Julia, wie
+gerne bin ich bei dir und wie traurig bin ich, weil ich jetzt wieder gehen
+muss."
+
+"Julia?" Ulo ueberlegte. "Ach so, ich verstehe. Na gut, dann bin ich eben
+jetzt Julia."
+
+"Hm?", fragte Julia, die es im Zimmer nicht mehr ausgehalten hatte.
+
+"Ach, nichts." Ulo rueckte zur Seite.
+
+"Bist du noch da, Romeo?", fluesterte Julia. "Wie schade, dass du kein Hund
+bist und ich keine Hundepfeife habe, denn dann koennte ich dich rufen, ohne
+gleich die ganze Nachbarschaft rebellisch zu machen."
+
+Wlad kicherte leise bei der Vorstellung von Romeo als Bernhardiner mit treuen,
+schwermuetigen Augen und einem Faesschen um den Hals, mit dessen Inhalt er
+sich waehrend der langen Nachtwachen vor Julias Fenster waermte.
+
+"Romeo?" Julia rief nun ein wenig lauter.
+
+"Ich bin schon da." Er sah zu Julias Balkon hoch. "Was soll ich tun?"
+
+"Ihr die Zeitung und die Pantoffeln bringen.", murmelte Ulo und zwinkerte Wlad
+zu.
+
+"Wann kann ich denn meinen Boten zu dir schicken?"
+
+"So gegen neun Uhr?", schlug Romeo vor.
+
+"Gut. Aber ich wollte noch etwas anderes..." Auf ihrer Stirn bildete sich eine
+steile Falte.
+
+"Ich bleibe hier, bis es dir wieder einfaellt." Romeo schien von dem Gedanken
+sehr angetan zu sein.
+
+Julia kicherte leise. "Dann erinnere ich mich nie mehr daran, weil du mich so
+voellig verwirrst und ich sowieso an nichts anderes als dich denken kann."
+
+Romeo liess sich Julias Satz noch einmal durch den Kopf gehen und nickte, als
+er ihn begriffen hatte. "Dann bleiben wir beide hier fuer immer und ewig
+stehen."
+
+"Und verhungern.", warf Ulo voellig unpoetisch ein.
+
+"Dann waerest du wie ein kleiner Hund, weisst du? Immer, wenn du mal eben
+aeh..." Julia zoegerte. "...einen Baum markieren willst, zoege ich an deiner
+Leine, weil ich dich nicht alleine gehen lassen will."
+
+"Das waere wunderschoen.", seufzte Romeo. "Ich waere gerne dein Hund."
+
+"Ja, der Gedanke ist reizvoll." Julia rief eine Generalmobilmachung fuer die
+gesamte Vernunft in ihrem Kopf aus. "Aber wahrscheinlich wuerde ich dich so
+schrecklich verwoehnen, dass du in kuerzester Zeit wie eine Sofarolle
+aussiehst und an Herzverfettung eingehst. Wenn du nicht bald gehst, sage ich
+dir gute Nacht, bis die Sonne aufgeht, und mache dann mit guten Morgen
+weiter." Sie laechelte, winkte ein letztes Mal und verschwand wieder in ihrem
+Zimmer.
+
+Romeo sah ihr mit leeren Augen hinterher. "Wenn ich doch bloss ihr Bett waere,
+oder ihre Bettdecke, dann koennte ich die ganze Nacht bei ihr sein." Er
+seufzte. "Es waere mir schon genug, wenn ich ein Traum sein duerfte, dann
+koennte ich die ganze Nacht in ihrem Kopf sein."
+
+Ulo grinste. "In ihren Kopf will er bestimmt nicht hinein."
+
+"Ferkel.", wies Azzuro sie zurecht.
+
+"Nein, Kraehe. Ferkel haben keine Fluegel und sind auch nicht schwarz."
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite11 b/d/seher/haeuser/special/special/rom_jul/seite11
new file mode 100644
index 0000000..2b5f62c
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite11
@@ -0,0 +1,131 @@
+DER ZWEITE AKT
+ DIE DRITTE SZENE
+
+Bruder Lawrence hob seine Fuesse in den Sandalen besonders hoch, denn das Gras
+war nass und kalt vom Tau. Ueber seinen Arm hatte er einen Korb gehaengt,
+seine Kutte vorne zusammengefasst und in den Strick gesteckt, der ihm als
+Guertel diente. Die Sonne, die vorsichtig ueber die Gartenmauer lugte, brachte
+Bruder Lawrencens Tonsur zum Schimmern und glitzerte auf seinen taunassen,
+haarigen Beinen, wenn er sich niederbueckte und Kraeuter ausrupfte, die er
+sorgfaeltig in seinen Korb legte.
+
+"Komm nur her, du huebscher Borretsch.", sagte Bruder Lawrence mit einem
+Laecheln, das die Pflanze nicht erwiderte. "Du kommst heute in meinen Salat."
+
+"Ich koennte mir angenehmeres vorstellen.", murmelte Ulo, die auf der Mauer
+sass und sich die Sonne auf das Gefieder scheinen liess.
+
+Azzuro, dem die durchwachte Nacht zusetzte, schreckte neben ihr aus seinem
+Nickerchen hoch. "Was meintest du?", fragte er verschlafen.
+
+Ulo antwortete nicht, sondern betrachtete Bruder Lawrence, dessen Bauch es ihm
+sichtlich schwer machte, die Gaensebluemchen zu pfluecken, die seinem Salat
+Farbe geben sollte.
+
+"Hab ich dich.", meinte der Moench triumphierend. "Du bist mir besonders
+erwuenscht, kleines Gaensebluemchen. Denn sagt nicht schon Leonhard Fuchs:
+_Die_ _Gennssblum_ _ist_ _fuertrefflich_ _gut_ _zu_ _den_ _lamen_ _glidern_.
+Und lahm fuehle ich mich heute morgen ganz bestimmt." Er rieb sich den Ruecken
+und liess seinen Blick ueber den Kraeutergarten wandern, bis er auf einem
+Maigloeckchen haengenblieb. "Dich esse ich lieber nicht, auch wenn du
+huebscher bist, als das Gaensebluemchen.", versicherte er der Blume, die ihm
+jedoch keine Aufmerksamkeit schenkte. "So schoen du riechst, so huebsch du
+anzuschauen bist, so boesartig giftig bist du auch." Er seufzte und drohte der
+Blume scherzhaft mit dem Finger. "Jaja, so dicht liegen Schoenheit und Tod
+manchmal nebeneinander."
+
+"Der gute Bruder ist heute philosophisch aufgelegt.", informierte Ulo ihren
+Gefaehrten.
+
+"Hmpf.", machte Azzuro ohne den Schnabel aus dem Gefieder zu ziehen.
+
+Ulo stiess ihn an und beobachtete mit haemischem Grinsen, wie Azzuro sich um
+sein Gleichgewicht bemuehte. "Romeo kommt."
+
+"Lass ihn kommen und mich schlafen.", brummte Azzuro ungehalten.
+
+"Was bist du, ein Mann oder..."
+
+"...eine Kraehe.", vervollstaendigte Azzuro den Satz und beschloss, lieber
+aufzuwachen, als Ulo weiterhin Gelegenheit zu geben, ihn von der Mauer zu
+stossen.
+
+"Guten Morgen, Bruder Lawrence." Romeo winkte dem Moench froehlich zu.
+
+"Du bist aber heute gut gelaunt, Romeo.", wunderte sich Bruder Lawrence.
+"Sonst bekommt man dich doch nicht so frueh aus dem Bett. Junge Leute schlafen
+lang und viel und das ist auch gut so. Andererseits..." Er mass Romeo mit
+einem kritischen Blick. "Du bist wohl im richtigen Alter um eine Nacht
+durchzumachen."
+
+"Genau. Und ich habe durchgemacht und fuehle mich frischer, als wenn ich die
+ganze Nacht geschlafen haette."
+
+Bruder Lawrence, der sich noch gut daran erinnerte, wie es war, bevor er
+Moench wurde, schickte das Grinsen, dass sich auf seinem Gesicht ausbreiten
+wollte mit einem energischen Stirnrunzeln zurueck und besann sich auf seine
+Pflichten als Priester und geistlicher Berater. "Du hast doch nicht etwa
+gesuendigt, mein Sohn?", fragte er streng. "Warst du bei Rosaline?"
+
+"Wer ist Rosaline?" Romeo rieb sich mit uebertrieben verwirrtem
+Gesichtsausdruck die Stirn. "Ach so, das war die Frau, die mich so schrecklich
+traurig gemacht hat." Er lachte. "Nein, Bruder Lawrence, diese Frau habe ich
+vergessen."
+
+"Siehst du, ich habe dir doch gleich gesagt, dass dies das beste fuer dich
+sein wuerde." Nun stahl sich trotz aller Anstrengungen, die der Moench
+unternahm, doch noch Neugierde in seinen Blick. "Wo hast du dich denn dann
+rumgetrieben?"
+
+"Ich habe beschlossen, den Anweisungen der Bibel zu folgen und meine Feinde zu
+lieben."
+
+"Das ist an und fuer sich sehr loeblich, aber wenn du mir nicht sagst, was du
+getan hast, kann ich dir auch nicht sagen, was ich davon halte. Und meinen Rat
+suchst du doch, wenn ich dich richtig verstehe."
+
+"Nein, eigentlich nicht.", antwortete Romeo und musste ueber das verwirrte
+Gesicht des Moenchs laecheln. "Also, gestern abend habe ich bei den Capulets
+eine Feier besucht und dabei Julia kennengelernt."
+
+"Oh.", machte Bruder Lawrence verstaendnislos.
+
+"Sie ist wunderschoen, ich liebe sie, sie liebt mich und alles was wir noch
+brauchen, um endgueltig gluecklich zu werden, ist ein Priester, der uns
+verheiratet.", sprudelte es nun aus Romeo heraus.
+
+"Aha." Nun verstand Bruder Lawrence, was sein Schuetzling wollte. "Und an
+dieser Stelle komme ich ins Spiel." Romeo laechelte seinen vaeterlichen Freund
+so strahlend an, dass dessen Herz dahinschmolz. "Ich muss schon sagen, das ist
+eine ueberraschende Wendung. Erst liebst du Rosaline und jammerst mir die
+Ohren voll, dann lernst du eine andere Frau kennen und schon ist Rosaline
+Schnee von gestern. Tja, ich sollte mir wohl angewoehnen, die jungen Leute mit
+einem Koernchen Salz zu geniessen. Zu meiner Zeit war man nicht so
+sprunghaft."
+
+"Aber du wolltest doch, dass ich Rosaline nicht mehr liebe." Romeo war
+verwirrt.
+
+"In Rosaline warst du verknallt, nicht verliebt. Das ist ein entscheidender
+Unterschied."
+
+"Siehst du, jetzt hast du doch deinen Willen. Ich liebe Julia und bin nicht
+verknallt in sie."
+
+"Das hast du von Rosaline auch gesagt."
+
+Romeo ueberlegte, denn dieser Einwand wog schwer. "Ja, aber Rosaline hat mich
+nicht zurueckgeliebt."
+
+Bruder Lawrence wiegte bedaechtig seinen Kopf hin und her. "Das ist wohl wahr.
+Na, ich werde euch verheiraten, zumindest wird es euren Eltern helfen, ihren
+Streit zu begraben."
+
+"Worauf warten wir dann noch?" Romeo lief ein paar Schritte auf die kleine
+Kapelle zu.
+
+"Immer langsam mit den jungen Pferden." Er wischte sich den Schweiss von der
+Stirn und bedachte Romeo mit einem langen Blick. "Nein, junge Hengste laufen
+schnell, es sind die alten Wallache, die nicht hinterherkommen.", korrigierte
+er sich und laechelte.
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite12 b/d/seher/haeuser/special/special/rom_jul/seite12
new file mode 100644
index 0000000..a79896f
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite12
@@ -0,0 +1,266 @@
+DER ZWEITE AKT
+ DIE VIERTE SZENE
+
+Mercutio zog ein unwilliges Gesicht. "Ich frage mich, wo zum Teufel Romeo
+steckt. Letzte Nacht war er nicht daheim."
+
+"Jedenfalls nicht bei seinem Vater.", grinste Benevolio.
+
+"Bestimmt ist er draussen herumgerannt und hat ueber diese Rosaline
+gejammert." Mercutio spuckte den Namen regelrecht aus.
+
+"Es kommt noch schlimmer." Benevolio zueckte ein Taschentuch und putzte sich
+umstaendlich die Nase. "Es ist ein Brief von Tybalt angekommen."
+
+"Ach du dicker..." Mercutio wurde blass. "Das ist bestimmt eine
+Herausforderung."
+
+Sie wissen, liebe Leserin, lieber Leser, dass in mythischer Zeit eine
+Herausforderung nicht mehr war, als heute eine Einladung zu einem Tennismatch
+unter Feinden. Natuerlich lief es nicht ganz so unblutig ab wie ein
+Tennismatch, dafuer aber hatten die Bestattungsunternehmer mehr zu tun und die
+Gerichte mussten sich nicht mit Beleidigungsklagen auseinandersetzen. Ein
+findiger Kopf erfand dann irgendwann die Rechtschutzversicherung und sorgte
+dafuer, dass Duelle verboten wurden. Wir schulden dem Erfinder dieser
+Versicherung bis heute Dank, denn ansonsten waeren die Praemien der
+Sterbekassen und Lebensversicherungen wesentlich hoeher.
+
+Benevolio nickte bedaechtig. "Romeo wird ihm schon eine angemessene Antwort
+darauf geben."
+
+"Solange es keine anmassende ist." Mercutio schuettelte den Kopf. "Dieser
+Tybalt macht mir Sorgen."
+
+"Ach was, Tybalt ist ein aufgeblasener Idiot."
+
+"Vielleicht. Aber ausserdem ist er noch ein verdammt guter Fechter."
+
+"Romeo auch."
+
+"Nicht gut genug, fuerchte ich." Mercutio haetter gerne eine bessere Meinung
+von den Fechtkuensten seines Freundes gehabt, hatte jedoch Tybalt schon
+kaempfen sehen.
+
+"Komm, male nicht schwarze Leute an weisse Waende." Benevolio wedelte mit den
+Haenden, als wolle er einen Mueckenschwarm verscheuchen. "Siehst du? So
+vertreibe ich deine trueben Gedanken."
+
+"Und holst Romeo damit her.", laechelte Mercutio. "Hallo Romeo. Na, Wie war
+deine Nacht?" Ein luesternes Grinsen breitete sich ueber sein Gesicht aus.
+
+"Interessant.", antwortete Romeo unbestimmt.
+
+"Das kann ich dir ansehen, mein Freund." Benevolio strich die zerzausten Haare
+seines Cousins zurecht.
+
+"Hast uns ja ganz schoen reingelegt, mein Lieber.", wies Mercutio Romeo
+zurecht.
+
+"Habe ich? Das tut mir leid, aber ich bin im Moment so schrecklich... aeh..."
+Er ueberlegte und fuegte dann mit einem Grinsen hinzu: "...strapaziert."
+
+Mercutio lachte. "Deine Strapazen moechte ich haben!"
+
+"Dann waerest du genauso muede wie ich." Romeo rieb sich uebertrieben die
+Augen.
+
+"Und haette wie du Aehnlichkeit mit der Katze, die den Sahnetopf ausgeschleckt
+hat."
+
+"Nachdem die Koechin das Verbrechen entdeckt hat, kannst du meine Rolle gerne
+haben.", meinte Romeo grinsend.
+
+"Das ist unfair: Die Sahne bekommst du und ich den Aerger mit der Koechin."
+
+"Besser den Aerger als die Koechin." Romeo schuettelte sich.
+
+"Besser die Sahne als beides." Mercutio wiegte sich in den Hueften. "So
+gefaellst du mir schon besser, Romeo. Gestern hast du noch ziemlich truebe aus
+der Waesche geschaut." Er grinste breit. "Und heute nacht in die Waesche
+hinein, nehme ich an."
+
+Romeo trat nach Mercutio, gab sich aber keine besondere Muehe, ihn zu treffen.
+"Nichts da, ich bin anstaendig."
+
+"Nicht, dass du es freiwillig waerest."
+
+"Pfft.", machte Romeo und wandte sich ab. Sein Blick blieb auf Polly haengen,
+die sich ihren Weg ueber den Marktplatz bahnte und dabei an ein Schlachtschiff
+unter vollen Segeln gemahnte. Verschaemt deutete er mit dem Finger auf Polly.
+"Streicht die Flagge, Leute, der Korsar wird uns entern."
+
+Mercutio verbarg sein Gesicht hinter den Haenden. "Bemannt die Boote, sie
+rammt uns!"
+
+Benevolio lachte. "Dort blaest er!"
+
+Azzuro schuettelte sich, als er wieder einmal ein fremdes Zitat hoerte, blieb
+aber stumm.
+
+"Was soll denn das, Benevolio?" Romeo ergriff die Nase seines Cousins mit zwei
+Fingern, zog sein Gesicht daran nach oben und beschaute sich sowohl die Zaehne
+als auch die Augen. "Bist du sicher, dass du ganz gesund bist?"
+
+"He!" Benevolio gab Romeo einen Stoss. "Lass das, du tust mir weh."
+
+"Ich wollte doch nur nachsehen, ob dir irgendetwas fehlt."
+
+"Da oben fehlt ihm nichts.", belehrte Mercutio seinen Freund. "Schon eher
+fehlt ihm unten etwas, aber darueber sprechen anstaendige Maenner ja nicht."
+
+"Anstaendige Maenner benutzen es und schweigen.", meinte Romeo.
+
+"Anstaendige Maenner brauchen es nicht." Benevolio rieb sich die Nase.
+
+"Armer Benevolio, hat man dir das zum Trost erzaehlt?" Mercutio taetschelte
+Benevolios Kopf.
+
+"Sieh an, die Galeone hat noch eine Schaluppe im Schlepptau.", bemerkte Romeo.
+
+"Die Schaluppe ist wohl das Proviantschiff." Benevolio hatte den grossen Korb
+bemerkt, der ueber Peters Arm hing und mit Gemuese vollgestopft war. Romeo
+nickte, doch da Polly nun auf Hoerweite herangekommen war, zog er es vor,
+nicht mehr zu antworten und sich statt dessen vor Polly zu verneigen.
+
+"Guten Morgen.", gruesste Polly.
+
+"Eher guten Abend.", gab Mercutio zurueck.
+
+"Wieso? Es ist doch noch frueh am Tag."
+
+"Aber Mittag ist viel zu unanstaendig, den uebergeht eine Dame besser. Wenn
+der Zeiger so aufgerichtet ist..." Mercutio liess den Rest des Satzes in der
+Luft haengen.
+
+"Peter, mein Faecher.", verlangte Polly und mass Mercutio mit einem Blick, den
+man nicht in Worten beschreiben kann.
+
+Eher ist es moeglich, Mercutios Entsetzen zu beschreiben, als er den Blick
+auffing und tiefrot wurde. Er erinnerte sich ploetzlich an den Tag, an dem ihn
+seine eigene Kinderfrau mit der Hand in der Hose erwischt hatte. Um seine
+Verlegenheit zu ueberspielen, rief er: "Jawohl, Peter, den Faecher der Dame,
+der Faecher ist wahrscheinlich ein schoenerer Anblick als das Gesicht."
+
+Polly kniff die Augen zusammen, sagte aber nichts.
+
+"Nehmen Sie ihn nicht zu ernst.", riet Romeo und versuchte, Pollys
+Aufmerksamkeit von Mercutio abzulenken.
+
+Polly seufzte. "Kann einer von Ihnen mir wohl sagen, wo ich einen jungen Mann
+namens Romeo finde?"
+
+"Wenn Sie nur seinen Vornamen wissen, wird er vermutlich ein Graubart sein,
+bevor sie ihn gefunden haben.", meinte Romeo laechelnd. "Aber wenn Sie
+einstweilen mit mir Vorlieb nehmen wollen?"
+
+"Nicht, dass ich eine Vorliebe fuer Sie haette, nein, aber wenn Sie Romeo
+heissen, dann nehme ich Sie."
+
+Mercutio machte "Ha!", und kruemmte sich dann in einem Hustenanfall, der ihm
+sofort von Benevolio ein paar kraeftige Schlaege auf den Ruecken eintrug.
+
+"Aeh, ich bringe Mercutio zu dir nach Hause, Romeo, er sollte etwas trinken."
+
+Benevolio gab sich alle erdenkliche Muehe, sein Gesicht ernst zu halten. "Wir
+treffen uns dann da zum Mittagessen." Er beugte sich besorgt ueber Mercutio
+und schleppte diesen aus Pollys Reichweite.
+
+"Was war denn das fuer ein Flegel?", fragte Polly.
+
+"Wie ich schon sagte, nehmen Sie ihn nicht fuer voll. Was kann ich fuer Sie
+tun?" Romeo hatte selbst Probleme, nicht zu lachen.
+
+"Also wirklich." Polly war immer noch nicht bereit, Mercutios Benehmen zu
+vergessen. "Wie kann er sich nur so gegen eine Dame verhalten. Als ob ich eine
+Hergelaufene waere, mit der er machen kann, was er will." Ihre Empoerung
+schlug in Wut gegen Peter um und sie schlug mit ihrem Faecher nach ihm. "Und
+du stehst dabei und haelst Maulaffen feil, waehrend der Kerl mir zu nahe
+tritt."
+
+Peter rieb sich die Stelle an seinem Arm, die Polly getroffen hatte. "Ich hab
+nix gesehen, hab ich nich. Is ja nich, als waer ich nich direkt dabei, wenn
+man Ihnen ueberhaupt zu nah kommen koennt." Sein Blick ruhte einen Augenblick
+interessiert auf Pollys stattlicher Figur. "Aber der Jung is ihnen nich zu nah
+gekommen, is er nich." Er nickte noch einmal zur Bekraeftigung und zwinkerte
+Romeo zu, der sich umstaendlich die Nase putzte und sein Grinsen hinter seinem
+Taschentuch verbarg.
+
+Polly betrachtete Peter nachdenklich, wandte sich dann aber Romeo zu. "Also,
+junger Mann. Sie wissen, dass Julia mich schickt. Ich sage Ihnen jetzt nicht,
+was sie mir gesagt hat, obwohl ich es nicht vergessen habe, denn ich vergesse
+nie etwas. Auch die Beleidigungen dieses Flegels nicht, der so schnell
+verschwunden ist, ohne sich zu entschuldigen. Wenn Sie ein anstaendiger Mann
+sind, und das hoffe ich fuer Sie, denn ansonsten bekommen Sie es mit mir zu
+tun, dann rate ich Ihnen, mir zu sagen, wie Ihre Absichten sind. Glauben Sie
+mir, ich werde Julia troesten, wenn Sie mit ihr ein falsches Spiel treiben,
+aber Sie werden sich in diesem Fall wuenschen, sie haetten es nie angefangen.
+Also, was sagen Sie?"
+
+Romeo ueberlegte nicht lange. "Wenn Sie mich so fragen, dann lassen Sie mich
+erklaeren, dass..."
+
+Polly klatschte in die Haende und beobachtete befriedigt, wie Romeo
+zusammenzuckte.
+
+"Gut, das ist sehr gut, da wird mein Laemmchen ausser sich sein vor Glueck."
+
+"Ich glaube, Sie hoeren mir nicht zu."
+
+"Wieso? Ich habe alles gehoert, was ich hoeren muss. Oder haben Sie etwa nicht
+gesagt, dass Sie sich erklaeren? Soweit ich weiss, sagt ein anstaendiger Mann
+doch, dass er sich erklaert. Wie auch immer, wenn Sie sich erklaeren, dann
+haben Sie lautere Absichten, also gebe ich mich zufrieden."
+
+"Da, jetzt gibt es keinen Weg zurueck." Ulo grinste boese.
+
+Azzuro schuettelte bedauernd den Kopf und schwieg.
+
+Als Romeo die Bedeutung von Pollys Worten daemmerte, wurde er, soviel soll zu
+seiner Ehrenrettung gesagt sein, nur fuer einen kurzen Moment bleich. Er
+raeusperte sich. "Na gut. Bitten Sie Julia, heute Nachmittag zu Bruder
+Lawrence zu kommen, dort werden wir heiraten." Er grub in seinen Taschen und
+foerderte ein paar Muenzen zutage, die er Polly in die Hand drueckte. "Und das
+ist fuer Sie."
+
+"Nein, danke. Ich nehme kein Geld dafuer, dass ich Julia einen Gefallen tue."
+Azzuro flog eine Runde um Romeos Kopf und fluesterte leise: "Denk an die
+Hochzeitsnacht, das ist doch das Beste am Heiraten."
+
+Romeos Gesicht leuchtete auf. "Na gut, dann nehmen Sie es dafuer, dass Sie
+waehrend der Trauung in Lawrencens Garten stehen und eine Strickleiter
+entgegen nehmen." Polly wurde puterrot. "Ah, ich verstehe, die
+Hochzeitsnacht." Rasch verbarg sie ihr Gesicht hinter dem Faecher und
+kicherte. "Einverstanden." Polly blickte zu Peter und runzelte die Stirn. "Hm,
+wer wird die Leiter denn bringen? Ich meine, wird derjenige auch schweigen
+koennen?"
+
+"Bestimmt, dafuer werde ich sorgen." Romeo laechelte.
+
+"Dann ist es ja gut. Tja, daran habe ich nicht gedacht, als sie als Kind auf
+die Nase fiel und mein Mann Gott-hab-ihn-selig sagte..." Polly unterbrach
+sich. "Ach ja, da gibt es noch einen jungen Mann, der gerade zu Besuch ist.
+Paris heisst er, vielleicht haben Sie schon von ihm gehoert? Er macht ganz den
+Eindruck, als haette er Lust, sich bei Julia einzunisten und wenn er soweit
+ist auch gleich bei ihrem Vater. Im Geldbeutel, wenn Sie verstehen, was ich
+meine. Was denken Sie, wie niedlich blass Julia wird, wenn ich sie aufziehe
+und ihr sage, dass Paris ein besserer Mann ist als Sie?" Polly genoss
+sichtlich Romeos verwirrten Gesichtsausdruck. "Sie will so gar nichts von
+einem anderen Mann hoeren und sieht wirklich allerliebst aus, wenn sie sich
+ueber mich aergert."
+
+"Aeh, ja?"
+
+"Ja, das tut sie. Und mehr noch, Sie wuerden Ihre helle Freude daran haben,
+wenn Sie hoeren koennten, wie sie ihrem Hund von Ihnen erzaehlt. Ganz niedlich
+rollt sie dabei das R in Ihrem Namen und macht dabei das Knurren des
+Huendchens nach." Romeo zog es vor, nicht weiter ueber die Aehnlichkeiten
+zwischen seinem Namen und dem Knurren eines Schosshuendchens nachzudenken und
+laechelte noch ein Mal mit erzwungener Freundlichkeit. "Wie dem auch sei.
+Bitte richten Sie Julia meine Gruesse aus."
+
+"Mehr nicht?"
+
+"Mehr sage ich ihr dann heute Nacht, nachdem wir verheiratet sind."
+
+Wieder wurde Polly rot. "Oh."
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite13 b/d/seher/haeuser/special/special/rom_jul/seite13
new file mode 100644
index 0000000..9705992
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite13
@@ -0,0 +1,122 @@
+DER ZWEITE AKT
+ DIE FUENFTE SZENE
+
+Ulo und Azzuro hatten sich im Garten damit vergnuegt, Julia zu beobachten.
+
+"Ich sitze wie auf Kohlen.", beklagte sich Julia bei Ulo.
+
+"Krah.", machten Ulo und Azzuro wie aus einem Schnabel.
+
+Verwirrt blickte Julia zu ihnen hoch. "Letzte Nacht konntet ihr reden." Sie
+zuckte die Schultern. "Aber letzte Nacht war ja ohnehin nichts so, wie es sein
+sollte. Alles war ganz..." Sie zoegerte. "...ganz verzaubert." Sichtlich
+erfreut ueber ihre poetische Wortwahl rief sie ihren Hund und spielte eine
+Zeit lang mit ihm. "Polly macht mich noch ganz verrueckt.", klaerte Julia den
+Hund auf. "Kannst du dir vorstellen, dass sie fuer einen simplen Botengang
+drei Stunden braucht?"
+
+Statt einer Antwort rollte sich der Hund auf den Ruecken und tat, was Hunde am
+besten koennen: Er hechelte.
+
+Hunde, liebe Leserin, lieber Leser, gehoeren in eine Geschichte wie der
+unseren einfach dazu. Sie sind das Salz in der Suppe.
+
+Wer jemals Liebeskummer hatte, weiss die Gesellschaft eines Hundes zu
+schaetzen, denn mit ihren seelenvollen braunen Augen haengen sie gebannt an
+den Lippen ihres Frauchens oder Herrchens und scheinen wahrhaftig jedes Wort
+zu verstehen. Dies ist selbstverstaendlich ein Trick, mit dem Hunde ihren
+Menschen dazu bringen, ihnen einen besonders schoenen Knochen zu spendieren.
+Dennoch fallen wir Menschen immer wieder auf Hunde herein, denn wir sind
+leicht zu domestizieren.
+
+Die ganze Tierwelt zollt den Hunden fuer ihren Erfolg mit der Zaehmung des
+Menschen grossen Respekt. Die einzigen Tiere, die den Hunden diese Leistung
+absprechen, sind die Katzen, doch das liegt eher daran, dass Katzen
+prinzipiell niemanden respektieren. Julia taetschelte ihrem Hund gehorsam den
+Bauch. "Wenn Polly bloss schneller waere. Ich halte es kaum noch aus."
+
+Das Knarzen und Quietschen des Gartentores gab die Ankunft wichtiger
+Neuigkeiten bekannt, noch bevor Polly hindurch trat. Julia sprang auf wie von
+einer Bremse gestochen und rannte auf Polly zu. "Polly, liebe Polly! Na, sag
+schon, was hat er gesagt? Was soll ich machen? Hast du ihn ueberhaupt
+getroffen? Red doch!"
+
+Polly schnaufte. "Nun mal langsam. Setz dich lieber erst einmal hin."
+
+"Ich kann mich nicht setzen, bevor du mir nicht gesagt hast, was los ist."
+
+"Und ich kann dir nichts sagen, solange ich noch so ausser Atem bin. Jetzt
+setz dich hin, du machst mich verrueckt. Wie soll ich denn Luft holen koennen,
+wenn Du so herumspringst?"
+
+Julia betrachtete ihre Amme kritisch. "So sehr kannst du doch gar nicht ausser
+Atem sein, wenn du mir sagen kannst, dass du ausser Atem bist."
+
+"Das verstehst du noch nicht." Polly holte tief Luft und donnerte: "Setz dich
+hin!" Julia plumpste ins Gras.
+
+"So doch nicht, du machst ja Flecken in dein Kleid." Polly seufzte. "Kind,
+Kind, wirst du denn nie erwachsen?"
+
+Wortlos stand Julia auf und liess sich auf einer Bank nieder. "Jetzt besser?
+Kannst du jetzt endlich reden?"
+
+Polly laechelte. "Ja, jetzt kann ich reden. Da hast du dir ja einen schoenen
+Galan ausgesucht, Julia. Also, ich will ihn ja nicht schlechter machen als er
+ist, aber ich muss schon sagen, er hat ein paar sehr unerfreuliche Freunde.
+Obwohl er einen knackigen ... Geist hat. Knackig im Sinne von frisch, wenn du
+verstehst, was ich meine. Er ist noch nicht ganz trocken. Hinter den Ohren.
+So, jetzt erzaehl aber, was du heute gefruehstueckt hast."
+
+Ulo grinste breit auf ihrem Ast. "Polly versteht es wirklich, Julia zu
+triezen."
+
+Azzuro, der fasziniert auf Pollys rotes Gesicht blickte und auf den
+Schlaganfall wartete, nickte nur.
+
+Julia, die wusste, was Polly beabsichtigte, seufzte tief. "Das weiss ich und
+nichts."
+
+"Nichts? Kind, du faellst mir ja ganz vom Fleisch. Das ist aber nicht gut,
+wenn Romeo sich an dir blaue Flecken holt."
+
+Julia setzte ein unschuldiges Gesicht auf. "Holt er sich denn blaue Flecken?",
+fragte sie scheinheilig.
+
+Azzuro nickte. "Tut er."
+
+Polly kniff Julia in die Seite. "Also, wenn du es genau wissen willst..."
+
+"Ja?"
+
+"Also, dein junger Freund sagt, so wie es ein anstaendiger Mann sagen sollte,
+wenn er auf sich haelt und ausserdem noch die Chance seines Lebens bekommt...
+Wo ist eigentlich deine Mutter?"
+
+"Also, Polly, das ist ja nun sicherlich nicht seine Antwort, oder? 'Wo ist
+deine Mutter'" Julia schuettelte den Kopf.
+
+"Du liebes bisschen, du bist ganz schoen heiss. Auf die Antwort, meine ich.
+Wenn du verstehst, was ich meine. Also, er sagt, ganz und gar..."
+
+Ulo stoehnte mit Julia im Chor.
+
+"Du sollst heute nachmittag in die Kapelle dieses Minoriten kommen. Lawrence
+heisst er. Und da bekomme ich einen Ring und du eine Leiter." Sie schuettelte
+den Kopf. "Nein, umgekehrt: Du bekommst den Ring und ich die Leiter fuer die
+Hochzeitsnacht."
+
+Jubelnd huepfte Julia um Polly herum und zog uebermuetig an Azzuros Schwanz.
+Ihr Hund, der ihre Freude missverstand, kniff Polly in die Wade und handelte
+sich einen Tritt ein.
+
+Auf Pollys verwittertes Gesicht stahl sich ein Laecheln. "Sieht ganz so aus,
+Kind, als fielest du gleich auf den Ruecken."
+
+"Erst heute abend.", versetzte Azzuro.
+
+"Hauptsache, sie faellt." Polly grinste und ihre Wangen bekamen einen
+maedchenhaft rosigen Schimmer. "Aeh, nicht herein, meine ich natuerlich."
+
+"Natuerlich.", stimmte Azzuro zu und schaffte es, voellig ernst zu bleiben.
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite14 b/d/seher/haeuser/special/special/rom_jul/seite14
new file mode 100644
index 0000000..b26ca1c
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite14
@@ -0,0 +1,93 @@
+DER ZWEITE AKT
+ DIE SECHSTE SZENE
+
+In jener mythischen Zeit waren heimliche Hochzeiten nicht selten, sie hatten
+den Vorteil, dass das Paar nicht zusammen lebte. Natuerlich ersparte eine
+heimliche Hochzeit auch die Kosten fuer ein Fest. Allerdings war die
+Hochzeitsnacht unabdingbarer Bestandteil der Ehe: Ohne Hochzeitsnacht galt die
+Ehe nicht als geschlossen. Romeo und Julia waren eine Ausnahme von der
+ueberwiegenden Mehrzahl der heimlichen Hochzeiten: Die meisten jungen Paare
+verlegten die Hochzeitsnacht vor und sparten auf diese Weise sogar die bei der
+Hochzeit uebliche Spende an die Kirche.
+
+Lawrence stand neben der Tuer seiner kleinen Kapelle und betrachtete
+nachdenklich Romeo, der den Huegel hinaufstuermte.
+
+"Er rennt, als seien alle Teufel der Hoelle hinter ihm her. Dabei ist Julia
+noch gar nicht hier." Azzuro reckte gemaechlich die Fluegel.
+
+Lawrence, der wie sein grosses Vorbild, der heilige Franziskus, sich nichts
+dabei dachte, mit Voegeln zu reden, drohte Azzuro mit dem Finger. "Unberufen!
+Julia ist doch ein nettes Maedchen."
+
+"Das sind sie vor der Hochzeit alle.", stellte Azzuro fest.
+
+"Komm schon, das sagst du jetzt nur, weil deine Frau nicht hier ist." Lawrence
+grinste.
+
+"Natuerlich. Sie ist ja auch schon mit mir verheiratet."
+
+Lawrence bueckte sich und zupfte einen Regenwurm aus dem saftigen Boden, den
+er Azzuro reichte. "Wo ist eigentlich deine Frau?"
+
+"Bei Julia. Sie meint, ein Maedchen sollte eine Brautjungfer haben."
+
+Lawrence nickte. "Ein kluger Gedanke."
+
+Azzuro bedachte den Regenwurm mit einem langen Blick. "Ich weiss nicht. Was,
+wenn sie den Brautstrauss faengt?"
+
+"Das kann sie ohne Haende nicht, mein schwarzer Freund.", troestete Lawrence
+ihn.
+
+"Sie wird dir erhalten bleiben."
+
+"Wahrscheinlich.", stimmte Azzuro truebsinnig zu.
+
+"Nun lach doch mal." Lawrence stiess Azzuro freundschaftlich an. "Eine
+Hochzeit ist eine froehliche Angelegenheit."
+
+"Solange sie dauert. Danach kommt das Verheiratet-Sein."
+
+Romeo, der Azzuros letzte Worte gehoert hatte, laechelte toericht. "Das ist
+doch das beste an der ganzen Heiraterei: Danach kann sie mir niemand mehr
+wegnehmen."
+
+"Eben, mein Junge, eben.", versetzte Azzuro.
+
+Auch Lawrence meinte, seinem Amt als Seelsorger gerecht werden zu muessen.
+"Einen gibt es, der dir alles wegnehmen kann.", meinte er und deutete zum
+Himmel.
+
+Romeos Blick folgte Lawrencens Finger und gewahrte eine dunkle Wolke. "Ach, so
+ein bisschen Regen wird Julia schon nicht abhalten."
+
+Tatsaechlich kam Julia den Hang herauf, gefolgt von einer keuchenden Ulo. "So,
+hier bin ich."
+
+Romeos Augen strahlten verdaechtig irre, als er sie betrachtete. "Wie huebsch
+du aussiehst."
+
+Julia laechelte geistlos. "Wer ist denn der huebsche Bursche hier, Bruder
+Lawrence?"
+
+Azzuro verdrehte die Augen. "Na, sieh zu, dass du fertig wirst, Lawrence, ich
+halte es nicht mehr aus!"
+
+Ulo liess sich auf einem Ast nieder und wischte sich mit der Fluegelspitze die
+Traenen ab. "Ach, Hochzeiten sind so ruehrend!"
+
+Azzuro, immer noch niedergeschlagen, nickte. "Ja, mir kommen auch jedes Mal
+die Traenen, wenn ich sehe, dass jemand lebenslaenglich bekommt."
+
+"J-U-L-I-A, ich lieb dich so!", traellerte Romeo.
+
+"Das macht er nur, um mich zu aergern.", grollte Azzuro.
+
+"Ich seh ein Licht...", sang nun auch Julia.
+
+Azzuro, der es hasste, wenn die Menschen den falschen Text aufsagten, grinste
+niedertraechtig. "... im Hause Frankenstein.", vollendete er die Zeile fuer
+Julia. Ueberlassen wir die Liebenden jetzt eine Weile sich selbst und ziehen
+uns diskret zurueck.
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite15 b/d/seher/haeuser/special/special/rom_jul/seite15
new file mode 100644
index 0000000..d39fbac
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite15
@@ -0,0 +1,414 @@
+DER DRITTE AKT
+ DIE ERSTE SZENE
+
+Benevolio wischte sich den Schweiss von der Stirn und sah ungluecklich zu
+Mercutio hinueber, der mit hochrotem Gesicht neben ihm hermarschierte. "Es ist
+zu heiss, um hier draussen herumzulaufen, Mercutio. Ausserdem sind die
+Capuleten los."
+
+"Angst?", fragte Mercutio.
+
+"Nein, aber es ist zu warm fuer Pruegeleien."
+
+"Huch?" Mercutio legte Benevolio die Hand an die Stirn. "Du bist doch nicht
+etwa krank? Sonst gibt es doch nichts, was dich von einer zuenftigen Pruegelei
+abhalten kann."
+
+Wieder zueckte Benevolio sein Taschentuch. "Doch, Hitze."
+
+"Ach, komm schon, ausgerechnet du willst jetzt ins Haus!"
+
+"Wieso ausgerechnet ich?"
+
+"Na, sonst beguckst du dir dein Messer und sagst: 'Walte Hugo, dass ich dich
+nur zum essen brauche.' Und zwar laut und vernehmlich, damit es auch ja jeder
+Raufbold hoert und weiss, dass du auf Streit aus bist."
+
+"So schlimm bin ich doch gar nicht."
+
+Haette Mercutio ueber unsere Welt Bescheid gewusst, so haette er Benevolio
+sicherlich als Grossmacht bezeichnet, denn nur Grossmaechte sind in der Lage,
+Waffen in Sichtweite anderer Grossmaechte aufzustellen und mit unbewegtem
+Gesicht zu sagen: "Wir brauchen diese Waffen eigentlich gar nicht, weil wir ja
+friedlich sind, wir wollen sie euch nur zeigen, weil sie so huebsch sind."
+
+"Nein, natuerlich nicht. Erinnerst du dich noch an den Kerl, den du verhauen
+hast, weil er an deiner Rose roch?"
+
+"Das musste ich doch! Rose ist ein anstaendiges Maedchen."
+
+"Ich meine nicht die Rose in deinem Bett, sondern die in eurem Vorgarten."
+
+"Hmpf.", machte Benevolio.
+
+In Mercutios Augen tanzten kleine Teufelchen, als er seinen Blick ueber den
+Platz schweifen liess. "Guck mal, da ist Tybalt."
+
+"Uh-oh."
+
+Tybalt trat auf die beiden zu und grinste hoehnisch, als er Benevolios
+schweissueberstroemtes Gesicht sah. "Wie sagte meine Grossmutter so treffend:
+'Schlechtes Fleisch schaeumt.'"
+
+Benevolio wandte sich zum Gehen. "Komm, Mercutio, hier heult ein Wolf den Mond
+an, das ist mir zu laut."
+
+"Mitnichten, Benevolio, wenn der gute Tybalt etwas von uns will, soll er fuer
+uns tanzen."
+
+"Was fuer eine praechtige Hochzeitsfeier.", kommentierte Azzuro bitter.
+
+"So sind die Menschen." Ulo war nachsichtig und milde gestimmt.
+
+Mercutio fischte in seiner Hosentasche nach einer Muenze, die er Tybalt
+zuwarf. "Mach Faxen, Alter."
+
+"Faxen kannst du haben!" Nun schaeumte auch Tybalt.
+
+Benevolio hob die Hand. "Beherrscht euch. Mitten auf der Strasse zu kaempfen
+ist aeusserst unfein. Da gehoert doch eine Wiese im Morgengrauen und ein
+stilvoller Nebel dazu."
+
+"Ach, Nebel." Mercutio wollte sich so leicht nicht ablenken lassen. "Ich hau
+Tybalt auch ohne Nebel meinen Saebel um die Ohren."
+
+"Hier guckt dir jeder zu, Mercutio."
+
+"Na, vielleicht lernen sie ja noch was. Genau wie ich Tybalt lehren werde."
+
+Romeo betrat den Platz mit einem unirdischen Strahlen auf dem Gesicht. Sie
+wissen schon: Das Strahlen, das man bei Menschen sehen kann, die gerade ein
+besonders exotisches Pilzragout gegessen haben und feststellen, dass es ihnen
+wider Erwarten gut - allzu gut - bekommt. "Guten Tag, ihr lieben, goldigen
+Menschen!"
+
+Tybalt bedachte Romeo mit einem Blick, der fuer gewoehnlich seltenen und
+abstossenden Kaefern vorbehalten bleibt. "Lieb?"
+
+Auch Mercutio sah seinen Freund interessiert an, allerdings glich sein Blick
+mehr dem eines Biologen. "Lieb. Hat er gesagt. Und goldig."
+
+Azzuro schuettelte sich. "Warte nur ab, bis ihm klar wird, dass ihn Julia
+jetzt am Haken hat. Dann ist Schluss mit lustig."
+
+Ulo stiess ihren Gefaehrten an. "Auch wenn du es nicht fuer moeglich haeltst,
+er ist gluecklich."
+
+"Noch."
+
+Tybalt ueberwand seine Verwirrung als erster und gab sich alle Muehe, seiner
+Aufgabe als Schurke dieser Geschichte gerecht zu werden. "Hund, elender!"
+
+Romeo, immer noch mit dem seligen Gesichtsausdruck, laechelte Tybalt an. "Ach,
+Tybalt, du ahnst ja nicht, wie gern ich dich habe."
+
+Ulo zog die Brauen hoch. "Auf einmal?"
+
+"Familienpflichten." Azzuro kannte diese Sitte, die verhindern sollte, dass
+sich Gefaehrten eines Rudels an die Kehle gehen, auch wenn die
+Rudelangehoerigen noch so widerlich sind. Formulieren wir es anders: Sie haben
+schon als kleines Kind gelernt, dass Sie Ihre Tante auch dann nicht vors
+Schienbein treten duerfen, wenn sie Ihnen noch so oft unerwuenschte Kuesse
+verpasst. Viele Menschen zahlen teure Sitzungen bei Psychotherapeuten um ihrer
+uebertragenen Tante endlich einmal - ohne mit schaerfsten Sanktionen belegt zu
+werden - sagen zu koennen, dass sie nicht gekuesst werden wollen.
+
+Tybalt, der sich die Gelegenheit nicht entgehen lassen wollte, schenkte Romeo
+ein zuckersuesses Laecheln. "Du hast wohl das Ufer gewechselt? Willst mich
+beleidigen, indem du mir unterstellst, ich..." Er brach ab und streichelte
+erwartungsvoll seinen Degen.
+
+"Aber nein!" Romeo, der offensichtlich Tybalts Ziel nicht erkennen wollte,
+strahlte weiterhin um die Wette. "Du kennst mich eben nicht, Tybalt Capulet,
+sonst wuesstest du, dass ich dich ebenso gern habe wie mich selbst."
+
+Mercutio stoehnte. "Himmel, hilf, er ist unter die Betbrueder gegangen!" Er
+zog blank. "Aber wenn Romeo selbst die Beleidigung nicht raechen will, dann
+lasse ich ihn nicht im Regen stehen. Zieh, Tybalt!"
+
+"Hoert auf." Romeo rang die Haende. "Ihr wisst doch, dass der Fuerst uns das
+verboten hat!"
+
+Tybalt schien Mercutio jetzt erst zu bemerken. "Was willst du denn?", fragte
+er in einem Tonfall, den manche Menschen kleinen Kindern und Hunden
+vorbehalten.
+
+"Dein Leben. Oder wenigstens ein ansehnliches Stueck davon."
+
+"Das musst du dir erst holen!" Tybalts Degen schien ploetzlich Fluegel
+bekommen zu haben, anders liess sich das Tempo nicht erklaeren, mit dem er
+seiner Scheide ledig wurde.
+
+Nun sind wir an der Stelle angelangt, an der jeder Autor die Grenzen des
+Papiers verflucht und sich fragt, ob er nicht doch lieber Drehbuecher
+schreiben sollte. Oder die Tintenkleckserei ganz an den Nagel haengen und
+vielleicht einer ehrbaren Arbeit nachgehen sollte, die - abgesehen von einem
+regelmaessigen Einkommen - noch den Ruf der Unstetigkeit tilgt, der jeden
+Schreiber (und jede Schreiberin - natuerlich habe ich das verstanden, Ulo) in
+die Naehe des Bahnhofsviertels rueckt. Dem Papier fehlt, trotz seiner bereits
+sprichwoertlichen Geduld, die Faehigkeit, Ereignisse, die sich in Bruchteilen
+von Sekunden abspielen, in angemessen kurzer Zeit wiederzugeben. Und das ist
+keine versteckte Beleidigung meiner LeserInnen.
+
+Stellen Sie sich also vor, sie stuenden in einer Disko. Vor Ihnen ist die
+Tanzflaeche, die Sie nur daran erkennen, dass keine Tische darauf stehen. Ihr
+Magen macht eigenartige Huepfbewegungen und wenn Sie sich konzentrieren,
+koennen Sie erkennen, dass die Huepferei im Takt zum Wummern der
+Basslautsprecher erfolgt. Messerscharf folgern Sie, dass die Musik (?) fuer
+die zuckenden Bewegungen Ihrer Innereien verantwortlich ist und nicht etwa das
+Chili con Carne von gestern abend. Im Stroboskoplicht, dass die Tanzflaeche
+beleuchtet, zucken einzelne Glieder durcheinander: Hier ein Arm, dort ein
+Bein, ein Stueckchen weiter eine wehende Haarmaehne und dazwischen vielleicht
+noch ein heller Fleck, der ein Gesicht sein koennte. Die Eindruecke folgen zu
+schnell aufeinander, als dass Sie die Glieder zaehlen koennten - ganz zu
+schweigen davon, dass Sie aus Armen, Beinen, Haaren und Gesichtern ganze
+Menschen konstruieren koennten. Also nehmen Sie die Bilder so hin, wie sie
+Ihnen geboten werden. Es bleibt der Gedanke, dass Menschen zu Musik tanzen.
+
+Oder stellen Sie sich einen Film mit den Marx-Brothers vor. Erinnern Sie sich?
+Es kam darin immer wieder zu Szenen, in denen sich die Brueder gegenseitig
+Torten in die Gesichter warfen oder Ohrfeigen austeilten. Schnelle Schnitte
+anstelle von Schwenks zeigten die Geschwindigkeit, in der das Geschehen
+passierte.
+
+Nachdem es also keine echte Moeglichkeit gibt, Ihnen das Tempo der Ereignisse
+der naechsten paar Minuten auf jenem Platz in Verona zu vermitteln, erlauben
+Sie mir, das Papier zu zerschneiden und Ihnen die Situation in Schnippseln zu
+praesentieren. Ganz so, als stuenden Sie daneben und liessen Ihre Augen im
+Takt der Ereignisse von einer Person zur naechsten huepfen, ohne die
+Geschehnisse unbedingt miteinander zu verbinden.
+
+Romeos Augen weiten sich vor Schreck. "Nein! Steckt die Dinger weg!"
+
+Benevolio, nicht weniger entsetzt als sein Freund, zueckt den Degen um die
+Waffen Tybalts und Mercutios herunterzuschlagen.
+
+Tybalt, der die Situation missversteht, fintet in Richtung Romeo, verfuehrt
+damit Benevolio dazu, seinen Degen mit dem seinen zu binden.
+
+Azzuro flattert aufgeregt mit den Fluegeln. "Juch-hu!", kraeht er vergnuegt.
+
+Romeo gibt sich alle Muehe, Mercutio aus dem Gerangel fortzuziehen, erreicht
+allerdings nur, dass Mercutio ihm eine saftige Ohrfeige verpasst.
+
+Ulo, die Romeo nicht an seinem Hochzeitstag tot sehen will, fliegt todesmutig
+einen Sturzangriff auf Tybalt.
+
+Tybalt schlaegt nach dem schwarzen Schemen vor seinem Gesicht und lenkt damit
+Mercutios Aufmerksamkeit wieder auf sich.
+
+Mercutio schuettelt Romeo ab und tritt Benevolio vors Schienbein, der Tybalt
+Ulo ueberlaesst.
+
+Azzuro hat erfolgreich einen Stein in die Klauen genommen und laesst ihn
+Benevolio auf den Kopf fallen.
+
+Benevolio, von dem Stein zwar nicht hart getroffen, wohl aber aus dem
+Gleichgewicht gebracht, laesst Mercutios Arm los.
+
+Mercutio, der sich gerade von Benevolio losreissen wollte, bekommt zuviel
+Schwung und rempelt Romeo an.
+
+Romeo taumelt zur Seite.
+
+Tybalt wittert Morgenluft, macht einen schnellen Ausfallschritt und versenkt
+seinen Degen in Mercutios Brust.
+
+Als Tybalt klar wurde, was er angerichtet hatte, nahm er die Beine in die
+Hand.
+
+Stille.
+
+Stille!
+
+STILLE!
+
+Mercutio tastete mit zitternder Hand nach seiner Schulter. "Verdammte
+Scheisse.", sagte er in die donnernde Stille hinein. Eine weisse Taube landete
+weich neben ihm und schaute ihn so vorwurfsvoll an, dass Mercutio seine Worte
+bedauerte. "Schon gut, ich lasse mir etwas besseres einfallen."
+
+"Damit sollte er sich besser beeilen.", raunte Azzuro Ulo zu.
+
+"Ist aber auch eine Schande, dass den Menschen so wenig Zeit bleibt, sich
+wuerdevolle letzte Worte auszudenken." Ulo schniefte leise.
+
+Ein Leuchten huschte ueber Mercutios Gesicht, als ihm eine brauchbare Idee kam.
+
+"Ach, Romeo, waerest du nicht zwischen diesen Ba... Elenden und mich getreten,
+ich haette mich nicht zurueckhalten muessen und sicherlich den Sieg
+davongetragen!", stoehnte er angemessen feierlich.
+
+"Er traegt zu dick auf." Azzuro bekam den mordluesternen Blick, den man sonst
+bei Kritikern beobachtet.
+
+Romeo, der aussergewoehnlich schnell erkannte, was von ihm erwartet wurde,
+fiel neben seinem Freund auf die Knie. "Ich habs doch nur gut gemeint!"
+
+Azzuro oeffnete den Schnabel, doch die Taube warf ihm einen Blick zu, der
+selbst einen Klatschspalten-Redakteur zum Schweigen gebracht haette.
+
+"...", sagte Mercutio und sein Kopf sank zur Seite.
+
+Romeo schluckte. "Ist er...?"
+
+Ulo liess sich auf seiner Schulter nieder und rieb sanft den Schnabel ueber
+seine Wange.
+
+"Ja."
+
+"Und nur, weil er nicht wollte, dass ich beleidigt werde. Dabei wusste er doch
+gar nicht, warum ich Tybalt in Ruhe liess." Er seufzte. "Ich liebe Julia, aber
+um ihretwillen habe ich zugelassen, dass Mercutio fuer mich die
+Unverschaemtheiten Tybalts bezahlte. Und jetzt hat er dafuer bezahlt. Ich habs
+doch nur gut gemeint." Verzweifelt schuettelte er den Kopf. "Nur gut gemeint."
+
+Die weisse Taube legte den Kopf schief. Da Mercutio nun fuer die Menschen der
+Mythenwelt tot war, durfte er das Ende der Geschichte eigentlich nicht mehr
+mit ansehen, doch so wie ein Schauspieler den Rest der Vorstellung beobachten
+und schliesslich mit seinen Kollegen gemeinsam vor dem Vorhang den Applaus des
+Publikums in Empfang nehmen darf, blieb die Taube zurueck und gesellte sich
+Ihnen und mir zu, die wir das Stueck beobachten, ohne selbst eingreifen zu
+koennen. Die Taube ist fuer die Goetter der Mythenwelt, was die Diskette fuer
+den Computer ist: Ein Speicher, der enthaelt, was erst spaeter wieder
+gebraucht wird. Obwohl CD-ROM wahrscheinlich ein besseres Wort waere, denn bei
+der naechsten Auffuehrung dieser Geschichte wird Mercutio wieder ganz der Alte
+sein, er wird nichts gelernt haben, keine Veraenderung erfahren.
+
+Benevolio beruehrte Romeo an der Schulter. "Tybalt."
+
+Romeo sprang auf wie von der Tarantel gestochen. "Na warte, der soll bezahlen!
+Er laeuft hier herum, als waere nichts passiert, waehrend Mercutio, der
+immerhin mit unserem Fuersten verwandt ist..." Er brach ab und zueckte seinen
+Degen. "Komm her, Tybalt, jetzt sollst du sehen, was du davon hast, meinen
+Freund umzubringen!" Halten wir Romeo zugute, dass er im Affekt handelt und
+keine boese Absicht hinter seiner Entscheidung zur Lynchjustiz steckt. Er
+ficht mit Tybalt und wir wollen uns eine genaue Beschreibung der einzelnen
+Schritte, Hiebe und Stiche ersparen - nicht nur, weil ich vom Fechten nichts
+verstehe, sondern auch, weil ich diejenigen unter Ihnen, die davon ebenfalls
+keine Ahnung haben, nicht langweilen moechte. Erzaehlen wir also die Szene so
+kurz als moeglich: Romeo und Tybalt fechten miteinander und Tybalts Taube
+gesellt sich zu Mercutios.
+
+Fragen Sie mich jetzt nicht, warum die Tauben die Koepfe zusammenstecken, es
+hat jedenfalls mit unserer Geschichte nichts zu tun. Hoffentlich.
+
+Benevolio sah das Verhaengnis in Gestalt aufgebrachter Polizisten nahen.
+"Mach, dass du wegkommst, Romeo!"
+
+Romeo, der noch versuchte, seinen Degen aus Tybalts Leiche zu ziehen, fluchte.
+"Hilf mir doch bei dem Ding."
+
+Benevolio schuettelte den Kopf. "Los, du hast keine Zeit zu verlieren. Wenn
+die Polizei dich erwischt, hast du es genauso hinter dir wie die beiden hier."
+
+Romeo, der die ganze Tragweite der Geschehnisse jetzt erst begriff, nickte und
+rannte los.
+
+Keine Seuche kann sich schneller ausbreiten als die Nachricht, dass es
+irgendwo eine Leiche zu sehen gibt, doch selbst die Geschwindigkeit dieser
+Nachricht ist nichts gegen das Tempo, mit dem Menschen herbeihasten, die einen
+leibhaftigen Moerder sehen wollen. Nicht anders war es auch jetzt: Die Buerger
+Veronas, sensationsluestern und blutgierig wie alle Menschen, flogen geradezu
+auf den Platz. Aus dem vielstimmigen Geschrei und dem gierigen Glanz der Augen
+liess sich ohne weiteres die Stimmung der Menge in einen einzigen Satz
+kristallisieren: "Wo ist Tybalt, der Moerder?"
+
+Benevolio trat unbehaglich von einem Fuss auf den anderen, wie es die meisten
+Leute taeten, die sich unversehens mit einem wuetigen Mob konfrontiert sehen.
+Er deutete auf Tybalts Leiche. "Hier."
+
+Enttaeuschung breitete sich auf den Gesichtern aus. Fuer Benevolio schien es
+jetzt unangenehm zu werden - er kannte so gut wie jeder andere den alten
+Spruch, dass der schrecklichste aller Schrecken ein Menschenmob ohne Opfer
+ist. Zu seinem grossen Glueck kamen jetzt Escalus und die Haeupter der Haeuser
+Capulet und Montague zum Platz, die von ihrer Honoratiorenwuerde nur wenig
+laenger zurueckgehalten worden waren als die anderen Buerger.
+
+Escalus schob sich durch die Menge wie ein Eisbrecher durch das Nordmeer und
+baute sich vor Benevolio auf. "Also?"
+
+Benevolio wagte kaum zu atmen. Jeder auf dem Platz schien den Atem anzuhalten,
+selbst Ulo und Azzuro hatte es einen Moment lang die Sprache verschlagen.
+Schliesslich holte Benevolio Luft und dieser Atemzug entwickelte sich zu einem
+kollektiven Seufzen. Er war sich unangenehm der Tatsache bewusst, dass aller
+Augen auf ihm ruhten.
+
+"Aeh...", begann er.
+
+"Ja?" Escalusens Geduld glich dem Gummiband im Flugzeug eines kleinen Jungen.
+
+"Also, da war Mercutio. Und dann war da Tybalt. Und das Wetter war so heiss.
+Und Tybalt wollte sich pruegeln. Ja. Und jetzt ist Mercutio tot. Und Tybalt."
+
+Frau Capulet, die aufgrund ihrer Erfahrung mit Polly Benevolios Saetze
+schneller sortiert hatte, als irgend ein anderer auf dem Platz, schrie auf und
+Rachedurst verzerrte ihre Gesichtszuege zu einer Fratze, die selbst eine
+Medusa haette zu Stein erstarren lassen. "Tybalt! Oh, Tybalt!" Sie warf sich
+an Escalusens Brust und trommelte mit den Faeusten auf ihn ein. "Ein Montague
+hat meinen Verwandten erstochen!" Sie zerraufte sich hoechst dramatisch das
+Haar. "Dafuer muss der Schuldige haengen!"
+
+Escalus wischte die Faeuste der Frau Capulet beiseite. "Wer hat denn
+angefangen?", fragte er geduldig.
+
+Benevolio schluckte. "Tybalt. Und dann hat Romeo versucht, ihn und Mercutio zu
+trennen. Er hat sogar gesagt, dass Sie es gar nicht gerne saehen, wenn die
+beiden sich auf offener Strasse pruegelten."
+
+"Auf offener Strasse. Soso."
+
+Benevolio bemerkte, dass diese Aeusserung falsch ausgelegt werden konnte und
+rang die Haende. "Tybalt wollte einfach nicht hoeren und hat nach Mercutio
+gezielt. Naja, Mercutio ist nicht gerade sanft, wenn man ihn zu rasieren
+versucht, und hat sich natuerlich gewehrt. Aber Tybalt war ein besserer
+Fechter, deshalb wollten die beiden gerade maechtig losfechten, als Romeo sie
+zu trennen versuchte. Noch mal zu trennen versuchte." Seine Rede hatte
+Benevolio ganz atemlos gemacht und er holte tief Luft. "Mercutio stand hinter
+Romeo und Tybalt vor ihm. Ja, und dann sticht Tybalt unter Romeos Arm durch
+und erwischt Mercutio."
+
+"Und dann?"
+
+"Dann ist Tybalt weggelaufen, aber weil er Romeo nicht stehen lassen wollte,
+kam er zurueck und Romeo sah rot. Tja, dann haben sie gefochten und Romeo hat
+gewonnen. Alles so schnell, dass ich nicht dazwischen gehen konnte."
+
+"Und Romeo?"
+
+"Ist weg."
+
+Escalusens Gesicht hatte jenen Ausdruck, der Erwachsenen eigen ist, die den
+Streit von Kindern aus deren Aussagen nachvollziehen wollen. Da die meisten
+Kinder die Geschehnisse, die zu einem Streit fuehren, nicht unbedingt
+folgerichtig wiedergeben, fuehrt der Versuch meistens dazu, dass Erwachsene
+beide Kinder gleichermassen ermahnen, Frieden zu halten, gleich, wer der
+Schuldige am Streit war. Dies jedoch hatte Escalus bereits versucht und er sah
+sich am Ende seiner Moeglichkeiten. _Fussball_, dachte er, _ist_ _schoen_
+_und_ _gut_, _aber_ _was_ _soll_ _ich_ _machen_, _wenn_ _sie_ _sich_ _Spikes_
+_unter_ _die_ _Schuhe_ _machen_ _und_ _behaupten_, _sie_ _waeren_ _nur_ _aus_
+_Versehen_ _dem_ _andern_ _auf_ _den_ _Fuss_ _getreten_? _Was_ _sind_
+_eigentlich_ _Spikes_?
+
+Frau Capulet, die den nachdenklichen Gesichtsausdruck Escalusens als
+Unsicherheit interpretierte, witterte Fruehlingsluft. "Ist doch vollkommen
+gleichgueltig, wer angefangen hat! Benevolio ist Romeos Freund, da kann man
+wohl kaum erwarten, dass er die Wahrheit aussagt."
+
+Escalus war sich der Befangenheit seines Zeugen durchaus bewusst, andererseits
+wusste er nur zu genau, dass ein Gehenkter niemals ausreicht, den Blutdurst
+des Mobs zu stillen. Er hob demonstrativ die Arme. "Tybalt hat Mercutio
+erstochen, bevor er selbst erstochen wurde. Mir scheint, liebe Frau Capulet,
+dass Romeo nur dem Rachewunsch der Familie Montague Genuege getan hat."
+
+Herr Montague zauderte nicht, in die gleiche Kerbe zu hauen. "Romeo haette
+wohl die Arbeit Herrn Escalus ueberlassen sollen, aber er hat sicherlich im
+Affekt gehandelt. War sozusagen nur Henker."
+
+Frau Capulet schnappte nach Luft. "Henker?"
+
+Escalus, dem die Situation zu entgleiten drohte, hob die Hand. "Schluss. Romeo
+hat meine Gerichtshoheit untergraben. Also verbanne ich ihn. Fuer den Mord
+will ich weiter keine Strafe verhaengen, weil ich Tybalt nicht anders
+behandelt haette."
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite16 b/d/seher/haeuser/special/special/rom_jul/seite16
new file mode 100644
index 0000000..471d4ba
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite16
@@ -0,0 +1,212 @@
+DER DRITTE AKT
+ DIE ZWEITE SZENE
+
+Julia sass auf dem Rasen, starrte in einen Zierteich und seufzte tief.
+
+Ulo kniff ein Auge zu. "Was sie wohl hat?", fluesterte sie Azzuro zu.
+
+"Zuviel Sonne?", vermutete Azzuro.
+
+Ein weiterer Seufzer Julias liess die Beiden wieder hinunter sehen. Julia
+ergriff einen Stein, wog ihn nachdenklich in der Hand und warf ihn dann nach
+dem Spiegelbild der Sonne im Teich. "Geh doch weg.", forderte sie die
+unnachgiebige Sonne auf.
+
+"Aber warum denn bloss?", entfuhr es Ulo lauter als geplant.
+
+Julia blinzelte. "Weil du stoerst. Wenn du untergegangen bist, kommt Romeo.
+Also tu mir einmal einen Gefallen und beeil dich." Sie verlegte sich auf List.
+"Guck mal, wenn du auch nur ein bisschen schneller waerest, dann koenntest du
+dich viel schneller ausruhen und vielleicht noch eine Weile lesen, oder so."
+
+Azzuro stoehnte. "Als ob die Sonne da einen Einfluss drauf haette. Und welches
+Buch sollte sie wohl lesen? Verbrennt doch sofort." Er schuettelte den Kopf
+ueber soviel Unvernunft.
+
+"Sie weiss es ja nicht besser." Ulo war bereit, Julia die Ignoranz ihrer Zeit
+nicht anzulasten.
+
+Julia schaute nach Westen. "Ich wuesste zu gerne, was du am liebsten isst,
+Nacht, dann koennte ich dich anlocken und du kaemest schneller." Sie
+laechelte. "Und mit dir kommt Romeo."
+
+"Und ob er kommt." Azzuro versuchte ein Hecheln und wartete auf einen
+Rippenstoss von Ulo. Als dieser ausblieb, blickte er verbluefft auf seine
+Gefaehrtin. Ulo schaute angestrengt nach Westen und schien aehnliche
+Ueberlegungen anzustellen wie Julia.
+
+Ein weiterer Stein wanderte in Julias Hand und ahnte nichts von dem Schicksal,
+das ihn erwartete: Er flog seinem Bruder nach in den Teich. "Da, so werfe ich
+dich weg, Jungfraeulichkeit."
+
+Azzuro kicherte. "Wenn doch alle Frauen..."
+
+Ulo schnaubte.
+
+"Fuer meinen Romeo..." Julia brach ab und ein gieriger Ausdruck trat auf ihr
+Gesicht. "MEIN Romeo, wie das klingt!"
+
+Waehrend Ulo verstaendnisvoll nickte, wand Azzuro sich bei Julias Worten.
+
+Julia schaute hoffnungsvoll zum Himmel, als dieser dunkler wurde und drohte
+dann einer vorwitzigen Wolke mit dem Finger. "Willst mich reinlegen, wie? Als
+koenntest du eine Nacht sein." Sie zog die Nase kraus und liess sich dann
+hintenueber fallen. "Allerdings siehst du fast aus wie mein Romeo."
+
+Azzuro, der keinerlei Aehnlichkeit feststellen konnte, sah Polly, die so rasch
+ihre alten Beine sie tragen wollten, zu Julia gelaufen kam. In ihren Armen
+trug sie ein Buendel, das sich beim Naeherkommen als eine aufgerollte und
+hoffnungslos ineinander verknotete Strickleiter entpuppte.
+
+Julia, die das Schnaufen Pollys hoerte, noch ehe sie ihre Amme sah, sprang
+auf. "Polly! Hast du die Leiter?"
+
+"Leiter, jajaja, die Leiter hab ich. Sofern man diesen Seilknubbel noch eine
+Leiter nennen kann." Polly liess die Leiter fallen und wischte sich den
+Schweiss von der Stirn.
+
+Julia betrachtete Polly kritisch. "Du siehst aus, als haettest du eine
+schlechte Nachricht."
+
+"Du liebe Guete, ja, allerdings eine schlechte Nachricht. Weil er tot ist.
+Ach, jetzt ist alles vorbei und wir koennen uns gerade so gut aufhaengen mit
+dieser unseligen Leiter." Sie rang die Haende. "Weil er naemlich tot ist und
+nie wieder kommt."
+
+Julia erbleichte und schluckte. "Was?"
+
+"Ich sag doch, er ist tot."
+
+"Das kann doch nicht wahr sein." Julia schuettelte den Kopf.
+
+"Doch, allerdings ist es wahr. Das haette ich Romeo nun wirklich nicht
+zugetraut!"
+
+Die Blaesse in Julias Gesicht wich hektischen Flecken. "Der Teufel soll dich
+holen, Polly!", schimpfte sie.
+
+"Was, mich auch noch?" Polly war entsetzt. Sie wusste zwar, dass sie mit
+einiger Sicherheit nicht das Paradies sehen wuerde, doch so schnell gedachte
+sie nicht ihren Platz zu raeumen.
+
+"Schlechte Nachrichten kann man nicht pruegeln, wohl aber den Boten.",
+kommentierte Ulo.
+
+"Ich wollte, du bekaemest einen einzigen Satz zusammenhaengend heraus, Polly."
+Julias Geduld hatte sich verabschiedet und sich zu James in die Kueche
+begeben, wo sie gemeinsam am Sherry naschten. "Also, da du einer klaren
+Aussage nicht faehig bist: Lebt Romeo? Und wehe, du sagst nicht einfach Ja
+oder Nein!" Ihr Blick wanderte zu den Seilen und von dort zu Polly.
+
+Polly, die ahnte, was Julias Blick bedeutete, holte Luft. "Ich hab ihn
+gesehen, das ganze Hemd voll Blut. Und das ist doch so schwer auszuwaschen.
+Herrjemineh, er sah so traurig aus, blass und voller Blut wie er war." Traurig
+sah sie Julia an und hoffte, ein wenig Mitleid zu erregen. "Ich konnte mich
+nicht mehr auf den Beinen halten."
+
+Julia wurde wieder bleich. "Dann ist wirklich alles aus."
+
+Polly zerdrueckte ein paar Traenen mit ihrem voluminoesen Taschentuch. "Ach,
+ich mochte ihn so gern, weil er doch immer hoeflich und freundlich war. Armer
+Tybalt, jetzt bist du tot und kannst nie mehr nett sein."
+
+Als Julia daemmerte, was Polly sagte, atmete tief ein und fluchte so
+ausdauernd, dass Azzuro sie staunend anblickte. "Ich ahnte ja nicht, dass sie
+solche Worte kennt!", murmelte er anerkennend.
+
+Auch Polly war offensichtlich entsetzt. "Kind, wie kannst du nur!"
+
+Julia hingegen war laengst jenseits allen gesitteten Benehmens. "Wenn du jetzt
+nicht augenblicklich sagst, wer tot ist, mein Lieblingsvetter Tybalt oder mein
+Herzliebster Romeo, dann bringe ich dich um!"
+
+Polly zweifelte nicht daran, dass Julia genau das tun wuerde. "Tybalt ist tot
+und Romeo hat ihn umgebracht. Romeo ist verbannt."
+
+"Sieh an, was eine gezielte Drohung nicht alles erreichen kann." Ulo haette
+Julia applaudiert, wenn ihre Fluegel das zugelassen haetten. "Sogar Polly
+bekommt eine klare Aussage zustande."
+
+Gestatten Sie mir, liebe Leserinnen und Leser, an dieser Stelle einen Moment
+zu verweilen. Beweist die Geschichte nicht an dieser Stelle, dass auch die
+Goetter der Mythen einen gewissen Sinn fuer Humor haben? Doch laenger will ich
+Sie nicht aufhalten, schon sehen Ulo und Azzuro mich wuetend an, weil ich das
+Band angehalten habe und den Anblick einer verwirrten Polly ebenso geniesse
+wie den der innerlich zerrissenen Julia.
+
+"Sie sitzt wirklich in der Patsche, nicht?" Ulo konnte sich ein haemisches
+Federschuetteln nicht verkneifen.
+
+Julia rannte verzweifelt um den Teich herum. "Was soll ich nun denken? Wie
+konnte Romeo das nur tun? Hat er zwei Gesichter? Hat er mich angelogen? Wollte
+er nicht seine ganze Familie aufgeben? Hat er mich so hintergangen? Hat er am
+Ende nur gesagt, er liebe mich, um mich und meine Familie damit zu kraenken?"
+Sie drehte eine weitere Runde um den Teich.
+
+"Maenner!", fluchte Polly mit Elan. "So sind sie doch alle: Hinterlistige,
+heuchlerische, halbseidene Hazardeure!" Sie kramte in ihrer Handtasche nach
+einer flachen Flasche. "Da hilft nur noch Medizin."
+
+Azzuro, der den Geruch von Pollys Medizin genuesslich einsog, haette ihr sogar
+die Schmaehung aller Maenner vergeben, wenn sie ihm nur ein paar Tropfen
+abgegeben haette.
+
+"Nichts da!" Julia schlug Polly die Flasche aus der Hand. "Im Hals soll dir
+das Zeug stecken bleiben, weil du Romeo so etwas nachsagst."
+
+Bedauernd schauten Azzuro und Polly auf die Flasche, die ihren kostbaren
+medizinischen Inhalt an ein paar Wuermer verteilte. "Du kannst doch nicht
+sagen, dass der Mann, der deinen Vetter umgebracht hat, ein anstaendiger
+ist.", meinte Polly verstaendnislos.
+
+"Immerhin ist er mein Ehemann.", wies Julia ihre Amme zurecht. "Und wenn ich
+mich nicht sehr taeusche, wird Romeo schon einen Grund gehabt haben." Sie
+ueberlegte und ihr Gesicht hellte sich auf. "Natuerlich, so wird es gewesen
+sein! Notwehr! Tybalt wollte meinen Romeo umbringen und Romeo hat sich nur
+gewehrt." Befriedigt ueber diese Lesart hob Julia die Flasche wieder auf und
+reichte sie Polly, die den Rest der Medizin in sich hineinschuettete.
+
+Julia sah nachdenklich auf Azzuro, der sich mit den Wuermern um die kleine
+Pfuetze stritt. "Viel schlimmer ist eine andere Sache. Romeo ist verbannt
+worden. Jetzt bin ich kaum drei Stunden verheiratet, aber meine Hochzeitsnacht
+bekomme ich nicht."
+
+Ulo konnte Julias Gesichtsausdruck nicht deuten. "So schlimm ist das nun auch
+wieder nicht."
+
+"Doch." Azzuro wusste wohl, dass Julia weniger darunter litt, dass ihre
+Eheschliessung jetzt nichtig zu sein drohte. "Sie hat Ovid gelesen."
+
+"Metamorphosen?", fragte Ulo.
+
+"Ars amandi."
+
+"Oh." Ulo war erstaunt.
+
+"Wo sind eigentlich meine Eltern?", fragte Julia.
+
+"Sie halten bei Tybalt die Totenwache. Ich kann dich hinbringen, allerdings
+solltest du dir vorher ein frisches Taschentuch holen."
+
+"Nein, es reicht, wenn sie Heulen und Zaehneknirschen demonstrieren, ich
+brauche da nicht mitzumachen. Ausserdem muesste ich mich zur Haelfte
+verstellen." Julia straffte die Schultern. "Ich gehe auf mein Zimmer und warte
+auf mein Ende."
+
+"Dafuer bist du noch zu jung, Kind. Es wird wohl noch eine Weile dauern."
+
+"Wenn Romeo meine Jungfraeulichkeit nicht bekommt, dann auch kein anderer als
+Tod, der ohnehin am Ende alles bekommt."
+
+"HM?", fragte eine dumpfe Stimme aus dem Schatten der Gartenmauer.
+
+"Nicht jetzt." Ulo scheuchte Tod davon.
+
+Polly, die Julias Blaesse missverstand und als Suizidabsicht deutete, ueber-
+legte angestrengt. "Dann gibt es wohl keine andere Moeglichkeit, als dass ich
+Romeo herbeischaffe. Er hat sich bei Bruder Lawrence versteckt."
+
+"Warum hast du das nicht eher gesagt?" Julia riss sich den Ring vom Finger,
+den sie gerade erst von Romeo bekommen hatte. "Bring ihm den Ring und sag ihm,
+dass er ihn mir wiedergeben soll."
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite17 b/d/seher/haeuser/special/special/rom_jul/seite17
new file mode 100644
index 0000000..7dd816e
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite17
@@ -0,0 +1,150 @@
+DER DRITTE AKT
+ DIE DRITTE SZENE
+
+Bruder Lawrence, der nicht weniger neugierig war als andere, hatte sich auf
+dem Marktplatz herumgetrieben, bis er von Romeos Verbannung hoerte. Nun rannte
+er, so schnell ihn seine Beine tragen wollten zu seiner Kapelle zurueck. Als
+er sie voellig ausser Atem erreichte, fand er Romeo, der das Gesicht in den
+Haenden vergraben hielt.
+
+"Romeo!" Lawrence bueckte sich stoehnend zu seinem Freund herunter. "Hast...
+bist... wirst...?" Er schnaufte.
+
+Romeo sah ihn mit trueben Augen an. "Dreimal ja."
+
+Verwirrt runzelte Lawrence die Stirn.
+
+Ein duennes Laecheln huschte ueber Romeos Gesicht, sah seine gefurchte Stirn,
+betrachtete die rastlos knetenden Haende und machte sich von dannen. "Ich habe
+Tybalt erstochen, ich bin geflohen und ich werde mich aufhaengen lassen.
+Dreimal ja, also."
+
+"Wer redet denn hier von Aufhaengen?"
+
+"Ich werde nicht davonkommen, weisst du. Escalus hat ziemlich deutlich
+gemacht, was er von Randale in den Strassen haelt."
+
+"Doch, doch.", beruhigte Bruder Lawrence ihn "Du kommst schon davon. Escalus
+war der Ansicht, dass er Tybalt ohnehin haette haengen muessen, weil er vorher
+Mercutio umgebracht hat. Jetzt verurteilt er dich nur zur Verbannung, weil du
+ihm vorgegriffen hast."
+
+Romeos Augen weiteten sich. "Verbannung? Das ist ja noch schlimmer!"
+
+"Unsinn. Wenigstens bleibst du am Leben."
+
+"Und was fuer ein wunderbares Leben das ist." Romeo knirschte vor Verbitterung
+mit den Zaehnen. "Ich muss Verona verlassen und Julia bleibt hier."
+
+"Wenn schon? Du lebst, sie lebt: Was willst du mehr?"
+
+"Bei ihr sein."
+
+"Sei nicht undankbar, Junge." So war Romeo schon lange nicht mehr von Bruder
+Lawrence bezeichnet worden. "Selbst wenn du Verona verlassen musst, bist du
+immer noch jung genug. Du lebst und kannst in Ruhe abwarten, was sich weiter
+ergibt. Vielleicht kannst du eines Tages ja zurueckkommen."
+
+"Eher ist die Erde eine Scheibe."
+
+Bruder Lawrence, der, fest im Dogma verankert, solch ketzerische Gedanken
+nicht von seinem Schuetzling hoeren wollte, warf verzweifelt die Haende in die
+Luft. "Das ist sie."
+
+Romeo lachte gackernd. "Natuerlich."
+
+"Romeo, reiss dich zusammen. Es ist noch nicht aller Tage Abend."
+
+"Doch, das ist es. Ohne Julia ist immer Nacht, ohne sie gibt es keine Sonne."
+
+"Ulo, reich mir einen Lappen, Romeo trieft.", fluesterte Azzuro.
+
+"Vor Traenen?"
+
+"Vor Schmalz."
+
+Ulo beachtete ihn nicht weiter, sondern rieb sich den Schnabel an einem Blatt.
+
+Auch Romeo wischte sich die Traenen ab. "Verbannung ist deshalb schlimmer als
+Haengen, weil ich dann jeden Tag daran denken muss, dass Julia hier ist.
+Selbst ihr Schosshund ist besser dran als ich, weil er in ihrer Naehe sein
+kann. Das ist ein Baerendienst, den Escalus und du mir erweisen, Bruder
+Lawrence."
+
+"Ich?" Lawrence war ehrlich entsetzt.
+
+"Du bringst mir die Nachricht, oder?"
+
+Ein Klopfen bewahrte Bruder Lawrence vor den Vorwuerfen, die Romeo noch auf
+den Lippen hatte.
+
+"Geh nach hinten, Romeo, ich will nachsehen, wer da ist."
+
+Romeo hatte sich auf dem Boden zusammengerollt und schluchzte still vor sich
+hin.
+
+"Romeo!", zischte Bruder Lawrence. Er wandte sich zur Tuer. "Einen Moment
+noch!" Verzweifelt blickte er zwischen der Tuer und Romeo hin und her. "Wer
+ist denn da?"
+
+Polly trat wuetend gegen die Tuer. "Ich bringe eine Nachricht von Julia."
+
+Romeo schaute auf.
+
+Lawrence oeffnete die Tuer und verdeckte mit seiner Leibesfuelle Romeo. Als er
+Polly erkannte, seufzte er. "Was gibt es?"
+
+"Erst muss ich wissen, wo Romeo ist."
+
+Lawrence trat zur Seite. "Sammeln Sie ihn auf.", schlug er vor und deutete auf
+das Haeufchen Elend zu seinen Fuessen.
+
+Polly schuettelte den Kopf. "Sowas Dummes aber auch! Jetzt stecken Julia und
+Sie im gleichen Schlamassel. Aber das ist vergossene Milch, jetzt kneifen Sie
+den A... Reissen Sie sich zusammen, meine ich natuerlich."
+
+Romeo versuchte es und scheiterte knapp.
+
+"So sieht ein braver Romeo aus.", lobte Polly. "Es ist noch nicht aller Tage
+Abend, mein Junge."
+
+"Meine Rede.", fuegte Lawrence laechelnd hinzu.
+
+"Was macht Julia?", wollte Romeo wissen.
+
+"Was soll sie schon tun? Sie weint und verflucht Sie und dann weint sie wieder
+und..."
+
+"Ich kann es ihr nicht verdenken. Aber wenn selbst sie mich verflucht..." Er
+brach ab und riss sein Messer heraus. "Dann sag ihr, dass ich mit ihrem Namen
+auf den Lippen sterben will!"
+
+Polly ohrfeigte ihn, das Messer flog in eine Ecke und Romeo in die andere.
+
+Bruder Lawrence, dessen Ueberzeugung ihm das gleiche Argument verbot, setzte
+zu einer Predigt an. "Du bist wirklich ein Volltrottel, Romeo. Erst ueberlebst
+du, obwohl Tybalt wahrscheinlich der bessere Fechter ist. Da hast du Glueck."
+Er schlug Romeo das Wort um die Ohren. "Escalus bestraft dich nicht fuer Mord,
+sondern fuer Selbstjustiz. Da hast du Glueck. Julia trauert um ihren Vetter,
+aber Polly ist bestimmt nicht hier, um dir zu sagen, dass sie dich nicht mehr
+sehen will. Da hast du Glueck."
+
+Polly nickte. "Allerdings. Hier ist dein Ring, Romeo."
+
+"Julia gibt ihn mir zurueck?" Romeo begann laut zu jammern.
+
+"Du sollst ihn ihr noch einmal geben, Trottel." Lawrence schlug die Haende
+zusammen ueber soviel Unverstand. "Morgen reist du ab und wartest in..." Er
+ueberlegte. "Sagen wir, Mantua, bis Polly und ich Gelegenheit haben, allen
+Leuten von Julias und deiner Ehe zu erzaehlen. Dann kommst du zurueck und wenn
+ihr nicht sterbt, lebt ihr gluecklich bis zu eurem Ende." Er wandte sich an
+Polly. "Geh zu Julia und sag ihr, dass Romeo kommt. Er weiss es zwar noch
+nicht, aber er kommt." Wieder fiel sein Blick auf Romeo. "So, jetzt hoer mir
+mal zu, Junge..."
+
+Azzuro stiess Ulo an. "Komm, das Gewitter will ich nicht miterleben."
+
+"Welches Gewitter?", fragte Lawrence scheinheilig.
+
+Die Turtelkraehen machten sich ebenso schnell aus dem Staub wie Polly.
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite18 b/d/seher/haeuser/special/special/rom_jul/seite18
new file mode 100644
index 0000000..bbe686f
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite18
@@ -0,0 +1,53 @@
+DER DRITTE AKT
+ DIE VIERTE SZENE
+
+Capulet und Paris sassen sich bei einem Glas Wein gegenueber. "Es tut mir
+wirklich leid, dass Julia heute abend nicht mehr zu uns kommt. Sie ist sehr
+aufgebracht." Er wiegte den Kopf. "Ich hatte noch keine Gelegenheit, ihr
+klarzumachen, dass sie dich heiraten wird."
+
+"Er klingt, als sei ihm Tybalts Tod voellig egal.", stellte Ulo fest.
+
+"Er ist ein homo politicus."
+
+"Solche Worte sagst du nicht in meinem Beisein, Azzuro!", verlangte Ulo
+entruestet.
+
+Azzuro schnappte nach Luft, schwieg aber.
+
+"Unglueckliche Umstaende sind das.", beklagte sich Paris. "Ich haette gerne
+ein bisschen Zeit mit ihr verbracht."
+
+Frau Capulet laechelte. "Keine Sorge, ich werde morgen frueh mit ihr reden und
+Julia wird mir sagen, dass sie sich auf ihre Hochzeit freut." Ihr Gesicht
+liess keinen Zweifel daran, dass Julia sich lieber freuen sollte. "Heute abend
+waere es sicherlich ein wenig..." Sie zoegerte. "...unpassend, sie zu stoeren,
+aber morgen sieht alles schon wieder anders aus."
+
+Herr Capulet nickte. "Ja, morgen sieht alles anders aus. Ich denke, wir
+sollten nur eine kleine Feier ausrichten, um eure Hochzeit zu feiern. Waere
+dir Mittwoch recht, Paris?"
+
+"Heute ist Montag, ist das nicht ein bisschen schnell?", wandte Paris ein.
+
+"Ja, drei Trauertage sollten wir einhalten, schliesslich soll Tybalt erst
+beerdigt sein. Also Donnerstag. Und was die Feier angeht, so werden die Leute
+reden, wenn wir mehr als ein halbes Dutzend Gaeste einladen."
+
+"Wir koennen ja die grosse Feier spaeter ausrichten." Frau Capulet wollte sich
+die Gelegenheit, Stiche in ihrer Bekanntschaft auszuteilen, nicht entgehen
+lassen.
+
+Herr Capulet sah nach draussen. "Spaeter, ja. Und jetzt ist es so spaet, dass
+ich fast schon wieder aufstehen muss. Also: Donnerstag sehen wir uns zur
+Hochzeit und Julia ueberlass getrost mir, Paris."
+
+Ulo schniefte. "Als ob Julia eine Kuh waere, die er zum Decken weggibt."
+
+"Ist sie doch.", meinte Azzuro. "In seinen Augen, meine ich.", fuegte er
+schnell hinzu, als er Ulos Blick auffing.
+
+"Und seine Frau macht mit."
+
+Azzuro nickte nur betruebt.
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite19 b/d/seher/haeuser/special/special/rom_jul/seite19
new file mode 100644
index 0000000..e856818
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite19
@@ -0,0 +1,252 @@
+DER DRITTE AKT
+ DIE FUENFTE SZENE
+
+Julia kuschelte sich in Romeos Arme und liess den Blick durch ihr Zimmer
+schweifen. Bevor Romeo zu ihr kam, hatte sie eilig ihre Puppen versteckt und
+sogar ihre Heiligenbilder von der Wand genommen. Jetzt sah ihr Zimmer eher wie
+das einer Frau aus. Sie fuehlte sich so wohl, dass sie am liebsten geschnurrt
+haette.
+
+Julia kitzelte Romeos Nase mit einer Straehne ihres Haares und beobachtete,
+wie sie zuckte. Schlaefrig wischte Romeo sich mit der Hand darueber.
+
+Vor dem Fenster zog Ulo gerade den Kopf aus dem Gefieder und stiess Azzuro an.
+"Sie wachen auf."
+
+Azzuro murmelte und versuchte, sich die Augen mit dem Fluegel zuzuhalten.
+
+Romeo schlug die Augen auf und linste aus dem Fenster. "Ich hoere eine
+Lerche."
+
+Julia schuettelte den Kopf. "Das war bestimmt eine Nachtigall. Guck, die
+Kraehen da draussen schlafen auch noch, obwohl sie sonst immer mit die ersten
+sind, die aufwachen."
+
+Zweifelnd blickte Romeo auf und begegnete Ulos Blick. "Die Kraehe da sieht
+aber ziemlich wach aus. Also war es doch die Lerche."
+
+Ulo plinkerte mit den Augen, um auch die letzten Reste des Schlafes zu
+vertreiben.
+
+"Sie hat nur getraeumt. Jetzt sind ihre Augen wieder zu und es war die
+Nachtigall."
+
+Azzuro streckte sich und klapperte mit dem Schnabel. "Da." Romeo zeigte mit
+dem Finger. "Jetzt ist die andere auch noch wach." Als er sah, dass Julia mit
+dem Kinn zitterte, streichelte er ihre Wange. "Schon gut, schon gut. Wenn du
+es gerne moechtest, ist es noch Nacht und die beiden da sind Fledermaeuse."
+
+"Wasss issst?", fragte Wlad.
+
+"Nichts.", versetzte Azzuro muerrisch. "Geh schlafen."
+
+Wlad zuckte die Schultern und verschwand unter der Dachrinne.
+
+Julia, die Wlad beobachtet hatte, stoehnte. "Leider geht die Fledermaus gerade
+schlafen. Wahrscheinlich ist es doch Morgen und du solltest gehen, sonst
+erwischen dich noch Escalusens Leute und du wirst aufgehaengt."
+
+"Es kann aber doch nicht Morgen sein. Du hast gerade gesagt, dass es noch
+Nacht ist.", noergelte Romeo.
+
+"Und jetzt sage ich, dass es Morgen ist."
+
+Romeo murmelte etwas darueber, dass Frauen nicht wissen, was sie wollen, stand
+aber gehorsam auf und zog sich an.
+
+"Ich moechte dich nicht gehen lassen."
+
+"Ich will ja auch nicht gehen. Aber..." Er brach ab.
+
+"Eben: Aber." Julia grabbelte auf dem Nachttisch nach einem Taschentuch.
+
+"Wenn sie jetzt sagt, dass ihre Herzen immer beieinander sind, hacke ich ihr
+die Augen aus.", brummte Azzuro.
+
+Julia laechelte unter Traenen. "Weisst du, unsere Koerper moegen zwar getrennt
+sein, aber..."
+
+Ulo sprang auf Azzuros Ruecken und hielt ihn fest.
+
+"Eben: Aber.", versetzte Romeo.
+
+Polly steckte den Kopf zur Tuer herein. "Es wird gleich hell. Ausserdem ist
+deine Mutter hierher unterwegs, Julia."
+
+Romeo, der schon auf der Strickleiter stand, reckte sich Julia entgegen.
+"Komm, gib mir noch einen Kuss."
+
+Julia grabschte ein hilfloses Holzpferdchen, das sich nicht rechtzeitig mit
+den anderen Spielsachen im Schrank versteckt hatte und kuesste es herzhaft.
+"Hier, das Pferd bekommt ganz viele Kuesse mit, dann hast du welche auf
+Vorrat." Sie reichte Romeo das Pferdchen.
+
+Romeo laechelte. "Ich komme zurueck, bevor sie alle aufgebraucht sind."
+
+"Wohl hoere ich der Botschaft Wort, allein, mir fehlt der Glaube.", meinte
+Julia.
+
+"Ich hasse diese falsche Zitiererei.", knurrte Azzuro.
+
+"Noch ist Polen nicht verloren." Romeo zwinkerte Julia aufmunternd zu.
+
+"Trotzdem, etwas ist faul..."
+
+"KRAH!", schrie Azzuro mit Nachdruck.
+
+"Siehst du, jetzt ist Morgen." Romeo winkte. "Ich schreibe dir."
+
+Julia winkte, bis Romeo ueber die Gartenmauer verschwunden war, dann kletterte
+sie von der Fensterbank und wandte sich ihrer Mutter zu.
+
+Frau Capulet, die offenbar gehofft hatte, Julia noch schlaftrunken und wenig
+widerspenstig anzutreffen, verzog das Gesicht, als sie ihre Tochter sah. "Du
+bist reichlich frueh auf."
+
+"Ich konnte nicht schlafen."
+
+"Haette sie auch gar nicht gewollt." Azzuro kicherte in sich hinein.
+
+"Du trauerst um Tybalt, hm?" Frau Capulet strich Julia ueber das Haar. "Du
+solltest dich nicht so sehr graemen."
+
+"Ich habe einen Menschen verloren, der mir sehr viel bedeutet." Julia
+schniefte.
+
+"Und ob sie das hat." Ulo wand sich vor unterdruecktem Lachen.
+
+"Du solltest nicht mehr um Tybalt weinen, das macht ihn nicht wieder lebendig.
+Eher weinte ich, weil dieser Romeo noch lebt."
+
+"Es waere gut, wenn ich Romeo gleich jetzt in meinen Haenden haette." Julia
+verbarg ihr Lachen hinter einem umstaendlichen Naseputzen.
+
+"Das laesst sich leider nicht machen. Allerdings werde ich dafuer sorgen, dass
+er auch im Exil nicht lange ueberlebt, glaub mir."
+
+Julia nickte ernsthaft. "Wenn ich nur wuesste, wie ich es anstellen soll, dann
+sorgte ich dafuer, dass Romeo bald eine ewige Ruhe findet."
+
+"Wenn Julia das in die Hand nimmt, kann Romeo allerdings ruhig schlafen.",
+meinte Azzuro.
+
+"Ihre Mutter merkt aber auch gar nichts, hm?" Ulo lehnte sich zurueck und
+genoss Julias spitze Zunge.
+
+Frau Capulet laechelte. "Das ist der rechte Geist, Julia. Wenn du so weiter
+machst, wirst du die Capulets wuerdig vertreten."
+
+"ZERtreten will ich sie." Julia stampfte mit dem Fuss auf. "Meine Feinde,
+natuerlich."
+
+"Natuerlich.", stimmte ihre Mutter zu. "Ich habe uebrigens eine gute Nachricht
+fuer dich."
+
+"Gibt es gute Nachrichten, wenn ein geliebter Mensch unerreichbar ist?"
+
+"Jetzt traegt sie zu dick auf." Azzuro schuettelte den Kopf.
+
+"Dein Vater meint, dass das Leben weitergehen muss. Er hat beschlossen, dass
+du Paris heiratest. Gleich am Donnerstag."
+
+Julia wurde kreidebleich. "Das ist ja schon uebermorgen! Das geht mir zu
+schnell."
+
+"Unsinn." Frau Capulet runzelte unwillig die Stirn. "Aber warte nur, bis dein
+Vater das hoert."
+
+Herr Capulet kam ins Zimmer und schuettelte den Kopf. "Heulst du denn immer
+noch, Julia? Hat deine Mutter dir nicht gesagt, dass du allen Grund zur Freude
+hast?"
+
+Julia schluchzte noch lauter.
+
+"Sie will Paris nicht heiraten.", klaerte Frau Capulet ihren Mann auf. "Es
+geht ihr zu schnell, sagt sie."
+
+In Herrn Capulet erwachte der Jaehzorn, den in seiner Jugend buchstaeblich die
+halbe Stadt gefuerchtet hatte. "Was? Paris ist ein guter Mann und eine
+hervorragende Partie. Und du willst nicht?" Sein Geschrei erklomm neue Hoehen.
+"Du wirst den Mann heiraten, den ich dir nenne, hast du mich verstanden? Und
+wenn ich dich an den Haaren zur Kirche zerre, du heiratest Paris!"
+
+"Aber, aber." Frau Capulet beobachtete besorgt die pochende Ader an der
+Schlaefe ihres Mannes und sah sich dem Witwenstand naeher als ihr lieb war.
+"Reg' dich nicht so auf."
+
+Julia erkannte, dass ihr Vater jenseits aller Vernunft war. "Lass mich doch
+erklaeren..."
+
+"Ich soll mich nicht aufregen? Nicht aufregen?" Er rang nach Luft. "Meine
+Tochter will, dass ich mein Wort nicht halte, zieht meinen guten Namen in den
+Schmutz und bringt mich vor der ganzen Stadt in Verruf - und ich soll mich
+nicht AUFREGEN?"
+
+Polly, die wusste, dass er gleich anfangen wuerde zu fluchen, stellte sich
+schuetzend vor Julia. "Lasst sie doch reden."
+
+"Reden? Ihr redet mir alle drei schon zuviel. Da ist ein gutaussehender Mann,
+erfolgreich, nett, der Julia alles bieten kann und einen anstaendigen
+Brautpreis zahlt... Und meiner Tochter faellt nichts besseres ein, als mir
+vorzuheulen, dass sie ihn nicht will. Was meinst du eigentlich, dass diese
+Maenner auf den Baeumen wachsen?"
+
+Ulo blickte auf Azzuro und schuettelte den Kopf. "Da hat er leider Recht."
+
+Herr Capulet schuettelte den Kopf wie ein Stier, der dem roten Tuch hinterher
+schaut. "Ich will dir mal was sagen, Julia: Entweder heiratest du Paris oder
+du kannst sehen wo du bleibst." Er drehte sich um und stapfte zur Tuer. "Ich
+dachte eigentlich, dass ich von Glueck reden kann, wenigstens ein Kind zu
+haben, wenn schon keinen Sohn, aber wenn ich mir dich so ansehe, Julia, frage
+ich mich, ob ich dich nicht besser gleich nach der Geburt ersaeuft haette."
+
+Julia zuckte zusammen, als die Tuer hinter ihrem Vater ins Schloss schepperte.
+"Mama?"
+
+Frau Capulet seufzte und stiess dann in das Horn ihres Mannes, wie sie es ihre
+ganze Ehe lang getan hatte. "Nein, nicht Mama. Sag, dass du Paris heiratest,
+dann kannst du auch wieder Mama sagen."
+
+"Wenn es das ist, was du willst, dann kannst du mich auch gleich neben Tybalt
+begraben!"
+
+Die Tuer flog ein zweites Mal mit lautem Knall zu. Julia trat verzweifelt
+dagegen. "Was soll ich jetzt bloss tun? Polly, hast du keine Idee? Ich kann
+doch nicht Paris heiraten!"
+
+"Und warum nicht?" Polly fand es leichter, sich vom Sturm vorwaerts blasen zu
+lassen, als sich gegen ihn zu stemmen. "Er ist bestimmt kein schlechter Mann.
+Dein Vater hat schon Recht: Er sieht besser aus als Romeo, hat einen besseren
+Ruf, ist nicht mit deiner Familie verfeindet und ausserdem ist er hier. Was
+willst du mehr?"
+
+Julia starrte ihre alte Vertraute unglaeubig an. "Auch du, meine Amme Polly?"
+
+Azzuro stoehnte.
+
+Polly hob hilflos die Haende. "Wir wollen alle nur dein bestes."
+
+"Das bekommt ihr aber nicht.", murmelte Julia.
+
+"Was sagst du?"
+
+"Ich sagte, dass ich zu Bruder Lawrence gehen will. Wenn ich heiraten soll,
+dann muss er mich auf eine wahrhaft christliche Ehe vorbereiten." Julia setzte
+ein falsches Laecheln auf.
+
+Polly traute dem ploetzlichen Frieden nicht ganz, zuckte aber die Schultern.
+"Das ist gut. Ich werde deiner Mutter sagen, dass du dich bessern willst." Sie
+ging und sah nicht, wie sich Julia weinend auf ihr Bett warf.
+
+
+Hier stehen sie nun, unsere Akteure. Julia weint sich die Augen aus dem
+Gesicht, weil sie sich nicht offen zu Romeo bekennen darf, Julias Mutter
+stellt den haeuslichen Frieden ueber das Glueck ihres Kindes, Polly ist
+wetterwendisch, Romeo verbannt, Paris sieht der Rettung fuer seinen allzu
+leeren Geldbeutel entgegen und Bruder Lawrence ist in einer boesen Zwangslage.
+
+Wie gerne, liebe Leserin, lieber Leser, versaehe ich die Geschichte mit einem
+gluecklichen Ende. Doch die Goetter der Mythenwelt haben es anders bestimmt
+und wuerzen unsere Geschichte mit unendlichen Schwierigkeiten. Es scheint, als
+haetten Romeo und Julia die Goetter veraergert.
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite2 b/d/seher/haeuser/special/special/rom_jul/seite2
new file mode 100644
index 0000000..7c4ffd4
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite2
@@ -0,0 +1,86 @@
+PROLOG
+Wir befinden uns in Verona. Stellen Sie sich die Stadt vor. Koennen Sie nicht?
+Gut, fangen wir am Anfang an, so, wie es sich gehoert.
+
+Eigentlich befinden wir uns in einem Zeitalter, dem man spaeter irgendeinen
+gelehrten und eigenartig klingenden Namen geben wird, aber das tut hier nichts
+zur Sache, denn wie es sich fuer eine Geschichte ziemt, ist die Zeit ohnehin
+die Gute Alte. Das heisst nicht, dass es in irgendeiner Weise besser und
+schoener waere, als es heute ist, es bedeutet lediglich, dass sie unseren
+Traeumen entspricht. Sie ist mythisch und somit jenseits aller Kritik.
+
+Stellen wir uns also Verona vor, wie die Stadt in der guten alten Zeit
+ausgesehen haben mag. Die Strassen sind sauber, so sauber, dass man von ihnen
+essen koennte. Womit ich nicht unterstellen will, dass Sie zu den Menschen
+gehoeren, die auf solche Gedanken kommen. Im Gegensatz zu aller Ueberlieferung
+und allen historischen Erkenntnissen sind die Gossen nicht schmutzig und
+niemand giesst aus den Fenstern des ersten Stocks eine unaussprechliche, aber
+im Grossen und Ganzen braune und gelbe Masse. Und bitteschoen, die Haeuser
+beugen sich nicht wie verhutzelte alte Leute ueber die Strassen und betrachten
+die Menschen mit dem arroganten Gesichtsausdruck, den ein Autor eines anderen
+Genres ihnen andichten wuerde. Das genaue Gegenteil ist der Fall. Die Mauern
+sind weiss, die Fenster sauber geputzt, die Gardinen frisch gewaschen und
+bunte Kaesten mit noch bunteren Blumen zieren die Fensterbaenke, die genauso
+frisch geputzt sind wie die Strassen. Ja, Sie haben richtig gehoert: In der
+guten alten Zeit putzten anstaendige Menschen sogar die Fensterbaenke. Sie
+haetten wahrscheinlich auch die Daecher geputzt, wenn ihre Arme lang genug
+gewesen waeren - fragen Sie die aelteren Menschen in ihrem Dorf, wenn Sie mir
+nicht glauben.
+
+Womit wir beim Thema Leute sind. Haben Sie bemerkt, wie geschickt ich die
+Ueberleitung gemacht habe? Wir befinden uns in einer mythischen Zeit, also
+koennen Sie sich die Menschen sicherlich vorstellen. Keine Frau, die sich dort
+mit Problemen wie Falten und Orangenhaut herumschluege, kein Mann, dessen Bart
+nicht dicht genug waere oder dessen Muskeln zu unentwickelt. Nein, meine Damen
+und Herren, hier ist Verona. Eigentlich sollte ich VERONA schreiben. Oder
+wenigstens _Verona_, wenn Ihnen die Grossbuchstaben zu pompoes sind. Jede
+einzelne der Frauen verdiente sich heute eine goldene Nase als Model, so
+perfekt ist ihre Figur, so ebenmaessig ihr Gesicht, so dezent ihr Make-up.
+Ihre Hautfarbe ist allerdings heute nicht mehr en Vogue, aber das ist nichts,
+dem nicht ein Nachmittag auf der Sonnenbank abhelfen koennte. Und die Maenner!
+Haben Sie eine Ausgabe von Capital zur Hand? Schauen Sie hinein und suchen Sie
+sich den attraktivsten Mann heraus. Haben Sie? Gut. Nun ziehen Sie ihm diesen
+grausigen Anzug aus und stecken Sie ihn in eine zweifarbige Strumpfhose. Dazu
+verpassen Sie ihm noch ein bauschiges Rueschenhemd. Und streichen Sie um
+Gottes Willen dieses schreckliche Handy!
+
+So also sehen die Menschen Veronas aus. Zumindest die, um welche wir uns in
+dieser Geschichte kuemmern wollen. Sie fragen nach den anderen? Aber, liebe
+Leserin, lieber Leser, wer fragt in einer Geschichte, die in mythischer Zeit
+spielt, nach den Namenlosen? Oder gehoeren Sie zu denen, die einen
+historischen Film mit vielen Statisten nur anschauen, um den unaufmerksamen
+Studenten zu finden, der sich schnell ein paar Mark verdienen wollte und in
+der Aufregung vergass, die Uhr auszuziehen? Wie profan, liebe Leserin, lieber
+Leser. Aber gut, wenn Sie es gar nicht anders haben wollen, fuegen wir hier
+noch ein paar Statisten ein und geben der Szene noch ein wenig Lokalkolorit.
+
+Sicherlich erkennen Sie die Dame, die dort auf dem Markt steht. Sie ist
+rundlich, traegt eine weisse Schuerze ueber dem weiten Rock und eine weisse
+Bluse, die huebsch mit ihrem roten Bustier kontrastiert. Sie hat apfelrote
+Wangen und ein freundliches Laecheln, bei dem weisse Zaehne blitzen. Nein, die
+Dame ist nicht die Gewinnerin eines Zahnpasta-Werbefilms, sie ist die
+Gemueseverkaeuferin. Sie handelt unter anderem mit AEpfeln und ist die
+Urheberin des Spruches: Damit Ihr auch morgen noch kraftvoll zubeissen koennt,
+Euer Exzellenz. Der Name dieser Frau ist in den Tiefen der Historie ertrunken,
+sonst fuehrten ihre Erben bis heute einen Kampf um das Urheberrecht an ihrem
+Werbeslogan.
+
+Selbstverstaendlich wollen wir ein moeglichst authentisches Bild entwerfen,
+daher fuegen wir nun auch noch die dunkle Gestalt am anderen Ende des Platzes
+ein. Wie Sie sich schon gedacht haben, handelt es sich bei diesem Mann um
+einen Dieb. Er hat nur fuer diesen Absatz seinen Urlaub auf der Ferieninsel
+der Mythen unterbrochen, also zollen Sie ihm gebuehrende Aufmerksamkeit. Sehen
+Sie, er winkt. Winken wir zurueck und lassen ihn seinen wohlverdienten Urlaub
+fortsetzen.
+
+Moment, was hat der dicke, sonnenverbrannte Mann im Hawaiihemd mit der Kamera
+da zu suchen? Halten Sie bitte einen Augenblick mit dem Lesen inne, ich
+schaffe ihn eben dorthin zurueck, wo er herkam.
+
+Danke, Sie koennen jetzt weiterlesen.
+
+Bevor Sie danach fragen, will ich Ihnen erklaeren, was es mit den beiden
+Kraehen auf sich hat, die auf der Winde des huebschen Brunnens in der
+Platzmitte sitzen. Es sind Turtelkraehen. Ihre Namen sind Ulo und Azzuro und
+Sie werden die beiden noch besser kennenlernen.
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite20 b/d/seher/haeuser/special/special/rom_jul/seite20
new file mode 100644
index 0000000..d51d595
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite20
@@ -0,0 +1,201 @@
+DER VIERTE AKT
+ DIE ERSTE SZENE
+
+Bruder Lawrence betrachtete Paris mit Unwillen. "Donnerstag? Julia?"
+
+Paris nickte. "So will es ihr Vater."
+
+"Das ist sehr kurzfristig." Er wiegte seinen Kopf hin und her. "Ich weiss
+nicht, ich weiss nicht."
+
+"Was wissen Sie nicht?" Paris zog die Stirn in Falten.
+
+"Na, so kurz nach dem Tod ihres Vetters... Mir kommt das ein wenig, wie soll
+ich sagen, spanisch vor."
+
+"Julias Vater ist entschlossen. Er meint, dass Tybalts Tod sie mehr
+beunruhigt, als gut fuer sie ist. Ausserdem braucht er wohl einen neuen Mann
+in den Reihen seiner Familie."
+
+"Als haetten nicht die Montagues auch einen Verlust, schliesslich ist Romeo
+nicht mehr in Verona."
+
+"Was fuer ein Problem fuer unseren kleinen Priester, hm?", murmelte Azzuro
+leise.
+
+"Wenn ihm nicht schnell etwas einfaellt, muss er Julia zweimal verheiraten. Ob
+sein Gott das mag?" Ulo fluesterte nur, doch Lawrence hatte sie gehoert und
+drohte ihr mit dem Finger.
+
+"Was sagt Julia selbst dazu?", fragte er Paris.
+
+"Ich habe noch nicht mit ihr gesprochen."
+
+"Nicht, dass sich irgendjemand darum kuemmerte.", raunte Ulo dem Moench zu.
+
+Bruder Lawrence nickte bedaechtig. "Es gefaellt mir nicht, ein Maedchen zu
+verheiraten, dass ueberhaupt nicht will."
+
+"Ich habe nicht gesagt, dass sie nicht will."
+
+"Das hat mir ein Voeglein ins Ohr gefluestert." Lawrence deutete auf Ulo.
+
+Paris, der einem Franziskaner nahezu alles zutraute, sah Ulo an und versuchte,
+den Ausdruck Voeglein mit der riesigen Kraehe in Einklang zu bringen. "Ich bin
+sicher, Ihr Voeglein hat der Nachricht Gewicht verliehen.", meinte er
+diplomatisch.
+
+Bruder Lawrence rieb sich mit der Hand ueber die Augen und sah den Huegel
+hinunter. "Taeusche ich mich, oder kommt da Julia?"
+
+Paris laechelte Julia zu. "Wie gut, dass du kommst, Lieblingsbraut. Wir
+sprachen gerade von dir."
+
+"Das kann ich mir denken.", antwortete Julia unterkuehlt.
+
+"Lieblingsbraut?" Azzuro kraechzte vergnuegt. "Ob er noch mehr davon hat?"
+
+"Wahrscheinlich nicht, sonst liesse er Julia in Frieden." Ulo war beeindruckt
+von Julias Haltung.
+
+"Ich haben gerade den Termin fuer die Hochzeit ausgemacht."
+
+"Muss das sein?" Julia verdrehte die Augen.
+
+"Natuerlich muss ich."
+
+"Warum geht er dann nicht hinter die Buesche?", murmelte Ulo.
+
+"Wenn es denn gar nicht anders geht."
+
+Paris, der annahm, Julia wollte sich vor der Hochzeit von Bruder Lawrence
+beraten lassen, laechelte freundlich. "Sag einfach Bruder Lawrence, dass du
+mich liebst, dann ist alles in Ordnung."
+
+"Wenn ich alles so einfach in Ordnung bringen koennte, indem ich sage, dass
+ich ihn liebe." Julia seufzte.
+
+"Na, jetzt wird ihre Zunge wieder spritziger." Ulo freute sich auf einen
+Disput mit Paris.
+
+Paris verzog sein Gesicht zu einem duemmlichen Laecheln. "Ich bin sicher, dass
+du mich liebst."
+
+"Eitler Pfau!", schnaubte Ulo veraechtlich.
+
+"Wenn du es sagst, Paris.", meinte Julia.
+
+"Sie uebt schon fuer die Zeit nach der Hochzeit." Ulo kannte den Trick, so
+lange Ja zu sagen, bis der andere sich eine Sache anders ueberlegte nur zu
+gut.
+
+"Jetzt tut mir Paris fast leid." Auch Azzuro hatte mit dieser Methode bereits
+Bekanntschaft geschlossen.
+
+Paris kuesste Julia zuechtig auf die Wange. "Am Donnerstag bekommt du den
+grossen Bruder von diesem Kuss." Er zwinkerte ihr anzueglich zu und drehte
+sich um.
+
+Julia wischte sich die Wange mit einem angewiderten Gesichtsausdruck ab. "Es
+sieht ganz danach aus."
+
+Als Paris den Huegel hinuntergestakst war, drehte Julia sich zu Bruder
+Lawrence um. "Scheisse."
+
+Ulo, Azzuro und Bruder Lawrence schnappten gleichzeitig nach Luft.
+
+"Das ist aber ein schlechtes Wort, Julia.", tadelte Bruder Lawrence mild.
+
+"Mir faellt kein besseres ein."
+
+"Nanana." Lawrence strich ihr sanft ueber das Haar.
+
+Julia sah Bruder Lawrence ernst an. "Ich bin mit Romeo rechtmaessig
+verheiratet, oder?"
+
+Der Moench nickte. "Wenn ihr..." Er blickte fragend zu Azzuro hoch, der
+bestaetigend nickte. "Ja, das seid ihr wohl."
+
+"Dann kann ich auch keinen anderen Mann heiraten. Schon gar nicht, wenn ich
+nicht will."
+
+"Es gibt Praezendenzfaelle, weisst du. Wenn ein Mann verbannt ist, kann er
+fuer tot erklaert werden."
+
+Julia richtete sich auf eine lange Vorlesung ein, doch als Lawrence schwieg,
+hob sie die Haende. "Nur, wenn man einen Antrag stellt. Und ich stelle den
+bestimmt nicht." Energisch putzte sie sich die Nase. "Ich werde Paris nicht
+heiraten. Er ist haesslich, aufgeblasen und nicht Romeo."
+
+Lawrence nickte. "Drei gute Gruende, aber was koenntest du sonst tun?"
+
+"Ich bring mich um."
+
+"Das lasse ich nicht zu. Gott verbietet es und wenn du mir davon erzaehlst,
+halte ich dich ab."
+
+"Versuchs nur." Julia schaute Bruder Lawrence so durchdringend an, dass dieser
+sich am liebsten in seiner Kutte verkrochen haette wie eine Schildkroete in
+ihrem Panzer.
+
+"Lass mich nachdenken, vielleicht habe ich eine Idee."
+
+"Denk lieber schnell, denn ich halte es nicht mehr aus."
+
+"Wenn du den Mut hast, dich umzubringen, was natuerlich gegen Gottes Gesetz
+waere, dann hast du doch bestimmt den Mut, dich scheinbar umzubringen und nur
+scheinbar gegen Gottes Gesetz zu handeln?"
+
+"Komplizierter kann er es wohl nicht ausdruecken.", maulte Ulo.
+
+"Legal, illegal..." Julia zoegerte.
+
+"Scheissegal.", half Azzuro aus und erntete einen vernichtenden Blick von
+Bruder Lawrence.
+
+Julia nickte. "Richtig. Ich nehme es mit allem auf, Bruder Lawrence. Wenn es
+sein muss, dann setze ich mich in einen Ameisenhaufen, spiele Karten mit einer
+Hexe, tanze auf dem Friedhof oder - ja, sogar das - ich sage meinem Vater,
+dass er ein herzloser Tyrann ist. Wenn du weisst, wie ich aus diesem
+Schlamassel herauskomme, dann rede."
+
+Bruder Lawrence verschwand in der Kapelle und kramte in einer Kiste.
+Schliesslich kam er mit einer kleinen Flasche wieder heraus. "Hier, das ist
+die Loesung."
+
+Julia wollte nach dem Flaeschchen greifen, doch Lawrence zog rasch die Hand
+zurueck. "Hoer mir erst zu. Du gehst hiermit nach Hause und tust ganz so, als
+haettest du es dir ueberlegt. Niemand darf Verdacht schoepfen, also sei
+froehlich und tu... Na, was immer eine Braut so tut. Am Mittwochabend gehst du
+ins Bett und sorgst dafuer, dass du in deinem Zimmer lange genug alleine
+bist." Er schwenkte die Flasche. "Dieses kleine Schaetzchen hier wirkt nicht
+so schnell, dass man die Wirkung nicht verhindern koennte, indem man dich
+zum... indem man deinen Magen leert."
+
+Julia nickte traurig. "Also bringe ich mich doch um."
+
+"Nein, nein. Dabei huelfe ich dir nicht." Lawrence laechelte. "Ganz im
+Gegenteil. Wenn du es trinkst, wirkst du nur fuer zweiundvierzig Stunden wie
+tot. Es laesst deinen Puls so langsam werden, dass niemand ihn mehr fuehlen
+kann, deine Muskeln werden steif, dein Atem setzt aus und deine Haut wird
+kalt. Jeder wird denken, du seist tot. Nur, dass du es nicht bist."
+
+Julia nickte. "Was nuetzt das? Irgendwann werde ich wach und alles ist wie
+vorher."
+
+Bruder Lawrence breitete die Arme aus, als hielte er ein grossartiges
+Geschenk. "Nicht ganz. Man wird dich begraben. Wenn die Wirkung nachlaesst,
+wird Romeo dich aus der Gruft holen und ihr beide koennt nach Mantua
+verschwinden, ohne dass je ein Mensch davon erfaehrt."
+
+"Romeo? Wie soll er..."
+
+Lawrence unterbrach sie. "Ganz einfach: Ich werde ihm schreiben."
+
+Julia fiel dem Moench um den Hals. "Ich koennte dich kuessen!"
+
+"Lieber nicht, sonst erwuergen ihn seine Geluebde.", meinte Ulo schadenfroh.
+
+"Sieh ihn dir an." Azzuro deutete mit dem Schnabel auf Bruder Lawrence. "Das
+tun sie so oder so."
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite21 b/d/seher/haeuser/special/special/rom_jul/seite21
new file mode 100644
index 0000000..0b12bf5
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite21
@@ -0,0 +1,57 @@
+DER VIERTE AKT
+ DIE ZWEITE SZENE
+
+Capulet ging mit seiner Frau die Gaesteliste durch. "Was meinst du, sollen wir
+Cousine Adelgund einladen?"
+
+"Bist du wahnsinnig? Wir haben Tante Frieda eingeladen!" Frau Capulet liebte
+zwar die kleinen Sticheleien der Gesellschaft, eine Bombe im Haushalt war ihr
+allerdings zuwider.
+
+"Ja, wahnsinnig bin ich wahrscheinlich." Herr Capulet seufzte. "Soviel
+Aufhebens und Julia hat noch nicht einmal ein nettes Wort fuer mich."
+
+Frau Capulet ueberwand sich und legte ihrem Mann die Hand auf die Schulter.
+"Eines Tages wird sie es verstehen."
+
+"Was verstehen?", fragte Julia von der Tuer aus.
+
+"Wieviel Muehe wir uns geben, um dich gut und anstaendig unter die Haube zu
+bringen." Abwesend zupfte Frau Capulet Julias Kleid gerade.
+
+"Doch, ich verstehe schon." Julia schenkte ihren Eltern ein ebenso strahlendes
+wie falsches Laecheln. "Ich verstehe sogar so gut, dass ich Paris heiraten
+werde, ohne einen Aufstand zu probieren."
+
+Herr Capulet blickte ueberrascht von der Gaesteliste auf. "Bist du doch noch
+zur Vernunft gekommen? In dem Fall feiern wir die Hochzeit gleich morgen,
+damit du es dir nicht noch einmal anders ueberlegst."
+
+Julia nickte ergeben. "Ganz wie mein Vater wuenscht."
+
+Herr Capulet taetschelte ihr den Kopf. "Das ist Papas kleines Maedchen." Er
+begann zu stammeln. Offensichtlich wusste er nicht mehr, was er sagen wollte.
+"Jaja, der gute Bruder Lawrence. Bis jetzt hat er noch jedem den Kopf
+zurechtgerueckt. Ich bin ihm dankbar." Er zoegerte und fluechtete sich dann in
+Phrasen. "Ach was, ganz Verona ist ihm zu Dank verpflichtet."
+
+Julia nickte. "Zumindest ich stehe tief in seiner Schuld." Sie dachte an die
+kleine Flasche in ihrer Handtasche und laechelte. "Mama, kann ich morgen ein
+bisschen Schmuck von dir haben?"
+
+Frau Capulet laechelte. "Such dir nur aus, was du haben moechtest."
+Nachdenklich blickte sie Julia nach und wandte sich dann an ihren Mann. "Ich
+denke nicht, dass wir den Termin auf morgen verschieben sollten. Uebermorgen
+waere immer noch ein guter Tag und fuer morgen haben wir bestimmt nicht genug
+Vorraete im Haus."
+
+"Ach, darum kuemmere ich mich schon." Herr Capulet war fest entschlossen, die
+milde Stimmung seiner Tochter auszunutzen und einen Skandal zu vermeiden.
+"Sorg du dafuer, dass Julia morgen herausgeputzt ist, ich putze dafuer das
+Haus und erledige den Rest."
+
+"Seit wann bist du unter die Hausmaenner gegangen?", fragte Frau Capulet
+zweifelnd.
+
+Ihr Mann brummte nur und beugte sich wieder ueber die Gaesteliste.
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite22 b/d/seher/haeuser/special/special/rom_jul/seite22
new file mode 100644
index 0000000..77219dc
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite22
@@ -0,0 +1,180 @@
+DER VIERTE AKT
+ DIE DRITTE SZENE
+
+Polly legte das Kleid, das Julias Mutter bei ihrer eigenen Hochzeit getragen
+hatte, ueber einen Stuhl. "Huebsch ist das. Bestimmt freust du dich, dass du
+es morgen anziehen kannst."
+
+Julia hatte die Anprobe wie eine Kleiderpuppe ueber sich ergehen lassen und
+reagierte auch jetzt nicht auf Pollys Worte. Obwohl es ihr schwer gefallen
+war, hatte sie nicht einmal Einspruch erhoben, als die Schneiderin darauf
+bestand, dass Julia zuviel Oberweite hatte und das Kleid unbedingt geaendert
+werden musste. Gluecklicherweise war Frau Capulet eine praktische Frau und
+hatte bei der Anfertigung des Kleides daran gedacht, ausreichend Stoff uebrig
+zu lassen. Nur Julia hatte Ulos veraechtlichen Kommentar gehoert, dass der
+Stoff wohl weniger aus Gruenden der Sparsamkeit dort verblieben war, sondern
+weil Frau Capulet bei der damaligen Anprobe gemogelt hatte.
+
+Ulo schuettelte auf ihrem Ast vor dem Fenster den Kopf. "Das arme Ding. Wie
+kann man ihr nur zumuten, zu ihrer Hochzeit abgelegte Kleider zu tragen."
+
+"Du hast dir noch nicht einmal ein Band um den Hals gebunden, als wir uns
+zusammen getan haben.", murrte Azzuro.
+
+"Warum haette ich auch sollen?", schnappte Ulo. "Du hattest es ja auch nicht
+noetig, mir einen Heiratsantrag zu machen, geschweige denn einen
+Verlobungsring zu besorgen."
+
+Azzuro, der sich sehr genau daran erinnerte, einen glitzernden Ring aus einem
+unbeaufsichtigten Schmuckkaestchen gestohlen zu haben, drehte sich schmollend
+um. "Ich habe dir immerhin ein schoenes Nest gebaut."
+
+Ulo ignorierte ihn und beobachtete Frau Capulet, die Julias Zimmer betrat.
+
+"Kommt ihr zurecht? Habt ihr alles gefunden?", fragte Frau Capulet
+aufgekratzt.
+
+"Wir sind fertig." Julia gaehnte hinter vorgehaltener Hand. "Ich bin muede und
+wenn ich morgen gut aussehen soll, muss ich noch ein bisschen schlafen."
+
+"Es gibt da noch etwas, worueber wir reden sollten.", begann Frau Capulet
+unsicher.
+
+"Keine Sorge, Mama, Polly hat mir schon gesagt, dass Paris wahrscheinlich
+schnarcht."
+
+"Das ist nicht das einzige, Julia." Frau Capulet erroetete.
+
+"Hat er Schweissfuesse?"
+
+"N-nein." Frau Capulet wand sich. "Du brauchst keine Angst vor der
+Hochzeitsnacht zu haben, weisst du." Sie aehnelte einem General, der eben
+einen hoffnungslosen Ausfall befohlen hat.
+
+"Natuerlich weiss ich, Mama." Julia genoss es, ihre Mutter so verlegen zu
+sehen.
+
+"Paris ist ein freundlicher Mann."
+
+"Und alt genug, dass sie selbst Erfahrungen mit ihm haben koennte.", fuegte
+Azzuro ungnaedig hinzu.
+
+"Ich bin jetzt muede, Mama." Julia zog die Vorhaenge vom Bett und winkte.
+"Gute Nacht."
+
+Frau Capulet wollte noch etwas sagen, wurde allerdings von Polly am Arm
+genommen. "Gehen wir schlafen und lassen Julia ihre Ruhe.", schlug Polly vor.
+
+Julia seufzte laut, als die beiden gegangen waren. "Hoffentlich nicht bis
+morgen."
+
+Ulo schniefte laut.
+
+"So schlimm ist es nicht, Kraehe." Julia zog ein Laecheln aus den Tiefen ihrer
+Erinnerung und nagelte es entschlossen auf ihrem Gesicht fest. "Ich bin froh,
+dass ihr hier seid. Dann muss ich das Zeug wenigstens nicht ganz alleine
+trinken."
+
+"Aehm, es macht dir aber hoffentlich nichts aus, wenn wir nicht mittrinken?",
+fragte Ulo.
+
+"Aber du koenntest es ruhig mit Wein verduennen und mir einen Schluck davon
+abgeben. Von dem Wein, natuerlich." Azzuro rieb sich beilaeufig mit der Kralle
+ueber den Schnabel.
+
+Julia hoerte nicht zu, sondern betrachtete die Flasche. "Was meint ihr, hat
+Bruder Lawrence mich reingelegt?"
+
+"Warum sollte er?", fragte Ulo.
+
+"Wie staende er wohl da, wenn ich allen erzaehle, dass er mich binnen zweier
+Tage gleich zwei Mal verheiratet hat?"
+
+"Ach was." Ulo kniff ein Auge zu. "Wer sollte dir wohl glauben, dass du
+ausgerechnet mit Romeo Montague verheiratet bist? Die Leute glauben viel, aber
+das ginge im Leben nicht in ihre Koepfe."
+
+Julia nickte. "Mag sein. Also scheidet das aus: Bruder Lawrence hat keinen
+Grund mich zu hintergehen. Bosheit ist es sicherlich nicht, schliesslich ist
+er ein Priester und heiliger Mann."
+
+"Heiliger Mann!", schnaubte Azzuro. "Hast du schon mal was von den Borghias
+gehoert?"
+
+"Sie sind glaube ich weitlaeufig mit mir verwandt. Allerdings habe ich sie
+noch nie getroffen, sie leben in einer anderen Stadt." Sie sagte es so, wie
+wir heute jemanden darueber aufklaeren, dass wir Verwandte in Australien
+haben.
+
+"Jedenfalls...Aua!" Azzuro verstummte und blickte Ulo verletzt an.
+
+"Wisst ihr, das Schlimmste waere, wenn es nicht wirkt. Ich meine, was, wenn
+ich morgen aufwache und heiraten muss?" Sie sah sich suchend im Zimmer um,
+erblickte ein scharfes Handarbeitsmesser und wog es nachdenklich in der Hand.
+"Na, ehe ich Paris heirate..."
+
+"Das gaebe eine ziemliche Schweinerei." Ulo schuettelte es allein bei dem
+Gedanken daran.
+
+"Besser als Paris heiraten.", versetzte Julia scharf.
+
+"Schon gut, schon gut." Ulo musste ihr wider Willen zustimmen.
+
+"Wenn nur mein Vater nicht in letzter Minute noch den Termin vorgezogen
+haette."
+
+"Was soll daran so schlimm sein?", fragte Azzuro. "Du trinkst das Zeug einfach
+einen Tag frueher."
+
+"Und wenn Romeo den Brief nicht rechtzeitig bekommt? Bruder Lawrence hat ihn
+losgeschickt, aber man weiss ja, wie langsam Klosterbrueder voran kommen, wenn
+sie auf Reisen sind."
+
+"Allzu viele Weinstuben gibt es auf dem Weg nach Mantua nicht.", beruhigte Ulo
+sie.
+
+"Trotzdem. Mich graust es bei dem Gedanken an diese staubige Gruft. Luftdicht
+ist gut, wenn man den Gestank drinnen halten will, aber wenn ich darin bin..."
+
+"Du wirst es ueberleben." Azzuro versuchte, seiner Stimme einen beruhigenden
+Klang zu geben.
+
+"Vielleicht waere das gar nicht so gut. Ich habe schreckliche Angst davor, da
+drinnen aufzuwachen. Am Ende werde ich wahnsinnig." Ihr Laecheln verschwand
+und machte einem bitteren Ausdruck Platz. "Das waere schlimmer als sterben."
+
+Ulo versuchte, sie zu troesten. "Du wuerdest es nicht merken."
+
+Julia nickte. "Vermutlich." Sie zog die Nase kraus und dachte nach. "Sagt mal,
+stimmt es, dass die Toten in der Gruft..." Sie zoegerte. "Ihr wisst schon...
+Es heisst, das es einige Tage dauert, bis sich der Tote mit seinem ...Platz
+abgefunden hat."
+
+"Woher sollen wir das wissen? Wir waren noch nicht tot." Azzuro zuckte die
+Schultern. "Es gibt da so etwas wie Gase, die noch rumoren, aber vielleicht
+ist das auch nur ein Geruecht."
+
+Julia dachte mit Grausen an Tybalt. "Ob ich Geister sehen werde? Tybalt
+vielleicht, der Romeo sucht und ihn nicht findet? Wenn er dann mit mir Vorlieb
+nimmt?" Sie schuettelte sich.
+
+"Du wirst schlafen." Ulo liess sich auf Julias Schulter nieder und strich ihr
+sanft mit dem Kopfgefieder ueber die Wange.
+
+"Das kitzelt." Julia kicherte, dann wurde sie wieder ernst. "Ich habe so viel
+darueber gehoert, was nachts auf Friedhoefen vorgeht. Manchmal hoert man die
+Toten entsetzlich schreien, heisst es."
+
+"Das sind bloss Katzen." Azzuro hatte die riesigen Tiere gesehen, die auf der
+Suche nach Ratten ueber die Graeber huschten und die Liebespaare stoerten,
+fuer die der Friedhof der einzige wirklich ungestoerte Ort war.
+
+"Wenn du es sagst.", meinte Julia zweifelnd. "Naja, wahrscheinlich hat es
+keinen Sinn, es noch laenger hinauszuschieben." Sie hob die Phiole. "Prost,
+ihr beiden. Falls ich es selbst nicht kann, gruesst Romeo von mir."
+
+Ulo huepfte zur Seite, als Julia niedersank. "Jetzt hat sie zumindest ihre
+Ruhe."
+
+"Sie haette es wirklich in Wein nehmen koennen.", murrte Azzuro.
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite23 b/d/seher/haeuser/special/special/rom_jul/seite23
new file mode 100644
index 0000000..e37dbce
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite23
@@ -0,0 +1,134 @@
+DER VIERTE AKT
+ DIE VIERTE SZENE
+
+Frau Capulet schleuderte ihre Blicke ueber das Schlachtfeld, das aus ihrem
+Haus geworden war, fand Polly und bannte sie mitten im Schritt. "Hier, nimm
+die Schluessel, in der Kueche werden noch Kraeuter gebraucht."
+
+Polly nahm die Insignien hausfraulicher Macht andaechtig entgegen. "Der
+Baecker moechte auch Datteln und Quitten haben."
+
+"Dann gib sie ihm." Frau Capulet sah ihren Mann die Treppe herunter kommen und
+stoehnte. "Er hat mir grade noch gefehlt."
+
+Herr Capulet nahm mit Schwung die Kurve um einen Diener herum, der ein
+Bierfass in Richtung Speisesaal rollte, duckte sich im letzten Moment unter
+einem Tablett mit Glaesern durch und wich um Haaresbreite einem Tisch aus,
+der, vollbeladen mit Obst, unschuldig inmitten des Raumes stand. "Was hat denn
+der Tisch hier zu suchen? Sonst ist der doch auch nicht da.", wunderte er
+sich.
+
+"Natuerlich nicht." Frau Capulet fasste sich mit uebertriebener Geste an die
+Stirn. "Aber nachdem wir so wenig Zeit haben, die Hochzeit vorzubereiten, kann
+schon einmal ein Tisch im Weg stehen."
+
+"Schon gut, schon gut." Herr Capulet gewahrte einen Kuechenjungen, der sich in
+eine Ecke drueckte und versuchte, moeglichst viel von der Plaenkelei zwischen
+ihm und seiner Frau zu hoeren. "Du da!"
+
+"Ich?" Der Kuechenjunge blickte sich um.
+
+"Ja, du. Sieh zu, dass du auf die Fuesse kommt, wir haben nicht den ganzen Tag
+Zeit." Herr Capulet wedelte mit den Haenden und ohrfeigte einen Diener, der
+sorgsam einen Fuss vor den anderen setzte und mit zusammengekniffenen Lippen
+auf die Suppenterrine in seinen Haenden starrte.
+
+Pollys Gesicht verzog sich zu einem Inbild des Zorns, als der Diener die
+Terrine fallen liess und eine gute Handvoll anderer Bediensteter mit
+bruehheisser Suppe ueberschuettete. Sie stemmte die Arme in die Seite und
+wartete geduldig, bis sich der Aufruhr gelegt hatte. "Herr Capulet?" Pollys
+Stimme war freundlich.
+
+"Ja?"
+
+Polly atmete tief durch und man sah ihre Lippen die Zahlen von eins bis zehn
+formen. Schliesslich kniff sie die Augen zusammen. "Sie wollten nicht
+zufaellig gerade gehen?", saeuselte Polly.
+
+"Kielholen, kielholen!" Ulo jauchzte.
+
+"Nein, eigentlich nicht." Herr Capulet war sichtlich verwirrt.
+
+"Ein Mann wie Sie hat sicherlich keine rechte Freude daran, Frauenarbeit zu
+tun, oder?"
+
+"Gibs ihm!" Azzuro vergass ganz und gar, kraehisch zu sprechen.
+
+"Habe ich Keks gesagt, dass du Kruemel dich meldest?", fragte Polly scharf und
+erwuergte Azzuro mit einem Blick.
+
+"Kruemel?" Azzuro war entruestet.
+
+"Irgendjemand muss sich ja darum kuemmern, dass alles glatt geht.",
+verteidigte sich Herr Capulet, der die Kraehen gar nicht beachtete.
+
+"Ja-a.", machte Polly. "Wir."
+
+"Wenn ich euch Weibern hier das Regiment ueberlasse, geht alles drunter und
+drueber."
+
+Polly betrachtete betont die Scherben der Terrine und schwieg.
+
+"Sie hat Kruemel gesagt!", empoerte sich Azzuro in die eisige Stille hinein.
+
+"Ueberhaupt war ich zu meiner Zeit durchaus in der Lage, mich um einen
+Haushalt zu kuemmern." Herr Capulet hob unbehaglich die Arme.
+
+"Richtig, zu Ihrer Zeit. Und morgen jammern Sie ueber ihr Zipperlein, weil Sie
+die Nacht durchgemacht haben."
+
+"Unsinn." Herr Capulet runzelte die Stirn. "Fuerchtest du, es koennte
+auffallen, wieviel besser ich das kann als du?"
+
+"Das Jammern?" Ulo kicherte.
+
+Alle Blicke senkten sich wieder auf die Scherben.
+
+"Liebling, das war die Terrine aus dem Service, das meine Mutter uns zur
+Hochzeit geschenkt hat.", mischte sich Frau Capulet ein.
+
+"Hoechste Zeit, dass wir ein neues anschaffen." Herr Capulet wandte sich
+brummend zu zwei Dienern um, die ein Schwein auf einem Spiess zur Kueche
+trugen. "Was ist das?", schnauzte er.
+
+Der vordere Diener wandte sich um und betrachtete das Tier auf dem Spiess.
+"Ein Schwein, wenn mich nicht alles taeuscht."
+
+"Ein Schwein, pah!" Polly schnaubte und schob sich an den Dienern vorbei in
+die Kueche.
+
+"Wen hat sie damit wohl gemeint?", fragte Ulo leise.
+
+"Kruemel, pah!" Azzuro schlug mit den Fluegeln.
+
+"Nein, mit dem Schwein."
+
+"Wen interessiert das? Sie hat mich Kruemel genannt!"
+
+Herrn Capulets Zeigefinger machte einen Vorstoss auf eine Magd. "Was ist in
+dem Korb?"
+
+"Keine Ahnung, ist fuer die Kueche."
+
+"Dann bring es hin."
+
+"Ich bin dabei.", versetzte die Magd.
+
+"Gut, gut." Herr Capulet ignorierte seine Frau, die sich mit verschraenkten
+Armen gegen die Wand lehnte.
+
+"Da kommt Paris." Ulo wandte den Kopf und betrachtete den bunten Zug von
+Musikanten und Akrobaten, die Paris begleiteten.
+
+Auch Herr Capulet hatte die Musik gehoert. "Du lieber Himmel, da ist ja schon
+Paris!" Er drehte sich um seine Achse. "Polly!"
+
+Polly streckte den Kopf durch die Kuechentuer. "Was ist denn?"
+
+"Paris ist los - nein, da. Los, los, wecke Julia. Bring sie her! Nein, zieh
+sie erst an, bring sie danach." Herr Capulet breitete die Arme aus und drehte
+sich um seine Achse.
+
+Polly fing den Blick Frau Capulets und tippte sich bedaechtig mit einem Finger
+an die Stirn, dann verschwand sie die Treppe hinauf.
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite24 b/d/seher/haeuser/special/special/rom_jul/seite24
new file mode 100644
index 0000000..502ad02
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite24
@@ -0,0 +1,217 @@
+DER VIERTE AKT
+ DIE FUENFTE SZENE
+
+Polly hielt sich nicht damit auf, an Julias Tuer zu klopfen, sondern stuermte
+gleich ins Zimmer. "Julia, Mauseschwaenzchen, Zeit zum Aufstehen.", floetete
+sie.
+
+"Wie lange sie wohl braucht?" Azzuro blickte betont zu Julias Bett, dessen
+Vorhaenge nur einen Spalt weit offen standen.
+
+"Warten wir's ab." Ulo legte bedaechtig eine Feder wieder an ihren richtigen
+Platz.
+
+"Julia, troedel nicht, dein Braeutigam ist da." Polly hielt einen Moment inne
+und kicherte. "Du tankst wohl jetzt schon Schlaf? Recht hast du, Paris wird
+sicherlich fuer die naechste Zeit andere Plaene fuer die Naechte haben. So,
+jetzt aber raus mit dir, du Schlafmuetze! Du willst doch nicht, dass Paris
+dich im Bett findet, oder? Dann kommt ihr beide verspaetet zur Hochzeit - und
+zu frueh zur Hochzeitsnacht." Sie kicherte wieder.
+
+"Da!" Azzuro wackelte aufgeregt auf seinem Ast hin und her. "Jetzt merkt
+sie's."
+
+Polly zog die Vorhaenge zurueck. "Was denn, immer noch angezogen? Warst du
+gestern so muede? Schaemen solltest du dich, das schoene Kleid ist ganz
+verdrueckt. Und ich muss es wieder buegeln." Sie ruettelte an Julias Schulter.
+"Julia!" Pollys Stirn krauste sich. "Julia?"
+
+"Achtung, jetzt kommt's. Was gaebe ich jetzt fuer ein Paar Haende!" Ulo
+stoehnte, als Polly markerschuetternd schrie.
+
+Wlad streckte den Kopf unter der Regenrinne hervor. "Wer ssschreit denn mitten
+in der Nacht?"
+
+"Schlaf weiter." Azzuro wandte den Blick nicht von der Szene in Julias
+Schlafzimmer.
+
+Brummelnd zog Wlad sich zurueck.
+
+"Was ist denn das fuer ein Laerm hier?" Frau Capulets modisch weisse Haut
+roetete sich vor Aerger.
+
+"Oh Jammer, oh Weh!" Polly zerraufte sich das Haar. "Julia!"
+
+"Hat sie wieder Floehe im Kopf?", fragte Herr Capulet ungnaedig, als er ins
+Zimmer kam.
+
+"Nein, aber bald Wuermer. Sie ist tot!" Polly zog das letzte Wort mit einem
+Schluchzen so lang, dass man es kaum verstehen konnte.
+
+"Tot." Frau Capulet wurde wieder bleich und plumpste auf den Boden.
+
+Herr Capulet schluckte schwer. "Tot?"
+
+"Verschieden, zu ihren Ahnen gegangen, hat den Loeffel abgegeben, den letzten
+Tanz getanzt, in den ewigen Jagdgruenden..." Polly holte Luft. "Tot."
+
+Nun daemmerte auch Herrn Capulet die Bedeutung ihrer Worte. Hilflos blickte er
+sich im Raum um, fand schliesslich eine Waschschuessel und schleuderte sie
+gegen die Wand. "Das ist nicht wahr!"
+
+Frau Capulet, die den Inhalt der Waschschuessel ins Gesicht bekommen hatte,
+oeffnete ein Auge und griff sich an die Brust. "Meine Julia? Julia!"
+
+"Krokodilstraenen." Ulo reckte veraechtlich den Schnabel in die Luft.
+
+"Du denkst auch immer das Schlimmste." Azzuro konnte sich ein Schniefen nicht
+verkneifen.
+
+"Ich kenne die Menschen.", versetzte Ulo.
+
+"Wie konnte das nur passieren?" Polly umfasste ihre kleine Flasche mit
+Lebenselixir, die sie aus ihren grossen Rocktaschen gezogen hatte.
+
+"Hey, davon kann sie mir etwas abgeben." Azzuro beugte sich nach vorne.
+
+"Pass nur auf, dass du nicht vom Ast faellst, Gierschlund." Ulo zupfte ihn
+missbilligend am Schwanz. "Da, jetzt kommt Paris. Da kannst du
+Krokodilstraenen sehen!"
+
+"Ach was. Er sagt doch, dass er sie liebt."
+
+"Richtig, er sagt es. Das heisst aber nicht, dass er es wirklich tut."
+
+"Wenn er sie nicht liebt, warum heiratet er sie dann? Sie hat noch nicht
+einmal Eier gelegt."
+
+"Menschen legen keine Eier, sie werden schwanger.", klaerte Ulo ihren
+Gefaehrten auf. "Paris will Julias Stellung und ihr Erbe. An ihr selbst hat er
+kein Interesse. Aber jetzt muss er trauern, sonst redet die Nachbarschaft
+ueber ihn."
+
+Bruder Lawrence erfasste beim ersten Blick ins Zimmer, dass Julia die von ihm
+verabreichte Medizin getrunken hatte. Er verkniff sich ein Laecheln. "Wie
+steht es? Ist unsere huebsche Braut fertig? Es ist Zeit fuer sie, zur Kirche
+zu gehen."
+
+Herr Capulet rieb sich ueber das Gesicht. "Tja, hingehen wird sie wohl, nur
+heim kommt sie nicht mehr."
+
+Paris, der das Schlafzimmer einer Dame nicht unaufgefordert betreten wollte,
+war an der Tuer stehen geblieben und ahnte noch nicht, dass er auf seine
+Hochzeit verzichten musste. Nun lachte er. "Doch, aber in mein Heim."
+
+Herr Capulet schuettelte den Kopf. "Nein, heute Nacht hat Julia den Tod
+geheiratet, und der hat sie dann gleich defloriert, meine kleine Blume."
+
+"Umpf." Azzuro wand sich. "Defloriert - wie unpassend."
+
+Paris machte einen taumelnden Schritt in den Raum hinein und schuettelte die
+Faust gegen die Decke. "Oh, Tod, wie konntest du mir das antun? Wie sehr habe
+ich mich darauf gefreut, meine Braut zu kuessen, und jetzt nimmst du sie mir
+weg."
+
+"ICH HABE DOCH GAR NICHTS DAMIT ZU TUN."
+
+Ulo wandte sich zu der dunklen Gestalt um, die neben ihr auf dem Ast sass und
+mit den knochigen Beinen baumelte. "Das weiss er aber nicht."
+
+"Du bist erst spaeter dran, warum trinkst du nicht noch einen Kaffee in der
+Garderobe?", schlug Azzuro vor.
+
+"WO SOLL ICH DEN DENN HINTUN?" Tod versank in die Schatten unter den
+Blaettern.
+
+Frau Capulet betupfte ihre Augen mit einem Spitzentuechlein. "Was fuer ein
+schrecklicher Tag. Da habe ich ein Kind, ein einziges, wunderbares,
+freundliches, schoenes, froehliches Kind, das einzige Kind, an dem ich Freude
+habe, und kaum kann ich sie verheiraten stirbt sie."
+
+Wie ein verstaerktes Echo trompetete Polly laut in ihr Taschentuch. "Wirklich
+ein schrecklicher, widerlicher, stinkender, ekelhafter Tag. Die arme kleine
+Julia, statt auf den Ruecken zu fallen und die Fuesse zur Decke zu strecken,
+faellt sie aufs Kreuz und bleibt liegen."
+
+Paris, der so rasch kein Taschentuch hatte finden koennen, nahm Julias
+Brautschleier und vergrub sein Gesicht darin. "Noch nicht verheiratet und
+schon von meiner Braut geschieden, ich fuehle mich betrogen." Er warf Herrn
+Capulet einen Blick zu, den dieser sogleich verstand.
+
+"Wem soll ich jetzt mein Vermoegen vererben? Warum konnte sie nicht zuerst
+heiraten und dann sterben?" Herr Capulet machte sich nicht die Muehe, ein
+Taschentuch zu suchen, sondern schneuzte sich in seinen Aermel.
+
+"Wahrscheinlich hattest du Recht mit den Krokodilstraenen.", meinte Azzuro.
+
+"Ich habe immer Recht." Ulo stiess ihren Gefaehrten mit dem Fluegel an.
+
+Bruder Lawrence war zum Fenster getreten. "Wann hat sie's getrunken?", raunte
+er den Kraehen zu.
+
+"Ungefaehr Mitternacht.", antwortete Ulo.
+
+Lawrence rechnete. "Zehn Stunden, bleiben noch zweiunddreissig. Gut. Zeit,
+dass sie beerdigt wird, sonst wacht sie uns noch waehrend der Beerdigung auf
+und das waere peinlich." Er wandte sich um und setzte die Miene auf, die er
+sonst fuer Predigten bereithielt. "So zu jammern ist wirklich nicht noetig,
+liebe Brueder und Schwestern. Ihr wisst doch, dass Julia jetzt im Himmel ist
+und mit den Englein Harfe spielt."
+
+Ulo verdrehte die Augen, schwieg aber.
+
+"Liebe Schwestern und Brueder, ihr solltet euch freuen, dass Julia jetzt im
+Himmel ist. Wie eigensuechtig von euch, hier zu weinen. Goennt ihr Julia denn
+nicht, dass sie jetzt im Paradies ist?" Er machte eine Pause. Als Frau Capulet
+Luft holte, um seine Frage zu beantworten, fuhr Lawrence schnell fort. "Eltern
+wuenschen sich doch, dass ihr Kind es gut hat. Und das hat sie es jetzt. Sie
+ist beim lieben Gott und darf jetzt fuer ihn singen. Statt zu jammern, solltet
+ihr euch freuen und feiern. Nur dass ihr jetzt nicht Julias Hochzeit mit einem
+irdischen Braeutigam feiert, sondern ihre Hochzeit mit einem himmlischen. Und
+der ist allemal besser als ein irdischer." Er zog Polly das Taschentuch
+herunter und enthuellte die kleine Flasche, die sie im Schutz des Tuches immer
+wieder an ihre Lippen gehoben hatte. "Also, Schluss jetzt mit dem Gejammer,
+zieht Julia huebsch an und bringt sie in die Kirche, damit sie beerdigt werden
+kann."
+
+Herr Capulet seufzte. "Jaja, das Leben geht weiter."
+
+"Richtig." Bruder Lawrence nickte ihm zu.
+
+"Dann werden wir also statt weisser Tuecher schwarze aufhaengen und traurige
+Lieder statt der froehlichen spielen. Mit dem Fest wollen wir Julias
+gedenken." Herr Capulet sah keinen Sinn darin, das gute Essen verkommen zu
+lassen.
+
+"Ganz genau. Und jetzt troedelt nicht laenger, Gott will, dass ihr Julia
+schnell beerdigt, damit nichts sie mehr von den Englein ablenkt." Bruder
+Lawrence scheuchte alle hinaus.
+
+Polly sah sich im Festsaal um. "Tja, da werden wir wohl noch ein paar Dinge
+aendern muessen." Ihr Blick fiel auf die Musiker. "Ihr koennt dann gehen, wir
+brauchen euch nicht."
+
+Ein alter Gaertner, der die Topfrosen hinaus und dafuer Buchsbaum herein
+brachte, schuettelte den Kopf. "Nein, geht noch nicht. Spielt mir doch 'Die
+Lorelei'."
+
+"Warum ausgerechnet das?", wollte der erste Geiger wissen.
+
+"Weil ich es mich auf andere Gedanken bringt. Ich hoere in meinem Kopf die
+ganze Zeit den Trauermarsch." Der alte Mann kratzte sich am Kopf und dachte an
+die Margaritenbaeumchen im Gewaechshaus. Julia hatte sie besonders gern gehabt
+und er beschloss, sie hier herein zu stellen und sich nicht um das Gezeter
+Herrn Capulets zu kuemmern, der Margariten unpassend finden wuerde. Er
+schneuzte sich verstohlen und nahm eine weitere Topfrose hoch.
+
+Der Geiger nickte. "Kannst du haben, aber was bekommen wir?"
+
+"Wie waere es mit einer Rose?" Der Gaertner spuerte Zorn aufsteigen. "Koennt
+ihr einem alten Mann nicht einfach einen Gefallen tun?"
+
+"Davon werden wir nicht satt, Mann."
+
+Der Bratschist hob beschwichtigend seinen Bogen. "Komm, lass gut sein. Wir
+spielen die Lorelei waehrend wir auf die Trauergaeste warten. Waere doch
+gelacht, wenn wir nicht ein paar Happen abbekaemen."
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite25 b/d/seher/haeuser/special/special/rom_jul/seite25
new file mode 100644
index 0000000..ce3a080
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite25
@@ -0,0 +1,117 @@
+DER FUENFTE AKT
+ DIE ERSTE SZENE
+
+"Das war eine bescheuerte Idee.", beschwerte sich Azzuro. "Wir haetten in
+Verona bleiben sollen."
+
+"Und diesen aufgeblasenen Affen zusehen, wie sie Trauer heucheln?" Ulo tauchte
+ihren Schnabel tief in eine Pfuetze und schmatzte.
+
+"Warum nicht? Schliesslich gibt es nachher ein Festmahl."
+
+"Du bist verfressen."
+
+"Ja." Azzuro konnte dies nicht abstreiten. "Aber nach Mantua ist es weit und
+ich bin muede."
+
+"Ich moechte Romeo sehen, wenn er zwei Nachrichten gleichzeitig bekommt. Was
+wird er wohl glauben, dass Julia tot ist oder dass sie schlaeft und auf ihn
+wartet? Und was, wenn Bruder Lawrence den Brief vergessen hat?"
+
+"Keine Ahnung. Sagen kannst du es ihm jedenfalls nicht, sonst sind wir
+draussen." Er schuettelte sich bei dem Gedanken. "Sieh mal, da geht Bruder
+John."
+
+"Wer ist das nun wieder?"
+
+"Lawrence hat ihm den Brief fuer Romeo gegeben. Gut, dann koennen wir jetzt
+umdrehen."
+
+"Ich wuerde mich lieber davon ueberzeugen, dass Romeo den Brief bekommt."
+
+"Sei nicht albern." Azzuro streckte die Fluegel und hob nach Verona ab, die
+seufzende Ulo dicht hinter sich.
+
+Kehren wir nicht mit den Turtelkraehen nach Verona zurueck, ich bin sicher,
+dass Sie, liebe Leserin, lieber Leser, sich Erspriesslicheres vorstellen
+koennen, als bei Julias Beerdigung zuzusehen. Zumal weder Sie noch ich etwas
+von dem Festschmaus hinterher bekommen werden.
+
+Romeo wischte sich den Schlaf aus den Augen, als sein Diener Balthasar
+eintrat. "Guten Morgen. Meine Guete, habe ich geschlafen."
+
+"Gut, hoffe ich?" Balthasar war nicht danach zumute, seine Nachrichten schnell
+loszuwerden.
+
+"Ich hatte einen verrueckten Traum. Ich lag tot in einem Grab und Julia kam zu
+mir. Hast du schon einmal so etwas Dummes gehoert?" Er gaehnte und schwang die
+Beine ueber die Bettkante. "Na, ich brauche nur an Julia zu denken, schon
+fuehle ich mich praechtig. Was gibt es Neues aus Verona? Wie geht es Julia?
+Und was macht meine Familie?"
+
+Balthasar goss Wasser in die Waschschuessel. "Ich habe zwei Nachrichten, eine
+gute und eine schlechte."
+
+"Raetsel am fruehen Morgen!", stoehnte Romeo. "Kannst du damit nicht warten,
+bis ich wacher bin?"
+
+"Julia geht es so gut, dass es schon wieder schlecht ist." Balthasar legte
+langsam ein Handtuch neben die Schuessel.
+
+"Komm, spuck's aus." Romeo tauchte das Gesicht ins Wasser.
+
+"Es geht Julia gut, denn sie ist im Himmel. Das ist die gute Nachricht."
+Balthasar sprach schnell.
+
+"Ich verstehe." Romeo verzog keine Miene. "Besorg' mir Papier, meins ist
+gestern ausgegangen."
+
+Balthasar betrachtete Romeo kritisch. "Du siehst nicht gut aus. Viel zu blass
+um die Nase fuer meinen Geschmack."
+
+Romeo, fest entschlossen, sich nichts anmerken zu lassen, grinste breit. "Du
+sollst mich ja auch nicht heiraten. Los schon, ich brauche das Papier."
+
+Balthasar ging, doch nicht ohne Romeo noch einen misstrauischen Blick
+zuzuwerfen.
+
+Romeo zog seine Hose an und stopfte das Hemd energisch hinein. "Heute abend
+bin ich bei Julia, komme was wolle.", murmelte er.
+
+Die Strassen Mantuas waren ueberfuellt und Romeo wurde staendig angerempelt,
+waehrend er sich einen Weg durch die Menge bahnte. Schliesslich erreichte er
+sein Ziel: Eine Apotheke, deren Geschaefte schlecht genug gingen, dass ihr
+Besitzer die Gesetze missachten und ihm Gift verkaufen wuerde. Aergerlich
+betrachtete er das Geschlossen-Schild an der Tuer und schlug dann mit der
+Faust gegen den Rahmen. "Hallo?"
+
+Der Apotheker oeffnete. "Ich habe heute keinen Notdienst."
+
+"Doch, haben Sie." Romeo hielt dem Mann ein kleines Vermoegen unter die Nase.
+
+"Kommen Sie rein." Der Apotheker zog ihn am Aermel hinter sich in den
+Verkaufsraum und schlug die Tuer zu. "Was wollen Sie?"
+
+"Gift. Ein gutes, schnelles Gift."
+
+Der Mann schuettelte den Kopf. "Ich bin doch nicht wahnsinnig. Wenn ich Ihnen
+Gift verkaufe, verliere ich meine Zulassung."
+
+"Zulassung hin, Geld her." Romeo schwenkte die Muenzen. "Ich werde Sie nicht
+verraten."
+
+Die Finger des Apothekers zuckten. "Ich kann nicht."
+
+"Was? Widerstehen?" Romeo laechelte. "Koennte ich auch nicht, wenn ich sehe,
+wie schlecht ausgestattet Sie sind. Fuer das Geld koennen Sie eine Menge Ware
+kaufen."
+
+Der Apotheker schloss umstaendlich einen Schrank auf. "Da, nehmen Sie. Und
+dann verschwinden Sie."
+
+Romeo nickte. "Ich verschwinde auf immer, keine Sorge. Und wenn jemand Sie
+fragt, haben Sie mir kein Gift verkauft, sondern Medizin."
+
+"Worauf Sie sich verlassen koennen." Der Apotheker blickte auf die Muenzen in
+seinen Haenden, denn Scheine waren noch nicht erfunden worden.
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite26 b/d/seher/haeuser/special/special/rom_jul/seite26
new file mode 100644
index 0000000..091d181
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite26
@@ -0,0 +1,51 @@
+DER FUENFTE AKT
+ DIE ZWEITE SZENE
+
+Wahrscheinlich fragen Sie sich jetzt, wo Bruder John abgeblieben ist, nicht
+wahr? Sehen wir also nach, wo er sich herumtreibt.
+
+Bruder John marschierte schnaufend den Berg hinauf. Als er Lawrence im
+Kraeutergarten sah, winkte er. "Lawrence, Bruder Lawrence!"
+
+Lawrence richtete sich stoehnend auf. "Ah, da bist du ja." Er reichte seinem
+Ordensbruder laechelnd einen Krug Wein. "Hier trink. Hast du den Brief
+abgeliefert?"
+
+John nahm einen tiefen Zug und schuettelte den Kopf. "Nein, so leid es mir
+tut." Er griff in seine Kutte und foerderte den zerknitterten und nach Wein
+riechenden Brief zutage. "Hier ist er wieder."
+
+"Hoelle und Teufel!" Lawrence ergriff den Kragen der Kutte seines Mitbruders.
+"Weisst du, wie wichtig dieser Brief ist?"
+
+"Ich konnte nichts dafuer!", wimmerte John. "Ich war schon halb in Mantua, als
+ich durch ein Dorf kam..."
+
+"Und du konntest dem Wein da nicht widerstehen? Nicht ein einziges Mal in
+deinem Leben?" Lawrence wedelte anklagend mit dem Brief unter Johns Nase hin
+und her. "Meinst du, ich rieche nicht, was du mit dem Brief angestellt hast?"
+
+"In dem Dorf war das Wasser verseucht, wir konnten nur Wein trinken, waehrend
+wir die Kranken versorgten."
+
+"Ja, natuerlich. Und die Erde ist eine Kugel." Bruder Lawrence schnaubte
+veraechtlich. "Himmel, was soll ich jetzt nur tun?"
+
+"Vielleicht einen neuen Brief schreiben?", wagte John vorzuschlagen.
+
+"Ja, aber erst muss ich Julia aus dem Grab holen."
+
+"Julia?" Bruder John war entsetzt. "Das ist Grabschaendung! Das darfst du
+nicht tun."
+
+Lawrence schuettelte den Kopf. "Julia lebt. Und genau das stand auch in dem
+Brief." Mit einem Stoehnen wischte er sich den Schweiss ab. "Und sie wird in
+ziemlich genau drei Stunden wieder wach werden."
+
+"Aber davon hast du mir nichts gesagt." Bruder Johns Stimme war voller
+Vorwurf.
+
+"Natuerlich nicht, sonst weiss es ja binnen einer Stunde die ganze Stadt.
+Also, besorg mir ein Brecheisen. Ich hole Julia aus der Gruft und dann
+schreibe ich einen neuen Brief an Romeo."
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite27 b/d/seher/haeuser/special/special/rom_jul/seite27
new file mode 100644
index 0000000..03521e6
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite27
@@ -0,0 +1,391 @@
+DER FUENFTE AKT
+ DIE FUENFTE SZENE
+
+Azzuro haemmerte mit dem Schnabel gegen die Regenrinne ueber Julias
+Schlafzimmer. "Wlad, aufwachen!"
+
+Wlads weinerliche Stimme ertoente von drinnen. "Meine Augen sssind ssstumpf,
+mein Radar issst muede und meine Sssaehne sssind taub... Wer ssstoert eine
+arme alte Fledermausss mitten in der Nacht?"
+
+"Hoer schon auf, wir sind's: Ulo und Azzuro!", rief Azzuro.
+
+Die Fledermaus streckte den Kopf heraus. "Ach ssso, und ich dachte ssschon,
+esss waere die Polizzzei. Wasss gibt esss denn?"
+
+"Kommst du mit zum Friedhof?", fragte Ulo.
+
+"Picknick?"
+
+Azzuro ruelpste verhalten. "Nein, ich bekomme keinen Bissen mehr runter."
+
+"Ich hoffe, du hassst mir noch eine Fliege uebrig gelasssen?"
+
+"Keine einzige..."
+
+"Wasss?", unterbrach ihn Wlad empoert.
+
+"Ich habe keine einzige Fliege gegessen. Wir haben uns bei Julias Begraebnis
+schadlos gehalten."
+
+"Warum habt ihr misss nissst geweckt? Dasss haette isss gerne gesehen. Und
+aussserdem: Wasss sssoll isss dann jetssst noch auf dem Friedhof?"
+
+"Showdown!" Azzuro machte eine dramatische Gebaerde.
+
+"Wiessso?"
+
+"Romeo hat den Brief nicht bekommen, in dem steht, dass Julia noch lebt. Und
+Paris will sich heute abend sehen lassen, wie er Julia zuenftig bejammert."
+
+"Klingt interesssant." Wlad grinste. "Alssso, fliegen wir."
+
+Sie erreichten den Friedhof zusammen mit Paris und seinem schwatzhaftesten
+Pagen.
+
+Paris nahm dem Jungen eine Flasche Parfum ab. "Du kannst da drueben auf mich
+warten. Wenn jemand kommt, pfeif nach mir."
+
+"Es ist dunkel, wir sind auf dem Friedhof und ich habe Angst.", wandte der
+Page ein.
+
+"Natuerlich ist es dunkel, schliesslich ist es Nacht." Paris schuettelte den
+Kopf. "Wenn du Gespenster siehst, kannst du ja pfeifen."
+
+Murmelnd zog der Junge sich zurueck und hockte sich ein Stueck entfernt unter
+eine Eibe.
+
+Wlad kicherte leise. "Passst mal auf." Sie liess sich von dem Ast fallen,
+unter dem sie gehangen hatte und drehte eine halsbrecherische Runde um den
+Kopf des Pagen. Der Junge spitzte die Lippen und versuchte zu pfeifen,
+erreichte aber nur ein kaum hoerbares Zischen. Lachend zog Wlad sich wieder
+auf ihren Ast zurueck.
+
+"Du bist gemein." Auch Ulo grinste.
+
+"Ja." Wlad strich sich mit dem Fluegel ueber die Ohren.
+
+"Guckt euch Paris an." Azzuro deutete mit dem Schnabel. "Ich haette eigentlich
+erwartet, dass er Zuschauer mitbringt."
+
+"Hat er doch." Ulo wies auf den Pagen. "Der Kleine ist nicht nur fuer seine
+Feigheit bekannt, er kann auch nichts fuer sich behalten."
+
+"Oh." Azzuro nickte.
+
+Paris drueckte sich ein Tuechlein ans Gesicht und vergoss ein paar Traenen.
+
+"Sssind dasss Ssswiebeln, die isss da riessse?", fragte Wlad.
+
+"Und Ammoniak." Ulo rieb sich den Schnabel mit der Klaue. "Das treibt einem ja
+die Traenen in die Augen."
+
+"Darum hat er es ja." Azzuro kniff die Augen zusammen. "Passt auf, jetzt kommt
+ein Gedicht."
+
+Ulo und Wlad stoehnten.
+
+"Oh, Julia, schoenste Blume du, mit Traenen decke ich dein Grab..." Paris
+zoegerte. "...mit Traenen deck' dein Grab ich zu. Blumen streu ich auf dein
+Haupt, weil boeser Tod dich hat geraubt."
+
+"Aua.", kommentierte Ulo.
+
+"Reim disss, oder isss beisss disss.", stimmte Wlad ihr zu. Grinsend deutete
+sie auf den Pagen. "Er versssucht'sss immer noch." Sie spitzte die Lippen und
+pfiff schrill. "Sssso geht dasss."
+
+Der Junge schaute sie aengstlich an. Paris, der festen Meinung, sein Page habe
+gepfiffen, blickte sich um und nahm einen Fackelschein wahr. Rasch steckte er
+das Parfumflaeschchen ein und duckte sich neben einen steinernen Engel.
+
+"Ah, da issst Romeo." Wlad reckte sich so weit vor, dass sie fast vom Ast
+fiel.
+
+Romeo nahm einen Brief aus seiner Jackentasche und reichte ihn Balthasar.
+"Hier, den gibst du gleich morgen frueh meinem Vater."
+
+Balthasar fuehlte sich alles andere als wohl in seiner Haut. "Was hast du
+vor?"
+
+"Ich werde mir Julias Ehering holen, denn schliesslich steht mir der als ihrem
+Mann zu, und ihr die letzte Ehre erweisen. Was sonst, meinst du?" Romeo nahm
+Balthasar das Stemmeisen ab. "Du musst hier verschwinden, ich will nicht, dass
+du meinetwegen in Schwierigkeiten kommst."
+
+"Ach, mit Schwierigkeiten werde ich fertig." Balthasar zuckte die Schultern.
+"Aber dich auf dem dunklen Friedhof allein zu lassen, das behagt mir nicht."
+
+"Vernuenftig, der Mann.", meinte Azzuro.
+
+Romeo legte seinem Diener die Hand auf die Schulter. "Mach dir um mich keine
+Sorgen. Verschwinde hier, und wenn ich dich erwische, dass du dich hier in der
+Naehe aufhaelst, reisse ich dir die Ohren ab, verstanden?"
+
+Balthasar nickte. "Ja, ich habe verstanden. Trotzdem: Romeo, mach keine
+Dummheiten."
+
+"Ich war nie in meinem Leben vernuenftiger. Mach dich vom Acker." Er sah, wie
+Balthasar zusammenzuckte. "Gottesacker, wollte ich sagen."
+
+Balthasar nickte ergeben, machte auf dem Absatz kehrt und blickte auch nicht
+zurueck, als er hoerte, wie Romeo das Grab aufbrach.
+
+Paris zitterte hinter dem Rock des Engels vor Wut, als er die hallenden
+Schlaege hoerte, mit denen Romeo das Grab oeffnete. "Du Grabschaender!"
+Wuetend sprang er nach vorne und zog seinen Degen.
+
+Romeo wandte sich langsam um, das Brecheisen in der Rechten. "Hoer zu, ich
+habe nicht vor, das Grab zu schaenden. Wenn du nur fuer fuenf Pfennig Verstand
+hast, machst du, dass du wegkommst."
+
+"Reicht es dir nicht, dass Julia vor lauter Kummer ueber deinen Mord an ihrem
+Vetters Tybalt Selbstmord begangen hat? Musst du jetzt auch noch ihre Ruhe
+stoeren?" Die Degenspitze reckte sich begehrlich Romeos Kehle entgegen.
+"Escalus hat dich verbannt fuer dieses Verbrechen, jetzt kommst du zurueck, um
+noch mehr Schandtaten zu begehen?" Paris Gesicht leuchtete weiss vor Zorn im
+schwachen Sternenlicht. "Diesmal kommst du nicht davon, das schwoere ich dir.
+Ich nehme dich fest und morgen wird Escalus dich zum Tod verurteilen."
+
+"Ich bin laengst zum Tod verurteilt, Mann." Romeo verzog bedauernd das
+Gesicht. "Ich bin nur hier, weil ich sterben will, verstehst du das nicht?
+Also tu mir und dir den Gefallen und zwing mich nicht, dich auch noch
+umzubringen." Er hob das Brecheisen.
+
+Paris antwortete nicht, sondern hieb wild nach Romeo.
+
+Der Page hoerte den Laerm und richtete sich abrupt auf, dann drehte er sich um
+und rannte lauthals nach der Wache schreiend den Huegel hinunter.
+
+"Als Fechter kann er noch etwas lernen." Azzuro schuettelte den Kopf.
+
+"Elegant ist er nicht, das stimmt." Ulo kraechzte leise, als Paris einen
+Schlag mir dem Brecheisen nur mit knapper Not abfing. Der naechste Schlag kam
+schneller, als Paris es erwartet hatte. "Und lernen wird er auch nichts mehr."
+
+"Sssie haetten sssisss ruhig ein bisssen mehr anstrengen koennen.", beschwerte
+sich Wlad.
+
+Paris stoehnte, als Romeo sich ueber ihn beugte. "Begrab mich neben Julia.",
+fluesterte er.
+
+Romeo nickte. "Versprochen." Als Paris starb, sah er genauer hin. Er wurde
+blass, als er Paris erkannte. "Verdammt."
+
+"Julia sollte ihn heiraten.", fluesterte Azzuro leise in Romeos Ohr.
+
+Romeo stampfte mit dem Fuss auf. "Verdammt, verdammt, verdammt. Wieso musste
+ich ausgerechnet ihn erwischen?"
+
+"He, Romeo, ich muss dir etwas sagen." Ulo huepfte auf einen Vorsprung der
+Gruft.
+
+Romeo blickte auf. "Tu's nicht."
+
+"Doch." Aufgeregt trippelte Ulo hin und her. "Julia ist..."
+
+"Tot und beerdigt, ich weiss.", unterbrach Romeo sie. "Und ich bin auch schon
+tot. So gut wie." Er seufzte und hob Paris hoch. "Und Paris wird von einem
+Toten beerdigt. Was fuer eine Ironie des Schicksals." Er lachte bitter.
+
+"Nein, Julia ist..."
+
+"...unten.", beendete Azzuro den Satz fuer Ulo und warf ihr einen drohenden
+Blick zu. Kurz entschlossen landete Wlad auf Ulos Kopf und hielt ihr den
+Schnabel mit den Fluegeln zu.
+
+Verwirrt sah Romeo zu Ulo hoch, die sich heftig gegen Wlad wehrte. "Eine
+Fledermaus hockt auf einer Kraehe. Das ist wohl ein Vorzeichen." Er schulterte
+Paris Leichnam und ging vorsichtig die Stufen der Gruft hinunter.
+
+Unten sah Romeo sich schaudernd um und legte dann Paris neben Tybalt auf den
+Stein. "So, jetzt hast du einen Platz, der dir angemessen ist. Denn direkt
+neben Julia liege ich - und niemand anders." Er beugte sich ueber Julia. "Du
+hast ja noch ganz rote Lippen." Er laechelte und kuesste sie. "Schade, dass es
+kein Maerchen ist, sonst wachtest du jetzt auf." Nachdenklich wog er die
+Phiole mit dem Gift in der Hand. "Wo du bist, will ich auch hingehen, Julia."
+Er trank und sein Laecheln vertiefte sich, bevor er leblos in Julias Arme
+sank.
+
+Draussen war es Ulo endlich gelungen, Wlad herunterzuschubsen. "Du..., du..."
+
+"Ja?", fragte Wlad freundlich.
+
+"Deinetwegen ist..."
+
+"Still, da kommt Bruder Lawrence.", unterbrach Azzuro den Streit.
+
+Lawrence beugte sich nachdenklich ueber das Blut und das Brecheisen am Boden.
+"Was ist denn hier passiert?"
+
+"Romeo war hier.", klaerte Azzuro ihn auf.
+
+"War?" Bruder Lawrence sah ihn entsetzt an. "Ich hatte schon den ganzen Tag
+ein ungutes Gefuehl." Er seufzte. "Wenigstens muss ich jetzt die Gruft nicht
+mehr aufbrechen." Behutsam stieg er hinunter.
+
+Mit Grausen liess Lawrence den Blick ueber die Leichen schweifen, dann blickte
+er zu Azzuro auf. "Wie lange?", fragte er leise.
+
+"Ungefaehr eine halbe Stunde."
+
+Bruder Lawrence fluchte so herzhaft, dass Wlad das Maul offen stehen blieb.
+"Fuer einen Priessster hat er einen interessssanten Wortsssatsss.", meinte sie
+beifaellig.
+
+"Dass du das ja nicht petzt." Bruder Lawrence drohte ihr mit dem Finger.
+
+"Ich?" Wlad versuchte, unschuldig auszusehen.
+
+Julia stoehnte und klappte muehsam ein Auge auf. "Wo...?" Sie oeffnete auch
+das andere Auge. "Oh, ja. Eine Gruft. Meine Gruft." Als sie sich aufsetzte,
+fiel ihr Blick auf Lawrence, der sie mit schreckgeweiteten Augen ansah.
+"Bruder Lawrence. Gut. Wo ist Romeo?"
+
+Wortlos deutete Lawrence auf die Leiche. Er raeusperte sich, als Julia einen
+Schrei ausstiess. "Julia, wir sollten hier verschwinden. Ich bringe dich in
+ein Kloster."
+
+"Kloster? Ich will bei Romeo sein!"
+
+"Sei vernuenftig, das geht doch nicht. Er ist tot."
+
+"Dann will ich das auch sein." Sie betrachtete die Phiole in Romeos Fingern.
+"Leer. Du Geizhals, wie soll ich jetzt zu dir kommen?"
+
+Romeo reagierte nicht auf ihre Vorwuerfe, doch eine der drei Tauben auf der
+Wolke ueber ihnen sah sehr betruebt aus.
+
+"Julia..." Bruder Lawrence fasste sie an der Schulter.
+
+"Nein." Julia zog Romeos Dolch aus der Scheide, winkte den Kraehen, der
+Fledermaus und Bruder Lawrence zu und erstach sich.
+
+"Sie hat gewunken." Ulo schluckte.
+
+"Warte, bis wir sie hinter der Buehne sehen. Das gibt Aerger.", meinte Azzuro.
+
+"KANN ICH JETZT?"
+
+"Bedien disss, sssie warten ssson."
+
+"DANKE."
+
+Bruder Lawrence hoerte einen Wachmann und blickte sich wild um. "Ich muss weg
+hier, das ist mir unheimlich." Er raffte seine Kutte zusammen und kletterte so
+geschwind aus der Gruft, dass Ulo anerkennend pfiff.
+
+Der Wachhauptmann kam zusammen mit Paris Pagen herab. "Was fuer eine
+Scheisse." Er seufzte und ging zu seinen Kollegen nach oben. "Durchkaemmt den
+Friedhof. Unten liegen drei Leichen, alle noch warm. Der Taeter kann noch
+nicht weit sein." Er deutete auf einen Gefreiten. "Du gehst und holst Fuerst
+Escalus, die Capulets und die Montagues."
+
+"Wer sind die Leichen?", wollte sein Sergeant wissen.
+
+"Graf Paris, Romeo Montague und - haltet euch fest - Julia Capulet."
+
+"Julia?" Der Sergeant runzelte die Stirn. "Wie kann sie noch warm sein? Ich
+denke, sie ist schon seit zwei Tagen tot?"
+
+"Nein, ist sie nicht.", kraechzte Ulo.
+
+"Tja.", meinte der Hauptmann. "Denkt was ihr wollt, aber die Kraehe hat
+Recht."
+
+Escalus, der sich zwar die Amtsrobe ueber die Schultern geworfen hatte,
+allerdings in der Aufregung vergessen hatte, sich auch Schuhe anzuziehen, sah
+sich verwirrt um. "Womit hat die Kraehe Recht?"
+
+"Hier in der Gruft liegen drei frische Leichen: Romeo, Julia und Paris." Der
+Hauptmann nahm Haltung an.
+
+Frau Capulet, die sich gerade einen Weg durch die versammelte Menge bahnte,
+schrie auf. "Meine Julia stirbt zweimal?"
+
+Auch Escalus konnte es kaum glauben. "Also von Anfang. Wer hat wen
+erschlagen?"
+
+Bruder Lawrence, der zwischen zwei Wachmaennern herangeschleppt wurde wie ein
+Sack Waesche, zupfte sich verlegen an der Nase. "Ich sollte wohl etwas dazu
+sagen."
+
+"Vermutlich." Fuerst Escalus nickte dem Moench zu. "Wenn Sie es koennen."
+
+Bruder Lawrence seufzte. "Ich glaube, ich bin an allem schuld. Also: Romeo und
+Julia haben am Dienstag heimlich geheiratet."
+
+Sowohl die Familie Capulet als auch Herr Montague stoehnten auf und blickten
+unglaeubig in die Runde.
+
+Herr Montague sah Fuerst Escalus aus grossen, traurigen Augen an. "Nicht
+genug, dass meine Frau heute gestorben ist, weil sie es nicht ertragen konnte,
+dass Romeo verbannt ist, stirbt jetzt auch noch mein Sohn."
+
+Romeo, der neben Julia auf der weichen Wolke sass und die Taubengestalt
+abgelegt hatte, um abwesend Ulos Gefieder zu kraulen, lachte auf. "Das ist
+starker Tobak fuer sie."
+
+Julia legte ihre Hand auf seinen Arm. "Das mit deiner Mutter tut mir leid."
+
+Lawrence nickte den Eltern zu. "Es stimmt. Und am Montag hat Romeo auch Tybalt
+erstochen. Deshalb musste er noch vor Sonnenaufgang am Dienstagmorgen aus der
+Stadt verschwinden. Ich nehme doch stark an, dass die Ehe trotzdem
+rechtsgueltig ist. Polly weiss das sicher besser als ich."
+
+Julia kicherte und wurde rot.
+
+"Weil Herr Capulet dann am Dienstag Julia mit Paris verlobt hat, kam Julia zu
+mir und wollte, dass ich ihr helfe." Bruder Lawrence zuckte die Schultern.
+"Ich wusste nichts besseres, als ihr ein Schlafmittel zu geben, dass sie am
+Mittwochabend nehmen sollte, damit alle glauben, sie habe sich vergiftet.
+Gleichzeitig habe ich einen Mitbruder mit einem Brief zu Romeo geschickt.
+Leider hat Herr Capulet dann Dienstag beschlossen, dass die Hochzeit zwischen
+Julia und Paris bereits am Mittwoch stattfinden soll, weshalb Julia das
+Schlafmittel schon am Dienstag nahm. Eigentlich haette die Frist noch
+ausgereicht, um Romeo zu warnen, dass Julia lebt, aber mein Bruder hat mir den
+Brief zurueckgegeben." Lawrence seufzte. "Heute abend kam ich her, damit ich
+Julia aus der Gruft holen konnte und fand Romeo und Paris bereits tot vor."
+
+Escalus nickte bedaechtig. "Gut. Oder vielmehr, nicht gut. Wer kann mir sagen,
+wie Paris hier hin kam?"
+
+Paris Page trat vor. "Ich habe ihn begleitet, weil er hier Blumen auf Julias
+Grab streuen wollte."
+
+"Dabei hat Romeo ihn unterbrochen.", fuegte Balthasar hinzu. "Als ich am
+Donnerstag hier war, um fuer Romeo Neuigkeiten zu erfahren, hoerte ich von
+Julias Tod. Ich ritt also nach Mantua zurueck und Romeo, nehme ich an, kaufte
+sich da ein Gift. Dann kamen wir hierher, wobei Romeo mich glauben machte,
+dass er nur Julia die letzte Ehre erweisen wollte. Er schickte mich weg, aber
+ich sah noch, dass er und Paris aneinandergerieten. Einen Brief hat er noch
+geschrieben." Er reichte Escalus den Umschlag.
+
+"Bist der bessere Fechter." Paris klopfte Romeo auf die Schulter.
+
+"Wir haben eine Ewigkeit Zeit, deinen Stil zu verbessern.", antwortete Romeo.
+
+Escalus las das Schreiben und nickte wieder. "Das ist ein Abschiedsbrief, in
+dem Romeo selbst schreibt, dass er mit Julia verheiratet war."
+
+Herr Montague streckte impulsiv seine Hand nach Herrn Capulet aus. "Verdammte
+Scheisse, wie?"
+
+"Ja, das auch." Misstrauisch blickte Herr Capulet auf die Hand seines
+Erzfeindes, entdeckte kein Messer und schloss ihn dann in die Arme.
+"Versoehnen wir uns?"
+
+Noch ehe Herr Montague antworten konnte, hob Escalus die Hand. "Und ob ihr
+euch versoehnt. Ansonsten stecke ich euch beide in einen Sack und schlage mit
+einem Knueppel drauf."
+
+"Traefe nicht die Verkehrten.", stimmte ihm Herr Montague zu.
+
+"Das haette Escalus lieber gleich tun sollen.", maulte Ulo.
+
+"Hauptsache, es ist endlich Ruhe." Azzuro schmiegte sich an Julia und liess
+sich von dieser kraulen.
+
+"Jawohl." Julia laechelte. "Frieden auf Erden und das Himmelreich fuer Romeo
+und mich."
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite28 b/d/seher/haeuser/special/special/rom_jul/seite28
new file mode 100644
index 0000000..20aeeae
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite28
@@ -0,0 +1,16 @@
+EPILOG
+
+Hier verlassen wir nun Verona, das sich wie jede andere anstaendige Stadt nun
+nur noch mit einem grossen Buchstaben schreibt, bis wir uns wiedersehen, um
+die Geschichte noch einmal zu erleben.
+
+Ich hoffe, Sie, liebe Leserin, lieber Leser, nehmen den Turtelkraehen ihren
+Vorwitz nicht uebel, denn die Goetter der Mythenwelt haben beschlossen, ueber
+ihre Verfehlungen hinwegzusehen. Also wollen wir nicht kleinlicher sein.
+
+Es bleibt noch hinzuzufuegen, dass sie, nun, da sie gestorben sind, bis zu dem
+Tag im Ferienparadies der Mythen ihre Flitterwochen verleben, bis sie das
+naechste Mal gebraucht werden.
+
+Auf Wiedersehen.
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite3 b/d/seher/haeuser/special/special/rom_jul/seite3
new file mode 100644
index 0000000..2239446
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite3
@@ -0,0 +1,1023 @@
+DER ERSTE AKT
+ DIE ERSTE SZENE
+An dieser Stelle sollte eigentlich ein Chor auftreten, denn so gehoert es sich
+fuer eine Tragoedie, doch im Zuge der allgemeinen Sparmassnahmen wurde der
+Chor gestrichen und Ulo und Azzuro bekamen zusaetzlich zu ihrer normalen
+Aufgabe die Pflicht aufgebuerdet, Sie, verehrte LeserInnen, ueber die jeweils
+aktuelle Lage auf dem Laufenden zu halten, fuer den Fall, dass Sie eine
+Zusammenfassung oder einen Kommentar wuenschen. Auch wenn Sie dies nicht
+wollen, werden die beiden Sie informieren, denn dafuer werden sie schliesslich
+bezahlt.
+
+Ulo holte tief Luft und setzte sich in Positur. "Two households, both alike in
+dignity, in fair Verona, where we lay our scene..."
+
+"Ach, sei ruhig." knurrte Azzuro.
+
+"Was denn, was denn? Sonst stehst du doch auf die Klassiker?" Ulo mochte es
+gar nicht, mitten in einem Zitat unterbrochen zu werden.
+
+"Denk doch mal an die Leser!"
+
+"Und Leserinnen."
+
+"Ja, die auch. Sie wollen doch nicht ein englisches Zitat lesen."
+
+"Woher weisst du das?"
+
+Bitte stellen Sie sich vor, liebe Leserin, lieber Leser, dass Sie im Theater
+sitzen und sich Ulo nun an Sie wendet. "Sagen Sie mir, was Sie hoeren wollen.
+Jaja, auch Sie, dahinten in der vierzigsten Reihe Parkett, ganz links."
+
+Nun, ich gehe davon aus, dass Sie, auch der Herr ganz links in der vierzigsten
+Reihe Parkett, mit Shakespeare vertraut sind. Daher erspare ich ihnen das
+Zitat und fasse den Inhalt kurz zusammen. Gerade stoesst mich Azzuro an und
+verweist auf die Gewerkschaft. Sie entschuldigen mich bitte, ich ueberlasse
+die Zusammenfassung unseren beiden Turtelkraehen.
+
+"Du oder ich?" Ulo ist weiblichen Geschlechts und immer bereit, Azzuro eine
+unangenehme Aufgabe zu ueberlassen.
+
+"Egal."
+
+"Dann du." Meistens hat Ulo Erfolg mit ihrer Taktik.
+
+"OK. Wir finden uns in Verona wieder, Zeit irgendwann. Zwei Familien leben
+hier."
+
+"Es sind bestimmt noch mehr."
+
+"Das ist doch nicht wichtig, oder? Es geht nur um die Capulets und die
+Montagues."
+
+"Wirklich?"
+
+"Nein, nicht wirklich, aber die beiden sind die wichtigsten, denn sie sind
+schuld daran, dass sich die ganze Stadt in zwei feindliche Lager gespalten
+hat."
+
+"Das ist doch Unsinn. Schuld daran ist niemand anderer als der Autor."
+
+"Ulo!"
+
+"Schon gut."
+
+Azzuro strich mit dem Schnabel ueber das Gefieder. "Aus irgendeinem lang
+vergessenem Grunde liegen die beiden Familien in Fehde miteinander und die
+jungen Leute einer jeden Generation finden immer wieder die Moeglichkeit, die
+Fehde nicht in Vergessenheit geraten zu lassen. Im Laufe der verschiedenen
+Hochzeiten, Geburten und Taufen haben sich alle Bewohner Veronas in irgendeine
+Beziehung zueinander gesetzt und da die Capulets und die Montagues die beiden
+aeltesten Familien sind, haben alle Buerger auch eine Beziehung zu der einen
+oder anderen Familie. Sei es, dass Onkel Adalbert der Vater der Frau war, die
+der junge Montague vor zwanzig Jahren ins Unglueck gestuerzt hat, weil er ihr
+die Rosen nicht gegeben hat, die doch der Bruder des Cousins seines besten
+Freundes ihm ausdruecklich fuer diese Frau uebergeben hatte."
+
+"Du schweifst ab.", tadelte Ulo.
+
+"Aber wie soll ich es denn sonst erklaeren?"
+
+"Ist doch einfach: Verona ist ein Dorf."
+
+"Oh."
+
+Triumphierend blickte Ulo auf ihren Gefaehrten. "Und ein Dorf ist ein Dorf ist
+ein Dorf ist ein Dorf."
+
+"Also gut. Verona ist ein Dorf, das in zwei Teile gespalten ist. Jeder hat
+einen Groll gegen jeden anderen."
+
+"Und jedE hat einen Groll gegen jedE andere." Ulo hatte die bemerkenswerte
+Faehigkeit, Grossbuchstaben auszusprechen.
+
+"Ja." Azzuro seufzte. "Wie auch immer. Die beiden Familien haben jede einen
+Sproessling. Romeo Montague ist ein huebscher Bengel von achtzehn Jahren, der
+eines Tages das Geld und die Fehde von seinem Vater erben wird. Julia, die
+einzige Tochter des Hauses Capulet, wird einmal bildhuebsch, wenn man sie noch
+ein paar Jahre auf die Weide schickt."
+
+"Wie kannst du das sagen?"
+
+"He, sie ist erst dreizehn!"
+
+"Alt genug, um demnaechst verheiratet zu werden. Und bereits jetzt schoener
+als Helena."
+
+"Was hat Helena damit zu tun?" Azzuro duckte sich sicherheitshalber.
+
+"Helena von Troja."
+
+"Ach so, die. Jaja, meinetwegen ist sie schoener als Helena."
+
+"An wen dachtest du denn?", verlangte Ulo zu wissen.
+
+_Sie_ _hat_ _schon_ _wieder_ _diesen_ _Tonfall_, dachte Azzuro. "Niemanden,
+selbstverstaendlich. Ausser dir sehe ich doch keine Frau an, Liebste, das
+weisst du doch."
+
+"Ist auch besser so."
+
+Zwei Maenner betraten den Platz und Azzuro deutete mit dem Schnabel auf die
+beiden.
+
+"Da. Samson und Gregory."
+
+"Was ist mit ihnen?"
+
+"Gleich werden sie mit ihren Saebeln rasseln und..."
+
+"Scht!"
+
+Verlegen blickte Azzuro auf die Frau, die sich gerade ueber den Brunnen beugte
+und Wasser schoepfte. "Ups."
+
+"Du weisst, dass _sie_ uns nicht hoeren duerfen."
+
+"Ja.", antwortete Azzuro kleinlaut. "Ich weiss."
+
+Hier unterbreche ich noch einmal den Lauf der Handlung, um Ihnen, liebe
+Leserin, lieber Leser, zu erklaeren, was Turtelkraehen nun eigentlich sind.
+
+Turtelkraehen, wie der Name vermuten laesst, treten immer paarweise auf. Ein
+Maennchen, in unserem Fall Azzuro, und ein Weibchen, Ulo, wie Sie sich
+bestimmt schon gedacht haben. Was Sie nicht wissen koennen, ist, dass die
+Turtelkraehen ein Geschenk der Goetter sind, und somit keineswegs das, was
+sich ein normaler Mensch wuenschen wuerde. Sie gehoeren zu jeder Geschichte,
+in der Liebende auftauchen. Fragen Sie mich nicht, warum, denn das haben die
+Goetter vergessen zu erwaehnen. Die Aufgabe der Turtelkraehen ist es, die
+Geschichte zu verfolgen und den Goettern der Sagenwelt Bericht zu erstatten.
+Auch dies ist eine Funktion, die von den Goettern unerklaert blieb, doch ich
+wage die Vermutung, dass Goetter zwar allwissend sind, aber dennoch nur zwei
+Augen haben, die noch dazu nicht unabhaengig voneinander funktionieren. Oder,
+um es anders auszudruecken, die Goetter sind wie Kaufhausdetektive, haben ihre
+Augen immer nur auf einem Bengel in zerschlissenen Jeans und haben daher die
+Turtelkraehen als eine Art Videoueberwachung installiert. Geschichten sind wie
+das Endlosband einer telefonischen Warteschleife. Kennen Sie das? Sie warten
+darauf, endlich eine Verbindung zu bekommen und hoeren sich schlecht
+interpretierte Musik in noch schlechterer Qualitaet an, die immer wieder von
+einer mehr oder minder freundlichen Stimme mit _Bitte_ _warten_, _please_
+_hold_ _the_ _line_ unterbrochen wird. Die Unterbrechung ist noch das
+angenehmste am ganzen Band. Wann immer diese Pause kommt, die andeutet, dass
+das Band nun ein Ende erreicht hat, steigt Ihre Spannung und Sie erwarten,
+gleich eine vielleicht nicht ganz so freundliche, dafuer aber menschliche
+Stimme zu hoeren, doch in Wahrheit spult sich das Band nur zurueck, um dem
+Anrufer die Langeweile zu verkuerzen. Falls Sie sich fragen, warum das Band
+dann endlos ist, werden Sie weiter ratlos bleiben muessen, denn darauf wissen
+selbst die Goetter keine Antwort. Bekanntermassen hatten die Goetter ohnehin
+nicht viel damit zu tun, die Warteschleife zu erfinden, dieses zweifelhafte
+Verdienst ist das der Hoelle. Damit soll Ihnen auch nur nahe gebracht werden,
+dass eine Geschichte endlos weitergeht, auch, wenn sie ihr scheinbares Ende
+erreicht hat. Sobald der eine Mensch die Warteschleife verlaesst und der
+naechste vom Besetztzeichen der Langeweile zur Kurzweil der Warteschleife
+vorrueckt, beginnt die Geschichte von vorne.
+
+So erklaert sich, dass Ulo und Azzuro reichlich Zeit hatten, die Geschichte
+kennenzulernen. Waehrend sie fuer die Akteure unseres Dramas jedes Mal neu
+ist, kennen die Turtelkraehen sie auswendig. Warum sie dann trotzdem weiterhin
+den Fortgang beobachten muessen, bleibt unklar, obwohl es vermutlich mit der
+Gewerkschaft zusammenhaengt.
+
+Ulo und Azzuro sitzen auf dem Brunnen und betrachten die Tragoedie, die sich
+vor ihren Augen abspult, wie ein altes Ehepaar die fuenfundzwanzigste
+Wiederholung von Vom Winde Verweht anschaut: Jeder (und jede) weiss, wann der
+(oder die) andere Taschentuecher benoetigt und wann er (oder sie) dem (oder
+der) anderen die Augen zuhalten muss. Leider haben die Turtelkraehen auch eine
+andere Eigenschaft des alten Ehepaares: Wann immer eine besonders gelungene
+Szene kommt, weisen sie einander im Voraus darauf hin und verderben sich damit
+jede Spannung.
+
+Bitte verzeihen Sie die umstaendliche Klammersetzung, aber Ulo besteht darauf.
+Sie, liebe Leserin, lieber Leser, koennen sich mit Sicherheit vorstellen, was
+geschaehe, wenn ein Kinobesucher Scarlett verriete, wie widerlich Rhett sich
+ihr gegenueber verhalten wird. Sie koennen es, nicht wahr? Und daher ist es
+Turtelkraehen strikt verboten, sich ueber Geschehnisse, die der werdenden
+Mutter Zukunft noch nicht einmal Wehen verursachen, zu unterhalten. Ganz
+undenkbar, wenn sie gar das Geschlecht des Kindes verrieten, dass Zukunft
+gebaeren wird!
+
+Kehren wir also zurueck zu unserer Geschichte und hoffen, dass Ulos Ermahnung
+Azzuro von weiteren Verfehlungen abhalten wird.
+
+Wir erinnern uns, dass gerade Samson und Gregory auf den Platz kamen. Samson
+pfiff einer jungen Frau hinterher und handelte sich einen Rippenstoss von
+seinem Freund ein.
+
+"Lass die Maedels in Ruhe, Sam.", verlangte Gregory.
+
+"Ach, komm schon, sie ist wirklich niedlich."
+
+Gregory schaute ueber die Schulter und konnte dem nur zustimmen. "Hey, wonach
+mir jetzt wirklich der Sinn stuende, das waere der eine oder andere Capulet."
+
+Samson grinste. "Am Spiess?"
+
+"Waere doch was, nicht?"
+
+"Und dann haeuten wir ihre Frauen?"
+
+"Faellt dir nichts besseres ein?", fragte Gregory.
+
+"Ich wuesste nichts besseres, als eine Frau mit meinem Spiess zu haeuten."
+
+"Oh, _die_ Haut meinst du. Du solltest Maedchen sagen."
+
+Ulo schuettelte sich und liess etwas fallen, was hier auf mit Ruecksicht auf
+jugendliche Leser (entschuldige Ulo) und Leserinnen nicht naeher benannt
+werden soll.
+
+"Die Kraehe hat mir auf den Kopf ge..." Samson holte ein nicht allzu sauberes
+Taschentuch heraus und wischte sich ueber die beginnende Glatze.
+
+"Das wird dich lehren, du Mistkerl!", kraechzte Ulo.
+
+"Und sie lacht auch noch." Samson fluchte. Er hatte Ulos Worte nicht
+verstanden, da diese klug genug gewesen war, Kraehisch zu sprechen, doch der
+Tonfall war unverkennbar.
+
+"Du spinnst, mein Freund. Seit wann lachen Kraehen? Steck den Saebel weg."
+
+"Ich bring das Vieh um!" Samson war keineswegs der Mann, der seine Emotionen
+kontrollieren konnte oder wollte.
+
+"Dann lass das Ding halt draussen, aber da drueben findest du ein groesseres
+Ziel." Samson grinste breit und entbloesste ein Gebiss, das einen Zahnarzt ein
+Jahr lang ernaehrt haette. "Capulets! Lasst sie mir!"
+
+"Wo mag er das nur aufgeschnappt haben? Im Original steht nichts
+dergleichen.", bemerkte Azzuro verdriesslich.
+
+"Halt! Wenn du so einfach losrennst, ist das nicht gut. Vergiss nie, dass wir
+das Gesetz auf unserer Seite haben wollen." Gregory hielt seinen Kameraden am
+Aermel zurueck.
+
+"Wen?"
+
+"Das Gesetz. Wenn du losstuermst und sie einfach angreifst, sind wir die
+Boesen und bekommen Schwierigkeiten. Also lass mich machen, ich sorge dafuer,
+dass wir in Notwehr handeln."
+
+Samson begriff nicht, was Gregory mit Gesetzen wollte, aber das Wort
+Schwierigkeiten weckte in ihm jene Vorsicht, die allen untergeordneten
+Soldaten dieser und aller anderen Welten gemein ist. Schwierigkeiten, das
+hatte etwas mit wuetenden Vorgesetzten, Latrinenputzen und Wochenenddienst zu
+tun, davon hielt man sich besser fern.
+
+"Zeig ihm den Stinkefinger.", schlug Samson vor.
+
+"Aber nicht doch, dann haetten wir das Gesetz nicht auf unserer Seite."
+Gregory schuettelte vehement den Kopf und streckte nichtsdestotrotz den
+Mittelfinger in unmissverstaendlicher Geste vor.
+
+"Hey, aber du zeigst ihm den Finger? Ich denke, das duerfen wir nicht?" Samson
+verstand seinen Kameraden nicht.
+
+"Wie? Zeigst du den Stinkefinger?", verlangte auch Abraham zu wissen.
+
+"Jawoll, ich zeige den Stinkefinger.", grinste Gregory und betrachtete die
+Hand Samsons, der ihm alles nachahmte.
+
+"Zeigst du ihn am Ende _mir_?" Abraham freute sich sichtlich auf die Antwort.
+
+Samson fluesterte: "Ist das Gesetz auf unserer Seite, wenn ich ja sage?"
+
+"Nein, bloss nicht." Gregory stupste seinen Freund in die Seite. "Lass mich
+machen."
+
+"Also, ich zeige den Stinkefinger, aber wie kommst du nur darauf, dass ich ihn
+dir zeigen koennte? Mein armer Finger! Das taete ich ihm niemals an!"
+
+"Wie war das? Sucht ihr Streit?"
+
+"Welch eine Unterstellung!"
+
+"Schade." Abraham grinste. "Ich sehe eine gute Gelegenheit, euch beiden zu
+zeigen, dass Capulet alle Male besser ist als Montague."
+
+"Pah." Gregory schnaubte.
+
+"Bloedsinn, die spinnen, die Capulets.", fuegte Samson aus tiefster
+Ueberzeugung hinzu.
+
+"Schon wieder!", empoerte sich Azzuro.
+
+"Oh doch, das ist es."
+
+"Ist es nicht."
+
+"Doch."
+
+"Nein."
+
+...
+
+Liebe Leserin, lieber Leser, setzen Sie in Gedanken dieses Auftrumpfen noch
+ein wenig fort. In Anbetracht der Tatsache, dass wir es mit erwachsenen
+Maennern zu tun haben, wollen wir uns nicht etwa Kinder vorstellen, die sich
+ueber die Groesse der Autos ihrer Vaeter streiten, sondern zum Beispiel
+Fussballfans, die sich nicht darueber einig werden koennen, welcher Verein es
+eher verdient hat, den Pokal zu gewinnen. Wie jeder gestandene Fussballfan
+Ihnen bestaetigen kann, haengt der Gewinn des Pokals ja in keiner Weise von
+den Faehigkeiten der Spieler oder des Trainers ab, sondern ausschliesslich von
+der Intensitaet des Glaubens der begeisterten Zuschauer. Fussball, so wissen
+wir, war zu jener Zeit noch nicht erfunden, doch wo immer zwei Mannschaften
+sind, finden sich auch Fans. Den Rest zu erklaeren ueberlasse ich weiseren
+Menschen.
+
+Eines wollen wir aber nicht vergessen: Wo immer sich zwei Trupps von Hooligans
+gegenueberstehen, ist der Fanbetreuer nicht weit und versucht, Frieden zu
+stiften. Gerade erinnerte Samson Gregory an seinen Lieblingsziegelstein.
+Verzeihung, seinen besten Saebelstreich, als Benevolio das nahende Unglueck
+sah.
+
+"Hoert ihr auf!" Benevolio zog seinen eigenen Saebel und schlaegt damit die
+der Kombattanten herunter. "Ihr habt sie wohl nicht mehr alle. Frieden jetzt,
+sonst hol ich die Polizei."
+
+"Hol die Bullen, mein Junge, aber steck den Zahnstocher weg.", knurrte
+Gregory.
+
+Benevolio ruempfte die Nase ueber die ungepflegte Ausdrucksweise. "Lern erst
+mal vernuenftig zu reden, dann hoere ich dir vielleicht auch zu. Und jetzt
+friedlich hier!"
+
+Ulo streckte den Kopf vor. "Ist er nicht ein Schaetzchen, unser Benevolio?"
+
+"Ein wahrer Held.", meinte Azzuro hoehnisch. "Nicht, dass er viel damit
+erreichte."
+
+"Wieso?"
+
+"Guck mal da rueber. Tybalt kommt."
+
+"Der Raufbold der Capulets? Na, dann haben wir ja gleich den schoensten Tanz
+hier."
+
+Ulo reckte den Kopf.
+
+Tybalt fragte nicht lange, sondern zog seinen Saebel blank. "Ja, was haben wir
+denn hier? Benevolio Montague, schau an. Und er hat auch noch zwei Freunde
+dabei. Das macht drei gegen zwei, wenn ich mich nicht taeusche. Schaemt ihr
+euch nicht, oder habt ihr etwa Angst?"
+
+"Schau an, er kann rechnen." Ulo lachte kraechzend.
+
+"Von Muffensausen kann keine Rede sein.", meinte Samson.
+
+Benevolio schenkte Tybalt einen veraechtlichen Blick. "Nein, keine Angst, mein
+Lieber, nur der Wunsch, Frieden zu stiften."
+
+"Indem ihr unsere Leute _umbringt_? Nicht gerade die feine Art, Herr
+Benevolio. Ich werde Ihnen schon zeigen, wie friedlich wir sind, wenn wir
+angegriffen werden."
+
+Sie kennen alle die schoenen Schlaegereien, die zum Western gehoeren, wie der
+rechte Schuh zum linken? Man pruegelt sich und achtet nicht weiter darauf, wen
+man gerade trifft, schliesslich ist jeder, der sich in die Naehe der Keilerei
+wagt entweder beteiligt oder selber schuld. Harmlose Passanten gibt es nicht,
+wer seine Zaehne behalten will, hat nur eine Moeglichkeit, dies zu erreichen:
+Er muss tot spielen und sich der Gefahr aussetzen, harte Tritte gegen weiche
+Teile zu kassieren oder er muss schneller zuschlagen als alle anderen. Binnen
+kuerzester Frist ist eine Schlaegerei im Gange, die ihresgleichen sucht.
+
+Wie immer in solchen Faellen platzt die Polizei mitten hinein, und da ihre
+Angehoerigen ebenfalls Menschen sind, koennen sie nicht umhin, bei der einen
+Partei ein wenig mehr Frieden zu stiften als bei der anderen. Halten wir der
+Polizei, insofern man fuer Individuen einen solch generalisierenden Ausdruck
+verwenden kann, zugute, dass sie bei all ihrer Menschlichkeit und Fehlbarkeit
+nichtsdestoweniger auf Ausgeglichenheit achtet, so dass fuer jeden Anhaenger
+der Capulets auch einer der Montagues eingestellt wird. Oder, um es ein wenig
+polemischer auszudruecken, keine der beiden Seiten bekommt weniger Polizei als
+die andere.
+
+Herr Capulet, der gerade seine Gattin auf einem Spaziergang begleitete, hatte
+seine helle Freude, als er die wunderschoene Pruegelei sah. "Das gibt es ja
+nicht! Ca-Pu-Let, Ca- Pu-Let!"
+
+"Idiot. Und guck nur, er hat einen Morgenrock an.", kommentierte Ulo. "Der
+Kerl ist wirklich senil."
+
+"Lass ihn doch. Der alte Knochen kann nur noch bruellen." Azzuro zuckte die
+Schultern.
+
+"Sollte mich wundern, wenn er es dabei beliesse." Ulo kannte ihre Pappenheimer.
+
+"Verdammt, wir verlieren! Mein Schwert!"
+
+Frau Capulet, jeder Zoll eine Dame und sich voellig im Klaren ueber den
+Zustand ihres Gatten, laechelte ein wenig. "Du meinst gewiss deine Kruecke,
+mein Schatz." "Ich meine mein Schwert."
+
+"Sag ich doch.", erwiderte seine Gattin malizioes.
+
+Herr Capulet, der ahnte, was ihn daheim erwartete, wenn er seiner Gattin jetzt
+widerspraeche, zuckte nur die Schultern und begnuegte sich damit, die
+Capuletanhaenger anzufeuern und uebersah in seinem Eifer ganz und gar, dass
+inzwischen auch Herr Montague mit seiner Frau das Schlachtfeld betreten hatte.
+Herrn Montague war die Gestalt seines Lieblingsfeindes allerdings keineswegs
+entgangen. "Du hinterhaeltiger Sack! Wozu hast du deine Leute angestiftet!" Er
+stuerzte mit erhobener Faust auf Capulet zu. "Du, du..."
+
+"Du Capulet.", soufflierte Azzuro und handelte sich einen zornigen Blick von
+Ulo ein. Dankbar nahm Montague die Hilfestellung an. "Du _Capulet_, dir zeig
+ich, was ein echter Montague ist!"
+
+"Jetzt wird es erst lustig.", freute sich Ulo und setzte sich in Positur.
+"Bestimmt bekommen wir gleich eine bilderbuchreife Herzattacke zu sehen."
+
+"Nichts da." Azzuro deutete mit dem Schnabel auf die Polizisten. "Da, siehst
+du? Sie haben es geschafft, die beiden Seiten zu trennen."
+
+Ulo seufzte. "Schade."
+
+Die Polizisten hatten die beiden feindlichen Seiten saeuberlich aussortiert
+und an den gegenueberliegenden Seiten des Platzes Aufstellung nehmen lassen.
+Zu jener Zeit hielt man sich nicht lange damit auf, die Personalien
+festzustellen, die Raufbolde abzufuehren, auszunuechtern und nach einigen
+Wochen oder Monaten vor Gericht zu stellen, man sammelte die Ueberreste der
+Pruegelei ein und fuehrte sie dem Richter einfach vor, der lange nicht so
+ueberlastet war, wie es die Gerichte in unserer leidgeplagten Zeit sind. So
+geschah es auch jetzt. Das Gericht, in Gestalt des Buergermeisters Escalus
+betrat den Gerichtshof, will sagen, den Marktplatz, und nahm am Brunnen
+Aufstellung.
+
+"Was ist hier los?", verlangte Escalus zu wissen.
+
+"Sie haben sich gepruegelt.", bemerkte Ulo leise.
+
+"Danke, soviel kann ich selber aus den blutigen Nasen ablesen." Escalus
+ignorierte die fragenden Blicke, denn er wusste ja nicht, dass er als Einziger
+Ulos Worte gehoert hatte. "Mir reicht es jetzt, Herrschaften. Geht es schon
+wieder um die alte Fehde?" Montague und Capulet, beides Maenner, die fuer ihre
+Angestellten und Anhaenger einstanden, nickten betreten.
+
+"Ich habe die Nase voll. Statt euch wie anstaendige Menschen zu benehmen,
+pruegelt ihr euch auf offener Strasse, als gaebe es keine zivilisierte Art,
+die Angelegenheit zu regeln."
+
+"Hoert, hoert." Azzuro grinste.
+
+"Warum erfindest du nicht den Fussball?", fragte Ulo so leise, dass wieder nur
+Escalus sie hoeren konnte.
+
+Wenn die Goetter der Mythenwelt Ulo jetzt gehoert haetten, waere sicherlich
+ein Blitz vom Himmel gekommen und haette sie erschlagen. Doch die Goetter
+waren anderweitig beschaeftigt, so kam es, dass Ulo ungeschoren davonkam und
+statt des strafenden Blitzes einer der Eingebung einschlug. Er traf auch nicht
+Ulo, in deren Kopf schon genug mehr oder minder dumme Ideen herumspukten,
+sondern Escalus, der tief Luft holte und die grandiose Idee in seinem Hirn
+speicherte, wo sie bis zu ihrer Reife liegen sollte. _Eines_ _Tages_, so
+dachte sich Escalus, _wird_ _die_ _Welt_ _friedlicher_ _sein_. _Dann_ _tragen_
+_wir_ _unseren_ _Streit_ _nicht_ _mehr_ _mit_ _Waffengewalt_ _aus_, _sondern_
+_spielen_ _statt_ _dessen_ _Fussball_. _Das_ _wird_ _eine_ _bessere_,
+_weisere_ _Welt_ _sein_, _ganz_ _bestimmt_. _Dann_, _eines_ _schoenen_
+_Tages_, _werden_ _zwei_ _verfeindete_ _Lager_ _ihre_ _besten_ _Leute_
+_auswaehlen_ _und_ _sie_ _in_ _fairem_ _Wettkampf_ _ihren_ _Streit_ _beilegen_
+_lassen_. _Ja_, _das_ _wird_ _wirklich_ _eine_ _bessere_ _Welt_ _sein_. _Ich_
+_muss_ _mir_ _nur_ _noch_ _ueberlegen_, _wie_ _man_ _Fussball_ _spielen_
+_soll_.
+
+Halten wir Escalus zugute, dass er noch nichts von Fans wissen konnte.
+
+"Das ist jetzt das dritte Mal, meine Herren. Dreimal hat euer verfluchter
+Haendel schon die ganze Stadt in Aufruhr gestuerzt."
+
+Er haette hinzufuegen koennen, dass bei jeder dieser Auseinandersetzungen
+Steuerzahler starben oder fuer laengere Zeit arbeitsunfaehig wurden, so dass
+man ihm persoenlichen Schaden zufuegte, aber ein solcher Mann war Escalus
+nicht. Statt dessen dachte er nur an die Menschen, die durch diesen dummen
+Streit keine Ruhe fanden und nie wussten, ob sie am naechsten Morgen ihre
+Stadt noch so vorfinden wuerden, wie sie am Abend, als sie sich schlafen
+legten, noch gewesen war. Wer konnte sagen, ob nicht am naechsten Tag alles in
+Schutt und Asche lag, was noch am Vortag als fuer die Ewigkeit gebaut
+ausgesehen hatte? Wer wusste, ob und wann der Streit zwischen den beiden
+Familien eskalierte? Wer konnte guten Gewissens _Bis_ _morgen_ zu seinen
+Freunden sagen, wenn er nicht wusste, ob er nicht beim Ueberqueren des Marktes
+alle Gedanken an ein Morgen gegen die unendliche Gleichgueltigkeit des Todes
+eintauschte? Haben Sie, liebe Leserin, lieber Leser, jemals eine Dorfkirmes
+besucht? Wenn nicht, empfehle ich Ihnen, sich ein solches Spektakel einmal
+anzusehen. Vielleicht gehen Sie am Samstagabend hin, wenn die jungen Maenner
+des Oberdorfes sich zum Bier an einem der drei Bierstaende treffen, waehrend
+die des Unterdorfes am zweiten stehen und die Erwachsenen, Distinguierten,
+Weiseren, in der Mitte zwischen den beiden Bierstaenden bei einem Glas sitzen
+und ueber Politik sprechen, waehrend sie darauf warten, dass der Spass
+anfaengt. Betrachten Sie die Szene und stellen Sie sich vor, dass statt der
+Faeuste Messer und Degen im Einsatz sind, dann koennen Sie sich in Escalusens
+Lage versetzen, der nichts anderes will, als endlich Frieden in seiner Stadt -
+und allen Menschen ein Wohlgefallen.
+
+Escalus war ein praktischer Mann, auch wenn ihm die Idee von einem Spiel, dass
+die Geschicke der Menschheit entschiede, ausnehmend gut gefiel. Moralische
+Skrupel plagten ihn weniger als die Probleme, die sich aus einer Fortsetzung
+des Streits ergaben. "Geht mir aus den Augen und wieder an eure Arbeit, Leute.
+Und benehmt euch wie Menschen, statt euch wie Tiere gegenseitig zu
+zerfleischen." Er schielte ein wenig, um beide Seiten des Marktplatzes
+gleichzeitig scharf ins Auge zu fassen. "Damit das eine klar ist: Ich dulde
+nicht, dass ihr euch weiterhin daneben benehmt. Wenn ich einen erwische, der
+sich mit einem anderen schlaegt, schlage ich mit der Faust dazwischen und
+lasse ihn auf der Stelle enthaupten. Verstanden?" Escalus wartete vergebens
+auf das verlegene Fuessescharren, das eine solche Drohung eigentlich
+hervorrufen sollte. Langsam, ein wenig widerstrebend machten sich die Buerger
+wieder auf den Weg zu ihren Haeusern und ihrer Arbeit. Capulet, immer noch in
+seinem gaenzlich unpassenden Morgenmantel, folgte Escalus zu dessen Buero, um
+dort zu einer Geldstrafe verdonnert zu werden, denn schliesslich war bei dem
+Streit ein Sachschaden entstanden, den Escalus ersetzt sehen wollte. Es
+interessierte Escalus nicht im geringsten, wer den Streit heute vom Zaun
+gebrochen hatte, solange er sowohl von Capulet als auch von Montague eine
+finanzielle Entschaedigung erhielt. Darin unterschied sich Escalus wenig von
+den heutigen Kommunen, die sich auch nicht besonders darum kuemmern, ob
+Nachbars Hund auf die Strasse lief und damit ursaechlich verantwortlich dafuer
+war, dass Herr Mueller oder Frau Schmitz gegen die Ampel fuhr - zumindest
+solange nicht, wie die Ampel bezahlt wird.
+
+Lassen wir also Escalus seinen Schadenersatz kassieren und folgen Ulo und
+Azzuro, denen es auf dem Marktplatz zu langweilig wurde, bis zu Montagues
+Haus, wo sich Benevolio Herrn Montague gegenueber rechtfertigen muss.
+
+"Ehrlich, Onkel, ich hatte ueberhaupt nichts mit der ganzen Angelegenheit zu
+tun."
+
+"Das sagst du jetzt.", regte sich Herr Montague auf.
+
+Frau Montague hatte als kluge Hausfrau nichts dafuer uebrig, ueber vergossene
+Milch zu klagen. "Wo steckt eigentlich Romeo?"
+
+"Lass Romeo jetzt, Liebste. Also, mein lieber Neffe, was war los?"
+
+"Also, da waren dieser Capulet, der sich mit Samson und Gregory angelegt
+hatte. Offenbar wollte er sich pruegeln, als ich dazu kam."
+
+"Eine Gelegenheit, die du dir nicht entgehen lassen konntest, nicht wahr?",
+fragte Herr Montague scharf.
+
+"Keineswegs, Onkel, ich habe nur versucht, die drei zu trennen. Tja, und dann
+kam Tybalt Capulet dazu."
+
+"Nur gut, dass Romeo nicht dabei war, dieser Tybalt haette ihn am Ende
+verletzt.", liess sich Frau Capulet vernehmen.
+
+"Die stellt sich vielleicht wegen des Bengels an.", knurrte Ulo von einem Ast,
+der, als haetten die Goetter ihn extra dort wachsen lassen, gerade so weit an
+das Fenster heranreichte, dass die beiden Turtelkraehen das Gespraech im
+Innern des Hauses mitverfolgen konnten.
+
+"Sie gibt nicht auf.", meinte Azzuro. "Was hat sie denn mit dem Jungen?"
+
+"Ach, wahrscheinlich ist er wieder hinter irgendeiner Frau her und heult sich
+deswegen die Augen aus." Ulo hielt nicht viel von Romeo.
+
+"Er ist halt jung." Azzuro hatte fuer das Verhalten Romeos deutlich mehr
+Verstaendnis.
+
+"Tybalt missverstand die Situation und hoerte mir auch nicht zu, als ich es
+ihm erklaeren wollte."
+
+"Sieht ihm aehnlich." Herr Montague kannte Tybalts schlechten Ruf.
+
+"Naja.", machte Benevolio gedehnt. "Ich musste mich doch gegen ihn
+verteidigen."
+
+Erinnern Sie sich, liebe Leserin, lieber Leser, wie Gregory sich eingangs
+ueber Notwehr aeusserte? Er hatte offenbar Erfolg mit seiner Taktik. Nur mit
+Buergermeister Escalus hat Gregory nicht gerechnet. Wenn Herr Montague
+wuesste, wie die Notwehr zustande kam, zoege er die Geldstrafe, die er nun zu
+zahlen hat, sicherlich von Gregorys Sold ab.
+
+"Wo ist denn nur Romeo?" Frau Montague war offensichtlich nicht bereit, die
+Sache auf sich beruhen zu lassen.
+
+"Er hat sich wieder eingeschlossen.", antwortete Benevolio.
+
+"Was heisst das?", verlangte Frau Montague mit der Verve einer besorgten
+Mutter zu wissen.
+
+"Weiss sie es am Ende wirklich nicht?", ueberlegte Ulo laut.
+
+"Wahrscheinlich nicht. Muetter nehmen ja immer nur das beste von ihren Kindern
+an." Azzuro zuckte mit den Schultern.
+
+"Es heisst, dass er sich in seinem Zimmer eingeschlossen und die Vorhaenge
+zugezogen hat.", antwortete Benevolio.
+
+"Er hat die Vorhaenge zugezogen?" Frau Montague mochte an ein solch
+unsittliches Verhalten bei ihrem Sohn nicht glauben. Wie Ihnen jedermann
+bestaetigen kann, sind am hellichten Tage zugezogene Vorhaenge ein deutliches
+Anzeichen liederlichen Lebenswandels, den Frau Montague ihrem Sohn nie
+gestattet haette. Zumindest, so koennen Sie es in jedem Dorf lernen, zieht man
+morgens die Vorhaenge auf und wahrt damit den Schein.
+
+"Sage ich doch, liebe Tante. Ausserdem hat er einen riesigen Vorrat an
+Taschentuechern."
+
+"Was will er denn damit?", wollte nun auch Herr Montague wissen.
+
+"Ist doch klar.", murmelte Azzuro.
+
+"Komm, das muss ich mir ansehen." Ulo grinste haemisch.
+
+Sie flogen um das Haus herum, denn im Gegensatz zum Wohnzimmer lagen die
+Schlafzimmer auf der Rueckseite des Hauses, zum Garten hinaus.
+
+"Hoer dir das an!" Ulo hatte ihre helle Freude an Romeos lautem Gejammer und
+Gestoehne.
+
+"Was hat er denn, der arme Kleine." Auch Azzuro hatte kein Mitleid fuer
+Menschen, die es so sehr uebertrieben.
+
+"Er hat Liebeskummer."
+
+"Och, da _tut_ er mir aber leid."
+
+"Ach, Rosaline!", erscholl es von drinnen, gefolgt von einem tiefen Seufzer.
+
+"Rosaline heisst sie also.", bemerkte Ulo ueberfluessigerweise.
+
+"Nicht Julia?"
+
+"Noch nicht, das kommt erst noch."
+
+Romeo, der den Kopf aus dem Fenster gesteckt hatte, warf einen verbluefften
+Blick auf die Kraehen. "Oh nein, meine einzige und wahre Liebe heisst
+Rosaline."
+
+Azzuro ueberlegte, wie er seinen Fehler wieder wett machen konnte. Er schaute
+schnell zu Ulo, doch auch diese schien zu betroffen zu sein, um sein Vergehen
+gegen die elementarsten Regeln des Turtelkraehendaseins den Goettern zu
+petzen.
+
+"Ganz bestimmt ist sie das.", versicherte Azzuro schnell. "Sie ist ja auch
+wunderschoen."
+
+Er trippelte verlegen von einem Fuss auf den anderen.
+
+"Ja, das ist sie. Aber wer ist Julia?"
+
+"Das braucht dich doch nicht zu interessieren, schliesslich ist Rosaline deine
+einzige Liebe."
+
+"Hm." Romeo ueberlegte einen Moment, dann brach er wieder in Traenen aus. "Ja,
+das ist sie. Und nie hat ein Mann eine so herzlose Frau geliebt."
+
+"Sie ist gemein zu dir?", fragte Azzuro.
+
+"Gemein ist gar kein Ausdruck. Ach, wenn ich nur wuesste, was ich tun muss, um
+sie zu ueberreden."
+
+Benevolio bollerte gegen Romeos Tuer und verlangte von seinem Cousin
+eingelassen zu werden, was Ulo und Azzuro zum Anlass nahmen, sich schleunigst
+zu verdruecken.
+
+"Du bist wohl wahnsinnig geworden!", schnauzte Ulo ihren Gefaehrten an.
+
+"Wer ahnt denn, dass der dumme Kerl ausgerechnet in diesem Moment aus dem
+Fenster guckt." verteidigte sich Azzuro.
+
+"Hoffentlich geht das gut."
+
+"Ach, da mach dir mal keine Sorgen. So wie der Junge gebaut ist, hat er
+Rosaline und Julia morgen vergessen und rennt einer dritten hinterher."
+
+"Wie kommst du denn darauf?"
+
+"Ist doch klar. Er ist achtzehn, aus guter Familie und reich. Wie sollte er da
+nicht ausreichend Maedchen finden, denen er unter die Roecke schauen kann?"
+Azzuro blickte auf seinen eigenen reichen Erfahrungsschatz zurueck.
+
+"Du denkst auch immer das schlechteste."
+
+"Aber nein. So sind die jungen Burschen nun mal. Fuer ihn ist es einfach chic,
+Liebeskummer zu haben."
+
+"Gut, dass du das hinter dir hast." Ulos Stimme liess vermuten, dass sie
+diesen Satz als Mahnung verstanden wissen wollte.
+
+"Hoefische Minne hat mir noch nie gelegen.", verteidigte sich Azzuro.
+
+"Ja, ich weiss." Ulo seufzte und gab sich fuer einige wenige Augenblicke ihren
+Traeumen hin.
+
+"Hoer auf damit, du weisst ja gar nicht, wovon du da traeumst." Azzuro kannte
+seine Gefaehrtin.
+
+"Ach, weiss ich nicht?"
+
+"Nein. Wenn du gewollt haettest, dass ich dich minne, dann haettest du mich
+niemals erhoeren duerfen."
+
+"Hm, haette ich besser getan, ja."
+
+"Versteh doch. Ich liebe dich ja, aber ich minne dich nicht. Zur Minne
+gehoert, dass man die angebliche Geliebte nie bekommen kann."
+
+"Wie kommst du denn darauf?"
+
+"Na, Minne hat nicht viel mit erfuellter Liebe zu tun, sondern mehr mit
+Aus-Der-Ferne- Schmachten."
+
+"Oh?" Ulos Stimme bekam eine deutliche Spitze. "Du vermisst mich also nicht,
+wenn ich nicht bei dir bin?"
+
+"Du bist doch nie von mir weg.", verteidigte sich Azzuro. "Und ueberhaupt,
+lenk nicht vom Thema ab."
+
+"Wer lenkt denn hier ab? Wahrscheinlich vergnuegst du dich ohnehin mit
+irgendeinem Spatzenflittchen, wenn ich mal nicht in der Naehe bin."
+
+Azzuro, der genau wusste, welche Richtung die Diskussion nehmen wuerde,
+betrachtete betont interessiert die Vorgaenge innerhalb Romeos Zimmer und zog
+es vor, nicht zu antworten.
+
+Benevolio hatte es inzwischen geschafft, Romeo dazu zu ueberreden, die Tuer zu
+oeffnen und ihn einzulassen. "Guten Morgen, Romeo.", begruesste er seinen
+Vetter froehlich.
+
+"Ist es denn Morgen?", fragte Romeo duester.
+
+"Und was fuer einer. Los, mach die Vorhaenge auf und schau dir den wunderbaren
+Sonnenschein an. Hoer nur, wie die Voegel singen." Benevolio riss die schweren
+Vorhaenge zur Seite und erblickte die beiden Kraehen. "Naja, vielleicht singen
+sie nicht ganz so schoen, aber die Sonne scheint auf jeden Fall."
+
+"Es ist schrecklich, aber ich bin so traurig, dass ich gar nicht sehen will,
+wie die Sonne scheint, denn das sieht so aus, als wolle sie mich verspotten."
+
+"Keineswegs will sie das. Sie hat nichts anderes im Sinn, als dich
+aufzuheitern."
+
+"Ist er irre?", fragte Ulo leise.
+
+"Aber nein. An ihm ist bloss eine Krankenschwester verloren gegangen.",
+bemerkte Azzuro.
+
+"Was macht dich denn so traurig, Romeo? Willst du es mir nicht erzaehlen?"
+fragte Benevolio.
+
+"Er ist wirklich ein Schaetzchen." Benevolio hatte unzweifelhaft Ulos Herz
+fuer sich gewonnen.
+
+"Ein Psychiater koennte er auch sein." Azzuro konnte dem freundlichen
+Benevolio nicht ganz so viel abgewinnen.
+
+"Mir ist langweilig, weil ich das nicht habe, was mir die Langeweile
+vertreibt.", antwortete Romeo.
+
+"Er will eine Modelleisenbahn?", vermutete Azzuro.
+
+Benevolio hatte offenbar ebenfalls keine Vorstellung von dem, was seinem
+Freund die Langeweile vertreiben koennte. "Was liebst du denn so sehr?"
+
+"Nicht was, sondern wen."
+
+"Liebe ist doch etwas schoenes, warum macht sie dich bloss so traurig?"
+
+"Weil ich Liebe gebe und keine bekomme. Ich fuehle mich wie eine leere
+Flasche. Das, was einmal in mir war, wollten alle haben, aber jetzt, da ich
+nur noch eine leere Flasche bin, gibt es niemanden mehr, der mich wieder
+fuellen wuerde."
+
+"Eine Flasche ist er allerdings.", bemerkte Ulo.
+
+"Nein, ist er nicht.", wies Benevolio sie streng zurecht. "Moment, seit wann
+koennen Kraehen reden?"
+
+"Seit Maenner Flaschen sind.", versetzte Ulo schnippisch.
+
+"Lass doch die bloeden Kraehen, Benevolio." Romeo mochte es gar nicht, wenn
+man sich nicht so leicht von ihm ablenken liess.
+
+Azzuro stiess Ulo mit einem gekonnten Schubs vom Ast und trieb sie zu einem
+Baum in sicherer Entfernung von Romeos Zimmer. "Halt bloss deinen vorlauten
+Schnabel!"
+
+"Er hat uns bloed genannt."
+
+"Ja."
+
+"Und das aergert mich."
+
+"Aha?"
+
+"Weil ich nicht bloed bin."
+
+"Du darfst in _ihrem_ Beisein trotzdem keine Kommentare machen, das weisst
+du."
+
+"Pah."
+
+"Weisst du es, oder nicht?"
+
+"Ja, ich weiss es. Aber er ist wirklich eine Flasche."
+
+"Das habe ich nicht bestritten. Wenn du jetzt deinen vorlauten Schnabel halten
+kannst, koennen wir wieder zurueck und uns den Rest ansehen."
+
+Ulo antwortete nicht, sondern flog wieder zu ihrem Ast und spaehte durch das
+Fenster auf die zuckenden Schultern Benevolios.
+
+"Lachst du mich aus?", fragte Romeo.
+
+"Mitnichten." Benevolios Stimme klang so ernst, dass selbst in Ulo Zweifel
+erwachten.
+
+"Eigentlich weine ich."
+
+"Warum denn das?"
+
+"Weil du so arm dran bist, lieber Romeo."
+
+"Hoer auf, bitte. Wenn du jetzt auch noch weinst, fuehle ich mich nur noch
+elender. Wenn das ueberhaupt geht."
+
+"Jaja, so geht das mit der Liebe." Benevolio grinste duemmlich.
+
+"Ja, genau so. Liebe, das ist ein Meer."
+
+"Ein Meer? Wie kommst du denn darauf?"
+
+Azzuro liess sich neben Ulo nieder.
+
+"Achtung, Romeo wird poetisch.", warnte Ulo ihren Gefaehrten.
+
+"Ein Meer, weil Traenen salzig sind und reichlich fliessen, wenn Liebe im
+Spiel ist."
+
+"Aha. Ja, ich glaube, ich weiss, was du meinst." Benevolio war prosaischer als
+sein Freund.
+
+"Ich glaube, ich mache einen Spaziergang." Romeo machte keine Anstalten,
+aufzustehen, sondern seufzte nur tief.
+
+"Immer langsam, ich weiss doch noch nicht alles, das waere gemein, wenn du
+mich jetzt so stehen liessest."
+
+"Ich bin sowieso nicht hier. Der echte Romeo ist woanders."
+
+"Und wo?"
+
+"Du willst wohl wissen, wie sie heisst?"
+
+"Gut gefolgert, lieber Watson."
+
+"Ich werde noch wahnsinnig!", stoehnte Azzuro.
+
+"Was ist denn los?" Ulo warf ihm einen verwirrten Blick zu.
+
+"Dauernd zitieren sie aus fremden Quellen, das macht mich irre."
+
+"Keine Sorge, du wirst dich nicht anders fuehlen als vorher." Ulo grinste.
+
+"Also soll ich dir vorstoehnen, wie sie heisst?", fragte Romeo mit einem
+Grinsen.
+
+"Es reicht, wenn du es mir einfach sagst.", antwortete Benevolio.
+
+"Klar, ich mache jetzt voellig einfach mein Testament."
+
+"Nana, so weit ist es noch nicht. Du bist ja noch gruen hinter den Ohren."
+Benevolio lachte.
+
+"Pfft.", machte Romeo. "So gruen bin ich nicht mehr, dass ich nicht weiss, wie
+man liebt."
+
+"Das wiederum habe ich nicht bezweifelt. Nun sag endlich, wie heisst sie?"
+
+"Sie ist eine Frau."
+
+"Hm, dachte ich mir. Zumindest hatte ich keinen Grund, etwas anderes
+anzunehmen."
+
+Romeo streckte seinem Vetter die Zunge heraus. "Und schoen ist sie auch."
+
+"Es war mir ebenfalls klar, dass du kein Kostveraechter bist."
+
+"Nein, ich verhungere lieber. Sie will mich nicht."
+
+"Klug und geschickt ist sie also auch noch?"
+
+"So geschickt, dass Cupidos Pfeil sie nicht trifft. Immer duckt sie sich weg."
+
+Wir wollen hier anmerken, dass auch Cupido zu jeder anstaendigen
+Liebesgeschichte gehoert. Auch zu den unanstaendigen, aber von denen reden wir
+hier lieber nicht, denn es mag ja sein, dass unter Ihnen, liebe Leserinnen,
+liebe Leser, Minderjaehrige sind. Kennen Sie Cupido? Das ist der kleine, dicke
+und nackte Bengel, den Sie auf fast jedem barocken Bild betrachten koennen.
+Damals hatte man eine Vorliebe fuer das Kerlchen, weil ein nackter Saeugling
+mit einem Bogen einfach lustig aussieht. Auf diese Weise gaben unsere
+Vorfahren dem im Grunde ernsten Ding Liebe noch eine amuesante Wendung. Bitte
+verwechseln Sie unseren kleinen Freund nicht mit den Engeln, die sind zwar
+auch nackt, klein und dick, haben aber keinen Bogen in den pummeligen
+Faeustchen.
+
+Romeo stellt sich Cupido noch nicht ganz so dick vor, dafuer sind seine Augen
+verbunden. Zu Romeos Zeiten, in jener mythischen und so ganz und gar
+unwirklichen Zeit, sah Cupido noch nicht, wen er mit seinen Pfeilen traf. Man
+koennte denken, dass dies zu allerlei Verwirrung gefuehrt haben muss, etwa,
+wenn sein Pfeil eigentlich dem Schaefer galt, der unaufmerksame Bengel
+allerdings eines der Schafe traf, doch scheint dies so selten der Fall gewesen
+zu sein, dass uns von solchen Geschehnissen nichts ueberliefert wurde. So
+muessen wir annehmen, dass damit lediglich das Sprichwort illustriert werden
+soll, das sagt: Wo die Liebe hinfaellt, da waechst kein Gras mehr.
+
+"Schlimmer noch." Jetzt stoehnte Romeo wirklich. "Sie ist eine wahre Diana,
+was das Ausweichen angeht."
+
+Sie erinnern sich sicher an Diana, liebe Leserin, lieber Leser. Sie war die
+Goettin der Jagd und Jungfrau von Beruf. Nichts und niemand konnte sie dazu
+bringen, sich mit einem Mann, gleich ob Gott oder Mensch, einzulassen. So
+schlimm trieb sie es, dass ein Mann zur Strafe, weil er ihr beim Baden
+zugesehen hatte, in einen Hirsch verwandelt und von seinen eigenen Hunden
+gefressen wurde. Diese Anekdote sagt ebensoviel ueber die Intelligenz eines
+Hundes wie ueber die des Mannes aus, denn beide vergassen ihre gesamte
+Erziehung. Die Hunde, als sie den Hirsch rochen, der Mann, als er die Frau
+sah.
+
+"Eine Diana, wie? Dann hat sie wohl lebenslange Keuschheit gelobt?"
+
+Romeo gab ein Geraeusch von sich, dass dem des gestellten Hirsches aehnlich
+sein mochte. "Was soll ich nur machen? Sie ist wunderschoen und es ist
+geradezu ein Frevel, dass sie ins Kloster will, denn damit verzichtet sie auch
+darauf, ihre Schoenheit an die Nachwelt zu ueberliefern."
+
+"Noch ist nicht aller Tage Abend. Vielleicht bekommt sie ja trotzdem Kinder."
+
+"Trotz der Keuschheit? Das geht nicht."
+
+"Stimmt.", grinste Ulo. "Das gute Maedchen ist wohl lesbisch, wie?"
+
+Azzuro zuckte die Schultern. "Wer weiss das schon?"
+
+"Hm, wenn ich nur unter Frauen sein wollte, ginge ich auch ins Kloster."
+
+Azzuro lachte. "Spielt es eine Rolle? Ich meine, wenn sie ihn nicht will, dann
+kann er sich auf den Kopf stellen und mit den Fuessen Hurra schreien, er wird
+nicht erhoert."
+
+"Grausame Welt.", seufzte Romeo von drinnen. "Ich kann einfach nicht an sie
+herankommen. Sie ist schoen, sie ist klug und ihre Weste ist so weiss wie
+Schnee. Nichts, aber auch gar nichts gibt mir eine Moeglichkeit, sie zu
+erpr..." Er unterbrach sich schnell.
+
+"Wollte er eben erpressen sagen?" fragte Ulo.
+
+"Ich nehme es an. Warum?"
+
+"Maenner!"
+
+"Du meinst Menschen." korrigierte Azzuro sie.
+
+"Ich meine Maenner. Wenn ich noch ein einziges Mal hoere, dass ein Mann eine
+Frau rein und keusch nennt, weiss ich, was ich davon zu halten habe."
+
+"So typisch ist Romeo nun auch wieder nicht."
+
+Ulo schob den Einwand mit einer ungeduldigen Bewegung ihres Fluegels beiseite.
+"Ich werde nie wieder einem Mann weiter trauen, als ich ihn spucken kann."
+
+"Wir koennen nicht spucken, wir sind Voegel."
+
+"Eben."
+
+Azzuro schuettelte den Kopf ueber soviel Unvernunft. "Du brauchst ja auch
+keinem Mann zu trauen, du hast ja mich."
+
+"Um so schlimmer."
+
+"He!", machte Azzuro.
+
+Benevolio betrachtete seinen Freund besorgt. "Lass dir einen Tip geben, Romeo.
+Vergiss sie."
+
+"Vergessen? Sie? Genauso gut koennte ich das Atmen vergessen."
+
+"Kann er doch gar nicht.", meinte Azzuro.
+
+"Das will er damit ja sagen.", informierte ihn Ulo.
+
+"Ich sag dir, wie du sie vergessen kannst." Benevolio sah sich genoetigt, ein
+wenig lauter zu sprechen, um das Geschrei der beiden Kraehen vor dem Fenster
+zu uebertoenen. "Schau dich einfach ein wenig um. Andere Muetter haben auch
+schoene Toechter."
+
+"Ach, damit machst du es ja nur noch schlimmer. Wenn ich andere Frauen sehe,
+vergleiche ich sie immer mit ihr und dann haben die anderen verloren. Lass
+mich lieber allein, ich will in meinem Schmerz ertrinken."
+
+"Er koennte ihn ersaeufen.", schlug Ulo vor.
+
+"In Schnaps?", fragte Azzuro.
+
+"Worin sonst? Meinst du, er versuchte, ihn mit einem Stein zusammen in einen
+Sack zu stecken und in den Fluss zu werfen?"
+
+Benevolio kannte das Leid der Jugend und grinste verschaemt. "Warte ab, ich
+lasse mir was einfallen."
+
+Kaum hatte Benevolio den Raum verlassen, als Romeo sich auf das Bett warf und
+zum Steinerweichen schluchzte.
+
+"So ein Jammerlappen.", bemerkte Ulo.
+
+"Nun hoer schon auf, er ist noch jung und er ist verliebt."
+
+"Schon gut, das ist der Freibrief fuer jede nur denkbare Bloedheit."
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite4 b/d/seher/haeuser/special/special/rom_jul/seite4
new file mode 100644
index 0000000..3041d58
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite4
@@ -0,0 +1,258 @@
+DER ERSTE AKT
+ DIE ZWEITE SZENE
+
+Ulo und Azzuro beschlossen, Romeo nicht weiter dabei zuzusehen, wie er sich
+seinem Liebeskummer hingab, sondern lieber zum Haus Capulets zu fliegen. Im
+Wohnzimmer der Villa Capulets fanden sie den inzwischen angezogenen Hausherren
+mit seinem Freund Paris.
+
+"Noch so ein Stutzer.", bemerkte Azzuro und deutete mit dem Schnabel auf
+Paris.
+
+"Was hast du denn gegen ihn?", fragte Ulo. "Ich finde, er hat einen
+knackigen..."
+
+"Ulo!"
+
+"...Ausdruck im Gesicht.", schloss Ulo lahm.
+
+"Seit wann gefallen dir denn Menschen?" Azzuro verstand seine Gefaehrtin
+nicht.
+
+"Es ist gut, dass ich so alt bin.", raesonierte Capulet drinnen.
+
+"Pfft.", machte Azzuro. "Das nennt man dann aus der Not eine Tugend machen."
+
+Ulo grinste nur zur Antwort.
+
+"Wenn ich juenger waere, fiele es mir wahrscheinlich schwerer, endlich Frieden
+mit Montague zu halten." Capulet seufzte.
+
+Ulo lachte kraechzend. "Kannst du dir vorstellen, wie es aussaehe, wenn die
+beiden alten Maenner aufeinander losgingen?"
+
+Azzuro lachte mit. "Nur zu gut. Wahrscheinlich wuerden sie sich mit
+Pillendoeschen bewerfen."
+
+"Oder ihre Krankengeschichte aufschreiben."
+
+Azzuro schuettelte sich. "Also _das_ waere dann wirklich zuviel."
+
+"Es ist schon eine Schande, dass der alte Streit immer noch existiert.",
+meinte Paris.
+
+"So geht es nun einmal. Irgendwann machen sich solche Streitigkeiten
+selbstaendig.", antwortete Capulet.
+
+"Das erste vernuenftige Wort, dass der Alte sagt." Haette Ulo Haende anstelle
+der Fluegel gehabt, so haette sie wohl Beifall geklatscht.
+
+Paris nickte bedaechtig. "Damit hast du wahrscheinlich Recht, aber lass uns
+von etwas angenehmeren reden. Was haeltst du von dem Gedanken, dass ich Julia
+heirate?"
+
+Azzuro warf einen kritischen Blick auf Paris. "Abstand haelt er, wenn er
+schlau ist."
+
+"Im Grund habe ich nichts dagegen, aber sie ist meine einzige Tochter und
+ausserdem noch zu jung. Sie weiss ja noch nicht einmal, was es bedeutet, zu
+heiraten. Warte, bis sie sechzehn ist, dann hast du meinen Segen."
+
+"Hm, ob sie ueberhaupt schon weiss, wie das mit den Bienchen und den Bluemchen
+ist?", fragte sich Ulo.
+
+"Sie wird es schon herausfinden. Immerhin laesst der Alte ihr ja noch zwei
+Jahre."
+
+"Ich kenne Frauen, die juenger waren", wandte Paris ein "und trotzdem mit
+einem Stall voller Kinder gluecklich wurden."
+
+"Sieh dir nur meine Frau an. Du hast nicht viel von ihr, wenn du sie so jung
+heiratest, glaub mir." Capulet zuckte mit den Schultern.
+
+"Dieser..." Ulo holte tief Luft.
+
+"Beherrsch dich." Azzuro zupfte sie an den Schwanzfedern.
+
+Paris nickte. "Wenn du meinst, werde ich mich natuerlich danach richten."
+
+"Ich koennte ihnen...", grollte Ulo.
+
+Azzuro ahnte, was jetzt kam. "Tus nicht."
+
+Ulo seufzte tief und verfluchte einmal mehr die Goetter, die sie zwangen, eine
+stumme Beobachterin zu sein.
+
+"Vertrau mir, ich habe schon manche Frau gesehen.", meinte Capulet.
+
+"Das glaub ich dem alten Bock.", grinste Azzuro.
+
+"Fang du nicht auch noch an, dich wie ein Macho zu benehmen.", fuhr Ulo ihren
+Gefaehrten an.
+
+"Heute abend gebe ich ein Fest, Paris, da kannst du Julia kennenlernen." Er
+zwinkerte seinem Freund zu. "Schau dich um und such dir unter den jungen
+Frauen einen angenehmen Zeitvertreib fuer die naechsten beiden Jahre. Und was
+Julia angeht, so umwirb sie ein bisschen, damit sie in zwei Jahren nicht
+gleich in Traenen ausbricht, dann kannst du sie haben."
+
+"Wenn das deine Entscheidung ist, werde ich mich natuerlich daran halten."
+
+Capulet wandte sich um und schuettelte heftig eine kleine Glocke, die auf dem
+Tisch stand. Ulo haette sich am liebsten die Ohren zugehalten, denn die Glocke
+war offensichtlich gebrochen und bewies, dass Capulet am falschen Ende sparte.
+Als der Diener das Zimmer betrat, drueckte Capulet ihm eine Liste in die Hand.
+"Geh und suche all die Leute auf, die auf dieser Liste stehen, richte ihnen
+aus, dass sie herzlich eingeladen sind."
+
+Der Diener warf einen zweifelnden Blick auf die Liste in seinen Haenden.
+"Alle?"
+
+"Was dachtest du denn?" Capulet schuettelte den Kopf und hakte sich bei Paris
+unter. "Komm mit, wir werfen einen Blick auf die Rosen."
+
+"Alle..." Der Diener, den wir, obwohl er keine weitere Bedeutung hat und
+eigentlich zu den Namenlosen gehoert, James nennen wollen, starrte die Liste
+an, als koenne er sie mit seinen Blicken in Brand setzen. "Alle soll ich
+einladen.", brummte er. "Als ob ich lesen koennte."
+
+Ulo zwinkerte belustigt. "Na, so ein Pech. Da wird Paris ja heute abend
+alleine sein."
+
+"Warten wirs ab.", antwortete Azzuro.
+
+"Jetzt steh ich hier, ich armer Tor." James seufzte.
+
+"Ich hasse es, wenn sie die Zitate vertauschen." Azzuro schuettelte sich. "Wie
+soll man denn da den Ueberblick behalten."
+
+Die Kraehen folgten James, als er mit der Liste in der Hand das Haus verliess,
+um jemanden zu finden, der ihm sagte, wen er einladen sollte. Wie so viele
+Menschen war auch Herr Capulet jemand, der Dingen, die er schwarz auf weiss
+vor sich sah, unbedingtes Vertrauen schenkte. Wer jedoch je erlebt hat, wie
+Geruechte wirken, weiss, dass das gesprochene und erinnerte Wort dem
+niedergeschriebenen immer ueberlegen ist. Geschichte, so wissen wir, besteht
+nur zu einem verschwindend kleinen Teil in Dokumenten. Seien Sie ehrlich, wem
+glaubten Sie denn eher: einem verstaubten und halbverschimmelten Brief, der
+besagt, dass Ihr Grossvater gar nicht Ihr Grossvater ist, oder den
+Erzaehlungen ihrer Grossmutter, die einen wunderbaren Kuchen backt, um ihre
+Behauptung zu untermauern?
+
+"Wenn James sich eine Menge Aerger ersparen will, braucht er nur die Liste als
+Klopapier zu benutzen.", meinte Ulo.
+
+James blickte verwirrt auf. "Was meinst du damit?"
+
+"Krah.", antwortete Azzuro an Ulos statt.
+
+"Ich hab genau gehoert, dass du geredet hast."
+
+"Krahrah.", machte nun auch Ulo.
+
+"Jajaja, Krahrahrah." James trat missmutig gegen einen Stein und fluchte, da
+der Stein den ungleichen Kampf gewann. "Ich habe es gehoert, habe ich."
+
+"Nichts hast du gehoert.", meinte Ulo. "Krah.", fuegte sie nach einer Pause
+hinzu.
+
+"Ach, leck mich. Erst die dumme Liste und dann auch noch eine Kraehe, die
+redet."
+
+"Nicht weniger dumm als die Liste.", kommentierte Azzuro so leise, dass nur
+Ulo ihn verstand.
+
+"He, wenn es diese Liste nicht gaebe, wuerde Romeo..."
+
+"Halt den Schnabel!", fuhr Azzuro seine Gefaehrtin an.
+
+"Wer ist Romeo?", verlangte James zu wissen, der immer sehr genau hinhoerte,
+wenn ein Gespraech nicht fuer ihn bestimmt war.
+
+Zu Ulos und Azzuros Glueck rief die Koechin nach James und gab ihm eine
+fluessige Staerkung mit auf den Weg. So schnell, wie der Schnaps seinen Weg in
+Jamesens Magen fand, vergass dieser die beiden Kraehen und machte sich an
+seinen Auftrag. Auch Sie und ich haben Glueck, liebe Leserin, lieber Leser,
+denn der erste Mensch, dem James begegnete, war Benevolio, der Romeo im
+wahrsten Sinne des Wortes hinter sich herschleppte. Stellen Sie sich nur vor,
+es sei jemand anders gewesen, dem James ueber den Weg lief. Vielleicht jemand,
+den Herr Capulet einzuladen vergessen hatte, dann verliefe unsere Geschichte
+von hier ab voellig anders, als Sie sie hoeren wollen und ich muesste mir
+einfallen lassen, wie ich dies den Goettern der Mythenwelt erklaere.
+
+"Und der Gewerkschaft.", sagt Ulo amuesiert.
+
+_Und_ _der_ _Gewerkschaft_, _ja_. _Sei_ _gewarnt_, _Ulo_. _Wenn_ _du_ _mir_
+_noch_ _einmal_ _dazwischenquasselst_, _streiche_ _ich_ _dich_ _aus_ _der_
+_Geschichte_!
+
+"Das glaubst du doch selbst nicht. Wenn du das machst, trete ich in Streik.",
+knurrt Azzuro und schwenkt ein rotes Faehnchen.
+
+_Schon_ _gut_. _Versucht_ _wenigstens_, _euch_ _anstaendig_ _zu_ _benehmen_.
+
+Benevolio grinste seinen Cousin an. "Hast du dich schon einmal im Kreis
+gedreht, bis dir schwindlig wurde?"
+
+"Aeh..." Romeo verstand nicht, worauf sein Freund hinaus wollte.
+
+"Wenn man sich dreht, bis einem schwindlig wird, kann man sich helfen, indem
+man sich in die andere Richtung dreht."
+
+"Das weiss ich."
+
+"Genauso ist es auch mit dir. Wenn du Rosaline nicht bekommen kannst, dann
+schau dir eine andere an und schon fuehlst du dich besser."
+
+"Das waere ja den Teufel mit Beelzebub austreiben.", kommentierte Azzuro.
+
+"Wenn's denn hilft." Romeo zuckte die Schultern.
+
+"Sie koennen nicht zufaellig lesen?", fragte James. "Guten Tag, uebrigens."
+
+"Kommt darauf an.", brummte Romeo schlechtgelaunt.
+
+"Ach, schon gut, dann suche ich mir eben jemanden, der es kann."
+
+"Ich kann lesen." Nun hatte die Neugierde Romeo gepackt.
+
+Romeo nahm Herrn Capulets Liste entgegen und entzifferte unter Stoehnen und
+Fluchen die Handschrift. Als er fertig war, gab er die Liste zurueck.
+
+"Danke, aber das brauche ich jetzt nicht mehr, schliesslich habe ich mir alles
+gemerkt."
+
+James war sichtlich stolz auf sein Gedaechtnis.
+
+"Wohin sollen denn all die Leute kommen?", wollte Romeo wissen.
+
+"Herr Capulet gibt heute ein Fest. Wissen Sie, kommen Sie doch einfach vorbei,
+wenn sie nicht gerade den Montagues die Stange halten."
+
+Benevolio grinste. "Das ist die Gelegenheit."
+
+"Du sprichst heute in Raetseln."
+
+"Hast du denn gar nicht darauf geachtet, was du vorgelesen hast?"
+
+"Ich war mit der Handschrift beschaeftigt."
+
+"Heute abend sind sowohl Rosaline als auch die schoensten Frauen Veronas bei
+Capulet zu Gast."
+
+"Ja und? Sollen wir jetzt ein eigenes Fest geben?"
+
+"Nein. Wir gehen da hin und dann kannst du mir sagen, ob Rosaline wirklich die
+Schoenste ist. Ich bin gespannt, was du sagst, wenn wir erst da sind."
+
+"Sie ist die Allerschoenste."
+
+"Sicher." Benevolio taetschelte Romeos Schulter. "Aber bis jetzt hast du sie
+noch nicht gesehen, wenn alle anderen Schoenheiten dabei waren."
+
+"Hoert sich an wie eine Miss-Wahl." meinte Azzuro.
+
+Romeo ueberlegte eine Weile, dann nickte er. "Ich komme mit, aber nicht, weil
+ich mir die anderen Frauen ansehen will, sondern bloss um Rosaline zu sehen."
+
+Benevolio seufzte. "Warten wir ab."
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite5 b/d/seher/haeuser/special/special/rom_jul/seite5
new file mode 100644
index 0000000..26f28b3
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite5
@@ -0,0 +1,213 @@
+DER ERSTE AKT
+ DIE DRITTE SZENE
+
+Im Boudoir Frau Capulets beobachteten Ulo und Azzuro zwei reichlich ungleiche
+Frauen. Die eine war Frau Capulet, zierlich und wenn schon nicht huebsch, dann
+doch wenigstens geschickt geschminkt. Die andere war Polly, Julias Amme, die
+dem Klischee ihres Berufes gerecht wurde, denn sie war frueh alt geworden und
+weniger geschickt im Umgang mit Schminke als Frau Capulet. Rundlich und
+inzwischen fast zahnlos, mit wirrem, fast ergrautem Haar und Falten, die man
+Alpen nennen wuerde, wenn sie nur ein wenig groesser waeren, wirbelte sie so
+schnell ihre krampfadrigen Beine sie tragen wollten durch das Zimmer.
+
+"Ich hab ihr gesagt, dass sie herkommen soll. Jawohl, das habe ich. Und ich
+vergesse nie etwas.", murmelte sie vor sich hin.
+
+"Sie ist jedenfalls nicht hier.", kommentierte Frau Capulet.
+
+Polly holte asthmatisch Luft und rief: "Julia! Wo steckst du, Schaetzchen?"
+
+"Ich bin ja schon da.", meinte Julia von der Tuer her.
+
+"Oh. Sie muss aber noch ziemlich lange auf die Weide." Azzuro schuettelte den
+Kopf.
+
+"Ist ja noch ein rechter Backfisch."
+
+"Ich geb' dir gleich Backfisch auf den Schnabel.", drohte Ulo.
+
+"Sieh sie dir doch an. Wenn sie einen Pfirsichkern verschluckt, sieht sie aus,
+als sei sie im fuenften Monat!"
+
+"Das waechst sich noch aus."
+
+"Bestimmt. Aber bis dahin holt man sich blaue Flecken."
+
+Ulo drehte sich empoert um und antwortete nicht mehr.
+
+"Was ist denn, Mama?", wollte Julia wissen.
+
+"Wie alt ist Julia jetzt, Polly?", fragte Frau Capulet.
+
+"Die Schminke hat ihr das Gehirn verkleistert." Ulo kicherte. "Sie weiss
+schon nicht mehr, wie alt ihre Tochter ist."
+
+"Ich vergesse nie etwas und ich sage Ihnen, Julia ist noch nicht vierzehn.",
+antwortete Polly. "Am ersten August ist sie geboren, da wette ich meine
+restlichen Zaehne drauf."
+
+"Erster August, ja. Koennte hinkommen." Frau Capulet hatte sichtlich Muehe,
+sich an die Geburt Julias zu erinnern.
+
+"Jawohl, da bin ich sicher, und ich vergesse nie etwas. Ich weiss sogar noch,
+wie sie an ihrem dritten Geburtstag hinfiel und sich eine Beule holte, so
+gross wie meine dicke Zehe. Und damals, das weiss ich auch noch, hat mein Mann
+Gott-hab-ihn-selig sie in den Arm genommen, weil sie so schrecklich geweint
+hat. Und er sagte, dass sie jetzt noch jung genug sei, um auf das Gesicht zu
+fallen, aber wenn sie aelter wuerde, werde sie gewitzter sein und auf den
+Ruecken fallen. Jawohl, das weiss ich noch, als waere es gestern gewesen.
+Sehen Sie, was ich fuer ein gutes Gedaechtnis habe."
+
+"Ja, Sie haben ein gutes Gedaechtnis." Frau Capulet schaute abwesend aus dem
+Fenster und versuchte vergeblich, Pollys Nebensaetze zu sortieren.
+
+"Jajaja. Und mein Mann sagte noch, wenn sie gewitzt sei, werde sie auf den
+Ruecken fallen und nicht auf das Gesicht. Und das Lustigste daran war, dass
+meine kleine Julia gleich aufhoerte, zu weinen und nur noch 'Ja.' sagte. Ganz
+so, als habe sie das alles schon verstanden. Ich musste ganz schrecklich
+lachen, als mein Mann sagte, dass sie auf den Ruecken fallen wuerde, wenn sie
+aelter waere."
+
+Mutter und Tochter stoehnten wie aus einem Munde und sahen sich dann in
+seltenem Einverstaendnis grinsend an.
+
+"Du warst das huebscheste Kind, das ich je gesehen habe, Julia. Und ich
+vergesse nie etwas. Mein groesster Wunsch waere, dich noch verheiratet zu
+sehen."
+
+"Das sollte sie besser nicht wuenschen.", meinte Azzuro.
+
+"Warum denn nicht?" wollte Ulo wissen.
+
+"Weil die Goetter sie sterben lassen koennten, wenn sie ihren Wunsch hat. So
+geht das doch in Mythen."
+
+"Ums Heiraten geht es gerade.", sagte Frau Capulet.
+
+Sowohl im Zimmer als auch auf dem Ast der beiden Turtelkraehen wurde es
+schlagartig so still, dass man die beruehmte Stecknadel haette fallen hoeren
+koennen.
+
+"Das waere ja noch schoener.", meinte Julia.
+
+"Nicht wahr?", fragte Polly, die sie absichtlich missverstand. "Wenn ich nicht
+wuesste, wer dich gestillt hat, als du noch klein warst, und ich vergesse nie
+etwas, dann sagte ich, dass du die Klugheit nicht nur mit Loeffeln gefressen,
+sondern schon mit der Milch getrunken haettest."
+
+"Ich denke noch nicht einmal darueber nach." Julia hatte sichtlich Muehe,
+nicht auf die Brueste ihrer Amme zu starren.
+
+"Wenn ich mich nicht verrechne, dann war ich schon deine Mutter, als ich noch
+nicht so alt war wie du."
+
+"Im Leben nicht.", meinte Azzuro.
+
+"Mit dem Rechnen steht sie auf Kriegsfuss, vergiss das nicht. Immerhin kann
+sie ja noch nicht einmal sagen, wie alt Julia ist." Ulo betrachtete Frau
+Capulet eingehend. "Aber so ungefaehr koennte es hinkommen. Sie ist bestimmt
+nicht halb so alt wie ihr Mann."
+
+"Wahrscheinlich warst du schon reifer, Mama."
+
+"Wenn sie nicht merkt, dass Julia sie auf den Arm nimmt, ist sie bestimmt
+schon um einiges reifer." Azzuro zupfte bedaechtig eine Feder zurecht.
+
+"Um wen geht es ueberhaupt?", wollte Julia wissen.
+
+"Paris hat sich in dich verliebt.", antwortete ihre Mutter.
+
+"Oh." Julia schien den Gedanken zu verarbeiten.
+
+Polly brach in helles Entzuecken aus. "Ein richtiger Mann, Julia. Stell dir
+das nur vor! Ausserdem findest du bestimmt keinen Besseren, er ist weich wie
+Wachs."
+
+"Seltsame Prioritaeten.", murmelte Azzuro.
+
+"Sie hat schon recht. Das ist es, worauf es bei einem Mann ankommt." Ulo
+grinste niedertraechtig.
+
+"Ach?"
+
+"Wuesstest du etwas anderes?" Ulo zerzauste das Gefieder ihres Gefaehrten
+wieder.
+
+"Denk darueber nach, Julia. Er ist wirklich eine gute Partie." Frau Capulet
+wandte sich ihrem Spiegel zu.
+
+"Ganz richtig, eine wunderbare Partie.", stimmte Polly aus vollem Herzen zu.
+
+Frau Capulet betrachtete im Spiegel das zweifelnde Gesicht ihrer Tochter. "Du
+wirst ihn heute abend kennenlernen. Schau ihn dir an, dann wirst du mir
+zustimmen, dass er wirklich ein netter Mann ist."
+
+"Er hatte ja Zeit genug, einer zu werden.", versetzte Julia.
+
+"Es fehlt ihm nur noch eines zu seinem Glueck. Die richtige Frau."
+
+"Und das soll ich sein?"
+
+"Er ist ein Buch, das noch keinen Einband hat."
+
+"Zumindest ist er so verknittert." Julia zog ein Gesicht.
+
+"Und wenn du ihn heiratest, dann kann man ihn nach dem Einband beurteilen.",
+sprang Polly hilfreich ein.
+
+"Ich meine mich zu erinnern, dass du mich gelehrt haettest, genau das nicht zu
+tun. Natuerlich ist mein Gedaechtnis nicht so gut wie das deine, Polly."
+
+"Sieh es doch mal so: Es gibt bestimmt haesslichere, aeltere und aermere
+Maenner als ihn.", sprang Polly hilfreich ein.
+
+Ulo schuettelte sich angewidert. "Das klingt ja fast wie eine Drohung."
+
+"Ein Mann wie er wird deine Position nicht verschlechtern.", fuegte Frau
+Capulet hinzu.
+
+"Nicht verschlechtern!" Polly war entsetzt. "Frauen wachsen an ihren Maennern,
+also verbessert sich Julias Position sogar."
+
+"Bestimmt werde ich beizeiten einiges ueber Krankenpflege lernen."
+
+"Du tust gerade so, als stuende er schon mit einem Bein im Grab." Frau Capulet
+schuettelte unwillig den Kopf. "So alt ist er wirklich noch nicht."
+
+"Wenn du darauf bestehst, werde ich mir wohl seine Annaeherungsversuche
+gefallen lassen muessen, Mama."
+
+"Das ist doch eine Farce!", empoerte sich Ulo.
+
+"Wieso?", verlangte Azzuro zu wissen. "Immerhin hat sie ihre Tochter gefragt."
+
+"Hat sie? Ich finde, das klang eher wie ein Befehl. Und Polly sollte zu ihr
+halten, statt dessen laesst sie Julia im Stich."
+
+"Nein, das tue ich nicht." Polly war zum Fenster getreten und hatte Ulos
+letzte Worte gehoert.
+
+"Doch."
+
+"Nein. Julia muss so oder so heiraten, da ist ein Mann wie Paris nicht die
+schlechteste aller Moeglichkeiten."
+
+"Und wenn sie ihn gar nicht will?"
+
+"Sie wird ihn schon wollen. Wie mein Mann damals sagte, sie wird schlau sein
+und auf den Ruecken fallen."
+
+Ulo schnaubte wuetend.
+
+_Ulo_! _Das_ _ist_ _die_ _letzte_ _Warnung_!
+
+"Polly, wenn du sie jetzt mit diesem Paris verkuppelst, bekommt sie nie den
+Mann, der ihr bestimmt ist.", sagte Ulo.
+
+Azzuro wirft einen misstrauischen Blick auf den Radiergummi, der Ulo aus der
+Geschichte entfernen soll und knurrt nur drohend: "Streik gefaellig?"
+
+"Das ist nicht wahr.", verteidigte sich Polly.
+
+"Du wirst es sehen."
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite6 b/d/seher/haeuser/special/special/rom_jul/seite6
new file mode 100644
index 0000000..a0972db
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite6
@@ -0,0 +1,105 @@
+DER ERSTE AKT
+ DIE VIERTE SZENE
+
+"Ich mag nicht.", murrte Romeo und versuchte, Benevolios Hand abzuschuetteln,
+die ihn langsam aber stetig auf die Villa der Capulets zuzog.
+
+"Ach komm schon, stell dich nicht so an." Mercutio stupste seinen Freund in
+die Seite. "Wir werden tanzen und uns darueber amuesieren, wie der alte
+Capulet sich vollaufen laesst."
+
+"Wir fliegen sowieso raus, noch bevor wir drinnen sind."
+
+"Das geht nicht.", kommentierte Benevolio, der sich fest vorgenommen hatte,
+Romeo aufzuheitern. "Es wird bestimmt lustig."
+
+"Klar. So lustig, wie mein Traum letzte Nacht."
+
+"Hey, Traeume sind Schaeume.", meinte Mercutio.
+
+"Was hast du denn getraeumt?" Benevolio nahm seinen Freund ernster.
+
+"Bestimmt von einer Frau.", sagte Mercutio lachend. "Davon traeumen doch die
+meisten Leute."
+
+"Nein, eine Frau war es nicht."
+
+Mercutio rueckte betont einen Schritt von Romeo ab. "Aeh, gibt es da etwas,
+was du uns sagen solltest? Nicht, dass ich dir zu nahe treten wollte, aber,
+aeh..." Er grinste breit.
+
+"Romeo, hoer mit dem Unsinn auf. Jeder traeumt einmal. Du hast bestimmt nur
+etwas Unrechtes gegessen."
+
+"Ich habe gar nicht gegessen."
+
+"Na, siehst du, was sage ich?"
+
+Benevolio warf einen verwirrten Blick auf Mercutio, beschloss dann aber, das
+Thema nicht weiter zu verfolgen und zupfte statt dessen Romeos Krawatte
+zurecht. "So, jetzt siehst du gut aus."
+
+"Ich habe wirklich keine Lust zu tanzen." Romeos Gesicht hatte einen Ausdruck,
+den jede Mutter sofort erkannt und mit einem strengen Blick geahndet haette.
+
+"Dann geh wenigstens mit hinein und tu so, als ob du dich amuesierst."
+Benevolio rueckte auch seine eigene Krawatte gerade. "Der Appetit kommt mit
+dem Essen."
+
+"Siehste, sag ich doch." Azzuro imitierte ueberzeugend Mercutios Stimme.
+
+"Hm, Mercutio, wir sprechen inzwischen ueber etwas anderes." Romeo konnte sich
+ein Grinsen nicht verkneifen.
+
+"Ich?" Mercutio deutete auf sich selbst. "Ich habe nichts gesagt."
+
+"Wisst ihr, ich habe getraeumt, dass ich heute meinem Verhaengnis begegne."
+Romeo schaffte es erstaunlich schnell, seine melancholische Stimmung
+wiederzubeleben.
+
+"Das Verhaengnis kenne ich. Es faengt mit R an und hoert mit osaline auf.",
+meinte Benevolio. "Warte es erst einmal ab, vielleicht gefaellt sie dir gar
+nicht mehr, wenn du sie erst einmal betrunken siehst."
+
+"Die edle, durchgeistigte und wunderschoene Rosaline und sich betrinken?
+Benevolio, wie kannst du so etwas unterstellen!" Mercutio legte die Arme um
+seine Freunde.
+
+"Wahrscheinlich wird es Romeo viel mehr stoeren, wenn er sie mit den anderen
+gackernd in der Ecke stehen sieht."
+
+"Sie gackert nicht.", brummte Romeo veraergert.
+
+"Oh, ich vergass." Mercutio zwinkerte Benevolio zu. "Sie kichert nur
+maedchenhaft hinter der vorgehaltenen Hand."
+
+"Ach, Romeo, was sind Sie aber auch fuer ein Schlimmer.", quiekte Benevolio im
+Falsett.
+
+"Hoert auf, ich komme ja schon mit, aber tanzen werde ich nicht."
+
+"Das werden wir ja sehen. Vielleicht frage ich Rosaline, ob sie mit mir tanzt,
+dann wette ich, dass du nichts eiligeres zu tun hast, als mich abzuloesen."
+Mercutio nahm Benevolios Hand. "Ach bitte, schoenste Rosaline, wollen Sie
+nicht mit mir tanzen?"
+
+"Oh, nur zu gerne, liebster Mercutio." Benevolio machte einen Knicks. "Aber
+treten Sie mir nicht so auf die Fuesse wie Romeo!"
+
+Romeo ergriff Benevolios Krawatte und zog kraeftig daran. "Ich bin ihr noch
+nie auf die Fuesse getreten."
+
+"Weil du noch nie mit ihr getanzt hast.", grinste Benevolio.
+
+"Ausserdem, wenn du ihr noch nie auf die Fuesse getreten bist, verstehe ich
+nicht, warum sie dich nicht lieben will.", fuegte Mercutio hinzu.
+
+Romeo verzog schmollend das Gesicht. "Das weiss ich auch nicht."
+
+"Schluss jetzt, wir gehen hinein und du wirst dich schon amuesieren, Romeo."
+
+"Das klingt wie eine Drohung, Benevolio.", lachte Mercutio. "Amuesier dich,
+Romeo, bis dir das Lachen im Halse stecken bleibt."
+
+"Das tut es bestimmt.", meinte Romeo duester.
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite7 b/d/seher/haeuser/special/special/rom_jul/seite7
new file mode 100644
index 0000000..9ffa64b
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite7
@@ -0,0 +1,420 @@
+DER ERSTE AKT
+ DIE FUENFTE SZENE
+
+Der Abend kam und mit ihm die Gaeste, die James dank Romeos Hilfe gefunden
+hatte. Sie wissen, wie es bei solchen Festen zugeht: Die Menschen, die sich
+dort treffen, sind einander haeufig spinnefeind und kommen nur deshalb zur
+Party, weil sie jemand anderem Bosheiten sagen wollen, die nichtsdestoweniger
+freundlich klingen. Niemand geht gerne zu einer solchen Veranstaltung, doch
+man kann sich nicht erlauben, ihr fern zu bleiben, weil man sonst die
+Geruechte verpasst, die bis zur naechsten Party den Gespraechsstoff fuer die
+ganze gute Gesellschaft bilden werden.
+
+James wirbelte mit einem Staubtuch in der Hand ein letztes Mal durch das
+Wohnzimmer der Capulets, aus dem man wohlweislich alles Zerbrechliche entfernt
+hatte. "Wo steckt Potpan?"
+
+"Was weiss denn ich?", fragte sein Kollege.
+
+"Da stehen ja noch die Stuehle! Muss ich denn alles selbst machen?" James
+schnappte sich einen Kuechenjungen bei den Haaren und schubste ihn in Richtung
+der unschuldig dastehenden Stuehle. "Los, bring sie raus."
+
+"Jawoll, Jungchen, hol ihn raus." Jamesens Kollege hielt sich den Bauch.
+
+"Keine Zeit jetzt fuer Witze.", grollte James. "Sieh zu, dass ein Stueck von
+dem Marzipan fuer mich uebrigbleibt."
+
+"Mach ich.", antwortete der andere und verschwand mit einem Tablett auf dem
+Arm in Richtung Kueche.
+
+James stapelte die Stuehle aufeinander. "Potpan!"
+
+"Ich bin ja schon da. Komm mal wieder runter." Potpan leckte sich die Reste
+der Schokoladensosse von den Fingern.
+
+"Wo hast du eigentlich nicht die Finger drin?", fragte James. "Los, los, wir
+haben nicht ewig Zeit. Ist die Buehne fertig?"
+
+"Ist sie."
+
+"Du hast auch die Ruhe weg."
+
+"Besser ruhig bleiben als einen Herzinfarkt bekommen.", grinste Potpan. "Hm,
+ist das Marzipan?"
+
+"Es ist _mein_ Marzipan." James stopfte sich das Stueck in den Mund. "Bo eiben
+ie enn?"
+
+"Kein Grund, sich zu ueberschlagen, im Moment stehen sie auf der Terrasse und
+rauchen. Zeit genug, hier fertig zu werden."
+
+James schluckte den letzten Bissen hinunter und rieb sich den Bauch. "Das war
+gut. Also, weiter jetzt, den letzten beissen die Hunde."
+
+"Den letzten beisst James.", grinste Potpan.
+
+Die Musiker, die gerade mit dem Stimmen ihrer Instrumente fertig geworden
+waren, spielten den River Kwai Marsch und begleiteten damit James Abgang.
+
+"Jetzt zitieren sie nicht nur aus voellig anderen Quellen, jetzt spielen sie
+auch noch die falsche Musik." Azzuro schuettelte sich verzweifelt.
+
+"Goenn ihnen den Spass.", meinte Ulo. "Nachher muessen sie eh nur Schlager
+spielen."
+
+Azzuro deutete auf die Tuer. "Da kommen sie. Aber wo steckt denn Romeo?"
+
+"Der kommt bestimmt gleich." Ulo zuckte die Schultern. "Er wird das Rendezvous
+mit seinem Schicksal kaum verpassen wollen."
+
+"Klang aber vorhin ganz so. Na, wir werden sehen. Julia ist jedenfalls da."
+
+"In diesem weissen Kleid sieht sie ziemlich schlank aus." Ulo schuettelte den
+Kopf. "Sie haette besser etwas farbiges angezogen."
+
+"Schlank?" Azzuro schaute hinueber. "So nett kann auch nur eine Frau
+untertreiben."
+
+Frau Capulet, deren blondes Haar ueber das dunkelblaue Kleid zu fliessen
+schien, beugte sich zu ihrer Cousine herueber. "Meine Liebste, was fuer ein
+wunderschoenes Kleid du da traegst!" Ihre Augen funkelten. "Ich habe diesen
+Stil letztes Jahr schon an unserer Putzfrau bewundert, du musst mir unbedingt
+sagen, wo du es hast machen lassen."
+
+Helena laechelte und zeigte dabei zu viele Zaehne. "Aber nur wenn du mir
+sagst, welcher Friseur dein Haar zurichtet."
+
+Ulo bog sich auf ihrem Ast vor unterdruecktem Lachen. "Hast du das gehoert,
+Azzuro?" Sie prustete los. "Zurichtet..."
+
+"Hm?" Azzuros Aufmerksamkeit galt den juengeren unter den weiblichen Gaesten.
+
+"Diese Stichelei ist doch das schoenste an so einem Fest." Ulo war
+offensichtlich in ihrem Element.
+
+Herr Capulet breitete theatralisch die Arme aus. "Gegessen haben wir, jetzt
+wollen wir den Damen Gelegenheit geben, die Kalorien abzuarbeiten." Er
+verneigte sich uebertrieben vor Frau Capulet. "Meine Liebe?"
+
+Das Gesicht, das Frau Capulet zog, liess keinen Zweifel daran, dass bei den
+Qualitaeten ihres Gatten als Taenzer die Betonung auf der ersten Silbe von
+Qualitaet lag. "Vielleicht sollten wir heute die jungen Leute den Tanz
+eroeffnen lassen, mein Lieber." Sie winkte Julia und Paris heran. "Seid so
+lieb, Kinder."
+
+"Ganz recht, Liebste, wir werden allmaehlich zu alt dafuer.", stimmte Herr
+Capulet zu und erntete dafuer einen giftigen Blick von seiner Frau, den er
+jedoch tunlichst uebersah. "Was, Hermann, ist schon eine ganze Zeit her, dass
+wir nur zum Spass getanzt haben, nicht?"
+
+"Ja doch." Sein Cousin Hermann liess sich schwer neben ihn auf die Bank
+fallen. "Das ist bestimmt schon zwanzig Jahre her."
+
+"Ach, so lang kann das doch nicht sein. Schliesslich haben wir bei Lucentios
+Hochzeit noch maechtig die Maedchen gewirbelt.", lachte Capulet.
+
+"Nein, da bin ich ganz sicher. Schliesslich war Lucentios Hochzeit nur ein
+halbes Jahr nach Klein-Markus Taufe, und der wird demnaechst selber
+Schwiegervater."
+
+"Das kann doch nicht sein. Kinder, Kinder, wie die Zeit vergeht." Herr Capulet
+taetschelte die Hand seiner Frau und laechelte duemmlich, als ihm aufging, was
+er gerade gesagt hatte. "Aber damals gab es dich ja noch gar nicht, meine
+Liebe."
+
+"Pfft.", machte Frau Capulet und wandte sich wieder ihrer Cousine zu, die
+einen Moment lang die Beherrschung verlor und ueber das ganze Gesicht grinste.
+
+"Schau an, Hermann, wir bekommen sogar unerwarteten Besuch." Capulet erhob
+sich und ging auf Romeo und seine Freunde zu. "Willkommen, meine Herren, aber
+nur, wenn sie auch wissen wie man tanzt."
+
+Mercutio verbeugte sich andeutungsweise. "Ja, das wissen wir."
+
+"Dann fuehlen Sie sich ganz wie daheim."
+
+Romeos Augen schweiften durch den Saal und suchten Rosaline, bis sie an Julia
+haengenblieben. Einen Augenblick lang hielt die Welt den Atem an. Die Musiker
+verstummten, die Taenzer standen still, die aelteren Maenner liessen ihre
+Weinglaeser sinken, den Damen blieben fuer einen Moment die Bosheiten im Halse
+stecken und selbst James vergass fuer den Hauch eines Augenblicks das
+Schnapsglas in seiner Hand. Eine Gasse schien sich durch die Menschen hindurch
+aufzutun, in der die metaphorischen Blitze, die zwischen den Augen Romeos und
+Julias hin und herschossen keinen Schaden anrichten konnten.
+
+Dann fiel James das Glas aus der Hand und der Bann war gebrochen.
+
+Romeo ergriff den Aermel eines Kellners. "Wer ist sie?"
+
+"Die obligatorische Frage.", murmelte Azzuro und versuchte, die Faszination zu
+ueberspielen, die auch ihn erfasst hatte.
+
+"Keine Ahnung, ich bin nur zur Aushilfe hier.", antwortete der Kellner.
+
+"Die obligatorische Antwort." Ulo schwelgte in der Romantik der Situation.
+"Halt dich fest, Azzuro, jetzt legt er los."
+
+Azzuro stoehnte. "Ich geh mir derweil eine Fliege fangen."
+
+Auch Mercutio war Romeos verzueckter Gesichtsausdruck nicht entgangen. "Wo ist
+denn Rosaline?"
+
+"Wer ist Rosaline?", fragte Romeo. Er blickte zu Ulo hinueber, die sich auf
+ihrem Ast vorlehnte. "Sie ist wie eine Taube, die zwischen Kraehen fliegt, so,
+wie sie da drueben zwischen den anderen Frauen steht. So schlank wie eine
+junge Birke."
+
+Azzuro kam mit einer Motte im Schnabel zurueck und reichte sie Ulo. "Birke?
+Das sind die mageren Dinger, die bei jedem Sturm Schwierigkeiten haben, stehen
+zu bleiben, nicht?"
+
+"Du bist widerlich, Azzuro." Ulo verspeiste die Motte, ohne den Blick von
+Romeo zu lassen.
+
+"Ich habe noch nie eine Frau wie sie gesehen. Und ich Trottel dachte, ich
+liebte Rosaline!"
+
+"Trottel ist das richtige Wort.", murmelte Azzuro.
+
+"Sag ich doch die ganze Zeit.", versetzte Ulo.
+
+Tybalt drehte den Kopf und erkannte Romeo. "Was denn, wie denn? Das ist doch
+Romeo Montague, da drueben?", fragte er Herrn Capulet.
+
+"Ja und?" Herr Capulet verstand seinen Neffen nicht.
+
+"Er ist bestimmt nur hergekommen, um uns das Fest zu verderben." Tybalt loeste
+seinen Degen in der Scheide.
+
+"Wie kommst du denn darauf?"
+
+"Er ist ein Montague, oder? Kannst du dir etwas anderes vorstellen, als dass
+er keine Gelegenheit auslaesst, uns zu aergern?"
+
+"Das ihr jungen Leute auch immer nur das Schlechte in anderen sehen muesst. Er
+ist jung, also wird er hergekommen sein, um zu tanzen. Gib also Ruhe."
+
+"Lieber Onkel, dem werde ich's zeigen.", knurrte Tybalt.
+
+"Wenn du darauf bestehst, dann besiege ihn auf der Tanzflaeche."
+
+"Mit einem Degen in der Hand.", freute sich Tybalt.
+
+"Nein, mit einem Maedchen im Arm." Capulet dachte an seine Geldboerse und
+daran, dass er sich eine neuerliche Geldstrafe nicht leisten konnte. "Immerhin
+ist er ein Gast und im Gegensatz zu dir ist er mir heute abend noch nicht
+unangenehm aufgefallen."
+
+"Aber..." Tybalt konnte nicht aus seiner Haut.
+
+"Benimm dich, verstehst du? Ja, Livia, da hast du ohne Zweifel recht." Er warf
+Tybalt einen letzten Blick zu und kam dann seinen Pflichten als Gastgeber
+nach.
+
+"Oh-oh.", machte Ulo.
+
+"Er ist sauer.", stimmte Azzuro ihr zu.
+
+"Sauer? Er ist daemlich." Tybalt bezog Azzuros Kommentar auf seinen Onkel.
+
+"Krah.", antwortete Ulo.
+
+"Weisst du was, Kraehe?" Tybalts Augen glitzerten.
+
+"Krah?"
+
+"Ich werde Romeo zeigen, was ich von ihm halte. Vielleicht nicht jetzt, denn
+mein tueddeliger Onkel will mich ja nicht lassen, aber bald. Sehr bald."
+
+Azzuro sah Tybalt nach. "Das also war der Auftritt des Boesewichts."
+
+"Vergiss ihn. Guck lieber da rueber. Sind sie nicht niedlich?" Ulos Augen
+hatten einen Ausdruck, den Azzuro von Frauen kannte, die einander mit
+Kinderwagen im Park begegneten und ihre Kinder verglichen.
+
+Romeo hatte inzwischen den Brei in seinen Beinen besiegt und es geschafft,
+sich durch das Gedraenge der Gaeste zu Julia vorzuarbeiten. Nun stand er vor
+ihr und schien einen ernsthaften Versuch zu unternehmen, in ihren Augen zu
+ertrinken.
+
+"Er sieht laecherlich aus." Azzuro kannte kein Mitgefuehl fuer den frisch
+Verliebten. "Schnappt mit offenem Mund nach Luft wie ein Fisch auf dem
+Trockenen."
+
+Nach einer Weile sah Romeo auf seine Hand hinab und eine Eingebung zuckte
+durch sein Gesicht wie ein Blitz ueber einen dunklen Himmel. "Darf ich dir die
+Hand geben?"
+
+Azzuro stoehnte.
+
+"Warum?" Julia hatte Romane gelesen.
+
+"Ich moechte dir guten Tag sagen."
+
+"Ah. Ja, du darfst mir die Hand geben." Julias Seufzer verschmolz mit Azzuros,
+der sich auf einer Zimmerpflanze niedergelassen hatte.
+
+"Wenn ich dich anfasse...", fluesterte Azzuro. "Nein, warte. Wenn ich dich
+beruehre, fuehle ich mich wie ein kleiner Junge vor einem Weihnachtsbaum."
+
+Romeo wiederholte Azzuros Worte.
+
+"Weihnachtsbaum? Habe ich denn pieksige Nadeln? Oder bin ich zu aufgeputzt?"
+
+"Aeh..", machte Romeo und warf einen verzweifelten Blick auf Azzuro, der nur
+haemisch grinste und den angehenden Liebhaber seinem Schicksal ueberliess.
+Romeo holte tief Luft und ging im Geiste alle mit einem Weihnachtsbaum
+assoziierten Gedanken durch, doch abgesehen von den Nadeln und dem Schmuck,
+die Julia bereits erwaehnt hatte, wollte ihm nur der Duft einfallen. Moment,
+dachte er, der Duft! "Ich wollte sagen, du duftest wie ein Weihnachtsbaum. So,
+als sei ein ganzer Wald in einem einzigen Zimmer." Romeo fuehlte die Alpen von
+seinem Herzen fallen.
+
+Julia holte tief Luft, besann sich dann aber ihrer guten Manieren und statt zu
+bruellen, senkte sie die Stimme zu einem unheilverkuendenden Fluestern.
+"Willst du wirklich sagen, dass ich nach _HO-Frisch_ rieche?"
+
+"Was meint sie mit HO-Frisch?", fragte Azzuro verwirrt.
+
+"Haimliches-Oertchen-Frisch.", antwortete Ulo, die Romeos Leid nicht mehr
+ertragen konnte und ihm leise ins Ohr fluesterte: "Ich stehe vor dir wie ein
+Kind und bewundere deine Schoenheit. Wo du bist, werden Traeume wahr."
+
+Romeos Lippen bewegten sich, als er die Worte wiederholte und an der richtigen
+Betonung ueberlegte. Schliesslich fasste er sich ein Herz und sprach sie laut
+aus. Julia, die schon halb entschlossen gewesen war, den jungen Mann, der sich
+so toelpelhaft benahm stehenzulassen, schmolz dahin. "Wirklich?"
+
+"Oh, ja.", versicherte ihr Romeo. "Und suess wie ein Marzipanapfel." Nun, da
+er einen Hinweis bekommen hatte, kam seine Zunge mit dem Aussprechen der
+Komplimente kaum noch nach. "Dein Haar ist golden wie das Kleid des Engels,
+den wir daheim immer auf die Spitze setzen. Deine Haende sind genauso zierlich
+wie seine. Weisst du, er ist aus Wachs, und leider ist er einmal zu nahe an
+eine Kerze geraten und dabei sind die Haende ein bisschen geschmolzen. Aber
+man kann immer noch sehen, dass es Haende sind. Dein Kleid glitzert wie die
+Staniolsterne, die wir immer werfen, damit sie nicht so hingesetzt aussehen.
+Deine Augen schimmern wie die Kerzen und sowieso habe ich das Gefuehl, dass
+sie mich gleich verbrennen werden." Auf den letzten Satz war Romeo besonders
+stolz, denn er hatte einmal in einem Roman seiner Mutter gestoebert und war
+ueber die Worte _brennende_ _Liebe_ gestolpert.
+
+Julia ueberlegte kurz, ob sie auf die geschmolzenen Haende des Engels genauer
+eingehen sollte, doch dann schob sie den Gedanken beiseite. "Wenn ich eine
+Kerze waere, wuerde ich schmelzen.", stellte sie fest.
+
+"Darf ich dich schmelzen?", fragte Romeo, der nun keck wurde.
+
+"Wenn du die Flamme bist, die mich schmilzt, gehst du aus, sobald ich
+geschmolzen bin."
+
+Romeo dachte einen Moment nach. "Oh, das ist nicht schlimm, denn wenn ich das
+Wachs nicht mehr habe, nuetzt mir auch der Docht nichts."
+
+Julia warf einen zweifelnden Blick auf Romeos Mitte. "Docht?"
+
+"Aeh..." Romeo zoegerte. "Naja, ich meine, wenn du nicht in der Welt bist,
+dann kann ich sowieso nie mehr brennen."
+
+"Ach so."
+
+Polly, die mit Argusaugen ueber die Tugend der beiden jungen Leute gewacht
+hatte, waehlte diesen Augenblick, um zu Julia zu treten. "Deine Mutter moechte
+dich sprechen, Schatz."
+
+Julia drehte das Gesicht zur Seite und zog eine Schnute, dann zuckte sie mit
+den Schultern und ging zu ihrer Mutter, die am Ausgang die Gaeste
+verabschiedete.
+
+"Wer ist denn ihre Mutter?", fragte Romeo.
+
+"Das wissen Sie nicht?" Polly war ehrlich erstaunt. "Ihre Mutter ist Frau
+Capulet, und wenn es stimmt, dass Toechter die juengeren Ausgaben ihrer
+Muetter sind, dann ist sie eine tugendhafte und kluge Frau."
+
+"Hm.", machte Romeo.
+
+"Naja, vielleicht hat sie auch ein bisschen von meinem guten Gedaechtnis
+mitbekommen. Und ausserdem bekommt sie ihres Vaters Moneten."
+
+"Was kann ein Mann sich mehr wuenschen.", meinte Azzuro leise.
+
+"Prima.", seufzte Romeo bitter. "Dann kann ich sie also gleich vergessen. Aber
+das will ich nicht, und wenn sie tausendmal die Tochter des alten Capulet
+waere."
+
+Benevolio nahm seinen Cousin beim Arm. "Komm, Romeo, wir wollen gehen. Sieh
+nur, wir sind schon fast die letzten, gleich beissen uns die Hunde."
+
+"Ja, so kommt es mir vor.", murmelte Romeo und folgte Benevolio zur Tuer.
+
+Herr Capulet laechelte breit, als er seine Gaeste sah. "Aber meine Herren, Sie
+wollen doch nicht schon gehen?" Sein Gesicht bekam einen erstaunten Ausdruck,
+als ihm Tybalt ins Ohr fluesterte. "Tatsaechlich?" Er rieb sich ueber die
+Glatze. "Na, dann muessen Sie wohl gehen, es war mir ein Vergnuegen, Sie hier
+begruessen zu duerfen."
+
+Tybalt schenkte Romeo ein Laecheln, das an einen Tiger gemahnte. "Gute Nacht,
+Romeo."
+
+Frau Capulet, die weitere Zusammenstoesse vermeiden wollte, hakte sich bei
+ihrem Mann ein. "Komm, Lieber, wir wollen zu Bett gehen, ich bekomme meine
+Migraene."
+
+Julia verstaute den Trick zum spaeteren Gebrauch in ihrem Gedaechtnis und zog
+an Pollys Aermel. "Wer ist der da?" Sie zeigte verstohlen mit dem Finger.
+
+"Das ist Tiberio junior. Der einzige Sohn und Erbe des alten Tiberio." Polly
+laechelte.
+
+"Und der?"
+
+"Petruchio, aber der ist nichts besonderes."
+
+Wieder deutete Julia mit dem Finger. "Und der da? Der den ganzen Abend nicht
+ein Mal getanzt hat?"
+
+Polly warf ihr einen misstrauischen Blick zu. "Warum willst du das denn alles
+wissen?"
+
+"Och, ich muss doch die Leute kennen, oder?" Julia schaute ihre Amme mit dem
+Blick an, der, wie sie wusste, am besten geeignet war, jeden Verdacht zu
+zerstreuen.
+
+"Ja. Aber wer der Junge ist, weiss ich nicht."
+
+"Dann tu mir die Liebe und frag ihn nach seinem Namen, ja?" Julia seufzte
+tief. "Wenn er schon verheiratet ist, werde ich ins Kloster gehen." Undeutlich
+erinnerte sie sich an einen Roman, in dem der Held, nach langen Jahren endlich
+Witwer, in einem Kloster seine einzige Geliebte trifft und diese ihre Geluebde
+sofort vergisst.
+
+"Nein, dann wirst du Paris heiraten.", meinte Polly bestimmt. "Er ist Romeo
+Montague."
+
+"Das gibt es doch nicht!" In Julias Augen machte sich Schrecken breit. "Er ist
+der einzige Mann, den ich lieben kann, und ausgerechnet ihn darf ich nicht
+lieben, weil sonst mein Vater einen Herzanfall bekommt." Eine weitere
+Erinnerung schwamm in ihrem Hirn nach oben wie eine Wasserleiche: Eine junge
+Frau, die heiratet und ungluecklich ist, bis ihr Geliebter sie aus der Ehe
+entfuehrt, damit sie in einem fernen Land gluecklich wuerden. Sie seufzte noch
+einmal. "Wenn das so ist, werde ich wohl fuer immer ungluecklich sein.",
+meinte sie und gefiel sich bereits jetzt in ihrer Rolle als Isolde.
+
+"Was soll denn der Unsinn, Kind?", fragte Polly unwillig.
+
+"Ach, schon gut, das verstehst du sowieso nicht.", antwortete Julia mit einem
+tragischen Laecheln.
+
+Die Stimme Frau Capulets rief nach ihrer Tochter und Polly schob Julia sanft
+aber bestimmt ins Haus. "Komm, Zeit, ins Bett zu gehen. Ausserdem sind jetzt
+alle weg und es gibt nichts mehr zu sehen."
+
+"Stimmt." Azzuro gaehnte. "Hoechste Zeit fuer einen gemuetlichen Ast, Liebes."
+
+"Es kommt noch was, geschlafen wird spaeter."
+
+"Oh, nein, nicht heute.", stoehnte Azzuro.
+
+"_Das_ meine ich nicht."
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite8 b/d/seher/haeuser/special/special/rom_jul/seite8
new file mode 100644
index 0000000..e07f4df
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite8
@@ -0,0 +1,72 @@
+DER ZWEITE AKT
+
+An dieser Stelle sollte eigentlich wieder ein Chor auftreten, doch inzwischen
+haben Sie gewiss nichts mehr gegen die Kuerzungen im Etat und nehmen mit Ulo
+und Azzuro vorlieb. Wenn ich ehrlich sein soll, mir sind die beiden richtig
+ans Herz gewachsen, obwohl ein Chor wahrscheinlich fuegsamer waere.
+
+"N'Abend, Kollege." Azzuro nickte einer Fledermaus zu, die im Schimmer der
+Lampen im Haus nach Insekten jagte.
+
+"Ssseid ssspaet dran.", kommentierte die Fledermaus. "Wollt ihr nissst lieber
+ssslafen gehen?"
+
+"Koennen wir noch nicht." Ulo gaehnte hinter dem vorgehaltenen Fluegel.
+
+"Wasss issst denn noch?" Bedauernd blickte die Fledermaus hinter einer Motte
+her, die Azzuro ihr weggeschnappt hatte. "Wenn ihr ssso ssspaet noch auf
+ssseid, dann lassst wenigssstensss die Sssnaebel von meinem Fruehssstueck.",
+schalt sie.
+
+"Ich habe Hunger.", entschuldigte sich Azzuro.
+
+"Isss auch. Aber jetssst ersssaehlt, wasss geht denn vor?"
+
+"Wir sehen jemandem zu, der gerade die Begierde gegen die Liebe eingetauscht
+hat."
+
+"Nein, wie romantisss!" Wie alle Fledermaeuse war auch diese hier sehr
+gefuehlsbetont.
+
+"Isss liebe sssolssse Gesssisssten."
+
+"Ja, ich auch.", freute sich Ulo.
+
+"Ersssaehl!"
+
+"Romeo hat festgestellt, dass Liebe und Begehren nicht das gleiche ist."
+
+"Dasss haette isss ihm vorher sssagen koennnen."
+
+Ulo nickte weise. "Ich weiss. Wahrscheinlich haette es ihm jede Frau sagen
+koennen."
+
+Sie warf Azzuro einen ironischen Seitenblick zu. "Aber Maenner sind
+Sklaven..."
+
+"... weniger anssstaendiger Absssisssten.", vollendete die Fledermaus den Satz
+verschaemt.
+
+"Genau. Na, und jetzt steckt er in einer boesen Klemme." Ulo machte eine
+Spannungspause.
+
+"Sssag ssson!"
+
+"Er hat sich ausgerechnet in eine Frau einer verfeindeten Familie verliebt,
+und zu allem Ueberdruss liebt sie ihn auch."
+
+Traenen traten in die kurzsichtigen Augen der Fledermaus. "Wie sssrecklisss
+sssoen! Wie heissst esss: Die Liebe findet einen Weg."
+
+"Wir werden sehen, ob er es schafft, den Wurm vom Haken zu holen ohne sich
+aufzuspiessen." Azzuro fand seine Freude daran, die Frauen mit wenig schoenen
+Metaphern zu schockieren. "Er kann ihr nicht mal ein Staendchen bringen, denn
+wenn man ihn hier im Garten erwischt..." Azzuro machte eine eindeutige Geste
+und schaute die Fledermaus erwartungsvoll an, die seinen Blick bemerkte und
+sich mit weiblichem Grossmut doch noch zu einem entsetzten Keuchen entschloss.
+
+"Aber dasss issst ja..."
+
+"Still!" Ulo hatte Romeo jenseits der Mauer entdeckt, die den Garten
+umschloss.
+
diff --git a/d/seher/haeuser/special/special/rom_jul/seite9 b/d/seher/haeuser/special/special/rom_jul/seite9
new file mode 100644
index 0000000..c6c1f41
--- /dev/null
+++ b/d/seher/haeuser/special/special/rom_jul/seite9
@@ -0,0 +1,130 @@
+DER ZWEITE AKT
+ DIE ERSTE SZENE
+
+Romeo stellte sich auf die Zehenspitzen und spaehte ueber die Mauer hinweg. Er
+wunderte sich nur einen Moment lang darueber, dass auf ein und demselben Ast
+eine Fledermaus kopfueber hing und direkt ueber ihr zwei Kraehen. _In_
+_dieser_ _Nacht_, so dachte Romeo mit einem Schulterzucken, _kann_ _wirklich_
+_alles_ _passieren_. _Ausserdem_: _Da_ _drin_ _irgendwo_ _ist_ _Julia_. Er
+zwinkerte den Kraehen zu.
+
+"Wisst ihr, ich gehe heute nacht nicht nach Hause. Schliesslich ist _sie_
+hier, da kann ich einfach nicht ins Bett gehen, als sei nichts passiert."
+
+Mercutio und Benevolio tauchten mit dem Laerm, den Betrunkene immer
+veranstalten, an der Strassenecke auf. Romeo glitt mit einer Behendigkeit, die
+ihn selbst erstaunte, in den Schatten eines Eingangs zurueck und betrachtete
+seine Freunde mit einem Grinsen.
+
+"Romeo, hey, alder Schunge, wo schteckscht du denn?", rief Benevolio.
+
+"Er ischt schlauer geweschen alsch wir und hat schisch schon insch Bedd
+gelescht..."
+
+Mercutio sah ganz danach aus, als habe er fuer nichts so gute Verwendung wie
+fuer ein Bett.
+
+"Seinen Schaedel moechte ich morgen frueh nicht haben.", bemerkte Azzuro
+mitfuehlend.
+
+"Ob er wohl genaussso sssmeckt wie eine Fliege, die ausss einem Weinglasss
+gesssluerrft hat?", ueberlegte die Fledermaus.
+
+"Du willst doch nicht etwa den Ruf der Fledermaeuse ruinieren und einen
+Menschen anknabbern?", fragte Ulo mit einem angeekelten Gesichtsausdruck.
+
+"Nein, esss war nur wissssensssafltissse Neugier."
+
+"Hm." Ulo schenkte der Fledermaus einen langen, forschenden Blick. "Sag
+mal,wie heisst du eigentlich?"
+
+"Wlad." Die Fledermaus grinste und leckte sich ueber ihre zarte,
+hufeisenfoermige Nase.
+
+"Wir sind Ulo und Azzuro." Ulo rueckte ein kleines Stueck von Wlad ab.
+
+"Er holt schisch den Tod, wenn er hier drauschen rumschpringt." Benevolio
+machte sich ernste Sorgen um seinen Cousin. "Ruf ihn, scheine Mu... Mutter
+reischt mir den Kopf ab, wenn isch ohne ihn ankomme."
+
+"Isch weisch wasch bescheresch." Auch Mercutio kannte Frau Montagues
+Einstellung zu Sauftouren. "Isch habe mal in einem Buch geleschen..."
+
+"Nein!" Benevolio lachte.
+
+"Doch. Pasch auf, isch werde ihn beschwoeren."
+
+"Und wasch scholl er tun?"
+
+"Herkommen, Schnapschnasche, wasch denn schonscht?" Mercutio holte Luft.
+
+"Romeo! Isch beschwoere disch bei deiner Verliebtheit, erscheine du
+Scheuftscher."
+
+"Er ischt doch gar kein Schaeufer." Benevolio erinnerte sich dunkel, dass
+Romeo den ganzen Abend an einem einzigen Glas Wein genippt hatte und schon
+nicht mehr bei ihnen gewesen war, als sie die Kneipe gefunden hatten.
+
+"Scheuftscher!" Mercutio verdeutlichte seine Worte, indem er tief seufzte. "Du
+bischt bloed und beschoffen."
+
+"Schtimmt." Benevolio grinste.
+
+"Romeo! Schag wasch. Esch reischt, wenn du 'Liebe' schagscht, wasch anderesch
+bekommscht du eh nischt rausch." Mercutio kicherte. "Du kannscht auch ein
+bi... bisch..." Ein konzentrierter Ausdruck trat auf Mercuitos Gesicht.
+"...biss-chen jammern, dann erkennen wir disch auch. Alscho, bei
+Roschalinschens langen Beinen, bei ihrer Schtupschnasche, ihren
+Schommerschproschen und ihrem Buschen: Romeo, erscheine!" Benevolio ruelpste
+ungeniert. "Wenn er disch jetscht gehoert hat, bekommscht du Pruegel."
+
+"Quatsch. Viel schlimmer waere esch doch, wenn isch ihn riefe und ihn dann
+schtehen liesche. Scho wasch machen nur gemeine Frauen." Sein Gesicht verzog
+sich in einer trunkenen Parodie der Trauer. "Aber leider schind scho viele
+Frauen gemein." Eine Weile hielten sich die beiden Maenner in den Armen und
+gedachten traenenreich frueherer Enttaeuschungen.
+
+Nach einer Weile putzte sich Benevolio umstaendlich die Nase, die jetzt nicht
+mehr nur vom Alkohol geroetet war. "Weischt du wasch, lasch unsch nach Hausche
+gehen, Romeo will beschtimmt den Mond anheulen, da schtoeren wir schowiescho
+nur." Mercutio schniefte, dann, in seinen Stimmungswechseln so schnell, wie
+nur Betrunkene es sein koennen, lachte er. "Wahrscheinlisch schitscht er unter
+einem Baum und wuenscht schisch, er mueschte nischt allesch schelber tun."
+Seine eindeutige Geste liess keinen Zweifel am Inhalt seiner Worte. "Alscho,
+fuer misch reischt heute nacht der Betrieb in meinem Bett." Er beugte sich
+nieder und betastete den Boden. "Nee, dasch ischt mir schu hart, lasch unsch
+nach Hausche gehen und Romeo..." Er ueberlegte einen Moment, dann rief er:
+"Schlaf gut, Romeo. Und wenn du heut nacht klempnerscht, dann verleg' fuer
+mich ein Rohr mit."
+
+"Was fuer ein ordinaerer..." Ulo suchte in ihrem Gedaechtnis nach Ausdruecken,
+die gleichzeitig damenhaft und ihrer Stimmung angemessen waren, fand
+allerdings keine.
+
+"Recht hassst du." Auch Wlad war empoert. "Ssso wasss sssollten wir Frauen
+unsss nissst gefallen lassssen."
+
+"Ist Vlad nicht ein Maennername?", wollte Azzuro wissen.
+
+"Mit V ssson, aber isss sssreibe misss mit W."
+
+"Oh.", machte Ulo und rueckte verlegen wieder naeher an Wlad heran.
+
+"Issst Romeo auch ssso ein Ssswein?"
+
+"Keine Ahnung." Ulo zuckte die Schultern. "Er ist ein Mann, wahrscheinlich ist
+er also um keinen Deut besser."
+
+"Was willst du damit sagen?", fragte Azzuro saeuerlich.
+
+"Ach, nichts. Still, Romeo kommt wieder."
+
+Romeo, der aus dem Schatten trat, war ebenso wenig begeistert von seinen
+Freunden wie Ulo und Wlad. "Der hat gut reden, so wie er gebaut ist, hat er
+die Haende immer frei.", murmelte er. Sein Blick fiel auf den Balkon im ersten
+Stock und den Baum davor.
+
+"Er ueberlegt, ob er da rauf kommt.", fluesterte Ulo.
+
+"Alssso issst er doch ein Ssswein.", stellte Wlad ebenso leise fest.
+
diff --git a/d/seher/haeuser/special/special/seherfaq.c b/d/seher/haeuser/special/special/seherfaq.c
new file mode 100644
index 0000000..e881696
--- /dev/null
+++ b/d/seher/haeuser/special/special/seherfaq.c
@@ -0,0 +1,247 @@
+inherit "std/thing";
+inherit "std/more";
+inherit "/mail/nedit";
+
+#include <properties.h>
+#include <wizlevels.h>
+#include "../haus.h"
+
+#define FAQ(f) (SPECIALPATH+"faq/"+(f))
+#define FAQUSER ({ "ryne", "toss" })
+#define IS_USER(pl) (member(FAQUSER, getuid(pl)) >= 0)
+
+static string *seite;
+static string f,*s;
+
+mapping synonym = ([]);
+
+create()
+{
+ ::create();
+ SetProp(P_NAME,"SeherFAQ");
+ SetProp(P_GENDER,FEMALE);
+ SetProp(P_NOGET,1);
+ AddId( ({"faq","seherfaq","FAQ","SeherFAQ" }) );
+ AddCmd("lies","lesen");
+ AddCmd(({"beschreib","beschreibe"}),"beschreiben");
+ AddCmd("seiten","seiten");
+ AddCmd(({"loesch","loesche"}),"loeschen");
+ AddCmd(({"kopier","kopiere"}),"kopieren");
+ restore_object(FAQ("faq"));
+ seite = get_dir(FAQ("*"))-({".","..","faq.o"});
+}
+
+init()
+{
+ thing::init();
+ if (this_player() && IS_USER(this_player()))
+ nedit::init_rescue();
+}
+
+string
+_query_short()
+{
+ if (this_player() && IS_SEER(this_player()))
+ return "Die SeherFAQ";
+ else
+ return 0;
+}
+
+string
+_query_long()
+{
+ if (this_player() && IS_SEER(this_player()))
+ return "Dies ist Rynes SeherFAQ.\n\
+Wenn Du weitere Fragen oder Anregungen zu dieser FAQ hast,\n\
+sei so nett und schicke Ryne einen kurzen Brief\n\n\
+Zum Inhalt der FAQ kommst Du mit >lies inhalt<\n";
+ else
+ return 0;
+}
+
+int
+id(string str)
+{
+ if (!IS_SEER(this_player()))
+ return 0;
+ else
+ return ::id(str);
+}
+
+int
+seiten(string str)
+{
+ int i,j;
+ string *syn;
+ closure filter_ldfied;
+
+ if (!IS_USER(this_player()))
+ return 0;
+
+ if(!(i = sizeof(seite)))
+ write("Keine Seiten beschrieben!\n");
+ else {
+ filter_ldfied = lambda(({'ind,'page,'map_ldfied/*'*/}),
+ ({#'==,'page,({#'[/*]'*/,'map_ldfied,'ind})}));
+ for (str = "",i-=1;i>=0;i--) {
+ syn = m_indices(filter_indices(synonym,filter_ldfied,seite[i],synonym));
+ printf("Seite '%s' - ",seite[i]);
+ if (j=sizeof(syn)) {
+ for(j-=1;j>=0;j--)
+ printf("'%s' ",syn[j]);
+ write("\n");
+ }
+ else
+ write( "(keine Synonyme definiert)\n");
+ }
+ }
+ return 1;
+}
+
+int
+lesen(string str)
+{
+ if (!IS_SEER(this_player()))
+ return 0;
+
+ if (!str || str == "") {
+ notify_fail("Was willst Du denn lesen?\n");
+ return 0;
+ }
+ str = lower_case(this_player()->_unparsed_args());
+ if (member(seite,str)<0) {
+ if (!member(synonym,str)) {
+ notify_fail("Diese Seite gibt es nicht...\n");
+ return 0;
+ }
+ else
+ str = synonym[str];
+ }
+ this_player()->More(FAQ(str),1);
+ return 1;
+}
+
+int
+beschreiben(string str)
+{
+ string faq,*desc;
+ int i;
+
+ if (!IS_USER(this_player()))
+ return 0;
+
+ str = lower_case(this_player()->_unparsed_args());
+
+ if (!str || str == "") {
+ notify_fail("Was willst Du denn beschreiben?\n");
+ return 0;
+ }
+ if (sscanf(str,"%s %s",faq,str)!=2 || !id(faq)) {
+ notify_fail("Syntax: beschreibe faq <seite>\n");
+ return 0;
+ }
+ str = implode(old_explode(str," ")-({""}), " ");
+ desc = old_explode(implode(old_explode(str,", "),","),",");
+ f = 0;
+ s = 0;
+
+ for (i=sizeof(desc)-1;i>=0;i--) {
+ if (member(seite,desc[i])>=0) {
+ f = desc[i];
+ s = desc-({desc[i]});
+ break;
+ }
+ }
+ if (!f) {
+ f = desc[0];
+ s = desc[1..];
+ }
+ write("Bitte Beschreibung fuer die FAQ-Seite '"+f+"' angeben\n");
+ nedit("faq");
+ return 1;
+}
+
+static void
+faq(string str)
+{
+ int i;
+ string file;
+
+ if (!str || str == 0) {
+ write("** Abbruch! **\nNichts geaendert!\n");
+ return;
+ }
+
+ if (file_size(file=FAQ(f))>=0)
+ rm(file);
+ write_file(file, str);
+ if (member(seite,f)==-1)
+ seite += ({f});
+
+ for (i=sizeof(s)-1;i>=0;i--)
+ synonym += ([ s[i] : f ]);
+
+ save_object(FAQ("faq"));
+}
+
+int
+loeschen(string str)
+{
+ string *syn;
+ int i;
+
+ if(!IS_USER(this_player()))
+ return 0;
+
+ str = lower_case(this_player()->_unparsed_args());
+ if (!str || str == "") {
+ notify_fail("Was willst Du denn loeschen?\n");
+ return 0;
+ }
+ if (member(seite,str)>=0) {
+ syn = m_indices(filter_indices(synonym,
+ lambda(({'ind,'page,'map_ldfied/*'*/}),
+ ({#'==,'page,({#'[/*]'*/,'map_ldfied,'ind})}))
+ ,seite[i],synonym));
+ rm(FAQ(str));
+ seite -= ({str});
+ }
+ else {
+ str = implode(old_explode(str," ")-({""}), " ");
+ syn = old_explode(implode(old_explode(str,", "),","),",");
+ }
+ for (i=sizeof(syn)-1; i>=0; i--)
+ synonym = filter_indices(synonym,
+ lambda(({'key,'cmp}),
+ ({#'!=,'key,'cmp/*'*/})),
+ syn[i]);
+
+ save_object(FAQ("faq"));
+ write("OK\n");
+ return 1;
+}
+
+int
+kopieren(string str)
+{
+ string *part;
+ int i;
+
+ if (!IS_USER(this_player()))
+ return 0;
+
+ str = lower_case(this_player()->_unparsed_args());
+ part = old_explode(str," ")-({""});
+ if(sizeof(part)<4 || !id(part[0]) || part[2] != "nach" ||
+ member(seite,part[1]) == -1) {
+ notify_fail("kopiere faq <seite> nach <alias>\n");
+ return 0;
+ }
+ str = part[1];
+ part=old_explode(implode(old_explode(implode(part[3..]," "),", "),","),",");
+ for(i=sizeof(part)-1;i>=0;i--)
+ synonym += ([ part[i] : str ]);
+ save_object(FAQ("faq"));
+ write("OK.\n");
+ return 1;
+}
diff --git a/d/seher/haeuser/tools/generator.c b/d/seher/haeuser/tools/generator.c
new file mode 100644
index 0000000..3254c2b
--- /dev/null
+++ b/d/seher/haeuser/tools/generator.c
@@ -0,0 +1,740 @@
+#include "../haus.h"
+
+inherit "/p/service/wargon/sm/statemachine";
+
+#include "/p/service/wargon/sm/statemachine.h"
+#include <properties.h>
+
+#define STATE_IDLE 0
+#define STATE_HOUSE 1
+#define STATE_ROOM 2
+#define STATE_CHEST 3
+#define STATE_DETAIL 4
+#define STATE_RDETAIL 5
+#define STATE_COMMAND 6
+#define STATE_FINALIZE 7
+#define STATE_EXITS 8
+
+#define SIG_INITIALIZE 0
+#define SIG_HOUSE 1
+#define SIG_HOUSE_DONE 2
+#define SIG_ROOM 3
+#define SIG_DO_CHEST 4
+#define SIG_DO_DETAIL 5
+#define SIG_DETAIL_DONE 6
+#define SIG_RDETAIL_DONE 7
+#define SIG_COMMAND_DONE 8
+#define SIG_DO_EXITS 9
+#define SIG_ROOM_DONE 10
+
+private nosave string file;
+private nosave int final;
+private nosave object raum;
+private nosave int nr;
+private nosave object hausmeister;
+private nosave mixed hmargs;
+
+string dump(object env, int final, mixed args);
+
+private string special(string str);
+private void removeOutputFile();
+private void dumpHouse();
+private void dumpRoomHeader();
+private void dumpChest();
+private void dumpDetails();
+private void dumpReadDetails();
+private void dumpCommands();
+private void doFinalize();
+private void dumpExits();
+private void dumpRoomTrailer();
+private void doReturn();
+private void sProp(string file, string pName, string pStr);
+static void mProp(string file, string pName, mixed map_ldfied, int pos, int signal);
+static void cProp(string file, string pName, mixed cmd, int pos, int signal);
+private void prettyString(string file, string *str, int indent);
+private void prettyArray(string file, string *arr, int sep);
+private void headerRoom();
+private void trailerRoom();
+private void headerHouse();
+private void trailerHouse();
+
+create()
+{
+ ::create();
+ seteuid(getuid());
+
+ AddState(STATE_IDLE, 0, 0);
+ AddState(STATE_HOUSE, #'dumpHouse, 0);
+ AddState(STATE_ROOM, #'dumpRoomHeader, 0);
+ AddState(STATE_CHEST, #'dumpChest, 0);
+ AddState(STATE_DETAIL, #'dumpDetails, 0);
+ AddState(STATE_RDETAIL, #'dumpReadDetails, 0);
+ AddState(STATE_COMMAND, #'dumpCommands, 0);
+ AddState(STATE_FINALIZE, #'doFinalize, 0);
+ AddState(STATE_EXITS, #'dumpExits, 0);
+
+ AddTransition(SM_INVALID, SIG_INITIALIZE, STATE_IDLE, 0);
+
+ // Zustandsuebergaenge zum Schreiben des Hauses
+ AddTransition(STATE_IDLE, SIG_HOUSE, STATE_HOUSE, #'removeOutputFile);
+ AddTransition(STATE_HOUSE, SIG_HOUSE_DONE, STATE_IDLE, #'doReturn);
+
+ // Zustandsuebergaenge zum Schreiben eines Raums
+ AddTransition(STATE_IDLE, SIG_ROOM, STATE_ROOM, #'removeOutputFile);
+ AddTransition(STATE_ROOM, SIG_DO_CHEST, STATE_CHEST);
+ AddTransition(STATE_ROOM, SIG_DO_DETAIL, STATE_DETAIL);
+ AddTransition(STATE_CHEST, SIG_DO_DETAIL, STATE_DETAIL);
+ AddTransition(STATE_DETAIL, SIG_DETAIL_DONE, STATE_RDETAIL);
+ AddTransition(STATE_RDETAIL, SIG_RDETAIL_DONE, STATE_COMMAND);
+ AddTransition(STATE_COMMAND, SIG_COMMAND_DONE, STATE_FINALIZE);
+ AddTransition(STATE_FINALIZE, SIG_DO_EXITS, STATE_EXITS);
+ AddTransition(STATE_FINALIZE, SIG_ROOM_DONE, STATE_IDLE, #'doReturn);
+ AddTransition(STATE_EXITS, SIG_ROOM_DONE, STATE_IDLE, #'dumpRoomTrailer);
+
+ StateTransition(SIG_INITIALIZE);
+}
+
+
+// Erzeuge normalen LPC-Quellcode aus einem Haus oder Raum.
+//
+// Parameter:
+// env: Das Haus oder der Raum, aus dem Quellcode erzeugt werden soll
+// fin: Falls gleich 0, so wird Quellcode fuer Typofixes o.ae.
+// erzeugt; das erzeugte File heisst immer 'fixed.c'.
+// Andernfalls wird Quellcode fuer ein eigenstaendiges Objekt
+// erzeugt. Dieses kann z.B. zum Anschluss als "Magierhaus"
+// verwendet werden. Die erzeugten Files heissen
+// 'rep/<name>raum<nr>.c' bzw. 'rep/<name>haus.c'. Befindet sich
+// in dem Raum die Truhe, wird zusaetzlich die Datei
+// 'rep/<name>truhe.c' geschrieben.
+//
+// Rueckgabewert:
+// Der Dateiname, in den die Daten geschrieben wurden.
+
+string
+dump(object env, int fin, mixed args)
+{
+ string out;
+ int num;
+
+ hausmeister = previous_object();
+ hmargs = args;
+
+ if (QueryState() != STATE_IDLE)
+ {
+ write("Der Generator arbeitet noch...\nBitte warten!\n");
+ return "<keine Datei generiert>\n";
+ }
+
+ // Falls ein Raum generiert wird, erhaelt <nr> die Raumnummer.
+ // Bei der Aussenansicht des Hauses wird <nr> auf -1 gesetzt.
+ if (sscanf(object_name(env), "%sraum%d", out, num) < 2)
+ {
+ num = -1;
+ }
+
+ if (fin)
+ {
+ out = PATH+"rep/"+env->QueryOwner();
+
+ if (num >= 0)
+ {
+ out += "raum"+num+".c";
+ }
+ else
+ {
+ out += "haus.c";
+ }
+ }
+ else
+ {
+ out = PATH+"fixed.c";
+ }
+
+ // Informationen fuer die Statemachine setzen
+ file = out;
+ final = fin;
+ raum = env;
+ nr = num;
+
+ if (num >= 0)
+ {
+ StateTransition(SIG_ROOM);
+ }
+ else
+ {
+ StateTransition(SIG_HOUSE);
+ }
+ return out;
+}
+
+// Sonderzeichen \, " und TAB korrekt umwandeln
+private string special(string s)
+{
+ s = implode(explode(s, "\\"), "\\\\");
+ s = implode(explode(s, "\t"), "\\t");
+ s = implode(explode(s, "\""), "\\\"");
+
+ return s;
+}
+
+/*** Funktionen zum Generieren einer Datei aus den Properties des Hauses ***/
+
+#define EXIT_TMPL "\"/players/%s/seherhaus/%sraum%d\""
+
+private void
+removeOutputFile()
+{
+ catch(rm(file));
+}
+
+private void
+dumpHouse()
+{
+ headerHouse();
+
+ sProp(file, "P_SHORT", raum->QueryProp(P_SHORT));
+ write_file(file, "\n");
+ sProp(file, "P_LONG", raum->QueryProp(P_LONG));
+ write_file(file, "\n");
+
+ if (final)
+ {
+ mixed n;
+
+ write_file(file, " SetProp(P_NOGET, 1);\n");
+ write_file(file,
+ " SetProp(P_GENDER, "+
+ ({"NEUTER","MALE","FEMALE"})[raum->QueryProp(P_GENDER)]+
+ " );\n SetProp(P_NAME, ");
+ n = raum->QueryProp(P_NAME);
+
+ if (stringp(n))
+ {
+ write_file(file, "\""+n+"\"");
+ }
+ else
+ {
+ prettyArray(file, n, 0);
+ }
+ write_file(file, " );\n\n AddId( ");
+ prettyArray(file,
+ raum->QueryProp(P_IDS)-({ "sehe\rhaus",
+ "\n"+raum->QueryOwner()+"haus" }),
+ 0);
+ write_file(file, " );\n");
+ }
+ trailerHouse();
+
+ StateTransition(SIG_HOUSE_DONE);
+}
+
+private void
+dumpRoomHeader()
+{
+ headerRoom();
+
+ sProp(file, "P_INT_SHORT", raum->QueryProp(P_INT_SHORT));
+ write_file(file, "\n");
+ sProp(file, "P_INT_LONG", raum->QueryProp(P_INT_LONG));
+ write_file(file, "\n");
+
+ if (final && raum->QueryProp(H_CHEST))
+ {
+ StateTransition(SIG_DO_CHEST);
+ }
+ else
+ {
+ StateTransition(SIG_DO_DETAIL);
+ }
+}
+
+private void
+dumpChest()
+{
+ mixed n;
+ string cfile;
+ object chest;
+
+ cfile = PATH+"rep/"+raum->QueryOwner()+"truhe.c";
+ chest = present(TRUHE, raum);
+
+ catch(rm(cfile));
+
+ write_file(cfile,
+ "#include <properties.h>\n#include <moving.h>\n\n"
+ "inherit \"/d/wueste/durian/behaelter\";\n\n"
+ "void create()\n{\n if(!clonep(this_object())) return;\n\n"
+ " ::create();\n\n" );
+ sProp(cfile, "P_SHORT", chest->QueryProp(P_SHORT));
+ sProp(cfile, "P_LONG", chest->QueryProp(P_LONG));
+
+ write_file(cfile, " SetProp(P_NOGET, 1);\n");
+ write_file(cfile,
+ " SetProp(P_GENDER, "+
+ ({"NEUTER","MALE","FEMALE"})[chest->QueryProp(P_GENDER)]+
+ " );\n SetProp(P_NAME, ");
+
+ n = chest->QueryProp(P_NAME);
+ if (stringp(n))
+ {
+ write_file(cfile, "\""+n+"\"");
+ }
+ else
+ {
+ prettyArray(file, n, 0);
+ }
+ write_file(cfile, " );\n\n AddId( ");
+ prettyArray(cfile, chest->QueryProp(P_IDS)-({ TRUHE }), 0);
+ write_file(cfile, " );\n");
+
+ if ((n=chest->QueryProp(P_ADJECTIVES)) && sizeof(n))
+ {
+ write_file(cfile, "\n AddAdjective( ");
+ prettyArray(cfile, n, 0);
+ write_file(cfile, " );\n");
+ }
+ if ((n=chest->QueryProp(P_NAME_ADJ)) && sizeof(n))
+ {
+ write_file(cfile, "\n SetProp(P_NAME_ADJ, ");
+ prettyArray(cfile, n, 0);
+ write_file(cfile, " );\n");
+ }
+ write_file(cfile, "}\n");
+
+ StateTransition(SIG_DO_DETAIL);
+}
+
+private void
+dumpDetails()
+{
+ mapping prop;
+ mixed det;
+
+ prop = raum->QueryProp(P_DETAILS);
+
+ if (sizeof(prop))
+ {
+ det = VERWALTER->PCrunch(prop);
+ // next state transition happens when do_mProp is done
+ mProp(file, "AddDetail", det, sizeof(det)-1, SIG_DETAIL_DONE);
+ }
+ else
+ {
+ StateTransition(SIG_DETAIL_DONE);
+ }
+}
+
+private void
+dumpReadDetails()
+{
+ mapping prop;
+ mixed rdet;
+
+ prop = raum->QueryProp(P_READ_DETAILS);
+
+ if (sizeof(prop))
+ {
+ rdet = VERWALTER->PCrunch(prop);
+ // next state transition happens when do_mProp is done
+ mProp(file, "AddReadDetail", rdet, sizeof(rdet)-1, SIG_RDETAIL_DONE);
+ }
+ else
+ {
+ StateTransition(SIG_RDETAIL_DONE);
+ }
+}
+
+private void
+dumpCommands()
+{
+ mapping comm;
+ mixed cmd;
+
+ comm = raum->QueryProp(H_COMMANDS);
+
+ if (sizeof(comm))
+ {
+ cmd = VERWALTER->PCrunch(comm);
+ // next state transition happens when do_cProp is done
+ cProp(file, "AddUserCmd", cmd, sizeof(cmd)-1, SIG_COMMAND_DONE);
+ }
+ else
+ {
+ StateTransition(SIG_COMMAND_DONE);
+ }
+}
+
+private void
+doFinalize()
+{
+ if (final)
+ {
+ StateTransition(SIG_DO_EXITS);
+ }
+ else
+ {
+ StateTransition(SIG_ROOM_DONE);
+ }
+}
+
+private void
+dumpExits()
+{
+ string *k, o;
+ mapping prop;
+ int i, num;
+
+ prop = raum->QueryProp(P_EXITS);
+ k = m_indices(prop);
+ if (member(k, "raus") >= 0)
+ {
+ k -= ({ "raus" });
+ write_file(file, sprintf(" AddExit( \"raus\", \"%s\");\n", prop["raus"]));
+ }
+
+ for (i=sizeof(k)-1; i>=0; i--)
+ {
+ if (sscanf(prop[k[i]], PATH+"%sraum%d", o, num) != 2)
+ {
+ printf("Komischer Exit (%O)\n%s -> %s\n", raum, k[i], prop[k[i]]);
+ }
+ else
+ {
+ if (o == raum->QueryOwner())
+ {
+ o = sprintf(EXIT_TMPL, o, o, num);
+ write_file(file, sprintf(" AddExit( \"%s\", %s);\n", k[i], o));
+ }
+ else
+ {
+ write_file(file,
+ sprintf(" AddExit( \"%s\", \"%s\");\n", k[i], prop[k[i]]));
+ printf("Exit von %O nach %s!\n", raum, prop[k[i]]);
+ }
+ }
+ }
+ StateTransition(SIG_ROOM_DONE);
+}
+
+private void
+dumpRoomTrailer()
+{
+ trailerRoom();
+ doReturn();
+}
+
+private void
+doReturn()
+{
+ if (hausmeister != 0)
+ {
+ apply(#'call_other, hausmeister, "GenerationDone", hmargs);
+ }
+ destruct(this_object());
+}
+
+private void
+sProp(string f, string pName, string pStr)
+{
+ string *str;
+
+ write_file(f, " SetProp( "+pName+",");
+
+ if (!pStr)
+ {
+ write_file(f, "0 );\n");
+ return;
+ }
+
+ pStr = special(pStr);
+
+ if (sizeof(str=old_explode(pStr,"\n")) > 1)
+ {
+ prettyString(f, str, 4);
+ }
+ else
+ {
+ if (sizeof(str)==0)
+ {
+ str = ({""});
+ }
+ write_file(f, "\n \""+str[0]);
+
+ if (pStr[<1] == '\n')
+ {
+ write_file(f, "\\n\"");
+ }
+ else
+ {
+ write_file(f, "\"");
+ }
+ }
+ write_file(f, " );\n");
+}
+
+static void
+mProp(string file, string pName, mixed cmd, int pos, int signal)
+{
+ int i;
+ string *eq, t1;
+
+ for (i = pos; (i >= 0) && (get_eval_cost() > 10000); --i)
+ {
+ write_file(file, " "+pName+"(\n ");
+ eq = cmd[i][0];
+ t1 = cmd[i][1];
+
+ prettyArray(file, eq, 0);
+ write_file(file, ", ");
+
+ prettyString(file, old_explode(special(t1), "\n"), 6);
+ write_file(file, " );\n");
+ }
+
+ // Falls wir die eval_cost ausgereizt haben, aber noch nicht
+ // alle Einträge bearbeitet wurden, wird jetzt die naechste
+ // Runde gestartet
+ if (i >= 0)
+ {
+ call_out("mProp", 1, file, pName, cmd, i, signal);
+ }
+ else
+ {
+ // Ansonsten wechseln wir jetzt in den naechsten Zustand
+ write_file(file, "\n");
+ StateTransition(signal);
+ }
+}
+
+static void
+cProp(string file, string pName, mixed cmd, int pos, int signal)
+{
+ string t1, t2;
+ mixed eq;
+ int i;
+
+ for (i = pos; (i >= 0) && (get_eval_cost() > 10000); --i)
+ {
+ write_file(file, " "+pName+"(\n ");
+ eq = cmd[i][0];
+ t1 = cmd[i][1];
+ t2 = cmd[i][2];
+
+ prettyArray(file, eq, 1);
+ write_file(file, ", 0, ");
+
+ prettyString(file, old_explode(special(t1), "\n"), 4);
+ write_file(file, ", ");
+
+ if (t2)
+ {
+ prettyString(file, old_explode(special(t2), "\n"), 4);
+ }
+ else
+ {
+ write_file(file, "0");
+ }
+
+ write_file(file, " );\n");
+ }
+
+ // Falls wir die eval_cost ausgereizt haben, aber noch nicht
+ // alle Einträge bearbeitet wurden, wird jetzt die naechste
+ // Runde gestartet
+ if (i >= 0)
+ {
+ call_out("cProp", 1, file, pName, cmd, i, signal);
+ }
+ else
+ {
+ // Ansonsten wechseln wir jetzt in den naechsten Zustand
+ write_file(file, "\n");
+ StateTransition(signal);
+ }
+}
+
+private void
+prettyString(string f, string *str, int indent)
+{
+ string ind;
+ int i;
+
+ ind = extract("\n ",0,indent);
+
+ if (!sizeof(str))
+ {
+ write_file(f, ind+" \"\\n\"");
+ return;
+ }
+
+ write_file(f, ind+" \""+str[0]+"\\n\"");
+
+ for (i=1; i<sizeof(str); i++)
+ {
+ write_file(f, ind+"+\""+str[i]+"\\n\"");
+ }
+}
+
+private void
+prettyArray(string f, string *arr, int sep)
+{
+ int i,j;
+ string res, t1, t2;
+
+ write_file(f, "({");
+
+ if (sizeof(arr))
+ {
+ t1 = ("\""+arr[0]+"\"");
+ res = " "+t1;
+ t2 = "";
+
+ for (i=1, j=sizeof(arr); i<j; i++)
+ {
+ t2 = "\""+arr[i]+"\"";
+ if (!sep)
+ {
+ if ((sizeof(t1) + sizeof(t2)) > 69)
+ {
+ res += (",\n "+t2);
+ t1 = t2;
+ t2 = "";
+ }
+ else {
+ t1 += (", "+t2);
+ res += (", "+t2);
+ }
+ }
+ else {
+ res += (",\n "+t2);
+ }
+ }
+ }
+ write_file(f, res + " })" );
+}
+
+private void
+headerRoom()
+{
+ if (final)
+ {
+ write_file(file,
+ "#include <properties.h>\n\n"
+ "inherit \"std/room\";\n"
+ "inherit \""+PATH+"modules/usercmd\";\n\n"
+ "create()\n"
+ "{\n"
+ " room::create();\n"
+ " usercmd::create();\n\n"
+ " SetProp(P_LIGHT, 1);\n"
+ " SetProp(P_INDOORS, 1);\n\n");
+ }
+ else
+ {
+ write_file(file,
+ "#include \"haus.h\"\n"
+ "#include <properties.h>\n\n"
+ "inherit RAUM;\n"
+ "inherit \"/std/thing/moving\";\n\n"
+ "create()\n"
+ "{\n"
+ " if (!clonep(this_object())) return;\n"
+ " ::create();\n\n"
+ " SetOwner(\""+raum->QueryOwner()+"\", "+nr+");\n"
+ " Load();\n\n"
+ " SetProp(P_DETAILS, ([]));\n"
+ " SetProp(P_READ_DETAILS, ([]));\n\n");
+ }
+}
+
+private void
+trailerRoom()
+{
+ if (final)
+ {
+ write_file(file, "}\n");
+ }
+ else
+ {
+ write_file(file,
+ " Save(1);\n\n"
+ " { object raum;\n"
+ " if (raum = find_object(RAUMNAME("
+ "\""+raum->QueryOwner()+"\", "+nr+")))\n"
+ " raum->Load();\n"
+ " }\n\n"
+ " call_out(\"remove\",0);\n"
+ "}\n");
+ }
+}
+
+private void
+headerHouse()
+{
+ if (final)
+ {
+ write_file(file,
+ "#include <properties.h>\n"
+ "#include <moving.h>\n"
+ "#include \""+PATH+"haus.h\"\n\n"
+ "inherit \"std/thing\";\n"
+ "inherit HAUSTUER;\n\n"
+ "create()\n"
+ "{\n"
+ " thing::create();\n"
+ " haustuer::create();\n\n");
+ }
+ else
+ {
+ write_file(file,
+ "#include \"haus.h\"\n"
+ "#include <properties.h>\n\n"
+ "inherit HAUS;\n"
+ "inherit \"/std/thing/moving\";\n\n"
+ "create()\n"
+ "{\n"
+ " if (!clonep(this_object())) return;\n"
+ " ::create();\n\n"
+ " SetOwner(\""+raum->QueryOwner()+"\"\n"
+ " Load();\n\n");
+ }
+}
+
+private void
+trailerHouse()
+{
+ if (final)
+ {
+ write_file(file, read_file(PATH+"tools/haus.apx"));
+ write_file(file, " this_player()->move(");
+ write_file(file, sprintf(EXIT_TMPL,
+ raum->QueryOwner(), raum->QueryOwner(), 0));
+ write_file(file,
+ ",\n\t\t\tM_GO, 0, \"betritt \"+name(WEN,1), \"kommt herein\");\n"
+ " return 1;\n}\n");
+ if (!raum->QueryProp(P_SHORT))
+ {
+ write_file(file,
+ "\nstring short()\n"
+ "{\n"
+ " string ret;\n\n"
+ " ret = ::short();\n"
+ " if (previous_object() != environment() && !ret)\n"
+ " ret =\"\";\n\n"
+ " return ret;\n"
+ "}\n");
+ }
+ }
+ else
+ {
+ write_file(file,
+ " Save(1);\n\n"
+ " { object raum;\n"
+ " if (raum = find_object(HAUSNAME("
+ "\""+raum->QueryOwner()+"\")))\n"
+ " raum->Load();\n"
+ " }\n\n"
+ " call_out(\"remove\",0);\n}\n");
+ }
+}
diff --git a/d/seher/haeuser/tools/haus.apx b/d/seher/haeuser/tools/haus.apx
new file mode 100644
index 0000000..74e2877
--- /dev/null
+++ b/d/seher/haeuser/tools/haus.apx
@@ -0,0 +1,25 @@
+
+ AddCmd( ({ "betritt", "betrete" }), "betritt");
+}
+
+string long()
+{
+ string door;
+
+ door = haustuer::long();
+
+ return QueryProp(P_LONG)+door;
+}
+
+static int betritt(string str)
+{
+ notify_fail("Was moechtest Du betreten?\n");
+
+ if (!str || !id(str))
+ return 0;
+
+ if (Query(H_DOORSTAT) & D_CLOSED) {
+ printf("%s von %s ist zu.\n", capitalize(name(WER,1)), capitalize(owner));
+ return 1;
+ }
+
diff --git a/d/seher/haeuser/tools/hausmeister.c b/d/seher/haeuser/tools/hausmeister.c
new file mode 100644
index 0000000..b39de0e
--- /dev/null
+++ b/d/seher/haeuser/tools/hausmeister.c
@@ -0,0 +1,247 @@
+#include "../haus.h"
+
+inherit "std/thing";
+inherit "/p/service/wargon/sm/statemachine";
+
+#include "/p/service/wargon/sm/statemachine.h"
+#include <properties.h>
+#include <moving.h>
+
+#define STATE_IDLE 0
+#define STATE_GENERATING 1
+
+#define SIG_INIT 0
+#define SIG_GENERATE 1
+#define SIG_DONE 2
+
+private string dump(int haus, int final);
+private void enterGenerating(string ow, object env, int nr, int fin, int all);
+private void doGenerating(string ow, object env, int nr, int fin, int all);
+
+create()
+{
+ if (!clonep(this_object())) return;
+ thing::create();
+ statemachine::create();
+
+ SetProp( P_NAME, "Hausmeister");
+ SetProp( P_SHORT, "Ein Hausmeister" );
+ SetProp( P_LONG,
+ "Dies ist der Hausmeister aller Seherhaeuser. Er hilft Wurzel bei der\n"
+ +"Verwaltung der Haeuser.\n"
+ +"Der Hausmeister hat einen blauen Kittel an und eine Abrissbirne gezueckt.\n" );
+ SetProp( P_GENDER,MALE);
+ SetProp( P_NOGET, 1);
+
+ AddId( "hausmeister" );
+
+ AddState(STATE_IDLE, 0, 0);
+ AddState(STATE_GENERATING, #'doGenerating, 0);
+
+ AddTransition(SM_INVALID, SIG_INIT, STATE_IDLE);
+ AddTransition(STATE_IDLE, SIG_GENERATE, STATE_GENERATING, #'enterGenerating);
+ AddTransition(STATE_GENERATING, SIG_GENERATE, STATE_GENERATING, #'enterGenerating);
+ AddTransition(STATE_GENERATING, SIG_DONE, STATE_IDLE);
+
+ StateTransition(SIG_INIT);
+
+ AddCmd( "generiere", "generieren" );
+ AddCmd( ({ "reiss", "reisse" }), "abreissen" );
+ AddCmd( "verlege", "verlegen" );
+}
+
+static int
+bewege(mixed dest, int flags, string msg1, string msg2)
+{
+ int ret;
+
+ tell_room(environment(), capitalize(name(WER))+" "+msg1+".\n");
+ if ((ret = move(dest, flags)) == 1)
+ tell_room(environment(), capitalize(name(WER))+" "+msg2+".\n");
+
+ return ret;
+}
+
+static int generieren(string str)
+{
+ object env;
+ int nr, fin, all;
+ string ow, *parm;
+
+ env = environment(this_player());
+
+ notify_fail( "Syntax: generiere <name> [<nr>] [soft | ganz]\n" );
+
+ if (!str || str == "")
+ return 0;
+
+ parm = old_explode(str, " ");
+ fin = 1;
+
+ switch (sizeof(parm)) {
+ case 3:
+ if (parm[2] == "soft")
+ fin = 0;
+ case 2:
+ if (parm[1] == "soft")
+ fin = 0;
+ else if (parm[1] == "ganz") {
+ ow = parm[0];
+ nr = (VERWALTER)->HausProp(ow, HP_ROOMS);
+ str = ow+"raum"+nr;
+ all = 1;
+ break;
+ }
+ else {
+ nr = to_int(parm[1]);
+ str = parm[0]+"raum"+parm[1];
+ ow = parm[0];
+ break;
+ }
+ case 1:
+ ow = parm[0];
+ nr = -1;
+ str = ow+"haus";
+ break;
+ default:
+ return 0;
+ }
+ if (file_size(HAUSSAVEPATH+ow+".o")<0) {
+ write( "Es gibt kein '"+str+"'!\n");
+ return 1;
+ }
+ StateTransition(SIG_GENERATE, ({ow, env, nr, fin, all }) );
+ return 1;
+}
+
+static void enterGenerating(string ow, object env, int nr, int fin, int all)
+{
+ string str;
+
+ if (nr >= 0)
+ str = ow+"raum"+nr;
+ else
+ str = ow+"haus";
+
+ bewege(PATH+str, M_NOCHECK, "geht zur Arbeit", "kommt an");
+ tell_room(environment(),
+ Name(WER)+" zueckt einen Block, sieht sich alles genau an und macht\n"
+ +"sich hin und wieder Notizen. Dann nickt er zufrieden und steckt seinen\n"
+ "Block wieder weg.\n" );
+}
+
+static void doGenerating(string ow, object env, int nr, int fin, int all)
+{
+ object gen;
+ string str, out;
+
+ gen = clone_object(PATH+"tools/generator");
+ out = gen->dump(environment(), fin, ({ ow, env, nr, fin, all }));
+
+ if (nr >= 0)
+ str = ow+"raum"+nr;
+ else
+ str = ow+"haus";
+
+ bewege(env, M_NOCHECK, "geht zu seinem Auftraggeber zurueck", "kommt an");
+ write( "Der Hausmeister sagt: Ich habe '"+str+"' in die Datei\n"
+ +"Der Hausmeister sagt: '"+out+"' geschrieben, Chef!\n");
+}
+
+void
+GenerationDone(string ow, object env, int nr, int fin, int all)
+{
+ if (all)
+ {
+ if (nr > 0)
+ {
+ call_out("StateTransition", 1,
+ SIG_GENERATE, ({ ow, env, nr-1, fin, 1 }) );
+ }
+ else
+ {
+ call_out("StateTransition", 1,
+ SIG_GENERATE, ({ ow, env, -1, fin, 0 }) );
+ }
+ }
+ else
+ {
+ StateTransition(SIG_DONE, ({ ow, env, -1, fin, 0 }) );
+ }
+}
+
+static int abreissen(string str)
+{
+ object haus, env;
+ string ich, msg;
+
+ if (!str || str == "" || sscanf(str, "%s ab",str) != 1) {
+ notify_fail( "Syntax: reisse <name> ab\n" );
+ return 0;
+ }
+ str = lower_case(str);
+ if (!(haus = VERWALTER->FindeHaus(str))) {
+ write( capitalize(str)+" hat kein Haus!\n" );
+ return 1;
+ }
+ ich = capitalize(name(WER));
+ env = environment();
+ bewege(environment(haus), M_NOCHECK, "geht zur Arbeit", "kommt an");
+ msg = haus->Name(WER);
+
+ if (VERWALTER->LoescheHaus(str) == -1) {
+ tell_room(environment(), ich+" versucht vergeblich, ein Haus abzureissen.\n" );
+ msg = "Der Abrissversuch ist fehlgeschlagen, Chef!\n";
+ }
+ else {
+ tell_room(environment(), ich+" betaetigt eine Sirene.\n"+msg+" wird von "+name(WEM)+" eingeebnet.\n");
+ msg = msg+" ist abgerissen, Chef!\n";
+ if (haus) haus->remove();
+ }
+ bewege(env, M_NOCHECK, "geht zu seinem Auftraggeber zurueck", "kommt an");
+ write( "Der Hausmeister sagt: "+msg);
+ return 1;
+}
+
+static int verlegen(string str)
+{
+ string name, von, nach;
+ object haus;
+ int ret;
+
+ if (!str || sscanf(str, "%s nach %s", name, nach) != 2) {
+ notify_fail( "Syntax: verlege <name> nach <ziel>\n" );
+ return 0;
+ }
+ if (nach == "hier")
+ nach = object_name(environment(this_player()));
+
+ name = lower_case(name);
+
+ if (!(haus = VERWALTER->FindeHaus(name))) {
+ write( "Der Hausmeister sagt: "+capitalize(name)+" hat kein Haus!\n" );
+ return 1;
+ }
+ von = object_name(environment(haus));
+ ret = VERWALTER->VerlegeHaus(name, von, nach);
+ write( "Der Hausmeister sagt: " );
+ switch(ret) {
+ case -111:
+ write( "Das hast Du nicht zu bestimmen!\n" );
+ break;
+ case -3:
+ write( "Der Zielraum laesst sich nicht laden! Verlegen abgebrochen!\n" );
+ break;
+ case -4:
+ write( "Im Zielraum kann nicht gebaut werden!\n" );
+ break;
+ case -5:
+ write( "Im Haus von "+capitalize(name)+" gibt es noch Ausgaenge in andere Haeuser!\n");
+ break;
+ case 1:
+ write( "OK, Chef, ich habe das Haus verlegt!\n" );
+ break;
+ }
+ return 1;
+}
+
diff --git a/d/seher/haeuser/tools/hausmeister2.c b/d/seher/haeuser/tools/hausmeister2.c
new file mode 100644
index 0000000..41c5450
--- /dev/null
+++ b/d/seher/haeuser/tools/hausmeister2.c
@@ -0,0 +1,534 @@
+#include "../haus.h"
+#include <properties.h>
+#include <moving.h>
+
+inherit "std/thing";
+
+static void do_gen(string ow, object env, int nr, int fin, int all);
+private string special(string str);
+private string dump(int haus, int final);
+private void header(string f, int final, object haus, int nr);
+private void trailer(string f, int final, object haus, int nr);
+private void sProp(string f, string pName, string pStr);
+private void mProp(string f, string pName, mapping pMap);
+private void cProp(string f, string pName, mapping cMap);
+private void prettyString(string f, string *str, int indent);
+private void prettyArray(string f, string *arr, int sep);
+
+create()
+{
+ if (!clonep(this_object())) return;
+ ::create();
+
+ SetProp( P_NAME, "Hausmeister");
+ SetProp( P_SHORT, "Ein Hausmeister" );
+ SetProp( P_LONG,
+ "Dies ist der Hausmeister aller Seherhaeuser. Er hilft Wurzel bei der\n"
+ +"Verwaltung der Haeuser.\n"
+ +"Der Hausmeister hat einen blauen Kittel an und eine Abrissbirne gezueckt.\n" );
+ SetProp( P_GENDER,MALE);
+ SetProp( P_NOGET, 1);
+
+ AddId( "hausmeister" );
+
+ AddCmd( "generiere", "generieren" );
+ AddCmd( ({ "reiss", "reisse" }), "abreissen" );
+ AddCmd( "verlege", "verlegen" );
+}
+
+static int
+bewege(mixed dest, int flags, string msg1, string msg2)
+{
+ int ret;
+
+ tell_room(environment(), capitalize(name(WER))+" "+msg1+".\n");
+ if ((ret = move(dest, flags)) == 1)
+ tell_room(environment(), capitalize(name(WER))+" "+msg2+".\n");
+
+ return ret;
+}
+
+static int generieren(string str)
+{
+ object env;
+ int nr, fin, all;
+ string ow, *parm;
+
+ env = environment(this_player());
+
+ notify_fail( "Syntax: generiere <name> [<nr>] [soft | ganz]\n" );
+
+ if (!str || str == "")
+ return 0;
+
+ parm = old_explode(str, " ");
+ fin = 1;
+
+ switch (sizeof(parm)) {
+ case 3:
+ if (parm[2] == "soft")
+ fin = 0;
+ case 2:
+ if (parm[1] == "soft")
+ fin = 0;
+ else if (parm[1] == "ganz") {
+ ow = parm[0];
+ nr = (VERWALTER)->HausProp(ow, HP_ROOMS);
+ str = ow+"raum"+nr;
+ all = 1;
+ break;
+ }
+ else {
+ nr = to_int(parm[1]);
+ str = parm[0]+"raum"+parm[1];
+ ow = parm[0];
+ break;
+ }
+ case 1:
+ ow = parm[0];
+ nr = -1;
+ str = ow+"haus";
+ break;
+ default:
+ return 0;
+ }
+ if (file_size(HAUSSAVEPATH+ow+".o")<0) {
+ if (nr >= 0 && file_size(HAUSSAVEPATH+ow+nr+".o")<0) {
+ write( "Es gibt kein '"+str+"'!\n");
+ return 1;
+ }
+ }
+ do_gen(ow, env, nr, fin, all);
+ return 1;
+}
+
+static void do_gen(string ow, object env, int nr, int fin, int all)
+{
+ string str, out;
+
+ if (nr >= 0)
+ str = ow+"raum"+nr;
+ else
+ str = ow+"haus";
+
+ bewege(PATH+str, M_NOCHECK, "geht zur Arbeit", "kommt an");
+ tell_room(environment(), Name(WER)+" zueckt einen Block, sieht sich alles genau an und macht\n"
+ +"sich hin und wieder Notizen. Dann nickt er zufrieden und steckt seinen\nBlock wieder weg.\n" );
+ out = dump(nr, fin);
+ bewege(env, M_NOCHECK, "geht zu seinem Auftraggeber zurueck", "kommt an");
+ write( "Der Hausmeister sagt: Ich habe '"+str+"' in die Datei\n"
+ +"Der Hausmeister sagt: '"+out+"' geschrieben, Chef!\n");
+
+ if (all) {
+ if (nr > 0)
+ call_out("do_gen", 1, ow, env, nr-1, fin, all);
+ else
+ call_out("do_gen", 1, ow, env, -1, fin);
+ }
+}
+
+static int abreissen(string str)
+{
+ object haus, env;
+ string ich, msg;
+
+ if (!str || str == "" || sscanf(str, "%s ab",str) != 1) {
+ notify_fail( "Syntax: reisse <name> ab\n" );
+ return 0;
+ }
+ str = lower_case(str);
+ if (!(haus = VERWALTER->FindeHaus(str))) {
+ write( capitalize(str)+" hat kein Haus!\n" );
+ return 1;
+ }
+ ich = capitalize(name(WER));
+ env = environment();
+ bewege(environment(haus), M_NOCHECK, "geht zur Arbeit", "kommt an");
+ msg = haus->Name(WER);
+
+ if (VERWALTER->LoescheHaus(str) == -1) {
+ tell_room(environment(), ich+" versucht vergeblich, ein Haus abzureissen.\n" );
+ msg = "Der Abrissversuch ist fehlgeschlagen, Chef!\n";
+ }
+ else {
+ tell_room(environment(), ich+" betaetigt eine Sirene.\n"+msg+" wird von "+name(WEM)+" eingeebnet.\n");
+ msg = msg+" ist abgerissen, Chef!\n";
+ if (haus) haus->remove();
+ }
+ bewege(env, M_NOCHECK, "geht zu seinem Auftraggeber zurueck", "kommt an");
+ write( "Der Hausmeister sagt: "+msg);
+ return 1;
+}
+
+static int verlegen(string str)
+{
+ string name, von, nach;
+ object haus;
+ int ret;
+
+ if (!str || sscanf(str, "%s nach %s", name, nach) != 2) {
+ notify_fail( "Syntax: verlege <name> nach <ziel>\n" );
+ return 0;
+ }
+ if (nach == "hier")
+ nach = object_name(environment(this_player()));
+
+ name = lower_case(name);
+
+ if (!(haus = VERWALTER->FindeHaus(name))) {
+ write( "Der Hausmeister sagt: "+capitalize(name)+" hat kein Haus!\n" );
+ return 1;
+ }
+ von = object_name(environment(haus));
+ ret = VERWALTER->VerlegeHaus(name, von, nach);
+ write( "Der Hausmeister sagt: " );
+ switch(ret) {
+ case -111:
+ write( "Das hast Du nicht zu bestimmen!\n" );
+ break;
+ case -3:
+ write( "Der Zielraum laesst sich nicht laden! Verlegen abgebrochen!\n" );
+ break;
+ case -4:
+ write( "Im Zielraum kann nicht gebaut werden!\n" );
+ break;
+ case -5:
+ write( "Im Haus von "+capitalize(name)+" gibt es noch Ausgaenge in andere Haeuser!\n");
+ break;
+ case 1:
+ write( "OK, Chef, ich habe das Haus verlegt!\n" );
+ break;
+ }
+ return 1;
+}
+
+/*** Funktionen zum Generieren einer Datei aus den Properties des Hauses ***/
+
+#define EXIT_TMPL "\"/players/%s/seherhaus/%sraum%d\""
+
+private void dump_chest(string out, object chest)
+{
+ mixed n;
+
+ catch(rm(out));
+
+ write_file(out, "#include <properties.h>\n#include <moving.h>\n\n"
+ "inherit \"/d/wueste/durian/behaelter\";\n\n"
+ "void create()\n{\n if(!clonep(this_object())) return;\n\n"
+ " ::create();\n\n" );
+ sProp(out, "P_SHORT", chest->QueryProp(P_SHORT));
+ sProp(out, "P_LONG", chest->QueryProp(P_LONG));
+
+ write_file(out, " SetProp(P_NOGET, 1);\n");
+ write_file(out, " SetProp(P_GENDER, "+
+ ({"NEUTER","MALE","FEMALE"})[chest->QueryProp(P_GENDER)]+
+ " );\n SetProp(P_NAME, ");
+
+ n = chest->QueryProp(P_NAME);
+ if (stringp(n))
+ write_file(out, "\""+n+"\"");
+ else
+ prettyArray(out, n, 0);
+ write_file(out, " );\n\n AddId( ");
+ prettyArray(out, chest->QueryProp(P_IDS)-({ TRUHE }), 0);
+ write_file(out, " );\n");
+
+ if ((n=chest->QueryProp(P_ADJECTIVES)) && sizeof(n)) {
+ write_file(out, "\n AddAdjective( ");
+ prettyArray(out, n, 0);
+ write_file(out, " );\n");
+ }
+ if ((n=chest->QueryProp(P_NAME_ADJ)) && sizeof(n)) {
+ write_file(out, "\n SetProp(P_NAME_ADJ, ");
+ prettyArray(out, n, 0);
+ write_file(out, " );\n");
+ }
+ write_file(out, "}\n");
+}
+
+private string dump(int nr, int final)
+{
+ string out;
+ object env;
+ mapping prop;
+
+ env = environment(this_object());
+
+ if (final && env->QueryProp(H_CHEST))
+ dump_chest(PATH+"rep/"+env->QueryOwner()+"truhe.c", present(TRUHE, env));
+
+ if (final) {
+ out = PATH+"rep/"+env->QueryOwner();
+ if (nr < 0)
+ out += "haus.c";
+ else
+ out += "raum"+nr+".c";
+ }
+ else
+ out = PATH+"fixed.c";
+
+ catch(rm(out));
+
+ header(out, final, env, nr);
+ if (nr<0) {
+ sProp(out, "P_SHORT", env->QueryProp(P_SHORT));
+ write_file(out, "\n");
+ sProp(out, "P_LONG", env->QueryProp(P_LONG));
+ write_file(out, "\n");
+
+ if (final) {
+ mixed n;
+
+ write_file(out, " SetProp(P_NOGET, 1);\n");
+ write_file(out, " SetProp(P_GENDER, "+
+ ({"NEUTER","MALE","FEMALE"})[env->QueryProp(P_GENDER)]+
+ " );\n SetProp(P_NAME, ");
+ n = env->QueryProp(P_NAME);
+ if (stringp(n))
+ write_file(out, "\""+n+"\"");
+ else
+ prettyArray(out, n, 0);
+ write_file(out, " );\n\n AddId( ");
+ prettyArray(out, env->QueryProp(P_IDS)-({ "sehe\rhaus", "\n"+env->QueryOwner()+"haus" }), 0);
+ write_file(out, " );\n");
+ }
+ }
+ else {
+ sProp(out, "P_INT_SHORT", env->QueryProp(P_INT_SHORT));
+ write_file(out, "\n");
+ sProp(out, "P_INT_LONG", env->QueryProp(P_INT_LONG));
+ write_file(out, "\n");
+ if (sizeof(prop = env->QueryProp(P_DETAILS))) {
+ mProp(out, "AddDetail", prop);
+ write_file(out, "\n");
+ }
+ if (sizeof(prop = env->QueryProp(P_READ_DETAILS))) {
+ mProp(out, "AddReadDetail", prop);
+ write_file(out, "\n");
+ }
+ if (sizeof(prop = env->QueryProp(H_COMMANDS)))
+ cProp(out, "AddUserCmd", prop);
+
+ write_file(out, "\n");
+ if (final) {
+ string *k, o;
+ int i, num;
+
+ prop = env->QueryProp(P_EXITS);
+ k = m_indices(prop);
+ if (member(k, "raus") >= 0) {
+ k -= ({ "raus" });
+ write_file(out, sprintf(" AddExit( \"raus\", \"%s\");\n", prop["raus"]));
+ }
+ for (i=sizeof(k)-1; i>=0; i--) {
+ if (sscanf(prop[k[i]], PATH+"%sraum%d", o, num) != 2)
+ printf("Komischer Exit (%O)\n%s -> %s\n", env, k[i], prop[k[i]]);
+ else {
+ if (o == env->QueryOwner()) {
+ o = sprintf(EXIT_TMPL, o, o, num);
+ write_file(out, sprintf(" AddExit( \"%s\", %s);\n", k[i], o));
+ }
+ else {
+ write_file(out, sprintf(" AddExit( \"%s\", \"%s\");\n", k[i], prop[k[i]]));
+ printf("Exit von %O nach %s!\n", env, prop[k[i]]);
+ }
+ }
+ }
+ }
+ }
+ trailer(out, final, env, nr);
+
+ return out;
+}
+
+private void header(string f, int final, object haus, int nr)
+{
+ if (final) {
+ write_file(f, "#include <properties.h>" );
+ if (nr >= 0) {
+ write_file(f, "\n\ninherit \"std/room\";\ninherit \""+PATH+"modules/usercmd\";");
+ write_file(f, "\n\ncreate()\n{\n room::create();\n usercmd::create();\n\n");
+ write_file(f, " SetProp(P_LIGHT, 1);\n SetProp(P_INDOORS, 1);\n\n");
+ }
+ else {
+ write_file(f, "\n#include <moving.h>\n#include \""+PATH+"haus.h\"\n\n" );
+ write_file(f, "inherit \"std/thing\";\ninherit HAUSTUER;\n\n" );
+ write_file(f, "create()\n{\n thing::create();\n haustuer::create();\n\n");
+ }
+ }
+ else {
+ write_file(f, "#include \"haus.h\"\n#include <properties.h>\n\ninherit ");
+ write_file(f, ((nr < 0) ? "HAUS" : "RAUM" ) );
+ write_file(f, ";\ninherit \"/std/thing/moving\";\n\n");
+ write_file(f, "create()\n{\n if (!clonep(this_object())) return;\n ::create();\n\n");
+ write_file(f, " SetOwner(\""+haus->QueryOwner()+"\"");
+ if (nr >= 0)
+ write_file(f, ", "+nr);
+ write_file(f, ");\n Load();\n\n");
+ if (nr >= 0)
+ write_file(f, " SetProp(P_DETAILS, ([]));\n SetProp(P_READ_DETAILS, ([]));\n\n");
+ }
+}
+
+private void trailer(string f, int final, object haus, int nr)
+{
+ if (final) {
+ if (nr >= 0)
+ write_file(f, "}\n");
+ else {
+ write_file(f, read_file(PATH+"tools/haus.apx"));
+ write_file(f, " this_player()->move(");
+ write_file(f, sprintf(EXIT_TMPL, haus->QueryOwner(), haus->QueryOwner(), 0));
+ write_file(f, ",\n\t\t\tM_GO, 0, \"betritt \"+name(WEN,1), \"kommt herein\");\n"
+ " return 1;\n}\n");
+ if (!haus->QueryProp(P_SHORT))
+ write_file(f, "\nstring short()\n{\n string ret;\n\n"
+ " ret = ::short();\n"
+ " if (previous_object() != environment() && !ret)\n"
+ " ret =\"\";\n\n return ret;\n}\n");
+ }
+ }
+ else {
+ write_file(f, " Save(1);\n\n");
+ write_file(f, " { object raum;\n if (raum = find_object(");
+ if (nr >= 0)
+ write_file(f, "RAUMNAME(\""+haus->QueryOwner()+"\", "+nr+")))\n");
+ else
+ write_file(f, "HAUSNAME(\""+haus->QueryOwner()+"\")))\n");
+ write_file(f, " raum->Load();\n }\n\n call_out(\"remove\",0);\n}\n");
+ }
+}
+
+private string special(string s)
+{
+ s = implode(explode(s, "\\"), "\\\\");
+ s = implode(explode(s, "\t"), "\\t");
+ s = implode(explode(s, "\""), "\\\"");
+
+ return s;
+}
+
+private void sProp(string f, string pName, string pStr)
+{
+ string *str;
+ write_file(f, " SetProp( "+pName+",");
+ if (!pStr) {
+ write_file(f, "0 );\n");
+ return;
+ }
+ pStr = special(pStr);
+ if (sizeof(str=old_explode(pStr,"\n")) > 1)
+ prettyString(f, str, 4);
+ else {
+ if (sizeof(str)==0)
+ str = ({""});
+ write_file(f, "\n \""+str[0]);
+ if (pStr[<1] == '\n')
+ write_file(f, "\\n\"");
+ else
+ write_file(f, "\"");
+ }
+ write_file(f, " );\n");
+}
+
+private void mProp(string f, string pName, mapping pMap)
+{
+ string *eq, t1;
+ mixed cmd;
+ int i,j;
+
+ if (sizeof(pMap) == 0)
+ return;
+
+ cmd = VERWALTER->PCrunch(pMap);
+
+ for (i=sizeof(cmd)-1; i>=0; i--) {
+ write_file(f, " "+pName+"(\n ");
+ eq = cmd[i][0];
+ t1 = cmd[i][1];
+
+ prettyArray(f, eq, 0);
+ write_file(f, ", ");
+
+ prettyString(f, old_explode(special(t1), "\n"), 6);
+ write_file(f, " );\n");
+ }
+}
+
+private void cProp(string f, string pName, mapping cMap)
+{
+ string t1, t2;
+ mixed cmd, eq;
+ int i,j;
+
+ cmd = VERWALTER->PCrunch(cMap);
+
+ for( i=sizeof(cmd)-1; i>=0; i--) {
+ write_file(f, " "+pName+"(\n ");
+ eq = cmd[i][0];
+ t1 = cmd[i][1];
+ t2 = cmd[i][2];
+
+ prettyArray(f, eq, 1);
+ write_file(f, ", 0, ");
+
+ prettyString(f, old_explode(special(t1), "\n"), 4);
+ write_file(f, ", ");
+ if (t2)
+ prettyString(f, old_explode(special(t2), "\n"), 4);
+ else
+ write_file(f, "0");
+ write_file(f, " );\n");
+ }
+}
+
+private void prettyString(string f, string *str, int indent)
+{
+ string ind;
+ int i;
+
+ ind = extract("\n ",0,indent);
+
+ if (!sizeof(str)) {
+ write_file(f, ind+" \"\\n\"");
+ return;
+ }
+ write_file(f, ind+" \""+str[0]+"\\n\"");
+ for (i=1; i<sizeof(str); i++) {
+ write_file(f, ind+"+\""+str[i]+"\\n\"");
+ }
+}
+
+private void prettyArray(string f, string *arr, int sep)
+{
+ int i,j;
+ string res, t1, t2;
+
+ write_file(f, "({");
+
+ if (sizeof(arr)) {
+ t1 = ("\""+arr[0]+"\"");
+ res = " "+t1;
+ t2 = "";
+
+ for (i=1, j=sizeof(arr); i<j; i++) {
+ t2 = "\""+arr[i]+"\"";
+ if (!sep) {
+ if ((sizeof(t1)+sizeof(t2))>69) {
+ res += (",\n "+t2);
+ t1 = t2;
+ t2 = "";
+ }
+ else {
+ t1 += (", "+t2);
+ res += (", "+t2);
+ }
+ }
+ else {
+ res += (",\n "+t2);
+ }
+ }
+ }
+ write_file(f, res + " })" );
+}
+
diff --git a/d/seher/haeuser/tools/haustool.c b/d/seher/haeuser/tools/haustool.c
new file mode 100644
index 0000000..50f6e1e
--- /dev/null
+++ b/d/seher/haeuser/tools/haustool.c
@@ -0,0 +1,182 @@
+#include "../haus.h"
+#include <properties.h>
+#include <moving.h>
+#include <wizlevels.h>
+
+inherit "std/secure_thing";
+
+private int secure()
+{
+ return (this_interactive() && (IS_ARCH(this_interactive()) ||
+ getuid(this_interactive()) == "wurzel"));
+}
+
+create()
+{
+ if (!clonep(this_object())) return;
+ ::create();
+
+ SetProp(P_SHORT, "Ein Adressverzeichnis" );
+ SetProp(P_LONG,
+ "Mit diesem Adressverzeichnis koennen die richtigen Leute Ordnung in den\n"
+ +"Wust der Seherhausangelegenheiten bringen.\n"
+ +"Die richtigen Leute?\n"
+ +"Ja: Man muss schon Erzmagier sein oder Wurzel heissen! ;)\n"
+ +"Du kannst es uebrigens lesen!\n" );
+ SetProp(P_NAME, "Adressverzeichnis");
+ SetProp(P_READ_MSG,
+ "Es stehen folgende Befehle zur Verfuegung:\n"
+ +"checked <name> [+/-] <nr>\n"
+ +"rep\n"
+ +"mkmail <name>\n"
+ );
+ SetProp(P_GENDER, NEUTER);
+ SetProp(P_WEIGHT, 100);
+ SetProp(P_AUTOLOADOBJ, 1);
+ SetProp(P_NEVERDROP, 1);
+ SetProp(P_NODROP, 1);
+
+ AddId( ({ "verzeichnis", "adressverzeichnis", "haustool" }) );
+
+ AddCmd("checked", "checked");
+ AddCmd("rep", "report");
+ AddCmd("mkmail", "mkmail");
+}
+
+#define CHECKED PATH+"log/CHECKED"
+static int
+checked(string str)
+{
+ mapping drin;
+ string name, *lines, *ind, pm;
+ int nr, i;
+ closure hp;
+
+ if (!secure())
+ return 0;
+
+ notify_fail("Syntax: checked <name> [+/-] <nr>\n" );
+ if (!str || str == "")
+ return 0;
+
+ if (file_size(CHECKED) > 0)
+ lines = explode(read_file(CHECKED), "\n") - ({""});
+ else
+ lines = ({});
+
+ for (drin = ([]), i=sizeof(lines)-1; i>=0; i--) {
+ if (sscanf(lines[i], "%s%t%d", name, nr) == 2)
+ drin += ([ name : nr-1 ]);
+ }
+ lines = ({ });
+ pm = "";
+ hp = symbol_function("HausProp", VERWALTER);
+
+ if (sscanf(str, "%s %d", name, nr)==2 || sscanf(str, "%s %s %d", name, pm, nr) == 3) {
+ if (!funcall(hp, name, HP_ENV)) {
+ write(capitalize(name)+" hat gar kein Haus!\n");
+ return 1;
+ }
+ if (nr < 0) {
+ write("Zum Abziehen nimm bitte 'checked <name> - <nr>'!\n");
+ return 1;
+ }
+ if (member(drin, name))
+ i = drin[name];
+ switch(pm) {
+ case "+":
+ if (i+nr > funcall(hp, name, HP_ROOMS)) {
+ printf("%d Raeume? Wie soll das gehen?\n", i+nr);
+ return 1;
+ }
+ drin[name] += nr;
+ break;
+ case "-":
+ if (i-nr < 0) {
+ write("Soviele Raeume kannst Du "+capitalize(name)+" gar nicht abziehen...\n");
+ return 1;
+ }
+ drin[name] -= nr;
+ break;
+ default:
+ if (nr > funcall(hp, name, HP_ROOMS)) {
+ printf("%s nat keine %d Raeume!\n",capitalize(name),nr);
+ return 1;
+ }
+ drin[name] = nr;
+ }
+ rm(CHECKED);
+ for (i=sizeof(ind=sort_array(m_indices(drin),#'<))-1; i>=0; i--)
+ write_file(CHECKED, sprintf("%s %d\n",ind[i], 1+drin[ind[i]]));
+ return 1;
+ }
+ else
+ return 0;
+}
+
+static int
+report()
+{
+ string *rep, *head, name;
+ int i, lp, nr;
+
+ if (file_size("/log/report/wurzel.rep")<=0) {
+ write("Kein wurzel.rep (Jippieh! ;)\n");
+ return 1;
+ }
+
+ rep = old_explode(read_file("/log/report/wurzel.rep"),"\n");
+ lp = sizeof(PATH)-1;
+
+ for (i=sizeof(rep)-2; i>=0; i-=2) {
+ head = old_explode(rep[i], " ");
+ if (head[4][0..lp] == PATH) {
+ name = old_explode(head[4],"/")[<1];
+ nr = to_int(name[<1..<1]);
+ name = name[0..<6];
+ head[2] = capitalize(head[2]);
+ write_file(PATH+"rep/"+name,
+ sprintf("%s in Raum %d:\n%s\n",
+ implode(head[0..2]," "),nr,rep[i+1]));
+ }
+ else
+ write_file(PATH+"rep/wurzel.rep",sprintf("%s\n%s\n", rep[i], rep[i+1]));
+ }
+ return 1;
+}
+
+static int
+mkmail(string str)
+{
+ string f,fm;
+
+ if (!str || str == "") {
+ notify_fail( "Syntax: mkmail <name>\n");
+ return 0;
+ }
+
+ if (!(f=(VERWALTER)->HausProp(str, HP_ENV))) {
+ printf("%s hat kein Haus!\n", str);
+ return 1;
+ }
+ fm = PATH+str+".mail";
+
+ write_file(fm, "\
+ Huhu!\n\
+\n\
+Da Du Magier bist, brauchst Du auch kein Seherhaus mehr. Damit Deine\n\
+Beschreibungen aber nicht verloren sind, findest Du die Files Deines\n\
+Hauses in /players/"+str+"/seherhaus/.\n\
+\n\
+Soll Dein Haus weiterhin an der jetzigen Stelle stehen bleiben\n\
+("+f+"),\n\
+so klaere das bitte mit dem dort zustaendigen Magier sowie den zustaen-\n\
+digen Regionsmagiern (weil es sich jetzt um den Anschluss von Files an\n\
+ein Gebiet handelt).\n\
+\n\
+!! Das Haus wird auf jeden Fall nach Ende der Haussperre abgerissen !!\n\
+\n\
+ Wargon.\n");
+
+ return 1;
+}
diff --git a/d/seher/haeuser/tools/liste.c b/d/seher/haeuser/tools/liste.c
new file mode 100755
index 0000000..12b39a2
--- /dev/null
+++ b/d/seher/haeuser/tools/liste.c
@@ -0,0 +1,25 @@
+#include "../haus.h"
+#include <wizlevels.h>
+
+mapping megamap;
+
+create() {
+ seteuid(getuid(this_object()));
+ restore_object(SAVEFILE);
+ do_dump();
+}
+
+do_dump()
+{
+ string *ow, typ;
+ int i, r, r2;
+ ow = m_indices(megamap);
+ ow = sort_array(ow,#'<);
+ i = sizeof(ow)-1;
+ for(r=0, r2=0; i>=0; i--) {
+ r = megamap[ow[i],HP_ROOMS];
+ if (IS_LEARNER(ow[i])) printf("%13s %d MAGIER(%d)\n", ow[i],r,query_wiz_level(ow[i]));
+ else if (!IS_SEER(ow[i])) printf("%13s %d KEIN SEHER MEHR\n", ow[i], r);
+ }
+ destruct(this_object());
+}
diff --git a/d/seher/haeuser/traghaus.c b/d/seher/haeuser/traghaus.c
new file mode 100644
index 0000000..f79fb36
--- /dev/null
+++ b/d/seher/haeuser/traghaus.c
@@ -0,0 +1,187 @@
+/*
+ * traghaus.c -- Wie suess! ;)
+ *
+ * (c) 1994 Boing@MorgenGrauen
+ * Be- und ueberarbeitet von Jof und Wargon.
+ *
+ * HINWEIS: Um einen Bauplatz zu kennzeichnen, muss dort die
+ * Propertie "haus_erlaubt" auf 1 gesetzt werden!
+ *
+ * 17.11.2003 Feigling - Bugfix: Fehlenden Regionsmagier abgefangen
+ *
+ * $Date: 1994/10/24 08:25:18 $
+ * $Revision: 1.5 $
+ * $Log: traghaus.c,v $
+ * Revision 1.5 1994/10/24 08:25:18 Wargon
+ * Macht jetzt Gebrauch von VERWALTER->Unbebaubar() und dem geaenderten
+ * VERWALTER->NeuesHaus().
+ *
+ * Revision 1.4 1994/10/19 10:03:29 Wargon
+ * Hinweis eingebaut (s.o.)
+ * Beschraenkung auf ein Seherhaus pro Raum rausgenommen.
+ *
+ * Revision 1.3 1994/10/09 20:17:03 Wargon
+ * In blas() haus->Save() eingefuegt.
+ *
+ * Revision 1.2 1994/10/07 22:13:17 Wargon
+ * Etwas aufgeraeumt.
+ * Text beim Giessen geaendert.
+ * Falls in dem Raum schon ein Seherhaus steht, kann kein weiteres mehr
+ * aufgestellt werden.
+ *
+ * Revision 1.1 1994/10/07 14:40:54 Wargon
+ * Initial revision
+ *
+ */
+#include <properties.h>
+#include <moving.h>
+#include "haus.h"
+
+inherit "std/thing";
+
+static string owner;
+
+void create()
+{
+ if (!clonep(this_object())) return;
+ ::create();
+ owner = getuid(this_player());
+ SetProp(P_SHORT, "Ein tragbares Instanthaus");
+ SetProp(P_LONG, "Dies ist Dein Haus. Du kannst es abstellen und giessen, dann wird daraus ein\n\
+richtiges Seherhaus, in das Du sofort einziehen kannst. Es ist allerdings\n\
+noetig, dass der Magier, der den Raum erschaffen hat, in dem Du es abstellen\n\
+moechtest, dem Bau eines Seherhauses in diesem Raum zustimmt.\n");
+ SetProp(P_NAME, "Haus");
+ SetProp(P_NEVERDROP, 1);
+ SetProp(P_GENDER, 0);
+ AddId(({"haus", "sehe\rhaus"}));
+ SetProp(P_VALUE, 0);
+ SetProp(P_WEIGHT, 0);
+ AddCmd(({"gies", "giess", "giesse"}), "blas");
+}
+
+string SetOwner(string o)
+{
+ return owner = o;
+}
+
+string QueryOwner()
+{
+ return owner;
+}
+
+string get_mag(mixed dest)
+{
+ mapping reg;
+ string *mag;
+ string ret;
+ int i, j;
+
+ catch(reg = "/obj/mliste"->QueryProp("Magierliste"));
+
+ if (mappingp(reg) && member(reg, getuid(dest)))
+ mag = reg[getuid(dest)];
+ else
+ return capitalize(getuid(dest));
+
+
+ if (!sizeof(mag))
+ return capitalize(getuid(dest)); //Hinzugefuegt Feigling
+
+ if ((i=sizeof(mag)) == 1)
+ return capitalize(mag[0]);
+ else {
+ ret = capitalize(mag[0]);
+ j = 1;
+ while (j < i-1) {
+ ret += ", "+capitalize(mag[j]);
+ j++;
+ }
+ ret += " und "+capitalize(mag[<1]);
+ }
+ return ret;
+}
+
+int move(mixed dest, int method)
+{
+ int nix;
+
+ if ((method & M_GIVE) == M_GIVE)
+ {
+ write("Dein sauer verdientes Seherhaus weggeben? NIEMALS!\n");
+ return 0;
+ }
+ if ((method & M_PUT) == M_PUT)
+ {
+ if ((nix = VERWALTER->Unbebaubar(dest)))
+ {
+ write( ({ "Hier ist das Bauen von Haeusern untersagt!\n",
+ "Du kannst das Haus nicht in geschlossenen Raeumen abstellen.\n",
+ "Dieser Platz ist nicht als Bauplatz gekennzeichnet, Du solltest mal\nmit dem verantwortlichen Magier reden. Die Zustaendigkeit fuer diesen Ort\nliegt bei "+get_mag(dest)+".\n"
+ })[nix-1]);
+ return 0;
+ }
+ return ::move(dest, method);
+ }
+ if ((method & M_GET) == M_GET)
+ {
+ if (getuid(this_player())!=owner)
+ {
+ write("Dies ist nicht Dein Haus.\n");
+ return 0;
+ }
+ }
+ return ::move(dest, method);
+}
+
+int blas(string str)
+{
+ object haus;
+
+ notify_fail("Was moechtest Du giessen?\n");
+ if (!str || str!="haus")
+ return 0;
+ if (living(environment()))
+ {
+ write("Du solltest das Haus vielleicht erst mal abstellen.\n");
+ return 1;
+ }
+ if (getuid(this_player())!=owner)
+ {
+ write("Machst Du immer fremde Haeuser nass?\n");
+ return 1;
+ }
+ if (!environment()->QueryProp(P_HAUS_ERLAUBT))
+ {
+ write("Dieser Platz ist nicht als Bauplatz gekennzeichnet, Du solltest mal\n\
+mit dem entsprechenden Magier reden.\nFrag mal "+capitalize(getuid(environment()))+".\n");
+ return 0;
+ }
+ write( "Voller Vorfreude greifst Du nach Deiner Giesskanne und beginnst, Dein mueh-\n\
+sam erspartes Instanthaus zu begiessen. Moment... Giesskanne? Reichlich ver-\n\
+dutzt schaust Du auf die kleine gruene Kanne in Deinen Haenden. Wo mag sie\n\
+nur hergekommen sein? Doch kaum erreichen die ersten Tropfen das Instanthaus,\n\
+wird Deine Aufmerksamkeit auch schon wieder von der Kanne abgelenkt:\n\
+Das Trockenhaus beginnt zu schaeumen und sich ueber den Boden auszubreiten.\n\
+In dem Schaum entstehen und vergehen Waende, Decken und Fenster, als ob sie\n\
+sich noch nicht recht entscheiden koennten, wie sich sich zu einem Ganzen zu-\n\
+sammenfuegen sollen.\n\
+Dann erhebt sich dort, wo Du das Trockenhaus abgestellt hattest, eine grosse,\n\
+schaumige Blase! Sie wird groesser und groesser, bis sie Dich schliesslich\n\
+streift. Dabei platzt sie mit einem leisen *PLOPP* - und es bleibt ein be-\n\
+zugsfertiges Seherhaus zurueck!\n\
+Du wirfst noch einmal einen verstohlenen Blick auf die Giesskanne, musst aber\n\
+feststellen, dass sie verschwunden ist und auch verschwunden bleibt.\n" );
+
+ say(capitalize((string)(this_player()->name()))+" verwandelt mit einem Tropfen Wasser "+
+ this_player()->QueryPossPronoun(this_object(), WEN) + " Haus.\n");
+
+ VERWALTER->NeuesHaus(owner, environment(this_object()));
+ remove();
+ return 1;
+}
+
+static string _query_autoloadobj()
+{
+ return owner;
+}
diff --git a/d/seher/haeuser/truhe.c b/d/seher/haeuser/truhe.c
new file mode 100644
index 0000000..3eab8ad
--- /dev/null
+++ b/d/seher/haeuser/truhe.c
@@ -0,0 +1,365 @@
+#include "haus.h"
+#include <properties.h>
+#include <moving.h>
+#include <wizlevels.h>
+
+inherit "/d/wueste/durian/behaelter";
+inherit "/p/service/wargon/mat_ed";
+inherit "/mail/nedit";
+
+static string owner;
+
+void create()
+{
+ if (!clonep(this_object())) return;
+
+ ::create();
+
+ Set(P_NAME, SAVE, F_MODE_AS);
+ Set(P_SHORT, SAVE, F_MODE_AS);
+ Set(P_LONG, SAVE, F_MODE_AS);
+ Set(P_GENDER, SAVE, F_MODE_AS);
+ Set(P_IDS, SAVE, F_MODE_AS);
+ Set(P_INVIS, SAVE, F_MODE_AS);
+ Set(P_NAME_ADJ, SAVE, F_MODE_AS);
+ Set(P_MATERIAL, SAVE, F_MODE_AS);
+ Set(H_DOORLSTAT, SAVE, F_MODE_AS);
+
+ SetProp( P_NAME, "Truhe" );
+ SetProp( P_SHORT, "Eine Truhe" );
+ SetProp( P_LONG,
+ "Eine stabile Holztruhe mit einem Sicherheitsschloss. Nur ausgewaehlte\n"
+ +"Personen duerfen die Truhe oeffnen und Sachen in ihr lagern oder aus\n"
+ +"ihr nehmen.\n" );
+ SetProp( P_GENDER, FEMALE );
+ SetProp( P_NOGET, 1 );
+ SetProp( P_IDS, ({ "truhe","holztruhe", TRUHE}) );
+ SetProp( P_MATERIAL, ([ MAT_MISC_WOOD : 100 ]) );
+ SetProp( H_DOORLSTAT, ({ "geschlossen", "geoeffnet"}) );
+
+ AddCmd( ({ "schieb","schiebe"}), "schieben" );
+ AddCmd( ({ "beschreib", "beschreibe" }), "beschreiben" );
+ AddCmd( ({ "aender", "aendere" }), "aendern" );
+}
+
+mixed
+_set_owner(string ow)
+{
+ string *na, *a;
+ int i;
+
+ if (ow && stringp(ow))
+ restore_object(HAUSSAVEPATH+ow+"truhe");
+
+ if ((na = QueryProp(P_NAME_ADJ)) && (i=sizeof(na))) {
+ for (a = ({ }), i-=1; i>=0; i--)
+ a += ({ DeclAdj(na[i], WER)[0..<2], DeclAdj(na[i], WEM)[0..<2], DeclAdj(na[i],WEN)[0..<2] });
+
+ a = m_indices(mkmapping(a));
+ if (sizeof(a))
+ AddAdjective(a);
+ }
+
+ SetZu();
+ return owner=ow;
+}
+
+string
+short()
+{
+ int open;
+ string sh, *stat;
+
+ open = (QueryProp(P_CNT_STATUS) == CNT_STATUS_OPEN);
+ sh = QueryProp(P_SHORT);
+ stat = QueryProp(H_DOORLSTAT);
+ if (!stat)
+ stat = ({ "", ""});
+ else if (strstr(sh, "%s") == -1)
+ sh += " (%s)";
+ if(QueryProp(P_INVIS)) return "";
+ return sprintf(sh, stat[offen])+".\n";
+}
+
+oeffne(string str)
+{
+ object env;
+
+ notify_fail("WAS moechtest Du oeffnen?\n");
+
+ // bin ich gemeint?
+ if (!str || present(str, environment()) != this_object())
+ return 0;
+
+ if ((env=environment()) && env->id("sehe\rhaus")) {
+ if (!env->allowed_check(this_player())) {
+ write("Du darfst "+name(WEN)+" nicht oeffnen!\n" );
+ return 1;
+ }
+ }
+ return ::oeffne(str);
+}
+
+int MayAddWeight(int w)
+{
+ return 0;
+}
+
+static int
+schieben(string richtung)
+{
+ string *aus;
+ mapping exits;
+
+ if (!environment() || (!environment()->id("sehe\rhaus")) ||
+ !environment()->tp_owner_check())
+ return 0;
+
+ notify_fail( "Syntax: schiebe <truhe> nach <richtung>\n");
+
+ if (!richtung || richtung == "")
+ return 0;
+
+ aus = old_explode(richtung, " ");
+ richtung = aus[<1];
+ if (sizeof(aus) < 3 || !id(implode(aus[0..<3]," ")))
+ return 0;
+
+ if (member(aus = m_indices(exits = environment()->QueryProp(P_EXITS)),richtung)==-1)
+ write( "Du kannst "+name(WEN,1)+" nicht nach '"+richtung+"' schieben!\n");
+ else if (!exits[richtung]->tp_owner_check())
+ write( "Du kannst "+name(WEN,1)+" nicht aus Deinem Haus hinausschieben!\n");
+ else {
+ write( "Du schiebst "+name(WEN,1)+" in einen anderen Raum. Dann kehrst\n"
+ +"Du wieder zurueck.\n");
+ say(capitalize(this_player()->name(WER))+" schiebt "+name(WEN)+" in einen anderen\n"
+ +"Raum, kehrt aber selber wieder.\n");
+ environment()->Set(H_CHEST,0);
+ environment()->Save();
+ move(exits[richtung], M_NOCHECK);
+ environment()->Set(H_CHEST,1);
+ environment()->Save();
+ }
+ return 1;
+}
+
+private string *brk(string str)
+{
+ int i;
+ string *t1, *t2;
+
+ t1 = regexplode(str, ", *");
+ for (t2 = ({}), i=sizeof(t1)-1; i>=0; i-=2)
+ t2 = ({t1[i]}) + t2;
+
+ return t2;
+}
+
+static void getShort();
+
+static int beschreiben(string str)
+{
+ string *x;
+
+ if (!str || getuid(this_player()) != owner)
+ return 0;
+
+ x = old_explode(str, " ");
+
+ if (x[<1] == "status" && !id(implode(x[0..<2]," ")))
+ return 0;
+ else if (!id(str) && (str != "truhe"))
+ return 0;
+
+ write( "Beschreibung "+name(WESSEN,1)+"\n"
+ +"Wenn die Vorgaben nicht geaendert werden sollen, einfach weiter\n"
+ +"mit <RETURN>.\n\n");
+ getShort();
+ return 1;
+}
+
+static void getShort()
+{
+ write("Geschlecht (m, w, s): ["
+ +({ "s","m","w" })[QueryProp(P_GENDER)]+"]\n]" );
+ input_to("gotGender");
+}
+
+static void gotGender(string str)
+{
+ int gen;
+ mixed name;
+
+ if (!str || str == "")
+ write("Geschlecht nicht geaendert.\n");
+ else if ((gen = member(({'s','m','w'}),str[0])) == -1) {
+ write( "Bitte nur 'm', 'w' oder 's' eingeben!\nGeschlecht:\n]");
+ input_to("gotGender");
+ return;
+ }
+ else {
+ SetProp(P_GENDER, gen);
+ write( "Das Geschlecht ist jetzt "+QueryGenderString()+".\n");
+ }
+
+ name = QueryProp(P_NAME);
+ write("Nun musst Du den Namen eingeben. Sollte der Name unregelmaessig dekliniert\n"
+ +"werden, musst Du den Namen in allen vier Faellen in der Reihenfolge Nomi-\n"
+ +"nativ, Genitiv, Dativ, Akkusativ und durch Kommata getrennt eingeben.\n"
+ +"Name: ["+(pointerp(name) ? implode(name, ", ") : name)+ "]\n]");
+ input_to("gotName");
+}
+
+static void gotName(string str)
+{
+ string *n;
+
+ if (!str || member(({ "", ".", "**", "~q"}), str) >= 0)
+ write("Name wurde nicht geaendert.\n");
+ else {
+ n = brk(str);
+
+ if (sizeof(n) == 1)
+ SetProp(P_NAME, n[0]);
+ else {
+ if (sizeof(n) > 4)
+ n = n[0..3];
+ else
+ while (sizeof(n) != 4)
+ n = n + ({ n[0] });
+ SetProp(P_NAME,n);
+ }
+ printf("Der Name ist jetzt '%s'\n", implode(n, ", "));
+ }
+ write("Du kannst jetzt noch Namensadjektive angeben. Hier darfst Du nur den Wort-\n"
+ +"stamm angeben, da die Adjektive automatisch dekliniert werden (also fuer\n"
+ +"eine 'alte Truhe' muesstest Du 'alt' angeben).\n"
+ +"Du kannst auch mehrere Adjektive, durch Kommata getrennt, angeben.\n"
+ +"Um alle Namensadjektive zu loeschen, gib bitte 'nix' ein.\n"
+ +"Namensadjektive: ["+implode(QueryProp(P_NAME_ADJ),", ")+"]\n");
+ input_to("gotAdj");
+}
+
+static void gotAdj(string str)
+{
+ string *n;
+
+ if (!str || member(({ "", ".", "**", "~q"}), str) >= 0)
+ write("Adjektive nicht geaendert.\n");
+ else {
+ n = brk(str);
+
+ if (member(n, "nix") == -1) {
+ SetProp(P_NAME_ADJ, n);
+ printf("Namensadjektive lauten %s.\n", implode(n,", "));
+ }
+ else {
+ SetProp(P_NAME_ADJ, ({}) );
+ write("Namensadjektive geloescht.\n");
+ }
+ }
+ SetProp(P_SHORT, capitalize(name(WER)));
+ write( "Die Kurzbeschreibung lautet damit:\n"+short());
+ write( "Falls das Ergebnis nicht Deinen Vorstellungen entspricht, gelangst Du\n"
+ +"mit 'n' wieder in die Geschlechtsabfrage, ansonsten geht es in der\n"
+ +"Beschreibunssequenz weiter.\n"
+ +"Stimmt die Kurzbeschreibung so? (j/n)\n]");
+ input_to("gotKurz");
+}
+
+static void gotKurz(string str)
+{
+ string art, nam, *p;
+ int gen;
+
+ if (str && sizeof(str) && str[0] == 'n') {
+ write( "Neues Spiel, neues Glueck... ;)\n");
+ getShort();
+ return;
+ }
+ write("\nIDs (durch Kommata getrennt):\n["+implode(QueryProp(P_IDS)-({TRUHE}), ",")+"]\n]");
+ input_to("gotIDs");
+}
+
+static void gotIDs(string str)
+{
+ if (!str || member( ({ "", ".", "**", "~q" }), str) >= 0 )
+ write("IDs nicht geaendert.\n");
+ else {
+ str = implode(old_explode(lower_case(str)," ")-({""})," ");
+ str = implode(old_explode(str,", "),",");
+ SetProp(P_IDS, old_explode(str, ",")+({TRUHE}));
+ write("OK, IDs lauten '"+str+"'\n");
+ }
+ write("\nBitte Langbeschreibung eingeben (Abbruch mit ~q, Ende mit . oder **):\n");
+ nedit("gotLang");
+}
+
+static void gotMat(mapping mat);
+
+static void gotLang(string str)
+{
+ if (!str || str == "")
+ write("Die Langbeschreibung wurde nicht veraendert.\n");
+ else
+ SetProp(P_LONG,implode(old_explode(str, "@@"),"**"));
+
+ write("\nBitte das Material "+name(WESSEN,1)+" bestimmen:\n"
+ "(<RETURN> falls nichts geaendert werden soll)\n\n");
+
+ EditMaterial(QueryProp(P_MATERIAL), #'gotMat, 0, ({MATGROUP_GAS,MATGROUP_EXPLOSIVE}));
+}
+
+static void gotMat(mapping mat)
+{
+ if (mappingp(mat)) {
+ SetProp(P_MATERIAL, mat);
+ write("OK.\n");
+ }
+ else
+ write("Das Material wurde nicht veraendert.\n");
+
+ save_object(HAUSSAVEPATH+owner+"truhe");
+}
+
+static int aendern(string str)
+{
+ if (getuid(this_player())!=owner || !id(str))
+ return 0;
+
+ write("Bitte Langbeschreibung aendern.\n(Abbruch mit ~q, Ende mit . oder **, Hilfe mit ~h)\n");
+ nedit("gotLang", QueryProp(P_LONG));
+ return 1;
+}
+
+void Save()
+{
+ save_object(HAUSSAVEPATH+owner+"truhe");
+}
+
+int SmartLog(string ofile, string typ, string msg, string date)
+{
+ object home;
+ string foo, bar;
+
+ write_file(REPFILE(owner), sprintf("%s von %s an der Truhe (%s):\n%s\n",
+ typ,
+ capitalize(getuid(this_player())),
+ date,
+ break_string(msg,78)));
+
+ if (IS_LEARNER(owner)) {
+ log_file("report/"+owner+".rep",
+ sprintf("MELDUNG von %s im Seherhaus, an der Truhe (%s):\n"
+ +"Bitte zur Kenntnis nehmen! (Mit dem Befehl 'meldungen') -Wargon\n",
+ capitalize(getuid(this_player())),
+ date));
+ }
+
+ home = load_object(RAUMNAME(owner,0));
+ home->Set(H_REPORT, home->Query(H_REPORT)+1);
+ home->Save();
+
+ return 1;
+}
+
diff --git a/d/seher/haeuser/txt/kommentar.txt b/d/seher/haeuser/txt/kommentar.txt
new file mode 100644
index 0000000..53a4e09
--- /dev/null
+++ b/d/seher/haeuser/txt/kommentar.txt
@@ -0,0 +1,68 @@
+ Jof'sche Kurz-Kommentare
+
+ Kommentar zum Bausparvertrag fuer Seher
+
+bearbeitet von:
+
+Aufsichtsratsvorschwitzender Dr. fac. ju. Beldin
+Oberjurisdiktionsschrat Dr. hcl. Olim
+
+Zu Art. 1 (Gegenstand des Vertrages): Du zahlst Erfahrung ein
+und bekommst am Ende (vielleicht) Dein Haus dafuer. Die Erfah-
+rungspunkte sind auf jeden Fall erstmal weg.
+
+Zu Art. 2 (Parteien): Es gibt zwei Parteien, Dich und die Bank.
+Die Bank ist immer gleichberechtigter als Du.
+
+Zu Art. 3 (Wohnstaette): Ein Haus.
+
+Zu Art. 4 (Finanzierung):
+
+ Abs.1 (Kapitalvolumen) Insgesamt kostet das Haus 2544000 EP
+ (Option A) bzw. 2120000 EP (Option B).
+
+ Abs.2 (Ratenzahlung/Laufzeit) Du musst immer 80000 pro Rate
+ zahlen. Dabei hast Du zwei Moeglichkeiten:
+
+ A: 4 Stunden Zeit fuer jede Rate. Zeit auch fuer andere
+ Aktivitaeten im Mud ausser zu Metzeln. Als Strafe darfst Du
+ dafuer insgesamt etwas mehr loehnen als bei Option B.
+ B: 2 Stunden Zeit fuer jede Rate. Brutal, aber Du bist
+ schneller fertig mit dem Kram. Waehl, unterschreib, und die
+ Zeit laeuft bis alles eingezahlt ist.
+
+ Abs.3 (Zinsertrag) 6% Zinsen d.h. Du musst nicht den ganzen
+ Betrag (2544000 bzw. 2120000 EP), sondern nur einen Teil
+ (2400000 bzw. 2000000 EP) zahlen.
+
+ Abs.4 (Einzahlung) Die Erfahrung, die die Bank interessiert,
+ musst Du beim Metzeln und Questen aufbringen. Worauf Du den
+ Schwerpunkt legst, bleibt Dir ganz selbst ueberlassen. Es wird
+ waehrend des Kampfes automatisch ein Teil der Dir zustehenden
+ Erfahrung auf den BLOCK umgebucht. Diesen musst Du dazu aber
+ erst einmal anziehen. Vor dem Kampf. Du kannst natuerlich nur
+ soviel Erfahrung im Block speichern, wie Deine Rate zulaesst.
+
+ Abs.5 (Saeumniss) Es gibt zwei Moeglichkeiten bei der Bank
+ mehr Erfahrung zu lassen:
+ 1. Du ueberziehst eine Ratenfrist -> Eine Vertragsstrafe
+ i.H.v. 48000 EP (60%) ist innerhalb von 2 bzw. 1 Onlinestunde
+ beizubringen.
+ 2. Du ueberziehst auch die Strafe -> Deine gesamte bisher
+ eingezahlte Erfahrung ist VERLOREN.
+
+Zu Art. 5 (Unterschrift): Du musst den Vertrag unterschreiben
+(SYNTAX: unterschreibe vertrag).
+
+Zu Art. 6 (Erfuellung des Vertrages): Wenn Du alles eingezahlt
+hast bekommst Du Dein Haus.
+
+Zu Art. 7 (Ansprueche des Kunden): Du hast keine Ansprueche.
+Genau das steht auch in den AGB.
+
+Zu Anhang A: Du kannst das Haus in einem gewissen Rahmen
+veraendern.
+
+Zu Anhang B: Mumpitz! Keine Garantie fuer gar nichts (Die
+GfgWbmbH ist eine 100% Tochter der MorgenGrauen-Bank)!
+
diff --git a/d/seher/haeuser/txt/vertrag.txt b/d/seher/haeuser/txt/vertrag.txt
new file mode 100644
index 0000000..13bcd07
--- /dev/null
+++ b/d/seher/haeuser/txt/vertrag.txt
@@ -0,0 +1,139 @@
+ BAUSPARVERTRAG fuer SEHER
+ MorgenGrauen-Bank, 'Die Bank in Ihrem Ruecken'
+
+Art. 1 (Gegenstand des Vertrages): Gegenstand dieses Vertrages
+ist die verzinsliche Ansparung von Erfahrungswerten zum Zwecke
+der Errichtung einer geeigneten Wohnstaette fuer den
+unterzeichnenden Seher. Eine vorzeitige Auszahlung (d.h. vor
+Ablauf des Vertrages) ist nicht vorgesehen. Zur Wohnstaette s.u.
+Art. 3, zur Laufzeit s.u. Art. 4 Abs.2, zur Erfuellung des
+Vertrages s.u. Art. 6.
+
+Art. 2 (Parteien): Parteien dieses Vertrages sind die
+MorgenGrauen-Bank auf der einen Seite (im folgenden Bank genannt)
+und Sie, der unterzeichnende Seher auf der anderen Seite (im
+folgenden Seher genannt). Gemaess unserer Unternehmensphilosophie
+sind Bank und Seher bei diesem Rechtsgeschaeft gleichberechtigte
+Partner.
+
+Art. 3 (Wohnstaette): Als geeignete Wohnstaette i.S. dieses
+Vertrages gilt das MorgenGrauen-Seher-Einheitshaus (MIN-Norm
+15647), welches jedoch beschraenkt modifizierbar ist. Zu den
+moeglichen Modifikationen s.u. Anhang A. Zum Volumen und dem
+Zinsertrag des Bausparvertrages s.u. Art. 4 Abs.1 und Abs.3.
+
+Art. 4 (Finanzierung): Abs.1 (Kapitalvolumen) Das Volumen des
+Vertrages ist variabel. Es belaeuft sich bei Option A (s. Abs.2)
+auf 2544000, und bei Option B (s. Abs.2) auf 2120000 Morgen-
+Grauen-Erfahrungspunkte (EP). In diesen Betrag eingeschlossen
+sind sowohl Ihre zu leistenden Zahlungen als auch der erwirt-
+schaftete Zinsertrag.
+
+ Abs.2 (Ratenzahlung/Laufzeit) Die Bank bietet Ihnen zwei
+ unterschiedliche Moeglichkeiten der Finanzierung:
+ Option A: DER SANFTE WEG ZUM EIGENHEIM Bei einer Ratenhoehe
+ von 80000 EP innerhalb von jeweils 4 Online-Stunden und einer
+ Ratenanzahl von 30 betraegt die Gesamtlaufzeit des Vertrages
+ 120 Online-Stunden.
+ Option B: DER SCHNELLE WEG ZUM EIGENHEIM Bei einer Ratenhoehe
+ von 80000 EP innerhalb von jeweils 2 Online-Stunden und einer
+ Ratenanzahl von 25 betraegt die Gesamtlaufzeit des Vertrages
+ 50 Online-Stunden.
+ Die Laufzeit beginnt mit dem Inkrafttreten des Vertrages und
+ endet mit der Erstellung des gewuenschten Hauses. Bei Saeumniss
+ des Sehers sind die Bestimmungen des Art. 4 Abs.5 anzuwenden.
+ Der Vertrag wird mit der Unterschrift des jeweiligen Sehers
+ wirksam. Zu den Bestimmungen ueber die Unterschrift wird auf
+ Art. 5 verwiesen.
+
+ Abs.3 (Zinsertrag) Der Zinssatz belaeuft sich auf 6,00%. Die
+ Zinsen werden mit Einzahlung des letzten Erfahrungspunktes be-
+ rechnet. Hieraus ergibt sich ein Zinsertrag von genau 144000 EP
+ bei Option A und 120000 bei Option B.
+
+ Abs.4 (Einzahlung) Die Bank bietet Ihnen eine bisher nie
+ dagewesene finanzielle Flexibilitaet mit dem MG MASTER-BLOCK.
+ Auch bei unvorhergesehenen und spontanen Raubzuegen koennen Sie
+ sich jederzeit Erfahrungspunkte gutschreiben lassen. Sie tragen
+ nur Ihren Block wie ein uebliches Amulett und waehrend des
+ Kampfes oder auch beim Loesen einer Quest wird ihnen ein Teil
+ der Erfahrungspunkte gutgeschrieben (bis zur Ratenhoechst-
+ grenze). Bareinzahlung der Raten ist nicht moeglich.
+
+ Abs.5 (Saeumniss) Saeumniss i.S. dieses Vertrages besteht immer
+ dann, wenn der Unterzeichnende den in Art.3 Abs.2 genannten
+ Mindestratenzeitraum ueberschreitet. Dabei wird zunaechst eine
+ Vertragsstrafe in Hoehe von 60% der Rate faellig. Wird darauf
+ die Strafe nicht innerhalb von 2 Online-Stunden (bei Option A)
+ oder 1 Online-Stunde (bei Option B) waehrend der natuerlich
+ weiterlaufenden, normalen Ratenzahlungsfrist beglichen, gilt
+ der Vertrag ex nunc als hinfaellig. Bei Hinfaelligkeit des
+ Vertrags wird das bisher eingezahlte Kapital von der Bank
+ einbehalten.
+
+Art. 5 (Unterschrift): Als gueltige Unterschrift wird nur ein
+individuelles Zeichen auf dem dafuer vorgesehenen Platz am
+unteren, rechten Rand der letzten Seite dieses Vertrages
+zugelassen (MIN-Norm 32454). Zur Sicherung der Authentizitaet des
+Dokuments ist die Unterschrift weiterhin mit Herzblut zu leisten.
+Als Schreibutensil werden sowohl eine Feder als auch ein Skalpell
+von der Bank zur Verfuegung gestellt. Die Unterschrift kann nur
+in Anwesenheit eines autorisierten Angestellten unseres Hauses
+geleistet werden.
+
+Art. 6 (Erfuellung des Vertrages): Bei Erfuellung des Vertrages
+lt. den o.a. Art. wird dem Seher das Haus an der Ausgabestelle
+schluesselfertig ausgeliefert. Der Erhalt ist zu quittieren.
+
+Art. 7 (Ansprueche des Kunden) Fuer etwaige Schaeden am Leser
+dieses Vertrages uebernimmt die Bank keine Haftung, da sie
+ausschliesslich auf fehlerhaftes Lesen oder Missbrauch
+zurueckzufuehren sind. Ansonsten garantiert die Bank, dass sich
+der Vertrag im wesentlichen (und nicht etwa komplett) an die
+derzeitig gueltigen Regeln der deutschen Grammatik,
+Orthographie, und Stilistik (und nicht etwa an die Regeln des
+gesunden Menschenverstandes) haelt. Bezueglich aller unklaren
+Begriffe in den o.a. Art., welche sich auf bankinterne Ablaeufe
+beziehen, haben Sie das Recht, die in der Bank aushaengenden AGB
+zu lesen. Unsere freundlichen geschulten Mitarbeiter werden
+sicherlich gerne auf die wenigen noch offenen Fragen eingehen.
+In jedem Fall gilt das Recht einer von uns im Schadensfall zu
+benennenden Region.
+
+Wir danken Ihnen fuer das entgegengebrachte Vertrauen
+
+i.A.
+Aufsichtsratsvorschwitzender Dr. fac. ju. Beldin
+Oberjurisdiktionsschrat Dr. hcl. Olim
+
+
+
+ ------------------------------
+ (Unterschrift von ***********)
+
+
+Anhang A (Auszug aus den Beschluessen der MG-Normenkonferenz)
+"Modifikation:"
+[...]
+Das Haus wird in einheitlicher Groesse und Ausstattung
+angeliefert (MIN-Norm 15647). Moderne Werkstoffe wie z.B.
+drachenodemgebrannte Nabla-Schlamm-Ziegel gewaehrleisten sowohl
+kostenguenstige Produktion, als auch eine fast unbegrenzte
+Haltbarkeit. Alle Bauteile sind numeriert, um moegliche
+Modifikationen zu erleichtern. [...]
+Dem Besitzer ist es erlaubt sowohl an der Fassade wie auch im
+Inneren gewisse, individuelle Merkmale einzubringen.
+
+Anhang B (Lieferbestimmung der Gesellschaft fuer gemeinnuetzigen
+ Wohnungsbau m.b.H.)
+[...]
+IV. Garantie
+Die GfgWbmbH uebernimmt keine Garantie fuer das uneingeschraenkte
+Funktionieren des Morgengrauen-Seher-Einheitshauses (MIN-Norm
+15647) bei der Auslieferung. Fehler im, sowie am Haus sind nach
+dem derzeitigen Stand der Bautechnik unvermeidlich und fuehren
+nicht zu Ersatzanspruechen. Fuer etwaige Schaeden am
+MorgenGrauen-Seher-Einheitshaus (MIN-Norm 15647) nach dessen
+Auslieferung uebernimmt die GfgWbmbH keine Haftung, da sie
+ausschliesslich auf fehlerhaftes Bewohnen oder Missbrauch
+zurueckzufuehren sind.
diff --git a/d/seher/haeuser/txt/vertrag_raum.txt b/d/seher/haeuser/txt/vertrag_raum.txt
new file mode 100644
index 0000000..5393f38
--- /dev/null
+++ b/d/seher/haeuser/txt/vertrag_raum.txt
@@ -0,0 +1,142 @@
+ BAUSPARVERTRAG fuer SEHER
+ -- AUSBAUVERTRAG --
+ MorgenGrauen-Bank, 'Die Bank in Ihrem Ruecken'
+
+Art. 1 (Gegenstand des Vertrages): Gegenstand dieses Vertrages
+ist die verzinsliche Ansparung von Erfahrungswerten zum Zwecke
+des Ausbaues der Wohnstaette des unterzeichnenden Sehers. Eine
+vorzeitige Auszahlung (d.h. vor Ablauf des Vertrages) ist nicht
+vorgesehen. Zum Ausbau der Wohnstaette s.u.Art. 3, zur Laufzeit
+s.u. Art. 4 Abs.2, zur Erfuellung des Vertrages s.u. Art. 6.
+
+Art. 2 (Parteien): Parteien dieses Vertrages sind die
+MorgenGrauen-Bank auf der einen Seite (im folgenden Bank genannt)
+und Sie, der unterzeichnende Seher auf der anderen Seite (im
+folgenden Seher genannt). Gemaess unserer Unternehmensphilosophie
+sind Bank und Seher bei diesem Rechtsgeschaeft gleichberechtigte
+Partner.
+
+Art. 3 (Ausbau der Wohnstaette): Als Ausbau der Wohnstaette i.S.
+dieses Vertrages gilt der MorgenGrauen-Seher-Einheitsraum
+(MIN-Norm 15648), welcher jedoch beschraenkt modifizierbar ist.
+Zu den moeglichen Modifikationen s.u. Anhang A. Zum Volumen und
+dem Zinsertrag des Bausparvertrages s.u. Art. 4 Abs.1 und Abs.3.
+
+Art. 4 (Finanzierung): Abs.1 (Kapitalvolumen) Das Volumen des
+Vertrages ist variabel. Es belaeuft sich bei Option A (s. Abs.2)
+auf 1017600, und bei Option B (s.Abs.2) auf 848000 MorgenGrauen-
+Erfahrungspunkte (EP). In diesen Betrag eingeschlossen sind
+sowohl Ihre zu leistenden Zahlungen als auch der erwirtschaftete
+Zinsertrag.
+
+ Abs.2 (Ratenzahlung/Laufzeit) Die Bank bietet Ihnen zwei
+ unterschiedliche Moeglichkeiten der Finanzierung:
+ Option A: DER SANFTE WEG ZUM AUSBAU Bei einer Ratenhoehe
+ von 80000 EP innerhalb von jeweils 4 Online-Stunden und einer
+ Ratenanzahl von 12 betraegt die Gesamtlaufzeit des Vertrages
+ 48 Online-Stunden.
+ Option B: DER SCHNELLE WEG ZUM AUSBAU Bei einer Ratenhoehe
+ von 80000 EP innerhalb von jeweils 2 Online-Stunden und einer
+ Ratenanzahl von 10 betraegt die Gesamtlaufzeit des Vertrages
+ 20 Online-Stunden.
+ Die Laufzeit beginnt mit dem Inkrafttreten des Vertrages und
+ endet mit dem Einbau des Ausbaus. Bei Saumnis des Sehers sind
+ sind die Bestimmungen des Art. 4 Abs.5 anzuwenden.
+ Der Vertrag wird mit der Unterschrift des jeweiligen Sehers
+ wirksam. Zu den Bestimmungen ueber die Unterschrift wird auf
+ Art. 5 verwiesen.
+
+ Abs.3 (Zinsertrag) Der Zinssatz belaeuft sich auf 6,00%. Die
+ Zinsen werden mit Einzahlung des letzten Erfahrungspunktes be-
+ rechnet. Hieraus ergibt sich ein Zinsertrag von genau 57600 EP
+ bei Option A und 48000 bei Option B.
+
+ Abs.4 (Einzahlung) Die Bank bietet Ihnen eine bisher nie
+ dagewesene finanzielle Flexibilitaet mit dem MG MASTER-BLOCK.
+ Auch bei unvorhergesehenen und spontanen Raubzuegen koennen Sie
+ sich jederzeit Erfahrungspunkte gutschreiben lassen. Sie tragen
+ nur Ihren Block wie ein uebliches Amulett und waehrend des
+ Kampfes oder auch beim Loesen einer Quest wird ihnen ein Teil
+ der Erfahrungspunkte gutgeschrieben (bis zur Ratenhoechst-
+ grenze). Bareinzahlung der Raten ist nicht moeglich.
+
+ Abs.5 (Saeumniss) Saeumniss i.S. dieses Vertrages besteht immer
+ dann, wenn der Unterzeichnende den in Art.3 Abs.2 genannten
+ Mindestratenzeitraum ueberschreitet. Dabei wird zunaechst eine
+ Vertragsstrafe in Hoehe von 60% der Rate faellig. Wird darauf
+ die Strafe nicht innerhalb von 2 Online-Stunden (bei Option A)
+ oder 1 Online-Stunde (bei Option B) waehrend der natuerlich
+ weiterlaufenden, normalen Ratenzahlungsfrist beglichen, gilt
+ der Vertrag ex nunc als hinfaellig. Bei Hinfaelligkeit des
+ Vertrags wird das bisher eingezahlte Kapital von der Bank
+ einbehalten.
+
+Art. 5 (Unterschrift): Als gueltige Unterschrift wird nur ein
+individuelles Zeichen auf dem dafuer vorgesehenen Platz am
+unteren, rechten Rand der letzten Seite dieses Vertrages
+zugelassen (MIN-Norm 32454). Zur Sicherung der Authentizitaet des
+Dokuments ist die Unterschrift weiterhin mit Herzblut zu leisten.
+Als Schreibutensil werden sowohl eine Feder als auch ein Skalpell
+von der Bank zur Verfuegung gestellt. Die Unterschrift kann nur
+in Anwesenheit eines autorisierten Angestellten unseres Hauses
+geleistet werden.
+
+Art. 6 (Erfuellung des Vertrages): Bei Erfuellung des Vertrages
+lt. den o.a. Art. wird bei Vorlage des Vertrages an der dafuer
+eingerichteten Stelle der Ausbau der Heimstatt des Sehers durch
+unseren Ausbauservice nach MIN-Norm 20815 unverzueglich
+vorgenommen. Dem Seher entstehen hierdurch keine weiteren
+Verpflichtungen.
+
+Art. 7 (Ansprueche des Kunden) Fuer etwaige Schaeden am Leser
+dieses Vertrages uebernimmt die Bank keine Haftung, da sie
+ausschliesslich auf fehlerhaftes Lesen oder Missbrauch
+zurueckzufuehren sind. Ansonsten garantiert die Bank, dass sich
+der Vertrag im wesentlichen (und nicht etwa komplett) an die
+derzeitig gueltigen Regeln der deutschen Grammatik,
+Orthographie, und Stilistik (und nicht etwa an die Regeln des
+gesunden Menschenverstandes) haelt. Bezueglich aller unklaren
+Begriffe in den o.a. Art., welche sich auf bankinterne Ablaeufe
+beziehen, haben Sie das Recht, die in der Bank aushaengenden AGB
+zu lesen. Unsere freundlichen geschulten Mitarbeiter werden
+sicherlich gerne auf die wenigen noch offenen Fragen eingehen.
+In jedem Fall gilt das Recht einer von uns im Schadensfall zu
+benennenden Region.
+
+Wir danken Ihnen fuer das entgegengebrachte Vertrauen
+
+i.A.
+Aufsichtsratsvorschwitzender Dr. fac. ju. Beldin
+Oberjurisdiktionsschrat Dr. hcl. Olim
+
+
+
+ ------------------------------
+ (Unterschrift von ***********)
+
+
+Anhang A (Auszug aus den Beschluessen der MG-Normenkonferenz)
+"Modifikation:"
+[...]
+Der Ausbau wird in einheitlicher Groesse und Ausstattung
+angeliefert (MIN-Norm 15648). Der Einbau des Ausbaus ist
+jedoch nur und ausschliesslich gestattet in einem
+MorgenGrauen-Seher-Einheitshaus (MIN-Norm 15648). Um etwaigem
+Missbrauch vorzubeugen, hat der Einbau des Ausbaus nur durch
+geschultes Fachpersonal zu erfolgen. [...]
+Dem Besitzer ist es erlaubt im Inneren gewisse, individuelle
+Merkmale einzubringen.
+
+Anhang B (Lieferbestimmung der Gesellschaft fuer gemeinnuetzigen
+ Wohnungsbau m.b.H.)
+[...]
+IV. Garantie
+Die GfgWbmbH uebernimmt keine Garantie fuer das uneingeschraenkte
+Funktionieren des Morgengrauen-Seher-Einheitsraumes (MIN-Norm
+15648) bei der Auslieferung. Fehler im, sowie am Raum sind nach
+dem derzeitigen Stand der Bautechnik unvermeidlich und fuehren
+nicht zu Ersatzanspruechen. Fuer etwaige Schaeden am
+MorgenGrauen-Seher-Einheitsraum (MIN-Norm 15648) nach dessen
+Einbau uebernimmt die GfgWbmbH keine Haftung, da sie
+ausschliesslich auf fehlerhaftes Bewohnen oder Missbrauch
+zurueckzufuehren sind.
diff --git a/d/seher/haeuser/virtual_compiler.c b/d/seher/haeuser/virtual_compiler.c
new file mode 100644
index 0000000..d5d1ab8
--- /dev/null
+++ b/d/seher/haeuser/virtual_compiler.c
@@ -0,0 +1,164 @@
+/** Letzte Aenderung:
+// 01.04.2008 - Objekte des VC werden jetzt im memory gespeichert
+// - Kleinere Aenderungen im Code.
+// 01.01.2007 - Grundlegende Ueberarbeitung, Vanion
+// - Verwaltung der Objekte in einer Liste
+// Dadurch kann ls die VC-Objekte darstellen
+// - Genauere Ueberpruefung der Dateinamen auf
+// Korrektheit. Falls ein illegaler Zugriff
+// stattfindet, wirds geloggt.
+//
+*/
+
+#pragma strict_types
+#pragma no_clone
+#pragma no_shadow
+#pragma no_inherit
+#pragma verbose_errors
+#pragma combine_strings
+#pragma pedantic
+#pragma warn_deprecated
+
+#include "haus.h"
+#include <thing/properties.h>
+#include <wizlevels.h>
+
+#define MEMORY "/secure/memory"
+
+private nosave mapping objects;
+private nosave int show_clone_list;
+
+/**
+ Initialisierung
+*/
+void create()
+{
+ seteuid(getuid());
+
+ // Zeiger auf Cloneliste holen
+ if (call_other(MEMORY,"HaveRights")) {
+ // Objektpointer laden
+ objects = (mixed) call_other(MEMORY,"Load","objects");
+
+ // Hats geklappt?
+ if (!mappingp(objects))
+ // vermutlich noch nicht initialisiert.
+ // Zeiger erzeugen
+ objects = ([]);
+ call_other(MEMORY,"Save","objects",objects); // Und in den Memory schreiben
+ } else {
+ // Wenn ich keinen Zeiger habe, muss ich halt einen lokalen nehmen.
+
+ objects = ([]);
+ }
+
+ show_clone_list = 0;
+}
+
+/**
+ Die Funktion wird vom GameDriver aufgerufen. Wenn die Namen-
+ konventionen passen, erzeugt compile_object ein passendes Objekt
+ und gibt es zurueck
+ \param name Name des zu ladenden Objekts
+ \return Das geladene und initialisierte Objekt
+*/
+object compile_object(string name)
+{
+ object ob;
+
+ if (name[<6..<3] == "haus" )
+ {
+ ob = (object) (VERWALTER)->_LadeHaus(name[0..<7]);
+ }
+ else if (name[<7..<4] == "raum" )
+ {
+ ob = (object) (VERWALTER)->_LadeRaum(name[0..<8], to_int(name[<3..<3]));
+ }
+ else
+ {
+ log_file("seher/haeuser/vc_load_error",
+ dtime(time())+"\n Falscher Objektname: "+name+"\n"+
+ " PO: "+object_name(previous_object(1))+",\n"+
+ " PPO: "+object_name(previous_object(2))+",\n"+
+ " TI: "+object_name(this_interactive())+".\n\n");
+ return 0;
+ }
+
+ // Objekt speichern (fuer ls)
+ if (objectp(ob)) objects[name] = ob;
+
+ return ob;
+}
+
+/**
+ Soll die Liste der Objekte zum VC per QueryObjects ausgegeben werden oder nicht?
+*/
+
+int ToggleCloneList()
+{
+ show_clone_list ^= 1;
+ tell_object(this_player(), "Die Clone List wird nun "+
+ (show_clone_list?"":"nicht mehr ")+"angezeigt.\n");
+}
+
+/**
+ return all cloned virtual objects, wird zum Beispiel fuer "ls" benutzt.
+*/
+mixed QueryObjects()
+{
+ if (show_clone_list)
+ return m_values(objects)-({0});
+ else
+ return ({});
+}
+
+/**
+ Nur EM und Maintainer duerfen die sicheren Funktionen nutzen
+*/
+int secure()
+{
+ if (ARCH_SECURITY || IS_MAINTAINER(this_interactive()))
+ return 1;
+ else
+ return 0;
+}
+
+/*
+/**
+ Die Funktion versucht, die Clones dieses VCs aus der Objekt List
+ zu regenerieren
+*/
+/*
+int regenerate_clone_list()
+{
+ if (sizeof(objects)==0)
+ HDEBUG("Tbd: regenerate_clone_list im vc");
+
+ return 1;
+}
+*/
+
+/**
+ Die Funktion zerstoert alle bereits geclonten Seherhausobjekte
+ Das gibt wirklich nur irre wenige Momente, wo das nicht schlecht ist.
+*/
+int desctruct_all_my_clones()
+{
+ mixed ob;
+
+ if (!secure()) return 0;
+
+ if(!mappingp(objects)) return 0;
+
+ for(ob = QueryObjects(); sizeof(ob); ob = ob[1..])
+ {
+ if(objectp(ob[0]))
+ {
+ ob[0]->remove();
+ if(objectp(ob[0])) destruct(ob[0]);
+ }
+ }
+
+ return 1;
+}
+