mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-12 18:27:24 +01:00
Add initial support for setting temporary mod settings.
This commit is contained in:
parent
e41755ed7e
commit
24452f3c79
22 changed files with 394 additions and 202 deletions
|
|
@ -293,6 +293,8 @@ public sealed class AutoDesignApplier : IDisposable
|
||||||
set.Designs.Where(d => d.IsActive(actor))
|
set.Designs.Where(d => d.IsActive(actor))
|
||||||
.SelectMany(d => d.Design.AllLinks(newApplication).Select(l => (l.Design, l.Flags & d.Type, d.Jobs.Flags))),
|
.SelectMany(d => d.Design.AllLinks(newApplication).Select(l => (l.Design, l.Flags & d.Type, d.Jobs.Flags))),
|
||||||
state.ModelData.Customize, state.BaseData, true, _config.AlwaysApplyAssociatedMods);
|
state.ModelData.Customize, state.BaseData, true, _config.AlwaysApplyAssociatedMods);
|
||||||
|
if (set.ResetTemporarySettings)
|
||||||
|
mergedDesign.ResetTemporarySettings = true;
|
||||||
|
|
||||||
_state.ApplyDesign(state, mergedDesign, new ApplySettings(0, StateSource.Fixed, respectManual, fromJobChange, false, false, false));
|
_state.ApplyDesign(state, mergedDesign, new ApplySettings(0, StateSource.Fixed, respectManual, fromJobChange, false, false, false));
|
||||||
forcedRedraw = mergedDesign.ForcedRedraw;
|
forcedRedraw = mergedDesign.ForcedRedraw;
|
||||||
|
|
|
||||||
|
|
@ -444,8 +444,9 @@ public class AutoDesignManager : ISavable, IReadOnlyList<AutoDesignSet>, IDispos
|
||||||
|
|
||||||
var set = new AutoDesignSet(name, group)
|
var set = new AutoDesignSet(name, group)
|
||||||
{
|
{
|
||||||
Enabled = obj["Enabled"]?.ToObject<bool>() ?? false,
|
Enabled = obj["Enabled"]?.ToObject<bool>() ?? false,
|
||||||
BaseState = obj["BaseState"]?.ToObject<AutoDesignSet.Base>() ?? AutoDesignSet.Base.Current,
|
ResetTemporarySettings = obj["ResetTemporarySettings"]?.ToObject<bool>() ?? false,
|
||||||
|
BaseState = obj["BaseState"]?.ToObject<AutoDesignSet.Base>() ?? AutoDesignSet.Base.Current,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (set.Enabled)
|
if (set.Enabled)
|
||||||
|
|
@ -602,9 +603,9 @@ public class AutoDesignManager : ISavable, IReadOnlyList<AutoDesignSet>, IDispos
|
||||||
? ActorIdentifier.RetainerType.Mannequin
|
? ActorIdentifier.RetainerType.Mannequin
|
||||||
: ActorIdentifier.RetainerType.Bell).CreatePermanent(),
|
: ActorIdentifier.RetainerType.Bell).CreatePermanent(),
|
||||||
],
|
],
|
||||||
IdentifierType.Npc => CreateNpcs(_actors, identifier),
|
IdentifierType.Npc => CreateNpcs(_actors, identifier),
|
||||||
IdentifierType.Owned => CreateNpcs(_actors, identifier),
|
IdentifierType.Owned => CreateNpcs(_actors, identifier),
|
||||||
_ => [],
|
_ => [],
|
||||||
};
|
};
|
||||||
|
|
||||||
static ActorIdentifier[] CreateNpcs(ActorManager manager, ActorIdentifier identifier)
|
static ActorIdentifier[] CreateNpcs(ActorManager manager, ActorIdentifier identifier)
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@ public class AutoDesignSet(string name, ActorIdentifier[] identifiers, List<Auto
|
||||||
public string Name = name;
|
public string Name = name;
|
||||||
public ActorIdentifier[] Identifiers = identifiers;
|
public ActorIdentifier[] Identifiers = identifiers;
|
||||||
public bool Enabled;
|
public bool Enabled;
|
||||||
public Base BaseState = Base.Current;
|
public Base BaseState = Base.Current;
|
||||||
|
public bool ResetTemporarySettings = false;
|
||||||
|
|
||||||
public JObject Serialize()
|
public JObject Serialize()
|
||||||
{
|
{
|
||||||
|
|
@ -20,11 +21,12 @@ public class AutoDesignSet(string name, ActorIdentifier[] identifiers, List<Auto
|
||||||
|
|
||||||
return new JObject()
|
return new JObject()
|
||||||
{
|
{
|
||||||
["Name"] = Name,
|
["Name"] = Name,
|
||||||
["Identifier"] = Identifiers[0].ToJson(),
|
["Identifier"] = Identifiers[0].ToJson(),
|
||||||
["Enabled"] = Enabled,
|
["Enabled"] = Enabled,
|
||||||
["BaseState"] = BaseState.ToString(),
|
["BaseState"] = BaseState.ToString(),
|
||||||
["Designs"] = list,
|
["ResetTemporarySettings"] = ResetTemporarySettings.ToString(),
|
||||||
|
["Designs"] = list,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,10 @@ public enum HeightDisplayType
|
||||||
|
|
||||||
public class DefaultDesignSettings
|
public class DefaultDesignSettings
|
||||||
{
|
{
|
||||||
public bool AlwaysForceRedrawing = false;
|
public bool AlwaysForceRedrawing = false;
|
||||||
public bool ResetAdvancedDyes = false;
|
public bool ResetAdvancedDyes = false;
|
||||||
public bool ShowQuickDesignBar = true;
|
public bool ShowQuickDesignBar = true;
|
||||||
|
public bool ResetTemporarySettings = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Configuration : IPluginConfiguration, ISavable
|
public class Configuration : IPluginConfiguration, ISavable
|
||||||
|
|
@ -63,6 +64,7 @@ public class Configuration : IPluginConfiguration, ISavable
|
||||||
public bool ShowColorConfig { get; set; } = true;
|
public bool ShowColorConfig { get; set; } = true;
|
||||||
public bool ChangeEntireItem { get; set; } = false;
|
public bool ChangeEntireItem { get; set; } = false;
|
||||||
public bool AlwaysApplyAssociatedMods { get; set; } = false;
|
public bool AlwaysApplyAssociatedMods { get; set; } = false;
|
||||||
|
public bool UseTemporarySettings { get; set; } = true;
|
||||||
public bool AllowDoubleClickToApply { get; set; } = false;
|
public bool AllowDoubleClickToApply { get; set; } = false;
|
||||||
public bool RespectManualOnAutomationUpdate { get; set; } = false;
|
public bool RespectManualOnAutomationUpdate { get; set; } = false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,32 +28,34 @@ public sealed class Design : DesignBase, ISavable, IDesignStandIn
|
||||||
internal Design(Design other)
|
internal Design(Design other)
|
||||||
: base(other)
|
: base(other)
|
||||||
{
|
{
|
||||||
Tags = [.. other.Tags];
|
Tags = [.. other.Tags];
|
||||||
Description = other.Description;
|
Description = other.Description;
|
||||||
QuickDesign = other.QuickDesign;
|
QuickDesign = other.QuickDesign;
|
||||||
ForcedRedraw = other.ForcedRedraw;
|
ForcedRedraw = other.ForcedRedraw;
|
||||||
ResetAdvancedDyes = other.ResetAdvancedDyes;
|
ResetAdvancedDyes = other.ResetAdvancedDyes;
|
||||||
Color = other.Color;
|
ResetTemporarySettings = other.ResetTemporarySettings;
|
||||||
AssociatedMods = new SortedList<Mod, ModSettings>(other.AssociatedMods);
|
Color = other.Color;
|
||||||
Links = Links.Clone();
|
AssociatedMods = new SortedList<Mod, ModSettings>(other.AssociatedMods);
|
||||||
|
Links = Links.Clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Metadata
|
// Metadata
|
||||||
public new const int FileVersion = 2;
|
public new const int FileVersion = 2;
|
||||||
|
|
||||||
public Guid Identifier { get; internal init; }
|
public Guid Identifier { get; internal init; }
|
||||||
public DateTimeOffset CreationDate { get; internal init; }
|
public DateTimeOffset CreationDate { get; internal init; }
|
||||||
public DateTimeOffset LastEdit { get; internal set; }
|
public DateTimeOffset LastEdit { get; internal set; }
|
||||||
public LowerString Name { get; internal set; } = LowerString.Empty;
|
public LowerString Name { get; internal set; } = LowerString.Empty;
|
||||||
public string Description { get; internal set; } = string.Empty;
|
public string Description { get; internal set; } = string.Empty;
|
||||||
public string[] Tags { get; internal set; } = [];
|
public string[] Tags { get; internal set; } = [];
|
||||||
public int Index { get; internal set; }
|
public int Index { get; internal set; }
|
||||||
public bool ForcedRedraw { get; internal set; }
|
public bool ForcedRedraw { get; internal set; }
|
||||||
public bool ResetAdvancedDyes { get; internal set; }
|
public bool ResetAdvancedDyes { get; internal set; }
|
||||||
public bool QuickDesign { get; internal set; } = true;
|
public bool ResetTemporarySettings { get; internal set; }
|
||||||
public string Color { get; internal set; } = string.Empty;
|
public bool QuickDesign { get; internal set; } = true;
|
||||||
public SortedList<Mod, ModSettings> AssociatedMods { get; private set; } = [];
|
public string Color { get; internal set; } = string.Empty;
|
||||||
public LinkContainer Links { get; private set; } = [];
|
public SortedList<Mod, ModSettings> AssociatedMods { get; private set; } = [];
|
||||||
|
public LinkContainer Links { get; private set; } = [];
|
||||||
|
|
||||||
public string Incognito
|
public string Incognito
|
||||||
=> Identifier.ToString()[..8];
|
=> Identifier.ToString()[..8];
|
||||||
|
|
@ -100,25 +102,26 @@ public sealed class Design : DesignBase, ISavable, IDesignStandIn
|
||||||
{
|
{
|
||||||
var ret = new JObject()
|
var ret = new JObject()
|
||||||
{
|
{
|
||||||
["FileVersion"] = FileVersion,
|
["FileVersion"] = FileVersion,
|
||||||
["Identifier"] = Identifier,
|
["Identifier"] = Identifier,
|
||||||
["CreationDate"] = CreationDate,
|
["CreationDate"] = CreationDate,
|
||||||
["LastEdit"] = LastEdit,
|
["LastEdit"] = LastEdit,
|
||||||
["Name"] = Name.Text,
|
["Name"] = Name.Text,
|
||||||
["Description"] = Description,
|
["Description"] = Description,
|
||||||
["ForcedRedraw"] = ForcedRedraw,
|
["ForcedRedraw"] = ForcedRedraw,
|
||||||
["ResetAdvancedDyes"] = ResetAdvancedDyes,
|
["ResetAdvancedDyes"] = ResetAdvancedDyes,
|
||||||
["Color"] = Color,
|
["ResetTemporarySettings"] = ResetTemporarySettings,
|
||||||
["QuickDesign"] = QuickDesign,
|
["Color"] = Color,
|
||||||
["Tags"] = JArray.FromObject(Tags),
|
["QuickDesign"] = QuickDesign,
|
||||||
["WriteProtected"] = WriteProtected(),
|
["Tags"] = JArray.FromObject(Tags),
|
||||||
["Equipment"] = SerializeEquipment(),
|
["WriteProtected"] = WriteProtected(),
|
||||||
["Bonus"] = SerializeBonusItems(),
|
["Equipment"] = SerializeEquipment(),
|
||||||
["Customize"] = SerializeCustomize(),
|
["Bonus"] = SerializeBonusItems(),
|
||||||
["Parameters"] = SerializeParameters(),
|
["Customize"] = SerializeCustomize(),
|
||||||
["Materials"] = SerializeMaterials(),
|
["Parameters"] = SerializeParameters(),
|
||||||
["Mods"] = SerializeMods(),
|
["Materials"] = SerializeMaterials(),
|
||||||
["Links"] = Links.Serialize(),
|
["Mods"] = SerializeMods(),
|
||||||
|
["Links"] = Links.Serialize(),
|
||||||
};
|
};
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -250,9 +253,10 @@ public sealed class Design : DesignBase, ISavable, IDesignStandIn
|
||||||
LoadParameters(json["Parameters"], design, design.Name);
|
LoadParameters(json["Parameters"], design, design.Name);
|
||||||
LoadMaterials(json["Materials"], design, design.Name);
|
LoadMaterials(json["Materials"], design, design.Name);
|
||||||
LoadLinks(linkLoader, json["Links"], design);
|
LoadLinks(linkLoader, json["Links"], design);
|
||||||
design.Color = json["Color"]?.ToObject<string>() ?? string.Empty;
|
design.Color = json["Color"]?.ToObject<string>() ?? string.Empty;
|
||||||
design.ForcedRedraw = json["ForcedRedraw"]?.ToObject<bool>() ?? false;
|
design.ForcedRedraw = json["ForcedRedraw"]?.ToObject<bool>() ?? false;
|
||||||
design.ResetAdvancedDyes = json["ResetAdvancedDyes"]?.ToObject<bool>() ?? false;
|
design.ResetAdvancedDyes = json["ResetAdvancedDyes"]?.ToObject<bool>() ?? false;
|
||||||
|
design.ResetTemporarySettings = json["ResetTemporarySettings"]?.ToObject<bool>() ?? false;
|
||||||
return design;
|
return design;
|
||||||
|
|
||||||
static string[] ParseTags(JObject json)
|
static string[] ParseTags(JObject json)
|
||||||
|
|
@ -278,12 +282,15 @@ public sealed class Design : DesignBase, ISavable, IDesignStandIn
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var settingsDict = tok["Settings"]?.ToObject<Dictionary<string, List<string>>>() ?? [];
|
var forceInherit = tok["Inherit"]?.ToObject<bool>() ?? false;
|
||||||
var settings = new Dictionary<string, List<string>>(settingsDict.Count);
|
var removeSetting = tok["Remove"]?.ToObject<bool>() ?? false;
|
||||||
|
var settingsDict = tok["Settings"]?.ToObject<Dictionary<string, List<string>>>() ?? [];
|
||||||
|
var settings = new Dictionary<string, List<string>>(settingsDict.Count);
|
||||||
foreach (var (key, value) in settingsDict)
|
foreach (var (key, value) in settingsDict)
|
||||||
settings.Add(key, value);
|
settings.Add(key, value);
|
||||||
var priority = tok["Priority"]?.ToObject<int>() ?? 0;
|
var priority = tok["Priority"]?.ToObject<int>() ?? 0;
|
||||||
if (!design.AssociatedMods.TryAdd(new Mod(name, directory), new ModSettings(settings, priority, enabled.Value)))
|
if (!design.AssociatedMods.TryAdd(new Mod(name, directory),
|
||||||
|
new ModSettings(settings, priority, enabled.Value, forceInherit, removeSetting)))
|
||||||
Glamourer.Messager.NotificationMessage("The loaded design contains a mod more than once, skipped.", NotificationType.Warning);
|
Glamourer.Messager.NotificationMessage("The loaded design contains a mod more than once, skipped.", NotificationType.Warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -99,14 +99,15 @@ public sealed class DesignManager : DesignEditor
|
||||||
var (actualName, path) = ParseName(name, handlePath);
|
var (actualName, path) = ParseName(name, handlePath);
|
||||||
var design = new Design(Customizations, Items)
|
var design = new Design(Customizations, Items)
|
||||||
{
|
{
|
||||||
CreationDate = DateTimeOffset.UtcNow,
|
CreationDate = DateTimeOffset.UtcNow,
|
||||||
LastEdit = DateTimeOffset.UtcNow,
|
LastEdit = DateTimeOffset.UtcNow,
|
||||||
Identifier = CreateNewGuid(),
|
Identifier = CreateNewGuid(),
|
||||||
Name = actualName,
|
Name = actualName,
|
||||||
Index = Designs.Count,
|
Index = Designs.Count,
|
||||||
ForcedRedraw = Config.DefaultDesignSettings.AlwaysForceRedrawing,
|
ForcedRedraw = Config.DefaultDesignSettings.AlwaysForceRedrawing,
|
||||||
ResetAdvancedDyes = Config.DefaultDesignSettings.ResetAdvancedDyes,
|
ResetAdvancedDyes = Config.DefaultDesignSettings.ResetAdvancedDyes,
|
||||||
QuickDesign = Config.DefaultDesignSettings.ShowQuickDesignBar,
|
QuickDesign = Config.DefaultDesignSettings.ShowQuickDesignBar,
|
||||||
|
ResetTemporarySettings = Config.DefaultDesignSettings.ResetTemporarySettings,
|
||||||
};
|
};
|
||||||
Designs.Add(design);
|
Designs.Add(design);
|
||||||
Glamourer.Log.Debug($"Added new design {design.Identifier}.");
|
Glamourer.Log.Debug($"Added new design {design.Identifier}.");
|
||||||
|
|
@ -121,14 +122,15 @@ public sealed class DesignManager : DesignEditor
|
||||||
var (actualName, path) = ParseName(name, handlePath);
|
var (actualName, path) = ParseName(name, handlePath);
|
||||||
var design = new Design(clone)
|
var design = new Design(clone)
|
||||||
{
|
{
|
||||||
CreationDate = DateTimeOffset.UtcNow,
|
CreationDate = DateTimeOffset.UtcNow,
|
||||||
LastEdit = DateTimeOffset.UtcNow,
|
LastEdit = DateTimeOffset.UtcNow,
|
||||||
Identifier = CreateNewGuid(),
|
Identifier = CreateNewGuid(),
|
||||||
Name = actualName,
|
Name = actualName,
|
||||||
Index = Designs.Count,
|
Index = Designs.Count,
|
||||||
ForcedRedraw = Config.DefaultDesignSettings.AlwaysForceRedrawing,
|
ForcedRedraw = Config.DefaultDesignSettings.AlwaysForceRedrawing,
|
||||||
ResetAdvancedDyes = Config.DefaultDesignSettings.ResetAdvancedDyes,
|
ResetAdvancedDyes = Config.DefaultDesignSettings.ResetAdvancedDyes,
|
||||||
QuickDesign = Config.DefaultDesignSettings.ShowQuickDesignBar,
|
QuickDesign = Config.DefaultDesignSettings.ShowQuickDesignBar,
|
||||||
|
ResetTemporarySettings = Config.DefaultDesignSettings.ResetTemporarySettings,
|
||||||
};
|
};
|
||||||
|
|
||||||
Designs.Add(design);
|
Designs.Add(design);
|
||||||
|
|
@ -144,11 +146,11 @@ public sealed class DesignManager : DesignEditor
|
||||||
var (actualName, path) = ParseName(name, handlePath);
|
var (actualName, path) = ParseName(name, handlePath);
|
||||||
var design = new Design(clone)
|
var design = new Design(clone)
|
||||||
{
|
{
|
||||||
CreationDate = DateTimeOffset.UtcNow,
|
CreationDate = DateTimeOffset.UtcNow,
|
||||||
LastEdit = DateTimeOffset.UtcNow,
|
LastEdit = DateTimeOffset.UtcNow,
|
||||||
Identifier = CreateNewGuid(),
|
Identifier = CreateNewGuid(),
|
||||||
Name = actualName,
|
Name = actualName,
|
||||||
Index = Designs.Count,
|
Index = Designs.Count,
|
||||||
};
|
};
|
||||||
Designs.Add(design);
|
Designs.Add(design);
|
||||||
Glamourer.Log.Debug(
|
Glamourer.Log.Debug(
|
||||||
|
|
@ -351,6 +353,17 @@ public sealed class DesignManager : DesignEditor
|
||||||
DesignChanged.Invoke(DesignChanged.Type.ResetAdvancedDyes, design, null);
|
DesignChanged.Invoke(DesignChanged.Type.ResetAdvancedDyes, design, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ChangeResetTemporarySettings(Design design, bool resetTemporarySettings)
|
||||||
|
{
|
||||||
|
if (design.ResetTemporarySettings == resetTemporarySettings)
|
||||||
|
return;
|
||||||
|
|
||||||
|
design.ResetTemporarySettings = resetTemporarySettings;
|
||||||
|
SaveService.QueueSave(design);
|
||||||
|
Glamourer.Log.Debug($"Set {design.Identifier} to {(resetTemporarySettings ? string.Empty : "not")} reset temporary settings.");
|
||||||
|
DesignChanged.Invoke(DesignChanged.Type.ResetTemporarySettings, design, null);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary> Change whether to apply a specific customize value. </summary>
|
/// <summary> Change whether to apply a specific customize value. </summary>
|
||||||
public void ChangeApplyCustomize(Design design, CustomizeIndex idx, bool value)
|
public void ChangeApplyCustomize(Design design, CustomizeIndex idx, bool value)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -26,5 +26,6 @@ public interface IDesignStandIn : IEquatable<IDesignStandIn>
|
||||||
|
|
||||||
public bool ForcedRedraw { get; }
|
public bool ForcedRedraw { get; }
|
||||||
|
|
||||||
public bool ResetAdvancedDyes { get; }
|
public bool ResetAdvancedDyes { get; }
|
||||||
|
public bool ResetTemporarySettings { get; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,8 @@ public class DesignMerger(
|
||||||
ret.ForcedRedraw = true;
|
ret.ForcedRedraw = true;
|
||||||
if (design.ResetAdvancedDyes)
|
if (design.ResetAdvancedDyes)
|
||||||
ret.ResetAdvancedDyes = true;
|
ret.ResetAdvancedDyes = true;
|
||||||
|
if (design.ResetTemporarySettings)
|
||||||
|
ret.ResetTemporarySettings = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyFixFlags(ret, fixFlags);
|
ApplyFixFlags(ret, fixFlags);
|
||||||
|
|
|
||||||
|
|
@ -101,4 +101,5 @@ public sealed class MergedDesign
|
||||||
public StateSources Sources = new();
|
public StateSources Sources = new();
|
||||||
public bool ForcedRedraw;
|
public bool ForcedRedraw;
|
||||||
public bool ResetAdvancedDyes;
|
public bool ResetAdvancedDyes;
|
||||||
|
public bool ResetTemporarySettings;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,4 +56,7 @@ public class QuickSelectedDesign(QuickDesignCombo combo) : IDesignStandIn, IServ
|
||||||
|
|
||||||
public bool ResetAdvancedDyes
|
public bool ResetAdvancedDyes
|
||||||
=> combo.Design?.ResetAdvancedDyes ?? false;
|
=> combo.Design?.ResetAdvancedDyes ?? false;
|
||||||
|
|
||||||
|
public bool ResetTemporarySettings
|
||||||
|
=> combo.Design?.ResetTemporarySettings ?? false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -92,8 +92,11 @@ public class RandomDesign(RandomDesignGenerator rng) : IDesignStandIn
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ForcedRedraw
|
public bool ForcedRedraw
|
||||||
=> false;
|
=> _currentDesign?.ForcedRedraw ?? false;
|
||||||
|
|
||||||
public bool ResetAdvancedDyes
|
public bool ResetAdvancedDyes
|
||||||
=> false;
|
=> _currentDesign?.ResetAdvancedDyes ?? false;
|
||||||
|
|
||||||
|
public bool ResetTemporarySettings
|
||||||
|
=> _currentDesign?.ResetTemporarySettings ?? false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,4 +48,7 @@ public class RevertDesign : IDesignStandIn
|
||||||
|
|
||||||
public bool ResetAdvancedDyes
|
public bool ResetAdvancedDyes
|
||||||
=> true;
|
=> true;
|
||||||
|
|
||||||
|
public bool ResetTemporarySettings
|
||||||
|
=> true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,9 @@ public sealed class DesignChanged()
|
||||||
/// <summary> An existing design had changed whether it always resets advanced dyes or not. </summary>
|
/// <summary> An existing design had changed whether it always resets advanced dyes or not. </summary>
|
||||||
ResetAdvancedDyes,
|
ResetAdvancedDyes,
|
||||||
|
|
||||||
|
/// <summary> An existing design had changed whether it always resets all prior temporary settings or not. </summary>
|
||||||
|
ResetTemporarySettings,
|
||||||
|
|
||||||
/// <summary> An existing design changed whether a specific customization is applied. </summary>
|
/// <summary> An existing design changed whether a specific customization is applied. </summary>
|
||||||
ApplyCustomize,
|
ApplyCustomize,
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,7 @@ public class ActorPanel
|
||||||
return;
|
return;
|
||||||
ImGui.TableSetupScrollFreeze(0, 1);
|
ImGui.TableSetupScrollFreeze(0, 1);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Dummy(Vector2.Zero);
|
||||||
var transformationId = _actor.IsCharacter ? _actor.AsCharacter->CharacterData.TransformationId : 0;
|
var transformationId = _actor.IsCharacter ? _actor.AsCharacter->CharacterData.TransformationId : 0;
|
||||||
if (transformationId != 0)
|
if (transformationId != 0)
|
||||||
ImGuiUtil.DrawTextButton($"Currently transformed to Transformation {transformationId}.",
|
ImGuiUtil.DrawTextButton($"Currently transformed to Transformation {transformationId}.",
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ using ImGuiNET;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
|
using OtterGui.Text;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Tabs.DesignTab;
|
namespace Glamourer.Gui.Tabs.DesignTab;
|
||||||
|
|
@ -41,7 +42,7 @@ public class DesignDetailTab
|
||||||
|
|
||||||
public void Draw()
|
public void Draw()
|
||||||
{
|
{
|
||||||
using var h = ImRaii.CollapsingHeader("Design Details");
|
using var h = ImUtf8.CollapsingHeaderId("Design Details"u8);
|
||||||
if (!h)
|
if (!h)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -54,19 +55,19 @@ public class DesignDetailTab
|
||||||
private void DrawDesignInfoTable()
|
private void DrawDesignInfoTable()
|
||||||
{
|
{
|
||||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ButtonTextAlign, new Vector2(0, 0.5f));
|
using var style = ImRaii.PushStyle(ImGuiStyleVar.ButtonTextAlign, new Vector2(0, 0.5f));
|
||||||
using var table = ImRaii.Table("Details", 2);
|
using var table = ImUtf8.Table("Details"u8, 2);
|
||||||
if (!table)
|
if (!table)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ImGui.TableSetupColumn("Type", ImGuiTableColumnFlags.WidthFixed, ImGui.CalcTextSize("Reset Advanced Dyes").X);
|
ImUtf8.TableSetupColumn("Type"u8, ImGuiTableColumnFlags.WidthFixed, ImUtf8.CalcTextSize("Reset Temporary Settings"u8).X);
|
||||||
ImGui.TableSetupColumn("Data", ImGuiTableColumnFlags.WidthStretch);
|
ImUtf8.TableSetupColumn("Data"u8, ImGuiTableColumnFlags.WidthStretch);
|
||||||
|
|
||||||
ImGuiUtil.DrawFrameColumn("Design Name");
|
ImUtf8.DrawFrameColumn("Design Name"u8);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
var width = new Vector2(ImGui.GetContentRegionAvail().X, 0);
|
var width = new Vector2(ImGui.GetContentRegionAvail().X, 0);
|
||||||
var name = _newName ?? _selector.Selected!.Name;
|
var name = _newName ?? _selector.Selected!.Name;
|
||||||
ImGui.SetNextItemWidth(width.X);
|
ImGui.SetNextItemWidth(width.X);
|
||||||
if (ImGui.InputText("##Name", ref name, 128))
|
if (ImUtf8.InputText("##Name"u8, ref name))
|
||||||
{
|
{
|
||||||
_newName = name;
|
_newName = name;
|
||||||
_changeDesign = _selector.Selected;
|
_changeDesign = _selector.Selected;
|
||||||
|
|
@ -80,10 +81,10 @@ public class DesignDetailTab
|
||||||
}
|
}
|
||||||
|
|
||||||
var identifier = _selector.Selected!.Identifier.ToString();
|
var identifier = _selector.Selected!.Identifier.ToString();
|
||||||
ImGuiUtil.DrawFrameColumn("Unique Identifier");
|
ImUtf8.DrawFrameColumn("Unique Identifier"u8);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
var fileName = _saveService.FileNames.DesignFile(_selector.Selected!);
|
var fileName = _saveService.FileNames.DesignFile(_selector.Selected!);
|
||||||
using (var mono = ImRaii.PushFont(UiBuilder.MonoFont))
|
using (ImRaii.PushFont(UiBuilder.MonoFont))
|
||||||
{
|
{
|
||||||
if (ImGui.Button(identifier, width))
|
if (ImGui.Button(identifier, width))
|
||||||
try
|
try
|
||||||
|
|
@ -100,14 +101,14 @@ public class DesignDetailTab
|
||||||
ImGui.SetClipboardText(identifier);
|
ImGui.SetClipboardText(identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiUtil.HoverTooltip(
|
ImUtf8.HoverTooltip(
|
||||||
$"Open the file\n\t{fileName}\ncontaining this design in the .json-editor of your choice.\n\nRight-Click to copy identifier to clipboard.");
|
$"Open the file\n\t{fileName}\ncontaining this design in the .json-editor of your choice.\n\nRight-Click to copy identifier to clipboard.");
|
||||||
|
|
||||||
ImGuiUtil.DrawFrameColumn("Full Selector Path");
|
ImUtf8.DrawFrameColumn("Full Selector Path"u8);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
var path = _newPath ?? _selector.SelectedLeaf!.FullName();
|
var path = _newPath ?? _selector.SelectedLeaf!.FullName();
|
||||||
ImGui.SetNextItemWidth(width.X);
|
ImGui.SetNextItemWidth(width.X);
|
||||||
if (ImGui.InputText("##Path", ref path, 1024))
|
if (ImUtf8.InputText("##Path"u8, ref path))
|
||||||
{
|
{
|
||||||
_newPath = path;
|
_newPath = path;
|
||||||
_changeLeaf = _selector.SelectedLeaf!;
|
_changeLeaf = _selector.SelectedLeaf!;
|
||||||
|
|
@ -125,32 +126,42 @@ public class DesignDetailTab
|
||||||
Glamourer.Messager.NotificationMessage(ex, ex.Message, "Could not rename or move design", NotificationType.Error);
|
Glamourer.Messager.NotificationMessage(ex, ex.Message, "Could not rename or move design", NotificationType.Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiUtil.DrawFrameColumn("Quick Design Bar");
|
ImUtf8.DrawFrameColumn("Quick Design Bar"u8);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
if (ImGui.RadioButton("Display##qdb", _selector.Selected.QuickDesign))
|
if (ImUtf8.RadioButton("Display##qdb"u8, _selector.Selected.QuickDesign))
|
||||||
_manager.SetQuickDesign(_selector.Selected!, true);
|
_manager.SetQuickDesign(_selector.Selected!, true);
|
||||||
var hovered = ImGui.IsItemHovered();
|
var hovered = ImGui.IsItemHovered();
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
if (ImGui.RadioButton("Hide##qdb", !_selector.Selected.QuickDesign))
|
if (ImUtf8.RadioButton("Hide##qdb"u8, !_selector.Selected.QuickDesign))
|
||||||
_manager.SetQuickDesign(_selector.Selected!, false);
|
_manager.SetQuickDesign(_selector.Selected!, false);
|
||||||
if (hovered || ImGui.IsItemHovered())
|
if (hovered || ImGui.IsItemHovered())
|
||||||
ImGui.SetTooltip("Display or hide this design in your quick design bar.");
|
{
|
||||||
|
using var tt = ImUtf8.Tooltip();
|
||||||
|
ImUtf8.Text("Display or hide this design in your quick design bar."u8);
|
||||||
|
}
|
||||||
|
|
||||||
var forceRedraw = _selector.Selected!.ForcedRedraw;
|
var forceRedraw = _selector.Selected!.ForcedRedraw;
|
||||||
ImGuiUtil.DrawFrameColumn("Force Redrawing");
|
ImUtf8.DrawFrameColumn("Force Redrawing"u8);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
if (ImGui.Checkbox("##ForceRedraw", ref forceRedraw))
|
if (ImUtf8.Checkbox("##ForceRedraw"u8, ref forceRedraw))
|
||||||
_manager.ChangeForcedRedraw(_selector.Selected!, forceRedraw);
|
_manager.ChangeForcedRedraw(_selector.Selected!, forceRedraw);
|
||||||
ImGuiUtil.HoverTooltip("Set this design to always force a redraw when it is applied through any means.");
|
ImUtf8.HoverTooltip("Set this design to always force a redraw when it is applied through any means."u8);
|
||||||
|
|
||||||
var resetAdvancedDyes = _selector.Selected!.ResetAdvancedDyes;
|
var resetAdvancedDyes = _selector.Selected!.ResetAdvancedDyes;
|
||||||
ImGuiUtil.DrawFrameColumn("Reset Advanced Dyes");
|
ImUtf8.DrawFrameColumn("Reset Advanced Dyes"u8);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
if (ImGui.Checkbox("##ResetAdvancedDyes", ref resetAdvancedDyes))
|
if (ImUtf8.Checkbox("##ResetAdvancedDyes"u8, ref resetAdvancedDyes))
|
||||||
_manager.ChangeResetAdvancedDyes(_selector.Selected!, resetAdvancedDyes);
|
_manager.ChangeResetAdvancedDyes(_selector.Selected!, resetAdvancedDyes);
|
||||||
ImGuiUtil.HoverTooltip("Set this design to reset any previously applied advanced dyes when it is applied through any means.");
|
ImUtf8.HoverTooltip("Set this design to reset any previously applied advanced dyes when it is applied through any means."u8);
|
||||||
|
|
||||||
ImGuiUtil.DrawFrameColumn("Color");
|
var resetTemporarySettings = _selector.Selected!.ResetTemporarySettings;
|
||||||
|
ImUtf8.DrawFrameColumn("Reset Temporary Settings"u8);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
if (ImUtf8.Checkbox("##ResetTemporarySettings"u8, ref resetTemporarySettings))
|
||||||
|
_manager.ChangeResetTemporarySettings(_selector.Selected!, resetTemporarySettings);
|
||||||
|
ImUtf8.HoverTooltip("Set this design to reset any temporary settings previously applied to the associated collection when it is applied through any means."u8);
|
||||||
|
|
||||||
|
ImUtf8.DrawFrameColumn("Color"u8);
|
||||||
var colorName = _selector.Selected!.Color.Length == 0 ? DesignColors.AutomaticName : _selector.Selected!.Color;
|
var colorName = _selector.Selected!.Color.Length == 0 ? DesignColors.AutomaticName : _selector.Selected!.Color;
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
if (_colorCombo.Draw("##colorCombo", colorName, "Associate a color with this design.\n"
|
if (_colorCombo.Draw("##colorCombo", colorName, "Associate a color with this design.\n"
|
||||||
|
|
@ -178,18 +189,18 @@ public class DesignDetailTab
|
||||||
var size = new Vector2(ImGui.GetFrameHeight());
|
var size = new Vector2(ImGui.GetFrameHeight());
|
||||||
using var font = ImRaii.PushFont(UiBuilder.IconFont);
|
using var font = ImRaii.PushFont(UiBuilder.IconFont);
|
||||||
ImGuiUtil.DrawTextButton(FontAwesomeIcon.ExclamationCircle.ToIconString(), size, 0, _colors.MissingColor);
|
ImGuiUtil.DrawTextButton(FontAwesomeIcon.ExclamationCircle.ToIconString(), size, 0, _colors.MissingColor);
|
||||||
ImGuiUtil.HoverTooltip("The color associated with this design does not exist.");
|
ImUtf8.HoverTooltip("The color associated with this design does not exist."u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiUtil.DrawFrameColumn("Creation Date");
|
ImUtf8.DrawFrameColumn("Creation Date"u8);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGuiUtil.DrawTextButton(_selector.Selected!.CreationDate.LocalDateTime.ToString("F"), width, 0);
|
ImGuiUtil.DrawTextButton(_selector.Selected!.CreationDate.LocalDateTime.ToString("F"), width, 0);
|
||||||
|
|
||||||
ImGuiUtil.DrawFrameColumn("Last Update Date");
|
ImUtf8.DrawFrameColumn("Last Update Date"u8);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGuiUtil.DrawTextButton(_selector.Selected!.LastEdit.LocalDateTime.ToString("F"), width, 0);
|
ImGuiUtil.DrawTextButton(_selector.Selected!.LastEdit.LocalDateTime.ToString("F"), width, 0);
|
||||||
|
|
||||||
ImGuiUtil.DrawFrameColumn("Tags");
|
ImUtf8.DrawFrameColumn("Tags"u8);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
DrawTags();
|
DrawTags();
|
||||||
}
|
}
|
||||||
|
|
@ -219,18 +230,18 @@ public class DesignDetailTab
|
||||||
var size = new Vector2(ImGui.GetContentRegionAvail().X, 12 * ImGui.GetTextLineHeightWithSpacing());
|
var size = new Vector2(ImGui.GetContentRegionAvail().X, 12 * ImGui.GetTextLineHeightWithSpacing());
|
||||||
if (!_editDescriptionMode)
|
if (!_editDescriptionMode)
|
||||||
{
|
{
|
||||||
using (var textBox = ImRaii.ListBox("##desc", size))
|
using (var textBox = ImUtf8.ListBox("##desc"u8, size))
|
||||||
{
|
{
|
||||||
ImGuiUtil.TextWrapped(desc);
|
ImUtf8.TextWrapped(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.Button("Edit Description"))
|
if (ImUtf8.Button("Edit Description"u8))
|
||||||
_editDescriptionMode = true;
|
_editDescriptionMode = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var edit = _newDescription ?? desc;
|
var edit = _newDescription ?? desc;
|
||||||
if (ImGui.InputTextMultiline("##desc", ref edit, (uint)Math.Max(2000, 4 * edit.Length), size))
|
if (ImUtf8.InputMultiLine("##desc"u8, ref edit, size))
|
||||||
_newDescription = edit;
|
_newDescription = edit;
|
||||||
|
|
||||||
if (ImGui.IsItemDeactivatedAfterEdit())
|
if (ImGui.IsItemDeactivatedAfterEdit())
|
||||||
|
|
@ -239,7 +250,7 @@ public class DesignDetailTab
|
||||||
_newDescription = null;
|
_newDescription = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.Button("Stop Editing"))
|
if (ImUtf8.Button("Stop Editing"u8))
|
||||||
_editDescriptionMode = false;
|
_editDescriptionMode = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -423,6 +423,7 @@ public class DesignPanel
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
if (_selector.Selected == null)
|
if (_selector.Selected == null)
|
||||||
return;
|
return;
|
||||||
|
ImGui.Dummy(Vector2.Zero);
|
||||||
DrawButtonRow();
|
DrawButtonRow();
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
|
|
@ -438,7 +439,6 @@ public class DesignPanel
|
||||||
|
|
||||||
private void DrawButtonRow()
|
private void DrawButtonRow()
|
||||||
{
|
{
|
||||||
ImGui.Dummy(Vector2.Zero);
|
|
||||||
DrawApplyToSelf();
|
DrawApplyToSelf();
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
DrawApplyToTarget();
|
DrawApplyToTarget();
|
||||||
|
|
|
||||||
|
|
@ -88,16 +88,18 @@ public class ModAssociationsTab(PenumbraService penumbra, DesignFileSystemSelect
|
||||||
|
|
||||||
private void DrawTable()
|
private void DrawTable()
|
||||||
{
|
{
|
||||||
using var table = ImRaii.Table("Mods", 5, ImGuiTableFlags.RowBg);
|
using var table = ImUtf8.Table("Mods"u8, 7, ImGuiTableFlags.RowBg);
|
||||||
if (!table)
|
if (!table)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ImGui.TableSetupColumn("##Buttons", ImGuiTableColumnFlags.WidthFixed,
|
ImUtf8.TableSetupColumn("##Buttons"u8, ImGuiTableColumnFlags.WidthFixed,
|
||||||
ImGui.GetFrameHeight() * 3 + ImGui.GetStyle().ItemInnerSpacing.X * 2);
|
ImGui.GetFrameHeight() * 3 + ImGui.GetStyle().ItemInnerSpacing.X * 2);
|
||||||
ImGui.TableSetupColumn("Mod Name", ImGuiTableColumnFlags.WidthStretch);
|
ImUtf8.TableSetupColumn("Mod Name"u8, ImGuiTableColumnFlags.WidthStretch);
|
||||||
ImGui.TableSetupColumn("State", ImGuiTableColumnFlags.WidthFixed, ImGui.CalcTextSize("State").X);
|
ImUtf8.TableSetupColumn("Remove"u8, ImGuiTableColumnFlags.WidthFixed, ImUtf8.CalcTextSize("Remove"u8).X);
|
||||||
ImGui.TableSetupColumn("Priority", ImGuiTableColumnFlags.WidthFixed, ImGui.CalcTextSize("Priority").X);
|
ImUtf8.TableSetupColumn("Inherit"u8, ImGuiTableColumnFlags.WidthFixed, ImUtf8.CalcTextSize("Inherit"u8).X);
|
||||||
ImGui.TableSetupColumn("##Options", ImGuiTableColumnFlags.WidthFixed, ImGui.CalcTextSize("Applym").X);
|
ImUtf8.TableSetupColumn("State"u8, ImGuiTableColumnFlags.WidthFixed, ImUtf8.CalcTextSize("State"u8).X);
|
||||||
|
ImUtf8.TableSetupColumn("Priority"u8, ImGuiTableColumnFlags.WidthFixed, ImUtf8.CalcTextSize("Priority"u8).X);
|
||||||
|
ImUtf8.TableSetupColumn("##Options"u8, ImGuiTableColumnFlags.WidthFixed, ImUtf8.CalcTextSize("Applym"u8).X);
|
||||||
ImGui.TableHeadersRow();
|
ImGui.TableHeadersRow();
|
||||||
|
|
||||||
Mod? removedMod = null;
|
Mod? removedMod = null;
|
||||||
|
|
@ -183,6 +185,17 @@ public class ModAssociationsTab(PenumbraService penumbra, DesignFileSystemSelect
|
||||||
if (ImGui.IsItemHovered())
|
if (ImGui.IsItemHovered())
|
||||||
ImGui.SetTooltip($"Mod Directory: {mod.DirectoryName}\n\nClick to open mod page in Penumbra.");
|
ImGui.SetTooltip($"Mod Directory: {mod.DirectoryName}\n\nClick to open mod page in Penumbra.");
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
var remove = settings.Remove;
|
||||||
|
if (TwoStateCheckbox.Instance.Draw("##Remove"u8, ref remove))
|
||||||
|
updatedMod = (mod, settings with { Remove = remove });
|
||||||
|
ImUtf8.HoverTooltip(
|
||||||
|
"Remove any temporary settings applied by Glamourer instead of applying the configured settings. Only works when using temporary settings, ignored otherwise."u8);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
var inherit = settings.ForceInherit;
|
||||||
|
if (TwoStateCheckbox.Instance.Draw("##Enabled"u8, ref inherit))
|
||||||
|
updatedMod = (mod, settings with { ForceInherit = inherit });
|
||||||
|
ImUtf8.HoverTooltip("Force the mod to inherit its settings from inherited collections."u8);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
var enabled = settings.Enabled;
|
var enabled = settings.Enabled;
|
||||||
if (TwoStateCheckbox.Instance.Draw("##Enabled"u8, ref enabled))
|
if (TwoStateCheckbox.Instance.Draw("##Enabled"u8, ref enabled))
|
||||||
updatedMod = (mod, settings with { Enabled = enabled });
|
updatedMod = (mod, settings with { Enabled = enabled });
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,9 @@ public class SettingsTab(
|
||||||
+ "Glamourer will NOT revert these applied settings automatically. This may mess up your collection and configuration.\n\n"
|
+ "Glamourer will NOT revert these applied settings automatically. This may mess up your collection and configuration.\n\n"
|
||||||
+ "If you enable this setting, you are aware that any resulting misconfiguration is your own fault.",
|
+ "If you enable this setting, you are aware that any resulting misconfiguration is your own fault.",
|
||||||
config.AlwaysApplyAssociatedMods, v => config.AlwaysApplyAssociatedMods = v);
|
config.AlwaysApplyAssociatedMods, v => config.AlwaysApplyAssociatedMods = v);
|
||||||
|
Checkbox("Use Temporary Mod Settings",
|
||||||
|
"Apply all settings as temporary settings so they will be reset when Glamourer or the game shut down.", config.UseTemporarySettings,
|
||||||
|
v => config.UseTemporarySettings = v);
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -120,6 +123,8 @@ public class SettingsTab(
|
||||||
config.DefaultDesignSettings.ResetAdvancedDyes, v => config.DefaultDesignSettings.ResetAdvancedDyes = v);
|
config.DefaultDesignSettings.ResetAdvancedDyes, v => config.DefaultDesignSettings.ResetAdvancedDyes = v);
|
||||||
Checkbox("Always Force Redraw", "Newly created designs will be configured to force character redraws on application by default.",
|
Checkbox("Always Force Redraw", "Newly created designs will be configured to force character redraws on application by default.",
|
||||||
config.DefaultDesignSettings.AlwaysForceRedrawing, v => config.DefaultDesignSettings.AlwaysForceRedrawing = v);
|
config.DefaultDesignSettings.AlwaysForceRedrawing, v => config.DefaultDesignSettings.AlwaysForceRedrawing = v);
|
||||||
|
Checkbox("Reset Temporary Settings", "Newly created designs will be configured to clear all advanced settings applied by Glamourer to the collection by default.",
|
||||||
|
config.DefaultDesignSettings.ResetTemporarySettings, v => config.DefaultDesignSettings.ResetTemporarySettings = v);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawInterfaceSettings()
|
private void DrawInterfaceSettings()
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,15 @@ using Glamourer.Services;
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
using Penumbra.GameData.Interop;
|
using Penumbra.GameData.Interop;
|
||||||
|
using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
namespace Glamourer.Interop.Penumbra;
|
namespace Glamourer.Interop.Penumbra;
|
||||||
|
|
||||||
public class ModSettingApplier(PenumbraService penumbra, Configuration config, ObjectManager objects, CollectionOverrideService overrides)
|
public class ModSettingApplier(PenumbraService penumbra, Configuration config, ObjectManager objects, CollectionOverrideService overrides)
|
||||||
: IService
|
: IService
|
||||||
{
|
{
|
||||||
|
private readonly HashSet<Guid> _collectionTracker = [];
|
||||||
|
|
||||||
public void HandleStateApplication(ActorState state, MergedDesign design)
|
public void HandleStateApplication(ActorState state, MergedDesign design)
|
||||||
{
|
{
|
||||||
if (!config.AlwaysApplyAssociatedMods || design.AssociatedMods.Count == 0)
|
if (!config.AlwaysApplyAssociatedMods || design.AssociatedMods.Count == 0)
|
||||||
|
|
@ -22,20 +25,20 @@ public class ModSettingApplier(PenumbraService penumbra, Configuration config, O
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var collections = new HashSet<Guid>();
|
_collectionTracker.Clear();
|
||||||
|
|
||||||
foreach (var actor in data.Objects)
|
foreach (var actor in data.Objects)
|
||||||
{
|
{
|
||||||
var (collection, _, overridden) = overrides.GetCollection(actor, state.Identifier);
|
var (collection, _, overridden) = overrides.GetCollection(actor, state.Identifier);
|
||||||
if (collection == Guid.Empty)
|
if (collection == Guid.Empty)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!collections.Add(collection))
|
if (!_collectionTracker.Add(collection))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
var index = ResetOldSettings(collection, actor, design.ResetTemporarySettings);
|
||||||
foreach (var (mod, setting) in design.AssociatedMods)
|
foreach (var (mod, setting) in design.AssociatedMods)
|
||||||
{
|
{
|
||||||
var message = penumbra.SetMod(mod, setting, collection);
|
var message = penumbra.SetMod(mod, setting, collection, index);
|
||||||
if (message.Length > 0)
|
if (message.Length > 0)
|
||||||
Glamourer.Log.Verbose($"[Mod Applier] Error applying mod settings: {message}");
|
Glamourer.Log.Verbose($"[Mod Applier] Error applying mod settings: {message}");
|
||||||
else
|
else
|
||||||
|
|
@ -45,7 +48,8 @@ public class ModSettingApplier(PenumbraService penumbra, Configuration config, O
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public (List<string> Messages, int Applied, Guid Collection, string Name, bool Overridden) ApplyModSettings(IReadOnlyDictionary<Mod, ModSettings> settings, Actor actor)
|
public (List<string> Messages, int Applied, Guid Collection, string Name, bool Overridden) ApplyModSettings(
|
||||||
|
IReadOnlyDictionary<Mod, ModSettings> settings, Actor actor, bool resetOther)
|
||||||
{
|
{
|
||||||
var (collection, name, overridden) = overrides.GetCollection(actor);
|
var (collection, name, overridden) = overrides.GetCollection(actor);
|
||||||
if (collection == Guid.Empty)
|
if (collection == Guid.Empty)
|
||||||
|
|
@ -53,9 +57,11 @@ public class ModSettingApplier(PenumbraService penumbra, Configuration config, O
|
||||||
|
|
||||||
var messages = new List<string>();
|
var messages = new List<string>();
|
||||||
var appliedMods = 0;
|
var appliedMods = 0;
|
||||||
|
|
||||||
|
var index = ResetOldSettings(collection, actor, resetOther);
|
||||||
foreach (var (mod, setting) in settings)
|
foreach (var (mod, setting) in settings)
|
||||||
{
|
{
|
||||||
var message = penumbra.SetMod(mod, setting, collection);
|
var message = penumbra.SetMod(mod, setting, collection, index);
|
||||||
if (message.Length > 0)
|
if (message.Length > 0)
|
||||||
messages.Add($"Error applying mod settings: {message}");
|
messages.Add($"Error applying mod settings: {message}");
|
||||||
else
|
else
|
||||||
|
|
@ -64,4 +70,18 @@ public class ModSettingApplier(PenumbraService penumbra, Configuration config, O
|
||||||
|
|
||||||
return (messages, appliedMods, collection, name, overridden);
|
return (messages, appliedMods, collection, name, overridden);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private ObjectIndex? ResetOldSettings(Guid collection, Actor actor, bool resetOther)
|
||||||
|
{
|
||||||
|
ObjectIndex? index = actor.Valid ? actor.Index : null;
|
||||||
|
if (!resetOther)
|
||||||
|
return index;
|
||||||
|
|
||||||
|
if (index == null)
|
||||||
|
penumbra.RemoveAllTemporarySettings(collection);
|
||||||
|
else
|
||||||
|
penumbra.RemoveAllTemporarySettings(index.Value);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,10 @@ public readonly record struct Mod(string Name, string DirectoryName) : IComparab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly record struct ModSettings(Dictionary<string, List<string>> Settings, int Priority, bool Enabled)
|
public readonly record struct ModSettings(Dictionary<string, List<string>> Settings, int Priority, bool Enabled, bool ForceInherit, bool Remove)
|
||||||
{
|
{
|
||||||
public ModSettings()
|
public ModSettings()
|
||||||
: this(new Dictionary<string, List<string>>(), 0, false)
|
: this(new Dictionary<string, List<string>>(), 0, false, false, false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public static ModSettings Empty
|
public static ModSettings Empty
|
||||||
|
|
@ -33,30 +33,41 @@ public readonly record struct ModSettings(Dictionary<string, List<string>> Setti
|
||||||
|
|
||||||
public class PenumbraService : IDisposable
|
public class PenumbraService : IDisposable
|
||||||
{
|
{
|
||||||
public const int RequiredPenumbraBreakingVersion = 5;
|
public const int RequiredPenumbraBreakingVersion = 5;
|
||||||
public const int RequiredPenumbraFeatureVersion = 0;
|
public const int RequiredPenumbraFeatureVersion = 3;
|
||||||
|
public const int RequiredPenumbraFeatureVersionTemp = 4;
|
||||||
|
|
||||||
private readonly IDalamudPluginInterface _pluginInterface;
|
private const int Key = -1610;
|
||||||
|
|
||||||
|
private readonly IDalamudPluginInterface _pluginInterface;
|
||||||
|
private readonly Configuration _config;
|
||||||
private readonly EventSubscriber<ChangedItemType, uint> _tooltipSubscriber;
|
private readonly EventSubscriber<ChangedItemType, uint> _tooltipSubscriber;
|
||||||
private readonly EventSubscriber<MouseButton, ChangedItemType, uint> _clickSubscriber;
|
private readonly EventSubscriber<MouseButton, ChangedItemType, uint> _clickSubscriber;
|
||||||
private readonly EventSubscriber<nint, Guid, nint, nint, nint> _creatingCharacterBase;
|
private readonly EventSubscriber<nint, Guid, nint, nint, nint> _creatingCharacterBase;
|
||||||
private readonly EventSubscriber<nint, Guid, nint> _createdCharacterBase;
|
private readonly EventSubscriber<nint, Guid, nint> _createdCharacterBase;
|
||||||
private readonly EventSubscriber<ModSettingChange, Guid, string, bool> _modSettingChanged;
|
private readonly EventSubscriber<ModSettingChange, Guid, string, bool> _modSettingChanged;
|
||||||
|
|
||||||
private global::Penumbra.Api.IpcSubscribers.GetCollectionsByIdentifier? _collectionByIdentifier;
|
private global::Penumbra.Api.IpcSubscribers.GetCollectionsByIdentifier? _collectionByIdentifier;
|
||||||
private global::Penumbra.Api.IpcSubscribers.GetCollections? _collections;
|
private global::Penumbra.Api.IpcSubscribers.GetCollections? _collections;
|
||||||
private global::Penumbra.Api.IpcSubscribers.RedrawObject? _redraw;
|
private global::Penumbra.Api.IpcSubscribers.RedrawObject? _redraw;
|
||||||
private global::Penumbra.Api.IpcSubscribers.GetDrawObjectInfo? _drawObjectInfo;
|
private global::Penumbra.Api.IpcSubscribers.GetDrawObjectInfo? _drawObjectInfo;
|
||||||
private global::Penumbra.Api.IpcSubscribers.GetCutsceneParentIndex? _cutsceneParent;
|
private global::Penumbra.Api.IpcSubscribers.GetCutsceneParentIndex? _cutsceneParent;
|
||||||
private global::Penumbra.Api.IpcSubscribers.GetCollectionForObject? _objectCollection;
|
private global::Penumbra.Api.IpcSubscribers.GetCollectionForObject? _objectCollection;
|
||||||
private global::Penumbra.Api.IpcSubscribers.GetModList? _getMods;
|
private global::Penumbra.Api.IpcSubscribers.GetModList? _getMods;
|
||||||
private global::Penumbra.Api.IpcSubscribers.GetCollection? _currentCollection;
|
private global::Penumbra.Api.IpcSubscribers.GetCollection? _currentCollection;
|
||||||
private global::Penumbra.Api.IpcSubscribers.GetCurrentModSettings? _getCurrentSettings;
|
private global::Penumbra.Api.IpcSubscribers.GetCurrentModSettings? _getCurrentSettings;
|
||||||
private global::Penumbra.Api.IpcSubscribers.TrySetMod? _setMod;
|
private global::Penumbra.Api.IpcSubscribers.TryInheritMod? _inheritMod;
|
||||||
private global::Penumbra.Api.IpcSubscribers.TrySetModPriority? _setModPriority;
|
private global::Penumbra.Api.IpcSubscribers.TrySetMod? _setMod;
|
||||||
private global::Penumbra.Api.IpcSubscribers.TrySetModSetting? _setModSetting;
|
private global::Penumbra.Api.IpcSubscribers.TrySetModPriority? _setModPriority;
|
||||||
private global::Penumbra.Api.IpcSubscribers.TrySetModSettings? _setModSettings;
|
private global::Penumbra.Api.IpcSubscribers.TrySetModSetting? _setModSetting;
|
||||||
private global::Penumbra.Api.IpcSubscribers.OpenMainWindow? _openModPage;
|
private global::Penumbra.Api.IpcSubscribers.TrySetModSettings? _setModSettings;
|
||||||
|
private global::Penumbra.Api.IpcSubscribers.SetTemporaryModSettings? _setTemporaryModSettings;
|
||||||
|
private global::Penumbra.Api.IpcSubscribers.SetTemporaryModSettingsPlayer? _setTemporaryModSettingsPlayer;
|
||||||
|
private global::Penumbra.Api.IpcSubscribers.RemoveTemporaryModSettings? _removeTemporaryModSettings;
|
||||||
|
private global::Penumbra.Api.IpcSubscribers.RemoveTemporaryModSettingsPlayer? _removeTemporaryModSettingsPlayer;
|
||||||
|
private global::Penumbra.Api.IpcSubscribers.RemoveAllTemporaryModSettings? _removeAllTemporaryModSettings;
|
||||||
|
private global::Penumbra.Api.IpcSubscribers.RemoveAllTemporaryModSettingsPlayer? _removeAllTemporaryModSettingsPlayer;
|
||||||
|
private global::Penumbra.Api.IpcSubscribers.OpenMainWindow? _openModPage;
|
||||||
|
|
||||||
private readonly IDisposable _initializedEvent;
|
private readonly IDisposable _initializedEvent;
|
||||||
private readonly IDisposable _disposedEvent;
|
private readonly IDisposable _disposedEvent;
|
||||||
|
|
@ -68,10 +79,11 @@ public class PenumbraService : IDisposable
|
||||||
public int CurrentMinor { get; private set; }
|
public int CurrentMinor { get; private set; }
|
||||||
public DateTime AttachTime { get; private set; }
|
public DateTime AttachTime { get; private set; }
|
||||||
|
|
||||||
public PenumbraService(IDalamudPluginInterface pi, PenumbraReloaded penumbraReloaded)
|
public PenumbraService(IDalamudPluginInterface pi, PenumbraReloaded penumbraReloaded, Configuration config)
|
||||||
{
|
{
|
||||||
_pluginInterface = pi;
|
_pluginInterface = pi;
|
||||||
_penumbraReloaded = penumbraReloaded;
|
_penumbraReloaded = penumbraReloaded;
|
||||||
|
_config = config;
|
||||||
_initializedEvent = global::Penumbra.Api.IpcSubscribers.Initialized.Subscriber(pi, Reattach);
|
_initializedEvent = global::Penumbra.Api.IpcSubscribers.Initialized.Subscriber(pi, Reattach);
|
||||||
_disposedEvent = global::Penumbra.Api.IpcSubscribers.Disposed.Subscriber(pi, Unattach);
|
_disposedEvent = global::Penumbra.Api.IpcSubscribers.Disposed.Subscriber(pi, Unattach);
|
||||||
_tooltipSubscriber = global::Penumbra.Api.IpcSubscribers.ChangedItemTooltip.Subscriber(pi);
|
_tooltipSubscriber = global::Penumbra.Api.IpcSubscribers.ChangedItemTooltip.Subscriber(pi);
|
||||||
|
|
@ -128,7 +140,7 @@ public class PenumbraService : IDisposable
|
||||||
if (ec is not PenumbraApiEc.Success)
|
if (ec is not PenumbraApiEc.Success)
|
||||||
return ModSettings.Empty;
|
return ModSettings.Empty;
|
||||||
|
|
||||||
return tuple.HasValue ? new ModSettings(tuple.Value.Item3, tuple.Value.Item2, tuple.Value.Item1) : ModSettings.Empty;
|
return tuple.HasValue ? new ModSettings(tuple.Value.Item3, tuple.Value.Item2, tuple.Value.Item1, false, false) : ModSettings.Empty;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -164,7 +176,7 @@ public class PenumbraService : IDisposable
|
||||||
.Select(t => (new Mod(t.Item2, t.Item1),
|
.Select(t => (new Mod(t.Item2, t.Item1),
|
||||||
!t.Item3.Item2.HasValue
|
!t.Item3.Item2.HasValue
|
||||||
? ModSettings.Empty
|
? ModSettings.Empty
|
||||||
: new ModSettings(t.Item3.Item2!.Value.Item3, t.Item3.Item2!.Value.Item2, t.Item3.Item2!.Value.Item1)))
|
: new ModSettings(t.Item3.Item2!.Value.Item3, t.Item3.Item2!.Value.Item2, t.Item3.Item2!.Value.Item1, false, false)))
|
||||||
.OrderByDescending(p => p.Item2.Enabled)
|
.OrderByDescending(p => p.Item2.Enabled)
|
||||||
.ThenBy(p => p.Item1.Name)
|
.ThenBy(p => p.Item1.Name)
|
||||||
.ThenBy(p => p.Item1.DirectoryName)
|
.ThenBy(p => p.Item1.DirectoryName)
|
||||||
|
|
@ -195,7 +207,7 @@ public class PenumbraService : IDisposable
|
||||||
/// Try to set all mod settings as desired. Only sets when the mod should be enabled.
|
/// Try to set all mod settings as desired. Only sets when the mod should be enabled.
|
||||||
/// If it is disabled, ignore all other settings.
|
/// If it is disabled, ignore all other settings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string SetMod(Mod mod, ModSettings settings, Guid? collectionInput = null)
|
public string SetMod(Mod mod, ModSettings settings, Guid? collectionInput = null, ObjectIndex? index = null)
|
||||||
{
|
{
|
||||||
if (!Available)
|
if (!Available)
|
||||||
return "Penumbra is not available.";
|
return "Penumbra is not available.";
|
||||||
|
|
@ -204,40 +216,10 @@ public class PenumbraService : IDisposable
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var collection = collectionInput ?? _currentCollection!.Invoke(ApiCollectionType.Current)!.Value.Id;
|
var collection = collectionInput ?? _currentCollection!.Invoke(ApiCollectionType.Current)!.Value.Id;
|
||||||
var ec = _setMod!.Invoke(collection, mod.DirectoryName, settings.Enabled);
|
if (_config.UseTemporarySettings && _setTemporaryModSettings != null)
|
||||||
switch (ec)
|
SetModTemporary(sb, mod, settings, collection, index);
|
||||||
{
|
else
|
||||||
case PenumbraApiEc.ModMissing: return $"The mod {mod.Name} [{mod.DirectoryName}] could not be found.";
|
SetModPermanent(sb, mod, settings, collection);
|
||||||
case PenumbraApiEc.CollectionMissing: return $"The collection {collection} could not be found.";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!settings.Enabled)
|
|
||||||
return string.Empty;
|
|
||||||
|
|
||||||
ec = _setModPriority!.Invoke(collection, mod.DirectoryName, settings.Priority);
|
|
||||||
Debug.Assert(ec is PenumbraApiEc.Success or PenumbraApiEc.NothingChanged, "Setting Priority should not be able to fail.");
|
|
||||||
|
|
||||||
foreach (var (setting, list) in settings.Settings)
|
|
||||||
{
|
|
||||||
ec = list.Count == 1
|
|
||||||
? _setModSetting!.Invoke(collection, mod.DirectoryName, setting, list[0])
|
|
||||||
: _setModSettings!.Invoke(collection, mod.DirectoryName, setting, list);
|
|
||||||
switch (ec)
|
|
||||||
{
|
|
||||||
case PenumbraApiEc.OptionGroupMissing:
|
|
||||||
sb.AppendLine($"Could not find the option group {setting} in mod {mod.Name}.");
|
|
||||||
break;
|
|
||||||
case PenumbraApiEc.OptionMissing:
|
|
||||||
sb.AppendLine($"Could not find all desired options in the option group {setting} in mod {mod.Name}.");
|
|
||||||
break;
|
|
||||||
case PenumbraApiEc.Success:
|
|
||||||
case PenumbraApiEc.NothingChanged:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sb.AppendLine($"Could not apply options in the option group {setting} in mod {mod.Name} for unknown reason {ec}.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
@ -247,6 +229,103 @@ public class PenumbraService : IDisposable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RemoveAllTemporarySettings(Guid collection)
|
||||||
|
=> _removeAllTemporaryModSettings?.Invoke(collection, Key);
|
||||||
|
|
||||||
|
public void RemoveAllTemporarySettings(ObjectIndex index)
|
||||||
|
=> _removeAllTemporaryModSettingsPlayer?.Invoke(index.Index, Key);
|
||||||
|
|
||||||
|
public void ClearAllTemporarySettings()
|
||||||
|
{
|
||||||
|
if (!Available || _removeAllTemporaryModSettings == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var collections = _collections!.Invoke();
|
||||||
|
foreach (var collection in collections)
|
||||||
|
RemoveAllTemporarySettings(collection.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetModTemporary(StringBuilder sb, Mod mod, ModSettings settings, Guid collection, ObjectIndex? index)
|
||||||
|
{
|
||||||
|
var ex = settings.Remove
|
||||||
|
? index.HasValue
|
||||||
|
? _removeTemporaryModSettingsPlayer!.Invoke(index.Value.Index, mod.DirectoryName, Key)
|
||||||
|
: _removeTemporaryModSettings!.Invoke(collection, mod.DirectoryName, Key)
|
||||||
|
: index.HasValue
|
||||||
|
? _setTemporaryModSettingsPlayer!.Invoke(index.Value.Index, mod.DirectoryName, settings.ForceInherit, settings.Enabled,
|
||||||
|
settings.Priority,
|
||||||
|
settings.Settings.ToDictionary(kvp => kvp.Key, kvp => (IReadOnlyList<string>)kvp.Value), "Glamourer", Key)
|
||||||
|
: _setTemporaryModSettings!.Invoke(collection, mod.DirectoryName, settings.ForceInherit, settings.Enabled, settings.Priority,
|
||||||
|
settings.Settings.ToDictionary(kvp => kvp.Key, kvp => (IReadOnlyList<string>)kvp.Value), "Glamourer", Key);
|
||||||
|
switch (ex)
|
||||||
|
{
|
||||||
|
case PenumbraApiEc.InvalidArgument:
|
||||||
|
sb.Append($"No actor with index {index!.Value.Index} could be identified.");
|
||||||
|
return;
|
||||||
|
case PenumbraApiEc.ModMissing:
|
||||||
|
sb.Append($"The mod {mod.Name} [{mod.DirectoryName}] could not be found.");
|
||||||
|
return;
|
||||||
|
case PenumbraApiEc.CollectionMissing:
|
||||||
|
sb.Append($"The collection {collection} could not be found.");
|
||||||
|
return;
|
||||||
|
case PenumbraApiEc.TemporarySettingImpossible:
|
||||||
|
sb.Append($"The collection {collection} can not have settings.");
|
||||||
|
return;
|
||||||
|
case PenumbraApiEc.TemporarySettingDisallowed:
|
||||||
|
sb.Append($"The mod {mod.Name} [{mod.DirectoryName}] already has temporary settings with a different key in {collection}.");
|
||||||
|
return;
|
||||||
|
case PenumbraApiEc.OptionGroupMissing:
|
||||||
|
case PenumbraApiEc.OptionMissing:
|
||||||
|
sb.Append($"The provided settings for {mod.Name} [{mod.DirectoryName}] did not correspond to its actual options.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetModPermanent(StringBuilder sb, Mod mod, ModSettings settings, Guid collection)
|
||||||
|
{
|
||||||
|
var ec = settings.ForceInherit
|
||||||
|
? _inheritMod!.Invoke(collection, mod.DirectoryName, true)
|
||||||
|
: _setMod!.Invoke(collection, mod.DirectoryName, settings.Enabled);
|
||||||
|
switch (ec)
|
||||||
|
{
|
||||||
|
case PenumbraApiEc.ModMissing:
|
||||||
|
sb.Append($"The mod {mod.Name} [{mod.DirectoryName}] could not be found.");
|
||||||
|
return;
|
||||||
|
case PenumbraApiEc.CollectionMissing:
|
||||||
|
sb.Append($"The collection {collection} could not be found.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.ForceInherit || !settings.Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ec = _setModPriority!.Invoke(collection, mod.DirectoryName, settings.Priority);
|
||||||
|
Debug.Assert(ec is PenumbraApiEc.Success or PenumbraApiEc.NothingChanged, "Setting Priority should not be able to fail.");
|
||||||
|
|
||||||
|
foreach (var (setting, list) in settings.Settings)
|
||||||
|
{
|
||||||
|
ec = list.Count == 1
|
||||||
|
? _setModSetting!.Invoke(collection, mod.DirectoryName, setting, list[0])
|
||||||
|
: _setModSettings!.Invoke(collection, mod.DirectoryName, setting, list);
|
||||||
|
switch (ec)
|
||||||
|
{
|
||||||
|
case PenumbraApiEc.OptionGroupMissing:
|
||||||
|
sb.AppendLine($"Could not find the option group {setting} in mod {mod.Name}.");
|
||||||
|
break;
|
||||||
|
case PenumbraApiEc.OptionMissing:
|
||||||
|
sb.AppendLine($"Could not find all desired options in the option group {setting} in mod {mod.Name}.");
|
||||||
|
break;
|
||||||
|
case PenumbraApiEc.Success:
|
||||||
|
case PenumbraApiEc.NothingChanged:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sb.AppendLine($"Could not apply options in the option group {setting} in mod {mod.Name} for unknown reason {ec}.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary> Obtain the name of the collection currently assigned to the player. </summary>
|
/// <summary> Obtain the name of the collection currently assigned to the player. </summary>
|
||||||
public Guid GetCurrentPlayerCollection()
|
public Guid GetCurrentPlayerCollection()
|
||||||
{
|
{
|
||||||
|
|
@ -347,12 +426,24 @@ public class PenumbraService : IDisposable
|
||||||
_getMods = new global::Penumbra.Api.IpcSubscribers.GetModList(_pluginInterface);
|
_getMods = new global::Penumbra.Api.IpcSubscribers.GetModList(_pluginInterface);
|
||||||
_currentCollection = new global::Penumbra.Api.IpcSubscribers.GetCollection(_pluginInterface);
|
_currentCollection = new global::Penumbra.Api.IpcSubscribers.GetCollection(_pluginInterface);
|
||||||
_getCurrentSettings = new global::Penumbra.Api.IpcSubscribers.GetCurrentModSettings(_pluginInterface);
|
_getCurrentSettings = new global::Penumbra.Api.IpcSubscribers.GetCurrentModSettings(_pluginInterface);
|
||||||
|
_inheritMod = new global::Penumbra.Api.IpcSubscribers.TryInheritMod(_pluginInterface);
|
||||||
_setMod = new global::Penumbra.Api.IpcSubscribers.TrySetMod(_pluginInterface);
|
_setMod = new global::Penumbra.Api.IpcSubscribers.TrySetMod(_pluginInterface);
|
||||||
_setModPriority = new global::Penumbra.Api.IpcSubscribers.TrySetModPriority(_pluginInterface);
|
_setModPriority = new global::Penumbra.Api.IpcSubscribers.TrySetModPriority(_pluginInterface);
|
||||||
_setModSetting = new global::Penumbra.Api.IpcSubscribers.TrySetModSetting(_pluginInterface);
|
_setModSetting = new global::Penumbra.Api.IpcSubscribers.TrySetModSetting(_pluginInterface);
|
||||||
_setModSettings = new global::Penumbra.Api.IpcSubscribers.TrySetModSettings(_pluginInterface);
|
_setModSettings = new global::Penumbra.Api.IpcSubscribers.TrySetModSettings(_pluginInterface);
|
||||||
_openModPage = new global::Penumbra.Api.IpcSubscribers.OpenMainWindow(_pluginInterface);
|
_openModPage = new global::Penumbra.Api.IpcSubscribers.OpenMainWindow(_pluginInterface);
|
||||||
Available = true;
|
if (CurrentMinor >= RequiredPenumbraFeatureVersionTemp)
|
||||||
|
{
|
||||||
|
_setTemporaryModSettings = new global::Penumbra.Api.IpcSubscribers.SetTemporaryModSettings(_pluginInterface);
|
||||||
|
_setTemporaryModSettingsPlayer = new global::Penumbra.Api.IpcSubscribers.SetTemporaryModSettingsPlayer(_pluginInterface);
|
||||||
|
_removeTemporaryModSettings = new global::Penumbra.Api.IpcSubscribers.RemoveTemporaryModSettings(_pluginInterface);
|
||||||
|
_removeTemporaryModSettingsPlayer = new global::Penumbra.Api.IpcSubscribers.RemoveTemporaryModSettingsPlayer(_pluginInterface);
|
||||||
|
_removeAllTemporaryModSettings = new global::Penumbra.Api.IpcSubscribers.RemoveAllTemporaryModSettings(_pluginInterface);
|
||||||
|
_removeAllTemporaryModSettingsPlayer =
|
||||||
|
new global::Penumbra.Api.IpcSubscribers.RemoveAllTemporaryModSettingsPlayer(_pluginInterface);
|
||||||
|
}
|
||||||
|
|
||||||
|
Available = true;
|
||||||
_penumbraReloaded.Invoke();
|
_penumbraReloaded.Invoke();
|
||||||
Glamourer.Log.Debug("Glamourer attached to Penumbra.");
|
Glamourer.Log.Debug("Glamourer attached to Penumbra.");
|
||||||
}
|
}
|
||||||
|
|
@ -373,27 +464,35 @@ public class PenumbraService : IDisposable
|
||||||
_modSettingChanged.Disable();
|
_modSettingChanged.Disable();
|
||||||
if (Available)
|
if (Available)
|
||||||
{
|
{
|
||||||
_collectionByIdentifier = null;
|
_collectionByIdentifier = null;
|
||||||
_collections = null;
|
_collections = null;
|
||||||
_redraw = null;
|
_redraw = null;
|
||||||
_drawObjectInfo = null;
|
_drawObjectInfo = null;
|
||||||
_cutsceneParent = null;
|
_cutsceneParent = null;
|
||||||
_objectCollection = null;
|
_objectCollection = null;
|
||||||
_getMods = null;
|
_getMods = null;
|
||||||
_currentCollection = null;
|
_currentCollection = null;
|
||||||
_getCurrentSettings = null;
|
_getCurrentSettings = null;
|
||||||
_setMod = null;
|
_inheritMod = null;
|
||||||
_setModPriority = null;
|
_setMod = null;
|
||||||
_setModSetting = null;
|
_setModPriority = null;
|
||||||
_setModSettings = null;
|
_setModSetting = null;
|
||||||
_openModPage = null;
|
_setModSettings = null;
|
||||||
Available = false;
|
_openModPage = null;
|
||||||
|
_setTemporaryModSettings = null;
|
||||||
|
_setTemporaryModSettingsPlayer = null;
|
||||||
|
_removeTemporaryModSettings = null;
|
||||||
|
_removeTemporaryModSettingsPlayer = null;
|
||||||
|
_removeAllTemporaryModSettings = null;
|
||||||
|
_removeAllTemporaryModSettingsPlayer = null;
|
||||||
|
Available = false;
|
||||||
Glamourer.Log.Debug("Glamourer detached from Penumbra.");
|
Glamourer.Log.Debug("Glamourer detached from Penumbra.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
ClearAllTemporarySettings();
|
||||||
Unattach();
|
Unattach();
|
||||||
_tooltipSubscriber.Dispose();
|
_tooltipSubscriber.Dispose();
|
||||||
_clickSubscriber.Dispose();
|
_clickSubscriber.Dispose();
|
||||||
|
|
|
||||||
|
|
@ -691,7 +691,7 @@ public class CommandService : IDisposable, IApiService
|
||||||
if (!applyMods || design is not Design d)
|
if (!applyMods || design is not Design d)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var (messages, appliedMods, _, name, overridden) = _modApplier.ApplyModSettings(d.AssociatedMods, actor);
|
var (messages, appliedMods, _, name, overridden) = _modApplier.ApplyModSettings(d.AssociatedMods, actor, d.ResetTemporarySettings);
|
||||||
|
|
||||||
foreach (var message in messages)
|
foreach (var message in messages)
|
||||||
Glamourer.Messager.Chat.Print($"Error applying mod settings: {message}");
|
Glamourer.Messager.Chat.Print($"Error applying mod settings: {message}");
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 882b778e78bb0806dd7d38e8b3670ff138a84a31
|
Subproject commit de0f281fbf9d8d9d3aa8463a28025d54877cde8d
|
||||||
Loading…
Add table
Add a link
Reference in a new issue