mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
This commit is contained in:
parent
d79e687162
commit
6b475ee229
66 changed files with 666 additions and 705 deletions
2
Luna
2
Luna
|
|
@ -1 +1 @@
|
|||
Subproject commit c764db88097c88cd49f2bed4f60268d617f97fdb
|
||||
Subproject commit 2870892f30f7b92bd74110c7da366779eae85ce7
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit cf3d868eeeb4ea3ea728ae15a8d09ec127ce80e9
|
||||
Subproject commit 3a5a03ff24e24151f80584cd4a8d45b36d94db36
|
||||
|
|
@ -1,57 +1,52 @@
|
|||
using Dalamud.Bindings.ImGui;
|
||||
using OtterGui.Text;
|
||||
using ImSharp;
|
||||
using Luna.Generators;
|
||||
|
||||
namespace Penumbra;
|
||||
|
||||
[NamedEnum(Unknown: "Error")]
|
||||
[TooltipEnum]
|
||||
public enum ChangedItemMode
|
||||
{
|
||||
[Name("Grouped (Collapsed)")]
|
||||
[Tooltip(
|
||||
"Display items as groups by their model and slot. Collapse those groups to a single item by default. Prefers items with more changes affecting them or configured items as the main item.")]
|
||||
GroupedCollapsed,
|
||||
|
||||
[Name("Grouped (Expanded)")]
|
||||
[Tooltip(
|
||||
"Display items as groups by their model and slot. Expand those groups showing all items by default. Prefers items with more changes affecting them or configured items as the main item.")]
|
||||
GroupedExpanded,
|
||||
|
||||
[Name("Alphabetical")]
|
||||
[Tooltip("Display all changed items in a single list sorted alphabetically.")]
|
||||
Alphabetical,
|
||||
}
|
||||
|
||||
public static class ChangedItemModeExtensions
|
||||
public static partial class ChangedItemModeExtensions
|
||||
{
|
||||
public static ReadOnlySpan<byte> ToName(this ChangedItemMode mode)
|
||||
=> mode switch
|
||||
{
|
||||
ChangedItemMode.GroupedCollapsed => "Grouped (Collapsed)"u8,
|
||||
ChangedItemMode.GroupedExpanded => "Grouped (Expanded)"u8,
|
||||
ChangedItemMode.Alphabetical => "Alphabetical"u8,
|
||||
_ => "Error"u8,
|
||||
};
|
||||
private static readonly ChangedItemModeCombo Combo = new();
|
||||
|
||||
public static ReadOnlySpan<byte> ToTooltip(this ChangedItemMode mode)
|
||||
=> mode switch
|
||||
{
|
||||
ChangedItemMode.GroupedCollapsed =>
|
||||
"Display items as groups by their model and slot. Collapse those groups to a single item by default. Prefers items with more changes affecting them or configured items as the main item."u8,
|
||||
ChangedItemMode.GroupedExpanded =>
|
||||
"Display items as groups by their model and slot. Expand those groups showing all items by default. Prefers items with more changes affecting them or configured items as the main item."u8,
|
||||
ChangedItemMode.Alphabetical => "Display all changed items in a single list sorted alphabetically."u8,
|
||||
_ => ""u8,
|
||||
};
|
||||
private sealed class ChangedItemModeCombo() : SimpleFilterCombo<ChangedItemMode>(SimpleFilterType.Text)
|
||||
{
|
||||
public override StringU8 DisplayString(in ChangedItemMode value)
|
||||
=> new(value.ToNameU8());
|
||||
|
||||
public override string FilterString(in ChangedItemMode value)
|
||||
=> value.ToName();
|
||||
|
||||
public override StringU8 Tooltip(in ChangedItemMode value)
|
||||
=> new(value.Tooltip());
|
||||
|
||||
public override IEnumerable<ChangedItemMode> GetBaseItems()
|
||||
=> Enum.GetValues<ChangedItemMode>();
|
||||
}
|
||||
|
||||
public static bool DrawCombo(ReadOnlySpan<byte> label, ChangedItemMode value, float width, Action<ChangedItemMode> setter)
|
||||
{
|
||||
ImGui.SetNextItemWidth(width);
|
||||
using var combo = ImUtf8.Combo(label, value.ToName());
|
||||
if (!combo)
|
||||
if (!Combo.Draw(label, ref value, StringU8.Empty, width))
|
||||
return false;
|
||||
|
||||
var ret = false;
|
||||
foreach (var newValue in Enum.GetValues<ChangedItemMode>())
|
||||
{
|
||||
var selected = ImUtf8.Selectable(newValue.ToName(), newValue == value);
|
||||
if (selected)
|
||||
{
|
||||
ret = true;
|
||||
setter(newValue);
|
||||
}
|
||||
|
||||
ImUtf8.HoverTooltip(newValue.ToTooltip());
|
||||
}
|
||||
|
||||
return ret;
|
||||
setter(value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
using Dalamud.Plugin.Services;
|
||||
using Lumina.Data.Parsing;
|
||||
using Luna;
|
||||
using OtterGui.Tasks;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.GameData.Data;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
using Dalamud.Bindings.ImGui;
|
||||
using ImSharp;
|
||||
using OtterGui;
|
||||
using OtterGui.Raii;
|
||||
using Penumbra.Import.Structs;
|
||||
using Penumbra.UI.Classes;
|
||||
|
||||
|
|
@ -23,9 +20,9 @@ public partial class TexToolsImporter
|
|||
|
||||
public bool DrawProgressInfo(Vector2 size)
|
||||
{
|
||||
if (_modPackCount == 0)
|
||||
if (_modPackCount is 0)
|
||||
{
|
||||
ImGuiUtil.Center("Nothing to extract.");
|
||||
ImEx.TextCentered("Nothing to extract."u8);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -35,40 +32,40 @@ public partial class TexToolsImporter
|
|||
return true;
|
||||
}
|
||||
|
||||
ImGui.NewLine();
|
||||
Im.Line.New();
|
||||
var percentage = (float)_currentModPackIdx / _modPackCount;
|
||||
ImGui.ProgressBar(percentage, size, $"Mod {_currentModPackIdx + 1} / {_modPackCount}");
|
||||
ImGui.NewLine();
|
||||
ImGui.TextUnformatted(State == ImporterState.DeduplicatingFiles
|
||||
Im.ProgressBar(percentage, size, $"Mod {_currentModPackIdx + 1} / {_modPackCount}");
|
||||
Im.Line.New();
|
||||
Im.Text(State is ImporterState.DeduplicatingFiles
|
||||
? $"Deduplicating {_currentModName}..."
|
||||
: $"Extracting {_currentModName}...");
|
||||
|
||||
if (_currentNumOptions > 1)
|
||||
{
|
||||
ImGui.NewLine();
|
||||
ImGui.NewLine();
|
||||
Im.Line.New();
|
||||
Im.Line.New();
|
||||
if (_currentOptionIdx >= _currentNumOptions)
|
||||
ImGui.ProgressBar(1f, size, $"Extracted {_currentNumOptions} Options");
|
||||
Im.ProgressBar(1f, size, $"Extracted {_currentNumOptions} Options");
|
||||
else
|
||||
ImGui.ProgressBar(_currentOptionIdx / (float)_currentNumOptions, size,
|
||||
Im.ProgressBar(_currentOptionIdx / (float)_currentNumOptions, size,
|
||||
$"Extracting Option {_currentOptionIdx + 1} / {_currentNumOptions}...");
|
||||
|
||||
ImGui.NewLine();
|
||||
if (State != ImporterState.DeduplicatingFiles)
|
||||
ImGui.TextUnformatted(
|
||||
Im.Line.New();
|
||||
if (State is not ImporterState.DeduplicatingFiles)
|
||||
Im.Text(
|
||||
$"Extracting Option {(_currentGroupName.Length == 0 ? string.Empty : $"{_currentGroupName} - ")}{_currentOptionName}...");
|
||||
}
|
||||
|
||||
ImGui.NewLine();
|
||||
ImGui.NewLine();
|
||||
Im.Line.New();
|
||||
Im.Line.New();
|
||||
if (_currentFileIdx >= _currentNumFiles)
|
||||
ImGui.ProgressBar(1f, size, $"Extracted {_currentNumFiles} Files");
|
||||
Im.ProgressBar(1f, size, $"Extracted {_currentNumFiles} Files");
|
||||
else
|
||||
ImGui.ProgressBar(_currentFileIdx / (float)_currentNumFiles, size, $"Extracting File {_currentFileIdx + 1} / {_currentNumFiles}...");
|
||||
Im.ProgressBar(_currentFileIdx / (float)_currentNumFiles, size, $"Extracting File {_currentFileIdx + 1} / {_currentNumFiles}...");
|
||||
|
||||
ImGui.NewLine();
|
||||
if (State != ImporterState.DeduplicatingFiles)
|
||||
ImGui.TextUnformatted($"Extracting File {_currentFileName}...");
|
||||
Im.Line.New();
|
||||
if (State is not ImporterState.DeduplicatingFiles)
|
||||
Im.Text($"Extracting File {_currentFileName}...");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -77,31 +74,33 @@ public partial class TexToolsImporter
|
|||
{
|
||||
var success = ExtractedMods.Count(t => t.Error == null);
|
||||
|
||||
ImGui.TextUnformatted($"Successfully extracted {success} / {ExtractedMods.Count} files.");
|
||||
ImGui.NewLine();
|
||||
using var table = ImRaii.Table("##files", 2);
|
||||
Im.Text($"Successfully extracted {success} / {ExtractedMods.Count} files.");
|
||||
Im.Line.New();
|
||||
using var table = Im.Table.Begin("##files"u8, 2);
|
||||
if (!table)
|
||||
return;
|
||||
|
||||
foreach (var (file, dir, ex) in ExtractedMods)
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TextUnformatted(file.Name);
|
||||
ImGui.TableNextColumn();
|
||||
if (ex == null)
|
||||
table.DrawColumn(file.Name);
|
||||
table.NextColumn();
|
||||
if (ex is null)
|
||||
{
|
||||
using var color = ImGuiColor.Text.Push(ColorId.FolderExpanded.Value());
|
||||
ImGui.TextUnformatted(dir?.FullName[(_baseDirectory.FullName.Length + 1)..] ?? "Unknown Directory");
|
||||
if (dir is null)
|
||||
Im.Text("Unknown Directory"u8);
|
||||
else
|
||||
Im.Text(dir.FullName.AsSpan(_baseDirectory.FullName.Length + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
using var color = ImGuiColor.Text.Push(ColorId.ConflictingMod.Value());
|
||||
ImGui.TextUnformatted(ex.Message);
|
||||
ImGuiUtil.HoverTooltip(ex.ToString());
|
||||
Im.Text(ex.Message);
|
||||
Im.Tooltip.OnHover($"{ex}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool DrawCancelButton(Vector2 size)
|
||||
=> ImGuiUtil.DrawDisabledButton("Cancel", size, string.Empty, _token.IsCancellationRequested);
|
||||
=> ImEx.Button("Cancel"u8, size, StringU8.Empty, _token.IsCancellationRequested);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using ImSharp;
|
||||
using OtterGui.Text;
|
||||
using Rgba32 = SixLabors.ImageSharp.PixelFormats.Rgba32;
|
||||
|
||||
namespace Penumbra.Import.Textures;
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@ using Dalamud.Interface.Textures;
|
|||
using Dalamud.Interface.Textures.TextureWraps;
|
||||
using Dalamud.Plugin.Services;
|
||||
using Lumina.Data.Files;
|
||||
using OtterGui.Log;
|
||||
using OtterGui.Tasks;
|
||||
using Luna;
|
||||
using OtterTex;
|
||||
using SharpDX.Direct3D11;
|
||||
using SixLabors.ImageSharp;
|
||||
|
|
@ -17,7 +16,7 @@ using Image = SixLabors.ImageSharp.Image;
|
|||
namespace Penumbra.Import.Textures;
|
||||
|
||||
public sealed class TextureManager(IDataManager gameData, Logger logger, ITextureProvider textureProvider, IUiBuilder uiBuilder)
|
||||
: SingleTaskQueue, IDisposable, Luna.IService
|
||||
: SingleTaskQueue, IDisposable, IService
|
||||
{
|
||||
private readonly Logger _logger = logger;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.CrashHandler.Buffers;
|
||||
using Penumbra.GameData;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.CrashHandler.Buffers;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.System.Scheduler.Resource;
|
||||
using JetBrains.Annotations;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.Interop.Structs;
|
||||
using Penumbra.String;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.System.Scheduler.Resource;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.Interop.Services;
|
||||
using Penumbra.String;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.CrashHandler.Buffers;
|
||||
using Penumbra.GameData;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.CrashHandler.Buffers;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
using Penumbra.Services;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
using Dalamud.Game.ClientState.Conditions;
|
||||
using Dalamud.Plugin.Services;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Scheduler.Base;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.GameData.Interop;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.CrashHandler.Buffers;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.GameData.Interop;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.CrashHandler.Buffers;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.CrashHandler.Buffers;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.GameData.Interop;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.GameData.Interop;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
|
|
@ -20,7 +20,7 @@ public unsafe class AtchCallerHook1 : FastHook<AtchCallerHook1.Delegate>, IDispo
|
|||
Task = hooks.CreateHook<Delegate>("AtchCaller1", Sigs.AtchCaller1, Detour,
|
||||
metaState.Config.EnableMods && !HookOverrides.Instance.Meta.AtchCaller1);
|
||||
if (!HookOverrides.Instance.Meta.AtchCaller1)
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
_metaState.Config.ModsEnabled += Set;
|
||||
}
|
||||
|
||||
private void Detour(DrawObjectData* data, uint slot, nint unk, Model playerModel)
|
||||
|
|
@ -34,5 +34,5 @@ public unsafe class AtchCallerHook1 : FastHook<AtchCallerHook1.Delegate>, IDispo
|
|||
}
|
||||
|
||||
public void Dispose()
|
||||
=> _metaState.Config.ModsEnabled -= Toggle;
|
||||
=> _metaState.Config.ModsEnabled -= Set;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.GameData.Interop;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
|
|
@ -20,7 +20,7 @@ public unsafe class AtchCallerHook2 : FastHook<AtchCallerHook2.Delegate>, IDispo
|
|||
Task = hooks.CreateHook<Delegate>("AtchCaller2", Sigs.AtchCaller2, Detour,
|
||||
metaState.Config.EnableMods && !HookOverrides.Instance.Meta.AtchCaller2);
|
||||
if (!HookOverrides.Instance.Meta.AtchCaller2)
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
_metaState.Config.ModsEnabled += Set;
|
||||
}
|
||||
|
||||
private void Detour(DrawObjectData* data, uint slot, nint unk, Model playerModel, uint unk2)
|
||||
|
|
@ -34,5 +34,5 @@ public unsafe class AtchCallerHook2 : FastHook<AtchCallerHook2.Delegate>, IDispo
|
|||
}
|
||||
|
||||
public void Dispose()
|
||||
=> _metaState.Config.ModsEnabled -= Toggle;
|
||||
=> _metaState.Config.ModsEnabled -= Set;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
|
||||
namespace Penumbra.Interop.Hooks.Meta;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.GameData.Structs;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
|
|
@ -19,7 +19,7 @@ public unsafe class EqdpAccessoryHook : FastHook<EqdpAccessoryHook.Delegate>, ID
|
|||
Task = hooks.CreateHook<Delegate>("GetEqdpAccessoryEntry", Sigs.GetEqdpAccessoryEntry, Detour,
|
||||
metaState.Config.EnableMods && !HookOverrides.Instance.Meta.EqdpAccessoryHook);
|
||||
if (!HookOverrides.Instance.Meta.EqdpAccessoryHook)
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
_metaState.Config.ModsEnabled += Set;
|
||||
}
|
||||
|
||||
private void Detour(CharacterUtility* utility, EqdpEntry* entry, uint setId, uint raceCode)
|
||||
|
|
@ -33,5 +33,5 @@ public unsafe class EqdpAccessoryHook : FastHook<EqdpAccessoryHook.Delegate>, ID
|
|||
}
|
||||
|
||||
public void Dispose()
|
||||
=> _metaState.Config.ModsEnabled -= Toggle;
|
||||
=> _metaState.Config.ModsEnabled -= Set;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
|
|
@ -18,7 +18,7 @@ public unsafe class EqdpEquipHook : FastHook<EqdpEquipHook.Delegate>, IDisposabl
|
|||
_metaState = metaState;
|
||||
Task = hooks.CreateHook<Delegate>("GetEqdpEquipEntry", Sigs.GetEqdpEquipEntry, Detour, metaState.Config.EnableMods && !HookOverrides.Instance.Meta.EqdpEquipHook);
|
||||
if (!HookOverrides.Instance.Meta.EqdpEquipHook)
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
_metaState.Config.ModsEnabled += Set;
|
||||
}
|
||||
|
||||
private void Detour(CharacterUtility* utility, EqdpEntry* entry, uint setId, uint raceCode)
|
||||
|
|
@ -32,5 +32,5 @@ public unsafe class EqdpEquipHook : FastHook<EqdpEquipHook.Delegate>, IDisposabl
|
|||
}
|
||||
|
||||
public void Dispose()
|
||||
=> _metaState.Config.ModsEnabled -= Toggle;
|
||||
=> _metaState.Config.ModsEnabled -= Set;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.GameData.Structs;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
|
|
@ -18,7 +18,7 @@ public unsafe class EqpHook : FastHook<EqpHook.Delegate>, IDisposable
|
|||
Task = hooks.CreateHook<Delegate>("GetEqpFlags", Sigs.GetEqpEntry, Detour,
|
||||
metaState.Config.EnableMods && !HookOverrides.Instance.Meta.EqpHook);
|
||||
if (!HookOverrides.Instance.Meta.EqpHook)
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
_metaState.Config.ModsEnabled += Set;
|
||||
}
|
||||
|
||||
private void Detour(CharacterUtility* utility, EqpEntry* flags, CharacterArmor* armor)
|
||||
|
|
@ -37,5 +37,5 @@ public unsafe class EqpHook : FastHook<EqpHook.Delegate>, IDisposable
|
|||
}
|
||||
|
||||
public void Dispose()
|
||||
=> _metaState.Config.ModsEnabled -= Toggle;
|
||||
=> _metaState.Config.ModsEnabled -= Set;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
|
|
@ -23,7 +23,7 @@ public unsafe class EstHook : FastHook<EstHook.Delegate>, IDisposable
|
|||
Task = hooks.CreateHook<Delegate>("FindEstEntry", Sigs.FindEstEntry, Detour,
|
||||
metaState.Config.EnableMods && !HookOverrides.Instance.Meta.EstHook);
|
||||
if (!HookOverrides.Instance.Meta.EstHook)
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
_metaState.Config.ModsEnabled += Set;
|
||||
}
|
||||
|
||||
private EstEntry Detour(ResourceHandle* estResource, uint genderRace, uint id)
|
||||
|
|
@ -59,5 +59,5 @@ public unsafe class EstHook : FastHook<EstHook.Delegate>, IDisposable
|
|||
}
|
||||
|
||||
public void Dispose()
|
||||
=> _metaState.Config.ModsEnabled -= Toggle;
|
||||
=> _metaState.Config.ModsEnabled -= Set;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using Lumina.Data.Parsing.Uld;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
using Penumbra.Meta.Files;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
|
||||
namespace Penumbra.Interop.Hooks.Meta;
|
||||
|
|
@ -20,7 +18,7 @@ public unsafe class GmpHook : FastHook<GmpHook.Delegate>, IDisposable
|
|||
Task = hooks.CreateHook<Delegate>("GetGmpEntry", Sigs.GetGmpEntry, Detour,
|
||||
metaState.Config.EnableMods && !HookOverrides.Instance.Meta.GmpHook);
|
||||
if (!HookOverrides.Instance.Meta.GmpHook)
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
_metaState.Config.ModsEnabled += Set;
|
||||
}
|
||||
|
||||
private ulong Detour(CharacterUtility* characterUtility, ulong* outputEntry, ushort setId)
|
||||
|
|
@ -39,5 +37,5 @@ public unsafe class GmpHook : FastHook<GmpHook.Delegate>, IDisposable
|
|||
}
|
||||
|
||||
public void Dispose()
|
||||
=> _metaState.Config.ModsEnabled -= Toggle;
|
||||
=> _metaState.Config.ModsEnabled -= Set;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
|
||||
namespace Penumbra.Interop.Hooks.Meta;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
|
|
@ -22,7 +22,7 @@ public unsafe class RspBustHook : FastHook<RspBustHook.Delegate>, IDisposable
|
|||
Task = hooks.CreateHook<Delegate>("GetRspBust", Sigs.GetRspBust, Detour,
|
||||
metaState.Config.EnableMods && !HookOverrides.Instance.Meta.RspBustHook);
|
||||
if (!HookOverrides.Instance.Meta.RspBustHook)
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
_metaState.Config.ModsEnabled += Set;
|
||||
}
|
||||
|
||||
private float* Detour(nint cmpResource, float* storage, SubRace clan, byte gender, byte bodyType, byte bustSize)
|
||||
|
|
@ -69,5 +69,5 @@ public unsafe class RspBustHook : FastHook<RspBustHook.Delegate>, IDisposable
|
|||
}
|
||||
|
||||
public void Dispose()
|
||||
=> _metaState.Config.ModsEnabled -= Toggle;
|
||||
=> _metaState.Config.ModsEnabled -= Set;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
|
|
@ -22,7 +22,7 @@ public class RspHeightHook : FastHook<RspHeightHook.Delegate>, IDisposable
|
|||
Task = hooks.CreateHook<Delegate>("GetRspHeight", Sigs.GetRspHeight, Detour,
|
||||
metaState.Config.EnableMods && !HookOverrides.Instance.Meta.RspHeightHook);
|
||||
if (!HookOverrides.Instance.Meta.RspHeightHook)
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
_metaState.Config.ModsEnabled += Set;
|
||||
}
|
||||
|
||||
private unsafe float Detour(nint cmpResource, SubRace clan, byte gender, byte bodyType, byte height)
|
||||
|
|
@ -79,5 +79,5 @@ public class RspHeightHook : FastHook<RspHeightHook.Delegate>, IDisposable
|
|||
}
|
||||
|
||||
public void Dispose()
|
||||
=> _metaState.Config.ModsEnabled -= Toggle;
|
||||
=> _metaState.Config.ModsEnabled -= Set;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using OtterGui.Services;
|
||||
using Penumbra.Collections;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
|
|
@ -22,7 +22,7 @@ public class RspTailHook : FastHook<RspTailHook.Delegate>, IDisposable
|
|||
Task = hooks.CreateHook<Delegate>("GetRspTail", Sigs.GetRspTail, Detour,
|
||||
metaState.Config.EnableMods && !HookOverrides.Instance.Meta.RspTailHook);
|
||||
if (!HookOverrides.Instance.Meta.RspTailHook)
|
||||
_metaState.Config.ModsEnabled += Toggle;
|
||||
_metaState.Config.ModsEnabled += Set;
|
||||
}
|
||||
|
||||
private unsafe float Detour(nint cmpResource, Race race, byte gender, byte isSecondSubRace, byte bodyType, byte tailLength)
|
||||
|
|
@ -73,5 +73,5 @@ public class RspTailHook : FastHook<RspTailHook.Delegate>, IDisposable
|
|||
}
|
||||
|
||||
public void Dispose()
|
||||
=> _metaState.Config.ModsEnabled -= Toggle;
|
||||
=> _metaState.Config.ModsEnabled -= Set;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using OtterGui.Services;
|
||||
using Penumbra.Collections;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using OtterGui.Services;
|
||||
using Penumbra.Collections;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
|
||||
namespace Penumbra.Interop.Hooks.Meta;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using Dalamud.Hooking;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
|
||||
namespace Penumbra.Interop.Hooks.Objects;
|
||||
|
|
@ -9,7 +9,7 @@ namespace Penumbra.Interop.Hooks.Objects;
|
|||
/// EnableDraw is what creates DrawObjects for gameObjects,
|
||||
/// so we always keep track of the current GameObject to be able to link it to the DrawObject.
|
||||
/// </summary>
|
||||
public sealed unsafe class EnableDraw : Luna.IHookService
|
||||
public sealed unsafe class EnableDraw : IHookService
|
||||
{
|
||||
private readonly Task<Hook<Delegate>> _task;
|
||||
private readonly GameState _state;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
|
||||
namespace Penumbra.Interop.Hooks.Objects;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
|
||||
namespace Penumbra.Interop.Hooks.PostProcessing;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
|
||||
namespace Penumbra.Interop.Hooks.Resources;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.Services;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
|
||||
using OtterGui.Services;
|
||||
using Luna;
|
||||
using Penumbra.GameData;
|
||||
|
||||
namespace Penumbra.Interop.Hooks.Resources;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
|
||||
using OtterGui.Text.HelperObjects;
|
||||
using Luna;
|
||||
using Penumbra.GameData.Data;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Render;
|
|||
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
|
||||
using FFXIVClientStructs.Interop;
|
||||
using Luna;
|
||||
using OtterGui.Text.HelperObjects;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.GameData.Data;
|
||||
|
|
@ -17,6 +16,7 @@ using Penumbra.String.Classes;
|
|||
using Penumbra.UI;
|
||||
using static Penumbra.Interop.Structs.StructExtensions;
|
||||
using CharaBase = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.CharacterBase;
|
||||
using SpanTextWriter = Luna.SpanTextWriter;
|
||||
|
||||
namespace Penumbra.Interop.ResourceTree;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
using OtterGui.Tasks;
|
||||
using Penumbra.Mods.Manager;
|
||||
|
||||
namespace Penumbra.Mods.Editor;
|
||||
|
|
@ -77,7 +76,7 @@ public class ModBackup
|
|||
return;
|
||||
|
||||
CreatingBackup = true;
|
||||
await AsyncTask.Run(Create);
|
||||
await Task.Run(Create);
|
||||
CreatingBackup = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,9 +59,6 @@ public class ModMerger : IDisposable, IService
|
|||
_communicator.ModPathChanged.Unsubscribe(OnModPathChange);
|
||||
}
|
||||
|
||||
public IEnumerable<Mod> ModsWithoutCurrent
|
||||
=> _mods.Where(m => m != MergeFromMod);
|
||||
|
||||
public bool CanMerge
|
||||
=> MergeToMod != null && MergeToMod != MergeFromMod;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
using Dalamud.Interface.ImGuiNotification;
|
||||
using Luna;
|
||||
using OtterGui.Tasks;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.SubMods;
|
||||
|
|
@ -9,7 +8,7 @@ using Penumbra.String.Classes;
|
|||
|
||||
namespace Penumbra.Mods.Editor;
|
||||
|
||||
public class ModNormalizer(ModManager modManager, Configuration config, SaveService saveService) : Luna.IService
|
||||
public class ModNormalizer(ModManager modManager, Configuration config, SaveService saveService) : IService
|
||||
{
|
||||
private readonly List<List<Dictionary<Utf8GamePath, FullPath>>> _redirections = [];
|
||||
|
||||
|
|
@ -36,7 +35,7 @@ public class ModNormalizer(ModManager modManager, Configuration config, SaveServ
|
|||
Step = 0;
|
||||
TotalSteps = mod.TotalFileCount + 5;
|
||||
|
||||
Worker = TrackedTask.Run(NormalizeSync);
|
||||
Worker = Task.Run(NormalizeSync);
|
||||
}
|
||||
|
||||
public void NormalizeUi(DirectoryInfo modDirectory)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
using System.Collections.Frozen;
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Interface.ImGuiNotification;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using ImSharp;
|
||||
using OtterGui.Text;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.UI.Classes;
|
||||
using Notification = Luna.Notification;
|
||||
|
|
@ -37,9 +33,8 @@ public static class FeatureChecker
|
|||
|
||||
if (missingFeatures.Count > 0)
|
||||
{
|
||||
Penumbra.Messager.AddMessage(new Notification(
|
||||
$"Please update Penumbra to use the mod {modName}{(modDirectory != modName ? $" at {modDirectory}" : string.Empty)}!\n\nLoading failed because it requires the unsupported feature{(missingFeatures.Count > 1 ? $"s\n\n\t[{string.Join("], [", missingFeatures)}]." : $" [{missingFeatures.First()}].")}",
|
||||
NotificationType.Warning));
|
||||
Penumbra.Messager.AddMessage(new Notification($"Please update Penumbra to use the mod {modName}{(modDirectory != modName ? $" at {modDirectory}" : string.Empty)}!\n\n"
|
||||
+ $"Loading failed because it requires the unsupported feature{(missingFeatures.Count > 1 ? $"s\n\n\t[{string.Join("], [", missingFeatures)}]." : $" [{missingFeatures.First()}].")}"));
|
||||
return FeatureFlags.Invalid;
|
||||
}
|
||||
|
||||
|
|
@ -52,20 +47,20 @@ public static class FeatureChecker
|
|||
public static void DrawFeatureFlagInput(ModDataEditor editor, Mod mod, float width)
|
||||
{
|
||||
const int numButtons = 5;
|
||||
var innerSpacing = ImGui.GetStyle().ItemInnerSpacing;
|
||||
var innerSpacing = Im.Style.ItemInnerSpacing;
|
||||
var size = new Vector2((width - (numButtons - 1) * innerSpacing.X) / numButtons, 0);
|
||||
var buttonColor = Im.Style[ImGuiColor.FrameBackground];
|
||||
var textColor = Im.Style[ImGuiColor.TextDisabled];
|
||||
using (var style = ImStyleBorder.Frame.Push(ColorId.FolderLine.Value(), 0)
|
||||
.Push(ImStyleDouble.ItemSpacing, innerSpacing)
|
||||
.Push(ImGuiColor.Button, buttonColor)
|
||||
.Push(ImGuiColor.Text, textColor))
|
||||
.Push(ImStyleDouble.ItemSpacing, innerSpacing)
|
||||
.Push(ImGuiColor.Button, buttonColor)
|
||||
.Push(ImGuiColor.Text, textColor))
|
||||
{
|
||||
foreach (var flag in SupportedFlags.Values)
|
||||
{
|
||||
if (mod.RequiredFeatures.HasFlag(flag))
|
||||
{
|
||||
style.Push(ImStyleSingle.FrameBorderThickness, ImUtf8.GlobalScale);
|
||||
style.Push(ImStyleSingle.FrameBorderThickness, Im.Style.GlobalScale);
|
||||
style.PopColor(2);
|
||||
if (Im.Button($"{flag}", size))
|
||||
editor.ChangeRequiredFeatures(mod, mod.RequiredFeatures & ~flag);
|
||||
|
|
@ -82,14 +77,14 @@ public static class FeatureChecker
|
|||
}
|
||||
}
|
||||
|
||||
if (ImUtf8.ButtonEx("Compute"u8, "Compute the required features automatically from the used features."u8, size))
|
||||
if (ImEx.Button("Compute"u8, size, "Compute the required features automatically from the used features."u8))
|
||||
editor.ChangeRequiredFeatures(mod, mod.ComputeRequiredFeatures());
|
||||
|
||||
Im.Line.Same();
|
||||
if (ImUtf8.ButtonEx("Clear"u8, "Clear all required features."u8, size))
|
||||
if (ImEx.Button("Clear"u8, size, "Clear all required features."u8))
|
||||
editor.ChangeRequiredFeatures(mod, FeatureFlags.None);
|
||||
|
||||
Im.Line.Same();
|
||||
ImUtf8.Text("Required Features"u8);
|
||||
Im.Text("Required Features"u8);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
25
Penumbra/Mods/Manager/ModCombo.cs
Normal file
25
Penumbra/Mods/Manager/ModCombo.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using ImSharp;
|
||||
using Luna;
|
||||
using Penumbra.Mods.Editor;
|
||||
|
||||
namespace Penumbra.Mods.Manager;
|
||||
|
||||
public class ModCombo(ModStorage modStorage) : SimpleFilterCombo<Mod>(SimpleFilterType.Regex), IUiService
|
||||
{
|
||||
protected readonly ModStorage ModStorage = modStorage;
|
||||
|
||||
public override StringU8 DisplayString(in Mod value)
|
||||
=> new(value.Name);
|
||||
|
||||
public override string FilterString(in Mod value)
|
||||
=> value.Name;
|
||||
|
||||
public override IEnumerable<Mod> GetBaseItems()
|
||||
=> ModStorage;
|
||||
}
|
||||
|
||||
public sealed class ModComboWithoutCurrent(ModStorage modStorage, ModMerger modMerger) : ModCombo(modStorage)
|
||||
{
|
||||
public override IEnumerable<Mod> GetBaseItems()
|
||||
=> ModStorage.Where(m => m != modMerger.MergeFromMod);
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
using Luna;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.Interop;
|
||||
using Penumbra.Mods.Editor;
|
||||
|
|
@ -228,7 +229,7 @@ public sealed class ModManager : ModStorage, IDisposable, Luna.IService
|
|||
if (oldName == newName)
|
||||
return NewDirectoryState.Identical;
|
||||
|
||||
var fixedNewName = ModCreator.ReplaceBadXivSymbols(newName, _config.ReplaceNonAsciiOnImport);
|
||||
var fixedNewName = newName.ReplaceBadXivSymbols(_config.ReplaceNonAsciiOnImport);
|
||||
if (fixedNewName != newName)
|
||||
return NewDirectoryState.ContainsInvalidSymbols;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,5 @@
|
|||
using OtterGui.Classes;
|
||||
using OtterGui.Widgets;
|
||||
|
||||
namespace Penumbra.Mods.Manager;
|
||||
|
||||
public class ModCombo(Func<IReadOnlyList<Mod>> generator) : FilterComboCache<Mod>(generator, MouseWheelType.None, Penumbra.Log)
|
||||
{
|
||||
protected override bool IsVisible(int globalIndex, LowerString filter)
|
||||
=> Items[globalIndex].Name.Contains(filter);
|
||||
|
||||
protected override string ToString(Mod obj)
|
||||
=> obj.Name;
|
||||
}
|
||||
|
||||
public class ModStorage : IReadOnlyList<Mod>
|
||||
{
|
||||
/// <summary> The actual list of mods. </summary>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using Luna;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.GameData.Structs;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
|
|
@ -137,7 +136,7 @@ public sealed class ImcModGroupEditor(CommunicatorService communicator, SaveServ
|
|||
|
||||
protected override bool MoveOption(ImcModGroup group, int optionIdxFrom, int optionIdxTo)
|
||||
{
|
||||
if (!Extensions.Move(group.OptionData, ref optionIdxFrom, ref optionIdxTo))
|
||||
if (!group.OptionData.Move(ref optionIdxFrom, ref optionIdxTo))
|
||||
return false;
|
||||
|
||||
group.DefaultSettings = group.DefaultSettings.MoveBit(optionIdxFrom, optionIdxTo);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
using Dalamud.Interface.ImGuiNotification;
|
||||
using Luna;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
|
|
@ -40,7 +39,7 @@ public class ModGroupEditor(
|
|||
CombiningModGroupEditor combiningEditor,
|
||||
CommunicatorService communicator,
|
||||
SaveService saveService,
|
||||
Configuration config) : Luna.IService
|
||||
Configuration config) : IService
|
||||
{
|
||||
public SingleModGroupEditor SingleEditor
|
||||
=> singleEditor;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using Luna;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Settings;
|
||||
|
|
@ -9,7 +8,7 @@ using Penumbra.Services;
|
|||
namespace Penumbra.Mods.Manager.OptionEditor;
|
||||
|
||||
public sealed class MultiModGroupEditor(CommunicatorService communicator, SaveService saveService, Configuration config)
|
||||
: ModOptionEditor<MultiModGroup, MultiSubMod>(communicator, saveService, config), Luna.IService
|
||||
: ModOptionEditor<MultiModGroup, MultiSubMod>(communicator, saveService, config), IService
|
||||
{
|
||||
public void ChangeToSingle(MultiModGroup group)
|
||||
{
|
||||
|
|
@ -75,7 +74,7 @@ public sealed class MultiModGroupEditor(CommunicatorService communicator, SaveSe
|
|||
|
||||
protected override bool MoveOption(MultiModGroup group, int optionIdxFrom, int optionIdxTo)
|
||||
{
|
||||
if (!Extensions.Move(group.OptionData, ref optionIdxFrom, ref optionIdxTo))
|
||||
if (!group.OptionData.Move(ref optionIdxFrom, ref optionIdxTo))
|
||||
return false;
|
||||
|
||||
group.DefaultSettings = group.DefaultSettings.MoveBit(optionIdxFrom, optionIdxTo);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using Luna;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Settings;
|
||||
|
|
@ -48,7 +47,7 @@ public sealed class SingleModGroupEditor(CommunicatorService communicator, SaveS
|
|||
|
||||
protected override bool MoveOption(SingleModGroup group, int optionIdxFrom, int optionIdxTo)
|
||||
{
|
||||
if (!Extensions.Move(group.OptionData, ref optionIdxFrom, ref optionIdxTo))
|
||||
if (!group.OptionData.Move(ref optionIdxFrom, ref optionIdxTo))
|
||||
return false;
|
||||
|
||||
group.DefaultSettings = group.DefaultSettings.MoveSingle(optionIdxFrom, optionIdxTo);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ using Dalamud.Interface.ImGuiNotification;
|
|||
using Luna;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.GameData.Data;
|
||||
using Penumbra.Import;
|
||||
|
|
@ -29,7 +28,8 @@ public partial class ModCreator(
|
|||
public readonly Configuration Config = config;
|
||||
|
||||
/// <summary> Creates directory and files necessary for a new mod without adding it to the manager. </summary>
|
||||
public DirectoryInfo? CreateEmptyMod(DirectoryInfo basePath, string newName, string description = "", string? author = null, params string[] tags)
|
||||
public DirectoryInfo? CreateEmptyMod(DirectoryInfo basePath, string newName, string description = "", string? author = null,
|
||||
params string[] tags)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -81,7 +81,7 @@ public partial class ModCreator(
|
|||
if (incorporateMetaChanges)
|
||||
IncorporateAllMetaChanges(mod, true, deleteDefaultMetaChanges);
|
||||
else if (deleteDefaultMetaChanges)
|
||||
ModMetaEditor.DeleteDefaultValues(mod, metaFileManager, saveService, false);
|
||||
ModMetaEditor.DeleteDefaultValues(mod, metaFileManager, saveService);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -98,7 +98,7 @@ public partial class ModCreator(
|
|||
{
|
||||
changes = changes
|
||||
|| saveService.FileNames.OptionGroupFile(mod.ModPath.FullName, mod.Groups.Count, group.Name, true)
|
||||
!= Path.Combine(file.DirectoryName!, ReplaceBadXivSymbols(file.Name, true));
|
||||
!= Path.Combine(file.DirectoryName!, file.Name.ReplaceBadXivSymbols(true));
|
||||
mod.Groups.Add(group);
|
||||
}
|
||||
else
|
||||
|
|
@ -167,7 +167,7 @@ public partial class ModCreator(
|
|||
|
||||
DeleteDeleteList(deleteList, delete);
|
||||
if (removeDefaultValues && !Config.KeepDefaultMetaChanges)
|
||||
changes |= ModMetaEditor.DeleteDefaultValues(mod, metaFileManager, null, false);
|
||||
changes |= ModMetaEditor.DeleteDefaultValues(mod, metaFileManager, null);
|
||||
|
||||
if (!changes)
|
||||
return;
|
||||
|
|
@ -306,33 +306,10 @@ public partial class ModCreator(
|
|||
/// <summary> Return the name of a new valid directory based on the base directory and the given name. </summary>
|
||||
public static DirectoryInfo NewOptionDirectory(DirectoryInfo baseDir, string optionName, bool onlyAscii)
|
||||
{
|
||||
var option = ReplaceBadXivSymbols(optionName, onlyAscii);
|
||||
var option = optionName.ReplaceBadXivSymbols(onlyAscii);
|
||||
return new DirectoryInfo(Path.Combine(baseDir.FullName, option.Length > 0 ? option : "_"));
|
||||
}
|
||||
|
||||
/// <summary> Normalize for nicer names, and remove invalid symbols or invalid paths. </summary>
|
||||
public static string ReplaceBadXivSymbols(string s, bool onlyAscii, string replacement = "_")
|
||||
{
|
||||
switch (s)
|
||||
{
|
||||
case ".": return replacement;
|
||||
case "..": return replacement + replacement;
|
||||
}
|
||||
|
||||
StringBuilder sb = new(s.Length);
|
||||
foreach (var c in s.Normalize(NormalizationForm.FormKC))
|
||||
{
|
||||
if (c.IsInvalidInPath())
|
||||
sb.Append(replacement);
|
||||
else if (onlyAscii && c.IsInvalidAscii())
|
||||
sb.Append(replacement);
|
||||
else
|
||||
sb.Append(c);
|
||||
}
|
||||
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public void SplitMultiGroups(DirectoryInfo baseDir)
|
||||
{
|
||||
var mod = new Mod(baseDir);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using OtterGui.Filesystem;
|
||||
using Luna;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Groups;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using Luna;
|
||||
using Newtonsoft.Json;
|
||||
using OtterGui;
|
||||
|
||||
namespace Penumbra.Mods.Settings;
|
||||
|
||||
|
|
@ -27,10 +27,10 @@ public readonly record struct Setting(ulong Value)
|
|||
=> idx >= 0 && (Value & (1ul << idx)) != 0;
|
||||
|
||||
public Setting MoveBit(int idx1, int idx2)
|
||||
=> new(Functions.MoveBit(Value, idx1, idx2));
|
||||
=> new(BitFunctions.MoveBit(Value, idx1, idx2));
|
||||
|
||||
public Setting RemoveBit(int idx)
|
||||
=> new(Functions.RemoveBit(Value, idx));
|
||||
=> new(BitFunctions.RemoveBit(Value, idx));
|
||||
|
||||
public Setting SetBit(int idx, bool value)
|
||||
=> new(value ? Value | (1ul << idx) : Value & ~(1ul << idx));
|
||||
|
|
|
|||
|
|
@ -17,13 +17,11 @@ using Penumbra.Interop.Hooks;
|
|||
using Penumbra.Interop.Hooks.PostProcessing;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
using Penumbra.Interop.Services;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.UI;
|
||||
using Penumbra.UI.AdvancedWindow;
|
||||
using Penumbra.UI.Tabs;
|
||||
using static System.Collections.Specialized.BitVector32;
|
||||
using ChangedItemClick = Penumbra.Communication.ChangedItemClick;
|
||||
using ChangedItemHover = Penumbra.Communication.ChangedItemHover;
|
||||
using DynamisIpc = OtterGui.Services.DynamisIpc;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
using Luna;
|
||||
using ImSharp;
|
||||
using Luna;
|
||||
using Penumbra.Mods.Manager;
|
||||
|
||||
namespace Penumbra.Services;
|
||||
|
||||
public class FileWatcher : IDisposable, IService
|
||||
public sealed class FileWatcher : IDisposable, IService
|
||||
{
|
||||
private readonly ConcurrentSet<string> _pending = new(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly ModImportManager _modImportManager;
|
||||
|
|
@ -47,9 +48,6 @@ public class FileWatcher : IDisposable, IService
|
|||
}
|
||||
}
|
||||
|
||||
internal void PauseConsumer(bool pause)
|
||||
=> _pausedConsumer = pause;
|
||||
|
||||
private void EndFileWatcher()
|
||||
{
|
||||
if (_fsw is null)
|
||||
|
|
@ -206,4 +204,47 @@ public class FileWatcher : IDisposable, IService
|
|||
EndConsumerTask();
|
||||
EndFileWatcher();
|
||||
}
|
||||
|
||||
public sealed class FileWatcherDrawer(Configuration config, FileWatcher fileWatcher) : IUiService
|
||||
{
|
||||
public void Draw()
|
||||
{
|
||||
using var tree = Im.Tree.Node("File Watcher"u8);
|
||||
if (!tree)
|
||||
return;
|
||||
|
||||
using var table = Im.Table.Begin("table"u8, 2);
|
||||
if (!table)
|
||||
return;
|
||||
|
||||
table.DrawColumn("Enabled"u8);
|
||||
table.DrawColumn($"{config.EnableDirectoryWatch}");
|
||||
|
||||
table.DrawColumn("Automatic Import"u8);
|
||||
table.DrawColumn($"{config.EnableAutomaticModImport}");
|
||||
|
||||
table.DrawColumn("Watched Directory"u8);
|
||||
table.DrawColumn(config.WatchDirectory);
|
||||
|
||||
table.DrawColumn("File Watcher Path"u8);
|
||||
table.DrawColumn(fileWatcher._fsw?.Path ?? "<NULL>");
|
||||
|
||||
table.DrawColumn("Raising Events"u8);
|
||||
table.DrawColumn($"{fileWatcher._fsw?.EnableRaisingEvents ?? false}");
|
||||
|
||||
table.DrawColumn("File Filters"u8);
|
||||
table.DrawColumn(StringU8.Join(", ", fileWatcher._fsw?.Filters ?? []));
|
||||
|
||||
table.DrawColumn("Consumer Task State"u8);
|
||||
table.DrawColumn($"{fileWatcher._consumer?.Status.ToString() ?? "<NULL>"}");
|
||||
|
||||
table.DrawColumn("Debug Pause Consumer"u8);
|
||||
table.NextColumn();
|
||||
if (Im.SmallButton(fileWatcher._pausedConsumer ? "Unpause"u8 : "Pause"u8))
|
||||
fileWatcher._pausedConsumer = !fileWatcher._pausedConsumer;
|
||||
|
||||
table.DrawColumn("Pending Files"u8);
|
||||
table.DrawColumn(StringU8.Join('\n', fileWatcher._pending));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,15 +64,15 @@ public sealed class FilenameService(IDalamudPluginInterface pi) : BaseFilePathPr
|
|||
public string ModMetaPath(string modDirectory)
|
||||
=> Path.Combine(modDirectory, "meta.json");
|
||||
|
||||
/// <summary> Obtain the path of the file describing a given option group by its index and the mod. If the index is < 0, return the path for the default mod file. </summary>
|
||||
/// <summary> Obtain the path of the file describing a given option group by its index and the mod. If the index is less than 0, return the path for the default mod file. </summary>
|
||||
public string OptionGroupFile(Mod mod, int index, bool onlyAscii)
|
||||
=> OptionGroupFile(mod.ModPath.FullName, index, index >= 0 ? mod.Groups[index].Name : string.Empty, onlyAscii);
|
||||
|
||||
/// <summary> Obtain the path of the file describing a given option group by its index, name and basepath. If the index is < 0, return the path for the default mod file. </summary>
|
||||
/// <summary> Obtain the path of the file describing a given option group by its index, name and basepath. If the index is less than 0, return the path for the default mod file. </summary>
|
||||
public string OptionGroupFile(string basePath, int index, string name, bool onlyAscii)
|
||||
{
|
||||
var fileName = index >= 0
|
||||
? $"group_{index + 1:D3}_{ModCreator.ReplaceBadXivSymbols(name.ToLowerInvariant(), onlyAscii)}.json"
|
||||
? $"group_{index + 1:D3}_{name.ToLowerInvariant().ReplaceBadXivSymbols(onlyAscii)}.json"
|
||||
: "default_mod.json";
|
||||
return Path.Combine(basePath, fileName);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,91 +0,0 @@
|
|||
using OtterGui.Tasks;
|
||||
|
||||
namespace Penumbra.Services;
|
||||
|
||||
public abstract class SyncServiceWrapper<T> : IDisposable
|
||||
{
|
||||
public string Name { get; }
|
||||
public T Service { get; }
|
||||
private bool _isDisposed;
|
||||
|
||||
public bool Valid
|
||||
=> !_isDisposed;
|
||||
|
||||
protected SyncServiceWrapper(string name, Func<T> factory)
|
||||
{
|
||||
Name = name;
|
||||
Service = factory();
|
||||
Penumbra.Log.Verbose($"[{Name}] Created.");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_isDisposed)
|
||||
return;
|
||||
|
||||
_isDisposed = true;
|
||||
if (Service is IDisposable d)
|
||||
d.Dispose();
|
||||
Penumbra.Log.Verbose($"[{Name}] Disposed.");
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class AsyncServiceWrapper<T> : IDisposable
|
||||
{
|
||||
public string Name { get; }
|
||||
public T? Service { get; private set; }
|
||||
|
||||
public T AwaitedService
|
||||
{
|
||||
get
|
||||
{
|
||||
_task?.Wait();
|
||||
return Service!;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Valid
|
||||
=> Service != null && !_isDisposed;
|
||||
|
||||
public event Action? FinishedCreation;
|
||||
private Task? _task;
|
||||
|
||||
private bool _isDisposed;
|
||||
|
||||
protected AsyncServiceWrapper(string name, Func<T> factory)
|
||||
{
|
||||
Name = name;
|
||||
_task = TrackedTask.Run(() =>
|
||||
{
|
||||
var service = factory();
|
||||
if (_isDisposed)
|
||||
{
|
||||
if (service is IDisposable d)
|
||||
d.Dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
Service = service;
|
||||
Penumbra.Log.Verbose($"[{Name}] Created.");
|
||||
_task = null;
|
||||
}
|
||||
});
|
||||
_task.ContinueWith((t, x) =>
|
||||
{
|
||||
if (!_isDisposed)
|
||||
FinishedCreation?.Invoke();
|
||||
}, TaskScheduler.Default);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_isDisposed)
|
||||
return;
|
||||
|
||||
_isDisposed = true;
|
||||
_task = null;
|
||||
if (Service is IDisposable d)
|
||||
d.Dispose();
|
||||
Penumbra.Log.Verbose($"[{Name}] Disposed.");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using Dalamud.Plugin.Services;
|
||||
using ImSharp;
|
||||
using OtterGui.Widgets;
|
||||
|
|
@ -14,6 +12,55 @@ using MouseWheelType = OtterGui.Widgets.MouseWheelType;
|
|||
|
||||
namespace Penumbra.Services;
|
||||
|
||||
// TODO
|
||||
//public sealed class StainTemplateCombo<TDyePack>(FilterComboColors[] stainCombos, StmFile<TDyePack> stmFile) : SimpleFilterCombo<StmKeyType>(SimpleFilterType.Text)
|
||||
// where TDyePack : unmanaged, IDyePack
|
||||
//{
|
||||
// public override StringU8 DisplayString(in StmKeyType value)
|
||||
// => new($"{value,4}");
|
||||
//
|
||||
// public override string FilterString(in StmKeyType value)
|
||||
// => $"{value,4}";
|
||||
//
|
||||
// public override IEnumerable<StmKeyType> GetBaseItems()
|
||||
// => throw new NotImplementedException();
|
||||
//
|
||||
// protected override bool DrawFilter(float width, FilterComboBaseCache<SimpleCacheItem<StmKeyType>> cache)
|
||||
// {
|
||||
// using var font = Im.Font.PushDefault();
|
||||
// return base.DrawFilter(width, cache);
|
||||
// }
|
||||
//
|
||||
// public bool Draw(Utf8StringHandler<LabelStringHandlerBuffer> label, Utf8StringHandler<HintStringHandlerBuffer> preview, Utf8StringHandler<TextStringHandlerBuffer> tooltip, ref int currentSelection, float previewWidth, float itemHeight,
|
||||
// ComboFlags flags = ComboFlags.None)
|
||||
// {
|
||||
// using var font = Im.Font.PushMono();
|
||||
// using var style = ImStyleDouble.ButtonTextAlign.Push(new Vector2(1, 0.5f))
|
||||
// .PushX(ImStyleDouble.ItemSpacing, Im.Style.ItemInnerSpacing.X);
|
||||
// var spaceSize = Im.Font.Mono.GetCharacterAdvance(' ');
|
||||
// var spaces = (int)(previewWidth / spaceSize) - 1;
|
||||
// return base.Draw(label, preview.PadLeft(spaces), tooltip, ref currentSelection, previewWidth, itemHeight, flags);
|
||||
// }
|
||||
//
|
||||
// protected override bool DrawSelectable(int globalIdx, bool selected)
|
||||
// {
|
||||
// var ret = base.DrawSelectable(globalIdx, selected);
|
||||
// var selection = stainCombos[CurrentDyeChannel].CurrentSelection.Key;
|
||||
// if (selection == 0 || !stmFile.TryGetValue(Items[globalIdx], selection, out var colors))
|
||||
// return ret;
|
||||
//
|
||||
// Im.Line.Same();
|
||||
//
|
||||
// var frame = new Vector2(Im.Style.TextHeight);
|
||||
// Im.Color.Button("D"u8, new Vector4(MtrlTab.PseudoSqrtRgb((Vector3)colors.DiffuseColor), 1), 0, frame);
|
||||
// Im.Line.Same();
|
||||
// Im.Color.Button("S"u8, new Vector4(MtrlTab.PseudoSqrtRgb((Vector3)colors.SpecularColor), 1), 0, frame);
|
||||
// Im.Line.Same();
|
||||
// Im.Color.Button("E"u8, new Vector4(MtrlTab.PseudoSqrtRgb((Vector3)colors.EmissiveColor), 1), 0, frame);
|
||||
// return ret;
|
||||
// }
|
||||
//}
|
||||
|
||||
public class StainService : Luna.IService
|
||||
{
|
||||
public sealed class StainTemplateCombo<TDyePack>(FilterComboColors[] stainCombos, StmFile<TDyePack> stmFile)
|
||||
|
|
@ -25,11 +72,11 @@ public class StainService : Luna.IService
|
|||
|
||||
protected override float GetFilterWidth()
|
||||
{
|
||||
var baseSize = ImGui.CalcTextSize("0000").X + ImGui.GetStyle().ScrollbarSize + ImGui.GetStyle().ItemInnerSpacing.X;
|
||||
var baseSize = Im.Font.CalculateSize("0000"u8).X + Im.Style.ScrollbarSize + Im.Style.ItemInnerSpacing.X;
|
||||
if (stainCombos[CurrentDyeChannel].CurrentSelection.Key == 0)
|
||||
return baseSize;
|
||||
|
||||
return baseSize + ImGui.GetTextLineHeight() * 3 + ImGui.GetStyle().ItemInnerSpacing.X * 3;
|
||||
return baseSize + Im.Style.TextHeight * 3 + Im.Style.ItemInnerSpacing.X * 3;
|
||||
}
|
||||
|
||||
protected override string ToString(StmKeyType obj)
|
||||
|
|
@ -37,17 +84,17 @@ public class StainService : Luna.IService
|
|||
|
||||
protected override void DrawFilter(int currentSelected, float width)
|
||||
{
|
||||
using var font = ImRaii.PushFont(UiBuilder.DefaultFont);
|
||||
using var font = Im.Font.PushDefault();
|
||||
base.DrawFilter(currentSelected, width);
|
||||
}
|
||||
|
||||
public override bool Draw(string label, string preview, string tooltip, ref int currentSelection, float previewWidth, float itemHeight,
|
||||
ImGuiComboFlags flags = ImGuiComboFlags.None)
|
||||
{
|
||||
using var font = ImRaii.PushFont(UiBuilder.MonoFont);
|
||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ButtonTextAlign, new Vector2(1, 0.5f))
|
||||
.Push(ImGuiStyleVar.ItemSpacing, ImGui.GetStyle().ItemSpacing with { X = ImGui.GetStyle().ItemInnerSpacing.X });
|
||||
var spaceSize = ImGui.CalcTextSize(" ").X;
|
||||
using var font = Im.Font.PushMono();
|
||||
using var style = ImStyleDouble.ButtonTextAlign.Push(new Vector2(1, 0.5f))
|
||||
.PushX(ImStyleDouble.ItemSpacing, Im.Style.ItemInnerSpacing.X);
|
||||
var spaceSize = Im.Font.Mono.GetCharacterAdvance(' ');
|
||||
var spaces = (int)(previewWidth / spaceSize) - 1;
|
||||
return base.Draw(label, preview.PadLeft(spaces), tooltip, ref currentSelection, previewWidth, itemHeight, flags);
|
||||
}
|
||||
|
|
@ -60,12 +107,13 @@ public class StainService : Luna.IService
|
|||
return ret;
|
||||
|
||||
Im.Line.Same();
|
||||
var frame = new Vector2(ImGui.GetTextLineHeight());
|
||||
ImGui.ColorButton("D", new Vector4(MtrlTab.PseudoSqrtRgb((Vector3)colors.DiffuseColor), 1), 0, frame);
|
||||
|
||||
var frame = new Vector2(Im.Style.TextHeight);
|
||||
Im.Color.Button("D"u8, new Vector4(MtrlTab.PseudoSqrtRgb((Vector3)colors.DiffuseColor), 1), 0, frame);
|
||||
Im.Line.Same();
|
||||
ImGui.ColorButton("S", new Vector4(MtrlTab.PseudoSqrtRgb((Vector3)colors.SpecularColor), 1), 0, frame);
|
||||
Im.Color.Button("S"u8, new Vector4(MtrlTab.PseudoSqrtRgb((Vector3)colors.SpecularColor), 1), 0, frame);
|
||||
Im.Line.Same();
|
||||
ImGui.ColorButton("E", new Vector4(MtrlTab.PseudoSqrtRgb((Vector3)colors.EmissiveColor), 1), 0, frame);
|
||||
Im.Color.Button("E"u8, new Vector4(MtrlTab.PseudoSqrtRgb((Vector3)colors.EmissiveColor), 1), 0, frame);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,10 +11,9 @@ using Penumbra.UI.Classes;
|
|||
|
||||
namespace Penumbra.UI.AdvancedWindow;
|
||||
|
||||
public class ModMergeTab(ModMerger modMerger) : Luna.IUiService
|
||||
public class ModMergeTab(ModMerger modMerger, ModComboWithoutCurrent combo) : Luna.IUiService
|
||||
{
|
||||
private readonly ModCombo _modCombo = new(() => modMerger.ModsWithoutCurrent.ToList());
|
||||
private string _newModName = string.Empty;
|
||||
private string _newModName = string.Empty;
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
|
|
@ -122,9 +121,9 @@ public class ModMergeTab(ModMerger modMerger) : Luna.IUiService
|
|||
|
||||
private void DrawCombo(float width)
|
||||
{
|
||||
_modCombo.Draw("##ModSelection", _modCombo.CurrentSelection?.Name ?? "Select the target Mod...", string.Empty, width,
|
||||
ImGui.GetTextLineHeight());
|
||||
modMerger.MergeToMod = _modCombo.CurrentSelection;
|
||||
if (combo.Draw("##ModSelection"u8, modMerger.MergeToMod?.Name ?? "Select the target Mod...", StringU8.Empty, width,
|
||||
out var cacheMod))
|
||||
modMerger.MergeToMod = cacheMod.Item;
|
||||
}
|
||||
|
||||
private void DrawSplitOff(float size)
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ public class DebugTab : Window, ITab
|
|||
private readonly RenderTargetDrawer _renderTargetDrawer;
|
||||
private readonly ModMigratorDebug _modMigratorDebug;
|
||||
private readonly ShapeInspector _shapeInspector;
|
||||
private readonly FileWatcher.FileWatcherDrawer _fileWatcherDrawer;
|
||||
|
||||
public DebugTab(Configuration config, CollectionManager collectionManager, ObjectManager objects,
|
||||
IClientState clientState, IDataManager dataManager,
|
||||
|
|
@ -117,7 +118,7 @@ public class DebugTab : Window, ITab
|
|||
Diagnostics diagnostics, IpcTester ipcTester, CrashHandlerPanel crashHandlerPanel, TexHeaderDrawer texHeaderDrawer,
|
||||
HookOverrideDrawer hookOverrides, RsfService rsfService, GlobalVariablesDrawer globalVariablesDrawer,
|
||||
SchedulerResourceManagementService schedulerService, ObjectIdentification objectIdentification, RenderTargetDrawer renderTargetDrawer,
|
||||
ModMigratorDebug modMigratorDebug, ShapeInspector shapeInspector)
|
||||
ModMigratorDebug modMigratorDebug, ShapeInspector shapeInspector, FileWatcher.FileWatcherDrawer fileWatcherDrawer)
|
||||
: base("Penumbra Debug Window", WindowFlags.NoCollapse)
|
||||
{
|
||||
IsOpen = true;
|
||||
|
|
@ -160,6 +161,7 @@ public class DebugTab : Window, ITab
|
|||
_renderTargetDrawer = renderTargetDrawer;
|
||||
_modMigratorDebug = modMigratorDebug;
|
||||
_shapeInspector = shapeInspector;
|
||||
_fileWatcherDrawer = fileWatcherDrawer;
|
||||
_objects = objects;
|
||||
_clientState = clientState;
|
||||
_dataManager = dataManager;
|
||||
|
|
@ -486,6 +488,8 @@ public class DebugTab : Window, ITab
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
_fileWatcherDrawer.Draw();
|
||||
}
|
||||
|
||||
private void DrawPerformanceTab()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue