From f6d27b71aad059535f2c97c40bd8eaa3bb3f803b Mon Sep 17 00:00:00 2001 From: NovaRain Date: Sun, 19 May 2019 00:27:13 +0800 Subject: [PATCH] Slightly simplified the code of NPCStage6Fix. Moved NPCsTryToSpendExtraAP to AI.cpp. --- artifacts/ddraw.ini | 4 +-- sfall/AI.cpp | 40 ++++++++++++++++++++++++-- sfall/FalloutEngine.cpp | 10 +++---- sfall/FalloutEngine.h | 10 +++---- sfall/PartyControl.cpp | 2 +- sfall/main.cpp | 63 +++++++++-------------------------------- 6 files changed, 63 insertions(+), 66 deletions(-) diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index 275535c7..c68b6240 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -22,7 +22,7 @@ AllowSoundForFloats=1 ;This does not effect the play_sfall_sound and stop_sfall_sound script functions AllowDShowSound=0 -;Set to 1 to override the music path used by default if not present in the cfg +;Set to 1 to override the music path used by default (i.e. data\sound\music\) if not present in the cfg ;Set to 2 to overwrite all occurances of the music path OverrideMusicDir=2 @@ -261,7 +261,7 @@ Movie17=credits.mve ;StartDay=-1 ;To change the limit of the distance away from the player to which you're allowed to scroll the local maps, uncomment the next two lines -;Defaults are 0x1E0 in the x direction and 0x190 in the y direction. +;Defaults are 480 in the x direction and 400 in the y direction. ;Not compatible with the res patch! ;LocalMapXLimit=480 ;LocalMapYLimit=400 diff --git a/sfall/AI.cpp b/sfall/AI.cpp index ea4ca145..8a993ba1 100644 --- a/sfall/AI.cpp +++ b/sfall/AI.cpp @@ -24,10 +24,37 @@ #include "FalloutEngine.h" #include "SafeWrite.h" -typedef stdext::hash_map :: const_iterator iter; +typedef stdext::hash_map::const_iterator iter; -static stdext::hash_map targets; -static stdext::hash_map sources; +static stdext::hash_map targets; +static stdext::hash_map sources; + +static DWORD RetryCombatLastAP; +static DWORD RetryCombatMinAP; +static void __declspec(naked) RetryCombatHook() { + __asm { + mov RetryCombatLastAP, 0; +retry: + call combat_ai_; +process: + cmp dword ptr ds:[_combat_turn_running], 0; + jle next; + call process_bk_; + jmp process; +next: + mov eax, [esi + 0x40]; + cmp eax, RetryCombatMinAP; + jl end; + cmp eax, RetryCombatLastAP; + je end; + mov RetryCombatLastAP, eax; + mov eax, esi; + xor edx, edx; + jmp retry; +end: + retn; + } +} static void __fastcall CombatAttackHook(DWORD source, DWORD target) { sources[target] = source; @@ -104,6 +131,13 @@ void AIInit() { MakeJump(0x45F6AF, BlockCombatHook1); // intface_use_item_ HookCall(0x4432A6, BlockCombatHook2); // game_handle_input_ GetPrivateProfileString("sfall", "BlockedCombat", "You cannot enter combat at this time.", combatBlockedMessage, 128, translationIni); + + RetryCombatMinAP = GetPrivateProfileIntA("Misc", "NPCsTryToSpendExtraAP", 0, ini); + if (RetryCombatMinAP > 0) { + dlog("Applying retry combat patch.", DL_INIT); + HookCall(0x422B94, RetryCombatHook); // combat_turn_ + dlogr(" Done", DL_INIT); + } } DWORD _stdcall AIGetLastAttacker(DWORD target) { diff --git a/sfall/FalloutEngine.cpp b/sfall/FalloutEngine.cpp index b7106fd6..6462b7d7 100644 --- a/sfall/FalloutEngine.cpp +++ b/sfall/FalloutEngine.cpp @@ -682,28 +682,28 @@ const DWORD xvfprintf_ = 0x4DF1AC; // please, use CamelCase for those -int __stdcall ItemGetType(TGameObj* item) { +long __stdcall ItemGetType(TGameObj* item) { __asm { mov eax, item; call item_get_type_; } } -int __stdcall ItemSize(TGameObj* item) { +long __stdcall ItemSize(TGameObj* item) { __asm { mov eax, item; call item_size_; } } -int _stdcall IsPartyMember(TGameObj* obj) { +long __stdcall IsPartyMember(TGameObj* obj) { __asm { mov eax, obj; call isPartyMember_; } } -int _stdcall PartyMemberGetCurrentLevel(TGameObj* obj) { +long __stdcall PartyMemberGetCurrentLevel(TGameObj* obj) { __asm { mov eax, obj; call partyMemberGetCurLevel_; @@ -789,7 +789,7 @@ void SkillSetTags(int* tags, DWORD num) { } } -int __stdcall ScrPtr(int scriptId, TScript** scriptPtr) { +long __stdcall ScrPtr(long scriptId, TScript** scriptPtr) { __asm { mov eax, scriptId; mov edx, scriptPtr; diff --git a/sfall/FalloutEngine.h b/sfall/FalloutEngine.h index af132f65..2b570c71 100644 --- a/sfall/FalloutEngine.h +++ b/sfall/FalloutEngine.h @@ -943,15 +943,15 @@ extern const DWORD xvfprintf_; // WRAPPERS: // TODO: move these to different namespace -int _stdcall IsPartyMember(TGameObj* obj); -int _stdcall PartyMemberGetCurrentLevel(TGameObj* obj); +long __stdcall IsPartyMember(TGameObj* obj); +long __stdcall PartyMemberGetCurrentLevel(TGameObj* obj); char* GetProtoPtr(DWORD pid); char AnimCodeByWeapon(TGameObj* weapon); // Displays message in main UI console window void DisplayConsoleMessage(const char* msg); const char* _stdcall GetMessageStr(DWORD fileAddr, DWORD messageId); -int __stdcall ItemGetType(TGameObj* item); -int __stdcall ItemSize(TGameObj* item); +long __stdcall ItemGetType(TGameObj* item); +long __stdcall ItemSize(TGameObj* item); // Change the name of playable character void CritterPcSetName(const char* newName); @@ -961,7 +961,7 @@ const char* __stdcall CritterName(TGameObj* critter); // Saves pointer to script object into scriptPtr using scriptID. // Returns 0 on success, -1 on failure. -int __stdcall ScrPtr(int scriptId, TScript** scriptPtr); +long __stdcall ScrPtr(long scriptId, TScript** scriptPtr); void SkillGetTags(int* result, DWORD num); void SkillSetTags(int* tags, DWORD num); diff --git a/sfall/PartyControl.cpp b/sfall/PartyControl.cpp index 74cc1281..187cc63c 100644 --- a/sfall/PartyControl.cpp +++ b/sfall/PartyControl.cpp @@ -260,7 +260,7 @@ static void __stdcall DisplayCantDoThat() { // 1 skip handler, -1 don't skip int __stdcall PartyControl_SwitchHandHook(TGameObj* item) { - if (IsControllingNPC > 0 && ItemGetType(item) == 3) { + if (IsControllingNPC > 0 && ItemGetType(item) == item_type_weapon) { int canUse; /* check below uses AI packets and skills to check if weapon is usable __asm { diff --git a/sfall/main.cpp b/sfall/main.cpp index ca34b6ae..b4bc4e21 100644 --- a/sfall/main.cpp +++ b/sfall/main.cpp @@ -451,33 +451,6 @@ really_end: } } -static DWORD RetryCombatLastAP; -static DWORD RetryCombatMinAP; -static void __declspec(naked) RetryCombatHook() { - __asm { - mov RetryCombatLastAP, 0; -retry: - call combat_ai_; -process: - cmp dword ptr ds:[_combat_turn_running], 0; - jle next; - call process_bk_; - jmp process; -next: - mov eax, [esi + 0x40]; - cmp eax, RetryCombatMinAP; - jl end; - cmp eax, RetryCombatLastAP; - je end; - mov RetryCombatLastAP, eax; - mov eax, esi; - xor edx, edx; - jmp retry; -end: - retn; - } -} - static void __declspec(naked) intface_rotate_numbers_hack() { __asm { push edi @@ -542,25 +515,23 @@ end: } static const DWORD NPCStage6Fix1End = 0x493D16; -static const DWORD NPCStage6Fix2End = 0x49423A; static void __declspec(naked) NPCStage6Fix1() { __asm { - mov eax, 0xcc; // set record size to 204 bytes - imul eax, edx; // multiply by number of NPC records in party.txt - call mem_malloc_; // malloc the necessary memory - mov edx, dword ptr ds:[_partyMemberMaxCount]; // retrieve number of NPC records in party.txt - mov ebx, 0xcc; // set record size to 204 bytes - imul ebx, edx; // multiply by number of NPC records in party.txt - jmp NPCStage6Fix1End; // call memset to set all malloc'ed memory to 0 + mov eax, 204; // set record size to 204 bytes + imul eax, edx; // multiply by number of NPC records in party.txt + mov ebx, eax; // copy total record size for later memset + call mem_malloc_; // malloc the necessary memory + jmp NPCStage6Fix1End; // call memset to set all malloc'ed memory to 0 } } +static const DWORD NPCStage6Fix2End = 0x49423A; static void __declspec(naked) NPCStage6Fix2() { __asm { - mov eax, 0xcc; // record size is 204 bytes - imul edx, eax; // multiply by NPC number as listed in party.txt - mov eax, dword ptr ds:[_partyMemberAIOptions]; // get starting offset of internal NPC table - jmp NPCStage6Fix2End; // eax+edx = offset of specific NPC record + mov eax, 204; // record size is 204 bytes + imul edx, eax; // multiply by NPC number as listed in party.txt + mov eax, dword ptr ds:[_partyMemberAIOptions]; // get starting offset of internal NPC table + jmp NPCStage6Fix2End; // eax+edx = offset of specific NPC record } } @@ -895,13 +866,6 @@ static void DllMain2() { dlogr(" Done", DL_INIT); } - RetryCombatMinAP = GetPrivateProfileIntA("Misc", "NPCsTryToSpendExtraAP", 0, ini); - if (RetryCombatMinAP > 0) { - dlog("Applying retry combat patch.", DL_INIT); - HookCall(0x422B94, RetryCombatHook); // combat_turn_ - dlogr(" Done", DL_INIT); - } - dlog("Checking for changed skilldex images.", DL_INIT); tmp = GetPrivateProfileIntA("Misc", "Lockpick", 293, ini); if (tmp != 293) SafeWrite32(0x518D54, tmp); @@ -1024,8 +988,8 @@ static void DllMain2() { if (GetPrivateProfileIntA("Misc", "NPCStage6Fix", 0, ini)) { dlog("Applying NPC Stage 6 Fix.", DL_INIT); MakeJump(0x493CE9, NPCStage6Fix1); - SafeWrite8(0x494063, 0x06); // loop should look for a potential 6th stage - SafeWrite8(0x4940BB, 0xCC); // move pointer by 204 bytes instead of 200 + SafeWrite8(0x494063, 6); // loop should look for a potential 6th stage + SafeWrite8(0x4940BB, 204); // move pointer by 204 bytes instead of 200 MakeJump(0x494224, NPCStage6Fix2); dlogr(" Done", DL_INIT); } @@ -1097,9 +1061,8 @@ static void DllMain2() { dlogr(" Done", DL_INIT); } - dlog("Applying AI patches.", DL_INIT); + dlogr("Running AIInit().", DL_INIT); AIInit(); - dlogr(" Done", DL_INIT); dlogr("Initializing party control.", DL_INIT); PartyControlInit();