Chapter 3. Creating a Command

In this chapter you will put all of the pieces together and create your first regular command. The first thing to realize when making a DIL command is that the dil command works the same as any dil copied onto a NPC or a PC. This means the 'self' Unitptr is availible to use in the command and will be set to the person that has activated the command. So if Papi typed the command 'jump' the self will be set to him.

We must now pick the command we are going to create. When this Manual was written the 'bury' command was still a part of the base code. This means that it can not be changed by a system admin. While the original can not be changed it can be replaced by a DIL command by just changing the define in the commands.def. If the command didn't already exist you would add it just by adding the command in the commands.def. The command we are going to write does exist so we will start with the old define, Example 3-1 and work from there.

Example 3-1. Original bury define

command  = bury
internal = bury
minpos   = POSITION_STANDING
minlevel = 0
loglevel = 0
type     = 0
turns    = 0

Examining Example 3-1 define will reveille that it uses the internal function bury. In order to convert this to a dil command we will need to change the line from 'internal' to 'func' and place our new DIL commands symbolic name in place of the internal function name. The new line will look as follows.

func = bury@commands
Your dil symbolic name may look different if you are testing your new command in another zone other than the 'commands' zone. After creating your define save it in the commands.def file and compile it. Once your commands.def has been compiled open the commands.zon and begin inputting your new command in the '%dil' section.

We will start buy creating a shell command structure so that we can point out a few things about the command. The example Example 3-2 is a working command. This means if you created a define and compiled the dil you could execute the command and it would work. While it works it does nothing. The important thing to learn from Example 3-2 is that you can use any name for the argument being passed to the command we use 'arg' in most of our examples just because the name makes it clear it is an argument you could use anything. The second thing you can learn from this example is you must have a 'quit' statement. If you do not put a quit statement the command will loop until the server deletes it.

Example 3-2. DIL command basic structure

dilbegin bury (what:string);
code
	{
	quit;
	}
dilend

Note: If you find when you log on it looks like your command is activating it is very possible you forgot to place a 'quit' instruction somewhere in your DIL .

The next step after making a shell dil structure is to actually create the heart of the command. The easiest way to start is by asking yourself questions about how you want the command to work the following are questions asked about the 'bury' command.

These are all questions we must answer when creating this command. The more you think about your command before creating it the less problems you will have when you sit down to write it. You might even want to do a design of the command before you even start writing it. In order to show you what we mean by designing the command before you write it we will give an example of a simple english like command design for the bury command in Example 3-3.

Example 3-3. Command Design

If the person gives no argument with the command.
	act no argument.
	quit.

If the person is not in position to do the command.
	act not in position.
	quit.

If the person is not in the right location for the command to work.
	act In bad room.
	quit.

If person types 'bury' with an argument.
	If argument not all.
		find item.
		If item can be buried.
			bury item.
			quit.

		If item can't be buried.
			act not buriable.
			quit.

	If argument is all.
		Loop through items in room.
			Bury item if it can be.
	End loop.
	quit

Now that we have a english like design it should be no work to convert it into a dil program. It is interesting to note that in Computer Science this english design is called Pseudo code. We of corse will not go into all the technical issues with pseudo code but if you want to learn more about it you can most likely research it on the internet. The basic idea of pseudo code is to allow you to design your program in an english like manor so that you can find logical problems before you even start coding the program. We will now take the pseudo code and our original DIL command structure we built earlier and convert the english to code the following dil in Example 3-4 is the result.

Example 3-4. Finished Command

dilbegin bury (arg:string);
var
	count:integer;
  item:unitptr;
code
  {
  count:=0;
  if (arg=="")
  	{
  	act ("Bury what?", A_ALWAYS,self,null,null,TO_CHAR);
  	quit;
  	}

	if (self.fighting!=null)
		{
  	act ("No Way! Your fighting for your life!", A_ALWAYS,self,null,null,TO_CHAR);
		quit;
		}

	if (self.outside.type!=UNIT_ST_ROOM)
		{
		act ("You can't bury stuff here.",A_ALWAYS,self,null,null,TO_CHAR);
		quit;
		}
	if (arg!="all")
		{
		item:=findunit (self,arg,FIND_UNIT_SURRO|FIND_UNIT_INVEN,null);
  	if ((item ==null) or
  		((item.outside!=self.outside) and
  		(item.outside!=self)) or
			(not (visible (self,item))))
			{
    	act ("Nothing like that here to bury.", A_ALWAYS,self,null,null,TO_CHAR);
    	quit;
    	}

		if (not(isset (item.manipulate,MANIPULATE_TAKE)))
			{
			act ("You can't bury that.",A_ALWAYS,self,null,null,TO_CHAR);
			quit;
			}
  	act ("$1n buries $3n.",A_SOMEONE,self,null,item,TO_REST);
  	act ("You bury $3n.",A_SOMEONE,self,null,item,TO_CHAR);
  	set (item.flags,UNIT_FL_BURIED);
  	link (item,self.outside);
  	quit;
  	}
	else
		{
	  foreach (UNIT_ST_OBJ,item)
	  	{
	    if (((item.outside!=self.outside) or
	      (item.outside==self)) or
	      (not (visible (self,item))))continue;
	  if (not(isset (item.manipulate,MANIPULATE_TAKE))) continue;
	  act ("$1n buries $3n.",A_SOMEONE,self,null,item,TO_REST);
	  act ("You bury $3n.",A_SOMEONE,self,null,item,TO_CHAR);
	  set (item.flags,UNIT_FL_BURIED);
	  link (item,self.outside);
	  count:=count+1;
	  }

	if (count==0) {
	    act ("Nothing here to bury.", A_ALWAYS,self,null,null,TO_CHAR);}
	  quit;
	  }

	quit;
	}
dilend

The command is now done. Now you need to compile the zone and reboot the VME. You should be able to log on and use your command. If the command doesn't work make sure both the command name and symbolic name are correct in the commands define and make sure the define file has been compiled. If your command still isn't working after that turn on your log and check if the dil command has an endless loop. If the dil has an endless loop it will delete itself and not activate. Endless loops are a good symptom of a missing quit statement or a loop that doesn't increment its index.

You should be able, with some imagination, to create just about any command you can think of. We have included the entire commands.zon so you can reference the commands that have already been created as examples for things you have yet to create. The file can be found in Appendix D.