blob: a7947135e1b359b4244fbcd10effc5baefe60103 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001 LPC Basics
2 Written by Descartes of Borg
3 first edition: 23 april 1993
4 second edition: 12 july 1993
5
6CHAPTER 8: The data type "object"
7
88.1 Review
9You should now be able to do anything so long as you stick to calling
10functions within your own object. You should also know, that at the
11bare minimum you can get the create() (or reset()) function in your object
12called to start just by loading it into memory, and that your reset()
13function will be called every now and then so that you may write the
14code necessary to refresh your room. Note that neither of these
15functions MUST be in your object. The driver checks to see if the
16function exists in your object first. If it does not, then it does not
17bother. You are also acquainted with the data types void, int, and string.
18
197.2 Objects as data types
20In this chapter you will be acquainted with a more complex data type,
21object. An object variable points to a real object loaded into the
22driver's memory. You declare it in the same manner as other data types:
23 object ob;
24It differs in that you cannot use +, -, +=, -=, *, or / (what would it
25mean to divide a monster by another monster?). And since efuns like
26say() and write() only want strings or ints, you cannot write() or
27say() them (again, what would it mean to say a monster?).
28But you can use them with some other of the most important efuns on any
29LPMud.
30
318.3 The efun: this_object()
32This is an efun which returns an object in which the function being executed
33exists. In other words, in a file, this_object() refers to the object your
34file is in whether the file gets cloned itself or inherted by another file.
35It is often useful when you are writing a file which is getting inherited
36by another file. Say you are writing your own living.c which gets
37inherited by user.c and monster.c, but never used alone. You want to log
38the function set_level() it is a player's level being set (but you do not
39care if it is a monster.
40You might do this:
41
42void set_level(int x) {
43 if(this_object()->is_player()) log_file("levels", "foo\n");
44 level = x;
45}
46
47Since is_player() is not defined in living.c or anything it inherits,
48just saying if(is_player()) will result in an error since the driver
49does not find that function in your file or anything it inherits.
50this_object() allows you to access functions which may or may not be
51present in any final products because your file is inherited by others
52without resulting in an error.
53
548.4 Calling functions in other objects
55This of course introduces us to the most important characteristic of
56the object data type. It allows us to access functions in other objects.
57In previous examples you have been able to find out about a player's level,
58reduce the money they have, and how much hp they have.
59Calls to functions in other objects may be done in two ways:
60
61object->function(parameters)
62call_other(object, "function", parameters);
63
64example:
65this_player()->add_money("silver", -5);
66call_other(this_player(), "add_money", "silver", -5);
67
68In some (very loose sense), the game is just a chain reaction of function
69calls initiated by player commands. When a player initiates a chain of
70function calls, that player is the object which is returned by
71the efun this_player(). So, since this_player() can change depending
72on who initiated the sequence of events, you want to be very careful
73as to where you place calls to functions in this_player(). The most common
74place you do this is through the last important lfun (we have mentioned
75create() and reset()) init().
76
778.5 The lfun: init()
78Any time a living thing encounters an object (enters a new room, or enters
79the same room as a certain other object), init() is called in all of
80the objects the living being newly encounters. It is at this point
81that you can add commands the player can issue in order to act.
82Here is a sample init() function in a flower.
83
84void init() {
85 ::init();
86 add_action("smell_flower", "smell");
87}
88
89Ito smell_flower(). So you should have smell_flower() look like this:
90
911 int smell_flower(string str); /* action functions are type int */
922
933 int smell_flower(string str) {
944 if(str != "flower") return 0; /* it is not the flower being smelled */
955 write("You sniff the flower.\n");
966 say((string)this_player()->query_cap_name()+" smells the flower.\n");
977 this_player()->add_hp(random(5));
988 return 1;
999 }
100
101In line 1, we have our function declared.
102In line 3, smell_flower() begins. str becomes whatever comes after the
103 players command (not including the first white space).
104In line 4, it checks to see if the player had typed "smell flower". If
105 the player had typed "smell cheese", then str would be "cheese". If
106 it is not in fact "flower" which is being smelled, then 0 is returned,
107 letting the driver know that this was not the function which should
108 have been called. If in fact the player had a piece of cheese as well
109 which had a smell command to it, the driver would then call the function
110 for smelling in that object. The driver will keep calling all functions
111 tied to smell commands until one of them returns 1. If they all return
112 0, then the player sees "What?"
113In line 5, the efun write() is called. write() prints the string which
114 is passed to it to this_player(). So whoever typed the command here
115 sees "You sniff the flower."
116In line 6, the efun say() is called. say() prints the string which is
117 doing the sniffing, we have to call the query_cap_name() function
118 in this_player(). That way if the player is invis, it will say
119 "Someone" (or something like that), and it will also be properly
120 capitalized.
121In line 7, we call the add_hp() function in the this_player() object,
122 since we want to do a little healing for the sniff (Note: do not
123 code this object on your mud, whoever balances your mud will shoot you).
124In line 8, we return control of the game to the driver, returning 1 to
125 let it know that this was in fact the right function to call.
126
1278.6 Adding objects to your rooms
128And now, using the data type object, you can add monsters to your rooms:
129
130void create() {
131 ::create();
132 set_property("light", 3);
133 set("short", "Krasna Square");
134 set("long", "Welcome to the Central Square of the town of Praxis.\n");
135 set_exits( ({ "d/standard/hall" }), ({ "east" }) );
136}
137
138void reset() {
139 object ob;
140
141 ::reset();
142 if(present("guard")) return; /* Do not want to add a guard if */
143 ob = new("/std/monster"); /* one is already here */
144 ob->set_name("guard");
145 ob->set("id", ({ "guard", "town guard" }) );
146 ob->set("short", "Town guard");
147 ob->set("long", "He guards Praxis from nothingness.\n");
148 ob->set_gender("male");
149 ob->set_race("human");
150 ob->set_level(10);
151 ob->set_alignment(200);
152 ob->set_humanoid();
153 ob->set_hp(150);
154 ob->set_wielding_limbs( ({ "right hand", "left hand" }) );
155 ob->move(this_object());
156}
157
158Now, this will be wildly different on most muds. Some, as noted before,
159in that object so you have a uniquely configured monster object. The
160last act in native muds is to call move() in the monster object to move
161it to this room (this_object()). In compat muds, you call the efun
162move_object() which takes two parameters, the object to be moved, and the
163object into which it is being moved.
164
1658.7 Chapter summary
166At this point, you now have enough knowledge to code some really nice
167stuff. Of course, as I have been stressing all along, you really need
168to read the documents on building for your mud, as they detail which
169functions exist in which types of objects for you to call. No matter
170what your knowledge of the mudlib is, you have enough know-how to
171give a player extra things to do like sniffing flowers or glue or whatever.
172At this point you should get busy coding stuff. But the moment things
173even look to become tedious, that means it is time for you to move to
174the next level and do more. Right now code yourself a small area.
175Make extensive use of the special functions coded in your mud's
176room.c (search the docs for obscure ones no one else seems to use).
177Add lots o' neat actions. Create weapons which have magic powers which
178gradually fade away. All of this you should be able to do now. Once
179this becomes routine for you, it will be time to move on to intermediate
180stuff. Note that few people actually get to the intermediate stuff.
181If you have played at all, you notice there are few areas on the mud
182which do what I just told you you should be able to do. It is not
183because it is hard, but because there is a lot of arrogance out there
184on the part of people who have gotten beyond this point, and very little
185communicating of that knowledge. The trick is to push yourself and
186think of something you want to do that is impossible. If you ask someone
187in the know how to do X, and they say that is impossible, find out
188youself how to code it by experimenting.
189
190George Reese
191Descartes of Borg
19212 july 1993
193borg@hebron.connected.com
194Descartes@Nightmare (intermud)
195Descartes@Igor (not intermud)