cover teammates who ask for it (teamwork rewarded)

git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@5083 e016b1c5-ed68-44aa-a2f7-31cac88cffde
This commit is contained in:
Rafael Barreto
2010-05-27 22:08:05 +00:00
parent 5bd1e8867e
commit d4e40cb521
4 changed files with 152 additions and 18 deletions
+41 -6
View File
@@ -225,20 +225,55 @@ bool good_map()
return checked;
}
VARP(hudextras, 0, 0, 2);
VARP(hudextras, 0, 0, 3);
char *stolower(const char *s, char *o)
{
char *c = (char *)s; int n = 0;
char *r = o;
c++; o++;
while( *c!='\0' && n < 40 ) {
*o = tolower(*c);
n++; o++; c++;
}
*o='\0';
return r;
}
char *stoupper(const char *s, char *o)
{
char *c = (char *)s; int n = 0;
char *r = o;
while( *c!='\0' && n < 40 ) {
*o = toupper(*c);
n++; o++; c++;
}
*o='\0';
return r;
}
void showhudextras(char hudextras, char value){
void (*outf)(const char *s, ...) = (hudextras == 2 ? hudoutf : conoutf);
void (*outf)(const char *s, ...) = (hudextras > 1 ? hudoutf : conoutf);
char *(*spam)(const char *s, char *o) = (hudextras == 2 ? stolower : stoupper);
char o[50];
switch(value)
{
case HE_COMBO:
outf("\f2COMBO"); break;
outf("\f2%s",spam("COMBO",o)); break;
case HE_FLAGDEFENDED:
outf("\f2FLAG DEFENDED"); break;
outf("\f2%s",spam("FLAG DEFENDED",o)); break;
case HE_FLAGCOVERED:
outf("\f2FLAG COVERED"); break;
outf("\f2%s",spam("FLAG COVERED",o)); break;
case HE_COVER:
outf("\f2%s",spam("TEAMMATE COVERED",o)); break;
default:
outf("\f2Update your client, NOOB!"); break;
{
if (value >= 100) { // beware here! this value is linked to checkteamplay::serverchecks.h value
outf("\f2Replied to %s",players[value-100]->name);
}
else outf("\f2Update your client, NOOB!");
break;
}
}
}
+14 -5
View File
@@ -2367,12 +2367,21 @@ void process(ENetPacket *packet, int sender, int chan)
}
case SV_VOICECOM:
getint(p);
QUEUE_MSG;
break;
case SV_VOICECOMTEAM:
sendvoicecomteam(getint(p), sender);
{
int s = getint(p);
/* spam filter */
if ( servmillis > cl->mute ) { // client is not muted
if( s < S_AFFIRMATIVE || s > S_NICESHOT ) cl->mute = servmillis + 10000; // vc is invalid
else if ( cl->lastvc + 4000 < servmillis ) { if ( cl->spam > 0 ) cl->spam -= (servmillis - cl->lastvc) / 4; } // no vc in the last 4 seconds
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 ( type == SV_VOICECOM ) { QUEUE_MSG; }
else sendvoicecomteam(s, sender);
}
}
break;
case SV_MAPIDENT:
+5
View File
@@ -207,6 +207,7 @@ struct client // server side version of "dynent" type
int vote;
int role;
int connectmillis;
int mute, spam, lastvc; // server side voice comm spam control
int acversion, acbuildtype;
bool isauthed; // for passworded servers
bool haswelcome;
@@ -231,6 +232,7 @@ struct client // server side version of "dynent" type
enet_uint32 bottomRTT;
int points, lasthit, lastgun, combohits, combo, combotime, combodamage, ncombos, ncovers, nhs;
int ask, askmillis, linked, linkmillis, linkreason;
gameevent &addevent()
{
@@ -257,6 +259,8 @@ struct client // server side version of "dynent" type
at3_lastforce = 0;
mapcollisions = farpickups = 0;
points = lasthit = lastgun = combohits = combo = combotime = combodamage = ncombos = ncovers = nhs = 0;
askmillis = linkmillis = 0;
linkreason = linked = ask = -1;
}
void reset()
@@ -277,6 +281,7 @@ struct client // server side version of "dynent" type
spectcn = FPCN_VOID;
mapchange();
freshgame = false; // don't spawn into running games
mute = spam = lastvc = 0;
}
void zap()
+92 -7
View File
@@ -142,9 +142,77 @@ void checkcombo (client *target, client *actor, int damage, int gun)
actor->lastgun = gun;
}
int FlagFlag = MINFF * 1000;
#define COVERDIST 2000 // about 45 cubes
int checkteamrequests(int sender)
{
float bestdist = COVERDIST * 1000;
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->ask>=0 && prot->askmillis + 5000 > gamemillis ) {
float dist = POW2XY(ant->state.o,prot->state.o);
if (dist < bestdist) {
bestid = i;
bestdist = dist;
}
}
}
if ( bestdist < MINFF ) return bestid;
return -1;
}
/** WIP */
void checkteamplay(int s, int sender)
{
client *actor = clients[sender];
switch(s){
case S_COVERME:
case S_STAYTOGETHER:
actor->ask = s;
actor->askmillis = gamemillis;
break;
case S_AFFIRMATIVE:
case S_ALLRIGHTSIR:
case S_YES:
{
int id = checkteamrequests(sender);
if (id >= 0) {
client *prot = clients[id];
prot->linked = id;
prot->linkmillis = gamemillis;
prot->linkreason = s;
sendf(actor->clientnum, 1, "ri2", SV_HUDEXTRAS, 100+id);
}
break;
}
/* case S_NEGATIVE:
case S_NOCANDO:
case S_THERESNOWAYSIR:
case S_COMEONMOVE:
case S_COMINGINWITHTHEFLAG:
case S_DEFENDTHEFLAG:
case S_ENEMYDOWN:
case S_GOGETEMBOYS:
case S_GOODJOBTEAM:
case S_IGOTONE:
case S_IMADECONTACT:
case S_IMATTACKING:
case S_IMONDEFENSE:
case S_IMONYOURTEAMMAN:
case S_RECOVERTHEFLAG:
case S_SORRY:
case S_SPREADOUT:
case S_STAYHERE:
case S_WEDIDIT:
case S_NICESHOT:*/
}
}
int FlagFlag = MINFF * 1000;
float a2c = 0, c2t = 0, a2t = 0; // distances: actor to covered, covered to target and actor to target
inline void testcover(int msg, int factor, client *actor)
@@ -161,12 +229,20 @@ inline void testcover(int msg, int factor, client *actor)
c2t = POW2XY(C,target->state.o);\
a2t = POW2XY(actor->state.o,target->state.o)
bool validlink (client *actor, int cn)
{
return actor->linked >= 0 && actor->linked == cn && gamemillis < actor->linkmillis + 20000 && valid_client(actor->linked);
}
/** WIP */
void checkcover (client *target, client *actor)
{
int team = actor->team;
int oteam = team_opposite(team);
bool covered = false;
int coverid = -1;
if ( m_flags ) {
sflaginfo &f = sflaginfos[team];
sflaginfo &of = sflaginfos[oteam];
@@ -174,25 +250,34 @@ void checkcover (client *target, client *actor)
if ( m_ctf ) {
if ( f.state == CTFF_INBASE ) {
CALCCOVER(f);
testcover(1, 1, actor); /* Flag defended */
testcover(HE_FLAGDEFENDED, 1, actor); /* Flag defended */
}
if ( of.state == CTFF_STOLEN && actor->clientnum != of.actor_cn ) {
covered = true; coverid = of.actor_cn;
CALCCOVER(clients[of.actor_cn]->state.o);
testcover(2, 2, actor); /* Flag covered */
testcover(HE_FLAGCOVERED, 2, actor); /* Flag covered */
}
} else if ( m_htf ) {
if ( f.state == CTFF_DROPPED ) {
struct { short x, y; } nf;
nf.x = f.pos[0]; nf.y = f.pos[1];
CALCCOVER(nf);
testcover(1, 1, actor); /* Flag defended */
testcover(HE_FLAGDEFENDED, 1, actor); /* Flag defended */
}
if ( f.state == CTFF_STOLEN && actor->clientnum != f.actor_cn ) {
covered = true; coverid = f.actor_cn;
CALCCOVER(clients[f.actor_cn]->state.o);
testcover(2, 3, actor); /* Flag covered */
testcover(HE_FLAGCOVERED, 3, actor); /* Flag covered */
}
}
}
if ( !(covered && actor->linked==coverid) && validlink(actor,actor->linked) )
{
CALCCOVER(clients[actor->linked]->state.o);
testcover(HE_COVER, 2, actor); /* covered */
}
}
#undef CALCCOVER
@@ -221,9 +306,9 @@ void checkfrag (client *target, client *actor, int gun, bool gib)
else actor->points += 3 * target->points / 100;
if (gib) {
if ( gun == GUN_GRENADE ) actor->points += 12;
if ( gun == GUN_GRENADE ) actor->points += 10;
else if ( gun == GUN_SNIPER ) {
actor->points += 16;
actor->points += 15;
actor->nhs++;
}
else if ( gun == GUN_KNIFE ) actor->points += 20;