diff --git a/source/src/client.cpp b/source/src/client.cpp index e2093420..54c93798 100644 --- a/source/src/client.cpp +++ b/source/src/client.cpp @@ -69,7 +69,7 @@ int smallerteam() void changeteam(int team) // force team and respawn { c2sinit = false; - if(m_ctf) dropctfflag(); + if(m_ctf) tryflagdrop(); s_strncpy(player1->team, team_string(team), MAXTEAMLEN+1); player1->lastaction = lastmillis; player1->state = CS_DEAD; diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index cfce433f..819d9d16 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -94,29 +94,7 @@ void freebotent(botent *d) }; }; -void dropctfflag() -{ - int flag = team_opposite(team_int(player1->team)); - flaginfo &f = flaginfos[flag]; - if(f.state==CTFF_STOLEN && f.actor==player1) - { - addmsg(SV_FLAGDROP, "ri", flag); - f.flag->spawned = false; - f.state = CTFF_DROPPED; - }; -}; -void resetctfflag() -{ - int flag = team_opposite(team_int(player1->team)); - flaginfo &f = flaginfos[flag]; - if(f.state==CTFF_STOLEN && f.actor==player1) - { - addmsg(SV_FLAGRESET, "ri", flag); - f.flag->spawned = false; - f.state = CTFF_INBASE; - }; -}; void respawnself() { @@ -494,7 +472,7 @@ void selfdamage(int damage, int actor, playerent *act, bool gib, playerent *pl) }; if(pl==player1) { - if(m_ctf) dropctfflag(); + if(m_ctf) tryflagdrop(); showscores(true); setscope(false); addmsg(gib ? SV_GIBDIED : SV_DIED, "ri", actor); @@ -624,8 +602,110 @@ void suicide() COMMAND(suicide, ARG_NONE); +// ctf flag actions done by the local player -void flagaction(int flag, int action) +void flagpickup() +{ + int flag = team_opposite(team_int(player1->team)); + flaginfo &f = flaginfos[flag]; + if(f.flag) + { + f.flag->spawned = false; + f.actor = player1; // do this although we don't know if we picked the flag to avoid getting it after a possible respawn + f.state = CTFF_STOLEN; + addmsg(SV_FLAGPICKUP, "ri", flag); + }; +}; + +void tryflagdrop() +{ + int flag = team_opposite(team_int(player1->team)); + flaginfo &f = flaginfos[flag]; + if(f.state==CTFF_STOLEN && f.actor==player1) + { + addmsg(SV_FLAGDROP, "ri", flag); + f.flag->spawned = false; + f.state = CTFF_DROPPED; + }; +}; + +void flagreturn() +{ + int flag = team_int(player1->team); + flaginfo &f = flaginfos[flag]; + if(f.flag) + { + f.flag->spawned = false; + addmsg(SV_FLAGRETURN, "ri", flag); + }; +}; + +void flagscore() +{ + int flag = team_opposite(team_int(player1->team)); + addmsg(SV_FLAGSCORE, "ri", flag); +}; + +void flagreset() +{ + int flag = team_opposite(team_int(player1->team)); + flaginfo &f = flaginfos[flag]; + if(f.state==CTFF_STOLEN && f.actor==player1) + { + addmsg(SV_FLAGRESET, "ri", flag); + f.flag->spawned = false; + f.state = CTFF_INBASE; + }; +}; + +// flag actions from the net + +void flagstolen(int flag, int action, playerent *actor) +{ + if(actor) + { + flaginfo &f = flaginfos[flag]; + f.actor = actor; + f.flag->spawned = false; + flagmsg(flag, action); + }; +}; + +void flagdropped(int flag, int action, short x, short y, short z) +{ + flaginfo &f = flaginfos[flag]; + sqr *dropplace = S_SECURE(x, y); + if(!dropplace) return; + + z -= 4; + float floor = (float) dropplace->floor; + if(z > hdr.waterlevel) // above water + { + if(floor < hdr.waterlevel) z = hdr.waterlevel; // avoid dropping into water + else z = (short) floor; + }; + + f.flag->x = x; + f.flag->y = y; + f.flag->z = z; + f.flag->spawned = true; + flagmsg(flag, action); +}; + +void flaginbase(int flag, int action, playerent *actor) +{ + flaginfo &f = flaginfos[flag]; + if(actor) f.actor = actor; + 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; + flagmsg(flag, action); +}; + +// msg and audio feedback + +void flagmsg(int flag, int action) { flaginfo &f = flaginfos[flag]; if(!f.actor) return; @@ -635,11 +715,7 @@ void flagaction(int flag, int action) case SV_FLAGPICKUP: { playsound(S_FLAGPICKUP); - if(f.actor==player1) - { - conoutf("\f2you got the enemy flag"); - f.pick_ack = true; - } + if(f.actor==player1) conoutf("\f2you got the enemy flag"); else conoutf("\f2%s got %s flag", f.actor->name, (ownflag ? "your": "the enemy")); break; }; diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index 2ba5f83a..e3205dab 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -418,49 +418,35 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) flaginfo &f = flaginfos[flag]; f.state = getint(p); int action = getint(p); + switch(f.state) { case CTFF_STOLEN: { - int actor_cn = getint(p); - f.actor = actor_cn == getclientnum() ? player1 : getclient(actor_cn); - f.flag->spawned = false; + int actor = getint(p); + flagstolen(flag, action, actor == getclientnum() ? player1 : getclient(actor)); break; }; case CTFF_DROPPED: { - f.flag->x = (ushort) (getint(p)/DMF); - f.flag->y = (ushort) (getint(p)/DMF); - f.flag->z = (ushort) (getint(p)/DMF); - f.flag->z -= 4; - sqr *dropplace = S_SECURE(f.flag->x, f.flag->y); - if(!dropplace) return; - float floor = (float)dropplace->floor; - if(f.flag->z > hdr.waterlevel) // above water - { - if(floor < hdr.waterlevel) - f.flag->z = hdr.waterlevel; // avoid dropping into water - else - f.flag->z = (short)floor; - }; - f.flag->spawned = true; + short x = (ushort) (getint(p)/DMF); + short y = (ushort) (getint(p)/DMF); + short z = (ushort) (getint(p)/DMF); + flagdropped(flag, action, x, y, z); break; }; case CTFF_INBASE: { - if(action==SV_FLAGRETURN) + playerent *actor = NULL; + if(action == SV_FLAGRETURN) { - int returnerer_cn = getint(p); - f.actor = returnerer_cn == getclientnum() ? player1 : getclient(returnerer_cn); + int a = getint(p); + actor = a == getclientnum() ? player1 : getclient(a); }; - 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; + flaginbase(flag, action, actor); break; }; }; - flagaction(flag, action); break; }; diff --git a/source/src/entities.cpp b/source/src/entities.cpp index 0004c671..a1ff9c47 100644 --- a/source/src/entities.cpp +++ b/source/src/entities.cpp @@ -186,37 +186,23 @@ void pickup(int n, playerent *d) d->onladder = true; break; - // EDIT: AH case CTF_FLAG: { - if(d->type!=ENT_PLAYER) break; - int team = ents[n].attr2; - flaginfo &f = flaginfos[team]; - bool isownflag = team == team_int(d->team); - if(f.state == CTFF_STOLEN) break; - else if(isownflag && f.state == CTFF_DROPPED) - { - addmsg(SV_FLAGRETURN, "ri", team); - ents[n].spawned = false; - } - else if(!isownflag) - { - addmsg(SV_FLAGPICKUP, "ri", team); - ents[n].spawned = false; - f.actor = d; // do this although we don't know if we picked the flag to avoid getting it after a possible respawn - f.state = CTFF_STOLEN; - f.pick_ack = false; - } - else if(isownflag && f.state == CTFF_INBASE) + if(d==player1) { - flaginfo &ef = flaginfos[team_opposite(team)]; - if(ef.state == CTFF_STOLEN && ef.actor == d) + int flag = ents[n].attr2; + flaginfo &f = flaginfos[flag]; + flaginfo &of = flaginfos[team_opposite(flag)]; + if(f.state == CTFF_STOLEN) break; + + if(flag == team_int(d->team)) // its the own flag { - addmsg(SV_FLAGSCORE, "ri", team_opposite(team)); - ef.state = CTFF_INBASE; - }; + if(f.state == CTFF_DROPPED) flagreturn(); + else if(f.state == CTFF_INBASE && of.state == CTFF_STOLEN && of.actor == d) flagscore(); + } + else flagpickup(); }; - break; + break; }; }; }; diff --git a/source/src/entity.h b/source/src/entity.h index d286fb9f..da507d19 100644 --- a/source/src/entity.h +++ b/source/src/entity.h @@ -229,8 +229,8 @@ struct flaginfo playerent *actor; vec originalpos; int state; // one of the types above - bool pick_ack; - flaginfo() : flag(0), actor(0), state(CTFF_INBASE), pick_ack(false) {}; + bool ack; + flaginfo() : flag(0), actor(0), state(CTFF_INBASE), ack(false) {}; }; enum { NADE_ACTIVATED = 1, NADE_THROWED, GIB}; diff --git a/source/src/protos.h b/source/src/protos.h index 7998a871..b00bc2ea 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -111,9 +111,16 @@ extern playerent *newclient(int cn); extern void timeupdate(int timeremain); extern void fixcamerarange(physent *cam = camera1); extern void respawnself(); -extern void dropctfflag(); extern void setskin(playerent *pl, int skin); //game mode extras +extern void flagpickup(); +extern void tryflagdrop(); +extern void flagreturn(); +extern void flagscore(); +extern void flagstolen(int flag, int action, playerent *thief); +extern void flagdropped(int flag, int action, short x, short y, short z); +extern void flaginbase(int flag, int action, playerent *actor); +extern void flagmsg(int flag, int action); extern void arenarespawn(); extern void respawn(); extern void mastercommand(int cmd, int arg1); @@ -296,7 +303,6 @@ extern bool intersect(dynent *d, vec &from, vec &to, vec *end = NULL); extern void renderents(); extern void putitems(ucharbuf &p); extern void realpickup(int n, playerent *d); -extern void flagaction(int team, int action); extern void renderentities(); extern void resetspawns(); extern void setspawn(int i, bool on); diff --git a/source/src/renderextras.cpp b/source/src/renderextras.cpp index 0e2a393e..793c03e3 100644 --- a/source/src/renderextras.cpp +++ b/source/src/renderextras.cpp @@ -452,7 +452,7 @@ void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwat // big flag icon flaginfo &f = flaginfos[team_opposite(team_int(player1->team))]; - if(f.state==CTFF_STOLEN && f.actor == player1 && f.pick_ack ) + if(f.state==CTFF_STOLEN && f.actor == player1) { glPushMatrix(); glOrtho(0, VIRTW/2, VIRTH/2, 0, -1, 1);