summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/entities/Vehicle.h6
-rw-r--r--src/modelinfo/ModelIndices.h1
-rw-r--r--src/modelinfo/VehicleModelInfo.cpp223
-rw-r--r--src/modelinfo/VehicleModelInfo.h9
4 files changed, 237 insertions, 2 deletions
diff --git a/src/entities/Vehicle.h b/src/entities/Vehicle.h
index c62605c9..16f11763 100644
--- a/src/entities/Vehicle.h
+++ b/src/entities/Vehicle.h
@@ -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];
diff --git a/src/modelinfo/ModelIndices.h b/src/modelinfo/ModelIndices.h
index d64cf939..8b188345 100644
--- a/src/modelinfo/ModelIndices.h
+++ b/src/modelinfo/ModelIndices.h
@@ -203,6 +203,7 @@ enum
MI_FATFEMALE01,
MI_FATFEMALE02,
+ MI_FIRETRUCK = 97,
MI_PREDATOR = 120,
MI_RHINO = 122,
MI_TRAIN = 124,
diff --git a/src/modelinfo/VehicleModelInfo.cpp b/src/modelinfo/VehicleModelInfo.cpp
index 575d0360..5e3a77fe 100644
--- a/src/modelinfo/VehicleModelInfo.cpp
+++ b/src/modelinfo/VehicleModelInfo.cpp
@@ -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);
diff --git a/src/modelinfo/VehicleModelInfo.h b/src/modelinfo/VehicleModelInfo.h
index ccc46f73..f69760b8 100644
--- a/src/modelinfo/VehicleModelInfo.h
+++ b/src/modelinfo/VehicleModelInfo.h
@@ -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); }