void demoplaybackstep() { while(demoplayback && lastmillis>=playbacktime) { int len = gzgeti(); if(len<1 || len>MAXTRANS) { conoutf("error: huge packet during demo play (%d)", len); stopreset(); return; }; uchar buf[MAXTRANS]; gzread(f, buf, len); localservertoclient(buf, len); // update game state dynent *target = players[democlientnum]; assert(target); int extras; if(extras = gzget()) // read additional client side state not present in normal network stream { target->gunselect = gzget(); target->lastattackgun = gzget(); target->lastaction = scaletime(gzgeti()); target->gunwait = gzgeti(); 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); }; // FIXME: set more client state here }; // insert latest copy of player into history if(extras && (playerhistory.empty() || playerhistory.last()->lastupdate!=playbacktime)) { dynent *d = newdynent(); *d = *target; d->lastupdate = playbacktime; playerhistory.add(d); if(playerhistory.length()>20) { zapdynent(playerhistory[0]); playerhistory.remove(0); }; }; readdemotime(); }; if(demoplayback) { int itime = lastmillis-demodelaymsec; loopvrev(playerhistory) if(playerhistory[i]->lastupdate<itime) // find 2 positions in history that surround interpolation time point { dynent *a = playerhistory[i]; dynent *b = a; if(i+1<playerhistory.length()) b = playerhistory[i+1]; *player1 = *b; if(a!=b) // interpolate pos & angles { dynent *c = b; if(i+2<playerhistory.length()) c = playerhistory[i+2]; dynent *z = a; if(i-1>=0) z = playerhistory[i-1]; //if(a==z || b==c) printf("* %d\n", lastmillis); float bf = (itime-a->lastupdate)/(float)(b->lastupdate-a->lastupdate); fixwrap(a, player1); fixwrap(c, player1); fixwrap(z, player1); vdist(dist, v, z->o, c->o); if(dist<16) // if teleport or spawn, dont't interpolate { catmulrom(z->o, a->o, b->o, c->o, bf, player1->o); catmulrom(*(vec *)&z->yaw, *(vec *)&a->yaw, *(vec *)&b->yaw, *(vec *)&c->yaw, bf, *(vec *)&player1->yaw); }; fixplayer1range(); }; break; }; //if(player1->state!=CS_DEAD) showscores(false); }; };
// clientgame.cpp: core game related stuff #include "cube.h" int nextmode = 0; // nextmode becomes gamemode after next map load VAR(gamemode, 1, 0, 0); void mode(int n) { addmsg(1, 2, SV_GAMEMODE, nextmode = n); }; COMMAND(mode, ARG_1INT); bool intermission = false; dynent *player1 = newdynent(); // our client dvector players; // other clients VARP(sensitivity, 0, 10, 10000); VARP(sensitivityscale, 1, 1, 10000); VARP(invmouse, 0, 0, 1); int lastmillis = 0; int curtime = 10; string clientmap; extern int framesinmap; char *getclientmap() { return clientmap; }; void resetmovement(dynent *d) { d->k_left = false; d->k_right = false;