diff --git a/Glamourer/Api/GlamourerIpc.Apply.cs b/Glamourer/Api/GlamourerIpc.Apply.cs
index fcff35b..94896f0 100644
--- a/Glamourer/Api/GlamourerIpc.Apply.cs
+++ b/Glamourer/Api/GlamourerIpc.Apply.cs
@@ -163,7 +163,7 @@ public partial class GlamourerIpc
if ((hasModelId || state.ModelData.ModelId == 0) && state.CanUnlock(lockCode))
{
_stateManager.ApplyDesign(state, design,
- new ApplySettings(Source: once ? StateSource.IpcManual : StateSource.IpcFixed, Key: lockCode, MergeLinks: true));
+ new ApplySettings(Source: once ? StateSource.IpcManual : StateSource.IpcFixed, Key: lockCode, MergeLinks: true, ResetMaterials: !once && lockCode != 0));
state.Lock(lockCode);
}
}
diff --git a/Glamourer/Automation/AutoDesignApplier.cs b/Glamourer/Automation/AutoDesignApplier.cs
index 380de33..b815376 100644
--- a/Glamourer/Automation/AutoDesignApplier.cs
+++ b/Glamourer/Automation/AutoDesignApplier.cs
@@ -254,7 +254,7 @@ public sealed class AutoDesignApplier : IDisposable
private unsafe void Reduce(Actor actor, ActorState state, AutoDesignSet set, bool respectManual, bool fromJobChange)
{
- if (set.BaseState == AutoDesignSet.Base.Game)
+ if (set.BaseState is AutoDesignSet.Base.Game)
_state.ResetStateFixed(state, respectManual);
else if (!respectManual)
state.Sources.RemoveFixedDesignSources();
@@ -265,7 +265,7 @@ public sealed class AutoDesignApplier : IDisposable
var mergedDesign = _designMerger.Merge(
set.Designs.Where(d => d.IsActive(actor)).SelectMany(d => d.Design?.AllLinks.Select(l => (l.Design, l.Flags & d.Type)) ?? [(d.Design, d.Type)]),
state.ModelData.Customize, state.BaseData, true, _config.AlwaysApplyAssociatedMods);
- _state.ApplyDesign(state, mergedDesign, new ApplySettings(0, StateSource.Fixed, respectManual, fromJobChange, false));
+ _state.ApplyDesign(state, mergedDesign, new ApplySettings(0, StateSource.Fixed, respectManual, fromJobChange, false, false, set.BaseState is AutoDesignSet.Base.Game));
}
/// Get world-specific first and all-world afterward.
diff --git a/Glamourer/Designs/IDesignEditor.cs b/Glamourer/Designs/IDesignEditor.cs
index d882310..a0aab84 100644
--- a/Glamourer/Designs/IDesignEditor.cs
+++ b/Glamourer/Designs/IDesignEditor.cs
@@ -12,7 +12,8 @@ public readonly record struct ApplySettings(
bool RespectManual = false,
bool FromJobChange = false,
bool UseSingleSource = false,
- bool MergeLinks = false)
+ bool MergeLinks = false,
+ bool ResetMaterials = false)
{
public static readonly ApplySettings Manual = new()
{
@@ -22,6 +23,7 @@ public readonly record struct ApplySettings(
RespectManual = false,
UseSingleSource = false,
MergeLinks = false,
+ ResetMaterials = false,
};
public static readonly ApplySettings ManualWithLinks = new()
@@ -32,6 +34,7 @@ public readonly record struct ApplySettings(
RespectManual = false,
UseSingleSource = false,
MergeLinks = true,
+ ResetMaterials = false,
};
public static readonly ApplySettings Game = new()
@@ -42,6 +45,7 @@ public readonly record struct ApplySettings(
RespectManual = false,
UseSingleSource = false,
MergeLinks = false,
+ ResetMaterials = true,
};
}
diff --git a/Glamourer/Interop/Material/DirectXService.cs b/Glamourer/Interop/Material/DirectXService.cs
index b204dd6..d3fa3db 100644
--- a/Glamourer/Interop/Material/DirectXService.cs
+++ b/Glamourer/Interop/Material/DirectXService.cs
@@ -15,7 +15,6 @@ namespace Glamourer.Interop.Material;
public unsafe class DirectXService(IFramework framework) : IService
{
private readonly object _lock = new();
-
private readonly ConcurrentDictionary _textures = [];
/// Generate a color table the way the game does inside the original texture, and release the original.
diff --git a/Glamourer/Interop/Material/LiveColorTablePreviewer.cs b/Glamourer/Interop/Material/LiveColorTablePreviewer.cs
index 6ec3496..5e1fa06 100644
--- a/Glamourer/Interop/Material/LiveColorTablePreviewer.cs
+++ b/Glamourer/Interop/Material/LiveColorTablePreviewer.cs
@@ -110,11 +110,11 @@ public sealed unsafe class LiveColorTablePreviewer : IService, IDisposable
private static Vector3 CalculateDiffuse()
{
- const int frameLength = 1;
- const int steps = 64;
- var frame = ImGui.GetFrameCount();
- var hueByte = frame % (steps * frameLength) / frameLength;
- var hue = (float)hueByte / steps;
+ const long frameLength = TimeSpan.TicksPerMillisecond * 5;
+ const long steps = 2000;
+ var frame = DateTimeOffset.UtcNow.UtcTicks;
+ var hueByte = frame % (steps * frameLength) / frameLength;
+ var hue = (float)hueByte / steps;
ImGui.ColorConvertHSVtoRGB(hue, 1, 1, out var r, out var g, out var b);
return new Vector3(r, g, b);
}
diff --git a/Glamourer/State/StateApplier.cs b/Glamourer/State/StateApplier.cs
index 52996ea..9c06ce5 100644
--- a/Glamourer/State/StateApplier.cs
+++ b/Glamourer/State/StateApplier.cs
@@ -301,11 +301,11 @@ public class StateApplier(
}
}
- public ActorData ChangeMaterialValues(ActorState state, bool apply)
+ public ActorData ChangeMaterialValue(ActorState state, MaterialValueIndex index, bool apply)
{
var data = GetData(state);
if (apply)
- ChangeMaterialValues(data, state.Materials, state.IsLocked);
+ ChangeMaterialValue(data, index, state.Materials.TryGetValue(index, out var v) ? v.Model : null, state.IsLocked);
return data;
}
@@ -326,7 +326,7 @@ public class StateApplier(
if (!mainKey.TryGetTexture(actor, out var texture))
continue;
- if (!_directX.TryGetColorTable(*texture, out var table))
+ if (!PrepareColorSet.TryGetColorTable(actor, mainKey, out var table))
continue;
foreach (var (key, value) in values)
@@ -337,14 +337,6 @@ public class StateApplier(
}
}
- public ActorData ChangeMaterialValue(ActorState state, MaterialValueIndex index, bool apply)
- {
- var data = GetData(state);
- if (apply)
- ChangeMaterialValue(data, index, state.Materials.TryGetValue(index, out var v) ? v.Model : null, state.IsLocked);
- return data;
- }
-
/// Apply the entire state of an actor to all relevant actors, either via immediate redraw or piecewise.
/// The state to apply.
/// Whether a redraw should be forced.
@@ -377,7 +369,6 @@ public class StateApplier(
ChangeMetaState(actors, MetaIndex.VisorState, state.ModelData.IsVisorToggled());
ChangeCrests(actors, state.ModelData.CrestVisibility);
ChangeParameters(actors, state.OnlyChangedParameters(), state.ModelData.Parameters, state.IsLocked);
- // This should never be applied when caused through IPC, then redraw should be true.
ChangeMaterialValues(actors, state.Materials, state.IsLocked);
}
}
diff --git a/Glamourer/State/StateEditor.cs b/Glamourer/State/StateEditor.cs
index 915aa2c..2ddacf6 100644
--- a/Glamourer/State/StateEditor.cs
+++ b/Glamourer/State/StateEditor.cs
@@ -296,6 +296,9 @@ public class StateEditor(
Editor.ChangeMetaState(state, meta, mergedDesign.Design.DesignData.GetMeta(meta), Source(meta), out _, settings.Key);
}
+ if (settings.ResetMaterials)
+ state.Materials.Clear();
+
foreach (var (key, value) in mergedDesign.Design.Materials)
{
if (!value.Enabled)
@@ -321,8 +324,6 @@ public class StateEditor(
settings.Source, out _, settings.Key);
}
}
-
- requiresRedraw |= mergedDesign.Design.Materials.Count > 0 && settings.Source.IsIpc();
}
var actors = settings.Source.RequiresChange()
diff --git a/Glamourer/State/StateManager.cs b/Glamourer/State/StateManager.cs
index e4772aa..46cd856 100644
--- a/Glamourer/State/StateManager.cs
+++ b/Glamourer/State/StateManager.cs
@@ -224,7 +224,6 @@ public sealed class StateManager(
|| !state.ModelData.IsHuman
|| CustomizeArray.Compare(state.ModelData.Customize, state.BaseData.Customize).RequiresRedraw();
- redraw |= state.Materials.Values.Count > 0 && source.IsIpc();
state.ModelData = state.BaseData;
state.ModelData.SetIsWet(false);
foreach (var index in Enum.GetValues())
@@ -346,7 +345,7 @@ public sealed class StateManager(
public void ReapplyState(Actor actor, ActorState state, StateSource source)
{
var data = Applier.ApplyAll(state,
- !actor.Model.IsHuman || CustomizeArray.Compare(actor.Model.GetCustomize(), state.ModelData.Customize).RequiresRedraw() || state.Materials.Values.Count > 0 && source.IsIpc(), false);
+ !actor.Model.IsHuman || CustomizeArray.Compare(actor.Model.GetCustomize(), state.ModelData.Customize).RequiresRedraw(), false);
StateChanged.Invoke(StateChanged.Type.Reapply, source, state, data, null);
}