Syntaxhilfe fuer Objekte eingebaut

Objekte koennen mit der Property P_SYNTAX_HELP explizite
Hilfen zur Syntax ihrer Kommandos anbieten.

Change-Id: Ib27a77b020d53fca411d83f0e02d85476ca62341
diff --git a/doc/hilfe.spieler b/doc/hilfe.spieler
index a2072f8..21a32fa 100644
--- a/doc/hilfe.spieler
+++ b/doc/hilfe.spieler
@@ -5,23 +5,23 @@
 Erlaeuterung angezeigt werden:
 
 Einfuehrung und erste Schritte:
-    Grundlegend: 
-      syntax, bewegung, regeln, einfuehrung
+    Grundlegend:
+      syntax, bewegung, regeln, einfuehrung, syntaxhilfe
     Charakter:
       attribute, zaubertraenke, stufen, stufenpunkte
-    Spiel:   
+    Spiel:
       abenteuer, gilden, zauberei
-    Neuspieler:  
+    Neuspieler:
       cicerones, tutorial
 
 Kommunikation:
-    Im Raum:	
+    Im Raum:
       sage, gespraech, frage, antworte
-    Privat:	
+    Privat:
       teile (mit), erzaehle, erwidere, fluestere,
-    MUD-weit:	
+    MUD-weit:
       rufe, ebenen, post, mrufe
-    Anderes:	
+    Anderes:
       ignoriere, kobold, weg, parties, senderwiederholung, klingelton
       teamspeak
 
diff --git a/doc/pcmd/syntaxhilfe b/doc/pcmd/syntaxhilfe
new file mode 100644
index 0000000..59596f6
--- /dev/null
+++ b/doc/pcmd/syntaxhilfe
@@ -0,0 +1,19 @@
+
+syntaxhilfe
+-----------
+
+ KOMMANDO:
+    syntaxhilfe <objekt>
+
+ ARGUMENTE:
+
+     <objekt>
+        Eine Bezeichnung fuer das Objekt, zu dem man eine Syntaxhilfe will
+
+ BESCHREIBUNG:
+    Wenn das gewuenschte Objekt gefunden wird und eine Syntaxhilfe anbietet,
+    wird diese angezeigt.
+
+    Hierbei kann es sein, dass die Syntaxhilfe nur unter bestimmten
+    Bedingungen (z.B. Gildenmitgliedschaft, Seher, etc.) angezeigt wird.
+
diff --git a/doc/props/P_SYNTAX_HELP b/doc/props/P_SYNTAX_HELP
new file mode 100644
index 0000000..13344f1
--- /dev/null
+++ b/doc/props/P_SYNTAX_HELP
@@ -0,0 +1,44 @@
+NAME:
+    P_SYNTAX_HELP              "lib_p_syntax_help"
+
+DEFINIERT IN:
+    /sys/thing/commands.h
+
+BESCHREIBUNG:
+    In dieser Property kann man fuer Spieler eine ausfuehrliche Syntaxhilfe zu
+    den Kommandos eines Objektes ablegen. Diese wird angezeigt, wenn der
+    Spieler das Kommando "synxtaxhilfe <objekt>" eingibt.
+    Die Property kann verschiedene Datenstrukturen enthalten:
+
+    1) ein String
+    Der String wird angezeigt, hierbei ggf. umgebrochen, vorhandene
+    Zeilenumbrueche werden beibehalten.
+
+    2) ein Array: ({hilfetext, bedingungen})
+
+    <hilfetext>:
+      * ein string:
+        Der String wird angezeigt, hierbei ggf. umgebrochen, vorhandene
+        Zeilenumbrueche werden beibehalten.
+      * eine lfun-closure:
+        Diese erhaelt beim Aufruf das betreffende Objekt als Argument.
+        Wenn diese dann einen String zurueckliefert, wird dieser dem Spieler
+        angezeigt. Hierbei wird ggf. umgebrochen, vorhandene Zeilenumbrueche
+        werden beibehalten.
+
+    <bedingungen>, welche erfuellt sein muessen, damit dem Spieler die Hilfe
+    angezeigt wird. Die Bedingungen sind entweder:
+      * ein Mapping fuer check_restriction()
+      * eine lfun-closure
+        Diese erhaelt beim Aufruf das betreffende Objekt als Argument und darf
+        eine 0 fuer 'erlaubt', 1 fuer 'nicht erlaubt (mit Standardtext)' oder
+        einen string fuer 'nicht erlaubt mit individuellem Text' sein.
+
+BEMERKUNGEN:
+    Hat ein Objekt keine Syntaxhilfe, wird das Kommando "syntaxhilfe" aus dem
+    Objekt wieder entfernt (d.h. die Property muss gesetzt sein, bevor der
+    erste Spieler das Kommando eingibt).
+
+SIEHE AUCH:
+    AddCmd
+
diff --git a/std/thing/commands.c b/std/thing/commands.c
index f745b67..fb13803 100644
--- a/std/thing/commands.c
+++ b/std/thing/commands.c
@@ -36,8 +36,11 @@
 #include <moving.h>
 #include <thing/language.h>
 #include <exploration.h>
+#include <defines.h>
+#include <living/comm.h>
 
 #define NEED_PROTOTYPES
+#include <thing/properties.h>
 #include <thing/description.h>
 #include <thing/commands.h>
 #undef NEED_PROTOTYPES
@@ -49,13 +52,82 @@
 
 private nosave mapping added_cmds;
 
+protected int _cmd_syntaxhelp(string str, string *args)
+{
+  mapping|closure restr;
+  mixed help = QueryProp(P_SYNTAX_HELP);
+  if (pointerp(help))
+  {
+    restr = help[1];
+    help = help[0];
+  }
+  // Restriktionen vor dem Anzeigen pruefen.
+  if (mappingp(restr))
+  {
+    string res = "/std/restriction_checker"->check_restrictions(PL,restr);
+    if (res)
+    {
+      PL->ReceiveMsg("Fuer " + name(WEN,1) + " darfst Du "
+                     "die Syntaxhilfe (noch) nicht lesen:\n"
+                     + res,
+                     MT_NOTIFICATION|MSG_BS_LEAVE_LFS,
+                     "syntaxhilfe",0,this_object());
+      return 1;
+    }
+  }
+  else if (closurep(restr))
+  {
+    string res = funcall(restr, ME);
+    if (res)
+    {
+      if (intp(res))
+        PL->ReceiveMsg("Fuer " + name(WEN,1) + " darfst Du "
+                       "die Syntaxhilfe (noch) nicht lesen.",
+                       MT_NOTIFICATION|MSG_BS_LEAVE_LFS,
+                       "syntaxhilfe",0,this_object());
+      else if (stringp(res))
+        PL->ReceiveMsg(res,
+                       MT_NOTIFICATION|MSG_BS_LEAVE_LFS,
+                       "syntaxhilfe",0,this_object());
+      return 1;
+    }
+  }
+
+  if (stringp(help))
+  {
+    help = "Fuer " + name(WEN,1) + " gibt es folgende Syntaxhilfe:\n"
+           + help;
+  }
+  else if (closurep(help))
+  {
+    help = funcall(help, this_object());
+  }
+  else
+  {
+    // wenn das Objekt keine Syntaxhilfe hat, braucht es das Kommando auch
+    // nicht.
+    notify_fail("Fuer " + name(WEN,1)
+                + " gibt es keine Syntaxhilfe.\n");
+    RemoveCmd(0,0, "_cmd_syntaxhelp");
+    return 0;
+  }
+  if (stringp(help) && sizeof(help))
+    PL->ReceiveMsg(help, MT_NOTIFICATION|MSG_BS_LEAVE_LFS,
+                   "syntaxhilfe",0,this_object());
+
+  return 1;
+}
+
 protected void create()
 {
+  AddCmd("syntaxhilfe&@ID", #'_cmd_syntaxhelp,
+         "Fuer WAS moechtest Du eine Syntaxhilfe?\n",
+         "_cmd_syntaxhelp");
 }
 
 protected void create_super() {
   set_next_reset(-1);
-}     
+}
 
 varargs void AddCmd(mixed cmd, mixed func, mixed flag, mixed cmdid) {
  int i,j;
diff --git a/sys/thing/commands.h b/sys/thing/commands.h
index 2bb876d..2f9dfc7 100644
--- a/sys/thing/commands.h
+++ b/sys/thing/commands.h
@@ -10,6 +10,7 @@
 // properties
 
 #define P_COMMANDS           "commands"
+#define P_SYNTAX_HELP        "lib_p_syntaxhelp"
 
 #endif // __THING_COMMANDS_H__