コード例 #1
0
ファイル: demo.cpp プロジェクト: r-lyeh-forks/mini.q
void loadgamerest(void) {
  if (demoplayback || !f) return;
  if (gzgeti()!=game::ents.length()) return loadgameout();
  loopv(game::ents) {
    game::ents[i].spawned = gzgetc(f)!=0;
    // TODO if (game::ents[i].type==game::CARROT && !game::ents[i].spawned)
      // world::trigger(game::ents[i].attr1, game::ents[i].attr2, true);
  }
  server::restoreserverstate(game::ents);

  gzread(f, game::player1, sizeof(game::dynent));
  game::player1->lastaction = game::lastmillis();

  int nmonsters = gzgeti();
  game::dvector &monsters = game::getmonsters();
  if (nmonsters!=monsters.length()) return loadgameout();
  loopv(monsters) {
    gzread(f, monsters[i], sizeof(game::dynent));
    monsters[i]->enemy = game::player1; // lazy, could save id of enemy instead
    monsters[i]->lastaction = monsters[i]->trigger = game::lastmillis()+500; // also lazy, but no real noticable effect on game
    if (monsters[i]->state==CS_DEAD) monsters[i]->lastaction = 0;
  }
  game::restoremonsterstate();

  int nplayers = gzgeti();
  loopi(nplayers) if (!gzget()) {
    game::dynent *d = game::getclient(i);
    assert(d);
    gzread(f, d, sizeof(game::dynent));
  }

  con::out("savegame restored");
  if (demoloading) start(); else stop();
}
コード例 #2
0
ファイル: demo.cpp プロジェクト: r-lyeh-forks/mini.q
static void readdemotime() {
  if (gzeof(f) || (playbacktime = gzgeti())==-1) {
    stopreset();
    return;
  }
  playbacktime = scaletime(playbacktime);
}
コード例 #3
0
ファイル: demo.cpp プロジェクト: r-lyeh-forks/mini.q
static void start(void) {
  democlientnum = gzgeti();
  demoplayback = true;
  starttime = game::lastmillis();
  con::out("now playing demo");
  game::dynent *d = game::getclient(democlientnum);
  assert(d);
  *d = *game::player1;
  readdemotime();
}
コード例 #4
0
ファイル: savegamedemo.cpp プロジェクト: mailgyc/cube
void startdemo() {
	democlientnum = gzgeti();
	demoplayback = true;
	starttime = lastmillis;
	conoutf("now playing demo");
	Sprite *d = getclient(democlientnum);
	assert(d);
	*d = *player1;
	readdemotime();
}
コード例 #5
0
ファイル: savegamedemo.cpp プロジェクト: mailgyc/cube
void loadgamerest() {
	if (demoplayback || !f)
		return;

	if (gzgeti() != entityList.size())
		return loadgameout();
	for(Entity &en : entityList) {
		en.spawned = gzgetc(f) != 0;
		if (en.type == CARROT && !en.spawned)
			trigger(en.attr1, en.attr2, true);
	};
	restoreserverstate(entityList);

	gzread(f, player1, sizeof(Sprite));
	player1->lastaction = lastmillis;

	int nmonsters = gzgeti();
	std::vector<Sprite *> &monsters = getmonsters();
	if (nmonsters != monsters.size())
		return loadgameout();
	loopv(monsters) {
		gzread(f, monsters[i], sizeof(Sprite));
		monsters[i]->enemy = player1;    // lazy, could save id of enemy instead
		monsters[i]->lastaction = monsters[i]->trigger = lastmillis + 500; // also lazy, but no real noticable effect on game
		if (monsters[i]->state == CS_DEAD)
			monsters[i]->lastaction = 0;
	};
	restoremonsterstate();

	int nplayers = gzgeti();
	loopi(nplayers)
		if (!gzget()) {
			Sprite *d = getclient(i);
			assert(d);
			gzread(f, d, sizeof(Sprite));
		};

	conoutf("savegame restored");
	if (demoloading)
		startdemo();
	else
		stop();
}
コード例 #6
0
ファイル: demo.cpp プロジェクト: r-lyeh-forks/mini.q
static void loadstate(char *fn) {
  stop();
  if (client::multiplayer()) return;
  f = gzopen(fn, "rb9");
  if (!f) { con::out("could not open %s", fn); return; }

  string buf;
  gzread(f, buf, 8);
  if (strncmp(buf, "CUBESAVE", 8)) goto out;
  if (gzgetc(f)!=sys::islittleendian()) goto out;     // not supporting save->load accross incompatible architectures simpifies things a LOT
  if (gzgeti()!=SAVEGAMEVERSION || gzgeti()!=sizeof(game::dynent)) goto out;
  string mapname;
  gzread(f, mapname, MAXDEFSTR);
  game::setnextmode(gzgeti());
  client::changemap(mapname); // continue below once map has been loaded and client & server have updated
  return;
out:
  con::out("aborting: savegame/demo from a different version of cube or cpu architecture");
  stop();
}
コード例 #7
0
ファイル: savegamedemo.cpp プロジェクト: mailgyc/cube
void loadstate(char *fn) {
	stop();
	if (multiplayer())
		return;
	f = gzopen(fn, "rb9");
	if (!f) {
		conoutf("could not open %s", fn);
		return;
	};

	char buf[_MAXDEFSTR];
	gzread(f, buf, 8);
	// not supporting save->load accross incompatible architectures simpifies things a LOT
	if (strncmp(buf, "CUBESAVE", 8) || gzgetc(f) != islittleendian || gzgeti() != SAVEGAMEVERSION || gzgeti() != sizeof(Sprite)) {
		conoutf("aborting: savegame/demo from a different version of cube or cpu architecture");
		stop();
	} else {
		memset(buf, 0, _MAXDEFSTR);
		gzread(f, buf, _MAXDEFSTR);
		nextmode = gzgeti();
		changemap(std::string(buf)); // continue below once map has been loaded and client & server have updated
	}
}
コード例 #8
0
ファイル: savegamedemo.cpp プロジェクト: jhunt/cube
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);
    };
};
コード例 #9
0
ファイル: demo.cpp プロジェクト: r-lyeh-forks/mini.q
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;
    }
  }
}