diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index db60f781..9ba95c5c 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -242,7 +242,7 @@ void showhudextras(char hudextras, char value){ case HE_COMBO5: { int n = value - HE_COMBO; - if (n > 3) outf("\f3%s",SSPAM("monster combo!!!")); + if (n > 3) outf("\f3%s",SSPAM("monster combo!!!")); // I expect to never see this one else if (!n) outf("\f5%s",SSPAM("combo")); else outf("\f5%s x%d",SSPAM("multi combo"),n+1); break; @@ -261,8 +261,8 @@ void showhudextras(char hudextras, char value){ } default: { - if (value >= 100) { // beware here! this value is linked to checkteamplay::serverchecks.h value - teamworkid = value-100; + if (value >= HE_NUM) { + teamworkid = value - HE_NUM; playerent *p = getclient(teamworkid); if (!p || p == player1) teamworkid = -1; else outf("\f4you replied to %s",p->name); diff --git a/source/src/protocol.cpp b/source/src/protocol.cpp index d67099ef..ece97833 100644 --- a/source/src/protocol.cpp +++ b/source/src/protocol.cpp @@ -339,7 +339,7 @@ static const int msgsizes[] = // size inclusive message token, 0 f SV_SWITCHNAME, 0, SV_SWITCHSKIN, 0, SV_SWITCHTEAM, 0, SV_CLIENT, 0, SV_EXTENSION, 0, - SV_MAPIDENT, 3, SV_HUDEXTRAS, 1, SV_POINTS, 0, + SV_MAPIDENT, 3, SV_HUDEXTRAS, 2, SV_POINTS, 0, -1 }; diff --git a/source/src/server.cpp b/source/src/server.cpp index 3f2dc1a1..009abedd 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -357,13 +357,15 @@ void sendextras() client &c = *clients[i]; if ( c.type!=ST_TCPIP || !c.isauthed || !(c.md.updated && c.md.upmillis < gamemillis) ) continue; if ( c.md.combosend ) { - sendf(c.clientnum, 1, "ri2", SV_HUDEXTRAS, c.md.combo-1 + HE_COMBO); + sendf(c.clientnum, 1, "ri2", SV_HUDEXTRAS, min(c.md.combo,c.md.combofrags)-1 + HE_COMBO); c.md.combosend = false; } - list[count] = i; - count++; + if ( c.md.dpt ) { + list[count] = i; + count++; + } } - nextsendscore = gamemillis + 200; + nextsendscore = gamemillis + 160; // about 4 cicles if ( !count ) return; packetbuf p(MAXTRANS, ENET_PACKET_FLAG_RELIABLE); @@ -730,6 +732,8 @@ void flagmessage(int flag, int message, int actor, int cn = -1) sendf(cn, 1, "riiii", SV_FLAGMSG, flag, message, actor); } +#include "serverchecks.h" // this is temporary, and will be let here for now for compatibility issues + void flagaction(int flag, int action, int actor) { if(!valid_flag(flag)) return; @@ -840,8 +844,10 @@ void flagaction(int flag, int action, int actor) } if(score) { - clients[actor]->state.flagscore += score; - sendf(-1, 1, "riii", SV_FLAGCNT, actor, clients[actor]->state.flagscore); + client *c = clients[actor]; + c->state.flagscore += score; + sendf(-1, 1, "riii", SV_FLAGCNT, actor, c->state.flagscore); +// if (m_teammode) computeteamwork(c->team, c->clientnum); WIP } if(valid_client(actor)) { @@ -962,8 +968,6 @@ void htf_forceflag(int flag) f.lastupdate = gamemillis; } -#include "serverchecks.h" // this is temporary, and will be let here for now for compatibility issues - int arenaround = 0, arenaroundstartmillis = 0; struct twoint { int index, value; }; @@ -2410,7 +2414,7 @@ void process(ENetPacket *packet, int sender, int chan) else cl->spam++; // the guy is spamming cl->lastvc = servmillis; // register if ( cl->spam > 4 ) { cl->mute = servmillis + 10000; break; } // 5 vcs in less than 20 seconds... shut up please - if ( m_teammode ) checkteamplay(s,sender); // finally here we check the teamplay + if ( m_teammode ) checkteamplay(s,sender); // finally here we check the teamplay comm if ( type == SV_VOICECOM ) { QUEUE_MSG; } else sendvoicecomteam(s, sender); } @@ -2542,6 +2546,7 @@ void process(ENetPacket *packet, int sender, int chan) if((cl->state.state!=CS_ALIVE && cl->state.state!=CS_DEAD) || ls!=cl->state.lifesequence || cl->state.lastspawn<0 || gunselect<0 || gunselect>=NUMGUNS) break; cl->state.lastspawn = -1; cl->state.spawn = gamemillis; + cl->upspawnp = false; cl->state.state = CS_ALIVE; cl->state.gunselect = gunselect; QUEUE_BUF( @@ -2703,10 +2708,13 @@ void process(ENetPacket *packet, int sender, int chan) int usefactor = q.getbits(2) + 7; int xt = q.getbits(usefactor + 4); int yt = q.getbits(usefactor + 4); - q.getbits(9 + 8); + int val[3]; + val[0] = q.getbits(9); + val[1] = q.getbits(8); if(!q.getbits(1)) q.getbits(6); if(!q.getbits(1)) q.getbits(4 + 4 + 4); int f = q.getbits(8); + val[2] = f; int negz = q.getbits(1); int zfull = q.getbits(1); int s = q.rembits(); @@ -2726,6 +2734,7 @@ void process(ENetPacket *packet, int sender, int chan) while(curmsgposition.add(p.buf[curmsg++]); } if(maplayout && !m_demo && !m_coop) checkclientpos(cl); + checkmove(cn, val); break; } diff --git a/source/src/server.h b/source/src/server.h index f3dc3abf..5161a768 100644 --- a/source/src/server.h +++ b/source/src/server.h @@ -197,15 +197,19 @@ struct savedscore struct medals { - int dpt, lasthit, lastgun, combohits, combo, combotime, combodamage, ncombos, ncovers, nhs; + int dpt, lasthit, lastgun, ncovers, nhs; + int combohits, combo, combofrags, combotime, combodamage, ncombos; int ask, askmillis, linked, linkmillis, linkreason, upmillis; bool updated, combosend; + vec pos; void reset() { - dpt = lasthit = lastgun = combohits = combo = combotime = combodamage = ncombos = ncovers = nhs = 0; + dpt = lasthit = lastgun = ncovers = nhs = 0; + combohits = combo = combofrags = combotime = combodamage = ncombos = 0; askmillis = linkmillis = upmillis = 0; linkreason = linked = ask = -1; updated = combosend = false; + pos = vec(-1e10f, -1e10f, -1e10f); } }; @@ -247,6 +251,8 @@ struct client // server side version of "dynent" type int mapcollisions, farpickups; enet_uint32 bottomRTT; medals md; + bool upspawnp; + vec spawnp; gameevent &addevent() { @@ -273,6 +279,8 @@ struct client // server side version of "dynent" type at3_lastforce = 0; mapcollisions = farpickups = 0; md.reset(); + upspawnp = false; + spawnp = vec(-1e10f, -1e10f, -1e10f); } void reset() diff --git a/source/src/serverchecks.h b/source/src/serverchecks.h index c09f071f..48f33b0f 100644 --- a/source/src/serverchecks.h +++ b/source/src/serverchecks.h @@ -86,7 +86,7 @@ inline void addpt(client *c, int points) { c->state.points += points; c->md.dpt += points; c->md.updated = true; - c->md.upmillis = gamemillis + 200; + c->md.upmillis = gamemillis + 240; // about 2 AR shots } inline int minhits2combo(int gun) @@ -111,7 +111,7 @@ void checkcombo (client *target, client *actor, int damage, int gun) return; } - if ( diffhittime < 750 ) { + if ( diffhittime < 800 ) { if ( gun == actor->md.lastgun ) { if ( diffhittime * 2 < guns[gun].attackdelay * 3 ) { actor->md.combohits++; @@ -140,32 +140,35 @@ void checkcombo (client *target, client *actor, int damage, int gun) } } } else { - actor->md.combo=0; - actor->md.combotime=0; - actor->md.combodamage=0; - actor->md.combohits=0; + actor->md.combo = 0; + actor->md.combofrags = 0; + actor->md.combotime = 0; + actor->md.combodamage = 0; + actor->md.combohits = 0; } actor->md.lastgun = gun; } #define COVERDIST 2000 // about 45 cubes +#define REPLYDIST 8000 // about 90 cubes int checkteamrequests(int sender) { - float bestdist = COVERDIST * 1000; + int dtime, besttime = -1; int bestid = -1; client *ant = clients[sender]; loopv(clients) { client *prot = clients[i]; - if ( i!=sender && prot->type!=ST_EMPTY && prot->team==ant->team && prot->md.ask>=0 && prot->md.askmillis + 5000 > gamemillis ) { + if ( i!=sender && prot->type != ST_EMPTY && prot->team == ant->team && + prot->state.state == CS_ALIVE && prot->md.askmillis > gamemillis && prot->md.ask >= 0 ) { float dist = POW2XY(ant->state.o,prot->state.o); - if (dist < bestdist) { + if ( dist < REPLYDIST && (dtime=prot->md.askmillis-gamemillis) > besttime) { bestid = i; - bestdist = dist; + besttime = dtime; } } } - if ( bestdist < MINFF ) return bestid; + if ( besttime >= 0 ) return bestid; return -1; } @@ -173,22 +176,37 @@ int checkteamrequests(int sender) void checkteamplay(int s, int sender) { client *actor = clients[sender]; + + if ( actor->state.state != CS_ALIVE ) return; switch(s){ + case S_IMONDEFENSE: + if ( actor->md.linkmillis + 10000 < gamemillis ) addpt(actor,1); + actor->md.linkmillis = gamemillis + 20000; + actor->md.linkreason = s; + break; case S_COVERME: case S_STAYTOGETHER: actor->md.ask = s; - actor->md.askmillis = gamemillis; + if ( actor->md.askmillis + 10000 < gamemillis ) addpt(actor,1); + actor->md.askmillis = gamemillis + 5000; break; case S_AFFIRMATIVE: case S_ALLRIGHTSIR: case S_YES: { int id = checkteamrequests(sender); - if (id >= 0) { + if ( id >= 0 ) { + client *sgt = clients[id]; actor->md.linked = id; - actor->md.linkmillis = gamemillis; - actor->md.linkreason = s; - sendf(actor->clientnum, 1, "ri2", SV_HUDEXTRAS, 100+id); + if ( actor->md.linkmillis < gamemillis ) addpt(actor,2); + actor->md.linkmillis = gamemillis + 30000; + actor->md.linkreason = sgt->md.ask; + sendf(actor->clientnum, 1, "ri2", SV_HUDEXTRAS, HE_NUM+id); + switch( actor->md.linkreason ) { + case S_STAYHERE: + actor->md.pos = sgt->state.o; + break; + } } break; } @@ -205,7 +223,6 @@ void checkteamplay(int s, int sender) case S_IGOTONE: case S_IMADECONTACT: case S_IMATTACKING: - case S_IMONDEFENSE: case S_IMONYOURTEAMMAN: case S_RECOVERTHEFLAG: case S_SORRY: @@ -216,6 +233,37 @@ void checkteamplay(int s, int sender) } } +void computeteamwork(int team, int exclude) // testing +{ + loopv(clients) { + client *actor = clients[i]; + if ( i == exclude || actor->type == ST_EMPTY || actor->team != team || actor->state.state != CS_ALIVE || actor->md.linkmillis < gamemillis ) continue; + vec position; + bool teamworkdone = false; + switch( actor->md.linkreason ) { + case S_IMONDEFENSE: + position = actor->spawnp; + teamworkdone = true; + break; + case S_STAYTOGETHER: + if ( valid_client(actor->md.linked) ) position = clients[actor->md.linked]->state.o; + teamworkdone = true; + break; + case S_STAYHERE: + position = actor->md.pos; + teamworkdone = true; + break; + } + if ( teamworkdone ) { + float dist = POW2XY(actor->state.o,position); + if (dist < COVERDIST) { + addpt(actor,3); + sendf(actor->clientnum, 1, "ri2", SV_HUDEXTRAS, HE_TEAMWORK); + } + } + } +} + int FlagFlag = MINFF * 1000; float a2c = 0, c2t = 0, a2t = 0; // distances: actor to covered, covered to target and actor to target @@ -236,7 +284,7 @@ inline void testcover(int msg, int factor, client *actor) bool validlink (client *actor, int cn) { - return actor->md.linked >= 0 && actor->md.linked == cn && gamemillis < actor->md.linkmillis + 20000 && valid_client(actor->md.linked); + return actor->md.linked >= 0 && actor->md.linked == cn && gamemillis < actor->md.linkmillis && valid_client(actor->md.linked); } /** WIP */ @@ -320,7 +368,10 @@ void checkfrag (client *target, client *actor, int gun, bool gib) } else addpt(actor, 10); - if ( actor->md.combo ) actor->md.combosend = true; + if ( actor->md.combo ) { + actor->md.combofrags++; + actor->md.combosend = true; + } } else { @@ -350,6 +401,11 @@ If you know nothing about these detections, please, just ignore it. inline void checkmove (int cn, int *v) { + client *cl = clients[cn]; + if ( !cl->upspawnp ) { + cl->spawnp = cl->state.o; + cl->upspawnp = true; + } return; }