/
oasis.c
executable file
·343 lines (296 loc) · 9.42 KB
/
oasis.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
337
338
339
340
341
342
/**************************************************************************
* File: oasis.c Part of tbaMUD *
* Usage: Oasis - General. *
* *
* By Levork. Copyright 1996 Harvey Gilpin. 1997-2001 George Greer. *
**************************************************************************/
#include "conf.h"
#include "sysdep.h"
#include "structs.h"
#include "utils.h"
#include "interpreter.h"
#include "comm.h"
#include "db.h"
#include "shop.h"
#include "genolc.h"
#include "genmob.h"
#include "genshp.h"
#include "genzon.h"
#include "genwld.h"
#include "genobj.h"
#include "oasis.h"
#include "screen.h"
#include "dg_olc.h"
#include "act.h"
#include "handler.h" /* for is_name */
#include "quest.h"
#include "ibt.h"
#include "msgedit.h"
/* Internal Data Structures */
/** @deprecated olc_scmd_info appears to be deprecated. Commented out for now.
static struct olc_scmd_info_t {
const char *text;
int con_type;
} olc_scmd_info[] = {
{ "room", CON_REDIT },
{ "object", CON_OEDIT },
{ "zone", CON_ZEDIT },
{ "mobile", CON_MEDIT },
{ "shop", CON_SEDIT },
{ "config", CON_CEDIT },
{ "trigger", CON_TRIGEDIT },
{ "action", CON_AEDIT },
* { "guild", CON_GEDIT },
{ "help", CON_HEDIT },
{ "quest", CON_QEDIT },
{ "\n", -1 }
};
*/
/* Global variables defined here, used elsewhere */
const char *nrm, *grn, *cyn, *yel;
/* Internal Function prototypes */
static void free_config(struct config_data *data);
/* Only player characters should be using OLC anyway. */
void clear_screen(struct descriptor_data *d)
{
if (PRF_FLAGGED(d->character, PRF_CLS))
write_to_output(d, "[H[J");
}
/* Exported utilities */
/* Set the color string pointers for that which this char will see at color
* level NRM. Changing the entries here will change the colour scheme
* throughout the OLC. */
void get_char_colors(struct char_data *ch)
{
nrm = CCNRM(ch, C_NRM);
grn = CCGRN(ch, C_NRM);
cyn = CCCYN(ch, C_NRM);
yel = CCYEL(ch, C_NRM);
}
/* This procedure frees up the strings and/or the structures attatched to a
* descriptor, sets all flags back to how they should be. */
void cleanup_olc(struct descriptor_data *d, byte cleanup_type)
{
/* Clean up WHAT? */
if (d->olc == NULL)
return;
/* Check for a room. free_room doesn't perform sanity checks, we must be
* careful here. */
if (OLC_ROOM(d)) {
switch (cleanup_type) {
case CLEANUP_ALL:
/* free(OLC_SCRIPT(d)) equivalent */
free_proto_script(OLC_ROOM(d), WLD_TRIGGER);
free_room(OLC_ROOM(d));
break;
case CLEANUP_STRUCTS:
free(OLC_ROOM(d));
break;
case CLEANUP_CONFIG:
free_config(OLC_CONFIG(d));
break;
default: /* The caller has screwed up. */
log("SYSERR: cleanup_olc: Unknown type!");
break;
}
}
/* Check for an existing object in the OLC. The strings aren't part of the
* prototype any longer. They get added with strdup(). */
if (OLC_OBJ(d)) {
free_object_strings(OLC_OBJ(d));
free(OLC_OBJ(d));
}
/* Check for a mob. free_mobile() makes sure strings are not in the
* prototype. */
if (OLC_MOB(d))
free_mobile(OLC_MOB(d));
/* Check for a zone. cleanup_type is irrelevant here, free() everything. */
if (OLC_ZONE(d)) {
if (OLC_ZONE(d)->builders)
free(OLC_ZONE(d)->builders);
if (OLC_ZONE(d)->name)
free(OLC_ZONE(d)->name);
if (OLC_ZONE(d)->cmd)
free(OLC_ZONE(d)->cmd);
free(OLC_ZONE(d));
}
/* Check for a shop. free_shop doesn't perform sanity checks, we must be
* careful here. OLC_SHOP(d) is a _copy_ - no pointers to the original. Just
* go ahead and free it all. */
if (OLC_SHOP(d))
free_shop(OLC_SHOP(d));
/* Check for a quest. */
if (OLC_QUEST(d)) {
switch (cleanup_type) {
case CLEANUP_ALL:
free_quest(OLC_QUEST(d));
break;
case CLEANUP_STRUCTS:
free(OLC_QUEST(d));
break;
default:
break;
}
}
/*. Check for a guild . */
if (OLC_GUILD(d)) {
switch (cleanup_type) {
case CLEANUP_ALL:
free_guild(OLC_GUILD(d));
break;
case CLEANUP_STRUCTS:
free(OLC_GUILD(d));
break;
default:
break;
}
}
/*. Check for aedit stuff -- M. Scott */
if (OLC_ACTION(d)) {
switch(cleanup_type) {
case CLEANUP_ALL:
free_action(OLC_ACTION(d));
break;
case CLEANUP_STRUCTS:
free(OLC_ACTION(d));
break;
default:
/* Caller has screwed up */
break;
}
}
/* Used for cleanup of Hedit */
if (OLC_HELP(d)) {
switch(cleanup_type) {
case CLEANUP_ALL:
free_help(OLC_HELP(d));
break;
case CLEANUP_STRUCTS:
free(OLC_HELP(d));
break;
default:
break;
}
}
if (OLC_IBT(d)) {
free_olc_ibt(OLC_IBT(d));
OLC_IBT(d) = NULL;
}
if (OLC_MSG_LIST(d)) {
free_message_list(OLC_MSG_LIST(d));
OLC_MSG_LIST(d) = NULL;
OLC_MSG(d) = NULL;
}
/* Free storage if allocated (tedit, aedit, and trigedit). This is the command
* list - it's been copied to disk already, so just free it -Welcor. */
if (OLC_STORAGE(d)) {
free(OLC_STORAGE(d));
OLC_STORAGE(d) = NULL;
}
/* Free this one regardless. If we've left olc, we've either made a fresh
* copy of it in the trig index, or we lost connection. Either way, we need
* to get rid of this. */
if (OLC_TRIG(d)) {
free_trigger(OLC_TRIG(d));
OLC_TRIG(d) = NULL;
}
/* Free this one regardless. If we've left olc, we've either copied the *
* preferences to the player, or we lost connection. Either way, we need *
* to get rid of this. */
if(OLC_PREFS(d)) {
/*. There is nothing else really to free, except this... .*/
free(OLC_PREFS(d));
OLC_PREFS(d) = NULL;
}
/* OLC_SCRIPT is always set as trig_proto of OLC_OBJ/MOB/ROOM. Therefore it
* should not be free'd here. */
/* Restore descriptor playing status. */
if (d->character) {
REMOVE_BIT_AR(PLR_FLAGS(d->character), PLR_WRITING);
act("$n stops using OLC.", TRUE, d->character, NULL, NULL, TO_ROOM);
if (cleanup_type == CLEANUP_CONFIG)
mudlog(BRF, ADMLVL_IMMORT, TRUE, "OLC: %s stops editing the game configuration", GET_NAME(d->character));
else if (STATE(d) == CON_TEDIT)
mudlog(BRF, ADMLVL_IMMORT, TRUE, "OLC: %s stops editing text files.", GET_NAME(d->character));
else if (STATE(d) == CON_HEDIT)
mudlog(CMP, ADMLVL_IMMORT, TRUE, "OLC: %s stops editing help files.", GET_NAME(d->character));
else
mudlog(CMP, ADMLVL_IMMORT, TRUE, "OLC: %s stops editing zone %d allowed zone %d", GET_NAME(d->character), zone_table[OLC_ZNUM(d)].number, GET_OLC_ZONE(d->character));
STATE(d) = CON_PLAYING;
}
free(d->olc);
d->olc = NULL;
}
void split_argument(char *argument, char *tag)
{
char *tmp = argument, *ttag = tag, *wrt = argument;
int i;
for (i = 0; *tmp; tmp++, i++) {
if (*tmp != ' ' && *tmp != '=')
*(ttag++) = *tmp;
else if (*tmp == '=')
break;
}
*ttag = '\0';
while (*tmp == '=' || *tmp == ' ')
tmp++;
while (*tmp)
*(wrt++) = *(tmp++);
*wrt = '\0';
}
static void free_config(struct config_data *data)
{
/* Free strings. */
free_strings(data, OASIS_CFG);
/* Free the data structure. */
free(data);
}
/* Checks to see if a builder can modify the specified zone. Ch is the imm
* requesting access to modify this zone. Rnum is the real number of the zone
* attempted to be modified. Returns TRUE if the builder has access, otherwisei
* FALSE. */
int can_edit_zone(struct char_data *ch, zone_rnum rnum)
{
/* no access if called with bad arguments */
if (!ch->desc || IS_NPC(ch) || rnum == NOWHERE)
return FALSE;
/* If zone is flagged NOBUILD, then No-one can edit it (use zunlock to open it) */
if (rnum != HEDIT_PERMISSION && rnum != AEDIT_PERMISSION && ZONE_FLAGGED(rnum, ZONE_NOBUILD) )
return FALSE;
if (GET_OLC_ZONE(ch) == ALL_PERMISSION)
return TRUE;
if (GET_OLC_ZONE(ch) == HEDIT_PERMISSION && rnum == HEDIT_PERMISSION)
return TRUE;
if (GET_OLC_ZONE(ch) == AEDIT_PERMISSION && rnum == AEDIT_PERMISSION)
return TRUE;
/* always access if ch is high enough level */
if (GET_ADMLEVEL(ch) >= ADMLVL_GRGOD)
return (TRUE);
/* always access if a player helped build the zone in the first place */
if (rnum != HEDIT_PERMISSION && rnum != AEDIT_PERMISSION)
if (is_name(GET_NAME(ch), zone_table[rnum].builders))
return (TRUE);
/* no access if you haven't been assigned a zone */
if (GET_OLC_ZONE(ch) == NOWHERE) {
return FALSE;
}
/* no access if you're not at least LVL_BUILDER */
if (GET_ADMLEVEL(ch) < ADMLVL_BUILDER)
return FALSE;
/* always access if you're assigned to this zone */
if (real_zone(GET_OLC_ZONE(ch)) == rnum)
return TRUE;
return (FALSE);
}
void send_cannot_edit(struct char_data *ch, zone_vnum zone)
{
char buf[MAX_STRING_LENGTH];
if (GET_OLC_ZONE(ch) != NOWHERE) {
send_to_char(ch, "You do not have permission to edit zone %d. Try zone %d.\r\n", zone, GET_OLC_ZONE(ch));
sprintf(buf, "OLC: %s tried to edit zone %d (allowed zone %d).", GET_NAME(ch), zone, GET_OLC_ZONE(ch));
} else {
send_to_char(ch, "You do not have permission to edit zone %d.\r\n", zone);
sprintf(buf, "OLC: %s tried to edit zone %d.", GET_NAME(ch), zone);
}
mudlog(BRF, ADMLVL_IMPL, TRUE, "%s", buf);
}