Added ai command setEquipment
[ryzomcore.git] / ryzom / server / src / ai_service / continent.h
blob4b954afb58faa657175dc5122f0f7fc9f25b19c6
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
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.
8 //
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/>.
20 #ifndef CONTINENT_H
21 #define CONTINENT_H
23 #include "nel/misc/string_mapper.h"
24 #include "child_container.h"
25 #include "alias_tree_root.h"
26 #include "manager_parent.h"
27 #include "family_profile.h"
28 #include "ai_place_xyr.h"
29 #include "server_share/mission_messages.h"
30 #include <set>
31 #include "family_behavior.h"
32 #include "ai_outpost.h"
33 #include "service_dependencies.h"
34 #include "sheets.h"
36 class CContinent;
37 class CRegion;
38 class COutpost;
39 class CCellZone;
40 class CGroupFamily;
41 class IGroupDesc;
42 template <class FamilyT>
43 class CGroupDesc;
44 template <class FamilyT>
45 class CBotDesc;
46 class CCell;
47 class CFaunaZone;
48 class CNpcZone;
49 class CRoad;
50 class CRoadTrigger;
51 class CAIInstance;
52 class CMgrFauna;
53 class CMgrNpc;
54 class CGrpFauna;
55 class CGroupNpc;
57 //////////////////////////////////////////////////////////////////////////////
58 // CPopulationRecord //
59 //////////////////////////////////////////////////////////////////////////////
61 // the description of the sets of alternative populations for the group
62 class CPopulationRecord
64 public:
65 CPopulationRecord(AISHEETS::ICreatureCPtr const& sheetData, uint count);
67 bool operator==(CPopulationRecord const& other) const;
69 AISHEETS::ICreatureCPtr getCreatureSheet() const;
70 uint getBotCount(bool useCreatureMultiplier) const;
72 uint32 getEnergyValue(bool useCreatureMultiplier) const;
74 private:
75 AISHEETS::ICreatureCPtr _SheetData;
76 uint _Count;
79 //////////////////////////////////////////////////////////////////////////////
80 // CPopulationOwner //
81 //////////////////////////////////////////////////////////////////////////////
83 class CPopulationOwner
85 public:
86 virtual ~CPopulationOwner() { }
87 // virtual std::string getPopulationOwnerIndexString() const = 0;
89 virtual std::string getIndexString() const = 0;
90 // {
91 // return getPopulationOwnerIndexString();
92 // }
95 //////////////////////////////////////////////////////////////////////////////
96 // CPopulation //
97 //////////////////////////////////////////////////////////////////////////////
99 class CPopulation
100 : public CAliasChild<CPopulationOwner>
101 , public NLMISC::CRefCount
103 public:
104 CPopulation(CPopulationOwner* owner, CAIAliasDescriptionNode* aliasDescription = NULL);
105 CPopulation(CPopulationOwner* owner, uint32 alias, std::string name);
107 std::string getIndexString() const;
109 void setSpawnType(AITYPES::TSpawnType spawnType) { _SpawnType = spawnType; }
110 AITYPES::TSpawnType const& getSpawnType() { return _SpawnType; }; // always/ day/ night/ etc
112 void setWeight(uint32 weight) { _Weight=weight; }
113 uint32 const& getWeight() const { return _Weight; } // random weighting for randomizer
115 void addPopRecord(CPopulationRecord popRecord);
117 // passing self off as a vector of CPopulationRecord (to avoid re-writing code)
118 CPopulationRecord& operator[](size_t idx) const { return const_cast<CPopulationRecord &>(_PopRecords[idx]); }
119 size_t size() const { return _PopRecords.size(); }
121 private:
122 std::vector<CPopulationRecord> _PopRecords;
123 uint32 _Weight; // random weighting for randomizer
124 AITYPES::TSpawnType _SpawnType; // always/ day/ night/ etc
127 //////////////////////////////////////////////////////////////////////////////
128 // CAICircle //
129 //////////////////////////////////////////////////////////////////////////////
131 /// Description of a circle with coordinate and radius
132 class CAICircle
134 public:
135 CAICircle() { }
136 template <class V, class R>
137 CAICircle(V const& center, R radius)
138 : _Center(center)
139 , _Radius(radius)
143 template <class V>
144 bool isInside(V const& pos)
146 return (pos - _Center).sqrnorm() <= (_Radius+1)*(_Radius+1);
149 CAIVector const& center() const { return _Center; }
150 double const& radius() const { return _Radius; }
152 private:
153 CAIVector _Center;
154 double _Radius;
157 //////////////////////////////////////////////////////////////////////////////
158 // CAabb //
159 //////////////////////////////////////////////////////////////////////////////
161 /// A simple AABB class
162 class CAabb
164 public:
165 CAabb();
167 template <class V>
168 CAabb(std::vector<V> const& coords)
169 : _VMax(INT_MIN/CAICoord::UNITS_PER_METER, INT_MIN/CAICoord::UNITS_PER_METER)
170 , _VMin(INT_MAX/CAICoord::UNITS_PER_METER, INT_MAX/CAICoord::UNITS_PER_METER)
172 for (uint k=0; k<coords.size(); ++k)
173 includePoint(coords[k]);
176 template <class V>
177 void includePoint(V const& point)
179 if (point.x() < _VMin.x())
180 _VMin.setX(point.x());
181 if (point.x() > _VMax.x())
182 _VMax.setX(point.x());
183 if (point.y() < _VMin.y())
184 _VMin.setY(point.y());
185 if (point.y() > _VMax.y())
186 _VMax.setY(point.y());
188 void includeAabb(CAabb const& box);
190 void init();
192 template<class V>
193 bool isInside(V const& v)
195 return v.x() >= _VMin.x() && v.y() >= _VMin.y() && v.x() <= _VMax.x() && v.y() <= _VMax.y();
198 CAIVector const& vmin() const { return _VMin; }
199 CAIVector const& vmax() const { return _VMax; }
201 private:
202 CAIVector _VMin;
203 CAIVector _VMax;
207 //////////////////////////////////////////////////////////////////////////////
208 // CBaseZone //
209 //////////////////////////////////////////////////////////////////////////////
211 /* Contains properties common to all zones
212 * (fauna zones, nps zones ...)
214 class CBaseZone
216 public:
217 typedef CTmpPropertyZone::TTarget TZoneType;
218 // Add a new Id identifying a substitution CGroupFamily that should be use instead
219 // of standard CGroupFamily (those defined in CRegion), when spawning fauna on that zone
220 // Substitution occurs when one or more subtitution id have been added
221 void addSubstitutionGroupFamilyId(size_t id) { nlassert(id != 0); _SubstitutionGroupFamilyIds.insert(id); }
222 void removeSubstitutionGroupFamilyId(size_t id) { nlassert(id != 0); _SubstitutionGroupFamilyIds.erase(id); }
223 bool isSubstituted() const { return !_SubstitutionGroupFamilyIds.empty(); }
224 bool isSubsitutedForGroupFamily(size_t id) const { return _SubstitutionGroupFamilyIds.count(id) != 0; }
225 virtual TZoneType getZoneType() const = 0;
226 virtual AITYPES::CPropertySet& additionalActivities() = 0;
227 virtual AITYPES::CPropertySet const& additionalActivities () const = 0;
228 virtual RYAI_MAP_CRUNCH::CWorldPosition const& worldValidPos() const = 0;
229 private:
230 std::set<size_t> _SubstitutionGroupFamilyIds;
234 //////////////////////////////////////////////////////////////////////////////
235 // CFaunaZone //
236 //////////////////////////////////////////////////////////////////////////////
238 /// Zone for fauna activity
239 class CFaunaZone
240 : public CBaseZone
241 , public NLMISC::CDbgRefCount<CFaunaZone>
242 , public CAIPlaceXYR
244 public:
245 CFaunaZone(CCell *owner, CAIAliasDescriptionNode *adn);
246 ~CFaunaZone();
248 CCell* getOwner() const;
250 bool haveActivity(AITYPES::CPropertyId const& activity) const;
251 bool haveActivity(AITYPES::CPropertySet const& activities) const;
252 float getFreeAreaScore() const;
254 AITYPES::CPropertySet& initialActivities() { return _InitialActivities; }
255 AITYPES::CPropertySet const& initialActivities() const { return _InitialActivities; }
257 virtual AITYPES::CPropertySet& additionalActivities() { return _AdditionalActivities; }
258 virtual AITYPES::CPropertySet const& additionalActivities () const { return _AdditionalActivities; }
261 virtual TZoneType getZoneType() const { return CTmpPropertyZone::Fauna; }
263 virtual RYAI_MAP_CRUNCH::CWorldPosition const& worldValidPos() const { return CAIPlaceXYR::worldValidPos(); }
265 private:
266 uint32 getNbUse() const;
267 private:
268 AITYPES::CPropertySet _InitialActivities;
269 AITYPES::CPropertySet _AdditionalActivities;
272 //////////////////////////////////////////////////////////////////////////////
273 // CAIRefPlaceXYR //
274 //////////////////////////////////////////////////////////////////////////////
275 class CAIRefPlaceXYR
276 : public CAIPlace
278 public:
279 CAIRefPlaceXYR(CPlaceOwner* owner, CAIPlace const* zone);
281 operator CAIPlace const*() const;
283 NLMISC::CSmartPtr<CAIPlace const> const& getZone() const { return _Zone; }
284 CAIPos const& midPos() const { return _Zone->midPos(); }
285 RYAI_MAP_CRUNCH::CWorldPosition const& worldValidPos() const { return _Zone->worldValidPos(); }
286 float getRadius() const { return _Zone->getRadius(); }
288 bool atPlace(CAIVectorMirror const& pos) const { return _Zone->atPlace(pos); }
289 bool atPlace(CAIVector const& pos) const { return _Zone->atPlace(pos); }
290 virtual bool atPlace(CAIEntityPhysical const* entity) const;
291 void getRandomPos(RYAI_MAP_CRUNCH::CWorldPosition& pos) const { _Zone->getRandomPos(pos); }
292 AITYPES::TVerticalPos getVerticalPos() const { return _Zone->getVerticalPos(); }
293 void display(CStringWriter& stringWriter) const { _Zone->display(stringWriter); }
295 private:
296 NLMISC::CSmartPtr<CAIPlace const> _Zone;
299 //////////////////////////////////////////////////////////////////////////////
300 // CAIRefPlaceXYRFauna //
301 //////////////////////////////////////////////////////////////////////////////
302 // Just made to track ref count CFaunaZone ..
303 class CAIRefPlaceXYRFauna
304 : public CAIRefPlaceXYR,
305 public CFaunaGenericPlace
307 public:
308 CAIRefPlaceXYRFauna(CPlaceOwner* owner, CAIPlace const* zone);
314 //////////////////////////////////////////////////////////////////////////////
315 // CNpcZone //
316 //////////////////////////////////////////////////////////////////////////////
318 /// Zone for npc activity //
319 class CNpcZone
320 : public CBaseZone
321 , public NLMISC::CDbgRefCount<CNpcZone>
322 , public virtual NLMISC::CVirtualRefCount
324 public:
325 virtual ~CNpcZone();
326 void unlinkNpcZone();
328 /// @name Abstract interface
329 //@{
330 virtual CCell* getOwner() const = 0;
331 virtual const CAliasTreeOwner& getAliasTreeOwner() const = 0;
332 virtual uint32 getIndex() const = 0;
334 virtual CPlaceRandomPos& getPlaceRandomPos() = 0;
335 virtual const CPlaceRandomPos& getPlaceRandomPos() const = 0;
337 /// Test whether a position is inside the zone
338 virtual bool atPlace(const CAIVector &pos) const = 0;
339 virtual bool atPlace(const CAIVectorMirror &pos) const = 0;
340 /// Return the position of the middle of the zone
341 virtual const CAIPos &midPos() const = 0;
343 /// Returns the area of the zone
344 virtual float getArea() const = 0;
345 //@}
347 /// Returns the number of times this zone is occupied
348 uint32 getNbUse() const;
350 /// Returns a score corresponding to the empty space
351 virtual float getFreeAreaScore() const;
353 std::string getIndexString() const;
355 void unrefZoneInRoads();
357 /// @name Accessors
358 //@{
359 AITYPES::CPropertySet& properties();
360 const AITYPES::CPropertySet& properties() const;
361 std::vector<NLMISC::CDbgPtr<CRoad> >& roads();
362 //@}
364 virtual TZoneType getZoneType() const { return CTmpPropertyZone::Npc; }
366 virtual AITYPES::CPropertySet& additionalActivities() { return _Properties; }
367 virtual AITYPES::CPropertySet const& additionalActivities () const { return _Properties; }
369 private:
370 AITYPES::CPropertySet _Properties;
371 /// The list of road starting from this zone.
372 std::vector<NLMISC::CDbgPtr<CRoad> > _Roads;
375 // :TODO: check if that inlining is necessary
376 //inline void CNpcZone::unrefZoneInRoads(); // See at end of this file
378 //////////////////////////////////////////////////////////////////////////////
379 // CNpcZonePlace //
380 //////////////////////////////////////////////////////////////////////////////
382 class CNpcZonePlace
383 : public CNpcZone
384 , public CPlaceRandomPos
385 , public CAIPlace
387 public:
388 CNpcZonePlace(CCell* owner, CAIAliasDescriptionNode* adn);
389 ~CNpcZonePlace();
391 /// @name CNpcZone implementation
392 //@{
393 CCell* getOwner() const;
394 CAliasTreeOwner const& getAliasTreeOwner() const;
395 uint32 getIndex() const;
397 CPlaceRandomPos& getPlaceRandomPos();
398 CPlaceRandomPos const& getPlaceRandomPos() const;
400 virtual bool atPlace(const CAIVector &pos) const;
401 virtual bool atPlace(const CAIVectorMirror &pos) const;
402 virtual bool atPlace(CAIEntityPhysical const* entity) const;
404 virtual CAIPos const& midPos() const;
406 virtual float getArea() const;
408 virtual RYAI_MAP_CRUNCH::CWorldPosition const& worldValidPos() const;
410 virtual float getRadius() const;
412 virtual void display(CStringWriter &stringWriter) const;
414 virtual AITYPES::TVerticalPos getVerticalPos() const;
415 virtual void getRandomPos(RYAI_MAP_CRUNCH::CWorldPosition &pos) const;
416 //@}
418 void setPosAndRadius(AITYPES::TVerticalPos verticalPos, const CAIPos& pos, uint32 radius);
420 private:
422 bool calcRandomPos(CAIPos& pos) const;
424 private:
425 RYAI_MAP_CRUNCH::CWorldPosition _worldValidPos;
426 CAIPos _pos;
427 float _radius;
430 //////////////////////////////////////////////////////////////////////////////
431 // CNpcZonePlaceNoPrim //
432 //////////////////////////////////////////////////////////////////////////////
434 class CNpcZonePlaceNoPrim
435 : public virtual NLMISC::CVirtualRefCount
437 public:
438 CNpcZonePlaceNoPrim();
439 ~CNpcZonePlaceNoPrim();
441 /// @name CNpcZone implementation
442 //@{
443 virtual bool atPlace(const CAIVector &pos) const;
444 virtual bool atPlace(const CAIVectorMirror &pos) const;
445 virtual bool atPlace(CAIEntityPhysical const* entity) const;
447 virtual CAIPos const& midPos() const;
449 virtual float getArea() const;
451 virtual RYAI_MAP_CRUNCH::CWorldPosition const& worldValidPos() const;
453 virtual float getRadius() const;
455 virtual void display(CStringWriter &stringWriter) const;
457 virtual AITYPES::TVerticalPos getVerticalPos() const;
458 virtual void getRandomPos(RYAI_MAP_CRUNCH::CWorldPosition &pos) const;
459 virtual uint getRandomPosCount() const { return 1; }
460 //@}
462 void setPosAndRadius(AITYPES::TVerticalPos verticalPos, const CAIPos& pos, uint32 radius);
464 private:
466 bool calcRandomPos(CAIPos& pos) const;
468 private:
469 RYAI_MAP_CRUNCH::CWorldPosition _WorldValidPos;
470 CAIPos _Pos;
471 float _Radius;
472 AITYPES::TVerticalPos _VerticalPos;
475 //////////////////////////////////////////////////////////////////////////////
476 // CNpcZoneShape //
477 //////////////////////////////////////////////////////////////////////////////
479 class CNpcZoneShape
480 : public CNpcZone
481 , public CAIPlace
483 public:
484 CNpcZoneShape(CCell* owner, CAIAliasDescriptionNode* adn);
485 ~CNpcZoneShape();
487 /// @name CNpcZone implementation
488 //@{
489 virtual CCell* getOwner() const;
490 virtual CAliasTreeOwner const& getAliasTreeOwner() const;
491 virtual uint32 getIndex() const;
493 virtual CPlaceRandomPos& getPlaceRandomPos();
494 virtual CPlaceRandomPos const& getPlaceRandomPos() const;
496 virtual bool atPlace(const CAIVector& pos) const;
497 virtual bool atPlace(const CAIVectorMirror &pos) const;
498 virtual bool atPlace(CAIEntityPhysical const* entity) const;
499 virtual CAIPos const& midPos() const;
501 virtual float getArea() const;
503 virtual const RYAI_MAP_CRUNCH::CWorldPosition& worldValidPos() const;
505 virtual float getRadius() const;
507 virtual void display(CStringWriter &stringWriter) const;
509 virtual AITYPES::TVerticalPos getVerticalPos() const;
510 virtual void getRandomPos(RYAI_MAP_CRUNCH::CWorldPosition &pos) const;
511 //@}
513 void setPatat(AITYPES::TVerticalPos verticalPos, const std::vector<CAIVector>& points);
515 private:
516 void buildMidPos();
518 private:
519 RYAI_MAP_CRUNCH::CWorldPosition _worldValidPos;
520 CShape _shape;
521 CAIPos _midPos;
524 //////////////////////////////////////////////////////////////////////////////
525 // CLazyProcess //
526 //////////////////////////////////////////////////////////////////////////////
528 class CLazyProcess
529 : public NLMISC::CRefCount
531 public:
532 virtual ~CLazyProcess() {}
533 /// Used to update some dependencies for instance road connections when the first next update of CContinent is called.
534 virtual void update() const = 0;
535 /// Used to check if there's no need to add another lazyprocess.
536 virtual bool absorb(CLazyProcess const& lazyProcess) const = 0;
539 //////////////////////////////////////////////////////////////////////////////
540 // CRebuildContinentAndOutPost //
541 //////////////////////////////////////////////////////////////////////////////
543 class CRebuildContinentAndOutPost
544 : public CLazyProcess
546 public:
547 CRebuildContinentAndOutPost(CContinent* continent);
549 protected:
550 void update () const;
551 bool absorb(CLazyProcess const& lazyProcess) const;
552 bool operator==(CRebuildContinentAndOutPost const& other) const;
554 private:
555 CContinent* _Continent;
558 //////////////////////////////////////////////////////////////////////////////
559 // CContinent //
560 //////////////////////////////////////////////////////////////////////////////
562 /// Store regions and spead energy level.
563 class CContinent
564 : public NLMISC::CDbgRefCount<CContinent>
565 , public CChild<CAIInstance>
566 , public NLMISC::CRefCount
567 , public CServiceEvent::CHandler
568 , public CAIEntity
570 public:
571 CContinent(CAIInstance* owner);
573 virtual ~CContinent();
575 CAIInstance* getAIInstance() const { return getOwner(); }
577 CAliasCont<CRegion>& regions() { return _Regions;}
578 CAliasCont<COutpost>& outposts() { return _Outposts;}
579 CAliasCont<COutpost> const& outposts() const { return _Outposts;}
581 CNpcZone* findNpcZone(CAIVector const& posInside);
583 /// Tag all the regions loaded from fileId to delete
584 bool markTagForDelete(NLMISC::TStringId fileId);
585 /// Delete all region that are taged
586 bool deleteTaggedAlias(NLMISC::TStringId fileId);
588 void rebuildBoundingBox();
589 /// Update the continent
590 void update();
592 void pushLazyProcess(NLMISC::CSmartPtr<CLazyProcess> lazyProcess);
593 void updateLazyProcess();
595 // Some service are up, need to send them data?
596 void serviceEvent(CServiceEvent const& info);
598 bool spawn();
599 bool despawn();
601 std::string getFullName() const { return getName(); }
602 std::string getIndexString() const;
603 virtual std::string getOneLineInfoString() const;
604 virtual std::vector<std::string> getMultiLineInfoString() const;
606 void setName(std::string const& name) { _ContinentName = name; }
608 std::string getName() const { return _ContinentName; }
610 /// Bounding box info.
611 CAabb _BoundingBox;
612 typedef std::vector<NLMISC::CSmartPtr<CLazyProcess> > TLazyProcessList;
613 TLazyProcessList _LazyProcess;
615 private:
616 /// @name AI service hierarchy
617 //@{
618 /// The set of regions stored in this continent
619 CAliasCont<CRegion> _Regions;
620 /// The set of outpost stored in this continent
621 CAliasCont<COutpost> _Outposts;
622 //@}
624 /// Name of the continent
625 std::string _ContinentName;
627 IAliasCont* getAliasCont(AITYPES::TAIType type);
630 //////////////////////////////////////////////////////////////////////////////
631 // CRegion //
632 //////////////////////////////////////////////////////////////////////////////
634 /// Store cell zones, groups templates and roads.
635 class CRegion
636 : public CAliasChild<CContinent>
637 , public NLMISC::CRefCount
638 , public CAliasTreeRoot
639 , public CServiceEvent::CHandler
640 , public CAIEntity
642 public:
643 CRegion(CContinent* owner, uint32 alias, std::string const& name, std::string const& filename);
644 virtual ~CRegion();
646 CAIInstance* getAIInstance() const { return getOwner()->getAIInstance(); }
648 CAliasCont<CCellZone>& cellZones() { return _CellZones; }
650 CAliasCont<CGroupFamily>& groupFamilies() { return _GroupFamilies; }
652 virtual std::string getIndexString() const;
653 virtual std::string getOneLineInfoString() const;
654 virtual std::vector<std::string> getMultiLineInfoString() const;
655 virtual std::string getFullName() const;
657 /// Rebuild the bounding box
658 void rebuildBoundingBox();
659 /// Rebuild the link road->zone and conectivity graph for cells
660 void rebuildConnectivity();
662 /// Update the region
663 void update();
664 void serviceEvent(CServiceEvent const& info);
666 bool spawn();
667 bool despawn();
669 /// Bounding box info.
670 CAabb _BoundingBox;
672 private:
673 /// @name AI service hierarchy
674 //@{
675 /// Container for owned cellzones
676 CAliasCont<CCellZone> _CellZones;
677 /// Container for owner group descs
678 CAliasCont<CGroupFamily> _GroupFamilies;
679 //@}
681 IAliasCont* getAliasCont(AITYPES::TAIType type);
682 CAliasTreeOwner* createChild(IAliasCont* cont, CAIAliasDescriptionNode* aliasTree);
685 //////////////////////////////////////////////////////////////////////////////
686 // CRoad //
687 //////////////////////////////////////////////////////////////////////////////
689 /// Road for npc moving.
690 class CRoad
691 : public NLMISC::CDbgRefCount<CRoad>
692 , public NLMISC::CRefCount
693 , public CAliasChild<CCell>
695 public:
696 CRoad(CCell* owner, uint32 alias, std::string const& name);
697 ~CRoad();
699 std::string getIndexString() const;
701 CAIVector const& getLogicStart() const { return _Start; }
702 CAIVector const& getLogicEnd() const { return _End; }
703 AITYPES::TVerticalPos const& verticalPos() const { return _VerticalPos; }
704 void setVerticalPos(AITYPES::TVerticalPos const& vertPos) { _VerticalPos = vertPos; }
705 std::vector<RYAI_MAP_CRUNCH::CWorldPosition> const& coords() const { return _Coords; }
706 void clearCoords() { _Coords.clear(); }
708 NLMISC::CDbgPtr<CNpcZone> const& startZone() const { return _StartZone; }
709 NLMISC::CDbgPtr<CNpcZone> const& endZone() const { return _EndZone; }
711 bool const& startExternal() const { return _StartExternal; }
713 bool const& endExternal() const { return _EndExternal; }
715 void setStartZone(CNpcZone const* npcZone);
716 void setEndZone(CNpcZone const* npcZone);
718 void unlinkRoad();
720 void calcLength();
722 void setDifficulty(float const& difficulty);
724 void calCost();
726 // Pathfinding property.
727 float getCost() const;
729 CAliasCont<CRoadTrigger>& triggers() { return _RoadTriggers; }
731 void setPathPoints(AITYPES::TVerticalPos verticalPos, std::vector<CAIVector> const& points);
733 std::set<CNpcZone*> AllZones;
735 private:
736 /// @name AI service hierarchy
737 //@{
738 CAliasCont<CRoadTrigger> _RoadTriggers;
739 //@}
741 IAliasCont* getAliasCont(AITYPES::TAIType type);
742 CAliasTreeOwner* createChild(IAliasCont* cont, CAIAliasDescriptionNode* aliasTree);
744 /// The vertical pos
745 AITYPES::TVerticalPos _VerticalPos;
746 /// The path of the road
747 std::vector<RYAI_MAP_CRUNCH::CWorldPosition> _Coords;
748 /// Pointer to the zone at start of road
749 NLMISC::CDbgPtr<CNpcZone> _StartZone;
750 /// Flag that indicate the zone is outside the region
751 bool _StartExternal;
752 /// Pointer to the zone at end of road
753 NLMISC::CDbgPtr<CNpcZone> _EndZone;
754 /// Flag that indicate the zone is outside the region
755 bool _EndExternal;
757 // Data for path finding
758 /// length of the road segment
759 float _Length;
760 /// Difficulty of the road
761 float _Difficulty;
763 float _CostCoef;
765 CAIVector _Start;
766 CAIVector _End;
769 //////////////////////////////////////////////////////////////////////////////
770 // CRoadTrigger //
771 //////////////////////////////////////////////////////////////////////////////
773 class CRoadTrigger
774 : public CAliasChild<CRoad>
775 , public NLMISC::CRefCount
777 public:
778 CRoadTrigger(CRoad* owner, uint32 alias, std::string const& name);
780 std::string getIndexString() const;
782 CAICircle _Trigger1;
783 CAICircle _Trigger2;
784 CAICircle _Spawn;
787 //////////////////////////////////////////////////////////////////////////////
788 // CZoneScorer //
789 //////////////////////////////////////////////////////////////////////////////
791 class CZoneScorer
793 public:
794 virtual ~CZoneScorer() { }
795 virtual float getScore(CNpcZone const& zone) const = 0;
796 virtual float getParam(CNpcZone const& zone) const { return 0.f; };
799 //////////////////////////////////////////////////////////////////////////////
800 // CCellZone //
801 //////////////////////////////////////////////////////////////////////////////
803 /// Container for cell and energy levels.
804 class CCellZone
805 : public CAliasChild<CRegion>
806 , public NLMISC::CRefCount
807 , public CServiceEvent::CHandler
808 , public CAIEntity
810 public:
811 CCellZone(CRegion* owner, uint32 alias, std::string const& name);
812 ~CCellZone();
814 CAIInstance* getAIInstance() const { return getOwner()->getAIInstance(); }
816 CAliasCont<CCell>& cells() { return _Cells; }
818 void unrefZoneInRoads();
820 std::string getIndexString() const;
821 virtual std::string getOneLineInfoString() const;
822 virtual std::vector<std::string> getMultiLineInfoString() const;
823 virtual std::string getFullName() const;
825 void rebuildEnergyLevels();
826 void update();
827 void serviceEvent(CServiceEvent const& info);
829 bool findRestAndFoodFaunaZoneInCellList(CFaunaZone const*& zoneRest, AITYPES::CPropertySet const& rest, CFaunaZone const*& zoneFood, AITYPES::CPropertySet const& food, std::vector<CCell*> const& cells, RYAI_MAP_CRUNCH::TAStarFlag denyflags);
832 CFaunaZone const* lookupFaunaZone(AITYPES::CPropertySet const& activity, RYAI_MAP_CRUNCH::TAStarFlag denyflags, size_t replacementGroupFamilyId = 0);
833 const CNpcZone *lookupNpcZone(AITYPES::CPropertySet const& activity, size_t replacementGroupFamilyId = 0);
834 static CNpcZone const* lookupNpcZoneScorer(std::vector<CCell*> cells, CZoneScorer const& scorer);
836 const CNpcZone* lookupNpcZoneByName(std::string const& zoneName);
838 CCont<CFamilyBehavior>& familyBehaviors() { return _Families; }
840 bool spawn();
841 bool despawn();
843 /// Bouding box surrounding all the contained cells.
844 CAabb _BoundingBox;
846 /// @name AI service hierarchy
847 //@{
848 public:
849 /// The family behavior container
850 CCont<CFamilyBehavior> _Families;
851 private:
852 CAliasCont<CCell> _Cells;
853 //@}
855 private:
856 // overloads for CAliasChild virtuals
857 IAliasCont* getAliasCont(AITYPES::TAIType type);
858 CAliasTreeOwner* createChild(IAliasCont* cont, CAIAliasDescriptionNode* aliasTree);
861 //////////////////////////////////////////////////////////////////////////////
862 // CCell //
863 //////////////////////////////////////////////////////////////////////////////
865 /** Cell definition.
866 * Contains npc and faune zones.
868 typedef CAliasCont<CNpcZonePlace> TAliasZonePlaceList;
869 typedef CAliasCont<CNpcZoneShape> TAliasZoneShapeList;
871 class CCell
872 : public NLMISC::CDbgRefCount<CCell>
873 , public NLMISC::CRefCount
874 , public CAliasChild<CCellZone>
875 , public CPlaceOwner
877 public:
878 CCell(CCellZone* owner, uint32 alias, std::string const& name);
879 ~CCell();
881 void unlinkCell();
883 CAliasCont<CRoad>& roads() { return _Roads; }
885 void connectRoads();
887 CAliasCont<CFaunaZone>& faunaZones() { return _FaunaZones; }
888 CAliasCont<CFaunaZone> const& faunaZonesCst() const { return _FaunaZones; }
890 CNpcZone* findNpcZone(CAIVector const& posInside);
892 size_t npcZoneCount();
893 CNpcZone* npcZone(size_t index);
894 TAliasZonePlaceList& npcZonePlaces() { return _NpcZonePlaces; }
895 TAliasZoneShapeList& npcZoneShapes() { return _NpcZoneShapes; }
896 TAliasZonePlaceList const& npcZonePlacesCst() const { return _NpcZonePlaces; }
897 TAliasZoneShapeList const& npcZoneShapesCst() const { return _NpcZoneShapes; }
899 AITYPES::CPropertySet const& properties() const { return _Properties; }
900 AITYPES::CPropertySet& properties() { return _Properties; }
902 void getNeighBourgCellList(std::vector<CCell*>& cells) const;
904 void unrefZoneInRoads();
906 virtual std::string getIndexString() const;
907 virtual std::string getFullName() const;
909 /// The coordinate of the polygon surounding the cell
910 std::vector<CAIVector> _Coords;
911 /// The liste of flag for family that can come in this cell
913 AITYPES::CPropertySet _Properties;
915 /// The list of neighbour cells
916 std::set<NLMISC::CDbgPtr<CCell> > _NeighbourCells;
918 CAabb _BoundingBox;
920 private:
921 /// @name AI service hierarchy
922 //@{
923 CAliasCont<CFaunaZone> _FaunaZones;
925 /// Container for owned roads
926 CAliasCont<CRoad> _Roads;
927 //@}
929 TAliasZonePlaceList _NpcZonePlaces;
930 TAliasZoneShapeList _NpcZoneShapes;
932 IAliasCont* getAliasCont(AITYPES::TAIType type);
933 CAliasTreeOwner* createChild(IAliasCont* cont, CAIAliasDescriptionNode* aliasTree);
935 // std::string getPlaceOwnerFullName() const { return getFullName(); }
936 // std::string getPlaceOwnerIndexString() const { return getIndexString(); }
939 //////////////////////////////////////////////////////////////////////////////
940 // CAggroGroupContainer //
941 //////////////////////////////////////////////////////////////////////////////
943 class CAggroGroupContainer
944 : public NLMISC::CVirtualRefCount
946 public:
947 std::vector<uint32> aggroGroupIds;
951 class CZoneMarker;
953 //////////////////////////////////////////////////////////////////////////////
954 // CGroupFamily //
955 //////////////////////////////////////////////////////////////////////////////
957 class CGroupFamily
958 : public NLMISC::CDbgRefCount<CGroupFamily>
959 , public NLMISC::CRefCount
960 , public CAliasTreeOwner
961 , public CLevelEnergy
963 public:
964 CGroupFamily(CAliasTreeOwner *owner, uint32 alias, std::string const& name);
965 virtual ~CGroupFamily();
967 CAliasTreeOwner *getOwner() const { return _Owner; }
969 void setFamilyTag(std::string const& familyTag) { _FamilyTag = AITYPES::CPropertyId(familyTag); }
970 AITYPES::CPropertyId const& getFamilyTag() const { return _FamilyTag; }
972 void setProfileName(std::string const& profileName) { _ProfileName = NLMISC::CStringMapper::map(profileName); }
974 typedef std::map<NLMISC::TStringId, NLMISC::CSmartPtr<NLMISC::CVirtualRefCount> > TParamsList;
975 TParamsList _Params;
977 void setProfileParams(std::string const& str, NLMISC::CVirtualRefCount* objet);
979 NLMISC::CVirtualRefCount const* getProfileParams(std::string const& str) const;
981 CAliasCont<CGroupDesc<CGroupFamily> >& groupDescs() { return _GroupDescs; }
984 std::string getFullName() const { return std::string(getOwner()->getFullName() +":"+ getName()); }
986 std::string getIndexString() const { return getOwner()->getIndexString()+NLMISC::toString(":%u", getChildIndex()); }
990 std::string getFullName() const { return "???:" + getName(); }
991 std::string getIndexString() const { return "???" + NLMISC::toString(":%u", getChildIndex()); }
993 // mimic CChild behaviour
994 void setChildIndex(uint32 index)
996 _Index = index;
999 uint32 getChildIndex() const
1001 return _Index;
1004 IAliasCont* getAliasCont(AITYPES::TAIType type);
1005 CAliasTreeOwner* createChild(IAliasCont* cont, CAIAliasDescriptionNode* aliasTree);
1007 CGroupDesc<CGroupFamily> const* getProportionalGroupDesc(CFamilyBehavior const* const familyBehavior, AITYPES::CPropertySet const& needActFlag, AITYPES::CPropertySet const& maskActFlag);
1009 NLMISC::TStringId const& profileName() const { return _ProfileName; }
1011 typedef std::map<NLMISC::TStringId, AITYPES::CPropertySet> TActivityList;
1013 void addProfileProperty(std::string const& propertyName, AITYPES::CPropertySet const& property);
1014 AITYPES::CPropertySet const& getProfileProperty(std::string const& propertyName) const;
1017 // mark this GroupFamily as a substitution group. An id of 0 means this group is not a substitution group (which is the default)
1018 // subtitution GroupFamily will shadow standard GroupFamily group at update
1019 // for the fauna zones that have the same id than this group in their subtitution id list.
1020 // (if the subtitution list is empty then the fauna zone GroupFamilies are not substituted)
1021 void setSubstitutionId(size_t substitutionId) { _SubstitutionId = substitutionId; }
1022 size_t getSubstitutionId() const { return _SubstitutionId; }
1024 void addZoneMarkerRef(CZoneMarker *zm) { _ZoneMarkerRef.insert(zm); }
1025 void removeZoneMarkerRef(CZoneMarker *zm) { _ZoneMarkerRef.erase(zm); }
1026 bool hasZoneMarkerRef() const { return !_ZoneMarkerRef.empty(); }
1028 virtual std::string getOneLineInfoString() const { return std::string("Group family '") + getName() + "'"; }
1030 private:
1031 /// @name AI service hierarchy
1032 //@{
1033 CAliasCont<CGroupDesc<CGroupFamily> > _GroupDescs;
1034 //@}
1036 TActivityList _Properties;
1037 NLMISC::TStringId _ProfileName;
1038 // If the family is a tribe, the property describe the name of the family (witch is the tribe name for tribe family)
1039 AITYPES::CPropertyId _FamilyTag;
1040 size_t _SubstitutionId;
1041 uint32 _Index;
1042 CAliasTreeOwner *_Owner;
1043 std::set<CZoneMarker *> _ZoneMarkerRef;
1048 //////////////////////////////////////////////////////////////////////////////
1049 // CGroupDesc //
1050 //////////////////////////////////////////////////////////////////////////////
1052 class IGroupDesc
1053 : public NLMISC::CRefCount
1055 public:
1056 virtual ~IGroupDesc() {}
1057 virtual uint32 groupEnergyValue() const = 0;
1058 virtual float groupEnergyCoef() const = 0;
1059 virtual bool getCountMultiplierFlag() const = 0;
1060 virtual uint32 getWeightForEnergy(size_t levelIndex) const = 0;
1061 virtual bool isValidForSeason(EGSPD::CSeason::TSeason const& season) const = 0;
1062 virtual AITYPES::CPropertySet& properties() = 0;
1063 virtual AITYPES::CPropertySet const& properties() const = 0;
1064 virtual std::string getFullName() const = 0;
1067 /// Description of a group template.
1068 template <class FamilyT>
1069 class CGroupDesc
1070 : public NLMISC::CDbgRefCount<CGroupDesc<FamilyT> >
1071 , public CAliasChild<FamilyT>
1072 , public IGroupDesc
1074 public:
1075 CGroupDesc(FamilyT* owner, uint32 alias, std::string const& name);
1077 std::string getIndexString() const;
1079 CAliasCont<CBotDesc<FamilyT> >& botDescs() { return _BotDescs; }
1080 CAliasCont<CBotDesc<FamilyT> > const& botDescs() const { return _BotDescs; }
1082 virtual std::string getFullName() const { return std::string(this->getOwner()->getFullName() +":"+ this->getName()); }
1084 virtual bool isValidForSeason(EGSPD::CSeason::TSeason const& season) const { return _SeasonFlags[season]; }
1086 bool isValidForDayOrNight(bool const& isDay) const;
1088 virtual AITYPES::CPropertySet& properties() { return _Properties; }
1089 virtual AITYPES::CPropertySet const& properties() const { return _Properties; }
1091 void setSheet(AISHEETS::ICreatureCPtr const& sheetPtr);
1093 bool setSheet(std::string const& sheetName);
1095 AISHEETS::ICreatureCPtr sheet(sint32 baseLevel = -1) const;
1097 virtual uint32 groupEnergyValue() const { return _GroupEnergyValue; }
1099 uint32 calcTotalEnergyValue() const;
1101 AITYPES::TSpawnType const& spawnType() const { return _SpawnType; }
1103 // Return the bot count as specified in the primitives data
1104 uint32 getBaseBotCount() const { return _BotCount; }
1106 // Set the bot count as specified in the primitives data
1107 void setBaseBotCount(uint32 const& botCount) { _BotCount = botCount; }
1109 // Return the 'real' bot count, ie the bot count multiplied by the creature sheet multiplier.
1110 // This is the number of bot we realy want to spawn.
1111 uint32 getRealBotCount() const;
1113 void setCountMultiplierFlag(bool countMultiplier) { _CountMultiplier = countMultiplier; }
1114 virtual bool getCountMultiplierFlag() const { return _CountMultiplier; }
1115 std::vector<std::string> const& grpParameters() const { return _GrpParameters; }
1116 std::vector<std::string>& grpParameters() { return _GrpParameters; }
1117 std::vector<std::string> const& botEquipment() const { return _BotEquipment; }
1118 std::vector<std::string>& botEquipment() { return _BotEquipment; }
1120 void setSeasonFlags(bool const seasonFlags[4]);
1121 void setWeightLevels(uint32 const weights[4]);
1123 void setSpawnType(AITYPES::TSpawnType const& spawnType) { _SpawnType = spawnType; }
1125 void setGroupEnergyCoef(float coef) { _EnergyCoef = coef; }
1127 virtual float groupEnergyCoef() const { return _EnergyCoef; }
1129 CGrpFauna* createFaunaGroup(CFamilyBehavior* familyBehavior) const;
1131 CGroupNpc* createNpcGroup(CMgrNpc* mgr, CAIVector const& pos, double dispersionRadius = 0., sint32 baseLevel = -1, bool spawnBots = true) const;
1133 virtual uint32 getWeightForEnergy(size_t levelIndex) const { return _WeightLevel[levelIndex]; }
1135 std::vector<CPopulationRecord>& populationRecords() { return _PopulationRecords; }
1137 // Don't really like this but have no time to do it on a member.
1138 sint getNbUse() const;
1140 bool getGDPlayerAttackable() const { return _PlayerAttackable; };
1141 void setGDPlayerAttackable(bool playerAttackable) const { _PlayerAttackable = playerAttackable; }
1143 bool getGDBotAttackable() const { return _BotAttackable; };
1144 void setGDBotAttackable(bool botAttackable) const { _BotAttackable = botAttackable; }
1145 void setMultiLevel(bool multiLevel) { _MultiLevel = multiLevel; }
1146 void setLevelDelta(sint32 levelDelta) { _LevelDelta = levelDelta; }
1147 sint32 getLevelDelta() const { return _LevelDelta; }
1148 bool isMultiLevel() const { return _MultiLevel; }
1150 private:
1151 /// @name AI service hierarchy
1152 //@{
1153 /// Container for named bot.
1154 CAliasCont<CBotDesc<FamilyT> > _BotDescs;
1155 //@}
1157 IAliasCont* getAliasCont(AITYPES::TAIType type);
1158 CAliasTreeOwner* createChild(IAliasCont* cont, CAIAliasDescriptionNode* aliasTree);
1160 /// The number of bot (for unamed bots)
1161 uint32 _BotCount;
1162 // If true, the _BotCount is multiplied by the quantity specified in the creature sheet.
1163 bool _CountMultiplier;
1165 // If the group is multilevel it has 20 sheets, else only one
1166 static size_t const _MultiLevelSheetCount;
1167 bool _MultiLevel;
1168 AISHEETS::ICreatureCPtr _Sheet;
1169 std::vector<AISHEETS::ICreatureCPtr> _MultiLevelSheets;
1170 sint32 _LevelDelta;
1172 /// The raw groups parameters
1173 std::vector<std::string> _GrpParameters;
1174 /// The raw bot equipment.
1175 std::vector<std::string> _BotEquipment;
1176 /// The season flags
1177 bool _SeasonFlags[4];
1179 uint32 _WeightLevel[4];
1181 /// The energy value of the group
1182 uint32 _GroupEnergyValue;
1184 /// Activity flags (for npcs)
1185 AITYPES::CPropertySet _Properties;
1187 /// Spawn type (for fauna)
1188 AITYPES::TSpawnType _SpawnType;
1189 // Energy Coef for bot of this group.
1190 float _EnergyCoef;
1192 std::vector<CPopulationRecord> _PopulationRecords;
1194 /** Flag to set the group attackable by players.
1195 * NB : this flag is set from the family code, not from the
1196 * primitives datas
1198 mutable bool _PlayerAttackable;
1199 // Flag to set the group attackable by other npcs
1200 mutable bool _BotAttackable;
1203 //////////////////////////////////////////////////////////////////////////////
1204 // CBotDesc //
1205 //////////////////////////////////////////////////////////////////////////////
1207 class IBotDesc {
1210 /// Description of a bot
1211 template <class FamilyT>
1212 class CBotDesc
1213 : public CAliasChild<CGroupDesc<FamilyT> >
1214 , public NLMISC::CRefCount
1215 , public IBotDesc
1217 public:
1218 CBotDesc(CGroupDesc<FamilyT>* owner, uint32 alias, std::string const& name);
1220 std::string getIndexString() const;
1222 void setSheet(AISHEETS::ICreatureCPtr const& sheetPtr)
1224 #ifdef NL_DEBUG
1225 nlassert(sheetPtr);
1226 #endif
1227 _Sheet = sheetPtr;
1230 void setSheet(std::string const& sheetName);
1232 AISHEETS::ICreatureCPtr sheet(sint32 baseLevel = -1) const;
1234 std::vector<std::string>& equipement() { return _Equipment; }
1236 uint32 energyValue() const;
1237 void setMultiLevel(bool multiLevel) { _MultiLevel = multiLevel; }
1238 void setLevelDelta(sint32 levelDelta) { _LevelDelta = levelDelta; }
1239 sint32 getLevelDelta() const { return _LevelDelta; }
1240 void setUseSheetBotName(bool useSheetBotName) { _UseSheetBotName = useSheetBotName; }
1242 std::string const& getBotName() const;
1244 private:
1245 /// Raw equipement
1246 std::vector<std::string> _Equipment;
1247 // If the bot is multilevel it has 20 sheets, else only one
1248 static size_t const _MultiLevelSheetCount;
1249 bool _MultiLevel;
1250 AISHEETS::ICreatureCPtr _Sheet;
1251 std::vector<AISHEETS::ICreatureCPtr> _MultiLevelSheets;
1252 sint32 _LevelDelta;
1253 bool _UseSheetBotName;
1256 //////////////////////////////////////////////////////////////////////////////
1257 // Free functions //
1258 //////////////////////////////////////////////////////////////////////////////
1260 bool pathFind(const CNpcZone *const start, const CNpcZone *const end, const AITYPES::CPropertySet &zoneFilter, std::vector<NLMISC::CSmartPtr<CRoad> > &path, bool logError=true);
1262 #endif // CONTINENT_H