lots of changes
This commit is contained in:
@@ -0,0 +1,234 @@
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Radio commands: takes over the stock CS:S radio commands (the listener blocks the game's
|
||||
// handling) and re-emits the voice line plus a custom-chatcolors styled chat line to the team.
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
||||
static const char g_sRadioCommands[][] = {
|
||||
"coverme", "takepoint", "holdpos", "regroup", "followme", "takingfire", "go",
|
||||
"fallback", "sticktog", "getinpos", "stormfront", "report", "roger", "enemyspot",
|
||||
"needbackup", "sectorclear", "inposition", "reportingin", "getout", "negative", "enemydown",
|
||||
"thanks", "cheer"
|
||||
};
|
||||
|
||||
// Everything from this index on is a custom addition, not a stock radio command
|
||||
// (gated behind sm_radio_custom).
|
||||
#define RADIO_FIRST_CUSTOM (sizeof(g_sRadioCommands) - 2)
|
||||
|
||||
static const char g_sRadioSounds[][] = {
|
||||
"radio/ct_coverme.wav", "radio/takepoint.wav", "radio/position.wav", "radio/regroup.wav",
|
||||
"radio/followme.wav", "radio/fireassis.wav", "radio/com_go.wav", "radio/fallback.wav",
|
||||
"radio/sticktog.wav", "radio/com_getinpos.wav", "radio/stormfront.wav", "radio/com_reportin.wav",
|
||||
"radio/roger.wav", "radio/ct_enemys.wav", "radio/ct_backup.wav", "radio/clear.wav",
|
||||
"radio/ct_inpos.wav", "radio/ct_reportingin.wav", "radio/blow.wav", "radio/negative.wav",
|
||||
"radio/enemydown.wav",
|
||||
"", "" // thanks/cheer have no stock radio sound; a random bot-chatter wav is picked below
|
||||
};
|
||||
|
||||
#define SOUND_AFFIRMATIVE "radio/ct_affirm.wav"
|
||||
#define SOUND_FIREINTHEHOLE "radio/ct_fireinhole.wav"
|
||||
|
||||
static const char g_sThanksSounds[][] = {
|
||||
"bot/nice.wav", "bot/nice2.wav", "bot/good_one.wav", "bot/good_one2.wav",
|
||||
"bot/very_nice.wav", "bot/well_done.wav"
|
||||
};
|
||||
|
||||
static const char g_sCheerSounds[][] = {
|
||||
"bot/whoo.wav", "bot/whoo2.wav", "bot/yesss.wav", "bot/yesss2.wav",
|
||||
"bot/yea_baby.wav", "bot/oh_yea.wav", "bot/oh_yea2.wav"
|
||||
};
|
||||
|
||||
// The bot chatter wavs are mastered 6-10 dB hotter than the radio wavs (radio averages
|
||||
// -16.6 LUFS), so each one carries a gain that brings it down to the radio loudness.
|
||||
static const float g_flThanksScales[] = {
|
||||
0.61, 0.44, 0.45, 0.63,
|
||||
0.43, 0.42
|
||||
};
|
||||
|
||||
static const float g_flCheerScales[] = {
|
||||
0.33, 0.27, 0.25, 0.32,
|
||||
0.31, 0.32, 0.39
|
||||
};
|
||||
|
||||
static const char g_sRadioPhrases[][] = {
|
||||
"Cover Me!", "You take the point.", "Hold This position.", "Regroup Team.",
|
||||
"Follow Me.", "Taking fire...need assistance!", "Go go go!", "Team, fall back!",
|
||||
"Stick together, team.", "Get in position and wait for my go.", "Storm the Front!",
|
||||
"Report in, team.", "Roger that.", "Enemy spotted.", "Need backup.", "Sector clear.",
|
||||
"I'm in position.", "Reporting in.", "Get out of there, it's gonna blow!",
|
||||
"Negative.", "Enemy down.",
|
||||
"Thanks!", "Cheered!!!"
|
||||
};
|
||||
|
||||
static const char g_sCheerColors[][] = {
|
||||
"FF0000", "FF4500", "FF8C00", "FFD700", "ADFF2F",
|
||||
"00FF00", "00BFFF", "1E90FF", "0000CD", "9400D3"
|
||||
};
|
||||
static const char g_sCheerText[] = "Cheered!!!";
|
||||
static int g_iCheerOffset;
|
||||
|
||||
static void Commands_BuildCheerPhrase(char[] phrase, int maxlen)
|
||||
{
|
||||
phrase[0] = '\0';
|
||||
for (int i = 0; i < sizeof(g_sCheerText) - 1; i++)
|
||||
{
|
||||
Format(phrase, maxlen, "%s\x07%s%c", phrase,
|
||||
g_sCheerColors[(i + g_iCheerOffset) % sizeof(g_sCheerColors)], g_sCheerText[i]);
|
||||
}
|
||||
g_iCheerOffset = (g_iCheerOffset + 1) % sizeof(g_sCheerColors);
|
||||
}
|
||||
|
||||
static StringMap g_RadioIndex;
|
||||
|
||||
void Commands_PrecacheSounds()
|
||||
{
|
||||
for (int i = 0; i < sizeof(g_sRadioSounds); i++)
|
||||
{
|
||||
if (g_sRadioSounds[i][0])
|
||||
PrecacheSound(g_sRadioSounds[i]);
|
||||
}
|
||||
PrecacheSound(SOUND_AFFIRMATIVE);
|
||||
PrecacheSound(SOUND_FIREINTHEHOLE); // grenade.sp
|
||||
for (int i = 0; i < sizeof(g_sThanksSounds); i++)
|
||||
PrecacheSound(g_sThanksSounds[i]);
|
||||
for (int i = 0; i < sizeof(g_sCheerSounds); i++)
|
||||
PrecacheSound(g_sCheerSounds[i]);
|
||||
}
|
||||
|
||||
void Radio_EmitToPlayers(const int[] players, int playersNum, const char[] sound, float scale = 1.0)
|
||||
{
|
||||
for (int i = 0; i < playersNum; i++)
|
||||
{
|
||||
float volume = Settings_GetVolume(players[i]);
|
||||
if (volume <= 0.0)
|
||||
continue;
|
||||
|
||||
EmitSoundToClient(players[i], sound, SOUND_FROM_PLAYER, SNDCHAN_VOICE,
|
||||
SNDLEVEL_NORMAL, SND_NOFLAGS, volume * scale);
|
||||
}
|
||||
}
|
||||
|
||||
void Commands_Init()
|
||||
{
|
||||
g_RadioIndex = new StringMap();
|
||||
for (int i = 0; i < sizeof(g_sRadioCommands); i++)
|
||||
{
|
||||
g_RadioIndex.SetValue(g_sRadioCommands[i], i);
|
||||
AddCommandListener(Command_Radio, g_sRadioCommands[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public Action Command_Radio(int client, const char[] command, int argc)
|
||||
{
|
||||
if (!g_cvEnabled.BoolValue)
|
||||
return Plugin_Continue;
|
||||
|
||||
if (client < 1 || client > MaxClients || !IsClientInGame(client))
|
||||
return Plugin_Continue;
|
||||
|
||||
// Console commands are case-insensitive, StringMap keys are not.
|
||||
char cmd[16];
|
||||
strcopy(cmd, sizeof(cmd), command);
|
||||
for (int i = 0; cmd[i]; i++)
|
||||
cmd[i] = CharToLower(cmd[i]);
|
||||
|
||||
int index;
|
||||
if (!g_RadioIndex.GetValue(cmd, index))
|
||||
return Plugin_Continue;
|
||||
|
||||
// With the custom commands disabled they fall through as unknown commands.
|
||||
if (index >= RADIO_FIRST_CUSTOM && !g_cvCustom.BoolValue)
|
||||
return Plugin_Continue;
|
||||
|
||||
if (Bans_IsBanned(client))
|
||||
return Plugin_Handled;
|
||||
|
||||
int team = GetClientTeam(client);
|
||||
if (team != CS_TEAM_T && team != CS_TEAM_CT)
|
||||
return Plugin_Handled;
|
||||
|
||||
if (!IsPlayerAlive(client) && !g_cvDead.BoolValue)
|
||||
return Plugin_Handled;
|
||||
|
||||
bool bLeader = Radio_IsLeader(client);
|
||||
|
||||
float flNow = GetGameTime();
|
||||
bool bPlaySound = g_cvSound.BoolValue;
|
||||
|
||||
if (!bLeader)
|
||||
{
|
||||
if (flNow < g_flNextRadio[client])
|
||||
return Plugin_Handled;
|
||||
|
||||
int limit = g_cvRoundLimit.IntValue;
|
||||
if (limit > 0 && g_iRadioCount[client] >= limit)
|
||||
return Plugin_Handled;
|
||||
|
||||
g_flNextRadio[client] = flNow + g_cvCooldown.FloatValue;
|
||||
}
|
||||
else if (flNow < g_flNextRadio[client])
|
||||
{
|
||||
// Leaders may spam the chat line, but the voice line still honours the cooldown.
|
||||
bPlaySound = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_flNextRadio[client] = flNow + g_cvCooldown.FloatValue;
|
||||
}
|
||||
|
||||
g_iRadioCount[client]++;
|
||||
|
||||
bool bCustom = (index >= RADIO_FIRST_CUSTOM);
|
||||
|
||||
int[] players = new int[MaxClients];
|
||||
int playersNum = 0;
|
||||
for (int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if (!IsClientInGame(i) || IsFakeClient(i) || GetClientTeam(i) != team)
|
||||
continue;
|
||||
|
||||
// Players may opt out of the custom commands in !settings.
|
||||
if (bCustom && !Settings_GetCustom(i))
|
||||
continue;
|
||||
|
||||
players[playersNum++] = i;
|
||||
}
|
||||
|
||||
if (!playersNum)
|
||||
return Plugin_Handled;
|
||||
|
||||
// phrase must hold the coloured cheer line (10 glyphs each prefixed by a 7-byte \x07RRGGBB code)
|
||||
char sound[32], phrase[128];
|
||||
float soundScale = 1.0;
|
||||
strcopy(sound, sizeof(sound), g_sRadioSounds[index]);
|
||||
strcopy(phrase, sizeof(phrase), g_sRadioPhrases[index]);
|
||||
|
||||
// Stock "roger" picks one of two acknowledgements at random.
|
||||
if (StrEqual(cmd, "roger") && GetRandomInt(0, 1))
|
||||
{
|
||||
strcopy(sound, sizeof(sound), SOUND_AFFIRMATIVE);
|
||||
strcopy(phrase, sizeof(phrase), "Affirmative.");
|
||||
}
|
||||
else if (StrEqual(cmd, "thanks"))
|
||||
{
|
||||
int pick = GetRandomInt(0, sizeof(g_sThanksSounds) - 1);
|
||||
strcopy(sound, sizeof(sound), g_sThanksSounds[pick]);
|
||||
soundScale = g_flThanksScales[pick];
|
||||
}
|
||||
else if (StrEqual(cmd, "cheer"))
|
||||
{
|
||||
int pick = GetRandomInt(0, sizeof(g_sCheerSounds) - 1);
|
||||
strcopy(sound, sizeof(sound), g_sCheerSounds[pick]);
|
||||
soundScale = g_flCheerScales[pick];
|
||||
Commands_BuildCheerPhrase(phrase, sizeof(phrase));
|
||||
}
|
||||
|
||||
if (bPlaySound && sound[0])
|
||||
Radio_EmitToPlayers(players, playersNum, sound, soundScale);
|
||||
|
||||
char text[256];
|
||||
Format_RadioLine(client, bLeader, phrase, text, sizeof(text));
|
||||
|
||||
Radio_SendChat(client, players, playersNum, text);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
Reference in New Issue
Block a user