From 36523d89e5d95114f9416a9a33539b72490833af Mon Sep 17 00:00:00 2001 From: NovaRain Date: Sun, 11 Aug 2019 23:53:01 +0800 Subject: [PATCH] Fixed obj_art_fid for dude_obj when the hero appearance mod is enabled --- artifacts/ddraw.ini | 1 + sfall/FalloutStructs.h | 2 +- sfall/HeroAppearance.cpp | 43 ++++++++++++++++++++++++++++++---------- sfall/HeroAppearance.h | 2 +- sfall/Inventory.cpp | 2 +- sfall/PartyControl.cpp | 4 ++-- sfall/main.cpp | 9 +++------ 7 files changed, 41 insertions(+), 22 deletions(-) diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index 6a4c7292..e6de7352 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -372,6 +372,7 @@ CorpseDeleteTime=6 ProcessorIdle=-1 ;Set to 1 if using the hero appearance mod +;Set to 2 for backward compatibility with old scripts that manually fix obj_art_fid script function for dude_obj ;You can add AppChCrt.frm and AppChEdt.frm files to art\intrface\ to set a custom background for the character screen EnableHeroAppearanceMod=0 diff --git a/sfall/FalloutStructs.h b/sfall/FalloutStructs.h index 21de93cd..0f9a967f 100644 --- a/sfall/FalloutStructs.h +++ b/sfall/FalloutStructs.h @@ -49,7 +49,7 @@ struct TGameObj long sy; long currentFrm; long rotation; - long artFID; + long artFid; long flags; long elevation; long invenCount; diff --git a/sfall/HeroAppearance.cpp b/sfall/HeroAppearance.cpp index 118795f0..13763ede 100644 --- a/sfall/HeroAppearance.cpp +++ b/sfall/HeroAppearance.cpp @@ -23,6 +23,7 @@ #include "FalloutEngine.h" #include "HeroAppearance.h" #include "Message.h" +#include "PartyControl.h" #include "ScriptExtender.h" bool appModEnabled = false; // check if Appearance mod enabled for script fuctions @@ -410,7 +411,6 @@ static bool LoadFrmHeader(UNLSTDfrm *frmHeader, void* frmStream) { } static bool LoadFrmFrame(UNLSTDframe *frame, void* frmStream) { - //FRMframe *frameHeader = (FRMframe*)frameMEM; //BYTE* frameBuff = frame + sizeof(FRMframe); @@ -433,7 +433,6 @@ static bool LoadFrmFrame(UNLSTDframe *frame, void* frmStream) { } UNLSTDfrm *LoadUnlistedFrm(char *frmName, unsigned int folderRef) { - if (folderRef > 10) return nullptr; char *artfolder = (char*)(0x51073C + folderRef * 32); // address of art type name @@ -799,7 +798,6 @@ endFunc: } static __declspec(noinline) int _stdcall LoadHeroDat(unsigned int race, unsigned int style, bool flush = false) { - if (flush) RefreshArtCache(); if (heroPathPtr->pDat) { // unload previous Dats @@ -905,25 +903,24 @@ static void __declspec(naked) AdjustHeroArmorArt() { jg endFunc; add eax, critterListSize; // shift critter art index up into hero range endFunc: - //mov dword ptr ds:[_i_fid], eax + //mov dword ptr ds:[_i_fid], eax; retn; } } static void _stdcall SetHeroArt(bool newArtFlag) { - TGameObj* hero = *ptr_obj_dude; // hero state struct - long heroFID = hero->artFID; // get hero FrmID + long heroFID = hero->artFid; // get hero FrmID DWORD fidBase = heroFID & 0xFFF; // mask out current weapon flag if (fidBase > critterListSize) { // check if critter LST index is in Hero range if (!newArtFlag) { heroFID -= critterListSize; // shift index down into normal critter range - hero->artFID = heroFID; + hero->artFid = heroFID; } } else if (newArtFlag) { heroFID += critterListSize; // shift index up into hero range - hero->artFID = heroFID; // set new FrmID to hero state struct + hero->artFid = heroFID; // set new FrmID to hero state struct } } @@ -1116,7 +1113,6 @@ void _stdcall SetHeroStyle(int newStyleVal) { // op_set_hero_race void _stdcall SetHeroRace(int newRaceVal) { - if (!appModEnabled || newRaceVal == currentRaceVal) return; if (LoadHeroDat(newRaceVal, 0, true) != 0) { // if new race fails with style at 0 @@ -1192,7 +1188,6 @@ static void DrawBody(DWORD critNum, BYTE* surface) { } static void DrawPCConsole() { - DWORD NewTick = *(DWORD*)0x5709C4; // char scrn gettickcount ret DWORD RotSpeed = *(DWORD*)0x47066B; // get rotation speed - inventory rotation speed @@ -1984,6 +1979,21 @@ endFunc: } } +static const DWORD op_obj_art_fid_Ret = 0x45C5D9; +static void __declspec(naked) op_obj_art_fid_hack() { + __asm { + mov esi, [edi + 0x20]; // artFid + push ecx; + call RealDudeObject; + pop ecx; + cmp eax, edi; // object is dude? + jnz skip; + sub esi, critterListSize; // fix hero FrmID +skip: + jmp op_obj_art_fid_Ret; + } +} + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Load Appearance data from GCD file @@ -2018,7 +2028,7 @@ static void __fastcall SaveGCDAppearance(void *FileStream) { FCloseFile(FileStream); } -void EnableHeroAppearanceMod() { +static void EnableHeroAppearanceMod() { appModEnabled = true; // setup paths @@ -2144,3 +2154,14 @@ void HeroAppearanceModExit() { delete racePathPtr; } } + +void HeroAppearanceModInit() { + int heroAppearanceMod = GetPrivateProfileIntA("Misc", "EnableHeroAppearanceMod", 0, ini); + if (heroAppearanceMod > 0) { + dlog("Setting up Appearance Char Screen buttons.", DL_INIT); + EnableHeroAppearanceMod(); + // Hero FrmID fix for obj_art_fid script function + if (heroAppearanceMod != 2) MakeJump(0x45C5C3, op_obj_art_fid_hack); + dlogr(" Done", DL_INIT); + } +} diff --git a/sfall/HeroAppearance.h b/sfall/HeroAppearance.h index a8af78fc..fb7c5e16 100644 --- a/sfall/HeroAppearance.h +++ b/sfall/HeroAppearance.h @@ -42,7 +42,7 @@ DWORD GetTextWidth(char *TextMsg); DWORD GetMaxCharWidth(); int check_buttons(void); -void EnableHeroAppearanceMod(); +void HeroAppearanceModInit(); void HeroAppearanceModExit(); void _stdcall HeroSelectWindow(int raceStyleFlag); diff --git a/sfall/Inventory.cpp b/sfall/Inventory.cpp index 78fc1290..855922e5 100644 --- a/sfall/Inventory.cpp +++ b/sfall/Inventory.cpp @@ -100,7 +100,7 @@ DWORD __stdcall sf_item_total_size(TGameObj* critter) { mov totalSize, eax; } - if (((critter->artFID >> 24) & 0x0F) == OBJ_TYPE_CRITTER) { + if (((critter->artFid >> 24) & 0x0F) == OBJ_TYPE_CRITTER) { TGameObj* item = InvenRightHand(critter); if (item && !(item->flags & 0x2000000)) { // ObjectFlag Right_Hand totalSize += ItemSize(item); diff --git a/sfall/PartyControl.cpp b/sfall/PartyControl.cpp index 7affbaa8..f724f6a3 100644 --- a/sfall/PartyControl.cpp +++ b/sfall/PartyControl.cpp @@ -147,7 +147,7 @@ static void TakeControlOfNPC(TGameObj* npc) { *ptr_sneak_working = 0; // deduce active hand by weapon anim code - char critterAnim = (npc->artFID & 0xF000) >> 12; // current weapon as seen in hands + char critterAnim = (npc->artFid & 0xF000) >> 12; // current weapon as seen in hands if (AnimCodeByWeapon(InvenLeftHand(npc)) == critterAnim) { // definitely left hand.. *ptr_itemCurrentItem = 0; } else { @@ -279,7 +279,7 @@ int __stdcall PartyControl_SwitchHandHook(TGameObj* item) { call ai_can_use_weapon_; mov canUse, eax; }*/ - int fId = (*ptr_obj_dude)->artFID; + int fId = (*ptr_obj_dude)->artFid; char weaponCode = AnimCodeByWeapon(item); fId = (fId & 0xFFFF0FFF) | (weaponCode << 12); // check if art with this weapon exists diff --git a/sfall/main.cpp b/sfall/main.cpp index 33b6834e..004b01c5 100644 --- a/sfall/main.cpp +++ b/sfall/main.cpp @@ -860,12 +860,6 @@ static void DllMain2() { dlogr(" Done", DL_INIT); } - if (GetPrivateProfileIntA("Misc", "EnableHeroAppearanceMod", 0, ini)) { - dlog("Setting up Appearance Char Screen buttons.", DL_INIT); - EnableHeroAppearanceMod(); - dlogr(" Done", DL_INIT); - } - dlog("Checking for changed skilldex images.", DL_INIT); tmp = GetPrivateProfileIntA("Misc", "Lockpick", 293, ini); if (tmp != 293) SafeWrite32(0x518D54, tmp); @@ -883,6 +877,9 @@ static void DllMain2() { if (tmp != 293) SafeWrite32(0x518D64, tmp); dlogr(" Done", DL_INIT); + dlogr("Running HeroAppearanceModInit().", DL_INIT); + HeroAppearanceModInit(); + dlogr("Running TilesInit().", DL_INIT); TilesInit();