summaryrefslogtreecommitdiff
path: root/src/control/PathFind.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/control/PathFind.h')
-rw-r--r--src/control/PathFind.h304
1 files changed, 304 insertions, 0 deletions
diff --git a/src/control/PathFind.h b/src/control/PathFind.h
new file mode 100644
index 0000000..9975959
--- /dev/null
+++ b/src/control/PathFind.h
@@ -0,0 +1,304 @@
+#pragma once
+
+#include "Treadable.h"
+
+class CVehicle;
+class CPtrList;
+
+#define LANE_WIDTH 5.0f
+#define WIDTH_TO_PED_NODE_WIDTH (31.f/(500.f * 8.f))
+
+enum
+{
+ NodeTypeExtern = 1,
+ NodeTypeIntern = 2,
+};
+
+enum
+{
+ PATH_CAR = 0,
+ PATH_PED = 1,
+};
+
+enum
+{
+ SWITCH_OFF = 0,
+ SWITCH_ON = 1,
+};
+
+enum
+{
+ ROUTE_ADD_BLOCKADE = 0,
+ ROUTE_NO_BLOCKADE = 1
+};
+
+struct CPedPathNode
+{
+ bool bBlockade;
+ uint8 nodeIdX;
+ uint8 nodeIdY;
+ int16 id;
+ CPedPathNode* prev;
+ CPedPathNode* next;
+};
+
+VALIDATE_SIZE(CPedPathNode, 0x10);
+
+class CPedPath {
+public:
+ static bool CalcPedRoute(int8 pathType, CVector position, CVector destination, CVector *pointPoses, int16 *pointsFound, int16 maxPoints);
+ static void AddNodeToPathList(CPedPathNode *pNodeToAdd, int16 id, CPedPathNode *pNodeList);
+ static void RemoveNodeFromList(CPedPathNode *pNode);
+ static void AddNodeToList(CPedPathNode *pNode, int16 index, CPedPathNode *pList);
+ static void AddBlockade(CEntity *pEntity, CPedPathNode(*pathNodes)[40], CVector *pPosition);
+ static void AddBlockadeSectorList(CPtrList& list, CPedPathNode(*pathNodes)[40], CVector *pPosition);
+ static void AddBuildingBlockade(CEntity*, CPedPathNode(*)[40], CVector*);
+ static void AddBuildingBlockadeSectorList(CPtrList&, CPedPathNode(*)[40], CVector*);
+};
+
+struct CPathNode
+{
+ int16 prevIndex;
+ int16 nextIndex;
+ int16 x;
+ int16 y;
+ int16 z;
+ int16 distance; // in path search
+ int16 firstLink;
+ uint8 width;
+ int8 group;
+
+ uint8 numLinks : 4;
+ uint8 bDeadEnd : 1;
+ uint8 bDisabled : 1;
+ uint8 bBetweenLevels : 1;
+ uint8 bUseInRoadBlock : 1;
+
+ uint8 bWaterPath : 1;
+ uint8 bOnlySmallBoats : 1;
+ uint8 bSelected : 1;
+ 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; }
+ bool HasDivider(void) { return width != 0; }
+ float GetDividerWidth(void) { return width/(2*8.0f); }
+ float GetPedNodeWidth(void) { return width*WIDTH_TO_PED_NODE_WIDTH; }
+ CPathNode *GetPrev(void);
+ CPathNode *GetNext(void);
+ void SetPrev(CPathNode *node);
+ void SetNext(CPathNode *node);
+};
+
+union CConnectionFlags
+{
+ uint8 flags;
+ struct {
+ uint8 bCrossesRoad : 1;
+ uint8 bTrafficLight : 1;
+ };
+};
+
+struct CCarPathLink
+{
+ int16 x;
+ int16 y;
+ int16 pathNodeIndex;
+ int8 dirX;
+ int8 dirY;
+ int8 numLeftLanes : 3;
+ int8 numRightLanes : 3;
+ uint8 trafficLightDirection : 1;
+ uint8 trafficLightType : 2;
+ uint8 bBridgeLights : 1; // at least in LCS...
+ uint8 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; }
+ float GetLaneOffset(void) { return width/(2*8.0f*LANE_WIDTH); }
+
+ float OneWayLaneOffset()
+ {
+ if (numLeftLanes == 0)
+ return 0.5f - 0.5f * numRightLanes;
+ if (numRightLanes == 0)
+ return 0.5f - 0.5f * numLeftLanes;
+ return 0.5f + GetLaneOffset();
+ }
+};
+
+// This is what we're reading from the files, only temporary
+struct CPathInfoForObject
+{
+ float x;
+ float y;
+ float z;
+ int8 type;
+ int8 next;
+ int8 numLeftLanes;
+ int8 numRightLanes;
+ int8 speedLimit;
+ uint8 width;
+
+ uint8 crossing : 1;
+ uint8 onlySmallBoats : 1;
+ uint8 roadBlock : 1;
+ uint8 disabled : 1;
+ uint8 waterPath : 1;
+ uint8 betweenLevels : 1;
+
+ uint8 spawnRate : 4;
+
+ void CheckIntegrity(void);
+ void SwapConnectionsToBeRightWayRound(void);
+};
+extern CPathInfoForObject *InfoForTileCars;
+extern CPathInfoForObject *InfoForTilePeds;
+
+struct CTempNode
+{
+ CVector pos;
+ int8 dirX; // *100
+ int8 dirY;
+ int16 link1;
+ int16 link2;
+ int8 numLeftLanes;
+ int8 numRightLanes;
+ uint8 width;
+ bool isCross;
+ int8 linkState;
+};
+
+struct CTempNodeExternal // made up name
+{
+ CVector pos;
+ int16 next;
+ int8 numLeftLanes;
+ int8 numRightLanes;
+ uint8 width;
+ bool isCross;
+};
+
+// from mobile
+template<typename T>
+class CRoute
+{
+ T m_node[8];
+};
+
+
+class CPathFind
+{
+public:
+ CPathNode m_pathNodes[NUM_PATHNODES];
+ CCarPathLink m_carPathLinks[NUM_CARPATHLINKS];
+ CTreadable *m_mapObjects[NUM_MAPOBJECTS];
+ uint16 m_connections[NUM_PATHCONNECTIONS]; // and flags
+ uint8 m_distances[NUM_PATHCONNECTIONS];
+ int16 m_carPathConnections[NUM_PATHCONNECTIONS];
+
+ int32 m_numPathNodes;
+ int32 m_numCarPathNodes;
+ int32 m_numPedPathNodes;
+ int16 m_numMapObjects;
+ int16 m_numConnections;
+ int32 m_numCarPathLinks;
+ int32 unk;
+ uint8 m_numGroups[2];
+ CPathNode m_searchNodes[512];
+
+ void Init(void);
+ void AllocatePathFindInfoMem(int16 numPathGroups);
+ void RegisterMapObject(CTreadable *mapObject);
+ void StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, float width, bool crossing, uint8 spawnRate);
+ void StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, float width, int8 numLeft, int8 numRight,
+ bool disabled, bool betweenLevels, uint8 speedLimit, bool roadBlock, bool waterPath, uint8 spawnRate);
+ void StoreDetachedNodeInfoPed(int32 node, int8 type, int32 next, float x, float y, float z, float width, bool crossing,
+ bool disabled, bool betweenLevels, uint8 spawnRate);
+ void StoreDetachedNodeInfoCar(int32 node, int8 type, int32 next, float x, float y, float z, float width, int8 numLeft, int8 numRight,
+ bool disabled, bool betweenLevels, uint8 speedLimit, bool roadBlock, bool waterPath, uint8 spawnRate, bool unk);
+ void CalcNodeCoors(float x, float y, float z, int32 id, CVector *out);
+ bool LoadPathFindData(void);
+ void PreparePathData(void);
+ void CountFloodFillGroups(uint8 type);
+ void PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoForObject *objectpathinfo,
+ float maxdist, CPathInfoForObject *detachednodes, int32 numDetached);
+
+ bool IsPathObject(int id) { return id < PATHNODESIZE && (InfoForTileCars[id*12].type != 0 || InfoForTilePeds[id*12].type != 0); }
+
+ float CalcRoadDensity(float x, float y);
+ bool TestForPedTrafficLight(CPathNode *n1, CPathNode *n2);
+ bool TestCrossesRoad(CPathNode *n1, CPathNode *n2);
+ void AddNodeToList(CPathNode *node, int32 listId);
+ void RemoveNodeFromList(CPathNode *node);
+ void RemoveBadStartNode(CVector pos, CPathNode **nodes, int16 *n);
+ void SetLinksBridgeLights(float, float, float, float, bool);
+ void SwitchOffNodeAndNeighbours(int32 nodeId, bool disable);
+ void SwitchRoadsOffInArea(float x1, float x2, float y1, float y2, float z1, float z2, bool disable);
+ void SwitchPedRoadsOffInArea(float x1, float x2, float y1, float y2, float z1, float z2, bool disable);
+ void SwitchRoadsInAngledArea(float x1, float y1, float z1, float x2, float y2, float z2, float length, uint8 type, uint8 enable);
+ 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);
+ int32 FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled = false, bool ignoreBetweenLevels = false, bool ignoreSelected = false, bool bWaterPath = false);
+ int32 FindNodeClosestToCoorsFavourDirection(CVector coors, uint8 type, float dirX, float dirY);
+ void FindNodePairClosestToCoors(CVector coors, uint8 type, int* node1, int* node2, float* angle, float minDist, float maxDist, bool ignoreDisabled = false, bool ignoreBetweenLevels = false, bool bWaterPath = false);
+ int32 FindNthNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled, bool ignoreBetweenLevels, int N, bool bWaterPath = false);
+ CVector FindNodeCoorsForScript(int32 id);
+ float FindNodeOrientationForCarPlacement(int32 nodeId);
+ float FindNodeOrientationForCarPlacementFacingDestination(int32 nodeId, float x, float y, bool towards);
+ bool GenerateCarCreationCoors(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);
+ 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);
+
+ static CVector TakeWidthIntoAccountForWandering(CPathNode*, uint16);
+ static void TakeWidthIntoAccountForCoors(CPathNode*, CPathNode*, uint16, float*, float*);
+
+ 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; }
+
+ void DisplayPathData(void);
+
+ // Following methods are present on mobile but are unused. TODO: implement them
+ void SavePathFindData(void);
+ void ComputeRoute(uint8, const CVector&, const CVector&, CRoute<CPathNode*>&);
+ void RecordNodesClosestToCoors(CVector, uint8, int, CPathNode**, float, bool, bool, bool);
+ void RecordNodesInCircle(const CVector&, float, uint8, int, CPathNode**, bool, bool, bool, bool);
+ void ArrangeOneNodeList(CPathInfoForObject*, int16);
+ void ArrangeNodes(int16);
+ void RegisterMarker(CVector*);
+ void Shutdown(void);
+};
+
+extern CPathFind ThePaths;
+
+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); }
+
+extern bool gbShowPedPaths;
+extern bool gbShowCarPaths;
+extern bool gbShowCarPathsLinks;