diff --git a/addons/sourcemod/gamedata/l4d_fix_rocket_jump.txt b/addons/sourcemod/gamedata/l4d_fix_rocket_jump.txt new file mode 100644 index 000000000..53186b32f --- /dev/null +++ b/addons/sourcemod/gamedata/l4d_fix_rocket_jump.txt @@ -0,0 +1,72 @@ +"Games" +{ + "#default" + { + "Functions" + { + "CGameMovement::SetGroundEntity" + { + "signature" "CGameMovement::SetGroundEntity" + "linux" + { + "callconv" "cdecl" + } + "windows" + { + "callconv" "stdcall" + } + "return" "void" + "arguments" + { + "this" + { + "type" "objectptr" + "windows" + { + "register" "ecx" + } + } + "a1" + { + "type" "objectptr" + } + } + } + } + + "Signatures" + { + "CGameMovement::SetGroundEntity" + { + "library" "server" + "linux" "@_ZN13CGameMovement15SetGroundEntityEP10CGameTrace" + } + } + } + + "left4dead" + { + "Signatures" + { + "CGameMovement::SetGroundEntity" + { + "library" "server" + "windows" "\x83\xEC\x0C\x53\x55\x8B\x6C\x24\x18\x85\xED\x56\x8B\xD9" + // 83 EC 0C 53 55 8B 6C 24 18 85 ED 56 8B D9 + } + } + } + + "left4dead2" + { + "Signatures" + { + "CGameMovement::SetGroundEntity" + { + "library" "server" + "windows" "\x55\x8B\xEC\x8B\x45\x08\x83\xEC\x0C\x53\x56\x57\x8B\xF9" + // 55 8B EC 8B 45 08 83 EC 0C 53 56 57 8B F9 + } + } + } +} \ No newline at end of file diff --git a/addons/sourcemod/plugins/fixes/l4d2_fix_rocketjump.smx b/addons/sourcemod/plugins/fixes/l4d2_fix_rocketjump.smx deleted file mode 100644 index 5e7e072fb..000000000 Binary files a/addons/sourcemod/plugins/fixes/l4d2_fix_rocketjump.smx and /dev/null differ diff --git a/addons/sourcemod/scripting/l4d2_fix_rocketjump.sp b/addons/sourcemod/scripting/archive/l4d2_fix_rocketjump.sp similarity index 100% rename from addons/sourcemod/scripting/l4d2_fix_rocketjump.sp rename to addons/sourcemod/scripting/archive/l4d2_fix_rocketjump.sp diff --git a/addons/sourcemod/scripting/l4d_fix_rocket_jump.sp b/addons/sourcemod/scripting/l4d_fix_rocket_jump.sp new file mode 100644 index 000000000..93a0c8753 --- /dev/null +++ b/addons/sourcemod/scripting/l4d_fix_rocket_jump.sp @@ -0,0 +1,154 @@ +#pragma semicolon 1 +#pragma newdecls required + +#include +#include + +#define PLUGIN_VERSION "1.0" + +public Plugin myinfo = +{ + name = "[L4D & 2] Fix Rocket Jump", + author = "Forgetest", + description = "Fix some \"grounds\" launching survivors into the air.", + version = PLUGIN_VERSION, + url = "https://github.com/Target5150/MoYu_Server_Stupid_Plugins", +} + +methodmap GameDataWrapper < GameData { + public GameDataWrapper(const char[] file) { + GameData gd = new GameData(file); + if (!gd) SetFailState("Missing gamedata \"%s\"", file); + return view_as(gd); + } + public DynamicDetour CreateDetourOrFail( + const char[] name, + DHookCallback preHook = INVALID_FUNCTION, + DHookCallback postHook = INVALID_FUNCTION) { + DynamicDetour hSetup = DynamicDetour.FromConf(this, name); + if (!hSetup) + SetFailState("Missing detour setup \"%s\"", name); + if (preHook != INVALID_FUNCTION && !hSetup.Enable(Hook_Pre, preHook)) + SetFailState("Failed to pre-detour \"%s\"", name); + if (postHook != INVALID_FUNCTION && !hSetup.Enable(Hook_Post, postHook)) + SetFailState("Failed to post-detour \"%s\"", name); + return hSetup; + } +} + +public void OnPluginStart() +{ + GameDataWrapper gd = new GameDataWrapper("l4d_fix_rocket_jump"); + delete gd.CreateDetourOrFail("CGameMovement::SetGroundEntity", DTR_SetGroundEntity, DTR_SetGroundEntity_Post); + delete gd; +} + +// https://github.com/ValveSoftware/source-sdk-2013/blob/39f6dde8fbc238727c020d13b05ecadd31bda4c0/src/game/shared/gamemovement.cpp#L3611 +static bool g_bRestore[MAXPLAYERS+1]; +static float g_vecSavedBaseVel[MAXPLAYERS+1][3]; +MRESReturn DTR_SetGroundEntity(DHookParam hParams) +{ + int client = hParams.GetObjectVar(1, 4, ObjectValueType_CBaseEntityPtr); + + int oldground = GetEntPropEnt(client, Prop_Send, "m_hGroundEntity"); + int newground = !hParams.IsNull(2) ? hParams.GetObjectVar(2, 76, ObjectValueType_CBaseEntityPtr) : -1; + + g_bRestore[client] = false; + + if ((oldground == -1 && newground != -1) || (oldground != -1 && newground == -1)) + { + g_bRestore[client] = !PassStandableGround(client, newground == -1 ? oldground : newground); + } + + if (g_bRestore[client]) + { + GetEntPropVector(client, Prop_Data, "m_vecBaseVelocity", g_vecSavedBaseVel[client]); + } + + return MRES_Ignored; +} + +MRESReturn DTR_SetGroundEntity_Post(DHookParam hParams) +{ + int client = hParams.GetObjectVar(1, 4, ObjectValueType_CBaseEntityPtr); + + if (g_bRestore[client]) + { + SetEntPropVector(client, Prop_Data, "m_vecBaseVelocity", g_vecSavedBaseVel[client]); + } + + return MRES_Ignored; +} + +bool PassStandableGround(int client, int entity) +{ + if (entity > MaxClients) + { + char cls[64]; + GetEntityClassname(entity, cls, sizeof(cls)); + + if (!strcmp(cls, "witch") || !strcmp(cls, "infected")) + return false; + + if (StrContains(cls, "_projectile") != -1) + return false; + } + else if (entity > 0) + { + if (GetClientTeam(client) == 2 && GetClientTeam(entity) == 3) + return false; + } + + return true; +} + +// Reverse bot's aim pitch for solo testing GL jump with "bot_mimic" on. +/* +#include + +methodmap CUserCmd +{ + property float viewangles_x { + public get() { return LoadFromAddress(view_as
(this) + view_as
(12), NumberType_Int32); } + public set(float x) { StoreToAddress(view_as
(this) + view_as
(12), x, NumberType_Int32); } + } +} + +int g_iRestoreMimic = -1; +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]) +{ + static ConVar bot_mimic = null; + if (bot_mimic == null) + bot_mimic = FindConVar("bot_mimic"); + + if (!IsClientInGame(client) || !IsFakeClient(client)) + return Plugin_Continue; + + int player = bot_mimic.IntValue; + if (player <= 0 || player > MaxClients || !IsClientInGame(player)) + return Plugin_Continue; + + g_iRestoreMimic = player; + GetPlayerLastCommand(player).viewangles_x = -GetPlayerLastCommand(player).viewangles_x; + return Plugin_Continue; +} + +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]) +{ + if (g_iRestoreMimic != -1) + { + GetPlayerLastCommand(g_iRestoreMimic).viewangles_x = -GetPlayerLastCommand(g_iRestoreMimic).viewangles_x; + g_iRestoreMimic = -1; + } +} + +CUserCmd GetPlayerLastCommand(int player) +{ + static int s_iOffs_m_LastCmd = -1; + if (s_iOffs_m_LastCmd == -1) + s_iOffs_m_LastCmd = FindDataMapInfo(player, "m_hViewModel") + + 4*2; // CHandle * MAX_VIEWMODELS + + return view_as(GetEntityAddress(player) + view_as
(s_iOffs_m_LastCmd)); +} +*/ \ No newline at end of file diff --git a/cfg/generalfixes.cfg b/cfg/generalfixes.cfg index db039efac..0066a519e 100644 --- a/cfg/generalfixes.cfg +++ b/cfg/generalfixes.cfg @@ -49,7 +49,7 @@ sm plugins load fixes/annoyance_exploit_fixes.smx sm plugins load fixes/l4d_fix_shove_duration.smx sm plugins load fixes/l4d2_jockey_hitbox_fix.smx sm plugins load fixes/l4d_consistent_escaperoute.smx -sm plugins load fixes/l4d2_fix_rocketjump.smx +sm plugins load fixes/l4d_fix_rocket_jump.smx sm plugins load fixes/l4d2_charge_target_fix.smx sm plugins load fixes/l4d2_shove_fix.smx sm plugins load fixes/l4d2_scripted_tank_stage_fix.smx