mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-12 18:27:24 +01:00
.
This commit is contained in:
parent
e57538561f
commit
90e451049e
5 changed files with 26 additions and 22 deletions
|
|
@ -77,7 +77,7 @@ public unsafe struct DesignData
|
|||
fixed (byte* ptr = _equipmentBytes)
|
||||
{
|
||||
var armorPtr = (CharacterArmor*)ptr;
|
||||
return armorPtr[slot is EquipSlot.MainHand ? 10 : 11].ToWeapon(_secondaryMainhand);
|
||||
return slot is EquipSlot.MainHand ? armorPtr[10].ToWeapon(_secondaryMainhand) : armorPtr[11].ToWeapon(_secondaryOffhand);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@ public unsafe class DebugTab : ITab
|
|||
? actor.AsCharacter->DrawData.IsWeaponHidden ? "Hidden" : "Visible"
|
||||
: "No Character");
|
||||
var text = string.Empty;
|
||||
// TODO
|
||||
|
||||
if (!model.IsHuman)
|
||||
{
|
||||
text = "No Model";
|
||||
|
|
@ -1142,6 +1142,11 @@ public unsafe class DebugTab : ITab
|
|||
_objectManager.Update();
|
||||
foreach (var (identifier, actors) in _objectManager)
|
||||
{
|
||||
if (ImGuiUtil.DrawDisabledButton($"{FontAwesomeIcon.Trash.ToIconString()}##{actors.Label}", new Vector2(ImGui.GetFrameHeight()),
|
||||
string.Empty, !_state.ContainsKey(identifier), true))
|
||||
_state.DeleteState(identifier);
|
||||
|
||||
ImGui.SameLine();
|
||||
using var t = ImRaii.TreeNode(actors.Label);
|
||||
if (!t)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@ using Dalamud.Utility.Signatures;
|
|||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using Glamourer.Events;
|
||||
using Glamourer.Interop.Structs;
|
||||
using ImGuiNET;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
using static FFXIVClientStructs.FFXIV.Client.UI.UIModule;
|
||||
|
||||
namespace Glamourer.Interop;
|
||||
|
||||
|
|
@ -69,26 +71,19 @@ public unsafe class WeaponService : IDisposable
|
|||
switch (slot)
|
||||
{
|
||||
case EquipSlot.MainHand:
|
||||
LoadWeaponDetour(&character.AsCharacter->DrawData, 0, weapon.Value, 0, 0, 1, 0);
|
||||
_loadWeaponHook.Original(&character.AsCharacter->DrawData, 0, weapon.Value, 0, 0, 1, 0);
|
||||
return;
|
||||
case EquipSlot.OffHand:
|
||||
LoadWeaponDetour(&character.AsCharacter->DrawData, 1, weapon.Value, 0, 0, 1, 0);
|
||||
_loadWeaponHook.Original(&character.AsCharacter->DrawData, 1, weapon.Value, 0, 0, 1, 0);
|
||||
return;
|
||||
case EquipSlot.BothHand:
|
||||
LoadWeaponDetour(&character.AsCharacter->DrawData, 0, weapon.Value, 0, 0, 1, 0);
|
||||
LoadWeaponDetour(&character.AsCharacter->DrawData, 1, CharacterWeapon.Empty.Value, 0, 0, 1, 0);
|
||||
_loadWeaponHook.Original(&character.AsCharacter->DrawData, 0, weapon.Value, 0, 0, 1, 0);
|
||||
_loadWeaponHook.Original(&character.AsCharacter->DrawData, 1, CharacterWeapon.Empty.Value, 0, 0, 1, 0);
|
||||
return;
|
||||
// function can also be called with '2', but does not seem to ever be.
|
||||
}
|
||||
}
|
||||
|
||||
// Load specific Main- and Offhand weapons.
|
||||
public void LoadWeapon(Actor character, CharacterWeapon main, CharacterWeapon off)
|
||||
{
|
||||
LoadWeaponDetour(&character.AsCharacter->DrawData, 0, main.Value, 1, 0, 1, 0);
|
||||
LoadWeaponDetour(&character.AsCharacter->DrawData, 1, off.Value, 1, 0, 1, 0);
|
||||
}
|
||||
|
||||
public void LoadStain(Actor character, EquipSlot slot, StainId stain)
|
||||
{
|
||||
var mdl = character.Model;
|
||||
|
|
|
|||
|
|
@ -312,10 +312,11 @@ public class StateListener : IDisposable
|
|||
return UpdateState.NoChange;
|
||||
|
||||
// Model ID did change, reload entire state accordingly.
|
||||
// Always use the actor for the base data.
|
||||
if (modelId == 0)
|
||||
state.BaseData.LoadNonHuman(modelId, *(Customize*)customizeData, (byte*)equipData);
|
||||
else
|
||||
state.BaseData = _manager.FromActor(actor);
|
||||
state.BaseData = _manager.FromActor(actor, false);
|
||||
|
||||
return UpdateState.Change;
|
||||
}
|
||||
|
|
@ -334,7 +335,7 @@ public class StateListener : IDisposable
|
|||
|
||||
// Customize array did not change to stored state.
|
||||
if (state.BaseData.Customize.Equals(customize))
|
||||
return UpdateState.NoChange;
|
||||
return UpdateState.NoChange; // TODO: handle wrong base data.
|
||||
|
||||
// Update customize base state.
|
||||
state.BaseData.Customize.Load(customize);
|
||||
|
|
|
|||
|
|
@ -75,12 +75,12 @@ public class StateManager : IReadOnlyDictionary<ActorIdentifier, ActorState>
|
|||
|
||||
try
|
||||
{
|
||||
var designData = FromActor(actor);
|
||||
// Initial Creation has identical base and model data.
|
||||
// Initial Creation, use the actors data for the base data,
|
||||
// and the draw objects data for the model data (where possible).
|
||||
state = new ActorState(identifier)
|
||||
{
|
||||
ModelData = designData,
|
||||
BaseData = designData,
|
||||
ModelData = FromActor(actor, true),
|
||||
BaseData = FromActor(actor, false),
|
||||
};
|
||||
// state.Identifier is owned.
|
||||
_states.Add(state.Identifier, state);
|
||||
|
|
@ -98,7 +98,7 @@ public class StateManager : IReadOnlyDictionary<ActorIdentifier, ActorState>
|
|||
/// This uses the draw object if available and where possible,
|
||||
/// and the game object where necessary.
|
||||
/// </summary>
|
||||
public unsafe DesignData FromActor(Actor actor)
|
||||
public unsafe DesignData FromActor(Actor actor, bool useModel)
|
||||
{
|
||||
var ret = new DesignData();
|
||||
// If the given actor is not a character, just return a default character.
|
||||
|
|
@ -110,7 +110,7 @@ public class StateManager : IReadOnlyDictionary<ActorIdentifier, ActorState>
|
|||
|
||||
// Model ID is only unambiguously contained in the game object.
|
||||
// The draw object only has the object type.
|
||||
// TODO do this right.
|
||||
// TODO reverse search model data to get model id from model.
|
||||
if (actor.AsCharacter->CharacterData.ModelCharaId != 0)
|
||||
{
|
||||
ret.LoadNonHuman((uint)actor.AsCharacter->CharacterData.ModelCharaId, *(Customize*)&actor.AsCharacter->DrawData.CustomizeData,
|
||||
|
|
@ -127,7 +127,7 @@ public class StateManager : IReadOnlyDictionary<ActorIdentifier, ActorState>
|
|||
ret.SetHatVisible(!actor.AsCharacter->DrawData.IsHatHidden);
|
||||
|
||||
// Use the draw object if it is a human.
|
||||
if (model.IsHuman)
|
||||
if (useModel && model.IsHuman)
|
||||
{
|
||||
// Customize can be obtained from the draw object.
|
||||
ret.Customize = model.GetCustomize();
|
||||
|
|
@ -484,4 +484,7 @@ public class StateManager : IReadOnlyDictionary<ActorIdentifier, ActorState>
|
|||
_editor.ChangeHatState(data, state.ModelData.IsHatVisible());
|
||||
_editor.ChangeVisor(data, state.ModelData.IsVisorToggled());
|
||||
}
|
||||
|
||||
public void DeleteState(ActorIdentifier identifier)
|
||||
=> _states.Remove(identifier);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue