Here is my version of the snippet. I made various improvements and support for DoD:S or any other game that only has one VM
PHP Code:
#pragma semicolon 1
#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#define EF_NODRAW 32
new g_iViewModels[MAXPLAYERS + 1][2];
new Handle:g_hCreateViewModel;
new g_iOffset_Effects;
new g_iOffset_ViewModel;
new g_iOffset_ActiveWeapon;
new g_iOffset_Weapon;
new g_iOffset_Sequence;
new g_iOffset_ModelIndex;
new g_iOffset_PlaybackRate;
static const String:g_szCustomVM_ClassName[3][] =
{
"garand",
"k98",
"thompson"
};
static const String:g_szCustomVM_Model[3][] =
{
"models/weapons/v_pistol.mdl",
"models/weapons/v_357.mdl",
"models/weapons/v_smg1.mdl"
};
new g_iCustomVM_ModelIndex[3];
public OnPluginStart()
{
new Handle:gameConf = LoadGameConfigFile("plugin.viewmodel");
if (!gameConf)
{
SetFailState("Fatal Error: Unable to open game config file: \"plugin.viewmodel\"!");
}
StartPrepSDKCall(SDKCall_Player);
PrepSDKCall_SetFromConf(gameConf, SDKConf_Virtual, "CreateViewModel");
PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_ByValue);
if ((g_hCreateViewModel = EndPrepSDKCall()) == INVALID_HANDLE)
{
SetFailState("Fatal Error: Unable to create SDK call \"CreateViewModel\"!");
}
CloseHandle(gameConf);
g_iOffset_Effects = GetSendPropOffset("CBaseEntity", "m_fEffects");
g_iOffset_ViewModel = GetSendPropOffset("CBasePlayer", "m_hViewModel");
g_iOffset_ActiveWeapon = GetSendPropOffset("CBasePlayer", "m_hActiveWeapon");
g_iOffset_Weapon = GetSendPropOffset("CBaseViewModel", "m_hWeapon");
g_iOffset_Sequence = GetSendPropOffset("CBaseViewModel", "m_nSequence");
g_iOffset_ModelIndex = GetSendPropOffset("CBaseViewModel", "m_nModelIndex");
g_iOffset_PlaybackRate = GetSendPropOffset("CBaseViewModel", "m_flPlaybackRate");
HookEvent("player_spawn", Event_PlayerSpawn);
}
GetSendPropOffset(const String:serverClass[], const String:propName[])
{
new offset = FindSendPropOffs(serverClass, propName);
if (!offset)
{
SetFailState("Fatal Error: Unable to find offset: \"%s::%s\"!", serverClass, propName);
}
return offset;
}
public OnMapStart()
{
for (new i = 0; i < 3; i++)
{
g_iCustomVM_ModelIndex[i] = PrecacheModel(g_szCustomVM_Model[i], true);
}
}
public OnClientPostAdminCheck(client)
{
g_iViewModels[client][0] = -1;
g_iViewModels[client][1] = -1;
SDKHook(client, SDKHook_PostThink, OnClientThinkPost);
}
public OnClientThinkPost(client)
{
static currentWeapon[MAXPLAYERS + 1];
new viewModel1 = g_iViewModels[client][0];
new viewModel2 = g_iViewModels[client][1];
if (!IsPlayerAlive(client))
{
if (viewModel2 != -1)
{
// If the player is dead, hide the secondary viewmodel.
ShowViewModel(viewModel2, false);
g_iViewModels[client][0] = -1;
g_iViewModels[client][1] = -1;
currentWeapon[client] = 0;
}
return;
}
new activeWeapon = GetEntDataEnt2(client, g_iOffset_ActiveWeapon);
// Check if the player has switched weapon.
if (activeWeapon != currentWeapon[client])
{
// Hide the secondary viewmodel, if necessary.
if (currentWeapon[client])
{
ShowViewModel(viewModel2, false);
}
currentWeapon[client] = 0;
decl String:className[32];
GetEdictClassname(activeWeapon, className, sizeof(className));
if (ReplaceString(className, sizeof(className), "weapon_", NULL_STRING))
{
for (new i = 0; i < 3; i++)
{
if (StrEqual(className, g_szCustomVM_ClassName[i]))
{
// Hide the primary viewmodel.
ShowViewModel(viewModel1, false);
// Show the secondary viewmodel.
ShowViewModel(viewModel2, true);
SetEntData(viewModel2, g_iOffset_ModelIndex, g_iCustomVM_ModelIndex[i], _, true);
SetEntData(viewModel2, g_iOffset_Weapon, GetEntData(viewModel1, g_iOffset_Weapon), _, true);
currentWeapon[client] = activeWeapon;
break;
}
}
}
}
if (currentWeapon[client])
{
SetEntData(viewModel2, g_iOffset_Sequence, GetEntData(viewModel1, g_iOffset_Sequence), _, true);
SetEntData(viewModel2, g_iOffset_PlaybackRate, GetEntData(viewModel1, g_iOffset_PlaybackRate), _, true);
}
}
ShowViewModel(viewModel, bool:show)
{
new flags = GetEntData(viewModel, g_iOffset_Effects);
SetEntData(viewModel, g_iOffset_Effects, show ? flags & ~EF_NODRAW : flags | EF_NODRAW, _, true);
}
public Event_PlayerSpawn(Handle:event, const String:name[], bool:dontBrodcast)
{
new client = GetClientOfUserId(GetEventInt(event, "userid"));
if (GetClientTeam(client) > 1)
{
// Create the second view model.
SDKCall(g_hCreateViewModel, client, 1);
g_iViewModels[client][0] = GetViewModel(client, 0);
g_iViewModels[client][1] = GetViewModel(client, 1);
}
}
GetViewModel(client, index)
{
return GetEntDataEnt2(client, g_iOffset_ViewModel + (index * 4));
}