Chapter 5. Creating an Attack skill

The task of creating an attack skill is really not much harder than creating a regular skill. If you haven't already read through the Chapter 4 then you should do so before continuing on. The main things we will add in this chapter is a new field in the skill define and a new step in creating the DIL TO figure in damage.

As we have done in the chapter on commands and regular skills we will first have to pick an attack skill to write. The kick skill seems to be a very good example of a attack skill so we will use it for our example. It really doesn't matter if you create the dil first or the define but we like to have the define done so that once the dil compiles we can reboot.

Example 5-1. Kick Define

index          = SKI_KICK
name           = kick
command        = kick
minpos         = POSITION_FIGHTING
turns          = PULSE_VIOLENCE/2
func           = kick@skills
race human     =   0
race elf       =  -1
race dwarf     =  -2
race halfling  =   0
race gnome     =   0
race half-orc  =   +1
race half-ogre =   0
race half-elf  =   0
race brownie   =  -1
race groll     =  +2
race darkelf   =   0

As you can see from Example 5-1, the define for kick, the first line has 'SKI_KICK' as the skills index value. This value is defined in the values.h When ever you create a skill you must add a value to the values.h that corresponds to your skill index. Next the name is what you want the skill to be known by for teachers and for the skills command. Finally we have set the kick skill to take up a half round of combat that way a person will have to decide wether she wants to kick or cast a spell. Notice also we have picked 'Half-Orc' and 'Groll' to be the races to learn the kick skill the easiest.

Note: This is a vein attempt to win back the Groll and Half-orc readers and make up for using them in our diagnose skill example.

Now you must add the define to the commands.def and compile it. If you haven't been reading this straight through you can find the information on compiling the defines in Chapter 2.

Now with the define written and compiled it is time to move on to designing and coding our skill. We will use the same method as we did in commands so we first need to start by asking ourselves some questions about how this command is going to work.

There could probably be more questions asked but the idea is to take time and think about what you want your skill to do before you start writing anything down. If you think better in your head than on paper these could all be questions floating around the Neural pathways.

After you have come up with not only the questions but the answers to the questions so that you think you know how you want the skill to work you should write out some Pseudo code so that your logic is clear before you start writing the skill.

Example 5-2. Kick Pseudo Code

if is  not skilled and is pc
 act not skilled
 if argument empty
   If is fighting
     opponent is target
 act who do you want to kick

if there is no target
  find target
  if no target or target not visible
   act no target

if target is not a PC or NPC
  act you can't kick it
	if target is kicker
	  act yeah right stupid

if kicker is PC and target is pc 
  check that person can kill other players if not act and quit
  if person is to tired 
    act your to tired

if person is not wielding anything give bonus to damage.

Do damage

With the pseudo code created it is a simple matter to convert the logic into code. The resulting conversion created the dil in Example 5-3.

Example 5-3. Kick DIL

dilbegin kick(arg : string);

   provoked_attack (victim : unitptr, ch : unitptr);

   bonus : integer;
   targ  : unitptr;

   if ((self.type == UNIT_ST_PC) and (self.weapons[WPN_KICK] <= 0))
      act("You must practice first.", A_ALWAYS, self, null, null, TO_CHAR);

   if (arg == "")
      if (self.fighting)
	 targ := self.fighting;
	 goto kick;

      act("Kick who?", A_SOMEONE, self, null, null, TO_CHAR);

   targ := findunit(self, arg, FIND_UNIT_SURRO, null);

   if ((targ == null) or not visible(self, targ))
      act("That person is not here!", A_SOMEONE, self, null, null, TO_CHAR);

   if (not (targ.type & (UNIT_ST_PC | UNIT_ST_NPC)))
      act("You can't kick that, silly!", A_SOMEONE, self, null, null,

   if (targ == self)
      act("You kick yourself.", A_HIDEINV, self, null, null,
      act("$1n kicks $1mself.", A_HIDEINV, self, null, null,

   if ((targ.type==UNIT_ST_PC) and
if (not(isset (self.pcflags, PC_PK_RELAXED)))
  act ("You are not allowed to do this unless you sign the book of blood.",

if (not(isset (targ.pcflags, PC_PK_RELAXED)))
  act ("You are not allowed to do this unless $2e signs the book of blood.",

   if (equipment(self, WEAR_WIELD))
     bonus := 0;
     bonus := rnd(1,(self.weapons[WPN_KICK] - 70));
     if(bonus <= 0) bonus := 1;
   if (self.endurance < 2)
     act("You are too exhausted to attempt that.", A_ALWAYS, self, null,
         null, TO_CHAR);
   else self.endurance := self.endurance - 2;
   provoked_attack (targ, self);
   bonus := meleeattack(self, targ, (bonus+self.level), WPN_KICK);

You may be asking why did we use the Melee attack function rather than creating our own damage. The melee attack function is explained in the DIL reference but in short the melee function takes into account the weapons and armours being used and does the correct amount of damage. While if we made our own damage function we would have to take into account the armour, position strength and everything that goes along with an attack. so as you can see this is much easier since if we didn't use it would take many more lines of code and much more debugging. This is not to say you can't do it the harder way it just means if you do there is a lot more you need to think about.

One more thing you may be wondering is what is the provoked attack function. This function causes your target to attack back. If you didn't have it in there you could just kick a person and they would do nothing automatically back.