From 93d2b80966ed5821502840f1f91d583fee6afe27 Mon Sep 17 00:00:00 2001 From: SIELA1915 Date: Wed, 13 Jan 2016 19:26:28 +0100 Subject: [PATCH] Adjustments to give more options to do custom emotes, "Khanatization" for the Mac Client, changements to the key system. --- code/ryzom/client/client_default.cfg | 1160 +-- .../data/gamedev/interfaces_v3/actions.xml | 635 +- .../data/gamedev/interfaces_v3/hierarchy.xml | 14 +- .../data/gamedev/interfaces_v3/macros.xml | 15 +- code/ryzom/client/macosx/khanat.icns | Bin 0 -> 205375 bytes code/ryzom/client/src/CMakeLists.txt | 10 +- code/ryzom/client/src/client.cpp | 2 +- code/ryzom/client/src/commands.cpp | 8361 +++++++++-------- .../tools/client/client_patcher/main.cpp | 2 +- 9 files changed, 5100 insertions(+), 5099 deletions(-) create mode 100644 code/ryzom/client/macosx/khanat.icns diff --git a/code/ryzom/client/client_default.cfg b/code/ryzom/client/client_default.cfg index 4b0e70e76..28633ff0b 100644 --- a/code/ryzom/client/client_default.cfg +++ b/code/ryzom/client/client_default.cfg @@ -1,576 +1,584 @@ -////////////////////////// -////////////////////////// -/// CLIENT CONFIG FILE /// -////////////////////////// -////////////////////////// - - -// If you set this variable to 1, your client.cfg will be overwritten when you quit the client. -// You will loose all the comments and identation in this file. -SaveConfig = 1; - -/////////////////// -// WINDOW CONFIG // -/////////////////// - -Driver3D="Auto"; // Valid values are "Auto" or "0", "OpengGL" or "1" & "Direct3D" or "2" - // "Auto" will choose the best suited driver depending on hardware -FullScreen = 1; -Width = 0; -Height = 0; -PositionX = 0; -PositionY = 0; -Frequency = 0; -Depth = 32; -Sleep = -1; -ProcessPriority = 0; // -2 = idle, -1 = below normal, 0 = normal, 1 = above normal, 2 = high, 3 = real time -Contrast = 0.0; // -1.0 ~ 1.0 -Luminosity = 0.0; // -1.0 ~ 1.0 -Gamma = 0.0; // -1.0 ~ 1.0 -Contrast_min = -1.0; -Luminosity_min = -1.0; -Gamma_min = -1.0; -Contrast_max = 1.0; -Luminosity_max = 1.0; -Gamma_max = 1.0; - - -///////////// -// NETWORK // -///////////// - -Application = { "ryzom_live", "./client_ryzom_r.exe", "./" }; -BackgroundDownloader = 0; -PatchServer = "http://dl.ryzom.com/patch_live"; -StartupHost = "shard.ryzom.com:40916"; -StartupPage = "/login/r2_login.php"; -InstallStatsUrl = ""; - -ConditionsTermsURL = "http://app.ryzom.com/app_forum/index.php?page=topic/view/21885/1&post148782=en#1"; -LoginSupportURL = "http://app.ryzom.com/app_forum/index.php?page=topic/view/22047/1&post149889=en#1"; - - -//////////////// -// INTERFACES // -//////////////// - -// the language to use as in ISO 639-2 -LanguageCode = "en"; // english - -XMLInputFile = "input_config_v3.xml"; - -XMLLoginInterfaceFiles = { - "login_config.xml", - "login_widgets.xml", - "login_main.xml", - "login_keys.xml", -}; - -XMLOutGameInterfaceFiles = { - "out_v2_config.xml", - "out_v2_widgets.xml", - "out_v2_connect.xml", - "out_v2_intro.xml", - "out_v2_select.xml", - "out_v2_appear.xml", - "out_v2_location.xml", - "out_v2_crash.xml", - "out_v2_hierarchy.xml", - "out_v2_keys.xml", -}; - -// The ligo primitive class file -LigoPrimitiveClass = "world_editor_classes.xml"; - -VerboseLog = 1; - -/////////// -// MOUSE // -/////////// -HardwareCursor = 1; - -CursorSpeed = 1.0; // In pixels per mickey -CursorSpeed_min = 0.5; -CursorSpeed_max = 2.0; - -CursorAcceleration = 40; // Threshold in mickey -CursorAcceleration_min = 20; -CursorAcceleration_max = 80; - -FreeLookSpeed = 0.004; // In radian per mickey -FreeLookSpeed_min = 0.0001; -FreeLookSpeed_max = 0.01; - -FreeLookAcceleration = 40; // Threshold in mickey -FreeLookAcceleration_min = 20; -FreeLookAcceleration_max = 80; - -FreeLookInverted = 0; -AutomaticCamera = 0; -DblClickMode = 1; -AutoEquipTool = 1; - -/////////////////// -// RENDER CONFIG // -/////////////////// - -// NB: thoses variables configure also the InGameConfigurator: -// _min and _max define the bounds -// _step defines the step (NB: take care of _min and _max!!) -// _ps0 is the LOW preset, _ps1 is the MEDIUM preset, _ps2 is the NORMAL Preset, and _ps3 is the HIGH one - - -// *** LANDSCAPE -LandscapeTileNear = 50.000000; -LandscapeTileNear_min = 20.000000; -LandscapeTileNear_max = 100.000000; -LandscapeTileNear_step = 10.0; -LandscapeTileNear_ps0 = 20.0; -LandscapeTileNear_ps1 = 40.0; -LandscapeTileNear_ps2 = 50.0; -LandscapeTileNear_ps3 = 80.0; - -// NB: threshold is inverted ULandscape::setThreshold(), to be more intelligible -LandscapeThreshold = 1000.0; -LandscapeThreshold_min = 100.0; // Low quality => 0.01 threshold -LandscapeThreshold_max = 2000.0; // High quality => 0.0005 threshold -LandscapeThreshold_step = 100.0; -LandscapeThreshold_ps0 = 100.0; -LandscapeThreshold_ps1 = 500.0; -LandscapeThreshold_ps2 = 1000.0; -LandscapeThreshold_ps3 = 2000.0; - -Vision = 500.000000; -Vision_min = 200.000000; -Vision_max = 800.000000; -Vision_step = 100.000000; -Vision_ps0 = 200.0; -Vision_ps1 = 400.0; -Vision_ps2 = 500.0; -Vision_ps3 = 800.0; - -MicroVeget = 1; // Enable/Disable MicroVeget. -MicroVeget_ps0 = 0; -MicroVeget_ps1 = 1; -MicroVeget_ps2 = 1; -MicroVeget_ps3 = 1; - -MicroVegetDensity = 80.0; -MicroVegetDensity_min = 10.0; -MicroVegetDensity_max = 100.0; -MicroVegetDensity_step = 10.0; -MicroVegetDensity_ps0 = 10.0; // not used since disabled! -MicroVegetDensity_ps1 = 30.0; -MicroVegetDensity_ps2 = 80.0; -MicroVegetDensity_ps3 = 100.0; - - -// *** FX -FxNbMaxPoly = 20000; -FxNbMaxPoly_min = 2000; -FxNbMaxPoly_max = 50000; -FxNbMaxPoly_step= 2000; -FxNbMaxPoly_ps0 = 2000; -FxNbMaxPoly_ps1 = 10000; -FxNbMaxPoly_ps2 = 20000; -FxNbMaxPoly_ps3 = 50000; - -Cloud = 1; -Cloud_ps0 = 0 ; -Cloud_ps1 = 1 ; -Cloud_ps2 = 1 ; -Cloud_ps3 = 1 ; - -CloudQuality = 160.0; -CloudQuality_min = 80.0; -CloudQuality_max = 320.0; -CloudQuality_step = 20.0; -CloudQuality_ps0 = 80.0; // not used since disabled! -CloudQuality_ps1 = 80.0; -CloudQuality_ps2 = 160.0; -CloudQuality_ps3 = 320.0; - -CloudUpdate = 1; -CloudUpdate_min = 1; -CloudUpdate_max = 8; -CloudUpdate_step= 1; -CloudUpdate_ps0 = 1; // not used since disabled! -CloudUpdate_ps1 = 1; -CloudUpdate_ps2 = 1; -CloudUpdate_ps3 = 3; - -Shadows = 1; -Shadows_ps0 = 0; -Shadows_ps1 = 1; -Shadows_ps2 = 1; -Shadows_ps3 = 1; - -FXAA = 1; -FXAA_ps0 = 0; -FXAA_ps1 = 1; -FXAA_ps2 = 1; -FXAA_ps3 = 1; - -AnisotropicFilter = 0; - -Bloom = 1; -Bloom_ps0 = 0; -Bloom_ps1 = 1; -Bloom_ps2 = 1; -Bloom_ps3 = 1; - -SquareBloom = 1; -SquareBloom_ps0 = 0; -SquareBloom_ps1 = 1; -SquareBloom_ps2 = 1; -SquareBloom_ps3 = 1; - -DensityBloom = 255.0; -DensityBloom_min = 0.0; -DensityBloom_max = 255.0; -DensityBloom_step = 1.0; -DensityBloom_ps0 = 255.0; -DensityBloom_ps1 = 255.0; -DensityBloom_ps2 = 255.0; -DensityBloom_ps3 = 255.0; - - -// *** CHARACTERS -SkinNbMaxPoly = 100000; -SkinNbMaxPoly_min = 5000; -SkinNbMaxPoly_max = 250000; -SkinNbMaxPoly_step = 5000; -SkinNbMaxPoly_ps0 = 10000; -SkinNbMaxPoly_ps1 = 70000; -SkinNbMaxPoly_ps2 = 100000; -SkinNbMaxPoly_ps3 = 200000; - -NbMaxSkeletonNotCLod = 125; -NbMaxSkeletonNotCLod_min = 5; -NbMaxSkeletonNotCLod_max = 255; -NbMaxSkeletonNotCLod_step = 5; -NbMaxSkeletonNotCLod_ps0 = 10; -NbMaxSkeletonNotCLod_ps1 = 50; -NbMaxSkeletonNotCLod_ps2 = 125; -NbMaxSkeletonNotCLod_ps3 = 255; - -CharacterFarClip = 200.0; -CharacterFarClip_min = 50.0; -CharacterFarClip_max = 500.0; -CharacterFarClip_step = 10.0; -CharacterFarClip_ps0 = 50.0; -CharacterFarClip_ps1 = 100.0; -CharacterFarClip_ps2 = 200.0; -CharacterFarClip_ps3 = 500.0; - -EnableRacialAnimation = 1; - -// *** MISC -// This is the actual aspect ratio of your screen (no relation with the resolution!!). Set 1.7777 if you got a 16/9 screen for instance -ScreenAspectRatio = 0.0; -ForceDXTC = 1; // Enable/Disable DXTC. -DivideTextureSizeBy2= 0; // Divide texture size -DisableVtxProgram = 0; // Disable Hardware Vertex Program. -DisableVtxAGP = 0; // Disable Hardware Vertex AGP. -DisableTextureShdr = 0; // Disable Hardware Texture Shader. -HDEntityTexture = 1; -HDTextureInstalled = 1; -WaitVBL = 0; // 0 or 1 to wait Vertical Sync. - -////////////////// -// GAME OPTIONS // -////////////////// -SelectWithRClick = 1; -DisplayWeapons = 1; -RotKeySpeedMax = 2.0; -RotKeySpeedMax_min = 1.0; -RotKeySpeedMax_max = 4.0; -RotKeySpeedMin = 1.0; -RotKeySpeedMin_min = 0.5; -RotKeySpeedMin_max = 2.0; -RotAccel = 3.0; -FollowOnAtk = 0; -AtkOnSelect = 0; -ZCPacsPrim = "gen_bt_col_ext.pacs_prim"; - -///////////////// -// PREFERENCES // -///////////////// -FPV = 0; // FPV(First Person View) : default is false (Third Person View). -CameraHeight = 2.2; // Camera Height (in meter) from the ground (for the Third Person View). -CameraDistance = 3.0; // Camera Distance(in meter) from the user (for the Third Person View). -CameraDistStep = 1.0; -CameraDistMin = 1.0; -CameraDistMax = 25.0; -CameraAccel = 5.0; -CameraSpeedMin = 2.0; -CameraSpeedMax = 100.0; -CameraResetSpeed = 10.0; // Speed in radian/s - -////////////////// -// SOUND CONFIG // -////////////////// -SoundForceSoftwareBuffer= 1; -SoundOn = 1; -UseEax = 0; - -MaxTrack = 32; -MaxTrack_min = 4; -MaxTrack_max = 32; -MaxTrack_step = 4; - -// This is the volume for "InGame" sound FXs -SoundSFXVolume = 1.0; -SoundSFXVolume_min = 0.0; -SoundSFXVolume_max = 1.0; -SoundSFXVolume_step = 0.001; - -// This is volume for "InGame" music. Does not affect the MP3 player -SoundGameMusicVolume = 0.5; -SoundGameMusicVolume_min = 0.0; -SoundGameMusicVolume_max = 1.0; -SoundGameMusicVolume_step = 0.001; - -// MISC -PreDataPath = { "user", "patch", "data", "examples" }; -NeedComputeVS = 0; - -NegFiltersDebug = {"Update DB", "Reading:", "Read Value :", "impulseCallBack", "CLIMPD:", "LNET" }; -NegFiltersInfo = { "CLIMPD:", "CPath::lookup" , "LNET" }; -NegFiltersWarning = { "'basics.Equipment Slot'.", "_usercolor.tga", "PACS" }; - -// Big screen shot -ScreenShotWidth = 0; -ScreenShotHeight = 0; -ScreenShotFullDetail = 1; // 1 to switch full detail mode for characters (both standard & big screenshots) - -// Read : "ID", "R G B A MODE [FX]" -SystemInfoColors = -{ -// OLD STUFF Here for compatibility -"RG", "0 0 0 255 normal", // Black to see when there is an error -"BC", "0 0 0 255 normal", // Black to see when there is an error -"JA", "0 0 0 255 normal", // Black to see when there is an error -"BL", "0 0 0 255 normal", // Black to see when there is an error -"VE", "0 0 0 255 normal", // Black to see when there is an error -"VI", "0 0 0 255 normal", // Black to see when there is an error - -// NEW System Info Categories -"SYS", "255 255 255 255 normal", // Default system messages -"BC", "255 255 255 255 centeraround", // Broadcast messages -"TAGBC", "255 255 255 255 centeraround", // Taged broadcast messages : color should remain white as some word are tagged -"XP", "255 255 64 255 over", // XP Gain -"SP", "255 255 64 255 over", // SP Gain -"TTL", "255 255 64 255 over", // Title -"TSK", "255 255 255 255 over", // Task -"ZON", "255 255 255 255 center", // Zone -"DG", "255 0 0 255 normal", // Damage to me -"DMG", "255 0 0 255 normal", // Damage to me -"DGP", "200 0 0 255 normal", // Damage to me from player -"DGM", "255 128 64 255 normal", // Damage from me -"MIS", "150 150 150 255 normal", // The opponent misses -"MISM", "255 255 255 255 normal", // I miss -"ITM", "0 200 0 255 over", // Item -"ITMO", "170 170 255 255 overonly", // Item other in group -"ITMF", "220 0 220 255 over", // Item failed -"SPL", "50 50 250 255 normal", // Spell to me -"SPLM", "50 150 250 255 normal", // Spell from me -"EMT", "255 150 150 255 normal", // Emote -"MTD", "255 255 0 255 over", // Message Of The Day -"FORLD","64 255 64 255 overonly", // Forage Locate Deposit -"CHK", "255 120 60 255 center", // Tous ce qui ne remplit pas une condition -"CHKCB","255 255 0 255 center", // Tous ce qui ne remplit pas une condition en combat (trop loin, cible invalide, pas assez de mana, etc.) -"PVPTM","255 120 60 255 overonly", // PVP timer -"THM", "255 255 64 255 over misc_levelup.ps", // Thema finished -"AMB", "255 255 64 255 center", // Ambiance -"ISE", "192 208 255 255 normal", // Item special effect -"ISE2", "192 208 255 255 center", // Item special effect with center text (for effects without flying text) -"OSM", "128 160 255 255 center", // Outpost state message -"AROUND","255 255 0 255 around", // Only in around channel -"R2_INVITE","0 255 0 255 around", // Ring invitation -}; - -PrintfCommands = { - "52", "15", "55 55 0 255", "28", "uiChapterV", "624", - "428", "0 0 0 255", "18", "", "624", "378", - "0 0 0 255", "14", "", "644", "278", "0 0 0 255", - "18", "", "52", "17", "255 255 255 255", "28", - "uiChapterV", "622", "430", "255 255 255 255", "18", "", - "622", "380", "255 255 255 255", "14", "", "642", - "280", "255 255 255 255", "18", "" -}; - -PrintfCommandsFreeTrial = { - "52", "15", "55 55 0 255", "28", "uiChapterV", "624", - "428", "0 0 0 255", "18", "", "624", "378", - "0 0 0 255", "14", "", "644", "278", "0 0 0 255", - "18", "", "52", "17", "255 255 255 255", "28", - "uiChapterV", "622", "430", "255 255 255 255", "18", "", - "622", "380", "255 255 255 255", "14", "", "642", - "280", "255 255 255 255", "18", "" -}; - -DisplayMissingAnimFile = 0; - -LoadingStringCount = 54; - - -// Some R2 parameters ... - -R2Mode = 1; -R2EDEnabled = 1; -R2EDExtendedDebug = 0; -R2EDLightPalette = 0; -R2ClientGw = "r2linux01"; -LoadLuaDebugger = 0; -CheckR2ScenarioMD5 = 1; -LevelDesignEnabled = 0; - -DmCameraDistMax = 25; -DmRun = 20; -DmWalk = 6; - -R2EDReloadFiles = { - "r2ed.xml", - "r2_basic_bricks.lua", - "r2_components.lua", - "r2_core.lua", - "r2_features_default.lua", - "r2_features_fauna.lua", - "r2_features_npc_groups.lua", - "r2_palette.lua", - "r2_scenario.lua", - "r2_ui.lua" -}; - -XMLInterfaceFiles = { - "config.xml", - "widgets.xml", - "webig_widgets.xml", - "player.xml", - "inventory.xml", - "interaction.xml", - "phrase.xml", - "harvest.xml", - "macros.xml", - "info_player.xml", - "outpost.xml", - "guild.xml", - "taskbar.xml", - "game_config.xml", - "game_context_menu.xml", - "player_trade.xml", - "bot_chat_v4.xml", - "compass.xml", - "map.xml", - "hierarchy.xml", - "reset.xml", - "actions.xml", - "help.xml", - "encyclopedia.xml", - "commands.xml", - "commands2.xml", - "ring_access_point_filter.xml", - "ring_window.xml", - "bg_downloader.xml" -}; - -XMLR2EDInterfaceFiles = -{ - "r2ed.xml", - "r2_triggers.xml", - "r2_logic_entities.xml", - "r2ed_acts.xml", - "r2ed_scenario.xml", - "r2ed_connect.xml" -}; - -FogDistAndDepthLookupBias = 20; // bias for lookup of fog distance and depth - - -// Hardware cursor textures -// These will be extracted from the corresponding packed ui .tga files when they are loaded -// * -// * individual .tga files for hardware cursor bitmap not looked for, and not supported yet -HardwareCursors = -{ - "curs_can_pan.tga", - "curs_can_pan_dup.tga", - "curs_create.tga", - "curs_create_multi.tga", - "curs_create_vertex_invalid.tga", - "curs_default.tga", - "curs_dup.tga", - "curs_L.tga", - "curs_M.tga", - "curs_pan.tga", - "curs_pan_dup.tga", - "curs_pick.tga", - "curs_pick_dup.tga", - "curs_R.tga", - "curs_resize_BL_TR.tga", - "curs_resize_BR_TL.tga", - "curs_resize_LR.tga", - "curs_resize_TB.tga", - "curs_rotate.tga", - "curs_scale.tga", - "curs_stop.tga", - "text_cursor.tga", - "r2_hand_can_pan.tga", - "r2_hand_pan.tga", - "r2ed_tool_can_pick.tga", - "r2ed_tool_can_rotate.tga", - "r2ed_tool_pick.tga", - "r2ed_tool_rotate.tga", - "r2ed_tool_rotating.tga" -}; - -Loading_BG = "new_loading_bg.tga"; // Default name for the loading background file. -Launch_BG = "new_launcher_bg.tga"; // Default name for the launch background file. -TeleportKami_BG = "new_teleport_kami_bg.tga"; -TeleportKaravan_BG = "new_teleport_caravan_bg.tga"; -Elevator_BG = "new_elevator_bg.tga"; // Default name for the loading background file. -ResurectKami_BG = "new_resurect_kami_bg.tga"; -ResurectKaravan_BG = "new_resurect_caravane_bg.tga"; -End_BG = "end_bg.tga"; // Default name for the last background file. - -ScenarioSavePath = "./my_scenarios/"; - -// list ofpredefined keyset -// name will be looked up in the translation file by searching 'uiCP_KeysetName_" + id -// tooltip will be looked up in the translation file by searching 'uiCP_KeysetTooltip_" + id -// 'bi.' stands for built-in -// note : we add a dot in the name to be sure that there cannot be a conflict with character keyset name -BuiltInKeySets = -{ - "", // default ryzom keyboard layout - "bi.zqsd", // european keyboard fps displacement style (NB : don't change this layout name, ryzom will automatically select it if keyboard is french or belgian) - "bi.wasd", // english keyboard fps displacement style (NB : don't change this layout name, ryzom will automatically select it if keyboard is not french nor belgian) - "bi.wow_alike" // 'world of warcraft' like keyboard style. (NB : not available for ring) -}; - -// "Newbie Training", "Story Telling", "Mistery", "Hack & Slash", "Guild Training", "Other" -ScenarioTypes = {"so_newbie_training","so_story_telling","so_mistery","so_hack_slash","so_guild_training","so_other"}; - -ScenarioLanguages = {"fr","de","en","other_lang"}; - -// Map each language to a forum help page -HelpPages = -{ - "fr=http://forums.ryzom.com/forum/showthread.php?t=29130", - "en=http://forums.ryzom.com/forum/showthread.php?t=29129", - "wk=http://forums.ryzom.com/forum/showthread.php?t=29129", - "de=http://forums.ryzom.com/forum/showthread.php?t=29131", - "es=http://forums.ryzom.com/forum/showthread.php?t=29129", - "ru=http://forums.ryzom.com/forum/showthread.php?t=29129" -}; - -WebIgMainDomain = "app.ryzom.com"; -WebIgTrustedDomains = { - "api.ryzom.com", "app.ryzom.com" -}; -PatchletUrl = "http://app.ryzom.com/app_patchlet/index.php?patch=preload"; - -SelectedSlot = 0; - -BuildName = "RELEASE_HEAD"; +////////////////////////// +/// CLIENT CONFIG FILE /// +////////////////////////// +////////////////////////// + +////////////////////////// + +// If you set this variable to 1, your client.cfg will be overwritten when you quit the client. +// You will loose all the comments and identation in this file. +SaveConfig = 1; + +/////////////////// +// WINDOW CONFIG // +/////////////////// + +Driver3D="Auto"; // Valid values are "Auto" or "0", "OpengGL" or "1" & "Direct3D" or "2" + // "Auto" will choose the best suited driver depending on hardware +FullScreen = 0; +Width = 0; +Height = 0; +PositionX = 0; +PositionY = 0; +Frequency = 0; +Depth = 32; +Sleep = -1; +ProcessPriority = 0; // -2 = idle, -1 = below normal, 0 = normal, 1 = above normal, 2 = high, 3 = real time +Contrast = 0.0; // -1.0 ~ 1.0 +Luminosity = 0.0; // -1.0 ~ 1.0 +Gamma = 0.0; // -1.0 ~ 1.0 +Contrast_min = -1.0; +Luminosity_min = -1.0; +Gamma_min = -1.0; +Contrast_max = 1.0; +Luminosity_max = 1.0; +Gamma_max = 1.0; + + +///////////// +// NETWORK // +///////////// + +Application = { "Lirria", "./client_ryzom_r.exe", "./" }; +BackgroundDownloader = 0; +PatchWanted = 1; +PatchUrl = "http://lirria.khaganat.net:43435"; +RingReleaseNotePath = "http://lirria.khaganat.net/patch/index.php"; +StartupHost = "lirria.khaganat.net:40916"; +StartupPage = "/login/r2_login.php"; +InstallStatsUrl = "http://lirria.khaganat.net:50000/stats/stats.php"; + +CreateAccountURL = "http://lirria.khaganat.net/ams/?page=register"; +EditAccountURL = "http://lirria.khaganat.net/"; +ForgetPwdURL = "http://lirria.khaganat.net/ams/index.php?page=forgot_password"; +//FreeTrialURL = "http://lirria.khaganat.net/"; +LoginSupportURL = "http://lirria.khaganat.net/"; +ConditionsTermsURL = "khaganat.net/wikhan/fr:charte"; + + + +//////////////// +// INTERFACES // +//////////////// + +// the language to use as in ISO 639-2 +LanguageCode = "en"; // english + +XMLInputFile = "input_config_v3.xml"; + +XMLLoginInterfaceFiles = { + "login_config.xml", + "login_widgets.xml", + "login_main.xml", + "login_keys.xml", +}; + +XMLOutGameInterfaceFiles = { + "out_v2_config.xml", + "out_v2_widgets.xml", + "out_v2_connect.xml", + "out_v2_intro.xml", + "out_v2_select.xml", + "out_v2_appear.xml", + "out_v2_location.xml", + "out_v2_crash.xml", + "out_v2_hierarchy.xml", + "out_v2_keys.xml", +}; + +// The ligo primitive class file +LigoPrimitiveClass = "world_editor_classes.xml"; + +VerboseLog = 1; + +/////////// +// MOUSE // +/////////// +HardwareCursor = 1; + +CursorSpeed = 1.0; // In pixels per mickey +CursorSpeed_min = 0.5; +CursorSpeed_max = 2.0; + +CursorAcceleration = 40; // Threshold in mickey +CursorAcceleration_min = 20; +CursorAcceleration_max = 80; + +FreeLookSpeed = 0.004; // In radian per mickey +FreeLookSpeed_min = 0.0001; +FreeLookSpeed_max = 0.01; + +FreeLookAcceleration = 40; // Threshold in mickey +FreeLookAcceleration_min = 20; +FreeLookAcceleration_max = 80; + +FreeLookInverted = 0; +AutomaticCamera = 0; +DblClickMode = 1; +AutoEquipTool = 1; + +/////////////////// +// RENDER CONFIG // +/////////////////// + +// NB: thoses variables configure also the InGameConfigurator: +// _min and _max define the bounds +// _step defines the step (NB: take care of _min and _max!!) +// _ps0 is the LOW preset, _ps1 is the MEDIUM preset, _ps2 is the NORMAL Preset, and _ps3 is the HIGH one + + +// *** LANDSCAPE +LandscapeTileNear = 50.000000; +LandscapeTileNear_min = 20.000000; +LandscapeTileNear_max = 100.000000; +LandscapeTileNear_step = 10.0; +LandscapeTileNear_ps0 = 20.0; +LandscapeTileNear_ps1 = 40.0; +LandscapeTileNear_ps2 = 50.0; +LandscapeTileNear_ps3 = 80.0; + +// NB: threshold is inverted ULandscape::setThreshold(), to be more intelligible +LandscapeThreshold = 1000.0; +LandscapeThreshold_min = 100.0; // Low quality => 0.01 threshold +LandscapeThreshold_max = 2000.0; // High quality => 0.0005 threshold +LandscapeThreshold_step = 100.0; +LandscapeThreshold_ps0 = 100.0; +LandscapeThreshold_ps1 = 500.0; +LandscapeThreshold_ps2 = 1000.0; +LandscapeThreshold_ps3 = 2000.0; + +Vision = 500.000000; +Vision_min = 200.000000; +Vision_max = 800.000000; +Vision_step = 100.000000; +Vision_ps0 = 200.0; +Vision_ps1 = 400.0; +Vision_ps2 = 500.0; +Vision_ps3 = 800.0; + +MicroVeget = 1; // Enable/Disable MicroVeget. +MicroVeget_ps0 = 0; +MicroVeget_ps1 = 1; +MicroVeget_ps2 = 1; +MicroVeget_ps3 = 1; + +MicroVegetDensity = 80.0; +MicroVegetDensity_min = 10.0; +MicroVegetDensity_max = 100.0; +MicroVegetDensity_step = 10.0; +MicroVegetDensity_ps0 = 10.0; // not used since disabled! +MicroVegetDensity_ps1 = 30.0; +MicroVegetDensity_ps2 = 80.0; +MicroVegetDensity_ps3 = 100.0; + + +// *** FX +FxNbMaxPoly = 20000; +FxNbMaxPoly_min = 2000; +FxNbMaxPoly_max = 50000; +FxNbMaxPoly_step= 2000; +FxNbMaxPoly_ps0 = 2000; +FxNbMaxPoly_ps1 = 10000; +FxNbMaxPoly_ps2 = 20000; +FxNbMaxPoly_ps3 = 50000; + +Cloud = 1; +Cloud_ps0 = 0 ; +Cloud_ps1 = 1 ; +Cloud_ps2 = 1 ; +Cloud_ps3 = 1 ; + +CloudQuality = 160.0; +CloudQuality_min = 80.0; +CloudQuality_max = 320.0; +CloudQuality_step = 20.0; +CloudQuality_ps0 = 80.0; // not used since disabled! +CloudQuality_ps1 = 80.0; +CloudQuality_ps2 = 160.0; +CloudQuality_ps3 = 320.0; + +CloudUpdate = 1; +CloudUpdate_min = 1; +CloudUpdate_max = 8; +CloudUpdate_step= 1; +CloudUpdate_ps0 = 1; // not used since disabled! +CloudUpdate_ps1 = 1; +CloudUpdate_ps2 = 1; +CloudUpdate_ps3 = 3; + +Shadows = 1; +Shadows_ps0 = 0; +Shadows_ps1 = 1; +Shadows_ps2 = 1; +Shadows_ps3 = 1; + +FXAA = 1; +FXAA_ps0 = 0; +FXAA_ps1 = 1; +FXAA_ps2 = 1; +FXAA_ps3 = 1; + +AnisotropicFilter = 0; + +Bloom = 1; +Bloom_ps0 = 0; +Bloom_ps1 = 1; +Bloom_ps2 = 1; +Bloom_ps3 = 1; + +SquareBloom = 1; +SquareBloom_ps0 = 0; +SquareBloom_ps1 = 1; +SquareBloom_ps2 = 1; +SquareBloom_ps3 = 1; + +DensityBloom = 255.0; +DensityBloom_min = 0.0; +DensityBloom_max = 255.0; +DensityBloom_step = 1.0; +DensityBloom_ps0 = 255.0; +DensityBloom_ps1 = 255.0; +DensityBloom_ps2 = 255.0; +DensityBloom_ps3 = 255.0; + + +// *** CHARACTERS +SkinNbMaxPoly = 100000; +SkinNbMaxPoly_min = 5000; +SkinNbMaxPoly_max = 250000; +SkinNbMaxPoly_step = 5000; +SkinNbMaxPoly_ps0 = 10000; +SkinNbMaxPoly_ps1 = 70000; +SkinNbMaxPoly_ps2 = 100000; +SkinNbMaxPoly_ps3 = 200000; + +NbMaxSkeletonNotCLod = 125; +NbMaxSkeletonNotCLod_min = 5; +NbMaxSkeletonNotCLod_max = 255; +NbMaxSkeletonNotCLod_step = 5; +NbMaxSkeletonNotCLod_ps0 = 10; +NbMaxSkeletonNotCLod_ps1 = 50; +NbMaxSkeletonNotCLod_ps2 = 125; +NbMaxSkeletonNotCLod_ps3 = 255; + +CharacterFarClip = 200.0; +CharacterFarClip_min = 50.0; +CharacterFarClip_max = 500.0; +CharacterFarClip_step = 10.0; +CharacterFarClip_ps0 = 50.0; +CharacterFarClip_ps1 = 100.0; +CharacterFarClip_ps2 = 200.0; +CharacterFarClip_ps3 = 500.0; + +EnableRacialAnimation = 1; + +// *** MISC +// This is the actual aspect ratio of your screen (no relation with the resolution!!). Set 1.7777 if you got a 16/9 screen for instance +ScreenAspectRatio = 0.0; +ForceDXTC = 1; // Enable/Disable DXTC. +DivideTextureSizeBy2= 0; // Divide texture size +DisableVtxProgram = 0; // Disable Hardware Vertex Program. +DisableVtxAGP = 0; // Disable Hardware Vertex AGP. +DisableTextureShdr = 0; // Disable Hardware Texture Shader. +HDEntityTexture = 1; +HDTextureInstalled = 1; +WaitVBL = 0; // 0 or 1 to wait Vertical Sync. + +////////////////// +// GAME OPTIONS // +////////////////// +SelectWithRClick = 1; +DisplayWeapons = 1; +RotKeySpeedMax = 2.0; +RotKeySpeedMax_min = 1.0; +RotKeySpeedMax_max = 4.0; +RotKeySpeedMin = 1.0; +RotKeySpeedMin_min = 0.5; +RotKeySpeedMin_max = 2.0; +RotAccel = 3.0; +FollowOnAtk = 0; +AtkOnSelect = 0; +ZCPacsPrim = "gen_bt_col_ext.pacs_prim"; + +///////////////// +// PREFERENCES // +///////////////// +FPV = 0; // FPV(First Person View) : default is false (Third Person View). +CameraHeight = 2.2; // Camera Height (in meter) from the ground (for the Third Person View). +CameraDistance = 3.0; // Camera Distance(in meter) from the user (for the Third Person View). +CameraDistStep = 1.0; +CameraDistMin = 1.0; +CameraDistMax = 25.0; +CameraAccel = 5.0; +CameraSpeedMin = 2.0; +CameraSpeedMax = 100.0; +CameraResetSpeed = 10.0; // Speed in radian/s + +////////////////// +// SOUND CONFIG // +////////////////// +SoundForceSoftwareBuffer= 1; +SoundOn = 1; +UseEax = 0; + +MaxTrack = 32; +MaxTrack_min = 4; +MaxTrack_max = 32; +MaxTrack_step = 4; + +// This is the volume for "InGame" sound FXs +SoundSFXVolume = 1.0; +SoundSFXVolume_min = 0.0; +SoundSFXVolume_max = 1.0; +SoundSFXVolume_step = 0.001; + +// This is volume for "InGame" music. Does not affect the MP3 player +SoundGameMusicVolume = 0.5; +SoundGameMusicVolume_min = 0.0; +SoundGameMusicVolume_max = 1.0; +SoundGameMusicVolume_step = 0.001; + +// MISC +PreDataPath = { "user", "patch", "examples", "data/patch_lirria.bnp", "data/fonts", "data/gamedev.bnp" }; +DataPath = { "data" }; +NeedComputeVS = 0; + +NegFiltersDebug = {"Update DB", "Reading:", "Read Value :", "impulseCallBack", "CLIMPD:", "LNET" }; +NegFiltersInfo = { "CLIMPD:", "CPath::lookup" , "LNET" }; +NegFiltersWarning = { "'basics.Equipment Slot'.", "_usercolor.tga", "PACS" }; + +// Big screen shot +ScreenShotWidth = 0; +ScreenShotHeight = 0; +ScreenShotFullDetail = 1; // 1 to switch full detail mode for characters (both standard & big screenshots) + +// Read : "ID", "R G B A MODE [FX]" +SystemInfoColors = +{ +// OLD STUFF Here for compatibility +"RG", "0 0 0 255 normal", // Black to see when there is an error +"BC", "0 0 0 255 normal", // Black to see when there is an error +"JA", "0 0 0 255 normal", // Black to see when there is an error +"BL", "0 0 0 255 normal", // Black to see when there is an error +"VE", "0 0 0 255 normal", // Black to see when there is an error +"VI", "0 0 0 255 normal", // Black to see when there is an error + +// NEW System Info Categories +"SYS", "255 255 255 255 normal", // Default system messages +"BC", "255 255 255 255 centeraround", // Broadcast messages +"TAGBC", "255 255 255 255 centeraround", // Taged broadcast messages : color should remain white as some word are tagged +"XP", "255 255 64 255 over", // XP Gain +"SP", "255 255 64 255 over", // SP Gain +"TTL", "255 255 64 255 over", // Title +"TSK", "255 255 255 255 over", // Task +"ZON", "255 255 255 255 center", // Zone +"DG", "255 0 0 255 normal", // Damage to me +"DMG", "255 0 0 255 normal", // Damage to me +"DGP", "200 0 0 255 normal", // Damage to me from player +"DGM", "255 128 64 255 normal", // Damage from me +"MIS", "150 150 150 255 normal", // The opponent misses +"MISM", "255 255 255 255 normal", // I miss +"ITM", "0 200 0 255 over", // Item +"ITMO", "170 170 255 255 overonly", // Item other in group +"ITMF", "220 0 220 255 over", // Item failed +"SPL", "50 50 250 255 normal", // Spell to me +"SPLM", "50 150 250 255 normal", // Spell from me +"EMT", "255 150 150 255 normal", // Emote +"MTD", "255 255 0 255 over", // Message Of The Day +"FORLD","64 255 64 255 overonly", // Forage Locate Deposit +"CHK", "255 120 60 255 center", // Tous ce qui ne remplit pas une condition +"CHKCB","255 255 0 255 center", // Tous ce qui ne remplit pas une condition en combat (trop loin, cible invalide, pas assez de mana, etc.) +"PVPTM","255 120 60 255 overonly", // PVP timer +"THM", "255 255 64 255 over misc_levelup.ps", // Thema finished +"AMB", "255 255 64 255 center", // Ambiance +"ISE", "192 208 255 255 normal", // Item special effect +"ISE2", "192 208 255 255 center", // Item special effect with center text (for effects without flying text) +"OSM", "128 160 255 255 center", // Outpost state message +"AROUND","255 255 0 255 around", // Only in around channel +"R2_INVITE","0 255 0 255 around", // Ring invitation +}; + +PrintfCommands = { + "52", "15", "55 55 0 255", "28", "uiEonSymbiose", "624", + "428", "0 0 0 255", "18", "", "624", "378", + "0 0 0 255", "14", "", "644", "278", "0 0 0 255", + "18", "", "52", "17", "255 255 255 255", "28", + "uiEonSymbiose", "622", "430", "255 255 255 255", "18", "", + "622", "380", "255 255 255 255", "14", "", "642", + "280", "255 255 255 255", "18", "" +}; + +PrintfCommandsFreeTrial = { + "52", "15", "55 55 0 255", "28", "uiEonSymbiose", "624", + "428", "0 0 0 255", "18", "", "624", "378", + "0 0 0 255", "14", "", "644", "278", "0 0 0 255", + "18", "", "52", "17", "255 255 255 255", "28", + "uiEonSymbiose", "622", "430", "255 255 255 255", "18", "", + "622", "380", "255 255 255 255", "14", "", "642", + "280", "255 255 255 255", "18", "" +}; + +DisplayMissingAnimFile = 0; + +LoadingStringCount = 54; + + +// Some R2 parameters ... + +R2Mode = 1; +R2EDEnabled = 1; +R2EDExtendedDebug = 0; +R2EDLightPalette = 0; +R2ClientGw = "r2linux01"; +LoadLuaDebugger = 0; +CheckR2ScenarioMD5 = 1; +LevelDesignEnabled = 0; + +DmCameraDistMax = 25; +DmRun = 20; +DmWalk = 6; + +R2EDReloadFiles = { + "r2ed.xml", + "r2_basic_bricks.lua", + "r2_components.lua", + "r2_core.lua", + "r2_features_default.lua", + "r2_features_fauna.lua", + "r2_features_npc_groups.lua", + "r2_palette.lua", + "r2_scenario.lua", + "r2_ui.lua" +}; + +XMLInterfaceFiles = { + "config.xml", + "widgets.xml", + "webig_widgets.xml", + "player.xml", + "inventory.xml", + "interaction.xml", + "phrase.xml", + "harvest.xml", + "macros.xml", + "info_player.xml", + "outpost.xml", + "guild.xml", + "taskbar.xml", + "game_config.xml", + "game_context_menu.xml", + "player_trade.xml", + "bot_chat_v4.xml", + "compass.xml", + "map.xml", + "hierarchy.xml", + "reset.xml", + "actions.xml", + "help.xml", + "encyclopedia.xml", + "commands.xml", + "commands2.xml", + "ring_access_point_filter.xml", + "ring_window.xml", + "bg_downloader.xml" +}; + +XMLR2EDInterfaceFiles = +{ + "r2ed.xml", + "r2_triggers.xml", + "r2_logic_entities.xml", + "r2ed_acts.xml", + "r2ed_scenario.xml", + "r2ed_connect.xml" +}; + +FogDistAndDepthLookupBias = 20; // bias for lookup of fog distance and depth + + +// Hardware cursor textures +// These will be extracted from the corresponding packed ui .tga files when they are loaded +// * +// * individual .tga files for hardware cursor bitmap not looked for, and not supported yet +HardwareCursors = +{ + "curs_can_pan.tga", + "curs_can_pan_dup.tga", + "curs_create.tga", + "curs_create_multi.tga", + "curs_create_vertex_invalid.tga", + "curs_default.tga", + "curs_dup.tga", + "curs_L.tga", + "curs_M.tga", + "curs_pan.tga", + "curs_pan_dup.tga", + "curs_pick.tga", + "curs_pick_dup.tga", + "curs_R.tga", + "curs_resize_BL_TR.tga", + "curs_resize_BR_TL.tga", + "curs_resize_LR.tga", + "curs_resize_TB.tga", + "curs_rotate.tga", + "curs_scale.tga", + "curs_stop.tga", + "text_cursor.tga", + "r2_hand_can_pan.tga", + "r2_hand_pan.tga", + "r2ed_tool_can_pick.tga", + "r2ed_tool_can_rotate.tga", + "r2ed_tool_pick.tga", + "r2ed_tool_rotate.tga", + "r2ed_tool_rotating.tga" +}; + +Loading_BG = "new_loading_bg.tga"; // Default name for the loading background file. +Launch_BG = "new_launcher_bg.tga"; // Default name for the launch background file. +TeleportKami_BG = "new_teleport_kami_bg.tga"; +TeleportKaravan_BG = "new_teleport_caravan_bg.tga"; +Elevator_BG = "new_elevator_bg.tga"; // Default name for the loading background file. +ResurectKami_BG = "new_resurect_kami_bg.tga"; +ResurectKaravan_BG = "new_resurect_caravane_bg.tga"; +End_BG = "end_bg.tga"; // Default name for the last background file. + +ScenarioSavePath = "./my_scenarios/"; + +// list ofpredefined keyset +// name will be looked up in the translation file by searching 'uiCP_KeysetName_" + id +// tooltip will be looked up in the translation file by searching 'uiCP_KeysetTooltip_" + id +// 'bi.' stands for built-in +// note : we add a dot in the name to be sure that there cannot be a conflict with character keyset name +BuiltInKeySets = +{ + "", // default ryzom keyboard layout + "bi.zqsd", // european keyboard fps displacement style (NB : don't change this layout name, ryzom will automatically select it if keyboard is french or belgian) + "bi.wasd", // english keyboard fps displacement style (NB : don't change this layout name, ryzom will automatically select it if keyboard is not french nor belgian) + "bi.wow_alike" // 'world of warcraft' like keyboard style. (NB : not available for ring) +}; + +// "Newbie Training", "Story Telling", "Mistery", "Hack & Slash", "Guild Training", "Other" +ScenarioTypes = {"so_newbie_training","so_story_telling","so_mistery","so_hack_slash","so_guild_training","so_other"}; + +ScenarioLanguages = {"fr","de","en","other_lang"}; + +// Map each language to a forum help page +HelpPages = +{ + "fr=http://www.khaganat.net/forum/index.php/board,31.0.html", + "en=http://www.khaganat.net/forum/index.php/board,31.0.html", + "wk=http://www.khaganat.net/forum/index.php/board,31.0.html", + "de=http://www.khaganat.net/forum/index.php/board,31.0.html", + "es=http://www.khaganat.net/forum/index.php/board,31.0.html", + "ru=http://www.khaganat.net/forum/index.php/board,31.0.html" +}; + +WebIgMainDomain = "app.khaganat.net"; +WebIgTrustedDomains = { + "api.khaganat.net", "app.khaganat.net", "lirria.khaganat.net" +}; +//PatchletUrl = ""; + +SelectedSlot = 0; + +BuildName = "RELEASE_HEAD"; diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/actions.xml b/code/ryzom/client/data/gamedev/interfaces_v3/actions.xml index 8696de32a..5fb009adf 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/actions.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/actions.xml @@ -77,70 +77,51 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -166,7 +147,7 @@ - + @@ -191,84 +172,150 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -295,239 +342,101 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/hierarchy.xml b/code/ryzom/client/data/gamedev/interfaces_v3/hierarchy.xml index 737db5c59..9499119ee 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/hierarchy.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/hierarchy.xml @@ -110,15 +110,15 @@ - - - - + - - + + + - + + + diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/macros.xml b/code/ryzom/client/data/gamedev/interfaces_v3/macros.xml index 65d6394d7..bbc7ffade 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/macros.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/macros.xml @@ -207,17 +207,15 @@ - - + + + - - - - - - + + + @@ -648,6 +646,7 @@ + diff --git a/code/ryzom/client/macosx/khanat.icns b/code/ryzom/client/macosx/khanat.icns new file mode 100644 index 0000000000000000000000000000000000000000..fafeddeb2544f486d5901f0f9b6f06b8abd59ac4 GIT binary patch literal 205375 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 z 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 Dl&0p0 literal 0 HcmV?d00001 diff --git a/code/ryzom/client/src/CMakeLists.txt b/code/ryzom/client/src/CMakeLists.txt index dec6492a8..3189d0baa 100644 --- a/code/ryzom/client/src/CMakeLists.txt +++ b/code/ryzom/client/src/CMakeLists.txt @@ -51,11 +51,11 @@ IF(WITH_RYZOM_CLIENT) # on Mac, create a .App Bundle if(APPLE) - SET(MACOSX_BUNDLE_INFO_STRING "Ryzom") - SET(MACOSX_BUNDLE_ICON_FILE "ryzom.icns") - SET(MACOSX_BUNDLE_GUI_IDENTIFIER "com.winchgate.Ryzom") + SET(MACOSX_BUNDLE_INFO_STRING "Khanat") + SET(MACOSX_BUNDLE_ICON_FILE "khanat.icns") + SET(MACOSX_BUNDLE_GUI_IDENTIFIER "com.khaganat.khanat") SET(MACOSX_BUNDLE_LONG_VERSION_STRING ${RYZOM_VERSION}) - SET(MACOSX_BUNDLE_BUNDLE_NAME "Ryzom") + SET(MACOSX_BUNDLE_BUNDLE_NAME "Khanat") SET(MACOSX_BUNDLE_SHORT_VERSION_STRING ${RYZOM_VERSION}) SET(MACOSX_BUNDLE_BUNDLE_VERSION "1.0") SET(MACOSX_BUNDLE_COPYRIGHT ${COPYRIGHT}) @@ -72,7 +72,7 @@ IF(WITH_RYZOM_CLIENT) SET_TARGET_PROPERTIES(ryzom_client PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${MAC_RESOURCES_DIR}/Info.plist) ADD_CUSTOM_COMMAND(TARGET ryzom_client PRE_BUILD COMMAND mkdir -p ${RYZOM_RESOURCES_DIR}) ADD_CUSTOM_COMMAND(TARGET ryzom_client POST_BUILD COMMAND cp ARGS -p ${MAC_RESOURCES_DIR}/PkgInfo ${RYZOM_CONTENTS_DIR}) - ADD_CUSTOM_COMMAND(TARGET ryzom_client POST_BUILD COMMAND cp ARGS -p ${MAC_RESOURCES_DIR}/ryzom.icns ${RYZOM_RESOURCES_DIR}) + ADD_CUSTOM_COMMAND(TARGET ryzom_client POST_BUILD COMMAND cp ARGS -p ${MAC_RESOURCES_DIR}/khanat.icns ${RYZOM_RESOURCES_DIR}) ADD_CUSTOM_COMMAND(TARGET ryzom_client POST_BUILD COMMAND cp ARGS -p ${CMAKE_SOURCE_DIR}/ryzom/client/client_default.cfg ${RYZOM_RESOURCES_DIR}) # remove any present installscript_osx.vdf before signing diff --git a/code/ryzom/client/src/client.cpp b/code/ryzom/client/src/client.cpp index 61b30b4c9..a4d43ab9d 100644 --- a/code/ryzom/client/src/client.cpp +++ b/code/ryzom/client/src/client.cpp @@ -376,7 +376,7 @@ int main(int argc, char **argv) // if client_default.cfg is not in current directory, use application default directory if (!CFile::isExists("client_default.cfg")) { - std::string currentPath = CPath::getApplicationDirectory("Ryzom"); + std::string currentPath = CPath::getApplicationDirectory("Khanat"); if (!CFile::isExists(currentPath)) CFile::createDirectory(currentPath); diff --git a/code/ryzom/client/src/commands.cpp b/code/ryzom/client/src/commands.cpp index f958869f5..572e2e620 100644 --- a/code/ryzom/client/src/commands.cpp +++ b/code/ryzom/client/src/commands.cpp @@ -145,11 +145,11 @@ static std::vector ShapeAddedByCommand; // list of shapes added with // Function to release all things allocated for commands. void releaseCommands() { - if(LDPrim) - { - delete LDPrim; - LDPrim = 0; - } + if(LDPrim) + { + delete LDPrim; + LDPrim = 0; + } } ////////////// @@ -159,181 +159,181 @@ void releaseCommands() // 'follow' : To Follow the target. NLMISC_COMMAND(follow, "Follow the target", "") { - // switch - if(UserEntity->follow()) - UserEntity->disableFollow(); - else - // enable follow, reseting the camera rotation - UserEntity->enableFollow(true); - return true; + // switch + if(UserEntity->follow()) + UserEntity->disableFollow(); + else + // enable follow, reseting the camera rotation + UserEntity->enableFollow(true); + return true; } NLMISC_COMMAND(where, "Ask information on the position", "") { - // Check parameters. - if(args.size() == 0) - { // Create the message and send. - const string msgName = "COMMAND:WHERE"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - NetMngr.push(out); - } - else - nlwarning("command 'where': unknown message named '%s'", msgName.c_str()); - return true; + // Check parameters. + if(args.size() == 0) + { // Create the message and send. + const string msgName = "COMMAND:WHERE"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + NetMngr.push(out); } - return false; + else + nlwarning("command 'where': unknown message named '%s'", msgName.c_str()); + return true; + } + return false; } NLMISC_COMMAND(who, "Display all players currently in region","[]") { - // Check parameters. - if(args.size() > 1) - return false; + // Check parameters. + if(args.size() > 1) + return false; - CBitMemStream out; - if(!GenericMsgHeaderMngr.pushNameToStream("DEBUG:WHO", out)) - { - nlwarning("Unknown message name DEBUG:WHO"); - return false; - } + CBitMemStream out; + if(!GenericMsgHeaderMngr.pushNameToStream("DEBUG:WHO", out)) + { + nlwarning("Unknown message name DEBUG:WHO"); + return false; + } - string opt; - if ( args.size() == 1 ) - { - opt = args[0]; - } - out.serial(opt); - NetMngr.push(out); - return true; + string opt; + if ( args.size() == 1 ) + { + opt = args[0]; + } + out.serial(opt); + NetMngr.push(out); + return true; } NLMISC_COMMAND(afk, "Set the player as 'away from keyboard'","[]") { - string customText; - if( args.size() > 0 ) - { - customText = args[0]; - } - for(uint i = 1; i < args.size(); ++i ) - { - customText += " "; - customText += args[i]; - } + string customText; + if( args.size() > 0 ) + { + customText = args[0]; + } + for(uint i = 1; i < args.size(); ++i ) + { + customText += " "; + customText += args[i]; + } - if (UserEntity != NULL) - UserEntity->setAFK(true,customText); -/* - CBitMemStream out; - if(!GenericMsgHeaderMngr.pushNameToStream("DEBUG:AFK", out)) - { - nlwarning("Unknown message name DEBUG:AFK"); - return false; - } - NetMngr.push(out); -*/ - return true; + if (UserEntity != NULL) + UserEntity->setAFK(true,customText); + /* + CBitMemStream out; + if(!GenericMsgHeaderMngr.pushNameToStream("DEBUG:AFK", out)) + { + nlwarning("Unknown message name DEBUG:AFK"); + return false; + } + NetMngr.push(out); + */ + return true; } bool randomCheckCharset(std::string const& str) { - std::string::const_iterator it, itEnd = str.end(); - for (it=str.begin(); it!=itEnd; ++it) - if (*it<'0' || *it>'9') - return false; - return true; + std::string::const_iterator it, itEnd = str.end(); + for (it=str.begin(); it!=itEnd; ++it) + if (*it<'0' || *it>'9') + return false; + return true; } // returns true if a<=b bool randomLexicographicLess(std::string a, std::string b) { - // Remove leading zeros - while (a.length()>1 && a[0]=='0') - a = a.substr(1); - while (b.length()>1 && b[0]=='0') - b = b.substr(1); - // Longest is the biggest - if (a.length()>b.length()) - return false; - if (a.length()1 && a[0]=='0') + a = a.substr(1); + while (b.length()>1 && b[0]=='0') + b = b.substr(1); + // Longest is the biggest + if (a.length()>b.length()) + return false; + if (a.length()0) return false; - if (!negative && max<0) return false; - // Check number is not too big nor too small with a lexicographic compare - std::string smin = NLMISC::toString(std::max(min,-min)); - std::string smax = NLMISC::toString(std::max(max,-max)); - bool tooSmall = false, tooBig = false; - if (min>=0 && randomLexicographicLess(sAbsVal, smin)) - tooSmall = true; - if (min<0 && randomLexicographicLess(smin, sAbsVal)) - tooSmall = true; - if (max>=0 && randomLexicographicLess(smax, sAbsVal)) - tooBig = true; - if (max<0 && randomLexicographicLess(sAbsVal, smax)) - tooBig = true; - if (!tooSmall && !tooBig) - { - NLMISC::fromString(str, val); - return true; - } - else - return false; + bool negative = str[0]=='-'; + std::string sAbsVal = str.substr(negative?1:0); + // Check we have only numerical characters + if (!randomCheckCharset(sAbsVal)) + return false; + // Check sign + if (negative && min>0) return false; + if (!negative && max<0) return false; + // Check number is not too big nor too small with a lexicographic compare + std::string smin = NLMISC::toString(std::max(min,-min)); + std::string smax = NLMISC::toString(std::max(max,-max)); + bool tooSmall = false, tooBig = false; + if (min>=0 && randomLexicographicLess(sAbsVal, smin)) + tooSmall = true; + if (min<0 && randomLexicographicLess(smin, sAbsVal)) + tooSmall = true; + if (max>=0 && randomLexicographicLess(smax, sAbsVal)) + tooBig = true; + if (max<0 && randomLexicographicLess(sAbsVal, smax)) + tooBig = true; + if (!tooSmall && !tooBig) + { + NLMISC::fromString(str, val); + return true; + } + else + return false; } NLMISC_COMMAND(random, "Roll a dice and say the result around","[] ") { - // Check parameters. - if (args.size()<1 || args.size()>2) - return false; + // Check parameters. + if (args.size()<1 || args.size()>2) + return false; - sint16 min = 1; - sint16 max; - if (!randomFromString(args[0], max)) + sint16 min = 1; + sint16 max; + if (!randomFromString(args[0], max)) + { + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + ucstring msg = CI18N::get("uiRandomBadParameter"); + strFindReplace(msg, "%s", args[0] ); + pIM->displaySystemInfo(msg); + return false; + } + if (args.size()==2) + { + if (!randomFromString(args[1], min)) { - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - ucstring msg = CI18N::get("uiRandomBadParameter"); - strFindReplace(msg, "%s", args[0] ); - pIM->displaySystemInfo(msg); - return false; + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + ucstring msg = CI18N::get("uiRandomBadParameter"); + strFindReplace(msg, "%s", args[0] ); + pIM->displaySystemInfo(msg); + return false; } - if (args.size()==2) - { - if (!randomFromString(args[1], min)) - { - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - ucstring msg = CI18N::get("uiRandomBadParameter"); - strFindReplace(msg, "%s", args[0] ); - pIM->displaySystemInfo(msg); - return false; - } - } - if (min>max) - std::swap(min, max); + } + if (min>max) + std::swap(min, max); - if (UserEntity != NULL) - UserEntity->rollDice(min, max); + if (UserEntity != NULL) + UserEntity->rollDice(min, max); - return true; + return true; } //----------------------------------------------- @@ -341,59 +341,59 @@ NLMISC_COMMAND(random, "Roll a dice and say the result around","[] ") //----------------------------------------------- NLMISC_COMMAND(dumpShapePos, "Dump Last Added Shape Pos.", "") { - #if FINAL_VERSION - if (!hasPrivilegeDEV() && - !hasPrivilegeSGM() && - !hasPrivilegeGM() && - !hasPrivilegeVG() && - !hasPrivilegeSG() && - !hasPrivilegeG() && - !hasPrivilegeEM() && - !hasPrivilegeEG()) - return true; - #endif // FINAL_VERSION +#if FINAL_VERSION + if (!hasPrivilegeDEV() && + !hasPrivilegeSGM() && + !hasPrivilegeGM() && + !hasPrivilegeVG() && + !hasPrivilegeSG() && + !hasPrivilegeG() && + !hasPrivilegeEM() && + !hasPrivilegeEG()) + return true; +#endif // FINAL_VERSION - if (ShapeAddedByCommand.empty()) - { - nlwarning("No shape created yet"); - return false; - } + if (ShapeAddedByCommand.empty()) + { + nlwarning("No shape created yet"); + return false; + } - CInterfaceManager *IM = CInterfaceManager::getInstance(); - CVector pos = ShapeAddedByCommand.back().getPos(); - IM->displaySystemInfo(ucstring(toString("Shape Pos = %f, %f, %f", pos.x, pos.y, pos.z))); - return true; + CInterfaceManager *IM = CInterfaceManager::getInstance(); + CVector pos = ShapeAddedByCommand.back().getPos(); + IM->displaySystemInfo(ucstring(toString("Shape Pos = %f, %f, %f", pos.x, pos.y, pos.z))); + return true; } //----------------------------------------------- // 'clearShape' : Remove all shapes added with the 'shape' command //----------------------------------------------- NLMISC_COMMAND(clearShape, "Remove all shapes added with the 'shape' command.", "") { - #if FINAL_VERSION - /*if (!hasPrivilegeDEV() && - !hasPrivilegeSGM() && - !hasPrivilegeGM() && - !hasPrivilegeVG() && - !hasPrivilegeSG() && - !hasPrivilegeG() && - !hasPrivilegeEM() && - !hasPrivilegeEG()) - return true;*/ - #endif // FINAL_VERSION +#if FINAL_VERSION + /*if (!hasPrivilegeDEV() && + !hasPrivilegeSGM() && + !hasPrivilegeGM() && + !hasPrivilegeVG() && + !hasPrivilegeSG() && + !hasPrivilegeG() && + !hasPrivilegeEM() && + !hasPrivilegeEG()) + return true;*/ +#endif // FINAL_VERSION - if (ShapeAddedByCommand.empty()) - { - nlwarning("No shape created yet"); - return false; - } + if (ShapeAddedByCommand.empty()) + { + nlwarning("No shape created yet"); + return false; + } - if (!Scene) return false; - for(uint k = 0; k < ShapeAddedByCommand.size(); ++k) - { - Scene->deleteInstance(ShapeAddedByCommand[k]); - } - ShapeAddedByCommand.clear(); - return true; + if (!Scene) return false; + for(uint k = 0; k < ShapeAddedByCommand.size(); ++k) + { + Scene->deleteInstance(ShapeAddedByCommand[k]); + } + ShapeAddedByCommand.clear(); + return true; } //----------------------------------------------------- @@ -401,43 +401,43 @@ NLMISC_COMMAND(clearShape, "Remove all shapes added with the 'shape' command.", //----------------------------------------------------- NLMISC_COMMAND(setShapeX, "Set X position for last created shape.", "") { - #if FINAL_VERSION - /*if (!hasPrivilegeDEV() && - !hasPrivilegeSGM() && - !hasPrivilegeGM() && - !hasPrivilegeVG() && - !hasPrivilegeSG() && - !hasPrivilegeG() && - !hasPrivilegeEM() && - !hasPrivilegeEG()) - return true;*/ - #endif // FINAL_VERSION +#if FINAL_VERSION + /*if (!hasPrivilegeDEV() && + !hasPrivilegeSGM() && + !hasPrivilegeGM() && + !hasPrivilegeVG() && + !hasPrivilegeSG() && + !hasPrivilegeG() && + !hasPrivilegeEM() && + !hasPrivilegeEG()) + return true;*/ +#endif // FINAL_VERSION - if (args.size() != 1) return false; - if (ShapeAddedByCommand.empty()) - { - nlwarning("No shape created yet"); - return false; - } - float coord; - bool valid_coord; - if (args[0][0] == '+') - valid_coord = fromString(args[0].substr(1), coord); - else - valid_coord = fromString(args[0], coord); + if (args.size() != 1) return false; + if (ShapeAddedByCommand.empty()) + { + nlwarning("No shape created yet"); + return false; + } + float coord; + bool valid_coord; + if (args[0][0] == '+') + valid_coord = fromString(args[0].substr(1), coord); + else + valid_coord = fromString(args[0], coord); - if (!valid_coord) - { - nlwarning("Can't get position"); - return false; - } - CVector pos = ShapeAddedByCommand.back().getPos(); - if (args[0][0] == '+') - pos.x += coord; - else - pos.x = coord; - ShapeAddedByCommand.back().setPos(pos); - return true; + if (!valid_coord) + { + nlwarning("Can't get position"); + return false; + } + CVector pos = ShapeAddedByCommand.back().getPos(); + if (args[0][0] == '+') + pos.x += coord; + else + pos.x = coord; + ShapeAddedByCommand.back().setPos(pos); + return true; } //----------------------------------------------------- @@ -445,43 +445,43 @@ NLMISC_COMMAND(setShapeX, "Set X position for last created shape.", "") { - #if FINAL_VERSION - /*if (!hasPrivilegeDEV() && - !hasPrivilegeSGM() && - !hasPrivilegeGM() && - !hasPrivilegeVG() && - !hasPrivilegeSG() && - !hasPrivilegeG() && - !hasPrivilegeEM() && - !hasPrivilegeEG()) - return true;*/ - #endif // FINAL_VERSION +#if FINAL_VERSION + /*if (!hasPrivilegeDEV() && + !hasPrivilegeSGM() && + !hasPrivilegeGM() && + !hasPrivilegeVG() && + !hasPrivilegeSG() && + !hasPrivilegeG() && + !hasPrivilegeEM() && + !hasPrivilegeEG()) + return true;*/ +#endif // FINAL_VERSION - if (args.size() != 1) return false; - if (ShapeAddedByCommand.empty()) - { - nlwarning("No shape created yet"); - return false; - } - float coord; - bool valid_coord; - if (args[0][0] == '+') - valid_coord = fromString(args[0].substr(1), coord); - else - valid_coord = fromString(args[0], coord); + if (args.size() != 1) return false; + if (ShapeAddedByCommand.empty()) + { + nlwarning("No shape created yet"); + return false; + } + float coord; + bool valid_coord; + if (args[0][0] == '+') + valid_coord = fromString(args[0].substr(1), coord); + else + valid_coord = fromString(args[0], coord); - if (!valid_coord) - { - nlwarning("Can't get position"); - return false; - } - CVector pos = ShapeAddedByCommand.back().getPos(); - if (args[0][0] == '+') - pos.y += coord; - else - pos.y = coord; - ShapeAddedByCommand.back().setPos(pos); - return true; + if (!valid_coord) + { + nlwarning("Can't get position"); + return false; + } + CVector pos = ShapeAddedByCommand.back().getPos(); + if (args[0][0] == '+') + pos.y += coord; + else + pos.y = coord; + ShapeAddedByCommand.back().setPos(pos); + return true; } //----------------------------------------------------- @@ -489,43 +489,43 @@ NLMISC_COMMAND(setShapeY, "Set Y position for last created shape.", "") { - #if FINAL_VERSION - /*if (!hasPrivilegeDEV() && - !hasPrivilegeSGM() && - !hasPrivilegeGM() && - !hasPrivilegeVG() && - !hasPrivilegeSG() && - !hasPrivilegeG() && - !hasPrivilegeEM() && - !hasPrivilegeEG()) - return true;*/ - #endif // FINAL_VERSION +#if FINAL_VERSION + /*if (!hasPrivilegeDEV() && + !hasPrivilegeSGM() && + !hasPrivilegeGM() && + !hasPrivilegeVG() && + !hasPrivilegeSG() && + !hasPrivilegeG() && + !hasPrivilegeEM() && + !hasPrivilegeEG()) + return true;*/ +#endif // FINAL_VERSION - if (args.size() != 1) return false; - if (ShapeAddedByCommand.empty()) - { - nlwarning("No shape created yet"); - return false; - } - float coord; - bool valid_coord; - if (args[0][0] == '+') - valid_coord = fromString(args[0].substr(1), coord); - else - valid_coord = fromString(args[0], coord); + if (args.size() != 1) return false; + if (ShapeAddedByCommand.empty()) + { + nlwarning("No shape created yet"); + return false; + } + float coord; + bool valid_coord; + if (args[0][0] == '+') + valid_coord = fromString(args[0].substr(1), coord); + else + valid_coord = fromString(args[0], coord); - if (!valid_coord) - { - nlwarning("Can't get position"); - return false; - } - CVector pos = ShapeAddedByCommand.back().getPos(); - if (args[0][0] == '+') - pos.z += coord; - else - pos.z = coord; - ShapeAddedByCommand.back().setPos(pos); - return true; + if (!valid_coord) + { + nlwarning("Can't get position"); + return false; + } + CVector pos = ShapeAddedByCommand.back().getPos(); + if (args[0][0] == '+') + pos.z += coord; + else + pos.z = coord; + ShapeAddedByCommand.back().setPos(pos); + return true; } @@ -534,41 +534,41 @@ NLMISC_COMMAND(setShapeZ, "Set Z position for last created shape.", "") { - #if FINAL_VERSION - /*if (!hasPrivilegeDEV() && - !hasPrivilegeSGM() && - !hasPrivilegeGM() && - !hasPrivilegeVG() && - !hasPrivilegeSG() && - !hasPrivilegeG() && - !hasPrivilegeEM() && - !hasPrivilegeEG()) - return true;*/ - #endif // FINAL_VERSION +#if FINAL_VERSION + /*if (!hasPrivilegeDEV() && + !hasPrivilegeSGM() && + !hasPrivilegeGM() && + !hasPrivilegeVG() && + !hasPrivilegeSG() && + !hasPrivilegeG() && + !hasPrivilegeEM() && + !hasPrivilegeEG()) + return true;*/ +#endif // FINAL_VERSION - if (args.size() != 1) return false; - if (ShapeAddedByCommand.empty()) - { - nlwarning("No shape created yet"); - return false; - } - float angle; - if (!fromString(args[0], angle)) - { - nlwarning("Can't get angle"); - return false; - } + if (args.size() != 1) return false; + if (ShapeAddedByCommand.empty()) + { + nlwarning("No shape created yet"); + return false; + } + float angle; + if (!fromString(args[0], angle)) + { + nlwarning("Can't get angle"); + return false; + } - CMatrix dir; - dir.identity(); - CVector vangle = CVector(sin(angle), cos(angle), 0.f); - CVector vi = vangle^CVector(0.f, 0.f, 1.f); - CVector vk = vi^vangle; - dir.setRot(vi, vangle, vk, true); - // Set Orientation : User Direction should be normalized. - ShapeAddedByCommand.back().setRotQuat(dir.getRot()); + CMatrix dir; + dir.identity(); + CVector vangle = CVector(sin(angle), cos(angle), 0.f); + CVector vi = vangle^CVector(0.f, 0.f, 1.f); + CVector vk = vi^vangle; + dir.setRot(vi, vangle, vk, true); + // Set Orientation : User Direction should be normalized. + ShapeAddedByCommand.back().setRotQuat(dir.getRot()); - return true; + return true; } @@ -577,156 +577,156 @@ NLMISC_COMMAND(setShapeDir, "Set direction angle for last created shape.", "") { - #if FINAL_VERSION -/* if (!hasPrivilegeDEV() && - !hasPrivilegeSGM() && - !hasPrivilegeGM() && - !hasPrivilegeVG() && - !hasPrivilegeSG() && - !hasPrivilegeG() && - !hasPrivilegeEM() && - !hasPrivilegeEG()) - return true;*/ - #endif // FINAL_VERSION +#if FINAL_VERSION + /* if (!hasPrivilegeDEV() && + !hasPrivilegeSGM() && + !hasPrivilegeGM() && + !hasPrivilegeVG() && + !hasPrivilegeSG() && + !hasPrivilegeG() && + !hasPrivilegeEM() && + !hasPrivilegeEG()) + return true;*/ +#endif // FINAL_VERSION - if(args.size() < 1) + if(args.size() < 1) + { + nlwarning("Command 'shape': need at least 1 parameter, try '/help shape' for more details."); + return false; + } + if (!Scene) + { + nlwarning("No scene available"); + return false; + } + UInstance instance = Scene->createInstance(args[0]); + if(!instance.empty()) + { + ShapeAddedByCommand.push_back(instance); + // Set the position + instance.setPos(UserEntity->pos()); + instance.setClusterSystem(UserEntity->getClusterSystem()); // for simplicity, assume it is in the same + // cluster system than the user + // Compute the direction Matrix + CMatrix dir; + dir.identity(); + CVector vi = UserEntity->dir()^CVector(0.f, 0.f, 1.f); + CVector vk = vi^UserEntity->dir(); + dir.setRot(vi, UserEntity->dir(), vk, true); + // Set Orientation : User Direction should be normalized. + instance.setRotQuat(dir.getRot()); + // if the shape is a particle system, additionnal parameters are user params + UParticleSystemInstance psi; + psi.cast (instance); + if (!psi.empty()) { - nlwarning("Command 'shape': need at least 1 parameter, try '/help shape' for more details."); - return false; - } - if (!Scene) - { - nlwarning("No scene available"); - return false; - } - UInstance instance = Scene->createInstance(args[0]); - if(!instance.empty()) - { - ShapeAddedByCommand.push_back(instance); - // Set the position - instance.setPos(UserEntity->pos()); - instance.setClusterSystem(UserEntity->getClusterSystem()); // for simplicity, assume it is in the same - // cluster system than the user - // Compute the direction Matrix - CMatrix dir; - dir.identity(); - CVector vi = UserEntity->dir()^CVector(0.f, 0.f, 1.f); - CVector vk = vi^UserEntity->dir(); - dir.setRot(vi, UserEntity->dir(), vk, true); - // Set Orientation : User Direction should be normalized. - instance.setRotQuat(dir.getRot()); - // if the shape is a particle system, additionnal parameters are user params - UParticleSystemInstance psi; - psi.cast (instance); - if (!psi.empty()) + // set each user param that is present + for(uint k = 0; k < 4; ++k) + { + if (args.size() >= (k + 2)) { - // set each user param that is present - for(uint k = 0; k < 4; ++k) - { - if (args.size() >= (k + 2)) - { - float uparam; - if (fromString(args[k + 1], uparam)) - { - psi.setUserParam(k, uparam); - } - else - { - nlwarning("Cant read param %d", k); - } - } - } + float uparam; + if (fromString(args[k + 1], uparam)) + { + psi.setUserParam(k, uparam); + } + else + { + nlwarning("Cant read param %d", k); + } } + } } - else - { - nlwarning("Command 'shape': cannot find the shape %s.", args[0].c_str()); - } + } + else + { + nlwarning("Command 'shape': cannot find the shape %s.", args[0].c_str()); + } - // Command Well Done - return true; + // Command Well Done + return true; } NLMISC_COMMAND(bugReport, "Call the bug report tool with dump", "") { - const char *brname[] = { "bug_report.exe", "bug_report_r.exe", "bug_report_rd.exe", "bug_report_df.exe", "bug_report_d.exe" }; + const char *brname[] = { "bug_report.exe", "bug_report_r.exe", "bug_report_rd.exe", "bug_report_df.exe", "bug_report_d.exe" }; - string brn; + string brn; - for (uint i = 0; i < sizeof(brname)/sizeof(brname[0]); i++) + for (uint i = 0; i < sizeof(brname)/sizeof(brname[0]); i++) + { + if (CFile::fileExists (brname[i])) { - if (CFile::fileExists (brname[i])) - { - brn = brname[i]; - break; - } + brn = brname[i]; + break; } + } - if (brn.empty()) - { - log.displayNL("bug_report*.exe not found"); - return false; - } + if (brn.empty()) + { + log.displayNL("bug_report*.exe not found"); + return false; + } - string sys; + string sys; - sys = "Language "+CI18N::getCurrentLanguageName().toString() +" "; + sys = "Language "+CI18N::getCurrentLanguageName().toString() +" "; - if (args.size()>0) - { - uint8 quality; - fromString(args[0], quality); - if (quality == 0) - quality = 80; + if (args.size()>0) + { + uint8 quality; + fromString(args[0], quality); + if (quality == 0) + quality = 80; - CBitmap btm; - Driver->getBuffer(btm); - string filename = CFile::findNewFile (getLogDirectory() + "screenshot.jpg"); - COFile fs(filename); - btm.writeJPG(fs, quality); - sys += "AttachedFile "+filename+" "; - } + CBitmap btm; + Driver->getBuffer(btm); + string filename = CFile::findNewFile (getLogDirectory() + "screenshot.jpg"); + COFile fs(filename); + btm.writeJPG(fs, quality); + sys += "AttachedFile "+filename+" "; + } - sys += NLMISC::toString("ClientVersion %s ", getVersion().c_str()); + sys += NLMISC::toString("ClientVersion %s ", getVersion().c_str()); - // for now, set the same version than client one - sys += NLMISC::toString("ShardVersion %s ", getVersion().c_str()); + // for now, set the same version than client one + sys += NLMISC::toString("ShardVersion %s ", getVersion().c_str()); - if (ClientCfg.Local) - sys += "ShardName OFFLINE "; + if (ClientCfg.Local) + sys += "ShardName OFFLINE "; - FILE *fp = fopen (std::string(getLogDirectory() + "bug_report.txt").c_str(), "wb"); - if (fp != NULL) - { - string res = addSlashR(getDebugInformation()); + FILE *fp = fopen (std::string(getLogDirectory() + "bug_report.txt").c_str(), "wb"); + if (fp != NULL) + { + string res = addSlashR(getDebugInformation()); - // must put \r\n each line - fprintf(fp, "%s", res.c_str()); + // must put \r\n each line + fprintf(fp, "%s", res.c_str()); -// // must put \r\n each line -// fprintf (fp, "UserId: %u\r\n", NetMngr.getUserId()); -// fprintf (fp, "Player Name: '%s'.\r\n", UserEntity->getName().toString().c_str()); -// fprintf (fp, "UserPosition: %.2f %.2f %.2f\r\n", UserEntity->pos().x, UserEntity->pos().y, UserEntity->pos().z); -// fprintf (fp, "ViewPosition: %.2f %.2f %.2f\r\n", View.viewPos().x, View.viewPos().y, View.viewPos().z); -// time_t ts; time( &ts ); -// fprintf (fp, "LocalTime: %s\r\n", NLMISC::IDisplayer::dateToHumanString( ts ) ); -// fprintf (fp, "ServerTick: %u\r\n", NetMngr.getCurrentServerTick()); -// fprintf (fp, "ConnectState: %s\r\n", NetMngr.getConnectionStateCStr()); -// fprintf (fp, "LocalAddress: %s\r\n", NetMngr.getAddress().asString().c_str()); + // // must put \r\n each line + // fprintf (fp, "UserId: %u\r\n", NetMngr.getUserId()); + // fprintf (fp, "Player Name: '%s'.\r\n", UserEntity->getName().toString().c_str()); + // fprintf (fp, "UserPosition: %.2f %.2f %.2f\r\n", UserEntity->pos().x, UserEntity->pos().y, UserEntity->pos().z); + // fprintf (fp, "ViewPosition: %.2f %.2f %.2f\r\n", View.viewPos().x, View.viewPos().y, View.viewPos().z); + // time_t ts; time( &ts ); + // fprintf (fp, "LocalTime: %s\r\n", NLMISC::IDisplayer::dateToHumanString( ts ) ); + // fprintf (fp, "ServerTick: %u\r\n", NetMngr.getCurrentServerTick()); + // fprintf (fp, "ConnectState: %s\r\n", NetMngr.getConnectionStateCStr()); + // fprintf (fp, "LocalAddress: %s\r\n", NetMngr.getAddress().asString().c_str()); - fclose (fp); + fclose (fp); - sys += "DumpFilename bug_report.txt "; - } + sys += "DumpFilename bug_report.txt "; + } - nlinfo ("Calling for bug report : '%s %s'", brn.c_str(), sys.c_str()); + nlinfo ("Calling for bug report : '%s %s'", brn.c_str(), sys.c_str()); - launchProgram(brn, sys); + launchProgram(brn, sys); - // give some cpu to the launched application - nlSleep (3000); + // give some cpu to the launched application + nlSleep (3000); - return true; + return true; } // @@ -738,39 +738,39 @@ NLMISC_COMMAND(bugReport, "Call the bug report tool with dump", " NLMISC_COMMAND(a, "Execute an admin command on you"," ") { - if(args.size() == 0) - return false; + if(args.size() == 0) + return false; - CBitMemStream out; - if (!GenericMsgHeaderMngr.pushNameToStream("COMMAND:ADMIN", out)) - return false; + CBitMemStream out; + if (!GenericMsgHeaderMngr.pushNameToStream("COMMAND:ADMIN", out)) + return false; - string cmd, arg; - cmd = args[0]; - for (uint i = 1; i < args.size(); i++) + string cmd, arg; + cmd = args[0]; + for (uint i = 1; i < args.size(); i++) + { + // temporary fix for utf-8 + // servers commands are not decoded so convert them to ansi + std::string tmp = ucstring::makeFromUtf8(args[i]).toString(); + + if (!arg.empty()) + arg += ' '; + if (tmp.find(' ') != std::string::npos) { - // temporary fix for utf-8 - // servers commands are not decoded so convert them to ansi - std::string tmp = ucstring::makeFromUtf8(args[i]).toString(); - - if (!arg.empty()) - arg += ' '; - if (tmp.find(' ') != std::string::npos) - { - arg += "\"" + tmp + "\""; - } - else - { - arg += tmp; - } + arg += "\"" + tmp + "\""; } - bool onTarget = false; - out.serial (onTarget); - out.serial (cmd); - out.serial (arg); - NetMngr.push (out); + else + { + arg += tmp; + } + } + bool onTarget = false; + out.serial (onTarget); + out.serial (cmd); + out.serial (arg); + NetMngr.push (out); - return true; + return true; } // @@ -782,39 +782,39 @@ NLMISC_COMMAND(a, "Execute an admin command on you"," ") NLMISC_COMMAND(b, "Execute an admin command on your target"," ") { - if(args.size() == 0) - return false; + if(args.size() == 0) + return false; - CBitMemStream out; - if (!GenericMsgHeaderMngr.pushNameToStream("COMMAND:ADMIN", out)) - return false; + CBitMemStream out; + if (!GenericMsgHeaderMngr.pushNameToStream("COMMAND:ADMIN", out)) + return false; - string cmd, arg; - cmd = args[0]; - for (uint i = 1; i < args.size(); i++) + string cmd, arg; + cmd = args[0]; + for (uint i = 1; i < args.size(); i++) + { + // temporary fix for utf-8 + // servers commands are not decoded so convert them to ansi + std::string tmp = ucstring::makeFromUtf8(args[i]).toString(); + + if (!arg.empty()) + arg += ' '; + if (tmp.find(' ') != std::string::npos) { - // temporary fix for utf-8 - // servers commands are not decoded so convert them to ansi - std::string tmp = ucstring::makeFromUtf8(args[i]).toString(); - - if (!arg.empty()) - arg += ' '; - if (tmp.find(' ') != std::string::npos) - { - arg += "\"" + tmp + "\""; - } - else - { - arg += tmp; - } + arg += "\"" + tmp + "\""; } - bool onTarget = true; - out.serial (onTarget); - out.serial (cmd); - out.serial (arg); - NetMngr.push (out); + else + { + arg += tmp; + } + } + bool onTarget = true; + out.serial (onTarget); + out.serial (cmd); + out.serial (arg); + NetMngr.push (out); - return true; + return true; } // @@ -827,484 +827,484 @@ NLMISC_COMMAND(b, "Execute an admin command on your target"," ") NLMISC_COMMAND(c, "Execute an admin command on character name"," ") { - if(args.size() < 2) - return false; + if(args.size() < 2) + return false; - CBitMemStream out; - if (!GenericMsgHeaderMngr.pushNameToStream("COMMAND:ADMIN_OFFLINE", out)) - return false; + CBitMemStream out; + if (!GenericMsgHeaderMngr.pushNameToStream("COMMAND:ADMIN_OFFLINE", out)) + return false; - string characterName, cmd, arg; + string characterName, cmd, arg; - characterName = args[0]; - cmd = args[1]; - for (uint i = 2; i < args.size(); i++) + characterName = args[0]; + cmd = args[1]; + for (uint i = 2; i < args.size(); i++) + { + // temporary fix for utf-8 + // servers commands are not decoded so convert them to ansi + std::string tmp = ucstring::makeFromUtf8(args[i]).toString(); + + if (!arg.empty()) + arg += ' '; + if (tmp.find(' ') != std::string::npos) { - // temporary fix for utf-8 - // servers commands are not decoded so convert them to ansi - std::string tmp = ucstring::makeFromUtf8(args[i]).toString(); - - if (!arg.empty()) - arg += ' '; - if (tmp.find(' ') != std::string::npos) - { - arg += "\"" + tmp + "\""; - } - else - { - arg += tmp; - } + arg += "\"" + tmp + "\""; } - out.serial (characterName); - out.serial (cmd); - out.serial (arg); - NetMngr.push (out); + else + { + arg += tmp; + } + } + out.serial (characterName); + out.serial (cmd); + out.serial (arg); + NetMngr.push (out); - return true; + return true; } NLMISC_COMMAND(boxes, "Show/Hide selection boxes", "[ : 0 to Hide, anything else to Show. Invert the current state if nothing specified.]") { #if FINAL_VERSION - if (!ClientCfg.ExtendedCommands) return false; + if (!ClientCfg.ExtendedCommands) return false; - if( !ClientCfg.Local && !hasPrivilegeDEV() && !hasPrivilegeSGM() && !hasPrivilegeGM() ) - return true; + if( !ClientCfg.Local && !hasPrivilegeDEV() && !hasPrivilegeSGM() && !hasPrivilegeGM() ) + return true; #endif // FINAL_VERSION - // Invert Current State - if(args.size() == 0) - { - // Invert the current value. - ClientCfg.DrawBoxes = !ClientCfg.DrawBoxes; - return true; - } - // Set Current State - else if(args.size() == 1) - { - // Invert the current value. - fromString(args[0], ClientCfg.DrawBoxes); - return true; - } - // Bad parameters. - else - return false; + // Invert Current State + if(args.size() == 0) + { + // Invert the current value. + ClientCfg.DrawBoxes = !ClientCfg.DrawBoxes; + return true; + } + // Set Current State + else if(args.size() == 1) + { + // Invert the current value. + fromString(args[0], ClientCfg.DrawBoxes); + return true; + } + // Bad parameters. + else + return false; } NLMISC_COMMAND(dump, "Command to create a file with the current state of the client", "[]") { - if(args.size() > 1) - return false; + if(args.size() > 1) + return false; - string dumpName; - if(args.size() == 1) - dumpName = args[0]; - else - dumpName = "default"; + string dumpName; + if(args.size() == 1) + dumpName = args[0]; + else + dumpName = "default"; - dump(dumpName); - return true; + dump(dumpName); + return true; } NLMISC_COMMAND(verbose, "Enable/Disable some Debug Information", "none or magic") { - // Check parameters. - if(args.size() != 1) + // Check parameters. + if(args.size() != 1) + { + // Help + CInterfaceManager *IM = CInterfaceManager::getInstance(); + IM->displaySystemInfo(ucstring("This command need 1 parameter :")); + IM->displaySystemInfo(ucstring(" :")); + IM->displaySystemInfo(ucstring("- none(to remove all verboses)")); + IM->displaySystemInfo(ucstring("- magic(to add debug infos about magic)")); + IM->displaySystemInfo(ucstring("- anim (to add debug infos about animation)")); + } + else + { + std::string type = NLMISC::toLower(args[0]); + if (type == "none") + Verbose = VerboseNone; + else if(type == "magic") + Verbose |= VerboseMagic; + else if(type == "anim") + Verbose |= VerboseAnim; + else { - // Help - CInterfaceManager *IM = CInterfaceManager::getInstance(); - IM->displaySystemInfo(ucstring("This command need 1 parameter :")); - IM->displaySystemInfo(ucstring(" :")); - IM->displaySystemInfo(ucstring("- none(to remove all verboses)")); - IM->displaySystemInfo(ucstring("- magic(to add debug infos about magic)")); - IM->displaySystemInfo(ucstring("- anim (to add debug infos about animation)")); + CInterfaceManager *IM = CInterfaceManager::getInstance(); + IM->displaySystemInfo(ucstring("This command need 1 parameter :")); + IM->displaySystemInfo(ucstring(" :")); + IM->displaySystemInfo(ucstring("- none(to remove all verboses)")); + IM->displaySystemInfo(ucstring("- magic(to add debug infos about magic)")); + IM->displaySystemInfo(ucstring("- anim (to add debug infos about animation)")); } - else - { - std::string type = NLMISC::toLower(args[0]); - if (type == "none") - Verbose = VerboseNone; - else if(type == "magic") - Verbose |= VerboseMagic; - else if(type == "anim") - Verbose |= VerboseAnim; - else - { - CInterfaceManager *IM = CInterfaceManager::getInstance(); - IM->displaySystemInfo(ucstring("This command need 1 parameter :")); - IM->displaySystemInfo(ucstring(" :")); - IM->displaySystemInfo(ucstring("- none(to remove all verboses)")); - IM->displaySystemInfo(ucstring("- magic(to add debug infos about magic)")); - IM->displaySystemInfo(ucstring("- anim (to add debug infos about animation)")); - } - } - return true; + } + return true; } NLMISC_COMMAND(verboseAnimSelection, "Enable/Disable the animation log for the current selection", "") { - // Check parameters. - if(args.size() != 0) - return false; + // Check parameters. + if(args.size() != 0) + return false; - VerboseAnimSelection = !VerboseAnimSelection; - if(VerboseAnimSelection) - nlinfo("Enable VerboseAnimSelection"); - else - nlinfo("Disable VerboseAnimSelection"); + VerboseAnimSelection = !VerboseAnimSelection; + if(VerboseAnimSelection) + nlinfo("Enable VerboseAnimSelection"); + else + nlinfo("Disable VerboseAnimSelection"); - return true; + return true; } NLMISC_COMMAND(verboseAnimUser, "Enable/Disable the animation log for the user", "") { - // Check parameters. - if(args.size() != 0) - return false; + // Check parameters. + if(args.size() != 0) + return false; - VerboseAnimUser = !VerboseAnimUser; - if(VerboseAnimUser) - nlinfo("Enable VerboseAnimUser"); - else - nlinfo("Disable VerboseAnimUser"); + VerboseAnimUser = !VerboseAnimUser; + if(VerboseAnimUser) + nlinfo("Enable VerboseAnimUser"); + else + nlinfo("Disable VerboseAnimUser"); - return true; + return true; } NLMISC_COMMAND(verboseDatabase, "Enable/Disable the log for the database", "") { - // Check parameters. - if(args.size() != 0) - return false; + // Check parameters. + if(args.size() != 0) + return false; - bool v = NLMISC::ICDBNode::isDatabaseVerbose(); - NLMISC::ICDBNode::setVerboseDatabase( !v ); + bool v = NLMISC::ICDBNode::isDatabaseVerbose(); + NLMISC::ICDBNode::setVerboseDatabase( !v ); - if( !v ) - nlinfo("Enable VerboseDatabase"); - else - nlinfo("Disable VerboseDatabase"); + if( !v ) + nlinfo("Enable VerboseDatabase"); + else + nlinfo("Disable VerboseDatabase"); - return true; + return true; } NLMISC_COMMAND(verbosePropertiesLoggingMode, "Set logging mode", "") { - // Check parameters. - if(args.size() != 0) - return false; + // Check parameters. + if(args.size() != 0) + return false; - CNetworkConnection::LoggingMode = !CNetworkConnection::LoggingMode; - if(CNetworkConnection::LoggingMode) - nlinfo("Enable LoggingMode"); - else - nlinfo("Disable LoggingMode"); + CNetworkConnection::LoggingMode = !CNetworkConnection::LoggingMode; + if(CNetworkConnection::LoggingMode) + nlinfo("Enable LoggingMode"); + else + nlinfo("Disable LoggingMode"); - return true; + return true; } NLMISC_COMMAND(logEntities, "Write the position and orientation af all entities in the vision in the file 'entities.txt'", "") { - // Check parameters - if(args.size() != 0) - return false; + // Check parameters + if(args.size() != 0) + return false; - // Log entities - EntitiesMngr.writeEntities(); + // Log entities + EntitiesMngr.writeEntities(); - // Command well done. - return true; + // Command well done. + return true; } NLMISC_COMMAND(log, "Add/Del Positive/Negative Filters for logs", "Log System , Type , Filter ") { - // check args, if there s not the right number of parameter, return bad - if(args.size() < 2 || args.size() > 3) - return false; + // check args, if there s not the right number of parameter, return bad + if(args.size() < 2 || args.size() > 3) + return false; - CLog *logSys; - // Debug log system. - if (string(args[0].c_str()) == "debug") - logSys = DebugLog; - // Info log system. - else if(string(args[0].c_str()) == "info") - logSys = InfoLog; - // Warning log system. - else if(string(args[0].c_str()) == "warning") - logSys = WarningLog; - // Assert log system. - else if(string(args[0].c_str()) == "assert") - logSys = AssertLog; - // Unknown Log System -> return false. - else - return false; + CLog *logSys; + // Debug log system. + if (string(args[0].c_str()) == "debug") + logSys = DebugLog; + // Info log system. + else if(string(args[0].c_str()) == "info") + logSys = InfoLog; + // Warning log system. + else if(string(args[0].c_str()) == "warning") + logSys = WarningLog; + // Assert log system. + else if(string(args[0].c_str()) == "assert") + logSys = AssertLog; + // Unknown Log System -> return false. + else + return false; - // Add a positive filter. - if (string(args[1].c_str()) == "pos") - logSys->addPositiveFilter(args[2].c_str()); - // Add a negative filter. - else if(string(args[1].c_str()) == "neg") - logSys->addNegativeFilter(args[2].c_str()); - // Removes a filter by name (in both filters). - else if(string(args[1].c_str()) == "del") - logSys->removeFilter(args[2].c_str()); - // Reset both filters. - else if(string(args[1].c_str()) == "reset") - logSys->resetFilters(); - // Unknown Filter -> return false. - else - return false; + // Add a positive filter. + if (string(args[1].c_str()) == "pos") + logSys->addPositiveFilter(args[2].c_str()); + // Add a negative filter. + else if(string(args[1].c_str()) == "neg") + logSys->addNegativeFilter(args[2].c_str()); + // Removes a filter by name (in both filters). + else if(string(args[1].c_str()) == "del") + logSys->removeFilter(args[2].c_str()); + // Reset both filters. + else if(string(args[1].c_str()) == "reset") + logSys->resetFilters(); + // Unknown Filter -> return false. + else + return false; - // Command well done. - return true; + // Command well done. + return true; } NLMISC_COMMAND(execScript, "Execute a script file (.cmd)","") { - int size = (int)args.size(); - if (size != 1) - return false; + int size = (int)args.size(); + if (size != 1) + return false; - CIFile iFile; + CIFile iFile; - if (iFile.open(CPath::lookup(args[0], false))) + if (iFile.open(CPath::lookup(args[0], false))) + { + char line[512]; + char *buffer; + // Read line by line and execute each line + + sint inComment= 0; + bool eof = false; + while (!eof) { - char line[512]; - char *buffer; - // Read line by line and execute each line - - sint inComment= 0; - bool eof = false; - while (!eof) + buffer = &line[0]; + uint read = 0; + for(;;) + { + if (read == 512 -1) { - buffer = &line[0]; - uint read = 0; - for(;;) - { - if (read == 512 -1) - { - *buffer = '\0'; - break; - } - - try - { - // read one byte - iFile.serialBuffer ((uint8 *)buffer, 1); - } - catch (const EFile &) - { - *buffer = '\0'; - eof = true; - break; - } - - if (*buffer == '\n') - { - *buffer = '\0'; - break; - } - - // skip '\r' char - if (*buffer != '\r') - { - buffer++; - read++; - } - } - - // execute line - if (strlen(line) > 0) - { - // if not a single comment - if(strncmp(line, "//", 2)!=0) - { - if(strncmp(line, "/*", 2)==0) - inComment++; - if(inComment<=0) - { - ucstring ucline(line); - CInterfaceManager::parseTokens(ucline); - ICommand::execute(ucline.toUtf8(), g_log); - } - if(strncmp(line, "*/", 2)==0) - inComment--; - } - } - - // end? - if (iFile.eof()) - eof = true; + *buffer = '\0'; + break; } - iFile.close(); - } - else - { - CInterfaceManager::getInstance()->displaySystemInfo(ucstring("Cannot open file")); - } - return true; + try + { + // read one byte + iFile.serialBuffer ((uint8 *)buffer, 1); + } + catch (const EFile &) + { + *buffer = '\0'; + eof = true; + break; + } + + if (*buffer == '\n') + { + *buffer = '\0'; + break; + } + + // skip '\r' char + if (*buffer != '\r') + { + buffer++; + read++; + } + } + + // execute line + if (strlen(line) > 0) + { + // if not a single comment + if(strncmp(line, "//", 2)!=0) + { + if(strncmp(line, "/*", 2)==0) + inComment++; + if(inComment<=0) + { + ucstring ucline(line); + CInterfaceManager::parseTokens(ucline); + ICommand::execute(ucline.toUtf8(), g_log); + } + if(strncmp(line, "*/", 2)==0) + inComment--; + } + } + + // end? + if (iFile.eof()) + eof = true; + } + iFile.close(); + } + else + { + CInterfaceManager::getInstance()->displaySystemInfo(ucstring("Cannot open file")); + } + + return true; } NLMISC_COMMAND(db, "Modify Database"," ") { - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - int size = (int)args.size(); - if (size == 2) - { + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + int size = (int)args.size(); + if (size == 2) + { #if !FINAL_VERSION - // check if 2nd arg is a sheet name - if (args[1].empty()) return false; - sint64 value; - if (isalpha(args[1][0])) - { - CSheetId sheet(args[1]); - value = (sint64) sheet.asInt(); - } - else - { - // Convert the string into an sint64. - fromString(args[1], value); - } - - // Set the property. - CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(args[0], false); - if(node) - node->setValue64(value); - else - pIM->displaySystemInfo(toString("DB '%s' does not exist.", args[0].c_str())); -#else - pIM->displaySystemInfo(ucstring("Can't write to DB when in Final Version.")); -#endif - } - else if (size == 1) + // check if 2nd arg is a sheet name + if (args[1].empty()) return false; + sint64 value; + if (isalpha(args[1][0])) { - CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(args[0], false); - if(node) - { - sint64 prop = node->getValue64(); - string str = toString(prop); - pIM->displaySystemInfo(ucstring(str)); - nlinfo("%s", str.c_str()); - } - else - pIM->displaySystemInfo(toString("DB '%s' does not exist.", args[0].c_str())); - return true; + CSheetId sheet(args[1]); + value = (sint64) sheet.asInt(); + } + else + { + // Convert the string into an sint64. + fromString(args[1], value); } - else - return false; - return true; + // Set the property. + CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(args[0], false); + if(node) + node->setValue64(value); + else + pIM->displaySystemInfo(toString("DB '%s' does not exist.", args[0].c_str())); +#else + pIM->displaySystemInfo(ucstring("Can't write to DB when in Final Version.")); +#endif + } + else if (size == 1) + { + CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(args[0], false); + if(node) + { + sint64 prop = node->getValue64(); + string str = toString(prop); + pIM->displaySystemInfo(ucstring(str)); + nlinfo("%s", str.c_str()); + } + else + pIM->displaySystemInfo(toString("DB '%s' does not exist.", args[0].c_str())); + return true; + } + else + return false; + + return true; } static bool talkInChan(uint32 nb,std::vectorargs) { - uint32 maxChans = CChatGroup::MaxDynChanPerPlayer; - if (nb>=maxChans) - { - return false; - } - if(args.size()>0) - { - std::string tmp=""; - std::vector::const_iterator first(args.begin()),last(args.end()); + uint32 maxChans = CChatGroup::MaxDynChanPerPlayer; + if (nb>=maxChans) + { + return false; + } + if(args.size()>0) + { + std::string tmp=""; + std::vector::const_iterator first(args.begin()),last(args.end()); - for(;first!=last;++first) - { - tmp = tmp + (*first); - tmp = tmp+" "; - } - - ucstring uctmp; - uctmp.fromUtf8(tmp); - PeopleInterraction.talkInDynamicChannel(nb, uctmp); - return true; - } - else + for(;first!=last;++first) { - ChatMngr.updateChatModeAndButton(CChatGroup::dyn_chat, nb); + tmp = tmp + (*first); + tmp = tmp+" "; } - return false; + + ucstring uctmp; + uctmp.fromUtf8(tmp); + PeopleInterraction.talkInDynamicChannel(nb, uctmp); + return true; + } + else + { + ChatMngr.updateChatModeAndButton(CChatGroup::dyn_chat, nb); + } + return false; } NLMISC_COMMAND(0,"talk in 0th dynamic chat channel"," ") { - return talkInChan(0,args); + return talkInChan(0,args); } NLMISC_COMMAND(1,"talk in first dynamic chat channel"," ") { - return talkInChan(1,args); + return talkInChan(1,args); } NLMISC_COMMAND(2,"talk in 2nd dynamic chat channel"," ") { - return talkInChan(2,args); + return talkInChan(2,args); } NLMISC_COMMAND(3,"talk in 3rd dynamic chat channel"," ") { - return talkInChan(3,args); + return talkInChan(3,args); } NLMISC_COMMAND(4,"talk in 4th dynamic chat channel"," ") { - return talkInChan(4,args); + return talkInChan(4,args); } NLMISC_COMMAND(5,"talk in 5th dynamic chat channel"," ") { - return talkInChan(5,args); + return talkInChan(5,args); } NLMISC_COMMAND(6,"talk in 6th dynamic chat channel"," ") { - return talkInChan(6,args); + return talkInChan(6,args); } NLMISC_COMMAND(7,"talk in 7th dynamic chat channel"," ") { - return talkInChan(7,args); + return talkInChan(7,args); } NLMISC_COMMAND(setItemName, "set name of items, sbrick, etc.."," ") { - if (args.size() < 2) return false; - CSheetId id(args[0]); - ucstring name; - name.fromUtf8(args[1]); - ucstring desc; - ucstring desc2; - if (args.size() > 2) - desc.fromUtf8(args[2]); - if (args.size() > 2) - desc2.fromUtf8(args[3]); + if (args.size() < 2) return false; + CSheetId id(args[0]); + ucstring name; + name.fromUtf8(args[1]); + ucstring desc; + ucstring desc2; + if (args.size() > 2) + desc.fromUtf8(args[2]); + if (args.size() > 2) + desc2.fromUtf8(args[3]); - STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance(); - if (pSMC) - pSMC->replaceSBrickName(id, name, desc, desc2); - else - return false; - return true; + STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance(); + if (pSMC) + pSMC->replaceSBrickName(id, name, desc, desc2); + else + return false; + return true; } NLMISC_COMMAND(setMissingDynstringText, "set text of missing dynamic string"," ") { - if (args.size() < 2) return false; - ucstring name; - name.fromUtf8(args[0]); - ucstring text; - text.fromUtf8(args[1]); + if (args.size() < 2) return false; + ucstring name; + name.fromUtf8(args[0]); + ucstring text; + text.fromUtf8(args[1]); - STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance(); - if (pSMC) - pSMC->replaceDynString(name, text); - else - return false; - return true; + STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance(); + if (pSMC) + pSMC->replaceDynString(name, text); + else + return false; + return true; } @@ -1323,561 +1323,573 @@ NLMISC_COMMAND(setMissingDynstringText, "set text of missing dynamic string"," < NLMISC_COMMAND(ah, "Launch an action handler", " ") { +<<<<<<< local + if (args.size() == 0) + return false; + + if (!ClientCfg.AllowDebugLua && toLower(args[0]) == "lua") +||||||| base + if (args.size() == 0) + return false; + + if (!ClientCfg.AllowDebugLua && strlwr(args[0]) == "lua") +======= if (args.size() == 0) return false; if (!ClientCfg.AllowDebugLua && toLower(args[0]) == "lua") +>>>>>>> other { return false; // not allowed!! } - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - if (args.size() == 1) - { - CAHManager::getInstance()->runActionHandler(args[0], NULL); - } - else - { - CAHManager::getInstance()->runActionHandler(args[0], NULL, args[1]); - } + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + if (args.size() == 1) + { + CAHManager::getInstance()->runActionHandler(args[0], NULL); + } + else + { + CAHManager::getInstance()->runActionHandler(args[0], NULL, args[1]); + } - return true; + return true; } static void setDynString(uint32 strID, const std::string &value) { - STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance(); - pSMC->receiveString(strID, ucstring(value)); - CBitMemStream bm; - if (bm.isReading()) bm.invert(); - bm.serial(strID); - bm.serial(strID); - bm.invert(); - bm.seek(0, NLMISC::IStream::begin); - pSMC->receiveDynString(bm); + STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance(); + pSMC->receiveString(strID, ucstring(value)); + CBitMemStream bm; + if (bm.isReading()) bm.invert(); + bm.serial(strID); + bm.serial(strID); + bm.invert(); + bm.seek(0, NLMISC::IStream::begin); + pSMC->receiveDynString(bm); } // for debug purposes, insert a string in the NLMISC_COMMAND(setDynString, "set a dynamic string"," ") { - if (args.size() != 2) return false; - uint32 strID; - fromString(args[0], strID); - setDynString(strID, args[1]); - return true; + if (args.size() != 2) return false; + uint32 strID; + fromString(args[0], strID); + setDynString(strID, args[1]); + return true; } class CAnimProgress : public IProgressCallback { public: - // Update the progress bar - virtual void progress (float value) - { - // can't do anything if no driver - if(Driver == NULL) - return; - // Get croped value - value = getCropedValue (value); - // Set matrix - Driver->setMatrixMode2D11(); - // Display a progress bar background - 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, - PROGRESS_BAR_BG_COLOR); - // Display a progress bar - 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, - PROGRESS_BAR_COLOR); - if(TextContext != NULL) - { - // Init the Pen. - TextContext->setKeep800x600Ratio(false); - TextContext->setColor(CRGBA(255,255,255)); - TextContext->setFontSize(20); - TextContext->setHotSpot(UTextContext::MiddleMiddle); + // Update the progress bar + virtual void progress (float value) + { + // can't do anything if no driver + if(Driver == NULL) + return; + // Get croped value + value = getCropedValue (value); + // Set matrix + Driver->setMatrixMode2D11(); + // Display a progress bar background + 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, + PROGRESS_BAR_BG_COLOR); + // Display a progress bar + 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, + PROGRESS_BAR_COLOR); + if(TextContext != NULL) + { + // Init the Pen. + TextContext->setKeep800x600Ratio(false); + TextContext->setColor(CRGBA(255,255,255)); + TextContext->setFontSize(20); + TextContext->setHotSpot(UTextContext::MiddleMiddle); - // Display the Text. - TextContext->printfAt(0.5f, 0.5f, _ProgressMessage.c_str()); - } - // Display to screen. - Driver->swapBuffers(); - } - // New message - void newMessage(const std::string &message) {_ProgressMessage = message;} + // Display the Text. + TextContext->printfAt(0.5f, 0.5f, _ProgressMessage.c_str()); + } + // Display to screen. + Driver->swapBuffers(); + } + // New message + void newMessage(const std::string &message) {_ProgressMessage = message;} private: - std::string _ProgressMessage; + std::string _ProgressMessage; }; NLMISC_COMMAND(reloadSearchPaths, "reload the search paths","") { - if (!args.empty()) return false; - CPath::memoryUncompress(); - CAnimProgress progress; - // remove all objects that may depend on an animation - CProjectileManager::getInstance().reset(); + if (!args.empty()) return false; + CPath::memoryUncompress(); + CAnimProgress progress; + // remove all objects that may depend on an animation + CProjectileManager::getInstance().reset(); - // Pathes - progress.newMessage("Reloading pathes"); - progress.progress(0.0f); - progress.pushCropedValues(0.0f, 1.0f); - // + // Pathes + progress.newMessage("Reloading pathes"); + progress.progress(0.0f); + progress.pushCropedValues(0.0f, 1.0f); + // - addSearchPaths(progress); - CPath::memoryCompress(); - return true; + addSearchPaths(progress); + CPath::memoryCompress(); + return true; } NLMISC_COMMAND(reloadAnim, "reload animations","") { - CPath::memoryUncompress(); - CAnimProgress dummy; - // remove all objects that may depend on an animation - CProjectileManager::getInstance().reset(); + CPath::memoryUncompress(); + CAnimProgress dummy; + // remove all objects that may depend on an animation + CProjectileManager::getInstance().reset(); - // Pathes - dummy.newMessage("Pathes"); - dummy.progress(0.0f); - dummy.pushCropedValues(0.0f, 0.5f); + // Pathes + dummy.newMessage("Pathes"); + dummy.progress(0.0f); + dummy.pushCropedValues(0.0f, 0.5f); - addSearchPaths(dummy); + addSearchPaths(dummy); - if (ClientCfg.UpdatePackedSheet) + if (ClientCfg.UpdatePackedSheet) + { + for(uint i = 0; i < ClientCfg.UpdatePackedSheetPath.size(); i++) { - for(uint i = 0; i < ClientCfg.UpdatePackedSheetPath.size(); i++) - { - dummy.progress((float)i/(float)ClientCfg.UpdatePackedSheetPath.size()); - dummy.pushCropedValues ((float)i/(float)ClientCfg.UpdatePackedSheetPath.size(), (float)(i+1)/(float)ClientCfg.UpdatePackedSheetPath.size()); - CPath::addSearchPath(ClientCfg.UpdatePackedSheetPath[i], true, false, &dummy); - dummy.popCropedValues(); - } + dummy.progress((float)i/(float)ClientCfg.UpdatePackedSheetPath.size()); + dummy.pushCropedValues ((float)i/(float)ClientCfg.UpdatePackedSheetPath.size(), (float)(i+1)/(float)ClientCfg.UpdatePackedSheetPath.size()); + CPath::addSearchPath(ClientCfg.UpdatePackedSheetPath[i], true, false, &dummy); + dummy.popCropedValues(); } + } - dummy.popCropedValues(); - // Animations - dummy.newMessage("Anims"); - dummy.progress(0.5f); - dummy.pushCropedValues(0.5f, 1.0f); - EAM->load(dummy, true); - dummy.popCropedValues(); - // Reload Animations - EntitiesMngr.reloadAnims(); - CPath::memoryCompress(); - return true; + dummy.popCropedValues(); + // Animations + dummy.newMessage("Anims"); + dummy.progress(0.5f); + dummy.pushCropedValues(0.5f, 1.0f); + EAM->load(dummy, true); + dummy.popCropedValues(); + // Reload Animations + EntitiesMngr.reloadAnims(); + CPath::memoryCompress(); + return true; } NLMISC_COMMAND(reloadAttack, "reload attack", "") { - if (!args.empty()) return false; - // remove all objects that may depend on an animation - ClientSheetsStrings.memoryUncompress(); - CProjectileManager::getInstance().reset(); - EntitiesMngr.removeAllAttachedFX(); - FXMngr.reset(); - // - std::vector exts; - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // replace attack list of creature in place (so pointers on character sheets remains valid) - CSheetManager sheetManager; - exts; - // exts.push_back("creature"); - exts.push_back("race_stats"); - NLMISC::IProgressCallback progress; - sheetManager.loadAllSheet(progress, true, false, false, true, &exts); - // - const CSheetManager::TEntitySheetMap &sm = SheetMngr.getSheets(); - for(CSheetManager::TEntitySheetMap::const_iterator it = sm.begin(); it != sm.end(); ++it) + if (!args.empty()) return false; + // remove all objects that may depend on an animation + ClientSheetsStrings.memoryUncompress(); + CProjectileManager::getInstance().reset(); + EntitiesMngr.removeAllAttachedFX(); + FXMngr.reset(); + // + std::vector exts; + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // replace attack list of creature in place (so pointers on character sheets remains valid) + CSheetManager sheetManager; + exts; + // exts.push_back("creature"); + exts.push_back("race_stats"); + NLMISC::IProgressCallback progress; + sheetManager.loadAllSheet(progress, true, false, false, true, &exts); + // + const CSheetManager::TEntitySheetMap &sm = SheetMngr.getSheets(); + for(CSheetManager::TEntitySheetMap::const_iterator it = sm.begin(); it != sm.end(); ++it) + { + if (it->second.EntitySheet && it->second.EntitySheet->Type == CEntitySheet::FAUNA) { - if (it->second.EntitySheet && it->second.EntitySheet->Type == CEntitySheet::FAUNA) - { - // find matching sheet in new sheetManager - const CEntitySheet *other = sheetManager.get(it->first); - if (other) - { - // replace data in place - ((CCharacterSheet &) *it->second.EntitySheet).AttackLists = ((const CCharacterSheet &) *other).AttackLists; - } - } - else if(it->second.EntitySheet && it->second.EntitySheet->Type == CEntitySheet::RACE_STATS) - { - // find matching sheet in new sheetManager - const CEntitySheet *other = sheetManager.get(it->first); - if (other) - { - // replace data in place - ((CRaceStatsSheet &) *it->second.EntitySheet).AttackLists = ((const CRaceStatsSheet &) *other).AttackLists; - } - } + // find matching sheet in new sheetManager + const CEntitySheet *other = sheetManager.get(it->first); + if (other) + { + // replace data in place + ((CCharacterSheet &) *it->second.EntitySheet).AttackLists = ((const CCharacterSheet &) *other).AttackLists; + } } - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - CAttackListManager::getInstance().release(); - // form to reload all sheets of interest - exts.clear(); - exts.push_back("attack_list"); - exts.push_back("animation_fx_set"); - exts.push_back("id_to_string_array"); - CDummyProgress dp; - SheetMngr.loadAllSheet(dp, true, false, true, true, &exts); - CAttackListManager::getInstance().init(); - // - ClientSheetsStrings.memoryCompress(); - return true; + else if(it->second.EntitySheet && it->second.EntitySheet->Type == CEntitySheet::RACE_STATS) + { + // find matching sheet in new sheetManager + const CEntitySheet *other = sheetManager.get(it->first); + if (other) + { + // replace data in place + ((CRaceStatsSheet &) *it->second.EntitySheet).AttackLists = ((const CRaceStatsSheet &) *other).AttackLists; + } + } + } + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + CAttackListManager::getInstance().release(); + // form to reload all sheets of interest + exts.clear(); + exts.push_back("attack_list"); + exts.push_back("animation_fx_set"); + exts.push_back("id_to_string_array"); + CDummyProgress dp; + SheetMngr.loadAllSheet(dp, true, false, true, true, &exts); + CAttackListManager::getInstance().init(); + // + ClientSheetsStrings.memoryCompress(); + return true; } NLMISC_COMMAND(reloadSky, "reload new style sky", "") { - if (!args.empty()) return false; - ContinentMngr.reloadSky(); - return false; + if (!args.empty()) return false; + ContinentMngr.reloadSky(); + return false; } NLMISC_COMMAND(missionReward, "debug"," ") { - if (args.size() == 1) + if (args.size() == 1) + { + uint8 index; + fromString(args[0], index); + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream("BOTCHAT:COMPLETE_MISSION", out)) { - uint8 index; - fromString(args[0], index); - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream("BOTCHAT:COMPLETE_MISSION", out)) - { - out.serial(index); - NetMngr.push(out); - } - else - nlwarning(" : unknown message name : BOTCHAT:COMPLETE_MISSION"); - return true; + out.serial(index); + NetMngr.push(out); } - return false; + else + nlwarning(" : unknown message name : BOTCHAT:COMPLETE_MISSION"); + return true; + } + return false; } NLMISC_COMMAND(missionProgress, "debug"," ") { - if (args.size() == 1) + if (args.size() == 1) + { + uint8 index; + fromString(args[0], index); + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream("BOTCHAT:PROGRESS_MISSION", out)) { - uint8 index; - fromString(args[0], index); - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream("BOTCHAT:PROGRESS_MISSION", out)) - { - out.serial(index); - NetMngr.push(out); - } - else - nlwarning(" : unknown message name : BOTCHAT:PROGRESS_MISSION"); - return true; + out.serial(index); + NetMngr.push(out); } - return false; + else + nlwarning(" : unknown message name : BOTCHAT:PROGRESS_MISSION"); + return true; + } + return false; } /* -NLMISC_COMMAND( displayDBModifs, "display server database modification in the chat window"," ") -{ - if ( VerboseDatabase ) - CInterfaceManager::getInstance()->getChatOutput()->addTextChild(ucstring("the database is already in verbose mode"),CRGBA(255,255,255,255)); - else - { - CInterfaceManager::getInstance()->getChatOutput()->addTextChild(ucstring("database is now in verbose mode"),CRGBA(255,255,255,255)); - VerboseDatabase = true; - } - return true; -} + NLMISC_COMMAND( displayDBModifs, "display server database modification in the chat window"," ") + { + if ( VerboseDatabase ) + CInterfaceManager::getInstance()->getChatOutput()->addTextChild(ucstring("the database is already in verbose mode"),CRGBA(255,255,255,255)); + else + { + CInterfaceManager::getInstance()->getChatOutput()->addTextChild(ucstring("database is now in verbose mode"),CRGBA(255,255,255,255)); + VerboseDatabase = true; + } + return true; + } -NLMISC_COMMAND( hideDBModifs, "stop displaying server database modification in the chat window"," ") -{ - if ( !VerboseDatabase ) - CInterfaceManager::getInstance()->getChatOutput()->addTextChild(ucstring("the database is already not in verbose mode"),CRGBA(255,255,255,255)); - else - { - CInterfaceManager::getInstance()->getChatOutput()->addTextChild(ucstring("database is not in verbose mode anymore"),CRGBA(255,255,255,255)); - VerboseDatabase = false; - } - return true; -} + NLMISC_COMMAND( hideDBModifs, "stop displaying server database modification in the chat window"," ") + { + if ( !VerboseDatabase ) + CInterfaceManager::getInstance()->getChatOutput()->addTextChild(ucstring("the database is already not in verbose mode"),CRGBA(255,255,255,255)); + else + { + CInterfaceManager::getInstance()->getChatOutput()->addTextChild(ucstring("database is not in verbose mode anymore"),CRGBA(255,255,255,255)); + VerboseDatabase = false; + } + return true; + } */ /* -NLMISC_COMMAND(save_sentences, "save sentences"," ") -{ - CSentenceDisplayer::saveSentences(); - return true; -} + NLMISC_COMMAND(save_sentences, "save sentences"," ") + { + CSentenceDisplayer::saveSentences(); + return true; + } */ NLMISC_COMMAND(getSheetId, "get_sheet_id","") { - if (args.size() != 1) - return false; - CSheetId id(args[0]); + if (args.size() != 1) + return false; + CSheetId id(args[0]); - CInterfaceManager::getInstance()->displaySystemInfo(ucstring(toString(id.asInt()))); - return true; + CInterfaceManager::getInstance()->displaySystemInfo(ucstring(toString(id.asInt()))); + return true; } NLMISC_COMMAND(getSheetName, "get_sheet_name","") { - if (args.size() != 1) - return false; - uint32 nId; - fromString(args[0], nId); - CSheetId id( nId ); + if (args.size() != 1) + return false; + uint32 nId; + fromString(args[0], nId); + CSheetId id( nId ); - string name = id.toString(); + string name = id.toString(); - CInterfaceManager::getInstance()->displaySystemInfo(ucstring(name)); - return true; + CInterfaceManager::getInstance()->displaySystemInfo(ucstring(name)); + return true; } NLMISC_COMMAND(forgetAll, "forget all bricks", "") { - // Check parameters. - if(args.size() != 0) - { - return false; - } - char buf[100]; - for (uint i = 0;i<20;i++) - { - sprintf(buf,"SERVER:BRICK_FAMILY:%d:BRICKS",i); - CCDBNodeLeaf * node= NLGUI::CDBManager::getInstance()->getDbProp(buf); - node->setValue64(0); - } - return true; + // Check parameters. + if(args.size() != 0) + { + return false; + } + char buf[100]; + for (uint i = 0;i<20;i++) + { + sprintf(buf,"SERVER:BRICK_FAMILY:%d:BRICKS",i); + CCDBNodeLeaf * node= NLGUI::CDBManager::getInstance()->getDbProp(buf); + node->setValue64(0); + } + return true; } NLMISC_COMMAND(usePreprogMagic, "use the specified magic preprog sentence", "") { - // Check parameters. - if(args.size() != 1) - { - return false; - } + // Check parameters. + if(args.size() != 1) + { + return false; + } - // Create the message for the server to execute a phrase. - const string msgName = "SENTENCE:EXECUTE"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream("SENTENCE:EXECUTE", out)) - { - uint8 phrase; - fromString(args[0], phrase); - out.serial(phrase); + // Create the message for the server to execute a phrase. + const string msgName = "SENTENCE:EXECUTE"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream("SENTENCE:EXECUTE", out)) + { + uint8 phrase; + fromString(args[0], phrase); + out.serial(phrase); - BRICK_TYPE::EBrickType type = BRICK_TYPE::MAGIC; - out.serialEnum( type ); + BRICK_TYPE::EBrickType type = BRICK_TYPE::MAGIC; + out.serialEnum( type ); - NetMngr.push(out); - } - else - nlwarning("mainLoop : unknown message name : '%s'", msgName.c_str()); + NetMngr.push(out); + } + else + nlwarning("mainLoop : unknown message name : '%s'", msgName.c_str()); - return true; + return true; } NLMISC_COMMAND(usePreprogCombat, "use the specified combat preprog sentence", "") { - // Check parameters. - if(args.size() != 1) - { - return false; - } + // Check parameters. + if(args.size() != 1) + { + return false; + } - // Create the message for the server to execute a phrase. - const string msgName = "SENTENCE:EXECUTE"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream("SENTENCE:EXECUTE", out)) - { - uint8 phrase; - fromString(args[0], phrase); - out.serial(phrase); + // Create the message for the server to execute a phrase. + const string msgName = "SENTENCE:EXECUTE"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream("SENTENCE:EXECUTE", out)) + { + uint8 phrase; + fromString(args[0], phrase); + out.serial(phrase); - BRICK_TYPE::EBrickType type = BRICK_TYPE::COMBAT; - out.serialEnum( type ); + BRICK_TYPE::EBrickType type = BRICK_TYPE::COMBAT; + out.serialEnum( type ); - NetMngr.push(out); - } - else - nlwarning("mainLoop : unknown message name : '%s'", msgName.c_str()); + NetMngr.push(out); + } + else + nlwarning("mainLoop : unknown message name : '%s'", msgName.c_str()); - return true; + return true; } NLMISC_COMMAND(engage, "engage target in combat", "") { - // Create the message for the server to execute a phrase. - const string msgName = "COMBAT:ENGAGE"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - NetMngr.push(out); - } - else - nlwarning("mainLoop : unknown message name : '%s'", msgName.c_str()); + // Create the message for the server to execute a phrase. + const string msgName = "COMBAT:ENGAGE"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + NetMngr.push(out); + } + else + nlwarning("mainLoop : unknown message name : '%s'", msgName.c_str()); - return true; + return true; } NLMISC_COMMAND(defaultAttack, "use default attack on target", "") { - // Default attack on the current selection. - UserEntity->attack(); + // Default attack on the current selection. + UserEntity->attack(); - // Well Done. - return true; + // Well Done. + return true; } NLMISC_COMMAND(disengage, "disengage from combat", "") { - // Disengage from combat. - UserEntity->disengage(); + // Disengage from combat. + UserEntity->disengage(); - // Well Done. - return true; + // Well Done. + return true; } NLMISC_COMMAND(leaveTeam, "leave team", "") { - // Create the message for the server to execute a phrase. - const string msgName = "TEAM:LEAVE"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - NetMngr.push(out); - } - else - nlwarning("mainLoop : unknown message name : '%s'", msgName.c_str()); + // Create the message for the server to execute a phrase. + const string msgName = "TEAM:LEAVE"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + NetMngr.push(out); + } + else + nlwarning("mainLoop : unknown message name : '%s'", msgName.c_str()); - return true; + return true; } NLMISC_COMMAND(joinTeam, "join the specified team", "") { - // Create the message for the server to execute a phrase. - const string msgName = "TEAM:JOIN"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - NetMngr.push(out); - } - else - nlwarning("mainLoop : unknown message name : '%s'", msgName.c_str()); + // Create the message for the server to execute a phrase. + const string msgName = "TEAM:JOIN"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + NetMngr.push(out); + } + else + nlwarning("mainLoop : unknown message name : '%s'", msgName.c_str()); - return true; + return true; } NLMISC_COMMAND(joinTeamProposal, "propose to current target to join the team", "") { - // Create the message for the server to execute a phrase. - const string msgName = "TEAM:JOIN_PROPOSAL"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - NetMngr.push(out); - } - else - nlwarning("mainLoop : unknown message name : '%s'", msgName.c_str()); + // Create the message for the server to execute a phrase. + const string msgName = "TEAM:JOIN_PROPOSAL"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + NetMngr.push(out); + } + else + nlwarning("mainLoop : unknown message name : '%s'", msgName.c_str()); - return true; + return true; } NLMISC_COMMAND(joinTeamDecline, "decline a join team proposal", "") { - // Create the message for the server to execute a phrase. - const string msgName = "TEAM:JOIN_PROPOSAL_DECLINE"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - NetMngr.push(out); - } - else - nlwarning("mainLoop : unknown message name : '%s'", msgName.c_str()); + // Create the message for the server to execute a phrase. + const string msgName = "TEAM:JOIN_PROPOSAL_DECLINE"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + NetMngr.push(out); + } + else + nlwarning("mainLoop : unknown message name : '%s'", msgName.c_str()); - return true; + return true; } NLMISC_COMMAND(kickTeammate, "kick someone from your team", "") { - // Create the message for the server to execute a phrase. - const string msgName = "TEAM:KICK"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - NetMngr.push(out); - } - else - nlwarning("mainLoop : unknown message name : '%s'", msgName.c_str()); + // Create the message for the server to execute a phrase. + const string msgName = "TEAM:KICK"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + NetMngr.push(out); + } + else + nlwarning("mainLoop : unknown message name : '%s'", msgName.c_str()); - return true; + return true; } NLMISC_COMMAND(cancelCurrentSentence, "cancel the sentence being executed", "") { - // no parameter needed + // no parameter needed - // Create the message for the server to cancel the phrase being executed - const string msgName = "SENTENCE:CANCEL_CURRENT"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - NetMngr.push(out); - } - else - nlwarning("command : unknown message name : '%s'", msgName.c_str()); + // Create the message for the server to cancel the phrase being executed + const string msgName = "SENTENCE:CANCEL_CURRENT"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + NetMngr.push(out); + } + else + nlwarning("command : unknown message name : '%s'", msgName.c_str()); - return true; + return true; } NLMISC_COMMAND(cancelAllPhrases, "cancel all the phrases being executed", "") { - // no parameter needed + // no parameter needed - UserEntity->cancelAllPhrases(); + UserEntity->cancelAllPhrases(); - return true; + return true; } /* -NLMISC_COMMAND(drop,"drop an item to the ground","") -{ - if( args.size() < 1 ) - { - return false; - } + NLMISC_COMMAND(drop,"drop an item to the ground","") + { + if( args.size() < 1 ) + { + return false; + } - uint32 id; - fromString(args[0], id); - CEntityId itemId(RYZOMID::object,id); + uint32 id; + fromString(args[0], id); + CEntityId itemId(RYZOMID::object,id); - sint32 x = (sint32)UserEntity->pos().x * 1000; - sint32 y = (sint32)UserEntity->pos().y * 1000; - sint32 z = (sint32)UserEntity->pos().z * 1000; + sint32 x = (sint32)UserEntity->pos().x * 1000; + sint32 y = (sint32)UserEntity->pos().y * 1000; + sint32 z = (sint32)UserEntity->pos().z * 1000; - CBitMemStream bms; - string msgType = "ITEM:DROP"; - if( GenericMsgHeaderMngr.pushNameToStream(msgType,bms) ) - { - bms.serial( itemId ); - bms.serial( x ); - bms.serial( y ); - bms.serial( z ); - NetMngr.push( bms ); - nldebug(" sending 'ITEM:DROP' message to server"); - } - else - { - nlwarning(" unknown message name : ITEM:DROP"); - }* + CBitMemStream bms; + string msgType = "ITEM:DROP"; + if( GenericMsgHeaderMngr.pushNameToStream(msgType,bms) ) + { + bms.serial( itemId ); + bms.serial( x ); + bms.serial( y ); + bms.serial( z ); + NetMngr.push( bms ); + nldebug(" sending 'ITEM:DROP' message to server"); + } + else + { + nlwarning(" unknown message name : ITEM:DROP"); + }* - return true; -} + return true; + } */ NLMISC_COMMAND(pos, "Change the position of the user (in local only)", " OR 1 name of 'tp.teleport_list'. or a bot name") { - CVectorD newPos; + CVectorD newPos; // Named destination. if(args.size() == 1) @@ -1900,1853 +1912,1854 @@ NLMISC_COMMAND(pos, "Change the position of the user (in local only)", " cause crash - */ + /* + CANNOT USE ProgressBar here, because it does pumpEvents(), and + ICommand::execute() is typically called from a pumpEvents() too... + => cause crash + */ - // Fade out the Game Sound - if(SoundMngr) - SoundMngr->fadeOutGameSound(ClientCfg.SoundTPFade); + // Fade out the Game Sound + if(SoundMngr) + SoundMngr->fadeOutGameSound(ClientCfg.SoundTPFade); - // Remove the selection. - UserEntity->selection(CLFECOMMON::INVALID_SLOT); - // Remove the target. - UserEntity->targetSlot(CLFECOMMON::INVALID_SLOT); - // Change the position of the entity and in Pacs. - UserEntity->pos(newPos); - // Select the closest continent from the new position. - CDummyProgress progress; - ContinentMngr.select(newPos, progress); - // Teleport the User. - UserEntity->tp(newPos); + // Remove the selection. + UserEntity->selection(CLFECOMMON::INVALID_SLOT); + // Remove the target. + UserEntity->targetSlot(CLFECOMMON::INVALID_SLOT); + // Change the position of the entity and in Pacs. + UserEntity->pos(newPos); + // Select the closest continent from the new position. + CDummyProgress progress; + ContinentMngr.select(newPos, progress); + // Teleport the User. + UserEntity->tp(newPos); - // First frame (for sound fade in) - extern bool FirstFrame; - FirstFrame = true; + // First frame (for sound fade in) + extern bool FirstFrame; + FirstFrame = true; - return true; + return true; } NLMISC_COMMAND(removeEntity, "Remove an entity", "") { - if (args.size() != 1) return false; - uint slot; - fromString(args[0], slot); - EntitiesMngr.remove(slot, true); - return true; + if (args.size() != 1) return false; + uint slot; + fromString(args[0], slot); + EntitiesMngr.remove(slot, true); + return true; } NLMISC_COMMAND(entity, "Create an entity on the user or just remove it if Form not valid", "
[posx posy posz] [relativeToPlayer]") { - CInterfaceManager *IM = CInterfaceManager::getInstance (); + CInterfaceManager *IM = CInterfaceManager::getInstance (); - // Check parameters. - if(args.size() != 2 && args.size() != 5 && args.size() != 6) - return false; + // Check parameters. + if(args.size() != 2 && args.size() != 5 && args.size() != 6) + return false; - // read pos. - CVector entityPos; - if(args.size()>=5) + // read pos. + CVector entityPos; + if(args.size()>=5) + { + fromString(args[2], entityPos.x); + fromString(args[3], entityPos.y); + fromString(args[4], entityPos.z); + // if want pos local to UserEntity + if(args.size()==6) { - fromString(args[2], entityPos.x); - fromString(args[3], entityPos.y); - fromString(args[4], entityPos.z); - // if want pos local to UserEntity - if(args.size()==6) - { - sint32 tmp; - fromString(args[5], tmp); - if (tmp != 0) - { - CMatrix mat; - mat.setRot(CVector::I, UserEntity->front(), CVector::K); - mat.normalize(CMatrix::YZX); - mat.setPos(UserEntity->pos()); - entityPos= mat * entityPos; - } - } + sint32 tmp; + fromString(args[5], tmp); + if (tmp != 0) + { + CMatrix mat; + mat.setRot(CVector::I, UserEntity->front(), CVector::K); + mat.normalize(CMatrix::YZX); + mat.setPos(UserEntity->pos()); + entityPos= mat * entityPos; + } } - else + } + else + { + entityPos= UserEntity->pos()+UserEntity->front()*2.0; + } + + // Try to create the sheet with the parameter as a string. + CSheetId sheetId; + if(!sheetId.buildSheetId(args[1])) + { + // Try to create the sheet with the parameter as an int. + uint32 nSheetId; + fromString(args[1], nSheetId); + sheetId = CSheetId(nSheetId); + if(sheetId == CSheetId::Unknown) { - entityPos= UserEntity->pos()+UserEntity->front()*2.0; + nlwarning("Command 'entity': '%s' is not a valid form", args[1].c_str()); + return false; } + } - // Try to create the sheet with the parameter as a string. - CSheetId sheetId; - if(!sheetId.buildSheetId(args[1])) + // The slot where the new entity will be. + CLFECOMMON::TCLEntityId slot; + fromString(args[0], slot); + + // Debug Infos + nldebug("Command 'entity' : AddNewEntity with form %s in the slot %d", args[1].c_str(), slot); + // Remove the old entity. + EntitiesMngr.remove(slot, false); + // Create the new entity. + + TNewEntityInfo emptyEntityInfo; + emptyEntityInfo.reset(); + CEntityCL *entity = EntitiesMngr.create(slot, sheetId.asInt(), emptyEntityInfo); + if(entity) + { + sint64 *prop = 0; + CCDBNodeLeaf *node = 0; + // Set The property 'CLFECOMMON::PROPERTY_POSITION'. + node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_POSX), false); + if(node) { - // Try to create the sheet with the parameter as an int. - uint32 nSheetId; - fromString(args[1], nSheetId); - sheetId = CSheetId(nSheetId); - if(sheetId == CSheetId::Unknown) - { - nlwarning("Command 'entity': '%s' is not a valid form", args[1].c_str()); - return false; - } + sint64 x = (sint64)(entityPos.x*1000.0); + sint64 y = (sint64)(entityPos.y*1000.0); + sint64 z = (sint64)(entityPos.z*1000.0); + node->setValue64(x); + node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_POSY), false); + if(node) + { + node->setValue64(y); + node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_POSZ), false); + if(node) + node->setValue64(z); + } } - - // The slot where the new entity will be. - CLFECOMMON::TCLEntityId slot; - fromString(args[0], slot); - - // Debug Infos - nldebug("Command 'entity' : AddNewEntity with form %s in the slot %d", args[1].c_str(), slot); - // Remove the old entity. - EntitiesMngr.remove(slot, false); - // Create the new entity. - - TNewEntityInfo emptyEntityInfo; - emptyEntityInfo.reset(); - CEntityCL *entity = EntitiesMngr.create(slot, sheetId.asInt(), emptyEntityInfo); - if(entity) + // Set The property 'PROPERTY_ORIENTATION'. + node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_ORIENTATION), false); + if(node) { - sint64 *prop = 0; - CCDBNodeLeaf *node = 0; - // Set The property 'CLFECOMMON::PROPERTY_POSITION'. - node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_POSX), false); - if(node) - { - sint64 x = (sint64)(entityPos.x*1000.0); - sint64 y = (sint64)(entityPos.y*1000.0); - sint64 z = (sint64)(entityPos.z*1000.0); - node->setValue64(x); - node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_POSY), false); - if(node) - { - node->setValue64(y); - node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_POSZ), false); - if(node) - node->setValue64(z); - } - } - // Set The property 'PROPERTY_ORIENTATION'. - node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_ORIENTATION), false); - if(node) - { - float dir = (float)atan2(UserEntity->front().y, UserEntity->front().x); - prop = (sint64 *)(&dir); - node->setValue64(*prop); - } - // Set Mode - node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_MODE), false); - if(node) - { - MBEHAV::EMode m = MBEHAV::NORMAL; - prop = (sint64 *)&m; - node->setValue64(*prop); - EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_MODE); - } - // Set Visual Properties - if(dynamic_cast(entity)) - { - SPropVisualA visualA; - visualA.PropertySubData.Sex = ClientCfg.Sex; - SPropVisualB visualB; - // Initialize the Visual Property C (Default parameters). - SPropVisualC visualC; - visualC.PropertySubData.CharacterHeight = 7; - visualC.PropertySubData.ArmsWidth = 7; - visualC.PropertySubData.LegsWidth = 7; - visualC.PropertySubData.TorsoWidth = 7; - visualC.PropertySubData.BreastSize = 7; - // Set The Database - prop = (sint64 *)&visualB; - NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_VPB))->setValue64(*prop); - prop = (sint64 *)&visualC; - NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_VPC))->setValue64(*prop); - prop = (sint64 *)&visualA; - NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_VPA))->setValue64(*prop); - // Apply Changes. - EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_VPA); - } - // Forage Source special - if(dynamic_cast(entity)) - { - sint64 barVal; - barVal= 32; barVal<<= 7; - barVal+= 32; barVal<<= 7; - barVal+= 10; barVal<<= 7; - barVal+= 127; - NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_BARS))->setValue64(barVal); - EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_BARS); - // must also update position, else don't work - EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_POSITION); - } - else - if (dynamic_cast(entity)) // FX cl special - { - // must also update position, else don't work - EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_POSITION); - } - // - nlinfo("entity: slot: %d \"%s\", \"%f\", \"%f\", \"%f\" ", - slot,args[1].c_str(), - entityPos.x, entityPos.y, entityPos.z); + float dir = (float)atan2(UserEntity->front().y, UserEntity->front().x); + prop = (sint64 *)(&dir); + node->setValue64(*prop); } - else - nldebug("command 'entity' : entity in slot %d removed", slot); + // Set Mode + node = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_MODE), false); + if(node) + { + MBEHAV::EMode m = MBEHAV::NORMAL; + prop = (sint64 *)&m; + node->setValue64(*prop); + EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_MODE); + } + // Set Visual Properties + if(dynamic_cast(entity)) + { + SPropVisualA visualA; + visualA.PropertySubData.Sex = ClientCfg.Sex; + SPropVisualB visualB; + // Initialize the Visual Property C (Default parameters). + SPropVisualC visualC; + visualC.PropertySubData.CharacterHeight = 7; + visualC.PropertySubData.ArmsWidth = 7; + visualC.PropertySubData.LegsWidth = 7; + visualC.PropertySubData.TorsoWidth = 7; + visualC.PropertySubData.BreastSize = 7; + // Set The Database + prop = (sint64 *)&visualB; + NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_VPB))->setValue64(*prop); + prop = (sint64 *)&visualC; + NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_VPC))->setValue64(*prop); + prop = (sint64 *)&visualA; + NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_VPA))->setValue64(*prop); + // Apply Changes. + EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_VPA); + } + // Forage Source special + if(dynamic_cast(entity)) + { + sint64 barVal; + barVal= 32; barVal<<= 7; + barVal+= 32; barVal<<= 7; + barVal+= 10; barVal<<= 7; + barVal+= 127; + NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", slot)+":P"+toString("%d", CLFECOMMON::PROPERTY_BARS))->setValue64(barVal); + EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_BARS); + // must also update position, else don't work + EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_POSITION); + } + else + if (dynamic_cast(entity)) // FX cl special + { + // must also update position, else don't work + EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_POSITION); + } + // + nlinfo("entity: slot: %d \"%s\", \"%f\", \"%f\", \"%f\" ", + slot,args[1].c_str(), + entityPos.x, entityPos.y, entityPos.z); + } + else + nldebug("command 'entity' : entity in slot %d removed", slot); - // Command well done. - return true; + // Command well done. + return true; } NLMISC_COMMAND(primPoint, "add a primitive point", "") { - if(args.size() != 2) - return false; + if(args.size() != 2) + return false; - if(LDPrim == 0) + if(LDPrim == 0) + { + LDPrim = new NLLIGO::CPrimitives; + if(LDPrim == 0) { - LDPrim = new NLLIGO::CPrimitives; - if(LDPrim == 0) - { - nlwarning("primPoint: LDPrim == 0"); - return false; - } + nlwarning("primPoint: LDPrim == 0"); + return false; } + } - if(LDPrim->RootNode == 0) + if(LDPrim->RootNode == 0) + { + nlwarning("primPoint: LDPrim.RootNode == 0"); + return true; + } + + NLLIGO::CPropertyString *str = 0; + NLLIGO::CPrimPoint *point = 0; + + point = new NLLIGO::CPrimPoint; + if(point == 0) + { + nlwarning("primPoint: point == 0"); + return true; + } + point->Point.x = (float)UserEntity->pos().x; + point->Point.y = (float)UserEntity->pos().y; + point->Point.z = (float)UserEntity->pos().z; + + str = new NLLIGO::CPropertyString; + if(str == 0) + { + nlwarning("primPoint: str == 0 (1)"); + return true; + } + point->addPropertyByName("class", str); + str->String = "reference_point"; + + str = new NLLIGO::CPropertyString; + if(str == 0) + { + nlwarning("primPoint: str == 0 (2)"); + return true; + } + point->addPropertyByName("name", str); + str->String = args[1]; + + // Add the point to the primitive. + LDPrim->RootNode->insertChild(point); + + // Open the file. + NLMISC::COFile file; + if(file.open(args[0])) + { + // Create the XML stream + NLMISC::COXml output; + // Init + if(output.init(&file, "1.0")) { - nlwarning("primPoint: LDPrim.RootNode == 0"); - return true; + LDPrim->write(output.getDocument(), args[0].c_str()); + // Flush the stream, write all the output file + output.flush(); } + else + nlwarning("primPoint: "); + // Close the File. + file.close(); + } + else + nlwarning("primPoint: cannot open/create the file '%s'", args[0].c_str()); - NLLIGO::CPropertyString *str = 0; - NLLIGO::CPrimPoint *point = 0; - - point = new NLLIGO::CPrimPoint; - if(point == 0) - { - nlwarning("primPoint: point == 0"); - return true; - } - point->Point.x = (float)UserEntity->pos().x; - point->Point.y = (float)UserEntity->pos().y; - point->Point.z = (float)UserEntity->pos().z; - - str = new NLLIGO::CPropertyString; - if(str == 0) - { - nlwarning("primPoint: str == 0 (1)"); - return true; - } - point->addPropertyByName("class", str); - str->String = "reference_point"; - - str = new NLLIGO::CPropertyString; - if(str == 0) - { - nlwarning("primPoint: str == 0 (2)"); - return true; - } - point->addPropertyByName("name", str); - str->String = args[1]; - - // Add the point to the primitive. - LDPrim->RootNode->insertChild(point); - - // Open the file. - NLMISC::COFile file; - if(file.open(args[0])) - { - // Create the XML stream - NLMISC::COXml output; - // Init - if(output.init(&file, "1.0")) - { - LDPrim->write(output.getDocument(), args[0].c_str()); - // Flush the stream, write all the output file - output.flush(); - } - else - nlwarning("primPoint: "); - // Close the File. - file.close(); - } - else - nlwarning("primPoint: cannot open/create the file '%s'", args[0].c_str()); - - return true; + return true; } #ifdef ENABLE_INCOMING_MSG_RECORDER NLMISC_COMMAND(record, "Start Recording", "") { - CInterfaceManager *IM = CInterfaceManager::getInstance (); + CInterfaceManager *IM = CInterfaceManager::getInstance (); - // Check parameters. - if(args.size() != 1) - return false; + // Check parameters. + if(args.size() != 1) + return false; - // Warning when already recording. - if(NetMngr.isRecording()) - { - IM->displaySystemInfo(ucstring("Already Recording. Stop the current Record first")); - return true; - } + // Warning when already recording. + if(NetMngr.isRecording()) + { + IM->displaySystemInfo(ucstring("Already Recording. Stop the current Record first")); + return true; + } - // Save entities and DB. - dump(args[0]); + // Save entities and DB. + dump(args[0]); - // On/Off record. - if(!ClientCfg.Local) - NetMngr.setRecordingMode(true, args[0]+"_net.rec"); - return true; + // On/Off record. + if(!ClientCfg.Local) + NetMngr.setRecordingMode(true, args[0]+"_net.rec"); + return true; } NLMISC_COMMAND(replay, "replay", "") { - // Check parameters. - if(args.size() != 1) - return false; + // Check parameters. + if(args.size() != 1) + return false; - // Load entities and DB. - loadDump(args[0]); + // Load entities and DB. + loadDump(args[0]); - // On/Off record. - if(ClientCfg.Local) - NetMngr.setReplayingMode(!NetMngr.isReplaying(), args[0]+"_net.rec"); - return true; + // On/Off record. + if(ClientCfg.Local) + NetMngr.setReplayingMode(!NetMngr.isReplaying(), args[0]+"_net.rec"); + return true; } NLMISC_COMMAND(stopRecord, "Stop Recording", "") { - // Check parameters. - if(args.size() != 0) - return false; + // Check parameters. + if(args.size() != 0) + return false; - // On/Off record. - if(!ClientCfg.Local) - NetMngr.setRecordingMode(false); - return true; + // On/Off record. + if(!ClientCfg.Local) + NetMngr.setRecordingMode(false); + return true; } #endif // ENABLE_INCOMING_MSG_RECORDER NLMISC_COMMAND(loadDump, "Command to load a dump file", "[]") { - if(args.size() > 1) - return false; + if(args.size() > 1) + return false; - string dumpName; - if(args.size() == 1) - dumpName = args[0]; - else - dumpName = "default"; + string dumpName; + if(args.size() == 1) + dumpName = args[0]; + else + dumpName = "default"; - loadDump(dumpName); - return true; + loadDump(dumpName); + return true; } NLMISC_COMMAND(sheet2idx, "Return the index of a sheet", " ") { - CInterfaceManager *IM = CInterfaceManager::getInstance (); + CInterfaceManager *IM = CInterfaceManager::getInstance (); - if(args.size() != 2) - return false; + if(args.size() != 2) + return false; - string result; - NLMISC::CSheetId sheetId; + string result; + NLMISC::CSheetId sheetId; - if(sheetId.buildSheetId(args[0])) - { - uint slot; - fromString(args[1], slot); - uint32 idx = CVisualSlotManager::getInstance()->sheet2Index(sheetId, (SLOTTYPE::EVisualSlot)slot); - result = NLMISC::toString("Index = %d", idx); - } - else - result = NLMISC::toString("sheet '%s' not valid", args[0].c_str()); + if(sheetId.buildSheetId(args[0])) + { + uint slot; + fromString(args[1], slot); + uint32 idx = CVisualSlotManager::getInstance()->sheet2Index(sheetId, (SLOTTYPE::EVisualSlot)slot); + result = NLMISC::toString("Index = %d", idx); + } + else + result = NLMISC::toString("sheet '%s' not valid", args[0].c_str()); - IM->displaySystemInfo(ucstring(result)); - nlinfo("'sheet2idx': %s", result.c_str()); - return true; + IM->displaySystemInfo(ucstring(result)); + nlinfo("'sheet2idx': %s", result.c_str()); + return true; } NLMISC_COMMAND(watchEntity, "Choose the entity to watch", "") { - if(args.size() != 1) - return false; + if(args.size() != 1) + return false; - // Set the new debug entity slot. - fromString(args[0], WatchedEntitySlot); - return true; + // Set the new debug entity slot. + fromString(args[0], WatchedEntitySlot); + return true; } NLMISC_COMMAND(dynstr, "display a dyn string value", "") { - if (args.size() != 1) - return false; + if (args.size() != 1) + return false; - uint dynId; - fromString(args[0], dynId); + uint dynId; + fromString(args[0], dynId); - ucstring result; - STRING_MANAGER::CStringManagerClient::instance()->getDynString(dynId, result); + ucstring result; + STRING_MANAGER::CStringManagerClient::instance()->getDynString(dynId, result); - CInterfaceManager::getInstance()->displaySystemInfo(result); - return true; + CInterfaceManager::getInstance()->displaySystemInfo(result); + return true; } NLMISC_COMMAND(serverstr, "display a server string value", "") { - if (args.size() != 1) - return false; + if (args.size() != 1) + return false; - uint dynId; - fromString(args[0], dynId); + uint dynId; + fromString(args[0], dynId); - ucstring result; - STRING_MANAGER::CStringManagerClient::instance()->getString(dynId, result); + ucstring result; + STRING_MANAGER::CStringManagerClient::instance()->getString(dynId, result); - CInterfaceManager::getInstance()->displaySystemInfo(result); - return true; + CInterfaceManager::getInstance()->displaySystemInfo(result); + return true; } NLMISC_COMMAND(cmd, "Send a command to a server"," ") { - // Check parameters. - if(args.size() < 2) - return false; + // Check parameters. + if(args.size() < 2) + return false; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream("DEBUG:CMD", out)) + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream("DEBUG:CMD", out)) + { + bool addentity = false; + string dest = args[0]; + string cmd = args[1]; + string arg; + for (uint i = 2; i < args.size(); i++) { - bool addentity = false; - string dest = args[0]; - string cmd = args[1]; - string arg; - for (uint i = 2; i < args.size(); i++) - { - arg += args[i] + " "; - } - out.serial(addentity); - out.serial(dest); - out.serial(cmd); - out.serial(arg); - NetMngr.push(out); + arg += args[i] + " "; } - else - nlwarning("mainLoop : unknown message name DEBUG:CMD"); - return true; + out.serial(addentity); + out.serial(dest); + out.serial(cmd); + out.serial(arg); + NetMngr.push(out); + } + else + nlwarning("mainLoop : unknown message name DEBUG:CMD"); + return true; } NLMISC_COMMAND(cmde, "Send a command to a server with entityid"," ") { - // Check parameters. - if(args.size() < 2) - return false; + // Check parameters. + if(args.size() < 2) + return false; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream("DEBUG:CMD", out)) + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream("DEBUG:CMD", out)) + { + bool addentity = true; + string dest = args[0]; + string cmd = args[1]; + string arg; + for (uint i = 2; i < args.size(); i++) { - bool addentity = true; - string dest = args[0]; - string cmd = args[1]; - string arg; - for (uint i = 2; i < args.size(); i++) - { - arg += args[i] + " "; - } - out.serial(addentity); - out.serial(dest); - out.serial(cmd); - out.serial(arg); - NetMngr.push(out); + arg += args[i] + " "; } - else - nlwarning("mainLoop : unknown message name DEBUG:CMD"); - return true; + out.serial(addentity); + out.serial(dest); + out.serial(cmd); + out.serial(arg); + NetMngr.push(out); + } + else + nlwarning("mainLoop : unknown message name DEBUG:CMD"); + return true; } NLMISC_COMMAND(askservices, "Ask the server all services up", "") { - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream("DEBUG:SERVICES", out)) - { - // Add the message to the send list. - NetMngr.push(out); - nlinfo("command 'services': 'DEBUG:SERVICES' sent"); - } - else - nlwarning("command 'services': unknown message named 'DEBUG:SERVICES'"); + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream("DEBUG:SERVICES", out)) + { + // Add the message to the send list. + NetMngr.push(out); + nlinfo("command 'services': 'DEBUG:SERVICES' sent"); + } + else + nlwarning("command 'services': unknown message named 'DEBUG:SERVICES'"); - return true; + return true; } NLMISC_COMMAND(mode, "Change the mode for an entity in a slot", " [dt(tick)]") { - // Check parameters. - if(args.size() < 2) + // Check parameters. + if(args.size() < 2) + { + // Help + CInterfaceManager::getInstance()->displaySystemInfo(ucstring("This command need 2 paramters :")); + CInterfaceManager::getInstance()->displaySystemInfo(ucstring(" : the slot number of the entity to change")); + CInterfaceManager::getInstance()->displaySystemInfo(ucstring(" : the mode wanted for the entity, one of the following number :")); + for(uint i = 0; idisplaySystemInfo(ucstring(NLMISC::toString(" %d - %s", i, MBEHAV::modeToString((MBEHAV::EMode)i).c_str()))); + } + // Right parameters number + else + { + // Compute parameters + CLFECOMMON::TCLEntityId slot; + fromString(args[0], slot); + MBEHAV::EMode mod = MBEHAV::stringToMode(args[1]); + if(mod==MBEHAV::UNKNOWN_MODE) { - // Help - CInterfaceManager::getInstance()->displaySystemInfo(ucstring("This command need 2 paramters :")); - CInterfaceManager::getInstance()->displaySystemInfo(ucstring(" : the slot number of the entity to change")); - CInterfaceManager::getInstance()->displaySystemInfo(ucstring(" : the mode wanted for the entity, one of the following number :")); - for(uint i = 0; idisplaySystemInfo(ucstring(NLMISC::toString(" %d - %s", i, MBEHAV::modeToString((MBEHAV::EMode)i).c_str()))); - } - // Right parameters number - else - { - // Compute parameters - CLFECOMMON::TCLEntityId slot; - fromString(args[0], slot); - MBEHAV::EMode mod = MBEHAV::stringToMode(args[1]); - if(mod==MBEHAV::UNKNOWN_MODE) - { - sint32 nMode; - fromString(args[1], nMode); - mod = (MBEHAV::EMode)nMode; - } - - // Compute the position. - CEntityCL *entity = EntitiesMngr.entity(slot); - if(entity) - { - // Write the behaviour in the DB. - IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_MODE), mod); - // Update the behaviour. - sint32 dt= 10; - if(args.size() > 2) - fromString(args[2], dt); - entity->updateVisualProperty(NetMngr.getCurrentServerTick()+dt, CLFECOMMON::PROPERTY_MODE); - } - // Invalid slot. - else - CInterfaceManager::getInstance()->displaySystemInfo(ucstring("There is no entity in the given slot")); + sint32 nMode; + fromString(args[1], nMode); + mod = (MBEHAV::EMode)nMode; } - // Command well done. - return true; + // Compute the position. + CEntityCL *entity = EntitiesMngr.entity(slot); + if(entity) + { + // Write the behaviour in the DB. + IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_MODE), mod); + // Update the behaviour. + sint32 dt= 10; + if(args.size() > 2) + fromString(args[2], dt); + entity->updateVisualProperty(NetMngr.getCurrentServerTick()+dt, CLFECOMMON::PROPERTY_MODE); + } + // Invalid slot. + else + CInterfaceManager::getInstance()->displaySystemInfo(ucstring("There is no entity in the given slot")); + } + + // Command well done. + return true; } NLMISC_COMMAND(behaviour, "Change the behaviour for an entity in a slot", " [] [] [] [dt(tick)]") { - // Check parameters. - if(args.size() < 2 || args.size() > 6) + // Check parameters. + if(args.size() < 2 || args.size() > 6) + { + // Help + CInterfaceManager::getInstance()->displaySystemInfo(ucstring("This command need 2 to 6 paramters :")); + CInterfaceManager::getInstance()->displaySystemInfo(ucstring(" : the slot number of the entity to change")); + CInterfaceManager::getInstance()->displaySystemInfo(ucstring(" : the behaviour to play for the entity, one of the following number :")); + for(uint i = 0; idisplaySystemInfo(ucstring(NLMISC::toString(" %d - %s", i, MBEHAV::behaviourToString((MBEHAV::EBehaviour)i).c_str()))); + CInterfaceManager::getInstance()->displaySystemInfo(ucstring(NLMISC::toString(" %d-%d - Emotes", MBEHAV::EMOTE_BEGIN, MBEHAV::EMOTE_END))); + } + else + { + // Compute parameters + CLFECOMMON::TCLEntityId slot; + fromString(args[0], slot); + MBEHAV::EBehaviour beh = MBEHAV::stringToBehaviour(args[1]); + if(beh==MBEHAV::UNKNOWN_BEHAVIOUR) { - // Help - CInterfaceManager::getInstance()->displaySystemInfo(ucstring("This command need 2 to 6 paramters :")); - CInterfaceManager::getInstance()->displaySystemInfo(ucstring(" : the slot number of the entity to change")); - CInterfaceManager::getInstance()->displaySystemInfo(ucstring(" : the behaviour to play for the entity, one of the following number :")); - for(uint i = 0; idisplaySystemInfo(ucstring(NLMISC::toString(" %d - %s", i, MBEHAV::behaviourToString((MBEHAV::EBehaviour)i).c_str()))); - CInterfaceManager::getInstance()->displaySystemInfo(ucstring(NLMISC::toString(" %d-%d - Emotes", MBEHAV::EMOTE_BEGIN, MBEHAV::EMOTE_END))); - } - else - { - // Compute parameters - CLFECOMMON::TCLEntityId slot; - fromString(args[0], slot); - MBEHAV::EBehaviour beh = MBEHAV::stringToBehaviour(args[1]); - if(beh==MBEHAV::UNKNOWN_BEHAVIOUR) - { - sint32 temp; - fromString(args[1], temp); - beh= (MBEHAV::EBehaviour)temp; - } - - // Make the behaviour - MBEHAV::CBehaviour behaviour(beh); - // Get the Power - if ( (beh == MBEHAV::PROSPECTING) || (beh == MBEHAV::PROSPECTING_END) ) - { - if(args.size() > 2) - { - uint16 range; - fromString(args[2], range); - behaviour.ForageProspection.Range = range; // 0..127 - } - if(args.size() > 3) - { - uint16 angle; - fromString(args[3], angle); - behaviour.ForageProspection.Angle = angle; // 0..3 - } - if(args.size() > 4) - { - uint16 level; - fromString(args[4], level); - behaviour.ForageProspection.Level = level; // 0..4 - } - } - else - { - if(args.size() > 2) - { - uint16 impactIntensity; - fromString(args[2], impactIntensity); - behaviour.Combat.ImpactIntensity = impactIntensity; - } - if(args.size() > 3) - { - uint16 impactIntensity; - fromString(args[3], impactIntensity); - behaviour.Combat.ImpactIntensity = impactIntensity; - } - if(args.size() > 4) - fromString(args[4], behaviour.DeltaHP); - } - // get the dt - sint32 dt= 10; - if(args.size() > 5) - fromString(args[5], dt); - - // Compute the position. - CEntityCL *entity = EntitiesMngr.entity(slot); - if(entity) - { - // Write the behaviour in the DB. - IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_BEHAVIOUR), behaviour); - // Update the behaviour. - entity->updateVisualProperty(NetMngr.getCurrentServerTick()+dt, CLFECOMMON::PROPERTY_BEHAVIOUR); - } - else - CInterfaceManager::getInstance()->displaySystemInfo(ucstring("There is no entity in the given slot")); + sint32 temp; + fromString(args[1], temp); + beh= (MBEHAV::EBehaviour)temp; } - // Command well done. - return true; + // Make the behaviour + MBEHAV::CBehaviour behaviour(beh); + // Get the Power + if ( (beh == MBEHAV::PROSPECTING) || (beh == MBEHAV::PROSPECTING_END) ) + { + if(args.size() > 2) + { + uint16 range; + fromString(args[2], range); + behaviour.ForageProspection.Range = range; // 0..127 + } + if(args.size() > 3) + { + uint16 angle; + fromString(args[3], angle); + behaviour.ForageProspection.Angle = angle; // 0..3 + } + if(args.size() > 4) + { + uint16 level; + fromString(args[4], level); + behaviour.ForageProspection.Level = level; // 0..4 + } + } + else + { + if(args.size() > 2) + { + uint16 impactIntensity; + fromString(args[2], impactIntensity); + behaviour.Combat.ImpactIntensity = impactIntensity; + } + if(args.size() > 3) + { + uint16 impactIntensity; + fromString(args[3], impactIntensity); + behaviour.Combat.ImpactIntensity = impactIntensity; + } + if(args.size() > 4) + fromString(args[4], behaviour.DeltaHP); + } + // get the dt + sint32 dt= 10; + if(args.size() > 5) + fromString(args[5], dt); + + // Compute the position. + CEntityCL *entity = EntitiesMngr.entity(slot); + if(entity) + { + // Write the behaviour in the DB. + IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_BEHAVIOUR), behaviour); + // Update the behaviour. + entity->updateVisualProperty(NetMngr.getCurrentServerTick()+dt, CLFECOMMON::PROPERTY_BEHAVIOUR); + } + else + CInterfaceManager::getInstance()->displaySystemInfo(ucstring("There is no entity in the given slot")); + } + + // Command well done. + return true; } /* -NLMISC_COMMAND(magic, "Cast a spell", "\n" -" : the one who cast the spell\n" -" : 0->GOOD 1->Bad 2->NEUTRAL\n" -" : 0->success 1->Fail 2->Fumble\n" -" : \n" -" : \n" -" : 0->not resisted, any other->resisted.\n") -{ - CInterfaceManager *IM = CInterfaceManager::getInstance (); + NLMISC_COMMAND(magic, "Cast a spell", "\n" + " : the one who cast the spell\n" + " : 0->GOOD 1->Bad 2->NEUTRAL\n" + " : 0->success 1->Fail 2->Fumble\n" + " : \n" + " : \n" + " : 0->not resisted, any other->resisted.\n") + { + CInterfaceManager *IM = CInterfaceManager::getInstance (); - // Check parameters. - if(args.size() != 6) - { - // Help -// CInterfaceManager::getInstance()->displaySystemInfo(ucstring("This command need 2 or 3 paramters :")); -// CInterfaceManager::getInstance()->displaySystemInfo(ucstring(" : the slot number of the entity to change")); -// CInterfaceManager::getInstance()->displaySystemInfo(ucstring(" : the behaviour to play for the entity, one of the following number :")); -// for(uint i = 0; idisplaySystemInfo(ucstring(NLMISC::toString(" %d - %s", i, MBEHAV::behaviourToString((MBEHAV::EBehaviour)i)))); -// CInterfaceManager::getInstance()->displaySystemInfo(ucstring(NLMISC::toString(" %d-%d - Emotes", MBEHAV::EMOTE_BEGIN, MBEHAV::EMOTE_END))); - } - else - { - // Compute parameters - CLFECOMMON::TCLEntityId slot; - fromString(args[0], slot); - // Magic Type (good bad neutral) - uint type; - fromString(args[1], type); - type %= 3; - MBEHAV::EBehaviour behTmp = (MBEHAV::EBehaviour)(MBEHAV::CASTING_GOOD+type); - MBEHAV::CBehaviour castingBeh(behTmp); - // Result - MBEHAV::CBehaviour behaviour; - uint result; - fromString(args[2], result); - result %= %3; - if (type==0) - behaviour.Behaviour = (MBEHAV::EBehaviour)(MBEHAV::END_CASTING_GOOD_SUCCESS + result); - else if(type==1) - behaviour.Behaviour = (MBEHAV::EBehaviour)(MBEHAV::END_CASTING_BAD_SUCCESS + result); - else - behaviour.Behaviour = (MBEHAV::EBehaviour)(MBEHAV::END_CASTING_NEUTRAL_SUCCESS + result); - uint16 spellPower, impactIntensity; - // Spell Power - fromString(args[3], spellPower); - behaviour.Magic.SpellPower = spellPower; - // Impact Intensity - fromString(args[4], impactIntensity); - behaviour.Magic.ImpactIntensity = impactIntensity; - // Resist - bool targetResists; - fromString(args[5], targetResists); - behaviour.Magic.TargetResists = targetResists; - // Get the entity - CEntityCL *entity = EntitiesMngr.entity(slot); - if(entity) - { - // Write the behaviour in the DB. - IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_BEHAVIOUR), castingBeh); - // Update the behaviour. - entity->updateVisualProperty(NetMngr.getCurrentServerTick()+10, CLFECOMMON::PROPERTY_BEHAVIOUR); - // Write the behaviour in the DB. - IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_BEHAVIOUR), behaviour); - // Update the behaviour. - entity->updateVisualProperty(NetMngr.getCurrentServerTick()+50, CLFECOMMON::PROPERTY_BEHAVIOUR); - } - else - CInterfaceManager::getInstance()->displaySystemInfo(ucstring("There is no entity in the given slot")); - } + // Check parameters. + if(args.size() != 6) + { + // Help + // CInterfaceManager::getInstance()->displaySystemInfo(ucstring("This command need 2 or 3 paramters :")); + // CInterfaceManager::getInstance()->displaySystemInfo(ucstring(" : the slot number of the entity to change")); + // CInterfaceManager::getInstance()->displaySystemInfo(ucstring(" : the behaviour to play for the entity, one of the following number :")); + // for(uint i = 0; idisplaySystemInfo(ucstring(NLMISC::toString(" %d - %s", i, MBEHAV::behaviourToString((MBEHAV::EBehaviour)i)))); + // CInterfaceManager::getInstance()->displaySystemInfo(ucstring(NLMISC::toString(" %d-%d - Emotes", MBEHAV::EMOTE_BEGIN, MBEHAV::EMOTE_END))); + } + else + { + // Compute parameters + CLFECOMMON::TCLEntityId slot; + fromString(args[0], slot); + // Magic Type (good bad neutral) + uint type; + fromString(args[1], type); + type %= 3; + MBEHAV::EBehaviour behTmp = (MBEHAV::EBehaviour)(MBEHAV::CASTING_GOOD+type); + MBEHAV::CBehaviour castingBeh(behTmp); + // Result + MBEHAV::CBehaviour behaviour; + uint result; + fromString(args[2], result); + result %= %3; + if (type==0) + behaviour.Behaviour = (MBEHAV::EBehaviour)(MBEHAV::END_CASTING_GOOD_SUCCESS + result); + else if(type==1) + behaviour.Behaviour = (MBEHAV::EBehaviour)(MBEHAV::END_CASTING_BAD_SUCCESS + result); + else + behaviour.Behaviour = (MBEHAV::EBehaviour)(MBEHAV::END_CASTING_NEUTRAL_SUCCESS + result); + uint16 spellPower, impactIntensity; + // Spell Power + fromString(args[3], spellPower); + behaviour.Magic.SpellPower = spellPower; + // Impact Intensity + fromString(args[4], impactIntensity); + behaviour.Magic.ImpactIntensity = impactIntensity; + // Resist + bool targetResists; + fromString(args[5], targetResists); + behaviour.Magic.TargetResists = targetResists; + // Get the entity + CEntityCL *entity = EntitiesMngr.entity(slot); + if(entity) + { + // Write the behaviour in the DB. + IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_BEHAVIOUR), castingBeh); + // Update the behaviour. + entity->updateVisualProperty(NetMngr.getCurrentServerTick()+10, CLFECOMMON::PROPERTY_BEHAVIOUR); + // Write the behaviour in the DB. + IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_BEHAVIOUR), behaviour); + // Update the behaviour. + entity->updateVisualProperty(NetMngr.getCurrentServerTick()+50, CLFECOMMON::PROPERTY_BEHAVIOUR); + } + else + CInterfaceManager::getInstance()->displaySystemInfo(ucstring("There is no entity in the given slot")); + } - // Command well done. - return true; -} + // Command well done. + return true; + } */ NLMISC_COMMAND(spell, "Cast a spell", "\n" - " : the one who cast the spell\n" - " : 0->OFF 1->CUR 2->MIX\n" - " : 0->Fail 1->Fumble 2->Success 3->Link\n" - " : 0->Resist 1->Not Resist\n" - " : \n" - " : [0, 5]\n") + " : the one who cast the spell\n" + " : 0->OFF 1->CUR 2->MIX\n" + " : 0->Fail 1->Fumble 2->Success 3->Link\n" + " : 0->Resist 1->Not Resist\n" + " : \n" + " : [0, 5]\n") { - // Check parameters. - if(args.size() != 6) + // Check parameters. + if(args.size() != 6) + { + // Help + // CInterfaceManager::getInstance()->displaySystemInfo(ucstring("This command need 2 or 3 paramters :")); + // CInterfaceManager::getInstance()->displaySystemInfo(ucstring(" : the slot number of the entity to change")); + // CInterfaceManager::getInstance()->displaySystemInfo(ucstring(" : the behaviour to play for the entity, one of the following number :")); + // for(uint i = 0; idisplaySystemInfo(ucstring(NLMISC::toString(" %d - %s", i, MBEHAV::behaviourToString((MBEHAV::EBehaviour)i)))); + // CInterfaceManager::getInstance()->displaySystemInfo(ucstring(NLMISC::toString(" %d-%d - Emotes", MBEHAV::EMOTE_BEGIN, MBEHAV::EMOTE_END))); + } + else + { + // Compute parameters + CLFECOMMON::TCLEntityId slot; + fromString(args[0], slot); + // Magic Type (good bad neutral) + uint type; + fromString(args[1], type); + type %= 3; + MBEHAV::EBehaviour behTmp = (MBEHAV::EBehaviour)(MBEHAV::CAST_OFF+type); + MBEHAV::CBehaviour castingBeh(behTmp); + // Result + MBEHAV::CBehaviour behaviour; + uint result; + fromString(args[2], result); + result %= 4; + behaviour.Behaviour = (MBEHAV::EBehaviour)(MBEHAV::CAST_OFF_FAIL+type*4+result); + // Spell Power + uint16 spellMode; + fromString(args[3], spellMode); + behaviour.Spell.SpellMode = spellMode; + // Impact Intensity + uint16 spellId; + fromString(args[4], spellId); + behaviour.Spell.SpellId = spellId; + // Resist + uint16 spellIntensity; + fromString(args[5], spellIntensity); + behaviour.Spell.SpellIntensity = spellIntensity; + // Get the entity + CEntityCL *entity = EntitiesMngr.entity(slot); + if(entity) { - // Help - // CInterfaceManager::getInstance()->displaySystemInfo(ucstring("This command need 2 or 3 paramters :")); - // CInterfaceManager::getInstance()->displaySystemInfo(ucstring(" : the slot number of the entity to change")); - // CInterfaceManager::getInstance()->displaySystemInfo(ucstring(" : the behaviour to play for the entity, one of the following number :")); - // for(uint i = 0; idisplaySystemInfo(ucstring(NLMISC::toString(" %d - %s", i, MBEHAV::behaviourToString((MBEHAV::EBehaviour)i)))); - // CInterfaceManager::getInstance()->displaySystemInfo(ucstring(NLMISC::toString(" %d-%d - Emotes", MBEHAV::EMOTE_BEGIN, MBEHAV::EMOTE_END))); - } - else - { - // Compute parameters - CLFECOMMON::TCLEntityId slot; - fromString(args[0], slot); - // Magic Type (good bad neutral) - uint type; - fromString(args[1], type); - type %= 3; - MBEHAV::EBehaviour behTmp = (MBEHAV::EBehaviour)(MBEHAV::CAST_OFF+type); - MBEHAV::CBehaviour castingBeh(behTmp); - // Result - MBEHAV::CBehaviour behaviour; - uint result; - fromString(args[2], result); - result %= 4; - behaviour.Behaviour = (MBEHAV::EBehaviour)(MBEHAV::CAST_OFF_FAIL+type*4+result); - // Spell Power - uint16 spellMode; - fromString(args[3], spellMode); - behaviour.Spell.SpellMode = spellMode; - // Impact Intensity - uint16 spellId; - fromString(args[4], spellId); - behaviour.Spell.SpellId = spellId; - // Resist - uint16 spellIntensity; - fromString(args[5], spellIntensity); - behaviour.Spell.SpellIntensity = spellIntensity; - // Get the entity - CEntityCL *entity = EntitiesMngr.entity(slot); - if(entity) - { - uint64 beha = castingBeh; - sint64 beha2 = *((sint64 *)(&beha)); - // Write the behaviour in the DB. - IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_BEHAVIOUR), beha2); - // Update the behaviour. - entity->updateVisualProperty(NetMngr.getCurrentServerTick()+10, CLFECOMMON::PROPERTY_BEHAVIOUR); - beha = behaviour; - beha2 = *((sint64 *)(&beha)); - // Write the behaviour in the DB. - IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_BEHAVIOUR), beha2); - // Update the behaviour. - entity->updateVisualProperty(NetMngr.getCurrentServerTick()+50, CLFECOMMON::PROPERTY_BEHAVIOUR); - } - else - CInterfaceManager::getInstance()->displaySystemInfo(ucstring("There is no entity in the given slot")); + uint64 beha = castingBeh; + sint64 beha2 = *((sint64 *)(&beha)); + // Write the behaviour in the DB. + IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_BEHAVIOUR), beha2); + // Update the behaviour. + entity->updateVisualProperty(NetMngr.getCurrentServerTick()+10, CLFECOMMON::PROPERTY_BEHAVIOUR); + beha = behaviour; + beha2 = *((sint64 *)(&beha)); + // Write the behaviour in the DB. + IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P" + toString(CLFECOMMON::PROPERTY_BEHAVIOUR), beha2); + // Update the behaviour. + entity->updateVisualProperty(NetMngr.getCurrentServerTick()+50, CLFECOMMON::PROPERTY_BEHAVIOUR); } + else + CInterfaceManager::getInstance()->displaySystemInfo(ucstring("There is no entity in the given slot")); + } - // Command well done. - return true; + // Command well done. + return true; } NLMISC_COMMAND(settarget, "Set a target for an entity. Do not set the target slot to remove the target", " []") { - CLFECOMMON::TCLEntityId targetSlot = CLFECOMMON::INVALID_SLOT; + CLFECOMMON::TCLEntityId targetSlot = CLFECOMMON::INVALID_SLOT; - // Check parameters. - switch(args.size()) - { - // Set the target for the entity. - case 2: - fromString(args[1], targetSlot); + // Check parameters. + switch(args.size()) + { + // Set the target for the entity. + case 2: + fromString(args[1], targetSlot); - // Remove the target for the entity. - case 1: - { - uint entitySlot; - fromString(args[0], entitySlot); - CEntityCL *entity = EntitiesMngr.entity(entitySlot); - if(entity) - entity->targetSlot(targetSlot); - else - nlwarning("command 'settarget': there is no entity in the slot %d", entitySlot); - } - break; + // Remove the target for the entity. + case 1: + { + uint entitySlot; + fromString(args[0], entitySlot); + CEntityCL *entity = EntitiesMngr.entity(entitySlot); + if(entity) + entity->targetSlot(targetSlot); + else + nlwarning("command 'settarget': there is no entity in the slot %d", entitySlot); + } + break; - // Bad command. - default: - return false; - } + // Bad command. + default: + return false; + } - // Well done. - return true; + // Well done. + return true; } NLMISC_COMMAND(particle, "Create a particule at the user position (play FireWorkA_with_sound.ps by default)", "[]") { - string fn; + string fn; - // Check parameters. - if(args.size() == 0) - { - fn = "FireWorkA_with_sound.ps"; - } - else if(args.size() == 1) - { - fn = args[0]; - } - else - return false; + // Check parameters. + if(args.size() == 0) + { + fn = "FireWorkA_with_sound.ps"; + } + else if(args.size() == 1) + { + fn = args[0]; + } + else + return false; - UInstance fx = Scene->createInstance(fn); + UInstance fx = Scene->createInstance(fn); - // not found - if(fx.empty()) - { - log.displayNL ("Can't create instance '%s'", fn.c_str()); - return false; - } + // not found + if(fx.empty()) + { + log.displayNL ("Can't create instance '%s'", fn.c_str()); + return false; + } - fx.setPos(UserEntity->pos()); - fx.setClusterSystem(UserEntity->skeleton()->getClusterSystem()); + fx.setPos(UserEntity->pos()); + fx.setClusterSystem(UserEntity->skeleton()->getClusterSystem()); - // Command well done. - return true; + // Command well done. + return true; } NLMISC_COMMAND(move, "Move an entity", "Slot: [1-254]") { - // Check parameters. - if(args.size() != 1) - return false; + // Check parameters. + if(args.size() != 1) + return false; - CLFECOMMON::TCLEntityId slot; - fromString(args[0], slot); + CLFECOMMON::TCLEntityId slot; + fromString(args[0], slot); - // Compute the position. - CEntityCL *entity = EntitiesMngr.entity(slot); - if(entity) - { - sint64 x = (sint64)((entity->pos().x+UserEntity->front().x*10.0)*1000.0); - sint64 y = (sint64)((entity->pos().y+UserEntity->front().y*10.0)*1000.0); - sint64 z = (sint64)((entity->pos().z+UserEntity->front().z*10.0)*1000.0); - // Write the position in the DB. - IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P0", x); - IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P1", y); - IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P2", z); - // Update the position. - EntitiesMngr.updateVisualProperty(NetMngr.getCurrentServerTick()+30, slot, 0); + // Compute the position. + CEntityCL *entity = EntitiesMngr.entity(slot); + if(entity) + { + sint64 x = (sint64)((entity->pos().x+UserEntity->front().x*10.0)*1000.0); + sint64 y = (sint64)((entity->pos().y+UserEntity->front().y*10.0)*1000.0); + sint64 z = (sint64)((entity->pos().z+UserEntity->front().z*10.0)*1000.0); + // Write the position in the DB. + IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P0", x); + IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P1", y); + IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P2", z); + // Update the position. + EntitiesMngr.updateVisualProperty(NetMngr.getCurrentServerTick()+30, slot, 0); - x = (sint64)((entity->pos().x)*1000.0); - y = (sint64)((entity->pos().y)*1000.0); - z = (sint64)((entity->pos().z)*1000.0); - // Write the position in the DB. - IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P0", x); - IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P1", y); - IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P2", z); - // Update the position. - EntitiesMngr.updateVisualProperty(NetMngr.getCurrentServerTick()+60, slot, 0); - } - else - nlwarning("command 'move' : there is no entity allocated in slot %d", slot); + x = (sint64)((entity->pos().x)*1000.0); + y = (sint64)((entity->pos().y)*1000.0); + z = (sint64)((entity->pos().z)*1000.0); + // Write the position in the DB. + IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P0", x); + IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P1", y); + IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P2", z); + // Update the position. + EntitiesMngr.updateVisualProperty(NetMngr.getCurrentServerTick()+60, slot, 0); + } + else + nlwarning("command 'move' : there is no entity allocated in slot %d", slot); - // Command well done. - return true; + // Command well done. + return true; } NLMISC_COMMAND(moveRel, "Move an entity, specifying delta pos from current", "Slot: [1-254] dx(m) dy(m) [dt(tick)] [predictedIV(tick)]") { - // Check parameters. - if(args.size() <3) - return false; + // Check parameters. + if(args.size() <3) + return false; - CLFECOMMON::TCLEntityId slot; - fromString(args[0], slot); + CLFECOMMON::TCLEntityId slot; + fromString(args[0], slot); - // Compute the position. - CEntityCL *entity = EntitiesMngr.entity(slot); - if(entity) - { - float dx, dy; - fromString(args[1], dx); - fromString(args[2], dy); - sint32 dt= 10; - if(args.size()>=4) - fromString(args[3], dt); - sint32 pi= 0; - if(args.size()>=5) - fromString(args[4], pi); - sint64 x = (sint64)((entity->pos().x+dx)*1000.0); - sint64 y = (sint64)((entity->pos().y+dy)*1000.0); - sint64 z = (sint64)((entity->pos().z+0)*1000.0); - // Write the position in the DB. - IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P0", x); - IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P1", y); - IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P2", z); - // Update the position. - EntitiesMngr.updateVisualProperty(NetMngr.getCurrentServerTick()+dt, slot, 0, pi); - } - else - nlwarning("command 'move' : there is no entity allocated in slot %d", slot); + // Compute the position. + CEntityCL *entity = EntitiesMngr.entity(slot); + if(entity) + { + float dx, dy; + fromString(args[1], dx); + fromString(args[2], dy); + sint32 dt= 10; + if(args.size()>=4) + fromString(args[3], dt); + sint32 pi= 0; + if(args.size()>=5) + fromString(args[4], pi); + sint64 x = (sint64)((entity->pos().x+dx)*1000.0); + sint64 y = (sint64)((entity->pos().y+dy)*1000.0); + sint64 z = (sint64)((entity->pos().z+0)*1000.0); + // Write the position in the DB. + IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P0", x); + IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P1", y); + IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P2", z); + // Update the position. + EntitiesMngr.updateVisualProperty(NetMngr.getCurrentServerTick()+dt, slot, 0, pi); + } + else + nlwarning("command 'move' : there is no entity allocated in slot %d", slot); - // Command well done. - return true; + // Command well done. + return true; } NLMISC_COMMAND(orient, "Orient an entity", "Slot: [1-254] orient(degree) [dt(tick)]") { - // Check parameters. - if(args.size() < 2) - return false; + // Check parameters. + if(args.size() < 2) + return false; - CLFECOMMON::TCLEntityId slot; - fromString(args[0], slot); + CLFECOMMON::TCLEntityId slot; + fromString(args[0], slot); - // Compute the position. - CEntityCL *entity = EntitiesMngr.entity(slot); - if(entity) - { - sint32 rot; - fromString(args[1], rot); - sint32 dt= 10; - if(args.size()> 2) - fromString(args[2], dt); - // Write the position in the DB. - float fRot= (float)(rot*Pi/180.f); - uint64 val= *(uint32*)(&fRot); - IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P"+toString(CLFECOMMON::PROPERTY_ORIENTATION), val); - // Update the position. - EntitiesMngr.updateVisualProperty(NetMngr.getCurrentServerTick()+dt, slot, CLFECOMMON::PROPERTY_ORIENTATION); - } - else - nlwarning("command 'move' : there is no entity allocated in slot %d", slot); + // Compute the position. + CEntityCL *entity = EntitiesMngr.entity(slot); + if(entity) + { + sint32 rot; + fromString(args[1], rot); + sint32 dt= 10; + if(args.size()> 2) + fromString(args[2], dt); + // Write the position in the DB. + float fRot= (float)(rot*Pi/180.f); + uint64 val= *(uint32*)(&fRot); + IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P"+toString(CLFECOMMON::PROPERTY_ORIENTATION), val); + // Update the position. + EntitiesMngr.updateVisualProperty(NetMngr.getCurrentServerTick()+dt, slot, CLFECOMMON::PROPERTY_ORIENTATION); + } + else + nlwarning("command 'move' : there is no entity allocated in slot %d", slot); - // Command well done. - return true; + // Command well done. + return true; } NLMISC_COMMAND(moveTo, "Move an entity to another one", ":[1-254], :[0-254] default 0") { - sint64 x, y, z; + sint64 x, y, z; - // Check parameters. - if(args.size() == 1) + // Check parameters. + if(args.size() == 1) + { + x = (sint64)(UserEntity->pos().x*1000.0); + y = (sint64)(UserEntity->pos().y*1000.0); + z = (sint64)(UserEntity->pos().z*1000.0); + } + else if(args.size() == 2) + { + CLFECOMMON::TCLEntityId slotDest; + fromString(args[1], slotDest); + // Compute the position. + CEntityCL *entity = EntitiesMngr.entity(slotDest); + if(entity) { - x = (sint64)(UserEntity->pos().x*1000.0); - y = (sint64)(UserEntity->pos().y*1000.0); - z = (sint64)(UserEntity->pos().z*1000.0); + x = (sint64)(entity->pos().x*1000.0); + y = (sint64)(entity->pos().y*1000.0); + z = (sint64)(entity->pos().z*1000.0); } - else if(args.size() == 2) + else { - CLFECOMMON::TCLEntityId slotDest; - fromString(args[1], slotDest); - // Compute the position. - CEntityCL *entity = EntitiesMngr.entity(slotDest); - if(entity) - { - x = (sint64)(entity->pos().x*1000.0); - y = (sint64)(entity->pos().y*1000.0); - z = (sint64)(entity->pos().z*1000.0); - } - else - { - // Command is correct but not all the parameters are valid. - nlwarning("command 'move_to' : there is no entity allocated for the dest in slot %d", slotDest); - return true; - } + // Command is correct but not all the parameters are valid. + nlwarning("command 'move_to' : there is no entity allocated for the dest in slot %d", slotDest); + return true; } - // Wrong number of parameters. - else - return false; + } + // Wrong number of parameters. + else + return false; - CLFECOMMON::TCLEntityId slot; - fromString(args[0], slot); - // Write the position in the DB. - IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P0", x); - IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P1", y); - IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P2", z); - // Update the position. - EntitiesMngr.updateVisualProperty(NetMngr.getCurrentServerTick()+30, slot, 0); + CLFECOMMON::TCLEntityId slot; + fromString(args[0], slot); + // Write the position in the DB. + IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P0", x); + IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P1", y); + IngameDbMngr.setProp("Entities:E" + toString(slot) + ":P2", z); + // Update the position. + EntitiesMngr.updateVisualProperty(NetMngr.getCurrentServerTick()+30, slot, 0); - // Command well done. - return true; + // Command well done. + return true; } NLMISC_COMMAND(setMode, "Set The Mode for an Entity without to add a stage for it", " ") { - // Check parameters. - if(args.size() != 2) - return false; + // Check parameters. + if(args.size() != 2) + return false; - // Get the Slot and the Mode. - CLFECOMMON::TCLEntityId slot; - fromString(args[0], slot); - sint32 nMode; - fromString(args[1], nMode); - MBEHAV::EMode mod = (MBEHAV::EMode)nMode; + // Get the Slot and the Mode. + CLFECOMMON::TCLEntityId slot; + fromString(args[0], slot); + sint32 nMode; + fromString(args[1], nMode); + MBEHAV::EMode mod = (MBEHAV::EMode)nMode; - // Compute the position. - CEntityCL *entity = EntitiesMngr.entity(slot); - if(entity) - entity->mode(mod); - else - nlwarning("command 'setMode' : there is no entity allocated in slot '%d'", slot); + // Compute the position. + CEntityCL *entity = EntitiesMngr.entity(slot); + if(entity) + entity->mode(mod); + else + nlwarning("command 'setMode' : there is no entity allocated in slot '%d'", slot); - // Command well done. - return true; + // Command well done. + return true; } NLMISC_COMMAND(paintTarget, "Modify the target color", - "\n" - " color for the target (0-7)\n") + "\n" + " color for the target (0-7)\n") { - // Check parameters - if(args.size() != 1) - return false; - // Get the entity slot - CLFECOMMON::TCLEntityId slot = UserEntity->selection(); - if(slot == CLFECOMMON::INVALID_SLOT) - return true; - // - SPropVisualA vA; - SPropVisualB vB; - SPropVisualC vC; - const string propNameA = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPA); - const string propNameB = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPB); - const string propNameC = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPC); - vA.PropertyA = NLGUI::CDBManager::getInstance()->getDbProp(propNameA)->getValue64(); - vB.PropertyB = NLGUI::CDBManager::getInstance()->getDbProp(propNameB)->getValue64(); - vC.PropertyC = NLGUI::CDBManager::getInstance()->getDbProp(propNameC)->getValue64(); + // Check parameters + if(args.size() != 1) + return false; + // Get the entity slot + CLFECOMMON::TCLEntityId slot = UserEntity->selection(); + if(slot == CLFECOMMON::INVALID_SLOT) + return true; + // + SPropVisualA vA; + SPropVisualB vB; + SPropVisualC vC; + const string propNameA = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPA); + const string propNameB = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPB); + const string propNameC = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPC); + vA.PropertyA = NLGUI::CDBManager::getInstance()->getDbProp(propNameA)->getValue64(); + vB.PropertyB = NLGUI::CDBManager::getInstance()->getDbProp(propNameB)->getValue64(); + vC.PropertyC = NLGUI::CDBManager::getInstance()->getDbProp(propNameC)->getValue64(); - // Get the visual item index - uint value; - fromString(args[0], value); - // Change color - vA.PropertySubData.JacketColor = value; - vA.PropertySubData.TrouserColor = value; - vA.PropertySubData.ArmColor = value; - vA.PropertySubData.HatColor = value; - vB.PropertySubData.HandsColor = value; - vB.PropertySubData.FeetColor = value; + // Get the visual item index + uint value; + fromString(args[0], value); + // Change color + vA.PropertySubData.JacketColor = value; + vA.PropertySubData.TrouserColor = value; + vA.PropertySubData.ArmColor = value; + vA.PropertySubData.HatColor = value; + vB.PropertySubData.HandsColor = value; + vB.PropertySubData.FeetColor = value; - // Set the database. - NLGUI::CDBManager::getInstance()->getDbProp(propNameA)->setValue64((sint64)vA.PropertyA); - NLGUI::CDBManager::getInstance()->getDbProp(propNameB)->setValue64((sint64)vB.PropertyB); - NLGUI::CDBManager::getInstance()->getDbProp(propNameC)->setValue64((sint64)vC.PropertyC); - // Force to update properties. - EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_VPA); + // Set the database. + NLGUI::CDBManager::getInstance()->getDbProp(propNameA)->setValue64((sint64)vA.PropertyA); + NLGUI::CDBManager::getInstance()->getDbProp(propNameB)->setValue64((sint64)vB.PropertyB); + NLGUI::CDBManager::getInstance()->getDbProp(propNameC)->setValue64((sint64)vC.PropertyC); + // Force to update properties. + EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_VPA); - // Done. - return true; + // Done. + return true; } NLMISC_COMMAND(playAnim, "Try to play the animation to the target", "") { - // Check parameters - if(args.size() != 1) - return false; + // Check parameters + if(args.size() != 1) + return false; - CLFECOMMON::TCLEntityId slot = UserEntity->selection(); - if(slot == CLFECOMMON::INVALID_SLOT) - return true; - if(EAM == 0) - return true; - NL3D::UAnimationSet *animset = EAM->getAnimationSet(); - if(animset == 0) - return true; - uint animId = animset->getAnimationIdByName(args[0]); - if(animId == UAnimationSet::NotFound) - { - nlwarning("anim not found %s", args[0].c_str()); - return true; - } - CEntityCL *selection = EntitiesMngr.entity(slot); - CCharacterCL *character = dynamic_cast(selection); - if(character) - character->setAnim(CAnimationStateSheet::Idle, (TAnimStateKey)CAnimation::UnknownAnim, animId); - return true; + CLFECOMMON::TCLEntityId slot = UserEntity->selection(); + if(slot == CLFECOMMON::INVALID_SLOT) + return true; + if(EAM == 0) + return true; + NL3D::UAnimationSet *animset = EAM->getAnimationSet(); + if(animset == 0) + return true; + uint animId = animset->getAnimationIdByName(args[0]); + if(animId == UAnimationSet::NotFound) + { + nlwarning("anim not found %s", args[0].c_str()); + return true; + } + CEntityCL *selection = EntitiesMngr.entity(slot); + CCharacterCL *character = dynamic_cast(selection); + if(character) + character->setAnim(CAnimationStateSheet::Idle, (TAnimStateKey)CAnimation::UnknownAnim, animId); + return true; } NLMISC_COMMAND(vP, "Modify the Visual Property", -"\n" -" of the entity to change.\n" -" the property to change :\n" -" 0->CHEST (0~511)\n" -" 1->LEG (0~255)\n" -" 2->ARM (0~255)\n" -" 3->HEAD (0~127)\n" -" 4->WEAPON_R (0~2047)\n" -" 5->WEAPON_L (0~255)\n" -" 6->FEET (0~511)\n" -" 7->HAND (0~511)\n" -" 8->EYES COLOR (0~7)\n" -" 9->SEX (0: Male, 1: Female)\n" -" 10->TATOO (0~31)\n" -" 11->CHEST COLOR (0~7)\n" -" 12->LEG COLOR (0~7)\n" -" 13->ARM COLOR (0~7)\n" -" 14->HAIR COLOR (0~7)\n" -" 15->HAND COLOR (0~7)\n" -" 16->FEET COLOR (0~7)\n" -" 17->MORPH 1 (0~7)\n" -" 18->MORPH 2 (0~7)\n" -" 19->MORPH 3 (0~7)\n" -" 20->MORPH 4 (0~7)\n" -" 21->MORPH 5 (0~7)\n" -" 22->MORPH 6 (0~7)\n" -" 23->MORPH 7 (0~7)\n" -" 24->CHARACTER HEIGHT (0~15)\n" -" 25->TORSO WIDTH (0~15)\n" -" 26->ARMS WIDTH (0~15)\n" -" 27->LEGS WIDTH (0~15)\n" -" 28->BREASTS SIZE (0~15)\n" -" for the property.\n") + "\n" + " of the entity to change.\n" + " the property to change :\n" + " 0->CHEST (0~511)\n" + " 1->LEG (0~255)\n" + " 2->ARM (0~255)\n" + " 3->HEAD (0~127)\n" + " 4->WEAPON_R (0~2047)\n" + " 5->WEAPON_L (0~255)\n" + " 6->FEET (0~511)\n" + " 7->HAND (0~511)\n" + " 8->EYES COLOR (0~7)\n" + " 9->SEX (0: Male, 1: Female)\n" + " 10->TATOO (0~31)\n" + " 11->CHEST COLOR (0~7)\n" + " 12->LEG COLOR (0~7)\n" + " 13->ARM COLOR (0~7)\n" + " 14->HAIR COLOR (0~7)\n" + " 15->HAND COLOR (0~7)\n" + " 16->FEET COLOR (0~7)\n" + " 17->MORPH 1 (0~7)\n" + " 18->MORPH 2 (0~7)\n" + " 19->MORPH 3 (0~7)\n" + " 20->MORPH 4 (0~7)\n" + " 21->MORPH 5 (0~7)\n" + " 22->MORPH 6 (0~7)\n" + " 23->MORPH 7 (0~7)\n" + " 24->CHARACTER HEIGHT (0~15)\n" + " 25->TORSO WIDTH (0~15)\n" + " 26->ARMS WIDTH (0~15)\n" + " 27->LEGS WIDTH (0~15)\n" + " 28->BREASTS SIZE (0~15)\n" + " for the property.\n") { - // Check parameters - if(args.size() != 3) - return false; + // Check parameters + if(args.size() != 3) + return false; - // Get the database entry. - SPropVisualA vA; - SPropVisualB vB; - SPropVisualC vC; - uint slot; - fromString(args[0], slot); - const string propNameA = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPA); - const string propNameB = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPB); - const string propNameC = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPC); - vA.PropertyA = NLGUI::CDBManager::getInstance()->getDbProp(propNameA)->getValue64(); - vB.PropertyB = NLGUI::CDBManager::getInstance()->getDbProp(propNameB)->getValue64(); - vC.PropertyC = NLGUI::CDBManager::getInstance()->getDbProp(propNameC)->getValue64(); - // Get the visual item index - uint value; - fromString(args[2], value); - // Get the visual slot to change. - uint type; - fromString(args[1], type); - // if .sitem visual slot, try translate .sitem to VSIndex - if(type<=7) + // Get the database entry. + SPropVisualA vA; + SPropVisualB vB; + SPropVisualC vC; + uint slot; + fromString(args[0], slot); + const string propNameA = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPA); + const string propNameB = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPB); + const string propNameC = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPC); + vA.PropertyA = NLGUI::CDBManager::getInstance()->getDbProp(propNameA)->getValue64(); + vB.PropertyB = NLGUI::CDBManager::getInstance()->getDbProp(propNameB)->getValue64(); + vC.PropertyC = NLGUI::CDBManager::getInstance()->getDbProp(propNameC)->getValue64(); + // Get the visual item index + uint value; + fromString(args[2], value); + // Get the visual slot to change. + uint type; + fromString(args[1], type); + // if .sitem visual slot, try translate .sitem to VSIndex + if(type<=7) + { + SLOTTYPE::EVisualSlot vslot= SLOTTYPE::HIDDEN_SLOT; + switch(type) { - SLOTTYPE::EVisualSlot vslot= SLOTTYPE::HIDDEN_SLOT; - switch(type) - { - case 0: vslot= SLOTTYPE::CHEST_SLOT; break; - case 1: vslot= SLOTTYPE::LEGS_SLOT; break; - case 2: vslot= SLOTTYPE::ARMS_SLOT; break; - case 3: vslot= SLOTTYPE::HEAD_SLOT; break; - case 4: vslot= SLOTTYPE::RIGHT_HAND_SLOT; break; - case 5: vslot= SLOTTYPE::LEFT_HAND_SLOT; break; - case 6: vslot= SLOTTYPE::FEET_SLOT; break; - case 7: vslot= SLOTTYPE::HANDS_SLOT; break; - default: break; - } - if(vslot!=SLOTTYPE::HIDDEN_SLOT && value==0) - { - sint vsIndex= SheetMngr.getVSIndex(args[2], vslot); - // succed! - if(vsIndex!=-1) - value= vsIndex; - } + case 0: vslot= SLOTTYPE::CHEST_SLOT; break; + case 1: vslot= SLOTTYPE::LEGS_SLOT; break; + case 2: vslot= SLOTTYPE::ARMS_SLOT; break; + case 3: vslot= SLOTTYPE::HEAD_SLOT; break; + case 4: vslot= SLOTTYPE::RIGHT_HAND_SLOT; break; + case 5: vslot= SLOTTYPE::LEFT_HAND_SLOT; break; + case 6: vslot= SLOTTYPE::FEET_SLOT; break; + case 7: vslot= SLOTTYPE::HANDS_SLOT; break; + default: break; } - // setup - switch(type) + if(vslot!=SLOTTYPE::HIDDEN_SLOT && value==0) { - case 0: - vA.PropertySubData.JacketModel = value; - break; - case 1: - vA.PropertySubData.TrouserModel = value; - break; - case 2: - vA.PropertySubData.ArmModel = value; - break; - case 3: - vA.PropertySubData.HatModel = value; - break; - case 4: - vA.PropertySubData.WeaponRightHand = value; - break; - case 5: - vA.PropertySubData.WeaponLeftHand = value; - break; - case 6: - vB.PropertySubData.FeetModel = value; - break; - case 7: - vB.PropertySubData.HandsModel = value; - break; - case 8: - vC.PropertySubData.EyesColor = value; - break; - case 9: - vA.PropertySubData.Sex = value; - break; - case 10: - vC.PropertySubData.Tattoo = value; - break; - case 11: - vA.PropertySubData.JacketColor = value; - break; - case 12: - vA.PropertySubData.TrouserColor = value; - break; - case 13: - vA.PropertySubData.ArmColor = value; - break; - case 14: - vA.PropertySubData.HatColor = value; - break; - case 15: - vB.PropertySubData.HandsColor = value; - break; - case 16: - vB.PropertySubData.FeetColor = value; - break; - case 17: - vC.PropertySubData.MorphTarget1 = value; - break; - case 18: - vC.PropertySubData.MorphTarget2 = value; - break; - case 19: - vC.PropertySubData.MorphTarget3 = value; - break; - case 20: - vC.PropertySubData.MorphTarget4 = value; - break; - case 21: - vC.PropertySubData.MorphTarget5 = value; - break; - case 22: - vC.PropertySubData.MorphTarget6 = value; - break; - case 23: - vC.PropertySubData.MorphTarget7 = value; - break; - case 24: - vC.PropertySubData.CharacterHeight = value; - break; - case 25: - vC.PropertySubData.TorsoWidth = value; - break; - case 26: - vC.PropertySubData.ArmsWidth = value; - break; - case 27: - vC.PropertySubData.LegsWidth = value; - break; - case 28: - vC.PropertySubData.BreastSize = value; - break; - - default: - nlwarning("command 'vP': type not valid"); - return false; - break; + sint vsIndex= SheetMngr.getVSIndex(args[2], vslot); + // succed! + if(vsIndex!=-1) + value= vsIndex; } + } + // setup + switch(type) + { + case 0: + vA.PropertySubData.JacketModel = value; + break; + case 1: + vA.PropertySubData.TrouserModel = value; + break; + case 2: + vA.PropertySubData.ArmModel = value; + break; + case 3: + vA.PropertySubData.HatModel = value; + break; + case 4: + vA.PropertySubData.WeaponRightHand = value; + break; + case 5: + vA.PropertySubData.WeaponLeftHand = value; + break; + case 6: + vB.PropertySubData.FeetModel = value; + break; + case 7: + vB.PropertySubData.HandsModel = value; + break; + case 8: + vC.PropertySubData.EyesColor = value; + break; + case 9: + vA.PropertySubData.Sex = value; + break; + case 10: + vC.PropertySubData.Tattoo = value; + break; + case 11: + vA.PropertySubData.JacketColor = value; + break; + case 12: + vA.PropertySubData.TrouserColor = value; + break; + case 13: + vA.PropertySubData.ArmColor = value; + break; + case 14: + vA.PropertySubData.HatColor = value; + break; + case 15: + vB.PropertySubData.HandsColor = value; + break; + case 16: + vB.PropertySubData.FeetColor = value; + break; + case 17: + vC.PropertySubData.MorphTarget1 = value; + break; + case 18: + vC.PropertySubData.MorphTarget2 = value; + break; + case 19: + vC.PropertySubData.MorphTarget3 = value; + break; + case 20: + vC.PropertySubData.MorphTarget4 = value; + break; + case 21: + vC.PropertySubData.MorphTarget5 = value; + break; + case 22: + vC.PropertySubData.MorphTarget6 = value; + break; + case 23: + vC.PropertySubData.MorphTarget7 = value; + break; + case 24: + vC.PropertySubData.CharacterHeight = value; + break; + case 25: + vC.PropertySubData.TorsoWidth = value; + break; + case 26: + vC.PropertySubData.ArmsWidth = value; + break; + case 27: + vC.PropertySubData.LegsWidth = value; + break; + case 28: + vC.PropertySubData.BreastSize = value; + break; - // Set the database. - NLGUI::CDBManager::getInstance()->getDbProp(propNameA)->setValue64((sint64)vA.PropertyA); - NLGUI::CDBManager::getInstance()->getDbProp(propNameB)->setValue64((sint64)vB.PropertyB); - NLGUI::CDBManager::getInstance()->getDbProp(propNameC)->setValue64((sint64)vC.PropertyC); - // Force to update properties. - EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_VPA); + default: + nlwarning("command 'vP': type not valid"); + return false; + break; + } - // Done. - return true; + // Set the database. + NLGUI::CDBManager::getInstance()->getDbProp(propNameA)->setValue64((sint64)vA.PropertyA); + NLGUI::CDBManager::getInstance()->getDbProp(propNameB)->setValue64((sint64)vB.PropertyB); + NLGUI::CDBManager::getInstance()->getDbProp(propNameC)->setValue64((sint64)vC.PropertyC); + // Force to update properties. + EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_VPA); + + // Done. + return true; } NLMISC_COMMAND(altLook, "Modify the Alternative Look Property", - "\n" - " of the entity to change.\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "[]\n" - "[]\n" - "[]\n") + "\n" + " of the entity to change.\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "[]\n" + "[]\n" + "[]\n") { - // Check parameters - if(args.size() < 8 || args.size() > 11) - return false; + // Check parameters + if(args.size() < 8 || args.size() > 11) + return false; - // Get the database entry. - uint slot; - fromString(args[0], slot); - const string propName = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPA); - // Get the old value (not useful since we change the whole property). - SAltLookProp altLookProp; - altLookProp.Summary = NLGUI::CDBManager::getInstance()->getDbProp(propName)->getValue64(); - uint32 colorTop, colorBot, weaponRightHand, weaponLeftHand, seed, colorHair, hat; - fromString(args[1], colorTop); - fromString(args[2], colorBot); - fromString(args[3], weaponRightHand); - fromString(args[4], weaponLeftHand); - fromString(args[5], seed); - fromString(args[6], colorHair); - fromString(args[7], hat); - altLookProp.Element.ColorTop = colorTop; - altLookProp.Element.ColorBot = colorBot; - altLookProp.Element.WeaponRightHand = weaponRightHand; - altLookProp.Element.WeaponLeftHand = weaponLeftHand; - altLookProp.Element.Seed = seed; - altLookProp.Element.ColorHair = colorHair; - altLookProp.Element.Hat = hat; - // New colours - if(args.size() == 11) - { - uint32 colorGlove, colorBoot, colorArm; - fromString(args[8], colorGlove); - fromString(args[9], colorBoot); - fromString(args[10], colorArm); - altLookProp.Element.ColorGlove = colorGlove; - altLookProp.Element.ColorBoot = colorBoot; - altLookProp.Element.ColorArm = colorArm; - } - // Old Colours - else - { - altLookProp.Element.ColorGlove = altLookProp.Element.ColorTop; - altLookProp.Element.ColorArm = altLookProp.Element.ColorTop; - altLookProp.Element.ColorBoot = altLookProp.Element.ColorBot; - } + // Get the database entry. + uint slot; + fromString(args[0], slot); + const string propName = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_VPA); + // Get the old value (not useful since we change the whole property). + SAltLookProp altLookProp; + altLookProp.Summary = NLGUI::CDBManager::getInstance()->getDbProp(propName)->getValue64(); + uint32 colorTop, colorBot, weaponRightHand, weaponLeftHand, seed, colorHair, hat; + fromString(args[1], colorTop); + fromString(args[2], colorBot); + fromString(args[3], weaponRightHand); + fromString(args[4], weaponLeftHand); + fromString(args[5], seed); + fromString(args[6], colorHair); + fromString(args[7], hat); + altLookProp.Element.ColorTop = colorTop; + altLookProp.Element.ColorBot = colorBot; + altLookProp.Element.WeaponRightHand = weaponRightHand; + altLookProp.Element.WeaponLeftHand = weaponLeftHand; + altLookProp.Element.Seed = seed; + altLookProp.Element.ColorHair = colorHair; + altLookProp.Element.Hat = hat; + // New colours + if(args.size() == 11) + { + uint32 colorGlove, colorBoot, colorArm; + fromString(args[8], colorGlove); + fromString(args[9], colorBoot); + fromString(args[10], colorArm); + altLookProp.Element.ColorGlove = colorGlove; + altLookProp.Element.ColorBoot = colorBoot; + altLookProp.Element.ColorArm = colorArm; + } + // Old Colours + else + { + altLookProp.Element.ColorGlove = altLookProp.Element.ColorTop; + altLookProp.Element.ColorArm = altLookProp.Element.ColorTop; + altLookProp.Element.ColorBoot = altLookProp.Element.ColorBot; + } - // Set the database. - NLGUI::CDBManager::getInstance()->getDbProp(propName)->setValue64((sint64)altLookProp.Summary); - // Force to update properties. - EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_VPA); + // Set the database. + NLGUI::CDBManager::getInstance()->getDbProp(propName)->setValue64((sint64)altLookProp.Summary); + // Force to update properties. + EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_VPA); - // Done. - return true; + // Done. + return true; } NLMISC_COMMAND(color, "Command to color an entity", -"\n" -": whole number (if <0 slot will be the current selection)\n" -": whole number\n" -": whole number\n" -": whole number\n" -"[]: whole number\n" -" default=the whole body\n" -" 0=CHEST\n" -" 1=LEG\n" -" 2=HEAD\n" -" 3=ARMS\n" -" 4=HANDS\n" -" 5=FEET\n") + "\n" + ": whole number (if <0 slot will be the current selection)\n" + ": whole number\n" + ": whole number\n" + ": whole number\n" + "[]: whole number\n" + " default=the whole body\n" + " 0=CHEST\n" + " 1=LEG\n" + " 2=HEAD\n" + " 3=ARMS\n" + " 4=HANDS\n" + " 5=FEET\n") { - // Check parameters. - if(args.size() != 4 && args.size() != 5) - return false; + // Check parameters. + if(args.size() != 4 && args.size() != 5) + return false; - // Witch part to dye ? - sint part = -1; - if(args.size() == 5) - fromString(args[4], part); + // Witch part to dye ? + sint part = -1; + if(args.size() == 5) + fromString(args[4], part); - // Get the entity slot to dye. - sint slotTmp; - fromString(args[0], slotTmp); - CLFECOMMON::TCLEntityId slot; - if(slotTmp >= 0) - slot = (CLFECOMMON::TCLEntityId)slotTmp; - else - slot = (CLFECOMMON::TCLEntityId)UserEntity->selection(); + // Get the entity slot to dye. + sint slotTmp; + fromString(args[0], slotTmp); + CLFECOMMON::TCLEntityId slot; + if(slotTmp >= 0) + slot = (CLFECOMMON::TCLEntityId)slotTmp; + else + slot = (CLFECOMMON::TCLEntityId)UserEntity->selection(); - CEntityCL *entity = EntitiesMngr.entity(slot); - if(entity) - { - sint color, hair, eyes; - fromString(args[1], color); - fromString(args[2], hair); - fromString(args[3], eyes); - entity->changeColors(color, hair, eyes, part); - } - else - nlwarning("command 'changeColors': there is no entity allocated in slot '%d'", slot); + CEntityCL *entity = EntitiesMngr.entity(slot); + if(entity) + { + sint color, hair, eyes; + fromString(args[1], color); + fromString(args[2], hair); + fromString(args[3], eyes); + entity->changeColors(color, hair, eyes, part); + } + else + nlwarning("command 'changeColors': there is no entity allocated in slot '%d'", slot); - // Command well done. - return true; + // Command well done. + return true; } NLMISC_COMMAND(saveIntCfg, "save the interface config file","") { - CInterfaceManager::getInstance()->saveConfig ("save/interface.icfg"); - return true; + CInterfaceManager::getInstance()->saveConfig ("save/interface.icfg"); + return true; } NLMISC_COMMAND(loadIntCfg, "load the interface config file","") { - CInterfaceManager *im = CInterfaceManager::getInstance(); - im->loadConfig ("save/interface.icfg"); - // reset the compass target - CGroupCompas *gc = dynamic_cast(CWidgetManager::getInstance()->getElementFromId("ui:interface:compass")); - if (gc && gc->isSavedTargetValid()) - { - gc->setTarget(gc->getSavedTarget()); - } - return true; + CInterfaceManager *im = CInterfaceManager::getInstance(); + im->loadConfig ("save/interface.icfg"); + // reset the compass target + CGroupCompas *gc = dynamic_cast(CWidgetManager::getInstance()->getElementFromId("ui:interface:compass")); + if (gc && gc->isSavedTargetValid()) + { + gc->setTarget(gc->getSavedTarget()); + } + return true; } NLMISC_COMMAND(harvestDeposit, "harvest a deposit", "") { - // no parameter needed + // no parameter needed - // Create the message for the server -/* CBitMemStream out; + // Create the message for the server + /* CBitMemStream out; if(GenericMsgHeaderMngr.pushNameToStream("HARVEST:DEPOSIT", out)) { - uint16 skill = SKILLS::digging; + uint16 skill = SKILLS::digging; - out.serial(skill); + out.serial(skill); - NetMngr.push(out); + NetMngr.push(out); - // open the interface - // CWidgetManager::getInstance()->getWindowFromId("ui:interface:harvest")->setActive(true); + // open the interface + // CWidgetManager::getInstance()->getWindowFromId("ui:interface:harvest")->setActive(true); } else - nlwarning("command : unknown message name : 'HARVEST:DEPOSIT'"); -*/ - return true; + nlwarning("command : unknown message name : 'HARVEST:DEPOSIT'"); + */ + return true; } NLMISC_COMMAND(training, "start a training action", "") { - // no parameter needed + // no parameter needed - // Create the message for the server - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream("TRAINING", out)) - { - NetMngr.push(out); - } - else - nlwarning("command : unknown message name : 'TRAINING'"); + // Create the message for the server + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream("TRAINING", out)) + { + NetMngr.push(out); + } + else + nlwarning("command : unknown message name : 'TRAINING'"); - return true; + return true; } NLMISC_COMMAND(testMount, "Set the entity to mount"," ") { - CLFECOMMON::TCLEntityId slot; - CLFECOMMON::TCLEntityId mount = CLFECOMMON::INVALID_SLOT; + CLFECOMMON::TCLEntityId slot; + CLFECOMMON::TCLEntityId mount = CLFECOMMON::INVALID_SLOT; - switch(args.size()) - { - case 2: - fromString(args[1], mount); - case 1: - fromString(args[0], slot); - break; + switch(args.size()) + { + case 2: + fromString(args[1], mount); + case 1: + fromString(args[0], slot); + break; - default: - return false; - break; - } + default: + return false; + break; + } - // Set the database. - string propName = toString("SERVER:Entities:E%d:P%d", mount, CLFECOMMON::PROPERTY_RIDER_ENTITY_ID); - NLGUI::CDBManager::getInstance()->getDbProp(propName)->setValue64(slot); - // Force to update properties. - EntitiesMngr.updateVisualProperty(0, mount, CLFECOMMON::PROPERTY_RIDER_ENTITY_ID); - // Set the database. - propName = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_ENTITY_MOUNTED_ID); - NLGUI::CDBManager::getInstance()->getDbProp(propName)->setValue64(mount); - // Force to update properties. - EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_ENTITY_MOUNTED_ID); - return true; + // Set the database. + string propName = toString("SERVER:Entities:E%d:P%d", mount, CLFECOMMON::PROPERTY_RIDER_ENTITY_ID); + NLGUI::CDBManager::getInstance()->getDbProp(propName)->setValue64(slot); + // Force to update properties. + EntitiesMngr.updateVisualProperty(0, mount, CLFECOMMON::PROPERTY_RIDER_ENTITY_ID); + // Set the database. + propName = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_ENTITY_MOUNTED_ID); + NLGUI::CDBManager::getInstance()->getDbProp(propName)->setValue64(mount); + // Force to update properties. + EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_ENTITY_MOUNTED_ID); + return true; } NLMISC_COMMAND(mount, "Set the entity to mount"," []") { - CLFECOMMON::TCLEntityId slot; - CLFECOMMON::TCLEntityId mount = CLFECOMMON::INVALID_SLOT; + CLFECOMMON::TCLEntityId slot; + CLFECOMMON::TCLEntityId mount = CLFECOMMON::INVALID_SLOT; - switch(args.size()) - { - case 2: - fromString(args[1], mount); - case 1: - fromString(args[0], slot); - break; + switch(args.size()) + { + case 2: + fromString(args[1], mount); + case 1: + fromString(args[0], slot); + break; - default: - return false; - break; - } + default: + return false; + break; + } - // Set the database. - string propName = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_ENTITY_MOUNTED_ID); - NLGUI::CDBManager::getInstance()->getDbProp(propName)->setValue64(mount); - // Force to update properties. - EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_ENTITY_MOUNTED_ID); + // Set the database. + string propName = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_ENTITY_MOUNTED_ID); + NLGUI::CDBManager::getInstance()->getDbProp(propName)->setValue64(mount); + // Force to update properties. + EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_ENTITY_MOUNTED_ID); - // Command well done - return true; + // Command well done + return true; } NLMISC_COMMAND(rider, "Set the rider"," []") { - CLFECOMMON::TCLEntityId slot; - CLFECOMMON::TCLEntityId rider = CLFECOMMON::INVALID_SLOT; + CLFECOMMON::TCLEntityId slot; + CLFECOMMON::TCLEntityId rider = CLFECOMMON::INVALID_SLOT; - switch(args.size()) - { - case 2: - fromString(args[1], rider); - case 1: - fromString(args[0], slot); - break; + switch(args.size()) + { + case 2: + fromString(args[1], rider); + case 1: + fromString(args[0], slot); + break; - default: - return false; - break; - } + default: + return false; + break; + } - // Set the database. - string propName = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_RIDER_ENTITY_ID); - NLGUI::CDBManager::getInstance()->getDbProp(propName)->setValue64(rider); - // Force to update properties. - EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_RIDER_ENTITY_ID); + // Set the database. + string propName = toString("SERVER:Entities:E%d:P%d", slot, CLFECOMMON::PROPERTY_RIDER_ENTITY_ID); + NLGUI::CDBManager::getInstance()->getDbProp(propName)->setValue64(rider); + // Force to update properties. + EntitiesMngr.updateVisualProperty(0, slot, CLFECOMMON::PROPERTY_RIDER_ENTITY_ID); - // Command well done - return true; + // Command well done + return true; } NLMISC_COMMAND(disbandConvoy, "disband current beasts convoy", "") { - // no parameter needed + // no parameter needed - // Create the message for the server - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream("ANIMALS:DISBAND_CONVOY", out)) - { - NetMngr.push(out); - } - else - nlwarning("command : unknown message name : 'ANIMALS:DISBAND_CONVOY'"); + // Create the message for the server + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream("ANIMALS:DISBAND_CONVOY", out)) + { + NetMngr.push(out); + } + else + nlwarning("command : unknown message name : 'ANIMALS:DISBAND_CONVOY'"); - return true; + return true; } NLMISC_COMMAND(learnAllBrick, "learn all bricks (only in local mode)", "") { - CInterfaceManager *pIM= CInterfaceManager::getInstance(); - uint i=0; - for(;;) - { - CCDBNodeLeaf * node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:BRICK_FAMILY:%d:BRICKS", i), false); - if(node) - node->setValue64(SINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)); - else - break; - i++; - } - return true; + CInterfaceManager *pIM= CInterfaceManager::getInstance(); + uint i=0; + for(;;) + { + CCDBNodeLeaf * node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:BRICK_FAMILY:%d:BRICKS", i), false); + if(node) + node->setValue64(SINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)); + else + break; + i++; + } + return true; } NLMISC_COMMAND(learnBrick, "learn a specified brick (only in local mode)", "") { - CInterfaceManager *pIM= CInterfaceManager::getInstance(); - CSBrickManager *pBM= CSBrickManager::getInstance(); + CInterfaceManager *pIM= CInterfaceManager::getInstance(); + CSBrickManager *pBM= CSBrickManager::getInstance(); - if(args.size()<1) - return false; + if(args.size()<1) + return false; - // translate to brick sheet id - CSheetId brickSheetId; - uint testId; - fromString(args[0], testId); - if(testId!=0) - { - brickSheetId= CSheetId(testId); - } - else - { - string str= args[0]; - if(str.find(".sbrick")==string::npos) - str+= ".sbrick"; - brickSheetId.buildSheetId(str); - } + // translate to brick sheet id + CSheetId brickSheetId; + uint testId; + fromString(args[0], testId); + if(testId!=0) + { + brickSheetId= CSheetId(testId); + } + else + { + string str= args[0]; + if(str.find(".sbrick")==string::npos) + str+= ".sbrick"; + brickSheetId.buildSheetId(str); + } - // get the brick sheet - CSBrickSheet *brick= pBM->getBrick(brickSheetId); - if(!brick) - { - pIM->displaySystemInfo(toString("brick '%s' not found", args[0].c_str())); - return false; - } + // get the brick sheet + CSBrickSheet *brick= pBM->getBrick(brickSheetId); + if(!brick) + { + pIM->displaySystemInfo(toString("brick '%s' not found", args[0].c_str())); + return false; + } - // force learn it. - CCDBNodeLeaf * node= pBM->getKnownBrickBitFieldDB(brick->BrickFamily); - if(node) - { - uint64 flags= node->getValue64(); - flags|= uint64(1)<<(brick->IndexInFamily-1); - node->setValue64(flags); - } - return true; + // force learn it. + CCDBNodeLeaf * node= pBM->getKnownBrickBitFieldDB(brick->BrickFamily); + if(node) + { + uint64 flags= node->getValue64(); + flags|= uint64(1)<<(brick->IndexInFamily-1); + node->setValue64(flags); + } + return true; } NLMISC_COMMAND(learnPhrase, "learn all bricks of a specified phrase (only in local mode)", "") { - CInterfaceManager *pIM= CInterfaceManager::getInstance(); - CSBrickManager *pBM= CSBrickManager::getInstance(); - CSPhraseManager *pPM= CSPhraseManager::getInstance(); + CInterfaceManager *pIM= CInterfaceManager::getInstance(); + CSBrickManager *pBM= CSBrickManager::getInstance(); + CSPhraseManager *pPM= CSPhraseManager::getInstance(); - if(args.size()<1) - return false; + if(args.size()<1) + return false; - // translate to brick sheet id - CSheetId phraseSheetId; - uint testId; - fromString(args[0], testId); - if(testId!=0) + // translate to brick sheet id + CSheetId phraseSheetId; + uint testId; + fromString(args[0], testId); + if(testId!=0) + { + phraseSheetId= CSheetId(testId); + } + else + { + string str= args[0]; + if(str.find(".sphrase")==string::npos) + str+= ".sphrase"; + phraseSheetId.buildSheetId(str); + } + + // get the brick sheet + CSPhraseCom phrase; + pPM->buildPhraseFromSheet(phrase, phraseSheetId.asInt()); + if(phrase.empty()) + { + pIM->displaySystemInfo(toString("phrase '%s' not found", args[0].c_str())); + return false; + } + + // For all bricks of this phrase + for(uint i=0;igetBrick(phrase.Bricks[i]); + if(brick) { - phraseSheetId= CSheetId(testId); - } - else - { - string str= args[0]; - if(str.find(".sphrase")==string::npos) - str+= ".sphrase"; - phraseSheetId.buildSheetId(str); + // force learn it. + CCDBNodeLeaf * node= pBM->getKnownBrickBitFieldDB(brick->BrickFamily); + if(node) + { + uint64 flags= node->getValue64(); + flags|= uint64(1)<<(brick->IndexInFamily-1); + node->setValue64(flags); + } } + } - // get the brick sheet - CSPhraseCom phrase; - pPM->buildPhraseFromSheet(phrase, phraseSheetId.asInt()); - if(phrase.empty()) - { - pIM->displaySystemInfo(toString("phrase '%s' not found", args[0].c_str())); - return false; - } - - // For all bricks of this phrase - for(uint i=0;igetBrick(phrase.Bricks[i]); - if(brick) - { - // force learn it. - CCDBNodeLeaf * node= pBM->getKnownBrickBitFieldDB(brick->BrickFamily); - if(node) - { - uint64 flags= node->getValue64(); - flags|= uint64(1)<<(brick->IndexInFamily-1); - node->setValue64(flags); - } - } - } - - return true; + return true; } /*NLMISC_COMMAND(xp, "To gain XP in a given Skill"," []") -{ - // Check parameters. - if( args.size() < 2 || args.size() > 3 ) - return false; + { + // Check parameters. + if( args.size() < 2 || args.size() > 3 ) + return false; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream("CHEAT:XP", out)) - { - uint32 xp; - fromString(args[0], xp); - string skill = args[1]; - string speciality; - if( args.size() == 3 ) - speciality = args[2]; - out.serial( xp ); - out.serial( skill ); - out.serial( speciality ); - // Add the message to the send list. - NetMngr.push(out); - // send CHEAT:XP - nlinfo("command 'xp': CHEAT:XP pushed"); - } - else - nlwarning("command 'xp': unknown message named 'CHEAT:XP'"); + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream("CHEAT:XP", out)) + { + uint32 xp; + fromString(args[0], xp); + string skill = args[1]; + string speciality; + if( args.size() == 3 ) + speciality = args[2]; + out.serial( xp ); + out.serial( skill ); + out.serial( speciality ); + // Add the message to the send list. + NetMngr.push(out); + // send CHEAT:XP + nlinfo("command 'xp': CHEAT:XP pushed"); + } + else + nlwarning("command 'xp': unknown message named 'CHEAT:XP'"); - // Done. - return true; -}*/ + // Done. + return true; + }*/ NLMISC_COMMAND(money, "To earn Money (only in local mode)"," [] [] []") { - if (args.size() != 1) return false; - uint64 money; - fromString(args[0], money); - CInterfaceManager *im = CInterfaceManager::getInstance(); - NLGUI::CDBManager::getInstance()->getDbProp("SERVER:INVENTORY:MONEY")->setValue64(money); - return true; -/* - sint32 a = 0; - sint32 b = 0; - sint32 c = 0; - sint32 d = 0; + if (args.size() != 1) return false; + uint64 money; + fromString(args[0], money); + CInterfaceManager *im = CInterfaceManager::getInstance(); + NLGUI::CDBManager::getInstance()->getDbProp("SERVER:INVENTORY:MONEY")->setValue64(money); + return true; + /* + sint32 a = 0; + sint32 b = 0; + sint32 c = 0; + sint32 d = 0; - // Check parameters. - switch(args.size()) - { - case 4: - fromString(args[3], d); - case 3: - fromString(args[2], c); - case 2: - fromString(args[1], b); - case 1: - fromString(args[0], a); - break; - default: - return false; - } + // Check parameters. + switch(args.size()) + { + case 4: + fromString(args[3], d); + case 3: + fromString(args[2], c); + case 2: + fromString(args[1], b); + case 1: + fromString(args[0], a); + break; + default: + return false; + } - CInterfaceManager *im = CInterfaceManager::getInstance(); - string ls = im->getDefine("money_1"); - string ms = im->getDefine("money_2"); - string bs = im->getDefine("money_3"); - string vbs = im->getDefine("money_4"); - NLGUI::CDBManager::getInstance()->getDbProp(ls + ":QUANTITY")->setValue32(a); - NLGUI::CDBManager::getInstance()->getDbProp(ms + ":QUANTITY")->setValue32(b); - NLGUI::CDBManager::getInstance()->getDbProp(bs + ":QUANTITY")->setValue32(c); - NLGUI::CDBManager::getInstance()->getDbProp(vbs + ":QUANTITY")->setValue32(d); - return true; -*/ + CInterfaceManager *im = CInterfaceManager::getInstance(); + string ls = im->getDefine("money_1"); + string ms = im->getDefine("money_2"); + string bs = im->getDefine("money_3"); + string vbs = im->getDefine("money_4"); + NLGUI::CDBManager::getInstance()->getDbProp(ls + ":QUANTITY")->setValue32(a); + NLGUI::CDBManager::getInstance()->getDbProp(ms + ":QUANTITY")->setValue32(b); + NLGUI::CDBManager::getInstance()->getDbProp(bs + ":QUANTITY")->setValue32(c); + NLGUI::CDBManager::getInstance()->getDbProp(vbs + ":QUANTITY")->setValue32(d); + return true; + */ } /* -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)>" ) -{ - // Check parameters. - if(args.size() < 5) return false; + 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)>" ) + { + // Check parameters. + if(args.size() < 5) return false; - // read params - string characterName = args[0]; - EGSPD::CPeople::TPeople race = EGSPD::CPeople::fromString( args[1] ); - if( race == EGSPD::CPeople::EndPeople ) return false; + // read params + string characterName = args[0]; + EGSPD::CPeople::TPeople race = EGSPD::CPeople::fromString( args[1] ); + if( race == EGSPD::CPeople::EndPeople ) return false; - GSGENDER::EGender gender = GSGENDER::stringToEnum( args[2] ); - if( gender == GSGENDER::unknown ) return false; + GSGENDER::EGender gender = GSGENDER::stringToEnum( args[2] ); + if( gender == GSGENDER::unknown ) return false; - ROLES::ERole role = ROLES::toRoleId( args[3] ); - if( role == ROLES::role_unknown ) return false; + ROLES::ERole role = ROLES::toRoleId( args[3] ); + if( role == ROLES::role_unknown ) return false; - uint16 level; - fromString(args[4], level); + uint16 level; + fromString(args[4], level); - CBitMemStream bms; - string msgType = "CHEAT:CREATE_CHARACTER"; - if( GenericMsgHeaderMngr.pushNameToStream(msgType,bms) ) - { - bms.serial( characterName ); - bms.serialEnum( race ); - bms.serialEnum( gender ); - bms.serialEnum( role ); - bms.serial( level ); - NetMngr.push( bms ); - nldebug(" sending 'CHEAT:CREATE_CHARACTER' message to server"); - } - else - { - nlwarning(" unknown message name : CHEAT:CREATE_CHARACTER"); - } - return true; -} + CBitMemStream bms; + string msgType = "CHEAT:CREATE_CHARACTER"; + if( GenericMsgHeaderMngr.pushNameToStream(msgType,bms) ) + { + bms.serial( characterName ); + bms.serialEnum( race ); + bms.serialEnum( gender ); + bms.serialEnum( role ); + bms.serial( level ); + NetMngr.push( bms ); + nldebug(" sending 'CHEAT:CREATE_CHARACTER' message to server"); + } + else + { + nlwarning(" unknown message name : CHEAT:CREATE_CHARACTER"); + } + return true; + } */ /* -NLMISC_COMMAND( add_role, "add role to character", "" ) -{ - // Check parameters. - if(args.size() < 2) return false; + NLMISC_COMMAND( add_role, "add role to character", "" ) + { + // Check parameters. + if(args.size() < 2) return false; - ROLES::ERole role = ROLES::toRoleId( args[0] ); - if( role == ROLES::role_unknown ) return false; + ROLES::ERole role = ROLES::toRoleId( args[0] ); + if( role == ROLES::role_unknown ) return false; - uint16 level; - fromString(args[1], level); + uint16 level; + fromString(args[1], level); - CBitMemStream bms; - string msgType = "CHEAT:ADD_ROLE"; - if( GenericMsgHeaderMngr.pushNameToStream(msgType,bms) ) - { - bms.serialEnum( role ); - bms.serial( level ); - NetMngr.push( bms ); - nldebug(" sending 'CHEAT:ADD_ROLE' message to server"); - } - else - { - nlwarning(" unknown message name : CHEAT:ADD_ROLE"); - } - return true; -} + CBitMemStream bms; + string msgType = "CHEAT:ADD_ROLE"; + if( GenericMsgHeaderMngr.pushNameToStream(msgType,bms) ) + { + bms.serialEnum( role ); + bms.serial( level ); + NetMngr.push( bms ); + nldebug(" sending 'CHEAT:ADD_ROLE' message to server"); + } + else + { + nlwarning(" unknown message name : CHEAT:ADD_ROLE"); + } + return true; + } */ NLMISC_COMMAND(test, "", "") { - sint64 x, y, z; - CLFECOMMON::TCLEntityId entSlot = UserEntity->selection(); - CEntityCL *entPtr = EntitiesMngr.entity(entSlot); - if(entPtr) + sint64 x, y, z; + CLFECOMMON::TCLEntityId entSlot = UserEntity->selection(); + CEntityCL *entPtr = EntitiesMngr.entity(entSlot); + if(entPtr) + { + if(entPtr->skeleton()) { - if(entPtr->skeleton()) - { - if(entPtr->skeleton()->getLastClippedState()) - { - NLMISC::CMatrix mat = entPtr->skeleton()->getLastWorldMatrixComputed(); - NLMISC::CVectorD newPos = entPtr->pos() + mat.getJ()*0.5f; - x = (sint64)(newPos.x*1000.0); - y = (sint64)(newPos.y*1000.0); - z = (sint64)(newPos.z*1000.0); - IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSX), x); - IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSY), y); - IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSZ), z); - entPtr->updateVisualProperty(NetMngr.getCurrentServerTick(), CLFECOMMON::PROPERTY_POSITION); + if(entPtr->skeleton()->getLastClippedState()) + { + NLMISC::CMatrix mat = entPtr->skeleton()->getLastWorldMatrixComputed(); + NLMISC::CVectorD newPos = entPtr->pos() + mat.getJ()*0.5f; + x = (sint64)(newPos.x*1000.0); + y = (sint64)(newPos.y*1000.0); + z = (sint64)(newPos.z*1000.0); + IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSX), x); + IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSY), y); + IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSZ), z); + entPtr->updateVisualProperty(NetMngr.getCurrentServerTick(), CLFECOMMON::PROPERTY_POSITION); - x = (sint64)(entPtr->pos().x*1000.0); - y = (sint64)(entPtr->pos().y*1000.0); - z = (sint64)(entPtr->pos().z*1000.0); - IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSX), x); - IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSY), y); - IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSZ), z); - entPtr->updateVisualProperty(NetMngr.getCurrentServerTick()+5, CLFECOMMON::PROPERTY_POSITION); - } - } + x = (sint64)(entPtr->pos().x*1000.0); + y = (sint64)(entPtr->pos().y*1000.0); + z = (sint64)(entPtr->pos().z*1000.0); + IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSX), x); + IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSY), y); + IngameDbMngr.setProp("Entities:E" + toString("%d", entSlot) + ":P" + toString("%d", CLFECOMMON::PROPERTY_POSZ), z); + entPtr->updateVisualProperty(NetMngr.getCurrentServerTick()+5, CLFECOMMON::PROPERTY_POSITION); + } } - return true; + } + return true; } @@ -3755,57 +3768,57 @@ NLMISC_COMMAND(test, "", "") /// commandName : Name of the command. /// variableName : Variable Name to change. //----------------------------------------------- -#define DIST_TO_COMMAND(commandName, variableName) \ - /* Check Parameters */ \ - if(args.size() != 2) \ - { \ - nlwarning("Command '" #commandName "': need 2 parameters, try '/help " #commandName "' for more details."); \ - return false; \ - } \ - \ - /* Try to create the sheet with the parameter as a string. */ \ - CSheetId sheetId; \ - if(!sheetId.buildSheetId(args[0])) \ - { \ - /* Try to create the sheet with the parameter as an int. */ \ - uint32 nSheetId; \ - fromString(args[0], nSheetId); \ - sheetId = CSheetId(nSheetId); \ - if(sheetId == CSheetId::Unknown) \ - { \ - nlwarning("Command '" #commandName "': '%s' is not a valid form.", args[0].c_str()); \ - return false; \ - } \ - } \ - \ - /* Get the new distance. */ \ - float dist; \ - fromString(args[1], dist); \ - if(dist < 0) \ - { \ - nlwarning("Command '" #commandName "': distance < 0, this is not good."); \ - return false; \ - } \ - \ - CCharacterSheet *ch = dynamic_cast(SheetMngr.get(sheetId)); \ - if(ch == 0) \ - { \ - nlwarning("Command '" #commandName "': cannot find the character for the given sheet."); \ - return false; \ - } \ - \ - /* Set the new distance for this sheet. */ \ - ch->variableName = dist; \ - \ - /* Well Done */ \ - return true; \ +#define DIST_TO_COMMAND(commandName, variableName) \ + /* Check Parameters */ \ + if(args.size() != 2) \ + { \ + nlwarning("Command '" #commandName "': need 2 parameters, try '/help " #commandName "' for more details."); \ + return false; \ + } \ + \ + /* Try to create the sheet with the parameter as a string. */ \ + CSheetId sheetId; \ + if(!sheetId.buildSheetId(args[0])) \ + { \ + /* Try to create the sheet with the parameter as an int. */ \ + uint32 nSheetId; \ + fromString(args[0], nSheetId); \ + sheetId = CSheetId(nSheetId); \ + if(sheetId == CSheetId::Unknown) \ + { \ + nlwarning("Command '" #commandName "': '%s' is not a valid form.", args[0].c_str()); \ + return false; \ + } \ + } \ + \ + /* Get the new distance. */ \ + float dist; \ + fromString(args[1], dist); \ + if(dist < 0) \ + { \ + nlwarning("Command '" #commandName "': distance < 0, this is not good."); \ + return false; \ + } \ + \ + CCharacterSheet *ch = dynamic_cast(SheetMngr.get(sheetId)); \ + if(ch == 0) \ + { \ + nlwarning("Command '" #commandName "': cannot find the character for the given sheet."); \ + return false; \ + } \ + \ + /* Set the new distance for this sheet. */ \ + ch->variableName = dist; \ + \ + /* Well Done */ \ + return true; \ //----------------------------------------------- // 'dist2front' : Change the distance to the front for a given sheet. //----------------------------------------------- NLMISC_COMMAND(dist2front, "Change the distance to the front for a given sheet.", " ") { - DIST_TO_COMMAND(dist2front, DistToFront); +DIST_TO_COMMAND(dist2front, DistToFront); } //----------------------------------------------- @@ -3813,7 +3826,7 @@ NLMISC_COMMAND(dist2front, "Change the distance to the front for a given sheet." //----------------------------------------------- NLMISC_COMMAND(dist2back, "Change the distance to the back for a given sheet.", " ") { - DIST_TO_COMMAND(dist2back, DistToBack); +DIST_TO_COMMAND(dist2back, DistToBack); } //----------------------------------------------- @@ -3821,7 +3834,7 @@ NLMISC_COMMAND(dist2back, "Change the distance to the back for a given sheet.", //----------------------------------------------- NLMISC_COMMAND(dist2side, "Change the distance to the side for a given sheet.", " ") { - DIST_TO_COMMAND(dist2side, DistToSide); +DIST_TO_COMMAND(dist2side, DistToSide); } @@ -3829,660 +3842,660 @@ NLMISC_COMMAND(dist2side, "Change the distance to the side for a given sheet.", // Change the parent of an entity. 'parent slot' not defined remove the current parent. NLMISC_COMMAND(parent, "Change the parent of an entity.", " []") { - CLFECOMMON::TCLEntityId parentSlot = CLFECOMMON::INVALID_SLOT; +CLFECOMMON::TCLEntityId parentSlot = CLFECOMMON::INVALID_SLOT; - // Check parameters. - switch(args.size()) - { - // Set the target for the entity. - case 2: - fromString(args[1], parentSlot); +// Check parameters. +switch(args.size()) + { +// Set the target for the entity. + case 2: +fromString(args[1], parentSlot); - // Remove the target for the entity. - case 1: - { - uint entitySlot; - fromString(args[0], entitySlot); - CEntityCL *entity = EntitiesMngr.entity(entitySlot); - if(entity) - { - entity->parent(parentSlot); - entity->pos(CVectorD::Null); - } - else - nlwarning("command 'parent': there is no entity in the slot %d", entitySlot); - } - break; +// Remove the target for the entity. + case 1: + { +uint entitySlot; +fromString(args[0], entitySlot); +CEntityCL *entity = EntitiesMngr.entity(entitySlot); +if(entity) + { +entity->parent(parentSlot); +entity->pos(CVectorD::Null); +} + else + nlwarning("command 'parent': there is no entity in the slot %d", entitySlot); +} +break; - // Bad command. - default: - return false; - } +// Bad command. + default: +return false; +} - // Well done. - return true; +// Well done. +return true; } NLMISC_COMMAND(displayInventoryCounter, "display the Inventory counter to compare with db counter", "") { - CInterfaceManager *pIM= CInterfaceManager::getInstance(); +CInterfaceManager *pIM= CInterfaceManager::getInstance(); - uint srvVal= NLGUI::CDBManager::getInstance()->getDbProp("SERVER:INVENTORY:COUNTER")->getValue32(); - uint locVal= pIM->getLocalSyncActionCounter() ; - srvVal&= pIM->getLocalSyncActionCounterMask(); - locVal&= pIM->getLocalSyncActionCounterMask(); +uint srvVal= NLGUI::CDBManager::getInstance()->getDbProp("SERVER:INVENTORY:COUNTER")->getValue32(); +uint locVal= pIM->getLocalSyncActionCounter() ; +srvVal&= pIM->getLocalSyncActionCounterMask(); +locVal&= pIM->getLocalSyncActionCounterMask(); - pIM->displaySystemInfo(ucstring( "ServerCounter: " + toString(srvVal) + "/ LocalCounter: " + toString(locVal)) ); +pIM->displaySystemInfo(ucstring( "ServerCounter: " + toString(srvVal) + "/ LocalCounter: " + toString(locVal)) ); - // Well done. - return true; +// Well done. +return true; } NLMISC_COMMAND(displayActionCounter, "display the action counters", "") { - CInterfaceManager *pIM= CInterfaceManager::getInstance(); - CSPhraseManager *pPM= CSPhraseManager::getInstance(); +CInterfaceManager *pIM= CInterfaceManager::getInstance(); +CSPhraseManager *pPM= CSPhraseManager::getInstance(); - // next - uint srvVal= NLGUI::CDBManager::getInstance()->getDbProp(PHRASE_DB_COUNTER_NEXT)->getValue32(); - uint locVal= pPM->getPhraseNextExecuteCounter() ; - srvVal&= PHRASE_EXECUTE_COUNTER_MASK; - locVal&= PHRASE_EXECUTE_COUNTER_MASK; +// next +uint srvVal= NLGUI::CDBManager::getInstance()->getDbProp(PHRASE_DB_COUNTER_NEXT)->getValue32(); +uint locVal= pPM->getPhraseNextExecuteCounter() ; +srvVal&= PHRASE_EXECUTE_COUNTER_MASK; +locVal&= PHRASE_EXECUTE_COUNTER_MASK; - pIM->displaySystemInfo(ucstring( "NextCounter: " + toString(srvVal) + "/ LocalCounter: " + toString(locVal)) ); +pIM->displaySystemInfo(ucstring( "NextCounter: " + toString(srvVal) + "/ LocalCounter: " + toString(locVal)) ); - // cycle - srvVal= NLGUI::CDBManager::getInstance()->getDbProp(PHRASE_DB_COUNTER_CYCLE)->getValue32(); - locVal= pPM->getPhraseCycleExecuteCounter() ; - srvVal&= PHRASE_EXECUTE_COUNTER_MASK; - locVal&= PHRASE_EXECUTE_COUNTER_MASK; +// cycle +srvVal= NLGUI::CDBManager::getInstance()->getDbProp(PHRASE_DB_COUNTER_CYCLE)->getValue32(); +locVal= pPM->getPhraseCycleExecuteCounter() ; +srvVal&= PHRASE_EXECUTE_COUNTER_MASK; +locVal&= PHRASE_EXECUTE_COUNTER_MASK; - pIM->displaySystemInfo(ucstring( "CycleCounter: " + toString(srvVal) + "/ LocalCounter: " + toString(locVal)) ); +pIM->displaySystemInfo(ucstring( "CycleCounter: " + toString(srvVal) + "/ LocalCounter: " + toString(locVal)) ); - return true; +return true; } NLMISC_COMMAND (url, "launch a browser to the specified url", "") { - if (args.size () != 1) - return false; + if (args.size () != 1) + return false; - return openURL(args[0].c_str()); + return openURL(args[0].c_str()); } NLMISC_COMMAND( reconnect, "Reconnect to the same shard (self Far TP)", "") { - // If the server is up, the egs will begin the quit sequence (shortened only if we are in edition or animation mode). - // If the server is down or frozen, a second /reconnect will be necessary to make the client reconnect - // but if you reconnect before letting the EGS save the character file, the previous saved file will be loaded. - switch ( LoginSM.getCurrentState() ) - { - case CLoginStateMachine::st_ingame: - LoginSM.pushEvent( CLoginStateMachine::ev_connect ); - break; - case CLoginStateMachine::st_leave_shard: - FarTP.onServerQuitOk(); - break; - default: - log.displayNL( "Can't reconnect from LoginSM state %u", (uint)LoginSM.getCurrentState() ); - } + // If the server is up, the egs will begin the quit sequence (shortened only if we are in edition or animation mode). + // If the server is down or frozen, a second /reconnect will be necessary to make the client reconnect + // but if you reconnect before letting the EGS save the character file, the previous saved file will be loaded. + switch ( LoginSM.getCurrentState() ) + { + case CLoginStateMachine::st_ingame: + LoginSM.pushEvent( CLoginStateMachine::ev_connect ); + break; + case CLoginStateMachine::st_leave_shard: + FarTP.onServerQuitOk(); + break; + default: + log.displayNL( "Can't reconnect from LoginSM state %u", (uint)LoginSM.getCurrentState() ); + } - return true; + return true; } struct CItemSheetSort { - const CItemSheet *IS; - CSheetId ID; - ITEMFAMILY::EItemFamily Family; + const CItemSheet *IS; + CSheetId ID; + ITEMFAMILY::EItemFamily Family; }; static inline bool operator < (const CItemSheetSort &lhs, const CItemSheetSort &rhs) { - return lhs.Family < rhs.Family; + return lhs.Family < rhs.Family; } NLMISC_COMMAND(dumpItems, "Sort items by category & display their sheet ids", "") { - std::vector isVect; - const CSheetManager::TEntitySheetMap &sheets = SheetMngr.getSheets(); - for(CSheetManager::TEntitySheetMap::const_iterator it = sheets.begin(); it != sheets.end(); ++it) + std::vector isVect; + const CSheetManager::TEntitySheetMap &sheets = SheetMngr.getSheets(); + for(CSheetManager::TEntitySheetMap::const_iterator it = sheets.begin(); it != sheets.end(); ++it) + { + const CEntitySheet *es = it->second.EntitySheet; + if (es && es->type() == CEntitySheet::ITEM) { - const CEntitySheet *es = it->second.EntitySheet; - if (es && es->type() == CEntitySheet::ITEM) - { - CItemSheetSort iss; - iss.IS = static_cast(es); - iss.ID = it->first; - iss.Family = iss.IS->Family; - isVect.push_back(iss); - } + CItemSheetSort iss; + iss.IS = static_cast(es); + iss.ID = it->first; + iss.Family = iss.IS->Family; + isVect.push_back(iss); } - // - // sort items - std::sort(isVect.begin(), isVect.end()); - // - for(std::vector::iterator itemIt = isVect.begin(); itemIt != isVect.end(); ++itemIt) - { - std::string info; - info = "FAMILY: "; - info += ITEMFAMILY::toString(itemIt->Family); - info += "; Name = "; - info += itemIt->IS->Id.toString(); - info += "; Sheet ID = "; - info += toString(itemIt->ID.asInt()); - nlwarning(info.c_str()); - } - return true; + } + // + // sort items + std::sort(isVect.begin(), isVect.end()); + // + for(std::vector::iterator itemIt = isVect.begin(); itemIt != isVect.end(); ++itemIt) + { + std::string info; + info = "FAMILY: "; + info += ITEMFAMILY::toString(itemIt->Family); + info += "; Name = "; + info += itemIt->IS->Id.toString(); + info += "; Sheet ID = "; + info += toString(itemIt->ID.asInt()); + nlwarning(info.c_str()); + } + return true; } NLMISC_COMMAND(dumpVisualSlots, "dump the visual slots", "") { - if (!args.empty()) return false; - SheetMngr.dumpVisualSlots(); - SheetMngr.dumpVisualSlotsIndex(); - return true; + if (!args.empty()) return false; + SheetMngr.dumpVisualSlots(); + SheetMngr.dumpVisualSlotsIndex(); + return true; } NLMISC_COMMAND(skillToInt, "Convert a skill to an int", "") { - if (args.size() != 1) return false; - CInterfaceManager *im = CInterfaceManager::getInstance(); - im->displaySystemInfo(ucstring(toString((uint) SKILLS::toSkill(args[0])))); - return true; + if (args.size() != 1) return false; + CInterfaceManager *im = CInterfaceManager::getInstance(); + im->displaySystemInfo(ucstring(toString((uint) SKILLS::toSkill(args[0])))); + return true; } NLMISC_COMMAND(browse, "Browse a HTML document with the internal help web browser.", "") { - if (args.size() != 1) return false; - CInterfaceManager *im = CInterfaceManager::getInstance(); - CAHManager::getInstance()->runActionHandler("browse", NULL, "name=ui:interface:help_browser:content:html|url="+args[0]); - return true; + if (args.size() != 1) return false; + CInterfaceManager *im = CInterfaceManager::getInstance(); + CAHManager::getInstance()->runActionHandler("browse", NULL, "name=ui:interface:help_browser:content:html|url="+args[0]); + return true; } NLMISC_COMMAND(openRingWindow, "Browse the main page in the ring web browser.", "") { - CInterfaceManager *im = CInterfaceManager::getInstance(); - CAHManager::getInstance()->runActionHandler("browse", NULL, "name=ui:interface:r2ed_web_admin:content:admin_web_page|url="+RingMainURL); - return true; + CInterfaceManager *im = CInterfaceManager::getInstance(); + CAHManager::getInstance()->runActionHandler("browse", NULL, "name=ui:interface:r2ed_web_admin:content:admin_web_page|url="+RingMainURL); + return true; } NLMISC_COMMAND(browseRingAdmin, "Browse a HTML document with the ring web browser.", "") { - if (args.size() != 1) return false; - CInterfaceManager *im = CInterfaceManager::getInstance(); - CAHManager::getInstance()->runActionHandler("browse", NULL, "name=ui:interface:r2ed_web_admin:content:admin_web_page|url="+args[0]); - return true; + if (args.size() != 1) return false; + CInterfaceManager *im = CInterfaceManager::getInstance(); + CAHManager::getInstance()->runActionHandler("browse", NULL, "name=ui:interface:r2ed_web_admin:content:admin_web_page|url="+args[0]); + return true; } NLMISC_COMMAND(GUCreate, "create a guild", "") { - if (args.size() != 1) return false; - const string msgName = "GUILD:CREATE"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - string buf = args[0]; - out.serial( buf ); - NetMngr.push(out); - } - return true; + if (args.size() != 1) return false; + const string msgName = "GUILD:CREATE"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + string buf = args[0]; + out.serial( buf ); + NetMngr.push(out); + } + return true; } NLMISC_COMMAND(GUQuit, "quit a guild", "") { - if (args.size() != 0) return false; - const string msgName = "GUILD:QUIT"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - NetMngr.push(out); - } - return true; + if (args.size() != 0) return false; + const string msgName = "GUILD:QUIT"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + NetMngr.push(out); + } + return true; } NLMISC_COMMAND(GULeaveLeadership, "abandon leadership of a guild", "") { - if (args.size() != 0) return false; - const string msgName = "GUILD:ABANDON_LEADERSHIP"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - NetMngr.push(out); - } - return true; + if (args.size() != 0) return false; + const string msgName = "GUILD:ABANDON_LEADERSHIP"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + NetMngr.push(out); + } + return true; } NLMISC_COMMAND(GULeaveOfficerTitle, "abandon officer title", "") { - if (args.size() != 0) return false; - const string msgName = "GUILD:ABANDON_OFFICER_TITLE"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - NetMngr.push(out); - } - return true; + if (args.size() != 0) return false; + const string msgName = "GUILD:ABANDON_OFFICER_TITLE"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + NetMngr.push(out); + } + return true; } NLMISC_COMMAND(GUNameOfficer, "name an officer", "") { - if (args.size() != 1) return false; - const string msgName = "GUILD:NAME_OFFICER"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - string buf = args[0]; - out.serial( buf ); - NetMngr.push(out); - } - return true; + if (args.size() != 1) return false; + const string msgName = "GUILD:NAME_OFFICER"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + string buf = args[0]; + out.serial( buf ); + NetMngr.push(out); + } + return true; } NLMISC_COMMAND(GUDismissOfficer, "dismiss an officer", "") { - if (args.size() != 1) return false; - const string msgName = "GUILD:DISMISS_OFFICER"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - string buf = args[0]; - out.serial( buf ); - NetMngr.push(out); - } - return true; + if (args.size() != 1) return false; + const string msgName = "GUILD:DISMISS_OFFICER"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + string buf = args[0]; + out.serial( buf ); + NetMngr.push(out); + } + return true; } NLMISC_COMMAND(GUKick, "kick a member", "") { - if (args.size() != 1) return false; - const string msgName = "GUILD:KICK_MEMBER"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - string buf = args[0]; - out.serial( buf ); - NetMngr.push(out); - } - return true; + if (args.size() != 1) return false; + const string msgName = "GUILD:KICK_MEMBER"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + string buf = args[0]; + out.serial( buf ); + NetMngr.push(out); + } + return true; } NLMISC_COMMAND(GUAccept, "accept an invitation", "") { - CAHManager::getInstance()->runActionHandler("accept_guild_invitation",NULL); - return true; + CAHManager::getInstance()->runActionHandler("accept_guild_invitation",NULL); + return true; } NLMISC_COMMAND(GURefuse, "refuse an invitation", "") { - CAHManager::getInstance()->runActionHandler("refuse_guild_invitation",NULL); - return true; + CAHManager::getInstance()->runActionHandler("refuse_guild_invitation",NULL); + return true; } NLMISC_COMMAND(GUFriend, "invite a player to become a friend of the guild", "") { - if (args.size() != 1) return false; - const string msgName = "GUILD:FRIEND_INVITATION"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - string buf = args[0]; - out.serial( buf ); - NetMngr.push(out); - } - return true; + if (args.size() != 1) return false; + const string msgName = "GUILD:FRIEND_INVITATION"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + string buf = args[0]; + out.serial( buf ); + NetMngr.push(out); + } + return true; } NLMISC_COMMAND(GUFriendAccept, "accept to be a friend of a guild that invited you", "") { - if (args.size() != 0) return false; - const string msgName = "GUILD:ACCEPT_FRIEND_INVITATION"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - NetMngr.push(out); - } - return true; + if (args.size() != 0) return false; + const string msgName = "GUILD:ACCEPT_FRIEND_INVITATION"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + NetMngr.push(out); + } + return true; } NLMISC_COMMAND(GUFriendRefuse, "refuse to be a friend of a guild that invited you", "") { - if (args.size() != 0) return false; - const string msgName = "GUILD:REFUSE_FRIEND_INVITATION"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - NetMngr.push(out); - } - return true; + if (args.size() != 0) return false; + const string msgName = "GUILD:REFUSE_FRIEND_INVITATION"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + NetMngr.push(out); + } + return true; } NLMISC_COMMAND(GUSetSuccessor, "set the successor of the guild leader", "") { - if (args.size() != 1) return false; - const string msgName = "GUILD:SET_SUCCESSOR"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - string buf = args[0]; - out.serial( buf ); - NetMngr.push(out); - } - return true; + if (args.size() != 1) return false; + const string msgName = "GUILD:SET_SUCCESSOR"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + string buf = args[0]; + out.serial( buf ); + NetMngr.push(out); + } + return true; } NLMISC_COMMAND(GUInfos, "get information on a guild", "") { - if (args.size() != 1) return false; - const string msgName = "GUILD:GET_INFOS"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - string buf = args[0]; - out.serial( buf ); - NetMngr.push(out); - } - return true; + if (args.size() != 1) return false; + const string msgName = "GUILD:GET_INFOS"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + string buf = args[0]; + out.serial( buf ); + NetMngr.push(out); + } + return true; } NLMISC_COMMAND(GUJournal, "get the guild journal", "") { - if (args.size() != 0) return false; - const string msgName = "GUILD:GET_LOG"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - NetMngr.push(out); - } - return true; + if (args.size() != 0) return false; + const string msgName = "GUILD:GET_LOG"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + NetMngr.push(out); + } + return true; } NLMISC_COMMAND(buildingTeleport, "teleport to a building", "building index") { - if (args.size() != 1) return false; - uint16 index; - fromString(args[0], index); - const string msgName = "GUILD:TELEPORT"; - CBitMemStream out; - if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) - { - out.serial(index); - NetMngr.push(out); - } - return true; + if (args.size() != 1) return false; + uint16 index; + fromString(args[0], index); + const string msgName = "GUILD:TELEPORT"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + out.serial(index); + NetMngr.push(out); + } + return true; } NLMISC_COMMAND(logFaberMpCompatibles, "log all MP compatibles for faber the item", "sheetid") { - if (args.size() != 1) return false; - uint32 sheetId; - fromString(args[0], sheetId); - CSBrickManager *pBM= CSBrickManager::getInstance(); + if (args.size() != 1) return false; + uint32 sheetId; + fromString(args[0], sheetId); + CSBrickManager *pBM= CSBrickManager::getInstance(); - // get the faber plan - CSBrickSheet *brick= pBM->getBrick(CSheetId(sheetId)); - // get the origin of the item built - CItemSheet *itemBuilt= NULL; - if(brick) - itemBuilt= dynamic_cast(SheetMngr.get(brick->FaberPlan.ItemBuilt)); - if(brick && itemBuilt) + // get the faber plan + CSBrickSheet *brick= pBM->getBrick(CSheetId(sheetId)); + // get the origin of the item built + CItemSheet *itemBuilt= NULL; + if(brick) + itemBuilt= dynamic_cast(SheetMngr.get(brick->FaberPlan.ItemBuilt)); + if(brick && itemBuilt) + { + + // build array of MP sheetId + std::vector mps; + mps.reserve(100); + const CSheetManager::TEntitySheetMap &sheetMap= SheetMngr.getSheets(); + CSheetManager::TEntitySheetMap::const_iterator it; + for(it= sheetMap.begin(); it!=sheetMap.end(); it++) { - - // build array of MP sheetId - std::vector mps; - mps.reserve(100); - const CSheetManager::TEntitySheetMap &sheetMap= SheetMngr.getSheets(); - CSheetManager::TEntitySheetMap::const_iterator it; - for(it= sheetMap.begin(); it!=sheetMap.end(); it++) - { - CItemSheet *mp= const_cast( dynamic_cast(it->second.EntitySheet) ); - if(mp && mp->Family == ITEMFAMILY::RAW_MATERIAL) - mps.push_back(mp); - } - - // header - uint numMpSlots= (uint)brick->FaberPlan.ItemPartMps.size(); - nlinfo("********** FABERLOG **********"); - nlinfo(" ItemBuilt Origin: %s", ITEM_ORIGIN::enumToString(itemBuilt->ItemOrigin).c_str() ); - nlinfo(" NumMPSlot: %d", numMpSlots); - - // Parse All Slots. - for(uint i=0;iFaberPlan.ItemPartMps[i]; - nlinfo(" MPSlot %d", i); - nlinfo(" Quantity: %d", mpSlot.Quantity); - nlinfo(" TypeReq: %s", RM_FABER_TYPE::toString(mpSlot.FaberTypeFilter).c_str() ); - nlinfo(" List Of Compatibles MPs:"); - - for(uint i=0;icanBuildItemPart(mpSlot.FaberTypeFilter, itemBuilt->ItemOrigin)) - ok= false; - - if(ok) - { - nlinfo(" %s", itemSheet->Id.toString().c_str() ); - } - } - - } + CItemSheet *mp= const_cast( dynamic_cast(it->second.EntitySheet) ); + if(mp && mp->Family == ITEMFAMILY::RAW_MATERIAL) + mps.push_back(mp); } - return true; + // header + uint numMpSlots= (uint)brick->FaberPlan.ItemPartMps.size(); + nlinfo("********** FABERLOG **********"); + nlinfo(" ItemBuilt Origin: %s", ITEM_ORIGIN::enumToString(itemBuilt->ItemOrigin).c_str() ); + nlinfo(" NumMPSlot: %d", numMpSlots); + + // Parse All Slots. + for(uint i=0;iFaberPlan.ItemPartMps[i]; + nlinfo(" MPSlot %d", i); + nlinfo(" Quantity: %d", mpSlot.Quantity); + nlinfo(" TypeReq: %s", RM_FABER_TYPE::toString(mpSlot.FaberTypeFilter).c_str() ); + nlinfo(" List Of Compatibles MPs:"); + + for(uint i=0;icanBuildItemPart(mpSlot.FaberTypeFilter, itemBuilt->ItemOrigin)) + ok= false; + + if(ok) + { + nlinfo(" %s", itemSheet->Id.toString().c_str() ); + } + } + + } + } + + return true; } NLMISC_COMMAND(debugItemInfo, "simulate a ItemInfo received from server", "itemSlotId version [enchant]") { - CItemInfos itemInfo; + CItemInfos itemInfo; - if (args.size() < 2 || args.size() > 3) return false; - bool enchant= false; - if(args.size()==3) - fromString(args[2], enchant); + if (args.size() < 2 || args.size() > 3) return false; + bool enchant= false; + if(args.size()==3) + fromString(args[2], enchant); - fromString(args[0], itemInfo.slotId); - fromString(args[1], itemInfo.versionInfo); + fromString(args[0], itemInfo.slotId); + fromString(args[1], itemInfo.versionInfo); - itemInfo.CurrentDamage= 10; - itemInfo.MaxDamage= 15; - itemInfo.DodgeModifier= 5; - itemInfo.ParryModifier= -10; - itemInfo.AdversaryDodgeModifier= 666; - itemInfo.AdversaryParryModifier= 333; - itemInfo.HpBuff= 12; - itemInfo.SapBuff= -14; - itemInfo.StaBuff= 0; - itemInfo.FocusBuff= 1; - itemInfo.MagicProtection[0]= PROTECTION_TYPE::Electricity; - itemInfo.MagicProtectionFactor[0]= 43; - itemInfo.MagicProtection[1]= PROTECTION_TYPE::Shockwave; - itemInfo.MagicProtectionFactor[1]= 21; - itemInfo.MagicProtection[2]= PROTECTION_TYPE::Rot; - itemInfo.MagicProtectionFactor[2]= 100; - itemInfo.DesertMagicResistance= 133; - itemInfo.ForestMagicResistance= 500; - itemInfo.PrimaryRootMagicResistance= 341; - itemInfo.Hp= 66; - itemInfo.HpMax= 100; - itemInfo.Range= 169; - itemInfo.SapLoadCurrent= 6; - itemInfo.SapLoadMax= 30; - itemInfo.HitRate= 8; - itemInfo.ProtectionFactor= 0.25; - itemInfo.MaxSlashingProtection= 38; - itemInfo.MaxPiercingProtection= 48; - itemInfo.MaxBluntProtection= 58; - itemInfo.WearEquipmentMalus= 0.31f; + itemInfo.CurrentDamage= 10; + itemInfo.MaxDamage= 15; + itemInfo.DodgeModifier= 5; + itemInfo.ParryModifier= -10; + itemInfo.AdversaryDodgeModifier= 666; + itemInfo.AdversaryParryModifier= 333; + itemInfo.HpBuff= 12; + itemInfo.SapBuff= -14; + itemInfo.StaBuff= 0; + itemInfo.FocusBuff= 1; + itemInfo.MagicProtection[0]= PROTECTION_TYPE::Electricity; + itemInfo.MagicProtectionFactor[0]= 43; + itemInfo.MagicProtection[1]= PROTECTION_TYPE::Shockwave; + itemInfo.MagicProtectionFactor[1]= 21; + itemInfo.MagicProtection[2]= PROTECTION_TYPE::Rot; + itemInfo.MagicProtectionFactor[2]= 100; + itemInfo.DesertMagicResistance= 133; + itemInfo.ForestMagicResistance= 500; + itemInfo.PrimaryRootMagicResistance= 341; + itemInfo.Hp= 66; + itemInfo.HpMax= 100; + itemInfo.Range= 169; + itemInfo.SapLoadCurrent= 6; + itemInfo.SapLoadMax= 30; + itemInfo.HitRate= 8; + itemInfo.ProtectionFactor= 0.25; + itemInfo.MaxSlashingProtection= 38; + itemInfo.MaxPiercingProtection= 48; + itemInfo.MaxBluntProtection= 58; + itemInfo.WearEquipmentMalus= 0.31f; - if(enchant) - { - itemInfo.Enchantment.Name="pipoSort"; - itemInfo.Enchantment.Bricks.resize(3); - itemInfo.Enchantment.Bricks[0]= CSheetId("bmpa01.sbrick"); - itemInfo.Enchantment.Bricks[1]= CSheetId("bmlchea01.sbrick"); - itemInfo.Enchantment.Bricks[2]= CSheetId("bmlchmh00005.sbrick"); - } + if(enchant) + { + itemInfo.Enchantment.Name="pipoSort"; + itemInfo.Enchantment.Bricks.resize(3); + itemInfo.Enchantment.Bricks[0]= CSheetId("bmpa01.sbrick"); + itemInfo.Enchantment.Bricks[1]= CSheetId("bmlchea01.sbrick"); + itemInfo.Enchantment.Bricks[2]= CSheetId("bmlchmh00005.sbrick"); + } - switch(rand()%4) - { - case 0: - break; - case 1: - { - itemInfo.CastingSpeedFactor[1]= 1.0f; - itemInfo.MagicPowerFactor[1]= 0.2f; - } - break; - case 2: - { - itemInfo.CastingSpeedFactor[0]= 0.4f; - itemInfo.MagicPowerFactor[0]= 0.2f; - itemInfo.CastingSpeedFactor[2]= 0.8f; - itemInfo.MagicPowerFactor[2]= 0.3f; - } - break; - case 3: - { - itemInfo.CastingSpeedFactor[0]= 0.3f; - itemInfo.MagicPowerFactor[0]= 0.3f; - itemInfo.CastingSpeedFactor[1]= 0.3f; - itemInfo.MagicPowerFactor[1]= 0.3f; - itemInfo.CastingSpeedFactor[2]= 0.3f; - itemInfo.MagicPowerFactor[2]= 0.3f; - itemInfo.CastingSpeedFactor[3]= 0.3f; - itemInfo.MagicPowerFactor[3]= 0.3f; - } - break; - }; + switch(rand()%4) + { + case 0: + break; + case 1: + { + itemInfo.CastingSpeedFactor[1]= 1.0f; + itemInfo.MagicPowerFactor[1]= 0.2f; + } + break; + case 2: + { + itemInfo.CastingSpeedFactor[0]= 0.4f; + itemInfo.MagicPowerFactor[0]= 0.2f; + itemInfo.CastingSpeedFactor[2]= 0.8f; + itemInfo.MagicPowerFactor[2]= 0.3f; + } + break; + case 3: + { + itemInfo.CastingSpeedFactor[0]= 0.3f; + itemInfo.MagicPowerFactor[0]= 0.3f; + itemInfo.CastingSpeedFactor[1]= 0.3f; + itemInfo.MagicPowerFactor[1]= 0.3f; + itemInfo.CastingSpeedFactor[2]= 0.3f; + itemInfo.MagicPowerFactor[2]= 0.3f; + itemInfo.CastingSpeedFactor[3]= 0.3f; + itemInfo.MagicPowerFactor[3]= 0.3f; + } + break; + }; - getInventory().onReceiveItemInfo(itemInfo); + getInventory().onReceiveItemInfo(itemInfo); - return true; + return true; } NLMISC_COMMAND(debugItemInfoWaiters, "log ItemInfoWaiters", "") { - getInventory().debugItemInfoWaiters(); + getInventory().debugItemInfoWaiters(); - return true; + return true; } NLMISC_COMMAND(debugInfoWindows, "log info windows sheetId", "") { - CInterfaceHelp::debugOpenedInfoWindows(); + CInterfaceHelp::debugOpenedInfoWindows(); - return true; + return true; } NLMISC_COMMAND(getSkillValue, "get a skill value by its name", "skill_name") { - if (args.size() != 1) return false; - CInterfaceManager *pIM= CInterfaceManager::getInstance(); - uint skillId= (uint) SKILLS::toSkill(args[0]); - CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:SKILL", skillId), false); - if(node) - { - pIM->displaySystemInfo(ucstring(toString(node->getValue32()))); - } + if (args.size() != 1) return false; + CInterfaceManager *pIM= CInterfaceManager::getInstance(); + uint skillId= (uint) SKILLS::toSkill(args[0]); + CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:SKILL", skillId), false); + if(node) + { + pIM->displaySystemInfo(ucstring(toString(node->getValue32()))); + } - return true; + return true; } NLMISC_COMMAND(setSkillValue, "set a skill value by its name", "skill_name value") { - if (args.size() != 2) return false; - CInterfaceManager *pIM= CInterfaceManager::getInstance(); - uint skillId= (uint) SKILLS::toSkill(args[0]); - CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:SKILL", skillId), false); - if(node) - { - sint32 value; - fromString(args[1], value); - node->setValue32(value); - } + if (args.size() != 2) return false; + CInterfaceManager *pIM= CInterfaceManager::getInstance(); + uint skillId= (uint) SKILLS::toSkill(args[0]); + CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:SKILL", skillId), false); + if(node) + { + sint32 value; + fromString(args[1], value); + node->setValue32(value); + } - return true; + return true; } NLMISC_COMMAND(getBaseSkillValue, "get a baseskill value by its name", "skill_name") { - if (args.size() != 1) return false; - CInterfaceManager *pIM= CInterfaceManager::getInstance(); - uint skillId= (uint) SKILLS::toSkill(args[0]); - CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:BaseSKILL", skillId), false); - if(node) - { - pIM->displaySystemInfo(ucstring(toString(node->getValue32()))); - } + if (args.size() != 1) return false; + CInterfaceManager *pIM= CInterfaceManager::getInstance(); + uint skillId= (uint) SKILLS::toSkill(args[0]); + CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:BaseSKILL", skillId), false); + if(node) + { + pIM->displaySystemInfo(ucstring(toString(node->getValue32()))); + } - return true; + return true; } NLMISC_COMMAND(setBaseSkillValue, "set a baseskill value by its name", "skill_name value") { - if (args.size() != 2) return false; - CInterfaceManager *pIM= CInterfaceManager::getInstance(); - uint skillId= (uint) SKILLS::toSkill(args[0]); - CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:BaseSKILL", skillId), false); - if(node) - { - sint32 value; - fromString(args[1], value); - node->setValue32(value); - } + if (args.size() != 2) return false; + CInterfaceManager *pIM= CInterfaceManager::getInstance(); + uint skillId= (uint) SKILLS::toSkill(args[0]); + CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:BaseSKILL", skillId), false); + if(node) + { + sint32 value; + fromString(args[1], value); + node->setValue32(value); + } - return true; + return true; } NLMISC_COMMAND(setAllSkillValue, "set all Skill and baseskill to the given value", "value") { - if (args.size() != 1) return false; - CInterfaceManager *pIM= CInterfaceManager::getInstance(); - uint value; - fromString(args[0], value); - for(uint i=0;igetDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:BaseSKILL", i), false); - if(node) - node->setValue32(value); - node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:SKILL", i), false); - if(node) - node->setValue32(value); - } + if (args.size() != 1) return false; + CInterfaceManager *pIM= CInterfaceManager::getInstance(); + uint value; + fromString(args[0], value); + for(uint i=0;igetDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:BaseSKILL", i), false); + if(node) + node->setValue32(value); + node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:CHARACTER_INFO:SKILLS:%d:SKILL", i), false); + if(node) + node->setValue32(value); + } - return true; + return true; } NLMISC_COMMAND(setEntityName, "set a entity name id", "entitySlot nameId") { - if (args.size() != 2) return false; - uint slot; - fromString(args[0], slot); + if (args.size() != 2) return false; + uint slot; + fromString(args[0], slot); - CCharacterCL *entity= dynamic_cast(EntitiesMngr.entity(slot)); - if(entity) - { - uint32 nameId; - fromString(args[1], nameId); - entity->debugSetNameId(nameId); - } - return true; + CCharacterCL *entity= dynamic_cast(EntitiesMngr.entity(slot)); + if(entity) + { + uint32 nameId; + fromString(args[1], nameId); + entity->debugSetNameId(nameId); + } + return true; } NLMISC_COMMAND(reloadWeather, "reload the weather sheets", "") { - if (!args.empty()) return false; - ContinentMngr.reloadWeather(); - return true; + if (!args.empty()) return false; + ContinentMngr.reloadWeather(); + return true; } @@ -4490,54 +4503,54 @@ NLMISC_COMMAND(reloadWeather, "reload the weather sheets", "") template bool reloadSheets(string filter, string wildcardFilter) { - CSheetManager sheetManager; - std::vector filters; - filters.push_back(filter); - ClientSheetsStrings.memoryUncompress(); - NLMISC::IProgressCallback progress; - sheetManager.loadAllSheetNoPackedSheet(progress, filters, wildcardFilter); - ClientSheetsStrings.memoryCompress(); - // copy sheets into current sheet manager (because numerous ptr are kept on the previous sheets in various places) - const CSheetManager::TEntitySheetMap &sheetMap= sheetManager.getSheets(); - CSheetManager::TEntitySheetMap::const_iterator it; - for(it=sheetMap.begin();it!=sheetMap.end();it++) + CSheetManager sheetManager; + std::vector filters; + filters.push_back(filter); + ClientSheetsStrings.memoryUncompress(); + NLMISC::IProgressCallback progress; + sheetManager.loadAllSheetNoPackedSheet(progress, filters, wildcardFilter); + ClientSheetsStrings.memoryCompress(); + // copy sheets into current sheet manager (because numerous ptr are kept on the previous sheets in various places) + const CSheetManager::TEntitySheetMap &sheetMap= sheetManager.getSheets(); + CSheetManager::TEntitySheetMap::const_iterator it; + for(it=sheetMap.begin();it!=sheetMap.end();it++) + { + T *dest = dynamic_cast(SheetMngr.get(it->first)); + if (dest) { - T *dest = dynamic_cast(SheetMngr.get(it->first)); - if (dest) - { - const T *src = dynamic_cast(it->second.EntitySheet); - if (src) - { - *dest = *src; - } - } + const T *src = dynamic_cast(it->second.EntitySheet); + if (src) + { + *dest = *src; + } } - return true; + } + return true; } std::string extendWildcard(const std::string &in) { - string out; - // append * at begin if not present (or if enp - if(in.empty() || in[0]!='*') - out= '*'; - out+= in; - // append .* at end if no . found - if(in.find('.')==string::npos) - out+= ".*"; - return out; + string out; + // append * at begin if not present (or if enp + if(in.empty() || in[0]!='*') + out= '*'; + out+= in; + // append .* at end if no . found + if(in.find('.')==string::npos) + out+= ".*"; + return out; } // macros to reload Sheets #define CMD_RELOAD_SHEET(_cmd_name, _filter, _type) \ -NLMISC_COMMAND(_cmd_name, #_cmd_name, "") \ -{ \ - if (args.size()>1) return false; \ - string wildcardFilter; \ - if (args.size()>=1) \ - wildcardFilter= extendWildcard(args[0]); \ - return reloadSheets<_type>(_filter, wildcardFilter); \ -} + NLMISC_COMMAND(_cmd_name, #_cmd_name, "") \ + { \ + if (args.size()>1) return false; \ + string wildcardFilter; \ + if (args.size()>=1) \ + wildcardFilter= extendWildcard(args[0]); \ + return reloadSheets<_type>(_filter, wildcardFilter); \ + } // Important ones CMD_RELOAD_SHEET(reloadCreature, "creature", CCharacterSheet) CMD_RELOAD_SHEET(reloadSbrick, "sbrick", CSBrickSheet) @@ -4545,474 +4558,474 @@ CMD_RELOAD_SHEET(reloadSphrase, "sphrase", CSPhraseSheet) CMD_RELOAD_SHEET(reloadSitem, "sitem", CItemSheet) // Not tested ones /* -CMD_RELOAD_SHEET(reloadPlayer, "player", CPlayerSheet) -CMD_RELOAD_SHEET(reloadFx, "fx", CFXSheet) -CMD_RELOAD_SHEET(reloadBuilding, "building", CBuildingSheet) -CMD_RELOAD_SHEET(reloadDeath_impact, "death_impact", CPactSheet) -CMD_RELOAD_SHEET(reloadMission, "mission", CMissionSheet) -CMD_RELOAD_SHEET(reloadRace_stats, "race_stats", CRaceStatsSheet) -CMD_RELOAD_SHEET(reloadLight_cycle, "light_cycle", CLightCycleSheet) -CMD_RELOAD_SHEET(reloadContinent, "continent", CContinentSheet) -CMD_RELOAD_SHEET(reloadWorld, "world", CWorldSheet) -CMD_RELOAD_SHEET(reloadMission_icon, "mission_icon", CMissionIconSheet) -CMD_RELOAD_SHEET(reloadSkill_tree, "skill_tree", CSkillsTreeSheet) -CMD_RELOAD_SHEET(reloadTitles, "titles", CUnblockTitlesSheet) -CMD_RELOAD_SHEET(reloadSucces_chances_table, "succes_chances_table", CSuccessTableSheet) -CMD_RELOAD_SHEET(reloadAutomaton_list, "automaton_list", CAutomatonListSheet) -CMD_RELOAD_SHEET(reloadAnimset_list, "animset_list", CAnimationSetListSheet) -CMD_RELOAD_SHEET(reloadAnimation_fx, "animation_fx", CAnimationFXSheet) -CMD_RELOAD_SHEET(reloadEmot, "emot", CEmotListSheet) -CMD_RELOAD_SHEET(reloadForage_source, "forage_source", CForageSourceSheet) -CMD_RELOAD_SHEET(reloadText_emotes, "text_emotes", CTextEmotListSheet) + CMD_RELOAD_SHEET(reloadPlayer, "player", CPlayerSheet) + CMD_RELOAD_SHEET(reloadFx, "fx", CFXSheet) + CMD_RELOAD_SHEET(reloadBuilding, "building", CBuildingSheet) + CMD_RELOAD_SHEET(reloadDeath_impact, "death_impact", CPactSheet) + CMD_RELOAD_SHEET(reloadMission, "mission", CMissionSheet) + CMD_RELOAD_SHEET(reloadRace_stats, "race_stats", CRaceStatsSheet) + CMD_RELOAD_SHEET(reloadLight_cycle, "light_cycle", CLightCycleSheet) + CMD_RELOAD_SHEET(reloadContinent, "continent", CContinentSheet) + CMD_RELOAD_SHEET(reloadWorld, "world", CWorldSheet) + CMD_RELOAD_SHEET(reloadMission_icon, "mission_icon", CMissionIconSheet) + CMD_RELOAD_SHEET(reloadSkill_tree, "skill_tree", CSkillsTreeSheet) + CMD_RELOAD_SHEET(reloadTitles, "titles", CUnblockTitlesSheet) + CMD_RELOAD_SHEET(reloadSucces_chances_table, "succes_chances_table", CSuccessTableSheet) + CMD_RELOAD_SHEET(reloadAutomaton_list, "automaton_list", CAutomatonListSheet) + CMD_RELOAD_SHEET(reloadAnimset_list, "animset_list", CAnimationSetListSheet) + CMD_RELOAD_SHEET(reloadAnimation_fx, "animation_fx", CAnimationFXSheet) + CMD_RELOAD_SHEET(reloadEmot, "emot", CEmotListSheet) + CMD_RELOAD_SHEET(reloadForage_source, "forage_source", CForageSourceSheet) + CMD_RELOAD_SHEET(reloadText_emotes, "text_emotes", CTextEmotListSheet) */ 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]") { - if(args.size()!=2 && args.size()!=3) return false; - uint slot; - fromString(args[0], slot); - uint propId; - fromString(args[1], propId); + if(args.size()!=2 && args.size()!=3) return false; + uint slot; + fromString(args[0], slot); + uint propId; + fromString(args[1], propId); - // set value in the DB? - if(args.size()==3) - { - sint64 val= 0; - fromString(args[2], val); - CInterfaceManager *pIM= CInterfaceManager::getInstance(); - CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:Entities:E%d:P%d", slot, propId), false); - if(node) - node->setValue64(val); - } + // set value in the DB? + if(args.size()==3) + { + sint64 val= 0; + fromString(args[2], val); + CInterfaceManager *pIM= CInterfaceManager::getInstance(); + CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:Entities:E%d:P%d", slot, propId), false); + if(node) + node->setValue64(val); + } - EntitiesMngr.updateVisualProperty(0, slot, propId); + EntitiesMngr.updateVisualProperty(0, slot, propId); - return true; + return true; } NLMISC_COMMAND(dataSetId, "Set the UID of an entity", "slot uid") { - if(args.size()!=2) return false; - uint slot; - fromString(args[0], slot); - uint uid; - fromString(args[1], uid); + if(args.size()!=2) return false; + uint slot; + fromString(args[0], slot); + uint uid; + fromString(args[1], uid); - CEntityCL *entity= EntitiesMngr.entity(slot); - if(!entity) - return false; + CEntityCL *entity= EntitiesMngr.entity(slot); + if(!entity) + return false; - entity->dataSetId(uid); + entity->dataSetId(uid); - return true; + return true; } NLMISC_COMMAND(forceDisplayFXBBoxes, "Force to display bboxes of all fxs", "0=off, 1=off") { - if (args.size() != 1) return false; - bool on; - fromString(args[0], on); - UParticleSystemInstance::forceDisplayBBox(on); - return true; + if (args.size() != 1) return false; + bool on; + fromString(args[0], on); + UParticleSystemInstance::forceDisplayBBox(on); + return true; } NLMISC_COMMAND(dumpVillages, "Dump villages loading zones in a bitmap", "filename>") { - if (args.size() != 1) return false; - ContinentMngr.cur()->dumpVillagesLoadingZones(args[0]); - return true; + if (args.size() != 1) return false; + ContinentMngr.cur()->dumpVillagesLoadingZones(args[0]); + return true; } NLMISC_COMMAND(dumpFogDayMap, "Dump fog day map", "filename>") { - if (args.size() != 1) return false; - ContinentMngr.cur()->dumpFogMap(CFogMapBuild::Day, args[0]); - return true; + if (args.size() != 1) return false; + ContinentMngr.cur()->dumpFogMap(CFogMapBuild::Day, args[0]); + return true; } NLMISC_COMMAND(dumpFogDepthMap, "Dump fog depth map", "filename>") { - if (args.size() != 1) return false; - ContinentMngr.cur()->dumpFogMap(CFogMapBuild::Depth, args[0]); - return true; + if (args.size() != 1) return false; + ContinentMngr.cur()->dumpFogMap(CFogMapBuild::Depth, args[0]); + return true; } NLMISC_COMMAND(dumpFogDistMap, "Dump fog depth map", "filename>") { - if (args.size() != 1) return false; - ContinentMngr.cur()->dumpFogMap(CFogMapBuild::Distance, args[0]); - return true; + if (args.size() != 1) return false; + ContinentMngr.cur()->dumpFogMap(CFogMapBuild::Distance, args[0]); + return true; } NLMISC_COMMAND(dumpRainMap, "Dump fog rain map", "filename>") { - if (args.size() != 1) return false; - CRGBA colorLookup[256]; - for(uint8 k = 1; k < 255; ++k) - { - colorLookup[k] = CRGBA(k, k, k, 1); - } - colorLookup[0] = CRGBA::Red; - colorLookup[255] = CRGBA::Blue; - ContinentMngr.cur()->dumpFogMap(CFogMapBuild::NoPrecipitation, args[0], CContinent::ChannelR, colorLookup); - return true; + if (args.size() != 1) return false; + CRGBA colorLookup[256]; + for(uint8 k = 1; k < 255; ++k) + { + colorLookup[k] = CRGBA(k, k, k, 1); + } + colorLookup[0] = CRGBA::Red; + colorLookup[255] = CRGBA::Blue; + ContinentMngr.cur()->dumpFogMap(CFogMapBuild::NoPrecipitation, args[0], CContinent::ChannelR, colorLookup); + return true; } NLMISC_COMMAND(stick_log, "", "") { - if(args.size()!=1) - return false; - CLFECOMMON::TCLEntityId slot; - fromString(args[0], slot); + if(args.size()!=1) + return false; + CLFECOMMON::TCLEntityId slot; + fromString(args[0], slot); - // Compute the position. - CEntityCL *entity = EntitiesMngr.entity(slot); - if(!entity) - return false; + // Compute the position. + CEntityCL *entity = EntitiesMngr.entity(slot); + if(!entity) + return false; - USkeleton *skel= entity->skeleton(); - if(skel) + USkeleton *skel= entity->skeleton(); + if(skel) + { + CInterfaceManager *pIM= CInterfaceManager::getInstance(); + nlinfo("Skel Log: %s", skel->getShapeName().c_str()); + + std::vector sticks; + skel->getStickedObjects(sticks); + + nlinfo("StickedModels: %d", sticks.size()); + pIM->displaySystemInfo(ucstring(toString("StickedModels: %d", sticks.size()))); + + for(uint i=0;igetShapeName().c_str()); - - std::vector sticks; - skel->getStickedObjects(sticks); - - nlinfo("StickedModels: %d", sticks.size()); - pIM->displaySystemInfo(ucstring(toString("StickedModels: %d", sticks.size()))); - - for(uint i=0;idisplaySystemInfo(str); - } - else - { - string str= toString(" %d: %X. NOT a TransformShape", i, sticks[i].getObjectPtr()); - nlinfo(str.c_str()); - pIM->displaySystemInfo(str); - } - } + UInstance inst; + inst.cast(sticks[i]); + if(!inst.empty()) + { + string str= toString(" %d: %X. %s", i, inst.getObjectPtr(), inst.getShapeName().c_str()); + nlinfo(str.c_str()); + pIM->displaySystemInfo(str); + } + else + { + string str= toString(" %d: %X. NOT a TransformShape", i, sticks[i].getObjectPtr()); + nlinfo(str.c_str()); + pIM->displaySystemInfo(str); + } } + } - return true; + return true; } NLMISC_COMMAND(print_sys, "", " ") { - if(args.size()<1) - return false; - string cat= args[0]; - string str; - for (uint i = 1; i < args.size(); i++) - { - str += args[i] + " "; - } + if(args.size()<1) + return false; + string cat= args[0]; + string str; + for (uint i = 1; i < args.size(); i++) + { + str += args[i] + " "; + } - CInterfaceManager *pIM= CInterfaceManager::getInstance(); - pIM->displaySystemInfo(str, cat); + CInterfaceManager *pIM= CInterfaceManager::getInstance(); + pIM->displaySystemInfo(str, cat); - return true; + return true; } NLMISC_COMMAND(fillAllInfoVersion, "", "") { - if(args.size()!=1) - return false; + if(args.size()!=1) + return false; - uint i,j; - uint ver; - fromString(args[0], ver); - CInventoryManager &im= getInventory(); + uint i,j; + uint ver; + fromString(args[0], ver); + CInventoryManager &im= getInventory(); - // BAG - for(i=0;igetDbProp(toString("SERVER:EXCHANGE:GIVE:%d:INFO_VERSION", i), false); - if(node) - node->setValue32(ver); - node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:EXCHANGE:RECEIVE:%d:INFO_VERSION", i), false); - if(node) - node->setValue32(ver); - } + // EXCHANGE + CInterfaceManager *pIM= CInterfaceManager::getInstance(); + for(i=0;igetDbProp(toString("SERVER:EXCHANGE:GIVE:%d:INFO_VERSION", i), false); + if(node) + node->setValue32(ver); + node= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:EXCHANGE:RECEIVE:%d:INFO_VERSION", i), false); + if(node) + node->setValue32(ver); + } - return true; + return true; } NLMISC_COMMAND(fullFillInventory, "", "dbstring sheetName") { - if(args.size()!=2) - return false; + if(args.size()!=2) + return false; - // read value - sint64 value; - if (isalpha(args[1][0])) + // read value + sint64 value; + if (isalpha(args[1][0])) + { + CSheetId sheet(args[1]); + value = (sint64) sheet.asInt(); + } + else + { + // Convert the string into an sint64. + fromString(args[1], value); + } + + // read db dest + CInterfaceManager *pIM= CInterfaceManager::getInstance(); + CCDBNodeBranch *nb= NLGUI::CDBManager::getInstance()->getDbBranch(args[0]); + if(!nb) + return false; + + uint num= nb->getNbNodes(); + for(uint i=0;igetDbProp(args[0]+":"+toString(i)+":SHEET", false); + if(nl) { - CSheetId sheet(args[1]); - value = (sint64) sheet.asInt(); - } - else - { - // Convert the string into an sint64. - fromString(args[1], value); + nl->setValue64(value); + nl= NLGUI::CDBManager::getInstance()->getDbProp(args[0]+":"+toString(i)+":QUALITY", false); + if(nl) + nl->setValue64(i); + nl= NLGUI::CDBManager::getInstance()->getDbProp(args[0]+":"+toString(i)+":PREREQUISIT_VALID", false); + if(nl) + nl->setValue64(1); } + } - // read db dest - CInterfaceManager *pIM= CInterfaceManager::getInstance(); - CCDBNodeBranch *nb= NLGUI::CDBManager::getInstance()->getDbBranch(args[0]); - if(!nb) - return false; - - uint num= nb->getNbNodes(); - for(uint i=0;igetDbProp(args[0]+":"+toString(i)+":SHEET", false); - if(nl) - { - nl->setValue64(value); - nl= NLGUI::CDBManager::getInstance()->getDbProp(args[0]+":"+toString(i)+":QUALITY", false); - if(nl) - nl->setValue64(i); - nl= NLGUI::CDBManager::getInstance()->getDbProp(args[0]+":"+toString(i)+":PREREQUISIT_VALID", false); - if(nl) - nl->setValue64(1); - } - } - - return true; + return true; } NLMISC_COMMAND(fillAllItemPreReq, "", "dbstring value") { - if(args.size()!=2) - return false; + if(args.size()!=2) + return false; - // read value - sint32 value; - fromString(args[1], value); - string dbBase= args[0]; + // read value + sint32 value; + fromString(args[1], value); + string dbBase= args[0]; - // write prop for all elements of the branch - uint index= 0; - for(;;) - { - CInterfaceManager *pIM= CInterfaceManager::getInstance(); - CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("%s:%d:PREREQUISIT_VALID", dbBase.c_str(), index), false); - if(!node) - break; - node->setValue32(value); - index++; - } + // write prop for all elements of the branch + uint index= 0; + for(;;) + { + CInterfaceManager *pIM= CInterfaceManager::getInstance(); + CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("%s:%d:PREREQUISIT_VALID", dbBase.c_str(), index), false); + if(!node) + break; + node->setValue32(value); + index++; + } - return true; + return true; } NLMISC_COMMAND(eventMusic, "", "music") { - if(args.size()<1 && args.size()>3) - return false; + if(args.size()<1 && args.size()>3) + return false; - string fileName= args[0].c_str(); - bool loop= false; - if(args.size() > 1) - fromString(args[1], loop); - uint fadeTime= 1000; - if(args.size() > 2) - fromString(args[2], fadeTime); + string fileName= args[0].c_str(); + bool loop= false; + if(args.size() > 1) + fromString(args[1], loop); + uint fadeTime= 1000; + if(args.size() > 2) + fromString(args[2], fadeTime); - if(SoundMngr) - SoundMngr->playEventMusic(fileName, fadeTime, loop); + if(SoundMngr) + SoundMngr->playEventMusic(fileName, fadeTime, loop); - return true; + return true; } NLMISC_COMMAND(setLightHour, "force the light hour, (negative value to reset to auto)", "") { - if( args.size()!=1 ) - return false; + if( args.size()!=1 ) + return false; - float hour; - fromString(args[0], hour); - if( hour < LightCycleManager.getLightDesc().NumHours ) + float hour; + fromString(args[0], hour); + if( hour < LightCycleManager.getLightDesc().NumHours ) + { + // check for privileges if this is the final build +#if FINAL_VERSION + // test that user has privilege + if (hasPrivilegeDEV() || + hasPrivilegeSGM() || + hasPrivilegeGM() || + hasPrivilegeVG() || + hasPrivilegeSG() || + hasPrivilegeG() || + hasPrivilegeEM() || + hasPrivilegeEG()) +#endif { - // check for privileges if this is the final build - #if FINAL_VERSION - // test that user has privilege - if (hasPrivilegeDEV() || - hasPrivilegeSGM() || - hasPrivilegeGM() || - hasPrivilegeVG() || - hasPrivilegeSG() || - hasPrivilegeG() || - hasPrivilegeEM() || - hasPrivilegeEG()) - #endif - { - ForcedDayNightCycleHour = hour; - return true; - } + ForcedDayNightCycleHour = hour; + return true; } - return false; + } + return false; } NLMISC_COMMAND(jobAnim, "set the job anim specialisation of an entity", "eid number") { - if(args.size()!=2) - return false; + if(args.size()!=2) + return false; - uint eid; - fromString(args[0], eid); - uint jas; - fromString(args[1], jas); - CCharacterCL *ent= dynamic_cast(EntitiesMngr.entity(eid)); - if(ent) - { - ent->setAnimJobSpecialisation(jas); - } + uint eid; + fromString(args[0], eid); + uint jas; + fromString(args[1], jas); + CCharacterCL *ent= dynamic_cast(EntitiesMngr.entity(eid)); + if(ent) + { + ent->setAnimJobSpecialisation(jas); + } - return true; + return true; } NLMISC_COMMAND(startLogStageChange, "start to log the change of stages of watched entity", "") { - // stop first any log - EntitiesMngr.stopLogStageChange(); + // stop first any log + EntitiesMngr.stopLogStageChange(); - // start the log - EntitiesMngr.startLogStageChange(NetMngr.getCurrentClientTick(), T1); + // start the log + EntitiesMngr.startLogStageChange(NetMngr.getCurrentClientTick(), T1); - return true; + return true; } NLMISC_COMMAND(stopLogStageChange, "stop to log the change of watched entity stages", "") { - EntitiesMngr.stopLogStageChange(); - return true; + EntitiesMngr.stopLogStageChange(); + return true; } NLMISC_COMMAND(testReceiveMissionInfo, "emulate a dummy receive of mission info", "") { - CBotChatManager::getInstance()->debugLocalReceiveMissionInfo(); - return true; + CBotChatManager::getInstance()->debugLocalReceiveMissionInfo(); + return true; } // command to dump the ui, no indentation full name NLMISC_COMMAND(dumpUIIndent, "Debug only : Dump the ui hierarchy in the output debug window", "") { - CInterfaceManager *im = CInterfaceManager::getInstance(); - im->dumpUI(true); - return true; + CInterfaceManager *im = CInterfaceManager::getInstance(); + im->dumpUI(true); + return true; } // command to dump the ui, no indentation full name NLMISC_COMMAND(dumpUIFull, "Debug only : Dump the ui hierarchy in the output debug window", "") { - CInterfaceManager *im = CInterfaceManager::getInstance(); - im->dumpUI(false); - return true; + CInterfaceManager *im = CInterfaceManager::getInstance(); + im->dumpUI(false); + return true; } // command to dump coordinates of a UI, for debug NLMISC_COMMAND(dumpUICoords, "Debug only : dump all coords info of an UI", "uiid") { - if(args.size()!=1) - return false; + if(args.size()!=1) + return false; - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - CInterfaceElement *el= CWidgetManager::getInstance()->getElementFromId(args[0]); - if(!el) + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + CInterfaceElement *el= CWidgetManager::getInstance()->getElementFromId(args[0]); + if(!el) + { + pIM->displaySystemInfo(toString("dumpUICoords: '%s' does not exist", args[0].c_str())); + } + else + { + pIM->displaySystemInfo(toString("dumpUICoords: **** '%s'", args[0].c_str())); + pIM->displaySystemInfo(toString(" active= %d", uint(el->getActive()) )); + pIM->displaySystemInfo(toString(" x= %d", el->getX() )); + pIM->displaySystemInfo(toString(" y= %d", el->getY() )); + pIM->displaySystemInfo(toString(" w= %d", el->getW() )); + pIM->displaySystemInfo(toString(" h= %d", el->getH() )); + pIM->displaySystemInfo(toString(" xreal= %d", el->getXReal() )); + pIM->displaySystemInfo(toString(" yreal= %d", el->getYReal() )); + pIM->displaySystemInfo(toString(" wreal= %d", el->getWReal() )); + pIM->displaySystemInfo(toString(" hreal= %d", el->getHReal() )); + pIM->displaySystemInfo(toString(" parent= '%s'", el->getParent()?el->getParent()->getId().c_str():"")); + pIM->displaySystemInfo(toString(" parentpos= '%s'", el->getParentPos()?el->getParentPos()->getId().c_str():"")); + pIM->displaySystemInfo(toString(" parentsize= '%s'", el->getParentSize()?el->getParentSize()->getId().c_str():"")); + + // SizeRef + string sr; + switch(el->getSizeRef()) { - pIM->displaySystemInfo(toString("dumpUICoords: '%s' does not exist", args[0].c_str())); + case 1: sr= "w"; break; + case 2: sr= "h"; break; + case 3: sr= "wh"; break; + default:break; } - else - { - pIM->displaySystemInfo(toString("dumpUICoords: **** '%s'", args[0].c_str())); - pIM->displaySystemInfo(toString(" active= %d", uint(el->getActive()) )); - pIM->displaySystemInfo(toString(" x= %d", el->getX() )); - pIM->displaySystemInfo(toString(" y= %d", el->getY() )); - pIM->displaySystemInfo(toString(" w= %d", el->getW() )); - pIM->displaySystemInfo(toString(" h= %d", el->getH() )); - pIM->displaySystemInfo(toString(" xreal= %d", el->getXReal() )); - pIM->displaySystemInfo(toString(" yreal= %d", el->getYReal() )); - pIM->displaySystemInfo(toString(" wreal= %d", el->getWReal() )); - pIM->displaySystemInfo(toString(" hreal= %d", el->getHReal() )); - pIM->displaySystemInfo(toString(" parent= '%s'", el->getParent()?el->getParent()->getId().c_str():"")); - pIM->displaySystemInfo(toString(" parentpos= '%s'", el->getParentPos()?el->getParentPos()->getId().c_str():"")); - pIM->displaySystemInfo(toString(" parentsize= '%s'", el->getParentSize()?el->getParentSize()->getId().c_str():"")); + pIM->displaySystemInfo(toString(" sizeref= '%s'", sr.c_str())); - // SizeRef - string sr; - switch(el->getSizeRef()) - { - case 1: sr= "w"; break; - case 2: sr= "h"; break; - case 3: sr= "wh"; break; - default:break; - } - pIM->displaySystemInfo(toString(" sizeref= '%s'", sr.c_str())); + // PosRef + string pr; + THotSpot hsParent= el->getParentPosRef(); + THotSpot hsSelf= el->getPosRef(); + // parent + if(hsParent & Hotspot_Bx) pr+= "B"; + else if(hsParent & Hotspot_Mx) pr+= "M"; + else if(hsParent & Hotspot_Tx) pr+= "T"; + else pr+= "?"; + if(hsParent & Hotspot_xL) pr+= "L"; + else if(hsParent & Hotspot_xM) pr+= "M"; + else if(hsParent & Hotspot_xR) pr+= "R"; + else pr+= "?"; + pr+=" "; + // self + if(hsSelf & Hotspot_Bx) pr+= "B"; + else if(hsSelf & Hotspot_Mx) pr+= "M"; + else if(hsSelf & Hotspot_Tx) pr+= "T"; + else pr+= "?"; + if(hsSelf & Hotspot_xL) pr+= "L"; + else if(hsSelf & Hotspot_xM) pr+= "M"; + else if(hsSelf & Hotspot_xR) pr+= "R"; + else pr+= "?"; + pIM->displaySystemInfo(toString(" posref= '%s'", pr.c_str())); - // PosRef - string pr; - THotSpot hsParent= el->getParentPosRef(); - THotSpot hsSelf= el->getPosRef(); - // parent - if(hsParent & Hotspot_Bx) pr+= "B"; - else if(hsParent & Hotspot_Mx) pr+= "M"; - else if(hsParent & Hotspot_Tx) pr+= "T"; - else pr+= "?"; - if(hsParent & Hotspot_xL) pr+= "L"; - else if(hsParent & Hotspot_xM) pr+= "M"; - else if(hsParent & Hotspot_xR) pr+= "R"; - else pr+= "?"; - pr+=" "; - // self - if(hsSelf & Hotspot_Bx) pr+= "B"; - else if(hsSelf & Hotspot_Mx) pr+= "M"; - else if(hsSelf & Hotspot_Tx) pr+= "T"; - else pr+= "?"; - if(hsSelf & Hotspot_xL) pr+= "L"; - else if(hsSelf & Hotspot_xM) pr+= "M"; - else if(hsSelf & Hotspot_xR) pr+= "R"; - else pr+= "?"; - pIM->displaySystemInfo(toString(" posref= '%s'", pr.c_str())); + pIM->displaySystemInfo(string("dumpUICoords: **** END")); + } - pIM->displaySystemInfo(string("dumpUICoords: **** END")); - } - - return true; + return true; } // Command to clear the dump of done Files opened and Async File Manager done files (for debug) NLMISC_COMMAND(clearDumpFiles, "clear the CAsyncFileManager and CIFile Debug list of opened files", "") { - CIFile::clearDump(); - CAsyncFileManager::getInstance().clearDump(); + CIFile::clearDump(); + CAsyncFileManager::getInstance().clearDump(); - return true; + return true; } #endif // FINAL_VERSION @@ -5031,25 +5044,25 @@ NLMISC_COMMAND(clearDumpFiles, "clear the CAsyncFileManager and CIFile Debug lis NLMISC_COMMAND(reloadFogMaps, "Force to reload all the fog maps", "<>") { - if (!args.empty()) return false; - ContinentMngr.cur()->reloadFogMap(); - return true; + if (!args.empty()) return false; + ContinentMngr.cur()->reloadFogMap(); + return true; } // dump the names of all loaded sounds NLMISC_COMMAND(dumpSounds, "Dump names of all loaded sound", "<>") { - if (!args.empty()) return false; - std::vector sounds; - extern CSoundManager *SoundMngr; - if (!SoundMngr) return false; - if (!SoundMngr->getMixer()) return false; - SoundMngr->getMixer()->getSoundNames(sounds); - for(uint k = 0; k < sounds.size(); ++k) - { - nlinfo(sounds[k].toString()/*NLMISC::CStringMapper::unmap(sounds[k])*/.c_str()); - } - return true; + if (!args.empty()) return false; + std::vector sounds; + extern CSoundManager *SoundMngr; + if (!SoundMngr) return false; + if (!SoundMngr->getMixer()) return false; + SoundMngr->getMixer()->getSoundNames(sounds); + for(uint k = 0; k < sounds.size(); ++k) + { + nlinfo(sounds[k].toString()/*NLMISC::CStringMapper::unmap(sounds[k])*/.c_str()); + } + return true; } // *************************************************************************** @@ -5059,104 +5072,104 @@ const char *LUADebugNotEnabledMsg= "Lua Commands are available only if you add ' NLMISC_COMMAND(luaReload, "reload all .lua script files", "") { - CInterfaceManager *pIM= CInterfaceManager::getInstance(); - if(ClientCfg.AllowDebugLua) - { - CWidgetManager::getInstance()->getParser()->reloadAllLuaFileScripts(); - return true; - } - else - { - pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg)); - return false; - } + CInterfaceManager *pIM= CInterfaceManager::getInstance(); + if(ClientCfg.AllowDebugLua) + { + CWidgetManager::getInstance()->getParser()->reloadAllLuaFileScripts(); + return true; + } + else + { + pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg)); + return false; + } } NLMISC_COMMAND(luaScript, "Execute a lua script", "direct_script_code") { - CInterfaceManager *pIM= CInterfaceManager::getInstance(); - if(ClientCfg.AllowDebugLua) + CInterfaceManager *pIM= CInterfaceManager::getInstance(); + if(ClientCfg.AllowDebugLua) + { + if(args.size()<1) + return false; + + // Concat list of string in one script + string script; + for(uint i=0;idisplaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg)); - return false; + script+= args[i] + " "; } + + // not smallScript because suppose var can change a lot + CLuaManager::getInstance().executeLuaScript(script, false); + + return true; + } + else + { + pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg)); + return false; + } } NLMISC_COMMAND(luaInfo, "Dump some information on LUA state", "detaillevel from 0 to 2") { - CInterfaceManager *pIM= CInterfaceManager::getInstance(); - if(ClientCfg.AllowDebugLua) - { - if(args.size()!=1) - return false; + CInterfaceManager *pIM= CInterfaceManager::getInstance(); + if(ClientCfg.AllowDebugLua) + { + if(args.size()!=1) + return false; - uint detail; - fromString(args[0], detail); + uint detail; + fromString(args[0], detail); - pIM->dumpLuaState(detail); - return true; - } - else - { - pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg)); - return false; - } + pIM->dumpLuaState(detail); + return true; + } + else + { + pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg)); + return false; + } } NLMISC_COMMAND(luaObject, "Dump the content of a lua object", " [maxDepth = 20, 0 for no limits]") { - if (args.empty()) return false; - if (args.size() > 2) return false; - CInterfaceManager *pIM= CInterfaceManager::getInstance(); - if (!ClientCfg.AllowDebugLua) - { - pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg)); - return false; - } - CLuaState *luaState = CLuaManager::getInstance().getLuaState(); - if (!luaState) return false; - CLuaStackChecker lsc(luaState); - // get the table - static const char *inspectedTable = "_____inspected_table"; - try - { - // make a reference to the table to be inspected (is this this a primitive type, just make a copy) - luaState->executeScript(std::string(inspectedTable) + " = " + args[0]); - } - catch(const ELuaError &e) - { - CLuaIHMRyzom::debugInfo(e.what()); - return false; - } - luaState->pushGlobalTable(); - CLuaObject env; - env.pop(*luaState); - uint maxDepth; - if (args.size() > 1) - fromString(args[1], maxDepth); - else - maxDepth = 20; - //CLuaIHM::debugInfo(env[inspectedTable].toStringRecurse(0, maxDepth)); - env[inspectedTable].dump(); - env.eraseValue(inspectedTable); - return true; + if (args.empty()) return false; + if (args.size() > 2) return false; + CInterfaceManager *pIM= CInterfaceManager::getInstance(); + if (!ClientCfg.AllowDebugLua) + { + pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg)); + return false; + } + CLuaState *luaState = CLuaManager::getInstance().getLuaState(); + if (!luaState) return false; + CLuaStackChecker lsc(luaState); + // get the table + static const char *inspectedTable = "_____inspected_table"; + try + { + // make a reference to the table to be inspected (is this this a primitive type, just make a copy) + luaState->executeScript(std::string(inspectedTable) + " = " + args[0]); + } + catch(const ELuaError &e) + { + CLuaIHMRyzom::debugInfo(e.what()); + return false; + } + luaState->pushGlobalTable(); + CLuaObject env; + env.pop(*luaState); + uint maxDepth; + if (args.size() > 1) + fromString(args[1], maxDepth); + else + maxDepth = 20; + //CLuaIHM::debugInfo(env[inspectedTable].toStringRecurse(0, maxDepth)); + env[inspectedTable].dump(); + env.eraseValue(inspectedTable); + return true; } @@ -5166,17 +5179,17 @@ NLMISC_COMMAND(luaObject, "Dump the content of a lua object", "
[max #if !FINAL_VERSION NLMISC_COMMAND(luaGC, "Force a garbage collector of lua", "") { - CInterfaceManager *pIM= CInterfaceManager::getInstance(); - if(ClientCfg.AllowDebugLua) - { - CLuaManager::getInstance().forceGarbageCollect(); - return true; - } - else - { - pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg)); - return false; - } + CInterfaceManager *pIM= CInterfaceManager::getInstance(); + if(ClientCfg.AllowDebugLua) + { + CLuaManager::getInstance().forceGarbageCollect(); + return true; + } + else + { + pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg)); + return false; + } } #endif @@ -5190,241 +5203,241 @@ std::map CUserCommand::CommandMap; // release memory void CUserCommand::release() { - std::map::iterator it = CommandMap.begin(); - while( it != CommandMap.end() ) - delete (*it++).second; - CommandMap.clear(); + std::map::iterator it = CommandMap.begin(); + while( it != CommandMap.end() ) + delete (*it++).second; + CommandMap.clear(); } // *************************************************************************** CUserCommand::CUserCommand(const string &commandName, const ucstring &help, const ucstring &argsHelp) - : ICommand("user", commandName.c_str(), toString(help).c_str(), toString(argsHelp).c_str()) + : ICommand("user", commandName.c_str(), toString(help).c_str(), toString(argsHelp).c_str()) { - CommandName = commandName; + CommandName = commandName; } // *************************************************************************** void CUserCommand::addMode (const string &action, uint numArg, bool infiniteAgr, const std::vector &keywords) { - CMode *mode; - if (!infiniteAgr) - mode = &(FixedArgModes[numArg]); - else - mode = &InfiniteMode; - mode->Action = action; - mode->KeywordsCount = numArg; - mode->Keywords = keywords; + CMode *mode; + if (!infiniteAgr) + mode = &(FixedArgModes[numArg]); + else + mode = &InfiniteMode; + mode->Action = action; + mode->KeywordsCount = numArg; + mode->Keywords = keywords; } // *************************************************************************** bool CUserCommand::execute(const std::string &/* rawCommandString */, const std::vector &args, NLMISC::CLog &/* log */, bool /* quiet */, bool /* human */) { - CInterfaceManager *pIM = CInterfaceManager::getInstance(); + CInterfaceManager *pIM = CInterfaceManager::getInstance(); - // Find the good keyword table - CMode *mode = NULL; - if (FixedArgModes.find ((uint)args.size()) != FixedArgModes.end()) - mode = &(FixedArgModes[(uint)args.size()]); - else - if (!InfiniteMode.Keywords.empty() && (args.size() >= InfiniteMode.KeywordsCount)) - mode = &InfiniteMode; + // Find the good keyword table + CMode *mode = NULL; + if (FixedArgModes.find ((uint)args.size()) != FixedArgModes.end()) + mode = &(FixedArgModes[(uint)args.size()]); + else + if (!InfiniteMode.Keywords.empty() && (args.size() >= InfiniteMode.KeywordsCount)) + mode = &InfiniteMode; - if (mode) + if (mode) + { + // Build the final string + static string finalArgs; + finalArgs = ""; + uint i; + uint index = 0; + const vector &keywords = mode->Keywords; + for (i=0; i &keywords = mode->Keywords; - for (i=0; i= args.size()) { - if ((keywords[i] == "$") || (keywords[i] == "+")) - { - if ((uint)index >= args.size()) - { - // Not enough arguments - pIM->displaySystemInfo (ucstring(CommandName+" : ")+CI18N::get ("uiCommandWrongArgumentCount")); - return false; - } - else - { - if (keywords[i] == "$") - finalArgs += /*ucstring(*/args[index++]/*).toUtf8()*/; - else - { - while (index 0) ? " " : ""; - // If arg contains spaces then put it in quotes - if (string::npos != args[index].find(" ")) - { - finalArgs += "\"" + args[index++] + "\""; - } - else - { - finalArgs += args[index++]; - } - } - } - } - } - else - { - finalArgs += keywords[i]; - } + // Not enough arguments + pIM->displaySystemInfo (ucstring(CommandName+" : ")+CI18N::get ("uiCommandWrongArgumentCount")); + return false; } + else + { + if (keywords[i] == "$") + finalArgs += /*ucstring(*/args[index++]/*).toUtf8()*/; + else + { + while (index 0) ? " " : ""; + // If arg contains spaces then put it in quotes + if (string::npos != args[index].find(" ")) + { + finalArgs += "\"" + args[index++] + "\""; + } + else + { + finalArgs += args[index++]; + } + } + } + } + } + else + { + finalArgs += keywords[i]; + } + } - // Run the action handler - CAHManager::getInstance()->runActionHandler (mode->Action, CWidgetManager::getInstance()->getOldCaptureKeyboard(), finalArgs); - } - else - { - // Not enough argument - pIM->displaySystemInfo (ucstring(CommandName+" : ")+CI18N::get ("uiCommandWrongArgumentCount")); - return false; - } - return true; + // Run the action handler + CAHManager::getInstance()->runActionHandler (mode->Action, CWidgetManager::getInstance()->getOldCaptureKeyboard(), finalArgs); + } + else + { + // Not enough argument + pIM->displaySystemInfo (ucstring(CommandName+" : ")+CI18N::get ("uiCommandWrongArgumentCount")); + return false; + } + return true; } // *************************************************************************** void CUserCommand::createCommand (const char *name, const char *action, const char *ptrParams) { - // Parse the params - std::vector keywords; + // Parse the params + std::vector keywords; - // Get the help and the argument help - uint countArgument = 0; - bool infiniteArgument = false; - string params = ptrParams; - string::size_type pos = 0; - while (pos < params.size()) + // Get the help and the argument help + uint countArgument = 0; + bool infiniteArgument = false; + string params = ptrParams; + string::size_type pos = 0; + while (pos < params.size()) + { + // Token ? + string::size_type last; + switch (params[pos]) { - // Token ? - string::size_type last; - switch (params[pos]) - { - case '|': - case '=': - case '$': - case '+': - if ((params[pos] == '$') || (params[pos] == '+')) - countArgument++; - if (params[pos] == '+') - infiniteArgument = true; - last = pos+1; - break; - default: - last = params.find_first_of ("|=$+", pos); - if (last == string::npos) - last = params.size(); - break; - } - - // Add a keyword - keywords.push_back (params.substr (pos, last-pos)); - pos = last; + case '|': + case '=': + case '$': + case '+': + if ((params[pos] == '$') || (params[pos] == '+')) + countArgument++; + if (params[pos] == '+') + infiniteArgument = true; + last = pos+1; + break; + default: + last = params.find_first_of ("|=$+", pos); + if (last == string::npos) + last = params.size(); + break; } - // Find action name - ucstring help; - const CBaseAction *ab = Actions.getBaseAction (::CAction::CName (action, ptrParams)); - if (ab) - help = CI18N::get(ab->LocalizedName); + // Add a keyword + keywords.push_back (params.substr (pos, last-pos)); + pos = last; + } - // Build a argument help - ucstring argsHelp; + // Find action name + ucstring help; + const CBaseAction *ab = Actions.getBaseAction (::CAction::CName (action, ptrParams)); + if (ab) + help = CI18N::get(ab->LocalizedName); - if (ab) + // Build a argument help + ucstring argsHelp; + + if (ab) + { + // Look for each arguments + uint i; + for (i=0; iParameters.size(); j++) + { + // Argument found + if (ab->Parameters[j].Name == keywords[i-2]) { - // Have a "=" ? - if ((i > 1) && (keywords[i-1]=="=")) - { - // Argument - bool bFound = false; - for (uint j=0; jParameters.size(); j++) - { - // Argument found - if (ab->Parameters[j].Name == keywords[i-2]) - { - // Add the string - if (!argsHelp.empty()) - argsHelp += " "; - argsHelp += ucstring("<") + CI18N::get(ab->Parameters[j].LocalizedName) + ucstring(">"); - bFound = true; - } - } - // Not found ? Warning - if (!bFound) - { - nlwarning ("Argument %s not found in command %s using action %s", keywords[i-2].c_str(), name, action); - } - } + // Add the string + if (!argsHelp.empty()) + argsHelp += " "; + argsHelp += ucstring("<") + CI18N::get(ab->Parameters[j].LocalizedName) + ucstring(">"); + bFound = true; } + } + // Not found ? Warning + if (!bFound) + { + nlwarning ("Argument %s not found in command %s using action %s", keywords[i-2].c_str(), name, action); + } } + } } + } - // Ugly : never deleted, but who cares ? - // Command exist ? - CUserCommand *currentCommand; - if (CommandMap.find (name) != CommandMap.end()) - currentCommand = CommandMap[name]; - else - { - currentCommand = new CUserCommand (name, help, argsHelp); - CommandMap[name] = currentCommand; - } + // Ugly : never deleted, but who cares ? + // Command exist ? + CUserCommand *currentCommand; + if (CommandMap.find (name) != CommandMap.end()) + currentCommand = CommandMap[name]; + else + { + currentCommand = new CUserCommand (name, help, argsHelp); + CommandMap[name] = currentCommand; + } - // Add keywords - currentCommand->addMode (action, countArgument, infiniteArgument, keywords); + // Add keywords + currentCommand->addMode (action, countArgument, infiniteArgument, keywords); } NLMISC_COMMAND(doAssert, "Create an assert", "") { - nlassert(0); - return true; + nlassert(0); + return true; } NLMISC_COMMAND(dumpPosAsPrim, "ld helper : add current position to pos.primitive with the given comment", "") { - if (!EntitiesMngr.entity(0)) return false; - std::string comment; - for(uint k = 0; k < args.size(); ++k) + if (!EntitiesMngr.entity(0)) return false; + std::string comment; + for(uint k = 0; k < args.size(); ++k) + { + if (k != 0) comment += " "; + comment += args[k]; + } + std::string srcFile; + const std::string path = "save/pos.primitive"; + if (CFile::fileExists(path)) + { + try { - if (k != 0) comment += " "; - comment += args[k]; + uint32 fileSize = CFile::getFileSize(path); + srcFile.resize(fileSize); + CIFile stream; + stream.open(path); + stream.serialBuffer((uint8 *) &srcFile[0], fileSize); } - std::string srcFile; - const std::string path = "save/pos.primitive"; - if (CFile::fileExists(path)) + catch(const NLMISC::EStream &e) { - try - { - uint32 fileSize = CFile::getFileSize(path); - srcFile.resize(fileSize); - CIFile stream; - stream.open(path); - stream.serialBuffer((uint8 *) &srcFile[0], fileSize); - } - catch(const NLMISC::EStream &e) - { - nlinfo(e.what()); - srcFile.clear(); - } + nlinfo(e.what()); + srcFile.clear(); } - std::string newPrim = - NLMISC::toString(" \n\ + } + std::string newPrim = + NLMISC::toString(" \n\ \n\ \n\ class \n\ @@ -5436,236 +5449,236 @@ NLMISC_COMMAND(dumpPosAsPrim, "ld helper : add current position to pos.primitive \n\ \n", (float) EntitiesMngr.entity(0)->pos().x, (float) EntitiesMngr.entity(0)->pos().y, (float) EntitiesMngr.entity(0)->pos().z, comment.c_str()); - // try to append result to current file - const std::string LAST_CHILD_MARKER = ""; - std::string::size_type insertPos = srcFile.rfind(LAST_CHILD_MARKER); - if (insertPos != std::string::npos) - { - insertPos += LAST_CHILD_MARKER.size(); - srcFile.insert(insertPos, "\n" + newPrim); - } - else - { - srcFile.clear(); - } - if (srcFile.empty()) - { - srcFile = " \n\ + // try to append result to current file + const std::string LAST_CHILD_MARKER = ""; + std::string::size_type insertPos = srcFile.rfind(LAST_CHILD_MARKER); + if (insertPos != std::string::npos) + { + insertPos += LAST_CHILD_MARKER.size(); + srcFile.insert(insertPos, "\n" + newPrim); + } + else + { + srcFile.clear(); + } + if (srcFile.empty()) + { + srcFile = " \n\ \n\ \n" - + newPrim - + " \n\ + + newPrim + + " \n\ \n"; - } + } - // write result - try - { - COFile stream; - stream.open(path); - stream.serialBuffer((uint8 *) &srcFile[0], (uint)srcFile.size()); - } - catch(const NLMISC::EStream &e) - { - nlinfo(e.what()); - } - return true; + // write result + try + { + COFile stream; + stream.open(path); + stream.serialBuffer((uint8 *) &srcFile[0], (uint)srcFile.size()); + } + catch(const NLMISC::EStream &e) + { + nlinfo(e.what()); + } + return true; } NLMISC_COMMAND(clear, "clear content of current char window", "") { - if (args.size() > 1) return false; - CInterfaceManager *im = CInterfaceManager::getInstance(); - im->flushDebugWindow(); - CChatWindow *cw; - if (args.size() == 1) + if (args.size() > 1) return false; + CInterfaceManager *im = CInterfaceManager::getInstance(); + im->flushDebugWindow(); + CChatWindow *cw; + if (args.size() == 1) + { + cw = getChatWndMgr().getChatWindowFromCaller(dynamic_cast(CWidgetManager::getInstance()->getElementFromId(args[0]))); + } + else + { + // if no chat window (or enclosed control) id is given then see if a chat window called this command + cw = CChatWindow::getChatWindowLaunchingCommand(); + } + if (cw && cw->getContainer()) + { + CGroupList *gl = dynamic_cast(cw->getContainer()->getGroup("text_list")); + if (gl) { - cw = getChatWndMgr().getChatWindowFromCaller(dynamic_cast(CWidgetManager::getInstance()->getElementFromId(args[0]))); + gl->deleteAllChildren(); } - else - { - // if no chat window (or enclosed control) id is given then see if a chat window called this command - cw = CChatWindow::getChatWindowLaunchingCommand(); - } - if (cw && cw->getContainer()) - { - CGroupList *gl = dynamic_cast(cw->getContainer()->getGroup("text_list")); - if (gl) - { - gl->deleteAllChildren(); - } - } - return true; + } + return true; } NLMISC_COMMAND(dumpAllLoadedZones, "dump all loaded zones", "") { - if (!args.empty()) return false; - if (Landscape) + if (!args.empty()) return false; + if (Landscape) + { + std::vector loadedZones; + Landscape->getAllZoneLoaded(loadedZones); + for(uint k = 0; k < loadedZones.size(); ++k) { - std::vector loadedZones; - Landscape->getAllZoneLoaded(loadedZones); - for(uint k = 0; k < loadedZones.size(); ++k) - { - nlwarning(loadedZones[k].c_str()); - } + nlwarning(loadedZones[k].c_str()); } - else - { - nlwarning("Landscape has no loaded zones "); - } - return true; + } + else + { + nlwarning("Landscape has no loaded zones "); + } + return true; } NLMISC_COMMAND(tickToDate, "convert a tick value into a readable ryzom time", "") { - if (args.size() != 1) return false; - CRyzomTime rt; - uint32 tick; - fromString(args[0], tick); - rt.updateRyzomClock(tick); - CInterfaceManager *im = CInterfaceManager::getInstance(); - float ryTime = rt.getRyzomTime(); - std::string readableDate = toString("Day = %d, hour = %d:%d", rt.getRyzomDay(), (int) floorf(ryTime), (int) floorf(60.f * fmodf(ryTime, 1.f))); - im->displaySystemInfo(ucstring(readableDate)); - return true; + if (args.size() != 1) return false; + CRyzomTime rt; + uint32 tick; + fromString(args[0], tick); + rt.updateRyzomClock(tick); + CInterfaceManager *im = CInterfaceManager::getInstance(); + float ryTime = rt.getRyzomTime(); + std::string readableDate = toString("Day = %d, hour = %d:%d", rt.getRyzomDay(), (int) floorf(ryTime), (int) floorf(60.f * fmodf(ryTime, 1.f))); + im->displaySystemInfo(ucstring(readableDate)); + return true; } NLMISC_COMMAND(dumpShapeMaxDist, "dump max dist for shapes", "") { -/* - std::set shapeSet; - typedef CHashMultiMap TShapeMap; - TShapeMap shapes; - const CSheetManager::TEntitySheetMap &sheets = SheetMngr.getSheets(); - std::vector equipList; - for (CSheetManager::TEntitySheetMap::const_iterator it = sheets.begin(); it != sheets.end(); ++it) - { - CCharacterSheet *cs = dynamic_cast(SheetMngr.get(it->first)); - if (cs) - { - equipList.clear(); - cs->getWholeEquipmentList(equipList); - for (uint k = 0; k < equipList.size(); ++k) - { - std::string item = toLower(equipList[k]->getItem()); - if (!item.empty()) - { + /* + std::set shapeSet; + typedef CHashMultiMap TShapeMap; + TShapeMap shapes; + const CSheetManager::TEntitySheetMap &sheets = SheetMngr.getSheets(); + std::vector equipList; + for (CSheetManager::TEntitySheetMap::const_iterator it = sheets.begin(); it != sheets.end(); ++it) + { + CCharacterSheet *cs = dynamic_cast(SheetMngr.get(it->first)); + if (cs) + { + equipList.clear(); + cs->getWholeEquipmentList(equipList); + for (uint k = 0; k < equipList.size(); ++k) + { + std::string item = toLower(equipList[k]->getItem()); + if (!item.empty()) + { - string ext = CFile::getExtension(item); - if (ext == "shape") - { - if (!shapeSet.count(item)) - { - UInstance inst = Scene->createInstance(item); - if (!inst.empty()) - { - shapes.insert(make_pair(inst.getDistMax(), item)); - Scene->deleteInstance(inst); - } - shapeSet.insert(item); - } - } - } - } - } - } - for (TShapeMap::iterator it = shapes.begin(); it != shapes.end(); ++it) - { - nlwarning("Dist = %f, shape = %s", it->first, it->second.c_str()); - } -*/ - return true; + string ext = CFile::getExtension(item); + if (ext == "shape") + { + if (!shapeSet.count(item)) + { + UInstance inst = Scene->createInstance(item); + if (!inst.empty()) + { + shapes.insert(make_pair(inst.getDistMax(), item)); + Scene->deleteInstance(inst); + } + shapeSet.insert(item); + } + } + } + } + } + } + for (TShapeMap::iterator it = shapes.begin(); it != shapes.end(); ++it) + { + nlwarning("Dist = %f, shape = %s", it->first, it->second.c_str()); + } + */ + return true; } NLMISC_COMMAND(dumpContinentCorners, "dump max dist for shapes", "") { - if (!args.empty()) return false; - if (!ContinentMngr.cur()) return false; + if (!args.empty()) return false; + if (!ContinentMngr.cur()) return false; - CVector2f posMin; - CVector2f posMax; - getPosFromZoneName(ContinentMngr.cur()->ZoneMin, posMin); - getPosFromZoneName(ContinentMngr.cur()->ZoneMax, posMax); - if (posMin.x > posMax.x) std::swap(posMin.x, posMax.x); - if (posMin.y > posMax.y) std::swap(posMin.y, posMax.y); - posMax.x += 160.f; - posMax.y += 160.f; - nlwarning("min = (%f, %f), max = (%f, %f)", posMin.x, posMin.y, posMax.x, posMax.y); - return true; + CVector2f posMin; + CVector2f posMax; + getPosFromZoneName(ContinentMngr.cur()->ZoneMin, posMin); + getPosFromZoneName(ContinentMngr.cur()->ZoneMax, posMax); + if (posMin.x > posMax.x) std::swap(posMin.x, posMax.x); + if (posMin.y > posMax.y) std::swap(posMin.y, posMax.y); + posMax.x += 160.f; + posMax.y += 160.f; + nlwarning("min = (%f, %f), max = (%f, %f)", posMin.x, posMin.y, posMax.x, posMax.y); + return true; } #if !FINAL_VERSION NLMISC_COMMAND(setMission, "locally set a mission text for test", "") { - if (!ClientCfg.Local) return false; - if (args.size() != 2) return false; - uint index; - fromString(args[0], index); - CInterfaceManager *im = CInterfaceManager::getInstance(); - static sint32 strID = 10000; // any abitrary string id will do in local - if (index >= 30) return false; - if (index < 15) - { - NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:MISSIONS:%d:TITLE", (int) index))->setValue32(strID); - NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:MISSIONS:%d:FINISHED", (int) index))->setValue32(0); - } - else - { - NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:GROUP:MISSIONS:%d:TITLE", (int) index - 15))->setValue32(strID); - NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:GROUP:MISSIONS:%d:FINISHED", (int) index - 15))->setValue32(0); - } - setDynString(strID++, args[1]); - return true; + if (!ClientCfg.Local) return false; + if (args.size() != 2) return false; + uint index; + fromString(args[0], index); + CInterfaceManager *im = CInterfaceManager::getInstance(); + static sint32 strID = 10000; // any abitrary string id will do in local + if (index >= 30) return false; + if (index < 15) + { + NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:MISSIONS:%d:TITLE", (int) index))->setValue32(strID); + NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:MISSIONS:%d:FINISHED", (int) index))->setValue32(0); + } + else + { + NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:GROUP:MISSIONS:%d:TITLE", (int) index - 15))->setValue32(strID); + NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:GROUP:MISSIONS:%d:FINISHED", (int) index - 15))->setValue32(0); + } + setDynString(strID++, args[1]); + return true; } static bool setMissionStep(uint missionIndex, uint stepIndex, uint32 strID) { - CInterfaceManager *im = CInterfaceManager::getInstance(); - if (stepIndex >= 30) return false; - if (stepIndex >= 20) return false; - if (missionIndex < 15) - { - NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:MISSIONS:%d:GOALS:%d:TEXT", (int) missionIndex, (int) stepIndex))->setValue32(strID); - } - else - { - NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:GROUP:MISSIONS:%d:GOALS:%d:TEXT", (int) (missionIndex - 15), (int) stepIndex))->setValue32(strID); - } - return true; + CInterfaceManager *im = CInterfaceManager::getInstance(); + if (stepIndex >= 30) return false; + if (stepIndex >= 20) return false; + if (missionIndex < 15) + { + NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:MISSIONS:%d:GOALS:%d:TEXT", (int) missionIndex, (int) stepIndex))->setValue32(strID); + } + else + { + NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:GROUP:MISSIONS:%d:GOALS:%d:TEXT", (int) (missionIndex - 15), (int) stepIndex))->setValue32(strID); + } + return true; } // add a new step in a mission, the mission must already exist NLMISC_COMMAND(setMissionStep, "locally set a mission step for test", "") { - if (!ClientCfg.Local) return false; - if (args.size() != 3) return false; - uint missionIndex; - fromString(args[0], missionIndex); - uint stepIndex; - fromString(args[1], stepIndex); + if (!ClientCfg.Local) return false; + if (args.size() != 3) return false; + uint missionIndex; + fromString(args[0], missionIndex); + uint stepIndex; + fromString(args[1], stepIndex); - static sint32 strID = 20000; // any abitrary string id will do in local - if (!setMissionStep(missionIndex, stepIndex, strID)) return false; - setDynString(strID++, args[2]); - return true; + static sint32 strID = 20000; // any abitrary string id will do in local + if (!setMissionStep(missionIndex, stepIndex, strID)) return false; + setDynString(strID++, args[2]); + return true; } // add a newstepin a mission, the mission must already exist NLMISC_COMMAND(clearMissionStep, "locally set a mission step for test", "") { - if (!ClientCfg.Local) return false; - if (args.size() != 2) return false; - uint missionIndex; - fromString(args[0], missionIndex); - uint stepIndex; - fromString(args[1], stepIndex); - return setMissionStep(missionIndex, stepIndex, 0); + if (!ClientCfg.Local) return false; + if (args.size() != 2) return false; + uint missionIndex; + fromString(args[0], missionIndex); + uint stepIndex; + fromString(args[1], stepIndex); + return setMissionStep(missionIndex, stepIndex, 0); } @@ -5675,17 +5688,17 @@ NLMISC_COMMAND(clearMissionStep, "locally set a mission step for test", "= 30) return false; - CInterfaceManager *im = CInterfaceManager::getInstance(); - if (index < 15) - { - NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:MISSIONS:%d:TITLE", (int) index))->setValue32(0); - } - else - { - NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:GROUP:MISSIONS:%d:TITLE", (int) index - 15))->setValue32(0); - } - return true; + if (index >= 30) return false; + CInterfaceManager *im = CInterfaceManager::getInstance(); + if (index < 15) + { + NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:MISSIONS:%d:TITLE", (int) index))->setValue32(0); + } + else + { + NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:GROUP:MISSIONS:%d:TITLE", (int) index - 15))->setValue32(0); + } + return true; } #endif @@ -5693,11 +5706,11 @@ static bool debugSetMissionState(uint index, sint32 /* state */) #if !FINAL_VERSION NLMISC_COMMAND(clearMission, "clear the content of a mission", "") { - if (!ClientCfg.Local) return false; - if (args.size() != 1) return false; - uint index; - fromString(args[0], index); - return debugSetMissionState(index, 0); + if (!ClientCfg.Local) return false; + if (args.size() != 1) return false; + uint index; + fromString(args[0], index); + return debugSetMissionState(index, 0); } #endif @@ -5705,22 +5718,22 @@ NLMISC_COMMAND(clearMission, "clear the content of a mission", "" #if !FINAL_VERSION NLMISC_COMMAND(finishMission, "clear the content of a mission", "") { - if (!ClientCfg.Local) return false; - if (args.size() != 1) return false; - uint index; - fromString(args[0], index); - return debugSetMissionState(index, 1); + if (!ClientCfg.Local) return false; + if (args.size() != 1) return false; + uint index; + fromString(args[0], index); + return debugSetMissionState(index, 1); } #endif #if !FINAL_VERSION NLMISC_COMMAND(failMission, "clear the content of a mission", "") { - if (!ClientCfg.Local) return false; - if (args.size() != 1) return false; - uint index; - fromString(args[0], index); - return debugSetMissionState(index, 2); + if (!ClientCfg.Local) return false; + if (args.size() != 1) return false; + uint index; + fromString(args[0], index); + return debugSetMissionState(index, 2); } #endif @@ -5731,70 +5744,142 @@ NLMISC_COMMAND(failMission, "clear the content of a mission", "") NLMISC_COMMAND(em, "emote command", "") { - if (args.size() < 1) return false; + if (args.size() < 1) return false; - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - if( pIM ) + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + if( pIM ) + { + string emotePhrase; + if( args.size() > 0 ) { - string emotePhrase; - if( args.size() > 0 ) - { - emotePhrase = args[0]; - } - for(uint i = 1; i < args.size(); ++i ) - { - emotePhrase += " "; - emotePhrase += args[i]; - } - CAHManager::getInstance()->runActionHandler("emote", NULL, "nb=0|behav=255|custom_phrase="+emotePhrase); - return true; + emotePhrase = args[0]; } - return false; + for(uint i = 1; i < args.size(); ++i ) + { + emotePhrase += " "; + emotePhrase += args[i]; + } + CAHManager::getInstance()->runActionHandler("emote", NULL, "nb=0|behav=255|custom_phrase="+emotePhrase); + return true; + } + return false; } +NLMISC_COMMAND(emote, "emote command (1)", "") +{ + if (args.size() < 1) return false; + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + if( pIM ) + { + string emotePhrase; + if( args.size() > 0 ) + { + emotePhrase = args[0]; + } + for(uint i = 1; i < args.size(); ++i ) + { + emotePhrase += " "; + emotePhrase += args[i]; + } + CAHManager::getInstance()->runActionHandler("emote", NULL, "nb=0|behav=255|custom_phrase="+emotePhrase); + return true; + } + return false; +} +NLMISC_COMMAND(m, "emote command", "") +{ + if (args.size() < 1) return false; + + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + if( pIM ) + { + string emotePhrase; + if( args.size() > 0 ) + { + emotePhrase = args[0]; + } + for(uint i = 1; i < args.size(); ++i ) + { + emotePhrase += " "; + emotePhrase += args[i]; + } + CAHManager::getInstance()->runActionHandler("emote", NULL, "nb=0|behav=255|custom_phrase="+emotePhrase); + return true; + } + return false; +} + +NLMISC_COMMAND(me, "emote command", "") +{ + if (args.size() < 1) return false; + + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + if( pIM ) + { + string emotePhrase; + if( args.size() > 0 ) + { + emotePhrase = args[0]; + } + for(uint i = 1; i < args.size(); ++i ) + { + emotePhrase += " "; + emotePhrase += args[i]; + } + CAHManager::getInstance()->runActionHandler("emote", NULL, "nb=0|behav=255|custom_phrase="+emotePhrase); + return true; + } + return false; +} NLMISC_COMMAND(guildmotd, "Set or see the guild message of the day","") { - CBitMemStream out; - if (!GenericMsgHeaderMngr.pushNameToStream("COMMAND:GUILDMOTD", out)) - return false; + CBitMemStream out; + if (!GenericMsgHeaderMngr.pushNameToStream("COMMAND:GUILDMOTD", out)) + return false; - string gmotd; - if( args.size() > 0 ) - { - gmotd = args[0]; - } - for(uint i = 1; i < args.size(); ++i ) - { - gmotd += " "; - gmotd += args[i]; - } + string gmotd; + if( args.size() > 0 ) + { + gmotd = args[0]; + } + for(uint i = 1; i < args.size(); ++i ) + { + gmotd += " "; + gmotd += args[i]; + } - out.serial (gmotd); - NetMngr.push (out); + out.serial (gmotd); + NetMngr.push (out); - return true; + return true; } NLMISC_COMMAND(time, "Shows information about the current time", "") { - const uint8 size = 50; - char cs_local[size]; - char cs_utc[size]; - time_t date; - time(&date); - struct tm *tm; - tm = localtime(&date); - strftime(cs_local, size, "%X", tm); - tm = gmtime(&date); - strftime(cs_utc, size, "%X", tm); + const uint8 size = 50; + char cs_local[size]; + char cs_utc[size]; + time_t date; + time(&date); + struct tm *tm; + tm = localtime(&date); + strftime(cs_local, size, "%X", tm); + tm = gmtime(&date); + strftime(cs_utc, size, "%X", tm); - ucstring msg = CI18N::get("uiCurrentLocalAndUtcTime"); - strFindReplace(msg, "%local", cs_local); - strFindReplace(msg, "%utc", cs_utc); - CInterfaceManager::getInstance()->displaySystemInfo(msg, "AROUND"); - return true; + ucstring msg = CI18N::get("uiCurrentLocalAndUtcTime"); + strFindReplace(msg, "%local", cs_local); + strFindReplace(msg, "%utc", cs_utc); + CInterfaceManager::getInstance()->displaySystemInfo(msg, "AROUND"); + return true; } + +NLMISC_COMMAND(easteregg_siela1915.khanat, "Miscellaneous", "") + { + CInterfaceManager::getInstance()->displaySystemInfo("Siela1915 blesses you..."); + return true; + } diff --git a/code/ryzom/tools/client/client_patcher/main.cpp b/code/ryzom/tools/client/client_patcher/main.cpp index a0730b19f..16821d2d2 100644 --- a/code/ryzom/tools/client/client_patcher/main.cpp +++ b/code/ryzom/tools/client/client_patcher/main.cpp @@ -159,7 +159,7 @@ int main(int argc, char *argv[]) // if client.cfg is not in current directory, use client.cfg from user directory if (!CFile::isExists(config)) - config = CPath::getApplicationDirectory("Ryzom") + config; + config = CPath::getApplicationDirectory("Khanat") + config; // if client.cfg is not in current directory, use client_default.cfg if (!CFile::isExists(config))