Well this is easy enough to do and it can give you some cool screenshots as well. The reason you can't do it in DeathMsg is because you can't time it. I have this code in glbegin before I draw those nifty HUD stats. It does lag briefly for a second while it takes the screenshot, which is not my fault.
First you need 3 vars which you can make global, but I use static because I don't like global vars.
bSS is true if we are going to take a screenshot, hstime is the time the hs was made, HScnt is a counter.
Code:
static bool bSS = false;
static int hstime = 0, HScnt = 0;
Don't forget to reset the counters if you have no headshots.
Code:
if(gfrags == 0)
{
ghshotcnt = 0;
HScnt = 0;
}
Here we check the counter and if they differ we have gotten a headshot. We seed the rand() func with srand and modulo it by 5. If that's true we set bSS to true and hstime to the current tick count.
Code:
if(HScnt != ghshotcnt)
{
HScnt = ghshotcnt;
if(!bSS)
{
srand(GetTickCount());
if(rand() % 5)
{
bSS = true;
hstime = GetTickCount();
}
}
}
Here we check if our screenshot bool is true and then we check if the current tick count - hstime >= 200. 200 is the millisecond value from the time of the headshot to the time we take our screenshot. For the client command you can use snapshot for a bmp or screenshot for a tga file.
Code:
if(bSS)
{
if((GetTickCount() - hstime) >= 200) // take screenshot 200 ms after the kill
{
bSS = false;
pEngfuncs->pfnClientCmd("snapshot");
pEngfuncs->pfnCenterPrint("Snapshot taken from this kill");
}
}
Here is a screenshot taken from the above code of me in midair headshotting the enemy.
http://ill.cc/~trioxide/Tetsuo/leeb_auto_ss.jpgThis may not appear elsewhere without permission, but may be linked to.
You can replace the client command above with the following code.
void ScreenShot(void)
{
BITMAPFILEHEADER bf;
BITMAPINFOHEADER bi;
static int fNum = 1;
char fName[32];
const char *gDir = pEngfuncs->pfnGetGameDirectory();
const char *map = pEngfuncs->pfnGetLevelName();
char *image = new char[vp[2] * vp[3] * 3];
for( ; ; )
{
wsprintf(fName, "%s\\%s%i.bmp", gDir, map, fNum);
fNum++;
if(!PathFileExists(fName))
break;
}
FILE *file = fopen(fName, "wb"); // opening an existing file with "wb" flags will overwrite it
if( image!=NULL )
{
if( file!=NULL )
{
glReadPixels( 0, 0, vp[2], vp[3], GL_BGR_EXT, GL_UNSIGNED_BYTE, image );
memset( &bf, 0, sizeof( bf ) );
memset( &bi, 0, sizeof( bi ) );
bf.bfType = 'MB';
bf.bfSize = sizeof(bf)+sizeof(bi)+vp[2]*vp[3]*3;
bf.bfOffBits = sizeof(bf)+sizeof(bi);
bi.biSize = sizeof(bi);
bi.biWidth = vp[2];
bi.biHeight = vp[3];
bi.biPlanes = 1;
bi.biBitCount = 24;
bi.biSizeImage = vp[2] * vp[3] * 3;
fwrite( &bf, sizeof(bf), 1, file );
fwrite( &bi, sizeof(bi), 1, file );
fwrite( image, sizeof(unsigned char), vp[3] * vp[2] * 3, file );
fclose( file );
}
delete[] image;
}
}
It didn't take the ss right when I tried it and it still lags for a split second, but there you go in case you're interested. I was also too lazy to fix the fact that the file name will come out like "fy_iceworld2k.bsp(random number).bmp".
Credits: Xen for the original code from his console command. Me for doing the above stuff ( even if it doesn't work right it can still be fixed ).