create 1 cfg file in configs .. zombie_claws.like this:
PHP Code:
#pragma semicolon 1
#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#include <zr_tools>
#define EF_NODRAW 32
new Handle:g_hCreateViewModel;
new Handle:g_hEnable;
new Handle:g_hDownListPath;
new bool:g_bEnable;
new String:g_sDownListPath[PLATFORM_MAX_PATH];
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;
new g_iViewModels[MAXPLAYERS+1][2];
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);
CreateConVar("zr_zombieclaws_version", PLUGIN_VERSION, "Version of the plugin", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_UNLOGGED|FCVAR_DONTRECORD|FCVAR_REPLICATED|FCVAR_NOTIFY);
g_hEnable = CreateConVar("zr_zombieclaws_enable", "1", "Enables/Disables the plugin", FCVAR_PLUGIN, true, 0.0, true, 1.0);
g_hDownListPath = CreateConVar("zr_zombieclaws_downloadpath", "addons/sourcemod/data/downlist_zrclaws.ini", "Path to the download list of zombie claws", FCVAR_PLUGIN);
HookConVarChange(g_hEnable, OnConVarChanged);
HookConVarChange(g_hDownListPath, OnConVarChanged);
g_bEnable = GetConVarBool(g_hEnable);
GetConVarString(g_hDownListPath, g_sDownListPath, sizeof(g_sDownListPath));
File_ReadDownloadList(g_sDownListPath);
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);
AutoExecConfig(true, "zombiereloaded/zombie_claws");
}
public OnConVarChanged(Handle:convar, const String:oldValue[], const String:newValue[])
{
if (convar == g_hEnable)
{
g_bEnable = bool:StringToInt(newValue);
}
else if(convar == g_hDownListPath)
{
Format(g_sDownListPath, sizeof(g_sDownListPath), "%s", newValue);
}
}
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 OnClientPostAdminCheck(client)
{
if (g_bEnable)
{
g_iViewModels[client][0] = -1;
g_iViewModels[client][1] = -1;
SDKHook(client, SDKHook_PostThink, OnClientThinkPost);
}
}
public OnClientThinkPost(client)
{
static currentWeapon[MAXPLAYERS + 1];
static OldSequence[MAXPLAYERS + 1];
static Float:OldCycle[MAXPLAYERS + 1];
new viewModel1 = g_iViewModels[client][0];
new viewModel2 = g_iViewModels[client][1];
if (!IsPlayerAlive(client))
{
if (viewModel2 != -1)
{
ShowViewModel(viewModel2, false);
g_iViewModels[client][0] = -1;
g_iViewModels[client][1] = -1;
currentWeapon[client] = 0;
}
return;
}
new activeWeapon = GetEntDataEnt2(client, g_iOffset_ActiveWeapon);
new Sequence = GetEntProp(viewModel1, Prop_Send, "m_nSequence");
new Float:Cycle = GetEntPropFloat(viewModel1, Prop_Data, "m_flCycle");
if (IsValidEdict(activeWeapon))
{
if (activeWeapon != currentWeapon[client])
{
if (currentWeapon[client])
{
ShowViewModel(viewModel2, false);
}
currentWeapon[client] = 0;
decl String:className[32];
GetEdictClassname(activeWeapon, className, sizeof(className));
if (StrEqual(className, "weapon_knife"))
{
decl String:Model[256];
ZRT_GetClientAttributeString(client, "claws_path", Model, sizeof(Model), "models/weapons/v_knife_t.mdl");
if (!StrEqual(Model, "models/weapons/v_knife_t.mdl", false))
{
ShowViewModel(viewModel1, false);
ShowViewModel(viewModel2, true);
new index = PrecacheModel(Model);
SetEntData(viewModel2, g_iOffset_ModelIndex, index, _, true);
SetEntData(viewModel2, g_iOffset_Weapon, GetEntData(viewModel1, g_iOffset_Weapon), _, true);
currentWeapon[client] = activeWeapon;
}
}
}
}
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);
if ((Cycle < OldCycle[client]) && (Sequence == OldSequence[client]))
{
SetEntProp(viewModel2, Prop_Send, "m_nSequence", 0);
}
}
OldSequence[client] = Sequence;
OldCycle[client] = Cycle;
}
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)
{
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));
}
new String:_smlib_empty_twodimstring_array[][] = { { '\0' } };
stock File_AddToDownloadsTable(const String:path[], bool:recursive=true, const String:ignoreExts[][]=_smlib_empty_twodimstring_array, size=0)
{
if (path[0] == '\0') {
return;
}
if (FileExists(path)) {
new String:fileExtension[4];
File_GetExtension(path, fileExtension, sizeof(fileExtension));
if (StrEqual(fileExtension, "bz2", false) || StrEqual(fileExtension, "ztmp", false)) {
return;
}
if (Array_FindString(ignoreExts, size, fileExtension) != -1) {
return;
}
AddFileToDownloadsTable(path);
}
else if (recursive && DirExists(path)) {
decl String:dirEntry[PLATFORM_MAX_PATH];
new Handle:__dir = OpenDirectory(path);
while (ReadDirEntry(__dir, dirEntry, sizeof(dirEntry))) {
if (StrEqual(dirEntry, ".") || StrEqual(dirEntry, "..")) {
continue;
}
Format(dirEntry, sizeof(dirEntry), "%s/%s", path, dirEntry);
File_AddToDownloadsTable(dirEntry, recursive, ignoreExts, size);
}
CloseHandle(__dir);
}
else if (FindCharInString(path, '*', true)) {
new String:fileExtension[4];
File_GetExtension(path, fileExtension, sizeof(fileExtension));
if (StrEqual(fileExtension, "*")) {
decl
String:dirName[PLATFORM_MAX_PATH],
String:fileName[PLATFORM_MAX_PATH],
String:dirEntry[PLATFORM_MAX_PATH];
File_GetDirName(path, dirName, sizeof(dirName));
File_GetFileName(path, fileName, sizeof(fileName));
StrCat(fileName, sizeof(fileName), ".");
new Handle:__dir = OpenDirectory(dirName);
while (ReadDirEntry(__dir, dirEntry, sizeof(dirEntry))) {
if (StrEqual(dirEntry, ".") || StrEqual(dirEntry, "..")) {
continue;
}
if (strncmp(dirEntry, fileName, strlen(fileName)) == 0) {
Format(dirEntry, sizeof(dirEntry), "%s/%s", dirName, dirEntry);
File_AddToDownloadsTable(dirEntry, recursive, ignoreExts, size);
}
}
CloseHandle(__dir);
}
}
return;
}
stock File_ReadDownloadList(const String:path[])
{
new Handle:file = OpenFile(path, "r");
if (file == INVALID_HANDLE) {
return;
}
new String:buffer[PLATFORM_MAX_PATH];
while (!IsEndOfFile(file)) {
ReadFileLine(file, buffer, sizeof(buffer));
new pos;
pos = StrContains(buffer, "//");
if (pos != -1) {
buffer[pos] = '\0';
}
pos = StrContains(buffer, "#");
if (pos != -1) {
buffer[pos] = '\0';
}
pos = StrContains(buffer, ";");
if (pos != -1) {
buffer[pos] = '\0';
}
TrimString(buffer);
if (buffer[0] == '\0') {
continue;
}
File_AddToDownloadsTable(buffer);
}
CloseHandle(file);
}
stock File_GetExtension(const String:path[], String:buffer[], size)
{
new extpos = FindCharInString(path, '.', true);
if (extpos == -1)
{
buffer[0] = '\0';
return;
}
strcopy(buffer, size, path[++extpos]);
}
stock Array_FindString(const String:array[][], size, const String:str[], bool:caseSensitive=true, start=0)
{
if (start < 0) {
start = 0;
}
for (new i=start; i < size; i++) {
if (StrEqual(array[i], str, caseSensitive)) {
return i;
}
}
return -1;
}
stock bool:File_GetFileName(const String:path[], String:buffer[], size)
{
if (path[0] == '\0') {
buffer[0] = '\0';
return;
}
File_GetBaseName(path, buffer, size);
new pos_ext = FindCharInString(buffer, '.', true);
if (pos_ext != -1) {
buffer[pos_ext] = '\0';
}
}
stock bool:File_GetDirName(const String:path[], String:buffer[], size)
{
if (path[0] == '\0') {
buffer[0] = '\0';
return;
}
new pos_start = FindCharInString(path, '/', true);
if (pos_start == -1) {
pos_start = FindCharInString(path, '\\', true);
if (pos_start == -1) {
buffer[0] = '\0';
return;
}
}
strcopy(buffer, size, path);
buffer[pos_start] = '\0';
}
stock bool:File_GetBaseName(const String:path[], String:buffer[], size)
{
if (path[0] == '\0') {
buffer[0] = '\0';
return;
}
new pos_start = FindCharInString(path, '/', true);
if (pos_start == -1) {
pos_start = FindCharInString(path, '\\', true);
}
pos_start++;
strcopy(buffer, size, path[pos_start]);
}