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(curmsg
position.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;
}