Added public files
Roughly added all public files. Probably missed some, though.
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");
+ }
+}