mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-15 05:04:16 +01:00
Some more interface work.
This commit is contained in:
parent
6f34d74752
commit
129f9e070f
17 changed files with 485 additions and 243 deletions
|
|
@ -81,7 +81,7 @@ public static class DesignBase64Migration
|
||||||
data.SetItem(EquipSlot.MainHand, main);
|
data.SetItem(EquipSlot.MainHand, main);
|
||||||
data.SetStain(EquipSlot.MainHand, cur[0].Stain);
|
data.SetStain(EquipSlot.MainHand, cur[0].Stain);
|
||||||
var off = items.Identify(EquipSlot.OffHand, cur[1].Set, cur[1].Type, (byte)cur[1].Variant, main.Type);
|
var off = items.Identify(EquipSlot.OffHand, cur[1].Set, cur[1].Type, (byte)cur[1].Variant, main.Type);
|
||||||
if (main.Type.Offhand() != FullEquipType.Unknown && !off.Valid)
|
if (main.Type.ValidOffhand() != FullEquipType.Unknown && !off.Valid)
|
||||||
throw new Exception($"Base64 string invalid, weapon could not be identified.");
|
throw new Exception($"Base64 string invalid, weapon could not be identified.");
|
||||||
|
|
||||||
data.SetItem(EquipSlot.OffHand, off);
|
data.SetItem(EquipSlot.OffHand, off);
|
||||||
|
|
|
||||||
|
|
@ -337,10 +337,8 @@ public class DesignManager
|
||||||
|
|
||||||
if (item.Type != currentMain.Type)
|
if (item.Type != currentMain.Type)
|
||||||
{
|
{
|
||||||
var newOffId = item.Type.Offhand().IsOffhandType()
|
var defaultOffhand = _items.GetDefaultOffhand(item);
|
||||||
? item.ItemId
|
if (!_items.IsOffhandValid(item, defaultOffhand.ItemId, out newOff))
|
||||||
: ItemManager.NothingId(item.Type.Offhand());
|
|
||||||
if (!_items.IsOffhandValid(item, newOffId, out newOff))
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using Dalamud.Data;
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
|
using Glamourer.Structs;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
|
|
@ -33,7 +34,7 @@ public class EquipmentDrawer
|
||||||
_codes = codes;
|
_codes = codes;
|
||||||
_textures = textures;
|
_textures = textures;
|
||||||
_stainData = items.Stains;
|
_stainData = items.Stains;
|
||||||
_stainCombo = new FilterComboColors(140,
|
_stainCombo = new FilterComboColors(280,
|
||||||
_stainData.Data.Prepend(new KeyValuePair<byte, (string Name, uint Dye, bool Gloss)>(0, ("None", 0, false))));
|
_stainData.Data.Prepend(new KeyValuePair<byte, (string Name, uint Dye, bool Gloss)>(0, ("None", 0, false))));
|
||||||
_itemCombo = EquipSlotExtensions.EqdpSlots.Select(e => new ItemCombo(gameData, items, e, textures)).ToArray();
|
_itemCombo = EquipSlotExtensions.EqdpSlots.Select(e => new ItemCombo(gameData, items, e, textures)).ToArray();
|
||||||
_weaponCombo = new Dictionary<FullEquipType, WeaponCombo>(FullEquipTypeExtensions.WeaponTypes.Count * 2);
|
_weaponCombo = new Dictionary<FullEquipType, WeaponCombo>(FullEquipTypeExtensions.WeaponTypes.Count * 2);
|
||||||
|
|
@ -54,39 +55,262 @@ public class EquipmentDrawer
|
||||||
public void Prepare()
|
public void Prepare()
|
||||||
{
|
{
|
||||||
_iconSize = new Vector2(2 * ImGui.GetFrameHeight() + ImGui.GetStyle().ItemSpacing.Y);
|
_iconSize = new Vector2(2 * ImGui.GetFrameHeight() + ImGui.GetStyle().ItemSpacing.Y);
|
||||||
_comboLength = 320 * ImGuiHelpers.GlobalScale;
|
_comboLength = 300 * ImGuiHelpers.GlobalScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string VerifyRestrictedGear(EquipItem gear, EquipSlot slot, Gender gender, Race race)
|
private bool VerifyRestrictedGear(EquipSlot slot, EquipItem gear, Gender gender, Race race)
|
||||||
{
|
{
|
||||||
if (slot.IsAccessory())
|
if (slot.IsAccessory())
|
||||||
return gear.Name;
|
return false;
|
||||||
|
|
||||||
var (changed, _) = _items.ResolveRestrictedGear(gear.Armor(), slot, race, gender);
|
var (changed, _) = _items.ResolveRestrictedGear(gear.Armor(), slot, race, gender);
|
||||||
if (changed)
|
return changed;
|
||||||
return gear.Name + " (Restricted)";
|
|
||||||
|
|
||||||
return gear.Name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DrawArmor(EquipItem current, EquipSlot slot, out EquipItem armor, Gender gender = Gender.Unknown, Race race = Race.Unknown)
|
[Flags]
|
||||||
|
public enum EquipChange : byte
|
||||||
{
|
{
|
||||||
Debug.Assert(slot.IsEquipment() || slot.IsAccessory(), $"Called {nameof(DrawArmor)} on {slot}.");
|
None = 0x00,
|
||||||
|
Item = 0x01,
|
||||||
|
Stain = 0x02,
|
||||||
|
ApplyItem = 0x04,
|
||||||
|
ApplyStain = 0x08,
|
||||||
|
Item2 = 0x10,
|
||||||
|
Stain2 = 0x20,
|
||||||
|
ApplyItem2 = 0x40,
|
||||||
|
ApplyStain2 = 0x80,
|
||||||
|
}
|
||||||
|
|
||||||
if (_codes.EnabledArtisan)
|
public EquipChange DrawEquip(EquipSlot slot, in DesignData designData, out EquipItem rArmor, out StainId rStain, EquipFlag? cApply,
|
||||||
return DrawArmorArtisan(current, slot, out armor, gender, race);
|
out bool rApply, out bool rApplyStain, bool locked)
|
||||||
|
=> DrawEquip(slot, designData.Item(slot), out rArmor, designData.Stain(slot), out rStain, cApply, out rApply, out rApplyStain, locked,
|
||||||
|
designData.Customize.Gender, designData.Customize.Race);
|
||||||
|
|
||||||
current.DrawIcon(_textures, _iconSize);
|
public EquipChange DrawEquip(EquipSlot slot, EquipItem cArmor, out EquipItem rArmor, StainId cStain, out StainId rStain, EquipFlag? cApply,
|
||||||
|
out bool rApply, out bool rApplyStain, bool locked, Gender gender = Gender.Unknown, Race race = Race.Unknown)
|
||||||
|
{
|
||||||
|
if (!locked && _codes.EnabledArtisan)
|
||||||
|
return DrawEquipArtisan(slot, cArmor, out rArmor, cStain, out rStain, cApply, out rApply, out rApplyStain);
|
||||||
|
|
||||||
|
var spacing = ImGui.GetStyle().ItemInnerSpacing with { Y = ImGui.GetStyle().ItemSpacing.Y };
|
||||||
|
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing);
|
||||||
|
|
||||||
|
var changes = EquipChange.None;
|
||||||
|
cArmor.DrawIcon(_textures, _iconSize);
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
using var group = ImRaii.Group();
|
using var group = ImRaii.Group();
|
||||||
|
if (DrawItem(slot, cArmor, out rArmor, out var label, locked))
|
||||||
|
changes |= EquipChange.Item;
|
||||||
|
if (cApply.HasValue)
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (DrawApply(slot, cApply.Value, out rApply, locked))
|
||||||
|
changes |= EquipChange.ApplyItem;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rApply = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.TextUnformatted(label);
|
||||||
|
if (DrawStain(slot, cStain, out rStain, locked))
|
||||||
|
changes |= EquipChange.Stain;
|
||||||
|
if (cApply.HasValue)
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (DrawApplyStain(slot, cApply.Value, out rApplyStain, locked))
|
||||||
|
changes |= EquipChange.ApplyStain;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rApplyStain = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VerifyRestrictedGear(slot, rArmor, gender, race))
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.TextUnformatted("(Restricted)");
|
||||||
|
}
|
||||||
|
|
||||||
|
return changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EquipChange DrawWeapons(in DesignData designData, out EquipItem rMainhand, out EquipItem rOffhand, out StainId rMainhandStain,
|
||||||
|
out StainId rOffhandStain, EquipFlag? cApply, out bool rApplyMainhand, out bool rApplyMainhandStain, out bool rApplyOffhand,
|
||||||
|
out bool rApplyOffhandStain, bool locked)
|
||||||
|
=> DrawWeapons(designData.Item(EquipSlot.MainHand), out rMainhand, designData.Item(EquipSlot.OffHand), out rOffhand,
|
||||||
|
designData.Stain(EquipSlot.MainHand), out rMainhandStain, designData.Stain(EquipSlot.OffHand), out rOffhandStain, cApply,
|
||||||
|
out rApplyMainhand, out rApplyMainhandStain, out rApplyOffhand, out rApplyOffhandStain, locked);
|
||||||
|
|
||||||
|
public EquipChange DrawWeapons(EquipItem cMainhand, out EquipItem rMainhand, EquipItem cOffhand, out EquipItem rOffhand,
|
||||||
|
StainId cMainhandStain, out StainId rMainhandStain, StainId cOffhandStain, out StainId rOffhandStain, EquipFlag? cApply,
|
||||||
|
out bool rApplyMainhand, out bool rApplyMainhandStain, out bool rApplyOffhand, out bool rApplyOffhandStain, bool locked)
|
||||||
|
{
|
||||||
|
var changes = EquipChange.None;
|
||||||
|
|
||||||
|
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing,
|
||||||
|
ImGui.GetStyle().ItemInnerSpacing with { Y = ImGui.GetStyle().ItemSpacing.Y });
|
||||||
|
|
||||||
|
cMainhand.DrawIcon(_textures, _iconSize);
|
||||||
|
ImGui.SameLine();
|
||||||
|
using (var group = ImRaii.Group())
|
||||||
|
{
|
||||||
|
rOffhand = cOffhand;
|
||||||
|
if (DrawMainhand(cMainhand, cApply.HasValue, out rMainhand, out var mainhandLabel, locked))
|
||||||
|
{
|
||||||
|
changes |= EquipChange.Item;
|
||||||
|
if (rMainhand.Type.ValidOffhand() != cMainhand.Type.ValidOffhand())
|
||||||
|
{
|
||||||
|
rOffhand = _items.GetDefaultOffhand(rMainhand);
|
||||||
|
changes |= EquipChange.Item2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cApply.HasValue)
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (DrawApply(EquipSlot.MainHand, cApply.Value, out rApplyMainhand, locked))
|
||||||
|
changes |= EquipChange.ApplyItem;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rApplyMainhand = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.TextUnformatted(mainhandLabel);
|
||||||
|
|
||||||
|
if (DrawStain(EquipSlot.MainHand, cMainhandStain, out rMainhandStain, locked))
|
||||||
|
changes |= EquipChange.Stain;
|
||||||
|
if (cApply.HasValue)
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (DrawApplyStain(EquipSlot.MainHand, cApply.Value, out rApplyMainhandStain, locked))
|
||||||
|
changes |= EquipChange.ApplyStain;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rApplyMainhandStain = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rOffhand.Type is FullEquipType.Unknown)
|
||||||
|
{
|
||||||
|
rOffhandStain = cOffhandStain;
|
||||||
|
rApplyOffhand = false;
|
||||||
|
rApplyOffhandStain = false;
|
||||||
|
return changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
rOffhand.DrawIcon(_textures, _iconSize);
|
||||||
|
ImGui.SameLine();
|
||||||
|
using (var group = ImRaii.Group())
|
||||||
|
{
|
||||||
|
if (DrawOffhand(rMainhand, rOffhand, out rOffhand, out var offhandLabel, locked))
|
||||||
|
changes |= EquipChange.Item2;
|
||||||
|
if (cApply.HasValue)
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (DrawApply(EquipSlot.OffHand, cApply.Value, out rApplyOffhand, locked))
|
||||||
|
changes |= EquipChange.ApplyItem2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rApplyOffhand = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.TextUnformatted(offhandLabel);
|
||||||
|
|
||||||
|
if (DrawStain(EquipSlot.OffHand, cOffhandStain, out rOffhandStain, locked))
|
||||||
|
changes |= EquipChange.Stain2;
|
||||||
|
if (cApply.HasValue)
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (DrawApplyStain(EquipSlot.OffHand, cApply.Value, out rApplyOffhandStain, locked))
|
||||||
|
changes |= EquipChange.ApplyStain2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rApplyOffhandStain = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool DrawMainhand(EquipItem current, bool drawAll, out EquipItem weapon, out string label, bool locked)
|
||||||
|
{
|
||||||
|
weapon = current;
|
||||||
|
if (!_weaponCombo.TryGetValue(drawAll ? FullEquipType.Unknown : current.Type, out var combo))
|
||||||
|
{
|
||||||
|
label = string.Empty;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
label = combo.Label;
|
||||||
|
using var disabled = ImRaii.Disabled(locked);
|
||||||
|
if (!combo.Draw(weapon.Name, weapon.ItemId, _comboLength))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
weapon = combo.CurrentSelection;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool DrawOffhand(EquipItem mainhand, EquipItem current, out EquipItem weapon, out string label, bool locked)
|
||||||
|
{
|
||||||
|
weapon = current;
|
||||||
|
if (!_weaponCombo.TryGetValue(current.Type, out var combo))
|
||||||
|
{
|
||||||
|
label = string.Empty;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
label = combo.Label;
|
||||||
|
using var disabled = ImRaii.Disabled(locked);
|
||||||
|
var change = combo.Draw(weapon.Name, weapon.ItemId, _comboLength);
|
||||||
|
if (change)
|
||||||
|
weapon = combo.CurrentSelection;
|
||||||
|
|
||||||
|
if (!locked)
|
||||||
|
{
|
||||||
|
var defaultOffhand = _items.GetDefaultOffhand(mainhand);
|
||||||
|
if (defaultOffhand.Id != weapon.Id)
|
||||||
|
{
|
||||||
|
ImGuiUtil.HoverTooltip("Right-click to set to Default.");
|
||||||
|
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||||
|
{
|
||||||
|
change = true;
|
||||||
|
weapon = defaultOffhand;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return change;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool DrawApply(EquipSlot slot, EquipFlag flags, out bool enabled, bool locked)
|
||||||
|
=> UiHelpers.DrawCheckbox($"##apply{slot}", "Apply this item when applying the Design.", flags.HasFlag(slot.ToFlag()), out enabled,
|
||||||
|
locked);
|
||||||
|
|
||||||
|
public bool DrawApplyStain(EquipSlot slot, EquipFlag flags, out bool enabled, bool locked)
|
||||||
|
=> UiHelpers.DrawCheckbox($"##applyStain{slot}", "Apply this dye when applying the Design.", flags.HasFlag(slot.ToStainFlag()),
|
||||||
|
out enabled, locked);
|
||||||
|
|
||||||
|
private bool DrawItem(EquipSlot slot, EquipItem current, out EquipItem armor, out string label, bool locked)
|
||||||
|
{
|
||||||
|
Debug.Assert(slot.IsEquipment() || slot.IsAccessory(), $"Called {nameof(DrawItem)} on {slot}.");
|
||||||
var combo = _itemCombo[slot.ToIndex()];
|
var combo = _itemCombo[slot.ToIndex()];
|
||||||
|
label = combo.Label;
|
||||||
armor = current;
|
armor = current;
|
||||||
var change = combo.Draw(VerifyRestrictedGear(armor, slot, gender, race), armor.ItemId, _comboLength);
|
using var disabled = ImRaii.Disabled(locked);
|
||||||
|
var change = combo.Draw(armor.Name, armor.ItemId, _comboLength);
|
||||||
if (change)
|
if (change)
|
||||||
armor = combo.CurrentSelection;
|
armor = combo.CurrentSelection;
|
||||||
|
|
||||||
if (armor.ModelId.Value != 0)
|
if (!locked && armor.ModelId.Value != 0)
|
||||||
{
|
{
|
||||||
ImGuiUtil.HoverTooltip("Right-click to clear.");
|
ImGuiUtil.HoverTooltip("Right-click to clear.");
|
||||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||||
|
|
@ -99,101 +323,34 @@ public class EquipmentDrawer
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DrawStain(StainId current, EquipSlot slot, out StainId ret)
|
private bool DrawStain(EquipSlot slot, StainId current, out StainId ret, bool locked)
|
||||||
{
|
{
|
||||||
if (_codes.EnabledArtisan)
|
var found = _stainData.TryGetValue(current, out var stain);
|
||||||
return DrawStainArtisan(current, slot, out ret);
|
using var disabled = ImRaii.Disabled(locked);
|
||||||
|
var change = _stainCombo.Draw($"##stain{slot}", stain.RgbaColor, stain.Name, found, stain.Gloss, _comboLength);
|
||||||
var found = _stainData.TryGetValue(current, out var stain);
|
|
||||||
var change = _stainCombo.Draw($"##stain{slot}", stain.RgbaColor, stain.Name, found, stain.Gloss, _comboLength);
|
|
||||||
ret = current;
|
ret = current;
|
||||||
if (change && _stainData.TryGetValue(_stainCombo.CurrentSelection.Key, out stain))
|
if (change && _stainData.TryGetValue(_stainCombo.CurrentSelection.Key, out stain))
|
||||||
ret = stain.RowIndex;
|
ret = stain.RowIndex;
|
||||||
|
|
||||||
ImGuiUtil.HoverTooltip("Right-click to clear.");
|
if (!locked && ret != Stain.None.RowIndex)
|
||||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
|
||||||
{
|
|
||||||
ret = Stain.None.RowIndex;
|
|
||||||
change = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return change;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool DrawMainhand(EquipItem current, bool drawAll, out EquipItem weapon)
|
|
||||||
{
|
|
||||||
weapon = current;
|
|
||||||
if (!_weaponCombo.TryGetValue(drawAll ? FullEquipType.Unknown : current.Type, out var combo))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!combo.Draw(weapon.Name, weapon.ItemId, 320 * ImGuiHelpers.GlobalScale))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
weapon = combo.CurrentSelection;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool DrawOffhand(EquipItem current, FullEquipType mainType, out EquipItem weapon)
|
|
||||||
{
|
|
||||||
weapon = current;
|
|
||||||
var offType = mainType.Offhand();
|
|
||||||
if (offType == FullEquipType.Unknown)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!_weaponCombo.TryGetValue(offType, out var combo))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
var change = combo.Draw(weapon.Name, weapon.ItemId, 320 * ImGuiHelpers.GlobalScale);
|
|
||||||
if (change)
|
|
||||||
{
|
|
||||||
weapon = combo.CurrentSelection;
|
|
||||||
}
|
|
||||||
else if (!offType.IsOffhandType() && weapon.ModelId.Value != 0)
|
|
||||||
{
|
{
|
||||||
ImGuiUtil.HoverTooltip("Right-click to clear.");
|
ImGuiUtil.HoverTooltip("Right-click to clear.");
|
||||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||||
{
|
{
|
||||||
|
ret = Stain.None.RowIndex;
|
||||||
change = true;
|
change = true;
|
||||||
weapon = ItemManager.NothingItem(offType);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DrawApply(Design design, EquipSlot slot, out bool enabled)
|
|
||||||
=> DrawCheckbox($"##apply{slot}", design.DoApplyEquip(slot), out enabled);
|
|
||||||
|
|
||||||
public bool DrawApplyStain(Design design, EquipSlot slot, out bool enabled)
|
|
||||||
=> DrawCheckbox($"##applyStain{slot}", design.DoApplyStain(slot), out enabled);
|
|
||||||
|
|
||||||
private static bool DrawCheckbox(string label, bool value, out bool on)
|
|
||||||
{
|
|
||||||
var ret = ImGuiUtil.Checkbox(label, string.Empty, value, v => value = v);
|
|
||||||
on = value;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool DrawVisor(bool current, out bool on)
|
|
||||||
=> DrawCheckbox("##visorToggled", current, out on);
|
|
||||||
|
|
||||||
public bool DrawHat(bool current, out bool on)
|
|
||||||
=> DrawCheckbox("##hatVisible", current, out on);
|
|
||||||
|
|
||||||
public bool DrawWeapon(bool current, out bool on)
|
|
||||||
=> DrawCheckbox("##weaponVisible", current, out on);
|
|
||||||
|
|
||||||
public bool DrawWetness(bool current, out bool on)
|
|
||||||
=> DrawCheckbox("##wetness", current, out on);
|
|
||||||
|
|
||||||
/// <summary> Draw an input for armor that can set arbitrary values instead of choosing items. </summary>
|
/// <summary> Draw an input for armor that can set arbitrary values instead of choosing items. </summary>
|
||||||
private bool DrawArmorArtisan(EquipItem current, EquipSlot slot, out EquipItem armor, Gender gender = Gender.Unknown,
|
private bool DrawArmorArtisan(EquipSlot slot, EquipItem current, out EquipItem armor)
|
||||||
Race race = Race.Unknown)
|
|
||||||
{
|
{
|
||||||
using var id = ImRaii.PushId((int)slot);
|
int setId = current.ModelId.Value;
|
||||||
int setId = current.ModelId.Value;
|
int variant = current.Variant;
|
||||||
int variant = current.Variant;
|
var ret = false;
|
||||||
var ret = false;
|
|
||||||
armor = current;
|
armor = current;
|
||||||
ImGui.SetNextItemWidth(80 * ImGuiHelpers.GlobalScale);
|
ImGui.SetNextItemWidth(80 * ImGuiHelpers.GlobalScale);
|
||||||
if (ImGui.InputInt("##setId", ref setId, 0, 0))
|
if (ImGui.InputInt("##setId", ref setId, 0, 0))
|
||||||
|
|
@ -222,10 +379,9 @@ public class EquipmentDrawer
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Draw an input for stain that can set arbitrary values instead of choosing valid stains. </summary>
|
/// <summary> Draw an input for stain that can set arbitrary values instead of choosing valid stains. </summary>
|
||||||
private bool DrawStainArtisan(StainId current, EquipSlot slot, out StainId stain)
|
private bool DrawStainArtisan(EquipSlot slot, StainId current, out StainId stain)
|
||||||
{
|
{
|
||||||
using var id = ImRaii.PushId((int)slot);
|
int stainId = current.Value;
|
||||||
int stainId = current.Value;
|
|
||||||
ImGui.SetNextItemWidth(40 * ImGuiHelpers.GlobalScale);
|
ImGui.SetNextItemWidth(40 * ImGuiHelpers.GlobalScale);
|
||||||
if (ImGui.InputInt("##stain", ref stainId, 0, 0))
|
if (ImGui.InputInt("##stain", ref stainId, 0, 0))
|
||||||
{
|
{
|
||||||
|
|
@ -240,4 +396,31 @@ public class EquipmentDrawer
|
||||||
stain = current;
|
stain = current;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private EquipChange DrawEquipArtisan(EquipSlot slot, EquipItem cArmor, out EquipItem rArmor, StainId cStain, out StainId rStain,
|
||||||
|
EquipFlag? cApply, out bool rApply, out bool rApplyStain)
|
||||||
|
{
|
||||||
|
var changes = EquipChange.None;
|
||||||
|
if (DrawStainArtisan(slot, cStain, out rStain))
|
||||||
|
changes |= EquipChange.Stain;
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (DrawArmorArtisan(slot, cArmor, out rArmor))
|
||||||
|
changes |= EquipChange.Item;
|
||||||
|
if (cApply.HasValue)
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (DrawApply(slot, cApply.Value, out rApply, false))
|
||||||
|
changes |= EquipChange.ApplyItem;
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (DrawApplyStain(slot, cApply.Value, out rApplyStain, false))
|
||||||
|
changes |= EquipChange.ApplyStain;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rApply = false;
|
||||||
|
rApplyStain = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ public sealed class ItemCombo : FilterComboCache<EquipItem>
|
||||||
public bool Draw(string previewName, uint previewIdx, float width)
|
public bool Draw(string previewName, uint previewIdx, float width)
|
||||||
{
|
{
|
||||||
_currentItem = previewIdx;
|
_currentItem = previewIdx;
|
||||||
return Draw(Label, previewName, string.Empty, width, ImGui.GetTextLineHeightWithSpacing());
|
return Draw($"##{Label}", previewName, string.Empty, width, ImGui.GetTextLineHeightWithSpacing());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool DrawSelectable(int globalIdx, bool selected)
|
protected override bool DrawSelectable(int globalIdx, bool selected)
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ public sealed class WeaponCombo : FilterComboCache<EquipItem>
|
||||||
public bool Draw(string previewName, uint previewId, float width)
|
public bool Draw(string previewName, uint previewId, float width)
|
||||||
{
|
{
|
||||||
_currentItemId = previewId;
|
_currentItemId = previewId;
|
||||||
return Draw(Label, previewName, string.Empty, width, ImGui.GetTextLineHeightWithSpacing());
|
return Draw($"##{Label}", previewName, string.Empty, width, ImGui.GetTextLineHeightWithSpacing());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool DrawSelectable(int globalIdx, bool selected)
|
protected override bool DrawSelectable(int globalIdx, bool selected)
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ public class MainWindow : Window
|
||||||
pi.UiBuilder.DisableGposeUiHide = true;
|
pi.UiBuilder.DisableGposeUiHide = true;
|
||||||
SizeConstraints = new WindowSizeConstraints()
|
SizeConstraints = new WindowSizeConstraints()
|
||||||
{
|
{
|
||||||
MinimumSize = new Vector2(675, 675),
|
MinimumSize = new Vector2(700, 675),
|
||||||
MaximumSize = ImGui.GetIO().DisplaySize,
|
MaximumSize = ImGui.GetIO().DisplaySize,
|
||||||
};
|
};
|
||||||
Settings = settings;
|
Settings = settings;
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,7 @@ public class PenumbraChangedItemTooltip : IDisposable
|
||||||
if (slot == EquipSlot.MainHand)
|
if (slot == EquipSlot.MainHand)
|
||||||
return item.Type == mainItem.Type;
|
return item.Type == mainItem.Type;
|
||||||
|
|
||||||
return item.Type == mainItem.Type.Offhand();
|
return item.Type == mainItem.Type.ValidOffhand();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPenumbraClick(MouseButton button, ChangedItemType type, uint id)
|
private void OnPenumbraClick(MouseButton button, ChangedItemType type, uint id)
|
||||||
|
|
|
||||||
|
|
@ -69,8 +69,11 @@ public class ActorPanel
|
||||||
{
|
{
|
||||||
var textColor = !_identifier.IsValid ? ImGui.GetColorU32(ImGuiCol.Text) :
|
var textColor = !_identifier.IsValid ? ImGui.GetColorU32(ImGuiCol.Text) :
|
||||||
_data.Valid ? ColorId.ActorAvailable.Value() : ColorId.ActorUnavailable.Value();
|
_data.Valid ? ColorId.ActorAvailable.Value() : ColorId.ActorUnavailable.Value();
|
||||||
HeaderDrawer.Draw(_actorName, textColor, ImGui.GetColorU32(ImGuiCol.FrameBg), 0,
|
HeaderDrawer.Draw(_actorName, textColor, ImGui.GetColorU32(ImGuiCol.FrameBg),
|
||||||
|
3, SetFromClipboardButton(), ExportToClipboardButton(), SaveAsDesignButton(), LockedButton(),
|
||||||
HeaderDrawer.Button.IncognitoButton(_selector.IncognitoMode, v => _selector.IncognitoMode = v));
|
HeaderDrawer.Button.IncognitoButton(_selector.IncognitoMode, v => _selector.IncognitoMode = v));
|
||||||
|
|
||||||
|
SaveDesignDrawPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
private (string, Actor) GetHeaderName()
|
private (string, Actor) GetHeaderName()
|
||||||
|
|
@ -90,12 +93,6 @@ public class ActorPanel
|
||||||
if (!child || !_selector.HasSelection || !_stateManager.GetOrCreate(_identifier, _actor, out _state))
|
if (!child || !_selector.HasSelection || !_stateManager.GetOrCreate(_identifier, _actor, out _state))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SetFromClipboard();
|
|
||||||
ImGui.SameLine();
|
|
||||||
ExportToClipboardButton();
|
|
||||||
ImGui.SameLine();
|
|
||||||
SaveDesignButton();
|
|
||||||
ImGui.SameLine();
|
|
||||||
DrawApplyToSelf();
|
DrawApplyToSelf();
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
DrawApplyToTarget();
|
DrawApplyToTarget();
|
||||||
|
|
@ -116,36 +113,40 @@ public class ActorPanel
|
||||||
_equipmentDrawer.Prepare();
|
_equipmentDrawer.Prepare();
|
||||||
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
||||||
{
|
{
|
||||||
var stain = _state.ModelData.Stain(slot);
|
var changes = _equipmentDrawer.DrawEquip(slot, _state.ModelData, out var newArmor, out var newStain, null, out _, out _,
|
||||||
if (_equipmentDrawer.DrawStain(stain, slot, out var newStain))
|
_state.IsLocked);
|
||||||
_stateManager.ChangeStain(_state, slot, newStain, StateChanged.Source.Manual);
|
switch (changes)
|
||||||
|
{
|
||||||
ImGui.SameLine();
|
case EquipmentDrawer.EquipChange.Item:
|
||||||
var armor = _state.ModelData.Item(slot);
|
_stateManager.ChangeItem(_state, slot, newArmor, StateChanged.Source.Manual);
|
||||||
if (_equipmentDrawer.DrawArmor(armor, slot, out var newArmor, _state.ModelData.Customize.Gender, _state.ModelData.Customize.Race))
|
break;
|
||||||
_stateManager.ChangeEquip(_state, slot, newArmor, newStain, StateChanged.Source.Manual);
|
case EquipmentDrawer.EquipChange.Stain:
|
||||||
|
_stateManager.ChangeStain(_state, slot, newStain, StateChanged.Source.Manual);
|
||||||
|
break;
|
||||||
|
case EquipmentDrawer.EquipChange.Item | EquipmentDrawer.EquipChange.Stain:
|
||||||
|
_stateManager.ChangeEquip(_state, slot, newArmor, newStain, StateChanged.Source.Manual);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var mhStain = _state.ModelData.Stain(EquipSlot.MainHand);
|
var weaponChanges = _equipmentDrawer.DrawWeapons(_state.ModelData, out var newMainhand, out var newOffhand, out var newMainhandStain,
|
||||||
if (_equipmentDrawer.DrawStain(mhStain, EquipSlot.MainHand, out var newMhStain))
|
out var newOffhandStain, null, out _, out _, out _, out _, _state.IsLocked);
|
||||||
_stateManager.ChangeStain(_state, EquipSlot.MainHand, newMhStain, StateChanged.Source.Manual);
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
if (weaponChanges.HasFlag(EquipmentDrawer.EquipChange.Item))
|
||||||
var mh = _state.ModelData.Item(EquipSlot.MainHand);
|
if (weaponChanges.HasFlag(EquipmentDrawer.EquipChange.Stain))
|
||||||
if (_equipmentDrawer.DrawMainhand(mh, false, out var newMh))
|
_stateManager.ChangeEquip(_state, EquipSlot.MainHand, newMainhand, newMainhandStain, StateChanged.Source.Manual);
|
||||||
_stateManager.ChangeEquip(_state, EquipSlot.MainHand, newMh, newMhStain, StateChanged.Source.Manual);
|
else
|
||||||
|
_stateManager.ChangeItem(_state, EquipSlot.MainHand, newMainhand, StateChanged.Source.Manual);
|
||||||
|
else if (weaponChanges.HasFlag(EquipmentDrawer.EquipChange.Stain))
|
||||||
|
_stateManager.ChangeStain(_state, EquipSlot.MainHand, newMainhandStain, StateChanged.Source.Manual);
|
||||||
|
|
||||||
if (newMh.Type.Offhand() is not FullEquipType.Unknown)
|
if (weaponChanges.HasFlag(EquipmentDrawer.EquipChange.Item2))
|
||||||
{
|
if (weaponChanges.HasFlag(EquipmentDrawer.EquipChange.Stain2))
|
||||||
var ohStain = _state.ModelData.Stain(EquipSlot.OffHand);
|
_stateManager.ChangeEquip(_state, EquipSlot.OffHand, newOffhand, newOffhandStain, StateChanged.Source.Manual);
|
||||||
if (_equipmentDrawer.DrawStain(ohStain, EquipSlot.OffHand, out var newOhStain))
|
else
|
||||||
_stateManager.ChangeStain(_state, EquipSlot.OffHand, newOhStain, StateChanged.Source.Manual);
|
_stateManager.ChangeItem(_state, EquipSlot.OffHand, newOffhand, StateChanged.Source.Manual);
|
||||||
|
else if (weaponChanges.HasFlag(EquipmentDrawer.EquipChange.Stain2))
|
||||||
ImGui.SameLine();
|
_stateManager.ChangeStain(_state, EquipSlot.OffHand, newOffhandStain, StateChanged.Source.Manual);
|
||||||
var oh = _state.ModelData.Item(EquipSlot.OffHand);
|
|
||||||
if (_equipmentDrawer.DrawOffhand(oh, newMh.Type, out var newOh))
|
|
||||||
_stateManager.ChangeEquip(_state, EquipSlot.OffHand, newOh, newOhStain, StateChanged.Source.Manual);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawMonsterPanel()
|
private void DrawMonsterPanel()
|
||||||
|
|
@ -209,12 +210,68 @@ public class ActorPanel
|
||||||
_stateManager.TurnHuman(_state, StateChanged.Source.Manual);
|
_stateManager.TurnHuman(_state, StateChanged.Source.Manual);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetFromClipboard()
|
private HeaderDrawer.Button SetFromClipboardButton()
|
||||||
|
=> new()
|
||||||
|
{
|
||||||
|
Description = "Try to apply a design from your clipboard.",
|
||||||
|
Icon = FontAwesomeIcon.Clipboard,
|
||||||
|
OnClick = SetFromClipboard,
|
||||||
|
Visible = _state != null,
|
||||||
|
};
|
||||||
|
|
||||||
|
private HeaderDrawer.Button ExportToClipboardButton()
|
||||||
|
=> new()
|
||||||
|
{
|
||||||
|
Description = "Copy the current design to your clipboard.",
|
||||||
|
Icon = FontAwesomeIcon.Copy,
|
||||||
|
OnClick = ExportToClipboard,
|
||||||
|
Visible = _state?.ModelData.IsHuman ?? false,
|
||||||
|
};
|
||||||
|
|
||||||
|
private HeaderDrawer.Button SaveAsDesignButton()
|
||||||
|
=> new()
|
||||||
|
{
|
||||||
|
Description = "Save the current state as a design.",
|
||||||
|
Icon = FontAwesomeIcon.Save,
|
||||||
|
OnClick = SaveDesignOpen,
|
||||||
|
Visible = _state?.ModelData.IsHuman ?? false,
|
||||||
|
};
|
||||||
|
|
||||||
|
private HeaderDrawer.Button LockedButton()
|
||||||
|
=> new()
|
||||||
|
{
|
||||||
|
Description = "The current state of this actor is locked by external tools.",
|
||||||
|
Icon = FontAwesomeIcon.Lock,
|
||||||
|
OnClick = () => { },
|
||||||
|
Disabled = true,
|
||||||
|
Visible = _state?.IsLocked ?? false,
|
||||||
|
TextColor = ColorId.ActorUnavailable.Value(),
|
||||||
|
BorderColor = ColorId.ActorUnavailable.Value(),
|
||||||
|
};
|
||||||
|
|
||||||
|
private string _newName = string.Empty;
|
||||||
|
private DesignBase? _newDesign = null;
|
||||||
|
|
||||||
|
private void SaveDesignOpen()
|
||||||
{
|
{
|
||||||
if (!ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Clipboard.ToIconString(), new Vector2(ImGui.GetFrameHeight()),
|
ImGui.OpenPopup("Save as Design");
|
||||||
"Try to apply a design from your clipboard.", false, true))
|
_newName = _state!.Identifier.ToName();
|
||||||
|
_newDesign = _converter.Convert(_state, EquipFlagExtensions.All, CustomizeFlagExtensions.All);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveDesignDrawPopup()
|
||||||
|
{
|
||||||
|
if (!ImGuiUtil.OpenNameField("Save as Design", ref _newName))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (_newDesign != null && _newName.Length > 0)
|
||||||
|
_designManager.CreateClone(_newDesign, _newName);
|
||||||
|
_newDesign = null;
|
||||||
|
_newName = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetFromClipboard()
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var text = ImGui.GetClipboardText();
|
var text = ImGui.GetClipboardText();
|
||||||
|
|
@ -228,12 +285,8 @@ public class ActorPanel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ExportToClipboardButton()
|
private void ExportToClipboard()
|
||||||
{
|
{
|
||||||
if (!ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Copy.ToIconString(), new Vector2(ImGui.GetFrameHeight()),
|
|
||||||
"Copy the current design to your clipboard.", false, true))
|
|
||||||
return;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var text = _converter.ShareBase64(_state!);
|
var text = _converter.ShareBase64(_state!);
|
||||||
|
|
@ -267,7 +320,7 @@ public class ActorPanel
|
||||||
{
|
{
|
||||||
var (id, data) = _objects.PlayerData;
|
var (id, data) = _objects.PlayerData;
|
||||||
if (!ImGuiUtil.DrawDisabledButton("Apply to Yourself", Vector2.Zero, "Apply the current state to your own character.",
|
if (!ImGuiUtil.DrawDisabledButton("Apply to Yourself", Vector2.Zero, "Apply the current state to your own character.",
|
||||||
!data.Valid || id == _identifier))
|
!data.Valid || id == _identifier || !_state!.ModelData.IsHuman))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_stateManager.GetOrCreate(id, data.Objects[0], out var state))
|
if (_stateManager.GetOrCreate(id, data.Objects[0], out var state))
|
||||||
|
|
@ -283,33 +336,11 @@ public class ActorPanel
|
||||||
? "Apply the current state to your current target."
|
? "Apply the current state to your current target."
|
||||||
: "The current target can not be manipulated."
|
: "The current target can not be manipulated."
|
||||||
: "No valid target selected.";
|
: "No valid target selected.";
|
||||||
if (!ImGuiUtil.DrawDisabledButton("Apply to Target", Vector2.Zero, tt, !data.Valid || id == _identifier))
|
if (!ImGuiUtil.DrawDisabledButton("Apply to Target", Vector2.Zero, tt, !data.Valid || id == _identifier || !_state!.ModelData.IsHuman))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_stateManager.GetOrCreate(id, data.Objects[0], out var state))
|
if (_stateManager.GetOrCreate(id, data.Objects[0], out var state))
|
||||||
_stateManager.ApplyDesign(_converter.Convert(_state!, EquipFlagExtensions.All, CustomizeFlagExtensions.AllRelevant), state,
|
_stateManager.ApplyDesign(_converter.Convert(_state!, EquipFlagExtensions.All, CustomizeFlagExtensions.AllRelevant), state,
|
||||||
StateChanged.Source.Manual);
|
StateChanged.Source.Manual);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _newName = string.Empty;
|
|
||||||
private DesignBase? _newDesign = null;
|
|
||||||
|
|
||||||
private void SaveDesignButton()
|
|
||||||
{
|
|
||||||
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Save.ToIconString(), new Vector2(ImGui.GetFrameHeight()),
|
|
||||||
"Save the current state as a design.", !_state!.ModelData.IsHuman, true))
|
|
||||||
{
|
|
||||||
ImGui.OpenPopup("Save as Design");
|
|
||||||
_newName = _state.Identifier.ToName();
|
|
||||||
_newDesign = _converter.Convert(_state, EquipFlagExtensions.All, CustomizeFlagExtensions.All);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGuiUtil.OpenNameField("Save as Design", ref _newName))
|
|
||||||
{
|
|
||||||
if (_newDesign != null && _newName.Length > 0)
|
|
||||||
_designManager.CreateClone(_newDesign, _newName);
|
|
||||||
_newDesign = null;
|
|
||||||
_newName = string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,23 +57,39 @@ public class DesignPanel
|
||||||
: _selector.Selected.WriteProtected()
|
: _selector.Selected.WriteProtected()
|
||||||
? new HeaderDrawer.Button
|
? new HeaderDrawer.Button
|
||||||
{
|
{
|
||||||
BorderColor = ColorId.HeaderButtons.Value(),
|
|
||||||
TextColor = ColorId.HeaderButtons.Value(),
|
|
||||||
Description = "Make this design editable.",
|
Description = "Make this design editable.",
|
||||||
Icon = FontAwesomeIcon.Lock,
|
Icon = FontAwesomeIcon.Lock,
|
||||||
OnClick = () => _manager.SetWriteProtection(_selector.Selected!, false),
|
OnClick = () => _manager.SetWriteProtection(_selector.Selected!, false),
|
||||||
}
|
}
|
||||||
: new HeaderDrawer.Button
|
: new HeaderDrawer.Button
|
||||||
{
|
{
|
||||||
BorderColor = ColorId.HeaderButtons.Value(),
|
|
||||||
TextColor = ColorId.HeaderButtons.Value(),
|
|
||||||
Description = "Write-protect this design.",
|
Description = "Write-protect this design.",
|
||||||
Icon = FontAwesomeIcon.LockOpen,
|
Icon = FontAwesomeIcon.LockOpen,
|
||||||
OnClick = () => _manager.SetWriteProtection(_selector.Selected!, true),
|
OnClick = () => _manager.SetWriteProtection(_selector.Selected!, true),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private HeaderDrawer.Button SetFromClipboardButton()
|
||||||
|
=> new()
|
||||||
|
{
|
||||||
|
Description = "Try to apply a design from your clipboard over this design.",
|
||||||
|
Icon = FontAwesomeIcon.Clipboard,
|
||||||
|
OnClick = SetFromClipboard,
|
||||||
|
Visible = _selector.Selected != null,
|
||||||
|
Disabled = _selector.Selected?.WriteProtected() ?? true,
|
||||||
|
};
|
||||||
|
|
||||||
|
private HeaderDrawer.Button ExportToClipboardButton()
|
||||||
|
=> new()
|
||||||
|
{
|
||||||
|
Description = "Copy the current design to your clipboard.",
|
||||||
|
Icon = FontAwesomeIcon.Copy,
|
||||||
|
OnClick = ExportToClipboard,
|
||||||
|
Visible = _selector.Selected != null,
|
||||||
|
};
|
||||||
|
|
||||||
private void DrawHeader()
|
private void DrawHeader()
|
||||||
=> HeaderDrawer.Draw(SelectionName, 0, ImGui.GetColorU32(ImGuiCol.FrameBg), 0, LockButton(),
|
=> HeaderDrawer.Draw(SelectionName, 0, ImGui.GetColorU32(ImGuiCol.FrameBg),
|
||||||
|
2, SetFromClipboardButton(), ExportToClipboardButton(), LockButton(),
|
||||||
HeaderDrawer.Button.IncognitoButton(_selector.IncognitoMode, v => _selector.IncognitoMode = v));
|
HeaderDrawer.Button.IncognitoButton(_selector.IncognitoMode, v => _selector.IncognitoMode = v));
|
||||||
|
|
||||||
private string SelectionName
|
private string SelectionName
|
||||||
|
|
@ -117,37 +133,37 @@ public class DesignPanel
|
||||||
_equipmentDrawer.Prepare();
|
_equipmentDrawer.Prepare();
|
||||||
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
foreach (var slot in EquipSlotExtensions.EqdpSlots)
|
||||||
{
|
{
|
||||||
var stain = _selector.Selected!.DesignData.Stain(slot);
|
var changes = _equipmentDrawer.DrawEquip(slot, _selector.Selected!.DesignData, out var newArmor, out var newStain,
|
||||||
if (_equipmentDrawer.DrawStain(stain, slot, out var newStain))
|
_selector.Selected.ApplyEquip, out var newApply, out var newApplyStain, _selector.Selected!.WriteProtected());
|
||||||
_manager.ChangeStain(_selector.Selected!, slot, newStain);
|
if (changes.HasFlag(EquipmentDrawer.EquipChange.Item))
|
||||||
|
_manager.ChangeEquip(_selector.Selected, slot, newArmor);
|
||||||
ImGui.SameLine();
|
if (changes.HasFlag(EquipmentDrawer.EquipChange.Stain))
|
||||||
var armor = _selector.Selected!.DesignData.Item(slot);
|
_manager.ChangeStain(_selector.Selected, slot, newStain);
|
||||||
if (_equipmentDrawer.DrawArmor(armor, slot, out var newArmor, _selector.Selected!.DesignData.Customize.Gender,
|
if (changes.HasFlag(EquipmentDrawer.EquipChange.ApplyItem))
|
||||||
_selector.Selected!.DesignData.Customize.Race))
|
_manager.ChangeApplyEquip(_selector.Selected, slot, newApply);
|
||||||
_manager.ChangeEquip(_selector.Selected!, slot, newArmor);
|
if (changes.HasFlag(EquipmentDrawer.EquipChange.ApplyStain))
|
||||||
|
_manager.ChangeApplyStain(_selector.Selected, slot, newApplyStain);
|
||||||
}
|
}
|
||||||
|
|
||||||
var mhStain = _selector.Selected!.DesignData.Stain(EquipSlot.MainHand);
|
var weaponChanges = _equipmentDrawer.DrawWeapons(_selector.Selected!.DesignData, out var newMainhand, out var newOffhand,
|
||||||
if (_equipmentDrawer.DrawStain(mhStain, EquipSlot.MainHand, out var newMhStain))
|
out var newMainhandStain, out var newOffhandStain, _selector.Selected.ApplyEquip, out var applyMain, out var applyMainStain,
|
||||||
_manager.ChangeStain(_selector.Selected!, EquipSlot.MainHand, newMhStain);
|
out var applyOff, out var applyOffStain, _selector.Selected!.WriteProtected());
|
||||||
|
if (weaponChanges.HasFlag(EquipmentDrawer.EquipChange.Item))
|
||||||
ImGui.SameLine();
|
_manager.ChangeWeapon(_selector.Selected, EquipSlot.MainHand, newMainhand);
|
||||||
var mh = _selector.Selected!.DesignData.Item(EquipSlot.MainHand);
|
if (weaponChanges.HasFlag(EquipmentDrawer.EquipChange.Stain))
|
||||||
if (_equipmentDrawer.DrawMainhand(mh, true, out var newMh))
|
_manager.ChangeStain(_selector.Selected, EquipSlot.MainHand, newMainhandStain);
|
||||||
_manager.ChangeWeapon(_selector.Selected!, EquipSlot.MainHand, newMh);
|
if (weaponChanges.HasFlag(EquipmentDrawer.EquipChange.ApplyItem))
|
||||||
|
_manager.ChangeApplyEquip(_selector.Selected, EquipSlot.MainHand, applyMain);
|
||||||
if (newMh.Type.Offhand() is not FullEquipType.Unknown)
|
if (weaponChanges.HasFlag(EquipmentDrawer.EquipChange.ApplyStain))
|
||||||
{
|
_manager.ChangeApplyStain(_selector.Selected, EquipSlot.MainHand, applyMainStain);
|
||||||
var ohStain = _selector.Selected!.DesignData.Stain(EquipSlot.OffHand);
|
if (weaponChanges.HasFlag(EquipmentDrawer.EquipChange.Item2))
|
||||||
if (_equipmentDrawer.DrawStain(ohStain, EquipSlot.OffHand, out var newOhStain))
|
_manager.ChangeWeapon(_selector.Selected, EquipSlot.OffHand, newOffhand);
|
||||||
_manager.ChangeStain(_selector.Selected!, EquipSlot.OffHand, newOhStain);
|
if (weaponChanges.HasFlag(EquipmentDrawer.EquipChange.Stain2))
|
||||||
|
_manager.ChangeStain(_selector.Selected, EquipSlot.OffHand, newOffhandStain);
|
||||||
ImGui.SameLine();
|
if (weaponChanges.HasFlag(EquipmentDrawer.EquipChange.ApplyItem2))
|
||||||
var oh = _selector.Selected!.DesignData.Item(EquipSlot.OffHand);
|
_manager.ChangeApplyEquip(_selector.Selected, EquipSlot.OffHand, applyOff);
|
||||||
if (_equipmentDrawer.DrawOffhand(oh, newMh.Type, out var newOh))
|
if (weaponChanges.HasFlag(EquipmentDrawer.EquipChange.ApplyStain2))
|
||||||
_manager.ChangeWeapon(_selector.Selected!, EquipSlot.OffHand, newOh);
|
_manager.ChangeApplyStain(_selector.Selected, EquipSlot.OffHand, applyOffStain);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawCustomize()
|
private void DrawCustomize()
|
||||||
|
|
@ -279,21 +295,13 @@ public class DesignPanel
|
||||||
|
|
||||||
private void DrawButtonRow()
|
private void DrawButtonRow()
|
||||||
{
|
{
|
||||||
SetFromClipboardButton();
|
|
||||||
ImGui.SameLine();
|
|
||||||
ExportToClipboardButton();
|
|
||||||
ImGui.SameLine();
|
|
||||||
DrawApplyToSelf();
|
DrawApplyToSelf();
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
DrawApplyToTarget();
|
DrawApplyToTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetFromClipboardButton()
|
private void SetFromClipboard()
|
||||||
{
|
{
|
||||||
if (!ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Clipboard.ToIconString(), new Vector2(ImGui.GetFrameHeight()),
|
|
||||||
"Try to apply a design from your clipboard.", _selector.Selected!.WriteProtected(), true))
|
|
||||||
return;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var text = ImGui.GetClipboardText();
|
var text = ImGui.GetClipboardText();
|
||||||
|
|
@ -307,12 +315,8 @@ public class DesignPanel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ExportToClipboardButton()
|
private void ExportToClipboard()
|
||||||
{
|
{
|
||||||
if (!ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Copy.ToIconString(), new Vector2(ImGui.GetFrameHeight()),
|
|
||||||
"Copy the current design to your clipboard.", false, true))
|
|
||||||
return;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var text = _converter.ShareBase64(_selector.Selected!);
|
var text = _converter.ShareBase64(_selector.Selected!);
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,11 @@ public static class HeaderDrawer
|
||||||
|
|
||||||
public Button()
|
public Button()
|
||||||
{
|
{
|
||||||
Visible = true;
|
Visible = true;
|
||||||
Width = ImGui.GetFrameHeightWithSpacing();
|
Width = ImGui.GetFrameHeightWithSpacing();
|
||||||
Disabled = false;
|
BorderColor = ColorId.HeaderButtons.Value();
|
||||||
|
TextColor = ColorId.HeaderButtons.Value();
|
||||||
|
Disabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly void Draw()
|
public readonly void Draw()
|
||||||
|
|
@ -41,24 +43,22 @@ public static class HeaderDrawer
|
||||||
|
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Border, BorderColor)
|
using var color = ImRaii.PushColor(ImGuiCol.Border, BorderColor)
|
||||||
.Push(ImGuiCol.Text, TextColor, TextColor != 0);
|
.Push(ImGuiCol.Text, TextColor, TextColor != 0);
|
||||||
if (ImGuiUtil.DrawDisabledButton(Icon.ToIconString(), new Vector2(Width, ImGui.GetFrameHeight()), Description, Disabled, true))
|
if (ImGuiUtil.DrawDisabledButton(Icon.ToIconString(), new Vector2(Width, ImGui.GetFrameHeight()), string.Empty, Disabled, true))
|
||||||
OnClick?.Invoke();
|
OnClick?.Invoke();
|
||||||
|
color.Pop();
|
||||||
|
ImGuiUtil.HoverTooltip(Description);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Button IncognitoButton(bool current, Action<bool> setter)
|
public static Button IncognitoButton(bool current, Action<bool> setter)
|
||||||
=> current
|
=> current
|
||||||
? new Button
|
? new Button
|
||||||
{
|
{
|
||||||
BorderColor = ColorId.HeaderButtons.Value(),
|
|
||||||
TextColor = ColorId.HeaderButtons.Value(),
|
|
||||||
Description = "Toggle incognito mode off.",
|
Description = "Toggle incognito mode off.",
|
||||||
Icon = FontAwesomeIcon.EyeSlash,
|
Icon = FontAwesomeIcon.EyeSlash,
|
||||||
OnClick = () => setter(false),
|
OnClick = () => setter(false),
|
||||||
}
|
}
|
||||||
: new Button
|
: new Button
|
||||||
{
|
{
|
||||||
BorderColor = ColorId.HeaderButtons.Value(),
|
|
||||||
TextColor = ColorId.HeaderButtons.Value(),
|
|
||||||
Description = "Toggle incognito mode on.",
|
Description = "Toggle incognito mode on.",
|
||||||
Icon = FontAwesomeIcon.Eye,
|
Icon = FontAwesomeIcon.Eye,
|
||||||
OnClick = () => setter(true),
|
OnClick = () => setter(true),
|
||||||
|
|
@ -83,7 +83,7 @@ public static class HeaderDrawer
|
||||||
var midSize = ImGui.GetContentRegionAvail().X - rightButtonSize - ImGuiHelpers.GlobalScale;
|
var midSize = ImGui.GetContentRegionAvail().X - rightButtonSize - ImGuiHelpers.GlobalScale;
|
||||||
|
|
||||||
style.Pop();
|
style.Pop();
|
||||||
style.Push(ImGuiStyleVar.ButtonTextAlign, new Vector2(0.5f + (rightButtonSize - leftButtonSize) / 2 / midSize, 0.5f));
|
style.Push(ImGuiStyleVar.ButtonTextAlign, new Vector2(0.5f + (rightButtonSize - leftButtonSize) / midSize, 0.5f));
|
||||||
if (textColor != 0)
|
if (textColor != 0)
|
||||||
ImGuiUtil.DrawTextButton(text, new Vector2(midSize, ImGui.GetFrameHeight()), frameColor, textColor);
|
ImGuiUtil.DrawTextButton(text, new Vector2(midSize, ImGui.GetFrameHeight()), frameColor, textColor);
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,7 @@ public class UnlockOverview
|
||||||
ImGui.TextUnformatted(item.Name);
|
ImGui.TextUnformatted(item.Name);
|
||||||
var slot = item.Type.ToSlot();
|
var slot = item.Type.ToSlot();
|
||||||
ImGui.TextUnformatted($"{item.Type.ToName()} ({slot.ToName()})");
|
ImGui.TextUnformatted($"{item.Type.ToName()} ({slot.ToName()})");
|
||||||
if (item.Type.Offhand().IsOffhandType())
|
if (item.Type.ValidOffhand().IsOffhandType())
|
||||||
ImGui.TextUnformatted(
|
ImGui.TextUnformatted(
|
||||||
$"{item.Weapon()}{(_items.ItemService.AwaitedService.TryGetValue(item.ItemId, false, out var offhand) ? $" | {offhand.Weapon()}" : string.Empty)}");
|
$"{item.Weapon()}{(_items.ItemService.AwaitedService.TryGetValue(item.ItemId, false, out var offhand) ? $" | {offhand.Weapon()}" : string.Empty)}");
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -241,7 +241,7 @@ public class UnlockTable : Table<EquipItem>, IDisposable
|
||||||
ImGui.AlignTextToFramePadding();
|
ImGui.AlignTextToFramePadding();
|
||||||
ImGuiUtil.RightAlign(item.ModelString);
|
ImGuiUtil.RightAlign(item.ModelString);
|
||||||
if (ImGui.IsItemHovered()
|
if (ImGui.IsItemHovered()
|
||||||
&& item.Type.Offhand().IsOffhandType()
|
&& item.Type.ValidOffhand().IsOffhandType()
|
||||||
&& _items.ItemService.AwaitedService.TryGetValue(item.ItemId, false, out var offhand))
|
&& _items.ItemService.AwaitedService.TryGetValue(item.ItemId, false, out var offhand))
|
||||||
{
|
{
|
||||||
using var tt = ImRaii.Tooltip();
|
using var tt = ImRaii.Tooltip();
|
||||||
|
|
@ -260,7 +260,7 @@ public class UnlockTable : Table<EquipItem>, IDisposable
|
||||||
if (FilterRegex?.IsMatch(item.ModelString) ?? item.ModelString.Contains(FilterValue, StringComparison.OrdinalIgnoreCase))
|
if (FilterRegex?.IsMatch(item.ModelString) ?? item.ModelString.Contains(FilterValue, StringComparison.OrdinalIgnoreCase))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (item.Type.Offhand().IsOffhandType() && _items.ItemService.AwaitedService.TryGetValue(item.ItemId, false, out var offhand))
|
if (item.Type.ValidOffhand().IsOffhandType() && _items.ItemService.AwaitedService.TryGetValue(item.ItemId, false, out var offhand))
|
||||||
return FilterRegex?.IsMatch(offhand.ModelString)
|
return FilterRegex?.IsMatch(offhand.ModelString)
|
||||||
?? offhand.ModelString.Contains(FilterValue, StringComparison.OrdinalIgnoreCase);
|
?? offhand.ModelString.Contains(FilterValue, StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,15 @@
|
||||||
|
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
|
using OtterGui.Raii;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
namespace Glamourer.Gui;
|
namespace Glamourer.Gui;
|
||||||
|
|
||||||
public static class UiHelpers
|
public static class UiHelpers
|
||||||
{
|
{
|
||||||
|
|
||||||
public static void DrawIcon(this EquipItem item, TextureService textures, Vector2 size)
|
public static void DrawIcon(this EquipItem item, TextureService textures, Vector2 size)
|
||||||
{
|
{
|
||||||
var isEmpty = item.ModelId.Value == 0;
|
var isEmpty = item.ModelId.Value == 0;
|
||||||
|
|
@ -31,4 +30,25 @@ public static class UiHelpers
|
||||||
ImGuiUtil.HoverIcon(ptr, textureSize, size);
|
ImGuiUtil.HoverIcon(ptr, textureSize, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public static bool DrawCheckbox(string label, string tooltip, bool value, out bool on, bool locked)
|
||||||
|
{
|
||||||
|
using var disabled = ImRaii.Disabled(locked);
|
||||||
|
var ret = ImGuiUtil.Checkbox(label, string.Empty, value, v => value = v);
|
||||||
|
ImGuiUtil.HoverTooltip(tooltip);
|
||||||
|
on = value;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool DrawVisor(bool current, out bool on, bool locked)
|
||||||
|
=> DrawCheckbox("##visorToggled", string.Empty, current, out on, locked);
|
||||||
|
|
||||||
|
public static bool DrawHat(bool current, out bool on, bool locked)
|
||||||
|
=> DrawCheckbox("##hatVisible", string.Empty, current, out on, locked);
|
||||||
|
|
||||||
|
public static bool DrawWeapon(bool current, out bool on, bool locked)
|
||||||
|
=> DrawCheckbox("##weaponVisible", string.Empty, current, out on, locked);
|
||||||
|
|
||||||
|
public static bool DrawWetness(bool current, out bool on, bool locked)
|
||||||
|
=> DrawCheckbox("##wetness", string.Empty, current, out on, locked);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,7 @@ public unsafe class WeaponService : IDisposable
|
||||||
private readonly Hook<LoadWeaponDelegate> _loadWeaponHook;
|
private readonly Hook<LoadWeaponDelegate> _loadWeaponHook;
|
||||||
|
|
||||||
|
|
||||||
private void LoadWeaponDetour(DrawDataContainer* drawData, uint slot, ulong weaponValue, byte redrawOnEquality, byte unk2,
|
private void LoadWeaponDetour(DrawDataContainer* drawData, uint slot, ulong weaponValue, byte redrawOnEquality, byte unk2, byte skipGameObject, byte unk4)
|
||||||
byte skipGameObject,
|
|
||||||
byte unk4)
|
|
||||||
{
|
{
|
||||||
var actor = (Actor)((nint*)drawData)[1];
|
var actor = (Actor)((nint*)drawData)[1];
|
||||||
var weapon = new CharacterWeapon(weaponValue);
|
var weapon = new CharacterWeapon(weaponValue);
|
||||||
|
|
@ -61,7 +59,7 @@ public unsafe class WeaponService : IDisposable
|
||||||
_loadWeaponHook.Original(drawData, slot, weapon.Value, redrawOnEquality, unk2, skipGameObject, unk4);
|
_loadWeaponHook.Original(drawData, slot, weapon.Value, redrawOnEquality, unk2, skipGameObject, unk4);
|
||||||
if (tmpWeapon.Value != weapon.Value)
|
if (tmpWeapon.Value != weapon.Value)
|
||||||
_loadWeaponHook.Original(drawData, slot, tmpWeapon.Value, 1, unk2, 1, unk4);
|
_loadWeaponHook.Original(drawData, slot, tmpWeapon.Value, 1, unk2, 1, unk4);
|
||||||
Glamourer.Log.Excessive(
|
Glamourer.Log.Information(
|
||||||
$"Weapon reloaded for 0x{actor.Address:X} ({actor.Utf8Name}) with attributes {slot} {weapon.Value:X14}, {redrawOnEquality}, {unk2}, {skipGameObject}, {unk4}");
|
$"Weapon reloaded for 0x{actor.Address:X} ({actor.Utf8Name}) with attributes {slot} {weapon.Value:X14}, {redrawOnEquality}, {unk2}, {skipGameObject}, {unk4}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ using Lumina.Excel;
|
||||||
using Penumbra.GameData.Data;
|
using Penumbra.GameData.Data;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
using static OtterGui.Raii.ImRaii;
|
|
||||||
using Race = Penumbra.GameData.Enums.Race;
|
using Race = Penumbra.GameData.Enums.Race;
|
||||||
|
|
||||||
namespace Glamourer.Services;
|
namespace Glamourer.Services;
|
||||||
|
|
@ -116,12 +115,21 @@ public class ItemManager : IDisposable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Return the default offhand for a given mainhand, that is for both handed weapons, return the correct offhand part, and for everything else Nothing. </summary>
|
||||||
|
public EquipItem GetDefaultOffhand(EquipItem mainhand)
|
||||||
|
{
|
||||||
|
var offhandType = mainhand.Type.ValidOffhand();
|
||||||
|
if (offhandType.IsOffhandType())
|
||||||
|
return Resolve(offhandType, mainhand.ItemId);
|
||||||
|
|
||||||
|
return NothingItem(offhandType);
|
||||||
|
}
|
||||||
|
|
||||||
public EquipItem Identify(EquipSlot slot, SetId id, WeaponType type, byte variant, FullEquipType mainhandType = FullEquipType.Unknown)
|
public EquipItem Identify(EquipSlot slot, SetId id, WeaponType type, byte variant, FullEquipType mainhandType = FullEquipType.Unknown)
|
||||||
{
|
{
|
||||||
if (slot is EquipSlot.OffHand)
|
if (slot is EquipSlot.OffHand)
|
||||||
{
|
{
|
||||||
var weaponType = mainhandType.Offhand();
|
var weaponType = mainhandType.ValidOffhand();
|
||||||
if (id.Value == 0)
|
if (id.Value == 0)
|
||||||
return NothingItem(weaponType);
|
return NothingItem(weaponType);
|
||||||
}
|
}
|
||||||
|
|
@ -161,7 +169,7 @@ public class ItemManager : IDisposable
|
||||||
return allowUnknown ? string.Empty : $"The item {itemId} yields an unknown item.";
|
return allowUnknown ? string.Empty : $"The item {itemId} yields an unknown item.";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsItemValid(slot, (uint) itemId, out item))
|
if (IsItemValid(slot, (uint)itemId, out item))
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
|
|
||||||
item = NothingItem(slot);
|
item = NothingItem(slot);
|
||||||
|
|
@ -201,7 +209,7 @@ public class ItemManager : IDisposable
|
||||||
/// <summary> Returns whether an offhand is valid given mainhand. </summary>
|
/// <summary> Returns whether an offhand is valid given mainhand. </summary>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
public bool IsOffhandValid(in EquipItem main, uint offId, out EquipItem off)
|
public bool IsOffhandValid(in EquipItem main, uint offId, out EquipItem off)
|
||||||
=> IsOffhandValid(main.Type.Offhand(), offId, out off);
|
=> IsOffhandValid(main.Type.ValidOffhand(), offId, out off);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check whether a combination of an item id for a mainhand and for an offhand is valid.
|
/// Check whether a combination of an item id for a mainhand and for an offhand is valid.
|
||||||
|
|
@ -219,7 +227,7 @@ public class ItemManager : IDisposable
|
||||||
ret = $"The mainhand weapon {mainId} does not exist, reset to default sword.";
|
ret = $"The mainhand weapon {mainId} does not exist, reset to default sword.";
|
||||||
}
|
}
|
||||||
|
|
||||||
var offType = main.Type.Offhand();
|
var offType = main.Type.ValidOffhand();
|
||||||
if (IsOffhandValid(offType, offId, out off))
|
if (IsOffhandValid(offType, offId, out off))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,7 @@ public class StateApplier
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ChangeMainhand(ActorData data, EquipItem weapon, StainId stain)
|
public void ChangeMainhand(ActorData data, EquipItem weapon, StainId stain)
|
||||||
{
|
{
|
||||||
var slot = weapon.Type.Offhand() == FullEquipType.Unknown ? EquipSlot.BothHand : EquipSlot.MainHand;
|
var slot = weapon.Type.ValidOffhand() == FullEquipType.Unknown ? EquipSlot.BothHand : EquipSlot.MainHand;
|
||||||
foreach (var actor in data.Objects.Where(a => a.Model.IsHuman))
|
foreach (var actor in data.Objects.Where(a => a.Model.IsHuman))
|
||||||
_weapon.LoadWeapon(actor, slot, weapon.Weapon().With(stain));
|
_weapon.LoadWeapon(actor, slot, weapon.Weapon().With(stain));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ public class StateEditor
|
||||||
|
|
||||||
// Can not change weapon type from expected type in state.
|
// Can not change weapon type from expected type in state.
|
||||||
if (slot is EquipSlot.MainHand && item.Type != state.BaseData.MainhandType
|
if (slot is EquipSlot.MainHand && item.Type != state.BaseData.MainhandType
|
||||||
|| slot is EquipSlot.OffHand && item.Type != state.BaseData.MainhandType.Offhand())
|
|| slot is EquipSlot.OffHand && item.Type != state.BaseData.MainhandType.ValidOffhand())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
state.ModelData.SetItem(slot, item);
|
state.ModelData.SetItem(slot, item);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue