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.
This commit is contained in:
Sally Coolatta 2022-06-07 19:09:02 -04:00
parent cc44588c9c
commit 04ec0b1ffd
6 changed files with 114 additions and 18 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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 <message>: 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;

View file

@ -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, ""},

View file

@ -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,