From 702da55ec9d0e8e02df25a26390a113e452676e3 Mon Sep 17 00:00:00 2001 From: aap Date: Sun, 3 May 2020 15:57:57 +0200 Subject: implemented most of vice city path system --- src/control/PathFind.h | 194 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 166 insertions(+), 28 deletions(-) (limited to 'src/control/PathFind.h') diff --git a/src/control/PathFind.h b/src/control/PathFind.h index 64c12d5b..a4bb02a2 100644 --- a/src/control/PathFind.h +++ b/src/control/PathFind.h @@ -55,6 +55,7 @@ public: struct CPathNode { +#ifndef MIAMI CVector pos; CPathNode *prev; CPathNode *next; @@ -69,31 +70,55 @@ struct CPathNode uint8 bBetweenLevels : 1; int8 group; -/* For reference VC: + + CVector &GetPosition(void) { return pos; } + void SetPosition(const CVector &p) { pos = p; } + float GetX(void) { return pos.x; } + float GetY(void) { return pos.y; } + float GetZ(void) { return pos.z; } + + CPathNode *GetPrev(void) { return prev; } + CPathNode *GetNext(void) { return next; } + void SetPrev(CPathNode *node) { prev = node; } + void SetNext(CPathNode *node) { next = node; } +#else int16 prevIndex; int16 nextIndex; int16 x; int16 y; int16 z; - int16 distance; + int16 distance; // in path search int16 firstLink; int8 width; int8 group; - int8 numLinks : 4; - int8 bDeadEnd : 1; - int8 bTurnedOff : 1; // flag 8 in node info - int8 flagA40 : 1; // flag 20 in node info - int8 flagA80 : 1; // flag 4 in node info - int8 flagB1 : 1; // flag 10 in node info - int8 flagB2 : 1; // flag 2 in node info - int8 flagB4 : 1; - int8 speedLimit : 2; // speed limit - int8 flagB20 : 1; - int8 flagB40 : 1; - int8 flagB80 : 1; - int8 spawnRate : 4; - int8 flagsC : 4; -*/ + + uint8 numLinks : 4; + uint8 bDeadEnd : 1; + uint8 bDisabled : 1; + uint8 bBetweenLevels : 1; + uint8 bUseInRoadBlock : 1; + + uint8 bWaterPath : 1; + uint8 flagB2 : 1; // flag 2 in node info, always zero + uint8 flagB4 : 1; // where is this set? + uint8 speedLimit : 2; + //uint8 flagB20 : 1; + //uint8 flagB40 : 1; + //uint8 flagB80 : 1; + + uint8 spawnRate : 4; + uint8 flagsC : 4; + + CVector GetPosition(void) { return CVector(x/8.0f, y/8.0f, z/8.0f); } + void SetPosition(const CVector &p) { x = p.x*8.0f; y = p.y*8.0f; z = p.z*8.0f; } + float GetX(void) { return x/8.0f; } + float GetY(void) { return y/8.0f; } + float GetZ(void) { return z/8.0f; } + CPathNode *GetPrev(void); + CPathNode *GetNext(void); + void SetPrev(CPathNode *node); + void SetNext(CPathNode *node); +#endif }; union CConnectionFlags @@ -107,6 +132,7 @@ union CConnectionFlags struct CCarPathLink { +#ifndef MIAMI CVector2D pos; CVector2D dir; int16 pathNodeIndex; @@ -117,6 +143,33 @@ struct CCarPathLink uint8 bBridgeLights : 1; // more? + CVector2D &GetPosition(void) { return pos; } + CVector2D &GetDirection(void) { return dir; } + float GetX(void) { return pos.x; } + float GetY(void) { return pos.y; } + float GetDirX(void) { return dir.x; } + float GetDirY(void) { return dir.y; } +#else + int16 x; + int16 y; + int16 pathNodeIndex; + int8 dirX; + int8 dirY; + int8 numLeftLanes : 3; + int8 numRightLanes : 3; + uint8 flag1 : 1; + uint8 trafficLightType : 2; + uint8 bBridgeLights : 1; // at least in LCS... + int8 width; + + CVector2D GetPosition(void) { return CVector2D(x/8.0f, y/8.0f); } + CVector2D GetDirection(void) { return CVector2D(dirX/100.0f, dirY/100.0f); } + float GetX(void) { return x/8.0f; } + float GetY(void) { return y/8.0f; } + float GetDirX(void) { return dirX/100.0f; } + float GetDirY(void) { return dirY/100.0f; } +#endif + float OneWayLaneOffset() { if (numLeftLanes == 0) @@ -127,8 +180,10 @@ struct CCarPathLink } }; +// This is what we're reading from the files, only temporary struct CPathInfoForObject { +#ifndef MIAMI int16 x; int16 y; int16 z; @@ -137,6 +192,28 @@ struct CPathInfoForObject int8 numLeftLanes; int8 numRightLanes; uint8 crossing : 1; +#else + float x; + float y; + float z; + int8 type; + int8 next; + int8 numLeftLanes; + int8 numRightLanes; + int8 speedLimit; + int8 width; + + uint8 crossing : 1; + uint8 flag02 : 1; // always zero + uint8 roadBlock : 1; + uint8 disabled : 1; + uint8 waterPath : 1; + uint8 betweenLevels : 1; + + uint8 spawnRate : 4; + + void SwapConnectionsToBeRightWayRound(void); +#endif }; extern CPathInfoForObject *InfoForTileCars; extern CPathInfoForObject *InfoForTilePeds; @@ -144,6 +221,7 @@ extern CPathInfoForObject *InfoForTilePeds; struct CTempNode { CVector pos; +#ifndef MIAMI float dirX; float dirY; int16 link1; @@ -151,34 +229,55 @@ struct CTempNode int8 numLeftLanes; int8 numRightLanes; int8 linkState; +#else + int8 dirX; // *100 + int8 dirY; + int16 link1; + int16 link2; + int8 numLeftLanes; + int8 numRightLanes; + int8 width; + bool isCross; + int8 linkState; +#endif }; +#ifdef MIAMI +struct CTempNodeExternal // made up name +{ + CVector pos; + int16 next; + int8 numLeftLanes; + int8 numRightLanes; + int8 width; + bool isCross; +}; +#endif + +#ifndef MIAMI struct CTempDetachedNode // unused { uint8 foo[20]; }; +#endif class CPathFind { public: -/* For reference VC: - CPathNode pathNodes[9650]; - CCarPathLink m_carPathLinks[3500]; - CBuilding *m_mapObjects[1250]; - // 0x8000 is cross road flag - // 0x4000 is traffic light flag - uint16 m_connections[20400]; - uint8 m_distances[20400]; - int16 m_carPathConnections[20400]; -*/ CPathNode m_pathNodes[NUM_PATHNODES]; CCarPathLink m_carPathLinks[NUM_CARPATHLINKS]; CTreadable *m_mapObjects[NUM_MAPOBJECTS]; +#ifndef MIAMI uint8 m_objectFlags[NUM_MAPOBJECTS]; int16 m_connections[NUM_PATHCONNECTIONS]; int16 m_distances[NUM_PATHCONNECTIONS]; CConnectionFlags m_connectionFlags[NUM_PATHCONNECTIONS]; +#else + uint16 m_connections[NUM_PATHCONNECTIONS]; // and flags + uint8 m_distances[NUM_PATHCONNECTIONS]; +#endif int16 m_carPathConnections[NUM_PATHCONNECTIONS]; + int32 m_numPathNodes; int32 m_numCarPathNodes; int32 m_numPedPathNodes; @@ -194,12 +293,20 @@ public: void RegisterMapObject(CTreadable *mapObject); void StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, bool crossing); void StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, int8 numLeft, int8 numRight); +#ifndef MIAMI void CalcNodeCoors(int16 x, int16 y, int16 z, int32 id, CVector *out); +#else + void CalcNodeCoors(float x, float y, float z, int32 id, CVector *out); +#endif bool LoadPathFindData(void); void PreparePathData(void); void CountFloodFillGroups(uint8 type); void PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoForObject *objectpathinfo, - float unk, CTempDetachedNode *detachednodes, int unused); +#ifndef MIAMI + float maxdist, CTempDetachedNode *detachednodes, int32 numDetached); +#else + float maxdist, CPathInfoForObject *detachednodes, int32 numDetached); +#endif bool IsPathObject(int id) { return id < PATHNODESIZE && (InfoForTileCars[id*12].type != 0 || InfoForTilePeds[id*12].type != 0); } @@ -217,25 +324,56 @@ public: void MarkRoadsBetweenLevelsNodeAndNeighbours(int32 nodeId); void MarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2, float z1, float z2); void PedMarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2, float z1, float z2); +#ifndef MIAMI int32 FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled = false, bool ignoreBetweenLevels = false); +#else +//--MIAMI: TODO: check callers for new arguments + int32 FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled = false, bool ignoreBetweenLevels = false, bool ignoreFlagB4 = false, bool bWaterPath = false); +#endif int32 FindNodeClosestToCoorsFavourDirection(CVector coors, uint8 type, float dirX, float dirY); float FindNodeOrientationForCarPlacement(int32 nodeId); float FindNodeOrientationForCarPlacementFacingDestination(int32 nodeId, float x, float y, bool towards); bool NewGenerateCarCreationCoors(float x, float y, float dirX, float dirY, float spawnDist, float angleLimit, bool forward, CVector *pPosition, int32 *pNode1, int32 *pNode2, float *pPositionBetweenNodes, bool ignoreDisabled = false); bool GeneratePedCreationCoors(float x, float y, float minDist, float maxDist, float minDistOffScreen, float maxDistOffScreen, CVector *pPosition, int32 *pNode1, int32 *pNode2, float *pPositionBetweenNodes, CMatrix *camMatrix); +#ifndef MIAMI CTreadable *FindRoadObjectClosestToCoors(CVector coors, uint8 type); +#endif void FindNextNodeWandering(uint8, CVector, CPathNode**, CPathNode**, uint8, uint8*); void DoPathSearch(uint8 type, CVector start, int32 startNodeId, CVector target, CPathNode **nodes, int16 *numNodes, int16 maxNumNodes, CVehicle *vehicle, float *dist, float distLimit, int32 forcedTargetNode); bool TestCoorsCloseness(CVector target, uint8 type, CVector start); void Save(uint8 *buf, uint32 *size); void Load(uint8 *buf, uint32 size); +#ifdef MIAMI + CPathNode *GetNode(int16 index); + int16 GetIndex(CPathNode *node); + + uint16 ConnectedNode(int id) { return m_connections[id] & 0x3FFF; } + bool ConnectionCrossesRoad(int id) { return !!(m_connections[id] & 0x8000); } + bool ConnectionHasTrafficLight(int id) { return !!(m_connections[id] & 0x4000); } + void ConnectionSetTrafficLight(int id) { m_connections[id] |= 0x4000; } +#else + uint16 ConnectedNode(int id) { return m_connections[id]; } + bool ConnectionCrossesRoad(int id) { return m_connectionFlags[id].bCrossesRoad; } + bool ConnectionHasTrafficLight(int id) { return m_connectionFlags[id].bTrafficLight; } + void ConnectionSetTrafficLight(int id) { m_connectionFlags[id].bTrafficLight = true; } +#endif + void DisplayPathData(void); }; +#ifndef MIAMI static_assert(sizeof(CPathFind) == 0x49bf4, "CPathFind: error"); +#endif extern CPathFind ThePaths; +#ifdef MIAMI +inline CPathNode *CPathNode::GetPrev(void) { return ThePaths.GetNode(prevIndex); } +inline CPathNode *CPathNode::GetNext(void) { return ThePaths.GetNode(nextIndex); } +inline void CPathNode::SetPrev(CPathNode *node) { prevIndex = ThePaths.GetIndex(node); } +inline void CPathNode::SetNext(CPathNode *node) { nextIndex = ThePaths.GetIndex(node); } +#endif + extern bool gbShowPedPaths; extern bool gbShowCarPaths; extern bool gbShowCarPathsLinks; -- cgit v1.2.3