Added public files
Roughly added all public files. Probably missed some, though.
diff --git a/items/kraeuter/virtual_compiler.c b/items/kraeuter/virtual_compiler.c
new file mode 100644
index 0000000..d48370e
--- /dev/null
+++ b/items/kraeuter/virtual_compiler.c
@@ -0,0 +1,300 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#pragma no_inherit,no_clone,strong_types,rtt_checks
+
+#include <defines.h>
+#include <properties.h>
+#include <v_compiler.h>
+#include <items/kraeuter/kraeuter.h>
+#include <wizlevels.h>
+
+inherit "/std/virtual/v_compiler";
+inherit "/std/thing/language";
+inherit "/std/thing/description";
+
+// mit Hilfe dieses mappings kommt man sowohl an die ID und die Eigenschaften,
+// als auch an die Liste der Raeume in denen das Kraut mit dem filenamen room
+// gefunden werden kann.
+// ([ "key": ({ ({eigenschaften}), ([raeume]) }) ])
+private mapping krautdaten;
+
+// AN: enthaelt die Liste der gueltigen Kraeuter-Dateinamen ohne .c
+// am Ende. Ich vermute, dass es deswegen ein Mapping ist, damit in
+// Validate() einfach member() drauf gemacht werden kann und man nur 0/1
+// als Rueckgabewerte pruefen muss, statt -1 bei nem member() auf ein Array.
+private mapping validfiles;
+
+public void update(mapping data)
+{
+ if (previous_object() == find_object(PLANTMASTER))
+ {
+ krautdaten = data;
+ validfiles = mkmapping(m_indices(krautdaten));
+ }
+}
+
+// Wird benutzt, um kurze IDs von Kraeutern zu raten. Diese IDs werden
+// eingetragen, wenn der Krautname die ID als Teilstring enthaelt.
+#define IDLIST ({ "klee", "rebe", "hahnenfuss", "rettich", "kraut", "wurz",\
+ "moos", "enzian", "rautenwicke", "pilz", "nelke",\
+ "lichtnelke", "wicke", "zwiebel", "hanf", "kresse"})
+
+void create()
+{
+ seteuid(getuid());
+
+ v_compiler::create();
+ description::create();
+
+ SetProp(P_COMPILER_PATH, __DIR__);
+ SetProp(P_STD_OBJECT, PLANTITEM);
+
+ PLANTMASTER->UpdateVC();
+}
+
+string Validate(string file)
+{
+ if (!stringp(file)) return 0;
+ file = ::Validate(explode(file, "#")[0]);
+#if MUDNAME == "MorgenGrauen"
+ return (member(validfiles, file) ? file : 0);
+#else
+ return file;
+#endif
+}
+
+private nosave object simul_efun;
+
+// fuer SIMUL_EFUN_FILE
+#include <config.h>
+
+// AN: Funktion liefert das clonende Objekt als dessen Blueprint-Namen,
+// indem es den Caller-Stack durchlaeuft und nach einem Objekt sucht,
+// das weder der Master, noch ein Simul-Efun-Objekt, noch dieser VC selbst
+// ist. Der Name des gefundenen Objekts wird zurueckgegeben, oder 0.
+nomask private string get_cloner()
+{
+ int i;
+ object po;
+
+ if (!simul_efun)
+ {
+ if (!(simul_efun=find_object(SIMUL_EFUN_FILE)))
+ simul_efun=find_object(SPARE_SIMUL_EFUN_FILE);
+ }
+ // wenn sie jetzt nicht existiert - auch gut, dann gibt es halt keine
+ // sefuns.
+
+ for (i=0; po=previous_object(i); i++)
+ {
+ if (po==master() || po==simul_efun || po==ME || po==previous_object())
+ continue;
+ return BLUE_NAME(po);
+ }
+ return 0;
+}
+
+// Konfiguriert das erzeugte Objekt entsprechend der dafuer im Kraeutermaster
+// bekannten Daten. Vergibt auf die Plant-ID.
+varargs string CustomizeObject(string file)
+{
+ if (previous_object()->QueryPlantId()) return 0; // bereits initialisiert
+
+ if (stringp(file))
+ file=Validate(file);
+ else file=::CustomizeObject();
+ if (!file) return 0;
+
+ closure sp=symbol_function("SetProp", previous_object());
+ mixed arr=krautdaten[file];
+ if (pointerp(arr))
+ {
+ // Welches Objekt clont das File?
+ string cloner = get_cloner();
+ string rooms = arr[1];
+ mixed props = arr[0];
+ // Wird das Kraut legal von einem eingetragenen Cloner erzeugt? Nur dann
+ // bekommt es eine gueltige Plant-ID.
+ int legal=member(rooms, get_cloner()) || cloner==PLANTMASTER;
+ if (!legal && this_interactive() && IS_ARCH(this_interactive()))
+ legal=1;
+
+ // Konfiguriert wird das Objekt dann, wenn es per VC erzeugt wird oder
+ // ein Clone einer per VC erzeugten BP ist - d.h. wenn es nicht aus
+ // einem real existierenden File auf der Platte existiert. Das ist dann
+ // der Fall, wenn der Loadname gleich dem Standardplantobjekt des VC
+ // ist.
+ if (load_name(previous_object())==PLANTITEM)
+ {
+ if ((props[INGREDIENT_NAME]=="Klee") ||
+ (props[INGREDIENT_NAME][<4..]=="klee")) {
+ funcall(sp, P_NAME, ({ props[INGREDIENT_NAME],
+ props[INGREDIENT_NAME]+"s",
+ props[INGREDIENT_NAME],
+ props[INGREDIENT_NAME]}));
+ }
+ else funcall(sp, P_NAME, props[INGREDIENT_NAME]);
+ funcall(sp, P_NAME_ADJ, props[INGREDIENT_ADJ]);
+ funcall(sp, P_GENDER, props[INGREDIENT_GENDER]);
+ funcall(sp, P_LONG, props[INGREDIENT_LONG]);
+ funcall(sp, PLANT_ROOMDETAIL, props[INGREDIENT_ROOMDETAIL]);
+ if (props[INGREDIENT_DEMON]==RAW) {
+ funcall(sp, P_ARTICLE, 0);
+ funcall(sp, P_SHORT, previous_object()->Name(WER));
+ funcall(sp, P_ARTICLE, 1);
+ }
+ else funcall(sp, P_SHORT,
+ previous_object()->Name(WER,props[INGREDIENT_DEMON]));
+ previous_object()->AddId(lowerstring(props[INGREDIENT_NAME]));
+ // bei zusammengesetzten Namen, auch den hauptnamen akzeptieren
+ string str=lowerstring(props[INGREDIENT_NAME]);
+ string *names=explode(str, "-");
+ if (sizeof(names)>1) previous_object()->AddId(names[<1]);
+ names=explode(str, " ");
+ if (sizeof(names)>1) previous_object()->AddId(names[<1]);
+ foreach(string id: IDLIST)
+ {
+ if (strstr(str, id)==-1) continue;
+ previous_object()->AddId(id);
+ break;
+ }
+ // Adjective vorher deklinieren
+ str=props[INGREDIENT_ADJ];
+ if (stringp(str))
+ {
+ str=DeclAdj(lowerstring(str), WEN, 0);
+ previous_object()->AddAdjective(str);
+ }
+ } // Ende Konfiguration eines VC-erzeugten Objekts
+ // Plant-ID wird fuer alle Objekte auf irgendwas gesetzt.
+ previous_object()->SetPlantId(legal ? props[INGREDIENT_ID] : -1);
+ }
+ // Keine Krautdaten bekannt...
+ else
+ {
+ funcall(sp, P_NAME, "Kraut");
+ funcall(sp, P_GENDER, NEUTER);
+ funcall(sp, P_SHORT, "Ein Testkraut ("+capitalize(file)+")");
+ funcall(sp, P_LONG, "Ein nicht naeher spezifiziertes Testkraut.\n");
+ funcall(sp, PLANT_ROOMDETAIL,
+ "Ein nicht naeher spezifiziertes Testkraut ("
+ +capitalize(file)+").\n");
+ previous_object()->AddId("kraut");
+ previous_object()->SetPlantId(-1);
+ }
+ return file;
+}
+
+int NoParaObjects()
+{ return 1; }
+
+// AN: Funktion erzeugt aus den vorliegenden Daten der Kraeuterliste ein
+// physikalisch existierendes File in diesem Verzeichnis, zB wenn die Daten
+// erweitert werden sollen. Die Kraeuterliste stellt nur generische Objekte
+// zur Verfuegung, die keine Details haben. Wenn die Objekte ausgeschmueckt
+// werden sollen, koennen diese auch als Datei hier liegen.
+// Wird vom Plantmaster aus gerufen. Die Existenz von Klartext-
+// Fehlermeldungen laesst darauf schliessen, dass diese Funktion dafuer
+// vorgesehen war, vom Planttool aus gerufen zu werden. Dies wird dadurch
+// bestaetigt, dass dort wie hier alle von Magiern benutzbaren Kommando-
+// funktionen mit _ beginnen (_showplant(), _addroom() etc.), und die
+// Kommandofunktion im Planttool generell in der Lage ist, alle _*()
+// im Plantmaster zu rufen, sofern existent und fuer den Magier freigegeben.
+// AN/TODO: ggf. sollte man hier noch pruefen, ob die VC-Blueprint des
+// angeforderten Krautes gerade existiert, denn sonst wuerde das auf der
+// Platte liegende, scheinbar (nicht) geladene Objekt nicht mit dem
+// VC-Objekt uebereinstimmen. Evtl. reicht es aus, die Blueprint einfach
+// zu zerstoeren und neuzuladen.
+int _createfile(string filename)
+{
+ int i;
+ string str, short, long, gender, *name, roomdetail;
+ string *ids;
+ string plantfile;
+
+/* if (object_name(previous_object())!=PLANTMASTER) {
+ write("Illegal usage of _createfile()!\n");
+ return 1;
+ }*/
+// ^^^ Zook, ggf.spaeter wieder Kommentar entfernen.
+
+ mixed arr;
+ if (!pointerp(arr=krautdaten[filename])) {
+ write("Unknown plant '"+filename+"'.\n");
+ return 1;
+ }
+ if (file_size(PLANTDIR+filename+".c")>=0) {
+ write("error: file "+PLANTDIR+filename+".c already exists.\n");
+ return 1;
+ }
+ mixed props = arr[0];
+
+ // Kurzbeschreibung erzeugen
+ SetProp(P_NAME, props[INGREDIENT_NAME]);
+ SetProp(P_NAME_ADJ, props[INGREDIENT_ADJ]);
+ SetProp(P_GENDER, props[INGREDIENT_GENDER]);
+ if (props[INGREDIENT_DEMON]==RAW) {
+ SetProp(P_ARTICLE, 0);
+ short=Name(WER);
+ SetProp(P_ARTICLE, 1);
+ }
+ else short=Name(WER,props[INGREDIENT_DEMON]);
+ ids = ({ lowerstring(props[INGREDIENT_NAME]) });
+ // bei zusammengesetzten Namen, auch den hauptnamen akzeptieren
+ str=lowerstring(props[INGREDIENT_NAME]);
+ name=explode(str, "-");
+ if (sizeof(name)>1) ids += ({ name[<1] });
+ name=explode(str, " ");
+ if (sizeof(name)>1) ids += ({ name[<1] });
+ for (i=sizeof(IDLIST)-1; i>=0; i--) {
+ if (strstr(str, IDLIST[i], 0)==-1) continue;
+ ids += ({ IDLIST[i] });
+ break;
+ }
+ switch(props[INGREDIENT_GENDER]) {
+ case MALE: gender="MALE"; break;
+ case FEMALE: gender="FEMALE"; break;
+ case NEUTER: gender="NEUTER"; break;
+ default: gender=props[INGREDIENT_GENDER];
+ }
+ long=" \""+implode(old_explode(props[INGREDIENT_LONG], "\n"),
+ "\\n\"\n +\"")+"\\n\"";
+ roomdetail=" \""+implode(
+ old_explode(props[INGREDIENT_ROOMDETAIL], "\n"), "\\n\"\n +\"")+
+ "\\n\"";
+ plantfile=
+ "#pragma strong_types,rtt_checks\n\n"
+ "#include <properties.h>\n"
+ "#include <items/kraeuter/kraueter.h>\n"
+ "#include <items/kraeuter/kraeuterliste.h>\n\n"
+ "inherit STDPLANT;\n\n"
+ "protected void create()\n"
+ "{\n"
+ " ::create();\n";
+ plantfile+=" customizeMe("+upperstring(filename)+");\n";
+ plantfile+=
+ " SetProp(P_NAME, \""+props[INGREDIENT_NAME]+"\");\n"
+ " SetProp(P_NAME_ADJ, \""+(props[INGREDIENT_ADJ]||"")+"\");\n"
+ " SetProp(P_GENDER, "+gender+");\n"
+ " SetProp(P_LONG, \n"+
+ long+");\n"
+ " SetProp(PLANT_ROOMDETAIL, \n"+
+ roomdetail+");\n"
+ " SetProp(P_SHORT, \""+short+"\");\n";
+ plantfile+=" AddId(({";
+ for (i=sizeof(ids)-1; i>=0; i--)
+ plantfile+=" \""+ids[i]+"\",";
+ plantfile[<1]=' ';
+ plantfile+="}));\n";
+ // Adjective vorher deklinieren
+ if (stringp(short=props[INGREDIENT_ADJ])) {
+ short=DeclAdj(lowerstring(short), WEN, 0)[0..<2];
+ plantfile+=" AddAdjective(\""+short+"\");\n";
+ }
+ plantfile+="}\n";
+ write(plantfile);
+ //write_file(PLANTDIR+filename+".c", plantfile);
+ write("Filename: "+PLANTDIR+filename+".c\n");
+ return 1;
+}
+