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:
NovaRain
2019-07-15 09:59:58 +08:00
parent f53aa16923
commit fc3b7180af
5 changed files with 100 additions and 91 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
;sfall configuration settings
;v3.8.19
;v3.8.20
[Main]
;Change to 1 if you want to use command line args to tell sfall to use another ini file.
+25
View 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 bool showItemDescription = false;
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
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
dlog("Applying fix for displaying ammo stats in barter screen.", DL_INIT);
MakeCall(0x49B4AD, obj_examine_func_hack_ammo0, 2);
+15 -8
View File
@@ -79,19 +79,26 @@ struct TGameObj
struct TComputeAttack
{
TGameObj* attacker;
char gap_4[4];
long hitMode;
TGameObj* weapon;
char gap_C[4];
long damageAttacker;
long flagsAttacker;
long rounds;
char gap_1C[4];
long field_C;
long attackerDamage;
long attackerFlags;
long numRounds;
long message;
TGameObj* target;
long targetTile;
long bodyPart;
long damageTarget;
long flagsTarget;
long targetDamage;
long targetFlags;
long knockbackValue;
TGameObj* mainTarget;
long numExtras;
TGameObj* extraTarget[6];
long extraBodyPart[6];
long extraDamage[6];
long extraFlags[6];
long extraKnockbackValue[6];
};
#pragma pack(pop)
+53 -76
View File
@@ -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 {
push edx;
push ebx;
push eax;
push ecx;
push ebx; // store dmg multiplier args[8]
push edx; // store num of rounds args[9]
push eax; // store ctd
call compute_damage_;
pop edx;
//zero damage insta death criticals fix
mov ebx, [edx+0x2c];
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;
pop ecx; // restore ctd (eax)
pop edx; // restore num of rounds
call ComputeDamageHook_Script; // stack - arg multiplier
pop ecx;
retn;
}
}
@@ -1486,14 +1463,14 @@ static void HookScriptInit2() {
HookCall(0x4109BF, &CalcDeathAnimHook2);
LoadHookScript("hs_combatdamage", HOOK_COMBATDAMAGE);
HookCall(0x42326C, &CombatDamageHook); // check_ranged_miss()
HookCall(0x4233E3, &CombatDamageHook); // shoot_along_path() - for extra burst targets
HookCall(0x423AB7, &CombatDamageHook); // compute_attack()
HookCall(0x423BBF, &CombatDamageHook); // compute_attack()
HookCall(0x423DE7, &CombatDamageHook); // compute_explosion_on_extras()
HookCall(0x423E69, &CombatDamageHook); // compute_explosion_on_extras()
HookCall(0x424220, &CombatDamageHook); // attack_crit_failure()
HookCall(0x4242FB, &CombatDamageHook); // attack_crit_failure()
HookCall(0x42326C, ComputeDamageHook); // check_ranged_miss()
HookCall(0x4233E3, ComputeDamageHook); // shoot_along_path() - for extra burst targets
HookCall(0x423AB7, ComputeDamageHook); // compute_attack()
HookCall(0x423BBF, ComputeDamageHook); // compute_attack()
HookCall(0x423DE7, ComputeDamageHook); // compute_explosion_on_extras()
HookCall(0x423E69, ComputeDamageHook); // compute_explosion_on_extras()
HookCall(0x424220, ComputeDamageHook); // attack_crit_failure()
HookCall(0x4242FB, ComputeDamageHook); // attack_crit_failure()
LoadHookScript("hs_ondeath", HOOK_ONDEATH);
HookCall(0x4130CC, &OnDeathHook);
+3 -3
View File
@@ -24,13 +24,13 @@
#define VERSION_MAJOR 3
#define VERSION_MINOR 8
#define VERSION_BUILD 19
#define VERSION_BUILD 20
#define VERSION_REV 0
#ifdef WIN2K
#define VERSION_STRING "3.8.19 win2k"
#define VERSION_STRING "3.8.20 win2k"
#else
#define VERSION_STRING "3.8.19"
#define VERSION_STRING "3.8.20"
#endif
//#define CHECK_VAL (4)