Position Offset in Vehicles menu

Shout-Out

User Tag List

Results 1 to 11 of 11
  1. #1
    Torpedoes's Avatar ★ Elder ★ Doomsayer
    Authenticator enabled
    Reputation
    1147
    Join Date
    Sep 2013
    Posts
    956
    Thanks G/R
    148/415
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Position Offset in Vehicles

    Hi, I'm currently working on a radar and have everything implemented except for one small detail. Whenever I'm in a vehicle that changes my hotbar (e.g. noodle cart, kun lai daily quest guy, etc), the player position becomes relative to that vehicle. What are some ways to handle this. I have a theory that unit's have a GUID of the vehicle they are in so you could use that as a position, however is there an easier way? perhaps another offset I could use. I am currently using 0x838 as the unit offset. Thanks.

    EDIT: Additional Details Here! (Bug with Position & Angle in Transport)
    Last edited by Torpedoes; 03-31-2014 at 06:08 PM.

    Position Offset in Vehicles
  2. #2
    Jadd's Avatar 🐸 Premium Seller
    Reputation
    1515
    Join Date
    May 2008
    Posts
    2,433
    Thanks G/R
    81/336
    Trade Feedback
    1 (100%)
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Torpedoes View Post
    is there an easier way?
    Isn't that easy enough?

    Code:
    CVector3 CGObject_C::GetPosition() {
        // Read position.
    }
    
    CVector3 CGObject_C::GetAbsolutePosition() {
        auto localPosition = GetPosition();
        auto transportUnit = GetTransport();
    
        if (transportUnit != nullptr)
            return localPosition + transportUnit->GetAbsolutePosition();
    
        return localPosition;
    }
    Last edited by Jadd; 02-11-2014 at 12:05 AM.

  3. #3
    Master674's Avatar Elite User
    Reputation
    487
    Join Date
    May 2008
    Posts
    578
    Thanks G/R
    2/23
    Trade Feedback
    1 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Torpedoes View Post
    Hi, I'm currently working on a radar and have everything implemented except for one small detail. Whenever I'm in a vehicle that changes my hotbar (e.g. noodle cart, kun lai daily quest guy, etc), the player position becomes relative to that vehicle. What are some ways to handle this. I have a theory that unit's have a GUID of the vehicle they are in so you could use that as a position, however is there an easier way? perhaps another offset I could use. I am currently using 0x838 as the unit offset. Thanks.
    Just call the GetPosition VMT function and it will give you the absolute position. No need to do anything.

  4. #4
    Torpedoes's Avatar ★ Elder ★ Doomsayer
    Authenticator enabled
    Reputation
    1147
    Join Date
    Sep 2013
    Posts
    956
    Thanks G/R
    148/415
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Jadd View Post
    Isn't that easy enough?
    Just wanted to make sure there wasn't another offset with the absolute position pre-calculated. I managed to implement your solution though and that fixed my problem. Thanks!

    For those interested:
    Code:
    5.4.2.17688
    Unit Transport Guid (uint64) x32: 0x830
    Unit Transport Guid (uint64) x64: 0x1038
    Originally Posted by Master674 View Post
    Just call the GetPosition VMT function and it will give you the absolute position. No need to do anything.
    I assume you're discussing function hooking techniques for internal tools. My radar is fully external so I don't have that option. I did fix it though.

  5. #5
    MaiN's Avatar Elite User
    Reputation
    335
    Join Date
    Sep 2006
    Posts
    1,047
    Thanks G/R
    0/10
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Jadd View Post
    Isn't that easy enough?

    Code:
    CVector3 CGObject_C::GetPosition() {
        // Read position.
    }
    
    CVector3 CGObject_C::GetAbsolutePosition() {
        auto localPosition = GetPosition();
        auto transportUnit = GetTransport();
    
        if (transportUnit != nullptr)
            return localPosition + transportUnit->GetAbsolutePosition();
    
        return localPosition;
    }
    This is not right. You need to transform your position by the transports world matrix (which is calculated by multiplying its matrix by its transports matrix, in turn, etc.). Just adding the position will not handle rotation correctly.

    There are two vfuncs to get location; there's the GetPosition and GetRawPosition vfuncs. The first one does the matrix transform for you; the second one returns the relative location. If you need to implement them externally, reverse the functions.
    Last edited by MaiN; 02-12-2014 at 10:18 AM.
    [16:15:41] Cypher: caus the CPU is a dick
    [16:16:07] kynox: CPU is mad
    [16:16:15] Cypher: CPU is all like
    [16:16:16] Cypher: whatever, i do what i want

  6. #6
    Jadd's Avatar 🐸 Premium Seller
    Reputation
    1515
    Join Date
    May 2008
    Posts
    2,433
    Thanks G/R
    81/336
    Trade Feedback
    1 (100%)
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by MaiN View Post
    This is not right. You need to transform your position by the transports world matrix (which is calculated by multiplying its matrix by its transports matrix, in turn, etc.). Just adding the position will not handle rotation correctly.

    There are two vfuncs to get location; there's the GetPosition and GetRawPosition vfuncs. The first one does the matrix transform for you; the second one returns the relative location. If you need to implement them externally, reverse the functions.
    Ah I see. I didn't know that. I only ever took positions by invoking their functions.

  7. #7
    Torpedoes's Avatar ★ Elder ★ Doomsayer
    Authenticator enabled
    Reputation
    1147
    Join Date
    Sep 2013
    Posts
    956
    Thanks G/R
    148/415
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by MaiN View Post
    This is not right. You need to transform your position by the transports world matrix (which is calculated by multiplying its matrix by its transports matrix, in turn, etc.). Just adding the position will not handle rotation correctly.

    There are two vfuncs to get location; there's the GetPosition and GetRawPosition vfuncs. The first one does the matrix transform for you; the second one returns the relative location. If you need to implement them externally, reverse the functions.
    This post is quite helpful, sorry I missed it earlier. Anyways, I've spent the better part of the day reversing the GetPosition function, it took a while since I'm still learning but I think I'm getting somewhere. I discovered that Objects, specifically the boat, have a 4x4 transformation matrix accessible via the offsets below. Performing a Vector3 transformation using the relative positions obtained from the unit and the transformation matrix resulted in accurate results. This transformation is only relevant when boarding GameObjects; NPCs and Players seem to use the identity matrix which is ignored.

    Code:
    5.4.7.18019
    Object Transformation Matrix (Mat4x4) x32: 0x1C4
    Object Transformation Matrix (Mat4x4) x64: 0x340
    The next problem I'm running into is angles. I wanted to believe so badly that it would be as simple as adding the unit angle to the transport angle but apparently its isn't. The boat angle seems to always be zero however upon entering, the player angle jumps, sometimes up to 180 degrees as can be seen in Stormwind (debugger revealed it to be 3.1295 radians). I started to look into GetFacing, it appears to rely on GetRawFacing which I haven't looked at yet, hopefully I'll be able to figure it out tomorrow. But anyways, perhaps someone knows something which could help me, would be appreciated. Here are some function offsets which might be helpful:

    Code:
    5.4.7.18019
    39F1EF GetFacing
    >> 3E2DEA Far Jump @ 3D494D
    
    39F3ED GetPosition
    >> Far Jump @ 3D482E
    >> (essentially a memcpy)
    Last edited by Torpedoes; 04-02-2014 at 09:32 PM.

  8. #8
    Torpedoes's Avatar ★ Elder ★ Doomsayer
    Authenticator enabled
    Reputation
    1147
    Join Date
    Sep 2013
    Posts
    956
    Thanks G/R
    148/415
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Alright, back again with some promising results for the GetFacing function. It's not complete yet but I feel I'm getting close. Looking at this thread and more specifically this thread I was able to figure out what's happening behind the scenes. As mentioned previously, Objects have a transformation matrix which are used to transform relative positions into absolute positions. Something similar happens with angles.

    The GetFacing function (39F1EF) converts the given relative angle into an absolute angle using MovementGetTransportFacing (3D4923) which uses the TransportGuid passed to it to return the facing angle of the transport. It does this by retrieving the angle using GetRawFacingFromRotation (39F663) and then once again transforming it using GetFacing. As one can tell from the function names, the facing does not come from the angle offset, it actually comes from the object rotation. This rotation is split up into two parts, the first is unpacking the quaternion and the second is computing the final rotation. Let's begin with the first part. The quaternion is found at Object+108. It is packed into 8 bytes (64 bits) and can be unpacked using the function below. The second part is the computation, which is where I'm currently at. The function below is somewhat the function used by the game, except I'm still not sure what's going on.

    Code:
    Quaternion ReadPackedQuaternion (int64 packed)
    {
    	Quaternion result;
    	float a = 1 / 2097152.0f;
    	float b = 1 / 1048576.0f;
    
    	result.X = (packed <<  0 >> 42) * a;
    	result.Y = (packed << 22 >> 43) * b;
    	result.Z = (packed << 43 >> 43) * b;
    
    	float w = result.X * result.X +
    		  result.Y * result.Y +
    		  result.Z * result.Z;
    
    	result.W = abs (w-1) >= b ? sqrt (1-w) : 0;
    	return result;
    }
    Code:
    bool sub_5BC5C (float a1, float a2)
    {
    	// sub_6714EB is a really complicated function
    	return sub_6714EB (a1 - a2) < (1 / 4194304.0f);
    }
    
    float GetRawFacingFromRotation (int64 packed)
    {
    	Quaternion v = ReadPackedQuaternion (packed);
    
    	float v14 = ((v.W * v.Z) + (v.X * v.Y)) * 2.0;
    	float v3 = v.Z*v.Z + v.Y*v.Y;
    	float v13 = 1.0 - (v3 + v3);
    
    	float v4, v5;
    	if (sub_5BC5C (v13, 0.0))
    	{
    		if (v14 >= 0.0)
    			v4 = 0.5f;
    		else
    			v4 = 1.5f;
    
    		v5 = v4 * 3.1415927;
    	}
    
    	else
    	{
    		if (!sub_5BC5C (v14, 0.0))
    		{
    			float a = atan2 (v14, v13);
    			return NormalizAangle0to2pi (a);
    		}
    
    		v5 = (v13 == 0.0) ? 3.1415927 : 0;
    	}
    
    	v14 = v5; // Not sure
    	return v14;
    }
    If somebody knows what sub_5BC5C or sub_6714EB are, please let me know. But overall this isn't too bad, hopefully someone is able to verify my work though. I'll post more when I figure out the rest of this function, hopefully with some real world results too.

    Everything in this post is: 5.4.7.18019 x32.
    Last edited by Torpedoes; 04-02-2014 at 09:38 PM.

  9. #9
    Torpedoes's Avatar ★ Elder ★ Doomsayer
    Authenticator enabled
    Reputation
    1147
    Join Date
    Sep 2013
    Posts
    956
    Thanks G/R
    148/415
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Alright I'm happy to announce that I've solved the GetFacing function. Turns out that sub_5BC5C is probably just some float comparison method. In our case it's used to ensure the atan2 parameters are not zero. I hardly believe this is necessary these days since std::atan2 seems to handle zeroes just fine. Below are some functions I'm using in case anybody finds them useful. The offsets can be found in this post ([WoW] [5.4.7 18019] Release x86 Info Dump Thread). This appears to be working, however please feel free to correct any mistakes I might have made.

    Code:
    // Transforms relative positions into absolute positions using the transporter transform
    Vector3 Vector3::Transform (const Matrix& matrix, const Vector3& value)
    {
    	return Vector3
    	(
    		matrix.M11*value.X + matrix.M21*value.Y + matrix.M31*value.Z + matrix.M41,
    		matrix.M12*value.X + matrix.M22*value.Y + matrix.M32*value.Z + matrix.M42,
    		matrix.M13*value.X + matrix.M23*value.Y + matrix.M33*value.Z + matrix.M43
    	);
    }
    Code:
    // Unpacks an eight byte quaternion
    Vector4 Vector4::FromPacked (long long packed)
    {
    	static const float a = 1 / 2097152.0f;
    	static const float b = 1 / 1048576.0f;
    
    	Vector4 result;
    	result.X = (packed <<  0 >> 42) * a;
    	result.Y = (packed << 22 >> 43) * b;
    	result.Z = (packed << 43 >> 43) * b;
    
    	float w = result.X * result.X +
    		  result.Y * result.Y +
    		  result.Z * result.Z;
    
    	result.W = abs (w-1) >= b ? sqrt (1-w) : 0;
    	return result;
    }
    Code:
    // Determines an objects angle based on its rotation
    Vector4 v = Vector4::FromPacked (rotation);
    entity.Angle = atan2
    	(0 + (v.X*v.Y + v.Z*v.W) * 2.0,
    	 1 - (v.Y*v.Y + v.Z*v.Z) * 2.0);
    Last edited by Torpedoes; 04-03-2014 at 02:33 PM.

  10. #10
    Corthezz's Avatar Elite User Authenticator enabled
    Reputation
    386
    Join Date
    Nov 2011
    Posts
    325
    Thanks G/R
    191/98
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    +3 rep for sharing your final solution instead of just throwing a "close please i solved it" reply. Not seen that often those days.

  11. #11
    Torpedoes's Avatar ★ Elder ★ Doomsayer
    Authenticator enabled
    Reputation
    1147
    Join Date
    Sep 2013
    Posts
    956
    Thanks G/R
    148/415
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Corthezz View Post
    +3 rep for sharing your final solution instead of just throwing a "close please i solved it" reply. Not seen that often those days.
    Of course! I feel this solution is worth sharing. I'm not done yet though. I mentioned in another post (Bug with Position & Angle in Transport) that the in-game overlays are also inaccurate. It turns out that for some reason the camera direction gets rotated when stepping on a transport. I haven't done enough testing to know for sure but it seems to only happen when the transport is an object. To fix this simply rotate the direction around the Z axis (0, 0, 1) by TransportAngle radians and everything should work again. Here's the function in case anyone doesn't know how to do this.

    Code:
    // Rotates a 3D vector around an axis
    Vector3 Vector3::Rotate (const Vector3& axis, float angle) const
    {
    	float sinAngle = sin (-angle);
    	float cosAngle = cos (-angle);
    
    	return Cross (axis * sinAngle) +
    		(*this * cosAngle) +
    		(axis * Dot (axis * (1 - cosAngle)));
    }

Similar Threads

  1. WoW Offsets & WPE
    By RyanoAthens in forum World of Warcraft General
    Replies: 2
    Last Post: 03-11-2014, 10:15 PM
  2. [NeedHelp] GameObject Position Offset + Type Detection
    By MadCoder in forum WoW Memory Editing
    Replies: 1
    Last Post: 02-29-2012, 02:17 AM
  3. Grinding positions
    By KuRIoS in forum World of Warcraft Guides
    Replies: 5
    Last Post: 12-21-2006, 05:15 AM
  4. How do you find memory offsets in the game?
    By koalaz2004 in forum World of Warcraft General
    Replies: 0
    Last Post: 08-18-2006, 09:40 PM
  5. [Trick] WSG Safe Flag Holding Position
    By Matt in forum World of Warcraft Exploits
    Replies: 4
    Last Post: 05-10-2006, 06:17 PM
All times are GMT -5. The time now is 09:44 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search