summaryrefslogtreecommitdiffstats
path: root/src/modelinfo/VehicleModelInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/modelinfo/VehicleModelInfo.cpp')
-rw-r--r--src/modelinfo/VehicleModelInfo.cpp223
1 files changed, 223 insertions, 0 deletions
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);