-=[ LPC Basics ]=-
directives (preprocessors):
LPC allows most of the ANSI preprocessor controls. Since
this is only a light brush of LPC, I will deal only with
the directives, #define, #undef, and #include. I will
leave an explanation of conditional directives later.
#define:
The #define directive allows you to do a macro
substitution. The directive defines an identifier, that
substitutes a string when encountered in the source
file.
Example:
#define query_name() QN
will substitute 'query_name()' whenever 'QN' is found in
your code. #define can used more powerfully as a psuedo-
function,
#define PAY(XXX) this_player()->add_money(-XXX)
if PAY(20) was called then, 20 coins would be deducted
from this_player().
The macro does not have to be only one line,
#define MOVE_OBJ(NN,FF) if(!present(NN,this_object())) {\
move_object(clone_object(FF),this_object());\
}
However, you must be careful using pseudo-functions. They
are not very leanient.
For example,
MOVE_OBJ("bob","players/zilanthius/monsters/bob");
would work fine. But,
MOVE_OBJ( "bob", path+"/monsters/bob");
would not work. One because of the spaces, and two
because of the 'path+'.
#undef:
#undef un-defines a macro. Why have this? There are times
when you do not want a particular macro defined, that was
carried through with an #include "file".
example: cloning a bag into a room using room.h
#include "/include/room.h"
#undef EXTRA_RESET
#define EXTRA_RESET if(!present("bag,this_object())) {\
move_object(clone_object("objects/bag"),this_object());\
}
#include:
The #include directive instructs the compiler to read
another file for 'library' routines. In effect it adds
the file to the 'head' file to the top of your
object.'file.h' files are known as "header" files for
this reason.
#include "/include/array.h"
Will instruct the compiler to put /include/array.h at the
head of the file. For example the function,
write_file_array(filename,your_array);
can be used if array.h is included. (write_file_array()
writes an array of strings, or ints line by line into
filename).
Some wizards make a "path.h" header file for directory
paths.
Eg. "path.h"
#define PATH "/players/zilanthius/"
#define OBJ "/players/zilanthius/obj/"
#define MONSTER "/players/zilanthius/monsters/"
#define WEAPON "/players/zilanthius/weapons/"
etc.
inherit:
I don't have a clear concept of the hows and whys of
inheritance. But I will have a go at explaining it. So
please forgive any misconceptions.
Inherit says that this new object is the same as an old one,
plus some modifications. It is useful because it conserves
coding effort. It is already debugged. Secondly, it has all
the standard criteria that other objects expect to see in
another object for the mud to run smoothly.
Since Lpc is object orientated, objects already have a
series of hard-coded functions that can be applied to
that object. For example, file_name(ob). However, lpc
allows you to "soft-coded" functions available in that
object. When then object is loaded, these soft-coded
functions are loaded into memory. For example, short().
This is fine when you have one object, but if you make
unique objects for everything, then the machines memory
is going to be filled with objects; objects must contain
an objects global variables, and the soft-coded functions
to manipulate those variables. But if you look at those
soft-coded functions, most mirror each other. It is only
the abstract variables in the functions that change.
So inheritance allows you to cut down memory usage, by
loading only one copy of the soft-coded function into
memory and using that function as a mirror.
Cloning an object seems to do the same thing, except,
that it is exact copy rather, than a manipulation of a
mirror.
The main point is that using the configurable objects
(bag, armour, weapons, monster, etc) saves mud memory,
and also gives the overall mud a general consistency.