View Single Post
Author Message
gubka
Veteran Member
Join Date: Jan 2012
Location: Russia
Old 03-15-2019 , 07:50   [CS:GO] Work with gestures/overlay animation (Pelipoika fix)
Reply With Quote #1

Work on monster_generic entities !

Sigs:
PHP Code:
/**
 * @brief Plugin is loading.
 **/
public void OnPluginStart(/*void*/)
{
    
// Loads a game config file
    
Handle hConfig LoadGameConfigFile("plugin.turret"); 

    
/*__________________________________________________________________________________________________*/
    
    // Load other offsets
    
if((view_as<int>(Platform) = GameConfGetOffset(hConfig"CServer::OS")) == -1SetFailState("Failed to get offset: \"CServer::OS\". Update offset in \"plugin.turret\""); 
    if((
Animating_StudioHdr GameConfGetOffset(hConfig"CBaseAnimating::StudioHdr")) == -1SetFailState("Failed to get offset: \"CBaseAnimating::StudioHdr\". Update offset in \"plugin.turret\""); 
    if((
AnimatingOverlay_Count GameConfGetOffset(hConfig"CBaseAnimatingOverlay::Count")) == -1SetFailState("Failed to get offset: \"CBaseAnimatingOverlay::Count\". Update offset in \"plugin.turret\""); 
        
    
/// Info bellow
    
int lightingOriginOffset;
    if((
lightingOriginOffset FindSendPropInfo("CBaseAnimating""m_hLightingOrigin")) < 1)  SetFailState("Failed to find prop: \"CBaseAnimating::m_hLightingOrigin\"");
    
    
// StudioHdr offset in gameconf is only relative to the offset of m_hLightingOrigin, in order to make the offset more resilient to game updates
    
Animating_StudioHdr += lightingOriginOffset;

    
/*__________________________________________________________________________________________________*/

    // Starts the preparation of an SDK call
    
StartPrepSDKCall(SDKCall_Entity); 
    
PrepSDKCall_SetFromConf(hConfigSDKConf_Signature"CBaseAnimating::LookupPoseParameter"); 
    
    
// Adds a parameter to the calling convention. This should be called in normal ascending order
    
PrepSDKCall_AddParameter(SDKType_PlainOldDataSDKPass_Plain);
    
PrepSDKCall_AddParameter(SDKType_StringSDKPass_Pointer);  
    
PrepSDKCall_SetReturnInfo(SDKType_PlainOldDataSDKPass_Plain); 
    
    
// Validate call
    
if((hSDKCallLookupPoseParameter EndPrepSDKCall()) == nullSetFailState("Failed to load SDK call \"CBaseAnimating::LookupPoseParameter\". Update signature in \"plugin.turret\""); 

    
/*__________________________________________________________________________________________________*/
    
    // Starts the preparation of an SDK call
    
StartPrepSDKCall((Platform == OS_Windows) ? SDKCall_Entity SDKCall_Raw); 
    
PrepSDKCall_SetFromConf(hConfigSDKConf_Signature"CBaseAnimating::LookupSequence");
    
    
// Adds a parameter to the calling convention. This should be called in normal ascending order
    
PrepSDKCall_AddParameter(SDKType_StringSDKPass_Pointer);  
    
PrepSDKCall_SetReturnInfo(SDKType_PlainOldDataSDKPass_Plain); 

    
// Validate call
    
if((hSDKCallLookupSequence EndPrepSDKCall()) == nullSetFailState("Failed to load SDK call \"CBaseAnimating::LookupSequence\". Update signature in \"plugin.turret\""); 

    
/*__________________________________________________________________________________________________*/
    
    // Starts the preparation of an SDK call
    
StartPrepSDKCall(SDKCall_Entity); 
    
PrepSDKCall_SetFromConf(hConfigSDKConf_Signature"CBaseAnimatingOverlay::StudioFrameAdvance"); 
    
    
// Validate call
    
if((hSDKCallStudioFrameAdvance EndPrepSDKCall()) == nullSetFailState("Failed to load SDK call \"CBaseAnimatingOverlay::StudioFrameAdvance\". Update signature in \"plugin.turret\"");      
    
    
/*__________________________________________________________________________________________________*/
    
    // Starts the preparation of an SDK call
    
StartPrepSDKCall(SDKCall_Entity);
    
PrepSDKCall_SetFromConf(hConfigSDKConf_Signature"CBaseAnimatingOverlay::AddLayeredSequence"); 
    
    
// Adds a parameter to the calling convention. This should be called in normal ascending order
    
PrepSDKCall_AddParameter(SDKType_PlainOldDataSDKPass_Plain);
    
PrepSDKCall_AddParameter(SDKType_PlainOldDataSDKPass_Plain);
    
PrepSDKCall_SetReturnInfo(SDKType_PlainOldDataSDKPass_Plain);

    
// Validate call
    
if((hSDKCallAddLayeredSequence EndPrepSDKCall()) == nullSetFailState("Failed to load SDK call \"CBaseAnimatingOverlay::AddLayeredSequence\". Update signature in \"plugin.turret\""); 
    
    
/*__________________________________________________________________________________________________*/

    // Close file
    
delete hConfig;

Improved methodmap (pelipoika fix)
PHP Code:
#define ANIM_LAYER_ACTIVE        0x0001 
#define ANIM_LAYER_AUTOKILL      0x0002 
#define ANIM_LAYER_KILLME        0x0004 
#define ANIM_LAYER_DONTRESTORE   0x0008 
#define ANIM_LAYER_CHECKACCESS   0x0010 
#define ANIM_LAYER_DYING         0x0020
#define ANIM_LAYER_NOEVENTS         0x0040

enum //CAnimationLayer 
{
    
m_fFlags 0,
    
m_bSequenceFinished 4,
    
m_bLooping 5,
    
m_nSequence 8,
    
m_flCycle 12,
    
m_flPlaybackRate 16,
    
m_flPrevCycle 20,
    
m_flWeight 24,
    
m_flWeightDeltaRate 28,
    
m_flBlendIn 32,
    
m_flBlendOut 36,
    
m_flKillRate 40,
    
m_flKillDelay 44,
    
m_flLayerAnimtime 48,
    
m_flLayerFadeOuttime 52,
    
/*
        ??? = 56,
        ??? = 60,
        ??? = 64,
    */
    
m_nActivity 68,
    
m_nPriority 72,
    
m_nOrder 76,
    
m_flLastEventCheck 80,
    
m_flLastAccess 84,
    
m_pOwnerEntity 88,
    
CAnimationLayer_Size 92
};

methodmap CAnimationOverlay  

    public 
CAnimationOverlay(int address)
    {
        return 
view_as<CAnimationOverlay>(address);
    }
    
    
property Address Address  
    

        public 
get()  
        { 
            return 
view_as<Address>(this); 
        } 
    } 
    
    
property bool isNull
    
{
        public 
get()  
        { 
            return 
this.Address == Address_Null
        } 
    }

    public 
any Get(int iOffsetint iLayer
    { 
        return 
LoadFromAddress(this.Address view_as<Address>(iOffset CAnimationLayer_Size iLayer), NumberType_Int32); 
    } 
     
    public 
void Set(int iOffsetint iLayerany iValue
    { 
        
StoreToAddress(this.Address view_as<Address>(iOffset CAnimationLayer_Size iLayer), iValueNumberType_Int32); 
    } 

    public 
bool IsActive(int iLayer)    { return ((this.Get(m_fFlagsiLayer) & ANIM_LAYER_ACTIVE)   != 0); } 
    public 
bool IsAutokill(int iLayer)  { return ((this.Get(m_fFlagsiLayer) & ANIM_LAYER_AUTOKILL) != 0); } 
    public 
bool IsKillMe(int iLayer)    { return ((this.Get(m_fFlagsiLayer) & ANIM_LAYER_KILLME)   != 0); } 
    public 
bool IsDying(int iLayer)     { return ((this.Get(m_fFlagsiLayer) & ANIM_LAYER_DYING)    != 0); } 
    public 
bool    NoEvents(int iLayer)    { return ((this.Get(m_fFlagsiLayer) & ANIM_LAYER_NOEVENTS) != 0); }
    public 
void KillMe(int iLayer)      { int iFlags this.Get(m_fFlagsiLayer); this.Set(m_fFlagsiLayer, (iFlags |= ANIM_LAYER_KILLME)); } 
    public 
void AutoKill(int iLayer)    { int iFlags this.Get(m_fFlagsiLayer); this.Set(m_fFlagsiLayer, (iFlags |= ANIM_LAYER_AUTOKILL)); }
    public 
void Dying(int iLayer)       { int iFlags this.Get(m_fFlagsiLayer); this.Set(m_fFlagsiLayer, (iFlags |= ANIM_LAYER_DYING));  } 
    public 
void Dead(int iLayer)        { int iFlags this.Get(m_fFlagsiLayer); this.Set(m_fFlagsiLayer, (iFlags &= ~ANIM_LAYER_DYING)); }
    
    
// @link https://github.com/VSES/SourceEngine2007/blob/43a5c90a5ada1e69ca044595383be67f40b33c61/src_main/game/server/BaseAnimatingOverlay.cpp#L1073
    
public void RemoveLayer(int iLayerfloat flKillRatefloat flKillDelay)
    {
        
this.Set(m_flKillRateiLayerflKillRate 0.0 this.Get(m_flWeightiLayer) / flKillRate 100.0);
        
this.Set(m_flKillDelayiLayerflKillDelay);
        
this.KillMe(iLayer);
    }
    
    
// @link https://github.com/VSES/SourceEngine2007/blob/43a5c90a5ada1e69ca044595383be67f40b33c61/src_main/game/server/BaseAnimatingOverlay.cpp#L815
    
public bool IsAlive(int iLayer)         { int iFlags this.Get(m_fFlagsiLayer); return (((iFlags ANIM_LAYER_ACTIVE) != 0) || ((iFlags ANIM_LAYER_KILLME) == 0)); }
    
    
// @link https://github.com/VSES/SourceEngine2007/blob/43a5c90a5ada1e69ca044595383be67f40b33c61/src_main/game/server/BaseAnimatingOverlay.cpp#L1060
    
public int GetLayerSequence(int iLayer) { return (this.Get(m_nSequenceiLayer)); }

PHP Code:
public Address GetStudioHdr() 
    { 
        return 
view_as<Address>(GetEntData(this.IndexAnimating_StudioHdr)); 
    } 

    public 
CAnimationOverlay CBaseAnimatingOverlay() 
    { 
        static 
int iOffset;
        if(!
iOffsetiOffset FindDataMapInfo(this.Index"m_AnimOverlay");
        return 
CAnimationOverlay(GetEntData(this.IndexiOffset));
    }
    
    public 
void SetPoseParameter(int iParameterfloat flStartfloat flEndfloat flValue)    
    { 
        
float flCtl = (flValue flStart) / (flEnd flStart); 
        if(
flCtl 0flCtl 0.0
        if(
flCtl 1flCtl 1.0
         
        
SetEntPropFloat(this.IndexProp_Send"m_flPoseParameter"flCtliParameter); 
    } 
    
    public 
int LookupPoseParameter(char[] sName)    
    {
        
// Validate address
        
Address pStudioHdrClass this.GetStudioHdr(); 
        if(
pStudioHdrClass == Address_Null
        {
            return -
1
        }
        
        return 
SDKCall(hSDKCallLookupPoseParameterthis.IndexpStudioHdrClasssName); 
    } 

    public 
void StudioFrameAdvance()
    {
        
SDKCall(hSDKCallStudioFrameAdvancethis.Index); 
    }
    
    public 
void GetAttachment(char[] sNamefloat vPosition[3], float vAngle[3])    
    { 
      
/*if(Platform == OS_Windows)
        {
            SDKCall(hSDKCallGetAttachment, this.Index, sName, vPosition, vAngle); 
        }
        else
        {
            int iAttach = SDKCall(hSDKCallLookupAttachment, this.Index, sName);
            if(iAttach)
            {
                SDKCall(hSDKCallGetAttachment, this.Index, iAttach, vPosition, vAngle); 
            }
        }*/
        
ZP_GetAttachment(this.IndexsNamevPositionvAngle);
    } 

    public 
int LookupSequence(char[] sAnim
    {
        if(
Platform == OS_Windows)
        {
            return 
SDKCall(hSDKCallLookupSequencethis.IndexsAnim); 
        }
        else
        {
            
// Validate address
            
Address pStudioHdrClass this.GetStudioHdr(); 
            if(
pStudioHdrClass == Address_Null
            {
                return -
1
            }
            
            return 
SDKCall(hSDKCallLookupSequencepStudioHdrClasssAnim); 
        }
    }
    
    public 
int AnimOverlayCount()
    {
        static 
int iOffset;
        if(!
iOffsetiOffset FindDataMapInfo(this.Index"m_AnimOverlay") + AnimatingOverlay_Count;
        return 
GetEntData(this.IndexiOffset);
    }
    
    
/*__________________________________________________________________________________________________*/
    
    // @info https://github.com/VSES/SourceEngine2007/blob/43a5c90a5ada1e69ca044595383be67f40b33c61/src_main/game/server/BaseAnimatingOverlay.cpp#L811
    
public int FindGestureLayer(char[] sAnim
    {
        
// Find the sequence index
        
int iSequence this.LookupSequence(sAnim); 
        if(
iSequence 0
        {
            return -
1
        }

        
// Validate address
        
CAnimationOverlay pOverlay this.CBaseAnimatingOverlay(); 
        if(
pOverlay.isNull
        {
            return -
1
        }
        
        
// i = layer index
        
int iCount this.AnimOverlayCount();
        for(
int i 0iCounti++) 
        {
            
// Validate layer
            
if(!pOverlay.IsAlive(i)) 
            {
                continue; 
            }

            
// Validate sequence
            
if(pOverlay.GetLayerSequence(i) == iSequence
            {
                return 
i
            }
        } 
        
        
// Return on the unsuccess
        
return -1
    }
    
    
// @link https://github.com/VSES/SourceEngine2007/blob/43a5c90a5ada1e69ca044595383be67f40b33c61/src_main/game/server/BaseAnimatingOverlay.cpp#L664
    
public bool IsValidLayer(int iLayer)
    {
        return (
iLayer >= && iLayer this.AnimOverlayCount());
    }

    
// @link https://github.com/VSES/SourceEngine2007/blob/43a5c90a5ada1e69ca044595383be67f40b33c61/src_main/game/server/BaseAnimatingOverlay.cpp#L527
    
public int AddGesture(char[] sAnimbool bAutoKill true
    { 
        
// Find the sequence index
        
int iSequence this.LookupSequence(sAnim); 
        if(
iSequence 0
        {
            return -
1
        }

        
// Validate address
        
CAnimationOverlay pOverlay this.CBaseAnimatingOverlay(); 
        if(
pOverlay.isNull
        {
            return -
1
        }
        
        
// Create a new layer
        
int iLayer SDKCall(hSDKCallAddLayeredSequencethis.IndexiSequence0); 
        if(
this.IsValidLayer(iLayer) && bAutoKill && pOverlay.IsActive(iLayer))
        {
            
// Set the main properties
            
pOverlay.AutoKill(iLayer);
        }
        
        
// Return on the success
        
return iLayer;
    } 

    
// @link https://github.com/VSES/SourceEngine2007/blob/43a5c90a5ada1e69ca044595383be67f40b33c61/src_main/game/server/BaseAnimatingOverlay.cpp#L836
    
public bool IsPlayingGesture(char[] sAnim)    
    { 
        return 
this.FindGestureLayer(sAnim) != -true false
    } 

    
// @link https://github.com/VSES/SourceEngine2007/blob/43a5c90a5ada1e69ca044595383be67f40b33c61/src_main/game/server/BaseAnimatingOverlay.cpp#L866
    
public void RemoveGesture(char[] sAnim
    { 
        
// Validate layer
        
int iLayer this.FindGestureLayer(sAnim); 
        if(
iLayer == -1
        {
            return; 
        }

        
// Validate address
        
CAnimationOverlay pOverlay this.CBaseAnimatingOverlay(); 
        if(
pOverlay.isNull
        {
            return; 
        }
        
        
// Delete it !
        
pOverlay.RemoveLayer(iLayer0.20.0)
    }

/*__________________________________________________________________________________________________*/ 
Working example (tuuret)
https://github.com/qubka/Zombie-Plague/blob/master/zp_weapon_dronegun.sp

PHP Code:
"Games"
{
    
"csgo"
    
{
        
"Offsets"
        
{
            
// @link https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/mp/src/game/server/baseanimating.h#L421
            
"CBaseAnimating::StudioHdr"
            
{
                
"windows"   "68"
                "linux"     "68"
            
}
            
// @link https://github.com/VSES/SourceEngine2007/blob/43a5c90a5ada1e69ca044595383be67f40b33c61/src_main/public/tier1/utlvector.h#L347
            
"CBaseAnimatingOverlay::Count"
            
{
                
"windows"   "12"
                "linux"     "12"
            
}
            
"CServer::OS"
            
{
                
"windows"   "1"
                "linux"     "2"
            
}
        }

        
// Sigs from the lib ( https://forums.alliedmods.net/showthread.php?t=309074 )
        // You can update them only by yourself using tutorial in the link
        
"Signatures"
        
{
            
// @link https://github.com/VSES/SourceEngine2007/blob/43a5c90a5ada1e69ca044595383be67f40b33c61/src_main/game/server/BaseAnimatingOverlay.cpp#L560
        
            
"CBaseAnimating::LookupPoseParameter" // Str: "Call to NULL CStudioHdr::GroupStudioHdr()\n" == "CStudioHdr::GroupStudioHdr" -> "CStudioHdr::pPoseParameter" -> "CStudioHdr::LookupPoseParameter"
            
{
                
"library"   "server"
                "windows"    "\x55\x8B\xEC\x57\x8B\x7D\x08\x85\xFF\x75\x2A\x33\xC0\x5F\x5D\xC2\x08\x00"
                "linux"     "\x55\x89\xE5\x57\x56\x53\x31\xDB\x83\xEC\x1C\x8B\x75\x0C\x8B\x7D\x10"
            
}
            
"CBaseAnimating::LookupSequence" // Str: "Discarding missing sequence %s on load.\n"
            
{
                
"library"   "server"
                "windows"    "\x55\x8B\xEC\x51\x56\x57\x8B\xF9\x83\xBF\xC0\x04\x00\x00\x00\x75\x2A\xA1\x2A\x2A\x2A\x2A\x8B\x30\x8B\x07\xFF\x50\x18\x8B\x0D\x2A\x2A\x2A\x2A\x50\xFF\x56\x04\x85\xC0\x74\x2A\x8B\xCF\xE8\x2A\x2A\x2A\x2A\x8B\xB7\xC0\x04\x00\x00\x85\xF6\x74\x2A\x83\x3E\x00\x74\x2A\x8B\xCE"
                "linux"     "\x55\x89\xE5\x83\xEC\x48\xA1\x2A\x2A\x2A\x2A\x89\x75\xF8\x89\x7D\xFC\x8B\x75\x08"
            
}
            
"CBaseAnimatingOverlay::StudioFrameAdvance" // Str: "removing %d (%d): %s : %5.3f (%.3f)\n" | " %d (%d): %s : %5.3f (%.3f)\n"
            
{
                
"library"   "server"
                "windows"    "\x55\x8B\xEC\x83\xE4\xC0\xA1\x2A\x2A\x2A\x2A\x83\xEC\x34\xF3\x0F\x10\x48\x10"
                "linux"     "\x55\x89\xE5\x57\x56\x53\x83\xEC\x5C\x8B\x75\x08\x89\x34\x24\xE8\x2A\x2A\x2A\x2A\x89\x34\x24"
            
}
            
"CBaseAnimatingOverlay::AddLayeredSequence" // Str: "%5.3f : adding %d (%d): %s : %5.3f (%.3f)\n" | "%s_t"
            
{
                
"library"   "server"
                "windows"    "\x55\x8B\xEC\x83\xE4\xC0\x83\xEC\x34\x53\x56\x57\xFF\x75\x0C"
                "linux"     "\x55\x89\xE5\x57\x56\x53\x83\xEC\x6C\x8B\x5D\x08\x8B\x45\x10\x89\x1C\x24"
            
}
"CBaseAnimating::LookupAttachment" // Str: "weapon_bone"
            

                
"library"   "server" 
                "windows"   "\x55\x8B\xEC\x57\x8B\xF9\x83\xBF\xC0\x04\x00\x00\x00\x75\x2A\xA1\x2A\x2A\x2A\x2A\x56\x8B\x30\x8B\x07\xFF\x50\x18\x8B\x0D\x2A\x2A\x2A\x2A\x50\xFF\x56\x04\x5E\x85\xC0\x74\x2A\x8B\xCF\xE8\x2A\x2A\x2A\x2A\x8B\x8F\xC0\x04\x00\x00\x5F\x85\xC9\x74\x2A\x83\x39\x00\x74\x2A\x8B\x55\x08\xE8\x2A\x2A\x2A\x2A" 
                "linux"     "\x55\x89\xE5\x53\x83\xEC\x14\x8B\x5D\x08\x8B\x83\xD8\x04\x00\x00\x85\xC0\x74\x2A\x8B\x83\xD8\x04\x00\x00\x85\xC0\x74\x2A\x8B\x18\x85\xDB" 
            
}  
            
"CBaseAnimating::GetAttachment" // Str: "weapon_bone"
            
{
                
"library"   "server"            
                "windows"   "\x55\x8B\xEC\x83\xE4\xF8\x83\xEC\x30\x8B\x01"
                "linux"     "\x55\x89\xE5\x83\xEC\x58\x8B\x45\x08\x89\x5D\xF4\x89\x75\xF8\x8B\x4D\x0C"
}
        }
    }

__________________

Last edited by gubka; 03-15-2019 at 07:50.
gubka is offline
Send a message via ICQ to gubka