ReceiveMsg()

public varargs int ReceiveMsg(string msg, int msg_typ, string msg_action,
                              string msg_prefix, mixed origin)

DEFINIERT IN:
    /std/living/comm.c
    /std/npc/comm.c
    /std/player/comm.c
    /std/room/items.c

ARGUMENTE:
    string msg
      String mit der uebermittelten Nachricht. Muss nicht umgebrochen sein,
      da ReceiveMsg() das ebenfalls erledigt.
    int msg_typ
      Nachrichtentyp(en) fuer Filterung und Flags fuer Behandlung/Umbruch.
      Siehe unten fuer mit | kombinierbare Konstanten.
    string msg_action (optional)
      Ausloesende Aktion, wird auch fuer Ignorieren verwendet.
      Default ist query_verb(). Siehe unten fuer alternative Konstanten.
    string msg_prefix (optional)
      String, welcher ggf. im break_string() als indent verwendet wird.
      Default ist 0 (kein Indent)
    mixed origin (<object>) (optional)
      Das die Meldung ausloesende Objekt, wird fuer Ignorieren verwendet.
      Default: previous_object()

BESCHREIBUNG:
    ReceiveMsg() wird benutzt, um einem Lebewesen eine Nachricht zu senden.
    Dabei ruft es das sonst uebliche tell_object() fuer Spieler bzw.
    catch_tell() im NPC auf.

    Gerade fuer Nachrichten an Spieler bietet die Methode weitere Features,
    die bisher sonst haendisch zu implementieren waren:
    1) Pruefung auf Empfangbarkeit, je nach 'msg_typ', zB
       MT_LOOK nur an Nichtblinde
       MT_LISTEN nur an Nichttaube
       MT_DEBUG nur an Magier/Testspieler
    2) Pruefen auf Ignorieren von
       - Aktion ('msg_action')
         - mit 'msg_action' || query_verb()
       - Urheber ('origin')
         - fuer sendende Spieler mit origin->query_realname()
         - fuer sendende NPCs mit origin->Name(RAW))
    3) Speicherung in der tmhist (Typ MT_COMM)
    4) Speicherung im Kobold (Typ MT_COMM + aktiver Kobold)
    5) Umbrechen unter Beruecksichtigung von indent, 'msg_typ'-Flags
       fuer Umbruch und P_PREPEND_BS

    Raeume definieren standardmaessig ebenfalls ein ReceiveMsg(), welches in
    jedem Objekt im Raum ReceiveMsg() mit den uebergebenen Argumenten aufruft.
    In diesem Fall ist der Rueckgabe der kleinste von allen gerufenen
    ReceiveMsg() zurueckgelieferte Wert.
    
RUeCKGABEWERT:
    > 0 fuer Erfolg, < 0 fuer Misserfolg, s.u.
    MSG_DELIVERED    bei erfolgreicher Zustellung
    MSG_BUFFERED     bei Zwischenspeicherung durch den Kobold

    MSG_FAILED       nicht naeher spezifizierter Fehler bei Zustellung
    MSG_IGNORED      Nachricht wurde ignoriert (Absender, origin)
    MSG_VERB_IGN     Nachricht wurde ignoriert (Kommandoverb, msg_action)
    MSG_MUD_IGN      Absendendes Mud wurde ignoriert.
    MSG_SENSE_BLOCK  Passende Sinne des Empfaenger sind blockiert (z.B.
                     blind, taub)
    MSG_BUFFER_FULL  Kobold kann sich nichts mehr merken

BEMERKUNGEN:
    Fuer saemtliche Alternativmeldungen im Falle einer nicht erfolgreich
    zugestellten Nachricht ist der Aufrufer von ReceiveMsg() verantwortlich.

    NPCs:
    * ReceiveMsg() ruft zwecks Abwaertskompatibilitaet catch_tell() auf
    * empfohlen ist, in NPCs nun ReceiveMsg() zu ueberschreiben.
      * catch_tell() muss weiterhin fuer andere tell_object()
        ueberschrieben  werden

BEISPIELE:
    #1.1 Nachricht an einen Spieler, zB in der Wueste
    this_player()->ReceiveMsg("Die Sonne brennt dir auf den Kopf.",
                              MT_FEEL|MT_LOOK);

    #1.2 Nachricht an einen Spieler von einem NPC mit Indent
    // bei aktivem Editor+Kobold landet dieser Text auch im Kobold
    this_player()->ReceiveMsg("Du haust ja ganz schoen rein!",
                              MT_COMM|MT_FAR|MSG_DONT_STORE,
                              MA_TELL,
                              "Arkshat teilt dir mit: ");

    #1.3 Nachricht an einen Spieler mit Fallback-Kaskade
    // Achtung, bei MT_COMM oder Ignorieren gibt es natuerlich auch
    // Misserfolgs-Rueckgaben. Bei einem normalen Kommando wie diesem
    // hier ist das unproblematisch und daher sinnvoll:
    if(this_player()->ReceiveMsg(
         "Du drueckst den Knopf und es oeffnet sich knirschend "
         "ein kleines Fach in der Wand.", MT_LOOK) < MSG_DELIVERED &&
       this_player()->ReceiveMsg(
         "Du drueckst den Knopf und irgend etwas scheint sich "
         "knirschend zu oeffnen. Das Geraeusch kam von der Wand.",
         MT_LISTEN) < MSG_DELIVERED) // leider blind UND taub ... also:
      this_player()->ReceiveMsg(
        "Du drueckst den Knopf und irgend etwas scheint zu passieren, "
        "aber leider siehst und hoerst du nichts.", MT_FEEL);


    #2.1 Im NPC als Empfaenger auf ein TM reagieren
    public varargs int ReceiveMsg(string msg, int msg_typ, string msg_action,
                                  string msg_prefix, mixed origin) {
      int ret = MSG_DELIVERED;  // Default

      // eine OOC-Kommunikation?
      if(msg_typ&MT_COMM) {
        if(strstr(msg, "hilfe")>=0)
          if(environment(origin)==environment()) {
            origin->ReceiveMsg("Ich werd dir gleich helfen!",
                               MT_COMM|MSG_DONT_STORE, MA_TELL,
                               "Arkshat teilt dir mit: ");
          } else {
            origin->ReceiveMsg("Hilf dir selbst, dann hilft dir Gott!",
                               MT_COMM|MT_FAR|MSG_DONT_STORE,
                               MA_TELL,
                               "Arkshat teilt dir mit: ");
          }
        else if(...)
        [...]
      } else if(msg_typ&MT_LISTEN && msg_action==MA_SAY) {
        [...]
      }

      return ret;
    }


    #3.1 als Sender an viele, Variante mit eigenem filter
    // Achtung: siehe 3.3. send_room() loest vieles.
    // Living nickt nur seinen Nichtgegnern zu
    object *all = filter(all_inventory(environment(this_player())),
                         #'living) - ({this_player()});
    all -= this_player()->PresentEnemies();
    all->ReceiveMsg(this_player()->Name()+
                    " nickt dir verstohlen zu und scheint bereit.",
                    MT_LOOK, MA_EMOTE);

    #3.2 als Sender an viele, Variante mit einzelnem Iterieren
    // Achtung: siehe 3.3. send_room() loest vieles.
    // Living trinkt etwas, jeder im Raum soll es sehen oder hoeren
    object ob = first_inventory(environment(this_player()));
    do {
      if(living(ob) && ob!=this_player())
        ob->ReceiveMsg(this_player()->Name()+" trinkt einen Schnaps aus.",
                       MT_LOOK|MT_LISTEN,
                       MA_DRINK);
      ob = next_inventory(ob);
    } while(ob);

    #3.3 als Sender an viele, Variante mit send_room
    // Living gruesst seine Freunde
    // send_room() ruft ReceiveMsg mit allen entsprechenden Parametern
    object *exclude = this_player()->PresentEnemies();
    send_room(this_object(),
              this_player()->Name()+" gruesst dich.",
              MT_LOOK|MT_LISTEN,
              MA_EMOTE,
              0,
              exclude);

    #3.4 als Sender an viele mit send_room und ReceiveMsg()
    // Living gruesst seine Freunde, seine Feinde sehen das
    // send_room() ruft ReceiveMsg mit allen entsprechenden Parametern
    object *exclude = this_player()->PresentEnemies();
    send_room(this_object(),
              this_player()->Name()+" gruesst dich.",
              MT_LOOK|MT_LISTEN, MA_EMOTE, 0, exclude);
    exclude->ReceiveMessage(
      this_player()->Name()+" gruesst, aber nicht dich.",
      MT_LOOK|MT_LISTEN, MA_EMOTE);

KONSTANTEN FUER PARAMETER:
    Saemtlich in "/sys/living/comm.h". Hier nicht notwendigerweise
    immer aktuell oder vollstaendig.

    <msg_typ>
      MT_UNKNOWN      unspez. Nachrichtentyp (nicht verwenden). Es wird
                      versucht, aufgrund <msg_action> den Typ zu erraten.
      MT_LOOK         alles, was man sieht
      MT_LISTEN       alles, was man hoert
      MT_FEEL         alles, was man fuehlt
      MT_TASTE        alles, was man schmeckt
      MT_SMELL        alles, was man riecht
      MT_MAGIC        alle sonstigen (uebersinnlichen) Wahrnehmungen
      MT_NOTIFICATION Statusmeldungen, Kommandobestaetigungen
      MT_COMM         alle OOC-Kommunikation, d.h. nicht durch o.g. Sinne
                      abgedeckt.
      MT_FAR          alles, was aus der Ferne / einem anderen Raum kommt.
                      muss mit min. einem anderen Typ kombiniert werden
      MT_DEBUG        Debugmeldungen, sehen nur Magier im Magiermodus
      MT_NEWS         Mails & MPA

      MSG_DONT_BUFFER Nachricht darf nicht im Kobold gespeichert werden
      MSG_DONT_STORE  Nachricht darf nicht in die Comm-History
      MSG_DONT_WRAP   Nachricht nicht per break_string umbrechen
      MSG_DONT_IGNORE Nachricht kann nicht ignoriert werden

      MSG_BS_LEAVE_LFS    wie BS_LEAVE_MY_LFS fuer break_string()
      MSG_BS_SINGLE_SPACE wie BS_SINGLE_SPACE fuer break_string()
      MSG_BS_BLOCK        wie BS_BLOCK fuer break_string()
      MSG_BS_NO_PARINDENT wie BS_NO_PARINDENT fuer break_string()
      MSG_BS_INDENT_ONCE  wie BS_INDENT_ONCE fuer break_string()
      MSG_BS_PREP_INDENT  wie BS_PREPEND_INDENT fuer break_string()

    <msg_action> (optional)
      MA_UNKNOWN     Unspez. Aktion. Es wird der Default query_verb()
                     benutzt bzw. versucht, die Aktion zu erraten.
      MA_PUT         Jemand legt etwas hin und gibt jemanden etwas
      MA_TAKE        Jemand nimmt etwas
      MA_MOVE_IN     Jemand betritt den Raum
      MA_MOVE_OUT    Jemand verlaesst den Raum
      MA_MOVE        Jemand bewegt sich 
      MA_FIGHT       Jemand kaempft
      MA_WIELD       Jemand zueckt eine Waffe
      MA_UNWIELD     Jemand steckt eine Waffe weg
      MA_WEAR        Jemand zieht etwas an
      MA_UNWEAR      Jemand zieht etwas aus
      MA_EAT         Jemand isst etwas
      MA_DRINK       Jemand trinkt etwas
      MA_SPELL       Jemand wirkt einen Spell
      MA_LOOK        Jemand sieht etwas an, untersucht etwas
      MA_LISTEN      Jemand horcht oder lauscht an etwas
      MA_FEEL        Jemand betastet etwas
      MA_SMELL       Jemand schnueffelt herum
      MA_SENSE       Jemand macht eine uebersinnliche Wahrnehmung
      MA_READ        Jemand liest etwas
      MA_USE         Jemand benutzt etwas
      MA_SAY         Jemand sagt etwas
      MA_REMOVE      Etwas verschwindet
      // MA_CHAT        Chatkrams (z.B. teile-mit, Teamkampfchat)
      MA_CHANNEL     Ebenen
      MA_EMOTE       (r)Emotes, Soulverben (remotes mit Typ MT_COMM|MT_FAR)
      MA_SHOUT       Rufen (nicht: shout()!)
      MA_SHOUT_SEFUN Rufen ueber shout(SE)

SIEHE AUCH:
    Verwandt: send_room(SE)
    Lfuns:    TestIgnore(L)
    Efuns:    tell_object(E), catch_tell(L), catch_msg(L)
              query_verb(E), query_once_interactive(E), break_string(SE)

13.03.2016, Zesstra

