lots of changes
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Grenade announce: throwing a grenade makes the game itself emit "Fire in the hole!" via the
|
||||
// RadioText usermessage (it is not a client command), so intercept it and re-send the line
|
||||
// styled a frame later. The game's SendAudio (Radio.FireInTheHole) is likewise intercepted and
|
||||
// re-emitted through EmitSoundToClient so each listener's radio volume preference applies.
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
||||
#define FIRE_IN_THE_HOLE_TOKEN "#Cstrike_TitlesTXT_Fire_in_the_hole"
|
||||
|
||||
void Grenade_Init()
|
||||
{
|
||||
UserMsg RadioText = GetUserMessageId("RadioText");
|
||||
if (RadioText == INVALID_MESSAGE_ID)
|
||||
SetFailState("RadioText usermessage unavailable.");
|
||||
|
||||
HookUserMessage(RadioText, Hook_RadioText, true);
|
||||
HookUserMessage(GetUserMessageId("SendAudio"), Hook_SendAudio, true);
|
||||
}
|
||||
|
||||
public Action Hook_SendAudio(UserMsg msg_id, Handle bf, const int[] players, int playersNum, bool reliable, bool init)
|
||||
{
|
||||
if (!g_cvEnabled.BoolValue)
|
||||
return Plugin_Continue;
|
||||
|
||||
char sound[32];
|
||||
BfReadString(bf, sound, sizeof(sound), false);
|
||||
|
||||
// Grenade announces are the only radio SendAudio the engine still emits (the command
|
||||
// listeners block the rest); round events (bomb/win jingles) pass through untouched.
|
||||
if (!StrEqual(sound, "Radio.FireInTheHole"))
|
||||
return Plugin_Continue;
|
||||
|
||||
// Sounds cannot be emitted from inside a usermessage hook either, so re-emit next frame.
|
||||
DataPack pack = new DataPack();
|
||||
pack.WriteCell(playersNum);
|
||||
for (int i = 0; i < playersNum; i++)
|
||||
{
|
||||
int target = players[i];
|
||||
pack.WriteCell((target >= 1 && target <= MaxClients && IsClientInGame(target)) ? GetClientUserId(target) : 0);
|
||||
}
|
||||
RequestFrame(OnFireInTheHoleResend, pack);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public void OnFireInTheHoleResend(DataPack pack)
|
||||
{
|
||||
pack.Reset();
|
||||
int num = pack.ReadCell();
|
||||
|
||||
int[] players = new int[MaxClients];
|
||||
int playersNum = 0;
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
int target = GetClientOfUserId(pack.ReadCell());
|
||||
if (target && !IsFakeClient(target))
|
||||
players[playersNum++] = target;
|
||||
}
|
||||
delete pack;
|
||||
|
||||
Radio_EmitToPlayers(players, playersNum, SOUND_FIREINTHEHOLE);
|
||||
}
|
||||
|
||||
public Action Hook_RadioText(UserMsg msg_id, Handle bf, const int[] players, int playersNum, bool reliable, bool init)
|
||||
{
|
||||
if (!g_cvEnabled.BoolValue)
|
||||
return Plugin_Continue;
|
||||
|
||||
BfReadByte(bf); // msg_dest
|
||||
int client = BfReadByte(bf);
|
||||
|
||||
if (client < 1 || client > MaxClients || !IsClientInGame(client))
|
||||
return Plugin_Continue;
|
||||
|
||||
// Layout: msg_name, then up to four params. "#Game_radio" carries the phrase token in
|
||||
// param2, "#Game_radio_location" in param3 (param2 is the nav place name).
|
||||
char msgName[64], param[64], token[64];
|
||||
BfReadString(bf, msgName, sizeof(msgName), false); // msg_name
|
||||
BfReadString(bf, param, sizeof(param), false); // param1 = player name
|
||||
BfReadString(bf, token, sizeof(token), false); // param2
|
||||
BfReadString(bf, param, sizeof(param), false); // param3
|
||||
|
||||
if (StrEqual(msgName, "#Game_radio_location"))
|
||||
strcopy(token, sizeof(token), param);
|
||||
else if (!StrEqual(msgName, "#Game_radio"))
|
||||
return Plugin_Continue;
|
||||
|
||||
if (!StrEqual(token, FIRE_IN_THE_HOLE_TOKEN))
|
||||
return Plugin_Continue;
|
||||
|
||||
if (Bans_IsBanned(client))
|
||||
return Plugin_Handled;
|
||||
|
||||
// Usermessages cannot be sent from inside a usermessage hook, so stash the data and
|
||||
// recipients (as userids) and re-send next frame.
|
||||
DataPack pack = new DataPack();
|
||||
pack.WriteCell(GetClientUserId(client));
|
||||
pack.WriteCell(playersNum);
|
||||
for (int i = 0; i < playersNum; i++)
|
||||
{
|
||||
int target = players[i];
|
||||
pack.WriteCell((target >= 1 && target <= MaxClients && IsClientInGame(target)) ? GetClientUserId(target) : 0);
|
||||
}
|
||||
RequestFrame(OnGrenadeResend, pack);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public void OnGrenadeResend(DataPack pack)
|
||||
{
|
||||
pack.Reset();
|
||||
int client = GetClientOfUserId(pack.ReadCell());
|
||||
int num = pack.ReadCell();
|
||||
|
||||
int[] players = new int[MaxClients];
|
||||
int playersNum = 0;
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
int target = GetClientOfUserId(pack.ReadCell());
|
||||
if (target && !IsFakeClient(target))
|
||||
players[playersNum++] = target;
|
||||
}
|
||||
delete pack;
|
||||
|
||||
if (!client || !IsClientInGame(client) || !playersNum)
|
||||
return;
|
||||
|
||||
char text[256];
|
||||
Format_RadioLine(client, Radio_IsLeader(client), "Fire in the hole!", text, sizeof(text));
|
||||
|
||||
Radio_SendChat(client, players, playersNum, text);
|
||||
}
|
||||
Reference in New Issue
Block a user