Resolve "Toggle Free Look with Hotkey"
[ryzomcore.git] / ryzom / client / src / commands.cpp
blob5cb45d9170a4bf6a27959bd35b0600ba46b1fe92
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;
391 NLMISC_COMMAND(freeHands, "free hands !", "")
393 std::string handPath = "LOCAL:INVENTORY:HAND:";
394 uint32 i;
395 for (i = 0; i < MAX_HANDINV_ENTRIES; ++i)
397 CInventoryManager::getInstance()->unequip(handPath + NLMISC::toString(i));
399 return true;
402 NLMISC_COMMAND(afk, "Set the player as 'away from keyboard'","[<custom text>]")
404 string customText;
405 if (!args.empty())
407 customText = args[0];
409 for(uint i = 1; i < args.size(); ++i )
411 customText += " ";
412 customText += args[i];
415 if (UserEntity != NULL)
416 UserEntity->setAFK(true,customText);
418 CBitMemStream out;
419 if(!GenericMsgHeaderMngr.pushNameToStream("DEBUG:AFK", out))
421 nlwarning("Unknown message name DEBUG:AFK");
422 return false;
424 NetMngr.push(out);
426 return true;
429 NLMISC_COMMAND(selfkill, "Kill the player ","")
431 CBitMemStream out;
432 if(!GenericMsgHeaderMngr.pushNameToStream("COMMAND:SELFKILL", out))
434 nlwarning("Unknown message name COMMAND:SELFKILL");
435 return false;
437 NetMngr.push(out);
438 return true;
441 bool randomCheckCharset(std::string const& str)
443 std::string::const_iterator it, itEnd = str.end();
444 for (it=str.begin(); it!=itEnd; ++it)
445 if (*it<'0' || *it>'9')
446 return false;
447 return true;
450 // returns true if a<=b
451 bool randomLexicographicLess(std::string a, std::string b)
453 // Remove leading zeros
454 while (a.length()>1 && a[0]=='0')
455 a = a.substr(1);
456 while (b.length()>1 && b[0]=='0')
457 b = b.substr(1);
458 // Longest is the biggest
459 if (a.length()>b.length())
460 return false;
461 if (a.length()<b.length())
462 return true;
463 // Skip equal characters
464 size_t i = 0;
465 while (i<a.length() && a[i]==b[i])
466 ++i;
467 // If all characters are equal a==b
468 if (i==a.length())
469 return false;
470 // Check highest weight different character
471 return a[i] < b[i];
474 bool randomFromString(std::string const& str, sint16& val, sint16 min = -32768, sint16 max = 32767)
476 bool negative = str[0]=='-';
477 std::string sAbsVal = str.substr(negative?1:0);
478 // Check we have only numerical characters
479 if (!randomCheckCharset(sAbsVal))
480 return false;
481 // Check sign
482 if (negative && min>0) return false;
483 if (!negative && max<0) return false;
484 // Check number is not too big nor too small with a lexicographic compare
485 std::string smin = NLMISC::toString(std::max<sint16>(min,-min));
486 std::string smax = NLMISC::toString(std::max<sint16>(max,-max));
487 bool tooSmall = false, tooBig = false;
488 if (min>=0 && randomLexicographicLess(sAbsVal, smin))
489 tooSmall = true;
490 if (min<0 && randomLexicographicLess(smin, sAbsVal))
491 tooSmall = true;
492 if (max>=0 && randomLexicographicLess(smax, sAbsVal))
493 tooBig = true;
494 if (max<0 && randomLexicographicLess(sAbsVal, smax))
495 tooBig = true;
496 if (!tooSmall && !tooBig)
498 NLMISC::fromString(str, val);
499 return true;
501 else
502 return false;
505 NLMISC_COMMAND(random, "Roll a dice and say the result around","[<min>] <max> [h|ide]")
507 // Check parameters.
508 if (args.size() < 1 || args.size() > 3)
509 return false;
511 sint16 min = 1;
512 sint16 max;
514 bool hide = args[args.size()-1][0] == 'h';
516 if (!randomFromString(args[0], max))
518 CInterfaceManager *pIM = CInterfaceManager::getInstance();
519 string msg = CI18N::get("uiRandomBadParameter");
520 strFindReplace(msg, "%s", args[0] );
521 pIM->displaySystemInfo(msg);
522 return false;
524 if (args.size() > 1 && args[1][0] != 'h')
526 if (!randomFromString(args[1], min))
528 CInterfaceManager *pIM = CInterfaceManager::getInstance();
529 string msg = CI18N::get("uiRandomBadParameter");
530 strFindReplace(msg, "%s", args[1] );
531 pIM->displaySystemInfo(msg);
532 return false;
535 if (min>max)
536 std::swap(min, max);
538 if (UserEntity != NULL)
539 UserEntity->rollDice(min, max, hide);
541 return true;
544 //-----------------------------------------------
545 // 'dumpShapePos' : Dump Last Added Shape Pos
546 //-----------------------------------------------
547 NLMISC_COMMAND(dumpShapePos, "Dump Last Added Shape Pos.", "")
549 #if FINAL_VERSION
550 if (!hasPrivilegeDEV() &&
551 !hasPrivilegeSGM() &&
552 !hasPrivilegeGM() &&
553 !hasPrivilegeVG() &&
554 !hasPrivilegeSG() &&
555 !hasPrivilegeG() &&
556 !hasPrivilegeEM() &&
557 !hasPrivilegeEG())
558 return true;
559 #endif // FINAL_VERSION
561 if (ShapeAddedByCommand.empty())
563 nlwarning("No shape created yet");
564 return false;
567 CInterfaceManager *IM = CInterfaceManager::getInstance();
568 CVector pos = ShapeAddedByCommand.back().getPos();
569 IM->displaySystemInfo(toString("Shape Pos = %f, %f, %f", pos.x, pos.y, pos.z));
570 return true;
572 //-----------------------------------------------
573 // 'clearShape' : Remove all shapes added with the 'shape' command
574 //-----------------------------------------------
575 NLMISC_COMMAND(clearShape, "Remove all shapes added with the 'shape' command.", "")
577 #if FINAL_VERSION
578 /*if (!hasPrivilegeDEV() &&
579 !hasPrivilegeSGM() &&
580 !hasPrivilegeGM() &&
581 !hasPrivilegeVG() &&
582 !hasPrivilegeSG() &&
583 !hasPrivilegeG() &&
584 !hasPrivilegeEM() &&
585 !hasPrivilegeEG())
586 return true;*/
587 #endif // FINAL_VERSION
589 if (ShapeAddedByCommand.empty())
591 nlwarning("No shape created yet");
592 return false;
595 if (!Scene) return false;
596 for(uint k = 0; k < ShapeAddedByCommand.size(); ++k)
598 Scene->deleteInstance(ShapeAddedByCommand[k]);
600 ShapeAddedByCommand.clear();
601 return true;
604 //-----------------------------------------------------
605 // 'setShapeX' : Set X position for last created shape
606 //-----------------------------------------------------
607 NLMISC_COMMAND(setShapeX, "Set X position for last created shape.", "<x coordinate>")
609 #if FINAL_VERSION
610 /*if (!hasPrivilegeDEV() &&
611 !hasPrivilegeSGM() &&
612 !hasPrivilegeGM() &&
613 !hasPrivilegeVG() &&
614 !hasPrivilegeSG() &&
615 !hasPrivilegeG() &&
616 !hasPrivilegeEM() &&
617 !hasPrivilegeEG())
618 return true;*/
619 #endif // FINAL_VERSION
621 if (args.size() != 1) return false;
622 if (ShapeAddedByCommand.empty())
624 nlwarning("No shape created yet");
625 return false;
627 float coord;
628 bool valid_coord;
629 if (args[0][0] == '+')
630 valid_coord = fromString(args[0].substr(1), coord);
631 else
632 valid_coord = fromString(args[0], coord);
634 if (!valid_coord)
636 nlwarning("Can't get position");
637 return false;
639 CVector pos = ShapeAddedByCommand.back().getPos();
640 if (args[0][0] == '+')
641 pos.x += coord;
642 else
643 pos.x = coord;
644 ShapeAddedByCommand.back().setPos(pos);
645 return true;
648 //-----------------------------------------------------
649 // 'setShapeY' : Set Y position for last created shape
650 //-----------------------------------------------------
651 NLMISC_COMMAND(setShapeY, "Set Y position for last created shape.", "<y coordinate>")
653 #if FINAL_VERSION
654 /*if (!hasPrivilegeDEV() &&
655 !hasPrivilegeSGM() &&
656 !hasPrivilegeGM() &&
657 !hasPrivilegeVG() &&
658 !hasPrivilegeSG() &&
659 !hasPrivilegeG() &&
660 !hasPrivilegeEM() &&
661 !hasPrivilegeEG())
662 return true;*/
663 #endif // FINAL_VERSION
665 if (args.size() != 1) return false;
666 if (ShapeAddedByCommand.empty())
668 nlwarning("No shape created yet");
669 return false;
671 float coord;
672 bool valid_coord;
673 if (args[0][0] == '+')
674 valid_coord = fromString(args[0].substr(1), coord);
675 else
676 valid_coord = fromString(args[0], coord);
678 if (!valid_coord)
680 nlwarning("Can't get position");
681 return false;
683 CVector pos = ShapeAddedByCommand.back().getPos();
684 if (args[0][0] == '+')
685 pos.y += coord;
686 else
687 pos.y = coord;
688 ShapeAddedByCommand.back().setPos(pos);
689 return true;
692 //-----------------------------------------------------
693 // 'setShapeZ' : Set Z position for last created shape
694 //-----------------------------------------------------
695 NLMISC_COMMAND(setShapeZ, "Set Z position for last created shape.", "<z coordinate>")
697 #if FINAL_VERSION
698 /*if (!hasPrivilegeDEV() &&
699 !hasPrivilegeSGM() &&
700 !hasPrivilegeGM() &&
701 !hasPrivilegeVG() &&
702 !hasPrivilegeSG() &&
703 !hasPrivilegeG() &&
704 !hasPrivilegeEM() &&
705 !hasPrivilegeEG())
706 return true;*/
707 #endif // FINAL_VERSION
709 if (args.size() != 1) return false;
710 if (ShapeAddedByCommand.empty())
712 nlwarning("No shape created yet");
713 return false;
715 float coord;
716 bool valid_coord;
717 if (args[0][0] == '+')
718 valid_coord = fromString(args[0].substr(1), coord);
719 else
720 valid_coord = fromString(args[0], coord);
722 if (!valid_coord)
724 nlwarning("Can't get position");
725 return false;
727 CVector pos = ShapeAddedByCommand.back().getPos();
728 if (args[0][0] == '+')
729 pos.z += coord;
730 else
731 pos.z = coord;
732 ShapeAddedByCommand.back().setPos(pos);
733 return true;
737 //-----------------------------------------------------
738 // 'setShapeDir' : Set direction angle for last created shape
739 //-----------------------------------------------------
740 NLMISC_COMMAND(setShapeDir, "Set direction angle for last created shape.", "<angle>")
742 #if FINAL_VERSION
743 /*if (!hasPrivilegeDEV() &&
744 !hasPrivilegeSGM() &&
745 !hasPrivilegeGM() &&
746 !hasPrivilegeVG() &&
747 !hasPrivilegeSG() &&
748 !hasPrivilegeG() &&
749 !hasPrivilegeEM() &&
750 !hasPrivilegeEG())
751 return true;*/
752 #endif // FINAL_VERSION
754 if (args.size() != 1) return false;
755 if (ShapeAddedByCommand.empty())
757 nlwarning("No shape created yet");
758 return false;
760 float angle;
761 if (!fromString(args[0], angle))
763 nlwarning("Can't get angle");
764 return false;
767 CMatrix dir;
768 dir.identity();
769 CVector vangle = CVector(sin(angle), cos(angle), 0.f);
770 CVector vi = vangle^CVector(0.f, 0.f, 1.f);
771 CVector vk = vi^vangle;
772 dir.setRot(vi, vangle, vk, true);
773 // Set Orientation : User Direction should be normalized.
774 ShapeAddedByCommand.back().setRotQuat(dir.getRot());
776 return true;
780 //-----------------------------------------------
781 // 'shape' : Add a shape in the scene.
782 //-----------------------------------------------
783 NLMISC_COMMAND(shape, "Add a shape in the scene.", "<shape file>")
785 #if FINAL_VERSION
786 /* if (!hasPrivilegeDEV() &&
787 !hasPrivilegeSGM() &&
788 !hasPrivilegeGM() &&
789 !hasPrivilegeVG() &&
790 !hasPrivilegeSG() &&
791 !hasPrivilegeG() &&
792 !hasPrivilegeEM() &&
793 !hasPrivilegeEG())
794 return true;*/
795 #endif // FINAL_VERSION
797 if(args.size() < 1)
799 nlwarning("Command 'shape': need at least 1 parameter, try '/help shape' for more details.");
800 return false;
802 if (!Scene)
804 nlwarning("No scene available");
805 return false;
807 UInstance instance = Scene->createInstance(args[0]);
808 if(!instance.empty())
810 ShapeAddedByCommand.push_back(instance);
811 // Set the position
812 instance.setPos(UserEntity->pos());
813 instance.setClusterSystem(UserEntity->getClusterSystem()); // for simplicity, assume it is in the same
814 // cluster system than the user
815 // Compute the direction Matrix
816 CMatrix dir;
817 dir.identity();
818 CVector vi = UserEntity->dir()^CVector(0.f, 0.f, 1.f);
819 CVector vk = vi^UserEntity->dir();
820 dir.setRot(vi, UserEntity->dir(), vk, true);
821 // Set Orientation : User Direction should be normalized.
822 instance.setRotQuat(dir.getRot());
823 // if the shape is a particle system, additionnal parameters are user params
824 UParticleSystemInstance psi;
825 psi.cast (instance);
826 if (!psi.empty())
828 // set each user param that is present
829 for(uint k = 0; k < 4; ++k)
831 if (args.size() >= (k + 2))
833 float uparam;
834 if (fromString(args[k + 1], uparam))
836 psi.setUserParam(k, uparam);
838 else
840 nlwarning("Cant read param %d", k);
846 else
848 nlwarning("Command 'shape': cannot find the shape %s.", args[0].c_str());
851 // Command Well Done
852 return true;
855 NLMISC_COMMAND(bugReport, "Call the bug report tool with dump", "<AddScreenshot>")
857 const char *brname[] = { "bug_report.exe", "bug_report_r.exe", "bug_report_rd.exe", "bug_report_df.exe", "bug_report_d.exe" };
859 string brn;
861 for (uint i = 0; i < sizeof(brname)/sizeof(brname[0]); i++)
863 if (CFile::fileExists (brname[i]))
865 brn = brname[i];
866 break;
870 if (brn.empty())
872 log.displayNL("bug_report*.exe not found");
873 return false;
876 string sys;
878 sys = "Language "+CI18N::getCurrentLanguageName() +" ";
880 if (!args.empty())
882 uint8 quality;
883 fromString(args[0], quality);
884 if (quality == 0)
885 quality = 80;
887 CBitmap btm;
888 Driver->getBuffer(btm);
889 string filename = CFile::findNewFile (getLogDirectory() + "screenshot.jpg");
890 COFile fs(filename);
891 btm.writeJPG(fs, quality);
892 sys += "AttachedFile "+filename+" ";
895 sys += NLMISC::toString("ClientVersion %s ", getVersion().c_str());
897 // for now, set the same version than client one
898 sys += NLMISC::toString("ShardVersion %s ", getVersion().c_str());
900 if (ClientCfg.Local)
901 sys += "ShardName OFFLINE ";
903 FILE *fp = nlfopen (getLogDirectory() + "bug_report.txt", "wb");
904 if (fp != NULL)
906 string res = addSlashR(getDebugInformation());
908 // must put \r\n each line
909 fprintf(fp, "%s", res.c_str());
911 // // must put \r\n each line
912 // fprintf (fp, "UserId: %u\r\n", NetMngr.getUserId());
913 // fprintf (fp, "Player Name: '%s'.\r\n", UserEntity->getName().toString().c_str());
914 // fprintf (fp, "UserPosition: %.2f %.2f %.2f\r\n", UserEntity->pos().x, UserEntity->pos().y, UserEntity->pos().z);
915 // fprintf (fp, "ViewPosition: %.2f %.2f %.2f\r\n", View.viewPos().x, View.viewPos().y, View.viewPos().z);
916 // time_t ts; time( &ts );
917 // fprintf (fp, "LocalTime: %s\r\n", NLMISC::IDisplayer::dateToHumanString( ts ) );
918 // fprintf (fp, "ServerTick: %u\r\n", NetMngr.getCurrentServerTick());
919 // fprintf (fp, "ConnectState: %s\r\n", NetMngr.getConnectionStateCStr());
920 // fprintf (fp, "LocalAddress: %s\r\n", NetMngr.getAddress().asString().c_str());
922 fclose (fp);
924 sys += "DumpFilename bug_report.txt ";
927 nlinfo ("Calling for bug report : '%s %s'", brn.c_str(), sys.c_str());
929 launchProgram(brn, sys);
931 // give some cpu to the launched application
932 nlSleep (3000);
934 return true;
939 // This command is use to do all admin execution commands on you
941 // For example: "/a God 1" will set you in god mode
944 NLMISC_COMMAND(a, "Execute an admin command on you","<cmd> <arg>")
946 if(args.empty())
947 return false;
949 CBitMemStream out;
950 if (!GenericMsgHeaderMngr.pushNameToStream("COMMAND:ADMIN", out))
951 return false;
953 string cmd, arg;
954 cmd = args[0];
955 for (uint i = 1; i < args.size(); i++)
957 std::string tmp = args[i];
959 if (!arg.empty())
960 arg += ' ';
961 if (tmp.find(' ') != std::string::npos)
963 arg += "\"" + tmp + "\"";
965 else
967 arg += tmp;
970 bool onTarget = false;
971 out.serial (onTarget);
972 out.serial (cmd);
973 out.serial (arg);
974 NetMngr.push (out);
976 return true;
981 // This command is use to do all admin execution commands on the target
983 // For example: "/b God 1" will set the target in god mod
986 NLMISC_COMMAND(b, "Execute an admin command on your target","<cmd> <arg>")
988 if(args.empty())
989 return false;
991 CBitMemStream out;
992 if (!GenericMsgHeaderMngr.pushNameToStream("COMMAND:ADMIN", out))
993 return false;
995 string cmd, arg;
996 cmd = args[0];
997 for (uint i = 1; i < args.size(); i++)
999 std::string tmp = args[i];
1001 if (!arg.empty())
1002 arg += ' ';
1003 if (tmp.find(' ') != std::string::npos)
1005 arg += "\"" + tmp + "\"";
1007 else
1009 arg += tmp;
1012 bool onTarget = true;
1013 out.serial (onTarget);
1014 out.serial (cmd);
1015 out.serial (arg);
1016 NetMngr.push (out);
1018 return true;
1023 // This command is used to do all admin execution commands on a character
1025 // For example: "/c charName God 1" will set god mod on character if it's online, or keep
1026 // command for wait character login
1029 NLMISC_COMMAND(c, "Execute an admin command on character name","<Character Name> <cmd> <arg>")
1031 if(args.size() < 2)
1032 return false;
1034 CBitMemStream out;
1035 if (!GenericMsgHeaderMngr.pushNameToStream("COMMAND:ADMIN_OFFLINE", out))
1036 return false;
1038 string characterName, cmd, arg;
1040 characterName = args[0];
1041 cmd = args[1];
1042 for (uint i = 2; i < args.size(); i++)
1044 std::string tmp = args[i];
1046 if (!arg.empty())
1047 arg += ' ';
1048 if (tmp.find(' ') != std::string::npos)
1050 arg += "\"" + tmp + "\"";
1052 else
1054 arg += tmp;
1057 out.serial (characterName);
1058 out.serial (cmd);
1059 out.serial (arg);
1060 NetMngr.push (out);
1062 return true;
1065 NLMISC_COMMAND(boxes, "Show/Hide selection boxes", "[<state> : 0 to Hide, anything else to Show. Invert the current state if nothing specified.]")
1067 #if FINAL_VERSION
1068 if (!ClientCfg.ExtendedCommands) return false;
1070 if( !ClientCfg.Local && !hasPrivilegeDEV() && !hasPrivilegeSGM() && !hasPrivilegeGM() )
1071 return true;
1072 #endif // FINAL_VERSION
1074 // Invert Current State
1075 if(args.empty())
1077 // Invert the current value.
1078 ClientCfg.DrawBoxes = !ClientCfg.DrawBoxes;
1079 return true;
1081 // Set Current State
1082 else if(args.size() == 1)
1084 // Invert the current value.
1085 fromString(args[0], ClientCfg.DrawBoxes);
1086 return true;
1088 // Bad parameters.
1089 else
1090 return false;
1093 NLMISC_COMMAND(dump, "Command to create a file with the current state of the client", "[<dump name>]")
1095 if(args.size() > 1)
1096 return false;
1098 string dumpName;
1099 if(args.size() == 1)
1100 dumpName = args[0];
1101 else
1102 dumpName = "default";
1104 dump(dumpName);
1105 return true;
1108 NLMISC_COMMAND(verbose, "Enable/Disable some Debug Information", "none or magic")
1110 // Check parameters.
1111 if(args.size() != 1)
1113 // Help
1114 CInterfaceManager *IM = CInterfaceManager::getInstance();
1115 IM->displaySystemInfo("This command need 1 parameter :");
1116 IM->displaySystemInfo("<string> :");
1117 IM->displaySystemInfo("- none(to remove all verboses)");
1118 IM->displaySystemInfo("- magic(to add debug infos about magic)");
1119 IM->displaySystemInfo("- anim (to add debug infos about animation)");
1121 else
1123 std::string type = NLMISC::toLowerAscii(args[0]);
1124 if (type == "none")
1125 Verbose = VerboseNone;
1126 else if(type == "magic")
1127 Verbose |= VerboseMagic;
1128 else if(type == "anim")
1129 Verbose |= VerboseAnim;
1130 else
1132 CInterfaceManager *IM = CInterfaceManager::getInstance();
1133 IM->displaySystemInfo("This command need 1 parameter :");
1134 IM->displaySystemInfo("<string> :");
1135 IM->displaySystemInfo("- none(to remove all verboses)");
1136 IM->displaySystemInfo("- magic(to add debug infos about magic)");
1137 IM->displaySystemInfo("- anim (to add debug infos about animation)");
1140 return true;
1143 NLMISC_COMMAND(verboseAnimSelection, "Enable/Disable the animation log for the current selection", "")
1145 // Check parameters.
1146 if(args.size() != 0)
1147 return false;
1149 VerboseAnimSelection = !VerboseAnimSelection;
1150 if(VerboseAnimSelection)
1151 nlinfo("Enable VerboseAnimSelection");
1152 else
1153 nlinfo("Disable VerboseAnimSelection");
1155 return true;
1158 NLMISC_COMMAND(verboseAnimUser, "Enable/Disable the animation log for the user", "")
1160 // Check parameters.
1161 if(args.size() != 0)
1162 return false;
1164 VerboseAnimUser = !VerboseAnimUser;
1165 if(VerboseAnimUser)
1166 nlinfo("Enable VerboseAnimUser");
1167 else
1168 nlinfo("Disable VerboseAnimUser");
1170 return true;
1173 NLMISC_COMMAND(verboseDatabase, "Enable/Disable the log for the database", "")
1175 // Check parameters.
1176 if(args.size() != 0)
1177 return false;
1179 bool v = NLMISC::ICDBNode::isDatabaseVerbose();
1180 NLMISC::ICDBNode::setVerboseDatabase( !v );
1182 if( !v )
1183 nlinfo("Enable VerboseDatabase");
1184 else
1185 nlinfo("Disable VerboseDatabase");
1187 return true;
1190 NLMISC_COMMAND(verbosePropertiesLoggingMode, "Set logging mode", "")
1192 // Check parameters.
1193 if(args.size() != 0)
1194 return false;
1196 CNetworkConnection::LoggingMode = !CNetworkConnection::LoggingMode;
1197 if(CNetworkConnection::LoggingMode)
1198 nlinfo("Enable LoggingMode");
1199 else
1200 nlinfo("Disable LoggingMode");
1202 return true;
1205 NLMISC_COMMAND(logEntities, "Write the position and orientation af all entities in the vision in the file 'entities.txt'", "")
1207 // Check parameters
1208 if(args.size() != 0)
1209 return false;
1211 // Log entities
1212 EntitiesMngr.writeEntities();
1214 // Command well done.
1215 return true;
1218 NLMISC_COMMAND(log, "Add/Del Positive/Negative Filters for logs", "Log System <debug, info, warning, assert>, Type <pos/neg/del/reset>, Filter <string>")
1220 // check args, if there s not the right number of parameter, return bad
1221 if(args.size() < 2 || args.size() > 3)
1222 return false;
1224 CLog *logSys;
1225 // Debug log system.
1226 if (string(args[0].c_str()) == "debug")
1227 logSys = DebugLog;
1228 // Info log system.
1229 else if(string(args[0].c_str()) == "info")
1230 logSys = InfoLog;
1231 // Warning log system.
1232 else if(string(args[0].c_str()) == "warning")
1233 logSys = WarningLog;
1234 // Assert log system.
1235 else if(string(args[0].c_str()) == "assert")
1236 logSys = AssertLog;
1237 // Unknown Log System -> return false.
1238 else
1239 return false;
1241 // Add a positive filter.
1242 if (string(args[1].c_str()) == "pos")
1243 logSys->addPositiveFilter(args[2].c_str());
1244 // Add a negative filter.
1245 else if(string(args[1].c_str()) == "neg")
1246 logSys->addNegativeFilter(args[2].c_str());
1247 // Removes a filter by name (in both filters).
1248 else if(string(args[1].c_str()) == "del")
1249 logSys->removeFilter(args[2].c_str());
1250 // Reset both filters.
1251 else if(string(args[1].c_str()) == "reset")
1252 logSys->resetFilters();
1253 // Unknown Filter -> return false.
1254 else
1255 return false;
1257 // Command well done.
1258 return true;
1261 NLMISC_COMMAND(execScript, "Execute a script file (.cmd)","<FileName>")
1263 int size = (int)args.size();
1264 if (size != 1)
1265 return false;
1267 CIFile iFile;
1269 if (iFile.open(CPath::lookup(args[0], false)))
1271 char line[512];
1272 char *buffer;
1273 // Read line by line and execute each line
1275 sint inComment= 0;
1276 bool eof = false;
1277 while (!eof)
1279 buffer = &line[0];
1280 uint read = 0;
1281 for(;;)
1283 if (read == 512 -1)
1285 *buffer = '\0';
1286 break;
1291 // read one byte
1292 iFile.serialBuffer ((uint8 *)buffer, 1);
1294 catch (const EFile &)
1296 *buffer = '\0';
1297 eof = true;
1298 break;
1301 if (*buffer == '\n')
1303 *buffer = '\0';
1304 break;
1307 // skip '\r' char
1308 if (*buffer != '\r')
1310 buffer++;
1311 read++;
1315 // execute line
1316 if (strlen(line) > 0)
1318 // if not a single comment
1319 if(strncmp(line, "//", 2)!=0)
1321 if(strncmp(line, "/*", 2)==0)
1322 inComment++;
1323 if(inComment<=0)
1325 string ucline(line);
1326 CInterfaceManager::parseTokens(ucline);
1327 ICommand::execute(ucline, g_log);
1329 if(strncmp(line, "*/", 2)==0)
1330 inComment--;
1334 // end?
1335 if (iFile.eof())
1336 eof = true;
1338 iFile.close();
1340 else
1342 CInterfaceManager::getInstance()->displaySystemInfo("Cannot open file");
1345 return true;
1349 NLMISC_COMMAND(db, "Modify Database","<Property> <Value>")
1351 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1352 int size = (int)args.size();
1353 if (size == 2)
1355 #if !FINAL_VERSION
1356 // check if 2nd arg is a sheet name
1357 if (args[1].empty()) return false;
1358 sint64 value;
1359 if (isalpha(args[1][0]))
1361 CSheetId sheet(args[1]);
1362 value = (sint64) sheet.asInt();
1364 else
1366 // Convert the string into an sint64.
1367 fromString(args[1], value);
1370 // Set the property.
1371 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(args[0], false);
1372 if(node)
1373 node->setValue64(value);
1374 else
1375 pIM->displaySystemInfo(toString("DB '%s' does not exist.", args[0].c_str()));
1376 #else
1377 pIM->displaySystemInfo("Can't write to DB when in Final Version.");
1378 #endif
1380 else if (size == 1)
1382 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(args[0], false);
1383 if(node)
1385 sint64 prop = node->getValue64();
1386 string str = toString(prop);
1387 pIM->displaySystemInfo(str);
1388 nlinfo("%s", str.c_str());
1390 else
1391 pIM->displaySystemInfo(toString("DB '%s' does not exist.", args[0].c_str()));
1392 return true;
1394 else
1395 return false;
1397 return true;
1400 NLMISC_COMMAND(setItemName, "set name of items, sbrick, etc..","<sheet_id> <name> <desc> <desc2>")
1402 if (args.size() < 2) return false;
1403 CSheetId id(args[0]);
1404 string name;
1405 name = args[1];
1406 string desc;
1407 string desc2;
1408 if (args.size() > 2)
1409 desc = args[2];
1410 if (args.size() > 3)
1411 desc2 = args[3];
1413 STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance();
1414 if (pSMC)
1415 pSMC->replaceSBrickName(id, name, desc, desc2);
1416 else
1417 return false;
1418 return true;
1422 NLMISC_COMMAND(setMissingDynstringText, "set text of missing dynamic string"," <name> <text>")
1424 if (args.size() < 2) return false;
1425 string name;
1426 name = args[0];
1427 string text;
1428 text = args[1];
1430 STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance();
1431 if (pSMC)
1432 pSMC->replaceDynString(name, text);
1433 else
1434 return false;
1435 return true;
1440 /////////////////////////////////////////////////////////////////////////////
1441 /////////////////////////////////////////////////////////////////////////////
1442 /////////////////////////////////////////////////////////////////////////////
1443 /////////////////////////////////////////////////////////////////////////////
1444 /////////// COMMANDS after should NOT appear IN the FINAL VERSION ///////////
1445 /////////////////////////////////////////////////////////////////////////////
1446 /////////////////////////////////////////////////////////////////////////////
1447 /////////////////////////////////////////////////////////////////////////////
1448 /////////////////////////////////////////////////////////////////////////////
1449 /////////////////////////////////////////////////////////////////////////////
1450 #if !FINAL_VERSION
1452 NLMISC_COMMAND(ah, "Launch an action handler", "<ActionHandler> <AHparam>")
1454 if (args.empty())
1455 return false;
1457 if (!ClientCfg.AllowDebugLua && toLowerAscii(args[0]) == "lua")
1459 return false; // not allowed!!
1462 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1463 if (args.size() == 1)
1465 CAHManager::getInstance()->runActionHandler(args[0], NULL);
1467 else
1469 CAHManager::getInstance()->runActionHandler(args[0], NULL, args[1]);
1472 return true;
1475 static void setDynString(uint32 strID, const std::string &value)
1477 STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance();
1478 pSMC->receiveString(strID, value);
1479 CBitMemStream bm;
1480 if (bm.isReading()) bm.invert();
1481 bm.serial(strID);
1482 bm.serial(strID);
1483 bm.invert();
1484 bm.seek(0, NLMISC::IStream::begin);
1485 pSMC->receiveDynString(bm);
1488 // for debug purposes, insert a string in the
1489 NLMISC_COMMAND(setDynString, "set a dynamic string","<stringID> <asciiValue>")
1491 if (args.size() != 2) return false;
1492 uint32 strID;
1493 fromString(args[0], strID);
1494 setDynString(strID, args[1]);
1495 return true;
1498 class CAnimProgress : public IProgressCallback
1500 public:
1501 // Update the progress bar
1502 virtual void progress (float value)
1504 // can't do anything if no driver
1505 if(Driver == NULL)
1506 return;
1507 // Get croped value
1508 value = getCropedValue (value);
1509 // Set matrix
1510 Driver->setMatrixMode2D11();
1511 // Display a progress bar background
1512 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,
1513 PROGRESS_BAR_BG_COLOR);
1514 // Display a progress bar
1515 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,
1516 PROGRESS_BAR_COLOR);
1517 if(TextContext != NULL)
1519 // Init the Pen.
1520 TextContext->setKeep800x600Ratio(false);
1521 TextContext->setColor(CRGBA(255,255,255));
1522 TextContext->setFontSize(20);
1523 TextContext->setHotSpot(UTextContext::MiddleMiddle);
1525 // Display the Text.
1526 TextContext->printfAt(0.5f, 0.5f, _ProgressMessage.c_str());
1528 // Display to screen.
1529 Driver->swapBuffers();
1531 // New message
1532 void newMessage(const std::string &message) {_ProgressMessage = message;}
1534 private:
1535 std::string _ProgressMessage;
1538 NLMISC_COMMAND(reloadSearchPaths, "reload the search paths","")
1540 if (!args.empty()) return false;
1541 CPath::memoryUncompress();
1542 CAnimProgress progress;
1543 // remove all objects that may depend on an animation
1544 CProjectileManager::getInstance().reset();
1546 // Pathes
1547 progress.newMessage("Reloading pathes");
1548 progress.progress(0.0f);
1549 progress.pushCropedValues(0.0f, 1.0f);
1552 addSearchPaths(progress);
1553 CPath::memoryCompress();
1554 return true;
1557 NLMISC_COMMAND(reloadAnim, "reload animations","")
1559 CPath::memoryUncompress();
1560 CAnimProgress dummy;
1561 // remove all objects that may depend on an animation
1562 CProjectileManager::getInstance().reset();
1564 // Pathes
1565 dummy.newMessage("Pathes");
1566 dummy.progress(0.0f);
1567 dummy.pushCropedValues(0.0f, 0.5f);
1570 addSearchPaths(dummy);
1572 if (ClientCfg.UpdatePackedSheet)
1574 for(uint i = 0; i < ClientCfg.UpdatePackedSheetPath.size(); i++)
1576 dummy.progress((float)i/(float)ClientCfg.UpdatePackedSheetPath.size());
1577 dummy.pushCropedValues ((float)i/(float)ClientCfg.UpdatePackedSheetPath.size(), (float)(i+1)/(float)ClientCfg.UpdatePackedSheetPath.size());
1578 CPath::addSearchPath(ClientCfg.UpdatePackedSheetPath[i], true, false, &dummy);
1579 dummy.popCropedValues();
1584 dummy.popCropedValues();
1585 // Animations
1586 dummy.newMessage("Anims");
1587 dummy.progress(0.5f);
1588 dummy.pushCropedValues(0.5f, 1.0f);
1589 EAM->load(dummy, true);
1590 dummy.popCropedValues();
1591 // Reload Animations
1592 EntitiesMngr.reloadAnims();
1593 CPath::memoryCompress();
1594 return true;
1597 NLMISC_COMMAND(reloadAttack, "reload attack", "")
1599 if (!args.empty()) return false;
1600 // remove all objects that may depend on an animation
1601 ClientSheetsStrings.memoryUncompress();
1602 CProjectileManager::getInstance().reset();
1603 EntitiesMngr.removeAllAttachedFX();
1604 FXMngr.reset();
1606 std::vector<std::string> exts;
1607 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1608 // replace attack list of creature in place (so pointers on character sheets remains valid)
1609 CSheetManager sheetManager;
1610 exts;
1611 // exts.push_back("creature");
1612 exts.push_back("race_stats");
1613 NLMISC::IProgressCallback progress;
1614 sheetManager.loadAllSheet(progress, true, false, false, true, &exts);
1616 const CSheetManager::TEntitySheetMap &sm = SheetMngr.getSheets();
1617 for(CSheetManager::TEntitySheetMap::const_iterator it = sm.begin(); it != sm.end(); ++it)
1619 if (it->second.EntitySheet && it->second.EntitySheet->Type == CEntitySheet::FAUNA)
1621 // find matching sheet in new sheetManager
1622 const CEntitySheet *other = sheetManager.get(it->first);
1623 if (other)
1625 // replace data in place
1626 ((CCharacterSheet &) *it->second.EntitySheet).AttackLists = ((const CCharacterSheet &) *other).AttackLists;
1629 else if(it->second.EntitySheet && it->second.EntitySheet->Type == CEntitySheet::RACE_STATS)
1631 // find matching sheet in new sheetManager
1632 const CEntitySheet *other = sheetManager.get(it->first);
1633 if (other)
1635 // replace data in place
1636 ((CRaceStatsSheet &) *it->second.EntitySheet).AttackLists = ((const CRaceStatsSheet &) *other).AttackLists;
1640 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1641 CAttackListManager::getInstance().release();
1642 // form to reload all sheets of interest
1643 exts.clear();
1644 exts.push_back("attack_list");
1645 exts.push_back("animation_fx_set");
1646 exts.push_back("id_to_string_array");
1647 CDummyProgress dp;
1648 SheetMngr.loadAllSheet(dp, true, false, true, true, &exts);
1649 CAttackListManager::getInstance().init();
1651 ClientSheetsStrings.memoryCompress();
1652 return true;
1655 NLMISC_COMMAND(reloadSky, "reload new style sky", "")
1657 if (!args.empty()) return false;
1658 ContinentMngr.reloadSky();
1659 return false;
1663 NLMISC_COMMAND(missionReward, "debug"," ")
1665 if (args.size() == 1)
1667 uint8 index;
1668 fromString(args[0], index);
1669 CBitMemStream out;
1670 if(GenericMsgHeaderMngr.pushNameToStream("BOTCHAT:COMPLETE_MISSION", out))
1672 out.serial(index);
1673 NetMngr.push(out);
1675 else
1676 nlwarning("<CBotChat acceptMission> : unknown message name : BOTCHAT:COMPLETE_MISSION");
1677 return true;
1679 return false;
1682 NLMISC_COMMAND(missionProgress, "debug"," ")
1684 if (args.size() == 1)
1686 uint8 index;
1687 fromString(args[0], index);
1688 CBitMemStream out;
1689 if(GenericMsgHeaderMngr.pushNameToStream("BOTCHAT:PROGRESS_MISSION", out))
1691 out.serial(index);
1692 NetMngr.push(out);
1694 else
1695 nlwarning("<CBotChat acceptMission> : unknown message name : BOTCHAT:PROGRESS_MISSION");
1696 return true;
1698 return false;
1702 NLMISC_COMMAND( displayDBModifs, "display server database modification in the chat window"," ")
1704 if ( VerboseDatabase )
1705 CInterfaceManager::getInstance()->getChatOutput()->addTextChild("the database is already in verbose mode",CRGBA(255,255,255,255));
1706 else
1708 CInterfaceManager::getInstance()->getChatOutput()->addTextChild("database is now in verbose mode",CRGBA(255,255,255,255));
1709 VerboseDatabase = true;
1711 return true;
1714 NLMISC_COMMAND( hideDBModifs, "stop displaying server database modification in the chat window"," ")
1716 if ( !VerboseDatabase )
1717 CInterfaceManager::getInstance()->getChatOutput()->addTextChild("the database is already not in verbose mode",CRGBA(255,255,255,255));
1718 else
1720 CInterfaceManager::getInstance()->getChatOutput()->addTextChild("database is not in verbose mode anymore",CRGBA(255,255,255,255));
1721 VerboseDatabase = false;
1723 return true;
1728 NLMISC_COMMAND(save_sentences, "save sentences"," ")
1730 CSentenceDisplayer::saveSentences();
1731 return true;
1735 NLMISC_COMMAND(getSheetId, "get_sheet_id","<sheet file name>")
1737 if (args.size() != 1)
1738 return false;
1739 CSheetId id(args[0]);
1741 CInterfaceManager::getInstance()->displaySystemInfo(toString(id.asInt()));
1742 return true;
1745 NLMISC_COMMAND(getSheetName, "get_sheet_name","<Sheet Id>")
1747 if (args.size() != 1)
1748 return false;
1749 uint32 nId;
1750 fromString(args[0], nId);
1751 CSheetId id( nId );
1753 string name = id.toString();
1756 CInterfaceManager::getInstance()->displaySystemInfo(name);
1757 return true;
1760 NLMISC_COMMAND(forgetAll, "forget all bricks", "")
1762 // Check parameters.
1763 if(args.size() != 0)
1765 return false;
1767 char buf[100];
1768 for (uint i = 0;i<20;i++)
1770 sprintf(buf,"SERVER:BRICK_FAMILY:%d:BRICKS",i);
1771 CCDBNodeLeaf * node= NLGUI::CDBManager::getInstance()->getDbProp(buf);
1772 node->setValue64(0);
1774 return true;
1777 NLMISC_COMMAND(usePreprogMagic, "use the specified magic preprog sentence", "<sentence id>")
1779 // Check parameters.
1780 if(args.size() != 1)
1782 return false;
1785 // Create the message for the server to execute a phrase.
1786 const string msgName = "SENTENCE:EXECUTE";
1787 CBitMemStream out;
1788 if(GenericMsgHeaderMngr.pushNameToStream("SENTENCE:EXECUTE", out))
1790 uint8 phrase;
1791 fromString(args[0], phrase);
1792 out.serial(phrase);
1794 BRICK_TYPE::EBrickType type = BRICK_TYPE::MAGIC;
1795 out.serialEnum( type );
1797 NetMngr.push(out);
1799 else
1800 nlwarning("mainLoop : unknown message name : '%s'", msgName.c_str());
1802 return true;
1805 NLMISC_COMMAND(usePreprogCombat, "use the specified combat preprog sentence", "<sentence id>")
1807 // Check parameters.
1808 if(args.size() != 1)
1810 return false;
1813 // Create the message for the server to execute a phrase.
1814 const string msgName = "SENTENCE:EXECUTE";
1815 CBitMemStream out;
1816 if(GenericMsgHeaderMngr.pushNameToStream("SENTENCE:EXECUTE", out))
1818 uint8 phrase;
1819 fromString(args[0], phrase);
1820 out.serial(phrase);
1822 BRICK_TYPE::EBrickType type = BRICK_TYPE::COMBAT;
1823 out.serialEnum( type );
1825 NetMngr.push(out);
1827 else
1828 nlwarning("mainLoop : unknown message name : '%s'", msgName.c_str());
1830 return true;
1833 NLMISC_COMMAND(engage, "engage target in combat", "")
1835 // Create the message for the server to execute a phrase.
1836 const char *msgName = "COMBAT:ENGAGE";
1837 CBitMemStream out;
1838 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
1840 NetMngr.push(out);
1842 else
1843 nlwarning("mainLoop : unknown message name : '%s'", msgName);
1845 return true;
1848 NLMISC_COMMAND(defaultAttack, "use default attack on target", "")
1850 // Default attack on the current selection.
1851 UserEntity->attack();
1853 // Well Done.
1854 return true;
1857 NLMISC_COMMAND(disengage, "disengage from combat", "")
1859 // Disengage from combat.
1860 UserEntity->disengage();
1862 // Well Done.
1863 return true;
1866 NLMISC_COMMAND(leaveTeam, "leave team", "")
1868 // Create the message for the server to execute a phrase.
1869 const char *msgName = "TEAM:LEAVE";
1870 CBitMemStream out;
1871 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
1873 NetMngr.push(out);
1875 else
1876 nlwarning("mainLoop : unknown message name : '%s'", msgName);
1878 return true;
1881 NLMISC_COMMAND(joinTeam, "join the specified team", "")
1883 // Create the message for the server to execute a phrase.
1884 const char *msgName = "TEAM:JOIN";
1885 CBitMemStream out;
1886 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
1888 NetMngr.push(out);
1890 else
1891 nlwarning("mainLoop : unknown message name : '%s'", msgName);
1893 return true;
1896 NLMISC_COMMAND(joinTeamProposal, "propose to current target to join the team", "")
1898 // Create the message for the server to execute a phrase.
1899 const char *msgName = "TEAM:JOIN_PROPOSAL";
1900 CBitMemStream out;
1901 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
1903 NetMngr.push(out);
1905 else
1906 nlwarning("mainLoop : unknown message name : '%s'", msgName);
1908 return true;
1911 NLMISC_COMMAND(joinTeamDecline, "decline a join team proposal", "")
1913 // Create the message for the server to execute a phrase.
1914 const char *msgName = "TEAM:JOIN_PROPOSAL_DECLINE";
1915 CBitMemStream out;
1916 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
1918 NetMngr.push(out);
1920 else
1921 nlwarning("mainLoop : unknown message name : '%s'", msgName);
1923 return true;
1926 NLMISC_COMMAND(kickTeammate, "kick someone from your team", "")
1928 // Create the message for the server to execute a phrase.
1929 const char *msgName = "TEAM:KICK";
1930 CBitMemStream out;
1931 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
1933 NetMngr.push(out);
1935 else
1936 nlwarning("mainLoop : unknown message name : '%s'", msgName);
1938 return true;
1941 NLMISC_COMMAND(cancelCurrentSentence, "cancel the sentence being executed", "")
1943 // no parameter needed
1945 // Create the message for the server to cancel the phrase being executed
1946 const char *msgName = "SENTENCE:CANCEL_CURRENT";
1947 CBitMemStream out;
1948 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
1950 NetMngr.push(out);
1952 else
1953 nlwarning("command : unknown message name : '%s'", msgName);
1955 return true;
1958 NLMISC_COMMAND(cancelAllPhrases, "cancel all the phrases being executed", "")
1960 // no parameter needed
1962 UserEntity->cancelAllPhrases();
1964 return true;
1969 NLMISC_COMMAND(drop,"drop an item to the ground","<id>")
1971 if( args.size() < 1 )
1973 return false;
1976 uint32 id;
1977 fromString(args[0], id);
1978 CEntityId itemId(RYZOMID::object,id);
1980 sint32 x = (sint32)UserEntity->pos().x * 1000;
1981 sint32 y = (sint32)UserEntity->pos().y * 1000;
1982 sint32 z = (sint32)UserEntity->pos().z * 1000;
1984 CBitMemStream bms;
1985 const char *msgType = "ITEM:DROP";
1986 if( GenericMsgHeaderMngr.pushNameToStream(msgType,bms) )
1988 bms.serial( itemId );
1989 bms.serial( x );
1990 bms.serial( y );
1991 bms.serial( z );
1992 NetMngr.push( bms );
1993 nldebug("<drop> sending 'ITEM:DROP' message to server");
1995 else
1997 nlwarning("<drop> unknown message name : ITEM:DROP");
2000 return true;
2006 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")
2008 CVectorD newPos;
2010 // Named destination.
2011 if(args.size() == 1)
2013 string dest = args[0];
2014 newPos = CTeleport::getPos(NLMISC::toLowerAscii(dest));
2015 if(newPos == CTeleport::Unknown)
2017 //here we try to teleport to a bot destination
2018 CBitMemStream out;
2019 if(GenericMsgHeaderMngr.pushNameToStream("TP:BOT", out))
2021 string str = args[0];
2022 out.serial( str );
2023 nldebug("/pos: TP:BOT sent");
2024 NetMngr.push(out);
2026 else
2027 nlwarning("/pos: unknown message name : 'TP:BOT'");
2028 return true;
2031 // Teleport to anywhere.
2032 else if(args.size() == 2 || args.size() == 3)
2034 fromString(args[0], newPos.x);
2035 fromString(args[1], newPos.y);
2036 if(args.size() == 3)
2037 fromString(args[2], newPos.z);
2038 else
2039 newPos.z = 0.0;
2041 // Bad argument number.
2042 else
2043 return false;
2046 CANNOT USE ProgressBar here, because it does pumpEvents(), and
2047 ICommand::execute() is typically called from a pumpEvents() too...
2048 => cause crash
2051 // Fade out the Game Sound
2052 if(SoundMngr)
2053 SoundMngr->fadeOutGameSound(ClientCfg.SoundTPFade);
2055 // Remove the selection.
2056 UserEntity->selection(CLFECOMMON::INVALID_SLOT);
2057 // Remove the target.
2058 UserEntity->targetSlot(CLFECOMMON::INVALID_SLOT);
2059 // Change the position of the entity and in Pacs.
2060 UserEntity->pos(newPos);
2061 // Select the closest continent from the new position.
2062 CDummyProgress progress;
2063 ContinentMngr.select(newPos, progress);
2064 // Teleport the User.
2065 UserEntity->tp(newPos);
2067 // First frame (for sound fade in)
2068 extern bool FirstFrame;
2069 FirstFrame = true;
2071 return true;
2074 NLMISC_COMMAND(removeEntity, "Remove an entity", "<Slot>")
2076 if (args.size() != 1) return false;
2077 uint slot;
2078 fromString(args[0], slot);
2079 EntitiesMngr.remove(slot, true);
2080 return true;
2084 NLMISC_COMMAND(entity, "Create an entity on the user or just remove it if Form not valid", "<Slot> <Form> [posx posy posz] [relativeToPlayer]")
2086 CInterfaceManager *IM = CInterfaceManager::getInstance ();
2088 // Check parameters.
2089 if(args.size() != 2 && args.size() != 5 && args.size() != 6)
2090 return false;
2092 // read pos.
2093 CVector entityPos;
2094 if(args.size()>=5)
2096 fromString(args[2], entityPos.x);
2097 fromString(args[3], entityPos.y);
2098 fromString(args[4], entityPos.z);
2099 // if want pos local to UserEntity
2100 if(args.size()==6)
2102 sint32 tmp;
2103 fromString(args[5], tmp);
2104 if (tmp != 0)
2106 CMatrix mat;
2107 mat.setRot(CVector::I, UserEntity->front(), CVector::K);
2108 mat.normalize(CMatrix::YZX);
2109 mat.setPos(UserEntity->pos());
2110 entityPos= mat * entityPos;
2114 else
2116 entityPos= UserEntity->pos()+UserEntity->front()*2.0;
2119 // Try to create the sheet with the parameter as a string.
2120 CSheetId sheetId;
2121 if(!sheetId.buildSheetId(args[1]))
2123 // Try to create the sheet with the parameter as an int.
2124 uint32 nSheetId;
2125 fromString(args[1], nSheetId);
2126 sheetId = CSheetId(nSheetId);
2127 if(sheetId == CSheetId::Unknown)
2129 nlwarning("Command 'entity': '%s' is not a valid form", args[1].c_str());
2130 return false;
2134 // The slot where the new entity will be.
2135 CLFECOMMON::TCLEntityId slot;
2136 fromString(args[0], slot);
2138 // Debug Infos
2139 nldebug("Command 'entity' : AddNewEntity with form %s in the slot %d", args[1].c_str(), slot);
2140 // Remove the old entity.
2141 EntitiesMngr.remove(slot, false);
2142 // Create the new entity.
2144 TNewEntityInfo emptyEntityInfo;
2145 emptyEntityInfo.reset();
2146 CEntityCL *entity = EntitiesMngr.create(slot, sheetId.asInt(), emptyEntityInfo);
2147 if(entity)
2149 sint64 *prop = 0;
2150 CCDBNodeLeaf *node = 0;
2151 // Set The property 'CLFECOMMON::PROPERTY_POSITION'.
2152 node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_POSX), false);
2153 if(node)
2155 sint64 x = (sint64)(entityPos.x*1000.0);
2156 sint64 y = (sint64)(entityPos.y*1000.0);
2157 sint64 z = (sint64)(entityPos.z*1000.0);
2158 node->setValue64(x);
2159 node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_POSY), false);
2160 if(node)
2162 node->setValue64(y);
2163 node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_POSZ), false);
2164 if(node)
2165 node->setValue64(z);
2168 // Set The property 'PROPERTY_ORIENTATION'.
2169 node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_ORIENTATION), false);
2170 if(node)
2172 C64BitsParts rot;
2173 rot.f[0] = (float)atan2(UserEntity->front().y, UserEntity->front().x);
2174 rot.f[1] = 0.f; // to be sure 64 bits value is initialized
2175 node->setValue64(rot.i64[0]);
2177 // Set Mode
2178 node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_MODE), false);
2179 if(node)
2181 node->setValue64((sint64)MBEHAV::NORMAL);
2182 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_MODE);
2184 // Set Visual Properties
2185 if(dynamic_cast<CPlayerCL *>(entity))
2187 SPropVisualA visualA;
2188 visualA.PropertySubData.Sex = ClientCfg.Sex;
2189 SPropVisualB visualB;
2190 // Initialize the Visual Property C (Default parameters).
2191 SPropVisualC visualC;
2192 visualC.PropertySubData.CharacterHeight = 7;
2193 visualC.PropertySubData.ArmsWidth = 7;
2194 visualC.PropertySubData.LegsWidth = 7;
2195 visualC.PropertySubData.TorsoWidth = 7;
2196 visualC.PropertySubData.BreastSize = 7;
2197 // Set The Database
2198 prop = (sint64 *)&visualB;
2199 NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_VPB))->setValue64(*prop);
2200 prop = (sint64 *)&visualC;
2201 NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_VPC))->setValue64(*prop);
2202 prop = (sint64 *)&visualA;
2203 NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_VPA))->setValue64(*prop);
2204 // Apply Changes.
2205 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_VPA);
2207 // Forage Source special
2208 if(dynamic_cast<CForageSourceCL*>(entity))
2210 sint64 barVal;
2211 barVal= 32; barVal<<= 7;
2212 barVal+= 32; barVal<<= 7;
2213 barVal+= 10; barVal<<= 7;
2214 barVal+= 127;
2215 NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_BARS))->setValue64(barVal);
2216 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_BARS);
2217 // must also update position, else don't work
2218 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_POSITION);
2220 else
2221 if (dynamic_cast<CFxCL*>(entity)) // FX cl special
2223 // must also update position, else don't work
2224 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_POSITION);
2227 nlinfo("entity: slot: %d \"%s\", \"%f\", \"%f\", \"%f\" ",
2228 slot,args[1].c_str(),
2229 entityPos.x, entityPos.y, entityPos.z);
2231 else
2232 nldebug("command 'entity' : entity in slot %d removed", slot);
2234 // Command well done.
2235 return true;
2238 NLMISC_COMMAND(primPoint, "add a primitive point", "<pointName>")
2240 if(args.size() != 2)
2241 return false;
2243 if(LDPrim == 0)
2245 LDPrim = new NLLIGO::CPrimitives;
2246 if(LDPrim == 0)
2248 nlwarning("primPoint: LDPrim == 0");
2249 return false;
2253 if(LDPrim->RootNode == 0)
2255 nlwarning("primPoint: LDPrim.RootNode == 0");
2256 return true;
2259 NLLIGO::CPropertyString *str = 0;
2260 NLLIGO::CPrimPoint *point = 0;
2262 point = new NLLIGO::CPrimPoint;
2263 if(point == 0)
2265 nlwarning("primPoint: point == 0");
2266 return true;
2268 point->Point.x = (float)UserEntity->pos().x;
2269 point->Point.y = (float)UserEntity->pos().y;
2270 point->Point.z = (float)UserEntity->pos().z;
2272 str = new NLLIGO::CPropertyString;
2273 if(str == 0)
2275 nlwarning("primPoint: str == 0 (1)");
2276 return true;
2278 point->addPropertyByName("class", str);
2279 str->String = "reference_point";
2281 str = new NLLIGO::CPropertyString;
2282 if(str == 0)
2284 nlwarning("primPoint: str == 0 (2)");
2285 return true;
2287 point->addPropertyByName("name", str);
2288 str->String = args[1];
2290 // Add the point to the primitive.
2291 LDPrim->RootNode->insertChild(point);
2293 // Open the file.
2294 NLMISC::COFile file;
2295 if(file.open(args[0]))
2297 // Create the XML stream
2298 NLMISC::COXml output;
2299 // Init
2300 if(output.init(&file, "1.0"))
2302 LDPrim->write(output.getDocument(), args[0].c_str());
2303 // Flush the stream, write all the output file
2304 output.flush();
2306 else
2307 nlwarning("primPoint: ");
2308 // Close the File.
2309 file.close();
2311 else
2312 nlwarning("primPoint: cannot open/create the file '%s'", args[0].c_str());
2314 return true;
2317 #ifdef ENABLE_INCOMING_MSG_RECORDER
2319 NLMISC_COMMAND(record, "Start Recording", "<name>")
2321 CInterfaceManager *IM = CInterfaceManager::getInstance ();
2323 // Check parameters.
2324 if(args.size() != 1)
2325 return false;
2327 // Warning when already recording.
2328 if(NetMngr.isRecording())
2330 IM->displaySystemInfo("Already Recording. Stop the current Record first");
2331 return true;
2334 // Save entities and DB.
2335 dump(args[0]);
2337 // On/Off record.
2338 if(!ClientCfg.Local)
2339 NetMngr.setRecordingMode(true, args[0]+"_net.rec");
2340 return true;
2343 NLMISC_COMMAND(replay, "replay", "<name>")
2345 // Check parameters.
2346 if(args.size() != 1)
2347 return false;
2349 // Load entities and DB.
2350 loadDump(args[0]);
2352 // On/Off record.
2353 if(ClientCfg.Local)
2354 NetMngr.setReplayingMode(!NetMngr.isReplaying(), args[0]+"_net.rec");
2355 return true;
2358 NLMISC_COMMAND(stopRecord, "Stop Recording", "")
2360 // Check parameters.
2361 if(args.size() != 0)
2362 return false;
2364 // On/Off record.
2365 if(!ClientCfg.Local)
2366 NetMngr.setRecordingMode(false);
2367 return true;
2370 #endif // ENABLE_INCOMING_MSG_RECORDER
2372 NLMISC_COMMAND(loadDump, "Command to load a dump file", "[<dump name>]")
2374 if(args.size() > 1)
2375 return false;
2377 string dumpName;
2378 if(args.size() == 1)
2379 dumpName = args[0];
2380 else
2381 dumpName = "default";
2383 loadDump(dumpName);
2384 return true;
2387 NLMISC_COMMAND(sheet2idx, "Return the index of a sheet", "<sheet name> <visual slot number>")
2389 CInterfaceManager *IM = CInterfaceManager::getInstance ();
2391 if(args.size() != 2)
2392 return false;
2394 string result;
2395 NLMISC::CSheetId sheetId;
2397 if(sheetId.buildSheetId(args[0]))
2399 uint slot;
2400 fromString(args[1], slot);
2401 uint32 idx = CVisualSlotManager::getInstance()->sheet2Index(sheetId, (SLOTTYPE::EVisualSlot)slot);
2402 result = NLMISC::toString("Index = %d", idx);
2404 else
2405 result = NLMISC::toString("sheet '%s' not valid", args[0].c_str());
2407 IM->displaySystemInfo(result);
2408 nlinfo("'sheet2idx': %s", result.c_str());
2409 return true;
2412 NLMISC_COMMAND(watchEntity, "Choose the entity to watch", "<slot>")
2414 if(args.size() != 1)
2415 return false;
2417 // Set the new debug entity slot.
2418 fromString(args[0], WatchedEntitySlot);
2419 return true;
2422 NLMISC_COMMAND(dynstr, "display a dyn string value", "<dyn string_id>")
2424 if (args.size() != 1)
2425 return false;
2427 uint dynId;
2428 fromString(args[0], dynId);
2430 string result;
2431 STRING_MANAGER::CStringManagerClient::instance()->getDynString(dynId, result);
2433 CInterfaceManager::getInstance()->displaySystemInfo(result);
2434 return true;
2437 NLMISC_COMMAND(serverstr, "display a server string value", "<serverstr string_id>")
2439 if (args.size() != 1)
2440 return false;
2442 uint dynId;
2443 fromString(args[0], dynId);
2445 string result;
2446 STRING_MANAGER::CStringManagerClient::instance()->getString(dynId, result);
2448 CInterfaceManager::getInstance()->displaySystemInfo(result);
2449 return true;
2452 NLMISC_COMMAND(cmd, "Send a command to a server","<service name> <cmd>")
2454 // Check parameters.
2455 if(args.size() < 2)
2456 return false;
2458 CBitMemStream out;
2459 if(GenericMsgHeaderMngr.pushNameToStream("DEBUG:CMD", out))
2461 bool addentity = false;
2462 string dest = args[0];
2463 string cmd = args[1];
2464 string arg;
2465 for (uint i = 2; i < args.size(); i++)
2467 arg += args[i] + " ";
2469 out.serial(addentity);
2470 out.serial(dest);
2471 out.serial(cmd);
2472 out.serial(arg);
2473 NetMngr.push(out);
2475 else
2476 nlwarning("mainLoop : unknown message name DEBUG:CMD");
2477 return true;
2480 NLMISC_COMMAND(cmde, "Send a command to a server with entityid","<service name> <cmd>")
2482 // Check parameters.
2483 if(args.size() < 2)
2484 return false;
2486 CBitMemStream out;
2487 if(GenericMsgHeaderMngr.pushNameToStream("DEBUG:CMD", out))
2489 bool addentity = true;
2490 string dest = args[0];
2491 string cmd = args[1];
2492 string arg;
2493 for (uint i = 2; i < args.size(); i++)
2495 arg += args[i] + " ";
2497 out.serial(addentity);
2498 out.serial(dest);
2499 out.serial(cmd);
2500 out.serial(arg);
2501 NetMngr.push(out);
2503 else
2504 nlwarning("mainLoop : unknown message name DEBUG:CMD");
2505 return true;
2508 NLMISC_COMMAND(askservices, "Ask the server all services up", "")
2510 CBitMemStream out;
2511 if(GenericMsgHeaderMngr.pushNameToStream("DEBUG:SERVICES", out))
2513 // Add the message to the send list.
2514 NetMngr.push(out);
2515 nlinfo("command 'services': 'DEBUG:SERVICES' sent");
2517 else
2518 nlwarning("command 'services': unknown message named 'DEBUG:SERVICES'");
2520 return true;
2523 NLMISC_COMMAND(mode, "Change the mode for an entity in a slot", "<Slot> <Mode> [dt(tick)]")
2525 // Check parameters.
2526 if(args.size() < 2)
2528 // Help
2529 CInterfaceManager::getInstance()->displaySystemInfo("This command need 2 paramters :");
2530 CInterfaceManager::getInstance()->displaySystemInfo(" <Slot> : the slot number of the entity to change");
2531 CInterfaceManager::getInstance()->displaySystemInfo(" <Mode> : the mode wanted for the entity, one of the following number :");
2532 for(uint i = 0; i<MBEHAV::NUMBER_OF_MODES; ++i)
2533 CInterfaceManager::getInstance()->displaySystemInfo(NLMISC::toString(" %d - %s", i, MBEHAV::modeToString((MBEHAV::EMode)i).c_str()));
2535 // Right parameters number
2536 else
2538 // Compute parameters
2539 CLFECOMMON::TCLEntityId slot;
2540 fromString(args[0], slot);
2541 MBEHAV::EMode mod = MBEHAV::stringToMode(args[1]);
2542 if(mod==MBEHAV::UNKNOWN_MODE)
2544 sint32 nMode;
2545 fromString(args[1], nMode);
2546 mod = (MBEHAV::EMode)nMode;
2549 // Compute the position.
2550 CEntityCL *entity = EntitiesMngr.entity(slot);
2551 if(entity)
2553 // Write the behaviour in the DB.
2554 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_MODE), mod);
2555 // Update the behaviour.
2556 sint32 dt= 10;
2557 if(args.size() > 2)
2558 fromString(args[2], dt);
2559 entity->updateVisualProperty(NetMngr.getCurrentServerTick()+dt, CLFECOMMON::PROPERTY_MODE);
2561 // Invalid slot.
2562 else
2563 CInterfaceManager::getInstance()->displaySystemInfo("There is no entity in the given slot");
2566 // Command well done.
2567 return true;
2570 NLMISC_COMMAND(behaviour, "Change the behaviour for an entity in a slot", "<Slot> <Behaviour> [<Attack Intensity>] [<Impact Intensity>] [<delta HP>] [dt(tick)]")
2572 // Check parameters.
2573 if(args.size() < 2 || args.size() > 6)
2575 // Help
2576 CInterfaceManager::getInstance()->displaySystemInfo("This command need 2 to 6 paramters :");
2577 CInterfaceManager::getInstance()->displaySystemInfo(" <Slot> : the slot number of the entity to change");
2578 CInterfaceManager::getInstance()->displaySystemInfo(" <Behaviour> : the behaviour to play for the entity, one of the following number :");
2579 for(uint i = 0; i<MBEHAV::EMOTE_BEGIN; ++i)
2580 CInterfaceManager::getInstance()->displaySystemInfo(NLMISC::toString(" %d - %s", i, MBEHAV::behaviourToString((MBEHAV::EBehaviour)i).c_str()));
2581 CInterfaceManager::getInstance()->displaySystemInfo(NLMISC::toString(" %d-%d - Emotes", MBEHAV::EMOTE_BEGIN, MBEHAV::EMOTE_END));
2583 else
2585 // Compute parameters
2586 CLFECOMMON::TCLEntityId slot;
2587 fromString(args[0], slot);
2588 MBEHAV::EBehaviour beh = MBEHAV::stringToBehaviour(args[1]);
2589 if(beh==MBEHAV::UNKNOWN_BEHAVIOUR)
2591 sint32 temp;
2592 fromString(args[1], temp);
2593 beh= (MBEHAV::EBehaviour)temp;
2596 // Make the behaviour
2597 MBEHAV::CBehaviour behaviour(beh);
2598 // Get the Power
2599 if ( (beh == MBEHAV::PROSPECTING) || (beh == MBEHAV::PROSPECTING_END) )
2601 if(args.size() > 2)
2603 uint16 range;
2604 fromString(args[2], range);
2605 behaviour.ForageProspection.Range = range; // 0..127
2607 if(args.size() > 3)
2609 uint16 angle;
2610 fromString(args[3], angle);
2611 behaviour.ForageProspection.Angle = angle; // 0..3
2613 if(args.size() > 4)
2615 uint16 level;
2616 fromString(args[4], level);
2617 behaviour.ForageProspection.Level = level; // 0..4
2620 else
2622 if(args.size() > 2)
2624 uint16 impactIntensity;
2625 fromString(args[2], impactIntensity);
2626 behaviour.Combat.ImpactIntensity = impactIntensity;
2628 if(args.size() > 3)
2630 uint16 impactIntensity;
2631 fromString(args[3], impactIntensity);
2632 behaviour.Combat.ImpactIntensity = impactIntensity;
2634 if(args.size() > 4)
2635 fromString(args[4], behaviour.DeltaHP);
2637 // get the dt
2638 sint32 dt= 10;
2639 if(args.size() > 5)
2640 fromString(args[5], dt);
2642 // Compute the position.
2643 CEntityCL *entity = EntitiesMngr.entity(slot);
2644 if(entity)
2646 // Write the behaviour in the DB.
2647 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_BEHAVIOUR), behaviour);
2648 // Update the behaviour.
2649 entity->updateVisualProperty(NetMngr.getCurrentServerTick()+dt, CLFECOMMON::PROPERTY_BEHAVIOUR);
2651 else
2652 CInterfaceManager::getInstance()->displaySystemInfo("There is no entity in the given slot");
2655 // Command well done.
2656 return true;
2660 NLMISC_COMMAND(magic, "Cast a spell", "\n"
2661 "<Slot> : the one who cast the spell\n"
2662 "<type> : 0->GOOD 1->Bad 2->NEUTRAL\n"
2663 "<success> : 0->success 1->Fail 2->Fumble\n"
2664 "<Spell Power> : \n"
2665 "<Impact Intensity> : \n"
2666 "<resist> : 0->not resisted, any other->resisted.\n")
2668 CInterfaceManager *IM = CInterfaceManager::getInstance ();
2670 // Check parameters.
2671 if(args.size() != 6)
2673 // Help
2674 // CInterfaceManager::getInstance()->displaySystemInfo("This command need 2 or 3 paramters :");
2675 // CInterfaceManager::getInstance()->displaySystemInfo(" <Slot> : the slot number of the entity to change");
2676 // CInterfaceManager::getInstance()->displaySystemInfo(" <Behaviour> : the behaviour to play for the entity, one of the following number :");
2677 // for(uint i = 0; i<MBEHAV::EMOTE_BEGIN; ++i)
2678 // CInterfaceManager::getInstance()->displaySystemInfo(NLMISC::toString(" %d - %s", i, MBEHAV::behaviourToString((MBEHAV::EBehaviour)i)));
2679 // CInterfaceManager::getInstance()->displaySystemInfo(NLMISC::toString(" %d-%d - Emotes", MBEHAV::EMOTE_BEGIN, MBEHAV::EMOTE_END));
2681 else
2683 // Compute parameters
2684 CLFECOMMON::TCLEntityId slot;
2685 fromString(args[0], slot);
2686 // Magic Type (good bad neutral)
2687 uint type;
2688 fromString(args[1], type);
2689 type %= 3;
2690 MBEHAV::EBehaviour behTmp = (MBEHAV::EBehaviour)(MBEHAV::CASTING_GOOD+type);
2691 MBEHAV::CBehaviour castingBeh(behTmp);
2692 // Result
2693 MBEHAV::CBehaviour behaviour;
2694 uint result;
2695 fromString(args[2], result);
2696 result %= %3;
2697 if (type==0)
2698 behaviour.Behaviour = (MBEHAV::EBehaviour)(MBEHAV::END_CASTING_GOOD_SUCCESS + result);
2699 else if(type==1)
2700 behaviour.Behaviour = (MBEHAV::EBehaviour)(MBEHAV::END_CASTING_BAD_SUCCESS + result);
2701 else
2702 behaviour.Behaviour = (MBEHAV::EBehaviour)(MBEHAV::END_CASTING_NEUTRAL_SUCCESS + result);
2703 uint16 spellPower, impactIntensity;
2704 // Spell Power
2705 fromString(args[3], spellPower);
2706 behaviour.Magic.SpellPower = spellPower;
2707 // Impact Intensity
2708 fromString(args[4], impactIntensity);
2709 behaviour.Magic.ImpactIntensity = impactIntensity;
2710 // Resist
2711 bool targetResists;
2712 fromString(args[5], targetResists);
2713 behaviour.Magic.TargetResists = targetResists;
2714 // Get the entity
2715 CEntityCL *entity = EntitiesMngr.entity(slot);
2716 if(entity)
2718 // Write the behaviour in the DB.
2719 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_BEHAVIOUR), castingBeh);
2720 // Update the behaviour.
2721 entity->updateVisualProperty(NetMngr.getCurrentServerTick()+10, CLFECOMMON::PROPERTY_BEHAVIOUR);
2722 // Write the behaviour in the DB.
2723 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_BEHAVIOUR), behaviour);
2724 // Update the behaviour.
2725 entity->updateVisualProperty(NetMngr.getCurrentServerTick()+50, CLFECOMMON::PROPERTY_BEHAVIOUR);
2727 else
2728 CInterfaceManager::getInstance()->displaySystemInfo("There is no entity in the given slot");
2731 // Command well done.
2732 return true;
2735 NLMISC_COMMAND(spell, "Cast a spell", "\n"
2736 "<Slot> : the one who cast the spell\n"
2737 "<type> : 0->OFF 1->CUR 2->MIX\n"
2738 "<success> : 0->Fail 1->Fumble 2->Success 3->Link\n"
2739 "<Resist> : 0->Resist 1->Not Resist\n"
2740 "<Spell Id> : \n"
2741 "<Intensity> : [0, 5]\n")
2743 // Check parameters.
2744 if(args.size() != 6)
2746 // Help
2747 // CInterfaceManager::getInstance()->displaySystemInfo("This command need 2 or 3 paramters :");
2748 // CInterfaceManager::getInstance()->displaySystemInfo(" <Slot> : the slot number of the entity to change");
2749 // CInterfaceManager::getInstance()->displaySystemInfo(" <Behaviour> : the behaviour to play for the entity, one of the following number :");
2750 // for(uint i = 0; i<MBEHAV::EMOTE_BEGIN; ++i)
2751 // CInterfaceManager::getInstance()->displaySystemInfo(NLMISC::toString(" %d - %s", i, MBEHAV::behaviourToString((MBEHAV::EBehaviour)i)));
2752 // CInterfaceManager::getInstance()->displaySystemInfo(NLMISC::toString(" %d-%d - Emotes", MBEHAV::EMOTE_BEGIN, MBEHAV::EMOTE_END));
2754 else
2756 // Compute parameters
2757 CLFECOMMON::TCLEntityId slot;
2758 fromString(args[0], slot);
2759 // Magic Type (good bad neutral)
2760 uint type;
2761 fromString(args[1], type);
2762 type %= 3;
2763 MBEHAV::EBehaviour behTmp = (MBEHAV::EBehaviour)(MBEHAV::CAST_OFF+type);
2764 MBEHAV::CBehaviour castingBeh(behTmp);
2765 // Result
2766 MBEHAV::CBehaviour behaviour;
2767 uint result;
2768 fromString(args[2], result);
2769 result %= 4;
2770 behaviour.Behaviour = (MBEHAV::EBehaviour)(MBEHAV::CAST_OFF_FAIL+type*4+result);
2771 // Spell Power
2772 uint16 spellMode;
2773 fromString(args[3], spellMode);
2774 behaviour.Spell.SpellMode = spellMode;
2775 // Impact Intensity
2776 uint16 spellId;
2777 fromString(args[4], spellId);
2778 behaviour.Spell.SpellId = spellId;
2779 // Resist
2780 uint16 spellIntensity;
2781 fromString(args[5], spellIntensity);
2782 behaviour.Spell.SpellIntensity = spellIntensity;
2783 // Get the entity
2784 CEntityCL *entity = EntitiesMngr.entity(slot);
2785 if(entity)
2787 uint64 beha = castingBeh;
2788 sint64 beha2 = *((sint64 *)(&beha));
2789 // Write the behaviour in the DB.
2790 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_BEHAVIOUR), beha2);
2791 // Update the behaviour.
2792 entity->updateVisualProperty(NetMngr.getCurrentServerTick()+10, CLFECOMMON::PROPERTY_BEHAVIOUR);
2793 beha = behaviour;
2794 beha2 = *((sint64 *)(&beha));
2795 // Write the behaviour in the DB.
2796 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_BEHAVIOUR), beha2);
2797 // Update the behaviour.
2798 entity->updateVisualProperty(NetMngr.getCurrentServerTick()+50, CLFECOMMON::PROPERTY_BEHAVIOUR);
2800 else
2801 CInterfaceManager::getInstance()->displaySystemInfo("There is no entity in the given slot");
2804 // Command well done.
2805 return true;
2808 NLMISC_COMMAND(settarget, "Set a target for an entity. Do not set the target slot to remove the target", "<Slot> [<Target Slot>]")
2810 CLFECOMMON::TCLEntityId targetSlot = CLFECOMMON::INVALID_SLOT;
2812 // Check parameters.
2813 switch(args.size())
2815 // Set the target for the entity.
2816 case 2:
2817 fromString(args[1], targetSlot);
2819 // Remove the target for the entity.
2820 case 1:
2822 uint entitySlot;
2823 fromString(args[0], entitySlot);
2824 CEntityCL *entity = EntitiesMngr.entity(entitySlot);
2825 if(entity)
2826 entity->targetSlot(targetSlot);
2827 else
2828 nlwarning("command 'settarget': there is no entity in the slot %d", entitySlot);
2830 break;
2832 // Bad command.
2833 default:
2834 return false;
2837 // Well done.
2838 return true;
2841 NLMISC_COMMAND(particle, "Create a particule at the user position (play FireWorkA_with_sound.ps by default)", "[<filename.ps>]")
2843 string fn;
2845 // Check parameters.
2846 if(args.empty())
2848 fn = "FireWorkA_with_sound.ps";
2850 else if(args.size() == 1)
2852 fn = args[0];
2854 else
2855 return false;
2857 UInstance fx = Scene->createInstance(fn);
2859 // not found
2860 if(fx.empty())
2862 log.displayNL ("Can't create instance '%s'", fn.c_str());
2863 return false;
2866 fx.setPos(UserEntity->pos());
2867 fx.setClusterSystem(UserEntity->skeleton()->getClusterSystem());
2869 // Command well done.
2870 return true;
2873 NLMISC_COMMAND(move, "Move an entity", "Slot: [1-254]")
2875 // Check parameters.
2876 if(args.size() != 1)
2877 return false;
2879 CLFECOMMON::TCLEntityId slot;
2880 fromString(args[0], slot);
2882 // Compute the position.
2883 CEntityCL *entity = EntitiesMngr.entity(slot);
2884 if(entity)
2886 sint64 x = (sint64)((entity->pos().x+UserEntity->front().x*10.0)*1000.0);
2887 sint64 y = (sint64)((entity->pos().y+UserEntity->front().y*10.0)*1000.0);
2888 sint64 z = (sint64)((entity->pos().z+UserEntity->front().z*10.0)*1000.0);
2889 // Write the position in the DB.
2890 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P0", x);
2891 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P1", y);
2892 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P2", z);
2893 // Update the position.
2894 EntitiesMngr.updateVisualProperty(NetMngr.getCurrentServerTick()+30, slot, 0);
2896 x = (sint64)((entity->pos().x)*1000.0);
2897 y = (sint64)((entity->pos().y)*1000.0);
2898 z = (sint64)((entity->pos().z)*1000.0);
2899 // Write the position in the DB.
2900 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P0", x);
2901 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P1", y);
2902 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P2", z);
2903 // Update the position.
2904 EntitiesMngr.updateVisualProperty(NetMngr.getCurrentServerTick()+60, slot, 0);
2906 else
2907 nlwarning("command 'move' : there is no entity allocated in slot %d", slot);
2909 // Command well done.
2910 return true;
2913 NLMISC_COMMAND(moveRel, "Move an entity, specifying delta pos from current", "Slot: [1-254] dx(m) dy(m) [dt(tick)] [predictedIV(tick)]")
2915 // Check parameters.
2916 if(args.size() <3)
2917 return false;
2919 CLFECOMMON::TCLEntityId slot;
2920 fromString(args[0], slot);
2922 // Compute the position.
2923 CEntityCL *entity = EntitiesMngr.entity(slot);
2924 if(entity)
2926 float dx, dy;
2927 fromString(args[1], dx);
2928 fromString(args[2], dy);
2929 sint32 dt= 10;
2930 if(args.size()>=4)
2931 fromString(args[3], dt);
2932 sint32 pi= 0;
2933 if(args.size()>=5)
2934 fromString(args[4], pi);
2935 sint64 x = (sint64)((entity->pos().x+dx)*1000.0);
2936 sint64 y = (sint64)((entity->pos().y+dy)*1000.0);
2937 sint64 z = (sint64)((entity->pos().z+0)*1000.0);
2938 // Write the position in the DB.
2939 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P0", x);
2940 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P1", y);
2941 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P2", z);
2942 // Update the position.
2943 EntitiesMngr.updateVisualProperty(NetMngr.getCurrentServerTick()+dt, slot, 0, pi);
2945 else
2946 nlwarning("command 'move' : there is no entity allocated in slot %d", slot);
2948 // Command well done.
2949 return true;
2952 NLMISC_COMMAND(orient, "Orient an entity", "Slot: [1-254] orient(degree) [dt(tick)]")
2954 // Check parameters.
2955 if(args.size() < 2)
2956 return false;
2958 CLFECOMMON::TCLEntityId slot;
2959 fromString(args[0], slot);
2961 // Compute the position.
2962 CEntityCL *entity = EntitiesMngr.entity(slot);
2963 if(entity)
2965 sint32 rot;
2966 fromString(args[1], rot);
2967 sint32 dt= 10;
2968 if(args.size()> 2)
2969 fromString(args[2], dt);
2970 // Write the position in the DB.
2971 float fRot= (float)(rot*Pi/180.f);
2973 C64BitsParts r;
2974 r.f[0] = fRot;
2975 r.f[1] = 0.f; // to be sure 64 bits value is initialized
2977 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P"+toString(CLFECOMMON::PROPERTY_ORIENTATION), r.u32[0]);
2978 // Update the position.
2979 EntitiesMngr.updateVisualProperty(NetMngr.getCurrentServerTick()+dt, slot, CLFECOMMON::PROPERTY_ORIENTATION);
2981 else
2982 nlwarning("command 'move' : there is no entity allocated in slot %d", slot);
2984 // Command well done.
2985 return true;
2988 NLMISC_COMMAND(moveTo, "Move an entity to another one", "<slot(from)>:[1-254], <slot(to)>:[0-254] default 0")
2990 sint64 x, y, z;
2992 // Check parameters.
2993 if(args.size() == 1)
2995 x = (sint64)(UserEntity->pos().x*1000.0);
2996 y = (sint64)(UserEntity->pos().y*1000.0);
2997 z = (sint64)(UserEntity->pos().z*1000.0);
2999 else if(args.size() == 2)
3001 CLFECOMMON::TCLEntityId slotDest;
3002 fromString(args[1], slotDest);
3003 // Compute the position.
3004 CEntityCL *entity = EntitiesMngr.entity(slotDest);
3005 if(entity)
3007 x = (sint64)(entity->pos().x*1000.0);
3008 y = (sint64)(entity->pos().y*1000.0);
3009 z = (sint64)(entity->pos().z*1000.0);
3011 else
3013 // Command is correct but not all the parameters are valid.
3014 nlwarning("command 'move_to' : there is no entity allocated for the dest in slot %d", slotDest);
3015 return true;
3018 // Wrong number of parameters.
3019 else
3020 return false;
3022 CLFECOMMON::TCLEntityId slot;
3023 fromString(args[0], slot);
3024 // Write the position in the DB.
3025 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P0", x);
3026 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P1", y);
3027 IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P2", z);
3028 // Update the position.
3029 EntitiesMngr.updateVisualProperty(NetMngr.getCurrentServerTick()+30, slot, 0);
3031 // Command well done.
3032 return true;
3035 NLMISC_COMMAND(setMode, "Set The Mode for an Entity without to add a stage for it", "<slot> <mode>")
3037 // Check parameters.
3038 if(args.size() != 2)
3039 return false;
3041 // Get the Slot and the Mode.
3042 CLFECOMMON::TCLEntityId slot;
3043 fromString(args[0], slot);
3044 sint32 nMode;
3045 fromString(args[1], nMode);
3046 MBEHAV::EMode mod = (MBEHAV::EMode)nMode;
3048 // Compute the position.
3049 CEntityCL *entity = EntitiesMngr.entity(slot);
3050 if(entity)
3051 entity->mode(mod);
3052 else
3053 nlwarning("command 'setMode' : there is no entity allocated in slot '%d'", slot);
3055 // Command well done.
3056 return true;
3058 NLMISC_COMMAND(paintTarget, "Modify the target color",
3059 "\n"
3060 "<color> color for the target (0-7)\n")
3062 // Check parameters
3063 if(args.size() != 1)
3064 return false;
3065 // Get the entity slot
3066 CLFECOMMON::TCLEntityId slot = UserEntity->selection();
3067 if(slot == CLFECOMMON::INVALID_SLOT)
3068 return true;
3070 SPropVisualA vA;
3071 SPropVisualB vB;
3072 SPropVisualC vC;
3073 const string propNameA = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPA);
3074 const string propNameB = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPB);
3075 const string propNameC = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPC);
3076 vA.PropertyA = NLGUI::CDBManager::getInstance()->getDbProp(propNameA)->getValue64();
3077 vB.PropertyB = NLGUI::CDBManager::getInstance()->getDbProp(propNameB)->getValue64();
3078 vC.PropertyC = NLGUI::CDBManager::getInstance()->getDbProp(propNameC)->getValue64();
3080 // Get the visual item index
3081 uint value;
3082 fromString(args[0], value);
3083 // Change color
3084 vA.PropertySubData.JacketColor = value;
3085 vA.PropertySubData.TrouserColor = value;
3086 vA.PropertySubData.ArmColor = value;
3087 vA.PropertySubData.HatColor = value;
3088 vB.PropertySubData.HandsColor = value;
3089 vB.PropertySubData.FeetColor = value;
3091 // Set the database.
3092 NLGUI::CDBManager::getInstance()->getDbProp(propNameA)->setValue64((sint64)vA.PropertyA);
3093 NLGUI::CDBManager::getInstance()->getDbProp(propNameB)->setValue64((sint64)vB.PropertyB);
3094 NLGUI::CDBManager::getInstance()->getDbProp(propNameC)->setValue64((sint64)vC.PropertyC);
3095 // Force to update properties.
3096 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_VPA);
3098 // Done.
3099 return true;
3102 NLMISC_COMMAND(playAnim, "Try to play the animation to the target", "<anim name>")
3104 // Check parameters
3105 if(args.size() != 1)
3106 return false;
3108 CLFECOMMON::TCLEntityId slot = UserEntity->selection();
3109 if(slot == CLFECOMMON::INVALID_SLOT)
3110 return true;
3111 if(EAM == 0)
3112 return true;
3113 NL3D::UAnimationSet *animset = EAM->getAnimationSet();
3114 if(animset == 0)
3115 return true;
3116 uint animId = animset->getAnimationIdByName(args[0]);
3117 if(animId == UAnimationSet::NotFound)
3119 nlwarning("anim not found %s", args[0].c_str());
3120 return true;
3122 CEntityCL *selection = EntitiesMngr.entity(slot);
3123 CCharacterCL *character = dynamic_cast<CCharacterCL *>(selection);
3124 if(character)
3125 character->setAnim(CAnimationStateSheet::Idle, (TAnimStateKey)CAnimation::UnknownAnim, animId);
3126 return true;
3129 NLMISC_COMMAND(vP, "Modify the Visual Property",
3130 "\n"
3131 "<slot> of the entity to change.\n"
3132 "<type> the property to change :\n"
3133 " 0->CHEST (0~511)\n"
3134 " 1->LEG (0~255)\n"
3135 " 2->ARM (0~255)\n"
3136 " 3->HEAD (0~127)\n"
3137 " 4->WEAPON_R (0~2047)\n"
3138 " 5->WEAPON_L (0~255)\n"
3139 " 6->FEET (0~511)\n"
3140 " 7->HAND (0~511)\n"
3141 " 8->EYES COLOR (0~7)\n"
3142 " 9->SEX (0: Male, 1: Female)\n"
3143 " 10->TATOO (0~31)\n"
3144 " 11->CHEST COLOR (0~7)\n"
3145 " 12->LEG COLOR (0~7)\n"
3146 " 13->ARM COLOR (0~7)\n"
3147 " 14->HAIR COLOR (0~7)\n"
3148 " 15->HAND COLOR (0~7)\n"
3149 " 16->FEET COLOR (0~7)\n"
3150 " 17->MORPH 1 (0~7)\n"
3151 " 18->MORPH 2 (0~7)\n"
3152 " 19->MORPH 3 (0~7)\n"
3153 " 20->MORPH 4 (0~7)\n"
3154 " 21->MORPH 5 (0~7)\n"
3155 " 22->MORPH 6 (0~7)\n"
3156 " 23->MORPH 7 (0~7)\n"
3157 " 24->CHARACTER HEIGHT (0~15)\n"
3158 " 25->TORSO WIDTH (0~15)\n"
3159 " 26->ARMS WIDTH (0~15)\n"
3160 " 27->LEGS WIDTH (0~15)\n"
3161 " 28->BREASTS SIZE (0~15)\n"
3162 "<value> for the property.\n")
3164 // Check parameters
3165 if(args.size() != 3)
3166 return false;
3168 // Get the database entry.
3169 SPropVisualA vA;
3170 SPropVisualB vB;
3171 SPropVisualC vC;
3172 uint slot;
3173 fromString(args[0], slot);
3174 const string propNameA = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPA);
3175 const string propNameB = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPB);
3176 const string propNameC = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPC);
3177 vA.PropertyA = NLGUI::CDBManager::getInstance()->getDbProp(propNameA)->getValue64();
3178 vB.PropertyB = NLGUI::CDBManager::getInstance()->getDbProp(propNameB)->getValue64();
3179 vC.PropertyC = NLGUI::CDBManager::getInstance()->getDbProp(propNameC)->getValue64();
3180 // Get the visual item index
3181 uint value;
3182 fromString(args[2], value);
3183 // Get the visual slot to change.
3184 uint type;
3185 fromString(args[1], type);
3186 // if .sitem visual slot, try translate .sitem to VSIndex
3187 if(type<=7)
3189 SLOTTYPE::EVisualSlot vslot= SLOTTYPE::HIDDEN_SLOT;
3190 switch(type)
3192 case 0: vslot= SLOTTYPE::CHEST_SLOT; break;
3193 case 1: vslot= SLOTTYPE::LEGS_SLOT; break;
3194 case 2: vslot= SLOTTYPE::ARMS_SLOT; break;
3195 case 3: vslot= SLOTTYPE::HEAD_SLOT; break;
3196 case 4: vslot= SLOTTYPE::RIGHT_HAND_SLOT; break;
3197 case 5: vslot= SLOTTYPE::LEFT_HAND_SLOT; break;
3198 case 6: vslot= SLOTTYPE::FEET_SLOT; break;
3199 case 7: vslot= SLOTTYPE::HANDS_SLOT; break;
3200 default: break;
3202 if(vslot!=SLOTTYPE::HIDDEN_SLOT && value==0)
3204 sint vsIndex= SheetMngr.getVSIndex(args[2], vslot);
3205 // succed!
3206 if(vsIndex!=-1)
3207 value= vsIndex;
3210 // setup
3211 switch(type)
3213 case 0:
3214 vA.PropertySubData.JacketModel = value;
3215 break;
3216 case 1:
3217 vA.PropertySubData.TrouserModel = value;
3218 break;
3219 case 2:
3220 vA.PropertySubData.ArmModel = value;
3221 break;
3222 case 3:
3223 vA.PropertySubData.HatModel = value;
3224 break;
3225 case 4:
3226 vA.PropertySubData.WeaponRightHand = value;
3227 break;
3228 case 5:
3229 vA.PropertySubData.WeaponLeftHand = value;
3230 break;
3231 case 6:
3232 vB.PropertySubData.FeetModel = value;
3233 break;
3234 case 7:
3235 vB.PropertySubData.HandsModel = value;
3236 break;
3237 case 8:
3238 vC.PropertySubData.EyesColor = value;
3239 break;
3240 case 9:
3241 vA.PropertySubData.Sex = value;
3242 break;
3243 case 10:
3244 vC.PropertySubData.Tattoo = value;
3245 break;
3246 case 11:
3247 vA.PropertySubData.JacketColor = value;
3248 break;
3249 case 12:
3250 vA.PropertySubData.TrouserColor = value;
3251 break;
3252 case 13:
3253 vA.PropertySubData.ArmColor = value;
3254 break;
3255 case 14:
3256 vA.PropertySubData.HatColor = value;
3257 break;
3258 case 15:
3259 vB.PropertySubData.HandsColor = value;
3260 break;
3261 case 16:
3262 vB.PropertySubData.FeetColor = value;
3263 break;
3264 case 17:
3265 vC.PropertySubData.MorphTarget1 = value;
3266 break;
3267 case 18:
3268 vC.PropertySubData.MorphTarget2 = value;
3269 break;
3270 case 19:
3271 vC.PropertySubData.MorphTarget3 = value;
3272 break;
3273 case 20:
3274 vC.PropertySubData.MorphTarget4 = value;
3275 break;
3276 case 21:
3277 vC.PropertySubData.MorphTarget5 = value;
3278 break;
3279 case 22:
3280 vC.PropertySubData.MorphTarget6 = value;
3281 break;
3282 case 23:
3283 vC.PropertySubData.MorphTarget7 = value;
3284 break;
3285 case 24:
3286 vC.PropertySubData.CharacterHeight = value;
3287 break;
3288 case 25:
3289 vC.PropertySubData.TorsoWidth = value;
3290 break;
3291 case 26:
3292 vC.PropertySubData.ArmsWidth = value;
3293 break;
3294 case 27:
3295 vC.PropertySubData.LegsWidth = value;
3296 break;
3297 case 28:
3298 vC.PropertySubData.BreastSize = value;
3299 break;
3301 default:
3302 nlwarning("command 'vP': type not valid");
3303 return false;
3304 break;
3307 // Set the database.
3308 NLGUI::CDBManager::getInstance()->getDbProp(propNameA)->setValue64((sint64)vA.PropertyA);
3309 NLGUI::CDBManager::getInstance()->getDbProp(propNameB)->setValue64((sint64)vB.PropertyB);
3310 NLGUI::CDBManager::getInstance()->getDbProp(propNameC)->setValue64((sint64)vC.PropertyC);
3311 // Force to update properties.
3312 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_VPA);
3314 // Done.
3315 return true;
3318 NLMISC_COMMAND(altLook, "Modify the Alternative Look Property",
3319 "\n"
3320 "<slot> of the entity to change.\n"
3321 "<colorTop>\n"
3322 "<colorBottom>\n"
3323 "<rWeapon>\n"
3324 "<lWeapon>\n"
3325 "<seed>\n"
3326 "<hairColor>\n"
3327 "<putHelm>\n"
3328 "[<colorGlove>]\n"
3329 "[<colorBoot>]\n"
3330 "[<colorArm>]\n")
3332 // Check parameters
3333 if(args.size() < 8 || args.size() > 11)
3334 return false;
3336 // Get the database entry.
3337 uint slot;
3338 fromString(args[0], slot);
3339 const string propName = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPA);
3340 // Get the old value (not useful since we change the whole property).
3341 SAltLookProp altLookProp;
3342 altLookProp.Summary = NLGUI::CDBManager::getInstance()->getDbProp(propName)->getValue64();
3343 uint32 colorTop, colorBot, weaponRightHand, weaponLeftHand, seed, colorHair, hat;
3344 fromString(args[1], colorTop);
3345 fromString(args[2], colorBot);
3346 fromString(args[3], weaponRightHand);
3347 fromString(args[4], weaponLeftHand);
3348 fromString(args[5], seed);
3349 fromString(args[6], colorHair);
3350 fromString(args[7], hat);
3351 altLookProp.Element.ColorTop = colorTop;
3352 altLookProp.Element.ColorBot = colorBot;
3353 altLookProp.Element.WeaponRightHand = weaponRightHand;
3354 altLookProp.Element.WeaponLeftHand = weaponLeftHand;
3355 altLookProp.Element.Seed = seed;
3356 altLookProp.Element.ColorHair = colorHair;
3357 altLookProp.Element.Hat = hat;
3358 // New colours
3359 if(args.size() == 11)
3361 uint32 colorGlove, colorBoot, colorArm;
3362 fromString(args[8], colorGlove);
3363 fromString(args[9], colorBoot);
3364 fromString(args[10], colorArm);
3365 altLookProp.Element.ColorGlove = colorGlove;
3366 altLookProp.Element.ColorBoot = colorBoot;
3367 altLookProp.Element.ColorArm = colorArm;
3369 // Old Colours
3370 else
3372 altLookProp.Element.ColorGlove = altLookProp.Element.ColorTop;
3373 altLookProp.Element.ColorArm = altLookProp.Element.ColorTop;
3374 altLookProp.Element.ColorBoot = altLookProp.Element.ColorBot;
3377 // Set the database.
3378 NLGUI::CDBManager::getInstance()->getDbProp(propName)->setValue64((sint64)altLookProp.Summary);
3379 // Force to update properties.
3380 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_VPA);
3382 // Done.
3383 return true;
3386 NLMISC_COMMAND(color, "Command to color an entity",
3387 "\n"
3388 "<Slot>: whole number (if <0 slot will be the current selection)\n"
3389 "<UserColor>: whole number\n"
3390 "<Hair>: whole number\n"
3391 "<Eyes>: whole number\n"
3392 "[<Part>]: whole number\n"
3393 " default=the whole body\n"
3394 " 0=CHEST\n"
3395 " 1=LEG\n"
3396 " 2=HEAD\n"
3397 " 3=ARMS\n"
3398 " 4=HANDS\n"
3399 " 5=FEET\n")
3401 // Check parameters.
3402 if(args.size() != 4 && args.size() != 5)
3403 return false;
3405 // Witch part to dye ?
3406 sint part = -1;
3407 if(args.size() == 5)
3408 fromString(args[4], part);
3410 // Get the entity slot to dye.
3411 sint slotTmp;
3412 fromString(args[0], slotTmp);
3413 CLFECOMMON::TCLEntityId slot;
3414 if(slotTmp >= 0)
3415 slot = (CLFECOMMON::TCLEntityId)slotTmp;
3416 else
3417 slot = (CLFECOMMON::TCLEntityId)UserEntity->selection();
3419 CEntityCL *entity = EntitiesMngr.entity(slot);
3420 if(entity)
3422 sint color, hair, eyes;
3423 fromString(args[1], color);
3424 fromString(args[2], hair);
3425 fromString(args[3], eyes);
3426 entity->changeColors(color, hair, eyes, part);
3428 else
3429 nlwarning("command 'changeColors': there is no entity allocated in slot '%d'", slot);
3431 // Command well done.
3432 return true;
3435 NLMISC_COMMAND(saveIntCfg, "save the interface config file","")
3437 CInterfaceManager::getInstance()->saveConfig ("save/interface.icfg");
3438 return true;
3441 NLMISC_COMMAND(loadIntCfg, "load the interface config file","")
3443 CInterfaceManager *im = CInterfaceManager::getInstance();
3444 im->loadConfig ("save/interface.icfg");
3445 // reset the compass target
3446 CGroupCompas *gc = dynamic_cast<CGroupCompas *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:compass"));
3447 if (gc && gc->isSavedTargetValid())
3449 gc->setTarget(gc->getSavedTarget());
3451 return true;
3454 NLMISC_COMMAND(harvestDeposit, "harvest a deposit", "")
3456 // no parameter needed
3458 // Create the message for the server
3459 /* CBitMemStream out;
3460 if(GenericMsgHeaderMngr.pushNameToStream("HARVEST:DEPOSIT", out))
3462 uint16 skill = SKILLS::digging;
3464 out.serial(skill);
3466 NetMngr.push(out);
3468 // open the interface
3469 // CWidgetManager::getInstance()->getWindowFromId("ui:interface:harvest")->setActive(true);
3471 else
3472 nlwarning("command : unknown message name : 'HARVEST:DEPOSIT'");
3474 return true;
3477 NLMISC_COMMAND(training, "start a training action", "")
3479 // no parameter needed
3481 // Create the message for the server
3482 CBitMemStream out;
3483 if(GenericMsgHeaderMngr.pushNameToStream("TRAINING", out))
3485 NetMngr.push(out);
3487 else
3488 nlwarning("command : unknown message name : 'TRAINING'");
3490 return true;
3493 NLMISC_COMMAND(testMount, "Set the entity to mount","<Slot> <Mount>")
3495 CLFECOMMON::TCLEntityId slot;
3496 CLFECOMMON::TCLEntityId mount = CLFECOMMON::INVALID_SLOT;
3498 switch(args.size())
3500 case 2:
3501 fromString(args[1], mount);
3502 case 1:
3503 fromString(args[0], slot);
3504 break;
3506 default:
3507 return false;
3508 break;
3511 // Set the database.
3512 string propName = toString("SERVER:Entities:E%d:P%d", mount, CLFECOMMON::PROPERTY_RIDER_ENTITY_ID);
3513 NLGUI::CDBManager::getInstance()->getDbProp(propName)->setValue64(slot);
3514 // Force to update properties.
3515 EntitiesMngr.updateVisualProperty(0, mount, CLFECOMMON::PROPERTY_RIDER_ENTITY_ID);
3516 // Set the database.
3517 propName = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_ENTITY_MOUNTED_ID);
3518 NLGUI::CDBManager::getInstance()->getDbProp(propName)->setValue64(mount);
3519 // Force to update properties.
3520 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_ENTITY_MOUNTED_ID);
3521 return true;
3524 NLMISC_COMMAND(mount, "Set the entity to mount","<Slot> [<Mount>]")
3526 CLFECOMMON::TCLEntityId slot;
3527 CLFECOMMON::TCLEntityId mount = CLFECOMMON::INVALID_SLOT;
3529 switch(args.size())
3531 case 2:
3532 fromString(args[1], mount);
3533 case 1:
3534 fromString(args[0], slot);
3535 break;
3537 default:
3538 return false;
3539 break;
3542 // Set the database.
3543 string propName = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_ENTITY_MOUNTED_ID);
3544 NLGUI::CDBManager::getInstance()->getDbProp(propName)->setValue64(mount);
3545 // Force to update properties.
3546 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_ENTITY_MOUNTED_ID);
3548 // Command well done
3549 return true;
3552 NLMISC_COMMAND(rider, "Set the rider","<Slot> [<rider>]")
3554 CLFECOMMON::TCLEntityId slot;
3555 CLFECOMMON::TCLEntityId rider = CLFECOMMON::INVALID_SLOT;
3557 switch(args.size())
3559 case 2:
3560 fromString(args[1], rider);
3561 case 1:
3562 fromString(args[0], slot);
3563 break;
3565 default:
3566 return false;
3567 break;
3570 // Set the database.
3571 string propName = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_RIDER_ENTITY_ID);
3572 NLGUI::CDBManager::getInstance()->getDbProp(propName)->setValue64(rider);
3573 // Force to update properties.
3574 EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_RIDER_ENTITY_ID);
3576 // Command well done
3577 return true;
3580 NLMISC_COMMAND(disbandConvoy, "disband current beasts convoy", "")
3582 // no parameter needed
3584 // Create the message for the server
3585 CBitMemStream out;
3586 if(GenericMsgHeaderMngr.pushNameToStream("ANIMALS:DISBAND_CONVOY", out))
3588 NetMngr.push(out);
3590 else
3591 nlwarning("command : unknown message name : 'ANIMALS:DISBAND_CONVOY'");
3593 return true;
3596 NLMISC_COMMAND(learnAllBrick, "learn all bricks (only in local mode)", "")
3598 CInterfaceManager *pIM= CInterfaceManager::getInstance();
3599 uint i=0;
3600 for(;;)
3602 CCDBNodeLeaf * node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:BRICK_FAMILY:%d:BRICKS", i), false);
3603 if(node)
3604 node->setValue64(SINT64_CONSTANT(0xFFFFFFFFFFFFFFFF));
3605 else
3606 break;
3607 i++;
3609 return true;
3612 NLMISC_COMMAND(learnBrick, "learn a specified brick (only in local mode)", "<brick number or name>")
3614 CInterfaceManager *pIM= CInterfaceManager::getInstance();
3615 CSBrickManager *pBM= CSBrickManager::getInstance();
3617 if(args.size()<1)
3618 return false;
3620 // translate to brick sheet id
3621 CSheetId brickSheetId;
3622 uint testId;
3623 fromString(args[0], testId);
3624 if(testId!=0)
3626 brickSheetId= CSheetId(testId);
3628 else
3630 string str= args[0];
3631 if(str.find(".sbrick")==string::npos)
3632 str+= ".sbrick";
3633 brickSheetId.buildSheetId(str);
3636 // get the brick sheet
3637 CSBrickSheet *brick= pBM->getBrick(brickSheetId);
3638 if(!brick)
3640 pIM->displaySystemInfo(toString("brick '%s' not found", args[0].c_str()));
3641 return false;
3644 // force learn it.
3645 CCDBNodeLeaf * node= pBM->getKnownBrickBitFieldDB(brick->BrickFamily);
3646 if(node)
3648 uint64 flags= node->getValue64();
3649 flags|= uint64(1)<<(brick->IndexInFamily-1);
3650 node->setValue64(flags);
3652 return true;
3655 NLMISC_COMMAND(learnPhrase, "learn all bricks of a specified phrase (only in local mode)", "<phrase sheetId or name>")
3657 CInterfaceManager *pIM= CInterfaceManager::getInstance();
3658 CSBrickManager *pBM= CSBrickManager::getInstance();
3659 CSPhraseManager *pPM= CSPhraseManager::getInstance();
3661 if(args.size()<1)
3662 return false;
3664 // translate to brick sheet id
3665 CSheetId phraseSheetId;
3666 uint testId;
3667 fromString(args[0], testId);
3668 if(testId!=0)
3670 phraseSheetId= CSheetId(testId);
3672 else
3674 string str= args[0];
3675 if(str.find(".sphrase")==string::npos)
3676 str+= ".sphrase";
3677 phraseSheetId.buildSheetId(str);
3680 // get the brick sheet
3681 CSPhraseCom phrase;
3682 pPM->buildPhraseFromSheet(phrase, phraseSheetId.asInt());
3683 if(phrase.empty())
3685 pIM->displaySystemInfo(toString("phrase '%s' not found", args[0].c_str()));
3686 return false;
3689 // For all bricks of this phrase
3690 for(uint i=0;i<phrase.Bricks.size();i++)
3692 CSBrickSheet *brick= pBM->getBrick(phrase.Bricks[i]);
3693 if(brick)
3695 // force learn it.
3696 CCDBNodeLeaf * node= pBM->getKnownBrickBitFieldDB(brick->BrickFamily);
3697 if(node)
3699 uint64 flags= node->getValue64();
3700 flags|= uint64(1)<<(brick->IndexInFamily-1);
3701 node->setValue64(flags);
3706 return true;
3709 /*NLMISC_COMMAND(xp, "To gain XP in a given Skill","<Amount Xp> <Skill> [<Speciality>]")
3711 // Check parameters.
3712 if( args.size() < 2 || args.size() > 3 )
3713 return false;
3715 CBitMemStream out;
3716 if(GenericMsgHeaderMngr.pushNameToStream("CHEAT:XP", out))
3718 uint32 xp;
3719 fromString(args[0], xp);
3720 string skill = args[1];
3721 string speciality;
3722 if( args.size() == 3 )
3723 speciality = args[2];
3724 out.serial( xp );
3725 out.serial( skill );
3726 out.serial( speciality );
3727 // Add the message to the send list.
3728 NetMngr.push(out);
3729 // send CHEAT:XP
3730 nlinfo("command 'xp': CHEAT:XP pushed");
3732 else
3733 nlwarning("command 'xp': unknown message named 'CHEAT:XP'");
3735 // Done.
3736 return true;
3739 NLMISC_COMMAND(money, "To earn Money (only in local mode)","<very big seed> [<big seed>] [<medium seed>] [<small seed>]")
3741 if (args.size() != 1) return false;
3742 uint64 money;
3743 fromString(args[0], money);
3744 CInterfaceManager *im = CInterfaceManager::getInstance();
3745 NLGUI::CDBManager::getInstance()->getDbProp("SERVER:INVENTORY:MONEY")->setValue64(money);
3746 return true;
3748 sint32 a = 0;
3749 sint32 b = 0;
3750 sint32 c = 0;
3751 sint32 d = 0;
3753 // Check parameters.
3754 switch(args.size())
3756 case 4:
3757 fromString(args[3], d);
3758 case 3:
3759 fromString(args[2], c);
3760 case 2:
3761 fromString(args[1], b);
3762 case 1:
3763 fromString(args[0], a);
3764 break;
3765 default:
3766 return false;
3769 CInterfaceManager *im = CInterfaceManager::getInstance();
3770 string ls = im->getDefine("money_1");
3771 string ms = im->getDefine("money_2");
3772 string bs = im->getDefine("money_3");
3773 string vbs = im->getDefine("money_4");
3774 NLGUI::CDBManager::getInstance()->getDbProp(ls + ":QUANTITY")->setValue32(a);
3775 NLGUI::CDBManager::getInstance()->getDbProp(ms + ":QUANTITY")->setValue32(b);
3776 NLGUI::CDBManager::getInstance()->getDbProp(bs + ":QUANTITY")->setValue32(c);
3777 NLGUI::CDBManager::getInstance()->getDbProp(vbs + ":QUANTITY")->setValue32(d);
3778 return true;
3782 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)>" )
3784 // Check parameters.
3785 if(args.size() < 5) return false;
3787 // read params
3788 string characterName = args[0];
3789 EGSPD::CPeople::TPeople race = EGSPD::CPeople::fromString( args[1] );
3790 if( race == EGSPD::CPeople::EndPeople ) return false;
3792 GSGENDER::EGender gender = GSGENDER::stringToEnum( args[2] );
3793 if( gender == GSGENDER::unknown ) return false;
3795 ROLES::ERole role = ROLES::toRoleId( args[3] );
3796 if( role == ROLES::role_unknown ) return false;
3798 uint16 level;
3799 fromString(args[4], level);
3801 CBitMemStream bms;
3802 const char *msgType = "CHEAT:CREATE_CHARACTER";
3803 if( GenericMsgHeaderMngr.pushNameToStream(msgType,bms) )
3805 bms.serial( characterName );
3806 bms.serialEnum( race );
3807 bms.serialEnum( gender );
3808 bms.serialEnum( role );
3809 bms.serial( level );
3810 NetMngr.push( bms );
3811 nldebug("<create_perso> sending 'CHEAT:CREATE_CHARACTER' message to server");
3813 else
3815 nlwarning("<create_perso> unknown message name : CHEAT:CREATE_CHARACTER");
3817 return true;
3821 NLMISC_COMMAND( add_role, "add role to character", "<Role( MeleeFighter, RangeFighter, AttackCaster, BufferCaster, HealerCaster...), Level (1-25 (but more accepted))>" )
3823 // Check parameters.
3824 if(args.size() < 2) return false;
3826 ROLES::ERole role = ROLES::toRoleId( args[0] );
3827 if( role == ROLES::role_unknown ) return false;
3829 uint16 level;
3830 fromString(args[1], level);
3832 CBitMemStream bms;
3833 const char *msgType = "CHEAT:ADD_ROLE";
3834 if( GenericMsgHeaderMngr.pushNameToStream(msgType,bms) )
3836 bms.serialEnum( role );
3837 bms.serial( level );
3838 NetMngr.push( bms );
3839 nldebug("<add_role> sending 'CHEAT:ADD_ROLE' message to server");
3841 else
3843 nlwarning("<add_role> unknown message name : CHEAT:ADD_ROLE");
3845 return true;
3849 NLMISC_COMMAND(test, "", "")
3851 sint64 x, y, z;
3852 CLFECOMMON::TCLEntityId entSlot = UserEntity->selection();
3853 CEntityCL *entPtr = EntitiesMngr.entity(entSlot);
3854 if(entPtr)
3856 if(entPtr->skeleton())
3858 if(entPtr->skeleton()->getLastClippedState())
3860 NLMISC::CMatrix mat = entPtr->skeleton()->getLastWorldMatrixComputed();
3861 NLMISC::CVectorD newPos = entPtr->pos() + mat.getJ()*0.5f;
3862 x = (sint64)(newPos.x*1000.0);
3863 y = (sint64)(newPos.y*1000.0);
3864 z = (sint64)(newPos.z*1000.0);
3865 IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSX), x);
3866 IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSY), y);
3867 IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSZ), z);
3868 entPtr->updateVisualProperty(NetMngr.getCurrentServerTick(), CLFECOMMON::PROPERTY_POSITION);
3870 x = (sint64)(entPtr->pos().x*1000.0);
3871 y = (sint64)(entPtr->pos().y*1000.0);
3872 z = (sint64)(entPtr->pos().z*1000.0);
3873 IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSX), x);
3874 IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSY), y);
3875 IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSZ), z);
3876 entPtr->updateVisualProperty(NetMngr.getCurrentServerTick()+5, CLFECOMMON::PROPERTY_POSITION);
3880 return true;
3883 NLMISC_COMMAND(testLongBubble, "To display a bubble with a long text", "<entity>")
3885 if (args.size() != 1) return false;
3886 uint entityId;
3887 fromString(args[0], entityId);
3889 CInterfaceManager *pIM = CInterfaceManager::getInstance();
3890 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");
3891 uint duration = CWidgetManager::getInstance()->getSystemOption(CWidgetManager::OptionTimeoutBubbles).getValSInt32();
3893 CEntityCL *entity = EntitiesMngr.entity(entityId);
3894 if (entity)
3895 InSceneBubbleManager.chatOpen(entity->dataSetId(), text, duration);
3897 return true;
3901 //-----------------------------------------------
3902 /// Macro to set the new dist to front(back or side) for a given sheet.
3903 /// commandName : Name of the command.
3904 /// variableName : Variable Name to change.
3905 //-----------------------------------------------
3906 #define DIST_TO_COMMAND(commandName, variableName) \
3907 /* Check Parameters */ \
3908 if(args.size() != 2) \
3910 nlwarning("Command '" #commandName "': need 2 parameters, try '/help " #commandName "' for more details."); \
3911 return false; \
3914 /* Try to create the sheet with the parameter as a string. */ \
3915 CSheetId sheetId; \
3916 if(!sheetId.buildSheetId(args[0])) \
3918 /* Try to create the sheet with the parameter as an int. */ \
3919 uint32 nSheetId; \
3920 fromString(args[0], nSheetId); \
3921 sheetId = CSheetId(nSheetId); \
3922 if(sheetId == CSheetId::Unknown) \
3924 nlwarning("Command '" #commandName "': '%s' is not a valid form.", args[0].c_str()); \
3925 return false; \
3929 /* Get the new distance. */ \
3930 float dist; \
3931 fromString(args[1], dist); \
3932 if(dist < 0) \
3934 nlwarning("Command '" #commandName "': distance < 0, this is not good."); \
3935 return false; \
3938 CCharacterSheet *ch = dynamic_cast<CCharacterSheet *>(SheetMngr.get(sheetId)); \
3939 if(ch == 0) \
3941 nlwarning("Command '" #commandName "': cannot find the character for the given sheet."); \
3942 return false; \
3945 /* Set the new distance for this sheet. */ \
3946 ch->variableName = dist; \
3948 /* Well Done */ \
3949 return true; \
3951 //-----------------------------------------------
3952 // 'dist2front' : Change the distance to the front for a given sheet.
3953 //-----------------------------------------------
3954 NLMISC_COMMAND(dist2front, "Change the distance to the front for a given sheet.", "<form> <dist>")
3956 DIST_TO_COMMAND(dist2front, DistToFront);
3959 //-----------------------------------------------
3960 // 'dist2back' : Change the distance to the back for a given sheet.
3961 //-----------------------------------------------
3962 NLMISC_COMMAND(dist2back, "Change the distance to the back for a given sheet.", "<form> <dist>")
3964 DIST_TO_COMMAND(dist2back, DistToBack);
3967 //-----------------------------------------------
3968 // 'dist2side' : Change the distance to the side for a given sheet.
3969 //-----------------------------------------------
3970 NLMISC_COMMAND(dist2side, "Change the distance to the side for a given sheet.", "<form> <dist>")
3972 DIST_TO_COMMAND(dist2side, DistToSide);
3977 // Change the parent of an entity. 'parent slot' not defined remove the current parent.
3978 NLMISC_COMMAND(parent, "Change the parent of an entity.", "<slot> [<parent slot>]")
3980 CLFECOMMON::TCLEntityId parentSlot = CLFECOMMON::INVALID_SLOT;
3982 // Check parameters.
3983 switch(args.size())
3985 // Set the target for the entity.
3986 case 2:
3987 fromString(args[1], parentSlot);
3989 // Remove the target for the entity.
3990 case 1:
3992 uint entitySlot;
3993 fromString(args[0], entitySlot);
3994 CEntityCL *entity = EntitiesMngr.entity(entitySlot);
3995 if(entity)
3997 entity->parent(parentSlot);
3998 entity->pos(CVectorD::Null);
4000 else
4001 nlwarning("command 'parent': there is no entity in the slot %d", entitySlot);
4003 break;
4005 // Bad command.
4006 default:
4007 return false;
4010 // Well done.
4011 return true;
4014 NLMISC_COMMAND(displayInventoryCounter, "display the Inventory counter to compare with db counter", "")
4017 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4019 uint srvVal= NLGUI::CDBManager::getInstance()->getDbProp("SERVER:INVENTORY:COUNTER")->getValue32();
4020 uint locVal= pIM->getLocalSyncActionCounter() ;
4021 srvVal&= pIM->getLocalSyncActionCounterMask();
4022 locVal&= pIM->getLocalSyncActionCounterMask();
4024 pIM->displaySystemInfo("ServerCounter: " + toString(srvVal) + "/ LocalCounter: " + toString(locVal));
4026 // Well done.
4027 return true;
4031 NLMISC_COMMAND(displayActionCounter, "display the action counters", "")
4033 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4034 CSPhraseManager *pPM= CSPhraseManager::getInstance();
4036 // next
4037 uint srvVal= NLGUI::CDBManager::getInstance()->getDbProp(PHRASE_DB_COUNTER_NEXT)->getValue32();
4038 uint locVal= pPM->getPhraseNextExecuteCounter() ;
4039 srvVal&= PHRASE_EXECUTE_COUNTER_MASK;
4040 locVal&= PHRASE_EXECUTE_COUNTER_MASK;
4042 pIM->displaySystemInfo("NextCounter: " + toString(srvVal) + "/ LocalCounter: " + toString(locVal));
4044 // cycle
4045 srvVal= NLGUI::CDBManager::getInstance()->getDbProp(PHRASE_DB_COUNTER_CYCLE)->getValue32();
4046 locVal= pPM->getPhraseCycleExecuteCounter() ;
4047 srvVal&= PHRASE_EXECUTE_COUNTER_MASK;
4048 locVal&= PHRASE_EXECUTE_COUNTER_MASK;
4050 pIM->displaySystemInfo("CycleCounter: " + toString(srvVal) + "/ LocalCounter: " + toString(locVal));
4052 return true;
4055 NLMISC_COMMAND( reconnect, "Reconnect to the same shard (self Far TP)", "")
4057 // If the server is up, the egs will begin the quit sequence (shortened only if we are in edition or animation mode).
4058 // If the server is down or frozen, a second /reconnect will be necessary to make the client reconnect
4059 // but if you reconnect before letting the EGS save the character file, the previous saved file will be loaded.
4060 switch ( LoginSM.getCurrentState() )
4062 case CLoginStateMachine::st_ingame:
4063 LoginSM.pushEvent( CLoginStateMachine::ev_connect );
4064 break;
4065 case CLoginStateMachine::st_leave_shard:
4066 FarTP.onServerQuitOk();
4067 break;
4068 default:
4069 log.displayNL( "Can't reconnect from LoginSM state %u", (uint)LoginSM.getCurrentState() );
4072 return true;
4075 struct CItemSheetSort
4077 const CItemSheet *IS;
4078 CSheetId ID;
4079 ITEMFAMILY::EItemFamily Family;
4082 static inline bool operator < (const CItemSheetSort &lhs, const CItemSheetSort &rhs)
4084 return lhs.Family < rhs.Family;
4087 NLMISC_COMMAND(dumpItems, "Sort items by category & display their sheet ids", "")
4089 std::vector<CItemSheetSort> isVect;
4090 const CSheetManager::TEntitySheetMap &sheets = SheetMngr.getSheets();
4091 for(CSheetManager::TEntitySheetMap::const_iterator it = sheets.begin(); it != sheets.end(); ++it)
4093 const CEntitySheet *es = it->second.EntitySheet;
4094 if (es && es->type() == CEntitySheet::ITEM)
4096 CItemSheetSort iss;
4097 iss.IS = static_cast<const CItemSheet *>(es);
4098 iss.ID = it->first;
4099 iss.Family = iss.IS->Family;
4100 isVect.push_back(iss);
4104 // sort items
4105 std::sort(isVect.begin(), isVect.end());
4107 for(std::vector<CItemSheetSort>::iterator itemIt = isVect.begin(); itemIt != isVect.end(); ++itemIt)
4109 std::string info;
4110 info = "FAMILY: ";
4111 info += ITEMFAMILY::toString(itemIt->Family);
4112 info += "; Name = ";
4113 info += itemIt->IS->Id.toString();
4114 info += "; Sheet ID = ";
4115 info += toString(itemIt->ID.asInt());
4116 nlwarning(info.c_str());
4118 return true;
4121 NLMISC_COMMAND(dumpVisualSlots, "dump the visual slots", "")
4123 if (!args.empty()) return false;
4124 SheetMngr.dumpVisualSlots();
4125 SheetMngr.dumpVisualSlotsIndex();
4126 return true;
4129 NLMISC_COMMAND(skillToInt, "Convert a skill to an int", "")
4131 if (args.size() != 1) return false;
4132 CInterfaceManager *im = CInterfaceManager::getInstance();
4133 im->displaySystemInfo(toString((uint) SKILLS::toSkill(args[0])));
4134 return true;
4137 NLMISC_COMMAND(browse, "Browse a HTML document with the internal help web browser.", "")
4139 if (args.size() != 1) return false;
4140 CInterfaceManager *im = CInterfaceManager::getInstance();
4141 CAHManager::getInstance()->runActionHandler("browse", NULL, "name=ui:interface:help_browser:content:html|url="+args[0]);
4142 return true;
4145 NLMISC_COMMAND(openRingWindow, "Browse the main page in the ring web browser.", "")
4147 CInterfaceManager *im = CInterfaceManager::getInstance();
4148 CAHManager::getInstance()->runActionHandler("browse", NULL, "name=ui:interface:r2ed_web_admin:content:admin_web_page|url="+RingMainURL);
4149 return true;
4152 NLMISC_COMMAND(browseRingAdmin, "Browse a HTML document with the ring web browser.", "")
4154 if (args.size() != 1) return false;
4155 CInterfaceManager *im = CInterfaceManager::getInstance();
4156 CAHManager::getInstance()->runActionHandler("browse", NULL, "name=ui:interface:r2ed_web_admin:content:admin_web_page|url="+args[0]);
4157 return true;
4160 NLMISC_COMMAND(GUCreate, "create a guild", "<guild name>")
4162 if (args.size() != 1) return false;
4163 const char *msgName = "GUILD:CREATE";
4164 CBitMemStream out;
4165 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4167 ucstring buf = ucstring::makeFromUtf8(args[0]); // FIXME: UTF-8 (serial)
4168 out.serial( buf );
4169 NetMngr.push(out);
4171 return true;
4174 NLMISC_COMMAND(GUQuit, "quit a guild", "")
4176 if (args.size() != 0) return false;
4177 const char *msgName = "GUILD:QUIT";
4178 CBitMemStream out;
4179 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4181 NetMngr.push(out);
4183 return true;
4186 NLMISC_COMMAND(GULeaveLeadership, "abandon leadership of a guild", "")
4188 if (args.size() != 0) return false;
4189 const char *msgName = "GUILD:ABANDON_LEADERSHIP";
4190 CBitMemStream out;
4191 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4193 NetMngr.push(out);
4195 return true;
4197 NLMISC_COMMAND(GULeaveOfficerTitle, "abandon officer title", "")
4199 if (args.size() != 0) return false;
4200 const char *msgName = "GUILD:ABANDON_OFFICER_TITLE";
4201 CBitMemStream out;
4202 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4204 NetMngr.push(out);
4206 return true;
4209 NLMISC_COMMAND(GUNameOfficer, "name an officer", "<player name>")
4211 if (args.size() != 1) return false;
4212 const char *msgName = "GUILD:NAME_OFFICER";
4213 CBitMemStream out;
4214 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4216 string buf = args[0];
4217 out.serial( buf );
4218 NetMngr.push(out);
4220 return true;
4223 NLMISC_COMMAND(GUDismissOfficer, "dismiss an officer", "<player name>")
4225 if (args.size() != 1) return false;
4226 const char *msgName = "GUILD:DISMISS_OFFICER";
4227 CBitMemStream out;
4228 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4230 string buf = args[0];
4231 out.serial( buf );
4232 NetMngr.push(out);
4234 return true;
4237 NLMISC_COMMAND(GUKick, "kick a member", "<player name>")
4239 if (args.size() != 1) return false;
4240 const char *msgName = "GUILD:KICK_MEMBER";
4241 CBitMemStream out;
4242 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4244 string buf = args[0];
4245 out.serial( buf );
4246 NetMngr.push(out);
4248 return true;
4252 NLMISC_COMMAND(GUAccept, "accept an invitation", "")
4254 CAHManager::getInstance()->runActionHandler("accept_guild_invitation",NULL);
4255 return true;
4258 NLMISC_COMMAND(GURefuse, "refuse an invitation", "")
4260 CAHManager::getInstance()->runActionHandler("refuse_guild_invitation",NULL);
4261 return true;
4264 NLMISC_COMMAND(GUFriend, "invite a player to become a friend of the guild", "<player name>")
4266 if (args.size() != 1) return false;
4267 const char *msgName = "GUILD:FRIEND_INVITATION";
4268 CBitMemStream out;
4269 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4271 string buf = args[0];
4272 out.serial( buf );
4273 NetMngr.push(out);
4275 return true;
4278 NLMISC_COMMAND(GUFriendAccept, "accept to be a friend of a guild that invited you", "")
4280 if (args.size() != 0) return false;
4281 const char *msgName = "GUILD:ACCEPT_FRIEND_INVITATION";
4282 CBitMemStream out;
4283 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4285 NetMngr.push(out);
4287 return true;
4290 NLMISC_COMMAND(GUFriendRefuse, "refuse to be a friend of a guild that invited you", "")
4292 if (args.size() != 0) return false;
4293 const char *msgName = "GUILD:REFUSE_FRIEND_INVITATION";
4294 CBitMemStream out;
4295 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4297 NetMngr.push(out);
4299 return true;
4302 NLMISC_COMMAND(GUSetSuccessor, "set the successor of the guild leader", "<player name>")
4304 if (args.size() != 1) return false;
4305 const char *msgName = "GUILD:SET_SUCCESSOR";
4306 CBitMemStream out;
4307 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4309 string buf = args[0];
4310 out.serial( buf );
4311 NetMngr.push(out);
4313 return true;
4316 NLMISC_COMMAND(GUInfos, "get information on a guild", "<guild name>")
4318 if (args.size() != 1) return false;
4319 const char *msgName = "GUILD:GET_INFOS";
4320 CBitMemStream out;
4321 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4323 string buf = args[0];
4324 out.serial( buf );
4325 NetMngr.push(out);
4327 return true;
4330 NLMISC_COMMAND(GUJournal, "get the guild journal", "")
4332 if (args.size() != 0) return false;
4333 const char *msgName = "GUILD:GET_LOG";
4334 CBitMemStream out;
4335 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4337 NetMngr.push(out);
4339 return true;
4342 NLMISC_COMMAND(buildingTeleport, "teleport to a building", "building index")
4344 if (args.size() != 1) return false;
4345 uint16 index;
4346 fromString(args[0], index);
4347 const char *msgName = "GUILD:TELEPORT";
4348 CBitMemStream out;
4349 if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
4351 out.serial(index);
4352 NetMngr.push(out);
4354 return true;
4357 NLMISC_COMMAND(logFaberMpCompatibles, "log all MP compatibles for faber the item", "sheetid")
4359 if (args.size() != 1) return false;
4360 uint32 sheetId;
4361 fromString(args[0], sheetId);
4362 CSBrickManager *pBM= CSBrickManager::getInstance();
4364 // get the faber plan
4365 CSBrickSheet *brick= pBM->getBrick(CSheetId(sheetId));
4366 // get the origin of the item built
4367 CItemSheet *itemBuilt= NULL;
4368 if(brick)
4369 itemBuilt= dynamic_cast<CItemSheet*>(SheetMngr.get(brick->FaberPlan.ItemBuilt));
4370 if(brick && itemBuilt)
4373 // build array of MP sheetId
4374 std::vector<CItemSheet*> mps;
4375 mps.reserve(100);
4376 const CSheetManager::TEntitySheetMap &sheetMap= SheetMngr.getSheets();
4377 CSheetManager::TEntitySheetMap::const_iterator it;
4378 for(it= sheetMap.begin(); it!=sheetMap.end(); it++)
4380 CItemSheet *mp= const_cast<CItemSheet*>( dynamic_cast<const CItemSheet*>(it->second.EntitySheet) );
4381 if(mp && mp->Family == ITEMFAMILY::RAW_MATERIAL)
4382 mps.push_back(mp);
4385 // header
4386 uint numMpSlots= (uint)brick->FaberPlan.ItemPartMps.size();
4387 nlinfo("********** FABERLOG **********");
4388 nlinfo(" ItemBuilt Origin: %s", ITEM_ORIGIN::enumToString(itemBuilt->ItemOrigin).c_str() );
4389 nlinfo(" NumMPSlot: %d", numMpSlots);
4391 // Parse All Slots.
4392 for(uint i=0;i<numMpSlots;i++)
4394 CSBrickSheet::CFaberPlan::CItemPartMP &mpSlot= brick->FaberPlan.ItemPartMps[i];
4395 nlinfo(" MPSlot %d", i);
4396 nlinfo(" Quantity: %d", mpSlot.Quantity);
4397 nlinfo(" TypeReq: %s", RM_FABER_TYPE::toString(mpSlot.FaberTypeFilter).c_str() );
4398 nlinfo(" List Of Compatibles MPs:");
4400 for(uint i=0;i<mps.size();i++)
4402 CItemSheet *itemSheet= mps[i];
4403 bool ok= true;
4404 // check faber type filter
4405 if( mpSlot.FaberTypeFilter!=RM_FABER_TYPE::Unknown && !itemSheet->canBuildItemPart(mpSlot.FaberTypeFilter, itemBuilt->ItemOrigin))
4406 ok= false;
4408 if(ok)
4410 nlinfo(" %s", itemSheet->Id.toString().c_str() );
4417 return true;
4420 NLMISC_COMMAND(debugItemInfo, "simulate a ItemInfo received from server", "itemSlotId version [enchant]")
4422 CItemInfos itemInfo;
4424 if (args.size() < 2 || args.size() > 3) return false;
4425 bool enchant= false;
4426 if(args.size()==3)
4427 fromString(args[2], enchant);
4429 fromString(args[0], itemInfo.slotId);
4430 fromString(args[1], itemInfo.versionInfo);
4432 itemInfo.CurrentDamage= 10;
4433 itemInfo.MaxDamage= 15;
4434 itemInfo.DodgeModifier= 5;
4435 itemInfo.ParryModifier= -10;
4436 itemInfo.AdversaryDodgeModifier= 666;
4437 itemInfo.AdversaryParryModifier= 333;
4438 itemInfo.HpBuff= 12;
4439 itemInfo.SapBuff= -14;
4440 itemInfo.StaBuff= 0;
4441 itemInfo.FocusBuff= 1;
4442 itemInfo.MagicProtection[0]= PROTECTION_TYPE::Electricity;
4443 itemInfo.MagicProtectionFactor[0]= 43;
4444 itemInfo.MagicProtection[1]= PROTECTION_TYPE::Shockwave;
4445 itemInfo.MagicProtectionFactor[1]= 21;
4446 itemInfo.MagicProtection[2]= PROTECTION_TYPE::Rot;
4447 itemInfo.MagicProtectionFactor[2]= 100;
4448 itemInfo.DesertMagicResistance= 133;
4449 itemInfo.ForestMagicResistance= 500;
4450 itemInfo.PrimaryRootMagicResistance= 341;
4451 itemInfo.Hp= 66;
4452 itemInfo.HpMax= 100;
4453 itemInfo.Range= 169;
4454 itemInfo.SapLoadCurrent= 6;
4455 itemInfo.SapLoadMax= 30;
4456 itemInfo.HitRate= 8;
4457 itemInfo.ProtectionFactor= 0.25;
4458 itemInfo.MaxSlashingProtection= 38;
4459 itemInfo.MaxPiercingProtection= 48;
4460 itemInfo.MaxBluntProtection= 58;
4461 itemInfo.WearEquipmentMalus= 0.31f;
4463 if(enchant)
4465 itemInfo.Enchantment.Name="pipoSort";
4466 itemInfo.Enchantment.Bricks.resize(3);
4467 itemInfo.Enchantment.Bricks[0]= CSheetId("bmpa01.sbrick");
4468 itemInfo.Enchantment.Bricks[1]= CSheetId("bmlchea01.sbrick");
4469 itemInfo.Enchantment.Bricks[2]= CSheetId("bmlchmh00005.sbrick");
4472 switch(rand()%4)
4474 case 0:
4475 break;
4476 case 1:
4478 itemInfo.CastingSpeedFactor[1]= 1.0f;
4479 itemInfo.MagicPowerFactor[1]= 0.2f;
4481 break;
4482 case 2:
4484 itemInfo.CastingSpeedFactor[0]= 0.4f;
4485 itemInfo.MagicPowerFactor[0]= 0.2f;
4486 itemInfo.CastingSpeedFactor[2]= 0.8f;
4487 itemInfo.MagicPowerFactor[2]= 0.3f;
4489 break;
4490 case 3:
4492 itemInfo.CastingSpeedFactor[0]= 0.3f;
4493 itemInfo.MagicPowerFactor[0]= 0.3f;
4494 itemInfo.CastingSpeedFactor[1]= 0.3f;
4495 itemInfo.MagicPowerFactor[1]= 0.3f;
4496 itemInfo.CastingSpeedFactor[2]= 0.3f;
4497 itemInfo.MagicPowerFactor[2]= 0.3f;
4498 itemInfo.CastingSpeedFactor[3]= 0.3f;
4499 itemInfo.MagicPowerFactor[3]= 0.3f;
4501 break;
4505 getInventory().onReceiveItemInfo(itemInfo);
4507 return true;
4510 NLMISC_COMMAND(debugItemInfoWaiters, "log ItemInfoWaiters", "")
4512 getInventory().debugItemInfoWaiters();
4514 return true;
4517 NLMISC_COMMAND(debugItemInfoCache, "log ItemInfoCache", "")
4519 getInventory().debugItemInfoCache();
4521 return true;
4524 NLMISC_COMMAND(debugInfoWindows, "log info windows sheetId", "")
4526 CInterfaceHelp::debugOpenedInfoWindows();
4528 return true;
4531 NLMISC_COMMAND(getSkillValue, "get a skill value by its name", "skill_name")
4533 if (args.size() != 1) return false;
4534 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4535 uint skillId= (uint) SKILLS::toSkill(args[0]);
4536 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:SKILL", skillId), false);
4537 if(node)
4539 pIM->displaySystemInfo(toString(node->getValue32()));
4542 return true;
4545 NLMISC_COMMAND(setSkillValue, "set a skill value by its name", "skill_name value")
4547 if (args.size() != 2) return false;
4548 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4549 uint skillId= (uint) SKILLS::toSkill(args[0]);
4550 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:SKILL", skillId), false);
4551 if(node)
4553 sint32 value;
4554 fromString(args[1], value);
4555 node->setValue32(value);
4558 return true;
4561 NLMISC_COMMAND(getBaseSkillValue, "get a baseskill value by its name", "skill_name")
4563 if (args.size() != 1) return false;
4564 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4565 uint skillId= (uint) SKILLS::toSkill(args[0]);
4566 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:BaseSKILL", skillId), false);
4567 if(node)
4569 pIM->displaySystemInfo(toString(node->getValue32()));
4572 return true;
4575 NLMISC_COMMAND(setBaseSkillValue, "set a baseskill value by its name", "skill_name value")
4577 if (args.size() != 2) return false;
4578 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4579 uint skillId= (uint) SKILLS::toSkill(args[0]);
4580 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:BaseSKILL", skillId), false);
4581 if(node)
4583 sint32 value;
4584 fromString(args[1], value);
4585 node->setValue32(value);
4588 return true;
4591 NLMISC_COMMAND(setAllSkillValue, "set all Skill and baseskill to the given value", "value")
4593 if (args.size() != 1) return false;
4594 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4595 uint value;
4596 fromString(args[0], value);
4597 for(uint i=0;i<SKILLS::NUM_SKILLS;i++)
4599 CCDBNodeLeaf *node;
4600 node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:BaseSKILL", i), false);
4601 if(node)
4602 node->setValue32(value);
4603 node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:SKILL", i), false);
4604 if(node)
4605 node->setValue32(value);
4608 return true;
4611 NLMISC_COMMAND(setEntityName, "set a entity name id", "entitySlot nameId")
4613 if (args.size() != 2) return false;
4614 uint slot;
4615 fromString(args[0], slot);
4617 CCharacterCL *entity= dynamic_cast<CCharacterCL*>(EntitiesMngr.entity(slot));
4618 if(entity)
4620 uint32 nameId;
4621 fromString(args[1], nameId);
4622 entity->debugSetNameId(nameId);
4624 return true;
4627 NLMISC_COMMAND(reloadWeather, "reload the weather sheets", "")
4629 if (!args.empty()) return false;
4630 ContinentMngr.reloadWeather();
4631 return true;
4635 // Common method to reload sheets (hope it works later...)
4636 template<class T>
4637 bool reloadSheets(string filter, string wildcardFilter)
4639 CSheetManager sheetManager;
4640 std::vector<std::string> filters;
4641 filters.push_back(filter);
4642 ClientSheetsStrings.memoryUncompress();
4643 NLMISC::IProgressCallback progress;
4644 sheetManager.loadAllSheetNoPackedSheet(progress, filters, wildcardFilter);
4645 ClientSheetsStrings.memoryCompress();
4646 // copy sheets into current sheet manager (because numerous ptr are kept on the previous sheets in various places)
4647 const CSheetManager::TEntitySheetMap &sheetMap= sheetManager.getSheets();
4648 CSheetManager::TEntitySheetMap::const_iterator it;
4649 for(it=sheetMap.begin();it!=sheetMap.end();it++)
4651 T *dest = dynamic_cast<T*>(SheetMngr.get(it->first));
4652 if (dest)
4654 const T *src = dynamic_cast<T*>(it->second.EntitySheet);
4655 if (src)
4657 *dest = *src;
4661 return true;
4664 std::string extendWildcard(const std::string &in)
4666 string out;
4667 // append * at begin if not present (or if enp
4668 if(in.empty() || in[0]!='*')
4669 out= '*';
4670 out+= in;
4671 // append .* at end if no . found
4672 if(in.find('.')==string::npos)
4673 out+= ".*";
4674 return out;
4677 // macros to reload Sheets
4678 #define CMD_RELOAD_SHEET(_cmd_name, _filter, _type) \
4679 NLMISC_COMMAND(_cmd_name, #_cmd_name, "") \
4681 if (args.size()>1) return false; \
4682 string wildcardFilter; \
4683 if (args.size()>=1) \
4684 wildcardFilter= extendWildcard(args[0]); \
4685 return reloadSheets<_type>(_filter, wildcardFilter); \
4687 // Important ones
4688 CMD_RELOAD_SHEET(reloadCreature, "creature", CCharacterSheet)
4689 CMD_RELOAD_SHEET(reloadSbrick, "sbrick", CSBrickSheet)
4690 CMD_RELOAD_SHEET(reloadSphrase, "sphrase", CSPhraseSheet)
4691 CMD_RELOAD_SHEET(reloadSitem, "sitem", CItemSheet)
4692 // Not tested ones
4694 CMD_RELOAD_SHEET(reloadPlayer, "player", CPlayerSheet)
4695 CMD_RELOAD_SHEET(reloadFx, "fx", CFXSheet)
4696 CMD_RELOAD_SHEET(reloadBuilding, "building", CBuildingSheet)
4697 CMD_RELOAD_SHEET(reloadDeath_impact, "death_impact", CPactSheet)
4698 CMD_RELOAD_SHEET(reloadMission, "mission", CMissionSheet)
4699 CMD_RELOAD_SHEET(reloadRace_stats, "race_stats", CRaceStatsSheet)
4700 CMD_RELOAD_SHEET(reloadLight_cycle, "light_cycle", CLightCycleSheet)
4701 CMD_RELOAD_SHEET(reloadContinent, "continent", CContinentSheet)
4702 CMD_RELOAD_SHEET(reloadWorld, "world", CWorldSheet)
4703 CMD_RELOAD_SHEET(reloadMission_icon, "mission_icon", CMissionIconSheet)
4704 CMD_RELOAD_SHEET(reloadSkill_tree, "skill_tree", CSkillsTreeSheet)
4705 CMD_RELOAD_SHEET(reloadTitles, "titles", CUnblockTitlesSheet)
4706 CMD_RELOAD_SHEET(reloadSucces_chances_table, "succes_chances_table", CSuccessTableSheet)
4707 CMD_RELOAD_SHEET(reloadAutomaton_list, "automaton_list", CAutomatonListSheet)
4708 CMD_RELOAD_SHEET(reloadAnimset_list, "animset_list", CAnimationSetListSheet)
4709 CMD_RELOAD_SHEET(reloadAnimation_fx, "animation_fx", CAnimationFXSheet)
4710 CMD_RELOAD_SHEET(reloadEmot, "emot", CEmotListSheet)
4711 CMD_RELOAD_SHEET(reloadForage_source, "forage_source", CForageSourceSheet)
4712 CMD_RELOAD_SHEET(reloadText_emotes, "text_emotes", CTextEmotListSheet)
4715 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]")
4717 if(args.size()!=2 && args.size()!=3) return false;
4718 uint slot;
4719 fromString(args[0], slot);
4720 uint propId;
4721 fromString(args[1], propId);
4723 // set value in the DB?
4724 if(args.size()==3)
4726 sint64 val= 0;
4727 fromString(args[2], val);
4728 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4729 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:Entities:E%d:P%d", slot, propId), false);
4730 if(node)
4731 node->setValue64(val);
4734 EntitiesMngr.updateVisualProperty(0, slot, propId);
4736 return true;
4739 NLMISC_COMMAND(dataSetId, "Set the UID of an entity", "slot uid")
4741 if(args.size()!=2) return false;
4742 uint slot;
4743 fromString(args[0], slot);
4744 uint uid;
4745 fromString(args[1], uid);
4747 CEntityCL *entity= EntitiesMngr.entity(slot);
4748 if(!entity)
4749 return false;
4751 entity->dataSetId(uid);
4753 return true;
4756 NLMISC_COMMAND(forceDisplayFXBBoxes, "Force to display bboxes of all fxs", "0=off, 1=off")
4758 if (args.size() != 1) return false;
4759 bool on;
4760 fromString(args[0], on);
4761 UParticleSystemInstance::forceDisplayBBox(on);
4762 return true;
4765 NLMISC_COMMAND(dumpVillages, "Dump villages loading zones in a bitmap", "filename>")
4767 if (args.size() != 1) return false;
4768 ContinentMngr.cur()->dumpVillagesLoadingZones(args[0]);
4769 return true;
4772 NLMISC_COMMAND(dumpFogDayMap, "Dump fog day map", "filename>")
4774 if (args.size() != 1) return false;
4775 ContinentMngr.cur()->dumpFogMap(CFogMapBuild::Day, args[0]);
4776 return true;
4780 NLMISC_COMMAND(dumpFogDepthMap, "Dump fog depth map", "filename>")
4782 if (args.size() != 1) return false;
4783 ContinentMngr.cur()->dumpFogMap(CFogMapBuild::Depth, args[0]);
4784 return true;
4787 NLMISC_COMMAND(dumpFogDistMap, "Dump fog depth map", "filename>")
4789 if (args.size() != 1) return false;
4790 ContinentMngr.cur()->dumpFogMap(CFogMapBuild::Distance, args[0]);
4791 return true;
4794 NLMISC_COMMAND(dumpRainMap, "Dump fog rain map", "filename>")
4796 if (args.size() != 1) return false;
4797 CRGBA colorLookup[256];
4798 for(uint8 k = 1; k < 255; ++k)
4800 colorLookup[k] = CRGBA(k, k, k, 1);
4802 colorLookup[0] = CRGBA::Red;
4803 colorLookup[255] = CRGBA::Blue;
4804 ContinentMngr.cur()->dumpFogMap(CFogMapBuild::NoPrecipitation, args[0], CContinent::ChannelR, colorLookup);
4805 return true;
4809 NLMISC_COMMAND(stick_log, "", "<slot>")
4811 if(args.size()!=1)
4812 return false;
4813 CLFECOMMON::TCLEntityId slot;
4814 fromString(args[0], slot);
4816 // Compute the position.
4817 CEntityCL *entity = EntitiesMngr.entity(slot);
4818 if(!entity)
4819 return false;
4821 USkeleton *skel= entity->skeleton();
4822 if(skel)
4824 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4825 nlinfo("Skel Log: %s", skel->getShapeName().c_str());
4827 std::vector<UTransform> sticks;
4828 skel->getStickedObjects(sticks);
4830 nlinfo("StickedModels: %d", sticks.size());
4831 pIM->displaySystemInfo(toString("StickedModels: %d", sticks.size()));
4833 for(uint i=0;i<sticks.size();i++)
4835 UInstance inst;
4836 inst.cast(sticks[i]);
4837 if(!inst.empty())
4839 string str= toString(" %d: %X. %s", i, inst.getObjectPtr(), inst.getShapeName().c_str());
4840 nlinfo(str.c_str());
4841 pIM->displaySystemInfo(str);
4843 else
4845 string str= toString(" %d: %X. NOT a TransformShape", i, sticks[i].getObjectPtr());
4846 nlinfo(str.c_str());
4847 pIM->displaySystemInfo(str);
4852 return true;
4855 NLMISC_COMMAND(print_sys, "", "<cat> <str>")
4857 if(args.size()<1)
4858 return false;
4859 string cat= args[0];
4860 string str;
4861 for (uint i = 1; i < args.size(); i++)
4863 str += args[i] + " ";
4866 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4867 pIM->displaySystemInfo(str, cat);
4869 return true;
4872 NLMISC_COMMAND(fillAllInfoVersion, "", "<version>")
4874 if(args.size()!=1)
4875 return false;
4877 uint i,j;
4878 uint ver;
4879 fromString(args[0], ver);
4880 CInventoryManager &im= getInventory();
4882 // BAG
4883 for(i=0;i<MAX_BAGINV_ENTRIES;i++)
4884 im.getServerBagItem(i).setInfoVersion(ver);
4886 // PACK_ANIMAL
4887 for(j=0;j<MAX_PACK_ANIMAL;j++)
4889 for(i=0;i<MAX_ANIMALINV_ENTRIES;i++)
4890 im.getServerPAItem(j,i).setInfoVersion(ver);
4893 // EXCHANGE
4894 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4895 for(i=0;i<CPlayerTrade::NumTradeSlot;i++)
4897 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:EXCHANGE:GIVE:%d:INFO_VERSION", i), false);
4898 if(node)
4899 node->setValue32(ver);
4900 node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:EXCHANGE:RECEIVE:%d:INFO_VERSION", i), false);
4901 if(node)
4902 node->setValue32(ver);
4905 return true;
4908 NLMISC_COMMAND(fullFillInventory, "", "dbstring sheetName")
4910 if(args.size()!=2)
4911 return false;
4913 // read value
4914 sint64 value;
4915 if (isalpha(args[1][0]))
4917 CSheetId sheet(args[1]);
4918 value = (sint64) sheet.asInt();
4920 else
4922 // Convert the string into an sint64.
4923 fromString(args[1], value);
4926 // read db dest
4927 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4928 CCDBNodeBranch *nb= NLGUI::CDBManager::getInstance()->getDbBranch(args[0]);
4929 if(!nb)
4930 return false;
4932 uint num= nb->getNbNodes();
4933 for(uint i=0;i<num;i++)
4935 CCDBNodeLeaf *nl;
4936 nl= NLGUI::CDBManager::getInstance()->getDbProp(args[0]+":"+toString(i)+":SHEET", false);
4937 if(nl)
4939 nl->setValue64(value);
4940 nl= NLGUI::CDBManager::getInstance()->getDbProp(args[0]+":"+toString(i)+":QUALITY", false);
4941 if(nl)
4942 nl->setValue64(i);
4943 nl= NLGUI::CDBManager::getInstance()->getDbProp(args[0]+":"+toString(i)+":PREREQUISIT_VALID", false);
4944 if(nl)
4945 nl->setValue64(1);
4949 return true;
4952 NLMISC_COMMAND(fillAllItemPreReq, "", "dbstring value")
4954 if(args.size()!=2)
4955 return false;
4957 // read value
4958 sint32 value;
4959 fromString(args[1], value);
4960 string dbBase= args[0];
4962 // write prop for all elements of the branch
4963 uint index= 0;
4964 for(;;)
4966 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4967 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("%s:%d:PREREQUISIT_VALID", dbBase.c_str(), index), false);
4968 if(!node)
4969 break;
4970 node->setValue32(value);
4971 index++;
4974 return true;
4977 NLMISC_COMMAND(eventMusic, "", "music")
4979 if(args.size()<1 && args.size()>3)
4980 return false;
4982 string fileName= args[0].c_str();
4983 bool loop= false;
4984 if(args.size() > 1)
4985 fromString(args[1], loop);
4986 uint fadeTime= 1000;
4987 if(args.size() > 2)
4988 fromString(args[2], fadeTime);
4990 if(SoundMngr)
4991 SoundMngr->playEventMusic(fileName, fadeTime, loop);
4993 return true;
4997 NLMISC_COMMAND(setLightHour, "force the light hour, (negative value to reset to auto)", "<hour>")
4999 if( args.size()!=1 )
5000 return false;
5002 float hour;
5003 fromString(args[0], hour);
5004 if( hour < LightCycleManager.getLightDesc().NumHours )
5006 // check for privileges if this is the final build
5007 #if FINAL_VERSION
5008 // test that user has privilege
5009 if (hasPrivilegeDEV() ||
5010 hasPrivilegeSGM() ||
5011 hasPrivilegeGM() ||
5012 hasPrivilegeVG() ||
5013 hasPrivilegeSG() ||
5014 hasPrivilegeG() ||
5015 hasPrivilegeEM() ||
5016 hasPrivilegeEG())
5017 #endif
5019 ForcedDayNightCycleHour = hour;
5020 return true;
5023 return false;
5028 NLMISC_COMMAND(jobAnim, "set the job anim specialisation of an entity", "eid number")
5030 if(args.size()!=2)
5031 return false;
5033 uint eid;
5034 fromString(args[0], eid);
5035 uint jas;
5036 fromString(args[1], jas);
5037 CCharacterCL *ent= dynamic_cast<CCharacterCL*>(EntitiesMngr.entity(eid));
5038 if(ent)
5040 ent->setAnimJobSpecialisation(jas);
5043 return true;
5046 NLMISC_COMMAND(startLogStageChange, "start to log the change of stages of watched entity", "")
5048 // stop first any log
5049 EntitiesMngr.stopLogStageChange();
5051 // start the log
5052 EntitiesMngr.startLogStageChange(NetMngr.getCurrentClientTick(), T1);
5054 return true;
5057 NLMISC_COMMAND(stopLogStageChange, "stop to log the change of watched entity stages", "")
5059 EntitiesMngr.stopLogStageChange();
5060 return true;
5063 NLMISC_COMMAND(testReceiveMissionInfo, "emulate a dummy receive of mission info", "")
5065 CBotChatManager::getInstance()->debugLocalReceiveMissionInfo();
5066 return true;
5069 // command to dump the ui, no indentation full name
5070 NLMISC_COMMAND(dumpUIIndent, "Debug only : Dump the ui hierarchy in the output debug window", "")
5072 CInterfaceManager *im = CInterfaceManager::getInstance();
5073 im->dumpUI(true);
5074 return true;
5077 // command to dump the ui, no indentation full name
5078 NLMISC_COMMAND(dumpUIFull, "Debug only : Dump the ui hierarchy in the output debug window", "")
5080 CInterfaceManager *im = CInterfaceManager::getInstance();
5081 im->dumpUI(false);
5082 return true;
5085 // command to dump coordinates of a UI, for debug
5086 NLMISC_COMMAND(dumpUICoords, "Debug only : dump all coords info of an UI", "uiid")
5088 if(args.size()!=1)
5089 return false;
5091 CInterfaceManager *pIM = CInterfaceManager::getInstance();
5092 CInterfaceElement *el= CWidgetManager::getInstance()->getElementFromId(args[0]);
5093 if(!el)
5095 pIM->displaySystemInfo(toString("dumpUICoords: '%s' does not exist", args[0].c_str()));
5097 else
5099 pIM->displaySystemInfo(toString("dumpUICoords: **** '%s'", args[0].c_str()));
5100 pIM->displaySystemInfo(toString(" active= %d", uint(el->getActive()) ));
5101 pIM->displaySystemInfo(toString(" x= %d", el->getX() ));
5102 pIM->displaySystemInfo(toString(" y= %d", el->getY() ));
5103 pIM->displaySystemInfo(toString(" w= %d", el->getW() ));
5104 pIM->displaySystemInfo(toString(" h= %d", el->getH() ));
5105 pIM->displaySystemInfo(toString(" xreal= %d", el->getXReal() ));
5106 pIM->displaySystemInfo(toString(" yreal= %d", el->getYReal() ));
5107 pIM->displaySystemInfo(toString(" wreal= %d", el->getWReal() ));
5108 pIM->displaySystemInfo(toString(" hreal= %d", el->getHReal() ));
5109 pIM->displaySystemInfo(toString(" parent= '%s'", el->getParent()?el->getParent()->getId().c_str():""));
5110 pIM->displaySystemInfo(toString(" parentpos= '%s'", el->getParentPos()?el->getParentPos()->getId().c_str():""));
5111 pIM->displaySystemInfo(toString(" parentsize= '%s'", el->getParentSize()?el->getParentSize()->getId().c_str():""));
5113 // SizeRef
5114 string sr;
5115 switch(el->getSizeRef())
5117 case 1: sr= "w"; break;
5118 case 2: sr= "h"; break;
5119 case 3: sr= "wh"; break;
5120 default:break;
5122 pIM->displaySystemInfo(toString(" sizeref= '%s'", sr.c_str()));
5124 // PosRef
5125 string pr;
5126 THotSpot hsParent= el->getParentPosRef();
5127 THotSpot hsSelf= el->getPosRef();
5128 // parent
5129 if(hsParent & Hotspot_Bx) pr+= "B";
5130 else if(hsParent & Hotspot_Mx) pr+= "M";
5131 else if(hsParent & Hotspot_Tx) pr+= "T";
5132 else pr+= "?";
5133 if(hsParent & Hotspot_xL) pr+= "L";
5134 else if(hsParent & Hotspot_xM) pr+= "M";
5135 else if(hsParent & Hotspot_xR) pr+= "R";
5136 else pr+= "?";
5137 pr+=" ";
5138 // self
5139 if(hsSelf & Hotspot_Bx) pr+= "B";
5140 else if(hsSelf & Hotspot_Mx) pr+= "M";
5141 else if(hsSelf & Hotspot_Tx) pr+= "T";
5142 else pr+= "?";
5143 if(hsSelf & Hotspot_xL) pr+= "L";
5144 else if(hsSelf & Hotspot_xM) pr+= "M";
5145 else if(hsSelf & Hotspot_xR) pr+= "R";
5146 else pr+= "?";
5147 pIM->displaySystemInfo(toString(" posref= '%s'", pr.c_str()));
5149 pIM->displaySystemInfo(string("dumpUICoords: **** END"));
5152 return true;
5155 // Command to clear the dump of done Files opened and Async File Manager done files (for debug)
5156 NLMISC_COMMAND(clearDumpFiles, "clear the CAsyncFileManager and CIFile Debug list of opened files", "")
5158 CIFile::clearDump();
5159 CAsyncFileManager::getInstance().clearDump();
5161 return true;
5164 #endif // FINAL_VERSION
5167 /////////////////////////////////////////////////////////////////////////////
5168 /////////////////////////////////////////////////////////////////////////////
5169 /////////////////////////////////////////////////////////////////////////////
5170 /////////////////////////////////////////////////////////////////////////////
5171 /////////// COMMANDS before should NOT appear IN the FINAL VERSION //////////
5172 /////////////////////////////////////////////////////////////////////////////
5173 /////////////////////////////////////////////////////////////////////////////
5174 /////////////////////////////////////////////////////////////////////////////
5175 /////////////////////////////////////////////////////////////////////////////
5176 /////////////////////////////////////////////////////////////////////////////
5178 NLMISC_COMMAND(reloadFogMaps, "Force to reload all the fog maps", "<>")
5180 if (!args.empty()) return false;
5181 ContinentMngr.cur()->reloadFogMap();
5182 return true;
5185 // dump the names of all loaded sounds
5186 NLMISC_COMMAND(dumpSounds, "Dump names of all loaded sound", "<>")
5188 if (!args.empty()) return false;
5189 std::vector<NLMISC::TStringId> sounds;
5190 extern CSoundManager *SoundMngr;
5191 if (!SoundMngr) return false;
5192 if (!SoundMngr->getMixer()) return false;
5193 SoundMngr->getMixer()->getSoundNames(sounds);
5194 for(uint k = 0; k < sounds.size(); ++k)
5196 nlinfo(NLMISC::CStringMapper::unmap(sounds[k]).c_str());
5198 return true;
5201 // ***************************************************************************
5202 // LUA
5203 // ***************************************************************************
5204 const char *LUADebugNotEnabledMsg= "Lua Commands are available only if you add 'AllowDebugLua= 1;' in your client.cfg";
5206 NLMISC_COMMAND(luaReload, "reload all .lua script files", "")
5208 CInterfaceManager *pIM= CInterfaceManager::getInstance();
5209 if(ClientCfg.AllowDebugLua)
5211 CWidgetManager::getInstance()->getParser()->reloadAllLuaFileScripts();
5212 return true;
5214 else
5216 pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg));
5217 return false;
5221 NLMISC_COMMAND(luaScript, "Execute a lua script", "direct_script_code")
5223 CInterfaceManager *pIM= CInterfaceManager::getInstance();
5224 if(ClientCfg.AllowDebugLua)
5226 if(args.size()<1)
5227 return false;
5229 // Concat list of string in one script
5230 string script;
5231 for(uint i=0;i<args.size();i++)
5233 script+= args[i] + " ";
5236 // not smallScript because suppose var can change a lot
5237 CLuaManager::getInstance().executeLuaScript(script, false);
5239 return true;
5241 else
5243 pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg));
5244 return false;
5248 NLMISC_COMMAND(luaInfo, "Dump some information on LUA state", "detaillevel from 0 to 2")
5250 CInterfaceManager *pIM= CInterfaceManager::getInstance();
5251 if(ClientCfg.AllowDebugLua)
5253 if(args.size()!=1)
5254 return false;
5256 uint detail;
5257 fromString(args[0], detail);
5259 pIM->dumpLuaState(detail);
5260 return true;
5262 else
5264 pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg));
5265 return false;
5269 NLMISC_COMMAND(luaObject, "Dump the content of a lua object", "<table name> [maxDepth = 20, 0 for no limits]")
5271 if (args.empty()) return false;
5272 if (args.size() > 2) return false;
5273 CInterfaceManager *pIM= CInterfaceManager::getInstance();
5274 if (!ClientCfg.AllowDebugLua)
5276 pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg));
5277 return false;
5279 CLuaState *luaState = CLuaManager::getInstance().getLuaState();
5280 if (!luaState) return false;
5281 CLuaStackChecker lsc(luaState);
5282 // get the table
5283 static const char *inspectedTable = "_____inspected_table";
5286 // make a reference to the table to be inspected (is this this a primitive type, just make a copy)
5287 luaState->executeScript(std::string(inspectedTable) + " = " + args[0]);
5289 catch(const ELuaError &e)
5291 CLuaIHMRyzom::debugInfo(e.what());
5292 return false;
5294 luaState->pushGlobalTable();
5295 CLuaObject env;
5296 env.pop(*luaState);
5297 uint maxDepth;
5298 if (args.size() > 1)
5299 fromString(args[1], maxDepth);
5300 else
5301 maxDepth = 20;
5302 //CLuaIHM::debugInfo(env[inspectedTable].toStringRecurse(0, maxDepth));
5303 env[inspectedTable].dump();
5304 env.eraseValue(inspectedTable);
5305 return true;
5311 // GC allowed only in Dev version
5312 #if !FINAL_VERSION
5313 NLMISC_COMMAND(luaGC, "Force a garbage collector of lua", "")
5315 CInterfaceManager *pIM= CInterfaceManager::getInstance();
5316 if(ClientCfg.AllowDebugLua)
5318 CLuaManager::getInstance().forceGarbageCollect();
5319 return true;
5321 else
5323 pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg));
5324 return false;
5327 #endif
5330 // ***************************************************************************
5331 // CUserCommand
5332 // ***************************************************************************
5334 std::map<std::string, CUserCommand*> CUserCommand::CommandMap;
5336 // release memory
5337 void CUserCommand::release()
5339 std::map<std::string, CUserCommand*>::iterator it = CommandMap.begin();
5340 while( it != CommandMap.end() )
5341 delete (*it++).second;
5342 CommandMap.clear();
5345 // ***************************************************************************
5347 CUserCommand::CUserCommand(const string &commandName, const string &help, const string &argsHelp)
5348 : ICommand("user", commandName.c_str(), help.c_str(), argsHelp.c_str())
5350 CommandName = commandName;
5353 // ***************************************************************************
5355 void CUserCommand::addMode (const string &action, uint numArg, bool infiniteAgr, const std::vector<string> &keywords)
5357 CMode *mode;
5358 if (!infiniteAgr)
5359 mode = &(FixedArgModes[numArg]);
5360 else
5361 mode = &InfiniteMode;
5362 mode->Action = action;
5363 mode->KeywordsCount = numArg;
5364 mode->Keywords = keywords;
5367 // ***************************************************************************
5369 bool CUserCommand::execute(const std::string &/* rawCommandString */, const std::vector<std::string> &args, NLMISC::CLog &/* log */, bool /* quiet */, bool /* human */)
5371 CInterfaceManager *pIM = CInterfaceManager::getInstance();
5373 // Find the good keyword table
5374 CMode *mode = NULL;
5375 if (FixedArgModes.find ((uint)args.size()) != FixedArgModes.end())
5376 mode = &(FixedArgModes[(uint)args.size()]);
5377 else
5378 if (!InfiniteMode.Keywords.empty() && (args.size() >= InfiniteMode.KeywordsCount))
5379 mode = &InfiniteMode;
5381 if (mode)
5383 // Build the final string
5384 static string finalArgs;
5385 finalArgs.clear();
5386 uint i;
5387 uint index = 0;
5388 const vector<string> &keywords = mode->Keywords;
5389 for (i=0; i<keywords.size(); i++)
5391 if ((keywords[i] == "$") || (keywords[i] == "+"))
5393 if ((uint)index >= args.size())
5395 // Not enough arguments
5396 pIM->displaySystemInfo (CommandName+" : "+CI18N::get ("uiCommandWrongArgumentCount"));
5397 return false;
5399 else
5401 if (keywords[i] == "$")
5402 finalArgs += args[index++];
5403 else
5405 while (index<args.size())
5407 finalArgs += (index > 0) ? " " : "";
5408 // If arg contains spaces then put it in quotes
5409 if (string::npos != args[index].find(" "))
5411 finalArgs += "\"" + args[index++] + "\"";
5413 else
5415 finalArgs += args[index++];
5421 else
5423 finalArgs += keywords[i];
5427 // Run the action handler
5428 CAHManager::getInstance()->runActionHandler (mode->Action, CWidgetManager::getInstance()->getOldCaptureKeyboard(), finalArgs);
5430 else
5432 // Not enough argument
5433 pIM->displaySystemInfo (CommandName+" : "+CI18N::get ("uiCommandWrongArgumentCount"));
5434 return false;
5436 return true;
5439 // ***************************************************************************
5441 void CUserCommand::createCommand (const char *name, const char *action, const char *ptrParams)
5443 // Parse the params
5444 std::vector<string> keywords;
5446 // Get the help and the argument help
5447 uint countArgument = 0;
5448 bool infiniteArgument = false;
5449 string params = ptrParams;
5450 string::size_type pos = 0;
5451 while (pos < params.size())
5453 // Token ?
5454 string::size_type last;
5455 switch (params[pos])
5457 case '|':
5458 case '=':
5459 case '$':
5460 case '+':
5461 if ((params[pos] == '$') || (params[pos] == '+'))
5462 countArgument++;
5463 if (params[pos] == '+')
5464 infiniteArgument = true;
5465 last = pos+1;
5466 break;
5467 default:
5468 last = params.find_first_of ("|=$+", pos);
5469 if (last == string::npos)
5470 last = params.size();
5471 break;
5474 // Add a keyword
5475 keywords.push_back (params.substr (pos, last-pos));
5476 pos = last;
5479 // Find action name
5480 string help;
5481 const CBaseAction *ab = Actions.getBaseAction (::CAction::CName (action, ptrParams));
5482 if (ab)
5483 help = CI18N::get(ab->LocalizedName);
5485 // Build a argument help
5486 string argsHelp;
5488 if (ab)
5490 // Look for each arguments
5491 uint i;
5492 for (i=0; i<keywords.size(); i++)
5494 // Look for a '$'
5495 if ((keywords[i] == "$") || (keywords[i] == "+"))
5497 // Have a "=" ?
5498 if ((i > 1) && (keywords[i-1]=="="))
5500 // Argument
5501 bool bFound = false;
5502 for (uint j=0; j<ab->Parameters.size(); j++)
5504 // Argument found
5505 if (ab->Parameters[j].Name == keywords[i-2])
5507 // Add the string
5508 if (!argsHelp.empty())
5509 argsHelp += " ";
5510 argsHelp += "<" + CI18N::get(ab->Parameters[j].LocalizedName) + ">";
5511 bFound = true;
5514 // Not found ? Warning
5515 if (!bFound)
5517 nlwarning ("Argument %s not found in command %s using action %s", keywords[i-2].c_str(), name, action);
5524 // Ugly : never deleted, but who cares ?
5525 // Command exist ?
5526 CUserCommand *currentCommand;
5527 if (CommandMap.find (name) != CommandMap.end())
5528 currentCommand = CommandMap[name];
5529 else
5531 currentCommand = new CUserCommand (name, help, argsHelp);
5532 CommandMap[name] = currentCommand;
5535 // Add keywords
5536 currentCommand->addMode (action, countArgument, infiniteArgument, keywords);
5539 NLMISC_COMMAND(doAssert, "Create an assert", "")
5541 nlassert(0);
5542 return true;
5545 NLMISC_COMMAND(dumpPosAsPrim, "ld helper : add current position to pos.primitive with the given comment", "")
5547 if (!EntitiesMngr.entity(0)) return false;
5548 std::string comment;
5549 for(uint k = 0; k < args.size(); ++k)
5551 if (k != 0) comment += " ";
5552 comment += args[k];
5554 std::string srcFile;
5555 const std::string path = "save/pos.primitive";
5556 if (CFile::fileExists(path))
5560 uint32 fileSize = CFile::getFileSize(path);
5561 srcFile.resize(fileSize);
5562 CIFile stream;
5563 stream.open(path);
5564 stream.serialBuffer((uint8 *) &srcFile[0], fileSize);
5566 catch(const NLMISC::EStream &e)
5568 nlinfo(e.what());
5569 srcFile.clear();
5572 std::string newPrim =
5573 NLMISC::toString("<CHILD TYPE=\"CPrimPoint\"> \n\
5574 <PT X=\"%f\" Y=\"%f\" Z=\"%f\"/> \n\
5575 <PROPERTY TYPE=\"string\"> \n\
5576 <NAME>class</NAME> \n\
5577 <STRING>plot</STRING> \n\
5578 </PROPERTY> \n\
5579 <PROPERTY TYPE=\"string\"> \n\
5580 <NAME>name</NAME> \n\
5581 <STRING>%s</STRING> \n\
5582 </PROPERTY> \n\
5583 </CHILD>\n", (float) EntitiesMngr.entity(0)->pos().x, (float) EntitiesMngr.entity(0)->pos().y, (float) EntitiesMngr.entity(0)->pos().z, comment.c_str());
5585 // try to append result to current file
5586 const std::string LAST_CHILD_MARKER = "</CHILD>";
5587 std::string::size_type insertPos = srcFile.rfind(LAST_CHILD_MARKER);
5588 if (insertPos != std::string::npos)
5590 insertPos += LAST_CHILD_MARKER.size();
5591 srcFile.insert(insertPos, "\n" + newPrim);
5593 else
5595 srcFile.clear();
5597 if (srcFile.empty())
5599 srcFile = "<?xml version=\"1.0\"?> \n\
5600 <PRIMITIVES VERSION=\"1\"> \n\
5601 <ROOT_PRIMITIVE TYPE=\"CPrimNode\"> \n"
5602 + newPrim
5603 + " </ROOT_PRIMITIVE> \n\
5604 </PRIMITIVES>\n";
5607 // write result
5610 COFile stream;
5611 stream.open(path);
5612 stream.serialBuffer((uint8 *) &srcFile[0], (uint)srcFile.size());
5614 catch(const NLMISC::EStream &e)
5616 nlinfo(e.what());
5618 return true;
5621 NLMISC_COMMAND(clear, "clear content of current char window", "<chat window caller id>")
5623 if (args.size() > 1) return false;
5624 CInterfaceManager *im = CInterfaceManager::getInstance();
5625 im->flushDebugWindow();
5626 CChatWindow *cw;
5627 if (args.size() == 1)
5629 cw = getChatWndMgr().getChatWindowFromCaller(dynamic_cast<CCtrlBase *>(CWidgetManager::getInstance()->getElementFromId(args[0])));
5631 else
5633 // if no chat window (or enclosed control) id is given then see if a chat window called this command
5634 cw = CChatWindow::getChatWindowLaunchingCommand();
5636 if (cw && cw->getContainer())
5638 CGroupList *gl = dynamic_cast<CGroupList *>(cw->getContainer()->getGroup("text_list"));
5639 if (gl)
5641 gl->deleteAllChildren();
5644 return true;
5647 NLMISC_COMMAND(dumpAllLoadedZones, "dump all loaded zones", "")
5649 if (!args.empty()) return false;
5650 if (Landscape)
5652 std::vector<std::string> loadedZones;
5653 Landscape->getAllZoneLoaded(loadedZones);
5654 for(uint k = 0; k < loadedZones.size(); ++k)
5656 nlwarning(loadedZones[k].c_str());
5659 else
5661 nlwarning("Landscape has no loaded zones ");
5663 return true;
5667 NLMISC_COMMAND(tickToDate, "convert a tick value into a readable ryzom time", "")
5669 if (args.size() != 1) return false;
5670 CRyzomTime rt;
5671 uint32 tick;
5672 fromString(args[0], tick);
5673 rt.updateRyzomClock(tick);
5674 CInterfaceManager *im = CInterfaceManager::getInstance();
5675 float ryTime = rt.getRyzomTime();
5676 std::string readableDate = toString("Day = %d, hour = %d:%d", rt.getRyzomDay(), (int) floorf(ryTime), (int) floorf(60.f * fmodf(ryTime, 1.f)));
5677 im->displaySystemInfo(readableDate);
5678 return true;
5682 NLMISC_COMMAND(dumpShapeMaxDist, "dump max dist for shapes", "")
5685 std::set<std::string> shapeSet;
5686 typedef CHashMultiMap<float, std::string> TShapeMap;
5687 TShapeMap shapes;
5688 const CSheetManager::TEntitySheetMap &sheets = SheetMngr.getSheets();
5689 std::vector<const CCharacterSheet::CEquipment*> equipList;
5690 for (CSheetManager::TEntitySheetMap::const_iterator it = sheets.begin(); it != sheets.end(); ++it)
5692 CCharacterSheet *cs = dynamic_cast<CCharacterSheet *>(SheetMngr.get(it->first));
5693 if (cs)
5695 equipList.clear();
5696 cs->getWholeEquipmentList(equipList);
5697 for (uint k = 0; k < equipList.size(); ++k)
5699 std::string item = toLowerAscii(equipList[k]->getItem());
5700 if (!item.empty())
5703 string ext = CFile::getExtension(item);
5704 if (ext == "shape")
5706 if (!shapeSet.count(item))
5708 UInstance inst = Scene->createInstance(item);
5709 if (!inst.empty())
5711 shapes.insert(make_pair(inst.getDistMax(), item));
5712 Scene->deleteInstance(inst);
5714 shapeSet.insert(item);
5721 for (TShapeMap::iterator it = shapes.begin(); it != shapes.end(); ++it)
5723 nlwarning("Dist = %f, shape = %s", it->first, it->second.c_str());
5726 return true;
5730 NLMISC_COMMAND(dumpContinentCorners, "dump max dist for shapes", "")
5732 if (!args.empty()) return false;
5733 if (!ContinentMngr.cur()) return false;
5735 CVector2f posMin;
5736 CVector2f posMax;
5737 getPosFromZoneName(ContinentMngr.cur()->ZoneMin, posMin);
5738 getPosFromZoneName(ContinentMngr.cur()->ZoneMax, posMax);
5739 if (posMin.x > posMax.x) std::swap(posMin.x, posMax.x);
5740 if (posMin.y > posMax.y) std::swap(posMin.y, posMax.y);
5741 posMax.x += 160.f;
5742 posMax.y += 160.f;
5743 nlwarning("min = (%f, %f), max = (%f, %f)", posMin.x, posMin.y, posMax.x, posMax.y);
5744 return true;
5748 #if !FINAL_VERSION
5749 NLMISC_COMMAND(setMission, "locally set a mission text for test", "<mission index><text>")
5751 if (!ClientCfg.Local) return false;
5752 if (args.size() != 2) return false;
5753 uint index;
5754 fromString(args[0], index);
5755 CInterfaceManager *im = CInterfaceManager::getInstance();
5756 static sint32 strID = 10000; // any abitrary string id will do in local
5757 if (index >= 30) return false;
5758 if (index < 15)
5760 NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:MISSIONS:%d:TITLE", (int) index))->setValue32(strID);
5761 NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:MISSIONS:%d:FINISHED", (int) index))->setValue32(0);
5763 else
5765 NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:GROUP:MISSIONS:%d:TITLE", (int) index - 15))->setValue32(strID);
5766 NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:GROUP:MISSIONS:%d:FINISHED", (int) index - 15))->setValue32(0);
5768 setDynString(strID++, args[1]);
5769 return true;
5772 static bool setMissionStep(uint missionIndex, uint stepIndex, uint32 strID)
5774 CInterfaceManager *im = CInterfaceManager::getInstance();
5775 if (stepIndex >= 30) return false;
5776 if (stepIndex >= 20) return false;
5777 if (missionIndex < 15)
5779 NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:MISSIONS:%d:GOALS:%d:TEXT", (int) missionIndex, (int) stepIndex))->setValue32(strID);
5781 else
5783 NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:GROUP:MISSIONS:%d:GOALS:%d:TEXT", (int) (missionIndex - 15), (int) stepIndex))->setValue32(strID);
5785 return true;
5789 // add a new step in a mission, the mission must already exist
5790 NLMISC_COMMAND(setMissionStep, "locally set a mission step for test", "<mission index><step index><text>")
5792 if (!ClientCfg.Local) return false;
5793 if (args.size() != 3) return false;
5794 uint missionIndex;
5795 fromString(args[0], missionIndex);
5796 uint stepIndex;
5797 fromString(args[1], stepIndex);
5799 static sint32 strID = 20000; // any abitrary string id will do in local
5800 if (!setMissionStep(missionIndex, stepIndex, strID)) return false;
5801 setDynString(strID++, args[2]);
5802 return true;
5805 // add a newstepin a mission, the mission must already exist
5806 NLMISC_COMMAND(clearMissionStep, "locally set a mission step for test", "<mission index><step index><text>")
5808 if (!ClientCfg.Local) return false;
5809 if (args.size() != 2) return false;
5810 uint missionIndex;
5811 fromString(args[0], missionIndex);
5812 uint stepIndex;
5813 fromString(args[1], stepIndex);
5814 return setMissionStep(missionIndex, stepIndex, 0);
5818 #endif
5821 #if !FINAL_VERSION
5822 static bool debugSetMissionState(uint index, sint32 /* state */)
5824 if (index >= 30) return false;
5825 CInterfaceManager *im = CInterfaceManager::getInstance();
5826 if (index < 15)
5828 NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:MISSIONS:%d:TITLE", (int) index))->setValue32(0);
5830 else
5832 NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:GROUP:MISSIONS:%d:TITLE", (int) index - 15))->setValue32(0);
5834 return true;
5836 #endif
5839 #if !FINAL_VERSION
5840 NLMISC_COMMAND(clearMission, "clear the content of a mission", "<mission index>")
5842 if (!ClientCfg.Local) return false;
5843 if (args.size() != 1) return false;
5844 uint index;
5845 fromString(args[0], index);
5846 return debugSetMissionState(index, 0);
5849 #endif
5851 #if !FINAL_VERSION
5852 NLMISC_COMMAND(finishMission, "clear the content of a mission", "<mission index>")
5854 if (!ClientCfg.Local) return false;
5855 if (args.size() != 1) return false;
5856 uint index;
5857 fromString(args[0], index);
5858 return debugSetMissionState(index, 1);
5860 #endif
5862 #if !FINAL_VERSION
5863 NLMISC_COMMAND(failMission, "clear the content of a mission", "<mission index>")
5865 if (!ClientCfg.Local) return false;
5866 if (args.size() != 1) return false;
5867 uint index;
5868 fromString(args[0], index);
5869 return debugSetMissionState(index, 2);
5871 #endif
5874 // ***************************************************************************
5877 NLMISC_COMMAND (url, "launch a browser to the specified url", "<url>")
5879 if (args.size () != 1)
5880 return false;
5882 return openURL(args[0]);
5886 NLMISC_COMMAND(em, "emote command", "<emote phrase>")
5888 if (args.size() < 1) return false;
5890 CInterfaceManager *pIM = CInterfaceManager::getInstance();
5891 if( pIM )
5893 string emotePhrase;
5894 if (!args.empty())
5896 emotePhrase = args[0];
5898 for(uint i = 1; i < args.size(); ++i )
5900 emotePhrase += " ";
5901 emotePhrase += args[i];
5903 CAHManager::getInstance()->runActionHandler("emote", NULL, "nb=0|behav=255|custom_phrase="+emotePhrase);
5904 return true;
5906 return false;
5912 NLMISC_COMMAND(guildmotd, "Set or see the guild message of the day","<msg of the day>")
5914 CBitMemStream out;
5915 if (!GenericMsgHeaderMngr.pushNameToStream("COMMAND:GUILDMOTD", out))
5916 return false;
5918 string gmotd;
5919 if (!args.empty())
5921 gmotd = args[0];
5923 for(uint i = 1; i < args.size(); ++i )
5925 gmotd += " ";
5926 gmotd += args[i];
5929 out.serial (gmotd);
5930 NetMngr.push (out);
5932 return true;
5936 NLMISC_COMMAND(time, "Shows information about the current time", "")
5938 const uint8 size = 50;
5939 char cs_local[size];
5940 char cs_utc[size];
5941 time_t date;
5942 time(&date);
5943 struct tm *tm;
5944 tm = localtime(&date);
5945 strftime(cs_local, size, "%X", tm);
5946 tm = gmtime(&date);
5947 strftime(cs_utc, size, "%X", tm);
5949 string msg = CI18N::get("uiCurrentLocalAndUtcTime");
5950 strFindReplace(msg, "%local", cs_local);
5951 strFindReplace(msg, "%utc", cs_utc);
5952 CInterfaceManager::getInstance()->displaySystemInfo(msg, "AROUND");
5953 return true;
5956 NLMISC_COMMAND(playedTime, "Display character played time", "")
5958 string msg = CI18N::get("uiPlayedTime");
5959 strFindReplace(msg, "%time", NLMISC::secondsToHumanReadable(CharPlayedTime));
5960 CInterfaceManager::getInstance()->displaySystemInfo(msg, "AROUND");
5961 return true;
5964 NLMISC_COMMAND(version, "Display client version", "")
5966 string msg = getDebugVersion();
5967 CInterfaceManager::getInstance()->displaySystemInfo(msg, "AROUND");
5968 return true;