What's new
  • Visit Rebornbuddy
  • Visit Panda Profiles
  • Visit LLamamMagic
  • Visit Resources
  • Visit Downloads
  • Visit Portal

To Whoever Maintains The Wiki:

DissBeeChris

New Member
Joined
Jan 15, 2010
Messages
34
Reaction score
0
Profile Writing: Locating X-Y-Z Coordinates for Game World Entities - Buddy Wiki
The X-Y-Z coordinates used by Honorbuddy are not the same ones used by the WoW client, itself. Thus, the coordinates on WoWHead are also of no use. Even if the two coordinate systems coincided, the WoW client and WoWHead do not capture or present the 'Z' contribution.
You are wrong, the xyz coordinates that Honorbuddy uses are the same ones used by the WoW client. For example, I can convert Elwynn Forest 50,50 to -9096.8745, -200 without ever going in game. In case you don't believe me:

http://www.thebuddyforum.com/archiv...sh-questing-release-schedule-9.html#post41968
 
DissBeeChris is correct, it can take some calculating, but it's not actually all that hard to convert coordinates (even percentage-based, zone-specific coordinates) to world coordinates. Can provide code samples if it helps.
 
Thank you for the information. I've bookmarked the thread and will try to write something up when I get some free time. If you guys could scribble me the equations for:
  • Converting HB coordinates to WoWclient
  • Converting WoWclient coordinates to HB
it would sure save me a lot of time!

There is a *long* list of things to do, so it may be a while, but the ball shouldn't be dropped. :D

cheers,
CJ
 
Last edited:
its basically just a ratio. after you get the top, bottom, left, and right bounds of the map you want to convert the coordinates to, you use the map coordinate as a percentage. let's say you have a map who's left bound is 100, right bound is 200, top bound is 200, and bottom bound is 100 and the map coordinates you want to convert is 50 50. for the x value, subtract the right bound by the left bound, 200 - 100 = 100. multiply this by the coordinate as a percentage, 100 x .5 = 50. you then add this back to the left bound, so the honorbuddy x coordinate would be 150. you do the same for the y value. to get the z value, you call FindHeight with the honorbuddy api.

I have an excel spreadsheet with the area bounds for every map, which can be found in the oldworld.dbc file (our something like that), along with the formula. I could send that spreadsheet to you if you want it. I also have a basic plugin i have for personal use that converts the coordinates. if anyone is interested in this, I could fix it up for the public and release that.
 
Felt like being constructive, sooo... Here ya go! Enjoy. ;)


Code:
       /**********************
         * ZonePosToWorldPos
         * 
         * This function converts a percentage-based coordinate and
         * a zone ID into a set of world coordinates, usable by HB.
         **********************/
        WoWPoint ZonePosToWorldPos(int iZoneID, float fPosX, float fPosY)
        {
            WoWDb.DbTable dbZone = StyxWoW.Db[ClientDb.WorldMapArea];

            // Ensure the zone we're looking for is actually in the database
            if (iZoneID < dbZone.MinIndex || iZoneID > dbZone.MaxIndex)
            {
                // Nope! The user is being silly again. Make him pay for his mistake! MWAHAHAH.
                return null;
            }

            WoWDb.Row dbFields = dbZone.GetRow((uint)iZoneID);

            // Make sure the zone is actually valid...
            if (!dbFields.IsValid)
            {
                // Doh! The user almost tricked us into crashing that time. ALMOST.
                return null;
            }

            // Get the zone info from the database
            float fZoneTop = dbFields.GetField<float>(4);
            float fZoneBottom = dbFields.GetField<float>(5);
            float fZoneLeft = dbFields.GetField<float>(6);
            float fZoneRight = dbFields.GetField<float>(7);

            WoWPoint pPos = new WoWPoint();

            // Convert from percentage-based location to world coords!
            // NOTE: X and Y coords are switched when going from WoW client -> HB
            pPos.X = (fPosY * (fZoneRight - fZoneLeft)) + fZoneLeft;
            pPos.Y = (fPosX * (fZoneBottom - fZoneTop)) + fZoneTop;

            // Grab the highest level at the specified point... Note there may be other Z levels.
            Styx.Logic.Pathing.Navigator.FindHeight(pPos.X, pPos.Y, out pPos.Z);

            return pPos;
        }


        /**********************
        * WorldPosToZonePos
        * 
        * This function converts a world coordinate pair into a zone
        * ID and a set of percentage-based coordinates, usable by WoW.
        **********************/
        bool WorldPosToZonePos(float fPosX, float fPosY, out int iZoneID, out Vector2 vPos)
        {
            WoWDb.DbTable dbZone = StyxWoW.Db[ClientDb.WorldMapArea];

            // NOTE: X and Y coords are switched when going from HB -> WoW Client
            float fTempX = fPosY;
            float fTempY = fPosX;

            // Make sure we set our zone and pos to default values (0, 0)
            iZoneID = -1;
            vPos.X = 0.0f;
            vPos.Y = 0.0f;

            for (int iIndex = dbZone.MinIndex; iIndex <= dbZone.MaxIndex; iIndex++)
            {
                WoWDb.Row dbFields = dbZone.GetRow((uint)iIndex);

                if (!dbFields.IsValid)
                    continue;

                float fZoneTop = dbFields.GetField<float>(4);
                float fZoneBottom = dbFields.GetField<float>(5);
                float fZoneLeft = dbFields.GetField<float>(6);
                float fZoneRight = dbFields.GetField<float>(7);

                // Check if this is the right zone for the coordinates
                if (fZoneTop > fTempY)
                    continue;

                if (fZoneBottom < fTempY)
                    continue;

                if (fZoneLeft > fTempX)
                    continue;

                if (fZoneRight < fTempX)
                    continue;

                // Ensure this isn't some weird zero-size zone... Divide by 0 is evil.
                if (fZoneRight == fZoneLeft || fZoneBottom == fZoneTop)
                {
                    // Oh god, we're going down! ABANDON SHIP!
                    return false;
                }

                // Looks like we've found the right zone! Convert and return.
                vPos.X = (fTempX - fZoneLeft) / (fZoneRight - fZoneLeft);
                vPos.Y = (fTempY - fZoneTop) / (fZoneBottom - fZoneTop);

                iZoneID = iIndex;

                return true;
            }

            // Looks like the coords we're looking for don't exist... Too bad, so sad.
            return false;
        }
 
Last edited:
Okay, [wiki]Profile Writing: Locating X-Y-Z Coordinates for Game World Entities[/wiki] was altered as follows...

Original text said:
The X-Y-Z coordinates used by Honorbuddy are not the same ones used by the WoW client, itself. Thus, the coordinates on WoWHead are also of no use. Even if the two coordinate systems coincided, the WoW client and WoWHead do not capture or present the 'Z' contribution.

New text said:
Some Honorbuddy Profile Tags need to know the X-Y-Z coordinates of entities within the game world. For the X-Y contributions, internally the WoWclient uses 'world coordinates' obtained from tables (DBC files) that describe the eastmost, westmost, northmost, and southmost coordinate for each zone. However, what the WoWclient displays to the user is a percentage-based position within each zone with the top left corner of the map representing the origin. These percentaged-based coordinates are what is also captured in WoWHead.

It is possible to convert from 'world coordinates' to percentage-based coordinates, and vice-versa. However, doing so requires programming skills in either LUA or C# (using Honorbuddy). Describing how to do this is beyond the scope of this article. But even with such facilities, the Z coordinate is not available.

For most users, using Honorbuddy itself to obtain X-Y-Z coordinates is the most straight-forward tool for solving the problem. Those that know how to program may choose to use other techniques.

Satisfactory?

Beowulfe, if you're willing to release that chunk of lovely code under the "Creative Commons &mdash; Attribution-ShareAlike 3.0 Unported (CC-BY-SA 3.0)''" license, I'll write a separate Wiki article that tells how to do it. Just a heads up before you say 'yes'... because the Wiki is a community effort, you will receive no particular attribution. The attribution will be to the 'Buddy Wiki'.

If 'no', that's completely fine too.

cheers,
CJ
 
Beowulfe, if you're willing to release that chunk of lovely code under the "Creative Commons — Attribution-ShareAlike 3.0 Unported (CC-BY-SA 3.0)''" license, I'll write a separate Wiki article that tells how to do it. Just a heads up before you say 'yes'... because the Wiki is a community effort, you will receive no particular attribution. The attribution will be to the 'Buddy Wiki'.

If 'no', that's completely fine too.

cheers,
CJ
This has all been covered by Cowdude (and me) some time ago. See these post:
http://www.thebuddyforum.com/honorbuddy-forum/developer-forum/6223-%5Bhelper%5D-worldmapareas-how-convert-abs-coords-map-coords-0-00-1-00-a.html#post73561
http://www.thebuddyforum.com/honorb...-coords-map-coords-0-00-1-00-a.html#post73506
Note that the latter is wrong.
The relative coordinate system that Lua uses in WoW, and what WoWHead uses, looks like this:
Lua%20Coordinates.jpg

(Note that when you reach 100 you will enter a new zone and therefore get to 0 again)

Now, the coordinate system WoW uses works for entire maps and is not relative to zones. It looks like this:
WoW%20Universe%20Coordinates.jpg

That means, to go from absolute (the lower) to relative (the upper), the math is:
Code:
float width = endY - startY;
float height = endX - startX;
float relativeX = (positionY - startY) / width;
float relativeY = (position.X - startX) / height;

To go the other way:
Code:
float absoluteX = Lerp(startX, endX, relX);
float absoluteY = Lerp(startY, endY, relY);

float Lerp(float min, float max, float amount)
{
  return min + (max - min) * amount;
}
 
Last edited:
Back
Top