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