Backported the code of DeathAnim1/2 hook from 4.x

Updated hookscripts.txt to reflect the change.
This commit is contained in:
NovaRain
2020-04-01 10:57:54 +08:00
parent 136404a723
commit bc2e8e4362
3 changed files with 70 additions and 84 deletions
+1
View File
@@ -132,6 +132,7 @@ int arg1 - The pid of the weapon performing the attack. (May be -1 if the at
critter arg2 - The attacker critter arg2 - The attacker
critter arg3 - The target critter arg3 - The target
int arg4 - The amount of damage int arg4 - The amount of damage
int arg5 - Unused, always -1 (since sfall 3.8.24)
int ret1 - The pid of an object to override the attacking weapon with int ret1 - The pid of an object to override the attacking weapon with
+1 -1
View File
@@ -3115,7 +3115,7 @@ void BugFixesInit()
// Radiation fixes // Radiation fixes
MakeCall(0x42D6C3, process_rads_hack, 1); // prevents player's death if a stat is less than 1 when removing radiation effects MakeCall(0x42D6C3, process_rads_hack, 1); // prevents player's death if a stat is less than 1 when removing radiation effects
HookCall(0x42D67A, process_rads_hook); // fix for the same message being displayed when removing radiation effects HookCall(0x42D67A, process_rads_hook); // fix for the same effect message being displayed when removing radiation effects
radEffectsMsgNum = GetConfigInt("Misc", "RadEffectsRemovalMsg", radEffectsMsgNum); radEffectsMsgNum = GetConfigInt("Misc", "RadEffectsRemovalMsg", radEffectsMsgNum);
// Display messages about radiation for the active geiger counter // Display messages about radiation for the active geiger counter
if (GetConfigInt("Misc", "ActiveGeigerMsgs", 1)) { if (GetConfigInt("Misc", "ActiveGeigerMsgs", 1)) {
+64 -79
View File
@@ -281,97 +281,82 @@ end:
} }
} }
// 4.x backport
static DWORD __fastcall CalcDeathAnimHook_Script(DWORD damage, TGameObj* target, TGameObj* attacker, TGameObj* weapon, int animation, int hitBack) {
BeginHook();
argCount = 5; // was 4
args[1] = (DWORD)attacker;
args[2] = (DWORD)target;
args[3] = damage;
// weapon_ptr
args[0] = (weapon) ? weapon->pid : -1; // attack is unarmed
bool createNewObj = false;
args[4] = -1; // set 'no anim' for combined hooks use
RunHookScript(HOOK_DEATHANIM1);
if (cRet > 0) {
DWORD pid = rets[0];
args[0] = pid; // replace for HOOK_DEATHANIM2
TGameObj* object = nullptr;
if (ObjPidNew((TGameObj*)&object, pid) != -1) { // create new object
createNewObj = true;
weapon = object; // replace pointer with newly created weapon object
}
cRet = 0; // reset rets from HOOK_DEATHANIM1
}
DWORD animDeath = PickDeath(attacker, target, weapon, damage, animation, hitBack); // vanilla pick death
//argCount = 5;
args[4] = animDeath;
RunHookScript(HOOK_DEATHANIM2);
if (cRet > 0) animDeath = rets[0];
EndHook();
if (createNewObj) ObjEraseObject(weapon, 0); // delete created object
return animDeath;
}
static void __declspec(naked) CalcDeathAnimHook() { static void __declspec(naked) CalcDeathAnimHook() {
__asm { __asm {
HookBeginArgs(4); push ecx;
mov args[24], ebx; push edx;
test ebx, ebx; push [esp + 4 + 12]; // hit_from_back
jz noweap push [esp + 4 + 12]; // animation
mov ebx, [ebx + 0x64]; push ebx; // weapon_ptr
and ebx, 0xFFF; push eax; // attacker
jmp weapend; call CalcDeathAnimHook_Script; // ecx - damage, edx - target
noweap: pop edx;
dec ebx; pop ecx;
weapend:
mov args[0], ebx;
mov ebx, args[24];
mov args[4], eax;
mov args[8], edx;
mov args[12], ecx;
mov args[20], 0;
pushad;
push HOOK_DEATHANIM1;
call RunHookScript;
cmp cRet, 1;
jl end1;
sub esp, 4;
mov edx, rets[0];
mov args[0], edx;
mov eax, esp;
call obj_pid_new_;
add esp, 4;
cmp eax, -1;
jz end1;
mov eax, [esp-4];
mov args[20], 1;
mov args[24], eax;
end1:
popad;
mov eax, [esp + 8];
mov ebx, [esp + 4];
push eax;
push ebx;
mov eax, args[4];
mov ebx, args[24];
call pick_death_;
mov args[16], eax;
mov eax, args[16];
mov argCount, 5;
pushad;
push HOOK_DEATHANIM2;
call RunHookScript;
popad;
cmp cRet, 1;
jl skip2;
mov eax, rets[0];
mov args[16], eax;
skip2:
mov eax, args[16];
push eax;
mov eax, args[20];
test eax, eax;
jz aend;
mov eax, args[24];
xor edx, edx;
call obj_erase_object_;
aend:
pop eax;
HookEnd;
retn 8; retn 8;
} }
} }
static void __declspec(naked) CalcDeathAnimHook2() { static void __declspec(naked) CalcDeathAnim2Hook() {
__asm { __asm {
HookBeginArgs(5);
call check_death_; // call original function call check_death_; // call original function
mov args[0], -1; // weaponPid, -1 HookBegin;
mov ebx, [esp + 60]; mov ebx, [esp + 60];
mov args[4], ebx; // attacker mov args[4], ebx; // attacker
mov args[8], esi; // target mov args[8], esi; // target
mov ebx, [esp + 12] mov ebx, [esp + 12];
mov args[12], ebx; // dmgAmount mov args[12], ebx; // dmgAmount
mov args[16], eax; // calculated animID mov args[16], eax; // calculated animID
pushad; pushad;
push HOOK_DEATHANIM2; }
call RunHookScript;
argCount = 5;
args[0] = -1; // weaponPid
RunHookScript(HOOK_DEATHANIM2);
__asm {
popad; popad;
cmp cRet, 1; cmp cRet, 1;
jl skip; cmovnb eax, rets[0];
mov eax, rets[0];
mov args[16], eax;
skip:
mov eax, args[16];
HookEnd; HookEnd;
retn; retn;
} }
@@ -1634,10 +1619,10 @@ static void HookScriptInit2() {
LoadHookScript("hs_deathanim1", HOOK_DEATHANIM1); LoadHookScript("hs_deathanim1", HOOK_DEATHANIM1);
LoadHookScript("hs_deathanim2", HOOK_DEATHANIM2); LoadHookScript("hs_deathanim2", HOOK_DEATHANIM2);
HookCall(0x4109DE, &CalcDeathAnimHook); // show_damage_to_object_ HookCall(0x4109DE, CalcDeathAnimHook); // show_damage_to_object_
HookCall(0x410981, &CalcDeathAnimHook2); // show_damage_to_object_ HookCall(0x410981, CalcDeathAnim2Hook); // show_damage_to_object_
HookCall(0x4109A1, &CalcDeathAnimHook2); // show_damage_to_object_ HookCall(0x4109A1, CalcDeathAnim2Hook); // show_damage_to_object_
HookCall(0x4109BF, &CalcDeathAnimHook2); // show_damage_to_object_ HookCall(0x4109BF, CalcDeathAnim2Hook); // show_damage_to_object_
LoadHookScript("hs_combatdamage", HOOK_COMBATDAMAGE); LoadHookScript("hs_combatdamage", HOOK_COMBATDAMAGE);
HookCall(0x42326C, ComputeDamageHook); // check_ranged_miss() HookCall(0x42326C, ComputeDamageHook); // check_ranged_miss()