blob: 0cb902f321369cf5aa9824c13dcd1af076a84046 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2//
3// awmaster.c -- Armours- and Weapons-Master
4//
5#pragma strict_types
6#pragma no_clone
7#pragma no_shadow
8#pragma no_inherit
9#pragma verbose_errors
10#pragma combine_strings
11#pragma pedantic
12#pragma range_check
13#pragma warn_deprecated
14
15#include <combat.h>
16#include <language.h>
17#include <properties.h>
18#include <wizlevels.h>
19
20#define SAVEFILE "/secure/ARCH/awmaster"
21#define ADUMPFILE "/log/ARCH/RUESTUNGEN"
22#define DDUMPFILE "/log/ARCH/DAMAGERS"
23#define WDUMPFILE "/log/ARCH/WAFFEN"
24
25#define AWF_PUTON 1
26#define AWF_PUTOFF 2
27#define AWF_BOOST 4
28#define AWF_ZAUBER 8
29#define AWF_RESIST 16
30
31#define AWM_TYPE 0
32#define AWM_CLASS 1
33#define AWM_EFF_CLASS 2
34#define AWM_FLAGS 3
35#define AWM_WEIGHT 4
36#define AWM_VALUE 5
37#define AWM_HANDS 6
38#define AWM_D_TYPE 7
39#define AWM_X_CLASS 8
40#define AWM_TIME 9
41
42mapping armours,weapons,damagers;
43private int save_me_soon;
44
45private int allowed()
46{
47 if (previous_object() && geteuid(previous_object())==ROOTID)
48 return 1;
49 if (!process_call() && previous_object() && this_interactive() && ARCH_SECURITY)
50 return 1;
51 return 0;
52}
53
54void create()
55{
56 seteuid(getuid(this_object()));
57
58 if (!restore_object(SAVEFILE))
59 {
60 armours = ([]);
61 weapons = ([]);
62 damagers = ([]);
63 }
64 if (widthof(damagers) == 1) {
65 mapping tmp = damagers;
66 damagers = m_allocate(sizeof(tmp),2);
67 foreach(string r, int flag: tmp) {
68 damagers[r,0]=flag;
69 }
70 }
71}
72
73void save_me(int now)
74{
75 if (now)
76 save_object(SAVEFILE);
77 else
78 save_me_soon=1;
79}
80
81void reset() {
82 if (save_me_soon)
83 {
84 save_me_soon=0;
85 save_me(1);
86 }
87}
88
89public varargs int remove(int silent) {
90 save_me(1);
91 destruct(this_object());
92 return 1;
93}
94
95int xflags(object ob){
96 int re;
97 mapping m;
98 if (!ob || !objectp(ob))
99 return 0;
100 re=0;
Vanion50652322020-03-10 21:13:25 +0100101 if ((({object})ob->QueryProp(P_WEAR_FUNC))==ob ||
102 (({object})ob->QueryProp(P_WIELD_FUNC))==ob )
MG Mud User88f12472016-06-24 23:31:02 +0200103 re += AWF_PUTON;
Vanion50652322020-03-10 21:13:25 +0100104 if ((({object})ob->QueryProp(P_REMOVE_FUNC))==ob ||
105 (({object})ob->QueryProp(P_UNWIELD_FUNC))==ob )
MG Mud User88f12472016-06-24 23:31:02 +0200106 re += AWF_PUTOFF;
Vanion50652322020-03-10 21:13:25 +0100107 if ((({object})ob->QueryProp(P_DEFEND_FUNC))==ob ||
108 (({object})ob->QueryProp(P_HIT_FUNC))==ob )
MG Mud User88f12472016-06-24 23:31:02 +0200109 re += AWF_BOOST;
110 // ists nen Mapping und nicht leer?
Vanion50652322020-03-10 21:13:25 +0100111 if (mappingp(m=({mapping})ob->QueryProp(P_RESISTANCE_STRENGTHS))
MG Mud User88f12472016-06-24 23:31:02 +0200112 && sizeof(m))
113 re += AWF_RESIST;
114 return re;
115}
116
117void RegisterArmour()
118{ object ob;
119 string id;
Arathornb3051452021-05-13 21:13:03 +0200120 int h;
MG Mud User88f12472016-06-24 23:31:02 +0200121
122 if (!objectp(ob=previous_object()) ||
123 member(inherit_list(ob),"/std/armour.c")==-1)
124 return;
125 id = explode(object_name(ob),"#")[0];
126 if (member(armours,id))
127 {
128 armours[id][AWM_TIME]=time();
Vanion50652322020-03-10 21:13:25 +0100129 if ((h=({int})ob->QueryProp(P_AC)) > armours[id][AWM_CLASS])
MG Mud User88f12472016-06-24 23:31:02 +0200130 {
131 armours[id][AWM_CLASS]=h;
MG Mud User88f12472016-06-24 23:31:02 +0200132 }
Vanion50652322020-03-10 21:13:25 +0100133 if ((h=({int})ob->QueryProp(P_EFFECTIVE_AC)) > armours[id][AWM_EFF_CLASS])
MG Mud User88f12472016-06-24 23:31:02 +0200134 {
135 armours[id][AWM_EFF_CLASS]=h;
MG Mud User88f12472016-06-24 23:31:02 +0200136 }
Vanion50652322020-03-10 21:13:25 +0100137 if ((h=({int})ob->QueryProp(P_NR_HANDS)) < armours[id][AWM_HANDS])
MG Mud User88f12472016-06-24 23:31:02 +0200138 {
139 armours[id][AWM_HANDS]=h;
MG Mud User88f12472016-06-24 23:31:02 +0200140 }
141 if ((h=xflags(ob)) != armours[id][AWM_FLAGS])
142 {
143 armours[id][AWM_FLAGS]=h;
MG Mud User88f12472016-06-24 23:31:02 +0200144 }
145 }
146 else
147 {
148 armours += ([ id :
149 ([
bugfixd94d0932020-04-08 11:27:13 +0200150 AWM_TYPE : ({string})ob->QueryProp(P_ARMOUR_TYPE) ,
151 AWM_CLASS : ({int})ob->QueryProp(P_AC) ,
152 AWM_EFF_CLASS : ({int})ob->QueryProp(P_EFFECTIVE_AC) ,
MG Mud User88f12472016-06-24 23:31:02 +0200153 AWM_FLAGS : xflags(ob),
bugfixd94d0932020-04-08 11:27:13 +0200154 AWM_WEIGHT : ({int})ob->QueryProp(P_WEIGHT) ,
155 AWM_VALUE : ({int})ob->QueryProp(P_VALUE) ,
156 AWM_HANDS : ({int})ob->QueryProp(P_NR_HANDS) , // Fuer Schilde
157 AWM_D_TYPE : ({string*})ob->QueryProp(P_DAM_TYPE) ,
158 AWM_X_CLASS : ({int})ob->QueryProp(P_EFFECTIVE_WC) ||
159 ({int})ob->QueryProp(P_WC),
MG Mud User88f12472016-06-24 23:31:02 +0200160 AWM_TIME : time()
161 ]) ]);
162 }
163 save_me(0);
164}
165
166void RegisterWeapon()
167{ object ob;
168 string id;
Arathornb3051452021-05-13 21:13:03 +0200169 int h;
MG Mud User88f12472016-06-24 23:31:02 +0200170
171 if (!objectp(ob=previous_object()) ||
172 member(inherit_list(ob),"/std/weapon.c")==-1)
173 return;
174 id = explode(object_name(ob),"#")[0];
175 if (member(weapons,id))
176 {
177 weapons[id][AWM_TIME] = time();
Vanion50652322020-03-10 21:13:25 +0100178 if ((h=({int})ob->QueryProp(P_WC)) > weapons[id][AWM_CLASS])
MG Mud User88f12472016-06-24 23:31:02 +0200179 {
180 weapons[id][AWM_CLASS]=h;
MG Mud User88f12472016-06-24 23:31:02 +0200181 }
Vanion50652322020-03-10 21:13:25 +0100182 if ((h=({int})ob->QueryProp(P_EFFECTIVE_WC)) > weapons[id][AWM_EFF_CLASS])
MG Mud User88f12472016-06-24 23:31:02 +0200183 {
184 weapons[id][AWM_EFF_CLASS]=h;
MG Mud User88f12472016-06-24 23:31:02 +0200185 }
Vanion50652322020-03-10 21:13:25 +0100186 if ((h=({int})ob->QueryProp(P_NR_HANDS)) < weapons[id][AWM_HANDS])
MG Mud User88f12472016-06-24 23:31:02 +0200187 {
188 weapons[id][AWM_HANDS]=h;
MG Mud User88f12472016-06-24 23:31:02 +0200189 }
190 if ((h=xflags(ob)) != weapons[id][AWM_FLAGS])
191 {
192 weapons[id][AWM_FLAGS]=h;
MG Mud User88f12472016-06-24 23:31:02 +0200193 }
194 }
195 else
196 {
197 weapons += ([ id :
198 ([
bugfixd94d0932020-04-08 11:27:13 +0200199 AWM_TYPE : ({string})ob->QueryProp(P_WEAPON_TYPE) ,
200 AWM_CLASS : ({int})ob->QueryProp(P_WC) ,
201 AWM_EFF_CLASS : ({int})ob->QueryProp(P_EFFECTIVE_WC) ,
MG Mud User88f12472016-06-24 23:31:02 +0200202 AWM_FLAGS : xflags(ob),
bugfixd94d0932020-04-08 11:27:13 +0200203 AWM_WEIGHT : ({int})ob->QueryProp(P_WEIGHT) ,
204 AWM_VALUE : ({int})ob->QueryProp(P_VALUE) ,
205 AWM_HANDS : ({int})ob->QueryProp(P_NR_HANDS) ,
206 AWM_D_TYPE : ({string*})ob->QueryProp(P_DAM_TYPE) ,
207 AWM_X_CLASS : ({int})ob->QueryProp(P_EFFECTIVE_AC) ||
208 ({int})ob->QueryProp(P_AC),
MG Mud User88f12472016-06-24 23:31:02 +0200209 AWM_TIME : time()
210 ]) ]);
211 }
212 save_me(0);
213}
214
215void RegisterDamager(object dam_ob,int old_dam, int new_dam)
216{ object ob;
217 int flag;
218 string fn;
219
220 if (!objectp(ob=previous_object()) ||
221 (member(inherit_list(ob),"/std/weapon.c")==-1 &&
222 member(inherit_list(ob),"/std/armour.c")==-1 ))
223 return;
224 if (old_dam>new_dam) // Repair
225 flag=2;
226 else if (new_dam>old_dam) // Damage
227 flag=1;
228 else
229 return;
230 if (!objectp(dam_ob))
231 return;
232 if (!(fn=old_explode(object_name(dam_ob),"#")[0]) || !stringp(fn))
233 return;
234 damagers[fn,0]=damagers[fn,0]|flag;
235 damagers[fn,1]=time();
236 save_me(0);
237}
238
239string dtdump(mixed arg)
240{ string re;
241 int i,w;
242
243 if (stringp(arg))
244 return capitalize(arg);
245 if (!pointerp(arg) || !stringp(arg[0]))
246 return "<NONE>";
247 if ((i=sizeof(arg))==1)
248 return capitalize(arg[0]);
249 w = (31-i)/i;
250 if (w--<1)
251 return "<MANY>";
252 for (re="",--i;i>=0;i--)
253 {
254 if (!stringp(arg[i]))
255 re += "-";
256 else
257 re += capitalize(arg[i][0..w]);
258 if (i)
259 re += "|";
260 }
261 return re;
262}
263
264int Dump(mixed what, int sortidx)
265{ string file,*ind;
266 mapping dump;
267
268 if (!allowed())
269 return -1;
270
271 if (!what)
272 {
273 write("Nimm doch mal einen richtigen Parameter!\n");
274 return 0;
275 }
276 if (stringp(what) && sizeof(what)>0)
277 {
278 what==what[0..0];
279 if (what=="a")
280 what=1;
281 else if (what=="w")
282 what=2;
283 else if (what=="d")
284 what=3;
285 else
286 {
287 write("Nimm doch mal einen richtigen Parameter!\n");
288 return 0;
289 }
290 }
291 if (!intp(what) || what<1 || what>3)
292 {
293 write("Nimm doch mal einen richtigen Parameter!\n");
294 return 0;
295 }
296 if (what==3) // Die 'damagers' haben ein anderes Ausgabeformat
297 {
298 printf("AWM: Dumping 'damagers' to '%s'\n",DDUMPFILE);
299 if (sizeof(damagers) < 1) {
300 write("AWM: Dump aborted, mapping empty.\n");
301 return 1;
302 }
303 if (file_size(DDUMPFILE)>1)
304 rm(DDUMPFILE);
305
306 // nach letzter Aktualisierung sortieren.
307 mixed sorted = sort_array(m_indices(damagers),
308 function int (string a, string b) {
309 return damagers[a,1] < damagers[b,1];
310 } );
311
312 string ausgabe = sprintf(
313 "--- Damagers-Dump --- %s --- %s ---\n\n"+
314 "%:15s D R [Filename]\n",
315 dtime(time()),capitalize(getuid(this_interactive())),
316 "Datum/Zeit");
317 foreach(string rue : sorted) {
318 ausgabe += sprintf("%:15s %1s %1s %s\n",
319 strftime("%y%m%d-%H:%M:%S",damagers[rue,1]),
320 (damagers[rue,0]&1?"+":"-"),
321 (damagers[rue,0]&2?"+":"-"),
322 rue);
323 }
324
325 write_file(DDUMPFILE, ausgabe);
326 return 1;
327 }
328 if (what==2)
329 what=0;
330 file=(what?ADUMPFILE:WDUMPFILE);
331
332 printf("AWM: Dumping '%s' to '%s'\n",
333 (what?"armours":"weapons"),file);
334
335 dump=(what?armours:weapons);
336
337 if (sortidx) {
338 ind = sort_array(m_indices(dump),
339 function int (string a, string b)
340 {return dump[a][sortidx] < dump[b][sortidx];} );
341 }
342 else
343 ind = sort_array(m_indices(dump),#'>);
344
345 if (sizeof(ind) < 1)
346 {
347 write("AWM: Dump aborted, mapping empty.\n");
348 return 1;
349 }
350
351 if (file_size(file)>1)
352 rm(file);
353
354 string ausgabe = sprintf(
355 "--- %s-Dump --- %s --- %s ---\n\n"+
356 "[Filename], Datum/Zeit\n"+
357 " ____Typ___ CLS ECL XCL NFBR WGHT. VALUE H %30.30'_'|s\n",
358 (what?"Ruestungs":"Waffen"),dtime(time()),
359 capitalize(getuid(this_interactive())),"DamType(s)");
360
361 foreach(string index : ind)
362 {
363 ausgabe += sprintf(
364 "[%s] %s\n %10s %3d %3d %3d %1s%1s%1s%1s %5d %5d %1d %-30.30s\n",
365 index, strftime("%y%m%d-%H:%M:%S",dump[index][AWM_TIME]),
366 dump[index][AWM_TYPE],
367 dump[index][AWM_CLASS],
368 dump[index][AWM_EFF_CLASS],
369 dump[index][AWM_X_CLASS],
370 (dump[index][AWM_FLAGS]&AWF_PUTON?"+":"-"),
371 (dump[index][AWM_FLAGS]&AWF_PUTOFF?"+":"-"),
372 (dump[index][AWM_FLAGS]&AWF_BOOST?"+":"-"),
373 (dump[index][AWM_FLAGS]&AWF_RESIST?"+":"-"),
374 dump[index][AWM_WEIGHT],
375 dump[index][AWM_VALUE],
376 dump[index][AWM_HANDS],
377 dtdump(dump[index][AWM_D_TYPE]) );
378 }
379 write_file(file,ausgabe);
380 write("AWM: Done.\n");
381 return 1;
382}
383
384int Unregister(string what)
385{
386 if (!allowed())
387 return -1;
388 if (!what)
389 {
390 write("Du solltest schon einen Filenamen angeben!\n");
391 return 0;
392 }
393 if (member(armours,what))
394 {
395 m_delete(armours,what);
396 write("Unregistered "+what+" from 'armours'.\n");
397 return 1;
398 }
399 if (member(weapons,what))
400 {
401 m_delete(weapons,what);
402 write("Unregistered "+what+" from 'weapons'.\n");
403 return 1;
404 }
405 if (member(damagers,what))
406 {
407 m_delete(damagers,what);
408 write("Unregistered "+what+" from 'damagers'.\n");
409 return 1;
410 }
411 save_me(0);
412 return 0;
413}
414
415int ResetDamagers()
416{
417 if (!allowed())
418 return -1;
419 damagers = m_allocate(0,2);
420 save_me(1);
421 return 1;
422}
423