mirror of
https://github.com/OpenDriver2/REDRIVER2.git
synced 2024-11-25 11:52:32 +01:00
97e738ba36
- re-arrange includes
756 lines
15 KiB
C
756 lines
15 KiB
C
#include "driver2.h"
|
|
#include "cosmetic.h"
|
|
#include "system.h"
|
|
#include "mission.h"
|
|
#include "handling.h"
|
|
#include "cars.h"
|
|
#include "debris.h"
|
|
#include "pause.h"
|
|
#include "camera.h"
|
|
#include "director.h"
|
|
#include "main.h"
|
|
|
|
char* CosmeticFiles[] = {
|
|
"LEVELS\\CHICAGO.LCF",
|
|
"LEVELS\\HAVANA.LCF",
|
|
"LEVELS\\VEGAS.LCF",
|
|
"LEVELS\\RIO.LCF",
|
|
};
|
|
|
|
CAR_COSMETICS car_cosmetics[MAX_CAR_MODELS];
|
|
|
|
// [A] storage for spooled models
|
|
// remember: we already have more than 1k of free memory with optimizations
|
|
CAR_COSMETICS levelSpecCosmetics[5];
|
|
|
|
// [D] [T]
|
|
void ProcessCosmeticsLump(char *lump_ptr, int lump_size)
|
|
{
|
|
int model;
|
|
int i;
|
|
int offset;
|
|
|
|
for (i = 0; i < MAX_CAR_MODELS; i++)
|
|
{
|
|
model = MissionHeader->residentModels[i];
|
|
|
|
if (model == 13)
|
|
{
|
|
model = 10 - (MissionHeader->residentModels[0] + MissionHeader->residentModels[1] + MissionHeader->residentModels[2]);
|
|
|
|
if (model < 1)
|
|
model = 1;
|
|
else if (model > 4)
|
|
model = 4;
|
|
}
|
|
|
|
if (model != -1)
|
|
{
|
|
offset = *(int*)(lump_ptr + model * sizeof(int));
|
|
memcpy((u_char*)&car_cosmetics[i], (u_char*)lump_ptr + offset, sizeof(CAR_COSMETICS));
|
|
|
|
FixCarCos(&car_cosmetics[i], model);
|
|
}
|
|
}
|
|
|
|
// [A] cache all special vehicle cosmetics
|
|
for (i = 0; i < 5; i++)
|
|
{
|
|
model = 8 + i;
|
|
|
|
offset = *(int*)(lump_ptr + model * sizeof(int));
|
|
memcpy((u_char*)&levelSpecCosmetics[i], (u_char*)lump_ptr + offset, sizeof(CAR_COSMETICS));
|
|
}
|
|
}
|
|
|
|
// [D] [T]
|
|
void LoadCosmetics(int level)
|
|
{
|
|
LoadfileSeg(CosmeticFiles[level], (char*)_other_buffer, 0, 3120);
|
|
ProcessCosmeticsLump((char*)_other_buffer, 0);
|
|
}
|
|
|
|
#define REVERSELIGHT_SIZE 14
|
|
#define INDICATORLIGHT_SIZE 20
|
|
#define BRAKELIGHT_SIZE 17
|
|
#define HEADLIGHT_SIZE 18
|
|
#define BACKLIGHT_SIZE 17
|
|
|
|
// [D] [T]
|
|
void AddReverseLight(CAR_DATA *cp)
|
|
{
|
|
CAR_COSMETICS *car_cos;
|
|
SVECTOR v1;
|
|
CVECTOR col;
|
|
|
|
car_cos = cp->ap.carCos;
|
|
|
|
col.r = 100;
|
|
col.g = 90;
|
|
col.b = 90;
|
|
|
|
v1 = car_cos->revLight;
|
|
|
|
v1.vx += car_cos->cog.vx;
|
|
v1.vy += car_cos->cog.vy;
|
|
v1.vz += car_cos->cog.vz;
|
|
|
|
if (cp->ap.damage[4] < 500)
|
|
{
|
|
ShowCarlight(&v1, cp, &col, REVERSELIGHT_SIZE, REVERSELIGHT_SIZE * 3, &light_texture, 0);
|
|
}
|
|
|
|
if (cp->ap.damage[3] < 500)
|
|
{
|
|
v1.vx = car_cos->cog.vx * 2 - v1.vx;
|
|
ShowCarlight(&v1, cp, &col, REVERSELIGHT_SIZE, REVERSELIGHT_SIZE * 3, &light_texture, 0);
|
|
}
|
|
}
|
|
|
|
// [D] [T]
|
|
void SetupSpecCosmetics(char *loadbuffer)
|
|
{
|
|
int model;
|
|
model = MissionHeader->residentModels[4];
|
|
|
|
#if 1
|
|
// [A] always use cached cosmetics
|
|
memcpy((u_char*)&car_cosmetics[4], (u_char*)&levelSpecCosmetics[model - 8], sizeof(CAR_COSMETICS));
|
|
#else
|
|
memcpy((u_char*)&car_cosmetics[4], loadbuffer, sizeof(CAR_COSMETICS));
|
|
#endif
|
|
|
|
// [A] don't forget
|
|
FixCarCos(&car_cosmetics[4], model);
|
|
}
|
|
|
|
// [D] [T]
|
|
void AddIndicatorLight(CAR_DATA *cp, int Type)
|
|
{
|
|
u_int brightness;
|
|
char *life;
|
|
CAR_COSMETICS *car_cos;
|
|
char *life2;
|
|
CVECTOR col;
|
|
SVECTOR vfrnt;
|
|
SVECTOR vback;
|
|
|
|
//if (cp->controlType != CONTROL_TYPE_CIV_AI) // [A] weird way to disable it here
|
|
// return;
|
|
|
|
life = &cp->ap.life;
|
|
life2 = &cp->ap.life2;
|
|
|
|
if (cp->ap.life < 0)
|
|
brightness = (0xff - (u_int)cp->ap.life) * 2;
|
|
else
|
|
brightness = cp->ap.life << 1;
|
|
|
|
col.r = brightness & 0xFF;
|
|
|
|
col.g = 0;
|
|
col.b = 0;
|
|
|
|
if (pauseflag == 0)
|
|
*life += 8;
|
|
|
|
car_cos = cp->ap.carCos;
|
|
|
|
vback = car_cos->backInd;
|
|
|
|
vback.vx += car_cos->cog.vx;
|
|
vback.vy += car_cos->cog.vy;
|
|
vback.vz += car_cos->cog.vz;
|
|
|
|
vfrnt = car_cos->frontInd;
|
|
|
|
vfrnt.vx += car_cos->cog.vx;
|
|
vfrnt.vy += car_cos->cog.vy;
|
|
vfrnt.vz += car_cos->cog.vz;
|
|
|
|
if (Type == 0 || Type == 2)
|
|
{
|
|
if (cp->ap.damage[4] < 500)
|
|
{
|
|
*life2 += brightness >> 3;
|
|
ShowCarlight(&vback, cp, &col, INDICATORLIGHT_SIZE, INDICATORLIGHT_SIZE * 4, &light_texture, 0);
|
|
}
|
|
|
|
if (cp->ap.damage[0] < 500)
|
|
{
|
|
ShowCarlight(&vfrnt, cp, &col, INDICATORLIGHT_SIZE, INDICATORLIGHT_SIZE * 4, &light_texture, 1);
|
|
}
|
|
}
|
|
|
|
if (Type - 1U < 2)
|
|
{
|
|
if (cp->ap.damage[3] < 500)
|
|
{
|
|
vback.vx = car_cos->cog.vx * 2 - vback.vx;
|
|
*life2 += brightness >> 3;
|
|
|
|
ShowCarlight(&vback, cp, &col, INDICATORLIGHT_SIZE, INDICATORLIGHT_SIZE * 4, &light_texture, 0);
|
|
}
|
|
|
|
if (cp->ap.damage[1] < 500)
|
|
{
|
|
vfrnt.vx = car_cos->cog.vx * 2 - vfrnt.vx;
|
|
ShowCarlight(&vfrnt, cp, &col, INDICATORLIGHT_SIZE, INDICATORLIGHT_SIZE * 4, &light_texture, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
// [D] [T]
|
|
void AddBrakeLight(CAR_DATA *cp)
|
|
{
|
|
short damageFac;
|
|
int damIndex;
|
|
short cogOffset;
|
|
CAR_COSMETICS *car_cos;
|
|
int offset;
|
|
char *life2;
|
|
int loop;
|
|
SVECTOR v1;
|
|
SVECTOR v2;
|
|
SVECTOR vec;
|
|
CVECTOR col;
|
|
short doubleFlag;
|
|
short verticalFlag;
|
|
|
|
car_cos = cp->ap.carCos;
|
|
col.r = 200;
|
|
col.g = 0;
|
|
col.b = 0;
|
|
|
|
life2 = &cp->ap.life2;
|
|
|
|
if (!(car_cos->extraInfo & 8))
|
|
return;
|
|
|
|
vec = car_cos->brakeLight;
|
|
|
|
vec.vx += car_cos->cog.vx;
|
|
vec.vy += car_cos->cog.vy;
|
|
vec.vz += car_cos->cog.vz;
|
|
|
|
offset = ((car_cos->extraInfo & 0x300) >> 6) + 10;
|
|
cogOffset = vec.vz + car_cos->cog.vz;
|
|
|
|
loop = 0;
|
|
|
|
doubleFlag = (car_cos->extraInfo & 0x4000) != 0;
|
|
verticalFlag = (car_cos->extraInfo & 0x1000) != 0;
|
|
|
|
do {
|
|
damIndex = (4 - loop);
|
|
|
|
if (doubleFlag)
|
|
{
|
|
if (verticalFlag)
|
|
{
|
|
v1 = vec;
|
|
v2 = vec;
|
|
|
|
damageFac = cp->ap.damage[damIndex] >> 6;
|
|
|
|
v1.vz = cogOffset + damageFac;
|
|
v2.vz = cogOffset + damageFac;
|
|
|
|
v1.vx = vec.vx;
|
|
v1.vy = offset + vec.vy;
|
|
v2.vy = vec.vy - offset;
|
|
|
|
if (cp->ap.damage[damIndex] < 500)
|
|
{
|
|
ShowCarlight(&v1, cp, &col, BRAKELIGHT_SIZE, BRAKELIGHT_SIZE * 4, &light_texture, 0);
|
|
ShowCarlight(&v2, cp, &col, BRAKELIGHT_SIZE, BRAKELIGHT_SIZE * 4, &light_texture, 0);
|
|
*life2 += 8;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
v1 = vec;
|
|
v2 = vec;
|
|
|
|
damageFac = cp->ap.damage[damIndex] >> 6;
|
|
v1.vz = cogOffset + damageFac;
|
|
v2.vz = cogOffset + damageFac;
|
|
|
|
v1.vx = offset + vec.vx;
|
|
v2.vx = vec.vx - offset;
|
|
|
|
if (cp->ap.damage[damIndex] < 500)
|
|
{
|
|
ShowCarlight(&v1, cp, &col, BRAKELIGHT_SIZE, BRAKELIGHT_SIZE * 4, &light_texture, 0);
|
|
ShowCarlight(&v2, cp, &col, BRAKELIGHT_SIZE, BRAKELIGHT_SIZE * 4, &light_texture, 0);
|
|
*life2 += 8;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
v1 = vec;
|
|
|
|
if (cp->ap.damage[damIndex] < 500)
|
|
{
|
|
ShowCarlight(&v1, cp, &col, BRAKELIGHT_SIZE, BRAKELIGHT_SIZE * 4, &light_texture, 0);
|
|
*life2 += 8;
|
|
}
|
|
}
|
|
|
|
offset = -offset;
|
|
|
|
vec.vx = car_cos->cog.vx * 2 - vec.vx;
|
|
|
|
loop++;
|
|
} while (loop < 2);
|
|
}
|
|
|
|
// [D] [T]
|
|
void AddCopCarLight(CAR_DATA *cp)
|
|
{
|
|
static char xpos1[8] = {
|
|
48, 32, 16, 0,
|
|
0, 16, 32, 48
|
|
};
|
|
|
|
int light;
|
|
int size;
|
|
short sign;
|
|
char count_speed;
|
|
int num_lights;
|
|
CAR_COSMETICS *car_cos;
|
|
char *coplife;
|
|
u_int pos;
|
|
int side;
|
|
SVECTOR v1;
|
|
CVECTOR col;
|
|
|
|
coplife = &cp->ap.coplife;
|
|
|
|
if (CameraCar == CAR_INDEX(cp) && cameraview == 2)
|
|
return;
|
|
|
|
if (FastForward != 0)
|
|
return;
|
|
|
|
// don't display on flipped cars
|
|
if (cp->hd.where.m[1][1] < 100)
|
|
return;
|
|
|
|
car_cos = cp->ap.carCos;
|
|
|
|
// configure
|
|
if (GameLevel == 1 || GameLevel == 3)
|
|
{
|
|
side = 1;
|
|
num_lights = 2;
|
|
pos = 3;
|
|
count_speed = 48;
|
|
}
|
|
else if (GameLevel == 0)
|
|
{
|
|
side = 2;
|
|
num_lights = 2;
|
|
pos = 3;
|
|
count_speed = 16;
|
|
}
|
|
else
|
|
{
|
|
side = 2;
|
|
num_lights = 3;
|
|
count_speed = 16;
|
|
pos = main_cop_light_pos + CAR_INDEX(cp) & 7;
|
|
}
|
|
|
|
sign = 1;
|
|
|
|
do {
|
|
side--;
|
|
|
|
if (side == -1)
|
|
return;
|
|
|
|
light = num_lights;
|
|
|
|
while (light-- >= 0)
|
|
{
|
|
v1.vx = car_cos->cog.vx;
|
|
|
|
if (GameLevel != 1 && GameLevel != 3)
|
|
v1.vx += (xpos1[pos] + car_cos->policeLight.vx) * sign;
|
|
|
|
col.g = 90;
|
|
v1.vy = car_cos->policeLight.vy + car_cos->cog.vy;
|
|
|
|
if (gNight != 0)
|
|
col.g = 50;
|
|
|
|
if (pauseflag == 0 && (CameraCnt & 1U) != 0 && GameLevel == 2)
|
|
pos++;
|
|
|
|
v1.vz = car_cos->policeLight.vz + car_cos->cog.vz;
|
|
|
|
size = *coplife >> 1;
|
|
|
|
// switch colours if needed
|
|
if (GameLevel == 1 || GameLevel == 3 || GameLevel == 2 && side == 0)
|
|
{
|
|
col.b = 255;
|
|
col.r = col.g;
|
|
}
|
|
else
|
|
{
|
|
col.r = 255;
|
|
col.b = col.g;
|
|
}
|
|
|
|
if (pauseflag == 0)
|
|
cp->ap.coplife += count_speed;
|
|
|
|
ShowCarlight(&v1, cp, &col, size, size*3, &light_texture, 0xff);
|
|
|
|
if (pauseflag == 0 && (CameraCnt & 1U) != 0 && GameLevel == 2)
|
|
pos++;
|
|
|
|
pos = pos & 7;
|
|
}
|
|
|
|
sign = -sign;
|
|
|
|
} while (true);
|
|
}
|
|
|
|
int gPlayerCarLights = 0;
|
|
int gcar_num = 0;
|
|
|
|
// [D] [T]
|
|
void AddNightLights(CAR_DATA *cp)
|
|
{
|
|
short offset;
|
|
int lightFlag;
|
|
char lights;
|
|
int damIndex;
|
|
CAR_COSMETICS *car_cos;
|
|
SVECTOR Position1;
|
|
SVECTOR Position2;
|
|
SVECTOR vec;
|
|
CVECTOR col;
|
|
CVECTOR col2;
|
|
int lit;
|
|
char *life2;
|
|
short loop;
|
|
short doubleFlag;
|
|
short verticalFlag;
|
|
short cogOffset;
|
|
|
|
life2 = &cp->ap.life2;
|
|
|
|
LeftLight = 0;
|
|
RightLight = 0;
|
|
|
|
car_cos = cp->ap.carCos;
|
|
|
|
cogOffset = car_cos->cog.vx;
|
|
gcar_num = CAR_INDEX(cp);
|
|
|
|
vec.vx = car_cos->headLight.vx + car_cos->cog.vx;
|
|
vec.vy = car_cos->headLight.vy + car_cos->cog.vy;
|
|
vec.vz = car_cos->headLight.vz + car_cos->cog.vz;
|
|
|
|
offset = ((car_cos->extraInfo & 0xC00) >> 8) + 10;
|
|
doubleFlag = (car_cos->extraInfo & 0x8000);
|
|
verticalFlag = (car_cos->extraInfo & 0x2000);
|
|
|
|
// draw front lights
|
|
lit = 0;
|
|
loop = 0;
|
|
do {
|
|
lights = 0;
|
|
lightFlag = 8 << (loop & 0x1f);
|
|
|
|
col.r = 128;
|
|
col.g = 124;
|
|
col.b = 112;
|
|
col2 = col;
|
|
|
|
if (cp->ap.damage[loop] < 1000)
|
|
{
|
|
if (doubleFlag)
|
|
{
|
|
if (verticalFlag)
|
|
{
|
|
Position1.vy = offset + vec.vy;
|
|
Position2.vy = vec.vy - offset;
|
|
|
|
Position1.vx = vec.vx;
|
|
Position2.vx = vec.vx;
|
|
}
|
|
else
|
|
{
|
|
Position1.vx = offset + vec.vx;
|
|
Position2.vx = vec.vx - offset;
|
|
|
|
Position1.vy = vec.vy;
|
|
Position2.vy = vec.vy;
|
|
}
|
|
|
|
Position1.vz = vec.vz + (cp->ap.damage[loop] >> 6);
|
|
Position2.vz = vec.vz + (cp->ap.damage[loop] >> 6);
|
|
|
|
ShowCarlight(&Position1, cp, &col, HEADLIGHT_SIZE, HEADLIGHT_SIZE*4, &light_texture, lightFlag & 0xff | 1);
|
|
|
|
lights = 1;
|
|
lit++;
|
|
|
|
if (cp->ap.damage[loop] < 500)
|
|
{
|
|
lights++;
|
|
|
|
ShowCarlight(&Position2, cp, &col2, HEADLIGHT_SIZE, HEADLIGHT_SIZE * 4, &light_texture, 1);
|
|
lit++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Position1.vx = vec.vx;
|
|
Position1.vy = vec.vy;
|
|
|
|
Position1.vz = vec.vz + (cp->ap.damage[loop] >> 6);
|
|
Position2.vz = vec.vz + (cp->ap.damage[loop] >> 6);
|
|
|
|
ShowCarlight(&Position1, cp, &col, HEADLIGHT_SIZE, HEADLIGHT_SIZE * 4, &light_texture, lightFlag & 0xff | 1);
|
|
|
|
lights = 1;
|
|
lit++;
|
|
|
|
if (cp->ap.damage[loop] < 500)
|
|
lights++;
|
|
}
|
|
}
|
|
|
|
if (loop == 0)
|
|
LeftLight = lights;
|
|
else
|
|
RightLight = lights;
|
|
|
|
vec.vx = cogOffset * 2 - vec.vx;
|
|
offset = -offset;
|
|
|
|
loop++;
|
|
} while (loop < 2);
|
|
|
|
|
|
// check if back lights are supported
|
|
// and draw
|
|
if (car_cos->extraInfo & 8)
|
|
{
|
|
offset = ((car_cos->extraInfo & 0x300) >> 6) + 10;
|
|
doubleFlag = car_cos->extraInfo & 0x4000;
|
|
verticalFlag = car_cos->extraInfo & 0x1000;
|
|
|
|
vec.vx = car_cos->brakeLight.vx + car_cos->cog.vx;
|
|
vec.vy = car_cos->brakeLight.vy + car_cos->cog.vy;
|
|
vec.vz = car_cos->brakeLight.vz + car_cos->cog.vz;
|
|
|
|
loop = 0;
|
|
|
|
do {
|
|
lightFlag = 2 << (loop & 0x1f);
|
|
damIndex = (4 - loop);
|
|
|
|
col.r = 110;
|
|
col.b = 0;
|
|
col.g = 0;
|
|
|
|
col2 = col;
|
|
|
|
if (cp->ap.damage[damIndex] < 500)
|
|
{
|
|
if (doubleFlag)
|
|
{
|
|
// double flag
|
|
if (verticalFlag)
|
|
{
|
|
Position1.vy = offset + vec.vy;
|
|
Position2.vy = vec.vy - offset;
|
|
|
|
Position1.vx = vec.vx;
|
|
Position2.vx = vec.vx;
|
|
}
|
|
else
|
|
{
|
|
Position1.vx = offset + vec.vx;
|
|
Position2.vx = vec.vx - offset;
|
|
|
|
Position1.vy = vec.vy;
|
|
Position2.vy = vec.vy;
|
|
}
|
|
|
|
Position2.vz = vec.vz - (cp->ap.damage[damIndex] >> 6);
|
|
Position1.vz = vec.vz - (cp->ap.damage[damIndex] >> 6);
|
|
|
|
ShowCarlight(&Position1, cp, &col, BACKLIGHT_SIZE, BACKLIGHT_SIZE * 3, &light_texture, lightFlag & 0xff);
|
|
ShowCarlight(&Position2, cp, &col2, BACKLIGHT_SIZE, BACKLIGHT_SIZE * 3, &light_texture, 0);
|
|
}
|
|
else
|
|
{
|
|
Position1 = vec;
|
|
|
|
ShowCarlight(&Position1, cp, &col, BACKLIGHT_SIZE, BACKLIGHT_SIZE * 3, &light_texture, lightFlag & 0xff);
|
|
}
|
|
|
|
*life2 += 16;
|
|
}
|
|
|
|
vec.vx = cogOffset * 2 - vec.vx;
|
|
offset = -offset;
|
|
|
|
loop++;
|
|
} while (loop < 2);
|
|
}
|
|
|
|
// front lights pool
|
|
if (lit)
|
|
{
|
|
col.r = 128;
|
|
col.g = 120;
|
|
col.b = 110;
|
|
|
|
PlacePoolForCar(cp, &col, 1, 0);
|
|
}
|
|
|
|
// back lights pool
|
|
col.r = *life2;
|
|
if (col.r)
|
|
{
|
|
col.b = 0;
|
|
col.g = 0;
|
|
|
|
PlacePoolForCar(cp, &col, 0, 0);
|
|
*life2 = 0;
|
|
}
|
|
}
|
|
|
|
// [D] [T]
|
|
void AddSmokingEngine(CAR_DATA *cp, int black_smoke, int WheelSpeed)
|
|
{
|
|
CAR_COSMETICS *car_cos;
|
|
VECTOR SmokePos;
|
|
VECTOR Drift;
|
|
SVECTOR svec;
|
|
|
|
if((CameraCnt & 3U) == (CAR_INDEX(cp) & 3U) && pauseflag == 0)
|
|
{
|
|
car_cos = cp->ap.carCos;
|
|
|
|
svec.vx = (rand() & 0x7f) - 0x40; //car_cos->smoke.vx + car_cos->cog.vx;
|
|
svec.vy = car_cos->smoke.vy + car_cos->cog.vy;
|
|
svec.vz = car_cos->smoke.vz + car_cos->cog.vz;
|
|
|
|
SmokePos.vx = cp->hd.where.t[0];
|
|
SmokePos.vy = -cp->hd.where.t[1];
|
|
SmokePos.vz = cp->hd.where.t[2];
|
|
|
|
if (black_smoke != 0)
|
|
SmokePos.vy -= 50;
|
|
|
|
gte_SetRotMatrix(cp->hd.drawCarMat.m);
|
|
|
|
InitFXPos(&SmokePos, &svec, cp);
|
|
GetSmokeDrift(&Drift);
|
|
|
|
if (black_smoke)
|
|
Setup_Smoke(&SmokePos, 100, 500, SMOKE_BLACK, WheelSpeed, &Drift, 0);
|
|
else
|
|
Setup_Smoke(&SmokePos, 100, 400, SMOKE_WHITE, WheelSpeed, &Drift, 0);
|
|
}
|
|
}
|
|
|
|
// [A] custom function for bringing back exhaust
|
|
void AddExhaustSmoke(CAR_DATA *cp, int black_smoke, int WheelSpeed)
|
|
{
|
|
CAR_COSMETICS *car_cos;
|
|
VECTOR SmokePos;
|
|
VECTOR Drift;
|
|
SVECTOR svec;
|
|
SVECTOR smokedir;
|
|
|
|
D_CHECK_ERROR(cp < car_data, "Invalid car");
|
|
|
|
if (cp->controlType == CONTROL_TYPE_CIV_AI && cp->ai.c.thrustState == 3 && (cp->ai.c.ctrlState == 5 || cp->ai.c.ctrlState == 7))
|
|
return;
|
|
|
|
if (WheelSpeed > 512 * 64)
|
|
return;
|
|
|
|
if ((CameraCnt & 3U) == (CAR_INDEX(cp) & 3U) && pauseflag == 0)
|
|
{
|
|
car_cos = cp->ap.carCos;
|
|
|
|
svec.vx = car_cos->exhaust.vx + car_cos->cog.vx;
|
|
svec.vy = car_cos->exhaust.vy + car_cos->cog.vy;
|
|
svec.vz = car_cos->exhaust.vz + car_cos->cog.vz;
|
|
|
|
SmokePos.vx = cp->hd.where.t[0];
|
|
SmokePos.vy = -cp->hd.where.t[1];
|
|
SmokePos.vz = cp->hd.where.t[2];
|
|
|
|
gte_SetRotMatrix(cp->hd.drawCarMat.m);
|
|
|
|
InitFXPos(&SmokePos, &svec, cp);
|
|
GetSmokeDrift(&Drift);
|
|
|
|
gte_ldv0(&svec);
|
|
gte_rtir();
|
|
gte_stsv(&smokedir);
|
|
|
|
Drift.vx /= 2;
|
|
Drift.vz /= 2;
|
|
|
|
Drift.vx -= FIXEDH(smokedir.vx) / 2;
|
|
Drift.vz -= FIXEDH(smokedir.vz) / 2;
|
|
|
|
if (black_smoke)
|
|
Setup_Smoke(&SmokePos, 10, 40, SMOKE_BLACK, WheelSpeed, &Drift, 1);
|
|
else
|
|
Setup_Smoke(&SmokePos, 10, 40, SMOKE_WHITE, WheelSpeed, &Drift, 1);
|
|
}
|
|
}
|
|
|
|
// [D] [T]
|
|
void AddFlamingEngine(CAR_DATA *cp)
|
|
{
|
|
CAR_COSMETICS *car_cos;
|
|
VECTOR SmokePos;
|
|
SVECTOR svec;
|
|
VECTOR Drift;
|
|
|
|
if ((CameraCnt & 1U) == (CAR_INDEX(cp) & 1U) && pauseflag == 0)
|
|
{
|
|
car_cos = cp->ap.carCos;
|
|
|
|
svec.vx = (rand() & 0x3f); //car_cos->smoke.vx + car_cos->cog.vx;
|
|
svec.vy = car_cos->fire.vy + car_cos->cog.vy;
|
|
svec.vz = car_cos->fire.vz + car_cos->cog.vz + (rand() & 0x3f);
|
|
|
|
SmokePos.vx = (cp->hd).where.t[0];
|
|
|
|
SmokePos.vz = (cp->hd).where.t[2];
|
|
SmokePos.vy = -(cp->hd).where.t[1];
|
|
|
|
SetRotMatrix(&(cp->hd).drawCarMat);
|
|
InitFXPos(&SmokePos, &svec, cp);
|
|
Drift.vx = 0;
|
|
Drift.vy = 0;
|
|
Drift.vz = 0;
|
|
|
|
Setup_Smoke(&SmokePos, 50, 100, SMOKE_FIRE, 0, &Drift, 0);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|