git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@997 e016b1c5-ed68-44aa-a2f7-31cac88cffde
This commit is contained in:
driAn
2007-05-14 18:43:59 +00:00
parent d3f97bc349
commit fd2ef397a2
13 changed files with 213 additions and 57 deletions
+6
View File
@@ -127,6 +127,12 @@ void disconnect(int onlyclean, int async)
conoutf("disconnected");
cleanup = true;
}
else if(demoplayback)
{
// todo: additional cleanups
cleanup = true;
}
if(cleanup)
{
stop();
+2 -2
View File
@@ -564,14 +564,14 @@ void flagmsg(int flag, int action)
case SV_FLAGDROP:
{
playsound(S_FLAGDROP);
if(f.actor==player1) conoutf("you lost the flag");
if(f.actor==player1) conoutf("\f2you lost the flag");
else conoutf("\f2%s lost %s flag", f.actor->name, (own ? "your" : "the enemy"));
break;
}
case SV_FLAGRETURN:
{
playsound(S_FLAGRETURN);
if(f.actor==player1) conoutf("you returned your flag");
if(f.actor==player1) conoutf("\f2you returned your flag");
else conoutf("\f2%s returned %s flag", f.actor->name, (own ? "your" : "the enemy"));
break;
}
+17 -2
View File
@@ -3,6 +3,7 @@
#include "cube.h"
#include "bot/bot.h"
extern int democlientnum;
extern bool c2sinit, senditemstoserver;
extern string clientpassword;
@@ -40,6 +41,10 @@ void updatepos(playerent *d)
if(fx<fy) d->o.y += dy<0 ? r-fy : -(r-fy); // push aside
else d->o.x += dx<0 ? r-fx : -(r-fx);
}
}
void updatelagtime(playerent *d)
{
int lagtime = lastmillis-d->lastupdate;
if(lagtime)
{
@@ -89,6 +94,7 @@ void parsepositions(ucharbuf &p)
f >>= 3;
d->onladder = f&1;
if(!demoplayback) updatepos(d);
updatelagtime(d);
break;
}
@@ -131,7 +137,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p)
}
case SV_SOUND:
playsound(getint(p), d ? &d->o : NULL);
playsound(getint(p), !d || (demoplayback && cn == democlientnum) ? NULL : &d->o);
break;
@@ -272,7 +278,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p)
conoutf("\f2%s suicided", d->name);
act = d;
}
else if(actor==getclientnum())
else if(actor==getclientnum() || (demoplayback && actor==democlientnum))
{
act = player1;
int frags;
@@ -553,6 +559,15 @@ void parsemessages(int cn, playerent *d, ucharbuf &p)
break;
default:
if(demoplayback) // filter demo messages
{
int size = msgsizelookup(type);
if(size)
{
loopi(size) getint(p);
break;
}
}
neterr("type");
return;
}
+2 -2
View File
@@ -400,7 +400,7 @@ void renderdoc(int x, int y)
if(ident->examples.length()) // examples
{
doclines.add(ident->examples.length() == 1 ? "Example:" : "Examples:");
doclines.add(newstring(ident->examples.length() == 1 ? "Example:" : "Examples:"));
loopvj(ident->examples)
{
cvector lines;
@@ -413,7 +413,7 @@ void renderdoc(int x, int y)
if(ident->keys.length()) // default keys
{
doclines.add(ident->keys.length() == 1 ? "Default key:" : "Default keys:");
doclines.add(newstring(ident->keys.length() == 1 ? "Default key:" : "Default keys:"));
loopvj(ident->keys)
{
dockey &k = ident->keys[j];
+7 -1
View File
@@ -306,7 +306,13 @@ int main(int argc, char **argv)
else if(curtime<1) curtime = 1;
cleardlights();
if(lastmillis) updateworld(curtime, lastmillis);
if(demoplayback && demopaused)
{
curtime = 0;
millis = lastmillis;
}
else if(lastmillis) updateworld(curtime, lastmillis);
lastmillis += curtime;
curmillis = millis;
+4 -2
View File
@@ -433,6 +433,7 @@ void attack(bool on)
{
if(intermission) return;
if(editmode) editdrag(on);
else if(demoplayback && on) shiftdemoplayer(1);
else if(player1->state==CS_DEAD) respawn();
else player1->attacking = on;
}
@@ -440,7 +441,8 @@ void attack(bool on)
void jumpn(bool on)
{
if(intermission) return;
if(player1->state==CS_DEAD)
if(demoplayback && on) demopaused = !demopaused;
else if(player1->state==CS_DEAD)
{
if(on) respawn();
}
@@ -474,7 +476,7 @@ void mousemove(int dx, int dy)
camera1->yaw += (dx/SENSF)*(sensitivity/(float)sensitivityscale);
camera1->pitch -= (dy/SENSF)*(sensitivity/(float)sensitivityscale)*(invmouse ? -1 : 1);
fixcamerarange();
if(camera1!=player1 && player1->state!=CS_DEAD)
if(camera1!=player1 && player1->state!=CS_DEAD && !demoplayback)
{
player1->yaw = camera1->yaw;
player1->pitch = camera1->pitch;
+5
View File
@@ -225,6 +225,11 @@ extern void stop();
extern void stopifrecording();
extern void demodamage(int damage, vec &o);
extern void demoblend(int damage);
extern bool demopaused;
extern playerent *demoplayer;
extern void shiftdemoplayer(int i);
extern bool localdemoplayer1st();
extern int demomillis();
// physics
extern float raycube(const vec &o, const vec &ray, vec &surface);
+31 -2
View File
@@ -228,7 +228,36 @@ COMMAND(trypitch, ARG_1INT);
void recomputecamera()
{
if(editmode || player1->state!=CS_DEAD)
if(demoplayback && demoplayer)
{
static physent democam;
extern bool firstpersondemo;
if(demoplayer == player1 && firstpersondemo)
{
democam = *(physent *)player1;
}
else
{
static playerent *lastplayer = NULL;
if(lastplayer != demoplayer)
{
lastplayer = demoplayer;
democam = *(physent *)demoplayer;
democam.type = ENT_CAMERA;
democam.reset();
democam.roll = 0;
democam.move = -1;
camera1 = &democam;
}
democam.o = demoplayer->o;
democam.o.x -= (float)(cosf(RAD*(demoplayer->yaw-90)))*demoplayer->radius*1.5f;
democam.o.y -= (float)(sinf(RAD*(demoplayer->yaw-90)))*demoplayer->radius*1.5f;
democam.o.z += demoplayer->eyeheight/3.0f;
if(!demopaused) democam.yaw = demoplayer->yaw;
}
}
else if(editmode || player1->state!=CS_DEAD)
{
camera1 = player1;
}
@@ -505,7 +534,7 @@ void drawhudgun(int w, int h, float aspect, int farplane)
gluPerspective((float)100.0f*h/w, aspect, 0.3f, farplane); // fov fixed at 100°
glMatrixMode(GL_MODELVIEW);
if(player1->state!=CS_DEAD) renderhudgun();
if(player1->state!=CS_DEAD && (!demoplayback || localdemoplayer1st())) renderhudgun();
rendermenumdl();
glMatrixMode(GL_PROJECTION);
+41 -22
View File
@@ -50,6 +50,7 @@ VARP(radarres, 1, 64, 1024);
VARP(radarentsize, 1, 4, 64);
VARP(hidectfhud, 0, 0, 1);
VARP(hideteamhud, 0, 0, 1);
VARP(hidedemohud, 0, 0, 1);
VAR(showmap, 0, 0, 1);
@@ -259,31 +260,35 @@ void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwat
glEnable(GL_TEXTURE_2D);
bool demo3rd = demoplayback && !localdemoplayer1st();
playerent *targetplayer = playerincrosshair();
bool didteamkill = player1->lastteamkill && player1->lastteamkill + 5000 > lastmillis;
bool menuvisible = rendermenu();
if(player1->state==CS_ALIVE && !player1->reloading && !didteamkill && !menuvisible)
{
bool drawteamwarning = targetplayer ? (isteam(targetplayer->team, player1->team) && targetplayer->state!=CS_DEAD) : false;
if(player1->gunselect==GUN_SNIPER && scoped) drawscope();
else if((player1->gunselect!=GUN_SNIPER || drawteamwarning)) drawcrosshair(drawteamwarning);
}
drawequipicons();
if(!hideradar)
{
glMatrixMode(GL_MODELVIEW);
drawradar(w, h);
glMatrixMode(GL_PROJECTION);
}
char *infostr = editinfo();
bool command = getcurcommand() ? true : false;
if(command) rendercommand(20, 1570);
else if(infostr) draw_text(infostr, 20, 1570);
else if(targetplayer) draw_text(targetplayer->name, 20, 1570);
if(!demo3rd)
{
if(player1->state==CS_ALIVE && !player1->reloading && !didteamkill && !menuvisible)
{
bool drawteamwarning = targetplayer ? (isteam(targetplayer->team, player1->team) && targetplayer->state!=CS_DEAD) : false;
if(player1->gunselect==GUN_SNIPER && scoped) drawscope();
else if((player1->gunselect!=GUN_SNIPER || drawteamwarning)) drawcrosshair(drawteamwarning);
}
drawequipicons();
if(!hideradar)
{
glMatrixMode(GL_MODELVIEW);
drawradar(w, h);
glMatrixMode(GL_PROJECTION);
}
char *infostr = editinfo();
if(command) rendercommand(20, 1570);
else if(infostr) draw_text(infostr, 20, 1570);
else if(targetplayer) draw_text(targetplayer->name, 20, 1570);
}
glLoadIdentity();
glOrtho(0, VIRTW*2, VIRTH*2, 0, -1, 1);
@@ -299,8 +304,22 @@ void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwat
draw_textf("wvt %d", left, top+240, curvert);
draw_textf("evt %d", left, top+320, xtraverts);
}
if(!hidedemohud && demoplayback)
{
const int left = VIRTW*2/80, top = VIRTH*2*3/4;
int dmillis = demomillis();
s_sprintfd(time)("%d:%02d", dmillis/1000/60, dmillis/1000%60);
s_sprintfd(following)("\f0Following %s", demoplayer->name);
if(player1->state==CS_ALIVE)
draw_text(time, left, top-FONTH);
draw_text(following, left, top);
draw_text("jump to pause", left, top+2*FONTH);
draw_text("attack to change view", left, top+3*FONTH);
draw_text("reload for slow-motion", left, top+4*FONTH);
}
if(player1->state==CS_ALIVE && !demo3rd)
{
glLoadIdentity();
glOrtho(0, VIRTW/2, VIRTH/2, 0, -1, 1);
+1 -1
View File
@@ -259,6 +259,6 @@ void renderclients()
{
playerent *d;
loopv(players) if((d = players[i]) && (!demoplayback || i!=democlientnum)) renderclient(d);
if(player1->state==CS_DEAD || (reflecting && !refracting)) renderclient(player1);
if(player1->state==CS_DEAD || (reflecting && !refracting) || (demoplayback && !localdemoplayer1st())) renderclient(player1);
}
+87 -19
View File
@@ -33,6 +33,7 @@ void stop()
demoloading = false;
loopv(playerhistory) zapplayer(playerhistory[i]);
playerhistory.setsize(0);
setvar("gamespeed", 100);
}
void stopifrecording() { if(demorecording) stop(); }
@@ -116,9 +117,10 @@ void loadgamerest()
int nplayers = gzgeti();
loopi(nplayers) if(!gzget())
{
playerent *d = getclient(i);
playerent *d = newclient(i);
ASSERT(d);
gzread(f, d, sizeof(playerent));
d->lastaction = d->lastpain = lastmillis;
}
conoutf("savegame restored");
@@ -132,6 +134,8 @@ int playbacktime = 0;
int ddamage, bdamage;
vec dorig;
int demomillis() { return lastmillis-starttime; }
void record(char *name)
{
int cn = getclientnum();
@@ -160,14 +164,32 @@ void incomingdemodata(int chan, uchar *buf, int len, bool extras)
{
gzput(player1->gunselect);
gzput(player1->lastattackgun);
gzputi(player1->lastaction-starttime);
gzputi(player1->akimbolastaction[0]-starttime);
gzputi(player1->akimbolastaction[1]-starttime);
gzputi(player1->gunwait);
gzputi(player1->lastaction-starttime);
gzputi(player1->lastanimswitchtime[0]);
gzputi(player1->lastanimswitchtime[1]);
loopi(NUMGUNS) { gzput(player1->ammo[i]); gzput(player1->mag[i]); }
gzput(player1->akimbo ? 1 : 0 | (player1->reloading ? 1 : 0) << 1 | (player1->weaponchanging ? 1 : 0) << 2);
switch(player1->gunselect) // AH,demo
{
case GUN_GRENADE:
gzputi(player1->thrownademillis); // AH,demo
gzput(player1->inhandnade ? 1 : 0); // AH,demo
break;
case GUN_PISTOL:
if(player1->akimbo)
{
gzputi(player1->akimbolastaction[0]-starttime);
gzputi(player1->akimbolastaction[1]-starttime);
}
break;
case GUN_SNIPER:
gzput(scoped ? 1 : 0);
break;
}
gzputi(player1->health);
gzputi(player1->armour);
//gzput(player1->armourtype);
loopi(NUMGUNS) gzput(player1->ammo[i]);
gzput(player1->state);
gzputi(bdamage);
bdamage = 0;
@@ -187,8 +209,7 @@ void demo(char *name)
void stopreset()
{
conoutf("demo stopped (%d msec elapsed)", lastmillis-starttime);
stop();
loopv(players) zapplayer(players[i]);
player1 = newplayerent();
disconnect(0, 0);
}
@@ -205,15 +226,36 @@ void readdemotime()
playbacktime = scaletime(playbacktime);
}
bool demopaused = false;
void togglepause() { demopaused = !demopaused; }
playerent *demoplayer = player1;
bool firstpersondemo = true;
bool localdemoplayer1st() { return demoplayback && demoplayer == player1 && firstpersondemo; }
void shiftdemoplayer(int i)
{
if(!i) return;
if(demoplayer == player1)
{
firstpersondemo = !firstpersondemo;
if(!firstpersondemo) return;
}
vector<playerent *> plrs;
loopv(players) if(players[i] != NULL) plrs.add(players[i]);
int cur = plrs.find(demoplayer);
if(cur >= 0) demoplayer = plrs[(cur+i) % plrs.length()];
}
void startdemo()
{
democlientnum = gzgeti();
demoplayback = true;
starttime = lastmillis;
conoutf("now playing demo");
dynent *d = newclient(democlientnum);
ASSERT(d);
*d = *player1;
while(democlientnum>=players.length()) players.add(NULL);
players[democlientnum] = player1;
demoplayer = player1;
readdemotime();
}
@@ -261,19 +303,40 @@ void demoplaybackstep()
{
target->gunselect = gzget();
target->lastattackgun = gzget();
target->lastaction = scaletime(gzgeti());
target->akimbolastaction[0] = scaletime(gzgeti());
target->akimbolastaction[1] = scaletime(gzgeti());
target->gunwait = gzgeti();
target->lastaction = scaletime(gzgeti());
target->lastanimswitchtime[0] = scaletime(gzgeti()); // AH,demo
target->lastanimswitchtime[1] = scaletime(gzgeti()); // AH,demo
loopi(NUMGUNS) { target->ammo[i] = gzget(); target->mag[i] = gzget(); } // AH,demo
uchar flags = gzget();
target->akimbo = flags&1 ? true : false; // AH, demo
target->reloading = (flags>>1)&1 ? true : false; // AH,demo
target->weaponchanging = (flags>>2)&1 ? true : false; //
switch(target->gunselect)
{
case GUN_GRENADE:
target->thrownademillis = scaletime(gzgeti()); // AH,demo
target->inhandnade = gzget() ? (bounceent *)1 : NULL; // AH,demo
break;
case GUN_PISTOL:
if(player1->akimbo)
{
target->akimbolastaction[0] = scaletime(gzgeti());
target->akimbolastaction[1] = scaletime(gzgeti());
}
break;
case GUN_SNIPER:
scoped = gzget() ? true : false;
break;
}
target->health = gzgeti();
target->armour = gzgeti();
//target->armourtype = gzget();
loopi(NUMGUNS) target->ammo[i] = gzget();
target->state = gzget();
target->lastmove = playbacktime;
if((bdamage = gzgeti())) damageblend(bdamage);
if((ddamage = gzgeti())) { gzgetv(dorig); particle_splash(3, ddamage, 1000, dorig); }
if((ddamage = gzgeti())) { gzgetv(dorig); particle_splash(3, ddamage, 1000, dorig); };
// FIXME: set more client state here
target->lastmove = playbacktime;
}
// insert latest copy of player into history
@@ -295,13 +358,16 @@ void demoplaybackstep()
if(demoplayback)
{
if(playerhistory.length()) memcpy(player1, playerhistory.last(), sizeof(playerent));
int itime = lastmillis-demodelaymsec;
loopvrev(playerhistory) if(playerhistory[i]->lastupdate<itime) // find 2 positions in history that surround interpolation time point
{
playerent *a = playerhistory[i];
playerent *b = a;
if(i+1<playerhistory.length()) b = playerhistory[i+1];
memcpy(player1, b, sizeof(playerent));
player1->o = b->o;
player1->yaw = b->yaw;
player1->pitch = b->pitch;
if(a!=b) // interpolate pos & angles
{
dynent *c = b;
@@ -332,6 +398,8 @@ void stopn() { if(demoplayback) stopreset(); else stop(); conoutf("demo stopped"
COMMAND(record, ARG_1STR);
COMMAND(demo, ARG_1STR);
COMMANDN(stop, stopn, ARG_NONE);
COMMANDN(demopause, togglepause, ARG_NONE);
COMMANDN(demoplayer, shiftdemoplayer, ARG_1INT);
COMMAND(savegame, ARG_1STR);
COMMAND(loadgame, ARG_1STR);
+6 -1
View File
@@ -203,7 +203,12 @@ void updatevol()
}
}
void playsoundc(int n) { addmsg(SV_SOUND, "i", n); playsound(n); }
void playsoundc(int n)
{
if(demoplayback) return;
addmsg(SV_SOUND, "i", n);
playsound(n);
}
int soundsatonce = 0, lastsoundmillis = 0;
+4 -3
View File
@@ -111,6 +111,7 @@ COMMAND(setscope, ARG_1INT);
void reload(playerent *d)
{
if(demoplayback) { setvar("gamespeed", getvar("gamespeed") != 100 ? 100 : 35); return; }
if(!d || d->state!=CS_ALIVE || d->reloading || d->weaponchanging) return;
if(!reloadable_gun(d->gunselect) || d->ammo[d->gunselect]<=0) return;
if(d->mag[d->gunselect] >= (has_akimbo(d) ? 2 : 1)*guns[d->gunselect].magsize) return;
@@ -500,7 +501,7 @@ bounceent *new_nade(playerent *d, int millis = 0)
d->inhandnade = p;
d->thrownademillis = 0;
playsound(S_GRENADEPULL, (d==player1 ? NULL : &d->o));
if(d==player1 && !demoplayback) playsoundc(S_GRENADEPULL);
return p;
}
@@ -514,7 +515,7 @@ void explode_nade(bounceent *i)
void shootv(int gun, vec &from, vec &to, playerent *d, bool local, int nademillis) // create visual effect from a shot
{
playsound(guns[gun].sound, d==player1 ? NULL : &d->o);
if(guns[gun].sound) playsound(guns[gun].sound, d==player1 ? NULL : &d->o);
switch(gun)
{
case GUN_KNIFE:
@@ -543,7 +544,7 @@ void shootv(int gun, vec &from, vec &to, playerent *d, bool local, int nademilli
case GUN_GRENADE:
{
if(d!=player1)
if(d!=player1 || demoplayback)
{
bounceent *p = new_nade(d, nademillis);
throw_nade(d, to, p);