1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
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.
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 #include "nel/misc/command.h"
21 #include "nel/misc/variable.h"
22 #include "nel/misc/file.h"
23 #include "nel/misc/i_xml.h"
24 #include "nel/misc/path.h"
25 #include "nel/misc/algo.h"
30 #include "actor_manager.h"
31 #include "macro_manager.h"
32 #include "position_generator.h"
37 #include "nel/ligo/primitive.h"
39 using namespace NLMISC
;
40 using namespace NLNET
;
47 //-------------------------------------------------------------------------
48 // Some global variables
49 uint32 GlobalActorCount
=0;
50 uint32 GlobalActorUpdates
=0;
51 uint32 GlobalActorMoves
=0;
53 NLMISC_VARIABLE(uint32
, GlobalActorCount
, "actors");
54 NLMISC_VARIABLE(uint32
, GlobalActorUpdates
, "updates");
55 NLMISC_VARIABLE(uint32
, GlobalActorMoves
, "moves");
58 //-------------------------------------------------------------------------
59 // some globals local to this file
60 static CActor::EActivity DefaultActivity
= CActor::SQUARE
;
61 static NLLIGO::CPrimZone
* DefaultPatatEvolution
= 0;
62 static float DefaultOrientation
= 0.0f
;
63 static float DefaultMagnetRange
= 50.0f
;
64 static float DefaultMagnetDecay
= 10.0f
;
65 static float DefaultAttackDistance
= 0.0f
;
66 static std::string DefaultBehaviour
;
67 static int DefaultDialogue
= 0;
68 static float DefaultMinSpawnTime
= 25.0f
;
69 static float DefaultMaxSpawnTime
= 25.0f
;
71 static map
<string
,string
> PrimOrigin
; // map of prim points and zones to prim filename
72 static std::string SpawnName
; // name or coordinates of the spawn point
73 static CAiMgrFile
* AIFile
=0; // the file to which ai managers are to be added
74 static CAiMgrInstance
* AIManager
=0; // the ai manager to which entities are to be added
75 static CAiMgrPopulation
* AIPopulation
=0; // the ai manager to which entities are to be added
77 //-------------------------------------------------------------------------
78 // some stuff for manageing the output of AI_MANAGER files
79 CAiMgrFile
*CurrentAiMgrFile
;
80 CAiMgrInstance
*CurrentAiMgrInstance
;
83 //-------------------------------------------------------------------------
84 // CLEANING AND INITIALISING THE SYSTEM
86 // Command for resetting the system
87 NLMISC_COMMAND(actorReset
,"Remove all actors and reset the actor system","")
89 COMMAND_MACRO_RECORD_TEST
91 CActorManager::release();
92 CActorManager::init();
98 // Command for removing actors
99 NLMISC_COMMAND(actorRemove,"Kill one or more actors","<actor name> [<actor name>...]")
101 if(args.size() <1) return false;
102 COMMAND_MACRO_RECORD_TEST
104 // iterate through the actor names
105 for (unsigned i=0;i<args.size();i++)
106 CActorManager::killActor(args[i]);
112 // Command for loading .prim file
113 NLMISC_COMMAND(loadPrim
,"load a .prim file","<file name>")
115 if(args
.size() !=1) return false;
117 CIFile
f(CPath::lookup(args
[0]));
118 NLLIGO::CPrimRegion region
;
124 // adding zones to move manager
125 for (i
=0; i
<region
.VZones
.size(); ++i
)
126 CMoveManager::addPrimZone(region
.VZones
[i
]);
128 // adding points and zones to the position generator
129 for (i
=0; i
<region
.VZones
.size(); ++i
)
130 CPositionGenerator::addSpawnZone(region
.VZones
[i
]);
132 for (i
=0; i
<region
.VPoints
.size(); ++i
)
133 CPositionGenerator::addSpawnPoint(region
.VPoints
[i
]);
135 // creating a map of point and zone names -> prim file
136 for (i
=0; i
<region
.VZones
.size(); ++i
)
137 PrimOrigin
[region
.VZones
[i
].getName()]=args
[0];
139 for (i
=0; i
<region
.VPoints
.size(); ++i
)
140 PrimOrigin
[region
.VPoints
[i
].getName()]=args
[0];
146 //-------------------------------------------------------------------------
147 // ACTOR CREATION POSITION GENERATOR
149 // Command for configuring how actors are placed on landscape
150 NLMISC_COMMAND(actorCreatePattern
,"Setup pattern for new actors","<pattern> [...]")
152 if(args
.size() <1) return false;
153 COMMAND_MACRO_RECORD_TEST
155 if (args
[0]==std::string("grid") && args
.size()==1)
157 else if (args
[0]==std::string("line") && args
.size()==1)
159 else if (args
[0]==std::string("line") && args
.size()==2)
160 CPositionGenerator::setSpacing(atoi(args
[0].c_str()));
164 CPositionGenerator::setPattern(args
[0]);
168 // Command for configuring how actors are placed on landscape
169 NLMISC_COMMAND(actorCreateSpacing
,"Setup spacing for new actors","<spacing>")
171 if(args
.size() !=1) return false;
172 COMMAND_MACRO_RECORD_TEST
174 CPositionGenerator::setSpacing(atoi(args
[0].c_str()));
179 // Command for configuring how actors are placed on landscape
180 NLMISC_COMMAND(actorCreatePosition
,"Setup start position for new actors","<x> <y> [<spacing>]")
182 COMMAND_MACRO_RECORD_TEST
189 CPositionGenerator::setPosition(args
[0].c_str());
193 CPositionGenerator::setSpacing(atoi(args
[2].c_str()));
194 // no break - drop through!
196 CPositionGenerator::setPosition(atoi(args
[0].c_str()), atoi(args
[1].c_str()));
197 SpawnName
=args
[0]+" "+args
[1];
207 //-------------------------------------------------------------------------
210 static CActor
*createActor(std::string type
,std::string name
)
212 CActor
*theNewActor
=CActorManager::newActor(type
,name
);
215 theNewActor
->setActivity (DefaultActivity
);
216 theNewActor
->setPrimZone (DefaultPatatEvolution
);
217 theNewActor
->setAngle (DefaultOrientation
);
218 theNewActor
->setMagnetRange (DefaultMagnetRange
,DefaultMagnetDecay
);
219 theNewActor
->setBehaviour (DefaultBehaviour
);
220 theNewActor
->setAttackDistance (DefaultAttackDistance
);
221 theNewActor
->setChatSet (DefaultDialogue
);
226 void addPopulation(std::string type
,std::string name
,uint count
)
228 // if no file has been opened yet then create one
231 AIFile
=new CAiMgrFile
;
232 AIFile
->setName(std::string("ags_test.ai_manager"));
233 CAiMgr::addFile(AIFile
);
236 // create a new ai_manager instance
237 AIManager
= new CAiMgrInstance
;
238 AIFile
->addChild(AIManager
);
240 AIManager
->setName(name
);
241 AIManager
->setCreatureLimit(count
);
242 if (DefaultPatatEvolution
!=0)
243 AIManager
->setBoundary(DefaultPatatEvolution
->getName());
245 // add a population record
246 AIPopulation
=new CAiMgrPopulation
;
247 AIManager
->addPopulation(AIPopulation
);
249 AIPopulation
->setName(name
);
250 AIPopulation
->setOrientation(DefaultOrientation
);
251 AIPopulation
->setQuantity(count
);
252 AIPopulation
->setSpawnRate(int(DefaultMinSpawnTime
*1000.0),int(DefaultMaxSpawnTime
*1000.0));
253 AIPopulation
->setType(NLMISC::CSheetId(type
));
255 // add a spawn location
256 CAiMgrSpawn
*spawn
=new CAiMgrSpawn
;
257 AIManager
->addSpawn(spawn
);
259 spawn
->setPlace(SpawnName
);
261 // check whether the spawn or evolution patats are in an unrefferenced prim file
262 if (PrimOrigin
.find(CPositionGenerator::getSpawnName())!=PrimOrigin
.end())
264 if (AIFile
->getPrim().empty())
265 AIFile
->setPrim(PrimOrigin
[CPositionGenerator::getSpawnName()]);
267 if (AIFile
->getPrim()!=PrimOrigin
[CPositionGenerator::getSpawnName()])
268 nlwarning("WARNING: Can only apply one prim file per AI manager - spawn '%s' in '%s' NOT '%s'",
269 CPositionGenerator::getSpawnName().c_str(),
270 PrimOrigin
[CPositionGenerator::getSpawnName()].c_str(),
271 AIFile
->getPrim().c_str() );
274 if (DefaultPatatEvolution
!=0)
275 if (PrimOrigin
.find(DefaultPatatEvolution
->getName())!=PrimOrigin
.end())
277 if (AIFile
->getPrim().empty())
278 AIFile
->setPrim(PrimOrigin
[DefaultPatatEvolution
->getName()]);
280 if (AIFile
->getPrim()!=PrimOrigin
[DefaultPatatEvolution
->getName()])
281 nlwarning("WARNING: Can only apply one prim file per AI manager - spawn '%s' in '%s' NOT '%s'",
282 DefaultPatatEvolution
->getName().c_str(),
283 PrimOrigin
[DefaultPatatEvolution
->getName()].c_str(),
284 AIFile
->getPrim().c_str() );
288 // Command for creating actors
289 NLMISC_COMMAND(actorCreate
,"Add one or more moving actors","<actor type> <actor name> [<actor name>...]")
291 if(args
.size() <2) return false;
292 COMMAND_MACRO_RECORD_TEST
294 // store the population information in an AI_MGR file record
295 addPopulation(args
[0],args
[1],args
.size()-1);
297 // iterate through the actor names
298 for (unsigned i
=1;i
<args
.size();i
++)
300 // create the named actor and add them to the GPMS and other services
302 CActor *theNewActor=CActorManager::newActor(args[0],args[i]);
303 theNewActor->setActivity (DefaultActivity);
304 theNewActor->setPrimZone (DefaultPatatEvolution);
305 theNewActor->setAngle (DefaultOrientation);
306 theNewActor->setMagnetRange (DefaultMagnetRange,DefaultMagnetDecay);
307 theNewActor->setBehaviour (DefaultBehaviour);
308 theNewActor->setAttackDistance (DefaultAttackDistance);
309 theNewActor->setChatSet (DefaultDialogue);
311 CActor
*theNewActor
=createActor(args
[0],args
[i
]);
317 // Command for creating actors
318 NLMISC_COMMAND(actorCreateCustom
,"Add one or more moving actors","<actor type> [ [-act <activity>] [-pos <posx> <posy>] [-ctop <color>] [-cbot <color>] [-chair <color>] [-rhand <int>] [-lhand <int>] ] <actor name> [<actor name>...]")
320 if(args
.size() <2) return false;
321 COMMAND_MACRO_RECORD_TEST
324 for (i=1; i<args.size(); ++i)
328 // store the population information in an AI_MGR file record
329 addPopulation(args[0],args[1],args.size()-1);
331 // iterate through the actor names
332 for (unsigned i=1;i<args.size();i++)
334 // create the named actor and add them to the GPMS and other services
335 CActor *theNewActor=createActor(args[0],args[i]);
341 // Command for creating actors
342 NLMISC_COMMAND(actorCreateGroup
,"Add a group of actors all at once","<actor type> <group name> <count>")
344 if(args
.size()!=3 || atoi(args
[2].c_str())<=0 || atoi(args
[2].c_str())>1024) return false;
345 COMMAND_MACRO_RECORD_TEST
347 CActorGroup
*theNewGroup
=CActorManager::newActorGroup(args
[1]);
349 // store the population information in an AI_MGR file record
350 addPopulation(args
[0],args
[1],atoi(args
[2].c_str()));
352 // iterate through the actor names
353 for (int i
=0;i
<atoi(args
[2].c_str());i
++)
355 // create the named actor and add them to the GPMS and other services
357 CActor *theNewActor=CActorManager::newActor(args[0],args[1]+toString(theNewGroup->actorCount()));
358 theNewActor->setActivity (DefaultActivity);
359 theNewActor->setPrimZone (DefaultPatatEvolution);
360 theNewActor->setAngle (DefaultOrientation);
361 theNewActor->setMagnetRange (DefaultMagnetRange,DefaultMagnetDecay);
362 theNewActor->setBehaviour (DefaultBehaviour);
363 theNewActor->setAttackDistance (DefaultAttackDistance);
364 theNewActor->setChatSet (DefaultDialogue);
366 CActor
*theNewActor
=createActor(args
[0],args
[1]+toString(theNewGroup
->actorCount()));
369 theNewGroup
->addActor(theNewActor
);
376 // Command for creating actors
377 NLMISC_COMMAND(actorCreateMoving
,"Add one or more static actors","<actor type> <actor name> [<actor name>...]")
379 if(args
.size() ==1) return false;
380 COMMAND_MACRO_RECORD_TEST
384 // no actor names specified so setup the default value to apply to new actors
385 DefaultActivity
= CActor::SQUARE
;
389 // store the population information in an AI_MGR file record
390 addPopulation(args
[0],args
[1],args
.size()-1);
392 // iterate through the actor names
393 for (unsigned i
=1;i
<args
.size();i
++)
395 // create the named actor and add them to the GPMS and other services
397 CActor *theNewActor= CActorManager::newActor(args[0],args[i]);
398 theNewActor->setPrimZone (DefaultPatatEvolution);
399 theNewActor->setAngle (DefaultOrientation);
400 theNewActor->setMagnetRange (DefaultMagnetRange,DefaultMagnetDecay);
401 theNewActor->setBehaviour (DefaultBehaviour);
402 theNewActor->setAttackDistance (DefaultAttackDistance);
403 theNewActor->setChatSet (DefaultDialogue);
405 CActor
*theNewActor
=createActor(args
[0],args
[i
]);
409 theNewActor
->doSquare();
410 theNewActor
->setActivity(CActor::SQUARE
);
419 // Command for creating actors
420 NLMISC_COMMAND(actorCreateStationary
,"Add one or more static actors","<actor type> [<actor name>...]")
422 if(args
.size() ==1) return false;
423 COMMAND_MACRO_RECORD_TEST
427 // no actor names specified so setup the default value to apply to new actors
428 DefaultActivity
= CActor::NOTHING
;
432 // store the population information in an AI_MGR file record
433 addPopulation(args
[0],args
[1],args
.size()-1);
435 // iterate through the actor names
436 for (unsigned i
=1;i
<args
.size();i
++)
438 // create the named actor and add them to the GPMS and other services
440 CActor *theNewActor= CActorManager::newActor(args[0],args[i]);
441 theNewActor->setPrimZone (DefaultPatatEvolution);
442 theNewActor->setAngle (DefaultOrientation);
443 theNewActor->setMagnetRange (DefaultMagnetRange,DefaultMagnetDecay);
444 theNewActor->setBehaviour (DefaultBehaviour);
445 theNewActor->setAttackDistance (DefaultAttackDistance);
446 theNewActor->setChatSet (DefaultDialogue);
448 CActor
*theNewActor
=createActor(args
[0],args
[i
]);
452 theNewActor
->doNothing();
453 theNewActor
->setActivity(CActor::NOTHING
);
462 // Command for creating actors
463 NLMISC_COMMAND(actorCreateWandering
,"Add one or more static actors","<actor type> <actor name> [<actor name>...]")
465 if(args
.size() ==1) return false;
466 COMMAND_MACRO_RECORD_TEST
470 // no actor names specified so setup the default value to apply to new actors
471 DefaultActivity
= CActor::WANDER
;
475 // store the population information in an AI_MGR file record
476 addPopulation(args
[0],args
[1],args
.size()-1);
478 // iterate through the actor names
479 for (unsigned i
=1;i
<args
.size();i
++)
481 // create the named actor and add them to the GPMS and other services
483 CActor *theNewActor= CActorManager::newActor(args[0],args[i]);
484 theNewActor->setPrimZone (DefaultPatatEvolution);
485 theNewActor->setAngle (DefaultOrientation);
486 theNewActor->setMagnetRange (DefaultMagnetRange,DefaultMagnetDecay);
487 theNewActor->setBehaviour (DefaultBehaviour);
488 theNewActor->setAttackDistance (DefaultAttackDistance);
489 theNewActor->setChatSet (DefaultDialogue);
491 CActor
*theNewActor
=createActor(args
[0],args
[i
]);
495 theNewActor
->doWander();
496 theNewActor
->setActivity(CActor::WANDER
);
505 // Command for moving actor from a group to another
506 NLMISC_COMMAND(moveActorsToGroup
,"Move actors from a group to another (source group is emptied). If no source specified, all actors from defaultGroup assumed.","[<source group>] <dest group>")
508 COMMAND_MACRO_RECORD_TEST
516 if (args
.size() == 1)
517 CActorManager::setActorsToGroup("defaultGroup", args
[0]);
519 CActorManager::setActorsToGroup(args
[0], args
[1]);
525 //-------------------------------------------------------------------------
526 // MANAGING EXISTING ACTORS
528 // Command for setting an actor PrimZone
529 NLMISC_COMMAND(actorSetPatatEvolution
,"Set actor patat evolution","<patat name> [<actor name>...]")
531 if(args
.size() <1) return false;
532 COMMAND_MACRO_RECORD_TEST
534 NLLIGO::CPrimZone
*primZone
= CMoveManager::getPrimZone(args
[0]);
535 if (primZone
== NULL
)
537 nlwarning("Can't find prim zone '%s'", args
[0].c_str());
543 // no actor names specified so setup the default value to apply to new actors
544 DefaultPatatEvolution
= primZone
;
548 // apply this evolution patat to the last manager stored in ai manager
550 AIManager
->setBoundary(args
[0]);
552 // iterate through the actor names
554 for (i
=1;i
<args
.size();i
++)
556 CActor
*actor
=CActorManager::getActor(args
[i
]);
558 nlinfo("Unknown actor: '%s'",args
[i
].c_str());
560 actor
->setPrimZone(primZone
);
569 // Command for setting actor orientations
570 NLMISC_COMMAND(actorSetOrientation
,"Add one or more static actors","<direction> [<actor name>...]")
572 if(args
.size() <1) return false;
573 COMMAND_MACRO_RECORD_TEST
575 const char *angleNames
[]= {"E", "ENE", "NE", "NNE", "N","NNW","NW","WNW","W","WSW","SW","SSW","S","SSE","SE","ESE"};
579 #ifndef NL_OS_WINDOWS
580 #define stricmp strcasecmp
583 for (i
=0; i
<sizeof(angleNames
)/sizeof(angleNames
[0]) &&
584 stricmp(args
[0].c_str(),angleNames
[i
]); i
++)
586 if (i
<(sizeof(angleNames
)/sizeof(angleNames
[0])))
587 theta
=3.14159265359f
*2.0f
*(float)i
/(float)(sizeof(angleNames
)/sizeof(angleNames
[0]));
590 NLMISC::fromString(args
[0], theta
);
591 theta
= theta
/ 360.0f
*2.0f
*3.14159265359f
;
596 // no actor names specified so setup the default value to apply to new actors
597 DefaultOrientation
= theta
;
601 // apply this orientation to the last manager stored in ai manager
603 AIPopulation
->setOrientation(theta
);
605 // iterate through the actor names
606 for (i
=1;i
<args
.size();i
++)
608 CActor
*actor
=CActorManager::getActor(args
[i
]);
610 nlinfo("Unknown actor: '%s'",args
[i
].c_str());
612 actor
->setAngle(theta
);
620 // Command for setting actor magnet range
621 NLMISC_COMMAND(actorSetMagnetRange
,"Set the magnet properties for wandering behaviour","<range> [<decay>] [<actor name>...]")
623 if(args
.size() <1) return false;
624 COMMAND_MACRO_RECORD_TEST
627 NLMISC::fromString(args
[0], range
);
628 if (range
<=0.0f
) return false;
632 NLMISC::fromString(args
[0], decay
);
633 if (decay
<0.0f
) return false;
641 if((sint
)args
.size() <(start
+1)) return false;
643 if (args
.size()<start
)
645 // no actor names specified so setup the default value to apply to new actors
646 DefaultMagnetRange
= range
;
648 DefaultMagnetDecay
= decay
;
652 // iterate through the actor names
653 for (unsigned i
=start
;i
<args
.size();i
++)
655 CActor
*actor
=CActorManager::getActor(args
[i
]);
657 nlinfo("Unknown actor: '%s'",args
[i
].c_str());
659 actor
->setMagnetRange(range
,decay
);
666 // Command for setting actor attack distance
667 NLMISC_COMMAND(actorSetAttackDistance
,"set actor attack distance","<distance> [<actor name>...]")
669 if(args
.size() <1) return false;
670 COMMAND_MACRO_RECORD_TEST
673 NLMISC::fromString(args
[0], distance
);
674 // if (distance<=0.0f) return false;
678 // no actor names specified so setup the default value to apply to new actors
679 DefaultAttackDistance
= distance
;
683 // iterate through the actor names
684 for (unsigned i
=1;i
<args
.size();i
++)
686 CActor
*actor
=CActorManager::getActor(args
[i
]);
688 nlinfo("Unknown actor: '%s'",args
[i
].c_str());
690 actor
->setAttackDistance(distance
);
697 // Command for setting actor mode
698 /*NLMISC_COMMAND(actorSetMode,"Set actor mode","<mode> <actor name>[...]")
700 if(args.size() <2) return false;
701 COMMAND_MACRO_RECORD_TEST
703 // iterate through the named actors setting their mode
704 for (unsigned i=1;i<args.size();i++)
706 CActor *actor=CActorManager::getActor(args[i]);
708 nlinfo("Unknown actor: '%s'",args[i].c_str());
710 actor->setMode(args[0]);
716 // Command for setting actor behaviour
717 NLMISC_COMMAND(actorSetBehaviour
,"Set actor behaviour","<behaviour> [<actor name>...]")
719 if(args
.size() <1) return false;
720 COMMAND_MACRO_RECORD_TEST
724 // no actor names specified so setup the default value to apply to new actors
725 DefaultBehaviour
= args
[0];
727 else if (args
.size() == 2 && args
[1] == "all")
729 uint num
= CActorManager::numActors();
731 for (i
=0; i
<num
; ++i
)
733 CActor
*actor
=CActorManager::getActor(i
);
735 actor
->setBehaviour(args
[0]);
740 // iterate through the named actors setting their behaviour
741 for (unsigned i
=1;i
<args
.size();i
++)
743 CActor
*actor
=CActorManager::getActor(args
[i
]);
745 nlinfo("Unknown actor: '%s'",args
[i
].c_str());
747 actor
->setBehaviour(args
[0]);
754 // Command for setting actor dialogue for bot chat
755 NLMISC_COMMAND(actorSetDialogue
,"Set actor bot-chat dialogue","<dialogue set> [<actor name>...]")
757 if(args
.size() <1) return false;
758 COMMAND_MACRO_RECORD_TEST
760 int dialogue
=atoi(args
[0].c_str());
764 // no actor names specified so setup the default value to apply to new actors
765 DefaultDialogue
= dialogue
;
769 // iterate through the named actors setting their behaviour
770 for (unsigned i
=1;i
<args
.size();i
++)
772 CActor
*actor
=CActorManager::getActor(args
[i
]);
774 nlinfo("Unknown actor: '%s'",args
[i
].c_str());
776 actor
->setChatSet(dialogue
);
784 // Command for setting actor respawn time (when dead)
785 NLMISC_COMMAND(actorSetRespawnDelay
,"set actor respawn delay","<min time> [<max time>] [<actor name>...]")
787 if(args
.size() <1) return false;
788 COMMAND_MACRO_RECORD_TEST
791 NLMISC::fromString(args
[0], min
);
792 if (min
<=0.0f
) return false;
796 NLMISC::fromString(args
[0], max
);
808 if((sint
)args
.size() <(start
+1)) return false;
810 if (args
.size()<start
)
812 // no actor names specified so setup the default value to apply to new actors
813 DefaultMinSpawnTime
= min
;
815 DefaultMaxSpawnTime
= max
;
819 // apply this orientation to the last manager stored in ai manager
821 AIPopulation
->setSpawnRate(int(1000.0*min
),int(1000.0*max
));
823 // iterate through the actor names
824 for (unsigned i
=start
;i
<args
.size();i
++)
826 CActor
*actor
=CActorManager::getActor(args
[i
]);
828 nlinfo("Unknown actor: '%s'",args
[i
].c_str());
830 actor
->setSpawnTime(min
,max
);
838 // Command for making actors walk in a square pattern
839 NLMISC_COMMAND(actorSetActivitySquare
,"Make actors walk in a square shape","[<actor name>...]")
841 if(args
.size() <1) return false;
842 COMMAND_MACRO_RECORD_TEST
846 // no actor names specified so setup the default value to apply to new actors
847 DefaultActivity
= CActor::SQUARE
;
849 else if (args
.size() == 1 && args
[0] == "all")
851 uint num
= CActorManager::numActors();
853 for (i
=0; i
<num
; ++i
)
855 CActor
*actor
=CActorManager::getActor(i
);
857 actor
->setActivity(CActor::SQUARE
);
862 // iterate through the actor names
863 for (unsigned i
=0;i
<args
.size();i
++)
865 CActor
*actor
=CActorManager::getActor(args
[i
]);
867 nlinfo("Unknown actor: '%s'",args
[i
].c_str());
869 CActorManager::getActor(args
[i
])->setActivity(CActor::SQUARE
);
876 // Command for making actor(s) wander about randomly
877 NLMISC_COMMAND(actorSetActivityWander
,"Make actors walk in a square shape","[<actor name>...]")
879 if(args
.size() <1) return false;
880 COMMAND_MACRO_RECORD_TEST
884 // no actor names specified so setup the default value to apply to new actors
885 DefaultActivity
= CActor::WANDER
;
887 else if (args
.size() == 1 && args
[0] == "all")
889 uint num
= CActorManager::numActors();
891 for (i
=0; i
<num
; ++i
)
893 CActor
*actor
=CActorManager::getActor(i
);
895 actor
->setActivity(CActor::WANDER
);
900 // iterate through the actor names
901 for (unsigned i
=0;i
<args
.size();i
++)
903 CActor
*actor
=CActorManager::getActor(args
[i
]);
905 nlinfo("Unknown actor: '%s'",args
[i
].c_str());
907 CActorManager::getActor(args
[i
])->setActivity(CActor::WANDER
);
914 // Command for making actor(s) stand still
915 NLMISC_COMMAND(actorSetActivityStationary
,"Make actors stop walking/ fighting","[<actor name>...]")
917 if(args
.size() <1) return false;
918 COMMAND_MACRO_RECORD_TEST
922 // no actor names specified so setup the default value to apply to new actors
923 DefaultActivity
= CActor::NOTHING
;
925 else if (args
.size() == 1 && args
[0] == "all")
927 uint num
= CActorManager::numActors();
929 for (i
=0; i
<num
; ++i
)
931 CActor
*actor
=CActorManager::getActor(i
);
933 actor
->setActivity(CActor::NOTHING
);
938 // iterate through the actor names
939 for (unsigned i
=0;i
<args
.size();i
++)
941 CActor
*actor
=CActorManager::getActor(args
[i
]);
943 nlinfo("Unknown actor: '%s'",args
[i
].c_str());
945 CActorManager::getActor(args
[i
])->setActivity(CActor::NOTHING
);
952 // Command for making actors attack entities
953 NLMISC_COMMAND(actorFight
,"Make actors fight eachother","<actor or group name> <actor or group name>")
955 if(args
.size()!=2) return false;
956 COMMAND_MACRO_RECORD_TEST
958 CActor
*actor0
=CActorManager::getActor(args
[0]);
959 CActor
*actor1
=CActorManager::getActor(args
[1]);
960 CActorGroup
*group0
=CActorManager::getActorGroup(args
[0]);
961 CActorGroup
*group1
=CActorManager::getActorGroup(args
[1]);
968 actor0
->doFight(actor1
);
969 nlinfo("ACTOR %s Attacking ACTOR: %s",args
[0].c_str(),args
[1].c_str());
970 // actor1->doFight(actor0);
974 actor0
->doFight(group1
);
975 nlinfo("ACTOR %s Attacking GROUP: %s",args
[0].c_str(),args
[1].c_str());
976 // group1->doFight(actor0);
981 id
.fromString( args
[1].c_str() );
983 nlinfo("ACTOR %s Attacking entity with SID: %s",args
[0].c_str(),args
[1].c_str());
990 group0
->doFight(actor1
);
991 nlinfo("GROUP %s Attacking ACTOR: %s",args
[0].c_str(),args
[1].c_str());
992 // actor1->doFight(group0);
996 group0
->doFight(group1
);
997 nlinfo("GROUP %s Attacking GROUP: %s",args
[0].c_str(),args
[1].c_str());
998 // group1->doFight(group0);
1003 id
.fromString( args
[1].c_str() );
1004 //group0->doFight(id);
1005 nlinfo("GROUP %s Cannot attack: %s (no actor or group of this name found in this service)",args
[0].c_str(),args
[1].c_str());
1008 else nlinfo("Actor or group doesn't exist: %s",args
[0].c_str());
1013 // Command for displaying all of or named actors
1014 NLMISC_COMMAND(actorDisplay
,"List the actors","[<actor name>...]")
1016 COMMAND_MACRO_RECORD_TEST
1020 // list all the actors' stats
1021 for (unsigned i
=0;i
<CActorManager::numActors();++i
)
1022 CActorManager::getActor(i
)->display();
1026 // iterate through the named actors listing their stats
1027 for (unsigned i
=0;i
<args
.size();i
++)
1029 CActor
*actor
=CActorManager::getActor(args
[i
]);
1031 log
.displayNL("Unknown actor: '%s'",args
[i
].c_str());
1033 actor
->display(&log
);
1040 //-------------------------------------------------------------------------
1041 // MANAGING AI FILES
1043 // command to display ai manager hierachy
1044 NLMISC_COMMAND(aiDisplay
,"Display the ai manager hierachy","")
1046 if(args
.size()!=0) return false;
1047 COMMAND_MACRO_RECORD_TEST
1049 CAiMgr::display(0, &log
);
1053 // command to set the output file for ai populations
1054 NLMISC_COMMAND(aiFile
,"Set the file name for the following ai populations","<file name>")
1056 if(args
.size()!=1) return false;
1057 COMMAND_MACRO_RECORD_TEST
1059 AIFile
=new CAiMgrFile
;
1060 AIFile
->setName(args
[0]+std::string(".ai_manager"));
1061 CAiMgr::addFile(AIFile
);
1065 // command to write ai manager hierachy to files
1066 NLMISC_COMMAND(aiWrite
,"Write the ai manager hierachy to disk","")
1068 if(args
.size()!=0) return false;
1069 COMMAND_MACRO_RECORD_TEST
1075 // command to read ai manager hierachy from files
1076 NLMISC_COMMAND(aiRead
,"Read the ai manager hierachy from disk","<path>")
1078 if(args
.size()!=1) return false;
1079 COMMAND_MACRO_RECORD_TEST
1081 CAiMgr::read(args
[0],true);
1086 //-------------------------------------------------------------------------
1089 // Command for creating a new macro
1090 NLMISC_COMMAND(macroRecord
,"Start recording a new macro","<macro name>")
1095 CMacroManager::recordMacro(args
[0]);
1101 // Command for adding a line to a macro
1102 NLMISC_COMMAND(macroStopRecord
,"stop macro recording","")
1107 CMacroManager::stopRecord();
1113 // Command for executing a macro
1114 NLMISC_COMMAND(macroExecute
,"Execute one or more macros","<macro name> [<macro name>...]")
1119 for (unsigned i
=0;i
<args
.size();++i
)
1120 CMacroManager::execute(args
[i
],log
);
1126 // Command for executing a macro
1127 NLMISC_COMMAND(macroDisplay
,"Display list of macros or contents of the given macros","")
1130 CMacroManager::listMacros(&log
);
1132 for (unsigned i
=0;i
<args
.size();++i
)
1133 CMacroManager::displayMacro(args
[i
], &log
);
1139 // Command for executing a macro
1140 NLMISC_COMMAND(sheetDisplay
,"Display list of sheets read","")
1142 CSheets::display(&log
);
1149 NLMISC_COMMAND(generateScript
, "Generate a sript that spawn a given type of creature", "<script_name> <spawn x> <spawn y> <spacing> <width> <extension> [<filter> ...]")
1151 if (args
.size() < 6)
1154 const string
&scriptName
= args
[0];
1156 NLMISC::fromString(args
[1], spawnX
);
1158 NLMISC::fromString(args
[2], spawnY
);
1160 NLMISC::fromString(args
[3], spacing
);
1162 NLMISC::fromString(args
[4], width
);
1163 const string
&extension
= args
[5];
1164 vector
<string
> filters
;
1167 for (i
=6; i
<args
.size(); ++i
)
1168 filters
.push_back(args
[i
]);
1170 vector
<string
> files
;
1171 CPath::getFileList(extension
, files
);
1173 if (!filters
.empty())
1175 vector
<string
>::iterator itr
;
1176 for (itr
=files
.begin(); itr
!=files
.end(); )
1180 if (files
[i
][0] != '_')
1182 for (i
=0; !match
&& i
<filters
.size(); ++i
)
1183 if (testWildCard(*itr
, filters
[i
]))
1190 itr
= files
.erase(itr
);
1200 if (!script
.open(scriptName
))
1203 smprintf(buffer
, 2048, "! %s\n", scriptName
.c_str());
1204 script
.serialBuffer((uint8
*)buffer
, strlen(buffer
));
1205 smprintf(buffer
, 2048, "! Generated using args: %s %g %g %g %d %s\n\n", scriptName
.c_str(), spawnX
, spawnY
, spacing
, width
, extension
.c_str());
1206 script
.serialBuffer((uint8
*)buffer
, strlen(buffer
));
1208 if (!filters
.empty())
1210 smprintf(buffer
, 2048, "! Filters are:");
1211 script
.serialBuffer((uint8
*)buffer
, strlen(buffer
));
1212 for (i
=0; i
<filters
.size(); ++i
)
1214 smprintf(buffer
, 2048, " %s", filters
[i
].c_str());
1215 script
.serialBuffer((uint8
*)buffer
, strlen(buffer
));
1217 smprintf(buffer
, 2048, "\n\n");
1218 script
.serialBuffer((uint8
*)buffer
, strlen(buffer
));
1221 smprintf(buffer
, 2048, "! %d actor sheets found\n\n", files
.size());
1222 script
.serialBuffer((uint8
*)buffer
, strlen(buffer
));
1224 smprintf(buffer
, 2048, "cmd actorCreateStationary\ncmd actorSetOrientation 0\n\n");
1225 script
.serialBuffer((uint8
*)buffer
, strlen(buffer
));
1227 double cx
= spawnX
, cy
= spawnY
;
1230 for (i
=0; i
<files
.size(); ++i
)
1232 string fileName
= CFile::getFilename(files
[i
]);
1233 string name
= CFile::getFilenameWithoutExtension(fileName
);
1235 smprintf(buffer
, 2048, "cmd actorCreatePosition %d %d\ncmd actorCreate %s %s\n", (int)cx
, (int)cy
, fileName
.c_str(), name
.c_str());
1236 script
.serialBuffer((uint8
*)buffer
, strlen(buffer
));
1241 if (inLine
>= width
)
1255 NLMISC_COMMAND(generateAndRun
, "Generate and run a sript that spawn a given type of creature", "<spawn x> <spawn y> <spacing> <width> <extension> [<filter> ...]")
1257 string scriptfile
= IService::getInstance()->WriteFilesDirectory
.toString()+"ags_generated.script";
1258 string commandLine
= "generateScript "+scriptfile
;
1261 for (i
=0; i
<args
.size(); ++i
)
1262 commandLine
+= string(" ")+args
[i
];
1264 // remove file first
1265 CFile::deleteFile(scriptfile
);
1268 ICommand::execute(commandLine
, log
);
1271 ICommand::execute("runScript ags_generated "+scriptfile
, log
);
1277 NLMISC_COMMAND(checkGenerateAndRun
, "Generate and run a sript that spawn a given type of creature", "<script_name> <spawn x> <spawn y> <spacing> <width> <extension> [<filter> ...]")
1279 if (args
.size() < 6)
1282 string scriptName
= args
[0];
1283 string filename
= scriptName
+".script";
1285 string scriptfile
= CPath::lookup(filename
, false, false);
1287 if (scriptfile
.empty())
1289 if (!CFile::isExists("data_shard/"))
1290 CFile::createDirectory("data_shard/");
1291 if (!CFile::isExists("data_shard/ags_script/"))
1292 CFile::createDirectory("data_shard/ags_script/");
1294 scriptfile
= string("data_shard/ags_script/")+filename
;
1296 string commandLine
= "generateScript "+scriptfile
;
1298 for (i
=1; i
<args
.size(); ++i
)
1299 commandLine
+= string(" ")+args
[i
];
1302 ICommand::execute(commandLine
, log
);
1306 ICommand::execute("runScript "+scriptName
+" "+scriptfile
, log
);
1314 NLMISC_COMMAND(setTargets
, "set targets for a multi cast", "<caster entityId> <cast_time> [<target1 entityId> ...]")
1316 if (args
.size() < 2)
1320 list
<CEntityId
> targets
;
1322 caster
.fromString(args
[0].c_str());
1324 CMirrorPropValueList
<TDataSetRow
> targetList(TheDataset
, caster
, "TargetList");
1329 for (i
=args
.size()-1; i
>=2; --i
)
1332 target
.fromString(args
[i
].c_str());
1333 TDataSetRow targetIndex
= CMirrors::DataSet
->getDataSetRow(target
);
1335 targetList
.push_front(targetIndex
);
1338 TGameCycle castTime
= CTickEventHandler::getGameCycle() + atoi(args
[1].c_str());
1339 targetList
.push_front(*((TDataSetRow
*)(&castTime
)));
1344 //-------------------------------------------------------------------------
1345 } // end of namespace AGS_TEST