khanat-opennel-code/code/ryzom/server/src/ai_service/ai_aggro.h

167 lines
6.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/>.
#ifndef AI_AGGRO_H
#define AI_AGGRO_H
#include "timer.h"
#include "ai.h"
#include "ai_place.h"
class CBotAggroOwner;
class CAIEntityPhysical;
//////////////////////////////////////////////////////////////////////////////
// CBotAggroEntry //
//////////////////////////////////////////////////////////////////////////////
/** A pair of aggro/entity values.
*
* Aggro values are between 0 and 1. 0 means no aggro, 1 means full aggro.
*/
class CBotAggroEntry
: public NLMISC::CRefCount
{
public:
CBotAggroEntry(TDataSetRow const& bot, float aggro, CBotAggroOwner const& owner, NLMISC::CSmartPtr<CAIPlace const> place = NLMISC::CSmartPtr<CAIPlace const>(NULL));
virtual ~CBotAggroEntry();
float finalAggro() const { return _Aggro; }
void addAggro(float aggro, NLMISC::CSmartPtr<CAIPlace const> place = NLMISC::CSmartPtr<CAIPlace const>(NULL));
void decrementAggros(uint32 ticks);
bool updateTime(uint32 const& ticks) const;
TDataSetRow const& getBot() const { return _Bot; }
NLMISC::CSmartPtr<CAIPlace const> getLastHitPlace() const { return _LastHitPlace; }
void setMinimum(float aggro, NLMISC::CSmartPtr<CAIPlace const> place = NLMISC::CSmartPtr<CAIPlace const>(NULL));
void setMaximum(float aggro);
void scaleBy(float const& scale) { _Aggro *= scale; }
void operator=(CBotAggroEntry const& other);
virtual bool atPlace(CAIVector const& pos) const { if (_LastHitPlace) return _LastHitPlace->atPlace(pos); else return true; }
virtual bool atPlace(CAIVectorMirror const& pos) const { if (_LastHitPlace) return _LastHitPlace->atPlace(pos); else return true; }
virtual bool atPlace(CAIEntityPhysical const* entity) const { if (_LastHitPlace) return _LastHitPlace->atPlace(entity); else return true; }
private:
CBotAggroOwner const& _Owner;
TDataSetRow _Bot;
float _Aggro;
NLMISC::CSmartPtr<CAIPlace const> _LastHitPlace;
};
//////////////////////////////////////////////////////////////////////////////
// CBotAggroOwner //
//////////////////////////////////////////////////////////////////////////////
class CBotAggroOwner
{
public:
typedef NLMISC::CSmartPtr<CBotAggroEntry> TAggroEntryPtr;
typedef std::map<TDataSetRow, TAggroEntryPtr> TBotAggroList;
public:
CBotAggroOwner();
virtual ~CBotAggroOwner();
static bool isAggroable(TDataSetRow const& dataSetRow);
void update(uint32 ticks);
/// @name Management of an aggro entry
//@{
/// Command used by fight script only
void blockAggro(sint32 blockTime);
void ignoreReturnAggro(bool ignored);
virtual void maximizeAggroFor(TDataSetRow const& botRow);
/// Command used by fight script only
void minimizeAggroFor(TDataSetRow const& botRow);
void addAggroFor(TDataSetRow const& bot, float aggro, bool forceReturnAggro, NLMISC::CSmartPtr<CAIPlace const> place = NLMISC::CSmartPtr<CAIPlace const>(NULL), bool transferAggro = true);
// Sets the minimum value the aggro can have in [0;1]
void setAggroMinimumFor(TDataSetRow const& bot, float aggro, bool forceReturnAggro, NLMISC::CSmartPtr<CAIPlace const> place = NLMISC::CSmartPtr<CAIPlace const>(NULL), bool transferAggro = true);
void forgetAggroFor(TDataSetRow const& bot, bool forgetDamages = false);
bool isAggroValid(TDataSetRow const& bot);
bool isNewAggroValid(TDataSetRow const& bot);
bool haveAggro() const { return !_BotAggroList.empty(); }
bool haveAggroWithEntity(const TDataSetRow& rowId) const;
bool haveAggroOrReturnPlace() const { return haveAggro() || _FirstHitPlace!=NULL; }
virtual RYAI_MAP_CRUNCH::CWorldPosition getAggroPos() const;
virtual NLMISC::CEntityId getAggroOwnerEid() const;
virtual NLMISC::CSmartPtr<CAIPlace const> buildFirstHitPlace(TDataSetRow const& aggroBot) const;
virtual std::set<CBotAggroOwner*> getAggroGroup(bool primary) const { return std::set<CBotAggroOwner*>(); }
virtual void propagateAggro() const { }
virtual float getReturnDistCheck() const;
virtual float getD1Radius() const;
virtual float getD2Radius() const;
virtual float getPrimaryGroupAggroDist() const;
virtual float getPrimaryGroupAggroCoef() const;
virtual float getSecondaryGroupAggroDist() const;
virtual float getSecondaryGroupAggroCoef() const;
virtual float getAggroPropagationRadius() const;
//@}
float getAggroFor(TDataSetRow const& bot);
/// Used by CSpawnBotFauna for assist only
bool hasBeenHit(uint32 ticks) const;
/// Used by group fight profile only
/// merge all the aggro value from the other aggro list into this aggro list
void mergeAggroList(CBotAggroOwner const& otherList, float scale);
void updateListAndMarkBot(std::vector<CAIEntityPhysical*>& botList, float coef);
void setCanAggro(bool canAggro);
bool getSendAggroLostToEGS() const { return _SendAggroLostToEGS; }
/// @name Accessors
//@{
TBotAggroList const& getBotAggroList() const { return _BotAggroList; }
void clearAggroList(bool sendMessageToEGS = true);
bool isReturning() const { return _BotAggroList.empty() && _FirstHitPlace; }
RYAI_MAP_CRUNCH::CWorldPosition getReturnPos() const { return _ReturnPos; }
//@}
/// @name Event handlers
//@{
virtual void aggroLost(TDataSetRow const& aggroBot) const = 0;
virtual void aggroGain(TDataSetRow const& aggroBot) const = 0;
//@}
private:
virtual bool atPlace(CAIVector const& pos) const { if (_FirstHitPlace) return _FirstHitPlace->atPlace(pos); else return true; }
virtual bool atPlace(CAIVectorMirror const& pos) const { if (_FirstHitPlace) return _FirstHitPlace->atPlace(pos); else return true; }
virtual bool atPlace(CAIEntityPhysical const* entity) const { if (_FirstHitPlace) return _FirstHitPlace->atPlace(entity); else return true; }
private:
TBotAggroList _BotAggroList;
uint32 _LastHitTime;
bool _AggroBlocked;
bool _ReturnAggroIgnored;
bool _DontAggro;
bool _SendAggroLostToEGS;
CAITimer _AggroBlockTimer;
RYAI_MAP_CRUNCH::CWorldPosition _ReturnPos;
NLMISC::CSmartPtr<CAIPlace const> _FirstHitPlace;
};
#endif