Game Development Community

dev|Pro Game Development Curriculum

T3D Clip/Ammo Counter

by Donnie Hutson Jr · 03/04/2014 (11:08 pm) · 4 comments

Ok, right or wrong and my first resource, this is how I came about my clip/ammo counter in the weapons hud. If anyone has any advice on a better way please by all means post it!!!

1. In game/scripts/server/commands.cs weapon reloading, replace this

%image.clearAmmoClip(%player, $WeaponSlot);
to
%image.reloadAmmoClip(%player, $WeaponSlot);

2. In all weapon CS files, located in art/datablocks/weapons folder, add or change the following;

datablock ItemData(YOURWEAPONNAMEClip)
{
   // Mission editor category
   category = "AmmoClip";

   // Add the Ammo namespace as a parent.  The ammo namespace provides
   // common ammo related functions and hooks into the inventory system.
   className = "AmmoClip";

   // Basic Item properties
   shapeFile = "art/shapes/weapons/YOURWEAPONCLIPMODEL.dts";
   mass = 1;
   elasticity = 0.2;
   friction = 0.6;

   // Dynamic properties defined by the scripts
   pickUpName = "YOURWEAPONNAME AmmoClip";
   count = 1;
   maxInventory = 3;
   clip = YOURWEAPONNAMEClip;//<--------DH Clip Count 
};

datablock ItemData(YOURWEAPONNAMEAmmo)
{
   // Mission editor category
   category = "Ammo";

   // Add the Ammo namespace as a parent.  The ammo namespace provides
   // common ammo related functions and hooks into the inventory system.
   className = "Ammo";

   // Basic Item properties
   shapeFile = "art/shapes/weapons/YOURWEAPONAMMOMODEL.dts";
   mass = 1;
   elasticity = 0.2;
   friction = 0.6;

   // Dynamic properties defined by the scripts
   pickUpName = "YOURWEAPONNAME ammo";
   maxInventory = 30;
   clip = YOURWEAPONNAMEClip;//<--------DH Clip Count 
};

in the same file under datablock ShapeBaseImageData(YOURWEAPONNAMEImage)

// Projectile && Ammo.
   item = "YOURWEAPONNAME";
   ammo = "YOURWEAPONNAMEAmmo";
   clip = "YOURWEAPONNAMEClip";//<--------DH Clip Count
   projectile = "YOURWEAPONNAMEProjectile";
   projectileType = "Projectile";

SAVE and close file...

2. in game/scripts/client/client.cs file, change clientCmdSetAmmoAmountHud and clientCmdRefreshWeaponHUD to the following;

function clientCmdSetAmmoAmountHud(%getClipCount, %amount)//<--------DH Clip Count  
{  
   if (!%amount)  
      AmmoAmount.setVisible(false);  
   else  
   {  
      AmmoAmount.setVisible(true);  
      AmmoAmount.setText("Ammo: " @ %getClipCount @ "/" @ %amount);//<--------DH Clip Count  
   }  
}  
  
function clientCmdRefreshWeaponHUD(%getClipCount, %preview, %ret, %zoomRet, %amount)//<--------DH Clip Count  
{  
   if (!%amount)  
      AmmoAmount.setVisible(false);  
   else  
   {  
      AmmoAmount.setVisible(true);  
      AmmoAmount.setText("Ammo: " @ %getClipCount @ "/" @ %amount);//<--------DH Clip Count  
   }

SAVE and close the file...

3. in game/scripts/server/game.cs near the end, change the following;

function GameConnection::setAmmoAmountHud(%client, %getClipCount, %amount )//<--------DH Clip Count  
{  
   commandToClient(%client, 'SetAmmoAmountHud', %getClipCount, %amount);//<--------DH Clip Count  
}  
  
function GameConnection::RefreshWeaponHud(%client, %getClipNumber, %preview, %ret, %zoomRet, %amount)//<--------DH Clip Count  
{  
   commandToClient(%client, 'RefreshWeaponHud', %getClipNumber, %preview, %ret, %zoomRet, %amount);//<--------DH Clip Count  
}

SAVE and close the file...

4. in game/scripts/server/weapon.cs file change the following functions;

function WeaponImage::onMount(%this, %obj, %slot)  
    {  
       // Images assume a false ammo state on load.  We need to  
       // set the state according to the current inventory.  
       if(%this.isField("clip"))  
       {  
          // Use the clip system for this weapon.  Check if the player already has  
          // some ammo in a clip.  
          if (%obj.getInventory(%this.ammo))  
          {  
             %obj.setImageAmmo(%slot, true);  
             %currentAmmo = %obj.getInventory(%this.ammo);  
          }  
          else if(%obj.getInventory(%this.clip) > 0)  
          {  
             // Fill the weapon up from the first clip  
             %obj.setInventory(%this.ammo, %this.ammo.maxInventory);  
             %obj.setImageAmmo(%slot, true);  
               
             // Add any spare ammo that may be "in the player's pocket"  
             %currentAmmo = %this.ammo.maxInventory;  
             %amountInClips += %obj.getFieldValue( "remaining" @ %this.ammo.getName());  
          }  
          else  
          {  
             %currentAmmo = 0 + %obj.getFieldValue( "remaining" @ %this.ammo.getName());  
          }  
            
          %getClipCount = %obj.getInventory(%this.clip);//<--------DH Clip Count  
                  
          if (%obj.client !$= "" && !%obj.isAiControlled)  
             %obj.client.RefreshWeaponHud(%getClipCount, %this.item.previewImage, %this.item.reticle, %this.item.zoomReticle, %currentAmmo);//<--------DH Clip Count  
       }  
       else if(%this.ammo !$= "")  
       {  
          // Use the ammo pool system for this weapon  
          if (%obj.getInventory(%this.ammo))  
          {  
             %obj.setImageAmmo(%slot, true);  
             %currentAmmo = %obj.getInventory(%this.ammo);  
          }  
          else  
             %currentAmmo = 0;  
      
          if (%obj.client !$= "" && !%obj.isAiControlled)  
             %obj.client.RefreshWeaponHud( 1, %this.item.previewImage, %this.item.reticle, %this.item.zoomReticle, %getClipCount, %currentAmmo);//<--------DH Clip Count  
       }  
    }

in the same file....

function AmmoClip::onPickup(%this, %obj, %shape, %amount)  
{  
   // The parent Item method performs the actual pickup.  
   if (Parent::onPickup(%this, %obj, %shape, %amount))  
      serverPlay3D(AmmoPickupSound, %shape.getTransform());  
  
   // The clip inventory state has changed, we need to update the  
   // current mounted image using this clip to reflect the new state.  
   if ((%image = %shape.getMountedImage($WeaponSlot)) > 0)  
   {  
      // Check if this weapon uses the clip we just picked up and if  
      // there is no ammo.  
      if (%image.isField("clip") && %image.clip.getId() == %this.getId())  
      {  
         %outOfAmmo = !%shape.getImageAmmo($WeaponSlot);  
           
         %currentAmmo = %shape.getInventory(%image.ammo);  
  
         if ( isObject( %image.clip ) )  
            %getClipCount = %shape.getInventory(%image.clip);//<--------DH Clip Count  
            %getClipCount += %obj.getFieldValue( "remaining" @ %this.clip.getName() );//<--------DH Clip Count  
                             
         %shape.client.setAmmoAmountHud(%getClipCount, %currentAmmo);//<--------DH Clip Count  
  
         if (%outOfAmmo)  
         {  
            %image.onClipEmpty(%shape, $WeaponSlot);  
         }  
      }  
   }     
}  
  
function Ammo::onInventory(%this, %obj, %amount)  
{  
   // The ammo inventory state has changed, we need to update any  
   // mounted images using this ammo to reflect the new state.  
   for (%i = 0; %i < 8; %i++)  
   {  
      if ((%image = %obj.getMountedImage(%i)) > 0)  
         if (isObject(%image.ammo) && %image.ammo.getId() == %this.getId())  
         {  
            %obj.setImageAmmo(%i, %amount != 0);  
            %currentAmmo = %obj.getInventory(%this);  
              
            if (%obj.getClassname() $= "Player")  
            {  
               if ( isObject( %this.clip ) )  
               {  
                  %getClipCount = %obj.getInventory(%this.clip);//DH Clip Count  
                  %getClipCount += %obj.getFieldValue( "remaining" @ %this.getName() );//<--------DH Clip Count                    
               }  
               else //Is a single fire weapon, like the grenade launcher.  
               {  
                  %amountInClips = %currentAmmo;                    
                  %currentAmmo = 1;  
               }  
                 
               if (%obj.client !$= "" && !%obj.isAiControlled)  
                  %obj.client.setAmmoAmountHud(%getClipCount, %currentAmmo);//<--------DH Clip Count  
            }  
        }  
    }  
}

SAVE and close file.... if I didnt forget anything, your weapons hud in game will show as a clip/ammo counter like this, Ammo: 3/30, instead of the ammo/total ammo counter...... Enjoy!!!

About the author

Electrical Engineer by trade, Computer geek by night. Still learning and loving every minute.

Recent Blogs

• T3D 3dArrow Port

#1
03/05/2014 (9:49 pm)
Thanks for sharing @Donnie!
#2
03/06/2014 (6:49 am)
Hope it helps someone.... lol Im still a beginner at programming but I try!!
#3
07/24/2014 (2:57 am)
hmm what about displaying it like : currentMagAmmo/Number of mags ?
#4
03/24/2015 (6:12 pm)
I think you can just switch getclipcount and currentammo around.... And this does port to T3D 3.6.3!!!