]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/notifications.qh
Notifications: strong references
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / notifications.qh
index 8586a16dc549d89164a4e5e300829cb82966c255..4df13ac90b25606ee884a27591e55f92a7ce6df7 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef NOTIFICATIONS_H
 #define NOTIFICATIONS_H
 
-#include "command/all.qh"
+#include <common/command/all.qh>
 
 #include "constants.qh"
 #include "teams.qh"
@@ -20,9 +20,16 @@ const int MSG_CENTER_CPID = 4; // Kill centerprint message
 const int MSG_MULTI = 5; // Subcall MSG_INFO and/or MSG_CENTER notifications
 const int MSG_CHOICE = 6; // Choose which subcall wrapper to activate
 
+typedef entity Notification;
+
 // negative confirmations
-const int NO_MSG = -12345;  // allows various things to know when no information is added
-const int NOTIF_ABORT = -1234;   // allows Send_Notification to safely abort sending
+/** allows various things to know when no information is added */
+Notification NO_MSG;
+STATIC_INIT(NO_MSG) { NO_MSG = new(Notification); }
+const int NO_MSG_ = -12345;
+/** allows Send_Notification to safely abort sending */
+Notification NOTIF_ABORT;
+STATIC_INIT(NOTIF_ABORT) { NOTIF_ABORT = new(Notification); }
 
 #define EIGHT_VARS_TO_VARARGS_VARLIST \
     VARITEM(1, 0, s1) \
@@ -51,37 +58,52 @@ const int NOTIF_ABORT = -1234;   // allows Send_Notification to safely abort sen
     VARITEM(4, 4, XPD(s1, s2, s3, s4, f1, f2, f3, f4))
 
 void Destroy_All_Notifications();
-void Create_Notification_Entity(
+void Create_Notification_Entity(entity notif,
     float var_default,
     float var_cvar,
     float typeId,
     float nameid,
-    string namestring,
-    int strnum,
-    int flnum,
-    /* MSG_ANNCE */
-    float channel,
-    string snd,
-    float vol,
-    float position,
-    /* MSG_INFO & MSG_CENTER */
-    string args,
-    string hudargs,
-    string icon,
-    float cpid,
-    string durcnt,
-    string normal,
-    string gentle,
-    /* MSG_MULTI */
-    float anncename,
-    float infoname,
-    float centername,
-    /* MSG_CHOICE */
-    float challow_def,
-    float challow_var,
-    float chtype,
-    float optiona,
-    float optionb);
+    string namestring);
+void Create_Notification_Entity_Annce(entity notif,
+                                       float var_cvar,
+                                       string namestring,
+                                       /* MSG_ANNCE */
+                                       float channel,
+                                       string snd,
+                                       float vol,
+                                       float position);
+
+void Create_Notification_Entity_InfoCenter(entity notif,
+                                               float var_cvar,
+                                               string namestring,
+                                               int strnum,
+                                               int flnum,
+                                               /* MSG_INFO & MSG_CENTER */
+                                               string args,
+                                               string hudargs,
+                                               string icon,
+                                               float cpid,
+                                               string durcnt,
+                                               string normal,
+                                               string gentle);
+
+void Create_Notification_Entity_Multi(entity notif,
+                                       float var_cvar,
+                                       string namestring,
+                                       /* MSG_MULTI */
+                                       Notification anncename,
+                                       Notification infoname,
+                                       Notification centername);
+
+void Create_Notification_Entity_Choice(entity notif,
+                                               float var_cvar,
+                                               string namestring,
+                                               /* MSG_CHOICE */
+                                               float challow_def,
+                                               float challow_var,
+                                               int chtype,
+                                               Notification optiona,
+                                               Notification optionb);
 
 void Dump_Notifications(float fh, float alsoprint);
 
@@ -140,9 +162,9 @@ GENERIC_COMMAND(dumpnotifs, "Dump all notifications into notifications_dump.txt"
 void Debug_Notification(string input);
 #endif
 
-void Local_Notification(int net_type, int net_name, ...count);
+void Local_Notification(int net_type, Notification net_name, ...count);
 void Local_Notification_WOVA(
-    float net_type, float net_name,
+    float net_type, Notification net_name,
     float stringcount, float floatcount,
     string s1, string s2, string s3, string s4,
     float f1, float f2, float f3, float f4);
@@ -153,29 +175,31 @@ float prev_soundtime;
 #endif
 
 #ifdef SVQC // SERVER ONLY
-const float NOTIF_ONE = 1;
-const float NOTIF_ONE_ONLY = 2;
-const float NOTIF_TEAM = 3;
-const float NOTIF_TEAM_EXCEPT = 4;
-const float NOTIF_ALL = 5;
-const float NOTIF_ALL_EXCEPT = 6;
+ENUMCLASS(NOTIF)
+    CASE(NOTIF, ONE)
+    CASE(NOTIF, ONE_ONLY)
+    CASE(NOTIF, TEAM)
+    CASE(NOTIF, TEAM_EXCEPT)
+    CASE(NOTIF, ALL)
+    CASE(NOTIF, ALL_EXCEPT)
+ENUMCLASS_END(NOTIF)
 
 void Kill_Notification(
-    float broadcast, entity client,
+    NOTIF broadcast, entity client,
     float net_type, float net_name);
 void Send_Notification(
-    float broadcast, entity client,
-    float net_type, float net_name,
+    NOTIF broadcast, entity client,
+    float net_type, Notification net_name,
     ...count);
 void Send_Notification_WOVA(
-    float broadcast, entity client,
-    float net_type, float net_name,
+    NOTIF broadcast, entity client,
+    float net_type, Notification net_name,
     float stringcount, float floatcount,
     string s1, string s2, string s3, string s4,
     float f1, float f2, float f3, float f4);
 void Send_Notification_WOCOVA(
-    float broadcast, entity client,
-    float net_type, float net_name,
+    NOTIF broadcast, entity client,
+    float net_type, Notification net_name,
     string s1, string s2, string s3, string s4,
     float f1, float f2, float f3, float f4);
 #endif
@@ -244,6 +268,7 @@ float autocvar_notification_show_sprees_center_specialonly = true;
     f2primsec: f2 float primary or secondary selection for weapons
     f3primsec: f3 float primary or secondary selection for weapons
     f1secs: count_seconds of f1
+    f1points: point or points depending on f1
     f1ord: count_ordinal of f1
     f1time: process_time of f1
     f1race_time: mmssss of f1
@@ -302,6 +327,7 @@ string BUFF_NAME(int i);
     ARG_CASE(ARG_CS,        "f2primsec",     (f2 ? _("secondary") : _("primary"))) \
     ARG_CASE(ARG_CS,        "f3primsec",     (f3 ? _("secondary") : _("primary"))) \
     ARG_CASE(ARG_CS,        "f1secs",        count_seconds(f1)) \
+    ARG_CASE(ARG_CS,        "f1points",      (f1 == 1 ? _("point") : _("points"))) \
     ARG_CASE(ARG_CS_SV,     "f1ord",         count_ordinal(f1)) \
     ARG_CASE(ARG_CS,        "f1time",        process_time(2, f1)) \
     ARG_CASE(ARG_CS_SV_HA,  "f1race_time",   mmssss(f1)) \
@@ -318,7 +344,7 @@ string BUFF_NAME(int i);
     ARG_CASE(ARG_CS_SV,     "spree_inf",     (autocvar_notification_show_sprees ? notif_arg_spree_inf(1, input, s2, f2) : "")) \
     ARG_CASE(ARG_CS_SV,     "spree_end",     (autocvar_notification_show_sprees ? notif_arg_spree_inf(-1, "", "", f1) : "")) \
     ARG_CASE(ARG_CS_SV,     "spree_lost",    (autocvar_notification_show_sprees ? notif_arg_spree_inf(-2, "", "", f1) : "")) \
-    ARG_CASE(ARG_CS_SV,     "item_wepname",  WEP_NAME(f1)) \
+    ARG_CASE(ARG_CS_SV,     "item_wepname",  Weapons_from(f1).m_name) \
     ARG_CASE(ARG_CS_SV,     "item_buffname", BUFF_NAME(f1)) \
     ARG_CASE(ARG_CS_SV,     "f3buffname",    BUFF_NAME(f3)) \
     ARG_CASE(ARG_CS_SV,     "item_wepammo",  (s1 != "" ? sprintf(_(" with %s"), s1) : "")) \
@@ -345,7 +371,7 @@ string BUFF_NAME(int i);
 #ifdef CSQC
 string notif_arg_frag_ping(float newline, float fping)
 {
-    if(fping == NO_MSG)
+    if(fping == NO_MSG_)
         return sprintf(CCR(_("%s(^F1Bot^BG)")), (newline ? "\n" : " "));
     else
         return sprintf(CCR(_("%s(Ping ^F1%d^BG)")), (newline ? "\n" : " "), fping);
@@ -623,7 +649,9 @@ entity msg_choice_notifs[NOTIF_CHOICE_MAX];
 .entity nent_optionb;
 
 // networked notification entity values
-.float nent_broadcast;
+#ifdef SVQC
+.NOTIF nent_broadcast;
+#endif
 .entity nent_client;
 .float nent_net_type;
 .float nent_net_name;
@@ -633,259 +661,134 @@ entity msg_choice_notifs[NOTIF_CHOICE_MAX];
 // other notification properties
 .float msg_choice_choices[NOTIF_CHOICE_MAX]; // set on each player containing MSG_CHOICE choices
 
+#define ACVNN(name) autocvar_notification_##name
+
 // initialization error detection
 float notif_error;
 float notif_global_error;
 
-#define MSG_ANNCE_NOTIF(default,name,channel,sound,volume,position) \
+#define MSG_ANNCE_NOTIF(name, default, sound, channel, volume, position) \
+    MSG_ANNCE_NOTIF_(ANNCE_##name, default, sound, channel, volume, position)
+#define MSG_ANNCE_NOTIF_(name, default, sound, channel, volume, position) \
     NOTIF_ADD_AUTOCVAR(name, default) \
-    float name; \
+    Notification name; \
     void RegisterNotification_##name() \
     { \
-        SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_ANNCE_COUNT) \
-        CHECK_MAX_COUNT(name, NOTIF_ANNCE_MAX, NOTIF_ANNCE_COUNT, "MSG_ANNCE") \
-        Create_Notification_Entity( \
-            /* COMMON ======================== */ \
-            default,            /* var_default */ \
-            ACVNN(name),        /* var_cvar    */ \
-            MSG_ANNCE,          /* typeId      */ \
-            name,               /* nameid      */ \
-            strtoupper(#name),  /* namestring  */ \
-            NO_MSG,             /* strnum      */ \
-            NO_MSG,             /* flnum       */ \
-            /* ANNCE ============= */ \
+        int name##_ = 0; \
+        SET_FIELD_COUNT(name##_, NOTIF_FIRST, NOTIF_ANNCE_COUNT) \
+        CHECK_MAX_COUNT(name##_, NOTIF_ANNCE_MAX, NOTIF_ANNCE_COUNT, "MSG_ANNCE") \
+        entity this = name = msg_annce_notifs[name##_ - 1] = new_pure(msg_annce_notification); \
+        Create_Notification_Entity      (this, default, ACVNN(name), MSG_ANNCE, name##_, strtoupper(#name)); \
+        Create_Notification_Entity_Annce(this, ACVNN(name), strtoupper(#name), \
             channel,   /* channel  */ \
             sound,     /* snd      */ \
             volume,    /* vol      */ \
-            position,  /* position */ \
-            /* INFO & CENTER == */ \
-            "",      /* args    */ \
-            "",      /* hudargs */ \
-            "",      /* icon    */ \
-            NO_MSG,  /* cpid    */ \
-            "",      /* durcnt  */ \
-            "",      /* normal  */ \
-            "",      /* gentle  */ \
-            /* MULTI ============= */ \
-            NO_MSG,  /* anncename  */ \
-            NO_MSG,  /* infoname   */ \
-            NO_MSG,  /* centername */ \
-            /* MSG_CHOICE ========== */ \
-            NO_MSG,   /* challow_def */ \
-            NO_MSG,   /* challow_var */ \
-            NO_MSG,   /* chtype      */ \
-            NO_MSG,   /* optiona     */ \
-            NO_MSG);  /* optionb     */ \
+            position); /* position */ \
     } \
     ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
 
-#define MSG_INFO_NOTIF(default,name,strnum,flnum,args,hudargs,icon,normal,gentle) \
+#define MSG_INFO_NOTIF(name, default, strnum, flnum, args, hudargs, icon, normal, gentle) \
+    MSG_INFO_NOTIF_(INFO_##name, default, strnum, flnum, args, hudargs, icon, normal, gentle)
+#define MSG_INFO_NOTIF_(name, default, strnum, flnum, args, hudargs, icon, normal, gentle) \
     NOTIF_ADD_AUTOCVAR(name, default) \
-    int name; \
+    Notification name; \
     void RegisterNotification_##name() \
     { \
-        SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_INFO_COUNT) \
-        CHECK_MAX_COUNT(name, NOTIF_INFO_MAX, NOTIF_INFO_COUNT, "MSG_INFO") \
-        Create_Notification_Entity( \
-            /* COMMON ======================== */ \
-            default,            /* var_default */ \
-            ACVNN(name),        /* var_cvar    */ \
-            MSG_INFO,           /* typeId      */ \
-            name,               /* nameid      */ \
-            strtoupper(#name),  /* namestring  */ \
-            strnum,             /* strnum      */ \
-            flnum,              /* flnum       */ \
-            /* ANNCE =========== */ \
-            NO_MSG,  /* channel  */ \
-            "",      /* snd      */ \
-            NO_MSG,  /* vol      */ \
-            NO_MSG,  /* position */ \
-            /* INFO & CENTER === */ \
+        int name##_ = 0; \
+        SET_FIELD_COUNT(name##_, NOTIF_FIRST, NOTIF_INFO_COUNT) \
+        CHECK_MAX_COUNT(name##_, NOTIF_INFO_MAX, NOTIF_INFO_COUNT, "MSG_INFO") \
+        entity this = name = msg_info_notifs[name##_ - 1] = new_pure(msg_info_notification); \
+        Create_Notification_Entity           (this, default, ACVNN(name), MSG_INFO, name##_, strtoupper(#name)); \
+        Create_Notification_Entity_InfoCenter(this, ACVNN(name), strtoupper(#name), strnum, flnum, \
             args,     /* args    */ \
             hudargs,  /* hudargs */ \
             icon,     /* icon    */ \
-            NO_MSG  /* cpid    */ \
+            NO_MSG_,  /* cpid    */ \
             "",       /* durcnt  */ \
             normal,   /* normal  */ \
-            gentle,   /* gentle  */ \
-            /* MULTI ============= */ \
-            NO_MSG,  /* anncename  */ \
-            NO_MSG,  /* infoname   */ \
-            NO_MSG,  /* centername */ \
-            /* CHOICE ============== */ \
-            NO_MSG,   /* challow_def */ \
-            NO_MSG,   /* challow_var */ \
-            NO_MSG,   /* chtype      */ \
-            NO_MSG,   /* optiona     */ \
-            NO_MSG);  /* optionb     */ \
+            gentle);  /* gentle  */ \
     } \
     ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
 
 .string nent_iconargs;
-#define MULTIICON_INFO(default,name,strnum,flnum,args,hudargs,iconargs,icon,normal,gentle) \
+#define MULTIICON_INFO(name, default, strnum, flnum, args, hudargs, iconargs, icon, normal, gentle) \
+    MULTIICON_INFO_(INFO_##name, default, strnum, flnum, args, hudargs, iconargs, icon, normal, gentle)
+#define MULTIICON_INFO_(name, default, strnum, flnum, args, hudargs, iconargs, icon, normal, gentle) \
     NOTIF_ADD_AUTOCVAR(name, default) \
-    int name; \
+    Notification name; \
     void RegisterNotification_##name() \
     { \
-        SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_INFO_COUNT) \
-        CHECK_MAX_COUNT(name, NOTIF_INFO_MAX, NOTIF_INFO_COUNT, "MSG_INFO") \
-        Create_Notification_Entity( \
-            /* COMMON ======================== */ \
-            default,            /* var_default */ \
-            ACVNN(name),        /* var_cvar    */ \
-            MSG_INFO,           /* typeid      */ \
-            name,               /* nameid      */ \
-            strtoupper(#name),  /* namestring  */ \
-            strnum,             /* strnum      */ \
-            flnum,              /* flnum       */ \
-            /* ANNCE =========== */ \
-            NO_MSG,  /* channel  */ \
-            "",      /* snd      */ \
-            NO_MSG,  /* vol      */ \
-            NO_MSG,  /* position */ \
-            /* INFO & CENTER === */ \
+        int name##_ = 0; \
+        SET_FIELD_COUNT(name##_, NOTIF_FIRST, NOTIF_INFO_COUNT) \
+        CHECK_MAX_COUNT(name##_, NOTIF_INFO_MAX, NOTIF_INFO_COUNT, "MSG_INFO") \
+        entity this = name = msg_info_notifs[name##_ - 1] = new_pure(msg_info_notification); \
+        Create_Notification_Entity           (this, default, ACVNN(name), MSG_INFO, name##_, strtoupper(#name)); \
+        Create_Notification_Entity_InfoCenter(this, ACVNN(name), strtoupper(#name), strnum, flnum, \
             args,     /* args    */ \
             hudargs,  /* hudargs */ \
             icon,     /* icon    */ \
-            NO_MSG  /* cpid    */ \
+            NO_MSG_,  /* cpid    */ \
             "",       /* durcnt  */ \
             normal,   /* normal  */ \
-            gentle,   /* gentle  */ \
-            /* MULTI ============= */ \
-            NO_MSG,  /* anncename  */ \
-            NO_MSG,  /* infoname   */ \
-            NO_MSG,  /* centername */ \
-            /* CHOICE ============== */ \
-            NO_MSG,   /* challow_def */ \
-            NO_MSG,   /* challow_var */ \
-            NO_MSG,   /* chtype      */ \
-            NO_MSG,   /* optiona     */ \
-            NO_MSG);  /* optionb     */ \
-        msg_info_notifs[name - 1].nent_iconargs = iconargs; \
+            gentle);  /* gentle  */ \
+        this.nent_iconargs = iconargs; \
     } \
     ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
 
-#define MSG_CENTER_NOTIF(default,name,strnum,flnum,args,cpid,durcnt,normal,gentle) \
+#define MSG_CENTER_NOTIF(name, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \
+    MSG_CENTER_NOTIF_(CENTER_##name, default, strnum, flnum, args, cpid, durcnt, normal, gentle)
+#define MSG_CENTER_NOTIF_(name, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \
     NOTIF_ADD_AUTOCVAR(name, default) \
-    float name; \
+    Notification name; \
     void RegisterNotification_##name() \
     { \
-        SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_CENTER_COUNT) \
-        CHECK_MAX_COUNT(name, NOTIF_CENTER_MAX, NOTIF_CENTER_COUNT, "MSG_CENTER") \
-        Create_Notification_Entity( \
-            /* COMMON ======================== */ \
-            default,            /* var_default */ \
-            ACVNN(name),        /* var_cvar    */ \
-            MSG_CENTER,         /* typeId      */ \
-            name,               /* nameid      */ \
-            strtoupper(#name),  /* namestring  */ \
-            strnum,             /* strnum      */ \
-            flnum,              /* flnum       */ \
-            /* ANNCE =========== */ \
-            NO_MSG,  /* channel  */ \
-            "",      /* snd      */ \
-            NO_MSG,  /* vol      */ \
-            NO_MSG,  /* position */ \
-            /* INFO & CENTER == */ \
+        int name##_ = 0; \
+        SET_FIELD_COUNT(name##_, NOTIF_FIRST, NOTIF_CENTER_COUNT) \
+        CHECK_MAX_COUNT(name##_, NOTIF_CENTER_MAX, NOTIF_CENTER_COUNT, "MSG_CENTER") \
+        entity this = name = msg_center_notifs[name##_ - 1] = new_pure(msg_center_notification); \
+        Create_Notification_Entity           (this, default, ACVNN(name), MSG_CENTER, name##_, strtoupper(#name)); \
+        Create_Notification_Entity_InfoCenter(this, ACVNN(name), strtoupper(#name), strnum, flnum, \
             args,    /* args    */ \
             "",      /* hudargs */ \
             "",      /* icon    */ \
             cpid,    /* cpid    */ \
             durcnt,  /* durcnt  */ \
             normal,  /* normal  */ \
-            gentle,  /* gentle  */ \
-            /* MULTI ============= */ \
-            NO_MSG,  /* anncename  */ \
-            NO_MSG,  /* infoname   */ \
-            NO_MSG,  /* centername */ \
-            /* CHOICE ============== */ \
-            NO_MSG,   /* challow_def */ \
-            NO_MSG,   /* challow_var */ \
-            NO_MSG,   /* chtype      */ \
-            NO_MSG,   /* optiona     */ \
-            NO_MSG);  /* optionb     */ \
+            gentle); /* gentle  */ \
     } \
     ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
 
-#define MSG_MULTI_NOTIF(default,name,anncename,infoname,centername) \
+#define MSG_MULTI_NOTIF(name, default, anncename, infoname, centername) \
     NOTIF_ADD_AUTOCVAR(name, default) \
-    int name; \
+    Notification name; \
     void RegisterNotification_##name() \
     { \
-        SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_MULTI_COUNT) \
-        CHECK_MAX_COUNT(name, NOTIF_MULTI_MAX, NOTIF_MULTI_COUNT, "MSG_MULTI") \
-        Create_Notification_Entity( \
-            /* COMMON ======================== */ \
-            default,            /* var_default */ \
-            ACVNN(name),        /* var_cvar    */ \
-            MSG_MULTI,          /* typeId      */ \
-            name,               /* nameid      */ \
-            strtoupper(#name),  /* namestring  */ \
-            NO_MSG,             /* strnum      */ \
-            NO_MSG,             /* flnum       */ \
-            /* ANNCE =========== */ \
-            NO_MSG,  /* channel  */ \
-            "",      /* snd      */ \
-            NO_MSG,  /* vol      */ \
-            NO_MSG,  /* position */ \
-            /* INFO & CENTER == */ \
-            "",      /* args    */ \
-            "",      /* hudargs */ \
-            "",      /* icon    */ \
-            NO_MSG,  /* cpid    */ \
-            "",      /* durcnt  */ \
-            "",      /* normal  */ \
-            "",      /* gentle  */ \
-            /* MULTI ================= */ \
+        int name##_ = 0; \
+        SET_FIELD_COUNT(name##_, NOTIF_FIRST, NOTIF_MULTI_COUNT) \
+        CHECK_MAX_COUNT(name##_, NOTIF_MULTI_MAX, NOTIF_MULTI_COUNT, "MSG_MULTI") \
+        entity this = name = msg_multi_notifs[name##_ - 1] = new_pure(msg_multi_notification); \
+        Create_Notification_Entity      (this, default, ACVNN(name), MSG_MULTI, name##_, strtoupper(#name)); \
+        Create_Notification_Entity_Multi(this, ACVNN(name), strtoupper(#name), \
             anncename,   /* anncename  */ \
             infoname,    /* infoname   */ \
-            centername,  /* centername */ \
-            /* CHOICE ============== */ \
-            NO_MSG,   /* challow_def */ \
-            NO_MSG,   /* challow_var */ \
-            NO_MSG,   /* chtype      */ \
-            NO_MSG,   /* optiona     */ \
-            NO_MSG);  /* optionb     */ \
+            centername); /* centername */ \
     } \
     ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
 
-#define ACVNN(name) autocvar_notification_##name
-
-#define MSG_CHOICE_NOTIF(default,challow,name,chtype,optiona,optionb) \
+#define MSG_CHOICE_NOTIF(name, default, challow, chtype, optiona, optionb) \
+    MSG_CHOICE_NOTIF_(CHOICE_##name, default, challow, chtype, optiona, optionb)
+#define MSG_CHOICE_NOTIF_(name, default, challow, chtype, optiona, optionb) \
     NOTIF_ADD_AUTOCVAR(name, default) \
     NOTIF_ADD_AUTOCVAR(name##_ALLOWED, challow) \
-    float name; \
+    Notification name; \
     void RegisterNotification_##name() \
     { \
-        SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_CHOICE_COUNT) \
-        CHECK_MAX_COUNT(name, NOTIF_CHOICE_MAX, NOTIF_CHOICE_COUNT, "MSG_CHOICE") \
-        Create_Notification_Entity( \
-            /* COMMON ======================== */ \
-            default,            /* var_default */ \
-            ACVNN(name),        /* var_cvar    */ \
-            MSG_CHOICE,         /* typeId      */ \
-            name,               /* nameid      */ \
-            strtoupper(#name),  /* namestring  */ \
-            NO_MSG,             /* strnum      */ \
-            NO_MSG,             /* flnum       */ \
-            /* ANNCE =========== */ \
-            NO_MSG,  /* channel  */ \
-            "",      /* snd      */ \
-            NO_MSG,  /* vol      */ \
-            NO_MSG,  /* position */ \
-            /* INFO & CENTER == */ \
-            "",      /* args    */ \
-            "",      /* hudargs */ \
-            "",      /* icon    */ \
-            NO_MSG,  /* cpid    */ \
-            "",      /* durcnt  */ \
-            "",      /* normal  */ \
-            "",      /* gentle  */ \
-            /* MULTI ============= */ \
-            NO_MSG,  /* anncename  */ \
-            NO_MSG,  /* infoname   */ \
-            NO_MSG,  /* centername */ \
-            /* CHOICE ============================================= */ \
+        int name##_ = 0; \
+        SET_FIELD_COUNT(name##_, NOTIF_FIRST, NOTIF_CHOICE_COUNT) \
+        CHECK_MAX_COUNT(name##_, NOTIF_CHOICE_MAX, NOTIF_CHOICE_COUNT, "MSG_CHOICE") \
+        entity this = name = msg_choice_notifs[name##_ - 1] = new_pure(msg_choice_notification); \
+        Create_Notification_Entity       (this, default, ACVNN(name), MSG_CHOICE, name##_, strtoupper(#name)); \
+        Create_Notification_Entity_Choice(this, ACVNN(name), strtoupper(#name), \
             challow,                                 /* challow_def */ \
             autocvar_notification_##name##_ALLOWED,  /* challow_var */ \
             chtype,                                  /* chtype      */ \