Sponge Schematic import
This commit is contained in:
parent
b30c551334
commit
c19ac61e8c
@ -21,7 +21,7 @@ for more details.
|
||||
<img src="https://gitlab.com/bztsrc/mtsedit/raw/master/docs/mtsedit.png">
|
||||
|
||||
The User Interface is translatable. Supported languages: English, Magyar, Español, Français, Deutch, Polski, Русский, Português
|
||||
and Italiana.
|
||||
and Italiano.
|
||||
|
||||
The other component is a Minetest mod, under the [mt-mod](https://gitlab.com/bztsrc/mtsedit/tree/master/mt-mod) directory. This
|
||||
small Lua script runs inside the game, and can import your edited MTS files into the game's world. It can also save MTS files
|
||||
|
1330
data/blocks.csv
1330
data/blocks.csv
File diff suppressed because it is too large
Load Diff
@ -66,7 +66,7 @@ You can also convert MTS files using different block type mappings:
|
||||
./mtsedit -m "Minetest Game" mcl2.mts mtg.mts
|
||||
```
|
||||
Where the parameter to "-m" is a coloumn name in [blocks.csv](https://gitlab.com/bztsrc/mtsedit/blob/master/docs/blocks.md) file,
|
||||
from the 5th coloumn and upwards. You can also use numbers, starting from 1 (which means the 5th coloumn, as the first four are
|
||||
from the 6th coloumn and upwards. You can also use numbers, starting from 1 (which means the 6th coloumn, as the first five are
|
||||
reserved for special use).
|
||||
```
|
||||
./mtsedit -m 1 mtg.mts mcl2.mts
|
||||
|
@ -26,7 +26,7 @@ from within the game (with all your desired mods enabled).
|
||||
|
||||
### Header
|
||||
|
||||
The first row is special, it defines the coloumn names. The first 4 coloumns are irrelevant and not parsed, others
|
||||
The first row is special, it defines the coloumn names. The first 5 coloumns are irrelevant and not parsed, others
|
||||
define the name of the block mappings (each coloumn is one mapping). These are the names used by the "/mtsedit export"
|
||||
chat command, and they are also shown on the Save As window.
|
||||
|
||||
@ -36,9 +36,10 @@ chat command, and they are also shown on the Save As window.
|
||||
|-------:|---------|---------------------------------------------------------------------------------------|
|
||||
| 1st | string | block id, canonical name of the block (also used to identify block images) |
|
||||
| 2nd | intlist | list of slash '/' separated integer numbers, the Minecraft BlockID in schematic files |
|
||||
| 3rd | string | an optional biome specific name for the block (like "biome:node_stone") |
|
||||
| 4th | string | an optional mapgen alias name for the block (like "mapgen_stone") |
|
||||
| 5th+ | string | block's name in the mapping (this coloumn may be repated as many times as you like) |
|
||||
| 3rd | string | list of slash '/' spearated strings, the Sponge BlockName in schematic files |
|
||||
| 4th | string | an optional biome specific name for the block (like "biome:node_stone") |
|
||||
| 5th | string | an optional mapgen alias name for the block (like "mapgen_stone") |
|
||||
| 6th+ | string | block's name in the mapping (this coloumn may be repated as many times as you like) |
|
||||
|
||||
Block mappings are sometimes referenced as node palette. The repository ships a default blocks.csv with two coloumns,
|
||||
mappings for "Mineclone2" and "Minetest Game", but feel free to add as many more mappings as you wish.
|
||||
@ -46,6 +47,15 @@ mappings for "Mineclone2" and "Minetest Game", but feel free to add as many more
|
||||
For file formats that rely on numeric IDs, the values in the 2nd coloumn are used. These can be however overriden on a
|
||||
per schematic file basis using the `-r` flag.
|
||||
|
||||
An example line (with Mineclone2 in 6th and MineTest Game in 7th coloumn) would look like this:
|
||||
```
|
||||
Stone,1,minecraft:stone,biome:node_stone,mapgen_stone,mcl_core:stone,default:stone
|
||||
```
|
||||
The 2nd and 3rd coloumns may have more values, like
|
||||
```
|
||||
Leaves,18,minecraft:leaves/minecraft:oak_leaves,,,mcl_core:leaves,default:leaves
|
||||
```
|
||||
|
||||
Block Images
|
||||
------------
|
||||
|
||||
|
@ -24,11 +24,20 @@ Minecraft Schematic Files
|
||||
-------------------------
|
||||
|
||||
These are [Minecraft NBT](https://minecraft.gamepedia.com/Schematic_file_format) files, used by many Minecraft-compatible
|
||||
editors. Typical extension is `.schematic`. Only the [blocks](https://minecraft.gamepedia.com/Java_Edition_data_values/Pre-flattening/Block_IDs)
|
||||
section is parsed, and only used to import schematics. MTSEdit does not save .schematic files.
|
||||
editors. Typical extension is `.schematic`. Only the [Blocks](https://minecraft.gamepedia.com/Java_Edition_data_values/Pre-flattening/Block_IDs)
|
||||
and Data chunks are parsed, and only used to import schematics. MTSEdit does not save .schematic files.
|
||||
|
||||
Limitations: rotation info are not imported properly, but works for basic nodes most of the time.
|
||||
|
||||
Sponge Schematic Files
|
||||
----------------------
|
||||
|
||||
These are [Minecraft NBT](https://minecraft.gamepedia.com/Schematic_file_format) files too, used by WorldEdit. Typical extension
|
||||
is `.schematic` too. Instead of Blocks and Data chunks, these have [BlockData](https://github.com/SpongePowered/Schematic-Specification/blob/master/versions/schematic-2.md)
|
||||
and Palette chunks. Although BlockData is a byte array, it contains bigger than 255 values using some messed up "varint" encoding.
|
||||
|
||||
Limitations: rotation info are not imported at all.
|
||||
|
||||
Model 3D Files
|
||||
--------------
|
||||
|
||||
|
@ -28,7 +28,7 @@ environment variable, or add `-l` to command line (useful in .desktop and .lnk f
|
||||
- "pl" Polski
|
||||
- "ru" Русский
|
||||
- "pt" Português
|
||||
- "it" Italiana
|
||||
- "it" Italiano
|
||||
|
||||
```
|
||||
LANG=hu ./mtsedit monkeyisland.mts
|
||||
|
@ -136,7 +136,7 @@ function mtsedit.export(param)
|
||||
end
|
||||
|
||||
local fn = minetest.get_worldpath() .. "/blocks.csv"
|
||||
local defpalettes = { "_Name", "BlockID", "Biome Specific", "MapGen Alias", param }
|
||||
local defpalettes = { "_Name", "BlockID", "BlockName", "Biome Specific", "MapGen Alias", param }
|
||||
local palettes, nodes, known, s = {}, {}, {}, {}
|
||||
local line, node, i, cnt, idx = 0, "", 0, 1, 0
|
||||
|
||||
@ -151,7 +151,7 @@ function mtsedit.export(param)
|
||||
palettes = defpalettes
|
||||
end
|
||||
end
|
||||
for i,t in ipairs(palettes) do if (cnt > 4 and t == param) then idx = i end cnt = cnt + 1 end
|
||||
for i,t in ipairs(palettes) do if (cnt > 5 and t == param) then idx = i end cnt = cnt + 1 end
|
||||
if (idx == 0) then
|
||||
table.insert(palettes, param)
|
||||
idx = cnt
|
||||
@ -181,34 +181,34 @@ function mtsedit.export(param)
|
||||
if (blockid ~= nil and blockid ~= "") then
|
||||
-- if new node
|
||||
if (nodes[blockid] == nil) then
|
||||
i = 4
|
||||
nodes[blockid] = { "", "", "" }
|
||||
i = 5
|
||||
nodes[blockid] = { "", "", "", "" }
|
||||
while (i < cnt) do table.insert(nodes[blockid], node) i = i + 1 end
|
||||
end
|
||||
-- if no biome specific name given already check if there's one
|
||||
if (node ~= "air" and node ~= "ignore" and t["drawtype"] ~= "airlike" and
|
||||
(nodes[blockid][2] == nil or nodes[blockid][2] == "")) then
|
||||
(nodes[blockid][3] == nil or nodes[blockid][3] == "")) then
|
||||
for name,biome in pairs(minetest.registered_biomes) do
|
||||
for propname,propval in pairs(biome) do
|
||||
if (string.sub(propname,1,5) == "node_" and propval == node) then
|
||||
nodes[blockid][2] = "biome:"..propname
|
||||
nodes[blockid][3] = "biome:"..propname
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- mapgen specific name
|
||||
if (nodes[blockid][3] == nil) then nodes[blockid][3] = "" end
|
||||
if (nodes[blockid][3] == "") then
|
||||
if (nodes[blockid][4] == nil) then nodes[blockid][4] = "" end
|
||||
if (nodes[blockid][4] == "") then
|
||||
for mapgen,oname in pairs(minetest.registered_aliases) do
|
||||
if (oname == node) then
|
||||
nodes[blockid][3] = mapgen
|
||||
nodes[blockid][4] = mapgen
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
-- replace block names
|
||||
i = 4
|
||||
i = 5
|
||||
while (i < cnt) do
|
||||
if (i == idx or nodes[blockid][i] == nil or nodes[blockid][i] == "") then nodes[blockid][i] = node end
|
||||
i = i + 1
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
22
src/blocks.c
22
src/blocks.c
@ -191,11 +191,11 @@ void blocks_parse()
|
||||
}
|
||||
|
||||
/* parse header */
|
||||
for(e = data, i = j = 0; *e && *e != '\r' && *e != '\n' && i < 4; e++) {
|
||||
for(e = data, i = j = 0; *e && *e != '\r' && *e != '\n' && i < 5; e++) {
|
||||
if(*e == '\"') j ^= 1;
|
||||
if(!j && (*e == ',' || *e == ';' || *e == '\t')) i++;
|
||||
}
|
||||
if(i != 4 || !*e || *e == '\r' || *e == '\n') errorcsv(1);
|
||||
if(i != 5 || !*e || *e == '\r' || *e == '\n') errorcsv(1);
|
||||
while(*e && *e != '\r' && *e != '\n') {
|
||||
while(*e == ',' || *e == ';' || *e == '\t' || *e == ' ') e++;
|
||||
if(*e == '\"') { e++; c = '\"'; } else c = ',';
|
||||
@ -224,12 +224,14 @@ void blocks_parse()
|
||||
blocks[0].name = (char*)malloc(strlen(t)+1);
|
||||
if(!blocks[0].name) error(lang[ERR_MEM]);
|
||||
strcpy(blocks[0].name, t);
|
||||
blocks[0].blocknames = (char**)malloc((numpalettes + 2) * sizeof(char*));
|
||||
blocks[0].blocknames = (char**)malloc((numpalettes + 3) * sizeof(char*));
|
||||
if(!blocks[0].blocknames) error(lang[ERR_MEM]);
|
||||
blocks[0].blocknames[0] = NULL;
|
||||
for(i = 1; i < (unsigned int)numpalettes + 2; i++) {
|
||||
blocks[0].blocknames[i] = (char*)malloc(4);
|
||||
for(i = 0; i < (unsigned int)numpalettes + 3; i++) {
|
||||
blocks[0].blocknames[i] = (char*)malloc(!i ? 33 : 4);
|
||||
if(!blocks[0].blocknames[i]) error(lang[ERR_MEM]);
|
||||
if(!i)
|
||||
memcpy(blocks[0].blocknames[i], "minecraft:air/minecraft:cave_air", 33);
|
||||
else
|
||||
memcpy(blocks[0].blocknames[i], "air", 4);
|
||||
}
|
||||
for(i = 0; i < numbids; i++)
|
||||
@ -250,9 +252,9 @@ void blocks_parse()
|
||||
blocks = (mtsblock_t*)realloc(blocks, numblocks * sizeof(mtsblock_t));
|
||||
if(!blocks) error(lang[ERR_MEM]);
|
||||
memset(&blocks[j], 0, sizeof(mtsblock_t));
|
||||
blocks[j].blocknames = (char**)malloc((numpalettes + 2) * sizeof(char*));
|
||||
blocks[j].blocknames = (char**)malloc((numpalettes + 3) * sizeof(char*));
|
||||
if(!blocks[j].blocknames) error(lang[ERR_MEM]);
|
||||
memset(blocks[j].blocknames, 0, (numpalettes + 2) * sizeof(char*));
|
||||
memset(blocks[j].blocknames, 0, (numpalettes + 3) * sizeof(char*));
|
||||
for(k = 0; s + k < e; k++)
|
||||
if(s[k] == ' ' || s[k] == '\'') s[k] = '_';
|
||||
/* translate block name */
|
||||
@ -366,7 +368,7 @@ void blocks_parse()
|
||||
memcpy(blocks[j].blocknames[k], s, e - s + 1);
|
||||
blocks[j].blocknames[k][e - s] = 0;
|
||||
}
|
||||
k++; if(k > (unsigned int)numpalettes + 2) errorcsv(j+2);
|
||||
k++; if(k > (unsigned int)numpalettes + 3) errorcsv(j+2);
|
||||
while(*e && *e != ',' && *e != ';' && *e != '\t' && *e != '\r' && *e != '\n') e++;
|
||||
}
|
||||
if(!numblocks || numblocks > 65535) error(lang[ERR_CSV]);
|
||||
@ -399,7 +401,7 @@ void blocks_free()
|
||||
for(i = 0; i < numblocks; i++) {
|
||||
free(blocks[i].name);
|
||||
if(blocks[i].blocknames) {
|
||||
for(j = 0; j < numpalettes + 2; j++)
|
||||
for(j = 0; j < numpalettes + 3; j++)
|
||||
if(blocks[i].blocknames[j]) free(blocks[i].blocknames[j]);
|
||||
free(blocks[i].blocknames);
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ typedef struct {
|
||||
char numpar2;
|
||||
char dobiome;
|
||||
uint32_t color;
|
||||
unsigned char blockids[4];
|
||||
unsigned short blockids[4];
|
||||
unsigned char *img;
|
||||
unsigned char *dr;
|
||||
unsigned char *tr;
|
||||
|
21
src/mts.c
21
src/mts.c
@ -118,15 +118,16 @@ void mts_load(unsigned char *data, unsigned int size)
|
||||
j = buff[1];
|
||||
buff += 2;
|
||||
for(k = 0; k < numblocks; k++)
|
||||
for(l = 0; l < numpalettes + 2; l++)
|
||||
for(l = 0; l < numpalettes + 3; l++)
|
||||
if((!blocks[k].blocknames && (int)strlen(blocks[k].name) == j &&
|
||||
!memcmp(blocks[k].name, buff, j)) || (blocks[k].blocknames && blocks[k].blocknames[l] &&
|
||||
(int)strlen(blocks[k].blocknames[l]) == j && !memcmp(blocks[k].blocknames[l], buff, j))) {
|
||||
if(k)
|
||||
switch(l) {
|
||||
case 0: blocks[k].dobiome = 1; savebiome = 1; break;
|
||||
case 1: if(!memcmp(buff, "mapgen", 6)) { savemapgen = 1; } break;
|
||||
default: palref[l - 2]++; break;
|
||||
case 0: break;
|
||||
case 1: blocks[k].dobiome = 1; savebiome = 1; break;
|
||||
case 2: if(!memcmp(buff, "mapgen", 6)) { savemapgen = 1; } break;
|
||||
default: palref[l - 3]++; break;
|
||||
}
|
||||
tr[i] = k;
|
||||
break;
|
||||
@ -269,10 +270,10 @@ int mts_save()
|
||||
fwrite(hdr, 2, 1, f);
|
||||
if(savepal < 0 || savepal >= numpalettes) savepal = 0;
|
||||
for(i = 0; i < j; i++) {
|
||||
c = !blocks[tr[i]].blocknames ? blocks[tr[i]].name : (savebiome && blocks[tr[i]].blocknames[0] &&
|
||||
blocks[tr[i]].dobiome ? blocks[tr[i]].blocknames[0] : (savemapgen && blocks[tr[i]].blocknames[1] &&
|
||||
blocks[tr[i]].blocknames[1][0] ? blocks[tr[i]].blocknames[1] : (blocks[tr[i]].blocknames[savepal+2] &&
|
||||
blocks[tr[i]].blocknames[savepal+2][0] ? blocks[tr[i]].blocknames[savepal+2] : blocks[tr[i]].name)));
|
||||
c = !blocks[tr[i]].blocknames ? blocks[tr[i]].name : (savebiome && blocks[tr[i]].blocknames[1] &&
|
||||
blocks[tr[i]].dobiome ? blocks[tr[i]].blocknames[1] : (savemapgen && blocks[tr[i]].blocknames[2] &&
|
||||
blocks[tr[i]].blocknames[2][0] ? blocks[tr[i]].blocknames[2] : (blocks[tr[i]].blocknames[savepal+3] &&
|
||||
blocks[tr[i]].blocknames[savepal+3][0] ? blocks[tr[i]].blocknames[savepal+3] : blocks[tr[i]].name)));
|
||||
hdr[1] = strlen(c);
|
||||
fwrite(hdr, 2, 1, f);
|
||||
fwrite(c, hdr[1], 1, f);
|
||||
@ -530,8 +531,8 @@ int mts_dump()
|
||||
printf("Map (x: %d y: %d z: %d):\r\n", max-mix+1, may-miy+1, maz-miz+1);
|
||||
if(savepal < 0 || savepal >= numpalettes) savepal = 0;
|
||||
for(i = 0; i < j; i++)
|
||||
printf("%4x: %s\r\n", i, blocks[tr[i]].blocknames && blocks[tr[i]].blocknames[savepal+1] ?
|
||||
blocks[tr[i]].blocknames[savepal+1] : blocks[tr[i]].name);
|
||||
printf("%4x: %s\r\n", i, blocks[tr[i]].blocknames && blocks[tr[i]].blocknames[savepal+3] ?
|
||||
blocks[tr[i]].blocknames[savepal+3] : blocks[tr[i]].name);
|
||||
|
||||
for(y = miy; y <= may; y++) {
|
||||
printf("\r\nLayer %d (probability %d%s):\r\n", y - miy, layerprob[y], y == gndlayer ? ", Ground level" : "");
|
||||
|
@ -96,8 +96,8 @@ void save_redraw()
|
||||
sdlprint(44,rect.y, savefld == 5 && biomepos == k ? THEME_INPUT : THEME_INACT, THEME_INPBG, blocks[i].name);
|
||||
strmaxw = screen->w - 5;
|
||||
sdlprint(screen->w/2,rect.y, savefld == 5 && biomepos == k ? THEME_INPUT : THEME_INACT, THEME_INPBG,
|
||||
blocks[i].blocknames[blocks[i].dobiome ? 0 : (savemapgen && blocks[i].blocknames[1] &&
|
||||
blocks[i].blocknames[1][0] ? 1 : savepal + 2)]);
|
||||
blocks[i].blocknames[blocks[i].dobiome ? 1 : (savemapgen && blocks[i].blocknames[2] &&
|
||||
blocks[i].blocknames[2][0] ? 2 : savepal + 3)]);
|
||||
rect.y += font->height;
|
||||
}
|
||||
k++;
|
||||
|
234
src/schemimp.c
234
src/schemimp.c
@ -29,6 +29,22 @@
|
||||
|
||||
#include "main.h"
|
||||
|
||||
/**
|
||||
* match name
|
||||
*/
|
||||
int namematch(char *a, char *b)
|
||||
{
|
||||
int la, lb, i;
|
||||
if(!a || !*a || !b || !*b) return 0;
|
||||
if(!strcmp(a, b)) return 1;
|
||||
la = strlen(a); lb = strlen(b);
|
||||
for(i = 0; i < lb - la + 1; i++) {
|
||||
if((!i || b[i-1] == '/') && !memcmp(a, b + i, la) && (!b[i + la] || b[i + la] == '/'))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a Minecraft NBT Schematic file
|
||||
*/
|
||||
@ -37,51 +53,83 @@
|
||||
case 3:v=(d[0]<<24)|(d[1]<<16)|(d[2]<<8)|d[3];d+=4;break;}}while(0)
|
||||
void schem_load(unsigned char *data, unsigned int size)
|
||||
{
|
||||
int i, j, k, x, y, z, min_x = 0, min_y = 0, min_z = 0;
|
||||
unsigned char *d, *blk, *blkd = NULL, *end = data + size;
|
||||
int i, j, k, l, x, y, z, g = 0, min_x = 0, min_y = 0, min_z = 0, tr[1024];
|
||||
char name[256];
|
||||
unsigned char *d, *s, *blk, *blkd = NULL, *blkp = NULL, *end = data + size;
|
||||
unsigned int n;
|
||||
|
||||
/* we don't care about that overcomplicated NBT mess */
|
||||
for(d = data; d < end && (!mts_y || !mts_z || !mts_x); d++) {
|
||||
for(d = data, blk = NULL; d + 12 < end; d++) {
|
||||
if(!memcmp(d, "\000\006Height", 8)) { d += 8; SCHEM_GETINT(mts_y, d[-9]); d--; } else
|
||||
if(!memcmp(d, "\000\006Length", 8)) { d += 8; SCHEM_GETINT(mts_z, d[-9]); d--; } else
|
||||
if(!memcmp(d, "\000\005Width", 7)) { d += 7; SCHEM_GETINT(mts_x, d[-8]); d--; } else
|
||||
if(!memcmp(d, "\007\000\004Data", 7)) { d += 7; blkd = d + 4; SCHEM_GETINT(i, 3); d += i; }
|
||||
if(!memcmp(d, "\000\009WEOffsetY", 11)) { d += 11; SCHEM_GETINT(g, d[-12]); d--; } else
|
||||
if(!memcmp(d, "\007\000\004Data", 7)) { d += 7; blkd = d + 4; SCHEM_GETINT(i, 3); d += i; } else
|
||||
if(!memcmp(d, "\007\000\006Blocks", 9)) { d += 9; SCHEM_GETINT(l, 3); blk = d; d += l; } else
|
||||
if(!memcmp(d, "\012\000\007Palette", 10)) { d += 10; blkp = d; } else
|
||||
if(!memcmp(d, "\007\000\011BlockData", 12)) { d += 12; SCHEM_GETINT(l, 3); blk = d; d += l; }
|
||||
}
|
||||
if(!mts_y || !mts_z || !mts_x || mts_y > 255 || mts_z > 255 || mts_x > 255) { mts_y = mts_z = mts_x = 0; return; }
|
||||
blocks[0].numref = mts_y * mts_z * mts_x;
|
||||
if(!blk || !mts_y || !mts_z || !mts_x || mts_y > 255 || mts_z > 255 || mts_x > 255 || l < mts_y * mts_z * mts_x) {
|
||||
mts_y = mts_z = mts_x = 0;
|
||||
return;
|
||||
}
|
||||
memset(tr, 0, sizeof(tr));
|
||||
if(!blkp) {
|
||||
for(i = 1; i < numblocks; i++)
|
||||
for(j = 0; j < 4; j++)
|
||||
if(blocks[i].blockids[j])
|
||||
tr[blocks[i].blockids[j]] = i;
|
||||
} else {
|
||||
for(d = blkp; *d > 0 && *d < 4;) {
|
||||
j = *d++; d++; l = *d++; s = d; d += l;
|
||||
memcpy(name, s, l); name[l] = 0;
|
||||
for(l = 0; name[l]; l++) if(name[l] == '[') { name[l] = 0; break; }
|
||||
SCHEM_GETINT(k, j);
|
||||
for(i = l = 0; i < numblocks; i++)
|
||||
if((blocks[i].name && !strcmp(blocks[i].name, name)) ||
|
||||
(blocks[i].blocknames && namematch(name, blocks[i].blocknames[0]))) { tr[k] = i; l = 1; break; }
|
||||
if(!l) {
|
||||
fprintf(stderr, "mtsedit: %s: %s '%s'\r\n", mtsfile, lang[ERR_NODE], name);
|
||||
j = numblocks++;
|
||||
blocks = (mtsblock_t*)realloc(blocks, numblocks * sizeof(mtsblock_t));
|
||||
if(!blocks) error(lang[ERR_MEM]);
|
||||
memset(&blocks[j], 0, sizeof(mtsblock_t));
|
||||
blocks[j].name = (char*)malloc(strlen(name) + 1);
|
||||
if(!blocks[j].name) error(lang[ERR_MEM]);
|
||||
strcpy(blocks[j].name, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
blocks[0].numref = l;
|
||||
min_x = 127 - mts_x / 2;
|
||||
min_y = 127 - mts_y / 2;
|
||||
min_z = 127 - mts_z / 2;
|
||||
gndlayer = min_y;
|
||||
/* now that we know the dimensions, find the blocks data */
|
||||
for(d = data; d < end; d++) {
|
||||
/* it must be type of byte array */
|
||||
if(!memcmp(d, "\007\000\006Blocks", 9)) {
|
||||
d += 9;
|
||||
SCHEM_GETINT(i, 3);
|
||||
if(i != mts_y * mts_z * mts_x) return;
|
||||
blk = d;
|
||||
for(y = 0; y < mts_y; y++)
|
||||
gndlayer = min_y - g;
|
||||
/* now that we know the dimensions, and the blocks data, we can parse */
|
||||
for(d = blk, i = y = 0; y < mts_y; y++)
|
||||
for(z = 0; z < mts_z; z++)
|
||||
for(x = 0; x < mts_x; x++, d++) {
|
||||
if(!*d) continue;
|
||||
for(i = 1, k = 0; i < numblocks; i++)
|
||||
for(j = 0; j < 4; j++)
|
||||
if(blocks[i].blockids[j] == *d) { k = i; i = numblocks; break; }
|
||||
if(k) {
|
||||
for(x = 0; x < mts_x; x++, i++) {
|
||||
if(!blkp)
|
||||
n = *d++;
|
||||
else {
|
||||
/* this is a f*cked up non-documented varint encoding...
|
||||
* see https://github.com/EngineHub/WorldEdit/blob/master/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java#L259 */
|
||||
for(n = 0, j = 0; j < 21; d++, j += 7) {
|
||||
n |= (*d & 0x7F) << j;
|
||||
if(!(*d & 0x80)) { d++; break; }
|
||||
}
|
||||
}
|
||||
if(n < 1024 && tr[n]) {
|
||||
layerprob[y+min_y] = 127;
|
||||
nodes[y+min_y][z+min_z][x+min_x].param0 = k;
|
||||
nodes[y+min_y][z+min_z][x+min_x].param0 = tr[n];
|
||||
nodes[y+min_y][z+min_z][x+min_x].param1 = 127;
|
||||
if(blkd)
|
||||
nodes[y+min_y][z+min_z][x+min_x].param2 = blkd[d - blk] & 3;
|
||||
blocks[k].numref++;
|
||||
} else
|
||||
fprintf(stderr, "mtsedit: %s: %s %d\r\n", mtsfile, lang[ERR_NODE], *d);
|
||||
nodes[y+min_y][z+min_z][x+min_x].param2 = blkd[i] & 3;
|
||||
blocks[tr[n]].numref++;
|
||||
} else if(!blkp && !*d)
|
||||
fprintf(stderr, "mtsedit: %s: %s %d\r\n", mtsfile, lang[ERR_NODE], n);
|
||||
}
|
||||
status = lang[LOADED];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -147,14 +195,19 @@ void m3d_load(unsigned char *data, unsigned int size)
|
||||
{
|
||||
unsigned char *f = NULL, *ch, *s, *e = data + size;
|
||||
char *strtbl, *n;
|
||||
int i, j, k, l, m, g = 0, ci_s, si_s, sk_s, nt = 0, *palref;
|
||||
int i, j, k, l, m, ci_s, si_s, sk_s, vd_s, vp_s, nt = 0, *palref;
|
||||
int min_x = 0, min_y = 0, min_z = 0, mi_x = 65536, mi_y = 65536, mi_z = 65536, ma_x = 0, ma_y = 0, ma_z = 0, x, y, z;
|
||||
int sx, sy, sz, px, py, pz;
|
||||
uint32_t c, *cmap = NULL, *tr = NULL;
|
||||
|
||||
data += 8;
|
||||
size -= 8;
|
||||
if(!memcmp(data, "PRVW", 4)) {
|
||||
size -= *((uint32_t*)(data + 4));
|
||||
data += *((uint32_t*)(data + 4));
|
||||
}
|
||||
if(memcmp(data, "HEAD", 4)) {
|
||||
data = f = (unsigned char *)stbi_zlib_decode_malloc_guesssize_headerflag((const char*)data+8, size-8, 4096, &l, 1);
|
||||
data = f = (unsigned char *)stbi_zlib_decode_malloc_guesssize_headerflag((const char*)data, size, 4096, &l, 1);
|
||||
if(!data || !l || memcmp(data, "HEAD", 4)) {
|
||||
if(data) free(data);
|
||||
return;
|
||||
@ -165,10 +218,13 @@ void m3d_load(unsigned char *data, unsigned int size)
|
||||
si_s = 1 << ((data[12] >> 4) & 3);
|
||||
ci_s = 1 << ((data[12] >> 6) & 3);
|
||||
sk_s = 1 << ((data[13] >> 6) & 3);
|
||||
vd_s = 1 << ((data[14] >> 6) & 3);
|
||||
vp_s = 1 << ((data[15] >> 0) & 3);
|
||||
if(ci_s == 8) ci_s = 0;
|
||||
if(sk_s == 8) sk_s = 0;
|
||||
if(vd_s == 8 || vp_s > 2) return;
|
||||
|
||||
/* detect dimensions and get palette */
|
||||
/* detect dimensions and get color and node palettes */
|
||||
ch = data;
|
||||
while(ch < e && memcmp(ch, "OMD3", 4)) {
|
||||
s = ch;
|
||||
@ -179,8 +235,7 @@ void m3d_load(unsigned char *data, unsigned int size)
|
||||
if(!memcmp(s, "CMAP", 4)) { cmap = (uint32_t*)(s + 8); } else
|
||||
if(!memcmp(s, "VOXT", 4)) {
|
||||
s += 8;
|
||||
g = *((uint16_t*)s); s += 2;
|
||||
nt = (l-2) / (ci_s + si_s + 1);
|
||||
nt = l / (ci_s + si_s + 3 + sk_s);
|
||||
tr = (uint32_t*)malloc(nt * sizeof(uint32_t));
|
||||
if(!tr) error(lang[ERR_MEM]);
|
||||
palref = (int*)malloc(numpalettes * sizeof(int));
|
||||
@ -205,19 +260,22 @@ void m3d_load(unsigned char *data, unsigned int size)
|
||||
n = strtbl + j;
|
||||
tr[i] = numblocks;
|
||||
for(k = 0; k < numblocks; k++)
|
||||
for(m = 0; m < numpalettes + 2; m++)
|
||||
for(m = 0; m < numpalettes + 3; m++)
|
||||
if((!blocks[k].blocknames && !strcmp(blocks[k].name, n)) ||
|
||||
(blocks[k].blocknames && blocks[k].blocknames[m] && !strcmp(blocks[k].blocknames[m], n))) {
|
||||
(blocks[k].blocknames && namematch(n, blocks[k].blocknames[m]))) {
|
||||
if(k)
|
||||
switch(m) {
|
||||
case 0: blocks[k].dobiome = 1; savebiome = 1; break;
|
||||
case 1: if(!memcmp(n, "mapgen", 6)) { savemapgen = 1; } break;
|
||||
default: palref[m - 2]++; break;
|
||||
case 0: break;
|
||||
case 1: blocks[k].dobiome = 1; savebiome = 1; break;
|
||||
case 2: if(!memcmp(n, "mapgen", 6)) { savemapgen = 1; } break;
|
||||
default: palref[m - 3]++; break;
|
||||
}
|
||||
tr[i] = k;
|
||||
break;
|
||||
}
|
||||
if(tr[i] == (uint32_t)numblocks) {
|
||||
if(c) tr[i] = color2blockid(c);
|
||||
else {
|
||||
fprintf(stderr, "mtsedit: %s: %s %d '%s'\r\n", mtsfile, lang[ERR_NODE], i, n);
|
||||
j = numblocks++;
|
||||
blocks = (mtsblock_t*)realloc(blocks, numblocks * sizeof(mtsblock_t));
|
||||
@ -227,12 +285,16 @@ void m3d_load(unsigned char *data, unsigned int size)
|
||||
if(!blocks[j].name) error(lang[ERR_MEM]);
|
||||
strcpy(blocks[j].name, n);
|
||||
}
|
||||
}
|
||||
} else
|
||||
/* fallback to best color match */
|
||||
if(c) tr[i] = color2blockid(c);
|
||||
else tr[i] = 0;
|
||||
tr[i] |= s[0] << 24;
|
||||
s += 2 + sk_s;
|
||||
/* skip over additional attributes */
|
||||
s += 2;
|
||||
j = *s;
|
||||
s += 1 + sk_s + j * (2 + si_s);
|
||||
}
|
||||
/* pick the node palette which has the most node reference */
|
||||
for(i = savepal = 0; i < numpalettes; i++)
|
||||
@ -240,9 +302,19 @@ void m3d_load(unsigned char *data, unsigned int size)
|
||||
free(palref);
|
||||
} else
|
||||
if(!memcmp(s, "VOXD", 4)) {
|
||||
s += 8;
|
||||
py = *((uint16_t*)(s + 0)); pz = *((uint16_t*)(s + 2)); px = *((uint16_t*)(s + 4));
|
||||
sy = *((uint16_t*)(s + 6)); sz = *((uint16_t*)(s + 8)); sx = *((uint16_t*)(s + 10));
|
||||
s += 8 + si_s;
|
||||
px = py = pz = sx = sy = sz = 0;
|
||||
switch(vd_s) {
|
||||
case 1:
|
||||
px = (int8_t)s[0]; py = (int8_t)s[1]; pz = (int8_t)s[2];
|
||||
sx = (int8_t)s[3]; sy = (int8_t)s[4]; sz = (int8_t)s[5];
|
||||
break;
|
||||
case 2:
|
||||
px = *((int16_t*)(s+0)); py = *((int16_t*)(s+2)); pz = *((int16_t*)(s+4));
|
||||
sx = *((int16_t*)(s+6)); sy = *((int16_t*)(s+8)); sz = *((int16_t*)(s+10));
|
||||
break;
|
||||
default: return; break;
|
||||
}
|
||||
if(px < mi_x) { mi_x = px; } if(px+sx > ma_x) { ma_x = px+sx; }
|
||||
if(py < mi_y) { mi_y = py; } if(py+sy > ma_y) { ma_y = py+sy; }
|
||||
if(pz < mi_z) { mi_z = pz; } if(pz+sz > ma_z) { ma_z = pz+sz; }
|
||||
@ -264,7 +336,7 @@ void m3d_load(unsigned char *data, unsigned int size)
|
||||
min_x = 127 - mts_x / 2;
|
||||
min_y = 127 - mts_y / 2;
|
||||
min_z = 127 - mts_z / 2;
|
||||
gndlayer = min_y + g;
|
||||
gndlayer = min_y - mi_y;
|
||||
|
||||
/* read in the layers */
|
||||
ch = data;
|
||||
@ -273,45 +345,51 @@ void m3d_load(unsigned char *data, unsigned int size)
|
||||
l = *((uint32_t*)(ch + 4));
|
||||
ch += l;
|
||||
if(!memcmp(s, "VOXD", 4)) {
|
||||
s += 8;
|
||||
py = *((uint16_t*)(s + 0))-mi_y+min_y; pz = *((uint16_t*)(s + 2))-mi_z+min_z; px = *((uint16_t*)(s + 4))-mi_x+min_x;
|
||||
sy = *((uint16_t*)(s + 6)); sz = *((uint16_t*)(s + 8)); sx = *((uint16_t*)(s + 10));
|
||||
s += 8 + si_s;
|
||||
px = py = pz = sx = sy = sz = 0;
|
||||
switch(vd_s) {
|
||||
case 1:
|
||||
px = (int8_t)s[0]; py = (int8_t)s[1]; pz = (int8_t)s[2];
|
||||
sx = (int8_t)s[3]; sy = (int8_t)s[4]; sz = (int8_t)s[5];
|
||||
s += 6;
|
||||
break;
|
||||
case 2:
|
||||
px = *((int16_t*)(s+0)); py = *((int16_t*)(s+2)); pz = *((int16_t*)(s+4));
|
||||
sx = *((int16_t*)(s+6)); sy = *((int16_t*)(s+8)); sz = *((int16_t*)(s+10));
|
||||
s += 12;
|
||||
break;
|
||||
}
|
||||
px += min_x-mi_x; py += min_y-mi_y; pz += min_z-mi_z;
|
||||
k = (255 - *s) >> 1;
|
||||
for(y = 0; y < sy; y++)
|
||||
if(py+y >= 0 && py+y < 256)
|
||||
layerprob[py+y] = k;
|
||||
k = sx * sz;
|
||||
for(s += si_s + 2, i = 0; s < ch;) {
|
||||
l = *s; s++;
|
||||
if(!l) { s += si_s; } else
|
||||
if(l < 0) {
|
||||
if(nt < 256) { m = *s; s++; } else { m = *((uint16_t*)s); s += 2; }
|
||||
for(j = 0; j < -l; j++, i++) {
|
||||
y = i / k;
|
||||
z = (i % k) / sx;
|
||||
x = i % sx;
|
||||
k = sx * sz; x = y = z = 0;
|
||||
for(s += 2, i = 0; s < ch;) {
|
||||
l = ((*s++) & 0x7F) + 1;
|
||||
if(s[-1] & 0x80) {
|
||||
if(vp_s == 1) { m = *s++; } else { m = *((uint16_t*)s); s += 2; }
|
||||
for(j = 0; j < l; j++, i++) {
|
||||
if(m >= 0 && m < nt && py+y >= 0 && py+y < 256 && pz+z >= 0 && pz+z < 256 && px+x >= 0 && px+x < 256) {
|
||||
nodes[py+y][py+z][px+x].param0 = tr[m] & 0xFFFFFF;
|
||||
nodes[py+y][py+z][px+x].param1 = tr[m] ? 127 : 0;
|
||||
nodes[py+y][py+z][px+x].param2 = (tr[m] >> 24) & PARAM2_MAX;
|
||||
nodes[py+y][pz+z][px+x].param0 = tr[m] & 0xFFFFFF;
|
||||
nodes[py+y][pz+z][px+x].param1 = tr[m] ? 127 : 0;
|
||||
nodes[py+y][pz+z][px+x].param2 = (tr[m] >> 24) & PARAM2_MAX;
|
||||
blocks[nodes[py+y][py+z][px+x].param0].numref++;
|
||||
blocks[0].numref--;
|
||||
}
|
||||
x++; if(x >= sx) { x = 0; z++; if(z >= sz) { z = 0; y++; } }
|
||||
}
|
||||
} else {
|
||||
for(j = 0; j < l; j++, i++) {
|
||||
y = i / k;
|
||||
z = (i % k) / sx;
|
||||
x = i % sx;
|
||||
if(nt < 256) { m = *s; s++; } else { m = *((uint16_t*)s); s += 2; }
|
||||
if(vp_s == 1) { m = *s++; } else { m = *((uint16_t*)s); s += 2; }
|
||||
if(m >= 0 && m < nt && py+y >= 0 && py+y < 256 && pz+z >= 0 && pz+z < 256 && px+x >= 0 && px+x < 256) {
|
||||
nodes[py+y][py+z][px+x].param0 = tr[m] & 0xFFFFFF;
|
||||
nodes[py+y][py+z][px+x].param1 = tr[m] ? 127 : 0;
|
||||
nodes[py+y][py+z][px+x].param2 = (tr[m] >> 24) & PARAM2_MAX;
|
||||
nodes[py+y][pz+z][px+x].param0 = tr[m] & 0xFFFFFF;
|
||||
nodes[py+y][pz+z][px+x].param1 = tr[m] ? 127 : 0;
|
||||
nodes[py+y][pz+z][px+x].param2 = (tr[m] >> 24) & PARAM2_MAX;
|
||||
blocks[nodes[py+y][py+z][px+x].param0].numref++;
|
||||
blocks[0].numref--;
|
||||
}
|
||||
x++; if(x >= sx) { x = 0; z++; if(z >= sz) { z = 0; y++; } }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -594,14 +672,14 @@ void qb_load(unsigned char *data, unsigned int size)
|
||||
/* detect dimensions */
|
||||
for(s = data + 24, i = 0; i < mc && s < e; i++) {
|
||||
s += s[0] + 1;
|
||||
sx = *((int*)(s + 0)); sy = *((int*)(s + 4)); sz = *((int*)(s + 8));
|
||||
px = *((int*)(s + 12)); py = *((int*)(s + 16)); pz = *((int*)(s + 20));
|
||||
sx = *((int*)(s + 0)); sz = *((int*)(s + 4)); sy = *((int*)(s + 8));
|
||||
px = *((int*)(s + 12)); pz = *((int*)(s + 16)); py = *((int*)(s + 20));
|
||||
if(px < mi_x) { mi_x = px; } if(px+sx > ma_x) { ma_x = px+sx; }
|
||||
if(py < mi_y) { mi_y = py; } if(py+sy > ma_y) { ma_y = py+sy; }
|
||||
if(pz < mi_z) { mi_z = pz; } if(pz+sz > ma_z) { ma_z = pz+sz; }
|
||||
s += 24;
|
||||
if(co) {
|
||||
for(z = 0; z < sz; z++) {
|
||||
for(y = 0; y < sy; y++) {
|
||||
while(1) {
|
||||
c = *((uint32_t*)s); s += 4;
|
||||
if(c == 6 || c == 0x60000) break;
|
||||
@ -627,26 +705,26 @@ void qb_load(unsigned char *data, unsigned int size)
|
||||
/* read in the layers */
|
||||
for(s = data + 24, i = 0; i < mc && s < e; i++) {
|
||||
s += s[0] + 1;
|
||||
sx = *((int*)(s + 0)); sy = *((int*)(s + 4)); sz = *((int*)(s + 8));
|
||||
px = *((int*)(s + 12)) - mi_x + min_x; py = *((int*)(s + 16)) - mi_y + min_y; pz = *((int*)(s + 20)) - mi_z + min_z;
|
||||
sx = *((int*)(s + 0)); sz = *((int*)(s + 4)); sy = *((int*)(s + 8));
|
||||
px = *((int*)(s + 12)) - mi_x + min_x; pz = *((int*)(s + 16)) - mi_z + min_z; py = *((int*)(s + 20)) - mi_y + min_y;
|
||||
s += 24;
|
||||
if(co) {
|
||||
for(z = 0; z < sz; z++) {
|
||||
for(y = 0; y < sy; y++) {
|
||||
for(i = 0; 1;) {
|
||||
c = *((uint32_t*)s); s += 4;
|
||||
if(c == 6 || c == 0x60000) break;
|
||||
if(c == 2 || c == 0x20000) { l = *((int32_t*)s); s += 4; c = *((uint32_t*)s); s += 4; } else l = 1;
|
||||
for(j = 0; j < l; j++, i++) {
|
||||
x = i % sx; y = i / sx;
|
||||
_qb_set(cf, px+x, py+y, pz + (za ? mts_z-z : z), (unsigned char*)&c);
|
||||
x = i % sx; z = i / sx;
|
||||
_qb_set(cf, px+x, pz + (za ? mts_z-z : z), py+y, (unsigned char*)&c);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(z = 0; z < sz; z++)
|
||||
for(y = 0; y < sy; y++)
|
||||
for(z = 0; z < sz; z++)
|
||||
for(x = 0; x < sx; x++, s += 4)
|
||||
_qb_set(cf, px+x, py+y, pz + (za ? mts_z-z : z), s);
|
||||
_qb_set(cf, px+x, pz + (za ? mts_z-z : z), py+y, s);
|
||||
}
|
||||
}
|
||||
status = lang[LOADED];
|
||||
|
@ -1354,10 +1354,11 @@ void tileremap()
|
||||
blocks_parse();
|
||||
for(j = 0; j < 256; j++)
|
||||
for(i = 0; i < numblocks; i++)
|
||||
if(blocks[i].blockids[0] == j) {
|
||||
if(blocks[i].blockids[0] == j || (j && blocks[i].blockids[1] == j)) {
|
||||
for(k = 0; k < (int)strlen(blocks[i].name); k++)
|
||||
if(blocks[i].name[k] == ' ') blocks[i].name[k] = '_';
|
||||
printf("%s\r\n", blocks[i].name);
|
||||
/* printf("0x%08x\n",blocks[i].color);*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user