Fix classique titles display
[ryzomcore.git] / ryzom / client / src / commands.cpp
blobb5cc4f0a35721971e925ae682e62fa09dd173c8d
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2019 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2012 Matt RAYKOWSKI (sfb) <matt.raykowski@gmail.com>
6 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
7 // Copyright (C) 2013-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
8 //
9 // This program is free software: you can redistribute it and/or modify
10 // it under the terms of the GNU Affero General Public License as
11 // published by the Free Software Foundation, either version 3 of the
12 // License, or (at your option) any later version.
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU Affero General Public License for more details.
19 // You should have received a copy of the GNU Affero General Public License
20 // along with this program. If not, see <http://www.gnu.org/licenses/>.
25 //////////////
26 // Includes //
27 //////////////
29 #include "stdpch.h"
31 // very nice \\// :)
33 #include "nel/misc/bit_mem_stream.h"
34 #include "nel/misc/command.h"
35 #include "nel/misc/i18n.h"
36 #include "nel/misc/o_xml.h"
37 #include "nel/misc/async_file_manager.h"
39 #include "nel/3d/u_particle_system_instance.h"
40 #include "nel/3d/u_play_list_manager.h"
41 #include "nel/3d/u_animation_set.h"
42 #include "nel/3d/u_landscape.h"
43 #include "nel/3d/u_play_list.h"
44 #include "nel/3d/u_animation.h"
45 #include "nel/3d/u_scene.h"
46 #include "nel/3d/u_track.h"
48 #include "nel/ligo/primitive.h"
50 #include "game_share/player_visual_properties.h"
51 #include "game_share/generic_xml_msg_mngr.h"
52 #include "game_share/visual_slot_manager.h"
53 #include "game_share/mode_and_behaviour.h"
54 #include "game_share/brick_types.h"
55 #include "game_share/time_weather_season/time_and_season.h"
57 #include "entity_animation_manager.h"
58 #include "ingame_database_manager.h"
59 #include "world_database_manager.h"
60 #include "string_manager_client.h"
61 #include "interface_v3/input_handler_manager.h"
62 #include "interface_v3/people_interraction.h"
63 #include "client_chat_manager.h"
64 #include "continent_manager.h"
65 #include "interface_v3/interface_manager.h"
66 #include "interface_v3/group_compas.h"
67 #include "init_main_loop.h"
68 #include "sheet_manager.h"
69 #include "sound_manager.h"
70 #include "nel/gui/group_editbox.h"
71 #include "debug_client.h"
72 #include "user_entity.h"
73 #include "time_client.h"
74 #include "net_manager.h"
75 #include "pacs_client.h"
76 #include "continent.h"
77 #include "ig_client.h"
78 #include "commands.h"
79 #include "entities.h"
80 #include "teleport.h"
81 #include "nel/misc/cdb_leaf.h"
82 #include "view.h"
83 #include "misc.h"
84 #include "demo.h"
85 #include "dummy_progress.h"
86 #include "interface_v3/sphrase_manager.h"
87 #include "interface_v3/sbrick_manager.h"
88 #include "interface_v3/inventory_manager.h"
89 #include "interface_v3/action_handler_help.h"
90 #include "projectile_manager.h"
91 #include "fx_manager.h"
92 #include "actions_client.h"
93 #include "attack_list.h"
94 #include "interface_v3/player_trade.h"
95 #include "nel/gui/ctrl_base_button.h"
96 #include "weather.h"
97 #include "forage_source_cl.h"
98 #include "connection.h"
99 #include "nel/gui/lua_object.h"
100 #include "nel/gui/lua_ihm.h"
101 #include "interface_v3/lua_ihm_ryzom.h"
102 #include "init.h"
103 #include "interface_v3/people_interraction.h"
104 #include "far_tp.h"
105 #include "zone_util.h"
106 #include "nel/gui/lua_manager.h"
107 #include "user_agent.h"
108 #include "item_group_manager.h"
111 // Only the define FINAL_VERSION can be defined on the project, not in this file
112 // to desactive some commands
115 #ifdef DEBUG_NEW
116 #define new DEBUG_NEW
117 #endif
120 ////////////////
121 // Namespaces //
122 ////////////////
123 using namespace NLMISC;
124 using namespace NLNET;
125 using namespace NL3D;
126 using namespace std;
129 /////////////
130 // Externs //
131 /////////////
132 extern CGenericXmlMsgHeaderManager GenericMsgHeaderMngr;
133 extern CEntityAnimationManager *EAM;
134 extern CClientChatManager ChatMngr;
135 extern ULandscape *Landscape;
136 extern UScene *Scene;
137 extern CLog g_log;
138 extern CEntityManager EntitiesMngr;
140 ///////////////
141 // Variables //
142 ///////////////
144 NLLIGO::CPrimitives *LDPrim = 0;
145 static std::vector<UInstance> ShapeAddedByCommand; // list of shapes added with the 'shape' command
149 ///////////////
150 // FUNCTIONS //
151 ///////////////
153 // Function to release all things allocated for commands.
154 void releaseCommands()
156 if(LDPrim)
158 delete LDPrim;
159 LDPrim = 0;
163 //////////////
164 // COMMANDS //
165 //////////////
167 // 'follow' : To Follow the target.
168 NLMISC_COMMAND(follow, "Follow the target", "")
170 // switch
171 if(UserEntity->follow())
172 UserEntity->disableFollow();
173 else
174 // enable follow, reseting the camera rotation
175 UserEntity->enableFollow(true);
176 return true;
179 NLMISC_COMMAND(where, "Ask information on the position", "")
181 // Check parameters.
182 if(args.empty())
183 { // Create the message and send.
184 const char *msgName = "COMMAND:WHERE";
185 CBitMemStream out;
186 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
188 NetMngr.push(out);
190 else
191 nlwarning("command 'where': unknown message named '%s'", msgName);
192 return true;
194 return false;
197 NLMISC_COMMAND(who, "Display all players currently in region","[<options (GM, channel name)>]")
199 // Check parameters.
200 if(args.size() > 1)
201 return false;
203 CBitMemStream out;
204 if(!GenericMsgHeaderMngr.pushNameToStream("DEBUG:WHO", out))
206 nlwarning("Unknown message name DEBUG:WHO");
207 return false;
210 string opt;
211 if ( args.size() == 1 )
213 opt = args[0];
215 out.serial(opt);
216 NetMngr.push(out);
217 return true;
220 /***********************************************************************
221 GROUP COMMANDS
222 ***********************************************************************/
225 NLMISC_COMMAND(listGroup, "list all available group", "")
227 CItemGroupManager::getInstance()->listGroup();
228 return true;
231 NLMISC_COMMAND(equipGroup, "equip group <name>", "name")
233 CInterfaceManager *pIM = CInterfaceManager::getInstance();
235 if(args.empty())
237 pIM->displaySystemInfo(CI18N::get("cmdEquipGroupUsage1"));
238 pIM->displaySystemInfo(CI18N::get("cmdEquipGroupUsage2"));
239 return false;
241 if(CItemGroupManager::getInstance()->equipGroup(args[0]))
243 string msg = CI18N::get("cmdEquipGroupSuccess");
244 //Use utf-8 string because group name can contain accentued characters (and stuff like that)
245 string nameUC = args[0];
246 strFindReplace(msg, "%name", nameUC);
247 pIM->displaySystemInfo(msg);
248 return true;
250 else
252 string msg = CI18N::get("cmdEquipGroupError");
253 //Use utf-8 string because group name can contain accentued characters (and stuff like that)
254 string nameUC = args[0];
255 strFindReplace(msg, "%name", nameUC);
256 pIM->displaySystemInfo(msg);
257 return false;
261 NLMISC_COMMAND(moveGroup, "move group <name> to <dst>", "name dst")
263 CInterfaceManager *pIM = CInterfaceManager::getInstance();
265 if(args.empty() || args.size() < 2)
267 pIM->displaySystemInfo(CI18N::get("cmdMoveGroupUsage1"));
268 pIM->displaySystemInfo(CI18N::get("cmdMoveGroupUsage2"));
269 pIM->displaySystemInfo(CI18N::get("cmdMoveGroupUsage3"));
270 return false;
273 if(CItemGroupManager::getInstance()->moveGroup(args[0], INVENTORIES::toInventory(args[1])))
275 string msg = CI18N::get("cmdMoveGroupSuccess");
276 //Use utf-8 string because group name can contain accentued characters (and stuff like that)
277 string nameUC = args[0];
278 strFindReplace(msg, "%name", nameUC);
279 strFindReplace(msg, "%inventory", args[1]);
280 pIM->displaySystemInfo(msg);
281 return true;
283 else
285 string msg = CI18N::get("cmdMoveGroupError");
286 //Use utf-8 string because group name can contain accentued characters (and stuff like that)
287 string nameUC = args[0];
288 strFindReplace(msg, "%name", nameUC);
289 strFindReplace(msg, "%inventory", args[1]);
290 pIM->displaySystemInfo(msg);
291 return false;
296 NLMISC_COMMAND(createGroup, "create group <name> [true](create a <remove> for every unequiped item)", "name [removeUnequiped]")
298 CInterfaceManager *pIM = CInterfaceManager::getInstance();
299 if(args.empty())
301 pIM->displaySystemInfo(CI18N::get("cmdCreateGroupUsage1"));
302 pIM->displaySystemInfo(CI18N::get("cmdCreateGroupUsage2"));
303 pIM->displaySystemInfo(CI18N::get("cmdCreateGroupUsage3"));
304 return false;
306 bool removeUnequiped = false;
307 if(args.size() > 1)
308 removeUnequiped = !args[1].empty();
309 if(CItemGroupManager::getInstance()->createGroup(args[0], removeUnequiped))
311 string msg;
312 if(removeUnequiped)
313 msg = CI18N::get("cmdCreateGroupSuccess2");
314 else
315 msg = CI18N::get("cmdCreateGroupSuccess1");
316 //Use utf-8 string because group name can contain accentued characters (and stuff like that)
317 string nameUC = args[0];
318 strFindReplace(msg, "%name", nameUC);
319 pIM->displaySystemInfo(msg);
320 return true;
322 else
324 string msg = CI18N::get("cmdCreateGroupError");
325 //Use utf-8 string because group name can contain accentued characters (and stuff like that)
326 string nameUC = args[0];
327 strFindReplace(msg, "%name", nameUC);
328 pIM->displaySystemInfo(msg);
329 return false;
336 NLMISC_COMMAND(deleteGroup, "delete group <name>", "name")
338 CInterfaceManager *pIM = CInterfaceManager::getInstance();
339 if(args.empty())
341 pIM->displaySystemInfo(CI18N::get("cmdDeleteGroupUsage1"));
342 pIM->displaySystemInfo(CI18N::get("cmdDeleteGroupUsage2"));
343 return false;
345 if(CItemGroupManager::getInstance()->deleteGroup(args[0]))
347 string msg = CI18N::get("cmdDeleteGroupSuccess");
348 //Use utf-8 string because group name can contain accentued characters (and stuff like that)
349 string nameUC = args[0];
350 strFindReplace(msg, "%name", nameUC);
351 pIM->displaySystemInfo(msg);
352 return true;
354 else
356 string msg = CI18N::get("cmdDeleteGroupError");
357 //Use utf-8 string because group name can contain accentued characters (and stuff like that)
358 string nameUC = args[0];
359 strFindReplace(msg, "%name", nameUC);
360 pIM->displaySystemInfo(msg);
361 return false;
365 NLMISC_COMMAND(naked, "get naked !", "")
367 std::string handPath = "LOCAL:INVENTORY:HAND:";
368 std::string equipPath = "LOCAL:INVENTORY:EQUIP:";
369 std::string hotbarPath = "LOCAL:INVENTORY:HOTBAR:";
370 uint32 i;
371 for (i = 0; i < MAX_HANDINV_ENTRIES; ++i)
373 CInventoryManager::getInstance()->unequip(handPath + NLMISC::toString(i));
377 for (i = 0; i < MAX_EQUIPINV_ENTRIES; ++i)
379 CInventoryManager::getInstance()->unequip(equipPath + NLMISC::toString(i));
383 for (i = 0; i < MAX_HOTBARINV_ENTRIES; ++i)
385 CInventoryManager::getInstance()->unequip(hotbarPath + NLMISC::toString(i));
388 return true;
392 NLMISC_COMMAND(nude, "get nude !", "")
394 std::string handPath = "LOCAL:INVENTORY:HAND:";
395 std::string equipPath = "LOCAL:INVENTORY:EQUIP:";
396 uint32 i;
397 for (i = 0; i < MAX_HANDINV_ENTRIES; ++i)
399 CInventoryManager::getInstance()->unequip(handPath + NLMISC::toString(i));
403 for (i = 0; i < MAX_EQUIPINV_ENTRIES; ++i)
405 CInventoryManager::getInstance()->unequip(equipPath + NLMISC::toString(i));
409 return true;
412 NLMISC_COMMAND(freeHands, "free hands !", "")
414 std::string handPath = "LOCAL:INVENTORY:HAND:";
415 uint32 i;
416 for (i = 0; i < MAX_HANDINV_ENTRIES; ++i)
418 CInventoryManager::getInstance()->unequip(handPath + NLMISC::toString(i));
420 return true;
423 NLMISC_COMMAND(afk, "Set the player as 'away from keyboard'","[<custom text>]")
425 string customText;
426 if (!args.empty())
428 customText = args[0];
430 for(uint i = 1; i < args.size(); ++i )
432 customText += " ";
433 customText += args[i];
436 if (UserEntity != NULL)
437 UserEntity->setAFK(true,customText);
439 CBitMemStream out;
440 if(!GenericMsgHeaderMngr.pushNameToStream("DEBUG:AFK", out))
442 nlwarning("Unknown message name DEBUG:AFK");
443 return false;
445 NetMngr.push(out);
447 return true;
450 NLMISC_COMMAND(selfkill, "Kill the player ","")
452 CBitMemStream out;
453 if(!GenericMsgHeaderMngr.pushNameToStream("COMMAND:SELFKILL", out))
455 nlwarning("Unknown message name COMMAND:SELFKILL");
456 return false;
458 NetMngr.push(out);
459 return true;
462 bool randomCheckCharset(std::string const& str)
464 std::string::const_iterator it, itEnd = str.end();
465 for (it=str.begin(); it!=itEnd; ++it)
466 if (*it<'0' || *it>'9')
467 return false;
468 return true;
471 // returns true if a<=b
472 bool randomLexicographicLess(std::string a, std::string b)
474 // Remove leading zeros
475 while (a.length()>1 && a[0]=='0')
476 a = a.substr(1);
477 while (b.length()>1 && b[0]=='0')
478 b = b.substr(1);
479 // Longest is the biggest
480 if (a.length()>b.length())
481 return false;
482 if (a.length()<b.length())
483 return true;
484 // Skip equal characters
485 size_t i = 0;
486 while (i<a.length() && a[i]==b[i])
487 ++i;
488 // If all characters are equal a==b
489 if (i==a.length())
490 return false;
491 // Check highest weight different character
492 return a[i] < b[i];
495 bool randomFromString(std::string const& str, sint16& val, sint16 min = -32768, sint16 max = 32767)
497 bool negative = str[0]=='-';
498 std::string sAbsVal = str.substr(negative?1:0);
499 // Check we have only numerical characters
500 if (!randomCheckCharset(sAbsVal))
501 return false;
502 // Check sign
503 if (negative && min>0) return false;
504 if (!negative && max<0) return false;
505 // Check number is not too big nor too small with a lexicographic compare
506 std::string smin = NLMISC::toString(std::max<sint16>(min,-min));
507 std::string smax = NLMISC::toString(std::max<sint16>(max,-max));
508 bool tooSmall = false, tooBig = false;
509 if (min>=0 && randomLexicographicLess(sAbsVal, smin))
510 tooSmall = true;
511 if (min<0 && randomLexicographicLess(smin, sAbsVal))
512 tooSmall = true;
513 if (max>=0 && randomLexicographicLess(smax, sAbsVal))
514 tooBig = true;
515 if (max<0 && randomLexicographicLess(sAbsVal, smax))
516 tooBig = true;
517 if (!tooSmall && !tooBig)
519 NLMISC::fromString(str, val);
520 return true;
522 else
523 return false;
526 NLMISC_COMMAND(random, "Roll a dice and say the result around","[<min>] <max> [h|ide]")
528 // Check parameters.
529 if (args.size() < 1 || args.size() > 3)
530 return false;
532 sint16 min = 1;
533 sint16 max;
535 bool hide = args[args.size()-1][0] == 'h';
537 if (!randomFromString(args[0], max))
539 CInterfaceManager *pIM = CInterfaceManager::getInstance();
540 string msg = CI18N::get("uiRandomBadParameter");
541 strFindReplace(msg, "%s", args[0] );
542 pIM->displaySystemInfo(msg);
543 return false;
545 if (args.size() > 1 && args[1][0] != 'h')
547 if (!randomFromString(args[1], min))
549 CInterfaceManager *pIM = CInterfaceManager::getInstance();
550 string msg = CI18N::get("uiRandomBadParameter");
551 strFindReplace(msg, "%s", args[1] );
552 pIM->displaySystemInfo(msg);
553 return false;
556 if (min>max)
557 std::swap(min, max);
559 if (UserEntity != NULL)
560 UserEntity->rollDice(min, max, hide);
562 return true;
565 //-----------------------------------------------
566 // 'dumpShapePos' : Dump Last Added Shape Pos
567 //-----------------------------------------------
568 NLMISC_COMMAND(dumpShapePos, "Dump Last Added Shape Pos.", "")
570 #if FINAL_VERSION
571 if (!hasPrivilegeDEV() &&
572 !hasPrivilegeSGM() &&
573 !hasPrivilegeGM() &&
574 !hasPrivilegeVG() &&
575 !hasPrivilegeSG() &&
576 !hasPrivilegeG() &&
577 !hasPrivilegeEM() &&
578 !hasPrivilegeEG())
579 return true;
580 #endif // FINAL_VERSION
582 if (ShapeAddedByCommand.empty())
584 nlwarning("No shape created yet");
585 return false;
588 CInterfaceManager *IM = CInterfaceManager::getInstance();
589 CVector pos = ShapeAddedByCommand.back().getPos();
590 IM->displaySystemInfo(toString("Shape Pos = %f, %f, %f", pos.x, pos.y, pos.z));
591 return true;
593 //-----------------------------------------------
594 // 'clearShape' : Remove all shapes added with the 'shape' command
595 //-----------------------------------------------
596 NLMISC_COMMAND(clearShape, "Remove all shapes added with the 'shape' command.", "")
598 #if FINAL_VERSION
599 /*if (!hasPrivilegeDEV() &&
600 !hasPrivilegeSGM() &&
601 !hasPrivilegeGM() &&
602 !hasPrivilegeVG() &&
603 !hasPrivilegeSG() &&
604 !hasPrivilegeG() &&
605 !hasPrivilegeEM() &&
606 !hasPrivilegeEG())
607 return true;*/
608 #endif // FINAL_VERSION
610 if (ShapeAddedByCommand.empty())
612 nlwarning("No shape created yet");
613 return false;
616 if (!Scene) return false;
617 for(uint k = 0; k < ShapeAddedByCommand.size(); ++k)
619 Scene->deleteInstance(ShapeAddedByCommand[k]);
621 ShapeAddedByCommand.clear();
622 return true;
625 //-----------------------------------------------------
626 // 'setShapeX' : Set X position for last created shape
627 //-----------------------------------------------------
628 NLMISC_COMMAND(setShapeX, "Set X position for last created shape.", "<x coordinate>")
630 #if FINAL_VERSION
631 /*if (!hasPrivilegeDEV() &&
632 !hasPrivilegeSGM() &&
633 !hasPrivilegeGM() &&
634 !hasPrivilegeVG() &&
635 !hasPrivilegeSG() &&
636 !hasPrivilegeG() &&
637 !hasPrivilegeEM() &&
638 !hasPrivilegeEG())
639 return true;*/
640 #endif // FINAL_VERSION
642 if (args.size() != 1) return false;
643 if (ShapeAddedByCommand.empty())
645 nlwarning("No shape created yet");
646 return false;
648 float coord;
649 bool valid_coord;
650 if (args[0][0] == '+')
651 valid_coord = fromString(args[0].substr(1), coord);
652 else
653 valid_coord = fromString(args[0], coord);
655 if (!valid_coord)
657 nlwarning("Can't get position");
658 return false;
660 CVector pos = ShapeAddedByCommand.back().getPos();
661 if (args[0][0] == '+')
662 pos.x += coord;
663 else
664 pos.x = coord;
665 ShapeAddedByCommand.back().setPos(pos);
666 return true;
669 //-----------------------------------------------------
670 // 'setShapeY' : Set Y position for last created shape
671 //-----------------------------------------------------
672 NLMISC_COMMAND(setShapeY, "Set Y position for last created shape.", "<y coordinate>")
674 #if FINAL_VERSION
675 /*if (!hasPrivilegeDEV() &&
676 !hasPrivilegeSGM() &&
677 !hasPrivilegeGM() &&
678 !hasPrivilegeVG() &&
679 !hasPrivilegeSG() &&
680 !hasPrivilegeG() &&
681 !hasPrivilegeEM() &&
682 !hasPrivilegeEG())
683 return true;*/
684 #endif // FINAL_VERSION
686 if (args.size() != 1) return false;
687 if (ShapeAddedByCommand.empty())
689 nlwarning("No shape created yet");
690 return false;
692 float coord;
693 bool valid_coord;
694 if (args[0][0] == '+')
695 valid_coord = fromString(args[0].substr(1), coord);
696 else
697 valid_coord = fromString(args[0], coord);
699 if (!valid_coord)
701 nlwarning("Can't get position");
702 return false;
704 CVector pos = ShapeAddedByCommand.back().getPos();
705 if (args[0][0] == '+')
706 pos.y += coord;
707 else
708 pos.y = coord;
709 ShapeAddedByCommand.back().setPos(pos);
710 return true;
713 //-----------------------------------------------------
714 // 'setShapeZ' : Set Z position for last created shape
715 //-----------------------------------------------------
716 NLMISC_COMMAND(setShapeZ, "Set Z position for last created shape.", "<z coordinate>")
718 #if FINAL_VERSION
719 /*if (!hasPrivilegeDEV() &&
720 !hasPrivilegeSGM() &&
721 !hasPrivilegeGM() &&
722 !hasPrivilegeVG() &&
723 !hasPrivilegeSG() &&
724 !hasPrivilegeG() &&
725 !hasPrivilegeEM() &&
726 !hasPrivilegeEG())
727 return true;*/
728 #endif // FINAL_VERSION
730 if (args.size() != 1) return false;
731 if (ShapeAddedByCommand.empty())
733 nlwarning("No shape created yet");
734 return false;
736 float coord;
737 bool valid_coord;
738 if (args[0][0] == '+')
739 valid_coord = fromString(args[0].substr(1), coord);
740 else
741 valid_coord = fromString(args[0], coord);
743 if (!valid_coord)
745 nlwarning("Can't get position");
746 return false;
748 CVector pos = ShapeAddedByCommand.back().getPos();
749 if (args[0][0] == '+')
750 pos.z += coord;
751 else
752 pos.z = coord;
753 ShapeAddedByCommand.back().setPos(pos);
754 return true;
758 //-----------------------------------------------------
759 // 'setShapeDir' : Set direction angle for last created shape
760 //-----------------------------------------------------
761 NLMISC_COMMAND(setShapeDir, "Set direction angle for last created shape.", "<angle>")
763 #if FINAL_VERSION
764 /*if (!hasPrivilegeDEV() &&
765 !hasPrivilegeSGM() &&
766 !hasPrivilegeGM() &&
767 !hasPrivilegeVG() &&
768 !hasPrivilegeSG() &&
769 !hasPrivilegeG() &&
770 !hasPrivilegeEM() &&
771 !hasPrivilegeEG())
772 return true;*/
773 #endif // FINAL_VERSION
775 if (args.size() != 1) return false;
776 if (ShapeAddedByCommand.empty())
778 nlwarning("No shape created yet");
779 return false;
781 float angle;
782 if (!fromString(args[0], angle))
784 nlwarning("Can't get angle");
785 return false;
788 CMatrix dir;
789 dir.identity();
790 CVector vangle = CVector(sin(angle), cos(angle), 0.f);
791 CVector vi = vangle^CVector(0.f, 0.f, 1.f);
792 CVector vk = vi^vangle;
793 dir.setRot(vi, vangle, vk, true);
794 // Set Orientation : User Direction should be normalized.
795 ShapeAddedByCommand.back().setRotQuat(dir.getRot());
797 return true;
801 //-----------------------------------------------
802 // 'shape' : Add a shape in the scene.
803 //-----------------------------------------------
804 NLMISC_COMMAND(shape, "Add a shape in the scene.", "<shape file>")
806 #if FINAL_VERSION
807 /* if (!hasPrivilegeDEV() &&
808 !hasPrivilegeSGM() &&
809 !hasPrivilegeGM() &&
810 !hasPrivilegeVG() &&
811 !hasPrivilegeSG() &&
812 !hasPrivilegeG() &&
813 !hasPrivilegeEM() &&
814 !hasPrivilegeEG())
815 return true;*/
816 #endif // FINAL_VERSION
818 if(args.size() < 1)
820 nlwarning("Command 'shape': need at least 1 parameter, try '/help shape' for more details.");
821 return false;
823 if (!Scene)
825 nlwarning("No scene available");
826 return false;
828 UInstance instance = Scene->createInstance(args[0]);
829 if(!instance.empty())
831 ShapeAddedByCommand.push_back(instance);
832 // Set the position
833 instance.setPos(UserEntity->pos());
834 instance.setClusterSystem(UserEntity->getClusterSystem()); // for simplicity, assume it is in the same
835 // cluster system than the user
836 // Compute the direction Matrix
837 CMatrix dir;
838 dir.identity();
839 CVector vi = UserEntity->dir()^CVector(0.f, 0.f, 1.f);
840 CVector vk = vi^UserEntity->dir();
841 dir.setRot(vi, UserEntity->dir(), vk, true);
842 // Set Orientation : User Direction should be normalized.
843 instance.setRotQuat(dir.getRot());
844 // if the shape is a particle system, additionnal parameters are user params
845 UParticleSystemInstance psi;
846 psi.cast (instance);
847 if (!psi.empty())
849 // set each user param that is present
850 for(uint k = 0; k < 4; ++k)
852 if (args.size() >= (k + 2))
854 float uparam;
855 if (fromString(args[k + 1], uparam))
857 psi.setUserParam(k, uparam);
859 else
861 nlwarning("Cant read param %d", k);
867 else
869 nlwarning("Command 'shape': cannot find the shape %s.", args[0].c_str());
872 // Command Well Done
873 return true;
876 NLMISC_COMMAND(bugReport, "Call the bug report tool with dump", "<AddScreenshot>")
878 const char *brname[] = { "bug_report.exe", "bug_report_r.exe", "bug_report_rd.exe", "bug_report_df.exe", "bug_report_d.exe" };
880 string brn;
882 for (uint i = 0; i < sizeof(brname)/sizeof(brname[0]); i++)
884 if (CFile::fileExists (brname[i]))
886 brn = brname[i];
887 break;
891 if (brn.empty())
893 log.displayNL("bug_report*.exe not found");
894 return false;
897 string sys;
899 sys = "Language "+CI18N::getCurrentLanguageName() +" ";
901 if (!args.empty())
903 uint8 quality;
904 fromString(args[0], quality);
905 if (quality == 0)
906 quality = 80;
908 CBitmap btm;
909 Driver->getBuffer(btm);
910 string filename = CFile::findNewFile (getLogDirectory() + "screenshot.jpg");
911 COFile fs(filename);
912 btm.writeJPG(fs, quality);
913 sys += "AttachedFile "+filename+" ";
916 sys += NLMISC::toString("ClientVersion %s ", getVersion().c_str());
918 // for now, set the same version than client one
919 sys += NLMISC::toString("ShardVersion %s ", getVersion().c_str());
921 if (ClientCfg.Local)
922 sys += "ShardName OFFLINE ";
924 FILE *fp = nlfopen (getLogDirectory() + "bug_report.txt", "wb");
925 if (fp != NULL)
927 string res = addSlashR(getDebugInformation());
929 // must put \r\n each line
930 fprintf(fp, "%s", res.c_str());
932 // // must put \r\n each line
933 // fprintf (fp, "UserId: %u\r\n", NetMngr.getUserId());
934 // fprintf (fp, "Player Name: '%s'.\r\n", UserEntity->getName().toString().c_str());
935 // fprintf (fp, "UserPosition: %.2f %.2f %.2f\r\n", UserEntity->pos().x, UserEntity->pos().y, UserEntity->pos().z);
936 // fprintf (fp, "ViewPosition: %.2f %.2f %.2f\r\n", View.viewPos().x, View.viewPos().y, View.viewPos().z);
937 // time_t ts; time( &ts );
938 // fprintf (fp, "LocalTime: %s\r\n", NLMISC::IDisplayer::dateToHumanString( ts ) );
939 // fprintf (fp, "ServerTick: %u\r\n", NetMngr.getCurrentServerTick());
940 // fprintf (fp, "ConnectState: %s\r\n", NetMngr.getConnectionStateCStr());
941 // fprintf (fp, "LocalAddress: %s\r\n", NetMngr.getAddress().asString().c_str());
943 fclose (fp);
945 sys += "DumpFilename bug_report.txt ";
948 nlinfo ("Calling for bug report : '%s %s'", brn.c_str(), sys.c_str());
950 launchProgram(brn, sys);
952 // give some cpu to the launched application
953 nlSleep (3000);
955 return true;
960 // This command is use to do all admin execution commands on you
962 // For example: "/a God 1" will set you in god mode
965 NLMISC_COMMAND(a, "Execute an admin command on you","<cmd> <arg>")
967 if(args.empty())
968 return false;
970 CBitMemStream out;
971 if (!GenericMsgHeaderMngr.pushNameToStream("COMMAND:ADMIN", out))
972 return false;
974 string cmd, arg;
975 cmd = args[0];
976 for (uint i = 1; i < args.size(); i++)
978 std::string tmp = args[i];
980 if (!arg.empty())
981 arg += ' ';
982 if (tmp.find(' ') != std::string::npos)
984 arg += "\"" + tmp + "\"";
986 else
988 arg += tmp;
991 bool onTarget = false;
992 out.serial (onTarget);
993 out.serial (cmd);
994 out.serial (arg);
995 NetMngr.push (out);
997 return true;
1002 // This command is use to do all admin execution commands on the target
1004 // For example: "/b God 1" will set the target in god mod
1007 NLMISC_COMMAND(b, "Execute an admin command on your target","<cmd> <arg>")
1009 if(args.empty())
1010 return false;
1012 CBitMemStream out;
1013 if (!GenericMsgHeaderMngr.pushNameToStream("COMMAND:ADMIN", out))
1014 return false;
1016 string cmd, arg;
1017 cmd = args[0];
1018 for (uint i = 1; i < args.size(); i++)
1020 std::string tmp = args[i];
1022 if (!arg.empty())
1023 arg += ' ';
1024 if (tmp.find(' ') != std::string::npos)
1026 arg += "\"" + tmp + "\"";
1028 else
1030 arg += tmp;
1033 bool onTarget = true;
1034 out.serial (onTarget);
1035 out.serial (cmd);
1036 out.serial (arg);
1037 NetMngr.push (out);
1039 return true;
1044 // This command is used to do all admin execution commands on a character
1046 // For example: "/c charName God 1" will set god mod on character if it's online, or keep
1047 // command for wait character login
1050 NLMISC_COMMAND(c, "Execute an admin command on character name","<Character Name> <cmd> <arg>")
1052 if(args.size() < 2)
1053 return false;
1055 CBitMemStream out;
1056 if (!GenericMsgHeaderMngr.pushNameToStream("COMMAND:ADMIN_OFFLINE", out))
1057 return false;
1059 string characterName, cmd, arg;
1061 characterName = args[0];
1062 cmd = args[1];
1063 for (uint i = 2; i < args.size(); i++)
1065 std::string tmp = args[i];
1067 if (!arg.empty())
1068 arg += ' ';
1069 if (tmp.find(' ') != std::string::npos)
1071 arg += "\"" + tmp + "\"";
1073 else
1075 arg += tmp;
1078 out.serial (characterName);
1079 out.serial (cmd);
1080 out.serial (arg);
1081 NetMngr.push (out);
1083 return true;
1086 NLMISC_COMMAND(boxes, "Show/Hide selection boxes", "[<state> : 0 to Hide, anything else to Show. Invert the current state if nothing specified.]")
1088 #if FINAL_VERSION
1089 if (!ClientCfg.ExtendedCommands) return false;
1091 if( !ClientCfg.Local && !hasPrivilegeDEV() && !hasPrivilegeSGM() && !hasPrivilegeGM() )
1092 return true;
1093 #endif // FINAL_VERSION
1095 // Invert Current State
1096 if(args.empty())
1098 // Invert the current value.
1099 ClientCfg.DrawBoxes = !ClientCfg.DrawBoxes;
1100 return true;
1102 // Set Current State
1103 else if(args.size() == 1)
1105 // Invert the current value.
1106 fromString(args[0], ClientCfg.DrawBoxes);
1107 return true;
1109 // Bad parameters.
1110 else
1111 return false;
1114 NLMISC_COMMAND(dump, "Command to create a file with the current state of the client", "[<dump name>]")
1116 if(args.size() > 1)
1117 return false;
1119 string dumpName;
1120 if(args.size() == 1)
1121 dumpName = args[0];
1122 else
1123 dumpName = "default";
1125 dump(dumpName);
1126 return true;
1129 NLMISC_COMMAND(verbose, "Enable/Disable some Debug Information", "none or magic")
1131 // Check parameters.
1132 if(args.size() != 1)
1134 // Help
1135 CInterfaceManager *IM = CInterfaceManager::getInstance();
1136 IM->displaySystemInfo("This command need 1 parameter :");
1137 IM->displaySystemInfo("<string> :");
1138 IM->displaySystemInfo("- none(to remove all verboses)");
1139 IM->displaySystemInfo("- magic(to add debug infos about magic)");
1140 IM->displaySystemInfo("- anim (to add debug infos about animation)");
1142 else
1144 std::string type = NLMISC::toLowerAscii(args[0]);
1145 if (type == "none")
1146 Verbose = VerboseNone;
1147 else if(type == "magic")
1148 Verbose |= VerboseMagic;
1149 else if(type == "anim")
1150 Verbose |= VerboseAnim;
1151 else
1153 CInterfaceManager *IM = CInterfaceManager::getInstance();
1154 IM->displaySystemInfo("This command need 1 parameter :");
1155 IM->displaySystemInfo("<string> :");
1156 IM->displaySystemInfo("- none(to remove all verboses)");
1157 IM->displaySystemInfo("- magic(to add debug infos about magic)");
1158 IM->displaySystemInfo("- anim (to add debug infos about animation)");
1161 return true;
1164 NLMISC_COMMAND(verboseAnimSelection, "Enable/Disable the animation log for the current selection", "")
1166 // Check parameters.
1167 if(args.size() != 0)
1168 return false;
1170 VerboseAnimSelection = !VerboseAnimSelection;
1171 if(VerboseAnimSelection)
1172 nlinfo("Enable VerboseAnimSelection");
1173 else
1174 nlinfo("Disable VerboseAnimSelection");
1176 return true;
1179 NLMISC_COMMAND(verboseAnimUser, "Enable/Disable the animation log for the user", "")
1181 // Check parameters.
1182 if(args.size() != 0)
1183 return false;
1185 VerboseAnimUser = !VerboseAnimUser;
1186 if(VerboseAnimUser)
1187 nlinfo("Enable VerboseAnimUser");
1188 else
1189 nlinfo("Disable VerboseAnimUser");
1191 return true;
1194 NLMISC_COMMAND(verboseDatabase, "Enable/Disable the log for the database", "")
1196 // Check parameters.
1197 if(args.size() != 0)
1198 return false;
1200 bool v = NLMISC::ICDBNode::isDatabaseVerbose();
1201 NLMISC::ICDBNode::setVerboseDatabase( !v );
1203 if( !v )
1204 nlinfo("Enable VerboseDatabase");
1205 else
1206 nlinfo("Disable VerboseDatabase");
1208 return true;
1211 NLMISC_COMMAND(verbosePropertiesLoggingMode, "Set logging mode", "")
1213 // Check parameters.
1214 if(args.size() != 0)
1215 return false;
1217 CNetworkConnection::LoggingMode = !CNetworkConnection::LoggingMode;
1218 if(CNetworkConnection::LoggingMode)
1219 nlinfo("Enable LoggingMode");
1220 else
1221 nlinfo("Disable LoggingMode");
1223 return true;
1226 NLMISC_COMMAND(logEntities, "Write the position and orientation af all entities in the vision in the file 'entities.txt'", "")
1228 // Check parameters
1229 if(args.size() != 0)
1230 return false;
1232 // Log entities
1233 EntitiesMngr.writeEntities();
1235 // Command well done.
1236 return true;
1239 NLMISC_COMMAND(log, "Add/Del Positive/Negative Filters for logs", "Log System <debug, info, warning, assert>, Type <pos/neg/del/reset>, Filter <string>")
1241 // check args, if there s not the right number of parameter, return bad
1242 if(args.size() < 2 || args.size() > 3)
1243 return false;
1245 CLog *logSys;
1246 // Debug log system.
1247 if (string(args[0].c_str()) == "debug")
1248 logSys = DebugLog;
1249 // Info log system.
1250 else if(string(args[0].c_str()) == "info")
1251 logSys = InfoLog;
1252 // Warning log system.
1253 else if(string(args[0].c_str()) == "warning")
1254 logSys = WarningLog;
1255 // Assert log system.
1256 else if(string(args[0].c_str()) == "assert")
1257 logSys = AssertLog;
1258 // Unknown Log System -> return false.
1259 else
1260 return false;
1262 // Add a positive filter.
1263 if (string(args[1].c_str()) == "pos")
1264 logSys->addPositiveFilter(args[2].c_str());
1265 // Add a negative filter.
1266 else if(string(args[1].c_str()) == "neg")
1267 logSys->addNegativeFilter(args[2].c_str());
1268 // Removes a filter by name (in both filters).
1269 else if(string(args[1].c_str()) == "del")
1270 logSys->removeFilter(args[2].c_str());
1271 // Reset both filters.
1272 else if(string(args[1].c_str()) == "reset")
1273 logSys->resetFilters();
1274 // Unknown Filter -> return false.
1275 else
1276 return false;
1278 // Command well done.
1279 return true;
1282 NLMISC_COMMAND(execScript, "Execute a script file (.cmd)","<FileName>")
1284 int size = (int)args.size();
1285 if (size != 1)
1286 return false;
1288 CIFile iFile;
1290 if (iFile.open(CPath::lookup(args[0], false)))
1292 char line[512];
1293 char *buffer;
1294 // Read line by line and execute each line
1296 sint inComment= 0;
1297 bool eof = false;
1298 while (!eof)
1300 buffer = &line[0];
1301 uint read = 0;
1302 for(;;)
1304 if (read == 512 -1)
1306 *buffer = '\0';
1307 break;
1312 // read one byte
1313 iFile.serialBuffer ((uint8 *)buffer, 1);
1315 catch (const EFile &)
1317 *buffer = '\0';
1318 eof = true;
1319 break;
1322 if (*buffer == '\n')
1324 *buffer = '\0';
1325 break;
1328 // skip '\r' char
1329 if (*buffer != '\r')
1331 buffer++;
1332 read++;
1336 // execute line
1337 if (strlen(line) > 0)
1339 // if not a single comment
1340 if(strncmp(line, "//", 2)!=0)
1342 if(strncmp(line, "/*", 2)==0)
1343 inComment++;
1344 if(inComment<=0)
1346 string ucline(line);
1347 CInterfaceManager::parseTokens(ucline);
1348 ICommand::execute(ucline, g_log);
1350 if(strncmp(line, "*/", 2)==0)
1351 inComment--;
1355 // end?
1356 if (iFile.eof())
1357 eof = true;
1359 iFile.close();
1361 else
1363 CInterfaceManager::getInstance()->displaySystemInfo("Cannot open file");
1366 return true;
1370 NLMISC_COMMAND(db, "Modify Database","<Property> <Value>")
1372 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1373 int size = (int)args.size();
1374 if (size == 2)
1376 #if !FINAL_VERSION
1377 // check if 2nd arg is a sheet name
1378 if (args[1].empty()) return false;
1379 sint64 value;
1380 if (isalpha(args[1][0]))
1382 CSheetId sheet(args[1]);
1383 value = (sint64) sheet.asInt();
1385 else
1387 // Convert the string into an sint64.
1388 fromString(args[1], value);
1391 // Set the property.
1392 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(args[0], false);
1393 if(node)
1394 node->setValue64(value);
1395 else
1396 pIM->displaySystemInfo(toString("DB '%s' does not exist.", args[0].c_str()));
1397 #else
1398 pIM->displaySystemInfo("Can't write to DB when in Final Version.");
1399 #endif
1401 else if (size == 1)
1403 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(args[0], false);
1404 if(node)
1406 sint64 prop = node->getValue64();
1407 string str = toString(prop);
1408 pIM->displaySystemInfo(str);
1409 nlinfo("%s", str.c_str());
1411 else
1412 pIM->displaySystemInfo(toString("DB '%s' does not exist.", args[0].c_str()));
1413 return true;
1415 else
1416 return false;
1418 return true;
1421 NLMISC_COMMAND(setItemName, "set name of items, sbrick, etc..","<sheet_id> <name> <desc> <desc2>")
1423 if (args.size() < 2) return false;
1424 CSheetId id(args[0]);
1425 string name;
1426 name = args[1];
1427 string desc;
1428 string desc2;
1429 if (args.size() > 2)
1430 desc = args[2];
1431 if (args.size() > 3)
1432 desc2 = args[3];
1434 STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance();
1435 if (pSMC)
1436 pSMC->replaceSBrickName(id, name, desc, desc2);
1437 else
1438 return false;
1439 return true;
1443 NLMISC_COMMAND(setMissingDynstringText, "set text of missing dynamic string"," <name> <text>")
1445 if (args.size() < 2) return false;
1446 string name;
1447 name = args[0];
1448 string text;
1449 text = args[1];
1451 STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance();
1452 if (pSMC)
1453 pSMC->replaceDynString(name, text);
1454 else
1455 return false;
1456 return true;
1461 /////////////////////////////////////////////////////////////////////////////
1462 /////////////////////////////////////////////////////////////////////////////
1463 /////////////////////////////////////////////////////////////////////////////
1464 /////////////////////////////////////////////////////////////////////////////
1465 /////////// COMMANDS after should NOT appear IN the FINAL VERSION ///////////
1466 /////////////////////////////////////////////////////////////////////////////
1467 /////////////////////////////////////////////////////////////////////////////
1468 /////////////////////////////////////////////////////////////////////////////
1469 /////////////////////////////////////////////////////////////////////////////
1470 /////////////////////////////////////////////////////////////////////////////
1471 #if !FINAL_VERSION
1473 NLMISC_COMMAND(ah, "Launch an action handler", "<ActionHandler> <AHparam>")
1475 if (args.empty())
1476 return false;
1478 if (!ClientCfg.AllowDebugLua && toLowerAscii(args[0]) == "lua")
1480 return false; // not allowed!!
1483 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1484 if (args.size() == 1)
1486 CAHManager::getInstance()->runActionHandler(args[0], NULL);
1488 else
1490 CAHManager::getInstance()->runActionHandler(args[0], NULL, args[1]);
1493 return true;
1496 static void setDynString(uint32 strID, const std::string &value)
1498 STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance();
1499 pSMC->receiveString(strID, value);
1500 CBitMemStream bm;
1501 if (bm.isReading()) bm.invert();
1502 bm.serial(strID);
1503 bm.serial(strID);
1504 bm.invert();
1505 bm.seek(0, NLMISC::IStream::begin);
1506 pSMC->receiveDynString(bm);
1509 // for debug purposes, insert a string in the
1510 NLMISC_COMMAND(setDynString, "set a dynamic string","<stringID> <asciiValue>")
1512 if (args.size() != 2) return false;
1513 uint32 strID;
1514 fromString(args[0], strID);
1515 setDynString(strID, args[1]);
1516 return true;
1519 class CAnimProgress : public IProgressCallback
1521 public:
1522 // Update the progress bar
1523 virtual void progress (float value)
1525 // can't do anything if no driver
1526 if(Driver == NULL)
1527 return;
1528 // Get croped value
1529 value = getCropedValue (value);
1530 // Set matrix
1531 Driver->setMatrixMode2D11();
1532 // Display a progress bar background
1533 Driver->drawQuad (PROGRESS_BAR_LEFT, 0.5f-PROGRESS_BAR_HEIGHT/2.0f, PROGRESS_BAR_LEFT+ PROGRESS_BAR_WIDTH, 0.5f+PROGRESS_BAR_HEIGHT/2.0f,
1534 PROGRESS_BAR_BG_COLOR);
1535 // Display a progress bar
1536 Driver->drawQuad (PROGRESS_BAR_LEFT, 0.5f-PROGRESS_BAR_HEIGHT/2.0f, PROGRESS_BAR_LEFT+value*PROGRESS_BAR_WIDTH, 0.5f+PROGRESS_BAR_HEIGHT/2.0f,
1537 PROGRESS_BAR_COLOR);
1538 if(TextContext != NULL)
1540 // Init the Pen.
1541 TextContext->setKeep800x600Ratio(false);
1542 TextContext->setColor(CRGBA(255,255,255));
1543 TextContext->setFontSize(20);
1544 TextContext->setHotSpot(UTextContext::MiddleMiddle);
1546 // Display the Text.
1547 TextContext->printfAt(0.5f, 0.5f, _ProgressMessage.c_str());
1549 // Display to screen.
1550 Driver->swapBuffers();
1552 // New message
1553 void newMessage(const std::string &message) {_ProgressMessage = message;}
1555 private:
1556 std::string _ProgressMessage;
1559 NLMISC_COMMAND(reloadSearchPaths, "reload the search paths","")
1561 if (!args.empty()) return false;
1562 CPath::memoryUncompress();
1563 CAnimProgress progress;
1564 // remove all objects that may depend on an animation
1565 CProjectileManager::getInstance().reset();
1567 // Pathes
1568 progress.newMessage("Reloading pathes");
1569 progress.progress(0.0f);
1570 progress.pushCropedValues(0.0f, 1.0f);
1573 addSearchPaths(progress);
1574 CPath::memoryCompress();
1575 return true;
1578 NLMISC_COMMAND(reloadAnim, "reload animations","")
1580 CPath::memoryUncompress();
1581 CAnimProgress dummy;
1582 // remove all objects that may depend on an animation
1583 CProjectileManager::getInstance().reset();
1585 // Pathes
1586 dummy.newMessage("Pathes");
1587 dummy.progress(0.0f);
1588 dummy.pushCropedValues(0.0f, 0.5f);
1591 addSearchPaths(dummy);
1593 if (ClientCfg.UpdatePackedSheet)
1595 for(uint i = 0; i < ClientCfg.UpdatePackedSheetPath.size(); i++)
1597 dummy.progress((float)i/(float)ClientCfg.UpdatePackedSheetPath.size());
1598 dummy.pushCropedValues ((float)i/(float)ClientCfg.UpdatePackedSheetPath.size(), (float)(i+1)/(float)ClientCfg.UpdatePackedSheetPath.size());
1599 CPath::addSearchPath(ClientCfg.UpdatePackedSheetPath[i], true, false, &dummy);
1600 dummy.popCropedValues();
1605 dummy.popCropedValues();
1606 // Animations
1607 dummy.newMessage("Anims");
1608 dummy.progress(0.5f);
1609 dummy.pushCropedValues(0.5f, 1.0f);
1610 EAM->load(dummy, true);
1611 dummy.popCropedValues();
1612 // Reload Animations
1613 EntitiesMngr.reloadAnims();
1614 CPath::memoryCompress();
1615 return true;
1618 NLMISC_COMMAND(reloadAttack, "reload attack", "")
1620 if (!args.empty()) return false;
1621 // remove all objects that may depend on an animation
1622 ClientSheetsStrings.memoryUncompress();
1623 CProjectileManager::getInstance().reset();
1624 EntitiesMngr.removeAllAttachedFX();
1625 FXMngr.reset();
1627 std::vector<std::string> exts;
1628 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1629 // replace attack list of creature in place (so pointers on character sheets remains valid)
1630 CSheetManager sheetManager;
1631 exts;
1632 // exts.push_back("creature");
1633 exts.push_back("race_stats");
1634 NLMISC::IProgressCallback progress;
1635 sheetManager.loadAllSheet(progress, true, false, false, true, &exts);
1637 const CSheetManager::TEntitySheetMap &sm = SheetMngr.getSheets();
1638 for(CSheetManager::TEntitySheetMap::const_iterator it = sm.begin(); it != sm.end(); ++it)
1640 if (it->second.EntitySheet && it->second.EntitySheet->Type == CEntitySheet::FAUNA)
1642 // find matching sheet in new sheetManager
1643 const CEntitySheet *other = sheetManager.get(it->first);
1644 if (other)
1646 // replace data in place
1647 ((CCharacterSheet &) *it->second.EntitySheet).AttackLists = ((const CCharacterSheet &) *other).AttackLists;
1650 else if(it->second.EntitySheet && it->second.EntitySheet->Type == CEntitySheet::RACE_STATS)
1652 // find matching sheet in new sheetManager
1653 const CEntitySheet *other = sheetManager.get(it->first);
1654 if (other)
1656 // replace data in place
1657 ((CRaceStatsSheet &) *it->second.EntitySheet).AttackLists = ((const CRaceStatsSheet &) *other).AttackLists;
1661 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1662 CAttackListManager::getInstance().release();
1663 // form to reload all sheets of interest
1664 exts.clear();
1665 exts.push_back("attack_list");
1666 exts.push_back("animation_fx_set");
1667 exts.push_back("id_to_string_array");
1668 CDummyProgress dp;
1669 SheetMngr.loadAllSheet(dp, true, false, true, true, &exts);
1670 CAttackListManager::getInstance().init();
1672 ClientSheetsStrings.memoryCompress();
1673 return true;
1676 NLMISC_COMMAND(reloadSky, "reload new style sky", "")
1678 if (!args.empty()) return false;
1679 ContinentMngr.reloadSky();
1680 return false;
1684 NLMISC_COMMAND(missionReward, "debug"," ")
1686 if (args.size() == 1)
1688 uint8 index;
1689 fromString(args[0], index);
1690 CBitMemStream out;
1691 if(GenericMsgHeaderMngr.pushNameToStream("BOTCHAT:COMPLETE_MISSION", out))
1693 out.serial(index);
1694 NetMngr.push(out);
1696 else
1697 nlwarning("<CBotChat acceptMission> : unknown message name : BOTCHAT:COMPLETE_MISSION");
1698 return true;
1700 return false;
1703 NLMISC_COMMAND(missionProgress, "debug"," ")
1705 if (args.size() == 1)
1707 uint8 index;
1708 fromString(args[0], index);
1709 CBitMemStream out;
1710 if(GenericMsgHeaderMngr.pushNameToStream("BOTCHAT:PROGRESS_MISSION", out))
1712 out.serial(index);
1713 NetMngr.push(out);
1715 else
1716 nlwarning("<CBotChat acceptMission> : unknown message name : BOTCHAT:PROGRESS_MISSION");
1717 return true;
1719 return false;
1723 NLMISC_COMMAND( displayDBModifs, "display server database modification in the chat window"," ")
1725 if ( VerboseDatabase )
1726 CInterfaceManager::getInstance()->getChatOutput()->addTextChild("the database is already in verbose mode",CRGBA(255,255,255,255));
1727 else
1729 CInterfaceManager::getInstance()->getChatOutput()->addTextChild("database is now in verbose mode",CRGBA(255,255,255,255));
1730 VerboseDatabase = true;
1732 return true;
1735 NLMISC_COMMAND( hideDBModifs, "stop displaying server database modification in the chat window"," ")
1737 if ( !VerboseDatabase )
1738 CInterfaceManager::getInstance()->getChatOutput()->addTextChild("the database is already not in verbose mode",CRGBA(255,255,255,255));
1739 else
1741 CInterfaceManager::getInstance()->getChatOutput()->addTextChild("database is not in verbose mode anymore",CRGBA(255,255,255,255));
1742 VerboseDatabase = false;
1744 return true;
1749 NLMISC_COMMAND(save_sentences, "save sentences"," ")
1751 CSentenceDisplayer::saveSentences();
1752 return true;
1756 NLMISC_COMMAND(getSheetId, "get_sheet_id","<sheet file name>")
1758 if (args.size() != 1)
1759 return false;
1760 CSheetId id(args[0]);
1762 CInterfaceManager::getInstance()->displaySystemInfo(toString(id.asInt()));
1763 return true;
1766 NLMISC_COMMAND(getSheetName, "get_sheet_name","<Sheet Id>")
1768 if (args.size() != 1)
1769 return false;
1770 uint32 nId;
1771 fromString(args[0], nId);
1772 CSheetId id( nId );
1774 string name = id.toString();
1777 CInterfaceManager::getInstance()->displaySystemInfo(name);
1778 return true;
1781 NLMISC_COMMAND(forgetAll, "forget all bricks", "")
1783 // Check parameters.
1784 if(args.size() != 0)
1786 return false;
1788 char buf[100];
1789 for (uint i = 0;i<20;i++)
1791 sprintf(buf,"SERVER:BRICK_FAMILY:%d:BRICKS",i);
1792 CCDBNodeLeaf * node= NLGUI::CDBManager::getInstance()->getDbProp(buf);
1793 node->setValue64(0);
1795 return true;
1798 NLMISC_COMMAND(usePreprogMagic, "use the specified magic preprog sentence", "<sentence id>")
1800 // Check parameters.
1801 if(args.size() != 1)
1803 return false;
1806 // Create the message for the server to execute a phrase.
1807 const string msgName = "SENTENCE:EXECUTE";
1808 CBitMemStream out;
1809 if(GenericMsgHeaderMngr.pushNameToStream("SENTENCE:EXECUTE", out))
1811 uint8 phrase;
1812 fromString(args[0], phrase);
1813 out.serial(phrase);
1815 BRICK_TYPE::EBrickType type = BRICK_TYPE::MAGIC;
1816 out.serialEnum( type );
1818 NetMngr.push(out);
1820 else
1821 nlwarning("mainLoop : unknown message name : '%s'", msgName.c_str());
1823 return true;
1826 NLMISC_COMMAND(usePreprogCombat, "use the specified combat preprog sentence", "<sentence id>")
1828 // Check parameters.
1829 if(args.size() != 1)
1831 return false;
1834 // Create the message for the server to execute a phrase.
1835 const string msgName = "SENTENCE:EXECUTE";
1836 CBitMemStream out;
1837 if(GenericMsgHeaderMngr.pushNameToStream("SENTENCE:EXECUTE", out))
1839 uint8 phrase;
1840 fromString(args[0], phrase);
1841 out.serial(phrase);
1843 BRICK_TYPE::EBrickType type = BRICK_TYPE::COMBAT;
1844 out.serialEnum( type );
1846 NetMngr.push(out);
1848 else
1849 nlwarning("mainLoop : unknown message name : '%s'", msgName.c_str());
1851 return true;
1854 NLMISC_COMMAND(engage, "engage target in combat", "")
1856 // Create the message for the server to execute a phrase.
1857 const char *msgName = "COMBAT:ENGAGE";
1858 CBitMemStream out;
1859 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
1861 NetMngr.push(out);
1863 else
1864 nlwarning("mainLoop : unknown message name : '%s'", msgName);
1866 return true;
1869 NLMISC_COMMAND(defaultAttack, "use default attack on target", "")
1871 // Default attack on the current selection.
1872 UserEntity->attack();
1874 // Well Done.
1875 return true;
1878 NLMISC_COMMAND(disengage, "disengage from combat", "")
1880 // Disengage from combat.
1881 UserEntity->disengage();
1883 // Well Done.
1884 return true;
1887 NLMISC_COMMAND(leaveTeam, "leave team", "")
1889 // Create the message for the server to execute a phrase.
1890 const char *msgName = "TEAM:LEAVE";
1891 CBitMemStream out;
1892 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
1894 NetMngr.push(out);
1896 else
1897 nlwarning("mainLoop : unknown message name : '%s'", msgName);
1899 return true;
1902 NLMISC_COMMAND(joinTeam, "join the specified team", "")
1904 // Create the message for the server to execute a phrase.
1905 const char *msgName = "TEAM:JOIN";
1906 CBitMemStream out;
1907 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
1909 NetMngr.push(out);
1911 else
1912 nlwarning("mainLoop : unknown message name : '%s'", msgName);
1914 return true;
1917 NLMISC_COMMAND(joinTeamProposal, "propose to current target to join the team", "")
1919 // Create the message for the server to execute a phrase.
1920 const char *msgName = "TEAM:JOIN_PROPOSAL";
1921 CBitMemStream out;
1922 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
1924 NetMngr.push(out);
1926 else
1927 nlwarning("mainLoop : unknown message name : '%s'", msgName);
1929 return true;
1932 NLMISC_COMMAND(joinTeamDecline, "decline a join team proposal", "")
1934 // Create the message for the server to execute a phrase.
1935 const char *msgName = "TEAM:JOIN_PROPOSAL_DECLINE";
1936 CBitMemStream out;
1937 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
1939 NetMngr.push(out);
1941 else
1942 nlwarning("mainLoop : unknown message name : '%s'", msgName);
1944 return true;
1947 NLMISC_COMMAND(kickTeammate, "kick someone from your team", "")
1949 // Create the message for the server to execute a phrase.
1950 const char *msgName = "TEAM:KICK";
1951 CBitMemStream out;
1952 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
1954 NetMngr.push(out);
1956 else
1957 nlwarning("mainLoop : unknown message name : '%s'", msgName);
1959 return true;
1962 NLMISC_COMMAND(cancelCurrentSentence, "cancel the sentence being executed", "")
1964 // no parameter needed
1966 // Create the message for the server to cancel the phrase being executed
1967 const char *msgName = "SENTENCE:CANCEL_CURRENT";
1968 CBitMemStream out;
1969 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
1971 NetMngr.push(out);
1973 else
1974 nlwarning("command : unknown message name : '%s'", msgName);
1976 return true;
1979 NLMISC_COMMAND(cancelAllPhrases, "cancel all the phrases being executed", "")
1981 // no parameter needed
1983 UserEntity->cancelAllPhrases();
1985 return true;
1990 NLMISC_COMMAND(drop,"drop an item to the ground","<id>")
1992 if( args.size() < 1 )
1994 return false;
1997 uint32 id;
1998 fromString(args[0], id);
1999 CEntityId itemId(RYZOMID::object,id);
2001 sint32 x = (sint32)UserEntity->pos().x * 1000;
2002 sint32 y = (sint32)UserEntity->pos().y * 1000;
2003 sint32 z = (sint32)UserEntity->pos().z * 1000;
2005 CBitMemStream bms;
2006 const char *msgType = "ITEM:DROP";
2007 if( GenericMsgHeaderMngr.pushNameToStream(msgType,bms) )
2009 bms.serial( itemId );
2010 bms.serial( x );
2011 bms.serial( y );
2012 bms.serial( z );
2013 NetMngr.push( bms );
2014 nldebug("<drop> sending 'ITEM:DROP' message to server");
2016 else
2018 nlwarning("<drop> unknown message name : ITEM:DROP");
2021 return true;
2027 NLMISC_COMMAND(pos, "Change the position of the user (in local only)", "<x, y, (z)> OR 1 name of 'tp.teleport_list'. or a bot name")
2029 CVectorD newPos;
2031 // Named destination.
2032 if(args.size() == 1)
2034 string dest = args[0];
2035 newPos = CTeleport::getPos(NLMISC::toLowerAscii(dest));
2036 if(newPos == CTeleport::Unknown)
2038 //here we try to teleport to a bot destination
2039 CBitMemStream out;
2040 if(GenericMsgHeaderMngr.pushNameToStream("TP:BOT", out))
2042 string str = args[0];
2043 out.serial( str );
2044 nldebug("/pos: TP:BOT sent");
2045 NetMngr.push(out);
2047 else
2048 nlwarning("/pos: unknown message name : 'TP:BOT'");
2049 return true;
2052 // Teleport to anywhere.
2053 else if(args.size() == 2 || args.size() == 3)
2055 fromString(args[0], newPos.x);
2056 fromString(args[1], newPos.y);
2057 if(args.size() == 3)
2058 fromString(args[2], newPos.z);
2059 else
2060 newPos.z = 0.0;
2062 // Bad argument number.
2063 else
2064 return false;
2067 CANNOT USE ProgressBar here, because it does pumpEvents(), and
2068 ICommand::execute() is typically called from a pumpEvents() too...
2069 => cause crash
2072 // Fade out the Game Sound
2073 if(SoundMngr)
2074 SoundMngr->fadeOutGameSound(ClientCfg.SoundTPFade);
2076 // Remove the selection.
2077 UserEntity->selection(CLFECOMMON::INVALID_SLOT);
2078 // Remove the target.
2079 UserEntity->targetSlot(CLFECOMMON::INVALID_SLOT);
2080 // Change the position of the entity and in Pacs.
2081 UserEntity->pos(newPos);
2082 // Select the closest continent from the new position.
2083 CDummyProgress progress;
2084 ContinentMngr.select(newPos, progress);
2085 // Teleport the User.
2086 UserEntity->tp(newPos);
2088 // First frame (for sound fade in)
2089 extern bool FirstFrame;
2090 FirstFrame = true;
2092 return true;
2095 NLMISC_COMMAND(removeEntity, "Remove an entity", "<Slot>")
2097 if (args.size() != 1) return false;
2098 uint slot;
2099 fromString(args[0], slot);
2100 EntitiesMngr.remove(slot, true);
2101 return true;
2105 NLMISC_COMMAND(entity, "Create an entity on the user or just remove it if Form not valid", "<Slot> <Form> [posx posy posz] [relativeToPlayer]")
2107 CInterfaceManager *IM = CInterfaceManager::getInstance ();
2109 // Check parameters.
2110 if(args.size() != 2 && args.size() != 5 && args.size() != 6)
2111 return false;
2113 // read pos.
2114 CVector entityPos;
2115 if(args.size()>=5)
2117 fromString(args[2], entityPos.x);
2118 fromString(args[3], entityPos.y);
2119 fromString(args[4], entityPos.z);
2120 // if want pos local to UserEntity
2121 if(args.size()==6)
2123 sint32 tmp;
2124 fromString(args[5], tmp);
2125 if (tmp != 0)
2127 CMatrix mat;
2128 mat.setRot(CVector::I, UserEntity->front(), CVector::K);
2129 mat.normalize(CMatrix::YZX);
2130 mat.setPos(UserEntity->pos());
2131 entityPos= mat * entityPos;
2135 else
2137 entityPos= UserEntity->pos()+UserEntity->front()*2.0;
2140 // Try to create the sheet with the parameter as a string.
2141 CSheetId sheetId;
2142 if(!sheetId.buildSheetId(args[1]))
2144 // Try to create the sheet with the parameter as an int.
2145 uint32 nSheetId;
2146 fromString(args[1], nSheetId);
2147 sheetId = CSheetId(nSheetId);
2148 if(sheetId == CSheetId::Unknown)
2150 nlwarning("Command 'entity': '%s' is not a valid form", args[1].c_str());
2151 return false;
2155 // The slot where the new entity will be.
2156 CLFECOMMON::TCLEntityId slot;
2157 fromString(args[0], slot);
2159 // Debug Infos
2160 nldebug("Command 'entity' : AddNewEntity with form %s in the slot %d", args[1].c_str(), slot);
2161 // Remove the old entity.
2162 EntitiesMngr.remove(slot, false);
2163 // Create the new entity.
2165 TNewEntityInfo emptyEntityInfo;
2166 emptyEntityInfo.reset();
2167 CEntityCL *entity = EntitiesMngr.create(slot, sheetId.asInt(), emptyEntityInfo);
2168 if(entity)
2170 sint64 *prop = 0;
2171 CCDBNodeLeaf *node = 0;
2172 // Set The property 'CLFECOMMON::PROPERTY_POSITION'.
2173 node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_POSX), false);
2174 if(node)
2176 sint64 x = (sint64)(entityPos.x*1000.0);
2177 sint64 y = (sint64)(entityPos.y*1000.0);
2178 sint64 z = (sint64)(entityPos.z*1000.0);
2179 node->setValue64(x);
2180 node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_POSY), false);
2181 if(node)
2183 node->setValue64(y);
2184 node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_POSZ), false);
2185 if(node)
2186 node->setValue64(z);
2189 // Set The property 'PROPERTY_ORIENTATION'.
2190 node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_ORIENTATION), false);
2191 if(node)
2193 C64BitsParts rot;
2194 rot.f[0] = (float)atan2(UserEntity->front().y, UserEntity->front().x);
2195 rot.f[1] = 0.f; // to be sure 64 bits value is initialized
2196 node->setValue64(rot.i64[0]);
2198 // Set Mode
2199 node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_MODE), false);
2200 if(node)
2202 node->setValue64((sint64)MBEHAV::NORMAL);
2203 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_MODE);
2205 // Set Visual Properties
2206 if(dynamic_cast<CPlayerCL *>(entity))
2208 SPropVisualA visualA;
2209 visualA.PropertySubData.Sex = ClientCfg.Sex;
2210 SPropVisualB visualB;
2211 // Initialize the Visual Property C (Default parameters).
2212 SPropVisualC visualC;
2213 visualC.PropertySubData.CharacterHeight = 7;
2214 visualC.PropertySubData.ArmsWidth = 7;
2215 visualC.PropertySubData.LegsWidth = 7;
2216 visualC.PropertySubData.TorsoWidth = 7;
2217 visualC.PropertySubData.BreastSize = 7;
2218 // Set The Database
2219 prop = (sint64 *)&visualB;
2220 NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_VPB))->setValue64(*prop);
2221 prop = (sint64 *)&visualC;
2222 NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_VPC))->setValue64(*prop);
2223 prop = (sint64 *)&visualA;
2224 NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_VPA))->setValue64(*prop);
2225 // Apply Changes.
2226 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_VPA);
2228 // Forage Source special
2229 if(dynamic_cast<CForageSourceCL*>(entity))
2231 sint64 barVal;
2232 barVal= 32; barVal<<= 7;
2233 barVal+= 32; barVal<<= 7;
2234 barVal+= 10; barVal<<= 7;
2235 barVal+= 127;
2236 NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_BARS))->setValue64(barVal);
2237 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_BARS);
2238 // must also update position, else don't work
2239 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_POSITION);
2241 else
2242 if (dynamic_cast<CFxCL*>(entity)) // FX cl special
2244 // must also update position, else don't work
2245 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_POSITION);
2248 nlinfo("entity: slot: %d \"%s\", \"%f\", \"%f\", \"%f\" ",
2249 slot,args[1].c_str(),
2250 entityPos.x, entityPos.y, entityPos.z);
2252 else
2253 nldebug("command 'entity' : entity in slot %d removed", slot);
2255 // Command well done.
2256 return true;
2259 NLMISC_COMMAND(primPoint, "add a primitive point", "<pointName>")
2261 if(args.size() != 2)
2262 return false;
2264 if(LDPrim == 0)
2266 LDPrim = new NLLIGO::CPrimitives;
2267 if(LDPrim == 0)
2269 nlwarning("primPoint: LDPrim == 0");
2270 return false;
2274 if(LDPrim->RootNode == 0)
2276 nlwarning("primPoint: LDPrim.RootNode == 0");
2277 return true;
2280 NLLIGO::CPropertyString *str = 0;
2281 NLLIGO::CPrimPoint *point = 0;
2283 point = new NLLIGO::CPrimPoint;
2284 if(point == 0)
2286 nlwarning("primPoint: point == 0");
2287 return true;
2289 point->Point.x = (float)UserEntity->pos().x;
2290 point->Point.y = (float)UserEntity->pos().y;
2291 point->Point.z = (float)UserEntity->pos().z;
2293 str = new NLLIGO::CPropertyString;
2294 if(str == 0)
2296 nlwarning("primPoint: str == 0 (1)");
2297 return true;
2299 point->addPropertyByName("class", str);
2300 str->String = "reference_point";
2302 str = new NLLIGO::CPropertyString;
2303 if(str == 0)
2305 nlwarning("primPoint: str == 0 (2)");
2306 return true;
2308 point->addPropertyByName("name", str);
2309 str->String = args[1];
2311 // Add the point to the primitive.
2312 LDPrim->RootNode->insertChild(point);
2314 // Open the file.
2315 NLMISC::COFile file;
2316 if(file.open(args[0]))
2318 // Create the XML stream
2319 NLMISC::COXml output;
2320 // Init
2321 if(output.init(&file, "1.0"))
2323 LDPrim->write(output.getDocument(), args[0].c_str());
2324 // Flush the stream, write all the output file
2325 output.flush();
2327 else
2328 nlwarning("primPoint: ");
2329 // Close the File.
2330 file.close();
2332 else
2333 nlwarning("primPoint: cannot open/create the file '%s'", args[0].c_str());
2335 return true;
2338 #ifdef ENABLE_INCOMING_MSG_RECORDER
2340 NLMISC_COMMAND(record, "Start Recording", "<name>")
2342 CInterfaceManager *IM = CInterfaceManager::getInstance ();
2344 // Check parameters.
2345 if(args.size() != 1)
2346 return false;
2348 // Warning when already recording.
2349 if(NetMngr.isRecording())
2351 IM->displaySystemInfo("Already Recording. Stop the current Record first");
2352 return true;
2355 // Save entities and DB.
2356 dump(args[0]);
2358 // On/Off record.
2359 if(!ClientCfg.Local)
2360 NetMngr.setRecordingMode(true, args[0]+"_net.rec");
2361 return true;
2364 NLMISC_COMMAND(replay, "replay", "<name>")
2366 // Check parameters.
2367 if(args.size() != 1)
2368 return false;
2370 // Load entities and DB.
2371 loadDump(args[0]);
2373 // On/Off record.
2374 if(ClientCfg.Local)
2375 NetMngr.setReplayingMode(!NetMngr.isReplaying(), args[0]+"_net.rec");
2376 return true;
2379 NLMISC_COMMAND(stopRecord, "Stop Recording", "")
2381 // Check parameters.
2382 if(args.size() != 0)
2383 return false;
2385 // On/Off record.
2386 if(!ClientCfg.Local)
2387 NetMngr.setRecordingMode(false);
2388 return true;
2391 #endif // ENABLE_INCOMING_MSG_RECORDER
2393 NLMISC_COMMAND(loadDump, "Command to load a dump file", "[<dump name>]")
2395 if(args.size() > 1)
2396 return false;
2398 string dumpName;
2399 if(args.size() == 1)
2400 dumpName = args[0];
2401 else
2402 dumpName = "default";
2404 loadDump(dumpName);
2405 return true;
2408 NLMISC_COMMAND(sheet2idx, "Return the index of a sheet", "<sheet name> <visual slot number>")
2410 CInterfaceManager *IM = CInterfaceManager::getInstance ();
2412 if(args.size() != 2)
2413 return false;
2415 string result;
2416 NLMISC::CSheetId sheetId;
2418 if(sheetId.buildSheetId(args[0]))
2420 uint slot;
2421 fromString(args[1], slot);
2422 uint32 idx = CVisualSlotManager::getInstance()->sheet2Index(sheetId, (SLOTTYPE::EVisualSlot)slot);
2423 result = NLMISC::toString("Index = %d", idx);
2425 else
2426 result = NLMISC::toString("sheet '%s' not valid", args[0].c_str());
2428 IM->displaySystemInfo(result);
2429 nlinfo("'sheet2idx': %s", result.c_str());
2430 return true;
2433 NLMISC_COMMAND(watchEntity, "Choose the entity to watch", "<slot>")
2435 if(args.size() != 1)
2436 return false;
2438 // Set the new debug entity slot.
2439 fromString(args[0], WatchedEntitySlot);
2440 return true;
2443 NLMISC_COMMAND(dynstr, "display a dyn string value", "<dyn string_id>")
2445 if (args.size() != 1)
2446 return false;
2448 uint dynId;
2449 fromString(args[0], dynId);
2451 string result;
2452 STRING_MANAGER::CStringManagerClient::instance()->getDynString(dynId, result);
2454 CInterfaceManager::getInstance()->displaySystemInfo(result);
2455 return true;
2458 NLMISC_COMMAND(serverstr, "display a server string value", "<serverstr string_id>")
2460 if (args.size() != 1)
2461 return false;
2463 uint dynId;
2464 fromString(args[0], dynId);
2466 string result;
2467 STRING_MANAGER::CStringManagerClient::instance()->getString(dynId, result);
2469 CInterfaceManager::getInstance()->displaySystemInfo(result);
2470 return true;
2473 NLMISC_COMMAND(cmd, "Send a command to a server","<service name> <cmd>")
2475 // Check parameters.
2476 if(args.size() < 2)
2477 return false;
2479 CBitMemStream out;
2480 if(GenericMsgHeaderMngr.pushNameToStream("DEBUG:CMD", out))
2482 bool addentity = false;
2483 string dest = args[0];
2484 string cmd = args[1];
2485 string arg;
2486 for (uint i = 2; i < args.size(); i++)
2488 arg += args[i] + " ";
2490 out.serial(addentity);
2491 out.serial(dest);
2492 out.serial(cmd);
2493 out.serial(arg);
2494 NetMngr.push(out);
2496 else
2497 nlwarning("mainLoop : unknown message name DEBUG:CMD");
2498 return true;
2501 NLMISC_COMMAND(cmde, "Send a command to a server with entityid","<service name> <cmd>")
2503 // Check parameters.
2504 if(args.size() < 2)
2505 return false;
2507 CBitMemStream out;
2508 if(GenericMsgHeaderMngr.pushNameToStream("DEBUG:CMD", out))
2510 bool addentity = true;
2511 string dest = args[0];
2512 string cmd = args[1];
2513 string arg;
2514 for (uint i = 2; i < args.size(); i++)
2516 arg += args[i] + " ";
2518 out.serial(addentity);
2519 out.serial(dest);
2520 out.serial(cmd);
2521 out.serial(arg);
2522 NetMngr.push(out);
2524 else
2525 nlwarning("mainLoop : unknown message name DEBUG:CMD");
2526 return true;
2529 NLMISC_COMMAND(askservices, "Ask the server all services up", "")
2531 CBitMemStream out;
2532 if(GenericMsgHeaderMngr.pushNameToStream("DEBUG:SERVICES", out))
2534 // Add the message to the send list.
2535 NetMngr.push(out);
2536 nlinfo("command 'services': 'DEBUG:SERVICES' sent");
2538 else
2539 nlwarning("command 'services': unknown message named 'DEBUG:SERVICES'");
2541 return true;
2544 NLMISC_COMMAND(mode, "Change the mode for an entity in a slot", "<Slot> <Mode> [dt(tick)]")
2546 // Check parameters.
2547 if(args.size() < 2)
2549 // Help
2550 CInterfaceManager::getInstance()->displaySystemInfo("This command need 2 paramters :");
2551 CInterfaceManager::getInstance()->displaySystemInfo(" <Slot> : the slot number of the entity to change");
2552 CInterfaceManager::getInstance()->displaySystemInfo(" <Mode> : the mode wanted for the entity, one of the following number :");
2553 for(uint i = 0; i<MBEHAV::NUMBER_OF_MODES; ++i)
2554 CInterfaceManager::getInstance()->displaySystemInfo(NLMISC::toString(" %d - %s", i, MBEHAV::modeToString((MBEHAV::EMode)i).c_str()));
2556 // Right parameters number
2557 else
2559 // Compute parameters
2560 CLFECOMMON::TCLEntityId slot;
2561 fromString(args[0], slot);
2562 MBEHAV::EMode mod = MBEHAV::stringToMode(args[1]);
2563 if(mod==MBEHAV::UNKNOWN_MODE)
2565 sint32 nMode;
2566 fromString(args[1], nMode);
2567 mod = (MBEHAV::EMode)nMode;
2570 // Compute the position.
2571 CEntityCL *entity = EntitiesMngr.entity(slot);
2572 if(entity)
2574 // Write the behaviour in the DB.
2575 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_MODE), mod);
2576 // Update the behaviour.
2577 sint32 dt= 10;
2578 if(args.size() > 2)
2579 fromString(args[2], dt);
2580 entity->updateVisualProperty(NetMngr.getCurrentServerTick()+dt, CLFECOMMON::PROPERTY_MODE);
2582 // Invalid slot.
2583 else
2584 CInterfaceManager::getInstance()->displaySystemInfo("There is no entity in the given slot");
2587 // Command well done.
2588 return true;
2591 NLMISC_COMMAND(behaviour, "Change the behaviour for an entity in a slot", "<Slot> <Behaviour> [<Attack Intensity>] [<Impact Intensity>] [<delta HP>] [dt(tick)]")
2593 // Check parameters.
2594 if(args.size() < 2 || args.size() > 6)
2596 // Help
2597 CInterfaceManager::getInstance()->displaySystemInfo("This command need 2 to 6 paramters :");
2598 CInterfaceManager::getInstance()->displaySystemInfo(" <Slot> : the slot number of the entity to change");
2599 CInterfaceManager::getInstance()->displaySystemInfo(" <Behaviour> : the behaviour to play for the entity, one of the following number :");
2600 for(uint i = 0; i<MBEHAV::EMOTE_BEGIN; ++i)
2601 CInterfaceManager::getInstance()->displaySystemInfo(NLMISC::toString(" %d - %s", i, MBEHAV::behaviourToString((MBEHAV::EBehaviour)i).c_str()));
2602 CInterfaceManager::getInstance()->displaySystemInfo(NLMISC::toString(" %d-%d - Emotes", MBEHAV::EMOTE_BEGIN, MBEHAV::EMOTE_END));
2604 else
2606 // Compute parameters
2607 CLFECOMMON::TCLEntityId slot;
2608 fromString(args[0], slot);
2609 MBEHAV::EBehaviour beh = MBEHAV::stringToBehaviour(args[1]);
2610 if(beh==MBEHAV::UNKNOWN_BEHAVIOUR)
2612 sint32 temp;
2613 fromString(args[1], temp);
2614 beh= (MBEHAV::EBehaviour)temp;
2617 // Make the behaviour
2618 MBEHAV::CBehaviour behaviour(beh);
2619 // Get the Power
2620 if ( (beh == MBEHAV::PROSPECTING) || (beh == MBEHAV::PROSPECTING_END) )
2622 if(args.size() > 2)
2624 uint16 range;
2625 fromString(args[2], range);
2626 behaviour.ForageProspection.Range = range; // 0..127
2628 if(args.size() > 3)
2630 uint16 angle;
2631 fromString(args[3], angle);
2632 behaviour.ForageProspection.Angle = angle; // 0..3
2634 if(args.size() > 4)
2636 uint16 level;
2637 fromString(args[4], level);
2638 behaviour.ForageProspection.Level = level; // 0..4
2641 else
2643 if(args.size() > 2)
2645 uint16 impactIntensity;
2646 fromString(args[2], impactIntensity);
2647 behaviour.Combat.ImpactIntensity = impactIntensity;
2649 if(args.size() > 3)
2651 uint16 impactIntensity;
2652 fromString(args[3], impactIntensity);
2653 behaviour.Combat.ImpactIntensity = impactIntensity;
2655 if(args.size() > 4)
2656 fromString(args[4], behaviour.DeltaHP);
2658 // get the dt
2659 sint32 dt= 10;
2660 if(args.size() > 5)
2661 fromString(args[5], dt);
2663 // Compute the position.
2664 CEntityCL *entity = EntitiesMngr.entity(slot);
2665 if(entity)
2667 // Write the behaviour in the DB.
2668 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_BEHAVIOUR), behaviour);
2669 // Update the behaviour.
2670 entity->updateVisualProperty(NetMngr.getCurrentServerTick()+dt, CLFECOMMON::PROPERTY_BEHAVIOUR);
2672 else
2673 CInterfaceManager::getInstance()->displaySystemInfo("There is no entity in the given slot");
2676 // Command well done.
2677 return true;
2681 NLMISC_COMMAND(magic, "Cast a spell", "\n"
2682 "<Slot> : the one who cast the spell\n"
2683 "<type> : 0->GOOD 1->Bad 2->NEUTRAL\n"
2684 "<success> : 0->success 1->Fail 2->Fumble\n"
2685 "<Spell Power> : \n"
2686 "<Impact Intensity> : \n"
2687 "<resist> : 0->not resisted, any other->resisted.\n")
2689 CInterfaceManager *IM = CInterfaceManager::getInstance ();
2691 // Check parameters.
2692 if(args.size() != 6)
2694 // Help
2695 // CInterfaceManager::getInstance()->displaySystemInfo("This command need 2 or 3 paramters :");
2696 // CInterfaceManager::getInstance()->displaySystemInfo(" <Slot> : the slot number of the entity to change");
2697 // CInterfaceManager::getInstance()->displaySystemInfo(" <Behaviour> : the behaviour to play for the entity, one of the following number :");
2698 // for(uint i = 0; i<MBEHAV::EMOTE_BEGIN; ++i)
2699 // CInterfaceManager::getInstance()->displaySystemInfo(NLMISC::toString(" %d - %s", i, MBEHAV::behaviourToString((MBEHAV::EBehaviour)i)));
2700 // CInterfaceManager::getInstance()->displaySystemInfo(NLMISC::toString(" %d-%d - Emotes", MBEHAV::EMOTE_BEGIN, MBEHAV::EMOTE_END));
2702 else
2704 // Compute parameters
2705 CLFECOMMON::TCLEntityId slot;
2706 fromString(args[0], slot);
2707 // Magic Type (good bad neutral)
2708 uint type;
2709 fromString(args[1], type);
2710 type %= 3;
2711 MBEHAV::EBehaviour behTmp = (MBEHAV::EBehaviour)(MBEHAV::CASTING_GOOD+type);
2712 MBEHAV::CBehaviour castingBeh(behTmp);
2713 // Result
2714 MBEHAV::CBehaviour behaviour;
2715 uint result;
2716 fromString(args[2], result);
2717 result %= %3;
2718 if (type==0)
2719 behaviour.Behaviour = (MBEHAV::EBehaviour)(MBEHAV::END_CASTING_GOOD_SUCCESS + result);
2720 else if(type==1)
2721 behaviour.Behaviour = (MBEHAV::EBehaviour)(MBEHAV::END_CASTING_BAD_SUCCESS + result);
2722 else
2723 behaviour.Behaviour = (MBEHAV::EBehaviour)(MBEHAV::END_CASTING_NEUTRAL_SUCCESS + result);
2724 uint16 spellPower, impactIntensity;
2725 // Spell Power
2726 fromString(args[3], spellPower);
2727 behaviour.Magic.SpellPower = spellPower;
2728 // Impact Intensity
2729 fromString(args[4], impactIntensity);
2730 behaviour.Magic.ImpactIntensity = impactIntensity;
2731 // Resist
2732 bool targetResists;
2733 fromString(args[5], targetResists);
2734 behaviour.Magic.TargetResists = targetResists;
2735 // Get the entity
2736 CEntityCL *entity = EntitiesMngr.entity(slot);
2737 if(entity)
2739 // Write the behaviour in the DB.
2740 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_BEHAVIOUR), castingBeh);
2741 // Update the behaviour.
2742 entity->updateVisualProperty(NetMngr.getCurrentServerTick()+10, CLFECOMMON::PROPERTY_BEHAVIOUR);
2743 // Write the behaviour in the DB.
2744 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_BEHAVIOUR), behaviour);
2745 // Update the behaviour.
2746 entity->updateVisualProperty(NetMngr.getCurrentServerTick()+50, CLFECOMMON::PROPERTY_BEHAVIOUR);
2748 else
2749 CInterfaceManager::getInstance()->displaySystemInfo("There is no entity in the given slot");
2752 // Command well done.
2753 return true;
2756 NLMISC_COMMAND(spell, "Cast a spell", "\n"
2757 "<Slot> : the one who cast the spell\n"
2758 "<type> : 0->OFF 1->CUR 2->MIX\n"
2759 "<success> : 0->Fail 1->Fumble 2->Success 3->Link\n"
2760 "<Resist> : 0->Resist 1->Not Resist\n"
2761 "<Spell Id> : \n"
2762 "<Intensity> : [0, 5]\n")
2764 // Check parameters.
2765 if(args.size() != 6)
2767 // Help
2768 // CInterfaceManager::getInstance()->displaySystemInfo("This command need 2 or 3 paramters :");
2769 // CInterfaceManager::getInstance()->displaySystemInfo(" <Slot> : the slot number of the entity to change");
2770 // CInterfaceManager::getInstance()->displaySystemInfo(" <Behaviour> : the behaviour to play for the entity, one of the following number :");
2771 // for(uint i = 0; i<MBEHAV::EMOTE_BEGIN; ++i)
2772 // CInterfaceManager::getInstance()->displaySystemInfo(NLMISC::toString(" %d - %s", i, MBEHAV::behaviourToString((MBEHAV::EBehaviour)i)));
2773 // CInterfaceManager::getInstance()->displaySystemInfo(NLMISC::toString(" %d-%d - Emotes", MBEHAV::EMOTE_BEGIN, MBEHAV::EMOTE_END));
2775 else
2777 // Compute parameters
2778 CLFECOMMON::TCLEntityId slot;
2779 fromString(args[0], slot);
2780 // Magic Type (good bad neutral)
2781 uint type;
2782 fromString(args[1], type);
2783 type %= 3;
2784 MBEHAV::EBehaviour behTmp = (MBEHAV::EBehaviour)(MBEHAV::CAST_OFF+type);
2785 MBEHAV::CBehaviour castingBeh(behTmp);
2786 // Result
2787 MBEHAV::CBehaviour behaviour;
2788 uint result;
2789 fromString(args[2], result);
2790 result %= 4;
2791 behaviour.Behaviour = (MBEHAV::EBehaviour)(MBEHAV::CAST_OFF_FAIL+type*4+result);
2792 // Spell Power
2793 uint16 spellMode;
2794 fromString(args[3], spellMode);
2795 behaviour.Spell.SpellMode = spellMode;
2796 // Impact Intensity
2797 uint16 spellId;
2798 fromString(args[4], spellId);
2799 behaviour.Spell.SpellId = spellId;
2800 // Resist
2801 uint16 spellIntensity;
2802 fromString(args[5], spellIntensity);
2803 behaviour.Spell.SpellIntensity = spellIntensity;
2804 // Get the entity
2805 CEntityCL *entity = EntitiesMngr.entity(slot);
2806 if(entity)
2808 uint64 beha = castingBeh;
2809 sint64 beha2 = *((sint64 *)(&beha));
2810 // Write the behaviour in the DB.
2811 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_BEHAVIOUR), beha2);
2812 // Update the behaviour.
2813 entity->updateVisualProperty(NetMngr.getCurrentServerTick()+10, CLFECOMMON::PROPERTY_BEHAVIOUR);
2814 beha = behaviour;
2815 beha2 = *((sint64 *)(&beha));
2816 // Write the behaviour in the DB.
2817 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_BEHAVIOUR), beha2);
2818 // Update the behaviour.
2819 entity->updateVisualProperty(NetMngr.getCurrentServerTick()+50, CLFECOMMON::PROPERTY_BEHAVIOUR);
2821 else
2822 CInterfaceManager::getInstance()->displaySystemInfo("There is no entity in the given slot");
2825 // Command well done.
2826 return true;
2829 NLMISC_COMMAND(settarget, "Set a target for an entity. Do not set the target slot to remove the target", "<Slot> [<Target Slot>]")
2831 CLFECOMMON::TCLEntityId targetSlot = CLFECOMMON::INVALID_SLOT;
2833 // Check parameters.
2834 switch(args.size())
2836 // Set the target for the entity.
2837 case 2:
2838 fromString(args[1], targetSlot);
2840 // Remove the target for the entity.
2841 case 1:
2843 uint entitySlot;
2844 fromString(args[0], entitySlot);
2845 CEntityCL *entity = EntitiesMngr.entity(entitySlot);
2846 if(entity)
2847 entity->targetSlot(targetSlot);
2848 else
2849 nlwarning("command 'settarget': there is no entity in the slot %d", entitySlot);
2851 break;
2853 // Bad command.
2854 default:
2855 return false;
2858 // Well done.
2859 return true;
2862 NLMISC_COMMAND(particle, "Create a particule at the user position (play FireWorkA_with_sound.ps by default)", "[<filename.ps>]")
2864 string fn;
2866 // Check parameters.
2867 if(args.empty())
2869 fn = "FireWorkA_with_sound.ps";
2871 else if(args.size() == 1)
2873 fn = args[0];
2875 else
2876 return false;
2878 UInstance fx = Scene->createInstance(fn);
2880 // not found
2881 if(fx.empty())
2883 log.displayNL ("Can't create instance '%s'", fn.c_str());
2884 return false;
2887 fx.setPos(UserEntity->pos());
2888 fx.setClusterSystem(UserEntity->skeleton()->getClusterSystem());
2890 // Command well done.
2891 return true;
2894 NLMISC_COMMAND(move, "Move an entity", "Slot: [1-254]")
2896 // Check parameters.
2897 if(args.size() != 1)
2898 return false;
2900 CLFECOMMON::TCLEntityId slot;
2901 fromString(args[0], slot);
2903 // Compute the position.
2904 CEntityCL *entity = EntitiesMngr.entity(slot);
2905 if(entity)
2907 sint64 x = (sint64)((entity->pos().x+UserEntity->front().x*10.0)*1000.0);
2908 sint64 y = (sint64)((entity->pos().y+UserEntity->front().y*10.0)*1000.0);
2909 sint64 z = (sint64)((entity->pos().z+UserEntity->front().z*10.0)*1000.0);
2910 // Write the position in the DB.
2911 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P0", x);
2912 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P1", y);
2913 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P2", z);
2914 // Update the position.
2915 EntitiesMngr.updateVisualProperty(NetMngr.getCurrentServerTick()+30, slot, 0);
2917 x = (sint64)((entity->pos().x)*1000.0);
2918 y = (sint64)((entity->pos().y)*1000.0);
2919 z = (sint64)((entity->pos().z)*1000.0);
2920 // Write the position in the DB.
2921 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P0", x);
2922 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P1", y);
2923 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P2", z);
2924 // Update the position.
2925 EntitiesMngr.updateVisualProperty(NetMngr.getCurrentServerTick()+60, slot, 0);
2927 else
2928 nlwarning("command 'move' : there is no entity allocated in slot %d", slot);
2930 // Command well done.
2931 return true;
2934 NLMISC_COMMAND(moveRel, "Move an entity, specifying delta pos from current", "Slot: [1-254] dx(m) dy(m) [dt(tick)] [predictedIV(tick)]")
2936 // Check parameters.
2937 if(args.size() <3)
2938 return false;
2940 CLFECOMMON::TCLEntityId slot;
2941 fromString(args[0], slot);
2943 // Compute the position.
2944 CEntityCL *entity = EntitiesMngr.entity(slot);
2945 if(entity)
2947 float dx, dy;
2948 fromString(args[1], dx);
2949 fromString(args[2], dy);
2950 sint32 dt= 10;
2951 if(args.size()>=4)
2952 fromString(args[3], dt);
2953 sint32 pi= 0;
2954 if(args.size()>=5)
2955 fromString(args[4], pi);
2956 sint64 x = (sint64)((entity->pos().x+dx)*1000.0);
2957 sint64 y = (sint64)((entity->pos().y+dy)*1000.0);
2958 sint64 z = (sint64)((entity->pos().z+0)*1000.0);
2959 // Write the position in the DB.
2960 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P0", x);
2961 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P1", y);
2962 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P2", z);
2963 // Update the position.
2964 EntitiesMngr.updateVisualProperty(NetMngr.getCurrentServerTick()+dt, slot, 0, pi);
2966 else
2967 nlwarning("command 'move' : there is no entity allocated in slot %d", slot);
2969 // Command well done.
2970 return true;
2973 NLMISC_COMMAND(orient, "Orient an entity", "Slot: [1-254] orient(degree) [dt(tick)]")
2975 // Check parameters.
2976 if(args.size() < 2)
2977 return false;
2979 CLFECOMMON::TCLEntityId slot;
2980 fromString(args[0], slot);
2982 // Compute the position.
2983 CEntityCL *entity = EntitiesMngr.entity(slot);
2984 if(entity)
2986 sint32 rot;
2987 fromString(args[1], rot);
2988 sint32 dt= 10;
2989 if(args.size()> 2)
2990 fromString(args[2], dt);
2991 // Write the position in the DB.
2992 float fRot= (float)(rot*Pi/180.f);
2994 C64BitsParts r;
2995 r.f[0] = fRot;
2996 r.f[1] = 0.f; // to be sure 64 bits value is initialized
2998 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P"+toString(CLFECOMMON::PROPERTY_ORIENTATION), r.u32[0]);
2999 // Update the position.
3000 EntitiesMngr.updateVisualProperty(NetMngr.getCurrentServerTick()+dt, slot, CLFECOMMON::PROPERTY_ORIENTATION);
3002 else
3003 nlwarning("command 'move' : there is no entity allocated in slot %d", slot);
3005 // Command well done.
3006 return true;
3009 NLMISC_COMMAND(moveTo, "Move an entity to another one", "<slot(from)>:[1-254], <slot(to)>:[0-254] default 0")
3011 sint64 x, y, z;
3013 // Check parameters.
3014 if(args.size() == 1)
3016 x = (sint64)(UserEntity->pos().x*1000.0);
3017 y = (sint64)(UserEntity->pos().y*1000.0);
3018 z = (sint64)(UserEntity->pos().z*1000.0);
3020 else if(args.size() == 2)
3022 CLFECOMMON::TCLEntityId slotDest;
3023 fromString(args[1], slotDest);
3024 // Compute the position.
3025 CEntityCL *entity = EntitiesMngr.entity(slotDest);
3026 if(entity)
3028 x = (sint64)(entity->pos().x*1000.0);
3029 y = (sint64)(entity->pos().y*1000.0);
3030 z = (sint64)(entity->pos().z*1000.0);
3032 else
3034 // Command is correct but not all the parameters are valid.
3035 nlwarning("command 'move_to' : there is no entity allocated for the dest in slot %d", slotDest);
3036 return true;
3039 // Wrong number of parameters.
3040 else
3041 return false;
3043 CLFECOMMON::TCLEntityId slot;
3044 fromString(args[0], slot);
3045 // Write the position in the DB.
3046 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P0", x);
3047 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P1", y);
3048 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P2", z);
3049 // Update the position.
3050 EntitiesMngr.updateVisualProperty(NetMngr.getCurrentServerTick()+30, slot, 0);
3052 // Command well done.
3053 return true;
3056 NLMISC_COMMAND(setMode, "Set The Mode for an Entity without to add a stage for it", "<slot> <mode>")
3058 // Check parameters.
3059 if(args.size() != 2)
3060 return false;
3062 // Get the Slot and the Mode.
3063 CLFECOMMON::TCLEntityId slot;
3064 fromString(args[0], slot);
3065 sint32 nMode;
3066 fromString(args[1], nMode);
3067 MBEHAV::EMode mod = (MBEHAV::EMode)nMode;
3069 // Compute the position.
3070 CEntityCL *entity = EntitiesMngr.entity(slot);
3071 if(entity)
3072 entity->mode(mod);
3073 else
3074 nlwarning("command 'setMode' : there is no entity allocated in slot '%d'", slot);
3076 // Command well done.
3077 return true;
3079 NLMISC_COMMAND(paintTarget, "Modify the target color",
3080 "\n"
3081 "<color> color for the target (0-7)\n")
3083 // Check parameters
3084 if(args.size() != 1)
3085 return false;
3086 // Get the entity slot
3087 CLFECOMMON::TCLEntityId slot = UserEntity->selection();
3088 if(slot == CLFECOMMON::INVALID_SLOT)
3089 return true;
3091 SPropVisualA vA;
3092 SPropVisualB vB;
3093 SPropVisualC vC;
3094 const string propNameA = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPA);
3095 const string propNameB = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPB);
3096 const string propNameC = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPC);
3097 vA.PropertyA = NLGUI::CDBManager::getInstance()->getDbProp(propNameA)->getValue64();
3098 vB.PropertyB = NLGUI::CDBManager::getInstance()->getDbProp(propNameB)->getValue64();
3099 vC.PropertyC = NLGUI::CDBManager::getInstance()->getDbProp(propNameC)->getValue64();
3101 // Get the visual item index
3102 uint value;
3103 fromString(args[0], value);
3104 // Change color
3105 vA.PropertySubData.JacketColor = value;
3106 vA.PropertySubData.TrouserColor = value;
3107 vA.PropertySubData.ArmColor = value;
3108 vA.PropertySubData.HatColor = value;
3109 vB.PropertySubData.HandsColor = value;
3110 vB.PropertySubData.FeetColor = value;
3112 // Set the database.
3113 NLGUI::CDBManager::getInstance()->getDbProp(propNameA)->setValue64((sint64)vA.PropertyA);
3114 NLGUI::CDBManager::getInstance()->getDbProp(propNameB)->setValue64((sint64)vB.PropertyB);
3115 NLGUI::CDBManager::getInstance()->getDbProp(propNameC)->setValue64((sint64)vC.PropertyC);
3116 // Force to update properties.
3117 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_VPA);
3119 // Done.
3120 return true;
3123 NLMISC_COMMAND(playAnim, "Try to play the animation to the target", "<anim name>")
3125 // Check parameters
3126 if(args.size() != 1)
3127 return false;
3129 CLFECOMMON::TCLEntityId slot = UserEntity->selection();
3130 if(slot == CLFECOMMON::INVALID_SLOT)
3131 return true;
3132 if(EAM == 0)
3133 return true;
3134 NL3D::UAnimationSet *animset = EAM->getAnimationSet();
3135 if(animset == 0)
3136 return true;
3137 uint animId = animset->getAnimationIdByName(args[0]);
3138 if(animId == UAnimationSet::NotFound)
3140 nlwarning("anim not found %s", args[0].c_str());
3141 return true;
3143 CEntityCL *selection = EntitiesMngr.entity(slot);
3144 CCharacterCL *character = dynamic_cast<CCharacterCL *>(selection);
3145 if(character)
3146 character->setAnim(CAnimationStateSheet::Idle, (TAnimStateKey)CAnimation::UnknownAnim, animId);
3147 return true;
3150 NLMISC_COMMAND(vP, "Modify the Visual Property",
3151 "\n"
3152 "<slot> of the entity to change.\n"
3153 "<type> the property to change :\n"
3154 " 0->CHEST (0~511)\n"
3155 " 1->LEG (0~255)\n"
3156 " 2->ARM (0~255)\n"
3157 " 3->HEAD (0~127)\n"
3158 " 4->WEAPON_R (0~2047)\n"
3159 " 5->WEAPON_L (0~255)\n"
3160 " 6->FEET (0~511)\n"
3161 " 7->HAND (0~511)\n"
3162 " 8->EYES COLOR (0~7)\n"
3163 " 9->SEX (0: Male, 1: Female)\n"
3164 " 10->TATOO (0~31)\n"
3165 " 11->CHEST COLOR (0~7)\n"
3166 " 12->LEG COLOR (0~7)\n"
3167 " 13->ARM COLOR (0~7)\n"
3168 " 14->HAIR COLOR (0~7)\n"
3169 " 15->HAND COLOR (0~7)\n"
3170 " 16->FEET COLOR (0~7)\n"
3171 " 17->MORPH 1 (0~7)\n"
3172 " 18->MORPH 2 (0~7)\n"
3173 " 19->MORPH 3 (0~7)\n"
3174 " 20->MORPH 4 (0~7)\n"
3175 " 21->MORPH 5 (0~7)\n"
3176 " 22->MORPH 6 (0~7)\n"
3177 " 23->MORPH 7 (0~7)\n"
3178 " 24->CHARACTER HEIGHT (0~15)\n"
3179 " 25->TORSO WIDTH (0~15)\n"
3180 " 26->ARMS WIDTH (0~15)\n"
3181 " 27->LEGS WIDTH (0~15)\n"
3182 " 28->BREASTS SIZE (0~15)\n"
3183 "<value> for the property.\n")
3185 // Check parameters
3186 if(args.size() != 3)
3187 return false;
3189 // Get the database entry.
3190 SPropVisualA vA;
3191 SPropVisualB vB;
3192 SPropVisualC vC;
3193 uint slot;
3194 fromString(args[0], slot);
3195 const string propNameA = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPA);
3196 const string propNameB = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPB);
3197 const string propNameC = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPC);
3198 vA.PropertyA = NLGUI::CDBManager::getInstance()->getDbProp(propNameA)->getValue64();
3199 vB.PropertyB = NLGUI::CDBManager::getInstance()->getDbProp(propNameB)->getValue64();
3200 vC.PropertyC = NLGUI::CDBManager::getInstance()->getDbProp(propNameC)->getValue64();
3201 // Get the visual item index
3202 uint value;
3203 fromString(args[2], value);
3204 // Get the visual slot to change.
3205 uint type;
3206 fromString(args[1], type);
3207 // if .sitem visual slot, try translate .sitem to VSIndex
3208 if(type<=7)
3210 SLOTTYPE::EVisualSlot vslot= SLOTTYPE::HIDDEN_SLOT;
3211 switch(type)
3213 case 0: vslot= SLOTTYPE::CHEST_SLOT; break;
3214 case 1: vslot= SLOTTYPE::LEGS_SLOT; break;
3215 case 2: vslot= SLOTTYPE::ARMS_SLOT; break;
3216 case 3: vslot= SLOTTYPE::HEAD_SLOT; break;
3217 case 4: vslot= SLOTTYPE::RIGHT_HAND_SLOT; break;
3218 case 5: vslot= SLOTTYPE::LEFT_HAND_SLOT; break;
3219 case 6: vslot= SLOTTYPE::FEET_SLOT; break;
3220 case 7: vslot= SLOTTYPE::HANDS_SLOT; break;
3221 default: break;
3223 if(vslot!=SLOTTYPE::HIDDEN_SLOT && value==0)
3225 sint vsIndex= SheetMngr.getVSIndex(args[2], vslot);
3226 // succed!
3227 if(vsIndex!=-1)
3228 value= vsIndex;
3231 // setup
3232 switch(type)
3234 case 0:
3235 vA.PropertySubData.JacketModel = value;
3236 break;
3237 case 1:
3238 vA.PropertySubData.TrouserModel = value;
3239 break;
3240 case 2:
3241 vA.PropertySubData.ArmModel = value;
3242 break;
3243 case 3:
3244 vA.PropertySubData.HatModel = value;
3245 break;
3246 case 4:
3247 vA.PropertySubData.WeaponRightHand = value;
3248 break;
3249 case 5:
3250 vA.PropertySubData.WeaponLeftHand = value;
3251 break;
3252 case 6:
3253 vB.PropertySubData.FeetModel = value;
3254 break;
3255 case 7:
3256 vB.PropertySubData.HandsModel = value;
3257 break;
3258 case 8:
3259 vC.PropertySubData.EyesColor = value;
3260 break;
3261 case 9:
3262 vA.PropertySubData.Sex = value;
3263 break;
3264 case 10:
3265 vC.PropertySubData.Tattoo = value;
3266 break;
3267 case 11:
3268 vA.PropertySubData.JacketColor = value;
3269 break;
3270 case 12:
3271 vA.PropertySubData.TrouserColor = value;
3272 break;
3273 case 13:
3274 vA.PropertySubData.ArmColor = value;
3275 break;
3276 case 14:
3277 vA.PropertySubData.HatColor = value;
3278 break;
3279 case 15:
3280 vB.PropertySubData.HandsColor = value;
3281 break;
3282 case 16:
3283 vB.PropertySubData.FeetColor = value;
3284 break;
3285 case 17:
3286 vC.PropertySubData.MorphTarget1 = value;
3287 break;
3288 case 18:
3289 vC.PropertySubData.MorphTarget2 = value;
3290 break;
3291 case 19:
3292 vC.PropertySubData.MorphTarget3 = value;
3293 break;
3294 case 20:
3295 vC.PropertySubData.MorphTarget4 = value;
3296 break;
3297 case 21:
3298 vC.PropertySubData.MorphTarget5 = value;
3299 break;
3300 case 22:
3301 vC.PropertySubData.MorphTarget6 = value;
3302 break;
3303 case 23:
3304 vC.PropertySubData.MorphTarget7 = value;
3305 break;
3306 case 24:
3307 vC.PropertySubData.CharacterHeight = value;
3308 break;
3309 case 25:
3310 vC.PropertySubData.TorsoWidth = value;
3311 break;
3312 case 26:
3313 vC.PropertySubData.ArmsWidth = value;
3314 break;
3315 case 27:
3316 vC.PropertySubData.LegsWidth = value;
3317 break;
3318 case 28:
3319 vC.PropertySubData.BreastSize = value;
3320 break;
3322 default:
3323 nlwarning("command 'vP': type not valid");
3324 return false;
3325 break;
3328 // Set the database.
3329 NLGUI::CDBManager::getInstance()->getDbProp(propNameA)->setValue64((sint64)vA.PropertyA);
3330 NLGUI::CDBManager::getInstance()->getDbProp(propNameB)->setValue64((sint64)vB.PropertyB);
3331 NLGUI::CDBManager::getInstance()->getDbProp(propNameC)->setValue64((sint64)vC.PropertyC);
3332 // Force to update properties.
3333 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_VPA);
3335 // Done.
3336 return true;
3339 NLMISC_COMMAND(altLook, "Modify the Alternative Look Property",
3340 "\n"
3341 "<slot> of the entity to change.\n"
3342 "<colorTop>\n"
3343 "<colorBottom>\n"
3344 "<rWeapon>\n"
3345 "<lWeapon>\n"
3346 "<seed>\n"
3347 "<hairColor>\n"
3348 "<putHelm>\n"
3349 "[<colorGlove>]\n"
3350 "[<colorBoot>]\n"
3351 "[<colorArm>]\n")
3353 // Check parameters
3354 if(args.size() < 8 || args.size() > 11)
3355 return false;
3357 // Get the database entry.
3358 uint slot;
3359 fromString(args[0], slot);
3360 const string propName = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPA);
3361 // Get the old value (not useful since we change the whole property).
3362 SAltLookProp altLookProp;
3363 altLookProp.Summary = NLGUI::CDBManager::getInstance()->getDbProp(propName)->getValue64();
3364 uint32 colorTop, colorBot, weaponRightHand, weaponLeftHand, seed, colorHair, hat;
3365 fromString(args[1], colorTop);
3366 fromString(args[2], colorBot);
3367 fromString(args[3], weaponRightHand);
3368 fromString(args[4], weaponLeftHand);
3369 fromString(args[5], seed);
3370 fromString(args[6], colorHair);
3371 fromString(args[7], hat);
3372 altLookProp.Element.ColorTop = colorTop;
3373 altLookProp.Element.ColorBot = colorBot;
3374 altLookProp.Element.WeaponRightHand = weaponRightHand;
3375 altLookProp.Element.WeaponLeftHand = weaponLeftHand;
3376 altLookProp.Element.Seed = seed;
3377 altLookProp.Element.ColorHair = colorHair;
3378 altLookProp.Element.Hat = hat;
3379 // New colours
3380 if(args.size() == 11)
3382 uint32 colorGlove, colorBoot, colorArm;
3383 fromString(args[8], colorGlove);
3384 fromString(args[9], colorBoot);
3385 fromString(args[10], colorArm);
3386 altLookProp.Element.ColorGlove = colorGlove;
3387 altLookProp.Element.ColorBoot = colorBoot;
3388 altLookProp.Element.ColorArm = colorArm;
3390 // Old Colours
3391 else
3393 altLookProp.Element.ColorGlove = altLookProp.Element.ColorTop;
3394 altLookProp.Element.ColorArm = altLookProp.Element.ColorTop;
3395 altLookProp.Element.ColorBoot = altLookProp.Element.ColorBot;
3398 // Set the database.
3399 NLGUI::CDBManager::getInstance()->getDbProp(propName)->setValue64((sint64)altLookProp.Summary);
3400 // Force to update properties.
3401 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_VPA);
3403 // Done.
3404 return true;
3407 NLMISC_COMMAND(color, "Command to color an entity",
3408 "\n"
3409 "<Slot>: whole number (if <0 slot will be the current selection)\n"
3410 "<UserColor>: whole number\n"
3411 "<Hair>: whole number\n"
3412 "<Eyes>: whole number\n"
3413 "[<Part>]: whole number\n"
3414 " default=the whole body\n"
3415 " 0=CHEST\n"
3416 " 1=LEG\n"
3417 " 2=HEAD\n"
3418 " 3=ARMS\n"
3419 " 4=HANDS\n"
3420 " 5=FEET\n")
3422 // Check parameters.
3423 if(args.size() != 4 && args.size() != 5)
3424 return false;
3426 // Witch part to dye ?
3427 sint part = -1;
3428 if(args.size() == 5)
3429 fromString(args[4], part);
3431 // Get the entity slot to dye.
3432 sint slotTmp;
3433 fromString(args[0], slotTmp);
3434 CLFECOMMON::TCLEntityId slot;
3435 if(slotTmp >= 0)
3436 slot = (CLFECOMMON::TCLEntityId)slotTmp;
3437 else
3438 slot = (CLFECOMMON::TCLEntityId)UserEntity->selection();
3440 CEntityCL *entity = EntitiesMngr.entity(slot);
3441 if(entity)
3443 sint color, hair, eyes;
3444 fromString(args[1], color);
3445 fromString(args[2], hair);
3446 fromString(args[3], eyes);
3447 entity->changeColors(color, hair, eyes, part);
3449 else
3450 nlwarning("command 'changeColors': there is no entity allocated in slot '%d'", slot);
3452 // Command well done.
3453 return true;
3456 NLMISC_COMMAND(saveIntCfg, "save the interface config file","")
3458 CInterfaceManager::getInstance()->saveConfig ("save/interface.icfg");
3459 return true;
3462 NLMISC_COMMAND(loadIntCfg, "load the interface config file","")
3464 CInterfaceManager *im = CInterfaceManager::getInstance();
3465 im->loadConfig ("save/interface.icfg");
3466 // reset the compass target
3467 CGroupCompas *gc = dynamic_cast<CGroupCompas *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:compass"));
3468 if (gc && gc->isSavedTargetValid())
3470 gc->setTarget(gc->getSavedTarget());
3472 return true;
3475 NLMISC_COMMAND(harvestDeposit, "harvest a deposit", "")
3477 // no parameter needed
3479 // Create the message for the server
3480 /* CBitMemStream out;
3481 if(GenericMsgHeaderMngr.pushNameToStream("HARVEST:DEPOSIT", out))
3483 uint16 skill = SKILLS::digging;
3485 out.serial(skill);
3487 NetMngr.push(out);
3489 // open the interface
3490 // CWidgetManager::getInstance()->getWindowFromId("ui:interface:harvest")->setActive(true);
3492 else
3493 nlwarning("command : unknown message name : 'HARVEST:DEPOSIT'");
3495 return true;
3498 NLMISC_COMMAND(training, "start a training action", "")
3500 // no parameter needed
3502 // Create the message for the server
3503 CBitMemStream out;
3504 if(GenericMsgHeaderMngr.pushNameToStream("TRAINING", out))
3506 NetMngr.push(out);
3508 else
3509 nlwarning("command : unknown message name : 'TRAINING'");
3511 return true;
3514 NLMISC_COMMAND(testMount, "Set the entity to mount","<Slot> <Mount>")
3516 CLFECOMMON::TCLEntityId slot;
3517 CLFECOMMON::TCLEntityId mount = CLFECOMMON::INVALID_SLOT;
3519 switch(args.size())
3521 case 2:
3522 fromString(args[1], mount);
3523 case 1:
3524 fromString(args[0], slot);
3525 break;
3527 default:
3528 return false;
3529 break;
3532 // Set the database.
3533 string propName = toString("SERVER:Entities:E%d:P%d", mount, CLFECOMMON::PROPERTY_RIDER_ENTITY_ID);
3534 NLGUI::CDBManager::getInstance()->getDbProp(propName)->setValue64(slot);
3535 // Force to update properties.
3536 EntitiesMngr.updateVisualProperty(0, mount, CLFECOMMON::PROPERTY_RIDER_ENTITY_ID);
3537 // Set the database.
3538 propName = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_ENTITY_MOUNTED_ID);
3539 NLGUI::CDBManager::getInstance()->getDbProp(propName)->setValue64(mount);
3540 // Force to update properties.
3541 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_ENTITY_MOUNTED_ID);
3542 return true;
3545 NLMISC_COMMAND(mount, "Set the entity to mount","<Slot> [<Mount>]")
3547 CLFECOMMON::TCLEntityId slot;
3548 CLFECOMMON::TCLEntityId mount = CLFECOMMON::INVALID_SLOT;
3550 switch(args.size())
3552 case 2:
3553 fromString(args[1], mount);
3554 case 1:
3555 fromString(args[0], slot);
3556 break;
3558 default:
3559 return false;
3560 break;
3563 // Set the database.
3564 string propName = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_ENTITY_MOUNTED_ID);
3565 NLGUI::CDBManager::getInstance()->getDbProp(propName)->setValue64(mount);
3566 // Force to update properties.
3567 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_ENTITY_MOUNTED_ID);
3569 // Command well done
3570 return true;
3573 NLMISC_COMMAND(rider, "Set the rider","<Slot> [<rider>]")
3575 CLFECOMMON::TCLEntityId slot;
3576 CLFECOMMON::TCLEntityId rider = CLFECOMMON::INVALID_SLOT;
3578 switch(args.size())
3580 case 2:
3581 fromString(args[1], rider);
3582 case 1:
3583 fromString(args[0], slot);
3584 break;
3586 default:
3587 return false;
3588 break;
3591 // Set the database.
3592 string propName = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_RIDER_ENTITY_ID);
3593 NLGUI::CDBManager::getInstance()->getDbProp(propName)->setValue64(rider);
3594 // Force to update properties.
3595 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_RIDER_ENTITY_ID);
3597 // Command well done
3598 return true;
3601 NLMISC_COMMAND(disbandConvoy, "disband current beasts convoy", "")
3603 // no parameter needed
3605 // Create the message for the server
3606 CBitMemStream out;
3607 if(GenericMsgHeaderMngr.pushNameToStream("ANIMALS:DISBAND_CONVOY", out))
3609 NetMngr.push(out);
3611 else
3612 nlwarning("command : unknown message name : 'ANIMALS:DISBAND_CONVOY'");
3614 return true;
3617 NLMISC_COMMAND(learnAllBrick, "learn all bricks (only in local mode)", "")
3619 CInterfaceManager *pIM= CInterfaceManager::getInstance();
3620 uint i=0;
3621 for(;;)
3623 CCDBNodeLeaf * node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:BRICK_FAMILY:%d:BRICKS", i), false);
3624 if(node)
3625 node->setValue64(SINT64_CONSTANT(0xFFFFFFFFFFFFFFFF));
3626 else
3627 break;
3628 i++;
3630 return true;
3633 NLMISC_COMMAND(learnBrick, "learn a specified brick (only in local mode)", "<brick number or name>")
3635 CInterfaceManager *pIM= CInterfaceManager::getInstance();
3636 CSBrickManager *pBM= CSBrickManager::getInstance();
3638 if(args.size()<1)
3639 return false;
3641 // translate to brick sheet id
3642 CSheetId brickSheetId;
3643 uint testId;
3644 fromString(args[0], testId);
3645 if(testId!=0)
3647 brickSheetId= CSheetId(testId);
3649 else
3651 string str= args[0];
3652 if(str.find(".sbrick")==string::npos)
3653 str+= ".sbrick";
3654 brickSheetId.buildSheetId(str);
3657 // get the brick sheet
3658 CSBrickSheet *brick= pBM->getBrick(brickSheetId);
3659 if(!brick)
3661 pIM->displaySystemInfo(toString("brick '%s' not found", args[0].c_str()));
3662 return false;
3665 // force learn it.
3666 CCDBNodeLeaf * node= pBM->getKnownBrickBitFieldDB(brick->BrickFamily);
3667 if(node)
3669 uint64 flags= node->getValue64();
3670 flags|= uint64(1)<<(brick->IndexInFamily-1);
3671 node->setValue64(flags);
3673 return true;
3676 NLMISC_COMMAND(learnPhrase, "learn all bricks of a specified phrase (only in local mode)", "<phrase sheetId or name>")
3678 CInterfaceManager *pIM= CInterfaceManager::getInstance();
3679 CSBrickManager *pBM= CSBrickManager::getInstance();
3680 CSPhraseManager *pPM= CSPhraseManager::getInstance();
3682 if(args.size()<1)
3683 return false;
3685 // translate to brick sheet id
3686 CSheetId phraseSheetId;
3687 uint testId;
3688 fromString(args[0], testId);
3689 if(testId!=0)
3691 phraseSheetId= CSheetId(testId);
3693 else
3695 string str= args[0];
3696 if(str.find(".sphrase")==string::npos)
3697 str+= ".sphrase";
3698 phraseSheetId.buildSheetId(str);
3701 // get the brick sheet
3702 CSPhraseCom phrase;
3703 pPM->buildPhraseFromSheet(phrase, phraseSheetId.asInt());
3704 if(phrase.empty())
3706 pIM->displaySystemInfo(toString("phrase '%s' not found", args[0].c_str()));
3707 return false;
3710 // For all bricks of this phrase
3711 for(uint i=0;i<phrase.Bricks.size();i++)
3713 CSBrickSheet *brick= pBM->getBrick(phrase.Bricks[i]);
3714 if(brick)
3716 // force learn it.
3717 CCDBNodeLeaf * node= pBM->getKnownBrickBitFieldDB(brick->BrickFamily);
3718 if(node)
3720 uint64 flags= node->getValue64();
3721 flags|= uint64(1)<<(brick->IndexInFamily-1);
3722 node->setValue64(flags);
3727 return true;
3730 /*NLMISC_COMMAND(xp, "To gain XP in a given Skill","<Amount Xp> <Skill> [<Speciality>]")
3732 // Check parameters.
3733 if( args.size() < 2 || args.size() > 3 )
3734 return false;
3736 CBitMemStream out;
3737 if(GenericMsgHeaderMngr.pushNameToStream("CHEAT:XP", out))
3739 uint32 xp;
3740 fromString(args[0], xp);
3741 string skill = args[1];
3742 string speciality;
3743 if( args.size() == 3 )
3744 speciality = args[2];
3745 out.serial( xp );
3746 out.serial( skill );
3747 out.serial( speciality );
3748 // Add the message to the send list.
3749 NetMngr.push(out);
3750 // send CHEAT:XP
3751 nlinfo("command 'xp': CHEAT:XP pushed");
3753 else
3754 nlwarning("command 'xp': unknown message named 'CHEAT:XP'");
3756 // Done.
3757 return true;
3760 NLMISC_COMMAND(money, "To earn Money (only in local mode)","<very big seed> [<big seed>] [<medium seed>] [<small seed>]")
3762 if (args.size() != 1) return false;
3763 uint64 money;
3764 fromString(args[0], money);
3765 CInterfaceManager *im = CInterfaceManager::getInstance();
3766 NLGUI::CDBManager::getInstance()->getDbProp("SERVER:INVENTORY:MONEY")->setValue64(money);
3767 return true;
3769 sint32 a = 0;
3770 sint32 b = 0;
3771 sint32 c = 0;
3772 sint32 d = 0;
3774 // Check parameters.
3775 switch(args.size())
3777 case 4:
3778 fromString(args[3], d);
3779 case 3:
3780 fromString(args[2], c);
3781 case 2:
3782 fromString(args[1], b);
3783 case 1:
3784 fromString(args[0], a);
3785 break;
3786 default:
3787 return false;
3790 CInterfaceManager *im = CInterfaceManager::getInstance();
3791 string ls = im->getDefine("money_1");
3792 string ms = im->getDefine("money_2");
3793 string bs = im->getDefine("money_3");
3794 string vbs = im->getDefine("money_4");
3795 NLGUI::CDBManager::getInstance()->getDbProp(ls + ":QUANTITY")->setValue32(a);
3796 NLGUI::CDBManager::getInstance()->getDbProp(ms + ":QUANTITY")->setValue32(b);
3797 NLGUI::CDBManager::getInstance()->getDbProp(bs + ":QUANTITY")->setValue32(c);
3798 NLGUI::CDBManager::getInstance()->getDbProp(vbs + ":QUANTITY")->setValue32(d);
3799 return true;
3803 NLMISC_COMMAND( createPerso, "create a new character", "Parameters:\n-Character name\n-Race( Fyros, Tryker...)\n-gender(Male, Female)\n-Role( MeleeFighter, RangeFighter, AttackCaster, BufferCaster, HealerCaster...)\n-Level (1-25 (but more accepted)>" )
3805 // Check parameters.
3806 if(args.size() < 5) return false;
3808 // read params
3809 string characterName = args[0];
3810 EGSPD::CPeople::TPeople race = EGSPD::CPeople::fromString( args[1] );
3811 if( race == EGSPD::CPeople::EndPeople ) return false;
3813 GSGENDER::EGender gender = GSGENDER::stringToEnum( args[2] );
3814 if( gender == GSGENDER::unknown ) return false;
3816 ROLES::ERole role = ROLES::toRoleId( args[3] );
3817 if( role == ROLES::role_unknown ) return false;
3819 uint16 level;
3820 fromString(args[4], level);
3822 CBitMemStream bms;
3823 const char *msgType = "CHEAT:CREATE_CHARACTER";
3824 if( GenericMsgHeaderMngr.pushNameToStream(msgType,bms) )
3826 bms.serial( characterName );
3827 bms.serialEnum( race );
3828 bms.serialEnum( gender );
3829 bms.serialEnum( role );
3830 bms.serial( level );
3831 NetMngr.push( bms );
3832 nldebug("<create_perso> sending 'CHEAT:CREATE_CHARACTER' message to server");
3834 else
3836 nlwarning("<create_perso> unknown message name : CHEAT:CREATE_CHARACTER");
3838 return true;
3842 NLMISC_COMMAND( add_role, "add role to character", "<Role( MeleeFighter, RangeFighter, AttackCaster, BufferCaster, HealerCaster...), Level (1-25 (but more accepted))>" )
3844 // Check parameters.
3845 if(args.size() < 2) return false;
3847 ROLES::ERole role = ROLES::toRoleId( args[0] );
3848 if( role == ROLES::role_unknown ) return false;
3850 uint16 level;
3851 fromString(args[1], level);
3853 CBitMemStream bms;
3854 const char *msgType = "CHEAT:ADD_ROLE";
3855 if( GenericMsgHeaderMngr.pushNameToStream(msgType,bms) )
3857 bms.serialEnum( role );
3858 bms.serial( level );
3859 NetMngr.push( bms );
3860 nldebug("<add_role> sending 'CHEAT:ADD_ROLE' message to server");
3862 else
3864 nlwarning("<add_role> unknown message name : CHEAT:ADD_ROLE");
3866 return true;
3870 NLMISC_COMMAND(test, "", "")
3872 sint64 x, y, z;
3873 CLFECOMMON::TCLEntityId entSlot = UserEntity->selection();
3874 CEntityCL *entPtr = EntitiesMngr.entity(entSlot);
3875 if(entPtr)
3877 if(entPtr->skeleton())
3879 if(entPtr->skeleton()->getLastClippedState())
3881 NLMISC::CMatrix mat = entPtr->skeleton()->getLastWorldMatrixComputed();
3882 NLMISC::CVectorD newPos = entPtr->pos() + mat.getJ()*0.5f;
3883 x = (sint64)(newPos.x*1000.0);
3884 y = (sint64)(newPos.y*1000.0);
3885 z = (sint64)(newPos.z*1000.0);
3886 IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSX), x);
3887 IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSY), y);
3888 IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSZ), z);
3889 entPtr->updateVisualProperty(NetMngr.getCurrentServerTick(), CLFECOMMON::PROPERTY_POSITION);
3891 x = (sint64)(entPtr->pos().x*1000.0);
3892 y = (sint64)(entPtr->pos().y*1000.0);
3893 z = (sint64)(entPtr->pos().z*1000.0);
3894 IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSX), x);
3895 IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSY), y);
3896 IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSZ), z);
3897 entPtr->updateVisualProperty(NetMngr.getCurrentServerTick()+5, CLFECOMMON::PROPERTY_POSITION);
3901 return true;
3904 NLMISC_COMMAND(testLongBubble, "To display a bubble with a long text", "<entity>")
3906 if (args.size() != 1) return false;
3907 uint entityId;
3908 fromString(args[0], entityId);
3910 CInterfaceManager *pIM = CInterfaceManager::getInstance();
3911 string text("test\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\n");
3912 uint duration = CWidgetManager::getInstance()->getSystemOption(CWidgetManager::OptionTimeoutBubbles).getValSInt32();
3914 CEntityCL *entity = EntitiesMngr.entity(entityId);
3915 if (entity)
3916 InSceneBubbleManager.chatOpen(entity->dataSetId(), text, duration);
3918 return true;
3922 //-----------------------------------------------
3923 /// Macro to set the new dist to front(back or side) for a given sheet.
3924 /// commandName : Name of the command.
3925 /// variableName : Variable Name to change.
3926 //-----------------------------------------------
3927 #define DIST_TO_COMMAND(commandName, variableName) \
3928 /* Check Parameters */ \
3929 if(args.size() != 2) \
3931 nlwarning("Command '" #commandName "': need 2 parameters, try '/help " #commandName "' for more details."); \
3932 return false; \
3935 /* Try to create the sheet with the parameter as a string. */ \
3936 CSheetId sheetId; \
3937 if(!sheetId.buildSheetId(args[0])) \
3939 /* Try to create the sheet with the parameter as an int. */ \
3940 uint32 nSheetId; \
3941 fromString(args[0], nSheetId); \
3942 sheetId = CSheetId(nSheetId); \
3943 if(sheetId == CSheetId::Unknown) \
3945 nlwarning("Command '" #commandName "': '%s' is not a valid form.", args[0].c_str()); \
3946 return false; \
3950 /* Get the new distance. */ \
3951 float dist; \
3952 fromString(args[1], dist); \
3953 if(dist < 0) \
3955 nlwarning("Command '" #commandName "': distance < 0, this is not good."); \
3956 return false; \
3959 CCharacterSheet *ch = dynamic_cast<CCharacterSheet *>(SheetMngr.get(sheetId)); \
3960 if(ch == 0) \
3962 nlwarning("Command '" #commandName "': cannot find the character for the given sheet."); \
3963 return false; \
3966 /* Set the new distance for this sheet. */ \
3967 ch->variableName = dist; \
3969 /* Well Done */ \
3970 return true; \
3972 //-----------------------------------------------
3973 // 'dist2front' : Change the distance to the front for a given sheet.
3974 //-----------------------------------------------
3975 NLMISC_COMMAND(dist2front, "Change the distance to the front for a given sheet.", "<form> <dist>")
3977 DIST_TO_COMMAND(dist2front, DistToFront);
3980 //-----------------------------------------------
3981 // 'dist2back' : Change the distance to the back for a given sheet.
3982 //-----------------------------------------------
3983 NLMISC_COMMAND(dist2back, "Change the distance to the back for a given sheet.", "<form> <dist>")
3985 DIST_TO_COMMAND(dist2back, DistToBack);
3988 //-----------------------------------------------
3989 // 'dist2side' : Change the distance to the side for a given sheet.
3990 //-----------------------------------------------
3991 NLMISC_COMMAND(dist2side, "Change the distance to the side for a given sheet.", "<form> <dist>")
3993 DIST_TO_COMMAND(dist2side, DistToSide);
3998 // Change the parent of an entity. 'parent slot' not defined remove the current parent.
3999 NLMISC_COMMAND(parent, "Change the parent of an entity.", "<slot> [<parent slot>]")
4001 CLFECOMMON::TCLEntityId parentSlot = CLFECOMMON::INVALID_SLOT;
4003 // Check parameters.
4004 switch(args.size())
4006 // Set the target for the entity.
4007 case 2:
4008 fromString(args[1], parentSlot);
4010 // Remove the target for the entity.
4011 case 1:
4013 uint entitySlot;
4014 fromString(args[0], entitySlot);
4015 CEntityCL *entity = EntitiesMngr.entity(entitySlot);
4016 if(entity)
4018 entity->parent(parentSlot);
4019 entity->pos(CVectorD::Null);
4021 else
4022 nlwarning("command 'parent': there is no entity in the slot %d", entitySlot);
4024 break;
4026 // Bad command.
4027 default:
4028 return false;
4031 // Well done.
4032 return true;
4035 NLMISC_COMMAND(displayInventoryCounter, "display the Inventory counter to compare with db counter", "")
4038 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4040 uint srvVal= NLGUI::CDBManager::getInstance()->getDbProp("SERVER:INVENTORY:COUNTER")->getValue32();
4041 uint locVal= pIM->getLocalSyncActionCounter() ;
4042 srvVal&= pIM->getLocalSyncActionCounterMask();
4043 locVal&= pIM->getLocalSyncActionCounterMask();
4045 pIM->displaySystemInfo("ServerCounter: " + toString(srvVal) + "/ LocalCounter: " + toString(locVal));
4047 // Well done.
4048 return true;
4052 NLMISC_COMMAND(displayActionCounter, "display the action counters", "")
4054 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4055 CSPhraseManager *pPM= CSPhraseManager::getInstance();
4057 // next
4058 uint srvVal= NLGUI::CDBManager::getInstance()->getDbProp(PHRASE_DB_COUNTER_NEXT)->getValue32();
4059 uint locVal= pPM->getPhraseNextExecuteCounter() ;
4060 srvVal&= PHRASE_EXECUTE_COUNTER_MASK;
4061 locVal&= PHRASE_EXECUTE_COUNTER_MASK;
4063 pIM->displaySystemInfo("NextCounter: " + toString(srvVal) + "/ LocalCounter: " + toString(locVal));
4065 // cycle
4066 srvVal= NLGUI::CDBManager::getInstance()->getDbProp(PHRASE_DB_COUNTER_CYCLE)->getValue32();
4067 locVal= pPM->getPhraseCycleExecuteCounter() ;
4068 srvVal&= PHRASE_EXECUTE_COUNTER_MASK;
4069 locVal&= PHRASE_EXECUTE_COUNTER_MASK;
4071 pIM->displaySystemInfo("CycleCounter: " + toString(srvVal) + "/ LocalCounter: " + toString(locVal));
4073 return true;
4076 NLMISC_COMMAND( reconnect, "Reconnect to the same shard (self Far TP)", "")
4078 // If the server is up, the egs will begin the quit sequence (shortened only if we are in edition or animation mode).
4079 // If the server is down or frozen, a second /reconnect will be necessary to make the client reconnect
4080 // but if you reconnect before letting the EGS save the character file, the previous saved file will be loaded.
4081 switch ( LoginSM.getCurrentState() )
4083 case CLoginStateMachine::st_ingame:
4084 LoginSM.pushEvent( CLoginStateMachine::ev_connect );
4085 break;
4086 case CLoginStateMachine::st_leave_shard:
4087 FarTP.onServerQuitOk();
4088 break;
4089 default:
4090 log.displayNL( "Can't reconnect from LoginSM state %u", (uint)LoginSM.getCurrentState() );
4093 return true;
4096 struct CItemSheetSort
4098 const CItemSheet *IS;
4099 CSheetId ID;
4100 ITEMFAMILY::EItemFamily Family;
4103 static inline bool operator < (const CItemSheetSort &lhs, const CItemSheetSort &rhs)
4105 return lhs.Family < rhs.Family;
4108 NLMISC_COMMAND(dumpItems, "Sort items by category & display their sheet ids", "")
4110 std::vector<CItemSheetSort> isVect;
4111 const CSheetManager::TEntitySheetMap &sheets = SheetMngr.getSheets();
4112 for(CSheetManager::TEntitySheetMap::const_iterator it = sheets.begin(); it != sheets.end(); ++it)
4114 const CEntitySheet *es = it->second.EntitySheet;
4115 if (es && es->type() == CEntitySheet::ITEM)
4117 CItemSheetSort iss;
4118 iss.IS = static_cast<const CItemSheet *>(es);
4119 iss.ID = it->first;
4120 iss.Family = iss.IS->Family;
4121 isVect.push_back(iss);
4125 // sort items
4126 std::sort(isVect.begin(), isVect.end());
4128 for(std::vector<CItemSheetSort>::iterator itemIt = isVect.begin(); itemIt != isVect.end(); ++itemIt)
4130 std::string info;
4131 info = "FAMILY: ";
4132 info += ITEMFAMILY::toString(itemIt->Family);
4133 info += "; Name = ";
4134 info += itemIt->IS->Id.toString();
4135 info += "; Sheet ID = ";
4136 info += toString(itemIt->ID.asInt());
4137 nlwarning(info.c_str());
4139 return true;
4142 NLMISC_COMMAND(dumpVisualSlots, "dump the visual slots", "")
4144 if (!args.empty()) return false;
4145 SheetMngr.dumpVisualSlots();
4146 SheetMngr.dumpVisualSlotsIndex();
4147 return true;
4150 NLMISC_COMMAND(skillToInt, "Convert a skill to an int", "")
4152 if (args.size() != 1) return false;
4153 CInterfaceManager *im = CInterfaceManager::getInstance();
4154 im->displaySystemInfo(toString((uint) SKILLS::toSkill(args[0])));
4155 return true;
4158 NLMISC_COMMAND(browse, "Browse a HTML document with the internal help web browser.", "")
4160 if (args.size() != 1) return false;
4161 CInterfaceManager *im = CInterfaceManager::getInstance();
4162 CAHManager::getInstance()->runActionHandler("browse", NULL, "name=ui:interface:help_browser:content:html|url="+args[0]);
4163 return true;
4166 NLMISC_COMMAND(openRingWindow, "Browse the main page in the ring web browser.", "")
4168 CInterfaceManager *im = CInterfaceManager::getInstance();
4169 CAHManager::getInstance()->runActionHandler("browse", NULL, "name=ui:interface:r2ed_web_admin:content:admin_web_page|url="+RingMainURL);
4170 return true;
4173 NLMISC_COMMAND(browseRingAdmin, "Browse a HTML document with the ring web browser.", "")
4175 if (args.size() != 1) return false;
4176 CInterfaceManager *im = CInterfaceManager::getInstance();
4177 CAHManager::getInstance()->runActionHandler("browse", NULL, "name=ui:interface:r2ed_web_admin:content:admin_web_page|url="+args[0]);
4178 return true;
4181 NLMISC_COMMAND(GUCreate, "create a guild", "<guild name>")
4183 if (args.size() != 1) return false;
4184 const char *msgName = "GUILD:CREATE";
4185 CBitMemStream out;
4186 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4188 ucstring buf = ucstring::makeFromUtf8(args[0]); // FIXME: UTF-8 (serial)
4189 out.serial( buf );
4190 NetMngr.push(out);
4192 return true;
4195 NLMISC_COMMAND(GUQuit, "quit a guild", "")
4197 if (args.size() != 0) return false;
4198 const char *msgName = "GUILD:QUIT";
4199 CBitMemStream out;
4200 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4202 NetMngr.push(out);
4204 return true;
4207 NLMISC_COMMAND(GULeaveLeadership, "abandon leadership of a guild", "")
4209 if (args.size() != 0) return false;
4210 const char *msgName = "GUILD:ABANDON_LEADERSHIP";
4211 CBitMemStream out;
4212 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4214 NetMngr.push(out);
4216 return true;
4218 NLMISC_COMMAND(GULeaveOfficerTitle, "abandon officer title", "")
4220 if (args.size() != 0) return false;
4221 const char *msgName = "GUILD:ABANDON_OFFICER_TITLE";
4222 CBitMemStream out;
4223 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4225 NetMngr.push(out);
4227 return true;
4230 NLMISC_COMMAND(GUNameOfficer, "name an officer", "<player name>")
4232 if (args.size() != 1) return false;
4233 const char *msgName = "GUILD:NAME_OFFICER";
4234 CBitMemStream out;
4235 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4237 string buf = args[0];
4238 out.serial( buf );
4239 NetMngr.push(out);
4241 return true;
4244 NLMISC_COMMAND(GUDismissOfficer, "dismiss an officer", "<player name>")
4246 if (args.size() != 1) return false;
4247 const char *msgName = "GUILD:DISMISS_OFFICER";
4248 CBitMemStream out;
4249 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4251 string buf = args[0];
4252 out.serial( buf );
4253 NetMngr.push(out);
4255 return true;
4258 NLMISC_COMMAND(GUKick, "kick a member", "<player name>")
4260 if (args.size() != 1) return false;
4261 const char *msgName = "GUILD:KICK_MEMBER";
4262 CBitMemStream out;
4263 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4265 string buf = args[0];
4266 out.serial( buf );
4267 NetMngr.push(out);
4269 return true;
4273 NLMISC_COMMAND(GUAccept, "accept an invitation", "")
4275 CAHManager::getInstance()->runActionHandler("accept_guild_invitation",NULL);
4276 return true;
4279 NLMISC_COMMAND(GURefuse, "refuse an invitation", "")
4281 CAHManager::getInstance()->runActionHandler("refuse_guild_invitation",NULL);
4282 return true;
4285 NLMISC_COMMAND(GUFriend, "invite a player to become a friend of the guild", "<player name>")
4287 if (args.size() != 1) return false;
4288 const char *msgName = "GUILD:FRIEND_INVITATION";
4289 CBitMemStream out;
4290 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4292 string buf = args[0];
4293 out.serial( buf );
4294 NetMngr.push(out);
4296 return true;
4299 NLMISC_COMMAND(GUFriendAccept, "accept to be a friend of a guild that invited you", "")
4301 if (args.size() != 0) return false;
4302 const char *msgName = "GUILD:ACCEPT_FRIEND_INVITATION";
4303 CBitMemStream out;
4304 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4306 NetMngr.push(out);
4308 return true;
4311 NLMISC_COMMAND(GUFriendRefuse, "refuse to be a friend of a guild that invited you", "")
4313 if (args.size() != 0) return false;
4314 const char *msgName = "GUILD:REFUSE_FRIEND_INVITATION";
4315 CBitMemStream out;
4316 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4318 NetMngr.push(out);
4320 return true;
4323 NLMISC_COMMAND(GUSetSuccessor, "set the successor of the guild leader", "<player name>")
4325 if (args.size() != 1) return false;
4326 const char *msgName = "GUILD:SET_SUCCESSOR";
4327 CBitMemStream out;
4328 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4330 string buf = args[0];
4331 out.serial( buf );
4332 NetMngr.push(out);
4334 return true;
4337 NLMISC_COMMAND(GUInfos, "get information on a guild", "<guild name>")
4339 if (args.size() != 1) return false;
4340 const char *msgName = "GUILD:GET_INFOS";
4341 CBitMemStream out;
4342 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4344 string buf = args[0];
4345 out.serial( buf );
4346 NetMngr.push(out);
4348 return true;
4351 NLMISC_COMMAND(GUJournal, "get the guild journal", "")
4353 if (args.size() != 0) return false;
4354 const char *msgName = "GUILD:GET_LOG";
4355 CBitMemStream out;
4356 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4358 NetMngr.push(out);
4360 return true;
4363 NLMISC_COMMAND(buildingTeleport, "teleport to a building", "building index")
4365 if (args.size() != 1) return false;
4366 uint16 index;
4367 fromString(args[0], index);
4368 const char *msgName = "GUILD:TELEPORT";
4369 CBitMemStream out;
4370 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4372 out.serial(index);
4373 NetMngr.push(out);
4375 return true;
4378 NLMISC_COMMAND(logFaberMpCompatibles, "log all MP compatibles for faber the item", "sheetid")
4380 if (args.size() != 1) return false;
4381 uint32 sheetId;
4382 fromString(args[0], sheetId);
4383 CSBrickManager *pBM= CSBrickManager::getInstance();
4385 // get the faber plan
4386 CSBrickSheet *brick= pBM->getBrick(CSheetId(sheetId));
4387 // get the origin of the item built
4388 CItemSheet *itemBuilt= NULL;
4389 if(brick)
4390 itemBuilt= dynamic_cast<CItemSheet*>(SheetMngr.get(brick->FaberPlan.ItemBuilt));
4391 if(brick && itemBuilt)
4394 // build array of MP sheetId
4395 std::vector<CItemSheet*> mps;
4396 mps.reserve(100);
4397 const CSheetManager::TEntitySheetMap &sheetMap= SheetMngr.getSheets();
4398 CSheetManager::TEntitySheetMap::const_iterator it;
4399 for(it= sheetMap.begin(); it!=sheetMap.end(); it++)
4401 CItemSheet *mp= const_cast<CItemSheet*>( dynamic_cast<const CItemSheet*>(it->second.EntitySheet) );
4402 if(mp && mp->Family == ITEMFAMILY::RAW_MATERIAL)
4403 mps.push_back(mp);
4406 // header
4407 uint numMpSlots= (uint)brick->FaberPlan.ItemPartMps.size();
4408 nlinfo("********** FABERLOG **********");
4409 nlinfo(" ItemBuilt Origin: %s", ITEM_ORIGIN::enumToString(itemBuilt->ItemOrigin).c_str() );
4410 nlinfo(" NumMPSlot: %d", numMpSlots);
4412 // Parse All Slots.
4413 for(uint i=0;i<numMpSlots;i++)
4415 CSBrickSheet::CFaberPlan::CItemPartMP &mpSlot= brick->FaberPlan.ItemPartMps[i];
4416 nlinfo(" MPSlot %d", i);
4417 nlinfo(" Quantity: %d", mpSlot.Quantity);
4418 nlinfo(" TypeReq: %s", RM_FABER_TYPE::toString(mpSlot.FaberTypeFilter).c_str() );
4419 nlinfo(" List Of Compatibles MPs:");
4421 for(uint i=0;i<mps.size();i++)
4423 CItemSheet *itemSheet= mps[i];
4424 bool ok= true;
4425 // check faber type filter
4426 if( mpSlot.FaberTypeFilter!=RM_FABER_TYPE::Unknown && !itemSheet->canBuildItemPart(mpSlot.FaberTypeFilter, itemBuilt->ItemOrigin))
4427 ok= false;
4429 if(ok)
4431 nlinfo(" %s", itemSheet->Id.toString().c_str() );
4438 return true;
4441 NLMISC_COMMAND(debugItemInfo, "simulate a ItemInfo received from server", "itemSlotId version [enchant]")
4443 CItemInfos itemInfo;
4445 if (args.size() < 2 || args.size() > 3) return false;
4446 bool enchant= false;
4447 if(args.size()==3)
4448 fromString(args[2], enchant);
4450 fromString(args[0], itemInfo.slotId);
4451 fromString(args[1], itemInfo.versionInfo);
4453 itemInfo.CurrentDamage= 10;
4454 itemInfo.MaxDamage= 15;
4455 itemInfo.DodgeModifier= 5;
4456 itemInfo.ParryModifier= -10;
4457 itemInfo.AdversaryDodgeModifier= 666;
4458 itemInfo.AdversaryParryModifier= 333;
4459 itemInfo.HpBuff= 12;
4460 itemInfo.SapBuff= -14;
4461 itemInfo.StaBuff= 0;
4462 itemInfo.FocusBuff= 1;
4463 itemInfo.MagicProtection[0]= PROTECTION_TYPE::Electricity;
4464 itemInfo.MagicProtectionFactor[0]= 43;
4465 itemInfo.MagicProtection[1]= PROTECTION_TYPE::Shockwave;
4466 itemInfo.MagicProtectionFactor[1]= 21;
4467 itemInfo.MagicProtection[2]= PROTECTION_TYPE::Rot;
4468 itemInfo.MagicProtectionFactor[2]= 100;
4469 itemInfo.DesertMagicResistance= 133;
4470 itemInfo.ForestMagicResistance= 500;
4471 itemInfo.PrimaryRootMagicResistance= 341;
4472 itemInfo.Hp= 66;
4473 itemInfo.HpMax= 100;
4474 itemInfo.Range= 169;
4475 itemInfo.SapLoadCurrent= 6;
4476 itemInfo.SapLoadMax= 30;
4477 itemInfo.HitRate= 8;
4478 itemInfo.ProtectionFactor= 0.25;
4479 itemInfo.MaxSlashingProtection= 38;
4480 itemInfo.MaxPiercingProtection= 48;
4481 itemInfo.MaxBluntProtection= 58;
4482 itemInfo.WearEquipmentMalus= 0.31f;
4484 if(enchant)
4486 itemInfo.Enchantment.Name="pipoSort";
4487 itemInfo.Enchantment.Bricks.resize(3);
4488 itemInfo.Enchantment.Bricks[0]= CSheetId("bmpa01.sbrick");
4489 itemInfo.Enchantment.Bricks[1]= CSheetId("bmlchea01.sbrick");
4490 itemInfo.Enchantment.Bricks[2]= CSheetId("bmlchmh00005.sbrick");
4493 switch(rand()%4)
4495 case 0:
4496 break;
4497 case 1:
4499 itemInfo.CastingSpeedFactor[1]= 1.0f;
4500 itemInfo.MagicPowerFactor[1]= 0.2f;
4502 break;
4503 case 2:
4505 itemInfo.CastingSpeedFactor[0]= 0.4f;
4506 itemInfo.MagicPowerFactor[0]= 0.2f;
4507 itemInfo.CastingSpeedFactor[2]= 0.8f;
4508 itemInfo.MagicPowerFactor[2]= 0.3f;
4510 break;
4511 case 3:
4513 itemInfo.CastingSpeedFactor[0]= 0.3f;
4514 itemInfo.MagicPowerFactor[0]= 0.3f;
4515 itemInfo.CastingSpeedFactor[1]= 0.3f;
4516 itemInfo.MagicPowerFactor[1]= 0.3f;
4517 itemInfo.CastingSpeedFactor[2]= 0.3f;
4518 itemInfo.MagicPowerFactor[2]= 0.3f;
4519 itemInfo.CastingSpeedFactor[3]= 0.3f;
4520 itemInfo.MagicPowerFactor[3]= 0.3f;
4522 break;
4526 getInventory().onReceiveItemInfo(itemInfo);
4528 return true;
4531 NLMISC_COMMAND(debugItemInfoWaiters, "log ItemInfoWaiters", "")
4533 getInventory().debugItemInfoWaiters();
4535 return true;
4538 NLMISC_COMMAND(debugItemInfoCache, "log ItemInfoCache", "")
4540 getInventory().debugItemInfoCache();
4542 return true;
4545 NLMISC_COMMAND(debugInfoWindows, "log info windows sheetId", "")
4547 CInterfaceHelp::debugOpenedInfoWindows();
4549 return true;
4552 NLMISC_COMMAND(getSkillValue, "get a skill value by its name", "skill_name")
4554 if (args.size() != 1) return false;
4555 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4556 uint skillId= (uint) SKILLS::toSkill(args[0]);
4557 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:SKILL", skillId), false);
4558 if(node)
4560 pIM->displaySystemInfo(toString(node->getValue32()));
4563 return true;
4566 NLMISC_COMMAND(setSkillValue, "set a skill value by its name", "skill_name value")
4568 if (args.size() != 2) return false;
4569 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4570 uint skillId= (uint) SKILLS::toSkill(args[0]);
4571 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:SKILL", skillId), false);
4572 if(node)
4574 sint32 value;
4575 fromString(args[1], value);
4576 node->setValue32(value);
4579 return true;
4582 NLMISC_COMMAND(getBaseSkillValue, "get a baseskill value by its name", "skill_name")
4584 if (args.size() != 1) return false;
4585 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4586 uint skillId= (uint) SKILLS::toSkill(args[0]);
4587 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:BaseSKILL", skillId), false);
4588 if(node)
4590 pIM->displaySystemInfo(toString(node->getValue32()));
4593 return true;
4596 NLMISC_COMMAND(setBaseSkillValue, "set a baseskill value by its name", "skill_name value")
4598 if (args.size() != 2) return false;
4599 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4600 uint skillId= (uint) SKILLS::toSkill(args[0]);
4601 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:BaseSKILL", skillId), false);
4602 if(node)
4604 sint32 value;
4605 fromString(args[1], value);
4606 node->setValue32(value);
4609 return true;
4612 NLMISC_COMMAND(setAllSkillValue, "set all Skill and baseskill to the given value", "value")
4614 if (args.size() != 1) return false;
4615 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4616 uint value;
4617 fromString(args[0], value);
4618 for(uint i=0;i<SKILLS::NUM_SKILLS;i++)
4620 CCDBNodeLeaf *node;
4621 node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:BaseSKILL", i), false);
4622 if(node)
4623 node->setValue32(value);
4624 node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:SKILL", i), false);
4625 if(node)
4626 node->setValue32(value);
4629 return true;
4632 NLMISC_COMMAND(setEntityName, "set a entity name id", "entitySlot nameId")
4634 if (args.size() != 2) return false;
4635 uint slot;
4636 fromString(args[0], slot);
4638 CCharacterCL *entity= dynamic_cast<CCharacterCL*>(EntitiesMngr.entity(slot));
4639 if(entity)
4641 uint32 nameId;
4642 fromString(args[1], nameId);
4643 entity->debugSetNameId(nameId);
4645 return true;
4648 NLMISC_COMMAND(reloadWeather, "reload the weather sheets", "")
4650 if (!args.empty()) return false;
4651 ContinentMngr.reloadWeather();
4652 return true;
4656 // Common method to reload sheets (hope it works later...)
4657 template<class T>
4658 bool reloadSheets(string filter, string wildcardFilter)
4660 CSheetManager sheetManager;
4661 std::vector<std::string> filters;
4662 filters.push_back(filter);
4663 ClientSheetsStrings.memoryUncompress();
4664 NLMISC::IProgressCallback progress;
4665 sheetManager.loadAllSheetNoPackedSheet(progress, filters, wildcardFilter);
4666 ClientSheetsStrings.memoryCompress();
4667 // copy sheets into current sheet manager (because numerous ptr are kept on the previous sheets in various places)
4668 const CSheetManager::TEntitySheetMap &sheetMap= sheetManager.getSheets();
4669 CSheetManager::TEntitySheetMap::const_iterator it;
4670 for(it=sheetMap.begin();it!=sheetMap.end();it++)
4672 T *dest = dynamic_cast<T*>(SheetMngr.get(it->first));
4673 if (dest)
4675 const T *src = dynamic_cast<T*>(it->second.EntitySheet);
4676 if (src)
4678 *dest = *src;
4682 return true;
4685 std::string extendWildcard(const std::string &in)
4687 string out;
4688 // append * at begin if not present (or if enp
4689 if(in.empty() || in[0]!='*')
4690 out= '*';
4691 out+= in;
4692 // append .* at end if no . found
4693 if(in.find('.')==string::npos)
4694 out+= ".*";
4695 return out;
4698 // macros to reload Sheets
4699 #define CMD_RELOAD_SHEET(_cmd_name, _filter, _type) \
4700 NLMISC_COMMAND(_cmd_name, #_cmd_name, "") \
4702 if (args.size()>1) return false; \
4703 string wildcardFilter; \
4704 if (args.size()>=1) \
4705 wildcardFilter= extendWildcard(args[0]); \
4706 return reloadSheets<_type>(_filter, wildcardFilter); \
4708 // Important ones
4709 CMD_RELOAD_SHEET(reloadCreature, "creature", CCharacterSheet)
4710 CMD_RELOAD_SHEET(reloadSbrick, "sbrick", CSBrickSheet)
4711 CMD_RELOAD_SHEET(reloadSphrase, "sphrase", CSPhraseSheet)
4712 CMD_RELOAD_SHEET(reloadSitem, "sitem", CItemSheet)
4713 // Not tested ones
4715 CMD_RELOAD_SHEET(reloadPlayer, "player", CPlayerSheet)
4716 CMD_RELOAD_SHEET(reloadFx, "fx", CFXSheet)
4717 CMD_RELOAD_SHEET(reloadBuilding, "building", CBuildingSheet)
4718 CMD_RELOAD_SHEET(reloadDeath_impact, "death_impact", CPactSheet)
4719 CMD_RELOAD_SHEET(reloadMission, "mission", CMissionSheet)
4720 CMD_RELOAD_SHEET(reloadRace_stats, "race_stats", CRaceStatsSheet)
4721 CMD_RELOAD_SHEET(reloadLight_cycle, "light_cycle", CLightCycleSheet)
4722 CMD_RELOAD_SHEET(reloadContinent, "continent", CContinentSheet)
4723 CMD_RELOAD_SHEET(reloadWorld, "world", CWorldSheet)
4724 CMD_RELOAD_SHEET(reloadMission_icon, "mission_icon", CMissionIconSheet)
4725 CMD_RELOAD_SHEET(reloadSkill_tree, "skill_tree", CSkillsTreeSheet)
4726 CMD_RELOAD_SHEET(reloadTitles, "titles", CUnblockTitlesSheet)
4727 CMD_RELOAD_SHEET(reloadSucces_chances_table, "succes_chances_table", CSuccessTableSheet)
4728 CMD_RELOAD_SHEET(reloadAutomaton_list, "automaton_list", CAutomatonListSheet)
4729 CMD_RELOAD_SHEET(reloadAnimset_list, "animset_list", CAnimationSetListSheet)
4730 CMD_RELOAD_SHEET(reloadAnimation_fx, "animation_fx", CAnimationFXSheet)
4731 CMD_RELOAD_SHEET(reloadEmot, "emot", CEmotListSheet)
4732 CMD_RELOAD_SHEET(reloadForage_source, "forage_source", CForageSourceSheet)
4733 CMD_RELOAD_SHEET(reloadText_emotes, "text_emotes", CTextEmotListSheet)
4736 NLMISC_COMMAND(vprop, "Flush the Visual Property (local only). you must write to the DB before (but if you give the value in the 3rd arg)", "slot propId [val]")
4738 if(args.size()!=2 && args.size()!=3) return false;
4739 uint slot;
4740 fromString(args[0], slot);
4741 uint propId;
4742 fromString(args[1], propId);
4744 // set value in the DB?
4745 if(args.size()==3)
4747 sint64 val= 0;
4748 fromString(args[2], val);
4749 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4750 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:Entities:E%d:P%d", slot, propId), false);
4751 if(node)
4752 node->setValue64(val);
4755 EntitiesMngr.updateVisualProperty(0, slot, propId);
4757 return true;
4760 NLMISC_COMMAND(dataSetId, "Set the UID of an entity", "slot uid")
4762 if(args.size()!=2) return false;
4763 uint slot;
4764 fromString(args[0], slot);
4765 uint uid;
4766 fromString(args[1], uid);
4768 CEntityCL *entity= EntitiesMngr.entity(slot);
4769 if(!entity)
4770 return false;
4772 entity->dataSetId(uid);
4774 return true;
4777 NLMISC_COMMAND(forceDisplayFXBBoxes, "Force to display bboxes of all fxs", "0=off, 1=off")
4779 if (args.size() != 1) return false;
4780 bool on;
4781 fromString(args[0], on);
4782 UParticleSystemInstance::forceDisplayBBox(on);
4783 return true;
4786 NLMISC_COMMAND(dumpVillages, "Dump villages loading zones in a bitmap", "filename>")
4788 if (args.size() != 1) return false;
4789 ContinentMngr.cur()->dumpVillagesLoadingZones(args[0]);
4790 return true;
4793 NLMISC_COMMAND(dumpFogDayMap, "Dump fog day map", "filename>")
4795 if (args.size() != 1) return false;
4796 ContinentMngr.cur()->dumpFogMap(CFogMapBuild::Day, args[0]);
4797 return true;
4801 NLMISC_COMMAND(dumpFogDepthMap, "Dump fog depth map", "filename>")
4803 if (args.size() != 1) return false;
4804 ContinentMngr.cur()->dumpFogMap(CFogMapBuild::Depth, args[0]);
4805 return true;
4808 NLMISC_COMMAND(dumpFogDistMap, "Dump fog depth map", "filename>")
4810 if (args.size() != 1) return false;
4811 ContinentMngr.cur()->dumpFogMap(CFogMapBuild::Distance, args[0]);
4812 return true;
4815 NLMISC_COMMAND(dumpRainMap, "Dump fog rain map", "filename>")
4817 if (args.size() != 1) return false;
4818 CRGBA colorLookup[256];
4819 for(uint8 k = 1; k < 255; ++k)
4821 colorLookup[k] = CRGBA(k, k, k, 1);
4823 colorLookup[0] = CRGBA::Red;
4824 colorLookup[255] = CRGBA::Blue;
4825 ContinentMngr.cur()->dumpFogMap(CFogMapBuild::NoPrecipitation, args[0], CContinent::ChannelR, colorLookup);
4826 return true;
4830 NLMISC_COMMAND(stick_log, "", "<slot>")
4832 if(args.size()!=1)
4833 return false;
4834 CLFECOMMON::TCLEntityId slot;
4835 fromString(args[0], slot);
4837 // Compute the position.
4838 CEntityCL *entity = EntitiesMngr.entity(slot);
4839 if(!entity)
4840 return false;
4842 USkeleton *skel= entity->skeleton();
4843 if(skel)
4845 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4846 nlinfo("Skel Log: %s", skel->getShapeName().c_str());
4848 std::vector<UTransform> sticks;
4849 skel->getStickedObjects(sticks);
4851 nlinfo("StickedModels: %d", sticks.size());
4852 pIM->displaySystemInfo(toString("StickedModels: %d", sticks.size()));
4854 for(uint i=0;i<sticks.size();i++)
4856 UInstance inst;
4857 inst.cast(sticks[i]);
4858 if(!inst.empty())
4860 string str= toString(" %d: %X. %s", i, inst.getObjectPtr(), inst.getShapeName().c_str());
4861 nlinfo(str.c_str());
4862 pIM->displaySystemInfo(str);
4864 else
4866 string str= toString(" %d: %X. NOT a TransformShape", i, sticks[i].getObjectPtr());
4867 nlinfo(str.c_str());
4868 pIM->displaySystemInfo(str);
4873 return true;
4876 NLMISC_COMMAND(print_sys, "", "<cat> <str>")
4878 if(args.size()<1)
4879 return false;
4880 string cat= args[0];
4881 string str;
4882 for (uint i = 1; i < args.size(); i++)
4884 str += args[i] + " ";
4887 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4888 pIM->displaySystemInfo(str, cat);
4890 return true;
4893 NLMISC_COMMAND(fillAllInfoVersion, "", "<version>")
4895 if(args.size()!=1)
4896 return false;
4898 uint i,j;
4899 uint ver;
4900 fromString(args[0], ver);
4901 CInventoryManager &im= getInventory();
4903 // BAG
4904 for(i=0;i<MAX_BAGINV_ENTRIES;i++)
4905 im.getServerBagItem(i).setInfoVersion(ver);
4907 // PACK_ANIMAL
4908 for(j=0;j<MAX_PACK_ANIMAL;j++)
4910 for(i=0;i<MAX_ANIMALINV_ENTRIES;i++)
4911 im.getServerPAItem(j,i).setInfoVersion(ver);
4914 // EXCHANGE
4915 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4916 for(i=0;i<CPlayerTrade::NumTradeSlot;i++)
4918 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:EXCHANGE:GIVE:%d:INFO_VERSION", i), false);
4919 if(node)
4920 node->setValue32(ver);
4921 node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:EXCHANGE:RECEIVE:%d:INFO_VERSION", i), false);
4922 if(node)
4923 node->setValue32(ver);
4926 return true;
4929 NLMISC_COMMAND(fullFillInventory, "", "dbstring sheetName")
4931 if(args.size()!=2)
4932 return false;
4934 // read value
4935 sint64 value;
4936 if (isalpha(args[1][0]))
4938 CSheetId sheet(args[1]);
4939 value = (sint64) sheet.asInt();
4941 else
4943 // Convert the string into an sint64.
4944 fromString(args[1], value);
4947 // read db dest
4948 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4949 CCDBNodeBranch *nb= NLGUI::CDBManager::getInstance()->getDbBranch(args[0]);
4950 if(!nb)
4951 return false;
4953 uint num= nb->getNbNodes();
4954 for(uint i=0;i<num;i++)
4956 CCDBNodeLeaf *nl;
4957 nl= NLGUI::CDBManager::getInstance()->getDbProp(args[0]+":"+toString(i)+":SHEET", false);
4958 if(nl)
4960 nl->setValue64(value);
4961 nl= NLGUI::CDBManager::getInstance()->getDbProp(args[0]+":"+toString(i)+":QUALITY", false);
4962 if(nl)
4963 nl->setValue64(i);
4964 nl= NLGUI::CDBManager::getInstance()->getDbProp(args[0]+":"+toString(i)+":PREREQUISIT_VALID", false);
4965 if(nl)
4966 nl->setValue64(1);
4970 return true;
4973 NLMISC_COMMAND(fillAllItemPreReq, "", "dbstring value")
4975 if(args.size()!=2)
4976 return false;
4978 // read value
4979 sint32 value;
4980 fromString(args[1], value);
4981 string dbBase= args[0];
4983 // write prop for all elements of the branch
4984 uint index= 0;
4985 for(;;)
4987 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4988 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("%s:%d:PREREQUISIT_VALID", dbBase.c_str(), index), false);
4989 if(!node)
4990 break;
4991 node->setValue32(value);
4992 index++;
4995 return true;
4998 NLMISC_COMMAND(eventMusic, "", "music")
5000 if(args.size()<1 && args.size()>3)
5001 return false;
5003 string fileName= args[0].c_str();
5004 bool loop= false;
5005 if(args.size() > 1)
5006 fromString(args[1], loop);
5007 uint fadeTime= 1000;
5008 if(args.size() > 2)
5009 fromString(args[2], fadeTime);
5011 if(SoundMngr)
5012 SoundMngr->playEventMusic(fileName, fadeTime, loop);
5014 return true;
5018 NLMISC_COMMAND(setLightHour, "force the light hour, (negative value to reset to auto)", "<hour>")
5020 if( args.size()!=1 )
5021 return false;
5023 float hour;
5024 fromString(args[0], hour);
5025 if( hour < LightCycleManager.getLightDesc().NumHours )
5027 // check for privileges if this is the final build
5028 #if FINAL_VERSION
5029 // test that user has privilege
5030 if (hasPrivilegeDEV() ||
5031 hasPrivilegeSGM() ||
5032 hasPrivilegeGM() ||
5033 hasPrivilegeVG() ||
5034 hasPrivilegeSG() ||
5035 hasPrivilegeG() ||
5036 hasPrivilegeEM() ||
5037 hasPrivilegeEG())
5038 #endif
5040 ForcedDayNightCycleHour = hour;
5041 return true;
5044 return false;
5049 NLMISC_COMMAND(jobAnim, "set the job anim specialisation of an entity", "eid number")
5051 if(args.size()!=2)
5052 return false;
5054 uint eid;
5055 fromString(args[0], eid);
5056 uint jas;
5057 fromString(args[1], jas);
5058 CCharacterCL *ent= dynamic_cast<CCharacterCL*>(EntitiesMngr.entity(eid));
5059 if(ent)
5061 ent->setAnimJobSpecialisation(jas);
5064 return true;
5067 NLMISC_COMMAND(startLogStageChange, "start to log the change of stages of watched entity", "")
5069 // stop first any log
5070 EntitiesMngr.stopLogStageChange();
5072 // start the log
5073 EntitiesMngr.startLogStageChange(NetMngr.getCurrentClientTick(), T1);
5075 return true;
5078 NLMISC_COMMAND(stopLogStageChange, "stop to log the change of watched entity stages", "")
5080 EntitiesMngr.stopLogStageChange();
5081 return true;
5084 NLMISC_COMMAND(testReceiveMissionInfo, "emulate a dummy receive of mission info", "")
5086 CBotChatManager::getInstance()->debugLocalReceiveMissionInfo();
5087 return true;
5090 // command to dump the ui, no indentation full name
5091 NLMISC_COMMAND(dumpUIIndent, "Debug only : Dump the ui hierarchy in the output debug window", "")
5093 CInterfaceManager *im = CInterfaceManager::getInstance();
5094 im->dumpUI(true);
5095 return true;
5098 // command to dump the ui, no indentation full name
5099 NLMISC_COMMAND(dumpUIFull, "Debug only : Dump the ui hierarchy in the output debug window", "")
5101 CInterfaceManager *im = CInterfaceManager::getInstance();
5102 im->dumpUI(false);
5103 return true;
5106 // command to dump coordinates of a UI, for debug
5107 NLMISC_COMMAND(dumpUICoords, "Debug only : dump all coords info of an UI", "uiid")
5109 if(args.size()!=1)
5110 return false;
5112 CInterfaceManager *pIM = CInterfaceManager::getInstance();
5113 CInterfaceElement *el= CWidgetManager::getInstance()->getElementFromId(args[0]);
5114 if(!el)
5116 pIM->displaySystemInfo(toString("dumpUICoords: '%s' does not exist", args[0].c_str()));
5118 else
5120 pIM->displaySystemInfo(toString("dumpUICoords: **** '%s'", args[0].c_str()));
5121 pIM->displaySystemInfo(toString(" active= %d", uint(el->getActive()) ));
5122 pIM->displaySystemInfo(toString(" x= %d", el->getX() ));
5123 pIM->displaySystemInfo(toString(" y= %d", el->getY() ));
5124 pIM->displaySystemInfo(toString(" w= %d", el->getW() ));
5125 pIM->displaySystemInfo(toString(" h= %d", el->getH() ));
5126 pIM->displaySystemInfo(toString(" xreal= %d", el->getXReal() ));
5127 pIM->displaySystemInfo(toString(" yreal= %d", el->getYReal() ));
5128 pIM->displaySystemInfo(toString(" wreal= %d", el->getWReal() ));
5129 pIM->displaySystemInfo(toString(" hreal= %d", el->getHReal() ));
5130 pIM->displaySystemInfo(toString(" parent= '%s'", el->getParent()?el->getParent()->getId().c_str():""));
5131 pIM->displaySystemInfo(toString(" parentpos= '%s'", el->getParentPos()?el->getParentPos()->getId().c_str():""));
5132 pIM->displaySystemInfo(toString(" parentsize= '%s'", el->getParentSize()?el->getParentSize()->getId().c_str():""));
5134 // SizeRef
5135 string sr;
5136 switch(el->getSizeRef())
5138 case 1: sr= "w"; break;
5139 case 2: sr= "h"; break;
5140 case 3: sr= "wh"; break;
5141 default:break;
5143 pIM->displaySystemInfo(toString(" sizeref= '%s'", sr.c_str()));
5145 // PosRef
5146 string pr;
5147 THotSpot hsParent= el->getParentPosRef();
5148 THotSpot hsSelf= el->getPosRef();
5149 // parent
5150 if(hsParent & Hotspot_Bx) pr+= "B";
5151 else if(hsParent & Hotspot_Mx) pr+= "M";
5152 else if(hsParent & Hotspot_Tx) pr+= "T";
5153 else pr+= "?";
5154 if(hsParent & Hotspot_xL) pr+= "L";
5155 else if(hsParent & Hotspot_xM) pr+= "M";
5156 else if(hsParent & Hotspot_xR) pr+= "R";
5157 else pr+= "?";
5158 pr+=" ";
5159 // self
5160 if(hsSelf & Hotspot_Bx) pr+= "B";
5161 else if(hsSelf & Hotspot_Mx) pr+= "M";
5162 else if(hsSelf & Hotspot_Tx) pr+= "T";
5163 else pr+= "?";
5164 if(hsSelf & Hotspot_xL) pr+= "L";
5165 else if(hsSelf & Hotspot_xM) pr+= "M";
5166 else if(hsSelf & Hotspot_xR) pr+= "R";
5167 else pr+= "?";
5168 pIM->displaySystemInfo(toString(" posref= '%s'", pr.c_str()));
5170 pIM->displaySystemInfo(string("dumpUICoords: **** END"));
5173 return true;
5176 // Command to clear the dump of done Files opened and Async File Manager done files (for debug)
5177 NLMISC_COMMAND(clearDumpFiles, "clear the CAsyncFileManager and CIFile Debug list of opened files", "")
5179 CIFile::clearDump();
5180 CAsyncFileManager::getInstance().clearDump();
5182 return true;
5185 #endif // FINAL_VERSION
5188 /////////////////////////////////////////////////////////////////////////////
5189 /////////////////////////////////////////////////////////////////////////////
5190 /////////////////////////////////////////////////////////////////////////////
5191 /////////////////////////////////////////////////////////////////////////////
5192 /////////// COMMANDS before should NOT appear IN the FINAL VERSION //////////
5193 /////////////////////////////////////////////////////////////////////////////
5194 /////////////////////////////////////////////////////////////////////////////
5195 /////////////////////////////////////////////////////////////////////////////
5196 /////////////////////////////////////////////////////////////////////////////
5197 /////////////////////////////////////////////////////////////////////////////
5199 NLMISC_COMMAND(reloadFogMaps, "Force to reload all the fog maps", "<>")
5201 if (!args.empty()) return false;
5202 ContinentMngr.cur()->reloadFogMap();
5203 return true;
5206 // dump the names of all loaded sounds
5207 NLMISC_COMMAND(dumpSounds, "Dump names of all loaded sound", "<>")
5209 if (!args.empty()) return false;
5210 std::vector<NLMISC::TStringId> sounds;
5211 extern CSoundManager *SoundMngr;
5212 if (!SoundMngr) return false;
5213 if (!SoundMngr->getMixer()) return false;
5214 SoundMngr->getMixer()->getSoundNames(sounds);
5215 for(uint k = 0; k < sounds.size(); ++k)
5217 nlinfo(NLMISC::CStringMapper::unmap(sounds[k]).c_str());
5219 return true;
5222 // ***************************************************************************
5223 // LUA
5224 // ***************************************************************************
5225 const char *LUADebugNotEnabledMsg= "Lua Commands are available only if you add 'AllowDebugLua= 1;' in your client.cfg";
5227 NLMISC_COMMAND(luaReload, "reload all .lua script files", "")
5229 CInterfaceManager *pIM= CInterfaceManager::getInstance();
5230 if(ClientCfg.AllowDebugLua)
5232 CWidgetManager::getInstance()->getParser()->reloadAllLuaFileScripts();
5233 return true;
5235 else
5237 pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg));
5238 return false;
5242 NLMISC_COMMAND(luaScript, "Execute a lua script", "direct_script_code")
5244 CInterfaceManager *pIM= CInterfaceManager::getInstance();
5245 if(ClientCfg.AllowDebugLua)
5247 if(args.size()<1)
5248 return false;
5250 // Concat list of string in one script
5251 string script;
5252 for(uint i=0;i<args.size();i++)
5254 script+= args[i] + " ";
5257 // not smallScript because suppose var can change a lot
5258 CLuaManager::getInstance().executeLuaScript(script, false);
5260 return true;
5262 else
5264 pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg));
5265 return false;
5269 NLMISC_COMMAND(luaInfo, "Dump some information on LUA state", "detaillevel from 0 to 2")
5271 CInterfaceManager *pIM= CInterfaceManager::getInstance();
5272 if(ClientCfg.AllowDebugLua)
5274 if(args.size()!=1)
5275 return false;
5277 uint detail;
5278 fromString(args[0], detail);
5280 pIM->dumpLuaState(detail);
5281 return true;
5283 else
5285 pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg));
5286 return false;
5290 NLMISC_COMMAND(luaObject, "Dump the content of a lua object", "<table name> [maxDepth = 20, 0 for no limits]")
5292 if (args.empty()) return false;
5293 if (args.size() > 2) return false;
5294 CInterfaceManager *pIM= CInterfaceManager::getInstance();
5295 if (!ClientCfg.AllowDebugLua)
5297 pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg));
5298 return false;
5300 CLuaState *luaState = CLuaManager::getInstance().getLuaState();
5301 if (!luaState) return false;
5302 CLuaStackChecker lsc(luaState);
5303 // get the table
5304 static const char *inspectedTable = "_____inspected_table";
5307 // make a reference to the table to be inspected (is this this a primitive type, just make a copy)
5308 luaState->executeScript(std::string(inspectedTable) + " = " + args[0]);
5310 catch(const ELuaError &e)
5312 CLuaIHMRyzom::debugInfo(e.what());
5313 return false;
5315 luaState->pushGlobalTable();
5316 CLuaObject env;
5317 env.pop(*luaState);
5318 uint maxDepth;
5319 if (args.size() > 1)
5320 fromString(args[1], maxDepth);
5321 else
5322 maxDepth = 20;
5323 //CLuaIHM::debugInfo(env[inspectedTable].toStringRecurse(0, maxDepth));
5324 env[inspectedTable].dump();
5325 env.eraseValue(inspectedTable);
5326 return true;
5332 // GC allowed only in Dev version
5333 #if !FINAL_VERSION
5334 NLMISC_COMMAND(luaGC, "Force a garbage collector of lua", "")
5336 CInterfaceManager *pIM= CInterfaceManager::getInstance();
5337 if(ClientCfg.AllowDebugLua)
5339 CLuaManager::getInstance().forceGarbageCollect();
5340 return true;
5342 else
5344 pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg));
5345 return false;
5348 #endif
5351 // ***************************************************************************
5352 // CUserCommand
5353 // ***************************************************************************
5355 std::map<std::string, CUserCommand*> CUserCommand::CommandMap;
5357 // release memory
5358 void CUserCommand::release()
5360 std::map<std::string, CUserCommand*>::iterator it = CommandMap.begin();
5361 while( it != CommandMap.end() )
5362 delete (*it++).second;
5363 CommandMap.clear();
5366 // ***************************************************************************
5368 CUserCommand::CUserCommand(const string &commandName, const string &help, const string &argsHelp)
5369 : ICommand("user", commandName.c_str(), help.c_str(), argsHelp.c_str())
5371 CommandName = commandName;
5374 // ***************************************************************************
5376 void CUserCommand::addMode (const string &action, uint numArg, bool infiniteAgr, const std::vector<string> &keywords)
5378 CMode *mode;
5379 if (!infiniteAgr)
5380 mode = &(FixedArgModes[numArg]);
5381 else
5382 mode = &InfiniteMode;
5383 mode->Action = action;
5384 mode->KeywordsCount = numArg;
5385 mode->Keywords = keywords;
5388 // ***************************************************************************
5390 bool CUserCommand::execute(const std::string &/* rawCommandString */, const std::vector<std::string> &args, NLMISC::CLog &/* log */, bool /* quiet */, bool /* human */)
5392 CInterfaceManager *pIM = CInterfaceManager::getInstance();
5394 // Find the good keyword table
5395 CMode *mode = NULL;
5396 if (FixedArgModes.find ((uint)args.size()) != FixedArgModes.end())
5397 mode = &(FixedArgModes[(uint)args.size()]);
5398 else
5399 if (!InfiniteMode.Keywords.empty() && (args.size() >= InfiniteMode.KeywordsCount))
5400 mode = &InfiniteMode;
5402 if (mode)
5404 // Build the final string
5405 static string finalArgs;
5406 finalArgs.clear();
5407 uint i;
5408 uint index = 0;
5409 const vector<string> &keywords = mode->Keywords;
5410 for (i=0; i<keywords.size(); i++)
5412 if ((keywords[i] == "$") || (keywords[i] == "+"))
5414 if ((uint)index >= args.size())
5416 // Not enough arguments
5417 pIM->displaySystemInfo (CommandName+" : "+CI18N::get ("uiCommandWrongArgumentCount"));
5418 return false;
5420 else
5422 if (keywords[i] == "$")
5423 finalArgs += args[index++];
5424 else
5426 while (index<args.size())
5428 finalArgs += (index > 0) ? " " : "";
5429 // If arg contains spaces then put it in quotes
5430 if (string::npos != args[index].find(" "))
5432 finalArgs += "\"" + args[index++] + "\"";
5434 else
5436 finalArgs += args[index++];
5442 else
5444 finalArgs += keywords[i];
5448 // Run the action handler
5449 CAHManager::getInstance()->runActionHandler (mode->Action, CWidgetManager::getInstance()->getOldCaptureKeyboard(), finalArgs);
5451 else
5453 // Not enough argument
5454 pIM->displaySystemInfo (CommandName+" : "+CI18N::get ("uiCommandWrongArgumentCount"));
5455 return false;
5457 return true;
5460 // ***************************************************************************
5462 void CUserCommand::createCommand (const char *name, const char *action, const char *ptrParams)
5464 // Parse the params
5465 std::vector<string> keywords;
5467 // Get the help and the argument help
5468 uint countArgument = 0;
5469 bool infiniteArgument = false;
5470 string params = ptrParams;
5471 string::size_type pos = 0;
5472 while (pos < params.size())
5474 // Token ?
5475 string::size_type last;
5476 switch (params[pos])
5478 case '|':
5479 case '=':
5480 case '$':
5481 case '+':
5482 if ((params[pos] == '$') || (params[pos] == '+'))
5483 countArgument++;
5484 if (params[pos] == '+')
5485 infiniteArgument = true;
5486 last = pos+1;
5487 break;
5488 default:
5489 last = params.find_first_of ("|=$+", pos);
5490 if (last == string::npos)
5491 last = params.size();
5492 break;
5495 // Add a keyword
5496 keywords.push_back (params.substr (pos, last-pos));
5497 pos = last;
5500 // Find action name
5501 string help;
5502 const CBaseAction *ab = Actions.getBaseAction (::CAction::CName (action, ptrParams));
5503 if (ab)
5504 help = CI18N::get(ab->LocalizedName);
5506 // Build a argument help
5507 string argsHelp;
5509 if (ab)
5511 // Look for each arguments
5512 uint i;
5513 for (i=0; i<keywords.size(); i++)
5515 // Look for a '$'
5516 if ((keywords[i] == "$") || (keywords[i] == "+"))
5518 // Have a "=" ?
5519 if ((i > 1) && (keywords[i-1]=="="))
5521 // Argument
5522 bool bFound = false;
5523 for (uint j=0; j<ab->Parameters.size(); j++)
5525 // Argument found
5526 if (ab->Parameters[j].Name == keywords[i-2])
5528 // Add the string
5529 if (!argsHelp.empty())
5530 argsHelp += " ";
5531 argsHelp += "<" + CI18N::get(ab->Parameters[j].LocalizedName) + ">";
5532 bFound = true;
5535 // Not found ? Warning
5536 if (!bFound)
5538 nlwarning ("Argument %s not found in command %s using action %s", keywords[i-2].c_str(), name, action);
5545 // Ugly : never deleted, but who cares ?
5546 // Command exist ?
5547 CUserCommand *currentCommand;
5548 if (CommandMap.find (name) != CommandMap.end())
5549 currentCommand = CommandMap[name];
5550 else
5552 currentCommand = new CUserCommand (name, help, argsHelp);
5553 CommandMap[name] = currentCommand;
5556 // Add keywords
5557 currentCommand->addMode (action, countArgument, infiniteArgument, keywords);
5560 NLMISC_COMMAND(doAssert, "Create an assert", "")
5562 nlassert(0);
5563 return true;
5566 NLMISC_COMMAND(dumpPosAsPrim, "ld helper : add current position to pos.primitive with the given comment", "")
5568 if (!EntitiesMngr.entity(0)) return false;
5569 std::string comment;
5570 for(uint k = 0; k < args.size(); ++k)
5572 if (k != 0) comment += " ";
5573 comment += args[k];
5575 std::string srcFile;
5576 const std::string path = "save/pos.primitive";
5577 if (CFile::fileExists(path))
5581 uint32 fileSize = CFile::getFileSize(path);
5582 srcFile.resize(fileSize);
5583 CIFile stream;
5584 stream.open(path);
5585 stream.serialBuffer((uint8 *) &srcFile[0], fileSize);
5587 catch(const NLMISC::EStream &e)
5589 nlinfo(e.what());
5590 srcFile.clear();
5593 std::string newPrim =
5594 NLMISC::toString("<CHILD TYPE=\"CPrimPoint\"> \n\
5595 <PT X=\"%f\" Y=\"%f\" Z=\"%f\"/> \n\
5596 <PROPERTY TYPE=\"string\"> \n\
5597 <NAME>class</NAME> \n\
5598 <STRING>plot</STRING> \n\
5599 </PROPERTY> \n\
5600 <PROPERTY TYPE=\"string\"> \n\
5601 <NAME>name</NAME> \n\
5602 <STRING>%s</STRING> \n\
5603 </PROPERTY> \n\
5604 </CHILD>\n", (float) EntitiesMngr.entity(0)->pos().x, (float) EntitiesMngr.entity(0)->pos().y, (float) EntitiesMngr.entity(0)->pos().z, comment.c_str());
5606 // try to append result to current file
5607 const std::string LAST_CHILD_MARKER = "</CHILD>";
5608 std::string::size_type insertPos = srcFile.rfind(LAST_CHILD_MARKER);
5609 if (insertPos != std::string::npos)
5611 insertPos += LAST_CHILD_MARKER.size();
5612 srcFile.insert(insertPos, "\n" + newPrim);
5614 else
5616 srcFile.clear();
5618 if (srcFile.empty())
5620 srcFile = "<?xml version=\"1.0\"?> \n\
5621 <PRIMITIVES VERSION=\"1\"> \n\
5622 <ROOT_PRIMITIVE TYPE=\"CPrimNode\"> \n"
5623 + newPrim
5624 + " </ROOT_PRIMITIVE> \n\
5625 </PRIMITIVES>\n";
5628 // write result
5631 COFile stream;
5632 stream.open(path);
5633 stream.serialBuffer((uint8 *) &srcFile[0], (uint)srcFile.size());
5635 catch(const NLMISC::EStream &e)
5637 nlinfo(e.what());
5639 return true;
5642 NLMISC_COMMAND(clear, "clear content of current char window", "<chat window caller id>")
5644 if (args.size() > 1) return false;
5645 CInterfaceManager *im = CInterfaceManager::getInstance();
5646 im->flushDebugWindow();
5647 CChatWindow *cw;
5648 if (args.size() == 1)
5650 cw = getChatWndMgr().getChatWindowFromCaller(dynamic_cast<CCtrlBase *>(CWidgetManager::getInstance()->getElementFromId(args[0])));
5652 else
5654 // if no chat window (or enclosed control) id is given then see if a chat window called this command
5655 cw = CChatWindow::getChatWindowLaunchingCommand();
5657 if (cw && cw->getContainer())
5659 CGroupList *gl = dynamic_cast<CGroupList *>(cw->getContainer()->getGroup("text_list"));
5660 if (gl)
5662 gl->deleteAllChildren();
5665 return true;
5668 NLMISC_COMMAND(dumpAllLoadedZones, "dump all loaded zones", "")
5670 if (!args.empty()) return false;
5671 if (Landscape)
5673 std::vector<std::string> loadedZones;
5674 Landscape->getAllZoneLoaded(loadedZones);
5675 for(uint k = 0; k < loadedZones.size(); ++k)
5677 nlwarning(loadedZones[k].c_str());
5680 else
5682 nlwarning("Landscape has no loaded zones ");
5684 return true;
5688 NLMISC_COMMAND(tickToDate, "convert a tick value into a readable ryzom time", "")
5690 if (args.size() != 1) return false;
5691 CRyzomTime rt;
5692 uint32 tick;
5693 fromString(args[0], tick);
5694 rt.updateRyzomClock(tick);
5695 CInterfaceManager *im = CInterfaceManager::getInstance();
5696 float ryTime = rt.getRyzomTime();
5697 std::string readableDate = toString("Day = %d, hour = %d:%d", rt.getRyzomDay(), (int) floorf(ryTime), (int) floorf(60.f * fmodf(ryTime, 1.f)));
5698 im->displaySystemInfo(readableDate);
5699 return true;
5703 NLMISC_COMMAND(dumpShapeMaxDist, "dump max dist for shapes", "")
5706 std::set<std::string> shapeSet;
5707 typedef CHashMultiMap<float, std::string> TShapeMap;
5708 TShapeMap shapes;
5709 const CSheetManager::TEntitySheetMap &sheets = SheetMngr.getSheets();
5710 std::vector<const CCharacterSheet::CEquipment*> equipList;
5711 for (CSheetManager::TEntitySheetMap::const_iterator it = sheets.begin(); it != sheets.end(); ++it)
5713 CCharacterSheet *cs = dynamic_cast<CCharacterSheet *>(SheetMngr.get(it->first));
5714 if (cs)
5716 equipList.clear();
5717 cs->getWholeEquipmentList(equipList);
5718 for (uint k = 0; k < equipList.size(); ++k)
5720 std::string item = toLowerAscii(equipList[k]->getItem());
5721 if (!item.empty())
5724 string ext = CFile::getExtension(item);
5725 if (ext == "shape")
5727 if (!shapeSet.count(item))
5729 UInstance inst = Scene->createInstance(item);
5730 if (!inst.empty())
5732 shapes.insert(make_pair(inst.getDistMax(), item));
5733 Scene->deleteInstance(inst);
5735 shapeSet.insert(item);
5742 for (TShapeMap::iterator it = shapes.begin(); it != shapes.end(); ++it)
5744 nlwarning("Dist = %f, shape = %s", it->first, it->second.c_str());
5747 return true;
5751 NLMISC_COMMAND(dumpContinentCorners, "dump max dist for shapes", "")
5753 if (!args.empty()) return false;
5754 if (!ContinentMngr.cur()) return false;
5756 CVector2f posMin;
5757 CVector2f posMax;
5758 getPosFromZoneName(ContinentMngr.cur()->ZoneMin, posMin);
5759 getPosFromZoneName(ContinentMngr.cur()->ZoneMax, posMax);
5760 if (posMin.x > posMax.x) std::swap(posMin.x, posMax.x);
5761 if (posMin.y > posMax.y) std::swap(posMin.y, posMax.y);
5762 posMax.x += 160.f;
5763 posMax.y += 160.f;
5764 nlwarning("min = (%f, %f), max = (%f, %f)", posMin.x, posMin.y, posMax.x, posMax.y);
5765 return true;
5769 #if !FINAL_VERSION
5770 NLMISC_COMMAND(setMission, "locally set a mission text for test", "<mission index><text>")
5772 if (!ClientCfg.Local) return false;
5773 if (args.size() != 2) return false;
5774 uint index;
5775 fromString(args[0], index);
5776 CInterfaceManager *im = CInterfaceManager::getInstance();
5777 static sint32 strID = 10000; // any abitrary string id will do in local
5778 if (index >= 30) return false;
5779 if (index < 15)
5781 NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:MISSIONS:%d:TITLE", (int) index))->setValue32(strID);
5782 NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:MISSIONS:%d:FINISHED", (int) index))->setValue32(0);
5784 else
5786 NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:GROUP:MISSIONS:%d:TITLE", (int) index - 15))->setValue32(strID);
5787 NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:GROUP:MISSIONS:%d:FINISHED", (int) index - 15))->setValue32(0);
5789 setDynString(strID++, args[1]);
5790 return true;
5793 static bool setMissionStep(uint missionIndex, uint stepIndex, uint32 strID)
5795 CInterfaceManager *im = CInterfaceManager::getInstance();
5796 if (stepIndex >= 30) return false;
5797 if (stepIndex >= 20) return false;
5798 if (missionIndex < 15)
5800 NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:MISSIONS:%d:GOALS:%d:TEXT", (int) missionIndex, (int) stepIndex))->setValue32(strID);
5802 else
5804 NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:GROUP:MISSIONS:%d:GOALS:%d:TEXT", (int) (missionIndex - 15), (int) stepIndex))->setValue32(strID);
5806 return true;
5810 // add a new step in a mission, the mission must already exist
5811 NLMISC_COMMAND(setMissionStep, "locally set a mission step for test", "<mission index><step index><text>")
5813 if (!ClientCfg.Local) return false;
5814 if (args.size() != 3) return false;
5815 uint missionIndex;
5816 fromString(args[0], missionIndex);
5817 uint stepIndex;
5818 fromString(args[1], stepIndex);
5820 static sint32 strID = 20000; // any abitrary string id will do in local
5821 if (!setMissionStep(missionIndex, stepIndex, strID)) return false;
5822 setDynString(strID++, args[2]);
5823 return true;
5826 // add a newstepin a mission, the mission must already exist
5827 NLMISC_COMMAND(clearMissionStep, "locally set a mission step for test", "<mission index><step index><text>")
5829 if (!ClientCfg.Local) return false;
5830 if (args.size() != 2) return false;
5831 uint missionIndex;
5832 fromString(args[0], missionIndex);
5833 uint stepIndex;
5834 fromString(args[1], stepIndex);
5835 return setMissionStep(missionIndex, stepIndex, 0);
5839 #endif
5842 #if !FINAL_VERSION
5843 static bool debugSetMissionState(uint index, sint32 /* state */)
5845 if (index >= 30) return false;
5846 CInterfaceManager *im = CInterfaceManager::getInstance();
5847 if (index < 15)
5849 NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:MISSIONS:%d:TITLE", (int) index))->setValue32(0);
5851 else
5853 NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:GROUP:MISSIONS:%d:TITLE", (int) index - 15))->setValue32(0);
5855 return true;
5857 #endif
5860 #if !FINAL_VERSION
5861 NLMISC_COMMAND(clearMission, "clear the content of a mission", "<mission index>")
5863 if (!ClientCfg.Local) return false;
5864 if (args.size() != 1) return false;
5865 uint index;
5866 fromString(args[0], index);
5867 return debugSetMissionState(index, 0);
5870 #endif
5872 #if !FINAL_VERSION
5873 NLMISC_COMMAND(finishMission, "clear the content of a mission", "<mission index>")
5875 if (!ClientCfg.Local) return false;
5876 if (args.size() != 1) return false;
5877 uint index;
5878 fromString(args[0], index);
5879 return debugSetMissionState(index, 1);
5881 #endif
5883 #if !FINAL_VERSION
5884 NLMISC_COMMAND(failMission, "clear the content of a mission", "<mission index>")
5886 if (!ClientCfg.Local) return false;
5887 if (args.size() != 1) return false;
5888 uint index;
5889 fromString(args[0], index);
5890 return debugSetMissionState(index, 2);
5892 #endif
5895 // ***************************************************************************
5898 NLMISC_COMMAND (url, "launch a browser to the specified url", "<url>")
5900 if (args.size () != 1)
5901 return false;
5903 return openURL(args[0]);
5907 NLMISC_COMMAND(em, "emote command", "<emote phrase>")
5909 if (args.size() < 1) return false;
5911 CInterfaceManager *pIM = CInterfaceManager::getInstance();
5912 if( pIM )
5914 string emotePhrase;
5915 if (!args.empty())
5917 emotePhrase = args[0];
5919 for(uint i = 1; i < args.size(); ++i )
5921 emotePhrase += " ";
5922 emotePhrase += args[i];
5924 CAHManager::getInstance()->runActionHandler("emote", NULL, "nb=0|behav=255|custom_phrase="+emotePhrase);
5925 return true;
5927 return false;
5933 NLMISC_COMMAND(guildmotd, "Set or see the guild message of the day","<msg of the day>")
5935 CBitMemStream out;
5936 if (!GenericMsgHeaderMngr.pushNameToStream("COMMAND:GUILDMOTD", out))
5937 return false;
5939 string gmotd;
5940 if (!args.empty())
5942 gmotd = args[0];
5944 for(uint i = 1; i < args.size(); ++i )
5946 gmotd += " ";
5947 gmotd += args[i];
5950 out.serial (gmotd);
5951 NetMngr.push (out);
5953 return true;
5957 NLMISC_COMMAND(time, "Shows information about the current time", "")
5959 const uint8 size = 50;
5960 char cs_local[size];
5961 char cs_utc[size];
5962 time_t date;
5963 time(&date);
5964 struct tm *tm;
5965 tm = localtime(&date);
5966 strftime(cs_local, size, "%X", tm);
5967 tm = gmtime(&date);
5968 strftime(cs_utc, size, "%X", tm);
5970 string msg = CI18N::get("uiCurrentLocalAndUtcTime");
5971 strFindReplace(msg, "%local", cs_local);
5972 strFindReplace(msg, "%utc", cs_utc);
5973 CInterfaceManager::getInstance()->displaySystemInfo(msg, "AROUND");
5974 return true;
5977 NLMISC_COMMAND(playedTime, "Display character played time", "")
5979 string msg = CI18N::get("uiPlayedTime");
5980 strFindReplace(msg, "%time", NLMISC::secondsToHumanReadable(CharPlayedTime));
5981 CInterfaceManager::getInstance()->displaySystemInfo(msg, "AROUND");
5982 return true;
5985 NLMISC_COMMAND(version, "Display client version", "")
5987 string msg = getDebugVersion();
5988 CInterfaceManager::getInstance()->displaySystemInfo(msg, "AROUND");
5989 return true;