summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Collision.cpp27
-rw-r--r--src/Collision.h6
-rw-r--r--src/Garages.cpp42
-rw-r--r--src/Garages.h7
-rw-r--r--src/SurfaceTable.h22
-rw-r--r--src/TempColModels.cpp17
-rw-r--r--src/TempColModels.h21
-rw-r--r--src/World.cpp545
-rw-r--r--src/World.h22
-rw-r--r--src/entities/Object.h1
-rw-r--r--src/entities/Ped.cpp164
-rw-r--r--src/entities/Ped.h61
-rw-r--r--src/entities/Physical.h15
-rw-r--r--src/main.cpp3
-rw-r--r--src/render/Renderer.cpp6
15 files changed, 915 insertions, 44 deletions
diff --git a/src/Collision.cpp b/src/Collision.cpp
index 14b3adcd..e6a81954 100644
--- a/src/Collision.cpp
+++ b/src/Collision.cpp
@@ -384,7 +384,7 @@ CCollision::TestSphereTriangle(const CColSphere &sphere,
}
bool
-CCollision::TestLineOfSight(CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSurf78)
+CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSeeThrough)
{
static CMatrix matTransform;
int i;
@@ -398,18 +398,18 @@ CCollision::TestLineOfSight(CColLine &line, const CMatrix &matrix, CColModel &mo
return false;
for(i = 0; i < model.numSpheres; i++)
- if(!ignoreSurf78 || model.spheres[i].surface != 7 && model.spheres[i].surface != 8)
+ if(!ignoreSeeThrough || model.spheres[i].surface != SURFACE_GLASS && model.spheres[i].surface != SURFACE_SCAFFOLD)
if(TestLineSphere(newline, model.spheres[i]))
return true;
for(i = 0; i < model.numBoxes; i++)
- if(!ignoreSurf78 || model.boxes[i].surface != 7 && model.boxes[i].surface != 8)
+ if(!ignoreSeeThrough || model.boxes[i].surface != SURFACE_GLASS && model.boxes[i].surface != SURFACE_SCAFFOLD)
if(TestLineBox(newline, model.boxes[i]))
return true;
CalculateTrianglePlanes(&model);
for(i = 0; i < model.numTriangles; i++)
- if(!ignoreSurf78 || model.triangles[i].surface != 7 && model.triangles[i].surface != 8)
+ if(!ignoreSeeThrough || model.triangles[i].surface != SURFACE_GLASS && model.triangles[i].surface != SURFACE_SCAFFOLD)
if(TestLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i]))
return true;
@@ -933,7 +933,7 @@ CCollision::ProcessSphereTriangle(const CColSphere &sphere,
bool
CCollision::ProcessLineOfSight(const CColLine &line,
const CMatrix &matrix, CColModel &model,
- CColPoint &point, float &mindist, bool ignoreSurf78)
+ CColPoint &point, float &mindist, bool ignoreSeeThrough)
{
static CMatrix matTransform;
int i;
@@ -948,16 +948,16 @@ CCollision::ProcessLineOfSight(const CColLine &line,
float coldist = mindist;
for(i = 0; i < model.numSpheres; i++)
- if(!ignoreSurf78 || model.spheres[i].surface != 7 && model.spheres[i].surface != 8)
+ if(!ignoreSeeThrough || model.spheres[i].surface != SURFACE_GLASS && model.spheres[i].surface != SURFACE_SCAFFOLD)
ProcessLineSphere(newline, model.spheres[i], point, coldist);
for(i = 0; i < model.numBoxes; i++)
- if(!ignoreSurf78 || model.boxes[i].surface != 7 && model.boxes[i].surface != 8)
+ if(!ignoreSeeThrough || model.boxes[i].surface != SURFACE_GLASS && model.boxes[i].surface != SURFACE_SCAFFOLD)
ProcessLineBox(newline, model.boxes[i], point, coldist);
CalculateTrianglePlanes(&model);
for(i = 0; i < model.numTriangles; i++)
- if(!ignoreSurf78 || model.triangles[i].surface != 7 && model.triangles[i].surface != 8)
+ if(!ignoreSeeThrough || model.triangles[i].surface != SURFACE_GLASS && model.triangles[i].surface != SURFACE_SCAFFOLD)
ProcessLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i], point, coldist);
if(coldist < mindist){
@@ -972,7 +972,7 @@ CCollision::ProcessLineOfSight(const CColLine &line,
bool
CCollision::ProcessVerticalLine(const CColLine &line,
const CMatrix &matrix, CColModel &model,
- CColPoint &point, float &mindist, bool ignoreSurf78, CStoredCollPoly *poly)
+ CColPoint &point, float &mindist, bool ignoreSeeThrough, CStoredCollPoly *poly)
{
static CStoredCollPoly TempStoredPoly;
int i;
@@ -988,17 +988,17 @@ CCollision::ProcessVerticalLine(const CColLine &line,
float coldist = mindist;
for(i = 0; i < model.numSpheres; i++)
- if(!ignoreSurf78 || model.spheres[i].surface != 7 && model.spheres[i].surface != 8)
+ if(!ignoreSeeThrough || model.spheres[i].surface != SURFACE_GLASS && model.spheres[i].surface != SURFACE_SCAFFOLD)
ProcessLineSphere(newline, model.spheres[i], point, coldist);
for(i = 0; i < model.numBoxes; i++)
- if(!ignoreSurf78 || model.boxes[i].surface != 7 && model.boxes[i].surface != 8)
+ if(!ignoreSeeThrough || model.boxes[i].surface != SURFACE_GLASS && model.boxes[i].surface != SURFACE_SCAFFOLD)
ProcessLineBox(newline, model.boxes[i], point, coldist);
CalculateTrianglePlanes(&model);
TempStoredPoly.valid = false;
for(i = 0; i < model.numTriangles; i++)
- if(!ignoreSurf78 || model.triangles[i].surface != 7 && model.triangles[i].surface != 8)
+ if(!ignoreSeeThrough || model.triangles[i].surface != SURFACE_GLASS && model.triangles[i].surface != SURFACE_SCAFFOLD)
ProcessVerticalLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i], point, coldist, &TempStoredPoly);
if(coldist < mindist){
@@ -1260,6 +1260,7 @@ CCollision::DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel,
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
+extern int gDbgSurf;
for(i = 0; i < colModel.numTriangles; i++){
colModel.GetTrianglePoint(verts[0], colModel.triangles[i].a);
@@ -1310,6 +1311,7 @@ CCollision::DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel,
}
// TODO: make some surface types flicker?
+//if(s != gDbgSurf) continue;
if(s > SURFACE_32){
r = CGeneral::GetRandomNumber();
@@ -1385,6 +1387,7 @@ CCollision::DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel,
}
// TODO: make some surface types flicker?
+//if(s != gDbgSurf) continue;
RenderBuffer::StartStoring(36, 8, &iptr, &vptr);
RwIm3DVertexSetRGBA(&vptr[0], r, g, b, 255);
diff --git a/src/Collision.h b/src/Collision.h
index 53a314bd..1bd4ca4a 100644
--- a/src/Collision.h
+++ b/src/Collision.h
@@ -132,7 +132,7 @@ public:
static bool TestLineTriangle(const CColLine &line, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane);
static bool TestLineSphere(const CColLine &line, const CColSphere &sph);
static bool TestSphereTriangle(const CColSphere &sphere, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane);
- static bool TestLineOfSight(CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSurf78);
+ static bool TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSeeThrough);
static bool ProcessSphereSphere(const CColSphere &s1, const CColSphere &s2, CColPoint &point, float &mindistsq);
static bool ProcessSphereBox(const CColSphere &sph, const CColBox &box, CColPoint &point, float &mindistsq);
@@ -141,8 +141,8 @@ public:
static bool ProcessLineTriangle(const CColLine &line , const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist);
static bool ProcessLineSphere(const CColLine &line, const CColSphere &sphere, CColPoint &point, float &mindist);
static bool ProcessSphereTriangle(const CColSphere &sph, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindistsq);
- static bool ProcessLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSurf78);
- static bool ProcessVerticalLine(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSurf78, CStoredCollPoly *poly);
+ static bool ProcessLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough);
+ static bool ProcessVerticalLine(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough, CStoredCollPoly *poly);
static int32 ProcessColModels(const CMatrix &matrix1, CColModel &model1, const CMatrix &matrix2, CColModel &model2, CColPoint *point1, CColPoint *point2, float *linedists);
// TODO:
diff --git a/src/Garages.cpp b/src/Garages.cpp
new file mode 100644
index 00000000..42e38a3a
--- /dev/null
+++ b/src/Garages.cpp
@@ -0,0 +1,42 @@
+#include "common.h"
+#include "patcher.h"
+#include "ModelIndices.h"
+#include "Garages.h"
+
+bool
+CGarages::IsModelIndexADoor(uint32 id)
+{
+ return id == MI_GARAGEDOOR1 ||
+ id == MI_GARAGEDOOR2 ||
+ id == MI_GARAGEDOOR3 ||
+ id == MI_GARAGEDOOR4 ||
+ id == MI_GARAGEDOOR5 ||
+ id == MI_GARAGEDOOR6 ||
+ id == MI_GARAGEDOOR7 ||
+ id == MI_GARAGEDOOR9 ||
+ id == MI_GARAGEDOOR10 ||
+ id == MI_GARAGEDOOR11 ||
+ id == MI_GARAGEDOOR12 ||
+ id == MI_GARAGEDOOR13 ||
+ id == MI_GARAGEDOOR14 ||
+ id == MI_GARAGEDOOR15 ||
+ id == MI_GARAGEDOOR16 ||
+ id == MI_GARAGEDOOR17 ||
+ id == MI_GARAGEDOOR18 ||
+ id == MI_GARAGEDOOR19 ||
+ id == MI_GARAGEDOOR20 ||
+ id == MI_GARAGEDOOR21 ||
+ id == MI_GARAGEDOOR22 ||
+ id == MI_GARAGEDOOR23 ||
+ id == MI_GARAGEDOOR24 ||
+ id == MI_GARAGEDOOR25 ||
+ id == MI_GARAGEDOOR26 ||
+ id == MI_GARAGEDOOR27 ||
+ id == MI_GARAGEDOOR28 ||
+ id == MI_GARAGEDOOR29 ||
+ id == MI_GARAGEDOOR30 ||
+ id == MI_GARAGEDOOR31 ||
+ id == MI_GARAGEDOOR32 ||
+ id == MI_CRUSHERBODY ||
+ id == MI_CRUSHERLID;
+}
diff --git a/src/Garages.h b/src/Garages.h
new file mode 100644
index 00000000..70add26d
--- /dev/null
+++ b/src/Garages.h
@@ -0,0 +1,7 @@
+#pragma once
+
+class CGarages
+{
+public:
+ static bool IsModelIndexADoor(uint32 id);
+};
diff --git a/src/SurfaceTable.h b/src/SurfaceTable.h
index f1ef3002..e61f5026 100644
--- a/src/SurfaceTable.h
+++ b/src/SurfaceTable.h
@@ -44,26 +44,26 @@ enum
// TODO: check and use this
enum eSurfaceType
{
- SURFACE_ROAD0,
- SURFACE_ROAD1,
+ SURFACE_DEFAULT,
+ SURFACE_TARMAC,
SURFACE_GRASS,
SURFACE_DIRT,
- SURFACE_MUD,
+ SURFACE_DIRTTRACK,
SURFACE_PAVEMENT,
SURFACE_METAL6,
SURFACE_GLASS,
- SURFACE_HARD8,
- SURFACE_METAL_DOOR,
- SURFACE_METAL10,
- SURFACE_METAL11,
- SURFACE_METAL12,
- SURFACE_METAL13,
+ SURFACE_SCAFFOLD,
+ SURFACE_METAL_DOOR, // garage door
+ SURFACE_BILLBOARD,
+ SURFACE_STEEL, //?
+ SURFACE_METAL_POLE, // ?
+ SURFACE_STREET_LIGHT,
SURFACE_METAL14,
SURFACE_METAL15,
SURFACE_METAL_FENCE,
SURFACE_FLESH,
- SURFACE_SAND18,
- SURFACE_WATER,
+ SURFACE_SAND,
+ SURFACE_PUDDLE,
SURFACE_WOOD,
SURFACE_WOOD_BOX,
SURFACE_WOOD_PLANK,
diff --git a/src/TempColModels.cpp b/src/TempColModels.cpp
new file mode 100644
index 00000000..a323d7c9
--- /dev/null
+++ b/src/TempColModels.cpp
@@ -0,0 +1,17 @@
+#include "common.h"
+#include "patcher.h"
+#include "TempColModels.h"
+
+CColModel &CTempColModels::ms_colModelPed1 = *(CColModel*)0x726CB0;
+CColModel &CTempColModels::ms_colModelPed2 = *(CColModel*)0x726D08;
+CColModel &CTempColModels::ms_colModelBBox = *(CColModel*)0x727FE0;
+CColModel &CTempColModels::ms_colModelBumper1 = *(CColModel*)0x86BE88;
+CColModel &CTempColModels::ms_colModelWheel1 = *(CColModel*)0x878C40;
+CColModel &CTempColModels::ms_colModelPanel1 = *(CColModel*)0x87BDD8;
+CColModel &CTempColModels::ms_colModelBodyPart2 = *(CColModel*)0x87BE30;
+CColModel &CTempColModels::ms_colModelBodyPart1 = *(CColModel*)0x87BE88;
+CColModel &CTempColModels::ms_colModelCutObj = *(CColModel*)0x87C960;
+CColModel &CTempColModels::ms_colModelPedGroundHit = *(CColModel*)0x880480;
+CColModel &CTempColModels::ms_colModelBoot1 = *(CColModel*)0x880670;
+CColModel &CTempColModels::ms_colModelDoor1 = *(CColModel*)0x880850;
+CColModel &CTempColModels::ms_colModelBonnet1 = *(CColModel*)0x8808A8;
diff --git a/src/TempColModels.h b/src/TempColModels.h
new file mode 100644
index 00000000..8ac74428
--- /dev/null
+++ b/src/TempColModels.h
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "Collision.h"
+
+class CTempColModels
+{
+public:
+ static CColModel &ms_colModelPed1;
+ static CColModel &ms_colModelPed2;
+ static CColModel &ms_colModelBBox;
+ static CColModel &ms_colModelBumper1;
+ static CColModel &ms_colModelWheel1;
+ static CColModel &ms_colModelPanel1;
+ static CColModel &ms_colModelBodyPart2;
+ static CColModel &ms_colModelBodyPart1;
+ static CColModel &ms_colModelCutObj;
+ static CColModel &ms_colModelPedGroundHit;
+ static CColModel &ms_colModelBoot1;
+ static CColModel &ms_colModelDoor1;
+ static CColModel &ms_colModelBonnet1;
+};
diff --git a/src/World.cpp b/src/World.cpp
index c657be78..58dee174 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -1,6 +1,10 @@
#include "common.h"
#include "patcher.h"
#include "Entity.h"
+#include "Ped.h"
+#include "Object.h"
+#include "Garages.h"
+#include "TempColModels.h"
#include "World.h"
CPtrList *CWorld::ms_bigBuildingsList = (CPtrList*)0x6FAB60;
@@ -10,6 +14,7 @@ uint16 &CWorld::ms_nCurrentScanCode = *(uint16*)0x95CC64;
bool &CWorld::bNoMoreCollisionTorque = *(bool*)0x95CDCC;
CEntity *&CWorld::pIgnoreEntity = *(CEntity**)0x8F6494;
+bool &CWorld::bIncludeDeadPeds = *(bool*)0x95CD8F;
bool &CWorld::bSecondShift = *(bool*)0x95CD54;
bool &CWorld::bForceProcessControl = *(bool*)0x95CD6C;
bool &CWorld::bProcessCutsceneOnly = *(bool*)0x95CD8B;
@@ -35,8 +40,548 @@ CWorld::ClearScanCodes(void)
}
}
+bool
+CWorld::CameraToIgnoreThisObject(CEntity *ent)
+{
+ if(CGarages::IsModelIndexADoor(ent->GetModelIndex()))
+ return false;
+ return ((CObject*)ent)->m_bCameraToAvoidThisObject != 1;
+}
+
+bool
+CWorld::ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects)
+{
+ int x, xstart, xend;
+ int y, ystart, yend;
+ int y1, y2;
+ float dist;
+
+ AdvanceCurrentScanCode();
+
+ entity = nil;
+ dist = 1.0f;
+
+ xstart = GetSectorIndexX(point1.x);
+ ystart = GetSectorIndexX(point1.y);
+ xend = GetSectorIndexX(point2.x);
+ yend = GetSectorIndexX(point2.y);
+
+#define LOSARGS CColLine(point1, point2), point, dist, entity, checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, ignoreSeeThrough, ignoreSomeObjects
+
+ if(xstart == xend && ystart == yend){
+ // Only one sector
+ return ProcessLineOfSightSector(*GetSector(xstart, ystart), LOSARGS);
+ }else if(xstart == xend){
+ // Only step in y
+ if(ystart < yend)
+ for(y = ystart; y <= yend; y++)
+ ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
+ else
+ for(y = ystart; y >= yend; y--)
+ ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
+ return dist < 1.0f;
+ }else if(ystart == yend){
+ // Only step in x
+ if(xstart < xend)
+ for(x = xstart; x <= xend; x++)
+ ProcessLineOfSightSector(*GetSector(x, ystart), LOSARGS);
+ else
+ for(x = xstart; x >= xend; x--)
+ ProcessLineOfSightSector(*GetSector(x, ystart), LOSARGS);
+ return dist < 1.0f;
+ }else{
+ if(point1.x < point2.x){
+ // Step from left to right
+ float m = (point2.y - point1.y) / (point2.x - point1.x);
+
+ y1 = ystart;
+ y2 = GetSectorIndexY((GetWorldX(xstart+1) - point1.x)*m + point1.y);
+ if(y1 < y2)
+ for(y = y1; y <= y2; y++)
+ ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
+ else
+ for(y = y1; y >= y2; y--)
+ ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
+
+ for(x = xstart+1; x < xend; x++){
+ y1 = y2;
+ y2 = GetSectorIndexY((GetWorldX(x+1) - point1.x)*m + point1.y);
+ if(y1 < y2)
+ for(y = y1; y <= y2; y++)
+ ProcessLineOfSightSector(*GetSector(x, y), LOSARGS);
+ else
+ for(y = y1; y >= y2; y--)
+ ProcessLineOfSightSector(*GetSector(x, y), LOSARGS);
+ }
+
+ y1 = y2;
+ y2 = yend;
+ if(y1 < y2)
+ for(y = y1; y <= y2; y++)
+ ProcessLineOfSightSector(*GetSector(xend, y), LOSARGS);
+ else
+ for(y = y1; y >= y2; y--)
+ ProcessLineOfSightSector(*GetSector(xend, y), LOSARGS);
+ }else{
+ // Step from right to left
+ float m = (point2.y - point1.y) / (point2.x - point1.x);
+
+ y1 = ystart;
+ y2 = GetSectorIndexY((GetWorldX(xstart) - point1.x)*m + point1.y);
+ if(y1 < y2)
+ for(y = y1; y <= y2; y++)
+ ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
+ else
+ for(y = y1; y >= y2; y--)
+ ProcessLineOfSightSector(*GetSector(xstart, y), LOSARGS);
+
+ for(x = xstart-1; x > xend; x--){
+ y1 = y2;
+ y2 = GetSectorIndexY((GetWorldX(x) - point1.x)*m + point1.y);
+ if(y1 < y2)
+ for(y = y1; y <= y2; y++)
+ ProcessLineOfSightSector(*GetSector(x, y), LOSARGS);
+ else
+ for(y = y1; y >= y2; y--)
+ ProcessLineOfSightSector(*GetSector(x, y), LOSARGS);
+ }
+
+ y1 = y2;
+ y2 = yend;
+ if(y1 < y2)
+ for(y = y1; y <= y2; y++)
+ ProcessLineOfSightSector(*GetSector(xend, y), LOSARGS);
+ else
+ for(y = y1; y >= y2; y--)
+ ProcessLineOfSightSector(*GetSector(xend, y), LOSARGS);
+ }
+ return dist < 1.0f;
+ }
+
+#undef LOSARGS
+}
+
+bool
+CWorld::ProcessLineOfSightSector(CSector &sector, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects)
+{
+ float mindist = dist;
+ bool deadPeds = !!bIncludeDeadPeds;
+ bIncludeDeadPeds = false;
+
+ if(checkBuildings){
+ ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_BUILDINGS], line, point, mindist, entity, ignoreSeeThrough);
+ ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_BUILDINGS_OVERLAP], line, point, mindist, entity, ignoreSeeThrough);
+ }
+
+ if(checkVehicles){
+ ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_VEHICLES], line, point, mindist, entity, ignoreSeeThrough);
+ ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_VEHICLES_OVERLAP], line, point, mindist, entity, ignoreSeeThrough);
+ }
+
+ if(checkPeds){
+ if(deadPeds)
+ bIncludeDeadPeds = true;
+ ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_PEDS], line, point, mindist, entity, ignoreSeeThrough);
+ ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_PEDS_OVERLAP], line, point, mindist, entity, ignoreSeeThrough);
+ bIncludeDeadPeds = false;
+ }
+
+ if(checkObjects){
+ ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_OBJECTS], line, point, mindist, entity, ignoreSeeThrough, ignoreSomeObjects);
+ ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_OBJECTS_OVERLAP], line, point, mindist, entity, ignoreSeeThrough, ignoreSomeObjects);
+ }
+
+ if(checkDummies){
+ ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_DUMMIES], line, point, mindist, entity, ignoreSeeThrough);
+ ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_DUMMIES_OVERLAP], line, point, mindist, entity, ignoreSeeThrough);
+ }
+
+ bIncludeDeadPeds = deadPeds;
+
+ if(mindist < dist){
+ dist = mindist;
+ return true;
+ }else
+ return false;
+}
+
+bool
+CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool ignoreSeeThrough, bool ignoreSomeObjects)
+{
+ bool deadPeds = false;
+ float mindist = dist;
+ CPtrNode *node;
+ CEntity *e;
+ CColModel *colmodel;
+
+ if(list.first && bIncludeDeadPeds && ((CEntity*)list.first->item)->IsPed())
+ deadPeds = true;
+
+ for(node = list.first; node; node = node->next){
+ e = (CEntity*)node->item;
+ if(e->m_scanCode != GetCurrentScanCode() &&
+ e != pIgnoreEntity &&
+ (e->bUsesCollision || deadPeds) &&
+ !(ignoreSomeObjects && CameraToIgnoreThisObject(e))){
+ colmodel = nil;
+ e->m_scanCode = GetCurrentScanCode();
+
+ if(e->IsPed()){
+ if(e->bUsesCollision ||
+ deadPeds && ((CPed*)e)->m_nPedState == PED_DEAD){
+ if(((CPed*)e)->UseGroundColModel())
+ colmodel = &CTempColModels::ms_colModelPedGroundHit;
+ else
+ colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
+ }else
+ colmodel = nil;
+ }else if(e->bUsesCollision)
+ colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
+
+ if(colmodel &&
+ CCollision::ProcessLineOfSight(line, e->GetMatrix(), *colmodel, point, dist, ignoreSeeThrough))
+ entity = e;
+ }
+ }
+
+ if(mindist < dist){
+ dist = mindist;
+ return true;
+ }else
+ return false;
+}
+
+bool
+CWorld::ProcessVerticalLine(const CVector &point1, float z2, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, CStoredCollPoly *poly)
+{
+ AdvanceCurrentScanCode();
+ CVector point2(point1.x, point1.y, z2);
+ return CWorld::ProcessVerticalLineSector(*GetSector(GetSectorIndexX(point1.x), GetSectorIndexX(point1.y)),
+ CColLine(point1, point2), point, entity,
+ checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, ignoreSeeThrough, poly);
+}
+
+bool
+CWorld::ProcessVerticalLineSector(CSector &sector, const CColLine &line, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, CStoredCollPoly *poly)
+{
+ float mindist = 1.0f;
+
+ if(checkBuildings){
+ ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_BUILDINGS], line, point, mindist, entity, ignoreSeeThrough, poly);
+ ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_BUILDINGS_OVERLAP], line, point, mindist, entity, ignoreSeeThrough, poly);
+ }
+
+ if(checkVehicles){
+ ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_VEHICLES], line, point, mindist, entity, ignoreSeeThrough, poly);
+ ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_VEHICLES_OVERLAP], line, point, mindist, entity, ignoreSeeThrough, poly);
+ }
+
+ if(checkPeds){
+ ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_PEDS], line, point, mindist, entity, ignoreSeeThrough, poly);
+ ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_PEDS_OVERLAP], line, point, mindist, entity, ignoreSeeThrough, poly);
+ }
+
+ if(checkObjects){
+ ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_OBJECTS], line, point, mindist, entity, ignoreSeeThrough, poly);
+ ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_OBJECTS_OVERLAP], line, point, mindist, entity, ignoreSeeThrough, poly);
+ }
+
+ if(checkDummies){
+ ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_DUMMIES], line, point, mindist, entity, ignoreSeeThrough, poly);
+ ProcessVerticalLineSectorList(sector.m_lists[ENTITYLIST_DUMMIES_OVERLAP], line, point, mindist, entity, ignoreSeeThrough, poly);
+ }
+
+ return mindist < 1.0f;
+}
+
+bool
+CWorld::ProcessVerticalLineSectorList(CPtrList &list, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool ignoreSeeThrough, CStoredCollPoly *poly)
+{
+ float mindist = dist;
+ CPtrNode *node;
+ CEntity *e;
+ CColModel *colmodel;
+
+ for(node = list.first; node; node = node->next){
+ e = (CEntity*)node->item;
+ if(e->m_scanCode != GetCurrentScanCode() &&
+ e->bUsesCollision){
+ e->m_scanCode = GetCurrentScanCode();
+
+ colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
+ if(CCollision::ProcessVerticalLine(line, e->GetMatrix(), *colmodel, point, dist, ignoreSeeThrough, poly))
+ entity = e;
+ }
+ }
+
+ if(mindist < dist){
+ dist = mindist;
+ return true;
+ }else
+ return false;
+}
+
+bool
+CWorld::GetIsLineOfSightClear(const CVector &point1, const CVector &point2, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects)
+{
+ int x, xstart, xend;
+ int y, ystart, yend;
+ int y1, y2;
+
+ AdvanceCurrentScanCode();
+
+ xstart = GetSectorIndexX(point1.x);
+ ystart = GetSectorIndexX(point1.y);
+ xend = GetSectorIndexX(point2.x);
+ yend = GetSectorIndexX(point2.y);
+
+#define LOSARGS CColLine(point1, point2), checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, ignoreSeeThrough, ignoreSomeObjects
+
+ if(xstart == xend && ystart == yend){
+ // Only one sector
+ return GetIsLineOfSightSectorClear(*GetSector(xstart, ystart), LOSARGS);
+ }else if(xstart == xend){
+ // Only step in y
+ if(ystart < yend){
+ for(y = ystart; y <= yend; y++)
+ if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS))
+ return false;
+ }else{
+ for(y = ystart; y >= yend; y--)
+ if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS))
+ return false;
+ }
+ }else if(ystart == yend){
+ // Only step in x
+ if(xstart < xend){
+ for(x = xstart; x <= xend; x++)
+ if(!GetIsLineOfSightSectorClear(*GetSector(x, ystart), LOSARGS))
+ return false;
+ }else{
+ for(x = xstart; x >= xend; x--)
+ if(!GetIsLineOfSightSectorClear(*GetSector(x, ystart), LOSARGS))
+ return false;
+ }
+ }else{
+ if(point1.x < point2.x){
+ // Step from left to right
+ float m = (point2.y - point1.y) / (point2.x - point1.x);
+
+ y1 = ystart;
+ y2 = GetSectorIndexY((GetWorldX(xstart+1) - point1.x)*m + point1.y);
+ if(y1 < y2){
+ for(y = y1; y <= y2; y++)
+ if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS))
+ return false;
+ }else{
+ for(y = y1; y >= y2; y--)
+ if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS))
+ return false;
+ }
+
+ for(x = xstart+1; x < xend; x++){
+ y1 = y2;
+ y2 = GetSectorIndexY((GetWorldX(x+1) - point1.x)*m + point1.y);
+ if(y1 < y2){
+ for(y = y1; y <= y2; y++)
+ if(!GetIsLineOfSightSectorClear(*GetSector(x, y), LOSARGS))
+ return false;
+ }else{
+ for(y = y1; y >= y2; y--)
+ if(!GetIsLineOfSightSectorClear(*GetSector(x, y), LOSARGS))
+ return false;
+ }
+ }
+
+ y1 = y2;
+ y2 = yend;
+ if(y1 < y2){
+ for(y = y1; y <= y2; y++)
+ if(!GetIsLineOfSightSectorClear(*GetSector(xend, y), LOSARGS))
+ return false;
+ }else{
+ for(y = y1; y >= y2; y--)
+ if(!GetIsLineOfSightSectorClear(*GetSector(xend, y), LOSARGS))
+ return false;
+ }
+ }else{
+ // Step from right to left
+ float m = (point2.y - point1.y) / (point2.x - point1.x);
+
+ y1 = ystart;
+ y2 = GetSectorIndexY((GetWorldX(xstart) - point1.x)*m + point1.y);
+ if(y1 < y2){
+ for(y = y1; y <= y2; y++)
+ if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS))
+ return false;
+ }else{
+ for(y = y1; y >= y2; y--)
+ if(!GetIsLineOfSightSectorClear(*GetSector(xstart, y), LOSARGS))
+ return false;
+ }
+
+ for(x = xstart-1; x > xend; x--){
+ y1 = y2;
+ y2 = GetSectorIndexY((GetWorldX(x) - point1.x)*m + point1.y);
+ if(y1 < y2){
+ for(y = y1; y <= y2; y++)
+ if(!GetIsLineOfSightSectorClear(*GetSector(x, y), LOSARGS))
+ return false;
+ }else{
+ for(y = y1; y >= y2; y--)
+ if(!GetIsLineOfSightSectorClear(*GetSector(x, y), LOSARGS))
+ return false;
+ }
+ }
+
+ y1 = y2;
+ y2 = yend;
+ if(y1 < y2){
+ for(y = y1; y <= y2; y++)
+ if(!GetIsLineOfSightSectorClear(*GetSector(xend, y), LOSARGS))
+ return false;
+ }else{
+ for(y = y1; y >= y2; y--)
+ if(!GetIsLineOfSightSectorClear(*GetSector(xend, y), LOSARGS))
+ return false;
+ }
+ }
+ }
+
+ return true;
+
+#undef LOSARGS
+}
+
+bool
+CWorld::GetIsLineOfSightSectorClear(CSector &sector, const CColLine &line, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects)
+{
+ if(checkBuildings){
+ if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_BUILDINGS], line, ignoreSeeThrough))
+ return false;
+ if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_BUILDINGS_OVERLAP], line, ignoreSeeThrough))
+ return false;
+ }
+
+ if(checkVehicles){
+ if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_VEHICLES], line, ignoreSeeThrough))
+ return false;
+ if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_VEHICLES_OVERLAP], line, ignoreSeeThrough))
+ return false;
+ }
+
+ if(checkPeds){
+ if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_PEDS], line, ignoreSeeThrough))
+ return false;
+ if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_PEDS_OVERLAP], line, ignoreSeeThrough))
+ return false;
+ }
+
+ if(checkObjects){
+ if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_OBJECTS], line, ignoreSeeThrough, ignoreSomeObjects))
+ return false;
+ if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_OBJECTS_OVERLAP], line, ignoreSeeThrough, ignoreSomeObjects))
+ return false;
+ }
+
+ if(checkDummies){
+ if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_DUMMIES], line, ignoreSeeThrough))
+ return false;
+ if(!GetIsLineOfSightSectorListClear(sector.m_lists[ENTITYLIST_DUMMIES_OVERLAP], line, ignoreSeeThrough))
+ return false;
+ }
+
+ return true;
+}
+
+bool
+CWorld::GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bool ignoreSeeThrough, bool ignoreSomeObjects)
+{
+ CPtrNode *node;
+ CEntity *e;
+ CColModel *colmodel;
+
+ for(node = list.first; node; node = node->next){
+ e = (CEntity*)node->item;
+ if(e->m_scanCode != GetCurrentScanCode() &&
+ e->bUsesCollision){
+
+ e->m_scanCode = GetCurrentScanCode();
+
+ if(e != pIgnoreEntity &&
+ !(ignoreSomeObjects && CameraToIgnoreThisObject(e))){
+
+ colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
+
+ if(CCollision::TestLineOfSight(line, e->GetMatrix(), *colmodel, ignoreSeeThrough))
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+float
+CWorld::FindGroundZForCoord(float x, float y)
+{
+ CColPoint point;
+ CEntity *ent;
+ if(ProcessVerticalLine(CVector(x, y, 1000.0f), -1000.0f, point, ent, true, false, false, false, true, false, nil))
+ return point.point.z;
+ else
+ return 20.0f;
+}
+
+float
+CWorld::FindGroundZFor3DCoord(float x, float y, float z, bool *found)
+{
+ CColPoint point;
+ CEntity *ent;
+ if(ProcessVerticalLine(CVector(x, y, z), -1000.0f, point, ent, true, false, false, false, false, false, nil)){
+ if(found)
+ *found = true;
+ return point.point.z;
+ }else{
+ if(found)
+ *found = false;
+ return 0.0f;
+ }
+}
+
+float
+CWorld::FindRoofZFor3DCoord(float x, float y, float z, bool *found)
+{
+ CColPoint point;
+ CEntity *ent;
+ if(ProcessVerticalLine(CVector(x, y, z), 1000.0f, point, ent, true, false, false, false, true, false, nil)){
+ if(found)
+ *found = true;
+ return point.point.z;
+ }else{
+ if(found == nil)
+ printf("THERE IS NO MAP BELOW THE FOLLOWING COORS:%f %f %f. (FindGroundZFor3DCoord)\n", x, y, z);
+ if(found)
+ *found = false;
+ return 20.0f;
+ }
+}
+
STARTPATCHES
InjectHook(0x4B1F60, CWorld::ClearScanCodes, PATCH_JUMP);
+ InjectHook(0x4AF970, CWorld::ProcessLineOfSight, PATCH_JUMP);
+ InjectHook(0x4B0A80, CWorld::ProcessLineOfSightSector, PATCH_JUMP);
+ InjectHook(0x4B0C70, CWorld::ProcessLineOfSightSectorList, PATCH_JUMP);
+ InjectHook(0x4B0DE0, CWorld::ProcessVerticalLine, PATCH_JUMP);
+ InjectHook(0x4B0EF0, CWorld::ProcessVerticalLineSector, PATCH_JUMP);
+ InjectHook(0x4B1090, CWorld::ProcessVerticalLineSectorList, PATCH_JUMP);
+ InjectHook(0x4AEAA0, CWorld::GetIsLineOfSightClear, PATCH_JUMP);
+ InjectHook(0x4B2000, CWorld::GetIsLineOfSightSectorClear, PATCH_JUMP);
+ InjectHook(0x4B2160, CWorld::GetIsLineOfSightSectorListClear, PATCH_JUMP);
+
+ InjectHook(0x4B3A80, CWorld::FindGroundZForCoord, PATCH_JUMP);
+ InjectHook(0x4B3AE0, CWorld::FindGroundZFor3DCoord, PATCH_JUMP);
+ InjectHook(0x4B3B50, CWorld::FindRoofZFor3DCoord, PATCH_JUMP);
ENDPATCHES
WRAPPER CVector &FindPlayerCoors(CVector &v) { EAXJMP(0x4A1030); }
diff --git a/src/World.h b/src/World.h
index 309f407c..45287989 100644
--- a/src/World.h
+++ b/src/World.h
@@ -33,6 +33,9 @@ public:
static_assert(sizeof(CSector) == 0x28, "CSector: error");
class CEntity;
+struct CColPoint;
+struct CColLine;
+struct CStoredCollPoly;
class CWorld
{
@@ -43,6 +46,7 @@ class CWorld
public:
static CEntity *&pIgnoreEntity;
+ static bool &bIncludeDeadPeds;
static bool &bNoMoreCollisionTorque;
static bool &bSecondShift;
static bool &bForceProcessControl;
@@ -61,10 +65,28 @@ public:
}
static void ClearScanCodes(void);
+ static bool CameraToIgnoreThisObject(CEntity *ent);
+
+ static bool ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects = false);
+ static bool ProcessLineOfSightSector(CSector &sector, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects = false);
+ static bool ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool ignoreSeeThrough, bool ignoreSomeObjects = false);
+ static bool ProcessVerticalLine(const CVector &point1, float z2, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, CStoredCollPoly *poly);
+ static bool ProcessVerticalLineSector(CSector &sector, const CColLine &line, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, CStoredCollPoly *poly);
+ static bool ProcessVerticalLineSectorList(CPtrList &list, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool ignoreSeeThrough, CStoredCollPoly *poly);
+ static bool GetIsLineOfSightClear(const CVector &point1, const CVector &point2, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects = false);
+ static bool GetIsLineOfSightSectorClear(CSector &sector, const CColLine &line, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects = false);
+ static bool GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bool ignoreSeeThrough, bool ignoreSomeObjects = false);
+
+ static float FindGroundZForCoord(float x, float y);
+ static float FindGroundZFor3DCoord(float x, float y, float z, bool *found);
+ static float FindRoofZFor3DCoord(float x, float y, float z, bool *found);
+
static float GetSectorX(float f) { return ((f + 2000.0f)/40.0f); }
static float GetSectorY(float f) { return ((f + 2000.0f)/40.0f); }
static int GetSectorIndexX(float f) { return (int)GetSectorX(f); }
static int GetSectorIndexY(float f) { return (int)GetSectorY(f); }
+ static float GetWorldX(int x) { return x*40.0f - 2000.0f; }
+ static float GetWorldY(int y) { return y*40.0f - 2000.0f; }
};
CVector &FindPlayerCoors(CVector &v);
diff --git a/src/entities/Object.h b/src/entities/Object.h
index e0b8dd91..d71b155e 100644
--- a/src/entities/Object.h
+++ b/src/entities/Object.h
@@ -16,7 +16,6 @@ public:
CMatrix m_objectMatrix;
float m_fUprootLimit;
int8 ObjectCreatedBy;
-// int8 m_nObjectFlags;
int8 m_obj_flag1 : 1;
int8 m_obj_flag2 : 1;
int8 m_obj_flag4 : 1;
diff --git a/src/entities/Ped.cpp b/src/entities/Ped.cpp
index 2d97545e..0d83ed97 100644
--- a/src/entities/Ped.cpp
+++ b/src/entities/Ped.cpp
@@ -7,3 +7,167 @@
//void CPed::operator delete(void *p, size_t sz) { CPools::GetPedPool()->Delete((CPed*)p); }
WRAPPER void CPed::KillPedWithCar(CVehicle *veh, float impulse) { EAXJMP(0x4EC430); }
+
+static char ObjectiveText[34][28] = {
+ "No Obj",
+ "Wait on Foot",
+ "Flee on Foot Till Safe",
+ "Guard Spot",
+ "Guard Area",
+ "Wait in Car",
+ "Wait in Car then Getout",
+ "Kill Char on Foot",
+ "Kill Char Any Means",
+ "Flee Char on Foot Till Safe",
+ "Flee Char on Foot Always",
+ "GoTo Char on Foot",
+ "Follow Char in Formation",
+ "Leave Car",
+ "Enter Car as Passenger",
+ "Enter Car as Driver",
+ "Follow Car in Car",
+ "Fire at Obj from Vehicle",
+ "Destroy Obj",
+ "Destroy Car",
+ "GoTo Area Any Means",
+ "GoTo Area on Foot",
+ "Run to Area",
+ "GoTo Area in Car",
+ "Follow Car on Foot Woffset",
+ "Guard Attack",
+ "Set Leader",
+ "Follow Route",
+ "Solicit",
+ "Take Taxi",
+ "Catch Train",
+ "Buy IceCream",
+ "Steal Any Car",
+ "Mug Char",
+};
+
+static char StateText[56][18] = {
+ "None", // 1
+ "Idle",
+ "Look Entity",
+ "Look Heading",
+ "Wander Range",
+ "Wander Path",
+ "Seek Pos",
+ "Seek Entity",
+ "Flee Pos",
+ "Flee Entity",
+ "Pursue",
+ "Follow Path",
+ "Sniper Mode",
+ "Rocket Mode",
+ "Dummy",
+ "Pause",
+ "Attack",
+ "Fight",
+ "Face Phone",
+ "Make Call",
+ "Chat",
+ "Mug",
+ "AimGun",
+ "AI Control",
+ "Seek Car",
+ "Seek InBoat",
+ "Follow Route",
+ "C.P.R.",
+ "Solicit",
+ "Buy IceCream",
+ "Investigate",
+ "Step away",
+ "STATES_NO_AI",
+ "On Fire",
+ "Jump",
+ "Fall",
+ "GetUp",
+ "Stagger",
+ "Dive away",
+ "STATES_NO_ST",
+ "Enter Train",
+ "Exit Train",
+ "Arrest Plyr",
+ "Driving",
+ "Passenger",
+ "Taxi Passngr",
+ "Open Door",
+ "Die",
+ "Dead",
+ "CarJack",
+ "Drag fm Car",
+ "Enter Car",
+ "Steal Car",
+ "Exit Car",
+ "Hands Up",
+ "Arrested",
+};
+
+static char PersonalityTypeText[32][18] = {
+ "Player",
+ "Cop",
+ "Medic",
+ "Fireman",
+ "Gang 1",
+ "Gang 2",
+ "Gang 3",
+ "Gang 4",
+ "Gang 5",
+ "Gang 6",
+ "Gang 7",
+ "Street Guy",
+ "Suit Guy",
+ "Sensible Guy",
+ "Geek Guy",
+ "Old Guy",
+ "Tough Guy",
+ "Street Girl",
+ "Suit Girl",
+ "Sensible Girl",
+ "Geek Girl",
+ "Old Girl",
+ "Tough Girl",
+ "Tramp",
+ "Tourist",
+ "Prostitute",
+ "Criminal",
+ "Busker",
+ "Taxi Driver",
+ "Psycho",
+ "Steward",
+ "Sports Fan",
+};
+
+static char WaitStateText[21][16] = {
+ "No Wait",
+ "Traffic Lights",
+ "Pause CrossRoad",
+ "Look CrossRoad",
+ "Look Ped",
+ "Look Shop",
+ "Look Accident",
+ "FaceOff Gang",
+ "Double Back",
+ "Hit Wall",
+ "Turn 180deg",
+ "Surprised",
+ "Ped Stuck",
+ "Look About",
+ "Play Duck",
+ "Play Cower",
+ "Play Taxi",
+ "Play HandsUp",
+ "Play HandsCower",
+ "Play Chat",
+ "Finish Flee",
+};
+
+bool
+CPed::UseGroundColModel(void)
+{
+ return m_nPedState == PED_FALL ||
+ m_nPedState == PED_DIVE_AWAY ||
+ m_nPedState == PED_DIE ||
+ m_nPedState == PED_DEAD;
+}
diff --git a/src/entities/Ped.h b/src/entities/Ped.h
index 4236340e..c5ad863d 100644
--- a/src/entities/Ped.h
+++ b/src/entities/Ped.h
@@ -2,9 +2,65 @@
#include "Physical.h"
-enum PedAction
+enum PedState
{
- PED_PASSENGER = 44,
+ // This is a bit strange...shouldn't PED_NONE be 0?
+ PED_NONE = 1,
+ PED_IDLE,
+ PED_LOOK_ENTITY,
+ PED_LOOK_HEADING,
+ PED_WANDER_RANGE,
+ PED_WANDER_PATH,
+ PED_SEEK_POS,
+ PED_SEEK_ENTITY,
+ PED_FLEE_POS,
+ PED_FLEE_ENTITY,
+ PED_PURSUE,
+ PED_FOLLOW_PATH,
+ PED_SNIPER_MODE,
+ PED_ROCKET_ODE,
+ PED_DUMMY,
+ PED_PAUSE,
+ PED_ATTACK,
+ PED_FIGHT,
+ PED_FACE_PHONE,
+ PED_MAKE_CALL,
+ PED_CHAT,
+ PED_MUG,
+ PED_AIM_GUN,
+ PED_AI_CONTROL,
+ PED_SEEK_CAR,
+ PED_SEEK_IN_BOAT,
+ PED_FOLLOW_ROUTE,
+ PED_CPR,
+ PED_SOLICIT,
+ PED_BUY_ICECREAM,
+ PED_INVESTIGATE,
+ PED_STEP_AWAY,
+ PED_STATES_NO_AI,
+ PED_ON_FIRE,
+ PED_JUMP,
+ PED_FALL,
+ PED_GETUP,
+ PED_STAGGER,
+ PED_DIVE_AWAY,
+ PED_STATES_NO_ST,
+ PED_ENTER_TRAIN,
+ PED_EXIT_TRAIN,
+ PED_ARREST_PLAYER,
+ PED_DRIVING,
+ PED_PASSENGER,
+ PED_TAXI_PASSENGER,
+ PED_OPEN_DOOR,
+ PED_DIE,
+ PED_DEAD,
+ PED_CARJACK,
+ PED_DRAG_FROM_CAR,
+ PED_ENTER_CAR,
+ PED_STEAL_CAR,
+ PED_EXIT_CAR,
+ PED_HANDS_UP,
+ PED_ARRESTED,
};
class CVehicle;
@@ -107,6 +163,7 @@ public:
// static void operator delete(void*, size_t);
bool IsPlayer(void) { return m_nPedType == 0 || m_nPedType== 1 || m_nPedType == 2 || m_nPedType == 3; }
+ bool UseGroundColModel(void);
void KillPedWithCar(CVehicle *veh, float impulse);
};
static_assert(offsetof(CPed, m_nPedState) == 0x224, "CPed: error");
diff --git a/src/entities/Physical.h b/src/entities/Physical.h
index 06ae3166..514994f7 100644
--- a/src/entities/Physical.h
+++ b/src/entities/Physical.h
@@ -58,18 +58,9 @@ public:
uint8 m_phy_flagA40 : 1;
uint8 m_phy_flagA80 : 1;
- uint8 m_phy_flagB1 : 1;
- uint8 m_phy_flagB2 : 1;
- uint8 m_phy_flagB4 : 1;
- uint8 m_phy_flagB8 : 1;
- uint8 m_phy_flagB10 : 1;
- uint8 m_phy_flagB20 : 1;
- uint8 m_phy_flagB40 : 1;
- uint8 m_phy_flagB80 : 1;
-
- char byteLastCollType;
- char byteZoneLevel;
- int16 pad;
+ uint8 m_nLastCollType;
+ uint8 m_nZoneLevel;
+ uint8 pad[3];
// from CEntity
diff --git a/src/main.cpp b/src/main.cpp
index b7d1d151..4f125098 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -59,6 +59,8 @@ open_script(const char *path, const char *mode)
return open_script_orig(path, mode);
}
+int gDbgSurf;
+
int (*RsEventHandler_orig)(int a, int b);
int
delayedPatches10(int a, int b)
@@ -71,6 +73,7 @@ delayedPatches10(int a, int b)
DebugMenuAddVarBool8("Debug", "Don't render Big Buildings", (int8*)&gbDontRenderBigBuildings, nil);
DebugMenuAddVarBool8("Debug", "Don't render Peds", (int8*)&gbDontRenderPeds, nil);
DebugMenuAddVarBool8("Debug", "Don't render Objects", (int8*)&gbDontRenderObjects, nil);
+ DebugMenuAddVar("Debug", "Dbg Surface", &gDbgSurf, nil, 1, 0, 34, nil);
}
return RsEventHandler_orig(a, b);
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index 5dc5959a..f8703c01 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -93,7 +93,7 @@ CRenderer::RenderOneNonRoad(CEntity *e)
return;
#endif
ped = (CPed*)e;
- if(ped->m_nPedState == PED_PASSENGER)
+ if(ped->m_nPedState == PED_DRIVING)
return;
}
#ifndef MASTER
@@ -111,10 +111,10 @@ CRenderer::RenderOneNonRoad(CEntity *e)
// Render Peds in vehicle before vehicle itself
if(e->IsVehicle()){
veh = (CVehicle*)e;
- if(veh->pDriver && veh->pDriver->m_nPedState == PED_PASSENGER)
+ if(veh->pDriver && veh->pDriver->m_nPedState == PED_DRIVING)
veh->pDriver->Render();
for(i = 0; i < 8; i++)
- if(veh->pPassengers[i] && veh->pPassengers[i]->m_nPedState == PED_PASSENGER)
+ if(veh->pPassengers[i] && veh->pPassengers[i]->m_nPedState == PED_DRIVING)
veh->pPassengers[i]->Render();
}
e->Render();