Correction to the hooks code

Minor edits to some code.
This commit is contained in:
NovaRain
2020-09-23 22:37:11 +08:00
parent 876616fc7d
commit 8179583160
9 changed files with 53 additions and 52 deletions
+1 -1
View File
@@ -73,7 +73,7 @@ WindowData=0
;GlobalShaderFile=global.fx ;GlobalShaderFile=global.fx
;Set to 1 to enable linear texture filtering ;Set to 1 to enable linear texture filtering
;This can be used in conjunction with GlobalShaderFile ;This can be used in conjunction with the GlobalShaderFile option
TextureFilter=1 TextureFilter=1
;Set to 1 to do the palette conversion on the GPU ;Set to 1 to do the palette conversion on the GPU
+3 -3
View File
@@ -3531,7 +3531,7 @@ void BugFixes::init()
// Fix the code in combat_is_shot_blocked_ to correctly get the next tile from a multihex object instead of the previous // Fix the code in combat_is_shot_blocked_ to correctly get the next tile from a multihex object instead of the previous
// object or source tile // object or source tile
// Note: this bug does not cause an error in the function work // Note: this bug does not cause any noticeable error in the function
BYTE codeData[] = { BYTE codeData[] = {
0x8B, 0x70, 0x04, // mov esi, [eax + 4] 0x8B, 0x70, 0x04, // mov esi, [eax + 4]
0xF6, 0x40, 0x25, 0x08, // test [eax + flags2], MultiHex_ 0xF6, 0x40, 0x25, 0x08, // test [eax + flags2], MultiHex_
@@ -3565,8 +3565,8 @@ void BugFixes::init()
// Fix to limit the maximum distance for the knockback animation // Fix to limit the maximum distance for the knockback animation
MakeCall(0x4104D5, action_knockback_hack); MakeCall(0x4104D5, action_knockback_hack);
// Fix for combat_is_shot_blocked_ engine function not checking critters and their flags correctly // Fix for combat_is_shot_blocked_ engine function not taking the flags of critters in the line of fire into account
// when calculating the hit chance penalty based on the number of critters in the line of fire // when calculating the hit chance penalty of ranged attacks in determine_to_hit_func_ engine function
SafeWriteBatch<BYTE>(0x41, {0x426D46, 0x426D4E}); // edi > ecx (replace target with object critter) SafeWriteBatch<BYTE>(0x41, {0x426D46, 0x426D4E}); // edi > ecx (replace target with object critter)
SafeWrite8(0x426D48, fo::DAM_DEAD | fo::DAM_KNOCKED_DOWN | fo::DAM_KNOCKED_OUT); SafeWrite8(0x426D48, fo::DAM_DEAD | fo::DAM_KNOCKED_DOWN | fo::DAM_KNOCKED_OUT);
} }
+2 -2
View File
@@ -72,7 +72,7 @@ struct KnockbackModifier {
double value; double value;
}; };
long Combat::rawHitChance; // the value of hit chance w/o any cap long Combat::determineHitChance; // the value of hit chance w/o any cap
static std::vector<long> noBursts; // object id static std::vector<long> noBursts; // object id
@@ -242,7 +242,7 @@ static void __declspec(naked) compute_dmg_damage_hack() {
} }
static int __fastcall HitChanceMod(int base, fo::GameObject* critter) { static int __fastcall HitChanceMod(int base, fo::GameObject* critter) {
Combat::rawHitChance = base; Combat::determineHitChance = base;
for (size_t i = 0; i < hitChanceMods.size(); i++) { for (size_t i = 0; i < hitChanceMods.size(); i++) {
if (critter->id == hitChanceMods[i].id) { if (critter->id == hitChanceMods[i].id) {
return min(base + hitChanceMods[i].mod, hitChanceMods[i].maximum); return min(base + hitChanceMods[i].mod, hitChanceMods[i].maximum);
+1 -1
View File
@@ -28,7 +28,7 @@ public:
const char* name() { return "Combat"; } const char* name() { return "Combat"; }
void init(); void init();
static long rawHitChance; static long determineHitChance;
static DWORD __fastcall check_item_ammo_cost(fo::GameObject* weapon, DWORD hitMode); static DWORD __fastcall check_item_ammo_cost(fo::GameObject* weapon, DWORD hitMode);
}; };
+7 -7
View File
@@ -13,8 +13,9 @@ namespace sfall
static void __declspec(naked) ToHitHook() { static void __declspec(naked) ToHitHook() {
__asm { __asm {
HookBegin; HookBegin;
mov args[4], eax; // attacker mov argCount, 8;
mov args[8], ebx; // target mov args[4], eax; // attacker
mov args[8], ebx; // target
mov args[12], ecx; // body part mov args[12], ecx; // body part
mov args[16], edx; // source tile mov args[16], edx; // source tile
mov eax, [esp + 8]; mov eax, [esp + 8];
@@ -29,8 +30,7 @@ static void __declspec(naked) ToHitHook() {
pushadc; pushadc;
} }
argCount = 8; args[7] = Combat::determineHitChance;
args[7] = Combat::rawHitChance;
RunHookScript(HOOK_TOHIT); RunHookScript(HOOK_TOHIT);
__asm { __asm {
@@ -89,13 +89,13 @@ long __fastcall sf_item_w_mp_cost(fo::GameObject* source, long hitMode, long isC
if (!HookScripts::HookHasScript(HOOK_CALCAPCOST)) return cost; if (!HookScripts::HookHasScript(HOOK_CALCAPCOST)) return cost;
BeginHook(); BeginHook();
argCount = 4;
args[0] = (DWORD)source; args[0] = (DWORD)source;
args[1] = hitMode; args[1] = hitMode;
args[2] = isCalled; args[2] = isCalled;
args[3] = cost; args[3] = cost;
argCount = 4;
RunHookScript(HOOK_CALCAPCOST); RunHookScript(HOOK_CALCAPCOST);
if (cRet > 0) cost = rets[0]; if (cRet > 0) cost = rets[0];
@@ -107,6 +107,7 @@ long __fastcall sf_item_w_mp_cost(fo::GameObject* source, long hitMode, long isC
static void __declspec(naked) CalcApCostHook() { static void __declspec(naked) CalcApCostHook() {
__asm { __asm {
HookBegin; HookBegin;
mov argCount, 4;
mov args[0], eax; mov args[0], eax;
mov args[4], edx; mov args[4], edx;
mov args[8], ebx; mov args[8], ebx;
@@ -115,7 +116,6 @@ static void __declspec(naked) CalcApCostHook() {
pushad; pushad;
} }
argCount = 4;
RunHookScript(HOOK_CALCAPCOST); RunHookScript(HOOK_CALCAPCOST);
__asm { __asm {
@@ -296,12 +296,12 @@ static void __declspec(naked) ItemDamageHook() {
mov args[20], ebp; // non-zero for weapon melee attack (add to min/max melee damage) mov args[20], ebp; // non-zero for weapon melee attack (add to min/max melee damage)
pushad; pushad;
} }
argCount = 6;
if (args[2] == 0) { // weapon arg if (args[2] == 0) { // weapon arg
args[4] += 8; // type arg args[4] += 8; // type arg
} }
argCount = 6;
RunHookScript(HOOK_ITEMDAMAGE); RunHookScript(HOOK_ITEMDAMAGE);
__asm popad; __asm popad;
+1 -1
View File
@@ -118,9 +118,9 @@ static void __declspec(naked) OnDeathHook() {
static void __declspec(naked) OnDeathHook2() { static void __declspec(naked) OnDeathHook2() {
__asm { __asm {
call fo::funcoffs::partyMemberRemove_;
HookBegin; HookBegin;
mov args[0], esi; mov args[0], esi;
call fo::funcoffs::partyMemberRemove_;
pushad; pushad;
} }
+4 -4
View File
@@ -12,6 +12,7 @@ static void __declspec(naked) HexMBlockingHook() {
static const DWORD _obj_blocking_at = 0x48B84E; static const DWORD _obj_blocking_at = 0x48B84E;
__asm { __asm {
HookBegin; HookBegin;
mov argCount, 4;
mov args[0], eax; mov args[0], eax;
mov args[4], edx; mov args[4], edx;
mov args[8], ebx; mov args[8], ebx;
@@ -29,7 +30,6 @@ return:
pushad; pushad;
} }
argCount = 4;
RunHookScript(HOOK_HEXMOVEBLOCKING); RunHookScript(HOOK_HEXMOVEBLOCKING);
__asm { __asm {
@@ -44,6 +44,7 @@ return:
static void __declspec(naked) HexABlockingHook() { static void __declspec(naked) HexABlockingHook() {
__asm { __asm {
HookBegin; HookBegin;
mov argCount, 4;
mov args[0], eax; mov args[0], eax;
mov args[4], edx; mov args[4], edx;
mov args[8], ebx; mov args[8], ebx;
@@ -52,7 +53,6 @@ static void __declspec(naked) HexABlockingHook() {
pushad; pushad;
} }
argCount = 4;
RunHookScript(HOOK_HEXAIBLOCKING); RunHookScript(HOOK_HEXAIBLOCKING);
__asm { __asm {
@@ -67,6 +67,7 @@ static void __declspec(naked) HexABlockingHook() {
static void __declspec(naked) HexShootBlockingHook() { static void __declspec(naked) HexShootBlockingHook() {
__asm { __asm {
HookBegin; HookBegin;
mov argCount, 4;
mov args[0], eax; mov args[0], eax;
mov args[4], edx; mov args[4], edx;
mov args[8], ebx; mov args[8], ebx;
@@ -75,7 +76,6 @@ static void __declspec(naked) HexShootBlockingHook() {
pushad; pushad;
} }
argCount = 4;
RunHookScript(HOOK_HEXSHOOTBLOCKING); RunHookScript(HOOK_HEXSHOOTBLOCKING);
__asm { __asm {
@@ -90,6 +90,7 @@ static void __declspec(naked) HexShootBlockingHook() {
static void __declspec(naked) HexSightBlockingHook() { static void __declspec(naked) HexSightBlockingHook() {
__asm { __asm {
HookBegin; HookBegin;
mov argCount, 4;
mov args[0], eax; mov args[0], eax;
mov args[4], edx; mov args[4], edx;
mov args[8], ebx; mov args[8], ebx;
@@ -98,7 +99,6 @@ static void __declspec(naked) HexSightBlockingHook() {
pushad; pushad;
} }
argCount = 4;
RunHookScript(HOOK_HEXSIGHTBLOCKING); RunHookScript(HOOK_HEXSIGHTBLOCKING);
__asm { __asm {
+11 -3
View File
@@ -45,6 +45,7 @@ static void __declspec(naked) RemoveObjHook() {
static void __declspec(naked) MoveCostHook() { static void __declspec(naked) MoveCostHook() {
__asm { __asm {
HookBegin; HookBegin;
mov argCount, 3;
mov args[0], eax; mov args[0], eax;
mov args[4], edx; mov args[4], edx;
call fo::funcoffs::critter_compute_ap_from_distance_; call fo::funcoffs::critter_compute_ap_from_distance_;
@@ -52,7 +53,6 @@ static void __declspec(naked) MoveCostHook() {
pushadc; pushadc;
} }
argCount = 3;
RunHookScript(HOOK_MOVECOST); RunHookScript(HOOK_MOVECOST);
__asm { __asm {
@@ -340,6 +340,7 @@ static long __fastcall InvenWieldHook_Script(fo::GameObject* critter, fo::GameOb
} }
} }
BeginHook(); BeginHook();
argCount = 5;
args[0] = (DWORD)critter; args[0] = (DWORD)critter;
args[1] = (DWORD)item; args[1] = (DWORD)item;
@@ -347,7 +348,6 @@ static long __fastcall InvenWieldHook_Script(fo::GameObject* critter, fo::GameOb
args[3] = isWield; // unwield/wield event args[3] = isWield; // unwield/wield event
args[4] = isRemove; args[4] = isRemove;
argCount = 5;
RunHookScript(HOOK_INVENWIELD); RunHookScript(HOOK_INVENWIELD);
long result = (cRet == 0 || rets[0] == -1); long result = (cRet == 0 || rets[0] == -1);
@@ -360,7 +360,6 @@ static __declspec(noinline) bool InvenWieldHook_ScriptPart(long isWield, long is
args[3] = isWield; // unwield/wield event args[3] = isWield; // unwield/wield event
args[4] = isRemove; args[4] = isRemove;
argCount = 5;
RunHookScript(HOOK_INVENWIELD); RunHookScript(HOOK_INVENWIELD);
bool result = (cRet == 0 || rets[0] == -1); bool result = (cRet == 0 || rets[0] == -1);
@@ -377,6 +376,8 @@ static void __declspec(naked) InvenWieldFuncHook() {
mov args[8], ebx; // slot mov args[8], ebx; // slot
pushad; pushad;
} }
argCount = 5;
// right hand slot? // right hand slot?
if (args[2] != fo::INVEN_TYPE_RIGHT_HAND && fo::GetItemType((fo::GameObject*)args[1]) != fo::item_type_armor) { if (args[2] != fo::INVEN_TYPE_RIGHT_HAND && fo::GetItemType((fo::GameObject*)args[1]) != fo::item_type_armor) {
args[2] = fo::INVEN_TYPE_LEFT_HAND; args[2] = fo::INVEN_TYPE_LEFT_HAND;
@@ -402,10 +403,13 @@ static void __declspec(naked) InvenUnwieldFuncHook() {
mov args[8], edx; // slot mov args[8], edx; // slot
pushad; pushad;
} }
argCount = 5;
// set slot // set slot
if (args[2] == 0) { // left hand slot? if (args[2] == 0) { // left hand slot?
args[2] = fo::INVEN_TYPE_LEFT_HAND; args[2] = fo::INVEN_TYPE_LEFT_HAND;
} }
// get item // get item
args[1] = (DWORD)fo::GetItemPtrSlot((fo::GameObject*)args[0], (fo::InvenType)args[2]); args[1] = (DWORD)fo::GetItemPtrSlot((fo::GameObject*)args[0], (fo::InvenType)args[2]);
@@ -431,6 +435,8 @@ static void __declspec(naked) CorrectFidForRemovedItemHook() {
mov args[8], ebx; // item flag mov args[8], ebx; // item flag
pushadc; pushadc;
} }
argCount = 5;
// set slot // set slot
if (args[2] & fo::ObjectFlag::Right_Hand) { // right hand slot if (args[2] & fo::ObjectFlag::Right_Hand) { // right hand slot
args[2] = fo::INVEN_TYPE_RIGHT_HAND; args[2] = fo::INVEN_TYPE_RIGHT_HAND;
@@ -439,7 +445,9 @@ static void __declspec(naked) CorrectFidForRemovedItemHook() {
} else { } else {
args[2] = fo::INVEN_TYPE_WORN; // armor slot args[2] = fo::INVEN_TYPE_WORN; // armor slot
} }
InvenWieldHook_ScriptPart(0, 1); // unwield event (armor by default) InvenWieldHook_ScriptPart(0, 1); // unwield event (armor by default)
// engine handler is not overridden // engine handler is not overridden
__asm { __asm {
popadc; popadc;
+23 -30
View File
@@ -7,7 +7,6 @@
#include "MiscHs.h" #include "MiscHs.h"
// Misc. hook scripts
namespace sfall namespace sfall
{ {
@@ -260,13 +259,13 @@ static long __fastcall PerceptionRangeHook_Script(fo::GameObject* watcher, fo::G
long result = fo::func::is_within_perception(watcher, target); long result = fo::func::is_within_perception(watcher, target);
BeginHook(); BeginHook();
argCount = 4;
args[0] = (DWORD)watcher; args[0] = (DWORD)watcher;
args[1] = (DWORD)target; args[1] = (DWORD)target;
args[2] = result; args[2] = result;
args[3] = type; args[3] = type;
argCount = 4;
RunHookScript(HOOK_WITHINPERCEPTION); RunHookScript(HOOK_WITHINPERCEPTION);
if (cRet > 0) result = rets[0]; if (cRet > 0) result = rets[0];
@@ -338,6 +337,7 @@ static constexpr long maxGasAmount = 80000;
static void CarTravelHook_Script() { static void CarTravelHook_Script() {
BeginHook(); BeginHook();
argCount = 2; argCount = 2;
// calculate vanilla speed // calculate vanilla speed
int carSpeed = 3; int carSpeed = 3;
if (fo::func::game_get_global_var(fo::GVAR_CAR_BLOWER)) { if (fo::func::game_get_global_var(fo::GVAR_CAR_BLOWER)) {
@@ -426,18 +426,17 @@ static void __declspec(naked) SetGlobalVarHook() {
} }
static int restTicks; static int restTicks;
static long __stdcall RestTimerHook_Script() {
DWORD addrHook;
__asm {
mov addrHook, ebx;
HookBegin;
mov args[0], eax;
mov args[8], ecx;
mov args[12], edx;
}
argCount = 4; static long __fastcall RestTimerHook_Script(DWORD hours, DWORD minutes, DWORD gameTime, DWORD addrHook) {
addrHook -= 5; addrHook -= 5;
BeginHook();
argCount = 4;
args[0] = gameTime;
args[2] = hours;
args[3] = minutes;
if (addrHook == 0x499CA1 || addrHook == 0x499B63) { if (addrHook == 0x499CA1 || addrHook == 0x499B63) {
args[0] = restTicks; args[0] = restTicks;
args[1] = -1; args[1] = -1;
@@ -458,19 +457,16 @@ static long __stdcall RestTimerHook_Script() {
static void __declspec(naked) RestTimerLoopHook() { static void __declspec(naked) RestTimerLoopHook() {
__asm { __asm {
push eax; pushadc;
push edx;
push ecx;
push ebx;
mov ebx, [esp + 16];
mov ecx, [esp + 20 + 0x40]; // hours_
mov edx, [esp + 20 + 0x44]; // minutes_ mov edx, [esp + 20 + 0x44]; // minutes_
mov ecx, [esp + 20 + 0x40]; // hours_
push [esp + 16]; // addrHook
push eax; // gameTime
call RestTimerHook_Script; call RestTimerHook_Script;
pop ebx;
pop ecx; pop ecx;
pop edx; pop edx;
cmp eax, 0; test eax, eax; // result >= 0
cmovge edi, eax; // return 1 to interrupt resting cmovge edi, eax; // return 1 to interrupt resting
pop eax; pop eax;
jmp fo::funcoffs::set_game_time_; jmp fo::funcoffs::set_game_time_;
} }
@@ -481,19 +477,16 @@ static void __declspec(naked) RestTimerEscapeHook() {
mov edi, 1; // engine code mov edi, 1; // engine code
cmp eax, 0x1B; // ESC ASCII code cmp eax, 0x1B; // ESC ASCII code
jnz skip; jnz skip;
push eax; pushadc;
push edx;
push ecx;
push ebx;
mov ebx, [esp + 16];
mov ecx, [esp + 20 + 0x40]; // hours_
mov edx, [esp + 20 + 0x44]; // minutes_ mov edx, [esp + 20 + 0x44]; // minutes_
mov ecx, [esp + 20 + 0x40]; // hours_
push [esp + 16]; // addrHook
push eax; // gameTime
call RestTimerHook_Script; call RestTimerHook_Script;
pop ebx;
pop ecx; pop ecx;
pop edx; pop edx;
cmp eax, 0; test eax, eax; // result >= 0
cmovge edi, eax; // return 0 for cancel ESC key cmovge edi, eax; // return 0 for cancel ESC key
pop eax; pop eax;
skip: skip:
retn; retn;