/* * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * In addition, as a special exception, the author gives permission to * link the code of this program with the Half-Life Game Engine ("HL * Engine") and Modified Game Libraries ("MODs") developed by Valve, * L.L.C ("Valve"). You must obey the GNU General Public License in all * respects for all of the code used other than the HL Engine and MODs * from Valve. If you modify this file, you may extend this exception * to your version of the file, but you are not obligated to do so. If * you do not wish to do so, delete this exception statement from your * version. * */ #pragma once class CNavNode { public: CNavNode(const Vector *pos, const Vector *normal, CNavNode *parent = nullptr); // return navigation node at the position, or NULL if none exists static const CNavNode *GetNode(const Vector *pos); // get navigation node connected in given direction, or NULL if cant go that way CNavNode *GetConnectedNode(NavDirType dir) const; const Vector *GetPosition() const; const Vector *GetNormal() const { return &m_normal; } unsigned int GetID() const { return m_id; } static CNavNode *GetFirst() { return m_list; } static unsigned int GetListLength() { return m_listLength; } CNavNode *GetNext() { return m_next; } // create a connection FROM this node TO the given node, in the given direction void ConnectTo(CNavNode *node, NavDirType dir); CNavNode *GetParent() const; void MarkAsVisited(NavDirType dir); // mark the given direction as having been visited BOOL HasVisited(NavDirType dir); // return TRUE if the given direction has already been searched BOOL IsBiLinked(NavDirType dir) const; // node is bidirectionally linked to another node in the given direction BOOL IsClosedCell() const; // node is the NW corner of a bi-linked quad of nodes void Cover() { m_isCovered = true; } // TODO: Should pass in area that is covering BOOL IsCovered() const { return m_isCovered; } // return true if this node has been covered by an area void AssignArea(CNavArea *area); // assign the given area to this node CNavArea *GetArea() const; // return associated area void SetAttributes(unsigned char bits) { m_attributeFlags = bits; } unsigned char GetAttributes() const { return m_attributeFlags; } private: friend void DestroyNavigationMap(); Vector m_pos; // position of this node in the world Vector m_normal; // surface normal at this location CNavNode *m_to[NUM_DIRECTIONS]; // links to north, south, east, and west. NULL if no link unsigned int m_id; // unique ID of this node unsigned char m_attributeFlags; // set of attribute bit flags (see NavAttributeType) static CNavNode *m_list; // the master list of all nodes for this map static unsigned int m_listLength; CNavNode *m_next; // next link in master list // below are only needed when generating // flags for automatic node generation. If direction bit is clear, that direction hasn't been explored yet. unsigned char m_visited; CNavNode *m_parent; // the node prior to this in the search, which we pop back to when this node's search is done (a stack) BOOL m_isCovered; // true when this node is "covered" by a CNavArea CNavArea *m_area; // the area this node is contained within }; inline CNavNode *CNavNode::GetConnectedNode(NavDirType dir) const { return m_to[dir]; } inline const Vector *CNavNode::GetPosition() const { return &m_pos; } inline CNavNode *CNavNode::GetParent() const { return m_parent; } inline void CNavNode::MarkAsVisited(NavDirType dir) { m_visited |= (1 << dir); } inline BOOL CNavNode::HasVisited(NavDirType dir) { if (m_visited & (1 << dir)) return true; return false; } inline void CNavNode::AssignArea(CNavArea *area) { m_area = area; } inline CNavArea *CNavNode::GetArea() const { return m_area; }