diff --git a/ChatTwo/Configuration.cs b/ChatTwo/Configuration.cs
index a64accf..79d9123 100755
--- a/ChatTwo/Configuration.cs
+++ b/ChatTwo/Configuration.cs
@@ -240,6 +240,14 @@ internal class Tab
public bool CanMove = true;
public bool CanResize = true;
+ public bool IndependentHide;
+ public bool HideDuringCutscenes = true;
+ public bool HideWhenNotLoggedIn = true;
+ public bool HideWhenUiHidden = true;
+ public bool HideInLoadingScreens;
+ public bool HideInBattle;
+ public bool HideWhenInactive;
+
[NonSerialized] public uint Unread;
[NonSerialized] public long LastActivity;
[NonSerialized] public MessageList Messages = new();
@@ -285,6 +293,13 @@ internal class Tab
CurrentChannel = CurrentChannel,
CanMove = CanMove,
CanResize = CanResize,
+ IndependentHide = IndependentHide,
+ HideDuringCutscenes = HideDuringCutscenes,
+ HideWhenNotLoggedIn = HideWhenNotLoggedIn,
+ HideWhenUiHidden = HideWhenUiHidden,
+ HideInLoadingScreens = HideInLoadingScreens,
+ HideInBattle = HideInBattle,
+ HideWhenInactive = HideWhenInactive,
};
}
diff --git a/ChatTwo/GameFunctions/Chat.cs b/ChatTwo/GameFunctions/Chat.cs
index 44176ac..f256119 100755
--- a/ChatTwo/GameFunctions/Chat.cs
+++ b/ChatTwo/GameFunctions/Chat.cs
@@ -561,4 +561,14 @@ internal sealed unsafe class Chat : IDisposable
_ => playerName
};
}
+
+ internal bool CheckHideFlags()
+ {
+ // Only hide the chat in a cutscene when the vanilla chat would've
+ // also been hidden. This prevents Chat 2 from hiding for a split
+ // second before the cutscene actually starts, because the game sets
+ // the cutscene conditions before processing the skip.
+ var raptureAtkUnitManager = RaptureAtkUnitManager.Instance();
+ return raptureAtkUnitManager == null || raptureAtkUnitManager->UiFlags.HasFlag(UIModule.UiFlags.Chat);
+ }
}
diff --git a/ChatTwo/Plugin.cs b/ChatTwo/Plugin.cs
index 001158d..bf05741 100755
--- a/ChatTwo/Plugin.cs
+++ b/ChatTwo/Plugin.cs
@@ -242,4 +242,8 @@ public sealed class Plugin : IDalamudPlugin
if (GameFunctions.GameFunctions.IsAddonInteractable(name))
GameFunctions.GameFunctions.SetAddonInteractable(name, false);
}
+
+ public static bool InBattle => Condition[ConditionFlag.InCombat];
+ public static bool GposeActive => Condition[ConditionFlag.WatchingCutscene];
+ public static bool CutsceneActive => Condition[ConditionFlag.OccupiedInCutSceneEvent] || Condition[ConditionFlag.WatchingCutscene78];
}
diff --git a/ChatTwo/Resources/Language.Designer.cs b/ChatTwo/Resources/Language.Designer.cs
index 9688f9a..85d3a3e 100755
--- a/ChatTwo/Resources/Language.Designer.cs
+++ b/ChatTwo/Resources/Language.Designer.cs
@@ -3236,6 +3236,15 @@ namespace ChatTwo.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to Use different hide condition than main window.
+ ///
+ internal static string Options_Tabs_IndependentHide {
+ get {
+ return ResourceManager.GetString("Options_Tabs_IndependentHide", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Use different opacity than main window.
///
diff --git a/ChatTwo/Resources/Language.resx b/ChatTwo/Resources/Language.resx
index dd7f74f..218ea20 100644
--- a/ChatTwo/Resources/Language.resx
+++ b/ChatTwo/Resources/Language.resx
@@ -541,6 +541,9 @@
Opacity
+
+ Use different hide condition than main window
+
Enable custom fonts
diff --git a/ChatTwo/Ui/ChatLogWindow.cs b/ChatTwo/Ui/ChatLogWindow.cs
index cef664e..ec23bfa 100644
--- a/ChatTwo/Ui/ChatLogWindow.cs
+++ b/ChatTwo/Ui/ChatLogWindow.cs
@@ -369,10 +369,6 @@ public sealed class ChatLogWindow : Window
Plugin.ServerCore.SendNewLogin();
}
- internal static bool InBattle => Plugin.Condition[ConditionFlag.InCombat];
- private static bool GposeActive => Plugin.Condition[ConditionFlag.WatchingCutscene];
- private static bool CutsceneActive => Plugin.Condition[ConditionFlag.OccupiedInCutSceneEvent] || Plugin.Condition[ConditionFlag.WatchingCutscene78];
-
private enum HideState
{
None,
@@ -385,30 +381,25 @@ public sealed class ChatLogWindow : Window
private HideState CurrentHideState = HideState.None;
public bool IsHidden;
- public unsafe void HideStateCheck()
+ public void HideStateCheck()
{
// if the chat has no hide state set, and the player has entered battle, we hide chat if they have configured it
- if (Plugin.Config.HideInBattle && CurrentHideState == HideState.None && InBattle)
+ if (Plugin.Config.HideInBattle && CurrentHideState == HideState.None && Plugin.InBattle)
CurrentHideState = HideState.Battle;
// If the chat is hidden because of battle, we reset it here
- if (CurrentHideState is HideState.Battle && !InBattle)
+ if (CurrentHideState is HideState.Battle && !Plugin.InBattle)
CurrentHideState = HideState.None;
// if the chat has no hide state and in a cutscene, set the hide state to cutscene
- if (Plugin.Config.HideDuringCutscenes && CurrentHideState == HideState.None && (CutsceneActive || GposeActive))
+ if (Plugin.Config.HideDuringCutscenes && CurrentHideState == HideState.None && (Plugin.CutsceneActive || Plugin.GposeActive))
{
- // Only hide the chat in a cutscene when the vanilla chat would've
- // also been hidden. This prevents Chat 2 from hiding for a split
- // second before the cutscene actually starts, because the game sets
- // the cutscene conditions before processing the skip.
- var raptureAtkUnitManager = RaptureAtkUnitManager.Instance();
- if (raptureAtkUnitManager == null || raptureAtkUnitManager->UiFlags.HasFlag(UIModule.UiFlags.Chat))
+ if (Plugin.Functions.Chat.CheckHideFlags())
CurrentHideState = HideState.Cutscene;
}
// if the chat is hidden because of a cutscene and no longer in a cutscene, set the hide state to none
- if (CurrentHideState is HideState.Cutscene or HideState.CutsceneOverride && !CutsceneActive && !GposeActive)
+ if (CurrentHideState is HideState.Cutscene or HideState.CutsceneOverride && !Plugin.CutsceneActive && !Plugin.GposeActive)
CurrentHideState = HideState.None;
// if the chat is hidden because of a cutscene and the chat has been activated, show chat
@@ -453,7 +444,7 @@ public sealed class ChatLogWindow : Window
if (IsHidden)
return false;
- if (!Plugin.Config.HideWhenInactive || (!Plugin.Config.InactivityHideActiveDuringBattle && InBattle) || Activate)
+ if (!Plugin.Config.HideWhenInactive || (!Plugin.Config.InactivityHideActiveDuringBattle && Plugin.InBattle) || Activate)
{
LastActivityTime = FrameTime;
return true;
diff --git a/ChatTwo/Ui/Popout.cs b/ChatTwo/Ui/Popout.cs
index e6c9d98..7a0b395 100644
--- a/ChatTwo/Ui/Popout.cs
+++ b/ChatTwo/Ui/Popout.cs
@@ -38,10 +38,10 @@ internal class Popout : Window
public override bool DrawConditions()
{
FrameTime = Environment.TickCount64;
- if (ChatLogWindow.IsHidden)
+ if (Tab.IndependentHide ? HideStateCheck() : ChatLogWindow.IsHidden)
return false;
- if (!Plugin.Config.HideWhenInactive || (!Plugin.Config.InactivityHideActiveDuringBattle && ChatLogWindow.InBattle) || !Tab.UnhideOnActivity)
+ if (!Plugin.Config.HideWhenInactive || (!Plugin.Config.InactivityHideActiveDuringBattle && Plugin.InBattle) || !Tab.UnhideOnActivity)
{
LastActivityTime = FrameTime;
return true;
@@ -108,4 +108,47 @@ internal class Popout : Window
Tab.PopOut = false;
ChatLogWindow.Plugin.SaveConfig();
}
+
+ private enum HideState
+ {
+ None,
+ Cutscene,
+ CutsceneOverride,
+ User,
+ Battle
+ }
+
+ private HideState CurrentHideState = HideState.None;
+
+ private bool HideStateCheck()
+ {
+ // if the chat has no hide state set, and the player has entered battle, we hide chat if they have configured it
+ if (Tab.HideInBattle && CurrentHideState == HideState.None && Plugin.InBattle)
+ CurrentHideState = HideState.Battle;
+
+ // If the chat is hidden because of battle, we reset it here
+ if (CurrentHideState is HideState.Battle && !Plugin.InBattle)
+ CurrentHideState = HideState.None;
+
+ // if the chat has no hide state and in a cutscene, set the hide state to cutscene
+ if (Tab.HideDuringCutscenes && CurrentHideState == HideState.None && (Plugin.CutsceneActive || Plugin.GposeActive))
+ {
+ if (ChatLogWindow.Plugin.Functions.Chat.CheckHideFlags())
+ CurrentHideState = HideState.Cutscene;
+ }
+
+ // if the chat is hidden because of a cutscene and no longer in a cutscene, set the hide state to none
+ if (CurrentHideState is HideState.Cutscene or HideState.CutsceneOverride && !Plugin.CutsceneActive && !Plugin.GposeActive)
+ CurrentHideState = HideState.None;
+
+ // if the chat is hidden because of a cutscene and the chat has been activated, show chat
+ if (CurrentHideState == HideState.Cutscene && ChatLogWindow.Activate)
+ CurrentHideState = HideState.CutsceneOverride;
+
+ // if the user hid the chat and is now activating chat, reset the hide state
+ if (CurrentHideState == HideState.User && ChatLogWindow.Activate)
+ CurrentHideState = HideState.None;
+
+ return CurrentHideState is HideState.Cutscene or HideState.User or HideState.Battle || (Tab.HideWhenNotLoggedIn && !Plugin.ClientState.IsLoggedIn);
+ }
}
diff --git a/ChatTwo/Ui/SettingsTabs/Tabs.cs b/ChatTwo/Ui/SettingsTabs/Tabs.cs
index e77f655..906410a 100755
--- a/ChatTwo/Ui/SettingsTabs/Tabs.cs
+++ b/ChatTwo/Ui/SettingsTabs/Tabs.cs
@@ -88,10 +88,31 @@ internal sealed class Tabs : ISettingsTab
ImGui.Checkbox(Language.Options_Tabs_PopOut, ref tab.PopOut);
if (tab.PopOut)
{
+ using var _ = ImRaii.PushIndent(10.0f);
ImGui.Checkbox(Language.Options_Tabs_IndependentOpacity, ref tab.IndependentOpacity);
if (tab.IndependentOpacity)
ImGuiUtil.DragFloatVertical(Language.Options_Tabs_Opacity, ref tab.Opacity, 0.25f, 0f, 100f, $"{tab.Opacity:N2}%%", ImGuiSliderFlags.AlwaysClamp);
+ ImGui.Checkbox(Language.Options_Tabs_IndependentHide, ref tab.IndependentHide);
+ if (tab.IndependentHide)
+ {
+ using var __ = ImRaii.PushIndent(10.0f);
+ ImGuiUtil.OptionCheckbox(ref tab.HideDuringCutscenes, Language.Options_HideDuringCutscenes_Name);
+ ImGui.Spacing();
+
+ ImGuiUtil.OptionCheckbox(ref tab.HideWhenNotLoggedIn, Language.Options_HideWhenNotLoggedIn_Name);
+ ImGui.Spacing();
+
+ ImGuiUtil.OptionCheckbox(ref tab.HideWhenUiHidden, Language.Options_HideWhenUiHidden_Name);
+ ImGui.Spacing();
+
+ ImGuiUtil.OptionCheckbox(ref tab.HideInLoadingScreens, Language.Options_HideInLoadingScreens_Name);
+ ImGui.Spacing();
+
+ ImGuiUtil.OptionCheckbox(ref tab.HideInBattle, Language.Options_HideInBattle_Name);
+ ImGui.Spacing();
+ }
+
ImGuiUtil.OptionCheckbox(ref tab.CanMove, Language.Popout_CanMove_Name);
ImGui.Spacing();