From 045926c8607f4202a9eb423fe76adbf7b67f2b67 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Wed, 1 May 2019 09:45:51 +0800 Subject: [PATCH] Reordered the execution of functions before exiting the map * partyMemberSaveProtos and queue_leaving_map are now called after executing map_exit_p_proc procedure. Replaced some obsolete implementation in ScriptExtender/Worldmap. --- sfall/Modules/KillCounter.cpp | 2 +- sfall/Modules/ScriptExtender.cpp | 31 +++++++++++++++++++++++++------ sfall/Modules/ScriptExtender.h | 3 ++- sfall/Modules/Worldmap.cpp | 9 ++++----- 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/sfall/Modules/KillCounter.cpp b/sfall/Modules/KillCounter.cpp index c6642832..75539914 100644 --- a/sfall/Modules/KillCounter.cpp +++ b/sfall/Modules/KillCounter.cpp @@ -69,7 +69,7 @@ static void KillCounterInit() { // Edit the functions to accept kill types over 19 SafeWriteBatch(38, extraKillTypesCountAddr); - SafeWrite32(0x42D9DD, 1488); + SafeWrite32(0x42D9DD, 1488); // critter_kill_info_ } void KillCounter::init() { diff --git a/sfall/Modules/ScriptExtender.cpp b/sfall/Modules/ScriptExtender.cpp index 833abd51..4f8051ec 100644 --- a/sfall/Modules/ScriptExtender.cpp +++ b/sfall/Modules/ScriptExtender.cpp @@ -76,6 +76,8 @@ struct SelfOverrideObj { fo::GameObject* object; char counter; + SelfOverrideObj(fo::GameObject* obj) : object(obj), counter(0) {} + bool UnSetSelf() { if (counter) counter--; return counter == 0; @@ -102,7 +104,7 @@ DWORD isGlobalScriptLoading = 0; std::unordered_map<__int64, int> globalVars; typedef std::unordered_map<__int64, int> :: iterator glob_itr; typedef std::unordered_map<__int64, int> :: const_iterator glob_citr; -typedef std::pair<__int64, int> glob_pair; +//typedef std::pair<__int64, int> glob_pair; DWORD availableGlobalScriptTypes = 0; bool isGameLoading; @@ -341,7 +343,7 @@ void __fastcall SetGlobalScriptType(fo::Program* script, int type) { static void SetGlobalVarInternal(__int64 var, int val) { glob_itr itr = globalVars.find(var); if (itr == globalVars.end()) { - globalVars.insert(glob_pair(var, val)); + globalVars.emplace(var, val); } else { if (val == 0) { globalVars.erase(itr); // applies for both float 0.0 and integer 0 @@ -395,10 +397,10 @@ void __fastcall SetSelfObject(fo::Program* script, fo::GameObject* obj) { it->second.counter = 0; } } else { - selfOverrideMap[script] = {obj, 0}; + selfOverrideMap.emplace(script, obj); } - } else { - if (isFind) selfOverrideMap.erase(it); + } else if (isFind) { + selfOverrideMap.erase(it); } } @@ -646,7 +648,7 @@ bool LoadGlobals(HANDLE h) { GlobalVar var; for (DWORD i = 0; i < count; i++) { ReadFile(h, &var, sizeof(GlobalVar), &unused, 0); - globalVars.insert(glob_pair(var.id, var.val)); + globalVars.emplace(var.id, var.val); } return false; } @@ -697,6 +699,17 @@ void SetGlobals(GlobalVar* globals) { } } +static void __declspec(naked) map_save_in_game_hook() { + __asm { + call fo::funcoffs::partyMemberSaveProtos_; + test cl, 1; + jz skip; + call fo::funcoffs::queue_leaving_map_; +skip: + jmp fo::funcoffs::game_time_; + } +} + void ScriptExtender::init() { LoadGameHook::OnAfterGameStarted() += LoadGlobalScripts; LoadGameHook::OnGameReset() += [] () { @@ -751,6 +764,12 @@ void ScriptExtender::init() { HookCall(0x421B72, CombatBeginHook); HookCall(0x421FC1, CombatOverHook); + // Reorder the execution of functions before exiting the map + // Call saving party member prototypes and removing the drug effects for NPC after executing map_exit_p_proc procedure + HookCall(0x483CF9, map_save_in_game_hook); + BlockCall(0x483CB4); // partyMemberSaveProtos_ + BlockCall(0x483CBE); // queue_leaving_map_ + InitNewOpcodes(); } diff --git a/sfall/Modules/ScriptExtender.h b/sfall/Modules/ScriptExtender.h index 295fb9ab..dc300d90 100644 --- a/sfall/Modules/ScriptExtender.h +++ b/sfall/Modules/ScriptExtender.h @@ -36,12 +36,13 @@ public: static Delegate<>& OnMapExit(); }; -#pragma pack(8) +#pragma pack(push, 8) struct GlobalVar { __int64 id; __int32 val; __int32 unused; }; +#pragma pack(pop) typedef struct { fo::Program* ptr = nullptr; diff --git a/sfall/Modules/Worldmap.cpp b/sfall/Modules/Worldmap.cpp index ba824bc9..5258b7ac 100644 --- a/sfall/Modules/Worldmap.cpp +++ b/sfall/Modules/Worldmap.cpp @@ -635,14 +635,13 @@ void Worldmap::SetRestMapLevel(int mapId, long elev, bool canRest) { } levelRest elevData = {-1, -1, -1, -1}; - std::pair info (mapId, elevData); if (elev == -1) { - info.second.level[++elev] = canRest; - info.second.level[++elev] = canRest; + elevData.level[++elev] = canRest; + elevData.level[++elev] = canRest; elev++; } - info.second.level[elev] = canRest; - mapRestInfo.insert(info); + elevData.level[elev] = canRest; + mapRestInfo.insert(std::make_pair(mapId, elevData)); } }