Add minimap overlay to your bot/radar menu

User Tag List

Results 1 to 2 of 2
  1. #1
    ndrax's Avatar Active Member CoreCoins Purchaser
    Reputation
    16
    Join Date
    Jan 2010
    Posts
    6
    Thanks G/R
    3/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Add minimap overlay to your bot/radar

    I was browsing the screenshot thread and I saw lots of bots with radars that show mob positions. However I noticed most of them did not provide a minimap overlay. Below is a quick guide on how to add minimap overlays to your radar. It should would for all versions of WoW, but I've only tested it on WoW Classic, and it only covers the Azeroth and Kalimdor continents.

    Existing work and credit
    Adding a minimap overlay is nothing new, neither is building a radar. There are many existing resources, however I could not find all the necessary information in one place today, and most of the existing code fragments on ownedcore are now 404. Hence this guide.

    Most of the code below I wrote a long time ago, using this site as a reference. I cannot remember exactly what was original vs. not. I do know the following:


    Getting minimap images
    First we need to collect all of the minimap images for use in our program. The best way I know to do this is to obtain a copy of common.MPQ and common-2.MPQ from 3.3.5a WoW and extract them using WinMPQ.
    • For the 3.3.5a files, look for an existing torrent. It should not be too hard to find since many private servers use 3.3.5a.
    • For WinMPQ, it is freely available, just search for it.


    The minimap images are stored in common.MPQ under `textures\Minimap\...` path. The filenames are hashes that are not too useful. In common-2.MPQ, there is a file `textures\Minimap\md5translate.trs` that translates between the hashes and the clean filenames, for example:

    Code:
    Azeroth\map39_26.blp	02dd4ce432e93438e7ea0ca0e41ff6b4.blp
    Azeroth\map39_27.blp	e455c8b91589193dd6a9def9271ae52c.blp
    Azeroth\map39_28.blp	08fe4ea582021b905f37db3a881d6619.blp
    ...
    Once you have extracted the .blp files for Azeroth and Kalimdor using WinMPQ, you should rename the files according to the mapping in md5translate.trs. You can write a Python script or similar for this.

    Finally you will probably want to convert to PNG since it's easier to work with than blp. Try out the BLP2PNG utility, or search this site for other similar utilities.

    Translating world coordinates to tiles
    Each image is 256x256 in size. The translated filenames are of the format `mapII_JJ.blp` where II (tile_i below) and JJ (tile_j) correspond to world coordinates according to a formula:

    Code:
    const float TILE_SCALE_FACTOR = 533.5F;
    int tile_i = 32 - (int)Math.Ceiling(player_y / TILE_SCALE_FACTOR);
    int tile_j = 32 - (int)Math.Ceiling(player_x / TILE_SCALE_FACTOR);
    For your convenience, here's a function that loads the correct image and draws it to a bitmap:

    Code:
    const int TILE_HEIGHT = 256;
    private Bitmap AddContinentTile(Bitmap img, int current_continent, int i, int j, int mm_x, int mm_y)
    {
        Graphics G = Graphics.FromImage(img);
    
        try
        {
            Image Minimap;
    
            if (current_continent == 1)
            {
                Minimap = Image.FromFile("Maps\\Azeroth\\map" + i + "_" + j + ".png");
            }
            else if (current_continent == 0)
            {
                Minimap = Image.FromFile("Maps\\Kalimdor\\map" + i + "_" + j + ".png");
            }
            else
            {
                Minimap = null;
            }
    
            G.DrawImage(Minimap, mm_x, mm_y, TILE_HEIGHT, TILE_HEIGHT);
        }
        catch (Exception ex)
        {
            G.FillRectangle(new SolidBrush(Color.Black), new Rectangle(mm_x, mm_y, TILE_HEIGHT, TILE_HEIGHT));
        }
    
        G.Dispose();
    
        return img;
    }
    Putting it together
    So now it's just a matter of some careful calculations to position tiles appropriately, handle edges of tiles, and add zoom if desired.

    First let's build an image of the current tile and the 8 surrounding tiles, forming a 3x3 grid with our current tile in the middle:

    Code:
    const int MM_WIDTH = 500;  // width of your output
    const int MM_HEIGHT = 500;  // height of your output
    private Bitmap GetNearbyMinimap(float local_x, float local_y, float zoom, int current_continent)
    {
        Bitmap Minimap = new Bitmap(TILE_HEIGHT * 3, TILE_HEIGHT * 3);
        Graphics G = Graphics.FromImage(Minimap);
    
        int tile_i = 32 - (int)Math.Ceiling(local_y / TILE_SCALE_FACTOR);
        int tile_j = 32 - (int)Math.Ceiling(local_x / TILE_SCALE_FACTOR);
    
        Minimap = AddContinentTile(Minimap, current_continent, tile_i, tile_j, (int)((MM_WIDTH) / 2) - (TILE_HEIGHT / 2), (int)((MM_HEIGHT) / 2) - (TILE_HEIGHT / 2));
    
        // Add adjacent tiles
        for (int i = tile_i - 1; i <= tile_i + 1; i++)
        {
            for (int j = tile_j - 1; j <= tile_j + 1; j++)
            {
                Minimap = AddContinentTile(Minimap, current_continent, i, j, TILE_HEIGHT + (TILE_HEIGHT * (i - tile_i)), TILE_HEIGHT + (TILE_HEIGHT * (j - tile_j)));
            }
        }
    
        Bitmap ret = new Bitmap((int)(zoom * 3), (int)(zoom * 3));
        Graphics G2 = Graphics.FromImage(ret);
    
        G2.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed;
        G2.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low;
        G2.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed;
    
        G2.DrawImage(Minimap, 0, 0, zoom * 3, zoom * 3);
        return ret;
    }
    The final piece is to position the large combined minimap image so that our player is in the center:

    Code:
    private Bitmap DrawMinimapOverlay(Bitmap nearby_mm, Bitmap out, float local_x, float local_y, float zoom)
    {
        Graphics G = Graphics.FromImage(out);
    
        int tile_x = (int)(((Math.Abs(local_y) % TILE_SCALE_FACTOR) / TILE_SCALE_FACTOR) * zoom);
        int tile_y = (int)(((Math.Abs(local_x) % TILE_SCALE_FACTOR) / TILE_SCALE_FACTOR) * zoom);
    
        float draw_x = 0;
        float draw_y = 0;
    
        if (local_y <= 0 && local_x <= 0)
        {
            draw_x = ((MM_WIDTH / 2) - tile_x) - zoom;
            draw_y = ((MM_HEIGHT / 2) - tile_y) - zoom;
        }
        else if (local_y >= 0 && local_x <= 0)
        {
            draw_x = ((int)((MM_WIDTH) / 2) + (tile_x - zoom)) - zoom;
            draw_y = ((int)((MM_HEIGHT) / 2) - tile_y) - zoom;
        }
        else if (local_y <= 0 && local_x >= 0)
        {
            draw_x = ((int)((MM_WIDTH) / 2) - tile_x) - zoom;
            draw_y = ((int)((MM_HEIGHT) / 2) + (tile_y - zoom)) - zoom;
        }
        else if (local_y >= 0 && local_x >= 0)
        {
            draw_x = ((int)((MM_WIDTH) / 2) + (tile_x - zoom)) - zoom;
            draw_y = ((int)((MM_HEIGHT) / 2) + (tile_y - zoom)) - zoom;
        }
    
        G.DrawImage(nearby_mm, draw_x, draw_y);
        return nearby_mm;
    }
    That's it! You will need to find the player X, Y, and current continent yourself. There are plenty of resources on how to do that on this site. Once you have them, you can do something like this:

    Code:
    float zoom_factor = 1.0f;  // 1.0f to 5.0f are typical values, where larger is more magnified
    float zoom = (int)(TILE_HEIGHT * (float)(zoom_factor / 0.5f));
    Bitmap out = new Bitmap(MM_WIDTH, MM_HEIGHT);
    float player_x = GetPlayerX();  // you implement this
    float player_y = GetPlayerY();  // you implement this
    int current_continent = GetCurrentContinent();  // you implement this
    DrawMinimapOverlay(GetNearbyMinimap(player_x, player_y, zoom, current_continent), out, player_x, player_y, zoom);
    pb.Image = out;  // pb is a PictureBox
    pb.Update();
    You should take some time to make this more efficient by caching calls to GetNearbyMinimap() if you are going to call it in a loop.


    mm.jpg

    Add minimap overlay to your bot/radar
  2. Thanks Icesythe7, KKira, sendeos23, ChrisIsMe, Corthezz, xalcon (6 members gave Thanks to ndrax for this useful post)
  3. #2
    xalcon's Avatar Contributor ふたなり
    Authenticator enabled
    Reputation
    198
    Join Date
    Oct 2008
    Posts
    291
    Thanks G/R
    20/58
    Trade Feedback
    0 (0%)
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Thanks for sharing your work.
    Did you manage to get interior minimaps working? I only shortly looked into it, but didnt deem it necessary at that time.
    I was using the mapfiles for my first radar as well, which was the reason why I wrote the SereniaBLPLib back then. I never hosted it on Github, but it seems tomrus88 took over and even ported it to dotnet standard <3
    So, in case someone is using CASCLib (or even MPQ libraries, if you are working on older versions), you can use SereniaBLPLib to parse the blp into a System.Drawing.Bitmap at runtime.

    It seems the most current version of the lib is available on the wow-tools repo, if anyone is interested.
    GitHub - WoW-Tools/SereniaBLPLib
    "Threads should always commit suicide - they should never be murdered" - DirectX SDK

Similar Threads

  1. How to add recall locations to your server?
    By Kendra in forum World of Warcraft Emulator Servers
    Replies: 5
    Last Post: 05-06-2008, 03:32 AM
  2. [Guide] How to add starting items to your players!
    By metehan in forum WoW EMU Guides & Tutorials
    Replies: 7
    Last Post: 04-15-2008, 09:42 PM
  3. {Release} sql qurey and file to add azshara crater to your server
    By *TraPStaR* in forum WoW EMU Guides & Tutorials
    Replies: 1
    Last Post: 02-06-2008, 12:10 PM
  4. [Guide] Add Azshara Crater To Your Server
    By MathWizard in forum WoW EMU Guides & Tutorials
    Replies: 25
    Last Post: 02-06-2008, 12:07 PM
  5. [GUIDE] Add Voice Chat to your ascent server! [GUIDE]
    By Dryice in forum WoW EMU Guides & Tutorials
    Replies: 26
    Last Post: 12-09-2007, 11:29 AM
All times are GMT -5. The time now is 04:06 AM. 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