-
-
Notifications
You must be signed in to change notification settings - Fork 156
Open
Description
Not currently in a situation where I can open a PR for this, but here's the relevant code from a standalone plugin I made for this. Seems like an appropriate tweak to me.
private unsafe delegate void* OnUpdateNameplateCastbarsDelegate(RaptureAtkModule* thisPtr);
[Signature("48 89 4C 24 ?? 57 41 55 41 56 41 57", DetourName = nameof(this.UpdateNameplateCastbarsDetour))]
private Hook<OnUpdateNameplateCastbarsDelegate> _updateNameplateCastbarsHook;
public Plugin() {
this.GameInterop!.InitializeFromAttributes(this);
this._updateNameplateCastbarsHook!.Enable();
}
public void Dispose() {
this._updateNameplateCastbarsHook.Dispose();
}
private unsafe void* UpdateNameplateCastbarsDetour(RaptureAtkModule* thisPtr) {
// The function this is hooking checks the caster's icon.
// || ((*(v16 + 0x1CC) - 2) & 0xFB) != 0 )
// The rest of the checks in this if statement are fine.
// To make this check evaluate to false, we set all icons to 2 before
// the function, then restore them after.
// You could also nop this check, but I think this is more reliable.
try {
return this.Inner(thisPtr);
} catch (Exception ex) {
this.Log.Error(ex, "Error in hook");
return this._updateNameplateCastbarsHook.Original(thisPtr);
}
}
private unsafe void* Inner(RaptureAtkModule* thisPtr) {
var oldIcons = new Dictionary<ulong, byte>();
foreach (var obj in this.ObjectTable) {
if (obj is IBattleNpc chara) {
var bc = (BattleChara*) chara.Address;
oldIcons[chara.GameObjectId] = bc->Icon;
bc->Icon = 2;
}
}
var ret = this._updateNameplateCastbarsHook.Original(thisPtr);
foreach (var obj in this.ObjectTable) {
if (oldIcons.TryGetValue(obj.GameObjectId, out var icon)) {
var bc = (BattleChara*) obj.Address;
bc->Icon = icon;
}
}
return ret;
}Apparently it's a thing in WoW and my gf wanted it in FFXIV. Thanks for being cool as always, Cara c:
Metadata
Metadata
Assignees
Labels
No labels