// 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 .
// Nel Misc
#include "nel/misc/command.h"
#include "nel/misc/variable.h"
#include "nel/misc/file.h"
#include "nel/misc/i_xml.h"
#include "nel/misc/path.h"
#include "nel/misc/algo.h"
// Local includes
#include "ags_test.h"
#include "actor.h"
#include "actor_manager.h"
#include "macro_manager.h"
#include "position_generator.h"
#include "sheets.h"
#include "mirrors.h"
#include "ai_mgr.h"
#include "nel/ligo/primitive.h"
using namespace NLMISC;
using namespace NLNET;
using namespace std;
namespace AGS_TEST
{
//-------------------------------------------------------------------------
// Some global variables
uint32 GlobalActorCount=0;
uint32 GlobalActorUpdates=0;
uint32 GlobalActorMoves=0;
NLMISC_VARIABLE(uint32, GlobalActorCount, "actors");
NLMISC_VARIABLE(uint32, GlobalActorUpdates, "updates");
NLMISC_VARIABLE(uint32, GlobalActorMoves, "moves");
//-------------------------------------------------------------------------
// some globals local to this file
static CActor::EActivity DefaultActivity = CActor::SQUARE;
static NLLIGO::CPrimZone * DefaultPatatEvolution = 0;
static float DefaultOrientation = 0.0f;
static float DefaultMagnetRange = 50.0f;
static float DefaultMagnetDecay = 10.0f;
static float DefaultAttackDistance = 0.0f;
static std::string DefaultBehaviour;
static int DefaultDialogue = 0;
static float DefaultMinSpawnTime = 25.0f;
static float DefaultMaxSpawnTime = 25.0f;
static map PrimOrigin; // map of prim points and zones to prim filename
static std::string SpawnName; // name or coordinates of the spawn point
static CAiMgrFile * AIFile=0; // the file to which ai managers are to be added
static CAiMgrInstance * AIManager=0; // the ai manager to which entities are to be added
static CAiMgrPopulation * AIPopulation=0; // the ai manager to which entities are to be added
//-------------------------------------------------------------------------
// some stuff for manageing the output of AI_MANAGER files
CAiMgrFile *CurrentAiMgrFile;
CAiMgrInstance *CurrentAiMgrInstance;
//-------------------------------------------------------------------------
// CLEANING AND INITIALISING THE SYSTEM
// Command for resetting the system
NLMISC_COMMAND(actorReset,"Remove all actors and reset the actor system","")
{
COMMAND_MACRO_RECORD_TEST
CActorManager::release();
CActorManager::init();
GlobalActorCount = 0;
return true;
}
/*
// Command for removing actors
NLMISC_COMMAND(actorRemove,"Kill one or more actors"," [...]")
{
if(args.size() <1) return false;
COMMAND_MACRO_RECORD_TEST
// iterate through the actor names
for (unsigned i=0;i")
{
if(args.size() !=1) return false;
CIFile f(CPath::lookup(args[0]));
NLLIGO::CPrimRegion region;
CIXml xml;
xml.init(f);
region.serial(xml);
uint i;
// adding zones to move manager
for (i=0; i prim file
for (i=0; i [...]")
{
if(args.size() <1) return false;
COMMAND_MACRO_RECORD_TEST
if (args[0]==std::string("grid") && args.size()==1)
{}
else if (args[0]==std::string("line") && args.size()==1)
{}
else if (args[0]==std::string("line") && args.size()==2)
CPositionGenerator::setSpacing(atoi(args[0].c_str()));
else
return false;
CPositionGenerator::setPattern(args[0]);
return true;
}
// Command for configuring how actors are placed on landscape
NLMISC_COMMAND(actorCreateSpacing,"Setup spacing for new actors","")
{
if(args.size() !=1) return false;
COMMAND_MACRO_RECORD_TEST
CPositionGenerator::setSpacing(atoi(args[0].c_str()));
return true;
}
// Command for configuring how actors are placed on landscape
NLMISC_COMMAND(actorCreatePosition,"Setup start position for new actors"," []")
{
COMMAND_MACRO_RECORD_TEST
switch(args.size())
{
case 0:
return false;
case 1:
CPositionGenerator::setPosition(args[0].c_str());
SpawnName=args[0];
break;
case 3:
CPositionGenerator::setSpacing(atoi(args[2].c_str()));
// no break - drop through!
case 2:
CPositionGenerator::setPosition(atoi(args[0].c_str()), atoi(args[1].c_str()));
SpawnName=args[0]+" "+args[1];
break;
default:
return false;
}
return true;
}
//-------------------------------------------------------------------------
// CREATING ACTORS
static CActor *createActor(std::string type,std::string name)
{
CActor *theNewActor=CActorManager::newActor(type,name);
if (theNewActor)
{
theNewActor->setActivity (DefaultActivity);
theNewActor->setPrimZone (DefaultPatatEvolution);
theNewActor->setAngle (DefaultOrientation);
theNewActor->setMagnetRange (DefaultMagnetRange,DefaultMagnetDecay);
theNewActor->setBehaviour (DefaultBehaviour);
theNewActor->setAttackDistance (DefaultAttackDistance);
theNewActor->setChatSet (DefaultDialogue);
}
return theNewActor;
}
void addPopulation(std::string type,std::string name,uint count)
{
// if no file has been opened yet then create one
if (AIFile==0)
{
AIFile=new CAiMgrFile;
AIFile->setName(std::string("ags_test.ai_manager"));
CAiMgr::addFile(AIFile);
}
// create a new ai_manager instance
AIManager= new CAiMgrInstance;
AIFile->addChild(AIManager);
AIManager->setName(name);
AIManager->setCreatureLimit(count);
if (DefaultPatatEvolution!=0)
AIManager->setBoundary(DefaultPatatEvolution->getName());
// add a population record
AIPopulation=new CAiMgrPopulation;
AIManager->addPopulation(AIPopulation);
AIPopulation->setName(name);
AIPopulation->setOrientation(DefaultOrientation);
AIPopulation->setQuantity(count);
AIPopulation->setSpawnRate(int(DefaultMinSpawnTime*1000.0),int(DefaultMaxSpawnTime*1000.0));
AIPopulation->setType(NLMISC::CSheetId(type));
// add a spawn location
CAiMgrSpawn *spawn=new CAiMgrSpawn;
AIManager->addSpawn(spawn);
spawn->setPlace(SpawnName);
// check whether the spawn or evolution patats are in an unrefferenced prim file
if (PrimOrigin.find(CPositionGenerator::getSpawnName())!=PrimOrigin.end())
{
if (AIFile->getPrim().empty())
AIFile->setPrim(PrimOrigin[CPositionGenerator::getSpawnName()]);
else
if (AIFile->getPrim()!=PrimOrigin[CPositionGenerator::getSpawnName()])
nlwarning("WARNING: Can only apply one prim file per AI manager - spawn '%s' in '%s' NOT '%s'",
CPositionGenerator::getSpawnName().c_str(),
PrimOrigin[CPositionGenerator::getSpawnName()].c_str(),
AIFile->getPrim().c_str() );
}
if (DefaultPatatEvolution!=0)
if (PrimOrigin.find(DefaultPatatEvolution->getName())!=PrimOrigin.end())
{
if (AIFile->getPrim().empty())
AIFile->setPrim(PrimOrigin[DefaultPatatEvolution->getName()]);
else
if (AIFile->getPrim()!=PrimOrigin[DefaultPatatEvolution->getName()])
nlwarning("WARNING: Can only apply one prim file per AI manager - spawn '%s' in '%s' NOT '%s'",
DefaultPatatEvolution->getName().c_str(),
PrimOrigin[DefaultPatatEvolution->getName()].c_str(),
AIFile->getPrim().c_str() );
}
}
// Command for creating actors
NLMISC_COMMAND(actorCreate,"Add one or more moving actors"," [...]")
{
if(args.size() <2) return false;
COMMAND_MACRO_RECORD_TEST
// store the population information in an AI_MGR file record
addPopulation(args[0],args[1],args.size()-1);
// iterate through the actor names
for (unsigned i=1;isetActivity (DefaultActivity);
theNewActor->setPrimZone (DefaultPatatEvolution);
theNewActor->setAngle (DefaultOrientation);
theNewActor->setMagnetRange (DefaultMagnetRange,DefaultMagnetDecay);
theNewActor->setBehaviour (DefaultBehaviour);
theNewActor->setAttackDistance (DefaultAttackDistance);
theNewActor->setChatSet (DefaultDialogue);
*/
CActor *theNewActor=createActor(args[0],args[i]);
}
return true;
}
// Command for creating actors
NLMISC_COMMAND(actorCreateCustom,"Add one or more moving actors"," [ [-act ] [-pos ] [-ctop ] [-cbot ] [-chair ] [-rhand ] [-lhand ] ] [...]")
{
if(args.size() <2) return false;
COMMAND_MACRO_RECORD_TEST
/*
uint i;
for (i=1; i")
{
if(args.size()!=3 || atoi(args[2].c_str())<=0 || atoi(args[2].c_str())>1024) return false;
COMMAND_MACRO_RECORD_TEST
CActorGroup *theNewGroup=CActorManager::newActorGroup(args[1]);
// store the population information in an AI_MGR file record
addPopulation(args[0],args[1],atoi(args[2].c_str()));
// iterate through the actor names
for (int i=0;iactorCount()));
theNewActor->setActivity (DefaultActivity);
theNewActor->setPrimZone (DefaultPatatEvolution);
theNewActor->setAngle (DefaultOrientation);
theNewActor->setMagnetRange (DefaultMagnetRange,DefaultMagnetDecay);
theNewActor->setBehaviour (DefaultBehaviour);
theNewActor->setAttackDistance (DefaultAttackDistance);
theNewActor->setChatSet (DefaultDialogue);
*/
CActor *theNewActor=createActor(args[0],args[1]+toString(theNewGroup->actorCount()));
if (theNewActor)
theNewGroup->addActor(theNewActor);
}
return true;
}
// Command for creating actors
NLMISC_COMMAND(actorCreateMoving,"Add one or more static actors"," [...]")
{
if(args.size() ==1) return false;
COMMAND_MACRO_RECORD_TEST
if (args.size()==0)
{
// no actor names specified so setup the default value to apply to new actors
DefaultActivity = CActor::SQUARE;
}
else
{
// store the population information in an AI_MGR file record
addPopulation(args[0],args[1],args.size()-1);
// iterate through the actor names
for (unsigned i=1;isetPrimZone (DefaultPatatEvolution);
theNewActor->setAngle (DefaultOrientation);
theNewActor->setMagnetRange (DefaultMagnetRange,DefaultMagnetDecay);
theNewActor->setBehaviour (DefaultBehaviour);
theNewActor->setAttackDistance (DefaultAttackDistance);
theNewActor->setChatSet (DefaultDialogue);
*/
CActor *theNewActor=createActor(args[0],args[i]);
if (theNewActor)
{
theNewActor->doSquare();
theNewActor->setActivity(CActor::SQUARE);
}
}
}
return true;
}
// Command for creating actors
NLMISC_COMMAND(actorCreateStationary,"Add one or more static actors"," [...]")
{
if(args.size() ==1) return false;
COMMAND_MACRO_RECORD_TEST
if (args.size()==0)
{
// no actor names specified so setup the default value to apply to new actors
DefaultActivity = CActor::NOTHING;
}
else
{
// store the population information in an AI_MGR file record
addPopulation(args[0],args[1],args.size()-1);
// iterate through the actor names
for (unsigned i=1;isetPrimZone (DefaultPatatEvolution);
theNewActor->setAngle (DefaultOrientation);
theNewActor->setMagnetRange (DefaultMagnetRange,DefaultMagnetDecay);
theNewActor->setBehaviour (DefaultBehaviour);
theNewActor->setAttackDistance (DefaultAttackDistance);
theNewActor->setChatSet (DefaultDialogue);
*/
CActor *theNewActor=createActor(args[0],args[i]);
if (theNewActor)
{
theNewActor->doNothing();
theNewActor->setActivity(CActor::NOTHING);
}
}
}
return true;
}
// Command for creating actors
NLMISC_COMMAND(actorCreateWandering,"Add one or more static actors"," [...]")
{
if(args.size() ==1) return false;
COMMAND_MACRO_RECORD_TEST
if (args.size()==0)
{
// no actor names specified so setup the default value to apply to new actors
DefaultActivity = CActor::WANDER;
}
else
{
// store the population information in an AI_MGR file record
addPopulation(args[0],args[1],args.size()-1);
// iterate through the actor names
for (unsigned i=1;isetPrimZone (DefaultPatatEvolution);
theNewActor->setAngle (DefaultOrientation);
theNewActor->setMagnetRange (DefaultMagnetRange,DefaultMagnetDecay);
theNewActor->setBehaviour (DefaultBehaviour);
theNewActor->setAttackDistance (DefaultAttackDistance);
theNewActor->setChatSet (DefaultDialogue);
*/
CActor *theNewActor=createActor(args[0],args[i]);
if (theNewActor)
{
theNewActor->doWander();
theNewActor->setActivity(CActor::WANDER);
}
}
}
return true;
}
// Command for moving actor from a group to another
NLMISC_COMMAND(moveActorsToGroup,"Move actors from a group to another (source group is emptied). If no source specified, all actors from defaultGroup assumed.","[