This commit is contained in:
Ottermandias 2022-08-03 12:14:19 +02:00
parent 15d93830a3
commit cb2e2f0128
8 changed files with 393 additions and 357 deletions

4
.gitmodules vendored Normal file
View file

@ -0,0 +1,4 @@
[submodule "OtterGui"]
path = OtterGui
url = git@github.com:Ottermandias/OtterGui.git
branch = main

View file

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework> <TargetFramework>net6.0-windows</TargetFramework>
<LangVersion>preview</LangVersion> <LangVersion>preview</LangVersion>
<PlatformTarget>x64</PlatformTarget> <PlatformTarget>x64</PlatformTarget>
<RootNamespace>Glamourer</RootNamespace> <RootNamespace>Glamourer</RootNamespace>
@ -17,6 +17,8 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputPath>bin\$(Configuration)\</OutputPath> <OutputPath>bin\$(Configuration)\</OutputPath>
<MSBuildWarningsAsMessages>$(MSBuildWarningsAsMessages);MSB3277</MSBuildWarningsAsMessages> <MSBuildWarningsAsMessages>$(MSBuildWarningsAsMessages);MSB3277</MSBuildWarningsAsMessages>
<ProduceReferenceAssembly>false</ProduceReferenceAssembly>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@ -32,31 +34,33 @@
<MSBuildWarningsAsMessages>$(MSBuildWarningsAsMessages);MSB3277</MSBuildWarningsAsMessages> <MSBuildWarningsAsMessages>$(MSBuildWarningsAsMessages);MSB3277</MSBuildWarningsAsMessages>
</PropertyGroup> </PropertyGroup>
<PropertyGroup>
<DalamudLibPath>$(AppData)\XIVLauncher\addon\Hooks\dev\</DalamudLibPath>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Dalamud"> <Reference Include="Dalamud">
<HintPath>$(DALAMUD_ROOT)\Dalamud.dll</HintPath> <HintPath>$(DalamudLibPath)Dalamud.dll</HintPath>
<HintPath>..\libs\Dalamud.dll</HintPath>
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Dalamud.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="FFXIVClientStructs"> <Reference Include="FFXIVClientStructs">
<HintPath>$(appdata)\XIVLauncher\addon\Hooks\dev\FFXIVClientStructs.dll</HintPath> <HintPath>$(DalamudLibPath)FFXIVClientStructs.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ImGuiScene">
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\ImGuiScene.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="Lumina"> <Reference Include="Lumina">
<HintPath>$(DALAMUD_ROOT)\Lumina.dll</HintPath> <HintPath>$(DalamudLibPath)Lumina.dll</HintPath>
<HintPath>..\libs\Lumina.dll</HintPath>
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Lumina.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="Lumina.Excel"> <Reference Include="Lumina.Excel">
<HintPath>$(DALAMUD_ROOT)\Lumina.Excel.dll</HintPath> <HintPath>$(DalamudLibPath)Lumina.Excel.dll</HintPath>
<HintPath>..\libs\Lumina.Excel.dll</HintPath> <Private>False</Private>
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Lumina.Excel.dll</HintPath> </Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>$(DalamudLibPath)Newtonsoft.Json.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ImGuiScene">
<HintPath>$(DalamudLibPath)ImGuiScene.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
</ItemGroup> </ItemGroup>

View file

@ -0,0 +1,149 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Glamourer.Customization;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
namespace Glamourer;
public class CurrentManipulations
{
private readonly RestrictedGear _restrictedGear = GameData.RestrictedGear(Dalamud.GameData);
private readonly Dictionary<Actor.IIdentifier, CharacterSave> _characterSaves = new();
public CharacterSave CreateSave(Actor actor)
{
var id = actor.GetIdentifier();
if (_characterSaves.TryGetValue(id, out var save))
return save;
save = new CharacterSave(actor);
_characterSaves.Add(id.CreatePermanent(), save);
return save;
}
public bool TryGetDesign(Actor.IIdentifier identifier, [NotNullWhen(true)] out CharacterSave? save)
=> _characterSaves.TryGetValue(identifier, out save);
public CharacterArmor? ChangeEquip(Actor actor, EquipSlot slot, CharacterArmor data)
{
var save = CreateSave(actor);
(_, data) = _restrictedGear.ResolveRestricted(data, slot, save.Customize.Race, save.Customize.Gender);
if (save.Equipment[slot] == data)
return null;
save.Equipment[slot] = data;
return data;
}
public bool ChangeWeapon(Actor actor, CharacterWeapon main)
{
var save = CreateSave(actor);
if (save.MainHand == main)
return false;
save.MainHand = main;
return true;
}
public bool ChangeWeapon(Actor actor, CharacterWeapon main, CharacterWeapon off)
{
var save = CreateSave(actor);
if (main == save.MainHand && off == save.OffHand)
return false;
save.MainHand = main;
save.OffHand = off;
return true;
}
public void ChangeCustomization(Actor actor, Customize customize)
{
var save = CreateSave(actor);
FixRestrictedGear(save, customize.Gender, customize.Race);
save.Customize.Load(customize);
}
public bool ChangeCustomization(Actor actor, CustomizationId id, byte value)
{
if (id == CustomizationId.Race)
return ChangeRace(actor, (SubRace)value);
if (id == CustomizationId.Gender)
return ChangeGender(actor, (Gender)value);
var save = CreateSave(actor);
var customize = save.Customize;
if (customize[id] != value)
return false;
customize[id] = value;
return true;
}
// Change a gender and fix up all required customizations afterwards.
public bool ChangeGender(Actor actor, Gender gender)
{
var save = CreateSave(actor);
if (save.Customize.Gender == gender)
return false;
var customize = save.Customize;
FixRestrictedGear(save, gender, customize.Race);
FixUpAttributes(customize);
return true;
}
// Change a race and fix up all required customizations afterwards.
public bool ChangeRace(Actor actor, SubRace clan)
{
var save = CreateSave(actor);
if (save.Customize.Clan == clan)
return false;
var customize = save.Customize;
var race = clan.ToRace();
var gender = race == Race.Hrothgar ? Gender.Male : customize.Gender; // TODO Female Hrothgar
FixRestrictedGear(save, gender, race);
customize.Gender = gender;
customize.Race = race;
customize.Clan = clan;
FixUpAttributes(customize);
return true;
}
// Go through a whole customization struct and fix up all settings that need fixing.
private void FixUpAttributes(Customize customize)
{
var set = Glamourer.Customization.GetList(customize.Clan, customize.Gender);
foreach (CustomizationId id in Enum.GetValues(typeof(CustomizationId)))
{
switch (id)
{
case CustomizationId.Race: break;
case CustomizationId.Clan: break;
case CustomizationId.BodyType: break;
case CustomizationId.Gender: break;
case CustomizationId.FacialFeaturesTattoos: break;
case CustomizationId.HighlightsOnFlag: break;
case CustomizationId.Face: break;
default:
var count = set.Count(id);
if (set.DataByValue(id, customize[id], out _) < 0)
customize[id] = count == 0 ? (byte)0 : set.Data(id, 0).Value;
break;
}
}
}
private void FixRestrictedGear(CharacterSave save, Gender gender, Race race)
{
if (race == save.Customize.Race && gender == save.Customize.Gender)
return;
var equip = save.Equipment;
foreach (var slot in EquipSlotExtensions.EqdpSlots)
(_, equip[slot]) = _restrictedGear.ResolveRestricted(equip[slot], slot, race, gender);
}
}

12
Glamourer/FixedDesigns.cs Normal file
View file

@ -0,0 +1,12 @@
using System.Diagnostics.CodeAnalysis;
namespace Glamourer;
public class FixedDesigns
{
public bool TryGetDesign(Actor.IIdentifier actor, [NotNullWhen(true)] out CharacterSave? save)
{
save = null;
return false;
}
}

View file

@ -1,29 +1,10 @@
using System.Collections; using System.Reflection;
using System.ComponentModel.Design;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.InteropServices.ComTypes;
using Dalamud.Data;
using Dalamud.Game.ClientState.JobGauge.Enums;
using Dalamud.Game.Command; using Dalamud.Game.Command;
using Dalamud.Hooking;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using Dalamud.Plugin; using Dalamud.Plugin;
using FFXIVClientStructs.Attributes;
using FFXIVClientStructs.FFXIV.Client.Game.UI;
using FFXIVClientStructs.FFXIV.Component.Excel;
using Glamourer.Api; using Glamourer.Api;
using Glamourer.Customization; using Glamourer.Customization;
using Glamourer.Gui; using Glamourer.Gui;
using Lumina.Data.Parsing;
using Microsoft.VisualBasic.CompilerServices;
using OtterGui.Table;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
using static FFXIVClientStructs.FFXIV.Client.UI.Misc.RaptureMacroModule;
using static System.Collections.Specialized.BitVector32;
using static System.Reflection.Metadata.BlobBuilder;
using Race = Lumina.Excel.GeneratedSheets.Race;
namespace Glamourer; namespace Glamourer;
@ -45,10 +26,11 @@ public class Glamourer : IDalamudPlugin
public static GlamourerConfig Config = null!; public static GlamourerConfig Config = null!;
public static PenumbraAttach Penumbra = null!; public static PenumbraAttach Penumbra = null!;
public static ICustomizationManager Customization = null!; public static ICustomizationManager Customization = null!;
public static RedrawManager RedrawManager = null!; public static RedrawManager RedrawManager = null!;
private readonly WindowSystem _windowSystem = new("Glamourer"); private readonly WindowSystem _windowSystem = new("Glamourer");
private readonly FixedDesigns _fixedDesigns;
private readonly CurrentManipulations _currentManipulations;
private readonly Interface _interface; private readonly Interface _interface;
//public readonly DesignManager Designs; //public readonly DesignManager Designs;
@ -62,11 +44,12 @@ public class Glamourer : IDalamudPlugin
Customization = CustomizationManager.Create(Dalamud.PluginInterface, Dalamud.GameData, Dalamud.ClientState.ClientLanguage); Customization = CustomizationManager.Create(Dalamud.PluginInterface, Dalamud.GameData, Dalamud.ClientState.ClientLanguage);
Config = GlamourerConfig.Load(); Config = GlamourerConfig.Load();
Penumbra = new PenumbraAttach(Config.AttachToPenumbra); Penumbra = new PenumbraAttach(Config.AttachToPenumbra);
_fixedDesigns = new FixedDesigns();
//Designs = new DesignManager(); //Designs = new DesignManager();
//GlamourerIpc = new GlamourerIpc(Dalamud.ClientState, Dalamud.Objects, Dalamud.PluginInterface); //GlamourerIpc = new GlamourerIpc(Dalamud.ClientState, Dalamud.Objects, Dalamud.PluginInterface);
RedrawManager = new RedrawManager(); RedrawManager = new RedrawManager(_fixedDesigns, _currentManipulations);
Dalamud.Commands.AddHandler(MainCommandString, new CommandInfo(OnGlamourer) Dalamud.Commands.AddHandler(MainCommandString, new CommandInfo(OnGlamourer)
{ {

View file

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework> <TargetFramework>net6.0-windows</TargetFramework>
<LangVersion>preview</LangVersion> <LangVersion>preview</LangVersion>
<PlatformTarget>x64</PlatformTarget> <PlatformTarget>x64</PlatformTarget>
<RootNamespace>Glamourer</RootNamespace> <RootNamespace>Glamourer</RootNamespace>
@ -18,6 +18,8 @@
<OutputPath>bin\$(Configuration)\</OutputPath> <OutputPath>bin\$(Configuration)\</OutputPath>
<MSBuildWarningsAsMessages>$(MSBuildWarningsAsMessages);MSB3277</MSBuildWarningsAsMessages> <MSBuildWarningsAsMessages>$(MSBuildWarningsAsMessages);MSB3277</MSBuildWarningsAsMessages>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<ProduceReferenceAssembly>false</ProduceReferenceAssembly>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@ -45,39 +47,39 @@
<EmbeddedResource Include="LegacyTattoo.raw" /> <EmbeddedResource Include="LegacyTattoo.raw" />
</ItemGroup> </ItemGroup>
<PropertyGroup>
<DalamudLibPath>$(AppData)\XIVLauncher\addon\Hooks\dev\</DalamudLibPath>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Dalamud"> <Reference Include="Dalamud">
<HintPath>$(appdata)\XIVLauncher\addon\Hooks\dev\Dalamud.dll</HintPath> <HintPath>$(DalamudLibPath)Dalamud.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="FFXIVClientStructs"> <Reference Include="FFXIVClientStructs">
<HintPath>$(appdata)\XIVLauncher\addon\Hooks\dev\FFXIVClientStructs.dll</HintPath> <HintPath>$(DalamudLibPath)FFXIVClientStructs.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="ImGui.NET"> <Reference Include="ImGui.NET">
<HintPath>$(appdata)\XIVLauncher\addon\Hooks\dev\ImGui.NET.dll</HintPath> <HintPath>$(DalamudLibPath)ImGui.NET.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="ImGuiScene"> <Reference Include="ImGuiScene">
<HintPath>$(appdata)\XIVLauncher\addon\Hooks\dev\ImGuiScene.dll</HintPath> <HintPath>$(DalamudLibPath)ImGuiScene.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="SDL2-CS">
<HintPath>$(appdata)\XIVLauncher\addon\Hooks\dev\SDL2-CS.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="Lumina"> <Reference Include="Lumina">
<HintPath>$(appdata)\XIVLauncher\addon\Hooks\dev\Lumina.dll</HintPath> <HintPath>$(DalamudLibPath)Lumina.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="Lumina.Excel"> <Reference Include="Lumina.Excel">
<HintPath>$(appdata)\XIVLauncher\addon\Hooks\dev\Lumina.Excel.dll</HintPath> <HintPath>$(DalamudLibPath)Lumina.Excel.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>$(DalamudLibPath)Newtonsoft.Json.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -116,7 +118,9 @@
</None> </None>
</ItemGroup> </ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent"> <Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="if $(Configuration) == Release powershell Compress-Archive -Force $(TargetPath), $(TargetDir)$(SolutionName).json, $(TargetDir)$(SolutionName).GameData.dll, $(TargetDir)Penumbra.GameData.dll $(SolutionDir)$(SolutionName).zip" /> <Exec
<Exec Command="if $(Configuration) == Release powershell Copy-Item -Force $(TargetDir)$(SolutionName).json -Destination $(SolutionDir)" /> Command="if $(Configuration) == Release powershell Compress-Archive -Force $(TargetPath), $(TargetDir)$(SolutionName).json, $(TargetDir)$(SolutionName).GameData.dll, $(TargetDir)Penumbra.GameData.dll $(SolutionDir)$(SolutionName).zip" />
<Exec
Command="if $(Configuration) == Release powershell Copy-Item -Force $(TargetDir)$(SolutionName).json -Destination $(SolutionDir)" />
</Target> </Target>
</Project> </Project>

View file

@ -1,163 +1,15 @@
using System; using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Dalamud.Hooking; using Dalamud.Hooking;
using Dalamud.Logging;
using Dalamud.Utility.Signatures; using Dalamud.Utility.Signatures;
using FFXIVClientStructs.FFXIV.Client.Game.Character; using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using Glamourer.Customization;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
using static Glamourer.Actor;
namespace Glamourer; namespace Glamourer;
public class CurrentManipulations
{
private readonly RestrictedGear _restrictedGear = GameData.RestrictedGear(Dalamud.GameData);
private readonly Dictionary<Actor.IIdentifier, CharacterSave> _characterSaves = new();
public CharacterSave CreateSave(Actor actor)
{
var id = actor.GetIdentifier();
if (_characterSaves.TryGetValue(id, out var save))
return save;
save = new CharacterSave(actor);
_characterSaves.Add(id.CreatePermanent(), save);
return save;
}
public bool GetSave(Actor actor, [NotNullWhen(true)] out CharacterSave? save)
{
save = null;
return actor && _characterSaves.TryGetValue(actor.GetIdentifier(), out save);
}
public bool GetSave(Actor.IIdentifier identifier, [NotNullWhen(true)] out CharacterSave? save)
=> _characterSaves.TryGetValue(identifier, out save);
public CharacterArmor? ChangeEquip(Actor actor, EquipSlot slot, CharacterArmor data)
{
var save = CreateSave(actor);
(_, data) = _restrictedGear.ResolveRestricted(data, slot, save.Customize.Race, save.Customize.Gender);
if (save.Equipment[slot] == data)
return null;
save.Equipment[slot] = data;
return data;
}
public bool ChangeWeapon(Actor actor, CharacterWeapon main)
{
var save = CreateSave(actor);
if (save.MainHand == main)
return false;
save.MainHand = main;
return true;
}
public bool ChangeWeapon(Actor actor, CharacterWeapon main, CharacterWeapon off)
{
var save = CreateSave(actor);
if (main == save.MainHand && off == save.OffHand)
return false;
save.MainHand = main;
save.OffHand = off;
return true;
}
public void ChangeCustomization(Actor actor, Customize customize)
{
var save = CreateSave(actor);
FixRestrictedGear(save, customize.Gender, customize.Race);
save.Customize.Load(customize);
}
public bool ChangeCustomization(Actor actor, CustomizationId id, byte value)
{
if (id == CustomizationId.Race)
return ChangeRace(actor, (SubRace)value);
if (id == CustomizationId.Gender)
return ChangeGender(actor, (Gender)value);
var save = CreateSave(actor);
var customize = save.Customize;
if (customize[id] != value)
return false;
customize[id] = value;
return true;
}
// Change a gender and fix up all required customizations afterwards.
public bool ChangeGender(Actor actor, Gender gender)
{
var save = CreateSave(actor);
if (save.Customize.Gender == gender)
return false;
var customize = save.Customize;
FixRestrictedGear(save, gender, customize.Race);
FixUpAttributes(customize);
return true;
}
// Change a race and fix up all required customizations afterwards.
public bool ChangeRace(Actor actor, SubRace clan)
{
var save = CreateSave(actor);
if (save.Customize.Clan == clan)
return false;
var customize = save.Customize;
var race = clan.ToRace();
var gender = race == Race.Hrothgar ? Gender.Male : customize.Gender; // TODO Female Hrothgar
FixRestrictedGear(save, gender, race);
customize.Gender = gender;
customize.Race = race;
customize.Clan = clan;
FixUpAttributes(customize);
return true;
}
// Go through a whole customization struct and fix up all settings that need fixing.
private void FixUpAttributes(Customize customize)
{
var set = Glamourer.Customization.GetList(customize.Clan, customize.Gender);
foreach (CustomizationId id in Enum.GetValues(typeof(CustomizationId)))
{
switch (id)
{
case CustomizationId.Race: break;
case CustomizationId.Clan: break;
case CustomizationId.BodyType: break;
case CustomizationId.Gender: break;
case CustomizationId.FacialFeaturesTattoos: break;
case CustomizationId.HighlightsOnFlag: break;
case CustomizationId.Face: break;
default:
var count = set.Count(id);
if (set.DataByValue(id, customize[id], out _) < 0)
customize[id] = count == 0 ? (byte)0 : set.Data(id, 0).Value;
break;
}
}
}
private void FixRestrictedGear(CharacterSave save, Gender gender, Race race)
{
if (race == save.Customize.Race && gender == save.Customize.Gender)
return;
var equip = save.Equipment;
foreach (var slot in EquipSlotExtensions.EqdpSlots)
(_, equip[slot]) = _restrictedGear.ResolveRestricted(equip[slot], slot, race, gender);
}
}
public unsafe partial class RedrawManager public unsafe partial class RedrawManager
{ {
public delegate ulong FlagSlotForUpdateDelegate(Human* drawObject, uint slot, CharacterArmor* data); public delegate ulong FlagSlotForUpdateDelegate(Human* drawObject, uint slot, CharacterArmor* data);
@ -168,25 +20,27 @@ public unsafe partial class RedrawManager
private ulong FlagSlotForUpdateDetour(Human* drawObject, uint slot, CharacterArmor* data) private ulong FlagSlotForUpdateDetour(Human* drawObject, uint slot, CharacterArmor* data)
{ {
//try try
//{ {
// var actor = Glamourer.Penumbra.GameObjectFromDrawObject((IntPtr)drawObject); var actor = Glamourer.Penumbra.GameObjectFromDrawObject((IntPtr)drawObject);
// if (actor && CurrentManipulations.GetSave(actor, out _)) var identifier = actor.GetIdentifier();
// // TODO fixed design
// if (_fixedDesigns.TryGetDesign(identifier, out var save))
// *data = CurrentManipulations.ChangeEquip(actor, slot.ToEquipSlot(), *data) ?? *data; PluginLog.Information($"Loaded {slot.ToEquipSlot()} from fixed design for {identifier}.");
//} else if (_currentManipulations.TryGetDesign(identifier, out save))
//catch PluginLog.Information($"Updated {slot.ToEquipSlot()} from current designs for {identifier}.");
//{ }
// // ignored catch (Exception e)
//} {
PluginLog.Error($"Error on loading new gear:\n{e}");
}
return _flagSlotForUpdateHook!.Original(drawObject, slot, data); return _flagSlotForUpdateHook!.Original(drawObject, slot, data);
} }
public bool ChangeEquip(Actor actor, EquipSlot slot, CharacterArmor data) public bool ChangeEquip(Actor actor, EquipSlot slot, CharacterArmor data)
{ {
if (actor && CurrentManipulations.ChangeEquip(actor, slot, data).HasValue && actor.DrawObject != null) if (actor && actor.DrawObject != null)
return _flagSlotForUpdateHook?.Original(actor.DrawObject, slot.ToIndex(), &data) != 0; return _flagSlotForUpdateHook?.Original(actor.DrawObject, slot.ToIndex(), &data) != 0;
return false; return false;
@ -214,6 +68,20 @@ public unsafe partial class RedrawManager
private void LoadWeaponDetour(IntPtr characterOffset, uint slot, CharacterWeapon weapon, byte unk1, byte unk2, byte unk3, byte unk4) private void LoadWeaponDetour(IntPtr characterOffset, uint slot, CharacterWeapon weapon, byte unk1, byte unk2, byte unk3, byte unk4)
{ {
try
{
var character = (Actor)(characterOffset - CharacterWeaponOffset);
var identifier = character.GetIdentifier();
if (_fixedDesigns.TryGetDesign(identifier, out var save))
PluginLog.Information($"Loaded weapon from fixed design for {identifier}.");
else if (unk1 == 1 && _currentManipulations.TryGetDesign(identifier, out save))
PluginLog.Information($"Loaded weapon from current design for {identifier}.");
}
catch (Exception e)
{
PluginLog.Error($"Error on loading new weapon:\n{e}");
}
_loadWeaponHook!.Original(characterOffset, slot, weapon, unk1, unk2, unk3, unk4); _loadWeaponHook!.Original(characterOffset, slot, weapon, unk1, unk2, unk3, unk4);
} }
@ -223,14 +91,14 @@ public unsafe partial class RedrawManager
switch (slot) switch (slot)
{ {
case EquipSlot.MainHand: case EquipSlot.MainHand:
LoadWeaponDetour(character + CharacterWeaponOffset, 0, weapon, 1, 1, 0, 1); LoadWeaponDetour(character + CharacterWeaponOffset, 0, weapon, 0, 1, 0, 0);
return; return;
case EquipSlot.OffHand: case EquipSlot.OffHand:
LoadWeaponDetour(character + CharacterWeaponOffset, 1, weapon, 1, 1, 0, 1); LoadWeaponDetour(character + CharacterWeaponOffset, 1, weapon, 0, 1, 0, 0);
return; return;
case EquipSlot.BothHand: case EquipSlot.BothHand:
LoadWeaponDetour(character + CharacterWeaponOffset, 0, weapon, 1, 1, 0, 1); LoadWeaponDetour(character + CharacterWeaponOffset, 0, weapon, 0, 1, 0, 0);
LoadWeaponDetour(character + CharacterWeaponOffset, 1, CharacterWeapon.Empty, 1, 1, 0, 1); LoadWeaponDetour(character + CharacterWeaponOffset, 1, CharacterWeapon.Empty, 0, 1, 0, 0);
return; return;
// function can also be called with '2', but does not seem to ever be. // function can also be called with '2', but does not seem to ever be.
} }
@ -242,8 +110,8 @@ public unsafe partial class RedrawManager
// Load specific Main- and Offhand weapons. // Load specific Main- and Offhand weapons.
public void LoadWeapon(IntPtr character, CharacterWeapon main, CharacterWeapon off) public void LoadWeapon(IntPtr character, CharacterWeapon main, CharacterWeapon off)
{ {
LoadWeaponDetour(character + CharacterWeaponOffset, 0, main, 1, 1, 0, 1); LoadWeaponDetour(character + CharacterWeaponOffset, 0, main, 0, 1, 0, 0);
LoadWeaponDetour(character + CharacterWeaponOffset, 1, off, 1, 1, 0, 1); LoadWeaponDetour(character + CharacterWeaponOffset, 1, off, 0, 1, 0, 0);
} }
public void LoadWeapon(Character* character, CharacterWeapon main, CharacterWeapon off) public void LoadWeapon(Character* character, CharacterWeapon main, CharacterWeapon off)
@ -254,10 +122,15 @@ public unsafe partial class RedrawManager : IDisposable
{ {
internal readonly CurrentManipulations CurrentManipulations = new(); internal readonly CurrentManipulations CurrentManipulations = new();
public RedrawManager() private readonly FixedDesigns _fixedDesigns;
private readonly CurrentManipulations _currentManipulations;
public RedrawManager(FixedDesigns fixedDesigns, CurrentManipulations currentManipulations)
{ {
SignatureHelper.Initialise(this); SignatureHelper.Initialise(this);
Glamourer.Penumbra.CreatingCharacterBase += OnCharacterRedraw; Glamourer.Penumbra.CreatingCharacterBase += OnCharacterRedraw;
_fixedDesigns = fixedDesigns;
_currentManipulations = currentManipulations;
//_flagSlotForUpdateHook?.Enable(); //_flagSlotForUpdateHook?.Enable();
//_loadWeaponHook?.Enable(); //_loadWeaponHook?.Enable();
} }
@ -271,13 +144,19 @@ public unsafe partial class RedrawManager : IDisposable
private void OnCharacterRedraw(IntPtr addr, IntPtr modelId, IntPtr customize, IntPtr equipData) private void OnCharacterRedraw(IntPtr addr, IntPtr modelId, IntPtr customize, IntPtr equipData)
{ {
//if (CurrentManipulations.GetSave(addr, out var save)) try
//{ {
// *(CustomizationData*)customize = *(CustomizationData*)save.Customization.Address; var actor = (Actor)addr;
// var equip = (CharacterEquip)equipData; var identifier = actor.GetIdentifier();
// var newEquip = save.Equipment;
// for (var i = 0; i < 10; ++i) if (_currentManipulations.TryGetDesign(identifier, out var save))
// equip[i] = newEquip[i]; PluginLog.Information($"Loaded current design for {identifier}.");
//} else if (_fixedDesigns.TryGetDesign(identifier, out save))
PluginLog.Information($"Loaded fixed design for {identifier}.");
}
catch (Exception e)
{
PluginLog.Error($"Error on new draw object creation:\n{e}");
}
} }
} }

1
OtterGui Submodule

@ -0,0 +1 @@
Subproject commit 4c92479175161617161d8faf844c8f683aa2d5d2