Slightly simplified the code of NPCStage6Fix.

Moved NPCsTryToSpendExtraAP to AI.cpp.
This commit is contained in:
NovaRain
2019-05-19 08:24:31 +08:00
parent 520f939afa
commit f6d27b71aa
6 changed files with 63 additions and 66 deletions
+2 -2
View File
@@ -22,7 +22,7 @@ AllowSoundForFloats=1
;This does not effect the play_sfall_sound and stop_sfall_sound script functions ;This does not effect the play_sfall_sound and stop_sfall_sound script functions
AllowDShowSound=0 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 ;Set to 2 to overwrite all occurances of the music path
OverrideMusicDir=2 OverrideMusicDir=2
@@ -261,7 +261,7 @@ Movie17=credits.mve
;StartDay=-1 ;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 ;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! ;Not compatible with the res patch!
;LocalMapXLimit=480 ;LocalMapXLimit=480
;LocalMapYLimit=400 ;LocalMapYLimit=400
+37 -3
View File
@@ -24,10 +24,37 @@
#include "FalloutEngine.h" #include "FalloutEngine.h"
#include "SafeWrite.h" #include "SafeWrite.h"
typedef stdext::hash_map<DWORD, DWORD> :: const_iterator iter; typedef stdext::hash_map<DWORD, DWORD>::const_iterator iter;
static stdext::hash_map<DWORD,DWORD> targets; static stdext::hash_map<DWORD, DWORD> targets;
static stdext::hash_map<DWORD,DWORD> sources; static stdext::hash_map<DWORD, DWORD> 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) { static void __fastcall CombatAttackHook(DWORD source, DWORD target) {
sources[target] = source; sources[target] = source;
@@ -104,6 +131,13 @@ void AIInit() {
MakeJump(0x45F6AF, BlockCombatHook1); // intface_use_item_ MakeJump(0x45F6AF, BlockCombatHook1); // intface_use_item_
HookCall(0x4432A6, BlockCombatHook2); // game_handle_input_ HookCall(0x4432A6, BlockCombatHook2); // game_handle_input_
GetPrivateProfileString("sfall", "BlockedCombat", "You cannot enter combat at this time.", combatBlockedMessage, 128, translationIni); 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) { DWORD _stdcall AIGetLastAttacker(DWORD target) {
+5 -5
View File
@@ -682,28 +682,28 @@ const DWORD xvfprintf_ = 0x4DF1AC;
// please, use CamelCase for those // please, use CamelCase for those
int __stdcall ItemGetType(TGameObj* item) { long __stdcall ItemGetType(TGameObj* item) {
__asm { __asm {
mov eax, item; mov eax, item;
call item_get_type_; call item_get_type_;
} }
} }
int __stdcall ItemSize(TGameObj* item) { long __stdcall ItemSize(TGameObj* item) {
__asm { __asm {
mov eax, item; mov eax, item;
call item_size_; call item_size_;
} }
} }
int _stdcall IsPartyMember(TGameObj* obj) { long __stdcall IsPartyMember(TGameObj* obj) {
__asm { __asm {
mov eax, obj; mov eax, obj;
call isPartyMember_; call isPartyMember_;
} }
} }
int _stdcall PartyMemberGetCurrentLevel(TGameObj* obj) { long __stdcall PartyMemberGetCurrentLevel(TGameObj* obj) {
__asm { __asm {
mov eax, obj; mov eax, obj;
call partyMemberGetCurLevel_; 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 { __asm {
mov eax, scriptId; mov eax, scriptId;
mov edx, scriptPtr; mov edx, scriptPtr;
+5 -5
View File
@@ -943,15 +943,15 @@ extern const DWORD xvfprintf_;
// WRAPPERS: // WRAPPERS:
// TODO: move these to different namespace // TODO: move these to different namespace
int _stdcall IsPartyMember(TGameObj* obj); long __stdcall IsPartyMember(TGameObj* obj);
int _stdcall PartyMemberGetCurrentLevel(TGameObj* obj); long __stdcall PartyMemberGetCurrentLevel(TGameObj* obj);
char* GetProtoPtr(DWORD pid); char* GetProtoPtr(DWORD pid);
char AnimCodeByWeapon(TGameObj* weapon); char AnimCodeByWeapon(TGameObj* weapon);
// Displays message in main UI console window // Displays message in main UI console window
void DisplayConsoleMessage(const char* msg); void DisplayConsoleMessage(const char* msg);
const char* _stdcall GetMessageStr(DWORD fileAddr, DWORD messageId); const char* _stdcall GetMessageStr(DWORD fileAddr, DWORD messageId);
int __stdcall ItemGetType(TGameObj* item); long __stdcall ItemGetType(TGameObj* item);
int __stdcall ItemSize(TGameObj* item); long __stdcall ItemSize(TGameObj* item);
// Change the name of playable character // Change the name of playable character
void CritterPcSetName(const char* newName); void CritterPcSetName(const char* newName);
@@ -961,7 +961,7 @@ const char* __stdcall CritterName(TGameObj* critter);
// Saves pointer to script object into scriptPtr using scriptID. // Saves pointer to script object into scriptPtr using scriptID.
// Returns 0 on success, -1 on failure. // 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 SkillGetTags(int* result, DWORD num);
void SkillSetTags(int* tags, DWORD num); void SkillSetTags(int* tags, DWORD num);
+1 -1
View File
@@ -260,7 +260,7 @@ static void __stdcall DisplayCantDoThat() {
// 1 skip handler, -1 don't skip // 1 skip handler, -1 don't skip
int __stdcall PartyControl_SwitchHandHook(TGameObj* item) { int __stdcall PartyControl_SwitchHandHook(TGameObj* item) {
if (IsControllingNPC > 0 && ItemGetType(item) == 3) { if (IsControllingNPC > 0 && ItemGetType(item) == item_type_weapon) {
int canUse; int canUse;
/* check below uses AI packets and skills to check if weapon is usable /* check below uses AI packets and skills to check if weapon is usable
__asm { __asm {
+7 -44
View File
@@ -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() { static void __declspec(naked) intface_rotate_numbers_hack() {
__asm { __asm {
push edi push edi
@@ -542,22 +515,20 @@ end:
} }
static const DWORD NPCStage6Fix1End = 0x493D16; static const DWORD NPCStage6Fix1End = 0x493D16;
static const DWORD NPCStage6Fix2End = 0x49423A;
static void __declspec(naked) NPCStage6Fix1() { static void __declspec(naked) NPCStage6Fix1() {
__asm { __asm {
mov eax, 0xcc; // set record size to 204 bytes mov eax, 204; // set record size to 204 bytes
imul eax, edx; // multiply by number of NPC records in party.txt 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 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 jmp NPCStage6Fix1End; // call memset to set all malloc'ed memory to 0
} }
} }
static const DWORD NPCStage6Fix2End = 0x49423A;
static void __declspec(naked) NPCStage6Fix2() { static void __declspec(naked) NPCStage6Fix2() {
__asm { __asm {
mov eax, 0xcc; // record size is 204 bytes mov eax, 204; // record size is 204 bytes
imul edx, eax; // multiply by NPC number as listed in party.txt 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 mov eax, dword ptr ds:[_partyMemberAIOptions]; // get starting offset of internal NPC table
jmp NPCStage6Fix2End; // eax+edx = offset of specific NPC record jmp NPCStage6Fix2End; // eax+edx = offset of specific NPC record
@@ -895,13 +866,6 @@ static void DllMain2() {
dlogr(" Done", DL_INIT); 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); dlog("Checking for changed skilldex images.", DL_INIT);
tmp = GetPrivateProfileIntA("Misc", "Lockpick", 293, ini); tmp = GetPrivateProfileIntA("Misc", "Lockpick", 293, ini);
if (tmp != 293) SafeWrite32(0x518D54, tmp); if (tmp != 293) SafeWrite32(0x518D54, tmp);
@@ -1024,8 +988,8 @@ static void DllMain2() {
if (GetPrivateProfileIntA("Misc", "NPCStage6Fix", 0, ini)) { if (GetPrivateProfileIntA("Misc", "NPCStage6Fix", 0, ini)) {
dlog("Applying NPC Stage 6 Fix.", DL_INIT); dlog("Applying NPC Stage 6 Fix.", DL_INIT);
MakeJump(0x493CE9, NPCStage6Fix1); MakeJump(0x493CE9, NPCStage6Fix1);
SafeWrite8(0x494063, 0x06); // loop should look for a potential 6th stage SafeWrite8(0x494063, 6); // loop should look for a potential 6th stage
SafeWrite8(0x4940BB, 0xCC); // move pointer by 204 bytes instead of 200 SafeWrite8(0x4940BB, 204); // move pointer by 204 bytes instead of 200
MakeJump(0x494224, NPCStage6Fix2); MakeJump(0x494224, NPCStage6Fix2);
dlogr(" Done", DL_INIT); dlogr(" Done", DL_INIT);
} }
@@ -1097,9 +1061,8 @@ static void DllMain2() {
dlogr(" Done", DL_INIT); dlogr(" Done", DL_INIT);
} }
dlog("Applying AI patches.", DL_INIT); dlogr("Running AIInit().", DL_INIT);
AIInit(); AIInit();
dlogr(" Done", DL_INIT);
dlogr("Initializing party control.", DL_INIT); dlogr("Initializing party control.", DL_INIT);
PartyControlInit(); PartyControlInit();