This commit is contained in:
Ottermandias 2023-06-28 01:39:53 +02:00
parent 63e82d19dc
commit e57538561f
34 changed files with 2428 additions and 720 deletions

View file

@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Dalamud.Data;
using Dalamud.Hooking;
using Dalamud.Utility.Signatures;
using FFXIVClientStructs.FFXIV.Client.Game.Character;
using Glamourer.Interop.Structs;
using Glamourer.Structs;
namespace Glamourer.Interop;
public class JobService : IDisposable
{
private readonly nint _characterDataOffset;
public readonly IReadOnlyDictionary<byte, Job> Jobs;
public readonly IReadOnlyDictionary<ushort, JobGroup> JobGroups;
public event Action<Actor, Job>? JobChanged;
public JobService(DataManager gameData)
{
SignatureHelper.Initialise(this);
_characterDataOffset = Marshal.OffsetOf<Character>(nameof(Character.CharacterData));
Jobs = GameData.Jobs(gameData);
JobGroups = GameData.JobGroups(gameData);
_changeJobHook.Enable();
}
public void Dispose()
{
_changeJobHook.Dispose();
}
private delegate void ChangeJobDelegate(nint data, uint job);
[Signature(Sigs.ChangeJob, DetourName = nameof(ChangeJobDetour))]
private readonly Hook<ChangeJobDelegate> _changeJobHook = null!;
private void ChangeJobDetour(nint data, uint jobIndex)
{
_changeJobHook.Original(data, jobIndex);
var actor = (Actor)(data - _characterDataOffset);
var job = Jobs.TryGetValue((byte) jobIndex, out var j) ? j : Jobs[0];
Glamourer.Log.Excessive($"{actor} changed job to {job}");
JobChanged?.Invoke(actor, job);
}
}

View file

@ -88,7 +88,7 @@ public readonly unsafe struct Model : IEquatable<Model>
/// <summary> Only valid for humans. </summary>
public CharacterArmor GetArmor(EquipSlot slot)
=> ((CharacterArmor*)AsHuman->EquipSlotData)[slot.ToIndex()];
=> ((CharacterArmor*)&AsHuman->Head)[slot.ToIndex()];
public Customize GetCustomize()
=> *(Customize*)&AsHuman->Customize;

View file

@ -51,11 +51,14 @@ public unsafe class WeaponService : IDisposable
_ => EquipSlot.Unknown,
};
var tmpWeapon = weapon;
// First call the regular function.
if (equipSlot is not EquipSlot.Unknown)
_event.Invoke(actor, equipSlot, ref weapon);
_event.Invoke(actor, equipSlot, ref tmpWeapon);
_loadWeaponHook.Original(drawData, slot, weapon.Value, redrawOnEquality, unk2, skipGameObject, unk4);
if (tmpWeapon.Value != weapon.Value)
_loadWeaponHook.Original(drawData, slot, tmpWeapon.Value, 1, unk2, 1, unk4);
Glamourer.Log.Excessive(
$"Weapon reloaded for 0x{actor.Address:X} ({actor.Utf8Name}) with attributes {slot} {weapon.Value:X14}, {redrawOnEquality}, {unk2}, {skipGameObject}, {unk4}");
}
@ -88,8 +91,10 @@ public unsafe class WeaponService : IDisposable
public void LoadStain(Actor character, EquipSlot slot, StainId stain)
{
var value = slot == EquipSlot.OffHand ? character.AsCharacter->DrawData.OffHandModel : character.AsCharacter->DrawData.MainHandModel;
var weapon = new CharacterWeapon(value.Value) { Stain = stain.Value };
var mdl = character.Model;
var (_, _, mh, oh) = mdl.GetWeapons(character);
var value = slot == EquipSlot.OffHand ? oh : mh;
var weapon = value.With(value.Set.Value == 0 ? 0 : stain);
LoadWeapon(character, slot, weapon);
}
}
}