mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2026-02-18 13:37:44 +01:00
.
This commit is contained in:
parent
63e82d19dc
commit
e57538561f
34 changed files with 2428 additions and 720 deletions
49
Glamourer/Interop/JobService.cs
Normal file
49
Glamourer/Interop/JobService.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue