Day 2: Weapons

By now you should have at least the basics of movement covered. Now we are going to learn how to dish out damage by using our weapons. Today we cover aiming, shooting, and reloading weapons.

Weapon Types

There are four basic weapon types. These are covered in the Robot Programming Manual ( http://www.conitec.net/arena/manual.htm ) in Appendix C. Each weapon has its own advantages and disadvantages. For instance, the laser does a great deal of damage, but it has a slow reload rate. Machineguns reload very quickly, but do the least amount of damage of all weapons.

Each robot chassis has two weapons, one on each arm. The weapon types are pre-selected for the chassis. Look at Appendix B of the Robot Programming Manual to see how the weapons are matched. Weapon #1 is on the right arm of the robot; weapon #2 is on the left arm.

 

Firing a Weapon

It is easy to fire a weapon, simply set the value of gun1_fire (for weapon #1) or gun2_fire (for weapon #2) to a value greater than zero. If the gun is loaded, the weapon will fire that round. For example:

 

function AI_ROBOT()
{
   // full speed ahead!!!
   force_left = 100;
   force_right = 100;
   
   // fire at target when close
   if(distance_to_target < 2000)
   {
      gun1_fire = 1; // fire primary
      gun2_fire = 1; // fire secondary
   }
}

Using this function your robot will charge blindly forward and shoot both its guns when the target is within 2000 quants. Obviously this is not a good strategy since we do not check to see if we are facing our opponent, there for we will only hit our opponent by pure luck. We will cover aiming a little later on.

Note: Unlike the apply_brake and force_left/force_right variables we talked about yesterday, the gunfire variables actually change from frame to frame depending on if a shot is fired. Each time a shot is fired, the gunfire value corresponding to that weapon is reduced by 1.

So what does this mean? In our above example, we tell both guns to fire when the target is within 2000 quants. This is fine as long as the weapons are loaded, but if the gun is still loading it will hold onto this value until the gun is loaded and then fire at that point. This will happen even if the target has moved out of range! This is a common mistake I will show a solution when I cover aiming.

 

Gun Status

In order for a weapon to fire it must have ammo and that ammo must be loaded (the only exception to this is the laser which has a reload time, but ‘unlimited’ ammo). We can monitor how much ammo we have left by checking the gun1_ammo and gun2_ammo values. These variables show how many more shots each weapon has before it runs out. If you are running low on ammo, or run completely out, you might want to rethink your attack:

 

function AI_ROBOT()
{
   // do we have ammo
   if((gun1_ammo == 0) && (gun1_ammo == 0))
   {
      // code to avoiding being shot
      …
   }
   else
   {
      // code for attacking our target
      …
   }
}

You can find out how much longer it will take to reload your weapons by checking the value stored in gun1_status and gun2_status. The values stored in these variables tell how many more ticks (remember 16 ticks equal 1 second) are left before the weapon is reloaded (expressed as a negative value) or it will contain a value of 1 if the weapon is ready to fire.

 

function AI_ROBOT()
{
   // more than 2 seconds before reload of main weapon
   if(gun1_status < -32)
   {
      // code to avoiding being shot
      …
   }
   else
   {
      // ready to fire?
      if(gun1_status == 1)
      {
         gun1_fire = 1;
      }
      else
      {
         // code for aiming at our target
         …
      }
   }
}

 

 

Aiming

Firing blindly we are not likely to score many hits on our target. Lucky for us we have already covered aiming in our previous workshop, movement. All we have to do is add a few more lines.

function AI_ROBOT()
{
   // ‘clear’ previous fire command
   gun1_fire = 0;
   gun2_fire = 0;
   
   // turn towards target
   if(angle_to_target > 5) // target to the left…
   {
      // turn left
      force_left = -5;
      force_right = 100;
      apply_brake = OFF;
   }
   else
   {
      if(angle_to_target < -5) // target to the right…
      {
         // turn right
         force_left = 100;
         force_right = -5;
         apply_brake = OFF;
      }
      else   // target dead ahead
      {
         // move forward, full speed
         force_right = 100;
         force_left = 100;
         apply_brake = OFF;
         // assume we are using a dual MG robot…
         if(distance_to_target < kRangeMG)
         {
            gun1_fire = 1;
            gun2_fire = 1;
         }
      }
   }
}

Since we only enter the last ‘else’ block of code when the target is within 5 degrees from straight ahead then there is a real good chance that our weapons are facing the target and will hit when fired.

Note: I ‘clear’ the gunfire values at the beginning of each turn by setting their values equal to ‘0’. This is important because a weapon may have been told to fire in a previous frame and not had the chance to because it needed to reload. If you don’t clear the value, it will fire at the next opportunity, which may not be what you wanted.

 

Line of Sight

The above solution works well for the Dual Machinegun robot (#3), since it has a fast reload rate but a short firing range. For the other robots you will probably want to use different strategies.

The laser robot, for instance, has very long range but an extremely slow reload time. In this case you will probable want to keep some distance from your target to make yourself harder to hit. As your range increases, so does the chance that something might get between you and your target. To make sure that you have a clear shot at your target you can check the los_to_target value before firing.

The los_to_target value is a simple Boolean value (meaning it can be either 1 or 0). If los_to_target equals 1 there is nothing between you and the target, if its value is 0 there is something in the way.

Note: Just because los_to_target is set to 1 doesn’t mean you are facing your target. Check your angle_to_target value make sure you are facing your target.

 

function AI_ROBOT()
{
   // ‘clear’ previous fire command
   gun1_fire = 0;
   gun2_fire = 0;

   // turn towards target
   if(angle_to_target > 5) // target to the left…
   {
      // turn left
      force_left = -5;
      force_right = 100;
      apply_brake = OFF;
   }
   else
   {
      if(angle_to_target < -5) // target to the right…
      {
         // turn right
         force_left = 100;
         force_right = -5;
         apply_brake = OFF;
      }
      else   // target dead ahead
      {
         // move forward, full speed
         force_right = 100;
         force_left = 100;
         apply_brake = OFF;
         // assume we are using a dual laser robot…
         if((distance_to_target < kRangeLaser)
            && (los_to_target == 1))
         {
            gun1_fire = 1;
            gun2_fire = 1;
         }
      }
   }
}

You should also remember that if the los_to_target value equals 1 chances are your opponent can see you as well.

 

Conclusion

Like movement, we just covered the very basics here. Hopefully this is enough to get you started. If you have any questions please feel free to ask them on the Arena forum (http://www.conitecserver.com/cgi-bin/ubbcgi/ultimatebb.cgi?ubb=forum;f=16; ).

Next time I will go into some more advanced features including ‘local’ variables and functions which makes customizing and debugging your robots easier. Until then, good hunting.