How to check for player surfing

Please post any questions about developing your plugin here. Please use the search function before posting!
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

How to check for player surfing

Postby decompile » Fri Jun 04, 2021 12:30 pm

Hello,

I was wondering if someone could please create me a snippet for checking if a player is currently surfing, possibly with comments aswell.

I was checking around and found that you can do that with TraceFilters, but I have no experience in using them in Source.Python.

Maybe this could be useful:

Code: Select all

public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon)
{
   if(g_bSlopeFixEnable == true)
   {
      g_bLastOnGround[client] = g_bOnGround[client];
      
      if (GetEntityFlags(client) & FL_ONGROUND)
         g_bOnGround[client] = true;
      else
         g_bOnGround[client] = false;
      
      g_vLast[client][0]    = g_vCurrent[client][0];
      g_vLast[client][1]    = g_vCurrent[client][1];
      g_vLast[client][2]    = g_vCurrent[client][2];
      g_vCurrent[client][0] = GetEntPropFloat(client, Prop_Send, "m_vecVelocity[0]");
      g_vCurrent[client][1] = GetEntPropFloat(client, Prop_Send, "m_vecVelocity[1]");
      g_vCurrent[client][2] = GetEntPropFloat(client, Prop_Send, "m_vecVelocity[2]");
      
      // Check if player landed on the ground
      if (g_bOnGround[client] == true && g_bLastOnGround[client] == false)
      {
         // Set up and do tracehull to find out if the player landed on a slope
         float vPos[3];
         GetEntPropVector(client, Prop_Data, "m_vecOrigin", vPos);

         float vMins[3];
         GetEntPropVector(client, Prop_Send, "m_vecMins", vMins);

         float vMaxs[3];
         GetEntPropVector(client, Prop_Send, "m_vecMaxs", vMaxs);

         float vEndPos[3];
         vEndPos[0] = vPos[0];
         vEndPos[1] = vPos[1];
         vEndPos[2] = vPos[2] - FindConVar("sv_maxvelocity").FloatValue;
         
         TR_TraceHullFilter(vPos, vEndPos, vMins, vMaxs, MASK_PLAYERSOLID_BRUSHONLY, TraceRayDontHitSelf, client);

         if(TR_DidHit())
         {
            // Gets the normal vector of the surface under the player
            float vPlane[3], vLast[3];
            TR_GetPlaneNormal(INVALID_HANDLE, vPlane);
            
            // Make sure it's not flat ground and not a surf ramp (1.0 = flat ground, < 0.7 = surf ramp)
            if(0.7 <= vPlane[2] < 1.0)
            {
                 [...]
            }
         }   
      }
   }
}


Thanks in advice.
Last edited by decompile on Sun Jun 27, 2021 1:47 am, edited 1 time in total.
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: Player is surfing

Postby decompile » Sat Jun 26, 2021 1:39 am

Does anyone have an idea? But I never worked with TraceFilter's. Help is very appreciated.

Found the following on sourcemod forums:
If you wanna check if they're currently on a surf ramp, you can do a trace hull and check the plane normal. IIRC for a plane to be surfable, the normal z has to be <= 0.7
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: How to check for player surfing

Postby decompile » Sun Jun 27, 2021 1:54 am

Hello,

by searching older forum posts, I finally figured out how to convert the snippet and It looks like its working as it should.

Thanks to both Kami & VinciT for sharing their GameTrace snippets on the forums which helped me figure it out:
@Kami - https://forums.sourcepython.com/viewtopic.php?p=15256#p15256
@VinciT - https://forums.sourcepython.com/viewtopic.php?p=14716#p14716

If you find something which can be improved, let me know.

test/test.py

Syntax: Select all

from cvars import ConVar
from engines.trace import ContentMasks
from engines.trace import GameTrace
from engines.trace import Ray
from engines.trace import TraceFilterSimple
from engines.trace import engine_trace
from listeners import OnPlayerRunCommand
from mathlib import Vector


sv_maxvelocity = ConVar("sv_maxvelocity")


@OnPlayerRunCommand
def on_player_run_command(player, user_cmd):
index = player.index

if player.dead:
return

is_surfing = is_player_surfing(player)

print("Is {} surfing? => {}".format(player.name, is_surfing))


def is_player_surfing(player):
origin = player.origin

destination = Vector(origin.x, origin.y, origin.z - sv_maxvelocity.get_int())

trace = GameTrace()

engine_trace.trace_ray(
Ray(origin, destination, player.mins, player.maxs),
ContentMasks.PLAYER_SOLID_BRUSH_ONLY,
TraceFilterSimple((player,)),
trace,
)

is_surfing = False

if trace.did_hit():
# Sometimes I'm getting 0.00048828125, mostly 0.0
destination_distance = trace.end_position.get_distance(origin)

if (
0 <= destination_distance <= 1
and trace.plane.normal.z <= 0.70
):
is_surfing = True

return is_surfing

Return to “Plugin Development Support”

Who is online

Users browsing this forum: No registered users and 22 guests