diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index 5d0f6a36..8bd29069 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -1169,7 +1169,7 @@ void resetmap(bool mrproper) int suicided = -1; extern bool good_map(); extern bool item_fail; -extern int MA, F2F; +extern int MA, F2F, Ma, Hhits; extern float Mh; VARP(mapstats_hud, 0, 0, 1); @@ -1178,7 +1178,8 @@ void showmapstats() { conoutf("\f2Map Quality Stats"); conoutf(" The mean height is: %.2f", Mh); - if (MA) conoutf(" The max area is: %d", MA); + if (Hhits) conoutf(" Height check is: %d", Hhits); + if (MA) conoutf(" The max area is: %d (of %d)", MA, Ma); if (m_flags && F2F < 1000) conoutf(" Flag-to-flag distance is: %d", (int)fSqrt(F2F)); if (item_fail) conoutf(" There are one or more items too close to each other in this map"); } diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index 2787bbf5..7f3192a6 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -26,10 +26,10 @@ VARP(autogetmap, 0, 1, 1); // only if the client doesn't have that map VARP(autogetnewmaprevisions, 0, 1, 1); bool localwrongmap = false; -int MA = 0; // flowtron: moved here +int MA = 0, Hhits = 0; // flowtron: moved here bool changemapserv(char *name, int mode, int download, int revision) // forced map change from the server { - MA = 0; // reset for checkarea() + MA = Hhits = 0; // reset for checkarea() gamemode = mode; if(m_demo) return true; if(m_coop) @@ -303,7 +303,8 @@ bool good_map() // call this function only at startmap } } - map_quality = (!item_fail && F2F > MINFF && MA < MAXMAREA && Mh < MAXMHEIGHT) ? MAP_IS_GOOD : MAP_IS_BAD; + map_quality = (!item_fail && F2F > MINFF && MA < MAXMAREA && Mh < MAXMHEIGHT && + Hhits < MAXHHITS && Hhits * 3 < Ma) ? MAP_IS_GOOD : MAP_IS_BAD; if ( (!connected || gamemode == GMODE_COOPEDIT) && map_quality == MAP_IS_BAD ) map_quality = MAP_IS_EDITABLE; return map_quality > 0; } diff --git a/source/src/serverfiles.h b/source/src/serverfiles.h index 0bb376da..d7568e91 100644 --- a/source/src/serverfiles.h +++ b/source/src/serverfiles.h @@ -232,13 +232,17 @@ struct configset }; int FlagFlag = MINFF * 1000; -int Mvolume, Marea, Mopen = 0; +int Mvolume, Marea, SHhits, Mopen = 0; float Mheight = 0; bool mapisok(mapstats *ms) { if ( Mheight > MAXMHEIGHT ) { logline(ACLOG_INFO, "MAP CHECK FAIL: The overall ceil height is too high (%.1f cubes)", Mheight); return false; } if ( Mopen > MAXMAREA ) { logline(ACLOG_INFO, "MAP CHECK FAIL: There is a big open area in this (hint: use more solid walls)", Mheight); return false; } + if ( SHhits > MAXHHITS || SHhits * 3 > Marea ) + { + logline(ACLOG_INFO, "MAP CHECK FAIL: Too high height in some parts of the map (%d hits)", SHhits); return false; + } if ( ms->hasflags ) // Check if flags are ok { diff --git a/source/src/tools.cpp b/source/src/tools.cpp index d509a695..13228795 100644 --- a/source/src/tools.cpp +++ b/source/src/tools.cpp @@ -27,7 +27,7 @@ const char *numtime() int mapdims[8]; // min/max X/Y and delta X/Y and min/max Z extern char *maplayout, *testlayout; -extern int maplayout_factor, testlayout_factor, Mvolume, Marea, Mopen; +extern int maplayout_factor, testlayout_factor, Mvolume, Marea, Mopen, SHhits; extern float Mheight; extern int checkarea(int, char *); @@ -85,7 +85,7 @@ mapstats *loadmapstats(const char *filename, bool getlayout) memset(testlayout, 0, layoutsize * sizeof(char)); char *t = NULL; char floor = 0, ceil, diff = 0; - Mvolume = Marea = 0; + Mvolume = Marea = SHhits = 0; loopk(layoutsize) { char *c = testlayout + k; @@ -126,6 +126,7 @@ mapstats *loadmapstats(const char *filename, bool getlayout) } if ( type != SOLID && diff > 6 ) { + if (diff > MAXMHEIGHT) SHhits += diff * n; Marea += n; Mvolume += diff * n; } diff --git a/source/src/world.h b/source/src/world.h index bf9c8c5a..1c91e096 100644 --- a/source/src/world.h +++ b/source/src/world.h @@ -127,6 +127,7 @@ struct mapstats #define OUTBORDRAD(x,y,rad) (int(x-rad)=ssize-MINBORD || (y+rad)>=ssize-MINBORD) #define MAXMHEIGHT 30 #define MAXMAREA 10000 +#define MAXHHITS 30000 #define MINFF 2500 struct block { int x, y, xs, ys; }; diff --git a/source/src/worldio.cpp b/source/src/worldio.cpp index 6e2f2f25..bc1452ef 100644 --- a/source/src/worldio.cpp +++ b/source/src/worldio.cpp @@ -469,7 +469,7 @@ int numspawn[3], maploaded = 0, numflagspawn[2]; VAR(curmaprevision, 1, 0, 0); extern char *mlayout; -extern int Mv, Ma; +extern int Mv, Ma, Hhits; extern float Mh; bool load_world(char *mname) // still supports all map formats that have existed since the earliest cube betas! @@ -549,7 +549,7 @@ bool load_world(char *mname) // still supports all map formats that have mlayout = new char[cubicsize + 256]; memset(mlayout, 0, cubicsize * sizeof(char)); char diff = 0; - Mv = Ma = 0; + Mv = Ma = Hhits = 0; if(!mapinfo.numelems || (mapinfo.access(mname) && !cmpf(cgzname, mapinfo[mname]))) world = (sqr *)ents.getbuf(); c2skeepalive(); @@ -643,6 +643,7 @@ bool load_world(char *mname) // still supports all map formats that have } if ( type != SOLID && diff > 6 ) { + if (diff > MAXMHEIGHT) Hhits += diff * n; Ma += n; Mv += diff * n; }