gamemodes 'hunt the flag' & 'keep the flag' added
git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@2485 e016b1c5-ed68-44aa-a2f7-31cac88cffde
@@ -71,6 +71,8 @@ alias pf [ votemap 6 $arg1 ]
|
||||
alias lss [ votemap 9 $arg1 ]
|
||||
alias osok [ votemap 10 $arg1 ]
|
||||
alias tosok [ votemap 11 $arg1 ]
|
||||
alias htf [ votemap 13 $arg1 ]
|
||||
alias ktf [ votemap 14 $arg1 ]
|
||||
|
||||
|
||||
//--------------------- editing -------------------------------
|
||||
|
||||
@@ -37,7 +37,19 @@ menudirlist "packages/maps" "cgz" "map $arg1"
|
||||
|
||||
|
||||
newmenu maps_ctf
|
||||
// Add maps to the below list to include them in the CTF map menu.
|
||||
// Add maps to the below list to include them in the CTF map menu. Maps should contain flags here.
|
||||
genmapitems "ac_depot ac_desert3 ac_elevation ac_keller ac_mines ac_power ac_shine ac_sunset ac_urban"
|
||||
menuitem """"
|
||||
menuitem "Show all maps.." [showmenu "all maps"]
|
||||
|
||||
newmenu maps_htf
|
||||
// Add maps to the below list to include them in the HTF map menu.
|
||||
genmapitems "ac_arctic ac_complex ac_depot ac_desert ac_desert2 ac_desert3 ac_elevation ac_keller ac_mines ac_power ac_scaffold ac_shine ac_snow ac_sunset ac_toxic ac_urban"
|
||||
menuitem """"
|
||||
menuitem "Show all maps..." [ showmenu "all maps" ]
|
||||
|
||||
newmenu maps_ktf
|
||||
// Add maps to the below list to include them in the KTF map menu. Maps should contain flags here.
|
||||
genmapitems "ac_depot ac_desert3 ac_elevation ac_keller ac_mines ac_power ac_shine ac_sunset ac_urban"
|
||||
menuitem """"
|
||||
menuitem "Show all maps.." [showmenu "all maps"]
|
||||
|
||||
@@ -26,6 +26,8 @@ menuitem "Deathmatch" "mode 2; showmenu maps"
|
||||
menuitem "Team Survivor" "mode 4; showmenu maps"
|
||||
menuitem "Survivor" "mode 3; showmenu maps"
|
||||
menuitem "Capture the Flag" "mode 5; showmenu maps_ctf"
|
||||
menuitem "Hunt the Flag" "mode 13; showmenu maps_htf"
|
||||
menuitem "Keep the Flag" "mode 14; showmenu maps_ktf"
|
||||
menuitem "Pistol Frenzy" "mode 6; showmenu maps"
|
||||
menuitem "Last Swiss Standing" "mode 9; showmenu maps"
|
||||
menuitem "One Shot, One Kill" "mode 10; showmenu maps"
|
||||
|
||||
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1,3 @@
|
||||
md3load tris.md3
|
||||
md3skin mesh skin.jpg
|
||||
md3anim flag 0 7
|
||||
|
After Width: | Height: | Size: 29 KiB |
@@ -0,0 +1,3 @@
|
||||
md3load tris.md3
|
||||
md3skin mesh skin.jpg
|
||||
md3anim flag 0 7
|
||||
|
After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1,3 @@
|
||||
md3load tris.md3
|
||||
md3skin mesh skin.jpg
|
||||
md3anim flag 0 7
|
||||
|
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1,2 @@
|
||||
mdlscale 60
|
||||
|
||||
|
After Width: | Height: | Size: 9.4 KiB |
@@ -0,0 +1 @@
|
||||
mdlscale 60
|
||||
|
After Width: | Height: | Size: 7.7 KiB |
@@ -0,0 +1 @@
|
||||
mdlscale 60
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
@@ -93,7 +93,7 @@ int smallerteam()
|
||||
void changeteam(int team, bool respawn) // force team and respawn
|
||||
{
|
||||
c2sinit = false;
|
||||
if(m_ctf) tryflagdrop(NULL);
|
||||
if(m_flags) tryflagdrop(false);
|
||||
filtertext(player1->team, team_string(team), false, MAXTEAMLEN);
|
||||
if(respawn) addmsg(SV_CHANGETEAM, "r");
|
||||
}
|
||||
@@ -281,8 +281,8 @@ void addsleep(char *msec, char *cmd)
|
||||
s.cmd = newstring(cmd);
|
||||
}
|
||||
|
||||
void resetsleep()
|
||||
{
|
||||
void resetsleep()
|
||||
{
|
||||
loopv(sleeps) DELETEA(sleeps[i].cmd);
|
||||
sleeps.setsize(0);
|
||||
}
|
||||
@@ -351,7 +351,7 @@ void findplayerstart(playerent *d, bool mapcenter, int arenaspawn)
|
||||
loopi(arenaspawn) x = findentity(PLAYERSTART, x+1, type);
|
||||
if(x >= 0) e = &ents[x];
|
||||
}
|
||||
else if(m_teammode || m_arena)
|
||||
else if((m_teammode || m_arena) && !m_ktf) // ktf uses ffa spawns
|
||||
{
|
||||
loopi(r) spawncycle = findentity(PLAYERSTART, spawncycle+1, type);
|
||||
if(spawncycle >= 0) e = &ents[spawncycle];
|
||||
@@ -362,7 +362,7 @@ void findplayerstart(playerent *d, bool mapcenter, int arenaspawn)
|
||||
|
||||
loopi(r)
|
||||
{
|
||||
spawncycle = findentity(PLAYERSTART, spawncycle+1);
|
||||
spawncycle = m_ktf && numspawn[2] > 5 ? findentity(PLAYERSTART, spawncycle+1, 100) : findentity(PLAYERSTART, spawncycle+1);
|
||||
if(spawncycle < 0) continue;
|
||||
float dist = nearestenemy(vec(ents[spawncycle].x, ents[spawncycle].y, ents[spawncycle].z), d->team);
|
||||
if(!e || dist < 0 || (bestdist >= 0 && dist > bestdist)) { e = &ents[spawncycle]; bestdist = dist; }
|
||||
@@ -419,7 +419,7 @@ bool tryrespawn()
|
||||
player1->respawnoffset = lastmillis; // count again
|
||||
}
|
||||
|
||||
int respawnmillis = player1->respawnoffset+(m_arena ? 0 : (m_ctf ? 5000 : 2000));
|
||||
int respawnmillis = player1->respawnoffset+(m_arena ? 0 : (m_flags ? 5000 : 2000));
|
||||
|
||||
if(lastmillis>respawnmillis)
|
||||
{
|
||||
@@ -480,8 +480,6 @@ void dokill(playerent *pl, playerent *act, bool gib)
|
||||
else outf("\f2%s %s %s", aname, death, pname);
|
||||
}
|
||||
|
||||
if(m_ctf && pl==player1) tryflagdrop(pl!=act && isteam(act->team, pl->team));
|
||||
|
||||
if(gib)
|
||||
{
|
||||
if(pl!=act && act->weaponsel->type == GUN_SNIPER) playsound(S_HEADSHOT, SP_LOW);
|
||||
@@ -556,9 +554,18 @@ entity flagdummies[2]; // in case the map does not provide flags
|
||||
|
||||
void preparectf(bool cleanonly=false)
|
||||
{
|
||||
loopi(2) flaginfos[i].flag = &flagdummies[i];
|
||||
loopi(2) flaginfos[i].flagent = &flagdummies[i];
|
||||
if(!cleanonly)
|
||||
{
|
||||
loopi(2)
|
||||
{
|
||||
flaginfo &f = flaginfos[i];
|
||||
f.ack = false;
|
||||
f.actor = NULL;
|
||||
f.actor_cn = -1;
|
||||
f.team = i;
|
||||
f.state = m_ktf ? CTFF_IDLE : CTFF_INBASE;
|
||||
}
|
||||
loopv(ents)
|
||||
{
|
||||
entity &e = ents[i];
|
||||
@@ -567,12 +574,7 @@ void preparectf(bool cleanonly=false)
|
||||
e.spawned = true;
|
||||
if(e.attr2>2) { conoutf("\f3invalid ctf-flag entity (%i)", i); e.attr2 = 0; }
|
||||
flaginfo &f = flaginfos[e.attr2];
|
||||
f.ack = false;
|
||||
f.actor = NULL;
|
||||
f.actor_cn = -1;
|
||||
f.team = e.attr2;
|
||||
f.flag = &e;
|
||||
f.state = CTFF_INBASE;
|
||||
f.flagent = &e;
|
||||
f.originalpos.x = (float) e.x;
|
||||
f.originalpos.y = (float) e.y;
|
||||
f.originalpos.z = (float) e.z;
|
||||
@@ -594,7 +596,7 @@ void startmap(const char *name) // called just after a map load
|
||||
// End add by Rick
|
||||
clearbounceents();
|
||||
resetspawns();
|
||||
if(m_ctf) preparectf();
|
||||
if(m_flags) preparectf();
|
||||
particlereset();
|
||||
suicided = -1;
|
||||
spawncycle = -1;
|
||||
@@ -625,11 +627,8 @@ void startmap(const char *name) // called just after a map load
|
||||
|
||||
void suicide()
|
||||
{
|
||||
if(player1->state!=CS_ALIVE) return;
|
||||
if(!m_mp(gamemode)) dokill(player1, player1);
|
||||
else if(suicided!=player1->lifesequence)
|
||||
if(player1->state == CS_ALIVE && suicided!=player1->lifesequence)
|
||||
{
|
||||
tryflagdrop(false);
|
||||
addmsg(SV_SUICIDE, "r");
|
||||
suicided = player1->lifesequence;
|
||||
}
|
||||
@@ -644,7 +643,7 @@ void flagmsg(int flag, int action)
|
||||
flaginfo &f = flaginfos[flag];
|
||||
if(!f.actor || !f.ack) return;
|
||||
bool own = flag == team_int(player1->team), firstperson = f.actor == player1;
|
||||
const char *teamstr = flag == team_int(player1->team) ? "your" : "the enemy";
|
||||
const char *teamstr = m_ktf ? "the" : own ? "your" : "the enemy";
|
||||
|
||||
switch(action)
|
||||
{
|
||||
@@ -653,53 +652,77 @@ void flagmsg(int flag, int action)
|
||||
playsound(S_FLAGPICKUP, SP_HIGH);
|
||||
if(firstperson)
|
||||
{
|
||||
conoutf("\f2you got the enemy flag");
|
||||
musicsuggest(M_FLAGGRAB, 90*1000, true);
|
||||
conoutf("\f2you got the %sflag", m_ctf ? "enemy " : "");
|
||||
musicsuggest(M_FLAGGRAB, m_ctf ? 90*1000 : 900*1000, true);
|
||||
}
|
||||
else conoutf("\f2%s got %s flag", colorname(f.actor), teamstr);
|
||||
break;
|
||||
}
|
||||
case SV_FLAGDROP:
|
||||
case SV_FLAGLOST:
|
||||
{
|
||||
const char *droplost = action == SV_FLAGLOST ? "lost" : "dropped";
|
||||
playsound(S_FLAGDROP, SP_HIGH);
|
||||
if(firstperson)
|
||||
{
|
||||
conoutf("\f2you lost the flag");
|
||||
conoutf("\f2you %s the flag", droplost);
|
||||
musicfadeout(M_FLAGGRAB);
|
||||
}
|
||||
else conoutf("\f2%s lost %s flag", colorname(f.actor), teamstr);
|
||||
else conoutf("\f2%s %s %s flag", colorname(f.actor), droplost, teamstr);
|
||||
break;
|
||||
}
|
||||
case SV_FLAGRETURN:
|
||||
{
|
||||
playsound(S_FLAGRETURN, SP_HIGH);
|
||||
if(firstperson) conoutf("\f2you returned your flag");
|
||||
else conoutf("\f2%s returned %s flag", colorname(f.actor), teamstr);
|
||||
if(m_ctf)
|
||||
{
|
||||
if(firstperson) conoutf("\f2you returned your flag");
|
||||
else conoutf("\f2%s returned %s flag", colorname(f.actor), teamstr);
|
||||
}
|
||||
else if(m_htf)
|
||||
{
|
||||
conoutf("\f2%s failed to score (own team flag not taken)", firstperson ? "you" : colorname(f.actor));
|
||||
}
|
||||
else
|
||||
{ //ktf
|
||||
conoutf("\f2%s lost the flag", firstperson ? "you" : colorname(f.actor));
|
||||
if(firstperson) musicfadeout(M_FLAGGRAB);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SV_FLAGSCORE:
|
||||
{
|
||||
playsound(S_FLAGSCORE, SP_HIGH);
|
||||
if(firstperson)
|
||||
playsound(m_ktf ? S_VOTEPASS : S_FLAGSCORE, SP_HIGH); // need better ktf sound here
|
||||
if(m_ktf)
|
||||
{
|
||||
const char *ta = firstperson ? "you have" : colorname(f.actor);
|
||||
const char *tb = firstperson ? "" : " has";
|
||||
int m = f.stolentime / 60;
|
||||
if(m)
|
||||
conoutf("%s%s been keeping the flag for %d minute%s %d seconds now", ta, tb, m, m == 1 ? "" : "s", f.stolentime % 60);
|
||||
else
|
||||
conoutf("%s%s been keeping the flag for %d seconds now", ta, tb, f.stolentime);
|
||||
}
|
||||
else if(firstperson)
|
||||
{
|
||||
conoutf("\f2you scored");
|
||||
addmsg(SV_FLAGS, "ri", ++player1->flagscore);
|
||||
musicfadeout(M_FLAGGRAB);
|
||||
if(m_ctf) musicfadeout(M_FLAGGRAB);
|
||||
}
|
||||
else conoutf("\f2%s scored for %s team", colorname(f.actor), (own ? "the enemy" : "your"));
|
||||
break;
|
||||
}
|
||||
case SV_FLAGRESET:
|
||||
{
|
||||
playsound(S_FLAGRETURN, SP_HIGH);
|
||||
conoutf("the server reset the flag");
|
||||
break;
|
||||
}
|
||||
case SV_FLAGRESET:
|
||||
{
|
||||
playsound(S_FLAGRETURN, SP_HIGH);
|
||||
conoutf("the server reset the flag");
|
||||
if(firstperson) musicfadeout(M_FLAGGRAB);
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void dropflag() { tryflagdrop(false); }
|
||||
void dropflag() { tryflagdrop(true); }
|
||||
COMMAND(dropflag, ARG_NONE);
|
||||
|
||||
char *votestring(int type, char *arg1, char *arg2)
|
||||
|
||||
@@ -268,7 +268,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p)
|
||||
getstring(text, p);
|
||||
filtertext(d->team, text, false, MAXTEAMLEN);
|
||||
setskin(d, getint(p));
|
||||
if(m_ctf) loopi(2)
|
||||
if(m_flags) loopi(2)
|
||||
{
|
||||
flaginfo &f = flaginfos[i];
|
||||
if(!f.actor) f.actor = getclient(f.actor_cn);
|
||||
@@ -539,37 +539,43 @@ void parsemessages(int cn, playerent *d, ucharbuf &p)
|
||||
flaginfo &f = flaginfos[flag];
|
||||
f.state = getint(p);
|
||||
int action = getint(p);
|
||||
int actor = f.state==CTFF_STOLEN || action==SV_FLAGRETURN ? getint(p) : -1;
|
||||
|
||||
switch(f.state)
|
||||
{
|
||||
case CTFF_STOLEN:
|
||||
{
|
||||
flagstolen(flag, action, getint(p));
|
||||
if(action==SV_FLAGSCORE) f.stolentime = getint(p);
|
||||
flagstolen(flag, action, actor);
|
||||
break;
|
||||
}
|
||||
case CTFF_DROPPED:
|
||||
{
|
||||
short x = (ushort) (getint(p)/DMF);
|
||||
short y = (ushort) (getint(p)/DMF);
|
||||
short z = ((ushort) (getint(p)/DMF))-((short)player1->eyeheight); // correct z offset, assumes all players do have the same eyeheight
|
||||
flagdropped(flag, action, x, y, z);
|
||||
if(action != SV_FLAGRETURN)
|
||||
{
|
||||
short x = (ushort) (getint(p)/DMF);
|
||||
short y = (ushort) (getint(p)/DMF);
|
||||
short z = ((ushort) (getint(p)/DMF))-((short)player1->eyeheight); // correct z offset, assumes all players do have the same eyeheight
|
||||
flagdropped(flag, action, x, y, z);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CTFF_INBASE:
|
||||
{
|
||||
int actor = -1;
|
||||
if(action == SV_FLAGRETURN) actor = getint(p);
|
||||
flaginbase(flag, action, actor);
|
||||
break;
|
||||
}
|
||||
case CTFF_IDLE:
|
||||
f.flagent->spawned = false;
|
||||
f.ack = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SV_FLAGS:
|
||||
{
|
||||
if(!d) return;
|
||||
d->flagscore = getint(p);
|
||||
int fcn = getint(p), flags = getint(p);
|
||||
playerent *p = (fcn == getclientnum() ? player1 : getclient(fcn));
|
||||
if(p) p->flagscore = flags;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -424,7 +424,7 @@ bool nickcomplete(char *s)
|
||||
|
||||
char *cp = s;
|
||||
for(int i = strlen(s) - 2; i > 0; i--)
|
||||
if (s[i] == ' ') { cp = s + i + 1; break; }
|
||||
if(s[i] == ' ') { cp = s + i + 1; break; }
|
||||
if(!completesize) { completesize = (int)strlen(cp); completeidx = 0; }
|
||||
|
||||
int idx = 0;
|
||||
@@ -460,7 +460,7 @@ void commandcomplete(char *s)
|
||||
if(!s[1]) return;
|
||||
char *cp = s;
|
||||
for(int i = strlen(s) - 2; i > 0; i--)
|
||||
if (s[i] == ';' || s[i] == ' ') { cp = s + i; break; }
|
||||
if(s[i] == ';' || s[i] == ' ') { cp = s + i; break; }
|
||||
if(!completesize)
|
||||
{
|
||||
completesize = (int)strlen(cp)-1;
|
||||
|
||||
@@ -8,15 +8,15 @@ const int physent::crouchtime = 200;
|
||||
vector<entity> ents;
|
||||
|
||||
const char *entnames[] =
|
||||
{
|
||||
{
|
||||
"none?", "light", "playerstart",
|
||||
"clips", "ammobox","grenades",
|
||||
"health", "armour", "akimbo",
|
||||
"mapmodel", "trigger",
|
||||
"mapmodel", "trigger",
|
||||
"ladder", "ctf-flag", "sound", "?", "?",
|
||||
};
|
||||
|
||||
const char *entmdlnames[] =
|
||||
const char *entmdlnames[] =
|
||||
{
|
||||
"pickups/pistolclips", "pickups/ammobox", "pickups/nades", "pickups/health", "pickups/kevlar", "pickups/akimbo",
|
||||
};
|
||||
@@ -28,13 +28,13 @@ void renderent(entity &e, const char *mdlname, float z, float yaw, int anim = AN
|
||||
|
||||
void renderentities()
|
||||
{
|
||||
if(editmode)
|
||||
if(editmode)
|
||||
{
|
||||
loopv(ents)
|
||||
{
|
||||
entity &e = ents[i];
|
||||
if(e.type==NOTUSED) continue;
|
||||
vec v(e.x, e.y, e.z);
|
||||
vec v(e.x, e.y, e.z);
|
||||
particle_splash(2, 2, 40, v);
|
||||
}
|
||||
}
|
||||
@@ -47,21 +47,6 @@ void renderentities()
|
||||
if(!&mmi) continue;
|
||||
rendermodel(mmi.name, ANIM_MAPMODEL|ANIM_LOOP, e.attr4, mmi.rad ? (float)mmi.rad : 1.1f, vec(e.x, e.y, (float)S(e.x, e.y)->floor+mmi.zoff+e.attr3), (float)((e.attr1+7)-(e.attr1+7)%15), 0, 10.0f);
|
||||
}
|
||||
else if(e.type==CTF_FLAG && (m_ctf || editmode))
|
||||
{
|
||||
flaginfo &f = flaginfos[e.attr2];
|
||||
if(f.state==CTFF_STOLEN)
|
||||
{
|
||||
if(!f.actor || f.actor == player1) continue;
|
||||
s_sprintfd(path)("pickups/flags/small_%s", team_string(e.attr2));
|
||||
rendermodel(path, ANIM_FLAG|ANIM_START, 0, 1.1f, vec(f.actor->o).add(vec(0, 0, 0.3f+(sinf(lastmillis/100.0f)+1)/10)), lastmillis/2.5f, 0, 120.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
s_sprintfd(path)("pickups/flags/%s", team_string(e.attr2));
|
||||
rendermodel(path, ANIM_FLAG|ANIM_LOOP, 0, 4, vec(e.x, e.y, f.state==CTFF_INBASE ? (float)S(e.x, e.y)->floor : e.z), (float)((e.attr1+7)-(e.attr1+7)%15), 0, 120.0f);
|
||||
}
|
||||
}
|
||||
else if(isitem(e.type))
|
||||
{
|
||||
if((!OUTBORD(e.x, e.y) && e.spawned) | editmode)
|
||||
@@ -70,6 +55,30 @@ void renderentities()
|
||||
}
|
||||
}
|
||||
}
|
||||
if(m_flags || editmode) loopi(2)
|
||||
{
|
||||
flaginfo &f = flaginfos[i];
|
||||
switch(f.state)
|
||||
{
|
||||
case CTFF_STOLEN:
|
||||
if(f.actor && f.actor != player1)
|
||||
{
|
||||
s_sprintfd(path)("pickups/flags/small_%s%s", m_ktf ? "" : team_string(i), m_htf ? "_htf" : m_ktf ? "ktf" : "");
|
||||
rendermodel(path, ANIM_FLAG|ANIM_START, 0, 1.1f, vec(f.actor->o).add(vec(0, 0, 0.3f+(sinf(lastmillis/100.0f)+1)/10)), lastmillis/2.5f, 0, 120.0f);
|
||||
}
|
||||
break;
|
||||
case CTFF_INBASE:
|
||||
case CTFF_DROPPED:
|
||||
{
|
||||
entity &e = *f.flagent;
|
||||
s_sprintfd(path)("pickups/flags/%s%s", m_ktf ? "" : team_string(i), m_htf ? "_htf" : m_ktf ? "ktf" : "");
|
||||
rendermodel(path, ANIM_FLAG|ANIM_LOOP, 0, 4, vec(e.x, e.y, f.state==CTFF_INBASE ? (float)S(e.x, e.y)->floor : e.z), (float)((e.attr1+7)-(e.attr1+7)%15), 0, 120.0f);
|
||||
break;
|
||||
}
|
||||
case CTFF_IDLE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// these two functions are called when the server acknowledges that you really
|
||||
@@ -129,13 +138,33 @@ void trypickup(int n, playerent *d)
|
||||
flaginfo &f = flaginfos[flag];
|
||||
flaginfo &of = flaginfos[team_opposite(flag)];
|
||||
if(f.state == CTFF_STOLEN) break;
|
||||
bool own = flag == team_int(d->team);
|
||||
|
||||
if(flag == team_int(d->team)) // it's the own flag
|
||||
if(m_ctf)
|
||||
{
|
||||
if(f.state == CTFF_DROPPED) flagreturn();
|
||||
else if(f.state == CTFF_INBASE && of.state == CTFF_STOLEN && of.actor == d && of.ack) flagscore();
|
||||
if(own) // it's the own flag
|
||||
{
|
||||
if(f.state == CTFF_DROPPED) flagreturn(flag);
|
||||
else if(f.state == CTFF_INBASE && of.state == CTFF_STOLEN && of.actor == d && of.ack) flagscore(of.team);
|
||||
}
|
||||
else flagpickup(flag);
|
||||
}
|
||||
else if(m_htf)
|
||||
{
|
||||
if(own)
|
||||
{
|
||||
flagpickup(flag);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(f.state == CTFF_DROPPED) flagscore(f.team); // may not count!
|
||||
}
|
||||
}
|
||||
else if(m_ktf)
|
||||
{
|
||||
if(f.state == CTFF_IDLE) break;
|
||||
flagpickup(flag);
|
||||
}
|
||||
else flagpickup();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -160,7 +189,7 @@ void checkitems(playerent *d)
|
||||
if(dist1<1.5f && dist2<e.attr1) trypickup(i, d);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if(!e.spawned) continue;
|
||||
if(OUTBORD(e.x, e.y)) continue;
|
||||
|
||||
@@ -189,7 +218,7 @@ void putitems(ucharbuf &p) // puts items in network stream and also s
|
||||
}
|
||||
}
|
||||
|
||||
void resetspawns()
|
||||
void resetspawns()
|
||||
{
|
||||
loopv(ents) ents[i].spawned = false;
|
||||
if(m_noitemsnade || m_pistol)
|
||||
@@ -229,10 +258,10 @@ bool intersect(entity *e, vec &from, vec &to, vec *end) // if lineseg hits entit
|
||||
{
|
||||
mapmodelinfo &mmi = getmminfo(e->attr2);
|
||||
if(!&mmi || !mmi.h) return false;
|
||||
|
||||
|
||||
float lo = (float)(S(e->x, e->y)->floor+mmi.zoff+e->attr3);
|
||||
float hi = lo+mmi.h;
|
||||
vec v = to, w(e->x, e->y, lo + (fabs(hi-lo)/2.0f)), *p;
|
||||
vec v = to, w(e->x, e->y, lo + (fabs(hi-lo)/2.0f)), *p;
|
||||
v.sub(from);
|
||||
w.sub(from);
|
||||
float c1 = w.dot(v);
|
||||
@@ -250,7 +279,7 @@ bool intersect(entity *e, vec &from, vec &to, vec *end) // if lineseg hits entit
|
||||
p = &v;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (p->x <= e->x+mmi.rad
|
||||
&& p->x >= e->x-mmi.rad
|
||||
&& p->y <= e->y+mmi.rad
|
||||
@@ -269,11 +298,11 @@ bool intersect(entity *e, vec &from, vec &to, vec *end) // if lineseg hits entit
|
||||
|
||||
int flagdropmillis = 0;
|
||||
|
||||
void flagpickup()
|
||||
void flagpickup(int fln)
|
||||
{
|
||||
if(flagdropmillis && flagdropmillis>lastmillis) return;
|
||||
flaginfo &f = flaginfos[team_opposite(team_int(player1->team))];
|
||||
f.flag->spawned = false;
|
||||
flaginfo &f = flaginfos[fln];
|
||||
f.flagent->spawned = false;
|
||||
f.state = CTFF_STOLEN;
|
||||
f.actor = player1; // do this although we don't know if we picked the flag to avoid getting it after a possible respawn
|
||||
f.actor_cn = getclientnum();
|
||||
@@ -281,32 +310,35 @@ void flagpickup()
|
||||
addmsg(SV_FLAGPICKUP, "ri", f.team);
|
||||
}
|
||||
|
||||
void tryflagdrop(bool reset)
|
||||
void tryflagdrop(bool manual)
|
||||
{
|
||||
flaginfo &f = flaginfos[team_opposite(team_int(player1->team))];
|
||||
if(f.state==CTFF_STOLEN && f.actor==player1)
|
||||
loopi(2)
|
||||
{
|
||||
f.flag->spawned = false;
|
||||
f.state = CTFF_DROPPED;
|
||||
f.ack = false;
|
||||
flagdropmillis = lastmillis+3000;
|
||||
addmsg(reset ? SV_FLAGRESET : SV_FLAGDROP, "ri", f.team);
|
||||
flaginfo &f = flaginfos[i];
|
||||
if(f.state==CTFF_STOLEN && f.actor==player1)
|
||||
{
|
||||
f.flagent->spawned = false;
|
||||
f.state = CTFF_DROPPED;
|
||||
f.ack = false;
|
||||
flagdropmillis = lastmillis+3000;
|
||||
addmsg(manual ? SV_FLAGDROP : SV_FLAGLOST, "ri", f.team);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void flagreturn()
|
||||
void flagreturn(int fln)
|
||||
{
|
||||
flaginfo &f = flaginfos[team_int(player1->team)];
|
||||
f.flag->spawned = false;
|
||||
flaginfo &f = flaginfos[fln];
|
||||
f.flagent->spawned = false;
|
||||
f.ack = false;
|
||||
addmsg(SV_FLAGRETURN, "ri", f.team);
|
||||
}
|
||||
|
||||
void flagscore()
|
||||
void flagscore(int fln)
|
||||
{
|
||||
flaginfo &f = flaginfos[team_opposite(team_int(player1->team))];
|
||||
flaginfo &f = flaginfos[fln];
|
||||
f.ack = false;
|
||||
addmsg(SV_FLAGSCORE, "ri", f.team);
|
||||
addmsg(SV_FLAGSCORE, "ri", fln);
|
||||
}
|
||||
|
||||
// flag ent actions from the net
|
||||
@@ -318,7 +350,7 @@ void flagstolen(int flag, int action, int act)
|
||||
flaginfo &f = flaginfos[flag];
|
||||
f.actor = actor;
|
||||
f.actor_cn = act;
|
||||
f.flag->spawned = false;
|
||||
f.flagent->spawned = false;
|
||||
f.ack = true;
|
||||
flagmsg(flag, action);
|
||||
}
|
||||
@@ -334,7 +366,7 @@ void flagdropped(int flag, int action, short x, short y, short z)
|
||||
p.o.z = z;
|
||||
p.vel.z = -0.8f;
|
||||
p.aboveeye = p.eyeheight = p.radius = 0.0f;
|
||||
|
||||
|
||||
bool oldcancollide = false;
|
||||
if(f.actor)
|
||||
{
|
||||
@@ -348,11 +380,11 @@ void flagdropped(int flag, int action, short x, short y, short z)
|
||||
}
|
||||
if(f.actor) f.actor->cancollide = oldcancollide; // restore settings
|
||||
|
||||
f.flag->x = (short)round(p.o.x);
|
||||
f.flag->y = (short)round(p.o.y);
|
||||
f.flag->z = (short)round(p.o.z);
|
||||
if(f.flag->z < hdr.waterlevel) f.flag->z = (short) hdr.waterlevel;
|
||||
f.flag->spawned = true;
|
||||
f.flagent->x = (short)round(p.o.x);
|
||||
f.flagent->y = (short)round(p.o.y);
|
||||
f.flagent->z = (short)round(p.o.z);
|
||||
if(f.flagent->z < hdr.waterlevel) f.flagent->z = (short) hdr.waterlevel;
|
||||
f.flagent->spawned = true;
|
||||
f.ack = true;
|
||||
flagmsg(flag, action);
|
||||
}
|
||||
@@ -362,10 +394,10 @@ void flaginbase(int flag, int action, int act)
|
||||
flaginfo &f = flaginfos[flag];
|
||||
playerent *actor = act == getclientnum() ? player1 : getclient(act);
|
||||
if(actor) { f.actor = actor; f.actor_cn = act; }
|
||||
f.flag->x = (ushort) f.originalpos.x;
|
||||
f.flag->y = (ushort) f.originalpos.y;
|
||||
f.flag->z = (ushort) f.originalpos.z;
|
||||
f.flag->spawned = true;
|
||||
f.flagent->x = (ushort) f.originalpos.x;
|
||||
f.flagent->y = (ushort) f.originalpos.y;
|
||||
f.flagent->z = (ushort) f.originalpos.z;
|
||||
f.flagent->spawned = true;
|
||||
f.ack = true;
|
||||
flagmsg(flag, action);
|
||||
}
|
||||
|
||||
@@ -465,18 +465,19 @@ struct botent : playerent
|
||||
int deaths() { return lifesequence; }
|
||||
};
|
||||
|
||||
enum { CTFF_INBASE = 0, CTFF_STOLEN, CTFF_DROPPED };
|
||||
enum { CTFF_INBASE = 0, CTFF_STOLEN, CTFF_DROPPED, CTFF_IDLE };
|
||||
|
||||
struct flaginfo
|
||||
{
|
||||
int team;
|
||||
entity *flag;
|
||||
entity *flagent;
|
||||
int actor_cn;
|
||||
playerent *actor;
|
||||
vec originalpos;
|
||||
int state; // one of CTFF_*
|
||||
bool ack;
|
||||
flaginfo() : flag(0), actor(0), state(CTFF_INBASE), ack(false) {}
|
||||
int stolentime;
|
||||
flaginfo() : flagent(0), actor(0), state(CTFF_INBASE), ack(false) {}
|
||||
};
|
||||
|
||||
enum { BT_NONE, BT_NADE, BT_GIB };
|
||||
|
||||
@@ -97,13 +97,13 @@ const char *modefullnames[] =
|
||||
{
|
||||
"team deathmatch", "coopedit", "deathmatch", "survivor",
|
||||
"team survivor", "ctf", "pistol frenzy", "bot team deathmatch", "bot deathmatch", "last swiss standing",
|
||||
"one shot, one kill", "team one shot, one kill", "bot one shot, one kill"
|
||||
"one shot, one kill", "team one shot, one kill", "bot one shot, one kill", "hunt the flag", "keep the flag"
|
||||
};
|
||||
|
||||
const char *modeacronymnames[] =
|
||||
{
|
||||
"TDM", "coop", "DM", "SURV", "TSURV", "CTF", "PF", "BTDM", "BDM", "LSS",
|
||||
"OSOK", "TOSOK", "BOSOK"
|
||||
"OSOK", "TOSOK", "BOSOK", "HTF", "CTF"
|
||||
};
|
||||
|
||||
const char *voteerrors[] = { "voting is currently disabled", "there is already a vote pending", "already voted", "can't vote that often", "this vote is not allowed in the current environment (singleplayer/multiplayer)", "no permission", "invalid vote" };
|
||||
@@ -125,7 +125,7 @@ char msgsizesl[] = // size inclusive message token, 0 for variable
|
||||
SV_EDITMODE, 2, SV_EDITH, 7, SV_EDITT, 7, SV_EDITS, 6, SV_EDITD, 6, SV_EDITE, 6,
|
||||
SV_SENDMAP, 0, SV_RECVMAP, 1, SV_SERVMSG, 0, SV_ITEMLIST, 0, SV_WEAPCHANGE, 2, SV_PRIMARYWEAP, 2,
|
||||
SV_MODELSKIN, 2,
|
||||
SV_FLAGPICKUP, 2, SV_FLAGDROP, 2, SV_FLAGRETURN, 2, SV_FLAGSCORE, 2, SV_FLAGRESET, 2, SV_FLAGINFO, 0, SV_FLAGS, 2,
|
||||
SV_FLAGPICKUP, 2, SV_FLAGDROP, 2, SV_FLAGLOST, 2, SV_FLAGRETURN, 2, SV_FLAGSCORE, 2, SV_FLAGRESET, 2, SV_FLAGINFO, 0, SV_FLAGS, 3,
|
||||
SV_ARENAWIN, 2,
|
||||
SV_SETADMIN, 0, SV_SERVOPINFO, 3,
|
||||
SV_CALLVOTE, 0, SV_CALLVOTESUC, 1, SV_CALLVOTEERR, 2, SV_VOTE, 2, SV_VOTERESULT, 2,
|
||||
|
||||
@@ -23,7 +23,7 @@ enum
|
||||
SV_EDITMODE, SV_EDITH, SV_EDITT, SV_EDITS, SV_EDITD, SV_EDITE,
|
||||
SV_SENDMAP, SV_RECVMAP, SV_SERVMSG, SV_ITEMLIST, SV_WEAPCHANGE, SV_PRIMARYWEAP,
|
||||
SV_MODELSKIN,
|
||||
SV_FLAGPICKUP, SV_FLAGDROP, SV_FLAGRETURN, SV_FLAGSCORE, SV_FLAGRESET, SV_FLAGINFO, SV_FLAGS,
|
||||
SV_FLAGPICKUP, SV_FLAGDROP, SV_FLAGLOST, SV_FLAGRETURN, SV_FLAGSCORE, SV_FLAGRESET, SV_FLAGINFO, SV_FLAGS,
|
||||
SV_ARENAWIN,
|
||||
SV_SETADMIN, SV_SERVOPINFO,
|
||||
SV_CALLVOTE, SV_CALLVOTESUC, SV_CALLVOTEERR, SV_VOTE, SV_VOTERESULT,
|
||||
@@ -69,11 +69,13 @@ enum
|
||||
GMODE_CTF,
|
||||
GMODE_PISTOLFRENZY,
|
||||
GMODE_BOTTEAMDEATHMATCH,
|
||||
GMODE_GOTDEATHMATCH,
|
||||
GMODE_BOTDEATHMATCH,
|
||||
GMODE_LASTSWISSSTANDING,
|
||||
GMODE_ONESHOTONEKILL,
|
||||
GMODE_TEAMONESHOTONEKILL,
|
||||
GMODE_BOTONESHOTONEKILL
|
||||
GMODE_BOTONESHOTONEKILL,
|
||||
GMODE_HUNTTHEFLAG, // 13
|
||||
GMODE_KEEPTHEFLAG
|
||||
};
|
||||
|
||||
#define m_lms (gamemode==3 || gamemode==4)
|
||||
@@ -81,6 +83,8 @@ enum
|
||||
#define m_pistol (gamemode==6)
|
||||
#define m_lss (gamemode==9)
|
||||
#define m_osok (gamemode>=10 && gamemode<=12)
|
||||
#define m_htf (gamemode==13)
|
||||
#define m_ktf (gamemode==14)
|
||||
|
||||
#define m_noitems (m_lms || m_osok)
|
||||
#define m_noitemsnade (m_lss)
|
||||
@@ -88,9 +92,10 @@ enum
|
||||
#define m_noprimary (m_pistol || m_lss)
|
||||
#define m_noguns (m_nopistol && m_noprimary)
|
||||
#define m_arena (m_lms || m_lss || m_osok)
|
||||
#define m_teammode (gamemode==0 || gamemode==4 || gamemode==5 || gamemode==7 || gamemode==11)
|
||||
#define m_teammode (gamemode==0 || gamemode==4 || gamemode==5 || gamemode==7 || gamemode==11 || gamemode==13 || gamemode==14)
|
||||
#define m_tarena (m_arena && m_teammode)
|
||||
#define m_botmode (gamemode==7 || gamemode == 8 || gamemode==12)
|
||||
#define m_valid(mode) (((mode)>=0 && (mode)<=12) || (mode) == -3)
|
||||
#define m_valid(mode) (((mode)>=0 && (mode)<=14) || (mode) == -3)
|
||||
#define m_mp(mode) (m_valid(mode) && (mode)!=7 && (mode)!=8 && (mode)!=12)
|
||||
#define m_demo (gamemode==-3)
|
||||
#define m_flags (m_ctf || m_htf || m_ktf)
|
||||
|
||||
@@ -302,10 +302,10 @@ extern void setskin(playerent *pl, uint skin);
|
||||
extern void callvote(int type, char *arg1 = NULL, char *arg2 = NULL);
|
||||
extern void resetsleep();
|
||||
//game mode extras
|
||||
extern void flagpickup();
|
||||
extern void tryflagdrop(bool reset = false);
|
||||
extern void flagreturn();
|
||||
extern void flagscore();
|
||||
extern void flagpickup(int fln);
|
||||
extern void tryflagdrop(bool manual = false);
|
||||
extern void flagreturn(int fln);
|
||||
extern void flagscore(int fln);
|
||||
extern void flagstolen(int flag, int action, int act);
|
||||
extern void flagdropped(int flag, int action, short x, short y, short z);
|
||||
extern void flaginbase(int flag, int action, int act);
|
||||
|
||||
@@ -34,9 +34,22 @@ void drawradaricon(float x, float y, float s, int col, int row)
|
||||
|
||||
void drawctficon(float x, float y, float s, int col, int row, float ts)
|
||||
{
|
||||
static Texture *tex = NULL;
|
||||
if(!tex) tex = textureload("packages/misc/ctficons.png");
|
||||
if(tex) drawicon(tex, x, y, s, col, row, ts);
|
||||
static Texture *ctftex = NULL, *htftex = NULL, *ktftex = NULL;
|
||||
if(!ctftex) ctftex = textureload("packages/misc/ctficons.png");
|
||||
if(!htftex) htftex = textureload("packages/misc/htficons.png");
|
||||
if(!ktftex) ktftex = textureload("packages/misc/ktficons.png");
|
||||
if(m_htf)
|
||||
{
|
||||
if(htftex) drawicon(htftex, x, y, s, col, row, ts);
|
||||
}
|
||||
else if(m_ktf)
|
||||
{
|
||||
if(ktftex) drawicon(ktftex, x, y, s, col, row, ts);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(ctftex) drawicon(ctftex, x, y, s, col, row, ts);
|
||||
}
|
||||
}
|
||||
|
||||
void drawvoteicon(float x, float y, int col, int row, bool noblend)
|
||||
@@ -332,22 +345,26 @@ void drawradar(playerent *p, int w, int h)
|
||||
if(!pl || pl==p || !isteam(p->team, pl->team) || !insideradar(centerpos, res/2, pl->o)) continue;
|
||||
drawradarent(pl->o.x*coordtrans, pl->o.y*coordtrans, pl->yaw, pl->state==CS_ALIVE ? (isattacking(pl) ? 2 : 0) : 1, team_int(pl->team), iconsize, isattacking(pl), colorname(pl));
|
||||
}
|
||||
if(m_ctf)
|
||||
if(m_flags)
|
||||
{
|
||||
glColor4f(1.0f, 1.0f, 1.0f, (sinf(lastmillis / 100.0f) + 1.0f) / 2.0f);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
loopi(2) // flag items
|
||||
{
|
||||
flaginfo &f = flaginfos[i];
|
||||
entity *e = f.flag;
|
||||
entity *e = f.flagent;
|
||||
if(!e) continue;
|
||||
float yaw = showmap ? 0 : p->yaw;
|
||||
if(m_ktf && f.state == CTFF_IDLE) continue;
|
||||
if(f.state==CTFF_STOLEN)
|
||||
{
|
||||
if(f.actor && i != team_int(p->team) && insideradar(centerpos, res/2, f.actor->o))
|
||||
drawradarent(f.actor->o.x*coordtrans+iconsize/2, f.actor->o.y*coordtrans+iconsize/2, yaw, 3, f.team, iconsize, true); // draw near flag thief
|
||||
bool tm = i != team_int(p->team);
|
||||
if(m_htf) tm = !tm;
|
||||
else if(m_ktf) tm = true;
|
||||
if(f.actor && tm && insideradar(centerpos, res/2, f.actor->o))
|
||||
drawradarent(f.actor->o.x*coordtrans+iconsize/2, f.actor->o.y*coordtrans+iconsize/2, yaw, 3, m_ktf ? 2 : f.team, iconsize, true); // draw near flag thief
|
||||
}
|
||||
else if(insideradar(centerpos, res/2, vec(e->x, e->y, centerpos.z))) drawradarent(e->x*coordtrans, e->y*coordtrans, yaw, 3, f.team, iconsize, false); // draw on entitiy pos
|
||||
else if(insideradar(centerpos, res/2, vec(e->x, e->y, centerpos.z))) drawradarent(e->x*coordtrans, e->y*coordtrans, yaw, 3, m_ktf ? 2 : f.team, iconsize, false); // draw on entitiy pos
|
||||
}
|
||||
}
|
||||
|
||||
@@ -512,7 +529,7 @@ void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwat
|
||||
if(p->weaponsel && p->weaponsel->type>=GUN_KNIFE && p->weaponsel->type<NUMGUNS) p->weaponsel->renderstats(); // flowtron
|
||||
}
|
||||
|
||||
if(m_ctf && !hidectfhud)
|
||||
if(m_flags && !hidectfhud)
|
||||
{
|
||||
glLoadIdentity();
|
||||
glOrtho(0, VIRTW, VIRTH, 0, -1, 1);
|
||||
@@ -526,12 +543,13 @@ void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwat
|
||||
}
|
||||
|
||||
// big flag-stolen icon
|
||||
flaginfo &f = flaginfos[team_opposite(team_int(p->team))];
|
||||
if(f.state==CTFF_STOLEN && f.actor == p && f.ack)
|
||||
int ft = 0;
|
||||
if((flaginfos[0].state==CTFF_STOLEN && flaginfos[0].actor == p && flaginfos[0].ack) ||
|
||||
(flaginfos[1].state==CTFF_STOLEN && flaginfos[1].actor == p && flaginfos[1].ack && ++ft))
|
||||
{
|
||||
glColor4f(1.0f, 1.0f, 1.0f, (sinf(lastmillis/100.0f)+1.0f) / 2.0f);
|
||||
glEnable(GL_BLEND);
|
||||
drawctficon(VIRTW-225-10, VIRTH*5/8, 225, team_opposite(team_int(p->team)), 1, 1/2.0f);
|
||||
drawctficon(VIRTW-225-10, VIRTH*5/8, 225, m_ktf ? team_int(p->team) : ft, 1, 1/2.0f);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ void *scoremenu = NULL, *teammenu = NULL, *ctfmenu = NULL;
|
||||
|
||||
void showscores(bool on)
|
||||
{
|
||||
menuset(on ? (m_ctf ? ctfmenu : (m_teammode ? teammenu : scoremenu)) : NULL);
|
||||
menuset(on ? (m_flags ? ctfmenu : (m_teammode ? teammenu : scoremenu)) : NULL);
|
||||
}
|
||||
|
||||
COMMAND(showscores, ARG_DOWN);
|
||||
@@ -33,7 +33,7 @@ struct teamscore
|
||||
teammembers.add(d);
|
||||
frags += d->frags;
|
||||
deaths += d->deaths;
|
||||
if(m_ctf) flagscore += d->flagscore;
|
||||
if(m_flags) flagscore += d->flagscore;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -92,7 +92,7 @@ void renderscore(void *menu, playerent *d)
|
||||
string &s = line.s;
|
||||
scoreratio sr;
|
||||
sr.calc(d->frags, d->deaths);
|
||||
if(m_ctf) s_sprintf(s)("%d\t%d\t%d\t%.*f\t%s\t%s\t%d\t%s%s", d->flagscore, d->frags, d->deaths, sr.precision, sr.ratio, d->state==CS_LAGGED ? "LAG" : lag, colorping(d->ping), d->clientnum, status, colorname(d));
|
||||
if(m_flags) s_sprintf(s)("%d\t%d\t%d\t%.*f\t%s\t%s\t%d\t%s%s", d->flagscore, d->frags, d->deaths, sr.precision, sr.ratio, d->state==CS_LAGGED ? "LAG" : lag, colorping(d->ping), d->clientnum, status, colorname(d));
|
||||
else if(m_teammode) s_sprintf(s)("%d\t%d\t%.*f\t%s\t%s\t%d\t%s%s", d->frags, d->deaths, sr.precision, sr.ratio, d->state==CS_LAGGED ? "LAG" : lag, colorping(d->ping), d->clientnum, status, colorname(d));
|
||||
else s_sprintf(s)("%d\t%d\t%.*f\t%s\t%s\t%d\t%s%s", d->frags, d->deaths, sr.precision, sr.ratio, d->state==CS_LAGGED ? "LAG" : lag, colorping(d->ping), d->clientnum, status, colorname(d));
|
||||
}
|
||||
@@ -108,7 +108,7 @@ void renderteamscore(void *menu, teamscore *t)
|
||||
s_sprintfd(plrs)("(%d %s)", t->teammembers.length(), t->teammembers.length() == 1 ? "player" : "players");
|
||||
scoreratio sr;
|
||||
sr.calc(t->frags, t->deaths);
|
||||
if(m_ctf) s_sprintf(line.s)("%d\t%d\t%d\t%.*f\t\t\t\t%s\t\t%s", t->flagscore, t->frags, t->deaths, sr.precision, sr.ratio, team_string(t->team), plrs);
|
||||
if(m_flags) s_sprintf(line.s)("%d\t%d\t%d\t%.*f\t\t\t\t%s\t\t%s", t->flagscore, t->frags, t->deaths, sr.precision, sr.ratio, team_string(t->team), plrs);
|
||||
else if(m_teammode) s_sprintf(line.s)("%d\t%d\t%.*f\t\t\t\t%s\t\t%s", t->frags, t->deaths, sr.precision, sr.ratio, team_string(t->team), plrs);
|
||||
static color teamcolors[2] = { color(1.0f, 0, 0, 0.2f), color(0, 0, 1.0f, 0.2f) };
|
||||
line.bgcolor = &teamcolors[t->team];
|
||||
|
||||
@@ -820,6 +820,7 @@ struct sflaginfo
|
||||
int actor_cn;
|
||||
float pos[3];
|
||||
int lastupdate;
|
||||
int stolentime;
|
||||
} sflaginfos[2];
|
||||
|
||||
void sendflaginfo(int flag, int action, int cn = -1)
|
||||
@@ -833,6 +834,7 @@ void sendflaginfo(int flag, int action, int cn = -1)
|
||||
putint(p, action);
|
||||
if(f.state==CTFF_STOLEN || action==SV_FLAGRETURN) putint(p, f.actor_cn);
|
||||
else if(f.state==CTFF_DROPPED) loopi(3) putint(p, int(f.pos[i]*DMF));
|
||||
if(f.state==CTFF_STOLEN && action==SV_FLAGSCORE) putint(p, (gamemillis - f.stolentime) / 1000);
|
||||
enet_packet_resize(packet, p.length());
|
||||
sendpacket(cn, 1, packet);
|
||||
if(packet->referenceCount==0) enet_packet_destroy(packet);
|
||||
@@ -842,7 +844,8 @@ void flagaction(int flag, int action, int sender)
|
||||
{
|
||||
if(!valid_flag(flag)) return;
|
||||
sflaginfo &f = sflaginfos[flag];
|
||||
|
||||
sflaginfo &of = sflaginfos[team_opposite(flag)];
|
||||
bool ktf_switch = false;
|
||||
switch(action)
|
||||
{
|
||||
case SV_FLAGPICKUP:
|
||||
@@ -850,15 +853,18 @@ void flagaction(int flag, int action, int sender)
|
||||
if(f.state == CTFF_STOLEN) return;
|
||||
f.state = CTFF_STOLEN;
|
||||
f.actor_cn = sender;
|
||||
f.stolentime = gamemillis;
|
||||
logger->writeline(log::info,"[%s] %s stole the flag", clients[sender]->hostname, clients[sender]->name);
|
||||
break;
|
||||
}
|
||||
case SV_FLAGDROP:
|
||||
case SV_FLAGLOST:
|
||||
{
|
||||
if(f.state!=CTFF_STOLEN || (sender != -1 && f.actor_cn != sender)) return;
|
||||
ktf_switch = true;
|
||||
f.state = CTFF_DROPPED;
|
||||
loopi(3) f.pos[i] = clients[sender]->state.o[i];
|
||||
logger->writeline(log::info,"[%s] %s dropped the flag", clients[sender]->hostname, clients[sender]->name);
|
||||
loopi(3) f.pos[i] = clients[f.actor_cn]->state.o[i];
|
||||
logger->writeline(log::info,"[%s] %s %s the flag", clients[f.actor_cn]->hostname, clients[f.actor_cn]->name, action == SV_FLAGLOST ? "lost" : "dropped");
|
||||
break;
|
||||
}
|
||||
case SV_FLAGRETURN:
|
||||
@@ -872,19 +878,50 @@ void flagaction(int flag, int action, int sender)
|
||||
case SV_FLAGRESET:
|
||||
{
|
||||
if(sender != -1 && f.actor_cn != sender) return;
|
||||
ktf_switch = true;
|
||||
f.state = CTFF_INBASE;
|
||||
logger->writeline(log::info,"The server reset the flag");
|
||||
break;
|
||||
}
|
||||
case SV_FLAGSCORE:
|
||||
{
|
||||
if(f.state != CTFF_STOLEN) return;
|
||||
f.state = CTFF_INBASE;
|
||||
logger->writeline(log::info, "[%s] %s scored with the flag for %s", clients[sender]->hostname, clients[sender]->name, clients[sender]->team);
|
||||
bool score = true;
|
||||
if(m_ctf)
|
||||
{ //ctf f: actor carrying, of: unstolen own
|
||||
if(f.state != CTFF_STOLEN || f.actor_cn != sender || of.state != CTFF_INBASE) return;
|
||||
f.state = CTFF_INBASE;
|
||||
}
|
||||
else if(m_htf)
|
||||
{ //htf of: own team carrying, f: other team dropped
|
||||
if(f.state != CTFF_DROPPED) return;
|
||||
f.state = CTFF_INBASE;
|
||||
if(of.state != CTFF_STOLEN)
|
||||
{
|
||||
action = SV_FLAGRETURN;
|
||||
score = false; // sry, fail
|
||||
}
|
||||
}
|
||||
if(score)
|
||||
{
|
||||
clients[sender]->state.flagscore += 1;
|
||||
sendf(-1, 1, "riii", SV_FLAGS, sender, clients[sender]->state.flagscore);
|
||||
logger->writeline(log::info, "[%s] %s scored with the flag for %s, new score %d", clients[sender]->hostname, clients[sender]->name, clients[sender]->team, clients[sender]->state.flagscore);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger->writeline(log::info, "[%s] %s failed to score", clients[sender]->hostname, clients[sender]->name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: return;
|
||||
}
|
||||
if(m_ktf && ktf_switch)
|
||||
{
|
||||
f.state = CTFF_IDLE;
|
||||
of.state = CTFF_INBASE;
|
||||
sendflaginfo(team_opposite(flag), SV_FLAGRETURN);
|
||||
action = 0;
|
||||
}
|
||||
|
||||
f.lastupdate = gamemillis;
|
||||
sendflaginfo(flag, action);
|
||||
@@ -892,14 +929,54 @@ void flagaction(int flag, int action, int sender)
|
||||
|
||||
void ctfreset()
|
||||
{
|
||||
int idleflag = m_ktf ? rnd(2) : -1;
|
||||
loopi(2)
|
||||
{
|
||||
sflaginfos[i].actor_cn = 0;
|
||||
sflaginfos[i].state = CTFF_INBASE;
|
||||
sflaginfos[i].state = i == idleflag ? CTFF_IDLE : CTFF_INBASE;
|
||||
sflaginfos[i].lastupdate = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void htf_forceflag(int flag)
|
||||
{
|
||||
sflaginfo &f = sflaginfos[flag];
|
||||
int besthealth = 0, numbesthealth = 0;
|
||||
loopv(clients) if(clients[i]->type!=ST_EMPTY)
|
||||
{
|
||||
if(clients[i]->state.state == CS_ALIVE && team_int(clients[i]->team) == flag)
|
||||
{
|
||||
if(clients[i]->state.health == besthealth)
|
||||
numbesthealth++;
|
||||
else
|
||||
{
|
||||
if(clients[i]->state.health > besthealth)
|
||||
{
|
||||
besthealth = clients[i]->state.health;
|
||||
numbesthealth = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(numbesthealth)
|
||||
{
|
||||
int pick = rnd(numbesthealth);
|
||||
loopv(clients) if(clients[i]->type!=ST_EMPTY)
|
||||
{
|
||||
if(clients[i]->state.state == CS_ALIVE && team_int(clients[i]->team) == flag && --pick < 0)
|
||||
{
|
||||
f.state = CTFF_STOLEN;
|
||||
f.actor_cn = i;
|
||||
sendflaginfo(flag, SV_FLAGPICKUP);
|
||||
logger->writeline(log::info,"[%s] %s got forced to pickup the flag", clients[i]->hostname, clients[i]->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
f.lastupdate = gamemillis;
|
||||
}
|
||||
|
||||
|
||||
bool canspawn(client *c, bool connecting = false)
|
||||
{
|
||||
if(m_arena)
|
||||
@@ -1015,7 +1092,7 @@ void arenacheck()
|
||||
if(!dead) return;
|
||||
sendf(-1, 1, "ri2", SV_ARENAWIN, !alive ? -1 : alive->clientnum);
|
||||
arenaround = gamemillis+5000;
|
||||
if (autoteam && m_teammode) refillteams(true);
|
||||
if(autoteam && m_teammode) refillteams(true);
|
||||
}
|
||||
|
||||
#define SPAMREPEATINTERVAL 15 // detect doubled lines only if interval < 15 seconds
|
||||
@@ -1141,7 +1218,7 @@ void serverdamage(client *target, client *actor, int damage, int gun, bool gib,
|
||||
{
|
||||
clientstate &ts = target->state;
|
||||
ts.dodamage(damage);
|
||||
actor->state.damage += damage;
|
||||
actor->state.damage += damage != 1000 ? damage : 0;
|
||||
sendf(-1, 1, "ri6", gib ? SV_GIBDAMAGE : SV_DAMAGE, target->clientnum, actor->clientnum, damage, ts.armour, ts.health);
|
||||
if(target!=actor && !hitpush.iszero())
|
||||
{
|
||||
@@ -1152,6 +1229,9 @@ void serverdamage(client *target, client *actor, int damage, int gun, bool gib,
|
||||
}
|
||||
if(ts.health<=0)
|
||||
{
|
||||
int targethasflag = -1;
|
||||
bool flagtk = false, suic = false;
|
||||
loopi(2) { if(sflaginfos[i].state == CTFF_STOLEN && sflaginfos[i].actor_cn == target->clientnum) targethasflag = i; }
|
||||
target->state.deaths++;
|
||||
if(target!=actor)
|
||||
{
|
||||
@@ -1160,14 +1240,29 @@ void serverdamage(client *target, client *actor, int damage, int gun, bool gib,
|
||||
{
|
||||
actor->state.frags--;
|
||||
actor->state.teamkills++;
|
||||
flagtk = true;
|
||||
}
|
||||
}
|
||||
else actor->state.frags--;
|
||||
else
|
||||
{ // suicide
|
||||
actor->state.frags--;
|
||||
flagtk = true;
|
||||
suic = true;
|
||||
}
|
||||
sendf(-1, 1, "ri4", gib ? SV_GIBDIED : SV_DIED, target->clientnum, actor->clientnum, actor->state.frags);
|
||||
if(flagtk && (m_htf || m_ktf) && targethasflag >= 0)
|
||||
{
|
||||
actor->state.flagscore--;
|
||||
sendf(-1, 1, "riii", SV_FLAGS, actor->clientnum, actor->state.flagscore);
|
||||
}
|
||||
target->position.setsizenodelete(0);
|
||||
ts.state = CS_DEAD;
|
||||
ts.lastdeath = gamemillis;
|
||||
logger->writeline(log::info, "[%s] %s %s %s", actor->hostname, actor->name, gib ? "gibbed" : "fragged", target->name);
|
||||
if(m_flags && targethasflag >= 0)
|
||||
{
|
||||
flagaction(targethasflag, suic ? SV_FLAGLOST : SV_FLAGRESET, -1);
|
||||
}
|
||||
// don't issue respawn yet until DEATHMILLIS has elapsed
|
||||
// ts.respawn();
|
||||
|
||||
@@ -1237,7 +1332,7 @@ void readscfg(const char *name)
|
||||
par[3] = par[4] = 0; // default values
|
||||
for(i = 0; i < CONFIG_MAXPAR; i++)
|
||||
{
|
||||
if ((l = strtok(NULL, sep)) != NULL)
|
||||
if((l = strtok(NULL, sep)) != NULL)
|
||||
par[i] = atoi(l);
|
||||
else
|
||||
break;
|
||||
@@ -1264,7 +1359,7 @@ int cmpipmatch(const void *a, const void * b) { return - (((struct iprange *)a)-
|
||||
enet_uint32 atoip(const char *s)
|
||||
{
|
||||
unsigned int d[3], res;
|
||||
if (sscanf(s, "%u.%u.%u.%u", &res, d, d + 1, d + 2) != 4) return 0;
|
||||
if(sscanf(s, "%u.%u.%u.%u", &res, d, d + 1, d + 2) != 4) return 0;
|
||||
loopi(3)
|
||||
{
|
||||
if(d[i] > 255) return 0;
|
||||
@@ -1445,7 +1540,7 @@ void forceteam(int client, int team, bool respawn, bool notify = false)
|
||||
|
||||
void calcscores()
|
||||
{
|
||||
loopv(clients) if (clients[i]->type!=ST_EMPTY)
|
||||
loopv(clients) if(clients[i]->type!=ST_EMPTY)
|
||||
{
|
||||
clients[i]->at3_score = clients[i]->state.frags * 100 / (clients[i]->state.deaths ? clients[i]->state.deaths : 1)
|
||||
+ clients[i]->state.flagscore < 3 ? 66 * clients[i]->state.flagscore : 66 + 33 * clients[i]->state.flagscore;
|
||||
@@ -1490,7 +1585,7 @@ bool refillteams(bool now, bool notify) // force only minimal amounts of player
|
||||
bool switched = false;
|
||||
|
||||
calcscores();
|
||||
loopv(clients) if (clients[i]->type!=ST_EMPTY) // playerlist stocktaking
|
||||
loopv(clients) if(clients[i]->type!=ST_EMPTY) // playerlist stocktaking
|
||||
{
|
||||
clients[i]->at3_dontmove = true;
|
||||
if(!clients[i]->awaitdisc)
|
||||
@@ -1500,8 +1595,8 @@ bool refillteams(bool now, bool notify) // force only minimal amounts of player
|
||||
{
|
||||
teamsize[t]++;
|
||||
teamscore[t] += clients[i]->at3_score;
|
||||
if(!m_ctf || !((sflaginfos[0].state==CTFF_STOLEN && sflaginfos[0].actor_cn==i) ||
|
||||
(sflaginfos[1].state==CTFF_STOLEN && sflaginfos[1].actor_cn==i) ))
|
||||
if(!m_flags || !((sflaginfos[0].state==CTFF_STOLEN && sflaginfos[0].actor_cn==i) ||
|
||||
(sflaginfos[1].state==CTFF_STOLEN && sflaginfos[1].actor_cn==i) ))
|
||||
{
|
||||
clients[i]->at3_dontmove = false;
|
||||
moveable[t]++;
|
||||
@@ -1519,7 +1614,7 @@ bool refillteams(bool now, bool notify) // force only minimal amounts of player
|
||||
if(now || gamemillis - lasttime_eventeams > 8000 + allplayers * 1000 || diffnum > 2 + allplayers / 10)
|
||||
{
|
||||
// time to even out teams
|
||||
loopv(clients) if (clients[i]->type!=ST_EMPTY && team_int(clients[i]->team) != bigteam) clients[i]->at3_dontmove = true; // dont move small team players
|
||||
loopv(clients) if(clients[i]->type!=ST_EMPTY && team_int(clients[i]->team) != bigteam) clients[i]->at3_dontmove = true; // dont move small team players
|
||||
while(diffnum > 1 && moveable[bigteam] > 0)
|
||||
{
|
||||
// pick best fitting cn
|
||||
@@ -1528,7 +1623,7 @@ bool refillteams(bool now, bool notify) // force only minimal amounts of player
|
||||
int bestfit = 1000000000;
|
||||
int targetscore = diffscore / (diffnum & ~1);
|
||||
s_sprintf(atlog)("at-target: %d, ", targetscore);
|
||||
loopv(clients) if (clients[i]->type!=ST_EMPTY && !clients[i]->at3_dontmove) // try all still movable players
|
||||
loopv(clients) if(clients[i]->type!=ST_EMPTY && !clients[i]->at3_dontmove) // try all still movable players
|
||||
{
|
||||
int fit = targetscore - clients[i]->at3_score;
|
||||
if(fit < 0 ) fit = -(fit * 15) / 10; // avoid too good players
|
||||
@@ -1607,7 +1702,7 @@ void resetmap(const char *newname, int newmode, int newtime, bool notify)
|
||||
{
|
||||
if(!lastteammode)
|
||||
shuffleteams(false);
|
||||
else if (autoteam)
|
||||
else if(autoteam)
|
||||
refillteams(true, false);
|
||||
}
|
||||
// send spawns
|
||||
@@ -1624,6 +1719,7 @@ void resetmap(const char *newname, int newmode, int newtime, bool notify)
|
||||
demonextmatch = false;
|
||||
setupdemorecord();
|
||||
}
|
||||
if(m_ktf) { sendflaginfo(0, 0); sendflaginfo(1, 0); }
|
||||
}
|
||||
|
||||
void nextcfgset(bool notify = true) // load next maprotation set
|
||||
@@ -1813,7 +1909,7 @@ const char *disc_reason(int reason)
|
||||
void disconnect_client(int n, int reason)
|
||||
{
|
||||
if(!clients.inrange(n) || clients[n]->type!=ST_TCPIP) return;
|
||||
if(m_ctf) loopi(2) if(sflaginfos[i].state==CTFF_STOLEN && sflaginfos[i].actor_cn==n) flagaction(i, SV_FLAGDROP, n);
|
||||
if(m_flags) loopi(2) if(sflaginfos[i].state==CTFF_STOLEN && sflaginfos[i].actor_cn==n) flagaction(i, SV_FLAGLOST, n);
|
||||
client &c = *clients[n];
|
||||
savedscore *sc = findscore(c, true);
|
||||
if(sc) sc->save(c.state);
|
||||
@@ -2069,7 +2165,7 @@ int checktype(int type, client *cl)
|
||||
static int edittypes[] = { SV_EDITENT, SV_EDITH, SV_EDITT, SV_EDITS, SV_EDITD, SV_EDITE };
|
||||
if(cl && smode!=1) loopi(sizeof(edittypes)/sizeof(int)) if(type == edittypes[i]) return -1;
|
||||
// server only messages
|
||||
static int servtypes[] = { SV_INITS2C, SV_MAPRELOAD, SV_SERVMSG, SV_GIBDAMAGE, SV_DAMAGE, SV_HITPUSH, SV_SHOTFX, SV_DIED, SV_SPAWNSTATE, SV_FORCEDEATH, SV_ITEMACC, SV_ITEMSPAWN, SV_TIMEUP, SV_CDIS, SV_PONG, SV_RESUME, SV_FLAGINFO, SV_ARENAWIN, SV_SENDDEMOLIST, SV_SENDDEMO, SV_DEMOPLAYBACK, SV_CLIENT, SV_CALLVOTESUC, SV_CALLVOTEERR, SV_VOTERESULT, SV_WHOISINFO };
|
||||
static int servtypes[] = { SV_INITS2C, SV_MAPRELOAD, SV_SERVMSG, SV_GIBDAMAGE, SV_DAMAGE, SV_HITPUSH, SV_SHOTFX, SV_DIED, SV_SPAWNSTATE, SV_FORCEDEATH, SV_ITEMACC, SV_ITEMSPAWN, SV_TIMEUP, SV_CDIS, SV_PONG, SV_RESUME, SV_FLAGINFO, SV_ARENAWIN, SV_SENDDEMOLIST, SV_SENDDEMO, SV_DEMOPLAYBACK, SV_CLIENT, SV_CALLVOTESUC, SV_CALLVOTEERR, SV_VOTERESULT, SV_WHOISINFO, SV_FLAGS, SV_FLAGRESET };
|
||||
if(cl) loopi(sizeof(servtypes)/sizeof(int)) if(type == servtypes[i]) return -1;
|
||||
return type;
|
||||
}
|
||||
@@ -2142,7 +2238,7 @@ void process(ENetPacket *packet, int sender, int chan) // sender may be -1
|
||||
welcomepacket(p, sender);
|
||||
enet_packet_resize(packet, p.length());
|
||||
sendpacket(sender, 1, packet);
|
||||
if(smapname[0] && m_ctf) loopi(2) sendflaginfo(i, -1, sender);
|
||||
if(smapname[0] && m_flags) loopi(2) sendflaginfo(i, -1, sender);
|
||||
if(clientrole != CR_DEFAULT) changeclientrole(sender, clientrole, NULL, true);
|
||||
}
|
||||
|
||||
@@ -2443,19 +2539,16 @@ void process(ENetPacket *packet, int sender, int chan) // sender may be -1
|
||||
|
||||
case SV_FLAGPICKUP:
|
||||
case SV_FLAGDROP:
|
||||
case SV_FLAGLOST:
|
||||
case SV_FLAGRETURN:
|
||||
case SV_FLAGSCORE:
|
||||
case SV_FLAGRESET:
|
||||
{
|
||||
if(!m_flags) { disconnect_client(sender, DISC_TAGT); return; }
|
||||
flagaction(getint(p), type, sender);
|
||||
break;
|
||||
}
|
||||
|
||||
case SV_FLAGS:
|
||||
cl->state.flagscore = getint(p);
|
||||
QUEUE_MSG;
|
||||
break;
|
||||
|
||||
case SV_SETADMIN:
|
||||
{
|
||||
bool claim = getint(p) != 0;
|
||||
@@ -2681,10 +2774,18 @@ void serverslice(uint timeout) // main server update, called from cube main lo
|
||||
{
|
||||
processevents();
|
||||
checkitemspawns(diff);
|
||||
if(m_ctf) loopi(2)
|
||||
if(m_flags) loopi(2)
|
||||
{
|
||||
sflaginfo &f = sflaginfos[i];
|
||||
if(f.state==CTFF_DROPPED && gamemillis-f.lastupdate>30000) flagaction(i, SV_FLAGRESET, -1);
|
||||
if(f.state == CTFF_DROPPED && gamemillis-f.lastupdate > (m_ctf ? 30000 : 10000)) flagaction(i, SV_FLAGRESET, -1);
|
||||
if(m_htf && f.state == CTFF_INBASE && gamemillis-f.lastupdate > 10000)
|
||||
{
|
||||
htf_forceflag(i);
|
||||
}
|
||||
if(m_ktf && f.state == CTFF_STOLEN && gamemillis-f.lastupdate > 15000)
|
||||
{
|
||||
flagaction(i, SV_FLAGSCORE, f.actor_cn);
|
||||
}
|
||||
}
|
||||
if(m_arena) arenacheck();
|
||||
}
|
||||
@@ -2750,20 +2851,20 @@ void serverslice(uint timeout) // main server update, called from cube main lo
|
||||
{
|
||||
|
||||
cvector teams;
|
||||
bool flag;
|
||||
bool addteam;
|
||||
loopv(clients)
|
||||
{
|
||||
if(clients[i]->type == ST_EMPTY || !clients[i]->name[0]) continue;
|
||||
flag = true;
|
||||
addteam = true;
|
||||
loopvj(teams)
|
||||
{
|
||||
if(strcmp(clients[i]->team,teams[j])==0 || !clients[i]->team[0])
|
||||
{
|
||||
flag = false;
|
||||
addteam = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(flag) teams.add(clients[i]->team);
|
||||
if(addteam) teams.add(clients[i]->team);
|
||||
}
|
||||
|
||||
loopv(teams)
|
||||
@@ -2778,7 +2879,7 @@ void serverslice(uint timeout) // main server update, called from cube main lo
|
||||
flagscore += clients[j]->state.flagscore;
|
||||
}
|
||||
logger->writeline(log::info, "Team %5s: %3d frags", teams[i], fragscore);
|
||||
if(m_ctf) logger->writeline(log::info, "Team %5s: %3d flags", teams[i], flagscore); // ctf only
|
||||
if(m_flags) logger->writeline(log::info, "Team %5s: %3d flags", teams[i], flagscore); // ctf only
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2910,19 +3011,19 @@ void extinfo_teamscorebuf(ucharbuf &p)
|
||||
if(!m_teammode) return;
|
||||
|
||||
cvector teams;
|
||||
bool flag;
|
||||
bool addteam;
|
||||
loopv(clients) if(clients[i]->type!=ST_EMPTY)
|
||||
{
|
||||
flag = true;
|
||||
addteam = true;
|
||||
loopvj(teams)
|
||||
{
|
||||
if(strcmp(clients[i]->team,teams[j])==0 || !clients[i]->team[0])
|
||||
{
|
||||
flag = false;
|
||||
addteam = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(flag) teams.add(clients[i]->team);
|
||||
if(addteam) teams.add(clients[i]->team);
|
||||
}
|
||||
|
||||
loopv(teams)
|
||||
@@ -2937,7 +3038,7 @@ void extinfo_teamscorebuf(ucharbuf &p)
|
||||
flagscore += clients[j]->state.flagscore;
|
||||
}
|
||||
putint(p,fragscore); //add fragscore per team
|
||||
if(m_ctf) //when capture mode
|
||||
if(m_flags) //when capture mode
|
||||
{
|
||||
putint(p,flagscore); //add flagscore per team
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
void processevent(client *c, explodeevent &e)
|
||||
{
|
||||
clientstate &gs = c->state;
|
||||
switch(e.gun)
|
||||
switch(e.gun)
|
||||
{
|
||||
case GUN_GRENADE:
|
||||
if(!gs.grenades.remove(e.id)) return;
|
||||
@@ -79,14 +79,7 @@ void processevent(client *c, shotevent &e)
|
||||
|
||||
void processevent(client *c, suicideevent &e)
|
||||
{
|
||||
clientstate &gs = c->state;
|
||||
if(gs.state!=CS_ALIVE) return;
|
||||
gs.frags--;
|
||||
gs.deaths++;
|
||||
sendf(-1, 1, "ri4", SV_DIED, c->clientnum, c->clientnum, gs.frags);
|
||||
c->position.setsizenodelete(0);
|
||||
gs.state = CS_DEAD;
|
||||
gs.respawn();
|
||||
serverdamage(c, c, 1000, GUN_KNIFE, false);
|
||||
logger->writeline(log::info, "[%s] %s suicided", c->hostname, c->name);
|
||||
}
|
||||
|
||||
@@ -102,7 +95,7 @@ void processevent(client *c, reloadevent &e)
|
||||
clientstate &gs = c->state;
|
||||
if(!gs.isalive(gamemillis) ||
|
||||
e.gun<GUN_KNIFE || e.gun>=NUMGUNS ||
|
||||
!reloadable_gun(e.gun) ||
|
||||
!reloadable_gun(e.gun) ||
|
||||
gs.ammo[e.gun]<=0)
|
||||
return;
|
||||
|
||||
@@ -148,7 +141,7 @@ void processevents()
|
||||
while(c->events.length())
|
||||
{
|
||||
gameevent &e = c->events[0];
|
||||
if(e.type<GE_SUICIDE)
|
||||
if(e.type<GE_SUICIDE)
|
||||
{
|
||||
if(e.shot.millis>gamemillis) break;
|
||||
if(e.shot.millis<c->lastevent) { clearevent(c); continue; }
|
||||
|
||||
@@ -299,7 +299,7 @@ bool load_world(char *mname) // still supports all map formats that have
|
||||
if(e.attr1>32) e.attr1 = 32; // 12_03 and below
|
||||
}
|
||||
|
||||
if (hdr.version<MAPVERSION && strncmp(hdr.head,"CUBE",4)==0) //only render lights, pl starts and map models on old maps
|
||||
if(hdr.version<MAPVERSION && strncmp(hdr.head,"CUBE",4)==0) //only render lights, pl starts and map models on old maps
|
||||
{
|
||||
switch(e.type)
|
||||
{
|
||||
|
||||