/* Put, Get, Drop multiple items by Darksword */

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;
  int put_num, amount;   /* Added by Darksword */

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

  if (!*arg1)
    send_to_char("Put what in what?\r\n", ch);
  else if (cont_dotmode != FIND_INDIV)
    send_to_char("You can only put things into one container at a time.\r\n", ch);


  /* ADDED by Darksword */
  else if (is_number(arg1)) {
    put_num = atoi(arg1);
    argument = two_arguments(argument, arg1, arg2);
    one_argument(argument, arg1);
    if (!*arg2)
      send_to_char("Put what in what?\r\n", ch);
    else if (!*arg1) {
      sprintf(buf, "What do you want to put %s in?\r\n", arg2);
      send_to_char(buf, ch);
    } else { 
    generic_find(arg1, FIND_OBJ_INV | FIND_OBJ_ROOM, ch, &tmp_char, &cont);
    if (!cont) {
      sprintf(buf, "You don't see %s %s here.\r\n", AN(arg1), arg1);
      send_to_char(buf, ch);
    } else if (GET_OBJ_TYPE(cont) != ITEM_CONTAINER)
      act("$p is not a container.", FALSE, ch, cont, 0, TO_CHAR);
    else if (IS_SET(GET_OBJ_VAL(cont, 1), CONT_CLOSED))
      send_to_char("You'd better open it first!\r\n", ch);
    else {
      /* ADDED by Darksword put # <obj> <container> */
      for  (amount = 0; amount < put_num; amount++)  
      if (!(obj = get_obj_in_list_vis(ch, arg2, ch->carrying))) {
	sprintf(buf, "You aren't carrying %s %s.\r\n", AN(arg2), arg2);
        send_to_char(buf, ch);
        amount = put_num;
      } else if (obj == cont) {
	  send_to_char("You attempt to fold it into itself, but fail.\r\n", ch);
          amount = put_num;
      }	else
	  perform_put(ch, obj, cont);
    } 
  }
  /* END of Darksword */

  } else if (!*arg2) {
    sprintf(buf, "What do you want to put %s in?\r\n",
	    ((obj_dotmode == FIND_INDIV) ? "it" : "them"));
    send_to_char(buf, ch);
  } else {
    generic_find(arg2, 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 (GET_OBJ_TYPE(cont) != ITEM_CONTAINER)
      act("$p is not a container.", FALSE, ch, cont, 0, TO_CHAR);
    else if (IS_SET(GET_OBJ_VAL(cont, 1), CONT_CLOSED))
      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)
	  send_to_char("You attempt to fold it into itself, but fail.\r\n", ch);
	else
	  perform_put(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;
	    perform_put(ch, obj, cont);
	  }
	}
	if (!found) {
	  if (obj_dotmode == FIND_ALL)
	    send_to_char("You don't seem to have anything to put in it.\r\n", ch);
	  else {
	    sprintf(buf, "You don't seem to have any %ss.\r\n", arg1);
	    send_to_char(buf, ch);
	  }
	}
      }
    }
  }
}


ACMD(do_get)
{
  char arg1[MAX_INPUT_LENGTH];
  char arg2[MAX_INPUT_LENGTH];
  struct obj_data *obj;
  int cont_dotmode, found = 0, mode;
  struct obj_data *cont;
  struct char_data *tmp_char;
  int amount, get_num;    /* Added by Darksword */

  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)
    send_to_char("Get what?\r\n", ch);

 /* ADDED by Darksword */
 /* The following code allows you to get # items from room or container */

  else if (is_number(arg1)) {
    get_num = atoi(arg1);
    argument = two_arguments(argument, arg1, arg2);
    one_argument(argument, arg1);
    if (!*arg2)
      send_to_char("Get what?\r\n", ch);
    else if (!*arg1) {
      for  (amount = 0; amount < get_num; amount++)  
     if (!(obj = get_obj_in_list_vis(ch, arg2, world[ch->in_room].contents))) {
        sprintf(buf, "You don't see %s %s here.\r\n", AN(arg2), arg2);
        send_to_char(buf, ch);
        amount = get_num;
      } else 
	  perform_get_from_room(ch, obj);
    }
    else { 
      mode = generic_find(arg1, FIND_OBJ_INV | FIND_OBJ_ROOM, ch, &tmp_char, &cont);
      if (!cont) {
	sprintf(buf, "You don't have %s %s.\r\n", AN(arg1), arg1);
	send_to_char(buf, ch);
      }
      else 
        if (GET_OBJ_TYPE(cont) != ITEM_CONTAINER)
 	  act("$p is not a container.", FALSE, ch, cont, 0, TO_CHAR);
        else 
    for  (amount = 0; amount < get_num; amount++)  
    if (!(obj = get_obj_in_list_vis(ch, arg2, cont->contains))) {
      sprintf(buf, "There doesn't seem to be %s %s in %s.\r\n", AN(arg2), arg2, arg1);
      send_to_char(buf, ch);
      amount = get_num;
    } else
      get_from_container(ch, cont, arg2, mode);
   }
  }
  /* END of Darksword */

  else if (!*arg2) 
	 get_from_room(ch, arg1);
  else { 
    cont_dotmode = find_all_dots(arg2);
    if (cont_dotmode == FIND_INDIV) {
      mode = generic_find(arg2, 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 (GET_OBJ_TYPE(cont) != ITEM_CONTAINER)
 	  act("$p is not a container.", FALSE, ch, cont, 0, TO_CHAR);
        else 
	    get_from_container(ch, cont, arg1, mode);
    } 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 (GET_OBJ_TYPE(cont) == ITEM_CONTAINER) {
	    found = 1;
   	      get_from_container(ch, cont, arg1, FIND_OBJ_INV);
	  } else if (cont_dotmode == FIND_ALLDOT) {
	    found = 1;
	    act("$p is not a container.", 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);
	    found = 1;
	  } else if (cont_dotmode == FIND_ALLDOT) {
	    act("$p is not a container.", FALSE, ch, cont, 0, TO_CHAR);
	    found = 1;
	  }
      if (!found) {
	if (cont_dotmode == FIND_ALL)
	  send_to_char("You can't seem to find any containers.\r\n", ch);
	else {
	  sprintf(buf, "You can't seem to find any %ss here.\r\n", arg2);
	  send_to_char(buf, ch);
	}
      }
    }
  }
}


ACMD(do_drop)
{
  extern sh_int donation_room_1;
#if 0
  extern sh_int donation_room_2;  /* uncomment if needed! */
  extern sh_int donation_room_3;  /* uncomment if needed! */
#endif
  struct obj_data *obj, *next_obj;
  sh_int RDR = 0;
  byte mode = SCMD_DROP;
  int dotmode, amount = 0;
  char *sname;
  int drop_num;  /* Added by Darksword -- to drop multiple items */


  switch (subcmd) {
  case SCMD_JUNK:
    sname = "junk";
    mode = SCMD_JUNK;
    break;
  case SCMD_DONATE:
    sname = "donate";
    mode = SCMD_DONATE;
    switch (number(0, 2)) {
    case 0:
      mode = SCMD_JUNK;
      break;
    case 1:
    case 2:
      RDR = real_room(donation_room_1);
      break;
/*    case 3: RDR = real_room(donation_room_2); break;
      case 4: RDR = real_room(donation_room_3); break;
*/
    }
    if (RDR == NOWHERE) {
      send_to_char("Sorry, you can't donate anything right now.\r\n", ch);
      return;
    }
    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("coins", arg) || !str_cmp("coin", arg))
          perform_drop_gold(ch, amount, mode, RDR);
        else {
          if (amount  < 0) {
            send_to_char("Sorry you can't do that.\r\n", ch);
            return;
          }
          else {
        /* Code to drop multiple items added by Darksword */
        /* added variables  int  drop_num           */
        drop_num = amount;
        for  (amount = 0; amount < drop_num; amount++)  
          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);
            amount = drop_num; /* just let them know no more then stop */
          } else
	      amount += perform_drop(ch, obj, mode, sname, RDR);
      }
    }
    return;
  } else {
    dotmode = find_all_dots(arg);
    /* Can't junk or donate all */
    if ((dotmode == FIND_ALL) && (subcmd == SCMD_JUNK || subcmd == SCMD_DONATE)) {
      if (subcmd == SCMD_JUNK)
	send_to_char("Go to the dump if you want to junk EVERYTHING!\r\n", ch);
      else
	send_to_char("Go do the donation room if you want to donate 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 (!(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);
    }
  }

  if (amount && (subcmd == SCMD_JUNK)) {
    send_to_char("You have been rewarded by the gods!\r\n", ch);
    act("$n has been rewarded by the gods!", TRUE, ch, 0, 0, TO_ROOM);
    GET_GOLD(ch) += amount;
  }
}


ACMD(do_give)
{
  int amount, dotmode;
  struct char_data *vict;
  struct obj_data *obj, *next_obj;
  char arg1[MAX_INPUT_LENGTH];
  char arg2[MAX_INPUT_LENGTH];
  int give_num;    /* Added by Darksword -- to give multiple items */

  argument = one_argument(argument, arg);

  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("coins", arg) || !str_cmp("coin", 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 added by Darksword */
        /* added variables  int  give_num                 */
      give_num = amount;
      argument = two_arguments(argument, arg1, arg2);
      if ((vict = give_find_vict(ch, arg1)))
        for  (amount = 0; amount < give_num; amount++)  
          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);
            amount = give_num; /* just let them know no more then stop */
          } else
              perform_give(ch, vict, obj);
 
        /* End added by Darksword */
 
      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);
	}
    }
  }
}
