mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Slightly simplified the code of NPCStage6Fix.
Moved NPCsTryToSpendExtraAP to AI.cpp.
This commit is contained in:
+2
-2
@@ -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
@@ -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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user