]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/notifications.qh
More work on item messages
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / notifications.qh
index c9db63c1520ae475527353e058df95376f2768b2..8a2695159260fb2327af9977b26963a6de3cef24 100644 (file)
@@ -7,7 +7,7 @@
 #define MSG_INFO 1 // "Global" information messages (sent to console, and notify panel if it has an icon)
 #define MSG_CENTER 2 // "Personal" centerprint messages
 #define MSG_CENTER_KILL 3 // Kill centerprint message
-#define MSG_WEAPON 4 // "Personal" weapon messages (like "You got the Nex", sent to weapon notify panel)
+#define MSG_WEAPON 4 // "Global" weapon messages 
 #define MSG_DEATH 5 // "Personal" AND "Global" death messages 
 
 #define NO_MSG -12345 
@@ -60,8 +60,12 @@ void Read_Notification(float is_new);
 void Kill_Notification(float broadcast, entity client, float net_type, float net_name);
 void Send_Notification(float broadcast, entity client, float net_type, float net_name, ...count);
 void Send_Notification_WOVA(float broadcast, entity client, float net_type, float net_name, string s1, string s2, string s3, string s4, float f1, float f2, float f3, float f4);
+
+// legacy stuff
 void Send_CSQC_Centerprint_Generic(entity e, float id, string s, float duration, float countdown_num);
 #define Send_CSQC_Centerprint_Generic_Expire(e,id) Send_CSQC_Centerprint_Generic(e, id, "", 1, 0)
+float CPID_MOTD = 9;
+float CPID_KH_MSG = 10;
 #endif
 
 
@@ -257,6 +261,8 @@ void Send_CSQC_Centerprint_Generic(entity e, float id, string s, float duration,
        MSG_INFO_NOTIF(2, INFO_VERSION_OLD,                                             2, 0, "s1 s2", "",                                              "",                                             _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s^BG, you have ^F2Xonotic %s\n"), "") \
        MSG_INFO_NOTIF(2, INFO_VERSION_OUTDATED,                                2, 0, "s1 s2", "",                                              "",                                             _("^F4NOTE: ^F1Xonotic %s^BG is out, and you still have ^F2Xonotic %s^BG - get the update from ^F3http://www.xonotic.org/^BG!\n"), "") \
        MSG_INFO_NOTIF(1, INFO_WATERMARK,                                               1, 0, "s1", "",                                                 "",                                             _("^F3SVQC Build information: ^F4%s\n"), "") \
+       MSG_INFO_NOTIF(0, INFO_WEAPON_GOTWEP,                                   0, 1, "item_wepname", "",                               "",                                     _("^BGYou got the ^F1%s\n"), "") \
+       MSG_INFO_NOTIF(0, INFO_WEAPON_DROPPED,                                  1, 1, "item_wepname item_wepammo", "",  "",                                     _("^BGYou dropped the ^F1%s^BG%s\n"), "") \
        MSG_INFO_NOTIF(1, INFO_WEAPON_THINKING_WITH_PORTALS,                    2, 1, "s1 s2loc spree_lost", "s1",                                      "notify_selfkill",                      _("^BG%s^K1 is now thinking with portals%s%s\n"), "") \
        MSG_INFO_NOTIF(1, INFO_WEAPON_CRYLINK_SUICIDE,                                  2, 1, "s1 s2loc spree_lost", "s1",                                      "weaponcrylink",                        _("^BG%s^K1 felt the strong pull of their Crylink%s%s\n"), "") \
        MSG_INFO_NOTIF(1, INFO_WEAPON_CRYLINK_MURDER,                                   3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",       "weaponcrylink",                        _("^BG%s%s^K1 felt the strong pull of ^BG%s^K1's Crylink%s%s\n"), "") \
@@ -419,10 +425,14 @@ void Send_CSQC_Centerprint_Generic(entity e, float id, string s, float duration,
        MSG_CENTER_NOTIF(1, CENTER_TEAMCHANGE_AUTO,                                     0, 1, "",                               CPID_TEAMCHANGE,                "1 f1", _("^BGChanging team in ^COUNT"), "") \
        MSG_CENTER_NOTIF(1, CENTER_TEAMCHANGE_SUICIDE,                          0, 1, "",                               CPID_TEAMCHANGE,                "1 f1", _("^K1Suicide in ^COUNT"), "") \
        MSG_CENTER_NOTIF(1, CENTER_TIMEOUT_BEGINNING,                           0, 1, "",                               CPID_TIMEOUT,                   "1 f1", _("^F4Timeout begins in ^COUNT"), "") \
-       MSG_CENTER_NOTIF(1, CENTER_TIMEOUT_ENDING,                                      0, 1, "",                               CPID_TIMEOUT,                   "1 f1", _("^F4Timeout ends in ^COUNT"), "")
+       MSG_CENTER_NOTIF(1, CENTER_TIMEOUT_ENDING,                                      0, 1, "",                               CPID_TIMEOUT,                   "1 f1", _("^F4Timeout ends in ^COUNT"), "") \
+       MSG_CENTER_NOTIF(1, CENTER_WEAPON_GOTWEP,                                       0, 1, "item_wepname",                           CPID_ITEM,      "item_centime 0", _("^BGYou got the ^F1%s"), "") \
+       MSG_CENTER_NOTIF(1, CENTER_WEAPON_DROPPED,                                      1, 1, "item_wepname item_wepammo",      CPID_ITEM,      "item_centime 0", _("^BGYou dropped the ^F1%s^BG%s"), "")
 
 #define MSG_WEAPON_NOTIFICATIONS \
        /*MSG_WEAPON_NOTIF(1, WEAPON_EMPTY,                                                     NO_MSG,                                                                         NO_MSG)*/ \
+       MSG_WEAPON_NOTIF(1, WEAPON_GOTWEP,                                                      INFO_WEAPON_GOTWEP,                                                     CENTER_WEAPON_GOTWEP) \
+       MSG_WEAPON_NOTIF(1, WEAPON_DROPPED,                                                     INFO_WEAPON_DROPPED,                                            CENTER_WEAPON_DROPPED) \
        MSG_WEAPON_NOTIF(1, WEAPON_THINKING_WITH_PORTALS,                       INFO_WEAPON_THINKING_WITH_PORTALS,                      CENTER_DEATH_SELF_GENERIC) \
        MSG_WEAPON_NOTIF(1, WEAPON_CRYLINK_SUICIDE,                             INFO_WEAPON_CRYLINK_SUICIDE,                            CENTER_DEATH_SELF_GENERIC) \
        MSG_WEAPON_NOTIF(1, WEAPON_CRYLINK_MURDER,                                      INFO_WEAPON_CRYLINK_MURDER,                             NO_MSG) \
@@ -555,7 +565,10 @@ var float autocvar_notification_show_sprees = TRUE;
 var float autocvar_notification_show_sprees_info = 3; // 0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker
 var float autocvar_notification_show_sprees_info_newline = FALSE;
 var float autocvar_notification_show_sprees_info_specialonly = TRUE;
+var float autocvar_notification_item_centerprinttime = 1.5;
 var float autocvar_notification_errors_are_fatal = TRUE;
+var float autocvar_notification_lifetime_runtime = 0.5;
+var float autocvar_notification_lifetime_mapload = 10;
 
 #ifdef SVQC
 .float FRAG_VERBOSE;
@@ -614,6 +627,7 @@ string arg_slot[NOTIF_MAX_ARGS];
 #define ARG_CS_SV 3 // enabled on CSQC and SVQC
 #define ARG_CS 4 // unique result to CSQC
 #define ARG_SV 5 // unique result to SVQC
+#define ARG_DC 6 // unique result to durcnt/centerprint
 
 // todo possible idea.... declare how many floats/strings each arg needs, and then dynamically increment the input
 // this way, we don't need to have duplicates like i.e. s2loc and s3loc
@@ -642,7 +656,9 @@ string arg_slot[NOTIF_MAX_ARGS];
        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,             "weapon",                       W_Name(f1)) \
+       ARG_CASE(ARG_CS_SV,             "item_wepname",         W_Name(f1)) \
+       ARG_CASE(ARG_CS_SV,                     "item_wepammo",         (s1 != "" ? s1 : "")) \
+       ARG_CASE(ARG_DC,                "item_centime",         ftos(autocvar_notification_item_centerprinttime)) \
        ARG_CASE(ARG_SV,                        "death_team",           Team_ColoredFullName(f1)) \
        ARG_CASE(ARG_CS,                        "death_team",           Team_ColoredFullName(f1 - 1)) \
        ARG_CASE(ARG_CS_SV,                     "race_time",            mmssss(f2)) \
@@ -957,7 +973,7 @@ string Process_Notif_Args(float arg_type, string args, string notiftype, string
                                switch(strtolower(selected))
                                {
                                        #define ARG_CASE(prog,selected,result) \
-                                               #if (prog == ARG_CS_SV_DC) \
+                                               #if (prog == ARG_CS_SV_DC) || (prog == ARG_DC) \
                                                        case selected: { ++sel_num; break; } \
                                                #endif
                                        NOTIF_ARGUMENT_LIST
@@ -1016,45 +1032,52 @@ string Process_Notif_Args(float arg_type, string args, string notiftype, string
                        notif.nent_floatcount = max(infoname_floatcount, centername_floatcount); \
                #endif \
        #else /* MSG_INFO and MSG_CENTER */ \
-               float nent_chat = (autocvar_notification_##name > 1); \
-               \
                notif.nent_stringcount = strnum; \
                notif.nent_floatcount = flnum; \
-               if(strnum + flnum > 4) { print(sprintf("^1NOTIFICATION HAS TOO MANY ARGUMENTS FOR BROKEN VARARGS: ^7net_type = MSG_%s, net_name = %s\n", strtoupper(#type), #name)); } \
-               if(strnum + flnum) \
-               { \
-                       if(args != "") { notif.nent_args = strzone(Process_Notif_Args(1, args, strtoupper(#type), #name)); } \
-                       else if((hudargs == "") && (durcnt =="")) { print(sprintf("^1NOTIFICATION HAS ARG COUNTS BUT NO ARGS OR HUDARGS OR DURCNT: ^7net_type = MSG_%s, net_name = %s, strnum = %d, flnum = %d\n", strtoupper(#type), #name, strnum, flnum)); notif_error = TRUE; } \
-               } \
-               else if(args != "") { notif.nent_args = strzone(Process_Notif_Args(1, args, strtoupper(#type), #name)); } \
                \
-               /* MSG_INFO only */ \
-               if(hudargs != "") \
-               { \
-                       notif.nent_hudargs = strzone(Process_Notif_Args(2, hudargs, strtoupper(#type), #name)); \
-                       if(icon != "") { notif.nent_icon = strzone(icon); } \
-                       else { print(sprintf("^1NOTIFICATION HAS HUDARGS BUT NO ICON: ^7net_type = MSG_%s, net_name = %s.\n", strtoupper(#type), #name)); notif_error = TRUE; } \
-               } \
-               else if(icon != "") { print(sprintf("^1NOTIFICATION HAS ICON BUT NO HUDARGS: ^7net_type = MSG_%s, net_name = %s.\n", strtoupper(#type), #name)); notif_error = TRUE; } \
-               \
-               /* MSG_CENTER only */ \
-               if(durcnt != "") \
-               { \
-                       notif.nent_durcnt = strzone(Process_Notif_Args(3, durcnt, strtoupper(#type), #name)); \
-                       if(cpid != NO_MSG) { notif.nent_cpid = cpid; } \
-                       else { print(sprintf("^1NOTIFICATION HAS DURCNT BUT NO CPID: ^7net_type = MSG_%s, net_name = %s.\n", strtoupper(#type), #name)); notif_error = TRUE; } \
-               } \
-               else if(cpid != NO_MSG) { notif.nent_cpid = cpid; } \
+               /* only initialize this information if we're on a client or a dedicated server */ \
+               #ifdef SVQC \
+               if(server_is_dedicated) { \
+               #endif \
                \
-               /* string setup */ \
-               /* select gentle/normal string and bake color codes in on init, this way it does not need to be re-processed at run time */ \
-               if(GENTLE) \
-               { \
-                       if(gentle != "") { notif.nent_string = strzone(CCR(Process_Notif_Line(check_newline, nent_chat, gentle, strtoupper(#type), #name, "GENTLE"))); } \
+                       if(strnum + flnum) \
+                       { \
+                               if(args != "") { notif.nent_args = strzone(Process_Notif_Args(1, args, strtoupper(#type), #name)); } \
+                               else if((hudargs == "") && (durcnt =="")) { print(sprintf("^1NOTIFICATION HAS ARG COUNTS BUT NO ARGS OR HUDARGS OR DURCNT: ^7net_type = MSG_%s, net_name = %s, strnum = %d, flnum = %d\n", strtoupper(#type), #name, strnum, flnum)); notif_error = TRUE; } \
+                       } \
+                       else if(args != "") { notif.nent_args = strzone(Process_Notif_Args(1, args, strtoupper(#type), #name)); } \
+                       \
+                       /* MSG_INFO only */ \
+                       if(hudargs != "") \
+                       { \
+                               notif.nent_hudargs = strzone(Process_Notif_Args(2, hudargs, strtoupper(#type), #name)); \
+                               if(icon != "") { notif.nent_icon = strzone(icon); } \
+                               else { print(sprintf("^1NOTIFICATION HAS HUDARGS BUT NO ICON: ^7net_type = MSG_%s, net_name = %s.\n", strtoupper(#type), #name)); notif_error = TRUE; } \
+                       } \
+                       else if(icon != "") { print(sprintf("^1NOTIFICATION HAS ICON BUT NO HUDARGS: ^7net_type = MSG_%s, net_name = %s.\n", strtoupper(#type), #name)); notif_error = TRUE; } \
+                       \
+                       /* MSG_CENTER only */ \
+                       if(durcnt != "") \
+                       { \
+                               notif.nent_durcnt = strzone(Process_Notif_Args(3, durcnt, strtoupper(#type), #name)); \
+                               if(cpid != NO_MSG) { notif.nent_cpid = cpid; } \
+                               else { print(sprintf("^1NOTIFICATION HAS DURCNT BUT NO CPID: ^7net_type = MSG_%s, net_name = %s.\n", strtoupper(#type), #name)); notif_error = TRUE; } \
+                       } \
+                       else if(cpid != NO_MSG) { notif.nent_cpid = cpid; } \
+                       \
+                       /* string setup */ \
+                       /* select gentle/normal string and bake color codes in on init, this way it does not need to be re-processed at run time */ \
+                       float nent_chat = (autocvar_notification_##name > 1); \
+                       if(GENTLE) \
+                       { \
+                               if(gentle != "") { notif.nent_string = strzone(CCR(Process_Notif_Line(check_newline, nent_chat, gentle, strtoupper(#type), #name, "GENTLE"))); } \
+                               else if(normal != "") { notif.nent_string = strzone(CCR(Process_Notif_Line(check_newline, nent_chat, normal, strtoupper(#type), #name, "NORMAL"))); } \
+                       } \
                        else if(normal != "") { notif.nent_string = strzone(CCR(Process_Notif_Line(check_newline, nent_chat, normal, strtoupper(#type), #name, "NORMAL"))); } \
+                       if(notif.nent_string == "") { print(sprintf("^1EMPTY NOTIFICATION: ^7net_type = MSG_%s, net_name = %s.\n", strtoupper(#type), #name)); notif_error = TRUE; } \
+               #ifdef SVQC \
                } \
-               else if(normal != "") { notif.nent_string = strzone(CCR(Process_Notif_Line(check_newline, nent_chat, normal, strtoupper(#type), #name, "NORMAL"))); } \
-               if(notif.nent_string == "") { print(sprintf("^1EMPTY NOTIFICATION: ^7net_type = MSG_%s, net_name = %s.\n", strtoupper(#type), #name)); notif_error = TRUE; } \
+               #endif \
        #endif \
        \
        /* now check to see if any errors happened */ \
@@ -1178,6 +1201,14 @@ string Process_Notif_Args(float arg_type, string args, string notiftype, string
 void RegisterNotifications_First()
 {
        notif_global_error = FALSE;
+
+       #ifdef SVQC
+       #define dedi (server_is_dedicated ? "a dedicated " : "")
+       #else
+       #define dedi ""
+       #endif
+       
+       print(sprintf("Beginning notification initialization on %s%s program...\n", dedi, PROGNAME));
        
        // maybe do another implementation of this with checksums? for now, we don't need versioning
        /*if(autocvar_notification_version != NOTIF_VERSION)
@@ -1190,17 +1221,21 @@ void RegisterNotifications_First()
                        notif_global_error = TRUE;
 
                print(sprintf("^1NOTIFICATION VERSION MISMATCH: ^7program = %s, config = %d, code = %d.\n",
-                       "foobar", autocvar_notification_version, NOTIF_VERSION));
+                       PROGNAME, autocvar_notification_version, NOTIF_VERSION));
        }*/
 }
 
 void RegisterNotifications_Done()
 {
-       if(notif_global_error && autocvar_notification_errors_are_fatal)
+       if(notif_global_error)
        {
-               // shit happened... stop the loading of the program now
-               error("Notification initialization failed!");
+               // shit happened... stop the loading of the program now if this is unacceptable
+               if(autocvar_notification_errors_are_fatal)
+                       error("Notification initialization failed! Read above and fix the errors!\n");
+               else
+                       print("Notification initialization failed! Read above and fix the errors!\n");
        }
+       else { print("Notification initialization successful!\n"); }
 }
 
 // NOW we actually activate the declarations