[Script] Allow adding custom script functions

This commit is contained in:
momo5502 2017-05-13 12:09:58 +02:00
parent 221e550180
commit 309e2d2987
5 changed files with 97 additions and 3 deletions

View File

@ -4,6 +4,7 @@ namespace Components
{
std::string Script::ScriptName;
std::vector<int> Script::ScriptHandles;
std::vector<Script::Function> Script::ScriptFunctions;
std::vector<std::string> Script::ScriptNameStack;
unsigned short Script::FunctionName;
@ -217,16 +218,78 @@ namespace Components
}
int handle = Script::LoadScriptAndLabel(file, "init");
if (handle)
if (handle) Script::ScriptHandles.push_back(handle);
else
{
Script::ScriptHandles.push_back(handle);
handle = Script::LoadScriptAndLabel(file, "main");
if (handle) Script::ScriptHandles.push_back(handle);
}
}
Game::GScr_LoadGameTypeScript();
}
void Script::AddFunction(std::string name, Game::scr_function_t function, bool isDev)
{
for(auto i = Script::ScriptFunctions.begin(); i != Script::ScriptFunctions.end();)
{
if(i->getName() == name)
{
i = Script::ScriptFunctions.erase(i);
continue;
}
++i;
}
Script::ScriptFunctions.push_back({ name, function, isDev });
}
Game::scr_function_t Script::GetFunction(const char** name, int* isDev)
{
if (name && *name) OutputDebugStringA(*name);
for (auto& function : Script::ScriptFunctions)
{
if (name)
{
if(std::string(*name) == function.getName())
{
*name = function.getName();
*isDev = function.isDev();
return function.getFunction();
}
}
else
{
Game::Scr_RegisterFunction(function.getFunction());
}
}
return nullptr;
}
__declspec(naked) void Script::GetFunctionStub()
{
__asm
{
push [esp + 8h]
push [esp + 8h]
mov eax, 5FA2B0h
call eax
test eax, eax
jnz returnSafe
call Script::GetFunction
returnSafe:
add esp, 8h
retn
}
}
int Script::SetExpFogStub()
{
if(Game::Scr_GetNumParam() == 6)
@ -259,6 +322,8 @@ namespace Components
Utils::Hook(0x48EFFE, Script::LoadGameType, HOOK_CALL).install()->quick();
Utils::Hook(0x45D44A, Script::LoadGameTypeScript, HOOK_CALL).install()->quick();
Utils::Hook(0x44E72E, Script::GetFunctionStub, HOOK_CALL).install()->quick();
Utils::Hook(0x5F41A3, Script::SetExpFogStub, HOOK_CALL).install()->quick();
}
@ -267,5 +332,6 @@ namespace Components
Script::ScriptName.clear();
Script::ScriptHandles.clear();
Script::ScriptNameStack.clear();
Script::ScriptFunctions.clear();
}
}

View File

@ -1,10 +1,26 @@
#pragma once
#include "Game/Structs.hpp"
namespace Components
{
class Script : public Component
{
public:
class Function
{
public:
Function(std::string _name, Game::scr_function_t _callback, bool _dev) : name(_name), callback(_callback), dev(_dev) {}
const char* getName() const { return this->name.data(); }
bool isDev() const { return this->dev; }
Game::scr_function_t getFunction() const { return this->callback; }
private:
std::string name;
Game::scr_function_t callback;
bool dev;
};
Script();
~Script();
@ -13,10 +29,12 @@ namespace Components
#endif
static int LoadScriptAndLabel(std::string script, std::string label);
static void AddFunction(std::string name, Game::scr_function_t function, bool isDev = false);
private:
static std::string ScriptName;
static std::vector<int> ScriptHandles;
static std::vector<Function> ScriptFunctions;
static std::vector<std::string> ScriptNameStack;
static unsigned short FunctionName;
@ -35,6 +53,9 @@ namespace Components
static void LoadGameType();
static void LoadGameTypeScript();
static Game::scr_function_t GetFunction(const char** name, int* isDev);
static void GetFunctionStub();
static int SetExpFogStub();
};
}

View File

@ -216,6 +216,7 @@ namespace Game
Scr_AddFloat_t Scr_AddFloat = Scr_AddFloat_t(0x61E860);
Scr_Notify_t Scr_Notify = Scr_Notify_t(0x4A4750);
Scr_RegisterFunction_t Scr_RegisterFunction = Scr_RegisterFunction_t(0x492D50);
Scr_ShutdownAllocNode_t Scr_ShutdownAllocNode = Scr_ShutdownAllocNode_t(0x441650);
Script_Alloc_t Script_Alloc = Script_Alloc_t(0x422E70);

View File

@ -541,6 +541,9 @@ namespace Game
typedef void(__cdecl * Scr_Notify_t)(gentity_t *ent, unsigned __int16 stringValue, unsigned int paramcount);
extern Scr_Notify_t Scr_Notify;
typedef void(__cdecl * Scr_RegisterFunction_t)(scr_function_t function);
extern Scr_RegisterFunction_t Scr_RegisterFunction;
typedef script_t* (__cdecl * Script_Alloc_t)(int length);
extern Script_Alloc_t Script_Alloc;

View File

@ -18,6 +18,9 @@ namespace Game
typedef vec_t vec3_t[3];
typedef vec_t vec4_t[4];
typedef int scr_entref_t;
typedef void(__cdecl * scr_function_t)(scr_entref_t);
typedef enum
{
ASSET_TYPE_PHYSPRESET = 0,