Merge pull request #587 from diamante0018/refactor/script
[Script]: Add IsSprinting & more
This commit is contained in:
commit
82a039e3b1
@ -111,9 +111,15 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bots::GScr_isTestClient(Game::scr_entref_t entref)
|
void Bots::GScr_isTestClient(const Game::scr_entref_t entref)
|
||||||
{
|
{
|
||||||
const auto* ent = Game::GetPlayerEntity(entref);
|
const auto* ent = Game::GetEntity(entref);
|
||||||
|
if (!ent->client)
|
||||||
|
{
|
||||||
|
Game::Scr_Error("isTestClient: entity must be a player entity");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Game::Scr_AddBool(Game::SV_IsTestClient(ent->s.number) != 0);
|
Game::Scr_AddBool(Game::SV_IsTestClient(ent->s.number) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,8 @@ namespace Components
|
|||||||
std::unordered_map<const char*, const char*> Script::ReplacedFunctions;
|
std::unordered_map<const char*, const char*> Script::ReplacedFunctions;
|
||||||
const char* Script::ReplacedPos = nullptr;
|
const char* Script::ReplacedPos = nullptr;
|
||||||
|
|
||||||
std::vector<int> Script::ScriptMainHandles;
|
std::unordered_map<std::string, int> Script::ScriptMainHandles;
|
||||||
std::vector<int> Script::ScriptInitHandles;
|
std::unordered_map<std::string, int> Script::ScriptInitHandles;
|
||||||
|
|
||||||
void Script::ShowDeprecationWarning()
|
void Script::ShowDeprecationWarning()
|
||||||
{
|
{
|
||||||
@ -28,16 +28,16 @@ namespace Components
|
|||||||
|
|
||||||
void Script::FunctionError()
|
void Script::FunctionError()
|
||||||
{
|
{
|
||||||
const auto* funcName = Game::SL_ConvertToString(Script::FunctionName);
|
const auto* funcName = Game::SL_ConvertToString(FunctionName);
|
||||||
|
|
||||||
Game::Scr_ShutdownAllocNode();
|
Game::Scr_ShutdownAllocNode();
|
||||||
|
|
||||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "\n");
|
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "\n");
|
||||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "******* script compile error *******\n");
|
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "******* script compile error *******\n");
|
||||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "Error: unknown function {} in {}\n", funcName, Script::ScriptName);
|
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "Error: unknown function {} in {}\n", funcName, ScriptName);
|
||||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "************************************\n");
|
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "************************************\n");
|
||||||
|
|
||||||
Logger::Error(Game::ERR_SCRIPT_DROP, "script compile error\nunknown function {}\n{}\n\n", funcName, Script::ScriptName);
|
Logger::Error(Game::ERR_SCRIPT_DROP, "script compile error\nunknown function {}\n{}\n\n", funcName, ScriptName);
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(naked) void Script::StoreFunctionNameStub()
|
__declspec(naked) void Script::StoreFunctionNameStub()
|
||||||
@ -45,7 +45,7 @@ namespace Components
|
|||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
mov eax, [esp - 8h]
|
mov eax, [esp - 8h]
|
||||||
mov Script::FunctionName, ax
|
mov FunctionName, ax
|
||||||
|
|
||||||
sub esp, 0Ch
|
sub esp, 0Ch
|
||||||
push 0
|
push 0
|
||||||
@ -87,12 +87,12 @@ namespace Components
|
|||||||
|
|
||||||
void Script::StoreScriptName(const char* name)
|
void Script::StoreScriptName(const char* name)
|
||||||
{
|
{
|
||||||
Script::ScriptNameStack.push_back(Script::ScriptName);
|
ScriptNameStack.push_back(ScriptName);
|
||||||
Script::ScriptName = name;
|
ScriptName = name;
|
||||||
|
|
||||||
if (!Utils::String::EndsWith(Script::ScriptName, ".gsc"))
|
if (!Utils::String::EndsWith(ScriptName, ".gsc"))
|
||||||
{
|
{
|
||||||
Script::ScriptName.append(".gsc");
|
ScriptName.append(".gsc");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ namespace Components
|
|||||||
lea ecx, [esp + 30h]
|
lea ecx, [esp + 30h]
|
||||||
push ecx
|
push ecx
|
||||||
|
|
||||||
call Script::StoreScriptName
|
call StoreScriptName
|
||||||
add esp, 4h
|
add esp, 4h
|
||||||
|
|
||||||
popad
|
popad
|
||||||
@ -120,8 +120,8 @@ namespace Components
|
|||||||
|
|
||||||
void Script::RestoreScriptName()
|
void Script::RestoreScriptName()
|
||||||
{
|
{
|
||||||
Script::ScriptName = Script::ScriptNameStack.back();
|
ScriptName = ScriptNameStack.back();
|
||||||
Script::ScriptNameStack.pop_back();
|
ScriptNameStack.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(naked) void Script::RestoreScriptNameStub()
|
__declspec(naked) void Script::RestoreScriptNameStub()
|
||||||
@ -129,7 +129,7 @@ namespace Components
|
|||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
pushad
|
pushad
|
||||||
call Script::RestoreScriptName
|
call RestoreScriptName
|
||||||
popad
|
popad
|
||||||
|
|
||||||
mov ds:1CDEAA8h, ebp
|
mov ds:1CDEAA8h, ebp
|
||||||
@ -205,17 +205,19 @@ namespace Components
|
|||||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "\n");
|
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "\n");
|
||||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "******* script compile error *******\n");
|
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "******* script compile error *******\n");
|
||||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "Error: {} ", msgbuf);
|
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "Error: {} ", msgbuf);
|
||||||
Script::PrintSourcePos(Script::ScriptName.data(), offset);
|
PrintSourcePos(ScriptName.data(), offset);
|
||||||
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "************************************\n\n");
|
Logger::Print(Game::CON_CHANNEL_PARSERSCRIPT, "************************************\n\n");
|
||||||
|
|
||||||
Logger::Error(Game::ERR_SCRIPT_DROP, "script compile error\n{}\n{}\n(see console for actual details)\n", msgbuf, Script::ScriptName);
|
Logger::Error(Game::ERR_SCRIPT_DROP, "script compile error\n{}\n{}\n(see console for actual details)\n", msgbuf, ScriptName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Script::Scr_LoadGameType_Stub()
|
void Script::Scr_LoadGameType_Stub()
|
||||||
{
|
{
|
||||||
for (const auto& handle : Script::ScriptMainHandles)
|
for (const auto& handle : ScriptMainHandles)
|
||||||
{
|
{
|
||||||
const auto id = Game::Scr_ExecThread(handle, 0);
|
Logger::Print("Executing '{}::main'\n", handle.first.data());
|
||||||
|
|
||||||
|
const auto id = Game::Scr_ExecThread(handle.second, 0);
|
||||||
Game::Scr_FreeThread(static_cast<std::uint16_t>(id));
|
Game::Scr_FreeThread(static_cast<std::uint16_t>(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,9 +226,11 @@ namespace Components
|
|||||||
|
|
||||||
void Script::Scr_StartupGameType_Stub()
|
void Script::Scr_StartupGameType_Stub()
|
||||||
{
|
{
|
||||||
for (const auto& handle : Script::ScriptInitHandles)
|
for (const auto& handle : ScriptInitHandles)
|
||||||
{
|
{
|
||||||
const auto id = Game::Scr_ExecThread(handle, 0);
|
Logger::Print("Executing '{}::init'\n", handle.first.data());
|
||||||
|
|
||||||
|
const auto id = Game::Scr_ExecThread(handle.second, 0);
|
||||||
Game::Scr_FreeThread(static_cast<std::uint16_t>(id));
|
Game::Scr_FreeThread(static_cast<std::uint16_t>(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,8 +241,8 @@ namespace Components
|
|||||||
void Script::GScr_LoadGameTypeScript_Stub()
|
void Script::GScr_LoadGameTypeScript_Stub()
|
||||||
{
|
{
|
||||||
// Clear handles (from previous GSC loading session)
|
// Clear handles (from previous GSC loading session)
|
||||||
Script::ScriptMainHandles.clear();
|
ScriptMainHandles.clear();
|
||||||
Script::ScriptInitHandles.clear();
|
ScriptInitHandles.clear();
|
||||||
|
|
||||||
char path[MAX_PATH]{};
|
char path[MAX_PATH]{};
|
||||||
|
|
||||||
@ -262,18 +266,17 @@ namespace Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
Logger::Print("Script {}.gsc loaded successfully.\n", path);
|
Logger::Print("Script {}.gsc loaded successfully.\n", path);
|
||||||
Logger::Debug("Finding script handle main or init...");
|
|
||||||
|
|
||||||
const auto initHandle = Game::Scr_GetFunctionHandle(path, "init");
|
const auto initHandle = Game::Scr_GetFunctionHandle(path, "init");
|
||||||
if (initHandle != 0)
|
if (initHandle != 0)
|
||||||
{
|
{
|
||||||
Script::ScriptInitHandles.push_back(initHandle);
|
ScriptInitHandles.insert_or_assign(path, initHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto mainHandle = Game::Scr_GetFunctionHandle(path, "main");
|
const auto mainHandle = Game::Scr_GetFunctionHandle(path, "main");
|
||||||
if (mainHandle != 0)
|
if (mainHandle != 0)
|
||||||
{
|
{
|
||||||
Script::ScriptMainHandles.push_back(mainHandle);
|
ScriptMainHandles.insert_or_assign(path, mainHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow scripts with no handles
|
// Allow scripts with no handles
|
||||||
@ -285,7 +288,7 @@ namespace Components
|
|||||||
|
|
||||||
void Script::AddFunction(const std::string& name, Game::BuiltinFunction func, bool type)
|
void Script::AddFunction(const std::string& name, Game::BuiltinFunction func, bool type)
|
||||||
{
|
{
|
||||||
Script::ScriptFunction toAdd;
|
ScriptFunction toAdd;
|
||||||
toAdd.actionFunc = func;
|
toAdd.actionFunc = func;
|
||||||
toAdd.type = type;
|
toAdd.type = type;
|
||||||
|
|
||||||
@ -294,7 +297,7 @@ namespace Components
|
|||||||
|
|
||||||
void Script::AddMethod(const std::string& name, Game::BuiltinMethod func, bool type)
|
void Script::AddMethod(const std::string& name, Game::BuiltinMethod func, bool type)
|
||||||
{
|
{
|
||||||
Script::ScriptMethod toAdd;
|
ScriptMethod toAdd;
|
||||||
toAdd.actionFunc = func;
|
toAdd.actionFunc = func;
|
||||||
toAdd.type = type;
|
toAdd.type = type;
|
||||||
|
|
||||||
@ -306,7 +309,7 @@ namespace Components
|
|||||||
if (pName != nullptr)
|
if (pName != nullptr)
|
||||||
{
|
{
|
||||||
// If no function was found let's call game's function
|
// If no function was found let's call game's function
|
||||||
if (const auto itr = Script::CustomScrFunctions.find(Utils::String::ToLower(*pName)); itr != Script::CustomScrFunctions.end())
|
if (const auto itr = CustomScrFunctions.find(Utils::String::ToLower(*pName)); itr != CustomScrFunctions.end())
|
||||||
{
|
{
|
||||||
*type = itr->second.type;
|
*type = itr->second.type;
|
||||||
return itr->second.actionFunc;
|
return itr->second.actionFunc;
|
||||||
@ -314,7 +317,7 @@ namespace Components
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (const auto& [name, builtin] : Script::CustomScrFunctions)
|
for (const auto& [name, builtin] : CustomScrFunctions)
|
||||||
{
|
{
|
||||||
Game::Scr_RegisterFunction(reinterpret_cast<int>(builtin.actionFunc), name.data());
|
Game::Scr_RegisterFunction(reinterpret_cast<int>(builtin.actionFunc), name.data());
|
||||||
}
|
}
|
||||||
@ -328,7 +331,7 @@ namespace Components
|
|||||||
if (pName != nullptr)
|
if (pName != nullptr)
|
||||||
{
|
{
|
||||||
// If no method was found let's call game's function
|
// If no method was found let's call game's function
|
||||||
if (const auto itr = Script::CustomScrMethods.find(Utils::String::ToLower(*pName)); itr != Script::CustomScrMethods.end())
|
if (const auto itr = CustomScrMethods.find(Utils::String::ToLower(*pName)); itr != CustomScrMethods.end())
|
||||||
{
|
{
|
||||||
*type = itr->second.type;
|
*type = itr->second.type;
|
||||||
return itr->second.actionFunc;
|
return itr->second.actionFunc;
|
||||||
@ -336,7 +339,7 @@ namespace Components
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (const auto& [name, builtin] : Script::CustomScrMethods)
|
for (const auto& [name, builtin] : CustomScrMethods)
|
||||||
{
|
{
|
||||||
Game::Scr_RegisterFunction(reinterpret_cast<int>(builtin.actionFunc), name.data());
|
Game::Scr_RegisterFunction(reinterpret_cast<int>(builtin.actionFunc), name.data());
|
||||||
}
|
}
|
||||||
@ -347,7 +350,7 @@ namespace Components
|
|||||||
|
|
||||||
void Script::StoreScriptBaseProgramNum()
|
void Script::StoreScriptBaseProgramNum()
|
||||||
{
|
{
|
||||||
Script::ScriptBaseProgramNum.insert_or_assign(Utils::Hook::Get<int>(0x1CFEEF8), Script::ScriptName);
|
ScriptBaseProgramNum.insert_or_assign(Utils::Hook::Get<int>(0x1CFEEF8), ScriptName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Script::Scr_PrintPrevCodePos(int scriptPos)
|
void Script::Scr_PrintPrevCodePos(int scriptPos)
|
||||||
@ -355,7 +358,7 @@ namespace Components
|
|||||||
auto bestCodePos = -1, nextCodePos = -1, offset = -1;
|
auto bestCodePos = -1, nextCodePos = -1, offset = -1;
|
||||||
std::string file;
|
std::string file;
|
||||||
|
|
||||||
for (const auto& [key, value] : Script::ScriptBaseProgramNum)
|
for (const auto& [key, value] : ScriptBaseProgramNum)
|
||||||
{
|
{
|
||||||
const auto codePos = key;
|
const auto codePos = key;
|
||||||
|
|
||||||
@ -388,7 +391,7 @@ namespace Components
|
|||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
push esi
|
push esi
|
||||||
call Script::Scr_PrintPrevCodePos
|
call Scr_PrintPrevCodePos
|
||||||
add esp, 4h
|
add esp, 4h
|
||||||
|
|
||||||
pop esi
|
pop esi
|
||||||
@ -402,7 +405,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
// execute our hook
|
// execute our hook
|
||||||
pushad
|
pushad
|
||||||
call Script::StoreScriptBaseProgramNum
|
call StoreScriptBaseProgramNum
|
||||||
popad
|
popad
|
||||||
|
|
||||||
// execute overwritten code caused by the jump hook
|
// execute overwritten code caused by the jump hook
|
||||||
@ -452,9 +455,9 @@ namespace Components
|
|||||||
|
|
||||||
void Script::GetReplacedPos(const char* pos)
|
void Script::GetReplacedPos(const char* pos)
|
||||||
{
|
{
|
||||||
if (Script::ReplacedFunctions.contains(pos))
|
if (ReplacedFunctions.contains(pos))
|
||||||
{
|
{
|
||||||
Script::ReplacedPos = Script::ReplacedFunctions[pos];
|
ReplacedPos = ReplacedFunctions[pos];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,12 +469,12 @@ namespace Components
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Script::ReplacedFunctions.contains(what))
|
if (ReplacedFunctions.contains(what))
|
||||||
{
|
{
|
||||||
Logger::Warning(Game::CON_CHANNEL_SCRIPT, "ReplacedFunctions already contains codePosValue for a function\n");
|
Logger::Warning(Game::CON_CHANNEL_SCRIPT, "ReplacedFunctions already contains codePosValue for a function\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
Script::ReplacedFunctions[what] = with;
|
ReplacedFunctions[what] = with;
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(naked) void Script::VMExecuteInternalStub()
|
__declspec(naked) void Script::VMExecuteInternalStub()
|
||||||
@ -481,12 +484,12 @@ namespace Components
|
|||||||
pushad
|
pushad
|
||||||
|
|
||||||
push edx
|
push edx
|
||||||
call Script::GetReplacedPos
|
call GetReplacedPos
|
||||||
|
|
||||||
pop edx
|
pop edx
|
||||||
popad
|
popad
|
||||||
|
|
||||||
cmp Script::ReplacedPos, 0
|
cmp ReplacedPos, 0
|
||||||
jne SetPos
|
jne SetPos
|
||||||
|
|
||||||
movzx eax, byte ptr [edx]
|
movzx eax, byte ptr [edx]
|
||||||
@ -509,8 +512,8 @@ namespace Components
|
|||||||
retn
|
retn
|
||||||
|
|
||||||
SetPos:
|
SetPos:
|
||||||
mov edx, Script::ReplacedPos
|
mov edx, ReplacedPos
|
||||||
mov Script::ReplacedPos, 0
|
mov ReplacedPos, 0
|
||||||
|
|
||||||
movzx eax, byte ptr [edx]
|
movzx eax, byte ptr [edx]
|
||||||
inc edx
|
inc edx
|
||||||
@ -521,7 +524,7 @@ namespace Components
|
|||||||
|
|
||||||
Game::client_t* Script::GetClient(const Game::gentity_t* ent)
|
Game::client_t* Script::GetClient(const Game::gentity_t* ent)
|
||||||
{
|
{
|
||||||
assert(ent != nullptr);
|
assert(ent);
|
||||||
|
|
||||||
if (ent->client == nullptr)
|
if (ent->client == nullptr)
|
||||||
{
|
{
|
||||||
@ -529,7 +532,7 @@ namespace Components
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ent->s.number >= *Game::svs_clientCount)
|
if (static_cast<std::size_t>(ent->s.number) >= Game::MAX_CLIENTS)
|
||||||
{
|
{
|
||||||
Game::Scr_ObjectError(Utils::String::VA("Entity %i is out of bounds", ent->s.number));
|
Game::Scr_ObjectError(Utils::String::VA("Entity %i is out of bounds", ent->s.number));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -540,7 +543,7 @@ namespace Components
|
|||||||
|
|
||||||
void Script::AddFunctions()
|
void Script::AddFunctions()
|
||||||
{
|
{
|
||||||
Script::AddFunction("ReplaceFunc", [] // gsc: ReplaceFunc(<function>, <function>)
|
AddFunction("ReplaceFunc", [] // gsc: ReplaceFunc(<function>, <function>)
|
||||||
{
|
{
|
||||||
if (Game::Scr_GetNumParam() != 2)
|
if (Game::Scr_GetNumParam() != 2)
|
||||||
{
|
{
|
||||||
@ -548,14 +551,14 @@ namespace Components
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto what = Script::GetCodePosForParam(0);
|
const auto what = GetCodePosForParam(0);
|
||||||
const auto with = Script::GetCodePosForParam(1);
|
const auto with = GetCodePosForParam(1);
|
||||||
|
|
||||||
Script::SetReplacedPos(what, with);
|
SetReplacedPos(what, with);
|
||||||
});
|
});
|
||||||
|
|
||||||
// System time
|
// System time
|
||||||
Script::AddFunction("GetSystemMilliseconds", [] // gsc: GetSystemMilliseconds()
|
AddFunction("GetSystemMilliseconds", [] // gsc: GetSystemMilliseconds()
|
||||||
{
|
{
|
||||||
SYSTEMTIME time;
|
SYSTEMTIME time;
|
||||||
GetSystemTime(&time);
|
GetSystemTime(&time);
|
||||||
@ -564,7 +567,7 @@ namespace Components
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Executes command to the console
|
// Executes command to the console
|
||||||
Script::AddFunction("Exec", [] // gsc: Exec(<string>)
|
AddFunction("Exec", [] // gsc: Exec(<string>)
|
||||||
{
|
{
|
||||||
const auto str = Game::Scr_GetString(0);
|
const auto str = Game::Scr_GetString(0);
|
||||||
|
|
||||||
@ -578,7 +581,7 @@ namespace Components
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Allow printing to the console even when developer is 0
|
// Allow printing to the console even when developer is 0
|
||||||
Script::AddFunction("PrintConsole", [] // gsc: PrintConsole(<string>)
|
AddFunction("PrintConsole", [] // gsc: PrintConsole(<string>)
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < Game::Scr_GetNumParam(); ++i)
|
for (std::size_t i = 0; i < Game::Scr_GetNumParam(); ++i)
|
||||||
{
|
{
|
||||||
@ -595,9 +598,9 @@ namespace Components
|
|||||||
});
|
});
|
||||||
|
|
||||||
// PlayerCmd_AreControlsFrozen GSC function from Black Ops 2
|
// PlayerCmd_AreControlsFrozen GSC function from Black Ops 2
|
||||||
Script::AddMethod("AreControlsFrozen", [](Game::scr_entref_t entref) // Usage: self AreControlsFrozen();
|
AddMethod("AreControlsFrozen", [](Game::scr_entref_t entref) // Usage: self AreControlsFrozen();
|
||||||
{
|
{
|
||||||
const auto* ent = Game::GetPlayerEntity(entref);
|
const auto* ent = Scr_GetPlayerEntity(entref);
|
||||||
|
|
||||||
Game::Scr_AddBool((ent->client->flags & Game::PLAYER_FLAG_FROZEN) != 0);
|
Game::Scr_AddBool((ent->client->flags & Game::PLAYER_FLAG_FROZEN) != 0);
|
||||||
});
|
});
|
||||||
@ -605,34 +608,34 @@ namespace Components
|
|||||||
|
|
||||||
Script::Script()
|
Script::Script()
|
||||||
{
|
{
|
||||||
Utils::Hook(0x612DB0, Script::StoreFunctionNameStub, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x612DB0, StoreFunctionNameStub, HOOK_JUMP).install()->quick();
|
||||||
Utils::Hook(0x427E71, Script::RestoreScriptNameStub, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x427E71, RestoreScriptNameStub, HOOK_JUMP).install()->quick();
|
||||||
Utils::Hook(0x427DBC, Script::StoreScriptNameStub, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x427DBC, StoreScriptNameStub, HOOK_JUMP).install()->quick();
|
||||||
Utils::Hook(0x426C2D, Script::StoreScriptBaseProgramNumStub, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x426C2D, StoreScriptBaseProgramNumStub, HOOK_JUMP).install()->quick();
|
||||||
Utils::Hook(0x42281B, Script::Scr_PrintPrevCodePosStub, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x42281B, Scr_PrintPrevCodePosStub, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
Utils::Hook(0x61E3AD, Script::RuntimeError, HOOK_CALL).install()->quick();
|
Utils::Hook(0x61E3AD, RuntimeError, HOOK_CALL).install()->quick();
|
||||||
Utils::Hook(0x621976, Script::RuntimeError, HOOK_CALL).install()->quick();
|
Utils::Hook(0x621976, RuntimeError, HOOK_CALL).install()->quick();
|
||||||
Utils::Hook(0x62246E, Script::RuntimeError, HOOK_CALL).install()->quick();
|
Utils::Hook(0x62246E, RuntimeError, HOOK_CALL).install()->quick();
|
||||||
// Skip check in GScr_CheckAllowedToSetPersistentData to prevent log spam in RuntimeError.
|
// Skip check in GScr_CheckAllowedToSetPersistentData to prevent log spam in RuntimeError.
|
||||||
// On IW5 the function is entirely nullsubbed
|
// On IW5 the function is entirely nullsubbed
|
||||||
Utils::Hook::Set<BYTE>(0x5F8DBF, 0xEB);
|
Utils::Hook::Set<std::uint8_t>(0x5F8DBF, 0xEB);
|
||||||
|
|
||||||
Utils::Hook(0x612E8D, Script::FunctionError, HOOK_CALL).install()->quick();
|
Utils::Hook(0x612E8D, FunctionError, HOOK_CALL).install()->quick();
|
||||||
Utils::Hook(0x612EA2, Script::FunctionError, HOOK_CALL).install()->quick();
|
Utils::Hook(0x612EA2, FunctionError, HOOK_CALL).install()->quick();
|
||||||
Utils::Hook(0x434260, Script::CompileError, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x434260, CompileError, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
Utils::Hook(0x48EFFE, Script::Scr_LoadGameType_Stub, HOOK_CALL).install()->quick();
|
Utils::Hook(0x48EFFE, Scr_LoadGameType_Stub, HOOK_CALL).install()->quick();
|
||||||
Utils::Hook(0x48F008, Script::Scr_StartupGameType_Stub, HOOK_CALL).install()->quick();
|
Utils::Hook(0x48F008, Scr_StartupGameType_Stub, HOOK_CALL).install()->quick();
|
||||||
Utils::Hook(0x45D44A, Script::GScr_LoadGameTypeScript_Stub, HOOK_CALL).install()->quick();
|
Utils::Hook(0x45D44A, GScr_LoadGameTypeScript_Stub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
// Fetch custom functions
|
// Fetch custom functions
|
||||||
Utils::Hook(0x44E72E, Script::BuiltIn_GetFunctionStub, HOOK_CALL).install()->quick(); // Scr_GetFunction
|
Utils::Hook(0x44E72E, BuiltIn_GetFunctionStub, HOOK_CALL).install()->quick(); // Scr_GetFunction
|
||||||
Utils::Hook(0x4EC8DD, Script::BuiltIn_GetMethodStub, HOOK_CALL).install()->quick(); // Scr_GetMethod
|
Utils::Hook(0x4EC8DD, BuiltIn_GetMethodStub, HOOK_CALL).install()->quick(); // Scr_GetMethod
|
||||||
|
|
||||||
Utils::Hook(0x5F41A3, Script::SetExpFogStub, HOOK_CALL).install()->quick();
|
Utils::Hook(0x5F41A3, SetExpFogStub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
Utils::Hook(0x61E92E, Script::VMExecuteInternalStub, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x61E92E, VMExecuteInternalStub, HOOK_JUMP).install()->quick();
|
||||||
Utils::Hook::Nop(0x61E933, 1);
|
Utils::Hook::Nop(0x61E933, 1);
|
||||||
|
|
||||||
Scheduler::Loop([]
|
Scheduler::Loop([]
|
||||||
@ -642,9 +645,9 @@ namespace Components
|
|||||||
|
|
||||||
const auto nowMs = Game::Sys_Milliseconds();
|
const auto nowMs = Game::Sys_Milliseconds();
|
||||||
|
|
||||||
if (Script::LastFrameTime != -1)
|
if (LastFrameTime != -1)
|
||||||
{
|
{
|
||||||
const auto timeTaken = (nowMs - Script::LastFrameTime) * static_cast<int>((*Game::com_timescale)->current.value);
|
const auto timeTaken = (nowMs - LastFrameTime) * static_cast<int>((*Game::com_timescale)->current.value);
|
||||||
|
|
||||||
if (timeTaken >= 500)
|
if (timeTaken >= 500)
|
||||||
{
|
{
|
||||||
@ -652,11 +655,11 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Script::LastFrameTime = nowMs;
|
LastFrameTime = nowMs;
|
||||||
}, Scheduler::Pipeline::SERVER);
|
}, Scheduler::Pipeline::SERVER);
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
Script::AddFunction("DebugBox", []
|
AddFunction("DebugBox", []
|
||||||
{
|
{
|
||||||
const auto* message = Game::Scr_GetString(0);
|
const auto* message = Game::Scr_GetString(0);
|
||||||
|
|
||||||
@ -666,14 +669,14 @@ namespace Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
MessageBoxA(nullptr, message, "DEBUG", MB_OK);
|
MessageBoxA(nullptr, message, "DEBUG", MB_OK);
|
||||||
}, 1);
|
}, true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Script::AddFunctions();
|
AddFunctions();
|
||||||
|
|
||||||
Events::OnVMShutdown([]
|
Events::OnVMShutdown([]
|
||||||
{
|
{
|
||||||
Script::ReplacedFunctions.clear();
|
ReplacedFunctions.clear();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,27 @@ namespace Components
|
|||||||
|
|
||||||
static void ShowDeprecationWarning();
|
static void ShowDeprecationWarning();
|
||||||
|
|
||||||
|
// Probably a macro 'originally' but this is fine
|
||||||
|
static Game::gentity_s* Scr_GetPlayerEntity(Game::scr_entref_t entref)
|
||||||
|
{
|
||||||
|
if (entref.classnum != 0)
|
||||||
|
{
|
||||||
|
Game::Scr_ObjectError("not an entity");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(entref.entnum < Game::MAX_GENTITIES);
|
||||||
|
|
||||||
|
auto* ent = &Game::g_entities[entref.entnum];
|
||||||
|
if (ent->client == nullptr)
|
||||||
|
{
|
||||||
|
Game::Scr_ObjectError(Utils::String::VA("entity %i is not a player", entref.entnum));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ent;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ScriptFunction
|
struct ScriptFunction
|
||||||
{
|
{
|
||||||
@ -38,8 +59,8 @@ namespace Components
|
|||||||
static std::unordered_map<int, std::string> ScriptBaseProgramNum;
|
static std::unordered_map<int, std::string> ScriptBaseProgramNum;
|
||||||
static int LastFrameTime;
|
static int LastFrameTime;
|
||||||
|
|
||||||
static std::vector<int> ScriptMainHandles;
|
static std::unordered_map<std::string, int> ScriptMainHandles;
|
||||||
static std::vector<int> ScriptInitHandles;
|
static std::unordered_map<std::string, int> ScriptInitHandles;
|
||||||
|
|
||||||
static std::unordered_map<const char*, const char*> ReplacedFunctions;
|
static std::unordered_map<const char*, const char*> ReplacedFunctions;
|
||||||
static const char* ReplacedPos;
|
static const char* ReplacedPos;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <STDInclude.hpp>
|
#include <STDInclude.hpp>
|
||||||
|
#include "GSC/Script.hpp"
|
||||||
|
|
||||||
namespace Components
|
namespace Components
|
||||||
{
|
{
|
||||||
@ -106,13 +107,13 @@ namespace Components
|
|||||||
|
|
||||||
// Bounce
|
// Bounce
|
||||||
push 0x4B1B34
|
push 0x4B1B34
|
||||||
retn
|
ret
|
||||||
|
|
||||||
noBounce:
|
noBounce:
|
||||||
// Original game code
|
// Original game code
|
||||||
cmp dword ptr [esp + 0x24], 0
|
cmp dword ptr [esp + 0x24], 0
|
||||||
push 0x4B1B48
|
push 0x4B1B48
|
||||||
retn
|
ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,6 +187,18 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlayerMovement::GScr_IsSprinting(const Game::scr_entref_t entref)
|
||||||
|
{
|
||||||
|
const auto* client = Game::GetEntity(entref)->client;
|
||||||
|
if (!client)
|
||||||
|
{
|
||||||
|
Game::Scr_Error("IsSprinting can only be called on a player");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Game::Scr_AddBool(Game::PM_IsSprinting(&client->ps));
|
||||||
|
}
|
||||||
|
|
||||||
const Game::dvar_t* PlayerMovement::Dvar_RegisterSpectateSpeedScale(const char* dvarName, float value,
|
const Game::dvar_t* PlayerMovement::Dvar_RegisterSpectateSpeedScale(const char* dvarName, float value,
|
||||||
float min, float max, unsigned __int16 /*flags*/, const char* description)
|
float min, float max, unsigned __int16 /*flags*/, const char* description)
|
||||||
{
|
{
|
||||||
@ -233,6 +246,9 @@ namespace Components
|
|||||||
|
|
||||||
PlayerMovement::PlayerMovement()
|
PlayerMovement::PlayerMovement()
|
||||||
{
|
{
|
||||||
|
AssertOffset(Game::playerState_s, eFlags, 0xB0);
|
||||||
|
AssertOffset(Game::playerState_s, pm_flags, 0xC);
|
||||||
|
|
||||||
Scheduler::Once([]
|
Scheduler::Once([]
|
||||||
{
|
{
|
||||||
static const char* bg_bouncesValues[] =
|
static const char* bg_bouncesValues[] =
|
||||||
@ -273,6 +289,8 @@ namespace Components
|
|||||||
Utils::Hook(0x45A5BF, CM_TransformedCapsuleTrace_Hk, HOOK_CALL).install()->quick(); // SV_ClipMoveToEntity
|
Utils::Hook(0x45A5BF, CM_TransformedCapsuleTrace_Hk, HOOK_CALL).install()->quick(); // SV_ClipMoveToEntity
|
||||||
Utils::Hook(0x5A0CAD, CM_TransformedCapsuleTrace_Hk, HOOK_CALL).install()->quick(); // CG_ClipMoveToEntity
|
Utils::Hook(0x5A0CAD, CM_TransformedCapsuleTrace_Hk, HOOK_CALL).install()->quick(); // CG_ClipMoveToEntity
|
||||||
|
|
||||||
|
Script::AddMethod("IsSprinting", GScr_IsSprinting);
|
||||||
|
|
||||||
RegisterMovementDvars();
|
RegisterMovementDvars();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,8 @@ namespace Components
|
|||||||
static int StuckInClient_Hk(Game::gentity_s* self);
|
static int StuckInClient_Hk(Game::gentity_s* self);
|
||||||
static void CM_TransformedCapsuleTrace_Hk(Game::trace_t* results, const float* start, const float* end, const Game::Bounds* bounds, const Game::Bounds* capsule, int contents, const float* origin, const float* angles);
|
static void CM_TransformedCapsuleTrace_Hk(Game::trace_t* results, const float* start, const float* end, const Game::Bounds* bounds, const Game::Bounds* capsule, int contents, const float* origin, const float* angles);
|
||||||
|
|
||||||
|
static void GScr_IsSprinting(Game::scr_entref_t entref);
|
||||||
|
|
||||||
static const Game::dvar_t* Dvar_RegisterSpectateSpeedScale(const char* dvarName, float value, float min, float max, unsigned __int16 flags, const char* description);
|
static const Game::dvar_t* Dvar_RegisterSpectateSpeedScale(const char* dvarName, float value, float min, float max, unsigned __int16 flags, const char* description);
|
||||||
|
|
||||||
static void RegisterMovementDvars();
|
static void RegisterMovementDvars();
|
||||||
|
@ -233,6 +233,7 @@ namespace Game
|
|||||||
PM_Trace_t PM_Trace = PM_Trace_t(0x441F60);
|
PM_Trace_t PM_Trace = PM_Trace_t(0x441F60);
|
||||||
PM_GetEffectiveStance_t PM_GetEffectiveStance = PM_GetEffectiveStance_t(0x412540);
|
PM_GetEffectiveStance_t PM_GetEffectiveStance = PM_GetEffectiveStance_t(0x412540);
|
||||||
PM_UpdateLean_t PM_UpdateLean = PM_UpdateLean_t(0x43DED0);
|
PM_UpdateLean_t PM_UpdateLean = PM_UpdateLean_t(0x43DED0);
|
||||||
|
PM_IsSprinting_t PM_IsSprinting = PM_IsSprinting_t(0x4B3830);
|
||||||
|
|
||||||
IN_RecenterMouse_t IN_RecenterMouse = IN_RecenterMouse_t(0x463D80);
|
IN_RecenterMouse_t IN_RecenterMouse = IN_RecenterMouse_t(0x463D80);
|
||||||
|
|
||||||
|
@ -524,6 +524,9 @@ namespace Game
|
|||||||
typedef void(*PM_UpdateLean_t)(playerState_s* ps, float msec, usercmd_s* cmd, void(*capsuleTrace)(trace_t*, const float*, const float*, const Bounds*, int, int));
|
typedef void(*PM_UpdateLean_t)(playerState_s* ps, float msec, usercmd_s* cmd, void(*capsuleTrace)(trace_t*, const float*, const float*, const Bounds*, int, int));
|
||||||
extern PM_UpdateLean_t PM_UpdateLean;
|
extern PM_UpdateLean_t PM_UpdateLean;
|
||||||
|
|
||||||
|
typedef bool(*PM_IsSprinting_t)(const playerState_s* ps);
|
||||||
|
extern PM_IsSprinting_t PM_IsSprinting;
|
||||||
|
|
||||||
typedef void(*IN_RecenterMouse_t)();
|
typedef void(*IN_RecenterMouse_t)();
|
||||||
extern IN_RecenterMouse_t IN_RecenterMouse;
|
extern IN_RecenterMouse_t IN_RecenterMouse;
|
||||||
|
|
||||||
|
@ -1679,23 +1679,23 @@ namespace Game
|
|||||||
|
|
||||||
enum usercmdButtonBits
|
enum usercmdButtonBits
|
||||||
{
|
{
|
||||||
CMD_BUTTON_ATTACK = 0x1,
|
CMD_BUTTON_ATTACK = 1 << 0,
|
||||||
CMD_BUTTON_SPRINT = 0x2,
|
CMD_BUTTON_SPRINT = 1 << 1,
|
||||||
CMD_BUTTON_MELEE = 0x4,
|
CMD_BUTTON_MELEE = 1 << 2,
|
||||||
CMD_BUTTON_ACTIVATE = 0x8,
|
CMD_BUTTON_ACTIVATE = 1 << 3,
|
||||||
CMD_BUTTON_RELOAD = 0x10,
|
CMD_BUTTON_RELOAD = 1 << 4,
|
||||||
CMD_BUTTON_USE_RELOAD = 0x20,
|
CMD_BUTTON_USE_RELOAD = 1 << 5,
|
||||||
CMD_BUTTON_LEAN_LEFT = 0x40,
|
CMD_BUTTON_LEAN_LEFT = 1 << 6,
|
||||||
CMD_BUTTON_LEAN_RIGHT = 0x80,
|
CMD_BUTTON_LEAN_RIGHT = 1 << 7,
|
||||||
CMD_BUTTON_PRONE = 0x100,
|
CMD_BUTTON_PRONE = 1 << 8,
|
||||||
CMD_BUTTON_CROUCH = 0x200,
|
CMD_BUTTON_CROUCH = 1 << 9,
|
||||||
CMD_BUTTON_UP = 0x400,
|
CMD_BUTTON_UP = 1 << 10,
|
||||||
CMD_BUTTON_ADS = 0x800,
|
CMD_BUTTON_ADS = 1 << 11,
|
||||||
CMD_BUTTON_DOWN = 0x1000,
|
CMD_BUTTON_DOWN = 1 << 12,
|
||||||
CMD_BUTTON_BREATH = 0x2000,
|
CMD_BUTTON_BREATH = 1 << 13,
|
||||||
CMD_BUTTON_FRAG = 0x4000,
|
CMD_BUTTON_FRAG = 1 << 14,
|
||||||
CMD_BUTTON_OFFHAND_SECONDARY = 0x8000,
|
CMD_BUTTON_OFFHAND_SECONDARY = 1 << 15,
|
||||||
CMD_BUTTON_THROW = 0x80000
|
CMD_BUTTON_THROW = 1 << 19,
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(push, 4)
|
#pragma pack(push, 4)
|
||||||
|
Loading…
Reference in New Issue
Block a user