SilentPatch/SilentPatchSA/VehicleSA.cpp

312 lines
9.3 KiB
C++
Raw Normal View History

2014-08-03 15:38:53 +02:00
#include "StdAfxSA.h"
2014-05-30 20:14:47 +02:00
2016-11-12 18:28:46 +01:00
#include <algorithm>
#include <vector>
2014-08-03 15:38:53 +02:00
#include "VehicleSA.h"
#include "TimerSA.h"
2017-03-23 11:30:06 +01:00
#include "DelimStringReader.h"
2014-05-30 20:14:47 +02:00
2016-11-12 18:28:46 +01:00
std::vector<unsigned int> vecRotorExceptions;
static bool ShouldIgnoreRotor( unsigned int id )
{
return std::find( vecRotorExceptions.begin(), vecRotorExceptions.end(), id ) != vecRotorExceptions.end();
}
2015-05-05 23:29:15 +02:00
2014-08-22 00:10:23 +02:00
static void* varVehicleRender = AddressByVersion<void*>(0x6D0E60, 0x6D1680, 0x70C0B0);
WRAPPER void CVehicle::Render() { VARJMP(varVehicleRender); }
2014-08-22 00:10:23 +02:00
static void* varIsLawEnforcementVehicle = AddressByVersion<void*>(0x6D2370, 0x6D2BA0, 0x70D8C0);
WRAPPER bool CVehicle::IsLawEnforcementVehicle() { VARJMP(varIsLawEnforcementVehicle); }
2014-05-30 20:14:47 +02:00
2016-11-12 18:28:46 +01:00
static int32_t random(int32_t from, int32_t to)
{
2017-03-09 00:53:03 +01:00
return from + ( Int32Rand() % (to-from) );
2016-11-12 18:28:46 +01:00
}
2014-05-30 20:14:47 +02:00
static RwObject* GetCurrentAtomicObjectCB(RwObject* pObject, void* data)
{
if ( RpAtomicGetFlags(pObject) & rpATOMICRENDER )
{
2014-05-30 20:14:47 +02:00
*static_cast<RwObject**>(data) = pObject;
return nullptr;
}
2014-05-30 20:14:47 +02:00
return pObject;
}
static RwFrame* GetFrameFromNameCB(RwFrame* pFrame, void* pData)
{
// Is this a frame we want?
std::pair<const char*,RwFrame*>* pFindData = static_cast<std::pair<const char*,RwFrame*>*>(pData);
2015-05-05 23:29:15 +02:00
if ( !strcmp(pFindData->first, GetFrameNodeName(pFrame)) )
{
pFindData->second = pFrame;
return nullptr;
}
// Try children
RwFrameForAllChildren(pFrame, GetFrameFromNameCB, pData);
return !pFindData->second ? pFrame : nullptr;
}
static RpMaterial* SetCompAlphaCB(RpMaterial* pMaterial, void* data)
{
pMaterial->color.alpha = reinterpret_cast<RwUInt8>(data);
return pMaterial;
}
2015-05-05 23:29:15 +02:00
void ReadRotorFixExceptions(const wchar_t* pPath)
{
const size_t SCRATCH_PAD_SIZE = 32767;
2017-03-23 11:30:06 +01:00
WideDelimStringReader reader( SCRATCH_PAD_SIZE );
2015-05-05 23:29:15 +02:00
2017-03-23 11:30:06 +01:00
GetPrivateProfileSectionW( L"RotorFixExceptions", reader.GetBuffer(), reader.GetSize(), pPath );
while ( const wchar_t* str = reader.GetString() )
{
2017-03-23 11:30:06 +01:00
unsigned int toList = _wtoi( str );
if ( toList != 0 )
2016-11-12 18:28:46 +01:00
vecRotorExceptions.push_back( toList );
2015-05-05 23:29:15 +02:00
}
}
void CVehicle::SetComponentAtomicAlpha(RpAtomic* pAtomic, int nAlpha)
{
RpGeometry* pGeometry = RpAtomicGetGeometry(pAtomic);
pGeometry->flags |= rpGEOMETRYMODULATEMATERIALCOLOR;
RpGeometryForAllMaterials(pGeometry, SetCompAlphaCB, reinterpret_cast<void*>(nAlpha));
}
2014-06-23 02:37:03 +02:00
bool CVehicle::CustomCarPlate_TextureCreate(CVehicleModelInfo* pModelInfo)
{
2016-03-12 14:18:24 +01:00
char PlateText[10];
2014-06-23 02:37:03 +02:00
const char* pOverrideText = pModelInfo->GetCustomCarPlateText();
if ( pOverrideText )
2016-03-11 21:11:35 +01:00
strcpy_s(PlateText, pOverrideText);
2014-06-23 02:37:03 +02:00
else
CCustomCarPlateMgr::GeneratePlateText(PlateText, 8);
PlateTexture = CCustomCarPlateMgr::CreatePlateTexture(PlateText, pModelInfo->m_nPlateType);
2014-06-23 14:54:36 +02:00
//PlateDesign = pModelInfo->m_nPlateType != -1 ? pModelInfo->m_nPlateType : CCustomCarPlateMgr::GetMapRegionPlateDesign();
if ( pModelInfo->m_nPlateType != -1 )
PlateDesign = pModelInfo->m_nPlateType;
else if ( IsLawEnforcementVehicle() )
PlateDesign = CCustomCarPlateMgr::GetMapRegionPlateDesign();
else
2016-11-12 18:28:46 +01:00
PlateDesign = random(0, 20) == 0 ? random(0, 3) : CCustomCarPlateMgr::GetMapRegionPlateDesign();
2014-06-23 02:37:03 +02:00
assert(PlateDesign >= 0 && PlateDesign < 3);
pModelInfo->m_plateText[0] = '\0';
pModelInfo->m_nPlateType = -1;
return true;
}
2014-06-23 15:08:48 +02:00
//static RwTexture* pPushedTextures[NUM_MAX_PLATES];
2014-06-23 02:37:03 +02:00
void CVehicle::CustomCarPlate_BeforeRenderingStart(CVehicleModelInfo* pModelInfo)
{
2014-06-29 22:21:18 +02:00
//CCustomCarPlateMgr::SetupPlates(reinterpret_cast<RpClump*>(pModelInfo->pRwObject), PlateTexture, PlateDesign);
for ( ptrdiff_t i = 0; i < NUM_MAX_PLATES; i++ )
2014-06-23 02:37:03 +02:00
{
if ( pModelInfo->m_apPlateMaterials[i] )
{
2014-06-23 15:08:48 +02:00
//RwTexture* pPlateTex = RpMaterialGetTexture(pModelInfo->m_apPlateMaterials[i]);
2014-06-23 02:37:03 +02:00
2014-06-23 15:08:48 +02:00
//RwTextureAddRef(pPlateTex);
//pPushedTextures[i] = pPlateTex;
2014-06-23 02:37:03 +02:00
RpMaterialSetTexture(pModelInfo->m_apPlateMaterials[i], PlateTexture);
}
if ( pModelInfo->m_apPlateMaterials[NUM_MAX_PLATES+i] )
CCustomCarPlateMgr::SetupMaterialPlatebackTexture(pModelInfo->m_apPlateMaterials[NUM_MAX_PLATES+i], PlateDesign);
//RwTexture* pPlatebackTex = RpMaterialGetTexture(pModelInfo->m_apPlateMaterials[4+i]);
//RwTextureAddRef(pPlatebackTex);
//pPushedTextures[4+i] = pPlateTex;
//RpMaterialSetTexture(pModelInfo->m_apPlateMaterials[i], PlateTexture);
}
}
2014-06-23 15:08:48 +02:00
// This is not needed
/*void CVehicle::CustomCarPlate_AfterRenderingStop(CVehicleModelInfo* pModelInfo)
2014-06-23 02:37:03 +02:00
{
for ( int i = 0; i < NUM_MAX_PLATES; i++ )
{
if ( pModelInfo->m_apPlateMaterials[i] )
{
//RwTexture* pPlateTex = RpMaterialGetTexture(pModelInfo->m_apPlateMaterials[i]);
//RwTextureAddRef(pPlateTex);
//pPushedTextures[i] = pPlateTex;
2014-06-23 15:08:48 +02:00
//RpMaterialSetTexture(pModelInfo->m_apPlateMaterials[i], pPushedTextures[i]);
//RwTextureDestroy(pPushedTextures[i]);
//pPushedTextures[i] = nullptr;
2014-06-23 02:37:03 +02:00
}
}
2014-06-23 15:08:48 +02:00
}*/
2014-06-23 02:37:03 +02:00
2014-05-30 20:14:47 +02:00
void CHeli::Render()
{
double dRotorsSpeed, dMovingRotorSpeed;
2016-11-12 18:28:46 +01:00
bool bDisplayRotors = !ShouldIgnoreRotor( m_nModelIndex );
bool bHasMovingRotor = m_pCarNode[13] != nullptr && bDisplayRotors;
bool bHasMovingRotor2 = m_pCarNode[15] != nullptr && bDisplayRotors;
2014-05-30 20:14:47 +02:00
2014-08-03 15:38:53 +02:00
m_nTimeTillWeNeedThisCar = CTimer::m_snTimeInMilliseconds + 3000;
2014-05-30 20:14:47 +02:00
if ( m_fRotorSpeed > 0.0 )
2016-11-12 18:28:46 +01:00
dRotorsSpeed = std::min(1.7 * (1.0/0.22) * m_fRotorSpeed, 1.5);
2014-05-30 20:14:47 +02:00
else
dRotorsSpeed = 0.0;
dMovingRotorSpeed = dRotorsSpeed - 0.4;
if ( dMovingRotorSpeed < 0.0 )
dMovingRotorSpeed = 0.0;
2016-11-12 18:28:46 +01:00
int nStaticRotorAlpha = static_cast<int>(std::min((1.5-dRotorsSpeed) * 255.0, 255.0));
int nMovingRotorAlpha = static_cast<int>(std::min(dMovingRotorSpeed * 175.0, 175.0));
2014-05-30 20:14:47 +02:00
if ( m_pCarNode[12] )
2014-05-30 20:14:47 +02:00
{
RpAtomic* pOutAtomic = nullptr;
RwFrameForAllObjects(m_pCarNode[12], GetCurrentAtomicObjectCB, &pOutAtomic);
2014-05-30 20:14:47 +02:00
if ( pOutAtomic )
SetComponentAtomicAlpha(pOutAtomic, bHasMovingRotor ? nStaticRotorAlpha : 255);
2014-05-30 20:14:47 +02:00
}
if ( m_pCarNode[14] )
2014-05-30 20:14:47 +02:00
{
RpAtomic* pOutAtomic = nullptr;
RwFrameForAllObjects(m_pCarNode[14], GetCurrentAtomicObjectCB, &pOutAtomic);
2014-05-30 20:14:47 +02:00
if ( pOutAtomic )
SetComponentAtomicAlpha(pOutAtomic, bHasMovingRotor2 ? nStaticRotorAlpha : 255);
2014-05-30 20:14:47 +02:00
}
2015-05-05 23:29:15 +02:00
if ( m_pCarNode[13] )
2014-05-30 20:14:47 +02:00
{
RpAtomic* pOutAtomic = nullptr;
RwFrameForAllObjects(m_pCarNode[13], GetCurrentAtomicObjectCB, &pOutAtomic);
2014-05-30 20:14:47 +02:00
if ( pOutAtomic )
2015-05-05 23:29:15 +02:00
SetComponentAtomicAlpha(pOutAtomic, bHasMovingRotor ? nMovingRotorAlpha : 0);
2014-05-30 20:14:47 +02:00
}
2015-05-05 23:29:15 +02:00
if ( m_pCarNode[15] )
2014-05-30 20:14:47 +02:00
{
RpAtomic* pOutAtomic = nullptr;
RwFrameForAllObjects(m_pCarNode[15], GetCurrentAtomicObjectCB, &pOutAtomic);
2014-05-30 20:14:47 +02:00
if ( pOutAtomic )
2015-05-05 23:29:15 +02:00
SetComponentAtomicAlpha(pOutAtomic, bHasMovingRotor2 ? nMovingRotorAlpha : 0);
2014-05-30 20:14:47 +02:00
}
CEntity::Render();
}
void CPlane::Render()
{
double dRotorsSpeed, dMovingRotorSpeed;
2016-11-12 18:28:46 +01:00
bool bDisplayRotors = !ShouldIgnoreRotor( m_nModelIndex );
bool bHasMovingProp = m_pCarNode[13] != nullptr && bDisplayRotors;
bool bHasMovingProp2 = m_pCarNode[15] != nullptr && bDisplayRotors;
2014-05-30 20:14:47 +02:00
2014-08-03 15:38:53 +02:00
m_nTimeTillWeNeedThisCar = CTimer::m_snTimeInMilliseconds + 3000;
2014-05-30 20:14:47 +02:00
if ( m_fPropellerSpeed > 0.0 )
2016-11-12 18:28:46 +01:00
dRotorsSpeed = std::min(1.7 * (1.0/0.31) * m_fPropellerSpeed, 1.5);
2014-05-30 20:14:47 +02:00
else
dRotorsSpeed = 0.0;
dMovingRotorSpeed = dRotorsSpeed - 0.4;
if ( dMovingRotorSpeed < 0.0 )
dMovingRotorSpeed = 0.0;
2016-11-12 18:28:46 +01:00
int nStaticRotorAlpha = static_cast<int>(std::min((1.5-dRotorsSpeed) * 255.0, 255.0));
int nMovingRotorAlpha = static_cast<int>(std::min(dMovingRotorSpeed * 175.0, 175.0));
2014-05-30 20:14:47 +02:00
if ( m_pCarNode[12] )
2014-05-30 20:14:47 +02:00
{
RpAtomic* pOutAtomic = nullptr;
RwFrameForAllObjects(m_pCarNode[12], GetCurrentAtomicObjectCB, &pOutAtomic);
2014-05-30 20:14:47 +02:00
if ( pOutAtomic )
2014-06-04 16:12:53 +02:00
SetComponentAtomicAlpha(pOutAtomic, bHasMovingProp ? nStaticRotorAlpha : 255);
2014-05-30 20:14:47 +02:00
}
if ( m_pCarNode[14] )
2014-05-30 20:14:47 +02:00
{
RpAtomic* pOutAtomic = nullptr;
RwFrameForAllObjects(m_pCarNode[14], GetCurrentAtomicObjectCB, &pOutAtomic);
2014-05-30 20:14:47 +02:00
if ( pOutAtomic )
2014-06-04 16:12:53 +02:00
SetComponentAtomicAlpha(pOutAtomic, bHasMovingProp2 ? nStaticRotorAlpha : 255);
2014-05-30 20:14:47 +02:00
}
2015-05-05 23:29:15 +02:00
if ( m_pCarNode[13] )
2014-05-30 20:14:47 +02:00
{
RpAtomic* pOutAtomic = nullptr;
RwFrameForAllObjects(m_pCarNode[13], GetCurrentAtomicObjectCB, &pOutAtomic);
2014-05-30 20:14:47 +02:00
if ( pOutAtomic )
2015-05-05 23:29:15 +02:00
SetComponentAtomicAlpha(pOutAtomic, bHasMovingProp ? nMovingRotorAlpha : 0);
2014-05-30 20:14:47 +02:00
}
2015-05-05 23:29:15 +02:00
if ( m_pCarNode[15] )
2014-05-30 20:14:47 +02:00
{
RpAtomic* pOutAtomic = nullptr;
RwFrameForAllObjects(m_pCarNode[15], GetCurrentAtomicObjectCB, &pOutAtomic);
2014-05-30 20:14:47 +02:00
if ( pOutAtomic )
2015-05-05 23:29:15 +02:00
SetComponentAtomicAlpha(pOutAtomic, bHasMovingProp2 ? nMovingRotorAlpha : 0);
2014-05-30 20:14:47 +02:00
}
CVehicle::Render();
}
void CPlane::Fix_SilentPatch()
{
// Reset bouncing panels
// No reset on Vortex
for ( ptrdiff_t i = m_nModelIndex == 539 ? 1 : 0; i < 3; i++ )
{
m_aBouncingPanel[i].m_nNodeIndex = -1;
}
}
void CAutomobile::Fix_SilentPatch()
{
ResetFrames();
// Reset bouncing panels
for ( ptrdiff_t i = (m_nModelIndex == 525 && m_pCarNode[21]) || (m_nModelIndex == 531 && m_pCarNode[17]) ? 1 : 0; i < 3; i++ )
{
// Towtruck/Tractor fix
m_aBouncingPanel[i].m_nNodeIndex = -1;
}
}
void CAutomobile::ResetFrames()
{
RpClump* pOrigClump = reinterpret_cast<RpClump*>(ms_modelInfoPtrs[m_nModelIndex]->pRwObject);
if ( pOrigClump )
{
// Instead of setting frame rotation to (0,0,0) like R* did, obtain the original frame matrix from CBaseNodelInfo clump
for ( ptrdiff_t i = 8; i < 25; i++ )
{
if ( m_pCarNode[i] )
{
// Find a frame in CBaseModelInfo object
std::pair<const char*,RwFrame*> FindData = std::make_pair(GetFrameNodeName(m_pCarNode[i]), nullptr);
RwFrameForAllChildren(RpClumpGetFrame(pOrigClump), GetFrameFromNameCB, &FindData);
if ( FindData.second )
{
// Found a frame, reset it
*RwFrameGetMatrix(m_pCarNode[i]) = *RwFrameGetMatrix(FindData.second);
RwMatrixUpdate(RwFrameGetMatrix(m_pCarNode[i]));
}
}
}
}
2014-05-30 20:14:47 +02:00
}