1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
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.
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/>.
22 #include "persistent_spawnable.h"
25 #include "keyword_owner.h"
26 #include "debug_history.h"
27 #include "game_share/misc_const.h"
28 #include "profile_in_state.h"
31 #include "service_dependencies.h"
38 class CPersistentStateInstance
;
40 extern bool GrpHistoryRecordLog
;
42 //////////////////////////////////////////////////////////////////////////////
44 //////////////////////////////////////////////////////////////////////////////
46 /// This is a common parent for all grp classes (bot group classes)
47 /// Group contains a container of Bots.
49 : public NLMISC::CDbgRefCount
<CSpawnGroup
>
50 , public CSpawnable
<CPersistent
<CSpawnGroup
> >
51 , public CProfileOwner
52 , public CProfileParameters
55 CSpawnGroup(CPersistent
<CSpawnGroup
>& owner
);
57 virtual ~CSpawnGroup();
59 virtual void spawnBotOfGroup();
61 void aggroLost(TDataSetRow
const& aggroBot
) const { }
63 void aggroGain(TDataSetRow
const& aggroBot
) const { }
65 virtual void spawnBots() = 0;
66 virtual void spawnBots(const std::string
&name
) = 0;
67 virtual void spawnBots(const std::string
&name
, const std::string
&vpx
) = 0;
68 virtual void despawnBots(bool immediately
) = 0;
70 virtual void update() = 0;
72 // Update Rate feature.
73 virtual int getUpdatePriority() const { return 0; }
75 virtual void recalcUpdatePriorityDelta() { }
77 CGroup
& getPersistent() const;
79 CAliasCont
<CBot
> const& bots() const;
80 CAliasCont
<CBot
>& bots();
84 CProfilePtr
& movingProfile() { return _MovingProfile
; }
85 CProfilePtr
& activityProfile() { return _ActivityProfile
; }
86 CProfilePtr
const& activityProfile() const { return _ActivityProfile
; }
87 CProfilePtr
& fightProfile() { return _FightProfile
; }
89 /// only for use by State Machine (or problems will occurs -> callStateChanged if same )
90 void setMoveProfileFromStateMachine(IAIProfileFactory
* staticProfile
);
91 /// only for use by State Machine (or problems will occurs -> callStateChanged if same )
92 void setActivityProfileFromStateMachine(IAIProfileFactory
* staticProfile
);
95 bool calcCenterPos(CAIVector
& grp_pos
, bool allowDeadBot
= false);
101 friend class CSpawnGroup
;
102 CBotToSpawn(uint32 botIndex
, uint32 despawnTime
, uint32 respawnTime
)
103 : _botIndex(botIndex
)
105 _despawnTimer
.set(despawnTime
);
106 _respawnTimer
.set(respawnTime
);
108 bool waitingDespawnTimeOver() const
110 return _despawnTimer
.test();
112 bool waitingRespawnTimeOver() const
114 return _respawnTimer
.test();
116 uint32
getBotIndex() const
120 CAITimer
& respawnTimer()
122 return _respawnTimer
;
125 CAITimer _despawnTimer
;
126 CAITimer _respawnTimer
;
129 void incSpawnedBot(CBot
& spawnBot
);
131 void decSpawnedBot();
133 void addBotToDespawnAndRespawnTime(CBot
* faunaBot
, uint32 despawnTime
, uint32 respawnTime
);
138 uint32
nbSpawnedBot() const { return _NbSpawnedBot
; }
140 uint32
nbBotToRespawn() const { return (uint32
)_BotsToRespawn
.size(); }
142 uint32
nbBotToDespawn() const { return (uint32
)_BotsToDespawn
.size(); }
144 bool isGroupAlive(uint32
const nbMoreKilledBot
= 0) const;
146 CAIVector
const& getCenterPos() const { return _CenterPos
; }
148 void setCenterPos(CAIVector
const& pos
) { _CenterPos
= pos
; }
150 std::vector
<std::string
> getMultiLineInfoString() const;
152 virtual NLMISC::CSmartPtr
<CAIPlace
const> buildFirstHitPlace(TDataSetRow
const& aggroBot
) const;
154 void addAggroFor(TDataSetRow
const& bot
, float aggro
, bool forceReturnAggro
, NLMISC::CSmartPtr
<CAIPlace
const> place
= NLMISC::CSmartPtr
<CAIPlace
const>(NULL
));
155 void setAggroMinimumFor(TDataSetRow
const& bot
, float aggro
, bool forceReturnAggro
, NLMISC::CSmartPtr
<CAIPlace
const> place
= NLMISC::CSmartPtr
<CAIPlace
const>(NULL
));
156 bool haveAggro() const;
157 bool haveAggroOrReturnPlace() const;
160 const std::string
getActionName() const { return _ActionName
; }
161 void setActionName(const std::string
&name
) { _ActionName
= name
; }
163 const std::string
getUrl() const { return _Url
; }
164 void setUrl(const std::string
&url
) { _Url
= url
; }
167 CProfilePtr _PunctualHoldMovingProfile
;
168 CProfilePtr _PunctualHoldActivityProfile
;
170 // The group center pos (not always updated)
171 CAIVector _CenterPos
;
174 uint32 _NbSpawnedBot
;
176 std::vector
<CBotToSpawn
> _BotsToRespawn
;
177 std::vector
<CBotToSpawn
> _BotsToDespawn
;
179 CProfilePtr _MovingProfile
;
180 CProfilePtr _ActivityProfile
;
181 CProfilePtr _FightProfile
;
183 std::string _ActionName
;
187 //////////////////////////////////////////////////////////////////////////////
189 //////////////////////////////////////////////////////////////////////////////
192 : public NLMISC::CDbgRefCount
<CGroup
>
193 , public CPersistent
<CSpawnGroup
>
194 , public CAliasChild
<CManager
>
196 , public CDebugHistory
197 , public NLMISC::CRefCount
198 , public CProfileParameters
199 , public CServiceEvent::CHandler
202 friend class CSpawnGroup
;
204 CGroup(CManager
* owner
, RYAI_MAP_CRUNCH::TAStarFlag denyFlag
, CAIAliasDescriptionNode
* aliasTree
= NULL
);
205 CGroup(CManager
* owner
, RYAI_MAP_CRUNCH::TAStarFlag denyFlag
, uint32 alias
, std::string
const& name
);
208 void serviceEvent(CServiceEvent
const& info
);
211 CBot
* getSquadLeader(bool checkAliveStatus
= true);
215 virtual CDynGrpBase
* getGrpDynBase() = 0;
217 CAliasTreeOwner
* aliasTreeOwner() { return this; }
222 void autoDestroy(bool ad
) { _AutoDestroy
= ad
; }
224 /// @name CChild implementation
226 virtual std::string
getIndexString() const;
227 virtual std::string
getOneLineInfoString() const;
228 virtual std::vector
<std::string
> getMultiLineInfoString() const;
229 virtual std::string
getFullName() const;
232 virtual void lastBotDespawned();
233 virtual void firstBotSpawned();
235 virtual CPersistentStateInstance
* getPersistentStateInstance() = 0;
237 RYAI_MAP_CRUNCH::TAStarFlag
getAStarFlag() const { return _DenyFlags
; }
239 virtual CAIS::CCounter
& getSpawnCounter() = 0;
240 virtual RYZOMID::TTypeId
getRyzomType() = 0;
241 virtual void setEvent(uint eventId
) = 0;
243 virtual bool spawn();
245 virtual NLMISC::CSmartPtr
<CSpawnGroup
> createSpawnGroup() = 0;
247 virtual void despawnGrp();
249 void despawnBots(bool immediately
);
251 CAliasCont
<CBot
> const& bots() const { return _Bots
; }
252 CAliasCont
<CBot
>& bots() { return _Bots
; }
254 void display(CStringWriter
& stringWriter
);
256 CBot
* getBot(uint32 index
);
259 CDebugHistory
* getDebugHistory() { return this; }
261 CBot
* getNextValidBotChild(CBot
* child
= NULL
) { return _Bots
.getNextValidChild(child
); }
263 CManager
& getManager() { return *getOwner(); }
265 void setEscortTeamId(uint16 teamId
) { _EscortTeamId
= teamId
; }
266 uint16
getEscortTeamId() const { return _EscortTeamId
; }
268 void setEscortRange(float range
) { _EscortRange
= range
; }
269 float getEscortRange() const { return _EscortRange
; }
271 virtual void setAutoSpawn(bool autoSpawn
) { _AutoSpawn
= autoSpawn
; }
272 bool isAutoSpawn() const { return _AutoSpawn
; }
274 CAIInstance
* getAIInstance() const { return getOwner()->getAIInstance(); }
276 void setEventParams(const std::vector
<std::string
> &a
) { _EventParams
= a
; }
277 std::string
getEventParamString(uint32 i
) { if (i
>= _EventParams
.size()) return ""; return _EventParams
[i
]; }
278 float getEventParamFloat(uint32 i
) { if (i
>= _EventParams
.size()) return 0.0f
; return (float)atof(_EventParams
[i
].c_str()); }
281 uint32 _UpdateNbTicks
;
284 CAliasCont
<CBot
> _Bots
;
285 /// Team Id of the escort (if any).
286 uint16 _EscortTeamId
;
287 /// The range of the escort, ie the maximal distance of any escorter player that alow the group to be escorted
289 /// The bots automaticaly spawn when the group is spawned.
292 RYAI_MAP_CRUNCH::TAStarFlag _DenyFlags
;
294 std::vector
<std::string
> _EventParams
;
297 /****************************************************************************/
298 /* Inlined methods */
299 /****************************************************************************/
301 //////////////////////////////////////////////////////////////////////////////
303 //////////////////////////////////////////////////////////////////////////////
306 CSpawnGroup::CSpawnGroup(CPersistent
<CSpawnGroup
>& owner
)
307 : CSpawnable
<CPersistent
<CSpawnGroup
> >(owner
)
314 void CSpawnGroup::setMoveProfileFromStateMachine(IAIProfileFactory
* staticProfile
)
316 _MovingProfile
.setAIProfile(this, staticProfile
, true);
320 void CSpawnGroup::setActivityProfileFromStateMachine(IAIProfileFactory
* staticProfile
)
322 _ActivityProfile
.setAIProfile(this, staticProfile
, true);
326 bool CSpawnGroup::isGroupAlive(uint32
const nbMoreKilledBot
) const
328 return ((sint32
)_NbSpawnedBot
-(sint32
)_BotsToDespawn
.size()-(sint32
)nbMoreKilledBot
)>0;
332 CGroup
& CSpawnGroup::getPersistent() const
334 return static_cast<CGroup
&>(CSpawnable
<CPersistent
<CSpawnGroup
> >::getPersistent());
338 CAliasCont
<CBot
> const& CSpawnGroup::bots() const
340 return getPersistent()._Bots
;
344 CAliasCont
<CBot
>& CSpawnGroup::bots()
346 return getPersistent()._Bots
;
349 //////////////////////////////////////////////////////////////////////////////
351 //////////////////////////////////////////////////////////////////////////////
359 if (!getSpawnCounter().remainToMax())
362 setSpawn(createSpawnGroup());
367 void CGroup::despawnGrp()
373 getOwner()->groups().removeChildByIndex(getChildIndex());
377 void CGroup::despawnBots(bool immediately
)
381 getSpawnObj()->despawnBots(immediately
);
385 CBot
* CGroup::getBot(uint32 index
)
387 if (index
>=_Bots
.size())