Merge pull request #102
fix: various keybind fixes (modifiers and linkshells)
This commit is contained in:
@@ -354,6 +354,55 @@ internal sealed unsafe class Chat : IDisposable
|
|||||||
return InfoProxyCrossWorldLinkshell.Instance()->CrossWorldLinkshells[(int) idx].Name.Length > 0;
|
return InfoProxyCrossWorldLinkshell.Instance()->CrossWorldLinkshells[(int) idx].Name.Length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static uint? RotateLinkshell(uint currentIndex, RotateMode rotate, Func<uint, bool> validFn)
|
||||||
|
{
|
||||||
|
if (rotate == RotateMode.None)
|
||||||
|
return null;
|
||||||
|
var delta = rotate switch
|
||||||
|
{
|
||||||
|
RotateMode.Forward => 1,
|
||||||
|
RotateMode.Reverse => -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Iterate up to 8 times to find a valid linkshell.
|
||||||
|
for (var i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
currentIndex = (uint) ((8 + currentIndex + delta) % 8);
|
||||||
|
if (validFn(currentIndex))
|
||||||
|
return currentIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static InputChannel? ResolveTempInputChannel(InputChannel? currentTempChannel, InputChannel channel, RotateMode rotate)
|
||||||
|
{
|
||||||
|
switch (channel)
|
||||||
|
{
|
||||||
|
case InputChannel.Linkshell1 or InputChannel.CrossLinkshell1 when rotate != RotateMode.None:
|
||||||
|
{
|
||||||
|
// If we're activating for the first time, start at the beginning
|
||||||
|
// or end of the linkshell list depending on the rotate mode.
|
||||||
|
var currentIndex = rotate == RotateMode.Forward ? 7u : 0u;
|
||||||
|
if (currentTempChannel != null)
|
||||||
|
{
|
||||||
|
switch (channel)
|
||||||
|
{
|
||||||
|
case InputChannel.Linkshell1 when currentTempChannel.Value.IsLinkshell():
|
||||||
|
case InputChannel.CrossLinkshell1 when currentTempChannel.Value.IsCrossLinkshell():
|
||||||
|
currentIndex = currentTempChannel.Value.LinkshellIndex();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var idx = RotateLinkshell(currentIndex, rotate, channel == InputChannel.Linkshell1 ? ValidLinkshell : ValidCrossLinkshell);
|
||||||
|
return channel + idx;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal static void SetChannel(InputChannel channel, string? tellTarget = null)
|
internal static void SetChannel(InputChannel channel, string? tellTarget = null)
|
||||||
{
|
{
|
||||||
// ExtraChat linkshells aren't supported in game so we never want to
|
// ExtraChat linkshells aren't supported in game so we never want to
|
||||||
|
|||||||
@@ -396,11 +396,13 @@ internal unsafe class KeybindManager : IDisposable {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the vanilla text input has just lost focus, clear all keys so we
|
// If the vanilla text input has just lost focus, clear all non-modifier
|
||||||
// don't try to process them immediately.
|
// keys so we don't try to process them immediately on the next frame.
|
||||||
if (VanillaTextInputHasFocus)
|
if (VanillaTextInputHasFocus)
|
||||||
{
|
{
|
||||||
Plugin.KeyState.ClearAll();
|
foreach (var key in Plugin.KeyState.GetValidVirtualKeys())
|
||||||
|
if (key is not VirtualKey.CONTROL and not VirtualKey.SHIFT and not VirtualKey.MENU)
|
||||||
|
Plugin.KeyState[key] = false;
|
||||||
VanillaTextInputHasFocus = false;
|
VanillaTextInputHasFocus = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+31
-25
@@ -167,20 +167,12 @@ public sealed class ChatLogWindow : Window
|
|||||||
|
|
||||||
if (info.Channel != null)
|
if (info.Channel != null)
|
||||||
{
|
{
|
||||||
if (!GameFunctions.Chat.ValidAnyLinkshell(info.Channel.Value))
|
var targetChannel = info.Channel;
|
||||||
return;
|
|
||||||
|
|
||||||
var prevTemp = TempChannel;
|
|
||||||
if (info.Permanent)
|
|
||||||
SetChannel(info.Channel.Value);
|
|
||||||
else
|
|
||||||
TempChannel = info.Channel.Value;
|
|
||||||
|
|
||||||
if (info.Channel is InputChannel.Tell)
|
if (info.Channel is InputChannel.Tell)
|
||||||
{
|
{
|
||||||
if (info.Rotate != RotateMode.None)
|
if (info.Rotate != RotateMode.None)
|
||||||
{
|
{
|
||||||
var idx = prevTemp != InputChannel.Tell
|
var idx = TempChannel != InputChannel.Tell
|
||||||
? 0 : info.Rotate == RotateMode.Reverse
|
? 0 : info.Rotate == RotateMode.Reverse
|
||||||
? -1 : 1;
|
? -1 : 1;
|
||||||
|
|
||||||
@@ -200,27 +192,41 @@ public sealed class ChatLogWindow : Window
|
|||||||
TellTarget = null;
|
TellTarget = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var mode = prevTemp == null ? RotateMode.None : info.Rotate;
|
if (info.Channel is InputChannel.Linkshell1 or InputChannel.CrossLinkshell1 && info.Rotate != RotateMode.None)
|
||||||
if (info.Channel is InputChannel.Linkshell1 && info.Rotate != RotateMode.None)
|
|
||||||
{
|
{
|
||||||
var idx = GameFunctions.Chat.RotateLinkshellHistory(mode);
|
// If any of these operations fail, do nothing.
|
||||||
if (idx < 0 || !GameFunctions.Chat.ValidLinkshell((uint)idx))
|
targetChannel = null;
|
||||||
|
if (info.Permanent)
|
||||||
{
|
{
|
||||||
TempChannel = 0;
|
// Rotate using the game's code.
|
||||||
return;
|
if (info.Channel == InputChannel.Linkshell1)
|
||||||
|
{
|
||||||
|
var idx = GameFunctions.Chat.RotateLinkshellHistory(info.Rotate);
|
||||||
|
if (idx >= 0 && GameFunctions.Chat.ValidLinkshell((uint)idx))
|
||||||
|
targetChannel = info.Channel + (uint)idx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var idx = GameFunctions.Chat.RotateCrossLinkshellHistory(info.Rotate);
|
||||||
|
if (idx >= 0 && GameFunctions.Chat.ValidCrossLinkshell((uint)idx))
|
||||||
|
targetChannel = info.Channel + (uint)idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetChannel = GameFunctions.Chat.ResolveTempInputChannel(TempChannel, info.Channel.Value, info.Rotate);
|
||||||
}
|
}
|
||||||
TempChannel = info.Channel.Value + (uint) idx;
|
|
||||||
}
|
}
|
||||||
else if (info.Channel is InputChannel.CrossLinkshell1 && info.Rotate != RotateMode.None)
|
|
||||||
|
if (targetChannel == null || !GameFunctions.Chat.ValidAnyLinkshell(targetChannel.Value))
|
||||||
{
|
{
|
||||||
var idx = GameFunctions.Chat.RotateCrossLinkshellHistory(mode);
|
Plugin.Log.Warning($"Channel was set to an invalid value '{targetChannel}', ignoring");
|
||||||
if (idx < 0 || !GameFunctions.Chat.ValidCrossLinkshell((uint)idx))
|
return;
|
||||||
{
|
|
||||||
TempChannel = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
TempChannel = info.Channel.Value + (uint) idx;
|
|
||||||
}
|
}
|
||||||
|
if (info.Permanent)
|
||||||
|
SetChannel(targetChannel);
|
||||||
|
else
|
||||||
|
TempChannel = targetChannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.Text != null && Chat.Length == 0)
|
if (info.Text != null && Chat.Length == 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user