AddInfo()
=========

FUNKTION
--------
::

     varargs void AddInfo( frage, meldung
			   [, indent [, [silent [, casebased] ] ] );

DEFINIERT IN
------------
::

     /std/npc/info.c

ARGUMENTE
---------
::

     string/string* frage
	Schluesseltext(e) auf die Informationen gegeben werden sollen.
     string/closure meldung
	Information, die gegeben werden soll/Closure
     string indent
	Text, der sich bei mehrzeiligen Meldungen wiederholen soll.
     int/string silent
	Ist silent gesetzt, so erfolgt Antwort nur an Fragenden.
     string/closure casebased
	Closure mit Returnwert string oder int.

BESCHREIBUNG
------------
::

     Wenn ein Spieler ein NPC mittels "frage <monstername> nach <frage>" nach
     einer Information mit dem Schluessel 'frage' fragt, so wird die
     entsprechende 'meldung' ausgegeben (oder die Closure in 'meldung'
     gerufen und der zurueckgegebene Text ausgegeben). Der Meldung wird
     der Name des Monsters vorangestellt.

     Frage:
      Schluessel muessen kleingeschrieben sein, koennen aber Leerzeichen
      enthalten.

     Meldung:
      Wenn kein 'indent' angegeben ist, muss man die Meldung selbst
      umbrechen.

     Indent:
      Wird ein 'indent' angegeben so wird jeder Zeile hinter dem
      Monsternamen noch das 'indent' vorangesetzt. Zusaetzlich wird
      'meldung' auf jeden Fall sauber umgebrochen.
      Ein typisches indent ist "sagt: ".

     Silent:
      Bei 'silent'==1 erfolgt keine Textausgabe der Antwortmeldung im Raum,
      ist 'silent' ein String, so wird jener an alle anderen Spieler ausser
      dem Fragesteller im Raum ausgegeben.

     Casebased:
      Die als Closure angegebene Methode entscheidet, ob oder wie der NPC 
      auf diese Frage antworten soll:
      - return 0:	normale Antwort mit "meldung"
      - return 1:	keine Antwort/Antwort mit DEFAULT_NOINFO
      - return string:	Antwort mit string unter Beruecksichtigung eines
			indent

     Die Strings von 'silent' und 'meldung' werden geparsed.
     Dabei koennen die @...-Tags von replace_personal() verwendet werden,
     Objekt 1 ist this_player(). Ersetzte String am Satzanfang werden
     automatisch gross geschrieben.
     AddInfo() konvertiert die alten Schluesselworte @WER, @WESSEN, @WEM,
     @WEN zu denen von replace_personal().

     Mittels der in <npc.h> definierten Frage DEFAULT_INFO kann eine
     Meldung gesetzt werden, die gegeben werden soll, wenn der Spieler
     etwas fragt, auf das keine Antwort vorgegeben ist (das loest
     SetProp(P_DEFAULT_INFO, <text>) ab).

BEISPIELE
---------
::

     ### eine Standardantwort setzen ###
     AddInfo(DEFAULT_INFO, "starrt Dir boese in die Augen.\n");
     // identisch zu
     SetProp(P_DEFAULT_INFO, "starrt Dir boese in die Augen.\n");

     ### einfache Beispiele, auch mit casebased ###
     AddInfo(({"knete","kohle"}),
	     "sagt: ich habe so etwas nicht.\n");
     AddInfo("geld",
	     "Ich habe zwar kein Geld, aber ... blablabla ...",
	     "sagt: " );
     AddInfo("muenzen",
	     "fluestert: Du willst Geld?\n",
	     0,
	     "fluestert @WEM etwas zu.\n");

     // "frage monster nach geld": alle im Raum hoeren
     //  Das Monster sagt: Ich habe zwar kein Geld, aber ...
     //  Das Monster sagt: ... blablabla ...

     // "frage monster nach muenzen":
     // - der Fragensteller hoert:
     //   "Das Monster fluestert: Du willst Geld?"
     // - alle andere hoeren:
     //   "Das Monster fluestert <Fragenstellernamen> etwas zu."

     ### dynamisch ###
     // ein Prototyp, damit wir die Methode bekannt machen
     static string query_kekse();
     ...
     AddInfo(({"keks","kekse"}),
	     #'query_kekse,		// ein Verweis auf die Funktion
	     "sagt: ");
     ...
     static string query_kekse() {
      if(present("keks"))
       return("Ich hab noch welche. Aetsch!");
      return("Menno. Keine mehr da!");
     }

     // "frage monster nach keks":
     // - wenn es noch Kekse hat, hoeren alle:
     //   "Das Monster sagt: Ich hab noch welche. Aetsch!
     // - sonst:
     //   "Das Monster sagt: "Menno. Keine mehr da!

     ### dynamischer ###
     // ein Prototyp, damit wir die Methode bekannt machen
     static string query_kekse();
     static mixed case_fighting();
     ...
     AddInfo(({"keks","kekse"}),
	     #'query_kekse,"		// ein Verweis auf die Funktion
	     sagt: ",
	     0,				// nicht silent :)
	     #'case_fighting);		// noch ein Funktionsverweis
     ...
     static string query_kekse() {
      if(present("keks"))
       return("Ich hab noch welche. Aetsch!");
      return("Menno. Keine mehr da!");
     }

     static mixed case_fighting() {
      if(InFight())
       return("Keine Zeit fuer Kekse. Muss kaempfen.");
      return 0;
     }

     // "frage monster nach keks":
     // - wenn es kaempft, hoeren alle:
     //   "Das Monster sagt: Keine Zeit fuer Kekse. Muss kaempfen.
     // - sonst, wenn es noch Kekse hat, hoeren alle:
     //   "Das Monster sagt: Ich hab noch welche. Aetsch!
     // - sonst:
     //   "Das Monster sagt: "Menno. Keine mehr da!


     ### dynamisch und komplex ###
     // ein Prototyp, damit wir die Methode bekannt machen
     static string question_gold();
     ...

     // "gold" wird eine Closure auf die Methode question_gold()
     // zugewiesen, ausserdem soll es still bleiben (wir informieren
     // den Restraum selbst)
     AddInfo("gold",#'question_gold,"murmelt: ",1);
     ...

     // los gehts, wir generieren unsere Antwort selbst
     static string question_gold() {
      int money;
      string *y, objstr;
      object o;
      // wieviel Kohle hat der Spieler
      money=this_player()->QueryMoney();
      y=allocate(0);
      // und jetzt suchen wir die Dinge aus Gold
      o=first_inventory(this_player());
      while(o) {
       if(o->QueryMaterial(MAT_GOLD)>0 &&
          strstr(object_name(o),"/obj/money"))
        y+=({o->name(WER,1)});
       o=next_inventory(o);
      }

      // das geht an alle anderen im Raum, silent bietet sich hier
      // nicht an, weil es mehrere Moeglichkeiten gibt
      say(break_string(
       Name(WER,1)+" murmelt "+
       this_player()->name(WEM,1)+
       " etwas zu"+
       ((money || sizeof(y))?
        " und glotzt "+
        this_player()->QueryPronoun(WEN)+" gierig an.":
        "."),78),({this_player()}));

      // und hier die Antwort an den Spieler selbst, mit vielen
      // Verzweigungen fuer dessen Besitztum
      return("Ich hab kein Gold bei mir."+
          ((money || sizeof(y))?
           " Aber du "+
           (money?"hast ja jede Menge Kohle bei dir, so etwa "+money+
            " Muenzen."+
            (sizeof(y)?
             " Ausserdem "+
             ((sizeof(y)==1)?"ist":"sind")+
             " auch noch "+CountUp(y)+" aus Gold.":
             ""):
            (sizeof(y)?" Aber was du so bei dir hast: "+
             CountUp(y)+
             (sizeof(y)==1?" ist":" sind")+
             " aus Gold.":"")):
           ""));
     }

     // "frage monster nach gold"
     // - der Fragesteller hoert zB:
     //   Das Monster murmelt: Ich hab kein Gold bei mir. Aber du hast ja
     //   Das Monster murmelt: jede Menge Kohle bei dir, so etwas <number>
     //   Das Monster murmelt: Muenzen. Ausserdem ist/sind noch <object1>
     //   Das Monster murmelt: und <object2> aus Gold."
     // - die Umstehenden hoeren:
     //   "Das Monster murmelt @WEM etwas zu."
     //   oder
     //   "Das Monster murmelt @WEM etwas zu und glotzt ihn/sie gierig an."

SIEHE AUCH
----------
::

     Verwandt:  AddSpecialInfo(L), RemoveInfo(L)
     Props:     P_PRE_INFO, P_DEFAULT_INFO
     Files:     /std/npc/info.c
     Loggen:    P_LOG_INFO
     Interna:   GetInfoArr, do_frage

7.Apr 2004 Gloinson

