mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Backported the code of COMBATDAMAGE hook from 4.x
Moved instadeath crit fix from COMBATDAMAGE hook to BugFixes.cpp. Completed the compute_attack struct. Updated version number.
This commit is contained in:
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
;sfall configuration settings
|
;sfall configuration settings
|
||||||
;v3.8.19
|
;v3.8.20
|
||||||
|
|
||||||
[Main]
|
[Main]
|
||||||
;Change to 1 if you want to use command line args to tell sfall to use another ini file.
|
;Change to 1 if you want to use command line args to tell sfall to use another ini file.
|
||||||
|
|||||||
@@ -1440,6 +1440,26 @@ end:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//zero damage insta death criticals fix (moved from compute_damage hook)
|
||||||
|
static void __fastcall InstantDeathFix(TComputeAttack &ctd) {
|
||||||
|
if (ctd.targetDamage == 0 && (ctd.targetFlags & DAM_DEAD)) {
|
||||||
|
ctd.targetDamage++; // set 1 hp damage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const DWORD ComputeDamageRet = 0x424BA7;
|
||||||
|
static void __declspec(naked) compute_damage_hack() {
|
||||||
|
__asm {
|
||||||
|
mov ecx, esi; // ctd
|
||||||
|
call InstantDeathFix;
|
||||||
|
// overwritten engine code
|
||||||
|
add esp, 0x34;
|
||||||
|
pop ebp;
|
||||||
|
pop edi;
|
||||||
|
jmp ComputeDamageRet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int currDescLen = 0;
|
static int currDescLen = 0;
|
||||||
static bool showItemDescription = false;
|
static bool showItemDescription = false;
|
||||||
static void __stdcall AppendText(const char* text, const char* desc) {
|
static void __stdcall AppendText(const char* text, const char* desc) {
|
||||||
@@ -2573,6 +2593,11 @@ void BugFixesInit()
|
|||||||
// in their AI packages is set to stay_close/charge, or NPCsTryToSpendExtraAP is enabled
|
// in their AI packages is set to stay_close/charge, or NPCsTryToSpendExtraAP is enabled
|
||||||
HookCall(0x42A1A8, ai_move_steps_closer_hook); // 0x42B24D
|
HookCall(0x42A1A8, ai_move_steps_closer_hook); // 0x42B24D
|
||||||
|
|
||||||
|
// Fix instant death critical
|
||||||
|
dlog("Applying instant death fix.", DL_INIT);
|
||||||
|
MakeJump(0x424BA2, compute_damage_hack);
|
||||||
|
dlogr(" Done", DL_INIT);
|
||||||
|
|
||||||
// Fix missing AC/DR mod stats when examining ammo in the barter screen
|
// Fix missing AC/DR mod stats when examining ammo in the barter screen
|
||||||
dlog("Applying fix for displaying ammo stats in barter screen.", DL_INIT);
|
dlog("Applying fix for displaying ammo stats in barter screen.", DL_INIT);
|
||||||
MakeCall(0x49B4AD, obj_examine_func_hack_ammo0, 2);
|
MakeCall(0x49B4AD, obj_examine_func_hack_ammo0, 2);
|
||||||
|
|||||||
+15
-8
@@ -79,19 +79,26 @@ struct TGameObj
|
|||||||
struct TComputeAttack
|
struct TComputeAttack
|
||||||
{
|
{
|
||||||
TGameObj* attacker;
|
TGameObj* attacker;
|
||||||
char gap_4[4];
|
long hitMode;
|
||||||
TGameObj* weapon;
|
TGameObj* weapon;
|
||||||
char gap_C[4];
|
long field_C;
|
||||||
long damageAttacker;
|
long attackerDamage;
|
||||||
long flagsAttacker;
|
long attackerFlags;
|
||||||
long rounds;
|
long numRounds;
|
||||||
char gap_1C[4];
|
long message;
|
||||||
TGameObj* target;
|
TGameObj* target;
|
||||||
long targetTile;
|
long targetTile;
|
||||||
long bodyPart;
|
long bodyPart;
|
||||||
long damageTarget;
|
long targetDamage;
|
||||||
long flagsTarget;
|
long targetFlags;
|
||||||
long knockbackValue;
|
long knockbackValue;
|
||||||
|
TGameObj* mainTarget;
|
||||||
|
long numExtras;
|
||||||
|
TGameObj* extraTarget[6];
|
||||||
|
long extraBodyPart[6];
|
||||||
|
long extraDamage[6];
|
||||||
|
long extraFlags[6];
|
||||||
|
long extraKnockbackValue[6];
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
|||||||
+53
-76
@@ -366,76 +366,53 @@ skip:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __declspec(naked) CombatDamageHook() {
|
// 4.x backport
|
||||||
|
static void __fastcall ComputeDamageHook_Script(TComputeAttack &ctd, DWORD rounds, DWORD multiplier) {
|
||||||
|
BeginHook();
|
||||||
|
argCount = 12;
|
||||||
|
|
||||||
|
args[0] = (DWORD)ctd.target; // Target
|
||||||
|
args[1] = (DWORD)ctd.attacker; // Attacker
|
||||||
|
args[2] = ctd.targetDamage; // amountTarget
|
||||||
|
args[3] = ctd.attackerDamage; // amountSource
|
||||||
|
args[4] = ctd.targetFlags; // flagsTarget
|
||||||
|
args[5] = ctd.attackerFlags; // flagsSource
|
||||||
|
args[6] = (DWORD)ctd.weapon;
|
||||||
|
args[7] = ctd.bodyPart;
|
||||||
|
args[8] = multiplier; // damage multiplier
|
||||||
|
args[9] = rounds; // number of rounds
|
||||||
|
args[10] = ctd.knockbackValue;
|
||||||
|
args[11] = ctd.hitMode; // attack type
|
||||||
|
|
||||||
|
RunHookScript(HOOK_COMBATDAMAGE);
|
||||||
|
|
||||||
|
if (cRet > 0) {
|
||||||
|
ctd.targetDamage = rets[0];
|
||||||
|
if (cRet > 1) {
|
||||||
|
ctd.attackerDamage = rets[1];
|
||||||
|
if (cRet > 2) {
|
||||||
|
ctd.targetFlags = rets[2]; // flagsTarget
|
||||||
|
if (cRet > 3) {
|
||||||
|
ctd.attackerFlags = rets[3]; // flagsSource
|
||||||
|
if (cRet > 4) ctd.knockbackValue = rets[4];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EndHook();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __declspec(naked) ComputeDamageHook() {
|
||||||
__asm {
|
__asm {
|
||||||
push edx;
|
push ecx;
|
||||||
push ebx;
|
push ebx; // store dmg multiplier args[8]
|
||||||
push eax;
|
push edx; // store num of rounds args[9]
|
||||||
|
push eax; // store ctd
|
||||||
call compute_damage_;
|
call compute_damage_;
|
||||||
pop edx;
|
pop ecx; // restore ctd (eax)
|
||||||
|
pop edx; // restore num of rounds
|
||||||
//zero damage insta death criticals fix
|
call ComputeDamageHook_Script; // stack - arg multiplier
|
||||||
mov ebx, [edx+0x2c];
|
pop ecx;
|
||||||
test ebx, ebx;
|
|
||||||
jnz hookscript;
|
|
||||||
mov ebx, [edx+0x30];
|
|
||||||
test bl, 0x80;
|
|
||||||
jz hookscript;
|
|
||||||
inc dword ptr ds:[edx+0x2c];
|
|
||||||
hookscript:
|
|
||||||
hookbegin(12);
|
|
||||||
mov ebx, [edx+0x20];
|
|
||||||
mov args[0x00], ebx;
|
|
||||||
mov ebx, [edx+0x00];
|
|
||||||
mov args[0x04], ebx;
|
|
||||||
mov ebx, [edx+0x2c];
|
|
||||||
mov args[0x08], ebx;
|
|
||||||
mov ebx, [edx+0x10];
|
|
||||||
mov args[0x0c], ebx;
|
|
||||||
mov ebx, [edx+0x30];
|
|
||||||
mov args[0x10], ebx;
|
|
||||||
mov ebx, [edx+0x14];
|
|
||||||
mov args[0x14], ebx;
|
|
||||||
mov ebx, [edx+0x08];
|
|
||||||
mov args[0x18], ebx;
|
|
||||||
mov ebx, [edx+0x28];
|
|
||||||
mov args[0x1c], ebx;
|
|
||||||
pop ebx; // roll result
|
|
||||||
mov args[0x20], ebx;
|
|
||||||
pop ebx; // num rounds
|
|
||||||
mov args[0x24], ebx;
|
|
||||||
mov ebx, [edx+0x34]; // knockback value
|
|
||||||
mov args[0x28], ebx;
|
|
||||||
mov ebx, [edx+0x04]; // attack type
|
|
||||||
mov args[0x2c], ebx;
|
|
||||||
|
|
||||||
pushad;
|
|
||||||
push HOOK_COMBATDAMAGE;
|
|
||||||
call RunHookScript;
|
|
||||||
popad;
|
|
||||||
|
|
||||||
cmp cRet, 1;
|
|
||||||
jl end;
|
|
||||||
mov ebx, rets[0x00];
|
|
||||||
mov [edx+0x2c], ebx;
|
|
||||||
cmp cRet, 2;
|
|
||||||
jl end;
|
|
||||||
mov ebx, rets[0x04];
|
|
||||||
mov [edx+0x10], ebx;
|
|
||||||
cmp cRet, 3;
|
|
||||||
jl end;
|
|
||||||
mov ebx, rets[0x08];
|
|
||||||
mov [edx+0x30], ebx;
|
|
||||||
cmp cRet, 4;
|
|
||||||
jl end;
|
|
||||||
mov ebx, rets[0x0c];
|
|
||||||
mov [edx+0x14], ebx;
|
|
||||||
cmp cRet, 5;
|
|
||||||
jl end;
|
|
||||||
mov ebx, rets[0x10];
|
|
||||||
mov [edx+0x34], ebx; // knockback
|
|
||||||
end:
|
|
||||||
hookend;
|
|
||||||
retn;
|
retn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1486,14 +1463,14 @@ static void HookScriptInit2() {
|
|||||||
HookCall(0x4109BF, &CalcDeathAnimHook2);
|
HookCall(0x4109BF, &CalcDeathAnimHook2);
|
||||||
|
|
||||||
LoadHookScript("hs_combatdamage", HOOK_COMBATDAMAGE);
|
LoadHookScript("hs_combatdamage", HOOK_COMBATDAMAGE);
|
||||||
HookCall(0x42326C, &CombatDamageHook); // check_ranged_miss()
|
HookCall(0x42326C, ComputeDamageHook); // check_ranged_miss()
|
||||||
HookCall(0x4233E3, &CombatDamageHook); // shoot_along_path() - for extra burst targets
|
HookCall(0x4233E3, ComputeDamageHook); // shoot_along_path() - for extra burst targets
|
||||||
HookCall(0x423AB7, &CombatDamageHook); // compute_attack()
|
HookCall(0x423AB7, ComputeDamageHook); // compute_attack()
|
||||||
HookCall(0x423BBF, &CombatDamageHook); // compute_attack()
|
HookCall(0x423BBF, ComputeDamageHook); // compute_attack()
|
||||||
HookCall(0x423DE7, &CombatDamageHook); // compute_explosion_on_extras()
|
HookCall(0x423DE7, ComputeDamageHook); // compute_explosion_on_extras()
|
||||||
HookCall(0x423E69, &CombatDamageHook); // compute_explosion_on_extras()
|
HookCall(0x423E69, ComputeDamageHook); // compute_explosion_on_extras()
|
||||||
HookCall(0x424220, &CombatDamageHook); // attack_crit_failure()
|
HookCall(0x424220, ComputeDamageHook); // attack_crit_failure()
|
||||||
HookCall(0x4242FB, &CombatDamageHook); // attack_crit_failure()
|
HookCall(0x4242FB, ComputeDamageHook); // attack_crit_failure()
|
||||||
|
|
||||||
LoadHookScript("hs_ondeath", HOOK_ONDEATH);
|
LoadHookScript("hs_ondeath", HOOK_ONDEATH);
|
||||||
HookCall(0x4130CC, &OnDeathHook);
|
HookCall(0x4130CC, &OnDeathHook);
|
||||||
|
|||||||
+3
-3
@@ -24,13 +24,13 @@
|
|||||||
|
|
||||||
#define VERSION_MAJOR 3
|
#define VERSION_MAJOR 3
|
||||||
#define VERSION_MINOR 8
|
#define VERSION_MINOR 8
|
||||||
#define VERSION_BUILD 19
|
#define VERSION_BUILD 20
|
||||||
#define VERSION_REV 0
|
#define VERSION_REV 0
|
||||||
|
|
||||||
#ifdef WIN2K
|
#ifdef WIN2K
|
||||||
#define VERSION_STRING "3.8.19 win2k"
|
#define VERSION_STRING "3.8.20 win2k"
|
||||||
#else
|
#else
|
||||||
#define VERSION_STRING "3.8.19"
|
#define VERSION_STRING "3.8.20"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//#define CHECK_VAL (4)
|
//#define CHECK_VAL (4)
|
||||||
|
|||||||
Reference in New Issue
Block a user