// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . template class CAIVision; #ifndef RYAI_VISION_H #define RYAI_VISION_H #include "nel/misc/types_nl.h" #include "nel/misc/common.h" #include "nel/misc/debug.h" #include "nel/misc/entity_id.h" #include "nel/misc/sheet_id.h" #include "game_share/player_vision_delta.h" #include "game_share/ryzom_entity_id.h" #include "ai_entity_matrix.h" #include "time_interface.h" #include "ai_instance.h" #include #include #include //-------------------------------------------------------------------------- // The class //-------------------------------------------------------------------------- template class CAIVision { public: //---------------------------------------------------------------------- // default ctor CAIVision() // : _lastUpdate(CTimeInterface::gameCycle()) {} {} virtual ~CAIVision() {} template void updateBotsAndPlayers(CAIInstance *aii, const VectorClass &xy,uint32 playerRadiusInMeters,uint32 botRadiusInMeters) { // _lastUpdate=CTimeInterface::gameCycle(); updatePlayers(aii, xy, playerRadiusInMeters); updateBots(aii, xy, botRadiusInMeters); } void clear () { _bots.clear(); _players.clear(); _botsVisionRadius = 0; _playersVisionRadius = 0; } //---------------------------------------------------------------------- // player and bot buffer accessors const std::vector > &bots() const { return _bots; } const std::vector > &players() const { return _players; } const CAIVector& getBotsVisionCenter() const { return _botsVisionCenter; } uint32 getBotsVisionRadius() const { return _botsVisionRadius; } const CAIVector& getPlayersVisionCenter() const { return _playersVisionCenter; } uint32 getPlayersVisionRadius() const { return _playersVisionRadius; } //---------------------------------------------------------------------- // an stl-like iterator for iterating through entities in vision class iterator { public: iterator(): _vect(NULL), _vision(NULL) {} iterator(const CAIVision *vision): _vision(vision) { if (!vision->players().empty()) { _vect=&vision->players(); _it=vision->players().begin(); } else if (!vision->bots().empty()) { _vect=&vision->bots(); _it=vision->bots().begin(); } else _vect=NULL; } T &operator*() const { #ifdef NL_DEBUG nlassert(_vect!=NULL); #endif const NLMISC::CDbgPtr &dbgRef=*_it; T& objRef=*dbgRef; return objRef; } T *operator->() const { #ifdef NL_DEBUG nlassert(_vect!=NULL); #endif const NLMISC::CDbgPtr &dbgRef=*_it; T* objPtr=(T*)dbgRef; return objPtr; } iterator operator++() { #ifdef NL_DEBUG nlassert(_vect!=NULL); #endif // try to just move the iterator forwards in the current vector // if not at end of vector then return (success) ++_it; if (_it!=_vect->end()) return *this; // we've reached the end of the current vector so check wehether we were // scanning the player vector - if so switch to the bot vector if (_vect==&(_vision->players()) && !_vision->bots().empty()) { _vect=&_vision->bots(); _it=_vision->bots().begin(); return *this; } // we've at the end of both player and bot vectors so flag 'end' condition _vect=NULL; return *this; } bool operator!=( const iterator &cmp ) const { // assume that: // - if _vect and cmp._vect don't match then no match // - if _vect and cmp._vect are both NULL we have a match // - otherwise match depends on iterators return ( _vect!=cmp._vect || (_vect!=NULL && _it != cmp._it)); } private: const CAIVision *_vision; const std::vector > *_vect; typename std::vector >::const_iterator _it; }; //---------------------------------------------------------------------- // stl-like begin() and end() iterator begin() { return iterator(this); } iterator end() { return iterator(); } // const uint32 &getLastUpdate () const // { // return _lastUpdate; // } private: inline CAIVector getPosition(const class RYAI_MAP_CRUNCH::CWorldPosition & xy) { return xy.toAIVector(); } inline CAIVector getPosition(const class CAIVector & xy) { return xy; } template void updateBots(CAIInstance *aii, const VectorClass &xy,uint32 botRadiusInMeters) { H_AUTO(VisionUpdateBots); _botsVisionCenter = xy; _botsVisionRadius = botRadiusInMeters; const CAIEntityMatrixIteratorTblLinear *tbl; typename CAIEntityMatrix::CEntityIteratorLinear it; _bots.clear(); if (botRadiusInMeters==0) return; tbl = CAIS::instance().bestLinearMatrixIteratorTbl(botRadiusInMeters); CAIVector aiVectorXy = getPosition(xy); for (it = aii->botMatrix().beginEntities(tbl,xy); !it.end(); ++it) { CAIEntityPhysical const* phys = const_cast(&*it)->getSpawnObj(); if (phys && phys->aipos().quickDistTo(aiVectorXy) < botRadiusInMeters) { _bots.push_back(const_cast(&*it)); } } } template void updatePlayers(CAIInstance *aii, const VectorClass &xy,uint32 playerRadiusInMeters) { H_AUTO(VisionUpdatePlayers); _playersVisionCenter = xy; _playersVisionRadius = playerRadiusInMeters; const CAIEntityMatrixIteratorTblLinear *tbl; typename CAIEntityMatrix::CEntityIteratorLinear it; _players.clear(); if (playerRadiusInMeters==0) return; tbl = CAIS::instance().bestLinearMatrixIteratorTbl(playerRadiusInMeters); CAIVector aiVectorXy = getPosition(xy); for (it = aii->playerMatrix().beginEntities(tbl,xy); !it.end(); ++it) { CAIEntityPhysical const* phys = const_cast(&*it)->getSpawnObj(); if (phys && phys->aipos().quickDistTo(aiVectorXy) < playerRadiusInMeters) { _players.push_back(const_cast(&*it)); } } } //---------------------------------------------------------------------- // private data CAIVector _botsVisionCenter; uint32 _botsVisionRadius; std::vector > _bots; CAIVector _playersVisionCenter; uint32 _playersVisionRadius; std::vector > _players; // uint32 _lastUpdate; }; #endif