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.obj.c                                    Part of CircleMUD  *
*  Usage: object handling routines                                        *
*                                                                         *
*  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 "structs.h"
#include "utils.h"
#include "comm.h"
#include "interpreter.h"
#include "handler.h"
#include "db.h"
#include "spells.h"
#include "awake.h"

/* extern variables */
extern const struct str_app_type str_app[];
extern struct room_data *world;
extern struct zone_data *zone_table;
extern char *drinks[];
extern int drink_aff[][3];
extern int top_of_zone_table;

// extern funcs
extern char *get_token(char *, char*);
extern int modify_target(struct char_data *ch);
extern int return_general(int skill_num);
extern int reverse_web(struct char_data *ch, int &skill, int &target);
extern void do_ic_response(struct char_data *ic, struct char_data *persona);
extern void check_quest_delivery(struct char_data *ch, struct char_data *mob, int vnum);
extern void check_quest_delivery(struct char_data *ch, struct obj_data *obj);
void calc_weight(struct char_data *ch);

bool search_cyberdeck(struct obj_data *cyberdeck, struct obj_data *program)
{
  struct obj_data *temp;

  for (temp = cyberdeck->contains; temp; temp = temp->next_content)
    if (GET_OBJ_VAL(temp, 0) == GET_OBJ_VAL(program, 0))
      return TRUE;

  return FALSE;
}

void perform_put(struct char_data *ch, struct obj_data *obj, struct obj_data *cont)
{
  int i;

  if (GET_OBJ_TYPE(cont) == ITEM_QUIVER) {
    if ((GET_OBJ_VAL(cont, 1) == 0 && !(GET_OBJ_TYPE(obj) == ITEM_MISSILE && GET_OBJ_VAL(obj, 0) == 0)) ||
        (GET_OBJ_VAL(cont, 1) == 1 && !(GET_OBJ_TYPE(obj) == ITEM_MISSILE && GET_OBJ_VAL(obj, 0) == 1)) ||
        (GET_OBJ_VAL(cont, 1) == 2 && !(GET_OBJ_TYPE(obj) == ITEM_WEAPON && GET_OBJ_VAL(obj, 3) == TYPE_SHURIKEN)) ||
        (GET_OBJ_VAL(cont, 1) == 3 && !(GET_OBJ_TYPE(obj) == ITEM_WEAPON && GET_OBJ_VAL(obj, 3) == TYPE_THROWING_KNIFE)))
      return;
    if (GET_OBJ_VAL(cont, 2) >= GET_OBJ_VAL(cont, 0))
      act("$p won't fit in $P.", FALSE, ch, obj, cont, TO_CHAR);
    else {
      obj_from_char(obj);
      obj_to_obj(obj, cont);
      GET_OBJ_VAL(cont, 2)++;
      act("You put $p in $P.", FALSE, ch, obj, cont, TO_CHAR);
      act("$n puts $p in $P.", TRUE, ch, obj, cont, TO_ROOM);
    }
  } else if (GET_OBJ_WEIGHT(cont) + GET_OBJ_WEIGHT(obj) > GET_OBJ_VAL(cont, 0))
    act("$p won't fit in $P.", FALSE, ch, obj, cont, TO_CHAR);
  else {
    obj_from_char(obj);
    obj_to_obj(obj, cont);
    act("You put $p in $P.", FALSE, ch, obj, cont, TO_CHAR);
    act("$n puts $p in $P.", TRUE, ch, obj, cont, TO_ROOM);
  }
}

void perform_put_cyberdeck(struct char_data * ch, struct obj_data * obj,
                                struct obj_data * cont)
{
  struct obj_data *temp;
  int i = 0;

  if (GET_OBJ_TYPE(obj) == ITEM_DECK_ACCESSORY) {
    switch (GET_OBJ_VAL(obj, 0)) {
      case TYPE_FILE:
        if (GET_OBJ_VAL(cont, 5) + GET_OBJ_VAL(obj, 1) > GET_OBJ_VAL(cont, 3)) {
          act("$p takes up too much memory to be uploaded into $P.", FALSE, ch, obj, cont, TO_CHAR);
          return;
        }
        obj_from_char(obj);
        obj_to_obj(obj, cont);
        GET_OBJ_VAL(cont, 5) += GET_OBJ_VAL(obj, 1);
        act("You upload $p in $P.", FALSE, ch, obj, cont, TO_CHAR);
        break;
      case TYPE_UPGRADE:
        switch (GET_OBJ_VAL(obj, 1)) {
          case 0:
            GET_OBJ_VAL(cont, 0) = GET_OBJ_VAL(obj, 2);
            act("You replace the MPCP chips in $p.", FALSE, ch, cont, 0, TO_CHAR);
            extract_obj(obj);
            break;
          case 1:
            if ((GET_OBJ_VAL(cont, 2) + GET_OBJ_VAL(obj, 2)) > (GET_OBJ_VAL(cont, 0) * 50)) {
              act("$p cannot hold that much active memory.", FALSE, ch, cont, 0, TO_CHAR);
              return;
            }
            GET_OBJ_VAL(cont, 2) = MIN(GET_OBJ_VAL(obj, 2) + GET_OBJ_VAL(cont, 2), GET_OBJ_VAL(cont, 0) * 50);
            act("You upgrade $p's active memory.", FALSE, ch, cont, 0, TO_CHAR);
            extract_obj(obj);
            break;
          case 2:
            GET_OBJ_VAL(cont, 3) += GET_OBJ_VAL(obj, 2);
            act("You upgrade $p's storage memory.", FALSE, ch, cont, 0, TO_CHAR);
            extract_obj(obj);
            break;
          case 3:
            if ((GET_OBJ_VAL(cont, 4) + GET_OBJ_VAL(obj, 2)) > (GET_OBJ_VAL(cont, 0) * 10)) {
              act("$p cannot hold that much load speed.", FALSE, ch, cont, 0, TO_CHAR);
              return;
            }
            GET_OBJ_VAL(cont, 4) = MAX(GET_OBJ_VAL(obj, 2) + GET_OBJ_VAL(cont, 4), GET_OBJ_VAL(cont, 0) * 10);
            act("You upgrade $p's load speed.", FALSE, ch, cont, 0, TO_CHAR);
            extract_obj(obj);
            break;
          case 4:
            if ((GET_OBJ_RENT(cont) + GET_OBJ_VAL(obj, 2)) > (GET_OBJ_VAL(cont, 0) * 20)) {
              act("$p cannot hold that much load speed.", FALSE, ch, cont, 0, TO_CHAR);
              return;
            }
            GET_OBJ_RENT(cont) = MAX(GET_OBJ_VAL(obj, 2) + GET_OBJ_RENT(cont), GET_OBJ_VAL(cont, 0) * 20);
            act("You upgrade $p's I/O speed.", FALSE, ch, cont, 0, TO_CHAR);
            extract_obj(obj);
            break;
          case 5:
            if (GET_OBJ_VAL(obj, 3) != GET_OBJ_VAL(cont, 0)) {
              act("$p doesn't seem to fit anywhere in $P.", FALSE, ch, obj, cont, TO_CHAR);
              return;
            }
            for (temp = cont->contains; temp; temp = temp->next_content)
              if ((GET_OBJ_TYPE(temp) == GET_OBJ_TYPE(obj)) && (GET_OBJ_VAL(temp, 1) == GET_OBJ_VAL(temp, 1))) {
                act("$p already has a reaction upgrade installed.", FALSE, ch, cont, 0, TO_CHAR);
                return;
              }
            obj_from_char(obj);
            obj_to_obj(obj, cont);
            act("You install $p in $P.", FALSE, ch, obj, cont, TO_CHAR);
            break;
        }
        break;
    }
    return;
  }
  if (GET_OBJ_VAL(cont, 5) + GET_OBJ_VAL(obj, 2) > GET_OBJ_VAL(cont, 3))
     act("$p takes up too much memory to be installed into $P.", FALSE,
         ch, obj, cont, TO_CHAR);
  else if (search_cyberdeck(cont, obj))
    act("You already have a similar program installed in $P.", FALSE, ch, obj, cont, TO_CHAR);
  else {
    if (GET_OBJ_VAL(obj, 0) <= PROG_SENSOR) {
      for (temp = cont->contains; temp; temp = temp->next_content)
        if (GET_OBJ_TYPE(temp) == ITEM_PROGRAM && GET_OBJ_VAL(temp, 0) <= PROG_SENSOR)
          i += GET_OBJ_VAL(temp, 1);
      if ((i + GET_OBJ_VAL(obj, 1)) > (GET_OBJ_VAL(cont, 0) * 3)) {
        act("$p does not have enough MPCP to control $P.", FALSE, ch, cont, obj, TO_CHAR);
        return;
      }
    }
    obj_from_char(obj);
    obj_to_obj(obj, cont);
    act("You install $p in $P.", FALSE, ch, obj, cont, TO_CHAR);
    GET_OBJ_VAL(cont, 5) += GET_OBJ_VAL(obj, 2);
    GET_OBJ_VAL(obj, 6) = 1;
  }
}

/* The following put modes are supported by the code below:

        1) put <object> <container>
        2) put all.<object> <container>
        3) put all <container>

        <container> must be in inventory or on ground.
        all objects to be put into container must be in inventory.
*/

ACMD(do_put)
{
  char arg1[MAX_INPUT_LENGTH];
  char arg2[MAX_INPUT_LENGTH];
  struct obj_data *obj, *next_obj, *cont;
  struct char_data *tmp_char;
  int obj_dotmode, cont_dotmode, found = 0;
  bool cyberdeck = FALSE;

  if (IS_PERSONA(ch)) {
    send_to_char("That is not a valid command.\r\n", ch);
    return;
  }

  if (IS_ASTRAL(ch)) {
    send_to_char("You can't!\r\n", ch);
    return;
  }

  two_arguments(argument, arg1, arg2);
  obj_dotmode = find_all_dots(arg1);
  cont_dotmode = find_all_dots(arg2);

  if (subcmd == SCMD_INSTALL)
    cyberdeck = TRUE;

  if (!*arg1) {
    sprintf(buf, "%s what in what?\r\n", (cyberdeck ? "Install" : "Put"));
    send_to_char(buf, ch);
  } else if (obj_dotmode != FIND_INDIV) {
    sprintf(buf, "You can only %s %s into one %s at a time.\r\n",
           (cyberdeck ? "install" : "put"), (cyberdeck ? "programs" : "things"),
           (cyberdeck ? "cyberdeck" : "container"));
    send_to_char(buf, ch);
  } else if (!*arg2) {
    sprintf(buf, "What do you want to %s %s in?\r\n", (cyberdeck ? "install" : "put"),
            ((obj_dotmode == FIND_INDIV) ? "it" : "them"));
    send_to_char(buf, ch);
  } else {
    generic_find(arg2, FIND_OBJ_EQUIP | FIND_OBJ_INV | FIND_OBJ_ROOM, ch, &tmp_char, &cont);
    if (!cont) {
      sprintf(buf, "You don't see %s %s here.\r\n", AN(arg2), arg2);
      send_to_char(buf, ch);
    } else if ((!cyberdeck && (GET_OBJ_TYPE(cont) != ITEM_CONTAINER && GET_OBJ_TYPE(cont) != ITEM_QUIVER)) ||
              (cyberdeck && (GET_OBJ_TYPE(cont) != ITEM_CYBERDECK))) {
      sprintf(buf, "$p is not a %s.", (cyberdeck ? "cyberdeck" : "container"));
      act(buf, FALSE, ch, cont, 0, TO_CHAR);
    } else if (IS_SET(GET_OBJ_VAL(cont, 1), CONT_CLOSED) && (GET_OBJ_TYPE(cont) != ITEM_CYBERDECK
            && GET_OBJ_TYPE(cont) != ITEM_QUIVER))
      send_to_char("You'd better open it first!\r\n", ch);
    else {
      if (obj_dotmode == FIND_INDIV) {  /* put <obj> <container> */
        if (!(obj = get_obj_in_list_vis(ch, arg1, ch->carrying))) {
          sprintf(buf, "You aren't carrying %s %s.\r\n", AN(arg1), arg1);
          send_to_char(buf, ch);
        } else if ((obj == cont) && !cyberdeck)
          send_to_char("You attempt to fold it into itself, but fail.\r\n", ch);
        else if (cyberdeck && (GET_OBJ_TYPE(obj) != ITEM_PROGRAM && GET_OBJ_TYPE(obj) != ITEM_DECK_ACCESSORY))
          send_to_char("You can't install that in a cyberdeck!\r\n", ch);
     else if (GET_OBJ_TYPE(cont) == ITEM_QUIVER) {
        if (GET_OBJ_VAL(cont, 1) == 0 && !(GET_OBJ_TYPE(obj) == ITEM_MISSILE && GET_OBJ_VAL(obj, 0) == 0))
          send_to_char("Only arrows may be placed in that.\r\n", ch);
        else if (GET_OBJ_VAL(cont, 1) == 1 && !(GET_OBJ_TYPE(obj) == ITEM_MISSILE && GET_OBJ_VAL(obj, 0) == 1))
          send_to_char("Only bolts may be placed in that.\r\n", ch);
        else if (GET_OBJ_VAL(cont, 1) == 2 && !(GET_OBJ_TYPE(obj) == ITEM_WEAPON && GET_OBJ_VAL(obj, 3) == TYPE_SHURIKEN))
          send_to_char("Only shurikens can be stored in that.\r\n", ch);
        else if (GET_OBJ_VAL(cont, 1) == 3 && !(GET_OBJ_TYPE(obj) == ITEM_WEAPON && GET_OBJ_VAL(obj, 3) == TYPE_THROWING_KNIFE))
          send_to_char("That is used to hold throwing knives only.\r\n", ch);
        else
        {
          perform_put(ch, obj, cont);
          //calc_weight(ch);
		}
     }
     else if (!cyberdeck)
     {
       perform_put(ch, obj, cont);
 	   //calc_weight(ch);
 	 }
     else perform_put_cyberdeck(ch, obj, cont);
      } else {
        for (obj = ch->carrying; obj; obj = next_obj) {
          next_obj = obj->next_content;
          if (obj != cont && CAN_SEE_OBJ(ch, obj) && (obj_dotmode == FIND_ALL || isname(arg1, obj->name))) {
            found = 1;
          if (!cyberdeck)
          {
            perform_put(ch, obj, cont);
	  	    //calc_weight(ch);
	  	  }
          else if (GET_OBJ_TYPE(obj) != ITEM_PROGRAM)
            send_to_char("That's not a program!\r\n", ch);
          else perform_put_cyberdeck(ch, obj, cont);
          }
        }
        if (!found) {
          if (obj_dotmode == FIND_ALL) {
            sprintf(buf, "You don't seem to have anything to %s in it.\r\n", (cyberdeck ? "install" : "put"));
            send_to_char(buf, ch);
          } else {
            sprintf(buf, "You don't seem to have any %ss.\r\n", arg1);
            send_to_char(buf, ch);
          }
        }
      }
    }
  }
}

int can_take_obj(struct char_data * ch, struct obj_data * obj)
{
  if (IS_CARRYING_N(ch) >= CAN_CARRY_N(ch)) {
    act("$p: you can't carry that many items.", FALSE, ch, obj, 0, TO_CHAR);
    return 0;
  } else if ((IS_CARRYING_W(ch) + GET_OBJ_WEIGHT(obj)) >
       CAN_CARRY_W(ch)) {
    act("$p: you can't carry that much weight.", FALSE, ch, obj, 0, TO_CHAR);
    return 0;
  } else if (!(CAN_WEAR(obj, ITEM_WEAR_TAKE))) {
    act("$p: you can't take that!", FALSE, ch, obj, 0, TO_CHAR);
    return 0;
  }
  return 1;
}

void get_check_money(struct char_data * ch, struct obj_data * obj)
{
  int zone;

  if (GET_OBJ_TYPE(obj) == ITEM_MONEY) {
    for (zone = 0; zone <= top_of_zone_table; zone++)
      if (!zone_table[zone].connected && GET_OBJ_VNUM(obj) >= (zone_table[zone].number * 100) &&
          GET_OBJ_VNUM(obj) <= zone_table[zone].top)
        break;
    if (zone <= top_of_zone_table)
      act("$p dissolves in your hands!", FALSE, ch, obj, 0, TO_CHAR);
    else if (GET_OBJ_VAL(obj, 0) > (!GET_OBJ_VAL(obj, 1) ? 0 : -1)) {
      if (!GET_OBJ_VAL(obj, 1)) {  //paper money
        if (GET_OBJ_VAL(obj, 0) > 1)
          send_to_char(ch, "There were %d nuyen.\r\n", GET_OBJ_VAL(obj, 0));
        else send_to_char(ch, "There was 1 nuyen.\r\n");
        GET_NUYEN(ch) += GET_OBJ_VAL(obj, 0);
      } else return;
    } else {
      act("$p dissloves in your hands!", FALSE, ch, obj, 0, TO_CHAR);
      mudlog("ERROR: Nuyen value < 1", ch, LOG_SYSLOG, TRUE);
    }
    extract_obj(obj);
  }
}

void calc_weight(struct char_data *ch)
{
	struct obj_data *char_eq[NUM_WEARS];
	struct obj_data *obj, *next_obj;
    int i=0, wield[2];
	/* first reset the player carry weight*/
	IS_CARRYING_W(ch) = 0;
	/* Go Through worn eq*/
	wield[0] = GET_WIELDED(ch, 0);
	wield[1] = GET_WIELDED(ch, 1);
	for (i = 0; i < NUM_WEARS; i++)
	{
    	if (ch->equipment[i])
    	{
    	 obj = unequip_char(ch, i);
		 IS_CARRYING_W(ch) += GET_OBJ_WEIGHT(obj);
		 equip_char(ch,obj,i);
		}
	}
  	for (obj = ch->carrying; obj; obj = next_obj)
  	{
    	next_obj = obj->next_content;
		IS_CARRYING_W(ch) +=GET_OBJ_WEIGHT(obj);
  	}
  	GET_WIELDED(ch,0) = wield[0];
  	GET_WIELDED(ch,1) = wield[1];
}

void perform_get_from_container(struct char_data * ch, struct obj_data * obj,
                                     struct obj_data * cont, int mode)
{
  bool cyberdeck = FALSE;
  int i;

  if (GET_OBJ_TYPE(cont) == ITEM_CYBERDECK)
     cyberdeck = TRUE;

  if (mode == FIND_OBJ_INV || can_take_obj(ch, obj)) {
    if (IS_CARRYING_N(ch) >= CAN_CARRY_N(ch))
      act("$p: you can't hold any more items.", FALSE, ch, obj, 0, TO_CHAR);
    else {
      obj_from_obj(obj);
      obj_to_char(obj, ch);
      if (GET_OBJ_TYPE(cont) == ITEM_QUIVER)
        GET_OBJ_VAL(cont, 2) = MAX(0, GET_OBJ_VAL(cont, 2) - 1);
      sprintf(buf, "You %s $p from $P.", (cyberdeck ? "uninstall" : "get"));
      if (cyberdeck && (GET_OBJ_TYPE(obj) == ITEM_PROGRAM || GET_OBJ_TYPE(obj) == ITEM_DECK_ACCESSORY)) {
        GET_OBJ_VAL(obj, 6) = 0;
        GET_OBJ_VAL(cont, 5) -= (GET_OBJ_TYPE(obj) == ITEM_PROGRAM ? GET_OBJ_VAL(obj, 2) :
                                (GET_OBJ_VAL(obj, 0) == TYPE_FILE ? GET_OBJ_VAL(obj, 1) : 0));
      }
      act(buf, FALSE, ch, obj, cont, TO_CHAR);
      if (!cyberdeck)
        act("$n gets $p from $P.", TRUE, ch, obj, cont, TO_ROOM);
      else act("$n uninstalls $p from $P.", TRUE, ch, obj, cont, TO_ROOM);
      get_check_money(ch, obj);
    }
  }
}


void get_from_container(struct char_data * ch, struct obj_data * cont,
                        char *arg, int mode)
{
  struct obj_data *obj, *next_obj;
  int obj_dotmode, found = 0;

  obj_dotmode = find_all_dots(arg);

  if (GET_OBJ_TYPE(cont) == ITEM_CYBERDECK) {
    if (obj_dotmode == FIND_ALL || obj_dotmode == FIND_ALLDOT) {
      send_to_char("You can't uninstall more than one program at a time!\r\n", ch);
      return;
    }
    obj = get_obj_in_list_vis(ch, arg, cont->contains);
    if (!obj) {
      sprintf(buf, "There doesn't seem to be %s %s installed in $p.", AN(arg), arg);
      act(buf, FALSE, ch, cont, 0, TO_CHAR);
      return;
    }
    perform_get_from_container(ch, obj, cont, mode);
    return;
  }

  if ( IS_OBJ_STAT(cont, ITEM_CORPSE) )
  {
    if ( GET_OBJ_VAL(cont, 4) == 1 && GET_OBJ_VAL(cont, 5) != GET_IDNUM(ch)
        && GET_LEVEL(ch) < LVL_BUILDER )
    {
      send_to_char("Corpse looting is ^rNOT^n allowed.\n\r",ch);
      return;
    }
    else
    {
      if (obj_dotmode == FIND_ALLDOT && !*arg) {
        send_to_char("Get all of what?\r\n", ch);
        return;
      }
      for (obj = cont->contains; obj; obj = next_obj) {
        next_obj = obj->next_content;
        if (CAN_SEE_OBJ(ch, obj) &&
            (obj_dotmode == FIND_ALL || isname(arg, obj->name))) {
          found = 1;
          perform_get_from_container(ch, obj, cont, mode);
        }
      }
      if (!found) {
        if (obj_dotmode == FIND_ALL)
          act("$p seems to be empty.", FALSE, ch, cont, 0, TO_CHAR);
        else {
          sprintf(buf, "You can't seem to find any %ss in $p.", arg);
          act(buf, FALSE, ch, cont, 0, TO_CHAR);
        }
      }
      return;
    }
  }

  found = 0;

  if (IS_SET(GET_OBJ_VAL(cont, 1), CONT_CLOSED))
    act("$p is closed.", FALSE, ch, cont, 0, TO_CHAR);
  else if (obj_dotmode == FIND_INDIV) {
    if (!(obj = get_obj_in_list_vis(ch, arg, cont->contains))) {
      sprintf(buf, "There doesn't seem to be %s %s in $p.", AN(arg), arg);
      act(buf, FALSE, ch, cont, 0, TO_CHAR);
    } else
      perform_get_from_container(ch, obj, cont, mode);
  } else {
    if (obj_dotmode == FIND_ALLDOT && !*arg) {
      send_to_char("Get all of what?\r\n", ch);
      return;
    }
    for (obj = cont->contains; obj; obj = next_obj) {
      next_obj = obj->next_content;
      if (CAN_SEE_OBJ(ch, obj) &&
          (obj_dotmode == FIND_ALL || isname(arg, obj->name))) {
        found = 1;
        perform_get_from_container(ch, obj, cont, mode);
      }
    }
    if (!found) {
      if (obj_dotmode == FIND_ALL)
        act("$p seems to be empty.", FALSE, ch, cont, 0, TO_CHAR);
      else {
        sprintf(buf, "You can't seem to find any %ss in $p.", arg);
          act(buf, FALSE, ch, cont, 0, TO_CHAR);
      }
    }
  }
}

int perform_get_from_room(struct char_data * ch, struct obj_data * obj, bool download)
{
  int i;

  if (can_take_obj(ch, obj))
  {
    obj_from_room(obj);
    obj_to_char(obj, ch);
    if (download) {
      act("You download $p.", FALSE, ch, obj, 0, TO_CHAR);
      act("$n downloads $p.", TRUE, ch, obj, 0, TO_ROOM);
    } else {
      act("You get $p.", FALSE, ch, obj, 0, TO_CHAR);
      act("$n gets $p.", TRUE, ch, obj, 0, TO_ROOM);
    }
    get_check_money(ch, obj);
    return 1;
    affect_total(ch);
  }
  return 0;
}

void get_from_room(struct char_data * ch, char *arg, bool download)
{
  struct obj_data *obj, *next_obj;
  struct char_data *ic;
  int dotmode, found = 0;
  dotmode = find_all_dots(arg);

  if (dotmode == FIND_INDIV || download) {
    if (!(obj = get_obj_in_list_vis(ch, arg, world[ch->in_room].contents))) {
      sprintf(buf, "You don't see %s %s here.\r\n", AN(arg), arg);
      send_to_char(buf, ch);
    } else {
      if ( download )
      {
        if (!(GET_OBJ_TYPE(obj) == ITEM_DECK_ACCESSORY &&
            GET_OBJ_VAL(obj, 0) == TYPE_FILE)) {
          send_to_char("You can only download data files.\r\n", ch);
          return;
        }
        if ((GET_STORAGE(ch) - GET_OBJ_VAL(obj, 1)) < 0) {
          send_to_char("You do not have enough memory to download that file.\r\n", ch);
          return;
        }

        /**** THIS LOOP WAS USING WRONG POINTER ****/
        for (ic = world[ch->in_room].people; ic; ic = ic->next_in_room)
	{
          if (IS_IC(ic) && GET_RACE(ic) == CLASS_SCRAMBLE)
          {
            send_to_char(buf,ch);
            do_ic_response(ic, ch);
            return;
          }
	}
        perform_get_from_room(ch, obj, TRUE);
        WAIT_STATE(ch, PULSE_VIOLENCE * MAX(1, GET_OBJ_VAL(obj, 1) / GET_IO_SPEED(ch)))
        GET_STORAGE(ch) -= GET_OBJ_VAL(obj, 1);
      }
      else
      {
	if ( CAN_SEE_OBJ(ch, obj) )
	{
          if ( IS_OBJ_STAT(obj, ITEM_CORPSE) && GET_OBJ_VAL(obj, 4) == 1
              && GET_OBJ_VAL(obj, 5) != GET_IDNUM(ch) && GET_LEVEL(ch) < LVL_BUILDER )
            send_to_char("It's not yours chummer...better leave it be.\n\r",ch);
          else
          {
            perform_get_from_room(ch, obj, FALSE);
		    //calc_weight(ch);
		  }
	    found = 1;
	}
      }
    }
  } else {
    if (dotmode == FIND_ALLDOT && !*arg) {
      send_to_char("Get all of what?\r\n", ch);
      return;
    }
    for (obj = world[ch->in_room].contents; obj; obj = next_obj) {
      next_obj = obj->next_content;
      if (CAN_SEE_OBJ(ch, obj) &&
          (dotmode == FIND_ALL || isname(arg, obj->name))) {
        found = 1;
        if ( IS_OBJ_STAT(obj, ITEM_CORPSE) && GET_OBJ_VAL(obj, 4) == 1
	    && GET_OBJ_VAL(obj, 5) != GET_IDNUM(ch) && GET_LEVEL(ch) < LVL_MANAGER )
          send_to_char("It's not yours chummer...better leave it be.\n\r",ch);
        else
        {
          perform_get_from_room(ch, obj, FALSE);
	      //calc_weight(ch);
	    }
      }
    }
    if (!found) {
      if (dotmode == FIND_ALL)
        send_to_char("There doesn't seem to be anything here.\r\n", ch);
      else {
        sprintf(buf, "You don't see any %ss here.\r\n", arg);
        send_to_char(buf, ch);
      }
    }
  }
}

ACMD(do_get)
{
  char arg1[MAX_INPUT_LENGTH];
  char arg2[MAX_INPUT_LENGTH];

  int cont_dotmode, found = 0, mode;
  struct obj_data *cont;
  struct char_data *tmp_char;
  bool cyberdeck = FALSE, download = FALSE;

  if (IS_ASTRAL(ch)) {
    send_to_char("You cannot grasp physical objects.\r\n", ch);
    return;
  }

  if (IS_PERSONA(ch)) {
    if (subcmd == SCMD_DOWNLOAD)
      download = TRUE;
    else {
      send_to_char("That is not a valid command.\r\n", ch);
      return;
    }
  }
  if (!IS_PERSONA(ch) && subcmd == SCMD_DOWNLOAD) {
    send_to_char("You have to be connected to download.\r\n", ch);
    return;
  }

  if (subcmd == SCMD_UNINSTALL)
    cyberdeck = TRUE;

  two_arguments(argument, arg1, arg2);

  if (IS_CARRYING_N(ch) >= CAN_CARRY_N(ch))
    send_to_char("Your arms are already full!\r\n", ch);
  else if (!*arg1) {
    sprintf(buf, "%s what?\r\n", (cyberdeck ? "Uninstall" : (download ? "Download" : "Get")));
    send_to_char(buf, ch);
  }
  else if (!*arg2 || download)
  {
    get_from_room(ch, arg1, download);
  }
  else {
    cont_dotmode = find_all_dots(arg2);
    if (cont_dotmode == FIND_INDIV) {
      mode = generic_find(arg2, FIND_OBJ_EQUIP | FIND_OBJ_INV | FIND_OBJ_ROOM, ch, &tmp_char, &cont);
      if (!cont) {
        sprintf(buf, "You don't have %s %s.\r\n", AN(arg2), arg2);
        send_to_char(buf, ch);
      } else if ((!cyberdeck && !(GET_OBJ_TYPE(cont) == ITEM_CONTAINER || GET_OBJ_TYPE(cont) == ITEM_QUIVER)) ||
         (cyberdeck && GET_OBJ_TYPE(cont) != ITEM_CYBERDECK)) {
        sprintf(buf, "$p is not a %s", (!cyberdeck ? "container" : "cyberdeck"));
        act(buf, FALSE, ch, cont, 0, TO_CHAR);
      }
      else
      {
        get_from_container(ch, cont, arg1, mode);
  	    //calc_weight(ch);
  	  }
    } else {
      if (cont_dotmode == FIND_ALLDOT && !*arg2) {
        send_to_char("Get from all of what?\r\n", ch);
        return;
      }
      for (cont = ch->carrying; cont; cont = cont->next_content)
        if (CAN_SEE_OBJ(ch, cont) &&
            (cont_dotmode == FIND_ALL || isname(arg2, cont->name)))
          if ((!cyberdeck && GET_OBJ_TYPE(cont) == ITEM_CONTAINER) ||
              (cyberdeck && GET_OBJ_TYPE(cont) == ITEM_CYBERDECK)) {
            found = 1;
            get_from_container(ch, cont, arg1, FIND_OBJ_INV);
            //calc_weight(ch);
          } else if (cont_dotmode == FIND_ALLDOT) {
            found = 1;
            sprintf(buf, "$p is not a %s", (!cyberdeck ? "container" : "cyberdeck"));
            act(buf, FALSE, ch, cont, 0, TO_CHAR);
          }
      for (cont = world[ch->in_room].contents; cont; cont = cont->next_content)
        if (CAN_SEE_OBJ(ch, cont) &&
            (cont_dotmode == FIND_ALL || isname(arg2, cont->name)))
          if (GET_OBJ_TYPE(cont) == ITEM_CONTAINER) {
            get_from_container(ch, cont, arg1, FIND_OBJ_ROOM);
            //calc_weight(ch);
            found = 1;
          } else if (cont_dotmode == FIND_ALLDOT) {
          sprintf(buf, "$p is not a %s", (!cyberdeck ? "container" : "cyberdeck"));
            act(buf, FALSE, ch, cont, 0, TO_CHAR);
            found = 1;
          }
      if (!found) {
        if (cont_dotmode == FIND_ALL) {
          sprintf(buf, "You can't seem to find any %s.\r\n", (!cyberdeck ? "containers" : "cyberdeck"));
          send_to_char(buf, ch);
        } else {
          sprintf(buf, "You can't seem to find any %ss here.\r\n", arg2);
          send_to_char(buf, ch);
        }
      }
    }
  }
}

void perform_drop_gold(struct char_data * ch, int amount, byte mode, sh_int RDR)
{
  struct obj_data *obj;

  if (mode == SCMD_UPLOAD) {
    send_to_char("You can only upload data files.\r\n", ch);
    return;
  } else if (mode != SCMD_DROP) {
    send_to_char("You can't do that!\r\n", ch);
    return;
  } else if (amount < 1) {
    send_to_char("How does that work?\r\n", ch);
    return;
  } else if (amount > GET_NUYEN(ch)) {
    send_to_char("You don't even have that much!\r\n", ch);
    return;
  }

  obj = read_object(110, VIRTUAL);
  GET_OBJ_VAL(obj, 0) = amount;

  GET_NUYEN(ch) -= amount;
  act("You drop $p.", FALSE, ch, obj, 0, TO_CHAR);
  act("$n drops $p.", TRUE, ch, obj, 0, TO_ROOM);
  affect_total(ch);

  obj_to_room(obj, ch->in_room);
  return;
}

#define VANISH(mode) ((mode == SCMD_DONATE || mode == SCMD_JUNK) ? "  It vanishes into a recycling bin!" : "")

int perform_drop(struct char_data * ch, struct obj_data * obj, byte mode,
                 char *sname, sh_int RDR)
{
  int value, i;

  if (IS_OBJ_STAT(obj, ITEM_NODROP)) {
    sprintf(buf, "You can't %s $p, it must be CURSED!", sname);
    act(buf, FALSE, ch, obj, 0, TO_CHAR);
    return 0;
  }

  if (mode == SCMD_UPLOAD && !(GET_OBJ_TYPE(obj) == ITEM_DECK_ACCESSORY && GET_OBJ_VAL(obj, 0) == TYPE_FILE)) {
    send_to_char("You can only upload data files.\r\n", ch);
    return 0;
  }

  sprintf(buf, "You %s $p.%s", sname, VANISH(mode));
  act(buf, FALSE, ch, obj, 0, TO_CHAR);
  sprintf(buf, "$n %ss $p.%s", sname, VANISH(mode));
  act(buf, TRUE, ch, obj, 0, TO_ROOM);
  obj_from_char(obj);
  affect_total(ch);

  if ((mode == SCMD_DONATE) && IS_OBJ_STAT(obj, ITEM_NODONATE))
    mode = SCMD_JUNK;

  switch (mode) {
    case SCMD_DROP:
      obj_to_room(obj, ch->in_room);
      if (!IS_NPC(ch) && GET_QUEST(ch))
        check_quest_delivery(ch, obj);
      else if (AFF_FLAGGED(ch, AFF_GROUP) && ch->master &&
               !IS_NPC(ch->master) && GET_QUEST(ch->master))
        check_quest_delivery(ch->master, obj);
      return 0;
    case SCMD_UPLOAD:
      obj_to_room(obj, ch->in_room);
      if (!IS_NPC(ch) && GET_QUEST(ch))
        check_quest_delivery(ch, obj);
      else if (AFF_FLAGGED(ch, AFF_GROUP) && ch->master &&
               !IS_NPC(ch->master) && GET_QUEST(ch->master))
        check_quest_delivery(ch->master, obj);
      GET_STORAGE(ch) += GET_OBJ_VAL(obj, 1);
      return 0;
    case SCMD_DONATE:
      obj_to_room(obj, RDR);
      if (world[RDR].people)
        act("You notice $p exposed beneath the junk.", FALSE, world[RDR].people, obj, 0, TO_ROOM);
      return 0;
    case SCMD_JUNK:
      value = MAX(1, MIN(200, GET_OBJ_COST(obj) >> 4));
      extract_obj(obj);
      return value;
    default:
      log("SYSERR: Incorrect argument passed to perform_drop");
      break;
  }

  return 0;
}

ACMD(do_drop)
{
  extern sh_int donation_room_1;
  extern sh_int donation_room_2;  /* uncomment if needed! */
  extern sh_int donation_room_3;  /* uncomment if needed! */
  extern sh_int donation_room_4;
  extern sh_int donation_room_5;
  extern sh_int donation_room_6;

  if (IS_PERSONA(ch) && subcmd != SCMD_UPLOAD) {
    send_to_char("That is not a valid command.\r\n", ch);
    return;
  }
  if (!IS_PERSONA(ch) && subcmd == SCMD_UPLOAD) {
    send_to_char("You have to be connected to upload.\r\n", ch);
    return;
  }

  if (IS_ASTRAL(ch)) {
    send_to_char("You can't!\r\n", ch);
    return;
  }

  struct obj_data *obj, *next_obj;
  sh_int RDR = 0;
  byte mode = SCMD_DROP;
  int dotmode, amount = 0;
  char *sname;

  switch (subcmd) {
    case SCMD_JUNK:
      sname = "junk";
      mode = SCMD_JUNK;
      break;
    case SCMD_DONATE:
      sname = "donate";
      mode = SCMD_DONATE;
      switch (number(0, 12)) {
        case 0:
          mode = SCMD_JUNK;
          break;
        case 12: case 1: RDR = real_room(donation_room_1); break;
        case 7:  case 2: RDR = real_room(donation_room_2); break;
        case 8:  case 3: RDR = real_room(donation_room_3); break;
        case 9:  case 4: RDR = real_room(donation_room_4); break;
        case 10: case 5: RDR = real_room(donation_room_5); break;
        case 11: case 6: RDR = real_room(donation_room_6); break;
      }
      if (RDR == NOWHERE) {
        send_to_char("Sorry, you can't donate anything right now.\r\n", ch);
        return;
      }
      break;
    case SCMD_UPLOAD:
      sname = "upload";
      mode = SCMD_UPLOAD;
      break;
    default:
      sname = "drop";
      break;
  }

  argument = one_argument(argument, arg);

  if (!*arg) {
    sprintf(buf, "What do you want to %s?\r\n", sname);
    send_to_char(buf, ch);
    return;
  } else if (is_number(arg)) {
    amount = atoi(arg);
    argument = one_argument(argument, arg);
    if (!str_cmp("nuyen", arg))
      perform_drop_gold(ch, amount, mode, RDR);
    else {
      /* code to drop multiple items.  anyone want to write it? -je */
      send_to_char("Sorry, you can't do that to more than one item at a time.\r\n", ch);
    }
    return;
  } else {
    dotmode = find_all_dots(arg);

    /* Can't junk or donate all */
    if ((dotmode == FIND_ALL) && (subcmd == SCMD_JUNK || subcmd == SCMD_DONATE || subcmd == SCMD_UPLOAD)) {
      if (subcmd == SCMD_JUNK)
        send_to_char("Go to the dump if you want to junk EVERYTHING!\r\n", ch);
      else if (subcmd == SCMD_DONATE)
        send_to_char("Go to the junkyard if you want to donate EVERYTHING!\r\n", ch);
      else send_to_char("Upload EVERYTHING?!\r\n", ch);
      return;
    }
    if (dotmode == FIND_ALL) {
      if (!ch->carrying)
        send_to_char("You don't seem to be carrying anything.\r\n", ch);
      else for (obj = ch->carrying; obj; obj = next_obj) {
          next_obj = obj->next_content;
          amount += perform_drop(ch, obj, mode, sname, RDR);
        }
    } else if (dotmode == FIND_ALLDOT) {
      if (!*arg) {
        sprintf(buf, "What do you want to %s all of?\r\n", sname);
        send_to_char(buf, ch);
        return;
      }
      if (subcmd == SCMD_UPLOAD) {
        send_to_char("You can't upload more than one file at a time.\r\n", ch);
        return;
      }
      if (!(obj = get_obj_in_list_vis(ch, arg, ch->carrying))) {
        sprintf(buf, "You don't seem to have any %ss.\r\n", arg);
        send_to_char(buf, ch);
      }
      while (obj) {
        next_obj = get_obj_in_list_vis(ch, arg, obj->next_content);
        amount += perform_drop(ch, obj, mode, sname, RDR);
        obj = next_obj;
      }
    } else {
      if (!(obj = get_obj_in_list_vis(ch, arg, ch->carrying))) {
        sprintf(buf, "You don't seem to have %s %s.\r\n", AN(arg), arg);
        send_to_char(buf, ch);
      } else amount += perform_drop(ch, obj, mode, sname, RDR);
    }
  }
  //calc_weight(ch);
  if (amount && (subcmd == SCMD_JUNK)) {
    send_to_char(ch, "You receive %d credits for recycling.\r\n", amount >> 4);
    GET_NUYEN(ch) += amount >> 4;
  }
}

int perform_give(struct char_data * ch, struct char_data * vict, struct obj_data * obj)
{
  struct obj_data *temp, *temp2, *next, *next2;

  if (IS_ASTRAL(vict)) {
    act("What use would $E have for $p?!", FALSE, ch, obj, vict, TO_CHAR);
    return 0;
  }
  if (IS_OBJ_STAT(obj, ITEM_NODROP)) {
    act("You can't let go of $p!!  Yeech!", FALSE, ch, obj, 0, TO_CHAR);
    return 0;
  }

  if (IS_CARRYING_N(vict) >= CAN_CARRY_N(vict)) {
    act("$N seems to have $S hands full.", FALSE, ch, 0, vict, TO_CHAR);
    return 0;
  }
  if (GET_OBJ_WEIGHT(obj) + IS_CARRYING_W(vict) > CAN_CARRY_W(vict)) {
    act("$E can't carry that much weight.", FALSE, ch, 0, vict, TO_CHAR);
    return 0;
  }
  if (!IS_NPC(ch) && IS_NPC(vict) && GET_QUEST(ch))
    check_quest_delivery(ch, vict, GET_OBJ_VNUM(obj));
  else if (AFF_FLAGGED(ch, AFF_GROUP) && ch->master &&
           !IS_NPC(ch->master) && IS_NPC(vict) && GET_QUEST(ch->master))
    check_quest_delivery(ch->master, vict, GET_OBJ_VNUM(obj));

  obj_from_char(obj);
  obj_to_char(obj, vict);
  act("You give $p to $N.", FALSE, ch, obj, vict, TO_CHAR);
  act("$n gives you $p.", FALSE, ch, obj, vict, TO_VICT);
  act("$n gives $p to $N.", TRUE, ch, obj, vict, TO_NOTVICT);

  return 1;
}

/* utility function for give */
struct char_data *give_find_vict(struct char_data * ch, char *arg)
{
  SPECIAL(fixer);
  struct char_data *vict;

  if (!*arg) {
    send_to_char("To who?\r\n", ch);
    return NULL;
  } else if (!(vict = get_char_room_vis(ch, arg))) {
    send_to_char(NOPERSON, ch);
    return NULL;
  } else if (vict == ch) {
    send_to_char("What's the point of that?\r\n", ch);
    return NULL;
  } else if (IS_NPC(vict) && GET_MOB_SPEC(vict) && GET_MOB_SPEC(vict) == fixer) {
    act("Do you really want to give $M stuff for free?!",
        FALSE, ch, 0, vict, TO_CHAR);
    return NULL;
  } else return vict;
}

void perform_give_gold(struct char_data *ch, struct char_data *vict, int amount)
{
  if (amount <= 0) {
    send_to_char("Heh heh heh ... we are jolly funny today, eh?\r\n", ch);
    return;
  }
  if (IS_ASTRAL(vict)) {
    send_to_char("Yeah, like astrals need nuyen.\r\n", ch);
    return;
  }
  if ((GET_NUYEN(ch) < amount) && (IS_NPC(ch) || (!access_level(ch, LVL_OWNER)))) {
    send_to_char("You don't have that much!\r\n", ch);
    return;
  }
  if ((GET_LEVEL(ch) >= LVL_LEGEND && !access_level(ch, LVL_OWNER)) && GET_LEVEL(vict) < LVL_LEGEND)
  {
    send_to_char("Maybe that's not such a good idea...\r\n", ch);
    return;
  }
  send_to_char(OK, ch);
  sprintf(buf, "$n gives you %d nuyen.", amount);
  act(buf, FALSE, ch, 0, vict, TO_VICT);
  sprintf(buf, "$n gives some nuyen to $N.");
  act(buf, TRUE, ch, 0, vict, TO_NOTVICT);
  if (IS_NPC(ch) || !access_level(ch, LVL_OWNER))
    GET_NUYEN(ch) -= amount;
  GET_NUYEN(vict) += amount;
  if (IS_NPC(ch) && !IS_NPC(vict)) {
    sprintf(buf, "%s -> %s: %d *", GET_NAME(ch), GET_NAME(vict), amount);
    mudlog(buf, ch, LOG_WIZLOG, TRUE);
  }
}

ACMD(do_give)
{
  int amount, dotmode;
  struct char_data *vict;
  struct obj_data *obj, *next_obj;

  argument = one_argument(argument, arg);

  if (IS_ASTRAL(ch)) {
    send_to_char("You can't!\r\n", ch);
    return;
  }

 if (IS_PERSONA(ch)) {
    send_to_char("That is not a valid command.\r\n", ch);
    return;
  }

  if (!*arg)
    send_to_char("Give what to who?\r\n", ch);
  else if (is_number(arg)) {
    amount = atoi(arg);
    argument = one_argument(argument, arg);
    if (!str_cmp("nuyen", arg)) {
      argument = one_argument(argument, arg);
      if ((vict = give_find_vict(ch, arg)))
        perform_give_gold(ch, vict, amount);
      return;
    } else {
      /* code to give multiple items.  anyone want to write it? -je */
      send_to_char("You can't give more than one item at a time.\r\n", ch);
      return;
    }
  } else {
    one_argument(argument, buf1);
    if (!(vict = give_find_vict(ch, buf1)))
      return;
    dotmode = find_all_dots(arg);
    if (dotmode == FIND_INDIV) {
      if (!(obj = get_obj_in_list_vis(ch, arg, ch->carrying))) {
        sprintf(buf, "You don't seem to have %s %s.\r\n", AN(arg), arg);
        send_to_char(buf, ch);
      } else
        perform_give(ch, vict, obj);
    } else {
      if (dotmode == FIND_ALLDOT && !*arg) {
        send_to_char("All of what?\r\n", ch);
        return;
      }
      if (!ch->carrying)
        send_to_char("You don't seem to be holding anything.\r\n", ch);
      else
        for (obj = ch->carrying; obj; obj = next_obj) {
          next_obj = obj->next_content;
          if (CAN_SEE_OBJ(ch, obj) &&
              ((dotmode == FIND_ALL || isname(arg, obj->name))))
            perform_give(ch, vict, obj);
        }
    }
  }
}

ACMD(do_transfer)
{
  send_to_char("Sorry, but you cannot do that here!\r\n", ch);
}

/* Everything from here down is what was formerly act.obj2.c */

void weight_change_object(struct obj_data * obj, int weight)
{
  struct obj_data *tmp_obj;
  struct char_data *tmp_ch;

  if (obj->in_room != NOWHERE) {
    GET_OBJ_WEIGHT(obj) += weight;
  } else if ((tmp_ch = obj->carried_by)) {
      obj_from_char(obj);
      GET_OBJ_WEIGHT(obj) += weight;
      obj_to_char(obj, tmp_ch);
  } else if ((tmp_obj = obj->in_obj)) {
    obj_from_obj(obj);
    GET_OBJ_WEIGHT(obj) += weight;
    obj_to_obj(obj, tmp_obj);
  } else {
    log("SYSERR: Unknown attempt to subtract weight from an object.");
  }
}

// this removes the name from the drinkcon, however, after rewriting it,
// I decided it was silly to use in the first place, hehehe
void name_from_drinkcon(struct obj_data *obj)
{
  char token[80], *temp; // hopefully this will be enough, hehehe
  extern struct obj_data *obj_proto;

  temp = get_token(obj->name, token);

  buf2[0] = '\0'; // so strcats will start at the beginning

  int i = 0;
  while (*token && strcasecmp(token, drinks[GET_OBJ_VAL(obj, 2)]))
  {
    strcat(buf2, token);
    strcat(buf2, " ");
    temp = get_token(temp, token);
    ++i;
  }

  // we do this in case there's only one word in the name list and it
  // is the name of the liquid
  if (i < 1)
    return;

  // now, we copy the remaining string onto the end of buf2
  if (temp)
    strcat(buf2, temp);

  buf2[strlen(buf2)] = '\0'; // remove the trailing space

  // only delete the object name if this object has a unique name
  if (GET_OBJ_RNUM(obj) < 0 || obj->name != obj_proto[GET_OBJ_RNUM(obj)].name)
    delete [] obj->name;
  // otherwise it just gets pointed to the new namelist
  obj->name = str_dup(buf2);
}

void name_to_drinkcon(struct obj_data * obj, int type)
{
  char *new_name;
  extern struct obj_data *obj_proto;
  extern char *drinknames[];

  new_name = new char[strlen(obj->name) + strlen(drinknames[type]) + 2];
  sprintf(new_name, "%s %s", drinknames[type], obj->name);
  if (GET_OBJ_RNUM(obj) < 0 || obj->name != obj_proto[GET_OBJ_RNUM(obj)].name)
    delete [] obj->name;
  obj->name = new_name;
}

ACMD(do_drink)
{
  struct obj_data *temp, *cyber;
  struct affected_type af;
  extern struct index_data *obj_index;
  int amount, weight, resist, potency = 0;
  int on_ground = 0;

  one_argument(argument, arg);

  if (IS_PERSONA(ch)) {
    send_to_char("That is not a valid command.\r\n", ch);
    return;
  }

  if (IS_ASTRAL(ch)) {
    send_to_char("Astral forms can't retain fluid.\r\n", ch);
    return;
  }

  if (!*arg) {
    send_to_char("Drink from what?\r\n", ch);
    return;
  }
  if (!(temp = get_obj_in_list_vis(ch, arg, ch->carrying))) {
    if (!(temp = get_obj_in_list_vis(ch, arg, world[ch->in_room].contents))) {
      act("You can't find it!", FALSE, ch, 0, 0, TO_CHAR);
      return;
    } else
      on_ground = 1;
  }
  if ((GET_OBJ_TYPE(temp) != ITEM_DRINKCON) &&
      (GET_OBJ_TYPE(temp) != ITEM_FOUNTAIN)) {
    send_to_char("You can't drink from that!\r\n", ch);
    return;
  }
  if (on_ground && (GET_OBJ_TYPE(temp) == ITEM_DRINKCON)) {
    send_to_char("You have to be holding that to drink from it.\r\n", ch);
    return;
  }
  if ((GET_COND(ch, DRUNK) > 10) && (GET_COND(ch, THIRST) > 0)) {
    /* The pig is drunk */
    send_to_char("You can't seem to get close enough to your mouth.\r\n", ch);
    act("$n tries to drink but misses $s mouth!", TRUE, ch, 0, 0, TO_ROOM);
    return;
  }
  if ((GET_COND(ch, FULL) > 20) && (GET_COND(ch, THIRST) > 0)) {
    send_to_char("Your stomach can't contain anymore!\r\n", ch);
    return;
  }
  if (!GET_OBJ_VAL(temp, 1)) {
    send_to_char("It's empty.\r\n", ch);
    return;
  }
  if (subcmd == SCMD_DRINK) {
    sprintf(buf, "$n drinks %s from $p.", drinks[GET_OBJ_VAL(temp, 2)]);
    act(buf, TRUE, ch, temp, 0, TO_ROOM);

    sprintf(buf, "You drink the %s.\r\n", drinks[GET_OBJ_VAL(temp, 2)]);
    send_to_char(buf, ch);
    if (drink_aff[GET_OBJ_VAL(temp, 2)][DRUNK] > 0)
      amount = (25 - GET_COND(ch, THIRST)) / drink_aff[GET_OBJ_VAL(temp, 2)][DRUNK];
    else amount = number(3, 10);
  } else {
    act("$n sips from $p.", TRUE, ch, temp, 0, TO_ROOM);
    sprintf(buf, "It tastes like %s.\r\n", drinks[GET_OBJ_VAL(temp, 2)]);
    send_to_char(buf, ch);
    amount = 1;
  }

  amount = MIN(amount, GET_OBJ_VAL(temp, 1));

  /* You can't subtract more than the object weighs */
  weight = MIN(amount, GET_OBJ_WEIGHT(temp));

  weight_change_object(temp, -weight);  /* Subtract amount */

  gain_condition(ch, DRUNK,
         (int) ((int) drink_aff[GET_OBJ_VAL(temp, 2)][DRUNK] * amount) / 4);

  gain_condition(ch, FULL,
          (int) ((int) drink_aff[GET_OBJ_VAL(temp, 2)][FULL] * amount) / 4);

  gain_condition(ch, THIRST,
        (int) ((int) drink_aff[GET_OBJ_VAL(temp, 2)][THIRST] * amount) / 4);

  if (GET_COND(ch, DRUNK) > 10)
    send_to_char("You feel drunk.\r\n", ch);

  if (GET_COND(ch, THIRST) > 20)
    send_to_char("You don't feel thirsty any more.\r\n", ch);

  if (GET_COND(ch, FULL) > 20)
    send_to_char("You are full.\r\n", ch);

  if (GET_OBJ_VAL(temp, 3)) {   /* The shit was poisoned ! */
    send_to_char("It tasted rather strange!\r\n", ch);
    act("$n chokes and utters some strange sounds.", TRUE, ch, 0, 0, TO_ROOM);
    resist = GET_BOD(ch);
    for (cyber = ch->cyberware; cyber; cyber = cyber->next_content)
      if (GET_OBJ_VAL(cyber, 2) == 26)
        resist += GET_OBJ_VAL(cyber, 0);
    if ((potency = resisted_test(resist, GET_OBJ_VAL(temp, 3), GET_OBJ_VAL(temp, 3), resist) <= 0)) {
      af.type = SPELL_POISON;
      af.duration = potency;
      af.modifier = MODERATE;
      af.location = APPLY_NONE;
      af.bitvector = AFF_POISON;
      af.sustained_by = 0;
      af.caster = FALSE;
      affect_to_char(ch, &af);
    }
  }
  /* empty the container, and no longer poison. */
  GET_OBJ_VAL(temp, 1) -= amount;
  if (!GET_OBJ_VAL(temp, 1)) {  /* The last bit */
    //name_from_drinkcon(temp); // do this first
    GET_OBJ_VAL(temp, 2) = 0;
    GET_OBJ_VAL(temp, 3) = 0;
  }
  return;
}

ACMD(do_eat)
{
  SPECIAL(anticoagulant);
  struct obj_data *food, *cyber;
  struct affected_type af;
  int amount, resist, potency;

  if (IS_ASTRAL(ch) || IS_PERSONA(ch)) {
    send_to_char("Eat?!  You don't even have a stomach!.\r\n", ch);
    return;
  }

  one_argument(argument, arg);

  if (!*arg) {
    send_to_char("Eat what?\r\n", ch);
    return;
  }
  if (!(food = get_obj_in_list_vis(ch, arg, ch->carrying))) {
    sprintf(buf, "You don't seem to have %s %s.\r\n", AN(arg), arg);
    send_to_char(buf, ch);
    return;
  }
  if (subcmd == SCMD_TASTE && ((GET_OBJ_TYPE(food) == ITEM_DRINKCON) ||
           (GET_OBJ_TYPE(food) == ITEM_FOUNTAIN))) {
    do_drink(ch, argument, 0, SCMD_SIP);
    return;
  }
  if ((GET_OBJ_TYPE(food) != ITEM_FOOD) && (GET_LEVEL(ch) < LVL_ARCHITECT)) {
    send_to_char("You can't eat THAT!\r\n", ch);
    return;
  }
  if (GET_COND(ch, FULL) > 20) {/* Stomach full */
    act("You are too full to eat more!", FALSE, ch, 0, 0, TO_CHAR);
    return;
  }
  if (subcmd == SCMD_EAT) {
    act("You eat the $o.", FALSE, ch, food, 0, TO_CHAR);
    act("$n eats $p.", TRUE, ch, food, 0, TO_ROOM);
    if (GET_OBJ_SPEC(food) && GET_OBJ_SPEC(food) == anticoagulant) {
      for (cyber = ch->bioware; cyber; cyber = cyber->next_content)
        if (GET_OBJ_VAL(cyber, 2) == 0) {
          GET_OBJ_VAL(cyber, 5) = 36;
          GET_OBJ_VAL(cyber, 6) = 0;
          break;
        }
    }
  } else {
    act("You nibble a little bit of the $o.", FALSE, ch, food, 0, TO_CHAR);
    act("$n tastes a little bit of $p.", TRUE, ch, food, 0, TO_ROOM);
  }

  amount = (subcmd == SCMD_EAT ? GET_OBJ_VAL(food, 0) : 1);

  gain_condition(ch, FULL, amount);

  if (GET_COND(ch, FULL) > 20)
    act("You are full.", FALSE, ch, 0, 0, TO_CHAR);

  if (GET_OBJ_VAL(food, 3) && (GET_LEVEL(ch) < LVL_LEGEND)) {
    /* The shit was poisoned ! */
    send_to_char("That tasted rather strange!\r\n", ch);
    act("$n coughs and utters some strange sounds.", FALSE, ch, 0, 0, TO_ROOM);
    resist = GET_BOD(ch);
    for (cyber = ch->cyberware; cyber; cyber = cyber->next_content)
      if (GET_OBJ_VAL(cyber, 2) == 26)
        resist += GET_OBJ_VAL(cyber, 0);
    if ((potency = resisted_test(resist, GET_OBJ_VAL(food, 3), GET_OBJ_VAL(food, 3), resist) <= 0)) {
      af.type = SPELL_POISON;
      af.duration = -potency;
      af.modifier = LIGHT;
      af.location = APPLY_NONE;
      af.bitvector = AFF_POISON;
      af.sustained_by = 0;
      af.caster = FALSE;
      affect_to_char(ch, &af);
    }
  }
  if (subcmd == SCMD_EAT)
    extract_obj(food);
  else {
    if (!(--GET_OBJ_VAL(food, 0))) {
      send_to_char("There's nothing left now.\r\n", ch);
      extract_obj(food);
    }
  }
}

ACMD(do_pour)
{
  char arg1[MAX_INPUT_LENGTH];
  char arg2[MAX_INPUT_LENGTH];
  struct obj_data *from_obj = NULL, *to_obj = NULL;
  int amount;

  if (IS_PERSONA(ch)) {
    send_to_char("That is not a valid command.\r\n", ch);
    return;
  }

  two_arguments(argument, arg1, arg2);

  if (subcmd == SCMD_POUR) {
    if (!*arg1) {               /* No arguments */
      act("What do you want to pour from?", FALSE, ch, 0, 0, TO_CHAR);
      return;
    }
    if (!(from_obj = get_obj_in_list_vis(ch, arg1, ch->carrying))) {
      act("You can't find it!", FALSE, ch, 0, 0, TO_CHAR);
      return;
    }
    if (GET_OBJ_TYPE(from_obj) != ITEM_DRINKCON) {
      act("You can't pour from that!", FALSE, ch, 0, 0, TO_CHAR);
      return;
    }
  }
  if (subcmd == SCMD_FILL) {
    if (!*arg1) {               /* no arguments */
      send_to_char("What do you want to fill?  And what are you filling it from?\r\n", ch);
      return;
    }
    if (!(to_obj = get_obj_in_list_vis(ch, arg1, ch->carrying))) {
      send_to_char("You can't find it!", ch);
      return;
    }
    if (GET_OBJ_TYPE(to_obj) != ITEM_DRINKCON) {
      act("You can't fill $p!", FALSE, ch, to_obj, 0, TO_CHAR);
      return;
    }
    if (!*arg2) {               /* no 2nd argument */
      act("What do you want to fill $p from?", FALSE, ch, to_obj, 0, TO_CHAR);
      return;
    }
    if (!(from_obj = get_obj_in_list_vis(ch, arg2, world[ch->in_room].contents))) {
      sprintf(buf, "There doesn't seem to be %s %s here.\r\n", AN(arg2), arg2);
      send_to_char(buf, ch);
      return;
    }
    if (GET_OBJ_TYPE(from_obj) != ITEM_FOUNTAIN) {
      act("You can't fill something from $p.", FALSE, ch, from_obj, 0, TO_CHAR);
      return;
    }
  }
  if (GET_OBJ_VAL(from_obj, 1) == 0) {
    act("The $p is empty.", FALSE, ch, from_obj, 0, TO_CHAR);
    return;
  }
  if (subcmd == SCMD_POUR) {    /* pour */
    if (!*arg2) {
      act("Where do you want it?  Out or in what?", FALSE, ch, 0, 0, TO_CHAR);
      return;
    }
    if (!str_cmp(arg2, "out")) {
      act("$n empties $p.", TRUE, ch, from_obj, 0, TO_ROOM);
      act("You empty $p.", FALSE, ch, from_obj, 0, TO_CHAR);

      weight_change_object(from_obj, -GET_OBJ_VAL(from_obj, 1));        /* Empty */

      GET_OBJ_VAL(from_obj, 1) = 0;
      GET_OBJ_VAL(from_obj, 2) = 0;
      GET_OBJ_VAL(from_obj, 3) = 0;
      name_from_drinkcon(from_obj);

      return;
    }
    if (!(to_obj = get_obj_in_list_vis(ch, arg2, ch->carrying))) {
      act("You can't find it!", FALSE, ch, 0, 0, TO_CHAR);
      return;
    }
    if ((GET_OBJ_TYPE(to_obj) != ITEM_DRINKCON) &&
        (GET_OBJ_TYPE(to_obj) != ITEM_FOUNTAIN)) {
      act("You can't pour anything into that.", FALSE, ch, 0, 0, TO_CHAR);
      return;
    }
  }
  if (to_obj == from_obj) {
    act("A most unproductive effort.", FALSE, ch, 0, 0, TO_CHAR);
    return;
  }
  if ((GET_OBJ_VAL(to_obj, 1) != 0) &&
      (GET_OBJ_VAL(to_obj, 2) != GET_OBJ_VAL(from_obj, 2))) {
    act("There is already another liquid in it!", FALSE, ch, 0, 0, TO_CHAR);
    return;
  }
  if (!(GET_OBJ_VAL(to_obj, 1) < GET_OBJ_VAL(to_obj, 0))) {
    act("There is no room for more.", FALSE, ch, 0, 0, TO_CHAR);
    return;
  }
  if (subcmd == SCMD_POUR) {
    sprintf(buf, "You pour the %s into the %s.",
            drinks[GET_OBJ_VAL(from_obj, 2)], arg2);
    send_to_char(buf, ch);
  }
  if (subcmd == SCMD_FILL) {
    act("You gently fill $p from $P.", FALSE, ch, to_obj, from_obj, TO_CHAR);
    act("$n gently fills $p from $P.", TRUE, ch, to_obj, from_obj, TO_ROOM);
  }
  /* New alias */
  if (GET_OBJ_VAL(to_obj, 1) == 0)
    name_to_drinkcon(to_obj, GET_OBJ_VAL(from_obj, 2));

  /* First same type liq. */
  GET_OBJ_VAL(to_obj, 2) = GET_OBJ_VAL(from_obj, 2);

  /* Then how much to pour */
  GET_OBJ_VAL(from_obj, 1) -= (amount =
                         (GET_OBJ_VAL(to_obj, 0) - GET_OBJ_VAL(to_obj, 1)));

  GET_OBJ_VAL(to_obj, 1) = GET_OBJ_VAL(to_obj, 0);

  if (GET_OBJ_VAL(from_obj, 1) < 0) {   /* There was too little */
    GET_OBJ_VAL(to_obj, 1) += GET_OBJ_VAL(from_obj, 1);
    amount += GET_OBJ_VAL(from_obj, 1);
    GET_OBJ_VAL(from_obj, 1) = 0;
    GET_OBJ_VAL(from_obj, 2) = 0;
    GET_OBJ_VAL(from_obj, 3) = 0;
    name_from_drinkcon(from_obj);
  }
  /* Then the poison boogie */
  GET_OBJ_VAL(to_obj, 3) =
    (GET_OBJ_VAL(to_obj, 3) || GET_OBJ_VAL(from_obj, 3));

  /* And the weight boogie */
  weight_change_object(from_obj, -amount);
  weight_change_object(to_obj, amount); /* Add weight */

  return;
}

void wear_message(struct char_data * ch, struct obj_data * obj, int where)
{
  char *wear_messages[][2] = {
    {"$n activate $p and holds it.",
    "You activate $p and hold it."},

    {"$n slides $p on to $s right ring finger.",
    "You slide $p on to your right ring finger."},

    {"$n slides $p on to $s left ring finger.",
    "You slide $p on to your left ring finger."},

    {"$n wears $p around $s neck.",
    "You wear $p around your neck."},

    {"$n wears $p around $s neck.",
    "You wear $p around your neck."},

    {"$n wears $p on $s body.",
    "You wear $p on your body.",},

    {"$n wears $p on $s head.",
    "You wear $p on your head."},

    {"$n puts $p on $s legs.",
    "You put $p on your legs."},

    {"$n wears $p on $s feet.",
    "You wear $p on your feet."},

    {"$n puts $p on $s hands.",
    "You put $p on your hands."},

    {"$n wears $p on $s arms.",
    "You wear $p on your arms."},

    {"$n straps $p around $s arm as a shield.",
    "You start to use $p as a shield."},

    {"$n wears $p about $s body.",
    "You wear $p around your body."},

    {"$n wears $p around $s waist.",
    "You wear $p around your waist."},

    {"$n puts $p on around $s right wrist.",
    "You put $p on around your right wrist."},

    {"$n puts $p on around $s left wrist.",
    "You put $p on around your left wrist."},

    {"$n wields $p.",
    "You wield $p."},

    {"$n grabs $p.",
    "You grab $p."},

    {"$n wears $p on $s eyes.",
     "You wear $p on your eyes."},

    {"$n wears $p in $s ear.",
     "You wear $p in your ear."}
  };
  /* Should we add move waer types?*/
  if (where == WEAR_WIELD || where == WEAR_HOLD) {
    if (GET_WIELDED(ch, where - WEAR_WIELD)) {
      act(wear_messages[WEAR_WIELD][0], TRUE, ch, obj, 0, TO_ROOM);
      act(wear_messages[WEAR_WIELD][1], FALSE, ch, obj, 0, TO_CHAR);
    } else {
      act(wear_messages[WEAR_HOLD][0], TRUE, ch, obj, 0, TO_ROOM);
      act(wear_messages[WEAR_HOLD][1], FALSE, ch, obj, 0, TO_CHAR);
    }
  } else {
    act(wear_messages[where][0], TRUE, ch, obj, 0, TO_ROOM);
    act(wear_messages[where][1], FALSE, ch, obj, 0, TO_CHAR);
  }
}

int can_wield_both(struct char_data *ch, struct obj_data *one, struct obj_data *two)
{
  if (!one || !two)
    return FALSE;

  if (GET_OBJ_TYPE(one) != ITEM_WEAPON || GET_OBJ_TYPE(two) != ITEM_WEAPON)
    return FALSE;

  if ((IS_GUN(GET_OBJ_VAL(one, 3)) && !IS_GUN(GET_OBJ_VAL(two, 3))) ||
      (IS_GUN(GET_OBJ_VAL(two, 3)) && !IS_GUN(GET_OBJ_VAL(one, 3))))
    return FALSE;
  else
    if ((GET_OBJ_VAL(one, 3) > TYPE_THROWING_KNIFE && GET_OBJ_VAL(one, 3) < TYPE_PISTOL)
        || (GET_OBJ_VAL(two, 3) > TYPE_THROWING_KNIFE && GET_OBJ_VAL(two, 3) < TYPE_PISTOL))
      return FALSE;

  return TRUE;
}

void perform_wear(struct char_data * ch, struct obj_data * obj, int where)
{
  struct obj_data *wielded = GET_EQ(ch, WEAR_WIELD);

  int wear_bitvectors[] = {
    ITEM_WEAR_TAKE, ITEM_WEAR_FINGER, ITEM_WEAR_FINGER, ITEM_WEAR_NECK,
    ITEM_WEAR_NECK, ITEM_WEAR_BODY, ITEM_WEAR_HEAD, ITEM_WEAR_LEGS,
    ITEM_WEAR_FEET, ITEM_WEAR_HANDS, ITEM_WEAR_ARMS, ITEM_WEAR_SHIELD,
    ITEM_WEAR_ABOUT, ITEM_WEAR_WAIST, ITEM_WEAR_WRIST, ITEM_WEAR_WRIST,
    ITEM_WEAR_WIELD, ITEM_WEAR_TAKE, ITEM_WEAR_EYES, ITEM_WEAR_EAR};

  char *already_wearing[] = {
    "You're already using a light.\r\n",
    "YOU SHOULD NEVER SEE THIS MESSAGE.  PLEASE REPORT.\r\n",
    "You're already wearing something on both of your ring fingers.\r\n",
    "YOU SHOULD NEVER SEE THIS MESSAGE.  PLEASE REPORT.\r\n",
    "You can't wear anything else around your neck.\r\n",
    "You're already wearing something on your body.\r\n",
    "You're already wearing something on your head.\r\n",
    "You're already wearing something on your legs.\r\n",
    "You're already wearing something on your feet.\r\n",
    "You're already wearing something on your hands.\r\n",
    "You're already wearing something on your arms.\r\n",
    "You're already using a shield.\r\n",
    "You're already wearing something about your body.\r\n",
    "You already have something around your waist.\r\n",
    "YOU SHOULD NEVER SEE THIS MESSAGE.  PLEASE REPORT.\r\n",
    "You're already wearing something around both of your wrists.\r\n",
    "You're already wielding a weapon.\r\n",
    "You're already holding something.\r\n",
    "You're already wearing something on your eyes.\r\n",
    "You're already wearing something in your ear.\r\n"
  };

  /* first, make sure that the wear position is valid. */
  if (!CAN_WEAR(obj, wear_bitvectors[where])) {
    act("You can't wear $p there.", FALSE, ch, obj, 0, TO_CHAR);
    return;
  }

  /* for neck, finger, and wrist, try pos 2 if pos 1 is already full */
  if ((where == WEAR_FINGER_R) || (where == WEAR_NECK_1) || (where == WEAR_WRIST_R))
    if (GET_EQ(ch, where))
      where++;

  if ((where == WEAR_WIELD || where == WEAR_HOLD) && IS_OBJ_STAT(obj, ITEM_TWOHANDS) &&
      (GET_EQ(ch, WEAR_SHIELD) || GET_EQ(ch, WEAR_HOLD) || GET_EQ(ch, WEAR_WIELD))) {
    act("$p requires two free hands.", FALSE, ch, obj, 0, TO_CHAR);
    return;
  }

  if (where == WEAR_WIELD) {
    if (!wielded) {
      if (GET_WIELDED(ch, 1) && !can_wield_both(ch, obj, GET_EQ(ch, WEAR_HOLD))) {
        act("That wouldn't work very well.", FALSE, ch, 0, 0, TO_CHAR);
        return;
      } else GET_WIELDED(ch, 0) = 1;
    } else {
      /* if attempting to wield a second weapon... */
      if (GET_EQ(ch, WEAR_HOLD)) {
        send_to_char("Your hands are already full!\r\n", ch);
        return;
      }
      where = WEAR_HOLD;
      if (!can_wield_both(ch, wielded, obj)) {
        act("That wouldn't work very well.", FALSE, ch, 0, 0, TO_CHAR);
        return;
      }
      GET_WIELDED(ch, 1) = 1;
    }
  } else if (GET_EQ(ch, where)) {
    send_to_char(already_wearing[where], ch);
    return;
  }

  if (GET_EQ(ch, WEAR_WIELD) && IS_OBJ_STAT(GET_EQ(ch, WEAR_WIELD), ITEM_TWOHANDS) &&
      (where == WEAR_HOLD || where == WEAR_SHIELD)) {
    act("$p requires two free hands.", FALSE, ch, GET_EQ(ch, WEAR_WIELD), 0, TO_CHAR);
    return;
  } else if (GET_EQ(ch, WEAR_HOLD) && IS_OBJ_STAT(GET_EQ(ch, WEAR_HOLD), ITEM_TWOHANDS) &&
             (where == WEAR_WIELD || where == WEAR_SHIELD)) {
    act("$p requires two free hands.", FALSE, ch, GET_EQ(ch, WEAR_HOLD), 0, TO_CHAR);
    return;
  }

  wear_message(ch, obj, where);
  obj_from_char(obj);
  equip_char(ch, obj, where);
}

int find_eq_pos(struct char_data * ch, struct obj_data * obj, char *arg)
{
  int where = -1;

  static const char *keywords[] = {
    "!RESERVED!",
    "finger",
    "!RESERVED!",
    "neck",
    "!RESERVED!",
    "body",
    "head",
    "legs",
    "feet",
    "hands",
    "arms",
    "shield",
    "about",
    "waist",
    "wrist",
    "!RESERVED!",
    "!RESERVED!",
    "!RESERVED!",
    "eyes",
    "ear",
    "\n"
  };

  if (!arg || !*arg) {
    if (CAN_WEAR(obj, ITEM_WEAR_FINGER))      where = WEAR_FINGER_R;
    if (CAN_WEAR(obj, ITEM_WEAR_NECK))        where = WEAR_NECK_1;
    if (CAN_WEAR(obj, ITEM_WEAR_BODY))        where = WEAR_BODY;
    if (CAN_WEAR(obj, ITEM_WEAR_HEAD))        where = WEAR_HEAD;
    if (CAN_WEAR(obj, ITEM_WEAR_LEGS))        where = WEAR_LEGS;
    if (CAN_WEAR(obj, ITEM_WEAR_FEET))        where = WEAR_FEET;
    if (CAN_WEAR(obj, ITEM_WEAR_HANDS))       where = WEAR_HANDS;
    if (CAN_WEAR(obj, ITEM_WEAR_ARMS))        where = WEAR_ARMS;
    if (CAN_WEAR(obj, ITEM_WEAR_SHIELD))      where = WEAR_SHIELD;
    if (CAN_WEAR(obj, ITEM_WEAR_ABOUT))       where = WEAR_ABOUT;
    if (CAN_WEAR(obj, ITEM_WEAR_WAIST))       where = WEAR_WAIST;
    if (CAN_WEAR(obj, ITEM_WEAR_WRIST))       where = WEAR_WRIST_R;
    if (CAN_WEAR(obj, ITEM_WEAR_EYES))        where = WEAR_EYES;
    if (CAN_WEAR(obj, ITEM_WEAR_EAR))         where = WEAR_EAR;
  } else {
    if ((where = search_block(arg, keywords, FALSE)) < 0) {
      sprintf(buf, "'%s'?  What part of your body is THAT?\r\n", arg);
      send_to_char(buf, ch);
    }
  }

  return where;
}

ACMD(do_load)
{
  ACMD(do_wizload);
  char arg1[MAX_INPUT_LENGTH];
  char arg2[MAX_INPUT_LENGTH];
  struct obj_data *obj, *next_obj;
  int where, dotmode, items_worn = 0, wait, i = 0;

  if (!IS_NPC(ch)) {
    if (access_level(ch, LVL_PRESIDENT)) {
      do_wizload(ch, argument, 0, 0);
      return;
    } else {
      send_to_char("You are not connected to the Matrix!\r\n", ch);
      return;
    }
  }

  if (!IS_PERSONA(ch)) {
    send_to_char("Only personas can load programs.\r\n", ch);
    return;
  }

  two_arguments(argument, arg1, arg2);

  if (!*arg1) {
    send_to_char("Load what?\r\n", ch);
    return;
  }
  dotmode = find_all_dots(arg1);

  if (dotmode == FIND_ALL || dotmode == FIND_ALLDOT) {
    send_to_char("One program at a time!\r\n", ch);
    return;
  } else {
    if (!(obj = get_obj_in_list_vis(ch, arg1, ch->carrying))) {
      sprintf(buf, "You don't seem to have %s %s.\r\n", AN(arg1), arg1);
      send_to_char(buf, ch);
      return;
    }
    if (GET_OBJ_VAL(obj, 2) > GET_ACTIVE(ch)) {
      send_to_char("You don't have enough active memory available to load that program.\r\n", ch);
      return;
    }
    switch (GET_PROG_TYPE(obj)) {
      case PROG_ATTACK:    i = WEAR_WIELD; break;
      case PROG_SLEAZE:    i = WEAR_HEAD; break;
      case PROG_SLOW:      i = WEAR_FEET; break;
      case PROG_ANALYZE:   i = WEAR_BODY; break;
      case PROG_MEDIC:     i = WEAR_LEGS; break;
      case PROG_MIRRORS:   i = WEAR_HANDS; break;
      case PROG_SHIELD:    i = WEAR_SHIELD; break;
      case PROG_SMOKE:     i = WEAR_ARMS; break;
      case PROG_DECRYPT:   i = WEAR_ABOUT; break;
      case PROG_DECEPTION: i = WEAR_WAIST; break;
      case PROG_RELOCATE:  i = WEAR_HOLD; break;
      deafult:             i = WEAR_HOLD; break;
    }
    if (GET_EQ(ch, i)) {
      act("You already have $p loaded.", FALSE, ch, GET_EQ(ch, i), 0, TO_CHAR);
      return;
    }
    obj_from_char(obj);
    equip_char(ch, obj, i);
    act("You load $p into active memory.", FALSE, ch, obj, 0, TO_CHAR);
    GET_ACTIVE(ch) -= GET_OBJ_VAL(obj, 2);
    WAIT_STATE(ch, (MAX(0, ((int)(GET_OBJ_VAL(obj, 2) / GET_LOAD_SPEED(ch)))) * PULSE_VIOLENCE));
  }
}

ACMD(do_wear)
{
  char arg1[MAX_INPUT_LENGTH];
  char arg2[MAX_INPUT_LENGTH];
  struct obj_data *obj, *next_obj;
  int where = -1, dotmode, items_worn = 0, wait;

  two_arguments(argument, arg1, arg2);

  if (IS_PERSONA(ch))
  {
    send_to_char("That is not a valid command.\r\n", ch);
    return;
  }

  if (!*arg1)
  {
    send_to_char("Wear what?\r\n", ch);
    return;
  }
  dotmode = find_all_dots(arg1);

  if (*arg2 && (dotmode != FIND_INDIV))
  {
    send_to_char("You can't specify the same body location for more than one item!\r\n", ch);
    return;
  }
  if (dotmode == FIND_ALL)
  {
    for (obj = ch->carrying; obj; obj = next_obj)
    {
      next_obj = obj->next_content;
      if (CAN_SEE_OBJ(ch, obj) && (where = find_eq_pos(ch, obj, 0)) >= 0)
      {
        items_worn++;
        perform_wear(ch, obj, where);
      }
    }
    if (!items_worn)
      send_to_char("You don't seem to have anything wearable.\r\n", ch);
  }
  else if (dotmode == FIND_ALLDOT)
  {
    if (!*arg1)
    {
      send_to_char("Wear all of what?\r\n", ch);
      return;
    }
    if (!(obj = get_obj_in_list_vis(ch, arg1, ch->carrying)))
    {
      sprintf(buf, "You don't seem to have any %ss.\r\n", arg1);
      send_to_char(buf, ch);
    }
    else
      while (obj)
      {
        next_obj = get_obj_in_list_vis(ch, arg1, obj->next_content);
        if ((where = find_eq_pos(ch, obj, 0)) >= 0)
          perform_wear(ch, obj, where);
        else act("You can't wear $p.", FALSE, ch, obj, 0, TO_CHAR);
        obj = next_obj;
      }
  }
  else
  {
    if (!(obj = get_obj_in_list_vis(ch, arg1, ch->carrying)))
    {
      sprintf(buf, "You don't seem to have %s %s.\r\n", AN(arg1), arg1);
      send_to_char(buf, ch);
    }
    else
    {
      if ((where = find_eq_pos(ch, obj, arg2)) >= 0)
        perform_wear(ch, obj, where);
      else if (!*arg2)
        act("You can't wear $p.", FALSE, ch, obj, 0, TO_CHAR);
    }
  }
}

ACMD(do_wield)
{
  struct obj_data *obj;

  if (IS_PERSONA(ch)) {
    send_to_char("That is not a valid command.\r\n", ch);
    return;
  }

  one_argument(argument, arg);

  if (!*arg)
    send_to_char("Wield what?\r\n", ch);
  else if (!(obj = get_obj_in_list_vis(ch, arg, ch->carrying))) {
    sprintf(buf, "You don't seem to have %s %s.\r\n", AN(arg), arg);
    send_to_char(buf, ch);
  } else {
    if (!CAN_WEAR(obj, ITEM_WEAR_WIELD))
      send_to_char("You can't wield that.\r\n", ch);
    else if (GET_OBJ_WEIGHT(obj) > str_app[STRENGTH_APPLY_INDEX(ch)].wield_w)
      send_to_char("It's too heavy for you to use.\r\n", ch);
    else if (GET_OBJ_TYPE(obj) == ITEM_FIREWEAPON &&
            ((!GET_OBJ_VAL(obj, 5) && GET_STR(ch) < GET_OBJ_VAL(obj, 6)) ||
            (GET_OBJ_VAL(obj, 5) == 1 && GET_STR(ch) < (GET_OBJ_VAL(obj, 1) + 2))))
      send_to_char("You aren't strong enough to use that weapon.\r\n", ch);
    else perform_wear(ch, obj, WEAR_WIELD);
  }
}

ACMD(do_grab)
{
  struct obj_data *obj;

  one_argument(argument, arg);

  if (IS_PERSONA(ch)) {
    send_to_char("That is not a valid command.\r\n", ch);
    return;
  }

  if (!*arg)
    send_to_char("Hold what?\r\n", ch);
  else if (!(obj = get_obj_in_list_vis(ch, arg, ch->carrying))) {
    sprintf(buf, "You don't seem to have %s %s.\r\n", AN(arg), arg);
    send_to_char(buf, ch);
  } else {
    if (GET_OBJ_TYPE(obj) == ITEM_LIGHT)
      perform_wear(ch, obj, WEAR_LIGHT);
    else {
      if (!CAN_WEAR(obj, ITEM_WEAR_HOLD) && GET_OBJ_TYPE(obj) != ITEM_WAND &&
      GET_OBJ_TYPE(obj) != ITEM_STAFF && GET_OBJ_TYPE(obj) != ITEM_SCROLL &&
          GET_OBJ_TYPE(obj) != ITEM_POTION)
        send_to_char("You can't hold that.\r\n", ch);
      else
           perform_wear(ch, obj, WEAR_HOLD);
    }
  }
}

void perform_remove(struct char_data * ch, int pos)
{
  struct obj_data *obj;

  if (!(obj = ch->equipment[pos])) {
    log("Error in perform_remove: bad pos passed.");
    return;
  }
  if (IS_CARRYING_N(ch) >= CAN_CARRY_N(ch))
    act("$p: you can't carry that many items!", FALSE, ch, obj, 0, TO_CHAR);
  else {
    if (IS_PERSONA(ch))
      GET_ACTIVE(ch) += GET_OBJ_VAL(GET_EQ(ch, pos), 2);
    obj_to_char(unequip_char(ch, pos), ch);
    act("You stop using $p.", FALSE, ch, obj, 0, TO_CHAR);
    act("$n stops using $p.", TRUE, ch, obj, 0, TO_ROOM);

    /* add damage back from stim patches */
    /* it doesn't do anything to keep track, */
    /* so I'm just makeing it a mod mental damage to it */
    if ( GET_OBJ_TYPE(obj) == ITEM_PATCH && GET_OBJ_VAL(obj, 0) == 1 )
    {
       GET_MENTAL(ch) = GET_OBJ_VAL(obj,5);
       GET_OBJ_VAL(obj,5) = 0;
	}
  }
}

ACMD(do_unload)
{
  struct obj_data *obj;
  int i, dotmode, found;

  if (!IS_PERSONA(ch)) {
    send_to_char("You have to be connected to do that.\r\n", ch);
    return;
  }

  one_argument(argument, arg);

  if (!*arg) {
    send_to_char("Unload what?\r\n", ch);
    return;
  }
  dotmode = find_all_dots(arg);

  if (dotmode == FIND_ALL) {

  } else if (dotmode == FIND_ALLDOT || dotmode == FIND_ALL)
    send_to_char("You can only unload one program at a time.\r\n", ch);
  else {
    if (!(obj = get_object_in_equip_vis(ch, arg, ch->equipment, &i))) {
      sprintf(buf, "You don't seem to have %s %s loaded.\r\n", AN(arg), arg);
      send_to_char(buf, ch);
    } else perform_remove(ch, i);
  }
}

ACMD(do_remove)
{
  struct obj_data *obj;
  int i, dotmode, found;

  one_argument(argument, arg);

  if (IS_PERSONA(ch)) {
    send_to_char("That is not a valid command.\r\n", ch);
    return;
  }

  if (!*arg) {
    send_to_char("Remove what?\r\n", ch);
    return;
  }

  dotmode = find_all_dots(arg);

  if (dotmode == FIND_ALL) {
    found = 0;
    for (i = 0; i < NUM_WEARS; i++)
      if (GET_EQ(ch, i)) {
        perform_remove(ch, i);
        found = 1;
      }
    if (!found)
      send_to_char("You're not using anything.\r\n", ch);
  } else if (dotmode == FIND_ALLDOT) {
    if (!*arg)
      send_to_char("Remove all of what?\r\n", ch);
    else {
      found = 0;
      for (i = 0; i < NUM_WEARS; i++)
        if (GET_EQ(ch, i) && CAN_SEE_OBJ(ch, GET_EQ(ch, i)) &&
            isname(arg, GET_EQ(ch, i)->name)) {
          perform_remove(ch, i);
          found = 1;
        }
      if (!found) {
        sprintf(buf, "You don't seem to be using any %ss.\r\n", arg);
        send_to_char(buf, ch);
      }
    }
  } else {
    if (!(obj = get_object_in_equip_vis(ch, arg, ch->equipment, &i))) {
      sprintf(buf, "You don't seem to be using %s %s.\r\n", AN(arg), arg);
      send_to_char(buf, ch);
    } else
      perform_remove(ch, i);
  }
}

ACMD(do_activate)
{
  struct obj_data *obj;
  int i;

  any_one_arg(argument, arg);

  if (!*arg) {
    send_to_char("What do you want to activate?\r\n", ch);
    return;
  }

  if (!(obj = get_obj_in_list_vis(ch, arg, ch->carrying)))
    if (!(obj = get_object_in_equip_vis(ch, arg, ch->equipment, &i))) {
      send_to_char(ch, "You don't have %s %s.", AN(arg), arg);
      return;
    }

  if (GET_OBJ_TYPE(obj) != ITEM_MONEY || !GET_OBJ_VAL(obj, 1)) {
    send_to_char("You can't activate that.\r\n", ch);
    return;
  } else if (GET_OBJ_VAL(obj, 4) != 0) {
    send_to_char("But that has already been activated!\r\n", ch);
    return;
  }

  if (!IS_NPC(ch)) {
    GET_OBJ_VAL(obj, 3) = 1;
    GET_OBJ_VAL(obj, 4) = GET_IDNUM(ch);
  } else {
    GET_OBJ_VAL(obj, 3) = 0;
    GET_OBJ_VAL(obj, 4) = ch->nr;
  }

  switch (GET_OBJ_VAL(obj, 2)) {
    case 1:
      GET_OBJ_VAL(obj, 5) = (number(1, 9) * 100000) + (number(0, 9) * 10000) +
                            (number(0, 9) * 1000) + (number(0, 9) * 100) +
                            (number(0, 9) * 10) + number(0, 9);
      send_to_char(ch, "You key %d as the passcode and the display flashes green.\r\n", GET_OBJ_VAL(obj,5));
      break;
    case 2:
      send_to_char("You press your thumb against the pad and the display flashes green.\r\n", ch);
      break;
    case 3:
      act("$p scans your retina and the display flashes green.\r\n", FALSE, ch, obj, 0, TO_CHAR);
      break;
  }
}

ACMD(do_type)
{
  struct obj_data *obj;
  int i;

  any_one_arg(any_one_arg(argument, arg), buf);

  if (!*arg || !*buf) {
    send_to_char("Type what into what?\r\n", ch);
    return;
  }

  if (!(obj = get_obj_in_list_vis(ch, arg, ch->carrying)))
    if (!(obj = get_object_in_equip_vis(ch, arg, ch->equipment, &i))) {
      send_to_char(ch, "You don't have %s %s.", AN(arg), arg);
      return;
    }

  if (GET_OBJ_TYPE(obj) != ITEM_MONEY || !GET_OBJ_VAL(obj, 1) || GET_OBJ_VAL(obj, 2) != 1) {
    send_to_char("You can't type a code into that!\r\n", ch);
    return;
  }

  i = atoi(buf);

  if (i < 100000 || i > 999999)
    send_to_char("Code must be 6-digits!\r\n", ch);
  else if (i != GET_OBJ_VAL(obj, 5))
    send_to_char("The display flashes red and beeps annoyingly.\r\n", ch);
  else {
    send_to_char("The display flashes green.\r\n", ch);
    GET_OBJ_VAL(obj, 3) = 0;
    GET_OBJ_VAL(obj, 4) = 0;
    GET_OBJ_VAL(obj, 5) = 0;
  }
}

ACMD(do_crack)
{
  int skill = SKILL_ELECTRONICS, mod = 0, rating, i;
  struct obj_data *obj;

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

  any_one_arg(argument, buf);

  if (!*buf) {
    send_to_char("What do you want to crack?\r\n", ch);
    return;
  }

  if (!(obj = get_obj_in_list_vis(ch, buf, ch->carrying)))
    if (!(obj = get_object_in_equip_vis(ch, buf, ch->equipment, &i))) {
      send_to_char(ch, "You don't have %s %s.\r\n", AN(buf), buf);
      return;
    }

  if (GET_OBJ_TYPE(obj) != ITEM_MONEY
      || !GET_OBJ_VAL(obj, 1)
      || GET_OBJ_VAL(obj, 2) > 3
      || !GET_OBJ_VAL(obj, 2)) {
    send_to_char("And how do you plan on doing that?\r\n", ch);
    return;
  } else if (!GET_OBJ_VAL(obj, 4)) {
    act("But $p's not even activated!", FALSE, ch, obj, 0, TO_CHAR);
    return;
  }

  rating = GET_OBJ_VAL(obj, 2) * 3 + 6 + mod;

  if (1)
    {
      char rbuf[MAX_STRING_LENGTH];
      sprintf(rbuf,"Crack: Skill %d, Rating %d, Modify Target %d.\n",
	      skill, rating, modify_target(ch));
      act(rbuf, FALSE, ch, NULL, NULL, TO_ROLLS);
    }

  if (!success_test(skill, rating + modify_target(ch)))
    act("$p sounds a series of beeps, and flashes red.", FALSE, ch, obj, 0, TO_CHAR);
  else {
    act("$p hums silently, and its display flashes green.", FALSE, ch, obj, 0, TO_CHAR);
    GET_OBJ_VAL(obj, 3) = 0;
    GET_OBJ_VAL(obj, 4) = 0;
    GET_OBJ_VAL(obj, 5) = 0;
  }
}