Game Development Community

RTS Stats gui ... a step towards displaying stats for client/units

by Jeff Yaskus · in RTS Starter Kit · 03/02/2010 (11:37 am) · 5 replies

My project is almost complete ... in fact, its due today. So I was trying to get the scoring to update and also the stats to work. I figured out how to add to the current stats ... and made a gui using the example from this other post;

http://www.torquepowered.com/community/resources/view/13020

To help others out -- here is the RTS Kit specific directions;

first create a new file called StatsGui.gui under client/ui/
//--- OBJECT WRITE BEGIN ---  
new GuiControl(StatsGUI) {  
    profile = "GuiDefaultProfile";  
    horizSizing = "right";  
    vertSizing = "bottom";  
    position = "0 0";  
    extent = "440 480";  
    minExtent = "8 2";  
    visible = "1";  
   
    new GuiWindowCtrl(StatsWindow) {  
       profile = "GuiWindowProfile";  
       horizSizing = "left";  
       vertSizing = "bottom";  
       position = "2 -2";  
       extent = "320 460";  
       minExtent = "8 2";  
       visible = "1";  
       text = "Stats";  
       maxLength = "255";  
       resizeWidth = "1";  
       resizeHeight = "1";  
       canMove = "1";  
       canClose = "1";  
       canMinimize = "1";  
       canMaximize = "1";  
       minSize = "50 50";  
       CloseCommand = "Canvas.PopDialog(StatsGUI);";  
        
       new GuiScrollCtrl() {  
          profile = "GuiScrollProfile";  
          horizSizing = "left";  
          vertSizing = "bottom";  
          position = "30 30";  
          extent = "200 400";  
          minExtent = "8 2";  
          visible = "1";  
          willFirstRespond = "1";  
          hScrollBar = "alwaysOn";  
          vScrollBar = "alwaysOn";  
          constantThumbHeight = "0";  
          childMargin = "0 0";  
   
          new GuiTextListCtrl(StatsListView) {  
             profile = "GuiTextArrayProfile";  
             horizSizing = "center";  
             vertSizing = "center";  
             position = "2 2";  
             extent = "188 2";  
             minExtent = "8 2";  
             visible = "1";  
             enumerate = "0";  
             resizeCell = "1";  
             columns = "0";  
             fitParentWidth = "1";  
             clipColumnText = "0";  
          };  
       };  
    };  
 };  
 //--- OBJECT WRITE END --- 
 function toggleStatsGUI(%val)
{
	if(%val)
      StatsGUI.toggle();
}

function StatsGUI::OnWake(%this)
{
	UpdateStatsListView();
}

//This function updates the StatsListView
function UpdateStatsListView()
{
	StatsListView.clear();	

	echo("Updating the players Stats gui ...");

   // valid only for player 0 -- currently
	%client = ClientGroup.getObject(0);	

   // Client stats
	StatsListView.addRow(0,"Client - Kills         :" SPC %client.stats["Kills"]);
	StatsListView.addRow(1,"Client - Damage Done   :" SPC %client.stats["Damage Delt"]);
	StatsListView.addRow(2,"Client - Units Built   :" SPC %client.stats["Units Built"]);
	StatsListView.addRow(3,"-------------------------------------------------------");
	
	%count = 4;
	
	if (isObject(%client.units))
      for( %i = 0; %i < %client.units.getCount(); %i++ )
      {
         %unit = %client.units.getObject(%i);
         %unitType = %unit.getDatablock().RTSUnitTypeName;
         StatsListView.addRow(%count++,%i @ "." @ %unitType SPC "Kills        :" SPC %unit.stats["Kills"]);      
         StatsListView.addRow(%count++,%i @ "." @ %unitType SPC "Damage Done  :" SPC %unit.stats["Damage Delt"]);	   
      } 

	StatsListView.setSelectedRow(0);
	StatsListView.scrollVisible(0);
}

function StatsGUI::toggle(%this)
{
    if (%this.isAwake())
      Canvas.popDialog(%this);
    else
      Canvas.pushDialog(%this);
}

add to client/scripts/default.bind.cs ... so we can bring it up.
//Allows us to view our stats gui with "s" key
moveMap.bind(keyboard,  s,          toggleStatsGUI);

add to client/init.cs ... up near the top, before default.bind.cs so it recognizes the function call
exec("./ui/statsGui.gui");

add to client/scripts/optionDlg.cs ... so the player can remap the key if needed.
$RemapName[$RemapCount] = "Toggle Stats Dialog";
$RemapCmd[$RemapCount] = "toggleStatsGUI";
$RemapCount++;

OK - that gets you the GUI and all its glory ... (well its quite simple actually)

But now -- how do we "increment" the stats ? Hmm ... lets goto the server/scripts/avatars/player.cs file;

Use this as an example to apply your stats collections ...
function RTSUnitData::damage(%this, %obj, %sourceObject, %position, %damage, %damageType)
{
  ...   
   // Deal with client callbacks here because we don't have this
   // information in the onDamage or onDisable methods
   %client = %obj.client;
   %sourceClient = %sourceObject ? %sourceObject.client : 0;
 ...   
   // give credit for damage
   %sourceClient.stats["Damage Delt"]+= %damage;  // for the client itself
   %sourceObject.stats["Damage Delt"]+= %damage;  // for each unit
  ...
}

oh, and I added this function ... to catch all the onDeath calls for units;
function Player::onDeath(%this, %client, %sourceObject, %sourceClient, %damageType, %location)
{   
   // try to only let the object die once
   if (%sourceObject.died == true)
      return;      
   %sourceObject.died = true;
   
   // credit them for the death  
   %sourceClient.stats["Kills"]++;
   %sourceObject.stats["Kills"]++;   
}

One other place I added stats ... is when the units get built when the game loads;
~/server/scripts/core/gameConnection.cs
function RTSConnection::createPlayer(%this, %spawnPoint, %index)
{
 ...
   %player.stats["Kills"] = 0;            //(getRandom() * 5) % 5;      // ? how to add these in game ? JY
   %player.stats["Damage Delt"] = 0;      //(getRandom() * 1000) % 1000;
   
   //keep track of units built per client
   %this.stats["Units Built"]++;
 ...
}

Player::onAdd() is possibly a better place to put this ... but for some reason, it doesn't seem to ever get called.

So its not keeping stats on building built either ... this is just a "starter kit" :O)

#1
03/02/2010 (5:42 pm)
So is there any chance that we'll be able to see the results of all your hard work, or is it destined to be filed away on your tutors desk never to be seen again?
#2
03/02/2010 (5:47 pm)
I just read that we use the game we made from this term, as our senior project ... and refine, improve and polish it into a full product. Of course, all this in 9 weeks or less. (like this time around)

I'll look at uploading it for everyone to view ... is there a "how to" or such, on best practices before uploading a game ? I'd want to be sure and protect the artists interests as well --
#3
09/06/2014 (7:37 pm)
A bit late, but I did eventually make it part of my portfolio site, before graduation:
jyaskus.com/gameAssets/frts/frts%20demo.zip
#4
09/08/2014 (8:30 am)
Wow - we still need to get together as a community and build a RTS branch of T3D. The Prototype is nifty, but there are some engine-side things that would be nice to add - in a branch so as not to clutter the main engine.
#5
09/12/2014 (4:33 am)
Wow - a new post :), thought this stuff was dead. Wouldn't mind seeing community/support for the T3D RTS stuff as well. Thanks for the sample and the post Jeff !