mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added new HOOK_SUBCOMBATDAMAGE and refactored damage formulas code in AmmoMod.cpp (from Mr.Stalin)
This commit is contained in:
+1
-1
@@ -372,7 +372,7 @@ NPCsTryToSpendExtraAP=0
|
||||
;Note that enabling this option can significantly affect the weapon choice of some NPCs in combat
|
||||
AIBestWeaponFix=0
|
||||
|
||||
;Set to 1 to fix NPCs not checking chem_primary_desire setting in AI.txt for drug use preference
|
||||
;Set to 1 to fix NPCs not taking chem_primary_desire in AI.txt as drug use preference when using drugs in their inventory
|
||||
AIDrugUsePerfFix=0
|
||||
|
||||
;Allows the use of tiles over 80*36 in size. sfall will just split and resave them at startup
|
||||
|
||||
@@ -267,4 +267,49 @@
|
||||
#define WPN_ANIM_MINIGUN (0x09) // (L)
|
||||
#define WPN_ANIM_ROCKET_LAUNCHER (0x0A) // (M)
|
||||
|
||||
// Compute attack result fields
|
||||
#define C_ATTACK_SOURCE (0x00)
|
||||
#define C_ATTACK_HIT_MODE (0x04)
|
||||
#define C_ATTACK_WEAPON (0x08)
|
||||
#define C_ATTACK_DAMAGE_SOURCE (0x10) // Amount
|
||||
#define C_ATTACK_FLAGS_SOURCE (0x14) // see DAM_* values in define.h
|
||||
#define C_ATTACK_ROUNDS (0x18)
|
||||
#define C_ATTACK_TARGET (0x20)
|
||||
#define C_ATTACK_BODY_PART (0x28)
|
||||
#define C_ATTACK_DAMAGE_TARGET (0x2C) // Amount
|
||||
#define C_ATTACK_FLAGS_TARGET (0x30) // see DAM_*
|
||||
#define C_ATTACK_KNOCKBACK_VALUE (0x34)
|
||||
#define C_ATTACK_MAIN_TARGET (0x38)
|
||||
#define C_ATTACK_AROUND_NUMBER (0x3C) // The number of critters around the target
|
||||
#define C_ATTACK_TARGET1 (0x40)
|
||||
#define C_ATTACK_TARGET2 (0x44)
|
||||
#define C_ATTACK_TARGET3 (0x48)
|
||||
#define C_ATTACK_TARGET4 (0x4C)
|
||||
#define C_ATTACK_TARGET5 (0x50)
|
||||
#define C_ATTACK_TARGET6 (0x54)
|
||||
#define C_ATTACK_BODY_PART1 (0x58)
|
||||
#define C_ATTACK_BODY_PART2 (0x5C)
|
||||
#define C_ATTACK_BODY_PART3 (0x60)
|
||||
#define C_ATTACK_BODY_PART4 (0x64)
|
||||
#define C_ATTACK_BODY_PART5 (0x68)
|
||||
#define C_ATTACK_BODY_PART6 (0x6C)
|
||||
#define C_ATTACK_DAMAGE_TARGET1 (0x70) // Amount
|
||||
#define C_ATTACK_DAMAGE_TARGET2 (0x74)
|
||||
#define C_ATTACK_DAMAGE_TARGET3 (0x78)
|
||||
#define C_ATTACK_DAMAGE_TARGET4 (0x7C)
|
||||
#define C_ATTACK_DAMAGE_TARGET5 (0x80)
|
||||
#define C_ATTACK_DAMAGE_TARGET6 (0x84)
|
||||
#define C_ATTACK_FLAGS_TARGET1 (0x88) // see DAM_*
|
||||
#define C_ATTACK_FLAGS_TARGET2 (0x8C)
|
||||
#define C_ATTACK_FLAGS_TARGET3 (0x90)
|
||||
#define C_ATTACK_FLAGS_TARGET4 (0x94)
|
||||
#define C_ATTACK_FLAGS_TARGET5 (0x98)
|
||||
#define C_ATTACK_FLAGS_TARGET6 (0x9C)
|
||||
#define C_ATTACK_KNOCKBACK_VALUE1 (0xA0)
|
||||
#define C_ATTACK_KNOCKBACK_VALUE2 (0xA4)
|
||||
#define C_ATTACK_KNOCKBACK_VALUE3 (0xA8)
|
||||
#define C_ATTACK_KNOCKBACK_VALUE4 (0xAC)
|
||||
#define C_ATTACK_KNOCKBACK_VALUE5 (0xB0)
|
||||
#define C_ATTACK_KNOCKBACK_VALUE6 (0xB4)
|
||||
|
||||
#endif // DEFINE_EXTRA_H
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
#define HOOK_DESCRIPTIONOBJ (34)
|
||||
#define HOOK_USESKILLON (35)
|
||||
#define HOOK_ONEXPLOSION (36)
|
||||
#define HOOK_SUBCOMBATDAMAGE (37)
|
||||
|
||||
//Valid arguments to list_begin
|
||||
#define LIST_CRITTERS (0)
|
||||
|
||||
@@ -166,7 +166,7 @@ int arg5 - The special effect flags for the target (use bwand DAM_* to chec
|
||||
int arg6 - The special effect flags for the attacker (use bwand DAM_* to check specific flags)
|
||||
int arg7 - The weapon used in the attack
|
||||
int arg8 - The bodypart that was struck
|
||||
int arg9 - Damage Multiplier (this is divided by 2, so a value of 3 does 1.5x damage, and 8 does 4x damage. Usually it's 2, but with Silent Death perk and the corresponding attack conditions, it's 4; for critical hits, the value is taken from the critical table)
|
||||
int arg9 - Damage Multiplier (this is divided by 2, so a value of 3 does 1.5x damage, and 8 does 4x damage. Usually it's 2; for critical hits, the value is taken from the critical table; with Silent Death perk and the corresponding attack conditions, the value will be doubled)
|
||||
int arg10 - Number of bullets actually hit the target (1 for melee attacks)
|
||||
int arg11 - The amount of knockback to the target
|
||||
int arg12 - Attack Type (see ATKTYPE_* constants)
|
||||
@@ -434,7 +434,7 @@ HOOK_INVENWIELD (hs_invenwield.int)
|
||||
Runs before wielding or unwielding an armor or a weapon by a critter (except when using inventory by PC).
|
||||
An example usage would be to change critter art depending on armor being used or to dynamically customize weapon animations.
|
||||
NOTE: when replacing a previously wielded armor or weapon, the unwielding hook will not be executed.
|
||||
If you need to rely on this, try checking if armor/weapon already equipped when wielding hook is executed.
|
||||
If you need to rely on this, try checking if armor/weapon is already equipped when wielding hook is executed.
|
||||
|
||||
Critter arg1 - critter
|
||||
Obj arg2 - item being wielded or unwielded (weapon/armor)
|
||||
@@ -578,3 +578,28 @@ Critter arg6 - The target critter, may be 0 or equal to the attacker
|
||||
int arg7 - 1 when using throwing weapons (e.g. grenades), 0 otherwise
|
||||
|
||||
int ret1 - overrides the found object on the checked tile, pass 0 to skip the object
|
||||
|
||||
-------------------------------------------
|
||||
|
||||
HOOK_SUBCOMBATDAMAGE (hs_subcombatdmg.int)
|
||||
|
||||
This hook overrides the vanilla damage calculation formula.
|
||||
Runs when:
|
||||
1) Before the game calculates how much damage each target will get. This includes primary target as well as all extras (explosions and bursts).
|
||||
2) AI decides whether it is safe to use area attack (burst, grenades), if he might hit friendlies.
|
||||
Does not run for misses, non-combat damage like dynamite explosions, or if one of the damage formulas is selected in ddraw.ini.
|
||||
|
||||
Critter arg1 - The attacker
|
||||
Critter arg2 - The target
|
||||
Obj arg3 - The weapon used in the attack
|
||||
int arg4 - Attack Type (see ATKTYPE_* constants)
|
||||
int arg5 - Number of bullets actually hit the target (1 for melee attacks)
|
||||
int arg6 - Target's Damage Resistance (DR) value (affected by critical hit effects, perks, traits, and special unarmed attacks)
|
||||
int arg7 - Target's Damage Threshold (DT) value (affected by critical hit effects, perks, traits, and special unarmed attacks)
|
||||
int arg8 - Bonus ranged damage from the perk
|
||||
int arg9 - Damage Multiplier (this is divided by 2, so a value of 3 does 1.5x damage, and 8 does 4x damage. Usually it's 2; for critical hits, the value is taken from the critical table; with Silent Death perk and the corresponding attack conditions, the value will be doubled)
|
||||
int arg10 - Combat Difficulty multiplier (125 - rough, 100 - normal, 75 - wimpy)
|
||||
int arg11 - The calculated amount of damage (usually 0, required when using multiple hook scripts to calculate damage and using the set_sfall_arg function)
|
||||
mixed arg12 - Computed attack results (see C_ATTACK_* for offsets and use read_int(arg12 + offset) to get the data)
|
||||
|
||||
int ret1 - The returned amount of damage
|
||||
|
||||
@@ -56,6 +56,10 @@ WRAP_WATCOM_FUNC1(long, item_w_anim_code, GameObject*, item)
|
||||
WRAP_WATCOM_FUNC2(long, item_w_anim_weap, GameObject*, item, DWORD, hitMode)
|
||||
WRAP_WATCOM_FUNC2(long, item_w_compute_ammo_cost, GameObject*, item, DWORD*, rounds)
|
||||
WRAP_WATCOM_FUNC1(long, item_w_curr_ammo, GameObject*, item)
|
||||
WRAP_WATCOM_FUNC2(long, item_w_damage, GameObject*, critter, long, hitMode)
|
||||
WRAP_WATCOM_FUNC1(long, item_w_dam_div, GameObject*, item)
|
||||
WRAP_WATCOM_FUNC1(long, item_w_dam_mult, GameObject*, item)
|
||||
WRAP_WATCOM_FUNC1(long, item_w_dr_adjust, GameObject*, item)
|
||||
WRAP_WATCOM_FUNC1(long, item_w_rounds, GameObject*, item)
|
||||
WRAP_WATCOM_FUNC1(long, item_w_max_ammo, GameObject*, item)
|
||||
WRAP_WATCOM_FUNC1(long, item_weight, GameObject*, item)
|
||||
|
||||
+104
-159
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "..\FalloutEngine\Fallout2.h"
|
||||
#include "..\Logging.h"
|
||||
#include "HookScripts.h"
|
||||
|
||||
#include "AmmoMod.h"
|
||||
|
||||
@@ -29,22 +30,25 @@ using namespace fo;
|
||||
|
||||
int AmmoMod::formula;
|
||||
|
||||
static const DWORD DamageFunctionReturn = 0x424A63;
|
||||
|
||||
// Damage Fix v5 (with v5.1 Damage Multiplier tweak) by Glovz 2014.04.16.xx.xx
|
||||
// TODO: remove or rewrite in C++
|
||||
static __declspec(naked) void DamageGlovz() {
|
||||
// TODO: rewrite in C++
|
||||
void AmmoMod::DamageGlovz(fo::ComputeAttackResult &ctd, DWORD* accumulatedDamage, int rounds, int armorDT, int armorDR, int bonusRangedDamage, int multiplyDamage, int difficulty) {
|
||||
if (rounds <= 0) return;
|
||||
|
||||
int ammoY = fo::func::item_w_dam_div(ctd.weapon); // ammoY value (divisor)
|
||||
int ammoX = fo::func::item_w_dam_mult(ctd.weapon); // ammoX value
|
||||
int ammoDRM = fo::func::item_w_dr_adjust(ctd.weapon); // ammoDRM value
|
||||
int mValue;
|
||||
|
||||
__asm {
|
||||
mov ebx, dword ptr ss:[esp + 0x1C]; // get the number of hits
|
||||
xor ecx, ecx; // set the loop counter to 0
|
||||
cmp ebx, 0; // compare the number of hits to 0
|
||||
jle end; // exit
|
||||
mov esi, ctd;
|
||||
mov edi, accumulatedDamage;
|
||||
begin:
|
||||
mov dword ptr ss:[esp + 0x30], 0; // clear value
|
||||
mov edx, dword ptr ds:[esi + 4]; // get pointer to weapon being used by an attacker (I think)
|
||||
mov mValue, 0; // clear value
|
||||
mov edx, dword ptr ds:[esi + 4]; // get the hit mode of weapon being used by an attacker
|
||||
mov eax, dword ptr ds:[esi]; // get pointer to critter attacking
|
||||
call fo::funcoffs::item_w_damage_; // get the raw damage value
|
||||
mov ebx, dword ptr ss:[esp + 0x18]; // get the bonus ranged damage value
|
||||
mov ebx, bonusRangedDamage; // get the bonus ranged damage value
|
||||
cmp ebx, 0; // compare the range bonus damage value to 0
|
||||
jle rdJmp; // if the RB value is less than or equal to 0 then goto rdJmp
|
||||
add eax, ebx; // add the RB value to the RD value
|
||||
@@ -52,47 +56,46 @@ rdJmp:
|
||||
cmp eax, 0; // compare the new damage value to 0
|
||||
jle noDamageJmp; // goto noDamageJmp
|
||||
mov ebx, eax; // set the ND value
|
||||
mov edx, dword ptr ss:[esp + 0x28]; // get the armorDT value
|
||||
mov edx, armorDT; // get the armorDT value
|
||||
cmp edx, 0; // compare the armorDT value to 0
|
||||
jle bJmp; // if the armorDT value is less than or equal to 0 then goto bJmp
|
||||
mov eax, dword ptr ds:[esi + 0x8]; // get pointer to critters ammo being used in their weapon (I think)
|
||||
call fo::funcoffs::item_w_dam_div_; // get the ammoY value
|
||||
mov eax, dword ptr ammoY; // get the ammoY value
|
||||
cmp eax, 0; // compare the ammoY value to 0
|
||||
jg aJmp; // if the ammoY value is greater than 0 then goto aJmp
|
||||
mov eax, 1; // set the ammoY value to 1
|
||||
aJmp:
|
||||
xor ebp, ebp; // clear value
|
||||
xor ecx, ecx; // clear value (old ebp)
|
||||
cmp edx, eax; // compare the dividend with the divisor
|
||||
jl lrThan; // the dividend is less than the divisor then goto lrThan
|
||||
jg grThan; // the dividend is greater than the divisor then goto grThan
|
||||
jmp setOne; // if the two values are equal then goto setOne
|
||||
lrThan:
|
||||
mov ebp, edx; // store the dividend value temporarily
|
||||
mov ecx, edx; // store the dividend value temporarily
|
||||
imul edx, 2; // multiply dividend value by 2
|
||||
sub edx, eax; // subtract divisor value from the dividend value
|
||||
cmp edx, 0; // compare the result to 0
|
||||
jl setZero; // if the result is less than 0 then goto setZero
|
||||
jg setOne; // if the result is greater than 0 then goto setOne
|
||||
mov edx, ebp; // restore dividend value
|
||||
mov edx, ecx; // restore dividend value
|
||||
and edx, 1; // if true (1) then odd if false (0) then even
|
||||
jz setZero; // if the result is equal to 0 then setZero
|
||||
jmp setOne; // if the result is not 0 then goto setOne
|
||||
grThan:
|
||||
mov ebp, eax; // assign the divisor value
|
||||
mov ecx, eax; // assign the divisor value
|
||||
xor eax, eax; // clear value
|
||||
bbbJmp:
|
||||
inc eax; // add 1 to the quotient value
|
||||
sub edx, ebp; // subtract the divisor value from the dividend value
|
||||
cmp edx, ebp; // compare the remainder value to the divisor value
|
||||
sub edx, ecx; // subtract the divisor value from the dividend value
|
||||
cmp edx, ecx; // compare the remainder value to the divisor value
|
||||
jge bbbJmp; // if the remainder value is greater or equal to the divisor value then goto bbbJmp
|
||||
jz endDiv; // if the remainder value is equal to 0 then goto endDiv
|
||||
imul edx, 2; // multiply temp remainder value by 2
|
||||
sub edx, ebp; // subtract the divisor value from the temp remainder
|
||||
sub edx, ecx; // subtract the divisor value from the temp remainder
|
||||
cmp edx, 0; // compare the result to 0
|
||||
jl endDiv; // if the result is less than 0 then goto endDiv
|
||||
jg addOne; // if the result is greater than 0 then goto addOne
|
||||
mov ebp, eax; // assign the quotient value
|
||||
and ebp, 1; // if true (1) then odd if false (0) then even
|
||||
mov ecx, eax; // assign the quotient value
|
||||
and ecx, 1; // if true (1) then odd if false (0) then even
|
||||
jz endDiv; // if the result is equal to zero goto endDiv
|
||||
addOne:
|
||||
inc eax; // add 1 to the quotient value
|
||||
@@ -103,31 +106,31 @@ setOne:
|
||||
setZero:
|
||||
xor eax, eax; // clear value
|
||||
endDiv:
|
||||
cmp dword ptr ss:[esp + 0x30], 2; // compare value to 2
|
||||
cmp mValue, 2; // compare value to 2
|
||||
je divTwo; // goto divTwo
|
||||
cmp dword ptr ss:[esp + 0x30], 3; // compare value to 3
|
||||
cmp mValue, 3; // compare value to 3
|
||||
je divThree; // goto divThree
|
||||
cmp dword ptr ss:[esp + 0x30], 4; // compare value to 4
|
||||
cmp mValue, 4; // compare value to 4
|
||||
je divFour; // goto divFour
|
||||
cmp dword ptr ss:[esp + 0x30], 5; // compare value to 5
|
||||
cmp mValue, 5; // compare value to 5
|
||||
je divFive; // goto divFive
|
||||
cmp dword ptr ss:[esp + 0x30], 6; // compare value to 6
|
||||
cmp mValue, 6; // compare value to 6
|
||||
je divSix; // goto divSix
|
||||
cmp dword ptr ss:[esp + 0x30], 7; // compare value to 7
|
||||
cmp mValue, 7; // compare value to 7 (added for v5.1 tweak)
|
||||
je divSeven; // goto divSeven
|
||||
sub ebx, eax; // subtract the new armorDT value from the RD value
|
||||
jmp cJmp; // goto cJmp
|
||||
bJmp:
|
||||
mov edx, dword ptr ss:[esp + 0x2C]; // get the armorDR value
|
||||
mov edx, armorDR; // get the armorDR value
|
||||
cmp edx, 0; // compare the armorDR value to 0
|
||||
jle dJmp; // if the armorDR value is less than or equal to 0 then goto dJmp
|
||||
cJmp:
|
||||
cmp ebx, 0; // compare the new damage value to 0
|
||||
jle noDamageJmp; // goto noDamageJmp
|
||||
mov edx, dword ptr ss:[esp + 0x2C]; // get the armorDR value
|
||||
mov edx, armorDR; // get the armorDR value
|
||||
cmp edx, 0; // compare the armorDR value to 0
|
||||
jle eJmp; // if the armorDR value is less than or equal to 0 then goto eJmp
|
||||
mov eax, dword ptr ss:[esp + 0x20]; // get the CD value
|
||||
mov eax, difficulty; // get the CD value
|
||||
cmp eax, 100; // compare the CD value to 100
|
||||
jg sdrJmp; // if the CD value is greater than 100 then goto sdrJmp
|
||||
je aSubCJmp; // if the CD value is equal to 100 then goto aSubCJmp
|
||||
@@ -136,47 +139,43 @@ cJmp:
|
||||
sdrJmp:
|
||||
sub edx, 20; // subtract 20 from the armorDR value
|
||||
aSubCJmp:
|
||||
mov eax, dword ptr ds:[esi + 0x8]; // get pointer to ammo being used in the critters weapon (I think)
|
||||
call fo::funcoffs::item_w_dr_adjust_; // get the ammoDRM value
|
||||
mov eax, dword ptr ammoDRM; // get the ammoDRM value
|
||||
cmp eax, 0; // compare the ammoDRM value to 0
|
||||
jl adrJmp; // if the ammoDRM value is less than 0 then goto adrJmp
|
||||
je bSubCJmp; // if the ammoDRM value is equal to 0 then goto bSubCJmp
|
||||
xor ebp, ebp; // clear value
|
||||
sub ebp, eax; // subtract ammoDRM value from 0
|
||||
mov eax, ebp; // set new ammoDRM value
|
||||
xor ecx, ecx; // clear value
|
||||
sub ecx, eax; // subtract ammoDRM value from 0
|
||||
mov eax, ecx; // set new ammoDRM value
|
||||
adrJmp:
|
||||
add edx, eax; // add the ammoDRM value to the armorDR value
|
||||
bSubCJmp:
|
||||
mov eax, dword ptr ds:[esi + 0x8]; // get pointer to ammo being used in the critters weapon (I think)
|
||||
call fo::funcoffs::item_w_dam_mult_; // get the ammoX value
|
||||
mov eax, dword ptr ammoX; // get the ammoX value
|
||||
cmp eax, 0; // compare the ammoX value to 0
|
||||
jg cSubCJmp; // if the ammoX value is greater than 0 then goto cSubCJmp;
|
||||
mov eax, 1; // set the ammoX value to 1
|
||||
cSubCJmp:
|
||||
mov dword ptr ss:[esp + 0x30], 2; // set value to 2
|
||||
mov mValue, 2; // set value to 2
|
||||
jmp aJmp; // goto aJmp
|
||||
divTwo:
|
||||
mov edx, ebx; // set temp value
|
||||
imul edx, eax; // multiply the ND value by the armorDR value
|
||||
mov eax, 100; // set divisor value to 100
|
||||
mov dword ptr ss:[esp + 0x30], 3; // set value to 3
|
||||
mov mValue, 3; // set value to 3
|
||||
jmp aJmp; // goto aJmp
|
||||
divThree:
|
||||
sub ebx, eax; // subtract the damage resisted value from the ND value
|
||||
jmp eJmp; // goto eJmp
|
||||
dJmp:
|
||||
mov eax, dword ptr ds:[esi + 0x8]; // get pointer to ammo being used in the critters weapon (I think)
|
||||
call fo::funcoffs::item_w_dam_mult_; // get the ammoX value
|
||||
mov eax, dword ptr ammoX; // get the ammoX value
|
||||
cmp eax, 1; // compare the ammoX value to 1
|
||||
jle bSubDJmp; // if the ammoX value is less than or equal to 1 then goto bSubDJmp;
|
||||
mov eax, dword ptr ds:[esi + 0x8]; // get pointer to critters ammo being used in their weapon (I think)
|
||||
call fo::funcoffs::item_w_dam_div_; // get the ammoY value
|
||||
mov eax, dword ptr ammoY; // get the ammoY value
|
||||
cmp eax, 1; // compare the ammoY value to 1
|
||||
jle aSubDJmp; // if the ammoY value is less than or equal to 1 then goto aSubDJmp
|
||||
mov edx, ebx; // set temp value
|
||||
imul edx, 15; // multiply the ND value by 15
|
||||
mov eax, 100; // set divisor value to 100
|
||||
mov dword ptr ss:[esp + 0x30], 4; // set value to 4
|
||||
mov mValue, 4; // set value to 4
|
||||
jmp aJmp; // goto aJmp
|
||||
divFour:
|
||||
add ebx, eax; // add the quotient value to the ND value
|
||||
@@ -185,27 +184,26 @@ aSubDJmp:
|
||||
mov edx, ebx; // set temp value
|
||||
imul edx, 20; // multiply the ND value by 20
|
||||
mov eax, 100; // set divisor value to 100
|
||||
mov dword ptr ss:[esp + 0x30], 5; // set value to 5
|
||||
mov mValue, 5; // set value to 5
|
||||
jmp aJmp; // goto aJmp
|
||||
divFive:
|
||||
add ebx, eax; // add the quotient value to the ND value
|
||||
jmp eJmp; // goto eJmp
|
||||
bSubDJmp:
|
||||
mov eax, dword ptr ds:[esi + 0x8]; // get pointer to critters ammo being used in their weapon (I think)
|
||||
call fo::funcoffs::item_w_dam_div_; // get the ammoY value
|
||||
mov eax, dword ptr ammoY; // get the ammoY value
|
||||
cmp eax, 1; // compare the ammoY value to 1
|
||||
jle eJmp; // goto eJmp
|
||||
mov edx, ebx; // set temp value
|
||||
imul edx, 10; // multiply the ND value by 10
|
||||
mov eax, 100; // set divisor value to 100
|
||||
mov dword ptr ss:[esp + 0x30], 6; // set value to 6
|
||||
mov mValue, 6; // set value to 6
|
||||
jmp aJmp; // goto aJmp
|
||||
divSix:
|
||||
add ebx, eax; // add the quotient value to the ND value
|
||||
eJmp:
|
||||
cmp ebx, 0; // compare the new damage value to 0
|
||||
jle noDamageJmp; // goto noDamageJmp
|
||||
mov eax, dword ptr ss:[esp + 0x24]; // get the CM value
|
||||
mov eax, multiplyDamage; // get the Critical Multiplier (CM) value
|
||||
cmp eax, 2; // compare the CM value to 2
|
||||
jle addNDJmp; // if the CM value is less than or equal to 2 then goto addNDJmp
|
||||
cmp AmmoMod::formula, 2; // check selected damage formula (added for v5.1 tweak)
|
||||
@@ -219,7 +217,7 @@ tweak:
|
||||
imul edx, eax; // multiply the temp ND value by the CM value
|
||||
imul edx, 25; // multiply the temp ND value by 25
|
||||
mov eax, 100; // set divisor value to 100
|
||||
mov dword ptr ss:[esp + 0x30], 7; // set value to 7
|
||||
mov mValue, 7; // set value to 7
|
||||
jmp aJmp; // goto aJmp
|
||||
divSeven:
|
||||
add ebx, eax; // add the critical damage value to the ND value
|
||||
@@ -227,108 +225,59 @@ divSeven:
|
||||
addNDJmp:
|
||||
add dword ptr ds:[edi], ebx; // accumulate damage
|
||||
noDamageJmp:
|
||||
mov eax, dword ptr ss:[esp + 0x1C]; // get the number of hits
|
||||
inc ecx; // the counter value increments by one
|
||||
cmp ecx, eax; // is the counter value less than the number of hits
|
||||
jl begin; // goto begin
|
||||
end:
|
||||
jmp DamageFunctionReturn; // exit
|
||||
dec dword ptr rounds; // decrease the hit counter value by one
|
||||
jnz begin; // compare the number of hits to 0
|
||||
}
|
||||
}
|
||||
|
||||
// YAAM
|
||||
// TODO: rewrite in C++
|
||||
static __declspec(naked) void DamageYAAM() {
|
||||
__asm {
|
||||
mov eax, dword ptr ds:[esi + 0x8]; // Get pointer to critter's weapon
|
||||
mov edx, dword ptr ss:[esp + 0x24]; // Get Critical Multiplier (passed in as argument to function)
|
||||
call fo::funcoffs::item_w_dam_mult_; // Retrieve Ammo Dividend
|
||||
imul edx, eax; // Damage Multipler = Critical Multipler * Ammo Dividend
|
||||
mov eax, dword ptr ds:[esi + 0x8]; // Get pointer to critter's weapon
|
||||
call fo::funcoffs::item_w_dam_div_; // Retrieve Ammo Divisor
|
||||
imul ebp, eax; // Ammo Divisor = 1 * Ammo Divisor (ebp set to 1 earlier in function)
|
||||
mov ebx, dword ptr ss:[esp + 0x1C]; // Get number of hits
|
||||
xor ecx, ecx; // Set loop counter to zero
|
||||
mov dword ptr ss:[esp + 0x24], edx; // Store Damage Multiplier
|
||||
test ebx, ebx; // Is number of hits <= 0?
|
||||
jle end; // If yes, jump beyond damage calculation loop
|
||||
ajmp: // Start of damage calculation loop
|
||||
mov edx, dword ptr ds:[esi + 0x4]; // Get pointer to weapon (?)
|
||||
mov eax, dword ptr ds:[esi]; // Get pointer to critter (?)
|
||||
mov ebx, dword ptr ss:[esp + 0x18]; // Get Bonus Ranged Damage
|
||||
call fo::funcoffs::item_w_damage_; // Retrieve Raw Damage
|
||||
add ebx, eax; // Raw Damage = Raw Damage + Bonus Ranged Damage
|
||||
mov edx, dword ptr ss:[esp + 0x28]; // Get armor DT
|
||||
mov eax, dword ptr ds:[esi + 0x8]; // Get pointer to critter's weapon
|
||||
call fo::funcoffs::item_w_dr_adjust_; // Retrieve ammo DT (well, it's really Retrieve ammo DR, but since we're treating ammo DR as ammo DT...)
|
||||
sub edx, eax; // DT = armor DT - ammo DT
|
||||
test edx, edx; // Is DT >= 0?
|
||||
jge bjmp; // If yes, skip the next instruction
|
||||
xor edx, edx; // Otherwise, set DT = 0
|
||||
bjmp:
|
||||
sub ebx, edx; // Raw Damage = Raw Damage - DT
|
||||
test ebx, ebx; // Is Raw Damage <= 0?
|
||||
jle cjmp; // If yes, skip damage calculation and go to bottom of loop
|
||||
imul ebx, dword ptr ss:[esp + 0x24]; // Otherwise, Raw Damage = Raw Damage * Damage Multiplier
|
||||
test ebp, ebp; // Is Ammo Divisor == 0?
|
||||
je djmp; // If yes, avoid divide by zero error
|
||||
mov edx, ebx;
|
||||
mov eax, ebx;
|
||||
sar edx, 31;
|
||||
idiv ebp;
|
||||
mov ebx, eax; // Otherwise, Raw Damage = Raw Damage / Ammo Divisor
|
||||
djmp:
|
||||
mov edx, ebx;
|
||||
mov eax, ebx;
|
||||
sar edx, 31;
|
||||
sub eax, edx;
|
||||
sar eax, 1; // Raw Damage = Raw Damage / 2 (related to critical hit damage multiplier bonus)
|
||||
mov edx, dword ptr ss:[esp + 0x20]; // Get combat difficulty setting (75 if wimpy, 100 if normal or if attacker is player, 125 if rough)
|
||||
imul edx, eax; // Raw Damage = Raw Damage * combat difficulty setting
|
||||
mov ebx, 100;
|
||||
mov eax, edx;
|
||||
sar edx, 31;
|
||||
idiv ebx;
|
||||
mov ebx, eax; // Raw Damage = Raw Damage / 100
|
||||
mov edx, dword ptr ss:[esp + 0x28]; // Get armor DT
|
||||
mov eax, dword ptr ds:[esi + 0x8]; // Get pointer to critter's weapon
|
||||
call fo::funcoffs::item_w_dr_adjust_; // Retrieve ammo DT
|
||||
sub edx, eax; // DT = armor DT - ammo DT
|
||||
test edx, edx; // Is DT >= 0?
|
||||
jge ejmp; // If yes, set DT = 0
|
||||
mov eax, 10;
|
||||
imul eax, edx; // Otherwise, DT = DT * 10 (note that this should be a negative value)
|
||||
jmp fjmp;
|
||||
ejmp:
|
||||
xor eax, eax;
|
||||
fjmp:
|
||||
mov edx, dword ptr ss:[esp + 0x2C]; // Get armor DR
|
||||
add edx, eax; // DR = armor DR + DT (note that DT should be less than or equal to zero)
|
||||
test edx, edx; // Is DR >= 0?
|
||||
jge gjmp;
|
||||
xor edx, edx; // If no, set DR = 0
|
||||
jmp hjmp;
|
||||
gjmp:
|
||||
cmp edx, 100; // Otherwise, is DR >= 100?
|
||||
jge ijmp; // If yes, damage will be zero, so stop calculating and go to bottom of loop
|
||||
hjmp:
|
||||
imul edx, ebx; // Otherwise, Resisted Damage = DR * Raw Damage
|
||||
mov dword ptr ss:[esp + 0x30], 100;
|
||||
mov eax, edx;
|
||||
sar edx, 31;
|
||||
idiv dword ptr ss:[esp + 0x30]; // Resisted Damage = Resisted Damage / 100
|
||||
sub ebx, eax; // Raw Damage = Raw Damage - Resisted Damage
|
||||
cjmp:
|
||||
test ebx, ebx; // Is Raw Damage <= 0?
|
||||
jle ijmp; // If yes, don't accumulate damage
|
||||
add dword ptr ds:[edi], ebx; // Otherwise, Accumulated Damage = Accumulated Damage + Raw Damage
|
||||
ijmp:
|
||||
mov eax, dword ptr ss:[esp + 0x1C]; // Get number of hits
|
||||
inc ecx; // counter += 1
|
||||
cmp ecx, eax; // Is counter < number of hits?
|
||||
jl ajmp; // If yes, go back to start of damage calcuation loop (calculate damage for next hit)
|
||||
end:
|
||||
jmp DamageFunctionReturn; // Otherwise, exit loop
|
||||
void AmmoMod::DamageYAAM(fo::ComputeAttackResult &ctd, DWORD* accumulatedDamage, int rounds, int armorDT, int armorDR, int bonusRangedDamage,int multiplyDamage, int difficulty) {
|
||||
int ammoDiv = fo::func::item_w_dam_div(ctd.weapon); // Retrieve Ammo Divisor
|
||||
int ammoMult = fo::func::item_w_dam_mult(ctd.weapon); // Retrieve Ammo Dividend
|
||||
|
||||
multiplyDamage *= ammoMult; // Damage Multipler = Critical Multipler * Ammo Dividend
|
||||
int ammoDivisor = 1 * ammoDiv; // Ammo Divisor = 1 * Ammo Divisor
|
||||
|
||||
int ammoDT = fo::func::item_w_dr_adjust(ctd.weapon); // Retrieve ammo DT (well, it's really Retrieve ammo DR, but since we're treating ammo DR as ammo DT...)
|
||||
|
||||
// Start of damage calculation loop
|
||||
for (int i = 0; i < rounds; i++) { // Check number of hits
|
||||
int rawDamage = fo::func::item_w_damage(ctd.attacker, ctd.hitMode); // Retrieve Raw Damage
|
||||
rawDamage += bonusRangedDamage; // Raw Damage = Raw Damage + Bonus Ranged Damage
|
||||
|
||||
int calcDT = armorDT - ammoDT; // DT = armor DT - ammo DT
|
||||
if (calcDT < 0) calcDT = 0;
|
||||
|
||||
rawDamage -= calcDT; // Raw Damage = Raw Damage - DT
|
||||
if (rawDamage <= 0) continue; // Is Raw Damage <= 0? If yes, skip damage calculation and go to bottom of loop
|
||||
|
||||
rawDamage *= multiplyDamage; // Raw Damage = Raw Damage * Damage Multiplier
|
||||
if (ammoDivisor != 0) { // avoid divide by zero error
|
||||
rawDamage /= ammoDivisor; // Raw Damage = Raw Damage / Ammo Divisor
|
||||
}
|
||||
rawDamage /= 2; // Raw Damage = Raw Damage / 2 (related to critical hit damage multiplier bonus)
|
||||
rawDamage *= difficulty; // Raw Damage = Raw Damage * combat difficulty setting (75 if wimpy, 100 if normal or if attacker is player, 125 if rough)
|
||||
rawDamage /= 100; // Raw Damage = Raw Damage / 100
|
||||
|
||||
calcDT = armorDT - ammoDT; // DT = armor DT - ammo DT
|
||||
if (calcDT >= 0) { // Is DT >= 0?
|
||||
calcDT = 0; // If yes, set DT = 0
|
||||
} else {
|
||||
calcDT *= 10; // Otherwise, DT = DT * 10 (note that this should be a negative value)
|
||||
}
|
||||
|
||||
int calcDR = armorDR + calcDT; // DR = armor DR + DT (note that DT should be less than or equal to zero)
|
||||
if (calcDR >= 100) { // Is DR >= 100?
|
||||
continue; // If yes, damage will be zero, so stop calculating and go to bottom of loop
|
||||
} else if (calcDR < 0) { // Is DR >= 0?
|
||||
calcDR = 0; // If no, set DR = 0
|
||||
}
|
||||
|
||||
int resistedDamage = calcDR * rawDamage; // Otherwise, Resisted Damage = DR * Raw Damage
|
||||
resistedDamage /= 100; // Resisted Damage = Resisted Damage / 100
|
||||
rawDamage -= resistedDamage; // Raw Damage = Raw Damage - Resisted Damage
|
||||
|
||||
if (rawDamage > 0) *accumulatedDamage += rawDamage; // Accumulated Damage = Accumulated Damage + Raw Damage
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -446,17 +395,13 @@ void AmmoMod::init() {
|
||||
switch (formula) {
|
||||
case 1:
|
||||
case 2:
|
||||
MakeJump(0x424995, DamageGlovz);
|
||||
break;
|
||||
/*case 3:
|
||||
MakeJump(0x424995, DamageFunction3);
|
||||
break;
|
||||
case 4:
|
||||
MakeJump(0x424995, DamageFunction4);
|
||||
break;*/
|
||||
case 5:
|
||||
MakeJump(0x424995, DamageYAAM);
|
||||
if (!HookScripts::IsInjectHook(HOOK_SUBCOMBATDAMAGE)) {
|
||||
HookScripts::InjectingHook(HOOK_SUBCOMBATDAMAGE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
formula = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@ public:
|
||||
void init();
|
||||
|
||||
static int formula;
|
||||
static void DamageGlovz(fo::ComputeAttackResult &ctd, DWORD* accumulatedDamage, int rounds, int armorDT, int armorDR, int bonusRangedDamage, int multiplyDamage, int difficulty);
|
||||
static void DamageYAAM(fo::ComputeAttackResult &ctd, DWORD* accumulatedDamage, int rounds, int armorDT, int armorDR, int bonusRangedDamage,int multiplyDamage, int difficulty);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -2172,7 +2172,7 @@ void BugFixes::init()
|
||||
// Display a pop-up messages box about death from radiation
|
||||
HookCall(0x42D733, process_rads_hook);
|
||||
|
||||
// Fix for AI not checking chem_primary_desire setting in AI.txt for drug use preference
|
||||
// Fix for AI not taking chem_primary_desire in AI.txt as drug use preference when using drugs in their inventory
|
||||
if (GetConfigInt("Misc", "AIDrugUsePerfFix", 0)) {
|
||||
dlog("Applying AI drug use preference fix.", DL_INIT);
|
||||
MakeCall(0x42869D, ai_check_drugs_hack_break);
|
||||
|
||||
@@ -81,6 +81,7 @@ static HooksInjectInfo injectHooks[] = {
|
||||
{HOOK_DESCRIPTIONOBJ, Inject_DescriptionObjHook, false},
|
||||
{HOOK_USESKILLON, Inject_UseSkillOnHook, false},
|
||||
{HOOK_ONEXPLOSION, Inject_OnExplosionHook, false},
|
||||
{HOOK_SUBCOMBATDAMAGE, Inject_SubCombatDamageHook, false},
|
||||
};
|
||||
|
||||
bool HookScripts::injectAllHooks;
|
||||
|
||||
@@ -63,6 +63,7 @@ enum HookType
|
||||
HOOK_DESCRIPTIONOBJ = 34,
|
||||
HOOK_USESKILLON = 35,
|
||||
HOOK_ONEXPLOSION = 36,
|
||||
HOOK_SUBCOMBATDAMAGE = 37,
|
||||
HOOK_COUNT
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user