Simple changes for 6.1

This commit is contained in:
Ottermandias 2022-04-14 21:59:30 +02:00
parent b141da40b0
commit e6e033bb8b
8 changed files with 539 additions and 529 deletions

View file

@ -2,8 +2,8 @@
using Lumina.Excel; using Lumina.Excel;
using Lumina.Excel.GeneratedSheets; using Lumina.Excel.GeneratedSheets;
namespace Glamourer.Customization namespace Glamourer.Customization;
{
[Sheet("CharaMakeParams")] [Sheet("CharaMakeParams")]
public class CharaMakeParams : ExcelRow public class CharaMakeParams : ExcelRow
{ {
@ -51,7 +51,7 @@ namespace Glamourer.Customization
public Menu[] Menus { get; set; } = new Menu[NumMenus]; public Menu[] Menus { get; set; } = new Menu[NumMenus];
public byte[] Voices { get; set; } = new byte[NumVoices]; public byte[] Voices { get; set; } = new byte[NumVoices];
public FacialFeatures[] FacialFeatureByFace { get; set; } = new FacialFeatures[NumFaces]; public FacialFeatures[] FacialFeatureByFace { get; set; } = new FacialFeatures[NumFaces];
public CharaMakeType.CharaMakeTypeUnkData3347Obj[] Equip { get; set; } = new CharaMakeType.CharaMakeTypeUnkData3347Obj[NumEquip]; public CharaMakeType.UnkData3347Obj[] Equip { get; set; } = new CharaMakeType.UnkData3347Obj[NumEquip];
public override void PopulateData(RowParser parser, Lumina.GameData gameData, Language language) public override void PopulateData(RowParser parser, Lumina.GameData gameData, Language language)
{ {
@ -95,13 +95,15 @@ namespace Glamourer.Customization
{ {
FacialFeatureByFace[i].Icons = new uint[NumFeatures]; FacialFeatureByFace[i].Icons = new uint[NumFeatures];
for (var j = 0; j < NumFeatures; ++j) for (var j = 0; j < NumFeatures; ++j)
{
FacialFeatureByFace[i].Icons[j] = FacialFeatureByFace[i].Icons[j] =
(uint)parser.ReadColumn<int>(3 + (MaxNumValues + 7 + NumGraphics) * NumMenus + NumVoices + j * NumFaces + i); (uint)parser.ReadColumn<int>(3 + (MaxNumValues + 7 + NumGraphics) * NumMenus + NumVoices + j * NumFaces + i);
} }
}
for (var i = 0; i < NumEquip; ++i) for (var i = 0; i < NumEquip; ++i)
{ {
Equip[i] = new CharaMakeType.CharaMakeTypeUnkData3347Obj() Equip[i] = new CharaMakeType.UnkData3347Obj()
{ {
Helmet = parser.ReadColumn<ulong>( Helmet = parser.ReadColumn<ulong>(
3 + (MaxNumValues + 7 + NumGraphics) * NumMenus + NumVoices + NumFaces * NumFeatures + i * 7 + 0), 3 + (MaxNumValues + 7 + NumGraphics) * NumMenus + NumVoices + NumFaces * NumFeatures + i * 7 + 0),
@ -121,4 +123,3 @@ namespace Glamourer.Customization
} }
} }
} }
}

View file

@ -23,7 +23,7 @@ namespace Glamourer.Customization
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct CharacterCustomization public struct CharacterCustomization
{ {
public const int CustomizationOffset = 0xDD8; public const int CustomizationOffset = 0x830;
public const int CustomizationBytes = 26; public const int CustomizationBytes = 26;
public static CharacterCustomization Default = new() public static CharacterCustomization Default = new()

View file

@ -196,7 +196,7 @@ namespace Glamourer.Customization
if (set.Faces.Count > 0) if (set.Faces.Count > 0)
set.SetAvailable(CustomizationId.Face); set.SetAvailable(CustomizationId.Face);
var count = race.ToRace() == Race.Hrothgar ? set.HairStyles.Count : set.Faces.Count; var count = set.Faces.Count;
var featureDict = new List<IReadOnlyList<Customization>>(count); var featureDict = new List<IReadOnlyList<Customization>>(count);
for (var i = 0; i < count; ++i) for (var i = 0; i < count; ++i)
{ {

View file

@ -4,14 +4,17 @@ namespace Glamourer;
public static class CharacterExtensions public static class CharacterExtensions
{ {
public const int WetnessOffset = 0x19E4; public const int WetnessOffset = 0x1ADA;
public const byte WetnessFlag = 0x08; public const byte WetnessFlag = 0x80;
public const int StateFlagsOffset = 0xDF6; public const int HatVisibleOffset = 0x84E;
public const int VisorToggledOffset = 0x84F;
public const byte HatHiddenFlag = 0x01; public const byte HatHiddenFlag = 0x01;
public const byte VisorToggledFlag = 0x10; public const byte VisorToggledFlag = 0x08;
public const int AlphaOffset = 0x18B8; public const int AlphaOffset = 0x19E0;
public const int WeaponHiddenOffset = 0xCD4; public const int WeaponHiddenOffset1 = 0x84F;
public const byte WeaponHiddenFlag = 0x02; public const int WeaponHiddenOffset2 = 0x72C; // maybe
public const byte WeaponHiddenFlag1 = 0x01;
public const byte WeaponHiddenFlag2 = 0x02;
public static unsafe bool IsWet(this Character a) public static unsafe bool IsWet(this Character a)
=> (*((byte*)a.Address + WetnessOffset) & WetnessFlag) != 0; => (*((byte*)a.Address + WetnessOffset) & WetnessFlag) != 0;
@ -29,49 +32,62 @@ public static class CharacterExtensions
return true; return true;
} }
public static unsafe ref byte StateFlags(this Character a) public static unsafe bool IsHatVisible(this Character a)
=> ref *((byte*)a.Address + StateFlagsOffset); => (*((byte*)a.Address + HatVisibleOffset) & HatHiddenFlag) == 0;
public static bool SetStateFlag(this Character a, bool value, byte flag) public static unsafe bool SetHatVisible(this Character a, bool visible)
{ {
var current = a.StateFlags(); var current = IsHatVisible(a);
var previousValue = (current & flag) != 0; if (current == visible)
if (previousValue == value)
return false; return false;
if (value) if (visible)
a.StateFlags() = (byte)(current | flag); *((byte*)a.Address + HatVisibleOffset) = (byte)(*((byte*)a.Address + HatVisibleOffset) & ~HatHiddenFlag);
else else
a.StateFlags() = (byte)(current & ~flag); *((byte*)a.Address + HatVisibleOffset) = (byte)(*((byte*)a.Address + HatVisibleOffset) | HatHiddenFlag);
return true; return true;
} }
public static bool IsHatHidden(this Character a) public static unsafe bool IsVisorToggled(this Character a)
=> (a.StateFlags() & HatHiddenFlag) != 0; => (*((byte*)a.Address + VisorToggledOffset) & VisorToggledFlag) == VisorToggledFlag;
public static unsafe bool SetVisorToggled(this Character a, bool toggled)
{
var current = IsVisorToggled(a);
if (current == toggled)
return false;
if (toggled)
*((byte*)a.Address + VisorToggledOffset) = (byte)(*((byte*)a.Address + VisorToggledOffset) | VisorToggledFlag);
else
*((byte*)a.Address + VisorToggledOffset) = (byte)(*((byte*)a.Address + VisorToggledOffset) & ~VisorToggledFlag);
return true;
}
public static unsafe bool IsWeaponHidden(this Character a) public static unsafe bool IsWeaponHidden(this Character a)
=> (a.StateFlags() & WeaponHiddenFlag) != 0 => (*((byte*)a.Address + WeaponHiddenOffset1) & WeaponHiddenFlag1) == WeaponHiddenFlag1
&& (*((byte*)a.Address + WeaponHiddenOffset) & WeaponHiddenFlag) != 0; && (*((byte*)a.Address + WeaponHiddenOffset2) & WeaponHiddenFlag2) == WeaponHiddenFlag2;
public static bool IsVisorToggled(this Character a)
=> (a.StateFlags() & VisorToggledFlag) != 0;
public static bool SetHatHidden(this Character a, bool value)
=> SetStateFlag(a, value, HatHiddenFlag);
public static unsafe bool SetWeaponHidden(this Character a, bool value) public static unsafe bool SetWeaponHidden(this Character a, bool value)
{ {
var ret = SetStateFlag(a, value, WeaponHiddenFlag); var hidden = IsWeaponHidden(a);
var val = *((byte*)a.Address + WeaponHiddenOffset); if (hidden == value)
if (value) return false;
*((byte*)a.Address + WeaponHiddenOffset) = (byte)(val | WeaponHiddenFlag);
else
*((byte*)a.Address + WeaponHiddenOffset) = (byte)(val & ~WeaponHiddenFlag);
return ret || (val & WeaponHiddenFlag) != 0 != value;
}
public static bool SetVisorToggled(this Character a, bool value) var val1 = *((byte*)a.Address + WeaponHiddenOffset1);
=> SetStateFlag(a, value, VisorToggledFlag); var val2 = *((byte*)a.Address + WeaponHiddenOffset2);
if (value)
{
*((byte*)a.Address + WeaponHiddenOffset1) = (byte)(val1 | WeaponHiddenFlag1);
*((byte*)a.Address + WeaponHiddenOffset2) = (byte)(val2 | WeaponHiddenFlag2);
}
else
{
*((byte*)a.Address + WeaponHiddenOffset1) = (byte)(val1 & ~WeaponHiddenFlag1);
*((byte*)a.Address + WeaponHiddenOffset2) = (byte)(val2 & ~WeaponHiddenFlag2);
}
return true;
}
public static unsafe ref float Alpha(this Character a) public static unsafe ref float Alpha(this Character a)
=> ref *(float*)((byte*)a.Address + AlphaOffset); => ref *(float*)((byte*)a.Address + AlphaOffset);

View file

@ -8,8 +8,8 @@ using Newtonsoft.Json.Linq;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
namespace Glamourer namespace Glamourer;
{
public class CharacterSaveConverter : JsonConverter public class CharacterSaveConverter : JsonConverter
{ {
public override bool CanConvert(Type objectType) public override bool CanConvert(Type objectType)
@ -292,7 +292,7 @@ namespace Glamourer
SetHatState = true; SetHatState = true;
SetVisorState = true; SetVisorState = true;
SetWeaponState = true; SetWeaponState = true;
StateFlags = a.StateFlags(); StateFlags = (byte)((a.IsHatVisible() ? 0x00 : 0x01) | (a.IsVisorToggled() ? 0x10 : 0x00) | (a.IsWeaponHidden() ? 0x02 : 0x00));
IsWet = a.IsWet(); IsWet = a.IsWet();
Alpha = a.Alpha(); Alpha = a.Alpha();
@ -309,20 +309,13 @@ namespace Glamourer
Equipment.Write(a.Address, WriteEquipment, WriteEquipment); Equipment.Write(a.Address, WriteEquipment, WriteEquipment);
a.SetWetness(IsWet); a.SetWetness(IsWet);
a.Alpha() = Alpha; a.Alpha() = Alpha;
if ((_bytes[1] & 0b11100) == 0b11100)
{
a.StateFlags() = StateFlags;
}
else
{
if (SetHatState) if (SetHatState)
a.SetHatHidden(HatState); a.SetHatVisible(!HatState);
if (SetVisorState) if (SetVisorState)
a.SetVisorToggled(VisorState); a.SetVisorToggled(VisorState);
if (SetWeaponState) if (SetWeaponState)
a.SetWeaponHidden(WeaponState); a.SetWeaponHidden(WeaponState);
} }
}
public void ApplyOnlyEquipment(Character a) public void ApplyOnlyEquipment(Character a)
{ {
@ -398,4 +391,3 @@ namespace Glamourer
} }
} }
} }
}

View file

@ -140,7 +140,7 @@ namespace Glamourer.Gui
ImGui.SameLine(); ImGui.SameLine();
if (InputInt($"##text_{id}", ref current, 1, count)) if (InputInt($"##text_{id}", ref current, 1, count))
{ {
customization[id] = set.Data(id, current).Value; customization[id] = (byte) current;
ret = true; ret = true;
} }

View file

@ -277,8 +277,9 @@ namespace Glamourer.Gui
var label = $"##fsPopup{child.FullName()}"; var label = $"##fsPopup{child.FullName()}";
if (ImGui.BeginPopup(label)) if (ImGui.BeginPopup(label))
{ {
if (ImGui.MenuItem("Delete")) if (ImGui.MenuItem("Delete") && ImGui.GetIO().KeyCtrl && ImGui.GetIO().KeyShift)
_designs.DeleteAllChildren(child, false); _designs.DeleteAllChildren(child, false);
ImGuiCustom.HoverTooltip("Hold Control and Shift to delete.");
RenameChildInput(child); RenameChildInput(child);

View file

@ -38,7 +38,7 @@ namespace Glamourer.Gui
ret |= DrawCheckMark("Hat Visible", save.HatState, v => ret |= DrawCheckMark("Hat Visible", save.HatState, v =>
{ {
save.HatState = v; save.HatState = v;
player?.SetHatHidden(!v); player?.SetHatVisible(v);
}); });
ret |= DrawCheckMark("Weapon Visible", save.WeaponState, v => ret |= DrawCheckMark("Weapon Visible", save.WeaponState, v =>