Target unit ground position menu

Shout-Out

User Tag List

Page 1 of 3 123 LastLast
Results 1 to 15 of 36
  1. #1
    goblin2kx's Avatar Member
    Reputation
    8
    Join Date
    Jun 2007
    Posts
    31
    Thanks G/R
    13/2
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Target unit ground position

    Hi,
    Thanks in advance to anyone who provides hints on this. I have an issue: I can extract any unit world position, get camera position/matrix/fov and apply transformation to get the correct game window x and y position of any unit. However my issue is that the position is somewhere inside the model with some height from the ground. Basically I want to retrieve the position of the centre of the target circle on the ground when a unit/player is selected. Is this even possible? I should mention I'm trying to do this without having to unlock any protected lua.

    Target unit ground position
  2. #2
    goblin2kx's Avatar Member
    Reputation
    8
    Join Date
    Jun 2007
    Posts
    31
    Thanks G/R
    13/2
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I guess if I have the unit height it should be simple subtraction of the z-height to get the position on the ground. It looks like 3.3.5 had this built into the unit class.

  3. #3
    Razzue's Avatar Contributor Avid Ailurophile

    CoreCoins Purchaser Authenticator enabled
    Reputation
    391
    Join Date
    Jun 2017
    Posts
    602
    Thanks G/R
    191/277
    Trade Feedback
    2 (100%)
    Mentioned
    14 Post(s)
    Tagged
    0 Thread(s)
    Wait.. what?

    All live versions of the game -> an entities x/y/z IS the ground co-ordinate.. 😅
    "May all your bacon burn"

  4. Thanks dreadcraft (1 members gave Thanks to Razzue for this useful post)
  5. #4
    goblin2kx's Avatar Member
    Reputation
    8
    Join Date
    Jun 2007
    Posts
    31
    Thanks G/R
    13/2
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Razzue View Post
    Wait.. what?

    All live versions of the game -> an entities x/y/z IS the ground co-ordinate.. 😅
    Weird all my coordinates end up being somewhere above the ground on the model. Maybe I have the wrong coordinates?
    My XYZ are extracted from the position struct (i.e. x = [[unit + 0xB8]+0x20])

  6. #5
    dreadcraft's Avatar Member
    Reputation
    2
    Join Date
    Jun 2018
    Posts
    13
    Thanks G/R
    11/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What version of the client are you working with? That might be a good starting point.
    Is it possible that you're using the offsets for a GameObject's X/Y/Z as opposed to a Unit's X/Y/Z?

  7. #6
    goblin2kx's Avatar Member
    Reputation
    8
    Join Date
    Jun 2007
    Posts
    31
    Thanks G/R
    13/2
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by dreadcraft View Post
    What version of the client are you working with? That might be a good starting point.
    Is it possible that you're using the offsets for a GameObject's X/Y/Z as opposed to a Unit's X/Y/Z?
    Hey thanks for the reply, I'm on retail. I was sure I was using the unit coordinates, but now I'm not so sure

    Edit: I found the unit coordinates through cheat engine. [[[object + 0x18] + 0xB8]+0x20]
    Last edited by goblin2kx; 10-08-2024 at 06:00 AM.

  8. #7
    thateuler's Avatar Active Member
    Reputation
    24
    Join Date
    May 2019
    Posts
    39
    Thanks G/R
    24/17
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Just an FYI goblin2kx. Those coordinates are the raw coordinates. If you're in a transport (like a boat or a thunderbluff elevator) then the raw coordinates will be relative to the transport coordinates. Some boss fights are in transports (loot ship in wrath. some dungeon in shadowlands). In retail I believe that the unit/player/localplayer object class vmt 18 is a function that will give you the actual coords even if the unit is in a transport.

    You know. I should be more hesitant to share this into in a public place. Blizz will just add more checks to vmts and I'll have to finally write the code to compute the transform myself. If anyone has a private forum where this type of information can be shared out of blizz's prying eyes, I'd appreciate an invite. In a couple of days I think i'll come back and redact this comment.

  9. Thanks Razzue, goblin2kx (2 members gave Thanks to thateuler for this useful post)
  10. #8
    Razzue's Avatar Contributor Avid Ailurophile

    CoreCoins Purchaser Authenticator enabled
    Reputation
    391
    Join Date
    Jun 2017
    Posts
    602
    Thanks G/R
    191/277
    Trade Feedback
    2 (100%)
    Mentioned
    14 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by goblin2kx View Post
    Hey thanks for the reply, I'm on retail. I was sure I was using the unit coordinates, but now I'm not so sure

    Edit: I found the unit coordinates through cheat engine. [[[object + 0x18] + 0xB8]+0x20]
    Ahh, looks like you were trying to walk the array objects as entities

    You can also utilize EnumVisObjects at 0x120 of the object manager, iirc retail entities are that address - 0x28 or 0x30. But theres better examples of what I'm going on about around the forum xD
    "May all your bacon burn"

  11. Thanks goblin2kx (1 members gave Thanks to Razzue for this useful post)
  12. #9
    scizzydo's Avatar Contributor
    Reputation
    182
    Join Date
    Oct 2019
    Posts
    121
    Thanks G/R
    5/76
    Trade Feedback
    0 (0%)
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by thateuler View Post
    Just an FYI goblin2kx. Those coordinates are the raw coordinates. If you're in a transport (like a boat or a thunderbluff elevator) then the raw coordinates will be relative to the transport coordinates. Some boss fights are in transports (loot ship in wrath. some dungeon in shadowlands). In retail I believe that the unit/player/localplayer object class vmt 18 is a function that will give you the actual coords even if the unit is in a transport.

    You know. I should be more hesitant to share this into in a public place. Blizz will just add more checks to vmts and I'll have to finally write the code to compute the transform myself. If anyone has a private forum where this type of information can be shared out of blizz's prying eyes, I'd appreciate an invite. In a couple of days I think i'll come back and redact this comment.
    No need to redact... this stuff has been public knowledge for quite some time. I have yet to see a VMT being checked, and even if they were ret checked, you can easily fake it with a rop gadget. It's just the aggressive checks where they register where functions are direct calls that the ret check requires it from specific calling locations. Stuff like the CGUnit_C::GetPosition is only called from vtable, so it would be a call rax type situation, easy to fake with assembly. As far as transforms:
    Code:
                    Matrix44 mat;
                    if (pobj->GetMatrix44(&mat)) {
                        const auto inv_m = mat.inverse();
                        const auto rel = inv_m.multiplyVec3(in);
                        lua_pushvec3(L, rel);
                        return 3;
                    }
    That's my lua callback code for transforming a world coordinate to the transport relative location (useful for the fights you're on a transport, and the transport moves). Without that, your spells would "slip" off the transport.
    Code:
    struct Matrix44 {
        float m[4][4];
        Matrix44() {
            m[0][0] = 1.f; m[0][1] = 0.f; m[0][2] = 0.f; m[0][3] = 0.f;
            m[1][0] = 0.f; m[1][1] = 1.f; m[1][2] = 0.f; m[1][3] = 0.f;
            m[2][0] = 0.f; m[2][1] = 0.f; m[2][2] = 1.f; m[2][3] = 0.f;
            m[3][0] = 0.f; m[3][1] = 0.f; m[3][2] = 0.f; m[3][3] = 1.f;
        }
        Matrix44(float val[4][4]) {
            for (int i = 0; i < 4; ++i)
                for (int j = 0; j < 4; ++j)
                    m[i][j] = val[i][j];
        }
    
        Matrix44 inverse() const {
            Matrix44 inv;
    
            // Transpose the 3x3 rotation part (this inverts the rotation)
            inv.m[0][0] = m[0][0]; // First column
            inv.m[0][1] = m[1][0];
            inv.m[0][2] = m[2][0];
    
            inv.m[1][0] = m[0][1]; // Second column
            inv.m[1][1] = m[1][1];
            inv.m[1][2] = m[2][1];
    
            inv.m[2][0] = m[0][2]; // Third column
            inv.m[2][1] = m[1][2];
            inv.m[2][2] = m[2][2];
    
            // Invert the translation by applying the inverted rotation to the translation vector
            inv.m[3][0] = -(inv.m[0][0] * m[3][0] + inv.m[1][0] * m[3][1] + inv.m[2][0] * m[3][2]);
            inv.m[3][1] = -(inv.m[0][1] * m[3][0] + inv.m[1][1] * m[3][1] + inv.m[2][1] * m[3][2]);
            inv.m[3][2] = -(inv.m[0][2] * m[3][0] + inv.m[1][2] * m[3][1] + inv.m[2][2] * m[3][2]);
    
            // Set the bottom row (identity matrix row)
            inv.m[0][3] = 0.0f;
            inv.m[1][3] = 0.0f;
            inv.m[2][3] = 0.0f;
            inv.m[3][3] = 1.0f;
    
            return inv;
        }
    
        Vec3 multiplyVec3(const Vec3& v) const {
            Vec3 result;
            result.x = m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0]; // m[3][0] is the x translation
            result.y = m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1]; // m[3][1] is the y translation
            result.z = m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z + m[3][2]; // m[3][2] is the z translation
            return result;
        }
    };
    Heck, even the transform matrix shit can be found on this forum from pretty far back if you search properly

    VMTs:
    CGObject_C::GetPosition - 18 windows, 19 mac
    CGObject_C::GetPositionRaw - 19 windows, 20 mac
    CGUnit_C::GetFacing - 20 windows, 21 mac
    CGUnit_C::GetFacingRaw - 21 windows, 22 mac

    Up to you to find the matrix Which one of the matrix functions that you can use from the mac wod binary is also now behind a ret check

    Hint: There is a virtual function that returns the matrix. It's just not as easy to call on MacOS (arm) due to arg2 not being in the correct register if you were to compile the code on your own :P
    Last edited by scizzydo; 10-10-2024 at 03:40 AM.

  13. Thanks goblin2kx, thateuler (2 members gave Thanks to scizzydo for this useful post)
  14. #10
    scizzydo's Avatar Contributor
    Reputation
    182
    Join Date
    Oct 2019
    Posts
    121
    Thanks G/R
    5/76
    Trade Feedback
    0 (0%)
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Razzue View Post
    Ahh, looks like you were trying to walk the array objects as entities

    You can also utilize EnumVisObjects at 0x120 of the object manager, iirc retail entities are that address - 0x28 or 0x30. But theres better examples of what I'm going on about around the forum xD
    Yeah, 0x120 contains the linked list of all CGObject_C derived types. 0x130 is the linked list of all unit/player and activeplayer objects. 0x30 on the CGObject_C for the neighbor object, and 0x40 for the neighbor unit. So, to what he said, walk that subtract 0x30 or 0x40, then +0xB8 for the unit movement struct which has the raw values.

    ...since we're talking about this now, anyone notice that facing isn't updated all the time now? At least in this structure. I render my targets facing all the time, and since 11.0.2 I noticed that if the Unit is stationary, but rotating yaw it's not updated in the movement struct... gotta look at the display data to get the facing correctly now. (At least for units, players are updated all the time)

  15. Thanks goblin2kx (1 members gave Thanks to scizzydo for this useful post)
  16. #11
    goblin2kx's Avatar Member
    Reputation
    8
    Join Date
    Jun 2007
    Posts
    31
    Thanks G/R
    13/2
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by scizzydo View Post
    No need to redact... this stuff has been public knowledge for quite some time. I have yet to see a VMT being checked, and even if they were ret checked, you can easily fake it with a rop gadget. It's just the aggressive checks where they register where functions are direct calls that the ret check requires it from specific calling locations. Stuff like the CGUnit_C::GetPosition is only called from vtable, so it would be a call rax type situation, easy to fake with assembly. As far as transforms:
    Code:
                    Matrix44 mat;
                    if (pobj->GetMatrix44(&mat)) {
                        const auto inv_m = mat.inverse();
                        const auto rel = inv_m.multiplyVec3(in);
                        lua_pushvec3(L, rel);
                        return 3;
                    }
    That's my lua callback code for transforming a world coordinate to the transport relative location (useful for the fights you're on a transport, and the transport moves). Without that, your spells would "slip" off the transport.
    Code:
    struct Matrix44 {
        float m[4][4];
        Matrix44() {
            m[0][0] = 1.f; m[0][1] = 0.f; m[0][2] = 0.f; m[0][3] = 0.f;
            m[1][0] = 0.f; m[1][1] = 1.f; m[1][2] = 0.f; m[1][3] = 0.f;
            m[2][0] = 0.f; m[2][1] = 0.f; m[2][2] = 1.f; m[2][3] = 0.f;
            m[3][0] = 0.f; m[3][1] = 0.f; m[3][2] = 0.f; m[3][3] = 1.f;
        }
        Matrix44(float val[4][4]) {
            for (int i = 0; i < 4; ++i)
                for (int j = 0; j < 4; ++j)
                    m[i][j] = val[i][j];
        }
    
        Matrix44 inverse() const {
            Matrix44 inv;
    
            // Transpose the 3x3 rotation part (this inverts the rotation)
            inv.m[0][0] = m[0][0]; // First column
            inv.m[0][1] = m[1][0];
            inv.m[0][2] = m[2][0];
    
            inv.m[1][0] = m[0][1]; // Second column
            inv.m[1][1] = m[1][1];
            inv.m[1][2] = m[2][1];
    
            inv.m[2][0] = m[0][2]; // Third column
            inv.m[2][1] = m[1][2];
            inv.m[2][2] = m[2][2];
    
            // Invert the translation by applying the inverted rotation to the translation vector
            inv.m[3][0] = -(inv.m[0][0] * m[3][0] + inv.m[1][0] * m[3][1] + inv.m[2][0] * m[3][2]);
            inv.m[3][1] = -(inv.m[0][1] * m[3][0] + inv.m[1][1] * m[3][1] + inv.m[2][1] * m[3][2]);
            inv.m[3][2] = -(inv.m[0][2] * m[3][0] + inv.m[1][2] * m[3][1] + inv.m[2][2] * m[3][2]);
    
            // Set the bottom row (identity matrix row)
            inv.m[0][3] = 0.0f;
            inv.m[1][3] = 0.0f;
            inv.m[2][3] = 0.0f;
            inv.m[3][3] = 1.0f;
    
            return inv;
        }
    
        Vec3 multiplyVec3(const Vec3& v) const {
            Vec3 result;
            result.x = m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0]; // m[3][0] is the x translation
            result.y = m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1]; // m[3][1] is the y translation
            result.z = m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z + m[3][2]; // m[3][2] is the z translation
            return result;
        }
    };
    Heck, even the transform matrix shit can be found on this forum from pretty far back if you search properly

    VMTs:
    CGObject_C::GetPosition - 18 windows, 19 mac
    CGObject_C::GetPositionRaw - 19 windows, 20 mac
    CGUnit_C::GetFacing - 20 windows, 21 mac
    CGUnit_C::GetFacingRaw - 21 windows, 22 mac

    Up to you to find the matrix Which one of the matrix functions that you can use from the mac wod binary is also now behind a ret check

    Hint: There is a virtual function that returns the matrix. It's just not as easy to call on MacOS (arm) due to arg2 not being in the correct register if you were to compile the code on your own :P
    Thanks for the replies everyone (gave you all thanks!), I found CGObject_C::GetPosition and CGObject_C::GetPositionRaw. Calling CGObject_C::GetPosition now, but getting same coordinates as before ([[[entity + 0x18] + 0xB8]+0x20]). Inspecting the code inside GetPosition seems to have some additional handing for transports as opposed to GetPositionRaw. This is good, that means as you said if I call CGObject_C::GetPosition on a transport, I should be getting the absolute position correct?

    CGObject_C::GetPosition:
    X pos -2499.14
    Y pos -379.241
    Z pos -8.19711

    CGObject_C::GetPositionRaw:
    X raw pos -2499.14
    Y raw pos -379.241
    Z raw pos -8.19711

    [[[entity + 0x18] + 0xB8]+0x20]
    world x -2499.14
    world y -379.241
    world z -8.19711


    So back to original question I had, are these positions supposed to to be at the feet of model, i.e. where the model touches the terrain (when the unit is on the ground anyway)? If so sounds like I have issues with my world XYZ->screen because when I translate the position I get slight elevated screen X,Y.

    Side note to anyone who's looking for these position functions (retail 56819):
    CGObject_C::GetPosition = 0x2558B50
    CGObject_C::GetPositionRaw = 0x2559120
    The need to be called with (CGObject_C*,float*) obviously.

    Edit: I was more or less sure that the coordinates are correct, I just wanted to show that what I'm getting and what the VMT function gives are the same.
    Last edited by goblin2kx; 10-10-2024 at 07:43 AM.

  17. #12
    scizzydo's Avatar Contributor
    Reputation
    182
    Join Date
    Oct 2019
    Posts
    121
    Thanks G/R
    5/76
    Trade Feedback
    0 (0%)
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by goblin2kx View Post
    Thanks for the replies everyone (gave you all thanks!), I found CGObject_C::GetPosition and CGObject_C::GetPositionRaw. Calling CGObject_C::GetPosition now, but getting same coordinates as before ([[[entity + 0x18] + 0xB8]+0x20]). Inspecting the code inside GetPosition seems to have some additional handing for transports as opposed to GetPositionRaw. This is good, that means as you said if I call CGObject_C::GetPosition on a transport, I should be getting the absolute position correct?

    CGObject_C::GetPosition:
    X pos -2499.14
    Y pos -379.241
    Z pos -8.19711

    CGObject_C::GetPositionRaw:
    X raw pos -2499.14
    Y raw pos -379.241
    Z raw pos -8.19711

    [[[entity + 0x18] + 0xB8]+0x20]
    world x -2499.14
    world y -379.241
    world z -8.19711


    So back to original question I had, are these positions supposed to to be at the feet of model, i.e. where the model touches the terrain (when the unit is on the ground anyway)? If so sounds like I have issues with my world XYZ->screen because when I translate the position I get slight elevated screen X,Y.

    Side note to anyone who's looking for these position functions (retail 56819):
    CGObject_C::GetPosition = 0x2558B50
    CGObject_C::GetPositionRaw = 0x2559120
    The need to be called with (CGObject_C*,float*) obviously.

    Edit: I was more or less sure that the coordinates are correct, I just wanted to show that what I'm getting and what the VMT function gives are the same.
    Yes, the position is from where they touch the ground. The only time you need to do a reverse matrix and get relative coordinates is from a world coordinate that isn't on a unit (to get the relative there). And when using the HandleTerrainClick the GUID is the transports and the location relative. This causes the ground effect to attach to the transport

  18. #13
    thateuler's Avatar Active Member
    Reputation
    24
    Join Date
    May 2019
    Posts
    39
    Thanks G/R
    24/17
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by goblin2kx View Post
    So back to original question I had, are these positions supposed to to be at the feet of model, i.e. where the model touches the terrain (when the unit is on the ground anyway)? If so sounds like I have issues with my world XYZ->screen because when I translate the position I get slight elevated screen X,Y.
    Blizz has a GetScreenCoords function. Thats what I'm using. @scizzydo has a great post with more information on that. https://www.ownedcore.com/forums/wor...ml#post4419210

    I've noticed that it doesn't work quite right if I use a custom UI scale or play in windowed mode. I'm playing retail. If I read over scizzydo's post again more carefully I can probably find the reason for that ui scale/window mode glitch. A TODO item for a future time.
    Last edited by thateuler; 10-11-2024 at 04:04 PM.

  19. #14
    scizzydo's Avatar Contributor
    Reputation
    182
    Join Date
    Oct 2019
    Posts
    121
    Thanks G/R
    5/76
    Trade Feedback
    0 (0%)
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by thateuler View Post
    Blizz has a GetScreenCoords function. Thats what I'm using. @scizzydo has a great post with more information on that. https://www.ownedcore.com/forums/wor...ml#post4419210

    I've noticed that it doesn't work quite right if I use a custom UI scale or play in windowed mode. I'm playing retail. If I read over scizzydo's post again more carefully I can probably find the reason for that ui scale/window mode glitch. A TODO item for a future time.
    How are you calling it? The issue with scales usually is like the UIParent:GetScale value. That's why I called my function WorldToViewport, as it returns the screen % of the x & y. If I call it from a rendering backend (lets say imgui) then I would use something like GetClientRect for the screen size and then apply the % to. If it's in lua though, and returned the % it's important to apply the frames scale to it. Without that, it'll be off at certain resolutions/scaling

  20. #15
    goblin2kx's Avatar Member
    Reputation
    8
    Join Date
    Jun 2007
    Posts
    31
    Thanks G/R
    13/2
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by scizzydo View Post
    How are you calling it? The issue with scales usually is like the UIParent:GetScale value. That's why I called my function WorldToViewport, as it returns the screen % of the x & y. If I call it from a rendering backend (lets say imgui) then I would use something like GetClientRect for the screen size and then apply the % to. If it's in lua though, and returned the % it's important to apply the frames scale to it. Without that, it'll be off at certain resolutions/scaling
    Hmmmmmm, I just noticed I'm using GetWindowRect and not GetClientRect, I think there is something there (I mean the slightly elevated part)... Well maybe? I'll have to look into this now!

Page 1 of 3 123 LastLast

Similar Threads

  1. [Classic] [1.13.6.37497] OnSpriteLeftClick - Targeting Units
    By _chase in forum WoW Memory Editing
    Replies: 18
    Last Post: 04-21-2021, 05:47 AM
  2. Finding unit position
    By swollen in forum WoW Memory Editing
    Replies: 18
    Last Post: 04-25-2010, 04:26 PM
  3. [Paladin] Kill grounding totem w/o Target
    By Weapon in forum World of Warcraft Exploits
    Replies: 24
    Last Post: 01-14-2010, 09:27 AM
  4. Question: Target Unit By GUID in Addons, Possible?
    By zys924 in forum WoW Memory Editing
    Replies: 14
    Last Post: 12-30-2009, 12:57 PM
  5. Need way to 'target' WOW units.
    By ShoniShilent in forum WoW Memory Editing
    Replies: 12
    Last Post: 05-31-2008, 09:51 AM
All times are GMT -5. The time now is 04:10 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search