]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Notifications: register
authorTimePath <andrew.hardaker1995@gmail.com>
Sat, 5 Mar 2016 05:10:26 +0000 (16:10 +1100)
committerTimePath <andrew.hardaker1995@gmail.com>
Sat, 5 Mar 2016 05:13:03 +0000 (16:13 +1100)
qcsrc/common/command/generic.qc
qcsrc/common/notifications.inc
qcsrc/common/notifications.qc
qcsrc/common/notifications.qh

index 5b53592831e8832154eea0220e4cace928af910d..04fbc445da76a203231e3fee139bc6ec01675aaa 100644 (file)
@@ -388,6 +388,11 @@ void GenericCommand_restartnotifs(float request)
                case CMD_REQUEST_COMMAND:
                {
                        #ifndef MENUQC
+                       int NOTIF_ANNCE_COUNT   = 0; FOREACH(Notifications, it.nent_type == MSG_ANNCE,   { ++NOTIF_ANNCE_COUNT;  });
+                       int NOTIF_INFO_COUNT    = 0; FOREACH(Notifications, it.nent_type == MSG_INFO,    { ++NOTIF_INFO_COUNT;   });
+                       int NOTIF_CENTER_COUNT  = 0; FOREACH(Notifications, it.nent_type == MSG_CENTER,  { ++NOTIF_CENTER_COUNT; });
+                       int NOTIF_MULTI_COUNT   = 0; FOREACH(Notifications, it.nent_type == MSG_MULTI,   { ++NOTIF_MULTI_COUNT;  });
+                       int NOTIF_CHOICE_COUNT  = 0; FOREACH(Notifications, it.nent_type == MSG_CHOICE,  { ++NOTIF_CHOICE_COUNT; });
                        LOG_INFOF(
                                strcat(
                                        "Restart_Notifications(): Restarting %d notifications... ",
index cdb6375ecae1edfb78d12043c6ef3e7a1a2f1f1e..140b363094021e8b3066648aacb98600f37406ec 100644 (file)
     MULTITEAM_INFO##teams(prefix, default, strnum, flnum, args, hudargs, icon, normal, gentle)
 
 // MSG_INFO_NOTIFICATIONS
-    MSG_INFO_NOTIF(CONNECTING,                              1,  1, 0, "s1", "",     "",     _("^BG%s^BG is connecting..."), "")
-
     MSG_INFO_NOTIF(CHAT_NOSPECTATORS,                       2,  0, 0, "", "",       "",     _("^F4NOTE: ^BGSpectator chat is not sent to players during the match"), "")
 
     MULTITEAM_INFO(CTF_CAPTURE, 4,                          1,  1, 0, "s1", "s1",                       "notify_%s_captured",       _("^BG%s^BG captured the ^TC^TT^BG flag"), "")
     MSG_INFO_NOTIF(ITEM_WEAPON_PRIMORSEC,                   0,  0, 3, "item_wepname f2primsec f3primsec", "",       "",     _("^F1%s %s^BG is unable to fire, but its ^F1%s^BG can"), "")
     MSG_INFO_NOTIF(ITEM_WEAPON_UNAVAILABLE,                 0,  0, 1, "item_wepname", "",                           "",     _("^F1%s^BG is ^F4not available^BG on this map"), "")
 
+    MSG_INFO_NOTIF(CONNECTING,                              1,  1, 0, "s1", "",         "",     _("^BG%s^BG is connecting..."), "")
     MSG_INFO_NOTIF(JOIN_CONNECT,                            2,  1, 0, "s1", "",         "",     _("^BG%s^F3 connected"), "")
     MULTITEAM_INFO(JOIN_CONNECT_TEAM, 4,                    2,  1, 0, "s1", "",         "",     _("^BG%s^F3 connected and joined the ^TC^TT team"), "")
     MSG_INFO_NOTIF(JOIN_PLAY,                               1,  1, 0, "s1", "",         "",     _("^BG%s^F3 is now playing"), "")
index acde91a893af33212d4d65ecae58520e5c55bc14..92207d844488083cc01f7b3aeed19a078abe2166 100644 (file)
@@ -162,14 +162,6 @@ void Destroy_Notification_Entity(entity notif)
 
 void Destroy_All_Notifications()
 {
-       #define DESTROY_LOOP(type,count) MACRO_BEGIN { \
-               for (int i = 1; i <= count; ++i) { \
-                       Notification notif = Get_Notif_Ent(type, i); \
-                       if (!notif) { backtrace("Destroy_All_Notifications(): Missing notification entity!\n"); return; } \
-                       Destroy_Notification_Entity(notif); \
-               } \
-       } MACRO_END
-
        // kill all networked notifications and centerprints
        #ifdef SVQC
        Kill_Notification(NOTIF_ALL, NULL, 0, 0);
@@ -178,12 +170,7 @@ void Destroy_All_Notifications()
        #endif
 
        // kill all real notification entities
-       DESTROY_LOOP(MSG_ANNCE, NOTIF_ANNCE_COUNT);
-       DESTROY_LOOP(MSG_INFO, NOTIF_INFO_COUNT);
-       DESTROY_LOOP(MSG_CENTER, NOTIF_CENTER_COUNT);
-       DESTROY_LOOP(MSG_MULTI, NOTIF_MULTI_COUNT);
-       DESTROY_LOOP(MSG_CHOICE, NOTIF_CHOICE_COUNT);
-       #undef DESTROY_LOOP
+       FOREACH(Notifications, true, { Destroy_Notification_Entity(it); });
 }
 
 string Process_Notif_Line(
@@ -414,7 +401,6 @@ void Create_Notification_Entity(entity notif,
        float var_default,
        float var_cvar,
        int typeId,
-       int nameid,
        string namestring)
 {
        // =====================
@@ -423,7 +409,6 @@ void Create_Notification_Entity(entity notif,
        notif.nent_default = var_default;
        notif.nent_enabled = (var_cvar >= 1);
        notif.nent_type = typeId;
-       notif.nent_id = nameid;
        notif.nent_name = strzone(namestring);
 
        // Other pre-notif-setup requisites
@@ -781,15 +766,15 @@ void Create_Notification_Entity_Choice(entity notif,
 #ifdef SVQC
 void Notification_GetCvars()
 {
-       for (int i = 0; i <= NOTIF_CHOICE_COUNT; ++i)
-       {
+       int idx = 0;
+       FOREACH(Notifications, it.nent_type == MSG_CHOICE, {
                GetCvars_handleFloat(
                        get_cvars_s,
                        get_cvars_f,
-                       msg_choice_choices[i],
-                       sprintf("notification_%s", msg_choice_notifs[i].nent_name)
+                       msg_choice_choices[idx++],
+                       sprintf("notification_%s", it.nent_name)
                );
-       }
+       });
 }
 #endif
 
@@ -849,62 +834,47 @@ void Dump_Notifications(int fh, bool alsoprint)
        // This is not necessary, and does not matter if they vary between config versions,
        // it is just a semi-helpful tool for those who want to manually change their user settings.
 
+       int NOTIF_ANNCE_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_ANNCE, { ++NOTIF_ANNCE_COUNT; });
        NOTIF_WRITE(sprintf("\n// MSG_ANNCE notifications (count = %d):\n", NOTIF_ANNCE_COUNT));
-       for (int i = 1; i <= NOTIF_ANNCE_COUNT; ++i)
-       {
-               Notification e = Get_Notif_Ent(MSG_ANNCE, i);
-               if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; }
-
-               NOTIF_WRITE_ENTITY(e,
+       FOREACH(Notifications, it.nent_type == MSG_ANNCE, {
+               NOTIF_WRITE_ENTITY(it,
                        "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
                );
-       }
+       });
 
+       int NOTIF_INFO_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_INFO, { ++NOTIF_INFO_COUNT; });
        NOTIF_WRITE(sprintf("\n// MSG_INFO notifications (count = %d):\n", NOTIF_INFO_COUNT));
-       for (int i = 1; i <= NOTIF_INFO_COUNT; ++i)
-       {
-               Notification e = Get_Notif_Ent(MSG_INFO, i);
-               if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; }
-
-               NOTIF_WRITE_ENTITY(e,
+       FOREACH(Notifications, it.nent_type == MSG_INFO, {
+               NOTIF_WRITE_ENTITY(it,
                        "0 = off, 1 = print to console, "
                        "2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
                );
-       }
+       });
 
+       int NOTIF_CENTER_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_CENTER, { ++NOTIF_CENTER_COUNT; });
        NOTIF_WRITE(sprintf("\n// MSG_CENTER notifications (count = %d):\n", NOTIF_CENTER_COUNT));
-       for (int i = 1; i <= NOTIF_CENTER_COUNT; ++i)
-       {
-               Notification e = Get_Notif_Ent(MSG_CENTER, i);
-               if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; }
-
-               NOTIF_WRITE_ENTITY(e,
+       FOREACH(Notifications, it.nent_type == MSG_CENTER, {
+               NOTIF_WRITE_ENTITY(it,
                        "0 = off, 1 = centerprint"
                );
-       }
+       });
 
+       int NOTIF_MULTI_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_MULTI, { ++NOTIF_MULTI_COUNT; });
        NOTIF_WRITE(sprintf("\n// MSG_MULTI notifications (count = %d):\n", NOTIF_MULTI_COUNT));
-       for (int i = 1; i <= NOTIF_MULTI_COUNT; ++i)
-       {
-               Notification e = Get_Notif_Ent(MSG_MULTI, i);
-               if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; }
-
-               NOTIF_WRITE_ENTITY(e,
+       FOREACH(Notifications, it.nent_type == MSG_MULTI, {
+               NOTIF_WRITE_ENTITY(it,
                        "Enable this multiple notification"
                );
-       }
+       });
 
+       int NOTIF_CHOICE_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_CHOICE, { ++NOTIF_CHOICE_COUNT; });
        NOTIF_WRITE(sprintf("\n// MSG_CHOICE notifications (count = %d):\n", NOTIF_CHOICE_COUNT));
-       for (int i = 1; i <= NOTIF_CHOICE_COUNT; ++i)
-       {
-               Notification e = Get_Notif_Ent(MSG_CHOICE, i);
-               if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; }
-
-               NOTIF_WRITE_ENTITY_CHOICE(e,
+       FOREACH(Notifications, it.nent_type == MSG_CHOICE, {
+               NOTIF_WRITE_ENTITY_CHOICE(it,
                        "Choice for this notification 0 = off, 1 = default message, 2 = verbose message",
                        "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
                );
-       }
+       });
 
        // edit these to match whichever cvars are used for specific notification options
        NOTIF_WRITE("\n// HARD CODED notification variables:\n");
@@ -1462,14 +1432,16 @@ NET_HANDLE(ENT_CLIENT_NOTIFICATION, bool is_new)
 {
        int net_type = ReadByte();
        int net_name = ReadShort();
+       Notification notif = Get_Notif_Ent(net_type, net_name);
 
        #ifdef NOTIFICATIONS_DEBUG
        Debug_Notification(sprintf(
-               "Read_Notification(%d) at %f: net_type = %s, net_name = %s\n",
+               "Read_Notification(%d) at %f: net_type = %s, net_name = %s (%d)\n",
                is_new,
                time,
                Get_Notif_TypeName(net_type),
-               notif.nent_name
+               notif.registered_id,
+               net_name
        ));
        #endif
 
@@ -1498,7 +1470,6 @@ NET_HANDLE(ENT_CLIENT_NOTIFICATION, bool is_new)
        else
        {
                // creating
-               Notification notif = Get_Notif_Ent(net_type, net_name);
                if (!notif) {
                        backtrace("Read_Notification: Could not find notification entity!\n");
                        return false;
@@ -1546,12 +1517,12 @@ void Net_Notification_Remove()
 
 bool Net_Write_Notification(entity this, entity client, int sf)
 {
-       if (!Notification_ShouldSend(self.nent_broadcast, client, self.nent_client)) return false;
+       if (!Notification_ShouldSend(this.nent_broadcast, client, this.nent_client)) return false;
        WriteHeader(MSG_ENTITY, ENT_CLIENT_NOTIFICATION);
-       WriteByte(MSG_ENTITY, self.nent_net_type);
-       WriteShort(MSG_ENTITY, self.nent_net_name);
-       for (int i = 0; i < self.nent_stringcount; ++i) { WriteString(MSG_ENTITY, self.nent_strings[i]); }
-       for (int i = 0; i < self.nent_floatcount; ++i) { WriteLong(MSG_ENTITY, self.nent_floats[i]); }
+       WriteByte(MSG_ENTITY, this.nent_net_type);
+       WriteShort(MSG_ENTITY, this.nent_net_name);
+       for (int i = 0; i < this.nent_stringcount; ++i) { WriteString(MSG_ENTITY, this.nent_strings[i]); }
+       for (int i = 0; i < this.nent_floatcount; ++i) { WriteLong(MSG_ENTITY, this.nent_floats[i]); }
        return true;
 }
 
@@ -1656,18 +1627,22 @@ void Send_Notification(
        float net_type, Notification net_name,
        ...count)
 {
+       entity notif = net_name;
+       string parms = sprintf("%s, '%s', %s, %s",
+               Get_Notif_BroadcastName(broadcast),
+               client.classname,
+               Get_Notif_TypeName(net_type),
+               net_name.registered_id
+       );
+       #ifdef NOTIFICATIONS_DEBUG
+       Debug_Notification(sprintf("Send_Notification(%s, ...%d);\n", parms, count));
+       #endif
        // check if this should be aborted
-       if (net_name == NOTIF_ABORT)
+       if (net_name == NOTIF_ABORT) return;
+
+       if (!notif)
        {
-               #ifdef NOTIFICATIONS_DEBUG
-               Debug_Notification(sprintf(
-                       "Send_Notification(%s, '%s', %s, %s, ...);\n",
-                       Get_Notif_BroadcastName(broadcast),
-                       client.classname,
-                       Get_Notif_TypeName(net_type),
-                       "NOTIF_ABORT"
-               ));
-               #endif
+               LOG_WARNING("Send_Notification: Could not find notification entity!");
                return;
        }
 
@@ -1675,33 +1650,7 @@ void Send_Notification(
        string checkargs = Notification_CheckArgs(broadcast, client, net_name);
        if (checkargs != "")
        {
-               #ifdef NOTIFICATIONS_DEBUG
-               Debug_Notification(sprintf(
-                       "Send_Notification(%s, '%s', %s, %s, ...);\n",
-                       Get_Notif_BroadcastName(broadcast),
-                       client.classname,
-                       Get_Notif_TypeName(net_type),
-                       net_name.nent_name
-               ));
-               #endif
-               backtrace(sprintf("Incorrect usage of Send_Notification: %s\n", checkargs));
-               return;
-       }
-
-       // retreive entity of this notification
-       entity notif = net_name;
-       if (!notif)
-       {
-               #ifdef NOTIFICATIONS_DEBUG
-               Debug_Notification(sprintf(
-                       "Send_Notification(%s, '%s', %s, %d, ...);\n",
-                       Get_Notif_BroadcastName(broadcast),
-                       client.classname,
-                       Get_Notif_TypeName(net_type),
-                       net_name
-               ));
-               #endif
-               backtrace("Send_Notification: Could not find notification entity!\n");
+               LOG_WARNINGF("Incorrect usage of Send_Notification: %s", checkargs);
                return;
        }
 
@@ -1717,13 +1666,7 @@ void Send_Notification(
        #ifdef NOTIFICATIONS_DEBUG
        Debug_Notification(sprintf(
                "Send_Notification(%s, %s, %s);\n",
-               sprintf(
-                       "%s, '%s', %s, %s",
-                       Get_Notif_BroadcastName(broadcast),
-                       client.classname,
-                       Get_Notif_TypeName(net_type),
-                       notif.nent_name
-               ),
+               parms,
                MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)),
                sprintf("%d, %d, %d, %d", f1, f2, f3, f4)
        ));
@@ -1731,29 +1674,15 @@ void Send_Notification(
 
        if ((notif.nent_stringcount + notif.nent_floatcount) != count)
        {
-               string s =
-               #ifdef NOTIFICATIONS_DEBUG
-               Get_Notif_BroadcastName(broadcast);
-               #else
-               ftos(ORDINAL(broadcast));
-               #endif
-               backtrace(sprintf(
-                       strcat(
-                               "Argument mismatch for Send_Notification(%s, ...)! ",
-                               "stringcount(%d) + floatcount(%d) != count(%d)\n",
-                               "Check the definition and function call for accuracy...?\n"
-                       ),
-                       sprintf(
-                               "%s, '%s', %s, %s",
-                               s,
-                               client.classname,
-                               Get_Notif_TypeName(net_type),
-                               notif.nent_name
-                       ),
+               LOG_WARNINGF(
+                       "Argument mismatch for Send_Notification(%s, ...)! "
+                       "stringcount(%d) + floatcount(%d) != count(%d)\n"
+                       "Check the definition and function call for accuracy...?\n",
+                       parms,
                        notif.nent_stringcount,
                        notif.nent_floatcount,
                        count
-               ));
+               );
                return;
        }
 
@@ -1792,7 +1721,7 @@ void Send_Notification(
 
                #define RECURSE_FROM_CHOICE(ent,action) MACRO_BEGIN { \
                        if (notif.nent_challow_var && (warmup_stage || (notif.nent_challow_var == 2))) { \
-                               switch (ent.msg_choice_choices[net_name.nent_id - 1]) \
+                               switch (ent.msg_choice_choices[net_name.nent_choice_idx]) \
                                { \
                                        case 1: found_choice = notif.nent_optiona; break; \
                                        case 2: found_choice = notif.nent_optionb; break; \
@@ -1838,7 +1767,7 @@ void Send_Notification(
                net_notif.nent_broadcast = broadcast;
                net_notif.nent_client = client;
                net_notif.nent_net_type = net_type;
-               net_notif.nent_net_name = net_name.nent_id;
+               net_notif.nent_net_name = notif.m_id;
                net_notif.nent_stringcount = notif.nent_stringcount;
                net_notif.nent_floatcount = notif.nent_floatcount;
 
index 3ba25c041063fb3f9d32e260becf2a2466fd3286..55275cd035124ae106dedc214311342e0d33e175 100644 (file)
@@ -84,7 +84,6 @@ void Create_Notification_Entity(entity notif,
        float var_default,
        float var_cvar,
        float typeId,
-       float nameid,
        string namestring);
 void Create_Notification_Entity_Annce(entity notif,
                                                                                float var_cvar,
@@ -216,8 +215,7 @@ ENUMCLASS(NOTIF)
        CASE(NOTIF, ALL_EXCEPT)
 ENUMCLASS_END(NOTIF)
 
-#ifdef NOTIFICATIONS_DEBUG
-string Get_Notif_BroadcastName(float broadcast)
+string Get_Notif_BroadcastName(NOTIF broadcast)
 {
        switch (broadcast)
        {
@@ -228,10 +226,9 @@ string Get_Notif_BroadcastName(float broadcast)
                case NOTIF_TEAM: return "NOTIF_TEAM";
                case NOTIF_TEAM_EXCEPT: return "NOTIF_TEAM_EXCEPT";
        }
-       backtrace(sprintf("Get_Notif_BroadcastName(%d): Improper broadcast!\n", broadcast));
+       LOG_WARNINGF("Get_Notif_BroadcastName(%d): Improper broadcast!\n", broadcast);
        return "";
 }
-#endif
 
 void Kill_Notification(
        NOTIF broadcast, entity client,
@@ -627,54 +624,17 @@ enum {
 // always last
 ,   NOTIF_CPID_COUNT
 };
-// notification counts
-/** @deprecated */
-const int NOTIF_FIRST = 1;
-int NOTIF_ANNCE_COUNT;
-int NOTIF_INFO_COUNT;
-int NOTIF_CENTER_COUNT;
-int NOTIF_MULTI_COUNT;
-int NOTIF_CHOICE_COUNT;
-
-// notification limits -- INCREASE AS NECESSARY
-const int NOTIF_ANNCE_MAX   = 400;
-const int NOTIF_INFO_MAX    = 450;
-const int NOTIF_CENTER_MAX  = 350;
-const int NOTIF_MULTI_MAX   = 300;
-const int NOTIF_CHOICE_MAX  = 50;
-
-// notification entities
-Notification msg_annce_notifs[NOTIF_ANNCE_MAX];
-Notification msg_info_notifs[NOTIF_INFO_MAX];
-Notification msg_center_notifs[NOTIF_CENTER_MAX];
-Notification msg_multi_notifs[NOTIF_MULTI_MAX];
-Notification msg_choice_notifs[NOTIF_CHOICE_MAX];
-
-Notification Get_Notif_Ent(int net_type, int net_name)
-{
-       switch (net_type)
-       {
-               case MSG_ANNCE: return msg_annce_notifs[net_name - 1];
-               case MSG_INFO: return msg_info_notifs[net_name - 1];
-               case MSG_CENTER: return msg_center_notifs[net_name - 1];
-               case MSG_MULTI: return msg_multi_notifs[net_name - 1];
-               case MSG_CHOICE: return msg_choice_notifs[net_name - 1];
-       }
-       backtrace(sprintf("Get_Notif_Ent(%d, %d): Improper net type!\n", net_type, net_name));
-       return NULL;
-}
 
 // common notification entity values
-.float nent_default;
-.float nent_enabled;
-.float nent_type;
-.float nent_id;
+.int nent_default;
+.bool nent_enabled;
+.int nent_type;
 .string nent_name;
 .int nent_stringcount;
 .int nent_floatcount;
 
 // MSG_ANNCE entity values
-.float nent_channel;
+.int nent_channel;
 .string nent_snd;
 .float nent_vol;
 .float nent_position;
@@ -708,47 +668,63 @@ Notification Get_Notif_Ent(int net_type, int net_name)
 .string nent_strings[4];
 .float nent_floats[4];
 
-// other notification properties
-.int msg_choice_choices[NOTIF_CHOICE_MAX]; // set on each player containing MSG_CHOICE choices
-
 #define ACVNN(name) autocvar_notification_##name
 
+REGISTRY(Notifications, BITS(11))
+REGISTER_REGISTRY(Notifications)
+REGISTRY_SORT(Notifications)
+REGISTRY_CHECK(Notifications)
+
+const int NOTIF_CHOICE_MAX = 50;
+int nent_choice_count = 0;
+.int nent_choice_idx;
+.int msg_choice_choices[NOTIF_CHOICE_MAX]; // set on each player containing MSG_CHOICE choices
 // initialization error detection
 bool notif_error;
 bool notif_global_error;
 
+STATIC_INIT_LATE(Notif_Choices) {
+       int c = 0;
+       FOREACH(Notifications, it.nent_type == MSG_CHOICE, { c++; });
+       if (c > NOTIF_CHOICE_MAX) {
+               LOG_FATALF("Too many MSG_CHOICE notifications (%d)", c);
+       }
+}
+
+Notification Get_Notif_Ent(int net_type, int net_name)
+{
+       if (net_type == MSG_CENTER_CPID) return NULL;
+       Notification it = _Notifications_from(net_name, NULL);
+       if (it.nent_type != net_type) {
+               LOG_WARNINGF("Get_Notif_Ent(%s (%d), %s (%d)): Improper net type '%s'!\n",
+                       Get_Notif_TypeName(net_type), net_type,
+                       it.registered_id, net_name,
+                       Get_Notif_TypeName(it.nent_type)
+               );
+               return NULL;
+       }
+       return it;
+}
+
 #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) \
-       Notification name; \
-       void RegisterNotification_##name() \
-       { \
-               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)); \
+       REGISTER(Notifications, name, m_id, new_pure(msg_annce_notification)) { \
+               Create_Notification_Entity      (this, default, ACVNN(name), MSG_ANNCE, strtoupper(#name)); \
                Create_Notification_Entity_Annce(this, ACVNN(name), strtoupper(#name), \
                        channel,   /* channel  */ \
                        sound,     /* snd      */ \
                        volume,    /* vol      */ \
                        position); /* position */ \
-       } \
-       ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
+       }
 
 #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) \
-       Notification name; \
-       void RegisterNotification_##name() \
-       { \
-               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)); \
+       REGISTER(Notifications, name, m_id, new_pure(msg_info_notification)) { \
+               Create_Notification_Entity           (this, default, ACVNN(name), MSG_INFO, strtoupper(#name)); \
                Create_Notification_Entity_InfoCenter(this, ACVNN(name), strtoupper(#name), strnum, flnum, \
                        args,     /* args    */ \
                        hudargs,  /* hudargs */ \
@@ -757,22 +733,15 @@ bool notif_global_error;
                        "",       /* durcnt  */ \
                        normal,   /* normal  */ \
                        gentle);  /* gentle  */ \
-       } \
-       ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
+       }
 
 .string nent_iconargs;
 #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) \
-       Notification name; \
-       void RegisterNotification_##name() \
-       { \
-               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)); \
+       REGISTER(Notifications, name, m_id, new_pure(msg_info_notification)) { \
+               Create_Notification_Entity           (this, default, ACVNN(name), MSG_INFO, strtoupper(#name)); \
                Create_Notification_Entity_InfoCenter(this, ACVNN(name), strtoupper(#name), strnum, flnum, \
                        args,     /* args    */ \
                        hudargs,  /* hudargs */ \
@@ -782,21 +751,14 @@ bool notif_global_error;
                        normal,   /* normal  */ \
                        gentle);  /* gentle  */ \
                this.nent_iconargs = iconargs; \
-       } \
-       ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
+       }
 
 #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) \
-       Notification name; \
-       void RegisterNotification_##name() \
-       { \
-               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)); \
+       REGISTER(Notifications, name, m_id, new_pure(msg_center_notification)) { \
+               Create_Notification_Entity           (this, default, ACVNN(name), MSG_CENTER, strtoupper(#name)); \
                Create_Notification_Entity_InfoCenter(this, ACVNN(name), strtoupper(#name), strnum, flnum, \
                        args,    /* args    */ \
                        "",      /* hudargs */ \
@@ -805,47 +767,33 @@ bool notif_global_error;
                        durcnt,  /* durcnt  */ \
                        normal,  /* normal  */ \
                        gentle); /* gentle  */ \
-       } \
-       ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
+       }
 
 #define MSG_MULTI_NOTIF(name, default, anncename, infoname, centername) \
        NOTIF_ADD_AUTOCVAR(name, default) \
-       Notification name; \
-       void RegisterNotification_##name() \
-       { \
-               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)); \
+       REGISTER(Notifications, name, m_id, new_pure(msg_multi_notification)) { \
+               Create_Notification_Entity      (this, default, ACVNN(name), MSG_MULTI, strtoupper(#name)); \
                Create_Notification_Entity_Multi(this, ACVNN(name), strtoupper(#name), \
                        anncename,   /* anncename  */ \
                        infoname,    /* infoname   */ \
                        centername); /* centername */ \
-       } \
-       ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
+       }
 
 #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) \
-       Notification name; \
-       void RegisterNotification_##name() \
-       { \
-               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)); \
+       REGISTER(Notifications, name, m_id, new_pure(msg_choice_notification)) { \
+               this.nent_choice_idx = nent_choice_count++; \
+               Create_Notification_Entity       (this, default, ACVNN(name), MSG_CHOICE, strtoupper(#name)); \
                Create_Notification_Entity_Choice(this, ACVNN(name), strtoupper(#name), \
                        challow,                                 /* challow_def */ \
                        autocvar_notification_##name##_ALLOWED,  /* challow_var */ \
                        chtype,                                  /* chtype      */ \
                        optiona,                                 /* optiona     */ \
                        optionb);                                /* optionb     */ \
-       } \
-       ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
+       }
 
 void RegisterNotifications_First()
 {