AwakeMUD-0.6Beta/doc/
AwakeMUD-0.6Beta/lib/
AwakeMUD-0.6Beta/lib/etc/
AwakeMUD-0.6Beta/lib/etc/pfiles/
AwakeMUD-0.6Beta/lib/fixer_data/
AwakeMUD-0.6Beta/lib/misc/
AwakeMUD-0.6Beta/lib/plrobjs/
AwakeMUD-0.6Beta/lib/plrobjs/A-E/
AwakeMUD-0.6Beta/lib/plrobjs/F-J/
AwakeMUD-0.6Beta/lib/plrobjs/K-O/
AwakeMUD-0.6Beta/lib/plrobjs/U-Z/
AwakeMUD-0.6Beta/lib/plrspells/A-E/
AwakeMUD-0.6Beta/lib/plrspells/F-J/
AwakeMUD-0.6Beta/lib/plrtext/A-E/
AwakeMUD-0.6Beta/lib/world/
AwakeMUD-0.6Beta/lib/world/mob/
AwakeMUD-0.6Beta/lib/world/obj/
AwakeMUD-0.6Beta/lib/world/qst/
AwakeMUD-0.6Beta/lib/world/shp/
AwakeMUD-0.6Beta/lib/world/wld/
AwakeMUD-0.6Beta/lib/world/zon/
/* ************************************************************************
*   File: act.other.c                                   Part of CircleMUD *
*  Usage: Miscellaneous player-level commands                             *
*                                                                         *
*  All rights reserved.  See license.doc for complete information.        *
*                                                                         *
*  Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University *
*  CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991.               *
************************************************************************ */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "structs.h"
#include "utils.h"
#include "comm.h"
#include "interpreter.h"
#include "handler.h"
#include "db.h"
#include "spells.h"
#include "house.h"
#include "newmagic.h"
#include "ident.h"
#include "olc.h"
#include "boards.h"
#include "screen.h"
#include "memory.h"
#include "awake.h"

/* extern variables */
extern const struct str_app_type str_app[];
extern struct room_data *world;
extern struct descriptor_data *descriptor_list;
extern struct room_data *world;
extern struct player_special_data dummy_mob;
//extern struct dex_skill_type dex_app_skill[];
extern struct spell_info_type spell_info[];
extern struct index_data *mob_index;
extern struct index_data *obj_index;
extern struct zone_data *zone_table;
extern int max_obj_save;
extern int top_of_zone_table;
extern int auto_save;
extern const char *spells[];
extern const char *wound_name[];
extern const char *ctypes[];
extern char *short_object(int virt, int where);
extern bool save_etext(struct char_data *ch);
extern bool read_extratext(struct char_data * ch);
extern int House_can_enter(struct char_data * ch, sh_int house);
extern int return_general(int skill_num);
extern int belongs_to(struct char_data *ch, struct obj_data *obj);
extern int reverse_web(struct char_data *ch, int &skill, int &target);
extern bool check_lar( char_data *ch, char *str, int channel );

extern class memoryClass *Mem;

/* extern procedures */
SPECIAL(shop_keeper);
extern char *how_good(int percent);
extern void perform_tell(struct char_data *, struct char_data *, char *);
extern void obj_to_cyberware(struct obj_data * object, struct char_data * ch);
extern void obj_to_bioware(struct obj_data * object, struct char_data * ch);
extern void obj_magic(struct char_data * ch, struct obj_data * obj, char *argument);
extern void end_quest(struct char_data *ch);
extern void save_fixers(void);

ACMD(do_quit)
{
  void die(struct char_data * ch);
  void Crash_rentsave(struct char_data * ch, int cost);
  extern int free_rent;
  int i, numitems = 0;
  struct obj_data *obj, *temp;
  struct descriptor_data *d, *next_d;

  if (IS_NPC(ch) || !ch->desc)
    return;

  if (subcmd != SCMD_QUIT && GET_LEVEL(ch) < LVL_LEGEND)
    send_to_char("You have to type quit - no less, to quit!\r\n", ch);
  else if (GET_POS(ch) == POS_FIGHTING)
    send_to_char("No way!  You're fighting for your life!\r\n", ch);
  else if (ROOM_FLAGGED(ch->in_room, ROOM_NOQUIT))
    send_to_char("You can't quit here!\r\n", ch);
  else if (GET_POS(ch) < POS_STUNNED) {
    send_to_char("You die before your time...\r\n", ch);
    act("$n gives up the struggle to live...", TRUE, ch, 0, 0, TO_ROOM);
    die(ch);
  } else if (GET_POS(ch) == POS_STUNNED) {
    send_to_char("You're unconscious!  You can't leave now!\r\n", ch);
    return;
  } else if (!PLR_FLAGGED(ch, PLR_LOADROOM) && (GET_LOADROOM(ch) < 2000 || GET_LOADROOM(ch) == 8039
      || ( GET_LOADROOM(ch) >= 700 && GET_LOADROOM(ch) <=799) ) &&
      GET_LEVEL(ch) < LVL_LEGEND && !PLR_FLAGGED(ch, PLR_NEWBIE)) {
    send_to_char("You can't quit -- you have never rented!\r\n", ch);
    return;
  } else {
    for (i = 0; i < (NUM_WEARS - 1); i++)
      if (GET_EQ(ch, i)) {
        numitems++;
        for (obj = GET_EQ(ch, i)->contains; obj; obj = obj->next_content)
          numitems++;
      }
    for (obj = ch->carrying; obj; obj = obj->next_content) {
      numitems++;
      for (temp = obj->contains; temp; temp = temp->next_content)
        numitems++;
    }
    if (numitems > max_obj_save) {
      send_to_char(ch, "You are only allowed to quit with %d items.\r\n", max_obj_save);
      return;
    }
    act("$n has left the game.", TRUE, ch, 0, 0, TO_ROOM);
    sprintf(buf, "%s has quit the game.", GET_NAME(ch));
    mudlog(buf, ch, LOG_CONNLOG, FALSE);
    send_to_char("Later, chummer.\r\n", ch);
    save_fixers();

    /*
     * kill off all sockets connected to the same player as the one who is
     * trying to quit.  Helps to maintain sanity as well as prevent duping.
     */
    for (d = descriptor_list; d; d = next_d)
    {
      next_d = d->next;
      if (d == ch->desc)
        continue;
      if (d->character && (GET_IDNUM(d->character) == GET_IDNUM(ch)))
        close_socket(d);
    }

    /*
     If you did not quit in your house
     You lose all your eq tough luck
    */

    int save_room = ch->in_room;
    if (GET_QUEST(ch))
      end_quest(ch);
    /* if (free_rent) */
    Crash_rentsave(ch, 0);
    /* If someone is quitting in their house, let them load back here */
    /* extract_char */
    if (ROOM_FLAGGED(save_room, ROOM_HOUSE) && House_can_enter(ch, world[save_room].number))
    {
      GET_LOADROOM(ch) = world[save_room].number;
      save_char(ch, GET_LOADROOM(ch));
    }
    else
    {
      ch->in_room = save_room;
      if ( !PLR_FLAGGED(ch, PLR_LOADROOM))
      {
      	if (PLR_FLAGGED(ch, PLR_NEWBIE))
	      GET_LOADROOM(ch) = 8039;
	  	else
	  	  GET_LOADROOM(ch) = 2127;
  	  }
      save_char(ch, GET_LOADROOM(ch));
    }
    if (ch->desc && GET_LEVEL(ch) < LVL_LEGEND)
      STATE(ch->desc) = CON_QMENU;
    extract_char(ch);           /* Char is saved in extract char */
  }
}

ACMD(do_save)
{
  if (IS_NPC(ch) || !ch->desc)
    return;

  if (cmd)
  {
    /*
    if (auto_save)
    {
      send_to_char("There is no need to save manually.\r\n", ch);
      return;
    }
    */
    /* Log the call so we can see abusers*/
    sprintf(buf,"Saving player %s",GET_NAME(ch));
	mudlog(buf,ch,LOG_MISCLOG, TRUE);

    sprintf(buf, "Saving %s.\r\n", GET_NAME(ch));
    send_to_char(buf, ch);
    WAIT_STATE(ch,8);
  }
  Crash_crashsave(ch);
  save_char(ch, NOWHERE);
  write_spells(ch);
  save_etext(ch);
  if (ROOM_FLAGGED(ch->in_room, ROOM_HOUSE_CRASH))
    House_crashsave(world[ch->in_room].number);
}

/* generic function for commands which are normally overridden by
   special procedures - i.e., shop commands, mail commands, etc. */
ACMD(do_not_here)
{
  send_to_char("Sorry, but you cannot do that here!\r\n", ch);
}

ACMD(do_sneak)
{
  struct affected_type af;
  bool has_sneak = FALSE;

  if (IS_AFFECTED(ch, AFF_SNEAK)) {
    REMOVE_BIT(AFF_FLAGS(ch), AFF_SNEAK);
    send_to_char("You stop sneaking around.\r\n", ch);
    return;
  }

  if (GET_SKILL(ch, SKILL_STEALTH) > 0)
    has_sneak = TRUE;

  if (has_sneak)
    send_to_char("You begin to move with stealth.\r\n", ch);
  else send_to_char("You attempt to move with stealth.\r\n", ch);
}

ACMD(do_hide)
{
  byte percent;

  send_to_char("You attempt to hide yourself.\r\n", ch);

  if (IS_AFFECTED(ch, AFF_HIDE))
    REMOVE_BIT(AFF_FLAGS(ch), AFF_HIDE);

  percent = number(1, 101);     /* 101% is a complete failure */

  if (percent > GET_SKILL(ch, SKILL_HIDE)) // + dex_app_skill[GET_QUI(ch)].hide)
    return;

  SET_BIT(AFF_FLAGS(ch), AFF_HIDE);
}

ACMD(do_steal)
{
  struct char_data *vict;
  struct obj_data *obj;
  char vict_name[240];
  char obj_name[240];
  int percent, gold, eq_pos, pcsteal = 0;
  extern int pt_allowed;
  bool ohoh = FALSE;

  ACMD(do_gen_comm);

  if (IS_ASTRAL(ch) || IS_PERSONA(ch)) {
    send_to_char("Heh...whatever.\r\n", ch);
    return;
  }

  argument = one_argument(argument, obj_name);
  one_argument(argument, vict_name);

  if (!(vict = get_char_room_vis(ch, vict_name))) {
    send_to_char("Steal what from who?\r\n", ch);
    return;
  } else if (vict == ch) {
    send_to_char("Come on now, that's rather stupid!\r\n", ch);
    return;
  }
  if (!pt_allowed) {
    if (!IS_NPC(vict) && !PLR_FLAGGED(vict, PLR_THIEF) &&
        !PLR_FLAGGED(vict, PLR_KILLER) && !PLR_FLAGGED(ch, PLR_THIEF)) {
      /*
       * SET_BIT(ch->specials.act, PLR_THIEF); send_to_char("Okay, you're the
       * boss... you're now a THIEF!\r\n",ch); sprintf(buf, "PC Thief bit set
       * on %s", GET_NAME(ch)); log(buf);
       */
      pcsteal = 1;
    }
    if (PLR_FLAGGED(ch, PLR_THIEF))
      pcsteal = 1;

    /*
     * We'll try something different... instead of having a thief flag, just
     * have PC Steals fail all the time.
     * We should allow PC thieves
     */
  }
  /* 101% is a complete failure */
  percent = number(1, 101); // - dex_app_skill[GET_QUI(ch)].p_pocket;

  if (GET_POS(vict) < POS_SLEEPING)
    percent = -1;               /* ALWAYS SUCCESS */

  /* NO NO With Imp's and Shopkeepers! */
  if ((GET_LEVEL(vict) >= LVL_LEGEND) || pcsteal || GET_MOB_SPEC(vict) == shop_keeper)
    percent = 101;              /* Failure */

  if (str_cmp(obj_name, "credits") && str_cmp(obj_name, "credstick")) {

    if (!(obj = get_obj_in_list_vis(vict, obj_name, vict->carrying))) {

      for (eq_pos = 0; eq_pos < NUM_WEARS; eq_pos++)
        if (GET_EQ(vict, eq_pos) &&
            (isname(obj_name, GET_EQ(vict, eq_pos)->name)) &&
            CAN_SEE_OBJ(ch, GET_EQ(vict, eq_pos))) {
          obj = GET_EQ(vict, eq_pos);
          break;
        }
      if (!obj) {
        act("$E hasn't got that item.", FALSE, ch, 0, vict, TO_CHAR);
        return;
      } else {                  /* It is equipment */
        if ((GET_POS(vict) > POS_STUNNED)) {


          send_to_char("Steal the equipment now?  Impossible!\r\n", ch);
          return;
        } else {
          act("You unequip $p and steal it.", FALSE, ch, obj, 0, TO_CHAR);
          act("$n steals $p from $N.", FALSE, ch, obj, vict, TO_NOTVICT);
          obj_to_char(unequip_char(vict, eq_pos), ch);
        }
      }
    } else {                    /* obj found in inventory */

      percent += GET_OBJ_WEIGHT(obj);   /* Make heavy harder */

      if (AWAKE(vict) && (percent > GET_SKILL(ch, SKILL_STEAL))) {
        ohoh = TRUE;
        act("Oops..", FALSE, ch, 0, 0, TO_CHAR);
        act("$n tried to steal something from you!", FALSE, ch, 0, vict, TO_VICT);
        act("$n tries to steal something from $N.", TRUE, ch, 0, vict, TO_NOTVICT);
      } else {                  /* Steal the item */
        if ((IS_CARRYING_N(ch) + 1 < CAN_CARRY_N(ch))) {
          if ((IS_CARRYING_W(ch) + GET_OBJ_WEIGHT(obj)) < CAN_CARRY_W(ch)) {
            obj_from_char(obj);
            obj_to_char(obj, ch);
            send_to_char("Got it!\r\n", ch);
          }
        } else
          send_to_char("You cannot carry that much.\r\n", ch);
      }
    }
  } else {      /* Steal some credits, probably an impossible task */
    if (AWAKE(vict) && (percent > GET_SKILL(ch, SKILL_STEAL))) {
      ohoh = TRUE;
      act("Oops..", FALSE, ch, 0, 0, TO_CHAR);
      act("You discover that $n has $s hands on your credstick.", FALSE, ch, 0, vict, TO_VICT);
      act("$n tries to steal a credstick from $N.", TRUE, ch, 0, vict, TO_NOTVICT);
    } else {
      /* Steal some credits */
      gold = (int) ((GET_NUYEN(vict) * number(1, 10)) / 100);
      gold = MIN(1782, gold);
      if (gold > 0) {
        GET_NUYEN(ch) += gold;
        GET_NUYEN(vict) -= gold;
        sprintf(buf, "Bingo!  You got %d credits.\r\n", gold);
        send_to_char(buf, ch);
      } else {
        send_to_char("You couldn't get any credits...\r\n", ch);
      }
    }
  }

  if (ohoh && IS_NPC(vict) && AWAKE(vict))
    set_fighting(vict, ch);
//    hit(vict, ch, TYPE_UNDEFINED);
}

ACMD(do_practice)
{
  send_to_char("You can only practice skills through a teacher.  (Use the 'skills' command\r\nto see which skills you know)\r\n", ch);
}

ACMD(do_train)
{
  send_to_char("You can only train with a trainer.\r\n", ch);
}

ACMD(do_visible)
{
  void appear(struct char_data * ch);

  if (IS_AFFECTED(ch, AFF_INVISIBLE) || IS_AFFECTED(ch, AFF_IMP_INVIS)) {
    appear(ch);
    send_to_char("You break the spell of invisibility.\r\n", ch);
  } else
    send_to_char("You are already visible.\r\n", ch);
}

ACMD(do_title)
{
  skip_spaces(&argument);
  delete_doubledollar(argument);

  if (IS_NPC(ch))
    send_to_char("Your title is fine... go away.\r\n", ch);
  else if (PLR_FLAGGED(ch, PLR_NOTITLE))
    send_to_char("You can't title yourself.\r\n", ch);
  else if (strstr((const char *)argument, "(") || strstr((const char *)argument, ")"))
    send_to_char("Titles can't contain the ( or ) characters.\r\n", ch);
  else if (strlen(argument) > (MAX_TITLE_LENGTH - 2)) {
    sprintf(buf, "Sorry, titles can't be longer than %d characters.\r\n",
            MAX_TITLE_LENGTH - 2);
    send_to_char(buf, ch);
  } else {

    /* Twink check */
    if ( check_lar( ch, argument, CHAN_TITLE ) )
	return;

    skip_spaces(&argument);
    strcat(argument, "^n");
    set_title(ch, argument);
    sprintf(buf, "Okay, you're now %s %s.\r\n", GET_NAME(ch), GET_TITLE(ch));
    send_to_char(buf, ch);
  }
}

int perform_group(struct char_data *ch, struct char_data *vict)
{
  if (IS_AFFECTED(vict, AFF_GROUP) || !CAN_SEE(ch, vict) || (GET_LEVEL(ch) < LVL_LEGEND &&
      GET_LEVEL(vict) >= LVL_LEGEND))
    return 0;

  SET_BIT(AFF_FLAGS(vict), AFF_GROUP);
  if (ch != vict)
    act("$N is now a member of your group.", FALSE, ch, 0, vict, TO_CHAR);
  act("You are now a member of $n's group.", FALSE, ch, 0, vict, TO_VICT);
  act("$N is now a member of $n's group.", FALSE, ch, 0, vict, TO_NOTVICT);
  return 1;
}

void print_group(struct char_data *ch)
{
  struct char_data *k;
  struct follow_type *f;

  if (!IS_AFFECTED(ch, AFF_GROUP))
    send_to_char("But you are not the member of a group!\r\n", ch);
  else {
    send_to_char("Your group consists of:\r\n", ch);

    k = (ch->master ? ch->master : ch);

      if (IS_AFFECTED(k, AFF_GROUP)) {
        sprintf(buf, "     [%3dP %3dM] %-20s (Head of group)\r\n",
                (int)(GET_PHYSICAL(k) / 100), (int)(GET_MENTAL(k) / 100), GET_NAME(k));
        send_to_char(buf, ch);
      }

    for (f = k->followers; f; f = f->next) {
      if (!IS_AFFECTED(f->follower, AFF_GROUP))
        continue;

          sprintf(buf, "     [%3dP %3dM] $N",
                      (int)(GET_PHYSICAL(f->follower) / 100),
                      (int)(GET_MENTAL(f->follower) / 100));
          act(buf, FALSE, ch, 0, f->follower, TO_CHAR);
    }
  }
}

ACMD(do_group)
{
  struct char_data *vict;
  struct follow_type *f;
  int found;

  one_argument(argument, buf);

  if (!*buf) {
    print_group(ch);
    return;
  }

  if (ch->master) {
    act("You can not enroll group members without being head of a group.",
        FALSE, ch, 0, 0, TO_CHAR);
    return;
  }

  if (!str_cmp(buf, "all")) {
    perform_group(ch, ch);
    for (found = 0, f = ch->followers; f; f = f->next)
      found += perform_group(ch, f->follower);
    if (!found)
      send_to_char("Everyone following you is already in your group.\r\n", ch);
    return;
  }

  if (!(vict = get_char_room_vis(ch, buf)))
    send_to_char(NOPERSON, ch);
  else if ((vict->master != ch) && (vict != ch))
    act("$N must follow you to enter your group.", FALSE, ch, 0, vict, TO_CHAR);
  else {
    if (!IS_AFFECTED(vict, AFF_GROUP))
      perform_group(ch, vict);
    else {
      if (ch != vict) {
        act("$N is no longer a member of your group.", FALSE, ch, 0, vict, TO_CHAR);
        if (ch->player_specials->gname) {
          delete [] ch->player_specials->gname;
         ch->player_specials->gname = NULL;
        }
      }
      act("You have been kicked out of $n's group!", FALSE, ch, 0, vict, TO_VICT);
      act("$N has been kicked out of $n's group!", FALSE, ch, 0, vict, TO_NOTVICT);
      REMOVE_BIT(AFF_FLAGS(vict), AFF_GROUP);
    }
  }
}

ACMD(do_gname)
{
  if (ch->master) {
    send_to_char(ch, "You must be the head of %s group to name it.\r\n",
                 IS_AFFECTED(ch, AFF_GROUP) ? "the" : "a");
    return;
  }
  skip_spaces(&argument);
  if (!*argument) {
    send_to_char(ch, "Current group name: %s\r\n", ch->player_specials->gname);
    return;
  } else if (strlen(argument) > MAX_NAME_LENGTH) {
    send_to_char(ch, "Group names are limited to %d characters.\r\n", MAX_NAME_LENGTH);
    return;
  }
  if (ch->player_specials->gname)
    delete [] ch->player_specials->gname;
  ch->player_specials->gname = str_dup(argument);
  send_to_char(ch, "Group name set to: %s\r\n", argument);
}

ACMD(do_ungroup)
{
  struct follow_type *f, *next_fol;
  struct char_data *tch;
  void stop_follower(struct char_data * ch);

  one_argument(argument, buf);

  if (!*buf) {
    if (ch->master || !(IS_AFFECTED(ch, AFF_GROUP))) {
      send_to_char("But you lead no group!\r\n", ch);
      return;
    }
    sprintf(buf2, "%s has disbanded the group.\r\n", GET_NAME(ch));
    for (f = ch->followers; f; f = next_fol) {
      next_fol = f->next;
      if (IS_AFFECTED(f->follower, AFF_GROUP)) {
        REMOVE_BIT(AFF_FLAGS(f->follower), AFF_GROUP);
        send_to_char(buf2, f->follower);
        if (!IS_AFFECTED(f->follower, AFF_CHARM))
          stop_follower(f->follower);
      }
    }

    if (ch->player_specials->gname) {
      delete [] ch->player_specials->gname;
      ch->player_specials->gname = NULL;
    }
    REMOVE_BIT(AFF_FLAGS(ch), AFF_GROUP);
    send_to_char("You disband the group.\r\n", ch);
    return;
  }
  if (!(tch = get_char_room_vis(ch, buf))) {
    send_to_char("There is no such person!\r\n", ch);
    return;
  }
  if (tch->master != ch) {
    send_to_char("That person is not following you!\r\n", ch);
    return;
  }

  if (!IS_AFFECTED(tch, AFF_GROUP)) {
    send_to_char("That person isn't in your group.\r\n", ch);
    return;
  }

  REMOVE_BIT(AFF_FLAGS(tch), AFF_GROUP);

  act("$N is no longer a member of your group.", FALSE, ch, 0, tch, TO_CHAR);
  act("You have been kicked out of $n's group!", FALSE, ch, 0, tch, TO_VICT);
  act("$N has been kicked out of $n's group!", FALSE, ch, 0, tch, TO_NOTVICT);

  if (!IS_AFFECTED(tch, AFF_CHARM))
    stop_follower(tch);
}

ACMD(do_report)
{
  struct char_data *k;
  struct follow_type *f;

  if (!IS_AFFECTED(ch, AFF_GROUP)) {
    send_to_char("But you are not a member of any group!\r\n", ch);
    return;
  }
  sprintf(buf, "%s reports: %d/%dP, %d/%dM\r\n", GET_NAME(ch),
          (int)(GET_PHYSICAL(ch) / 100), (int)(GET_MAX_PHYSICAL(ch) / 100),
          (int)(GET_MENTAL(ch) / 100), (int)(GET_MAX_MENTAL(ch) / 100));

  CAP(buf);

  k = (ch->master ? ch->master : ch);

  for (f = k->followers; f; f = f->next)
    if (IS_AFFECTED(f->follower, AFF_GROUP) && f->follower != ch)
      send_to_char(buf, f->follower);
  if (k != ch)
    send_to_char(buf, k);
  send_to_char("You report to the group.\r\n", ch);
}

ACMD(do_split)
{
  int amount, num, share;
  struct char_data *k;
  struct follow_type *f;

  if (IS_NPC(ch))
    return;

  one_argument(argument, buf);

  if (is_number(buf)) {
    amount = atoi(buf);
    if (amount <= 0) {
      send_to_char("Sorry, you can't do that.\r\n", ch);
      return;
    }
    if (amount > GET_NUYEN(ch)) {
      send_to_char("You don't seem to have that much gold to split.\r\n", ch);
      return;
    }
    k = (ch->master ? ch->master : ch);

    if (IS_AFFECTED(k, AFF_GROUP) && (k->in_room == ch->in_room))
      num = 1;
    else
      num = 0;

    for (f = k->followers; f; f = f->next)
      if (IS_AFFECTED(f->follower, AFF_GROUP) &&
          (!IS_NPC(f->follower)) &&
          (f->follower->in_room == ch->in_room))
        num++;

    if (num && IS_AFFECTED(ch, AFF_GROUP))
      share = amount / num;
    else {
      send_to_char("With whom do you wish to share your nuyen?\r\n", ch);
      return;
    }

    GET_NUYEN(ch) -= share * (num - 1);

    if (IS_AFFECTED(k, AFF_GROUP) && (k->in_room == ch->in_room)
        && !(IS_NPC(k)) && k != ch) {
      GET_NUYEN(k) += share;
      sprintf(buf, "%s splits %d nuyen; you receive %d.\r\n", GET_NAME(ch),
              amount, share);
      send_to_char(buf, k);
    }
    for (f = k->followers; f; f = f->next) {
      if (IS_AFFECTED(f->follower, AFF_GROUP) &&
          (!IS_NPC(f->follower)) &&
          (f->follower->in_room == ch->in_room) &&
          f->follower != ch) {
        GET_NUYEN(f->follower) += share;
        sprintf(buf, "%s splits %d nuyen; you receive %d.\r\n", GET_NAME(ch),
                amount, share);
        send_to_char(buf, f->follower);
      }
    }
    sprintf(buf, "You split %d nuyen among %d members -- %d nuyen each.\r\n",
            amount, num, share);
    send_to_char(buf, ch);
  } else {
    send_to_char("How much nuyen do you wish to split with your group?\r\n", ch);
    return;
  }
}

ACMD(do_patch)
{
  struct char_data *vict;
  struct obj_data *patch;
  half_chop(argument, arg, buf);

  if (!*arg || !*buf) {
   send_to_char("Who do you want to patch and with what?\r\n", ch);
   return;
  }

  if (!(patch = get_obj_in_list_vis(ch, arg, ch->carrying))) {
    send_to_char(ch, "You don't seem to have a '%s'.\r\n", arg);
    return;
  }
  if (!(vict = get_char_room_vis(ch, buf))) {
    send_to_char(ch, "There doesn't seem to be a '%s' here.\r\n", buf);
    return;
  }
  if (GET_EQ(vict, WEAR_PATCH)) {
    act("$N already has a patch applied.", FALSE, ch, 0, vict, TO_CHAR);
    return;
  }
  if (GET_OBJ_VAL(patch, 1) < 1) {
    send_to_char("That patch seems to be defective...\r\n", ch);
    return;
  }
  switch (GET_OBJ_VAL(patch, 0)) {
    case 0:                          // antidote
      if (!AFF_FLAGGED(vict, AFF_POISON)) {
        act("But $N is not even poisoned!", FALSE, ch, 0, vict, TO_CHAR);
        return;
      }
      if (vict == ch)
        act("You slap $p on your shoulder.", FALSE, ch, patch, 0, TO_CHAR);
      else {
        act("You slap $p on $N's shoulder.", FALSE, ch, patch, vict, TO_CHAR);
        act("$n slaps $p on your shoulder.", FALSE, ch, patch, vict, TO_VICT);
        act("$n slaps $p on $N's shoulder.", FALSE, ch, patch, vict, TO_NOTVICT);
      }
      obj_from_char(patch);
      GET_EQ(vict, WEAR_PATCH) = patch;
      patch->worn_by = vict;
      patch->worn_on = WEAR_PATCH;
      break;
    case 1:                          // stim
      if (vict != ch) {
        send_to_char("You can only use stim patches on yourself.\r\n", ch);
        return;
      }
      act("You slap $p on your shoulder and feel more aware.", FALSE, ch, patch, 0, TO_CHAR);
      act("$n slaps $p on $s shoulder and appears more aware.", FALSE, ch, patch, 0, TO_ROOM);
      GET_OBJ_VAL(patch,5) = GET_MENTAL(ch);
      GET_MENTAL(ch) = MIN(GET_MAX_MENTAL(ch), GET_MENTAL(ch) + (GET_OBJ_VAL(patch, 1) * 100));
      obj_from_char(patch);
      GET_EQ(vict, WEAR_PATCH) = patch;
      patch->worn_by = vict;
      patch->worn_on = WEAR_PATCH;
      break;
    case 2:                          // tranq
      if (GET_POS(vict) == POS_FIGHTING) {
        send_to_char("You can't put a tranq patch on a fighting person!\r\n", ch);
        return;
      }
      if (vict == ch) {
        send_to_char("Now why would you do that?\r\n", ch);
        return;
      }
      if (GET_POS(vict) > POS_SLEEPING) {
        if (resisted_test(GET_QUI(ch), GET_QUI(vict) - GET_POS(vict) + POS_STANDING, GET_QUI(vict),
            GET_QUI(ch) - GET_POS(ch) + POS_STANDING) <= 0) {
          act("$N nimbly dodges your attempt to put $p on $M.", FALSE, ch, patch, vict, TO_CHAR);
          act("You nimbly dodge $n's attempt to put $p on you.", FALSE, ch, patch, vict, TO_VICT);
          act("$N nimbly dodges $n's attempt to put $p on $M.", FALSE, ch, patch, vict, TO_NOTVICT);
          if (IS_NPC(vict) || (IS_NPC(ch) && !IS_NPC(vict))) {
            set_fighting(vict, ch);
            set_fighting(ch, vict);
          }
          return;
        } else {
          act("You slap $p on $N before $E has a chance to move!", FALSE, ch, patch, vict, TO_CHAR);
          act("$n slaps $p on you before you can get out of the way!", FALSE, ch, patch, vict, TO_VICT);
          act("$n slaps $p on $N before $E has a chance to move!", FALSE, ch, patch, vict, TO_NOTVICT);
          if (IS_NPC(vict) || (IS_NPC(ch) && !IS_NPC(vict))) {
            set_fighting(vict, ch);
            set_fighting(ch, vict);
          }
        }
      }
      obj_from_char(patch);
      GET_EQ(vict, WEAR_PATCH) = patch;
      patch->worn_by = vict;
      patch->worn_on = WEAR_PATCH;
      break;
    case 3:                          // trauma
      if (GET_POS(vict) >= POS_STUNNED) {
        send_to_char("Now where's the sense in that?\r\n", ch);
        return;
      }
      act("You slap $p over $N's heart.", FALSE, ch, patch, vict, TO_CHAR);
      act("$n slaps $p over $N's heart.", FALSE, ch, patch, vict, TO_NOTVICT);
      obj_from_char(patch);
      GET_EQ(vict, WEAR_PATCH) = patch;
      patch->worn_by = vict;
      patch->worn_on = WEAR_PATCH;
      /* Code here to do a trauma patch And we can check for it in death penalty */
      break;
    default:
      act("$p seems to be defective.", FALSE, ch, patch, 0, TO_CHAR);
      sprintf(buf, "Illegal patch type - object #%d", GET_OBJ_VNUM(patch));
      mudlog(buf, ch, LOG_SYSLOG, FALSE);
      break;
  }
}

ACMD(do_use)
{
  SPECIAL(anticoagulant);
  struct obj_data *mag_item, *obj, *corpse;
  struct char_data *tmp_char;
  int equipped = 1;

  half_chop(argument, arg, buf);
  if (!*arg) {
    sprintf(buf2, "What do you want to %s?\r\n", CMD_NAME);
    send_to_char(buf2, ch);
    return;
  }

  for (obj = ch->carrying; obj; obj = obj->next_content)
    if (GET_OBJ_TYPE(obj) == ITEM_MONEY && GET_OBJ_VAL(obj, 1) && isname(arg, obj->name))
      break;

  if (obj) {
    generic_find(buf, FIND_OBJ_INV | FIND_OBJ_ROOM, ch, &tmp_char, &corpse);
    if (!corpse)
      act("Use $p on what?", FALSE, ch, obj, 0, TO_CHAR);
    else if (GET_OBJ_VAL(obj, 2) == 1)
      send_to_char("You can't use that type of credstick.\r\n", ch);
    else if (!GET_OBJ_VAL(obj, 4) || belongs_to(ch, obj))
      send_to_char("And why would you need to do that?\r\n", ch);
    else if (!IS_SET(GET_OBJ_EXTRA(corpse), ITEM_CORPSE))
      send_to_char("And how, praytell, would that work?\r\n", ch);
    else if (GET_OBJ_VAL(obj, 3) || GET_OBJ_VAL(obj, 4) != GET_OBJ_VAL(corpse, 5)) {
      if (GET_OBJ_VAL(obj, 2) == 2) {
        act("You press $p against its thumb, but the diplay flashes red.",
            FALSE, ch, obj, 0, TO_CHAR);
        act("$n holds $p against $P's thumb.", TRUE, ch, obj, corpse, TO_ROOM);
      } else {
        act("After scanning the retina, $p's display flashes red.", FALSE,
            ch, obj, 0, TO_CHAR);
        act("$n scans $P's retina with $p.", TRUE, ch, obj, corpse, TO_ROOM);
      }
    } else {
      if (GET_OBJ_VAL(obj, 2) == 2) {
        act("You press $p against its thumb, and the diplay flashes green.", FALSE,
            ch, obj, 0, TO_CHAR);
        act("$n holds $p against $P's thumb.", TRUE, ch, obj, corpse, TO_ROOM);
      } else {
        act("After scanning the retina, $p's display flashes green.", FALSE,
            ch, obj, 0, TO_CHAR);
        act("$n scans $P's retina with $p.", TRUE, ch, obj, corpse, TO_ROOM);
      }
      GET_OBJ_VAL(obj, 3) = 0;
      GET_OBJ_VAL(obj, 4) = 0;
    }
    return;
  }

  mag_item = GET_EQ(ch, WEAR_HOLD);

  if (ROOM_FLAGGED(ch->in_room, ROOM_NOMAGIC)) {
    send_to_char("You can't do that here.\r\n", ch);
    return;
  }

  if (!mag_item || !isname(arg, mag_item->name)) {
    switch (subcmd) {
      case SCMD_RECITE:
      case SCMD_QUAFF:
        equipped = 0;
        if (!(mag_item = get_obj_in_list_vis(ch, arg, ch->carrying))) {
          sprintf(buf2, "You don't seem to have %s %s.\r\n", AN(arg), arg);
          send_to_char(buf2, ch);
          return;
        }
        break;
      case SCMD_USE:
        sprintf(buf2, "You don't seem to be holding %s %s.\r\n", AN(arg), arg);
        send_to_char(buf2, ch);
        return;
        break;
      default:
        log("SYSERR: Unknown subcmd passed to do_use");
        return;
        break;
    }
  }
  switch (subcmd) {
    case SCMD_QUAFF:
      if (GET_OBJ_TYPE(mag_item) != ITEM_POTION) {
        send_to_char("You can only quaff potions.\r\n", ch);
        return;
      }
      if (GET_OBJ_SPEC(mag_item) && GET_OBJ_SPEC(mag_item) == anticoagulant) {
        act("You quaff $p.", FALSE, ch, mag_item, 0, TO_CHAR);
        act("$n quaffs $p.", FALSE, ch, mag_item, 0, TO_ROOM);
        for (obj = ch->bioware; obj; obj = obj->next_content)
          if (GET_OBJ_VAL(obj, 2) == 0)
            break;
        if (obj) {
          GET_OBJ_VAL(obj, 5) = 36;
          GET_OBJ_VAL(obj, 6) = 0;
        }
        extract_obj(mag_item);
      }
      break;
    case SCMD_RECITE:
      if (GET_OBJ_TYPE(mag_item) != ITEM_SCROLL) {
        send_to_char("You can only recite scrolls.\r\n", ch);
        return;
      }
      break;
    case SCMD_USE:
      if ((GET_OBJ_TYPE(mag_item) != ITEM_WAND) && (GET_OBJ_TYPE(mag_item) != ITEM_STAFF)) {
        send_to_char("You can't seem to figure out how to use it.\r\n", ch);
        return;
      }
      break;
  }
  obj_magic(ch, mag_item, buf);
}

ACMD(do_wimpy)
{
  int wimp_lev;

  one_argument(argument, arg);

  if (!*arg) {
    if (GET_WIMP_LEV(ch)) {
      sprintf(buf, "Your current wimp level is %d hit points.\r\n",
              GET_WIMP_LEV(ch));
      send_to_char(buf, ch);
      return;
    } else {
      send_to_char("At the moment, you're not a wimp.  (sure, sure...)\r\n", ch);
      return;
    }
  }
  if (isdigit(*arg)) {
    if ((wimp_lev = atoi(arg))) {
      if (wimp_lev < 0)
        send_to_char("Heh, heh, heh.. we are jolly funny today, eh?\r\n", ch);
      else if (wimp_lev > (int)(GET_MAX_PHYSICAL(ch) / 100))
        send_to_char("That doesn't make much sense, now does it?\r\n", ch);
      else if (wimp_lev > ((int)(GET_MAX_PHYSICAL(ch) / 100) >> 1))
        send_to_char("You can't set your wimp level above half your hit points.\r\n", ch);
      else {
        sprintf(buf, "Okay, you'll wimp out if you drop below %d hit points.\r\n",
                wimp_lev);
        send_to_char(buf, ch);
        GET_WIMP_LEV(ch) = wimp_lev;
      }
    } else {
      send_to_char("Okay, you'll now tough out fights to the bitter end.\r\n", ch);
      GET_WIMP_LEV(ch) = 0;
    }
  } else
    send_to_char("Specify at how many hit points you want to wimp out at. (0 to disable)\r\n", ch);

  return;

}

ACMD(do_display)
{
  struct char_data *tch;
  unsigned int i;

  if (IS_NPC(ch) && !ch->desc->original) {
    send_to_char("Monsters don't need displays.  Go away.\r\n", ch);
    return;
  } else tch = (ch->desc->original ? ch->desc->original : ch);

  skip_spaces(&argument);
  delete_doubledollar(argument);

  if (!*argument) {
    send_to_char(ch, "Current prompt:\r\n%s\r\n", GET_PROMPT(tch));
    return;
  } else if (strlen(argument) > LINE_LENGTH - 1) {
    send_to_char(ch, "Customized prompts are limited to %d characters.\r\n",
                 LINE_LENGTH - 1);
    return;
  } else {
    for (i = 0; i < strlen(argument); i++)
      if (argument[i] == '\\' && argument[i+1] == 'n')
      {
        argument[i] = '\r';
        i++;
        argument[i] = '\n';
      }
    delete [] GET_PROMPT(tch);
    GET_PROMPT(tch) = str_dup(argument);
    send_to_char(OK, ch);
  }
}

ACMD(do_gen_write)
{
  FILE *fl;
  char *tmp, *filename;
  struct stat fbuf;
  extern int max_filesize;
  time_t ct;

  switch (subcmd) {
    case SCMD_BUG:
      filename = BUG_FILE;
      break;
    case SCMD_TYPO:
      filename = TYPO_FILE;
      break;
    case SCMD_IDEA:
      filename = IDEA_FILE;
      break;
    default:
      return;
  }

  ct = time(0);
  tmp = asctime(localtime(&ct));

  if (IS_NPC(ch) && !ch->desc) {
    send_to_char("Monsters can't have ideas - Go away.\r\n", ch);
    return;
  }

  skip_spaces(&argument);
  delete_doubledollar(argument);

  if (!*argument) {
    send_to_char("That must be a mistake...\r\n", ch);
    return;
  }
  sprintf(buf, "%s %s: %s", (ch->desc->original ? GET_NAME(ch->desc->original) : GET_NAME(ch)),
          CMD_NAME, argument);
  mudlog(buf, ch, LOG_MISCLOG, FALSE);

  if (stat(filename, &fbuf) < 0) {
    perror("Error statting file");
    return;
  }
  if (fbuf.st_size >= max_filesize) {
    send_to_char("Sorry, the file is full right now.. try again later.\r\n", ch);
    return;
  }
  if (!(fl = fopen(filename, "a"))) {
    perror("do_gen_write");
    send_to_char("Could not open the file.  Sorry.\r\n", ch);
    return;
  }
  fprintf(fl, "%-8s (%6.6s) [%5d] %s\n", (ch->desc->original ? GET_NAME(ch->desc->original) : GET_NAME(ch)),
          (tmp + 4), world[ch->in_room].number, argument);
  fclose(fl);
  send_to_char("Okay.  Thanks!\r\n", ch);
}

#define PRF_TOG_CHK(ch,flag) ((TOGGLE_BIT(PRF_FLAGS(ch), (flag))) & (flag))

char *tog_messages[][2] = {
  {"You should never see this.  Use the \"bug\" command to report!\r\n",
   "You are afk.\r\n"},
  {"Autoexits disabled.\r\n",
  "Autoexits enabled.\r\n"},
  {"Compact mode off.\r\n",
   "Compact mode on.\r\n"},
  {"You will now have your communication repeated.\r\n",
   "You will no longer have your communication repeated.\r\n"},
  {"Fightgag off.\r\n",
   "Fightgag on.\r\n"},                               // 5
  {"HolyLight mode off.\r\n",
   "HolyLight mode on.\r\n"},
  {"Movegag off.\r\n",
   "Movegag on.\r\n"},
  {"You can now hear radio communications.\r\n",
   "You are now deaf to radio communications.\r\n"},
  {"Nohassle disabled.\r\n",
   "Nohassle enabled.\r\n"},                          // 10
  {"You can now hear the newbie channel again.\r\n",
   "You are now deaf to the newbie channel.\r\n"},
  {"You can now hear shouts.\r\n",
   "You are now deaf to shouts.\r\n"},
  {"You can now hear tells.\r\n",
   "You are now deaf to tells.\r\n"},
  {"You can now hear the Wiz-channel.\r\n",
   "You are now deaf to the Wiz-channel.\r\n"},       // 15
  {"But you are already a pk'er!\r\n",
   "You're now a pk'er...better watch your back!\r\n"},
  {"You are no longer on a job.\r\n",
   "Okay, consider yourself hired!\r\n"},
  {"You will no longer see the room flags.\r\n",
   "You will now see the room flags.\r\n"},
  {"Mud Sound Protocol triggers disabled.\r\n",
   "Mud Sound Protocol triggers enabled.\r\n"},
  {"Details on rolls disabled.\r\n",
   "Details on rolls enabled.\r\n"},
  {"You can now hear the OOC channel.\r\n",
   "You are now deaf to the OOC channel.\r\n"},
  {"Auto-invisibility disabled.\r\n",
   "Auto-invisibility enabled.\r\n"}
};

ACMD(do_toggle)
{
  long result = 0;
  int mode = 0;

  if (IS_NPC(ch)) {
    send_to_char("You cannot view or change your preferences in your current form.\r\n", ch);
    return;
  }
  skip_spaces(&argument);
  if (!*argument) {
    if (GET_WIMP_LEV(ch) == 0)
      strcpy(buf2, "OFF");
    else sprintf(buf2, "%-3d", GET_WIMP_LEV(ch));
    if (GET_LEVEL(ch) < LVL_LEGEND)
      sprintf(buf, "       Fightgag: %-3s              NoOOC: %-3s               Hired: %-3s\r\n"
                   "        Movegag: %-3s            Compact: %-3s               AutoExits: %-3s\r\n"
                   "         NoTell: %-3s            NoShout: %-3s               Echo: %-3s\r\n"
                   "           Pker: %-3s                MSP: %-3s               Wimp Level: %-3s\r\n"
                   "    Color Level: %-8s\r\n",
              ONOFF(PRF_FLAGGED(ch, PRF_FIGHTGAG)), ONOFF(PRF_FLAGGED(ch, PRF_NOOOC)),
              YESNO(PRF_FLAGGED(ch, PRF_QUEST)), ONOFF(PRF_FLAGGED(ch, PRF_MOVEGAG)),
              ONOFF(PRF_FLAGGED(ch, PRF_COMPACT)), ONOFF(PRF_FLAGGED(ch, PRF_AUTOEXIT)),
              ONOFF(PRF_FLAGGED(ch, PRF_NOTELL)), ONOFF(PRF_FLAGGED(ch, PRF_DEAF)),
              ONOFF(!PRF_FLAGGED(ch, PRF_NOREPEAT)), YESNO(PRF_FLAGGED(ch, PRF_PKER)),
              ONOFF(PRF_FLAGGED(ch, PRF_MSP)), buf2, ctypes[COLOR_LEV(ch)]);
    else
      sprintf(buf, "       Fightgag: %-3s              NoOOC: %-3s               Quest: %-3s\r\n"
                   "        Movegag: %-3s            Compact: %-3s               AutoExits: %-3s\r\n"
                   "         NoTell: %-3s            NoShout: %-3s               Echo: %-3s\r\n"
                   "            Wiz: %-3s             Newbie: %-3s               Nohassle: %-3s\r\n"
                   "      Holylight: %-3s          Roomflags: %-3s               Pker: %-3s\r\n"
                   "          Radio: %-3s                MSP: %-3s               Wimp Level: %-3s\r\n"
                   "    Color Level: %-8s     Autoinvis: %-3s\r\n",
              ONOFF(PRF_FLAGGED(ch, PRF_FIGHTGAG)), ONOFF(PRF_FLAGGED(ch, PRF_NOOOC)),
              YESNO(PRF_FLAGGED(ch, PRF_QUEST)), ONOFF(PRF_FLAGGED(ch, PRF_MOVEGAG)),
              ONOFF(PRF_FLAGGED(ch, PRF_COMPACT)), ONOFF(PRF_FLAGGED(ch, PRF_AUTOEXIT)),
              ONOFF(PRF_FLAGGED(ch, PRF_NOTELL)), ONOFF(PRF_FLAGGED(ch, PRF_DEAF)),
              ONOFF(!PRF_FLAGGED(ch, PRF_NOREPEAT)), ONOFF(!PRF_FLAGGED(ch, PRF_NOWIZ)),
              ONOFF(!PRF_FLAGGED(ch, PRF_NONEWBIE)), ONOFF(PRF_FLAGGED(ch, PRF_NOHASSLE)),
              ONOFF(PRF_FLAGGED(ch, PRF_HOLYLIGHT)), ONOFF(PRF_FLAGGED(ch, PRF_ROOMFLAGS)),
              YESNO(PRF_FLAGGED(ch, PRF_PKER)), ONOFF(PRF_FLAGGED(ch, PRF_NORADIO)),
              ONOFF(PRF_FLAGGED(ch, PRF_MSP)), buf2, ctypes[COLOR_LEV(ch)],
	      ONOFF(PRF_FLAGGED(ch, PRF_AUTOINVIS)));
    send_to_char(buf, ch);
  } else {
    if (is_abbrev(argument, "afk"))
      result = PRF_TOG_CHK(ch, PRF_AFK);
    else if (is_abbrev(argument, "autoexits")) {
      result = PRF_TOG_CHK(ch, PRF_AUTOEXIT);
      mode = 1;
    } else if (is_abbrev(argument, "compact")) {
      result = PRF_TOG_CHK(ch, PRF_COMPACT);
      mode = 2;
    } else if (is_abbrev(argument, "echo")) {
      result = PRF_TOG_CHK(ch, PRF_NOREPEAT);
      mode = 3;
    } else if (is_abbrev(argument, "fightgag")) {
      result = PRF_TOG_CHK(ch, PRF_FIGHTGAG);
      mode = 4;
    } else if (is_abbrev(argument, "holylight") && GET_LEVEL(ch) >= LVL_LEGEND) {
      result = PRF_TOG_CHK(ch, PRF_HOLYLIGHT);
      mode = 5;
    } else if (is_abbrev(argument, "movegag")) {
      result = PRF_TOG_CHK(ch, PRF_MOVEGAG);
      mode = 6;
    } else if (is_abbrev(argument, "noradio") && GET_LEVEL(ch) >= LVL_LEGEND) {
      result = PRF_TOG_CHK(ch, PRF_NORADIO);
      mode = 7;
    } else if (is_abbrev(argument, "nohassle") && GET_LEVEL(ch) >= LVL_LEGEND) {
      result = PRF_TOG_CHK(ch, PRF_NOHASSLE);
      mode = 8;
    } else if (is_abbrev(argument, "nonewbie") && GET_LEVEL(ch) >= LVL_LEGEND) {
      result = PRF_TOG_CHK(ch, PRF_NONEWBIE);
      mode = 9;
    } else if (is_abbrev(argument, "noshout")) {
      result = PRF_TOG_CHK(ch, PRF_DEAF);
      mode = 10;
    } else if (is_abbrev(argument, "notell")) {
      result = PRF_TOG_CHK(ch, PRF_NOTELL);
      mode = 11;
    } else if (is_abbrev(argument, "nowiz") && GET_LEVEL(ch) >= LVL_LEGEND) {
      result = PRF_TOG_CHK(ch, PRF_NOWIZ);
      mode = 12;
    } else if (is_abbrev(argument, "ooc")) {
      result = PRF_TOG_CHK(ch, PRF_NOOOC);
      mode = 18;
    } else if (is_abbrev(argument, "pk")) {
      if (PLR_FLAGGED(ch, PLR_NEWBIE)) {
        send_to_char("You are not yet able to become a pk'er.\r\n", ch);
        return;
      }
      if (PRF_FLAGGED(ch, PRF_PKER)) {
        send_to_char("You are already a pk'er!\r\n", ch);
        return;
      }
      if (!PRF_FLAGGED(ch, PRF_PKER))
        SET_BIT(PRF_FLAGS(ch), PRF_PKER);
      mode = 13;
      result = 1;
    } else if (is_abbrev(argument, "hired")) {
      result = PRF_TOG_CHK(ch, PRF_QUEST);
      mode = 14;
    } else if (GET_LEVEL(ch) >= LVL_LEGEND && is_abbrev(argument, "rolls")) {
      result = PRF_TOG_CHK(ch, PRF_ROLLS);
      mode = 17;
    } else if (is_abbrev(argument, "roomflags") && GET_LEVEL(ch) >= LVL_BUILDER) {
      result = PRF_TOG_CHK(ch, PRF_ROOMFLAGS);
      mode = 15;
    } else if (is_abbrev(argument, "msp")) {
      result = PRF_TOG_CHK(ch, PRF_MSP);
      mode = 16;
    } else if (is_abbrev(argument, "autoinvis")) {
      result = PRF_TOG_CHK(ch, PRF_AUTOINVIS);
      mode = 19;
    } else {
      send_to_char("That is not a valid toggle option.\r\n", ch);
      return;
    }
    if (result)
      send_to_char(tog_messages[mode][1], ch);
    else send_to_char(tog_messages[mode][0], ch);
  }
}

ACMD(do_slowns)
{
  extern int nameserver_is_slow;
  int result = (nameserver_is_slow = !nameserver_is_slow);

  if (result)
    send_to_char("Nameserver_is_slow changed to YES; sitenames will no longer be resolved.\r\n", ch);
  else send_to_char("Nameserver_is_slow changed to NO; IP addresses will now be resolved.\r\n", ch);
}

ACMD(do_ident)
{
  int result = (ident = !ident);

  if (result)
    send_to_char("Ident changed to YES;  remote usernames lookups will be attempted.\r\n", ch);
  else send_to_char("Ident changed to NO;  remote username lookups will not be attempted.\r\n", ch);
}

/* Assumes that *argument does start with first letter of chopped string */
ACMD(do_skills)
{
   int i;
   if (subcmd == SCMD_SKILLS) {
     sprintf(buf, "You know the following skills:\r\n");
     for (i = SKILL_STEALTH; i < SKILL_PERCEPTION; i++)
       if ((GET_SKILL(ch, i)) > 0) {
         sprintf(buf2, "%-20s %-17s\r\n", spells[i], how_good(GET_SKILL(ch, i)));
         strcat(buf, buf2);
       }
   } else {
     if (!IS_NPC(ch) && GET_TRADITION(ch) != TRAD_ADEPT) {
       send_to_char("You do not have any abilities.\r\n", ch);
       return;
     }
     sprintf(buf, "You know the following abilities:\r\n");
     for (i = SKILL_PERCEPTION; i <= SKILL_RESISTANCE; i++)
       if (GET_SKILL(ch, i) > 0) {
         sprintf(buf2, "%-20s", spells[i]);
         if (i == SKILL_COMBAT_SENSE || i == SKILL_REFLEXES || i == SKILL_RESISTANCE)
           sprintf(buf2, "%s +%d\r\n", buf2, GET_SKILL(ch, i));
         else if (i == SKILL_PERCEPTION)
           strcat(buf2, "\r\n");
         else if (i == SKILL_KILL_HANDS)
           sprintf(buf2, "%s %-8s\r\n", buf2, wound_name[MIN(4, GET_SKILL(ch, i))]);
         strcat(buf, buf2);
      }
   }
   page_string(ch->desc, buf, 1);
}

extern char *spell_category[];
extern char *wound_arr[];

ACMD(do_spells)
{
  if (GET_LEVEL(ch) < LVL_LEGEND && (GET_MAG(ch) == 0
   || GET_TRADITION(ch) == TRAD_MUNDANE) ) {
    send_to_char("You are but a mundane, sorry.\r\n", ch);
    return;
  }

  if (!ch->spells) {
    send_to_char("You don't know any spells.\r\n", ch);
    return;
  }

  sprintf(buf, "Spell                          Force   Drain   Category\r\n");
  for (register spell_t *temp = ch->spells; temp; temp = temp->next)
    {
      check_spell_drain( ch, temp );
      sprintf(buf2, "%-30s  %2d     %2d%s     %s\r\n",
	      temp->name,
	      temp->force,
	      MAX(2, (temp->force >> 1) + DRAIN_POWER(temp->drain)),
	      (DRAIN_LEVEL(temp->drain) == 0
	       ? "V"
	       : wound_arr[DRAIN_LEVEL(temp->drain)]),
	      spell_category[temp->category]);
      strcat(buf, buf2);
    }

  strcat(buf, "\r\n");
  page_string(ch->desc, buf, 1);
}

ACMD(do_operate)
{
  struct char_data *vict;
  struct obj_data *cyber, *check;

  if ((!IS_NPC(ch) && !access_level(ch, LVL_PRESIDENT)) || IS_NPC(ch) ||
      GET_SKILL(ch, SKILL_CYBERSURGERY) < 1) {
     send_to_char("You'd better call a REAL doctor to do that!\r\n", ch);
     return;
  }

  half_chop(argument, buf1, buf2);

  if (!*buf1) {
    send_to_char("Who do you want to operate on?\r\n", ch);
    return;
  }

  if (!(vict = get_char_room_vis(ch, buf1))) {
    send_to_char("You can't seem to find that person here.\r\n", ch);
    return;
  }

  if (IS_NPC(vict) && (!access_level(ch, LVL_OWNER))) {
    send_to_char("You can't operate on a mob!\r\n", ch);
    return;
  }

  if ((ch == vict) && (!access_level(ch, LVL_OWNER))) {
    send_to_char("You can't operate on yourself!\r\n", ch);
    return;
  }

  if (!*buf2) {
    send_to_char("You have to surgically install something!\r\n", ch);
    return;
  } else if (!(cyber = get_obj_in_list_vis(ch, buf2, ch->carrying))) {
    send_to_char("You don't seem to have that item.\r\n", ch);
    return;
  }

  if (GET_OBJ_TYPE(cyber) != ITEM_CYBERWARE && GET_OBJ_TYPE(cyber) != ITEM_BIOWARE) {
    send_to_char("That's not cyber- or bioware!\r\n", ch);
    return;
  }

  if (GET_OBJ_TYPE(cyber) == ITEM_CYBERWARE) {
    if ((vict->real_abils.ess - ((GET_TOTEM(vict) == TOTEM_EAGLE) ?
        GET_OBJ_VAL(cyber, 1) << 1 : GET_OBJ_VAL(cyber, 1))) < 0) {
      act("$n refuses to perform cybersurgery when $e realizes it would kill you.", FALSE, ch, 0, vict, TO_VICT);
      act("You realize performing cybersurgery on $N would kill $M!", FALSE, ch, 0, vict, TO_CHAR);
      return;
    }
    for (check = vict->cyberware; check != NULL; check = check->next_content) {
      if ((GET_OBJ_VNUM(check) == GET_OBJ_VNUM(cyber))) {
        act("$n already has that installed!", FALSE, vict, 0, ch, TO_VICT);
        return;
      }
      if (GET_OBJ_VAL(check, 2) == GET_OBJ_VAL(cyber, 2)) {
        act("$n already has a similar piece of cyberware!", FALSE, vict, 0, ch, TO_VICT);
        return;
      }
    }
    if (GET_OBJ_VAL(cyber, 2) == 23 || GET_OBJ_VAL(cyber, 2) == 30 || GET_OBJ_VAL(cyber, 2) == 20)
      for (check = vict->bioware; check; check = check->next_content) {
        if (GET_OBJ_VAL(check, 2) == 2 && GET_OBJ_VAL(cyber, 2) == 23) {
          act("$p is not compatible with orthoskin!", FALSE, ch, cyber, 0, TO_CHAR);
          return;
        }
        if (GET_OBJ_VAL(check, 2) == 8 && GET_OBJ_VAL(cyber, 2) == 30) {
          act("$p is not compatible with synaptic accelerators!", FALSE, ch, cyber, 0, TO_CHAR);
          return;
        }
        if (GET_OBJ_VAL(check, 2) == 10 && GET_OBJ_VAL(cyber, 2) == 20) {
          act("$p is not compatible with muscle augmentation!", FALSE, ch, cyber, 0, TO_CHAR);
          return;
        }
      }
    obj_from_char(cyber);
    obj_to_cyberware(cyber, vict);
  } else {
    if (GET_INDEX(vict) < GET_OBJ_VAL(cyber, 1)) {
      act("$N does not have enough body index for $p.", FALSE, ch, cyber, vict, TO_CHAR);
      return;
    }
    for (check = vict->bioware; check != NULL; check = check->next_content) {
      if ((GET_OBJ_VNUM(check) == GET_OBJ_VNUM(cyber))) {
        act("$n already has that piece of bioware!", FALSE, vict, 0, ch, TO_VICT);
        return;
      }
      if (GET_OBJ_VAL(check, 2) == GET_OBJ_VAL(cyber, 2)) {
        act("$n already has a similar piece of bioware!", FALSE, vict, 0, ch, TO_VICT);
        return;
      }
    }
    if (GET_OBJ_VAL(cyber, 2) == 2 || GET_OBJ_VAL(cyber, 2) == 8 || GET_OBJ_VAL(cyber, 2) == 10)
      for (check = vict->cyberware; check; check = check->next_content) {
        if (GET_OBJ_VAL(check, 2) == 23 && GET_OBJ_VAL(cyber, 2) == 2) {
          send_to_char("Orthoskin is not compatible with any form of dermal plating!\r\n", ch);
          return;
        }
        if (GET_OBJ_VAL(check, 2) == 30 && GET_OBJ_VAL(cyber, 2) == 8) {
          send_to_char("Synaptic accelerators are not compatible with boosted/wired reflexes!\r\n", ch);
          return;
        }
        if (GET_OBJ_VAL(check, 2) == 20 && GET_OBJ_VAL(cyber, 2) == 10) {
          send_to_char("Muscle augmentation is not compatible with muscle replacement!\r\n", ch);
          return;
        }
      }
    if (GET_OBJ_VAL(cyber, 2) == 0) {
      GET_OBJ_VAL(cyber, 5) = 12;
      GET_OBJ_VAL(cyber, 6) = 0;
    }
    obj_from_char(cyber);
    obj_to_bioware(cyber, vict);
  }

  act("You delicately install $p into $N's body.", FALSE, ch, cyber, vict, TO_CHAR);
  act("$n performs a delicate procedure on $N.", FALSE, ch, 0, vict, TO_NOTVICT);
  act("$n delicately installs $p into your body.", FALSE, ch, cyber, vict, TO_VICT);
  GET_PHYSICAL(vict) = 100;
  GET_MENTAL(vict) = 0;
}

struct obj_data * find_clip(struct obj_data *gun, struct obj_data *i)
{
  for (; i; i = i->next_content)
    {
      if ((GET_OBJ_TYPE(i) == ITEM_GUN_CLIP)
	  && (GET_OBJ_VAL(i, 0) == GET_OBJ_VAL(gun, 5))
	  && (GET_OBJ_VAL(i, 1) == (GET_OBJ_VAL(gun, 3) - TYPE_HIT)))
	{
	  return i;
	}
      if (i->contains)
	{
	  struct obj_data *found;
	  found = find_clip(gun, i->contains);
	  if ( found )
	    return found;
	}
    }
  return NULL;
}


ACMD(do_reload)
{
   struct obj_data *i, *gun = NULL;
   bool found = FALSE;
   int n, def = 0;

   any_one_arg(argument, buf);

   if (!*buf) {
     if ((i = GET_EQ(ch, WEAR_WIELD)) && GET_OBJ_TYPE(i) == ITEM_WEAPON &&
         GET_OBJ_VAL(i, 5) > 0 && GET_WIELDED(ch, 0) && !GET_OBJ_VAL(i, 6))
       gun = i;
     else if ((i = GET_EQ(ch, WEAR_HOLD)) && GET_OBJ_TYPE(i) == ITEM_WEAPON &&
              GET_OBJ_VAL(i, 5) > 0 && GET_WIELDED(ch, 1) && !GET_OBJ_VAL(i, 6))
       gun = i;
     else {
       for (n = 0; n < (NUM_WEARS - 1) && !gun; n++)
         if (GET_EQ(ch, n) && GET_OBJ_TYPE(GET_EQ(ch, n)) == ITEM_WEAPON &&
             GET_OBJ_VAL(GET_EQ(ch, n), 5) > 0 && !GET_OBJ_VAL(GET_EQ(ch, n), 6))
           gun = GET_EQ(ch, n);
       for (i = ch->carrying; i && !gun; i = i->next_content)
         if (GET_OBJ_TYPE(i) == ITEM_WEAPON && GET_OBJ_VAL(i, 5) > 0 &&
             !GET_OBJ_VAL(i, 6))
           gun = i;
     }
     if (!gun) {
       send_to_char("No weapons in need of reloading found.\r\n", ch);
       return;
     }
     def = 1;
   } else if (!(gun = get_object_in_equip_vis(ch, buf, ch->equipment, &n)))
     if (!(gun = get_obj_in_list_vis(ch, buf, ch->carrying))) {
       send_to_char(ch, "You don't have a '%s'.\r\n", buf);
       return;
     }

   if (GET_OBJ_TYPE(gun) != ITEM_WEAPON
       || GET_OBJ_VAL(gun, 3) <= TYPE_HAND_GRENADE
       || GET_OBJ_VAL(gun, 5) < 1) {
     send_to_char("That's not a reloadable weapon!\r\n", ch);
     return;
   }

   if (GET_OBJ_VAL(gun, 6) == GET_OBJ_VAL(gun, 5))
     {
       act("$p is already loaded to maximum capacity!", FALSE, ch, gun, 0, TO_CHAR);
       return;
     }

#if RELOAD_FROM_INV_ONLY
   for (i = ch->carrying; i; i = i->next_content)
     {
       if ((GET_OBJ_TYPE(i) == ITEM_GUN_CLIP)
	   && (GET_OBJ_VAL(i, 0) == GET_OBJ_VAL(gun, 5))
	   && (GET_OBJ_VAL(i, 1) == (GET_OBJ_VAL(gun, 3) - TYPE_HIT)))
	 {
	   found = TRUE;
	   break;
	 }
     }

   if (!found) {
     act("You can't find a clip that would work in $p.", FALSE, ch, gun, 0, TO_CHAR);
     return;
   }
#else
   i = find_clip( gun, ch->carrying );
   if (!i) {
     act("You can't find a clip that would work in $p.",
	 FALSE, ch, gun, 0, TO_CHAR);
     return;
   }
#endif

   /* remove the object from inventory and mud, then reset ammo on weapon */
   extract_obj(i);

#if 0
   GET_OBJ_VAL(gun, 6) = GET_OBJ_VAL(gun, 5) + (FIGHTING(ch) ? 1 : 0);
#else
   GET_OBJ_VAL(gun, 6) = GET_OBJ_VAL(gun, 5);
#endif

   if (def)
     act("Reloaded $p.", FALSE, ch, gun, 0, TO_CHAR);
   else
     send_to_char("Reloaded.\r\n", ch);
   return;
}

ACMD(do_attach) {
  struct obj_data *item = NULL, *item2 = NULL;
  int where, j;
  bool modified = FALSE;

  argument = any_one_arg(argument, buf1);
  argument = one_argument(argument, buf2);

  if (!*buf1 || !*buf2) {
    send_to_char("You need to attach something to something else.\r\n", ch);
    return;
  }

  if (!(item = get_obj_in_list_vis(ch, buf1, ch->carrying)) ||
      !(item2 = get_obj_in_list_vis(ch, buf2, ch->carrying))) {
        send_to_char("You don't seem to have that item.\r\n", ch);
        return;
  }

  if ((GET_OBJ_TYPE(item) != ITEM_GUN_ACCESSORY) || (GET_OBJ_TYPE(item2) != ITEM_WEAPON)) {
     send_to_char("You can only attach gun accessories to a gun.\r\n", ch);
     return;
  }

  if (((GET_OBJ_VAL(item, 0) == 0) && (GET_OBJ_VAL(item2, 7) > 0)) ||
      ((GET_OBJ_VAL(item, 0) == 1) && (GET_OBJ_VAL(item2, 8) > 0)) ||
      ((GET_OBJ_VAL(item, 0) == 2) && (GET_OBJ_VAL(item2, 9) > 0))) {
     send_to_char("You cannot mount more than one accessory to the same place.\r\n", ch);
     return;
  }

  if (((GET_OBJ_VAL(item, 0) == 0) && (GET_OBJ_VAL(item2, 7) == -1)) ||
      ((GET_OBJ_VAL(item, 0) == 1) && (GET_OBJ_VAL(item2, 8) == -1)) ||
      ((GET_OBJ_VAL(item, 0) == 2) && (GET_OBJ_VAL(item2, 9) == -1))) {
     sprintf(buf, "%s doesn't seem to fit on %s.\r\n", CAP(item->short_description), item2->short_description);
     send_to_char(buf, ch);
     return;
  }

  for (j = 0; (j < MAX_OBJ_AFFECT) && !modified; ++j) {
    if (!(item2->affected[j].modifier)) {
       item2->affected[j].location = item->affected[0].location;
       item2->affected[j].modifier = item->affected[0].modifier;
       modified = TRUE;
    }
  }

  if (!modified) {
    sprintf(buf, "You seem unable to connect %s to %s.\r\n", item->short_description,
           item2->short_description);
    send_to_char(buf, ch);
    return;
  }

  if (GET_OBJ_VAL(item, 0) == 0)
    GET_OBJ_VAL(item2, 7) = GET_OBJ_VNUM(item);
  else if (GET_OBJ_VAL(item, 0) == 1)
    GET_OBJ_VAL(item2, 8) = GET_OBJ_VNUM(item);
  else if (GET_OBJ_VAL(item, 0) == 2)
    GET_OBJ_VAL(item2, 9) = GET_OBJ_VNUM(item);

  GET_OBJ_WEIGHT(item2) += GET_OBJ_WEIGHT(item);
  GET_OBJ_COST(item2) += GET_OBJ_COST(item);
  if (IS_SET(item->obj_flags.bitvector, AFF_LASER_SIGHT))
    SET_BIT(item2->obj_flags.bitvector, AFF_LASER_SIGHT);
  if (IS_SET(item->obj_flags.bitvector, AFF_VISION_MAG_1))
    SET_BIT(item2->obj_flags.bitvector, AFF_VISION_MAG_1);
  if (IS_SET(item->obj_flags.bitvector, AFF_VISION_MAG_2))
    SET_BIT(item2->obj_flags.bitvector, AFF_VISION_MAG_2);
  if (IS_SET(item->obj_flags.bitvector, AFF_VISION_MAG_3))
    SET_BIT(item2->obj_flags.bitvector, AFF_VISION_MAG_3);

  where = GET_OBJ_VAL(item, 0);

  sprintf(buf, "You attach $p to the %s of $P.",
          (where == 0 ? "top" : (where == 1 ? "barrel" : "bottom")));
  act(buf, TRUE, ch, item, item2, TO_CHAR);

  sprintf(buf, "$n attaches $p to the %s of $P.",
          (where == 0 ? "top" : (where == 1 ? "barrel" : "bottom")));
  act(buf, TRUE, ch, item, item2, TO_ROOM);

  obj_from_char(item);
  extract_obj(item);

  return;
}

ACMD(do_unattach) {
  struct obj_data *item, *gun;
  int i, j, r_num;
  bool found = FALSE, modified = FALSE;

  argument = any_one_arg(argument, buf1);
  argument = one_argument(argument, buf2);

  if (!*buf1 || !*buf2) {
    send_to_char("You need to unattach something from something else.\r\n", ch);
    return;
  }

  if (!(gun = get_obj_in_list_vis(ch, buf2, ch->carrying))) {
     send_to_char("You don't seem to have that item.\r\n", ch);
     return;
  }

  if (GET_OBJ_TYPE(gun) != ITEM_WEAPON) {
     send_to_char("You can only unattach accessories from weapons.\r\n", ch);
     return;
  }

  for (i = 7;i < 10 && !found;++i)
     if (GET_OBJ_VAL(gun, i) > 0 && isname(buf1, short_object(GET_OBJ_VAL(gun, i), 1)))
       found = TRUE;

  /* subtract one from i to make it point to correct value */
  i--;

  if (!found) {
    act("That doesn't seem to be attached to $p.", FALSE, ch, gun, 0, TO_CHAR);
    return;
  }

  if ((r_num = real_object(GET_OBJ_VAL(gun, i))) < 0) {
    send_to_char("You accidentally break it as you remove it!\r\n", ch);
    log("SYSERR: Trying to unattach nonexistant object from weapon");
    GET_OBJ_VAL(gun, i) = 0;
    return;
  }

  item = read_object(GET_OBJ_VAL(gun, i), VIRTUAL);
  if (GET_OBJ_VAL(item, 1) == 3) {
    act("You can't remove $p from $P!", FALSE, ch, item, gun, TO_CHAR);
    extract_obj(item);
    return;
  }
  obj_to_char(item, ch);
  GET_OBJ_VAL(gun, i) = 0;
  GET_OBJ_WEIGHT(gun) -= GET_OBJ_WEIGHT(item);
  GET_OBJ_COST(gun) = MAX(GET_OBJ_COST(gun) - GET_OBJ_COST(item), 50);

  if (IS_SET(gun->obj_flags.bitvector, AFF_LASER_SIGHT) && IS_SET(item->obj_flags.bitvector, AFF_LASER_SIGHT))
    REMOVE_BIT(gun->obj_flags.bitvector, AFF_LASER_SIGHT);
  if (IS_SET(gun->obj_flags.bitvector, AFF_VISION_MAG_1) && IS_SET(item->obj_flags.bitvector, AFF_VISION_MAG_1))
    REMOVE_BIT(gun->obj_flags.bitvector, AFF_VISION_MAG_1);
  if (IS_SET(gun->obj_flags.bitvector, AFF_VISION_MAG_2) && IS_SET(item->obj_flags.bitvector, AFF_VISION_MAG_2))
    REMOVE_BIT(gun->obj_flags.bitvector, AFF_VISION_MAG_2);
  if (IS_SET(gun->obj_flags.bitvector, AFF_VISION_MAG_3) && IS_SET(item->obj_flags.bitvector, AFF_VISION_MAG_3))
    REMOVE_BIT(gun->obj_flags.bitvector, AFF_VISION_MAG_3);

  for (j = 0;(j < MAX_OBJ_AFFECT) && !modified;++j) {
    if ((gun->affected[j].location == item->affected[0].location) &&
        (gun->affected[j].modifier == item->affected[0].modifier)) {
       gun->affected[j].location = APPLY_NONE;
       gun->affected[j].modifier = 0;
       modified = TRUE;
    }
  }

  act("You unattach $p from $P.", TRUE, ch, item, gun, TO_CHAR);
  act("$n unattaches $p from $P.", TRUE, ch, item, gun, TO_ROOM);
}

ACMD(do_defense)
{
  int val, low, high;
  struct obj_data *one, *two;

  one_argument(argument, buf);

  val = atoi(buf);
  one = (GET_WIELDED(ch, 0) ? GET_EQ(ch, WEAR_WIELD) :
        (struct obj_data *) NULL);
  two = (GET_WIELDED(ch, 1) ? GET_EQ(ch, WEAR_HOLD) :
        (struct obj_data *) NULL);
  if (!one && !two)
    low = MAX(0, GET_COMBAT(ch) - GET_SKILL(ch, SKILL_UNARMED_COMBAT));
  else if (one) {
    if (!GET_SKILL(ch, GET_OBJ_VAL(one, 4)))
      low = GET_SKILL(ch, return_general(GET_OBJ_VAL(one, 4)));
    else low = GET_SKILL(ch, GET_OBJ_VAL(one, 4));
    low = MAX(0, GET_COMBAT(ch) - low);
  } else if (two) {
    if (!GET_SKILL(ch, GET_OBJ_VAL(two, 4)))
      low = GET_SKILL(ch, return_general(GET_OBJ_VAL(two, 4)));
    else low = GET_SKILL(ch, GET_OBJ_VAL(two, 4));
    low = MAX(0, GET_COMBAT(ch) - low);
  } else {
    if (GET_SKILL(ch, GET_OBJ_VAL(one, 4)) <= GET_SKILL(ch, GET_OBJ_VAL(two, 4))) {
      if (!GET_SKILL(ch, GET_OBJ_VAL(one, 4)))
        low = GET_SKILL(ch, return_general(GET_OBJ_VAL(one, 4)));
      else low = GET_SKILL(ch, GET_OBJ_VAL(one, 4));
    } else {
      if (!GET_SKILL(ch, GET_OBJ_VAL(two, 4)))
        low = GET_SKILL(ch, return_general(GET_OBJ_VAL(two, 4)));
      else low = GET_SKILL(ch, GET_OBJ_VAL(two, 4));
    }
    low = MAX(0, GET_COMBAT(ch) - low);
  }
  high = GET_COMBAT(ch);

  if ((val < low) || (val > high)) {
    send_to_char(ch, "The value must be from %d to %d.\r\n", low, high);
    return;
  }

  GET_DEFENSE(ch) = val;
  ch->real_abils.defense_pool = val;
  GET_OFFENSE(ch) = GET_COMBAT(ch) - GET_DEFENSE(ch);
  sprintf(buf1, "Defense is now at %d, offense is now at %d.\r\n", val, GET_OFFENSE(ch));
  send_to_char(buf1, ch);
  return;
}

ACMD(do_learn)
{
  extern spell_t *find_spell(struct char_data *, char *);
  spell_t *spell;
  int counter;
  char spell_name[100];

  if (GET_MAG(ch) < 1) {
    send_to_char("You must have magical ability to learn spells.\r\n", ch);
    return;
  }

  half_chop(argument, buf1, buf2);

  // first, find out if they named the spell or not
  if (!*buf1) {
    send_to_char("You must specify the name of the spell you wish to learn.\r\n", ch);
    return;
  }

  // then find the item named in their inventory
  struct obj_data *formula;
  if (!(formula = get_obj_in_list_vis(ch, buf1, ch->carrying))) {
    send_to_char("You can't seem to find that spell formula.\r\n", ch);
    return;
  }

  // now, make sure it's a spell formula
  if (GET_OBJ_TYPE(formula) != ITEM_SPELL_FORMULA) {
    send_to_char("That's not a spell formula!\r\n", ch);
    return;
  }

#if 0
  if (access_level(ch, LVL_PRESIDENT)) {
    send_to_char("You have no need to learn standard spells.\r\n", ch);
    return;
  }
#endif

  if (GET_TRADITION(ch) != TRAD_HERMETIC && GET_TRADITION(ch) != TRAD_SHAMANIC) {
    send_to_char("You can't learn spells!\r\n", ch);
    return;
  }

  // here we make sure they are learning from the correct formula tradition
  if ((GET_OBJ_VAL(formula, 7) == 0) && (GET_TRADITION(ch) != TRAD_HERMETIC)) {
    send_to_char("You can only learn shaman spells.\r\n", ch);
    return;
  } else if ((GET_OBJ_VAL(formula, 7) == 1) && (GET_TRADITION(ch) != TRAD_SHAMANIC)) {
    send_to_char("You can only learn mage spells.\r\n", ch);
    return;
  }

  if (GET_LEVEL(ch) < LVL_LEGEND && (from_ip_zone(GET_OBJ_VNUM(formula)) ||
      IS_OBJ_STAT(formula, ITEM_VOLATILE))) {
    act("You cannot decrypt the words on $p.", FALSE, ch, formula, 0, TO_CHAR);
    return;
  }

  if (GET_KARMA(ch) < (GET_OBJ_VAL(formula, 2) * 100)) {
    send_to_char("You don't have enough karma to learn the spell.\r\n", ch);
    return;
  }

  if (GET_OBJ_RNUM(formula) == 1) {
    int i = strlen(formula->name) - 14;
    if (i < 1) {
      send_to_char("The spell formula is blank.\r\n", ch);
      return;
    }
    strcpy(spell_name, formula->name+14);
  } else {
    strcpy(spell_name, spells[GET_OBJ_VAL(formula, 6)]);
  }

  spell = find_spell(ch, spell_name);
  if ( !spell )
    {
      spell = new spell_t;
      // now add to the player's spell list
      if (!ch->spells) {
	ch->spells = spell;
	spell->next = NULL;
      } else {
	spell->next = ch->spells;
	ch->spells = spell;
      }
      int i = strlen(spell_name);
      spell->name = new char[i+1];
      strcpy(spell->name, spell_name);
    }
  else
    {
      if ( GET_OBJ_VAL(formula,2) <= spell->force )
	{
	  send_to_char("You can only learn a higher force of a spell you already know.\r\n", ch);
	  return;
	}
    }

  // and copy over the values
  spell->physical = GET_OBJ_VAL(formula, 0);
  spell->category = GET_OBJ_VAL(formula, 1);
  spell->force = GET_OBJ_VAL(formula, 2);
  spell->target = GET_OBJ_VAL(formula, 3);
  spell->drain = GET_OBJ_VAL(formula, 4);
  spell->damage = GET_OBJ_VAL(formula, 5);
  spell->type = GET_OBJ_VAL(formula, 6);
  spell->effect = GET_OBJ_VAL(formula, 8);

  GET_KARMA(ch) -= GET_OBJ_VAL(formula, 2) * 100;

  send_to_char(ch, "You use up %s as you learn %s.\r\n",
	       formula->short_description, spell->name);
  obj_from_char(formula);
  extract_obj(formula);
}

ACMD(do_treat)
{
  struct char_data *vict;
  struct obj_data *obj;
  int target = 0, i, found = 0, skill = SKILL_BIOTECH;

  if (subcmd && (!IS_NPC(ch) || !GET_MOB_SPEC(ch)))
    return;

  if (FIGHTING(ch)) {
    send_to_char("Administer first aid while fighting?!?\r\n", ch);
    return;
  }

  if (!*argument) {
    send_to_char("Treat who?!\r\n", ch);
    return;
  }

  any_one_arg(argument, arg);
  if (!(vict = get_char_room_vis(ch, arg))) {
    send_to_char(ch, "You can't seem to find a '%s' here.\r\n", arg);
    return;
  }

  if (vict == ch) {
    send_to_char("You can't treat yourself!\r\n", ch);
    return;
  } else if (FIGHTING(vict)) {
    act("Not while $E's fighting!", FALSE, ch, 0, vict, TO_CHAR);
    return;
  } else if (GET_POS(vict) > POS_SITTING && !subcmd) {
    act("$N must at least be sitting to receive first aid.", FALSE, ch, 0, vict, TO_CHAR);
    return;
  } else if (LAST_HEAL(vict) != 0 || (!IS_NPC(vict) && GET_LEVEL(vict) < LVL_LEGEND &&
      GET_REAL_LEVEL(ch) >= LVL_LEGEND && !access_level(ch, LVL_DIRECTOR))) {
    act("Treating $N will not do $M any good.", FALSE, ch, 0, vict, TO_CHAR);
    return;
  }

  if (GET_PHYSICAL(vict) < 100)
    target = 10;
  else if (GET_PHYSICAL(vict) <= (GET_MAX_PHYSICAL(vict) * 2/5))
    target = 8;
  else if (GET_PHYSICAL(vict) <= (GET_MAX_PHYSICAL(vict) * 7/10))
    target = 6;
  else if (GET_PHYSICAL(vict) <= (GET_MAX_PHYSICAL(vict) * 9/10))
    target = 4;
  else {
    act("$N doesn't need to be treated.", FALSE, ch, 0, vict, TO_CHAR);
    if (subcmd)
      perform_tell(ch, vict, "Treatment will do you no good.");
    return;
  }

  if (!GET_SKILL(ch, skill)) {
    i = reverse_web(ch, skill, target);
    skill = i;
  } else skill = GET_SKILL(ch, skill);

  for (obj = ch->carrying; obj && !found; obj = obj->next_content)
    if (GET_OBJ_TYPE(obj) == ITEM_WORKING_GEAR && !GET_OBJ_VAL(obj, 0))
      found = 1;
  for (i = 0; !found && i < (NUM_WEARS - 1); i++)
    if ((obj = GET_EQ(ch, i)) && GET_OBJ_TYPE(obj) == ITEM_WORKING_GEAR && !GET_OBJ_VAL(obj, 0))
      found = 1;
  if (!found && !subcmd)
    target += 4;

  if (vict->real_abils.bod >= 10)
    target -= 3;
  else if (vict->real_abils.bod >= 7)
    target -= 2;
  else if (vict->real_abils.bod >= 4)
    target--;

  if (vict->real_abils.mag > 0)
    target += 2;

  act("$n begins to treat $N.", TRUE, ch, 0, vict, TO_NOTVICT);
  if (success_test(GET_SKILL(ch, SKILL_BIOTECH), target)) {
    act("$N appears better.", FALSE, ch, 0, vict, TO_CHAR);
    act("The pain seems significantly less after $n's treatment.",
        FALSE, ch, 0, vict, TO_VICT);
    if (GET_PHYSICAL(vict) < 100) {
      GET_PHYSICAL(vict) = MIN(GET_MAX_PHYSICAL(vict), 100);
      GET_MENTAL(vict) = 0;
      GET_POS(vict) = POS_STUNNED;
      LAST_HEAL(vict) = MAX(1, (int)(GET_MAX_PHYSICAL(vict) / 100));
    } else if (GET_PHYSICAL(vict) <= (GET_MAX_PHYSICAL(vict) * 2/5)) {
      GET_PHYSICAL(vict) += (int)(GET_MAX_PHYSICAL(vict) * 3/1000);
      LAST_HEAL(vict) = (int)(GET_MAX_PHYSICAL(vict) * 3/1000);
    } else if (GET_PHYSICAL(vict) <= (GET_MAX_PHYSICAL(vict) * 7/10)) {
      GET_PHYSICAL(vict) += (int)(GET_MAX_PHYSICAL(vict) / 500);
      LAST_HEAL(vict) = (int)(GET_MAX_PHYSICAL(vict) / 500);
    } else if (GET_PHYSICAL(vict) <= (GET_MAX_PHYSICAL(vict) * 9/10)) {
      GET_PHYSICAL(vict) += (int)(GET_MAX_PHYSICAL(vict) / 1000);
      LAST_HEAL(vict) = (int)(GET_MAX_PHYSICAL(vict) / 1000);
    }
  } else {
    act("Your treatment does nothing for $N.", FALSE, ch, 0, vict, TO_CHAR);
    act("$n's treatment doesn't help your wounds.", FALSE, ch, 0, vict, TO_VICT);
    LAST_HEAL(vict) = 3;
  }
}

ACMD(do_prequel)
{
  time_t remaining = 927608400 - time(0);
  int days, hours, mins, secs;

  days = (int)remaining / 86400;
  hours = (int)(remaining / 3600) % 24;
  mins = (int)(remaining / 60) % 60;
  secs = (int)remaining % 60;

  send_to_char(ch, "Time remaining until the release of 'Star Wars: Episode One':\r\n"
         "%d days, %d hours, %d minutes, %d seconds.\r\n", days, hours, mins, secs);
}

ACMD(do_astral)
{
  struct char_data *astral;
  struct obj_data *foci, *new_foci;
  int r_num, i;

  one_argument(argument, arg);

  if (GET_TRADITION(ch) != TRAD_SHAMANIC && GET_TRADITION(ch) != TRAD_HERMETIC &&
      !access_level(ch, LVL_PRESIDENT) && !(GET_TRADITION(ch) == TRAD_ADEPT &&
      GET_SKILL(ch, SKILL_PERCEPTION) > 0 && subcmd == SCMD_PERCEIVE)) {
    send_to_char("You can't do that!\r\n", ch);
    return;
  } else if (IS_NPC(ch))
    return;

  if (IS_PROJECT(ch)) {
    send_to_char("But you are already projecting!\r\n", ch);
    return;
  }

  if (subcmd == SCMD_PERCEIVE) {
    if (PLR_FLAGGED(ch, PLR_PERCEIVE)) {
      REMOVE_BIT(PLR_FLAGS(ch), PLR_PERCEIVE);
      send_to_char("You return to your physical senses.\r\n", ch);
    } else {
      SET_BIT(PLR_FLAGS(ch), PLR_PERCEIVE);
      send_to_char("Your physical body seems distant, as the astral plane slides into view.\r\n", ch);
    }
    return;
  }

  if (ch->desc->original) {
    send_to_char("You can't project now.\r\n", ch);
    return;
  } else if (FIGHTING(ch)) {
    send_to_char("You can't project while fighting!\r\n", ch);
    return;
  } else if (!ch->player_specials || ch->player_specials == &dummy_mob) {
    send_to_char("That won't work, for some reason.\r\n", ch);
    return;
  }

  if ((r_num = real_mobile(22)) < 0) {
    log("No astral mob");
    send_to_char("The astral plane is strangely inaccessible...\r\n", ch);
    return;
  }

  if (PLR_FLAGGED(ch, PLR_PERCEIVE)) {
    REMOVE_BIT(PLR_FLAGS(ch), PLR_PERCEIVE);
    send_to_char("You briefly return your perception to your physical senses.\r\n", ch);
  }

  if (!ch->player.aname)
    ch->player.aname = str_dup("reflection");
  if (!ch->player.asdesc)
    ch->player.asdesc = str_dup("a reflection");
  if (!ch->player.adesc)
    ch->player.adesc = str_dup("The reflection of some physical being stands here.\r\n");

  GET_POS(ch) = POS_SITTING;
  astral = read_mobile(r_num, REAL);

  astral->player.name = ch->player.aname;
  astral->player.short_descr = ch->player.asdesc;
  astral->player.long_descr = ch->player.adesc;
  astral->player.description = ch->player.aldesc;

  GET_PHYSICAL(astral) = GET_PHYSICAL(ch);
  GET_MENTAL(astral) = GET_MENTAL(ch);

  astral->real_abils.str = GET_CHA(ch);  GET_STR(astral) = GET_CHA(ch);
  astral->real_abils.qui = GET_INT(ch);  GET_QUI(astral) = GET_INT(ch);
  astral->real_abils.bod = GET_WIL(ch);  GET_BOD(astral) = GET_WIL(ch);
  astral->real_abils.rea = 2 * GET_INT(ch);  GET_REA(astral) = 2 * GET_INT(ch);
  astral->real_abils.mag = GET_MAG(ch);  GET_MAG(astral) = GET_MAG(ch);
  astral->real_abils.intel = GET_INT(ch);  GET_INT(astral) = GET_INT(ch);
  astral->real_abils.wil = GET_WIL(ch);  GET_WIL(astral) = GET_WIL(ch);
  astral->real_abils.cha = GET_CHA(ch);  GET_CHA(astral) = GET_CHA(ch);
  astral->real_abils.ess = GET_ESS(ch);  GET_ESS(astral) = GET_ESS(ch);
  astral->char_specials.saved.skills = ch->char_specials.saved.skills;
  astral->spells = ch->spells;
  GET_ASTRAL(astral) = GET_ASTRAL(ch);
  GET_COMBAT(astral) = GET_ASTRAL(ch);
  GET_MAGIC(astral) = GET_MAGIC(ch);

  char_to_room(astral, ch->in_room);

  foci = GET_EQ(ch, WEAR_WIELD);
  if (foci && GET_OBJ_TYPE(foci) == ITEM_WEAPON && GET_OBJ_VAL(foci, 3) < TYPE_TASER &&
       GET_OBJ_VAL(foci, 7) && GET_OBJ_VAL(foci, 8) && GET_OBJ_VAL(foci, 9) == GET_IDNUM(ch)) {
    new_foci = read_object(foci->item_number, REAL);
    GET_OBJ_VAL(new_foci, 7) = GET_OBJ_VAL(foci, 7);
    GET_OBJ_VAL(new_foci, 8) = GET_OBJ_VAL(foci, 8);
    GET_OBJ_VAL(new_foci, 9) = GET_OBJ_VAL(foci, 9);
    equip_char(astral, new_foci, WEAR_WIELD);
  }

  ch->desc->character = astral;
  ch->desc->original = ch;

  astral->desc = ch->desc;
  ch->desc = NULL;

  act("$n leaves his body behind, entering a deep trance.", TRUE, ch, 0, astral, TO_NOTVICT);
  act("You enter the Astral Plane.", FALSE, astral, 0, 0, TO_CHAR);
  act("$n swirls into view.", TRUE, astral, 0, 0, TO_ROOM);

  SET_BIT(PLR_FLAGS(ch), PLR_PROJECT);
  look_at_room(astral, 1);
}

ACMD(do_customize)
{
  struct obj_data *cyber;
  int found = 0;

  if (FIGHTING(ch)) {
    send_to_char("You can't customize your descriptions while fighting!\r\n", ch);
    return;
  }

  if (IS_NPC(ch)) {
    send_to_char("You can't right now.\r\n", ch);
    return;
  }

  skip_spaces(&argument);
  if (!*argument) {
    send_to_char("Usage: customize <persona/reflection>\r\n", ch);
    return;
  }

  if (is_abbrev(argument, "persona")) {
    for (cyber = ch->cyberware; !found && cyber; cyber = cyber->next_content)
      if (GET_OBJ_VAL(cyber, 2) == CYB_DATAJACK)
        found = 1;
    if (!found) {
      send_to_char("But you don't even have a datajack?!\r\n", ch);
      return;
    }
    STATE(ch->desc) = CON_PCUSTOMIZE;
  } else if (is_abbrev(argument, "reflection")) {
    if (GET_LEVEL(ch) < LVL_LEGEND && GET_TRADITION(ch) != TRAD_SHAMANIC &&
        GET_TRADITION(ch) != TRAD_HERMETIC) {
      send_to_char("And just why would you need to do that?!\r\n", ch);
      return;
    }
    STATE(ch->desc) = CON_ACUSTOMIZE;
  } else {
    send_to_char("Usage: customize <persona/reflection>\r\n", ch);
    return;
  }

  SET_BIT(PLR_FLAGS(ch), PLR_CUSTOMIZE);

  send_to_char("Do you wish to customize your descriptions?\r\n", ch);

  ch->desc->edit_mode = CEDIT_CONFIRM_EDIT;
}

void cedit_disp_menu(struct descriptor_data *d, int mode)
{
  CLS(CH);

  send_to_char(CH, "1) Alias: %s%s%s\r\n", CCCYN(CH, C_CMP),
               d->edit_mob->player.name, CCNRM(CH, C_CMP));
  send_to_char(CH, "2) Short Description: %s%s%s\r\n", CCCYN(CH, C_CMP),
               d->edit_mob->player.short_descr, CCNRM(CH, C_CMP));
  send_to_char(CH, "3) Description: %s%s%s\r\n", CCCYN(CH, C_CMP),
               d->edit_mob->player.long_descr, CCNRM(CH, C_CMP));
  send_to_char(CH, "4) Long Descrption: %s%s%s\r\n", CCCYN(CH, C_CMP),
               d->edit_mob->player.description, CCNRM(CH, C_CMP));

  if (mode)
    send_to_char(CH, "q) Quit\r\nLine too long (max %d characters); function aborted.\r\n"
                     "Enter your choice:\r\n", LINE_LENGTH - 1);
  else send_to_char("q) Quit\r\nEnter your choice:\r\n", CH);
  d->edit_mode = CEDIT_MAIN_MENU;
}

void cedit_parse(struct descriptor_data *d, char *arg)
{
  char tmp_name[MAX_INPUT_LENGTH];
  struct char_data tmp_store;
  int player_i;

  int load_char(char *name, struct char_data *ch);

  switch (d->edit_mode) {
    case CEDIT_CONFIRM_EDIT:
      switch (*arg) {
        case 'y':
        case 'Y':
          d->edit_mob = Mem->GetCh();
          d->edit_mob->player_specials = &dummy_mob;
          if (STATE(d) == CON_PCUSTOMIZE)
          {
            d->edit_mob->player.name = str_dup(CH->player.mname);
            d->edit_mob->player.short_descr = str_dup(CH->player.msdesc);
            d->edit_mob->player.long_descr = str_dup(CH->player.mdesc);
            d->edit_mob->player.description = str_dup(CH->player.mldesc);
          } else {
            d->edit_mob->player.name = str_dup(CH->player.aname);
            d->edit_mob->player.short_descr = str_dup(CH->player.asdesc);
            d->edit_mob->player.long_descr = str_dup(CH->player.adesc);
            d->edit_mob->player.description = str_dup(CH->player.aldesc);
          }
          cedit_disp_menu(d, 0);
          break;
        case 'n':
        case 'N':
          STATE(d) = CON_PLAYING;
          d->edit_mode = 0;
          REMOVE_BIT(PLR_FLAGS(CH), PLR_CUSTOMIZE);
          break;
        default:
          send_to_char("That's not a valid choice.\r\n", CH);
          send_to_char("Do you wish to customize your descriptions? (y/n)\r\n", CH);
          break;
      }
      break;

    case CEDIT_CONFIRM_SAVESTRING:
      switch (*arg) {
        case 'y':
        case 'Y':
          REMOVE_BIT(PLR_FLAGS(CH), PLR_CUSTOMIZE);
          if (STATE(d) == CON_PCUSTOMIZE) {
            if (CH->player.mname)
              delete [] CH->player.mname;
            CH->player.mname = str_dup(d->edit_mob->player.name);
			strcat(CH->player.adesc,"(icon)");
            if (CH->player.msdesc)
              delete [] CH->player.msdesc;
            CH->player.msdesc = str_dup(d->edit_mob->player.short_descr);
            if (CH->player.mdesc)
              delete [] CH->player.mdesc;
            CH->player.mdesc = str_dup(d->edit_mob->player.long_descr);
            if (CH->player.mldesc)
              delete [] CH->player.mldesc;
            CH->player.mldesc = str_dup(d->edit_mob->player.description);
          }
          else
          {
            if (CH->player.aname)
              delete [] CH->player.aname;
            CH->player.aname = str_dup(d->edit_mob->player.name);
            strcat(CH->player.aname,"(astral)");
            if (CH->player.asdesc)
              delete [] CH->player.asdesc;
            CH->player.asdesc = str_dup(d->edit_mob->player.short_descr);
            if (CH->player.adesc)
              delete [] CH->player.adesc;
            CH->player.adesc = str_dup(d->edit_mob->player.long_descr);
            if (CH->player.aldesc)
              delete [] CH->player.aldesc;
            CH->player.aldesc = str_dup(d->edit_mob->player.description);
          }
          if (d->edit_mob)
            Mem->DeleteCh(d->edit_mob);
          d->edit_mob = NULL;
          d->edit_mode = 0;
          STATE(d) = CON_PLAYING;
          save_char(CH, NOWHERE);
          break;
        case 'n':
        case 'N':
          REMOVE_BIT(PLR_FLAGS(CH), PLR_CUSTOMIZE);
          if (d->edit_mob)
            Mem->DeleteCh(d->edit_mob);
          d->edit_mob = NULL;
          d->edit_mode = 0;
          STATE(d) = CON_PLAYING;
          break;
        default:
          send_to_char("Invalid choice, please enter yes or no.\r\n"
                       "Do you wish to save the changes?\r\n", CH);
          break;
      }
      break;
    case CEDIT_MAIN_MENU:
      switch (*arg) {
        case 'q':
        case 'Q':
          send_to_char("Do you wish to save the changes?\r\n", CH);
          d->edit_mode = CEDIT_CONFIRM_SAVESTRING;
          break;
        case '1':
          if (STATE(d) == CON_PCUSTOMIZE)
            send_to_char("Enter persona aliases: ", CH);
          else send_to_char("Enter reflection aliases: ", CH);
          d->edit_mode = CEDIT_ALIAS;
          break;
        case '2':
          send_to_char("Enter short description: ", CH);
          d->edit_mode = CEDIT_SHORT_DESC;
          break;
        case '3':
          if (STATE(d) == CON_PCUSTOMIZE)
            send_to_char("Enter persona description: ", CH);
          else send_to_char("Enter reflection description: ", CH);
          d->edit_mode = CEDIT_DESC;
          d->str = new (char *);
          if (!d->str) {
            mudlog("Malloc failed!", NULL, LOG_SYSLOG, TRUE);
            exit(1);
          }
          *(d->str) = NULL;
          d->max_str = EXDSCR_LENGTH;
          d->mail_to = 0;
          break;
        case '4':
          send_to_char("Enter long (active) description:\r\n", CH);
          d->edit_mode = CEDIT_LONG_DESC;
          d->str = new (char *);
          if (!d->str) {
            mudlog("Malloc failed!", NULL, LOG_SYSLOG, TRUE);
            exit(1);
          }
          *(d->str) = NULL;
          d->max_str = EXDSCR_LENGTH;
          d->mail_to = 0;
          break;
        default:
          cedit_disp_menu(d, 0);
          break;
      }
      break;
    case CEDIT_ALIAS:
      if (strlen(arg) >= LINE_LENGTH) {
        cedit_disp_menu(d, 1);
        return;
      } else if (STATE(d) == CON_PCUSTOMIZE && !isname("persona", arg))
        strcat(arg, " persona");
      else if (!isname("reflection", arg))
        strcat(arg, " reflection");
      if (d->edit_mob->player.name)
        delete [] d->edit_mob->player.name;
      d->edit_mob->player.name = str_dup(arg);
      cedit_disp_menu(d, 0);
      break;
    case CEDIT_SHORT_DESC:
      if (strlen(arg) >= LINE_LENGTH) {
        cedit_disp_menu(d, 1);
        return;
      }
      if (d->edit_mob->player.short_descr)
        delete [] d->edit_mob->player.short_descr;
      d->edit_mob->player.short_descr = str_dup(arg);
      cedit_disp_menu(d, 0);
      break;
    default:
      break;
  }
}