From 8d31466fc5fa7999358841b85e1ce36bbeb26e0d Mon Sep 17 00:00:00 2001 From: FutureRave Date: Wed, 4 May 2022 12:44:45 +0100 Subject: [PATCH 01/13] [Script] GScr_IsArray --- src/Components/Modules/ClientCommand.cpp | 2 +- src/Components/Modules/Download.cpp | 4 +- src/Components/Modules/Script.cpp | 26 +++---- src/Components/Modules/ScriptExtension.cpp | 34 ++++++++-- src/Game/Functions.cpp | 1 + src/Game/Functions.hpp | 5 +- src/Game/Structs.hpp | 79 ++++++++++++++++------ 7 files changed, 108 insertions(+), 43 deletions(-) diff --git a/src/Components/Modules/ClientCommand.cpp b/src/Components/Modules/ClientCommand.cpp index 060fb81f..7d8436da 100644 --- a/src/Components/Modules/ClientCommand.cpp +++ b/src/Components/Modules/ClientCommand.cpp @@ -354,7 +354,7 @@ namespace Components } }); - Script::AddFunction("DropAllBots", []() // gsc: DropAllBots(); + Script::AddFunction("DropAllBots", [] // gsc: DropAllBots(); { Game::SV_DropAllBots(); }); diff --git a/src/Components/Modules/Download.cpp b/src/Components/Modules/Download.cpp index c9d875da..5865d569 100644 --- a/src/Components/Modules/Download.cpp +++ b/src/Components/Modules/Download.cpp @@ -964,7 +964,7 @@ namespace Components Download::ScriptDownloads.clear(); }); - Script::AddFunction("HttpGet", []() + Script::AddFunction("HttpGet", [] { if (!Flags::HasFlag("scriptablehttp")) return; @@ -985,7 +985,7 @@ namespace Components Game::RemoveRefToObject(object); }); - Script::AddFunction("HttpCancel", []() + Script::AddFunction("HttpCancel", [] { if (!Flags::HasFlag("scriptablehttp")) return; diff --git a/src/Components/Modules/Script.cpp b/src/Components/Modules/Script.cpp index 798a2541..cb4dc4e9 100644 --- a/src/Components/Modules/Script.cpp +++ b/src/Components/Modules/Script.cpp @@ -431,7 +431,7 @@ namespace Components { std::memmove(&Game::scrVmPub->top[-4], &Game::scrVmPub->top[-5], sizeof(Game::VariableValue) * 6); Game::scrVmPub->top += 1; - Game::scrVmPub->top[-6].type = Game::VAR_FLOAT; + Game::scrVmPub->top[-6].type = Game::scrParamType_t::VAR_FLOAT; Game::scrVmPub->top[-6].u.floatValue = 0.0f; ++Game::scrVmPub->outparamcount; @@ -450,7 +450,7 @@ namespace Components const auto value = &Game::scrVmPub->top[-index]; - if (value->type != Game::VAR_FUNCTION) + if (value->type != Game::scrParamType_t::VAR_FUNCTION) { Game::Scr_ParamError(static_cast(index), "^1GetCodePosForParam: Expects a function as parameter!\n"); return ""; @@ -549,7 +549,7 @@ namespace Components void Script::AddFunctions() { - Script::AddFunction("ReplaceFunc", []() // gsc: ReplaceFunc(, ) + Script::AddFunction("ReplaceFunc", [] // gsc: ReplaceFunc(, ) { if (Game::Scr_GetNumParam() != 2u) { @@ -564,7 +564,7 @@ namespace Components }); // System time - Script::AddFunction("GetSystemTime", []() // gsc: GetSystemTime() + Script::AddFunction("GetSystemTime", [] // gsc: GetSystemTime() { SYSTEMTIME time; GetSystemTime(&time); @@ -572,7 +572,7 @@ namespace Components Game::Scr_AddInt(time.wSecond); }); - Script::AddFunction("GetSystemMilliseconds", []() // gsc: GetSystemMilliseconds() + Script::AddFunction("GetSystemMilliseconds", [] // gsc: GetSystemMilliseconds() { SYSTEMTIME time; GetSystemTime(&time); @@ -581,7 +581,7 @@ namespace Components }); // Executes command to the console - Script::AddFunction("Exec", []() // gsc: Exec() + Script::AddFunction("Exec", [] // gsc: Exec() { const auto str = Game::Scr_GetString(0); @@ -595,7 +595,7 @@ namespace Components }); // Allow printing to the console even when developer is 0 - Script::AddFunction("PrintConsole", []() // gsc: PrintConsole() + Script::AddFunction("PrintConsole", [] // gsc: PrintConsole() { for (auto i = 0u; i < Game::Scr_GetNumParam(); i++) { @@ -612,7 +612,7 @@ namespace Components }); // Script Storage Functions - Script::AddFunction("StorageSet", []() // gsc: StorageSet(, ); + Script::AddFunction("StorageSet", [] // gsc: StorageSet(, ); { const auto* key = Game::Scr_GetString(0); const auto* value = Game::Scr_GetString(1); @@ -626,7 +626,7 @@ namespace Components Script::ScriptStorage.insert_or_assign(key, value); }); - Script::AddFunction("StorageRemove", []() // gsc: StorageRemove(); + Script::AddFunction("StorageRemove", [] // gsc: StorageRemove(); { const auto* key = Game::Scr_GetString(0); @@ -645,7 +645,7 @@ namespace Components Script::ScriptStorage.erase(key); }); - Script::AddFunction("StorageGet", []() // gsc: StorageGet(); + Script::AddFunction("StorageGet", [] // gsc: StorageGet(); { const auto* key = Game::Scr_GetString(0); @@ -665,7 +665,7 @@ namespace Components Game::Scr_AddString(data.data()); }); - Script::AddFunction("StorageHas", []() // gsc: StorageHas(); + Script::AddFunction("StorageHas", [] // gsc: StorageHas(); { const auto* key = Game::Scr_GetString(0); @@ -678,7 +678,7 @@ namespace Components Game::Scr_AddBool(static_cast(Script::ScriptStorage.count(key))); // Until C++17 }); - Script::AddFunction("StorageClear", []() // gsc: StorageClear(); + Script::AddFunction("StorageClear", [] // gsc: StorageClear(); { Script::ScriptStorage.clear(); }); @@ -746,7 +746,7 @@ namespace Components }); #ifdef _DEBUG - Script::AddFunction("DebugBox", []() + Script::AddFunction("DebugBox", [] { const auto* message = Game::Scr_GetString(0); diff --git a/src/Components/Modules/ScriptExtension.cpp b/src/Components/Modules/ScriptExtension.cpp index 68e80a7a..66e166de 100644 --- a/src/Components/Modules/ScriptExtension.cpp +++ b/src/Components/Modules/ScriptExtension.cpp @@ -116,7 +116,7 @@ namespace Components void ScriptExtension::AddFunctions() { // File functions - Script::AddFunction("FileWrite", []() // gsc: FileWrite(, , ) + Script::AddFunction("FileWrite", [] // gsc: FileWrite(, , ) { const auto* path = Game::Scr_GetString(0); auto* text = Game::Scr_GetString(1); @@ -159,7 +159,7 @@ namespace Components } }); - Script::AddFunction("FileRead", []() // gsc: FileRead() + Script::AddFunction("FileRead", [] // gsc: FileRead() { const auto* path = Game::Scr_GetString(0); @@ -187,7 +187,7 @@ namespace Components Game::Scr_AddString(FileSystem::FileReader(path).getBuffer().data()); }); - Script::AddFunction("FileExists", []() // gsc: FileExists() + Script::AddFunction("FileExists", [] // gsc: FileExists() { const auto* path = Game::Scr_GetString(0); @@ -209,7 +209,7 @@ namespace Components Game::Scr_AddInt(FileSystem::FileReader(path).exists()); }); - Script::AddFunction("FileRemove", []() // gsc: FileRemove() + Script::AddFunction("FileRemove", [] // gsc: FileRemove() { const auto* path = Game::Scr_GetString(0); @@ -235,7 +235,7 @@ namespace Components }); // Misc functions - Script::AddFunction("ToUpper", []() // gsc: ToUpper() + Script::AddFunction("ToUpper", [] // gsc: ToUpper() { const auto scriptValue = Game::Scr_GetConstString(0); const auto* string = Game::SL_ConvertToString(scriptValue); @@ -280,7 +280,7 @@ namespace Components }); // Func present on IW5 - Script::AddFunction("StrICmp", []() // gsc: StrICmp(, ) + Script::AddFunction("StrICmp", [] // gsc: StrICmp(, ) { const auto value1 = Game::Scr_GetConstString(0); const auto value2 = Game::Scr_GetConstString(1); @@ -292,7 +292,7 @@ namespace Components }); // Func present on IW5 - Script::AddFunction("IsEndStr", []() // gsc: IsEndStr(, ) + Script::AddFunction("IsEndStr", [] // gsc: IsEndStr(, ) { const auto* s1 = Game::Scr_GetString(0); const auto* s2 = Game::Scr_GetString(1); @@ -305,6 +305,26 @@ namespace Components Game::Scr_AddBool(Utils::String::EndsWith(s1, s2)); }); + + Script::AddFunction("IsArray", [] + { + const auto type = Game::Scr_GetType(0); + + bool result; + if (type == Game::scrParamType_t::VAR_POINTER) + { + const auto ptr_type = Game::Scr_GetPointerType(0); + assert(ptr_type >= Game::FIRST_OBJECT); + result = (ptr_type == Game::scrParamType_t::VAR_ARRAY); + } + else + { + assert(type < Game::FIRST_OBJECT); + result = false; + } + + Game::Scr_AddBool(result); + }); } void ScriptExtension::AddMethods() diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 5fb7505a..4dab19e6 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -293,6 +293,7 @@ namespace Game Scr_ParamError_t Scr_ParamError = Scr_ParamError_t(0x4FBC70); Scr_GetType_t Scr_GetType = Scr_GetType_t(0x422900); + Scr_GetPointerType_t Scr_GetPointerType = Scr_GetPointerType_t(0x4828E0); Scr_ClearOutParams_t Scr_ClearOutParams = Scr_ClearOutParams_t(0x4386E0); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 4369bbad..a03f0c85 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -735,9 +735,12 @@ namespace Game typedef bool(__cdecl * Scr_IsSystemActive_t)(); extern Scr_IsSystemActive_t Scr_IsSystemActive; - typedef int(__cdecl * Scr_GetType_t)(unsigned int); + typedef int(__cdecl * Scr_GetType_t)(unsigned int index); extern Scr_GetType_t Scr_GetType; + typedef int(__cdecl * Scr_GetPointerType_t)(unsigned int index); + extern Scr_GetPointerType_t Scr_GetPointerType; + typedef void(__cdecl * Scr_Error_t)(const char*); extern Scr_Error_t Scr_Error; diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index e0eb5dcc..f30a607d 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -234,7 +234,7 @@ namespace Game CS_ACTIVE = 0x5, } clientstate_t; - typedef enum + enum errorParm_t { ERR_FATAL = 0x0, ERR_DROP = 0x1, @@ -244,7 +244,39 @@ namespace Game ERR_SCRIPT_DROP = 0x5, ERR_LOCALIZATION = 0x6, ERR_MAPLOADERRORSUMMARY = 0x7 - } errorParm_t; + }; + + enum conChannel_t + { + CON_CHANNEL_DONT_FILTER, + CON_CHANNEL_ERROR, + CON_CHANNEL_GAMENOTIFY, + CON_CHANNEL_BOLDGAME, + CON_CHANNEL_SUBTITLE, + CON_CHANNEL_OBITUARY, + CON_CHANNEL_LOGFILEONLY, + CON_CHANNEL_CONSOLEONLY, + CON_CHANNEL_GFX, + CON_CHANNEL_SOUND, + CON_CHANNEL_FILES, + CON_CHANNEL_DEVGUI, + CON_CHANNEL_PROFILE, + CON_CHANNEL_UI, + CON_CHANNEL_CLIENT, + CON_CHANNEL_SERVER, + CON_CHANNEL_SYSTEM, + CON_CHANNEL_PLAYERWEAP, + CON_CHANNEL_AI, + CON_CHANNEL_ANIM, + CON_CHANNEL_PHYS, + CON_CHANNEL_FX, + CON_CHANNEL_LEADERBOARDS, + CON_CHANNEL_PARSERSCRIPT, + CON_CHANNEL_SCRIPT, + CON_CHANNEL_NETWORK, + + CON_BUILTIN_CHANNEL_COUNT, + }; enum entityFlag { @@ -5096,7 +5128,7 @@ namespace Game char buf[1]; }; - enum VariableType + enum scrParamType_t { VAR_UNDEFINED = 0x0, VAR_BEGIN_REF = 0x1, @@ -5114,21 +5146,30 @@ namespace Game VAR_BUILTIN_METHOD = 0xB, VAR_STACK = 0xC, VAR_ANIMATION = 0xD, - VAR_PRE_ANIMATION = 0xE, - VAR_THREAD = 0xF, - VAR_NOTIFY_THREAD = 0x10, - VAR_TIME_THREAD = 0x11, - VAR_CHILD_THREAD = 0x12, - VAR_OBJECT = 0x13, - VAR_DEAD_ENTITY = 0x14, - VAR_ENTITY = 0x15, - VAR_ARRAY = 0x16, - VAR_DEAD_THREAD = 0x17, - VAR_COUNT = 0x18, - VAR_FREE = 0x18, - VAR_THREAD_LIST = 0x19, - VAR_ENDON_LIST = 0x1A, - VAR_TOTAL_COUNT = 0x1B, + VAR_DEVELOPER_CODEPOS = 0xE, + VAR_PRE_ANIMATION = 0xF, + VAR_THREAD = 0x10, + VAR_NOTIFY_THREAD = 0x11, + VAR_TIME_THREAD = 0x12, + VAR_CHILD_THREAD = 0x13, + VAR_OBJECT = 0x14, + VAR_DEAD_ENTITY = 0x15, + VAR_ENTITY = 0x16, + VAR_ARRAY = 0x17, + VAR_DEAD_THREAD = 0x18, + VAR_COUNT = 0x19, + VAR_THREAD_LIST = 0x1A, + VAR_ENDON_LIST = 0x1B, + }; + + enum $2441F0C7E439C64E6C27842ECB570A7C + { + FIRST_OBJECT = 0x10, + FIRST_CLEARABLE_OBJECT = 0x14, + LAST_NONENTITY_OBJECT = 0x14, + FIRST_ENTITY_OBJECT = 0x16, + FIRST_NONFIELD_OBJECT = 0x17, + FIRST_DEAD_OBJECT = 0x18, }; union VariableUnion @@ -5147,7 +5188,7 @@ namespace Game struct VariableValue { VariableUnion u; - VariableType type; + scrParamType_t type; }; struct function_stack_t From bf0ea14fdee8761894599aab059fe9db73b1c43e Mon Sep 17 00:00:00 2001 From: FutureRave Date: Wed, 4 May 2022 12:49:03 +0100 Subject: [PATCH 02/13] [General] Update changelog --- CHANGELOG.md | 2 ++ src/Components/Modules/ScriptExtension.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 725f82b6..4c277f8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,9 @@ The format is based on [Keep a Changelog v0.3.0](http://keepachangelog.com/en/0. ### Changed - Test clients' native functionality has been restored by default (#162) +- Renamed GSC method `isBot` to `IsTestClient` (#162) - Custom GSC functions can be called correctly from a game script (#216) +- GSC functions `HttpCancel` and `HttpCancel` require the game to be launched with the command line argument `scriptablehttp` (#162) - Master server list will be used instead of the node system (load server list faster) (#234) ### Fixed diff --git a/src/Components/Modules/ScriptExtension.cpp b/src/Components/Modules/ScriptExtension.cpp index 66e166de..31b55ae1 100644 --- a/src/Components/Modules/ScriptExtension.cpp +++ b/src/Components/Modules/ScriptExtension.cpp @@ -306,7 +306,7 @@ namespace Components Game::Scr_AddBool(Utils::String::EndsWith(s1, s2)); }); - Script::AddFunction("IsArray", [] + Script::AddFunction("IsArray", [] // gsc: IsArray() { const auto type = Game::Scr_GetType(0); From 378ef7ec6008af7e09caeb5c225a0107e6a973ae Mon Sep 17 00:00:00 2001 From: Jan Date: Wed, 4 May 2022 17:47:50 +0200 Subject: [PATCH 03/13] Update gamepad patch dvar flags --- src/Components/Modules/Gamepad.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Components/Modules/Gamepad.cpp b/src/Components/Modules/Gamepad.cpp index ca170379..a511feea 100644 --- a/src/Components/Modules/Gamepad.cpp +++ b/src/Components/Modules/Gamepad.cpp @@ -1711,8 +1711,8 @@ namespace Components { gpad_enabled = Dvar::Register("gpad_enabled", false, Game::DVAR_ARCHIVE, "Game pad enabled"); gpad_debug = Dvar::Register("gpad_debug", false, Game::DVAR_NONE, "Game pad debugging"); - gpad_present = Dvar::Register("gpad_present", false, Game::DVAR_NONE, "Game pad present"); - gpad_in_use = Dvar::Register("gpad_in_use", false, Game::DVAR_NONE, "A game pad is in use"); + gpad_present = Dvar::Register("gpad_present", false, Game::DVAR_READONLY, "Game pad present"); + gpad_in_use = Dvar::Register("gpad_in_use", false, Game::DVAR_READONLY, "A game pad is in use"); gpad_style = Dvar::Register("gpad_style", false, Game::DVAR_ARCHIVE, "Switch between Xbox and PS HUD"); gpad_sticksConfig = Dvar::Register("gpad_sticksConfig", "", Game::DVAR_ARCHIVE, "Game pad stick configuration"); gpad_buttonConfig = Dvar::Register("gpad_buttonConfig", "", Game::DVAR_ARCHIVE, "Game pad button configuration"); @@ -1720,15 +1720,15 @@ namespace Components gpad_menu_scroll_delay_rest = Dvar::Register("gpad_menu_scroll_delay_rest", 210, 0, 1000, Game::DVAR_ARCHIVE, "Menu scroll key-repeat delay, for repeats after the first, in milliseconds"); gpad_rumble = Dvar::Register("gpad_rumble", true, Game::DVAR_ARCHIVE, "Enable game pad rumble"); - gpad_stick_pressed_hysteresis = Dvar::Register("gpad_stick_pressed_hysteresis", 0.1f, 0.0f, 1.0f, Game::DVAR_NONE, + gpad_stick_pressed_hysteresis = Dvar::Register("gpad_stick_pressed_hysteresis", 0.1f, 0.0f, 1.0f, Game::DVAR_ARCHIVE, "Game pad stick pressed no-change-zone around gpad_stick_pressed to prevent bouncing"); - gpad_stick_pressed = Dvar::Register("gpad_stick_pressed", 0.4f, 0.0, 1.0, Game::DVAR_NONE, "Game pad stick pressed threshhold"); - gpad_stick_deadzone_max = Dvar::Register("gpad_stick_deadzone_max", 0.01f, 0.0f, 1.0f, Game::DVAR_NONE, "Game pad maximum stick deadzone"); - gpad_stick_deadzone_min = Dvar::Register("gpad_stick_deadzone_min", 0.2f, 0.0f, 1.0f, Game::DVAR_NONE, "Game pad minimum stick deadzone"); - gpad_button_deadzone = Dvar::Register("gpad_button_deadzone", 0.13f, 0.0f, 1.0f, Game::DVAR_NONE, "Game pad button deadzone threshhold"); - gpad_button_lstick_deflect_max = Dvar::Register("gpad_button_lstick_deflect_max", 1.0f, 0.0f, 1.0f, Game::DVAR_NONE, "Game pad maximum pad stick pressed value"); - gpad_button_rstick_deflect_max = Dvar::Register("gpad_button_rstick_deflect_max", 1.0f, 0.0f, 1.0f, Game::DVAR_NONE, "Game pad maximum pad stick pressed value"); - gpad_use_hold_time = Dvar::Register("gpad_use_hold_time", 250, 0, std::numeric_limits::max(), Game::DVAR_NONE, "Time to hold the 'use' button on gamepads to activate use"); + gpad_stick_pressed = Dvar::Register("gpad_stick_pressed", 0.4f, 0.0, 1.0, Game::DVAR_ARCHIVE, "Game pad stick pressed threshhold"); + gpad_stick_deadzone_max = Dvar::Register("gpad_stick_deadzone_max", 0.01f, 0.0f, 1.0f, Game::DVAR_ARCHIVE, "Game pad maximum stick deadzone"); + gpad_stick_deadzone_min = Dvar::Register("gpad_stick_deadzone_min", 0.2f, 0.0f, 1.0f, Game::DVAR_ARCHIVE, "Game pad minimum stick deadzone"); + gpad_button_deadzone = Dvar::Register("gpad_button_deadzone", 0.13f, 0.0f, 1.0f, Game::DVAR_ARCHIVE, "Game pad button deadzone threshhold"); + gpad_button_lstick_deflect_max = Dvar::Register("gpad_button_lstick_deflect_max", 1.0f, 0.0f, 1.0f, Game::DVAR_ARCHIVE, "Game pad maximum pad stick pressed value"); + gpad_button_rstick_deflect_max = Dvar::Register("gpad_button_rstick_deflect_max", 1.0f, 0.0f, 1.0f, Game::DVAR_ARCHIVE, "Game pad maximum pad stick pressed value"); + gpad_use_hold_time = Dvar::Register("gpad_use_hold_time", 250, 0, std::numeric_limits::max(), Game::DVAR_ARCHIVE, "Time to hold the 'use' button on gamepads to activate use"); gpad_lockon_enabled = Dvar::Register("gpad_lockon_enabled", true, Game::DVAR_ARCHIVE, "Game pad lockon aim assist enabled"); gpad_slowdown_enabled = Dvar::Register("gpad_slowdown_enabled", true, Game::DVAR_ARCHIVE, "Game pad slowdown aim assist enabled"); From 4af77130df2bf18d12eda1392f4589ca8233339d Mon Sep 17 00:00:00 2001 From: Jan Date: Wed, 4 May 2022 20:15:17 +0200 Subject: [PATCH 04/13] Fix RawMouse patch making gamepad mouse move hook not getting called --- src/Components/Modules/Gamepad.cpp | 7 ++++++- src/Components/Modules/Gamepad.hpp | 2 ++ src/Components/Modules/RawMouse.cpp | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Components/Modules/Gamepad.cpp b/src/Components/Modules/Gamepad.cpp index a511feea..250a5d85 100644 --- a/src/Components/Modules/Gamepad.cpp +++ b/src/Components/Modules/Gamepad.cpp @@ -1833,13 +1833,18 @@ namespace Components return gamePads[0].inUse; } - int Gamepad::CL_MouseEvent_Hk(const int x, const int y, const int dx, const int dy) + void Gamepad::OnMouseMove(const int x, const int y, const int dx, const int dy) { if (dx != 0 || dy != 0) { gamePads[0].inUse = false; gpad_in_use.setRaw(false); } + } + + int Gamepad::CL_MouseEvent_Hk(const int x, const int y, const int dx, const int dy) + { + OnMouseMove(x, y, dx, dy); // Call original function return Utils::Hook::Call(0x4D7C50)(x, y, dx, dy); diff --git a/src/Components/Modules/Gamepad.hpp b/src/Components/Modules/Gamepad.hpp index 024d0c6a..a09a4ec6 100644 --- a/src/Components/Modules/Gamepad.hpp +++ b/src/Components/Modules/Gamepad.hpp @@ -41,6 +41,8 @@ namespace Components public: Gamepad(); + static void OnMouseMove(int x, int y, int dx, int dy); + private: static Game::ButtonToCodeMap_t buttonList[]; static Game::StickToCodeMap_t analogStickList[4]; diff --git a/src/Components/Modules/RawMouse.cpp b/src/Components/Modules/RawMouse.cpp index 3f95a874..51cba280 100644 --- a/src/Components/Modules/RawMouse.cpp +++ b/src/Components/Modules/RawMouse.cpp @@ -97,6 +97,7 @@ namespace Components Game::s_wmv->oldPos = curPos; ScreenToClient(Window::GetWindow(), &curPos); + Gamepad::OnMouseMove(curPos.x, curPos.y, dx, dy); auto recenterMouse = Game::CL_MouseEvent(curPos.x, curPos.y, dx, dy); if (recenterMouse) From 20d17a3dec95cce2c8ac48a5a22122eb721ad56f Mon Sep 17 00:00:00 2001 From: Jan Date: Wed, 4 May 2022 20:29:02 +0200 Subject: [PATCH 05/13] Mark Gamepad OnMouseMove parameters as maybe unused --- src/Components/Modules/Gamepad.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Modules/Gamepad.cpp b/src/Components/Modules/Gamepad.cpp index 250a5d85..364021c8 100644 --- a/src/Components/Modules/Gamepad.cpp +++ b/src/Components/Modules/Gamepad.cpp @@ -1833,7 +1833,7 @@ namespace Components return gamePads[0].inUse; } - void Gamepad::OnMouseMove(const int x, const int y, const int dx, const int dy) + void Gamepad::OnMouseMove([[maybe_unused]] const int x, [[maybe_unused]] const int y, const int dx, const int dy) { if (dx != 0 || dy != 0) { From 9685dccdcddec1d405ce74052a124e9b30830ada Mon Sep 17 00:00:00 2001 From: FutureRave Date: Thu, 5 May 2022 10:20:10 +0100 Subject: [PATCH 06/13] Clarify some things in the elevators patch --- src/Components/Modules/Elevators.cpp | 21 ++++++++++----------- src/Game/Functions.cpp | 4 ++-- src/Game/Functions.hpp | 8 ++++---- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/Components/Modules/Elevators.cpp b/src/Components/Modules/Elevators.cpp index 08dffeb7..6507f1f2 100644 --- a/src/Components/Modules/Elevators.cpp +++ b/src/Components/Modules/Elevators.cpp @@ -16,9 +16,9 @@ namespace Components const auto elevatorSetting = Elevators::BG_Elevators.get(); while (true) { - point[0] = ps->origin[0] + Game::CorrectSolidDeltas[i][0]; - point[1] = ps->origin[1] + Game::CorrectSolidDeltas[i][1]; - point[2] = ps->origin[2] + Game::CorrectSolidDeltas[i][2]; + point[0] = ps->origin[0] + (*Game::CorrectSolidDeltas)[i][0]; + point[1] = ps->origin[1] + (*Game::CorrectSolidDeltas)[i][1]; + point[2] = ps->origin[2] + (*Game::CorrectSolidDeltas)[i][2]; Game::PM_playerTrace(pm, trace, point, point, &pm->bounds, ps->clientNum, pm->tracemask); @@ -40,8 +40,8 @@ namespace Components } } - i += 1; - if (i >= 26) + ++i; + if (i >= 26) // CorrectSolidDeltas count { ps->groundEntityNum = Game::ENTITYNUM_NONE; pml->groundPlane = 0; @@ -62,15 +62,15 @@ namespace Components return 1; } - void Elevators::PM_Trace_Hk(Game::pmove_s* pm, Game::trace_t* trace, const float* f3, - const float* f4, const Game::Bounds* bounds, int a6, int a7) + void Elevators::PM_Trace_Hk(Game::pmove_s* pm, Game::trace_t* results, const float* start, + const float* end, const Game::Bounds* bounds, int passEntityNum, int contentMask) { - Game::PM_Trace(pm, trace, f3, f4, bounds, a6, a7); + Game::PM_Trace(pm, results, start, end, bounds, passEntityNum, contentMask); // Allow the player to stand even when there is no headroom if (Elevators::BG_Elevators.get() == Elevators::EASY) { - trace->allsolid = false; + results->allsolid = false; } } @@ -111,8 +111,7 @@ namespace Components Elevators::ENABLED, Game::DVAR_CODINFO, "Elevators glitch settings"); }); - //Replace PM_CorrectAllSolid - Utils::Hook(0x57369E, Elevators::PM_CorrectAllSolidStub, HOOK_CALL).install()->quick(); + Utils::Hook(0x57369E, Elevators::PM_CorrectAllSolidStub, HOOK_CALL).install()->quick(); // PM_GroundTrace // Place hooks in PM_CheckDuck. If the elevators dvar is set to easy the // flags for duck/prone will always be removed from the player state diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 4dab19e6..3edcc68a 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -547,11 +547,11 @@ namespace Game FastCriticalSection* db_hashCritSect = reinterpret_cast(0x16B8A54); - vec3_t* CorrectSolidDeltas = reinterpret_cast(0x739BB8); // Count 26 + float (*CorrectSolidDeltas)[26][3] = reinterpret_cast(0x739BB8); // Count 26 level_locals_t* level = reinterpret_cast(0x1A831A8); - float(*penetrationDepthTable)[PENETRATE_TYPE_COUNT][SURF_TYPE_COUNT] = reinterpret_cast(0x7C4878); + float (*penetrationDepthTable)[PENETRATE_TYPE_COUNT][SURF_TYPE_COUNT] = reinterpret_cast(0x7C4878); WinMouseVars_t* s_wmv = reinterpret_cast(0x649D640); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index a03f0c85..e6840329 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -999,10 +999,10 @@ namespace Game typedef void(__cdecl * Jump_ClearState_t)(playerState_s* ps); extern Jump_ClearState_t Jump_ClearState; - typedef void(__cdecl * PM_playerTrace_t)(pmove_s*, trace_t*, const float*, const float*, const Bounds*, int, int); + typedef void(__cdecl * PM_playerTrace_t)(pmove_s* pm, trace_t* results, const float* start, const float* end, const Bounds* bounds, int passEntityNum, int contentMask); extern PM_playerTrace_t PM_playerTrace; - typedef void(__cdecl * PM_Trace_t)(pmove_s*, trace_t*, const float*, const float*, const Bounds*, int, int); + typedef void(__cdecl * PM_Trace_t)(pmove_s* pm, trace_t* results, const float* start, const float* end, const Bounds* bounds, int passEntityNum, int contentMask); extern PM_Trace_t PM_Trace; typedef EffectiveStance(__cdecl * PM_GetEffectiveStance_t)(const playerState_s* ps); @@ -1145,13 +1145,13 @@ namespace Game constexpr auto MAX_MODELS = 512; extern XModel** cached_models; - extern vec3_t* CorrectSolidDeltas; + extern float (*CorrectSolidDeltas)[26][3]; extern FastCriticalSection* db_hashCritSect; extern level_locals_t* level; - extern float(*penetrationDepthTable)[PENETRATE_TYPE_COUNT][SURF_TYPE_COUNT]; + extern float (*penetrationDepthTable)[PENETRATE_TYPE_COUNT][SURF_TYPE_COUNT]; extern WinMouseVars_t* s_wmv; From 41c652ed36a91641c2114a6362d653e1cc32c03c Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 5 May 2022 21:24:25 +0200 Subject: [PATCH 07/13] Fix not being able to assign gamepad keys in bind menu fields --- src/Components/Modules/Gamepad.cpp | 36 ++++++++++++++++++++++++++---- src/Components/Modules/Gamepad.hpp | 5 +++-- src/Game/Functions.cpp | 2 ++ src/Game/Functions.hpp | 2 ++ 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/Components/Modules/Gamepad.cpp b/src/Components/Modules/Gamepad.cpp index 364021c8..3cad580b 100644 --- a/src/Components/Modules/Gamepad.cpp +++ b/src/Components/Modules/Gamepad.cpp @@ -1033,6 +1033,13 @@ namespace Components void Gamepad::UI_GamepadKeyEvent(const int gamePadIndex, const int key, const bool down) { + // If we are currently capturing a key for menu bind inputs then do not map keys and pass to game + if (*Game::g_waitingForKey) + { + Game::UI_KeyEvent(gamePadIndex, key, down); + return; + } + for (const auto& mapping : controllerMenuKeyMappings) { if (mapping.controllerKey == key) @@ -1777,19 +1784,19 @@ namespace Components return command; } - int Gamepad::Key_GetCommandAssignmentInternal_Hk(const char* cmd, int (*keys)[2]) + int Gamepad::Key_GetCommandAssignmentInternal([[maybe_unused]] int localClientNum, const char* cmd, int (*keys)[2]) { auto keyCount = 0; if (gamePads[0].inUse) { - cmd = GetGamePadCommand(cmd); + const auto gamePadCmd = GetGamePadCommand(cmd); for (auto keyNum = 0; keyNum < Game::K_LAST_KEY; keyNum++) { if (!Key_IsValidGamePadChar(keyNum)) continue; - if (Game::playerKeys[0].keys[keyNum].binding && strcmp(Game::playerKeys[0].keys[keyNum].binding, cmd) == 0) + if (Game::playerKeys[0].keys[keyNum].binding && strcmp(Game::playerKeys[0].keys[keyNum].binding, gamePadCmd) == 0) { (*keys)[keyCount++] = keyNum; @@ -1818,6 +1825,27 @@ namespace Components return keyCount; } + void __declspec(naked) Gamepad::Key_GetCommandAssignmentInternal_Stub() + { + __asm + { + push eax + pushad + + push [esp + 0x20 + 0x4 + 0x8] // keyNums + push [esp + 0x20 + 0x4 + 0x8] // command + push eax // localClientNum + call Key_GetCommandAssignmentInternal + add esp, 0xC + + mov[esp + 0x20], eax + + popad + pop eax + ret + } + } + void Gamepad::CL_KeyEvent_Hk(const int localClientNum, const int key, const int down, const unsigned time) { // A keyboard key has been pressed. Mark controller as unused. @@ -1954,7 +1982,7 @@ namespace Components Utils::Hook(0x48E527, UI_RefreshViewport_Hk, HOOK_CALL).install()->quick(); // Only return gamepad keys when gamepad enabled and only non gamepad keys when not - Utils::Hook(0x5A7A23, Key_GetCommandAssignmentInternal_Hk, HOOK_CALL).install()->quick(); + Utils::Hook(0x5A7890, Key_GetCommandAssignmentInternal_Stub, HOOK_JUMP).install()->quick(); // Add gamepad inputs to remote control (eg predator) handling Utils::Hook(0x5A6D4E, CL_RemoteControlMove_Stub, HOOK_CALL).install()->quick(); diff --git a/src/Components/Modules/Gamepad.hpp b/src/Components/Modules/Gamepad.hpp index a09a4ec6..36c969e9 100644 --- a/src/Components/Modules/Gamepad.hpp +++ b/src/Components/Modules/Gamepad.hpp @@ -192,8 +192,9 @@ namespace Components static void CG_RegisterDvars_Hk(); static const char* GetGamePadCommand(const char* command); - static int Key_GetCommandAssignmentInternal_Hk(const char* cmd, int(*keys)[2]); - static bool IsGamePadInUse(); + static int Key_GetCommandAssignmentInternal(int localClientNum, const char* cmd, int (*keys)[2]); + static void Key_GetCommandAssignmentInternal_Stub(); + static bool IsGamePadInUse(); static void CL_KeyEvent_Hk(int localClientNum, int key, int down, unsigned int time); static int CL_MouseEvent_Hk(int x, int y, int dx, int dy); static bool UI_RefreshViewport_Hk(); diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 4dab19e6..f617cb4e 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -558,6 +558,8 @@ namespace Game int* window_center_x = reinterpret_cast(0x649D638); int* window_center_y = reinterpret_cast(0x649D630); + int* g_waitingForKey = reinterpret_cast(0x63A50FC); + void Sys_LockRead(FastCriticalSection* critSect) { InterlockedIncrement(&critSect->readCount); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index a03f0c85..48f02c0a 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -1158,6 +1158,8 @@ namespace Game extern int* window_center_x; extern int* window_center_y; + extern int* g_waitingForKey; + void Sys_LockRead(FastCriticalSection* critSect); void Sys_UnlockRead(FastCriticalSection* critSect); From 13911fcb620754b514427fc72776d2dff508837d Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 5 May 2022 21:36:27 +0200 Subject: [PATCH 08/13] Whenever a gamepad button is rebound with a menu bind field, set the button config to custom so gamepad config shows a changed button layout --- src/Components/Modules/Gamepad.cpp | 13 +++++++++++++ src/Components/Modules/Gamepad.hpp | 1 + src/Game/Functions.cpp | 1 + src/Game/Functions.hpp | 3 +++ 4 files changed, 18 insertions(+) diff --git a/src/Components/Modules/Gamepad.cpp b/src/Components/Modules/Gamepad.cpp index 3cad580b..fa97f155 100644 --- a/src/Components/Modules/Gamepad.cpp +++ b/src/Components/Modules/Gamepad.cpp @@ -1846,6 +1846,14 @@ namespace Components } } + void Gamepad::Key_SetBinding_Hk(const int localClientNum, const int keyNum, const char* binding) + { + if(Key_IsValidGamePadChar(keyNum)) + gpad_buttonConfig.set("custom"); + + Game::Key_SetBinding(localClientNum, keyNum, binding); + } + void Gamepad::CL_KeyEvent_Hk(const int localClientNum, const int key, const int down, const unsigned time) { // A keyboard key has been pressed. Mark controller as unused. @@ -1984,6 +1992,11 @@ namespace Components // Only return gamepad keys when gamepad enabled and only non gamepad keys when not Utils::Hook(0x5A7890, Key_GetCommandAssignmentInternal_Stub, HOOK_JUMP).install()->quick(); + // Whenever a key binding for a gamepad key is replaced update the button config + Utils::Hook(0x47D473, Key_SetBinding_Hk, HOOK_CALL).install()->quick(); + Utils::Hook(0x47D485, Key_SetBinding_Hk, HOOK_CALL).install()->quick(); + Utils::Hook(0x47D49D, Key_SetBinding_Hk, HOOK_CALL).install()->quick(); + // Add gamepad inputs to remote control (eg predator) handling Utils::Hook(0x5A6D4E, CL_RemoteControlMove_Stub, HOOK_CALL).install()->quick(); diff --git a/src/Components/Modules/Gamepad.hpp b/src/Components/Modules/Gamepad.hpp index 36c969e9..f468dacd 100644 --- a/src/Components/Modules/Gamepad.hpp +++ b/src/Components/Modules/Gamepad.hpp @@ -194,6 +194,7 @@ namespace Components static const char* GetGamePadCommand(const char* command); static int Key_GetCommandAssignmentInternal(int localClientNum, const char* cmd, int (*keys)[2]); static void Key_GetCommandAssignmentInternal_Stub(); + static void Key_SetBinding_Hk(int localClientNum, int keyNum, const char* binding); static bool IsGamePadInUse(); static void CL_KeyEvent_Hk(int localClientNum, int key, int down, unsigned int time); static int CL_MouseEvent_Hk(int x, int y, int dx, int dy); diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index f617cb4e..343466db 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -171,6 +171,7 @@ namespace Game Key_SetCatcher_t Key_SetCatcher = Key_SetCatcher_t(0x43BD00); Key_RemoveCatcher_t Key_RemoveCatcher = Key_RemoveCatcher_t(0x408260); Key_IsKeyCatcherActive_t Key_IsKeyCatcherActive = Key_IsKeyCatcherActive_t(0x4DA010); + Key_SetBinding_t Key_SetBinding = Key_SetBinding_t(0x494C90); LargeLocalInit_t LargeLocalInit = LargeLocalInit_t(0x4A62A0); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 48f02c0a..da3ab84e 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -420,6 +420,9 @@ namespace Game typedef bool(__cdecl * Key_IsKeyCatcherActive_t)(int localClientNum, int catcher); extern Key_IsKeyCatcherActive_t Key_IsKeyCatcherActive; + typedef void(__cdecl * Key_SetBinding_t)(int localClientNum, int keyNum, const char* binding); + extern Key_SetBinding_t Key_SetBinding; + typedef void(__cdecl * LargeLocalInit_t)(); extern LargeLocalInit_t LargeLocalInit; From f9bfb0b8831df4aaa481fab9bf57b097eef24392 Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 5 May 2022 21:42:15 +0200 Subject: [PATCH 09/13] replace spaces with tabs in gamepad patch --- src/Components/Modules/Gamepad.cpp | 4 ++-- src/Components/Modules/Gamepad.hpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Components/Modules/Gamepad.cpp b/src/Components/Modules/Gamepad.cpp index fa97f155..0a4b8b89 100644 --- a/src/Components/Modules/Gamepad.cpp +++ b/src/Components/Modules/Gamepad.cpp @@ -1849,9 +1849,9 @@ namespace Components void Gamepad::Key_SetBinding_Hk(const int localClientNum, const int keyNum, const char* binding) { if(Key_IsValidGamePadChar(keyNum)) - gpad_buttonConfig.set("custom"); + gpad_buttonConfig.set("custom"); - Game::Key_SetBinding(localClientNum, keyNum, binding); + Game::Key_SetBinding(localClientNum, keyNum, binding); } void Gamepad::CL_KeyEvent_Hk(const int localClientNum, const int key, const int down, const unsigned time) diff --git a/src/Components/Modules/Gamepad.hpp b/src/Components/Modules/Gamepad.hpp index f468dacd..2e55c67d 100644 --- a/src/Components/Modules/Gamepad.hpp +++ b/src/Components/Modules/Gamepad.hpp @@ -193,9 +193,9 @@ namespace Components static const char* GetGamePadCommand(const char* command); static int Key_GetCommandAssignmentInternal(int localClientNum, const char* cmd, int (*keys)[2]); - static void Key_GetCommandAssignmentInternal_Stub(); - static void Key_SetBinding_Hk(int localClientNum, int keyNum, const char* binding); - static bool IsGamePadInUse(); + static void Key_GetCommandAssignmentInternal_Stub(); + static void Key_SetBinding_Hk(int localClientNum, int keyNum, const char* binding); + static bool IsGamePadInUse(); static void CL_KeyEvent_Hk(int localClientNum, int key, int down, unsigned int time); static int CL_MouseEvent_Hk(int x, int y, int dx, int dy); static bool UI_RefreshViewport_Hk(); From d75a5a71e58d8520fe5364ed5e71c0aaf7ba4a60 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Thu, 5 May 2022 23:48:33 +0100 Subject: [PATCH 10/13] [Bots] Add isBot GSC meth back --- src/Components/Modules/Bots.cpp | 21 +++++++++++++-------- src/Components/Modules/Bots.hpp | 1 + 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/Components/Modules/Bots.cpp b/src/Components/Modules/Bots.cpp index edccc68b..8c53ec2d 100644 --- a/src/Components/Modules/Bots.cpp +++ b/src/Components/Modules/Bots.cpp @@ -108,8 +108,19 @@ namespace Components } } + void Bots::GScr_isTestClient(Game::scr_entref_t entref) + { + const auto* ent = Game::GetPlayerEntity(entref); + const auto* client = Script::GetClient(ent); + + Game::Scr_AddBool(client->bIsTestClient == 1); + } + void Bots::AddMethods() { + Script::AddMethod("IsBot", Bots::GScr_isTestClient); // Usage: self IsBot(); + Script::AddMethod("IsTestClient", Bots::GScr_isTestClient); // Usage: self IsTestClient(); + Script::AddMethod("SetPing", [](Game::scr_entref_t entref) // gsc: self SetPing() { auto ping = Game::Scr_GetInt(0); @@ -128,14 +139,6 @@ namespace Components client->ping = static_cast(ping); }); - Script::AddMethod("IsTestClient", [](Game::scr_entref_t entref) // Usage: IsTestClient(); - { - const auto* gentity = Game::GetPlayerEntity(entref); - const auto* client = Script::GetClient(gentity); - - Game::Scr_AddBool(client->bIsTestClient == 1); - }); - Script::AddMethod("BotStop", [](Game::scr_entref_t entref) // Usage: BotStop(); { const auto* ent = Game::GetPlayerEntity(entref); @@ -327,6 +330,8 @@ namespace Components Bots::Bots() { + AssertOffset(Game::client_s, bIsTestClient, 0x41AF0); + // Replace connect string Utils::Hook::Set(0x48ADA6, "connect bot%d \"\\cg_predictItems\\1\\cl_anonymous\\0\\color\\4\\head\\default\\model\\multi\\snaps\\20\\rate\\5000\\name\\%s\\protocol\\%d\\checksum\\%d\\statver\\%d %u\\qport\\%d\""); diff --git a/src/Components/Modules/Bots.hpp b/src/Components/Modules/Bots.hpp index 910bacfa..8bf9045c 100644 --- a/src/Components/Modules/Bots.hpp +++ b/src/Components/Modules/Bots.hpp @@ -14,6 +14,7 @@ namespace Components static void Spawn(unsigned int count); + static void GScr_isTestClient(Game::scr_entref_t entref); static void AddMethods(); static void BotAiAction(Game::client_t* cl); From 849b890a96751dd2ed1f6b692dfe99f3a308b65c Mon Sep 17 00:00:00 2001 From: FutureRave Date: Sat, 7 May 2022 00:49:29 +0100 Subject: [PATCH 11/13] Get rid of direct checks of bistestclient --- src/Components/Modules/Bots.cpp | 43 +++++++++++++-------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/src/Components/Modules/Bots.cpp b/src/Components/Modules/Bots.cpp index 8c53ec2d..e89c73a2 100644 --- a/src/Components/Modules/Bots.cpp +++ b/src/Components/Modules/Bots.cpp @@ -111,9 +111,7 @@ namespace Components void Bots::GScr_isTestClient(Game::scr_entref_t entref) { const auto* ent = Game::GetPlayerEntity(entref); - const auto* client = Script::GetClient(ent); - - Game::Scr_AddBool(client->bIsTestClient == 1); + Game::Scr_AddBool(Game::SV_IsTestClient(ent->s.number) != 0); } void Bots::AddMethods() @@ -130,7 +128,7 @@ namespace Components const auto* ent = Game::GetPlayerEntity(entref); auto* client = Script::GetClient(ent); - if (!client->bIsTestClient) + if (Game::SV_IsTestClient(ent->s.number) == 0) { Game::Scr_Error("^1SetPing: Can only call on a bot!\n"); return; @@ -142,9 +140,8 @@ namespace Components Script::AddMethod("BotStop", [](Game::scr_entref_t entref) // Usage: BotStop(); { const auto* ent = Game::GetPlayerEntity(entref); - const auto* client = Script::GetClient(ent); - if (!client->bIsTestClient) + if (Game::SV_IsTestClient(ent->s.number) == 0) { Game::Scr_Error("^1BotStop: Can only call on a bot!\n"); return; @@ -157,17 +154,16 @@ namespace Components Script::AddMethod("BotWeapon", [](Game::scr_entref_t entref) // Usage: BotWeapon(); { - const auto* weapon = Game::Scr_GetString(0); - const auto* ent = Game::GetPlayerEntity(entref); - const auto* client = Script::GetClient(ent); - if (!client->bIsTestClient) + if (Game::SV_IsTestClient(ent->s.number) == 0) { Game::Scr_Error("^1BotWeapon: Can only call on a bot!\n"); return; } + const auto* weapon = Game::Scr_GetString(0); + if (weapon == nullptr || weapon[0] == '\0') { g_botai[entref.entnum].weapon = 1; @@ -181,6 +177,14 @@ namespace Components Script::AddMethod("BotAction", [](Game::scr_entref_t entref) // Usage: BotAction(); { + const auto* ent = Game::GetPlayerEntity(entref); + + if (Game::SV_IsTestClient(ent->s.number) == 0) + { + Game::Scr_Error("^1BotAction: Can only call on a bot!\n"); + return; + } + const auto* action = Game::Scr_GetString(0); if (action == nullptr) @@ -189,15 +193,6 @@ namespace Components return; } - const auto* ent = Game::GetPlayerEntity(entref); - const auto* client = Script::GetClient(ent); - - if (!client->bIsTestClient) - { - Game::Scr_Error("^1BotAction: Can only call on a bot!\n"); - return; - } - if (action[0] != '+' && action[0] != '-') { Game::Scr_ParamError(0, "^1BotAction: Sign for action must be '+' or '-'.\n"); @@ -223,20 +218,16 @@ namespace Components Script::AddMethod("BotMovement", [](Game::scr_entref_t entref) // Usage: BotMovement(, ); { - auto forwardInt = Game::Scr_GetInt(0); - auto rightInt = Game::Scr_GetInt(1); - const auto* ent = Game::GetPlayerEntity(entref); - const auto* client = Script::GetClient(ent); - if (!client->bIsTestClient) + if (Game::SV_IsTestClient(ent->s.number) == 0) { Game::Scr_Error("^1BotMovement: Can only call on a bot!\n"); return; } - forwardInt = std::clamp(forwardInt, std::numeric_limits::min(), std::numeric_limits::max()); - rightInt = std::clamp(rightInt, std::numeric_limits::min(), std::numeric_limits::max()); + const auto forwardInt = std::clamp(Game::Scr_GetInt(0), std::numeric_limits::min(), std::numeric_limits::max()); + const auto rightInt = std::clamp(Game::Scr_GetInt(1), std::numeric_limits::min(), std::numeric_limits::max()); g_botai[entref.entnum].forward = static_cast(forwardInt); g_botai[entref.entnum].right = static_cast(rightInt); From ae8580079f0874ee78c9ec906d90c01b4f3f002a Mon Sep 17 00:00:00 2001 From: FutureRave Date: Sat, 7 May 2022 01:17:15 +0100 Subject: [PATCH 12/13] Fix issue with get system milliseconds --- src/Components/Modules/Script.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Components/Modules/Script.cpp b/src/Components/Modules/Script.cpp index cb4dc4e9..dbe79ccc 100644 --- a/src/Components/Modules/Script.cpp +++ b/src/Components/Modules/Script.cpp @@ -564,14 +564,6 @@ namespace Components }); // System time - Script::AddFunction("GetSystemTime", [] // gsc: GetSystemTime() - { - SYSTEMTIME time; - GetSystemTime(&time); - - Game::Scr_AddInt(time.wSecond); - }); - Script::AddFunction("GetSystemMilliseconds", [] // gsc: GetSystemMilliseconds() { SYSTEMTIME time; From c0b2ca0813cdb20ca16f94efdc14235f0857a91d Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 7 May 2022 14:26:32 +0200 Subject: [PATCH 13/13] Fix knife charge not working anymore with gamepad patch enabled --- src/Components/Modules/Gamepad.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Components/Modules/Gamepad.cpp b/src/Components/Modules/Gamepad.cpp index 0a4b8b89..5a7a98b8 100644 --- a/src/Components/Modules/Gamepad.cpp +++ b/src/Components/Modules/Gamepad.cpp @@ -661,7 +661,8 @@ namespace Components Game::AimAssist_UpdateAdsLerp(input); AimAssist_ApplyTurnRates(input, output); - Game::AimAssist_ApplyAutoMelee(input, output); + // Automelee has already been done by keyboard so don't do it again + AimAssist_ApplyLockOn(input, output); } @@ -886,8 +887,6 @@ namespace Components AimAssist_UpdateGamePadInput(&aimInput, &aimOutput); clientActive.clViewangles[0] = aimOutput.pitch; clientActive.clViewangles[1] = aimOutput.yaw; - cmd->meleeChargeDist = aimOutput.meleeChargeDist; - cmd->meleeChargeYaw = aimOutput.meleeChargeYaw; } }