From d5bd8961898f9e507fbbba7e3112232b549ffbfb Mon Sep 17 00:00:00 2001 From: ac-stef Date: Sat, 20 Aug 2016 14:45:41 +0200 Subject: [PATCH] properly adjust texlists when deleting texture slots check texlists during save (and print warning, if errors were corrected) also add (undocumented) command to patch messed up texlists --- source/src/clientgame.cpp | 3 +-- source/src/editing.cpp | 7 +++++++ source/src/protos.h | 2 +- source/src/texture.cpp | 19 +++++++++++++++++- source/src/worldio.cpp | 42 +++++++++++++++++++++------------------ 5 files changed, 50 insertions(+), 23 deletions(-) diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index 4a4927f1..a3356630 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -1080,10 +1080,9 @@ void resetmap(bool mrproper) resetzones(); clearminimap(); cleardynlights(); - pruneundos(); + reseteditor(); changedents.setsize(0); deleted_ents.setsize(0); - pinnedclosestent = false; particlereset(); setmapinfo("", ""); if(mrproper) diff --git a/source/src/editing.cpp b/source/src/editing.cpp index f234718c..5935e3e2 100644 --- a/source/src/editing.cpp +++ b/source/src/editing.cpp @@ -1132,3 +1132,10 @@ void transformclipentities() // transforms all clip entities to tag clips, if t } COMMAND(transformclipentities, ""); + +void reseteditor() // reset only stuff that would cause trouble editing the next map (don't reset selections, for example) +{ + loopk(3) curedittex[k] = -1; + pruneundos(0); + pinnedclosestent = false; +} diff --git a/source/src/protos.h b/source/src/protos.h index ccf8bf02..75d589c1 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -640,6 +640,7 @@ extern void text_endcolumns(); // editing extern void cursorupdate(); extern void toggleedit(bool force = false); +extern void reseteditor(); extern char *editinfo(); extern void makeundo(block &sel); extern void editdrag(bool isdown); @@ -651,7 +652,6 @@ extern void edittexxy(int type, int t, block &sel); extern void editheightxy(bool isfloor, int amount, block &sel); //extern bool noteditmode(); extern bool noteditmode(const char* func = NULL); -extern void pruneundos(int maxremain = 0); extern void storeposition(short p[]); extern void restoreposition(short p[]); extern void restoreeditundo(ucharbuf &q); diff --git a/source/src/texture.cpp b/source/src/texture.cpp index bdb411b3..4ad0a389 100644 --- a/source/src/texture.cpp +++ b/source/src/texture.cpp @@ -1046,7 +1046,17 @@ void deletetextureslot(int *n, char *opt, char *_replace) // delete texture slot } else if(e.attr4 > *n) e.attr4--; // adjust models in higher slots } - // FIXME: texlists... + loopk(3) // adjust texlists + { + int j = 255; + loopi(256) + { + if(hdr.texlists[k][i] == *n) j = i; + if(hdr.texlists[k][i] > *n) hdr.texlists[k][i]--; + } + if(j < 255) memmove(&hdr.texlists[k][j], &hdr.texlists[k][j + 1], 255 - j); + hdr.texlists[k][255] = 255; + } slots.remove(*n); defformatstring(m)(" (%d uses removed)", deld); if(replace != 255) formatstring(m)(" (%d uses changed to use slot #%d)", deld, replace); @@ -1148,3 +1158,10 @@ uchar *texconfig_paste(void *_s, uchar *usedslots) // create mapping table to tr return res; } +#ifdef _DEBUG +void resettexturelists() +{ + loopk(3) loopi(256) hdr.texlists[k][i] = i; +} +COMMAND(resettexturelists, ""); +#endif diff --git a/source/src/worldio.cpp b/source/src/worldio.cpp index ca9e85f8..8d028321 100644 --- a/source/src/worldio.cpp +++ b/source/src/worldio.cpp @@ -525,6 +525,28 @@ VAR(advancemaprevision, 1, 1, 100); VARP(mapbackupsonsave, 0, 1, 1); +void rebuildtexlists() // checks the texlists, if they still contain all possible textures +{ + short h[256]; + int mk[3], mt = 0; + vector missing; + loopk(3) + { + missing.setsize(0); + uchar *p = hdr.texlists[k]; + loopi(256) h[i] = 0; + loopi(256) h[p[i]]++; + loopi(256) if(h[i] == 0) missing.add(i); + mt += mk[k] = missing.length(); + loopi(256) if(h[p[i]] > 1) + { + h[p[i]]--; + p[i] = missing.pop(); + } + } + if(mt) conoutf("WARNING: rebuildtexlists() fixed %d|%d|%d missing entries", mk[0], mk[1], mk[2]); +} + void save_world(char *mname, bool skipoptimise, bool addcomfort) { if(!*mname) mname = getclientmap(); @@ -560,6 +582,7 @@ void save_world(char *mname, bool skipoptimise, bool addcomfort) hdr.version = MAPVERSION; hdr.headersize = sizeof(header); hdr.timestamp = (int) time(NULL); + rebuildtexlists(); hdr.numents = 0; loopv(ents) if(ents[i].type!=NOTUSED) hdr.numents++; if(hdr.numents > MAXENTITIES) @@ -687,25 +710,6 @@ extern char *mlayout; extern int Mv, Ma, Hhits; extern float Mh; -void rebuildtexlists() // checks the texlists, if they still contain all possible textures -{ - short h[256]; - vector missing; - loopk(3) - { - missing.setsize(0); - uchar *p = hdr.texlists[k]; - loopi(256) h[i] = 0; - loopi(256) h[p[i]]++; - loopi(256) if(h[i] == 0) missing.add(i); - loopi(256) if(h[p[i]] > 1) - { - h[p[i]]--; - p[i] = missing.pop(); - } - } -} - static string lastloadedconfigfile; bool load_world(char *mname) // still supports all map formats that have existed since the earliest cube betas!