demo playback as 1st person, convenient spect toggling
git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@1893 e016b1c5-ed68-44aa-a2f7-31cac88cffde
This commit is contained in:
+30
-39
@@ -6,7 +6,6 @@
|
||||
|
||||
int nextmode = 0; // nextmode becomes gamemode after next map load
|
||||
VAR(gamemode, 1, 0, 0);
|
||||
VARF(followmode, 0, 1, 1, if(player1->state==CS_SPECTATE) followplayer (player1->followplayercn)); // follow(0) or embody(1)
|
||||
|
||||
flaginfo flaginfos[2];
|
||||
|
||||
@@ -821,59 +820,51 @@ void refreshsopmenu(void *menu, bool init)
|
||||
}
|
||||
}
|
||||
|
||||
void followplayer(int j)
|
||||
void spectate(int mode) // set new spect mode
|
||||
{
|
||||
if(player1->state==CS_ALIVE) return;
|
||||
player1->state = CS_SPECTATE; // fix CS_DEAD state
|
||||
if(!player1->isspectating()) return;
|
||||
showscores(false);
|
||||
player1->spectating = (followmode==1) ? SM_EMBODYPLAYER : SM_FOLLOWPLAYER;
|
||||
if(players.length())
|
||||
switch(mode)
|
||||
{
|
||||
if(j!=-1)
|
||||
case SM_FOLLOW1ST:
|
||||
case SM_FOLLOW3RD:
|
||||
case SM_FOLLOW3RD_TRANSPARENT:
|
||||
{
|
||||
if(players.inrange(j) && players[j] && players[j]->state == CS_ALIVE)
|
||||
if(players.length())
|
||||
{
|
||||
player1->followplayercn = j;
|
||||
return;
|
||||
player1->followplayercn %= players.length();
|
||||
break;
|
||||
}
|
||||
}
|
||||
loopv(players)
|
||||
case SM_FLY:
|
||||
{
|
||||
player1->followplayercn = (player1->followplayercn+1+i) % players.length();
|
||||
ASSERT(player1->followplayercn < players.length());
|
||||
if(players[player1->followplayercn] && players[player1->followplayercn]->state == CS_ALIVE) return;
|
||||
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
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
player1->spectating = SM_FLY;
|
||||
player1->spectating = mode;
|
||||
}
|
||||
|
||||
void spectate()
|
||||
|
||||
void togglespect() // cycle through all spectating modes
|
||||
{
|
||||
if(player1->state==CS_ALIVE) return;
|
||||
showscores(false);
|
||||
if(player1->spectating != SM_NONE && 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->spectating = SM_FLY;
|
||||
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);
|
||||
}
|
||||
|
||||
void toggledeathcam()
|
||||
{
|
||||
showscores(false);
|
||||
if(player1->spectating == SM_FOLLOWPLAYER) followplayer();
|
||||
else
|
||||
{
|
||||
player1->spectating = (player1->spectating+1) % SM_NUM;
|
||||
if(player1->spectating==SM_FOLLOWPLAYER) followplayer();
|
||||
}
|
||||
}
|
||||
|
||||
COMMAND(followplayer, ARG_1INT);
|
||||
COMMAND(spectate, ARG_NONE);
|
||||
COMMAND(spectate, ARG_1INT);
|
||||
COMMAND(togglespect, ARG_NONE);
|
||||
|
||||
int isalive() { return player1->state==CS_ALIVE ? 1 : 0; }
|
||||
COMMANDN(alive, isalive, ARG_NONE);
|
||||
|
||||
@@ -653,7 +653,8 @@ void parsemessages(int cn, playerent *d, ucharbuf &p)
|
||||
if(demoplayback)
|
||||
{
|
||||
player1->state = CS_SPECTATE;
|
||||
player1->spectating = SM_EMBODYPLAYER;
|
||||
player1->spectating = SM_NONE;
|
||||
togglespect();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+16
-1
@@ -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_FLY, SM_FOLLOWPLAYER, SM_EMBODYPLAYER, SM_NUM };
|
||||
enum { SM_NONE = 0, SM_FOLLOW1ST, SM_FOLLOW3RD, SM_FOLLOW3RD_TRANSPARENT, SM_FLY, SM_NUM };
|
||||
|
||||
struct physent
|
||||
{
|
||||
@@ -406,8 +406,23 @@ struct playerent : dynent, playerstate
|
||||
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); }
|
||||
|
||||
/*
|
||||
static struct playerent *cameraplayer()
|
||||
{
|
||||
extern playerent *player1;
|
||||
extern vector<struct playerent *>players;
|
||||
if(player1->isspectating())
|
||||
{
|
||||
if(player1->spectating==SM_FOLLOW1ST && players.inrange(player1->followplayercn)) return players[player1->followplayercn];
|
||||
else return NULL;
|
||||
}
|
||||
else return player1;
|
||||
}*/
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CBot;
|
||||
|
||||
struct botent : playerent
|
||||
|
||||
@@ -515,13 +515,9 @@ void attack(bool on)
|
||||
void jumpn(bool on)
|
||||
{
|
||||
if(intermission) return;
|
||||
if(player1->state==CS_DEAD || player1->state==CS_SPECTATE)
|
||||
if(player1->isspectating())
|
||||
{
|
||||
if(on)
|
||||
{
|
||||
showscores(false);
|
||||
player1->spectating = SM_FLY;
|
||||
}
|
||||
if(on) togglespect();
|
||||
}
|
||||
else if(player1->crouching) return;
|
||||
else player1->jumpnext = on;
|
||||
|
||||
+2
-3
@@ -180,7 +180,7 @@ extern void gl_drawframe(int w, int h, float changelod, float curfps);
|
||||
extern void clearminimap();
|
||||
extern void rendercursor(int x, int y, int w);
|
||||
extern void renderaboveheadicon(playerent *p);
|
||||
extern void drawcrosshair(bool showteamwarning);
|
||||
extern void drawcrosshair(playerent *p, bool showteamwarning);
|
||||
extern void drawscope();
|
||||
extern float dynfov();
|
||||
|
||||
@@ -288,8 +288,7 @@ extern void serveropcommand(int cmd, int arg1);
|
||||
extern void refreshsopmenu(void *menu, bool init);
|
||||
extern char *colorname(playerent *d, int num = 0, char *name = NULL, const char *prefix = "");
|
||||
extern char *colorping(int ping);
|
||||
extern void toggledeathcam();
|
||||
extern void followplayer(int j = -1);
|
||||
extern void togglespect();
|
||||
|
||||
struct votedisplayinfo
|
||||
{
|
||||
|
||||
+14
-10
@@ -309,6 +309,7 @@ void recomputecamera()
|
||||
{
|
||||
if((player1->state==CS_SPECTATE || player1->state==CS_DEAD) && !editmode)
|
||||
{
|
||||
bool followvalid = players.inrange(player1->followplayercn) && players[player1->followplayercn];
|
||||
switch(player1->spectating)
|
||||
{
|
||||
case SM_NONE:
|
||||
@@ -327,13 +328,13 @@ void recomputecamera()
|
||||
case SM_FLY:
|
||||
camera1 = player1;
|
||||
break;
|
||||
case SM_FOLLOWPLAYER:
|
||||
case SM_EMBODYPLAYER:
|
||||
if(!players.inrange(player1->followplayercn) || !players[player1->followplayercn])
|
||||
{
|
||||
toggledeathcam();
|
||||
return;
|
||||
}
|
||||
case SM_FOLLOW1ST:
|
||||
if(!followvalid) { togglespect(); return; }
|
||||
camera1 = players[player1->followplayercn];
|
||||
break;
|
||||
case SM_FOLLOW3RD:
|
||||
case SM_FOLLOW3RD_TRANSPARENT:
|
||||
if(!followvalid) { togglespect(); return; }
|
||||
playerent *p = players[player1->followplayercn];
|
||||
static physent followcam;
|
||||
static playerent *lastplayer;
|
||||
@@ -350,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_FOLLOWPLAYER)
|
||||
if(player1->spectating == 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;
|
||||
@@ -663,8 +664,11 @@ void drawhudgun(int w, int h, float aspect, int farplane)
|
||||
{
|
||||
sethudgunperspective(true);
|
||||
|
||||
if(hudgun && player1->state==CS_ALIVE) player1->weaponsel->renderhudmodel();
|
||||
//if(hudgun && player1->state==CS_SPECTATE && players[player1->followplayercn]) players[player1->followplayercn]->weaponsel->renderhudmodel();
|
||||
if(hudgun && !player1->isspectating() && camera1->type==ENT_PLAYER)
|
||||
{
|
||||
playerent *p = (playerent *)camera1;
|
||||
if(p->state==CS_ALIVE) p->weaponsel->renderhudmodel();
|
||||
}
|
||||
rendermenumdl();
|
||||
|
||||
sethudgunperspective(false);
|
||||
|
||||
+22
-18
@@ -120,7 +120,7 @@ void loadcrosshair(char *c)
|
||||
|
||||
COMMAND(loadcrosshair, ARG_1STR);
|
||||
|
||||
void drawcrosshair(bool showteamwarning)
|
||||
void drawcrosshair(playerent *p, bool showteamwarning)
|
||||
{
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
static Texture *teammatetex = NULL;
|
||||
@@ -132,14 +132,14 @@ void drawcrosshair(bool showteamwarning)
|
||||
if(crosshairfx)
|
||||
{
|
||||
if(showteamwarning) glColor3ub(255, 0, 0);
|
||||
else if(player1->gunwait) glColor3ub(128,128,128);
|
||||
else if(p->gunwait) glColor3ub(128,128,128);
|
||||
else if(!m_osok)
|
||||
{
|
||||
if(player1->health<=25) glColor3ub(255,0,0);
|
||||
else if(player1->health<=50) glColor3ub(255,128,0);
|
||||
if(p->health<=25) glColor3ub(255,0,0);
|
||||
else if(p->health<=50) glColor3ub(255,128,0);
|
||||
}
|
||||
}
|
||||
float chsize = (float)crosshairsize * (player1->weaponsel->type==GUN_ASSAULT && player1->weaponsel->shots > 3 ? 1.4f : 1.0f) * (showteamwarning ? 2.0f : 1.0f);
|
||||
float chsize = (float)crosshairsize * (p->weaponsel->type==GUN_ASSAULT && p->weaponsel->shots > 3 ? 1.4f : 1.0f) * (showteamwarning ? 2.0f : 1.0f);
|
||||
glTexCoord2i(0, 0); glVertex2f(VIRTW/2 - chsize, VIRTH/2 - chsize);
|
||||
glTexCoord2i(1, 0); glVertex2f(VIRTW/2 + chsize, VIRTH/2 - chsize);
|
||||
glTexCoord2i(1, 1); glVertex2f(VIRTW/2 + chsize, VIRTH/2 + chsize);
|
||||
@@ -375,6 +375,8 @@ void drawteamicons(int w, int h)
|
||||
|
||||
void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwater)
|
||||
{
|
||||
playerent *p = camera1->type==ENT_PLAYER ? (playerent *)camera1 : player1;
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
@@ -406,15 +408,15 @@ void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwat
|
||||
bool menu = menuvisible();
|
||||
bool command = getcurcommand() ? true : false;
|
||||
|
||||
if((player1->state==CS_ALIVE || player1->state==CS_EDITING) && !player1->weaponsel->reloading && !menu)
|
||||
if((p->state==CS_ALIVE || p->state==CS_EDITING) && !p->weaponsel->reloading && !menu)
|
||||
{
|
||||
bool drawteamwarning = crosshairteamsign && targetplayer && isteam(targetplayer->team, player1->team) && targetplayer->state!=CS_DEAD;
|
||||
player1->weaponsel->renderaimhelp(drawteamwarning);
|
||||
bool drawteamwarning = crosshairteamsign && targetplayer && isteam(targetplayer->team, p->team) && targetplayer->state!=CS_ALIVE;
|
||||
p->weaponsel->renderaimhelp(drawteamwarning);
|
||||
}
|
||||
|
||||
drawdmgindicator();
|
||||
|
||||
if(player1->state==CS_ALIVE && !hidehudequipment) drawequipicons();
|
||||
if(p->state==CS_ALIVE && !hidehudequipment) drawequipicons();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
if(!menu && (!hideradar || showmap)) drawradar(w, h);
|
||||
@@ -472,7 +474,8 @@ void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwat
|
||||
|
||||
if(!hidehudmsgs) hudmsgs.render();
|
||||
|
||||
if(!hidespecthud && player1->state==CS_DEAD && player1->spectating==SM_NONE)
|
||||
/*
|
||||
if(!hidespecthud && p->state==CS_DEAD && p->spectating==SM_NONE)
|
||||
{
|
||||
glLoadIdentity();
|
||||
glOrtho(0, VIRTW*3/2, VIRTH*3/2, 0, -1, 1);
|
||||
@@ -480,24 +483,25 @@ void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwat
|
||||
draw_textf("F7 spectate", left, top);
|
||||
draw_textf("F8 follow player", left, top+80);
|
||||
}
|
||||
*/
|
||||
|
||||
if(!hidespecthud && (player1->state==CS_SPECTATE || (player1->state==CS_DEAD && player1->spectating!=SM_NONE)))
|
||||
if(!hidespecthud && (p->state==CS_SPECTATE || (p->state==CS_DEAD && p->spectating!=SM_NONE)))
|
||||
{
|
||||
glLoadIdentity();
|
||||
glOrtho(0, VIRTW, VIRTH, 0, -1, 1);
|
||||
draw_text("SPECTATING", VIRTW/40, VIRTH/10*7);
|
||||
}
|
||||
|
||||
if(player1->state==CS_ALIVE)
|
||||
if(p->state==CS_ALIVE)
|
||||
{
|
||||
glLoadIdentity();
|
||||
glOrtho(0, VIRTW/2, VIRTH/2, 0, -1, 1);
|
||||
|
||||
if(!hidehudequipment)
|
||||
{
|
||||
draw_textf("%d", 90, 827, player1->health);
|
||||
if(player1->armour) draw_textf("%d", 390, 827, player1->armour);
|
||||
player1->weaponsel->renderstats();
|
||||
draw_textf("%d", 90, 827, p->health);
|
||||
if(p->armour) draw_textf("%d", 390, 827, p->armour);
|
||||
p->weaponsel->renderstats();
|
||||
}
|
||||
|
||||
if(m_ctf && !hidectfhud)
|
||||
@@ -514,12 +518,12 @@ 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(player1->team))];
|
||||
if(f.state==CTFF_STOLEN && f.actor == player1 && f.ack)
|
||||
flaginfo &f = flaginfos[team_opposite(team_int(p->team))];
|
||||
if(f.state==CTFF_STOLEN && f.actor == p && f.ack)
|
||||
{
|
||||
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(player1->team)), 1, 1/2.0f);
|
||||
drawctficon(VIRTW-225-10, VIRTH*5/8, 225, team_opposite(team_int(p->team)), 1, 1/2.0f);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,7 +447,6 @@ void renderclient(playerent *d, const char *mdlname, const char *vwepname, int t
|
||||
vec o(d->o);
|
||||
o.z -= d->dyneyeheight();
|
||||
int basetime = -((int)(size_t)d&0xFFF);
|
||||
//if(player1->state == CS_SPECTATE && d->clientnum == player1->followplayercn) return; // don't draw followed player (or see below for "see through")
|
||||
if(d->state==CS_DEAD)
|
||||
{
|
||||
if(d==player1 && d->allowmove()) return;
|
||||
@@ -484,8 +483,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->state == CS_DEAD || player1->state == CS_SPECTATE) && d->clientnum == player1->followplayercn && player1->spectating == SM_EMBODYPLAYER) anim |= ANIM_TRANSLUCENT; // see through followed player
|
||||
if(player1->state == CS_SPECTATE && d->clientnum == player1->followplayercn && player1->spectating == SM_EMBODYPLAYER) anim |= ANIM_TRANSLUCENT; // see through followed player
|
||||
if(player1->isspectating() && d->clientnum == player1->followplayercn && player1->spectating == 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);
|
||||
}
|
||||
@@ -514,7 +512,7 @@ void renderclient(playerent *d)
|
||||
void renderclients()
|
||||
{
|
||||
playerent *d;
|
||||
loopv(players) if((d = players[i]) && d->state!=CS_SPAWNING) renderclient(d);
|
||||
loopv(players) if((d = players[i]) && d->state!=CS_SPAWNING && (!player1->isspectating() || player1->spectating != SM_FOLLOW1ST || player1->followplayercn != i)) renderclient(d);
|
||||
if(player1->state==CS_DEAD || (reflecting && !refracting)) renderclient(player1);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ void shiftweapon(int s)
|
||||
selectweapon(player1->weapons[trygun]);
|
||||
}
|
||||
}
|
||||
else if(player1->isspectating()) { (player1->followplayercn += s) %= players.length(); }
|
||||
}
|
||||
|
||||
int currentprimary() { return player1->primweap->type; }
|
||||
@@ -516,7 +517,7 @@ void weapon::onselecting()
|
||||
}
|
||||
|
||||
void weapon::renderhudmodel() { renderhudmodel(owner->lastaction); }
|
||||
void weapon::renderaimhelp(bool teamwarning) { drawcrosshair(teamwarning); }
|
||||
void weapon::renderaimhelp(bool teamwarning) { drawcrosshair(owner, teamwarning); }
|
||||
int weapon::dynspread() { return info.spread; }
|
||||
float weapon::dynrecoil() { return info.recoil; }
|
||||
bool weapon::selectable() { return this != owner->weaponsel && owner->state == CS_ALIVE && !owner->weaponchanging; }
|
||||
@@ -863,7 +864,7 @@ void sniperrifle::onselecting() { weapon::onselecting(); scoped = false; }
|
||||
void sniperrifle::ondeselecting() { scoped = false; }
|
||||
void sniperrifle::onownerdies() { scoped = false; }
|
||||
void sniperrifle::renderhudmodel() { if(!scoped) weapon::renderhudmodel(); }
|
||||
void sniperrifle::renderaimhelp(bool teamwarning) { if(scoped) drawscope(); if(teamwarning) drawcrosshair(teamwarning); }
|
||||
void sniperrifle::renderaimhelp(bool teamwarning) { if(scoped) drawscope(); if(teamwarning) drawcrosshair(owner, teamwarning); }
|
||||
|
||||
void sniperrifle::setscope(bool enable) { if(this == owner->weaponsel && !reloading && owner->state == CS_ALIVE) scoped = enable; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user