From 62f890d28782789050740671766043dc9de19415 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Sat, 7 Sep 2019 20:16:50 +0800 Subject: [PATCH] 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. --- artifacts/ddraw.ini | 5 ++- artifacts/scripting/headers/define_extra.h | 10 +++++ sfall/Combat.cpp | 46 +++++++++++++++++++++- sfall/FalloutEngine.cpp | 2 +- sfall/FalloutEngine.h | 2 +- sfall/ScriptExtender.cpp | 16 ++------ sfall/ScriptOps/MiscOps.hpp | 24 ++++------- 7 files changed, 71 insertions(+), 34 deletions(-) diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index 4a7789b2..74bd4988 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -332,14 +332,17 @@ SaveInCombatFix=1 AdditionalWeaponAnims=1 ;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_Left_Arm=-30 ;BodyHit_Right_Arm=-30 -;BodyHit_Torso_Uncalled=0 +;BodyHit_Torso=0 ;BodyHit_Right_Leg=-20 ;BodyHit_Left_Leg=-20 ;BodyHit_Eyes=-60 ;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 2 to use the default critical with bug fixes (doesn't require an ini) diff --git a/artifacts/scripting/headers/define_extra.h b/artifacts/scripting/headers/define_extra.h index 55151784..a606e4b6 100644 --- a/artifacts/scripting/headers/define_extra.h +++ b/artifacts/scripting/headers/define_extra.h @@ -2,6 +2,16 @@ #ifndef 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_CRITTER (1) #define OBJ_TYPE_SCENERY (2) diff --git a/sfall/Combat.cpp b/sfall/Combat.cpp index 5fc28819..f4a6824e 100644 --- a/sfall/Combat.cpp +++ b/sfall/Combat.cpp @@ -27,14 +27,14 @@ #include "Combat.h" -static std::vector noBursts; // object id - struct KnockbackModifier { long id; DWORD type; double value; }; +static std::vector noBursts; // object id + static std::vector mTargets; static std::vector mAttackers; static std::vector mWeapons; @@ -395,6 +395,38 @@ void _stdcall ForceAimedShots(DWORD 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() { + ptr_hit_location_penalty[0] = static_cast(GetPrivateProfileIntA("Misc", "BodyHit_Head", -40, ini)); + ptr_hit_location_penalty[1] = static_cast(GetPrivateProfileIntA("Misc", "BodyHit_Left_Arm", -30, ini)); + ptr_hit_location_penalty[2] = static_cast(GetPrivateProfileIntA("Misc", "BodyHit_Right_Arm", -30, ini)); + ptr_hit_location_penalty[3] = static_cast(GetPrivateProfileIntA("Misc", "BodyHit_Torso", 0, ini)); + ptr_hit_location_penalty[4] = static_cast(GetPrivateProfileIntA("Misc", "BodyHit_Right_Leg", -20, ini)); + ptr_hit_location_penalty[5] = static_cast(GetPrivateProfileIntA("Misc", "BodyHit_Left_Leg", -20, ini)); + ptr_hit_location_penalty[6] = static_cast(GetPrivateProfileIntA("Misc", "BodyHit_Eyes", -60, ini)); + ptr_hit_location_penalty[7] = static_cast(GetPrivateProfileIntA("Misc", "BodyHit_Groin", -30, ini)); + ptr_hit_location_penalty[8] = static_cast(GetPrivateProfileIntA("Misc", "BodyHit_Torso_Uncalled", 0, ini)); +} + void Combat_OnGameLoad() { baseHitChance.maximum = 95; baseHitChance.mod = 0; @@ -405,6 +437,8 @@ void Combat_OnGameLoad() { noBursts.clear(); disabledAS.clear(); forcedAS.clear(); + + BodypartHitChances(); // was in ClearGlobalScripts() } void CombatInit() { @@ -423,4 +457,12 @@ void CombatInit() { HookCall(0x42A95D, ai_try_attack_hook); // jz func 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_) + for (int i = 0; i < sizeof(bodypartAddr) / 4; i++) { // replace Body_Torso with Body_Uncalled + SafeWrite8(bodypartAddr[i], 8); + } } diff --git a/sfall/FalloutEngine.cpp b/sfall/FalloutEngine.cpp index 584c6ca7..131ac910 100644 --- a/sfall/FalloutEngine.cpp +++ b/sfall/FalloutEngine.cpp @@ -79,7 +79,7 @@ DWORD* ptr_gmouse_current_cursor = reinterpret_cast(_gmouse_current DWORD* ptr_gmovie_played_list = reinterpret_cast(_gmovie_played_list); DWORD* ptr_GreenColor = reinterpret_cast(_GreenColor); DWORD* ptr_gsound_initialized = reinterpret_cast(_gsound_initialized); -DWORD* ptr_hit_location_penalty = reinterpret_cast(_hit_location_penalty); +long* ptr_hit_location_penalty = reinterpret_cast(_hit_location_penalty); DWORD* ptr_holo_flag = reinterpret_cast(_holo_flag); DWORD* ptr_holopages = reinterpret_cast(_holopages); DWORD* ptr_hot_line_count = reinterpret_cast(_hot_line_count); diff --git a/sfall/FalloutEngine.h b/sfall/FalloutEngine.h index f6f86cf3..80f13a54 100644 --- a/sfall/FalloutEngine.h +++ b/sfall/FalloutEngine.h @@ -321,7 +321,7 @@ extern DWORD* ptr_gmouse_current_cursor; extern DWORD* ptr_gmovie_played_list; extern DWORD* ptr_GreenColor; extern DWORD* ptr_gsound_initialized; -extern DWORD* ptr_hit_location_penalty; +extern long* ptr_hit_location_penalty; extern DWORD* ptr_holo_flag; extern DWORD* ptr_holopages; extern DWORD* ptr_hot_line_count; diff --git a/sfall/ScriptExtender.cpp b/sfall/ScriptExtender.cpp index 6d913f8b..28c2c562 100644 --- a/sfall/ScriptExtender.cpp +++ b/sfall/ScriptExtender.cpp @@ -1878,26 +1878,16 @@ void ClearGlobalScripts() { globalExportedVars.clear(); HookScriptClear(); + //Stat ranges + StatsReset(); //Reset some settable game values back to the defaults //xp mod SafeWrite8(0x4AFAB8, 0x53); SafeWrite32(0x4AFAB9, 0x55575651); //HP bonus SafeWrite8(0x4AFBC1, 2); - //Stat ranges - StatsReset(); - //Bodypart hit chances - *((DWORD*)0x510954) = GetPrivateProfileIntA("Misc", "BodyHit_Head", 0xFFFFFFD8, ini); - *((DWORD*)0x510958) = GetPrivateProfileIntA("Misc", "BodyHit_Left_Arm", 0xFFFFFFE2, ini); - *((DWORD*)0x51095C) = GetPrivateProfileIntA("Misc", "BodyHit_Right_Arm", 0xFFFFFFE2, ini); - *((DWORD*)0x510960) = GetPrivateProfileIntA("Misc", "BodyHit_Torso_Uncalled", 0x00000000, ini); - *((DWORD*)0x510964) = GetPrivateProfileIntA("Misc", "BodyHit_Right_Leg", 0xFFFFFFEC, ini); - *((DWORD*)0x510968) = GetPrivateProfileIntA("Misc", "BodyHit_Left_Leg", 0xFFFFFFEC, ini); - *((DWORD*)0x51096C) = GetPrivateProfileIntA("Misc", "BodyHit_Eyes", 0xFFFFFFC4, ini); - *((DWORD*)0x510970) = GetPrivateProfileIntA("Misc", "BodyHit_Groin", 0xFFFFFFE2, ini); - *((DWORD*)0x510974) = GetPrivateProfileIntA("Misc", "BodyHit_Torso_Uncalled", 0x00000000, ini); //skill points per level mod - SafeWrite8(0x43C27a, 5); + SafeWrite8(0x43C27A, 5); } void RunScriptProcByNum(DWORD sptr, DWORD procNum) { diff --git a/sfall/ScriptOps/MiscOps.hpp b/sfall/ScriptOps/MiscOps.hpp index deca404e..40c51a95 100644 --- a/sfall/ScriptOps/MiscOps.hpp +++ b/sfall/ScriptOps/MiscOps.hpp @@ -521,12 +521,12 @@ static void _stdcall IncNPCLevel2() { // restore code SafeWrite32(0x495C50, 0x01FB840F); - SafeWrite16(0x495C77, 0x8C0F); - SafeWrite32(0x495C79, 0x000001D4); + long long data = 0x01D48C0F; + SafeWriteBytes(0x495C77, (BYTE*)&data, 6); //SafeWrite16(0x495C8C, 0x8D0F); //SafeWrite32(0x495C8E, 0x000001BF); - SafeWrite16(0x495CEC, 0x850F); - SafeWrite32(0x495CEE, 0x00000130); + data = 0x0130850F; + SafeWriteBytes(0x495CEC, (BYTE*)&data, 6); if (!npcAutoLevelEnabled) { SafeWrite8(0x495CFB, 0x74); } @@ -767,10 +767,10 @@ static void __declspec(naked) GetBodypartHitModifier() { call interpretPopLong_ cmp dx, VAR_TYPE_INT jnz fail - cmp eax, 8 // Body_Uncalled? - jg fail test eax, eax jl fail + cmp eax, 8 // Body_Uncalled? + jg fail mov edx, ds:[_hit_location_penalty+eax*4] jmp end fail: @@ -806,19 +806,11 @@ static void __declspec(naked) SetBodypartHitModifier() { jnz end cmp cx, VAR_TYPE_INT jnz end - cmp eax, 8 // Body_Uncalled? - jg end - cmp eax, 3 // Body_Torso? - jne skip // No - add eax, 5 -skip: test eax, eax jl end - mov ds:[_hit_location_penalty+eax*4], ebx cmp eax, 8 // Body_Uncalled? - jne end // No - sub eax, 5 // Body_Torso - jmp skip + jg end + mov ds:[_hit_location_penalty+eax*4], ebx end: pop edx pop ecx