Skip to content

Instantly share code, notes, and snippets.

@21Joakim
Created June 11, 2024 12:26
Show Gist options
  • Select an option

  • Save 21Joakim/9825489a715216abe2f1dba5f1749ad2 to your computer and use it in GitHub Desktop.

Select an option

Save 21Joakim/9825489a715216abe2f1dba5f1749ad2 to your computer and use it in GitHub Desktop.
CS2: Remove player clipping
// Remove the player clipping, this means you can walk outside the map and go up into the sky unrestricted,
// might be useful for a flying scoutsman type gamemode. As a side effect of this it's likely any stairs
// won't be smooth anymore (your view will jump up a little each step) because it uses the same player clipping.
// Found this by removing each of the flags set one at a time.
public const long SOLID_MASK_PLAYERCLIP = 16;
// How to find
// 1. Find the `dev_create_move_report` convar and check the function it's used in,
// this is a method of CCSPlayer_MovementServices, the first argument is the movement services.
// 2. Somewhere towards the end there will a call to a function which has a bitwise OR as one of the arguments
// sub_E3F260(*(_QWORD*) (aMovementServices + 48) + 2152LL, v12 | v13);
//
// Alternative way of finding it (probably more reliable but a bit less direct)
// 1. Find the `mp_solid_teammates` convar and the functions using it
// 2. There will a short function which returns a bool based on the convar (this is IsTeammateSolid)
// 3. Check where this function is used and follow 2. above
public static readonly MemoryFunctionWithReturn<IntPtr, long, long> SetSolidMask = new("48 8B 47 20 48 39 F0 75 07 C3");
// This is called every tick so the solid mask needs to be continuously set
public HookResult SetSolidMaskHook(DynamicHook hook)
{
IntPtr pointer = hook.GetParam<IntPtr>(0);
long flag = hook.GetParam<long>(1);
// If you need the player to do some checks it can be retrieved like this,
// the offset can be found by checking the first argument of the function that
// calls this, it might look something like "*(a1 + 48) + 2152", 48 is the offset
// between movement services and the player pawn.
CCSPlayerPawn pawn = new(pointer - 2152);
if (pawn.Bot != null)
{
return HookResult.Continue;
}
hook.SetParam(1, flag & ~SOLID_MASK_PLAYERCLIP);
return HookResult.Continue;
}
public void Load() => SetSolidMask.Hook(SetSolidMaskHook, HookMode.Pre);
public void Unload() => SetSolidMask.Unhook(SetSolidMaskHook, HookMode.Pre);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment