Weapon Reload Tutorial
by Tim Newell · 03/04/2002 (9:57 am) · 26 comments
Weapon Reload Tutorial
This tutorial covers setting up torque to allow for bullet reload animations (like pulling back the bolt lever on a rifle and pushing a new shell in) and clip reloading. (reloading the gun with bullets) It is all done within script so there are no C++ changes and it works with the standard torque inventory system.
First thing we will do is add our reload clip keyboard bind. Do to the fact that by default "r" is used in another function I will use the letter "g" to reload clips with.
Open fps/client/config.cs if it exists (this is a generated file by the options dlg)
add to the bottom of it:
Next open fps/client/scripts/default.bind.cs and add to it
Now that we have the keyboard bound to the command...lets add the command to the server code.
Open fps/server/scripts/commands.cs and add the following function to the bottom.
Now to the weapon specific code. The following changes that I make to fps/server/scripts/rifle.cs will need to be made for all of your weapons.
First we define a new datablock..add this after datablock ItemData(RifleAmmo)
Next go down to datablock ShapeBaseImageData(RifleImage) and go to the line in it ammo = RifleAmmo; and after that line:
Also in this same datablock go to the line stateEjectShell[4] = true; and add after it:
Next add the following 3 functions to the end of the file:
Now we need to update the player datablock to know how many clips we can carry
Go to fps/server/scripts/player.cs and go down to the [/b]datablock PlayerData(LightMaleHumanArmor)[/b] and add this to the datablock: (best place would be at the end with the other vars like it)
The last change to make is to open up your mission files and change the RifleAmmo to RifleAmmoClip (The little blue boxes will represent clips)
To do this open fps/data/missions/waterWorld.mis and look for something that looks like this:
and change the dataBlock = "RifleAmmo"; to dataBlock = "RifleAmmoClip";
Now when you go in game and pickup the rifle and clips you will not be able to fire until you press the reload key ("g")...then you will have 50 shots until you have to reload again. You'll notice that I didnt have any real animations so instead I print to the screen and describe what is happening :)
If you see any bugs, like always let me know.
-Tim aka Spock
This tutorial covers setting up torque to allow for bullet reload animations (like pulling back the bolt lever on a rifle and pushing a new shell in) and clip reloading. (reloading the gun with bullets) It is all done within script so there are no C++ changes and it works with the standard torque inventory system.
First thing we will do is add our reload clip keyboard bind. Do to the fact that by default "r" is used in another function I will use the letter "g" to reload clips with.
Open fps/client/config.cs if it exists (this is a generated file by the options dlg)
add to the bottom of it:
moveMap.bindCmd(keyboard, "g", "commandToServer(\'WeaponReload\');", "");
Next open fps/client/scripts/default.bind.cs and add to it
moveMap.bindCmd(keyboard, "g", "commandToServer(\'WeaponReload\');", "");
Now that we have the keyboard bound to the command...lets add the command to the server code.
Open fps/server/scripts/commands.cs and add the following function to the bottom.
function serverCmdWeaponReload(%client) {
%currentWeapon = %client.player.getMountedImage($WeaponSlot);
%currentWeapon.ReloadAmmoClip(%client.player);
}Now to the weapon specific code. The following changes that I make to fps/server/scripts/rifle.cs will need to be made for all of your weapons.
First we define a new datablock..add this after datablock ItemData(RifleAmmo)
datablock ItemData(RifleAmmoClip)
{
// 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 = "~/data/shapes/rifle/ammo.dts";
mass = 1;
elasticity = 0.2;
friction = 0.6;
// Dynamic properties defined by the scripts
pickUpName = "rifle clip";
maxInventory = 1;
};Next go down to datablock ShapeBaseImageData(RifleImage) and go to the line in it ammo = RifleAmmo; and after that line:
clip = RifleAmmoClip;
Also in this same datablock go to the line stateEjectShell[4] = true; and add after it:
stateScript[4] = "onReload";
Next add the following 3 functions to the end of the file:
function RifleImage::onReload(%this, %obj, %slot)
{
//remember to adjust how long the state lasts so your animation isnt interrupted
%message = "I pull the bolt action back and the shell ejects..." @
"I shove another shot into the chamber as I push the lever back. " @
"This would be cooler with a animation too...huh?";
%time = 5;
%lines = 2;
//to keep it from printing on a clip reload
if (%obj.getInventory(%this.ammo) < %this.ammo.maxInventory)
centerPrint( %obj.client, %message, %time, %lines );
}
function RifleImage::ReloadAmmoClip(%this, %obj) {
if (%obj.getInventory(%this.clip) > 0) {
%message = "I push a stripperclip of ammo into the gun..." @
"I shove another shot into the chamber as I push the lever back. " @
"This would be cooler with a animation...huh?";
%time = 5;
%lines = 2;
centerPrint( %obj.client, %message, %time, %lines );
//remember to change this first number to the number of milliseconds
//that your animation lasts
schedule(2000, 0, "reloadBullets",%this,%obj);
} else {
%message = "Shazbot! I don't have any clips!";
%time = 5;
%lines = 1;
centerPrint( %obj.client, %message, %time, %lines );
}
}
function reloadBullets(%image, %obj) {
// 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))
%obj.setImageAmmo(%i,true);
}
%obj.decInventory(%image.clip,1);
%obj.setInventory(%image.ammo,%image.ammo.maxInventory);
}Now we need to update the player datablock to know how many clips we can carry
Go to fps/server/scripts/player.cs and go down to the [/b]datablock PlayerData(LightMaleHumanArmor)[/b] and add this to the datablock: (best place would be at the end with the other vars like it)
maxInv[RifleAmmoClip] = 10;
The last change to make is to open up your mission files and change the RifleAmmo to RifleAmmoClip (The little blue boxes will represent clips)
To do this open fps/data/missions/waterWorld.mis and look for something that looks like this:
new Item() {
position = "-129.578 -104.689 212.995";
rotation = "1 0 0 0";
scale = "1 1 1";
dataBlock = "RifleAmmo";
collideable = "0";
static = "1";
rotate = "1";
};and change the dataBlock = "RifleAmmo"; to dataBlock = "RifleAmmoClip";
Now when you go in game and pickup the rifle and clips you will not be able to fire until you press the reload key ("g")...then you will have 50 shots until you have to reload again. You'll notice that I didnt have any real animations so instead I print to the screen and describe what is happening :)
If you see any bugs, like always let me know.
-Tim aka Spock
#22
here's what I have for the backpack ammo setup except my bpammo remains named clip for ease of integration, however clip as a name is a little misleading in this case so don't think of clip as actually meaning anything other than the reserve ammo. This needs a second HUD for clips if you don't already have one.
function M16Image::ReloadAmmoClip(%this, %obj)
{
%requestedAmmo = %this.ammo.maxInventory - %obj.getInventory(%this.ammo);
if (%obj.getInventory(%this.clip) < %this.ammo.maxInventory)
{
if (%requestedAmmo > %obj.getInventory(%this.clip))
{
if (%obj.getInventory(%this.clip) < 1)
{
%message = "out of clips!";
%time = 5;
%lines = 1;
centerPrint( %obj.client, %message, %time, %lines );
}
else
{
%reloadamount = %obj.getInventory(%this.clip);
echo("reload amount is "@ %reloadamount);
schedule(2200, 0, "reloadBullets" ,%this, %obj, %reloadamount);
}
}
else
{
%reloadamount = %this.ammo.maxInventory - %obj.getInventory(%this.ammo);
echo("reload amount is "@ %reloadamount);
schedule(2200, 0, "reloadBullets", %this, %obj, %reloadamount);
}
}
else
{
%reloadamount = %this.ammo.maxInventory - %obj.getInventory(%this.ammo);
echo("reload amount is "@ %reloadamount);
schedule(2200, 0, "reloadBullets", %this, %obj, %reloadamount);
}
}
function reloadBullets(%image, %obj, %reloadamount)
{
echo("reload amount is "@ %reloadamount);
// 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))
%obj.setImageAmmo(%i,true);
}
%obj.decInventory(%image.clip, %reloadamount);
%obj.incInventory(%image.ammo, %reloadamount);
%currentAmmo = %obj.getInventory(%image.ammo);
%obj.client.setAmmoAmountHud(%currentAmmo);
%currentClip = %obj.getInventory(%image.clip);
%obj.client.setClipAmountHud(%currentClip);
}
Automatic Reload at 0 ammo.
and in the onFire in you rifle.cs or whatever gun your using I put this right before
return %p near the bottom of he function. before return %p not after.
if (%obj.getInventory(%this.ammo) < 1)
{
commandToServer('WeaponReload');
}
Make sure your game.cs does not spawn your player with more ammo or clips than your player.cs maxInventory.
hopefully I've pasted everything here you need. Anyone reading this before putting in Tim's resource should STOP NOW and go to the top and finish his tut start to finish before making these changes. 1. to learn 2. it won't work without Tim's tutorial having been completed.
If I forgot something and it doesn't work let me know.
Thanks for great Tut Tim, You definitely have street cred in my book.
06/24/2007 (7:51 am)
@Hong Jin Parkhere's what I have for the backpack ammo setup except my bpammo remains named clip for ease of integration, however clip as a name is a little misleading in this case so don't think of clip as actually meaning anything other than the reserve ammo. This needs a second HUD for clips if you don't already have one.
function M16Image::ReloadAmmoClip(%this, %obj)
{
%requestedAmmo = %this.ammo.maxInventory - %obj.getInventory(%this.ammo);
if (%obj.getInventory(%this.clip) < %this.ammo.maxInventory)
{
if (%requestedAmmo > %obj.getInventory(%this.clip))
{
if (%obj.getInventory(%this.clip) < 1)
{
%message = "out of clips!";
%time = 5;
%lines = 1;
centerPrint( %obj.client, %message, %time, %lines );
}
else
{
%reloadamount = %obj.getInventory(%this.clip);
echo("reload amount is "@ %reloadamount);
schedule(2200, 0, "reloadBullets" ,%this, %obj, %reloadamount);
}
}
else
{
%reloadamount = %this.ammo.maxInventory - %obj.getInventory(%this.ammo);
echo("reload amount is "@ %reloadamount);
schedule(2200, 0, "reloadBullets", %this, %obj, %reloadamount);
}
}
else
{
%reloadamount = %this.ammo.maxInventory - %obj.getInventory(%this.ammo);
echo("reload amount is "@ %reloadamount);
schedule(2200, 0, "reloadBullets", %this, %obj, %reloadamount);
}
}
function reloadBullets(%image, %obj, %reloadamount)
{
echo("reload amount is "@ %reloadamount);
// 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))
%obj.setImageAmmo(%i,true);
}
%obj.decInventory(%image.clip, %reloadamount);
%obj.incInventory(%image.ammo, %reloadamount);
%currentAmmo = %obj.getInventory(%image.ammo);
%obj.client.setAmmoAmountHud(%currentAmmo);
%currentClip = %obj.getInventory(%image.clip);
%obj.client.setClipAmountHud(%currentClip);
}
Automatic Reload at 0 ammo.
and in the onFire in you rifle.cs or whatever gun your using I put this right before
return %p near the bottom of he function. before return %p not after.
if (%obj.getInventory(%this.ammo) < 1)
{
commandToServer('WeaponReload');
}
Make sure your game.cs does not spawn your player with more ammo or clips than your player.cs maxInventory.
hopefully I've pasted everything here you need. Anyone reading this before putting in Tim's resource should STOP NOW and go to the top and finish his tut start to finish before making these changes. 1. to learn 2. it won't work without Tim's tutorial having been completed.
If I forgot something and it doesn't work let me know.
Thanks for great Tut Tim, You definitely have street cred in my book.
#23
06/25/2007 (12:59 pm)
Worked the first time, thank you!
#24
01/27/2008 (11:36 am)
Works perfectly. One question? Is there a setting for bolt action vs automatic?
#26
07/20/2011 (3:30 pm)
NVM I figured it out lol 
Torque Owner Joseph Jonathan