khanat-opennel-code/code/ryzom/server/src/ai_service/ai_place.h
2017-03-15 20:43:10 +01:00

176 lines
4.7 KiB
C++

// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// 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 <http://www.gnu.org/licenses/>.
//class CAIPlace;
#ifndef RYAI_PLACE_H
#define RYAI_PLACE_H
#include "nel/misc/variable.h"
#include "ai_route.h"
#include "ai_share/world_map.h"
#include "world_container.h"
#include "ai.h"
class CPlaceOwner;
// come from config file
//extern uint32 RandomPosMaxRetry;
extern NLMISC::CVariable<uint32> RandomPosMaxRetry;
//extern bool LogAcceptablePos;
extern NLMISC::CVariable<bool> LogAcceptablePos;
const uint32 MAX_PLACE_RANDOM_POS = 64;
/** Base class for random generated pos inside a place.
* NB : this class as no idea of the place geometry it
* only store random valid position.
*/
class CPlaceRandomPos
:public NLMISC::CDbgRefCount<CPlaceRandomPos>
{
public:
CPlaceRandomPos()
{
_MaxPlacesFound = 0;
_VerticalPos = AITYPES::vp_auto;
}
void setVerticalPos(AITYPES::TVerticalPos verticalPos)
{
_VerticalPos = verticalPos;
}
AITYPES::TVerticalPos getVerticalPos() const
{
return _VerticalPos;
}
uint getRandomPosCount() const
{
return _MaxPlacesFound;
}
// return a random position within the place
void getRandomPos(RYAI_MAP_CRUNCH::CWorldPosition &pos) const
{
#ifdef NL_DEBUG
nlassert(_MaxPlacesFound>0);
#endif
pos=_PosList[CAIS::rand16(_MaxPlacesFound)];
}
void buildRandomPos(const RYAI_MAP_CRUNCH::CWorldPosition &validPos, float radius)
{
_MaxPlacesFound = 0;
RYAI_MAP_CRUNCH::CWorldPosition worldValidPos;
if (!CWorldContainer::calcNearestWPosFromPosAnRadius (_VerticalPos, worldValidPos, validPos, radius, 1000, CWorldContainer::CPosValidatorDefault()))
{
if (LogAcceptablePos)
nlwarning("Unvalid place (no collision free position found) at %d %d", validPos.toAIVector().x().asInt(), validPos.toAIVector().y().asInt());
}
uint maxTries= RandomPosMaxRetry;
nlassert(MAX_PLACE_RANDOM_POS>0);
_MaxPlacesFound = 0;
_PosList[_MaxPlacesFound] = worldValidPos;
_MaxPlacesFound++;
while (_MaxPlacesFound<MAX_PLACE_RANDOM_POS)
{
CAIPos dummyPos;
bool foundRandomPos=false;
while (!foundRandomPos)
{
if (calcRandomPos(dummyPos))
foundRandomPos=CWorldContainer::getWorldMap().setWorldPosition(_VerticalPos, _PosList[_MaxPlacesFound], dummyPos);
maxTries--;
if (maxTries<=0)
break;
}
if (maxTries<=0)
break;
_MaxPlacesFound++;
}
}
// virtual to overload to generate a random pos inside the place.
virtual bool calcRandomPos(CAIPos &pos) const =0;
protected:
AITYPES::TVerticalPos _VerticalPos;
private:
RYAI_MAP_CRUNCH::CWorldPosition _PosList[MAX_PLACE_RANDOM_POS];
uint32 _MaxPlacesFound;
};
/** This virtual base class represents a place to which AIs may go and
* contains route generator for pathfinding
*/
class CAIPlace:
public NLMISC::CDbgRefCount<CAIPlace>,
public CAliasChild<CPlaceOwner>,
public virtual NLMISC::CVirtualRefCount
{
public:
// ctor & dtor
CAIPlace(CPlaceOwner* owner, CAIAliasDescriptionNode *aliasDescription)
: CAliasChild<CPlaceOwner>(owner,aliasDescription)
{
}
virtual ~CAIPlace()
{
}
std::string getIndexString() const;
/// @name Abstract interface
//@{
/// Test whether a position is 'at the place'
virtual bool atPlace(const CAIVector &pos) const = 0;
/// Test whether a position is 'at the place'
virtual bool atPlace(const CAIVectorMirror &pos) const = 0;
/// Test whether an entity is 'at the place'
virtual bool atPlace(CAIEntityPhysical const* entity) const = 0;
/// Return the position of the middle of the place
virtual const CAIPos &midPos() const = 0;
/// Return a valid world position in the place.
virtual const RYAI_MAP_CRUNCH::CWorldPosition &worldValidPos() const = 0;
/// Return the outer radius of the place
virtual float getRadius() const = 0;
virtual void display(CStringWriter &stringWriter) const = 0;
virtual AITYPES::TVerticalPos getVerticalPos() const = 0;
virtual void getRandomPos(RYAI_MAP_CRUNCH::CWorldPosition &pos) const = 0;
//@}
virtual std::string getOneLineInfoString() const { return ""; }
};
#endif