// 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 FAMILY_BEHAVIOR_H
#define FAMILY_BEHAVIOR_H
#include "ai_share/ai_types.h"
#include "child_container.h"
#include "manager_parent.h"
#include "family_profile.h"
#include "ai_mgr_npc.h"
#include "ai_mgr_fauna.h"
#include "time_interface.h"
class CCellZone;
class CLevelEnergy : public NLMISC::CDbgRefCount
{
public:
CLevelEnergy ()
{
for (uint32 i=0;i<4;i++)
{
_LevelEnergyValue[i]=1.f;
}
}
CLevelEnergy (const CLevelEnergy &other)
{
for (uint32 i=0;i<4;i++)
{
_LevelEnergyValue[i]=other._LevelEnergyValue[i];
}
}
inline void setLevelEnergyValue (const double &v, const uint32 &index)
{
#ifdef NL_DEBUG
nlassert(index<=3);
#endif
if (index>3)
return;
_LevelEnergyValue[index]=v;
}
inline double levelEnergyValue (const uint32 &levelIndex) const
{
#ifdef NL_DEBUG
nlassert(levelIndex<=3);
#endif
if (levelIndex>3)
return 0;
return _LevelEnergyValue[levelIndex];
}
// protected:
private:
double _LevelEnergyValue[4];
};
/** Bot Family master behavior.
* This class contains state and ai profile for a family inside a cellzone.
* Also, there is a
*/
class CGroupFamily;
class CFamilyBehavior
: public NLMISC::CDbgRefCount
, public NLMISC::CRefCount
, public CChild
, public IManagerParent
, public CServiceEvent::CHandler
, public CAIEntity
{
public:
std::string getIndexString() const;
std::string getManagerIndexString(const CManager *child) const;
CFamilyBehavior(CCellZone *owner, const CGroupFamily *grpFamily); // ;const std::string &name, const NLMISC::TStringId &profileName)
virtual ~CFamilyBehavior()
{
_FamilyProfile = NULL;
_ManagerNpc = NULL;
_ManagerFauna = NULL;
}
CMgrNpc* mgrNpc()
{
#ifdef NL_DEBUG
nlassert(_ManagerNpc);
#endif
return _ManagerNpc;
}
CMgrFauna* mgrFauna()
{
#ifdef NL_DEBUG
nlassert(_ManagerFauna);
#endif
return _ManagerFauna;
}
bool isFamilyProfileValid() const
{
return _FamilyProfile!=NULL;
}
IFamilyProfile* familyProfile() const
{
return _FamilyProfile;
}
void updateManagers();
void update(uint32 nbTicks);
void displayLogOld(CStringWriter& stringWriter, bool detailled=false);
void displayLog(CStringWriter& stringWriter, int index, bool detailled, std::vector widths);
void checkLogWidths(std::vector& widths, int index, bool detailled);
static void displayLogLine(CStringWriter& stringWriter, int index, bool detailled, std::vector widths);
static void displayLogHeaders(CStringWriter& stringWriter, int index, bool detailled, std::vector widths);
static void checkLogHeadersWidths(std::vector& widths, int index, bool detailled);
// const AITYPES::TPopulationFamily &getFamily() const { return _Family; }
const AITYPES::CPropertyId &getFamilyTag() const
{
return _FamilyTag;
}
void serviceEvent (const CServiceEvent &info);
uint getStaticFameIndex()
{
return _Faction;
}
// NLMISC::CMustConsume CFamilyBehavior::getActivities (AITYPES::CPropertyId &food, AITYPES::CPropertyId &rest, bool &plante, const CGroupDesc*const gd) const;
void getActivities (AITYPES::CPropertySet &food, AITYPES::CPropertySet &rest/*, *bool &plante, const CGroupDesc*const gd*/) const;
void getNpcFlags(AITYPES::CPropertySet &flags);
// NLMISC::CMustConsume getActivities (AITYPES::TZoneActivity &food, AITYPES::TZoneActivity &rest, bool &plante, const CGroupDesc*const gd) const;
const uint32 &baseLevel () const
{
return _BaseLevel;
}
uint32 getLevelIndex () const
{
// check energy level
if (effectiveLevel()=0.25 <0.5
return 1;
}
else // >=0.5
{
if (effectiveLevel()=0.5 <0.75
return 2;
else // >=0.75
return 3;
}
}
const uint32 &effectiveLevel () const
{
return _EffectiveLevel;
}
void setBaseLevel (const uint32 &baseLevel)
{
_BaseLevel=baseLevel;
}
void setEffectiveLevel (const uint32 &effectiveLevel)
{
_EffectiveLevel=effectiveLevel;
}
/// Fill a vector of outpost id name assigned to tribe
void fillOutpostNames(std::vector outpostNames);
/// Add an outpost for the tribe (nb : the family must be a tribe)
void outpostAdd(NLMISC::TStringId outpostName);
/// Remove an from the tribe
void outpostRemove(NLMISC::TStringId outpostName);
void outpostEvent(NLMISC::TStringId outpostName, ZCSTATE::TZcState state);
void spawnBoss(NLMISC::TStringId outpostName);
uint32 energyScale (uint32 levelIndex=~0) const;
void setModifier (const float &value, const uint32 &index)
{
_Modifier[index]=value;
}
float getModifier (const uint32 &index) const
{
return _Modifier[index];
}
bool needUpdate () const
{
return getDt()>_UpdatePeriod;
}
NLMISC::TGameCycle getDt () const
{
return CTimeInterface::gameCycle()-_LastUpdateTime;
}
CGroupNpc *createNpcGroup(const CNpcZone *const zone, const CGroupDesc *const groupDesc);
uint32 _TheoricalLevel;
virtual std::string getName() const;
const NLMISC::CDbgPtr &grpFamily() const
{
return _GrpFamily;
}
bool spawn();
bool despawn();
virtual std::string getOneLineInfoString() const;
virtual std::vector getMultiLineInfoString() const;
private:
CAIInstance *getAIInstance() const;
virtual void addEnergy (uint32 energy);
virtual void removeEnergy (uint32 energy);
void groupDead(CGroup *grp);
// overloads for IManagerParent virtuals
CAIInstance &getAiInstance() const;
inline CCellZone *getCellZone()
{
return getOwner();
}
// If the family is a tribe, the property describe the name of the family (witch is the tribe name for tribe family)
AITYPES::CPropertyId _FamilyTag;
// AITYPES::TPopulationFamily _Family;
uint32 _Faction;
NLMISC::CSmartPtr _FamilyProfile;
/// A list of group to delete at the next master update.
std::vector > _GroupToDelete;
/// The base level. Come from a random at start of cycle.
uint32 _BaseLevel;
/// The effective level, computed from base level at start of cycle.
uint32 _EffectiveLevel;
/// The cumulated players actions effect.
uint32 _PlayerEffect;
/// The current energie level represented by the living population
/** The potential energy.
* This is a very special one. Each time a new group is spawn, the
* global energy value is added to this var.
* The value of this var always decay during time.
* The value is added to CurrentLevel before compare to EffectiveLevel.
* This avoid spawning lots of unneeded group because the
* spawn of the bots are delayed so they dont give value
* in CurrentLevel.
*/
uint32 _CurrentLevel;
NLMISC::CSmartPtr _ManagerNpc;
NLMISC::CSmartPtr _ManagerFauna;
// NLMISC::CstCDbgPtr _energyScale;
float _Modifier[4];
NLMISC::TGameCycle _LastUpdateTime;
uint32 _UpdatePeriod;
NLMISC::CDbgPtr _GrpFamily;
};
#endif // FAMILY_BEHAVIOR_H