From cc2b95d64e1cf3446f381c351a1ecdd4912f5af5 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Tue, 16 Oct 2018 10:14:32 +0800 Subject: [PATCH] Added displaying party member's current level & AC & addict flag info to the combat control panel (from Mr.Stalin) Added additional notes to HOOK_COMBATDAMAGE in hookscripts.txt (#204) --- artifacts/config_files/Translations.ini | 3 ++ artifacts/scripting/hookscripts.txt | 4 +-- sfall/FalloutEngine.cpp | 16 +++++++++ sfall/FalloutEngine.h | 5 +++ sfall/PartyControl.cpp | 44 +++++++++++++++++++++++++ 5 files changed, 70 insertions(+), 2 deletions(-) diff --git a/artifacts/config_files/Translations.ini b/artifacts/config_files/Translations.ini index 5221ebe4..67dfd81b 100644 --- a/artifacts/config_files/Translations.ini +++ b/artifacts/config_files/Translations.ini @@ -7,6 +7,9 @@ HighlightFail2=Your motion sensor is out of charge. SuperStimExploitMsg=You cannot use a super stim on someone who is not injured! BlockedCombat=You cannot enter combat at this time. SaveSfallDataFail=ERROR saving extended savegame information! Check if other programs interfere with savegame files/folders and try again. +PartyLvlMsg=Lvl: +PartyACMsg=AC: +PartyAddictMsg=Addict [AppearanceMod] RaceText=Race diff --git a/artifacts/scripting/hookscripts.txt b/artifacts/scripting/hookscripts.txt index 975e8ea0..a02a99c4 100644 --- a/artifacts/scripting/hookscripts.txt +++ b/artifacts/scripting/hookscripts.txt @@ -162,8 +162,8 @@ critter arg1 - The target critter arg2 - The attacker int arg3 - The amount of damage to the target int arg4 - The amount of damage to the attacker -int arg5 - The special effect flags for the target -int arg6 - The special effect flags for the attacker +int arg5 - The special effect flags for the target (use bwand DAM_* to check specific flags) +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) diff --git a/sfall/FalloutEngine.cpp b/sfall/FalloutEngine.cpp index 07525f14..2554e107 100644 --- a/sfall/FalloutEngine.cpp +++ b/sfall/FalloutEngine.cpp @@ -933,3 +933,19 @@ void __stdcall DisplayTargetInventory(long inventoryOffset, long visibleOffset, call display_target_inventory_ } } + +long __stdcall StatLevel(TGameObj* critter, long statId) { + __asm { + mov edx, statId + mov eax, critter + call stat_level_ + } +} + +long __stdcall QueueFindFirst(TGameObj* object, long qType) { + __asm { + mov edx, qType + mov eax, object + call queue_find_first_ + } +} diff --git a/sfall/FalloutEngine.h b/sfall/FalloutEngine.h index 3a554c4e..66813708 100644 --- a/sfall/FalloutEngine.h +++ b/sfall/FalloutEngine.h @@ -60,6 +60,7 @@ #define _curr_pc_stat 0x6681AC #define _curr_stack 0x59E96C #define _cursor_line 0x664514 +#define _DarkGreenColor 0x6A3A90 #define _dialog_target 0x518848 #define _dialog_target_is_party 0x51884C #define _dialogue_state 0x518714 @@ -983,3 +984,7 @@ void __stdcall RedrawWin(DWORD winRef); void __stdcall DisplayInventory(long inventoryOffset, long visibleOffset, long mode); void __stdcall DisplayTargetInventory(long inventoryOffset, long visibleOffset, DWORD* targetInventory, long mode); + +long __stdcall StatLevel(TGameObj* critter, long statId); + +long __stdcall QueueFindFirst(TGameObj* object, long qType); diff --git a/sfall/PartyControl.cpp b/sfall/PartyControl.cpp index 94472453..844301d5 100644 --- a/sfall/PartyControl.cpp +++ b/sfall/PartyControl.cpp @@ -28,6 +28,7 @@ #include "main.h" #include "Define.h" #include "FalloutEngine.h" +#include "HeroAppearance.h" #include "PartyControl.h" #if (_MSC_VER < 1600) #include "Cpp11_emu.h" @@ -346,6 +347,43 @@ end: } } +static char levelMsg[12], armorClassMsg[12], addictMsg[16]; +static void __fastcall PartyMemberPrintStat(BYTE* surface, DWORD toWidth) { + const char* fmt = "%s %d"; + char lvlMsg[16], acMsg[16]; + + TGameObj* partyMember = (TGameObj*)*ptr_dialog_target; + int xPos = 350; + + int level = PartyMemberGetCurrentLevel(partyMember); + sprintf_s(lvlMsg, fmt, levelMsg, level); + + BYTE color = *(BYTE*)_GreenColor; + int widthText = GetTextWidth(lvlMsg); + PrintText(lvlMsg, color, xPos - widthText, 96, widthText, toWidth, surface); + + int ac = StatLevel(partyMember, STAT_ac); + sprintf_s(acMsg, fmt, armorClassMsg, ac); + + xPos -= GetTextWidth(armorClassMsg) + 20; + PrintText(acMsg, color, xPos, 167, GetTextWidth(acMsg), toWidth, surface); + + color = (QueueFindFirst(partyMember, 2)) ? *(BYTE*)_RedColor : *(BYTE*)_DarkGreenColor; + widthText = GetTextWidth(addictMsg); + PrintText(addictMsg, color, 350 - widthText, 148, widthText, toWidth, surface); +} + +static void __declspec(naked) gdControlUpdateInfo_hook() { + __asm { + mov edi, eax; // keep fontnum + mov ecx, ebp; + mov edx, esi; + call PartyMemberPrintStat; + mov eax, edi; + jmp text_font_; + } +} + void PartyControlInit() { Mode = GetPrivateProfileIntA("Misc", "ControlCombat", 0, ini); if (Mode > 2) @@ -381,6 +419,12 @@ void PartyControlInit() { HookCall(0x41279A, &pc_flag_toggle_hook); } else dlogr(" Disabled.", DL_INIT); + + // display party member's current level & AC & addict flag + HookCall(0x44926F, gdControlUpdateInfo_hook); + GetPrivateProfileString("sfall", "PartyLvlMsg", "Lvl:", levelMsg, 12, translationIni); + GetPrivateProfileString("sfall", "PartyACMsg", "AC:", armorClassMsg, 12, translationIni); + GetPrivateProfileString("sfall", "PartyAddictMsg", "Addict", addictMsg, 16, translationIni); } void __stdcall PartyControlReset() {