I wasn't happy with the above attempt because it was clumsy and updated the data file every single kill. As the data file is appended, it would eventually become very large, very quickly. So, I worked on a way to update the data file either when the player disconnects, or at the end of a match/game. That would mean much less appending to the file, and thus much smaller in size. This is what I have now:
File Function:
Code:
init()
{
level thread onPlayerConnect();
level thread onGameEnd();
}
onPlayerConnect()
{
for( ;; )
{
level waittill( "connected", player );
// initialize the player kills flag
if( player getPlayerKills() )
player.pers["kills"] = player.kills;
else
player.pers["kills"] = 0;
}
}
onGameEnd()
{
for( ;; )
{
level waittill( "intermission" );
players = getentarray( "player", "classname" );
for(i = 0; i < players.size; i++)
{
player = players[i];
player thread saveKills( player.pers["kills"] );
}
}
}
onPlayerScore()
{
// update the player kills flag
self.pers["kills"]++;
self thread demon\_playerhud::UpdateHud();
}
saveKills( kills )
{
filename = self.name + ".txt";
filehandle = openfile( filename, "append" );
if( filehandle != -1 )
{
fprintln( filehandle, kills );
closefile( filehandle );
}
}
getPlayerKills()
{
filename = self.name + ".txt";
file = OpenFile( filename, "read" );
if( file == -1 )
return( false );
for( ;; )
{
elems = freadln( file );
if( elems == -1 )
break;
if( elems == 0 )
continue;
line = "";
for( pos = 0; pos < elems; pos++ )
{
line = line + fgetarg( file, pos );
if( pos < elems - 1 )
line = line + ",";
}
array = strtok( line, "," );
for( i=0; i < array.size; i++ )
self.kills = int( array[i] );
}
CloseFile( file );
return( true );
}
Player Hud:
Code:
init()
{
game["ratio"] = &"DEMON_TEST";
precacheString( game["ratio"] );
level thread onPlayerConnect();
}
onPlayerConnect()
{
for( ;; )
{
level waittill( "connected", player );
player thread onPlayerSpawned();
player thread onPlayerKilled();
}
}
onPlayerSpawned()
{
self endon( "disconnect" );
for( ;; )
{
self waittill( "spawned_player" );
self thread ratio();
}
}
onPlayerKilled()
{
self endon( "disconnect" );
for( ;; )
{
self waittill( "killed_player" );
if( isDefined( self.ratiohud ) )
self.ratiohud destroy();
}
}
ratio()
{
self endon( "killed_player" );
self endon( "disconnect" );
if( isDefined( self.ratiohud ) ) self.ratiohud destroy();
if( !isDefined( self.ratiohud ) )
{
self.ratiohud = newClientHudElem( self );
self.ratiohud.vertAlign = "fullscreen";
self.ratiohud.horzAlign = "fullscreen";
self.ratiohud.alignX = "left";
self.ratiohud.alignY = "middle";
self.ratiohud.x = 25;
self.ratiohud.y = 474;
self.ratiohud.sort = 1;
self.ratiohud.alpha = 1;
self.ratiohud.fontScale = 0.8;
self.ratiohud.archived = true;
self.ratiohud.label = (game["ratio"]);
}
self thread UpdateHud();
}
UpdateHud()
{
if( isDefined( self.ratiohud ) )
self.ratiohud setValue( self.pers["kills"] );
}
There are 2 callbacks in the gametype files:
Code:
Callback_PlayerDisconnect()
{
iprintln( &"MP_DISCONNECTED", self );
self thread demon\_playerdata::saveKills( self.pers["kills"] );
}
Code:
Callback_PlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
{
attacker thread demon\_playerdata::onPlayerScore();
}
I've never worked much with the "write" file function. I've always only really used the "read" function. It was an interesting, if somewhat frustrating, experience. I never knew that a data file will not overwrite itself when the "write" function is used. Now, to work out how to create a new line using "append". If anyone knows how, you can perhaps share and save me some experimentation time.