mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-12 18:27:24 +01:00
More stains, more misc fixes
I made my best to try to fix as much as I could. I have no idea if it is correct but I hope it is and I hope this will be helpful for ApiX / Dawntrail update.
This commit is contained in:
parent
8a954e6e09
commit
e9d1efccdc
25 changed files with 117 additions and 110 deletions
|
|
@ -257,10 +257,10 @@ public class DesignBase
|
|||
foreach (var slot in EquipSlotExtensions.EqdpSlots.Prepend(EquipSlot.OffHand).Prepend(EquipSlot.MainHand))
|
||||
{
|
||||
var item = _designData.Item(slot);
|
||||
var stain = _designData.Stain(slot);
|
||||
var stains = _designData.Stain(slot);
|
||||
var crestSlot = slot.ToCrestFlag();
|
||||
var crest = _designData.Crest(crestSlot);
|
||||
ret[slot.ToString()] = Serialize(item.Id, stain, crest, DoApplyEquip(slot), DoApplyStain(slot), DoApplyCrest(crestSlot));
|
||||
ret[slot.ToString()] = Serialize(item.Id, stains, crest, DoApplyEquip(slot), DoApplyStain(slot), DoApplyCrest(crestSlot));
|
||||
}
|
||||
|
||||
ret["Hat"] = new QuadBool(_designData.IsHatVisible(), DoApplyMeta(MetaIndex.HatState)).ToJObject("Show", "Apply");
|
||||
|
|
@ -274,11 +274,11 @@ public class DesignBase
|
|||
|
||||
return ret;
|
||||
|
||||
static JObject Serialize(CustomItemId id, StainId stain, bool crest, bool apply, bool applyStain, bool applyCrest)
|
||||
static JObject Serialize(CustomItemId id, StainIds stains, bool crest, bool apply, bool applyStain, bool applyCrest)
|
||||
=> new()
|
||||
{
|
||||
["ItemId"] = id.Id,
|
||||
["Stain"] = stain.Id,
|
||||
["Stain"] = stains.ToString(),
|
||||
["Crest"] = crest,
|
||||
["Apply"] = apply,
|
||||
["ApplyStain"] = applyStain,
|
||||
|
|
@ -522,15 +522,15 @@ public class DesignBase
|
|||
return;
|
||||
}
|
||||
|
||||
static (CustomItemId, StainId, bool, bool, bool, bool) ParseItem(EquipSlot slot, JToken? item)
|
||||
static (CustomItemId, StainIds, bool, bool, bool, bool) ParseItem(EquipSlot slot, JToken? item)
|
||||
{
|
||||
var id = item?["ItemId"]?.ToObject<ulong>() ?? ItemManager.NothingId(slot).Id;
|
||||
var stain = (StainId)(item?["Stain"]?.ToObject<byte>() ?? 0);
|
||||
var stains = (item?["Stain"]?.ToObject<StainIds>() ?? StainIds.None);
|
||||
var crest = item?["Crest"]?.ToObject<bool>() ?? false;
|
||||
var apply = item?["Apply"]?.ToObject<bool>() ?? false;
|
||||
var applyStain = item?["ApplyStain"]?.ToObject<bool>() ?? false;
|
||||
var applyCrest = item?["ApplyCrest"]?.ToObject<bool>() ?? false;
|
||||
return (id, stain, crest, apply, applyStain, applyCrest);
|
||||
return (id, stains, crest, apply, applyStain, applyCrest);
|
||||
}
|
||||
|
||||
void PrintWarning(string msg)
|
||||
|
|
@ -541,13 +541,13 @@ public class DesignBase
|
|||
|
||||
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
||||
{
|
||||
var (id, stain, crest, apply, applyStain, applyCrest) = ParseItem(slot, equip[slot.ToString()]);
|
||||
var (id, stains, crest, apply, applyStain, applyCrest) = ParseItem(slot, equip[slot.ToString()]);
|
||||
|
||||
PrintWarning(items.ValidateItem(slot, id, out var item, allowUnknown));
|
||||
PrintWarning(items.ValidateStain(stain, out stain, allowUnknown));
|
||||
PrintWarning(items.ValidateStain(stains, out stains, allowUnknown));
|
||||
var crestSlot = slot.ToCrestFlag();
|
||||
design._designData.SetItem(slot, item);
|
||||
design._designData.SetStain(slot, stain);
|
||||
design._designData.SetStain(slot, stains);
|
||||
design._designData.SetCrest(crestSlot, crest);
|
||||
design.SetApplyEquip(slot, apply);
|
||||
design.SetApplyStain(slot, applyStain);
|
||||
|
|
|
|||
|
|
@ -52,10 +52,10 @@ public unsafe struct DesignData
|
|||
|| name.IsContained(_nameMainhand)
|
||||
|| name.IsContained(_nameOffhand);
|
||||
|
||||
public readonly StainId Stain(EquipSlot slot)
|
||||
public readonly StainIds Stain(EquipSlot slot)
|
||||
{
|
||||
var index = slot.ToIndex();
|
||||
return index > 11 ? (StainId)0 : _equipmentBytes[4 * index + 3];
|
||||
return index > 11 ? StainIds.None : new(_equipmentBytes[4 * index + 3], _equipmentBytes[4 * index + 3]);
|
||||
}
|
||||
|
||||
public readonly bool Crest(CrestFlag slot)
|
||||
|
|
|
|||
|
|
@ -167,29 +167,29 @@ public class DesignEditor(
|
|||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void ChangeStain(object data, EquipSlot slot, StainId stain, ApplySettings _ = default)
|
||||
public void ChangeStain(object data, EquipSlot slot, StainIds stains, ApplySettings _ = default)
|
||||
{
|
||||
var design = (Design)data;
|
||||
if (Items.ValidateStain(stain, out var _, false).Length > 0)
|
||||
if (Items.ValidateStain(stains, out var _, false).Length > 0)
|
||||
return;
|
||||
|
||||
var oldStain = design.DesignData.Stain(slot);
|
||||
if (!design.GetDesignDataRef().SetStain(slot, stain))
|
||||
if (!design.GetDesignDataRef().SetStain(slot, stains))
|
||||
return;
|
||||
|
||||
design.LastEdit = DateTimeOffset.UtcNow;
|
||||
SaveService.QueueSave(design);
|
||||
Glamourer.Log.Debug($"Set stain of {slot} equipment piece to {stain.Id}.");
|
||||
DesignChanged.Invoke(DesignChanged.Type.Stain, design, (oldStain, stain, slot));
|
||||
Glamourer.Log.Debug($"Set stain of {slot} equipment piece to {stains}.");
|
||||
DesignChanged.Invoke(DesignChanged.Type.Stain, design, (oldStain, stains, slot));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void ChangeEquip(object data, EquipSlot slot, EquipItem? item, StainId? stain, ApplySettings _ = default)
|
||||
public void ChangeEquip(object data, EquipSlot slot, EquipItem? item, StainIds? stains, ApplySettings _ = default)
|
||||
{
|
||||
if (item.HasValue)
|
||||
ChangeItem(data, slot, item.Value, _);
|
||||
if (stain.HasValue)
|
||||
ChangeStain(data, slot, stain.Value, _);
|
||||
if (stains.HasValue)
|
||||
ChangeStain(data, slot, stains.Value, _);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
|
@ -366,4 +366,9 @@ public class DesignEditor(
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ChangeEquip(object data, EquipSlot slot, EquipItem? item, StainId? stain, ApplySettings settings = default)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,11 +65,11 @@ public interface IDesignEditor
|
|||
=> ChangeEquip(data, slot, item, null, settings);
|
||||
|
||||
/// <summary> Change the stain for any equipment piece. </summary>
|
||||
public void ChangeStain(object data, EquipSlot slot, StainId stain, ApplySettings settings = default)
|
||||
=> ChangeEquip(data, slot, null, stain, settings);
|
||||
public void ChangeStain(object data, EquipSlot slot, StainIds stains, ApplySettings settings = default)
|
||||
=> ChangeEquip(data, slot, null, stains, settings);
|
||||
|
||||
/// <summary> Change an equipment piece and its stain at the same time. </summary>
|
||||
public void ChangeEquip(object data, EquipSlot slot, EquipItem? item, StainId? stain, ApplySettings settings = default);
|
||||
public void ChangeEquip(object data, EquipSlot slot, EquipItem? item, StainIds? stains, ApplySettings settings = default);
|
||||
|
||||
/// <summary> Change the crest visibility for any equipment piece. </summary>
|
||||
public void ChangeCrest(object data, CrestFlag slot, bool crest, ApplySettings settings = default);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace Glamourer.Events;
|
|||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class MovedEquipment()
|
||||
: EventWrapper<(EquipSlot, uint, StainId)[], MovedEquipment.Priority>(nameof(MovedEquipment))
|
||||
: EventWrapper<(EquipSlot, uint, StainIds)[], MovedEquipment.Priority>(nameof(MovedEquipment))
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ public struct EquipDrawData(EquipSlot slot, in DesignData designData)
|
|||
public readonly void SetItem(EquipItem item)
|
||||
=> _editor.ChangeItem(_object, Slot, item, ApplySettings.Manual);
|
||||
|
||||
public readonly void SetStain(StainId stain)
|
||||
=> _editor.ChangeStain(_object, Slot, stain, ApplySettings.Manual);
|
||||
public readonly void SetStain(StainIds stains)
|
||||
=> _editor.ChangeStain(_object, Slot, stains, ApplySettings.Manual);
|
||||
|
||||
public readonly void SetApplyItem(bool value)
|
||||
{
|
||||
|
|
@ -41,9 +41,9 @@ public struct EquipDrawData(EquipSlot slot, in DesignData designData)
|
|||
}
|
||||
|
||||
public EquipItem CurrentItem = designData.Item(slot);
|
||||
public StainId CurrentStain = designData.Stain(slot);
|
||||
public StainIds CurrentStain = designData.Stain(slot);
|
||||
public EquipItem GameItem = default;
|
||||
public StainId GameStain = default;
|
||||
public StainIds GameStain = default;
|
||||
public bool CurrentApply;
|
||||
public bool CurrentApplyStain;
|
||||
|
||||
|
|
|
|||
|
|
@ -87,8 +87,8 @@ public class ActiveStatePanel(StateManager _stateManager, ObjectManager _objectM
|
|||
foreach (var slot in EquipSlotExtensions.EqdpSlots.Prepend(EquipSlot.OffHand).Prepend(EquipSlot.MainHand))
|
||||
{
|
||||
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.BaseData.Stain(slot)[0]}, {state.BaseData.Stain(slot)[1]}");
|
||||
ImGuiUtil.DrawTableColumn($"{state.ModelData.Stain(slot)[0]}, {state.ModelData.Stain(slot)[1]}");
|
||||
ImGuiUtil.DrawTableColumn(state.Sources[slot, true].ToString());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ public unsafe class GlamourPlatePanel : IGameDataDrawer
|
|||
using (ImRaii.Group())
|
||||
{
|
||||
ImGuiUtil.CopyOnClickSelectable($"0x{(ulong)manager:X}");
|
||||
ImGui.TextUnformatted(manager == null ? "-" : manager->GlamourPlatesSpan.Length.ToString());
|
||||
ImGui.TextUnformatted(manager == null ? "-" : manager->GlamourPlates.Length.ToString());
|
||||
ImGui.TextUnformatted(manager == null ? "-" : manager->GlamourPlatesRequested.ToString());
|
||||
ImGui.SameLine();
|
||||
if (ImGui.SmallButton("Request Update"))
|
||||
|
|
@ -67,13 +67,13 @@ public unsafe class GlamourPlatePanel : IGameDataDrawer
|
|||
var (identifier, data) = _objects.PlayerData;
|
||||
var enabled = data.Valid && _state.GetOrCreate(identifier, data.Objects[0], out state);
|
||||
|
||||
for (var i = 0; i < manager->GlamourPlatesSpan.Length; ++i)
|
||||
for (var i = 0; i < manager->GlamourPlates.Length; ++i)
|
||||
{
|
||||
using var tree = ImRaii.TreeNode($"Plate #{i + 1:D2}");
|
||||
if (!tree)
|
||||
continue;
|
||||
|
||||
ref var plate = ref manager->GlamourPlatesSpan[i];
|
||||
ref var plate = ref manager->GlamourPlates[i];
|
||||
if (ImGuiUtil.DrawDisabledButton("Apply to Player", Vector2.Zero, string.Empty, !enabled))
|
||||
{
|
||||
var design = CreateDesign(plate);
|
||||
|
|
@ -90,7 +90,7 @@ public unsafe class GlamourPlatePanel : IGameDataDrawer
|
|||
using (ImRaii.Group())
|
||||
{
|
||||
foreach (var (_, index) in EquipSlotExtensions.FullSlots.WithIndex())
|
||||
ImGui.TextUnformatted($"{plate.ItemIds[index]:D6}, {plate.StainIds[index]:D3}");
|
||||
ImGui.TextUnformatted($"{plate.ItemIds[index]:D6}, {plate.Stain0Ids[index]:D3}, {plate.Stain1Ids[index]:D3}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -126,7 +126,7 @@ public unsafe class GlamourPlatePanel : IGameDataDrawer
|
|||
continue;
|
||||
|
||||
design.GetDesignDataRef().SetItem(slot, item);
|
||||
design.GetDesignDataRef().SetStain(slot, plate.StainIds[index]);
|
||||
design.GetDesignDataRef().SetStain(slot, new(plate.Stain0Ids[index], plate.Stain1Ids[index]));
|
||||
design.ApplyEquip |= slot.ToBothFlags();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ public unsafe class InventoryPanel : IGameDataDrawer
|
|||
}
|
||||
else
|
||||
{
|
||||
ImGuiUtil.DrawTableColumn(item->ItemID.ToString());
|
||||
ImGuiUtil.DrawTableColumn(item->GlamourID.ToString());
|
||||
ImGuiUtil.DrawTableColumn(item->ItemId.ToString());
|
||||
ImGuiUtil.DrawTableColumn(item->GlamourId.ToString());
|
||||
ImGui.TableNextColumn();
|
||||
ImGuiUtil.CopyOnClickSelectable($"0x{(ulong)item:X}");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -453,7 +453,7 @@ public class DesignPanel
|
|||
}
|
||||
|
||||
private static unsafe string GetUserPath()
|
||||
=> Framework.Instance()->UserPath;
|
||||
=> Framework.Instance()->UserPathString;
|
||||
|
||||
|
||||
private sealed class LockButton(DesignPanel panel) : Button
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ public class UnlockOverview
|
|||
ImGui.TextUnformatted($"For all {_jobs.AllJobGroups[item.JobRestrictions.Id].Name} of at least Level {item.Level}");
|
||||
}
|
||||
|
||||
if (item.Flags.HasFlag(ItemFlags.IsDyable))
|
||||
if (item.Flags.HasFlag(ItemFlags.IsDyable1))
|
||||
ImGui.TextUnformatted("Dyable");
|
||||
if (item.Flags.HasFlag(ItemFlags.IsTradable))
|
||||
ImGui.TextUnformatted("Tradable");
|
||||
|
|
|
|||
|
|
@ -384,7 +384,7 @@ public class UnlockTable : Table<EquipItem>, IDisposable
|
|||
=> Tooltip = "Whether the item is dyable.";
|
||||
|
||||
protected override bool GetValue(EquipItem item)
|
||||
=> item.Flags.HasFlag(ItemFlags.IsDyable);
|
||||
=> item.Flags.HasFlag(ItemFlags.IsDyable1);
|
||||
}
|
||||
|
||||
private sealed class TradableColumn : YesNoColumn<EquipItem>
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ public unsafe class ChangeCustomizeService : EventWrapperRef2<Model, CustomizeAr
|
|||
_penumbraReloaded = penumbraReloaded;
|
||||
_interop = interop;
|
||||
_changeCustomizeHook = Create();
|
||||
_original = Human.MemberFunctionPointers.UpdateDrawData;
|
||||
_original = (delegate* unmanaged[Stdcall]<Human*, byte*, bool, bool>)Human.MemberFunctionPointers.UpdateDrawData;
|
||||
interop.InitializeFromAttributes(this);
|
||||
_penumbraReloaded.Subscribe(Restore, PenumbraReloaded.Priority.ChangeCustomizeService);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ public sealed class CharaFile
|
|||
return;
|
||||
|
||||
data.SetItem(slot, item);
|
||||
data.SetStain(slot, dye);
|
||||
data.SetStain(slot, new(dye, dye));
|
||||
flags |= slot.ToFlag();
|
||||
flags |= slot.ToStainFlag();
|
||||
}
|
||||
|
|
@ -79,7 +79,7 @@ public sealed class CharaFile
|
|||
return;
|
||||
|
||||
data.SetItem(slot, item);
|
||||
data.SetStain(slot, dye);
|
||||
data.SetStain(slot, new(dye, dye));
|
||||
flags |= slot.ToFlag();
|
||||
flags |= slot.ToStainFlag();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ public sealed class CmaFile
|
|||
if (offhand == null)
|
||||
{
|
||||
data.SetItem(EquipSlot.MainHand, defaultOffhand);
|
||||
data.SetStain(EquipSlot.MainHand, defaultOffhand.PrimaryId.Id == 0 ? 0 : data.Stain(EquipSlot.MainHand));
|
||||
data.SetStain(EquipSlot.MainHand, defaultOffhand.PrimaryId.Id == 0 ? StainIds.None : data.Stain(EquipSlot.MainHand));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ public sealed unsafe class CrestService : EventWrapperRef3<Actor, CrestFlag, boo
|
|||
if (!model.IsHuman)
|
||||
return false;
|
||||
|
||||
var getter = (delegate* unmanaged<Human*, byte, byte>)((nint*)model.AsCharacterBase->VTable)[95];
|
||||
var getter = (delegate* unmanaged<Human*, byte, byte>)((nint*)model.AsCharacterBase->VirtualTable)[95];
|
||||
return getter(model.AsHuman, index) != 0;
|
||||
}
|
||||
case CrestType.Offhand:
|
||||
|
|
@ -105,7 +105,7 @@ public sealed unsafe class CrestService : EventWrapperRef3<Actor, CrestFlag, boo
|
|||
if (!model.IsWeapon)
|
||||
return false;
|
||||
|
||||
var getter = (delegate* unmanaged<Weapon*, byte, byte>)((nint*)model.AsCharacterBase->VTable)[95];
|
||||
var getter = (delegate* unmanaged<Weapon*, byte, byte>)((nint*)model.AsCharacterBase->VirtualTable)[95];
|
||||
return getter(model.AsWeapon, index) != 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ public sealed unsafe class InventoryService : IDisposable, IRequiredService
|
|||
{
|
||||
private readonly MovedEquipment _movedItemsEvent;
|
||||
private readonly EquippedGearset _gearsetEvent;
|
||||
private readonly List<(EquipSlot, uint, StainId)> _itemList = new(12);
|
||||
private readonly List<(EquipSlot, uint, StainIds)> _itemList = new(12);
|
||||
|
||||
public InventoryService(MovedEquipment movedItemsEvent, IGameInteropProvider interop, EquippedGearset gearsetEvent)
|
||||
{
|
||||
|
|
@ -60,56 +60,56 @@ public sealed unsafe class InventoryService : IDisposable, IRequiredService
|
|||
|
||||
if (glamourPlateId != 0)
|
||||
{
|
||||
void Add(EquipSlot slot, uint glamourId, StainId glamourStain, ref RaptureGearsetModule.GearsetItem item)
|
||||
void Add(EquipSlot slot, uint glamourId, StainId glamourStain1, StainId glamourStain2, ref RaptureGearsetModule.GearsetItem item)
|
||||
{
|
||||
if (item.ItemID == 0)
|
||||
_itemList.Add((slot, 0, 0));
|
||||
if (item.ItemId == 0)
|
||||
_itemList.Add((slot, 0, new(0, 0)));
|
||||
else if (glamourId != 0)
|
||||
_itemList.Add((slot, glamourId, glamourStain));
|
||||
_itemList.Add((slot, glamourId, new(glamourStain1, glamourStain2)));
|
||||
else if (item.GlamourId != 0)
|
||||
_itemList.Add((slot, item.GlamourId, item.Stain));
|
||||
_itemList.Add((slot, item.GlamourId, new(item.Stain0Id, item.Stain1Id)));
|
||||
else
|
||||
_itemList.Add((slot, FixId(item.ItemID), item.Stain));
|
||||
_itemList.Add((slot, FixId(item.ItemId), new(item.Stain0Id, item.Stain1Id)));
|
||||
}
|
||||
|
||||
var plate = MirageManager.Instance()->GlamourPlatesSpan[glamourPlateId - 1];
|
||||
Add(EquipSlot.MainHand, plate.ItemIds[0], plate.StainIds[0], ref entry->ItemsSpan[0]);
|
||||
Add(EquipSlot.OffHand, plate.ItemIds[1], plate.StainIds[1], ref entry->ItemsSpan[1]);
|
||||
Add(EquipSlot.Head, plate.ItemIds[2], plate.StainIds[2], ref entry->ItemsSpan[2]);
|
||||
Add(EquipSlot.Body, plate.ItemIds[3], plate.StainIds[3], ref entry->ItemsSpan[3]);
|
||||
Add(EquipSlot.Hands, plate.ItemIds[4], plate.StainIds[4], ref entry->ItemsSpan[5]);
|
||||
Add(EquipSlot.Legs, plate.ItemIds[5], plate.StainIds[5], ref entry->ItemsSpan[6]);
|
||||
Add(EquipSlot.Feet, plate.ItemIds[6], plate.StainIds[6], ref entry->ItemsSpan[7]);
|
||||
Add(EquipSlot.Ears, plate.ItemIds[7], plate.StainIds[7], ref entry->ItemsSpan[8]);
|
||||
Add(EquipSlot.Neck, plate.ItemIds[8], plate.StainIds[8], ref entry->ItemsSpan[9]);
|
||||
Add(EquipSlot.Wrists, plate.ItemIds[9], plate.StainIds[9], ref entry->ItemsSpan[10]);
|
||||
Add(EquipSlot.RFinger, plate.ItemIds[10], plate.StainIds[10], ref entry->ItemsSpan[11]);
|
||||
Add(EquipSlot.LFinger, plate.ItemIds[11], plate.StainIds[11], ref entry->ItemsSpan[12]);
|
||||
var plate = MirageManager.Instance()->GlamourPlates[glamourPlateId - 1];
|
||||
Add(EquipSlot.MainHand, plate.ItemIds[0], plate.Stain0Ids[0], plate.Stain1Ids[0], ref entry->Items[0]);
|
||||
Add(EquipSlot.OffHand, plate.ItemIds[1], plate.Stain0Ids[1], plate.Stain1Ids[1], ref entry->Items[1]);
|
||||
Add(EquipSlot.Head, plate.ItemIds[2], plate.Stain0Ids[2], plate.Stain1Ids[2], ref entry->Items[2]);
|
||||
Add(EquipSlot.Body, plate.ItemIds[3], plate.Stain0Ids[3], plate.Stain1Ids[3], ref entry->Items[3]);
|
||||
Add(EquipSlot.Hands, plate.ItemIds[4], plate.Stain0Ids[4], plate.Stain1Ids[4], ref entry->Items[5]);
|
||||
Add(EquipSlot.Legs, plate.ItemIds[5], plate.Stain0Ids[5], plate.Stain1Ids[5], ref entry->Items[6]);
|
||||
Add(EquipSlot.Feet, plate.ItemIds[6], plate.Stain0Ids[6], plate.Stain1Ids[6], ref entry->Items[7]);
|
||||
Add(EquipSlot.Ears, plate.ItemIds[7], plate.Stain0Ids[7], plate.Stain1Ids[7], ref entry->Items[8]);
|
||||
Add(EquipSlot.Neck, plate.ItemIds[8], plate.Stain0Ids[8], plate.Stain1Ids[8], ref entry->Items[9]);
|
||||
Add(EquipSlot.Wrists, plate.ItemIds[9], plate.Stain0Ids[9], plate.Stain1Ids[9], ref entry->Items[10]);
|
||||
Add(EquipSlot.RFinger, plate.ItemIds[10], plate.Stain0Ids[10], plate.Stain1Ids[10], ref entry->Items[11]);
|
||||
Add(EquipSlot.LFinger, plate.ItemIds[11], plate.Stain0Ids[11], plate.Stain1Ids[11], ref entry->Items[12]);
|
||||
}
|
||||
else
|
||||
{
|
||||
void Add(EquipSlot slot, ref RaptureGearsetModule.GearsetItem item)
|
||||
{
|
||||
if (item.ItemID == 0)
|
||||
_itemList.Add((slot, 0, 0));
|
||||
if (item.ItemId == 0)
|
||||
_itemList.Add((slot, 0, new(0, 0)));
|
||||
else if (item.GlamourId != 0)
|
||||
_itemList.Add((slot, item.GlamourId, item.Stain));
|
||||
_itemList.Add((slot, item.GlamourId, new(item.Stain0Id, item.Stain1Id)));
|
||||
else
|
||||
_itemList.Add((slot, FixId(item.ItemID), item.Stain));
|
||||
_itemList.Add((slot, FixId(item.ItemId), new(item.Stain0Id, item.Stain1Id)));
|
||||
}
|
||||
|
||||
Add(EquipSlot.MainHand, ref entry->ItemsSpan[0]);
|
||||
Add(EquipSlot.OffHand, ref entry->ItemsSpan[1]);
|
||||
Add(EquipSlot.Head, ref entry->ItemsSpan[2]);
|
||||
Add(EquipSlot.Body, ref entry->ItemsSpan[3]);
|
||||
Add(EquipSlot.Hands, ref entry->ItemsSpan[5]);
|
||||
Add(EquipSlot.Legs, ref entry->ItemsSpan[6]);
|
||||
Add(EquipSlot.Feet, ref entry->ItemsSpan[7]);
|
||||
Add(EquipSlot.Ears, ref entry->ItemsSpan[8]);
|
||||
Add(EquipSlot.Neck, ref entry->ItemsSpan[9]);
|
||||
Add(EquipSlot.Wrists, ref entry->ItemsSpan[10]);
|
||||
Add(EquipSlot.RFinger, ref entry->ItemsSpan[11]);
|
||||
Add(EquipSlot.LFinger, ref entry->ItemsSpan[12]);
|
||||
Add(EquipSlot.MainHand, ref entry->Items[0]);
|
||||
Add(EquipSlot.OffHand, ref entry->Items[1]);
|
||||
Add(EquipSlot.Head, ref entry->Items[2]);
|
||||
Add(EquipSlot.Body, ref entry->Items[3]);
|
||||
Add(EquipSlot.Hands, ref entry->Items[5]);
|
||||
Add(EquipSlot.Legs, ref entry->Items[6]);
|
||||
Add(EquipSlot.Feet, ref entry->Items[7]);
|
||||
Add(EquipSlot.Ears, ref entry->Items[8]);
|
||||
Add(EquipSlot.Neck, ref entry->Items[9]);
|
||||
Add(EquipSlot.Wrists, ref entry->Items[10]);
|
||||
Add(EquipSlot.RFinger, ref entry->Items[11]);
|
||||
Add(EquipSlot.LFinger, ref entry->Items[12]);
|
||||
}
|
||||
|
||||
_movedItemsEvent.Invoke(_itemList.ToArray());
|
||||
|
|
@ -155,7 +155,7 @@ public sealed unsafe class InventoryService : IDisposable, IRequiredService
|
|||
return ret;
|
||||
}
|
||||
|
||||
private static bool InvokeSource(InventoryType sourceContainer, uint sourceSlot, out (EquipSlot, uint, StainId) tuple)
|
||||
private static bool InvokeSource(InventoryType sourceContainer, uint sourceSlot, out (EquipSlot, uint, StainIds) tuple)
|
||||
{
|
||||
tuple = default;
|
||||
if (sourceContainer is not InventoryType.EquippedItems)
|
||||
|
|
@ -165,12 +165,12 @@ public sealed unsafe class InventoryService : IDisposable, IRequiredService
|
|||
if (slot is EquipSlot.Unknown)
|
||||
return false;
|
||||
|
||||
tuple = (slot, 0u, 0);
|
||||
tuple = (slot, 0u, StainIds.None);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool InvokeTarget(InventoryManager* manager, InventoryType targetContainer, uint targetSlot,
|
||||
out (EquipSlot, uint, StainId) tuple)
|
||||
out (EquipSlot, uint, StainIds) tuple)
|
||||
{
|
||||
tuple = default;
|
||||
if (targetContainer is not InventoryType.EquippedItems)
|
||||
|
|
@ -189,7 +189,7 @@ public sealed unsafe class InventoryService : IDisposable, IRequiredService
|
|||
if (item == null)
|
||||
return false;
|
||||
|
||||
tuple = (slot, item->GlamourID != 0 ? item->GlamourID : item->ItemID, item->Stain);
|
||||
tuple = (slot, item->GlamourId != 0 ? item->GlamourId : item->ItemId, new(item->Stains[0], item->Stains[1]));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,12 +48,14 @@ public unsafe class MetaService : IDisposable
|
|||
if (!actor.IsCharacter)
|
||||
return;
|
||||
|
||||
actor.AsCharacter->DrawData.SetVisor(value);
|
||||
|
||||
// The function seems to not do anything if the head is 0, but also breaks for carbuncles turned human, sometimes?
|
||||
var old = actor.AsCharacter->DrawData.Head.Id;
|
||||
/* var old = actor.AsCharacter->DrawData.Head.Id;
|
||||
if (old == 0 && actor.AsCharacter->CharacterData.ModelCharaId == 0)
|
||||
actor.AsCharacter->DrawData.Head.Id = 1;
|
||||
_hideHatGearHook.Original(&actor.AsCharacter->DrawData, 0, (byte)(value ? 0 : 1));
|
||||
actor.AsCharacter->DrawData.Head.Id = old;
|
||||
actor.AsCharacter->DrawData.Head.Id = old; */
|
||||
}
|
||||
|
||||
public void SetWeaponState(Actor actor, bool value)
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ public sealed class CollectionOverrideService : IService, ISavable
|
|||
var collection = _penumbra.CollectionByIdentifier(collectionIdentifier);
|
||||
if (collection == null)
|
||||
{
|
||||
Glamourer.Messager.AddMessage(new Notification(
|
||||
Glamourer.Messager.AddMessage(new OtterGui.Classes.Notification(
|
||||
$"The overridden collection for identifier {identifier.Incognito(null)} with name {collectionIdentifier} could not be found by Penumbra for migration.",
|
||||
NotificationType.Warning));
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -195,16 +195,16 @@ public class ItemManager
|
|||
/// The returned stain id is either the input or 0.
|
||||
/// The return value is an empty string if there was no problem and a warning otherwise.
|
||||
/// </summary>
|
||||
public string ValidateStain(StainId stain, out StainId ret, bool allowUnknown)
|
||||
public string ValidateStain(StainIds stains, out StainIds ret, bool allowUnknown)
|
||||
{
|
||||
if (allowUnknown || IsStainValid(stain))
|
||||
if (allowUnknown || IsStainValid(stains[0]) && IsStainValid(stains[1]))
|
||||
{
|
||||
ret = stain;
|
||||
ret = stains;
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
return $"The Stain {stain} does not exist, reset to unstained.";
|
||||
ret = StainIds.None;
|
||||
return $"The Stains {stains} does not exist, reset to unstained.";
|
||||
}
|
||||
|
||||
/// <summary> Returns whether an offhand is valid given the required offhand type. </summary>
|
||||
|
|
|
|||
|
|
@ -152,11 +152,11 @@ public class InternalStateEditor(
|
|||
}
|
||||
|
||||
/// <summary> Change a single piece of equipment including stain. </summary>
|
||||
public bool ChangeEquip(ActorState state, EquipSlot slot, EquipItem item, StainId stain, StateSource source, out EquipItem oldItem,
|
||||
out StainId oldStain, uint key = 0)
|
||||
public bool ChangeEquip(ActorState state, EquipSlot slot, EquipItem item, StainIds stains, StateSource source, out EquipItem oldItem,
|
||||
out StainIds oldStains, uint key = 0)
|
||||
{
|
||||
oldItem = state.ModelData.Item(slot);
|
||||
oldStain = state.ModelData.Stain(slot);
|
||||
oldStains = state.ModelData.Stain(slot);
|
||||
if (!state.CanUnlock(key))
|
||||
return false;
|
||||
|
||||
|
|
@ -168,7 +168,7 @@ public class InternalStateEditor(
|
|||
return false;
|
||||
|
||||
var old = oldItem;
|
||||
var oldS = oldStain;
|
||||
var oldS = oldStains;
|
||||
gPose.AddActionOnLeave(() =>
|
||||
{
|
||||
if (old.Type == state.BaseData.Item(slot).Type)
|
||||
|
|
@ -177,16 +177,16 @@ public class InternalStateEditor(
|
|||
}
|
||||
|
||||
state.ModelData.SetItem(slot, item);
|
||||
state.ModelData.SetStain(slot, stain);
|
||||
state.ModelData.SetStain(slot, stains);
|
||||
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, StainIds stains, StateSource source, out StainId oldStain, uint key = 0)
|
||||
public bool ChangeStain(ActorState state, EquipSlot slot, StainIds stains, StateSource source, out StainIds oldStains, uint key = 0)
|
||||
{
|
||||
oldStain = state.ModelData.Stain(slot);
|
||||
oldStains = state.ModelData.Stain(slot);
|
||||
if (!state.CanUnlock(key))
|
||||
return false;
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ public class StateEditor(
|
|||
ApplyMainhandPeriphery(state, item, stains, settings);
|
||||
|
||||
Glamourer.Log.Verbose(
|
||||
$"Set {slot.ToName()} in state {state.Identifier.Incognito(null)} from {old.Name} ({old.ItemId}) to {item!.Value.Name} ({item.Value.ItemId}) and its stain from {oldStain.Id} to {stain!.Value.Id}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
$"Set {slot.ToName()} in state {state.Identifier.Incognito(null)} from {old.Name} ({old.ItemId}) to {item!.Value.Name} ({item.Value.ItemId}) and its stains from {oldStain[0]},{oldStain[1]} to {stains!.Value[0]}, {stains!.Value[1]}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
StateChanged.Invoke(type, settings.Source, state, actors, (old, item!.Value, slot));
|
||||
StateChanged.Invoke(StateChangeType.Stain, settings.Source, state, actors, (oldStain, stains!.Value, slot));
|
||||
}
|
||||
|
|
@ -132,7 +132,7 @@ public class StateEditor(
|
|||
|
||||
var actors = Applier.ChangeStain(state, slot, settings.Source.RequiresChange());
|
||||
Glamourer.Log.Verbose(
|
||||
$"Set {slot.ToName()} stain in state {state.Identifier.Incognito(null)} from {old.Id} to {stains.ToString()}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
$"Set {slot.ToName()} stain in state {state.Identifier.Incognito(null)} from {old[0]},{old[1]} to {stains.ToString()}. [Affecting {actors.ToLazyString("nothing")}.]");
|
||||
StateChanged.Invoke(StateChangeType.Stain, settings.Source, state, actors, (old, stains, slot));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -227,14 +227,14 @@ public class StateListener : IDisposable
|
|||
(_, armor) = _items.RestrictedGear.ResolveRestricted(armor, slot, customize.Race, customize.Gender);
|
||||
}
|
||||
|
||||
private void OnMovedEquipment((EquipSlot, uint, StainId)[] items)
|
||||
private void OnMovedEquipment((EquipSlot, uint, StainIds)[] items)
|
||||
{
|
||||
_objects.Update();
|
||||
var (identifier, objects) = _objects.PlayerData;
|
||||
if (!identifier.IsValid || !_manager.TryGetValue(identifier, out var state))
|
||||
return;
|
||||
|
||||
foreach (var (slot, item, stain) in items)
|
||||
foreach (var (slot, item, stains) in items)
|
||||
{
|
||||
var currentItem = state.BaseData.Item(slot);
|
||||
var model = slot is EquipSlot.MainHand or EquipSlot.OffHand
|
||||
|
|
@ -244,7 +244,7 @@ public class StateListener : IDisposable
|
|||
if (model.Value == current.Value || !_items.ItemData.TryGetValue(item, EquipSlot.MainHand, out var changedItem))
|
||||
continue;
|
||||
|
||||
var changed = changedItem.Weapon(stain);
|
||||
var changed = changedItem.Weapon(stains);
|
||||
var itemChanged = current.Skeleton == changed.Skeleton
|
||||
&& current.Variant == changed.Variant
|
||||
&& current.Weapon == changed.Weapon
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ public class CustomizeUnlockManager : IDisposable, ISavable
|
|||
IDataManager gameData)
|
||||
{
|
||||
var ret = new Dictionary<CustomizeData, (uint Data, string Name)>();
|
||||
var sheet = gameData.GetExcelSheet<CharaMakeCustomize>(ClientLanguage.English)!;
|
||||
var sheet = gameData.GetExcelSheet<CharaMakeCustomize>(Dalamud.Game.ClientLanguage.English)!;
|
||||
foreach (var (clan, gender) in CustomizeManager.AllSets())
|
||||
{
|
||||
var list = customizations.Manager.GetSet(clan, gender);
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ public class ItemUnlockManager : ISavable, IDisposable, IReadOnlyDictionary<Item
|
|||
if (newPlateState != _lastPlateState)
|
||||
{
|
||||
_lastPlateState = newPlateState;
|
||||
foreach (var plate in mirageManager->GlamourPlatesSpan)
|
||||
foreach (var plate in mirageManager->GlamourPlates)
|
||||
{
|
||||
// TODO: Make independent from hardcoded value
|
||||
var span = new ReadOnlySpan<uint>(plate.ItemIds, 12);
|
||||
|
|
@ -176,8 +176,8 @@ public class ItemUnlockManager : ISavable, IDisposable, IReadOnlyDictionary<Item
|
|||
var item = container->GetInventorySlot(_currentInventoryIndex++);
|
||||
if (item != null)
|
||||
{
|
||||
changes |= AddItem(item->ItemID, time);
|
||||
changes |= AddItem(item->GlamourID, time);
|
||||
changes |= AddItem(item->ItemId, time);
|
||||
changes |= AddItem(item->GlamourId, time);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue