Added public files
Roughly added all public files. Probably missed some, though.
diff --git a/std/clothing/container_description.c b/std/clothing/container_description.c
new file mode 100644
index 0000000..f7942bc
--- /dev/null
+++ b/std/clothing/container_description.c
@@ -0,0 +1,137 @@
+// MorgenGrauen MUDlib
+//
+// clothing/container_description.c -- clothing_container description handling
+//
+// $Id: container_description.c 6198 2007-02-13 23:39:43Z Zesstra $
+
+#pragma strict_types
+#pragma save_types
+#pragma no_clone
+#pragma pedantic
+#pragma range_check
+
+inherit "/std/thing/description";
+
+#define NEED_PROTOTYPES
+
+#include <thing/properties.h>
+#include <thing/description.h>
+#include <thing/language.h>
+#include <container.h>
+#include <combat.h>
+#include <thing/material.h>
+#include <defines.h>
+#include <wizlevels.h>
+#include <player/base.h>
+
+void create()
+{
+ ::create();
+ SetProp(P_TRANSPARENT, 1);
+ AddId("Container");
+}
+
+string dam_descr()
+{ string re;
+ mixed desc;
+ int maximum,dam,pos;
+
+ if (!QueryProp(P_NAME) || !QueryProp(P_DAMAGED) || !QueryProp(P_SHORT) ||
+ !(desc=QueryProp(P_DAM_DESC)) || (!stringp(desc) && !pointerp(desc)))
+ return "";
+ re = capitalize(name(WER,2))+" ";
+ maximum = QueryProp(P_AC)+(dam=QueryProp(P_DAMAGED));
+ if (stringp(desc))
+ return (dam>(maximum/2))?(re+desc+".\n"):"";
+ pos = (sizeof(desc)*dam/maximum);
+ if (stringp(desc[pos]))
+ return (re+desc[pos]+".\n");
+ return "";
+}
+
+string short()
+{ string s;
+ if(!(s=process_string(QueryProp(P_SHORT))))
+ return 0;
+ return s+(QueryProp(P_WORN)?" (angezogen).\n":".\n");
+}
+
+varargs string long(int mode)
+{ string descr, inv_descr;
+
+ descr=(process_string(QueryProp(P_LONG)||"") + (dam_descr()||""));
+ if (!QueryProp(P_TRANSPARENT))
+ return descr;
+
+ inv_descr = make_invlist(PL, all_inventory(ME), mode );
+ if ( inv_descr != "" )
+ descr += capitalize(QueryPronoun(WER)) + " enthaelt:\n" + inv_descr;
+ return descr;
+}
+
+mapping _query_material() {
+ mixed res,at;
+
+ if (mappingp(res=Query(P_MATERIAL)))
+ return res;
+ at=QueryProp(P_ARMOUR_TYPE);
+ switch(at) {
+ case AT_ARMOUR:
+ case AT_HELMET:
+ case AT_RING:
+ case AT_AMULET:
+ case AT_SHIELD:
+ return ([MAT_MISC_METAL:100]);
+ case AT_CLOAK:
+ case AT_TROUSERS:
+ return ([MAT_CLOTH:100]);
+ case AT_GLOVE:
+ case AT_BOOT:
+ return ([MAT_CLOTH:100]);
+ }
+ return ([MAT_CLOTH:100]);
+}
+
+// flags: 1 - wizard, 2 - don't collect equal objects '
+// flags: 4 - don't append infos for wizards
+private void stringenize(mixed obj, int flags, mixed objs, mixed info)
+{
+ string id, tmp;
+ int idx;
+ tmp = capitalize(obj->short()||"")[0..<2]
+ + (!(flags & 4) && (flags & 1) ? " ["+object_name(obj)+"]" : "");
+ if(flags & 3 || living(obj)) id = object_name(obj);
+ else
+ id = explode(object_name(obj), "#")[0] + tmp;
+ if((idx = member(objs, id)) == -1)
+ {
+ objs += ({ id });
+ info += ({ ({ tmp, 1, obj}) });
+ }
+ else
+ info[idx][1]++;
+}
+
+private string collect(mixed obj)
+{
+ if(!sizeof(obj[0])) return 0;
+ return obj[0] + (obj[1] > 1 ? " ("+obj[1]+")" : "");
+}
+
+// flags: 1 - return array, 2 - don't collect equal objects '
+// flags: 4 - don't append infos for wizards
+varargs mixed make_invlist(object viewer, mixed inv, int flags)
+{
+ int iswiz;
+ mixed objs, info;
+ string descr;
+
+ iswiz = IS_LEARNER( viewer ) && viewer->QueryProp(P_WANTS_TO_LEARN);
+ descr = ""; objs = ({}); info = ({});
+ map(inv, #'stringenize/*'*/, iswiz | (flags & 2) | (flags & 4), &objs, &info);
+ if(flags & 1) return info;
+ inv = map(info, #'collect/*'*/) - ({ 0 });
+ if(!sizeof(inv)) return "";
+ return sprintf("%"+(sizeof(inv) > 6 ? "#" : "=")+"-78s",
+ implode(inv, "\n")) + "\n";
+}
diff --git a/std/clothing/description.c b/std/clothing/description.c
new file mode 100644
index 0000000..fa226fd
--- /dev/null
+++ b/std/clothing/description.c
@@ -0,0 +1,58 @@
+// MorgenGrauen MUDlib
+//
+// armour/description.c -- armour description handling
+//
+// $Id: description.c,v 1.7 2002/08/19 14:21:04 Rikus Exp $
+
+#pragma strict_types
+#pragma save_types
+#pragma no_clone
+#pragma pedantic
+#pragma range_check
+#pragma warn_empty_casts
+
+inherit "/std/thing/description";
+
+//#define NEED_PROTOTYPES
+
+#include <properties.h>
+
+string dam_descr() {
+ return "";
+}
+
+string short()
+{ string s;
+ if(!(s=process_string(QueryProp(P_SHORT))))
+ return 0;
+ return s+(QueryProp(P_WORN)?" (angezogen).\n":".\n");
+}
+
+varargs string long()
+{
+ return (process_string(QueryProp(P_LONG)||"") + (dam_descr()||""));
+}
+
+mapping _query_material() {
+ mixed res,at;
+
+ if (mappingp(res=Query(P_MATERIAL)))
+ return res;
+ at=QueryProp(P_ARMOUR_TYPE);
+ switch(at) {
+ case AT_ARMOUR:
+ case AT_HELMET:
+ case AT_RING:
+ case AT_AMULET:
+ case AT_SHIELD:
+ return ([MAT_MISC_METAL:100]);
+ case AT_CLOAK:
+ case AT_TROUSERS:
+ return ([MAT_CLOTH:100]);
+ case AT_GLOVE:
+ case AT_BOOT:
+ return ([MAT_LEATHER:100]);
+ }
+ return ([MAT_CLOTH:100]);
+}
+
diff --git a/std/clothing/moving.c b/std/clothing/moving.c
new file mode 100644
index 0000000..ba2e05f
--- /dev/null
+++ b/std/clothing/moving.c
@@ -0,0 +1,46 @@
+// MorgenGrauen MUDlib
+//
+// armour/moving.c -- armour moving object
+//
+// $Id: moving.c,v 3.3 1998/03/02 08:34:57 Paracelsus Exp $
+
+#pragma strict_types
+#pragma save_types
+#pragma no_clone
+#pragma pedantic
+#pragma range_check
+
+inherit "/std/thing/moving";
+
+#define NEED_PROTOTYPES 1
+
+#include <thing/properties.h>
+#include <properties.h>
+#include <moving.h>
+#include <defines.h>
+#include <clothing.h>
+
+/* Bekleidung muss vor Bewegung und Zerstoerung ausgezogen werden */
+
+varargs int move(mixed dest, int method ) {
+ // ggf. Ausziehen
+ if (objectp(QueryProp(P_WORN)))
+ DoUnwear(method & (M_SILENT|M_NOCHECK));
+
+ if ((method&M_NOCHECK) || (!(object)QueryProp(P_WORN)))
+ return ::move(dest, method);
+
+ return ME_CANT_BE_DROPPED;
+}
+
+varargs int remove(int silent) {
+ // ggf. Ausziehen
+ if (objectp(QueryProp(P_WORN)))
+ DoUnwear(M_SILENT|M_NOCHECK);
+
+ if (!(object)QueryProp(P_WORN))
+ return ::remove(silent);
+ // Ausziehen hat irgendwie nicht geklappt. :-(
+ return 0;
+}
+
diff --git a/std/clothing/wear.c b/std/clothing/wear.c
new file mode 100644
index 0000000..dcde4bd
--- /dev/null
+++ b/std/clothing/wear.c
@@ -0,0 +1,594 @@
+// MorgenGrauen MUDlib
+//
+// clothing/wear.c -- Funktionen rund ums Anziehen/Tragen von Kleidung.
+//
+// $Id: combat.c 6243 2007-03-15 21:10:21Z Zesstra $
+
+#pragma strict_types
+#pragma save_types
+#pragma no_clone
+#pragma pedantic
+#pragma range_check
+
+#define NEED_PROTOTYPES
+
+#include <thing/properties.h>
+#include <thing/commands.h>
+#include <thing/description.h>
+#include <living/clothing.h>
+#include <clothing.h>
+#include <living/combat.h>
+#include <language.h>
+#include <defines.h>
+#include <new_skills.h>
+#include <moving.h>
+
+// Globale Variablen
+nosave int flaw, ftime;
+
+void create()
+{
+ // Einige Properties sollten nicht von aussen gesetzt werden koennen
+ Set(P_WORN, PROTECTED, F_MODE);
+ Set(P_LAST_USE, PROTECTED, F_MODE_AS);
+ Set(P_RESTRICTIONS,([]),F_VALUE);
+
+ // Bekleidung benoetigt Kommandos, mit denen man sie an- und
+ // ausziehen kann
+ AddCmd( ({"zieh","ziehe"}),"ziehe" );
+ AddCmd( ({"trag","trage"}),"do_wear" );
+}
+
+// aktuelles Lebewesen, was diese Kleidung (oder auch Ruestung) zur Zeit
+// traegt.
+public object QueryUser()
+{
+ return QueryProp(P_WORN);
+}
+
+
+// Ausgabe von Meldungen ueber write() oder _notify_fail(), je nachdem, ob der
+// Spieler alles anzieht oder was bestimmtes.
+protected void msg(string str, mixed fl) {
+ if (!stringp(str)) {
+ return;
+ }
+ if (fl) {
+ write(str);
+ }
+ else {
+ _notify_fail(str);
+ }
+}
+
+/*
+ * Ausgabe einer Meldung beim Anziehen geht nur an Spieler, nicht an NPC.
+ * Die Umgebung bekommt immer eine Meldung.
+ */
+varargs void doWearMessage(int all) {
+ string *str,s1;
+ mixed wearmsg;
+
+ if(wearmsg=QueryProp(P_WEAR_MSG)) { // Ist eine WearMsg gesetzt?
+ if(closurep(wearmsg)) { // Evtl. gar als extra Fkt.?
+
+ str = funcall(wearmsg, PL);
+ if(interactive(PL)) {
+ // Im Falle, dass all gesetzt ist, wird als Indent der Name des
+ // angezogenen Objektes gesetzt. (trag alles)
+ write(break_string(str[0],78,
+ (all?(Name(WER)+": "):0), BS_LEAVE_MY_LFS));
+ }
+ //(Zesstra): say() ist hier bloed, weil es an das Env vom this_player()
+ //ausgibt, sofern der existiert. So koennen Spieler die meldung kriegen,
+ //obwohl die laengst woanders sind (z.B. Sequenzen)
+ //Daher nun Ausgabe an das Env vom Env (wenn das kein Raum sein sollte,
+ //was durchaus sein koennte, macht tell_room() nix).
+ if ( objectp(environment()) && objectp(environment(environment())) )
+ tell_room(environment(environment()),
+ break_string(str[1], 78, 0, BS_LEAVE_MY_LFS),({PL}) );
+
+ return;
+ }
+ else if(interactive(PL)) {
+ s1 = replace_personal(sprintf(wearmsg[0],"@WEN2"), ({PL,ME}), 1);
+
+ write(break_string(s1,78,(all?(Name(WER)+": "):0), BS_LEAVE_MY_LFS));
+ }
+
+ s1 = replace_personal(sprintf(wearmsg[1],"@WER1","@WENU2"),
+ ({PL, ME}), 1);
+
+ if ( objectp(environment()) && objectp(environment(environment())) )
+ tell_room(environment(environment()),
+ break_string(s1, 78, 0, BS_LEAVE_MY_LFS),({ PL }) );
+
+ return;
+ }
+ /*
+ * Keine WearMsg gesetzt. Ausgabe der Default-Meldungen.
+ */
+ else if(interactive(PL)) {
+ write(break_string("Du ziehst " + name(WEN,1) + " an.",78,
+ (all?(Name(WER)+": "):0)));
+ }
+ if ( objectp(environment()) && objectp(environment(environment())) )
+ tell_room(environment(environment()),break_string(PL->Name(WER)
+ + " zieht " + name(WEN,0) +" an.",78), ({PL}));
+}
+
+/*
+ * Ausgabe einer Meldung beim Ausziehen geht nur an Spieler, nicht an NPC.
+ * Die Umgebung bekommt natuerlich immer eine Meldung.
+ */
+void doUnwearMessage(object worn_by, int all)
+{
+ string *str,s1;
+ mixed msg;
+
+ if(!objectp(worn_by)) { // Na huch, gar nicht angezogen? Abbruch.
+ return;
+ }
+
+ if(msg=QueryProp(P_UNWEAR_MSG)) { // Ist eine UnwearMsg gesetzt?
+ if(closurep(msg)) { // Oho! Gar gleich als Fkt.?
+
+ str = funcall(msg, worn_by);
+ if(interactive(worn_by)) {
+ tell_object(worn_by,break_string(str[0], 78,
+ (all?(Name(WER)+": "):0),BS_LEAVE_MY_LFS));
+ }
+
+ //(Zesstra): say() ist hier bloed, weil es an das Env vom this_player()
+ //ausgibt, sofern der existiert. So koennen Spieler die meldung kriegen,
+ //obwohl die laengst woanders sind (z.B. Sequenzen)
+ //Daher nun Ausgabe an das Env vom worn_by (wenn das kein Raum sein sollte,
+ //macht tell_room() nix).
+ if ( objectp(environment(worn_by)) )
+ tell_room(environment(worn_by),
+ break_string(str[1],78, 0, BS_LEAVE_MY_LFS),({ worn_by }) );
+
+ return;
+ }
+ else if(interactive(worn_by)) {
+ s1 = replace_personal(sprintf(msg[0],"@WEN2"),
+ ({worn_by,ME}), 1);
+
+ tell_object(worn_by,break_string(s1,78,
+ (all?(Name(WER)+": "):0), BS_LEAVE_MY_LFS));
+ }
+
+ s1 = replace_personal(sprintf(msg[1],"@WER1","@WENU2"),
+ ({worn_by, ME }), 1);
+
+ if ( objectp(environment(worn_by)) )
+ tell_room(environment(environment()),
+ break_string(s1,78, 0, BS_LEAVE_MY_LFS),({ worn_by }) );
+ return;
+ }
+ /*
+ * Keine UnwearMsg gesetzt. Ausgabe der Default-Meldungen.
+ */
+ else if(interactive(worn_by)) {
+ tell_object(worn_by,break_string("Du ziehst " + name(WEN,1) + " aus.",78,
+ (all?(Name(WER)+": "):0)));
+ }
+ if ( objectp(environment(worn_by)) )
+ tell_room(environment(worn_by), break_string(worn_by->Name(WER)
+ + " zieht " + name(WEN,0) + " aus.",78), ({ worn_by }) );
+}
+
+// Diese Funktion wird aufgerufen, wenn die Ruestung wirklich angezogen
+// wird
+protected void InformWear(object pl, int silent, int all) {
+ return;
+}
+
+// Diese Funktion wird aufgerufen, wenn die Ruestung wirklich ausgezogen
+// wird
+protected void InformUnwear(object pl, int silent, int all) {
+ return;
+}
+
+// liefert Werte <0 zurueck, wenn der Spieler die Kleidung _nicht_
+// anziehen darf.
+// Hierbei steht -1 dafuer, dass der Aufrufer return 0 machen sollte,
+// <= -2 sollte zur einem return !all fuehren.
+protected int _check_wear_restrictions(int silent, int all) {
+ mixed type,res;
+ object *armours;
+
+ // Man kann nur Kram anziehen, die man bei sich traegt
+ if (environment()!=PL) {
+ msg(break_string("Du musst "+name(WEN,1)+" erst nehmen!",78,
+ (all?(Name(WER)+": "):0)), all);
+ return(-1);
+ }
+
+ // Eine getragene Ruestung kann man nicht nochmal anziehen
+ if (QueryProp(P_WORN)) {
+ msg(break_string("Du traegst "+name(WEN,1)+" bereits.",78,
+ (all?(Name(WER)+": "):0)), all);
+ return(-1);
+ }
+
+ // Diese Funktion versucht immer, TP anzuziehen (*args*). Es gibt aber viele
+ // Magier, die ohne TP oder mit dem falschen TP anziehen wollen. Daher mal
+ // pruefen und ggf. Fehler ausloesen.
+ if (!this_player())
+ raise_error("Kein this_player() existent beim Anziehen!\n");
+ else if (this_player() != environment())
+ raise_error("Meine Umgebung beim Anziehen ist nicht this_player()!\n");
+
+ // Ueber P_RESTRICTIONS kann man einige Restriktionen definieren, ohne
+ // gleich auf eine WearFunc zurueckgreifen zu muessen.
+ // Die Auswertung erfolgt ueber den RestrictionChecker
+ if ((res=QueryProp(P_RESTRICTIONS)) && mappingp(res) &&
+ (res=(string)"/std/restriction_checker"->check_restrictions(PL,res))
+ && stringp(res)) {
+ msg(break_string(res,78,(all?(Name(WER)+": "):0)),all);
+ return(-1);
+ }
+
+ // Ist eine WearFunc gesetzt, wird diese aufgerufen.
+ if (objectp(res=QueryProp(P_WEAR_FUNC)) &&
+ !(res->WearFunc(ME, silent, environment()))) {
+ // Eine Meldung muss von der WearFunc ausgegeben werden
+ return(-2);
+ }
+
+ // scheinbar darf man das hier anziehen. ;-)
+ return 0;
+}
+
+protected void _informwear(int silent, int all) {
+
+ // Eine Meldung ausgeben, wenn das silent-Flag nicht gesetzt ist
+ if (!silent) {
+ doWearMessage(all);
+ }
+
+ // Inform-Funktion aufrufen
+ InformWear(PL, silent, all);
+}
+
+// Die Funktion, die das eigentliche Anziehen durchfuehrt
+varargs int DoWear(int silent, int all) {
+ int nh;
+
+ // Bedingungen pruefen, _check_restrictions() gibt die notwendigen Meldungen
+ // an den Spieler aus.
+ int res = _check_wear_restrictions(silent, all);
+ if (res == -1)
+ return(0);
+ else if (res <= -2)
+ return(!all);
+
+ // Der Check auf freie Haende muss nach allen anderen Checks aus Kleidung
+ // und Ruestung erfolgen und ist im Prinzip identisch fuer beide. Daher wird
+ // der hier in dieser Funktion gemacht.
+ // Soll das Objekt Haende "benutzen"? Steht da auch wirklich ein
+ // Integer-Wert drin? ich mach da jetzt ein raise_error(), das soll
+ // schliesslich gefixt werden. Ausserdem spart es nen Workaround beim
+ // Ausziehen.
+ if (!intp(nh=QueryProp(P_NR_HANDS))) {
+ raise_error(sprintf("Invalid P_NR_HANDS in %O",object_name()));
+ }
+ // Wenn Haende benutzt werden sollen, muss natuerlich auch getestet
+ // werden, ob das ueberhaupt geht
+ if (nh>0) {
+ if (!(PL->UseHands(ME, nh))) {
+ // Schade, nicht genug Haende frei -> Meldung ausgeben
+ write(break_string("Du hast keine Hand mehr frei.",78,
+ (all?(Name(WER)+": "):0)));
+ return(!all);
+ }
+ }
+
+ // OK, die Ruestung kann angezogen werden.
+ // Behinderung beim Wechsel nur fuer Spieler
+ if (query_once_interactive(PL))
+ // Wenn das Ganze ,,wirklich'' eine Kleidung/Ruestung ist und kein SMS
+ // oder aehnliches...
+ if (!QueryProp(P_WEAPON_TYPE)) {
+ // Aktion noch setzen, Spieler hat ja was angezogen
+ PL->SetProp(P_LAST_WEAR_ACTION,({WA_WEAR,time()}));
+ // Im Kampf verliert der Spieler durch Kleidungswechsel eine Runde.
+ if (PL->InFight()) {
+ PL->SetProp(P_ATTACK_BUSY,1);
+ }
+ }
+ // Eintragen in P_CLOTHING/P_ARMOURS
+ PL->Wear(this_object());
+
+ PL->SetProp(P_EQUIP_TIME,time());
+ SetProp(P_WORN, PL);
+ SetProp(P_EQUIP_TIME,time());
+
+ // ggf. andere Objekte informieren etc.
+ _informwear(silent, all);
+
+ // Fertig mit dem Anziehen. Vorgang beenden bzw. mit anderen
+ // Ruestungen fortfahren
+ return !all;
+}
+
+
+// liefert 0 zureck, wenn die Kleidung/Ruestung ausgezogen werden kann
+// bei M_NOCHECK ist das Ausziehen immer erlaubt, allerdings wird
+// P_REMOVE_FUNC auch dann gerufen (wenn auch ignoriert).
+// <0 verbietet das Ausziehen
+protected int _check_unwear_restrictions(object worn_by, int silent,
+ int all)
+{
+ // Nicht getragene Ruestungen kann man auch nicht ausziehen
+ if (!objectp(worn_by)) {
+ return(-2);
+ }
+
+ // Ist eine RemoveFunc gesetzt, wird diese aufgerufen
+ // Im Falle von M_NOCHECK wird das Ergebnis allerdings ignoriert.
+ mixed res=QueryProp(P_REMOVE_FUNC);
+ if (objectp(res)
+ && !res->RemoveFunc(ME,silent,worn_by)
+ && !(silent & M_NOCHECK)
+ )
+ {
+ // Eine Meldung muss von der RemoveFunc ausgegeben werden
+ return(-2);
+ }
+
+ // generell hebt M_NOCHECK die Restriktionen auf - sonst kommt es zu
+ // massiven Inkonsistenzen beim Bewegen mit M_NOCHECK.
+ if (silent & M_NOCHECK)
+ return 1;
+
+ // Eine verfluchte Ruestung kann man natuerlich nicht ausziehen
+ res=QueryProp(P_CURSED);
+ if (res ) {
+ if (stringp(res)) {
+ // Stand in P_CURSED ein String? Dann diesen ausgeben
+ tell_object(worn_by,
+ (res[<1]=='\n' ? res : break_string(res,78,
+ (all?(Name(WER)+": "):0))));
+ }
+ else {
+ // Sonst eine Standard-Meldung ausgeben
+ tell_object(worn_by,break_string(
+ "Du kannst " + name(WEN) + " nicht ausziehen, " + QueryPronoun(WER)
+ + " ist verflucht worden.\n",78,(all?(Name(WER)+": "):0)));
+ }
+ return(-2);
+ }
+
+ // Ausziehen moeglich
+ return(1);
+}
+
+protected void _informunwear(object worn_by, int silent, int all) {
+
+ // Inform-Funktion aufrufen
+ InformUnwear(worn_by, silent, all);
+
+ // Meldung ausgeben, wenn das silent-Flag nicht gesetzt ist
+ if (!(silent&M_SILENT)) {
+ doUnwearMessage( worn_by, all );
+ }
+}
+
+// Die Funktion, die das eigentliche Ausziehen durchfuehrt
+// hier steht nur drin, was auf jeden Fall fuer Kleidungen und Ruestungen
+// gleich ist, damit man bei Ruestungen diese Funktion nicht ueberschreiben
+// muss.
+varargs int DoUnwear(int silent, int all) {
+ object worn_by;
+ int nh;
+
+ // Das Flag "silent" wird in der RemoveFunc() etwas anders behandelt
+ // als ueberall anders. Deshalb wird M_SILENT gesetzt, sofern "silent"
+ // _irgendeinen_ Wert ausser M_NOCHECK hatte.
+ if ( silent & ~M_NOCHECK )
+ silent |= M_SILENT;
+
+ // Standard-Notfiyfail setzen.
+ if (all)
+ notify_fail("Alles ausgezogen, was ging.\n");
+
+ // Hat das Objekt Haende "benutzt"? Steht da auch wirklich ein
+ // Integer-Wert drin? Wenn nicht, mach ich nen raise_error(), das duerfte
+ // eigentlich gar nicht passieren. Pruefung mal am Anfang machen, bevor
+ // irgendwas anderes (RemoveFunc()) passiert ist.
+ if (!intp(nh=QueryProp(P_NR_HANDS))) {
+ raise_error(sprintf("Invalid P_NR_HANDS in %O",object_name()));
+ }
+
+ worn_by=QueryProp(P_WORN);
+ // darf ausgezogen werden? Wenn nicht, Ende.
+ int res = _check_unwear_restrictions(worn_by,silent,all);
+ if (res < 0)
+ return(!all);
+
+ // OK, alles klar, die Ruestung wird ausgezogen
+ worn_by->Unwear(ME);
+
+ // Benutzte Haende wieder freigeben
+ if (nh>0) {
+ worn_by->FreeHands(ME);
+ }
+
+ worn_by->SetProp(P_EQUIP_TIME, time());
+ SetProp(P_WORN, 0);
+
+ // Flag noch setzen, Spieler hat ja was ausgezogen
+ // Aber nur wenns auch der Spieler selbst ist.
+ // und wenn das wirklich eine Ruestung und kein SMS o.ae. ist.
+ if (PL && PL==worn_by && !QueryProp(P_WEAPON_TYPE)) {
+ //Behinderung beim Wechsel nur fuer Spieler
+ if (query_once_interactive(PL)) {
+ PL->SetProp(P_LAST_WEAR_ACTION,({WA_UNWEAR,time()}));
+ if (PL->InFight()) {
+ PL->SetProp(P_ATTACK_BUSY,1);
+ }
+ }
+ }
+
+ // ok, nun noch andere Objekte informieren.
+ _informunwear(worn_by,silent,all);
+
+ // Fertig mit dem Anziehen. Vorgang beenden bzw. mit anderen
+ // Ruestungen fortfahren
+ return !all;
+}
+
+protected int _do_wear(string str, int silent, int all) {
+ int *last;
+
+ // Standard-Notfiy-Fail setzen.
+ if (all)
+ notify_fail("Alles angezogen, was ging.\n");
+
+ // Ist diese Ruestung ueberhaupt gemeint? Bei "trage alles" ist dies
+ // natuerlich immer der Fall
+ if (!str || (!all && !id(str))) {
+ return 0;
+ }
+
+ // Vielleicht darf der Spieler ja gar nix mehr anziehen.
+ if ((object)PL->InFight()) {
+ last=(int*)PL->QueryProp(P_LAST_WEAR_ACTION);
+ if (pointerp(last) && (last[0]==WA_UNWEAR) && ((time()-last[1])<2)) {
+ notify_fail("Du hast doch gerade erst etwas ausgezogen!\n"
+ "So schnell bist Du nicht!\n");
+ return 0;
+ }
+ }
+
+ // Auf zum eigentlichen Anziehen
+ return DoWear(silent, all);
+
+}
+
+// Funktion, die das "trage"/"ziehe * an"-Kommando auswertet
+varargs int do_wear(string str, int silent) {
+ int all;
+
+ // Hat der Spieler "trage alles" eingegeben?
+ all=(str=="alles" || str=="alle kleidung" || str=="alle bekleidung");
+
+ return(_do_wear(str,silent,all));
+}
+
+protected int _do_unwear(string str, int silent, int all) {
+ int * last;
+
+ // Ist diese Ruestung ueberhaupt gemeint? Und hat dieser Spieler sie
+ // auch wirklich an?
+ if (!stringp(str) || (!all && !id(str))) {
+ return 0;
+ }
+
+ if (!QueryProp(P_WORN)) {
+ if (all) {
+ notify_fail("Alles ausgezogen, was ging.\n");
+ return 0;
+ }
+ if (!Query(P_ARTICLE) || QueryProp(P_PLURAL)) {
+ notify_fail( break_string(
+ "Du traegst k"+name(WEN,0)+".",78) );
+ }
+ else {
+ notify_fail( break_string(
+ "Du traegst "+name(WEN,1)+" nicht.",78) );
+ }
+ return 0;
+ }
+
+ // Vielleicht darf der Spieler ja gar nichts mehr ausziehen.
+ if ((object)PL->InFight()) {
+ last=(int*)PL->QueryProp(P_LAST_WEAR_ACTION);
+ if (pointerp(last) && (last[0]==WA_WEAR) && ((time()-last[1])<2)) {
+ notify_fail("Du hast doch gerade erst etwas angezogen!\n"
+ "So schnell bist Du nicht!\n");
+ return 0;
+ }
+ }
+ // Auf zum eigentlichen Ausziehen
+ return DoUnwear(silent, all);
+}
+
+// Die Funktion, die das "ziehe * aus"-Kommando auswertet
+varargs int do_unwear(string str, int silent) {
+ int all;
+
+ all=(str=="alles" || str=="alle kleidung" || str=="alle bekleidung");
+
+ return(_do_unwear(str,silent,all));
+}
+
+// Funktion, die das "ziehe"-Kommando auswertet
+int ziehe(string str) {
+ string ob;
+
+ // Uebergebenes Argument pruefen
+ if (!stringp(str)) {
+ return 0;
+ }
+
+ // Ist ANziehen gemeint?
+ if (sscanf(str, "%s an", ob)==1) {
+ return do_wear(ob );
+ }
+
+ // Oder ist AUSziehen gemeint?
+ if (sscanf(str, "%s aus", ob)==1 ) {
+ return do_unwear(ob);
+ }
+
+ // Ok, es geht wohl weder ums an- noch ums ausziehen
+ return 0;
+}
+
+
+// Beschaedigen des Kleidungsstuecks
+
+// Direktes Beschaedigen der Kleidung durch Setzen der Prop gibts nicht. ;-)
+// Das geht aus Kompatibilitaetgruenden bei Ruestungen, aber nicht mehr bei
+// Kleidung. Punkt.
+static mixed _set_item_damaged(mixed arg) {
+ return(QueryProp(P_DAMAGED));
+}
+
+// Will man eine Kleidung beschaedigen oder reparieren, so macht man das
+// am besten ueber die Funktion Damage(argument). Positive Argumente
+// bedeuten eine Beschaedigung, negative eine Reparatur. Der Rueckgabewert
+// ist die wirklich durchgefuehrte Aenderung des Beschaedigungswertes
+int Damage(int new_dam) {
+ return 0;
+}
+
+// Wird die Kleidung einer Belastung ausgesetzt (bei Ruestungen z.B. bei einem
+// Angriff eines Gegners), dann wird TakeFlaw() aufgerufen. Bei Kleidungen
+// koennte man ja per P_SENSITIVE arbeiten oder ein Magier ruft bei Aktionen
+// TakeFlaw() auf.
+varargs void TakeFlaw(mixed dam_types,mapping einfos) {
+ int quality;
+
+ // Ist der Ruestung eine Qualitaet gesetzt worden, so kann es zu einer
+ // allmaehlichen Beschaedigung der Ruestung kommen. Im if() flaw gleich
+ // hochzaehlen.
+ if ((quality=QueryProp(P_QUALITY)) && !((++flaw) % quality)) {
+ Damage(1);
+ }
+
+ // Zeitpunkt des ersten Aufrufes festhalten
+ if (!ftime)
+ ftime=time();
+}
+
+// Die Flaw-Daten koennen natuerlich auch abgerufen werden
+mixed *QueryFlaw() {
+ return ({flaw,ftime,dtime(ftime)});
+}
+
+public status IsClothing() {return 1;}
+