/ circle3.1 / src / olc.c
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  }