-
Notifications
You must be signed in to change notification settings - Fork 0
/
create.c
336 lines (299 loc) · 8.44 KB
/
create.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
#include "copyright.h"
/* Commands that create new objects */
#include "db.h"
#include "config.h"
#include "interface.h"
#include "externs.h"
/* utility for open and link */
static dbref parse_linkable_room(dbref player, object_flag_type thing,
const char *room_name)
{
dbref room;
/* skip leading NUMBER_TOKEN if any */
if(*room_name == NUMBER_TOKEN) room_name++;
/* parse room */
if(!string_compare(room_name, "here")) {
room = db[player].location;
} else if(!string_compare(room_name, "home")) {
return HOME; /* HOME is always linkable */
} else {
room = parse_dbref(room_name);
}
/* check room */
if(room < 0 || room >= db_top
|| Typeof(room) != TYPE_ROOM) {
notify(player, "That's not a room!");
return NOTHING;
} else if(!can_link_to(player, thing, room)) {
notify(player, "You can't link to that.");
return NOTHING;
} else {
return room;
}
}
/* use this to create an exit */
void do_open(dbref player, const char *direction, const char *linkto)
{
dbref loc;
dbref exit;
#ifdef RESTRICTED_BUILDING
if(!Builder(player)) {
notify(player, "That command is restricted to authorized builders.");
return;
}
#endif /* RESTRICTED_BUILDING */
if((loc = getloc(player)) == NOTHING) return;
if(!*direction) {
notify(player, "Open where?");
return;
} else if(!ok_name(direction)) {
notify(player, "That's a strange name for an exit!");
return;
}
if(!controls(player, loc)) {
notify(player, "Permission denied.");
} else if(!payfor(player, EXIT_COST)) {
notify(player,
"Sorry, you don't have enough pennies to open an exit.");
} else {
/* create the exit */
exit = new_object();
/* initialize everything */
db[exit].name = alloc_string(direction);
db[exit].owner = player;
db[exit].flags = TYPE_EXIT;
/* link it in */
PUSH(exit, db[loc].exits);
/* and we're done */
notify(player, "Opened.");
/* check second arg to see if we should do a link */
if(*linkto != '\0') {
notify(player, "Trying to link...");
if((loc = parse_linkable_room(player, TYPE_EXIT, linkto)) !=
NOTHING) {
if(!payfor(player, LINK_COST)) {
notify(player, "You don't have enough pennies to link.");
} else {
/* it's ok, link it */
db[exit].location = loc;
notify(player, "Linked.");
}
}
}
}
}
/* use this to link to a room that you own */
/* it seizes ownership of the exit */
/* costs 1 penny */
/* plus a penny transferred to the exit owner if they aren't you */
/* you must own the linked-to room AND specify it by room number */
void do_link(dbref player, const char *name, const char *room_name)
{
dbref thing;
dbref room;
init_match(player, name, TYPE_EXIT);
match_exit();
match_neighbor();
match_possession();
match_me();
match_here();
if(Wizard(player)) {
match_absolute();
match_player();
}
if((thing = noisy_match_result()) != NOTHING) {
if((room = parse_linkable_room(player, Typeof(thing), room_name)) ==
NOTHING)
return;
switch(Typeof(thing)) {
case TYPE_EXIT:
/* we're ok, check the usual stuff */
if(db[thing].location != NOTHING) {
if(controls(player, thing)) {
/*
* Changed 5/18/90 Fuzzy - exits linked to *home*
* break 'Typeof() call'
*/
if(db[thing].location >= 0 &&
Typeof(db[thing].location) == TYPE_PLAYER) {
notify(player, "That exit is being carried.");
} else {
notify(player, "That exit is already linked.");
}
} else {
notify(player, "Permission denied.");
}
} else {
/* handle costs */
if(db[thing].owner == player) {
if(!payfor(player, LINK_COST)) {
notify(player,
"It costs a penny to link this exit.");
return;
}
} else {
if(!payfor(player, LINK_COST + EXIT_COST)) {
notify(player,
"It costs two pennies to link this exit.");
return;
#ifdef RESTRICTED_BUILDING
} else if(!Builder(player)) {
notify(player,
"Only authorized builders may seize exits.");
#endif /* RESTRICTED_BUILDING */
} else {
/* pay the owner for his loss */
db[db[thing].owner].pennies += EXIT_COST;
}
}
/* link has been validated and paid for; do it */
db[thing].owner = player;
db[thing].location = room;
/* notify the player */
notify(player, "Linked.");
}
break;
case TYPE_PLAYER:
case TYPE_THING:
if(!controls(player, thing)) {
notify(player, "Permission denied.");
} else if(room == HOME) {
notify(player, "Can't set home to home.");
} else {
/* do the link */
db[thing].exits = room; /* home */
notify(player, "Home set.");
}
break;
case TYPE_ROOM:
if(!controls(player, thing)) {
notify(player, "Permission denied.");
} else {
/* do the link, in location */
db[thing].location = room; /* dropto */
notify(player, "Dropto set.");
}
break;
default:
notify(player, "Internal error: weird object type.");
writelog("PANIC weird object: Typeof(%d) = %d\n",
thing, Typeof(thing));
break;
}
}
}
/* use this to create a room */
void do_dig(dbref player, const char *name)
{
dbref room;
char buf[BUFFER_LEN];
#ifdef RESTRICTED_BUILDING
if(!Builder(player)) {
notify(player, "That command is restricted to authorized builders.");
return;
}
#endif /* RESTRICTED_BUILDING */
/* we don't need to know player's location! hooray! */
if(*name == '\0') {
notify(player, "Dig what?");
} else if(!ok_name(name)) {
notify(player, "That's a silly name for a room!");
} else if(!payfor(player, ROOM_COST)) {
notify(player, "Sorry, you don't have enough pennies to dig a room.");
} else {
room = new_object();
/* Initialize everything */
db[room].name = alloc_string(name);
db[room].owner = player;
db[room].flags = TYPE_ROOM;
sprintf(buf, "%s created with room number %d.", name, room);
notify(player, buf);
}
}
/* use this to create an object */
void do_create(dbref player, char *name, int cost)
{
dbref loc;
dbref thing;
#ifdef RESTRICTED_BUILDING
if(!Builder(player)) {
notify(player, "That command is restricted to authorized builders.");
return;
}
#endif /* RESTRICTED_BUILDING */
if(*name == '\0') {
notify(player, "Create what?");
return;
} else if(!ok_name(name)) {
notify(player, "That's a silly name for a thing!");
return;
} else if(cost < 0) {
notify(player, "You can't create an object for less than nothing!");
return;
} else if(cost < OBJECT_COST) {
cost = OBJECT_COST;
}
if(!payfor(player, cost)) {
notify(player, "Sorry, you don't have enough pennies.");
} else {
/* create the object */
thing = new_object();
/* initialize everything */
db[thing].name = alloc_string(name);
db[thing].location = player;
db[thing].owner = player;
db[thing].pennies = OBJECT_ENDOWMENT(cost);
db[thing].flags = TYPE_THING;
/* endow the object */
if(db[thing].pennies > MAX_OBJECT_ENDOWMENT) {
db[thing].pennies = MAX_OBJECT_ENDOWMENT;
}
/* home is here (if we can link to it) or player's home */
if((loc = db[player].location) != NOTHING
&& controls(player, loc)) {
db[thing].exits = loc; /* home */
} else {
db[thing].exits = db[player].exits; /* home */
}
/* link it in */
PUSH(thing, db[player].contents);
/* and we're done */
notify(player, "Created.");
}
}
#ifdef REGISTRATION
void do_pcreate (dbref player, char *newplayer, char *newpass)
{
dbref ptmp;
#ifdef GOD_MODE && GOD_ONLY_PCREATE
if (!God(player))
#ifndef TINKER
notify (player, "Only GOD can create a new player.");
#else TINKER
notify (player, "Only the Master Tinker can create a new player.");
#endif TINKER
#else GOD_MODE && GOD_ONLY_PCREATE
if (!Wizard(player))
#ifndef TINKER
notify (player, "Only a Wizard can create a new player.");
#else TINKER
notify (player, "Only a Tinker can create a new player.");
#endif TINKER
#endif GOD_MODE && GOD_ONLY_PCREATE
else if (!*newplayer || !*newpass)
notify (player, "You must specify name and password.");
else {
ptmp = create_player (newplayer, newpass);
if (ptmp == NOTHING) {
notify(player, "Either there is already a player with that name, or that name is illegal.");
writelog("FAILED CREATE %s by %s\n",newplayer,db[player].name);
} else {
char buf[512];
sprintf(buf, "%s created as object #%d.",db[ptmp].name,ptmp);
notify(player, buf);
writelog("CREATED %s(%d) by %s\n",db[ptmp].name,ptmp,
db[player].name);
}
}
}
#endif REGISTRATION