mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2024-12-28 06:43:01 +05:00
VC: Fix the construction site LOD losing its HQ model and showing at all times
This commit is contained in:
parent
b76637d391
commit
0f92e082b4
7 changed files with 134 additions and 28 deletions
|
@ -839,7 +839,7 @@ namespace SitInBoat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace SVFReadyHook
|
namespace ModelIndicesReadyHook
|
||||||
{
|
{
|
||||||
static void (*orgInitialiseObjectData)(const char*);
|
static void (*orgInitialiseObjectData)(const char*);
|
||||||
static void InitialiseObjectData_ReadySVF(const char* path)
|
static void InitialiseObjectData_ReadySVF(const char* path)
|
||||||
|
@ -1010,7 +1010,7 @@ void InjectDelayedPatches_III_Common( bool bHasDebugMenu, const wchar_t* wcModul
|
||||||
// Register CBaseModelInfo::GetModelInfo for SVF so we can resolve model names
|
// Register CBaseModelInfo::GetModelInfo for SVF so we can resolve model names
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using namespace SVFReadyHook;
|
using namespace ModelIndicesReadyHook;
|
||||||
|
|
||||||
auto initialiseObjectData = get_pattern("E8 ? ? ? ? B3 01 59 8D 6D 04");
|
auto initialiseObjectData = get_pattern("E8 ? ? ? ? B3 01 59 8D 6D 04");
|
||||||
auto getModelInfo = (void*(*)(const char*, int*))get_pattern("31 FF 8D 84 20 00 00 00 00 8B 04 BD", -7);
|
auto getModelInfo = (void*(*)(const char*, int*))get_pattern("31 FF 8D 84 20 00 00 00 00 8B 04 BD", -7);
|
||||||
|
|
|
@ -2652,7 +2652,7 @@ static bool IgnoresWeaponPedsForPCFix()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace SVFReadyHook
|
namespace ModelIndicesReadyHook
|
||||||
{
|
{
|
||||||
static void (*orgMatchAllModelStrings)();
|
static void (*orgMatchAllModelStrings)();
|
||||||
static void MatchAllModelStrings_ReadySVF()
|
static void MatchAllModelStrings_ReadySVF()
|
||||||
|
@ -3899,7 +3899,7 @@ BOOL InjectDelayedPatches_10()
|
||||||
|
|
||||||
// Register CBaseModelInfo::GetModelInfo for SVF so we can resolve model names
|
// Register CBaseModelInfo::GetModelInfo for SVF so we can resolve model names
|
||||||
{
|
{
|
||||||
using namespace SVFReadyHook;
|
using namespace ModelIndicesReadyHook;
|
||||||
|
|
||||||
auto func = (void*(*)(const char*, int*))0x4C5940;
|
auto func = (void*(*)(const char*, int*))0x4C5940;
|
||||||
|
|
||||||
|
|
22
SilentPatchVC/EntityVC.h
Normal file
22
SilentPatchVC/EntityVC.h
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#pragma
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#include "TheFLAUtils.h"
|
||||||
|
|
||||||
|
enum // m_objectCreatedBy
|
||||||
|
{
|
||||||
|
GAME_OBJECT = 1,
|
||||||
|
MISSION_OBJECT = 2,
|
||||||
|
TEMP_OBJECT = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
class CEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::byte __pad[80];
|
||||||
|
uint8_t m_nType : 3;
|
||||||
|
std::byte __pad2[11];
|
||||||
|
FLAUtils::int16 m_modelIndex;
|
||||||
|
};
|
|
@ -23,5 +23,16 @@ public:
|
||||||
static void AttachCarPipeToRwObject_Default(RwObject*) { }
|
static void AttachCarPipeToRwObject_Default(RwObject*) { }
|
||||||
static inline void (*AttachCarPipeToRwObject)(RwObject* object) = &AttachCarPipeToRwObject_Default;
|
static inline void (*AttachCarPipeToRwObject)(RwObject* object) = &AttachCarPipeToRwObject_Default;
|
||||||
};
|
};
|
||||||
|
static_assert(sizeof(CVehicleModelInfo) == 0x174, "Wrong size: CVehicleModelInfo");
|
||||||
|
|
||||||
static_assert(sizeof(CVehicleModelInfo) == 0x174, "Wrong size: CvehicleModelInfo");
|
class CSimpleModelInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void* __vmt;
|
||||||
|
char m_name[24];
|
||||||
|
uint8_t __pad[12];
|
||||||
|
void* m_atomics[3];
|
||||||
|
float m_lodDistances[3];
|
||||||
|
uint8_t __pad2[4];
|
||||||
|
};
|
||||||
|
static_assert(sizeof(CSimpleModelInfo) == 68, "Wrong size: CSimpleModelInfo");
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "Common_ddraw.h"
|
#include "Common_ddraw.h"
|
||||||
#include "Desktop.h"
|
#include "Desktop.h"
|
||||||
|
#include "EntityVC.h"
|
||||||
#include "ModelInfoVC.h"
|
#include "ModelInfoVC.h"
|
||||||
#include "VehicleVC.h"
|
#include "VehicleVC.h"
|
||||||
#include "SVF.h"
|
#include "SVF.h"
|
||||||
|
@ -65,6 +66,8 @@ DebugMenuAPI gDebugMenuAPI;
|
||||||
static RsGlobalType* RsGlobal;
|
static RsGlobalType* RsGlobal;
|
||||||
static const void* SubtitlesShadowFix_JumpBack;
|
static const void* SubtitlesShadowFix_JumpBack;
|
||||||
|
|
||||||
|
void* (*GetModelInfo)(const char*, int*);
|
||||||
|
|
||||||
// This is actually CBaseModelInfo, but we currently don't have it defined
|
// This is actually CBaseModelInfo, but we currently don't have it defined
|
||||||
CVehicleModelInfo**& ms_modelInfoPtrs = *hook::get_pattern<CVehicleModelInfo**>("8B 15 ? ? ? ? 8D 04 24", 2);
|
CVehicleModelInfo**& ms_modelInfoPtrs = *hook::get_pattern<CVehicleModelInfo**>("8B 15 ? ? ? ? 8D 04 24", 2);
|
||||||
int32_t& numModelInfos = *hook::get_pattern<int32_t>("81 FD ? ? ? ? 7C B7", 2);
|
int32_t& numModelInfos = *hook::get_pattern<int32_t>("81 FD ? ? ? ? 7C B7", 2);
|
||||||
|
@ -722,22 +725,7 @@ namespace SelectableBackfaceCulling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only the parts of CEntity and CObject we need
|
// Only the parts of CObject we need
|
||||||
enum // m_objectCreatedBy
|
|
||||||
{
|
|
||||||
GAME_OBJECT = 1,
|
|
||||||
MISSION_OBJECT = 2,
|
|
||||||
TEMP_OBJECT = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Entity
|
|
||||||
{
|
|
||||||
std::byte __pad[80];
|
|
||||||
uint8_t m_nType : 3;
|
|
||||||
std::byte __pad2[11];
|
|
||||||
FLAUtils::int16 m_modelIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Object
|
struct Object
|
||||||
{
|
{
|
||||||
std::byte __pad[364];
|
std::byte __pad[364];
|
||||||
|
@ -755,7 +743,7 @@ namespace SelectableBackfaceCulling
|
||||||
};
|
};
|
||||||
|
|
||||||
static void* EntityRender_Prologue_JumpBack;
|
static void* EntityRender_Prologue_JumpBack;
|
||||||
__declspec(naked) static void __fastcall EntityRender_Original(Entity*)
|
__declspec(naked) static void __fastcall EntityRender_Original(CEntity*)
|
||||||
{
|
{
|
||||||
_asm
|
_asm
|
||||||
{
|
{
|
||||||
|
@ -766,7 +754,7 @@ namespace SelectableBackfaceCulling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ShouldDisableBackfaceCulling(const Entity* entity)
|
static bool ShouldDisableBackfaceCulling(const CEntity* entity)
|
||||||
{
|
{
|
||||||
const uint8_t entityType = entity->m_nType;
|
const uint8_t entityType = entity->m_nType;
|
||||||
|
|
||||||
|
@ -797,9 +785,9 @@ namespace SelectableBackfaceCulling
|
||||||
}
|
}
|
||||||
|
|
||||||
// If CEntity::Render is re-routed by another mod, we overwrite this later
|
// If CEntity::Render is re-routed by another mod, we overwrite this later
|
||||||
static void (__fastcall *orgEntityRender)(Entity* obj) = &EntityRender_Original;
|
static void (__fastcall *orgEntityRender)(CEntity* obj) = &EntityRender_Original;
|
||||||
|
|
||||||
static void __fastcall EntityRender_BackfaceCulling(Entity* obj)
|
static void __fastcall EntityRender_BackfaceCulling(CEntity* obj)
|
||||||
{
|
{
|
||||||
RwScopedRenderState<rwRENDERSTATECULLMODE> cullState;
|
RwScopedRenderState<rwRENDERSTATECULLMODE> cullState;
|
||||||
|
|
||||||
|
@ -813,15 +801,76 @@ namespace SelectableBackfaceCulling
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace SVFReadyHook
|
// ============= Fix the construction site LOD losing its HQ model and showing at all times =============
|
||||||
|
namespace ConstructionSiteLODFix
|
||||||
{
|
{
|
||||||
static void* (*GetModelInfo)(const char*, int*);
|
static bool bActivateConstructionSiteFix = false;
|
||||||
|
|
||||||
|
static int32_t MI_BLDNGST2MESH, MI_BLDNGST2MESHDAM;
|
||||||
|
static CSimpleModelInfo* Bldngst2mesh_ModelInfo;
|
||||||
|
static CSimpleModelInfo* Bldngst2meshDam_ModelInfo;
|
||||||
|
static CSimpleModelInfo* LODngst2mesh_ModelInfo;
|
||||||
|
void MatchModelIndices()
|
||||||
|
{
|
||||||
|
CSimpleModelInfo* Bldngst2mesh = reinterpret_cast<CSimpleModelInfo*>(GetModelInfo("bldngst2mesh", &MI_BLDNGST2MESH));
|
||||||
|
CSimpleModelInfo* Bldngst2meshDam = reinterpret_cast<CSimpleModelInfo*>(GetModelInfo("bldngst2meshdam", &MI_BLDNGST2MESHDAM));
|
||||||
|
CSimpleModelInfo* LODngst2mesh = reinterpret_cast<CSimpleModelInfo*>(GetModelInfo("LODngst2mesh", nullptr));
|
||||||
|
CSimpleModelInfo* LODngst2meshDam = reinterpret_cast<CSimpleModelInfo*>(GetModelInfo("LODngst2meshdam", nullptr));
|
||||||
|
|
||||||
|
const bool bHasBldngst2mesh = Bldngst2mesh != nullptr;
|
||||||
|
const bool bHasBldngst2meshDam = Bldngst2meshDam != nullptr;
|
||||||
|
const bool bHasLODngst2mesh = LODngst2mesh != nullptr;
|
||||||
|
const bool bHasLODngst2meshDam = LODngst2meshDam != nullptr;
|
||||||
|
|
||||||
|
// LODngst2meshdam doesn't exist in the vanilla game, so if it exists - a mod to fix this issue via
|
||||||
|
// the map modifications has been installed.
|
||||||
|
bActivateConstructionSiteFix = bHasBldngst2mesh && bHasBldngst2meshDam && bHasLODngst2mesh && !bHasLODngst2meshDam;
|
||||||
|
|
||||||
|
Bldngst2mesh_ModelInfo = Bldngst2mesh;
|
||||||
|
Bldngst2meshDam_ModelInfo = Bldngst2meshDam;
|
||||||
|
LODngst2mesh_ModelInfo = LODngst2mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FixConstructionSiteModel(int oldModelID, int newModelID)
|
||||||
|
{
|
||||||
|
if (!bActivateConstructionSiteFix)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldModelID == MI_BLDNGST2MESH && newModelID == MI_BLDNGST2MESHDAM)
|
||||||
|
{
|
||||||
|
LODngst2mesh_ModelInfo->m_atomics[2] = Bldngst2meshDam_ModelInfo;
|
||||||
|
}
|
||||||
|
else if (oldModelID == MI_BLDNGST2MESHDAM && newModelID == MI_BLDNGST2MESH)
|
||||||
|
{
|
||||||
|
LODngst2mesh_ModelInfo->m_atomics[2] = Bldngst2mesh_ModelInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t Index>
|
||||||
|
static void (__fastcall *orgReplaceWithNewModel)(CEntity* building, void*, int newModelID);
|
||||||
|
|
||||||
|
template<std::size_t Index>
|
||||||
|
static void __fastcall ReplaceWithNewModel_ConstructionSiteFix(CEntity* building, void*, int newModelID)
|
||||||
|
{
|
||||||
|
const int oldModelID = building->m_modelIndex.Get();
|
||||||
|
orgReplaceWithNewModel<Index>(building, nullptr, newModelID);
|
||||||
|
FixConstructionSiteModel(oldModelID, newModelID);
|
||||||
|
}
|
||||||
|
|
||||||
|
HOOK_EACH_FUNC(ReplaceWithNewModel, orgReplaceWithNewModel, ReplaceWithNewModel_ConstructionSiteFix);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace ModelIndicesReadyHook
|
||||||
|
{
|
||||||
static void (*orgInitialiseObjectData)(const char*);
|
static void (*orgInitialiseObjectData)(const char*);
|
||||||
static void InitialiseObjectData_ReadySVF(const char* path)
|
static void InitialiseObjectData_ReadySVF(const char* path)
|
||||||
{
|
{
|
||||||
orgInitialiseObjectData(path);
|
orgInitialiseObjectData(path);
|
||||||
SVF::MarkModelNamesReady();
|
SVF::MarkModelNamesReady();
|
||||||
|
ConstructionSiteLODFix::MatchModelIndices();
|
||||||
|
|
||||||
// This is a bit dirty, but whatever
|
// This is a bit dirty, but whatever
|
||||||
// Tooled Up in North Point Mall needs a "draw last" flag, or else our BFC changes break it very badly
|
// Tooled Up in North Point Mall needs a "draw last" flag, or else our BFC changes break it very badly
|
||||||
|
@ -991,10 +1040,12 @@ void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModule
|
||||||
TXN_CATCH();
|
TXN_CATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool HasModelInfo = false;
|
||||||
// Register CBaseModelInfo::GetModelInfo for SVF so we can resolve model names
|
// Register CBaseModelInfo::GetModelInfo for SVF so we can resolve model names
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using namespace SVFReadyHook;
|
using namespace ModelIndicesReadyHook;
|
||||||
|
|
||||||
auto initialiseObjectData = get_pattern("E8 ? ? ? ? 59 E8 ? ? ? ? E8 ? ? ? ? 31 DB");
|
auto initialiseObjectData = get_pattern("E8 ? ? ? ? 59 E8 ? ? ? ? E8 ? ? ? ? 31 DB");
|
||||||
auto getModelInfo = (void*(*)(const char*, int*))get_pattern("57 31 FF 55 8B 6C 24 14", -6);
|
auto getModelInfo = (void*(*)(const char*, int*))get_pattern("57 31 FF 55 8B 6C 24 14", -6);
|
||||||
|
@ -1002,6 +1053,24 @@ void InjectDelayedPatches_VC_Common( bool bHasDebugMenu, const wchar_t* wcModule
|
||||||
GetModelInfo = getModelInfo;
|
GetModelInfo = getModelInfo;
|
||||||
InterceptCall(initialiseObjectData, orgInitialiseObjectData, InitialiseObjectData_ReadySVF);
|
InterceptCall(initialiseObjectData, orgInitialiseObjectData, InitialiseObjectData_ReadySVF);
|
||||||
SVF::RegisterGetModelInfoCB(getModelInfo);
|
SVF::RegisterGetModelInfoCB(getModelInfo);
|
||||||
|
|
||||||
|
HasModelInfo = true;
|
||||||
|
}
|
||||||
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
||||||
|
// Fix the construction site LOD losing its HQ model and showing at all times
|
||||||
|
if (HasModelInfo) try
|
||||||
|
{
|
||||||
|
using namespace ConstructionSiteLODFix;
|
||||||
|
|
||||||
|
std::array<void*, 3> replaceWithNewModel = {
|
||||||
|
get_pattern("E8 ? ? ? ? C7 85 ? ? ? ? 00 00 00 00 83 8D ? ? ? ? FF"),
|
||||||
|
get_pattern("DD D8 E8 ? ? ? ? 56", 2),
|
||||||
|
get_pattern("E8 ? ? ? ? FF 44 24 0C 83 C5 0C"),
|
||||||
|
};
|
||||||
|
|
||||||
|
HookEach_ReplaceWithNewModel(replaceWithNewModel, InterceptCall);
|
||||||
}
|
}
|
||||||
TXN_CATCH();
|
TXN_CATCH();
|
||||||
|
|
||||||
|
|
|
@ -181,6 +181,7 @@
|
||||||
<ClInclude Include="..\SilentPatch\Utils\MemoryMgr.GTA.h" />
|
<ClInclude Include="..\SilentPatch\Utils\MemoryMgr.GTA.h" />
|
||||||
<ClInclude Include="..\SilentPatch\Utils\MemoryMgr.h" />
|
<ClInclude Include="..\SilentPatch\Utils\MemoryMgr.h" />
|
||||||
<ClInclude Include="..\SilentPatch\Utils\Patterns.h" />
|
<ClInclude Include="..\SilentPatch\Utils\Patterns.h" />
|
||||||
|
<ClInclude Include="EntityVC.h" />
|
||||||
<ClInclude Include="ModelInfoVC.h" />
|
<ClInclude Include="ModelInfoVC.h" />
|
||||||
<ClInclude Include="VehicleVC.h" />
|
<ClInclude Include="VehicleVC.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -72,6 +72,9 @@
|
||||||
<ClInclude Include="..\SilentPatch\Random.h">
|
<ClInclude Include="..\SilentPatch\Random.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="EntityVC.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\SilentPatch\Timer.cpp">
|
<ClCompile Include="..\SilentPatch\Timer.cpp">
|
||||||
|
|
Loading…
Reference in a new issue