more CVehicleModelInfo

This commit is contained in:
aap 2019-05-28 21:17:47 +02:00
parent cb8993f15e
commit c5a058b615
4 changed files with 237 additions and 2 deletions

View file

@ -8,7 +8,11 @@ class CVehicle : public CPhysical
{
public:
// 0x128
uint8 stuff1[120];
uint8 stuff1[116];
uint8 m_currentColour1;
uint8 m_currentColour2;
uint8 m_extra1;
uint8 m_extra2;
int16 m_nAlarmState;
CPed *pDriver;
CPed *pPassengers[8];

View file

@ -203,6 +203,7 @@ enum
MI_FATFEMALE01,
MI_FATFEMALE02,
MI_FIRETRUCK = 97,
MI_PREDATOR = 120,
MI_RHINO = 122,
MI_TRAIN = 124,

View file

@ -7,6 +7,10 @@
#include "TxdStore.h"
#include "Weather.h"
#include "VisibilityPlugins.h"
#include "FileMgr.h"
#include "World.h"
#include "Vehicle.h"
#include "ModelIndices.h"
#include "ModelInfo.h"
int8 *CVehicleModelInfo::ms_compsToUse = (int8*)0x5FF2EC; // -2, -2
@ -280,6 +284,16 @@ CVehicleModelInfo::HideDamagedAtomicCB(RpAtomic *atomic, void *data)
return atomic;
}
RpAtomic*
CVehicleModelInfo::HideAllComponentsAtomicCB(RpAtomic *atomic, void *data)
{
if(CVisibilityPlugins::GetAtomicId(atomic) & (int)data)
RpAtomicSetFlags(atomic, 0);
else
RpAtomicSetFlags(atomic, rpATOMICRENDER);
return atomic;
}
RpMaterial*
CVehicleModelInfo::HasAlphaMaterialCB(RpMaterial *material, void *data)
{
@ -758,6 +772,183 @@ CVehicleModelInfo::SetVehicleColour(uint8 c1, uint8 c2)
}
}
void
CVehicleModelInfo::ChooseVehicleColour(uint8 &col1, uint8 &col2)
{
if(m_numColours == 0){
col1 = 0;
col2 = 0;
}else{
m_lastColorVariation = (m_lastColorVariation+1) % m_numColours;
col1 = m_colours1[m_lastColorVariation];
col2 = m_colours2[m_lastColorVariation];
if(m_numColours > 1){
CVehicle *veh = FindPlayerVehicle();
if(veh && CModelInfo::GetModelInfo(veh->GetModelIndex()) == this &&
veh->m_currentColour1 == col1 &&
veh->m_currentColour2 == col2){
m_lastColorVariation = (m_lastColorVariation+1) % m_numColours;
col1 = m_colours1[m_lastColorVariation];
col2 = m_colours2[m_lastColorVariation];
}
}
}
}
void
CVehicleModelInfo::AvoidSameVehicleColour(uint8 *col1, uint8 *col2)
{
int i, n;
if(m_numColours > 1)
for(i = 0; i < 8; i++){
if(*col1 != m_lastColour1 || *col2 != m_lastColour2)
break;
n = CGeneral::GetRandomNumberInRange(0, m_numColours);
*col1 = m_colours1[n];
*col2 = m_colours2[n];
}
m_lastColour1 = *col1;
m_lastColour2 = *col2;
}
RwTexture*
CreateCarColourTexture(uint8 r, uint8 g, uint8 b)
{
RwImage *img;
RwRaster *ras;
RwTexture *tex;
RwUInt8 *pixels;
RwInt32 width, height, depth, format;
img = RwImageCreate(2, 2, 32);
pixels = (RwUInt8*)RwMalloc(2*2*4);
pixels[0] = r;
pixels[1] = g;
pixels[2] = b;
pixels[3] = 0xFF;
pixels[4] = r;
pixels[5] = g;
pixels[6] = b;
pixels[7] = 0xFF;
pixels[8] = r;
pixels[9] = g;
pixels[10] = b;
pixels[11] = 0xFF;
pixels[12] = r;
pixels[13] = g;
pixels[14] = b;
pixels[15] = 0xFF;
RwImageSetPixels(img, pixels);
RwImageSetPalette(img, nil);
RwImageFindRasterFormat(img, rwRASTERTYPETEXTURE, &width, &height, &depth, &format);
ras = RwRasterCreate(width, height, depth, format);
RwRasterSetFromImage(ras, img);
RwImageDestroy(img);
RwFree(pixels);
tex = RwTextureCreate(ras);
tex->name[0] = '@';
return tex;
}
void
CVehicleModelInfo::LoadVehicleColours(void)
{
int fd;
int i;
char line[1024];
int start, end;
int section, numCols;
enum {
NONE,
COLOURS,
CARS
};
int r, g, b;
char name[64];
int colors[16];
int n;
CFileMgr::ChangeDir("\\DATA\\");
fd = CFileMgr::OpenFile("CARCOLS.DAT", "r");
CFileMgr::ChangeDir("\\");
for(i = 0; i < 256; i++)
ms_colourTextureTable[i] = nil;
section = 0;
numCols = 0;
while(CFileMgr::ReadLine(fd, line, sizeof(line))){
// find first valid character in line
for(start = 0; ; start++)
if(line[start] > ' ' || line[start] == '\0' || line[start] == '\n')
break;
// find end of line
for(end = start; ; end++){
if(line[end] == '\0' || line[end] == '\n')
break;
if(line[end] == ',' || line[end] == '\r')
line[end] = ' ';
}
line[end] = '\0';
// empty line
if(line[start] == '#' || line[start] == '\0')
continue;
if(section == NONE){
if(strncmp(&line[start], "col", 3) == 0)
section = COLOURS;
else if(strncmp(&line[start], "car", 3) == 0)
section = CARS;
}else if(strncmp(&line[start], "end", 3) == 0){
section = NONE;
}else if(section == COLOURS){
sscanf(&line[start], // BUG: games doesn't add start
"%d %d %d", &r, &g, &b);
ms_vehicleColourTable[numCols].red = r;
ms_vehicleColourTable[numCols].green = g;
ms_vehicleColourTable[numCols].blue = b;
ms_vehicleColourTable[numCols].alpha = 0xFF;
ms_colourTextureTable[numCols] = CreateCarColourTexture(r, g, b);
numCols++;
}else if(section == CARS){
n = sscanf(&line[start], // BUG: games doesn't add start
"%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
name,
&colors[0], &colors[1],
&colors[2], &colors[3],
&colors[4], &colors[5],
&colors[6], &colors[7],
&colors[8], &colors[9],
&colors[10], &colors[11],
&colors[12], &colors[13],
&colors[14], &colors[15]);
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(name, nil);
assert(mi);
mi->m_numColours = (n-1)/2;
for(i = 0; i < mi->m_numColours; i++){
mi->m_colours1[i] = colors[i*2 + 0];
mi->m_colours2[i] = colors[i*2 + 1];
}
}
}
CFileMgr::CloseFile(fd);
}
void
CVehicleModelInfo::DeleteVehicleColourTextures(void)
{
int i;
for(i = 0; i < 256; i++){
if(ms_colourTextureTable[i]){
RwTextureDestroy(ms_colourTextureTable[i]);
ms_colourTextureTable[i] = nil;
}
}
}
RpMaterial*
CVehicleModelInfo::HasSpecularMaterialCB(RpMaterial *material, void *data)
@ -872,6 +1063,31 @@ CVehicleModelInfo::ShutdownEnvironmentMaps(void)
pMatFxIdentityFrame = nil;
}
int
CVehicleModelInfo::GetMaximumNumberOfPassengersFromNumberOfDoors(int id)
{
int n;
switch(id){
case MI_TRAIN:
n = 3;
break;
case MI_FIRETRUCK:
n = 2;
break;
default:
n = ((CVehicleModelInfo*)CModelInfo::GetModelInfo(id))->m_numDoors;
}
if(n == 0)
return id == MI_RCBANDIT ? 0 : 1;
if(id == MI_COACH)
return 8;
return n - 1;
}
STARTPATCHES
InjectHook(0x51FDC0, &CVehicleModelInfo::DeleteRwObject_, PATCH_JUMP);
InjectHook(0x51FCB0, &CVehicleModelInfo::CreateInstance_, PATCH_JUMP);
@ -880,6 +1096,7 @@ STARTPATCHES
InjectHook(0x51FE10, &CVehicleModelInfo::CollapseFramesCB, PATCH_JUMP);
InjectHook(0x51FE50, &CVehicleModelInfo::MoveObjectsCB, PATCH_JUMP);
InjectHook(0x51FE70, &CVehicleModelInfo::HideDamagedAtomicCB, PATCH_JUMP);
InjectHook(0x51FED0, &CVehicleModelInfo::HideAllComponentsAtomicCB, PATCH_JUMP);
InjectHook(0x51FEF0, &CVehicleModelInfo::HasAlphaMaterialCB, PATCH_JUMP);
InjectHook(0x51FF10, &CVehicleModelInfo::SetAtomicRendererCB, PATCH_JUMP);
@ -907,6 +1124,12 @@ STARTPATCHES
InjectHook(0x520D30, (RpMaterial *(*)(RpMaterial*, void*))CVehicleModelInfo::GetEditableMaterialListCB, PATCH_JUMP);
InjectHook(0x520DE0, &CVehicleModelInfo::FindEditableMaterialList, PATCH_JUMP);
InjectHook(0x520E70, &CVehicleModelInfo::SetVehicleColour, PATCH_JUMP);
InjectHook(0x520FD0, &CVehicleModelInfo::ChooseVehicleColour, PATCH_JUMP);
InjectHook(0x5210A0, &CVehicleModelInfo::AvoidSameVehicleColour, PATCH_JUMP);
InjectHook(0x521260, &CVehicleModelInfo::LoadVehicleColours, PATCH_JUMP);
InjectHook(0x521650, &CVehicleModelInfo::DeleteVehicleColourTextures, PATCH_JUMP);
InjectHook(0x5219D0, &CVehicleModelInfo::GetMaximumNumberOfPassengersFromNumberOfDoors, PATCH_JUMP);
InjectHook(0x521820, (RpAtomic *(*)(RpAtomic*, void*))CVehicleModelInfo::SetEnvironmentMapCB, PATCH_JUMP);
InjectHook(0x5217A0, (RpMaterial *(*)(RpMaterial*, void*))CVehicleModelInfo::SetEnvironmentMapCB, PATCH_JUMP);

View file

@ -56,7 +56,7 @@ public:
uint8 m_colours1[NUM_VEHICLE_COLOURS];
uint8 m_colours2[NUM_VEHICLE_COLOURS];
uint8 m_numColours;
uint8 m_bLastColorVariation; //
uint8 m_lastColorVariation;
uint8 m_currentColour1;
uint8 m_currentColour2;
RwTexture *m_envMap;
@ -78,6 +78,7 @@ public:
static RwFrame *CollapseFramesCB(RwFrame *frame, void *data);
static RwObject *MoveObjectsCB(RwObject *object, void *data);
static RpAtomic *HideDamagedAtomicCB(RpAtomic *atomic, void *data);
static RpAtomic *HideAllComponentsAtomicCB(RpAtomic *atomic, void *data);
static RpMaterial *HasAlphaMaterialCB(RpMaterial *material, void *data);
static RpAtomic *SetAtomicRendererCB(RpAtomic *atomic, void *data);
@ -100,6 +101,10 @@ public:
static RpAtomic *GetEditableMaterialListCB(RpAtomic *atomic, void *data);
void FindEditableMaterialList(void);
void SetVehicleColour(uint8 c1, uint8 c2);
void ChooseVehicleColour(uint8 &col1, uint8 &col2);
void AvoidSameVehicleColour(uint8 *col1, uint8 *col2);
static void LoadVehicleColours(void);
static void DeleteVehicleColourTextures(void);
static RpAtomic *SetEnvironmentMapCB(RpAtomic *atomic, void *data);
static RpMaterial *SetEnvironmentMapCB(RpMaterial *material, void *data);
@ -108,6 +113,8 @@ public:
static void LoadEnvironmentMaps(void);
static void ShutdownEnvironmentMaps(void);
static int GetMaximumNumberOfPassengersFromNumberOfDoors(int id);
void DeleteRwObject_(void) { this->CVehicleModelInfo::DeleteRwObject(); }
RwObject *CreateInstance_(void) { return this->CVehicleModelInfo::CreateInstance(); }
void SetClump_(RpClump *clump) { this->CVehicleModelInfo::SetClump(clump); }