mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-12 10:17:23 +01:00
Reworked all of the meta, made StateIndex its own thing.
This commit is contained in:
parent
70e4833fb5
commit
1ad70541d3
36 changed files with 747 additions and 657 deletions
|
|
@ -3,6 +3,7 @@ using Dalamud.Plugin;
|
|||
using Glamourer.Designs;
|
||||
using Glamourer.Events;
|
||||
using Glamourer.Interop.Structs;
|
||||
using Glamourer.State;
|
||||
using Penumbra.Api.Helpers;
|
||||
using Penumbra.GameData.Actors;
|
||||
|
||||
|
|
@ -130,7 +131,7 @@ public partial class GlamourerIpc
|
|||
|
||||
if ((hasModelId || state.ModelData.ModelId == 0) && state.CanUnlock(lockCode))
|
||||
{
|
||||
_stateManager.ApplyDesign(design, state, StateChanged.Source.Ipc, lockCode);
|
||||
_stateManager.ApplyDesign(design, state, StateSource.Ipc, lockCode);
|
||||
state.Lock(lockCode);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ public partial class GlamourerIpc
|
|||
private readonly EventProvider<StateChanged.Type, nint, Lazy<string>> _stateChangedProvider;
|
||||
private readonly EventProvider<bool> _gPoseChangedProvider;
|
||||
|
||||
private void OnStateChanged(StateChanged.Type type, StateChanged.Source source, ActorState state, ActorData actors, object? data = null)
|
||||
private void OnStateChanged(StateChanged.Type type, StateSource source, ActorState state, ActorData actors, object? data = null)
|
||||
{
|
||||
foreach (var actor in actors.Objects)
|
||||
_stateChangedProvider.Invoke(type, actor.Address, new Lazy<string>(() => _designConverter.ShareBase64(state)));
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Dalamud.Plugin;
|
||||
using Glamourer.Events;
|
||||
using Glamourer.State;
|
||||
using Penumbra.Api.Helpers;
|
||||
using Penumbra.GameData.Actors;
|
||||
|
||||
|
|
@ -82,7 +83,7 @@ public partial class GlamourerIpc
|
|||
foreach (var id in actors)
|
||||
{
|
||||
if (_stateManager.TryGetValue(id, out var state))
|
||||
_stateManager.ResetState(state, StateChanged.Source.Ipc, lockCode);
|
||||
_stateManager.ResetState(state, StateSource.Ipc, lockCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
using Dalamud.Plugin;
|
||||
using Glamourer.Events;
|
||||
using Glamourer.Services;
|
||||
using Glamourer.State;
|
||||
using Penumbra.Api.Helpers;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
|
|
@ -55,7 +56,7 @@ public partial class GlamourerIpc
|
|||
if (!state.ModelData.IsHuman)
|
||||
return GlamourerErrorCode.ActorNotHuman;
|
||||
|
||||
_stateManager.ChangeEquip(state, slot, item, stainId, StateChanged.Source.Ipc, key);
|
||||
_stateManager.ChangeEquip(state, slot, item, stainId, StateSource.Ipc, key);
|
||||
return GlamourerErrorCode.Success;
|
||||
}
|
||||
|
||||
|
|
@ -82,7 +83,7 @@ public partial class GlamourerIpc
|
|||
if (!state.ModelData.IsHuman)
|
||||
return GlamourerErrorCode.ActorNotHuman;
|
||||
|
||||
_stateManager.ChangeEquip(state, slot, item, stainId, StateChanged.Source.Ipc, key);
|
||||
_stateManager.ChangeEquip(state, slot, item, stainId, StateSource.Ipc, key);
|
||||
found = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,9 +18,8 @@ public enum ApplicationType : byte
|
|||
|
||||
public static class ApplicationTypeExtensions
|
||||
{
|
||||
public static (EquipFlag Equip, CustomizeFlag Customize, CrestFlag Crest, CustomizeParameterFlag Parameters, bool ApplyHat, bool ApplyVisor,
|
||||
bool
|
||||
ApplyWeapon, bool ApplyWet) ApplyWhat(this ApplicationType type, DesignBase? design)
|
||||
public static (EquipFlag Equip, CustomizeFlag Customize, CrestFlag Crest, CustomizeParameterFlag Parameters, MetaFlag Meta) ApplyWhat(
|
||||
this ApplicationType type, DesignBase? design)
|
||||
{
|
||||
var equipFlags = (type.HasFlag(ApplicationType.Weapons) ? WeaponFlags : 0)
|
||||
| (type.HasFlag(ApplicationType.Armor) ? ArmorFlags : 0)
|
||||
|
|
@ -29,18 +28,15 @@ public static class ApplicationTypeExtensions
|
|||
var customizeFlags = type.HasFlag(ApplicationType.Customizations) ? CustomizeFlagExtensions.All : 0;
|
||||
var parameterFlags = type.HasFlag(ApplicationType.Customizations) ? CustomizeParameterExtensions.All : 0;
|
||||
var crestFlag = type.HasFlag(ApplicationType.GearCustomization) ? CrestExtensions.AllRelevant : 0;
|
||||
var metaFlag = (type.HasFlag(ApplicationType.Armor) ? MetaFlag.HatState | MetaFlag.VisorState : 0)
|
||||
| (type.HasFlag(ApplicationType.Weapons) ? MetaFlag.WeaponState : 0)
|
||||
| (type.HasFlag(ApplicationType.Customizations) ? MetaFlag.Wetness : 0);
|
||||
|
||||
if (design == null)
|
||||
return (equipFlags, customizeFlags, crestFlag, parameterFlags, type.HasFlag(ApplicationType.Armor),
|
||||
type.HasFlag(ApplicationType.Armor),
|
||||
type.HasFlag(ApplicationType.Weapons), type.HasFlag(ApplicationType.Customizations));
|
||||
return (equipFlags, customizeFlags, crestFlag, parameterFlags, metaFlag);
|
||||
|
||||
return (equipFlags & design!.ApplyEquip, customizeFlags & design.ApplyCustomize, crestFlag & design.ApplyCrest,
|
||||
parameterFlags & design.ApplyParameters,
|
||||
type.HasFlag(ApplicationType.Armor) && design.DoApplyHatVisible(),
|
||||
type.HasFlag(ApplicationType.Armor) && design.DoApplyVisorToggle(),
|
||||
type.HasFlag(ApplicationType.Weapons) && design.DoApplyWeaponVisible(),
|
||||
type.HasFlag(ApplicationType.Customizations) && design.DoApplyWetness());
|
||||
parameterFlags & design.ApplyParameters, metaFlag & design.ApplyMeta);
|
||||
}
|
||||
|
||||
public const EquipFlag WeaponFlags = EquipFlag.Mainhand | EquipFlag.Offhand;
|
||||
|
|
|
|||
|
|
@ -68,7 +68,6 @@ public class AutoDesign
|
|||
return ret;
|
||||
}
|
||||
|
||||
public (EquipFlag Equip, CustomizeFlag Customize, CrestFlag Crest, CustomizeParameterFlag Parameters, bool ApplyHat, bool ApplyVisor, bool
|
||||
ApplyWeapon, bool ApplyWet) ApplyWhat()
|
||||
public (EquipFlag Equip, CustomizeFlag Customize, CrestFlag Crest, CustomizeParameterFlag Parameters, MetaFlag Meta) ApplyWhat()
|
||||
=> Type.ApplyWhat(Design);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ public sealed class AutoDesignApplier : IDisposable
|
|||
private readonly IClientState _clientState;
|
||||
|
||||
private ActorState? _jobChangeState;
|
||||
private readonly Dictionary<FullEquipType, (EquipItem, StateChanged.Source)> _jobChange = [];
|
||||
private readonly Dictionary<FullEquipType, (EquipItem, StateSource)> _jobChange = [];
|
||||
|
||||
private void ResetJobChange()
|
||||
{
|
||||
|
|
@ -183,7 +183,7 @@ public sealed class AutoDesignApplier : IDisposable
|
|||
}
|
||||
else if (_state.TryGetValue(id, out var state))
|
||||
{
|
||||
state.Source.RemoveFixedDesignSources();
|
||||
state.Sources.RemoveFixedDesignSources();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -197,9 +197,9 @@ public sealed class AutoDesignApplier : IDisposable
|
|||
{
|
||||
if (id.Type is IdentifierType.Player && id.HomeWorld == WorldId.AnyWorld)
|
||||
foreach (var state in _state.Where(kvp => kvp.Key.PlayerName == id.PlayerName).Select(kvp => kvp.Value))
|
||||
state.Source.RemoveFixedDesignSources();
|
||||
state.Sources.RemoveFixedDesignSources();
|
||||
else if (_state.TryGetValue(id, out var state))
|
||||
state.Source.RemoveFixedDesignSources();
|
||||
state.Sources.RemoveFixedDesignSources();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -256,13 +256,13 @@ public sealed class AutoDesignApplier : IDisposable
|
|||
else if (!GetPlayerSet(identifier, out set!))
|
||||
{
|
||||
if (state.UpdateTerritory(_clientState.TerritoryType) && _config.RevertManualChangesOnZoneChange)
|
||||
_state.ResetState(state, StateChanged.Source.Game);
|
||||
_state.ResetState(state, StateSource.Game);
|
||||
return true;
|
||||
}
|
||||
|
||||
var respectManual = !state.UpdateTerritory(_clientState.TerritoryType) || !_config.RevertManualChangesOnZoneChange;
|
||||
if (!respectManual)
|
||||
_state.ResetState(state, StateChanged.Source.Game);
|
||||
_state.ResetState(state, StateSource.Game);
|
||||
Reduce(actor, state, set, respectManual, false);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -272,13 +272,13 @@ public sealed class AutoDesignApplier : IDisposable
|
|||
if (set.BaseState == AutoDesignSet.Base.Game)
|
||||
_state.ResetStateFixed(state, respectManual);
|
||||
else if (!respectManual)
|
||||
state.Source.RemoveFixedDesignSources();
|
||||
state.Sources.RemoveFixedDesignSources();
|
||||
|
||||
if (!_humans.IsHuman((uint)actor.AsCharacter->CharacterData.ModelCharaId))
|
||||
return;
|
||||
|
||||
var mergedDesign = _designMerger.Merge(set.Designs.Where(d => d.IsActive(actor)).Select(d => ((DesignBase?) d.Design, d.Type)), state.ModelData, true);
|
||||
ApplyToState(state, mergedDesign, respectManual, fromJobChange, StateChanged.Source.Fixed);
|
||||
var mergedDesign = _designMerger.Merge(set.Designs.Where(d => d.IsActive(actor)).Select(d => ((DesignBase?) d.Design, d.Type)), state.ModelData, true, false);
|
||||
ApplyToState(state, mergedDesign, respectManual, fromJobChange, StateSource.Fixed);
|
||||
}
|
||||
|
||||
/// <summary> Get world-specific first and all-world afterward. </summary>
|
||||
|
|
@ -304,27 +304,27 @@ public sealed class AutoDesignApplier : IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
private void ApplyToState(ActorState state, MergedDesign mergedDesign, bool respectManual, bool fromJobChange, StateChanged.Source source)
|
||||
private void ApplyToState(ActorState state, MergedDesign mergedDesign, bool respectManual, bool fromJobChange, StateSource source)
|
||||
{
|
||||
foreach (var slot in CrestExtensions.AllRelevantSet.Where(mergedDesign.Design.DoApplyCrest))
|
||||
if (!respectManual || state.Source[slot] is not StateChanged.Source.Manual)
|
||||
if (!respectManual || state.Sources[slot] is not StateSource.Manual)
|
||||
_state.ChangeCrest(state, slot, mergedDesign.Design.DesignData.Crest(slot), mergedDesign.GetSource(slot, source));
|
||||
|
||||
foreach (var parameter in mergedDesign.Design.ApplyParameters.Iterate())
|
||||
if (!respectManual || state.Source[parameter] is not StateChanged.Source.Manual and not StateChanged.Source.Pending)
|
||||
if (!respectManual || state.Sources[parameter] is not StateSource.Manual and not StateSource.Pending)
|
||||
_state.ChangeCustomizeParameter(state, parameter, mergedDesign.Design.DesignData.Parameters[parameter], mergedDesign.GetSource(parameter, source));
|
||||
|
||||
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
||||
{
|
||||
if (mergedDesign.Design.DoApplyEquip(slot))
|
||||
{
|
||||
if (!respectManual || state.Source[slot, false] is not StateChanged.Source.Manual)
|
||||
if (!respectManual || state.Sources[slot, false] is not StateSource.Manual)
|
||||
_state.ChangeItem(state, slot, mergedDesign.Design.DesignData.Item(slot), mergedDesign.GetSource(slot, false, source));
|
||||
}
|
||||
|
||||
if (mergedDesign.Design.DoApplyStain(slot))
|
||||
{
|
||||
if (!respectManual || state.Source[slot, true] is not StateChanged.Source.Manual)
|
||||
if (!respectManual || state.Sources[slot, true] is not StateSource.Manual)
|
||||
_state.ChangeStain(state, slot, mergedDesign.Design.DesignData.Stain(slot), mergedDesign.GetSource(slot, true, source));
|
||||
}
|
||||
}
|
||||
|
|
@ -333,14 +333,14 @@ public sealed class AutoDesignApplier : IDisposable
|
|||
{
|
||||
if (mergedDesign.Design.DoApplyStain(weaponSlot))
|
||||
{
|
||||
if (!respectManual || state.Source[weaponSlot, true] is not StateChanged.Source.Manual)
|
||||
if (!respectManual || state.Sources[weaponSlot, true] is not StateSource.Manual)
|
||||
_state.ChangeStain(state, weaponSlot, mergedDesign.Design.DesignData.Stain(weaponSlot), mergedDesign.GetSource(weaponSlot, true, source));
|
||||
}
|
||||
|
||||
if (!mergedDesign.Design.DoApplyEquip(weaponSlot))
|
||||
continue;
|
||||
|
||||
if (respectManual && state.Source[weaponSlot, false] is StateChanged.Source.Manual)
|
||||
if (respectManual && state.Sources[weaponSlot, false] is StateSource.Manual)
|
||||
continue;
|
||||
|
||||
var currentType = state.ModelData.Item(weaponSlot).Type;
|
||||
|
|
@ -359,7 +359,7 @@ public sealed class AutoDesignApplier : IDisposable
|
|||
}
|
||||
|
||||
private void ReduceEquip(ActorState state, in DesignData design, EquipFlag equipFlags, ref EquipFlag totalEquipFlags, bool respectManual,
|
||||
StateChanged.Source source, bool fromJobChange)
|
||||
StateSource source, bool fromJobChange)
|
||||
{
|
||||
equipFlags &= ~totalEquipFlags;
|
||||
if (equipFlags == 0)
|
||||
|
|
@ -373,7 +373,7 @@ public sealed class AutoDesignApplier : IDisposable
|
|||
var item = design.Item(slot);
|
||||
if (!_config.UnlockedItemMode || _itemUnlocks.IsUnlocked(item.Id, out _))
|
||||
{
|
||||
if (!respectManual || state.Source[slot, false] is not StateChanged.Source.Manual)
|
||||
if (!respectManual || state.Sources[slot, false] is not StateSource.Manual)
|
||||
_state.ChangeItem(state, slot, item, source);
|
||||
totalEquipFlags |= flag;
|
||||
}
|
||||
|
|
@ -382,7 +382,7 @@ public sealed class AutoDesignApplier : IDisposable
|
|||
var stainFlag = slot.ToStainFlag();
|
||||
if (equipFlags.HasFlag(stainFlag))
|
||||
{
|
||||
if (!respectManual || state.Source[slot, true] is not StateChanged.Source.Manual)
|
||||
if (!respectManual || state.Sources[slot, true] is not StateSource.Manual)
|
||||
_state.ChangeStain(state, slot, design.Stain(slot), source);
|
||||
totalEquipFlags |= stainFlag;
|
||||
}
|
||||
|
|
@ -392,7 +392,7 @@ public sealed class AutoDesignApplier : IDisposable
|
|||
{
|
||||
var item = design.Item(EquipSlot.MainHand);
|
||||
var checkUnlock = !_config.UnlockedItemMode || _itemUnlocks.IsUnlocked(item.Id, out _);
|
||||
var checkState = !respectManual || state.Source[EquipSlot.MainHand, false] is not StateChanged.Source.Manual;
|
||||
var checkState = !respectManual || state.Sources[EquipSlot.MainHand, false] is not StateSource.Manual;
|
||||
if (checkUnlock && checkState)
|
||||
{
|
||||
if (fromJobChange)
|
||||
|
|
@ -412,7 +412,7 @@ public sealed class AutoDesignApplier : IDisposable
|
|||
{
|
||||
var item = design.Item(EquipSlot.OffHand);
|
||||
var checkUnlock = !_config.UnlockedItemMode || _itemUnlocks.IsUnlocked(item.Id, out _);
|
||||
var checkState = !respectManual || state.Source[EquipSlot.OffHand, false] is not StateChanged.Source.Manual;
|
||||
var checkState = !respectManual || state.Sources[EquipSlot.OffHand, false] is not StateSource.Manual;
|
||||
if (checkUnlock && checkState)
|
||||
{
|
||||
if (fromJobChange)
|
||||
|
|
@ -430,21 +430,21 @@ public sealed class AutoDesignApplier : IDisposable
|
|||
|
||||
if (equipFlags.HasFlag(EquipFlag.MainhandStain))
|
||||
{
|
||||
if (!respectManual || state.Source[EquipSlot.MainHand, true] is not StateChanged.Source.Manual)
|
||||
if (!respectManual || state.Sources[EquipSlot.MainHand, true] is not StateSource.Manual)
|
||||
_state.ChangeStain(state, EquipSlot.MainHand, design.Stain(EquipSlot.MainHand), source);
|
||||
totalEquipFlags |= EquipFlag.MainhandStain;
|
||||
}
|
||||
|
||||
if (equipFlags.HasFlag(EquipFlag.OffhandStain))
|
||||
{
|
||||
if (!respectManual || state.Source[EquipSlot.OffHand, true] is not StateChanged.Source.Manual)
|
||||
if (!respectManual || state.Sources[EquipSlot.OffHand, true] is not StateSource.Manual)
|
||||
_state.ChangeStain(state, EquipSlot.OffHand, design.Stain(EquipSlot.OffHand), source);
|
||||
totalEquipFlags |= EquipFlag.OffhandStain;
|
||||
}
|
||||
}
|
||||
|
||||
private void ReduceCustomize(ActorState state, in DesignData design, CustomizeFlag customizeFlags, ref CustomizeFlag totalCustomizeFlags,
|
||||
bool respectManual, StateChanged.Source source)
|
||||
bool respectManual, StateSource source)
|
||||
{
|
||||
customizeFlags &= ~totalCustomizeFlags;
|
||||
if (customizeFlags == 0)
|
||||
|
|
@ -459,7 +459,7 @@ public sealed class AutoDesignApplier : IDisposable
|
|||
|
||||
if (customizeFlags.HasFlag(CustomizeFlag.Clan))
|
||||
{
|
||||
if (!respectManual || state.Source[CustomizeIndex.Clan] is not StateChanged.Source.Manual)
|
||||
if (!respectManual || state.Sources[CustomizeIndex.Clan] is not StateSource.Manual)
|
||||
fixFlags |= _customizations.ChangeClan(ref customize, design.Customize.Clan);
|
||||
customizeFlags &= ~(CustomizeFlag.Clan | CustomizeFlag.Race);
|
||||
totalCustomizeFlags |= CustomizeFlag.Clan | CustomizeFlag.Race;
|
||||
|
|
@ -467,7 +467,7 @@ public sealed class AutoDesignApplier : IDisposable
|
|||
|
||||
if (customizeFlags.HasFlag(CustomizeFlag.Gender))
|
||||
{
|
||||
if (!respectManual || state.Source[CustomizeIndex.Gender] is not StateChanged.Source.Manual)
|
||||
if (!respectManual || state.Sources[CustomizeIndex.Gender] is not StateSource.Manual)
|
||||
fixFlags |= _customizations.ChangeGender(ref customize, design.Customize.Gender);
|
||||
customizeFlags &= ~CustomizeFlag.Gender;
|
||||
totalCustomizeFlags |= CustomizeFlag.Gender;
|
||||
|
|
@ -478,7 +478,7 @@ public sealed class AutoDesignApplier : IDisposable
|
|||
|
||||
if (customizeFlags.HasFlag(CustomizeFlag.Face))
|
||||
{
|
||||
if (!respectManual || state.Source[CustomizeIndex.Face] is not StateChanged.Source.Manual)
|
||||
if (!respectManual || state.Sources[CustomizeIndex.Face] is not StateSource.Manual)
|
||||
_state.ChangeCustomize(state, CustomizeIndex.Face, design.Customize.Face, source);
|
||||
customizeFlags &= ~CustomizeFlag.Face;
|
||||
totalCustomizeFlags |= CustomizeFlag.Face;
|
||||
|
|
@ -498,42 +498,21 @@ public sealed class AutoDesignApplier : IDisposable
|
|||
if (data.HasValue && _config.UnlockedItemMode && !_customizeUnlocks.IsUnlocked(data.Value, out _))
|
||||
continue;
|
||||
|
||||
if (!respectManual || state.Source[index] is not StateChanged.Source.Manual)
|
||||
if (!respectManual || state.Sources[index] is not StateSource.Manual)
|
||||
_state.ChangeCustomize(state, index, value, source);
|
||||
totalCustomizeFlags |= flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ReduceMeta(ActorState state, in DesignData design, bool applyHat, bool applyVisor, bool applyWeapon, bool applyWet,
|
||||
ref byte totalMetaFlags, bool respectManual, StateChanged.Source source)
|
||||
private void ReduceMeta(ActorState state, in DesignData design, MetaFlag apply, ref MetaFlag totalMetaFlags, bool respectManual, StateSource source)
|
||||
{
|
||||
if (applyHat && (totalMetaFlags & 0x01) == 0)
|
||||
apply &= ~totalMetaFlags;
|
||||
foreach (var index in MetaExtensions.AllRelevant)
|
||||
{
|
||||
if (!respectManual || state.Source[MetaIndex.HatState] is not StateChanged.Source.Manual)
|
||||
_state.ChangeHatState(state, design.IsHatVisible(), source);
|
||||
totalMetaFlags |= 0x01;
|
||||
}
|
||||
|
||||
if (applyVisor && (totalMetaFlags & 0x02) == 0)
|
||||
{
|
||||
if (!respectManual || state.Source[MetaIndex.VisorState] is not StateChanged.Source.Manual)
|
||||
_state.ChangeVisorState(state, design.IsVisorToggled(), source);
|
||||
totalMetaFlags |= 0x02;
|
||||
}
|
||||
|
||||
if (applyWeapon && (totalMetaFlags & 0x04) == 0)
|
||||
{
|
||||
if (!respectManual || state.Source[MetaIndex.WeaponState] is not StateChanged.Source.Manual)
|
||||
_state.ChangeWeaponState(state, design.IsWeaponVisible(), source);
|
||||
totalMetaFlags |= 0x04;
|
||||
}
|
||||
|
||||
if (applyWet && (totalMetaFlags & 0x08) == 0)
|
||||
{
|
||||
if (!respectManual || state.Source[MetaIndex.Wetness] is not StateChanged.Source.Manual)
|
||||
_state.ChangeWetness(state, design.IsWet(), source);
|
||||
totalMetaFlags |= 0x08;
|
||||
if (!respectManual || state.Sources[index] is not StateSource.Manual)
|
||||
_state.ChangeMeta(state, index, design.GetMeta(index), source);
|
||||
totalMetaFlags |= index.ToFlag();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -163,16 +163,15 @@ public class DesignBase64Migration
|
|||
}
|
||||
}
|
||||
|
||||
public static unsafe string CreateOldBase64(in DesignData save, EquipFlag equipFlags, CustomizeFlag customizeFlags,
|
||||
bool setHat, bool setVisor, bool setWeapon, bool writeProtected, float alpha = 1.0f)
|
||||
public static unsafe string CreateOldBase64(in DesignData save, EquipFlag equipFlags, CustomizeFlag customizeFlags, MetaFlag meta, bool writeProtected, float alpha = 1.0f)
|
||||
{
|
||||
var data = stackalloc byte[Base64SizeV4];
|
||||
data[0] = 5;
|
||||
data[1] = (byte)((customizeFlags == CustomizeFlagExtensions.All ? 0x01 : 0)
|
||||
| (save.IsWet() ? 0x02 : 0)
|
||||
| (setHat ? 0x04 : 0)
|
||||
| (setWeapon ? 0x08 : 0)
|
||||
| (setVisor ? 0x10 : 0)
|
||||
| (meta.HasFlag(MetaFlag.HatState) ? 0x04 : 0)
|
||||
| (meta.HasFlag(MetaFlag.WeaponState) ? 0x08 : 0)
|
||||
| (meta.HasFlag(MetaFlag.VisorState) ? 0x10 : 0)
|
||||
| (writeProtected ? 0x20 : 0));
|
||||
data[2] = (byte)((equipFlags.HasFlag(EquipFlag.Mainhand) ? 0x01 : 0)
|
||||
| (equipFlags.HasFlag(EquipFlag.Offhand) ? 0x02 : 0)
|
||||
|
|
|
|||
|
|
@ -55,10 +55,10 @@ public class DesignConverter(ItemManager _items, DesignManager _designs, Customi
|
|||
design.ApplyCustomize = customizeFlags & CustomizeFlagExtensions.AllRelevant;
|
||||
design.ApplyCrest = crestFlags & CrestExtensions.All;
|
||||
design.ApplyParameters = parameterFlags & CustomizeParameterExtensions.All;
|
||||
design.SetApplyHatVisible(design.DoApplyEquip(EquipSlot.Head));
|
||||
design.SetApplyVisorToggle(design.DoApplyEquip(EquipSlot.Head));
|
||||
design.SetApplyWeaponVisible(design.DoApplyEquip(EquipSlot.MainHand) || design.DoApplyEquip(EquipSlot.OffHand));
|
||||
design.SetApplyWetness(true);
|
||||
design.SetApplyMeta(MetaIndex.HatState, design.DoApplyEquip(EquipSlot.Head));
|
||||
design.SetApplyMeta(MetaIndex.VisorState, design.DoApplyEquip(EquipSlot.Head));
|
||||
design.SetApplyMeta(MetaIndex.WeaponState, design.DoApplyEquip(EquipSlot.MainHand) || design.DoApplyEquip(EquipSlot.OffHand));
|
||||
design.SetApplyMeta(MetaIndex.Wetness, true);
|
||||
design.SetDesignData(_customize, data);
|
||||
return design;
|
||||
}
|
||||
|
|
@ -126,16 +126,14 @@ public class DesignConverter(ItemManager _items, DesignManager _designs, Customi
|
|||
return null;
|
||||
}
|
||||
|
||||
ret.SetApplyWetness(customize);
|
||||
ret.SetApplyMeta(MetaIndex.Wetness, customize);
|
||||
ret.ApplyCustomize = customize ? CustomizeFlagExtensions.AllRelevant : 0;
|
||||
|
||||
if (!equip)
|
||||
{
|
||||
ret.ApplyEquip = 0;
|
||||
ret.ApplyCrest = 0;
|
||||
ret.SetApplyHatVisible(false);
|
||||
ret.SetApplyWeaponVisible(false);
|
||||
ret.SetApplyVisorToggle(false);
|
||||
ret.ApplyMeta &= ~(MetaFlag.HatState | MetaFlag.WeaponState | MetaFlag.VisorState);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -523,15 +523,7 @@ public class DesignManager
|
|||
/// <summary> Change the application value of one of the meta flags. </summary>
|
||||
public void ChangeApplyMeta(Design design, MetaIndex metaIndex, bool value)
|
||||
{
|
||||
var change = metaIndex switch
|
||||
{
|
||||
MetaIndex.Wetness => design.SetApplyWetness(value),
|
||||
MetaIndex.HatState => design.SetApplyHatVisible(value),
|
||||
MetaIndex.VisorState => design.SetApplyVisorToggle(value),
|
||||
MetaIndex.WeaponState => design.SetApplyWeaponVisible(value),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(metaIndex), metaIndex, null),
|
||||
};
|
||||
if (!change)
|
||||
if (!design.SetApplyMeta(metaIndex, value))
|
||||
return;
|
||||
|
||||
design.LastEdit = DateTimeOffset.UtcNow;
|
||||
|
|
@ -556,14 +548,8 @@ public class DesignManager
|
|||
public void ApplyDesign(Design design, DesignBase other)
|
||||
{
|
||||
_undoStore[design.Identifier] = design.DesignData;
|
||||
if (other.DoApplyWetness())
|
||||
design.GetDesignDataRef().SetIsWet(other.DesignData.IsWet());
|
||||
if (other.DoApplyHatVisible())
|
||||
design.GetDesignDataRef().SetHatVisible(other.DesignData.IsHatVisible());
|
||||
if (other.DoApplyVisorToggle())
|
||||
design.GetDesignDataRef().SetVisor(other.DesignData.IsVisorToggled());
|
||||
if (other.DoApplyWeaponVisible())
|
||||
design.GetDesignDataRef().SetWeaponVisible(other.DesignData.IsWeaponVisible());
|
||||
foreach (var index in MetaExtensions.AllRelevant.Where(other.DoApplyMeta))
|
||||
design.GetDesignDataRef().SetMeta(index, other.DesignData.GetMeta(index));
|
||||
|
||||
if (design.DesignData.IsHuman)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using Glamourer.Automation;
|
||||
using Glamourer.Events;
|
||||
using Glamourer.GameData;
|
||||
using Glamourer.Services;
|
||||
using Glamourer.State;
|
||||
|
|
@ -28,13 +27,13 @@ public class DesignMerger(
|
|||
continue;
|
||||
|
||||
ref readonly var data = ref design == null ? ref baseRef : ref design.GetDesignDataRef();
|
||||
var source = design == null ? StateChanged.Source.Game : StateChanged.Source.Manual;
|
||||
var source = design == null ? StateSource.Game : StateSource.Manual;
|
||||
|
||||
if (!data.IsHuman)
|
||||
continue;
|
||||
|
||||
var (equipFlags, customizeFlags, crestFlags, parameterFlags, applyHat, applyVisor, applyWeapon, applyWet) = type.ApplyWhat(design);
|
||||
ReduceMeta(data, applyHat, applyVisor, applyWeapon, applyWet, ret, source);
|
||||
var (equipFlags, customizeFlags, crestFlags, parameterFlags, applyMeta) = type.ApplyWhat(design);
|
||||
ReduceMeta(data, applyMeta, ret, source);
|
||||
ReduceCustomize(data, customizeFlags, ref fixFlags, ret, source, respectOwnership);
|
||||
ReduceEquip(data, equipFlags, ret, source, respectOwnership);
|
||||
ReduceMainhands(data, equipFlags, ret, source, respectOwnership);
|
||||
|
|
@ -58,39 +57,22 @@ public class DesignMerger(
|
|||
ret.AssociatedMods.TryAdd(mod, settings);
|
||||
}
|
||||
|
||||
private static void ReduceMeta(in DesignData design, bool applyHat, bool applyVisor, bool applyWeapon, bool applyWet, MergedDesign ret,
|
||||
StateChanged.Source source)
|
||||
private static void ReduceMeta(in DesignData design, MetaFlag applyMeta, MergedDesign ret, StateSource source)
|
||||
{
|
||||
if (applyHat && !ret.Design.DoApplyHatVisible())
|
||||
{
|
||||
ret.Design.SetApplyHatVisible(true);
|
||||
ret.Design.GetDesignDataRef().SetHatVisible(design.IsHatVisible());
|
||||
ret.Source[MetaIndex.HatState] = source;
|
||||
}
|
||||
applyMeta &= ~ret.Design.ApplyMeta;
|
||||
|
||||
if (applyVisor && !ret.Design.DoApplyVisorToggle())
|
||||
foreach (var index in MetaExtensions.AllRelevant)
|
||||
{
|
||||
ret.Design.SetApplyVisorToggle(true);
|
||||
ret.Design.GetDesignDataRef().SetVisor(design.IsVisorToggled());
|
||||
ret.Source[MetaIndex.VisorState] = source;
|
||||
}
|
||||
if (!applyMeta.HasFlag(index.ToFlag()))
|
||||
continue;
|
||||
|
||||
if (applyWeapon && !ret.Design.DoApplyWeaponVisible())
|
||||
{
|
||||
ret.Design.SetApplyWeaponVisible(true);
|
||||
ret.Design.GetDesignDataRef().SetWeaponVisible(design.IsWeaponVisible());
|
||||
ret.Source[MetaIndex.WeaponState] = source;
|
||||
}
|
||||
|
||||
if (applyWet && !ret.Design.DoApplyWetness())
|
||||
{
|
||||
ret.Design.SetApplyWetness(true);
|
||||
ret.Design.GetDesignDataRef().SetIsWet(design.IsWet());
|
||||
ret.Source[MetaIndex.Wetness] = source;
|
||||
ret.Design.SetApplyMeta(index, true);
|
||||
ret.Design.GetDesignDataRef().SetMeta(index, design.GetMeta(index));
|
||||
ret.Sources[index] = source;
|
||||
}
|
||||
}
|
||||
|
||||
private static void ReduceCrests(in DesignData design, CrestFlag crestFlags, MergedDesign ret, StateChanged.Source source)
|
||||
private static void ReduceCrests(in DesignData design, CrestFlag crestFlags, MergedDesign ret, StateSource source)
|
||||
{
|
||||
crestFlags &= ~ret.Design.ApplyCrest;
|
||||
if (crestFlags == 0)
|
||||
|
|
@ -103,12 +85,12 @@ public class DesignMerger(
|
|||
|
||||
ret.Design.GetDesignDataRef().SetCrest(slot, design.Crest(slot));
|
||||
ret.Design.SetApplyCrest(slot, true);
|
||||
ret.Source[slot] = source;
|
||||
ret.Sources[slot] = source;
|
||||
}
|
||||
}
|
||||
|
||||
private static void ReduceParameters(in DesignData design, CustomizeParameterFlag parameterFlags, MergedDesign ret,
|
||||
StateChanged.Source source)
|
||||
StateSource source)
|
||||
{
|
||||
parameterFlags &= ~ret.Design.ApplyParameters;
|
||||
if (parameterFlags == 0)
|
||||
|
|
@ -121,11 +103,11 @@ public class DesignMerger(
|
|||
|
||||
ret.Design.GetDesignDataRef().Parameters.Set(flag, design.Parameters[flag]);
|
||||
ret.Design.SetApplyParameter(flag, true);
|
||||
ret.Source[flag] = source;
|
||||
ret.Sources[flag] = source;
|
||||
}
|
||||
}
|
||||
|
||||
private void ReduceEquip(in DesignData design, EquipFlag equipFlags, MergedDesign ret, StateChanged.Source source,
|
||||
private void ReduceEquip(in DesignData design, EquipFlag equipFlags, MergedDesign ret, StateSource source,
|
||||
bool respectOwnership)
|
||||
{
|
||||
equipFlags &= ~ret.Design.ApplyEquip;
|
||||
|
|
@ -142,7 +124,7 @@ public class DesignMerger(
|
|||
if (!respectOwnership || _itemUnlocks.IsUnlocked(item.Id, out _))
|
||||
ret.Design.GetDesignDataRef().SetItem(slot, item);
|
||||
ret.Design.SetApplyEquip(slot, true);
|
||||
ret.Source[slot, false] = source;
|
||||
ret.Sources[slot, false] = source;
|
||||
}
|
||||
|
||||
var stainFlag = slot.ToStainFlag();
|
||||
|
|
@ -150,7 +132,7 @@ public class DesignMerger(
|
|||
{
|
||||
ret.Design.GetDesignDataRef().SetStain(slot, design.Stain(slot));
|
||||
ret.Design.SetApplyStain(slot, true);
|
||||
ret.Source[slot, true] = source;
|
||||
ret.Sources[slot, true] = source;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -161,12 +143,12 @@ public class DesignMerger(
|
|||
{
|
||||
ret.Design.GetDesignDataRef().SetStain(slot, design.Stain(slot));
|
||||
ret.Design.SetApplyStain(slot, true);
|
||||
ret.Source[slot, true] = source;
|
||||
ret.Sources[slot, true] = source;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ReduceMainhands(in DesignData design, EquipFlag equipFlags, MergedDesign ret, StateChanged.Source source,
|
||||
private void ReduceMainhands(in DesignData design, EquipFlag equipFlags, MergedDesign ret, StateSource source,
|
||||
bool respectOwnership)
|
||||
{
|
||||
if (!equipFlags.HasFlag(EquipFlag.Mainhand))
|
||||
|
|
@ -185,7 +167,7 @@ public class DesignMerger(
|
|||
ret.Weapons.TryAdd(weapon.Type, (weapon, source));
|
||||
}
|
||||
|
||||
private void ReduceOffhands(in DesignData design, EquipFlag equipFlags, MergedDesign ret, StateChanged.Source source, bool respectOwnership)
|
||||
private void ReduceOffhands(in DesignData design, EquipFlag equipFlags, MergedDesign ret, StateSource source, bool respectOwnership)
|
||||
{
|
||||
if (!equipFlags.HasFlag(EquipFlag.Offhand))
|
||||
return;
|
||||
|
|
@ -205,7 +187,7 @@ public class DesignMerger(
|
|||
}
|
||||
|
||||
private void ReduceCustomize(in DesignData design, CustomizeFlag customizeFlags, ref CustomizeFlag fixFlags, MergedDesign ret,
|
||||
StateChanged.Source source, bool respectOwnership)
|
||||
StateSource source, bool respectOwnership)
|
||||
{
|
||||
customizeFlags &= ~ret.Design.ApplyCustomizeRaw;
|
||||
if (customizeFlags == 0)
|
||||
|
|
@ -222,8 +204,8 @@ public class DesignMerger(
|
|||
ret.Design.SetApplyCustomize(CustomizeIndex.Clan, true);
|
||||
ret.Design.SetApplyCustomize(CustomizeIndex.Race, true);
|
||||
customizeFlags &= ~(CustomizeFlag.Clan | CustomizeFlag.Race);
|
||||
ret.Source[CustomizeIndex.Clan] = source;
|
||||
ret.Source[CustomizeIndex.Race] = source;
|
||||
ret.Sources[CustomizeIndex.Clan] = source;
|
||||
ret.Sources[CustomizeIndex.Race] = source;
|
||||
}
|
||||
|
||||
if (customizeFlags.HasFlag(CustomizeFlag.Gender))
|
||||
|
|
@ -231,7 +213,7 @@ public class DesignMerger(
|
|||
fixFlags |= _customize.ChangeGender(ref customize, design.Customize.Gender);
|
||||
ret.Design.SetApplyCustomize(CustomizeIndex.Gender, true);
|
||||
customizeFlags &= ~CustomizeFlag.Gender;
|
||||
ret.Source[CustomizeIndex.Gender] = source;
|
||||
ret.Sources[CustomizeIndex.Gender] = source;
|
||||
}
|
||||
|
||||
if (customizeFlags.HasFlag(CustomizeFlag.Face))
|
||||
|
|
@ -239,7 +221,7 @@ public class DesignMerger(
|
|||
customize[CustomizeIndex.Face] = design.Customize.Face;
|
||||
ret.Design.SetApplyCustomize(CustomizeIndex.Face, true);
|
||||
customizeFlags &= ~CustomizeFlag.Face;
|
||||
ret.Source[CustomizeIndex.Face] = source;
|
||||
ret.Sources[CustomizeIndex.Face] = source;
|
||||
}
|
||||
|
||||
var set = ret.Design.CustomizeSet;
|
||||
|
|
@ -259,7 +241,7 @@ public class DesignMerger(
|
|||
|
||||
customize[index] = data?.Value ?? value;
|
||||
ret.Design.SetApplyCustomize(index, true);
|
||||
ret.Source[index] = source;
|
||||
ret.Sources[index] = source;
|
||||
fixFlags &= ~flag;
|
||||
}
|
||||
|
||||
|
|
@ -272,15 +254,15 @@ public class DesignMerger(
|
|||
return;
|
||||
|
||||
var source = ret.Design.DoApplyCustomize(CustomizeIndex.Clan)
|
||||
? ret.Source[CustomizeIndex.Clan]
|
||||
: ret.Source[CustomizeIndex.Gender];
|
||||
? ret.Sources[CustomizeIndex.Clan]
|
||||
: ret.Sources[CustomizeIndex.Gender];
|
||||
foreach (var index in Enum.GetValues<CustomizeIndex>())
|
||||
{
|
||||
var flag = index.ToFlag();
|
||||
if (!fixFlags.HasFlag(flag))
|
||||
continue;
|
||||
|
||||
ret.Source[index] = source;
|
||||
ret.Sources[index] = source;
|
||||
ret.Design.SetApplyCustomize(index, true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,14 +26,14 @@ public sealed class MergedDesign
|
|||
{
|
||||
var weapon = design.DesignData.Item(EquipSlot.MainHand);
|
||||
if (weapon.Valid)
|
||||
Weapons.TryAdd(weapon.Type, (weapon, StateChanged.Source.Manual));
|
||||
Weapons.TryAdd(weapon.Type, (weapon, StateSource.Manual));
|
||||
}
|
||||
|
||||
if (design.DoApplyEquip(EquipSlot.OffHand))
|
||||
{
|
||||
var weapon = design.DesignData.Item(EquipSlot.OffHand);
|
||||
if (weapon.Valid)
|
||||
Weapons.TryAdd(weapon.Type, (weapon, StateChanged.Source.Manual));
|
||||
Weapons.TryAdd(weapon.Type, (weapon, StateSource.Manual));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -45,25 +45,25 @@ public sealed class MergedDesign
|
|||
}
|
||||
|
||||
public readonly DesignBase Design;
|
||||
public readonly Dictionary<FullEquipType, (EquipItem, StateChanged.Source)> Weapons = new(4);
|
||||
public readonly StateSource Source = new();
|
||||
public readonly Dictionary<FullEquipType, (EquipItem, StateSource)> Weapons = new(4);
|
||||
public readonly SortedList<Mod, ModSettings> AssociatedMods = [];
|
||||
public StateSources Sources = new();
|
||||
|
||||
public StateChanged.Source GetSource(EquipSlot slot, bool stain, StateChanged.Source actualSource)
|
||||
=> GetSource(Source[slot, stain], actualSource);
|
||||
public StateSource GetSource(EquipSlot slot, bool stain, StateSource actualSource)
|
||||
=> GetSource(Sources[slot, stain], actualSource);
|
||||
|
||||
public StateChanged.Source GetSource(CrestFlag slot, StateChanged.Source actualSource)
|
||||
=> GetSource(Source[slot], actualSource);
|
||||
public StateSource GetSource(CrestFlag slot, StateSource actualSource)
|
||||
=> GetSource(Sources[slot], actualSource);
|
||||
|
||||
public StateChanged.Source GetSource(CustomizeIndex type, StateChanged.Source actualSource)
|
||||
=> GetSource(Source[type], actualSource);
|
||||
public StateSource GetSource(CustomizeIndex type, StateSource actualSource)
|
||||
=> GetSource(Sources[type], actualSource);
|
||||
|
||||
public StateChanged.Source GetSource(MetaIndex index, StateChanged.Source actualSource)
|
||||
=> GetSource(Source[index], actualSource);
|
||||
public StateSource GetSource(MetaIndex index, StateSource actualSource)
|
||||
=> GetSource(Sources[index], actualSource);
|
||||
|
||||
public StateChanged.Source GetSource(CustomizeParameterFlag flag, StateChanged.Source actualSource)
|
||||
=> GetSource(Source[flag], actualSource);
|
||||
public StateSource GetSource(CustomizeParameterFlag flag, StateSource actualSource)
|
||||
=> GetSource(Sources[flag], actualSource);
|
||||
|
||||
public static StateChanged.Source GetSource(StateChanged.Source given, StateChanged.Source actualSource)
|
||||
=> given is StateChanged.Source.Game ? StateChanged.Source.Game : actualSource;
|
||||
public static StateSource GetSource(StateSource given, StateSource actualSource)
|
||||
=> given is StateSource.Game ? StateSource.Game : actualSource;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
using Penumbra.GameData.Enums;
|
||||
using Glamourer.State;
|
||||
|
||||
namespace Glamourer.State;
|
||||
namespace Glamourer.Designs;
|
||||
|
||||
public enum MetaIndex
|
||||
{
|
||||
Wetness = EquipFlagExtensions.NumEquipFlags + CustomizationExtensions.NumIndices,
|
||||
HatState,
|
||||
VisorState,
|
||||
WeaponState,
|
||||
ModelId,
|
||||
Wetness = StateIndex.MetaWetness,
|
||||
HatState = StateIndex.MetaHatState,
|
||||
VisorState = StateIndex.MetaVisorState,
|
||||
WeaponState = StateIndex.MetaWeaponState,
|
||||
ModelId = StateIndex.MetaModelId,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
|
|
@ -36,4 +36,24 @@ public static class MetaExtensions
|
|||
MetaIndex.WeaponState => MetaFlag.WeaponState,
|
||||
_ => (MetaFlag)byte.MaxValue,
|
||||
};
|
||||
|
||||
public static string ToName(this MetaIndex index)
|
||||
=> index switch
|
||||
{
|
||||
MetaIndex.HatState => "Hat Visible",
|
||||
MetaIndex.VisorState => "Visor Toggled",
|
||||
MetaIndex.WeaponState => "Weapon Visible",
|
||||
MetaIndex.Wetness => "Force Wetness",
|
||||
_ => "Unknown Meta",
|
||||
};
|
||||
|
||||
public static string ToTooltip(this MetaIndex index)
|
||||
=> index switch
|
||||
{
|
||||
MetaIndex.HatState => "Hide or show the characters head gear.",
|
||||
MetaIndex.VisorState => "Toggle the visor state of the characters head gear.",
|
||||
MetaIndex.WeaponState => "Hide or show the characters weapons when not drawn.",
|
||||
MetaIndex.Wetness => "Force the character to be wet or not.",
|
||||
_ => string.Empty,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ using Glamourer.Interop.Structs;
|
|||
using Glamourer.State;
|
||||
using OtterGui.Classes;
|
||||
|
||||
namespace Glamourer.Events;
|
||||
|
||||
namespace Glamourer.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// Triggered when a Design is edited in any way.
|
||||
/// <list type="number">
|
||||
|
|
@ -14,7 +14,7 @@ namespace Glamourer.Events;
|
|||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class StateChanged()
|
||||
: EventWrapper<StateChanged.Type, StateChanged.Source, ActorState, ActorData, object?, StateChanged.Priority>(nameof(StateChanged))
|
||||
: EventWrapper<StateChanged.Type, StateSource, ActorState, ActorData, object?, StateChanged.Priority>(nameof(StateChanged))
|
||||
{
|
||||
public enum Type
|
||||
{
|
||||
|
|
@ -52,18 +52,9 @@ public sealed class StateChanged()
|
|||
Other,
|
||||
}
|
||||
|
||||
public enum Source : byte
|
||||
{
|
||||
Game,
|
||||
Manual,
|
||||
Fixed,
|
||||
Ipc,
|
||||
// Only used for CustomizeParameters.
|
||||
Pending,
|
||||
}
|
||||
|
||||
public enum Priority
|
||||
{
|
||||
GlamourerIpc = int.MinValue,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ public ref struct CustomizeParameterDrawData(CustomizeParameterFlag flag, in Des
|
|||
{
|
||||
Locked = state.IsLocked,
|
||||
DisplayApplication = false,
|
||||
ValueSetter = v => manager.ChangeCustomizeParameter(state, flag, v, StateChanged.Source.Manual),
|
||||
ValueSetter = v => manager.ChangeCustomizeParameter(state, flag, v, StateSource.Manual),
|
||||
GameValue = state.BaseData.Parameters[flag],
|
||||
AllowRevert = true,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ public sealed class DesignQuickBar : Window, IDisposable
|
|||
|
||||
var (applyGear, applyCustomize, applyCrest, applyParameters) = UiHelpers.ConvertKeysToFlags();
|
||||
using var _ = design!.TemporarilyRestrictApplication(applyGear, applyCustomize, applyCrest, applyParameters);
|
||||
_stateManager.ApplyDesign(design, state, StateChanged.Source.Manual);
|
||||
_stateManager.ApplyDesign(design, state, StateSource.Manual);
|
||||
}
|
||||
|
||||
public void DrawRevertButton(Vector2 buttonSize)
|
||||
|
|
@ -189,7 +189,7 @@ public sealed class DesignQuickBar : Window, IDisposable
|
|||
|
||||
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.UndoAlt, buttonSize, tooltip, available);
|
||||
if (clicked)
|
||||
_stateManager.ResetState(state!, StateChanged.Source.Manual);
|
||||
_stateManager.ResetState(state!, StateSource.Manual);
|
||||
}
|
||||
|
||||
public void DrawRevertAutomationButton(Vector2 buttonSize)
|
||||
|
|
@ -257,7 +257,7 @@ public sealed class DesignQuickBar : Window, IDisposable
|
|||
ImGui.SameLine();
|
||||
var (clicked, _, _, state) = ResolveTarget(FontAwesomeIcon.Palette, buttonSize, tooltip, available);
|
||||
if (clicked)
|
||||
_stateManager.ResetAdvancedState(state!, StateChanged.Source.Manual);
|
||||
_stateManager.ResetAdvancedState(state!, StateSource.Manual);
|
||||
}
|
||||
|
||||
private (bool, ActorIdentifier, ActorData, ActorState?) ResolveTarget(FontAwesomeIcon icon, Vector2 buttonSize, string tooltip,
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ public ref struct EquipDrawData(EquipSlot slot, in DesignData designData)
|
|||
public static EquipDrawData FromState(StateManager manager, ActorState state, EquipSlot slot)
|
||||
=> new(slot, state.ModelData)
|
||||
{
|
||||
ItemSetter = i => manager.ChangeItem(state, slot, i, StateChanged.Source.Manual),
|
||||
StainSetter = i => manager.ChangeStain(state, slot, i, StateChanged.Source.Manual),
|
||||
ItemSetter = i => manager.ChangeItem(state, slot, i, StateSource.Manual),
|
||||
StainSetter = i => manager.ChangeStain(state, slot, i, StateSource.Manual),
|
||||
Locked = state.IsLocked,
|
||||
DisplayApplication = false,
|
||||
GameItem = state.BaseData.Item(slot),
|
||||
|
|
|
|||
|
|
@ -113,22 +113,22 @@ public class PenumbraChangedItemTooltip : IDisposable
|
|||
case (false, false):
|
||||
Glamourer.Log.Information($"Applying {item.Name} to Right Finger.");
|
||||
SetLastItem(EquipSlot.RFinger, item, state);
|
||||
_stateManager.ChangeItem(state, EquipSlot.RFinger, item, StateChanged.Source.Manual);
|
||||
_stateManager.ChangeItem(state, EquipSlot.RFinger, item, StateSource.Manual);
|
||||
break;
|
||||
case (false, true):
|
||||
Glamourer.Log.Information($"Applying {item.Name} to Left Finger.");
|
||||
SetLastItem(EquipSlot.LFinger, item, state);
|
||||
_stateManager.ChangeItem(state, EquipSlot.LFinger, item, StateChanged.Source.Manual);
|
||||
_stateManager.ChangeItem(state, EquipSlot.LFinger, item, StateSource.Manual);
|
||||
break;
|
||||
case (true, false) when last.Valid:
|
||||
Glamourer.Log.Information($"Re-Applying {last.Name} to Right Finger.");
|
||||
SetLastItem(EquipSlot.RFinger, default, state);
|
||||
_stateManager.ChangeItem(state, EquipSlot.RFinger, last, StateChanged.Source.Manual);
|
||||
_stateManager.ChangeItem(state, EquipSlot.RFinger, last, StateSource.Manual);
|
||||
break;
|
||||
case (true, true) when _lastItems[EquipSlot.LFinger.ToIndex()].Valid:
|
||||
Glamourer.Log.Information($"Re-Applying {last.Name} to Left Finger.");
|
||||
SetLastItem(EquipSlot.LFinger, default, state);
|
||||
_stateManager.ChangeItem(state, EquipSlot.LFinger, last, StateChanged.Source.Manual);
|
||||
_stateManager.ChangeItem(state, EquipSlot.LFinger, last, StateSource.Manual);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -138,13 +138,13 @@ public class PenumbraChangedItemTooltip : IDisposable
|
|||
{
|
||||
Glamourer.Log.Information($"Re-Applying {last.Name} to {slot.ToName()}.");
|
||||
SetLastItem(slot, default, state);
|
||||
_stateManager.ChangeItem(state, slot, last, StateChanged.Source.Manual);
|
||||
_stateManager.ChangeItem(state, slot, last, StateSource.Manual);
|
||||
}
|
||||
else
|
||||
{
|
||||
Glamourer.Log.Information($"Applying {item.Name} to {slot.ToName()}.");
|
||||
SetLastItem(slot, item, state);
|
||||
_stateManager.ChangeItem(state, slot, item, StateChanged.Source.Manual);
|
||||
_stateManager.ChangeItem(state, slot, item, StateSource.Manual);
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -61,13 +61,13 @@ public class ActorPanel(
|
|||
|
||||
if (_importService.CreateDatTarget(out var dat))
|
||||
{
|
||||
_stateManager.ChangeCustomize(_state!, dat.Customize, CustomizeApplicationFlags, StateChanged.Source.Manual);
|
||||
_stateManager.ChangeCustomize(_state!, dat.Customize, CustomizeApplicationFlags, StateSource.Manual);
|
||||
Glamourer.Messager.NotificationMessage($"Applied games .dat file {dat.Description} customizations to {_state.Identifier}.",
|
||||
NotificationType.Success, false);
|
||||
}
|
||||
else if (_importService.CreateCharaTarget(out var designBase, out var name))
|
||||
{
|
||||
_stateManager.ApplyDesign(designBase, _state!, StateChanged.Source.Manual);
|
||||
_stateManager.ApplyDesign(designBase, _state!, StateSource.Manual);
|
||||
Glamourer.Messager.NotificationMessage($"Applied Anamnesis .chara file {name} to {_state.Identifier}.", NotificationType.Success,
|
||||
false);
|
||||
}
|
||||
|
|
@ -139,7 +139,7 @@ public class ActorPanel(
|
|||
return;
|
||||
|
||||
if (_customizationDrawer.Draw(_state!.ModelData.Customize, _state.IsLocked, _lockedRedraw))
|
||||
_stateManager.ChangeCustomize(_state, _customizationDrawer.Customize, _customizationDrawer.Changed, StateChanged.Source.Manual);
|
||||
_stateManager.ChangeCustomize(_state, _customizationDrawer.Customize, _customizationDrawer.Changed, StateSource.Manual);
|
||||
|
||||
EquipmentDrawer.DrawMetaToggle(ToggleDrawData.FromState(MetaIndex.Wetness, _stateManager, _state));
|
||||
ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight() / 2));
|
||||
|
|
@ -159,7 +159,7 @@ public class ActorPanel(
|
|||
var data = EquipDrawData.FromState(_stateManager, _state!, slot);
|
||||
_equipmentDrawer.DrawEquip(data);
|
||||
if (usedAllStain)
|
||||
_stateManager.ChangeStain(_state, slot, newAllStain, StateChanged.Source.Manual);
|
||||
_stateManager.ChangeStain(_state, slot, newAllStain, StateSource.Manual);
|
||||
}
|
||||
|
||||
var mainhand = EquipDrawData.FromState(_stateManager, _state, EquipSlot.MainHand);
|
||||
|
|
@ -264,7 +264,7 @@ public class ActorPanel(
|
|||
}
|
||||
|
||||
if (turnHuman)
|
||||
_stateManager.TurnHuman(_state, StateChanged.Source.Manual);
|
||||
_stateManager.TurnHuman(_state, StateSource.Manual);
|
||||
}
|
||||
|
||||
private HeaderDrawer.Button SetFromClipboardButton()
|
||||
|
|
@ -340,7 +340,7 @@ public class ActorPanel(
|
|||
var text = ImGui.GetClipboardText();
|
||||
var design = _converter.FromBase64(text, applyCustomize, applyGear, out _)
|
||||
?? throw new Exception("The clipboard did not contain valid data.");
|
||||
_stateManager.ApplyDesign(design, _state!, StateChanged.Source.Manual);
|
||||
_stateManager.ApplyDesign(design, _state!, StateSource.Manual);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -368,7 +368,7 @@ public class ActorPanel(
|
|||
{
|
||||
if (ImGuiUtil.DrawDisabledButton("Revert to Game", Vector2.Zero, "Revert the character to its actual state in the game.",
|
||||
_state!.IsLocked))
|
||||
_stateManager.ResetState(_state!, StateChanged.Source.Manual);
|
||||
_stateManager.ResetState(_state!, StateSource.Manual);
|
||||
|
||||
ImGui.SameLine();
|
||||
if (ImGuiUtil.DrawDisabledButton("Reapply State", Vector2.Zero, "Try to reapply the configured state if something went wrong.",
|
||||
|
|
@ -396,7 +396,7 @@ public class ActorPanel(
|
|||
var (applyGear, applyCustomize, applyCrest, applyParameters) = UiHelpers.ConvertKeysToFlags();
|
||||
if (_stateManager.GetOrCreate(id, data.Objects[0], out var state))
|
||||
_stateManager.ApplyDesign(_converter.Convert(_state!, applyGear, applyCustomize, applyCrest, applyParameters), state,
|
||||
StateChanged.Source.Manual);
|
||||
StateSource.Manual);
|
||||
}
|
||||
|
||||
private void DrawApplyToTarget()
|
||||
|
|
@ -414,6 +414,6 @@ public class ActorPanel(
|
|||
var (applyGear, applyCustomize, applyCrest, applyParameters) = UiHelpers.ConvertKeysToFlags();
|
||||
if (_stateManager.GetOrCreate(id, data.Objects[0], out var state))
|
||||
_stateManager.ApplyDesign(_converter.Convert(_state!, applyGear, applyCustomize, applyCrest, applyParameters), state,
|
||||
StateChanged.Source.Manual);
|
||||
StateSource.Manual);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ public class SetPanel(
|
|||
var size = new Vector2(ImGui.GetFrameHeight());
|
||||
size.X += ImGuiHelpers.GlobalScale;
|
||||
|
||||
var (equipFlags, customizeFlags, _, _, _, _, _, _) = design.ApplyWhat();
|
||||
var (equipFlags, customizeFlags, _, _, _) = design.ApplyWhat();
|
||||
var sb = new StringBuilder();
|
||||
foreach (var slot in EquipSlotExtensions.EqdpSlots.Append(EquipSlot.MainHand).Append(EquipSlot.OffHand))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -52,11 +52,11 @@ public class ActiveStatePanel(StateManager _stateManager, ObjectManager _objectM
|
|||
ImGuiUtil.DrawTableColumn(state.Identifier.ToString());
|
||||
ImGui.TableNextColumn();
|
||||
if (ImGui.Button("Reset"))
|
||||
stateManager.ResetState(state, StateChanged.Source.Manual);
|
||||
stateManager.ResetState(state, StateSource.Manual);
|
||||
|
||||
ImGui.TableNextRow();
|
||||
|
||||
static void PrintRow<T>(string label, T actor, T model, StateChanged.Source source) where T : notnull
|
||||
static void PrintRow<T>(string label, T actor, T model, StateSource source) where T : notnull
|
||||
{
|
||||
ImGuiUtil.DrawTableColumn(label);
|
||||
ImGuiUtil.DrawTableColumn(actor.ToString()!);
|
||||
|
|
@ -70,44 +70,44 @@ public class ActiveStatePanel(StateManager _stateManager, ObjectManager _objectM
|
|||
return $"{item.Name} ({item.PrimaryId.Id}{(item.SecondaryId != 0 ? $"-{item.SecondaryId.Id}" : string.Empty)}-{item.Variant})";
|
||||
}
|
||||
|
||||
PrintRow("Model ID", state.BaseData.ModelId, state.ModelData.ModelId, state.Source[MetaIndex.ModelId]);
|
||||
PrintRow("Model ID", state.BaseData.ModelId, state.ModelData.ModelId, state.Sources[MetaIndex.ModelId]);
|
||||
ImGui.TableNextRow();
|
||||
PrintRow("Wetness", state.BaseData.IsWet(), state.ModelData.IsWet(), state.Source[MetaIndex.Wetness]);
|
||||
PrintRow("Wetness", state.BaseData.IsWet(), state.ModelData.IsWet(), state.Sources[MetaIndex.Wetness]);
|
||||
ImGui.TableNextRow();
|
||||
|
||||
if (state.BaseData.IsHuman && state.ModelData.IsHuman)
|
||||
{
|
||||
PrintRow("Hat Visible", state.BaseData.IsHatVisible(), state.ModelData.IsHatVisible(), state.Source[MetaIndex.HatState]);
|
||||
PrintRow("Hat Visible", state.BaseData.IsHatVisible(), state.ModelData.IsHatVisible(), state.Sources[MetaIndex.HatState]);
|
||||
ImGui.TableNextRow();
|
||||
PrintRow("Visor Toggled", state.BaseData.IsVisorToggled(), state.ModelData.IsVisorToggled(),
|
||||
state.Source[MetaIndex.VisorState]);
|
||||
state.Sources[MetaIndex.VisorState]);
|
||||
ImGui.TableNextRow();
|
||||
PrintRow("Weapon Visible", state.BaseData.IsWeaponVisible(), state.ModelData.IsWeaponVisible(),
|
||||
state.Source[MetaIndex.WeaponState]);
|
||||
state.Sources[MetaIndex.WeaponState]);
|
||||
ImGui.TableNextRow();
|
||||
foreach (var slot in EquipSlotExtensions.EqdpSlots.Prepend(EquipSlot.OffHand).Prepend(EquipSlot.MainHand))
|
||||
{
|
||||
PrintRow(slot.ToName(), ItemString(state.BaseData, slot), ItemString(state.ModelData, slot), state.Source[slot, false]);
|
||||
PrintRow(slot.ToName(), ItemString(state.BaseData, slot), ItemString(state.ModelData, slot), state.Sources[slot, false]);
|
||||
ImGuiUtil.DrawTableColumn(state.BaseData.Stain(slot).Id.ToString());
|
||||
ImGuiUtil.DrawTableColumn(state.ModelData.Stain(slot).Id.ToString());
|
||||
ImGuiUtil.DrawTableColumn(state.Source[slot, true].ToString());
|
||||
ImGuiUtil.DrawTableColumn(state.Sources[slot, true].ToString());
|
||||
}
|
||||
|
||||
foreach (var type in Enum.GetValues<CustomizeIndex>())
|
||||
{
|
||||
PrintRow(type.ToDefaultName(), state.BaseData.Customize[type].Value, state.ModelData.Customize[type].Value, state.Source[type]);
|
||||
PrintRow(type.ToDefaultName(), state.BaseData.Customize[type].Value, state.ModelData.Customize[type].Value, state.Sources[type]);
|
||||
ImGui.TableNextRow();
|
||||
}
|
||||
|
||||
foreach (var crest in CrestExtensions.AllRelevantSet)
|
||||
{
|
||||
PrintRow(crest.ToLabel(), state.BaseData.Crest(crest), state.ModelData.Crest(crest), state.Source[crest]);
|
||||
PrintRow(crest.ToLabel(), state.BaseData.Crest(crest), state.ModelData.Crest(crest), state.Sources[crest]);
|
||||
ImGui.TableNextRow();
|
||||
}
|
||||
|
||||
foreach (var flag in CustomizeParameterExtensions.AllFlags)
|
||||
{
|
||||
PrintRow(flag.ToString(), state.BaseData.Parameters[flag], state.ModelData.Parameters[flag], state.Source[flag]);
|
||||
PrintRow(flag.ToString(), state.BaseData.Parameters[flag], state.ModelData.Parameters[flag], state.Sources[flag]);
|
||||
ImGui.TableNextRow();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,9 +25,8 @@ public class DesignManagerPanel(DesignManager _designManager, DesignFileSystem _
|
|||
continue;
|
||||
|
||||
DrawDesign(design, _designFileSystem);
|
||||
var base64 = DesignBase64Migration.CreateOldBase64(design.DesignData, design.ApplyEquip, design.ApplyCustomizeRaw,
|
||||
design.DoApplyHatVisible(),
|
||||
design.DoApplyVisorToggle(), design.DoApplyWeaponVisible(), design.WriteProtected());
|
||||
var base64 = DesignBase64Migration.CreateOldBase64(design.DesignData, design.ApplyEquip, design.ApplyCustomizeRaw, design.ApplyMeta,
|
||||
design.WriteProtected());
|
||||
using var font = ImRaii.PushFont(UiBuilder.MonoFont);
|
||||
ImGuiUtil.TextWrapped(base64);
|
||||
if (ImGui.IsItemClicked())
|
||||
|
|
@ -85,18 +84,12 @@ public class DesignManagerPanel(DesignManager _designManager, DesignFileSystem _
|
|||
ImGuiUtil.DrawTableColumn(applyCrest ? "Apply" : "Keep");
|
||||
}
|
||||
|
||||
ImGuiUtil.DrawTableColumn("Hat Visible");
|
||||
ImGuiUtil.DrawTableColumn(design.DesignData.IsHatVisible().ToString());
|
||||
ImGuiUtil.DrawTableColumn(design.DoApplyHatVisible() ? "Apply" : "Keep");
|
||||
ImGui.TableNextRow();
|
||||
ImGuiUtil.DrawTableColumn("Visor Toggled");
|
||||
ImGuiUtil.DrawTableColumn(design.DesignData.IsVisorToggled().ToString());
|
||||
ImGuiUtil.DrawTableColumn(design.DoApplyVisorToggle() ? "Apply" : "Keep");
|
||||
ImGui.TableNextRow();
|
||||
ImGuiUtil.DrawTableColumn("Weapon Visible");
|
||||
ImGuiUtil.DrawTableColumn(design.DesignData.IsWeaponVisible().ToString());
|
||||
ImGuiUtil.DrawTableColumn(design.DoApplyWeaponVisible() ? "Apply" : "Keep");
|
||||
ImGui.TableNextRow();
|
||||
foreach (var index in MetaExtensions.AllRelevant)
|
||||
{
|
||||
ImGuiUtil.DrawTableColumn(index.ToName());
|
||||
ImGuiUtil.DrawTableColumn(design.DesignData.GetMeta(index).ToString());
|
||||
ImGuiUtil.DrawTableColumn(design.DoApplyMeta(index) ? "Apply" : "Keep");
|
||||
}
|
||||
|
||||
ImGuiUtil.DrawTableColumn("Model ID");
|
||||
ImGuiUtil.DrawTableColumn(design.DesignData.ModelId.ToString());
|
||||
|
|
@ -111,9 +104,5 @@ public class DesignManagerPanel(DesignManager _designManager, DesignFileSystem _
|
|||
ImGuiUtil.DrawTableColumn(apply ? "Apply" : "Keep");
|
||||
ImGui.TableNextRow();
|
||||
}
|
||||
|
||||
ImGuiUtil.DrawTableColumn("Is Wet");
|
||||
ImGuiUtil.DrawTableColumn(design.DesignData.IsWet().ToString());
|
||||
ImGui.TableNextRow();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,10 +55,8 @@ public class DesignTesterPanel(ItemManager _items, HumanModelList _humans) : IGa
|
|||
|
||||
try
|
||||
{
|
||||
_parse64 = DesignBase64Migration.MigrateBase64(_items, _humans, _base64, out var ef, out var cf, out var wp, out var ah,
|
||||
out var av,
|
||||
out var aw);
|
||||
_restore = DesignBase64Migration.CreateOldBase64(in _parse64, ef, cf, ah, av, aw, wp);
|
||||
_parse64 = DesignBase64Migration.MigrateBase64(_items, _humans, _base64, out var ef, out var cf, out var wp, out var meta);
|
||||
_restore = DesignBase64Migration.CreateOldBase64(in _parse64, ef, cf, meta, wp);
|
||||
_restoreBytes = Convert.FromBase64String(_restore);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
|||
|
|
@ -67,9 +67,9 @@ public class NpcAppearancePanel(NpcCombo _npcCombo, StateManager _state, ObjectM
|
|||
if (ImGuiUtil.DrawDisabledButton("Apply", Vector2.Zero, string.Empty, disabled))
|
||||
{
|
||||
foreach (var (slot, item, stain) in _designConverter.FromDrawData(data.Equip.ToArray(), data.Mainhand, data.Offhand, true))
|
||||
_state.ChangeEquip(state!, slot, item, stain, StateChanged.Source.Manual);
|
||||
_state.ChangeVisorState(state!, data.VisorToggled, StateChanged.Source.Manual);
|
||||
_state.ChangeCustomize(state!, data.Customize, CustomizeFlagExtensions.All, StateChanged.Source.Manual);
|
||||
_state.ChangeEquip(state!, slot, item, stain, StateSource.Manual);
|
||||
_state.ChangeMeta(state!, MetaIndex.VisorState, data.VisorToggled, StateSource.Manual);
|
||||
_state.ChangeCustomize(state!, data.Customize, CustomizeFlagExtensions.All, StateSource.Manual);
|
||||
}
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
|
|
|
|||
|
|
@ -288,27 +288,24 @@ public class DesignPanel(
|
|||
private void DrawMetaApplication()
|
||||
{
|
||||
using var id = ImRaii.PushId("Meta");
|
||||
const uint all = 0x0Fu;
|
||||
var flags = (_selector.Selected!.DoApplyHatVisible() ? 0x01u : 0x00)
|
||||
| (_selector.Selected!.DoApplyVisorToggle() ? 0x02u : 0x00)
|
||||
| (_selector.Selected!.DoApplyWeaponVisible() ? 0x04u : 0x00)
|
||||
| (_selector.Selected!.DoApplyWetness() ? 0x08u : 0x00);
|
||||
const uint all = (uint)MetaExtensions.All;
|
||||
var flags = (uint)_selector.Selected!.ApplyMeta;
|
||||
var bigChange = ImGui.CheckboxFlags("Apply All Meta Changes", ref flags, all);
|
||||
var apply = bigChange ? (flags & 0x01) == 0x01 : _selector.Selected!.DoApplyHatVisible();
|
||||
if (ImGui.Checkbox("Apply Hat Visibility", ref apply) || bigChange)
|
||||
|
||||
var labels = new[]
|
||||
{
|
||||
"Apply Hat Visibility",
|
||||
"Apply Visor State",
|
||||
"Apply Weapon Visibility",
|
||||
"Apply Wetness",
|
||||
};
|
||||
|
||||
foreach (var (index, label) in MetaExtensions.AllRelevant.Zip(labels))
|
||||
{
|
||||
var apply = bigChange ? ((MetaFlag)flags).HasFlag(index.ToFlag()) : _selector.Selected!.DoApplyMeta(index);
|
||||
if (ImGui.Checkbox(label, ref apply) || bigChange)
|
||||
_manager.ChangeApplyMeta(_selector.Selected!, MetaIndex.HatState, apply);
|
||||
|
||||
apply = bigChange ? (flags & 0x02) == 0x02 : _selector.Selected!.DoApplyVisorToggle();
|
||||
if (ImGui.Checkbox("Apply Visor State", ref apply) || bigChange)
|
||||
_manager.ChangeApplyMeta(_selector.Selected!, MetaIndex.VisorState, apply);
|
||||
|
||||
apply = bigChange ? (flags & 0x04) == 0x04 : _selector.Selected!.DoApplyWeaponVisible();
|
||||
if (ImGui.Checkbox("Apply Weapon Visibility", ref apply) || bigChange)
|
||||
_manager.ChangeApplyMeta(_selector.Selected!, MetaIndex.WeaponState, apply);
|
||||
|
||||
apply = bigChange ? (flags & 0x08) == 0x08 : _selector.Selected!.DoApplyWetness();
|
||||
if (ImGui.Checkbox("Apply Wetness", ref apply) || bigChange)
|
||||
_manager.ChangeApplyMeta(_selector.Selected!, MetaIndex.Wetness, apply);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawParameterApplication()
|
||||
|
|
@ -442,7 +439,7 @@ public class DesignPanel(
|
|||
{
|
||||
var (applyGear, applyCustomize, applyCrest, applyParameters) = UiHelpers.ConvertKeysToFlags();
|
||||
using var _ = _selector.Selected!.TemporarilyRestrictApplication(applyGear, applyCustomize, applyCrest, applyParameters);
|
||||
_state.ApplyDesign(_selector.Selected!, state, StateChanged.Source.Manual);
|
||||
_state.ApplyDesign(_selector.Selected!, state, StateSource.Manual);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -461,7 +458,7 @@ public class DesignPanel(
|
|||
{
|
||||
var (applyGear, applyCustomize, applyCrest, applyParameters) = UiHelpers.ConvertKeysToFlags();
|
||||
using var _ = _selector.Selected!.TemporarilyRestrictApplication(applyGear, applyCustomize, applyCrest, applyParameters);
|
||||
_state.ApplyDesign(_selector.Selected!, state, StateChanged.Source.Manual);
|
||||
_state.ApplyDesign(_selector.Selected!, state, StateSource.Manual);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ public class NpcPanel(
|
|||
{
|
||||
var (applyGear, applyCustomize, _, _) = UiHelpers.ConvertKeysToFlags();
|
||||
var design = _converter.Convert(ToDesignData(), applyGear, applyCustomize, 0, 0);
|
||||
_state.ApplyDesign(design, state, StateChanged.Source.Manual);
|
||||
_state.ApplyDesign(design, state, StateSource.Manual);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -221,7 +221,7 @@ public class NpcPanel(
|
|||
{
|
||||
var (applyGear, applyCustomize, _, _) = UiHelpers.ConvertKeysToFlags();
|
||||
var design = _converter.Convert(ToDesignData(), applyGear, applyCustomize, 0, 0);
|
||||
_state.ApplyDesign(design, state, StateChanged.Source.Manual);
|
||||
_state.ApplyDesign(design, state, StateSource.Manual);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using Glamourer.Designs;
|
||||
using Glamourer.Events;
|
||||
using Glamourer.State;
|
||||
using Penumbra.GameData.Enums;
|
||||
|
||||
|
|
@ -23,32 +22,17 @@ public ref struct ToggleDrawData
|
|||
{ }
|
||||
|
||||
public static ToggleDrawData FromDesign(MetaIndex index, DesignManager manager, Design design)
|
||||
=> new()
|
||||
{
|
||||
var (label, value, apply, setValue, setApply) = index switch
|
||||
{
|
||||
MetaIndex.HatState => ("Hat Visible", design.DesignData.IsHatVisible(), design.DoApplyHatVisible(),
|
||||
(Action<bool>)(b => manager.ChangeMeta(design, index, b)), (Action<bool>)(b => manager.ChangeApplyMeta(design, index, b))),
|
||||
MetaIndex.VisorState => ("Visor Toggled", design.DesignData.IsVisorToggled(), design.DoApplyVisorToggle(),
|
||||
b => manager.ChangeMeta(design, index, b), b => manager.ChangeApplyMeta(design, index, b)),
|
||||
MetaIndex.WeaponState => ("Weapon Visible", design.DesignData.IsWeaponVisible(), design.DoApplyWeaponVisible(),
|
||||
b => manager.ChangeMeta(design, index, b), b => manager.ChangeApplyMeta(design, index, b)),
|
||||
MetaIndex.Wetness => ("Force Wetness", design.DesignData.IsWet(), design.DoApplyWetness(),
|
||||
b => manager.ChangeMeta(design, index, b), b => manager.ChangeApplyMeta(design, index, b)),
|
||||
_ => throw new Exception("Unsupported meta index."),
|
||||
};
|
||||
|
||||
return new ToggleDrawData
|
||||
{
|
||||
Label = label,
|
||||
Label = index.ToName(),
|
||||
Tooltip = string.Empty,
|
||||
Locked = design.WriteProtected(),
|
||||
DisplayApplication = true,
|
||||
CurrentValue = value,
|
||||
CurrentApply = apply,
|
||||
SetValue = setValue,
|
||||
SetApply = setApply,
|
||||
CurrentValue = design.DesignData.GetMeta(index),
|
||||
CurrentApply = design.DoApplyMeta(index),
|
||||
SetValue = b => manager.ChangeMeta(design, index, b),
|
||||
SetApply = b => manager.ChangeApplyMeta(design, index, b),
|
||||
};
|
||||
}
|
||||
|
||||
public static ToggleDrawData CrestFromDesign(CrestFlag slot, DesignManager manager, Design design)
|
||||
=> new()
|
||||
|
|
@ -70,52 +54,27 @@ public ref struct ToggleDrawData
|
|||
Tooltip = "Hide or show your free company crest on this piece of gear.",
|
||||
Locked = state.IsLocked,
|
||||
CurrentValue = state.ModelData.Crest(slot),
|
||||
SetValue = v => manager.ChangeCrest(state, slot, v, StateChanged.Source.Manual),
|
||||
SetValue = v => manager.ChangeCrest(state, slot, v, StateSource.Manual),
|
||||
};
|
||||
|
||||
public static ToggleDrawData FromState(MetaIndex index, StateManager manager, ActorState state)
|
||||
{
|
||||
var (label, tooltip, value, setValue) = index switch
|
||||
{
|
||||
MetaIndex.HatState => ("Hat Visible", "Hide or show the characters head gear.", state.ModelData.IsHatVisible(),
|
||||
(Action<bool>)(b => manager.ChangeHatState(state, b, StateChanged.Source.Manual))),
|
||||
MetaIndex.VisorState => ("Visor Toggled", "Toggle the visor state of the characters head gear.",
|
||||
state.ModelData.IsVisorToggled(),
|
||||
b => manager.ChangeVisorState(state, b, StateChanged.Source.Manual)),
|
||||
MetaIndex.WeaponState => ("Weapon Visible", "Hide or show the characters weapons when not drawn.",
|
||||
state.ModelData.IsWeaponVisible(),
|
||||
b => manager.ChangeWeaponState(state, b, StateChanged.Source.Manual)),
|
||||
MetaIndex.Wetness => ("Force Wetness", "Force the character to be wet or not.", state.ModelData.IsWet(),
|
||||
b => manager.ChangeWetness(state, b, StateChanged.Source.Manual)),
|
||||
_ => throw new Exception("Unsupported meta index."),
|
||||
};
|
||||
|
||||
return new ToggleDrawData
|
||||
{
|
||||
Label = label,
|
||||
Tooltip = tooltip,
|
||||
Label = index.ToName(),
|
||||
Tooltip = index.ToTooltip(),
|
||||
Locked = state.IsLocked,
|
||||
CurrentValue = value,
|
||||
SetValue = setValue,
|
||||
CurrentValue = state.ModelData.GetMeta(index),
|
||||
SetValue = b => manager.ChangeMeta(state, index, b, StateSource.Manual),
|
||||
};
|
||||
}
|
||||
|
||||
public static ToggleDrawData FromValue(MetaIndex index, bool value)
|
||||
=> new()
|
||||
{
|
||||
var (label, tooltip) = index switch
|
||||
{
|
||||
MetaIndex.HatState => ("Hat Visible", "Hide or show the characters head gear."),
|
||||
MetaIndex.VisorState => ("Visor Toggled", "Toggle the visor state of the characters head gear."),
|
||||
MetaIndex.WeaponState => ("Weapon Visible", "Hide or show the characters weapons when not drawn."),
|
||||
MetaIndex.Wetness => ("Force Wetness", "Force the character to be wet or not."),
|
||||
_ => throw new Exception("Unsupported meta index."),
|
||||
};
|
||||
return new ToggleDrawData
|
||||
{
|
||||
Label = label,
|
||||
Tooltip = tooltip,
|
||||
Label = index.ToName(),
|
||||
Tooltip = index.ToTooltip(),
|
||||
Locked = true,
|
||||
CurrentValue = value,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,14 +118,14 @@ public class ContextMenuService : IDisposable
|
|||
return;
|
||||
|
||||
var slot = item.Type.ToSlot();
|
||||
_state.ChangeEquip(state, slot, item, 0, StateChanged.Source.Manual);
|
||||
_state.ChangeEquip(state, slot, item, 0, StateSource.Manual);
|
||||
if (item.Type.ValidOffhand().IsOffhandType())
|
||||
{
|
||||
if (item.PrimaryId.Id is > 1600 and < 1651
|
||||
&& _items.ItemData.TryGetValue(item.ItemId, EquipSlot.Hands, out var gauntlets))
|
||||
_state.ChangeEquip(state, EquipSlot.Hands, gauntlets, 0, StateChanged.Source.Manual);
|
||||
_state.ChangeEquip(state, EquipSlot.Hands, gauntlets, 0, StateSource.Manual);
|
||||
if (_items.ItemData.TryGetValue(item.ItemId, EquipSlot.OffHand, out var offhand))
|
||||
_state.ChangeEquip(state, EquipSlot.OffHand, offhand, 0, StateChanged.Source.Manual);
|
||||
_state.ChangeEquip(state, EquipSlot.OffHand, offhand, 0, StateSource.Manual);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -142,14 +142,14 @@ public class ContextMenuService : IDisposable
|
|||
return;
|
||||
|
||||
var slot = item.Type.ToSlot();
|
||||
_state.ChangeEquip(state, slot, item, 0, StateChanged.Source.Manual);
|
||||
_state.ChangeEquip(state, slot, item, 0, StateSource.Manual);
|
||||
if (item.Type.ValidOffhand().IsOffhandType())
|
||||
{
|
||||
if (item.PrimaryId.Id is > 1600 and < 1651
|
||||
&& _items.ItemData.TryGetValue(item.ItemId, EquipSlot.Hands, out var gauntlets))
|
||||
_state.ChangeEquip(state, EquipSlot.Hands, gauntlets, 0, StateChanged.Source.Manual);
|
||||
_state.ChangeEquip(state, EquipSlot.Hands, gauntlets, 0, StateSource.Manual);
|
||||
if (_items.ItemData.TryGetValue(item.ItemId, EquipSlot.OffHand, out var offhand))
|
||||
_state.ChangeEquip(state, EquipSlot.OffHand, offhand, 0, StateChanged.Source.Manual);
|
||||
_state.ChangeEquip(state, EquipSlot.OffHand, offhand, 0, StateSource.Manual);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -333,7 +333,7 @@ public class CommandService : IDisposable
|
|||
foreach (var identifier in identifiers)
|
||||
{
|
||||
if (_stateManager.TryGetValue(identifier, out var state))
|
||||
_stateManager.ResetState(state, StateChanged.Source.Manual);
|
||||
_stateManager.ResetState(state, StateSource.Manual);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -419,7 +419,7 @@ public class CommandService : IDisposable
|
|||
if (!_objects.TryGetValue(identifier, out var actors))
|
||||
{
|
||||
if (_stateManager.TryGetValue(identifier, out var state))
|
||||
_stateManager.ApplyDesign(design, state, StateChanged.Source.Manual);
|
||||
_stateManager.ApplyDesign(design, state, StateSource.Manual);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -428,7 +428,7 @@ public class CommandService : IDisposable
|
|||
if (_stateManager.GetOrCreate(actor.GetIdentifier(_actors), actor, out var state))
|
||||
{
|
||||
ApplyModSettings(design, actor, applyMods);
|
||||
_stateManager.ApplyDesign(design, state, StateChanged.Source.Manual);
|
||||
_stateManager.ApplyDesign(design, state, StateSource.Manual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,13 +68,13 @@ public class ActorState
|
|||
=> Unlock(1337);
|
||||
|
||||
/// <summary> This contains whether a change to the base data was made by the game, the user via manual input or through automatic application. </summary>
|
||||
public readonly StateSource Source = new();
|
||||
public StateSources Sources = new();
|
||||
|
||||
internal ActorState(ActorIdentifier identifier)
|
||||
=> Identifier = identifier.CreatePermanent();
|
||||
|
||||
public CustomizeParameterFlag OnlyChangedParameters()
|
||||
=> CustomizeParameterExtensions.AllFlags.Where(f => Source[f] is not StateChanged.Source.Game)
|
||||
=> CustomizeParameterExtensions.AllFlags.Where(f => Sources[f] is not StateSource.Game)
|
||||
.Aggregate((CustomizeParameterFlag)0, (a, b) => a | b);
|
||||
|
||||
public bool UpdateTerritory(ushort territory)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using Glamourer.Events;
|
||||
using Glamourer.Designs;
|
||||
using Glamourer.Events;
|
||||
using Glamourer.GameData;
|
||||
using Glamourer.Interop;
|
||||
using Glamourer.Interop.Penumbra;
|
||||
|
|
@ -118,7 +119,7 @@ public class StateApplier(
|
|||
// If the source is not IPC we do not want to apply restrictions.
|
||||
var data = GetData(state);
|
||||
if (apply)
|
||||
ChangeArmor(data, slot, state.ModelData.Armor(slot), state.Source[slot, false] is not StateChanged.Source.Ipc,
|
||||
ChangeArmor(data, slot, state.ModelData.Armor(slot), state.Sources[slot, false] is not StateSource.Ipc,
|
||||
state.ModelData.IsHatVisible());
|
||||
|
||||
return data;
|
||||
|
|
@ -200,67 +201,44 @@ public class StateApplier(
|
|||
_weapon.LoadWeapon(actor, EquipSlot.OffHand, weapon.Weapon().With(stain));
|
||||
}
|
||||
|
||||
/// <summary> Change the visor state of actors only on the draw object. </summary>
|
||||
public void ChangeVisor(ActorData data, bool value)
|
||||
/// <summary> Change a meta state. </summary>
|
||||
public unsafe void ChangeMetaState(ActorData data, MetaIndex index, bool value)
|
||||
{
|
||||
foreach (var actor in data.Objects.Where(a => a.Model.IsHuman))
|
||||
_visor.SetVisorState(actor.Model, value);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ChangeVisor(ActorData, bool)"/>
|
||||
public ActorData ChangeVisor(ActorState state, bool apply)
|
||||
switch (index)
|
||||
{
|
||||
var data = GetData(state);
|
||||
if (apply)
|
||||
ChangeVisor(data, state.ModelData.IsVisorToggled());
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary> Change the forced wetness state on actors. </summary>
|
||||
public unsafe void ChangeWetness(ActorData data, bool value)
|
||||
case MetaIndex.Wetness:
|
||||
{
|
||||
foreach (var actor in data.Objects.Where(a => a.IsCharacter))
|
||||
actor.AsCharacter->IsGPoseWet = value;
|
||||
return;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ChangeWetness(ActorData, bool)"/>
|
||||
public ActorData ChangeWetness(ActorState state, bool apply)
|
||||
{
|
||||
var data = GetData(state);
|
||||
if (apply)
|
||||
ChangeWetness(data, state.ModelData.IsWet());
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary> Change the hat-visibility state on actors. </summary>
|
||||
public void ChangeHatState(ActorData data, bool value)
|
||||
case MetaIndex.HatState:
|
||||
{
|
||||
foreach (var actor in data.Objects.Where(a => a.IsCharacter))
|
||||
_metaService.SetHatState(actor, value);
|
||||
return;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ChangeHatState(ActorData, bool)"/>
|
||||
public ActorData ChangeHatState(ActorState state, bool apply)
|
||||
{
|
||||
var data = GetData(state);
|
||||
if (apply)
|
||||
ChangeHatState(data, state.ModelData.IsHatVisible());
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary> Change the weapon-visibility state on actors. </summary>
|
||||
public void ChangeWeaponState(ActorData data, bool value)
|
||||
case MetaIndex.WeaponState:
|
||||
{
|
||||
foreach (var actor in data.Objects.Where(a => a.IsCharacter))
|
||||
_metaService.SetWeaponState(actor, value);
|
||||
return;
|
||||
}
|
||||
case MetaIndex.VisorState:
|
||||
{
|
||||
foreach (var actor in data.Objects.Where(a => a.Model.IsHuman))
|
||||
_visor.SetVisorState(actor.Model, value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ChangeWeaponState(ActorData, bool)"/>
|
||||
public ActorData ChangeWeaponState(ActorState state, bool apply)
|
||||
/// <inheritdoc cref="ChangeMetaState(ActorData, MetaIndex, bool)"/>
|
||||
public ActorData ChangeMetaState(ActorState state, MetaIndex index, bool apply)
|
||||
{
|
||||
var data = GetData(state);
|
||||
if (apply)
|
||||
ChangeWeaponState(data, state.ModelData.IsWeaponVisible());
|
||||
ChangeMetaState(data, index, state.ModelData.GetMeta(index));
|
||||
return data;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ public class StateEditor(CustomizeService customizations, HumanModelList humans,
|
|||
{
|
||||
/// <summary> Change the model id. If the actor is changed from a human to another human, customize and equipData are unused. </summary>
|
||||
/// <remarks> We currently only allow changing things to humans, not humans to monsters. </remarks>
|
||||
public bool ChangeModelId(ActorState state, uint modelId, in CustomizeArray customize, nint equipData, StateChanged.Source source,
|
||||
public bool ChangeModelId(ActorState state, uint modelId, in CustomizeArray customize, nint equipData, StateSource source,
|
||||
out uint oldModelId, uint key = 0)
|
||||
{
|
||||
oldModelId = state.ModelData.ModelId;
|
||||
|
|
@ -45,21 +45,21 @@ public class StateEditor(CustomizeService customizations, HumanModelList humans,
|
|||
state.ModelData.SetHatVisible(true);
|
||||
state.ModelData.SetWeaponVisible(true);
|
||||
state.ModelData.SetVisor(false);
|
||||
state.Source[MetaIndex.ModelId] = source;
|
||||
state.Source[MetaIndex.HatState] = source;
|
||||
state.Source[MetaIndex.WeaponState] = source;
|
||||
state.Source[MetaIndex.VisorState] = source;
|
||||
state.Sources[MetaIndex.ModelId] = source;
|
||||
state.Sources[MetaIndex.HatState] = source;
|
||||
state.Sources[MetaIndex.WeaponState] = source;
|
||||
state.Sources[MetaIndex.VisorState] = source;
|
||||
foreach (var slot in EquipSlotExtensions.FullSlots)
|
||||
{
|
||||
state.Source[slot, true] = source;
|
||||
state.Source[slot, false] = source;
|
||||
state.Sources[slot, true] = source;
|
||||
state.Sources[slot, false] = source;
|
||||
}
|
||||
|
||||
state.Source[CustomizeIndex.Clan] = source;
|
||||
state.Source[CustomizeIndex.Gender] = source;
|
||||
state.Sources[CustomizeIndex.Clan] = source;
|
||||
state.Sources[CustomizeIndex.Gender] = source;
|
||||
var set = customizations.Manager.GetSet(state.ModelData.Customize.Clan, state.ModelData.Customize.Gender);
|
||||
foreach (var index in Enum.GetValues<CustomizeIndex>().Where(set.IsAvailable))
|
||||
state.Source[index] = source;
|
||||
state.Sources[index] = source;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -67,14 +67,14 @@ public class StateEditor(CustomizeService customizations, HumanModelList humans,
|
|||
return false;
|
||||
|
||||
state.ModelData.LoadNonHuman(modelId, customize, equipData);
|
||||
state.Source[MetaIndex.ModelId] = source;
|
||||
state.Sources[MetaIndex.ModelId] = source;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary> Change a customization value. </summary>
|
||||
public bool ChangeCustomize(ActorState state, CustomizeIndex idx, CustomizeValue value, StateChanged.Source source,
|
||||
public bool ChangeCustomize(ActorState state, CustomizeIndex idx, CustomizeValue value, StateSource source,
|
||||
out CustomizeValue old, uint key = 0)
|
||||
{
|
||||
old = state.ModelData.Customize[idx];
|
||||
|
|
@ -82,12 +82,12 @@ public class StateEditor(CustomizeService customizations, HumanModelList humans,
|
|||
return false;
|
||||
|
||||
state.ModelData.Customize[idx] = value;
|
||||
state.Source[idx] = source;
|
||||
state.Sources[idx] = source;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary> Change an entire customization array according to flags. </summary>
|
||||
public bool ChangeHumanCustomize(ActorState state, in CustomizeArray customizeInput, CustomizeFlag applyWhich, StateChanged.Source source,
|
||||
public bool ChangeHumanCustomize(ActorState state, in CustomizeArray customizeInput, CustomizeFlag applyWhich, StateSource source,
|
||||
out CustomizeArray old, out CustomizeFlag changed, uint key = 0)
|
||||
{
|
||||
old = state.ModelData.Customize;
|
||||
|
|
@ -104,14 +104,14 @@ public class StateEditor(CustomizeService customizations, HumanModelList humans,
|
|||
foreach (var type in Enum.GetValues<CustomizeIndex>())
|
||||
{
|
||||
if (applied.HasFlag(type.ToFlag()))
|
||||
state.Source[type] = source;
|
||||
state.Sources[type] = source;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary> Change a single piece of equipment without stain. </summary>
|
||||
public bool ChangeItem(ActorState state, EquipSlot slot, EquipItem item, StateChanged.Source source, out EquipItem oldItem, uint key = 0)
|
||||
public bool ChangeItem(ActorState state, EquipSlot slot, EquipItem item, StateSource source, out EquipItem oldItem, uint key = 0)
|
||||
{
|
||||
oldItem = state.ModelData.Item(slot);
|
||||
if (!state.CanUnlock(key))
|
||||
|
|
@ -128,17 +128,17 @@ public class StateEditor(CustomizeService customizations, HumanModelList humans,
|
|||
gPose.AddActionOnLeave(() =>
|
||||
{
|
||||
if (old.Type == state.BaseData.Item(slot).Type)
|
||||
ChangeItem(state, slot, old, state.Source[slot, false], out _, key);
|
||||
ChangeItem(state, slot, old, state.Sources[slot, false], out _, key);
|
||||
});
|
||||
}
|
||||
|
||||
state.ModelData.SetItem(slot, item);
|
||||
state.Source[slot, false] = source;
|
||||
state.Sources[slot, false] = source;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary> Change a single piece of equipment including stain. </summary>
|
||||
public bool ChangeEquip(ActorState state, EquipSlot slot, EquipItem item, StainId stain, StateChanged.Source source, out EquipItem oldItem,
|
||||
public bool ChangeEquip(ActorState state, EquipSlot slot, EquipItem item, StainId stain, StateSource source, out EquipItem oldItem,
|
||||
out StainId oldStain, uint key = 0)
|
||||
{
|
||||
oldItem = state.ModelData.Item(slot);
|
||||
|
|
@ -158,43 +158,43 @@ public class StateEditor(CustomizeService customizations, HumanModelList humans,
|
|||
gPose.AddActionOnLeave(() =>
|
||||
{
|
||||
if (old.Type == state.BaseData.Item(slot).Type)
|
||||
ChangeEquip(state, slot, old, oldS, state.Source[slot, false], out _, out _, key);
|
||||
ChangeEquip(state, slot, old, oldS, state.Sources[slot, false], out _, out _, key);
|
||||
});
|
||||
}
|
||||
|
||||
state.ModelData.SetItem(slot, item);
|
||||
state.ModelData.SetStain(slot, stain);
|
||||
state.Source[slot, false] = source;
|
||||
state.Source[slot, true] = source;
|
||||
state.Sources[slot, false] = source;
|
||||
state.Sources[slot, true] = source;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary> Change only the stain of an equipment piece. </summary>
|
||||
public bool ChangeStain(ActorState state, EquipSlot slot, StainId stain, StateChanged.Source source, out StainId oldStain, uint key = 0)
|
||||
public bool ChangeStain(ActorState state, EquipSlot slot, StainId stain, StateSource source, out StainId oldStain, uint key = 0)
|
||||
{
|
||||
oldStain = state.ModelData.Stain(slot);
|
||||
if (!state.CanUnlock(key))
|
||||
return false;
|
||||
|
||||
state.ModelData.SetStain(slot, stain);
|
||||
state.Source[slot, true] = source;
|
||||
state.Sources[slot, true] = source;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary> Change the crest of an equipment piece. </summary>
|
||||
public bool ChangeCrest(ActorState state, CrestFlag slot, bool crest, StateChanged.Source source, out bool oldCrest, uint key = 0)
|
||||
public bool ChangeCrest(ActorState state, CrestFlag slot, bool crest, StateSource source, out bool oldCrest, uint key = 0)
|
||||
{
|
||||
oldCrest = state.ModelData.Crest(slot);
|
||||
if (!state.CanUnlock(key))
|
||||
return false;
|
||||
|
||||
state.ModelData.SetCrest(slot, crest);
|
||||
state.Source[slot] = source;
|
||||
state.Sources[slot] = source;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary> Change the customize flags of a character. </summary>
|
||||
public bool ChangeParameter(ActorState state, CustomizeParameterFlag flag, CustomizeParameterValue value, StateChanged.Source source,
|
||||
public bool ChangeParameter(ActorState state, CustomizeParameterFlag flag, CustomizeParameterValue value, StateSource source,
|
||||
out CustomizeParameterValue oldValue, uint key = 0)
|
||||
{
|
||||
oldValue = state.ModelData.Parameters[flag];
|
||||
|
|
@ -202,29 +202,20 @@ public class StateEditor(CustomizeService customizations, HumanModelList humans,
|
|||
return false;
|
||||
|
||||
state.ModelData.Parameters.Set(flag, value);
|
||||
state.Source[flag] = source;
|
||||
state.Sources[flag] = source;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool ChangeMetaState(ActorState state, MetaIndex index, bool value, StateChanged.Source source, out bool oldValue,
|
||||
public bool ChangeMetaState(ActorState state, MetaIndex index, bool value, StateSource source, out bool oldValue,
|
||||
uint key = 0)
|
||||
{
|
||||
(var setter, oldValue) = index switch
|
||||
{
|
||||
MetaIndex.Wetness => ((Func<bool, bool>)(v => state.ModelData.SetIsWet(v)), state.ModelData.IsWet()),
|
||||
MetaIndex.HatState => ((Func<bool, bool>)(v => state.ModelData.SetHatVisible(v)), state.ModelData.IsHatVisible()),
|
||||
MetaIndex.VisorState => ((Func<bool, bool>)(v => state.ModelData.SetVisor(v)), state.ModelData.IsVisorToggled()),
|
||||
MetaIndex.WeaponState => ((Func<bool, bool>)(v => state.ModelData.SetWeaponVisible(v)),
|
||||
state.ModelData.IsWeaponVisible()),
|
||||
_ => throw new Exception("Invalid MetaIndex."),
|
||||
};
|
||||
|
||||
oldValue = state.ModelData.GetMeta(index);
|
||||
if (!state.CanUnlock(key))
|
||||
return false;
|
||||
|
||||
setter(value);
|
||||
state.Source[index] = source;
|
||||
state.ModelData.SetMeta(index, value);
|
||||
state.Sources[index] = source;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
235
Glamourer/State/StateIndex.cs
Normal file
235
Glamourer/State/StateIndex.cs
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
using Glamourer.Designs;
|
||||
using Glamourer.GameData;
|
||||
using Penumbra.GameData.Enums;
|
||||
|
||||
namespace Glamourer.State;
|
||||
|
||||
public readonly record struct StateIndex(int Value) : IEqualityOperators<StateIndex, StateIndex, bool>
|
||||
{
|
||||
public static readonly StateIndex Invalid = new(-1);
|
||||
|
||||
public static implicit operator StateIndex(EquipFlag flag)
|
||||
=> flag switch
|
||||
{
|
||||
EquipFlag.Head => new StateIndex(EquipHead),
|
||||
EquipFlag.Body => new StateIndex(EquipBody),
|
||||
EquipFlag.Hands => new StateIndex(EquipHands),
|
||||
EquipFlag.Legs => new StateIndex(EquipLegs),
|
||||
EquipFlag.Feet => new StateIndex(EquipFeet),
|
||||
EquipFlag.Ears => new StateIndex(EquipEars),
|
||||
EquipFlag.Neck => new StateIndex(EquipNeck),
|
||||
EquipFlag.Wrist => new StateIndex(EquipWrist),
|
||||
EquipFlag.RFinger => new StateIndex(EquipRFinger),
|
||||
EquipFlag.LFinger => new StateIndex(EquipLFinger),
|
||||
EquipFlag.Mainhand => new StateIndex(EquipMainhand),
|
||||
EquipFlag.Offhand => new StateIndex(EquipOffhand),
|
||||
EquipFlag.HeadStain => new StateIndex(StainHead),
|
||||
EquipFlag.BodyStain => new StateIndex(StainBody),
|
||||
EquipFlag.HandsStain => new StateIndex(StainHands),
|
||||
EquipFlag.LegsStain => new StateIndex(StainLegs),
|
||||
EquipFlag.FeetStain => new StateIndex(StainFeet),
|
||||
EquipFlag.EarsStain => new StateIndex(StainEars),
|
||||
EquipFlag.NeckStain => new StateIndex(StainNeck),
|
||||
EquipFlag.WristStain => new StateIndex(StainWrist),
|
||||
EquipFlag.RFingerStain => new StateIndex(StainRFinger),
|
||||
EquipFlag.LFingerStain => new StateIndex(StainLFinger),
|
||||
EquipFlag.MainhandStain => new StateIndex(StainMainhand),
|
||||
EquipFlag.OffhandStain => new StateIndex(StainOffhand),
|
||||
_ => Invalid,
|
||||
};
|
||||
|
||||
public static implicit operator StateIndex(CustomizeIndex index)
|
||||
=> index switch
|
||||
{
|
||||
CustomizeIndex.Race => new StateIndex(CustomizeRace),
|
||||
CustomizeIndex.Gender => new StateIndex(CustomizeGender),
|
||||
CustomizeIndex.BodyType => new StateIndex(CustomizeBodyType),
|
||||
CustomizeIndex.Height => new StateIndex(CustomizeHeight),
|
||||
CustomizeIndex.Clan => new StateIndex(CustomizeClan),
|
||||
CustomizeIndex.Face => new StateIndex(CustomizeFace),
|
||||
CustomizeIndex.Hairstyle => new StateIndex(CustomizeHairstyle),
|
||||
CustomizeIndex.Highlights => new StateIndex(CustomizeHighlights),
|
||||
CustomizeIndex.SkinColor => new StateIndex(CustomizeSkinColor),
|
||||
CustomizeIndex.EyeColorRight => new StateIndex(CustomizeEyeColorRight),
|
||||
CustomizeIndex.HairColor => new StateIndex(CustomizeHairColor),
|
||||
CustomizeIndex.HighlightsColor => new StateIndex(CustomizeHighlightsColor),
|
||||
CustomizeIndex.FacialFeature1 => new StateIndex(CustomizeFacialFeature1),
|
||||
CustomizeIndex.FacialFeature2 => new StateIndex(CustomizeFacialFeature2),
|
||||
CustomizeIndex.FacialFeature3 => new StateIndex(CustomizeFacialFeature3),
|
||||
CustomizeIndex.FacialFeature4 => new StateIndex(CustomizeFacialFeature4),
|
||||
CustomizeIndex.FacialFeature5 => new StateIndex(CustomizeFacialFeature5),
|
||||
CustomizeIndex.FacialFeature6 => new StateIndex(CustomizeFacialFeature6),
|
||||
CustomizeIndex.FacialFeature7 => new StateIndex(CustomizeFacialFeature7),
|
||||
CustomizeIndex.LegacyTattoo => new StateIndex(CustomizeLegacyTattoo),
|
||||
CustomizeIndex.TattooColor => new StateIndex(CustomizeTattooColor),
|
||||
CustomizeIndex.Eyebrows => new StateIndex(CustomizeEyebrows),
|
||||
CustomizeIndex.EyeColorLeft => new StateIndex(CustomizeEyeColorLeft),
|
||||
CustomizeIndex.EyeShape => new StateIndex(CustomizeEyeShape),
|
||||
CustomizeIndex.SmallIris => new StateIndex(CustomizeSmallIris),
|
||||
CustomizeIndex.Nose => new StateIndex(CustomizeNose),
|
||||
CustomizeIndex.Jaw => new StateIndex(CustomizeJaw),
|
||||
CustomizeIndex.Mouth => new StateIndex(CustomizeMouth),
|
||||
CustomizeIndex.Lipstick => new StateIndex(CustomizeLipstick),
|
||||
CustomizeIndex.LipColor => new StateIndex(CustomizeLipColor),
|
||||
CustomizeIndex.MuscleMass => new StateIndex(CustomizeMuscleMass),
|
||||
CustomizeIndex.TailShape => new StateIndex(CustomizeTailShape),
|
||||
CustomizeIndex.BustSize => new StateIndex(CustomizeBustSize),
|
||||
CustomizeIndex.FacePaint => new StateIndex(CustomizeFacePaint),
|
||||
CustomizeIndex.FacePaintReversed => new StateIndex(CustomizeFacePaintReversed),
|
||||
CustomizeIndex.FacePaintColor => new StateIndex(CustomizeFacePaintColor),
|
||||
_ => Invalid,
|
||||
};
|
||||
|
||||
public static implicit operator StateIndex(MetaIndex meta)
|
||||
=> new((int)meta);
|
||||
|
||||
public static implicit operator StateIndex(CrestFlag crest)
|
||||
=> crest switch
|
||||
{
|
||||
CrestFlag.OffHand => new StateIndex(CrestOffhand),
|
||||
CrestFlag.Head => new StateIndex(CrestHead),
|
||||
CrestFlag.Body => new StateIndex(CrestBody),
|
||||
_ => Invalid,
|
||||
};
|
||||
|
||||
public static implicit operator StateIndex(CustomizeParameterFlag param)
|
||||
=> param switch
|
||||
{
|
||||
CustomizeParameterFlag.SkinDiffuse => new StateIndex(ParamSkinDiffuse),
|
||||
CustomizeParameterFlag.MuscleTone => new StateIndex(ParamMuscleTone),
|
||||
CustomizeParameterFlag.SkinSpecular => new StateIndex(ParamSkinSpecular),
|
||||
CustomizeParameterFlag.LipDiffuse => new StateIndex(ParamLipDiffuse),
|
||||
CustomizeParameterFlag.HairDiffuse => new StateIndex(ParamHairDiffuse),
|
||||
CustomizeParameterFlag.HairSpecular => new StateIndex(ParamHairSpecular),
|
||||
CustomizeParameterFlag.HairHighlight => new StateIndex(ParamHairHighlight),
|
||||
CustomizeParameterFlag.LeftEye => new StateIndex(ParamLeftEye),
|
||||
CustomizeParameterFlag.RightEye => new StateIndex(ParamRightEye),
|
||||
CustomizeParameterFlag.FeatureColor => new StateIndex(ParamFeatureColor),
|
||||
CustomizeParameterFlag.FacePaintUvMultiplier => new StateIndex(ParamFacePaintUvMultiplier),
|
||||
CustomizeParameterFlag.FacePaintUvOffset => new StateIndex(ParamFacePaintUvOffset),
|
||||
CustomizeParameterFlag.DecalColor => new StateIndex(ParamDecalColor),
|
||||
_ => Invalid,
|
||||
};
|
||||
|
||||
public const int EquipHead = 0;
|
||||
public const int EquipBody = 1;
|
||||
public const int EquipHands = 2;
|
||||
public const int EquipLegs = 3;
|
||||
public const int EquipFeet = 4;
|
||||
public const int EquipEars = 5;
|
||||
public const int EquipNeck = 6;
|
||||
public const int EquipWrist = 7;
|
||||
public const int EquipRFinger = 8;
|
||||
public const int EquipLFinger = 9;
|
||||
public const int EquipMainhand = 10;
|
||||
public const int EquipOffhand = 11;
|
||||
|
||||
public const int StainHead = 12;
|
||||
public const int StainBody = 13;
|
||||
public const int StainHands = 14;
|
||||
public const int StainLegs = 15;
|
||||
public const int StainFeet = 16;
|
||||
public const int StainEars = 17;
|
||||
public const int StainNeck = 18;
|
||||
public const int StainWrist = 19;
|
||||
public const int StainRFinger = 20;
|
||||
public const int StainLFinger = 21;
|
||||
public const int StainMainhand = 22;
|
||||
public const int StainOffhand = 23;
|
||||
|
||||
public const int CustomizeRace = 24;
|
||||
public const int CustomizeGender = 25;
|
||||
public const int CustomizeBodyType = 26;
|
||||
public const int CustomizeHeight = 27;
|
||||
public const int CustomizeClan = 28;
|
||||
public const int CustomizeFace = 29;
|
||||
public const int CustomizeHairstyle = 30;
|
||||
public const int CustomizeHighlights = 31;
|
||||
public const int CustomizeSkinColor = 32;
|
||||
public const int CustomizeEyeColorRight = 33;
|
||||
public const int CustomizeHairColor = 34;
|
||||
public const int CustomizeHighlightsColor = 35;
|
||||
public const int CustomizeFacialFeature1 = 36;
|
||||
public const int CustomizeFacialFeature2 = 37;
|
||||
public const int CustomizeFacialFeature3 = 38;
|
||||
public const int CustomizeFacialFeature4 = 39;
|
||||
public const int CustomizeFacialFeature5 = 40;
|
||||
public const int CustomizeFacialFeature6 = 41;
|
||||
public const int CustomizeFacialFeature7 = 42;
|
||||
public const int CustomizeLegacyTattoo = 43;
|
||||
public const int CustomizeTattooColor = 44;
|
||||
public const int CustomizeEyebrows = 45;
|
||||
public const int CustomizeEyeColorLeft = 46;
|
||||
public const int CustomizeEyeShape = 47;
|
||||
public const int CustomizeSmallIris = 48;
|
||||
public const int CustomizeNose = 49;
|
||||
public const int CustomizeJaw = 50;
|
||||
public const int CustomizeMouth = 51;
|
||||
public const int CustomizeLipstick = 52;
|
||||
public const int CustomizeLipColor = 53;
|
||||
public const int CustomizeMuscleMass = 54;
|
||||
public const int CustomizeTailShape = 55;
|
||||
public const int CustomizeBustSize = 56;
|
||||
public const int CustomizeFacePaint = 57;
|
||||
public const int CustomizeFacePaintReversed = 58;
|
||||
public const int CustomizeFacePaintColor = 59;
|
||||
|
||||
public const int MetaWetness = 60;
|
||||
public const int MetaHatState = 61;
|
||||
public const int MetaVisorState = 62;
|
||||
public const int MetaWeaponState = 63;
|
||||
public const int MetaModelId = 64;
|
||||
|
||||
public const int CrestHead = 65;
|
||||
public const int CrestBody = 66;
|
||||
public const int CrestOffhand = 67;
|
||||
|
||||
public const int ParamSkinDiffuse = 68;
|
||||
public const int ParamMuscleTone = 69;
|
||||
public const int ParamSkinSpecular = 70;
|
||||
public const int ParamLipDiffuse = 71;
|
||||
public const int ParamHairDiffuse = 72;
|
||||
public const int ParamHairSpecular = 73;
|
||||
public const int ParamHairHighlight = 74;
|
||||
public const int ParamLeftEye = 75;
|
||||
public const int ParamRightEye = 76;
|
||||
public const int ParamFeatureColor = 77;
|
||||
public const int ParamFacePaintUvMultiplier = 78;
|
||||
public const int ParamFacePaintUvOffset = 79;
|
||||
public const int ParamDecalColor = 80;
|
||||
|
||||
public const int Size = 81;
|
||||
}
|
||||
|
||||
public static class StateExtensions
|
||||
{
|
||||
public static StateIndex ToState(this EquipSlot slot, bool stain = false)
|
||||
=> (slot, stain) switch
|
||||
{
|
||||
(EquipSlot.Head, true) => new StateIndex(StateIndex.EquipHead),
|
||||
(EquipSlot.Body, true) => new StateIndex(StateIndex.EquipBody),
|
||||
(EquipSlot.Hands, true) => new StateIndex(StateIndex.EquipHands),
|
||||
(EquipSlot.Legs, true) => new StateIndex(StateIndex.EquipLegs),
|
||||
(EquipSlot.Feet, true) => new StateIndex(StateIndex.EquipFeet),
|
||||
(EquipSlot.Ears, true) => new StateIndex(StateIndex.EquipEars),
|
||||
(EquipSlot.Neck, true) => new StateIndex(StateIndex.EquipNeck),
|
||||
(EquipSlot.Wrists, true) => new StateIndex(StateIndex.EquipWrist),
|
||||
(EquipSlot.RFinger, true) => new StateIndex(StateIndex.EquipRFinger),
|
||||
(EquipSlot.LFinger, true) => new StateIndex(StateIndex.EquipLFinger),
|
||||
(EquipSlot.MainHand, true) => new StateIndex(StateIndex.EquipMainhand),
|
||||
(EquipSlot.OffHand, true) => new StateIndex(StateIndex.EquipOffhand),
|
||||
(EquipSlot.Head, false) => new StateIndex(StateIndex.StainHead),
|
||||
(EquipSlot.Body, false) => new StateIndex(StateIndex.StainBody),
|
||||
(EquipSlot.Hands, false) => new StateIndex(StateIndex.StainHands),
|
||||
(EquipSlot.Legs, false) => new StateIndex(StateIndex.StainLegs),
|
||||
(EquipSlot.Feet, false) => new StateIndex(StateIndex.StainFeet),
|
||||
(EquipSlot.Ears, false) => new StateIndex(StateIndex.StainEars),
|
||||
(EquipSlot.Neck, false) => new StateIndex(StateIndex.StainNeck),
|
||||
(EquipSlot.Wrists, false) => new StateIndex(StateIndex.StainWrist),
|
||||
(EquipSlot.RFinger, false) => new StateIndex(StateIndex.StainRFinger),
|
||||
(EquipSlot.LFinger, false) => new StateIndex(StateIndex.StainLFinger),
|
||||
(EquipSlot.MainHand, false) => new StateIndex(StateIndex.StainMainhand),
|
||||
(EquipSlot.OffHand, false) => new StateIndex(StateIndex.StainOffhand),
|
||||
_ => StateIndex.Invalid,
|
||||
};
|
||||
}
|
||||
|
|
@ -164,21 +164,21 @@ public class StateListener : IDisposable
|
|||
var model = state.ModelData.Customize;
|
||||
if (customize.Gender != model.Gender || customize.Clan != model.Clan)
|
||||
{
|
||||
_manager.ChangeCustomize(state, in customize, CustomizeFlagExtensions.AllRelevant, StateChanged.Source.Game);
|
||||
_manager.ChangeCustomize(state, in customize, CustomizeFlagExtensions.AllRelevant, StateSource.Game);
|
||||
return;
|
||||
}
|
||||
|
||||
var set = _customizations.Manager.GetSet(model.Clan, model.Gender);
|
||||
foreach (var index in CustomizationExtensions.AllBasic)
|
||||
{
|
||||
if (state.Source[index] is not StateChanged.Source.Fixed)
|
||||
if (state.Sources[index] is not StateSource.Fixed)
|
||||
{
|
||||
var newValue = customize[index];
|
||||
var oldValue = model[index];
|
||||
if (newValue != oldValue)
|
||||
{
|
||||
if (set.Validate(index, newValue, out _, model.Face))
|
||||
_manager.ChangeCustomize(state, index, newValue, StateChanged.Source.Game);
|
||||
_manager.ChangeCustomize(state, index, newValue, StateSource.Game);
|
||||
else
|
||||
customize[index] = oldValue;
|
||||
}
|
||||
|
|
@ -214,7 +214,7 @@ public class StateListener : IDisposable
|
|||
&& _manager.TryGetValue(identifier, out var state))
|
||||
{
|
||||
HandleEquipSlot(actor, state, slot, ref armor);
|
||||
locked = state.Source[slot, false] is StateChanged.Source.Ipc;
|
||||
locked = state.Sources[slot, false] is StateSource.Ipc;
|
||||
}
|
||||
|
||||
_funModule.ApplyFunToSlot(actor, ref armor, slot);
|
||||
|
|
@ -241,10 +241,10 @@ public class StateListener : IDisposable
|
|||
continue;
|
||||
|
||||
var changed = changedItem.Weapon(stain);
|
||||
if (current.Value == changed.Value && state.Source[slot, false] is not StateChanged.Source.Fixed and not StateChanged.Source.Ipc)
|
||||
if (current.Value == changed.Value && state.Sources[slot, false] is not StateSource.Fixed and not StateSource.Ipc)
|
||||
{
|
||||
_manager.ChangeItem(state, slot, currentItem, StateChanged.Source.Game);
|
||||
_manager.ChangeStain(state, slot, current.Stain, StateChanged.Source.Game);
|
||||
_manager.ChangeItem(state, slot, currentItem, StateSource.Game);
|
||||
_manager.ChangeStain(state, slot, current.Stain, StateSource.Game);
|
||||
switch (slot)
|
||||
{
|
||||
case EquipSlot.MainHand:
|
||||
|
|
@ -252,7 +252,7 @@ public class StateListener : IDisposable
|
|||
_applier.ChangeWeapon(objects, slot, currentItem, stain);
|
||||
break;
|
||||
default:
|
||||
_applier.ChangeArmor(objects, slot, current.ToArmor(), state.Source[slot, false] is not StateChanged.Source.Ipc,
|
||||
_applier.ChangeArmor(objects, slot, current.ToArmor(), state.Sources[slot, false] is not StateSource.Ipc,
|
||||
state.ModelData.IsHatVisible());
|
||||
break;
|
||||
}
|
||||
|
|
@ -286,13 +286,13 @@ public class StateListener : IDisposable
|
|||
// Do nothing. But this usually can not happen because the hooked function also writes to game objects later.
|
||||
case UpdateState.Transformed: break;
|
||||
case UpdateState.Change:
|
||||
if (state.Source[slot, false] is not StateChanged.Source.Fixed and not StateChanged.Source.Ipc)
|
||||
_manager.ChangeItem(state, slot, state.BaseData.Item(slot), StateChanged.Source.Game);
|
||||
if (state.Sources[slot, false] is not StateSource.Fixed and not StateSource.Ipc)
|
||||
_manager.ChangeItem(state, slot, state.BaseData.Item(slot), StateSource.Game);
|
||||
else
|
||||
apply = true;
|
||||
|
||||
if (state.Source[slot, true] is not StateChanged.Source.Fixed and not StateChanged.Source.Ipc)
|
||||
_manager.ChangeStain(state, slot, state.BaseData.Stain(slot), StateChanged.Source.Game);
|
||||
if (state.Sources[slot, true] is not StateSource.Fixed and not StateSource.Ipc)
|
||||
_manager.ChangeStain(state, slot, state.BaseData.Stain(slot), StateSource.Game);
|
||||
else
|
||||
apply = true;
|
||||
break;
|
||||
|
|
@ -385,13 +385,13 @@ public class StateListener : IDisposable
|
|||
// Update model state if not on fixed design.
|
||||
case UpdateState.Change:
|
||||
var apply = false;
|
||||
if (state.Source[slot, false] is not StateChanged.Source.Fixed and not StateChanged.Source.Ipc)
|
||||
_manager.ChangeItem(state, slot, state.BaseData.Item(slot), StateChanged.Source.Game);
|
||||
if (state.Sources[slot, false] is not StateSource.Fixed and not StateSource.Ipc)
|
||||
_manager.ChangeItem(state, slot, state.BaseData.Item(slot), StateSource.Game);
|
||||
else
|
||||
apply = true;
|
||||
|
||||
if (state.Source[slot, true] is not StateChanged.Source.Fixed and not StateChanged.Source.Ipc)
|
||||
_manager.ChangeStain(state, slot, state.BaseData.Stain(slot), StateChanged.Source.Game);
|
||||
if (state.Sources[slot, true] is not StateSource.Fixed and not StateSource.Ipc)
|
||||
_manager.ChangeStain(state, slot, state.BaseData.Stain(slot), StateSource.Game);
|
||||
else
|
||||
apply = true;
|
||||
|
||||
|
|
@ -419,8 +419,8 @@ public class StateListener : IDisposable
|
|||
switch (UpdateBaseCrest(actor, state, slot, value))
|
||||
{
|
||||
case UpdateState.Change:
|
||||
if (state.Source[slot] is not StateChanged.Source.Fixed and not StateChanged.Source.Ipc)
|
||||
_manager.ChangeCrest(state, slot, state.BaseData.Crest(slot), StateChanged.Source.Game);
|
||||
if (state.Sources[slot] is not StateSource.Fixed and not StateSource.Ipc)
|
||||
_manager.ChangeCrest(state, slot, state.BaseData.Crest(slot), StateSource.Game);
|
||||
else
|
||||
value = state.ModelData.Crest(slot);
|
||||
break;
|
||||
|
|
@ -565,10 +565,10 @@ public class StateListener : IDisposable
|
|||
{
|
||||
// if base state changed, either overwrite the actual value if we have fixed values,
|
||||
// or overwrite the stored model state with the new one.
|
||||
if (state.Source[MetaIndex.VisorState] is StateChanged.Source.Fixed or StateChanged.Source.Ipc)
|
||||
if (state.Sources[MetaIndex.VisorState] is StateSource.Fixed or StateSource.Ipc)
|
||||
value = state.ModelData.IsVisorToggled();
|
||||
else
|
||||
_manager.ChangeVisorState(state, value, StateChanged.Source.Game);
|
||||
_manager.ChangeMeta(state, MetaIndex.VisorState, value, StateSource.Game);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -598,10 +598,10 @@ public class StateListener : IDisposable
|
|||
{
|
||||
// if base state changed, either overwrite the actual value if we have fixed values,
|
||||
// or overwrite the stored model state with the new one.
|
||||
if (state.Source[MetaIndex.HatState] is StateChanged.Source.Fixed or StateChanged.Source.Ipc)
|
||||
if (state.Sources[MetaIndex.HatState] is StateSource.Fixed or StateSource.Ipc)
|
||||
value = state.ModelData.IsHatVisible();
|
||||
else
|
||||
_manager.ChangeHatState(state, value, StateChanged.Source.Game);
|
||||
_manager.ChangeMeta(state, MetaIndex.HatState, value, StateSource.Game);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -631,10 +631,10 @@ public class StateListener : IDisposable
|
|||
{
|
||||
// if base state changed, either overwrite the actual value if we have fixed values,
|
||||
// or overwrite the stored model state with the new one.
|
||||
if (state.Source[MetaIndex.WeaponState] is StateChanged.Source.Fixed or StateChanged.Source.Ipc)
|
||||
if (state.Sources[MetaIndex.WeaponState] is StateSource.Fixed or StateSource.Ipc)
|
||||
value = state.ModelData.IsWeaponVisible();
|
||||
else
|
||||
_manager.ChangeWeaponState(state, value, StateChanged.Source.Game);
|
||||
_manager.ChangeMeta(state, MetaIndex.WeaponState, value, StateSource.Game);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -700,9 +700,9 @@ public class StateListener : IDisposable
|
|||
return;
|
||||
|
||||
var data = new ActorData(gameObject, _creatingIdentifier.ToName());
|
||||
_applier.ChangeHatState(data, _creatingState.ModelData.IsHatVisible());
|
||||
_applier.ChangeWeaponState(data, _creatingState.ModelData.IsWeaponVisible());
|
||||
_applier.ChangeWetness(data, _creatingState.ModelData.IsWet());
|
||||
_applier.ChangeMetaState(data, MetaIndex.HatState, _creatingState.ModelData.IsHatVisible());
|
||||
_applier.ChangeMetaState(data, MetaIndex.Wetness, _creatingState.ModelData.IsWet());
|
||||
_applier.ChangeMetaState(data, MetaIndex.WeaponState, _creatingState.ModelData.IsWeaponVisible());
|
||||
|
||||
ApplyParameters(_creatingState, drawObject);
|
||||
}
|
||||
|
|
@ -733,30 +733,30 @@ public class StateListener : IDisposable
|
|||
foreach (var flag in CustomizeParameterExtensions.AllFlags)
|
||||
{
|
||||
var newValue = data[flag];
|
||||
switch (state.Source[flag])
|
||||
switch (state.Sources[flag])
|
||||
{
|
||||
case StateChanged.Source.Game:
|
||||
case StateSource.Game:
|
||||
if (state.BaseData.Parameters.Set(flag, newValue))
|
||||
_manager.ChangeCustomizeParameter(state, flag, newValue, StateChanged.Source.Game);
|
||||
_manager.ChangeCustomizeParameter(state, flag, newValue, StateSource.Game);
|
||||
break;
|
||||
case StateChanged.Source.Manual:
|
||||
case StateSource.Manual:
|
||||
if (state.BaseData.Parameters.Set(flag, newValue))
|
||||
_manager.ChangeCustomizeParameter(state, flag, newValue, StateChanged.Source.Game);
|
||||
_manager.ChangeCustomizeParameter(state, flag, newValue, StateSource.Game);
|
||||
else if (_config.UseAdvancedParameters)
|
||||
model.ApplySingleParameterData(flag, state.ModelData.Parameters);
|
||||
break;
|
||||
case StateChanged.Source.Fixed:
|
||||
case StateSource.Fixed:
|
||||
state.BaseData.Parameters.Set(flag, newValue);
|
||||
if (_config.UseAdvancedParameters)
|
||||
model.ApplySingleParameterData(flag, state.ModelData.Parameters);
|
||||
break;
|
||||
case StateChanged.Source.Ipc:
|
||||
case StateSource.Ipc:
|
||||
state.BaseData.Parameters.Set(flag, newValue);
|
||||
model.ApplySingleParameterData(flag, state.ModelData.Parameters);
|
||||
break;
|
||||
case StateChanged.Source.Pending:
|
||||
case StateSource.Pending:
|
||||
state.BaseData.Parameters.Set(flag, newValue);
|
||||
state.Source[flag] = StateChanged.Source.Manual;
|
||||
state.Sources[flag] = StateSource.Manual;
|
||||
if (_config.UseAdvancedParameters)
|
||||
model.ApplySingleParameterData(flag, state.ModelData.Parameters);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -207,58 +207,58 @@ public class StateManager(
|
|||
#region Change Values
|
||||
|
||||
/// <summary> Turn an actor human. </summary>
|
||||
public void TurnHuman(ActorState state, StateChanged.Source source, uint key = 0)
|
||||
public void TurnHuman(ActorState state, StateSource source, uint key = 0)
|
||||
=> ChangeModelId(state, 0, CustomizeArray.Default, nint.Zero, source, key);
|
||||
|
||||
/// <summary> Turn an actor to. </summary>
|
||||
public void ChangeModelId(ActorState state, uint modelId, CustomizeArray customize, nint equipData, StateChanged.Source source,
|
||||
public void ChangeModelId(ActorState state, uint modelId, CustomizeArray customize, nint equipData, StateSource source,
|
||||
uint key = 0)
|
||||
{
|
||||
if (!_editor.ChangeModelId(state, modelId, customize, equipData, source, out var old, key))
|
||||
return;
|
||||
|
||||
var actors = _applier.ForceRedraw(state, source is StateChanged.Source.Manual or StateChanged.Source.Ipc);
|
||||
var actors = _applier.ForceRedraw(state, source is StateSource.Manual or StateSource.Ipc);
|
||||
Glamourer.Log.Verbose(
|
||||
$"Set model id in state {state.Identifier.Incognito(null)} from {old} to {modelId}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
_event.Invoke(StateChanged.Type.Model, source, state, actors, (old, modelId));
|
||||
}
|
||||
|
||||
/// <summary> Change a customization value. </summary>
|
||||
public void ChangeCustomize(ActorState state, CustomizeIndex idx, CustomizeValue value, StateChanged.Source source, uint key = 0)
|
||||
public void ChangeCustomize(ActorState state, CustomizeIndex idx, CustomizeValue value, StateSource source, uint key = 0)
|
||||
{
|
||||
if (!_editor.ChangeCustomize(state, idx, value, source, out var old, key))
|
||||
return;
|
||||
|
||||
var actors = _applier.ChangeCustomize(state, source is StateChanged.Source.Manual or StateChanged.Source.Ipc);
|
||||
var actors = _applier.ChangeCustomize(state, source is StateSource.Manual or StateSource.Ipc);
|
||||
Glamourer.Log.Verbose(
|
||||
$"Set {idx.ToDefaultName()} customizations in state {state.Identifier.Incognito(null)} from {old.Value} to {value.Value}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
_event.Invoke(StateChanged.Type.Customize, source, state, actors, (old, value, idx));
|
||||
}
|
||||
|
||||
/// <summary> Change an entire customization array according to flags. </summary>
|
||||
public void ChangeCustomize(ActorState state, in CustomizeArray customizeInput, CustomizeFlag apply, StateChanged.Source source,
|
||||
public void ChangeCustomize(ActorState state, in CustomizeArray customizeInput, CustomizeFlag apply, StateSource source,
|
||||
uint key = 0)
|
||||
{
|
||||
if (!_editor.ChangeHumanCustomize(state, customizeInput, apply, source, out var old, out var applied, key))
|
||||
return;
|
||||
|
||||
var actors = _applier.ChangeCustomize(state, source is StateChanged.Source.Manual or StateChanged.Source.Ipc);
|
||||
var actors = _applier.ChangeCustomize(state, source is StateSource.Manual or StateSource.Ipc);
|
||||
Glamourer.Log.Verbose(
|
||||
$"Set {applied} customizations in state {state.Identifier.Incognito(null)} from {old} to {customizeInput}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
_event.Invoke(StateChanged.Type.EntireCustomize, source, state, actors, (old, applied));
|
||||
}
|
||||
|
||||
/// <summary> Change a single piece of equipment without stain. </summary>
|
||||
/// <remarks> Do not use this in the same frame as ChangeStain, use <see cref="ChangeEquip(ActorState,EquipSlot,EquipItem,StainId,StateChanged.Source,uint)"/> instead. </remarks>
|
||||
public void ChangeItem(ActorState state, EquipSlot slot, EquipItem item, StateChanged.Source source, uint key = 0)
|
||||
/// <remarks> Do not use this in the same frame as ChangeStain, use <see cref="ChangeEquip(ActorState,EquipSlot,EquipItem,StainId,StateSource,uint)"/> instead. </remarks>
|
||||
public void ChangeItem(ActorState state, EquipSlot slot, EquipItem item, StateSource source, uint key = 0)
|
||||
{
|
||||
if (!_editor.ChangeItem(state, slot, item, source, out var old, key))
|
||||
return;
|
||||
|
||||
var type = slot.ToIndex() < 10 ? StateChanged.Type.Equip : StateChanged.Type.Weapon;
|
||||
var actors = type is StateChanged.Type.Equip
|
||||
? _applier.ChangeArmor(state, slot, source is StateChanged.Source.Manual or StateChanged.Source.Ipc)
|
||||
: _applier.ChangeWeapon(state, slot, source is StateChanged.Source.Manual or StateChanged.Source.Ipc,
|
||||
? _applier.ChangeArmor(state, slot, source is StateSource.Manual or StateSource.Ipc)
|
||||
: _applier.ChangeWeapon(state, slot, source is StateSource.Manual or StateSource.Ipc,
|
||||
item.Type != (slot is EquipSlot.MainHand ? state.BaseData.MainhandType : state.BaseData.OffhandType));
|
||||
Glamourer.Log.Verbose(
|
||||
$"Set {slot.ToName()} in state {state.Identifier.Incognito(null)} from {old.Name} ({old.ItemId}) to {item.Name} ({item.ItemId}). [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
|
|
@ -266,15 +266,15 @@ public class StateManager(
|
|||
}
|
||||
|
||||
/// <summary> Change a single piece of equipment including stain. </summary>
|
||||
public void ChangeEquip(ActorState state, EquipSlot slot, EquipItem item, StainId stain, StateChanged.Source source, uint key = 0)
|
||||
public void ChangeEquip(ActorState state, EquipSlot slot, EquipItem item, StainId stain, StateSource source, uint key = 0)
|
||||
{
|
||||
if (!_editor.ChangeEquip(state, slot, item, stain, source, out var old, out var oldStain, key))
|
||||
return;
|
||||
|
||||
var type = slot.ToIndex() < 10 ? StateChanged.Type.Equip : StateChanged.Type.Weapon;
|
||||
var actors = type is StateChanged.Type.Equip
|
||||
? _applier.ChangeArmor(state, slot, source is StateChanged.Source.Manual or StateChanged.Source.Ipc)
|
||||
: _applier.ChangeWeapon(state, slot, source is StateChanged.Source.Manual or StateChanged.Source.Ipc,
|
||||
? _applier.ChangeArmor(state, slot, source is StateSource.Manual or StateSource.Ipc)
|
||||
: _applier.ChangeWeapon(state, slot, source is StateSource.Manual or StateSource.Ipc,
|
||||
item.Type != (slot is EquipSlot.MainHand ? state.BaseData.MainhandType : state.BaseData.OffhandType));
|
||||
Glamourer.Log.Verbose(
|
||||
$"Set {slot.ToName()} in state {state.Identifier.Incognito(null)} from {old.Name} ({old.ItemId}) to {item.Name} ({item.ItemId}) and its stain from {oldStain.Id} to {stain.Id}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
|
|
@ -283,25 +283,25 @@ public class StateManager(
|
|||
}
|
||||
|
||||
/// <summary> Change only the stain of an equipment piece. </summary>
|
||||
/// <remarks> Do not use this in the same frame as ChangeEquip, use <see cref="ChangeEquip(ActorState,EquipSlot,EquipItem,StainId,StateChanged.Source,uint)"/> instead. </remarks>
|
||||
public void ChangeStain(ActorState state, EquipSlot slot, StainId stain, StateChanged.Source source, uint key = 0)
|
||||
/// <remarks> Do not use this in the same frame as ChangeEquip, use <see cref="ChangeEquip(ActorState,EquipSlot,EquipItem,StainId,StateSource,uint)"/> instead. </remarks>
|
||||
public void ChangeStain(ActorState state, EquipSlot slot, StainId stain, StateSource source, uint key = 0)
|
||||
{
|
||||
if (!_editor.ChangeStain(state, slot, stain, source, out var old, key))
|
||||
return;
|
||||
|
||||
var actors = _applier.ChangeStain(state, slot, source is StateChanged.Source.Manual or StateChanged.Source.Ipc);
|
||||
var actors = _applier.ChangeStain(state, slot, source is StateSource.Manual or StateSource.Ipc);
|
||||
Glamourer.Log.Verbose(
|
||||
$"Set {slot.ToName()} stain in state {state.Identifier.Incognito(null)} from {old.Id} to {stain.Id}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
_event.Invoke(StateChanged.Type.Stain, source, state, actors, (old, stain, slot));
|
||||
}
|
||||
|
||||
/// <summary> Change the crest of an equipment piece. </summary>
|
||||
public void ChangeCrest(ActorState state, CrestFlag slot, bool crest, StateChanged.Source source, uint key = 0)
|
||||
public void ChangeCrest(ActorState state, CrestFlag slot, bool crest, StateSource source, uint key = 0)
|
||||
{
|
||||
if (!_editor.ChangeCrest(state, slot, crest, source, out var old, key))
|
||||
return;
|
||||
|
||||
var actors = _applier.ChangeCrests(state, source is StateChanged.Source.Manual or StateChanged.Source.Ipc);
|
||||
var actors = _applier.ChangeCrests(state, source is StateSource.Manual or StateSource.Ipc);
|
||||
Glamourer.Log.Verbose(
|
||||
$"Set {slot.ToLabel()} crest in state {state.Identifier.Incognito(null)} from {old} to {crest}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
_event.Invoke(StateChanged.Type.Crest, source, state, actors, (old, crest, slot));
|
||||
|
|
@ -309,7 +309,7 @@ public class StateManager(
|
|||
|
||||
/// <summary> Change the crest of an equipment piece. </summary>
|
||||
public void ChangeCustomizeParameter(ActorState state, CustomizeParameterFlag flag, CustomizeParameterValue value,
|
||||
StateChanged.Source source, uint key = 0)
|
||||
StateSource source, uint key = 0)
|
||||
{
|
||||
// Also apply main color to highlights when highlights is off.
|
||||
if (!state.ModelData.Customize.Highlights && flag is CustomizeParameterFlag.HairDiffuse)
|
||||
|
|
@ -319,63 +319,27 @@ public class StateManager(
|
|||
return;
|
||||
|
||||
var @new = state.ModelData.Parameters[flag];
|
||||
var actors = _applier.ChangeParameters(state, flag, source is StateChanged.Source.Manual or StateChanged.Source.Ipc);
|
||||
var actors = _applier.ChangeParameters(state, flag, source is StateSource.Manual or StateSource.Ipc);
|
||||
Glamourer.Log.Verbose(
|
||||
$"Set {flag} crest in state {state.Identifier.Incognito(null)} from {old} to {@new}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
_event.Invoke(StateChanged.Type.Parameter, source, state, actors, (old, @new, flag));
|
||||
}
|
||||
|
||||
/// <summary> Change hat visibility. </summary>
|
||||
public void ChangeHatState(ActorState state, bool value, StateChanged.Source source, uint key = 0)
|
||||
/// <summary> Change meta state. </summary>
|
||||
public void ChangeMeta(ActorState state, MetaIndex meta, bool value, StateSource source, uint key = 0)
|
||||
{
|
||||
if (!_editor.ChangeMetaState(state, MetaIndex.HatState, value, source, out var old, key))
|
||||
if (!_editor.ChangeMetaState(state, meta, value, source, out var old, key))
|
||||
return;
|
||||
|
||||
var actors = _applier.ChangeHatState(state, source is StateChanged.Source.Manual or StateChanged.Source.Ipc);
|
||||
var actors = _applier.ChangeMetaState(state, meta, source is StateSource.Manual or StateSource.Ipc);
|
||||
Glamourer.Log.Verbose(
|
||||
$"Set Head Gear Visibility in state {state.Identifier.Incognito(null)} from {old} to {value}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
_event.Invoke(StateChanged.Type.Other, source, state, actors, (old, value, MetaIndex.HatState));
|
||||
}
|
||||
|
||||
/// <summary> Change weapon visibility. </summary>
|
||||
public void ChangeWeaponState(ActorState state, bool value, StateChanged.Source source, uint key = 0)
|
||||
{
|
||||
if (!_editor.ChangeMetaState(state, MetaIndex.WeaponState, value, source, out var old, key))
|
||||
return;
|
||||
|
||||
var actors = _applier.ChangeWeaponState(state, source is StateChanged.Source.Manual or StateChanged.Source.Ipc);
|
||||
Glamourer.Log.Verbose(
|
||||
$"Set Weapon Visibility in state {state.Identifier.Incognito(null)} from {old} to {value}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
_event.Invoke(StateChanged.Type.Other, source, state, actors, (old, value, MetaIndex.WeaponState));
|
||||
}
|
||||
|
||||
/// <summary> Change visor state. </summary>
|
||||
public void ChangeVisorState(ActorState state, bool value, StateChanged.Source source, uint key = 0)
|
||||
{
|
||||
if (!_editor.ChangeMetaState(state, MetaIndex.VisorState, value, source, out var old, key))
|
||||
return;
|
||||
|
||||
var actors = _applier.ChangeVisor(state, source is StateChanged.Source.Manual or StateChanged.Source.Ipc);
|
||||
Glamourer.Log.Verbose(
|
||||
$"Set Visor State in state {state.Identifier.Incognito(null)} from {old} to {value}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
_event.Invoke(StateChanged.Type.Other, source, state, actors, (old, value, MetaIndex.VisorState));
|
||||
}
|
||||
|
||||
/// <summary> Set GPose Wetness. </summary>
|
||||
public void ChangeWetness(ActorState state, bool value, StateChanged.Source source, uint key = 0)
|
||||
{
|
||||
if (!_editor.ChangeMetaState(state, MetaIndex.Wetness, value, source, out var old, key))
|
||||
return;
|
||||
|
||||
var actors = _applier.ChangeWetness(state, true);
|
||||
Glamourer.Log.Verbose(
|
||||
$"Set Wetness in state {state.Identifier.Incognito(null)} from {old} to {value}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
_event.Invoke(StateChanged.Type.Other, state.Source[MetaIndex.Wetness], state, actors, (old, value, MetaIndex.Wetness));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void ApplyDesign(DesignBase design, ActorState state, StateChanged.Source source, uint key = 0)
|
||||
public void ApplyDesign(DesignBase design, ActorState state, StateSource source, uint key = 0)
|
||||
{
|
||||
if (!_editor.ChangeModelId(state, design.DesignData.ModelId, design.DesignData.Customize, design.GetDesignDataRef().GetEquipmentPtr(),
|
||||
source,
|
||||
|
|
@ -383,16 +347,16 @@ public class StateManager(
|
|||
return;
|
||||
|
||||
var redraw = oldModelId != design.DesignData.ModelId || !design.DesignData.IsHuman;
|
||||
if (design.DoApplyWetness())
|
||||
if (design.DoApplyMeta(MetaIndex.Wetness))
|
||||
_editor.ChangeMetaState(state, MetaIndex.Wetness, design.DesignData.IsWet(), source, out _, key);
|
||||
|
||||
if (state.ModelData.IsHuman)
|
||||
{
|
||||
if (design.DoApplyHatVisible())
|
||||
if (design.DoApplyMeta(MetaIndex.HatState))
|
||||
_editor.ChangeMetaState(state, MetaIndex.HatState, design.DesignData.IsHatVisible(), source, out _, key);
|
||||
if (design.DoApplyWeaponVisible())
|
||||
if (design.DoApplyMeta(MetaIndex.WeaponState))
|
||||
_editor.ChangeMetaState(state, MetaIndex.WeaponState, design.DesignData.IsWeaponVisible(), source, out _, key);
|
||||
if (design.DoApplyVisorToggle())
|
||||
if (design.DoApplyMeta(MetaIndex.VisorState))
|
||||
_editor.ChangeMetaState(state, MetaIndex.VisorState, design.DesignData.IsVisorToggled(), source, out _, key);
|
||||
|
||||
var flags = state.AllowsRedraw(_condition)
|
||||
|
|
@ -407,8 +371,8 @@ public class StateManager(
|
|||
foreach (var slot in CrestExtensions.AllRelevantSet.Where(design.DoApplyCrest))
|
||||
_editor.ChangeCrest(state, slot, design.DesignData.Crest(slot), source, out _, key);
|
||||
|
||||
var paramSource = source is StateChanged.Source.Manual
|
||||
? StateChanged.Source.Pending
|
||||
var paramSource = source is StateSource.Manual
|
||||
? StateSource.Pending
|
||||
: source;
|
||||
|
||||
foreach (var flag in CustomizeParameterExtensions.AllFlags.Where(design.DoApplyParameter))
|
||||
|
|
@ -418,13 +382,13 @@ public class StateManager(
|
|||
if (!state.ModelData.Customize.Highlights)
|
||||
_editor.ChangeParameter(state, CustomizeParameterFlag.HairHighlight,
|
||||
state.ModelData.Parameters[CustomizeParameterFlag.HairDiffuse],
|
||||
state.Source[CustomizeParameterFlag.HairDiffuse], out _, key);
|
||||
state.Sources[CustomizeParameterFlag.HairDiffuse], out _, key);
|
||||
}
|
||||
|
||||
var actors = ApplyAll(state, redraw, false);
|
||||
Glamourer.Log.Verbose(
|
||||
$"Applied design to {state.Identifier.Incognito(null)}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
_event.Invoke(StateChanged.Type.Design, state.Source[MetaIndex.Wetness], state, actors, design);
|
||||
_event.Invoke(StateChanged.Type.Design, state.Sources[MetaIndex.Wetness], state, actors, design);
|
||||
return;
|
||||
|
||||
void HandleEquip(EquipSlot slot, bool applyPiece, bool applyStain)
|
||||
|
|
@ -442,7 +406,7 @@ public class StateManager(
|
|||
|
||||
private ActorData ApplyAll(ActorState state, bool redraw, bool withLock)
|
||||
{
|
||||
var actors = _applier.ChangeWetness(state, true);
|
||||
var actors = _applier.ChangeMetaState(state, MetaIndex.Wetness, true);
|
||||
if (redraw)
|
||||
{
|
||||
if (withLock)
|
||||
|
|
@ -454,7 +418,7 @@ public class StateManager(
|
|||
_applier.ChangeCustomize(actors, state.ModelData.Customize);
|
||||
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
||||
{
|
||||
_applier.ChangeArmor(actors, slot, state.ModelData.Armor(slot), state.Source[slot, false] is not StateChanged.Source.Ipc,
|
||||
_applier.ChangeArmor(actors, slot, state.ModelData.Armor(slot), state.Sources[slot, false] is not StateSource.Ipc,
|
||||
state.ModelData.IsHatVisible());
|
||||
}
|
||||
|
||||
|
|
@ -466,9 +430,9 @@ public class StateManager(
|
|||
|
||||
if (state.ModelData.IsHuman)
|
||||
{
|
||||
_applier.ChangeHatState(actors, state.ModelData.IsHatVisible());
|
||||
_applier.ChangeWeaponState(actors, state.ModelData.IsWeaponVisible());
|
||||
_applier.ChangeVisor(actors, state.ModelData.IsVisorToggled());
|
||||
_applier.ChangeMetaState(actors, MetaIndex.HatState, state.ModelData.IsHatVisible());
|
||||
_applier.ChangeMetaState(actors, MetaIndex.WeaponState, state.ModelData.IsWeaponVisible());
|
||||
_applier.ChangeMetaState(actors, MetaIndex.VisorState, state.ModelData.IsVisorToggled());
|
||||
_applier.ChangeCrests(actors, state.ModelData.CrestVisibility);
|
||||
_applier.ChangeParameters(actors, state.OnlyChangedParameters(), state.ModelData.Parameters, state.IsLocked);
|
||||
}
|
||||
|
|
@ -476,7 +440,7 @@ public class StateManager(
|
|||
return actors;
|
||||
}
|
||||
|
||||
public void ResetState(ActorState state, StateChanged.Source source, uint key = 0)
|
||||
public void ResetState(ActorState state, StateSource source, uint key = 0)
|
||||
{
|
||||
if (!state.Unlock(key))
|
||||
return;
|
||||
|
|
@ -488,25 +452,25 @@ public class StateManager(
|
|||
state.ModelData = state.BaseData;
|
||||
state.ModelData.SetIsWet(false);
|
||||
foreach (var index in Enum.GetValues<CustomizeIndex>())
|
||||
state.Source[index] = StateChanged.Source.Game;
|
||||
state.Sources[index] = StateSource.Game;
|
||||
|
||||
foreach (var slot in EquipSlotExtensions.FullSlots)
|
||||
{
|
||||
state.Source[slot, true] = StateChanged.Source.Game;
|
||||
state.Source[slot, false] = StateChanged.Source.Game;
|
||||
state.Sources[slot, true] = StateSource.Game;
|
||||
state.Sources[slot, false] = StateSource.Game;
|
||||
}
|
||||
|
||||
foreach (var type in Enum.GetValues<MetaIndex>())
|
||||
state.Source[type] = StateChanged.Source.Game;
|
||||
state.Sources[type] = StateSource.Game;
|
||||
|
||||
foreach (var slot in CrestExtensions.AllRelevantSet)
|
||||
state.Source[slot] = StateChanged.Source.Game;
|
||||
state.Sources[slot] = StateSource.Game;
|
||||
|
||||
foreach (var flag in CustomizeParameterExtensions.AllFlags)
|
||||
state.Source[flag] = StateChanged.Source.Game;
|
||||
state.Sources[flag] = StateSource.Game;
|
||||
|
||||
var actors = ActorData.Invalid;
|
||||
if (source is StateChanged.Source.Manual or StateChanged.Source.Ipc)
|
||||
if (source is StateSource.Manual or StateSource.Ipc)
|
||||
actors = ApplyAll(state, redraw, true);
|
||||
|
||||
Glamourer.Log.Verbose(
|
||||
|
|
@ -514,7 +478,7 @@ public class StateManager(
|
|||
_event.Invoke(StateChanged.Type.Reset, source, state, actors, null);
|
||||
}
|
||||
|
||||
public void ResetAdvancedState(ActorState state, StateChanged.Source source, uint key = 0)
|
||||
public void ResetAdvancedState(ActorState state, StateSource source, uint key = 0)
|
||||
{
|
||||
if (!state.Unlock(key) || !state.ModelData.IsHuman)
|
||||
return;
|
||||
|
|
@ -522,10 +486,10 @@ public class StateManager(
|
|||
state.ModelData.Parameters = state.BaseData.Parameters;
|
||||
|
||||
foreach (var flag in CustomizeParameterExtensions.AllFlags)
|
||||
state.Source[flag] = StateChanged.Source.Game;
|
||||
state.Sources[flag] = StateSource.Game;
|
||||
|
||||
var actors = ActorData.Invalid;
|
||||
if (source is StateChanged.Source.Manual or StateChanged.Source.Ipc)
|
||||
if (source is StateSource.Manual or StateSource.Ipc)
|
||||
actors = _applier.ChangeParameters(state, CustomizeParameterExtensions.All, true);
|
||||
Glamourer.Log.Verbose(
|
||||
$"Reset advanced customization state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
|
|
@ -537,69 +501,69 @@ public class StateManager(
|
|||
if (!state.Unlock(key))
|
||||
return;
|
||||
|
||||
foreach (var index in Enum.GetValues<CustomizeIndex>().Where(i => state.Source[i] is StateChanged.Source.Fixed))
|
||||
foreach (var index in Enum.GetValues<CustomizeIndex>().Where(i => state.Sources[i] is StateSource.Fixed))
|
||||
{
|
||||
state.Source[index] = StateChanged.Source.Game;
|
||||
state.Sources[index] = StateSource.Game;
|
||||
state.ModelData.Customize[index] = state.BaseData.Customize[index];
|
||||
}
|
||||
|
||||
foreach (var slot in EquipSlotExtensions.FullSlots)
|
||||
{
|
||||
if (state.Source[slot, true] is StateChanged.Source.Fixed)
|
||||
if (state.Sources[slot, true] is StateSource.Fixed)
|
||||
{
|
||||
state.Source[slot, true] = StateChanged.Source.Game;
|
||||
state.Sources[slot, true] = StateSource.Game;
|
||||
state.ModelData.SetStain(slot, state.BaseData.Stain(slot));
|
||||
}
|
||||
|
||||
if (state.Source[slot, false] is StateChanged.Source.Fixed)
|
||||
if (state.Sources[slot, false] is StateSource.Fixed)
|
||||
{
|
||||
state.Source[slot, false] = StateChanged.Source.Game;
|
||||
state.Sources[slot, false] = StateSource.Game;
|
||||
state.ModelData.SetItem(slot, state.BaseData.Item(slot));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var slot in CrestExtensions.AllRelevantSet)
|
||||
{
|
||||
if (state.Source[slot] is StateChanged.Source.Fixed)
|
||||
if (state.Sources[slot] is StateSource.Fixed)
|
||||
{
|
||||
state.Source[slot] = StateChanged.Source.Game;
|
||||
state.Sources[slot] = StateSource.Game;
|
||||
state.ModelData.SetCrest(slot, state.BaseData.Crest(slot));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var flag in CustomizeParameterExtensions.AllFlags)
|
||||
{
|
||||
switch (state.Source[flag])
|
||||
switch (state.Sources[flag])
|
||||
{
|
||||
case StateChanged.Source.Fixed:
|
||||
case StateChanged.Source.Manual when !respectManualPalettes:
|
||||
state.Source[flag] = StateChanged.Source.Game;
|
||||
case StateSource.Fixed:
|
||||
case StateSource.Manual when !respectManualPalettes:
|
||||
state.Sources[flag] = StateSource.Game;
|
||||
state.ModelData.Parameters[flag] = state.BaseData.Parameters[flag];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (state.Source[MetaIndex.HatState] is StateChanged.Source.Fixed)
|
||||
if (state.Sources[MetaIndex.HatState] is StateSource.Fixed)
|
||||
{
|
||||
state.Source[MetaIndex.HatState] = StateChanged.Source.Game;
|
||||
state.Sources[MetaIndex.HatState] = StateSource.Game;
|
||||
state.ModelData.SetHatVisible(state.BaseData.IsHatVisible());
|
||||
}
|
||||
|
||||
if (state.Source[MetaIndex.VisorState] is StateChanged.Source.Fixed)
|
||||
if (state.Sources[MetaIndex.VisorState] is StateSource.Fixed)
|
||||
{
|
||||
state.Source[MetaIndex.VisorState] = StateChanged.Source.Game;
|
||||
state.Sources[MetaIndex.VisorState] = StateSource.Game;
|
||||
state.ModelData.SetVisor(state.BaseData.IsVisorToggled());
|
||||
}
|
||||
|
||||
if (state.Source[MetaIndex.WeaponState] is StateChanged.Source.Fixed)
|
||||
if (state.Sources[MetaIndex.WeaponState] is StateSource.Fixed)
|
||||
{
|
||||
state.Source[MetaIndex.WeaponState] = StateChanged.Source.Game;
|
||||
state.Sources[MetaIndex.WeaponState] = StateSource.Game;
|
||||
state.ModelData.SetWeaponVisible(state.BaseData.IsWeaponVisible());
|
||||
}
|
||||
|
||||
if (state.Source[MetaIndex.Wetness] is StateChanged.Source.Fixed)
|
||||
if (state.Sources[MetaIndex.Wetness] is StateSource.Fixed)
|
||||
{
|
||||
state.Source[MetaIndex.Wetness] = StateChanged.Source.Game;
|
||||
state.Sources[MetaIndex.Wetness] = StateSource.Game;
|
||||
state.ModelData.SetIsWet(state.BaseData.IsWet());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,49 +1,75 @@
|
|||
using Glamourer.GameData;
|
||||
using Penumbra.GameData.Enums;
|
||||
using static Glamourer.Events.StateChanged;
|
||||
using Penumbra.GameData.Enums;
|
||||
|
||||
namespace Glamourer.State;
|
||||
|
||||
public readonly struct StateSource
|
||||
public enum StateSource : byte
|
||||
{
|
||||
public static readonly int Size = EquipFlagExtensions.NumEquipFlags
|
||||
+ CustomizationExtensions.NumIndices
|
||||
+ 5
|
||||
+ CrestExtensions.AllRelevantSet.Count
|
||||
+ CustomizeParameterExtensions.AllFlags.Count;
|
||||
Game,
|
||||
Manual,
|
||||
Fixed,
|
||||
Ipc,
|
||||
|
||||
// Only used for CustomizeParameters.
|
||||
Pending,
|
||||
}
|
||||
|
||||
public unsafe struct StateSources
|
||||
{
|
||||
public const int Size = (StateIndex.Size + 1) / 2;
|
||||
private fixed byte _data[Size];
|
||||
|
||||
|
||||
private readonly Source[] _data = Enumerable.Repeat(Source.Game, Size).ToArray();
|
||||
|
||||
public StateSource()
|
||||
public StateSources()
|
||||
{ }
|
||||
|
||||
public ref Source this[EquipSlot slot, bool stain]
|
||||
=> ref _data[slot.ToIndex() + (stain ? EquipFlagExtensions.NumEquipFlags / 2 : 0)];
|
||||
public StateSource this[StateIndex index]
|
||||
{
|
||||
get
|
||||
{
|
||||
var val = _data[index.Value / 2];
|
||||
return (StateSource)((index.Value & 1) == 1 ? val >> 4 : val & 0x0F);
|
||||
}
|
||||
set
|
||||
{
|
||||
var val = _data[index.Value / 2];
|
||||
if ((index.Value & 1) == 1)
|
||||
val = (byte)((val & 0x0F) | ((byte)value << 4));
|
||||
else
|
||||
val = (byte)((val & 0xF0) | (byte)value);
|
||||
_data[index.Value / 2] = val;
|
||||
}
|
||||
}
|
||||
|
||||
public ref Source this[CrestFlag slot]
|
||||
=> ref _data[EquipFlagExtensions.NumEquipFlags + CustomizationExtensions.NumIndices + 5 + slot.ToInternalIndex()];
|
||||
|
||||
public ref Source this[CustomizeIndex type]
|
||||
=> ref _data[EquipFlagExtensions.NumEquipFlags + (int)type];
|
||||
|
||||
public ref Source this[MetaIndex index]
|
||||
=> ref _data[(int)index];
|
||||
|
||||
public ref Source this[CustomizeParameterFlag flag]
|
||||
=> ref _data[
|
||||
EquipFlagExtensions.NumEquipFlags
|
||||
+ CustomizationExtensions.NumIndices
|
||||
+ 5
|
||||
+ CrestExtensions.AllRelevantSet.Count
|
||||
+ flag.ToInternalIndex()];
|
||||
public StateSource this[EquipSlot slot, bool stain]
|
||||
{
|
||||
get => this[slot.ToState(stain)];
|
||||
set => this[slot.ToState(stain)] = value;
|
||||
}
|
||||
|
||||
public void RemoveFixedDesignSources()
|
||||
{
|
||||
for (var i = 0; i < _data.Length; ++i)
|
||||
for (var i = 0; i < Size; ++i)
|
||||
{
|
||||
if (_data[i] is Source.Fixed)
|
||||
_data[i] = Source.Manual;
|
||||
var value = _data[i];
|
||||
switch (value)
|
||||
{
|
||||
case (byte)StateSource.Fixed | ((byte)StateSource.Fixed << 4):
|
||||
_data[i] = (byte)StateSource.Manual | ((byte)StateSource.Manual << 4);
|
||||
break;
|
||||
|
||||
case (byte)StateSource.Game | ((byte)StateSource.Fixed << 4):
|
||||
case (byte)StateSource.Manual | ((byte)StateSource.Fixed << 4):
|
||||
case (byte)StateSource.Ipc | ((byte)StateSource.Fixed << 4):
|
||||
case (byte)StateSource.Pending | ((byte)StateSource.Fixed << 4):
|
||||
_data[i] = (byte)((value & 0x0F) | ((byte)StateSource.Manual << 4));
|
||||
break;
|
||||
case (byte)StateSource.Fixed:
|
||||
case ((byte)StateSource.Manual << 4) | (byte)StateSource.Fixed:
|
||||
case ((byte)StateSource.Ipc << 4) | (byte)StateSource.Fixed:
|
||||
case ((byte)StateSource.Pending << 4) | (byte)StateSource.Fixed:
|
||||
_data[i] = (byte)((value & 0xF0) | (byte)StateSource.Manual);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue