- Use EndConditional

- Fix #132 (maybe)
This commit is contained in:
Infi
2024-11-21 13:59:45 +01:00
parent d0a55e80ea
commit 5bd6518e1a
4 changed files with 93 additions and 57 deletions
+8
View File
@@ -432,6 +432,14 @@ internal class UsedChannel
internal bool UseTempChannel;
internal InputChannel TempChannel = InputChannel.Invalid;
internal TellTarget? TempTellTarget;
internal void ResetTempChannel()
{
UseTempChannel = false;
TempTellTarget = null;
TempChannel = InputChannel.Invalid;
}
}
[Serializable]
+2 -2
View File
@@ -258,7 +258,7 @@ internal sealed unsafe class Chat : IDisposable
{
Channel = (InputChannel) channel,
Name = nameChunks,
TellTarget = playerName != null ? new TellTarget(playerName, worldId, 0, 0) : null,
TellTarget = playerName != null ? new TellTarget(playerName, worldId, 0, 0) : null
};
return ret;
@@ -284,7 +284,7 @@ internal sealed unsafe class Chat : IDisposable
try
{
var target = new TellTarget(playerName->ToString(), worldId, contentId, (TellReason) reason);
Plugin.ChatLogWindow.Activated(new ChatActivatedArgs(new ChannelSwitchInfo(InputChannel.Tell))
Plugin.ChatLogWindow.Activated(new ChatActivatedArgs(new ChannelSwitchInfo(InputChannel.Tell, permanent: setChatType))
{
TellReason = (TellReason) reason,
TellTarget = target,
+62 -54
View File
@@ -163,9 +163,7 @@ public sealed class ChatLogWindow : Window
var tellInfo = Plugin.Functions.Chat.GetTellHistoryInfo(idx);
if (tellInfo != null && reason != null)
{
Plugin.CurrentTab.CurrentChannel.TellTarget = new TellTarget(tellInfo.Name, (ushort) tellInfo.World, tellInfo.ContentId, reason.Value);
}
Plugin.CurrentTab.CurrentChannel.TempTellTarget = new TellTarget(tellInfo.Name, (ushort) tellInfo.World, tellInfo.ContentId, reason.Value);
}
else
{
@@ -630,8 +628,7 @@ public sealed class ChatLogWindow : Window
if (activeTab.CurrentChannel.UseTempChannel)
{
activeTab.CurrentChannel.UseTempChannel = false;
activeTab.CurrentChannel.TempChannel = InputChannel.Invalid;
activeTab.CurrentChannel.ResetTempChannel();
SetChannel(activeTab.CurrentChannel.Channel);
}
}
@@ -643,8 +640,7 @@ public sealed class ChatLogWindow : Window
if (activeTab.CurrentChannel.UseTempChannel)
{
activeTab.CurrentChannel.UseTempChannel = false;
activeTab.CurrentChannel.TempChannel = InputChannel.Invalid;
activeTab.CurrentChannel.ResetTempChannel();
SetChannel(activeTab.CurrentChannel.Channel);
}
}
@@ -666,10 +662,9 @@ public sealed class ChatLogWindow : Window
UIGlobals.PlaySoundEffect(ChatCloseSfx);
}
if (Plugin.CurrentTab.CurrentChannel.UseTempChannel)
if (activeTab.CurrentChannel.UseTempChannel)
{
Plugin.CurrentTab.CurrentChannel.UseTempChannel = false;
activeTab.CurrentChannel.TempChannel = InputChannel.Invalid;
activeTab.CurrentChannel.ResetTempChannel();
SetChannel(Plugin.CurrentTab.CurrentChannel.Channel);
}
}
@@ -763,50 +758,42 @@ public sealed class ChatLogWindow : Window
DrawChunks(currentChannel);
}
internal Chunk[] ReadChannelName(Tab activeTab)
private Chunk[] ReadChannelName(Tab activeTab)
{
Chunk[] channelNameChunks;
if (activeTab.CurrentChannel.TellTarget != null && activeTab.CurrentChannel.TellTarget.IsSet())
// Check the temp channel before others
if (activeTab.CurrentChannel.UseTempChannel)
{
var playerName = activeTab.CurrentChannel.TellTarget.Name;
if (ScreenshotMode)
// Note: don't use HidePlayerInString here because
// abbreviation settings do not affect this.
playerName = HashPlayer(activeTab.CurrentChannel.TellTarget.Name, activeTab.CurrentChannel.TellTarget.World);
var world = Sheets.WorldSheet.TryGetRow(activeTab.CurrentChannel.TellTarget.World, out var worldRow)
? worldRow.Name.ExtractText()
: "???";
channelNameChunks =
[
new TextChunk(ChunkSource.None, null, "Tell "),
new TextChunk(ChunkSource.None, null, playerName),
new IconChunk(ChunkSource.None, null, BitmapFontIcon.CrossWorld),
new TextChunk(ChunkSource.None, null, world)
];
}
else if (activeTab.CurrentChannel.UseTempChannel)
{
string name;
if (activeTab.CurrentChannel.TempChannel.IsLinkshell())
if (activeTab.CurrentChannel.TempTellTarget != null && activeTab.CurrentChannel.TempTellTarget.IsSet())
{
var idx = (uint) activeTab.CurrentChannel.TempChannel - (uint) InputChannel.Linkshell1;
var lsName = Plugin.Functions.Chat.GetLinkshellName(idx);
name = $"LS #{idx + 1}: {lsName}";
}
else if (activeTab.CurrentChannel.TempChannel.IsCrossLinkshell())
{
var idx = (uint) activeTab.CurrentChannel.TempChannel - (uint) InputChannel.CrossLinkshell1;
var cwlsName = Plugin.Functions.Chat.GetCrossLinkshellName(idx);
name = $"CWLS [{idx + 1}]: {cwlsName}";
channelNameChunks = GenerateTellTargetName(activeTab.CurrentChannel.TempTellTarget);
}
else
{
name = activeTab.CurrentChannel.TempChannel.ToChatType().Name();
}
string name;
if (activeTab.CurrentChannel.TempChannel.IsLinkshell())
{
var idx = (uint) activeTab.CurrentChannel.TempChannel - (uint) InputChannel.Linkshell1;
var lsName = Plugin.Functions.Chat.GetLinkshellName(idx);
name = $"LS #{idx + 1}: {lsName}";
}
else if (activeTab.CurrentChannel.TempChannel.IsCrossLinkshell())
{
var idx = (uint) activeTab.CurrentChannel.TempChannel - (uint) InputChannel.CrossLinkshell1;
var cwlsName = Plugin.Functions.Chat.GetCrossLinkshellName(idx);
name = $"CWLS [{idx + 1}]: {cwlsName}";
}
else
{
name = activeTab.CurrentChannel.TempChannel.ToChatType().Name();
}
channelNameChunks = [new TextChunk(ChunkSource.None, null, name)];
channelNameChunks = [new TextChunk(ChunkSource.None, null, name)];
}
}
else if (activeTab.CurrentChannel.TellTarget != null && activeTab.CurrentChannel.TellTarget.IsSet())
{
channelNameChunks = GenerateTellTargetName(activeTab.CurrentChannel.TellTarget);
}
else if (activeTab is { Channel: { } channel })
{
@@ -859,9 +846,11 @@ public sealed class ChatLogWindow : Window
internal void SetChannel(InputChannel? channel)
{
channel ??= InputChannel.Say;
if (channel != InputChannel.Tell)
{
Plugin.CurrentTab.CurrentChannel.TellTarget = null;
Plugin.CurrentTab.CurrentChannel.TempTellTarget = null;
}
// Instead of calling SetChannel(), we ask the ExtraChat plugin to set a
// channel override by just calling the command directly.
@@ -881,7 +870,29 @@ public sealed class ChatLogWindow : Window
return;
}
Plugin.Functions.Chat.SetChannel(channel.Value, Plugin.CurrentTab.CurrentChannel.TellTarget);
var target = Plugin.CurrentTab.CurrentChannel.TempTellTarget ?? Plugin.CurrentTab.CurrentChannel.TellTarget;
Plugin.Functions.Chat.SetChannel(channel.Value, target);
}
private Chunk[] GenerateTellTargetName(TellTarget tellTarget)
{
var playerName = tellTarget.Name;
if (ScreenshotMode)
// Note: don't use HidePlayerInString here because
// abbreviation settings do not affect this.
playerName = HashPlayer(tellTarget.Name, tellTarget.World);
var world = Sheets.WorldSheet.TryGetRow(tellTarget.World, out var worldRow)
? worldRow.Name.ExtractText()
: "???";
return
[
new TextChunk(ChunkSource.None, null, "Tell "),
new TextChunk(ChunkSource.None, null, playerName),
new IconChunk(ChunkSource.None, null, BitmapFontIcon.CrossWorld),
new TextChunk(ChunkSource.None, null, world)
];
}
internal void SendChatBox(Tab activeTab)
@@ -900,10 +911,7 @@ public sealed class ChatLogWindow : Window
Plugin.Functions.Chat.SendTellUsingCommandInner(tellBytes);
TellSpecial = false;
activeTab.CurrentChannel.UseTempChannel = false;
if (activeTab.CurrentChannel.TempChannel is InputChannel.Tell)
activeTab.CurrentChannel.TellTarget = null;
activeTab.CurrentChannel.TempChannel = InputChannel.Invalid;
activeTab.CurrentChannel.ResetTempChannel();
Chat = string.Empty;
return;
@@ -911,7 +919,7 @@ public sealed class ChatLogWindow : Window
if (!trimmed.StartsWith('/'))
{
var target = activeTab.CurrentChannel.TellTarget;
var target = activeTab.CurrentChannel.TempTellTarget ?? activeTab.CurrentChannel.TellTarget;
if (target != null)
{
// ContentId 0 is a case where we can't directly send messages, so we send a /tell formatted message and let the game handle it
@@ -941,7 +949,7 @@ public sealed class ChatLogWindow : Window
}
if (activeTab.CurrentChannel.TempChannel is InputChannel.Tell)
activeTab.CurrentChannel.TellTarget = null;
activeTab.CurrentChannel.TempTellTarget = null;
Chat = string.Empty;
return;
+21 -1
View File
@@ -583,6 +583,26 @@ internal static class ImGuiUtil
}
}
// Use end-function only on success.
private struct EndConditionally(Action endAction, bool success) : ImRaii.IEndObject
{
public bool Success { get; } = success;
private bool Disposed { get; set; } = false;
private Action EndAction { get; } = endAction;
public void Dispose()
{
if (Disposed)
return;
if (Success)
EndAction();
Disposed = true;
}
}
public static ImRaii.IEndObject TextWrapPos()
{
ImGui.PushTextWrapPos();
@@ -600,7 +620,7 @@ internal static class ImGuiUtil
public static ImRaii.IEndObject Menu(string label)
{
return new EndUnconditionally(ImGui.EndMenu, ImGui.BeginMenu(label));
return new EndConditionally(ImGui.EndMenu, ImGui.BeginMenu(label));
}
public static void ChannelSelector(string headerText, Dictionary<ChatType, ChatSource> chatCodes)