/* ************************************************************************
*  file: act.obj1.c , Implementation of commands.         Part of DIKUMUD *
*  Usage : Commands mainly moving around objects.                         *
*  Copyright (C) 1990, 1991 - see 'license.doc' for complete information. *
************************************************************************* */

#include <stdio.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"

#ifdef USE_PRIME
#define CAN_REALLY_TAKE(ch,obj) (CAN_WEAR(obj,ITEM_TAKE) && \
 (!IS_SET(obj->obj_flags.extra_flags,ITEM_PRIME) || \
 (GET_LEVEL(ch)>=(IMO>>3))) && \
 (!IS_SET(obj->obj_flags.extra_flags,ITEM_ANTIPRIME) || \
 (GET_LEVEL(ch)<=(IMO>>1))))
#else
#define CAN_REALLY_TAKE(ch,obj) CAN_WEAR(obj,ITEM_TAKE)
#endif

/* extern variables */

extern struct room_data *world;
extern struct descriptor_data *descriptor_list;
extern struct room_data *world;
     
/* extern functions */

struct obj_data *create_money( int amount );


/* procedures related to get */
void get(struct char_data *ch, struct obj_data *obj_object, 
  struct obj_data *sub_object)
{
  struct char_data *tmp_char;
  char buffer[MAX_STRING_LENGTH];
  int t;

  if (sub_object) {
    obj_from_obj(obj_object);
    obj_to_char(obj_object, ch);
    if (sub_object->carried_by == ch) {
      act("You get $p from $P.", 0, ch, obj_object, sub_object,
        TO_CHAR);
      act("$n gets $p from $P.", 1, ch, obj_object, sub_object, TO_ROOM);
    } else {
      act("You get $p from $P.", 0, ch, obj_object, sub_object,
        TO_CHAR);

      act("$n gets $p from $P.", 1, ch, obj_object, sub_object, TO_ROOM);
    }
  } else {
    obj_from_room(obj_object);
    obj_to_char(obj_object, ch);
    act("You get $p.", 0, ch, obj_object, 0, TO_CHAR);
    act("$n gets $p.", 1, ch, obj_object, 0, TO_ROOM);
  }
  if((obj_object->obj_flags.type_flag == ITEM_MONEY) && 
    (obj_object->obj_flags.value[0]>=1))
  {
    sprintf(buffer,"There was %d coins.\n\r", obj_object->obj_flags.value[0]);
    send_to_char(buffer,ch);
    t = GET_GOLD(ch) + obj_object->obj_flags.value[0];
    if(t > 0){
      obj_from_char(obj_object);
      GET_GOLD(ch) = t;
      extract_obj(obj_object);
    } else
      send_to_char("Your pockets are overloaded with gold.\n\r",ch);
  }
}


void do_get(struct char_data *ch, char *argument, int cmd)
{
  char arg1[MAX_STRING_LENGTH];
  char arg2[MAX_STRING_LENGTH];
  char buffer[MAX_STRING_LENGTH];
  struct obj_data *sub_object;
  struct obj_data *obj_object;
  struct obj_data *next_obj;
  bool found = FALSE;
  bool fail  = FALSE;
  int type   = 3;

  argument_interpreter(argument, arg1, arg2);

  /* get type */
  if (!*arg1) {
    type = 0;
  }
  if (*arg1 && !*arg2) {
    if (!str_cmp(arg1,"all")) {
      type = 1;
    } else {
      type = 2;
    }
  }
  if (*arg1 && *arg2) {
    if (!str_cmp(arg1,"all")) {
      if (!str_cmp(arg2,"all")) {
        type = 3;
      } else {
        type = 4;
      }
    } else {
      if (!str_cmp(arg2,"all")) {
        type = 5;
      } else {
        type = 6;
      }
    }
  }

  switch (type) {
    /* get */
    case 0:{ 
      send_to_char("Get what?\n\r", ch); 
    } break;
    /* get all */
    case 1:{ 
      sub_object = 0;
      found = FALSE;
      fail  = FALSE;
      for(obj_object = world[ch->in_room].contents;
        obj_object;
        obj_object = next_obj) {
        next_obj = obj_object->next_content;
        if (CAN_SEE_OBJ(ch,obj_object)) {
          if ((IS_CARRYING_N(ch) + 1) <= CAN_CARRY_N(ch)) {
            if ((IS_CARRYING_W(ch) + obj_object->obj_flags.weight) <= 
              CAN_CARRY_W(ch)) {
              if (CAN_REALLY_TAKE(ch,obj_object)){
                get(ch,obj_object,sub_object);
                found = TRUE;
              } else {
                send_to_char("You can't take that\n\r", ch);
                fail = TRUE;
              }
            } else {
              sprintf(buffer,"%s : You can't carry that much weight.\n\r", 
                fname(obj_object->name));
              send_to_char(buffer, ch);
              fail = TRUE;
            }
          } else {
            sprintf(buffer,"%s : You can't carry that many items.\n\r", 
              fname(obj_object->name));
            send_to_char(buffer, ch);
            fail = TRUE;
          }
        }
      }
      if (found) {
        send_to_char("OK.\n\r", ch);
      } else {
        if (!fail) send_to_char("You see nothing here.\n\r", ch);
      }
    } break;
    /* get ??? */
    case 2:{
      sub_object = 0;
      found = FALSE;
      fail  = FALSE;
      obj_object = get_obj_in_list_vis(ch, arg1, 
        world[ch->in_room].contents);
      if (obj_object) {
        if ((IS_CARRYING_N(ch) + 1 < CAN_CARRY_N(ch))) {
          if ((IS_CARRYING_W(ch) + obj_object->obj_flags.weight) < 
            CAN_CARRY_W(ch)) {
            if (CAN_REALLY_TAKE(ch,obj_object)) {
              get(ch,obj_object,sub_object);
              found = TRUE;
            } else {
              send_to_char("You can't take that\n\r", ch);
              fail = TRUE;
            }
          } else {
            sprintf(buffer,"%s : You can't carry that much weight.\n\r", 
              fname(obj_object->name));
            send_to_char(buffer, ch);
            fail = TRUE;
          }
        } else {
          sprintf(buffer,"%s : You can't carry that many items.\n\r", 
            fname(obj_object->name));
          send_to_char(buffer, ch);
          fail = TRUE;
        }
      } else {
        sprintf(buffer,"You do not see a %s here.\n\r", arg1);
        send_to_char(buffer, ch);
        fail = TRUE;
      }
    } break;
    /* get all all */
    case 3:{ 
      send_to_char("You must be joking?!\n\r", ch);
    } break;
    /* get all ??? */
    case 4:{
      found = FALSE;
      fail  = FALSE; 
      sub_object = get_obj_in_list_vis(ch, arg2, 
        world[ch->in_room].contents);
      if (!sub_object){
        sub_object = get_obj_in_list_vis(ch, arg2, ch->carrying);
      }
      if (sub_object) {
        if (GET_ITEM_TYPE(sub_object) == ITEM_CONTAINER) {
          if(IS_SET(sub_object->obj_flags.value[1], CONT_CLOSED)){
            send_to_char("It's closed.\n\r",ch);
            fail = TRUE;
          } else if(IS_SET(sub_object->obj_flags.value[1],CONT_LOCKED)){
            send_to_char("It's locked.\n\r",ch);
            fail = TRUE;
          } else
          for(obj_object = sub_object->contains;
            obj_object;
            obj_object = next_obj) {
            next_obj = obj_object->next_content;
            if (CAN_SEE_OBJ(ch,obj_object)) {
              if ((IS_CARRYING_N(ch) + 1 < CAN_CARRY_N(ch))) {
                if ((IS_CARRYING_W(ch) + obj_object->obj_flags.weight) < 
                  CAN_CARRY_W(ch)) {
                  if (CAN_REALLY_TAKE(ch,obj_object)) {
                    get(ch,obj_object,sub_object);
                    found = TRUE;
                  } else {
                    send_to_char("You can't take that\n\r", ch);
                    fail = TRUE;
                  }
                } else {
                  sprintf(buffer,"%s : You can't carry that much weight.\n\r", 
                    fname(obj_object->name));
                  send_to_char(buffer, ch);
                  fail = TRUE;
                }
              } else {
                sprintf(buffer,"%s : You can't carry that many items.\n\r", 
                  fname(obj_object->name));
                send_to_char(buffer, ch);
                fail = TRUE;
              }
            }
          }
          if (!found && !fail) {
            sprintf(buffer,"You do not see anything in the %s.\n\r", 
              fname(sub_object->name));
            send_to_char(buffer, ch);
            fail = TRUE;
          }
        } else {
          sprintf(buffer,"The %s is not a container.\n\r",
            fname(sub_object->name));
          send_to_char(buffer, ch);
          fail = TRUE;
        }
      } else { 
        sprintf(buffer,"You do not see or have the %s.\n\r", arg2);
        send_to_char(buffer, ch);
        fail = TRUE;
      }
    } break;
    case 5:{ 
      send_to_char("You can't take a thing from more than one container.\n\r", 
        ch);
    } break;
    case 6:{
      found = FALSE;
      fail  = FALSE;
      sub_object = get_obj_in_list_vis(ch, arg2, 
        world[ch->in_room].contents);
      if (!sub_object){
        sub_object = get_obj_in_list_vis(ch, arg2, ch->carrying);
      }
      if (sub_object) {
        if (GET_ITEM_TYPE(sub_object) == ITEM_CONTAINER) {
          if(IS_SET(sub_object->obj_flags.value[1], CONT_CLOSED)){
            send_to_char("It's closed.\n\r",ch);
            fail = TRUE;
          } else if(IS_SET(sub_object->obj_flags.value[1],CONT_LOCKED)){
            send_to_char("It's locked.\n\r",ch);
            fail = TRUE;
          } else {
          obj_object = get_obj_in_list_vis(ch, arg1, sub_object->contains);
          if (obj_object) {
            if ((IS_CARRYING_N(ch) + 1 < CAN_CARRY_N(ch))) {
              if ((IS_CARRYING_W(ch) + obj_object->obj_flags.weight) < 
                CAN_CARRY_W(ch)) {
                if (CAN_REALLY_TAKE(ch,obj_object)) {
                  get(ch,obj_object,sub_object);
                  found = TRUE;
                } else {
                  send_to_char("You can't take that\n\r", ch);
                  fail = TRUE;
                }
              } else {
                sprintf(buffer,"%s : You can't carry that much weight.\n\r", 
                  fname(obj_object->name));
                send_to_char(buffer, ch);
                fail = TRUE;
              }
            } else {
              sprintf(buffer,"%s : You can't carry that many items.\n\r", 
                fname(obj_object->name));
              send_to_char(buffer, ch);
              fail = TRUE;
            }
          } else {
            sprintf(buffer,"The %s does not contain the %s.\n\r", 
              fname(sub_object->name), arg1);
            send_to_char(buffer, ch);
            fail = TRUE;
          }
          }
        } else {
          sprintf(buffer,"The %s is not a container.\n\r",
            fname(sub_object->name));
          send_to_char(buffer, ch);
          fail = TRUE;
        }
      } else {
        sprintf(buffer,"You do not see or have the %s.\n\r", arg2);
        send_to_char(buffer, ch);
        fail = TRUE;
      }
    } break;
  }
}


void do_drop(struct char_data *ch, char *argument, int cmd) {
  char arg[MAX_STRING_LENGTH];
  int amount;
  char buffer[MAX_STRING_LENGTH];
  struct obj_data *tmp_object;
  struct obj_data *next_obj;
  struct char_data *tmp_char;
  bool test = FALSE;
  
  argument=one_argument(argument, arg);
  if(is_number(arg)) {
    amount = atoi(arg);
    argument=one_argument(argument,arg);
    if (str_cmp("coins",arg) && str_cmp("coin",arg)) {
      send_to_char("Sorry, you can't do that (yet)...\n\r",ch);
      return;
    }
    if(amount<0) {
      send_to_char("Sorry, you can't do that!\n\r",ch);
      return;
    }
    if(GET_GOLD(ch)<amount) {
      send_to_char("You haven't got that many coins!\n\r",ch);
      return;
    }
    send_to_char("OK.\n\r",ch);
    if(amount==0)
      return;
    if(amount >= 10){
      act("$n drops some gold.",FALSE,ch,0,0,TO_ROOM);
      tmp_object = create_money(amount);
      obj_to_room(tmp_object,ch->in_room);
    } else {
      act("$n scatters coins to winds...",FALSE,ch,0,0,TO_ROOM);
    }
    GET_GOLD(ch)-=amount;
    return;
  }
  if (*arg) {
    if (!str_cmp(arg,"all")) {
      for(tmp_object = ch->carrying;
        tmp_object;
        tmp_object = next_obj) {
        next_obj = tmp_object->next_content;
        if((GET_LEVEL(ch) > IMO) ||
           (!IS_SET(tmp_object->obj_flags.extra_flags,ITEM_NODROP))){
          if (CAN_SEE_OBJ(ch, tmp_object)) {
            sprintf(buffer, "You drop the %s.\n\r", fname(tmp_object->name));
            send_to_char(buffer, ch);
          } else {
            send_to_char("You drop something.\n\r", ch);
          }
          act("$n drops $p.", 1, ch, tmp_object, 0, TO_ROOM);
          obj_from_char(tmp_object);
          obj_to_room(tmp_object,ch->in_room);
          test = TRUE;
        } else {
          if (CAN_SEE_OBJ(ch, tmp_object)) {
            sprintf(buffer, "You can't drop the %s, it must be CURSED!\n\r",
              fname(tmp_object->name));
            send_to_char(buffer, ch);
            test = TRUE;
          }
        }
      }
      if (!test) {
        send_to_char("You do not seem to have anything.\n\r", ch);
      }
   } else {
      tmp_object = get_obj_in_list_vis(ch, arg, ch->carrying);
      if (tmp_object) {
        if (! IS_SET(tmp_object->obj_flags.extra_flags, ITEM_NODROP)) {
          sprintf(buffer, "You drop the %s.\n\r", fname(tmp_object->name));
          send_to_char(buffer, ch);
          act("$n drops $p.", 1, ch, tmp_object, 0, TO_ROOM);
          obj_from_char(tmp_object);
          obj_to_room(tmp_object,ch->in_room);
        } else {
          send_to_char("You can't drop it, it must be CURSED!\n\r", ch);
        }
      } else {
        send_to_char("You do not have that item.\n\r", ch);
      }
    }
  } else {
    send_to_char("Drop what?\n\r", ch);
  }
}

void do_put(struct char_data *ch, char *argument, int cmd)
{
  char buffer[MAX_STRING_LENGTH],buf[MAX_STRING_LENGTH];
  char arg1[MAX_STRING_LENGTH],*ptr,*p;
  char arg2[MAX_STRING_LENGTH];
  struct obj_data *obj_object, *sub_object, *list;
  struct char_data *tmp_char;
  int i,bits,tout;

  argument_interpreter(argument, arg1, arg2);
  if(*arg1) {
   if(*arg2) {
    if(strcmp("all",arg1)==0){
     if(p=(char *)index(arg2,'.'))
       sprintf(buf,"!%s",p+1);
     else
       sprintf(buf,"!%s",arg2);
     ptr=buf; tout=2;
    } else if(strncmp("all.",arg1,4)==0){
     ptr=arg1+4; tout=1;
    } else {
     ptr=arg1; tout=0;
    }
    bits=generic_find(arg2,FIND_OBJ_INV|FIND_OBJ_ROOM,ch,&tmp_char,&sub_object);
    if(!sub_object){
      sprintf(buffer, "You don't have the %s.\n\r", arg2);
      send_to_char(buffer, ch); return;
    }
    if(GET_ITEM_TYPE(sub_object)!=ITEM_CONTAINER){
      sprintf(buffer,"The %s is not a container.\n\r",fname(sub_object->name));
      send_to_char(buffer, ch); return;
    }
    if(IS_SET(sub_object->obj_flags.value[1],CONT_CLOSED)) {
      send_to_char("It seems to be closed.\n\r", ch); return;
    }
    for(i=0;;i++){
     if(obj_object = get_obj_in_list_vis(ch,ptr,ch->carrying)){
      if(obj_object == sub_object) {
       send_to_char("You attempt to fold it into itself, but fail.\n\r",ch);
       return;
      }
      if(IS_SET(obj_object->obj_flags.extra_flags,ITEM_NO_PUT_IN)){
        act("$p won't fit!\n\r",TRUE,ch,obj_object,0,TO_CHAR);
        return;
      }
      if(((sub_object->obj_flags.weight) + (obj_object->obj_flags.weight)) <
          (sub_object->obj_flags.value[0])) {
        send_to_char("Ok.\n\r", ch);
        if (bits==FIND_OBJ_INV) {
          obj_from_char(obj_object);
          IS_CARRYING_W(ch) += GET_OBJ_WEIGHT(obj_object);
          obj_to_obj(obj_object, sub_object);
        } else {
          obj_from_char(obj_object);
          obj_to_obj(obj_object, sub_object);
        }
        act("$n puts $p in $P",TRUE, ch, obj_object, sub_object, TO_ROOM);
      } else {
        send_to_char("It won't fit.\n\r", ch); return;
      }
    } else {
      if(i==0){
       sprintf(buffer,"You put %d objects in %s.\n\r",i,arg2);
       send_to_char(buffer, ch);
      }
      return;
    }
    if(!tout) return;
   } /* of for */
  } else {
   sprintf(buffer, "Put %s in what?\n\r", arg1);
   send_to_char(buffer, ch);
  }
 } else {
  send_to_char("Put what in what?\n\r",ch);
 }
}

void do_give(struct char_data *ch, char *argument, int cmd)
{
  char obj_name[80], vict_name[80], buf[MAX_STRING_LENGTH];
  char arg[80];
  int amount;
  struct char_data *vict, *sh;
  struct obj_data *obj;

  argument=one_argument(argument,obj_name);
  if(is_number(obj_name)) {
    amount = atoi(obj_name);
    argument=one_argument(argument, arg);
    if (str_cmp("coins",arg) && str_cmp("coin",arg)) {
      send_to_char("Sorry, you can't do that (yet)...\n\r",ch);
      return;
    }
    if(amount<0) {
      send_to_char("Sorry, you can't do that!\n\r",ch);
      return;
    }
    if((GET_GOLD(ch)<amount) && (IS_NPC(ch) || (GET_LEVEL(ch) < (IMO+99)))) {
      send_to_char("You haven't got that many coins!\n\r",ch);
      return;
    }
    argument=one_argument(argument, vict_name);
    if(!*vict_name) {
      send_to_char("To who?\n\r",ch);
      return;
    }
    if (!(vict = get_char_room_vis(ch, vict_name))) {
      send_to_char("To who?\n\r",ch);
      return;
    }
    send_to_char("Ok.\n\r",ch);
    sprintf(buf,"%s gives you %d gold coins.\n\r",PERS(ch,vict),amount);
    send_to_char(buf,vict);
    act("$n gives some gold to $N.", 1, ch, 0, vict, TO_NOTVICT);
    if (IS_NPC(ch) || (GET_LEVEL(ch) < (IMO+1)))
      GET_GOLD(ch)-=amount;
    GET_GOLD(vict)+=amount;
    if(GET_LEVEL(ch) > IMO){
      sprintf(buf,"%s gave %d coins to %s",
        GET_NAME(ch),amount,GET_NAME(vict));
      log(buf);
    }
    return;
  }
  argument=one_argument(argument, vict_name);
  if (!*obj_name || !*vict_name) {
    send_to_char("Give what to who?\n\r", ch);
    return;
  }
  if (!(obj = get_obj_in_list_vis(ch, obj_name, ch->carrying))) {
    send_to_char("You do not seem to have anything like that.\n\r", ch);
    return;
  }
  if (IS_SET(obj->obj_flags.extra_flags, ITEM_NODROP)) {
    send_to_char("You can't let go of it! Yeech!!\n\r", ch);
    return;
  }
  if (!(vict = get_char_room_vis(ch, vict_name))) {
    send_to_char("No one by that name around here.\n\r", ch);
    return;
  }
  if ((1+IS_CARRYING_N(vict)) > CAN_CARRY_N(vict)){
    act("$N seems to have $S hands full.", 0, ch, 0, vict, TO_CHAR);
    return;
  }
  if(obj->obj_flags.weight + IS_CARRYING_W(vict) > CAN_CARRY_W(vict)){
    act("$E can't carry that much weight.", 0, ch, 0, vict, TO_CHAR);
    return;
  }
  if((GET_LEVEL(vict)<10)&&(IS_SET(obj->obj_flags.extra_flags,ITEM_PRIME))){
    act("$E can't handle one of those.",0,ch,0,vict,TO_CHAR);
    return;
  }
  if((GET_ITEM_TYPE(obj)==ITEM_BOMB)&&(GET_INT(vict) > 30)){
    act("$E is too intelligent to fall for that!",0,ch,0,vict,TO_CHAR);
    return;
  }
  obj_from_char(obj);
  obj_to_char(obj, vict);
  act("$n gives $p to $N.", 1, ch, obj, vict, TO_NOTVICT);
  act("$n gives you $p.", 0, ch, obj, vict, TO_VICT);
  send_to_char("Ok.\n\r", ch);
}

void do_reload(struct char_data *ch, char *argument, int cmd)
{
  char buffer[MAX_STRING_LENGTH];
  char arg1[MAX_STRING_LENGTH];
  char arg2[MAX_STRING_LENGTH];
  struct obj_data *gun;
  struct obj_data *ammo;
  extern struct index_data *obj_index;

  if(GET_POS(ch) < POSITION_STANDING){
    send_to_char("You need to be standing still for that.\n\r",ch);
    return;
  }
  argument_interpreter(argument, arg1, arg2);
  if (*arg1) {
    if (*arg2) {
      gun=get_obj_in_list_vis(ch, arg1,ch->carrying);
      if (gun) {
        if(GET_ITEM_TYPE(gun) != ITEM_FIREWEAPON){
          send_to_char("You can't reload that!\n\r",ch);
          return;
        }
        ammo=get_obj_in_list_vis(ch, arg2,ch->carrying);
        if(ammo){
          if((1+obj_index[gun->item_number].virtual)!=
            (obj_index[ammo->item_number].virtual)){
            sprintf(buffer,"%s cannot be used as ammo for %s\n\r",arg2,arg1);
            send_to_char(buffer,ch);
            return;
          }
          gun->obj_flags.value[0]=gun->obj_flags.value[1];
          if(gun->obj_flags.value[2] > gun->obj_flags.value[1])
            --gun->obj_flags.value[2];
          extract_obj(ammo);
          act("$n reloads $p",TRUE,ch,gun,0,TO_ROOM);
          send_to_char("You reload.\n\r",ch);
        } else {
          sprintf(buffer, "You dont have the %s.\n\r", arg2);
          send_to_char(buffer, ch);
        }
      } else {
        sprintf(buffer, "You dont have the %s.\n\r", arg1);
        send_to_char(buffer, ch);
      }
    } else {
      sprintf(buffer, "Reload %s with what?\n\r", arg1);
      send_to_char(buffer, ch);
    }
  } else {
    send_to_char("Reload what with what?\n\r",ch);
  }
}


void do_recharge(struct char_data *ch, char *argument, int cmd)
{
  char buffer[MAX_STRING_LENGTH];
  char arg1[MAX_STRING_LENGTH];
  char arg2[MAX_STRING_LENGTH];
  struct obj_data *gun;
  struct obj_data *ammo;
  extern struct index_data *obj_index;

  if(GET_POS(ch) < POSITION_STANDING){
    send_to_char("You need to be standing still for that.\n\r",ch);
    return;
  }
  argument_interpreter(argument, arg1, arg2);
  if (*arg1) {
    if (*arg2) {
      gun=get_obj_in_list_vis(ch, arg1,ch->carrying);
      if (gun) {
        if((GET_ITEM_TYPE(gun) != ITEM_WAND)&&
           (GET_ITEM_TYPE(gun) != ITEM_STAFF)){
          send_to_char("You can't recharge that!\n\r",ch);
          return;
        }
        ammo=get_obj_in_list_vis(ch, arg2,ch->carrying);
        if(!ammo){
          send_to_char("Think again.\n\r",ch);
          return;
        }
        if(GET_ITEM_TYPE(ammo) != ITEM_CHARGE){
          send_to_char("You can't recharge with that.\n\r",ch);
          return;
        }
        if(ammo){
          if((obj_index[gun->item_number].virtual)!=
            (ammo->obj_flags.value[2])){
            sprintf(buffer,"%s cannot recharge %s\n\r",arg2,arg1);
            send_to_char(buffer,ch);
            return;
          }
          ++gun->obj_flags.value[2];
          if(gun->obj_flags.value[2] > gun->obj_flags.value[1])
            ++gun->obj_flags.value[1];
          extract_obj(ammo);
          act("$n recharges $p",TRUE,ch,gun,0,TO_ROOM);
          send_to_char("You recharge.\n\r",ch);
        } else {
          sprintf(buffer, "You dont have the %s.\n\r", arg2);
          send_to_char(buffer, ch);
        }
      } else {
        sprintf(buffer, "You dont have the %s.\n\r", arg1);
        send_to_char(buffer, ch);
      }
    } else {
      sprintf(buffer, "Recharge %s with what?\n\r", arg1);
      send_to_char(buffer, ch);
    }
  } else {
    send_to_char("Recharge what with what?\n\r",ch);
  }
}

char *dirdesc[]={
  "the north",
  "the east",
  "the south",
  "the west",
  "above",
  "below"
};
void throw(struct char_data *ch, struct obj_data *o, int dir)
{
  struct char_data *p;
  char buf[256];
  extern char *dirs[];
  extern int revdir[];

  if(!CAN_GO(ch,dir)||IS_SET(EXIT(ch, dir)->exit_info, EX_CLOSED)){
    send_to_char("You can't throw it that way.\n\r",ch);
    return;
  }
  obj_from_char(o);
  if(EXIT(ch, dir))
    obj_to_room(o,EXIT(ch, dir)->to_room);
  else
    return;
  sprintf(buf,"$n throws $p %s.",dirs[dir]);
  act(buf,TRUE,ch,o,0,TO_ROOM);
  act("You throw $p.",TRUE,ch,o,0,TO_CHAR);
  p=world[EXIT(ch, dir)->to_room].people;
  if(p){
    sprintf(buf,"$p comes flying into the room from %s.",
      dirdesc[revdir[dir]]);
    act(buf,FALSE,p,o,0,TO_ROOM);
    if(!IS_NPC(p))
      act(buf,FALSE,p,o,0,TO_CHAR);
  }
}
void do_throw(struct char_data *ch, char *argument, int cmd)
{
  char buf[256], arg1[256], arg2[256];
  struct obj_data *o;
  int dir;

  if(GET_POS(ch) < POSITION_STANDING){
    send_to_char("You need to be standing still for that.\n\r",ch);
    return;
  }
  argument_interpreter(argument, arg1, arg2);
  if(*arg1) {
    o=get_obj_in_list_vis(ch, arg1,ch->carrying);
    if(!o){
      send_to_char("You don't have it!\n\r",ch);
      return;
    }
    if(IS_SET(o->obj_flags.extra_flags,ITEM_NODROP)){
      send_to_char("Sorry, it's cursed.\n\r",ch);
      return;
    }
    if(GET_STR(ch) < o->obj_flags.weight){
      send_to_char("That's a little too heavy to throw.\n\r",ch);
      return;
    }
    switch(*arg2){
      case 'n': dir=0; break;
      case 'e': dir=1; break;
      case 's': dir=2; break;
      case 'w': dir=3; break;
      case 'u': dir=4; break;
      case 'd': dir=5; break;
      default:
       {
        do_drop(ch,argument,cmd);
        return;
       }
    }
    throw(ch,o,dir);
  } else {
    send_to_char("Throw what?\n\r",ch);
  }
  return;
}