Resolve "Toggle Free Look with Hotkey"
[ryzomcore.git] / ryzom / server / src / ai_service / ai_vision.h
blob01d33e367d8021991c407b3145c55b470e7480bb
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
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.
8 //
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/>.
19 template <class T> class CAIVision;
22 #ifndef RYAI_VISION_H
23 #define RYAI_VISION_H
25 #include "nel/misc/types_nl.h"
26 #include "nel/misc/common.h"
27 #include "nel/misc/debug.h"
28 #include "nel/misc/entity_id.h"
29 #include "nel/misc/sheet_id.h"
31 #include "game_share/player_vision_delta.h"
32 #include "game_share/ryzom_entity_id.h"
33 #include "ai_entity_matrix.h"
34 #include "time_interface.h"
35 #include "ai_instance.h"
37 #include <map>
38 #include <vector>
39 #include <string>
42 //--------------------------------------------------------------------------
43 // The class
44 //--------------------------------------------------------------------------
46 template <class T>
47 class CAIVision
49 public:
50 //----------------------------------------------------------------------
51 // default ctor
52 CAIVision() // : _lastUpdate(CTimeInterface::gameCycle()) {}
54 virtual ~CAIVision() {}
56 template <class VectorClass>
57 void updateBotsAndPlayers(CAIInstance *aii, const VectorClass &xy,uint32 playerRadiusInMeters,uint32 botRadiusInMeters, uint32 cell=0)
59 // _lastUpdate=CTimeInterface::gameCycle();
60 updatePlayers(aii, xy, playerRadiusInMeters, cell);
61 updateBots(aii, xy, botRadiusInMeters, cell);
64 void clear ()
66 _bots.clear();
67 _players.clear();
68 _botsVisionRadius = 0;
69 _playersVisionRadius = 0;
72 //----------------------------------------------------------------------
73 // player and bot buffer accessors
74 const std::vector<NLMISC::CDbgPtr<T> > &bots() const { return _bots; }
75 const std::vector<NLMISC::CDbgPtr<T> > &players() const { return _players; }
77 const CAIVector& getBotsVisionCenter() const { return _botsVisionCenter; }
78 uint32 getBotsVisionRadius() const { return _botsVisionRadius; }
79 const CAIVector& getPlayersVisionCenter() const { return _playersVisionCenter; }
80 uint32 getPlayersVisionRadius() const { return _playersVisionRadius; }
82 //----------------------------------------------------------------------
83 // an stl-like iterator for iterating through entities in vision
84 class iterator
86 public:
87 iterator(): _vect(NULL), _vision(NULL) {}
88 iterator(const CAIVision *vision): _vision(vision)
90 if (!vision->players().empty())
92 _vect=&vision->players();
93 _it=vision->players().begin();
95 else if (!vision->bots().empty())
97 _vect=&vision->bots();
98 _it=vision->bots().begin();
100 else
101 _vect=NULL;
103 T &operator*() const
105 #ifdef NL_DEBUG
106 nlassert(_vect!=NULL);
107 #endif
108 const NLMISC::CDbgPtr<T> &dbgRef=*_it;
109 T& objRef=*dbgRef;
110 return objRef;
112 T *operator->() const
114 #ifdef NL_DEBUG
115 nlassert(_vect!=NULL);
116 #endif
117 const NLMISC::CDbgPtr<T> &dbgRef=*_it;
118 T* objPtr=(T*)dbgRef;
120 return objPtr;
122 iterator operator++()
124 #ifdef NL_DEBUG
125 nlassert(_vect!=NULL);
126 #endif
128 // try to just move the iterator forwards in the current vector
129 // if not at end of vector then return (success)
130 ++_it;
131 if (_it!=_vect->end())
132 return *this;
134 // we've reached the end of the current vector so check wehether we were
135 // scanning the player vector - if so switch to the bot vector
136 if (_vect==&(_vision->players()) && !_vision->bots().empty())
138 _vect=&_vision->bots();
139 _it=_vision->bots().begin();
140 return *this;
143 // we've at the end of both player and bot vectors so flag 'end' condition
144 _vect=NULL;
145 return *this;
148 bool operator!=( const iterator &cmp ) const
150 // assume that:
151 // - if _vect and cmp._vect don't match then no match
152 // - if _vect and cmp._vect are both NULL we have a match
153 // - otherwise match depends on iterators
154 return ( _vect!=cmp._vect || (_vect!=NULL && _it != cmp._it));
157 private:
158 const CAIVision *_vision;
159 const std::vector<NLMISC::CDbgPtr<T> > *_vect;
160 typename std::vector<NLMISC::CDbgPtr<T> >::const_iterator _it;
163 //----------------------------------------------------------------------
164 // stl-like begin() and end()
165 iterator begin()
167 return iterator(this);
169 iterator end()
171 return iterator();
174 // const uint32 &getLastUpdate () const
175 // {
176 // return _lastUpdate;
177 // }
179 private:
181 inline CAIVector getPosition(const class RYAI_MAP_CRUNCH::CWorldPosition & xy)
183 return xy.toAIVector();
186 inline CAIVector getPosition(const class CAIVector & xy)
188 return xy;
193 template <class VectorClass>
194 void updateBots(CAIInstance *aii, const VectorClass &xy, uint32 botRadiusInMeters, uint32 cell)
196 H_AUTO(VisionUpdateBots);
198 _botsVisionCenter = xy;
199 _botsVisionRadius = botRadiusInMeters;
201 const CAIEntityMatrixIteratorTblLinear *tbl;
202 typename CAIEntityMatrix<T>::CEntityIteratorLinear it;
204 _bots.clear();
205 if (botRadiusInMeters==0)
206 return;
207 tbl = CAIS::instance().bestLinearMatrixIteratorTbl(botRadiusInMeters);
209 CAIVector aiVectorXy = getPosition(xy);
211 for (it = aii->botMatrix().beginEntities(tbl,xy); !it.end(); ++it)
213 CAIEntityPhysical const* phys = const_cast<T*>(&*it)->getSpawnObj();
215 CMirrorPropValueRO<uint32> botCell( TheDataset, phys->dataSetRow(), DSPropertyCELL );
216 if ((cell >= 0 || botCell() == cell) && phys && phys->aipos().quickDistTo(aiVectorXy) < botRadiusInMeters)
218 _bots.push_back(const_cast<T*>(&*it));
223 template <class VectorClass>
224 void updatePlayers(CAIInstance *aii, const VectorClass &xy, uint32 playerRadiusInMeters, uint32 cell = 0)
226 H_AUTO(VisionUpdatePlayers);
228 _playersVisionCenter = xy;
229 _playersVisionRadius = playerRadiusInMeters;
231 const CAIEntityMatrixIteratorTblLinear *tbl;
232 typename CAIEntityMatrix<T>::CEntityIteratorLinear it;
234 _players.clear();
235 if (playerRadiusInMeters==0)
236 return;
237 tbl = CAIS::instance().bestLinearMatrixIteratorTbl(playerRadiusInMeters);
238 CAIVector aiVectorXy = getPosition(xy);
240 for (it = aii->playerMatrix().beginEntities(tbl,xy); !it.end(); ++it)
242 CAIEntityPhysical const* phys = const_cast<T*>(&*it)->getSpawnObj();
243 CMirrorPropValueRO<uint32> botCell( TheDataset, phys->dataSetRow(), DSPropertyCELL );
244 if ((cell >= 0 || botCell() == cell) && phys && phys->aipos().quickDistTo(aiVectorXy) < playerRadiusInMeters)
246 _players.push_back(const_cast<T*>(&*it));
251 //----------------------------------------------------------------------
252 // private data
254 CAIVector _botsVisionCenter;
255 uint32 _botsVisionRadius;
256 std::vector<NLMISC::CDbgPtr<T> > _bots;
258 CAIVector _playersVisionCenter;
259 uint32 _playersVisionRadius;
260 std::vector<NLMISC::CDbgPtr<T> > _players;
262 // uint32 _lastUpdate;
265 #endif