mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Backported optimization for global/hook scripts execution from 4.x
This commit is contained in:
@@ -10,8 +10,6 @@ To aid in mods compatibility, avoid using hs_xxx .int scripts. Instead it is rec
|
|||||||
|
|
||||||
Example setup for a hook-script based mod:
|
Example setup for a hook-script based mod:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
procedure tohit_hook_handler begin
|
procedure tohit_hook_handler begin
|
||||||
display_msg("Modifying hit_hook " + get_sfall_arg);
|
display_msg("Modifying hit_hook " + get_sfall_arg);
|
||||||
set_hit_chance_max(100);
|
set_hit_chance_max(100);
|
||||||
@@ -25,8 +23,6 @@ procedure start begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
There are script functions available, specific to hook scripts:
|
There are script functions available, specific to hook scripts:
|
||||||
|
|
||||||
> int init_hook()
|
> int init_hook()
|
||||||
@@ -48,7 +44,7 @@ Changes argument value. The argument number (argnum) is 0-indexed. This is usefu
|
|||||||
Used from a normal global script if you want to run it at the same point a full hook script would normally run. In case of this function, "start" proc will be executed in a current global script. You can use all above functions like normal.
|
Used from a normal global script if you want to run it at the same point a full hook script would normally run. In case of this function, "start" proc will be executed in a current global script. You can use all above functions like normal.
|
||||||
|
|
||||||
> void register_hook_proc(int hook, procedure proc)
|
> void register_hook_proc(int hook, procedure proc)
|
||||||
The same as register_hook, except that you specifically define which procedure in the current script should be called as a hook (instead of "start"). Pass procedure the same as how you use dialog option functions. This IS the recommended way to use hook scripts, as it gives both modularity (each mod logic in a separate global script, no conflicts if you don't use "hs_*.int" scripts) and flexibility (you can place all related hook scripts for specific mod in a single script!).
|
The same as register_hook, except that you specifically define which procedure in the current script should be called as a hook (instead of "start" by default). Pass procedure the same as how you use dialog option functions. This IS the recommended way to use hook scripts, as it gives both modularity (each mod logic in a separate global script, no conflicts if you don't use "hs_*.int" scripts) and flexibility (you can place all related hook scripts for specific mod in a single script!).
|
||||||
|
|
||||||
NOTE: you can hook several scripts to a single hook point, for example if it's different mods from different authors or just some different aspects of one larger mod. In this case scripts are executed in reverse order of how they were registered. When one of the scripts in a chain returns value with "set_sfall_return", the next script may override this value if calls "set_sfall_return" again. Sometimes you need to multiply certain value in a chain of hook scripts.
|
NOTE: you can hook several scripts to a single hook point, for example if it's different mods from different authors or just some different aspects of one larger mod. In this case scripts are executed in reverse order of how they were registered. When one of the scripts in a chain returns value with "set_sfall_return", the next script may override this value if calls "set_sfall_return" again. Sometimes you need to multiply certain value in a chain of hook scripts.
|
||||||
Example: let's say we have a Mod A which reduces all "to hit" chances by 50%. The code might look like this:
|
Example: let's say we have a Mod A which reduces all "to hit" chances by 50%. The code might look like this:
|
||||||
@@ -336,7 +332,6 @@ int arg4 - Type of hook (0 - when subtracting ammo after single shot attack,
|
|||||||
|
|
||||||
int ret1 - new ammo cost value (set to 0 for unlimited ammo)
|
int ret1 - new ammo cost value (set to 0 for unlimited ammo)
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
|
|
||||||
HOOK_KEYPRESS (hs_keypress.int)
|
HOOK_KEYPRESS (hs_keypress.int)
|
||||||
|
|||||||
+3
-2
@@ -125,7 +125,7 @@ static void CritTableLoad() {
|
|||||||
memcpy(&baseCritTable[6 * 9 * 38], (CritStruct*)_pc_crit_succ_eff, 6 * 9 * sizeof(CritStruct)); // PC crit table
|
memcpy(&baseCritTable[6 * 9 * 38], (CritStruct*)_pc_crit_succ_eff, 6 * 9 * sizeof(CritStruct)); // PC crit table
|
||||||
|
|
||||||
if (mode == 3) {
|
if (mode == 3) {
|
||||||
dlog(" and CriticalOverrides.ini (new fmt)", DL_CRITICALS);
|
dlogr(" and CriticalOverrides.ini (new fmt)", DL_CRITICALS);
|
||||||
char buf[32], buf2[32], buf3[32];
|
char buf[32], buf2[32], buf3[32];
|
||||||
for (int critter = 0; critter < CritTableCount; critter++) {
|
for (int critter = 0; critter < CritTableCount; critter++) {
|
||||||
sprintf_s(buf, "c_%02d", critter);
|
sprintf_s(buf, "c_%02d", critter);
|
||||||
@@ -147,8 +147,9 @@ static void CritTableLoad() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
dlog("\n", DL_CRITICALS);
|
||||||
}
|
}
|
||||||
dlog("\n", DL_CRITICALS);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ static void _stdcall RunSpecificHookScript(sHookScript *hook) {
|
|||||||
if (hook->callback != -1) {
|
if (hook->callback != -1) {
|
||||||
RunScriptProcByNum(hook->prog.ptr, hook->callback);
|
RunScriptProcByNum(hook->prog.ptr, hook->callback);
|
||||||
} else {
|
} else {
|
||||||
RunScriptProc(&hook->prog, start);
|
hook->callback = RunScriptStartProc(&hook->prog); // run start
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+27
-22
@@ -435,17 +435,13 @@ static char HighlightFail2[128];
|
|||||||
|
|
||||||
struct sGlobalScript {
|
struct sGlobalScript {
|
||||||
sScriptProgram prog;
|
sScriptProgram prog;
|
||||||
DWORD count;
|
int startProc; // position of the 'start' procedure in the script
|
||||||
DWORD repeat;
|
int count;
|
||||||
DWORD mode; //0 - local map loop, 1 - input loop, 2 - world map loop, 3 - local and world map loops
|
int repeat;
|
||||||
|
int mode; // 0 - local map loop, 1 - input loop, 2 - world map loop, 3 - local and world map loops
|
||||||
|
|
||||||
sGlobalScript() {}
|
//sGlobalScript() {}
|
||||||
sGlobalScript(sScriptProgram script) {
|
sGlobalScript(sScriptProgram script) : prog(script), startProc(-1), count(0), repeat(0), mode(0) {}
|
||||||
prog = script;
|
|
||||||
count = 0;
|
|
||||||
repeat = 0;
|
|
||||||
mode = 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sExportedVar {
|
struct sExportedVar {
|
||||||
@@ -820,10 +816,11 @@ static void __declspec(naked) register_hook() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void _stdcall register_hook_proc2() {
|
static void _stdcall register_hook_proc2() {
|
||||||
const ScriptValue &idArg = opHandler.arg(0);
|
const ScriptValue &idArg = opHandler.arg(0),
|
||||||
|
&procArg = opHandler.arg(1);
|
||||||
|
|
||||||
if (idArg.isInt()) {
|
if (idArg.isInt() && procArg.isInt()) {
|
||||||
RegisterHook((DWORD)opHandler.program(), idArg.rawValue(), opHandler.arg(1).rawValue());
|
RegisterHook((DWORD)opHandler.program(), idArg.rawValue(), procArg.rawValue());
|
||||||
} else {
|
} else {
|
||||||
OpcodeInvalidArgs("register_hook_proc");
|
OpcodeInvalidArgs("register_hook_proc");
|
||||||
}
|
}
|
||||||
@@ -1787,10 +1784,8 @@ void AddProgramToMap(sScriptProgram &prog) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sScriptProgram* GetGlobalScriptProgram(DWORD scriptPtr) {
|
sScriptProgram* GetGlobalScriptProgram(DWORD scriptPtr) {
|
||||||
for (std::vector<sGlobalScript>::iterator it = globalScripts.begin(); it != globalScripts.end(); it++) {
|
SfallProgsMap::iterator it = sfallProgsMap.find(scriptPtr);
|
||||||
if (it->prog.ptr == scriptPtr) return &it->prog;
|
return (it == sfallProgsMap.end()) ? nullptr : &it->second ; // prog
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _stdcall isGameScript(const char* filename) {
|
bool _stdcall isGameScript(const char* filename) {
|
||||||
@@ -1835,9 +1830,8 @@ void LoadGlobalScripts() {
|
|||||||
LoadScriptProgram(prog, baseName.c_str());
|
LoadScriptProgram(prog, baseName.c_str());
|
||||||
if (prog.ptr) {
|
if (prog.ptr) {
|
||||||
dlogr(" Done", DL_SCRIPT);
|
dlogr(" Done", DL_SCRIPT);
|
||||||
DWORD idx;
|
|
||||||
sGlobalScript gscript = sGlobalScript(prog);
|
sGlobalScript gscript = sGlobalScript(prog);
|
||||||
idx = globalScripts.size();
|
gscript.startProc = prog.procLookup[start]; // get 'start' procedure position
|
||||||
globalScripts.push_back(gscript);
|
globalScripts.push_back(gscript);
|
||||||
AddProgramToMap(prog);
|
AddProgramToMap(prog);
|
||||||
// initialize script (start proc will be executed for the first time) -- this needs to be after script is added to "globalScripts" array
|
// initialize script (start proc will be executed for the first time) -- this needs to be after script is added to "globalScripts" array
|
||||||
@@ -1916,9 +1910,20 @@ void RunScriptProc(sScriptProgram* prog, DWORD procId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int RunScriptStartProc(sScriptProgram* prog) {
|
||||||
|
DWORD sptr = prog->ptr;
|
||||||
|
DWORD procNum = prog->procLookup[start];
|
||||||
|
if (procNum != -1) {
|
||||||
|
RunScriptProcByNum(sptr, procNum);
|
||||||
|
}
|
||||||
|
return procNum;
|
||||||
|
}
|
||||||
|
|
||||||
static void RunScript(sGlobalScript* script) {
|
static void RunScript(sGlobalScript* script) {
|
||||||
script->count = 0;
|
script->count = 0;
|
||||||
RunScriptProc(&script->prog, start); // run "start"
|
if (script->startProc != -1) {
|
||||||
|
RunScriptProcByNum(script->prog.ptr, script->startProc); // run "start"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2009,8 +2014,8 @@ void RunGlobalScripts3() {
|
|||||||
static DWORD _stdcall HandleMapUpdateForScripts(const DWORD procId) {
|
static DWORD _stdcall HandleMapUpdateForScripts(const DWORD procId) {
|
||||||
if (procId == map_enter_p_proc) {
|
if (procId == map_enter_p_proc) {
|
||||||
// map changed, all game objects were destroyed and scripts detached, need to re-insert global scripts into the game
|
// map changed, all game objects were destroyed and scripts detached, need to re-insert global scripts into the game
|
||||||
for (SfallProgsMap::iterator it = sfallProgsMap.begin(); it != sfallProgsMap.end(); it++) {
|
for (std::vector<sGlobalScript>::const_iterator it = globalScripts.cbegin(); it != globalScripts.cend(); it++) {
|
||||||
DWORD progPtr = it->second.ptr;
|
DWORD progPtr = it->prog.ptr;
|
||||||
__asm {
|
__asm {
|
||||||
mov eax, progPtr;
|
mov eax, progPtr;
|
||||||
call runProgram_;
|
call runProgram_;
|
||||||
|
|||||||
@@ -87,6 +87,8 @@ void RunScriptProc(sScriptProgram* prog, const char* procName);
|
|||||||
// execute script proc by procId from define.h
|
// execute script proc by procId from define.h
|
||||||
void RunScriptProc(sScriptProgram* prog, DWORD procId);
|
void RunScriptProc(sScriptProgram* prog, DWORD procId);
|
||||||
|
|
||||||
|
int RunScriptStartProc(sScriptProgram* prog);
|
||||||
|
|
||||||
void AddProgramToMap(sScriptProgram &prog);
|
void AddProgramToMap(sScriptProgram &prog);
|
||||||
sScriptProgram* GetGlobalScriptProgram(DWORD scriptPtr);
|
sScriptProgram* GetGlobalScriptProgram(DWORD scriptPtr);
|
||||||
|
|
||||||
|
|||||||
+6
-8
@@ -741,20 +741,18 @@ static void DllMain2() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//if (GetPrivateProfileIntA("Misc", "ScriptExtender", 0, ini)) {
|
//if (GetPrivateProfileIntA("Misc", "ScriptExtender", 0, ini)) {
|
||||||
dlog("Applying script extender patch.", DL_INIT);
|
dlogr("Running StatsInit().", DL_INIT);
|
||||||
StatsInit();
|
StatsInit();
|
||||||
dlog(".", DL_INIT);
|
dlogr("Running ScriptExtenderSetup().", DL_INIT);
|
||||||
ScriptExtenderSetup();
|
ScriptExtenderSetup();
|
||||||
dlog(".", DL_INIT);
|
dlogr("Running LoadGameHookInit().", DL_INIT);
|
||||||
LoadGameHookInit();
|
LoadGameHookInit();
|
||||||
dlog(".", DL_INIT);
|
dlogr("Running PerksInit().", DL_INIT);
|
||||||
PerksInit();
|
PerksInit();
|
||||||
dlog(".", DL_INIT);
|
dlogr("Running CombatInit().", DL_INIT);
|
||||||
CombatInit();
|
CombatInit();
|
||||||
dlog(".", DL_INIT);
|
dlogr("Running SkillsInit().", DL_INIT);
|
||||||
SkillsInit();
|
SkillsInit();
|
||||||
dlog(".", DL_INIT);
|
|
||||||
dlogr(" Done", DL_INIT);
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
dlogr("Running FileSystemInit().", DL_INIT);
|
dlogr("Running FileSystemInit().", DL_INIT);
|
||||||
|
|||||||
Reference in New Issue
Block a user