mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2026-02-21 06:57:44 +01:00
Add state editing and tracking.
This commit is contained in:
parent
5cdcb9288e
commit
fb7aac5228
10 changed files with 383 additions and 235 deletions
|
|
@ -2,6 +2,7 @@
|
|||
using Glamourer.Designs;
|
||||
using Glamourer.Events;
|
||||
using Glamourer.GameData;
|
||||
using Glamourer.Interop.Material;
|
||||
using Glamourer.Services;
|
||||
using Penumbra.GameData.DataContainers;
|
||||
using Penumbra.GameData.Enums;
|
||||
|
|
@ -220,6 +221,39 @@ public class InternalStateEditor(
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary> Change the value of a single material color table entry. </summary>
|
||||
public bool ChangeMaterialValue(ActorState state, MaterialValueIndex index, Vector3 value, Vector3 gameValue, StateSource source, out Vector3 oldValue,
|
||||
uint key = 0)
|
||||
{
|
||||
// We already have an existing value.
|
||||
if (state.Materials.TryGetValue(index, out var old))
|
||||
{
|
||||
oldValue = old.Model;
|
||||
if (!state.CanUnlock(key))
|
||||
return false;
|
||||
|
||||
// Remove if overwritten by a game value.
|
||||
if (source is StateSource.Game)
|
||||
{
|
||||
state.Materials.RemoveValue(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Update if edited.
|
||||
state.Materials.UpdateValue(index, new MaterialValueState(gameValue, value, source), out _);
|
||||
return true;
|
||||
}
|
||||
|
||||
// We do not have an existing value.
|
||||
oldValue = gameValue;
|
||||
// Do not do anything if locked or if the game value updates, because then we do not need to add an entry.
|
||||
if (!state.CanUnlock(key) || source is StateSource.Game)
|
||||
return false;
|
||||
|
||||
// Only add an entry if it is sufficiently different from the game value.
|
||||
return !value.NearEqual(gameValue) && state.Materials.TryAddValue(index, new MaterialValueState(gameValue, value, source));
|
||||
}
|
||||
|
||||
public bool ChangeMetaState(ActorState state, MetaIndex index, bool value, StateSource source, out bool oldValue,
|
||||
uint key = 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using Glamourer.Designs;
|
||||
using Glamourer.GameData;
|
||||
using Glamourer.Interop;
|
||||
using Glamourer.Interop.Material;
|
||||
using Glamourer.Interop.Penumbra;
|
||||
using Glamourer.Interop.Structs;
|
||||
using Glamourer.Services;
|
||||
|
|
@ -275,6 +276,41 @@ public class StateApplier(
|
|||
return data;
|
||||
}
|
||||
|
||||
public unsafe void ChangeMaterialValue(ActorData data, MaterialValueIndex index, Vector3? value, bool force)
|
||||
{
|
||||
if (!force && !_config.UseAdvancedParameters)
|
||||
return;
|
||||
|
||||
foreach (var actor in data.Objects.Where(a => a is { IsCharacter: true, Model.IsHuman: true }))
|
||||
{
|
||||
if (!index.TryGetTexture(actor, out var texture))
|
||||
continue;
|
||||
|
||||
if (!index.TryGetColorTable(texture, out var table))
|
||||
continue;
|
||||
|
||||
Vector3 actualValue;
|
||||
if (value.HasValue)
|
||||
actualValue = value.Value;
|
||||
else if (!PrepareColorSet.TryGetColorTable(actor, index, out var baseTable)
|
||||
|| !index.DataIndex.TryGetValue(baseTable[index.RowIndex], out actualValue))
|
||||
continue;
|
||||
|
||||
if (!index.DataIndex.SetValue(ref table[index.RowIndex], actualValue))
|
||||
continue;
|
||||
|
||||
MaterialService.ReplaceColorTable(texture, table);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary> Apply the entire state of an actor to all relevant actors, either via immediate redraw or piecewise. </summary>
|
||||
/// <param name="state"> The state to apply. </param>
|
||||
/// <param name="redraw"> Whether a redraw should be forced. </param>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using Glamourer.Designs;
|
|||
using Glamourer.Designs.Links;
|
||||
using Glamourer.Events;
|
||||
using Glamourer.GameData;
|
||||
using Glamourer.Interop.Material;
|
||||
using Glamourer.Interop.Penumbra;
|
||||
using Glamourer.Interop.Structs;
|
||||
using Glamourer.Services;
|
||||
|
|
@ -149,9 +150,7 @@ public class StateEditor(
|
|||
/// <inheritdoc/>
|
||||
public void ChangeCustomizeParameter(object data, CustomizeParameterFlag flag, CustomizeParameterValue value, ApplySettings settings)
|
||||
{
|
||||
if (data is not ActorState state)
|
||||
return;
|
||||
|
||||
var state = (ActorState)data;
|
||||
// Also apply main color to highlights when highlights is off.
|
||||
if (!state.ModelData.Customize.Highlights && flag is CustomizeParameterFlag.HairDiffuse)
|
||||
ChangeCustomizeParameter(state, CustomizeParameterFlag.HairHighlight, value, settings);
|
||||
|
|
@ -166,6 +165,17 @@ public class StateEditor(
|
|||
StateChanged.Invoke(StateChanged.Type.Parameter, settings.Source, state, actors, (old, @new, flag));
|
||||
}
|
||||
|
||||
public void ChangeMaterialValue(object data, MaterialValueIndex index, Vector3 value, Vector3 gameValue, ApplySettings settings)
|
||||
{
|
||||
var state = (ActorState)data;
|
||||
if (!Editor.ChangeMaterialValue(state, index, value, gameValue, settings.Source, out var oldValue, settings.Key))
|
||||
return;
|
||||
|
||||
var actors = Applier.ChangeMaterialValue(state, index, settings.Source.RequiresChange());
|
||||
Glamourer.Log.Verbose($"Set material value in state {state.Identifier.Incognito(null)} from {oldValue} to {value}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
StateChanged.Invoke(StateChanged.Type.MaterialValue, settings.Source, state, actors, (oldValue, value, index));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void ChangeMetaState(object data, MetaIndex index, bool value, ApplySettings settings)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue