From 2f55903ad0dbca25cc1be42089bc212f4a787329 Mon Sep 17 00:00:00 2001 From: Lucas GAUTHERON Date: Mon, 27 May 2013 17:25:21 +0000 Subject: [PATCH] messy patch tmp revert git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@7491 e016b1c5-ed68-44aa-a2f7-31cac88cffde --- source/src/server.cpp | 6 +- source/src/server.h | 2 +- source/src/serveractions.h | 7 +-- source/src/serverfiles.h | 77 +++++++++++++++++++++++- source/src/tools.cpp | 118 ++++++------------------------------- source/src/world.h | 45 -------------- 6 files changed, 98 insertions(+), 157 deletions(-) diff --git a/source/src/server.cpp b/source/src/server.cpp index c41b671e..1ff3de15 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -1413,7 +1413,7 @@ bool serverpickup(int i, int sender) // server side item pickup, acknowl if(cl->type==ST_TCPIP) { if( cl->state.state!=CS_ALIVE || !cl->state.canpickup(e.type) || ( m_arena && !free_items(sender) ) ) return false; - vec v(e.x, e.y, float(SS(e.x, e.y)->floor) + float(e.elevation)); + vec v(e.x, e.y, cl->state.o.z); float dist = cl->state.o.dist(v); int pdist = check_pdist(cl,dist); if (pdist) @@ -1955,12 +1955,12 @@ void startgame(const char *newname, int newmode, int newtime, bool notify) { e.type = smapstats.enttypes[i]; e.transformtype(smode); - server_entity se = { e.type, false, false, false, 0, smapstats.entposs[i * 3], smapstats.entposs[i * 3 + 1], smapstats.entposs[i * 3 + 2] }; + server_entity se = { e.type, false, false, false, 0, smapstats.entposs[i * 3], smapstats.entposs[i * 3 + 1]}; sents.add(se); if(e.fitsmode(smode)) sents[i].spawned = sents[i].legalpickup = true; } mapbuffer.setrevision(); - logline(ACLOG_INFO, "Map height density information for %s: AvgHeight = %.2f Vol = %d, Area = %d and MxOpenArea = %d", smapname, ms->height, ms->volume, ms->area, ms->maxopenarea); + logline(ACLOG_INFO, "Map height density information for %s: H = %.2f V = %d, A = %d and MA = %d", smapname, Mheight, Mvolume, Marea, Mopen); items_blocked = false; } else if(isdedicated) sendservmsg("\f3server error: map not found - please start another map or send this map to the server"); diff --git a/source/src/server.h b/source/src/server.h index 8889496e..6b9cf912 100644 --- a/source/src/server.h +++ b/source/src/server.h @@ -371,7 +371,7 @@ struct server_entity // server side version of "entity" type int type; bool spawned, legalpickup, twice; int spawntime; - short x, y, elevation; + short x, y; }; struct clientidentity diff --git a/source/src/serveractions.h b/source/src/serveractions.h index 9cd5b97f..2b2e1419 100644 --- a/source/src/serveractions.h +++ b/source/src/serveractions.h @@ -65,12 +65,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 && !readonlymap(maploc); - if(ms && mode != GMODE_COOPEDIT && !ms->goodmap) - { - mapok = false; - loopv(ms->errors) if(ms->errors[i]) logline(ACLOG_INFO, "map check fail: %s", ms->errors[i]); - } + mapok = (ms != NULL) && ( (mode != GMODE_COOPEDIT && mapisok(ms)) || (mode == GMODE_COOPEDIT && !readonlymap(maploc)) ); if(!mapok) { if(notify) sendservmsg(ms ? diff --git a/source/src/serverfiles.h b/source/src/serverfiles.h index 36170c55..78774b2e 100644 --- a/source/src/serverfiles.h +++ b/source/src/serverfiles.h @@ -232,6 +232,75 @@ struct configset }; int FlagFlag = MINFF * 1000; +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 ) { 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 + { + struct { short x, y; } fl[2]; + loopi(2) + { + if(ms->flags[i] == 1) + { + short *fe = ms->entposs + ms->flagents[i] * 3; + fl[i].x = *fe; fe++; fl[i].y = *fe; + } + else fl[i].x = fl[i].y = 0; // the map has no valid flags + } + FlagFlag = pow2(fl[0].x - fl[1].x) + pow2(fl[0].y - fl[1].y); + } + 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]; + if (v < I_CLIPS || v > I_AKIMBO) continue; + short *p = &ms->entposs[i*3]; + float density = 0, hdensity = 0; + for(int j = 0; j < ms->hdr.numents; j++) + { + int w = ms->enttypes[j]; + if (w < I_CLIPS || w > I_AKIMBO || i == j) continue; + 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, "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) + { + hdensity += r2; + continue; + } + density += r2; + } +/* 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, "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, "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; + case I_HELMET: LOGTHISSWITCH(0.02f); break; + case I_ARMOUR: + case I_GRENADE: + case I_AKIMBO: LOGTHISSWITCH(0.005f); break; + default: break; +#undef LOGTHISSWITCH + } + } + return true; +} struct servermaprot : serverconfigfile { @@ -302,8 +371,12 @@ struct servermaprot : serverconfigfile if((n >= c->minplayer || i >= csl) && (!c->maxplayer || n <= c->maxplayer || i >= 2 * csl)) { mapstats *ms = NULL; - if((ms = getservermapstats(c->mapname)) && ms->goodmap) break; - else logline(ACLOG_INFO, "maprot error: map '%s' %s", c->mapname, (ms ? "does not satisfy some basic requirements" : "not found")); + if((ms = getservermapstats(c->mapname)) && mapisok(ms)) break; + else + { + logline(ACLOG_INFO, "maprot error: map '%s' %s", c->mapname, (ms ? "does not satisfy some basic requirements" : "not found")); + loopv(ms->errors) if(ms->errors[i]) logline(ACLOG_INFO, "map check fail: %s", ms->errors[i]); + } } if(i >= 3 * csl) fatal("maprot unusable"); // not a single map in rotation can be found... } diff --git a/source/src/tools.cpp b/source/src/tools.cpp index e559403b..a65c4628 100644 --- a/source/src/tools.cpp +++ b/source/src/tools.cpp @@ -27,7 +27,8 @@ 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; +extern int maplayout_factor, testlayout_factor, Mvolume, Marea, Mopen, SHhits; +extern float Mheight; extern int checkarea(int, char *); mapstats *loadmapstats(const char *filename, bool getlayout) @@ -66,7 +67,7 @@ mapstats *loadmapstats(const char *filename, bool getlayout) if(e.type == CTF_FLAG && (e.attr2 == 0 || e.attr2 == 1)) { s.flags[e.attr2]++; s.flagents[e.attr2] = i; } s.entcnt[e.type]++; enttypes[i] = e.type; - entposs[i * 3] = e.x; entposs[i * 3 + 1] = e.y; entposs[i * 3 + 2] = e.attr1; + entposs[i * 3] = e.x; entposs[i * 3 + 1] = e.y; entposs[i * 3 + 2] = e.z + e.attr1; } DELETEA(testlayout); int minfloor = 0; @@ -78,14 +79,13 @@ mapstats *loadmapstats(const char *filename, bool getlayout) bool fail = false; testlayout = new char[layoutsize + 256]; memset(testlayout, 0, layoutsize * sizeof(char)); - ssqr *t = NULL; + char *t = NULL; char floor = 0, ceil; int diff = 0; - s.initworld(); + Mvolume = Marea = SHhits = 0; loopk(layoutsize) { char *c = testlayout + k; - ssqr *ss = &s.serverworld[k]; int type = f->getchar(); int n = 1; switch(type) @@ -93,23 +93,20 @@ mapstats *loadmapstats(const char *filename, bool getlayout) case 255: { if(!t || (n = f->getchar()) < 0) { fail = true; break; } - char tmp = *(c-1); - memset(c, tmp, n); - for(int i = 0; igetchar(); f->getchar(); break; default: if(type<0 || type>=MAXTYPE) { fail = true; break; } - ss->type = type; - ss->floor = floor = f->getchar(); - ss->ceil = ceil = f->getchar(); - if(floor >= ceil && ceil > -128) ss->floor = floor = ceil - 1; // for pre 12_13 + floor = f->getchar(); + ceil = f->getchar(); + if(floor >= ceil && ceil > -128) floor = ceil - 1; // for pre 12_13 diff = ceil - floor; if(type == FHF) floor = -128; if(floor!=-128 && floorgetchar(); f->getchar(); if(s.hdr.version>=2) f->getchar(); if(s.hdr.version>=5) f->getchar(); - *c = ss->floor; + case SOLID: - ss->type = SOLID; *c = type == SOLID ? 127 : floor; f->getchar(); f->getchar(); if(s.hdr.version<=2) { f->getchar(); f->getchar(); } @@ -128,18 +124,18 @@ mapstats *loadmapstats(const char *filename, bool getlayout) if ( type != SOLID && diff > 6 ) { // Lucas (10mar2013): Removed "pow2" because it was too strict - if (diff > MAXMHEIGHT) s.heighthits += /*pow2*/(diff-MAXMHEIGHT)*n; // linear is more permissive - s.area += n; - s.volume += diff * n; + if (diff > MAXMHEIGHT) SHhits += /*pow2*/(diff-MAXMHEIGHT)*n; + Marea += n; + Mvolume += diff * n; } if(fail) break; - t = ss; + t = c; } if(fail) { DELETEA(testlayout); } else { - s.height = s.area ? float(s.volume)/s.area : 0; - s.maxopenarea = checkarea(testlayout_factor, testlayout); + Mheight = Marea ? (float)Mvolume/Marea : 0; + Mopen = checkarea(testlayout_factor, testlayout); } } if(getlayout) @@ -176,87 +172,9 @@ mapstats *loadmapstats(const char *filename, bool getlayout) s.enttypes = enttypes; s.entposs = entposs; s.cgzsize = getfilesize(filename); - s.mapcheck(); return &s; } -#define logmaperror(format, ...) { if(this->errors.length() >= 20) return false; \ - formatstring(error)(format, __VA_ARGS__); \ - this->errors.add(newstring(error)); \ - this->goodmap = false; } \ - -bool mapstats::mapcheck() -{ - this->goodmap = true; - this->errors.deletearrays(); - string error; - if(this->height > MAXMHEIGHT) logmaperror("The overall ceil height is too high (%.1f cubes)", this->height); - if(this->maxopenarea > MAXMAREA) logmaperror("There is a big open area in this map (%d cubes*cubes) (hint: use more solid walls)", this->maxopenarea); - if(this->heighthits > MAXHHITS) logmaperror("Too high height in some parts of the map (%d hits)", this->heighthits); - - if (this->hasflags) // Check if flags are ok - { - struct { short x, y; } fl[2]; - loopi(2) - { - if(this->flags[i] == 1) - { - short *fe = this->entposs + this->flagents[i] * 3; - fl[i].x = *fe; fe++; fl[i].y = *fe; - } - else fl[i].x = fl[i].y = 0; // the map has no valid flags - } - float FlagFlag = pow2(fl[0].x - fl[1].x) + pow2(fl[0].y - fl[1].y); - - if (FlagFlag < MINFF) logmaperror("The flags are too close to each other (distance = %.1f, min required = %.1f)", sqrt(FlagFlag), sqrt(float(MINFF))); - } - //else FlagFlag = MINFF * 1000; // the map has no flags - - for (int i = 0; i < this->hdr.numents; i++) - { - int v = this->enttypes[i]; - if (v < I_CLIPS || v > I_AKIMBO) continue; - short *p = &this->entposs[i*3]; - float density = 0, hdensity = 0; - for(int j = 0; j < this->hdr.numents; j++) - { - int w = this->enttypes[j]; - if (w < I_CLIPS || w > I_AKIMBO || i == j) continue; - short *q = &this->entposs[j*3]; - float pz = SWS(serverworld, p[0], p[1], hdr.sfactor)->floor, - qz = SWS(serverworld, q[0], q[1], hdr.sfactor)->floor; - float r2 = (vec(p[0], p[1], p[2] + pz).sub(vec(q[0], q[1], q[2] + qz))).squaredlen(); - if ( r2 == 0.0f) logmaperror("Items too close %s %s (%hd,%hd)", entnames[v], entnames[w], p[0], p[1]); - r2 = 1/r2; - if (r2 < 0.0025f) continue; - if (w != v) - { - hdensity += r2; - continue; - } - density += r2; - } -/* 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) logmaperror("Items too close %s %.2f (%hd,%hd)", entnames[v],hdensity,p[0],p[1]); - switch(v) - { -#define LOGTHISSWITCH(X) if( density > X ) logmaperror("Items too close %s %.2f (%hd,%hd)", entnames[v],density,p[0],p[1]); - case I_CLIPS: - case I_HEALTH: LOGTHISSWITCH(0.24f); break; - case I_AMMO: LOGTHISSWITCH(0.04f); break; - case I_HELMET: LOGTHISSWITCH(0.02f); break; - case I_ARMOUR: - case I_GRENADE: - case I_AKIMBO: LOGTHISSWITCH(0.005f); break; - default: break; -#undef LOGTHISSWITCH - } - } - return this->goodmap; -} -#undef logmaperror - ///////////////////////// debugging /////////////////////// #if defined(WIN32) && !defined(_DEBUG) && !defined(__GNUC__) diff --git a/source/src/world.h b/source/src/world.h index fec822ed..41e819ac 100644 --- a/source/src/world.h +++ b/source/src/world.h @@ -23,13 +23,6 @@ struct sqr uchar reserved[2]; }; -// simplified square -struct ssqr -{ - uchar type; - char floor, ceil; -}; - enum // hardcoded texture numbers { DEFAULT_SKY = 0, @@ -71,40 +64,6 @@ struct mapstats bool hasffaspawns; bool hasteamspawns; bool hasflags; - - int area, volume; - float height; // average height - int heighthits; // sum (height-maxheight) for each cube if height > maxheight - int numheighthits; // number of cubes with height > maxheight - int maxopenarea; // biggest open area - bool goodmap; // pass requirements ? - vector errors; - ssqr *serverworld; - - void initworld() - { - DELETEA(serverworld); - int size = 1 << (hdr.sfactor*2); - serverworld = new ssqr[size]; - memset(serverworld, 0, size*sizeof(ssqr)); - loopi(size) - { - ssqr *ss = &serverworld[i]; - if(!ss) continue; - ss->floor = 0; - ss->ceil = 16; - ss->type = SOLID; - } - - volume = area = heighthits = numheighthits = 0; - } - - bool mapstats::mapcheck(); - - ~mapstats() - { - DELETEA(serverworld); - } }; #define TRANSFORMOLDENTITIES(headr) \ @@ -158,10 +117,6 @@ struct mapstats #define SWS(w,x,y,s) (&(w)[((y)<<(s))+(x)]) #define SW(w,x,y) SWS(w,x,y,sfactor) #define S(x,y) SW(world,x,y) // convenient lookup of a lowest mip cube - -#define SSW(w,x,y) SWS(w,x,y,smapstats.hdr.sfactor) -#define SS(x,y) SSW(smapstats.serverworld,x,y) - #define SMALLEST_FACTOR 6 // determines number of mips there can be #define DEFAULT_FACTOR 8 #define LARGEST_FACTOR 11 // 10 is already insane