case NOTIF_ALL: // send to everyone
{
return TRUE;
- break;
}
case NOTIF_ALL_EXCEPT: // send to everyone except X person and their spectators
{
) { return TRUE; }
break;
}
- default: { return FALSE; }
}
+ return FALSE;
}
#endif
string durcnt,
string normal,
string gentle,
+ float challow_def,
+ float challow_var,
float chtype,
float optiona,
float optionb)
{
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;
}
notif.nent_default = var_default;
notif.nent_name = strzone(namestring);
+ notif.nent_type = typeid;
notif.nent_id = nameid;
notif.nent_enabled = (1 <= var_cvar);
+ typestring = Get_Notif_TypeName(typeid);
+
// Other pre-notif-setup requisites
notif_error = FALSE;
case MSG_CHOICE:
{
+ if((chtype == NO_MSG) || (optiona == NO_MSG) || (optionb == NO_MSG))
+ {
+ print(sprintf(
+ 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:
+ {
+ error(sprintf(
+ 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"
+ "^ optiona: %s %s : %d %d\n"
+ "^ optionb: %s %s : %d %d\n",
+ notif.nent_name,
+ Get_Notif_TypeName(notif.nent_optiona.nent_type),
+ notif.nent_optiona.nent_name,
+ notif.nent_optiona.nent_stringcount,
+ notif.nent_optiona.nent_floatcount,
+ Get_Notif_TypeName(notif.nent_optiona.nent_type),
+ notif.nent_optiona.nent_name,
+ notif.nent_optiona.nent_stringcount,
+ notif.nent_optiona.nent_floatcount
+ ));
+ #endif
+ }
break;
}
}
-// =========================================
-// 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)
+ );
+ }
+
+ GetCvars_handleFloat(get_cvars_s, get_cvars_f, FRAG_VERBOSE, "notification_frag_verbose");
+}
+#endif
+// used to output notifications.cfg file
void Dump_Notifications(float fh, float alsoprint)
{
#define NOTIF_WRITE(a) { \
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( \
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"
+ 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"
);
}
#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
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
#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);
+ }
}
}
entity notif = Get_Notif_Ent(net_type, net_name);
if not(notif) { backtrace("Send_Notification: Could not find notification entity!\n"); return; }
+ string s1 = ((0 < notif.nent_stringcount) ? ...(0, string) : "");
+ string s2 = ((1 < notif.nent_stringcount) ? ...(1, string) : "");
+ string s3 = ((2 < notif.nent_stringcount) ? ...(2, string) : "");
+ string s4 = ((3 < notif.nent_stringcount) ? ...(3, string) : "");
+ float f1 = ((0 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 0), float) : 0);
+ float f2 = ((1 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 1), float) : 0);
+ float f3 = ((2 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 2), float) : 0);
+ float f4 = ((3 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 3), float) : 0);
+
+ #ifdef NOTIFICATIONS_DEBUG
+ Debug_Notification(sprintf(
+ "Send_Notification(%d, %s, %s, %s, %s);\n",
+ broadcast,
+ 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(
return;
}
- string s1 = ((0 < notif.nent_stringcount) ? ...(0, string) : "");
- string s2 = ((1 < notif.nent_stringcount) ? ...(1, string) : "");
- string s3 = ((2 < notif.nent_stringcount) ? ...(2, string) : "");
- string s4 = ((3 < notif.nent_stringcount) ? ...(3, string) : "");
- float f1 = ((0 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 0), float) : 0);
- float f2 = ((1 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 1), float) : 0);
- float f3 = ((2 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 2), float) : 0);
- float f4 = ((3 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 3), float) : 0);
-
- #ifdef NOTIFICATIONS_DEBUG
- Debug_Notification(sprintf(
- "Send_Notification(%d, %s, %s, %s, %s);\n",
- broadcast,
- 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(
server_is_dedicated
&&
{
// THIS GETS TRICKY... now we have to cycle through each possible player (checking broadcast)
// and then do an individual NOTIF_ONE_ONLY recursive call for each one depending on their option...
- // It's slow, but it's better than the alternatives
+ // 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;
-
+
+ #define RECURSE_FROM_CHOICE(ent,action) \
+ if(notif.nent_challow_var && (warmup_stage || (notif.nent_challow_var == 2))) \
+ { \
+ 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_type, \
+ found_choice.nent_id, \
+ found_choice.nent_stringcount, \
+ found_choice.nent_floatcount, \
+ s1, s2, s3, s4, \
+ f1, f2, f3, f4);
+
switch(broadcast)
{
case NOTIF_ONE_ONLY: // we can potentially save processing power with this broadcast method
{
if(IS_REAL_CLIENT(client))
- {
- switch(client.msg_choice_choices[net_name])
- {
- case 1: found_choice = notif.nent_choicea;
- case 2: found_choice = notif.nent_choiceb;
- default: return; // nothing to do here, client disables this
- }
- Send_Notification_WOVA(
- NOTIF_ONE_ONLY,
- client,
- found_choice.nent_net_type,
- found_choice.nent_net_name,
- s1, s2, s3, s4,
- f1, f2, f3, f4);
- }
+ { RECURSE_FROM_CHOICE(client, return) }
break;
}
-
default:
{
entity to;
FOR_EACH_REALCLIENT(to)
- {
- if(Notification_ShouldSend(broadcast, to, client))
- {
- switch(client.msg_choice_choices[net_name])
- {
- case 1: found_choice = notif.nent_choicea;
- case 2: found_choice = notif.nent_choiceb;
- default: continue; // nothing to do here, client disables this
- }
- Send_Notification_WOVA(
- NOTIF_ONE_ONLY,
- to,
- found_choice.nent_net_type,
- found_choice.nent_net_name,
- s1, s2, s3, s4,
- f1, f2, f3, f4);
- }
- }
+ { if(Notification_ShouldSend(broadcast, to, client))
+ { RECURSE_FROM_CHOICE(to, continue) } }
break;
}
}
// 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(%d, %s, %d, %d, %d, %s, %s);\n",
+ broadcast,
+ 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,
#ifdef NOTIFICATIONS_DEBUG
Debug_Notification(sprintf(
- "Send_Notification_WOVA(%d, %s, %s, %s, %s);\n",
+ "Send_Notification_WOCOVA(%d, %s, %s, %s, %s);\n",
broadcast,
Get_Notif_TypeName(net_type),
notif.nent_name,