aers / FFXIVClientStructs

Resources for reverse-engineering the FFXIV client's native classes.
MIT License
224 stars 157 forks source link

AgentMap reports incorrect CurrentOffsetX and CurrentOffsetY values #1029

Closed thesabinelim closed 3 months ago

thesabinelim commented 3 months ago

Example steps to reproduce:

  1. Visit Shirogane Subdivision (Wards 31-60)
  2. Check the values of (*AgentMap.Instance()).CurrentOffsetX and (*AgentMap.Instance()).CurrentOffsetY
  3. Observe that they are -704 and -704, respectively

These numbers should be 704 and 704. Perhaps something changed in Dawntrail to make them negative?

This is currently breaking Dalamud's GetMapCoordinates() method: goatcorp/Dalamud#1916

Haselnussbomber commented 3 months ago

As far as I can see, nothing changed. They must have been negative before DT already.

6.58h2 @ 0x140BF424A is the same as in 7.0h1 @ 0x140DFB9B4:

a1->CurrentOffsetX = -v15->OffsetX;
a1->CurrentOffsetY = -v15->OffsetY;

SelectedOffsetX and Y in 6.58h2 @ 0x140BF9DFC is also the same as 7.0f1 @ 0x140E032C5.

a1->SelectedOffsetX = -v5->OffsetX;
a1->SelectedOffsetY = -v5->OffsetY;

Maybe an oversight in Dalamuds implementation of GetMapCoordinates().

pohky commented 3 months ago

yes it's missing something, the X and Y (or Z depending on naming) coordinates need to be adjusted by offset * scale when using the values from the agent (address for reference 1413A6170 where i got that from) my personal impl:

public static Vector3 WorldToMapDisplay(Vector3 worldPos, short sizeFactor, short offsetX, short offsetY, short offsetZ) {
    var scale = sizeFactor / 100f;
    worldPos -= new Vector3(offsetX, 0, offsetY) * scale;

    var x = (10 + 0.2f * (worldPos.X + offsetX) + 1024f * 0.2f / scale) / 10f;
    var y = MathF.Floor((worldPos.Y - offsetZ) / 10f) * 10f / 100f;
    var z = (10 + 0.2f * (worldPos.Z + offsetY) + 1024f * 0.2f / scale) / 10f;

    return new Vector3(x, y, z);
}
thesabinelim commented 3 months ago

As far as I can see, nothing changed. They must have been negative before DT already.

Interesting! Feel free to close this issue then, but OOC do we know why they're negative, while the equivalent OffsetX and OffsetY within Lumina's Map Excel sheet are not?

Haselnussbomber commented 3 months ago

I don't know why they saved it that way. Maybe it's a formula thing.

But as you can see above, it takes the offsets from the map sheet (v5 and v15 were Map row pointers) and assigns them to the AgentMap fields, just with an inverted sign.

When passing them to the WorldToMap function in Dalamud, you can simply invert it again. That way you save yourself the sheet lookup. 🤷‍♂️

            -agentMap->CurrentOffsetX,
            -agentMap->CurrentOffsetY,