Use with e.g.
cl_cmd demotimer 20 "slowmo 100"
cl_cmd demotimer 59 "slowmo 1"
cl_cmd demotimer 60 "cl_capturevideo 1"
cl_cmd demotimer 120 "cl_capturevideo 0"
cl_cmd demotimer 121 "disconnect"
I leave it as exercise to the reader to create useful aliases, etc..
Note that only demos recorded with the patched csprogs will allow this..
Have fun..
EDIT: errors..
EDIT: Thanks MrBougo for guiding me through hacking this up


EDIT: Updated diff to provide a hook called hook_demostart. This hook is executed right after playback of the demo started. With this you could do the following:
alias hook_demostart cl_cmd "demotimer 1 disconnect"
and then run a demo.. It will run until exactly 1 second into the gametime. Note that the start of the demo is not nessecarily at gametime 0.. No timing problems using defer anymore..
So to create a way to record e.g. the game from 0:10 to 0:20, you could do something like the following:
alias hook_demostart "cl_cmd demotimer 10 \"slowmo 1; cl_capturevideo 1\"; cl_cmd demotimer 20 \"cl_capturevideo 0; disconnect; slowmo 1\"; slowmo 100"
- Code: Select all
Index: data/qcsrc/client/Main.qc
===================================================================
--- data/qcsrc/client/Main.qc (revision 7768)
+++ data/qcsrc/client/Main.qc (working copy)
@@ -447,6 +447,12 @@
debug_shotorg.view_ofs = '25 8 -8';
}
+void thinkdemotimer() {
+ localcmd("\n", self.message, ";");
+ strunzone(self.message);
+ remove(self);
+}
+
void GameCommand(string msg)
{
float argc;
@@ -459,6 +465,7 @@
print(" radar\n");
print(" sbar_columns_set ...\n");
print(" sbar_columns_help\n");
+ print(" demotimer secs cmd | demotimer clear | demotimer list \n");
GameCommand_Generic("help");
return;
}
@@ -474,6 +481,39 @@
else if(cmd == "settemp") {
cvar_clientsettemp(argv(1), argv(2));
}
+ else if(cmd == "demotimer") {
+ if not(isdemo()) {
+ print("Error! demotimer can be only used during demo playback");
+ return;
+ }
+ if (argv(1) == "clear") {
+ local entity e;
+ e = world;
+ for( ; e=find(e, classname,"demotimer") ; ) {
+ strunzone(e.message);
+ remove(e);
+ }
+ return;
+ }
+ if (argv(1) == "list") {
+ local entity e;
+ e = world;
+ for( ; e=find(e, classname,"demotimer") ; ) {
+ print(ftos(e.nextthink), " ", e.message, "\n");
+ }
+ return;
+ }
+ if (stof(argv(1)) < time) {
+ print("Error! time is in the past");
+ return;
+ }
+ local entity e;
+ e = spawn();
+ e.classname = "demotimer";
+ e.nextthink = stof(argv(1));
+ e.message = strzone(argv(2));
+ e.think = thinkdemotimer;
+ }
else if(cmd == "radar") {
ons_showmap = !ons_showmap;
}
@@ -868,6 +908,8 @@
{
localcmd("\n_cl_hook_gamestart ", GametypeNameFromType(gametype), ";");
calledhooks |= HOOK_START;
+ } else { // isdemo() == true
+ localcmd("\nhook_demostart");
}
}
// CSQC_Parse_StuffCmd : Provides the stuffcmd string in the first parameter that the server provided. To execute standard behavior, simply execute localcmd with the string.