diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index 4c6a447c..a882053d 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -73,7 +73,7 @@ WindowData=0 ;GlobalShaderFile=global.fx ;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 ;Set to 1 to do the palette conversion on the GPU diff --git a/sfall/Modules/BugFixes.cpp b/sfall/Modules/BugFixes.cpp index f3e3ffeb..b883089b 100644 --- a/sfall/Modules/BugFixes.cpp +++ b/sfall/Modules/BugFixes.cpp @@ -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 // 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[] = { 0x8B, 0x70, 0x04, // mov esi, [eax + 4] 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 MakeCall(0x4104D5, action_knockback_hack); - // Fix for combat_is_shot_blocked_ engine function not checking critters and their flags correctly - // when calculating the hit chance penalty based on the number of critters in the line of fire + // 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 of ranged attacks in determine_to_hit_func_ engine function SafeWriteBatch(0x41, {0x426D46, 0x426D4E}); // edi > ecx (replace target with object critter) SafeWrite8(0x426D48, fo::DAM_DEAD | fo::DAM_KNOCKED_DOWN | fo::DAM_KNOCKED_OUT); } diff --git a/sfall/Modules/Combat.cpp b/sfall/Modules/Combat.cpp index bca67334..f75c91d5 100644 --- a/sfall/Modules/Combat.cpp +++ b/sfall/Modules/Combat.cpp @@ -72,7 +72,7 @@ struct KnockbackModifier { 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 noBursts; // object id @@ -242,7 +242,7 @@ static void __declspec(naked) compute_dmg_damage_hack() { } static int __fastcall HitChanceMod(int base, fo::GameObject* critter) { - Combat::rawHitChance = base; + Combat::determineHitChance = base; for (size_t i = 0; i < hitChanceMods.size(); i++) { if (critter->id == hitChanceMods[i].id) { return min(base + hitChanceMods[i].mod, hitChanceMods[i].maximum); diff --git a/sfall/Modules/Combat.h b/sfall/Modules/Combat.h index 1ac1ab7f..1a0055ea 100644 --- a/sfall/Modules/Combat.h +++ b/sfall/Modules/Combat.h @@ -28,7 +28,7 @@ public: const char* name() { return "Combat"; } void init(); - static long rawHitChance; + static long determineHitChance; static DWORD __fastcall check_item_ammo_cost(fo::GameObject* weapon, DWORD hitMode); }; diff --git a/sfall/Modules/HookScripts/CombatHs.cpp b/sfall/Modules/HookScripts/CombatHs.cpp index 6a394b7a..3bd51e3d 100644 --- a/sfall/Modules/HookScripts/CombatHs.cpp +++ b/sfall/Modules/HookScripts/CombatHs.cpp @@ -13,8 +13,9 @@ namespace sfall static void __declspec(naked) ToHitHook() { __asm { HookBegin; - mov args[4], eax; // attacker - mov args[8], ebx; // target + mov argCount, 8; + mov args[4], eax; // attacker + mov args[8], ebx; // target mov args[12], ecx; // body part mov args[16], edx; // source tile mov eax, [esp + 8]; @@ -29,8 +30,7 @@ static void __declspec(naked) ToHitHook() { pushadc; } - argCount = 8; - args[7] = Combat::rawHitChance; + args[7] = Combat::determineHitChance; RunHookScript(HOOK_TOHIT); __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; BeginHook(); + argCount = 4; args[0] = (DWORD)source; args[1] = hitMode; args[2] = isCalled; args[3] = cost; - argCount = 4; RunHookScript(HOOK_CALCAPCOST); 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() { __asm { HookBegin; + mov argCount, 4; mov args[0], eax; mov args[4], edx; mov args[8], ebx; @@ -115,7 +116,6 @@ static void __declspec(naked) CalcApCostHook() { pushad; } - argCount = 4; RunHookScript(HOOK_CALCAPCOST); __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) pushad; } + argCount = 6; if (args[2] == 0) { // weapon arg args[4] += 8; // type arg } - argCount = 6; RunHookScript(HOOK_ITEMDAMAGE); __asm popad; diff --git a/sfall/Modules/HookScripts/DeathHs.cpp b/sfall/Modules/HookScripts/DeathHs.cpp index e5d43c73..cf026e06 100644 --- a/sfall/Modules/HookScripts/DeathHs.cpp +++ b/sfall/Modules/HookScripts/DeathHs.cpp @@ -118,9 +118,9 @@ static void __declspec(naked) OnDeathHook() { static void __declspec(naked) OnDeathHook2() { __asm { + call fo::funcoffs::partyMemberRemove_; HookBegin; mov args[0], esi; - call fo::funcoffs::partyMemberRemove_; pushad; } diff --git a/sfall/Modules/HookScripts/HexBlockingHs.cpp b/sfall/Modules/HookScripts/HexBlockingHs.cpp index 78fcbe4a..0342bfd5 100644 --- a/sfall/Modules/HookScripts/HexBlockingHs.cpp +++ b/sfall/Modules/HookScripts/HexBlockingHs.cpp @@ -12,6 +12,7 @@ static void __declspec(naked) HexMBlockingHook() { static const DWORD _obj_blocking_at = 0x48B84E; __asm { HookBegin; + mov argCount, 4; mov args[0], eax; mov args[4], edx; mov args[8], ebx; @@ -29,7 +30,6 @@ return: pushad; } - argCount = 4; RunHookScript(HOOK_HEXMOVEBLOCKING); __asm { @@ -44,6 +44,7 @@ return: static void __declspec(naked) HexABlockingHook() { __asm { HookBegin; + mov argCount, 4; mov args[0], eax; mov args[4], edx; mov args[8], ebx; @@ -52,7 +53,6 @@ static void __declspec(naked) HexABlockingHook() { pushad; } - argCount = 4; RunHookScript(HOOK_HEXAIBLOCKING); __asm { @@ -67,6 +67,7 @@ static void __declspec(naked) HexABlockingHook() { static void __declspec(naked) HexShootBlockingHook() { __asm { HookBegin; + mov argCount, 4; mov args[0], eax; mov args[4], edx; mov args[8], ebx; @@ -75,7 +76,6 @@ static void __declspec(naked) HexShootBlockingHook() { pushad; } - argCount = 4; RunHookScript(HOOK_HEXSHOOTBLOCKING); __asm { @@ -90,6 +90,7 @@ static void __declspec(naked) HexShootBlockingHook() { static void __declspec(naked) HexSightBlockingHook() { __asm { HookBegin; + mov argCount, 4; mov args[0], eax; mov args[4], edx; mov args[8], ebx; @@ -98,7 +99,6 @@ static void __declspec(naked) HexSightBlockingHook() { pushad; } - argCount = 4; RunHookScript(HOOK_HEXSIGHTBLOCKING); __asm { diff --git a/sfall/Modules/HookScripts/InventoryHs.cpp b/sfall/Modules/HookScripts/InventoryHs.cpp index 5a9c9011..e0c82258 100644 --- a/sfall/Modules/HookScripts/InventoryHs.cpp +++ b/sfall/Modules/HookScripts/InventoryHs.cpp @@ -45,6 +45,7 @@ static void __declspec(naked) RemoveObjHook() { static void __declspec(naked) MoveCostHook() { __asm { HookBegin; + mov argCount, 3; mov args[0], eax; mov args[4], edx; call fo::funcoffs::critter_compute_ap_from_distance_; @@ -52,7 +53,6 @@ static void __declspec(naked) MoveCostHook() { pushadc; } - argCount = 3; RunHookScript(HOOK_MOVECOST); __asm { @@ -340,6 +340,7 @@ static long __fastcall InvenWieldHook_Script(fo::GameObject* critter, fo::GameOb } } BeginHook(); + argCount = 5; args[0] = (DWORD)critter; 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[4] = isRemove; - argCount = 5; RunHookScript(HOOK_INVENWIELD); 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[4] = isRemove; - argCount = 5; RunHookScript(HOOK_INVENWIELD); bool result = (cRet == 0 || rets[0] == -1); @@ -377,6 +376,8 @@ static void __declspec(naked) InvenWieldFuncHook() { mov args[8], ebx; // slot pushad; } + argCount = 5; + // right hand slot? 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; @@ -402,10 +403,13 @@ static void __declspec(naked) InvenUnwieldFuncHook() { mov args[8], edx; // slot pushad; } + argCount = 5; + // set slot if (args[2] == 0) { // left hand slot? args[2] = fo::INVEN_TYPE_LEFT_HAND; } + // get item 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 pushadc; } + argCount = 5; + // set slot if (args[2] & fo::ObjectFlag::Right_Hand) { // right hand slot args[2] = fo::INVEN_TYPE_RIGHT_HAND; @@ -439,7 +445,9 @@ static void __declspec(naked) CorrectFidForRemovedItemHook() { } else { args[2] = fo::INVEN_TYPE_WORN; // armor slot } + InvenWieldHook_ScriptPart(0, 1); // unwield event (armor by default) + // engine handler is not overridden __asm { popadc; diff --git a/sfall/Modules/HookScripts/MiscHs.cpp b/sfall/Modules/HookScripts/MiscHs.cpp index 1a4be0f8..53605559 100644 --- a/sfall/Modules/HookScripts/MiscHs.cpp +++ b/sfall/Modules/HookScripts/MiscHs.cpp @@ -7,7 +7,6 @@ #include "MiscHs.h" -// Misc. hook scripts 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); BeginHook(); + argCount = 4; args[0] = (DWORD)watcher; args[1] = (DWORD)target; args[2] = result; args[3] = type; - argCount = 4; RunHookScript(HOOK_WITHINPERCEPTION); if (cRet > 0) result = rets[0]; @@ -338,6 +337,7 @@ static constexpr long maxGasAmount = 80000; static void CarTravelHook_Script() { BeginHook(); argCount = 2; + // calculate vanilla speed int carSpeed = 3; if (fo::func::game_get_global_var(fo::GVAR_CAR_BLOWER)) { @@ -426,18 +426,17 @@ static void __declspec(naked) SetGlobalVarHook() { } 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; + + BeginHook(); + argCount = 4; + + args[0] = gameTime; + args[2] = hours; + args[3] = minutes; + if (addrHook == 0x499CA1 || addrHook == 0x499B63) { args[0] = restTicks; args[1] = -1; @@ -458,19 +457,16 @@ static long __stdcall RestTimerHook_Script() { static void __declspec(naked) RestTimerLoopHook() { __asm { - push eax; - push edx; - push ecx; - push ebx; - mov ebx, [esp + 16]; - mov ecx, [esp + 20 + 0x40]; // hours_ + pushadc; mov edx, [esp + 20 + 0x44]; // minutes_ + mov ecx, [esp + 20 + 0x40]; // hours_ + push [esp + 16]; // addrHook + push eax; // gameTime call RestTimerHook_Script; - pop ebx; pop ecx; pop edx; - cmp eax, 0; - cmovge edi, eax; // return 1 to interrupt resting + test eax, eax; // result >= 0 + cmovge edi, eax; // return 1 to interrupt resting pop eax; jmp fo::funcoffs::set_game_time_; } @@ -481,19 +477,16 @@ static void __declspec(naked) RestTimerEscapeHook() { mov edi, 1; // engine code cmp eax, 0x1B; // ESC ASCII code jnz skip; - push eax; - push edx; - push ecx; - push ebx; - mov ebx, [esp + 16]; - mov ecx, [esp + 20 + 0x40]; // hours_ + pushadc; mov edx, [esp + 20 + 0x44]; // minutes_ + mov ecx, [esp + 20 + 0x40]; // hours_ + push [esp + 16]; // addrHook + push eax; // gameTime call RestTimerHook_Script; - pop ebx; pop ecx; pop edx; - cmp eax, 0; - cmovge edi, eax; // return 0 for cancel ESC key + test eax, eax; // result >= 0 + cmovge edi, eax; // return 0 for cancel ESC key pop eax; skip: retn;