Exemple #1
0
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);
    };
};
Exemple #2
0
void playbackstep(void) {
  while (demoplayback && game::lastmillis()>=playbacktime) {
    int len = gzgeti();
    if (len<1 || len>MAXTRANS) {
      con::out("error: huge packet during demo play (%d)", len);
      stopreset();
      return;
    }
    u8 buf[MAXTRANS];
    gzread(f, buf, len);
    client::localservertoclient(buf, len);  // update game state

    game::dynent *target = game::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(game::NUMGUNS) target->ammo[i] = gzget();
      target->state = gzget();
      target->lastmove = playbacktime;
      // if ((bdamage = gzgeti()) != 0) rr::damageblend(bdamage);
      if ((ddamage = gzgeti()) != 0) {
        gzgetv(dorig);
        rr::particle_splash(rr::PT_BLOOD_SPATS, ddamage, 1000, dorig);
      }
      // FIXME: set more client state here
    }

    // insert latest copy of player into history
    if (extras && (playerhistory.empty() || playerhistory.last()->lastupdate!=playbacktime)) {
      game::dynent *d = game::newdynent();
      *d = *target;
      d->lastupdate = playbacktime;
      playerhistory.add(d);
      if (playerhistory.length()>20) {
        game::zapdynent(playerhistory[0]);
        playerhistory.remove(0);
      }
    }

    readdemotime();
  }

  if (demoplayback) {
    int itime = game::lastmillis()-demodelaymsec;
    loopvrev(playerhistory) if (playerhistory[i]->lastupdate<itime) { // find 2 positions in history that surround interpolation time point
      game::dynent *a = playerhistory[i];
      game::dynent *b = a;
      if (i+1<playerhistory.length()) b = playerhistory[i+1];
      *game::player1 = *b;
      if (a!=b) { // interpolate pos & angles
        game::dynent *c = b;
        if (i+2<playerhistory.length()) c = playerhistory[i+2];
        game::dynent *z = a;
        if (i-1>=0) z = playerhistory[i-1];
        float bf = (itime-a->lastupdate)/(float)(b->lastupdate-a->lastupdate);
        fixwrap(a, game::player1);
        fixwrap(c, game::player1);
        fixwrap(z, game::player1);
        const float dist = distance(z->o,c->o);
        if (dist<16.f) { // if teleport or spawn, dont't interpolate
          catmulrom(z->o, a->o, b->o, c->o, bf, game::player1->o);
          // catmulrom(*(vec3f*)&z->ypr.x, *(vec3f*)&a->ypr.x, *(vec3f*)&b->ypr.x, *(vec3f*)&c->ypr.x, bf, *(vec3f *)&game::player1->ypr.x);
          vec3f dstangle;
          catmulrom(z->ypr, a->ypr, b->ypr, c->ypr, bf, dstangle);
          game::player1->ypr.x = dstangle.x;
          game::player1->ypr.y = dstangle.y;
          game::player1->ypr.z = dstangle.z;
        }
        game::fixplayer1range();
      }
      break;
    }
  }
}