diff --git a/src/Components/Modules/Script.cpp b/src/Components/Modules/Script.cpp index c88b219c..5d10ca9c 100644 --- a/src/Components/Modules/Script.cpp +++ b/src/Components/Modules/Script.cpp @@ -388,20 +388,34 @@ namespace Components { if (Game::Scr_GetNumParam() == 6u) { - std::memmove(&Game::scriptContainer->stack[-4], &Game::scriptContainer->stack[-5], sizeof(Game::VariableValue) * 6); - Game::scriptContainer->stack += 1; - Game::scriptContainer->stack[-6].type = Game::VAR_FLOAT; - Game::scriptContainer->stack[-6].u.floatValue = 0; + 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].u.floatValue = 0; - ++Game::scriptContainer->numParam; + ++Game::scrVmPub->outparamcount; } return Game::Scr_GetNumParam(); } - const char* Script::GetCodePosForParam(int index) + const char* Script::GetCodePosForParam(unsigned int index) { - return Game::scriptContainer->stack[index].u.codePosValue; + if (index >= Game::scrVmPub->outparamcount) + { + Game::Scr_Error("^1GetCodePosForParam: Index is out of range!\n"); + return ""; + } + + const auto value = &Game::scrVmPub->top[0 - index]; + + if (value->type != Game::VAR_FUNCTION) + { + Game::Scr_Error("^1GetCodePosForParam: Expects a function as parameter!\n"); + return ""; + } + + return value->u.codePosValue; } void Script::GetReplacedPos(const char* pos) @@ -414,9 +428,15 @@ namespace Components void Script::SetReplacedPos(const char* what, const char* with) { + if (what[0] == '\0' || with[0] == '\0') + { + Logger::Print("Warning: Invalid paramters passed to ReplacedFunctions\n"); + return; + } + if (Script::ReplacedFunctions.find(what) != Script::ReplacedFunctions.end()) { - Logger::Print("Warning: a function was already detoured by a script\n"); + Logger::Print("Warning: ReplacedFunctions already contains codePosValue for a function\n"); } Script::ReplacedFunctions[what] = with; @@ -453,7 +473,7 @@ namespace Components pop ecx - push 0x061E944 + push 0x61E944 retn SetPos: @@ -499,7 +519,7 @@ namespace Components } const auto what = Script::GetCodePosForParam(0); - const auto with = Script::GetCodePosForParam(-1); + const auto with = Script::GetCodePosForParam(1); Script::SetReplacedPos(what, with); }); @@ -683,31 +703,10 @@ namespace Components Script::AddFunctions(); - // Script::AddFunction("playviewmodelfx", [](Game::scr_entref_t /*index*/) - // { - // /*auto Scr_Error = Utils::Hook::Call(0x42EF40); - // if (index >> 16) - // { - // Scr_Error("not an entity"); - // return; - // }*/ - - // // obtain FX name - // auto fxName = Game::Scr_GetString(0); - // auto fx = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_FX, fxName).fx; - - // auto tagName = Game::Scr_GetString(1); - // auto tagIndex = Game::SL_GetString(tagName, 0); - - // /*char boneIndex = -2; - // if (!Game::CG_GetBoneIndex(2048, tagIndex, &boneIndex)) - // { - // Scr_Error(Utils::String::VA("Unknown bone %s.\n", tagName)); - // return; - // }*/ - - // Game::CG_PlayBoltedEffect(0, fx, 2048, tagIndex); - // }); + Script::OnVMShutdown([] + { + Script::ReplacedFunctions.clear(); + }); } Script::~Script() diff --git a/src/Components/Modules/Script.hpp b/src/Components/Modules/Script.hpp index c9125831..5fb13727 100644 --- a/src/Components/Modules/Script.hpp +++ b/src/Components/Modules/Script.hpp @@ -72,7 +72,7 @@ namespace Components static unsigned int SetExpFogStub(); - static const char* GetCodePosForParam(int index); + static const char* GetCodePosForParam(unsigned int index); static void GetReplacedPos(const char* pos); static void SetReplacedPos(const char* what, const char* with); static void VMExecuteInternalStub(); diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 462c6d9c..d61e41fa 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -460,7 +460,7 @@ namespace Game XZone* g_zones = reinterpret_cast(0x14C0F80); unsigned short* db_hashTable = reinterpret_cast(0x12412B0); - ScriptContainer* scriptContainer = reinterpret_cast(0x2040D00); + scrVmPub_t* scrVmPub = reinterpret_cast(0x2040CF0); clientstate_t* clcState = reinterpret_cast(0xB2C540); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 47487a29..f5e89711 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -968,7 +968,7 @@ namespace Game extern XZone* g_zones; extern unsigned short* db_hashTable; - extern ScriptContainer* scriptContainer; + extern scrVmPub_t* scrVmPub; extern clientstate_t* clcState; diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 6e112ee4..1f090ec0 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -4889,15 +4889,35 @@ namespace Game VariableType type; }; - struct ScriptContainer + struct function_stack_t { - VariableValue* stack; - char unk1; - char unk2; - char unk3; - char pad; - DWORD unk4; - int numParam; + const char* pos; + unsigned int localId; + unsigned int localVarCount; + VariableValue* top; + VariableValue* startTop; + }; + + struct function_frame_t + { + function_stack_t fs; + int topType; + }; + + struct scrVmPub_t + { + unsigned int* localVars; + VariableValue* maxStack; + int function_count; + function_frame_t* function_frame; + VariableValue* top; + bool debugCode; + bool abort_on_error; + bool terminal_error; + unsigned int inparamcount; + unsigned int outparamcount; + function_frame_t function_frame_start[32]; + VariableValue stack[2048]; }; enum UILocalVarType