mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2024-12-29 15:23:02 +05:00
Unified special vehicle features and double rwheels override (it's now internally a special vehicle feature, just like rotors)
This commit is contained in:
parent
75ebedef98
commit
2dfc9d30be
2 changed files with 90 additions and 61 deletions
|
@ -1003,66 +1003,9 @@ void DrawScriptSpritesAndRectangles( uint8_t arg )
|
||||||
orgDrawScriptSpritesAndRectangles( arg );
|
orgDrawScriptSpritesAndRectangles( arg );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector< std::pair<int32_t, bool> > doubleRearWheelsList;
|
// Now in VehicleSA.cpp
|
||||||
bool ReadDoubleRearWheels(const wchar_t* pPath)
|
bool ReadDoubleRearWheels(const wchar_t* pPath);
|
||||||
{
|
bool __stdcall CheckDoubleRWheelsList( void* modelInfo, uint8_t* handlingData );
|
||||||
bool listedAny = false;
|
|
||||||
|
|
||||||
constexpr size_t SCRATCH_PAD_SIZE = 32767;
|
|
||||||
WideDelimStringReader reader( SCRATCH_PAD_SIZE );
|
|
||||||
|
|
||||||
GetPrivateProfileSectionW( L"DoubleRearWheels", reader.GetBuffer(), reader.GetSize(), pPath );
|
|
||||||
while ( const wchar_t* str = reader.GetString() )
|
|
||||||
{
|
|
||||||
wchar_t textLine[64];
|
|
||||||
wchar_t* context = nullptr;
|
|
||||||
wchar_t* token;
|
|
||||||
|
|
||||||
wcscpy_s( textLine, str );
|
|
||||||
token = wcstok_s( textLine, L"=", &context );
|
|
||||||
|
|
||||||
int32_t toList = wcstol( token, nullptr, 0 );
|
|
||||||
if ( toList <= 0 ) continue;
|
|
||||||
|
|
||||||
wchar_t* begin = wcstok_s( nullptr, L"=", &context );
|
|
||||||
if ( begin == nullptr ) continue;
|
|
||||||
|
|
||||||
wchar_t* end = nullptr;
|
|
||||||
bool value = wcstoul( begin, &end, 0 ) != 0;
|
|
||||||
if ( begin != end )
|
|
||||||
{
|
|
||||||
doubleRearWheelsList.emplace_back( toList, value );
|
|
||||||
listedAny = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return listedAny;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1.0 ONLY!
|
|
||||||
bool __stdcall CheckDoubleRWheelsList( void* modelInfo, uint8_t* handlingData )
|
|
||||||
{
|
|
||||||
static void* lastModelInfo = nullptr;
|
|
||||||
static bool lastResult = false;
|
|
||||||
|
|
||||||
if ( modelInfo == lastModelInfo ) return lastResult;
|
|
||||||
lastModelInfo = modelInfo;
|
|
||||||
|
|
||||||
const uint32_t numModelInfoPtrs = *(uint32_t*)0x4C5956+2;
|
|
||||||
int32_t modelID = std::distance( ms_modelInfoPtrs, std::find( ms_modelInfoPtrs, ms_modelInfoPtrs+numModelInfoPtrs, modelInfo ) );
|
|
||||||
|
|
||||||
auto it = std::find_if( doubleRearWheelsList.begin(), doubleRearWheelsList.end(), [modelID]( const auto& item ) {
|
|
||||||
return item.first == modelID;
|
|
||||||
} );
|
|
||||||
if ( it == doubleRearWheelsList.end() )
|
|
||||||
{
|
|
||||||
uint32_t flags = *(uint32_t*)(handlingData+0xCC);
|
|
||||||
lastResult = (flags & 0x20000000) != 0;
|
|
||||||
return lastResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastResult = it->second;
|
|
||||||
return lastResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
CVehicleModelInfo* (__thiscall *orgVehicleModelInfoCtor)(CVehicleModelInfo*);
|
CVehicleModelInfo* (__thiscall *orgVehicleModelInfoCtor)(CVehicleModelInfo*);
|
||||||
CVehicleModelInfo* __fastcall VehicleModelInfoCtor(CVehicleModelInfo* me)
|
CVehicleModelInfo* __fastcall VehicleModelInfoCtor(CVehicleModelInfo* me)
|
||||||
|
|
|
@ -41,11 +41,13 @@ namespace SVF {
|
||||||
// Internal SP use only, formerly "rotor exceptions"
|
// Internal SP use only, formerly "rotor exceptions"
|
||||||
// Unreachable from RegisterSpecialVehicleFeature
|
// Unreachable from RegisterSpecialVehicleFeature
|
||||||
NO_ROTOR_FADE,
|
NO_ROTOR_FADE,
|
||||||
|
FORCE_DOUBLE_RWHEELS_OFF,
|
||||||
|
FORCE_DOUBLE_RWHEELS_ON,
|
||||||
};
|
};
|
||||||
|
|
||||||
Feature GetFeatureFromName( const char* featureName )
|
Feature GetFeatureFromName( const char* featureName )
|
||||||
{
|
{
|
||||||
const std::pair< const char*, Feature > features[] = {
|
constexpr std::pair< const char*, Feature > features[] = {
|
||||||
{ "PHOENIX_FLUTTER", Feature::PHOENIX_FLUTTER },
|
{ "PHOENIX_FLUTTER", Feature::PHOENIX_FLUTTER },
|
||||||
{ "SWEEPER_BRUSHES", Feature::SWEEPER_BRUSHES },
|
{ "SWEEPER_BRUSHES", Feature::SWEEPER_BRUSHES },
|
||||||
{ "NEWSVAN_DISH", Feature::NEWSVAN_DISH },
|
{ "NEWSVAN_DISH", Feature::NEWSVAN_DISH },
|
||||||
|
@ -142,6 +144,90 @@ namespace SVF {
|
||||||
return std::get<Feature>(e.second) == feature;
|
return std::get<Feature>(e.second) == feature;
|
||||||
} ) != results.second;
|
} ) != results.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Pred>
|
||||||
|
Pred ForAllModelFeatures( int32_t modelID, Pred&& pred )
|
||||||
|
{
|
||||||
|
auto results = specialVehFeatures.equal_range( modelID );
|
||||||
|
for ( auto it = results.first; it != results.second; ++it )
|
||||||
|
{
|
||||||
|
std::forward<Pred>(pred)(std::get<Feature>(it->second));
|
||||||
|
}
|
||||||
|
return std::forward<Pred>(pred);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadDoubleRearWheels(const wchar_t* pPath)
|
||||||
|
{
|
||||||
|
bool listedAny = false;
|
||||||
|
|
||||||
|
constexpr size_t SCRATCH_PAD_SIZE = 32767;
|
||||||
|
WideDelimStringReader reader( SCRATCH_PAD_SIZE );
|
||||||
|
|
||||||
|
GetPrivateProfileSectionW( L"DoubleRearWheels", reader.GetBuffer(), reader.GetSize(), pPath );
|
||||||
|
while ( const wchar_t* str = reader.GetString() )
|
||||||
|
{
|
||||||
|
wchar_t textLine[64];
|
||||||
|
wchar_t* context = nullptr;
|
||||||
|
wchar_t* token;
|
||||||
|
|
||||||
|
wcscpy_s( textLine, str );
|
||||||
|
token = wcstok_s( textLine, L"=", &context );
|
||||||
|
|
||||||
|
int32_t toList = wcstol( token, nullptr, 0 );
|
||||||
|
if ( toList <= 0 ) continue;
|
||||||
|
|
||||||
|
wchar_t* begin = wcstok_s( nullptr, L"=", &context );
|
||||||
|
if ( begin == nullptr ) continue;
|
||||||
|
|
||||||
|
wchar_t* end = nullptr;
|
||||||
|
bool value = wcstoul( begin, &end, 0 ) != 0;
|
||||||
|
if ( begin != end )
|
||||||
|
{
|
||||||
|
SVF::RegisterFeature( toList, value ? SVF::Feature::FORCE_DOUBLE_RWHEELS_ON : SVF::Feature::FORCE_DOUBLE_RWHEELS_OFF );
|
||||||
|
listedAny = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return listedAny;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1.0 ONLY!
|
||||||
|
bool __stdcall CheckDoubleRWheelsList( void* modelInfo, uint8_t* handlingData )
|
||||||
|
{
|
||||||
|
static void* lastModelInfo = nullptr;
|
||||||
|
static bool lastResult = false;
|
||||||
|
|
||||||
|
if ( modelInfo == lastModelInfo ) return lastResult;
|
||||||
|
lastModelInfo = modelInfo;
|
||||||
|
|
||||||
|
const uint32_t numModelInfoPtrs = *(uint32_t*)0x4C5956+2;
|
||||||
|
int32_t modelID = std::distance( ms_modelInfoPtrs, std::find( ms_modelInfoPtrs, ms_modelInfoPtrs+numModelInfoPtrs, modelInfo ) );
|
||||||
|
|
||||||
|
bool foundFeature = false;
|
||||||
|
bool featureStatus = false;
|
||||||
|
SVF::ForAllModelFeatures( modelID, [&]( SVF::Feature f ) {
|
||||||
|
if ( foundFeature ) return;
|
||||||
|
|
||||||
|
if ( f == SVF::Feature::FORCE_DOUBLE_RWHEELS_OFF )
|
||||||
|
{
|
||||||
|
foundFeature = true;
|
||||||
|
featureStatus = false;
|
||||||
|
}
|
||||||
|
else if ( f == SVF::Feature::FORCE_DOUBLE_RWHEELS_ON )
|
||||||
|
{
|
||||||
|
foundFeature = true;
|
||||||
|
featureStatus = true;
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
if ( !foundFeature )
|
||||||
|
{
|
||||||
|
uint32_t flags = *(uint32_t*)(handlingData+0xCC);
|
||||||
|
lastResult = (flags & 0x20000000) != 0;
|
||||||
|
return lastResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastResult = featureStatus;
|
||||||
|
return lastResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue