diff --git a/addons/sourcemod/scripting/include/movementapi.inc b/addons/sourcemod/scripting/include/movementapi.inc index 08a073a..59b167a 100644 --- a/addons/sourcemod/scripting/include/movementapi.inc +++ b/addons/sourcemod/scripting/include/movementapi.inc @@ -107,6 +107,16 @@ forward void Movement_OnStopDucking(int client); */ forward void Movement_OnPlayerJump(int client, bool jumpbug); +/** + * Called when a player edgebugs + * Setting velocity when this is called may not be effective. + * + * @param client Client index. + * @param origin Player origin before edgebug. + * @param velocity Player velocity before edgebug. + */ +forward void Movement_OnPlayerEdgebug(int client, float origin[3], float velocity[3]); + /** * Called before PlayerMove movement function is called. * Modifying origin or velocity parameters will change player's origin and velocity accordingly. @@ -283,28 +293,28 @@ forward Action Movement_OnCategorizePositionPre(int client, float origin[3], flo */ forward Action Movement_OnCategorizePositionPost(int client, float origin[3], float velocity[3]); -/** - * Called before TryPlayerMove movement function is called. - * Modifying origin or velocity parameters will change player's origin and velocity accordingly. - * - * @param client Client index. - * @param origin Player origin. - * @param velocity Player velocity. - * @return Plugin_Changed if origin or velocity is changed, Plugin_Continue otherwise. - */ -forward Action Movement_OnTryPlayerMovePre(int client, float origin[3], float velocity[3]); - -/** - * Called after TryPlayerMove movement function is called. - * Modifying origin or velocity parameters will change player's origin and velocity accordingly. - * - * @param client Client index. - * @param origin Player origin. - * @param velocity Player velocity. - * @return Plugin_Changed if origin or velocity is changed, Plugin_Continue otherwise. - */ -forward Action Movement_OnTryPlayerMovePost(int client, float origin[3], float velocity[3]); - +/** + * Called before TryPlayerMove movement function is called. + * Modifying origin or velocity parameters will change player's origin and velocity accordingly. + * + * @param client Client index. + * @param origin Player origin. + * @param velocity Player velocity. + * @return Plugin_Changed if origin or velocity is changed, Plugin_Continue otherwise. + */ +forward Action Movement_OnTryPlayerMovePre(int client, float origin[3], float velocity[3]); + +/** + * Called after TryPlayerMove movement function is called. + * Modifying origin or velocity parameters will change player's origin and velocity accordingly. + * + * @param client Client index. + * @param origin Player origin. + * @param velocity Player velocity. + * @return Plugin_Changed if origin or velocity is changed, Plugin_Continue otherwise. + */ +forward Action Movement_OnTryPlayerMovePost(int client, float origin[3], float velocity[3]); + // =====[ NATIVES ]===== /** @@ -735,4 +745,4 @@ public void __pl_movementapi_SetNTVOptional() MarkNativeAsOptional("Movement_GetCollisionEndOrigin"); MarkNativeAsOptional("Movement_GetCollisionNormal"); } -#endif +#endif \ No newline at end of file diff --git a/addons/sourcemod/scripting/movementapi/forwards.sp b/addons/sourcemod/scripting/movementapi/forwards.sp index 4ba3891..bc96b00 100644 --- a/addons/sourcemod/scripting/movementapi/forwards.sp +++ b/addons/sourcemod/scripting/movementapi/forwards.sp @@ -4,6 +4,7 @@ static Handle H_OnStartTouchGround; static Handle H_OnStopTouchGround; static Handle H_OnChangeMovetype; static Handle H_OnPlayerJump; +static Handle H_OnPlayerEdgebug; static Handle H_OnPlayerMovePre; static Handle H_OnPlayerMovePost; @@ -21,8 +22,8 @@ static Handle H_OnWalkMovePre; static Handle H_OnWalkMovePost; static Handle H_OnCategorizePositionPre; static Handle H_OnCategorizePositionPost; -static Handle H_OnTryPlayerMovePre; -static Handle H_OnTryPlayerMovePost; +static Handle H_OnTryPlayerMovePre; +static Handle H_OnTryPlayerMovePost; void CreateGlobalForwards() { @@ -32,6 +33,7 @@ void CreateGlobalForwards() H_OnStopTouchGround = CreateGlobalForward("Movement_OnStopTouchGround", ET_Ignore, Param_Cell, Param_Cell, Param_Cell, Param_Cell); H_OnChangeMovetype = CreateGlobalForward("Movement_OnChangeMovetype", ET_Ignore, Param_Cell, Param_Cell, Param_Cell); H_OnPlayerJump = CreateGlobalForward("Movement_OnPlayerJump", ET_Ignore, Param_Cell, Param_Cell); + H_OnPlayerEdgebug = CreateGlobalForward("Movement_OnPlayerEdgebug", ET_Ignore, Param_Cell, Param_Array, Param_Array); H_OnPlayerMovePre = CreateGlobalForward("Movement_OnPlayerMovePre", ET_Event, Param_Cell, Param_Array, Param_Array); H_OnPlayerMovePost = CreateGlobalForward("Movement_OnPlayerMovePost", ET_Event, Param_Cell, Param_Array, Param_Array); @@ -90,8 +92,6 @@ void Call_OnStopTouchGround(int client, bool jumped, bool ladderJump, bool jumpb Call_PushCell(ladderJump); Call_PushCell(jumpbug); Call_Finish(); - // Immediately update OldOnGround state, so we can catch takeoffs that happen outside movement processing. - gB_OldOnGround[client] = false; } @@ -112,6 +112,15 @@ void Call_OnPlayerJump(int client, bool jumpbug) Call_Finish(); } +void Call_OnPlayerEdgebug(int client, float origin[3], float velocity[3]) +{ + Call_StartForward(H_OnPlayerEdgebug); + Call_PushCell(client); + Call_PushArray(origin, 3); + Call_PushArray(velocity, 3); + Call_Finish(); +} + Action Call_OnPlayerMovePre(int client, float origin[3], float velocity[3], Action &result) { Call_StartForward(H_OnPlayerMovePre); diff --git a/addons/sourcemod/scripting/movementapi/hooks.sp b/addons/sourcemod/scripting/movementapi/hooks.sp index c842be2..440588f 100644 --- a/addons/sourcemod/scripting/movementapi/hooks.sp +++ b/addons/sourcemod/scripting/movementapi/hooks.sp @@ -568,12 +568,45 @@ public MRESReturn DHooks_OnTryPlayerMove_Post(Address pThis, DHookReturn hReturn Address m_TouchList_m_pElements = LoadFromAddress(moveHelperAddr + view_as
(8) + view_as(16), NumberType_Int32); + bool hitStandableSurface = false; + static ConVar sv_standable_normal; + if (sv_standable_normal == INVALID_HANDLE) + { + sv_standable_normal = FindConVar("sv_standable_normal"); + } for (int i = 0; i < gI_CollisionCount[client]; i++) { Trace trace = Trace(m_TouchList_m_pElements + view_as(i*96) + view_as(12)); trace.startpos.ToArray(gF_TraceStartOrigin[client][i]); trace.endpos.ToArray(gF_TraceEndOrigin[client][i]); trace.plane.normal.ToArray(gF_TraceNormal[client][i]); + if (trace.plane.normal.z >= sv_standable_normal.FloatValue) + { + hitStandableSurface = true; + } + } + + // Edgebug detection + + if (hitStandableSurface) + { + float currentOrigin[3], groundEndPoint[3]; + + GameMove_GetOrigin(pThis, currentOrigin); + groundEndPoint = currentOrigin; + groundEndPoint[2] -= 2.0; + float mins[3] = {-16.0, -16.0, 0.0}; + float maxs[3] = {16.0, 16.0, 0.0}; + TR_TraceHullFilter(currentOrigin, groundEndPoint, mins, maxs, MASK_PLAYERSOLID, TraceEntityFilterPlayers, client); + + float groundPos[3]; + TR_GetEndPosition(groundPos); + + // Note: Origin and velocity are not updated yet. + if (!TR_DidHit()) + { + Call_OnPlayerEdgebug(client, gF_Origin[client], gF_Velocity[client]); + } } Action result = UpdateMoveData(pThis, client, Call_OnTryPlayerMovePost);