From ee9010217e3aba89461c28ca2cb672e509d69890 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Tue, 8 May 2018 12:30:53 +0800 Subject: [PATCH] Added description of HOOK_RESTTIMER, set_rest_heal_time, and set_rest_mode to documents. Renamed the bit flags for set_rest_mode. Fixed compilation error in Worldmap.cpp. --- artifacts/scripting/headers/sfall.h | 10 ++-- artifacts/scripting/hookscripts.txt | 13 +++++ artifacts/scripting/sfall function notes.txt | 4 ++ sfall/Modules/HookScripts/MiscHs.cpp | 34 +++++------ sfall/Modules/Worldmap.cpp | 59 +++++++++----------- 5 files changed, 65 insertions(+), 55 deletions(-) diff --git a/artifacts/scripting/headers/sfall.h b/artifacts/scripting/headers/sfall.h index bb40ae8e..99da7a80 100644 --- a/artifacts/scripting/headers/sfall.h +++ b/artifacts/scripting/headers/sfall.h @@ -180,6 +180,11 @@ #define CURSOR_COMMAND (1) #define CURSOR_TARGETING (2) +//Valid flags for set_rest_mode +#define RESTMODE_DISABLED (1) // disable resting on all maps +#define RESTMODE_STRICT (2) // disable resting on maps with "can_rest_here=No" in Maps.txt, even if there are no other critters +#define RESTMODE_NO_HEALING (4) // disable healing during resting + #define mstr_combat(x) (message_str_game(GAME_MSG_COMBAT, x)) #define mstr_ai(x) (message_str_game(GAME_MSG_AI, x)) #define mstr_scrname(x) (message_str_game(GAME_MSG_SCRNAME, x)) @@ -207,11 +212,6 @@ #define BLOCKING_TYPE_AI (2) #define BLOCKING_TYPE_SIGHT (3) // not really useful (works not as you would expect), game uses this only when checking if you can talk to a person -//Rest mode flags -#define DISABLE_REST (1) -#define DISABLE_REST_FIX (2) -#define DISABLE_REST_HEAL (4) - #define party_member_list_critters party_member_list(0) #define party_member_list_all party_member_list(1) diff --git a/artifacts/scripting/hookscripts.txt b/artifacts/scripting/hookscripts.txt index 85d58fd8..3f8a5330 100644 --- a/artifacts/scripting/hookscripts.txt +++ b/artifacts/scripting/hookscripts.txt @@ -485,3 +485,16 @@ int arg1 - the index number of the global variable being set int arg2 - the set value of the global variable int ret1 - overrides the value of the global variable + +------------------------------------------- + +HOOK_RESTTIMER (hs_resttimer.int) + +Runs continuously while the player is resting (using pipboy alarm clock). + +int arg1 - the game time in ticks +int arg2 - event type: 1 - when the resting ends normally, -1 - when pressing ESC to cancel the timer, 0 - otherwise +int arg3 - the hour part of the length of resting time +int arg4 - the minute part of the length of resting time + +int ret1 - pass 1 to interrupt the resting diff --git a/artifacts/scripting/sfall function notes.txt b/artifacts/scripting/sfall function notes.txt index 204617e0..a9d5e817 100644 --- a/artifacts/scripting/sfall function notes.txt +++ b/artifacts/scripting/sfall function notes.txt @@ -466,8 +466,12 @@ Some utility/math functions are available: - works only in map_enter_p_proc procedure > void sfall_func1("set_rest_heal_time", int minutes) +- sets the time interval in minutes for healing during resting. The default is 180 +- The time interval will be reset each time the player reloads the game > void sfall_func1("set_rest_mode", int mode) +- sets the bit flags for the rest mode (see REST_* constants in sfall.h) +- passing 0 will reset the rest mode. It will also be reset each time the player reloads the game ------------------------ ------ MORE INFO ------- diff --git a/sfall/Modules/HookScripts/MiscHs.cpp b/sfall/Modules/HookScripts/MiscHs.cpp index 7f171cba..1ab3c410 100644 --- a/sfall/Modules/HookScripts/MiscHs.cpp +++ b/sfall/Modules/HookScripts/MiscHs.cpp @@ -6,7 +6,7 @@ #include "MiscHs.h" -// Misc. hook scripts +// Misc. hook scripts namespace sfall { @@ -21,7 +21,7 @@ static void __declspec(naked) UseObjOnHook() { call RunHookScript; popad; cmp cRet, 1; - jl defaulthandler; + jl defaulthandler; mov eax, rets[0]; jmp end; defaulthandler: @@ -43,7 +43,7 @@ static void __declspec(naked) UseObjOnHook_item_d_take_drug() { call RunHookScript; popad; cmp cRet, 1; - jl defaulthandler; + jl defaulthandler; mov eax, rets[0]; jmp end; defaulthandler: @@ -64,7 +64,7 @@ static void __declspec(naked) UseObjHook() { call RunHookScript; popad; cmp cRet, 1; - jl defaulthandler; + jl defaulthandler; cmp rets[0], -1; je defaulthandler; mov eax, rets[0]; @@ -129,7 +129,7 @@ static void __declspec(naked) UseSkillHook() { call RunHookScript; popad; cmp cRet, 1; - jl defaulthandler; + jl defaulthandler; cmp rets[0], -1; je defaulthandler; mov eax, rets[0]; @@ -154,7 +154,7 @@ static void __declspec(naked) StealCheckHook() { call RunHookScript; popad; cmp cRet, 1; - jl defaulthandler; + jl defaulthandler; cmp rets[0], -1; je defaulthandler; mov eax, rets[0]; @@ -179,7 +179,7 @@ static void __declspec(naked) PerceptionRangeHook() { call RunHookScript; popad; cmp cRet, 1; - jl end; + jl end; mov eax, rets[0]; end: hookend; @@ -289,16 +289,16 @@ static void __declspec(naked) SetGlobalVarHook() { } } -static int restTicks; // previous ticks +static int restTicks; static void _stdcall RestTimerHookScript() { - int addrHook; + DWORD addrHook; __asm { mov addrHook, ebx; mov args[0], eax; mov args[8], ecx; mov args[12], edx; } - + BeginHook(); argCount = 4; addrHook -= 5; @@ -317,8 +317,8 @@ static void __declspec(naked) RestTimerLoopHook() { __asm { pushad; mov ebx, [esp + 32]; - mov ecx, [esp+36+0x40]; // hours_ - mov edx, [esp+36+0x44]; // minutes_ + mov ecx, [esp + 36 + 0x40]; // hours_ + mov edx, [esp + 36 + 0x44]; // minutes_ call RestTimerHookScript; popad; cmp cRet, 1; @@ -333,12 +333,12 @@ skip: static void __declspec(naked) RestTimerEscapeHook() { __asm { - cmp eax, 0x1B; + cmp eax, 0x1B; // ESC ASCII code jnz skip; pushad; - mov ebx, [esp+32]; - mov ecx, [esp+36+0x40]; // hours_ - mov edx, [esp+36+0x44]; // minutes_ + mov ebx, [esp + 32]; + mov ecx, [esp + 36 + 0x40]; // hours_ + mov edx, [esp + 36 + 0x44]; // minutes_ call RestTimerHookScript; popad; cmp cRet, 1; @@ -398,7 +398,7 @@ void InitMiscHookScripts() { LoadHookScript("hs_setglobalvar", HOOK_SETGLOBALVAR); HookCall(0x455A6D, SetGlobalVarHook); - + LoadHookScript("hs_resttimer", HOOK_RESTTIMER); HookCalls(RestTimerLoopHook, { 0x499B4B, 0x499BE0, 0x499D2C, 0x499DF2 }); MakeCalls(RestTimerEscapeHook, { 0x499B63, 0x499CA1 }); diff --git a/sfall/Modules/Worldmap.cpp b/sfall/Modules/Worldmap.cpp index 863b674e..ed91f07b 100644 --- a/sfall/Modules/Worldmap.cpp +++ b/sfall/Modules/Worldmap.cpp @@ -225,6 +225,18 @@ static __declspec(naked) void PathfinderFix() { } } +static void RestRestore() { + if (!restMode) return; + + restMode = false; + SafeWrite8(0x49952C, 0x85); + SafeWrite8(0x497557, 0x85); + SafeWrite8(0x42E587, 0xC7); + SafeWrite32(0x42E588, 0x10C2444); + SafeWrite16(0x499FD4, 0xC201); + SafeWrite16(0x499E93, 0x0574); +} + void WorldLimitsPatches() { DWORD date = GetConfigInt("Misc", "LocalMapXLimit", 0); if (date) { @@ -297,17 +309,11 @@ void TimeLimitPatch() { HookCall(0x4A34F9, &TimerReset); HookCall(0x4A3551, &TimerReset); - SafeWrite32(0x4A34EF, 0x90909090); - SafeWrite32(0x4A34F3, 0x90909090); - SafeWrite16(0x4A34F7, 0x9090); - SafeWrite32(0x4A34FE, 0x90909090); - SafeWrite16(0x4A3502, 0x9090); + SafeMemSet(0x4A34EF, 0x90, 10); + SafeMemSet(0x4A34FE, 0x90, 6); - SafeWrite32(0x4A3547, 0x90909090); - SafeWrite32(0x4A354B, 0x90909090); - SafeWrite16(0x4A354F, 0x9090); - SafeWrite32(0x4A3556, 0x90909090); - SafeWrite16(0x4A355A, 0x9090); + SafeMemSet(0x4A3547, 0x90, 10); + SafeMemSet(0x4A3556, 0x90, 6); } else { SafeWrite8(0x4A34EC, limit); SafeWrite8(0x4A3544, limit); @@ -423,8 +429,7 @@ void Worldmap::init() { LoadGameHook::OnGameReset() += []() { SetCarInterfaceArt(0x1B1); - if (restTime) - SetRestHealTime(180); + if (restTime) SetRestHealTime(180); RestRestore(); }; } @@ -437,44 +442,32 @@ void Worldmap::SetCarInterfaceArt(DWORD artIndex) { SafeWrite32(0x4C2D9B, artIndex); } -static void SetRestHealTime(DWORD minutes) { +void Worldmap::SetRestHealTime(DWORD minutes) { if (minutes > 0) { SafeWrite32(0x499FDE, minutes); restTime = (minutes != 180); } } -static void SetRestMode(DWORD mode) { +void Worldmap::SetRestMode(DWORD mode) { RestRestore(); // restore default - + restMode = ((mode & 0x7) > 0); if (!restMode) return; - if (mode & 1) { // bit1 - disable rest - SafeWrite8(0x49952C, 0x31); //test to xor + if (mode & 1) { // bit1 - disable resting on all maps + SafeWrite8(0x49952C, 0x31); // test to xor SafeWrite8(0x497557, 0x31); return; } - if (mode & 2) { // bit2 - fix rest + if (mode & 2) { // bit2 - disable resting on maps with "can_rest_here=No" in Maps.txt, even if there are no other critters SafeWrite8(0x42E587, 0xE9); - SafeWrite32(0x42E588, 0x94); + SafeWrite32(0x42E588, 0x00000094); // jmp 0x42E620 } - if (mode & 4) { // bit3 - disable heal + if (mode & 4) { // bit3 - disable healing during resting SafeWrite16(0x499FD4, 0x9090); - SafeWrite16(0x499E93, 0x8FEB); + SafeWrite16(0x499E93, 0x8FEB); // jmp 0x499E24 } } -static void RestRestore() { - if (!restMode) return; - - restMode = false; - SafeWrite8(0x49952C, 0x85); - SafeWrite8(0x497557, 0x85); - SafeWrite8(0x42E587, 0xC7); - SafeWrite32(0x42E588, 0x10C2444); - SafeWrite16(0x499FD4, 0xC201); - SafeWrite16(0x499E93, 0x0574); -} - }