From 29bea67da1c056b7b11b853dcc6037525495c5c8 Mon Sep 17 00:00:00 2001 From: Rafael Barreto Date: Tue, 19 Oct 2010 12:28:17 +0000 Subject: [PATCH] making the map quality requisites more transparent: 1) "MAP CHECK FAIL" messages in the server logs; 2) console messages to the client (WiP). git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@5769 e016b1c5-ed68-44aa-a2f7-31cac88cffde --- source/src/clientgame.cpp | 4 +++- source/src/clients2c.cpp | 11 ++++++----- source/src/entity.h | 2 ++ source/src/serveractions.h | 2 +- source/src/serverchecks.h | 1 + source/src/serverfiles.h | 13 +++++++++---- 6 files changed, 22 insertions(+), 11 deletions(-) diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index 2bd5e419..7e5922e3 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -603,7 +603,6 @@ bool bad_map() // this function makes a pair with good_map from clients2c return (gamemode != GMODE_COOPEDIT && ( Mh >= MAXMHEIGHT || MA >= MAXMAREA )); } - inline const char * spawn_message() { if (spawnpermission == SP_WRONGMAP) @@ -927,6 +926,7 @@ void resetmap(bool mrproper) } int suicided = -1; +extern bool good_map(); void startmap(const char *name, bool reset) // called just after a map load { @@ -943,6 +943,7 @@ void startmap(const char *name, bool reset) // called just after a map load lasthit = 0; if(m_valid(gamemode) && !m_mp(gamemode)) respawnself(); else findplayerstart(player1); + if(good_map()==MAP_IS_BAD) conoutf(_("You cannot play in this map due to quality requisites. Please, report this incident.")); if(!reset) return; @@ -956,6 +957,7 @@ void startmap(const char *name, bool reset) // called just after a map load arenaintermission = 0; bool noflags = (m_ctf || m_ktf) && (!numflagspawn[0] || !numflagspawn[1]); if(*clientmap) conoutf(_("game mode is \"%s\"%s"), modestr(gamemode, modeacronyms > 0), noflags ? " - \f2but there are no flag bases on this map" : ""); + if(multiplayer(false) || m_botmode) { loopv(gmdescs) if(gmdescs[i].mode == gamemode) diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index 87bb4db4..f2a2e47c 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -243,12 +243,13 @@ char *mlayout = NULL; int Mv = 0, Ma = 0; // moved up:, MA = 0; float Mh = 0; extern int connected; +int map_quality = MAP_IS_EDITABLE; -bool good_map() +bool good_map() // call this function only at startmap { - if (!connected || gamemode == GMODE_COOPEDIT) return true; - bool checked = (MA==0) ? ((MA = checkarea(sfactor, mlayout)) < MAXMAREA && Mh < MAXMHEIGHT) : true; - return checked; + map_quality = ((MA = checkarea(sfactor, mlayout)) < MAXMAREA && Mh < MAXMHEIGHT) ? MAP_IS_GOOD : MAP_IS_BAD; + if ( (!connected || gamemode == GMODE_COOPEDIT) && map_quality == MAP_IS_BAD ) map_quality = MAP_IS_EDITABLE; + return map_quality; } VARP(hudextras, 0, 0, 3); @@ -549,7 +550,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) case SV_SPAWNSTATE: { - if ( !good_map() ) + if ( map_quality == MAP_IS_BAD ) { loopi(6+2*NUMGUNS) getint(p); conoutf(_("map deemed unplayable - fix it before you can spawn")); diff --git a/source/src/entity.h b/source/src/entity.h index b643475b..31d4b879 100644 --- a/source/src/entity.h +++ b/source/src/entity.h @@ -16,6 +16,8 @@ enum // static entity types MAXENTTYPES }; +enum {MAP_IS_BAD, MAP_IS_EDITABLE, MAP_IS_GOOD}; + extern const char *entnames[MAXENTTYPES]; #define isitem(i) ((i) >= I_CLIPS && (i) <= I_AKIMBO) diff --git a/source/src/serveractions.h b/source/src/serveractions.h index b0f5f7c8..7577c528 100644 --- a/source/src/serveractions.h +++ b/source/src/serveractions.h @@ -61,7 +61,7 @@ struct mapaction : serveraction bool notify = valid_client(caller); int maploc = MAP_NOTFOUND; mapstats *ms = map[0] ? getservermapstats(map, false, &maploc) : NULL; - mapok = ms != NULL && ( (mode != GMODE_COOPEDIT && mapisok(ms)) || (mode == GMODE_COOPEDIT && !readonlymap(maploc)) ); + mapok = (ms != NULL) && ( (mode != GMODE_COOPEDIT && mapisok(ms)) || (mode == GMODE_COOPEDIT && !readonlymap(maploc)) ); if(!mapok) { defformatstring(msg)("%s", ms ? ( mode == GMODE_COOPEDIT ? "this map cannot be coopedited in this server" : "sorry, but this map does not satisfy some quality requisites to be played in MultiPlayer Mode" ) : "the server does not have this map" ); diff --git a/source/src/serverchecks.h b/source/src/serverchecks.h index 537e512d..452a8877 100644 --- a/source/src/serverchecks.h +++ b/source/src/serverchecks.h @@ -93,6 +93,7 @@ int getmaxarea(int inversed_x, int inversed_y, int transposed, int ml_factor, ch int checkarea(int maplayout_factor, char *maplayout) { int area = 0, maxarea = 0; + if (!maplayout) { printf("WARNING: there is no maplayout to read in checkarea!"); return 0; } for (int i=0; i < 8; i++) { area = getmaxarea((i & 1),(i & 2),(i & 4), maplayout_factor, maplayout); if ( area > maxarea ) maxarea = area; diff --git a/source/src/serverfiles.h b/source/src/serverfiles.h index e208b837..a535a2e4 100644 --- a/source/src/serverfiles.h +++ b/source/src/serverfiles.h @@ -237,6 +237,9 @@ float Mheight = 0; bool mapisok(mapstats *ms) { + if ( Mheight > MAXMHEIGHT ) { logline(ACLOG_INFO, "MAP CHECK FAIL: The overall ceil height is too high (%d 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 ( ms->hasflags ) // Check if flags are ok { struct { short x, y; } fl[2]; @@ -253,6 +256,8 @@ bool mapisok(mapstats *ms) } else FlagFlag = MINFF * 1000; // the map has no flags + if ( FlagFlag < MINFF ) { logline(ACLOG_INFO, "MAP CHECK FAIL: The flags are too close to each other"); return false; } + for (int i = 0; i < ms->hdr.numents; i++) { int v = ms->enttypes[i]; @@ -266,7 +271,7 @@ bool mapisok(mapstats *ms) short *q = &ms->entposs[j*3]; float r2 = 0; loopk(3){ r2 += (p[k]-q[k])*(p[k]-q[k]); } - if ( r2 == 0.0f ) { logline(ACLOG_INFO, "Items too close %s %s (%hd,%hd)", entnames[v], entnames[w],p[0],p[1]); return false; } + if ( r2 == 0.0f ) { logline(ACLOG_INFO, "MAP CHECK FAIL: Items too close %s %s (%hd,%hd)", entnames[v], entnames[w],p[0],p[1]); return false; } r2 = 1/r2; if (r2 < 0.0025f) continue; if (w != v) @@ -278,10 +283,10 @@ bool mapisok(mapstats *ms) } /* if (hdensity > 0.0f) { logline(ACLOG_INFO, "ITEM CHECK H %s %f", entnames[v], hdensity); } if (density > 0.0f) { logline(ACLOG_INFO, "ITEM CHECK D %s %f", entnames[v], density); }*/ - if ( hdensity > 0.5f ) { logline(ACLOG_INFO, "Items too close %s %.2f (%hd,%hd)", entnames[v],hdensity,p[0],p[1]); return false; } + if ( hdensity > 0.5f ) { logline(ACLOG_INFO, "MAP CHECK FAIL: Items too close %s %.2f (%hd,%hd)", entnames[v],hdensity,p[0],p[1]); return false; } switch(v) { -#define LOGTHISSWITCH(X) if( density > X ) { logline(ACLOG_INFO, "Items too close %s %.2f (%hd,%hd)", entnames[v],density,p[0],p[1]); return false; } +#define LOGTHISSWITCH(X) if( density > X ) { logline(ACLOG_INFO, "MAP CHECK FAIL: Items too close %s %.2f (%hd,%hd)", entnames[v],density,p[0],p[1]); return false; } case I_CLIPS: case I_HEALTH: LOGTHISSWITCH(0.24f); break; case I_AMMO: LOGTHISSWITCH(0.04f); break; @@ -293,7 +298,7 @@ bool mapisok(mapstats *ms) #undef LOGTHISSWITCH } } - return Mheight < MAXMHEIGHT && Mopen < MAXMAREA && FlagFlag > MINFF; + return true; } struct servermaprot : serverconfigfile