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/>.
21 #include "nel/misc/command.h"
22 #include "nel/misc/file.h"
23 #include "nel/misc/i_xml.h"
24 #include "nel/misc/path.h"
26 #include "gpm_service.h"
27 #include "world_position_manager.h"
29 using namespace NLMISC
;
30 using namespace NLNET
;
35 * Commands for GPMS initialisation
38 // Enable/disable player speed checking
39 NLMISC_COMMAND(setPlayerSpeedCheck
, "set player speed check (0=disable)", "entityId <0/1>")
45 id
.fromString(args
[0].c_str());
47 NLMISC::fromString(args
[1], enable
);
49 CWorldEntity
*entity
= CWorldPositionManager::getEntityPtr( CWorldPositionManager::getEntityIndex(id
) );
50 if (entity
== NULL
|| entity
->PlayerInfos
== NULL
)
52 log
.displayNL("CGPMPlayerPrivilegeInst::callback(): entity '%d' is not a player", id
.toString().c_str());
56 // enable/disable speed checking
57 entity
->PlayerInfos
->CheckSpeed
= enable
;
63 // Command to load a continent
64 NLMISC_COMMAND(loadContinent
, "load a continent in the gpms","index name filename")
70 NLMISC::fromString(args
[0], continent
);
71 string name
= args
[1];
72 string file
= args
[2];
74 CWorldPositionManager::loadContinent(name
, file
, continent
);
79 // Command to remove a continent
80 NLMISC_COMMAND(removeContinent
, "remove a continent from the gpms","index")
86 NLMISC::fromString(args
[0], continent
);
88 CWorldPositionManager::removeContinent(continent
);
93 // Command to init trigger manager
94 NLMISC_COMMAND(initPatatManager
, "init/reset patat&pacs trigger manager", "")
96 CWorldPositionManager::initPatatManager();
100 // Command to load patat
101 NLMISC_COMMAND(loadPatatFile
, "load a patat file in patat manager (.prim file)", "filename")
103 if (args
.size() != 1)
106 CWorldPositionManager::loadPatatsInFile(args
[0]);
110 // Command to load patat
111 NLMISC_COMMAND(loadPatatPath
, "load a patat path in patat manager (all .prim files in path)", "pathname")
113 if (args
.size() != 1)
116 CWorldPositionManager::loadPatatsInPath(args
[0]);
120 // Command to load patat
121 NLMISC_COMMAND(loadPatatManagerFile
, "load a patat manager file", "filename")
123 if (args
.size() != 1)
126 CWorldPositionManager::loadPatatManagerFile(args
[0]);
130 // Command to load patat
131 NLMISC_COMMAND(savePatatManagerFile
, "save a patat manager file", "filename")
133 if (args
.size() != 1)
136 CWorldPositionManager::savePatatManagerFile(args
[0]);
140 // Add CPrimZone class filter
141 NLMISC_COMMAND(addPrimZoneFilter
, "add one or more positive filters on CPrimZone for PatatSubscribeManager", "<className> ...")
147 for (i
=0; i
<args
.size(); ++i
)
148 CWorldPositionManager::addPrimZoneFilter(args
[i
]);
153 // Remove CPrimZone class filter
154 NLMISC_COMMAND(removePrimZoneFilter
, "remove one or more positive filters on CPrimZone for PatatSubscribeManager", "<className> ...")
160 for (i
=0; i
<args
.size(); ++i
)
161 CWorldPositionManager::removePrimZoneFilter(args
[i
]);
166 // Reset CPrimZone class filter
167 NLMISC_COMMAND(resetPrimZoneFilter
, "reset all positive filters on CPrimZone for PatatSubscribeManager", "")
169 CWorldPositionManager::resetPrimZoneFilter();
175 NLMISC_COMMAND(getPatatEntryIndex
, "Get the patat entry index at a pos", "x, y")
177 if (args
.size() != 2)
182 NLMISC::fromString(args
[0], pos
.x
);
183 NLMISC::fromString(args
[1], pos
.y
);
186 nlinfo("entryIndex(%.1f, %.1f) = %d", pos
.x
, pos
.y
, CWorldPositionManager::getEntryIndex(pos
));
194 * Commands for entity management
198 // Command to add an entity to the GPMS
200 NLMISC_COMMAND(addEntity,"Add entity to GPMS","entity Id, entity PosX(meters), entity PosY, entity PosZ, service Id")
202 // check args, if there s not the right number of parameter, return bad
203 if(args.size() != 5) return false;
207 id.fromString(args[0].c_str());
208 sint32 PosX, PosY, PosZ;
209 NLMISC::fromString(args[1], PosX);
210 NLMISC::fromString(args[2], PosY);
211 NLMISC::fromString(args[3], PosZ);
214 NLMISC::fromString(args[4], FeId);
216 // display the result on the displayer
217 log.displayNL("Add entity Id %s to GPMS", id.toString().c_str() );
219 TheMirror.addEntity( id );
220 CWorldPositionManager::onAddEntity( TheDataset.getDataSetRow(id) ); // because a local change is not notified
221 //CWorldPositionManager::onAddEntity(id, 1000 * PosX, 1000*PosY, 1000*PosZ, 0.0f, INVALID_CONTINENT_INDEX, 0, CTickEventHandler::getGameCycle() - 1, CSheetId(0),FeId);
222 CWorldPositionManager::teleport( id, PosX, PosY, PosZ, 0.0f, INVALID_CONTINENT_INDEX, 0, CTickEventHandler::getGameCycle() );
228 // Command to add x non player characters in the GPMS
229 /*NLMISC_COMMAND(addNpcs,"Add npcs in the GPMS","number of entities to add")
231 srand( (uint) CTickEventHandler::getGameCycle() );
233 // check args, if there s not the right number of parameter, return bad
234 if(args.size() != 1) return false;
238 NLMISC::fromString(args[0], num);
242 id.setType( RYZOMID::npc );
244 for (uint i = 0 ; i < num ; ++i)
246 sint32 x = 1000 * (rand() % 1500 + 17000);
247 sint32 y = 1000 * (rand() % 2000 - 31000);
249 id.setShortId( i+9000 );
250 CWorldPositionManager::addEntity(id, x, y, 0, 0.0f, INVALID_CONTINENT_INDEX, 0, CTickEventHandler::getGameCycle(),CSheetId(0),0);
253 log.displayNL("Add %d entities in the GPMS", num);
260 // Command to add x player characters in the GPMS
261 /*NLMISC_COMMAND(addPlayers,"Add players in the GPMS","number of entities to add")
263 srand( (uint) CTickEventHandler::getGameCycle() );
265 // check args, if there s not the right number of parameter, return bad
266 if(args.size() != 1) return false;
270 NLMISC::fromString(args[0], num);
275 id.setType( RYZOMID::player );
277 for (uint i = 0 ; i < num ; ++i)
279 sint32 x = 1000 * (rand() % 1500 + 17000);
280 sint32 y = 1000 * (rand() % 2000 - 31000);
282 id.setShortId( i+1000 );
283 CWorldPositionManager::addEntity(id, x, y, 0 , 0.0f, INVALID_CONTINENT_INDEX, 0, CTickEventHandler::getGameCycle() - 1,CSheetId(0),0);
286 log.displayNL("Add %d entities in the GPMS", num);
292 // Command to remove an entity from the GPMS
293 NLMISC_COMMAND(removeEntity
,"Remove an entity from the GPMS","entity Id")
295 // check args, if there s not the right number of parameter, return bad
296 if(args
.size() != 1) return false;
300 id
.fromString(args
[0].c_str());
302 // display the result on the displayer
303 log
.displayNL("Remove entity Id %s from GPMS", id
.toString().c_str());
305 TDataSetRow index
= CWorldPositionManager::getEntityIndex(id
);
306 TheMirror
.removeEntity( id
);
307 CWorldPositionManager::onRemoveEntity( index
); // because a local change is not notified
313 NLMISC_COMMAND(removeAllEntities
,"remove AiVision entities for the specified service (or all services if no param)","service id")
318 NLMISC::fromString(args
[0], serviceId
);
320 NLNET::TServiceId
ServiceId(serviceId
);
322 //CWorldPositionManager::removeAiVisionEntitiesForService( ServiceId );
326 CWorldPositionManager::removeAllEntities();
335 * Commands for position management
338 // Command to move an entity in the GPMS
339 NLMISC_COMMAND(moveEntity
,"move an entity in the GPMS","entity Id, newPos X (meters), newPos Y, newPos Z")
342 // check args, if there s not the right number of parameter, return bad
343 if(args.size() != 4) return false;
347 NLMISC::fromString(args[0], Id);
349 NLMISC::fromString(args[1], PosX);
351 NLMISC::fromString(args[2], PosY);
353 NLMISC::fromString(args[3], PosZ);
357 id.fromString(args[0].c_str());
359 // display the result on the displayer
360 log.displayNL("move entity Id %d from GPMS", Id);
362 CWorldPositionManager::setEntityPosition(id,1000*PosX, 1000*PosY, 1000*PosZ, 0.0f, CTickEventHandler::getGameCycle() );
367 // Command to move an entity in the GPMS
368 NLMISC_COMMAND(teleportEntity
,"teleport an entity", "entity Id, newPos X (meters), newPos Y, newPos Z, cell")
370 // check args, if there s not the right number of parameter, return bad
371 if(args
.size() != 5) return false;
375 id
.fromString(args
[0].c_str());
379 NLMISC::fromString(args
[1], PosX
);
381 NLMISC::fromString(args
[2], PosY
);
383 NLMISC::fromString(args
[3], PosZ
);
385 NLMISC::fromString(args
[4], Cell
);
387 // display the result on the displayer
388 log
.displayNL("teleport entity %s", id
.toString().c_str());
390 TDataSetRow index
= CWorldPositionManager::getEntityIndex(id
);
391 CWorldPositionManager::teleport(index
, 1000*PosX
, 1000*PosY
, 1000*PosZ
, 0.0f
, INVALID_CONTINENT_INDEX
, Cell
, CTickEventHandler::getGameCycle());
396 // Command to move an entity in the GPMS
397 NLMISC_COMMAND(setEntityContent
,"set an entity content", "CEntityId entityId, [CEntityId containeeId, CSheetId(int) containeeSheet]+")
399 // check args, if there s not the right number of parameter, return bad
403 if ((args
.size() & 1) == 0)
409 id
.fromString(args
[0].c_str());
412 vector
<CEntitySheetId
> content
;
415 while (arg
< args
.size())
418 id
.fromString(args
[arg
].c_str());
420 NLMISC::fromString(args
[arg
+1], sheetId
);
421 CSheetId
sheet(sheetId
);
422 content
.push_back(CEntitySheetId(id
, sheet
));
425 CWorldPositionManager::setContent(CWorldPositionManager::getEntityIndex(id
), content
);
434 // Command to display all vision or the vision for the specified entity
435 NLMISC_COMMAND(mirrorAroundEntity
,"Ask a local mirror arround an entity","service Id, entity Id")
437 // check args, if there s not the right number of parameter, return bad
445 NLMISC::fromString(args
[0], serviceId
);
446 NLNET::TServiceId
ServiceId(serviceId
);
448 NLMISC::fromString(args
[1], Id
);
450 list
< string
> properties
;
451 properties
.push_back( "X" );
452 properties
.push_back( "Y" );
453 properties
.push_back( "Z" );
454 properties
.push_back( "Theta" );
455 properties
.push_back( "Sheet" );
459 id
.fromString(args
[0].c_str());
461 CWorldPositionManager::requestForEntityAround( ServiceId
, id
, properties
);
469 // Command to display a single entity or more, with full debug info
470 NLMISC_COMMAND(displayEntity
,"display single or more entities in the gpms","[CEntityId]*")
472 if (args
.size() == 0)
474 CWorldPositionManager::displayAllEntitiesFullDebug(&log
);
479 for (i
=0; i
<args
.size(); ++i
)
482 id
.fromString(args
[i
].c_str());
483 CWorldPositionManager::displayEntityFullDebug(CWorldPositionManager::getEntityIndex(id
), &log
);
490 // Command to display all entities
491 NLMISC_COMMAND(displayEntities
,"display entities in the gpms","[CEntityId]*")
493 if (args
.size() == 0)
495 CWorldPositionManager::displayAllEntities(&log
);
500 for (i
=0; i
<args
.size(); ++i
)
503 id
.fromString(args
[i
].c_str());
504 CWorldPositionManager::displayEntity(CWorldPositionManager::getEntityIndex(id
), &log
);
511 // Command to display all entities
512 NLMISC_COMMAND(displayPlayers
,"display all players in the gpms","")
514 CWorldPositionManager::displayAllPlayers(&log
);
519 // Command to display all entities
520 NLMISC_COMMAND(displayPlayersPosHistory
, "display all players positions history","")
522 CWorldPositionManager::displayPlayersPosHistory(&log
);
527 // Command to display entities vision (no parameter = all players)
528 NLMISC_COMMAND(displayVision
, "display entities vision", "[CEntityId]*")
530 if (args
.size() == 0)
532 CWorldPositionManager::displayAllVisions(&log
);
537 for (i
=0; i
<args
.size(); ++i
)
540 id
.fromString(args
[i
].c_str());
541 CWorldPositionManager::displayVision(id
, &log
);
549 // Command to display pacs triggers
550 NLMISC_COMMAND(displayPacsTriggers
, "display pacs triggers", "")
552 CWorldPositionManager::displayPacsTriggers(&log
);
556 // Command to display entities vision (no parameter = all players)
557 NLMISC_COMMAND(displayTriggers
, "display triggers", "")
559 CWorldPositionManager::displayTriggers(&log
);
563 // Command to display entities vision (no parameter = all players)
564 NLMISC_COMMAND(displayTriggerInfo
, "display trigger info", "triggerName(string)")
566 if (args
.size() != 1)
568 CWorldPositionManager::displayTriggerInfo(args
[0], &log
);
572 // Command to display entities vision (no parameter = all players)
573 NLMISC_COMMAND(displayTriggerSubscribers
, "display triggerSubscribers", "")
575 CWorldPositionManager::displaySubscribers(&log
);
579 // Command to display entities vision (no parameter = all players)
580 NLMISC_COMMAND(displayTriggerSubscriberInfo
, "display subscriber info", "triggerName(string)")
582 if (args
.size() != 1)
585 NLMISC::fromString(args
[0], serviceId
);
587 CWorldPositionManager::displaySubscriberInfo(TServiceId(serviceId
), &log
);
593 NLMISC_COMMAND(trackEntity
, "get track of an entity position", "id")
605 if (sscanf(args
[0].c_str(), "(%" NL_I64
"x:%x:%x:%x)", &id
, &type
, &creatorId
, &dynamicId
) != 4)
608 eid
.setShortId( id
);
610 eid
.setCreatorId( creatorId
);
611 eid
.setDynamicId( dynamicId
);
613 pCGPMS
->Tracked
.push_back(eid
);
615 pCGPMS
->EntityTrack1
= pCGPMS
->EntityTrack0
;
616 pCGPMS
->EntityTrack0
= eid
;
621 NLMISC_COMMAND(removeTracks
, "remove all entities tracks", "")
623 pCGPMS
->Tracked
.clear();
628 NLMISC_COMMAND(autoCheck
, "perform autocheck", "")
630 CWorldPositionManager::autoCheck(&log
);
635 NLMISC_COMMAND(displayVisionCells
, "display VisionCells info", "")
637 CWorldPositionManager::displayVisionCells(&log
);
645 NLMISC_COMMAND(test_vision
, "", "")
647 CVector
centerPos(4700, -3500, 0);
651 for (i
=-7; i
<=+7; ++i
)
653 for (j
=-7; j
<=+7; ++j
)
656 id
.setType( RYZOMID::npc
);
658 sint32 x
= (sint32
)((centerPos
.x
+i
*16)*1000);
659 sint32 y
= (sint32
)((centerPos
.y
+j
*16)*1000);
661 id
.setShortId( k
+9000 );
664 TheMirror
.addEntity( false, id
);
665 TDataSetRow index
= TheDataset
.getDataSetRow(id
);
666 CWorldPositionManager::onAddEntity( index
); // because a local change is not notified
667 //CWorldPositionManager::onAddEntity(id, 1000 * PosX, 1000*PosY, 1000*PosZ, 0.0f, INVALID_CONTINENT_INDEX, 0, CTickEventHandler::getGameCycle() - 1/*CTickEventHandler::getGameCycles()*/,/*sheet*/CSheetId(0),FeId);
668 CWorldPositionManager::teleport( index
, x
, y
, 0, 0.0f
, INVALID_CONTINENT_INDEX
, 0, CTickEventHandler::getGameCycle() );
673 id
.setType( RYZOMID::player
);
674 sint32 x
= (sint32
)((centerPos
.x
)*1000);
675 sint32 y
= (sint32
)((centerPos
.y
)*1000);
676 id
.setShortId( k
+9000 );
678 TheMirror
.addEntity( false, id
);
679 TDataSetRow index
= TheDataset
.getDataSetRow(id
);
680 CWorldPositionManager::onAddEntity( index
); // because a local change is not notified
681 //CWorldPositionManager::onAddEntity(id, 1000 * PosX, 1000*PosY, 1000*PosZ, 0.0f, INVALID_CONTINENT_INDEX, 0, CTickEventHandler::getGameCycle() - 1/*CTickEventHandler::getGameCycles()*/,/*sheet*/CSheetId(0),FeId);
682 CWorldPositionManager::teleport( index
, x
, y
, 0, 0.0f
, INVALID_CONTINENT_INDEX
, 0, CTickEventHandler::getGameCycle() );
688 NLMISC_COMMAND(dumpRingVisionUniverse
, "dump state information from the ring vision universe", "")
693 pCGPMS
->RingVisionUniverse
->dump(log
);
697 NLMISC_COMMAND(resetRingVision
, "resets a character's vision in ring mode", "<datasetrow>")
702 uint32 idx
=NLMISC::CSString(args
[0]).atoui();
703 TDataSetRow
row(*(TDataSetRow
*)&idx
);
705 pCGPMS
->RingVisionUniverse
->forceResetVision(row
);