From 5525dcaf63bd698e54e88fd4c9b1e3c5df9d0ed9 Mon Sep 17 00:00:00 2001 From: simon Date: Sun, 21 Jan 2024 17:24:09 -0500 Subject: [PATCH] update and ui fixes --- Data/credits.png | Bin 8806 -> 3021 bytes OofPlugin/DalamudPackager.targets | 9 --- OofPlugin/OofPlugin.cs | 36 ++++++++- OofPlugin/OofPlugin.csproj | 11 ++- OofPlugin/OofPlugin.yaml | 15 ++-- OofPlugin/PluginUI.cs | 118 ++++++++++++++++++++++-------- OofPlugin/PluginUIComponents.cs | 59 +++++++++------ 7 files changed, 172 insertions(+), 76 deletions(-) delete mode 100644 OofPlugin/DalamudPackager.targets diff --git a/Data/credits.png b/Data/credits.png index 2135cc94ab7f2fd5b51e40f558af493c7cc11445..f2ac09e125ba9f7cc11dfcd2a9b52e1546c5e9f7 100644 GIT binary patch literal 3021 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 - - - - \ No newline at end of file diff --git a/OofPlugin/OofPlugin.cs b/OofPlugin/OofPlugin.cs index 048b239..2ae75fe 100644 --- a/OofPlugin/OofPlugin.cs +++ b/OofPlugin/OofPlugin.cs @@ -3,16 +3,20 @@ using Dalamud.Game.ClientState.Conditions; using Dalamud.Game.ClientState.Party; using Dalamud.Game.Command; +using Dalamud.Interface.Utility.Table; using Dalamud.IoC; using Dalamud.Plugin; +using Dalamud.Plugin.Ipc.Exceptions; using Dalamud.Plugin.Services; using Dalamud.Utility; +using FFXIVClientStructs.FFXIV.Client.System.Framework; using NAudio.Wave; using System; using System.IO; using System.Linq; using System.Numerics; using System.Threading; +using static Lumina.Data.Parsing.Layer.LayerCommon; using Task = System.Threading.Tasks.Task; //shoutout anna clemens @@ -43,7 +47,6 @@ public sealed class OofPlugin : IDalamudPlugin // i love global variables!!!! the more global the more globaly it gets // sound public bool isSoundPlaying { get; set; } = false; - // private WaveStream? reader; private DirectSoundOut? soundOut; private string? soundFile { get; set; } @@ -305,10 +308,11 @@ private async Task OofAudioPolling(CancellationToken token) { if (player.DidPlayOof) continue; float volume = 1f; - if (Configuration.DistanceBasedOof && player.Distance != Vector3.Zero && player.Distance != ClientState!.LocalPlayer!.Position) + if (Configuration.DistanceBasedOof && player.Distance != ClientState!.LocalPlayer!.Position) { - var dist = Vector3.Distance(ClientState!.LocalPlayer!.Position, player.Distance); - volume = Math.Max(Configuration.DistanceMinVolume, 1f / (dist * Configuration.DistanceFalloff)); + var dist = 0f; + if (player.Distance != Vector3.Zero) dist = Vector3.Distance(ClientState!.LocalPlayer!.Position, player.Distance); + volume = CalcVolumeFromDist(dist); } PlaySound(token, volume); player.DidPlayOof = true; @@ -317,6 +321,30 @@ private async Task OofAudioPolling(CancellationToken token) } } } + public float CalcVolumeFromDist(float dist,float distMax = 30) + { + if (dist > distMax) dist = distMax; + var falloff = Configuration.DistanceFalloff > 0 ? 3f - Configuration.DistanceFalloff*3f : 3f - 0.001f; + var vol = 1f - ((dist / distMax) * ( 1 / falloff)); + return Math.Max(Configuration.DistanceMinVolume, vol); + } + + public async Task TestDistanceAudio(CancellationToken token) + { + async Task CheckthenPlay(float volume) + { + if (token.IsCancellationRequested) return; + + PlaySound(token, volume); + await Task.Delay(500, token); + } + await CheckthenPlay(CalcVolumeFromDist(0)); + await CheckthenPlay(CalcVolumeFromDist(10)); + await CheckthenPlay(CalcVolumeFromDist(20)); + await CheckthenPlay(CalcVolumeFromDist(30)); + + } + /// /// dispose diff --git a/OofPlugin/OofPlugin.csproj b/OofPlugin/OofPlugin.csproj index b19f070..cc21cab 100644 --- a/OofPlugin/OofPlugin.csproj +++ b/OofPlugin/OofPlugin.csproj @@ -3,8 +3,8 @@ Frogworks Interactive Frogworks Interactive - 1.2.3.0 - 1.2.3.0 + 1.3.0.0 + 1.3.0.0 OOF! @@ -85,4 +85,11 @@ + + + + Never + + + diff --git a/OofPlugin/OofPlugin.yaml b/OofPlugin/OofPlugin.yaml index 811cb4f..6afa02a 100644 --- a/OofPlugin/OofPlugin.yaml +++ b/OofPlugin/OofPlugin.yaml @@ -1,19 +1,16 @@ name: OOF! author: Frogworks Interactive -punchline: Play the OOF! sound on fall and/or death. The Only Plugin You Need! +punchline: Play OOF! on fall and/or death. The Only Plugin You Need! description: |- i love roblox!!! - craaazzzy features - - oof on party & alliance deaths! - - use custom mp3 sounds! - - DBO© (Distance Based Oof)! - - instant access to the hour long documentary on oof by hbomberguy! - - fully featured settings window! + whimsical and magical features... + - when other ppl die + - custom mp3 + - instant access to the hour long documentary on oof by hbomberguy repo_url: https://github.com/Frogworks-Interactive/OOF internal_name: OofPlugin -dalamud_api_level: 9 tags: - Oof - Fall Damage @@ -22,4 +19,4 @@ tags: - Alarm - Roblox - Obby - - Sound \ No newline at end of file + - Sound diff --git a/OofPlugin/PluginUI.cs b/OofPlugin/PluginUI.cs index 922b046..76224a9 100644 --- a/OofPlugin/PluginUI.cs +++ b/OofPlugin/PluginUI.cs @@ -7,6 +7,7 @@ using Dalamud.Plugin; using Dalamud.Utility; using ImGuiNET; +using ImPlotNET; using ImGuiScene; using System; using System.IO; @@ -51,11 +52,15 @@ public void DrawSettingsWindow() { if (!SettingsVisible) return; // i miss html/css - ImGui.SetNextWindowSize(new Vector2(355, 560), ImGuiCond.Appearing); + ImGui.SetNextWindowSize(new Vector2(355, 700), ImGuiCond.Appearing); if (ImGui.Begin("oof options", ref settingsVisible, ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse)) { - // volume with icons + + + AddLoadAudioUI(); + + /// volume cntrol ----- var oofVolume = configuration.Volume; var headingColor = ImGuiColors.DalamudGrey; ImGuiHelpers.SafeTextColoredWrapped(headingColor, "Volume"); @@ -72,12 +77,11 @@ public void DrawSettingsWindow() ImGui.SameLine(); ImGui.AlignTextToFramePadding(); IconTextColor(FontAwesomeIcon.VolumeUp.ToIconString(), headingColor); + /// end volume control ----- + ImGui.Spacing(); ImGui.Spacing(); - - LoadAudioUI(); ImGui.Spacing(); - ImGui.Separator(); ImGui.Spacing(); //ImGuiComponents.HelpMarker( @@ -109,7 +113,7 @@ public void DrawSettingsWindow() if (!oofOnFall) ImGui.EndDisabled(); SectionEnd(ref fallOptionsHeight, oofOnFall ? ImGuiCol.PopupBg : ImGuiCol.TitleBg); - + ImGui.Spacing(); // when people die options SectionStart(deathOptionsHeight); var oofOnDeath = configuration.OofOnDeath; @@ -117,24 +121,30 @@ public void DrawSettingsWindow() SectionHeader("Death", ref oofOnDeath, () => { configuration.OofOnDeath = oofOnDeath; }); if (!oofOnDeath) ImGui.BeginDisabled(); + + + ImGui.Columns(2); - var oofOnDeathSelf = configuration.OofOnDeathSelf; - if (ImGui.Checkbox("Self dies###death:self", ref oofOnDeathSelf)) + var oofInBattle = configuration.OofOnDeathBattle; + + if (ImGui.Checkbox("During combat###death:combat", ref oofInBattle)) { - configuration.OofOnDeathSelf = oofOnDeathSelf; + configuration.OofOnDeathBattle = oofInBattle; configuration.Save(); } + ImGui.NextColumn(); - var oofInBattle = configuration.OofOnDeathBattle; + var oofOnDeathSelf = configuration.OofOnDeathSelf; - if (ImGui.Checkbox("During combat###death:combat", ref oofInBattle)) + if (ImGui.Checkbox("Self dies###death:self", ref oofOnDeathSelf)) { - configuration.OofOnDeathBattle = oofInBattle; + configuration.OofOnDeathSelf = oofOnDeathSelf; configuration.Save(); } - ImGui.NextColumn(); + + var oofOthersInParty = configuration.OofOnDeathParty; if (ImGui.Checkbox("Party member dies###death:party", ref oofOthersInParty)) @@ -150,9 +160,11 @@ public void DrawSettingsWindow() configuration.Save(); } ImGui.Columns(1); + + ImGui.Spacing(); + ImGui.Spacing(); - ImGui.Separator(); // distance based oof ImGui.Spacing(); @@ -162,15 +174,62 @@ public void DrawSettingsWindow() configuration.DistanceBasedOof = distanceBasedOof; configuration.Save(); } - ImGui.SameLine(); - ImGuiComponents.HelpMarker( - "change volume based on how far away \nthe player dies from you"); + if (!distanceBasedOof) ImGui.BeginDisabled(); - ImGui.Columns(2); + + ImGui.SameLine(ImGui.GetContentRegionAvail().X - ImGui.GetFontSize() * 2.4f); + ImGui.PushFont(UiBuilder.IconFont); + + if (CornerButton(FontAwesomeIcon.Play.ToIconString(), "dbo:play", ImDrawFlags.RoundCornersLeft)) plugin.TestDistanceAudio(plugin.CancelToken.Token); + ImGui.PopFont(); + if (ImGui.IsItemHovered()) ImGui.SetTooltip("Test distance"); + + ImGui.SameLine(0, 0); + ImGui.PushFont(UiBuilder.IconFont); + + if (CornerButton(FontAwesomeIcon.Stop.ToIconString(), "dbo:stop", ImDrawFlags.RoundCornersRight)) plugin.StopSound(); + ImGui.PopFont(); - if (!distanceBasedOof) ImGui.BeginDisabled(); + ImGuiHelpers.SafeTextColoredWrapped(ImGuiColors.DalamudGrey, "Lower volume based on how far someone dies from you, from 0 to 30 yalms"); + + + + /// graph + var steps = 800; + var distancePoints = new float[steps]; + var volumemPoints = new float[steps]; + var step = 30f / steps; + for (int i = 0; i < steps; i++) + { + distancePoints[i] = step * i; + volumemPoints[i] = plugin.CalcVolumeFromDist(step * i); + + } + if (ImPlot.BeginPlot("##dbo:graph", new Vector2(-1, 80), ImPlotFlags.CanvasOnly)) + { + ImPlot.PushStyleColor(ImPlotCol.FrameBg, new Vector4(0, 0, 0, 0)); + ImPlot.PushStyleColor(ImPlotCol.AxisBgHovered, new Vector4(0, 0, 0, 0)); + ImPlot.PushStyleColor(ImPlotCol.AxisText, ImGuiColors.DalamudGrey); + + ImPlot.SetupMouseText(ImPlotLocation.North, ImPlotMouseTextFlags.None); + ImPlot.SetupLegend(ImPlotLocation.NorthEast, ImPlotLegendFlags.NoHighlightItem); + + ImPlot.SetupAxisLimitsConstraints(ImAxis.X1, 0, 30); + ImPlot.SetupAxisLimitsConstraints(ImAxis.Y1,0, 1); + ImPlot.SetupAxisZoomConstraints(ImAxis.X1, 30,30); + ImPlot.SetupAxisZoomConstraints(ImAxis.Y1, 1, 1); + ImPlot.SetupAxes(null, null, ImPlotAxisFlags.None, ImPlotAxisFlags.NoTickLabels); + ImPlot.PopStyleColor(); + ImPlot.SetupFinish(); + + ImPlot.PlotLine("volume", ref distancePoints[0], ref volumemPoints[0], steps); + + ImPlot.EndPlot(); + } + ImGui.Columns(2); + ImGuiHelpers.SafeTextColoredWrapped(headingColor, "Falloff Intensity"); var distanceFalloff = configuration.DistanceFalloff; ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X); @@ -192,30 +251,31 @@ public void DrawSettingsWindow() if (!distanceBasedOof) ImGui.EndDisabled(); ImGui.Columns(1); + if (!oofOnDeath) ImGui.EndDisabled(); SectionEnd(ref deathOptionsHeight, oofOnDeath ? ImGuiCol.PopupBg : ImGuiCol.TitleBg); + ImGui.Spacing(); ImGui.Spacing(); - - ImGui.Separator(); - // watch video! ImGui.Spacing(); + /// watch video! -------- + if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.ExternalLinkSquareAlt, "Watch on Youtube")) OofPlugin.OpenVideo(); + var desc = "Hot Tip: You can Macro the /oofvideo command to\n for easy and streamlined access to this video."; + if (ImGui.IsItemHovered()) ImGui.SetTooltip(desc); - ImGuiHelpers.SafeTextColoredWrapped(ImGuiColors.DalamudWhite2, "Learn about the history behind the Roblox Oof with Hbomberguy's Documentary:"); + ImGuiHelpers.SafeTextColoredWrapped(ImGuiColors.DalamudGrey, "Learn about the history behind the Roblox Oof with Hbomberguy's Documentary"); - if (ImGui.Button("Watch on Youtube")) OofPlugin.OpenVideo(); - var desc = "Hot Tip: You can Macro the /oofvideo command to\n for easy and streamlined access to this video."; + - if (ImGui.IsItemHovered()) ImGui.SetTooltip(desc); ImGui.Spacing(); + ImGuiHelpers.SafeTextColoredWrapped(ImGuiColors.DalamudGrey, "Original Oof sound by Joey Kuras"); + ImGui.Spacing(); - ImGui.Separator(); - ImGuiHelpers.SafeTextColoredWrapped(ImGuiColors.DalamudGrey, "Original Oof sound by Joey Kuras"); //logo - var size = new Vector2(this.creditsTexture.Width * (float)0.60, this.creditsTexture.Height * (float)0.60); + var size = new Vector2(this.creditsTexture.Width , this.creditsTexture.Height); ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, Vector2.Zero); ImGui.PushStyleVar(ImGuiStyleVar.FrameRounding, 13); ImGui.PushStyleColor(ImGuiCol.Button, new Vector4(0, 0, 0, 0)); diff --git a/OofPlugin/PluginUIComponents.cs b/OofPlugin/PluginUIComponents.cs index 30a742d..f0aebdf 100644 --- a/OofPlugin/PluginUIComponents.cs +++ b/OofPlugin/PluginUIComponents.cs @@ -5,7 +5,7 @@ using ImGuiNET; using System; using System.Numerics; - +/// ok i knooow partial class files are like not the right way to do things but like im lazy asf namespace OofPlugin { public partial class PluginUI @@ -57,7 +57,7 @@ public static void SectionStart(float height = 0f) /// end section with filled bg /// /// - public static void SectionEnd(ref float height, ImGuiCol bg = ImGuiCol.MenuBarBg, ImGuiCol border = ImGuiCol.TableBorderLight) + public static void SectionEnd(ref float height, ImGuiCol bg = ImGuiCol.MenuBarBg, ImGuiCol border = ImGuiCol.MenuBarBg) { var padding = ImGui.GetStyle().WindowPadding; ImGui.PopClipRect(); @@ -114,12 +114,19 @@ public void SectionHeader(string title, ref bool toggle, Action action1) ImGui.SameLine(); ImGuiHelpers.SafeTextColoredWrapped(ImGuiColors.DalamudWhite2, title); - ImGui.SameLine(ImGui.GetWindowWidth() - textSize.X - ImGui.GetFontSize() * 1.8f - padding.X * 2); - ImGuiHelpers.SafeTextColoredWrapped(ImGuiColors.DalamudWhite2, $"{text}"); + ImGui.SameLine(ImGui.GetWindowWidth() - textSize.X - ImGui.GetFontSize() * 1f - padding.X); + + Vector4 lowOpacityRed = ImGuiColors.DalamudRed; + lowOpacityRed[3] = 30; + var statusColor = toggle ? ImGuiColors.DalamudGrey2 : lowOpacityRed; + + ImGuiHelpers.SafeTextColoredWrapped(statusColor, $"{text}"); ImGui.SameLine(); - var iconString = toggle ? FontAwesomeIcon.CheckSquare.ToIconString() : FontAwesomeIcon.SquareXmark.ToIconString(); - IconTextColor(iconString, ImGuiColors.DalamudWhite2); + + ImGui.Spacing(); ImGui.Spacing(); + ImGui.Spacing(); + } private static void IconTextColor(string text, Vector4 color = new Vector4()) @@ -138,7 +145,12 @@ private static float CalcButtonSize(float value) { return value + ImGui.GetStyle().FramePadding.X * 2; } - private void LoadAudioUI() + + + /// + /// load audio interface + /// + private void AddLoadAudioUI() { var WindowPos = ImGui.GetWindowPos(); var windowPadding = ImGui.GetStyle().WindowPadding; @@ -147,9 +159,9 @@ private void LoadAudioUI() ImGui.AlignTextToFramePadding(); - ImGuiHelpers.SafeTextColoredWrapped(ImGuiColors.DalamudGrey, "Loaded SoundFile"); + ImGuiHelpers.SafeTextColoredWrapped(ImGuiColors.DalamudGrey, "Sound file to play"); ImGuiComponents.HelpMarker( - "You can upload a custom audio file from computer. "); + "The audio that is triggered on death/fall damage"); ImGui.SameLine(ImGui.GetWindowWidth() - CalcButtonSize(em) - windowPadding.X); if (ImGuiComponents.IconButton(FontAwesomeIcon.UndoAlt)) { @@ -159,17 +171,17 @@ private void LoadAudioUI() } if (ImGui.IsItemHovered()) - ImGui.SetTooltip("Reset audio file to oof"); + ImGui.SetTooltip("Reset audio file to default (oof)"); ImGui.PushFont(UiBuilder.IconFont); - if (CornerButton(FontAwesomeIcon.PlayCircle.ToIconString(), ImDrawFlags.RoundCornersLeft)) plugin.PlaySound(plugin.CancelToken.Token); + if (CornerButton(FontAwesomeIcon.Play.ToIconString(), "volume:play", ImDrawFlags.RoundCornersLeft)) plugin.PlaySound(plugin.CancelToken.Token); ImGui.PopFont(); if (ImGui.IsItemHovered()) ImGui.SetTooltip("Play"); ImGui.SameLine(0, 0); ImGui.PushFont(UiBuilder.IconFont); - if (CornerButton(FontAwesomeIcon.StopCircle.ToIconString(), ImDrawFlags.RoundCornersRight)) plugin.StopSound(); + if (CornerButton(FontAwesomeIcon.Stop.ToIconString(),"volume:stop", ImDrawFlags.RoundCornersRight)) plugin.StopSound(); ImGui.PopFont(); if (ImGui.IsItemHovered()) ImGui.SetTooltip("Stop"); @@ -183,13 +195,13 @@ private void LoadAudioUI() if (formatString.Success) soundFileName = formatString.Value; } - customDraggableText(soundFileName); - var browseText = "Upload Audio"; + var buttonWidth = CalcButtonSize(browseText) + ImGui.GetFontSize() * 1.4f ; + customDraggableText(soundFileName, buttonWidth); - ImGui.SameLine(ImGui.GetWindowWidth() - CalcButtonSize(browseText) - windowPadding.X); - if (ImGui.Button(browseText)) + ImGui.SameLine(); + if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.FolderOpen, browseText)) { void UpdatePath(bool success, string path) { @@ -202,21 +214,22 @@ void UpdatePath(bool success, string path) manager.OpenFileDialog("Open Audio File...", "Audio{.wav,.mp3,.aac,.wma}", UpdatePath); } - ImGui.Spacing(); + if (ImGui.IsItemHovered()) ImGui.SetTooltip("upload a custom audio file from your very own computer."); + } /// - /// theres no reason to use this over an input box but it was fun to make /// makes textbox draggable if text overflows + /// + /// theres no reason to use this over an input box but it was fun to make /// - private static void customDraggableText(string text) + private static void customDraggableText(string text,float rightsideSpacing) { var WindowPos = ImGui.GetWindowPos(); var draw = ImGui.GetWindowDrawList(); - var em = ImGui.GetFontSize(); var cursorPos = ImGui.GetCursorPos(); var panelMin = new Vector2(cursorPos.X + WindowPos.X, ImGui.GetItemRectMin().Y); - var panelMax = new Vector2(WindowPos.X + ImGui.GetContentRegionAvail().X - CalcButtonSize(em) - ImGui.GetStyle().ItemSpacing.X, ImGui.GetItemRectMax().Y); + var panelMax = new Vector2(WindowPos.X + cursorPos.X + ImGui.GetContentRegionAvail().X - rightsideSpacing - ImGui.GetStyle().WindowPadding.X, ImGui.GetItemRectMax().Y); var boxSize = panelMax - panelMin; var framePadding = ImGui.GetStyle().FramePadding; @@ -283,7 +296,7 @@ public static bool ToggleButton(string id, ref bool v) drawList.AddCircleFilled(new Vector2(p.X + radius + ((v ? 1 : 0) * (width - (radius * 2.0f))), p.Y + radius), radius - 1.5f, ImGui.GetColorU32(ImGuiColors.DalamudWhite2)); return changed; } - public static bool CornerButton(string text, ImDrawFlags flags = ImDrawFlags.None) + public static bool CornerButton(string text, string id, ImDrawFlags flags = ImDrawFlags.None) { var p = ImGui.GetCursorScreenPos(); @@ -296,7 +309,7 @@ public static bool CornerButton(string text, ImDrawFlags flags = ImDrawFlags.Non // TODO: animate // Draw content above the rectangle var changed = false; - ImGui.InvisibleButton(text, boxsize); + ImGui.InvisibleButton(text + "###"+ id, boxsize); if (ImGui.IsItemClicked()) {