Orpheu: Engine PM Functions

For scripting examples for learning how to use AMXX.
User avatar
Archive-Poster
Posts: 1267
Gender:
United States of America

Orpheu: Engine PM Functions

Post by Archive-Poster »

In half life engine there is a part of the code where the physic calculations to player movement happen (jumping, ducking, moving on water, no clipping, etc). It is unexplored in scripting because those functions are not acessible normally. With orpheu you can use them.

The entry point for the calculations is the function PM_Move, that has the following header:

Code: Select all

PM_Move ( struct playermove_s *ppmove, int server )
The first argument is a structure (a group of data belonging to a player) that is saved when PM_Move is called and then used in other PM functions.

When using Orpheu to hook PM functions the way of accessing the ppmove structure varies from PM_Move to other functions.

In PM_Move you can use it directly:

Code: Select all

public PM_Move(ppmove,server)
{
    new Float:gravity = Float:OrpheuGetParamStructMember(1,"gravity")
} 
In other functions you have to get ppmove from memory and use it after.
We need to declare in a file how to obtain it from memory but that part is already made by me so you just have to care with using it:

Code: Select all

OrpheuStruct:get_ppmove()
{        
    return OrpheuGetStructFromAddress(OrpheuStructPlayerMove,OrpheuMemoryGet("ppmove"))
}
   
public PM_Duck()
{
    new OrpheuStruct:ppmove = get_ppmove()
        
    new gravity = OrpheuGetStructMember(ppmove,"gravity")
} 
To retrieve the id of a player you should use the member of ppmove called "player_index":

Code: Select all

new id = OrpheuGetStructMember(ppmove,"player_index") + 1 
A full example on blocking duck for non bot players:

Code: Select all

#include <amxmodx>
#include <orpheu>
#include <orpheu_advanced>
#include <orpheu_memory>
    
public plugin_init()
{        
    OrpheuRegisterHook(OrpheuGetFunction("PM_Duck"),"OnPM_Duck")
}

public OrpheuHookReturn:OnPM_Duck()
{
    new OrpheuStruct:ppmove = get_ppmove()
    
    new id = OrpheuGetStructMember(ppmove,"player_index") + 1
    
    if(is_user_bot(id))
    {
        return OrpheuSupercede
    }
    
    return OrpheuIgnored
}

OrpheuStruct:get_ppmove()
{        
    return OrpheuGetStructFromAddress(OrpheuStructPlayerMove,OrpheuMemoryGet("ppmove"))
} 
Before using these functions do some research about how they work.
Download hlsdk

And check multiplayer/pm_shared/pm_shared.cpp

As attachment I will provide an example script and files to use those functions out of the box:

Code: Select all

PM_Init
PM_Move
PM_PlayerMove
PM_Jump
PM_PlayStepSound
PM_CatagorizeTextureType
PM_FlyMove
PM_UpdateStepSound
PM_CheckVelocity
PM_WaterMove
PM_CheckWater
PM_SpectatorMove
PM_LadderMove
PM_Physics_Toss
PM_CheckWaterJump
PM_CheckFalling
PM_ReduceTimers
PM_CreateStuckTable
Note that these files are meant to be used for your experiments and thus I did not took the time to create signatures but instead providing their offsets. This means that you should use them for testing only. If you want to release plugins with it make signatures or ask here.

On a last note, PM functions occur in parallel in the server and the client and because of client prediction there are functions that are useless to block since they will occur in the client anyway or at least don't act exactly as expected.
Attachments
pm_pack.zip
(7.47 KiB) Downloaded 5 times

Who is online

Users browsing this forum: No registered users and 1 guest