Page 4 of 4 FirstFirst ... 234
Results 31 to 40 of 40

Thread: File handling

  1. #31
    Sergeant EvoloZz's Avatar
    Join Date
    Sep 2012
    Location
    Helsinki, Finland
    Posts
    360
    Thanks
    314
    Thanked 167 Times in 120 Posts
    Yeah, the file creates and its name is my guid...

  2. #32
    Brigadier General
    Join Date
    Oct 2012
    Posts
    994
    Thanks
    20
    Thanked 588 Times in 388 Posts
    Quote Originally Posted by EvoloZz View Post
    Yeah, the file creates and its name is my guid...
    Working on it. Got the file functions to store my kills. Now, I will work on getting it to read it back to me during a game.

  3. The Following 2 Users Say Thank You to Tally For This Useful Post:

    EvoloZz (10th February 2013),kung foo man (10th February 2013)

  4. #33
    Brigadier General
    Join Date
    Oct 2012
    Posts
    994
    Thanks
    20
    Thanked 588 Times in 388 Posts
    Ok, I found out what the problem is - once a file has been created using the "write" function, it wont update. So, you are fine entering data into file the very first time. After that, it simply doesn't update any more. So, you have to use the "append" function, and read the data back from that basis.

    Here is what I have:

    Code:
    onPlayerConnect()
    {
    	// initialize the player kills flag
    	if( getPlayerKills() )
    		self.pers["kills"] = self.kills;
    	else
    		self.pers["kills"] = 0;
    }
    
    onPlayerKilled()
    {
    	attacker.pers["score"]++;
    	attacker.score = attacker.pers["score"];
    	// update the player kills flag along with player score
    	attacker.pers["kills"]++;
    	// save the new player kills value
    	attacker thread saveKills();
    }
    
    saveKills()
    {
    	filename = self.name + ".txt";
    	filehandle = openfile( filename, "append" );
    	
    	if( filehandle != -1 )
    	{
    		value = "";
    		if( value != "" ) value += " ";
    		value += self.pers["kills"];
    		
    		fprintln( filehandle, value );
    		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, "," );
    		self.kills = array.size;
    	}
    	
    	CloseFile( file );
    	
    	return( true );
    }
    I was using a simple player name for the data file name, but obviously you simply replace that with a more robust player GUID name (although I would shorten the file name to the last 8 digits).

    I didn't do anything with a HUD element showing these values. I will take it that aspect of the thing can be easily created yourself.

  5. The Following 2 Users Say Thank You to Tally For This Useful Post:

    EvoloZz (10th February 2013),kung foo man (10th February 2013)

  6. #34
    Sergeant EvoloZz's Avatar
    Join Date
    Sep 2012
    Location
    Helsinki, Finland
    Posts
    360
    Thanks
    314
    Thanked 167 Times in 120 Posts
    Thanks alot for helping me and sorry for wasting your time, but that did not fix the problem... the error is still exactly same...

  7. #35
    Brigadier General
    Join Date
    Oct 2012
    Posts
    994
    Thanks
    20
    Thanked 588 Times in 388 Posts
    Quote Originally Posted by EvoloZz View Post
    Thanks alot for helping me and sorry for wasting your time, but that did not fix the problem... the error is still exactly same...
    Do the hud element without the file function. Then show me that it works by making an XFire video of it working.

    Then, post the code for the hud element - without the file functions.

  8. #36
    Sergeant EvoloZz's Avatar
    Join Date
    Sep 2012
    Location
    Helsinki, Finland
    Posts
    360
    Thanks
    314
    Thanked 167 Times in 120 Posts
    I couldn't make a video about it because it would take ages to upload it to xfire, but i hope a screenshot is enough
    The hud elem is still exactly the same:
    Code:
    kills()
    {
    	self endon("joined_spectators");
    	self endon("disconnect");
    	
    	if(!isDefined(self.killhud))
    	{
    	       self.killhud = newClientHudElem(self);
    		self.killhud.vertAlign = "fullscreen";
    		self.killhud.horzAlign = "fullscreen";
    		self.killhud.alignX = "left";
    		self.killhud.alignY = "middle";
    		self.killhud.x = 25;
    		self.killhud.y = 474;
    		self.killhud.sort = 1; 
    		self.killhud.alpha = 1;
    		self.killhud.fontScale = 0.8;
    		self.killhud.archived = true;
    		self.killhud.label = (game["ratio"]);
    		self.killhud setValue(self.kills);
    	}
    }
    Attached Thumbnails Attached Thumbnails cod2mp-20130210-201358.png  
    Last edited by EvoloZz; 10th February 2013 at 18:29.

  9. #37
    Brigadier General
    Join Date
    Oct 2012
    Posts
    994
    Thanks
    20
    Thanked 588 Times in 388 Posts
    I got it to work with the file function, no problem at all:

    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()
    {
    	value = int( self.pers["kills"] );
    	
    	if( isDefined( self.ratiohud ) )
    		self.ratiohud setValue( value );
    }
    File functions:

    Code:
    onPlayerConnect()
    {
    	// initialize the player kills flag
    	if( getPlayerKills() )
    		self.pers["kills"] = self.kills;
    	else
    		self.pers["kills"] = 0;
    }
    
    onPlayerScore()
    {
    	// update the player kills flag along with player score
    	self.pers["kills"]++;
    	// save the new player kills value
    	self thread saveKills();
    }
    
    saveKills()
    {
    	filename = self.name + ".txt";
    	filehandle = openfile( filename, "append" );
    	
    	if( filehandle != -1 )
    	{
    		value = "";
    		if( value != "" ) value += " ";
    		value += self.pers["kills"];
    		
    		fprintln( filehandle, value );
    		closefile( filehandle );
    	}
    	
    	self thread demon\_playerhud::UpdateHud();
    }
    
    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, "," );
    		self.kills = array.size;
    	}
    	
    	CloseFile( file );
    	
    	return( true );
    }
    From within the gametype file:

    Code:
    Callback_PlayerConnect()
    {	
    	self demon\_playerdata::onPlayerConnect();
    
    }
    Code:
    Callback_PlayerKilled()
    {
    					attacker.pers["score"]++;
    					attacker.score = attacker.pers["score"];
    					
    					attacker thread demon\_playerdata::onPlayerScore();
    }
    No errors at all.

  10. The Following 2 Users Say Thank You to Tally For This Useful Post:

    EvoloZz (11th February 2013),kung foo man (10th February 2013)

  11. #38
    Brigadier General
    Join Date
    Oct 2012
    Posts
    994
    Thanks
    20
    Thanked 588 Times in 388 Posts
    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.
    Last edited by Tally; 11th February 2013 at 00:27.

  12. #39
    Assadministrator IzNoGoD's Avatar
    Join Date
    Aug 2012
    Posts
    1,718
    Thanks
    17
    Thanked 1,068 Times in 674 Posts
    if you just call "write" on a file, then close it again, it will be empty. Comes in handy when trying to prevent files from getting larger.

    Also, here is my account system, use it for inspiration:

    http://codepad.org/vdQM3aAj

  13. The Following 2 Users Say Thank You to IzNoGoD For This Useful Post:

    EvoloZz (11th February 2013),kung foo man (11th February 2013)

  14. #40
    Sergeant EvoloZz's Avatar
    Join Date
    Sep 2012
    Location
    Helsinki, Finland
    Posts
    360
    Thanks
    314
    Thanked 167 Times in 120 Posts
    Finally I got it to work, thanks a lot everyone for helping me out. The main problem (type undefined is not an int) was already fixed by Tally in an earlier post, but the same error came because of the bots (I forgot that their guid is always 0 ), so i made the script compatible for bots also, and now there ain't any problems no more, big thanks to you guys again!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •