Elevdump
Jump to navigation
Jump to search
An elevdump is a file that contains the terrain data of the world. It can be used to backup and restore terrain. Together with the atdump (world attributes) and propdump (world property) it forms a complete backup of a world.
Elevdump structure
elevdump version 2
An elevdump file starts with a line containing the version number used by the SDK. There are currently two versions. Version 2 is used from 4.1.
Every line in a elevdump is a terrain node. The data in the line is seperated by spaces and tell things about the position of the node, the heights and textures used in the node. To understand what terrain nodes are and how terrain works, please see SDK Terrain for more information.
Below is an example line:
0 0 32 64 8 1 1 0 0
- The 1st part (0) is the X coordinate of the terrain page.
- The 2nd part (0) is the Z coordinate of the terrain page.
- The 3rd part (32) is the X coordinate of the node, relative to its page.
- The 4th part (64) is the Z coordinate of the node, relative to its page.
- The 5th part (8) is the radius of the node. (multiply this by 2 to get AW_TERRAIN_NODE_SIZE.)
- The 6th part (1) is the number of textures used in this node.
- The 7th part (1) is the number of heights used in this node. (1 means flat node.)
- The 8th part (0 0) contains first all texture numbers (in this case one zero) and thereafter all heights in cm.
Code Sniplets
Write Elevation Format
FILE* fp = NULL; static void handle_terrain_result(int rc) { if (!fp) return; if (rc == RC_SUCCESS && !aw_bool(AW_TERRAIN_COMPLETE)) { aw_terrain_next(); return; } if (rc != RC_SUCCESS) { // TODO: inform user about an error } if (fp) { fclose(fp); fp = NULL; } } static void handle_terrain_data(void) { int* heights; unsigned short* textures; unsigned int len; int node_size; int i; if (!fp) return; node_size = aw_int(AW_TERRAIN_NODE_SIZE); textures = (unsigned short*)aw_data(AW_TERRAIN_NODE_TEXTURES, &len); heights = (int*)aw_data(AW_TERRAIN_NODE_HEIGHTS, &len); fprintf(fp, "%d %d %d %d %d %d %d", aw_int(AW_TERRAIN_PAGE_X), aw_int(AW_TERRAIN_PAGE_Z), aw_int(AW_TERRAIN_NODE_X), aw_int(AW_TERRAIN_NODE_Z), node_size / 2, aw_int(AW_TERRAIN_NODE_TEXTURE_COUNT), aw_int(AW_TERRAIN_NODE_HEIGHT_COUNT)); fprintf(fp, " %d", *textures++); if (aw_int(AW_TERRAIN_NODE_TEXTURE_COUNT) > 1) { for (i = 1; i < 64; i++) fprintf(fp, " %d", *textures++); } fprintf(fp, " %d", *heights++); if (aw_int(AW_TERRAIN_NODE_HEIGHT_COUNT) > 1) { for (i = 1; i < 64; i++) fprintf(fp, " %d", *heights++); } fprintf(fp, "\n"); } void elevdump() { if (fp) { // already open return; } if (!(fp = fopen("elevdump.txt", "w"))) { // unable to open file return; } fprintf(fp, "elevdump version 2\n"); aw_callback_set(AW_CALLBACK_TERRAIN_NEXT_RESULT, handle_terrain_result); aw_event_set(AW_EVENT_TERRAIN_DATA, handle_terrain_data); aw_int_set(AW_TERRAIN_VERSION_NEEDED, 2); aw_int_set(AW_TERRAIN_PAGE_X, 0); aw_int_set(AW_TERRAIN_PAGE_Z, 0); aw_int_set(AW_TERRAIN_NODE_X, 0); aw_int_set(AW_TERRAIN_NODE_Z, 0); aw_int_set(AW_TERRAIN_NODE_SIZE, 0); aw_terrain_next(); }
Read Elevation Format
static FILE* fp = NULL; static void load_node(void) { int rc; int page_x; int page_z; int node_x; int node_z; int s; int texture_count; int height_count; int val; int i; unsigned short textures[64]; int heights[64]; if (!fp) return; rc = fscanf(fp, "%d %d %d %d %d %d %d", &page_x, &page_z, &node_x, &node_z, &s, &texture_count, &height_count); if (rc == EOF) { fclose(fp); fp = NULL; return; } if (texture_count < 0 || texture_count > 64 || height_count < 0 || height_count > 64) { fclose(fp); fp = NULL; // TODO: inform user about invalid format return; } for (i = 0; i < texture_count; i++) { fscanf(fp, "%d", &val); textures[i] = (unsigned short)val; } for (i = 0; i < height_count; i++) { fscanf(fp, "%d", &val); if (server_build() >= MIN_WORLD_BUILD_TERRAIN_V2) heights[i] = val; } aw_int_set(AW_TERRAIN_PAGE_X, page_x); aw_int_set(AW_TERRAIN_PAGE_Z, page_z); aw_int_set(AW_TERRAIN_NODE_X, node_x); aw_int_set(AW_TERRAIN_NODE_Z, node_z); aw_int_set(AW_TERRAIN_NODE_SIZE, s * 2); aw_int_set(AW_TERRAIN_NODE_TEXTURE_COUNT, texture_count); aw_int_set(AW_TERRAIN_NODE_HEIGHT_COUNT, height_count); aw_data_set(AW_TERRAIN_NODE_TEXTURES, (char*)textures, texture_count * sizeof(unsigned short)); aw_data_set(AW_TERRAIN_NODE_HEIGHTS, (char*)heights, height_count * sizeof(int)); if (rc = aw_terrain_load_node()) { fclose(fp); fp = NULL; // TODO: inform user about an error } } static void handle_node_result(int rc) { if (!fp) return; if (rc == RC_SUCCESS) load_node(); else { //TODO: inform user about an error if (fp) { fclose(fp); fp = NULL; } } } void elevload(void) { int rc; if (fp) { // already open; return; } fp = fopen("elevdump.txt", "r"); if (fscanf(fp, "elevdump version %d", &version) != 1 || version != 2) { // invalid format fclose(fp); fp = NULL; return; } aw_callback_set(AW_CALLBACK_TERRAIN_DELETE_ALL_RESULT, NULL); if (rc = aw_terrain_delete_all()) { // deleting old terrain failed fclose(fp); fp = NULL; return; } aw_callback_set(AW_CALLBACK_TERRAIN_LOAD_NODE_RESULT, handle_node_result); load_node(); }