From 04ec0b1ffd8fc537c434b65c5ef5586e65619955 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 7 Jun 2022 19:09:02 -0400 Subject: [PATCH] Implement shout commands - shout command to create a server message, with its own special sound cue & color - shoutname to control the nametag, by default this is "SERVER" - shoutcolor controls the color of the message. By default it's red, but there's also a option for player colored. - autoshout makes any message sent by a admin/server automatically turn into a shout - Unlike HOSTMOD shout, integrated it with the dedicated server say behavior -- using say on dedicated server is always a shout. --- src/d_netcmd.c | 5 +++ src/g_game.c | 30 +++++++++++++++++ src/g_game.h | 1 + src/hu_stuff.c | 90 ++++++++++++++++++++++++++++++++++++++++---------- src/sounds.c | 3 ++ src/sounds.h | 3 ++ 6 files changed, 114 insertions(+), 18 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index a784ad8e2..8a3a0066e 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -947,6 +947,11 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_consolechat); CV_RegisterVar(&cv_chatnotifications); CV_RegisterVar(&cv_chatbacktint); + + CV_RegisterVar(&cv_shoutname); + CV_RegisterVar(&cv_shoutcolor); + CV_RegisterVar(&cv_autoshout); + CV_RegisterVar(&cv_songcredits); CV_RegisterVar(&cv_tutorialprompt); CV_RegisterVar(&cv_showfocuslost); diff --git a/src/g_game.c b/src/g_game.c index 896ea00ea..bfc66c4e1 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -393,6 +393,36 @@ consvar_t cv_chatbacktint = CVAR_INIT ("chatbacktint", "On", CV_SAVE, CV_OnOff, static CV_PossibleValue_t consolechat_cons_t[] = {{0, "Window"}, {1, "Console"}, {2, "Window (Hidden)"}, {0, NULL}}; consvar_t cv_consolechat = CVAR_INIT ("chatmode", "Window", CV_SAVE, consolechat_cons_t, NULL); +// Shout settings +// The relevant ones are CV_NETVAR because too lazy to send them any other way +consvar_t cv_shoutname = CVAR_INIT ("shout_name", "SERVER", CV_NETVAR, NULL, NULL); + +static CV_PossibleValue_t shoutcolor_cons_t[] = +{ + {-1, "Player color"}, + {0, "White"}, + {1, "Yellow"}, + {2, "Purple"}, + {3, "Green"}, + {4, "Blue"}, + {5, "Red"}, + {6, "Gray"}, + {7, "Orange"}, + {8, "Sky-blue"}, + {9, "Gold"}, + {10, "Lavender"}, + {11, "Aqua-green"}, + {12, "Magenta"}, + {13, "Pink"}, + {14, "Brown"}, + {15, "Tan"}, + {0, NULL} +}; +consvar_t cv_shoutcolor = CVAR_INIT ("shout_color", "Red", CV_NETVAR, shoutcolor_cons_t, NULL); + +// If on and you're an admin, your messages will automatically become shouts. +consvar_t cv_autoshout = CVAR_INIT ("autoshout", "Off", CV_NETVAR, CV_OnOff, NULL); + // Pause game upon window losing focus consvar_t cv_pauseifunfocused = CVAR_INIT ("pauseifunfocused", "Yes", CV_SAVE, CV_YesNo, NULL); diff --git a/src/g_game.h b/src/g_game.h index 52c7c7a0d..40495b5c3 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -48,6 +48,7 @@ extern boolean promptactive; extern consvar_t cv_tutorialprompt; extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection; +extern consvar_t cv_shoutname, cv_shoutcolor, cv_autoshout; extern consvar_t cv_songcredits; extern consvar_t cv_pauseifunfocused; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 933cccbb4..ed0727fc1 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -64,8 +64,11 @@ #define HU_INPUTX 0 #define HU_INPUTY 0 -#define HU_SERVER_SAY 1 // Server message (dedicated). -#define HU_CSAY 2 // Server CECHOes to everyone. +typedef enum +{ + HU_SHOUT = 1, // Shout message + HU_CSAY = 1<<1, // Middle-of-screen server message +} sayflags_t; //------------------------------------------- // heads up font @@ -169,6 +172,7 @@ static void Command_Say_f(void); static void Command_Sayto_f(void); static void Command_Sayteam_f(void); static void Command_CSay_f(void); +static void Command_Shout(void); static void Got_Saycmd(UINT8 **p, INT32 playernum); #endif @@ -210,6 +214,7 @@ void HU_Init(void) COM_AddCommand("sayto", Command_Sayto_f); COM_AddCommand("sayteam", Command_Sayteam_f); COM_AddCommand("csay", Command_CSay_f); + COM_AddCommand("shout", Command_Shout); RegisterNetXCmd(XD_SAY, Got_Saycmd); #endif @@ -456,7 +461,7 @@ void HU_AddChatText(const char *text, boolean playsound) * to -32 to say to everyone on that player's team. Note: This means you * have to add 1 to the player number, since they are 0 to 31 internally. * - * The flag HU_SERVER_SAY will be set if it is the dedicated server speaking. + * The flag HU_SHOUT will be set if it is the dedicated server speaking. * * This function obtains the message using COM_Argc() and COM_Argv(). * @@ -483,14 +488,17 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags) return; } - // Only servers/admins can CSAY. - if(!server && !(IsPlayerAdmin(consoleplayer))) - flags &= ~HU_CSAY; + // Only servers/admins can shout or CSAY. + if (!server && !IsPlayerAdmin(consoleplayer)) + { + flags &= ~(HU_SHOUT|HU_CSAY); + } - // We handle HU_SERVER_SAY, not the caller. - flags &= ~HU_SERVER_SAY; - if(dedicated && !(flags & HU_CSAY)) - flags |= HU_SERVER_SAY; + // Enforce shout for the dedicated server. + if (dedicated && !(flags & HU_CSAY)) + { + flags |= HU_SHOUT; + } buf[0] = target; buf[1] = flags; @@ -564,6 +572,8 @@ static void Command_Say_f(void) return; } + // Autoshout is handled by HU_queueChatChar. + // If you're using the say command, you can use the shout command, lol. DoSayCommand(0, 1, 0); } @@ -627,7 +637,7 @@ static void Command_CSay_f(void) return; } - if(!server && !IsPlayerAdmin(consoleplayer)) + if (!server && !IsPlayerAdmin(consoleplayer)) { CONS_Alert(CONS_NOTICE, M_GetText("Only servers and admins can use csay.\n")); return; @@ -635,6 +645,24 @@ static void Command_CSay_f(void) DoSayCommand(0, 1, HU_CSAY); } + +static void Command_Shout(void) +{ + if (COM_Argc() < 2) + { + CONS_Printf(M_GetText("shout : send a message with special alert sound, name, and color\n")); + return; + } + + if (!server && !IsPlayerAdmin(consoleplayer)) + { + CONS_Alert(CONS_NOTICE, M_GetText("Only servers and admins can use shout.\n")); + return; + } + + DoSayCommand(0, 1, HU_SHOUT); +} + static tic_t stop_spamming[MAXPLAYERS]; /** Receives a message, processing an ::XD_SAY command. @@ -658,7 +686,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) msg = (char *)*p; SKIPSTRING(*p); - if ((cv_mute.value || flags & (HU_CSAY|HU_SERVER_SAY)) && playernum != serverplayer && !(IsPlayerAdmin(playernum))) + if ((cv_mute.value || flags & (HU_CSAY|HU_SHOUT)) && playernum != serverplayer && !(IsPlayerAdmin(playernum))) { CONS_Alert(CONS_WARNING, cv_mute.value ? M_GetText("Illegal say command received from %s while muted\n") : M_GetText("Illegal csay command received from non-admin %s\n"), @@ -687,7 +715,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) // before we do anything, let's verify the guy isn't spamming, get this easier on us. //if (stop_spamming[playernum] != 0 && cv_chatspamprotection.value && !(flags & HU_CSAY)) - if (stop_spamming[playernum] != 0 && consoleplayer != playernum && cv_chatspamprotection.value && !(flags & HU_CSAY)) + if (stop_spamming[playernum] != 0 && consoleplayer != playernum && cv_chatspamprotection.value && !(flags & (HU_CSAY|HU_SHOUT))) { CONS_Debug(DBG_NETPLAY,"Received SAY cmd too quickly from Player %d (%s), assuming as spam and blocking message.\n", playernum+1, player_names[playernum]); stop_spamming[playernum] = 4; @@ -720,8 +748,8 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) action = true; } - if (flags & HU_SERVER_SAY) - dispname = "SERVER"; + if (flags & HU_SHOUT) + dispname = cv_shoutname.zstring; else dispname = player_names[playernum]; @@ -747,7 +775,30 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) char *tempchar = NULL; char color_prefix[2]; - if (players[playernum].spectator) + if (flags & HU_SHOUT) + { + if (cv_shoutcolor.value == -1) + { + UINT16 chatcolor = skincolors[players[playernum].skincolor].chatcolor; + + if (chatcolor > V_TANMAP) + { + sprintf(color_prefix, "%c", '\x80'); + } + else + { + sprintf(color_prefix, "%c", '\x80' + (chatcolor >> V_CHARCOLORSHIFT)); + } + } + else + { + sprintf(color_prefix, "%c", '\x80' + cv_shoutcolor.value); + } + + // Colorize full text + cstart = textcolor = color_prefix; + } + else if (players[playernum].spectator) { // grey text cstart = textcolor = "\x86"; @@ -834,7 +885,10 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) fmt2 = "%s<%s%s>\x80%s %s%s"; }*/ - HU_AddChatText(va(fmt2, prefix, cstart, dispname, cend, textcolor, msg), cv_chatnotifications.value); // add to chat + HU_AddChatText(va(fmt2, prefix, cstart, dispname, cend, textcolor, msg), (cv_chatnotifications.value) && !(flags & HU_SHOUT)); // add to chat + + if ((cv_chatnotifications.value) && (flags & HU_SHOUT)) + S_StartSound(NULL, sfx_sysmsg); if (tempchar) Z_Free(tempchar); @@ -1156,7 +1210,7 @@ static void HU_queueChatChar(INT32 c) else buf[0] = target; - buf[1] = 0; // flags + buf[1] = ((server || IsPlayerAdmin(consoleplayer)) && cv_autoshout.value) ? HU_SHOUT : 0; // flags SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1); } return; diff --git a/src/sounds.c b/src/sounds.c index 761fa109c..121e49a6b 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1111,6 +1111,9 @@ sfxinfo_t S_sfx[NUMSFX] = // SRB2kart - Grow/invinc clash {"parry", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // SF_X8AWAYSOUND + // Shout message sound effect + {"sysmsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Server notification"}, + // SRB2Kart - Engine sounds // Engine class A {"krta00", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR, ""}, diff --git a/src/sounds.h b/src/sounds.h index 336cd8b74..d3468971a 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -1175,6 +1175,9 @@ typedef enum // SRB2Kart - Powerup clash SFX sfx_parry, + // Shout message sound effect + sfx_sysmsg, + // Next up: UNIQUE ENGINE SOUNDS! Hoooooo boy... // Engine class A - Low Speed, Low Weight sfx_krta00,