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 type = TYPE_SKILL 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.
What if the person doesn't have Diagnose skill?
What if argument given is empty?
What if argument is not a character?
Does skill work different in combat?
How will the skill do its check?
What skill and ability will be used for the skill for both success and defense
What happens if the skill fails
Do we show the percentage or a textual representation of the health of the character being diagnosed?
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 quit if argument empty If is fighting opponent is target else act who do you want to kick quit if there is no target find target if no target or target not visible act no target quit if target is not a PC or NPC act you can't kick it quit if target is kicker act yeah right stupid quit 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 quit if person is not wielding anything give bonus to damage. Do damage quit
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); external provoked_attack (victim : unitptr, ch : unitptr); var bonus : integer; targ : unitptr; code { if ((self.type == UNIT_ST_PC) and (self.weapons[WPN_KICK] <= 0)) { act("You must practice first.", A_ALWAYS, self, null, null, TO_CHAR); quit; } if (arg == "") { if (self.fighting) { targ := self.fighting; goto kick; } act("Kick who?", A_SOMEONE, self, null, null, TO_CHAR); quit; } 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); quit; } if (not (targ.type & (UNIT_ST_PC | UNIT_ST_NPC))) { act("You can't kick that, silly!", A_SOMEONE, self, null, null, TO_CHAR); quit; } if (targ == self) { act("You kick yourself.", A_HIDEINV, self, null, null, TO_CHAR); act("$1n kicks $1mself.", A_HIDEINV, self, null, null, TO_ROOM); quit; } if ((targ.type==UNIT_ST_PC) and (self.type==UNIT_ST_PC)) { if (not(isset (self.pcflags, PC_PK_RELAXED))) { act ("You are not allowed to do this unless you sign the book of blood.", A_ALWAYS,self,null,null,TO_CHAR); quit; } if (not(isset (targ.pcflags, PC_PK_RELAXED))) { act ("You are not allowed to do this unless $2e signs the book of blood.", A_ALWAYS,self,targ,null,TO_CHAR); quit; } } :kick: if (equipment(self, WEAR_WIELD)) bonus := 0; else { 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); quit; } dilend
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.