Skip to content

[Code] Make all enemy casts show under their nameplates #993

@anna-is-cute

Description

@anna-is-cute

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

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions