1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #ifndef RYAI_PATH_BEHAVIOR_H
18 #define RYAI_PATH_BEHAVIOR_H
20 #include "world_container.h"
21 #include "ai_entity_physical.h"
22 #include "ai_entity_physical_inline.h"
23 #include "ai_instance.h"
24 #include "time_interface.h"
25 #include "nel/misc/variable.h"
27 extern NLMISC::CVariable
<bool> LogAcceptablePos
;
29 //////////////////////////////////////////////////////////////////////////////
31 //////////////////////////////////////////////////////////////////////////////
33 class CAIPath
: public NLMISC::CRefCount
37 std::vector
<RYAI_MAP_CRUNCH::CTopology::TTopologyRef
> const& topologiesPath() const { return _TopologiesPath
; }
38 std::vector
<RYAI_MAP_CRUNCH::CTopology::TTopologyRef
>& topologiesPathForCalc() { return _TopologiesPath
; }
40 RYAI_MAP_CRUNCH::CWorldPosition
const& getStartPos() const { return _Start
; }
41 void setStartPos(RYAI_MAP_CRUNCH::CWorldPosition
const& pos
) { _Start
= pos
; }
43 RYAI_MAP_CRUNCH::CWorldPosition
const& getEndPos() const { return _End
; }
44 void setEndPos(RYAI_MAP_CRUNCH::CWorldPosition
const& pos
) { _End
= pos
; }
48 RYAI_MAP_CRUNCH::CWorldPosition _Start
;
49 RYAI_MAP_CRUNCH::CWorldPosition _End
;
50 std::vector
<RYAI_MAP_CRUNCH::CTopology::TTopologyRef
> _TopologiesPath
;
53 //////////////////////////////////////////////////////////////////////////////
55 //////////////////////////////////////////////////////////////////////////////
57 class CInsidePath
: public NLMISC::CRefCount
60 std::vector
<RYAI_MAP_CRUNCH::CDirection
> _DirectionPath
;
63 //////////////////////////////////////////////////////////////////////////////
65 //////////////////////////////////////////////////////////////////////////////
76 FOLLOWING_INSIDE_TOPO
,
81 /// @name Constructor and destructor
83 CPathPosition(CAngle
const& angle
);
84 virtual ~CPathPosition() { } // Defined coz no base class
89 NLMISC::CSmartPtr
<CAIPath
> const& getPath() const { return _Path
; }
90 RYAI_MAP_CRUNCH::CTopology::TTopologyRef
const& getTopology() const;
91 RYAI_MAP_CRUNCH::CTopology::TTopologyRef
const& getNextTopology() const;
94 bool isPathValid() const;
95 bool isFinished() const;
97 bool haveNextTopology(uint nbTopo
= 1);
99 NLMISC::CSmartPtr
<CAIPath
> _Path
;
100 NLMISC::CSmartPtr
<CInsidePath
> _InsidePath
;
101 RYAI_MAP_CRUNCH::CMapPosition _InsideStartPos
;
102 RYAI_MAP_CRUNCH::CMapPosition _InsideDestPos
;
104 TPathPosState _PathState
;
105 uint32 _TimeTopoChanged
;
106 uint32 _TimeDestChanged
;
110 friend class CPathCont
;
114 //////////////////////////////////////////////////////////////////////////////
116 //////////////////////////////////////////////////////////////////////////////
118 class CPathCont
: public NLMISC::CDbgRefCount
<CPathCont
>
121 /// @name Constructors
123 CPathCont(RYAI_MAP_CRUNCH::TAStarFlag denyFlags
);
124 CPathCont(CPathCont
const& pathCont
);
129 RYAI_MAP_CRUNCH::TAStarFlag
const& denyFlags() const { return _denyFlags
; }
130 RYAI_MAP_CRUNCH::TAStarFlag
const& getDenyFlags() const { return _denyFlags
; }
131 void setDenyFlags(RYAI_MAP_CRUNCH::TAStarFlag denyFlags
) { _denyFlags
= denyFlags
; }
133 CAIVector
const& getDestination() const { return _Destination
; }
134 RYAI_MAP_CRUNCH::CWorldPosition
const& getDestPos() const { return _DestPos
; }
135 void setDestination(RYAI_MAP_CRUNCH::CWorldPosition
const& destPos
);
136 void setDestination(AITYPES::TVerticalPos verticalPos
, CAIVector
const& destPos
);
141 bool getPathForSource(CPathPosition
& pathPos
, RYAI_MAP_CRUNCH::CWorldPosition
const& startPos
) const;
142 bool calcPathForSource(CPathPosition
& pathPos
, RYAI_MAP_CRUNCH::CWorldPosition
const& startPos
);
143 bool getCalcPathForSource(CPathPosition
& pathPos
, RYAI_MAP_CRUNCH::CWorldPosition
const& startPos
);
145 uint32 _TimeTopoChanged
;
146 uint32 _TimeDestChanged
;
149 CAIVector _Destination
;
150 RYAI_MAP_CRUNCH::CMapPosition _DestinationMapPos
;
151 AITYPES::TVerticalPos _VerticalPos
;
153 RYAI_MAP_CRUNCH::CTopology::TTopologyRef _TopoRef
;
154 RYAI_MAP_CRUNCH::CWorldPosition _DestPos
;
155 std::vector
<NLMISC::CSmartPtr
<CAIPath
> > _SourcePaths
;
157 RYAI_MAP_CRUNCH::TAStarFlag _denyFlags
;
160 //////////////////////////////////////////////////////////////////////////////
161 // CFollowPathContext //
162 //////////////////////////////////////////////////////////////////////////////
164 class CFollowPathContext
168 // - This method adds the new object to the top of the CFollowPath singleton's context stack
170 // - contextName : an arbitrary string naming the context
171 // - maxSearchDepth : the value that the path finder search depth should be limitted to (default to std::numeric_limits<uint32>::max() meaning no limit)
172 // - forceMaxDepth : set this flag true to override previous limit with larger value
174 // - ... Before we begin ... CFollowPath::_MaxSearchDepth = std::numeric_limits<uint32>::max()
175 // - CFollowPathContext context1("tata") : CFollowPath::_MaxSearchDepth => std::numeric_limits<uint32>::max()
176 // - CFollowPathContext context2("tete",456) : CFollowPath::_MaxSearchDepth => 456
177 // - CFollowPathContext context3("titi",123) : CFollowPath::_MaxSearchDepth => 123
178 // - CFollowPathContext context4("toto",456) : CFollowPath::_MaxSearchDepth => 123
179 // - CFollowPathContext context5("tutu") : CFollowPath::_MaxSearchDepth => 123
180 // - CFollowPathContext context6("dada",456,true) : CFollowPath::_MaxSearchDepth => 456
181 // - CFollowPathContext context6.~CFollowPathContext() : CFollowPath::_MaxSearchDepth => 123
182 // - CFollowPathContext context5.~CFollowPathContext() : CFollowPath::_MaxSearchDepth => 123
183 // - CFollowPathContext context4.~CFollowPathContext() : CFollowPath::_MaxSearchDepth => 123
184 // - CFollowPathContext context3.~CFollowPathContext() : CFollowPath::_MaxSearchDepth => 456
185 // - CFollowPathContext context2.~CFollowPathContext() : CFollowPath::_MaxSearchDepth => std::numeric_limits<uint32>::max()
186 // - CFollowPathContext context1.~CFollowPathContext() : CFollowPath::_MaxSearchDepth => std::numeric_limits<uint32>::max()
187 CFollowPathContext(const char* contextName
, uint32 maxSearchDepth
=std::numeric_limits
<uint32
>::max(), bool forceMaxDepth
=false);
190 // - This method removes the destroyed object from the CFollowPath singleton's context stack
191 // - Out of order destruction is supported ok, but the _MaxSearchDepth values of higher stack entries are not recalculated
192 ~CFollowPathContext();
194 // getter for _MaxSearchDepth
195 uint32
getMaxSearchDepth() const { return _MaxSearchDepth
; }
197 // simple accessor for contructing the full context name of this object by concatenating own name with names of previous context stack entries
198 void buildContextName(std::string
&result
) const;
201 CFollowPathContext
* _PrevContext
;
202 CFollowPathContext
* _NextContext
;
203 const char* _ContextName
;
204 uint32 _MaxSearchDepth
;
208 //////////////////////////////////////////////////////////////////////////////
210 //////////////////////////////////////////////////////////////////////////////
215 static CFollowPath
* _Instance
;
217 static CFollowPath
* getInstance();
218 static void destroyInstance();
224 FOLLOW_NO_PATH
, // no path found
225 FOLLOW_ARRIVED
, // arrived
226 FOLLOW_BLOCKED
// Is blocked by someone(s), cannot move.
233 FNP_NO_INSIDE_ASTAR_PATH
237 TFollowReason _LastReason
;
238 RYAI_MAP_CRUNCH::CWorldMap::TFindInsideAStarPathReason _LastFIASPReason
;
241 static std::string
toString(TFollowReason reason
, RYAI_MAP_CRUNCH::CWorldMap::TFindInsideAStarPathReason fIASPReason
= RYAI_MAP_CRUNCH::CWorldMap::FIASPR_NO_REASON
)
245 case FNP_NOT_INITIALIZED
:
246 return "FOLLOW_NO_PATH::NOT_INITIALIZED";
247 case FNP_NO_INSIDE_ASTAR_PATH
:
248 return "FOLLOW_NO_PATH::NO_INSIDE_ASTAR_PATH::" + RYAI_MAP_CRUNCH::CWorldMap::toString(fIASPReason
);
250 return "UnknownReason(" + NLMISC::toString((int)reason
) + ")";
253 TFollowReason
lastReason() { return _LastReason
; }
254 RYAI_MAP_CRUNCH::CWorldMap::TFindInsideAStarPathReason
lastFIASPReason() { return _LastFIASPReason
; }
257 NLMISC::CMustConsume
<TFollowStatus
> followPath(
258 CModEntityPhysical
* bot
,
259 CPathPosition
& pathPos
,
262 float modecalageDist
,
263 float angleAmort
= 1.f
,
264 bool focusOnTargetDirection
= true,
265 CAIVector
* realDestination
= NULL
,
266 float repulsSpeed
= 0.025f
,
267 bool updateOrient
= true);
270 friend class CFollowPathContext
;
271 CFollowPathContext
* _TopFollowPathContext
;
273 uint32
getMaxSearchDepth() const { return (_TopFollowPathContext
==NULL
)? std::numeric_limits
<uint32
>::max(): _TopFollowPathContext
->getMaxSearchDepth(); }
274 const char* getContextName() const;