private void DrawManage() { if (!ImGui.BeginTabItem("Manage Screens")) { return; } ImGui.Text("This tab allows you to manage installed title screen presets."); ImGui.Separator(); ImGui.BeginChild("scrolling", new Vector2(0, 0), false); if (ImGui.CollapsingHeader("Export##titleEditExport")) { if (ImGui.Combo("##exportComboBox", ref _selectedTitleIndexExport, _titleScreensExport, _titleScreensExport.Length)) { _exportRef = ""; string fileName = Path.Combine(_titleScreenFolder, _titleScreensExport[_selectedTitleIndexExport] + ".json"); PluginLog.Log($"Exporting {fileName}"); if (File.Exists(fileName)) { string text = File.ReadAllText(fileName); var bytes = Encoding.UTF8.GetBytes(text); string base64 = "TE2" + Convert.ToBase64String(bytes); _exportRef = base64; } } ImGui.SameLine(); if (ImGui.Button("Copy")) { ImGui.SetClipboardText(_exportRef); } ImGui.BeginChild("##exportthingydo", new Vector2(0, GuiScale(150)), true); ImGui.TextWrapped(_exportRef); ImGui.EndChild(); } if (ImGui.CollapsingHeader("Import##titleEditImport")) { ImGui.Text("Paste import text here:"); ImGui.SameLine(); ImGui.SetNextItemWidth(GuiScale(254)); ImGui.InputText("##importextThingydo", ref _importRef, 2048); ImGui.SameLine(); TitleEditScreen screen = null; if (ImGui.Button("Import")) { if (!_importRef.StartsWith("TE2")) { _importParsed = false; Task.Delay(2000).ContinueWith(_ => _importParsed = true); } else { try { string toImport = Encoding.UTF8.GetString(Convert.FromBase64String(_importRef.Substring(3).Trim())); screen = JsonConvert.DeserializeObject <TitleEditScreen>(toImport); string fileName = Path.Combine(_titleScreenFolder, screen.Name + ".json"); PluginLog.Log($"Importing {fileName}"); if (!File.Exists(fileName)) { File.WriteAllText(fileName, toImport); _importName = screen.Name; EnumerateTitleScreenFiles(); Task.Delay(2000).ContinueWith(_ => _importName = ""); } else { _importExistsScreen = screen; } } catch (Exception e) { if (screen == null) { PluginLog.Error(e, $"Failed to parse input text!"); _importParsed = false; Task.Delay(2000).ContinueWith(_ => _importParsed = true); } } } } if (!_importParsed) { ImGui.TextColored(new Vector4(1, 0, 0, 1), $"Could not parse input."); } else if (_importExistsScreen != null) { ImGui.TextColored(new Vector4(1, 0, 0, 1), $"A title screen already exists by the name {_importExistsScreen.Name}."); ImGui.Text("Would you like to save this by a different name?"); ImGui.SameLine(); if (ImGui.Button("Yes##YesImportThisFilePleaseI'mBeggingYou")) { int i = 1; while (_titleScreens.Contains(_importExistsScreen.Name + $" ({i})")) { i++; } _importExistsScreen.Name += $" ({i})"; var toImport = JsonConvert.SerializeObject(_importExistsScreen, Formatting.Indented); var fileName = Path.Combine(_titleScreenFolder, _importExistsScreen.Name + ".json"); try { File.WriteAllText(fileName, toImport); _importName = _importExistsScreen.Name; EnumerateTitleScreenFiles(); Task.Delay(2000).ContinueWith(_ => _importName = ""); } catch (Exception e) { PluginLog.Error(e, $"Failed to save {_importExistsScreen.Name} to {fileName}"); _importError = _importExistsScreen.Name; Task.Delay(2000).ContinueWith(_ => _importError = ""); } _importExistsScreen = null; _importRef = ""; } } if (!string.IsNullOrEmpty(_importName)) { ImGui.TextColored(new Vector4(0, 1, 0, 1), $"Successfully imported {_importName}"); } else if (!string.IsNullOrEmpty(_importName)) { ImGui.TextColored(new Vector4(1, 0, 0, 1), $"Failed to import {_importError}. Please check the log!"); } } if (ImGui.CollapsingHeader("Installed Screens")) { var width = GuiScale(_widestScreenName + 100); ImGui.BeginChild("scrollingCustomList", new Vector2(width, -1), true, ImGuiWindowFlags.HorizontalScrollbar); foreach (var titleScreen in _titleScreensExport) { ImGui.Text(titleScreen); ImGui.SameLine(); ImGui.SetCursorPosX(GuiScale(_widestScreenName + 15f)); if (ImGui.Button($"Delete##{titleScreen}")) { try { File.Delete(GetTitlePath(titleScreen)); if (_customTsName == titleScreen) { _nameAlreadyExists = false; } EnumerateTitleScreenFiles(); } catch (Exception e) { PluginLog.Error(e, $"Could not delete title file for {titleScreen} from {GetTitlePath(titleScreen)}"); } } } ImGui.EndChild(); ImGui.SameLine(); if (ImGui.Button("Open presets folder")) { Process.Start(new ProcessStartInfo(_titleScreenFolder) { UseShellExecute = true }); } } ImGui.EndChild(); ImGui.EndTabItem(); }
private void DrawCreation() { if (!ImGui.BeginTabItem("Create")) { return; } ImGui.Text("This tab allows you to create a custom title screen."); ImGui.Text("It is recommended to use first-person view."); #if DEBUG ImGui.BeginChild("scrolling", new Vector2(0, GuiScale(400)), true, ImGuiWindowFlags.NoScrollbar); #else ImGui.BeginChild("scrolling", new Vector2(0, GuiScale(400)), true, ImGuiWindowFlags.NoScrollWithMouse | ImGuiWindowFlags.NoScrollbar); #endif bool stateInvalid; BgmInfo selectedBgm = new BgmInfo { Title = "Unknown", FilePath = "" }; Vector3 eyesPos = default; Vector3 lookAt = default; #if !DEBUG if (_clientState.LocalPlayer?.Position == null) { ImGui.TextColored(new Vector4(1f, 0f, 0f, 1f), "The current game state is invalid for creating a title screen."); stateInvalid = true; _nameEmpty = false; //hax } else #endif { ImGui.Text("Name of custom title screen:"); ImGui.SameLine(); ImGui.SetNextItemWidth(GuiScale(280f)); if (ImGui.InputText("##title_screen_name", ref _customTsName, 64)) { _nameEmpty = false; _nameContainsInvalidCharacters = false; _nameAlreadyExists = false; if (string.IsNullOrEmpty(_customTsName)) { _nameEmpty = true; } else if (_customTsName.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0 || _customTsName.StartsWith("TE_")) { _nameContainsInvalidCharacters = true; } else { _titleScreenSavePath = Path.Combine(_titleScreenFolder, _customTsName + ".json"); if (File.Exists(_titleScreenSavePath) || _customTsName == "Random" || _customTsName == "Random (custom)") { _nameAlreadyExists = true; } } } stateInvalid = _nameAlreadyExists | _nameContainsInvalidCharacters | _nameEmpty; ImGui.Text("Logo setting:"); ImGui.SameLine(); if (_titleLogosCreate[_selectedLogoIndexCreate] != "Unspecified") { ImGui.SetNextItemWidth(GuiScale(263f)); } else { ImGui.SetNextItemWidth(GuiScale(368f)); } ImGui.Combo("##titleeditLogoSetting", ref _selectedLogoIndexCreate, _titleLogosCreate, _titleLogosCreate.Length); if (_titleLogosCreate[_selectedLogoIndexCreate] != "Unspecified") { ImGui.SameLine(); ImGui.Checkbox("Display logo", ref _selectedLogoVisibleCreate); } #if DEBUG ImGui.Text("Terri path:"); ImGui.SameLine(); ImGui.SetNextItemWidth(GuiScale(220f)); ImGui.InputText("##manualTerritype", ref _terriPath, 64); var search = _territoryPaths.Values.Where(row => row.Bg == _terriPath); var results = search as TerritoryType[] ?? search.ToArray(); if (results.Any()) { var val = results[0]; ImGui.SameLine(); ImGui.PushTextWrapPos(GuiScale(450f)); ImGui.TextWrapped($"{val.PlaceName.Value.Name}"); ImGui.PopTextWrapPos(); } #else if (!_territoryPaths.ContainsKey(_clientState.TerritoryType)) { ImGui.TextColored(new Vector4(1f, 0f, 0f, 1f), "The current territory is not valid for a title screen."); stateInvalid = true; } else { ImGui.Text($"Title screen zone: {_territoryPaths[_clientState.TerritoryType].PlaceName.Value.Name}"); } #endif eyesPos = EyesPos(_clientState.LocalPlayer?.Position ?? new Vector3 { X = 0, Y = 0, Z = 0 }); ImGui.Text($"Camera position: {eyesPos.X:F2}, {eyesPos.Y:F2}, {eyesPos.Z:F2}"); lookAt = LookAt(new Vector3(eyesPos.X, eyesPos.Y, eyesPos.Z)); ImGui.Text($"\"Fix-on\" position: {lookAt.X:F2}, {lookAt.Y:F2}, {lookAt.Z:F2}"); ImGui.Text("Title camera FOV (in-game FoV will not change)"); ImGui.SameLine(); ImGui.SetNextItemWidth(GuiScale(128f)); ImGui.SliderFloat("##customTsFovY", ref _fovY, 0.01f, 3f, "%.2f"); ImGui.SameLine(); if (ImGui.Button("Reset##resetFovY")) { _fovY = 1f; } // Weather var newType = _clientState.TerritoryType; if (newType != _lastTerritoryId) { _lastTerritoryId = newType; UpdateWeathers(newType); } byte currentWeather = _titleEdit.GetWeather(); ImGui.Text($"Current weather: {GetWeatherDescriptor(currentWeather)}"); ImGui.SameLine(); ImGui.SetCursorPosX(GuiScale(383f)); if (ImGui.Button("Set Current##weather")) { _inputIntWeatherId = currentWeather; _weatherId = currentWeather; if (_territoryWeathers != null) { for (int i = 0; i < _territoryWeathers.Length; i++) { if (_territoryWeathers[i] != _weatherId) { continue; } _selectedWeatherIndex = i; break; } } } ImGui.Text("Title zone weather:"); ImGui.SameLine(); #if !DEBUG if (_territoryWeathers == null || _territoryWeathers.Length == 0) #endif { ImGui.SetNextItemWidth(GuiScale(90)); if (ImGui.InputInt("##customTSweather", ref _inputIntWeatherId)) { _weatherId = _inputIntWeatherId; } } #if !DEBUG else { ImGui.SetNextItemWidth(GuiScale(332f)); if (ImGui.BeginCombo("##customTSweatherCombo", GetWeatherDescriptor(_territoryWeathers[_selectedWeatherIndex]))) { for (int i = 0; i < _territoryWeathers.Length; i++) { if (ImGui.Selectable(GetWeatherDescriptor(_territoryWeathers[i]))) { _selectedWeatherIndex = i; _weatherId = _territoryWeathers[_selectedWeatherIndex]; } } ImGui.EndCombo(); } } #endif if (_weatherId < 1 || _weatherId > 255 || !_weathers.ContainsKey((uint)_inputIntWeatherId)) { ImGui.SameLine(); ImGui.TextColored(new Vector4(1f, 0f, 0f, 1f), "(invalid)"); stateInvalid = true; } else if (_territoryWeathers == null || _territoryWeathers.Length == 0) { ImGui.SameLine(); ImGui.Text(GetWeatherDescriptor((ushort)_weatherId)); } // Music ushort currentBgmId = _titleEdit.GetSong(); var currentBgm = _bgmSheet.GetBgmInfo(currentBgmId); if (_lastBgmId != currentBgmId) { _lastBgmId = currentBgmId; UpdateBgmDescription(currentBgmId, currentBgm); } ImGui.Text("Current song:"); ImGui.SameLine(); ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(0.5f, 0.5f, 0.5f, 1)); ImGui.Text(_songDescription); ImGui.PopStyleColor(); if (ImGui.IsItemHovered()) { DrawBgmTooltip(currentBgm); } ImGui.SameLine(); ImGui.SetCursorPosX(GuiScale(383f)); if (ImGui.Button("Set Current##music")) { _selectedBgmId = currentBgmId; } ImGui.Text("Title zone music:"); ImGui.SameLine(); ImGui.SetNextItemWidth(GuiScale(150f)); ImGui.InputInt("##customTSmusic", ref _selectedBgmId); selectedBgm = _bgmSheet.GetBgmInfo((ushort)_selectedBgmId); if (ImGui.IsItemHovered()) { DrawBgmTooltip(selectedBgm); } ImGui.SameLine(); if (_selectedBgmId < 1 || currentBgm.Title == "Invalid") { ImGui.TextColored(new Vector4(1f, 0f, 0f, 1f), "(invalid)"); stateInvalid = true; } else { ImGui.TextWrapped($"{selectedBgm.Title}"); } // Time long etS = 0; unsafe { etS = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance()->EorzeaTime; } var et = DateTimeOffset.FromUnixTimeSeconds(etS); ImGui.Text($"Current time: {et.Hour:D2}:{et.Minute:D2}"); ImGui.SameLine(); ImGui.SetCursorPosX(GuiScale(383f)); if (ImGui.Button("Set Current##time")) { _tsTimeHrs = et.Hour; _tsTimeMin = et.Minute; var scaled = _tsTimeMin / 60f * 100; _tsTimeOffset = (int)(_tsTimeHrs * 100 + scaled % 100); } ImGui.Text("Time:"); ImGui.SameLine(); float timeWidth = GuiScale(50f); ImGui.SetNextItemWidth(timeWidth); if (ImGui.InputInt("hrs", ref _tsTimeHrs, 0, 23)) { var scaled = _tsTimeMin / 60f * 100; _tsTimeOffset = (int)(_tsTimeHrs * 100 + scaled % 100); } ImGui.SameLine(); ImGui.SetNextItemWidth(timeWidth); if (ImGui.InputInt("mins", ref _tsTimeMin, 0, 59)) { var scaled = _tsTimeMin / 60f * 100; _tsTimeOffset = (int)(_tsTimeHrs * 100 + scaled % 100); } } #if DEBUG ImGui.Text($"_stateInvalid: {stateInvalid}"); ImGui.Text($"_nameEmpty: {_nameEmpty}"); ImGui.Text($"_fileWasCreatedRecently: {_fileWasCreatedRecently}"); ImGui.Text($"_nameAlreadyExists: {_nameAlreadyExists}"); ImGui.Text($"_nameContainsInvalidCharacters: {_nameContainsInvalidCharacters}"); #endif ImGui.EndChild(); if (_fileWasCreatedRecently) { ImGui.TextColored(new Vector4(0f, 1f, 0f, 1f), "Title screen created!"); ImGui.EndTabItem(); return; } if (_nameEmpty) { ImGui.TextColored(new Vector4(1f, 0f, 0f, 1f), "The title screen name is empty."); } if (_nameAlreadyExists) { ImGui.TextColored(new Vector4(1f, 0f, 0f, 1f), "A custom title screen already exists by this name."); } else if (_nameContainsInvalidCharacters) { ImGui.TextColored(new Vector4(1f, 0f, 0f, 1f), "Title must be a valid filename without extension."); } if (stateInvalid) { ImGui.EndTabItem(); return; } if (ImGui.Button("Generate")) { TitleEditScreen scr = new TitleEditScreen(); scr.Name = _customTsName; scr.Logo = _titleLogosCreate[_selectedLogoIndexCreate]; scr.DisplayLogo = _selectedLogoVisibleCreate; #if DEBUG scr.TerritoryPath = _terriPath; #else scr.TerritoryPath = _territoryPaths[_clientState.TerritoryType].Bg.ToString(); #endif scr.CameraPos = eyesPos; scr.FixOnPos = lookAt; scr.FovY = _fovY; scr.WeatherId = (byte)_weatherId; scr.TimeOffset = (ushort)_tsTimeOffset; scr.BgmPath = selectedBgm.FilePath; var text = JsonConvert.SerializeObject(scr, Formatting.Indented); bool createSuccess = false; try { File.WriteAllText(_titleScreenSavePath, text); EnumerateTitleScreenFiles(); createSuccess = true; } catch (Exception e) { PluginLog.LogError(e, "Error occurred saving title screen."); } if (createSuccess) { _nameAlreadyExists = true; _fileWasCreatedRecently = true; Task.Delay(2000).ContinueWith(_ => _fileWasCreatedRecently = false); } } ImGui.EndTabItem(); }