mirror of
https://github.com/GTAmodding/re3.git
synced 2024-11-29 07:33:42 +00:00
reversed CPhysical::ProcessShiftSectorList
This commit is contained in:
parent
e9e72523d5
commit
5b8f20b08e
10 changed files with 235 additions and 7 deletions
|
@ -22,6 +22,7 @@ struct CColBox
|
||||||
uint8 piece;
|
uint8 piece;
|
||||||
|
|
||||||
void Set(const CVector &min, const CVector &max, uint8 surf, uint8 piece);
|
void Set(const CVector &min, const CVector &max, uint8 surf, uint8 piece);
|
||||||
|
CVector GetSize(void) { return max - min; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CColLine
|
struct CColLine
|
||||||
|
|
|
@ -9,6 +9,11 @@ CSector (*CWorld::ms_aSectors)[NUMSECTORS_X] = (CSector (*)[NUMSECTORS_Y])0x6656
|
||||||
uint16 &CWorld::ms_nCurrentScanCode = *(uint16*)0x95CC64;
|
uint16 &CWorld::ms_nCurrentScanCode = *(uint16*)0x95CC64;
|
||||||
|
|
||||||
bool &CWorld::bNoMoreCollisionTorque = *(bool*)0x95CDCC;
|
bool &CWorld::bNoMoreCollisionTorque = *(bool*)0x95CDCC;
|
||||||
|
CEntity *&CWorld::pIgnoreEntity = *(CEntity**)0x8F6494;
|
||||||
|
bool &CWorld::bSecondShift = *(bool*)0x95CD54;
|
||||||
|
bool &CWorld::bForceProcessControl = *(bool*)0x95CD6C;
|
||||||
|
bool &CWorld::bProcessCutsceneOnly = *(bool*)0x95CD8B;
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CWorld::ClearScanCodes(void)
|
CWorld::ClearScanCodes(void)
|
||||||
|
|
|
@ -32,6 +32,8 @@ public:
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CSector) == 0x28, "CSector: error");
|
static_assert(sizeof(CSector) == 0x28, "CSector: error");
|
||||||
|
|
||||||
|
class CEntity;
|
||||||
|
|
||||||
class CWorld
|
class CWorld
|
||||||
{
|
{
|
||||||
static CPtrList *ms_bigBuildingsList; // [4];
|
static CPtrList *ms_bigBuildingsList; // [4];
|
||||||
|
@ -40,7 +42,12 @@ class CWorld
|
||||||
static uint16 &ms_nCurrentScanCode;
|
static uint16 &ms_nCurrentScanCode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static CEntity *&pIgnoreEntity;
|
||||||
static bool &bNoMoreCollisionTorque;
|
static bool &bNoMoreCollisionTorque;
|
||||||
|
static bool &bSecondShift;
|
||||||
|
static bool &bForceProcessControl;
|
||||||
|
static bool &bProcessCutsceneOnly;
|
||||||
|
|
||||||
|
|
||||||
static CSector *GetSector(int x, int y) { return &ms_aSectors[y][x]; }
|
static CSector *GetSector(int x, int y) { return &ms_aSectors[y][x]; }
|
||||||
static CPtrList &GetBigBuildingList(eLevelName i) { return ms_bigBuildingsList[i]; }
|
static CPtrList &GetBigBuildingList(eLevelName i) { return ms_bigBuildingsList[i]; }
|
||||||
|
|
|
@ -8,6 +8,8 @@ enum {
|
||||||
TEMP_OBJECT = 3,
|
TEMP_OBJECT = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CVehicle;
|
||||||
|
|
||||||
class CObject : public CPhysical
|
class CObject : public CPhysical
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -39,7 +41,7 @@ public:
|
||||||
int8 field_186;
|
int8 field_186;
|
||||||
int8 field_187;
|
int8 field_187;
|
||||||
CEntity *m_pCurSurface;
|
CEntity *m_pCurSurface;
|
||||||
CEntity *field_18C;
|
CVehicle *m_pCollidingVehicle;
|
||||||
int8 m_colour1, m_colour2;
|
int8 m_colour1, m_colour2;
|
||||||
|
|
||||||
static void *operator new(size_t);
|
static void *operator new(size_t);
|
||||||
|
|
|
@ -24,7 +24,10 @@ public:
|
||||||
bool bInVehicle;
|
bool bInVehicle;
|
||||||
uint8 stuff4[23];
|
uint8 stuff4[23];
|
||||||
int32 m_nPedType;
|
int32 m_nPedType;
|
||||||
uint8 stuff5[528];
|
|
||||||
|
uint8 stuff5[28];
|
||||||
|
CVehicle *m_pCollidingVehicle;
|
||||||
|
uint8 stuff6[496];
|
||||||
|
|
||||||
bool IsPlayer(void) { return m_nPedType == 0 || m_nPedType== 1 || m_nPedType == 2 || m_nPedType == 3; }
|
bool IsPlayer(void) { return m_nPedType == 0 || m_nPedType== 1 || m_nPedType == 2 || m_nPedType == 3; }
|
||||||
};
|
};
|
||||||
|
@ -32,4 +35,5 @@ static_assert(offsetof(CPed, m_nPedState) == 0x224, "CPed: error");
|
||||||
static_assert(offsetof(CPed, m_pCurSurface) == 0x2FC, "CPed: error");
|
static_assert(offsetof(CPed, m_pCurSurface) == 0x2FC, "CPed: error");
|
||||||
static_assert(offsetof(CPed, m_pMyVehicle) == 0x310, "CPed: error");
|
static_assert(offsetof(CPed, m_pMyVehicle) == 0x310, "CPed: error");
|
||||||
static_assert(offsetof(CPed, m_nPedType) == 0x32C, "CPed: error");
|
static_assert(offsetof(CPed, m_nPedType) == 0x32C, "CPed: error");
|
||||||
|
static_assert(offsetof(CPed, m_pCollidingVehicle) == 0x34C, "CPed: error");
|
||||||
static_assert(sizeof(CPed) == 0x540, "CPed: error");
|
static_assert(sizeof(CPed) == 0x540, "CPed: error");
|
||||||
|
|
|
@ -787,6 +787,17 @@ CPhysical::ApplyFriction(float adhesiveLimit, CColPoint &colpoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ProcessCollision calls
|
||||||
|
// CheckCollision
|
||||||
|
// CheckCollision_SimpleCar
|
||||||
|
// CheckCollision calls
|
||||||
|
// ProcessCollisionSectorList
|
||||||
|
// CheckCollision_SimpleCar
|
||||||
|
// ProcessCollisionSectorList_SimpleCar
|
||||||
|
// ProcessShift calls
|
||||||
|
// ProcessCollisionSectorList
|
||||||
|
// ProcessShiftSectorList
|
||||||
|
|
||||||
void
|
void
|
||||||
CPhysical::AddCollisionRecord(CEntity *ent)
|
CPhysical::AddCollisionRecord(CEntity *ent)
|
||||||
{
|
{
|
||||||
|
@ -839,6 +850,168 @@ CPhysical::GetHasCollidedWith(CEntity *ent)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CPhysical::ProcessShiftSectorList(CPtrList *lists)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
CPtrList *list;
|
||||||
|
CPtrNode *node;
|
||||||
|
CPhysical *A, *B;
|
||||||
|
CObject *Bobj;
|
||||||
|
bool canshift;
|
||||||
|
CVector center;
|
||||||
|
float radius;
|
||||||
|
|
||||||
|
int numCollisions;
|
||||||
|
int mostColliding;
|
||||||
|
CColPoint colpoints[32];
|
||||||
|
CVector shift = { 0.0f, 0.0f, 0.0f };
|
||||||
|
bool doShift = false;
|
||||||
|
CEntity *boat = nil;
|
||||||
|
|
||||||
|
bool skipShift;
|
||||||
|
|
||||||
|
A = this;
|
||||||
|
|
||||||
|
A->GetBoundCentre(center);
|
||||||
|
radius = A->GetBoundRadius();
|
||||||
|
for(i = 0; i <= ENTITYLIST_PEDS_OVERLAP; i++){
|
||||||
|
list = &lists[i];
|
||||||
|
for(node = list->first; node; node = node->next){
|
||||||
|
B = (CPhysical*)node->item;
|
||||||
|
Bobj = (CObject*)B;
|
||||||
|
skipShift = false;
|
||||||
|
|
||||||
|
if(B->IsBuilding() ||
|
||||||
|
B->IsObject() && B->bInfiniteMass)
|
||||||
|
canshift = true;
|
||||||
|
else
|
||||||
|
canshift = A->IsPed() &&
|
||||||
|
B->IsObject() && B->bInfiniteMass && !Bobj->bHasBeenDamaged;
|
||||||
|
if(B == A ||
|
||||||
|
B->m_scanCode == CWorld::GetCurrentScanCode() ||
|
||||||
|
!B->bUsesCollision ||
|
||||||
|
(A->bHasHitWall && !canshift) ||
|
||||||
|
!B->GetIsTouching(center, radius))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// This could perhaps be done a bit nicer
|
||||||
|
|
||||||
|
if(B->IsBuilding())
|
||||||
|
skipShift = false;
|
||||||
|
else if(IsTrafficLight(A->GetModelIndex()) &&
|
||||||
|
(B->IsVehicle() || B->IsPed()) &&
|
||||||
|
A->GetUp().z < 0.66f)
|
||||||
|
skipShift = true;
|
||||||
|
else if((A->IsVehicle() || A->IsPed()) &&
|
||||||
|
B->GetUp().z < 0.66f &&
|
||||||
|
IsTrafficLight(B->GetModelIndex()))
|
||||||
|
skipShift = true;
|
||||||
|
else if(A->IsObject() && B->IsVehicle()){
|
||||||
|
CObject *Aobj = (CObject*)A;
|
||||||
|
if(Aobj->ObjectCreatedBy != TEMP_OBJECT &&
|
||||||
|
!Aobj->bHasBeenDamaged &&
|
||||||
|
Aobj->bIsStatic){
|
||||||
|
if(Aobj->m_pCollidingVehicle == B)
|
||||||
|
Aobj->m_pCollidingVehicle = nil;
|
||||||
|
}else if(Aobj->m_pCollidingVehicle != B){
|
||||||
|
CMatrix inv;
|
||||||
|
CVector size = CModelInfo::GetModelInfo(A->GetModelIndex())->GetColModel()->boundingBox.GetSize();
|
||||||
|
size = A->GetMatrix() * size;
|
||||||
|
if(size.z < B->GetPosition().z ||
|
||||||
|
(Invert(B->GetMatrix(), inv) * size).z < 0.0f){
|
||||||
|
skipShift = true;
|
||||||
|
Aobj->m_pCollidingVehicle = (CVehicle*)B;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if(B->IsObject() && A->IsVehicle()){
|
||||||
|
CObject *Bobj = (CObject*)B;
|
||||||
|
if(Bobj->ObjectCreatedBy != TEMP_OBJECT &&
|
||||||
|
!Bobj->bHasBeenDamaged &&
|
||||||
|
Bobj->bIsStatic){
|
||||||
|
if(Bobj->m_pCollidingVehicle == A)
|
||||||
|
Bobj->m_pCollidingVehicle = nil;
|
||||||
|
}else if(Bobj->m_pCollidingVehicle != A){
|
||||||
|
CMatrix inv;
|
||||||
|
CVector size = CModelInfo::GetModelInfo(B->GetModelIndex())->GetColModel()->boundingBox.GetSize();
|
||||||
|
size = B->GetMatrix() * size;
|
||||||
|
if(size.z < A->GetPosition().z ||
|
||||||
|
(Invert(A->GetMatrix(), inv) * size).z < 0.0f){
|
||||||
|
skipShift = true;
|
||||||
|
Bobj->m_pCollidingVehicle = (CVehicle*)A;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if(IsBodyPart(A->GetModelIndex()) && B->IsPed())
|
||||||
|
skipShift = true;
|
||||||
|
else if(A->IsPed() && IsBodyPart(B->GetModelIndex()))
|
||||||
|
skipShift = true;
|
||||||
|
else if(A->IsPed() && ((CPed*)A)->m_pCollidingVehicle == B ||
|
||||||
|
B->IsPed() && ((CPed*)B)->m_pCollidingVehicle == A ||
|
||||||
|
A->GetModelIndex() == MI_RCBANDIT && B->IsVehicle() ||
|
||||||
|
B->GetModelIndex() == MI_RCBANDIT && (A->IsPed() || A->IsVehicle()))
|
||||||
|
skipShift = true;
|
||||||
|
|
||||||
|
if(skipShift)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
B->m_scanCode = CWorld::GetCurrentScanCode();
|
||||||
|
numCollisions = A->ProcessEntityCollision(B, colpoints);
|
||||||
|
if(numCollisions <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
mostColliding = 0;
|
||||||
|
for(j = 1; j < numCollisions; j++)
|
||||||
|
if(colpoints[j].depth > colpoints[mostColliding].depth)
|
||||||
|
mostColliding = j;
|
||||||
|
|
||||||
|
if(CWorld::bSecondShift)
|
||||||
|
for(j = 0; j < numCollisions; j++)
|
||||||
|
shift += colpoints[j].normal * colpoints[j].depth * 1.5f/numCollisions;
|
||||||
|
else
|
||||||
|
for(j = 0; j < numCollisions; j++)
|
||||||
|
shift += colpoints[j].normal * colpoints[j].depth * 1.2f/numCollisions;
|
||||||
|
|
||||||
|
if(A->IsVehicle() && B->IsVehicle()){
|
||||||
|
CVector dir = A->GetPosition() - B->GetPosition();
|
||||||
|
dir.Normalise();
|
||||||
|
if(dir.z < 0.0f && dir.z < A->GetForward().z && dir.z < A->GetRight().z)
|
||||||
|
dir.z = min(0.0f, min(A->GetForward().z, A->GetRight().z));
|
||||||
|
shift += dir * colpoints[mostColliding].depth * 0.5f;
|
||||||
|
}else if(A->IsPed() && B->IsVehicle() && ((CVehicle*)B)->IsBoat()){
|
||||||
|
CVector dir = colpoints[mostColliding].normal;
|
||||||
|
float f = min(fabs(dir.z), 0.9f);
|
||||||
|
dir.z = 0.0f;
|
||||||
|
dir.Normalise();
|
||||||
|
shift += dir * colpoints[mostColliding].depth / (1.0f - f);
|
||||||
|
boat = B;
|
||||||
|
}else if(B->IsPed() && A->IsVehicle() && ((CVehicle*)A)->IsBoat()){
|
||||||
|
CVector dir = colpoints[mostColliding].normal * -1.0f;
|
||||||
|
float f = min(fabs(dir.z), 0.9f);
|
||||||
|
dir.z = 0.0f;
|
||||||
|
dir.Normalise();
|
||||||
|
B->GetPosition() += dir * colpoints[mostColliding].depth / (1.0f - f);
|
||||||
|
// BUG? how can that ever happen? A is a Ped
|
||||||
|
if(B->IsVehicle())
|
||||||
|
B->ProcessEntityCollision(A, colpoints);
|
||||||
|
}else{
|
||||||
|
if(CWorld::bSecondShift)
|
||||||
|
shift += colpoints[mostColliding].normal * colpoints[mostColliding].depth * 0.4f;
|
||||||
|
else
|
||||||
|
shift += colpoints[mostColliding].normal * colpoints[mostColliding].depth * 0.2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
doShift = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!doShift)
|
||||||
|
return false;
|
||||||
|
GetPosition() += shift;
|
||||||
|
if(boat)
|
||||||
|
ProcessEntityCollision(boat, colpoints);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CPhysical::ProcessControl(void)
|
CPhysical::ProcessControl(void)
|
||||||
{
|
{
|
||||||
|
@ -897,6 +1070,8 @@ STARTPATCHES
|
||||||
InjectHook(0x4970C0, &CPhysical::AddCollisionRecord_Treadable, PATCH_JUMP);
|
InjectHook(0x4970C0, &CPhysical::AddCollisionRecord_Treadable, PATCH_JUMP);
|
||||||
InjectHook(0x497240, &CPhysical::GetHasCollidedWith, PATCH_JUMP);
|
InjectHook(0x497240, &CPhysical::GetHasCollidedWith, PATCH_JUMP);
|
||||||
|
|
||||||
|
InjectHook(0x49DA10, &CPhysical::ProcessShiftSectorList, PATCH_JUMP);
|
||||||
|
|
||||||
#define F3 float, float, float
|
#define F3 float, float, float
|
||||||
InjectHook(0x495B10, &CPhysical::ApplyMoveSpeed, PATCH_JUMP);
|
InjectHook(0x495B10, &CPhysical::ApplyMoveSpeed, PATCH_JUMP);
|
||||||
InjectHook(0x497280, &CPhysical::ApplyTurnSpeed, PATCH_JUMP);
|
InjectHook(0x497280, &CPhysical::ApplyTurnSpeed, PATCH_JUMP);
|
||||||
|
|
|
@ -77,6 +77,8 @@ public:
|
||||||
CRect GetBoundRect(void);
|
CRect GetBoundRect(void);
|
||||||
void ProcessControl(void);
|
void ProcessControl(void);
|
||||||
|
|
||||||
|
virtual int32 ProcessEntityCollision(CEntity *ent, CColPoint *point);
|
||||||
|
|
||||||
void RemoveAndAdd(void);
|
void RemoveAndAdd(void);
|
||||||
void AddToMovingList(void);
|
void AddToMovingList(void);
|
||||||
void RemoveFromMovingList(void);
|
void RemoveFromMovingList(void);
|
||||||
|
@ -128,6 +130,8 @@ public:
|
||||||
void AddCollisionRecord_Treadable(CEntity *ent);
|
void AddCollisionRecord_Treadable(CEntity *ent);
|
||||||
bool GetHasCollidedWith(CEntity *ent);
|
bool GetHasCollidedWith(CEntity *ent);
|
||||||
|
|
||||||
|
bool ProcessShiftSectorList(CPtrList *ptrlists);
|
||||||
|
|
||||||
// to make patching virtual functions possible
|
// to make patching virtual functions possible
|
||||||
void Add_(void) { CPhysical::Add(); }
|
void Add_(void) { CPhysical::Add(); }
|
||||||
void Remove_(void) { CPhysical::Remove(); }
|
void Remove_(void) { CPhysical::Remove(); }
|
||||||
|
|
|
@ -16,6 +16,12 @@ public:
|
||||||
CEntity *m_pCurSurface;
|
CEntity *m_pCurSurface;
|
||||||
uint8 stuff3[160];
|
uint8 stuff3[160];
|
||||||
int32 m_vehType;
|
int32 m_vehType;
|
||||||
|
|
||||||
|
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; }
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CVehicle) == 0x288, "CVehicle: error");
|
static_assert(sizeof(CVehicle) == 0x288, "CVehicle: error");
|
||||||
static_assert(offsetof(CVehicle, m_pCurSurface) == 0x1E0, "CVehicle: error");
|
static_assert(offsetof(CVehicle, m_pCurSurface) == 0x1E0, "CVehicle: error");
|
||||||
|
|
|
@ -205,6 +205,16 @@ enum
|
||||||
|
|
||||||
MI_RHINO = 122,
|
MI_RHINO = 122,
|
||||||
MI_COACH = 127,
|
MI_COACH = 127,
|
||||||
|
MI_RCBANDIT = 131,
|
||||||
|
|
||||||
|
MI_CAR_DOOR = 190,
|
||||||
|
MI_CAR_BUMPER,
|
||||||
|
MI_CAR_PANEL,
|
||||||
|
MI_CAR_BONNET,
|
||||||
|
MI_CAR_BOOT,
|
||||||
|
MI_CAR_WEEL,
|
||||||
|
MI_BODYPARTA,
|
||||||
|
MI_BODYPARTB,
|
||||||
};
|
};
|
||||||
|
|
||||||
void InitModelIndices(void);
|
void InitModelIndices(void);
|
||||||
|
@ -222,3 +232,19 @@ IsGlass(int16 id)
|
||||||
id == MI_GLASS7 ||
|
id == MI_GLASS7 ||
|
||||||
id == MI_GLASS8;
|
id == MI_GLASS8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
IsTrafficLight(int16 id)
|
||||||
|
{
|
||||||
|
return id == MI_TRAFFICLIGHTS ||
|
||||||
|
id == MI_SINGLESTREETLIGHTS1 ||
|
||||||
|
id == MI_SINGLESTREETLIGHTS2 ||
|
||||||
|
id == MI_SINGLESTREETLIGHTS3 ||
|
||||||
|
id == MI_DOUBLESTREETLIGHTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
IsBodyPart(int16 id)
|
||||||
|
{
|
||||||
|
return id == MI_BODYPARTA || id == MI_BODYPARTB;
|
||||||
|
}
|
||||||
|
|
|
@ -195,7 +195,7 @@ CRenderer::RenderEverythingBarRoads(void)
|
||||||
|
|
||||||
if(e->IsVehicle() ||
|
if(e->IsVehicle() ||
|
||||||
e->IsPed() && CVisibilityPlugins::GetClumpAlpha((RpClump*)e->m_rwObject) != 255){
|
e->IsPed() && CVisibilityPlugins::GetClumpAlpha((RpClump*)e->m_rwObject) != 255){
|
||||||
if(e->IsVehicle() && ((CVehicle*)e)->m_vehType == VEHICLE_TYPE_BOAT){
|
if(e->IsVehicle() && ((CVehicle*)e)->IsBoat()){
|
||||||
dist = ms_vecCameraPosition - e->GetPosition();
|
dist = ms_vecCameraPosition - e->GetPosition();
|
||||||
if(!CVisibilityPlugins::InsertEntityIntoSortedList(e, dist.Magnitude())){
|
if(!CVisibilityPlugins::InsertEntityIntoSortedList(e, dist.Magnitude())){
|
||||||
printf("Ran out of space in alpha entity list");
|
printf("Ran out of space in alpha entity list");
|
||||||
|
@ -221,7 +221,7 @@ CRenderer::RenderVehiclesButNotBoats(void)
|
||||||
node != &gSortedVehiclesAndPeds.head;
|
node != &gSortedVehiclesAndPeds.head;
|
||||||
node = node->prev){
|
node = node->prev){
|
||||||
CVehicle *v = (CVehicle*)node->item.ent;
|
CVehicle *v = (CVehicle*)node->item.ent;
|
||||||
if(v->IsVehicle() && v->m_vehType == VEHICLE_TYPE_BOAT) // BUG: missing in III
|
if(v->IsVehicle() && v->IsBoat()) // BUG: IsVehicle missing in III
|
||||||
continue;
|
continue;
|
||||||
RenderOneNonRoad(v);
|
RenderOneNonRoad(v);
|
||||||
}
|
}
|
||||||
|
@ -236,9 +236,7 @@ CRenderer::RenderBoats(void)
|
||||||
node != &gSortedVehiclesAndPeds.head;
|
node != &gSortedVehiclesAndPeds.head;
|
||||||
node = node->prev){
|
node = node->prev){
|
||||||
CVehicle *v = (CVehicle*)node->item.ent;
|
CVehicle *v = (CVehicle*)node->item.ent;
|
||||||
if(!v->IsVehicle()) // BUG: missing in III
|
if(v->IsVehicle() && v->IsBoat()) // BUG: IsVehicle missing in III
|
||||||
continue;
|
|
||||||
if(v->m_vehType == VEHICLE_TYPE_BOAT)
|
|
||||||
RenderOneNonRoad(v);
|
RenderOneNonRoad(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue