Hello everyone,
What i'm trying to make now is FF2 subplugin which will replace minigun(tf_weapon_minigun) sounds with custom one. So far i have no luck while trying to mute the default sound played by the weapon:
1. Sound Hooks are not fired when the weapon is playing sounds
2. I found out it uses m_iWeaponState which plays sound for every client client-side, then i used code from
Be the giant deflector heavyplugin to detect when minigun starts playing sound. It manages to play the new sound, but it doesn't stop the default one
3. Applied "minigun no spin sounds" attribute to the minigun, but this attribute doesn't want to work with stock minigun and it only stops windup sounds...
4. Another idea is to use SendProxy and send another value of m_iWeaponState netvar to clients, but looking at the leaked Source 2007 code, this will break client-side animation, not sure, but strongly sure this will happen, so didn't try this method
5. Another idea is to disable client-side prediction faking the cvar sv_client_predict, but i know this will deteriorate the game experience(laggy movement, slow action, etc)
I'm stuck and i don't know what to do to prevent minigun sounds from playing but without side effects. I can accept "NO" answer too, just tell me if it's possible or not
Edit:
My fast and dirty plugin for testing minigun sound replacement:
PHP Code:
#include <sourcemod>
#include <sdktools>
#include <freak_fortress_2>
#include <tf2attributes>
bool Locked1[MAXPLAYERS+1];
bool Locked2[MAXPLAYERS+1];
bool Locked3[MAXPLAYERS+1];
bool CanWindDown[MAXPLAYERS+1];
bool stopsound=false;
#define SOUND_GUNFIRE ")mvm/giant_heavy/giant_heavy_gunfire.wav"
#define SOUND_GUNSPIN ")mvm/giant_heavy/giant_heavy_gunspin.wav"
#define SOUND_WINDUP ")mvm/giant_heavy/giant_heavy_gunwindup.wav"
#define SOUND_WINDDOWN ")mvm/giant_heavy/giant_heavy_gunwinddown.wav"
#define SOUND_GUNFIRE_1 "mvm/giant_heavy/giant_heavy_gunfire.wav"
#define SOUND_GUNSPIN_1 "mvm/giant_heavy/giant_heavy_gunspin.wav"
#define SOUND_WINDUP_1 "mvm/giant_heavy/giant_heavy_gunwindup.wav"
#define SOUND_WINDDOWN_1 "mvm/giant_heavy/giant_heavy_gunwinddown.wav"
public OnPluginStart()
{
RegAdminCmd("sm_stopsounds", Command_StopSounds, ADMFLAG_CHEATS, "Stop a sound!");
//HookUserMessage(GetUserMessageId("PlayerTauntSoundLoopStart"), HookTauntMessage, true);
//AddNormalSoundHook(HookSound);
PrecacheSound(SOUND_GUNFIRE_1);
PrecacheSound(SOUND_GUNSPIN_1);
PrecacheSound(SOUND_WINDUP_1);
PrecacheSound(SOUND_WINDDOWN_1);
}
public Action:Command_StopSounds(client, args)
{
stopsound=!stopsound;
ReplyToCommand(client, "Toggled!");
int value=1;
if(stopsound)
{
int index=1;
while ((index = FindEntityByClassname(index, "tf_weapon_minigun")) != -1)
{
TF2Attrib_SetByName(index, "minigun no spin sounds", view_as<float>(value));
}
}
return Plugin_Handled;
}
/*
public Action HookTauntMessage(UserMsg msg_id, BfRead msg, const int[] players, int playersNum, bool reliable, bool init)
{
int byte = msg.ReadByte(); //The client index sending the sound
char string[PLATFORM_MAX_PATH]; //The sound
msg.ReadString(string, PLATFORM_MAX_PATH);
if(stopsound)
{
PrintToServer("%i %s", byte, string);
return Plugin_Handled;
}
return Plugin_Continue;
}
*/
public Action OnPlayerRunCmd(int iClient, int& iButtons, int& iImpulse, float[3] fVel, float[3] fAng, int& iWeapon)
{
if(!stopsound)
{
return Plugin_Continue;
}
if (IsValidClient(iClient))
{
int weapon = GetPlayerWeaponSlot(iClient, 0);
char classname[64];
GetEntityClassname(weapon, classname, sizeof(classname));
if(IsValidEntity(weapon) && StrEqual(classname, "tf_weapon_minigun", false))
{
int iWeaponState = GetEntProp(weapon, Prop_Send, "m_iWeaponState");
if (iWeaponState == 1 && !Locked1[iClient])
{
EmitSoundToAll(SOUND_WINDUP, iClient);
// PrintToChatAll("WeaponState = Windup");
Locked1[iClient] = true;
Locked2[iClient] = false;
Locked3[iClient] = false;
CanWindDown[iClient] = true;
StopSound(iClient, SNDCHAN_AUTO, SOUND_GUNSPIN);
StopSound(iClient, SNDCHAN_AUTO, SOUND_GUNFIRE);
}
else if (iWeaponState == 2 && !Locked2[iClient])
{
EmitSoundToAll(SOUND_GUNFIRE, iClient);
// PrintToChatAll("WeaponState = Firing");
Locked2[iClient] = true;
Locked1[iClient] = true;
Locked3[iClient] = false;
CanWindDown[iClient] = true;
StopSound(iClient, SNDCHAN_AUTO, SOUND_GUNSPIN);
StopSound(iClient, SNDCHAN_AUTO, SOUND_WINDUP);
}
else if (iWeaponState == 3 && !Locked3[iClient])
{
EmitSoundToAll(SOUND_GUNSPIN, iClient);
// PrintToChatAll("WeaponState = Spun Up");
Locked3[iClient] = true;
Locked1[iClient] = true;
Locked2[iClient] = false;
CanWindDown[iClient] = true;
StopSound(iClient, SNDCHAN_AUTO, SOUND_GUNFIRE);
StopSound(iClient, SNDCHAN_AUTO, SOUND_WINDUP);
}
else if (iWeaponState == 0)
{
if (CanWindDown[iClient])
{
// PrintToChatAll("WeaponState = WindDown");
EmitSoundToAll(SOUND_WINDDOWN, iClient);
CanWindDown[iClient] = false;
}
StopSound(iClient, SNDCHAN_AUTO, SOUND_GUNSPIN);
StopSound(iClient, SNDCHAN_AUTO, SOUND_GUNFIRE);
Locked1[iClient] = false;
Locked2[iClient] = false;
Locked3[iClient] = false;
}
}
}
return Plugin_Continue;
}
bool IsValidClient(client)
{
if (client <= 0) return false;
if (client > MaxClients) return false;
return IsClientInGame(client);
}
/*
#if SOURCEMOD_V_MAJOR==1 && SOURCEMOD_V_MINOR<=7
public Action:HookSound(clients[64], &numClients, String:sound[PLATFORM_MAX_PATH], &client, &channel, &Float:volume, &level, &pitch, &flags)
#else
public Action:HookSound(clients[64], &numClients, String:sound[PLATFORM_MAX_PATH], &client, &channel, &Float:volume, &level, &pitch, &flags, String:soundEntry[PLATFORM_MAX_PATH], &seed)
#endif
{
if(stopsound)
{
PrintToChatAll("Sound: %s", sound);
EmitSound(clients, numClients, "vo/engineer_ThanksForTheHeal02.mp3", client, channel, level, flags, volume, pitch);
return Plugin_Stop;
}
return Plugin_Continue;
}
*/
What happens is that both the new and default sounds are played and overlapped
__________________