Slightly simplified the code of NPCStage6Fix.

Moved NPCsTryToSpendExtraAP to AI.cpp.
This commit is contained in:
NovaRain
2019-05-19 08:15:45 +08:00
parent 16a0ef3bdf
commit 30ac2a9690
5 changed files with 57 additions and 63 deletions
+2 -2
View File
@@ -30,7 +30,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
@@ -256,7 +256,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
+1 -1
View File
@@ -84,7 +84,7 @@ void SkillSetTags(long* tags, long num) {
fo::func::skill_set_tags(tags, num);
}
int __fastcall GetItemType(GameObject* item) {
long __fastcall GetItemType(GameObject* item) {
return fo::func::item_get_type(item);
}
+1 -1
View File
@@ -52,7 +52,7 @@ void SkillGetTags(long* result, long num);
// wrapper for skill_set_tags with bounds checking
void SkillSetTags(long* tags, long num);
int __fastcall GetItemType(GameObject* item);
long __fastcall GetItemType(GameObject* item);
__declspec(noinline) GameObject* GetItemPtrSlot(GameObject* critter, InvenType slot);
+39 -3
View File
@@ -26,11 +26,40 @@
namespace sfall
{
using namespace fo;
using namespace Fields;
typedef std::unordered_map<DWORD, DWORD> :: const_iterator iter;
typedef std::unordered_map<DWORD, DWORD>::const_iterator iter;
static std::unordered_map<DWORD,DWORD> targets;
static std::unordered_map<DWORD,DWORD> sources;
static std::unordered_map<DWORD, DWORD> targets;
static std::unordered_map<DWORD, DWORD> sources;
static DWORD RetryCombatLastAP;
static DWORD RetryCombatMinAP;
static void __declspec(naked) RetryCombatHook() {
__asm {
mov RetryCombatLastAP, 0;
retry:
call fo::funcoffs::combat_ai_;
process:
cmp dword ptr ds:[FO_VAR_combat_turn_running], 0;
jle next;
call fo::funcoffs::process_bk_;
jmp process;
next:
mov eax, [esi + movePoints];
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;
@@ -107,6 +136,13 @@ void AI::init() {
MakeJump(0x45F6AF, BlockCombatHook1); // intface_use_item_
HookCall(0x4432A6, BlockCombatHook2); // game_handle_input_
combatBlockedMessage = Translate("sfall", "BlockedCombat", "You cannot enter combat at this time.");
RetryCombatMinAP = GetConfigInt("Misc", "NPCsTryToSpendExtraAP", 0);
if (RetryCombatMinAP > 0) {
dlog("Applying retry combat patch.", DL_INIT);
HookCall(0x422B94, RetryCombatHook); // combat_turn_
dlogr(" Done", DL_INIT);
}
}
DWORD _stdcall AIGetLastAttacker(DWORD target) {
+14 -56
View File
@@ -243,60 +243,29 @@ really_end:
}
}
static DWORD RetryCombatLastAP;
static DWORD RetryCombatMinAP;
static void __declspec(naked) RetryCombatHook() {
using namespace fo;
using namespace Fields;
__asm {
mov RetryCombatLastAP, 0;
retry:
call fo::funcoffs::combat_ai_;
process:
cmp dword ptr ds:[FO_VAR_combat_turn_running], 0;
jle next;
call fo::funcoffs::process_bk_;
jmp process;
next:
mov eax, [esi + movePoints];
cmp eax, RetryCombatMinAP;
jl end;
cmp eax, RetryCombatLastAP;
je end;
mov RetryCombatLastAP, eax;
mov eax, esi;
xor edx, edx;
jmp retry;
end:
retn;
}
}
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 fo::funcoffs::mem_malloc_; // malloc the necessary memory
mov edx,dword ptr ds:[FO_VAR_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 fo::funcoffs::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:[FO_VAR_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:[FO_VAR_partyMemberAIOptions]; // get starting offset of internal NPC table
jmp NPCStage6Fix2End; // eax+edx = offset of specific NPC record
}
}
static const DWORD ScannerHookRet=0x41BC1D;
static const DWORD ScannerHookFail=0x41BC65;
static const DWORD ScannerHookRet = 0x41BC1D;
static const DWORD ScannerHookFail = 0x41BC65;
static void __declspec(naked) ScannerAutomapHook() {
using fo::PID_MOTION_SENSOR;
__asm {
@@ -605,21 +574,12 @@ void CorpseLineOfFireFix() {
}
}
void ApplyNpcExtraApPatch() {
RetryCombatMinAP = GetConfigInt("Misc", "NPCsTryToSpendExtraAP", 0);
if (RetryCombatMinAP > 0) {
dlog("Applying retry combat patch.", DL_INIT);
HookCall(0x422B94, RetryCombatHook); // combat_turn_
dlogr(" Done", DL_INIT);
}
}
void NpcStage6Fix() {
if (GetConfigInt("Misc", "NPCStage6Fix", 0)) {
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);
}
@@ -906,8 +866,6 @@ void MiscPatches::init() {
PlayIdleAnimOnReloadPatch();
CorpseLineOfFireFix();
ApplyNpcExtraApPatch();
SkilldexImagesPatch();
SpeedInterfaceCounterAnimsPatch();