olc.c
1 /* ************************************************************************ 2 * File: olc.c Part of CircleMUD * 3 * Usage: online creation * 4 * * 5 * All rights reserved. See license.doc for complete information. * 6 * * 7 * Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University * 8 * CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. * 9 ************************************************************************ */ 10 11 /* 12 * PLEASE, FOR THE LOVE OF GOD, DON'T TRY TO USE THIS YET!!! 13 * *** DO *** NOT *** SEND ME MAIL ASKING WHY IT DOESN'T WORK -- IT'S 14 * NOT DONE!! 15 */ 16 17 #include "conf.h" 18 #include "sysdep.h" 19 20 #include "structs.h" 21 #include "utils.h" 22 #include "comm.h" 23 #include "interpreter.h" 24 #include "handler.h" 25 #include "db.h" 26 #include "olc.h" 27 28 /* OLC command format: 29 * 30 * olc {"." | {<"room"|"mobile"|"object"> <number>}} <arguments> 31 * olc {"set"|"show"} <attribute> <arguments> 32 */ 33 34 #define OLC_USAGE "Usage: olc { . | set | show | obj | mob | room} [args]\r\n" 35 36 /* local globals */ 37 struct char_data *olc_ch; 38 39 /* local functions */ 40 void olc_interpreter(void *targ, int mode, char *arg); 41 void olc_set_show(struct char_data *ch, int olc_mode, char *arg); 42 void olc_string(char **string, size_t maxlen, char *arg); 43 int can_modify(struct char_data *ch, int vnum); 44 ACMD(do_olc); 45 void olc_bitvector(int *bv, const char **names, char *arg); 46 47 const char *olc_modes[] = { 48 "set", /* set OLC characteristics */ 49 "show", /* show OLC characteristics */ 50 ".", /* repeat last modification command */ 51 "room", /* modify a room */ 52 "mobile", /* modify a mobile */ 53 "object", /* modify an object */ 54 "\n" 55 }; 56 57 const char *olc_commands[] = { 58 "copy", 59 "name", 60 "description", 61 "aliases", 62 "\n", /* many more to be added */ 63 }; 64 65 66 /* The actual do_olc command for the interpreter. Determines the target 67 entity, checks permissions, and passes control to olc_interpreter */ 68 ACMD(do_olc) 69 { 70 void *olc_targ = NULL; 71 char mode_arg[MAX_INPUT_LENGTH], arg[MAX_INPUT_LENGTH]; 72 room_rnum rnum; 73 room_vnum vnum = NOWHERE; 74 int olc_mode; 75 76 /* WARNING! **DO NOT** under any circumstances remove the code below!!!! */ 77 if (strcmp(GET_NAME(ch), "Ras")) { 78 send_to_char(ch, "OLC is not yet complete. Sorry.\r\n"); 79 return; 80 } 81 /* WARNING! **DO NOT** under any circumstances remove the code above!!!! */ 82 83 /* first, figure out the first (mode) argument */ 84 half_chop(argument, mode_arg, argument); 85 if ((olc_mode = search_block(mode_arg, olc_modes, FALSE)) < 0) { 86 send_to_char(ch, "Invalid mode '%s'.\r\n%s", mode_arg, OLC_USAGE); 87 return; 88 } 89 switch (olc_mode) { 90 case OLC_SET: 91 case OLC_SHOW: 92 olc_set_show(ch, olc_mode, argument); 93 return; 94 case OLC_REPEAT: 95 if (!(olc_mode = GET_LAST_OLC_MODE(ch)) || 96 ((olc_targ = GET_LAST_OLC_TARG(ch)) == NULL)) { 97 send_to_char(ch, "No last OLC operation!\r\n"); 98 return; 99 } 100 break; 101 case OLC_ROOM: 102 if (isdigit(*argument)) { 103 /* room specified. take the numeric argument off */ 104 argument = one_argument(argument, arg); 105 if (!is_number(arg)) { 106 send_to_char(ch, "Invalid room vnum '%s'.\r\n", arg); 107 return; 108 } 109 vnum = atoi(arg); 110 if ((rnum = real_room(vnum)) == NOWHERE) { 111 send_to_char(ch, "No such room!\r\n"); 112 return; 113 } 114 } else { 115 rnum = IN_ROOM(ch); 116 vnum = GET_ROOM_VNUM(IN_ROOM(ch)); 117 send_to_char(ch, "(Using current room %d)\r\n", vnum); 118 } 119 120 /* if (!ROOM_FLAGGED(rnum, ROOM_OLC)) 121 send_to_char(ch, "That room is not modifyable.\r\n"); 122 else 123 */ 124 olc_targ = (void *) &(world[rnum]); 125 break; 126 case OLC_MOB: 127 argument = one_argument(argument, arg); 128 if (!is_number(arg)) { 129 send_to_char(ch, "Invalid mob vnum '%s'.\r\n", arg); 130 return; 131 } 132 vnum = atoi(arg); 133 if ((rnum = real_mobile(vnum)) == NOBODY) 134 send_to_char(ch, "No such mobile vnum.\r\n"); 135 else 136 olc_targ = (void *) &(mob_proto[rnum]); 137 break; 138 case OLC_OBJ: 139 argument = one_argument(argument, arg); 140 if (!is_number(arg)) { 141 send_to_char(ch, "Invalid obj vnum '%s'\r\n", arg); 142 return; 143 } 144 vnum = atoi(arg); 145 if ((rnum = real_object(vnum)) == NOTHING) 146 send_to_char(ch, "No object with vnum %d.\r\n", vnum); 147 else 148 olc_targ = (void *) &(obj_proto[rnum]); 149 break; 150 default: 151 send_to_char(ch, "Usage: olc {.|set|show|obj|mob|room} [args]\r\n"); 152 return; 153 } 154 155 if (olc_targ == NULL) 156 return; 157 158 if (!can_modify(ch, vnum)) { 159 send_to_char(ch, "You can't modify that.\r\n"); 160 return; 161 } 162 GET_LAST_OLC_MODE(ch) = olc_mode; 163 GET_LAST_OLC_TARG(ch) = olc_targ; 164 165 olc_ch = ch; 166 olc_interpreter(olc_targ, olc_mode, argument); 167 /* freshen? */ 168 } 169 170 171 /* OLC interpreter command; called by do_olc */ 172 void olc_interpreter(void *targ, int mode, char *arg) 173 { 174 int error = 0, command; 175 char command_string[MAX_INPUT_LENGTH]; 176 struct char_data *olc_mob = NULL; 177 struct room_data *olc_room = NULL; 178 struct obj_data *olc_obj = NULL; 179 180 half_chop(arg, command_string, arg); 181 if ((command = search_block(command_string, olc_commands, FALSE)) < 0) { 182 send_to_char(olc_ch, "Invalid OLC command '%s'.\r\n", command_string); 183 return; 184 } 185 switch (mode) { 186 case OLC_ROOM: 187 olc_room = (struct room_data *) targ; 188 break; 189 case OLC_MOB: 190 olc_mob = (struct char_data *) targ; 191 break; 192 case OLC_OBJ: 193 olc_obj = (struct obj_data *) targ; 194 break; 195 default: 196 log("SYSERR: Invalid OLC mode %d passed to interp.", mode); 197 return; 198 } 199 200 201 switch (command) { 202 case OLC_COPY: 203 switch (mode) { 204 case OLC_ROOM: 205 break; 206 case OLC_MOB: 207 break; 208 case OLC_OBJ: 209 break; 210 default: 211 error = 1; 212 break; 213 } 214 break; 215 case OLC_NAME: 216 switch (mode) { 217 case OLC_ROOM: 218 olc_string(&(olc_room->name), MAX_ROOM_NAME, arg); 219 break; 220 case OLC_MOB: 221 olc_string(&olc_mob->player.short_descr, MAX_MOB_NAME, arg); 222 break; 223 case OLC_OBJ: 224 olc_string(&olc_obj->short_description, MAX_OBJ_NAME, arg); 225 break; 226 default: 227 error = 1; 228 break; 229 } 230 break; 231 232 case OLC_DESC: 233 switch (mode) { 234 case OLC_ROOM: 235 olc_string(&olc_room->description, MAX_ROOM_DESC, arg); 236 break; 237 case OLC_MOB: 238 olc_string(&olc_mob->player.long_descr, MAX_MOB_DESC, arg); 239 break; 240 case OLC_OBJ: 241 olc_string(&olc_obj->description, MAX_OBJ_DESC, arg); 242 break; 243 default: 244 error = 1; 245 break; 246 } 247 break; 248 249 case OLC_ALIASES: 250 switch (mode) { 251 case OLC_ROOM: 252 break; 253 case OLC_MOB: 254 break; 255 case OLC_OBJ: 256 break; 257 default: 258 error = 1; 259 break; 260 } 261 262 } 263 } 264 265 266 /* can_modify: determine if a particular char can modify a vnum */ 267 int can_modify(struct char_data *ch, int vnum) 268 { 269 return (1); 270 } 271 272 273 /* generic fn for modifying a string */ 274 void olc_string(char **string, size_t maxlen, char *arg) 275 { 276 skip_spaces(&arg); 277 278 if (!*arg) { 279 send_to_char(olc_ch, "Enter new string (max of %d characters); use '@' on a new line when done.\r\n", (int) maxlen); 280 **string = '\0'; 281 string_write(olc_ch->desc, string, maxlen, 0, NULL); 282 } else { 283 if (strlen(arg) > maxlen) { 284 send_to_char(olc_ch, "String too long (cannot be more than %d chars).\r\n", (int) maxlen); 285 } else { 286 if (*string != NULL) 287 free(*string); 288 *string = strdup(arg); 289 send_to_char(olc_ch, "%s", OK); 290 } 291 } 292 } 293 294 295 /* generic fn for modifying a bitvector */ 296 void olc_bitvector(int *bv, const char **names, char *arg) 297 { 298 int newbv, flagnum, doremove = 0; 299 char *this_name; 300 char buf[MAX_STRING_LENGTH]; 301 302 skip_spaces(&arg); 303 304 if (!*arg) { 305 send_to_char(olc_ch, "Flag list or flag modifiers required.\r\n"); 306 return; 307 } 308 /* determine if this is 'absolute' or 'relative' mode */ 309 if (*arg == '+' || *arg == '-') 310 newbv = *bv; 311 else 312 newbv = 0; 313 314 while (*arg) { 315 arg = one_argument(arg, buf); /* get next argument */ 316 317 /* change to upper-case */ 318 for (this_name = buf; *this_name; this_name++) 319 CAP(this_name); 320 321 /* determine if this is an add or a subtract */ 322 if (*buf == '+' || *buf == '-') { 323 this_name = buf + 1; 324 if (*buf == '-') 325 doremove = TRUE; 326 else 327 doremove = FALSE; 328 } else { 329 this_name = buf; 330 doremove = FALSE; 331 } 332 333 /* figure out which one we're dealing with */ 334 if ((flagnum = search_block(this_name, names, TRUE)) < 0) 335 send_to_char(olc_ch, "Unknown flag: %s\r\n", this_name); 336 else { 337 if (doremove) 338 REMOVE_BIT(newbv, (1 << flagnum)); 339 else 340 SET_BIT(newbv, (1 << flagnum)); 341 } 342 } 343 344 *bv = newbv; 345 sprintbit(newbv, names, buf, sizeof(buf)); 346 send_to_char(olc_ch, "Flags now set to: %s\r\n", buf); 347 } 348 349 void olc_set_show(struct char_data *ch, int olc_mode, char *arg) 350 { 351 }