blob: 69cb54f0656ca61d90d442ff40973341212ffd1a [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2//
3// clothing/wear.c -- Funktionen rund ums Anziehen/Tragen von Kleidung.
4//
5// $Id: combat.c 6243 2007-03-15 21:10:21Z Zesstra $
6
7#pragma strict_types
8#pragma save_types
9#pragma no_clone
MG Mud User88f12472016-06-24 23:31:02 +020010#pragma range_check
11
12#define NEED_PROTOTYPES
13
14#include <thing/properties.h>
15#include <thing/commands.h>
16#include <thing/description.h>
17#include <living/clothing.h>
18#include <clothing.h>
19#include <living/combat.h>
20#include <language.h>
21#include <defines.h>
22#include <new_skills.h>
23#include <moving.h>
24
25// Globale Variablen
26nosave int flaw, ftime;
27
28void create()
29{
30 // Einige Properties sollten nicht von aussen gesetzt werden koennen
31 Set(P_WORN, PROTECTED, F_MODE);
32 Set(P_LAST_USE, PROTECTED, F_MODE_AS);
33 Set(P_RESTRICTIONS,([]),F_VALUE);
34
35 // Bekleidung benoetigt Kommandos, mit denen man sie an- und
36 // ausziehen kann
37 AddCmd( ({"zieh","ziehe"}),"ziehe" );
38 AddCmd( ({"trag","trage"}),"do_wear" );
39}
40
41// aktuelles Lebewesen, was diese Kleidung (oder auch Ruestung) zur Zeit
42// traegt.
43public object QueryUser()
44{
45 return QueryProp(P_WORN);
46}
47
48
49// Ausgabe von Meldungen ueber write() oder _notify_fail(), je nachdem, ob der
50// Spieler alles anzieht oder was bestimmtes.
51protected void msg(string str, mixed fl) {
52 if (!stringp(str)) {
53 return;
54 }
55 if (fl) {
56 write(str);
57 }
58 else {
59 _notify_fail(str);
60 }
61}
62
63/*
64 * Ausgabe einer Meldung beim Anziehen geht nur an Spieler, nicht an NPC.
65 * Die Umgebung bekommt immer eine Meldung.
66 */
67varargs void doWearMessage(int all) {
68 string *str,s1;
69 mixed wearmsg;
70
71 if(wearmsg=QueryProp(P_WEAR_MSG)) { // Ist eine WearMsg gesetzt?
72 if(closurep(wearmsg)) { // Evtl. gar als extra Fkt.?
73
74 str = funcall(wearmsg, PL);
75 if(interactive(PL)) {
76 // Im Falle, dass all gesetzt ist, wird als Indent der Name des
77 // angezogenen Objektes gesetzt. (trag alles)
78 write(break_string(str[0],78,
79 (all?(Name(WER)+": "):0), BS_LEAVE_MY_LFS));
80 }
81 //(Zesstra): say() ist hier bloed, weil es an das Env vom this_player()
82 //ausgibt, sofern der existiert. So koennen Spieler die meldung kriegen,
83 //obwohl die laengst woanders sind (z.B. Sequenzen)
84 //Daher nun Ausgabe an das Env vom Env (wenn das kein Raum sein sollte,
85 //was durchaus sein koennte, macht tell_room() nix).
86 if ( objectp(environment()) && objectp(environment(environment())) )
87 tell_room(environment(environment()),
88 break_string(str[1], 78, 0, BS_LEAVE_MY_LFS),({PL}) );
89
90 return;
91 }
92 else if(interactive(PL)) {
93 s1 = replace_personal(sprintf(wearmsg[0],"@WEN2"), ({PL,ME}), 1);
94
95 write(break_string(s1,78,(all?(Name(WER)+": "):0), BS_LEAVE_MY_LFS));
96 }
97
98 s1 = replace_personal(sprintf(wearmsg[1],"@WER1","@WENU2"),
99 ({PL, ME}), 1);
100
101 if ( objectp(environment()) && objectp(environment(environment())) )
102 tell_room(environment(environment()),
103 break_string(s1, 78, 0, BS_LEAVE_MY_LFS),({ PL }) );
104
105 return;
106 }
107 /*
108 * Keine WearMsg gesetzt. Ausgabe der Default-Meldungen.
109 */
110 else if(interactive(PL)) {
111 write(break_string("Du ziehst " + name(WEN,1) + " an.",78,
112 (all?(Name(WER)+": "):0)));
113 }
114 if ( objectp(environment()) && objectp(environment(environment())) )
bugfixaf2be4f2020-03-22 19:13:07 +0100115 tell_room(environment(environment()),break_string(
116 ({string})PL->Name(WER)
MG Mud User88f12472016-06-24 23:31:02 +0200117 + " zieht " + name(WEN,0) +" an.",78), ({PL}));
118}
119
120/*
121 * Ausgabe einer Meldung beim Ausziehen geht nur an Spieler, nicht an NPC.
122 * Die Umgebung bekommt natuerlich immer eine Meldung.
123 */
124void doUnwearMessage(object worn_by, int all)
125{
126 string *str,s1;
127 mixed msg;
128
129 if(!objectp(worn_by)) { // Na huch, gar nicht angezogen? Abbruch.
130 return;
131 }
132
133 if(msg=QueryProp(P_UNWEAR_MSG)) { // Ist eine UnwearMsg gesetzt?
134 if(closurep(msg)) { // Oho! Gar gleich als Fkt.?
135
136 str = funcall(msg, worn_by);
137 if(interactive(worn_by)) {
138 tell_object(worn_by,break_string(str[0], 78,
139 (all?(Name(WER)+": "):0),BS_LEAVE_MY_LFS));
140 }
141
142 //(Zesstra): say() ist hier bloed, weil es an das Env vom this_player()
143 //ausgibt, sofern der existiert. So koennen Spieler die meldung kriegen,
144 //obwohl die laengst woanders sind (z.B. Sequenzen)
145 //Daher nun Ausgabe an das Env vom worn_by (wenn das kein Raum sein sollte,
146 //macht tell_room() nix).
147 if ( objectp(environment(worn_by)) )
148 tell_room(environment(worn_by),
149 break_string(str[1],78, 0, BS_LEAVE_MY_LFS),({ worn_by }) );
150
151 return;
152 }
153 else if(interactive(worn_by)) {
154 s1 = replace_personal(sprintf(msg[0],"@WEN2"),
155 ({worn_by,ME}), 1);
156
157 tell_object(worn_by,break_string(s1,78,
158 (all?(Name(WER)+": "):0), BS_LEAVE_MY_LFS));
159 }
160
161 s1 = replace_personal(sprintf(msg[1],"@WER1","@WENU2"),
162 ({worn_by, ME }), 1);
163
164 if ( objectp(environment(worn_by)) )
165 tell_room(environment(environment()),
166 break_string(s1,78, 0, BS_LEAVE_MY_LFS),({ worn_by }) );
167 return;
168 }
169 /*
170 * Keine UnwearMsg gesetzt. Ausgabe der Default-Meldungen.
171 */
172 else if(interactive(worn_by)) {
173 tell_object(worn_by,break_string("Du ziehst " + name(WEN,1) + " aus.",78,
174 (all?(Name(WER)+": "):0)));
175 }
176 if ( objectp(environment(worn_by)) )
bugfixaf2be4f2020-03-22 19:13:07 +0100177 tell_room(environment(worn_by), break_string(
178 ({string})worn_by->Name(WER)
MG Mud User88f12472016-06-24 23:31:02 +0200179 + " zieht " + name(WEN,0) + " aus.",78), ({ worn_by }) );
180}
181
182// Diese Funktion wird aufgerufen, wenn die Ruestung wirklich angezogen
183// wird
184protected void InformWear(object pl, int silent, int all) {
185 return;
186}
187
188// Diese Funktion wird aufgerufen, wenn die Ruestung wirklich ausgezogen
189// wird
190protected void InformUnwear(object pl, int silent, int all) {
191 return;
192}
193
194// liefert Werte <0 zurueck, wenn der Spieler die Kleidung _nicht_
195// anziehen darf.
196// Hierbei steht -1 dafuer, dass der Aufrufer return 0 machen sollte,
197// <= -2 sollte zur einem return !all fuehren.
198protected int _check_wear_restrictions(int silent, int all) {
199 mixed type,res;
200 object *armours;
201
202 // Man kann nur Kram anziehen, die man bei sich traegt
203 if (environment()!=PL) {
204 msg(break_string("Du musst "+name(WEN,1)+" erst nehmen!",78,
205 (all?(Name(WER)+": "):0)), all);
206 return(-1);
207 }
208
209 // Eine getragene Ruestung kann man nicht nochmal anziehen
210 if (QueryProp(P_WORN)) {
211 msg(break_string("Du traegst "+name(WEN,1)+" bereits.",78,
212 (all?(Name(WER)+": "):0)), all);
213 return(-1);
214 }
215
216 // Diese Funktion versucht immer, TP anzuziehen (*args*). Es gibt aber viele
217 // Magier, die ohne TP oder mit dem falschen TP anziehen wollen. Daher mal
218 // pruefen und ggf. Fehler ausloesen.
219 if (!this_player())
220 raise_error("Kein this_player() existent beim Anziehen!\n");
221 else if (this_player() != environment())
222 raise_error("Meine Umgebung beim Anziehen ist nicht this_player()!\n");
223
224 // Ueber P_RESTRICTIONS kann man einige Restriktionen definieren, ohne
225 // gleich auf eine WearFunc zurueckgreifen zu muessen.
226 // Die Auswertung erfolgt ueber den RestrictionChecker
227 if ((res=QueryProp(P_RESTRICTIONS)) && mappingp(res) &&
bugfixaf2be4f2020-03-22 19:13:07 +0100228 (res=({string})"/std/restriction_checker"->check_restrictions(PL,res))
MG Mud User88f12472016-06-24 23:31:02 +0200229 && stringp(res)) {
230 msg(break_string(res,78,(all?(Name(WER)+": "):0)),all);
231 return(-1);
232 }
233
234 // Ist eine WearFunc gesetzt, wird diese aufgerufen.
235 if (objectp(res=QueryProp(P_WEAR_FUNC)) &&
bugfixaf2be4f2020-03-22 19:13:07 +0100236 !(({int})res->WearFunc(ME, silent, environment()))) {
MG Mud User88f12472016-06-24 23:31:02 +0200237 // Eine Meldung muss von der WearFunc ausgegeben werden
238 return(-2);
239 }
240
241 // scheinbar darf man das hier anziehen. ;-)
242 return 0;
243}
244
245protected void _informwear(int silent, int all) {
246
247 // Eine Meldung ausgeben, wenn das silent-Flag nicht gesetzt ist
248 if (!silent) {
249 doWearMessage(all);
250 }
251
252 // Inform-Funktion aufrufen
253 InformWear(PL, silent, all);
254}
255
256// Die Funktion, die das eigentliche Anziehen durchfuehrt
257varargs int DoWear(int silent, int all) {
258 int nh;
259
260 // Bedingungen pruefen, _check_restrictions() gibt die notwendigen Meldungen
261 // an den Spieler aus.
262 int res = _check_wear_restrictions(silent, all);
263 if (res == -1)
264 return(0);
265 else if (res <= -2)
266 return(!all);
267
268 // Der Check auf freie Haende muss nach allen anderen Checks aus Kleidung
269 // und Ruestung erfolgen und ist im Prinzip identisch fuer beide. Daher wird
270 // der hier in dieser Funktion gemacht.
271 // Soll das Objekt Haende "benutzen"? Steht da auch wirklich ein
272 // Integer-Wert drin? ich mach da jetzt ein raise_error(), das soll
273 // schliesslich gefixt werden. Ausserdem spart es nen Workaround beim
274 // Ausziehen.
275 if (!intp(nh=QueryProp(P_NR_HANDS))) {
276 raise_error(sprintf("Invalid P_NR_HANDS in %O",object_name()));
277 }
278 // Wenn Haende benutzt werden sollen, muss natuerlich auch getestet
279 // werden, ob das ueberhaupt geht
280 if (nh>0) {
bugfixaf2be4f2020-03-22 19:13:07 +0100281 if (!(({int})PL->UseHands(ME, nh))) {
MG Mud User88f12472016-06-24 23:31:02 +0200282 // Schade, nicht genug Haende frei -> Meldung ausgeben
283 write(break_string("Du hast keine Hand mehr frei.",78,
284 (all?(Name(WER)+": "):0)));
285 return(!all);
286 }
287 }
288
289 // OK, die Ruestung kann angezogen werden.
290 // Behinderung beim Wechsel nur fuer Spieler
291 if (query_once_interactive(PL))
292 // Wenn das Ganze ,,wirklich'' eine Kleidung/Ruestung ist und kein SMS
293 // oder aehnliches...
294 if (!QueryProp(P_WEAPON_TYPE)) {
295 // Aktion noch setzen, Spieler hat ja was angezogen
bugfixaf2be4f2020-03-22 19:13:07 +0100296 ({int*})PL->SetProp(P_LAST_WEAR_ACTION,({WA_WEAR,time()}));
MG Mud User88f12472016-06-24 23:31:02 +0200297 // Im Kampf verliert der Spieler durch Kleidungswechsel eine Runde.
bugfixaf2be4f2020-03-22 19:13:07 +0100298 if (({int})PL->InFight()) {
299 ({int})PL->SetProp(P_ATTACK_BUSY,1);
MG Mud User88f12472016-06-24 23:31:02 +0200300 }
301 }
302 // Eintragen in P_CLOTHING/P_ARMOURS
bugfixaf2be4f2020-03-22 19:13:07 +0100303 ({int})PL->Wear(this_object());
MG Mud User88f12472016-06-24 23:31:02 +0200304
bugfixaf2be4f2020-03-22 19:13:07 +0100305 ({int})PL->SetProp(P_EQUIP_TIME,time());
MG Mud User88f12472016-06-24 23:31:02 +0200306 SetProp(P_WORN, PL);
307 SetProp(P_EQUIP_TIME,time());
308
309 // ggf. andere Objekte informieren etc.
310 _informwear(silent, all);
311
312 // Fertig mit dem Anziehen. Vorgang beenden bzw. mit anderen
313 // Ruestungen fortfahren
314 return !all;
315}
316
317
318// liefert 0 zureck, wenn die Kleidung/Ruestung ausgezogen werden kann
319// bei M_NOCHECK ist das Ausziehen immer erlaubt, allerdings wird
320// P_REMOVE_FUNC auch dann gerufen (wenn auch ignoriert).
321// <0 verbietet das Ausziehen
322protected int _check_unwear_restrictions(object worn_by, int silent,
323 int all)
324{
325 // Nicht getragene Ruestungen kann man auch nicht ausziehen
326 if (!objectp(worn_by)) {
327 return(-2);
328 }
329
330 // Ist eine RemoveFunc gesetzt, wird diese aufgerufen
331 // Im Falle von M_NOCHECK wird das Ergebnis allerdings ignoriert.
332 mixed res=QueryProp(P_REMOVE_FUNC);
333 if (objectp(res)
bugfixaf2be4f2020-03-22 19:13:07 +0100334 && !({int})res->RemoveFunc(ME,silent,worn_by)
MG Mud User88f12472016-06-24 23:31:02 +0200335 && !(silent & M_NOCHECK)
336 )
337 {
338 // Eine Meldung muss von der RemoveFunc ausgegeben werden
339 return(-2);
340 }
341
342 // generell hebt M_NOCHECK die Restriktionen auf - sonst kommt es zu
343 // massiven Inkonsistenzen beim Bewegen mit M_NOCHECK.
344 if (silent & M_NOCHECK)
345 return 1;
346
347 // Eine verfluchte Ruestung kann man natuerlich nicht ausziehen
348 res=QueryProp(P_CURSED);
349 if (res ) {
350 if (stringp(res)) {
351 // Stand in P_CURSED ein String? Dann diesen ausgeben
352 tell_object(worn_by,
353 (res[<1]=='\n' ? res : break_string(res,78,
354 (all?(Name(WER)+": "):0))));
355 }
356 else {
357 // Sonst eine Standard-Meldung ausgeben
358 tell_object(worn_by,break_string(
359 "Du kannst " + name(WEN) + " nicht ausziehen, " + QueryPronoun(WER)
360 + " ist verflucht worden.\n",78,(all?(Name(WER)+": "):0)));
361 }
362 return(-2);
363 }
364
365 // Ausziehen moeglich
366 return(1);
367}
368
369protected void _informunwear(object worn_by, int silent, int all) {
370
371 // Inform-Funktion aufrufen
372 InformUnwear(worn_by, silent, all);
373
374 // Meldung ausgeben, wenn das silent-Flag nicht gesetzt ist
375 if (!(silent&M_SILENT)) {
376 doUnwearMessage( worn_by, all );
377 }
378}
379
380// Die Funktion, die das eigentliche Ausziehen durchfuehrt
381// hier steht nur drin, was auf jeden Fall fuer Kleidungen und Ruestungen
382// gleich ist, damit man bei Ruestungen diese Funktion nicht ueberschreiben
383// muss.
384varargs int DoUnwear(int silent, int all) {
385 object worn_by;
386 int nh;
387
388 // Das Flag "silent" wird in der RemoveFunc() etwas anders behandelt
389 // als ueberall anders. Deshalb wird M_SILENT gesetzt, sofern "silent"
390 // _irgendeinen_ Wert ausser M_NOCHECK hatte.
391 if ( silent & ~M_NOCHECK )
392 silent |= M_SILENT;
393
394 // Standard-Notfiyfail setzen.
395 if (all)
396 notify_fail("Alles ausgezogen, was ging.\n");
397
398 // Hat das Objekt Haende "benutzt"? Steht da auch wirklich ein
399 // Integer-Wert drin? Wenn nicht, mach ich nen raise_error(), das duerfte
400 // eigentlich gar nicht passieren. Pruefung mal am Anfang machen, bevor
401 // irgendwas anderes (RemoveFunc()) passiert ist.
402 if (!intp(nh=QueryProp(P_NR_HANDS))) {
403 raise_error(sprintf("Invalid P_NR_HANDS in %O",object_name()));
404 }
405
406 worn_by=QueryProp(P_WORN);
407 // darf ausgezogen werden? Wenn nicht, Ende.
408 int res = _check_unwear_restrictions(worn_by,silent,all);
409 if (res < 0)
410 return(!all);
411
412 // OK, alles klar, die Ruestung wird ausgezogen
bugfixaf2be4f2020-03-22 19:13:07 +0100413 ({int})worn_by->Unwear(ME);
MG Mud User88f12472016-06-24 23:31:02 +0200414
415 // Benutzte Haende wieder freigeben
416 if (nh>0) {
bugfixaf2be4f2020-03-22 19:13:07 +0100417 ({int})worn_by->FreeHands(ME);
MG Mud User88f12472016-06-24 23:31:02 +0200418 }
419
bugfixaf2be4f2020-03-22 19:13:07 +0100420 ({int})worn_by->SetProp(P_EQUIP_TIME, time());
MG Mud User88f12472016-06-24 23:31:02 +0200421 SetProp(P_WORN, 0);
422
423 // Flag noch setzen, Spieler hat ja was ausgezogen
424 // Aber nur wenns auch der Spieler selbst ist.
425 // und wenn das wirklich eine Ruestung und kein SMS o.ae. ist.
426 if (PL && PL==worn_by && !QueryProp(P_WEAPON_TYPE)) {
427 //Behinderung beim Wechsel nur fuer Spieler
428 if (query_once_interactive(PL)) {
bugfixaf2be4f2020-03-22 19:13:07 +0100429 ({int*})PL->SetProp(P_LAST_WEAR_ACTION,({WA_UNWEAR,time()}));
430 if (({int})PL->InFight()) {
431 ({int})PL->SetProp(P_ATTACK_BUSY,1);
MG Mud User88f12472016-06-24 23:31:02 +0200432 }
433 }
434 }
435
436 // ok, nun noch andere Objekte informieren.
437 _informunwear(worn_by,silent,all);
438
439 // Fertig mit dem Anziehen. Vorgang beenden bzw. mit anderen
440 // Ruestungen fortfahren
441 return !all;
442}
443
444protected int _do_wear(string str, int silent, int all) {
445 int *last;
446
447 // Standard-Notfiy-Fail setzen.
448 if (all)
Zesstra1fd31172018-12-18 21:34:49 +0100449 notify_fail("Alles angezogen was ging.\n");
MG Mud User88f12472016-06-24 23:31:02 +0200450
451 // Ist diese Ruestung ueberhaupt gemeint? Bei "trage alles" ist dies
452 // natuerlich immer der Fall
453 if (!str || (!all && !id(str))) {
454 return 0;
455 }
456
457 // Vielleicht darf der Spieler ja gar nix mehr anziehen.
bugfixaf2be4f2020-03-22 19:13:07 +0100458 if (({int})PL->InFight()) {
459 last=({int*})PL->QueryProp(P_LAST_WEAR_ACTION);
MG Mud User88f12472016-06-24 23:31:02 +0200460 if (pointerp(last) && (last[0]==WA_UNWEAR) && ((time()-last[1])<2)) {
461 notify_fail("Du hast doch gerade erst etwas ausgezogen!\n"
462 "So schnell bist Du nicht!\n");
463 return 0;
464 }
465 }
466
467 // Auf zum eigentlichen Anziehen
468 return DoWear(silent, all);
469
470}
471
472// Funktion, die das "trage"/"ziehe * an"-Kommando auswertet
473varargs int do_wear(string str, int silent) {
474 int all;
475
476 // Hat der Spieler "trage alles" eingegeben?
477 all=(str=="alles" || str=="alle kleidung" || str=="alle bekleidung");
478
479 return(_do_wear(str,silent,all));
480}
481
482protected int _do_unwear(string str, int silent, int all) {
483 int * last;
484
485 // Ist diese Ruestung ueberhaupt gemeint? Und hat dieser Spieler sie
486 // auch wirklich an?
487 if (!stringp(str) || (!all && !id(str))) {
488 return 0;
489 }
490
491 if (!QueryProp(P_WORN)) {
492 if (all) {
493 notify_fail("Alles ausgezogen, was ging.\n");
494 return 0;
495 }
496 if (!Query(P_ARTICLE) || QueryProp(P_PLURAL)) {
497 notify_fail( break_string(
498 "Du traegst k"+name(WEN,0)+".",78) );
499 }
500 else {
501 notify_fail( break_string(
502 "Du traegst "+name(WEN,1)+" nicht.",78) );
503 }
504 return 0;
505 }
506
507 // Vielleicht darf der Spieler ja gar nichts mehr ausziehen.
bugfixaf2be4f2020-03-22 19:13:07 +0100508 if (({int})PL->InFight()) {
509 last=({int*})PL->QueryProp(P_LAST_WEAR_ACTION);
MG Mud User88f12472016-06-24 23:31:02 +0200510 if (pointerp(last) && (last[0]==WA_WEAR) && ((time()-last[1])<2)) {
511 notify_fail("Du hast doch gerade erst etwas angezogen!\n"
512 "So schnell bist Du nicht!\n");
513 return 0;
514 }
515 }
516 // Auf zum eigentlichen Ausziehen
517 return DoUnwear(silent, all);
518}
519
520// Die Funktion, die das "ziehe * aus"-Kommando auswertet
521varargs int do_unwear(string str, int silent) {
522 int all;
523
524 all=(str=="alles" || str=="alle kleidung" || str=="alle bekleidung");
525
526 return(_do_unwear(str,silent,all));
527}
528
529// Funktion, die das "ziehe"-Kommando auswertet
530int ziehe(string str) {
531 string ob;
532
533 // Uebergebenes Argument pruefen
534 if (!stringp(str)) {
535 return 0;
536 }
537
538 // Ist ANziehen gemeint?
539 if (sscanf(str, "%s an", ob)==1) {
540 return do_wear(ob );
541 }
542
543 // Oder ist AUSziehen gemeint?
544 if (sscanf(str, "%s aus", ob)==1 ) {
545 return do_unwear(ob);
546 }
547
548 // Ok, es geht wohl weder ums an- noch ums ausziehen
549 return 0;
550}
551
552
553// Beschaedigen des Kleidungsstuecks
554
555// Direktes Beschaedigen der Kleidung durch Setzen der Prop gibts nicht. ;-)
556// Das geht aus Kompatibilitaetgruenden bei Ruestungen, aber nicht mehr bei
557// Kleidung. Punkt.
558static mixed _set_item_damaged(mixed arg) {
559 return(QueryProp(P_DAMAGED));
560}
561
562// Will man eine Kleidung beschaedigen oder reparieren, so macht man das
563// am besten ueber die Funktion Damage(argument). Positive Argumente
564// bedeuten eine Beschaedigung, negative eine Reparatur. Der Rueckgabewert
565// ist die wirklich durchgefuehrte Aenderung des Beschaedigungswertes
566int Damage(int new_dam) {
567 return 0;
568}
569
570// Wird die Kleidung einer Belastung ausgesetzt (bei Ruestungen z.B. bei einem
571// Angriff eines Gegners), dann wird TakeFlaw() aufgerufen. Bei Kleidungen
572// koennte man ja per P_SENSITIVE arbeiten oder ein Magier ruft bei Aktionen
573// TakeFlaw() auf.
574varargs void TakeFlaw(mixed dam_types,mapping einfos) {
575 int quality;
576
577 // Ist der Ruestung eine Qualitaet gesetzt worden, so kann es zu einer
578 // allmaehlichen Beschaedigung der Ruestung kommen. Im if() flaw gleich
579 // hochzaehlen.
580 if ((quality=QueryProp(P_QUALITY)) && !((++flaw) % quality)) {
581 Damage(1);
582 }
583
584 // Zeitpunkt des ersten Aufrufes festhalten
585 if (!ftime)
586 ftime=time();
587}
588
589// Die Flaw-Daten koennen natuerlich auch abgerufen werden
590mixed *QueryFlaw() {
591 return ({flaw,ftime,dtime(ftime)});
592}
593
594public status IsClothing() {return 1;}
595