// 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 . #ifndef RYAI_BOT_H #define RYAI_BOT_H #include "nel/misc/path.h" #include "ai_entity_physical.h" #include "ai_entity_physical_inline.h" #include "ai_instance.h" #include "ai_pos.h" #include "states.h" #include "debug_history.h" #include "sheets.h" #include "profile.h" #include "ai_aggro.h" #include "dyn_grp.h" #include "nel/misc/variable.h" #include "service_dependencies.h" #include "game_share/timer.h" #include "fx_entity_manager.h" class CGroup; template class CSpawnable; template class CPersistent; void sAggroLost(TDataSetRow playerBot, TDataSetRow targetBot); void sAggroGain(TDataSetRow playerBot, TDataSetRow targetBot); class CSpawnGroup; class CSpawnGroup; extern CAIVector lastTriedPos; ////////////////////////////////////////////////////////////////////////////// // CSpawnBot // ////////////////////////////////////////////////////////////////////////////// class CSpawnBot : public NLMISC::CDbgRefCount , public CModEntityPhysical , public CProfileOwner , public CProfilePtr , public CBotAggroOwner , public CDynSpawnBot { public: typedef CHashMap TPropList; public: CSpawnBot(TDataSetRow const& entityIndex, CBot& owner, NLMISC::CEntityId const& id, float radius, uint32 level, RYAI_MAP_CRUNCH::TAStarFlag denyFlags); virtual ~CSpawnBot(); virtual void setTheta(CAngle theta); virtual void sendInfoToEGS() const; CBot& getPersistent() const; CSpawnGroup& spawnGrp() const; /// @name CBotAggroOwner implementation //@{ virtual void aggroLost(TDataSetRow const& aggroBot) const; virtual void aggroGain(TDataSetRow const& aggroBot) const; virtual NLMISC::CEntityId getAggroOwnerEid() const { return getEntityId(); } virtual RYAI_MAP_CRUNCH::CWorldPosition getAggroPos() const { return wpos(); } virtual NLMISC::CSmartPtr buildFirstHitPlace(TDataSetRow const& aggroBot) const; virtual std::set getAggroGroup(bool primary) 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; //@} virtual void setVisualPropertiesName(); // as there not a lot of prop (1 or 2, maybe 3) stores in this comportment, we don't need hash. bool getProp(size_t Id, uint32& value) const; void setProp(size_t Id, uint32 value); virtual float fightWeight() const; virtual float fightValue() const; CAIInstance* getAIInstance() const; std::vector getMultiLineInfoString() const; void setSpawnGroup(CSpawnGroup* spawnGroup) { _SpawnGroup = spawnGroup; } bool isHitting() const { return (getActionFlags()&RYZOMACTIONFLAGS::Attacks)!=0; } virtual void sheetChanged(); bool canHeal(); bool canSelfHeal(); void healTriggered(); void selfHealTriggered(); virtual float getSpeedFactor() const { return _SpeedFactor; } virtual void setSpeedFactor(float value) { _SpeedFactor = value; } public: TPropList _PropList; float _DamageSpeedCoef; float _DamageCoef; private: CSpawnGroup* _SpawnGroup; private: uint32 _LastHealTick; uint32 _LastSelfHealTick; float _SpeedFactor; }; ////////////////////////////////////////////////////////////////////////////// // CBot // ////////////////////////////////////////////////////////////////////////////// class CBot : public CAliasChild , public CPersistentOfPhysical , public CAIEntity , public CDebugHistory , public NLMISC::CRefCount , public CDynBot , public CServiceEvent::CHandler { friend class CGroup; public: /// @name Ctors and dtor //@{ CBot(CGroup* owner, CAIAliasDescriptionNode* alias = NULL); CBot(CGroup* owner, uint32 alias, std::string const& name); virtual ~CBot(); //@} /// @name CChild implementation //@{ virtual std::string getIndexString() const; virtual std::string getEntityIdString() const; virtual std::string getOneLineInfoString() const; virtual std::vector getMultiLineInfoString() const; virtual std::string getFullName() const; //@} /// @name Sheet management //@{ virtual AISHEETS::ICreatureCPtr getSheet() const { return _Sheet; } virtual bool isSheetValid() const { return !_Sheet.isNull(); } virtual void setSheet(AISHEETS::ICreatureCPtr const& sheet); virtual void triggerSetSheet(AISHEETS::ICreatureCPtr const& sheet); //@} /// @name AI objects hierarchy access //@{ CAIInstance* getAIInstance() const; CGroup& getGroup() { return *getOwner(); } CAliasTreeOwner const* getAliasTreeOwner() const { return this; } CSpawnBot* getSpawnObj() const; //@} /// @name CDynBot stuff //@{ void addEnergy() const; void removeEnergy() const; CDynBot const& getDynBot() const { return *this; }; void initEnergy(float energyCoef); //@} /// @name Observers management //@{ class IObserver { public: virtual void notifyBotDespawn(CBot* bot) {} virtual void notifyBotDeath(CBot* bot) {} virtual void notifyStopNpcControl(CBot* bot) {} }; void attachObserver(IObserver* obs); void detachObserver(IObserver* obs); void notifyBotDespawn(); void notifyBotDeath(); void notifyStopNpcControl(); //@} /// Debugging stuff CDebugHistory* getDebugHistory() { return this; } void serviceEvent(CServiceEvent const& info); virtual AITYPES::TFaunaType type() const { return AITYPES::FaunaTypeBadType; } virtual RYZOMID::TTypeId getRyzomType() const = 0; virtual void getSpawnPos(CAIVector& triedPos, RYAI_MAP_CRUNCH::CWorldPosition& pos, RYAI_MAP_CRUNCH::CWorldMap const& worldMap, CAngle& spawnTheta) = 0; virtual CAIS::CCounter& getSpawnCounter() = 0; virtual bool spawn(); virtual void despawnBot(); virtual bool reSpawn(bool sendMessage = true); bool isStuck() const { return _Stuck; } void setStuck(bool value) { _Stuck = value; } bool isBuildingBot() const { return _BuildingBot; } void setBuildingBot(bool value) { _BuildingBot = value; } bool ignoreOffensiveActions() const { return _IgnoreOffensiveActions; } void setIgnoreOffensiveActions(bool value) { _IgnoreOffensiveActions = value; } bool isHealer() const; void setHealer(bool value) { _Healer = value; } NLMISC::CEntityId createEntityId() const; const ucstring& getCustomName() const { return _CustomName; } void setCustomName(const ucstring &name) { _CustomName = name; } const uint32& getCustomMaxHp() const { return _CustomMaxHp; } void setCustomMaxHp(const uint32 &maxHp) { _CustomMaxHp = maxHp; } virtual void setClientSheet(const std::string & clientSheetName); // Can be redefine by NpcGroup in case of a BotNpc with a fauna sheet but that we don't want the name to ignore // Especialy for Ring Creatures virtual bool getFaunaBotUseBotName() const { return false;} protected: virtual CSpawnBot* getSpawnBot(TDataSetRow const& row, NLMISC::CEntityId const& id, float radius) = 0; virtual void sheetChanged(); bool finalizeSpawn(RYAI_MAP_CRUNCH::CWorldPosition const& botWPos, CAngle const& spawnTheta, float botMeterSize); virtual void initAdditionalMirrorValues() {} void setSheetDelayed(uint32 step); void setSheetDelayed0(); void setSheetDelayed1(); void setSheetDelayed2(); friend class CSetSheetTimerEvent; protected: AITYPES::TVerticalPos _VerticalPos; private: AISHEETS::ICreatureCPtr _Sheet; NLMISC::CSheetId _ClientSheet; bool _Stuck; bool _IgnoreOffensiveActions; bool _Healer; bool _BuildingBot; ucstring _CustomName; uint32 _CustomMaxHp; CTimer _SetSheetTimer; struct CSetSheetData { AISHEETS::ICreatureCPtr _SheetToSet; NLMISC::CSheetId _FxSheetId; CFxEntityPtr _Fx; }; CSetSheetData* _SetSheetData; std::vector* _Observers; public: void* _ProfileData; }; #endif