mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Removed the dependency of Body_Torso from Body_Uncalled hit modifier
Re-added BodyHit_Torso to ddraw.ini. Reverted set_bodypart_hit_modifier function to pre-3.7.4 behavior.
This commit is contained in:
+4
-1
@@ -349,14 +349,17 @@ SaveInCombatFix=1
|
|||||||
AdditionalWeaponAnims=1
|
AdditionalWeaponAnims=1
|
||||||
|
|
||||||
;Uncomment these lines to modify the default modifiers for aimed shots at specific bodyparts
|
;Uncomment these lines to modify the default modifiers for aimed shots at specific bodyparts
|
||||||
|
;Modifiers affect both NPCs and the player
|
||||||
;BodyHit_Head=-40
|
;BodyHit_Head=-40
|
||||||
;BodyHit_Left_Arm=-30
|
;BodyHit_Left_Arm=-30
|
||||||
;BodyHit_Right_Arm=-30
|
;BodyHit_Right_Arm=-30
|
||||||
;BodyHit_Torso_Uncalled=0
|
;BodyHit_Torso=0
|
||||||
;BodyHit_Right_Leg=-20
|
;BodyHit_Right_Leg=-20
|
||||||
;BodyHit_Left_Leg=-20
|
;BodyHit_Left_Leg=-20
|
||||||
;BodyHit_Eyes=-60
|
;BodyHit_Eyes=-60
|
||||||
;BodyHit_Groin=-30
|
;BodyHit_Groin=-30
|
||||||
|
;The modifier for unaimed shots
|
||||||
|
;BodyHit_Torso_Uncalled=0
|
||||||
|
|
||||||
;Set to 1 to use a CriticalOverrides.ini file to override the default critical table
|
;Set to 1 to use a CriticalOverrides.ini file to override the default critical table
|
||||||
;Set to 2 to use the default critical with bug fixes (doesn't require an ini)
|
;Set to 2 to use the default critical with bug fixes (doesn't require an ini)
|
||||||
|
|||||||
@@ -2,6 +2,16 @@
|
|||||||
#ifndef DEFINE_EXTRA_H
|
#ifndef DEFINE_EXTRA_H
|
||||||
#define DEFINE_EXTRA_H
|
#define DEFINE_EXTRA_H
|
||||||
|
|
||||||
|
#define BODY_HIT_HEAD (0)
|
||||||
|
#define BODY_HIT_LEFT_ARM (1)
|
||||||
|
#define BODY_HIT_RIGHT_ARM (2)
|
||||||
|
#define BODY_HIT_TORSO (3)
|
||||||
|
#define BODY_HIT_RIGHT_LEG (4)
|
||||||
|
#define BODY_HIT_LEFT_LEG (5)
|
||||||
|
#define BODY_HIT_EYES (6)
|
||||||
|
#define BODY_HIT_GROIN (7)
|
||||||
|
#define BODY_UNCALLED (8)
|
||||||
|
|
||||||
#define OBJ_TYPE_ITEM (0)
|
#define OBJ_TYPE_ITEM (0)
|
||||||
#define OBJ_TYPE_CRITTER (1)
|
#define OBJ_TYPE_CRITTER (1)
|
||||||
#define OBJ_TYPE_SCENERY (2)
|
#define OBJ_TYPE_SCENERY (2)
|
||||||
|
|||||||
@@ -30,14 +30,14 @@
|
|||||||
namespace sfall
|
namespace sfall
|
||||||
{
|
{
|
||||||
|
|
||||||
static std::vector<long> noBursts; // object id
|
|
||||||
|
|
||||||
struct KnockbackModifier {
|
struct KnockbackModifier {
|
||||||
long id;
|
long id;
|
||||||
DWORD type;
|
DWORD type;
|
||||||
double value;
|
double value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static std::vector<long> noBursts; // object id
|
||||||
|
|
||||||
static std::vector<KnockbackModifier> mTargets;
|
static std::vector<KnockbackModifier> mTargets;
|
||||||
static std::vector<KnockbackModifier> mAttackers;
|
static std::vector<KnockbackModifier> mAttackers;
|
||||||
static std::vector<KnockbackModifier> mWeapons;
|
static std::vector<KnockbackModifier> mWeapons;
|
||||||
@@ -391,6 +391,39 @@ void _stdcall ForceAimedShots(DWORD pid) {
|
|||||||
forcedAS.push_back(pid);
|
forcedAS.push_back(pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const DWORD bodypartAddr[] = {
|
||||||
|
0x425562, // combat_display_
|
||||||
|
0x42A68F, 0x42A739, // ai_called_shot_
|
||||||
|
0x429E82, 0x429EC2, 0x429EFF, // ai_pick_hit_mode_
|
||||||
|
0x423231, 0x423268, // check_ranged_miss_
|
||||||
|
0x4242D4, // attack_crit_failure_
|
||||||
|
// for combat_ctd_init_ func
|
||||||
|
0x412E9C, // action_explode_
|
||||||
|
0x413519, // action_dmg_
|
||||||
|
0x421656, 0x421675, // combat_safety_invalidate_weapon_func_
|
||||||
|
0x421CC0, // combat_begin_extra_
|
||||||
|
0x4229A9, // combat_turn_
|
||||||
|
0x42330E, 0x4233AB, // shoot_along_path_
|
||||||
|
0x423E25, 0x423E2A, // compute_explosion_on_extras_
|
||||||
|
0x425F83, // combat_anim_finished_
|
||||||
|
0x42946D, // ai_best_weapon_
|
||||||
|
0x46FCC8, // exit_inventory_
|
||||||
|
0x49C00C, // protinstTestDroppedExplosive_
|
||||||
|
};
|
||||||
|
|
||||||
|
static void BodypartHitChances() {
|
||||||
|
using fo::var::hit_location_penalty;
|
||||||
|
hit_location_penalty[0] = static_cast<long>(GetConfigInt("Misc", "BodyHit_Head", -40));
|
||||||
|
hit_location_penalty[1] = static_cast<long>(GetConfigInt("Misc", "BodyHit_Left_Arm", -30));
|
||||||
|
hit_location_penalty[2] = static_cast<long>(GetConfigInt("Misc", "BodyHit_Right_Arm", -30));
|
||||||
|
hit_location_penalty[3] = static_cast<long>(GetConfigInt("Misc", "BodyHit_Torso", 0));
|
||||||
|
hit_location_penalty[4] = static_cast<long>(GetConfigInt("Misc", "BodyHit_Right_Leg", -20));
|
||||||
|
hit_location_penalty[5] = static_cast<long>(GetConfigInt("Misc", "BodyHit_Left_Leg", -20));
|
||||||
|
hit_location_penalty[6] = static_cast<long>(GetConfigInt("Misc", "BodyHit_Eyes", -60));
|
||||||
|
hit_location_penalty[7] = static_cast<long>(GetConfigInt("Misc", "BodyHit_Groin", -30));
|
||||||
|
hit_location_penalty[8] = static_cast<long>(GetConfigInt("Misc", "BodyHit_Torso_Uncalled", 0));
|
||||||
|
}
|
||||||
|
|
||||||
static void Combat_OnGameLoad() {
|
static void Combat_OnGameLoad() {
|
||||||
baseHitChance.SetDefault();
|
baseHitChance.SetDefault();
|
||||||
mTargets.clear();
|
mTargets.clear();
|
||||||
@@ -418,6 +451,14 @@ void Combat::init() {
|
|||||||
HookCall(0x42A95D, ai_try_attack_hook); // jz func
|
HookCall(0x42A95D, ai_try_attack_hook); // jz func
|
||||||
MakeCall(0x4234B3, compute_spray_hack, 1);
|
MakeCall(0x4234B3, compute_spray_hack, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove the dependency of Body_Torso from Body_Uncalled
|
||||||
|
SafeWrite8(0x423830, 0xEB); // compute_attack_
|
||||||
|
BlockCall(0x42303F); // block Body_Torso check (combat_attack_)
|
||||||
|
SafeWrite8(0x42A713, 7); // Body_Uncalled > Body_Groin (ai_called_shot_)
|
||||||
|
SafeWriteBatch<BYTE>(8, bodypartAddr); // replace Body_Torso with Body_Uncalled
|
||||||
|
LoadGameHook::OnBeforeGameStart() += BodypartHitChances; // set on start & load
|
||||||
|
|
||||||
LoadGameHook::OnGameReset() += Combat_OnGameLoad;
|
LoadGameHook::OnGameReset() += Combat_OnGameLoad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ struct ChanceModifier {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void _stdcall SetHitChanceMax(fo::GameObject* critter, DWORD maximum, DWORD mod);
|
void _stdcall SetHitChanceMax(fo::GameObject* critter, DWORD maximum, DWORD mod);
|
||||||
void _stdcall KnockbackSetMod(fo::GameObject* object, DWORD type, float val, DWORD on);
|
void _stdcall KnockbackSetMod(fo::GameObject* object, DWORD type, float val, DWORD mode);
|
||||||
void _stdcall KnockbackRemoveMod(fo::GameObject* object, DWORD on);
|
void _stdcall KnockbackRemoveMod(fo::GameObject* object, DWORD mode);
|
||||||
|
|
||||||
void _stdcall SetNoBurstMode(fo::GameObject* critter, bool on);
|
void _stdcall SetNoBurstMode(fo::GameObject* critter, bool on);
|
||||||
void _stdcall DisableAimedShots(DWORD pid);
|
void _stdcall DisableAimedShots(DWORD pid);
|
||||||
|
|||||||
@@ -774,19 +774,6 @@ void UseWalkDistancePatch() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BodypartHitChances() {
|
|
||||||
using fo::var::hit_location_penalty;
|
|
||||||
hit_location_penalty[0] = static_cast<long>(GetConfigInt("Misc", "BodyHit_Head", -40));
|
|
||||||
hit_location_penalty[1] = static_cast<long>(GetConfigInt("Misc", "BodyHit_Left_Arm", -30));
|
|
||||||
hit_location_penalty[2] = static_cast<long>(GetConfigInt("Misc", "BodyHit_Right_Arm", -30));
|
|
||||||
hit_location_penalty[3] = static_cast<long>(GetConfigInt("Misc", "BodyHit_Torso_Uncalled", 0));
|
|
||||||
hit_location_penalty[4] = static_cast<long>(GetConfigInt("Misc", "BodyHit_Right_Leg", -20));
|
|
||||||
hit_location_penalty[5] = static_cast<long>(GetConfigInt("Misc", "BodyHit_Left_Leg", -20));
|
|
||||||
hit_location_penalty[6] = static_cast<long>(GetConfigInt("Misc", "BodyHit_Eyes", -60));
|
|
||||||
hit_location_penalty[7] = static_cast<long>(GetConfigInt("Misc", "BodyHit_Groin", -30));
|
|
||||||
hit_location_penalty[8] = static_cast<long>(GetConfigInt("Misc", "BodyHit_Torso_Uncalled", 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MiscPatches::init() {
|
void MiscPatches::init() {
|
||||||
mapName[64] = 0;
|
mapName[64] = 0;
|
||||||
if (GetConfigString("Misc", "StartingMap", "", mapName, 64)) {
|
if (GetConfigString("Misc", "StartingMap", "", mapName, 64)) {
|
||||||
@@ -860,8 +847,6 @@ void MiscPatches::init() {
|
|||||||
// Increase the max text width of the information card in the character screen
|
// Increase the max text width of the information card in the character screen
|
||||||
SafeWriteBatch<BYTE>(144, {0x43ACD5, 0x43DD37}); // 136, 133
|
SafeWriteBatch<BYTE>(144, {0x43ACD5, 0x43DD37}); // 136, 133
|
||||||
|
|
||||||
LoadGameHook::OnBeforeGameStart() += BodypartHitChances; // set on start & load
|
|
||||||
|
|
||||||
CombatProcFix();
|
CombatProcFix();
|
||||||
DialogueFix();
|
DialogueFix();
|
||||||
AdditionalWeaponAnimsPatch();
|
AdditionalWeaponAnimsPatch();
|
||||||
|
|||||||
@@ -1427,8 +1427,8 @@ void Perks::init() {
|
|||||||
enginePerkMod = GetPrivateProfileIntA("PerksTweak", "WeaponHandlingBonus", -1, perksFile);
|
enginePerkMod = GetPrivateProfileIntA("PerksTweak", "WeaponHandlingBonus", -1, perksFile);
|
||||||
if (enginePerkMod >= 0 && enginePerkMod != 3) {
|
if (enginePerkMod >= 0 && enginePerkMod != 3) {
|
||||||
if (enginePerkMod > 10) enginePerkMod = 10;
|
if (enginePerkMod > 10) enginePerkMod = 10;
|
||||||
SafeWrite8(0x424636, static_cast<char>(enginePerkMod));
|
SafeWrite8(0x424636, static_cast<signed char>(enginePerkMod));
|
||||||
SafeWrite8(0x4251CE, static_cast<char>(-enginePerkMod));
|
SafeWrite8(0x4251CE, static_cast<signed char>(-enginePerkMod));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LoadGameHook::OnGameReset() += PerksReset;
|
LoadGameHook::OnGameReset() += PerksReset;
|
||||||
|
|||||||
@@ -466,12 +466,12 @@ void sf_inc_npc_level(OpcodeContext& ctx) {
|
|||||||
|
|
||||||
// restore code
|
// restore code
|
||||||
SafeWrite32(0x495C50, 0x01FB840F);
|
SafeWrite32(0x495C50, 0x01FB840F);
|
||||||
SafeWrite16(0x495C77, 0x8C0F);
|
long long data = 0x01D48C0F;
|
||||||
SafeWrite32(0x495C79, 0x000001D4);
|
SafeWriteBytes(0x495C77, (BYTE*)&data, 6);
|
||||||
//SafeWrite16(0x495C8C, 0x8D0F);
|
//SafeWrite16(0x495C8C, 0x8D0F);
|
||||||
//SafeWrite32(0x495C8E, 0x000001BF);
|
//SafeWrite32(0x495C8E, 0x000001BF);
|
||||||
SafeWrite16(0x495CEC, 0x850F);
|
data = 0x0130850F;
|
||||||
SafeWrite32(0x495CEE, 0x00000130);
|
SafeWriteBytes(0x495CEC, (BYTE*)&data, 6);
|
||||||
if (!npcAutoLevelEnabled) {
|
if (!npcAutoLevelEnabled) {
|
||||||
SafeWrite8(0x495CFB, 0x74);
|
SafeWrite8(0x495CFB, 0x74);
|
||||||
}
|
}
|
||||||
@@ -640,10 +640,10 @@ void __declspec(naked) op_get_bodypart_hit_modifier() {
|
|||||||
call fo::funcoffs::interpretPopLong_
|
call fo::funcoffs::interpretPopLong_
|
||||||
cmp dx, VAR_TYPE_INT
|
cmp dx, VAR_TYPE_INT
|
||||||
jnz fail
|
jnz fail
|
||||||
cmp eax, 8 // Body_Uncalled?
|
|
||||||
jg fail
|
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jl fail
|
jl fail
|
||||||
|
cmp eax, 8 // Body_Uncalled?
|
||||||
|
jg fail
|
||||||
mov edx, ds:[FO_VAR_hit_location_penalty+eax*4]
|
mov edx, ds:[FO_VAR_hit_location_penalty+eax*4]
|
||||||
jmp end
|
jmp end
|
||||||
fail:
|
fail:
|
||||||
@@ -679,19 +679,11 @@ void __declspec(naked) op_set_bodypart_hit_modifier() {
|
|||||||
jnz end
|
jnz end
|
||||||
cmp cx, VAR_TYPE_INT
|
cmp cx, VAR_TYPE_INT
|
||||||
jnz end
|
jnz end
|
||||||
cmp eax, 8 // Body_Uncalled?
|
|
||||||
jg end
|
|
||||||
cmp eax, 3 // Body_Torso?
|
|
||||||
jne skip // No
|
|
||||||
add eax, 5
|
|
||||||
skip:
|
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jl end
|
jl end
|
||||||
mov ds:[FO_VAR_hit_location_penalty+eax*4], ebx
|
|
||||||
cmp eax, 8 // Body_Uncalled?
|
cmp eax, 8 // Body_Uncalled?
|
||||||
jne end // No
|
jg end
|
||||||
sub eax, 5 // Body_Torso
|
mov ds:[FO_VAR_hit_location_penalty+eax*4], ebx
|
||||||
jmp skip
|
|
||||||
end:
|
end:
|
||||||
pop edx
|
pop edx
|
||||||
pop ecx
|
pop ecx
|
||||||
|
|||||||
Reference in New Issue
Block a user