Register for your free account! | Forgot your password?

Go Back   elitepvpers > MMORPGs > Rappelz > Rappelz Private Server
You last visited: Today at 19:07

  • Please register to post and access all features, it's quick, easy and FREE!

 

[RELEASE](C#) PARTIAL MAP EDITOR + SOURCE

Reply
 
Old   #16
 
elite*gold: 0
Join Date: Oct 2010
Posts: 2,557
Received Thanks: 2,411
v3 Released

This morning while I waited for Shatterglass to login for a list I needed I worked on the Map Editor and have made some progress.

Notes:
  • The program now displays at the furthest level of zoom out by default
  • The programs view area has been taken down to 512 x 512 instead of 3072 x 3072 (3072x3072 now available on zoom x 6)
  • The program should now be able to open map after map instead of having to reset the program on each unique map load.
  • Zooming System rewritten and working flawlessly
  • Moving main map works flawlessly up to x5.5 zoom @ 6 something goes wrong, tried several times to figure it out maybe I just suck (Look at GUI.MINIMAP_MOUSE_DOWN)
  • Drawing mini map focus rectangle works up to x5 zoom and then bugs(Look at MAP.SET_MINIMAP_FOCUS)
  • VIEW menu has been removed
  • Load Button added below mini map
  • Map Parts (NFA, C, S etc..) are now only loaded when they are checked above the load button
  • The program now uses the /NFA/ folder to create the map list
  • NFE may be added next release if I can get some help working on the MAP.SET_MINIMAP_FOCUS and GUI.MINIMAP_MOUSE_DOWN issues solved.

SCREENSHOTS:



DOWNLOAD:

Check original post



ismokedrow is offline  
Thanks
1 User
Old   #17
 
elite*gold: 0
Join Date: Oct 2012
Posts: 14
Received Thanks: 2
Amazing , Thanks very


Amaady is offline  
Old   #18
 
elite*gold: 0
Join Date: Apr 2012
Posts: 448
Received Thanks: 766
I looked into nfm files as they contain the terrain map.
The format of terrain data is:
Code:
struct NFM_HEADER_V22
{
  char szSign[16];
  unsigned int dwVersion;
  unsigned int dwMapPropertiesOffset;
  unsigned int dwTerrainSegmentOffset;   //the offset in file to terrain data with vertex heights
  unsigned int dwPropOffset;
  unsigned int dwVectorAttrOffset;
  unsigned int dwWaterOffset;
  unsigned int dwGrassColonyOffset;
  unsigned int dwEventAreaOffset;
  int nTileCountPerSegment;
  int nSegmentCountPerMap;
  float fTileLength;
};

struct TerrainSegments
{
  NFM_SEGMENTHEADER_V11 segments[4096];  //matrix of 64x64 of NFM_SEGMENTHEADER_V11 structure
};

struct NFM_SEGMENTHEADER_V11  //information about one segment
{
  unsigned int dwVersion;
  unsigned __int16 tile[3];
  NFM_VERTEXSTRUCT_V11 vertices[36];
};

struct NFM_VERTEXSTRUCT_V11
{
  float fHeight;  //the height of the vertex
  unsigned int wFillBits[2];
  unsigned __int64 wAttribute;
  KTripleColor Color;
};
I don't know for the other fields, I think it's about the terrain ground texture (one bit per type maybe, 0 being grass)

4096 is in fact 64x64 which as the map contains a grid of 64x64 segments (which each segments contains 6x6 tiles which contains information about a vertex)

Here is an image of the data (heights of all vertices in m009_004.nfm, which is the map with horizon) (using matlab to convert matrix of float to a gray scale heightmap image, blender to create the terrain with the heightmap and a screenshot of TSP's map editor to have the texture (which is projected on the map, yes the method is bad ^^ but it was faster than merging image using another tool)
You must register and activate your account in order to view images.
glandu2 is offline  
Thanks
5 Users
Old   #19
 
elite*gold: 0
Join Date: Mar 2013
Posts: 75
Received Thanks: 5
wonderful I think near we can create new world in rappelz >>
go ahead guys >>>>>>


hassuny is offline  
Old   #20
 
elite*gold: 0
Join Date: Oct 2010
Posts: 2,557
Received Thanks: 2,411
Quote:
Originally Posted by glandu2 View Post
I looked into nfm files as they contain the terrain map.
The format of terrain data is:
Code:
struct NFM_HEADER_V22
{
  char szSign[16];
  unsigned int dwVersion;
  unsigned int dwMapPropertiesOffset;
  unsigned int dwTerrainSegmentOffset;   //the offset in file to terrain data with vertex heights
  unsigned int dwPropOffset;
  unsigned int dwVectorAttrOffset;
  unsigned int dwWaterOffset;
  unsigned int dwGrassColonyOffset;
  unsigned int dwEventAreaOffset;
  int nTileCountPerSegment;
  int nSegmentCountPerMap;
  float fTileLength;
};

struct TerrainSegments
{
  NFM_SEGMENTHEADER_V11 segments[4096];  //matrix of 64x64 of NFM_SEGMENTHEADER_V11 structure
};

struct NFM_SEGMENTHEADER_V11  //information about one segment
{
  unsigned int dwVersion;
  unsigned __int16 tile[3];
  NFM_VERTEXSTRUCT_V11 vertices[36];
};

struct NFM_VERTEXSTRUCT_V11
{
  float fHeight;  //the height of the vertex
  unsigned int wFillBits[2];
  unsigned __int64 wAttribute;
  KTripleColor Color;
};
I don't know for the other fields, I think it's about the terrain ground texture (one bit per type maybe, 0 being grass)

4096 is in fact 64x64 which as the map contains a grid of 64x64 segments (which each segments contains 6x6 tiles which contains information about a vertex)

Here is an image of the data (heights of all vertices in m009_004.nfm, which is the map with horizon) (using matlab to convert matrix of float to a gray scale heightmap image, blender to create the terrain with the heightmap and a screenshot of TSP's map editor to have the texture (which is projected on the map, yes the method is bad ^^ but it was faster than merging image using another tool)
You must register and activate your account in order to view images.
Due to the attention this thing is attracting I will add NFE tonight or tomorrow and get a more polished version of the editor out and ready for use. If anyone could help me out with the things I mentioned in the last post like SET_MINIMAP_FOCUS (Draws weird at x5.5+ zoom) and why MINIMAP_MOUSE_DOWN has problems moving the map @ x6 ZOOM that would be greatly appreciated.

THAT IMAGE IS SO BOSS @ Glandu2 and thanks for the NFM info, you think I should write an info reader into the program for NFM (would anyone be willing to tackle drawing the raw data into a 3d model inside of the program or would it be better to just convert NFM to blender?)
ismokedrow is offline  
Thanks
1 User
Old   #21
 
elite*gold: 0
Join Date: Apr 2012
Posts: 448
Received Thanks: 766
Quote:
Originally Posted by ismokedrow View Post
Due to the attention this thing is attracting I will add NFE tonight or tomorrow and get a more polished version of the editor out and ready for use. If anyone could help me out with the things I mentioned in the last post like SET_MINIMAP_FOCUS (Draws weird at x5.5+ zoom) and why MINIMAP_MOUSE_DOWN has problems moving the map @ x6 ZOOM that would be greatly appreciated.

THAT IMAGE IS SO BOSS @ Glandu2 and thanks for the NFM info, you think I should write an info reader into the program for NFM (would anyone be willing to tackle drawing the raw data into a 3d model inside of the program or would it be better to just convert NFM to blender?)
I think using blender would be better, as the 3D stuff is already done by blender. But loading a map is somewhat heavy as there are 5 308 416 vertex ... so some operations can take time to complete on some computers. The most interesting thing of blender is the possibility to edit the map (and the import of the terrain data should be much easier than btrf files, but I still don't know how the terrain texture is computed, which is mandatory to be able to write a correct terrain (or else it would be full of grass I think))

But maybe other tools exists especially made for terrain editing and that support many vertex better than blender, but its plugin architecture allow to do pretty much everything someone want.
glandu2 is offline  
Thanks
1 User
Old   #22
 
elite*gold: 0
Join Date: Oct 2010
Posts: 2,557
Received Thanks: 2,411
Quote:
Originally Posted by glandu2 View Post
I think using blender would be better, as the 3D stuff is already done by blender. But loading a map is somewhat heavy as there are 5 308 416 vertex ... so some operations can take time to complete on some computers. The most interesting thing of blender is the possibility to edit the map (and the import of the terrain data should be much easier than btrf files, but I still don't know how the terrain texture is computed, which is mandatory to be able to write a correct terrain (or else it would be full of grass I think))

But maybe other tools exists especially made for terrain editing and that support many vertex better than blender, but its plugin architecture allow to do pretty much everything someone want.
I know that NFM calls to TerrainTextureInfo.cfg


And I am pretty sure terrainseamlessworld.cfg places the maps in a manner that walking from one to another feels natural (so the map from horizon leads on to the horizon west map when exiting it from the west etc..

ismokedrow is offline  
Thanks
1 User
Old   #23
 
elite*gold: 26
Join Date: Dec 2012
Posts: 19
Received Thanks: 51
Quote:
Originally Posted by glandu2 View Post
I think using blender would be better, as the 3D stuff is already done by blender. But loading a map is somewhat heavy as there are 5 308 416 vertex ... so some operations can take time to complete on some computers. The most interesting thing of blender is the possibility to edit the map (and the import of the terrain data should be much easier than btrf files, but I still don't know how the terrain texture is computed, which is mandatory to be able to write a correct terrain (or else it would be full of grass I think))

But maybe other tools exists especially made for terrain editing and that support many vertex better than blender, but its plugin architecture allow to do pretty much everything someone want.
I strip off my piece of code that should help, I have not figured out how summed DDS
Code:
                dataGridView13.Columns.Add("Column Name", "№");
                dataGridView13.Columns.Add("Column Name", "TextureDefault");
                dataGridView13.Columns.Add("Column Name", "TextureColor1");
                dataGridView13.Columns.Add("Column Name", "TextureColor2");

                dataGridView15.Columns.Add("Column Name", "№");
                dataGridView15.Columns.Add("Column Name", "Z");
                dataGridView15.Columns.Add("Column Name", "Color1_line1");
                dataGridView15.Columns.Add("Column Name", "Color1_line2");
                dataGridView15.Columns.Add("Column Name", "Color1_line3");
                dataGridView15.Columns.Add("Column Name", "Color1_line4");
                dataGridView15.Columns.Add("Column Name", "Color2_line1");
                dataGridView15.Columns.Add("Column Name", "Color2_line2");
                dataGridView15.Columns.Add("Column Name", "Color2_line3");
                dataGridView15.Columns.Add("Column Name", "Color2_line4");
                dataGridView15.Columns.Add("Column Name", "Vertex №");
Code:
////////////////////////Start Read Terrein//////////////////////////////
                            int v1 = -2309;
                            int v2 = -1924;
                            int v3 = -1539;
                            int v4 = -1154;
                            int v5 = -769;
                            int v6 = -384;
                            int o = 0;
                            for (int i = 0; i < (Convert.ToInt32(label51.Text) - Convert.ToInt32(label52.Text)) / 838; i++)
                            {
                                h += 1;
                            dataGridView13.Rows.Add();
                            this.dataGridView13.Rows[s].Cells[0].Value = h; //№
                            br.ReadUInt16();// open (0) | save (0)
                            br.ReadUInt16();// open (0) | save (0)
                            this.dataGridView13.Rows[s].Cells[1].Value = br.ReadUInt16();//=TerrainTextureInfo.cfg
                            this.dataGridView13.Rows[s].Cells[2].Value = br.ReadUInt16();//=TerrainTextureInfo.cfg
                            this.dataGridView13.Rows[s].Cells[3].Value = br.ReadUInt16();//=TerrainTextureInfo.cfg
                                if (i == 0)
                                {
                                    v1 += 2310;
                                    v2 += 2310;
                                    v3 += 2310;
                                    v4 += 2310;
                                    v5 += 2310;
                                    v6 += 2310;
                                    o+=64;
                                }
                                if (i == o)
                                {
                                    v1 += 1926;
                                    v2 += 1926;
                                    v3 += 1926;
                                    v4 += 1926;
                                    v5 += 1926;
                                    v6 += 1926;
                                    o += 64;
                                }
                                for (int j = 0; j < 36; j++)
                                {
                        dataGridView15.Rows.Add();
                        this.dataGridView15.Rows[g].Cells[0].Value = h;
                        this.dataGridView15.Rows[g].Cells[1].Value = br.ReadSingle();//Z
                        this.dataGridView15.Rows[g].Cells[2].Value = br.ReadByte();// open (0 - 255)
                        this.dataGridView15.Rows[g].Cells[3].Value = br.ReadByte();// open (0 - 255)
                        this.dataGridView15.Rows[g].Cells[4].Value = br.ReadByte();// open (0 - 255)
                        this.dataGridView15.Rows[g].Cells[5].Value = br.ReadByte();// open (0 - 255)
                        this.dataGridView15.Rows[g].Cells[6].Value = br.ReadByte();// open (0 - 255)
                        this.dataGridView15.Rows[g].Cells[7].Value = br.ReadByte();// open (0 - 255)
                        this.dataGridView15.Rows[g].Cells[8].Value = br.ReadByte();// open (0 - 255)
                        this.dataGridView15.Rows[g].Cells[9].Value = br.ReadByte();// open (0 - 255)
                        br.ReadByte();// open (0 - 255) | save (0)
                        br.ReadByte();// open (0 - 255) | save (0)
                        br.ReadByte();// open (0 - 255) | save (0)
                        br.ReadByte();// open (0 - 255) | save (0)
                        br.ReadByte();// open (0 - 255) | save (0)
                        br.ReadByte();// open (0 - 255) | save (0)
                        br.ReadByte();// open (0 - 255) | save (0)
                        br.ReadByte();// open (0 - 255) | save (0)
                        br.ReadByte();// open (0 - 255) | save (0)
                        br.ReadByte();// open (0 - 255) | save (0)
                        br.ReadByte();// open (0 - 255) | save (0)
                        if (j < 6)// 0 1 2 3 4 5
                        {
                            this.dataGridView15.Rows[g].Cells[10].Value = v1;
                            v1 += 1;
                        }
                        if (j > 5 && j < 12)// 6 7 8 9 10 11
                        {
                            this.dataGridView15.Rows[g].Cells[10].Value = v2;
                            v2 += 1;
                        }
                        if (j > 11 && j < 18)// 12 13 14 15 16 17
                        {
                            this.dataGridView15.Rows[g].Cells[10].Value = v3;
                            v3 += 1;
                        }
                        if (j > 17 && j < 24)// 18 19 20 21 22 23
                        {
                            this.dataGridView15.Rows[g].Cells[10].Value = v4;
                            v4 += 1;
                        }
                        if (j > 23 && j < 30)// 24 25 26 27 28 29
                        {
                            this.dataGridView15.Rows[g].Cells[10].Value = v5;
                            v5 += 1;
                        }
                        if (j > 29 && j < 36)// 30 31 32 33 34 35
                        {
                            this.dataGridView15.Rows[g].Cells[10].Value = v6;
                            v6 += 1;
                        }
                                    g += 1;
                                }
                                s += 1;
                            }
////////////////////////End Read Terrein//////////////////////////////
Attached Images
File Type: jpg DwaddYP.jpg (14.2 KB, 203 views)
[Xsanadu]Dream is offline  
Thanks
2 Users
Old   #24
 
elite*gold: 0
Join Date: Apr 2012
Posts: 448
Received Thanks: 766
What bytes have you modified to change the map ? Your code is only the loading part ?
glandu2 is offline  
Old   #25
 
elite*gold: 26
Join Date: Dec 2012
Posts: 19
Received Thanks: 51
Quote:
Originally Posted by glandu2 View Post
What bytes have you modified to change the map ? Your is only the loading part ?
I have changed only the peaks of Z points and kept them back, then the problem arose with Vertex №, but as seen in the source I numbered all Vertex. Yes it is a piece of code to read Terrain. I've been thinking how to assemble these dds one each square or a paint overlay dds, but never came to the conclusion in terms of that COLLADA is unrealistic hard to implement. If you have any ideas tell me ...

Sorry for the translator...

glandu2, Please add me on Skype, I would like something to ask you, and help...
[Xsanadu]Dream is offline  
Old   #26
 
elite*gold: 0
Join Date: Oct 2010
Posts: 2,557
Received Thanks: 2,411
Add me to skype as-well at glandu, I'd love to have your contact just incase I need to speak with you, same goes for you dream.
ismokedrow is offline  
Old   #27
 
elite*gold: 0
Join Date: Apr 2012
Posts: 448
Received Thanks: 766
[Xsanadu]Dream, I was asking what you have changed in the nfm file to change the texture, as in your screenshot you changed the texture of a small square from grass to something else
glandu2 is offline  
Old   #28
 
elite*gold: 26
Join Date: Dec 2012
Posts: 19
Received Thanks: 51
Quote:
Originally Posted by glandu2 View Post
[Xsanadu]Dream, I was asking what you have changed in the nfm file to change the texture, as in your screenshot you changed the texture of a small square from grass to something else
Take the square see when you open such data

Code:
TextureDefault = 0 (TEXTURE=0,)
TextureColor1 = 21104 (TEXTURE=21104,)
TextureColor2 = 21105 (TEXTURE=21105,)

Color1_line1 = 255
Color1_line2 = 0
Color1_line3 = 255
Color1_line4 = 0

Color2_line1 = 0
Color2_line2 = 255
Color2_line3 = 0
Color2_line4 = 255
And get this result

From 0 to 255 the number of shading changing how I do not know
Attached Images
File Type: jpg DwaddYP.jpg (14.2 KB, 169 views)
[Xsanadu]Dream is offline  
Thanks
1 User
Old   #29
 
elite*gold: 0
Join Date: Apr 2012
Posts: 448
Received Thanks: 766
Ok, so
unsigned __int16 tile[3]; is the 3 textures ID for a segment (with 6x6 tiles inside)
and unsigned int wFillBits[2]; the data about which texture to apply on a tile

wFillBits[0] is the mask of the the second texture and wFillBits[1] the mask of the third texture, if neither of them are shown, the first texture is used.

A mask is 32 bits wide, with 2 bits per texture 'unit', there are a grid of 4x4 texture 'units' in a tile, and for each of these grid cells, we choose which texture to use with masks

0 don't use the texture and the maximum 3 use the texture with no transparency

So in binary:
Code:
ooppqqrr
kkllmmnn
eeffgghh
aabbccdd
with one byte per line, so aa is two bit masking the first part of the tile at the bottom right (aabbccdd is the first byte in the file)

This mask:

00000000 //msb
00000000
00001100
00000000 //lsb

Would be 0x00 0x0C 0x00 0x00 in the file.
But images is maybe better to explain maps:

A map file contains a grid of 64 x 64 segments:
You must register and activate your account in order to view images.

Error in this screen, East direction is X and north is Y direction. A game map is 16128 game units wide (so map size is 16128x16128. 16128 = 64*6*42, tiles dimensions are 42x42 in game units)

A segment contains 6x6 tiles and can have at most 3 textures (and tiles use them with a mask):
You must register and activate your account in order to view images.

A tile contains 4x4 positions for texture masking (aka texture splatting) (the camera is watching the south)
You must register and activate your account in order to view images.

So east is X and north is Y and data is serialized with continuous X data

There is an error in the last screen, it's not 0x000C0000 but rather 0x00 0x0C 0x00 0x00 (which is in little endian 0x00000C00) with 0x0C the second byte

Blender support texture splatting but for a whole object, so we would need to split the map with segments as blender objects with extra vertex to have a continuous terrain (as here is no face between two blender objects) and for texture we need to associate the 3 used texture of a segment to the material of the corresponding object, with stencil texture for the masks. But blender is not meant to render and edit terrain ... so vertex can be not only moved along Z, but deformed to have something non representable as a terrain (like making holes in the terrain), so the terrain can be easily screwed up.

Textures are zoomed by DETAIL field in TerrainTextureInfo.cfg (ie, DETAIL=2 makes the texture to be on 4 tiles, 2 times wide on each direction, 1 makes the texture on one tile only, 6 makes the texture on the full segment. So DETAIL is the width and height (always a square) of the texture in tile count) The texture has it's Y inverted, the top of the texture is toward Y=0 and the bottom toward Y = +infinity (the left and right does not change, left of texture is still left of the map: west and right of texture is east)

The exact texture point center seems to be the center of a grid cell instead of an intersection (ie the grass in the last image is centered on 1,5 (with values in [0;4[). So if you go with the client on a small circle of texture, takes the coords of where you are, then mod them with 42 (tile size) and it should be either 5, 16, 26 or 37
glandu2 is offline  
Thanks
6 Users
Old   #30
 
elite*gold: 0
Join Date: Oct 2010
Posts: 2,557
Received Thanks: 2,411
Wow, just wow @ Glandu. I can understand what you're saying, but as I suxors at math/vertex and drawing images in general it's almost over my head. THANK you so much guys for the information you're laying down here (I almost have NFE integrated, been hectic in my personal life)

Just again, thanks to you both for all the information you're putting in this topic, before long the dream of a creating new maps or significantly altering existing ones is in all of our reach!


ismokedrow is offline  
Reply



« Previous Thread | Next Thread »

Similar Threads
[Release] Source von Localclient/Object Editor,..
Kurze Vorgeschichte: Nachdem der Localclient von passy nub relativ viel genutzt wurde und er nach einigen obszönen Posts den Localclienten...
9 Replies - Metin2 PServer Guides & Strategies
[RELEASE+SOURCE] C# QPF Editor
http://puu.sh/3YG5q.png p.s. Sorry for crazy theme, I use Windows High Contrast Theme :D I would like to release a simple tool to any developer...
17 Replies - Rappelz Private Server
[OPEN SOURCE RELEASE] ACRE - Advanced Client Resource Editor
http://i.imgur.com/GH6P5In.png ACRE Concept: iSmokeDrow ACRE Founder: xXExiledXx ACRE Primary Coder:xXExiledXx ACRE Secondary Coder: iSmokeDrow...
28 Replies - Rappelz Private Server



All times are GMT +2. The time now is 19:07.


Powered by vBulletin®
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.

Support | Contact Us | FAQ | Advertising | Privacy Policy
Copyright ©2017 elitepvpers All Rights Reserved.