comm_beep(): Piepston selber ausgeben.

comm_beep() prueft die Erlaubnis von Piepstoenen fuer die
msg_action und ob die minimale Zeit zwischen zwei Piepstoenen
abgelaufen ist und gibt ggf. den Piepston aus.

Ausserdem nur Piepsen, wenn MSG_ALERT vorliegt, keine
impliziten Annahmen machen und implizites MSG_ALERT
annehmen, wenn die Nachricht von einem interactive kommt und die
msg_action passt.

Ein P_MESSAGE_BEEP==0 schaltet in Zukunft nicht mehr global ab
(dafuer gibts ja AL_NO_SOUND), sondern ermoeglicht einen
Piepston bei jeder Nachricht.

Das BEL-Zeichen aus ASCII zum Piepsen wird jetzt per
binary_message() gesendet anstatt an den String angehaengt.

Ausserdem comm_beep() noch etwas restrukturiert.

Change-Id: I386434cee83c565be8375e5d3e3ed2133793aaba
diff --git a/std/player/comm.c b/std/player/comm.c
index 716f0af..eadc6bc 100644
--- a/std/player/comm.c
+++ b/std/player/comm.c
@@ -532,20 +532,43 @@
      (name == ignore[0] && member(ignore[1..], verb) != -1));
 }
 
-private int comm_beep(string msg_action)
+private void comm_beep(string msg_action)
 {
-  if (QueryProp(P_ALERT) & AL_NO_SOUND) return 0; // kein ton
+  // Wenn Alerts komplett abgeschaltet sind, gibts nix.
+  int alert_config = ({int})QueryProp(P_ALERT);
+  if (alert_config & AL_NO_SOUND)
+    return; // kein ton
+  // und maximal alle P_MESSAGE_BEEP Sekunden aufmerksam machen; bei 0s ist
+  // jedes Mal erlaubt.
   int beep_interval=({int})QueryProp(P_MESSAGE_BEEP);
-  if(beep_interval && ((time()-last_beep_time) > beep_interval) &&
-    ((msg_action == MA_TELL && QueryProp(P_ALERT) & MB_TELL) ||
-    (msg_action == MA_SAY && QueryProp(P_ALERT) & MB_SAY) ||
-    (msg_action == MA_CHANNEL && QueryProp(P_ALERT) & MB_CHANNEL) ||
-    (msg_action == MA_SHOUT && QueryProp(P_ALERT) & MB_SHOUT)))
+  if ((time()-last_beep_time) < beep_interval)
+    return;
+  int required;
+  switch(msg_action)
   {
-    last_beep_time=time();
-    return 1;
+      case MA_TELL:
+        required |= MB_TELL;
+        break;
+      case MA_SAY:
+        required |= MB_SAY;
+        break;
+      case MA_CHANNEL:
+        required |= MB_CHANNEL;
+        break;
+      case MA_SHOUT:
+        required |= MB_SHOUT;
+        break;
+      default:
+        // Alle anderen Aktionen, die keine gesonderten Aktionsfilter haben
+        required |= MB_MISC;
+        break;
   }
-  return 0;
+  // wenn in alert min. ein notwendiges Flag drin ist darf gepiepst werden
+  if (required & alert_config)
+  {
+    last_beep_time = time();
+    binary_message(b"\a", 1);
+  }
 }
 
 private varargs void add_to_tell_history( string uid, int sent, int recv,
@@ -917,13 +940,16 @@
   if(te && QueryProp(P_AWAY))
     msg = msg[0..<2]+" [" + strftime("%H:%M",time()) + "]\n";
 
-  if((!objectp(sender) || sender != ME) &&
-    ((flag & MSGFLAG_SAY) && comm_beep(MA_SAY) ||
-    (flag & MSGFLAG_TELL) && comm_beep(MA_TELL) ||
-    (flag & MSGFLAG_CHANNEL) && comm_beep(MA_CHANNEL) ||
-    (flag & MSGFLAG_SHOUT) && comm_beep(MA_SHOUT)))
+  if(!objectp(sender) || sender != ME)
   {
-    msg=MESSAGE_BEEP+msg;
+    if (flag & MSGFLAG_SAY)
+      comm_beep(MA_SAY);
+    else if (flag & MSGFLAG_TELL)
+      comm_beep(MA_TELL);
+    else if (flag & MSGFLAG_CHANNEL)
+      comm_beep(MA_CHANNEL);
+    else if (flag & MSGFLAG_SHOUT)
+      comm_beep(MA_SHOUT);
   }
   efun::tell_object(ME, msg);
   return MESSAGE_OK;
@@ -974,38 +1000,40 @@
 }
 
 
-private int filter_flags(int flag, string text)
+private int _alert_filter_flags(int flag, string text)
 {
   return (flag & QueryProp(P_ALERT));
 }
 
-static int _msg_beep(string str) {
-  int beep_interval = to_int(str);
-  if(beep_interval > 0)
+static int _msg_beep(string str)
+{
+  int beep_interval;
+
+  notify_fail(
+    "Syntax:\n"
+    "- klingelton <1 bis 3600 Sekunden>\n"
+    "- klingelton aus\n"
+    "- klingelton ein\n"
+    "- klingelton <+/-><tm / sag / ebenen / ruf / erwaehnung / sonstige / alle / >\n");
+
+  if(!sizeof(str))
+    return 0;
+  if (regmatch(str,"^[[:alpha:]]", RE_PCRE))
   {
-    SetProp(P_MESSAGE_BEEP,beep_interval);
-  }
-  else if (stringp(str))
-  {
-    notify_fail(
-      "Syntax:\n"
-      "- klingelton <1 bis 3600 Sekunden>\n"
-      "- klingelton aus\n"
-      "- klingelton <+/-><tm / sag / ebenen / ruf / alle>\n");
     if (str=="aus")
-      SetProp(P_MESSAGE_BEEP,0);
+          SetProp(P_ALERT, QueryProp(P_ALERT) | AL_NO_SOUND);
+    else if (str=="ein")
+          SetProp(P_ALERT, QueryProp(P_ALERT) & ~AL_NO_SOUND);
     else
     {
       mapping flags = ([
-        "tm": MB_TELL,
-        "teilemit": MB_TELL,
-        "sag": MB_SAY,
-        "sage": MB_SAY,
-        "ebene": MB_CHANNEL,
-        "ebenen": MB_CHANNEL,
-        "ruf": MB_SHOUT,
-        "rufe": MB_SHOUT,
-        "alle": MB_ALL]);
+        "tm": MB_TELL, "teilemit": MB_TELL,
+        "sag": MB_SAY, "sage": MB_SAY,
+        "ebene": MB_CHANNEL, "ebenen": MB_CHANNEL,
+        "ruf": MB_SHOUT, "rufe": MB_SHOUT,
+        "sonstige": MB_MISC, "sonstiges": MB_MISC,
+        "alle": MB_ALL, "alles": MB_ALL,
+        ]);
       foreach(string part : explode(str, " ") - ({""}))
       {
         if(!(part[1..] in flags)) continue;
@@ -1022,14 +1050,23 @@
       }
     }
   }
+  else
+  {
+    beep_interval = to_int(str);
+    if(beep_interval >= 0)
+    {
+        SetProp(P_MESSAGE_BEEP, beep_interval);
+    }
+  }
 
   beep_interval=({int})QueryProp(P_MESSAGE_BEEP);
   mapping text = ([
     MB_SAY: "sage",
     MB_TELL: "teile mit",
     MB_CHANNEL: "Ebenenmeldungen",
-    MB_SHOUT: "rufe"]);
-  string types = CountUp(map(filter(m_indices(text), #'filter_flags), text));
+    MB_SHOUT: "rufe",
+    MB_MISC: "sonstige",]);
+  string types = CountUp(map(filter(m_indices(text), #'_alert_filter_flags), text));
   if(!sizeof(types))
   {
     types = "nichts";
@@ -1037,7 +1074,9 @@
   ReceiveNotify(
     "Klingelton bei "
     + types
-    + (beep_interval ? ", alle " + beep_interval + " Sekunden." : ", nie."),
+    + (beep_interval ? ", alle " + beep_interval + " Sekunden." : ", immer.")
+    + (QueryProp(P_ALERT) & AL_NO_SOUND ? " Allerdings sind Toene insgesamt "
+         "bei Dir abgeschaltet. (\'hilfe ton\')" : ""),
     query_verb());
   return 1;
 }
@@ -1993,11 +2032,8 @@
     }
   }
 
-  if((flags & MSG_ALERT && !(QueryProp(P_ALERT) & AL_NO_SOUND)) ||
-    (interactive(origin) && origin != ME && comm_beep(msg_action)))
-  {
-    msg += MESSAGE_BEEP;
-  }
+  if ((msg_type & MSG_ALERT))
+    comm_beep(msg_action);
 
   // Ausgabenachricht bauen und an den Spieler senden.
   if (flags & MSG_DONT_WRAP)