mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2026-01-01 05:13:44 +01:00
.
This commit is contained in:
parent
7710cfadfa
commit
2d6fd6015d
88 changed files with 2304 additions and 383 deletions
305
GlamourerOld/State/ActiveDesign.Manager.cs
Normal file
305
GlamourerOld/State/ActiveDesign.Manager.cs
Normal file
|
|
@ -0,0 +1,305 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using Glamourer.Interop;
|
||||
using Penumbra.GameData.Actors;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||
using Glamourer.Api;
|
||||
using Glamourer.Customization;
|
||||
using Glamourer.Designs;
|
||||
using Glamourer.Services;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
using CustomizeData = Penumbra.GameData.Structs.CustomizeData;
|
||||
|
||||
namespace Glamourer.State;
|
||||
|
||||
public sealed partial class ActiveDesign
|
||||
{
|
||||
[Flags]
|
||||
public enum ChangeType
|
||||
{
|
||||
Default = 0x00,
|
||||
Changed = 0x01,
|
||||
Fixed = 0x02,
|
||||
}
|
||||
|
||||
public class Manager : IReadOnlyDictionary<ActorIdentifier, ActiveDesign>
|
||||
{
|
||||
private readonly ActorService _actors;
|
||||
private readonly ObjectManager _objects;
|
||||
private readonly PenumbraAttach _penumbra;
|
||||
private readonly ItemManager _items;
|
||||
private readonly VisorService _visor;
|
||||
private readonly ChangeCustomizeService _customize;
|
||||
private readonly UpdateSlotService _updateSlot;
|
||||
private readonly WeaponService _weaponService;
|
||||
|
||||
private readonly Dictionary<ActorIdentifier, ActiveDesign> _characterSaves = new();
|
||||
|
||||
public Manager(ActorService actors, ObjectManager objects, PenumbraAttach penumbra, ItemManager items, VisorService visor,
|
||||
ChangeCustomizeService customize, UpdateSlotService updateSlot, WeaponService weaponService)
|
||||
{
|
||||
_actors = actors;
|
||||
_objects = objects;
|
||||
_penumbra = penumbra;
|
||||
_items = items;
|
||||
_visor = visor;
|
||||
_customize = customize;
|
||||
_updateSlot = updateSlot;
|
||||
_weaponService = weaponService;
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<ActorIdentifier, ActiveDesign>> GetEnumerator()
|
||||
=> _characterSaves.GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
=> GetEnumerator();
|
||||
|
||||
public int Count
|
||||
=> _characterSaves.Count;
|
||||
|
||||
public bool ContainsKey(ActorIdentifier key)
|
||||
=> _characterSaves.ContainsKey(key);
|
||||
|
||||
public bool TryGetValue(ActorIdentifier key, [NotNullWhen(true)] out ActiveDesign? value)
|
||||
=> _characterSaves.TryGetValue(key, out value);
|
||||
|
||||
public ActiveDesign this[ActorIdentifier key]
|
||||
=> _characterSaves[key];
|
||||
|
||||
public IEnumerable<ActorIdentifier> Keys
|
||||
=> _characterSaves.Keys;
|
||||
|
||||
public IEnumerable<ActiveDesign> Values
|
||||
=> _characterSaves.Values;
|
||||
|
||||
public void DeleteSave(ActorIdentifier identifier)
|
||||
=> _characterSaves.Remove(identifier);
|
||||
|
||||
public unsafe ActiveDesign GetOrCreateSave(Actor actor)
|
||||
{
|
||||
var id = _actors.AwaitedService.FromObject((GameObject*)actor.Pointer, out _, false, false, false);
|
||||
if (_characterSaves.TryGetValue(id, out var save))
|
||||
{
|
||||
save.Initialize(_items, actor);
|
||||
return save;
|
||||
}
|
||||
|
||||
id = id.CreatePermanent();
|
||||
save = new ActiveDesign(_items, id, actor);
|
||||
save.Initialize(_items, actor);
|
||||
_characterSaves.Add(id, save);
|
||||
return save;
|
||||
}
|
||||
|
||||
public void SetWetness(ActiveDesign design, bool wet, bool fromFixed)
|
||||
=> design.IsWet = wet;
|
||||
|
||||
public void SetHatVisible(ActiveDesign design, bool visible, bool fromFixed)
|
||||
=> design.IsHatVisible = visible;
|
||||
|
||||
public void SetVisor(ActiveDesign design, bool toggled, bool fromFixed)
|
||||
=> design.IsVisorToggled = toggled;
|
||||
|
||||
public void SetWeaponVisible(ActiveDesign design, bool visible, bool fromFixed)
|
||||
=> design.IsWeaponVisible = visible;
|
||||
|
||||
public unsafe void ApplyDesign(ActiveDesign to, Design from, bool fromFixed)
|
||||
{
|
||||
if (to.ModelId != from.ModelId)
|
||||
return;
|
||||
|
||||
if (from.DoApplyEquip(EquipSlot.MainHand))
|
||||
ChangeMainHand(to, from.MainHandId, fromFixed);
|
||||
if (from.DoApplyStain(EquipSlot.MainHand))
|
||||
ChangeStain(to, EquipSlot.MainHand, from.WeaponMain.Stain, fromFixed);
|
||||
|
||||
if (from.DoApplyEquip(EquipSlot.OffHand))
|
||||
ChangeOffHand(to, from.OffHandId, fromFixed);
|
||||
if (from.DoApplyStain(EquipSlot.OffHand))
|
||||
ChangeStain(to, EquipSlot.OffHand, from.WeaponOff.Stain, fromFixed);
|
||||
|
||||
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
||||
{
|
||||
var armor = from.Armor(slot);
|
||||
if (from.DoApplyEquip(slot))
|
||||
ChangeEquipment(to, slot, armor, fromFixed);
|
||||
if (from.DoApplyStain(slot))
|
||||
ChangeStain(to, slot, armor.Stain, fromFixed);
|
||||
}
|
||||
|
||||
ChangeCustomize(to, from.ApplyCustomize, from.ModelData.Customize.Data, fromFixed);
|
||||
|
||||
if (from.Wetness.Enabled)
|
||||
SetWetness(to, from.Wetness.ForcedValue, fromFixed);
|
||||
if (from.Hat.Enabled)
|
||||
SetHatVisible(to, from.Hat.ForcedValue, fromFixed);
|
||||
if (from.Visor.Enabled)
|
||||
SetVisor(to, from.Visor.ForcedValue, fromFixed);
|
||||
if (from.Weapon.Enabled)
|
||||
SetWeaponVisible(to, from.Weapon.ForcedValue, fromFixed);
|
||||
}
|
||||
|
||||
public void RevertDesign(ActiveDesign design)
|
||||
{
|
||||
RevertCustomize(design, design.ChangedCustomize);
|
||||
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
||||
RevertEquipment(design, slot, design.ChangedEquip.HasFlag(slot.ToFlag()), design.ChangedEquip.HasFlag(slot.ToStainFlag()));
|
||||
|
||||
RevertMainHand(design);
|
||||
RevertOffHand(design);
|
||||
}
|
||||
|
||||
public void ChangeMainHand(ActiveDesign design, uint itemId, bool fromFixed)
|
||||
=> design.SetMainhand(_items, itemId);
|
||||
|
||||
public void ChangeOffHand(ActiveDesign design, uint itemId, bool fromFixed)
|
||||
=> design.SetOffhand(_items, itemId);
|
||||
|
||||
public void RevertMainHand(ActiveDesign design)
|
||||
{ }
|
||||
|
||||
public void RevertOffHand(ActiveDesign design)
|
||||
{ }
|
||||
|
||||
public void RevertCustomize(ActiveDesign design, CustomizeFlag flags)
|
||||
=> ChangeCustomize(design, flags, design._initialData.Customize.Data, false);
|
||||
|
||||
public void ChangeCustomize(ActiveDesign design, CustomizeFlag flags, CustomizeData newValue, bool fromFixed)
|
||||
{
|
||||
var customize = new Customize(newValue);
|
||||
var anyChanges = false;
|
||||
foreach (var option in Enum.GetValues<CustomizeIndex>())
|
||||
{
|
||||
var flag = option.ToFlag();
|
||||
var apply = flags.HasFlag(flag);
|
||||
anyChanges |= apply && design.SetCustomize(option, customize[option]);
|
||||
if (design.GetCustomize(option).Value != design._initialData.Customize[option].Value)
|
||||
design.ChangedCustomize |= flag;
|
||||
else
|
||||
design.ChangedCustomize &= ~flag;
|
||||
|
||||
if (fromFixed)
|
||||
design.FixedCustomize |= flag;
|
||||
else
|
||||
design.FixedCustomize &= ~flag;
|
||||
}
|
||||
|
||||
if (!anyChanges)
|
||||
return;
|
||||
|
||||
_objects.Update();
|
||||
if (!_objects.TryGetValue(design.Identifier, out var data))
|
||||
return;
|
||||
|
||||
var redraw = flags.RequiresRedraw();
|
||||
foreach (var obj in data.Objects)
|
||||
{
|
||||
if (redraw)
|
||||
_penumbra.RedrawObject(obj, RedrawType.Redraw);
|
||||
else
|
||||
_customize.UpdateCustomize(obj, design.ModelData.Customize.Data);
|
||||
}
|
||||
}
|
||||
|
||||
public void RevertEquipment(ActiveDesign design, EquipSlot slot, bool equip, bool stain)
|
||||
{
|
||||
var item = design._initialData.Armor(slot);
|
||||
if (equip)
|
||||
{
|
||||
var flag = slot.ToFlag();
|
||||
design.UpdateArmor(_items, slot, item, true);
|
||||
design.ChangedEquip &= ~flag;
|
||||
design.FixedEquip &= ~flag;
|
||||
}
|
||||
|
||||
if (stain)
|
||||
{
|
||||
var flag = slot.ToStainFlag();
|
||||
design.SetStain(slot, item.Stain);
|
||||
design.ChangedEquip &= ~flag;
|
||||
design.FixedEquip &= ~flag;
|
||||
}
|
||||
|
||||
_objects.Update();
|
||||
if (!_objects.TryGetValue(design.Identifier, out var data))
|
||||
return;
|
||||
|
||||
foreach (var obj in data.Objects)
|
||||
_updateSlot.UpdateSlot(obj.DrawObject, slot, item);
|
||||
}
|
||||
|
||||
public void ChangeEquipment(ActiveDesign design, EquipSlot slot, Item item, bool fromFixed)
|
||||
{
|
||||
var flag = slot.ToFlag();
|
||||
design.SetArmor(slot, item);
|
||||
var current = design.Armor(slot);
|
||||
var initial = design._initialData.Armor(slot);
|
||||
if (current.ModelBase.Value != initial.Set.Value || current.Variant != initial.Variant)
|
||||
design.ChangedEquip |= flag;
|
||||
else
|
||||
design.ChangedEquip &= ~flag;
|
||||
if (fromFixed)
|
||||
design.FixedEquip |= flag;
|
||||
else
|
||||
design.FixedEquip &= ~flag;
|
||||
|
||||
_objects.Update();
|
||||
if (!_objects.TryGetValue(design.Identifier, out var data))
|
||||
return;
|
||||
|
||||
foreach (var obj in data.Objects)
|
||||
_updateSlot.UpdateSlot(obj.DrawObject, slot, item.Model);
|
||||
}
|
||||
|
||||
public void ChangeStain(ActiveDesign design, EquipSlot slot, StainId stain, bool fromFixed)
|
||||
{
|
||||
var flag = slot.ToStainFlag();
|
||||
design.SetStain(slot, stain);
|
||||
var (current, initial, weapon) = slot switch
|
||||
{
|
||||
EquipSlot.MainHand => (design.WeaponMain.Stain, design._initialData.MainHand.Stain, true),
|
||||
EquipSlot.OffHand => (design.WeaponOff.Stain, design._initialData.OffHand.Stain, true),
|
||||
_ => (design.Armor(slot).Stain, design._initialData.Armor(slot).Stain, false),
|
||||
};
|
||||
if (current.Value != initial.Value)
|
||||
design.ChangedEquip |= flag;
|
||||
else
|
||||
design.ChangedEquip &= ~flag;
|
||||
if (fromFixed)
|
||||
design.FixedEquip |= flag;
|
||||
else
|
||||
design.FixedEquip &= ~flag;
|
||||
|
||||
_objects.Update();
|
||||
if (!_objects.TryGetValue(design.Identifier, out var data))
|
||||
return;
|
||||
|
||||
foreach (var obj in data.Objects)
|
||||
{
|
||||
if (weapon)
|
||||
_weaponService.LoadStain(obj, EquipSlot.MainHand, stain);
|
||||
else
|
||||
_updateSlot.UpdateStain(obj.DrawObject, slot, stain);
|
||||
}
|
||||
}
|
||||
|
||||
public void ChangeVisor(ActiveDesign design, bool on, bool fromFixed)
|
||||
{
|
||||
var current = design.IsVisorToggled;
|
||||
if (current == on)
|
||||
return;
|
||||
|
||||
design.IsVisorToggled = on;
|
||||
_objects.Update();
|
||||
if (!_objects.TryGetValue(design.Identifier, out var data))
|
||||
return;
|
||||
|
||||
foreach (var obj in data.Objects)
|
||||
_visor.SetVisorState(obj.DrawObject, on);
|
||||
}
|
||||
}
|
||||
}
|
||||
117
GlamourerOld/State/ActiveDesign.cs
Normal file
117
GlamourerOld/State/ActiveDesign.cs
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
using Glamourer.Customization;
|
||||
using Glamourer.Designs;
|
||||
using Glamourer.Interop;
|
||||
using Glamourer.Services;
|
||||
using Penumbra.GameData.Actors;
|
||||
using Penumbra.GameData.Enums;
|
||||
|
||||
namespace Glamourer.State;
|
||||
|
||||
|
||||
|
||||
public sealed partial class ActiveDesign : DesignData
|
||||
{
|
||||
public readonly ActorIdentifier Identifier;
|
||||
|
||||
private ModelData _initialData = new();
|
||||
|
||||
public CustomizeFlag ChangedCustomize { get; private set; } = 0;
|
||||
public CustomizeFlag FixedCustomize { get; private set; } = 0;
|
||||
|
||||
public EquipFlag ChangedEquip { get; private set; } = 0;
|
||||
public EquipFlag FixedEquip { get; private set; } = 0;
|
||||
|
||||
|
||||
public bool IsHatVisible { get; private set; } = false;
|
||||
public bool IsWeaponVisible { get; private set; } = false;
|
||||
public bool IsVisorToggled { get; private set; } = false;
|
||||
public bool IsWet { get; private set; } = false;
|
||||
|
||||
private ActiveDesign(ItemManager items, ActorIdentifier identifier)
|
||||
: base(items)
|
||||
=> Identifier = identifier;
|
||||
|
||||
public ActiveDesign(ItemManager items, ActorIdentifier identifier, Actor actor)
|
||||
: base(items)
|
||||
{
|
||||
Identifier = identifier;
|
||||
Initialize(items, actor);
|
||||
}
|
||||
|
||||
//public void ApplyToActor(Actor actor)
|
||||
//{
|
||||
// if (!actor)
|
||||
// return;
|
||||
//
|
||||
// void Redraw()
|
||||
// => Glamourer.Penumbra.RedrawObject(actor.Character, RedrawType.Redraw);
|
||||
//
|
||||
// if (_drawData.ModelId != actor.ModelId)
|
||||
// {
|
||||
// Redraw();
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// var customize1 = _drawData.Customize;
|
||||
// var customize2 = actor.Customize;
|
||||
// if (RedrawManager.NeedsRedraw(customize1, customize2))
|
||||
// {
|
||||
// Redraw();
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// Glamourer.RedrawManager.UpdateCustomize(actor, customize2);
|
||||
// foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
||||
// Glamourer.RedrawManager.ChangeEquip(actor, slot, actor.Equip[slot]);
|
||||
// Glamourer.RedrawManager.LoadWeapon(actor, actor.MainHand, actor.OffHand);
|
||||
// if (actor.IsHuman && actor.DrawObject)
|
||||
// RedrawManager.SetVisor(actor.DrawObject.Pointer, actor.VisorEnabled);
|
||||
//}
|
||||
//
|
||||
public void Initialize(ItemManager items, Actor actor)
|
||||
{
|
||||
if (!actor)
|
||||
return;
|
||||
|
||||
if (!_initialData.Customize.Equals(actor.Customize))
|
||||
{
|
||||
_initialData.Customize.Load(actor.Customize);
|
||||
ModelData.Customize.Load(actor.Customize);
|
||||
}
|
||||
|
||||
var currentEquip = actor.Equip;
|
||||
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
||||
{
|
||||
var current = currentEquip[slot];
|
||||
if (_initialData.Armor(slot) != current)
|
||||
{
|
||||
_initialData.SetPiece(slot, current.Set, current.Variant, current.Stain, out _);
|
||||
UpdateArmor(items, slot, current, true);
|
||||
SetStain(slot, current.Stain);
|
||||
}
|
||||
}
|
||||
|
||||
if (_initialData.MainHand != actor.MainHand)
|
||||
{
|
||||
_initialData.MainHand = actor.MainHand;
|
||||
UpdateMainhand(items, actor.MainHand);
|
||||
SetStain(EquipSlot.MainHand, actor.MainHand.Stain);
|
||||
}
|
||||
|
||||
if (_initialData.OffHand != actor.OffHand)
|
||||
{
|
||||
_initialData.OffHand = actor.OffHand;
|
||||
UpdateOffhand(items, actor.OffHand);
|
||||
SetStain(EquipSlot.OffHand, actor.OffHand.Stain);
|
||||
}
|
||||
|
||||
var visor = VisorService.GetVisorState(actor.DrawObject);
|
||||
if (IsVisorToggled != visor)
|
||||
IsVisorToggled = visor;
|
||||
}
|
||||
|
||||
public string CreateOldBase64()
|
||||
=> DesignBase64Migration.CreateOldBase64(in ModelData, EquipFlagExtensions.All, CustomizeFlagExtensions.All, IsWet, IsHatVisible, true,
|
||||
IsVisorToggled,
|
||||
true, IsWeaponVisible, true, false, 1f);
|
||||
}
|
||||
29
GlamourerOld/State/FixedDesignManager.cs
Normal file
29
GlamourerOld/State/FixedDesignManager.cs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.InstanceContent;
|
||||
using Glamourer.Designs;
|
||||
using Glamourer.Interop;
|
||||
using Glamourer.Structs;
|
||||
using Penumbra.GameData.Actors;
|
||||
|
||||
namespace Glamourer.State;
|
||||
|
||||
public class FixedDesignManager
|
||||
{
|
||||
public class FixedDesign
|
||||
{
|
||||
public Design Design = null!;
|
||||
public byte? JobCondition;
|
||||
public ushort? TerritoryCondition;
|
||||
|
||||
public bool Applies(byte job, ushort territoryType)
|
||||
=> (!JobCondition.HasValue || JobCondition.Value == job)
|
||||
&& (!TerritoryCondition.HasValue || TerritoryCondition.Value == territoryType);
|
||||
}
|
||||
|
||||
public IReadOnlyList<FixedDesign> GetDesigns(ActorIdentifier actor)
|
||||
{
|
||||
return Array.Empty<FixedDesign>();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue