Add infos into target window
[ryzomcore.git] / ryzom / server / src / ags_test / commands.cpp
blob4fa955401ab944488107c3388de3012bef2bf1ff
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
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.
8 //
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/>.
19 // Nel Misc
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"
27 // Local includes
28 #include "ags_test.h"
29 #include "actor.h"
30 #include "actor_manager.h"
31 #include "macro_manager.h"
32 #include "position_generator.h"
33 #include "sheets.h"
34 #include "mirrors.h"
35 #include "ai_mgr.h"
37 #include "nel/ligo/primitive.h"
39 using namespace NLMISC;
40 using namespace NLNET;
41 using namespace std;
43 namespace AGS_TEST
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();
93 GlobalActorCount = 0;
94 return true;
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]);
108 return true;
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;
119 CIXml xml;
120 xml.init(f);
121 region.serial(xml);
123 uint i;
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];
142 return true;
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()));
161 else
162 return false;
164 CPositionGenerator::setPattern(args[0]);
165 return true;
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()));
176 return true;
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
184 switch(args.size())
186 case 0:
187 return false;
188 case 1:
189 CPositionGenerator::setPosition(args[0].c_str());
190 SpawnName=args[0];
191 break;
192 case 3:
193 CPositionGenerator::setSpacing(atoi(args[2].c_str()));
194 // no break - drop through!
195 case 2:
196 CPositionGenerator::setPosition(atoi(args[0].c_str()), atoi(args[1].c_str()));
197 SpawnName=args[0]+" "+args[1];
198 break;
199 default:
200 return false;
203 return true;
207 //-------------------------------------------------------------------------
208 // CREATING ACTORS
210 static CActor *createActor(std::string type,std::string name)
212 CActor *theNewActor=CActorManager::newActor(type,name);
213 if (theNewActor)
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);
223 return theNewActor;
226 void addPopulation(std::string type,std::string name,uint count)
228 // if no file has been opened yet then create one
229 if (AIFile==0)
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()]);
266 else
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()]);
279 else
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]);
314 return true;
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
323 uint i;
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]);
338 return true;
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()));
368 if (theNewActor)
369 theNewGroup->addActor(theNewActor);
372 return true;
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
382 if (args.size()==0)
384 // no actor names specified so setup the default value to apply to new actors
385 DefaultActivity = CActor::SQUARE;
387 else
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]);
407 if (theNewActor)
409 theNewActor->doSquare();
410 theNewActor->setActivity(CActor::SQUARE);
415 return true;
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
425 if (args.size()==0)
427 // no actor names specified so setup the default value to apply to new actors
428 DefaultActivity = CActor::NOTHING;
430 else
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]);
450 if (theNewActor)
452 theNewActor->doNothing();
453 theNewActor->setActivity(CActor::NOTHING);
458 return true;
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
468 if (args.size()==0)
470 // no actor names specified so setup the default value to apply to new actors
471 DefaultActivity = CActor::WANDER;
473 else
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]);
493 if (theNewActor)
495 theNewActor->doWander();
496 theNewActor->setActivity(CActor::WANDER);
501 return true;
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
510 if (args.size() < 1)
511 return false;
513 if (args.size() > 2)
514 return false;
516 if (args.size() == 1)
517 CActorManager::setActorsToGroup("defaultGroup", args[0]);
518 else
519 CActorManager::setActorsToGroup(args[0], args[1]);
521 return true;
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());
538 return false;
541 if (args.size()==1)
543 // no actor names specified so setup the default value to apply to new actors
544 DefaultPatatEvolution = primZone;
546 else
548 // apply this evolution patat to the last manager stored in ai manager
549 if (AIManager)
550 AIManager->setBoundary(args[0]);
552 // iterate through the actor names
553 uint i;
554 for (i=1;i<args.size();i++)
556 CActor *actor=CActorManager::getActor(args[i]);
557 if (actor==0)
558 nlinfo("Unknown actor: '%s'",args[i].c_str());
559 else
560 actor->setPrimZone(primZone);
564 return true;
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"};
576 unsigned i;
577 float theta;
579 #ifndef NL_OS_WINDOWS
580 #define stricmp strcasecmp
581 #endif
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]));
588 else
590 NLMISC::fromString(args[0], theta);
591 theta = theta / 360.0f*2.0f*3.14159265359f;
594 if (args.size()==1)
596 // no actor names specified so setup the default value to apply to new actors
597 DefaultOrientation = theta;
599 else
601 // apply this orientation to the last manager stored in ai manager
602 if (AIPopulation)
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]);
609 if (actor==0)
610 nlinfo("Unknown actor: '%s'",args[i].c_str());
611 else
612 actor->setAngle(theta);
616 return true;
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
626 float range;
627 NLMISC::fromString(args[0], range);
628 if (range<=0.0f) return false;
630 unsigned start;
631 float decay;
632 NLMISC::fromString(args[0], decay);
633 if (decay<0.0f) return false;
634 if (decay==0.0f)
636 decay=10.0f;
637 start=1;
639 else
640 start=2;
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;
647 if (start>1)
648 DefaultMagnetDecay = decay;
650 else
652 // iterate through the actor names
653 for (unsigned i=start;i<args.size();i++)
655 CActor *actor=CActorManager::getActor(args[i]);
656 if (actor==0)
657 nlinfo("Unknown actor: '%s'",args[i].c_str());
658 else
659 actor->setMagnetRange(range,decay);
663 return true;
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
672 float distance;
673 NLMISC::fromString(args[0], distance);
674 // if (distance<=0.0f) return false;
676 if (args.size()<2)
678 // no actor names specified so setup the default value to apply to new actors
679 DefaultAttackDistance = distance;
681 else
683 // iterate through the actor names
684 for (unsigned i=1;i<args.size();i++)
686 CActor *actor=CActorManager::getActor(args[i]);
687 if (actor==0)
688 nlinfo("Unknown actor: '%s'",args[i].c_str());
689 else
690 actor->setAttackDistance(distance);
694 return true;
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]);
707 if (actor==0)
708 nlinfo("Unknown actor: '%s'",args[i].c_str());
709 else
710 actor->setMode(args[0]);
713 return true;
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
722 if (args.size()<2)
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();
730 uint i;
731 for (i=0; i<num; ++i)
733 CActor *actor=CActorManager::getActor(i);
734 if (actor != NULL)
735 actor->setBehaviour(args[0]);
738 else
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]);
744 if (actor==0)
745 nlinfo("Unknown actor: '%s'",args[i].c_str());
746 else
747 actor->setBehaviour(args[0]);
751 return true;
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());
762 if (args.size()<2)
764 // no actor names specified so setup the default value to apply to new actors
765 DefaultDialogue = dialogue;
767 else
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]);
773 if (actor==0)
774 nlinfo("Unknown actor: '%s'",args[i].c_str());
775 else
776 actor->setChatSet(dialogue);
780 return true;
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
790 float min;
791 NLMISC::fromString(args[0], min);
792 if (min<=0.0f) return false;
794 unsigned start;
795 float max;
796 NLMISC::fromString(args[0], max);
797 if (max==0.0f)
799 max=min;
800 start=1;
802 else
804 if (max<min)
805 return false;
806 start=2;
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;
814 if (start>1)
815 DefaultMaxSpawnTime = max;
817 else
819 // apply this orientation to the last manager stored in ai manager
820 if (AIPopulation)
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]);
827 if (actor==0)
828 nlinfo("Unknown actor: '%s'",args[i].c_str());
829 else
830 actor->setSpawnTime(min,max);
834 return true;
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
844 if (args.size()==0)
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();
852 uint i;
853 for (i=0; i<num; ++i)
855 CActor *actor=CActorManager::getActor(i);
856 if (actor != NULL)
857 actor->setActivity(CActor::SQUARE);
860 else
862 // iterate through the actor names
863 for (unsigned i=0;i<args.size();i++)
865 CActor *actor=CActorManager::getActor(args[i]);
866 if (actor==0)
867 nlinfo("Unknown actor: '%s'",args[i].c_str());
868 else
869 CActorManager::getActor(args[i])->setActivity(CActor::SQUARE);
873 return true;
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
882 if (args.size()==0)
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();
890 uint i;
891 for (i=0; i<num; ++i)
893 CActor *actor=CActorManager::getActor(i);
894 if (actor != NULL)
895 actor->setActivity(CActor::WANDER);
898 else
900 // iterate through the actor names
901 for (unsigned i=0;i<args.size();i++)
903 CActor *actor=CActorManager::getActor(args[i]);
904 if (actor==0)
905 nlinfo("Unknown actor: '%s'",args[i].c_str());
906 else
907 CActorManager::getActor(args[i])->setActivity(CActor::WANDER);
911 return true;
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
920 if (args.size()==0)
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();
928 uint i;
929 for (i=0; i<num; ++i)
931 CActor *actor=CActorManager::getActor(i);
932 if (actor != NULL)
933 actor->setActivity(CActor::NOTHING);
936 else
938 // iterate through the actor names
939 for (unsigned i=0;i<args.size();i++)
941 CActor *actor=CActorManager::getActor(args[i]);
942 if (actor==0)
943 nlinfo("Unknown actor: '%s'",args[i].c_str());
944 else
945 CActorManager::getActor(args[i])->setActivity(CActor::NOTHING);
949 return true;
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]);
964 if (actor0)
966 if (actor1)
968 actor0->doFight(actor1);
969 nlinfo("ACTOR %s Attacking ACTOR: %s",args[0].c_str(),args[1].c_str());
970 // actor1->doFight(actor0);
972 else if (group1)
974 actor0->doFight(group1);
975 nlinfo("ACTOR %s Attacking GROUP: %s",args[0].c_str(),args[1].c_str());
976 // group1->doFight(actor0);
978 else
980 CEntityId id;
981 id.fromString( args[1].c_str() );
982 actor0->doFight(id);
983 nlinfo("ACTOR %s Attacking entity with SID: %s",args[0].c_str(),args[1].c_str());
986 else if (group0)
988 if (actor1)
990 group0->doFight(actor1);
991 nlinfo("GROUP %s Attacking ACTOR: %s",args[0].c_str(),args[1].c_str());
992 // actor1->doFight(group0);
994 else if (group1)
996 group0->doFight(group1);
997 nlinfo("GROUP %s Attacking GROUP: %s",args[0].c_str(),args[1].c_str());
998 // group1->doFight(group0);
1000 else
1002 CEntityId id;
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());
1010 return true;
1013 // Command for displaying all of or named actors
1014 NLMISC_COMMAND(actorDisplay,"List the actors","[<actor name>...]")
1016 COMMAND_MACRO_RECORD_TEST
1018 if(args.size() <1)
1020 // list all the actors' stats
1021 for (unsigned i=0;i<CActorManager::numActors();++i)
1022 CActorManager::getActor(i)->display();
1024 else
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]);
1030 if (actor==0)
1031 log.displayNL("Unknown actor: '%s'",args[i].c_str());
1032 else
1033 actor->display(&log);
1037 return true;
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);
1050 return true;
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);
1062 return true;
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
1071 CAiMgr::write();
1072 return true;
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);
1082 return true;
1086 //-------------------------------------------------------------------------
1087 // MANAGING MACROS
1089 // Command for creating a new macro
1090 NLMISC_COMMAND(macroRecord,"Start recording a new macro","<macro name>")
1092 if(args.size() !=1)
1093 return false;
1095 CMacroManager::recordMacro(args[0]);
1097 return true;
1101 // Command for adding a line to a macro
1102 NLMISC_COMMAND(macroStopRecord,"stop macro recording","")
1104 if(args.size() !=0)
1105 return false;
1107 CMacroManager::stopRecord();
1109 return true;
1113 // Command for executing a macro
1114 NLMISC_COMMAND(macroExecute,"Execute one or more macros","<macro name> [<macro name>...]")
1116 if(args.size() <1)
1117 return false;
1119 for (unsigned i=0;i<args.size();++i)
1120 CMacroManager::execute(args[i],log);
1122 return true;
1126 // Command for executing a macro
1127 NLMISC_COMMAND(macroDisplay,"Display list of macros or contents of the given macros","")
1129 if(args.size()==0)
1130 CMacroManager::listMacros(&log);
1131 else
1132 for (unsigned i=0;i<args.size();++i)
1133 CMacroManager::displayMacro(args[i], &log);
1136 return true;
1139 // Command for executing a macro
1140 NLMISC_COMMAND(sheetDisplay,"Display list of sheets read","")
1142 CSheets::display(&log);
1143 return true;
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)
1152 return false;
1154 const string &scriptName = args[0];
1155 double spawnX;
1156 NLMISC::fromString(args[1], spawnX);
1157 double spawnY;
1158 NLMISC::fromString(args[2], spawnY);
1159 double spacing;
1160 NLMISC::fromString(args[3], spacing);
1161 uint width;
1162 NLMISC::fromString(args[4], width);
1163 const string &extension = args[5];
1164 vector<string> filters;
1166 uint i;
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(); )
1178 bool match = false;
1180 if (files[i][0] != '_')
1182 for (i=0; !match && i<filters.size(); ++i)
1183 if (testWildCard(*itr, filters[i]))
1184 match = true;
1187 if (match)
1188 ++itr;
1189 else
1190 itr = files.erase(itr);
1194 if (files.empty())
1195 return false;
1197 char buffer[2048];
1199 COFile script;
1200 if (!script.open(scriptName))
1201 return false;
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;
1228 uint inLine = 0;
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));
1238 ++inLine;
1239 cx += spacing;
1241 if (inLine >= width)
1243 cx = spawnX;
1244 cy += spacing;
1245 inLine = 0;
1249 script.close();
1251 return true;
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;
1260 uint i;
1261 for (i=0; i<args.size(); ++i)
1262 commandLine += string(" ")+args[i];
1264 // remove file first
1265 CFile::deleteFile(scriptfile);
1267 // generate script
1268 ICommand::execute(commandLine, log);
1270 // run script
1271 ICommand::execute("runScript ags_generated "+scriptfile, log);
1273 return true;
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)
1280 return false;
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;
1297 uint i;
1298 for (i=1; i<args.size(); ++i)
1299 commandLine += string(" ")+args[i];
1301 // generate script
1302 ICommand::execute(commandLine, log);
1305 // run script
1306 ICommand::execute("runScript "+scriptName+" "+scriptfile, log);
1308 return true;
1312 //NLMISC_COMMAND
1314 NLMISC_COMMAND(setTargets, "set targets for a multi cast", "<caster entityId> <cast_time> [<target1 entityId> ...]")
1316 if (args.size() < 2)
1317 return false;
1319 CEntityId caster;
1320 list<CEntityId> targets;
1322 caster.fromString(args[0].c_str());
1324 CMirrorPropValueList<TDataSetRow> targetList(TheDataset, caster, "TargetList");
1326 targetList.clear();
1328 uint i;
1329 for (i=args.size()-1; i>=2; --i)
1331 CEntityId target;
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)));
1341 return true;
1344 //-------------------------------------------------------------------------
1345 } // end of namespace AGS_TEST