add map export to format 9

Export to the map format of AC 1.2. Use with caution. Experimental.
This commit is contained in:
ac-stef
2015-09-14 16:32:56 +02:00
parent f424c95a7f
commit f6c161bcc5
+70 -2
View File
@@ -279,11 +279,12 @@ void clearheaderextras() { loopvrev(headerextras) delete headerextras.remove(i);
void deleteheaderextra(int n) { if(headerextras.inrange(n)) delete headerextras.remove(n); }
COMMANDF(listheaderextras, "", ()
void listheaderextras()
{
loopv(headerextras) conoutf("extra header record %d: %s, %d bytes", i, hx_name(headerextras[i]->flags), headerextras[i]->len);
if(!headerextras.length()) conoutf("no extra header records found");
});
}
COMMAND(listheaderextras, "");
int findheaderextra(int type)
{
@@ -589,6 +590,73 @@ VARP(preserveundosonsave, 0, 0, 1);
COMMANDF(savemap, "s", (char *name) { save_world(name, preserveundosonsave && editmode, preserveundosonsave && editmode); } );
COMMANDF(savemapoptimised, "s", (char *name) { save_world(name, false, false); } );
void save_world9(char *mname)
{
if(unsavededits) { conoutf("\f3There are unsaved changes to the map. Please save them to a lossless format first (\"savemap\")."); return; }
if(!*mname) { conoutf("\f3You need to specify a map file name."); return; }
if(securemapcheck(mname)) return;
if(!validmapname(mname)) { conoutf("\f3Invalid map name. It must only contain letters, digits, '-', '_' and be less than %d characters long", MAXMAPNAMELEN); return; }
if(findheaderextra(HX_CONFIG) >= 0)
{ // extract embedded config file first
string clientmapbak;
copystring(clientmapbak, getclientmap());
copystring(getclientmap(), mname); // hack!
extractconfigfile();
copystring(getclientmap(), clientmapbak);
}
if(headerextras.length())
{
conoutf("\f3not writing header extra information:");
listheaderextras();
}
setnames(mname);
backup(cgzname, bakname);
stream *f = opengzfile(cgzname, "wb");
if(!f) { conoutf("could not write map to %s", cgzname); return; }
strncpy(hdr.head, "ACMP", 4); // ensure map now declares itself as an AssaultCube map, even if imported as CUBE
hdr.version = 9;
hdr.headersize = sizeof(header);
hdr.timestamp = (int) time(NULL); // non-zero timestamps in format 9 can be used to identify "exported" maps
hdr.numents = 0;
loopv(ents) if(ents[i].type!=NOTUSED) hdr.numents++;
if(hdr.numents > MAXENTITIES)
{
conoutf("too many map entities (%d), only %d will be written to file", hdr.numents, MAXENTITIES);
hdr.numents = MAXENTITIES;
}
header tmp = hdr;
tmp.maprevision += advancemaprevision;
tmp.flags = 0;
tmp.waterlevel /= WATERLEVELSCALING;
lilswap(&tmp.version, 4); // version, headersize, sfactor, numents
lilswap(&tmp.waterlevel, 1);
lilswap(&tmp.maprevision, 4); // maprevision, ambient, flags, timestamp
f->write(&tmp, sizeof(header));
int ne = hdr.numents, ec = 0;
loopv(ents)
{
if(ents[i].type!=NOTUSED)
{
if(!ne--) break;
persistent_entity tmp = ents[i];
clampentityattributes(tmp);
tmp.attr1 /= entscale[tmp.type][0];
tmp.attr2 /= entscale[tmp.type][1];
tmp.attr3 /= entscale[tmp.type][2];
tmp.attr4 /= entscale[tmp.type][3];
if(tmp.attr5 || tmp.attr6 || tmp.attr7) conoutf("\f3lost some attributes for entity #%d (%d)", i, ++ec);
lilswap((short *)&tmp, 4);
f->write(&tmp, 12);
}
}
vector<uchar> rawcubes;
rlencodecubes(rawcubes, world, cubicsize, false);
f->write(rawcubes.getbuf(), rawcubes.length());
delete f;
conoutf("wrote map file %s with format 9", cgzname);
}
COMMANDN(savemap9, save_world9, "s");
void showmapdims()
{
conoutf(" min X|Y|Z: %3d : %3d : %3d", mapdims.x1, mapdims.y1, mapdims.minfloor);