Skip to content

Commit 1dd69bc

Browse files
authored
Attempt to address inconsistent rocket jump fix (#934)
* Add `l4d_fix_rocket_jump` * Archive old `l4d2_fix_rocketjump` * Update generalfixes.cfg
1 parent 939adb5 commit 1dd69bc

File tree

5 files changed

+227
-1
lines changed

5 files changed

+227
-1
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
"Games"
2+
{
3+
"#default"
4+
{
5+
"Functions"
6+
{
7+
"CGameMovement::SetGroundEntity"
8+
{
9+
"signature" "CGameMovement::SetGroundEntity"
10+
"linux"
11+
{
12+
"callconv" "cdecl"
13+
}
14+
"windows"
15+
{
16+
"callconv" "stdcall"
17+
}
18+
"return" "void"
19+
"arguments"
20+
{
21+
"this"
22+
{
23+
"type" "objectptr"
24+
"windows"
25+
{
26+
"register" "ecx"
27+
}
28+
}
29+
"a1"
30+
{
31+
"type" "objectptr"
32+
}
33+
}
34+
}
35+
}
36+
37+
"Signatures"
38+
{
39+
"CGameMovement::SetGroundEntity"
40+
{
41+
"library" "server"
42+
"linux" "@_ZN13CGameMovement15SetGroundEntityEP10CGameTrace"
43+
}
44+
}
45+
}
46+
47+
"left4dead"
48+
{
49+
"Signatures"
50+
{
51+
"CGameMovement::SetGroundEntity"
52+
{
53+
"library" "server"
54+
"windows" "\x83\xEC\x0C\x53\x55\x8B\x6C\x24\x18\x85\xED\x56\x8B\xD9"
55+
// 83 EC 0C 53 55 8B 6C 24 18 85 ED 56 8B D9
56+
}
57+
}
58+
}
59+
60+
"left4dead2"
61+
{
62+
"Signatures"
63+
{
64+
"CGameMovement::SetGroundEntity"
65+
{
66+
"library" "server"
67+
"windows" "\x55\x8B\xEC\x8B\x45\x08\x83\xEC\x0C\x53\x56\x57\x8B\xF9"
68+
// 55 8B EC 8B 45 08 83 EC 0C 53 56 57 8B F9
69+
}
70+
}
71+
}
72+
}
-4.61 KB
Binary file not shown.
File renamed without changes.
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
#pragma semicolon 1
2+
#pragma newdecls required
3+
4+
#include <sourcemod>
5+
#include <dhooks>
6+
7+
#define PLUGIN_VERSION "1.0"
8+
9+
public Plugin myinfo =
10+
{
11+
name = "[L4D & 2] Fix Rocket Jump",
12+
author = "Forgetest",
13+
description = "Fix some \"grounds\" launching survivors into the air.",
14+
version = PLUGIN_VERSION,
15+
url = "https://github.com/Target5150/MoYu_Server_Stupid_Plugins",
16+
}
17+
18+
methodmap GameDataWrapper < GameData {
19+
public GameDataWrapper(const char[] file) {
20+
GameData gd = new GameData(file);
21+
if (!gd) SetFailState("Missing gamedata \"%s\"", file);
22+
return view_as<GameDataWrapper>(gd);
23+
}
24+
public DynamicDetour CreateDetourOrFail(
25+
const char[] name,
26+
DHookCallback preHook = INVALID_FUNCTION,
27+
DHookCallback postHook = INVALID_FUNCTION) {
28+
DynamicDetour hSetup = DynamicDetour.FromConf(this, name);
29+
if (!hSetup)
30+
SetFailState("Missing detour setup \"%s\"", name);
31+
if (preHook != INVALID_FUNCTION && !hSetup.Enable(Hook_Pre, preHook))
32+
SetFailState("Failed to pre-detour \"%s\"", name);
33+
if (postHook != INVALID_FUNCTION && !hSetup.Enable(Hook_Post, postHook))
34+
SetFailState("Failed to post-detour \"%s\"", name);
35+
return hSetup;
36+
}
37+
}
38+
39+
public void OnPluginStart()
40+
{
41+
GameDataWrapper gd = new GameDataWrapper("l4d_fix_rocket_jump");
42+
delete gd.CreateDetourOrFail("CGameMovement::SetGroundEntity", DTR_SetGroundEntity, DTR_SetGroundEntity_Post);
43+
delete gd;
44+
}
45+
46+
// https://github.com/ValveSoftware/source-sdk-2013/blob/39f6dde8fbc238727c020d13b05ecadd31bda4c0/src/game/shared/gamemovement.cpp#L3611
47+
static bool g_bRestore[MAXPLAYERS+1];
48+
static float g_vecSavedBaseVel[MAXPLAYERS+1][3];
49+
MRESReturn DTR_SetGroundEntity(DHookParam hParams)
50+
{
51+
int client = hParams.GetObjectVar(1, 4, ObjectValueType_CBaseEntityPtr);
52+
53+
int oldground = GetEntPropEnt(client, Prop_Send, "m_hGroundEntity");
54+
int newground = !hParams.IsNull(2) ? hParams.GetObjectVar(2, 76, ObjectValueType_CBaseEntityPtr) : -1;
55+
56+
g_bRestore[client] = false;
57+
58+
if ((oldground == -1 && newground != -1) || (oldground != -1 && newground == -1))
59+
{
60+
g_bRestore[client] = !PassStandableGround(client, newground == -1 ? oldground : newground);
61+
}
62+
63+
if (g_bRestore[client])
64+
{
65+
GetEntPropVector(client, Prop_Data, "m_vecBaseVelocity", g_vecSavedBaseVel[client]);
66+
}
67+
68+
return MRES_Ignored;
69+
}
70+
71+
MRESReturn DTR_SetGroundEntity_Post(DHookParam hParams)
72+
{
73+
int client = hParams.GetObjectVar(1, 4, ObjectValueType_CBaseEntityPtr);
74+
75+
if (g_bRestore[client])
76+
{
77+
SetEntPropVector(client, Prop_Data, "m_vecBaseVelocity", g_vecSavedBaseVel[client]);
78+
}
79+
80+
return MRES_Ignored;
81+
}
82+
83+
bool PassStandableGround(int client, int entity)
84+
{
85+
if (entity > MaxClients)
86+
{
87+
char cls[64];
88+
GetEntityClassname(entity, cls, sizeof(cls));
89+
90+
if (!strcmp(cls, "witch") || !strcmp(cls, "infected"))
91+
return false;
92+
93+
if (StrContains(cls, "_projectile") != -1)
94+
return false;
95+
}
96+
else if (entity > 0)
97+
{
98+
if (GetClientTeam(client) == 2 && GetClientTeam(entity) == 3)
99+
return false;
100+
}
101+
102+
return true;
103+
}
104+
105+
// Reverse bot's aim pitch for solo testing GL jump with "bot_mimic" on.
106+
/*
107+
#include <sdktools_hooks>
108+
109+
methodmap CUserCmd
110+
{
111+
property float viewangles_x {
112+
public get() { return LoadFromAddress(view_as<Address>(this) + view_as<Address>(12), NumberType_Int32); }
113+
public set(float x) { StoreToAddress(view_as<Address>(this) + view_as<Address>(12), x, NumberType_Int32); }
114+
}
115+
}
116+
117+
int g_iRestoreMimic = -1;
118+
public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2])
119+
{
120+
static ConVar bot_mimic = null;
121+
if (bot_mimic == null)
122+
bot_mimic = FindConVar("bot_mimic");
123+
124+
if (!IsClientInGame(client) || !IsFakeClient(client))
125+
return Plugin_Continue;
126+
127+
int player = bot_mimic.IntValue;
128+
if (player <= 0 || player > MaxClients || !IsClientInGame(player))
129+
return Plugin_Continue;
130+
131+
g_iRestoreMimic = player;
132+
GetPlayerLastCommand(player).viewangles_x = -GetPlayerLastCommand(player).viewangles_x;
133+
return Plugin_Continue;
134+
}
135+
136+
public void OnPlayerRunCmdPost(int client, int buttons, int impulse, const float vel[3], const float angles[3], int weapon, int subtype, int cmdnum, int tickcount, int seed, const int mouse[2])
137+
{
138+
if (g_iRestoreMimic != -1)
139+
{
140+
GetPlayerLastCommand(g_iRestoreMimic).viewangles_x = -GetPlayerLastCommand(g_iRestoreMimic).viewangles_x;
141+
g_iRestoreMimic = -1;
142+
}
143+
}
144+
145+
CUserCmd GetPlayerLastCommand(int player)
146+
{
147+
static int s_iOffs_m_LastCmd = -1;
148+
if (s_iOffs_m_LastCmd == -1)
149+
s_iOffs_m_LastCmd = FindDataMapInfo(player, "m_hViewModel")
150+
+ 4*2; // CHandle<CBaseViewModel> * MAX_VIEWMODELS
151+
152+
return view_as<CUserCmd>(GetEntityAddress(player) + view_as<Address>(s_iOffs_m_LastCmd));
153+
}
154+
*/

cfg/generalfixes.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ sm plugins load fixes/annoyance_exploit_fixes.smx
4949
sm plugins load fixes/l4d_fix_shove_duration.smx
5050
sm plugins load fixes/l4d2_jockey_hitbox_fix.smx
5151
sm plugins load fixes/l4d_consistent_escaperoute.smx
52-
sm plugins load fixes/l4d2_fix_rocketjump.smx
52+
sm plugins load fixes/l4d_fix_rocket_jump.smx
5353
sm plugins load fixes/l4d2_charge_target_fix.smx
5454
sm plugins load fixes/l4d2_shove_fix.smx
5555
sm plugins load fixes/l4d2_scripted_tank_stage_fix.smx

0 commit comments

Comments
 (0)