/ circle3.1 / src / act.other.c
act.other.c
  1  /* ************************************************************************
  2  *   File: act.other.c                                   Part of CircleMUD *
  3  *  Usage: Miscellaneous player-level commands                             *
  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  #define __ACT_OTHER_C__
 12  
 13  #include "conf.h"
 14  #include "sysdep.h"
 15  
 16  #include "structs.h"
 17  #include "utils.h"
 18  #include "comm.h"
 19  #include "interpreter.h"
 20  #include "handler.h"
 21  #include "db.h"
 22  #include "spells.h"
 23  #include "screen.h"
 24  #include "house.h"
 25  #include "constants.h"
 26  
 27  /* extern variables */
 28  extern struct spell_info_type spell_info[];
 29  extern const char *class_abbrevs[];
 30  extern int free_rent;
 31  extern int pt_allowed;
 32  extern int max_filesize;
 33  extern int nameserver_is_slow;
 34  extern int auto_save;
 35  extern int track_through_doors;
 36  
 37  /* extern procedures */
 38  void list_skills(struct char_data *ch);
 39  void appear(struct char_data *ch);
 40  void write_aliases(struct char_data *ch);
 41  void perform_immort_vis(struct char_data *ch);
 42  SPECIAL(shop_keeper);
 43  ACMD(do_gen_comm);
 44  void die(struct char_data *ch);
 45  void Crash_rentsave(struct char_data *ch, int cost);
 46  
 47  /* local functions */
 48  ACMD(do_quit);
 49  ACMD(do_save);
 50  ACMD(do_not_here);
 51  ACMD(do_sneak);
 52  ACMD(do_hide);
 53  ACMD(do_steal);
 54  ACMD(do_practice);
 55  ACMD(do_visible);
 56  ACMD(do_title);
 57  int perform_group(struct char_data *ch, struct char_data *vict);
 58  void print_group(struct char_data *ch);
 59  ACMD(do_group);
 60  ACMD(do_ungroup);
 61  ACMD(do_report);
 62  ACMD(do_split);
 63  ACMD(do_use);
 64  ACMD(do_wimpy);
 65  ACMD(do_display);
 66  ACMD(do_gen_write);
 67  ACMD(do_gen_tog);
 68  
 69  
 70  ACMD(do_quit)
 71  {
 72    if (IS_NPC(ch) || !ch->desc)
 73      return;
 74  
 75    if (subcmd != SCMD_QUIT && GET_LEVEL(ch) < LVL_IMMORT)
 76      send_to_char(ch, "You have to type quit--no less, to quit!\r\n");
 77    else if (GET_POS(ch) == POS_FIGHTING)
 78      send_to_char(ch, "No way!  You're fighting for your life!\r\n");
 79    else if (GET_POS(ch) < POS_STUNNED) {
 80      send_to_char(ch, "You die before your time...\r\n");
 81      die(ch);
 82    } else {
 83      act("$n has left the game.", TRUE, ch, 0, 0, TO_ROOM);
 84      mudlog(NRM, MAX(LVL_IMMORT, GET_INVIS_LEV(ch)), TRUE, "%s has quit the game.", GET_NAME(ch));
 85      send_to_char(ch, "Goodbye, friend.. Come back soon!\r\n");
 86  
 87      /*  We used to check here for duping attempts, but we may as well
 88       *  do it right in extract_char(), since there is no check if a
 89       *  player rents out and it can leave them in an equally screwy
 90       *  situation.
 91       */
 92  
 93      if (free_rent)
 94        Crash_rentsave(ch, 0);
 95  
 96      /* If someone is quitting in their house, let them load back here. */
 97      if (!PLR_FLAGGED(ch, PLR_LOADROOM) && ROOM_FLAGGED(IN_ROOM(ch), ROOM_HOUSE))
 98        GET_LOADROOM(ch) = GET_ROOM_VNUM(IN_ROOM(ch));
 99  
100      extract_char(ch);		/* Char is saved before extracting. */
101    }
102  }
103  
104  
105  
106  ACMD(do_save)
107  {
108    if (IS_NPC(ch) || !ch->desc)
109      return;
110  
111    /* Only tell the char we're saving if they actually typed "save" */
112    if (cmd) {
113      /*
114       * This prevents item duplication by two PC's using coordinated saves
115       * (or one PC with a house) and system crashes. Note that houses are
116       * still automatically saved without this enabled. This code assumes
117       * that guest immortals aren't trustworthy. If you've disabled guest
118       * immortal advances from mortality, you may want < instead of <=.
119       */
120      if (auto_save && GET_LEVEL(ch) <= LVL_IMMORT) {
121        send_to_char(ch, "Saving aliases.\r\n");
122        write_aliases(ch);
123        return;
124      }
125      send_to_char(ch, "Saving %s and aliases.\r\n", GET_NAME(ch));
126    }
127  
128    write_aliases(ch);
129    save_char(ch);
130    Crash_crashsave(ch);
131    if (ROOM_FLAGGED(IN_ROOM(ch), ROOM_HOUSE_CRASH))
132      House_crashsave(GET_ROOM_VNUM(IN_ROOM(ch)));
133  }
134  
135  
136  /* generic function for commands which are normally overridden by
137     special procedures - i.e., shop commands, mail commands, etc. */
138  ACMD(do_not_here)
139  {
140    send_to_char(ch, "Sorry, but you cannot do that here!\r\n");
141  }
142  
143  
144  
145  ACMD(do_sneak)
146  {
147    struct affected_type af;
148    byte percent;
149  
150    if (IS_NPC(ch) || !GET_SKILL(ch, SKILL_SNEAK)) {
151      send_to_char(ch, "You have no idea how to do that.\r\n");
152      return;
153    }
154    send_to_char(ch, "Okay, you'll try to move silently for a while.\r\n");
155    if (AFF_FLAGGED(ch, AFF_SNEAK))
156      affect_from_char(ch, SKILL_SNEAK);
157  
158    percent = rand_number(1, 101);	/* 101% is a complete failure */
159  
160    if (percent > GET_SKILL(ch, SKILL_SNEAK) + dex_app_skill[GET_DEX(ch)].sneak)
161      return;
162  
163    af.type = SKILL_SNEAK;
164    af.duration = GET_LEVEL(ch);
165    af.modifier = 0;
166    af.location = APPLY_NONE;
167    af.bitvector = AFF_SNEAK;
168    affect_to_char(ch, &af);
169  }
170  
171  
172  
173  ACMD(do_hide)
174  {
175    byte percent;
176  
177    if (IS_NPC(ch) || !GET_SKILL(ch, SKILL_HIDE)) {
178      send_to_char(ch, "You have no idea how to do that.\r\n");
179      return;
180    }
181  
182    send_to_char(ch, "You attempt to hide yourself.\r\n");
183  
184    if (AFF_FLAGGED(ch, AFF_HIDE))
185      REMOVE_BIT(AFF_FLAGS(ch), AFF_HIDE);
186  
187    percent = rand_number(1, 101);	/* 101% is a complete failure */
188  
189    if (percent > GET_SKILL(ch, SKILL_HIDE) + dex_app_skill[GET_DEX(ch)].hide)
190      return;
191  
192    SET_BIT(AFF_FLAGS(ch), AFF_HIDE);
193  }
194  
195  
196  
197  
198  ACMD(do_steal)
199  {
200    struct char_data *vict;
201    struct obj_data *obj;
202    char vict_name[MAX_INPUT_LENGTH], obj_name[MAX_INPUT_LENGTH];
203    int percent, gold, eq_pos, pcsteal = 0, ohoh = 0;
204  
205    if (IS_NPC(ch) || !GET_SKILL(ch, SKILL_STEAL)) {
206      send_to_char(ch, "You have no idea how to do that.\r\n");
207      return;
208    }
209    if (ROOM_FLAGGED(IN_ROOM(ch), ROOM_PEACEFUL)) {
210      send_to_char(ch, "This room just has such a peaceful, easy feeling...\r\n");
211      return;
212    }
213  
214    two_arguments(argument, obj_name, vict_name);
215  
216    if (!(vict = get_char_vis(ch, vict_name, NULL, FIND_CHAR_ROOM))) {
217      send_to_char(ch, "Steal what from who?\r\n");
218      return;
219    } else if (vict == ch) {
220      send_to_char(ch, "Come on now, that's rather stupid!\r\n");
221      return;
222    }
223  
224    /* 101% is a complete failure */
225    percent = rand_number(1, 101) - dex_app_skill[GET_DEX(ch)].p_pocket;
226  
227    if (GET_POS(vict) < POS_SLEEPING)
228      percent = -1;		/* ALWAYS SUCCESS, unless heavy object. */
229  
230    if (!pt_allowed && !IS_NPC(vict))
231      pcsteal = 1;
232  
233    if (!AWAKE(vict))	/* Easier to steal from sleeping people. */
234      percent -= 50;
235  
236    /* NO NO With Imp's and Shopkeepers, and if player thieving is not allowed */
237    if (GET_LEVEL(vict) >= LVL_IMMORT || pcsteal ||
238        GET_MOB_SPEC(vict) == shop_keeper)
239      percent = 101;		/* Failure */
240  
241    if (str_cmp(obj_name, "coins") && str_cmp(obj_name, "gold")) {
242  
243      if (!(obj = get_obj_in_list_vis(ch, obj_name, NULL, vict->carrying))) {
244  
245        for (eq_pos = 0; eq_pos < NUM_WEARS; eq_pos++)
246  	if (GET_EQ(vict, eq_pos) &&
247  	    (isname(obj_name, GET_EQ(vict, eq_pos)->name)) &&
248  	    CAN_SEE_OBJ(ch, GET_EQ(vict, eq_pos))) {
249  	  obj = GET_EQ(vict, eq_pos);
250  	  break;
251  	}
252        if (!obj) {
253  	act("$E hasn't got that item.", FALSE, ch, 0, vict, TO_CHAR);
254  	return;
255        } else {			/* It is equipment */
256  	if ((GET_POS(vict) > POS_STUNNED)) {
257  	  send_to_char(ch, "Steal the equipment now?  Impossible!\r\n");
258  	  return;
259  	} else {
260  	  act("You unequip $p and steal it.", FALSE, ch, obj, 0, TO_CHAR);
261  	  act("$n steals $p from $N.", FALSE, ch, obj, vict, TO_NOTVICT);
262  	  obj_to_char(unequip_char(vict, eq_pos), ch);
263  	}
264        }
265      } else {			/* obj found in inventory */
266  
267        percent += GET_OBJ_WEIGHT(obj);	/* Make heavy harder */
268  
269        if (percent > GET_SKILL(ch, SKILL_STEAL)) {
270  	ohoh = TRUE;
271  	send_to_char(ch, "Oops..\r\n");
272  	act("$n tried to steal something from you!", FALSE, ch, 0, vict, TO_VICT);
273  	act("$n tries to steal something from $N.", TRUE, ch, 0, vict, TO_NOTVICT);
274        } else {			/* Steal the item */
275  	if (IS_CARRYING_N(ch) + 1 < CAN_CARRY_N(ch)) {
276  	  if (IS_CARRYING_W(ch) + GET_OBJ_WEIGHT(obj) < CAN_CARRY_W(ch)) {
277  	    obj_from_char(obj);
278  	    obj_to_char(obj, ch);
279  	    send_to_char(ch, "Got it!\r\n");
280  	  }
281  	} else
282  	  send_to_char(ch, "You cannot carry that much.\r\n");
283        }
284      }
285    } else {			/* Steal some coins */
286      if (AWAKE(vict) && (percent > GET_SKILL(ch, SKILL_STEAL))) {
287        ohoh = TRUE;
288        send_to_char(ch, "Oops..\r\n");
289        act("You discover that $n has $s hands in your wallet.", FALSE, ch, 0, vict, TO_VICT);
290        act("$n tries to steal gold from $N.", TRUE, ch, 0, vict, TO_NOTVICT);
291      } else {
292        /* Steal some gold coins */
293        gold = (GET_GOLD(vict) * rand_number(1, 10)) / 100;
294        gold = MIN(1782, gold);
295        if (gold > 0) {
296  	GET_GOLD(ch) += gold;
297  	GET_GOLD(vict) -= gold;
298          if (gold > 1)
299  	  send_to_char(ch, "Bingo!  You got %d gold coins.\r\n", gold);
300  	else
301  	  send_to_char(ch, "You manage to swipe a solitary gold coin.\r\n");
302        } else {
303  	send_to_char(ch, "You couldn't get any gold...\r\n");
304        }
305      }
306    }
307  
308    if (ohoh && IS_NPC(vict) && AWAKE(vict))
309      hit(vict, ch, TYPE_UNDEFINED);
310  }
311  
312  
313  
314  ACMD(do_practice)
315  {
316    char arg[MAX_INPUT_LENGTH];
317  
318    if (IS_NPC(ch))
319      return;
320  
321    one_argument(argument, arg);
322  
323    if (*arg)
324      send_to_char(ch, "You can only practice skills in your guild.\r\n");
325    else
326      list_skills(ch);
327  }
328  
329  
330  
331  ACMD(do_visible)
332  {
333    if (GET_LEVEL(ch) >= LVL_IMMORT) {
334      perform_immort_vis(ch);
335      return;
336    }
337  
338    if AFF_FLAGGED(ch, AFF_INVISIBLE) {
339      appear(ch);
340      send_to_char(ch, "You break the spell of invisibility.\r\n");
341    } else
342      send_to_char(ch, "You are already visible.\r\n");
343  }
344  
345  
346  
347  ACMD(do_title)
348  {
349    skip_spaces(&argument);
350    delete_doubledollar(argument);
351  
352    if (IS_NPC(ch))
353      send_to_char(ch, "Your title is fine... go away.\r\n");
354    else if (PLR_FLAGGED(ch, PLR_NOTITLE))
355      send_to_char(ch, "You can't title yourself -- you shouldn't have abused it!\r\n");
356    else if (strstr(argument, "(") || strstr(argument, ")"))
357      send_to_char(ch, "Titles can't contain the ( or ) characters.\r\n");
358    else if (strlen(argument) > MAX_TITLE_LENGTH)
359      send_to_char(ch, "Sorry, titles can't be longer than %d characters.\r\n", MAX_TITLE_LENGTH);
360    else {
361      set_title(ch, argument);
362      send_to_char(ch, "Okay, you're now %s %s.\r\n", GET_NAME(ch), GET_TITLE(ch));
363    }
364  }
365  
366  
367  int perform_group(struct char_data *ch, struct char_data *vict)
368  {
369    if (AFF_FLAGGED(vict, AFF_GROUP) || !CAN_SEE(ch, vict))
370      return (0);
371  
372    SET_BIT(AFF_FLAGS(vict), AFF_GROUP);
373    if (ch != vict)
374      act("$N is now a member of your group.", FALSE, ch, 0, vict, TO_CHAR);
375    act("You are now a member of $n's group.", FALSE, ch, 0, vict, TO_VICT);
376    act("$N is now a member of $n's group.", FALSE, ch, 0, vict, TO_NOTVICT);
377    return (1);
378  }
379  
380  
381  void print_group(struct char_data *ch)
382  {
383    struct char_data *k;
384    struct follow_type *f;
385  
386    if (!AFF_FLAGGED(ch, AFF_GROUP))
387      send_to_char(ch, "But you are not the member of a group!\r\n");
388    else {
389      char buf[MAX_STRING_LENGTH];
390  
391      send_to_char(ch, "Your group consists of:\r\n");
392  
393      k = (ch->master ? ch->master : ch);
394  
395      if (AFF_FLAGGED(k, AFF_GROUP)) {
396        snprintf(buf, sizeof(buf), "     [%3dH %3dM %3dV] [%2d %s] $N (Head of group)",
397  	      GET_HIT(k), GET_MANA(k), GET_MOVE(k), GET_LEVEL(k), CLASS_ABBR(k));
398        act(buf, FALSE, ch, 0, k, TO_CHAR);
399      }
400  
401      for (f = k->followers; f; f = f->next) {
402        if (!AFF_FLAGGED(f->follower, AFF_GROUP))
403  	continue;
404  
405        snprintf(buf, sizeof(buf), "     [%3dH %3dM %3dV] [%2d %s] $N", GET_HIT(f->follower),
406  	      GET_MANA(f->follower), GET_MOVE(f->follower),
407  	      GET_LEVEL(f->follower), CLASS_ABBR(f->follower));
408        act(buf, FALSE, ch, 0, f->follower, TO_CHAR);
409      }
410    }
411  }
412  
413  
414  
415  ACMD(do_group)
416  {
417    char buf[MAX_STRING_LENGTH];
418    struct char_data *vict;
419    struct follow_type *f;
420    int found;
421  
422    one_argument(argument, buf);
423  
424    if (!*buf) {
425      print_group(ch);
426      return;
427    }
428  
429    if (ch->master) {
430      act("You can not enroll group members without being head of a group.",
431  	FALSE, ch, 0, 0, TO_CHAR);
432      return;
433    }
434  
435    if (!str_cmp(buf, "all")) {
436      perform_group(ch, ch);
437      for (found = 0, f = ch->followers; f; f = f->next)
438        found += perform_group(ch, f->follower);
439      if (!found)
440        send_to_char(ch, "Everyone following you is already in your group.\r\n");
441      return;
442    }
443  
444    if (!(vict = get_char_vis(ch, buf, NULL, FIND_CHAR_ROOM)))
445      send_to_char(ch, "%s", NOPERSON);
446    else if ((vict->master != ch) && (vict != ch))
447      act("$N must follow you to enter your group.", FALSE, ch, 0, vict, TO_CHAR);
448    else {
449      if (!AFF_FLAGGED(vict, AFF_GROUP))
450        perform_group(ch, vict);
451      else {
452        if (ch != vict)
453  	act("$N is no longer a member of your group.", FALSE, ch, 0, vict, TO_CHAR);
454        act("You have been kicked out of $n's group!", FALSE, ch, 0, vict, TO_VICT);
455        act("$N has been kicked out of $n's group!", FALSE, ch, 0, vict, TO_NOTVICT);
456        REMOVE_BIT(AFF_FLAGS(vict), AFF_GROUP);
457      }
458    }
459  }
460  
461  
462  
463  ACMD(do_ungroup)
464  {
465    char buf[MAX_INPUT_LENGTH];
466    struct follow_type *f, *next_fol;
467    struct char_data *tch;
468  
469    one_argument(argument, buf);
470  
471    if (!*buf) {
472      if (ch->master || !(AFF_FLAGGED(ch, AFF_GROUP))) {
473        send_to_char(ch, "But you lead no group!\r\n");
474        return;
475      }
476  
477      for (f = ch->followers; f; f = next_fol) {
478        next_fol = f->next;
479        if (AFF_FLAGGED(f->follower, AFF_GROUP)) {
480  	REMOVE_BIT(AFF_FLAGS(f->follower), AFF_GROUP);
481          act("$N has disbanded the group.", TRUE, f->follower, NULL, ch, TO_CHAR);
482          if (!AFF_FLAGGED(f->follower, AFF_CHARM))
483  	  stop_follower(f->follower);
484        }
485      }
486  
487      REMOVE_BIT(AFF_FLAGS(ch), AFF_GROUP);
488      send_to_char(ch, "You disband the group.\r\n");
489      return;
490    }
491    if (!(tch = get_char_vis(ch, buf, NULL, FIND_CHAR_ROOM))) {
492      send_to_char(ch, "There is no such person!\r\n");
493      return;
494    }
495    if (tch->master != ch) {
496      send_to_char(ch, "That person is not following you!\r\n");
497      return;
498    }
499  
500    if (!AFF_FLAGGED(tch, AFF_GROUP)) {
501      send_to_char(ch, "That person isn't in your group.\r\n");
502      return;
503    }
504  
505    REMOVE_BIT(AFF_FLAGS(tch), AFF_GROUP);
506  
507    act("$N is no longer a member of your group.", FALSE, ch, 0, tch, TO_CHAR);
508    act("You have been kicked out of $n's group!", FALSE, ch, 0, tch, TO_VICT);
509    act("$N has been kicked out of $n's group!", FALSE, ch, 0, tch, TO_NOTVICT);
510   
511    if (!AFF_FLAGGED(tch, AFF_CHARM))
512      stop_follower(tch);
513  }
514  
515  
516  
517  
518  ACMD(do_report)
519  {
520    char buf[MAX_STRING_LENGTH];
521    struct char_data *k;
522    struct follow_type *f;
523  
524    if (!AFF_FLAGGED(ch, AFF_GROUP)) {
525      send_to_char(ch, "But you are not a member of any group!\r\n");
526      return;
527    }
528  
529    snprintf(buf, sizeof(buf), "$n reports: %d/%dH, %d/%dM, %d/%dV\r\n",
530  	  GET_HIT(ch), GET_MAX_HIT(ch),
531  	  GET_MANA(ch), GET_MAX_MANA(ch),
532  	  GET_MOVE(ch), GET_MAX_MOVE(ch));
533  
534    k = (ch->master ? ch->master : ch);
535  
536    for (f = k->followers; f; f = f->next)
537      if (AFF_FLAGGED(f->follower, AFF_GROUP) && f->follower != ch)
538        act(buf, TRUE, ch, NULL, f->follower, TO_VICT);
539  
540    if (k != ch)
541      act(buf, TRUE, ch, NULL, k, TO_VICT);
542  
543    send_to_char(ch, "You report to the group.\r\n");
544  }
545  
546  
547  
548  ACMD(do_split)
549  {
550    char buf[MAX_INPUT_LENGTH];
551    int amount, num, share, rest;
552    size_t len;
553    struct char_data *k;
554    struct follow_type *f;
555  
556    if (IS_NPC(ch))
557      return;
558  
559    one_argument(argument, buf);
560  
561    if (is_number(buf)) {
562      amount = atoi(buf);
563      if (amount <= 0) {
564        send_to_char(ch, "Sorry, you can't do that.\r\n");
565        return;
566      }
567      if (amount > GET_GOLD(ch)) {
568        send_to_char(ch, "You don't seem to have that much gold to split.\r\n");
569        return;
570      }
571      k = (ch->master ? ch->master : ch);
572  
573      if (AFF_FLAGGED(k, AFF_GROUP) && (IN_ROOM(k) == IN_ROOM(ch)))
574        num = 1;
575      else
576        num = 0;
577  
578      for (f = k->followers; f; f = f->next)
579        if (AFF_FLAGGED(f->follower, AFF_GROUP) &&
580  	  (!IS_NPC(f->follower)) &&
581  	  (IN_ROOM(f->follower) == IN_ROOM(ch)))
582  	num++;
583  
584      if (num && AFF_FLAGGED(ch, AFF_GROUP)) {
585        share = amount / num;
586        rest = amount % num;
587      } else {
588        send_to_char(ch, "With whom do you wish to share your gold?\r\n");
589        return;
590      }
591  
592      GET_GOLD(ch) -= share * (num - 1);
593  
594      /* Abusing signed/unsigned to make sizeof work. */
595      len = snprintf(buf, sizeof(buf), "%s splits %d coins; you receive %d.\r\n",
596  		GET_NAME(ch), amount, share);
597      if (rest && len < sizeof(buf)) {
598        snprintf(buf + len, sizeof(buf) - len,
599  		"%d coin%s %s not splitable, so %s keeps the money.\r\n", rest,
600  		(rest == 1) ? "" : "s", (rest == 1) ? "was" : "were", GET_NAME(ch));
601      }
602      if (AFF_FLAGGED(k, AFF_GROUP) && IN_ROOM(k) == IN_ROOM(ch) &&
603  		!IS_NPC(k) && k != ch) {
604        GET_GOLD(k) += share;
605        send_to_char(k, "%s", buf);
606      }
607  
608      for (f = k->followers; f; f = f->next) {
609        if (AFF_FLAGGED(f->follower, AFF_GROUP) &&
610  	  (!IS_NPC(f->follower)) &&
611  	  (IN_ROOM(f->follower) == IN_ROOM(ch)) &&
612  	  f->follower != ch) {
613  
614  	GET_GOLD(f->follower) += share;
615  	send_to_char(f->follower, "%s", buf);
616        }
617      }
618      send_to_char(ch, "You split %d coins among %d members -- %d coins each.\r\n",
619  	    amount, num, share);
620  
621      if (rest) {
622        send_to_char(ch, "%d coin%s %s not splitable, so you keep the money.\r\n",
623  		rest, (rest == 1) ? "" : "s", (rest == 1) ? "was" : "were");
624        GET_GOLD(ch) += rest;
625      }
626    } else {
627      send_to_char(ch, "How many coins do you wish to split with your group?\r\n");
628      return;
629    }
630  }
631  
632  
633  
634  ACMD(do_use)
635  {
636    char buf[MAX_INPUT_LENGTH], arg[MAX_INPUT_LENGTH];
637    struct obj_data *mag_item;
638  
639    half_chop(argument, arg, buf);
640    if (!*arg) {
641      send_to_char(ch, "What do you want to %s?\r\n", CMD_NAME);
642      return;
643    }
644    mag_item = GET_EQ(ch, WEAR_HOLD);
645  
646    if (!mag_item || !isname(arg, mag_item->name)) {
647      switch (subcmd) {
648      case SCMD_RECITE:
649      case SCMD_QUAFF:
650        if (!(mag_item = get_obj_in_list_vis(ch, arg, NULL, ch->carrying))) {
651  	send_to_char(ch, "You don't seem to have %s %s.\r\n", AN(arg), arg);
652  	return;
653        }
654        break;
655      case SCMD_USE:
656        send_to_char(ch, "You don't seem to be holding %s %s.\r\n", AN(arg), arg);
657        return;
658      default:
659        log("SYSERR: Unknown subcmd %d passed to do_use.", subcmd);
660        return;
661      }
662    }
663    switch (subcmd) {
664    case SCMD_QUAFF:
665      if (GET_OBJ_TYPE(mag_item) != ITEM_POTION) {
666        send_to_char(ch, "You can only quaff potions.\r\n");
667        return;
668      }
669      break;
670    case SCMD_RECITE:
671      if (GET_OBJ_TYPE(mag_item) != ITEM_SCROLL) {
672        send_to_char(ch, "You can only recite scrolls.\r\n");
673        return;
674      }
675      break;
676    case SCMD_USE:
677      if ((GET_OBJ_TYPE(mag_item) != ITEM_WAND) &&
678  	(GET_OBJ_TYPE(mag_item) != ITEM_STAFF)) {
679        send_to_char(ch, "You can't seem to figure out how to use it.\r\n");
680        return;
681      }
682      break;
683    }
684  
685    mag_objectmagic(ch, mag_item, buf);
686  }
687  
688  
689  
690  ACMD(do_wimpy)
691  {
692    char arg[MAX_INPUT_LENGTH];
693    int wimp_lev;
694  
695    /* 'wimp_level' is a player_special. -gg 2/25/98 */
696    if (IS_NPC(ch))
697      return;
698  
699    one_argument(argument, arg);
700  
701    if (!*arg) {
702      if (GET_WIMP_LEV(ch)) {
703        send_to_char(ch, "Your current wimp level is %d hit points.\r\n", GET_WIMP_LEV(ch));
704        return;
705      } else {
706        send_to_char(ch, "At the moment, you're not a wimp.  (sure, sure...)\r\n");
707        return;
708      }
709    }
710    if (isdigit(*arg)) {
711      if ((wimp_lev = atoi(arg)) != 0) {
712        if (wimp_lev < 0)
713  	send_to_char(ch, "Heh, heh, heh.. we are jolly funny today, eh?\r\n");
714        else if (wimp_lev > GET_MAX_HIT(ch))
715  	send_to_char(ch, "That doesn't make much sense, now does it?\r\n");
716        else if (wimp_lev > (GET_MAX_HIT(ch) / 2))
717  	send_to_char(ch, "You can't set your wimp level above half your hit points.\r\n");
718        else {
719  	send_to_char(ch, "Okay, you'll wimp out if you drop below %d hit points.\r\n", wimp_lev);
720  	GET_WIMP_LEV(ch) = wimp_lev;
721        }
722      } else {
723        send_to_char(ch, "Okay, you'll now tough out fights to the bitter end.\r\n");
724        GET_WIMP_LEV(ch) = 0;
725      }
726    } else
727      send_to_char(ch, "Specify at how many hit points you want to wimp out at.  (0 to disable)\r\n");
728  }
729  
730  
731  ACMD(do_display)
732  {
733    size_t i;
734  
735    if (IS_NPC(ch)) {
736      send_to_char(ch, "Mosters don't need displays.  Go away.\r\n");
737      return;
738    }
739    skip_spaces(&argument);
740  
741    if (!*argument) {
742      send_to_char(ch, "Usage: prompt { { H | M | V } | all | auto | none }\r\n");
743      return;
744    }
745  
746    if (!str_cmp(argument, "auto")) {
747      TOGGLE_BIT(PRF_FLAGS(ch), PRF_DISPAUTO);
748      send_to_char(ch, "Auto prompt %sabled.\r\n", PRF_FLAGGED(ch, PRF_DISPAUTO) ? "en" : "dis");
749      return;
750    }
751  
752    if (!str_cmp(argument, "on") || !str_cmp(argument, "all"))
753      SET_BIT(PRF_FLAGS(ch), PRF_DISPHP | PRF_DISPMANA | PRF_DISPMOVE);
754    else if (!str_cmp(argument, "off") || !str_cmp(argument, "none"))
755      REMOVE_BIT(PRF_FLAGS(ch), PRF_DISPHP | PRF_DISPMANA | PRF_DISPMOVE);
756    else {
757      REMOVE_BIT(PRF_FLAGS(ch), PRF_DISPHP | PRF_DISPMANA | PRF_DISPMOVE);
758  
759      for (i = 0; i < strlen(argument); i++) {
760        switch (LOWER(argument[i])) {
761        case 'h':
762  	SET_BIT(PRF_FLAGS(ch), PRF_DISPHP);
763  	break;
764        case 'm':
765  	SET_BIT(PRF_FLAGS(ch), PRF_DISPMANA);
766  	break;
767        case 'v':
768  	SET_BIT(PRF_FLAGS(ch), PRF_DISPMOVE);
769  	break;
770        default:
771  	send_to_char(ch, "Usage: prompt { { H | M | V } | all | auto | none }\r\n");
772  	return;
773        }
774      }
775    }
776  
777    send_to_char(ch, "%s", OK);
778  }
779  
780  
781  
782  ACMD(do_gen_write)
783  {
784    FILE *fl;
785    char *tmp;
786    const char *filename;
787    struct stat fbuf;
788    time_t ct;
789  
790    switch (subcmd) {
791    case SCMD_BUG:
792      filename = BUG_FILE;
793      break;
794    case SCMD_TYPO:
795      filename = TYPO_FILE;
796      break;
797    case SCMD_IDEA:
798      filename = IDEA_FILE;
799      break;
800    default:
801      return;
802    }
803  
804    ct = time(0);
805    tmp = asctime(localtime(&ct));
806  
807    if (IS_NPC(ch)) {
808      send_to_char(ch, "Monsters can't have ideas - Go away.\r\n");
809      return;
810    }
811  
812    skip_spaces(&argument);
813    delete_doubledollar(argument);
814  
815    if (!*argument) {
816      send_to_char(ch, "That must be a mistake...\r\n");
817      return;
818    }
819    mudlog(CMP, LVL_IMMORT, FALSE, "%s %s: %s", GET_NAME(ch), CMD_NAME, argument);
820  
821    if (stat(filename, &fbuf) < 0) {
822      perror("SYSERR: Can't stat() file");
823      return;
824    }
825    if (fbuf.st_size >= max_filesize) {
826      send_to_char(ch, "Sorry, the file is full right now.. try again later.\r\n");
827      return;
828    }
829    if (!(fl = fopen(filename, "a"))) {
830      perror("SYSERR: do_gen_write");
831      send_to_char(ch, "Could not open the file.  Sorry.\r\n");
832      return;
833    }
834    fprintf(fl, "%-8s (%6.6s) [%5d] %s\n", GET_NAME(ch), (tmp + 4),
835  	  GET_ROOM_VNUM(IN_ROOM(ch)), argument);
836    fclose(fl);
837    send_to_char(ch, "Okay.  Thanks!\r\n");
838  }
839  
840  
841  
842  #define TOG_OFF 0
843  #define TOG_ON  1
844  
845  #define PRF_TOG_CHK(ch,flag) ((TOGGLE_BIT(PRF_FLAGS(ch), (flag))) & (flag))
846  
847  ACMD(do_gen_tog)
848  {
849    long /* bitvector_t */ result;
850  
851    const char *tog_messages[][2] = {
852      {"You are now safe from summoning by other players.\r\n",
853      "You may now be summoned by other players.\r\n"},
854      {"Nohassle disabled.\r\n",
855      "Nohassle enabled.\r\n"},
856      {"Brief mode off.\r\n",
857      "Brief mode on.\r\n"},
858      {"Compact mode off.\r\n",
859      "Compact mode on.\r\n"},
860      {"You can now hear tells.\r\n",
861      "You are now deaf to tells.\r\n"},
862      {"You can now hear auctions.\r\n",
863      "You are now deaf to auctions.\r\n"},
864      {"You can now hear shouts.\r\n",
865      "You are now deaf to shouts.\r\n"},
866      {"You can now hear gossip.\r\n",
867      "You are now deaf to gossip.\r\n"},
868      {"You can now hear the congratulation messages.\r\n",
869      "You are now deaf to the congratulation messages.\r\n"},
870      {"You can now hear the Wiz-channel.\r\n",
871      "You are now deaf to the Wiz-channel.\r\n"},
872      {"You are no longer part of the Quest.\r\n",
873      "Okay, you are part of the Quest!\r\n"},
874      {"You will no longer see the room flags.\r\n",
875      "You will now see the room flags.\r\n"},
876      {"You will now have your communication repeated.\r\n",
877      "You will no longer have your communication repeated.\r\n"},
878      {"HolyLight mode off.\r\n",
879      "HolyLight mode on.\r\n"},
880      {"Nameserver_is_slow changed to NO; IP addresses will now be resolved.\r\n",
881      "Nameserver_is_slow changed to YES; sitenames will no longer be resolved.\r\n"},
882      {"Autoexits disabled.\r\n",
883      "Autoexits enabled.\r\n"},
884      {"Will no longer track through doors.\r\n",
885      "Will now track through doors.\r\n"}
886    };
887  
888  
889    if (IS_NPC(ch))
890      return;
891  
892    switch (subcmd) {
893    case SCMD_NOSUMMON:
894      result = PRF_TOG_CHK(ch, PRF_SUMMONABLE);
895      break;
896    case SCMD_NOHASSLE:
897      result = PRF_TOG_CHK(ch, PRF_NOHASSLE);
898      break;
899    case SCMD_BRIEF:
900      result = PRF_TOG_CHK(ch, PRF_BRIEF);
901      break;
902    case SCMD_COMPACT:
903      result = PRF_TOG_CHK(ch, PRF_COMPACT);
904      break;
905    case SCMD_NOTELL:
906      result = PRF_TOG_CHK(ch, PRF_NOTELL);
907      break;
908    case SCMD_NOAUCTION:
909      result = PRF_TOG_CHK(ch, PRF_NOAUCT);
910      break;
911    case SCMD_DEAF:
912      result = PRF_TOG_CHK(ch, PRF_DEAF);
913      break;
914    case SCMD_NOGOSSIP:
915      result = PRF_TOG_CHK(ch, PRF_NOGOSS);
916      break;
917    case SCMD_NOGRATZ:
918      result = PRF_TOG_CHK(ch, PRF_NOGRATZ);
919      break;
920    case SCMD_NOWIZ:
921      result = PRF_TOG_CHK(ch, PRF_NOWIZ);
922      break;
923    case SCMD_QUEST:
924      result = PRF_TOG_CHK(ch, PRF_QUEST);
925      break;
926    case SCMD_ROOMFLAGS:
927      result = PRF_TOG_CHK(ch, PRF_ROOMFLAGS);
928      break;
929    case SCMD_NOREPEAT:
930      result = PRF_TOG_CHK(ch, PRF_NOREPEAT);
931      break;
932    case SCMD_HOLYLIGHT:
933      result = PRF_TOG_CHK(ch, PRF_HOLYLIGHT);
934      break;
935    case SCMD_SLOWNS:
936      result = (nameserver_is_slow = !nameserver_is_slow);
937      break;
938    case SCMD_AUTOEXIT:
939      result = PRF_TOG_CHK(ch, PRF_AUTOEXIT);
940      break;
941    case SCMD_TRACK:
942      result = (track_through_doors = !track_through_doors);
943      break;
944    default:
945      log("SYSERR: Unknown subcmd %d in do_gen_toggle.", subcmd);
946      return;
947    }
948  
949    if (result)
950      send_to_char(ch, "%s", tog_messages[subcmd][TOG_ON]);
951    else
952      send_to_char(ch, "%s", tog_messages[subcmd][TOG_OFF]);
953  
954    return;
955  }