internal static void InitMenu() { ModMenu = new UIMenu("Map Editor", "~b~" + Translation.Translate("EXTERNAL MODS")); ModMenu.DisableInstructionalButtons(true); ModMenu.OnItemSelect += (menu, item, index) => { var tmpMod = Mods[index]; if (CurrentMod == tmpMod) { UI.Notify("~b~~h~Map Editor~h~~n~~w~Mod ~h~" + tmpMod.Name + "~h~ " + Translation.Translate("has been disconnected.")); CurrentMod.ModDisconnectInvoker(); CurrentMod = null; } else { UI.Notify("~b~~h~Map Editor~h~~n~~w~Mod ~h~" + tmpMod.Name + "~h~ " + Translation.Translate("has been connected.")); tmpMod.ModSelectInvoker(); CurrentMod = tmpMod; } }; }
public MapEditor() { Tick += OnTick; KeyDown += OnKeyDown; if (!Directory.Exists("scripts\\MapEditor")) Directory.CreateDirectory("scripts\\MapEditor"); ObjectDatabase.SetupRelationships(); LoadSettings(); try { Translation.Load("scripts\\MapEditor", _settings.Translation); } catch (Exception e) { UI.Notify("~b~~h~Map Editor~h~~w~~n~Failed to load translations. Falling back to English."); UI.Notify(e.Message); } _scaleform = new Scaleform(0); _scaleform.Load("instructional_buttons"); _objectInfoMenu = new UIMenu("", "~b~" + Translation.Translate("PROPERTIES"), new Point(0, -107)); _objectInfoMenu.ResetKey(UIMenu.MenuControls.Back); _objectInfoMenu.DisableInstructionalButtons(true); _objectInfoMenu.SetBannerType(new UIResRectangle(new Point(), new Size())); _menuPool.Add(_objectInfoMenu); ModManager.InitMenu(); _objectsMenu = new UIMenu("Map Editor", "~b~" + Translation.Translate("PLACE OBJECT")); ObjectDatabase.LoadFromFile("scripts\\ObjectList.ini", ref ObjectDatabase.MainDb); ObjectDatabase.LoadInvalidHashes(); ObjectDatabase.LoadFromFile("scripts\\PedList.ini", ref ObjectDatabase.PedDb); ObjectDatabase.LoadFromFile("scripts\\VehicleList.ini", ref ObjectDatabase.VehicleDb); _crosshairPath = Path.GetFullPath("scripts\\MapEditor\\crosshair.png"); _crosshairBluePath = Path.GetFullPath("scripts\\MapEditor\\crosshair_blue.png"); _crosshairYellowPath = Path.GetFullPath("scripts\\MapEditor\\crosshair_yellow.png"); if (!File.Exists("scripts\\MapEditor\\crosshair.png")) _crosshairPath = Sprite.WriteFileFromResources(Assembly.GetExecutingAssembly(), "MapEditor.crosshair.png", "scripts\\MapEditor\\crosshair.png"); if (!File.Exists("scripts\\MapEditor\\crosshair_blue.png")) _crosshairBluePath = Sprite.WriteFileFromResources(Assembly.GetExecutingAssembly(), "MapEditor.crosshair_blue.png", "scripts\\MapEditor\\crosshair_blue.png"); if (!File.Exists("scripts\\MapEditor\\crosshair_yellow.png")) _crosshairYellowPath = Sprite.WriteFileFromResources(Assembly.GetExecutingAssembly(), "MapEditor.crosshair_yellow.png", "scripts\\MapEditor\\crosshair_yellow.png"); RedrawObjectsMenu(); _objectsMenu.OnItemSelect += OnObjectSelect; _objectsMenu.OnIndexChange += OnIndexChange; _menuPool.Add(_objectsMenu); _objectsMenu.ResetKey(UIMenu.MenuControls.Back); _objectsMenu.AddInstructionalButton(new InstructionalButton(Control.SelectWeapon, Translation.Translate("Change Axis"))); _objectsMenu.AddInstructionalButton(new InstructionalButton(Control.MoveUpDown, Translation.Translate("Zoom"))); _objectsMenu.AddInstructionalButton(new InstructionalButton(Control.Jump, Translation.Translate("Search"))); _searchMenu = new UIMenu("Map Editor", "~b~" + Translation.Translate("PLACE OBJECT")); _searchMenu.OnItemSelect += OnObjectSelect; _searchMenu.OnIndexChange += OnIndexChange; _menuPool.Add(_searchMenu); _searchMenu.ResetKey(UIMenu.MenuControls.Back); _searchMenu.AddInstructionalButton(new InstructionalButton(Control.SelectWeapon, Translation.Translate("Change Axis"))); _searchMenu.AddInstructionalButton(new InstructionalButton(Control.MoveUpDown, Translation.Translate("Zoom"))); _searchMenu.AddInstructionalButton(new InstructionalButton(Control.Jump, Translation.Translate("Search"))); _mainMenu = new UIMenu("Map Editor", "~b~" + Translation.Translate("MAIN MENU")); _mainMenu.AddItem(new UIMenuItem(Translation.Translate("Enter/Exit Map Editor"))); _mainMenu.AddItem(new UIMenuItem(Translation.Translate("New Map"), Translation.Translate("Remove all current objects and start a new map."))); _mainMenu.AddItem(new UIMenuItem(Translation.Translate("Save Map"), Translation.Translate("Save all current objects to a file."))); _mainMenu.AddItem(new UIMenuItem(Translation.Translate("Load Map"), Translation.Translate("Load objects from a file and add them to the world."))); _mainMenu.RefreshIndex(); _mainMenu.DisableInstructionalButtons(true); _menuPool.Add(_mainMenu); _formatMenu = new UIMenu("Map Editor", "~b~" + Translation.Translate("SELECT FORMAT")); _formatMenu.DisableInstructionalButtons(true); _formatMenu.ParentMenu = _mainMenu; RedrawFormatMenu(); _menuPool.Add(_formatMenu); _metadataMenu = new UIMenu("Map Editor", "~b~" + Translation.Translate("SAVE MAP")); _metadataMenu.DisableInstructionalButtons(true); _metadataMenu.ParentMenu = _formatMenu; RedrawMetadataMenu(); _menuPool.Add(_metadataMenu); _filepicker = new UIMenu("Map Editor", "~b~" + Translation.Translate("PICK FILE")); _filepicker.DisableInstructionalButtons(true); _filepicker.ParentMenu = _formatMenu; _menuPool.Add(_filepicker); _mainMenu.OnItemSelect += (m, it, i) => { switch (i) { case 0: // Enter/Exit Map Editor IsInFreecam = !IsInFreecam; Game.Player.Character.FreezePosition = IsInFreecam; Game.Player.Character.IsVisible = !IsInFreecam; World.RenderingCamera = null; if (!IsInFreecam) { Game.Player.Character.Position -= new Vector3(0f, 0f, Game.Player.Character.HeightAboveGround - 1f); return; } World.DestroyAllCameras(); _mainCamera = World.CreateCamera(GameplayCamera.Position, GameplayCamera.Rotation, 60f); _objectPreviewCamera = World.CreateCamera(new Vector3(1200.016f, 3980.998f, 86.05062f), new Vector3(0f, 0f, 0f), 60f); World.RenderingCamera = _mainCamera; break; case 1: // New Map JavascriptHook.StopAllScripts(); PropStreamer.RemoveAll(); PropStreamer.Markers.Clear(); _currentObjectsMenu.Clear(); PropStreamer.Identifications.Clear(); PropStreamer.ActiveScenarios.Clear(); PropStreamer.ActiveRelationships.Clear(); PropStreamer.ActiveWeapons.Clear(); PropStreamer.Doors.Clear(); PropStreamer.CurrentMapMetadata = new MapMetadata(); ModManager.CurrentMod?.ModDisconnectInvoker(); ModManager.CurrentMod = null; foreach (MapObject o in PropStreamer.RemovedObjects) { var t = World.CreateProp(o.Hash, o.Position, o.Rotation, true, false); t.PositionNoOffset = o.Position; } PropStreamer.RemovedObjects.Clear(); _loadedEntities = 0; _changesMade = 0; _lastAutosave = DateTime.Now; UI.Notify("~b~~h~Map Editor~h~~w~~n~" + Translation.Translate("Loaded new map.")); break; case 2: if (ModManager.CurrentMod != null) { string filename = Game.GetUserInput(255); if (String.IsNullOrWhiteSpace(filename)) { UI.Notify("~r~~h~Map Editor~h~~n~~w~" + Translation.Translate("The filename was empty.")); return; } Map tmpMap = new Map(); tmpMap.Objects.AddRange(PropStreamer.GetAllEntities()); tmpMap.RemoveFromWorld.AddRange(PropStreamer.RemovedObjects); tmpMap.Markers.AddRange(PropStreamer.Markers); UI.Notify("~b~~h~Map Editor~h~~n~~w~" + Translation.Translate("Map sent to external mod for saving.")); ModManager.CurrentMod.MapSavedInvoker(tmpMap, filename); return; } _savingMap = true; _mainMenu.Visible = false; RedrawFormatMenu(); _formatMenu.Visible = true; break; case 3: _savingMap = false; _mainMenu.Visible = false; RedrawFormatMenu(); _formatMenu.Visible = true; break; } }; _formatMenu.OnItemSelect += (m, item, indx) => { if (_savingMap) { string filename = ""; if (indx != 0) filename = Game.GetUserInput(255); switch (indx) { case 0: // XML // TODO: Send to another menu _formatMenu.Visible = false; RedrawMetadataMenu(); _metadataMenu.Visible = true; break; case 1: // Objects.ini if (!filename.EndsWith(".ini")) filename += ".ini"; SaveMap(filename, MapSerializer.Format.SimpleTrainer); break; case 2: // C# if (!filename.EndsWith(".cs")) filename += ".cs"; SaveMap(filename, MapSerializer.Format.CSharpCode); break; case 3: // Raw if (!filename.EndsWith(".txt")) filename += ".txt"; SaveMap(filename, MapSerializer.Format.Raw); break; case 4: // SpoonerLegacy if (!filename.EndsWith(".SP00N")) filename += ".SP00N"; SaveMap(filename, MapSerializer.Format.SpoonerLegacy); break; case 5: // Menyoo if (!filename.EndsWith(".xml")) filename += ".xml"; SaveMap(filename, MapSerializer.Format.Menyoo); break; } } else { string filename = ""; if (indx != 4) filename = Game.GetUserInput(255); MapSerializer.Format tmpFor = MapSerializer.Format.NormalXml; switch (indx) { case 0: // XML tmpFor = MapSerializer.Format.NormalXml; break; case 1: // Objects.ini tmpFor = MapSerializer.Format.SimpleTrainer; break; case 2: // Spooner tmpFor = MapSerializer.Format.SpoonerLegacy; break; case 3: // Spooner tmpFor = MapSerializer.Format.Menyoo; break; case 4: // File picker _formatMenu.Visible = false; RedrawFilepickerMenu(); _filepicker.Visible = true; return; } LoadMap(filename, tmpFor); } _formatMenu.Visible = false; }; _settingsMenu = new UIMenu("Map Editor", "~b~" + Translation.Translate("SETTINGS")); for (int i = -_possibleRange; i <= _possibleRange; i++) { _possiblePositions.Add(i * 0.01); } for (int i = -36000; i <= 36000; i++) { _possibleRoll.Add(i * 0.01); } var possibleLangauges = new List<string> { "Auto" }; possibleLangauges.AddRange(Translation.Translations.Select(t => t.Language).ToList()); var language = new UIMenuListItem(Translation.Translate("Language"), possibleLangauges.Select(t => (dynamic) t).ToList(), possibleLangauges.IndexOf(_settings.Translation)); language.OnListChanged += (sender, index) => { var newLanguage = sender.IndexToItem(index).ToString(); Translation.SetLanguage(newLanguage); _settings.Translation = newLanguage; SaveSettings(); if (newLanguage == "Auto") { language.Description = "Use your game's language settings."; return; } var descFile = Translation.Translations.FirstOrDefault(t => t.Language == newLanguage); if (descFile == null) return; language.Description = "~h~" + Translation.Translate("Translator") + ":~h~ " + descFile.Translator; }; var checkem = new UIMenuListItem(Translation.Translate("Marker"), new List<dynamic>(Enum.GetNames(typeof(CrosshairType))), Enum.GetNames(typeof(CrosshairType)).ToList().FindIndex(x => x == _settings.CrosshairType.ToString())); checkem.OnListChanged += (i, indx) => { CrosshairType outHash; Enum.TryParse(i.IndexToItem(indx).ToString(), out outHash); _settings.CrosshairType = outHash; SaveSettings(); }; List<dynamic> autosaveList = new List<dynamic> {Translation.Translate("Disable")}; for (int i = 5; i <= 60; i += 5) { autosaveList.Add(i); } int aIndex = autosaveList.IndexOf(_settings.AutosaveInterval); if (aIndex == -1) aIndex = 0; var autosaveItem = new UIMenuListItem(Translation.Translate("Autosave Interval"), autosaveList, aIndex, Translation.Translate("Interval in minutes between automatic autosaves.")); autosaveItem.OnListChanged += (item, index) => { var sel = item.IndexToItem(index); _settings.AutosaveInterval = (sel as string) == Translation.Translate("Disable") ? -1 : Convert.ToInt32(item.IndexToItem(index), CultureInfo.InvariantCulture); SaveSettings(); }; List<dynamic> possibleDrawDistances = new List<dynamic> {Translation.Translate("Default"), 50, 75}; for (int i = 100; i <= 3000; i += 100) { possibleDrawDistances.Add(i); } int dIndex = possibleDrawDistances.IndexOf(_settings.DrawDistance); if (dIndex == -1) dIndex = 0; var drawDistanceItem = new UIMenuListItem(Translation.Translate("Draw Distance"), possibleDrawDistances, dIndex, Translation.Translate("Draw distance for props, vehicles and peds. Reload the map for changes to take effect.")); drawDistanceItem.OnListChanged += (item, index) => { var sel = item.IndexToItem(index); _settings.DrawDistance = (sel as string) == Translation.Translate("Default") ? -1 : Convert.ToInt32(item.IndexToItem(index), CultureInfo.InvariantCulture); SaveSettings(); }; List<dynamic> senslist = new List<dynamic>(); for (int i = 1; i < 60; i++) { senslist.Add(i); } var gamboy = new UIMenuListItem(Translation.Translate("Mouse Camera Sensitivity"), senslist, _settings.CameraSensivity - 1); gamboy.OnListChanged += (item, index) => { _settings.CameraSensivity = index + 1; SaveSettings(); }; var gampadSens = new UIMenuListItem(Translation.Translate("Gamepad Camera Sensitivity"), senslist, _settings.GamepadCameraSensitivity - 1); gampadSens.OnListChanged += (item, index) => { _settings.GamepadCameraSensitivity = index + 1; SaveSettings(); }; var keymovesens = new UIMenuListItem(Translation.Translate("Keyboard Movement Sensitivity"), senslist, _settings.KeyboardMovementSensitivity - 1); keymovesens.OnListChanged += (item, index) => { _settings.KeyboardMovementSensitivity = index + 1; SaveSettings(); }; var gammovesens = new UIMenuListItem(Translation.Translate("Gamepad Movement Sensitivity"), senslist, _settings.GamepadMovementSensitivity - 1); gammovesens.OnListChanged += (item, index) => { _settings.GamepadMovementSensitivity = index + 1; SaveSettings(); }; var butts = new UIMenuCheckboxItem(Translation.Translate("Instructional Buttons"), _settings.InstructionalButtons); butts.CheckboxEvent += (i, checkd) => { _settings.InstructionalButtons = checkd; SaveSettings(); }; var gamepadItem = new UIMenuCheckboxItem(Translation.Translate("Enable Gamepad Shortcut"), _settings.Gamepad); gamepadItem.CheckboxEvent += (i, checkd) => { _settings.Gamepad = checkd; SaveSettings(); }; var counterItem = new UIMenuCheckboxItem(Translation.Translate("Entity Counter"), _settings.PropCounterDisplay); counterItem.CheckboxEvent += (i, checkd) => { _settings.PropCounterDisplay = checkd; SaveSettings(); }; var snapper = new UIMenuCheckboxItem(Translation.Translate("Follow Object With Camera"), _settings.SnapCameraToSelectedObject); snapper.CheckboxEvent += (i, checkd) => { _settings.SnapCameraToSelectedObject = checkd; SaveSettings(); }; var boundItem = new UIMenuCheckboxItem(Translation.Translate("Bounding Box"), _settings.BoundingBox.GetValueOrDefault(false)); boundItem.CheckboxEvent += (i, checkd) => { _settings.BoundingBox = checkd; SaveSettings(); }; var scriptItem = new UIMenuCheckboxItem(Translation.Translate("Execute Scripts"), _settings.LoadScripts); scriptItem.CheckboxEvent += (i, checkd) => { _settings.LoadScripts = checkd; SaveSettings(); }; var validate = new UIMenuItem(Translation.Translate("Validate Object Database"),Translation.Translate( "This will update the current object database, removing any invalid objects. The changes will take effect after you restart the script." + " It will take a couple of minutes.")); validate.Activated += (men, item) => ValidateDatabase(); var resetGrps = new UIMenuItem(Translation.Translate("Reset Active Relationship Groups"), Translation.Translate("This will set all ped's relationship groups to Companion.")); resetGrps.Activated += (men, item) => { PropStreamer.Peds.ForEach(ped => ObjectDatabase.SetPedRelationshipGroup(new Ped(ped), "Companion")); }; var objectValidationItem = new UIMenuCheckboxItem(Translation.Translate("Skip Invalid Objects"), _settings.OmitInvalidObjects); objectValidationItem.CheckboxEvent += (i, checkd) => { _settings.OmitInvalidObjects = checkd; SaveSettings(); }; #if DEBUG var testItem = new UIMenuItem("Load Terrain"); testItem.Activated += (sender, item) => { if (!Game.IsWaypointActive) { Function.Call(Hash.CLEAR_HD_AREA); return; } var wpyPos = World.GetWaypointPosition(); Function.Call(Hash.SET_HD_AREA, wpyPos.X, wpyPos.Y, wpyPos.Z, 400f); }; _settingsMenu.AddItem(testItem); #endif _settingsMenu.AddItem(language); _settingsMenu.AddItem(gamepadItem); _settingsMenu.AddItem(drawDistanceItem); _settingsMenu.AddItem(autosaveItem); _settingsMenu.AddItem(checkem); _settingsMenu.AddItem(boundItem); _settingsMenu.AddItem(gamboy); _settingsMenu.AddItem(gampadSens); _settingsMenu.AddItem(keymovesens); _settingsMenu.AddItem(gammovesens); _settingsMenu.AddItem(butts); _settingsMenu.AddItem(counterItem); _settingsMenu.AddItem(snapper); _settingsMenu.AddItem(scriptItem); _settingsMenu.AddItem(objectValidationItem); _settingsMenu.AddItem(validate); _settingsMenu.AddItem(resetGrps); _settingsMenu.RefreshIndex(); _settingsMenu.DisableInstructionalButtons(true); _menuPool.Add(_settingsMenu); _currentObjectsMenu = new UIMenu("Map Editor", "~b~" + Translation.Translate("CURRENT ENTITES")); _currentObjectsMenu.OnItemSelect += OnEntityTeleport; _currentObjectsMenu.DisableInstructionalButtons(true); _menuPool.Add(_currentObjectsMenu); var binder = new UIMenuItem(Translation.Translate("Settings")); _currentEntitiesItem = new UIMenuItem(Translation.Translate("Current Entities")); var binder2 = new UIMenuItem(Translation.Translate("Create Map for External Mod")); _mainMenu.AddItem(_currentEntitiesItem); _mainMenu.AddItem(binder); _mainMenu.AddItem(binder2); _mainMenu.BindMenuToItem(_settingsMenu, binder); _mainMenu.BindMenuToItem(_currentObjectsMenu, _currentEntitiesItem); _mainMenu.BindMenuToItem(ModManager.ModMenu, binder2); _mainMenu.RefreshIndex(); _menuPool.Add(ModManager.ModMenu); }