Change fixed state handling for advanced dyes.

This commit is contained in:
Ottermandias 2024-03-02 16:11:31 +01:00
parent bade38f82e
commit 93ba44d230
3 changed files with 41 additions and 7 deletions

View file

@ -4,6 +4,7 @@ using Glamourer.Designs;
using Glamourer.Designs.Links;
using Glamourer.Events;
using Glamourer.Interop;
using Glamourer.Interop.Material;
using Glamourer.Interop.Structs;
using Glamourer.State;
using Penumbra.GameData.Actors;
@ -256,9 +257,16 @@ public sealed class AutoDesignApplier : IDisposable
private unsafe void Reduce(Actor actor, ActorState state, AutoDesignSet set, bool respectManual, bool fromJobChange)
{
if (set.BaseState is AutoDesignSet.Base.Game)
{
_state.ResetStateFixed(state, respectManual);
}
else if (!respectManual)
{
state.Sources.RemoveFixedDesignSources();
foreach(var (key, value) in state.Materials.Values)
if (value.Source is StateSource.Fixed)
state.Materials.UpdateValue(key, new MaterialValueState(value.Game, value.Model, value.DrawData, StateSource.Manual), out _);
}
if (!_humans.IsHuman((uint)actor.AsCharacter->CharacterData.ModelCharaId))
return;
@ -266,7 +274,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))),
state.ModelData.Customize, state.BaseData, true, _config.AlwaysApplyAssociatedMods);
_state.ApplyDesign(state, mergedDesign, new ApplySettings(0, StateSource.Fixed, respectManual, fromJobChange, false, false, set.BaseState is AutoDesignSet.Base.Game));
_state.ApplyDesign(state, mergedDesign, new ApplySettings(0, StateSource.Fixed, respectManual, fromJobChange, false, false, false));
}
/// <summary> Get world-specific first and all-world afterward. </summary>

View file

@ -228,6 +228,9 @@ public readonly struct MaterialValueManager<T>
}
public bool TryGetValue(MaterialValueIndex index, out T value)
=> TryGetValue(index.Key, out value);
public bool TryGetValue(uint key, out T value)
{
if (_values.Count == 0)
{
@ -235,7 +238,7 @@ public readonly struct MaterialValueManager<T>
return false;
}
var idx = Search(index.Key);
var idx = Search(key);
if (idx >= 0)
{
value = _values[idx].Value;
@ -247,8 +250,10 @@ public readonly struct MaterialValueManager<T>
}
public bool TryAddValue(MaterialValueIndex index, in T value)
=> TryAddValue(index.Key, value);
public bool TryAddValue(uint key, in T value)
{
var key = index.Key;
var idx = Search(key);
if (idx >= 0)
return false;
@ -258,11 +263,14 @@ public readonly struct MaterialValueManager<T>
}
public bool RemoveValue(MaterialValueIndex index)
=> RemoveValue(index.Key);
public bool RemoveValue(uint key)
{
if (_values.Count == 0)
return false;
var idx = Search(index.Key);
var idx = Search(key);
if (idx < 0)
return false;
@ -271,8 +279,10 @@ public readonly struct MaterialValueManager<T>
}
public void AddOrUpdateValue(MaterialValueIndex index, in T value)
=> AddOrUpdateValue(index.Key, value);
public void AddOrUpdateValue(uint key, in T value)
{
var key = index.Key;
var idx = Search(key);
if (idx < 0)
_values.Insert(~idx, (key, value));
@ -281,6 +291,9 @@ public readonly struct MaterialValueManager<T>
}
public bool UpdateValue(MaterialValueIndex index, in T value, out T oldValue)
=> UpdateValue(index.Key, value, out oldValue);
public bool UpdateValue(uint key, in T value, out T oldValue)
{
if (_values.Count == 0)
{
@ -288,7 +301,6 @@ public readonly struct MaterialValueManager<T>
return false;
}
var key = index.Key;
var idx = Search(key);
if (idx < 0)
{

View file

@ -322,8 +322,10 @@ public sealed class StateManager(
{
actors = Applier.ChangeArmor(state, EquipSlotExtensions.EqdpSlots[0], true);
foreach (var slot in EquipSlotExtensions.EqdpSlots.Skip(1))
{
Applier.ChangeArmor(actors, slot, state.ModelData.Armor(slot), !state.Sources[slot, false].IsIpc(),
state.ModelData.IsHatVisible());
}
var mainhandActors = state.ModelData.MainhandType != state.BaseData.MainhandType ? actors.OnlyGPose() : actors;
Applier.ChangeMainhand(mainhandActors, state.ModelData.Item(EquipSlot.MainHand), state.ModelData.Stain(EquipSlot.MainHand));
@ -331,7 +333,8 @@ public sealed class StateManager(
Applier.ChangeOffhand(offhandActors, state.ModelData.Item(EquipSlot.OffHand), state.ModelData.Stain(EquipSlot.OffHand));
}
Glamourer.Log.Verbose($"Reset equipment state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]");
Glamourer.Log.Verbose(
$"Reset equipment state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]");
}
public void ResetStateFixed(ActorState state, bool respectManualPalettes, uint key = 0)
@ -386,6 +389,17 @@ public sealed class StateManager(
state.Sources[meta] = StateSource.Game;
state.ModelData.SetMeta(meta, state.BaseData.GetMeta(meta));
}
foreach (var (index, value) in state.Materials.Values.ToList())
{
switch (value.Source)
{
case StateSource.Fixed:
case StateSource.Manual when !respectManualPalettes:
state.Materials.RemoveValue(index);
break;
}
}
}
public void ReapplyState(Actor actor, StateSource source)