diff --git a/source/src/client.cpp b/source/src/client.cpp index 5ed546f6..01e88a4e 100644 --- a/source/src/client.cpp +++ b/source/src/client.cpp @@ -9,6 +9,7 @@ ENetHost *clienthost = NULL; ENetPeer *curpeer = NULL, *connpeer = NULL; int connmillis = 0, connattempts = 0, discmillis = 0; bool watchingdemo = false; +string demofile; extern bool clfail, cllock; extern int searchlan; @@ -763,6 +764,39 @@ void listdemos() addmsg(SV_LISTDEMOS, "r"); } +void shiftgametime(int newmillis) +{ + newmillis = max(0, newmillis); + int gamemillis = gametimecurrent + (lastmillis - lastgametimeupdate); + + if(!watchingdemo) { conoutf("You have to be watching a demo to change game time"); return; } + if(newmillis > gametimemaximum) { conoutf("Invalid time specified"); return; } + + if(newmillis < gamemillis) + { + // if rewinding + if(!demofile || !demofile[0]) return; + watchingdemo = false; + callvote(SA_MAP, demofile, "-1"); + nextmillis = newmillis; + } + else + { + nextmillis = newmillis - gamemillis; + } +} + +void setminutesremaining(int minutes) +{ + shiftgametime(gametimemaximum - minutes * 60000); +} + +void rewinddemo(int seconds) +{ + int gamemillis = gametimecurrent+(lastmillis-lastgametimeupdate); + shiftgametime(gamemillis-seconds*1000); +} + COMMAND(sendmap, ARG_1STR); COMMAND(getmap, ARG_NONE); COMMAND(deleteservermap, ARG_1STR); @@ -770,3 +804,5 @@ COMMAND(resetsecuremaps, ARG_NONE); COMMAND(securemap, ARG_1STR); COMMAND(getdemo, ARG_2STR); COMMAND(listdemos, ARG_NONE); +COMMANDN(setmr, setminutesremaining, ARG_1INT); +COMMANDN(rewind, rewinddemo, ARG_1INT); diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index 487525d4..6a051398 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -52,7 +52,7 @@ struct serverstate servstate = { 0 }; playerent *player1 = newplayerent(); // our client vector players; // other clients -int lastmillis = 0, totalmillis = 0; +int lastmillis = 0, totalmillis = 0, nextmillis = 0; int lasthit = 0; int curtime = 0; string clientmap = ""; @@ -951,13 +951,21 @@ VAR(gametimecurrent, 1, 0, 0); VAR(gametimemaximum, 1, 0, 0); VAR(lastgametimeupdate, 1, 0, 0); -void timeupdate(int milliscur, int millismax) +void silenttimeupdate(int milliscur, int millismax) { - if( lastmillis - lastgametimeupdate < 1000 ) return; // avoid double-output, but possibly omit new message if joined 1s before server switches to next minute lastgametimeupdate = lastmillis; gametimecurrent = milliscur; gametimemaximum = millismax; minutesremaining = (gametimemaximum - gametimecurrent + 60000 - 1) / 60000; +} + +void timeupdate(int milliscur, int millismax) +{ + bool display = lastmillis - lastgametimeupdate > 1000; // avoid double-output + + silenttimeupdate(milliscur, millismax); + + if(!display) return; if(!minutesremaining) { intermission = true; diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index e1b2871b..39682a16 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -1268,7 +1268,9 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) case SV_DEMOPLAYBACK: { - watchingdemo = demoplayback = getint(p)!=0; + extern string demofile; + getstring(demofile, p); + watchingdemo = demoplayback = demofile && demofile[0]; if(demoplayback) { player1->resetspec(); diff --git a/source/src/cube.h b/source/src/cube.h index 3a03c429..2634c680 100644 --- a/source/src/cube.h +++ b/source/src/cube.h @@ -33,7 +33,7 @@ extern bool editmode; extern vector ents; // map entities extern vector eh_ents; // edithide entities extern vec worldpos, camup, camright, camdir; // current target of the crosshair in the world -extern int lastmillis, totalmillis; // last time +extern int lastmillis, totalmillis, nextmillis; // last time extern int curtime; // current frame time extern int interm; extern int gamemode, nextmode; diff --git a/source/src/main.cpp b/source/src/main.cpp index 0551f91a..df8b58ae 100644 --- a/source/src/main.cpp +++ b/source/src/main.cpp @@ -1193,6 +1193,11 @@ int main(int argc, char **argv) if(millisread(&nextplayback, sizeof(nextplayback))!=sizeof(nextplayback)) { @@ -3719,7 +3721,14 @@ void serverslice(uint timeout) // main server update, called from cube main lo servertime = ((diff + 3 * servertime)>>2); if (servertime > 40) serverlagged = servmillis; - if(m_demo) readdemo(); +#ifndef STANDALONE + if(m_demo) + { + readdemo(); + extern void silenttimeupdate(int milliscur, int millismax); + silenttimeupdate(gamemillis, gamelimit); + } +#endif if(minremain>0) {