blob: d48370ed8aab7b1bdeb5052e26888929f49a9e24 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// (c) by Padreic (Padreic@mg.mud.de)
2
3#pragma no_inherit,no_clone,strong_types,rtt_checks
4
5#include <defines.h>
6#include <properties.h>
7#include <v_compiler.h>
8#include <items/kraeuter/kraeuter.h>
9#include <wizlevels.h>
10
11inherit "/std/virtual/v_compiler";
12inherit "/std/thing/language";
13inherit "/std/thing/description";
14
15// mit Hilfe dieses mappings kommt man sowohl an die ID und die Eigenschaften,
16// als auch an die Liste der Raeume in denen das Kraut mit dem filenamen room
17// gefunden werden kann.
18// ([ "key": ({ ({eigenschaften}), ([raeume]) }) ])
19private mapping krautdaten;
20
21// AN: enthaelt die Liste der gueltigen Kraeuter-Dateinamen ohne .c
22// am Ende. Ich vermute, dass es deswegen ein Mapping ist, damit in
23// Validate() einfach member() drauf gemacht werden kann und man nur 0/1
24// als Rueckgabewerte pruefen muss, statt -1 bei nem member() auf ein Array.
25private mapping validfiles;
26
27public void update(mapping data)
28{
29 if (previous_object() == find_object(PLANTMASTER))
30 {
31 krautdaten = data;
32 validfiles = mkmapping(m_indices(krautdaten));
33 }
34}
35
36// Wird benutzt, um kurze IDs von Kraeutern zu raten. Diese IDs werden
37// eingetragen, wenn der Krautname die ID als Teilstring enthaelt.
38#define IDLIST ({ "klee", "rebe", "hahnenfuss", "rettich", "kraut", "wurz",\
39 "moos", "enzian", "rautenwicke", "pilz", "nelke",\
40 "lichtnelke", "wicke", "zwiebel", "hanf", "kresse"})
41
42void create()
43{
44 seteuid(getuid());
45
46 v_compiler::create();
47 description::create();
48
49 SetProp(P_COMPILER_PATH, __DIR__);
50 SetProp(P_STD_OBJECT, PLANTITEM);
51
52 PLANTMASTER->UpdateVC();
53}
54
55string Validate(string file)
56{
57 if (!stringp(file)) return 0;
58 file = ::Validate(explode(file, "#")[0]);
59#if MUDNAME == "MorgenGrauen"
60 return (member(validfiles, file) ? file : 0);
61#else
62 return file;
63#endif
64}
65
66private nosave object simul_efun;
67
68// fuer SIMUL_EFUN_FILE
69#include <config.h>
70
71// AN: Funktion liefert das clonende Objekt als dessen Blueprint-Namen,
72// indem es den Caller-Stack durchlaeuft und nach einem Objekt sucht,
73// das weder der Master, noch ein Simul-Efun-Objekt, noch dieser VC selbst
74// ist. Der Name des gefundenen Objekts wird zurueckgegeben, oder 0.
75nomask private string get_cloner()
76{
77 int i;
78 object po;
79
80 if (!simul_efun)
81 {
82 if (!(simul_efun=find_object(SIMUL_EFUN_FILE)))
83 simul_efun=find_object(SPARE_SIMUL_EFUN_FILE);
84 }
85 // wenn sie jetzt nicht existiert - auch gut, dann gibt es halt keine
86 // sefuns.
87
88 for (i=0; po=previous_object(i); i++)
89 {
90 if (po==master() || po==simul_efun || po==ME || po==previous_object())
91 continue;
92 return BLUE_NAME(po);
93 }
94 return 0;
95}
96
97// Konfiguriert das erzeugte Objekt entsprechend der dafuer im Kraeutermaster
98// bekannten Daten. Vergibt auf die Plant-ID.
99varargs string CustomizeObject(string file)
100{
101 if (previous_object()->QueryPlantId()) return 0; // bereits initialisiert
102
103 if (stringp(file))
104 file=Validate(file);
105 else file=::CustomizeObject();
106 if (!file) return 0;
107
108 closure sp=symbol_function("SetProp", previous_object());
109 mixed arr=krautdaten[file];
110 if (pointerp(arr))
111 {
112 // Welches Objekt clont das File?
113 string cloner = get_cloner();
114 string rooms = arr[1];
115 mixed props = arr[0];
116 // Wird das Kraut legal von einem eingetragenen Cloner erzeugt? Nur dann
117 // bekommt es eine gueltige Plant-ID.
118 int legal=member(rooms, get_cloner()) || cloner==PLANTMASTER;
119 if (!legal && this_interactive() && IS_ARCH(this_interactive()))
120 legal=1;
121
122 // Konfiguriert wird das Objekt dann, wenn es per VC erzeugt wird oder
123 // ein Clone einer per VC erzeugten BP ist - d.h. wenn es nicht aus
124 // einem real existierenden File auf der Platte existiert. Das ist dann
125 // der Fall, wenn der Loadname gleich dem Standardplantobjekt des VC
126 // ist.
127 if (load_name(previous_object())==PLANTITEM)
128 {
129 if ((props[INGREDIENT_NAME]=="Klee") ||
130 (props[INGREDIENT_NAME][<4..]=="klee")) {
131 funcall(sp, P_NAME, ({ props[INGREDIENT_NAME],
132 props[INGREDIENT_NAME]+"s",
133 props[INGREDIENT_NAME],
134 props[INGREDIENT_NAME]}));
135 }
136 else funcall(sp, P_NAME, props[INGREDIENT_NAME]);
137 funcall(sp, P_NAME_ADJ, props[INGREDIENT_ADJ]);
138 funcall(sp, P_GENDER, props[INGREDIENT_GENDER]);
139 funcall(sp, P_LONG, props[INGREDIENT_LONG]);
140 funcall(sp, PLANT_ROOMDETAIL, props[INGREDIENT_ROOMDETAIL]);
141 if (props[INGREDIENT_DEMON]==RAW) {
142 funcall(sp, P_ARTICLE, 0);
143 funcall(sp, P_SHORT, previous_object()->Name(WER));
144 funcall(sp, P_ARTICLE, 1);
145 }
146 else funcall(sp, P_SHORT,
147 previous_object()->Name(WER,props[INGREDIENT_DEMON]));
148 previous_object()->AddId(lowerstring(props[INGREDIENT_NAME]));
149 // bei zusammengesetzten Namen, auch den hauptnamen akzeptieren
150 string str=lowerstring(props[INGREDIENT_NAME]);
151 string *names=explode(str, "-");
152 if (sizeof(names)>1) previous_object()->AddId(names[<1]);
153 names=explode(str, " ");
154 if (sizeof(names)>1) previous_object()->AddId(names[<1]);
155 foreach(string id: IDLIST)
156 {
157 if (strstr(str, id)==-1) continue;
158 previous_object()->AddId(id);
159 break;
160 }
161 // Adjective vorher deklinieren
162 str=props[INGREDIENT_ADJ];
163 if (stringp(str))
164 {
165 str=DeclAdj(lowerstring(str), WEN, 0);
166 previous_object()->AddAdjective(str);
167 }
168 } // Ende Konfiguration eines VC-erzeugten Objekts
169 // Plant-ID wird fuer alle Objekte auf irgendwas gesetzt.
170 previous_object()->SetPlantId(legal ? props[INGREDIENT_ID] : -1);
171 }
172 // Keine Krautdaten bekannt...
173 else
174 {
175 funcall(sp, P_NAME, "Kraut");
176 funcall(sp, P_GENDER, NEUTER);
177 funcall(sp, P_SHORT, "Ein Testkraut ("+capitalize(file)+")");
178 funcall(sp, P_LONG, "Ein nicht naeher spezifiziertes Testkraut.\n");
179 funcall(sp, PLANT_ROOMDETAIL,
180 "Ein nicht naeher spezifiziertes Testkraut ("
181 +capitalize(file)+").\n");
182 previous_object()->AddId("kraut");
183 previous_object()->SetPlantId(-1);
184 }
185 return file;
186}
187
188int NoParaObjects()
189{ return 1; }
190
191// AN: Funktion erzeugt aus den vorliegenden Daten der Kraeuterliste ein
192// physikalisch existierendes File in diesem Verzeichnis, zB wenn die Daten
193// erweitert werden sollen. Die Kraeuterliste stellt nur generische Objekte
194// zur Verfuegung, die keine Details haben. Wenn die Objekte ausgeschmueckt
195// werden sollen, koennen diese auch als Datei hier liegen.
196// Wird vom Plantmaster aus gerufen. Die Existenz von Klartext-
197// Fehlermeldungen laesst darauf schliessen, dass diese Funktion dafuer
198// vorgesehen war, vom Planttool aus gerufen zu werden. Dies wird dadurch
199// bestaetigt, dass dort wie hier alle von Magiern benutzbaren Kommando-
200// funktionen mit _ beginnen (_showplant(), _addroom() etc.), und die
201// Kommandofunktion im Planttool generell in der Lage ist, alle _*()
202// im Plantmaster zu rufen, sofern existent und fuer den Magier freigegeben.
203// AN/TODO: ggf. sollte man hier noch pruefen, ob die VC-Blueprint des
204// angeforderten Krautes gerade existiert, denn sonst wuerde das auf der
205// Platte liegende, scheinbar (nicht) geladene Objekt nicht mit dem
206// VC-Objekt uebereinstimmen. Evtl. reicht es aus, die Blueprint einfach
207// zu zerstoeren und neuzuladen.
208int _createfile(string filename)
209{
210 int i;
211 string str, short, long, gender, *name, roomdetail;
212 string *ids;
213 string plantfile;
214
215/* if (object_name(previous_object())!=PLANTMASTER) {
216 write("Illegal usage of _createfile()!\n");
217 return 1;
218 }*/
219// ^^^ Zook, ggf.spaeter wieder Kommentar entfernen.
220
221 mixed arr;
222 if (!pointerp(arr=krautdaten[filename])) {
223 write("Unknown plant '"+filename+"'.\n");
224 return 1;
225 }
226 if (file_size(PLANTDIR+filename+".c")>=0) {
227 write("error: file "+PLANTDIR+filename+".c already exists.\n");
228 return 1;
229 }
230 mixed props = arr[0];
231
232 // Kurzbeschreibung erzeugen
233 SetProp(P_NAME, props[INGREDIENT_NAME]);
234 SetProp(P_NAME_ADJ, props[INGREDIENT_ADJ]);
235 SetProp(P_GENDER, props[INGREDIENT_GENDER]);
236 if (props[INGREDIENT_DEMON]==RAW) {
237 SetProp(P_ARTICLE, 0);
238 short=Name(WER);
239 SetProp(P_ARTICLE, 1);
240 }
241 else short=Name(WER,props[INGREDIENT_DEMON]);
242 ids = ({ lowerstring(props[INGREDIENT_NAME]) });
243 // bei zusammengesetzten Namen, auch den hauptnamen akzeptieren
244 str=lowerstring(props[INGREDIENT_NAME]);
245 name=explode(str, "-");
246 if (sizeof(name)>1) ids += ({ name[<1] });
247 name=explode(str, " ");
248 if (sizeof(name)>1) ids += ({ name[<1] });
249 for (i=sizeof(IDLIST)-1; i>=0; i--) {
250 if (strstr(str, IDLIST[i], 0)==-1) continue;
251 ids += ({ IDLIST[i] });
252 break;
253 }
254 switch(props[INGREDIENT_GENDER]) {
255 case MALE: gender="MALE"; break;
256 case FEMALE: gender="FEMALE"; break;
257 case NEUTER: gender="NEUTER"; break;
258 default: gender=props[INGREDIENT_GENDER];
259 }
260 long=" \""+implode(old_explode(props[INGREDIENT_LONG], "\n"),
261 "\\n\"\n +\"")+"\\n\"";
262 roomdetail=" \""+implode(
263 old_explode(props[INGREDIENT_ROOMDETAIL], "\n"), "\\n\"\n +\"")+
264 "\\n\"";
265 plantfile=
266 "#pragma strong_types,rtt_checks\n\n"
267 "#include <properties.h>\n"
268 "#include <items/kraeuter/kraueter.h>\n"
269 "#include <items/kraeuter/kraeuterliste.h>\n\n"
270 "inherit STDPLANT;\n\n"
271 "protected void create()\n"
272 "{\n"
273 " ::create();\n";
274 plantfile+=" customizeMe("+upperstring(filename)+");\n";
275 plantfile+=
276 " SetProp(P_NAME, \""+props[INGREDIENT_NAME]+"\");\n"
277 " SetProp(P_NAME_ADJ, \""+(props[INGREDIENT_ADJ]||"")+"\");\n"
278 " SetProp(P_GENDER, "+gender+");\n"
279 " SetProp(P_LONG, \n"+
280 long+");\n"
281 " SetProp(PLANT_ROOMDETAIL, \n"+
282 roomdetail+");\n"
283 " SetProp(P_SHORT, \""+short+"\");\n";
284 plantfile+=" AddId(({";
285 for (i=sizeof(ids)-1; i>=0; i--)
286 plantfile+=" \""+ids[i]+"\",";
287 plantfile[<1]=' ';
288 plantfile+="}));\n";
289 // Adjective vorher deklinieren
290 if (stringp(short=props[INGREDIENT_ADJ])) {
291 short=DeclAdj(lowerstring(short), WEN, 0)[0..<2];
292 plantfile+=" AddAdjective(\""+short+"\");\n";
293 }
294 plantfile+="}\n";
295 write(plantfile);
296 //write_file(PLANTDIR+filename+".c", plantfile);
297 write("Filename: "+PLANTDIR+filename+".c\n");
298 return 1;
299}
300