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 §or, 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 §or, 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 §or, 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 §or, 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 §or, 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 §or, 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();