diff --git a/source/src/client.cpp b/source/src/client.cpp index c9e2872d..ef9d7552 100644 --- a/source/src/client.cpp +++ b/source/src/client.cpp @@ -375,7 +375,7 @@ void c2sinfo(playerent *d) // send update to the server dz = dzt - d->vel_t.i[2], // pack rest in 1 int: strafe:2, move:2, onfloor:1, onladder: 1 f = (d->strafe&3) | ((d->move&3)<<2) | (((int)d->onfloor)<<4) | (((int)d->onladder)<<5) | ((d->lifesequence&1)<<6) | (((int)d->crouching)<<7), - g = (dx?1:0) | ((dy?1:0)<<1) | ((dz?1:0)<<2) | ((r?1:0)<<3) | (((int)d->scoping)<<4) | (((int)d->shoot)<<5); // FIXME please remove this d->shoot in the protocol update + g = (dx?1:0) | ((dy?1:0)<<1) | ((dz?1:0)<<2) | ((r?1:0)<<3) | (((int)d->scoping)<<4) | (((int)d->shoot)<<5); d->vel_t.i[0] = dxt; d->vel_t.i[1] = dyt; d->vel_t.i[2] = dzt; @@ -419,7 +419,7 @@ void c2sinfo(playerent *d) // send update to the server b.putbits(1, s == 11 ? 1 : 0); b.putbits(s, z); b.putbits(1, d->scoping ? 1 : 0); - b.putbits(1, d->shoot ? 1 : 0); // FIXME please remove this d->shoot in the protocol update + b.putbits(1, d->shoot ? 1 : 0); } else { // classic POS packet @@ -447,7 +447,6 @@ void c2sinfo(playerent *d) // send update to the server if(sendmapidenttoserver) // new map { -// spawnallitems(); this was the worst idea ever, wrong command in the wrong place p.reliable(); putint(p, SV_MAPIDENT); putint(p, maploaded); diff --git a/source/src/command.cpp b/source/src/command.cpp index cdff4836..fb15cad9 100644 --- a/source/src/command.cpp +++ b/source/src/command.cpp @@ -92,6 +92,18 @@ void pop(const char *name) COMMAND(push, ARG_2STR); COMMAND(pop, ARG_1STR); +void delalias(const char *name) +{ + ident *id = idents->access(name); + if(!id || id->type != ID_ALIAS) return; + if(contextisolated[execcontext] && execcontext > id->context) + { + conoutf("cannot remove alias %s in this execution context", id->name); + return; + } + idents->remove(name); +} +COMMAND(delalias, ARG_1STR); void alias(const char *name, const char *action) { @@ -117,6 +129,11 @@ void alias(const char *name, const char *action) COMMAND(alias, ARG_2STR); +void checkalias(const char *name) +{ + intret(getalias(name)?1:0); +} +COMMAND(checkalias, ARG_1STR); // variable's and commands are registered through globals, see cube.h int variable(const char *name, int minval, int cur, int maxval, int *storage, void (*fun)(), bool persist) @@ -165,14 +182,20 @@ void setsvar(const char *name, const char *str, bool dofunc) *id->storage.s = exchangestr(*id->storage.s, str); if(dofunc && id->fun) ((void (__cdecl *)())id->fun)(); // call trigger function if available } + void plusmin_eq(const char *name, const char *str,bool addsub) { if(!name[0] || !str[0]) return; ident *b = idents->access(name); if(b) { - _GETVAR(id, b->type, name, ); - if(b->type == ID_FVAR) {*id->storage.f = clamp(*id->storage.f+(addsub?(float)atof(str):-(float)atof(str)), id->minvalf, id->maxvalf); } - if(b->type == ID_VAR) {*id->storage.i = clamp(*id->storage.i+(addsub?(int)ATOI(str):-(int)ATOI(str)), id->minval, id->maxval); } + if(!allowidentaccess(b)) + { + conoutf("not allowed in this execution context: %s", b->name); + return; + } + + if(b->type == ID_FVAR) {*b->storage.f = clamp(*b->storage.f+(addsub?(float)atof(str):-(float)atof(str)), b->minvalf, b->maxvalf); } + if(b->type == ID_VAR) {*b->storage.i = clamp(*b->storage.i+(addsub?(int)ATOI(str):-(int)ATOI(str)), b->minval, b->maxval); } #define stringtypes(storagep,itype) \ if(b->type == itype) {\ float f=atof(storagep);int i=ATOI(storagep);float fstr=atof(str);int istr=ATOI(str);\ @@ -183,9 +206,10 @@ void plusmin_eq(const char *name, const char *str,bool addsub) }\ } - stringtypes(id->action,ID_ALIAS) - stringtypes(*id->storage.s,ID_SVAR) - if(id->fun && (b->type == ID_VAR || b->type == ID_FVAR || b->type == ID_SVAR)) ((void (__cdecl *)())id->fun)(); + stringtypes(b->action,ID_ALIAS) + stringtypes(*b->storage.s,ID_SVAR) + #undef stringtypes + if(b->fun && (b->type == ID_VAR || b->type == ID_FVAR || b->type == ID_SVAR)) ((void (__cdecl *)())b->fun)(); } else { conoutf("ident called '%s' is inexistant.",name); } diff --git a/source/src/console.cpp b/source/src/console.cpp index f85b1d28..18c4453a 100644 --- a/source/src/console.cpp +++ b/source/src/console.cpp @@ -104,14 +104,19 @@ void clientlogf(const char *s, ...) } while(p); } - +SVAR(conline,"n/a"); void conoutf(const char *s, ...) { defvformatstring(sf, s, s); clientlogf("%s", sf); con.addline(sf); + delete[] conline; conline=newstring(sf); } - +void strstra(const char *a,const char *b) { + intret(strstr(a,b)?1:0); + return; +} +COMMANDN(strstr,strstra,ARG_2STR); /** This is the 1.0.4 function It will substituted by rendercommand_wip I am putting this temporarily here because it is very difficult to chat in game with the current cursor behavior, @@ -214,7 +219,11 @@ void bindk(const char *key, const char *action) if(!km) { conoutf("unknown key \"%s\"", key); return; } bindkey(km, action); } - +void keybind(const char *key) +{ + keym *km = findbind(key); + result(km->action); +} bool bindc(int code, const char *action) { keym *km = findbindc(code); @@ -223,7 +232,7 @@ bool bindc(int code, const char *action) } COMMANDN(bind, bindk, ARG_2STR); - +COMMAND(keybind, ARG_1STR); struct releaseaction { keym *key; diff --git a/source/src/geom.h b/source/src/geom.h index 5496cce4..0672f199 100644 --- a/source/src/geom.h +++ b/source/src/geom.h @@ -26,6 +26,11 @@ inline float fACos( float x ) } #undef UFINVSQRT +inline float pow2(float x) +{ + return x*x; +} + // Fast Cosine // inspired after http://www.devmaster.net/forums/showthread.php?t=5784 #define FCOS \ diff --git a/source/src/server.cpp b/source/src/server.cpp index f8d6f146..8de00530 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -1527,6 +1527,7 @@ bool balanceteams(int ftr) // pro vs noobs never more if(mastermode != MM_OPEN || totalclients < 3 ) return true; int tsize[2] = {0, 0}, tscore[2] = {0, 0}; int totalscore = 0, nplayers = 0; + int flagmult = (m_ctf ? 20 : (m_htf ? 10 : 5)); loopv(clients) if(clients[i]->type!=ST_EMPTY) { @@ -1536,7 +1537,9 @@ bool balanceteams(int ftr) // pro vs noobs never more int time = servmillis - c->connectmillis + 5000; if ( time > gamemillis ) time = gamemillis + 5000; tsize[c->team]++; - c->eff_score = c->state.points * 60 * 1000 / time; // effective score per minute, thanks to wtfthisgame for the nice idea + // effective score per minute, thanks to wtfthisgame for the nice idea + // in a normal game, normal players will do 500 points in 10 minutes + c->eff_score = c->state.points * 60 * 1000 / time + c->state.points / 10 + c->state.flagscore * flagmult; tscore[c->team] += c->eff_score; nplayers++; totalscore += c->state.points; @@ -1742,9 +1745,6 @@ void startdemoplayback(const char *newname) setupdemoplayback(); } -int Mvolume, Marea, Mopen = 0; -float Mheight = 0; - inline void send_item_list(packetbuf &p) { putint(p, SV_ITEMLIST); diff --git a/source/src/server.h b/source/src/server.h index 0fe26407..9ec85b5b 100644 --- a/source/src/server.h +++ b/source/src/server.h @@ -272,6 +272,7 @@ struct client // server side version of "dynent" type float dda, tr, sda; int ps, ph, tcn, bdt, pws; float pr; + int yls, pls, tls; gameevent &addevent() { @@ -312,6 +313,7 @@ struct client // server side version of "dynent" type ps = ph = bdt = pws = 0; tcn = -1; pr = 0.0f; + yls = pls = tls = 0; } void reset() diff --git a/source/src/serveractions.h b/source/src/serveractions.h index 0673b11f..b0f5f7c8 100644 --- a/source/src/serveractions.h +++ b/source/src/serveractions.h @@ -33,67 +33,6 @@ void kick_abuser(int cn, int &cmillis, int &count, int limit) if( count >= limit ) disconnect_client(cn, DISC_ABUSE); } -bool mapisok(mapstats *ms) -{ - 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 - - 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, "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, "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; } - 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 Mheight < MAXMHEIGHT && (Mopen = checkarea(testlayout_factor, testlayout)) < MAXMAREA && FlagFlag > MINFF; -} - struct mapaction : serveraction { char *map; diff --git a/source/src/serverchecks.h b/source/src/serverchecks.h index 66305e13..dcd0a02c 100644 --- a/source/src/serverchecks.h +++ b/source/src/serverchecks.h @@ -3,11 +3,6 @@ inline bool is_lagging(client *cl) return ( cl->spj > 50 || cl->ping > 500 || cl->ldt > 80 ); // do not change this except if you really know what are you doing } -inline float pow2(float x) -{ - return x*x; -} - inline bool outside_border(vec &po) { return (po.x < 0 || po.y < 0 || po.x >= maplayoutssize || po.y >= maplayoutssize); @@ -36,22 +31,22 @@ inline void checkclientpos(client *cl) //FIXME /* There are smarter ways to implement this function, but must probably they will be very complex */ -int getmaxarea(int inversed_x, int inversed_y, int transposed, int maplayout_factor, char *maplayout) +int getmaxarea(int inversed_x, int inversed_y, int transposed, int ml_factor, char *ml) { - int ls = (1 << maplayout_factor); + int ls = (1 << ml_factor); int xi = 0, oxi = 0, xf = 0, oxf = 0, yi = 0, yf = 0, fx = 0, fy = 0; int area = 0, maxarea = 0; bool sav_x = false, sav_y = false; - if (transposed) fx = maplayout_factor; - else fy = maplayout_factor; + if (transposed) fx = ml_factor; + else fy = ml_factor; // walk on x for each y for ( int y = (inversed_y ? ls-1 : 0); (inversed_y ? y >= 0 : y < ls); (inversed_y ? y-- : y++) ) { /* Analyzing each cube of the line */ for ( int x = (inversed_x ? ls-1 : 0); (inversed_x ? x >= 0 : x < ls); (inversed_x ? x-- : x++) ) { - if ( maplayout[ ( x << fx ) + ( y << fy ) ] != 127 ) { // if it is not solid + if ( ml[ ( x << fx ) + ( y << fy ) ] != 127 ) { // if it is not solid if ( sav_x ) { // if the last cube was saved xf = x; // new end for this line } @@ -95,7 +90,8 @@ int getmaxarea(int inversed_x, int inversed_y, int transposed, int maplayout_fac return maxarea; } -int checkarea(int maplayout_factor, char *maplayout) { +int checkarea(int maplayout_factor, char *maplayout) +{ int area = 0, maxarea = 0; for (int i=0; i < 8; i++) { area = getmaxarea((i & 1),(i & 2),(i & 4), maplayout_factor, maplayout); @@ -369,8 +365,6 @@ void computeteamwork(int team, int exclude) // testing } } -int FlagFlag = MINFF * 1000; - float a2c = 0, c2t = 0, a2t = 0; // distances: actor to covered, covered to target and actor to target inline bool testcover(int msg, int factor, client *actor) diff --git a/source/src/serverfiles.h b/source/src/serverfiles.h index 551f162b..77661d01 100644 --- a/source/src/serverfiles.h +++ b/source/src/serverfiles.h @@ -233,6 +233,71 @@ struct configset }; }; +int FlagFlag = MINFF * 1000; +int Mvolume, Marea, Mopen = 0; +float Mheight = 0; + +bool mapisok(mapstats *ms) +{ + 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 + + 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, "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, "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; } + 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 Mheight < MAXMHEIGHT && Mopen < MAXMAREA && FlagFlag > MINFF; +} + struct servermaprot : serverconfigfile { vector configsets; @@ -301,8 +366,9 @@ struct servermaprot : serverconfigfile c = &configsets[ccs]; if((n >= c->minplayer || i >= csl) && (!c->maxplayer || n <= c->maxplayer || i >= 2 * csl)) { - if(getservermapstats(c->mapname)) break; - else logline(ACLOG_INFO, "maprot error: map '%s' not found", c->mapname); + mapstats *ms = NULL; + 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")); } 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 fa6cc250..5cd523b0 100644 --- a/source/src/tools.cpp +++ b/source/src/tools.cpp @@ -25,8 +25,9 @@ const char *numtime() } extern char *maplayout, *testlayout; -extern int maplayout_factor, testlayout_factor, Mvolume, Marea; +extern int maplayout_factor, testlayout_factor, Mvolume, Marea, Mopen; extern float Mheight; +extern int checkarea(int, char *); mapstats *loadmapstats(const char *filename, bool getlayout) { @@ -126,7 +127,11 @@ mapstats *loadmapstats(const char *filename, bool getlayout) t = c; } if(fail) { DELETEA(testlayout); } - else Mheight = Marea ? (float)Mvolume/Marea : 0; + else + { + Mheight = Marea ? (float)Mvolume/Marea : 0; + Mopen = checkarea(testlayout_factor, testlayout); + } } if(getlayout) { diff --git a/source/src/weapon.cpp b/source/src/weapon.cpp index 1cad9d6e..1f8d060a 100644 --- a/source/src/weapon.cpp +++ b/source/src/weapon.cpp @@ -652,8 +652,8 @@ int weapon::flashtime() const { return max((int)info.attackdelay, 120)/4; } void weapon::sendshoot(vec &from, vec &to) { if(owner!=player1) return; + owner->shoot = true; addmsg(SV_SHOOT, "ri2i3iv", lastmillis, owner->weaponsel->type, -// (int)(from.x*DMF), (int)(from.y*DMF), (int)(from.z*DMF), (int)(to.x*DMF), (int)(to.y*DMF), (int)(to.z*DMF), hits.length(), hits.length()*sizeof(hitmsg)/sizeof(int), hits.getbuf()); } @@ -1093,7 +1093,6 @@ bool gun::attack(vec &targ) mag--; sendshoot(from, to); - owner->shoot = true; return true; } @@ -1384,14 +1383,14 @@ int knife::flashtime() const { return 0; } bool knife::attack(vec &targ) { int attackmillis = lastmillis-owner->lastaction; - if(attackmillisattacking) return false; updatelastaction(owner); owner->lastattackweapon = this; - owner->attacking = false; + owner->attacking = false; vec from = owner->o; vec to = targ;