mirror of
https://github.com/halpz/re3.git
synced 2025-07-17 03:38:10 +00:00
the great reorganization
This commit is contained in:
18
src/vehicles/Automobile.cpp
Normal file
18
src/vehicles/Automobile.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Automobile.h"
|
||||
|
||||
CAutomobile::CAutomobile(int mi, uint8 owner)
|
||||
{
|
||||
ctor(mi, owner);
|
||||
}
|
||||
|
||||
WRAPPER CAutomobile* CAutomobile::ctor(int, uint8) { EAXJMP(0x52C6B0); }
|
||||
|
||||
WRAPPER void CAutomobile::SetDoorDamage(int32, uint32, bool) { EAXJMP(0x530200); }
|
||||
WRAPPER void CAutomobile::SetPanelDamage(int32, uint32, bool) { EAXJMP(0x5301A0); }
|
||||
WRAPPER void CAutomobile::SetBumperDamage(int32, uint32, bool) { EAXJMP(0x530120); }
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x52D170, &CAutomobile::dtor, PATCH_JUMP);
|
||||
ENDPATCHES
|
67
src/vehicles/Automobile.h
Normal file
67
src/vehicles/Automobile.h
Normal file
@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#include "DamageManager.h"
|
||||
#include "Vehicle.h"
|
||||
|
||||
struct CDoor
|
||||
{
|
||||
float m_fAngleWhenOpened;
|
||||
float m_fAngleWhenClosed;
|
||||
char field_8;
|
||||
char field_9;
|
||||
char field_10;
|
||||
char field_11;
|
||||
float m_fAngle;
|
||||
float m_fPreviousAngle;
|
||||
float m_fAngularVelocity;
|
||||
CVector m_vecVelocity;
|
||||
};
|
||||
|
||||
class CAutomobile : public CVehicle
|
||||
{
|
||||
public:
|
||||
// 0x288
|
||||
CDamageManager Damage;
|
||||
CDoor Doors[6];
|
||||
RwFrame *m_aCarNodes[NUM_CAR_NODES];
|
||||
CColPoint m_aWheelColPoints[4];
|
||||
float m_aSuspensionSpringRatio[4];
|
||||
float m_aSuspensionSpringRatioPrev[4];
|
||||
float m_aWheelSkidThing[4];
|
||||
int field_49C;
|
||||
bool m_aWheelSkidmarkMuddy[4];
|
||||
bool m_aWheelSkidmarkBloody[4];
|
||||
float m_aWheelRotation[4];
|
||||
float m_aWheelPosition[4];
|
||||
float m_aWheelSpeed[4];
|
||||
uint8 stuff3[12];
|
||||
uint32 m_nBusDoorTimerEnd;
|
||||
uint32 m_nBusDoorTimerStart;
|
||||
float m_aSuspensionSpringLength[4];
|
||||
float m_aSuspensionLineLength[4];
|
||||
float m_fHeightAboveRoad;
|
||||
float m_fImprovedHandling;
|
||||
uint8 stuff6[32];
|
||||
CPhysical *m_aGroundPhysical[4]; // physicals touching wheels
|
||||
CVector m_aGroundOffset[4]; // from ground object to colpoint
|
||||
CEntity *m_pBlowUpEntity;
|
||||
float m_weaponThingA; // TODO
|
||||
float m_weaponThingB; // TODO
|
||||
float m_fCarGunLR;
|
||||
float m_fCarGunUD;
|
||||
float m_fWindScreenRotation;
|
||||
uint8 stuff4[4];
|
||||
uint8 m_nWheelsOnGround_2;
|
||||
uint8 m_nWheelsOnGround;
|
||||
uint8 m_nWheelsOnGroundPrev;
|
||||
uint8 stuff5[5];
|
||||
int32 m_aWheelState[4];
|
||||
|
||||
CAutomobile(int, uint8);
|
||||
CAutomobile* ctor(int, uint8);
|
||||
void SetDoorDamage(int32, uint32, bool); /* TODO: eDoors */
|
||||
void SetPanelDamage(int32, uint32, bool); /* TODO: ePanels */
|
||||
void SetBumperDamage(int32, uint32, bool); /* TODO: ePanels */
|
||||
void dtor() { this->CAutomobile::~CAutomobile(); }
|
||||
};
|
||||
static_assert(sizeof(CAutomobile) == 0x5A8, "CAutomobile: error");
|
14
src/vehicles/Boat.cpp
Normal file
14
src/vehicles/Boat.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Boat.h"
|
||||
|
||||
CBoat::CBoat(int mi, uint8 owner)
|
||||
{
|
||||
ctor(mi, owner);
|
||||
}
|
||||
|
||||
WRAPPER CBoat* CBoat::ctor(int, uint8) { EAXJMP(0x53E3E0); }
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x53E790, &CBoat::dtor, PATCH_JUMP);
|
||||
ENDPATCHES
|
17
src/vehicles/Boat.h
Normal file
17
src/vehicles/Boat.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "Vehicle.h"
|
||||
|
||||
class CBoat : public CVehicle
|
||||
{
|
||||
public:
|
||||
// 0x288
|
||||
uint8 stuff1[57];
|
||||
bool m_bIsAnchored;
|
||||
uint8 stuff[450];
|
||||
|
||||
CBoat(int, uint8);
|
||||
CBoat* ctor(int, uint8);
|
||||
void dtor() { this->CBoat::~CBoat(); };
|
||||
};
|
||||
static_assert(sizeof(CBoat) == 0x484, "CBoat: error");
|
243
src/vehicles/DamageManager.cpp
Normal file
243
src/vehicles/DamageManager.cpp
Normal file
@ -0,0 +1,243 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "General.h"
|
||||
#include "DamageManager.h"
|
||||
|
||||
|
||||
float G_aComponentDamage[] = { 2.5f, 1.25f, 3.2f, 1.4f, 2.5f, 2.8f, 0.5f };
|
||||
|
||||
void
|
||||
CDamageManager::ResetDamageStatus(void)
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
}
|
||||
|
||||
void
|
||||
CDamageManager::FuckCarCompletely(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
m_wheelStatus[0] = 2;
|
||||
// wheels 1-3 not reset?
|
||||
|
||||
m_doorStatus[0] = 3;
|
||||
m_doorStatus[1] = 3;
|
||||
m_doorStatus[2] = 3;
|
||||
m_doorStatus[3] = 3;
|
||||
m_doorStatus[4] = 3;
|
||||
m_doorStatus[5] = 3;
|
||||
|
||||
for(i = 0; i < 3; i++){
|
||||
#ifdef FIX_BUGS
|
||||
ProgressPanelDamage(VEHBUMPER_FRONT);
|
||||
ProgressPanelDamage(VEHBUMPER_REAR);
|
||||
#else
|
||||
// this can't be right
|
||||
ProgressPanelDamage(COMPONENT_BUMPER_FRONT);
|
||||
ProgressPanelDamage(COMPONENT_BUMPER_REAR);
|
||||
#endif
|
||||
}
|
||||
// Why set to no damage?
|
||||
m_lightStatus = 0;
|
||||
m_panelStatus = 0;
|
||||
SetEngineStatus(250);
|
||||
}
|
||||
|
||||
bool
|
||||
CDamageManager::ApplyDamage(tComponent component, float damage, float unused)
|
||||
{
|
||||
tComponentGroup group;
|
||||
uint8 subComp;
|
||||
|
||||
GetComponentGroup(component, &group, &subComp);
|
||||
damage *= G_aComponentDamage[group];
|
||||
if(damage > 150.0f){
|
||||
switch(group){
|
||||
case COMPGROUP_WHEEL:
|
||||
ProgressWheelDamage(subComp);
|
||||
break;
|
||||
case COMPGROUP_DOOR:
|
||||
case COMPGROUP_BOOT:
|
||||
ProgressDoorDamage(subComp);
|
||||
break;
|
||||
case COMPGROUP_BONNET:
|
||||
if(damage > 220.0f)
|
||||
ProgressEngineDamage();
|
||||
ProgressDoorDamage(subComp);
|
||||
break;
|
||||
case COMPGROUP_PANEL:
|
||||
// so windscreen is a light?
|
||||
SetLightStatus((eLights)subComp, 1);
|
||||
// fall through
|
||||
case COMPGROUP_BUMPER:
|
||||
if(damage > 220.0f &&
|
||||
(component == COMPONENT_PANEL_FRONT_LEFT ||
|
||||
component == COMPONENT_PANEL_FRONT_RIGHT ||
|
||||
component == COMPONENT_PANEL_WINDSCREEN))
|
||||
ProgressEngineDamage();
|
||||
ProgressPanelDamage(subComp);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CDamageManager::GetComponentGroup(tComponent component, tComponentGroup *componentGroup, uint8 *subComp)
|
||||
{
|
||||
*subComp = -2; // ??
|
||||
|
||||
// This is done very strangely in the game, maybe an optimized switch?
|
||||
if(component >= COMPONENT_PANEL_FRONT_LEFT){
|
||||
if(component >= COMPONENT_BUMPER_FRONT)
|
||||
*componentGroup = COMPGROUP_BUMPER;
|
||||
else
|
||||
*componentGroup = COMPGROUP_PANEL;
|
||||
*subComp = component - COMPONENT_PANEL_FRONT_LEFT;
|
||||
return true;
|
||||
}else if(component >= COMPONENT_DOOR_BONNET){
|
||||
if(component == COMPONENT_DOOR_BONNET)
|
||||
*componentGroup = COMPGROUP_BONNET;
|
||||
else if(component == COMPONENT_DOOR_BOOT)
|
||||
*componentGroup = COMPGROUP_BOOT;
|
||||
else
|
||||
*componentGroup = COMPGROUP_DOOR;
|
||||
*subComp = component - COMPONENT_DOOR_BONNET;
|
||||
return true;
|
||||
}else if(component >= COMPONENT_WHEEL_FRONT_LEFT){
|
||||
*componentGroup = COMPGROUP_WHEEL;
|
||||
*subComp = component - COMPONENT_WHEEL_FRONT_LEFT;
|
||||
return true;
|
||||
}else if(component >= COMPONENT_DEFAULT){
|
||||
*componentGroup = COMPGROUP_DEFAULT;
|
||||
*subComp = component - COMPONENT_DEFAULT;
|
||||
return true;
|
||||
}else
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
CDamageManager::SetDoorStatus(int32 door, uint32 status)
|
||||
{
|
||||
m_doorStatus[door] = status;
|
||||
}
|
||||
|
||||
int32
|
||||
CDamageManager::GetDoorStatus(int32 door)
|
||||
{
|
||||
return m_doorStatus[door];
|
||||
}
|
||||
|
||||
bool
|
||||
CDamageManager::ProgressDoorDamage(uint8 door)
|
||||
{
|
||||
int status = GetDoorStatus(door);
|
||||
if(status == 3)
|
||||
return false;
|
||||
SetDoorStatus(door, status+1);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CDamageManager::SetPanelStatus(int32 panel, uint32 status)
|
||||
{
|
||||
m_panelStatus = dpb(status, panel*4, 4, m_panelStatus);
|
||||
}
|
||||
|
||||
int32
|
||||
CDamageManager::GetPanelStatus(int32 panel)
|
||||
{
|
||||
return ldb(panel*4, 4, m_panelStatus);
|
||||
}
|
||||
|
||||
bool
|
||||
CDamageManager::ProgressPanelDamage(uint8 panel)
|
||||
{
|
||||
int status = GetPanelStatus(panel);
|
||||
if(status == 3)
|
||||
return false;
|
||||
SetPanelStatus(panel, status+1);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CDamageManager::SetLightStatus(eLights light, uint32 status)
|
||||
{
|
||||
m_lightStatus = dpb(status, light*2, 2, m_lightStatus);
|
||||
}
|
||||
|
||||
int32
|
||||
CDamageManager::GetLightStatus(eLights light)
|
||||
{
|
||||
return ldb(light*2, 2, m_lightStatus);
|
||||
}
|
||||
|
||||
void
|
||||
CDamageManager::SetWheelStatus(int32 wheel, uint32 status)
|
||||
{
|
||||
m_wheelStatus[wheel] = status;
|
||||
}
|
||||
|
||||
int32
|
||||
CDamageManager::GetWheelStatus(int32 wheel)
|
||||
{
|
||||
return m_wheelStatus[wheel];
|
||||
}
|
||||
|
||||
bool
|
||||
CDamageManager::ProgressWheelDamage(uint8 wheel)
|
||||
{
|
||||
int status = GetWheelStatus(wheel);
|
||||
if(status == 3)
|
||||
return false;
|
||||
SetWheelStatus(wheel, status+1);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CDamageManager::SetEngineStatus(uint32 status)
|
||||
{
|
||||
if(status > 250)
|
||||
m_engineStatus = 250;
|
||||
else
|
||||
m_engineStatus = status;
|
||||
}
|
||||
|
||||
int32
|
||||
CDamageManager::GetEngineStatus(void)
|
||||
{
|
||||
return m_engineStatus;
|
||||
}
|
||||
|
||||
bool
|
||||
CDamageManager::ProgressEngineDamage(void)
|
||||
{
|
||||
int status = GetEngineStatus();
|
||||
int newstatus = status + 32 + (CGeneral::GetRandomNumber() & 0x1F);
|
||||
if(status < 225 && newstatus > 224)
|
||||
newstatus = 224;
|
||||
SetEngineStatus(newstatus);
|
||||
return true;
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x545850, &CDamageManager::ResetDamageStatus, PATCH_JUMP);
|
||||
InjectHook(0x545B70, &CDamageManager::FuckCarCompletely, PATCH_JUMP);
|
||||
InjectHook(0x545790, &CDamageManager::GetComponentGroup, PATCH_JUMP);
|
||||
InjectHook(0x545A80, &CDamageManager::ApplyDamage, PATCH_JUMP);
|
||||
InjectHook(0x545920, &CDamageManager::SetDoorStatus, PATCH_JUMP);
|
||||
InjectHook(0x545930, &CDamageManager::GetDoorStatus, PATCH_JUMP);
|
||||
InjectHook(0x545970, &CDamageManager::ProgressDoorDamage, PATCH_JUMP);
|
||||
InjectHook(0x5458B0, &CDamageManager::SetPanelStatus, PATCH_JUMP);
|
||||
InjectHook(0x5458E0, (int32 (CDamageManager::*)(int32))&CDamageManager::GetPanelStatus, PATCH_JUMP);
|
||||
InjectHook(0x545A00, &CDamageManager::ProgressPanelDamage, PATCH_JUMP);
|
||||
InjectHook(0x545860, &CDamageManager::SetLightStatus, PATCH_JUMP);
|
||||
InjectHook(0x545890, &CDamageManager::GetLightStatus, PATCH_JUMP);
|
||||
InjectHook(0x545900, &CDamageManager::SetWheelStatus, PATCH_JUMP);
|
||||
InjectHook(0x545910, &CDamageManager::GetWheelStatus, PATCH_JUMP);
|
||||
InjectHook(0x545A40, &CDamageManager::ProgressWheelDamage, PATCH_JUMP);
|
||||
InjectHook(0x545940, &CDamageManager::SetEngineStatus, PATCH_JUMP);
|
||||
InjectHook(0x545960, &CDamageManager::GetEngineStatus, PATCH_JUMP);
|
||||
InjectHook(0x5459B0, &CDamageManager::ProgressEngineDamage, PATCH_JUMP);
|
||||
ENDPATCHES
|
92
src/vehicles/DamageManager.h
Normal file
92
src/vehicles/DamageManager.h
Normal file
@ -0,0 +1,92 @@
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
|
||||
// TODO: move some of this into Vehicle.h
|
||||
|
||||
enum tComponent
|
||||
{
|
||||
COMPONENT_DEFAULT,
|
||||
COMPONENT_WHEEL_FRONT_LEFT,
|
||||
COMPONENT_WHEEL_FRONT_RIGHT,
|
||||
COMPONENT_WHEEL_REAR_LEFT,
|
||||
COMPONENT_WHEEL_REAR_RIGHT,
|
||||
COMPONENT_DOOR_BONNET,
|
||||
COMPONENT_DOOR_BOOT,
|
||||
COMPONENT_DOOR_FRONT_LEFT,
|
||||
COMPONENT_DOOR_FRONT_RIGHT,
|
||||
COMPONENT_DOOR_REAR_LEFT,
|
||||
COMPONENT_DOOR_REAR_RIGHT,
|
||||
COMPONENT_PANEL_FRONT_LEFT,
|
||||
COMPONENT_PANEL_FRONT_RIGHT,
|
||||
COMPONENT_PANEL_REAR_LEFT,
|
||||
COMPONENT_PANEL_REAR_RIGHT,
|
||||
COMPONENT_PANEL_WINDSCREEN,
|
||||
COMPONENT_BUMPER_FRONT,
|
||||
COMPONENT_BUMPER_REAR,
|
||||
};
|
||||
|
||||
enum tComponentGroup
|
||||
{
|
||||
COMPGROUP_BUMPER,
|
||||
COMPGROUP_WHEEL,
|
||||
COMPGROUP_DOOR,
|
||||
COMPGROUP_BONNET,
|
||||
COMPGROUP_BOOT,
|
||||
COMPGROUP_PANEL,
|
||||
COMPGROUP_DEFAULT,
|
||||
};
|
||||
|
||||
enum eLights
|
||||
{
|
||||
VEHLIGHT_FRONT_LEFT,
|
||||
VEHLIGHT_FRONT_RIGHT,
|
||||
VEHLIGHT_REAR_LEFT,
|
||||
VEHLIGHT_REAR_RIGHT,
|
||||
};
|
||||
|
||||
enum {
|
||||
VEHPANEL_FRONT_LEFT,
|
||||
VEHPANEL_FRONT_RIGHT,
|
||||
VEHPANEL_REAR_LEFT,
|
||||
VEHPANEL_REAR_RIGHT,
|
||||
VEHPANEL_WINDSCREEN,
|
||||
VEHBUMPER_FRONT,
|
||||
VEHBUMPER_REAR,
|
||||
};
|
||||
|
||||
class CDamageManager
|
||||
{
|
||||
public:
|
||||
|
||||
float field_0;
|
||||
uint8 m_engineStatus;
|
||||
uint8 m_wheelStatus[4];
|
||||
uint8 m_doorStatus[6];
|
||||
uint32 m_lightStatus;
|
||||
uint32 m_panelStatus;
|
||||
uint32 field_24;
|
||||
|
||||
void ResetDamageStatus(void);
|
||||
void FuckCarCompletely(void);
|
||||
bool ApplyDamage(tComponent component, float damage, float unused);
|
||||
bool GetComponentGroup(tComponent component, tComponentGroup *componentGroup, uint8 *foo);
|
||||
|
||||
void SetDoorStatus(int32 door, uint32 status);
|
||||
int32 GetDoorStatus(int32 door);
|
||||
bool ProgressDoorDamage(uint8 door);
|
||||
void SetPanelStatus(int32 panel, uint32 status);
|
||||
int32 GetPanelStatus(int32 panel);
|
||||
bool ProgressPanelDamage(uint8 panel);
|
||||
// needed for CReplay
|
||||
static int32 GetPanelStatus(uint32 panelstatus, int32 panel) { return ldb(panel*4, 4, panelstatus); }
|
||||
void SetLightStatus(eLights light, uint32 status);
|
||||
int32 GetLightStatus(eLights light);
|
||||
void SetWheelStatus(int32 wheel, uint32 status);
|
||||
int32 GetWheelStatus(int32 wheel);
|
||||
bool ProgressWheelDamage(uint8 wheel);
|
||||
void SetEngineStatus(uint32 status);
|
||||
int32 GetEngineStatus(void);
|
||||
bool ProgressEngineDamage(void);
|
||||
};
|
||||
VALIDATE_SIZE(CDamageManager, 0x1C);
|
247
src/vehicles/HandlingMgr.cpp
Normal file
247
src/vehicles/HandlingMgr.cpp
Normal file
@ -0,0 +1,247 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "main.h"
|
||||
#include "FileMgr.h"
|
||||
#include "HandlingMgr.h"
|
||||
|
||||
cHandlingDataMgr &mod_HandlingManager = *(cHandlingDataMgr*)0x728060;
|
||||
|
||||
char *HandlingFilename = "HANDLING.CFG";
|
||||
|
||||
char VehicleNames[NUMHANDLINGS][14] = {
|
||||
"LANDSTAL",
|
||||
"IDAHO",
|
||||
"STINGER",
|
||||
"LINERUN",
|
||||
"PEREN",
|
||||
"SENTINEL",
|
||||
"PATRIOT",
|
||||
"FIRETRUK",
|
||||
"TRASH",
|
||||
"STRETCH",
|
||||
"MANANA",
|
||||
"INFERNUS",
|
||||
"BLISTA",
|
||||
"PONY",
|
||||
"MULE",
|
||||
"CHEETAH",
|
||||
"AMBULAN",
|
||||
"FBICAR",
|
||||
"MOONBEAM",
|
||||
"ESPERANT",
|
||||
"TAXI",
|
||||
"KURUMA",
|
||||
"BOBCAT",
|
||||
"MRWHOOP",
|
||||
"BFINJECT",
|
||||
"POLICE",
|
||||
"ENFORCER",
|
||||
"SECURICA",
|
||||
"BANSHEE",
|
||||
"PREDATOR",
|
||||
"BUS",
|
||||
"RHINO",
|
||||
"BARRACKS",
|
||||
"TRAIN",
|
||||
"HELI",
|
||||
"DODO",
|
||||
"COACH",
|
||||
"CABBIE",
|
||||
"STALLION",
|
||||
"RUMPO",
|
||||
"RCBANDIT",
|
||||
"BELLYUP",
|
||||
"MRWONGS",
|
||||
"MAFIA",
|
||||
"YARDIE",
|
||||
"YAKUZA",
|
||||
"DIABLOS",
|
||||
"COLUMB",
|
||||
"HOODS",
|
||||
"AIRTRAIN",
|
||||
"DEADDODO",
|
||||
"SPEEDER",
|
||||
"REEFER",
|
||||
"PANLANT",
|
||||
"FLATBED",
|
||||
"YANKEE",
|
||||
"BORGNINE"
|
||||
};
|
||||
|
||||
cHandlingDataMgr::cHandlingDataMgr(void)
|
||||
{
|
||||
memset(this, 0, sizeof(this));
|
||||
}
|
||||
|
||||
void
|
||||
cHandlingDataMgr::Initialise(void)
|
||||
{
|
||||
LoadHandlingData();
|
||||
field_0 = 0.1f;
|
||||
field_4 = 0.9f;
|
||||
field_8 = 1.0f;
|
||||
field_C = 0.8f;
|
||||
field_10 = 0.98f;
|
||||
}
|
||||
|
||||
void
|
||||
cHandlingDataMgr::LoadHandlingData(void)
|
||||
{
|
||||
char *start, *end;
|
||||
char line[201]; // weird value
|
||||
char delim[4]; // not sure
|
||||
char *word;
|
||||
int field, handlingId;
|
||||
int keepGoing;
|
||||
tHandlingData *handling;
|
||||
|
||||
CFileMgr::SetDir("DATA");
|
||||
CFileMgr::LoadFile(HandlingFilename, work_buff, sizeof(work_buff), "r");
|
||||
CFileMgr::SetDir("");
|
||||
|
||||
start = (char*)work_buff;
|
||||
end = start+1;
|
||||
handling = nil;
|
||||
keepGoing = 1;
|
||||
|
||||
while(keepGoing){
|
||||
// find end of line
|
||||
while(*end != '\n') end++;
|
||||
|
||||
// get line
|
||||
strncpy(line, start, end - start);
|
||||
line[end - start] = '\0';
|
||||
start = end+1;
|
||||
end = start+1;
|
||||
|
||||
// yeah, this is kinda crappy
|
||||
if(strncmp(line, ";the end", 9) == 0)
|
||||
keepGoing = 0;
|
||||
else if(line[0] != ';'){
|
||||
field = 0;
|
||||
strcpy(delim, " \t");
|
||||
// FIX: game seems to use a do-while loop here
|
||||
for(word = strtok(line, delim); word; word = strtok(nil, delim)){
|
||||
switch(field){
|
||||
case 0:
|
||||
handlingId = FindExactWord(word, (const char*)VehicleNames, 14, NUMHANDLINGS);
|
||||
assert(handlingId >= 0 && handlingId < NUMHANDLINGS);
|
||||
handling = &HandlingData[handlingId];
|
||||
handling->nIdentifier = handlingId;
|
||||
break;
|
||||
case 1: handling->fMass = strtod(word, nil); break;
|
||||
case 2: handling->Dimension.x = strtod(word, nil); break;
|
||||
case 3: handling->Dimension.y = strtod(word, nil); break;
|
||||
case 4: handling->Dimension.z = strtod(word, nil); break;
|
||||
case 5: handling->CentreOfMass.x = strtod(word, nil); break;
|
||||
case 6: handling->CentreOfMass.y = strtod(word, nil); break;
|
||||
case 7: handling->CentreOfMass.z = strtod(word, nil); break;
|
||||
case 8: handling->nPercentSubmerged = atoi(word); break;
|
||||
case 9: handling->fTractionMultiplier = strtod(word, nil); break;
|
||||
case 10: handling->fTractionLoss = strtod(word, nil); break;
|
||||
case 11: handling->fTractionBias = strtod(word, nil); break;
|
||||
case 12: handling->TransmissionData.nNumberOfGears = atoi(word); break;
|
||||
case 13: handling->TransmissionData.fMaxVelocity = strtod(word, nil); break;
|
||||
case 14: handling->TransmissionData.fEngineAcceleration = strtod(word, nil) * 0.4f; break;
|
||||
case 15: handling->TransmissionData.nDriveType = word[0]; break;
|
||||
case 16: handling->TransmissionData.nEngineType = word[0]; break;
|
||||
case 17: handling->fBrakeDeceleration = strtod(word, nil); break;
|
||||
case 18: handling->fBrakeBias = strtod(word, nil); break;
|
||||
case 19: handling->bABS = !!atoi(word); break;
|
||||
case 20: handling->fSteeringLock = strtod(word, nil); break;
|
||||
case 21: handling->fSuspensionForceLevel = strtod(word, nil); break;
|
||||
case 22: handling->fSuspensionDampingLevel = strtod(word, nil); break;
|
||||
case 23: handling->fSeatOffsetDistance = strtod(word, nil); break;
|
||||
case 24: handling->fCollisionDamageMultiplier = strtod(word, nil); break;
|
||||
case 25: handling->nMonetaryValue = atoi(word); break;
|
||||
case 26: handling->fSuspensionUpperLimit = strtod(word, nil); break;
|
||||
case 27: handling->fSuspensionLowerLimit = strtod(word, nil); break;
|
||||
case 28: handling->fSuspensionBias = strtod(word, nil); break;
|
||||
case 29:
|
||||
sscanf(word, "%x", &handling->Flags);
|
||||
handling->TransmissionData.Flags = handling->Flags;
|
||||
break;
|
||||
case 30: handling->FrontLights = atoi(word); break;
|
||||
case 31: handling->RearLights = atoi(word); break;
|
||||
}
|
||||
field++;
|
||||
}
|
||||
ConvertDataToGameUnits(handling);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
cHandlingDataMgr::FindExactWord(const char *word, const char *words, int wordLen, int numWords)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < numWords; i++){
|
||||
// BUG: the game does something really stupid here, it's fixed here
|
||||
if(strncmp(word, words, wordLen) == 0)
|
||||
return i;
|
||||
words += wordLen;
|
||||
}
|
||||
return numWords;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cHandlingDataMgr::ConvertDataToGameUnits(tHandlingData *handling)
|
||||
{
|
||||
// TODO: figure out what exactly is being converted here
|
||||
float velocity, a, b, specificVolume;
|
||||
|
||||
handling->TransmissionData.fEngineAcceleration /= 2500.0f;
|
||||
handling->TransmissionData.fMaxVelocity /= 180.0f;
|
||||
handling->fBrakeDeceleration /= 2500.0f;
|
||||
handling->fTurnMass = (sq(handling->Dimension.x) + sq(handling->Dimension.y)) * handling->fMass / 12.0f;
|
||||
if(handling->fTurnMass < 10.0f)
|
||||
handling->fTurnMass *= 5.0f;
|
||||
handling->fInvMass = 1.0f/handling->fMass;
|
||||
handling->fBuoyancy = 100.0f/handling->nPercentSubmerged * 0.008*handling->fMass;
|
||||
|
||||
// What the hell is going on here?
|
||||
specificVolume = handling->Dimension.x*handling->Dimension.z*0.5f / handling->fMass; // ?
|
||||
a = 0.0f;
|
||||
b = 100.0f;
|
||||
velocity = handling->TransmissionData.fMaxVelocity;
|
||||
while(a < b && velocity > 0.0f){
|
||||
velocity -= 0.01;
|
||||
a = handling->TransmissionData.fEngineAcceleration/6.0f;
|
||||
b = -velocity * (1.0f/(specificVolume * sq(velocity) + 1.0f) - 1.0f);
|
||||
}
|
||||
|
||||
if(handling->nIdentifier == HANDLING_RCBANDIT){
|
||||
handling->TransmissionData.fUnkMaxVelocity = handling->TransmissionData.fMaxVelocity;
|
||||
}else{
|
||||
handling->TransmissionData.fUnkMaxVelocity = velocity;
|
||||
handling->TransmissionData.fMaxVelocity = velocity * 1.2f;
|
||||
}
|
||||
handling->TransmissionData.fMaxReverseVelocity = -0.2f;
|
||||
|
||||
if(handling->TransmissionData.nDriveType == '4')
|
||||
handling->TransmissionData.fEngineAcceleration /= 4.0f;
|
||||
else
|
||||
handling->TransmissionData.fEngineAcceleration /= 2.0f;
|
||||
|
||||
handling->TransmissionData.InitGearRatios();
|
||||
}
|
||||
|
||||
int32
|
||||
cHandlingDataMgr::GetHandlingId(const char *name)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < NUMHANDLINGS; i++)
|
||||
if(strncmp(VehicleNames[i], name, 14) == 0)
|
||||
break;
|
||||
return i;
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x546D80, &cHandlingDataMgr::Initialise, PATCH_JUMP);
|
||||
InjectHook(0x546DB0, &cHandlingDataMgr::LoadHandlingData, PATCH_JUMP);
|
||||
InjectHook(0x546BB0, &cHandlingDataMgr::ConvertDataToGameUnits, PATCH_JUMP);
|
||||
InjectHook(0x546AA0, &cHandlingDataMgr::FindExactWord, PATCH_JUMP);
|
||||
InjectHook(0x546B70, &cHandlingDataMgr::GetHandlingId, PATCH_JUMP);
|
||||
ENDPATCHES
|
139
src/vehicles/HandlingMgr.h
Normal file
139
src/vehicles/HandlingMgr.h
Normal file
@ -0,0 +1,139 @@
|
||||
#pragma once
|
||||
|
||||
#include "Transmission.h"
|
||||
|
||||
enum eHandlingId
|
||||
{
|
||||
HANDLING_LANDSTAL,
|
||||
HANDLING_IDAHO,
|
||||
HANDLING_STINGER,
|
||||
HANDLING_LINERUN,
|
||||
HANDLING_PEREN,
|
||||
HANDLING_SENTINEL,
|
||||
HANDLING_PATRIOT,
|
||||
HANDLING_FIRETRUK,
|
||||
HANDLING_TRASH,
|
||||
HANDLING_STRETCH,
|
||||
HANDLING_MANANA,
|
||||
HANDLING_INFERNUS,
|
||||
HANDLING_BLISTA,
|
||||
HANDLING_PONY,
|
||||
HANDLING_MULE,
|
||||
HANDLING_CHEETAH,
|
||||
HANDLING_AMBULAN,
|
||||
HANDLING_FBICAR,
|
||||
HANDLING_MOONBEAM,
|
||||
HANDLING_ESPERANT,
|
||||
HANDLING_TAXI,
|
||||
HANDLING_KURUMA,
|
||||
HANDLING_BOBCAT,
|
||||
HANDLING_MRWHOOP,
|
||||
HANDLING_BFINJECT,
|
||||
HANDLING_POLICE,
|
||||
HANDLING_ENFORCER,
|
||||
HANDLING_SECURICA,
|
||||
HANDLING_BANSHEE,
|
||||
HANDLING_PREDATOR,
|
||||
HANDLING_BUS,
|
||||
HANDLING_RHINO,
|
||||
HANDLING_BARRACKS,
|
||||
HANDLING_TRAIN,
|
||||
HANDLING_HELI,
|
||||
HANDLING_DODO,
|
||||
HANDLING_COACH,
|
||||
HANDLING_CABBIE,
|
||||
HANDLING_STALLION,
|
||||
HANDLING_RUMPO,
|
||||
HANDLING_RCBANDIT,
|
||||
HANDLING_BELLYUP,
|
||||
HANDLING_MRWONGS,
|
||||
HANDLING_MAFIA,
|
||||
HANDLING_YARDIE,
|
||||
HANDLING_YAKUZA,
|
||||
HANDLING_DIABLOS,
|
||||
HANDLING_COLUMB,
|
||||
HANDLING_HOODS,
|
||||
HANDLING_AIRTRAIN,
|
||||
HANDLING_DEADDODO,
|
||||
HANDLING_SPEEDER,
|
||||
HANDLING_REEFER,
|
||||
HANDLING_PANLANT,
|
||||
HANDLING_FLATBED,
|
||||
HANDLING_YANKEE,
|
||||
HANDLING_BORGNINE
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HANDLING_1G_BOOST = 1,
|
||||
HANDLING_2G_BOOST = 2,
|
||||
HANDLING_REV_BONNET = 4,
|
||||
HANDLING_HANGING_BOOT = 8,
|
||||
HANDLING_NO_DOORS = 0x10,
|
||||
HANDLING_IS_VAN = 0x20,
|
||||
HANDLING_IS_BUS = 0x40,
|
||||
HANDLING_IS_LOW = 0x80,
|
||||
HANDLING_DBL_EXHAUST = 0x100,
|
||||
HANDLING_TAILGATE_BOOT = 0x200,
|
||||
HANDLING_NOSWING_BOOT = 0x400,
|
||||
HANDLING_NONPLAYER_STABILISER = 0x800,
|
||||
HANDLING_NEUTRALHANDLING = 0x1000,
|
||||
HANDLING_HAS_NO_ROOF = 0x2000,
|
||||
HANDLING_IS_BIG = 0x4000,
|
||||
HANDLING_HALOGEN_LIGHTS = 0x8000,
|
||||
};
|
||||
|
||||
struct tHandlingData
|
||||
{
|
||||
int32 nIdentifier;
|
||||
float fMass;
|
||||
float fInvMass;
|
||||
float fTurnMass;
|
||||
CVector Dimension;
|
||||
CVector CentreOfMass;
|
||||
int8 nPercentSubmerged;
|
||||
float fBuoyancy;
|
||||
float fTractionMultiplier;
|
||||
cTransmission TransmissionData;
|
||||
float fBrakeDeceleration;
|
||||
float fBrakeBias;
|
||||
int8 bABS;
|
||||
float fSteeringLock;
|
||||
float fTractionLoss;
|
||||
float fTractionBias;
|
||||
uint32 field_AC;
|
||||
float fSuspensionForceLevel;
|
||||
float fSuspensionDampingLevel;
|
||||
float fSuspensionUpperLimit;
|
||||
float fSuspensionLowerLimit;
|
||||
float fSuspensionBias;
|
||||
float fCollisionDamageMultiplier;
|
||||
uint32 Flags;
|
||||
float fSeatOffsetDistance;
|
||||
int32 nMonetaryValue;
|
||||
int8 FrontLights;
|
||||
int8 RearLights;
|
||||
};
|
||||
VALIDATE_SIZE(tHandlingData, 0xD8);
|
||||
|
||||
class cHandlingDataMgr
|
||||
{
|
||||
float field_0; // unused it seems
|
||||
float field_4; // wheel related
|
||||
float field_8; //
|
||||
float field_C; // unused it seems
|
||||
float field_10; //
|
||||
tHandlingData HandlingData[NUMHANDLINGS];
|
||||
uint32 field_302C; // unused it seems, padding?
|
||||
|
||||
public:
|
||||
cHandlingDataMgr(void);
|
||||
void Initialise(void);
|
||||
void LoadHandlingData(void);
|
||||
int FindExactWord(const char *word, const char *words, int wordLen, int numWords);
|
||||
void ConvertDataToGameUnits(tHandlingData *handling);
|
||||
int32 GetHandlingId(const char *name);
|
||||
tHandlingData *GetHandlingData(eHandlingId id) { return &HandlingData[id]; }
|
||||
};
|
||||
VALIDATE_SIZE(cHandlingDataMgr, 0x3030);
|
||||
extern cHandlingDataMgr &mod_HandlingManager;
|
15
src/vehicles/Heli.cpp
Normal file
15
src/vehicles/Heli.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Heli.h"
|
||||
|
||||
CHeli::CHeli(int mi, uint8 owner)
|
||||
{
|
||||
ctor(mi, owner);
|
||||
}
|
||||
|
||||
WRAPPER CHeli* CHeli::ctor(int, uint8) { EAXJMP(0x547220); }
|
||||
WRAPPER void CHeli::SpecialHeliPreRender(void) { EAXJMP(0x54AE10); }
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x5474A0, &CHeli::dtor, PATCH_JUMP);
|
||||
ENDPATCHES
|
17
src/vehicles/Heli.h
Normal file
17
src/vehicles/Heli.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "Vehicle.h"
|
||||
|
||||
class CHeli : public CVehicle
|
||||
{
|
||||
public:
|
||||
// 0x288
|
||||
uint8 stuff[180];
|
||||
|
||||
CHeli(int, uint8);
|
||||
CHeli* ctor(int, uint8);
|
||||
void dtor(void) { this->CHeli::~CHeli(); }
|
||||
|
||||
static void SpecialHeliPreRender(void);
|
||||
};
|
||||
static_assert(sizeof(CHeli) == 0x33C, "CHeli: error");
|
19
src/vehicles/Plane.cpp
Normal file
19
src/vehicles/Plane.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Plane.h"
|
||||
|
||||
CPlane::CPlane(int mi, uint8 owner)
|
||||
{
|
||||
ctor(mi, owner);
|
||||
}
|
||||
|
||||
WRAPPER CPlane* CPlane::ctor(int, uint8) { EAXJMP(0x54B170); }
|
||||
|
||||
CPlane::~CPlane()
|
||||
{
|
||||
DeleteRwObject();
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x54B270, &CPlane::dtor, PATCH_JUMP);
|
||||
ENDPATCHES
|
18
src/vehicles/Plane.h
Normal file
18
src/vehicles/Plane.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
#include "Vehicle.h"
|
||||
|
||||
class CPlane : public CVehicle
|
||||
{
|
||||
public:
|
||||
// 0x288
|
||||
uint8 stuff[20];
|
||||
|
||||
CPlane(int, uint8);
|
||||
~CPlane(void);
|
||||
CPlane* ctor(int, uint8);
|
||||
void dtor(void) { this->CPlane::~CPlane(); }
|
||||
void FlagToDestroyWhenNextProcessed() { bRemoveFromWorld = true; }
|
||||
};
|
||||
static_assert(sizeof(CPlane) == 0x29C, "CPlane: error");
|
14
src/vehicles/Train.cpp
Normal file
14
src/vehicles/Train.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Train.h"
|
||||
|
||||
CTrain::CTrain(int mi, uint8 owner)
|
||||
{
|
||||
ctor(mi, owner);
|
||||
}
|
||||
|
||||
WRAPPER CTrain* CTrain::ctor(int, uint8) { EAXJMP(0x54E2A0); }
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x54E450, &CTrain::dtor, PATCH_JUMP);
|
||||
ENDPATCHES
|
26
src/vehicles/Train.h
Normal file
26
src/vehicles/Train.h
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Vehicle.h"
|
||||
|
||||
enum
|
||||
{
|
||||
TRAIN_DOOR_STATE2 = 2
|
||||
};
|
||||
|
||||
class CTrain : public CVehicle
|
||||
{
|
||||
public:
|
||||
// 0x288
|
||||
uint8 stuff1[20];
|
||||
uint8 m_trackId;
|
||||
uint8 stuff2[7];
|
||||
int16 m_doorState;
|
||||
uint8 stuff3[62];
|
||||
|
||||
CTrain(int, uint8);
|
||||
CTrain* ctor(int, uint8);
|
||||
void dtor(void) { this->CTrain::~CTrain(); }
|
||||
};
|
||||
static_assert(sizeof(CTrain) == 0x2E4, "CTrain: error");
|
37
src/vehicles/Transmission.cpp
Normal file
37
src/vehicles/Transmission.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Transmission.h"
|
||||
|
||||
void
|
||||
cTransmission::InitGearRatios(void)
|
||||
{
|
||||
static tGear *pGearRatio0 = nil;
|
||||
static tGear *pGearRatio1 = nil;
|
||||
int i;
|
||||
float velocityDiff;
|
||||
|
||||
memset(Gears, 0, sizeof(Gears));
|
||||
|
||||
for(i = 1; i <= nNumberOfGears; i++){
|
||||
pGearRatio0 = &Gears[i-1];
|
||||
pGearRatio1 = &Gears[i];
|
||||
|
||||
pGearRatio1->fMaxVelocity = (float)i / nNumberOfGears * fMaxVelocity;
|
||||
|
||||
velocityDiff = pGearRatio1->fMaxVelocity - pGearRatio0->fMaxVelocity;
|
||||
|
||||
if(i >= nNumberOfGears){
|
||||
pGearRatio1->fShiftUpVelocity = fMaxVelocity;
|
||||
}else{
|
||||
Gears[i+1].fShiftDownVelocity = velocityDiff*0.42f + pGearRatio0->fMaxVelocity;
|
||||
pGearRatio1->fShiftUpVelocity = velocityDiff*0.6667f + pGearRatio0->fMaxVelocity;
|
||||
}
|
||||
}
|
||||
|
||||
// Reverse gear
|
||||
Gears[0].fMaxVelocity = fMaxReverseVelocity;
|
||||
Gears[0].fShiftUpVelocity = -0.01f;
|
||||
Gears[0].fShiftDownVelocity = fMaxReverseVelocity;
|
||||
|
||||
Gears[1].fShiftDownVelocity = -0.01f;
|
||||
}
|
26
src/vehicles/Transmission.h
Normal file
26
src/vehicles/Transmission.h
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
struct tGear
|
||||
{
|
||||
float fMaxVelocity;
|
||||
float fShiftUpVelocity;
|
||||
float fShiftDownVelocity;
|
||||
};
|
||||
|
||||
class cTransmission
|
||||
{
|
||||
public:
|
||||
// Gear 0 is reverse, 1-5 are forward
|
||||
tGear Gears[6];
|
||||
char nDriveType;
|
||||
char nEngineType;
|
||||
int8 nNumberOfGears;
|
||||
uint8 Flags;
|
||||
float fEngineAcceleration;
|
||||
float fMaxVelocity;
|
||||
float fUnkMaxVelocity;
|
||||
float fMaxReverseVelocity;
|
||||
float field_5C;
|
||||
|
||||
void InitGearRatios(void);
|
||||
};
|
489
src/vehicles/Vehicle.cpp
Normal file
489
src/vehicles/Vehicle.cpp
Normal file
@ -0,0 +1,489 @@
|
||||
#include "common.h"
|
||||
#include "main.h"
|
||||
#include "patcher.h"
|
||||
#include "Timer.h"
|
||||
#include "Vehicle.h"
|
||||
#include "Pools.h"
|
||||
#include "HandlingMgr.h"
|
||||
#include "CarCtrl.h"
|
||||
#include "Population.h"
|
||||
#include "ModelIndices.h"
|
||||
#include "World.h"
|
||||
#include "Lights.h"
|
||||
#include "PointLights.h"
|
||||
#include "Renderer.h"
|
||||
#include "DMAudio.h"
|
||||
#include "Radar.h"
|
||||
|
||||
bool &CVehicle::bWheelsOnlyCheat = *(bool *)0x95CD78;
|
||||
bool &CVehicle::bAllDodosCheat = *(bool *)0x95CD75;
|
||||
bool &CVehicle::bCheat3 = *(bool *)0x95CD66;
|
||||
bool &CVehicle::bCheat4 = *(bool *)0x95CD65;
|
||||
bool &CVehicle::bCheat5 = *(bool *)0x95CD64;
|
||||
bool &CVehicle::m_bDisableMouseSteering = *(bool *)0x60252C;
|
||||
|
||||
void *CVehicle::operator new(size_t sz) { return CPools::GetVehiclePool()->New(); }
|
||||
void *CVehicle::operator new(size_t sz, int handle) { return CPools::GetVehiclePool()->New(handle); }
|
||||
void CVehicle::operator delete(void *p, size_t sz) { CPools::GetVehiclePool()->Delete((CVehicle*)p); }
|
||||
void CVehicle::operator delete(void *p, int handle) { CPools::GetVehiclePool()->Delete((CVehicle*)p); }
|
||||
|
||||
CVehicle::~CVehicle()
|
||||
{
|
||||
m_nAlarmState = 0;
|
||||
if (m_audioEntityId >= 0){
|
||||
DMAudio.DestroyEntity(m_audioEntityId);
|
||||
m_audioEntityId = -5;
|
||||
}
|
||||
CRadar::ClearBlipForEntity(BLIP_CAR, CPools::GetVehiclePool()->GetIndex(this));
|
||||
if (pDriver)
|
||||
pDriver->FlagToDestroyWhenNextProcessed();
|
||||
for (int i = 0; i < m_nNumMaxPassengers; i++){
|
||||
if (pPassengers[i])
|
||||
pPassengers[i]->FlagToDestroyWhenNextProcessed();
|
||||
}
|
||||
if (m_pCarFire)
|
||||
m_pCarFire->Extinguish();
|
||||
CCarCtrl::UpdateCarCount(this, true);
|
||||
if (bIsAmbulanceOnDuty){
|
||||
CCarCtrl::NumAmbulancesOnDuty--;
|
||||
bIsAmbulanceOnDuty = false;
|
||||
}
|
||||
if (bIsFireTruckOnDuty){
|
||||
CCarCtrl::NumFiretrucksOnDuty--;
|
||||
bIsFireTruckOnDuty = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CVehicle::SetModelIndex(uint32 id)
|
||||
{
|
||||
CEntity::SetModelIndex(id);
|
||||
m_aExtras[0] = CVehicleModelInfo::ms_compsUsed[0];
|
||||
m_aExtras[1] = CVehicleModelInfo::ms_compsUsed[1];
|
||||
m_nNumMaxPassengers = CVehicleModelInfo::GetMaximumNumberOfPassengersFromNumberOfDoors(id);
|
||||
}
|
||||
|
||||
bool
|
||||
CVehicle::SetupLighting(void)
|
||||
{
|
||||
ActivateDirectional();
|
||||
SetAmbientColoursForPedsCarsAndObjects();
|
||||
|
||||
if(bRenderScorched){
|
||||
WorldReplaceNormalLightsWithScorched(Scene.world, 0.1f);
|
||||
}else{
|
||||
CVector coors = GetPosition();
|
||||
float lighting = CPointLights::GenerateLightsAffectingObject(&coors);
|
||||
if(!bHasBlip && lighting != 1.0f){
|
||||
SetAmbientAndDirectionalColours(lighting);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
CVehicle::RemoveLighting(bool reset)
|
||||
{
|
||||
CRenderer::RemoveVehiclePedLights(this, reset);
|
||||
}
|
||||
|
||||
float
|
||||
CVehicle::GetHeightAboveRoad(void)
|
||||
{
|
||||
return -1.0f * CModelInfo::GetModelInfo(GetModelIndex())->GetColModel()->boundingBox.min.z;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CVehicle::IsLawEnforcementVehicle(void)
|
||||
{
|
||||
switch(GetModelIndex()){
|
||||
case MI_FBICAR:
|
||||
case MI_POLICE:
|
||||
case MI_ENFORCER:
|
||||
case MI_PREDATOR:
|
||||
case MI_RHINO:
|
||||
case MI_BARRACKS:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CVehicle::UsesSiren(uint32 id)
|
||||
{
|
||||
switch(id){
|
||||
case MI_FIRETRUCK:
|
||||
case MI_AMBULAN:
|
||||
case MI_FBICAR:
|
||||
case MI_MRWHOOP:
|
||||
case MI_POLICE:
|
||||
case MI_ENFORCER:
|
||||
case MI_PREDATOR:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CVehicle::IsVehicleNormal(void)
|
||||
{
|
||||
if(pDriver && m_nNumPassengers == 0 && m_status != STATUS_WRECKED){
|
||||
switch(GetModelIndex())
|
||||
case MI_FIRETRUCK:
|
||||
case MI_AMBULAN:
|
||||
case MI_TAXI:
|
||||
case MI_POLICE:
|
||||
case MI_ENFORCER:
|
||||
case MI_BUS:
|
||||
case MI_RHINO:
|
||||
case MI_BARRACKS:
|
||||
case MI_DODO:
|
||||
case MI_COACH:
|
||||
case MI_CABBIE:
|
||||
case MI_RCBANDIT:
|
||||
case MI_BORGNINE:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CVehicle::CarHasRoof(void)
|
||||
{
|
||||
if((m_handling->Flags & HANDLING_HAS_NO_ROOF) == 0)
|
||||
return true;
|
||||
if(m_aExtras[0] && m_aExtras[1])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CVehicle::IsUpsideDown(void)
|
||||
{
|
||||
if(GetUp().z > -0.9f)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CVehicle::IsOnItsSide(void)
|
||||
{
|
||||
if(GetRight().z < 0.8f && GetRight().z > -0.8f)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CVehicle::CanBeDeleted(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(m_nNumGettingIn || m_nGettingOutFlags)
|
||||
return false;
|
||||
|
||||
if(pDriver){
|
||||
// This looks like it was inlined
|
||||
if(pDriver->CharCreatedBy == MISSION_CHAR)
|
||||
return false;
|
||||
if(pDriver->GetPedState() != PED_DRIVING &&
|
||||
pDriver->GetPedState() != PED_DEAD)
|
||||
return false;
|
||||
}
|
||||
|
||||
for(i = 0; i < 8; i++){
|
||||
// Same check as above
|
||||
if(pPassengers[i]){
|
||||
if(pPassengers[i]->CharCreatedBy == MISSION_CHAR)
|
||||
return false;
|
||||
if(pPassengers[i]->GetPedState() != PED_DRIVING &&
|
||||
pPassengers[i]->GetPedState() != PED_DEAD)
|
||||
return false;
|
||||
}
|
||||
// and then again... probably because something was inlined
|
||||
if(pPassengers[i]){
|
||||
if(pPassengers[i]->GetPedState() != PED_DRIVING &&
|
||||
pPassengers[i]->GetPedState() != PED_DEAD)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
switch(VehicleCreatedBy){
|
||||
case RANDOM_VEHICLE: return true;
|
||||
case MISSION_VEHICLE: return false;
|
||||
case PARKED_VEHICLE: return true;
|
||||
case PERMANENT_VEHICLE: return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CVehicle::CanPedOpenLocks(CPed *ped)
|
||||
{
|
||||
if(m_nDoorLock == CARLOCK_LOCKED ||
|
||||
m_nDoorLock == CARLOCK_COP_CAR ||
|
||||
m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE)
|
||||
return false;
|
||||
if(ped->IsPlayer() && m_nDoorLock == CARLOCK_LOCKOUT_PLAYER_ONLY)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CVehicle::CanPedEnterCar(void)
|
||||
{
|
||||
CVector up = GetUp();
|
||||
// can't enter when car is on side
|
||||
if(up.z > 0.1f || up.z < -0.1f){
|
||||
// also when car is moving too fast
|
||||
if(m_vecMoveSpeed.MagnitudeSqr() > sq(0.2f))
|
||||
return false;
|
||||
if(m_vecTurnSpeed.MagnitudeSqr() > sq(0.2f))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CVehicle::CanPedExitCar(void)
|
||||
{
|
||||
CVector up = GetUp();
|
||||
if(up.z > 0.1f || up.z < -0.1f){
|
||||
// can't exit when car is moving too fast
|
||||
if(m_vecMoveSpeed.MagnitudeSqr() > 0.005f)
|
||||
return false;
|
||||
// if car is slow enough, check turn speed
|
||||
if(fabs(m_vecTurnSpeed.x) > 0.01f ||
|
||||
fabs(m_vecTurnSpeed.y) > 0.01f ||
|
||||
fabs(m_vecTurnSpeed.z) > 0.01f)
|
||||
return false;
|
||||
return true;
|
||||
}else{
|
||||
// What is this? just > replaced by >= ??
|
||||
|
||||
// can't exit when car is moving too fast
|
||||
if(m_vecMoveSpeed.MagnitudeSqr() >= 0.005f)
|
||||
return false;
|
||||
// if car is slow enough, check turn speed
|
||||
if(fabs(m_vecTurnSpeed.x) >= 0.01f ||
|
||||
fabs(m_vecTurnSpeed.y) >= 0.01f ||
|
||||
fabs(m_vecTurnSpeed.z) >= 0.01f)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CVehicle::ChangeLawEnforcerState(uint8 enable)
|
||||
{
|
||||
if (enable) {
|
||||
if (!bIsLawEnforcer) {
|
||||
bIsLawEnforcer = true;
|
||||
CCarCtrl::NumLawEnforcerCars++;
|
||||
}
|
||||
} else {
|
||||
if (bIsLawEnforcer) {
|
||||
bIsLawEnforcer = false;
|
||||
CCarCtrl::NumLawEnforcerCars--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CPed*
|
||||
CVehicle::SetUpDriver(void)
|
||||
{
|
||||
if(pDriver)
|
||||
return pDriver;
|
||||
if(VehicleCreatedBy != RANDOM_VEHICLE)
|
||||
return nil;
|
||||
|
||||
pDriver = CPopulation::AddPedInCar(this);
|
||||
pDriver->m_pMyVehicle = this;
|
||||
pDriver->m_pMyVehicle->RegisterReference((CEntity**)&pDriver->m_pMyVehicle);
|
||||
pDriver->bInVehicle = true;
|
||||
pDriver->SetPedState(PED_DRIVING);
|
||||
if(bIsBus)
|
||||
pDriver->m_ped_flagC4 = false;
|
||||
return pDriver;
|
||||
}
|
||||
|
||||
CPed*
|
||||
CVehicle::SetupPassenger(int n)
|
||||
{
|
||||
if(pPassengers[n])
|
||||
return pPassengers[n];
|
||||
|
||||
pPassengers[n] = CPopulation::AddPedInCar(this);
|
||||
pPassengers[n]->m_pMyVehicle = this;
|
||||
pPassengers[n]->m_pMyVehicle->RegisterReference((CEntity**)&pPassengers[n]->m_pMyVehicle);
|
||||
pPassengers[n]->bInVehicle = true;
|
||||
pPassengers[n]->SetPedState(PED_DRIVING);
|
||||
if(bIsBus)
|
||||
pPassengers[n]->m_ped_flagC4 = false;
|
||||
return pPassengers[n];
|
||||
}
|
||||
|
||||
void
|
||||
CVehicle::SetDriver(CPed *driver)
|
||||
{
|
||||
pDriver = driver;
|
||||
pDriver->RegisterReference((CEntity**)&pDriver);
|
||||
|
||||
if(bFreebies && driver == FindPlayerPed()){
|
||||
if(GetModelIndex() == MI_AMBULAN)
|
||||
FindPlayerPed()->m_fHealth = min(FindPlayerPed()->m_fHealth + 20.0f, 100.0f);
|
||||
else if(GetModelIndex() == MI_TAXI)
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 25;
|
||||
else if(GetModelIndex() == MI_POLICE)
|
||||
driver->GiveWeapon(WEAPONTYPE_SHOTGUN, 5);
|
||||
else if(GetModelIndex() == MI_ENFORCER)
|
||||
driver->m_fArmour = max(driver->m_fArmour, 100.0f);
|
||||
else if(GetModelIndex() == MI_CABBIE || GetModelIndex() == MI_BORGNINE)
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 25;
|
||||
bFreebies = false;
|
||||
}
|
||||
|
||||
ApplyTurnForce(0.0f, 0.0f, -0.2f*driver->m_fMass,
|
||||
driver->GetPosition().x - GetPosition().x,
|
||||
driver->GetPosition().y - GetPosition().y,
|
||||
0.0f);
|
||||
}
|
||||
|
||||
bool
|
||||
CVehicle::AddPassenger(CPed *passenger)
|
||||
{
|
||||
int i;
|
||||
|
||||
ApplyTurnForce(0.0f, 0.0f, -0.2f*passenger->m_fMass,
|
||||
passenger->GetPosition().x - GetPosition().x,
|
||||
passenger->GetPosition().y - GetPosition().y,
|
||||
0.0f);
|
||||
|
||||
for(i = 0; i < m_nNumMaxPassengers; i++)
|
||||
if(pPassengers[i] == nil){
|
||||
pPassengers[i] = passenger;
|
||||
m_nNumPassengers++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CVehicle::AddPassenger(CPed *passenger, uint8 n)
|
||||
{
|
||||
if(bIsBus)
|
||||
return AddPassenger(passenger);
|
||||
|
||||
ApplyTurnForce(0.0f, 0.0f, -0.2f*passenger->m_fMass,
|
||||
passenger->GetPosition().x - GetPosition().x,
|
||||
passenger->GetPosition().y - GetPosition().y,
|
||||
0.0f);
|
||||
|
||||
if(n < m_nNumMaxPassengers && pPassengers[n] == nil){
|
||||
pPassengers[n] = passenger;
|
||||
m_nNumPassengers++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
CVehicle::RemoveDriver(void)
|
||||
{
|
||||
m_status = STATUS_ABANDONED;
|
||||
pDriver = nil;
|
||||
}
|
||||
|
||||
void
|
||||
CVehicle::RemovePassenger(CPed *p)
|
||||
{
|
||||
if (IsTrain()){
|
||||
for (int i = 0; i < 8; i++){
|
||||
if (pPassengers[i] == p) {
|
||||
pPassengers[i] = nil;
|
||||
m_nNumPassengers--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < m_nNumMaxPassengers; i++){
|
||||
if (pPassengers[i] == p){
|
||||
pPassengers[i] = nil;
|
||||
m_nNumPassengers--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CVehicle::ProcessCarAlarm(void)
|
||||
{
|
||||
uint32 step;
|
||||
|
||||
if(m_nAlarmState == 0 || m_nAlarmState == -1)
|
||||
return;
|
||||
|
||||
step = CTimer::GetTimeStepInMilliseconds();
|
||||
if((uint16)m_nAlarmState < step)
|
||||
m_nAlarmState = 0;
|
||||
else
|
||||
m_nAlarmState -= step;
|
||||
}
|
||||
|
||||
bool
|
||||
CVehicle::IsSphereTouchingVehicle(float sx, float sy, float sz, float radius)
|
||||
{
|
||||
float x, y, z;
|
||||
// sphere relative to vehicle
|
||||
CVector sph = CVector(sx, sy, sz) - GetPosition();
|
||||
CColModel *colmodel = CModelInfo::GetModelInfo(GetModelIndex())->GetColModel();
|
||||
|
||||
x = DotProduct(sph, GetRight());
|
||||
if(colmodel->boundingBox.min.x - radius > x ||
|
||||
colmodel->boundingBox.max.x + radius < x)
|
||||
return false;
|
||||
y = DotProduct(sph, GetForward());
|
||||
if(colmodel->boundingBox.min.y - radius > y ||
|
||||
colmodel->boundingBox.max.y + radius < y)
|
||||
return false;
|
||||
z = DotProduct(sph, GetUp());
|
||||
if(colmodel->boundingBox.min.z - radius > z ||
|
||||
colmodel->boundingBox.max.z + radius < z)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x551170, &CVehicle::SetModelIndex_, PATCH_JUMP);
|
||||
InjectHook(0x4A7DD0, &CVehicle::SetupLighting_, PATCH_JUMP);
|
||||
InjectHook(0x4A7E60, &CVehicle::RemoveLighting_, PATCH_JUMP);
|
||||
InjectHook(0x417E60, &CVehicle::GetHeightAboveRoad_, PATCH_JUMP);
|
||||
|
||||
InjectHook(0x552880, &CVehicle::IsLawEnforcementVehicle, PATCH_JUMP);
|
||||
InjectHook(0x552820, &CVehicle::ChangeLawEnforcerState, PATCH_JUMP);
|
||||
InjectHook(0x552200, &CVehicle::UsesSiren, PATCH_JUMP);
|
||||
InjectHook(0x5527E0, &CVehicle::IsVehicleNormal, PATCH_JUMP);
|
||||
InjectHook(0x552B70, &CVehicle::CarHasRoof, PATCH_JUMP);
|
||||
InjectHook(0x552230, &CVehicle::IsUpsideDown, PATCH_JUMP);
|
||||
InjectHook(0x552260, &CVehicle::IsOnItsSide, PATCH_JUMP);
|
||||
InjectHook(0x5511B0, &CVehicle::CanBeDeleted, PATCH_JUMP);
|
||||
InjectHook(0x5522A0, &CVehicle::CanPedOpenLocks, PATCH_JUMP);
|
||||
InjectHook(0x5522F0, &CVehicle::CanPedEnterCar, PATCH_JUMP);
|
||||
InjectHook(0x5523C0, &CVehicle::CanPedExitCar, PATCH_JUMP);
|
||||
InjectHook(0x5520C0, &CVehicle::SetUpDriver, PATCH_JUMP);
|
||||
InjectHook(0x552160, &CVehicle::SetupPassenger, PATCH_JUMP);
|
||||
InjectHook(0x551F20, &CVehicle::SetDriver, PATCH_JUMP);
|
||||
InjectHook(0x551D90, (bool (CVehicle::*)(CPed*))&CVehicle::AddPassenger, PATCH_JUMP);
|
||||
InjectHook(0x551E10, (bool (CVehicle::*)(CPed*,uint8))&CVehicle::AddPassenger, PATCH_JUMP);
|
||||
InjectHook(0x5520A0, &CVehicle::RemoveDriver, PATCH_JUMP);
|
||||
InjectHook(0x551EB0, &CVehicle::RemovePassenger, PATCH_JUMP);
|
||||
InjectHook(0x5525A0, &CVehicle::ProcessCarAlarm, PATCH_JUMP);
|
||||
InjectHook(0x552620, &CVehicle::IsSphereTouchingVehicle, PATCH_JUMP);
|
||||
ENDPATCHES
|
240
src/vehicles/Vehicle.h
Normal file
240
src/vehicles/Vehicle.h
Normal file
@ -0,0 +1,240 @@
|
||||
#pragma once
|
||||
|
||||
#include "Physical.h"
|
||||
#include "AutoPilot.h"
|
||||
|
||||
class CPed;
|
||||
class CFire;
|
||||
struct tHandlingData;
|
||||
|
||||
enum {
|
||||
RANDOM_VEHICLE = 1,
|
||||
MISSION_VEHICLE = 2,
|
||||
PARKED_VEHICLE = 3,
|
||||
PERMANENT_VEHICLE = 4,
|
||||
};
|
||||
|
||||
enum eCarLock {
|
||||
CARLOCK_NOT_USED,
|
||||
CARLOCK_UNLOCKED,
|
||||
CARLOCK_LOCKED,
|
||||
CARLOCK_LOCKOUT_PLAYER_ONLY,
|
||||
CARLOCK_LOCKED_PLAYER_INSIDE,
|
||||
CARLOCK_COP_CAR,
|
||||
CARLOCK_FORCE_SHUT_DOORS,
|
||||
CARLOCK_SKIP_SHUT_DOORS
|
||||
};
|
||||
|
||||
|
||||
enum eCarNodes
|
||||
{
|
||||
CAR_WHEEL_RF = 1,
|
||||
CAR_WHEEL_RM,
|
||||
CAR_WHEEL_RB,
|
||||
CAR_WHEEL_LF,
|
||||
CAR_WHEEL_LM,
|
||||
CAR_WHEEL_LB,
|
||||
CAR_BUMP_FRONT,
|
||||
CAR_BUMP_REAR,
|
||||
CAR_WING_RF,
|
||||
CAR_WING_RR,
|
||||
CAR_DOOR_RF,
|
||||
CAR_DOOR_RR,
|
||||
CAR_WING_LF,
|
||||
CAR_WING_LR,
|
||||
CAR_DOOR_LF,
|
||||
CAR_DOOR_LR,
|
||||
CAR_BONNET,
|
||||
CAR_BOOT,
|
||||
CAR_WINDSCREEN,
|
||||
NUM_CAR_NODES,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CAR_POS_HEADLIGHTS,
|
||||
CAR_POS_TAILLIGHTS,
|
||||
CAR_POS_FRONTSEAT,
|
||||
CAR_POS_BACKSEAT,
|
||||
CAR_POS_EXHAUST = 9,
|
||||
};
|
||||
|
||||
enum eDoors
|
||||
{
|
||||
DOOR_BONNET = 0,
|
||||
DOOR_BOOT,
|
||||
DOOR_FRONT_LEFT,
|
||||
DOOR_FRONT_RIGHT,
|
||||
DOOR_REAR_LEFT,
|
||||
DOOR_REAR_RIGHT
|
||||
};
|
||||
|
||||
class CVehicle : public CPhysical
|
||||
{
|
||||
public:
|
||||
// 0x128
|
||||
tHandlingData *m_handling;
|
||||
CAutoPilot m_autoPilot;
|
||||
uint8 m_currentColour1;
|
||||
uint8 m_currentColour2;
|
||||
uint8 m_aExtras[2];
|
||||
int16 m_nAlarmState; // m_nWantedStarsOnEnter on DK22
|
||||
int16 m_nMissionValue;
|
||||
CPed *pDriver;
|
||||
CPed *pPassengers[8];
|
||||
uint8 m_nNumPassengers;
|
||||
int8 m_nNumGettingIn;
|
||||
int8 m_nGettingInFlags;
|
||||
int8 m_nGettingOutFlags;
|
||||
uint8 m_nNumMaxPassengers;
|
||||
char field_1CD[19];
|
||||
CEntity *m_pCurSurface;
|
||||
CFire *m_pCarFire;
|
||||
float m_fSteerAngle;
|
||||
float m_fGasPedal;
|
||||
float m_fBreakPedal;
|
||||
uint8 VehicleCreatedBy;
|
||||
|
||||
// cf. https://github.com/DK22Pac/plugin-sdk/blob/master/plugin_sa/game_sa/CVehicle.h from R*
|
||||
uint8 bIsLawEnforcer: 1; // Is this guy chasing the player at the moment
|
||||
uint8 bIsAmbulanceOnDuty: 1; // Ambulance trying to get to an accident
|
||||
uint8 bIsFireTruckOnDuty: 1; // Firetruck trying to get to a fire
|
||||
uint8 bIsLocked: 1; // Is this guy locked by the script (cannot be removed)
|
||||
uint8 bEngineOn: 1; // For sound purposes. Parked cars have their engines switched off (so do destroyed cars)
|
||||
uint8 bIsHandbrakeOn: 1; // How's the handbrake doing ?
|
||||
uint8 bLightsOn: 1; // Are the lights switched on ?
|
||||
uint8 bFreebies: 1; // Any freebies left in this vehicle ?
|
||||
|
||||
uint8 bIsVan: 1; // Is this vehicle a van (doors at back of vehicle)
|
||||
uint8 bIsBus: 1; // Is this vehicle a bus
|
||||
uint8 bIsBig: 1; // Is this vehicle a bus
|
||||
uint8 bLowVehicle: 1; // Need this for sporty type cars to use low getting-in/out anims
|
||||
uint8 m_veh_flagB10 : 1;
|
||||
uint8 m_veh_flagB20 : 1;
|
||||
uint8 m_veh_flagB40 : 1;
|
||||
uint8 m_veh_flagB80 : 1;
|
||||
|
||||
uint8 m_veh_flagC1 : 1;
|
||||
uint8 m_veh_flagC2 : 1;
|
||||
uint8 m_veh_flagC4 : 1;
|
||||
uint8 m_veh_flagC8 : 1;
|
||||
uint8 m_veh_flagC10 : 1;
|
||||
uint8 m_veh_flagC20 : 1;
|
||||
uint8 m_veh_flagC40 : 1;
|
||||
uint8 m_veh_flagC80 : 1;
|
||||
|
||||
uint8 m_veh_flagD1 : 1;
|
||||
uint8 m_veh_flagD2 : 1;
|
||||
uint8 m_veh_flagD4 : 1;
|
||||
uint8 m_veh_flagD8 : 1;
|
||||
uint8 bRecordedForReplay : 1;
|
||||
uint8 m_veh_flagD20 : 1;
|
||||
uint8 m_veh_flagD40 : 1;
|
||||
uint8 m_veh_flagD80 : 1;
|
||||
|
||||
int8 field_1F9;
|
||||
uint8 m_nAmmoInClip; // Used to make the guns on boat do a reload (20 by default)
|
||||
int8 field_1FB;
|
||||
int8 field_1FC[4];
|
||||
float m_fHealth; // 1000.0f = full health. 0 -> explode
|
||||
uint8 m_nCurrentGear;
|
||||
int8 field_205[3];
|
||||
int field_208;
|
||||
uint32 m_nGunFiringTime; // last time when gun on vehicle was fired (used on boats)
|
||||
uint32 m_nTimeOfDeath;
|
||||
int16 field_214;
|
||||
int16 m_nBombTimer; // goes down with each frame
|
||||
CPed *m_pWhoDetonatedMe;
|
||||
float field_21C;
|
||||
float field_220;
|
||||
eCarLock m_nDoorLock;
|
||||
int8 m_nLastWeaponDamage; // see eWeaponType, -1 if no damage
|
||||
int8 m_nRadioStation;
|
||||
int8 field_22A;
|
||||
int8 field_22B;
|
||||
uint8 m_nCarHornTimer;
|
||||
int8 field_22D;
|
||||
uint8 m_nSirenOrAlarm;
|
||||
int8 field_22F;
|
||||
// TODO: this is an array
|
||||
CStoredCollPoly m_frontCollPoly; // poly which is under front part of car
|
||||
CStoredCollPoly m_rearCollPoly; // poly which is under rear part of car
|
||||
float m_fSteerRatio;
|
||||
eVehicleType m_vehType;
|
||||
|
||||
static void *operator new(size_t);
|
||||
static void *operator new(size_t sz, int slot);
|
||||
static void operator delete(void*, size_t);
|
||||
static void operator delete(void*, int);
|
||||
|
||||
~CVehicle(void);
|
||||
// from CEntity
|
||||
void SetModelIndex(uint32 i);
|
||||
bool SetupLighting(void);
|
||||
void RemoveLighting(bool);
|
||||
void FlagToDestroyWhenNextProcessed(void) {}
|
||||
|
||||
virtual void ProcessControlInputs(uint8) {}
|
||||
virtual void GetComponentWorldPosition(int32 component, CVector &pos) {}
|
||||
virtual bool IsComponentPresent(int32 component) { return false; }
|
||||
virtual void SetComponentRotation(int32 component, CVector rotation) {}
|
||||
virtual void OpenDoor(int32, eDoors door, float) {}
|
||||
virtual void ProcessOpenDoor(uint32, uint32, float) {}
|
||||
virtual bool IsDoorReady(eDoors door) { return false; }
|
||||
virtual bool IsDoorFullyOpen(eDoors door) { return false; }
|
||||
virtual bool IsDoorClosed(eDoors door) { return false; }
|
||||
virtual bool IsDoorMissing(eDoors door) { return false; }
|
||||
virtual void RemoveRefsToVehicle(CEntity *ent) {}
|
||||
virtual void BlowUpCar(CEntity *ent) {}
|
||||
virtual bool SetUpWheelColModel(CColModel *colModel) { return false; }
|
||||
virtual void BurstTyre(uint8 tyre) {}
|
||||
virtual bool IsRoomForPedToLeaveCar(uint32, CVector *) { return false;}
|
||||
virtual float GetHeightAboveRoad(void);
|
||||
virtual void PlayCarHorn(void) {}
|
||||
|
||||
bool IsCar(void) { return m_vehType == VEHICLE_TYPE_CAR; }
|
||||
bool IsBoat(void) { return m_vehType == VEHICLE_TYPE_BOAT; }
|
||||
bool IsTrain(void) { return m_vehType == VEHICLE_TYPE_TRAIN; }
|
||||
bool IsHeli(void) { return m_vehType == VEHICLE_TYPE_HELI; }
|
||||
bool IsPlane(void) { return m_vehType == VEHICLE_TYPE_PLANE; }
|
||||
bool IsLawEnforcementVehicle(void);
|
||||
void ChangeLawEnforcerState(uint8 enable);
|
||||
bool UsesSiren(uint32 id);
|
||||
bool IsVehicleNormal(void);
|
||||
bool CarHasRoof(void);
|
||||
bool IsUpsideDown(void);
|
||||
bool IsOnItsSide(void);
|
||||
bool CanBeDeleted(void);
|
||||
bool CanPedOpenLocks(CPed *ped);
|
||||
bool CanPedEnterCar(void);
|
||||
bool CanPedExitCar(void);
|
||||
// do these two actually return something?
|
||||
CPed *SetUpDriver(void);
|
||||
CPed *SetupPassenger(int n);
|
||||
void SetDriver(CPed *driver);
|
||||
bool AddPassenger(CPed *passenger);
|
||||
bool AddPassenger(CPed *passenger, uint8 n);
|
||||
void RemovePassenger(CPed *passenger);
|
||||
void RemoveDriver(void);
|
||||
void ProcessCarAlarm(void);
|
||||
bool IsSphereTouchingVehicle(float sx, float sy, float sz, float radius);
|
||||
|
||||
static bool &bWheelsOnlyCheat;
|
||||
static bool &bAllDodosCheat;
|
||||
static bool &bCheat3;
|
||||
static bool &bCheat4;
|
||||
static bool &bCheat5;
|
||||
static bool &m_bDisableMouseSteering;
|
||||
|
||||
|
||||
void dtor(void) { CVehicle::~CVehicle(); }
|
||||
void SetModelIndex_(uint32 id) { CVehicle::SetModelIndex(id); }
|
||||
bool SetupLighting_(void) { return CVehicle::SetupLighting(); }
|
||||
void RemoveLighting_(bool reset) { CVehicle::RemoveLighting(reset); }
|
||||
float GetHeightAboveRoad_(void) { return CVehicle::GetHeightAboveRoad(); }
|
||||
};
|
||||
|
||||
static_assert(sizeof(CVehicle) == 0x288, "CVehicle: error");
|
||||
static_assert(offsetof(CVehicle, m_pCurSurface) == 0x1E0, "CVehicle: error");
|
||||
static_assert(offsetof(CVehicle, m_nAlarmState) == 0x1A0, "CVehicle: error");
|
||||
static_assert(offsetof(CVehicle, m_nLastWeaponDamage) == 0x228, "CVehicle: error");
|
Reference in New Issue
Block a user