SYNOPSIS
        void say(string str);
        void say(string str, object exclude);
        void say(string str, object *excludes);

        void say(mixed *|mapping|struct|object msg);
        void say(mixed *|mapping|struct|object msg, object exclude);
        void say(mixed *|mapping|struct|object msg, object *excludes);

BESCHREIBUNG
        Es bestehen zwei Hauptanwendungen fuer say():

        Wenn das erste Argument ein String <str> ist, wird er an alle
        lebendigen Objekte im aktuellen Raum gesendet, ausser zum Objekt,
        das die Funktion aufgerufen hat.

        Wenn das erste Argument ein nicht-String <msg> ist, wird die Lfun
        catch_msg() in allen lebendigen Objekt im Raum aufgerufen, ausser im
        Objekt, das say() aufgerufen hat. Der Wert <msg> wird als erstes
        Argument an catch_msg() uebergeben, das aufrufende Objekt als zweites
        Argument.

        MERKE: Wenn die Lfun catch_msg() den Wert <msg> veraendert, erhalten
        alle nachfolgenden Objekte das veraenderte <msg>.

        Wird der Efun say() ein zweites Argument angegeben, kann man andere
        Objekte als nur das aufrufende Objekt ausschliessen. Wenn das zweite
        Argument ein einzelnes Objekt <exclude> ist, werden das aufrufende
        Objekt und <exclude> von der Meldung ausgeschlossen. Wenn das zweite
        Argument ein Array <excludes> ist, werden alle Objekte aus dieser
        Liste zusaetzlich zum aufrufenden Objekt als Empfaenger von say()
        ausgeschlossen.

        Das aufrufende Objekt wird nach folgenden Regeln bestimmt:
          - Wenn say() aus einem lebendigen Objekt aufgerufen wird, gilt
            dieses als das aufrufende Objekt.
          - Wenn say() aus einem nicht-lebendigen Objekt als Resultat einer
            Handlung eines Benutzers aufgerufen wird (das heisst,
            this_player() ist gueltig), gilt this_player() als aufrufendes
            Objekt.
          - In allen anderen Faellen gilt das Objekt, das say() aufgerufen
            hat, als aufrufendes Objekt.

BEISPIELE
        Folgende Aufrufe sind gleich, wenn sie aus einem nicht lebendigen
        Objekt aufgerufen werden:

            say("Hi!\n");
            say("Hi!\n", this_player());

        Das folgende Beispiel zeigt, wie say() zusammen mit catch_tell()
        funktioniert. Das zweite Objekt darf nicht lebendig sein, sodass
        write() an den aktuellen Benutzer geht.

        Objekt 1 (living):
            void catch_tell(string str)
            {
                write("Empfangen: "+str+"\n");
            }

        Objekt 2 (nicht living):
            void func()
            {
                ...
                say("HiHo!\n");
                ...
            }

        Ein etwas komplexeres Beispiel zeigt das Zusammenspiel von say()
        und catch_msg(). Auch hier wird ein nicht-lebendiges Objekt
        verwendet, das die Nachricht ausgibt, sodass das 'wer' in
        catch_msg() auf den aktuellen Benutzer zeigt.

        Object 1 (living):
            void catch_msg(mixed *arr, object who)
            {
                int i;
                if(!arr) return;
                for(i=0;i<sizeof(arr);i++)
                    tell_object(who, (stringp(arr[i]) ? arr[i] : "-/-")+"\n");
            }

        Object 2 (nicht living):
            void func()
            {
                ...
                say( ({ "Hello", "there!" }) );
                ...
            }

ANMERKUNG
        Wenn die Lfun catch_msg() den Wert <msg> veraendert, erhalten alle
        nachfolgenden Objekte das veraenderte <msg>.

GESCHICHTE
        LDMud 3.3.686 erlaubt die Verwendung eines mapping/struct/object als
        zweites Argument.

SIEHE AUCH
        write(E), tell_object(E), tell_room(E)
