Jump to content
V3ct0r

Map glue and cut tool

Recommended Posts

Map glue and cut tool

 

logo.png

 

This tool allows you to cut square map sections from game client side .map and .obj files, as well as add fragments to existing maps, thus, combine several maps into one.

With its help, for example, you can cut out a separate island or create a unified world map with three main continents and islands.


The .map files contain all the basic information about the maps of the game world:
1) Areas of land and water;
2) ID of textures of the surface of the land;
3) IDs of regions from areaset.bin;
4) Terrain relief, heights;
5) Passable and impassable areas;
6) Combat and safe zones.


The .obj files contain a list of all inanimate objects that are present on the map (buildings, structures, trees, plants, stones, etc.).


The tool itself is not a complete program in the traditional sense, it is rather a set of programming codes, software development kit (SDK), that allows you to work with maps - the user have to independently write a program that will create the required map. The programming language is C++, and the programming environment is Visual Studio 2019 Community. Thus, basic knowledge of the C++ language is required to use this tool.

 


API


The toolkit is mainly represented by two classes, which are located in the Map.h file:
1) pkodev::MapFile – class for working with maps in the format .map;
2) pkodev::ObjFile – class for working with maps in the format .obj.

These classes have the same interface (they have the same methods for working with maps)


In addition, the pkodev::point structure is defined in the Map.h file, which describes a point with coordinates (x, y).


Since, basically, you need to edit .map and .obj files at the same time, the pkodev::MapWrapper class was defined, which encapsulates the pkodev::MapFile and pkodev::ObjFile objects within itself, and ensures that they are modified at the same time. Has the same interface as these classes.


In the process of working with maps, various errors may occur. To handle them, the pkodev::map_file_exception and pkodev::obj_file_exception classes are defined, which inherit from the std::runtime_error class.

 

MapFile::MapFile(), ObjFile::ObjFile()
Create an empty map with zero size.


MapFile(unsigned int width, unsigned int height), ObjFile:: ObjFile(unsigned int width, unsigned int height)
Create an empty map with dimensions width x height.


void MapFile::load(const std::string& path), void ObjFile::load(const std::string& path)
Load the map from a file. Throws pkodev::map_file_exception and pkodev::obj_file_exception, respectively.


void MapFile::save(const std::string& path), void ObjFile:: save (const std::string& path)
Save the map to a file. Throws pkodev::map_file_exception and pkodev: :obj_file_exception, respectively.


MapFile MapFile::cut(const point& start, const point& end), ObjFile ObjFile::cut(const point& start, const point& end)
Cut out a square section of the map. start - start coordinates (x0, y0), end - end coordinates (x1, y1). Throws pkodev::map_file_exception and pkodev::obj_file_exception, respectively.


void MapFile::glue(const point& pos, MapFile& map), void ObjFile::glue(const point& pos, ObjFile& map)
Add a square section to the map. pos - coordinates at which to place the section, map - the section to glue. Throws pkodev::map_file_exception and pkodev: :obj_file_exception, respectively.


void MapFile::del(const point& start, const point& end), void ObjFile::del(const point& start, const point& end)
Remove a square section from the map. start - start coordinates (x0, y0), end - end coordinates (x1, y1).  The section is replaced by the sea. Throws pkodev::map_file_exception and pkodev: :obj_file_exception, respectively.


void MapFile::clear(), void ObjFile::clear()
Remove the map and free memory.


Class pkodev::MapWrapper has a similar interface, but there is a difference in the load() and save() methods: the path to the file is specified without the extension.

 


Examples of usage


Cut a map section


Let's write a program that will cut the "Isle of Fortune" out of the "Deep Blue" location. Accordingly, we need to work with the files darkblue.map and darkblue.obj. Open Visual Studio 2019 Community, create a C++ console application project and add Map.h and Map.cpp files to the project, or load a ready-made project from the attached .zip.


The program algorithm will be as follows:
1) Open files darkblue.map and darkblue.obj;
2) Cut out a map section from them with coordinates x0 = 1430, y0 = 1675, x1 = 1780, y1 = 2025;
3) Save the section to the files fortune.map and fortune.obj.

 

Write the code:

#include <iostream>
#include "Map.h"

// Entry point
int main(int argc, char* argv[])
{
    try
    {
        // Create an object for simultaneous work with .map and .obj files
        pkodev::MapWrapper darkblue;

        // Load a map from "darkblue.map", "darkblue.obj" files
        darkblue.load("C:\\pkodev\\Client\\map\\darkblue");

        // Cut "Isle of Fortune" from the map
        pkodev::MapWrapper fortune = darkblue.cut({ 1430, 1675 }, { 1780, 2025 });

        // Save "Isle of Fortune" to the "fortune.map", "fortune.obj" files
        fortune.save("C:\\pkodev\\Client\\map\\fortune");
    }
    catch (const pkodev::map_file_exception& e)
    {
        std::cout << ".map file error: " << e.what() << std::endl;
        return 1;
    }
    catch (const pkodev::obj_file_exception& e)
    {
        std::cout << ".obj file error: " << e.what() << std::endl;
        return 2;
    }
    catch (...)
    {
        std::cout << "Unknown error!" << std::endl;
        return 3;
    }

    return 0
}

 

As a result, we will get a map (screenshot from YAMMI):

example_1.png

 


Glue several maps into the one map
Now let's try to glue some maps into the one map. For example, let's create an array of "Isles of Fortune" from the island we got in the previous example.


The program algorithm will be as follows:
1) Create an empty map with a size of 1024 x 1024;
2) Load "Isle of Fortune" from files fortune.map and fortune.obj;
3) Place the "Isle of Fortune" at coordinates (128, 32) on the map;
4) Place the "Isle of Fortune" at coordinates (512, 320) on the map;
5) Place the "Isle of Fortune" at coordinates (128, 576) on the map;
6) Save the map to array.map and array.obj files.


Write the code:

#include <iostream>
#include "Map.h"

// Entry point
int main(int argc, char* argv[])
{
    try
    {
        // Create an empty map 1024 x 1024
        pkodev::MapWrapper map(1024, 1024);

        // "Isle of Fortune" map
        pkodev::MapWrapper fortune;

        // Load the "Isle of Fortune" map from "fortune.map", "fortune.obj" files
        fortune.load("C:\\pkodev\\Client\\map\\fortune");

        // Adding several "Isles of Fortune" to the empty map
        map.glue({ 128, 32  }, fortune);
        map.glue({ 512, 320 }, fortune);
        map.glue({ 128, 576 }, fortune);

        // Save the map
        map.save("C:\\pkodev\\Client\\map\\array");
    }
    catch (const pkodev::map_file_exception& e)
    {
        std::cout << ".map file error: " << e.what() << std::endl;
        return 1;
    }
    catch (const pkodev::obj_file_exception& e)
    {
        std::cout << ".obj file error: " << e.what() << std::endl;
        return 2;
    }
    catch (...)
    {
        std::cout << "Unknown error!" << std::endl;
        return 3;
    }

    return 0;
}

 

As a result, we will get a map (screenshot from YAMMI):

example_2.png

 

 

Download the tool (9 KB)
 

  • Like 2

Share this post


Link to post
Share on other sites

Hello @V3ct0r, I would like to know if you could explain some method similar to the ".cut" function instead of it being rectangular, making round cuts or even uniform. as well a function to rotate a fragment to be cut

Share this post


Link to post
Share on other sites

Hello @noanshadow,

 

I'm sorry to be late with the reply.

 

Fragments of a shape other than rectangular cannot be cut, since the tool works with whole sections, not single tiles. Everything needs to be rewritten.

 

Regarding the fragment rotation, it is possible. But I ran into a misunderstanding of how to properly blend the terrain textures:

maprotate.png

 

maprotate_err1.png

 

 

maprotate_err2.png


Share this post


Link to post
Share on other sites
On 12/12/2021 at 12:45 PM, V3ct0r said:

Map glue and cut tool

 

logo.png

 

This tool allows you to cut square map sections from game client side .map and .obj files, as well as add fragments to existing maps, thus, combine several maps into one.

With its help, for example, you can cut out a separate island or create a unified world map with three main continents and islands.


The .map files contain all the basic information about the maps of the game world:
1) Areas of land and water;
2) ID of textures of the surface of the land;
3) IDs of regions from areaset.bin;
4) Terrain relief, heights;
5) Passable and impassable areas;
6) Combat and safe zones.


The .obj files contain a list of all inanimate objects that are present on the map (buildings, structures, trees, plants, stones, etc.).


The tool itself is not a complete program in the traditional sense, it is rather a set of programming codes, software development kit (SDK), that allows you to work with maps - the user have to independently write a program that will create the required map. The programming language is C++, and the programming environment is Visual Studio 2019 Community. Thus, basic knowledge of the C++ language is required to use this tool.

 


API


The toolkit is mainly represented by two classes, which are located in the Map.h file:
1) pkodev::MapFile – class for working with maps in the format .map;
2) pkodev::ObjFile – class for working with maps in the format .obj.

These classes have the same interface (they have the same methods for working with maps)


In addition, the pkodev::point structure is defined in the Map.h file, which describes a point with coordinates (x, y).


Since, basically, you need to edit .map and .obj files at the same time, the pkodev::MapWrapper class was defined, which encapsulates the pkodev::MapFile and pkodev::ObjFile objects within itself, and ensures that they are modified at the same time. Has the same interface as these classes.


In the process of working with maps, various errors may occur. To handle them, the pkodev::map_file_exception and pkodev::obj_file_exception classes are defined, which inherit from the std::runtime_error class.

 

MapFile::MapFile(), ObjFile::ObjFile()
Create an empty map with zero size.


MapFile(unsigned int width, unsigned int height), ObjFile:: ObjFile(unsigned int width, unsigned int height)
Create an empty map with dimensions width x height.


void MapFile::load(const std::string& path), void ObjFile::load(const std::string& path)
Load the map from a file. Throws pkodev::map_file_exception and pkodev::obj_file_exception, respectively.


void MapFile::save(const std::string& path), void ObjFile:: save (const std::string& path)
Save the map to a file. Throws pkodev::map_file_exception and pkodev: :obj_file_exception, respectively.


MapFile MapFile::cut(const point& start, const point& end), ObjFile ObjFile::cut(const point& start, const point& end)
Cut out a square section of the map. start - start coordinates (x0, y0), end - end coordinates (x1, y1). Throws pkodev::map_file_exception and pkodev::obj_file_exception, respectively.


void MapFile::glue(const point& pos, MapFile& map), void ObjFile::glue(const point& pos, ObjFile& map)
Add a square section to the map. pos - coordinates at which to place the section, map - the section to glue. Throws pkodev::map_file_exception and pkodev: :obj_file_exception, respectively.


void MapFile::del(const point& start, const point& end), void ObjFile::del(const point& start, const point& end)
Remove a square section from the map. start - start coordinates (x0, y0), end - end coordinates (x1, y1).  The section is replaced by the sea. Throws pkodev::map_file_exception and pkodev: :obj_file_exception, respectively.


void MapFile::clear(), void ObjFile::clear()
Remove the map and free memory.


Class pkodev::MapWrapper has a similar interface, but there is a difference in the load() and save() methods: the path to the file is specified without the extension.

 


Examples of usage


Cut a map section


Let's write a program that will cut the "Isle of Fortune" out of the "Deep Blue" location. Accordingly, we need to work with the files darkblue.map and darkblue.obj. Open Visual Studio 2019 Community, create a C++ console application project and add Map.h and Map.cpp files to the project, or load a ready-made project from the attached .zip.


The program algorithm will be as follows:
1) Open files darkblue.map and darkblue.obj;
2) Cut out a map section from them with coordinates x0 = 1430, y0 = 1675, x1 = 1780, y1 = 2025;
3) Save the section to the files fortune.map and fortune.obj.

 

Write the code:


#include <iostream>
#include "Map.h"

// Entry point
int main(int argc, char* argv[])
{
    try
    {
        // Create an object for simultaneous work with .map and .obj files
        pkodev::MapWrapper darkblue;

        // Load a map from "darkblue.map", "darkblue.obj" files
        darkblue.load("C:\\pkodev\\Client\\map\\darkblue");

        // Cut "Isle of Fortune" from the map
        pkodev::MapWrapper fortune = darkblue.cut({ 1430, 1675 }, { 1780, 2025 });

        // Save "Isle of Fortune" to the "fortune.map", "fortune.obj" files
        fortune.save("C:\\pkodev\\Client\\map\\fortune");
    }
    catch (const pkodev::map_file_exception& e)
    {
        std::cout << ".map file error: " << e.what() << std::endl;
        return 1;
    }
    catch (const pkodev::obj_file_exception& e)
    {
        std::cout << ".obj file error: " << e.what() << std::endl;
        return 2;
    }
    catch (...)
    {
        std::cout << "Unknown error!" << std::endl;
        return 3;
    }

    return 0
}

 

As a result, we will get a map (screenshot from YAMMI):

example_1.png

 


Glue several maps into the one map
Now let's try to glue some maps into the one map. For example, let's create an array of "Isles of Fortune" from the island we got in the previous example.


The program algorithm will be as follows:
1) Create an empty map with a size of 1024 x 1024;
2) Load "Isle of Fortune" from files fortune.map and fortune.obj;
3) Place the "Isle of Fortune" at coordinates (128, 32) on the map;
4) Place the "Isle of Fortune" at coordinates (512, 320) on the map;
5) Place the "Isle of Fortune" at coordinates (128, 576) on the map;
6) Save the map to array.map and array.obj files.


Write the code:


#include <iostream>
#include "Map.h"

// Entry point
int main(int argc, char* argv[])
{
    try
    {
        // Create an empty map 1024 x 1024
        pkodev::MapWrapper map(1024, 1024);

        // "Isle of Fortune" map
        pkodev::MapWrapper fortune;

        // Load the "Isle of Fortune" map from "fortune.map", "fortune.obj" files
        fortune.load("C:\\pkodev\\Client\\map\\fortune");

        // Adding several "Isles of Fortune" to the empty map
        map.glue({ 128, 32  }, fortune);
        map.glue({ 512, 320 }, fortune);
        map.glue({ 128, 576 }, fortune);

        // Save the map
        map.save("C:\\pkodev\\Client\\map\\array");
    }
    catch (const pkodev::map_file_exception& e)
    {
        std::cout << ".map file error: " << e.what() << std::endl;
        return 1;
    }
    catch (const pkodev::obj_file_exception& e)
    {
        std::cout << ".obj file error: " << e.what() << std::endl;
        return 2;
    }
    catch (...)
    {
        std::cout << "Unknown error!" << std::endl;
        return 3;
    }

    return 0;
}

 

As a result, we will get a map (screenshot from YAMMI):

example_2.png

 

 

Download the tool (9 KB)
 

Hey man, think you can create a video for us dummy on how to do it proper. It would helps many of us. Thanks.

Share this post


Link to post
Share on other sites
On 4/12/2023 at 3:28 AM, DangThao said:

Hey man, think you can create a video for us dummy on how to do it proper. It would helps many of us. Thanks.

Hello @DangThao,

 

This tool is intended for experienced users who know how to edit and compile C++ sources. Maybe I will make a version with a GUI for all users in the future.

  • Thanks 1

Share this post


Link to post
Share on other sites
On 5/14/2022 at 7:29 PM, V3ct0r said:

Hello @noanshadow,

 

I'm sorry to be late with the reply.

 

Fragments of a shape other than rectangular cannot be cut, since the tool works with whole sections, not single tiles. Everything needs to be rewritten.

 

Regarding the fragment rotation, it is possible. But I ran into a misunderstanding of how to properly blend the terrain textures:

maprotate.png

 

maprotate_err1.png

 

 

maprotate_err2.png

I ran into this problem in 3ds max.
mmm I wouldn't know how to explain it to you, but I'll try.
in the folder [Bin\texture\terrain\alpha\] there is a texture.
I think it works with the shader. poof I got off topic.
That image works with this code.
MPMap.cpp
float AlphaNo2UV[16][2] =
{
     0.0f, 0.0f,
     0.0f, 0.0f,
     0.25f, 0.0f,
     0.5f, 0.0f,
     0.75f, 0.0f,
     0.0f, 0.25f,
     0.25f, 0.25f,
     0.5f, 0.25f,
     0.75f, 0.25f,
     0.0f, 0.5f,
     0.25f, 0.5f,
     0.5f, 0.5f,
     0.75f, 0.5f,
     0.0f, 0.75f,
     0.25f, 0.75f,
     0.5f, 0.75f
};
The thing is that in 3ds max they are the UV coordinates (Texture UV) For other programs or shader.
the top map is 4048*4048 maximum and *2 if they are the Block.
and it is divided into 8*8 chunks.if you manage to flip the chunks separately. you will do it 

  • Thanks 1

Discord:Wolfen#1498

https://www.patreon.com/ReTop

Share this post


Link to post
Share on other sites

Hello @wolfenx,

 

Thanks a lot for your tip. I have an idea how to fix it, but don't know when I will be able to check it.


Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...