mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-13 12:14:18 +01:00
Add IpcManual state.
This commit is contained in:
parent
994b7bfb6c
commit
818bf71032
15 changed files with 242 additions and 109 deletions
|
|
@ -11,7 +11,9 @@ namespace Glamourer.Api;
|
||||||
public partial class GlamourerIpc
|
public partial class GlamourerIpc
|
||||||
{
|
{
|
||||||
public const string LabelApplyAll = "Glamourer.ApplyAll";
|
public const string LabelApplyAll = "Glamourer.ApplyAll";
|
||||||
|
public const string LabelApplyAllOnce = "Glamourer.ApplyAllOnce";
|
||||||
public const string LabelApplyAllToCharacter = "Glamourer.ApplyAllToCharacter";
|
public const string LabelApplyAllToCharacter = "Glamourer.ApplyAllToCharacter";
|
||||||
|
public const string LabelApplyAllOnceToCharacter = "Glamourer.ApplyAllOnceToCharacter";
|
||||||
public const string LabelApplyOnlyEquipment = "Glamourer.ApplyOnlyEquipment";
|
public const string LabelApplyOnlyEquipment = "Glamourer.ApplyOnlyEquipment";
|
||||||
public const string LabelApplyOnlyEquipmentToCharacter = "Glamourer.ApplyOnlyEquipmentToCharacter";
|
public const string LabelApplyOnlyEquipmentToCharacter = "Glamourer.ApplyOnlyEquipmentToCharacter";
|
||||||
public const string LabelApplyOnlyCustomization = "Glamourer.ApplyOnlyCustomization";
|
public const string LabelApplyOnlyCustomization = "Glamourer.ApplyOnlyCustomization";
|
||||||
|
|
@ -24,11 +26,15 @@ public partial class GlamourerIpc
|
||||||
public const string LabelApplyOnlyCustomizationLock = "Glamourer.ApplyOnlyCustomizationLock";
|
public const string LabelApplyOnlyCustomizationLock = "Glamourer.ApplyOnlyCustomizationLock";
|
||||||
public const string LabelApplyOnlyCustomizationToCharacterLock = "Glamourer.ApplyOnlyCustomizationToCharacterLock";
|
public const string LabelApplyOnlyCustomizationToCharacterLock = "Glamourer.ApplyOnlyCustomizationToCharacterLock";
|
||||||
|
|
||||||
public const string LabelApplyByGuid = "Glamourer.ApplyByGuid";
|
public const string LabelApplyByGuid = "Glamourer.ApplyByGuid";
|
||||||
public const string LabelApplyByGuidToCharacter = "Glamourer.ApplyByGuidToCharacter";
|
public const string LabelApplyByGuidOnce = "Glamourer.ApplyByGuidOnce";
|
||||||
|
public const string LabelApplyByGuidToCharacter = "Glamourer.ApplyByGuidToCharacter";
|
||||||
|
public const string LabelApplyByGuidOnceToCharacter = "Glamourer.ApplyByGuidOnceToCharacter";
|
||||||
|
|
||||||
private readonly ActionProvider<string, string> _applyAllProvider;
|
private readonly ActionProvider<string, string> _applyAllProvider;
|
||||||
|
private readonly ActionProvider<string, string> _applyAllOnceProvider;
|
||||||
private readonly ActionProvider<string, Character?> _applyAllToCharacterProvider;
|
private readonly ActionProvider<string, Character?> _applyAllToCharacterProvider;
|
||||||
|
private readonly ActionProvider<string, Character?> _applyAllOnceToCharacterProvider;
|
||||||
private readonly ActionProvider<string, string> _applyOnlyEquipmentProvider;
|
private readonly ActionProvider<string, string> _applyOnlyEquipmentProvider;
|
||||||
private readonly ActionProvider<string, Character?> _applyOnlyEquipmentToCharacterProvider;
|
private readonly ActionProvider<string, Character?> _applyOnlyEquipmentToCharacterProvider;
|
||||||
private readonly ActionProvider<string, string> _applyOnlyCustomizationProvider;
|
private readonly ActionProvider<string, string> _applyOnlyCustomizationProvider;
|
||||||
|
|
@ -42,14 +48,22 @@ public partial class GlamourerIpc
|
||||||
private readonly ActionProvider<string, Character?, uint> _applyOnlyCustomizationToCharacterProviderLock;
|
private readonly ActionProvider<string, Character?, uint> _applyOnlyCustomizationToCharacterProviderLock;
|
||||||
|
|
||||||
private readonly ActionProvider<Guid, string> _applyByGuidProvider;
|
private readonly ActionProvider<Guid, string> _applyByGuidProvider;
|
||||||
|
private readonly ActionProvider<Guid, string> _applyByGuidOnceProvider;
|
||||||
private readonly ActionProvider<Guid, Character?> _applyByGuidToCharacterProvider;
|
private readonly ActionProvider<Guid, Character?> _applyByGuidToCharacterProvider;
|
||||||
|
private readonly ActionProvider<Guid, Character?> _applyByGuidOnceToCharacterProvider;
|
||||||
|
|
||||||
public static ActionSubscriber<string, string> ApplyAllSubscriber(DalamudPluginInterface pi)
|
public static ActionSubscriber<string, string> ApplyAllSubscriber(DalamudPluginInterface pi)
|
||||||
=> new(pi, LabelApplyAll);
|
=> new(pi, LabelApplyAll);
|
||||||
|
|
||||||
|
public static ActionSubscriber<string, string> ApplyAllOnceSubscriber(DalamudPluginInterface pi)
|
||||||
|
=> new(pi, LabelApplyAllOnce);
|
||||||
|
|
||||||
public static ActionSubscriber<string, Character?> ApplyAllToCharacterSubscriber(DalamudPluginInterface pi)
|
public static ActionSubscriber<string, Character?> ApplyAllToCharacterSubscriber(DalamudPluginInterface pi)
|
||||||
=> new(pi, LabelApplyAllToCharacter);
|
=> new(pi, LabelApplyAllToCharacter);
|
||||||
|
|
||||||
|
public static ActionSubscriber<string, Character?> ApplyAllOnceToCharacterSubscriber(DalamudPluginInterface pi)
|
||||||
|
=> new(pi, LabelApplyAllOnceToCharacter);
|
||||||
|
|
||||||
public static ActionSubscriber<string, string> ApplyOnlyEquipmentSubscriber(DalamudPluginInterface pi)
|
public static ActionSubscriber<string, string> ApplyOnlyEquipmentSubscriber(DalamudPluginInterface pi)
|
||||||
=> new(pi, LabelApplyOnlyEquipment);
|
=> new(pi, LabelApplyOnlyEquipment);
|
||||||
|
|
||||||
|
|
@ -65,15 +79,27 @@ public partial class GlamourerIpc
|
||||||
public static ActionSubscriber<Guid, string> ApplyByGuidSubscriber(DalamudPluginInterface pi)
|
public static ActionSubscriber<Guid, string> ApplyByGuidSubscriber(DalamudPluginInterface pi)
|
||||||
=> new(pi, LabelApplyByGuid);
|
=> new(pi, LabelApplyByGuid);
|
||||||
|
|
||||||
|
public static ActionSubscriber<Guid, string> ApplyByGuidOnceSubscriber(DalamudPluginInterface pi)
|
||||||
|
=> new(pi, LabelApplyByGuidOnce);
|
||||||
|
|
||||||
public static ActionSubscriber<Guid, Character?> ApplyByGuidToCharacterSubscriber(DalamudPluginInterface pi)
|
public static ActionSubscriber<Guid, Character?> ApplyByGuidToCharacterSubscriber(DalamudPluginInterface pi)
|
||||||
=> new(pi, LabelApplyByGuidToCharacter);
|
=> new(pi, LabelApplyByGuidToCharacter);
|
||||||
|
|
||||||
|
public static ActionSubscriber<Guid, Character?> ApplyByGuidOnceToCharacterSubscriber(DalamudPluginInterface pi)
|
||||||
|
=> new(pi, LabelApplyByGuidOnceToCharacter);
|
||||||
|
|
||||||
public void ApplyAll(string base64, string characterName)
|
public void ApplyAll(string base64, string characterName)
|
||||||
=> ApplyDesign(_designConverter.FromBase64(base64, true, true, out var version), FindActors(characterName), version, 0);
|
=> ApplyDesign(_designConverter.FromBase64(base64, true, true, out var version), FindActors(characterName), version, 0);
|
||||||
|
|
||||||
|
public void ApplyAllOnce(string base64, string characterName)
|
||||||
|
=> ApplyDesign(_designConverter.FromBase64(base64, true, true, out var version), FindActors(characterName), version, 0, true);
|
||||||
|
|
||||||
public void ApplyAllToCharacter(string base64, Character? character)
|
public void ApplyAllToCharacter(string base64, Character? character)
|
||||||
=> ApplyDesign(_designConverter.FromBase64(base64, true, true, out var version), FindActors(character), version, 0);
|
=> ApplyDesign(_designConverter.FromBase64(base64, true, true, out var version), FindActors(character), version, 0);
|
||||||
|
|
||||||
|
public void ApplyAllOnceToCharacter(string base64, Character? character)
|
||||||
|
=> ApplyDesign(_designConverter.FromBase64(base64, true, true, out var version), FindActors(character), version, 0, true);
|
||||||
|
|
||||||
public void ApplyOnlyEquipment(string base64, string characterName)
|
public void ApplyOnlyEquipment(string base64, string characterName)
|
||||||
=> ApplyDesign(_designConverter.FromBase64(base64, false, true, out var version), FindActors(characterName), version, 0);
|
=> ApplyDesign(_designConverter.FromBase64(base64, false, true, out var version), FindActors(characterName), version, 0);
|
||||||
|
|
||||||
|
|
@ -107,12 +133,18 @@ public partial class GlamourerIpc
|
||||||
|
|
||||||
|
|
||||||
public void ApplyByGuid(Guid identifier, string characterName)
|
public void ApplyByGuid(Guid identifier, string characterName)
|
||||||
=> ApplyDesignByGuid(identifier, FindActors(characterName), 0);
|
=> ApplyDesignByGuid(identifier, FindActors(characterName), 0, false);
|
||||||
|
|
||||||
|
public void ApplyByGuidOnce(Guid identifier, string characterName)
|
||||||
|
=> ApplyDesignByGuid(identifier, FindActors(characterName), 0, true);
|
||||||
|
|
||||||
public void ApplyByGuidToCharacter(Guid identifier, Character? character)
|
public void ApplyByGuidToCharacter(Guid identifier, Character? character)
|
||||||
=> ApplyDesignByGuid(identifier, FindActors(character), 0);
|
=> ApplyDesignByGuid(identifier, FindActors(character), 0, false);
|
||||||
|
|
||||||
private void ApplyDesign(DesignBase? design, IEnumerable<ActorIdentifier> actors, byte version, uint lockCode)
|
public void ApplyByGuidOnceToCharacter(Guid identifier, Character? character)
|
||||||
|
=> ApplyDesignByGuid(identifier, FindActors(character), 0, true);
|
||||||
|
|
||||||
|
private void ApplyDesign(DesignBase? design, IEnumerable<ActorIdentifier> actors, byte version, uint lockCode, bool once = false)
|
||||||
{
|
{
|
||||||
if (design == null)
|
if (design == null)
|
||||||
return;
|
return;
|
||||||
|
|
@ -130,12 +162,13 @@ public partial class GlamourerIpc
|
||||||
|
|
||||||
if ((hasModelId || state.ModelData.ModelId == 0) && state.CanUnlock(lockCode))
|
if ((hasModelId || state.ModelData.ModelId == 0) && state.CanUnlock(lockCode))
|
||||||
{
|
{
|
||||||
_stateManager.ApplyDesign(state, design, new ApplySettings(Source:StateSource.Ipc, Key:lockCode));
|
_stateManager.ApplyDesign(state, design,
|
||||||
|
new ApplySettings(Source: once ? StateSource.IpcManual : StateSource.IpcFixed, Key: lockCode));
|
||||||
state.Lock(lockCode);
|
state.Lock(lockCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplyDesignByGuid(Guid identifier, IEnumerable<ActorIdentifier> actors, uint lockCode)
|
private void ApplyDesignByGuid(Guid identifier, IEnumerable<ActorIdentifier> actors, uint lockCode, bool once)
|
||||||
=> ApplyDesign(_designManager.Designs.ByIdentifier(identifier), actors, DesignConverter.Version, lockCode);
|
=> ApplyDesign(_designManager.Designs.ByIdentifier(identifier), actors, DesignConverter.Version, lockCode, once);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
using Dalamud.Game.ClientState.Objects.Types;
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Glamourer.Events;
|
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using Penumbra.Api.Helpers;
|
using Penumbra.Api.Helpers;
|
||||||
using Penumbra.GameData.Actors;
|
using Penumbra.GameData.Actors;
|
||||||
|
|
@ -83,7 +82,7 @@ public partial class GlamourerIpc
|
||||||
foreach (var id in actors)
|
foreach (var id in actors)
|
||||||
{
|
{
|
||||||
if (_stateManager.TryGetValue(id, out var state))
|
if (_stateManager.TryGetValue(id, out var state))
|
||||||
_stateManager.ResetState(state, StateSource.Ipc, lockCode);
|
_stateManager.ResetState(state, StateSource.IpcFixed, lockCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,20 +20,30 @@ public partial class GlamourerIpc
|
||||||
ItemInvalid,
|
ItemInvalid,
|
||||||
}
|
}
|
||||||
|
|
||||||
public const string LabelSetItem = "Glamourer.SetItem";
|
public const string LabelSetItem = "Glamourer.SetItem";
|
||||||
public const string LabelSetItemByActorName = "Glamourer.SetItemByActorName";
|
public const string LabelSetItemOnce = "Glamourer.SetItemOnce";
|
||||||
|
public const string LabelSetItemByActorName = "Glamourer.SetItemByActorName";
|
||||||
|
public const string LabelSetItemOnceByActorName = "Glamourer.SetItemOnceByActorName";
|
||||||
|
|
||||||
|
|
||||||
private readonly FuncProvider<Character?, byte, ulong, byte, uint, int> _setItemProvider;
|
private readonly FuncProvider<Character?, byte, ulong, byte, uint, int> _setItemProvider;
|
||||||
|
private readonly FuncProvider<Character?, byte, ulong, byte, uint, int> _setItemOnceProvider;
|
||||||
private readonly FuncProvider<string, byte, ulong, byte, uint, int> _setItemByActorNameProvider;
|
private readonly FuncProvider<string, byte, ulong, byte, uint, int> _setItemByActorNameProvider;
|
||||||
|
private readonly FuncProvider<string, byte, ulong, byte, uint, int> _setItemOnceByActorNameProvider;
|
||||||
|
|
||||||
public static FuncSubscriber<Character?, byte, ulong, byte, uint, int> SetItemSubscriber(DalamudPluginInterface pi)
|
public static FuncSubscriber<Character?, byte, ulong, byte, uint, int> SetItemSubscriber(DalamudPluginInterface pi)
|
||||||
=> new(pi, LabelSetItem);
|
=> new(pi, LabelSetItem);
|
||||||
|
|
||||||
|
public static FuncSubscriber<Character?, byte, ulong, byte, uint, int> SetItemOnceSubscriber(DalamudPluginInterface pi)
|
||||||
|
=> new(pi, LabelSetItemOnce);
|
||||||
|
|
||||||
public static FuncSubscriber<string, byte, ulong, byte, uint, int> SetItemByActorNameSubscriber(DalamudPluginInterface pi)
|
public static FuncSubscriber<string, byte, ulong, byte, uint, int> SetItemByActorNameSubscriber(DalamudPluginInterface pi)
|
||||||
=> new(pi, LabelSetItemByActorName);
|
=> new(pi, LabelSetItemByActorName);
|
||||||
|
|
||||||
private GlamourerErrorCode SetItem(Character? character, EquipSlot slot, CustomItemId itemId, StainId stainId, uint key)
|
public static FuncSubscriber<string, byte, ulong, byte, uint, int> SetItemOnceByActorNameSubscriber(DalamudPluginInterface pi)
|
||||||
|
=> new(pi, LabelSetItemOnceByActorName);
|
||||||
|
|
||||||
|
private GlamourerErrorCode SetItem(Character? character, EquipSlot slot, CustomItemId itemId, StainId stainId, uint key, bool once)
|
||||||
{
|
{
|
||||||
if (itemId.Id == 0)
|
if (itemId.Id == 0)
|
||||||
itemId = ItemManager.NothingId(slot);
|
itemId = ItemManager.NothingId(slot);
|
||||||
|
|
@ -57,11 +67,12 @@ public partial class GlamourerIpc
|
||||||
if (!state.ModelData.IsHuman)
|
if (!state.ModelData.IsHuman)
|
||||||
return GlamourerErrorCode.ActorNotHuman;
|
return GlamourerErrorCode.ActorNotHuman;
|
||||||
|
|
||||||
_stateManager.ChangeEquip(state, slot, item, stainId, new ApplySettings(Source: StateSource.Ipc, Key:key));
|
_stateManager.ChangeEquip(state, slot, item, stainId,
|
||||||
|
new ApplySettings(Source: once ? StateSource.IpcManual : StateSource.IpcFixed, Key: key));
|
||||||
return GlamourerErrorCode.Success;
|
return GlamourerErrorCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private GlamourerErrorCode SetItemByActorName(string name, EquipSlot slot, CustomItemId itemId, StainId stainId, uint key)
|
private GlamourerErrorCode SetItemByActorName(string name, EquipSlot slot, CustomItemId itemId, StainId stainId, uint key, bool once)
|
||||||
{
|
{
|
||||||
if (itemId.Id == 0)
|
if (itemId.Id == 0)
|
||||||
itemId = ItemManager.NothingId(slot);
|
itemId = ItemManager.NothingId(slot);
|
||||||
|
|
@ -84,7 +95,8 @@ public partial class GlamourerIpc
|
||||||
if (!state.ModelData.IsHuman)
|
if (!state.ModelData.IsHuman)
|
||||||
return GlamourerErrorCode.ActorNotHuman;
|
return GlamourerErrorCode.ActorNotHuman;
|
||||||
|
|
||||||
_stateManager.ChangeEquip(state, slot, item, stainId, new ApplySettings(Source: StateSource.Ipc, Key: key));
|
_stateManager.ChangeEquip(state, slot, item, stainId,
|
||||||
|
new ApplySettings(Source: once ? StateSource.IpcManual : StateSource.IpcFixed, Key: key));
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,11 @@ public sealed partial class GlamourerIpc : IDisposable
|
||||||
_getAllCustomizationFromCharacterProvider =
|
_getAllCustomizationFromCharacterProvider =
|
||||||
new FuncProvider<Character?, string?>(pi, LabelGetAllCustomizationFromCharacter, GetAllCustomizationFromCharacter);
|
new FuncProvider<Character?, string?>(pi, LabelGetAllCustomizationFromCharacter, GetAllCustomizationFromCharacter);
|
||||||
|
|
||||||
_applyAllProvider = new ActionProvider<string, string>(pi, LabelApplyAll, ApplyAll);
|
_applyAllProvider = new ActionProvider<string, string>(pi, LabelApplyAll, ApplyAll);
|
||||||
_applyAllToCharacterProvider = new ActionProvider<string, Character?>(pi, LabelApplyAllToCharacter, ApplyAllToCharacter);
|
_applyAllOnceProvider = new ActionProvider<string, string>(pi, LabelApplyAll, ApplyAllOnce);
|
||||||
_applyOnlyEquipmentProvider = new ActionProvider<string, string>(pi, LabelApplyOnlyEquipment, ApplyOnlyEquipment);
|
_applyAllToCharacterProvider = new ActionProvider<string, Character?>(pi, LabelApplyAllToCharacter, ApplyAllToCharacter);
|
||||||
|
_applyAllOnceToCharacterProvider = new ActionProvider<string, Character?>(pi, LabelApplyAllToCharacter, ApplyAllOnceToCharacter);
|
||||||
|
_applyOnlyEquipmentProvider = new ActionProvider<string, string>(pi, LabelApplyOnlyEquipment, ApplyOnlyEquipment);
|
||||||
_applyOnlyEquipmentToCharacterProvider =
|
_applyOnlyEquipmentToCharacterProvider =
|
||||||
new ActionProvider<string, Character?>(pi, LabelApplyOnlyEquipmentToCharacter, ApplyOnlyEquipmentToCharacter);
|
new ActionProvider<string, Character?>(pi, LabelApplyOnlyEquipmentToCharacter, ApplyOnlyEquipmentToCharacter);
|
||||||
_applyOnlyCustomizationProvider = new ActionProvider<string, string>(pi, LabelApplyOnlyCustomization, ApplyOnlyCustomization);
|
_applyOnlyCustomizationProvider = new ActionProvider<string, string>(pi, LabelApplyOnlyCustomization, ApplyOnlyCustomization);
|
||||||
|
|
@ -66,8 +68,11 @@ public sealed partial class GlamourerIpc : IDisposable
|
||||||
_applyOnlyCustomizationToCharacterProviderLock =
|
_applyOnlyCustomizationToCharacterProviderLock =
|
||||||
new ActionProvider<string, Character?, uint>(pi, LabelApplyOnlyCustomizationToCharacterLock, ApplyOnlyCustomizationToCharacterLock);
|
new ActionProvider<string, Character?, uint>(pi, LabelApplyOnlyCustomizationToCharacterLock, ApplyOnlyCustomizationToCharacterLock);
|
||||||
|
|
||||||
_applyByGuidProvider = new ActionProvider<Guid, string>(pi, LabelApplyByGuid, ApplyByGuid);
|
_applyByGuidProvider = new ActionProvider<Guid, string>(pi, LabelApplyByGuid, ApplyByGuid);
|
||||||
|
_applyByGuidOnceProvider = new ActionProvider<Guid, string>(pi, LabelApplyByGuidOnce, ApplyByGuidOnce);
|
||||||
_applyByGuidToCharacterProvider = new ActionProvider<Guid, Character?>(pi, LabelApplyByGuidToCharacter, ApplyByGuidToCharacter);
|
_applyByGuidToCharacterProvider = new ActionProvider<Guid, Character?>(pi, LabelApplyByGuidToCharacter, ApplyByGuidToCharacter);
|
||||||
|
_applyByGuidOnceToCharacterProvider =
|
||||||
|
new ActionProvider<Guid, Character?>(pi, LabelApplyByGuidOnceToCharacter, ApplyByGuidOnceToCharacter);
|
||||||
|
|
||||||
_revertProvider = new ActionProvider<string>(pi, LabelRevert, Revert);
|
_revertProvider = new ActionProvider<string>(pi, LabelRevert, Revert);
|
||||||
_revertCharacterProvider = new ActionProvider<Character?>(pi, LabelRevertCharacter, RevertCharacter);
|
_revertCharacterProvider = new ActionProvider<Character?>(pi, LabelRevertCharacter, RevertCharacter);
|
||||||
|
|
@ -83,9 +88,14 @@ public sealed partial class GlamourerIpc : IDisposable
|
||||||
_gPoseChangedProvider = new EventProvider<bool>(pi, LabelGPoseChanged);
|
_gPoseChangedProvider = new EventProvider<bool>(pi, LabelGPoseChanged);
|
||||||
|
|
||||||
_setItemProvider = new FuncProvider<Character?, byte, ulong, byte, uint, int>(pi, LabelSetItem,
|
_setItemProvider = new FuncProvider<Character?, byte, ulong, byte, uint, int>(pi, LabelSetItem,
|
||||||
(idx, slot, item, stain, key) => (int)SetItem(idx, (EquipSlot)slot, item, stain, key));
|
(idx, slot, item, stain, key) => (int)SetItem(idx, (EquipSlot)slot, item, stain, key, false));
|
||||||
_setItemByActorNameProvider = new FuncProvider<string, byte, ulong, byte, uint, int>(pi, LabelSetItemByActorName,
|
_setItemOnceProvider = new FuncProvider<Character?, byte, ulong, byte, uint, int>(pi, LabelSetItem,
|
||||||
(name, slot, item, stain, key) => (int)SetItemByActorName(name, (EquipSlot)slot, item, stain, key));
|
(idx, slot, item, stain, key) => (int)SetItem(idx, (EquipSlot)slot, item, stain, key, true));
|
||||||
|
|
||||||
|
_setItemByActorNameProvider = new FuncProvider<string, byte, ulong, byte, uint, int>(pi, LabelSetItemOnceByActorName,
|
||||||
|
(name, slot, item, stain, key) => (int)SetItemByActorName(name, (EquipSlot)slot, item, stain, key, false));
|
||||||
|
_setItemOnceByActorNameProvider = new FuncProvider<string, byte, ulong, byte, uint, int>(pi, LabelSetItemOnceByActorName,
|
||||||
|
(name, slot, item, stain, key) => (int)SetItemByActorName(name, (EquipSlot)slot, item, stain, key, true));
|
||||||
|
|
||||||
_stateChangedEvent.Subscribe(OnStateChanged, StateChanged.Priority.GlamourerIpc);
|
_stateChangedEvent.Subscribe(OnStateChanged, StateChanged.Priority.GlamourerIpc);
|
||||||
_gPose.Subscribe(OnGPoseChanged, GPoseService.Priority.GlamourerIpc);
|
_gPose.Subscribe(OnGPoseChanged, GPoseService.Priority.GlamourerIpc);
|
||||||
|
|
@ -102,7 +112,9 @@ public sealed partial class GlamourerIpc : IDisposable
|
||||||
_getAllCustomizationFromCharacterProvider.Dispose();
|
_getAllCustomizationFromCharacterProvider.Dispose();
|
||||||
|
|
||||||
_applyAllProvider.Dispose();
|
_applyAllProvider.Dispose();
|
||||||
|
_applyAllOnceProvider.Dispose();
|
||||||
_applyAllToCharacterProvider.Dispose();
|
_applyAllToCharacterProvider.Dispose();
|
||||||
|
_applyAllOnceToCharacterProvider.Dispose();
|
||||||
_applyOnlyEquipmentProvider.Dispose();
|
_applyOnlyEquipmentProvider.Dispose();
|
||||||
_applyOnlyEquipmentToCharacterProvider.Dispose();
|
_applyOnlyEquipmentToCharacterProvider.Dispose();
|
||||||
_applyOnlyCustomizationProvider.Dispose();
|
_applyOnlyCustomizationProvider.Dispose();
|
||||||
|
|
@ -113,8 +125,11 @@ public sealed partial class GlamourerIpc : IDisposable
|
||||||
_applyOnlyEquipmentToCharacterProviderLock.Dispose();
|
_applyOnlyEquipmentToCharacterProviderLock.Dispose();
|
||||||
_applyOnlyCustomizationProviderLock.Dispose();
|
_applyOnlyCustomizationProviderLock.Dispose();
|
||||||
_applyOnlyCustomizationToCharacterProviderLock.Dispose();
|
_applyOnlyCustomizationToCharacterProviderLock.Dispose();
|
||||||
|
|
||||||
_applyByGuidProvider.Dispose();
|
_applyByGuidProvider.Dispose();
|
||||||
|
_applyByGuidOnceProvider.Dispose();
|
||||||
_applyByGuidToCharacterProvider.Dispose();
|
_applyByGuidToCharacterProvider.Dispose();
|
||||||
|
_applyByGuidOnceToCharacterProvider.Dispose();
|
||||||
|
|
||||||
_revertProvider.Dispose();
|
_revertProvider.Dispose();
|
||||||
_revertCharacterProvider.Dispose();
|
_revertCharacterProvider.Dispose();
|
||||||
|
|
@ -133,7 +148,9 @@ public sealed partial class GlamourerIpc : IDisposable
|
||||||
_getDesignListProvider.Dispose();
|
_getDesignListProvider.Dispose();
|
||||||
|
|
||||||
_setItemProvider.Dispose();
|
_setItemProvider.Dispose();
|
||||||
|
_setItemOnceProvider.Dispose();
|
||||||
_setItemByActorNameProvider.Dispose();
|
_setItemByActorNameProvider.Dispose();
|
||||||
|
_setItemOnceByActorNameProvider.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<ActorIdentifier> FindActors(string actorName)
|
private IEnumerable<ActorIdentifier> FindActors(string actorName)
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ public class Configuration : IPluginConfiguration, ISavable
|
||||||
public bool UseRgbForColors { get; set; } = true;
|
public bool UseRgbForColors { get; set; } = true;
|
||||||
public bool ShowColorConfig { get; set; } = true;
|
public bool ShowColorConfig { get; set; } = true;
|
||||||
public bool ChangeEntireItem { get; set; } = false;
|
public bool ChangeEntireItem { get; set; } = false;
|
||||||
|
public bool AlwaysApplyAssociatedMods { get; set; } = false;
|
||||||
public ModifiableHotkey ToggleQuickDesignBar { get; set; } = new(VirtualKey.NO_KEY);
|
public ModifiableHotkey ToggleQuickDesignBar { get; set; } = new(VirtualKey.NO_KEY);
|
||||||
public DoubleModifier DeleteDesignModifier { get; set; } = new(ModifierHotkey.Control, ModifierHotkey.Shift);
|
public DoubleModifier DeleteDesignModifier { get; set; } = new(ModifierHotkey.Control, ModifierHotkey.Shift);
|
||||||
public ChangeLogDisplayType ChangeLogDisplayType { get; set; } = ChangeLogDisplayType.New;
|
public ChangeLogDisplayType ChangeLogDisplayType { get; set; } = ChangeLogDisplayType.New;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Glamourer.GameData;
|
using Glamourer.GameData;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.Events;
|
|
||||||
using Glamourer.Interop;
|
using Glamourer.Interop;
|
||||||
using Glamourer.Interop.Structs;
|
using Glamourer.Interop.Structs;
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,9 @@ public class IpcTesterPanel(DalamudPluginInterface _pluginInterface, ObjectManag
|
||||||
private string _base64Apply = string.Empty;
|
private string _base64Apply = string.Empty;
|
||||||
private string _designIdentifier = string.Empty;
|
private string _designIdentifier = string.Empty;
|
||||||
private GlamourerIpc.GlamourerErrorCode _setItemEc;
|
private GlamourerIpc.GlamourerErrorCode _setItemEc;
|
||||||
|
private GlamourerIpc.GlamourerErrorCode _setItemOnceEc;
|
||||||
private GlamourerIpc.GlamourerErrorCode _setItemByActorNameEc;
|
private GlamourerIpc.GlamourerErrorCode _setItemByActorNameEc;
|
||||||
|
private GlamourerIpc.GlamourerErrorCode _setItemOnceByActorNameEc;
|
||||||
|
|
||||||
public unsafe void Draw()
|
public unsafe void Draw()
|
||||||
{
|
{
|
||||||
|
|
@ -77,12 +79,23 @@ public class IpcTesterPanel(DalamudPluginInterface _pluginInterface, ObjectManag
|
||||||
if (ImGui.Button("Apply##AllName"))
|
if (ImGui.Button("Apply##AllName"))
|
||||||
GlamourerIpc.ApplyAllSubscriber(_pluginInterface).Invoke(_base64Apply, _gameObjectName);
|
GlamourerIpc.ApplyAllSubscriber(_pluginInterface).Invoke(_base64Apply, _gameObjectName);
|
||||||
|
|
||||||
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyAllOnce);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
if (ImGui.Button("Apply Once##AllName"))
|
||||||
|
GlamourerIpc.ApplyAllOnceSubscriber(_pluginInterface).Invoke(_base64Apply, _gameObjectName);
|
||||||
|
|
||||||
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyAllToCharacter);
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyAllToCharacter);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
if (ImGui.Button("Apply##AllCharacter"))
|
if (ImGui.Button("Apply##AllCharacter"))
|
||||||
GlamourerIpc.ApplyAllToCharacterSubscriber(_pluginInterface)
|
GlamourerIpc.ApplyAllToCharacterSubscriber(_pluginInterface)
|
||||||
.Invoke(_base64Apply, _objectManager.Objects[_gameObjectIndex] as Character);
|
.Invoke(_base64Apply, _objectManager.Objects[_gameObjectIndex] as Character);
|
||||||
|
|
||||||
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyAllOnceToCharacter);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
if (ImGui.Button("Apply Once##AllCharacter"))
|
||||||
|
GlamourerIpc.ApplyAllOnceToCharacterSubscriber(_pluginInterface)
|
||||||
|
.Invoke(_base64Apply, _objectManager.Objects[_gameObjectIndex] as Character);
|
||||||
|
|
||||||
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyOnlyEquipment);
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyOnlyEquipment);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
if (ImGui.Button("Apply##EquipName"))
|
if (ImGui.Button("Apply##EquipName"))
|
||||||
|
|
@ -111,12 +124,23 @@ public class IpcTesterPanel(DalamudPluginInterface _pluginInterface, ObjectManag
|
||||||
if (ImGui.Button("Apply##ByGuidName") && Guid.TryParse(_designIdentifier, out var guid1))
|
if (ImGui.Button("Apply##ByGuidName") && Guid.TryParse(_designIdentifier, out var guid1))
|
||||||
GlamourerIpc.ApplyByGuidSubscriber(_pluginInterface).Invoke(guid1, _gameObjectName);
|
GlamourerIpc.ApplyByGuidSubscriber(_pluginInterface).Invoke(guid1, _gameObjectName);
|
||||||
|
|
||||||
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyByGuidOnce);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
if (ImGui.Button("Apply Once##ByGuidName") && Guid.TryParse(_designIdentifier, out var guid1Once))
|
||||||
|
GlamourerIpc.ApplyByGuidOnceSubscriber(_pluginInterface).Invoke(guid1Once, _gameObjectName);
|
||||||
|
|
||||||
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyByGuidToCharacter);
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyByGuidToCharacter);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
if (ImGui.Button("Apply##ByGuidCharacter") && Guid.TryParse(_designIdentifier, out var guid2))
|
if (ImGui.Button("Apply##ByGuidCharacter") && Guid.TryParse(_designIdentifier, out var guid2))
|
||||||
GlamourerIpc.ApplyByGuidToCharacterSubscriber(_pluginInterface)
|
GlamourerIpc.ApplyByGuidToCharacterSubscriber(_pluginInterface)
|
||||||
.Invoke(guid2, _objectManager.Objects[_gameObjectIndex] as Character);
|
.Invoke(guid2, _objectManager.Objects[_gameObjectIndex] as Character);
|
||||||
|
|
||||||
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyByGuidOnceToCharacter);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
if (ImGui.Button("Apply Once##ByGuidCharacter") && Guid.TryParse(_designIdentifier, out var guid2Once))
|
||||||
|
GlamourerIpc.ApplyByGuidOnceToCharacterSubscriber(_pluginInterface)
|
||||||
|
.Invoke(guid2Once, _objectManager.Objects[_gameObjectIndex] as Character);
|
||||||
|
|
||||||
|
|
||||||
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelUnlock);
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelUnlock);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
|
@ -149,6 +173,17 @@ public class IpcTesterPanel(DalamudPluginInterface _pluginInterface, ObjectManag
|
||||||
ImGui.TextUnformatted(_setItemEc.ToString());
|
ImGui.TextUnformatted(_setItemEc.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelSetItemOnce);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
if (ImGui.Button("Set Once##SetItem"))
|
||||||
|
_setItemOnceEc = (GlamourerIpc.GlamourerErrorCode)GlamourerIpc.SetItemOnceSubscriber(_pluginInterface)
|
||||||
|
.Invoke(_objectManager.Objects[_gameObjectIndex] as Character, (byte)_slot, _customItemId.Id, _stainId.Id, 1337);
|
||||||
|
if (_setItemOnceEc != GlamourerIpc.GlamourerErrorCode.Success)
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.TextUnformatted(_setItemOnceEc.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelSetItemByActorName);
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelSetItemByActorName);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
if (ImGui.Button("Set##SetItemByActorName"))
|
if (ImGui.Button("Set##SetItemByActorName"))
|
||||||
|
|
@ -159,6 +194,17 @@ public class IpcTesterPanel(DalamudPluginInterface _pluginInterface, ObjectManag
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
ImGui.TextUnformatted(_setItemByActorNameEc.ToString());
|
ImGui.TextUnformatted(_setItemByActorNameEc.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelSetItemOnceByActorName);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
if (ImGui.Button("Set Once##SetItemByActorName"))
|
||||||
|
_setItemOnceByActorNameEc = (GlamourerIpc.GlamourerErrorCode)GlamourerIpc.SetItemOnceByActorNameSubscriber(_pluginInterface)
|
||||||
|
.Invoke(_gameObjectName, (byte)_slot, _customItemId.Id, _stainId.Id, 1337);
|
||||||
|
if (_setItemOnceByActorNameEc != GlamourerIpc.GlamourerErrorCode.Success)
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.TextUnformatted(_setItemOnceByActorNameEc.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawItemInput()
|
private void DrawItemInput()
|
||||||
|
|
|
||||||
|
|
@ -95,9 +95,13 @@ public class DesignDetailTab
|
||||||
Glamourer.Messager.NotificationMessage(ex, $"Could not open file {fileName}.", $"Could not open file {fileName}",
|
Glamourer.Messager.NotificationMessage(ex, $"Could not open file {fileName}.", $"Could not open file {fileName}",
|
||||||
NotificationType.Warning);
|
NotificationType.Warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||||
|
ImGui.SetClipboardText(identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiUtil.HoverTooltip($"Open the file\n\t{fileName}\ncontaining this design in the .json-editor of your choice.");
|
ImGuiUtil.HoverTooltip(
|
||||||
|
$"Open the file\n\t{fileName}\ncontaining this design in the .json-editor of your choice.\n\nRight-Click to copy identifier to clipboard.");
|
||||||
|
|
||||||
ImGuiUtil.DrawFrameColumn("Full Selector Path");
|
ImGuiUtil.DrawFrameColumn("Full Selector Path");
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
|
@ -131,9 +135,10 @@ public class DesignDetailTab
|
||||||
colorName = _colorCombo.CurrentSelection is DesignColors.AutomaticName ? string.Empty : _colorCombo.CurrentSelection;
|
colorName = _colorCombo.CurrentSelection is DesignColors.AutomaticName ? string.Empty : _colorCombo.CurrentSelection;
|
||||||
_manager.ChangeColor(_selector.Selected!, colorName);
|
_manager.ChangeColor(_selector.Selected!, colorName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||||
_manager.ChangeColor(_selector.Selected!, string.Empty);
|
_manager.ChangeColor(_selector.Selected!, string.Empty);
|
||||||
|
|
||||||
if (_colors.TryGetValue(_selector.Selected!.Color, out var currentColor))
|
if (_colors.TryGetValue(_selector.Selected!.Color, out var currentColor))
|
||||||
{
|
{
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,11 @@ public class SettingsTab(
|
||||||
Checkbox("Enable Advanced Customization Options",
|
Checkbox("Enable Advanced Customization Options",
|
||||||
"Enable the display and editing of advanced customization options like arbitrary colors.",
|
"Enable the display and editing of advanced customization options like arbitrary colors.",
|
||||||
config.UseAdvancedParameters, paletteChecker.SetAdvancedParameters);
|
config.UseAdvancedParameters, paletteChecker.SetAdvancedParameters);
|
||||||
|
Checkbox("Always Apply Associated Mods",
|
||||||
|
"Whenever a design is applied to a character (including via automation), Glamourer will try to apply its associated mod settings to the collection currently associated with that character, if it is available.\n\n"
|
||||||
|
+ "Glamourer will NOT revert these applied settings automatically. This may mess up your collection and configuration.\n\n"
|
||||||
|
+ "If you enable this setting, you are aware that any resulting misconfiguration is your own fault.",
|
||||||
|
config.AlwaysApplyAssociatedMods, v => config.AlwaysApplyAssociatedMods = v);
|
||||||
PaletteImportButton();
|
PaletteImportButton();
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -131,19 +131,16 @@ public sealed unsafe class MaterialManager : IRequiredService, IDisposable
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (source)
|
switch (source.Base())
|
||||||
{
|
{
|
||||||
case StateSource.Manual:
|
case StateSource.Manual:
|
||||||
case StateSource.Pending:
|
|
||||||
state.Materials.RemoveValue(idx);
|
state.Materials.RemoveValue(idx);
|
||||||
--i;
|
--i;
|
||||||
break;
|
break;
|
||||||
case StateSource.Ipc:
|
|
||||||
case StateSource.Fixed:
|
case StateSource.Fixed:
|
||||||
idx.DataIndex.SetValue(ref row, model);
|
idx.DataIndex.SetValue(ref row, model);
|
||||||
state.Materials.UpdateValue(idx, new MaterialValueState(newGame, model, source), out _);
|
state.Materials.UpdateValue(idx, new MaterialValueState(newGame, model, source), out _);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -118,8 +118,7 @@ public class StateApplier(
|
||||||
// If the source is not IPC we do not want to apply restrictions.
|
// If the source is not IPC we do not want to apply restrictions.
|
||||||
var data = GetData(state);
|
var data = GetData(state);
|
||||||
if (apply)
|
if (apply)
|
||||||
ChangeArmor(data, slot, state.ModelData.Armor(slot), state.Sources[slot, false] is not StateSource.Ipc,
|
ChangeArmor(data, slot, state.ModelData.Armor(slot), !state.Sources[slot, false].IsIpc(), state.ModelData.IsHatVisible());
|
||||||
state.ModelData.IsHatVisible());
|
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
@ -267,7 +266,7 @@ public class StateApplier(
|
||||||
actor.Model.ApplyParameterData(flags, values);
|
actor.Model.ApplyParameterData(flags, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="ChangeParameters(ActorData,CustomizeParameterFlag,in CustomizeParameterData)"/>
|
/// <inheritdoc cref="ChangeParameters(ActorData,CustomizeParameterFlag,in CustomizeParameterData,bool)"/>
|
||||||
public ActorData ChangeParameters(ActorState state, CustomizeParameterFlag flags, bool apply)
|
public ActorData ChangeParameters(ActorState state, CustomizeParameterFlag flags, bool apply)
|
||||||
{
|
{
|
||||||
var data = GetData(state);
|
var data = GetData(state);
|
||||||
|
|
@ -294,10 +293,7 @@ public class StateApplier(
|
||||||
{
|
{
|
||||||
ChangeCustomize(actors, state.ModelData.Customize);
|
ChangeCustomize(actors, state.ModelData.Customize);
|
||||||
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
||||||
{
|
ChangeArmor(actors, slot, state.ModelData.Armor(slot), !state.Sources[slot, false].IsIpc(), state.ModelData.IsHatVisible());
|
||||||
ChangeArmor(actors, slot, state.ModelData.Armor(slot), state.Sources[slot, false] is not StateSource.Ipc,
|
|
||||||
state.ModelData.IsHatVisible());
|
|
||||||
}
|
|
||||||
|
|
||||||
var mainhandActors = state.ModelData.MainhandType != state.BaseData.MainhandType ? actors.OnlyGPose() : actors;
|
var mainhandActors = state.ModelData.MainhandType != state.BaseData.MainhandType ? actors.OnlyGPose() : actors;
|
||||||
ChangeMainhand(mainhandActors, state.ModelData.Item(EquipSlot.MainHand), state.ModelData.Stain(EquipSlot.MainHand));
|
ChangeMainhand(mainhandActors, state.ModelData.Item(EquipSlot.MainHand), state.ModelData.Stain(EquipSlot.MainHand));
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ public class StateEditor(
|
||||||
if (!Editor.ChangeModelId(state, modelId, customize, equipData, source, out var old, key))
|
if (!Editor.ChangeModelId(state, modelId, customize, equipData, source, out var old, key))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var actors = Applier.ForceRedraw(state, source is StateSource.Manual or StateSource.Ipc);
|
var actors = Applier.ForceRedraw(state, source.RequiresChange());
|
||||||
Glamourer.Log.Verbose(
|
Glamourer.Log.Verbose(
|
||||||
$"Set model id in state {state.Identifier.Incognito(null)} from {old} to {modelId}. [Affecting {actors.ToLazyString("nothing")}.]");
|
$"Set model id in state {state.Identifier.Incognito(null)} from {old} to {modelId}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||||
StateChanged.Invoke(StateChanged.Type.Model, source, state, actors, (old, modelId));
|
StateChanged.Invoke(StateChanged.Type.Model, source, state, actors, (old, modelId));
|
||||||
|
|
@ -44,7 +44,7 @@ public class StateEditor(
|
||||||
if (!Editor.ChangeCustomize(state, idx, value, settings.Source, out var old, settings.Key))
|
if (!Editor.ChangeCustomize(state, idx, value, settings.Source, out var old, settings.Key))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var actors = Applier.ChangeCustomize(state, settings.Source is StateSource.Manual or StateSource.Ipc);
|
var actors = Applier.ChangeCustomize(state, settings.Source.RequiresChange());
|
||||||
Glamourer.Log.Verbose(
|
Glamourer.Log.Verbose(
|
||||||
$"Set {idx.ToDefaultName()} customizations in state {state.Identifier.Incognito(null)} from {old.Value} to {value.Value}. [Affecting {actors.ToLazyString("nothing")}.]");
|
$"Set {idx.ToDefaultName()} customizations in state {state.Identifier.Incognito(null)} from {old.Value} to {value.Value}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||||
StateChanged.Invoke(StateChanged.Type.Customize, settings.Source, state, actors, (old, value, idx));
|
StateChanged.Invoke(StateChanged.Type.Customize, settings.Source, state, actors, (old, value, idx));
|
||||||
|
|
@ -57,7 +57,7 @@ public class StateEditor(
|
||||||
if (!Editor.ChangeHumanCustomize(state, customizeInput, apply, _ => settings.Source, out var old, out var applied, settings.Key))
|
if (!Editor.ChangeHumanCustomize(state, customizeInput, apply, _ => settings.Source, out var old, out var applied, settings.Key))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var actors = Applier.ChangeCustomize(state, settings.Source is StateSource.Manual or StateSource.Ipc);
|
var actors = Applier.ChangeCustomize(state, settings.Source.RequiresChange());
|
||||||
Glamourer.Log.Verbose(
|
Glamourer.Log.Verbose(
|
||||||
$"Set {applied} customizations in state {state.Identifier.Incognito(null)} from {old} to {customizeInput}. [Affecting {actors.ToLazyString("nothing")}.]");
|
$"Set {applied} customizations in state {state.Identifier.Incognito(null)} from {old} to {customizeInput}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||||
StateChanged.Invoke(StateChanged.Type.EntireCustomize, settings.Source, state, actors, (old, applied));
|
StateChanged.Invoke(StateChanged.Type.EntireCustomize, settings.Source, state, actors, (old, applied));
|
||||||
|
|
@ -72,8 +72,8 @@ public class StateEditor(
|
||||||
|
|
||||||
var type = slot.ToIndex() < 10 ? StateChanged.Type.Equip : StateChanged.Type.Weapon;
|
var type = slot.ToIndex() < 10 ? StateChanged.Type.Equip : StateChanged.Type.Weapon;
|
||||||
var actors = type is StateChanged.Type.Equip
|
var actors = type is StateChanged.Type.Equip
|
||||||
? Applier.ChangeArmor(state, slot, settings.Source is StateSource.Manual or StateSource.Ipc)
|
? Applier.ChangeArmor(state, slot, settings.Source.RequiresChange())
|
||||||
: Applier.ChangeWeapon(state, slot, settings.Source is StateSource.Manual or StateSource.Ipc,
|
: Applier.ChangeWeapon(state, slot, settings.Source.RequiresChange(),
|
||||||
item.Type != (slot is EquipSlot.MainHand ? state.BaseData.MainhandType : state.BaseData.OffhandType));
|
item.Type != (slot is EquipSlot.MainHand ? state.BaseData.MainhandType : state.BaseData.OffhandType));
|
||||||
|
|
||||||
if (slot is EquipSlot.MainHand)
|
if (slot is EquipSlot.MainHand)
|
||||||
|
|
@ -105,8 +105,8 @@ public class StateEditor(
|
||||||
|
|
||||||
var type = slot.ToIndex() < 10 ? StateChanged.Type.Equip : StateChanged.Type.Weapon;
|
var type = slot.ToIndex() < 10 ? StateChanged.Type.Equip : StateChanged.Type.Weapon;
|
||||||
var actors = type is StateChanged.Type.Equip
|
var actors = type is StateChanged.Type.Equip
|
||||||
? Applier.ChangeArmor(state, slot, settings.Source is StateSource.Manual or StateSource.Ipc)
|
? Applier.ChangeArmor(state, slot, settings.Source.RequiresChange())
|
||||||
: Applier.ChangeWeapon(state, slot, settings.Source is StateSource.Manual or StateSource.Ipc,
|
: Applier.ChangeWeapon(state, slot, settings.Source.RequiresChange(),
|
||||||
item!.Value.Type != (slot is EquipSlot.MainHand ? state.BaseData.MainhandType : state.BaseData.OffhandType));
|
item!.Value.Type != (slot is EquipSlot.MainHand ? state.BaseData.MainhandType : state.BaseData.OffhandType));
|
||||||
|
|
||||||
if (slot is EquipSlot.MainHand)
|
if (slot is EquipSlot.MainHand)
|
||||||
|
|
@ -125,7 +125,7 @@ public class StateEditor(
|
||||||
if (!Editor.ChangeStain(state, slot, stain, settings.Source, out var old, settings.Key))
|
if (!Editor.ChangeStain(state, slot, stain, settings.Source, out var old, settings.Key))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var actors = Applier.ChangeStain(state, slot, settings.Source is StateSource.Manual or StateSource.Ipc);
|
var actors = Applier.ChangeStain(state, slot, settings.Source.RequiresChange());
|
||||||
Glamourer.Log.Verbose(
|
Glamourer.Log.Verbose(
|
||||||
$"Set {slot.ToName()} stain in state {state.Identifier.Incognito(null)} from {old.Id} to {stain.Id}. [Affecting {actors.ToLazyString("nothing")}.]");
|
$"Set {slot.ToName()} stain in state {state.Identifier.Incognito(null)} from {old.Id} to {stain.Id}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||||
StateChanged.Invoke(StateChanged.Type.Stain, settings.Source, state, actors, (old, stain, slot));
|
StateChanged.Invoke(StateChanged.Type.Stain, settings.Source, state, actors, (old, stain, slot));
|
||||||
|
|
@ -138,7 +138,7 @@ public class StateEditor(
|
||||||
if (!Editor.ChangeCrest(state, slot, crest, settings.Source, out var old, settings.Key))
|
if (!Editor.ChangeCrest(state, slot, crest, settings.Source, out var old, settings.Key))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var actors = Applier.ChangeCrests(state, settings.Source is StateSource.Manual or StateSource.Ipc);
|
var actors = Applier.ChangeCrests(state, settings.Source.RequiresChange());
|
||||||
Glamourer.Log.Verbose(
|
Glamourer.Log.Verbose(
|
||||||
$"Set {slot.ToLabel()} crest in state {state.Identifier.Incognito(null)} from {old} to {crest}. [Affecting {actors.ToLazyString("nothing")}.]");
|
$"Set {slot.ToLabel()} crest in state {state.Identifier.Incognito(null)} from {old} to {crest}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||||
StateChanged.Invoke(StateChanged.Type.Crest, settings.Source, state, actors, (old, crest, slot));
|
StateChanged.Invoke(StateChanged.Type.Crest, settings.Source, state, actors, (old, crest, slot));
|
||||||
|
|
@ -158,7 +158,7 @@ public class StateEditor(
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var @new = state.ModelData.Parameters[flag];
|
var @new = state.ModelData.Parameters[flag];
|
||||||
var actors = Applier.ChangeParameters(state, flag, settings.Source is StateSource.Manual or StateSource.Ipc);
|
var actors = Applier.ChangeParameters(state, flag, settings.Source.RequiresChange());
|
||||||
Glamourer.Log.Verbose(
|
Glamourer.Log.Verbose(
|
||||||
$"Set {flag} crest in state {state.Identifier.Incognito(null)} from {old} to {@new}. [Affecting {actors.ToLazyString("nothing")}.]");
|
$"Set {flag} crest in state {state.Identifier.Incognito(null)} from {old} to {@new}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||||
StateChanged.Invoke(StateChanged.Type.Parameter, settings.Source, state, actors, (old, @new, flag));
|
StateChanged.Invoke(StateChanged.Type.Parameter, settings.Source, state, actors, (old, @new, flag));
|
||||||
|
|
@ -171,7 +171,7 @@ public class StateEditor(
|
||||||
if (!Editor.ChangeMetaState(state, index, value, settings.Source, out var old, settings.Key))
|
if (!Editor.ChangeMetaState(state, index, value, settings.Source, out var old, settings.Key))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var actors = Applier.ChangeMetaState(state, index, settings.Source is StateSource.Manual or StateSource.Ipc);
|
var actors = Applier.ChangeMetaState(state, index, settings.Source.RequiresChange());
|
||||||
Glamourer.Log.Verbose(
|
Glamourer.Log.Verbose(
|
||||||
$"Set Head Gear Visibility in state {state.Identifier.Incognito(null)} from {old} to {value}. [Affecting {actors.ToLazyString("nothing")}.]");
|
$"Set Head Gear Visibility in state {state.Identifier.Incognito(null)} from {old} to {value}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||||
StateChanged.Invoke(StateChanged.Type.Other, settings.Source, state, actors, (old, value, MetaIndex.HatState));
|
StateChanged.Invoke(StateChanged.Type.Other, settings.Source, state, actors, (old, value, MetaIndex.HatState));
|
||||||
|
|
@ -191,7 +191,7 @@ public class StateEditor(
|
||||||
{
|
{
|
||||||
foreach (var slot in CrestExtensions.AllRelevantSet.Where(mergedDesign.Design.DoApplyCrest))
|
foreach (var slot in CrestExtensions.AllRelevantSet.Where(mergedDesign.Design.DoApplyCrest))
|
||||||
{
|
{
|
||||||
if (!settings.RespectManual || state.Sources[slot] is not StateSource.Manual)
|
if (!settings.RespectManual || !state.Sources[slot].IsManual())
|
||||||
Editor.ChangeCrest(state, slot, mergedDesign.Design.DesignData.Crest(slot), Source(slot),
|
Editor.ChangeCrest(state, slot, mergedDesign.Design.DesignData.Crest(slot), Source(slot),
|
||||||
out _, settings.Key);
|
out _, settings.Key);
|
||||||
}
|
}
|
||||||
|
|
@ -201,7 +201,7 @@ public class StateEditor(
|
||||||
customizeFlags |= CustomizeFlag.Race;
|
customizeFlags |= CustomizeFlag.Race;
|
||||||
|
|
||||||
Func<CustomizeIndex, bool> applyWhich = settings.RespectManual
|
Func<CustomizeIndex, bool> applyWhich = settings.RespectManual
|
||||||
? i => customizeFlags.HasFlag(i.ToFlag()) && state.Sources[i] is not StateSource.Manual
|
? i => customizeFlags.HasFlag(i.ToFlag()) && !state.Sources[i].IsManual()
|
||||||
: i => customizeFlags.HasFlag(i.ToFlag());
|
: i => customizeFlags.HasFlag(i.ToFlag());
|
||||||
|
|
||||||
if (Editor.ChangeHumanCustomize(state, mergedDesign.Design.DesignData.Customize, applyWhich, i => Source(i), out _, out var changed,
|
if (Editor.ChangeHumanCustomize(state, mergedDesign.Design.DesignData.Customize, applyWhich, i => Source(i), out _, out var changed,
|
||||||
|
|
@ -210,12 +210,10 @@ public class StateEditor(
|
||||||
|
|
||||||
foreach (var parameter in mergedDesign.Design.ApplyParameters.Iterate())
|
foreach (var parameter in mergedDesign.Design.ApplyParameters.Iterate())
|
||||||
{
|
{
|
||||||
if (settings.RespectManual && state.Sources[parameter] is StateSource.Manual or StateSource.Pending)
|
if (settings.RespectManual && state.Sources[parameter].IsManual())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var source = Source(parameter);
|
var source = Source(parameter).SetPending();
|
||||||
if (source is StateSource.Manual)
|
|
||||||
source = StateSource.Pending;
|
|
||||||
Editor.ChangeParameter(state, parameter, mergedDesign.Design.DesignData.Parameters[parameter], source, out _, settings.Key);
|
Editor.ChangeParameter(state, parameter, mergedDesign.Design.DesignData.Parameters[parameter], source, out _, settings.Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -228,12 +226,12 @@ public class StateEditor(
|
||||||
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
||||||
{
|
{
|
||||||
if (mergedDesign.Design.DoApplyEquip(slot))
|
if (mergedDesign.Design.DoApplyEquip(slot))
|
||||||
if (!settings.RespectManual || state.Sources[slot, false] is not StateSource.Manual)
|
if (!settings.RespectManual || !state.Sources[slot, false].IsManual())
|
||||||
Editor.ChangeItem(state, slot, mergedDesign.Design.DesignData.Item(slot),
|
Editor.ChangeItem(state, slot, mergedDesign.Design.DesignData.Item(slot),
|
||||||
Source(slot.ToState()), out _, settings.Key);
|
Source(slot.ToState()), out _, settings.Key);
|
||||||
|
|
||||||
if (mergedDesign.Design.DoApplyStain(slot))
|
if (mergedDesign.Design.DoApplyStain(slot))
|
||||||
if (!settings.RespectManual || state.Sources[slot, true] is not StateSource.Manual)
|
if (!settings.RespectManual || !state.Sources[slot, true].IsManual())
|
||||||
Editor.ChangeStain(state, slot, mergedDesign.Design.DesignData.Stain(slot),
|
Editor.ChangeStain(state, slot, mergedDesign.Design.DesignData.Stain(slot),
|
||||||
Source(slot.ToState(true)), out _, settings.Key);
|
Source(slot.ToState(true)), out _, settings.Key);
|
||||||
}
|
}
|
||||||
|
|
@ -241,14 +239,14 @@ public class StateEditor(
|
||||||
foreach (var weaponSlot in EquipSlotExtensions.WeaponSlots)
|
foreach (var weaponSlot in EquipSlotExtensions.WeaponSlots)
|
||||||
{
|
{
|
||||||
if (mergedDesign.Design.DoApplyStain(weaponSlot))
|
if (mergedDesign.Design.DoApplyStain(weaponSlot))
|
||||||
if (!settings.RespectManual || state.Sources[weaponSlot, true] is not StateSource.Manual)
|
if (!settings.RespectManual || !state.Sources[weaponSlot, true].IsManual())
|
||||||
Editor.ChangeStain(state, weaponSlot, mergedDesign.Design.DesignData.Stain(weaponSlot),
|
Editor.ChangeStain(state, weaponSlot, mergedDesign.Design.DesignData.Stain(weaponSlot),
|
||||||
Source(weaponSlot.ToState(true)), out _, settings.Key);
|
Source(weaponSlot.ToState(true)), out _, settings.Key);
|
||||||
|
|
||||||
if (!mergedDesign.Design.DoApplyEquip(weaponSlot))
|
if (!mergedDesign.Design.DoApplyEquip(weaponSlot))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (settings.RespectManual && state.Sources[weaponSlot, false] is StateSource.Manual)
|
if (settings.RespectManual && !state.Sources[weaponSlot, false].IsManual())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var currentType = state.ModelData.Item(weaponSlot).Type;
|
var currentType = state.ModelData.Item(weaponSlot).Type;
|
||||||
|
|
@ -268,12 +266,12 @@ public class StateEditor(
|
||||||
|
|
||||||
foreach (var meta in MetaExtensions.AllRelevant)
|
foreach (var meta in MetaExtensions.AllRelevant)
|
||||||
{
|
{
|
||||||
if (!settings.RespectManual || state.Sources[meta] is not StateSource.Manual)
|
if (!settings.RespectManual || !state.Sources[meta].IsManual())
|
||||||
Editor.ChangeMetaState(state, meta, mergedDesign.Design.DesignData.GetMeta(meta), Source(meta), out _, settings.Key);
|
Editor.ChangeMetaState(state, meta, mergedDesign.Design.DesignData.GetMeta(meta), Source(meta), out _, settings.Key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var actors = settings.Source is StateSource.Manual or StateSource.Ipc
|
var actors = settings.Source.RequiresChange()
|
||||||
? Applier.ApplyAll(state, requiresRedraw, false)
|
? Applier.ApplyAll(state, requiresRedraw, false)
|
||||||
: ActorData.Invalid;
|
: ActorData.Invalid;
|
||||||
|
|
||||||
|
|
@ -311,7 +309,7 @@ public class StateEditor(
|
||||||
/// <summary> Apply offhand item and potentially gauntlets if configured. </summary>
|
/// <summary> Apply offhand item and potentially gauntlets if configured. </summary>
|
||||||
private void ApplyMainhandPeriphery(ActorState state, EquipItem? newMainhand, ApplySettings settings)
|
private void ApplyMainhandPeriphery(ActorState state, EquipItem? newMainhand, ApplySettings settings)
|
||||||
{
|
{
|
||||||
if (!Config.ChangeEntireItem || settings.Source is not StateSource.Manual)
|
if (!Config.ChangeEntireItem || !settings.Source.IsManual())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var mh = newMainhand ?? state.ModelData.Item(EquipSlot.MainHand);
|
var mh = newMainhand ?? state.ModelData.Item(EquipSlot.MainHand);
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,7 @@ public class StateListener : IDisposable
|
||||||
var set = _customizations.Manager.GetSet(model.Clan, model.Gender);
|
var set = _customizations.Manager.GetSet(model.Clan, model.Gender);
|
||||||
foreach (var index in CustomizationExtensions.AllBasic)
|
foreach (var index in CustomizationExtensions.AllBasic)
|
||||||
{
|
{
|
||||||
if (state.Sources[index] is not StateSource.Fixed)
|
if (!state.Sources[index].IsFixed())
|
||||||
{
|
{
|
||||||
var newValue = customize[index];
|
var newValue = customize[index];
|
||||||
var oldValue = model[index];
|
var oldValue = model[index];
|
||||||
|
|
@ -214,7 +214,7 @@ public class StateListener : IDisposable
|
||||||
&& _manager.TryGetValue(identifier, out var state))
|
&& _manager.TryGetValue(identifier, out var state))
|
||||||
{
|
{
|
||||||
HandleEquipSlot(actor, state, slot, ref armor);
|
HandleEquipSlot(actor, state, slot, ref armor);
|
||||||
locked = state.Sources[slot, false] is StateSource.Ipc;
|
locked = state.Sources[slot, false] is StateSource.IpcFixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
_funModule.ApplyFunToSlot(actor, ref armor, slot);
|
_funModule.ApplyFunToSlot(actor, ref armor, slot);
|
||||||
|
|
@ -241,7 +241,7 @@ public class StateListener : IDisposable
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var changed = changedItem.Weapon(stain);
|
var changed = changedItem.Weapon(stain);
|
||||||
if (current.Value == changed.Value && state.Sources[slot, false] is not StateSource.Fixed and not StateSource.Ipc)
|
if (current.Value == changed.Value && !state.Sources[slot, false].IsFixed())
|
||||||
{
|
{
|
||||||
_manager.ChangeItem(state, slot, currentItem, ApplySettings.Game);
|
_manager.ChangeItem(state, slot, currentItem, ApplySettings.Game);
|
||||||
_manager.ChangeStain(state, slot, current.Stain, ApplySettings.Game);
|
_manager.ChangeStain(state, slot, current.Stain, ApplySettings.Game);
|
||||||
|
|
@ -252,7 +252,7 @@ public class StateListener : IDisposable
|
||||||
_applier.ChangeWeapon(objects, slot, currentItem, stain);
|
_applier.ChangeWeapon(objects, slot, currentItem, stain);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
_applier.ChangeArmor(objects, slot, current.ToArmor(), state.Sources[slot, false] is not StateSource.Ipc,
|
_applier.ChangeArmor(objects, slot, current.ToArmor(), !state.Sources[slot, false].IsFixed(),
|
||||||
state.ModelData.IsHatVisible());
|
state.ModelData.IsHatVisible());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -278,20 +278,19 @@ public class StateListener : IDisposable
|
||||||
|| !_manager.TryGetValue(identifier, out var state))
|
|| !_manager.TryGetValue(identifier, out var state))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ref var actorWeapon = ref weapon;
|
var baseType = state.BaseData.Item(slot).Type;
|
||||||
var baseType = state.BaseData.Item(slot).Type;
|
var apply = false;
|
||||||
var apply = false;
|
switch (UpdateBaseData(actor, state, slot, weapon))
|
||||||
switch (UpdateBaseData(actor, state, slot, actorWeapon))
|
|
||||||
{
|
{
|
||||||
// Do nothing. But this usually can not happen because the hooked function also writes to game objects later.
|
// Do nothing. But this usually can not happen because the hooked function also writes to game objects later.
|
||||||
case UpdateState.Transformed: break;
|
case UpdateState.Transformed: break;
|
||||||
case UpdateState.Change:
|
case UpdateState.Change:
|
||||||
if (state.Sources[slot, false] is not StateSource.Fixed and not StateSource.Ipc)
|
if (!state.Sources[slot, false].IsFixed())
|
||||||
_manager.ChangeItem(state, slot, state.BaseData.Item(slot), ApplySettings.Game);
|
_manager.ChangeItem(state, slot, state.BaseData.Item(slot), ApplySettings.Game);
|
||||||
else
|
else
|
||||||
apply = true;
|
apply = true;
|
||||||
|
|
||||||
if (state.Sources[slot, true] is not StateSource.Fixed and not StateSource.Ipc)
|
if (!state.Sources[slot, true].IsFixed())
|
||||||
_manager.ChangeStain(state, slot, state.BaseData.Stain(slot), ApplySettings.Game);
|
_manager.ChangeStain(state, slot, state.BaseData.Stain(slot), ApplySettings.Game);
|
||||||
else
|
else
|
||||||
apply = true;
|
apply = true;
|
||||||
|
|
@ -306,9 +305,9 @@ public class StateListener : IDisposable
|
||||||
// Only allow overwriting identical weapons
|
// Only allow overwriting identical weapons
|
||||||
var newWeapon = state.ModelData.Weapon(slot);
|
var newWeapon = state.ModelData.Weapon(slot);
|
||||||
if (baseType is FullEquipType.Unknown || baseType == state.ModelData.Item(slot).Type || _gPose.InGPose && actor.IsGPoseOrCutscene)
|
if (baseType is FullEquipType.Unknown || baseType == state.ModelData.Item(slot).Type || _gPose.InGPose && actor.IsGPoseOrCutscene)
|
||||||
actorWeapon = newWeapon;
|
weapon = newWeapon;
|
||||||
else if (actorWeapon.Skeleton.Id != 0)
|
else if (weapon.Skeleton.Id != 0)
|
||||||
actorWeapon = actorWeapon.With(newWeapon.Stain);
|
weapon = weapon.With(newWeapon.Stain);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fist Weapon Offhand hack.
|
// Fist Weapon Offhand hack.
|
||||||
|
|
@ -385,12 +384,12 @@ public class StateListener : IDisposable
|
||||||
// Update model state if not on fixed design.
|
// Update model state if not on fixed design.
|
||||||
case UpdateState.Change:
|
case UpdateState.Change:
|
||||||
var apply = false;
|
var apply = false;
|
||||||
if (state.Sources[slot, false] is not StateSource.Fixed and not StateSource.Ipc)
|
if (!state.Sources[slot, false].IsFixed())
|
||||||
_manager.ChangeItem(state, slot, state.BaseData.Item(slot), ApplySettings.Game);
|
_manager.ChangeItem(state, slot, state.BaseData.Item(slot), ApplySettings.Game);
|
||||||
else
|
else
|
||||||
apply = true;
|
apply = true;
|
||||||
|
|
||||||
if (state.Sources[slot, true] is not StateSource.Fixed and not StateSource.Ipc)
|
if (!state.Sources[slot, true].IsFixed())
|
||||||
_manager.ChangeStain(state, slot, state.BaseData.Stain(slot), ApplySettings.Game);
|
_manager.ChangeStain(state, slot, state.BaseData.Stain(slot), ApplySettings.Game);
|
||||||
else
|
else
|
||||||
apply = true;
|
apply = true;
|
||||||
|
|
@ -419,7 +418,7 @@ public class StateListener : IDisposable
|
||||||
switch (UpdateBaseCrest(actor, state, slot, value))
|
switch (UpdateBaseCrest(actor, state, slot, value))
|
||||||
{
|
{
|
||||||
case UpdateState.Change:
|
case UpdateState.Change:
|
||||||
if (state.Sources[slot] is not StateSource.Fixed and not StateSource.Ipc)
|
if (!state.Sources[slot].IsFixed())
|
||||||
_manager.ChangeCrest(state, slot, state.BaseData.Crest(slot), ApplySettings.Game);
|
_manager.ChangeCrest(state, slot, state.BaseData.Crest(slot), ApplySettings.Game);
|
||||||
else
|
else
|
||||||
value = state.ModelData.Crest(slot);
|
value = state.ModelData.Crest(slot);
|
||||||
|
|
@ -565,7 +564,7 @@ public class StateListener : IDisposable
|
||||||
{
|
{
|
||||||
// if base state changed, either overwrite the actual value if we have fixed values,
|
// if base state changed, either overwrite the actual value if we have fixed values,
|
||||||
// or overwrite the stored model state with the new one.
|
// or overwrite the stored model state with the new one.
|
||||||
if (state.Sources[MetaIndex.VisorState] is StateSource.Fixed or StateSource.Ipc)
|
if (!state.Sources[MetaIndex.VisorState].IsFixed())
|
||||||
value = state.ModelData.IsVisorToggled();
|
value = state.ModelData.IsVisorToggled();
|
||||||
else
|
else
|
||||||
_manager.ChangeMetaState(state, MetaIndex.VisorState, value, ApplySettings.Game);
|
_manager.ChangeMetaState(state, MetaIndex.VisorState, value, ApplySettings.Game);
|
||||||
|
|
@ -598,7 +597,7 @@ public class StateListener : IDisposable
|
||||||
{
|
{
|
||||||
// if base state changed, either overwrite the actual value if we have fixed values,
|
// if base state changed, either overwrite the actual value if we have fixed values,
|
||||||
// or overwrite the stored model state with the new one.
|
// or overwrite the stored model state with the new one.
|
||||||
if (state.Sources[MetaIndex.HatState] is StateSource.Fixed or StateSource.Ipc)
|
if (!state.Sources[MetaIndex.HatState].IsFixed())
|
||||||
value = state.ModelData.IsHatVisible();
|
value = state.ModelData.IsHatVisible();
|
||||||
else
|
else
|
||||||
_manager.ChangeMetaState(state, MetaIndex.HatState, value, ApplySettings.Game);
|
_manager.ChangeMetaState(state, MetaIndex.HatState, value, ApplySettings.Game);
|
||||||
|
|
@ -631,7 +630,7 @@ public class StateListener : IDisposable
|
||||||
{
|
{
|
||||||
// if base state changed, either overwrite the actual value if we have fixed values,
|
// if base state changed, either overwrite the actual value if we have fixed values,
|
||||||
// or overwrite the stored model state with the new one.
|
// or overwrite the stored model state with the new one.
|
||||||
if (state.Sources[MetaIndex.WeaponState] is StateSource.Fixed or StateSource.Ipc)
|
if (!state.Sources[MetaIndex.WeaponState].IsFixed())
|
||||||
value = state.ModelData.IsWeaponVisible();
|
value = state.ModelData.IsWeaponVisible();
|
||||||
else
|
else
|
||||||
_manager.ChangeMetaState(state, MetaIndex.WeaponState, value, ApplySettings.Game);
|
_manager.ChangeMetaState(state, MetaIndex.WeaponState, value, ApplySettings.Game);
|
||||||
|
|
@ -700,8 +699,8 @@ public class StateListener : IDisposable
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var data = new ActorData(gameObject, _creatingIdentifier.ToName());
|
var data = new ActorData(gameObject, _creatingIdentifier.ToName());
|
||||||
_applier.ChangeMetaState(data, MetaIndex.HatState, _creatingState.ModelData.IsHatVisible());
|
_applier.ChangeMetaState(data, MetaIndex.HatState, _creatingState.ModelData.IsHatVisible());
|
||||||
_applier.ChangeMetaState(data, MetaIndex.Wetness, _creatingState.ModelData.IsWet());
|
_applier.ChangeMetaState(data, MetaIndex.Wetness, _creatingState.ModelData.IsWet());
|
||||||
_applier.ChangeMetaState(data, MetaIndex.WeaponState, _creatingState.ModelData.IsWeaponVisible());
|
_applier.ChangeMetaState(data, MetaIndex.WeaponState, _creatingState.ModelData.IsWeaponVisible());
|
||||||
|
|
||||||
ApplyParameters(_creatingState, drawObject);
|
ApplyParameters(_creatingState, drawObject);
|
||||||
|
|
@ -745,12 +744,18 @@ public class StateListener : IDisposable
|
||||||
else if (_config.UseAdvancedParameters)
|
else if (_config.UseAdvancedParameters)
|
||||||
model.ApplySingleParameterData(flag, state.ModelData.Parameters);
|
model.ApplySingleParameterData(flag, state.ModelData.Parameters);
|
||||||
break;
|
break;
|
||||||
|
case StateSource.IpcManual:
|
||||||
|
if (state.BaseData.Parameters.Set(flag, newValue))
|
||||||
|
_manager.ChangeCustomizeParameter(state, flag, newValue, ApplySettings.Game);
|
||||||
|
else
|
||||||
|
model.ApplySingleParameterData(flag, state.ModelData.Parameters);
|
||||||
|
break;
|
||||||
case StateSource.Fixed:
|
case StateSource.Fixed:
|
||||||
state.BaseData.Parameters.Set(flag, newValue);
|
state.BaseData.Parameters.Set(flag, newValue);
|
||||||
if (_config.UseAdvancedParameters)
|
if (_config.UseAdvancedParameters)
|
||||||
model.ApplySingleParameterData(flag, state.ModelData.Parameters);
|
model.ApplySingleParameterData(flag, state.ModelData.Parameters);
|
||||||
break;
|
break;
|
||||||
case StateSource.Ipc:
|
case StateSource.IpcFixed:
|
||||||
state.BaseData.Parameters.Set(flag, newValue);
|
state.BaseData.Parameters.Set(flag, newValue);
|
||||||
model.ApplySingleParameterData(flag, state.ModelData.Parameters);
|
model.ApplySingleParameterData(flag, state.ModelData.Parameters);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -243,7 +243,7 @@ public sealed class StateManager(
|
||||||
state.Materials.Clear();
|
state.Materials.Clear();
|
||||||
|
|
||||||
var actors = ActorData.Invalid;
|
var actors = ActorData.Invalid;
|
||||||
if (source is StateSource.Manual or StateSource.Ipc)
|
if (source is not StateSource.Game)
|
||||||
actors = Applier.ApplyAll(state, redraw, true);
|
actors = Applier.ApplyAll(state, redraw, true);
|
||||||
|
|
||||||
Glamourer.Log.Verbose(
|
Glamourer.Log.Verbose(
|
||||||
|
|
@ -262,7 +262,7 @@ public sealed class StateManager(
|
||||||
state.Sources[flag] = StateSource.Game;
|
state.Sources[flag] = StateSource.Game;
|
||||||
|
|
||||||
var actors = ActorData.Invalid;
|
var actors = ActorData.Invalid;
|
||||||
if (source is StateSource.Manual or StateSource.Ipc)
|
if (source is not StateSource.Game)
|
||||||
actors = Applier.ChangeParameters(state, CustomizeParameterExtensions.All, true);
|
actors = Applier.ChangeParameters(state, CustomizeParameterExtensions.All, true);
|
||||||
Glamourer.Log.Verbose(
|
Glamourer.Log.Verbose(
|
||||||
$"Reset advanced customization state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]");
|
$"Reset advanced customization state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||||
|
|
@ -316,28 +316,10 @@ public sealed class StateManager(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.Sources[MetaIndex.HatState] is StateSource.Fixed)
|
foreach (var meta in MetaExtensions.AllRelevant.Where(f => state.Sources[f] is StateSource.Fixed))
|
||||||
{
|
{
|
||||||
state.Sources[MetaIndex.HatState] = StateSource.Game;
|
state.Sources[meta] = StateSource.Game;
|
||||||
state.ModelData.SetHatVisible(state.BaseData.IsHatVisible());
|
state.ModelData.SetMeta(meta, state.BaseData.GetMeta(meta));
|
||||||
}
|
|
||||||
|
|
||||||
if (state.Sources[MetaIndex.VisorState] is StateSource.Fixed)
|
|
||||||
{
|
|
||||||
state.Sources[MetaIndex.VisorState] = StateSource.Game;
|
|
||||||
state.ModelData.SetVisor(state.BaseData.IsVisorToggled());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.Sources[MetaIndex.WeaponState] is StateSource.Fixed)
|
|
||||||
{
|
|
||||||
state.Sources[MetaIndex.WeaponState] = StateSource.Game;
|
|
||||||
state.ModelData.SetWeaponVisible(state.BaseData.IsWeaponVisible());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.Sources[MetaIndex.Wetness] is StateSource.Fixed)
|
|
||||||
{
|
|
||||||
state.Sources[MetaIndex.Wetness] = StateSource.Game;
|
|
||||||
state.ModelData.SetIsWet(state.BaseData.IsWet());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,48 @@ public enum StateSource : byte
|
||||||
Game,
|
Game,
|
||||||
Manual,
|
Manual,
|
||||||
Fixed,
|
Fixed,
|
||||||
Ipc,
|
IpcFixed,
|
||||||
|
IpcManual,
|
||||||
|
|
||||||
// Only used for CustomizeParameters.
|
// Only used for CustomizeParameters.
|
||||||
Pending,
|
Pending,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class StateSourceExtensions
|
||||||
|
{
|
||||||
|
public static StateSource Base(this StateSource source)
|
||||||
|
=> source switch
|
||||||
|
{
|
||||||
|
StateSource.Manual or StateSource.IpcManual or StateSource.Pending => StateSource.Manual,
|
||||||
|
StateSource.Fixed or StateSource.IpcFixed => StateSource.Fixed,
|
||||||
|
_ => StateSource.Game,
|
||||||
|
};
|
||||||
|
|
||||||
|
public static bool IsGame(this StateSource source)
|
||||||
|
=> source.Base() is StateSource.Game;
|
||||||
|
|
||||||
|
public static bool IsManual(this StateSource source)
|
||||||
|
=> source.Base() is StateSource.Manual;
|
||||||
|
|
||||||
|
public static bool IsFixed(this StateSource source)
|
||||||
|
=> source.Base() is StateSource.Fixed;
|
||||||
|
|
||||||
|
public static StateSource SetPending(this StateSource source)
|
||||||
|
=> source is StateSource.Manual ? StateSource.Pending : source;
|
||||||
|
|
||||||
|
public static bool RequiresChange(this StateSource source)
|
||||||
|
=> source switch
|
||||||
|
{
|
||||||
|
StateSource.Manual => true,
|
||||||
|
StateSource.IpcFixed => true,
|
||||||
|
StateSource.IpcManual => true,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
public static bool IsIpc(this StateSource source)
|
||||||
|
=> source is StateSource.IpcManual or StateSource.IpcFixed;
|
||||||
|
}
|
||||||
|
|
||||||
public unsafe struct StateSources
|
public unsafe struct StateSources
|
||||||
{
|
{
|
||||||
public const int Size = (StateIndex.Size + 1) / 2;
|
public const int Size = (StateIndex.Size + 1) / 2;
|
||||||
|
|
@ -59,14 +95,16 @@ public unsafe struct StateSources
|
||||||
|
|
||||||
case (byte)StateSource.Game | ((byte)StateSource.Fixed << 4):
|
case (byte)StateSource.Game | ((byte)StateSource.Fixed << 4):
|
||||||
case (byte)StateSource.Manual | ((byte)StateSource.Fixed << 4):
|
case (byte)StateSource.Manual | ((byte)StateSource.Fixed << 4):
|
||||||
case (byte)StateSource.Ipc | ((byte)StateSource.Fixed << 4):
|
case (byte)StateSource.IpcFixed | ((byte)StateSource.Fixed << 4):
|
||||||
case (byte)StateSource.Pending | ((byte)StateSource.Fixed << 4):
|
case (byte)StateSource.Pending | ((byte)StateSource.Fixed << 4):
|
||||||
|
case (byte)StateSource.IpcManual | ((byte)StateSource.Fixed << 4):
|
||||||
_data[i] = (byte)((value & 0x0F) | ((byte)StateSource.Manual << 4));
|
_data[i] = (byte)((value & 0x0F) | ((byte)StateSource.Manual << 4));
|
||||||
break;
|
break;
|
||||||
case (byte)StateSource.Fixed:
|
case (byte)StateSource.Fixed:
|
||||||
case ((byte)StateSource.Manual << 4) | (byte)StateSource.Fixed:
|
case ((byte)StateSource.Manual << 4) | (byte)StateSource.Fixed:
|
||||||
case ((byte)StateSource.Ipc << 4) | (byte)StateSource.Fixed:
|
case ((byte)StateSource.IpcFixed << 4) | (byte)StateSource.Fixed:
|
||||||
case ((byte)StateSource.Pending << 4) | (byte)StateSource.Fixed:
|
case ((byte)StateSource.Pending << 4) | (byte)StateSource.Fixed:
|
||||||
|
case ((byte)StateSource.IpcManual << 4) | (byte)StateSource.Fixed:
|
||||||
_data[i] = (byte)((value & 0xF0) | (byte)StateSource.Manual);
|
_data[i] = (byte)((value & 0xF0) | (byte)StateSource.Manual);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue