khanat-opennel-code/code/ryzom/server/src/ai_service/commands.h
2010-05-06 02:08:41 +02:00

619 lines
15 KiB
C++

// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// 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 <http://www.gnu.org/licenses/>.
#ifndef RYAI_COMMANDS_H
#define RYAI_COMMANDS_H
#include <string>
//////////////////////////////////////////////////////////////////////////////
// CStringFilter //
//////////////////////////////////////////////////////////////////////////////
/// Match name according '*' and '?' DOS properties.
class CStringFilter
{
public:
CStringFilter(std::string const& filter)
: _Filter(filter)
{
}
virtual ~CStringFilter() { }
bool operator !=(std::string const& other) const { return !operator ==(other); }
bool operator ==(std::string const& other) const { return NLMISC::testWildCard(other, _Filter); }
private:
std::string _Filter;
};
//////////////////////////////////////////////////////////////////////////////
// Entity filters //
//////////////////////////////////////////////////////////////////////////////
/*
AIS hierarchy:
CAIS
+- CAIInstance
+- COutpostSquadFamily
| \- CGroupDesc<COutpostSquadFamily>
| \- CBotDesc<COutpostSquadFamily>
+- CContinent
| +- CRegion
| | +- CCellZone
| | | \- CCell
| | | +- CFaunaZone
| | | \- CRoad
| | | \- CRoadTrigger
| | +- CGroupFamily
| | | \- CGroupDesc<CGroupFamily>
| | | \- CBotDesc<CGroupFamily>
| | \- CFamilyBehavior
| | +- CMgrNpc : CManager
| | | \- CGroup
| | | \- CBot
| | \- CMgrFauna : CManager
| | \- CGroup
| | \- CBot
| \- COutpost
| +- COutpostSpawnZone
| \- COutpostManager : CManager
| \- CGroup
| \- CBot
\- CManager
\- CGroup
\- CBot
*/
//- Fetchers -----------------------------------------------------------------
template <class TContainer>
void buildInstanceList(TContainer& container)
{
FOREACH(itAIInstance, CCont<CAIInstance>, CAIS::instance().AIList())
{
CAIInstance* aiinstance = *itAIInstance;
container.push_back(aiinstance);
}
}
template <class TContainer>
void buildContinentList(TContainer& container)
{
std::deque<CAIInstance*> aiinstances;
buildInstanceList(aiinstances);
FOREACH(itAIInstance, std::deque<CAIInstance*>, aiinstances)
{
CAIInstance* aiinstance = *itAIInstance;
if (aiinstance == NULL)
continue;
FOREACH(itContinent, CCont<CContinent>, aiinstance->continents())
{
CContinent* continent = *itContinent;
container.push_back(continent);
}
}
}
template <class TContainer>
void buildRegionList(TContainer& container)
{
std::deque<CContinent*> continents;
buildContinentList(continents);
FOREACH(itContinent, std::deque<CContinent*>, continents)
{
CContinent* continent = *itContinent;
if (continent == NULL)
continue;
FOREACH(itRegion, CCont<CRegion>, continent->regions())
{
CRegion* region = *itRegion;
container.push_back(region);
}
}
}
template <class TContainer>
void buildCellZoneList(TContainer& container)
{
std::deque<CRegion*> regions;
buildRegionList(regions);
FOREACH(itRegion, std::deque<CRegion*>, regions)
{
CRegion* region = *itRegion;
if (region == NULL)
continue;
FOREACH(itCellZone, CCont<CCellZone>, region->cellZones())
{
CCellZone* cellZone = *itCellZone;
container.push_back(cellZone);
}
}
}
template <class TContainer>
void buildFamilyBehaviorList(TContainer& container)
{
std::deque<CCellZone*> cellZones;
buildCellZoneList(cellZones);
FOREACH(itCellZone, std::deque<CCellZone*>, cellZones)
{
CCellZone* cellZone = *itCellZone;
if (cellZone == NULL)
continue;
FOREACH(itFamilyBehavior, CCont<CFamilyBehavior>, cellZone->familyBehaviors())
{
CFamilyBehavior* familyBehavior = *itFamilyBehavior;
container.push_back(familyBehavior);
}
}
}
template <class TContainer>
void buildOutpostList(TContainer& container)
{
std::deque<CContinent*> continents;
buildContinentList(continents);
FOREACH(itContinent, std::deque<CContinent*>, continents)
{
CContinent* continent = *itContinent;
if (continent == NULL)
continue;
FOREACH(itOutpost, CCont<COutpost>, continent->outposts())
{
COutpost* outpost = *itOutpost;
container.push_back(outpost);
}
}
}
template <class TContainer>
void buildManagerList(TContainer& container)
{
std::deque<CFamilyBehavior*> familyBehaviors;
buildFamilyBehaviorList(familyBehaviors);
FOREACH(itFamilyBehavior, std::deque<CFamilyBehavior*>, familyBehaviors)
{
CFamilyBehavior* familyBehavior = *itFamilyBehavior;
if (familyBehavior == NULL)
continue;
container.push_back(static_cast<CManager*>(familyBehavior->mgrNpc()));
container.push_back(static_cast<CManager*>(familyBehavior->mgrFauna()));
}
std::deque<CAIInstance*> aiinstances;
buildInstanceList(aiinstances);
FOREACH(itAIInstance, std::deque<CAIInstance*>, aiinstances)
{
CAIInstance* aiinstance = *itAIInstance;
if (aiinstance == NULL)
continue;
FOREACH(itManager, CCont<CManager>, aiinstance->managers())
{
CManager* manager = *itManager;
container.push_back(manager);
}
}
std::deque<COutpost*> outposts;
buildOutpostList(outposts);
FOREACH(itOutpost, std::deque<COutpost*>, outposts)
{
COutpost* outpost = *itOutpost;
if (outpost == NULL)
continue;
FOREACH(itManager, CCont<COutpostManager>, outpost->managers())
{
CManager* manager = static_cast<CManager*>(*itManager);
container.push_back(manager);
}
}
}
template <class TContainer>
void buildGroupList(TContainer& container)
{
std::deque<CManager*> managers;
buildManagerList(managers);
FOREACH(itManager, std::deque<CManager*>, managers)
{
CManager* manager = *itManager;
if (manager == NULL)
continue;
FOREACH(itGroup, CCont<CGroup>, manager->groups())
{
CGroup* group = *itGroup;
container.push_back(group);
}
}
}
template <class TContainer>
bool buildFilteredGroupList(TContainer& container, std::string filterString)
{
typedef typename TContainer::value_type TValue;
std::deque<TValue> _container;
buildGroupList(_container);
FOREACHC(it, typename std::deque<TValue>, _container)
{
typename TContainer::value_type value = *it;
if (value == NULL)
continue;
CStringFilter filter(filterString);
if (!isIdentifiedAs(*value, filter))
continue;
container.push_back(value);
}
return true;
}
template <class TContainer>
void buildBotList(TContainer& container)
{
std::deque<CGroup*> groups;
buildGroupList(groups);
FOREACH(itGroup, std::deque<CGroup*>, groups)
{
CGroup* group = *itGroup;
if (group == NULL)
continue;
FOREACH(itBot, CCont<CBot>, group->bots())
{
CBot* bot = *itBot;
container.push_back(bot);
}
}
}
template <class TContainer>
bool buildFilteredBotList(TContainer& container, std::string filterString)
{
typedef typename TContainer::value_type TValue;
std::deque<TValue> _container;
buildBotList(_container);
FOREACHC(it, typename std::deque<TValue>, _container)
{
typename TContainer::value_type value = *it;
if (value == NULL)
continue;
CStringFilter filter(filterString);
if (!isIdentifiedAs(*value, filter))
continue;
container.push_back(value);
}
return true;
}
template <class TContainer>
void buildPlayerList(TContainer& container)
{
std::deque<CAIInstance*> aiinstances;
buildInstanceList(aiinstances);
FOREACH(itAIInstance, std::deque<CAIInstance*>, aiinstances)
{
CAIInstance* aiinstance = *itAIInstance;
if (!aiinstance)
continue;
CManagerPlayer* manager = aiinstance->getPlayerMgr();
if (!manager)
continue;
FOREACH(itPlayer, CManagerPlayer::TPlayerMap, manager->playerList())
{
CBotPlayer* player = itPlayer->second;
container.push_back(player);
}
}
}
template <class TContainer>
void buildFaunaPlaceList(TContainer& container)
{
std::deque<CGroup *> groups;
buildGroupList(groups);
FOREACH(itGroup, std::deque<CGroup*>, groups)
{
CGrpFauna *grpFauna = dynamic_cast<CGrpFauna *>(*itGroup);
if (!grpFauna)
continue;
FOREACH(itPlaces, CAliasCont<CAIPlace>, grpFauna->places())
{
container.push_back(*itPlaces);
}
}
}
//- Selector -----------------------------------------------------------------
template <class TValue>
bool isIdentifiedAs(TValue const& value, CStringFilter const& filter)
{
if (filter==value.getIndexString())
return true;
return false;
}
template <>
inline
bool isIdentifiedAs<CBot>(CBot const& value, CStringFilter const& filter)
{
if (filter==value.getIndexString())
return true;
if (filter==value.getEntityIdString())
return true;
if (filter==value.getAliasString())
return true;
if (filter==value.getName())
return true;
if (filter==value.getFullName())
return true;
return false;
}
template <>
inline
bool isIdentifiedAs<CGroup>(CGroup const& value, CStringFilter const& filter)
{
if (filter==value.getIndexString())
return true;
if (filter==value.getAliasString())
return true;
if (filter==value.getName())
return true;
if (filter==value.getFullName())
return true;
return false;
}
template <>
inline
bool isIdentifiedAs<CManager>(CManager const& value, CStringFilter const& filter)
{
if (filter==value.getIndexString())
return true;
if (filter==value.getAliasString())
return true;
if (filter==value.getName())
return true;
if (filter==value.getFullName())
return true;
return false;
}
template <>
inline
bool isIdentifiedAs<CBotPlayer>(CBotPlayer const& value, CStringFilter const& filter)
{
if (filter==value.getIndexString())
return true;
if (filter==value.getEntityIdString())
return true;
return false;
}
template <>
inline
bool isIdentifiedAs<CAIInstance>(CAIInstance const& value, CStringFilter const& filter)
{
if (filter==value.getIndexString())
return true;
if (filter==value.getContinentName())
return true;
return false;
}
template <>
inline
bool isIdentifiedAs<CContinent>(CContinent const& value, CStringFilter const& filter)
{
if (filter==value.getIndexString())
return true;
if (filter==value.getName())
return true;
return false;
}
template <>
inline
bool isIdentifiedAs<CRegion>(CRegion const& value, CStringFilter const& filter)
{
if (filter==value.getIndexString())
return true;
if (filter==value.getName())
return true;
return false;
}
template <>
inline
bool isIdentifiedAs<CCellZone>(CCellZone const& value, CStringFilter const& filter)
{
if (filter==value.getIndexString())
return true;
if (filter==value.getName())
return true;
return false;
}
template <>
inline
bool isIdentifiedAs<CFamilyBehavior>(CFamilyBehavior const& value, CStringFilter const& filter)
{
if (filter==value.getIndexString())
return true;
if (filter==value.grpFamily()->getName())
return true;
return false;
}
//- Functors -----------------------------------------------------------------
template <class TValue>
void display(TValue& value, NLMISC::CLog& log)
{
log.displayNL("%s %s", value.getIndexString().c_str(), value.getOneLineInfoString().c_str());
}
template <class TValue>
void displayEx(TValue& value, NLMISC::CLog& log)
{
std::vector<std::string> strings = value.getMultiLineInfoString();
FOREACHC(itString, std::vector<std::string>, strings)
log.displayNL("%s", itString->c_str());
}
template <class TValue>
void spawn(TValue& value)
{
value.spawn();
}
template <class TValue>
void despawn(TValue& value)
{
value.despawn();
}
//- Specialized functors -----------------------------------------------------
template <>
inline
void despawn(CGroup& value)
{
value.despawnGrp();
}
template <>
inline
void despawn(CManager& value)
{
value.despawnMgr();
}
// CFaunaGenericPlace specialization
inline
void spawn(CAIPlace &value)
{
CFaunaGenericPlace *fgp = dynamic_cast<CFaunaGenericPlace *>(&value);
if (fgp)
{
if (!fgp->getTimeDriven())
{
fgp->setActive(true);
}
else
{
nlwarning("Places %s is not time driven, cannot activate it", value.getIndexString().c_str());
}
}
}
inline
void despawn(CAIPlace &value)
{
CFaunaGenericPlace *fgp = dynamic_cast<CFaunaGenericPlace *>(&value);
if (fgp)
{
if (!fgp->getTimeDriven())
{
fgp->setActive(false);
}
else
{
nlwarning("Places %s is not time driven, cannot deactivate it", value.getIndexString().c_str());
}
}
}
//- Top-level functions ------------------------------------------------------
template <class TContainer>
void displayList(NLMISC::CLog& log, TContainer const& container, std::string filterString = std::string("*"))
{
FOREACHC(it, typename TContainer, container)
{
typename TContainer::value_type value = *it;
if (value == NULL)
continue;
CStringFilter filter(filterString);
if (!isIdentifiedAs(*value, filter))
continue;
display(*value, log);
}
}
template <class TContainer>
void displayListEx(NLMISC::CLog& log, TContainer const& container, std::string filter = std::string("*"))
{
CLogStringWriter stringWriter(&log);
FOREACHC(it, typename TContainer, container)
{
typename TContainer::value_type value = *it;
if (value == NULL)
continue;
if (!isIdentifiedAs(*value, filter))
continue;
displayEx(*value, log);
}
}
template <class TContainer>
void spawnList(NLMISC::CLog& log, TContainer const& container, std::string filterString = std::string("*"))
{
FOREACHC(it, typename TContainer, container)
{
typename TContainer::value_type value = *it;
if (value == NULL)
continue;
CStringFilter filter(filterString);
if (!isIdentifiedAs(*value, filter))
continue;
spawn(*value);
}
}
template <class TContainer>
void despawnList(NLMISC::CLog& log, TContainer const& container, std::string filterString = std::string("*"))
{
FOREACHC(it, typename TContainer, container)
{
typename TContainer::value_type value = *it;
if (value == NULL)
continue;
CStringFilter filter(filterString);
if (!isIdentifiedAs(*value, filter))
continue;
despawn(*value);
}
}
//- NeL commands -------------------------------------------------------------
#define RYAI_TEMPLATED_COMMAND(__name,__help,__args,__type,__fetchmethod,__functor) \
NLMISC_COMMAND(__name,__help,__args) \
{ \
std::deque<__type*> container; \
__fetchmethod(container); \
if (args.size()>0) \
__functor(log, container, args[0]); \
else \
__functor(log, container); \
return true; \
}
#endif