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:
@@ -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
@@ -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:
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user