diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index f8b121d5..22888457 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -136,6 +136,7 @@ VARP(showscoresondeath, 0, 1, 1); void deathstate(playerent *pl) { pl->state = CS_DEAD; + pl->spectatemode = SM_DEATHCAM; pl->lastpain = pl->lastaction = lastmillis; pl->move = pl->strafe = 0; pl->pitch = pl->roll = 0; @@ -823,6 +824,7 @@ void refreshsopmenu(void *menu, bool init) void spectate(int mode) // set new spect mode { if(!player1->isspectating()) return; + if(mode == player1->spectatemode) return; showscores(false); switch(mode) { @@ -835,32 +837,35 @@ void spectate(int mode) // set new spect mode player1->followplayercn %= players.length(); break; } + else mode = SM_FLY; } case SM_FLY: { - if(players.inrange(player1->followplayercn)) // set spectator location to last followed player + if(player1->spectatemode != SM_FLY) { - playerent *f = players[player1->followplayercn]; - player1->o = f->o; - player1->yaw = f->yaw; - player1->pitch = 0.0f; + if(players.inrange(player1->followplayercn)) // set spectator location to last followed player + { + playerent *f = players[player1->followplayercn]; + player1->o = f->o; + player1->yaw = f->yaw; + player1->pitch = 0.0f; + } + else entinmap(player1); // or drop 'em at a random place } - else entinmap(player1); // or drop 'em at a random place break; } default: break; } - player1->spectating = mode; + player1->spectatemode = mode; } void togglespect() // cycle through all spectating modes { - int mode ; - if(player1->spectating == SM_NONE) mode = SM_FOLLOW1ST; // start with 1st person spect - else mode = SM_FOLLOW1ST + (((player1->spectating) % (SM_NUM-SM_FOLLOW1ST))); - if(mode != player1->spectating) spectate(mode); - conoutf("%i", mode); + int mode; + if(player1->spectatemode<=SM_DEATHCAM) mode = SM_FOLLOW1ST; // start with 1st person spect + else mode = SM_FOLLOW1ST + (((player1->spectatemode-1) % (SM_NUM-SM_FOLLOW1ST))); + spectate(mode); } COMMAND(spectate, ARG_1INT); diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index ed41a704..2863a4b2 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -653,7 +653,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) if(demoplayback) { player1->state = CS_SPECTATE; - player1->spectating = SM_NONE; + player1->spectatemode = SM_NONE; togglespect(); } else diff --git a/source/src/entity.h b/source/src/entity.h index e0d854f6..29fa6ec2 100644 --- a/source/src/entity.h +++ b/source/src/entity.h @@ -89,7 +89,7 @@ static inline int magsize(int gun) { return guns[gun].magsize; } enum { ENT_PLAYER = 0, ENT_BOT, ENT_CAMERA, ENT_BOUNCE }; enum { CS_ALIVE = 0, CS_DEAD, CS_SPAWNING, CS_LAGGED, CS_EDITING, CS_SPECTATE }; enum { CR_DEFAULT = 0, CR_MASTER, CR_ADMIN }; -enum { SM_NONE = 0, SM_FOLLOW1ST, SM_FOLLOW3RD, SM_FOLLOW3RD_TRANSPARENT, SM_FLY, SM_NUM }; +enum { SM_NONE = 0, SM_DEATHCAM, SM_FOLLOW1ST, SM_FOLLOW3RD, SM_FOLLOW3RD_TRANSPARENT, SM_FLY, SM_NUM }; struct physent { @@ -339,9 +339,9 @@ struct playerent : dynent, playerstate int weaponchanging; int nextweapon; // weapon we switch to int skin, nextskin; // skin after respawning - int spectating, followplayercn; - virtual float dyneyeheight() { return (state==CS_DEAD || state==CS_SPECTATE) && spectating==SM_FLY ? 1.0f : physent::dyneyeheight(); } - bool allowmove() { return state!=CS_DEAD || spectating==SM_FLY; } + int spectatemode, followplayercn; + virtual float dyneyeheight() { return (state==CS_DEAD || state==CS_SPECTATE) && spectatemode==SM_FLY ? 1.0f : physent::dyneyeheight(); } + bool allowmove() { return state!=CS_DEAD || spectatemode==SM_FLY; } weapon *weapons[NUMGUNS]; weapon *weaponsel, *nextweaponsel, *primweap, *nextprimweap, *lastattackweapon; @@ -353,7 +353,7 @@ struct playerent : dynent, playerstate int smoothmillis; playerent() : clientnum(-1), plag(0), ping(0), lifesequence(0), frags(0), flagscore(0), deaths(0), lastpain(0), lastvoicecom(0), clientrole(CR_DEFAULT), - skin(0), nextskin(0), spectating(SM_NONE), followplayercn(0), + skin(0), nextskin(0), spectatemode(SM_NONE), followplayercn(0), weaponsel(NULL), nextweaponsel(NULL), primweap(NULL), nextprimweap(NULL), lastattackweapon(NULL), smoothmillis(-1) { @@ -390,7 +390,7 @@ struct playerent : dynent, playerstate lastattackweapon = NULL; attacking = false; weaponchanging = 0; - spectating = SM_NONE; + spectatemode = SM_NONE; followplayercn = 0; } @@ -405,7 +405,7 @@ struct playerent : dynent, playerstate void selectweapon(int w) { weaponsel = weapons[(gunselect = w)]; } void setprimary(int w) { primweap = weapons[(primary = w)]; } void setnextprimary(int w) { nextprimweap = weapons[(nextprimary = w)]; } - bool isspectating() { return state==CS_SPECTATE || (state==CS_DEAD && spectating); } + bool isspectating() { return state==CS_SPECTATE || (state==CS_DEAD && spectatemode > SM_NONE); } }; diff --git a/source/src/physics.cpp b/source/src/physics.cpp index 5dddf30d..53b64a86 100644 --- a/source/src/physics.cpp +++ b/source/src/physics.cpp @@ -249,7 +249,7 @@ void moveplayer(physent *pl, int moveres, bool local, int curtime) { bool water = false; const bool editfly = (editmode && local) || pl->state==CS_EDITING; - const bool specfly = local && pl->type==ENT_PLAYER && ((playerent *)pl)->spectating==SM_FLY; + const bool specfly = local && pl->type==ENT_PLAYER && ((playerent *)pl)->spectatemode==SM_FLY; vec d; // vector of direction we ideally want to move in diff --git a/source/src/rendergl.cpp b/source/src/rendergl.cpp index 381345f0..15ecb51f 100644 --- a/source/src/rendergl.cpp +++ b/source/src/rendergl.cpp @@ -310,9 +310,9 @@ void recomputecamera() if((player1->state==CS_SPECTATE || player1->state==CS_DEAD) && !editmode) { bool followvalid = players.inrange(player1->followplayercn) && players[player1->followplayercn]; - switch(player1->spectating) + switch(player1->spectatemode) { - case SM_NONE: + case SM_DEATHCAM: { static physent deathcam; if(camera1==&deathcam) return; @@ -351,7 +351,7 @@ void recomputecamera() followcam.o = p->o; // move camera into the desired direction using physics to avoid getting stuck in map geometry - if(player1->spectating == SM_FOLLOW3RD) + if(player1->spectatemode == SM_FOLLOW3RD) { followcam.vel.x = -(float)(cosf(RAD*(p->yaw-90)))*p->radius*1.5f; followcam.vel.y = -(float)(sinf(RAD*(p->yaw-90)))*p->radius*1.5f; diff --git a/source/src/renderhud.cpp b/source/src/renderhud.cpp index 27e23aff..0217f895 100644 --- a/source/src/renderhud.cpp +++ b/source/src/renderhud.cpp @@ -475,7 +475,7 @@ void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwat if(!hidehudmsgs) hudmsgs.render(); /* - if(!hidespecthud && p->state==CS_DEAD && p->spectating==SM_NONE) + if(!hidespecthud && p->state==CS_DEAD && p->spectatemode==SM_NONE) { glLoadIdentity(); glOrtho(0, VIRTW*3/2, VIRTH*3/2, 0, -1, 1); @@ -485,7 +485,7 @@ void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwat } */ - if(!hidespecthud && (p->state==CS_SPECTATE || (p->state==CS_DEAD && p->spectating!=SM_NONE))) + if(!hidespecthud && (p->state==CS_SPECTATE || (p->state==CS_DEAD && p->spectatemode!=SM_NONE))) { glLoadIdentity(); glOrtho(0, VIRTW, VIRTH, 0, -1, 1); diff --git a/source/src/rendermodel.cpp b/source/src/rendermodel.cpp index fdd46ddc..5bb7f2c6 100644 --- a/source/src/rendermodel.cpp +++ b/source/src/rendermodel.cpp @@ -486,7 +486,7 @@ void renderclient(playerent *d, const char *mdlname, const char *vwepname, int t } // FIXME: while networked my state as spectator seems to stay CS_DEAD, not CS_SPECTATE // flowtron: I fixed this for following at least (see followplayer()) - if(player1->isspectating() && d->clientnum == player1->followplayercn && player1->spectating == SM_FOLLOW3RD_TRANSPARENT) anim |= ANIM_TRANSLUCENT; // see through followed player + if(player1->isspectating() && d->clientnum == player1->followplayercn && player1->spectatemode == SM_FOLLOW3RD_TRANSPARENT) anim |= ANIM_TRANSLUCENT; // see through followed player rendermodel(mdlname, anim, tex, 1.5f, o, d->yaw+90, d->pitch/4, speed, basetime, d, a); if(isteam(player1->team, d->team)) renderaboveheadicon(d); } @@ -515,7 +515,7 @@ void renderclient(playerent *d) void renderclients() { playerent *d; - loopv(players) if((d = players[i]) && d->state!=CS_SPAWNING && (!player1->isspectating() || player1->spectating != SM_FOLLOW1ST || player1->followplayercn != i)) renderclient(d); + loopv(players) if((d = players[i]) && d->state!=CS_SPAWNING && (!player1->isspectating() || player1->spectatemode != SM_FOLLOW1ST || player1->followplayercn != i)) renderclient(d); if(player1->state==CS_DEAD || (reflecting && !refracting)) renderclient(player1); }