X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fcommon%2Fnotifications.qc;h=4fd6e1f25dcc37373a00a04a565aec114867ddb2;hb=60484e63e0fcdc59daf98d7a52c04e79bc13a3c3;hp=580368d09f9ad9fd6195fc5309b2aea12c7b42e2;hpb=7d86ade6464587abe1ece66045169fd862d09eab;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/common/notifications.qc b/qcsrc/common/notifications.qc index 580368d09..4fd6e1f25 100644 --- a/qcsrc/common/notifications.qc +++ b/qcsrc/common/notifications.qc @@ -1,6 +1,6 @@ // ================================================ // Unified notification system, written by Samual -// Last updated: June, 2013 +// Last updated: August, 2013 // ================================================ string Get_Notif_TypeName(float net_type) @@ -32,6 +32,25 @@ entity Get_Notif_Ent(float net_type, float net_name) return world; } +#ifdef SVQC +#ifdef NOTIFICATIONS_DEBUG +string Get_Notif_BroadcastName(float broadcast) +{ + switch(broadcast) + { + case NOTIF_ONE: return "NOTIF_ONE"; + case NOTIF_ONE_ONLY: return "NOTIF_ONE_ONLY"; + case NOTIF_ALL_EXCEPT: return "NOTIF_ALL_EXCEPT"; + case NOTIF_ALL: return "NOTIF_ALL"; + case NOTIF_TEAM: return "NOTIF_TEAM"; + case NOTIF_TEAM_EXCEPT: return "NOTIF_TEAM_EXCEPT"; + } + backtrace(sprintf("Get_Notif_BroadcastName(%d): Improper broadcast!\n", broadcast)); + return ""; +} +#endif +#endif + string Notification_CheckArgs_TypeName(float net_type, float net_name) { // check supplied type and name for errors @@ -69,33 +88,38 @@ string Notification_CheckArgs( { checkargs = sprintf("%sNo client provided!", checkargs); } break; } - + case NOTIF_ALL_EXCEPT: { if(IS_NOT_A_CLIENT(client)) { checkargs = sprintf("%sException can't be a non-client!", checkargs); } break; } - + case NOTIF_ALL: { if(client) { checkargs = sprintf("%sEntity provided when world was required!", checkargs); } break; } - + case NOTIF_TEAM: + { + if (!teamplay) + { checkargs = sprintf("%sTeamplay not active!", checkargs); } + //else if (!client.team) { checkargs = sprintf("%sNo team provided!", checkargs); } + break; + } + case NOTIF_TEAM_EXCEPT: { - if not(teamplay) { checkargs = sprintf("%sTeamplay not active!", checkargs); } + if (!teamplay) + { checkargs = sprintf("%sTeamplay not active!", checkargs); } else if(IS_NOT_A_CLIENT(client)) - { - if(broadcast == NOTIF_TEAM) { checkargs = sprintf("%sNo client provided!", checkargs); } - else { checkargs = sprintf("%sException can't be a non-client!", checkargs); } - } + { checkargs = sprintf("%sException can't be a non-client!", checkargs); } break; } - + default: { checkargs = sprintf("%sImproper broadcast: %d!", checkargs, broadcast); break; } } return checkargs; @@ -201,12 +225,12 @@ void Destroy_All_Notifications(void) { entity notif; float i; - + #define DESTROY_LOOP(type,count) \ for(i = 1; i <= count; ++i) \ { \ notif = Get_Notif_Ent(type, i); \ - if not(notif) { backtrace("Destroy_All_Notifications(): Missing notification entity!\n"); return; } \ + if (!notif) { backtrace("Destroy_All_Notifications(): Missing notification entity!\n"); return; } \ Destroy_Notification_Entity(notif); \ } @@ -257,7 +281,7 @@ string Process_Notif_Line( // done to both MSG_INFO and MSG_CENTER if(substring(input, (strlen(input) - 1), 1) == "\n") { - print(sprintf( + printf( strcat( "^1TRAILING NEW LINE AT END OF NOTIFICATION: ", "^7net_type = %s, net_name = %s, string = %s.\n" @@ -265,7 +289,7 @@ string Process_Notif_Line( notiftype, notifname, stringtype - )); + ); notif_error = TRUE; input = substring(input, 1, (strlen(input) - 1)); } @@ -292,7 +316,7 @@ string Process_Notif_Args( { if(sel_num == NOTIF_MAX_ARGS) { - print(sprintf( + printf( strcat( "^1NOTIFICATION HAS TOO MANY ARGUMENTS: ", "^7net_type = %s, net_name = %s, max args = %d.\n" @@ -300,22 +324,31 @@ string Process_Notif_Args( notiftype, notifname, NOTIF_MAX_ARGS - )); + ); notif_error = TRUE; break; } switch(strtolower(selected)) { - #define ARG_CASE(prog,selected,result) \ - #if (prog != ARG_DC) \ - case selected: { ++sel_num; break; } \ - #endif + #define ARG_CASE_ARG_CS_SV_HA(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE_ARG_CS_SV_DC(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE_ARG_CS_SV(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE_ARG_CS(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE_ARG_SV(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE_ARG_DC(selected,result) + #define ARG_CASE(prog,selected,result) ARG_CASE_##prog(selected,result) NOTIF_ARGUMENT_LIST #undef ARG_CASE + #undef ARG_CASE_ARG_DC + #undef ARG_CASE_ARG_SV + #undef ARG_CASE_ARG_CS + #undef ARG_CASE_ARG_CS_SV + #undef ARG_CASE_ARG_CS_SV_DC + #undef ARG_CASE_ARG_CS_SV_HA default: { - print(sprintf( + printf( strcat( "^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: ", "^7net_type = %s, net_name = %s, args arg = '%s'.\n" @@ -323,7 +356,7 @@ string Process_Notif_Args( notiftype, notifname, selected - )); + ); notif_error = TRUE; break; } @@ -334,7 +367,7 @@ string Process_Notif_Args( { if(sel_num == NOTIF_MAX_HUDARGS) { - print(sprintf( + printf( strcat( "^1NOTIFICATION HAS TOO MANY ARGUMENTS: ", "^7net_type = %s, net_name = %s, max hudargs = %d.\n" @@ -342,22 +375,31 @@ string Process_Notif_Args( notiftype, notifname, NOTIF_MAX_HUDARGS - )); + ); notif_error = TRUE; break; } switch(strtolower(selected)) { - #define ARG_CASE(prog,selected,result) \ - #if (prog == ARG_CS_SV_HA) \ - case selected: { ++sel_num; break; } \ - #endif + #define ARG_CASE_ARG_CS_SV_HA(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE_ARG_CS_SV_DC(selected,result) + #define ARG_CASE_ARG_CS_SV(selected,result) + #define ARG_CASE_ARG_CS(selected,result) + #define ARG_CASE_ARG_SV(selected,result) + #define ARG_CASE_ARG_DC(selected,result) + #define ARG_CASE(prog,selected,result) ARG_CASE_##prog(selected,result) NOTIF_ARGUMENT_LIST #undef ARG_CASE + #undef ARG_CASE_ARG_DC + #undef ARG_CASE_ARG_SV + #undef ARG_CASE_ARG_CS + #undef ARG_CASE_ARG_CS_SV + #undef ARG_CASE_ARG_CS_SV_DC + #undef ARG_CASE_ARG_CS_SV_HA default: { - print(sprintf( + printf( strcat( "^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: ", "^7net_type = %s, net_name = %s, hudargs arg = '%s'.\n" @@ -365,18 +407,18 @@ string Process_Notif_Args( notiftype, notifname, selected - )); + ); notif_error = TRUE; break; } } break; } - case 3: // durcnt + case 3: // durcnt { if(sel_num == NOTIF_MAX_DURCNT) { - print(sprintf( + printf( strcat( "^1NOTIFICATION HAS TOO MANY ARGUMENTS: ", "^7net_type = %s, net_name = %s, max durcnt = %d.\n" @@ -384,25 +426,34 @@ string Process_Notif_Args( notiftype, notifname, NOTIF_MAX_DURCNT - )); + ); notif_error = TRUE; break; } switch(strtolower(selected)) { - #define ARG_CASE(prog,selected,result) \ - #if (prog == ARG_CS_SV_DC) || (prog == ARG_DC) \ - case selected: { ++sel_num; break; } \ - #endif + #define ARG_CASE_ARG_CS_SV_HA(selected,result) + #define ARG_CASE_ARG_CS_SV_DC(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE_ARG_CS_SV(selected,result) + #define ARG_CASE_ARG_CS(selected,result) + #define ARG_CASE_ARG_SV(selected,result) + #define ARG_CASE_ARG_DC(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE(prog,selected,result) ARG_CASE_##prog(selected,result) NOTIF_ARGUMENT_LIST #undef ARG_CASE + #undef ARG_CASE_ARG_DC + #undef ARG_CASE_ARG_SV + #undef ARG_CASE_ARG_CS + #undef ARG_CASE_ARG_CS_SV + #undef ARG_CASE_ARG_CS_SV_DC + #undef ARG_CASE_ARG_CS_SV_HA default: { if(ftos(stof(selected)) != "") { ++sel_num; } else { - print(sprintf( + printf( strcat( "^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: ", "^7net_type = %s, net_name = %s, durcnt arg = '%s'.\n" @@ -410,7 +461,7 @@ string Process_Notif_Args( notiftype, notifname, selected - )); + ); notif_error = TRUE; } break; @@ -429,15 +480,14 @@ void Create_Notification_Entity( float typeid, float nameid, string namestring, - float anncename, - float infoname, - float centername, + float strnum, + float flnum, + /* MSG_ANNCE */ float channel, string snd, float vol, float position, - float strnum, - float flnum, + /* MSG_INFO & MSG_CENTER */ string args, string hudargs, string icon, @@ -445,6 +495,13 @@ void Create_Notification_Entity( 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) @@ -453,40 +510,34 @@ void Create_Notification_Entity( // Global Entity Setup // ===================== entity notif = spawn(); - string typestring = ""; switch(typeid) { case MSG_ANNCE: { - typestring = "MSG_ANNCE"; msg_annce_notifs[nameid - 1] = notif; notif.classname = "msg_annce_notification"; break; } case MSG_INFO: { - typestring = "MSG_INFO"; msg_info_notifs[nameid - 1] = notif; notif.classname = "msg_info_notification"; break; } case MSG_CENTER: { - typestring = "MSG_CENTER"; msg_center_notifs[nameid - 1] = notif; notif.classname = "msg_center_notification"; break; } case MSG_MULTI: { - typestring = "MSG_MULTI"; msg_multi_notifs[nameid - 1] = notif; notif.classname = "msg_multi_notification"; break; } case MSG_CHOICE: { - typestring = "MSG_CHOICE"; msg_choice_notifs[nameid - 1] = notif; notif.classname = "msg_choice_notification"; break; @@ -506,9 +557,12 @@ void Create_Notification_Entity( } } notif.nent_default = var_default; - notif.nent_name = strzone(namestring); - notif.nent_id = nameid; notif.nent_enabled = (1 <= var_cvar); + notif.nent_type = typeid; + notif.nent_id = nameid; + notif.nent_name = strzone(namestring); + + string typestring = Get_Notif_TypeName(typeid); // Other pre-notif-setup requisites notif_error = FALSE; @@ -522,7 +576,7 @@ void Create_Notification_Entity( { // Set MSG_ANNCE information and handle precaching #ifdef CSQC - if not(GENTLE && (var_cvar == 1)) + if (!(GENTLE && (var_cvar == 1))) { if(snd != "") { @@ -537,14 +591,14 @@ void Create_Notification_Entity( } else { - print(sprintf( + printf( strcat( "^1NOTIFICATION WITH NO SOUND: ", "^7net_type = %s, net_name = %s.\n" ), typestring, namestring - )); + ); notif_error = TRUE; } } @@ -555,7 +609,7 @@ void Create_Notification_Entity( break; } - + case MSG_INFO: case MSG_CENTER: { @@ -584,7 +638,7 @@ void Create_Notification_Entity( } else if((hudargs == "") && (durcnt =="")) { - print(sprintf( + printf( strcat( "^1NOTIFICATION HAS ARG COUNTS BUT NO ARGS OR HUDARGS OR DURCNT: ", "^7net_type = %s, net_name = %s, strnum = %d, flnum = %d\n" @@ -593,7 +647,7 @@ void Create_Notification_Entity( namestring, strnum, flnum - )); + ); notif_error = TRUE; } } @@ -614,31 +668,31 @@ void Create_Notification_Entity( { notif.nent_hudargs = strzone( Process_Notif_Args(2, hudargs, typestring, namestring)); - + if(icon != "") { notif.nent_icon = strzone(icon); } else { - print(sprintf( + printf( strcat( "^1NOTIFICATION HAS HUDARGS BUT NO ICON: ", "^7net_type = %s, net_name = %s.\n" ), typestring, namestring - )); + ); notif_error = TRUE; } } else if(icon != "") { - print(sprintf( + printf( strcat( "^1NOTIFICATION HAS ICON BUT NO HUDARGS: ", "^7net_type = %s, net_name = %s.\n" ), typestring, namestring - )); + ); notif_error = TRUE; } @@ -646,21 +700,21 @@ void Create_Notification_Entity( { notif.nent_durcnt = strzone( Process_Notif_Args(3, durcnt, typestring, namestring)); - + if(cpid != NO_MSG) { notif.nent_cpid = cpid; } else { - print(sprintf( + printf( strcat( "^1NOTIFICATION HAS DURCNT BUT NO CPID: ", "^7net_type = %s, net_name = %s.\n" ), typestring, namestring - )); + ); notif_error = TRUE; } - } + } else if(cpid != NO_MSG) { notif.nent_cpid = cpid; } #endif @@ -686,20 +740,20 @@ void Create_Notification_Entity( else if(normal != "") { SET_NOTIF_STRING(normal, "NORMAL") } } else if(normal != "") { SET_NOTIF_STRING(normal, "NORMAL") } - + #undef SET_NOTIF_STRING // Check to make sure a string was chosen if(notif.nent_string == "") { - print(sprintf( + printf( strcat( "^1EMPTY NOTIFICATION: ", "^7net_type = %s, net_name = %s.\n" ), typestring, namestring - )); + ); notif_error = TRUE; } } @@ -712,55 +766,154 @@ void Create_Notification_Entity( // Set MSG_MULTI string/float counts if((anncename == NO_MSG) && (infoname == NO_MSG) && (centername == NO_MSG)) { - print(sprintf( + printf( strcat( "^1NOTIFICATION WITH NO SUBCALLS: ", "^7net_type = %s, net_name = %s.\n" ), typestring, namestring - )); + ); notif_error = TRUE; } else { // announcements don't actually need any arguments, so lets not even count them. if(anncename != NO_MSG) { notif.nent_msgannce = msg_annce_notifs[anncename - 1]; } - + float infoname_stringcount = 0, infoname_floatcount = 0; float centername_stringcount = 0, centername_floatcount = 0; - + if(infoname != NO_MSG) { notif.nent_msginfo = msg_info_notifs[infoname - 1]; infoname_stringcount = notif.nent_msginfo.nent_stringcount; infoname_floatcount = notif.nent_msginfo.nent_floatcount; } - + if(centername != NO_MSG) { notif.nent_msgcenter = msg_center_notifs[centername - 1]; centername_stringcount = notif.nent_msgcenter.nent_stringcount; centername_floatcount = notif.nent_msgcenter.nent_floatcount; } - + // set the requirements of THIS notification to the totals of its subcalls notif.nent_stringcount = max(infoname_stringcount, centername_stringcount); notif.nent_floatcount = max(infoname_floatcount, centername_floatcount); } - + break; } case MSG_CHOICE: { + if((chtype == NO_MSG) || (optiona == NO_MSG) || (optionb == NO_MSG)) + { + printf( + strcat( + "^1NOTIFICATION IS MISSING CHOICE PARAMS: ", + "^7net_type = %s, net_name = %s.\n" + ), + typestring, + namestring + ); + notif_error = TRUE; + } + else + { + switch(chtype) + { + case MSG_ANNCE: + { + notif.nent_optiona = msg_annce_notifs[optiona - 1]; + notif.nent_optionb = msg_annce_notifs[optionb - 1]; + break; + } + case MSG_INFO: + { + notif.nent_optiona = msg_info_notifs[optiona - 1]; + notif.nent_optionb = msg_info_notifs[optionb - 1]; + break; + } + case MSG_CENTER: + { + notif.nent_optiona = msg_center_notifs[optiona - 1]; + notif.nent_optionb = msg_center_notifs[optionb - 1]; + break; + } + case MSG_MULTI: + { + notif.nent_optiona = msg_multi_notifs[optiona - 1]; + notif.nent_optionb = msg_multi_notifs[optionb - 1]; + break; + } + case MSG_CHOICE: // should we REALLY allow nested options?... + { + notif.nent_optiona = msg_choice_notifs[optiona - 1]; + notif.nent_optionb = msg_choice_notifs[optionb - 1]; + break; + } + + default: + { + printf( + strcat( + "^1NOTIFICATION WITH IMPROPER TYPE: ", + "^7net_type = %d, net_name = %s.\n" + ), + typeid, + namestring + ); + notif_error = TRUE; + break; + } + } + notif.nent_challow_def = challow_def; // 0: never allowed, 1: allowed in warmup, 2: always allowed + notif.nent_challow_var = challow_var; // 0: never allowed, 1: allowed in warmup, 2: always allowed + notif.nent_stringcount = max(notif.nent_optiona.nent_stringcount, notif.nent_optionb.nent_stringcount); + notif.nent_floatcount = max(notif.nent_optiona.nent_floatcount, notif.nent_optionb.nent_floatcount); + + /*#ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Create_Notification_Entity(...): MSG_CHOICE: %s\n%s\n%s\n", + notif.nent_name, + sprintf( + "^ optiona: %s %s : %d %d", + Get_Notif_TypeName(notif.nent_optiona.nent_type), + notif.nent_optiona.nent_name, + notif.nent_optiona.nent_stringcount, + notif.nent_optiona.nent_floatcount + ), + sprintf( + "^ optionb: %s %s : %d %d", + Get_Notif_TypeName(notif.nent_optionb.nent_type), + notif.nent_optionb.nent_name, + notif.nent_optionb.nent_stringcount, + notif.nent_optionb.nent_floatcount + ) + )); + #endif*/ + } + break; + } + + default: + { + printf( + strcat( + "^1NOTIFICATION WITH IMPROPER TYPE: ", + "^7net_type = %d, net_name = %s.\n" + ), + typeid, + namestring + ); + notif_error = TRUE; break; } - - default: print("DAFUQ?\n"); notif_error = TRUE; break; } - // now check to see if any errors happened + // now check to see if any errors happened if(notif_error) { notif.nent_enabled = FALSE; // disable the notification so it can't cause trouble @@ -769,10 +922,28 @@ void Create_Notification_Entity( } -// ========================================= -// Cvar Handling With 'dumpnotifs' Command -// ========================================= +// =============== +// Cvar Handling +// =============== + +// used by MSG_CHOICE to build list of choices +#ifdef SVQC +void Notification_GetCvars(void) +{ + float i; + for(i = 0; i <= NOTIF_CHOICE_COUNT; ++i) + { + GetCvars_handleFloat( + get_cvars_s, + get_cvars_f, + msg_choice_choices[i], + sprintf("notification_%s", msg_choice_notifs[i].nent_name) + ); + } +} +#endif +// used to output notifications.cfg file void Dump_Notifications(float fh, float alsoprint) { #define NOTIF_WRITE(a) { \ @@ -785,6 +956,15 @@ void Dump_Notifications(float fh, float alsoprint) e.nent_name, e.nent_default, description \ ); \ NOTIF_WRITE(notif_msg) } + #define NOTIF_WRITE_ENTITY_CHOICE(descriptiona,descriptionb) { \ + notif_msg = \ + sprintf( \ + "seta notification_%s \"%d\" \"%s\"\n" \ + "seta notification_%s_ALLOWED \"%d\" \"%s\"\n", \ + e.nent_name, e.nent_default, descriptiona, \ + e.nent_name, e.nent_challow_def, descriptionb \ + ); \ + NOTIF_WRITE(notif_msg) } #define NOTIF_WRITE_HARDCODED(cvar,default,description) { \ notif_msg = \ sprintf( \ @@ -824,8 +1004,8 @@ void Dump_Notifications(float fh, float alsoprint) for(i = 1; i <= NOTIF_ANNCE_COUNT; ++i) { e = Get_Notif_Ent(MSG_ANNCE, i); - if not(e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; } - + if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; } + NOTIF_WRITE_ENTITY( "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)" ); @@ -835,8 +1015,8 @@ void Dump_Notifications(float fh, float alsoprint) for(i = 1; i <= NOTIF_INFO_COUNT; ++i) { e = Get_Notif_Ent(MSG_INFO, i); - if not(e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; } - + if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; } + NOTIF_WRITE_ENTITY( "Notification control cvar: 0 = off, 1 = print to console, " "2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" @@ -847,8 +1027,8 @@ void Dump_Notifications(float fh, float alsoprint) for(i = 1; i <= NOTIF_CENTER_COUNT; ++i) { e = Get_Notif_Ent(MSG_CENTER, i); - if not(e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; } - + if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; } + NOTIF_WRITE_ENTITY( "Notification control cvar: 0 = off, 1 = centerprint" ); @@ -858,8 +1038,8 @@ void Dump_Notifications(float fh, float alsoprint) for(i = 1; i <= NOTIF_MULTI_COUNT; ++i) { e = Get_Notif_Ent(MSG_MULTI, i); - if not(e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; } - + if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; } + NOTIF_WRITE_ENTITY( "Notification control cvar: 0 = off, 1 = trigger subcalls" ); @@ -869,119 +1049,94 @@ void Dump_Notifications(float fh, float alsoprint) for(i = 1; i <= NOTIF_CHOICE_COUNT; ++i) { e = Get_Notif_Ent(MSG_CHOICE, i); - if not(e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; } - - NOTIF_WRITE_ENTITY( - "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall" + if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; } + + NOTIF_WRITE_ENTITY_CHOICE( + "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall", + "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed" ); } // edit these to match whichever cvars are used for specific notification options NOTIF_WRITE("\n// HARD CODED notification variables:\n"); - + NOTIF_WRITE_HARDCODED( "allow_chatboxprint", "1", "Allow notifications to be printed to chat box by setting notification cvar to 2 " "(You can also set this cvar to 2 to force ALL notifications to be printed to the chatbox)" ); - - NOTIF_WRITE_HARDCODED( - "ctf_capture_verbose", "0", - "Show extra information when someone captures a flag" - ); - - NOTIF_WRITE_HARDCODED( - "ctf_pickup_enemy_verbose", "0", - "Show extra information if an enemy picks up a flag" - ); - - NOTIF_WRITE_HARDCODED( - "ctf_pickup_team_verbose", "0", - "Show extra information if a team mate picks up a flag" - ); - + NOTIF_WRITE_HARDCODED( "debug", "0", "Print extra debug information on all notification function calls " "(Requires -DNOTIFICATIONS_DEBUG flag to be enabled on QCSRC compilation)... " "0 = disabled, 1 = dprint, 2 = print" ); - + NOTIF_WRITE_HARDCODED( "errors_are_fatal", "1", "If a notification fails upon initialization, cause a Host_Error to stop the program" ); - - NOTIF_WRITE_HARDCODED( - "frag_verbose", "1", - "Show extra information when you frag someone (or when you are fragged" - ); - + NOTIF_WRITE_HARDCODED( "item_centerprinttime", "1.5", "How long to show item information centerprint messages (like 'You got the Electro' or such)" ); - + NOTIF_WRITE_HARDCODED( "lifetime_mapload", "10", "Amount of time that notification entities last immediately at mapload (in seconds) " "to help prevent notifications from being lost on early init (like gamestart countdown)" ); - + NOTIF_WRITE_HARDCODED( "lifetime_runtime", "0.5", "Amount of time that notification entities last on the server during runtime (In seconds)" ); - - NOTIF_WRITE_HARDCODED( - "server_allows_frag_verbose", "1", - "Server side cvar for showing extra information in frag messages... 0 = no extra frag information, " - "1 = frag information only in warmup, 2 = frag information allowed all the time" - ); - + NOTIF_WRITE_HARDCODED( "server_allows_location", "1", "Server side cvar for allowing death messages to show location information too" ); - + NOTIF_WRITE_HARDCODED( "show_location", "0", "Append location information to MSG_INFO death/kill messages" ); - + NOTIF_WRITE_HARDCODED( "show_location_string", "", "Replacement string piped into sprintf, " "so you can do different messages like this: ' at the %s' or ' (near %s)'" ); - + NOTIF_WRITE_HARDCODED( "show_sprees", "1", "Print information about sprees in death/kill messages" ); - + NOTIF_WRITE_HARDCODED( "show_sprees_center", "1", "Show spree information in MSG_CENTER messages... " "0 = off, 1 = target (but only for first victim) and attacker" ); - + NOTIF_WRITE_HARDCODED( "show_sprees_center_specialonly", "1", "Don't show spree information in MSG_CENTER messages if it isn't an achievement" ); - + NOTIF_WRITE_HARDCODED( "show_sprees_info", "3", "Show spree information in MSG_INFO messages... " "0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker" ); - + NOTIF_WRITE_HARDCODED( "show_sprees_info_newline", "1", "Show attacker spree information for MSG_INFO messages on a separate line than the death notification itself" ); - + NOTIF_WRITE_HARDCODED( "show_sprees_info_specialonly", "1", "Don't show attacker spree information in MSG_INFO messages if it isn't an achievement" @@ -1005,20 +1160,13 @@ void Dump_Notifications(float fh, float alsoprint) NOTIF_MULTI_COUNT, NOTIF_CHOICE_COUNT )); - + return; #undef NOTIF_WRITE_HARDCODED #undef NOTIF_WRITE_ENTITY #undef NOTIF_WRITE } -#ifdef SVQC -void Notification_GetCvars() -{ - GetCvars_handleFloat(get_cvars_s, get_cvars_f, FRAG_VERBOSE, "notification_frag_verbose"); -} -#endif - // =============================== // Frontend Notification Pushing @@ -1036,7 +1184,7 @@ void Debug_Notification(string input) #endif string Local_Notification_sprintf( - string input, string args, + string input, string args, string s1, string s2, string s3, string s4, float f1, float f2, float f3, float f4) { @@ -1049,7 +1197,7 @@ string Local_Notification_sprintf( sprintf("%d, %d, %d, %d", f1, f2, f3, f4) )); #endif - + string selected; float sel_num; for(sel_num = 0; sel_num < NOTIF_MAX_ARGS; ++sel_num) { arg_slot[sel_num] = ""; } @@ -1062,22 +1210,43 @@ string Local_Notification_sprintf( NOTIF_HIT_MAX(NOTIF_MAX_ARGS, "Local_Notification_sprintf") switch(strtolower(selected)) { - #define ARG_CASE(prog,selected,result) \ - #ifdef CSQC \ - #if (prog != ARG_SV) && (prog != ARG_DC) \ - case selected: { arg_slot[sel_num] = result; ++sel_num; break; } \ - #endif \ - #else \ - #if (prog != ARG_CS) && (prog != ARG_DC) \ - case selected: { arg_slot[sel_num] = result; ++sel_num; break; } \ - #endif \ - #endif + #ifdef CSQC + #define ARG_CASE_ARG_CS_SV_HA(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } + #define ARG_CASE_ARG_CS_SV_DC(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } + #define ARG_CASE_ARG_CS_SV(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } + #define ARG_CASE_ARG_CS(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } + #define ARG_CASE_ARG_SV(selected,result) + #define ARG_CASE_ARG_DC(selected,result) + #else + #define ARG_CASE_ARG_CS_SV_HA(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } + #define ARG_CASE_ARG_CS_SV_DC(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } + #define ARG_CASE_ARG_CS_SV(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } + #define ARG_CASE_ARG_CS(selected,result) + #define ARG_CASE_ARG_SV(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } + #define ARG_CASE_ARG_DC(selected,result) + #endif + #define ARG_CASE(prog,selected,result) ARG_CASE_##prog(selected,result) NOTIF_ARGUMENT_LIST #undef ARG_CASE + #undef ARG_CASE_ARG_DC + #undef ARG_CASE_ARG_SV + #undef ARG_CASE_ARG_CS + #undef ARG_CASE_ARG_CS_SV + #undef ARG_CASE_ARG_CS_SV_DC + #undef ARG_CASE_ARG_CS_SV_HA default: NOTIF_HIT_UNKNOWN(NOTIF_MAX_ARGS, "Local_Notification_sprintf") } } - return sprintf(strcat(input, "\n"), arg_slot[0], arg_slot[1], arg_slot[2], arg_slot[3], arg_slot[4], arg_slot[5], arg_slot[6]); + return sprintf( + strcat(input, "\n"), + arg_slot[0], + arg_slot[1], + arg_slot[2], + arg_slot[3], + arg_slot[4], + arg_slot[5], + arg_slot[6] + ); } #ifdef CSQC @@ -1100,7 +1269,7 @@ void Local_Notification_sound( soundposition )); #endif - + sound( world, soundchannel, @@ -1112,7 +1281,7 @@ void Local_Notification_sound( soundvolume, soundposition ); - + if(prev_soundfile) { strunzone(prev_soundfile); } prev_soundfile = strzone(soundfile); prev_soundtime = time; @@ -1143,7 +1312,8 @@ void Local_Notification_sound( void Local_Notification_HUD_Notify_Push( string icon, string hudargs, - string s1, string s2, string s3, string s4) + string s1, string s2, string s3, string s4, + float f1, float f2, float f3, float f4) { string selected; float sel_num; @@ -1155,21 +1325,31 @@ void Local_Notification_HUD_Notify_Push( NOTIF_HIT_MAX(NOTIF_MAX_HUDARGS, "Local_Notification_HUD_Notify_Push") switch(strtolower(selected)) { - #define ARG_CASE(prog,selected,result) \ - #if (prog == ARG_CS_SV_HA) \ - case selected: { arg_slot[sel_num] = result; ++sel_num; break; } \ - #endif + #define ARG_CASE_ARG_CS_SV_HA(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } + #define ARG_CASE_ARG_CS_SV_DC(selected,result) + #define ARG_CASE_ARG_CS_SV(selected,result) + #define ARG_CASE_ARG_CS(selected,result) + #define ARG_CASE_ARG_SV(selected,result) + #define ARG_CASE_ARG_DC(selected,result) + #define ARG_CASE(prog,selected,result) ARG_CASE_##prog(selected,result) NOTIF_ARGUMENT_LIST #undef ARG_CASE + #undef ARG_CASE_ARG_DC + #undef ARG_CASE_ARG_SV + #undef ARG_CASE_ARG_CS + #undef ARG_CASE_ARG_CS_SV + #undef ARG_CASE_ARG_CS_SV_DC + #undef ARG_CASE_ARG_CS_SV_HA default: NOTIF_HIT_UNKNOWN(NOTIF_MAX_HUDARGS, "Local_Notification_HUD_Notify_Push") } } #ifdef NOTIFICATIONS_DEBUG Debug_Notification(sprintf( - "Local_Notification_HUD_Notify_Push('%s^7', '%s', %s, %s);\n", + "Local_Notification_HUD_Notify_Push('%s^7', '%s', %s, %s, %s);\n", icon, hudargs, MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), + sprintf("%d, %d, %d, %d", f1, f2, f3, f4), MakeConsoleSafe(sprintf("'%s^7', '%s^7'", stof(arg_slot[0]), stof(arg_slot[1]))) )); #endif @@ -1190,12 +1370,21 @@ void Local_Notification_centerprint_generic( NOTIF_HIT_MAX(NOTIF_MAX_DURCNT, "Local_Notification_centerprint_generic") switch(strtolower(selected)) { - #define ARG_CASE(prog,selected,result) \ - #if (prog == ARG_CS_SV_DC) || (prog == ARG_DC) \ - case selected: { arg_slot[sel_num] = result; ++sel_num; break; } \ - #endif + #define ARG_CASE_ARG_CS_SV_HA(selected,result) + #define ARG_CASE_ARG_CS_SV_DC(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } + #define ARG_CASE_ARG_CS_SV(selected,result) + #define ARG_CASE_ARG_CS(selected,result) + #define ARG_CASE_ARG_SV(selected,result) + #define ARG_CASE_ARG_DC(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } + #define ARG_CASE(prog,selected,result) ARG_CASE_##prog(selected,result) NOTIF_ARGUMENT_LIST #undef ARG_CASE + #undef ARG_CASE_ARG_DC + #undef ARG_CASE_ARG_SV + #undef ARG_CASE_ARG_CS + #undef ARG_CASE_ARG_CS_SV + #undef ARG_CASE_ARG_CS_SV_DC + #undef ARG_CASE_ARG_CS_SV_HA default: { if(ftos(stof(selected)) != "") { arg_slot[sel_num] = selected; ++sel_num; } @@ -1210,7 +1399,8 @@ void Local_Notification_centerprint_generic( MakeConsoleSafe(input), durcnt, f1, f2, - stof(arg_slot[0]), stof(arg_slot[1]) + stof(arg_slot[0]), + stof(arg_slot[1]) )); #endif centerprint_generic(cpid, input, stof(arg_slot[0]), stof(arg_slot[1])); @@ -1219,48 +1409,59 @@ void Local_Notification_centerprint_generic( void Local_Notification(float net_type, float net_name, ...count) { + // check if this should be aborted + if(net_name == NOTIF_ABORT) + { + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Local_Notification(%s, %s, ...);\n", + Get_Notif_TypeName(net_type), + "NOTIF_ABORT" + )); + #endif + return; + } + // check supplied type and name for errors string checkargs = Notification_CheckArgs_TypeName(net_type, net_name); - if(checkargs != "") { backtrace(sprintf("Incorrect usage of Local_Notification: %s\n", checkargs)); return; } - - entity notif = Get_Notif_Ent(net_type, net_name); - if not(notif) { backtrace("Local_Notification: Could not find notification entity!\n"); return; } - if not(notif.nent_enabled) + if(checkargs != "") { #ifdef NOTIFICATIONS_DEBUG Debug_Notification(sprintf( - "Local_Notification(%s, %s): Entity was disabled...\n", + "Local_Notification(%s, %d, ...);\n", Get_Notif_TypeName(net_type), - notif.nent_name + Get_Notif_Ent(net_type, net_name).nent_name )); #endif + backtrace(sprintf("Incorrect usage of Local_Notification: %s\n", checkargs)); return; } - - if((notif.nent_stringcount + notif.nent_floatcount) > count) + + // retreive entity of this notification + entity notif = Get_Notif_Ent(net_type, net_name); + if (!notif) { - backtrace(sprintf( - strcat( - "Not enough arguments for Local_Notification(%s, %s, ...)! ", - "stringcount(%d) + floatcount(%d) > count(%d)\n", - "Check the definition and function call for accuracy...?\n" - ), - Get_Notif_TypeName(net_type), notif.nent_name, - notif.nent_stringcount, notif.nent_floatcount, count + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Local_Notification(%s, %d, ...);\n", + Get_Notif_TypeName(net_type), + net_name )); + #endif + backtrace("Local_Notification: Could not find notification entity!\n"); return; } - else if((notif.nent_stringcount + notif.nent_floatcount) < count) + + // check if the notification is enabled + if (!notif.nent_enabled) { - backtrace(sprintf( - strcat( - "Too many arguments for Local_Notification(%s, %s, ...)! ", - "stringcount(%d) + floatcount(%d) < count(%d)\n", - "Check the definition and function call for accuracy...?\n" - ), - Get_Notif_TypeName(net_type), notif.nent_name, - notif.nent_stringcount, notif.nent_floatcount, count + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Local_Notification(%s, %s, ...): Entity was disabled...\n", + Get_Notif_TypeName(net_type), + notif.nent_name )); + #endif return; } @@ -1282,7 +1483,40 @@ void Local_Notification(float net_type, float net_name, ...count) sprintf("%d, %d, %d, %d", f1, f2, f3, f4) )); #endif - + + if((notif.nent_stringcount + notif.nent_floatcount) > count) + { + backtrace(sprintf( + strcat( + "Not enough arguments for Local_Notification(%s, %s, ...)! ", + "stringcount(%d) + floatcount(%d) > count(%d)\n", + "Check the definition and function call for accuracy...?\n" + ), + Get_Notif_TypeName(net_type), + notif.nent_name, + notif.nent_stringcount, + notif.nent_floatcount, + count + )); + return; + } + else if((notif.nent_stringcount + notif.nent_floatcount) < count) + { + backtrace(sprintf( + strcat( + "Too many arguments for Local_Notification(%s, %s, ...)! ", + "stringcount(%d) + floatcount(%d) < count(%d)\n", + "Check the definition and function call for accuracy...?\n" + ), + Get_Notif_TypeName(net_type), + notif.nent_name, + notif.nent_stringcount, + notif.nent_floatcount, + count + )); + return; + } + switch(net_type) { case MSG_ANNCE: @@ -1299,35 +1533,36 @@ void Local_Notification(float net_type, float net_name, ...count) #endif break; } - + case MSG_INFO: { print( Local_Notification_sprintf( notif.nent_string, - notif.nent_args, + notif.nent_args, s1, s2, s3, s4, f1, f2, f3, f4) ); - #ifdef CSQC + #ifdef CSQC if(notif.nent_icon != "") { Local_Notification_HUD_Notify_Push( notif.nent_icon, notif.nent_hudargs, - s1, s2, s3, s4); - } - #endif + s1, s2, s3, s4, + f1, f2, f3, f4); + } + #endif break; } - + #ifdef CSQC case MSG_CENTER: { Local_Notification_centerprint_generic( Local_Notification_sprintf( notif.nent_string, - notif.nent_args, + notif.nent_args, s1, s2, s3, s4, f1, f2, f3, f4), notif.nent_durcnt, @@ -1336,7 +1571,7 @@ void Local_Notification(float net_type, float net_name, ...count) break; } #endif - + case MSG_MULTI: { if(notif.nent_msginfo) @@ -1344,9 +1579,9 @@ void Local_Notification(float net_type, float net_name, ...count) { Local_Notification_WOVA( MSG_INFO, - notif.nent_msginfo.nent_id, - notif.nent_msginfo.nent_stringcount, - notif.nent_msginfo.nent_floatcount, + notif.nent_msginfo.nent_id, + notif.nent_msginfo.nent_stringcount, + notif.nent_msginfo.nent_floatcount, s1, s2, s3, s4, f1, f2, f3, f4); } @@ -1356,8 +1591,8 @@ void Local_Notification(float net_type, float net_name, ...count) { Local_Notification_WOVA( MSG_ANNCE, - notif.nent_msgannce.nent_id, - 0, 0, + notif.nent_msgannce.nent_id, + 0, 0, "", "", "", "", 0, 0, 0, 0); } @@ -1366,19 +1601,43 @@ void Local_Notification(float net_type, float net_name, ...count) { Local_Notification_WOVA( MSG_CENTER, - notif.nent_msgcenter.nent_id, - notif.nent_msgcenter.nent_stringcount, - notif.nent_msgcenter.nent_floatcount, + notif.nent_msgcenter.nent_id, + notif.nent_msgcenter.nent_stringcount, + notif.nent_msgcenter.nent_floatcount, s1, s2, s3, s4, - f1, f2, f3, f4); + f1, f2, f3, f4); } #endif break; } + + case MSG_CHOICE: + { + entity found_choice; + + if(notif.nent_challow_var && (warmup_stage || (notif.nent_challow_var == 2))) + { + switch(cvar_string(sprintf("notification_%s", notif.nent_name))) + { + case 1: found_choice = notif.nent_optiona; break; + case 2: found_choice = notif.nent_optionb; break; + default: return; // not enabled anyway + } + } + else { found_choice = notif.nent_optiona; } + + Local_Notification_WOVA( + found_choice.nent_type, + found_choice.nent_id, + found_choice.nent_stringcount, + found_choice.nent_floatcount, + s1, s2, s3, s4, + f1, f2, f3, f4); + } } } -// WOVA = Without Variable Arguments +// WOVA = Without Variable Arguments void Local_Notification_WOVA( float net_type, float net_name, float stringcount, float floatcount, @@ -1417,7 +1676,7 @@ void Read_Notification(float is_new) net_name )); #endif - + if(is_new) { if(net_name == 0) { reset_centerprint_messages(); } @@ -1433,13 +1692,13 @@ void Read_Notification(float is_new) is_new, time )); - } + } } } else { notif = Get_Notif_Ent(net_type, net_name); - if not(notif) { backtrace("Read_Notification: Could not find notification entity!\n"); return; } + if (!notif) { backtrace("Read_Notification: Could not find notification entity!\n"); return; } #ifdef NOTIFICATIONS_DEBUG Debug_Notification(sprintf( @@ -1459,7 +1718,7 @@ void Read_Notification(float is_new) float f2 = ((1 < notif.nent_floatcount) ? ReadLong() : 0); float f3 = ((2 < notif.nent_floatcount) ? ReadLong() : 0); float f4 = ((3 < notif.nent_floatcount) ? ReadLong() : 0); - + if(is_new) { Local_Notification_WOVA( @@ -1476,8 +1735,8 @@ void Read_Notification(float is_new) #ifdef SVQC void Net_Notification_Remove() { - if not(self) { backtrace(sprintf("Net_Notification_Remove() at %f: Missing self!?\n", time)); return; } - + if (!self) { backtrace(sprintf("Net_Notification_Remove() at %f: Missing self!?\n", time)); return; } + #ifdef NOTIFICATIONS_DEBUG Debug_Notification(sprintf( "Net_Notification_Remove() at %f: %s '%s - %s' notification\n", @@ -1487,7 +1746,7 @@ void Net_Notification_Remove() self.owner.nent_name )); #endif - + float i; for(i = 0; i < 4; ++i) { if(self.nent_strings[i]) { strunzone(self.nent_strings[i]); } } remove(self); @@ -1501,7 +1760,7 @@ float Net_Write_Notification(entity client, float sf) WriteByte(MSG_ENTITY, ENT_CLIENT_NOTIFICATION); WriteByte(MSG_ENTITY, self.nent_net_type); WriteShort(MSG_ENTITY, self.nent_net_name); - for(i = 0; i < self.nent_stringcount; ++i) { WriteString(MSG_ENTITY, self.nent_strings[i]); } + for(i = 0; i < self.nent_stringcount; ++i) { WriteString(MSG_ENTITY, self.nent_strings[i]); } for(i = 0; i < self.nent_floatcount; ++i) { WriteLong(MSG_ENTITY, self.nent_floats[i]); } return TRUE; } @@ -1512,22 +1771,22 @@ void Kill_Notification( float broadcast, entity client, float net_type, float net_name) { - string checkargs = Notification_CheckArgs(broadcast, client, 1, 1); - if(checkargs != "") { backtrace(sprintf("Incorrect usage of Kill_Notification: %s\n", checkargs)); return; } - #ifdef NOTIFICATIONS_DEBUG Debug_Notification(sprintf( - "Kill_Notification(%d, '%s', %s, %d);\n", - broadcast, + "Kill_Notification(%s, '%s', %s, %d);\n", + Get_Notif_BroadcastName(broadcast), client.netname, (net_type ? Get_Notif_TypeName(net_type) : "0"), net_name )); #endif + string checkargs = Notification_CheckArgs(broadcast, client, 1, 1); + if(checkargs != "") { backtrace(sprintf("Incorrect usage of Kill_Notification: %s\n", checkargs)); return; } + entity notif, net_notif; float killed_cpid = NO_CPID; - + switch(net_type) { case 0: @@ -1535,14 +1794,14 @@ void Kill_Notification( killed_cpid = 0; // kill ALL centerprints break; } - + case MSG_CENTER: { if(net_name) { entity notif = Get_Notif_Ent(net_type, net_name); - if not(notif) { backtrace("Kill_Notification: Could not find notification entity!\n"); return; } - + if (!notif) { backtrace("Kill_Notification: Could not find notification entity!\n"); return; } + if(notif.nent_cpid) killed_cpid = notif.nent_cpid; else @@ -1606,38 +1865,52 @@ void Send_Notification( float net_type, float net_name, ...count) { + // check if this should be aborted + if(net_name == NOTIF_ABORT) + { + #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 + return; + } + // check supplied broadcast, target, type, and name for errors string checkargs = Notification_CheckArgs(broadcast, client, net_type, net_name); - if(checkargs != "") { backtrace(sprintf("Incorrect usage of Send_Notification: %s\n", checkargs)); return; } - - // retreive counts for the arguments of this notification - entity notif = Get_Notif_Ent(net_type, net_name); - if not(notif) { backtrace("Send_Notification: Could not find notification entity!\n"); return; } - - if((notif.nent_stringcount + notif.nent_floatcount) > count) + if(checkargs != "") { - backtrace(sprintf( - strcat( - "Not enough arguments for Send_Notification(%d, %s, %s, ...)! ", - "stringcount(%d) + floatcount(%d) > count(%d)\n", - "Check the definition and function call for accuracy...?\n" - ), - broadcast, Get_Notif_TypeName(net_type), notif.nent_name, - notif.nent_stringcount, notif.nent_floatcount, count + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Send_Notification(%s, '%s', %s, %s, ...);\n", + Get_Notif_BroadcastName(broadcast), + client.classname, + Get_Notif_TypeName(net_type), + Get_Notif_Ent(net_type, net_name).nent_name )); + #endif + backtrace(sprintf("Incorrect usage of Send_Notification: %s\n", checkargs)); return; } - else if((notif.nent_stringcount + notif.nent_floatcount) < count) + + // retreive entity of this notification + entity notif = Get_Notif_Ent(net_type, net_name); + if (!notif) { - backtrace(sprintf( - strcat( - "Too many arguments for Send_Notification(%d, %s, %s, ...)! ", - "stringcount(%d) + floatcount(%d) < count(%d)\n", - "Check the definition and function call for accuracy...?\n" - ), - broadcast, Get_Notif_TypeName(net_type), notif.nent_name, - notif.nent_stringcount, notif.nent_floatcount, count + #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"); return; } @@ -1652,15 +1925,72 @@ void Send_Notification( #ifdef NOTIFICATIONS_DEBUG Debug_Notification(sprintf( - "Send_Notification(%d, %s, %s, %s, %s);\n", - broadcast, - Get_Notif_TypeName(net_type), - notif.nent_name, + "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 + ), MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), sprintf("%d, %d, %d, %d", f1, f2, f3, f4) )); #endif + if((notif.nent_stringcount + notif.nent_floatcount) > count) + { + backtrace(sprintf( + strcat( + "Not enough arguments for Send_Notification(%s, ...)! ", + "stringcount(%d) + floatcount(%d) > count(%d)\n", + "Check the definition and function call for accuracy...?\n" + ), + sprintf( + #ifdef NOTIFICATIONS_DEBUG + "%s, '%s', %s, %s", + Get_Notif_BroadcastName(broadcast), + #else + "%d, '%s', %s, %s", + broadcast, + #endif + client.classname, + Get_Notif_TypeName(net_type), + notif.nent_name + ), + notif.nent_stringcount, + notif.nent_floatcount, + count + )); + return; + } + else if((notif.nent_stringcount + notif.nent_floatcount) < count) + { + backtrace(sprintf( + strcat( + "Too many arguments for Send_Notification(%s, ...)! ", + "stringcount(%d) + floatcount(%d) < count(%d)\n", + "Check the definition and function call for accuracy...?\n" + ), + sprintf( + #ifdef NOTIFICATIONS_DEBUG + "%s, '%s', %s, %s", + Get_Notif_BroadcastName(broadcast), + #else + "%d, '%s', %s, %s", + broadcast, + #endif + client.classname, + Get_Notif_TypeName(net_type), + notif.nent_name + ), + notif.nent_stringcount, + notif.nent_floatcount, + count + )); + return; + } + if( server_is_dedicated && @@ -1692,20 +2022,26 @@ void Send_Notification( // It's slow, but it's better than the alternatives: // 1. Constantly networking all info and letting client decide // 2. Manually handling each separate call on per-usage basis (See old CTF usage of verbose) - entity found_choice; + entity found_choice; #define RECURSE_FROM_CHOICE(ent,action) \ - switch(ent.msg_choice_choices[net_name]) \ + if(notif.nent_challow_var && (warmup_stage || (notif.nent_challow_var == 2))) \ { \ - case 1: found_choice = notif.nent_choicea; \ - case 2: found_choice = notif.nent_choiceb; \ - default: action; \ + switch(ent.msg_choice_choices[net_name]) \ + { \ + case 1: found_choice = notif.nent_optiona; break; \ + case 2: found_choice = notif.nent_optionb; break; \ + default: action; \ + } \ } \ + else { found_choice = notif.nent_optiona; } \ Send_Notification_WOVA( \ NOTIF_ONE_ONLY, \ ent, \ - found_choice.nent_net_type, \ - found_choice.nent_net_name, \ + found_choice.nent_type, \ + found_choice.nent_id, \ + found_choice.nent_stringcount, \ + found_choice.nent_floatcount, \ s1, s2, s3, s4, \ f1, f2, f3, f4); @@ -1738,7 +2074,7 @@ void Send_Notification( net_notif.nent_net_name = net_name; net_notif.nent_stringcount = notif.nent_stringcount; net_notif.nent_floatcount = notif.nent_floatcount; - + float i; for(i = 0; i < net_notif.nent_stringcount; ++i) { net_notif.nent_strings[i] = strzone(...(i, string)); } @@ -1752,32 +2088,70 @@ void Send_Notification( (time + autocvar_notification_lifetime_runtime) : autocvar_notification_lifetime_mapload - ); + ); Net_LinkEntity(net_notif, FALSE, 0, Net_Write_Notification); } } -// WOVA = Without Variable Arguments +// WOVA = Without Variable Arguments void Send_Notification_WOVA( float broadcast, entity client, float net_type, float net_name, + float stringcount, float floatcount, string s1, string s2, string s3, string s4, float f1, float f2, float f3, float f4) { + #ifdef NOTIFICATIONS_DEBUG entity notif = Get_Notif_Ent(net_type, net_name); - + Debug_Notification(sprintf( + "Send_Notification_WOVA(%s, %d, %d, %s, %s);\n", + sprintf( + "%s, '%s', %s, %s", + Get_Notif_BroadcastName(broadcast), + client.classname, + Get_Notif_TypeName(net_type), + notif.nent_name + ), + stringcount, + floatcount, + MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), + sprintf("%d, %d, %d, %d", f1, f2, f3, f4) + )); + #endif + + #define VARITEM(stringc,floatc,args) \ + if((stringcount == stringc) && (floatcount == floatc)) \ + { Send_Notification(broadcast, client, net_type, net_name, args); return; } + EIGHT_VARS_TO_VARARGS_VARLIST + #undef VARITEM + Send_Notification(broadcast, client, net_type, net_name); // some notifications don't have any arguments at all +} + +// WOCOVA = Without Counts Or Variable Arguments +void Send_Notification_WOCOVA( + 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) +{ + entity notif = Get_Notif_Ent(net_type, net_name); + #ifdef NOTIFICATIONS_DEBUG Debug_Notification(sprintf( - "Send_Notification_WOVA(%d, %s, %s, %s, %s);\n", - broadcast, - Get_Notif_TypeName(net_type), - notif.nent_name, + "Send_Notification_WOCOVA(%s, %s, %s);\n", + sprintf( + "%s, '%s', %s, %s", + Get_Notif_BroadcastName(broadcast), + client.classname, + Get_Notif_TypeName(net_type), + notif.nent_name + ), MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), sprintf("%d, %d, %d, %d", f1, f2, f3, f4) )); #endif - + #define VARITEM(stringc,floatc,args) \ if((notif.nent_stringcount == stringc) && (notif.nent_floatcount == floatc)) \ { Send_Notification(broadcast, client, net_type, net_name, args); return; }