View Single Post
Andersso
Member
Join Date: Nov 2009
Location: E8 2A 2A 2A 2A
Old 04-08-2012 , 13:46   Re: [SNIPPET][CSS]custom viewmodels without flickers and without disabling prediction
Reply With Quote #14

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(gameConfSDKConf_Virtual"CreateViewModel");
    
PrepSDKCall_AddParameter(SDKType_PlainOldDataSDKPass_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(serverClasspropName);

    if (!
offset)
    {
        
SetFailState("Fatal Error: Unable to find offset: \"%s::%s\"!"serverClasspropName);
    }

    return 
offset;
}

public 
OnMapStart()
{
    for (new 
03i++)
    {
        
g_iCustomVM_ModelIndex[i] = PrecacheModel(g_szCustomVM_Model[i], true);
    }
}

public 
OnClientPostAdminCheck(client)
{
    
g_iViewModels[client][0] = -1;
    
g_iViewModels[client][1] = -1;

    
SDKHook(clientSDKHook_PostThinkOnClientThinkPost);
}

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(viewModel2false);
            
            
g_iViewModels[client][0] = -1;
            
g_iViewModels[client][1] = -1;
            
            
currentWeapon[client] = 0;
        }
        
        return;
    }
    
    new 
activeWeapon GetEntDataEnt2(clientg_iOffset_ActiveWeapon);
    
    
// Check if the player has switched weapon.
    
if (activeWeapon != currentWeapon[client])
    {
        
// Hide the secondary viewmodel, if necessary.
        
if (currentWeapon[client])
        {
            
ShowViewModel(viewModel2false);
        }
        
        
currentWeapon[client] = 0;
        
        
decl String:className[32];
        
GetEdictClassname(activeWeaponclassNamesizeof(className));
        
        if (
ReplaceString(classNamesizeof(className), "weapon_"NULL_STRING))
        {
            for (new 
03i++)
            {
                if (
StrEqual(classNameg_szCustomVM_ClassName[i]))
                {
                    
// Hide the primary viewmodel.
                    
ShowViewModel(viewModel1false);
                    
                    
// Show the secondary viewmodel.
                    
ShowViewModel(viewModel2true);
                    
                    
SetEntData(viewModel2g_iOffset_ModelIndexg_iCustomVM_ModelIndex[i], _true);
                    
SetEntData(viewModel2g_iOffset_WeaponGetEntData(viewModel1g_iOffset_Weapon), _true);
                    
                    
currentWeapon[client] = activeWeapon;
                    
                    break;
                }
            }
        }
    }
    
    if (
currentWeapon[client])
    {
        
SetEntData(viewModel2g_iOffset_SequenceGetEntData(viewModel1g_iOffset_Sequence), _true);
        
SetEntData(viewModel2g_iOffset_PlaybackRateGetEntData(viewModel1g_iOffset_PlaybackRate), _true);
    }
}

ShowViewModel(viewModelbool:show)
{
    new 
flags GetEntData(viewModelg_iOffset_Effects);
    
    
SetEntData(viewModelg_iOffset_Effectsshow 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_hCreateViewModelclient1);
        
        
g_iViewModels[client][0] = GetViewModel(client0);
        
g_iViewModels[client][1] = GetViewModel(client1);
    }
}

GetViewModel(clientindex)
{
    return 
GetEntDataEnt2(clientg_iOffset_ViewModel + (index 4));

Attached Files
File Type: txt plugin.viewmodel.txt (115 Bytes, 473 views)

Last edited by Andersso; 04-08-2012 at 13:49.
Andersso is offline