// 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_PROFILE_TRIBE_H
#define FAMILY_PROFILE_TRIBE_H
extern NLMISC::CVariable LogOutpostDebug;
class CFamilyProfileTribe;
/// outpost information
class COutpostInfo
:public NLMISC::CRefCount
{
COutpostInfo (CFamilyBehavior *const familyBehavior, const CFamilyProfileTribe *const familyProfileTribe, const CNpcZone*const zoneNpc)
:_State(ZCSTATE::Tribe)
,_FamilyBehavior(familyBehavior)
,_FamilyProfileTribe(familyProfileTribe)
,_ZoneNpc(zoneNpc)
,_FightGroupExist(false)
,_BossGroupExist(false)
,_ContactGroupExist(false)
{
}
public:
static NLMISC::CSmartPtr createOutpost (CFamilyBehavior *const familyBehavior, const CFamilyProfileTribe *const familyProfileTribe, const NLMISC::TStringId &outpostName)
{
const CNpcZone *const zoneNpc=familyBehavior->getOwner()->lookupNpcZoneByName(/*familyBehavior->getFamily(), */NLMISC::CStringMapper::unmap(outpostName));
if ( !zoneNpc
|| !familyProfileTribe
|| !familyBehavior)
return NULL;
return new COutpostInfo(familyBehavior, familyProfileTribe, zoneNpc);
}
typedef std::vector > TGroupList;
virtual ~COutpostInfo()
{
for (TGroupList::iterator it=_FightGroup.begin(), itEnd=_FightGroup.end();it!=itEnd;++it)
{
NLMISC::CDbgPtr &dbgPtr=*it;
if (!dbgPtr.isNULL())
dbgPtr->despawnGrp();
}
for (TGroupList::iterator it=_ContactGroups.begin(), itEnd=_ContactGroups.end();it!=itEnd;++it)
{
NLMISC::CDbgPtr &dbgPtr=*it;
if (!dbgPtr.isNULL())
dbgPtr->despawnGrp();
}
if (!_BossGroup.isNULL())
{
_BossGroup->despawnGrp();
}
}
void spawnBoss ();
void outpostEvent (ZCSTATE::TZcState state);
void updateOutPostInfo ();
void fightGroups(bool exist);
void bossGroups(bool exist);
void contactGroups(bool exist);
void addToDespawnGroupList (CSpawnGroupNpc *grpNpc)
{
grpNpc->activityProfile().setAIProfile(NULL); // remove comportment.
_DespawnList.push_back(&grpNpc->getPersistent());
}
void checkDespawnGroupList ();
private:
/// The npc zone for the outpost
NLMISC::CstCDbgPtr _ZoneNpc;
/// The current outpost state.
ZCSTATE::TZcState _State;
TGroupList _ContactGroups;
/// Fight Groups.
TGroupList _FightGroup;
TGroupList _DespawnList;
/// Pointer on the boss group when present.
NLMISC::CDbgPtr _BossGroup;
NLMISC::CDbgPtr _FamilyBehavior;
NLMISC::CDbgPtr _FamilyProfileTribe;
public:
bool _FightGroupExist;
bool _BossGroupExist;
bool _ContactGroupExist;
};
class CFamilyProfileTribe
:public NLMISC::CDbgRefCount
,public IFamilyProfile
{
/// The zone that is used as camp for the tribe.
NLMISC::CSmartPtr _CampZone; // smart to have a counter on NpcZone. (Bad but no time to do better).
/// The contact group in the camp
NLMISC::CstCDbgPtr _CampContact;
public:
std::vector _AggroGroupIds;
CFamilyProfileTribe (const CtorParam &ctorParam);
virtual ~CFamilyProfileTribe ()
{
}
CFamilyBehavior *getFamilyBehavior ()
{
return _FamilyBehavior;
}
/// The zone that is used as camp for the tribe.
const NLMISC::CSmartPtr &getCampZone() const
{
return _CampZone;
}
void setCampZone (const CNpcZone *campZone)
{
_CampZone=campZone;
}
void spawnBoss(NLMISC::TStringId outpostName);
void setDefaultProfile(const CNpcZone *const zone, CGroupNpc *grp);
typedef std::map > TOutpostContainer;
TOutpostContainer _OutpostInfos;
void fillOutpostNames(std::vector outpostNames)
{
outpostNames.clear();
for (TOutpostContainer::const_iterator first(_OutpostInfos.begin()), last(_OutpostInfos.end()); first != last; ++first)
outpostNames.push_back(first->first);
}
void outpostAdd(NLMISC::TStringId outpostName);
void outpostRemove(NLMISC::TStringId outpostName);
void outpostEvent(NLMISC::TStringId outpostName, ZCSTATE::TZcState state)
{
TOutpostContainer::iterator it(_OutpostInfos.find(outpostName));
if (it==_OutpostInfos.end())
return;
// nlassert(it != _OutpostInfos.end());
it->second->outpostEvent(state);
};
void spawnGroup();
/// The main update for the profile. Called aprox every 10 s (100 ticks)
void update();
};
extern IAiFactory *_ProfileTribe;
//---------------------------------------------------------------------------------
// CGrpProfileDynContact
//---------------------------------------------------------------------------------
//
//
class CGrpProfileDynContact
: public CGrpProfileNormal
{
public:
CGrpProfileDynContact(CProfileOwner *const owner, CFamilyProfileTribe *const familyProfile, COutpostInfo *const outPostInfo, bool isTheContactGroup=false)
:CGrpProfileNormal(owner)
,_FamilyProfile(familyProfile)
,_isTheContactGroup(isTheContactGroup)
,_OutPostInfo(outPostInfo)
{
_CurrentZone=_FamilyProfile->getCampZone();
// this group can't be despawnded
_Grp->getPersistent().setDiscardable(!isTheContactGroup);
}
virtual ~CGrpProfileDynContact()
{
}
//---------------------------------------------------------------------------------------------------------
// virtual routines used to mange behaviour of bot
// note that this code is responsible for setting the 'nextActivity' bot property and may modify
// the 'activityTimer' property - may also set the 'nextTarget' property
// routine called when a bot starts to use a given profile
// note that bots have a data member called 'void *aiProfileData' reserved for the use of the profile code
// this data member should be setup here if it is to be used by the profile
virtual void beginProfile();
// routine called just before bot starts to use a new profile or when a bot dies
virtual void endProfile();
// routine called every time the bot is updated (frequency depends on player proximity, etc)
virtual void updateProfile(uint ticksSinceLastUpdate);
// routine used to build a debug string for detailed information on a bot's status (with respect to their aiProfile)
virtual std::string buildDebugString() const;
virtual AITYPES::TProfiles getAIProfileType () const
{
return AITYPES::ACTIVITY_CONTACT;
}
void gotoZone(const CNpcZone *const zone, const AITYPES::CPropertySet &flags);
private:
COutpostInfo *const _OutPostInfo;
CFamilyProfileTribe *const _FamilyProfile;
NLMISC::CstCDbgPtr _CurrentZone;
const bool _isTheContactGroup;
};
//---------------------------------------------------------------------------------
// CGrpProfileDynHarvest
//---------------------------------------------------------------------------------
class CGrpProfileDynHarvest: public CGrpProfileNormal
{
public:
CGrpProfileDynHarvest(CProfileOwner *const owner, CFamilyProfileTribe *const familyProfile, const CNpcZone *const harvestZone, const CNpcZone *const currentZone)
:CGrpProfileNormal(owner)
,_FamilyProfile(familyProfile)
,_HarvestZone(harvestZone)
{
_CurrentZone=currentZone;
}
virtual ~CGrpProfileDynHarvest()
{
}
//---------------------------------------------------------------------------------------------------------
// virtual routines used to mange behaviour of bot
// note that this code is responsible for setting the 'nextActivity' bot property and may modify
// the 'activityTimer' property - may also set the 'nextTarget' property
// routine called when a bot starts to use a given profile
// note that bots have a data member called 'void *aiProfileData' reserved for the use of the profile code
// this data member should be setup here if it is to be used by the profile
virtual void beginProfile();
// routine called just before bot starts to use a new profile or when a bot dies
virtual void endProfile();
// routine called every time the bot is updated (frequency depends on player proximity, etc)
virtual void updateProfile(uint ticksSinceLastUpdate);
void checkTargetsAround ();
// routine used to build a debug string for detailed information on a bot's status (with respect to their aiProfile)
virtual std::string buildDebugString() const;
virtual AITYPES::TProfiles getAIProfileType () const
{
return AITYPES::ACTIVITY_HARVEST;
}
private:
CAITimer _checkTargetTimer;
CFamilyProfileTribe *const _FamilyProfile;
NLMISC::CstCDbgPtr _CurrentZone;
NLMISC::CstCDbgPtr const _HarvestZone;
};
//---------------------------------------------------------------------------------
// CGrpProfileDynHarvest
//---------------------------------------------------------------------------------
//---------------------------------------------------------------------------------
// CGrpProfileDynFight
//---------------------------------------------------------------------------------
//
//
class CGrpProfileDynFight: public CGrpProfileNormal
{
public:
CGrpProfileDynFight(CProfileOwner *const owner, CFamilyProfileTribe *const familyProfile, const CNpcZone*const zone, COutpostInfo *const outPostInfo)
:CGrpProfileNormal(owner)
,_FamilyProfile(familyProfile)
,_CurrentZone(zone)
,_OutPostInfo(outPostInfo)
{
}
virtual ~CGrpProfileDynFight()
{
}
//---------------------------------------------------------------------------------------------------------
// virtual routines used to mange behaviour of bot
// note that this code is responsible for setting the 'nextActivity' bot property and may modify
// the 'activityTimer' property - may also set the 'nextTarget' property
// routine called when a bot starts to use a given profile
// note that bots have a data member called 'void *aiProfileData' reserved for the use of the profile code
// this data member should be setup here if it is to be used by the profile
virtual void beginProfile();
// routine called just before bot starts to use a new profile or when a bot dies
virtual void endProfile();
// routine called every time the bot is updated (frequency depends on player proximity, etc)
virtual void updateProfile(uint ticksSinceLastUpdate);
// routine used to build a debug string for detailed information on a bot's status (with respect to their aiProfile)
virtual std::string buildDebugString() const;
virtual AITYPES::TProfiles getAIProfileType () const
{
return AITYPES::ACTIVITY_FIGHT;
}
void gotoZone(const CNpcZone *const zone, const AITYPES::CPropertySet &flags);
private:
COutpostInfo *const _OutPostInfo;
CFamilyProfileTribe *const _FamilyProfile;
NLMISC::CstCDbgPtr _CurrentZone;
};
#endif