mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-12 18:27:24 +01:00
Simple changes for 6.1
This commit is contained in:
parent
b141da40b0
commit
e6e033bb8b
8 changed files with 539 additions and 529 deletions
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 =>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue