mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-12 10:17:23 +01:00
Random fixes and penumbra attach update.
This commit is contained in:
parent
78fd4ce9b9
commit
dbdaaf1ca8
15 changed files with 264 additions and 180 deletions
|
|
@ -150,7 +150,7 @@ namespace Glamourer.Customization
|
||||||
var row = _listSheet.GetRow(((uint) race - 1) * 2 - 1 + (uint) gender)!;
|
var row = _listSheet.GetRow(((uint) race - 1) * 2 - 1 + (uint) gender)!;
|
||||||
var set = new CustomizationSet(race, gender)
|
var set = new CustomizationSet(race, gender)
|
||||||
{
|
{
|
||||||
HairStyles = race.ToRace() == Race.Hrothgar ? HrothgarFaces(row) : GetHairStyles(race, gender),
|
HairStyles = GetHairStyles(race, gender),
|
||||||
HairColors = hair,
|
HairColors = hair,
|
||||||
SkinColors = skin,
|
SkinColors = skin,
|
||||||
EyeColors = _eyeColorPicker,
|
EyeColors = _eyeColorPicker,
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,9 @@
|
||||||
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Lumina.Excel.dll</HintPath>
|
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Lumina.Excel.dll</HintPath>
|
||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Penumbra.GameData">
|
</ItemGroup>
|
||||||
<HintPath>..\..\Penumbra\Penumbra\bin\$(Configuration)\$(TargetFramework)\Penumbra.GameData.dll</HintPath>
|
|
||||||
</Reference>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\Penumbra\Penumbra.GameData\Penumbra.GameData.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 16
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 16.0.29613.14
|
VisualStudioVersion = 17.2.32210.308
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Glamourer", "Glamourer\Glamourer.csproj", "{A5439F6B-83C1-4078-9371-354A147FF554}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Glamourer", "Glamourer\Glamourer.csproj", "{A5439F6B-83C1-4078-9371-354A147FF554}"
|
||||||
EndProject
|
EndProject
|
||||||
|
|
@ -13,6 +13,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Glamourer.GameData", "Glamourer.GameData\Glamourer.GameData.csproj", "{51F4DDB0-1FA0-4629-9CFE-C55B6062907B}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Glamourer.GameData", "Glamourer.GameData\Glamourer.GameData.csproj", "{51F4DDB0-1FA0-4629-9CFE-C55B6062907B}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Penumbra.GameData", "..\Penumbra\Penumbra.GameData\Penumbra.GameData.csproj", "{9BEE2336-AA93-4669-8EEA-4756B3B2D024}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Penumbra.PlayerWatch", "..\Penumbra\Penumbra.PlayerWatch\Penumbra.PlayerWatch.csproj", "{FECEDB39-C103-4333-82A6-A422BDC51EEE}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
|
@ -47,6 +51,30 @@ Global
|
||||||
{51F4DDB0-1FA0-4629-9CFE-C55B6062907B}.Release|x64.Build.0 = Release|Any CPU
|
{51F4DDB0-1FA0-4629-9CFE-C55B6062907B}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{51F4DDB0-1FA0-4629-9CFE-C55B6062907B}.Release|x86.ActiveCfg = Release|Any CPU
|
{51F4DDB0-1FA0-4629-9CFE-C55B6062907B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{51F4DDB0-1FA0-4629-9CFE-C55B6062907B}.Release|x86.Build.0 = Release|Any CPU
|
{51F4DDB0-1FA0-4629-9CFE-C55B6062907B}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{9BEE2336-AA93-4669-8EEA-4756B3B2D024}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{9BEE2336-AA93-4669-8EEA-4756B3B2D024}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{9BEE2336-AA93-4669-8EEA-4756B3B2D024}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{9BEE2336-AA93-4669-8EEA-4756B3B2D024}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{9BEE2336-AA93-4669-8EEA-4756B3B2D024}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{9BEE2336-AA93-4669-8EEA-4756B3B2D024}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{9BEE2336-AA93-4669-8EEA-4756B3B2D024}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{9BEE2336-AA93-4669-8EEA-4756B3B2D024}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{9BEE2336-AA93-4669-8EEA-4756B3B2D024}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{9BEE2336-AA93-4669-8EEA-4756B3B2D024}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{9BEE2336-AA93-4669-8EEA-4756B3B2D024}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{9BEE2336-AA93-4669-8EEA-4756B3B2D024}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{FECEDB39-C103-4333-82A6-A422BDC51EEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{FECEDB39-C103-4333-82A6-A422BDC51EEE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{FECEDB39-C103-4333-82A6-A422BDC51EEE}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{FECEDB39-C103-4333-82A6-A422BDC51EEE}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{FECEDB39-C103-4333-82A6-A422BDC51EEE}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{FECEDB39-C103-4333-82A6-A422BDC51EEE}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{FECEDB39-C103-4333-82A6-A422BDC51EEE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{FECEDB39-C103-4333-82A6-A422BDC51EEE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{FECEDB39-C103-4333-82A6-A422BDC51EEE}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{FECEDB39-C103-4333-82A6-A422BDC51EEE}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{FECEDB39-C103-4333-82A6-A422BDC51EEE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{FECEDB39-C103-4333-82A6-A422BDC51EEE}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
<s:String x:Key="/Default/Environment/AssemblyExplorer/XmlDocument/@EntryValue"><AssemblyExplorer>
|
<s:String x:Key="/Default/Environment/AssemblyExplorer/XmlDocument/@EntryValue"><AssemblyExplorer>
|
||||||
<Assembly Path="H:\Projects\FFPlugins\Penumbra\Penumbra\bin\Debug\net472\Penumbra.GameData.dll" />
|
<Assembly Path="H:\Projects\FFPlugins\Penumbra\Penumbra\bin\Debug\net472\Penumbra.GameData.dll" />
|
||||||
|
<Assembly Path="C:\Users\Ozy\AppData\Roaming\XIVLauncher\addon\Hooks\dev\Dalamud.dll" />
|
||||||
|
<Assembly Path="H:\Projects\FFPlugins\Penumbra\Penumbra\bin\Debug\net5.0-windows\Penumbra.GameData.dll" />
|
||||||
</AssemblyExplorer></s:String></wpf:ResourceDictionary>
|
</AssemblyExplorer></s:String></wpf:ResourceDictionary>
|
||||||
BIN
Glamourer.zip
BIN
Glamourer.zip
Binary file not shown.
|
|
@ -4,20 +4,8 @@ namespace Glamourer;
|
||||||
|
|
||||||
public static class CharacterExtensions
|
public static class CharacterExtensions
|
||||||
{
|
{
|
||||||
public const int WetnessOffset = 0x1ADA;
|
|
||||||
public const byte WetnessFlag = 0x80;
|
|
||||||
public const int HatVisibleOffset = 0x84E;
|
|
||||||
public const int VisorToggledOffset = 0x84F;
|
|
||||||
public const byte HatHiddenFlag = 0x01;
|
|
||||||
public const byte VisorToggledFlag = 0x08;
|
|
||||||
public const int AlphaOffset = 0x19E0;
|
|
||||||
public const int WeaponHiddenOffset1 = 0x84F;
|
|
||||||
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 + Offsets.Character.Wetness) & Offsets.Character.Flags.IsWet) != 0;
|
||||||
|
|
||||||
public static unsafe bool SetWetness(this Character a, bool value)
|
public static unsafe bool SetWetness(this Character a, bool value)
|
||||||
{
|
{
|
||||||
|
|
@ -26,14 +14,16 @@ public static class CharacterExtensions
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (value)
|
if (value)
|
||||||
*((byte*)a.Address + WetnessOffset) = (byte)(*((byte*)a.Address + WetnessOffset) | WetnessFlag);
|
*((byte*)a.Address + Offsets.Character.Wetness) =
|
||||||
|
(byte)(*((byte*)a.Address + Offsets.Character.Wetness) | Offsets.Character.Flags.IsWet);
|
||||||
else
|
else
|
||||||
*((byte*)a.Address + WetnessOffset) = (byte)(*((byte*)a.Address + WetnessOffset) & ~WetnessFlag);
|
*((byte*)a.Address + Offsets.Character.Wetness) =
|
||||||
|
(byte)(*((byte*)a.Address + Offsets.Character.Wetness) & ~Offsets.Character.Flags.IsWet);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe bool IsHatVisible(this Character a)
|
public static unsafe bool IsHatVisible(this Character a)
|
||||||
=> (*((byte*)a.Address + HatVisibleOffset) & HatHiddenFlag) == 0;
|
=> (*((byte*)a.Address + Offsets.Character.HatVisible) & Offsets.Character.Flags.IsHatHidden) == 0;
|
||||||
|
|
||||||
public static unsafe bool SetHatVisible(this Character a, bool visible)
|
public static unsafe bool SetHatVisible(this Character a, bool visible)
|
||||||
{
|
{
|
||||||
|
|
@ -42,14 +32,17 @@ public static class CharacterExtensions
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (visible)
|
if (visible)
|
||||||
*((byte*)a.Address + HatVisibleOffset) = (byte)(*((byte*)a.Address + HatVisibleOffset) & ~HatHiddenFlag);
|
*((byte*)a.Address + Offsets.Character.HatVisible) =
|
||||||
|
(byte)(*((byte*)a.Address + Offsets.Character.HatVisible) & ~Offsets.Character.Flags.IsHatHidden);
|
||||||
else
|
else
|
||||||
*((byte*)a.Address + HatVisibleOffset) = (byte)(*((byte*)a.Address + HatVisibleOffset) | HatHiddenFlag);
|
*((byte*)a.Address + Offsets.Character.HatVisible) =
|
||||||
|
(byte)(*((byte*)a.Address + Offsets.Character.HatVisible) | Offsets.Character.Flags.IsHatHidden);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe bool IsVisorToggled(this Character a)
|
public static unsafe bool IsVisorToggled(this Character a)
|
||||||
=> (*((byte*)a.Address + VisorToggledOffset) & VisorToggledFlag) == VisorToggledFlag;
|
=> (*((byte*)a.Address + Offsets.Character.VisorToggled) & Offsets.Character.Flags.IsVisorToggled)
|
||||||
|
== Offsets.Character.Flags.IsVisorToggled;
|
||||||
|
|
||||||
public static unsafe bool SetVisorToggled(this Character a, bool toggled)
|
public static unsafe bool SetVisorToggled(this Character a, bool toggled)
|
||||||
{
|
{
|
||||||
|
|
@ -58,15 +51,19 @@ public static class CharacterExtensions
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (toggled)
|
if (toggled)
|
||||||
*((byte*)a.Address + VisorToggledOffset) = (byte)(*((byte*)a.Address + VisorToggledOffset) | VisorToggledFlag);
|
*((byte*)a.Address + Offsets.Character.VisorToggled) =
|
||||||
|
(byte)(*((byte*)a.Address + Offsets.Character.VisorToggled) | Offsets.Character.Flags.IsVisorToggled);
|
||||||
else
|
else
|
||||||
*((byte*)a.Address + VisorToggledOffset) = (byte)(*((byte*)a.Address + VisorToggledOffset) & ~VisorToggledFlag);
|
*((byte*)a.Address + Offsets.Character.VisorToggled) =
|
||||||
|
(byte)(*((byte*)a.Address + Offsets.Character.VisorToggled) & ~Offsets.Character.Flags.IsVisorToggled);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe bool IsWeaponHidden(this Character a)
|
public static unsafe bool IsWeaponHidden(this Character a)
|
||||||
=> (*((byte*)a.Address + WeaponHiddenOffset1) & WeaponHiddenFlag1) == WeaponHiddenFlag1
|
=> (*((byte*)a.Address + Offsets.Character.WeaponHidden1) & Offsets.Character.Flags.IsWeaponHidden1)
|
||||||
&& (*((byte*)a.Address + WeaponHiddenOffset2) & WeaponHiddenFlag2) == WeaponHiddenFlag2;
|
== Offsets.Character.Flags.IsWeaponHidden1
|
||||||
|
&& (*((byte*)a.Address + Offsets.Character.WeaponHidden2) & Offsets.Character.Flags.IsWeaponHidden2)
|
||||||
|
== Offsets.Character.Flags.IsWeaponHidden2;
|
||||||
|
|
||||||
public static unsafe bool SetWeaponHidden(this Character a, bool value)
|
public static unsafe bool SetWeaponHidden(this Character a, bool value)
|
||||||
{
|
{
|
||||||
|
|
@ -74,21 +71,22 @@ public static class CharacterExtensions
|
||||||
if (hidden == value)
|
if (hidden == value)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var val1 = *((byte*)a.Address + WeaponHiddenOffset1);
|
var val1 = *((byte*)a.Address + Offsets.Character.WeaponHidden1);
|
||||||
var val2 = *((byte*)a.Address + WeaponHiddenOffset2);
|
var val2 = *((byte*)a.Address + Offsets.Character.WeaponHidden2);
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
*((byte*)a.Address + WeaponHiddenOffset1) = (byte)(val1 | WeaponHiddenFlag1);
|
*((byte*)a.Address + Offsets.Character.WeaponHidden1) = (byte)(val1 | Offsets.Character.Flags.IsWeaponHidden1);
|
||||||
*((byte*)a.Address + WeaponHiddenOffset2) = (byte)(val2 | WeaponHiddenFlag2);
|
*((byte*)a.Address + Offsets.Character.WeaponHidden2) = (byte)(val2 | Offsets.Character.Flags.IsWeaponHidden2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*((byte*)a.Address + WeaponHiddenOffset1) = (byte)(val1 & ~WeaponHiddenFlag1);
|
*((byte*)a.Address + Offsets.Character.WeaponHidden1) = (byte)(val1 & ~Offsets.Character.Flags.IsWeaponHidden1);
|
||||||
*((byte*)a.Address + WeaponHiddenOffset2) = (byte)(val2 & ~WeaponHiddenFlag2);
|
*((byte*)a.Address + Offsets.Character.WeaponHidden2) = (byte)(val2 & ~Offsets.Character.Flags.IsWeaponHidden2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
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 + Offsets.Character.Alpha);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -310,11 +310,11 @@ public class CharacterSave
|
||||||
a.SetWetness(IsWet);
|
a.SetWetness(IsWet);
|
||||||
a.Alpha() = Alpha;
|
a.Alpha() = Alpha;
|
||||||
if (SetHatState)
|
if (SetHatState)
|
||||||
a.SetHatVisible(!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)
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ namespace Glamourer.Designs
|
||||||
design.Jobs.Name);
|
design.Jobs.Name);
|
||||||
design.Design.Data.Apply(character);
|
design.Design.Data.Apply(character);
|
||||||
Glamourer.PlayerWatcher.UpdatePlayerWithoutEvent(character);
|
Glamourer.PlayerWatcher.UpdatePlayerWithoutEvent(character);
|
||||||
Glamourer.Penumbra.RedrawObject(character, RedrawType.WithSettings, false);
|
Glamourer.Penumbra.RedrawObject(character, RedrawType.Redraw, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(string name, Design design, JobGroup group, bool enabled = false)
|
public void Add(string name, Design design, JobGroup group, bool enabled = false)
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<OutputPath>bin\$(Configuration)\</OutputPath>
|
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||||
<MSBuildWarningsAsMessages>$(MSBuildWarningsAsMessages);MSB3277</MSBuildWarningsAsMessages>
|
<MSBuildWarningsAsMessages>$(MSBuildWarningsAsMessages);MSB3277</MSBuildWarningsAsMessages>
|
||||||
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
|
@ -69,23 +70,35 @@
|
||||||
<HintPath>$(appdata)\XIVLauncher\addon\Hooks\dev\Lumina.Excel.dll</HintPath>
|
<HintPath>$(appdata)\XIVLauncher\addon\Hooks\dev\Lumina.Excel.dll</HintPath>
|
||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Penumbra.GameData">
|
|
||||||
<HintPath>..\..\Penumbra\Penumbra\bin\$(Configuration)\$(TargetFramework)\Penumbra.GameData.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Penumbra.PlayerWatch">
|
|
||||||
<HintPath>..\..\Penumbra\Penumbra\bin\$(Configuration)\$(TargetFramework)\Penumbra.PlayerWatch.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3">
|
||||||
|
<Private>false</Private>
|
||||||
|
</PackageReference>
|
||||||
|
|
||||||
<PackageReference Include="System.Memory" Version="4.5.3" />
|
<PackageReference Include="System.Memory" Version="4.5.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Glamourer.GameData\Glamourer.GameData.csproj" />
|
<ProjectReference Include="..\Glamourer.GameData\Glamourer.GameData.csproj" />
|
||||||
|
<ProjectReference Include="..\..\Penumbra\Penumbra.GameData\Penumbra.GameData.csproj" />
|
||||||
|
<ProjectReference Include="..\..\Penumbra\Penumbra.PlayerWatch\Penumbra.PlayerWatch.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Update="Properties\Resources.Designer.cs">
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Update="Properties\Resources.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||||
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ namespace Glamourer.Gui
|
||||||
private readonly CharacterSave _currentSave = new();
|
private readonly CharacterSave _currentSave = new();
|
||||||
private string _newDesignName = string.Empty;
|
private string _newDesignName = string.Empty;
|
||||||
private bool _keyboardFocus;
|
private bool _keyboardFocus;
|
||||||
|
private bool _holdShift;
|
||||||
|
private bool _holdCtrl;
|
||||||
private const string DesignNamePopupLabel = "Save Design As...";
|
private const string DesignNamePopupLabel = "Save Design As...";
|
||||||
private const uint RedHeaderColor = 0xFF1818C0;
|
private const uint RedHeaderColor = 0xFF1818C0;
|
||||||
private const uint GreenHeaderColor = 0xFF18C018;
|
private const uint GreenHeaderColor = 0xFF18C018;
|
||||||
|
|
@ -58,10 +60,10 @@ namespace Glamourer.Gui
|
||||||
save.Apply(player);
|
save.Apply(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CharacterSave ConditionalCopy(CharacterSave save)
|
private static CharacterSave ConditionalCopy(CharacterSave save, bool shift, bool ctrl)
|
||||||
{
|
{
|
||||||
var copy = save.Copy();
|
var copy = save.Copy();
|
||||||
if (ImGui.GetIO().KeyShift)
|
if (shift)
|
||||||
{
|
{
|
||||||
copy.Load(new CharacterEquipment());
|
copy.Load(new CharacterEquipment());
|
||||||
copy.SetHatState = false;
|
copy.SetHatState = false;
|
||||||
|
|
@ -69,7 +71,7 @@ namespace Glamourer.Gui
|
||||||
copy.SetWeaponState = false;
|
copy.SetWeaponState = false;
|
||||||
copy.WriteEquipment = CharacterEquipMask.None;
|
copy.WriteEquipment = CharacterEquipMask.None;
|
||||||
}
|
}
|
||||||
else if (ImGui.GetIO().KeyCtrl)
|
else if (ctrl)
|
||||||
{
|
{
|
||||||
copy.Load(CharacterCustomization.Default);
|
copy.Load(CharacterCustomization.Default);
|
||||||
copy.SetHatState = false;
|
copy.SetHatState = false;
|
||||||
|
|
@ -78,7 +80,7 @@ namespace Glamourer.Gui
|
||||||
copy.WriteCustomizations = false;
|
copy.WriteCustomizations = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return save.Copy();
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool DrawApplyClipboardButton()
|
private bool DrawApplyClipboardButton()
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ namespace Glamourer.Gui
|
||||||
var count = set.Count(CustomizationId.FacialFeaturesTattoos);
|
var count = set.Count(CustomizationId.FacialFeaturesTattoos);
|
||||||
using (var _ = ImGuiRaii.NewGroup())
|
using (var _ = ImGuiRaii.NewGroup())
|
||||||
{
|
{
|
||||||
var face = set.Race == Race.Hrothgar ? customization.Hairstyle : customization.Face;
|
var face = customization.Face;
|
||||||
if (set.Faces.Count < face)
|
if (set.Faces.Count < face)
|
||||||
face = 1;
|
face = 1;
|
||||||
for (var i = 0; i < count; ++i)
|
for (var i = 0; i < count; ++i)
|
||||||
|
|
@ -288,9 +288,6 @@ namespace Glamourer.Gui
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id == CustomizationId.Hairstyle && customization.Race == Race.Hrothgar)
|
|
||||||
customization[CustomizationId.Face] = (byte) ((customization[CustomizationId.Hairstyle] + 1) / 2);
|
|
||||||
|
|
||||||
ImGui.Text($"{label} ({custom.Value.Value})");
|
ImGui.Text($"{label} ({custom.Value.Value})");
|
||||||
ImGuiCustom.HoverTooltip(tooltip);
|
ImGuiCustom.HoverTooltip(tooltip);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ namespace Glamourer.Gui
|
||||||
if (!change)
|
if (!change)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
newItem = new Item(newItem.Base, newItem.Name, slot);
|
||||||
if (_player == null)
|
if (_player == null)
|
||||||
return _inDesignMode && (_selection?.Data.WriteItem(newItem) ?? false);
|
return _inDesignMode && (_selection?.Data.WriteItem(newItem) ?? false);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,10 +37,7 @@ namespace Glamourer.Gui
|
||||||
case CustomizationId.Gender: break;
|
case CustomizationId.Gender: break;
|
||||||
case CustomizationId.FacialFeaturesTattoos: break;
|
case CustomizationId.FacialFeaturesTattoos: break;
|
||||||
case CustomizationId.HighlightsOnFlag: break;
|
case CustomizationId.HighlightsOnFlag: break;
|
||||||
case CustomizationId.Face:
|
case CustomizationId.Face: break;
|
||||||
if (customization.Race != Race.Hrothgar)
|
|
||||||
goto default;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
var count = set.Count(id);
|
var count = set.Count(id);
|
||||||
if (set.DataByValue(id, customization[id], out _) < 0)
|
if (set.DataByValue(id, customization[id], out _) < 0)
|
||||||
|
|
@ -148,7 +145,7 @@ namespace Glamourer.Gui
|
||||||
switch (use)
|
switch (use)
|
||||||
{
|
{
|
||||||
case DesignNameUse.SaveCurrent:
|
case DesignNameUse.SaveCurrent:
|
||||||
SaveNewDesign(ConditionalCopy(_currentSave));
|
SaveNewDesign(ConditionalCopy(_currentSave, _holdShift, _holdCtrl));
|
||||||
break;
|
break;
|
||||||
case DesignNameUse.NewDesign:
|
case DesignNameUse.NewDesign:
|
||||||
var empty = new CharacterSave();
|
var empty = new CharacterSave();
|
||||||
|
|
@ -157,7 +154,7 @@ namespace Glamourer.Gui
|
||||||
SaveNewDesign(empty);
|
SaveNewDesign(empty);
|
||||||
break;
|
break;
|
||||||
case DesignNameUse.DuplicateDesign:
|
case DesignNameUse.DuplicateDesign:
|
||||||
SaveNewDesign(ConditionalCopy(_selection!.Data));
|
SaveNewDesign(ConditionalCopy(_selection!.Data, _holdShift, _holdCtrl));
|
||||||
break;
|
break;
|
||||||
case DesignNameUse.NewFolder:
|
case DesignNameUse.NewFolder:
|
||||||
_designs.FileSystem
|
_designs.FileSystem
|
||||||
|
|
@ -196,6 +193,8 @@ namespace Glamourer.Gui
|
||||||
{
|
{
|
||||||
_newDesignName = string.Empty;
|
_newDesignName = string.Empty;
|
||||||
_keyboardFocus = true;
|
_keyboardFocus = true;
|
||||||
|
_holdCtrl = ImGui.GetIO().KeyCtrl;
|
||||||
|
_holdShift = ImGui.GetIO().KeyShift;
|
||||||
ImGui.OpenPopup($"{DesignNamePopupLabel}{use}");
|
ImGui.OpenPopup($"{DesignNamePopupLabel}{use}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
23
Glamourer/Offsets.cs
Normal file
23
Glamourer/Offsets.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
namespace Glamourer;
|
||||||
|
|
||||||
|
public static class Offsets
|
||||||
|
{
|
||||||
|
public static class Character
|
||||||
|
{
|
||||||
|
public const int Wetness = 0x1ADA;
|
||||||
|
public const int HatVisible = 0x84E;
|
||||||
|
public const int VisorToggled = 0x84F;
|
||||||
|
public const int WeaponHidden1 = 0x84F;
|
||||||
|
public const int WeaponHidden2 = 0x72C;
|
||||||
|
public const int Alpha = 0x19E0;
|
||||||
|
|
||||||
|
public static class Flags
|
||||||
|
{
|
||||||
|
public const byte IsHatHidden = 0x01;
|
||||||
|
public const byte IsVisorToggled = 0x08;
|
||||||
|
public const byte IsWet = 0x80;
|
||||||
|
public const byte IsWeaponHidden1 = 0x01;
|
||||||
|
public const byte IsWeaponHidden2 = 0x02;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,19 +6,31 @@ using Glamourer.Gui;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
|
||||||
namespace Glamourer
|
namespace Glamourer;
|
||||||
|
|
||||||
|
public class PenumbraAttach : IDisposable
|
||||||
{
|
{
|
||||||
public class PenumbraAttach : IDisposable
|
public const int RequiredPenumbraShareVersion = 4;
|
||||||
{
|
|
||||||
public const int RequiredPenumbraShareVersion = 3;
|
|
||||||
|
|
||||||
private ICallGateSubscriber<ChangedItemType, uint, object>? _tooltipSubscriber;
|
private ICallGateSubscriber<ChangedItemType, uint, object>? _tooltipSubscriber;
|
||||||
private ICallGateSubscriber<MouseButton, ChangedItemType, uint, object>? _clickSubscriber;
|
private ICallGateSubscriber<MouseButton, ChangedItemType, uint, object>? _clickSubscriber;
|
||||||
private ICallGateSubscriber<string, int, object>? _redrawSubscriberName;
|
private ICallGateSubscriber<string, int, object>? _redrawSubscriberName;
|
||||||
private ICallGateSubscriber<GameObject, int, object>? _redrawSubscriberObject;
|
private ICallGateSubscriber<GameObject, int, object>? _redrawSubscriberObject;
|
||||||
|
|
||||||
|
private readonly ICallGateSubscriber<object?> _initializedEvent;
|
||||||
|
private readonly ICallGateSubscriber<object?> _disposedEvent;
|
||||||
|
|
||||||
public PenumbraAttach(bool attach)
|
public PenumbraAttach(bool attach)
|
||||||
=> Reattach(attach);
|
{
|
||||||
|
_initializedEvent = Dalamud.PluginInterface.GetIpcSubscriber<object?>("Penumbra.Initialized");
|
||||||
|
_disposedEvent = Dalamud.PluginInterface.GetIpcSubscriber<object?>("Penumbra.Disposed");
|
||||||
|
_initializedEvent.Subscribe(Reattach);
|
||||||
|
_disposedEvent.Subscribe(Unattach);
|
||||||
|
Reattach(attach);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Reattach()
|
||||||
|
=> Reattach(Glamourer.Config.AttachToPenumbra);
|
||||||
|
|
||||||
public void Reattach(bool attach)
|
public void Reattach(bool attach)
|
||||||
{
|
{
|
||||||
|
|
@ -42,6 +54,7 @@ namespace Glamourer
|
||||||
Dalamud.PluginInterface.GetIpcSubscriber<MouseButton, ChangedItemType, uint, object>("Penumbra.ChangedItemClick");
|
Dalamud.PluginInterface.GetIpcSubscriber<MouseButton, ChangedItemType, uint, object>("Penumbra.ChangedItemClick");
|
||||||
_tooltipSubscriber.Subscribe(PenumbraTooltip);
|
_tooltipSubscriber.Subscribe(PenumbraTooltip);
|
||||||
_clickSubscriber.Subscribe(PenumbraRightClick);
|
_clickSubscriber.Subscribe(PenumbraRightClick);
|
||||||
|
PluginLog.Debug("Glamourer attached to Penumbra.");
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
@ -56,11 +69,19 @@ namespace Glamourer
|
||||||
_tooltipSubscriber = null;
|
_tooltipSubscriber = null;
|
||||||
_clickSubscriber = null;
|
_clickSubscriber = null;
|
||||||
_redrawSubscriberName = null;
|
_redrawSubscriberName = null;
|
||||||
|
if (_redrawSubscriberObject != null)
|
||||||
|
{
|
||||||
|
PluginLog.Debug("Glamourer detached from Penumbra.");
|
||||||
_redrawSubscriberObject = null;
|
_redrawSubscriberObject = null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
=> Unattach();
|
{
|
||||||
|
_initializedEvent.Unsubscribe(Reattach);
|
||||||
|
_disposedEvent.Unsubscribe(Unattach);
|
||||||
|
Unattach();
|
||||||
|
}
|
||||||
|
|
||||||
private static void PenumbraTooltip(ChangedItemType type, uint _)
|
private static void PenumbraTooltip(ChangedItemType type, uint _)
|
||||||
{
|
{
|
||||||
|
|
@ -75,7 +96,7 @@ namespace Glamourer
|
||||||
|
|
||||||
var gPose = Dalamud.Objects[Interface.GPoseObjectId] as Character;
|
var gPose = Dalamud.Objects[Interface.GPoseObjectId] as Character;
|
||||||
var player = Dalamud.Objects[0] as Character;
|
var player = Dalamud.Objects[0] as Character;
|
||||||
var item = (Lumina.Excel.GeneratedSheets.Item) type.GetObject(id)!;
|
var item = (Lumina.Excel.GeneratedSheets.Item)type.GetObject(id)!;
|
||||||
var writeItem = new Item(item, string.Empty);
|
var writeItem = new Item(item, string.Empty);
|
||||||
if (gPose != null)
|
if (gPose != null)
|
||||||
{
|
{
|
||||||
|
|
@ -95,7 +116,7 @@ namespace Glamourer
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_redrawSubscriberObject.InvokeAction(actor, (int) settings);
|
_redrawSubscriberObject.InvokeAction(actor, (int)settings);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
@ -126,7 +147,7 @@ namespace Glamourer
|
||||||
public void UpdateCharacters(Character character, Character? gPoseOriginalCharacter = null)
|
public void UpdateCharacters(Character character, Character? gPoseOriginalCharacter = null)
|
||||||
{
|
{
|
||||||
var newEquip = Glamourer.PlayerWatcher.UpdatePlayerWithoutEvent(character);
|
var newEquip = Glamourer.PlayerWatcher.UpdatePlayerWithoutEvent(character);
|
||||||
RedrawObject(character, RedrawType.WithSettings, true);
|
RedrawObject(character, RedrawType.Redraw, true);
|
||||||
|
|
||||||
// Special case for carrying over changes to the gPose player to the regular player, too.
|
// Special case for carrying over changes to the gPose player to the regular player, too.
|
||||||
if (gPoseOriginalCharacter == null)
|
if (gPoseOriginalCharacter == null)
|
||||||
|
|
@ -134,7 +155,6 @@ namespace Glamourer
|
||||||
|
|
||||||
newEquip.Write(gPoseOriginalCharacter.Address);
|
newEquip.Write(gPoseOriginalCharacter.Address);
|
||||||
Glamourer.PlayerWatcher.UpdatePlayerWithoutEvent(gPoseOriginalCharacter);
|
Glamourer.PlayerWatcher.UpdatePlayerWithoutEvent(gPoseOriginalCharacter);
|
||||||
RedrawObject(gPoseOriginalCharacter, RedrawType.AfterGPoseWithSettings, false);
|
RedrawObject(gPoseOriginalCharacter, RedrawType.AfterGPose, false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue