/* ************************************************************************ * File: act.obj1.c Part of CircleMUD * * Usage: object handling routines -- get/drop and container handling * * * * All rights reserved. See license.doc for complete information. * * * * Copyright (C) 1993 by the Trustees of the Johns Hopkins University * * CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. * ************************************************************************ */ /* Archipelago changes by Alastair J. Neil Copyright (C) 1993, 94, 95, 96 */ #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" #define MARTHA_VNUM 2059 #define DONATE_RNUM 2024 /* extern variables */ extern struct str_app_type str_app[]; extern int top_of_world; extern struct index_data *obj_index; extern struct obj_data *obj_proto; extern struct str_app_type str_app[]; extern struct room_data *world; extern struct char_data *martha; extern struct obj_data *don_box; extern struct dual_list_type nonreg_plurals[]; struct char_data *give_find_vict(struct char_data *ch, char *arg1); void clear_timer(struct obj_data *object); char *report_cost(int gold); void drop_excess_gold(struct char_data *ch, int amount); int report_money_weight(int amount); int report_pennies(int amount); int report_groats(int amount); int report_crowns(int amount); bool is_plural(char *arg); char *make_plural(char *arg); void perform_drop_gold(struct char_data *ch, int amount, byte mode, sh_int RDR); int perform_drop(struct char_data *ch, struct obj_data *obj, byte mode, char *sname, sh_int RDR); void hitch(struct char_data *ch, struct obj_data *cart, struct char_data *vict, char quiet); void unhitch(struct char_data *ch, struct obj_data *cart, struct char_data *vict, char quiet); bool do_get_mob(struct char_data *ch, struct char_data *victim); void do_drop_mob(struct char_data *ch); void perform_sheath(struct char_data *ch, struct obj_data *weapon, struct obj_data *scabbard) { if (GET_ITEM_TYPE(weapon) != ITEM_WEAPON) { send_to_char("You can only put weapons in sheaths.\r\n",ch); return; } if (IS_GODITEM(weapon) && !IS_GODITEM(scabbard)) { act("$p is too holy to go in $P.", FALSE, ch, weapon, scabbard, TO_CHAR); return; } if (scabbard->contains) { act("$P seems to have a weapon in it already.", FALSE, ch, weapon, scabbard, TO_CHAR); return; } if (scabbard->obj_flags.value[0] > 0) { if (scabbard->obj_flags.value[0] != obj_index[weapon->item_number].virtual) { act("$p does not belong in $P.", FALSE, ch, weapon, scabbard, TO_CHAR); return; } } else if (scabbard->obj_flags.value[3] != weapon->obj_flags.value[3]) { act("That sort of weapon does not belong in this kind of sheath.", FALSE, ch, weapon, scabbard, TO_CHAR); return;} else if (GET_OBJ_SIZE(scabbard) > GET_OBJ_SIZE(weapon)) { act("$p is too big to fit in $P.", FALSE, ch, weapon, scabbard, TO_CHAR); return; } /* else if (GET_OBJ_SIZE(scabbard) < GET_OBJ_SIZE(weapon)) { act("$p is too small to fit in $P.", FALSE, ch, weapon, scabbard, TO_CHAR); return; }*/ obj_from_char(weapon,0); clear_timer(weapon); obj_to_obj (weapon, scabbard); act("You slip $p into $P.", FALSE, ch, weapon, scabbard, TO_CHAR); act("$n slips $p into $P.", FALSE, ch, weapon, scabbard, TO_ROOM); } void perform_put(struct char_data *ch, struct obj_data *obj, struct obj_data *container) { if (GET_ITEM_TYPE(container) == ITEM_SCABBARD) { perform_sheath(ch,obj,container); return; } if (GET_OBJ_WEIGHT(container) + GET_OBJ_WEIGHT(obj) > container->obj_flags.value[0]) act("$p won't fit in $P.", FALSE, ch, obj, container, TO_CHAR); else { obj_from_char(obj,0); clear_timer(obj); obj_to_obj (obj, container); act("You put $p in $P.", FALSE, ch, obj, container, TO_CHAR); act("$n puts $p in $P.", TRUE, ch, obj, container, TO_ROOM); } } /* 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; struct obj_data *next_obj; struct obj_data *container; struct char_data *tmp_char; int obj_dotmode, cont_dotmode; argument_interpreter(argument, arg1, arg2); obj_dotmode = find_all_dots(arg1); cont_dotmode = find_all_dots(arg2); if (cont_dotmode != FIND_INDIV) send_to_char("You can only put things into one container at a time.\r\n", ch); else if (!*arg1) send_to_char("Put what in what?\r\n", ch); else if (!*arg2) { sprintf(buf, "What do you want to put %s in?\r\n", ((obj_dotmode != FIND_INDIV) ? "them" : "it")); send_to_char(buf, ch); } else { generic_find(arg2, FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_OBJ_EQUIP, ch, &tmp_char, &container); if (!container) { sprintf(buf, "You don't see a %s here.\r\n", arg2); send_to_char(buf, ch); } else if ((GET_ITEM_TYPE(container) != ITEM_CONTAINER) && (GET_ITEM_TYPE(container) != ITEM_SCABBARD)) { act("You cannot put things in $p.", FALSE, ch, container, 0, TO_CHAR); } else if (IS_SET(container->obj_flags.value[1], CONT_CLOSED)) { send_to_char("You'd better open it first!\r\n", ch); } else { if (obj_dotmode == FIND_ALL) { /* "put all <container>" case */ /* check and make sure the guy has something first */ if (container == ch->inventory && !ch->inventory->next_content) send_to_char("You don't seem to have anything to put in it.\r\n", ch); else for (obj = ch->inventory; obj; obj = next_obj) { next_obj = obj->next_content; if (obj != container) perform_put(ch, obj, container); } } else if (obj_dotmode == FIND_ALLDOT) { /* "put all.x <cont>" case */ if (!(obj = get_obj_in_list_vis(ch, arg1, ch->inventory))) { if (is_plural(arg1)) sprintf(buf, "You don't seem to have any %s.\r\n", arg1); else sprintf(buf, "You don't seem to have any %s.\r\n", make_plural(arg1)); send_to_char(buf, ch); } else while (obj) { next_obj = get_obj_in_list_vis(ch, arg1, obj->next_content); if (obj != container) perform_put(ch, obj, container); obj = next_obj; } } else { /* "put <thing> <container>" case */ if (!(obj = get_obj_in_list_vis(ch, arg1, ch->inventory))) { sprintf(buf, "You aren't carrying %s %s.\r\n", AN(arg1), arg1); send_to_char(buf, ch); } else if (obj == container) send_to_char("You attempt to fold it into itself, but fail.\r\n", ch); else perform_put(ch, obj, container); } } } } int can_take_obj(struct char_data *ch, struct obj_data *obj) { if (IS_CARRYING_N(ch) >= CAN_CARRY_N(ch)) { if (obj->description){ sprintf(buf, "%s: You can't carry that many items.\r\n",OBJS(obj, ch)); send_to_char(buf, ch);} return 0;} else if (!(CAN_WEAR(obj, ITEM_TAKE))) { if (obj->description){ sprintf(buf, "%s: You can't take that!\r\n", OBJS(obj, ch)); send_to_char(buf, ch);} return 0;} else if ((IS_CARRYING_W(ch) + GET_OBJ_WEIGHT(obj)) > CAN_CARRY_W(ch)) { if (obj->description){ sprintf(buf,"%s: You can't carry that much weight.\r\n",OBJS(obj, ch)); send_to_char(buf, ch);} return 0;} else if (IS_GODITEM(obj) && GET_LEVEL(ch) < LEVEL_BUILDER){ if (obj->description){ sprintf(buf, "%s: You aren't holy enough to use this item.\r\n", OBJS(obj, ch)); send_to_char(buf, ch);} return 0; } return 1; } void get_check_money(struct char_data *ch, struct obj_data *obj) { int amount; amount = obj->obj_flags.value[0]; if ((GET_ITEM_TYPE(obj) == ITEM_MONEY) && (amount > 0)) { obj_from_char(obj,1); if (amount > 1 && amount != 1000 && amount != 100 && amount != 10) { sprintf(buf, "There were %s.\r\n", report_cost(amount)); send_to_char(buf, ch); } else if (amount > 1){ sprintf(buf, "There was %s.\r\n", report_cost(amount)); send_to_char(buf, ch); } drop_excess_gold(ch, amount); extract_obj(obj,0); } } void perform_unsheath(struct char_data *ch, struct obj_data *weapon, struct obj_data *scabbard) { int where; if (!(where = can_wield(ch, weapon))) return; obj_from_obj(weapon); clear_timer(weapon); if (ch->specials.carrying) do_drop_mob(ch); act ("You slide $p from $P.",FALSE,ch,weapon, scabbard,TO_CHAR); act ("$n slides $p from $P.",FALSE,ch,weapon, scabbard,TO_ROOM); if (affected_by_spell(ch, SPELL_SPASMS) && !number(0,1)){ send_to_char("Your hands are trembling too much.\r\n",ch); act("$n tries to wield $p, but $s hands shake.",FALSE,ch,weapon,0,TO_ROOM); obj_to_char(weapon, ch, 1); perform_drop(ch,weapon,SCMD_DROP,"drop",0); return; } equip_char(ch, weapon, where); wear_message(ch, weapon, where); } void perform_get_from_container(struct char_data *ch, struct obj_data *obj, struct obj_data *cont, int mode) { if (GET_ITEM_TYPE(cont) == ITEM_SCABBARD) { perform_unsheath(ch,obj, cont); return; } if (mode == FIND_OBJ_INV || can_take_obj(ch, obj)) { if (IS_CARRYING_N(ch) >= CAN_CARRY_N(ch)) sprintf(buf, "%s: You can't hold any more items.\r\n", OBJS(obj, ch)); else if (can_take_obj(ch,obj)) { obj_from_obj(obj); obj_to_char(obj, ch, 0); act("You get $p from $P.", FALSE, ch, obj, cont, TO_CHAR); act("$n gets $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, to_room; obj_dotmode = find_all_dots(arg); to_room = real_room(cont->obj_flags.value[3]); if (IS_SET(cont->obj_flags.value[1], CONT_CLOSED)){ act("The $p is closed.", FALSE, ch, cont, 0, TO_CHAR); return; } if (obj_dotmode == FIND_ALL) { if (HASROOM(cont)) { for (obj = world[to_room].contents;obj;){ next_obj = obj->next_content; if (CAN_SEE_OBJ(ch,obj)){ found = 1; if (can_take_obj(ch,obj)) { GET_OBJ_WEIGHT(cont) = MAX(10, GET_OBJ_WEIGHT(cont)- GET_OBJ_WEIGHT(obj)); act("$N gets $p.",TRUE,0,obj,ch,TO_ROOM); obj_from_room(obj); obj_to_char(obj, ch, 0); act("$n gets $p from $P.", TRUE,ch,obj,cont,TO_ROOM); act("You get $p from $P.", TRUE,ch,obj,cont,TO_CHAR); get_check_money(ch,obj); } } obj = next_obj; } } else { for (obj = cont->contains; obj; obj = next_obj) { next_obj = obj->next_content; if (CAN_SEE_OBJ(ch, obj)) { found = 1; perform_get_from_container(ch, obj, cont, mode); } } } if (!found) act("$p seems to be empty.", FALSE, ch, cont, 0, TO_CHAR); } else if (obj_dotmode == FIND_ALLDOT) { if (!*arg) { send_to_char("Get all of what?\r\n", ch); return; } if (HASROOM(cont)) { obj = get_obj_in_list_vis(ch, arg, world[to_room].contents); while(obj) { next_obj = get_obj_in_list_vis(ch, arg, obj->next_content); if (CAN_SEE_OBJ(ch,obj)) { found = 1; if (can_take_obj(ch,obj)) { GET_OBJ_WEIGHT(cont) = MAX(10,GET_OBJ_WEIGHT(cont)- GET_OBJ_WEIGHT(obj)); act("$N gets $p.",TRUE,0,obj,ch,TO_ROOM); obj_from_room(obj); obj_to_char(obj, ch, 0); act("$n gets $p from $P.", TRUE,ch,obj,cont,TO_ROOM); act("You get $p from $P.", TRUE,ch,obj,cont,TO_CHAR); get_check_money(ch,obj); } } obj = next_obj; } } else { obj = get_obj_in_list_vis(ch, arg, cont->contains); while (obj) { next_obj = get_obj_in_list_vis(ch, arg, obj->next_content); if (CAN_SEE_OBJ(ch, obj)) { found = 1; perform_get_from_container(ch, obj, cont, mode); } obj = next_obj; } } if (!found) { if (is_plural(arg)) sprintf(buf, "You can't find any %s in $p.", arg); else sprintf(buf, "You can't find any %s in $p.", make_plural(arg)); act(buf, FALSE, ch, cont, 0, TO_CHAR); } } else { if (HASROOM(cont)){ if (!(obj = get_obj_in_list_vis(ch, arg, world[to_room].contents))) { sprintf(buf, "There doesn't seem to be %s %s in $p.", AN(arg), arg); act(buf, FALSE, ch, cont, 0, TO_CHAR); } else if (can_take_obj(ch,obj)) { GET_OBJ_WEIGHT(cont) = MAX(10,GET_OBJ_WEIGHT(cont)- GET_OBJ_WEIGHT(obj)); act("$N gets $p.",TRUE,0,obj,ch,TO_ROOM); obj_from_room(obj); obj_to_char(obj, ch, 0); act("$n gets $p from $P.",TRUE,ch,obj,cont,TO_ROOM); act("You get $p from $P.",TRUE,ch,obj,cont,TO_CHAR); get_check_money(ch,obj); } } else { 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); } } } int perform_get_from_room(struct char_data *ch, struct obj_data *obj) { if (can_take_obj(ch, obj)) { obj_from_room(obj); obj_to_char(obj, ch, 0); 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; } return 0; } void get_from_room(struct char_data *ch, char *arg) { struct obj_data *obj, *next_obj; struct char_data *pobj; int dotmode, found = 0; dotmode = find_all_dots(arg); if (dotmode == FIND_ALL) { for (obj = world[ch->in_room].contents; obj; obj = next_obj) { next_obj = obj->next_content; if (CAN_SEE_OBJ(ch, obj) && obj->description) { found = 1; perform_get_from_room(ch, obj); } } if (!found) send_to_char("There doesn't seem to be anything here.\r\n", ch); } else if (dotmode == FIND_ALLDOT) { if (!*arg) { send_to_char("Get all of what?\r\n", ch); return; } if (!(obj = get_obj_in_list_vis(ch, arg, world[ch->in_room].contents))) { if (is_plural(arg)) sprintf(buf, "You don't see any %s here.\r\n", arg); else sprintf(buf, "You don't see any %s here.\r\n", make_plural(arg)); send_to_char(buf, ch); } else while (obj) { next_obj = get_obj_in_list_vis(ch, arg, obj->next_content); perform_get_from_room(ch, obj); obj = next_obj; } } else { if (!(obj = get_obj_in_list_vis(ch, arg, world[ch->in_room].contents))) { if (generic_find(arg, FIND_CHAR_ROOM, ch, &pobj, &obj)) if (CAN_SEE(ch, pobj)) { do_get_mob(ch, pobj); return; } sprintf(buf, "You don't see %s %s here.\r\n", AN(arg), arg); send_to_char(buf, ch); } else perform_get_from_room(ch, obj); } } ACMD(do_get) { char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; int cont_dotmode, found = 0, mode; struct obj_data *cont, *next_cont; struct char_data *tmp_char; if (IS_CARRYING_N(ch) >= CAN_CARRY_N(ch)) send_to_char("Your arms are already full!\r\n", ch); else { argument_interpreter(argument, arg1, arg2); if (!*arg1) send_to_char("Get what?\r\n", ch); else { if (!*arg2) get_from_room(ch, arg1); else { cont_dotmode = find_all_dots(arg2); if (cont_dotmode == FIND_ALL) { /* use all in inv. and on ground */ for(cont = ch->inventory; cont; cont = cont->next_content) if ((GET_ITEM_TYPE(cont) == ITEM_CONTAINER) || (GET_ITEM_TYPE(cont) == ITEM_SCABBARD)) { found = 1; get_from_container(ch, cont, arg1, FIND_OBJ_INV); } for(cont = world[ch->in_room].contents; cont; cont = cont->next_content) if (CAN_SEE_OBJ(ch, cont) && ((GET_ITEM_TYPE(cont) == ITEM_CONTAINER) || (GET_ITEM_TYPE(cont) == ITEM_SCABBARD))) { found = 1; get_from_container(ch, cont, arg1, FIND_OBJ_ROOM); } if (!found) send_to_char("You can't seem to find any containers.\r\n", ch); } else if (cont_dotmode == FIND_ALLDOT) { if (!*arg2) { send_to_char("Get from all of what?\r\n", ch); return; } cont = get_obj_in_list_vis(ch, arg2, ch->inventory); while (cont) { found = 1; next_cont = get_obj_in_list_vis(ch, arg2, cont->next_content); if ((GET_ITEM_TYPE(cont) != ITEM_CONTAINER) && (GET_ITEM_TYPE(cont) != ITEM_SCABBARD)) act("$p is not a container.", FALSE, ch, cont, 0, TO_CHAR); else get_from_container(ch, cont, arg1, FIND_OBJ_INV); cont = next_cont; } cont = get_obj_in_list_vis(ch, arg2, world[ch->in_room].contents); while (cont) { found = 1; next_cont = get_obj_in_list_vis(ch, arg2, cont->next_content); if ((GET_ITEM_TYPE(cont) != ITEM_CONTAINER) && (GET_ITEM_TYPE(cont) != ITEM_SCABBARD)) act("$p is not a container.", FALSE, ch, cont, 0, TO_CHAR); else get_from_container(ch, cont, arg1, FIND_OBJ_ROOM); cont = next_cont; } if (!found) { if (is_plural(arg2)) sprintf(buf, "You can't seem to find any %s here.\r\n", arg2); else sprintf(buf, "You can't seem to find any %s here.\r\n",make_plural(arg2)); send_to_char(buf, ch); } } else { /* get <items> <container> (no all or all.x) */ mode = generic_find(arg2, FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_OBJ_EQUIP, 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_ITEM_TYPE(cont) != ITEM_CONTAINER) && (GET_ITEM_TYPE(cont) != ITEM_SCABBARD)) act("$p is not a container.", FALSE, ch, cont, 0, TO_CHAR); else get_from_container(ch, cont, arg1, mode); } } } } } void perform_drop_gold(struct char_data *ch, int amount, byte mode, sh_int RDR) { struct obj_data *obj; if (amount <= 0) send_to_char("Heh heh heh.. we are jolly funny today, eh?\r\n", ch); else if (GET_GOLD(ch) < amount) send_to_char("You don't have that many coins!\r\n", ch); else { if (mode != SCMD_JUNK) { obj = create_money(amount); if (mode == SCMD_DONATE) { send_to_char("You throw some coins into the air where it disappears in a puff of smoke!\r\n", ch); act("$n throws some coins into the air where it disappears in a puff of smoke!", FALSE, ch, 0, 0, TO_ROOM); send_to_room("Some money suddenly appears in mid-air, then drops to the ground!\r\n", RDR, FALSE); obj_to_obj(obj, don_box); } else { send_to_char("You drop some money.\r\n", ch); act("$n drops some money.", FALSE, ch, 0, 0, TO_ROOM); obj_to_room(obj, ch->in_room, FALSE); } } else { act("$n drops some money which disappears in a puff of smoke!", FALSE, ch, 0, 0, TO_ROOM); send_to_char("You drop some money which disappears in a puff of smoke!\r\n", ch); } change_gold(ch, -amount); } } #define VANISH(mode) ((mode == SCMD_DONATE || mode == SCMD_JUNK) ? \ " It vanishes in a puff of smoke!" : "") int perform_drop(struct char_data *ch, struct obj_data *obj, byte mode, char *sname, sh_int RDR) { extern sh_int donation_room_1; int value=0; if (IS_SET(obj->obj_flags.extra_flags, ITEM_NODROP)) { sprintf(buf, "You can't %s %s, it must be CURSED!\r\n", sname, OBJS(obj, ch)); send_to_char(buf, ch); return 0; } if ((mode == SCMD_DONATE) && IS_SET(obj->obj_flags.extra_flags, ITEM_NODONATE)) { sprintf(buf, "You can't donate %s.\r\n", OBJS(obj, ch)); send_to_char(buf, ch); return 0; } sprintf(buf, "You %s %s.%s\r\n", sname, OBJS(obj, ch), VANISH(mode)); send_to_char(buf, ch); sprintf(buf, "$n %ss $p.%s", sname, VANISH(mode)); act(buf, TRUE, ch, obj, 0, TO_ROOM); obj_from_char(obj,0); switch(mode) { case SCMD_DROP: if (ch->specials.carrying) do_drop_mob(ch); obj_to_room(obj, ch->in_room, FALSE); return 0; break; case SCMD_DONATE: if(RDR == real_room(donation_room_1)){ obj_to_char(obj,martha, 0); send_to_room("Martha grabs something from thin air!\r\n", RDR, FALSE); } return 0; break; case SCMD_JUNK: if ((GET_ITEM_TYPE(obj) == ITEM_CONTAINER) && (obj->obj_flags.value[3] < 0)) value = MAX(10, MIN(200,obj->obj_flags.cost/4)); extract_obj(obj,0); return value; break; default: logg("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; extern sh_int donation_room_3; 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, 5)) { case 0: case 1: RDR = real_room(donation_room_1); 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) || !str_cmp("pennies", arg) || !str_cmp("penny",arg)){ if (amount > report_pennies(GET_GOLD(ch))) send_to_char("You don't have that many pennies.\r\n",ch); else perform_drop_gold(ch, amount*10, mode, RDR);} else if (!str_cmp("groats", arg) || !str_cmp("groat", arg) ){ if (amount > report_groats(GET_GOLD(ch))) send_to_char("You don't have that many groats.\r\n",ch); else perform_drop_gold(ch, amount*100, mode, RDR);} else if (!str_cmp("crowns", arg) || !str_cmp("crown", arg) ){ if (amount > report_crowns(GET_GOLD(ch))) send_to_char("You don't have that many crowns.\r\n",ch); else perform_drop_gold(ch, amount*1000, mode, RDR);} else { /* code to drop multiple items. anyone want to write it? -je */ send_to_char("Sorry, you can't do that (yet)...\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)) { 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->specials.carrying) do_drop_mob(ch); if (!ch->inventory) send_to_char("You don't seem to be carrying anything.\r\n", ch); else for (obj = ch->inventory; 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->inventory))) { if (is_plural(arg)) sprintf(buf, "You don't seem to have any %s.\r\n", arg); else sprintf(buf, "You don't seem to have any %s.\r\n", make_plural(arg)); send_to_char(buf, ch); } if (ch->specials.carrying) do_drop_mob(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 (ch->specials.carrying && isname(arg, ch->specials.carrying->player.name)) do_drop_mob(ch); else if (!(obj = get_obj_in_list_vis(ch, arg, ch->inventory))) { 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) && (GET_LEVEL(ch)< 10) && ((GET_GOLD(ch) + GET_BANK_GOLD(ch)) < 1000)) { 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); change_gold(ch , amount*2); } } void perform_give(struct char_data *ch, struct char_data *vict, struct obj_data *obj) { if (IS_GODITEM(obj) && GET_LEVEL(vict) < LEVEL_BUILDER){ sprintf(buf, "%s: You aren't holy enough to use this item.\r\n", OBJS(obj, vict)); send_to_char(buf, vict); sprintf(buf, "%s isn't holy enough to use this item.\r\n", GET_NAME(vict)); send_to_char(buf, ch); return;} if (IS_SET(obj->obj_flags.extra_flags, ITEM_NODROP)) { act("You can't let go of $p!! Yeech!", FALSE, ch, obj, 0, TO_CHAR); return; } if (IS_CARRYING_N(vict) >= CAN_CARRY_N(vict)) { act("$N seems to have $S hands full.", FALSE, ch, 0, vict, TO_CHAR); return; } 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; } obj_from_char(obj,0); obj_to_char(obj, vict,0); 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); } /* utility function for give */ struct char_data *give_find_vict(struct char_data *ch, char *arg1) { struct char_data *vict; char arg2[MAX_INPUT_LENGTH]; strcpy(buf, arg1); argument_interpreter(buf, arg1, arg2); if (!*arg1) { send_to_char("Give what to who?\r\n", ch); return 0; } else if (!*arg2) { send_to_char("To who?\r\n", ch); return 0; } else if (!(vict = get_char_room_vis(ch, arg2))) { send_to_char("No-one by that name here.\r\n", ch); return 0; } else if (vict == ch) { send_to_char("What's the point of that?\r\n", ch); return 0; } 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 ((GET_GOLD(ch) < amount) && (IS_NPC(ch) || (GET_LEVEL(ch) < LEVEL_GOD))) { send_to_char("You haven't got that many coins!\r\n", ch); return; } send_to_char("Ok.\r\n", ch); sprintf(buf, "%s gives you %s.\r\n", PERS(ch, vict), report_cost(amount)); send_to_char(buf, vict); act("$n gives some money to $N.", TRUE, ch, 0, vict, TO_NOTVICT); drop_excess_gold(vict, amount); if (IS_NPC(ch) || (GET_LEVEL(ch) < LEVEL_GOD)) change_gold(ch, -amount); } ACMD(do_unhitch) { ACMD(do_say); struct char_data *vict; struct obj_data *cart; one_argument(argument, arg); if (!*arg){ send_to_char("Unhitch what?\r\n", ch); return; } if (!(vict = get_char_room_vis(ch, arg))){ send_to_char("Unhitch who?\r\n", ch); return;} else if (!(cart = IS_PULLING(vict))) { act("$N isn't hitched to anything.\n",TRUE,ch,0,vict,TO_CHAR); return; } if ((vict->master != ch && vict != ch) && vict->in_room == ch->in_room && (GET_LEVEL(ch) < LEVEL_BUILDER)){ if (IS_MOB(vict)){ if (CAN_SPEAK(vict)){ act("$n slaps your wrist.",TRUE,vict,0,ch,TO_VICT); act("$n slaps $N's wrist.",TRUE,vict,0,ch,TO_ROOM); do_say(vict,"Hey get your own cart!",0,0);} else{ act("$n shies away from $N.",TRUE,vict,0,ch,TO_NOTVICT); act("$n shies away from you.",TRUE,vict,0,ch,TO_VICT); } } else act("$n just tried to remove your cart.",TRUE,ch,0,vict,TO_VICT); return; } else unhitch(ch, cart, vict, 0); return; } void unhitch(struct char_data *ch, struct obj_data *cart, struct char_data *vict, char quiet) { struct follow_type *j,*k; if (!quiet){ act("You unhitch $N.",FALSE,ch,0,vict,TO_CHAR); act("$n unhitches $N from $p.",FALSE,ch,cart,vict,TO_ROOM); act("$n unhitches $p from you.",FALSE,ch,cart,vict,TO_VICT); } if (cart->pulled_by->follower == vict){ k = cart->pulled_by; cart->pulled_by = k->next; free(k);} else { for (k = cart->pulled_by; k->next->follower != vict;k = k->next) ; j = k->next; k->next = j->next; free(j); } vict->specials.cart = 0; } void hitch(struct char_data *ch, struct obj_data *cart, struct char_data *vict, char quiet) { struct follow_type *k; CREATE(k, struct follow_type, 1); k->follower = vict; k->next = cart->pulled_by; cart->pulled_by = k; vict->specials.cart = cart; if (!quiet){ act("You hitch $p to $N",TRUE,ch,cart,vict,TO_CHAR); act("$n hitches $p to $N",TRUE,ch,cart,vict,TO_ROOM); act("$n hitches $p to you",TRUE,ch,cart,vict,TO_VICT); } } ACMD(do_mount) { ACMD(do_say); struct char_data *victim; int num, result; one_argument(argument, arg); if (!*arg) { send_to_char("Mount what?\r\n",ch); return; } if (ch->specials.mount) { send_to_char("You should dismount before you try mounting another mount.\r\n",ch); return; } victim = get_char_room_vis(ch, arg); if (victim) { if (victim == ch) { send_to_char("You attempt to clamber on your own back - to no avail.\r\n" ,ch); return; } if (victim->specials.fighting) { send_to_char("You can't mount beasts in combat.\r\n",ch); return; } if (IS_PULLING(victim)) { send_to_char("You can mount beasts pulling carts.\r\n",ch); return; } if (victim->specials.carried_by) { act("$N is being carried you cannot mount $M." ,FALSE,ch,0,victim,TO_CHAR); return; } if (ch->specials.carrying) { act("You had better drop $N first.", FALSE,ch,0,ch->specials.carrying,TO_CHAR); return; } if (victim->specials.rider) { act("$N already has a rider.",FALSE,ch,0,victim,TO_CHAR); return; } if ((GET_SIZE(ch) > GET_SIZE(victim)) && ((GET_SIZE(ch) - GET_SIZE(victim)) > 1)) { act("You can't ride $N, $E's too big.",FALSE,ch,0,victim,TO_CHAR); return; } else if ((GET_SIZE(ch) < GET_SIZE(victim)) && ((GET_SIZE(victim) - GET_SIZE(ch)) > 1)) { act("You can't ride $N, $E's too small.",FALSE,ch,0,victim,TO_CHAR); return; } if ((GET_WEIGHT(ch) + IS_CARRYING_W(ch)) > CAN_CARRY_W(victim)) { act("You can't ride $N. You are too heavy.",FALSE,ch,0,victim,TO_CHAR); return; } if (GET_SKILL(ch, SKILL_MOUNT) < (num = number(0,31))) { act("$n trys to mount up on $N and falls on $s backside.", FALSE,ch,0,victim,TO_ROOM); act("$n trys to mount up on you and falls on $s backside.", FALSE,ch,0,victim,TO_VICT); act("You try to mount up on $N and fall on your backside.", FALSE,ch,0,victim,TO_CHAR); GET_POS(ch) = POSITION_SITTING; if (num == 0 && (number(0,31) == 0) && (number(0,31) > GET_SKILL(ch, SKILL_MOUNT)) && (GET_SKILL(ch, SKILL_MOUNT) < 30)) { send_to_char("You realise how you can improve your mounting technique\r\n.",ch); SET_SKILL(ch, SKILL_MOUNT,(GET_SKILL(ch,SKILL_MOUNT) +1)); rmdamage(ch,GET_HEIGHT(victim)/number(5,20)); } return; } if (IS_MOB(victim) && MOB_FLAGGED(victim, MOB_DOCILE) && !IS_AFFECTED(victim, AFF_CHARM)) { if (victim->master && victim->master != ch) stop_follower_quiet(victim); if (!victim->master) if (!circle_follow(victim, ch)) if ((result = add_follower(victim,ch)) == 0){ act("$N tried to follow you but you already have too many followers." ,FALSE,ch,0,victim,TO_CHAR); act("$n already has too many followers." ,FALSE,ch,0,victim,TO_VICT); return; } } if (victim->master != ch) { send_to_char("Your mount must follow you first.\r\n",ch); if (IS_MOB(victim)) { act("$n attempts to mount $N.",FALSE,ch,0,victim,TO_ROOM); if (!CAN_SPEAK(victim)) act("$N shies away from $n.",FALSE,ch,0,victim,TO_ROOM); else { act("$N tells $n to get lost.",FALSE,ch,0,victim,TO_ROOM); act("$N tells you to get lost.",FALSE,ch,0,victim,TO_CHAR); } } else act("$N just tried to mount up on your back.", FALSE,victim,0,ch,TO_CHAR); return; } act("$n mounts up on $N's back.",FALSE,ch,0,victim,TO_NOTVICT); act("$n mounts up on your back.",FALSE,ch,0,victim,TO_VICT); act("You mount up on $N's back.",FALSE,ch,0,victim,TO_CHAR); if (IS_AFFECTED(ch, AFF_SNEAK)) affect_from_char(ch, SKILL_SNEAK); if (IS_SET(MOB_FLAGS(victim), MOB_MEMORY)) REMOVE_BIT(MOB_FLAGS(victim), MOB_MEMORY); ch->specials.mount = victim; victim->specials.rider = ch; IS_CARRYING_W(victim) += (GET_WEIGHT(ch) + IS_CARRYING_W(ch)); return; } sprintf(buf,"You don't see %s here.\r\n",arg); send_to_char(buf,ch); return; } bool do_get_mob(struct char_data *ch, struct char_data *victim) { ACMD(do_say); int num, result; if (ch->specials.carrying) { act("You are already carrying $N.", FALSE,ch,0,ch->specials.carrying, TO_CHAR); return(FALSE); } if (victim) { if (victim == ch) { send_to_char("Don't be silly.\r\n",ch); return(FALSE); } if (victim->specials.fighting) { send_to_char("You pick people up in combat.\r\n",ch); return(FALSE); } if (IS_PULLING(victim)) { send_to_char("Try unhitching them first.\r\n",ch); return(FALSE); } if (victim->specials.rider) { act("Get $N to dismount first.", FALSE,ch,0,victim->specials.rider,TO_CHAR); return(FALSE); } if (victim->specials.mount) { act("Get $N to dismount first.",FALSE,ch,0,victim,TO_CHAR); return(FALSE); } if (victim->specials.carried_by) { act("$N is already being carried.",FALSE,ch,0,victim,TO_CHAR); return(FALSE); } if (ch->equipment[WIELD] || ch->equipment[HOLD]) { send_to_char("Your hands seem to be full.\r\n",ch); return; } if ((GET_SIZE(ch) > GET_SIZE(victim)) && ((GET_SIZE(ch) - GET_SIZE(victim)) > 1)) { act("You can't carry $N, $E's too big.",FALSE,ch,0,victim,TO_CHAR); return(FALSE); } if ((GET_WEIGHT(victim) + IS_CARRYING_W(victim)) > CAN_CARRY_W(ch)) { act("You can't carry $N, $E's too heavy.",FALSE,ch,0,victim,TO_CHAR); return(FALSE); } if (IS_MOB(victim) && MOB_FLAGGED(victim, MOB_DOCILE) && !IS_AFFECTED(victim, AFF_CHARM)) { if (victim->master && victim->master != ch) stop_follower_quiet(victim); if (!victim->master) if (!circle_follow(victim, ch)) if ((result = add_follower(victim,ch)) == 0){ act("$N tried to follow you but you already have too many followers." ,FALSE,ch,0,victim,TO_CHAR); act("$n already has too many followers." ,FALSE,ch,0,victim,TO_VICT); return; } } if (victim->master != ch) { act("$N must follow you first.",FALSE,ch,0,victim, TO_CHAR); if (IS_MOB(victim)) { act("$n attempts to pick up $N.",FALSE,ch,0,victim,TO_ROOM); if (!CAN_SPEAK(victim)) act("$N shies away from $n.",FALSE,ch,0,victim,TO_ROOM); else { act("$N tells $n to get lost.",FALSE,ch,0,victim,TO_ROOM); act("$N tells you to get lost.",FALSE,ch,0,victim,TO_CHAR); } } else act("$N just tried to pick you up.", FALSE,victim,0,ch,TO_CHAR); return(FALSE); } act("$n picks up $N.",FALSE,ch,0,victim,TO_NOTVICT); act("$n picks you up.",FALSE,ch,0,victim,TO_VICT); act("You pick $N up.",FALSE,ch,0,victim,TO_CHAR); if (IS_AFFECTED(ch, AFF_SNEAK)) affect_from_char(ch, SKILL_SNEAK); if (IS_SET(MOB_FLAGS(victim), MOB_MEMORY)) REMOVE_BIT(MOB_FLAGS(victim), MOB_MEMORY); ch->specials.carrying = victim; victim->specials.carried_by = ch; IS_CARRYING_W(ch) += (GET_WEIGHT(victim) + IS_CARRYING_W(victim)); return(TRUE); } send_to_char("Get who?\r\n",ch); return(FALSE); } void do_drop_mob(struct char_data *ch) { struct char_data *victim; if (victim = ch->specials.carrying) { victim->specials.carried_by = 0; ch->specials.carrying = 0; IS_CARRYING_W(ch) -= (GET_WEIGHT(victim) + IS_CARRYING_W(victim)); act("You drop $N.",FALSE,ch,0,victim, TO_CHAR); act("$n drops You.",FALSE,ch,0,victim, TO_VICT); act("$n drops $N.",FALSE,ch,0,victim, TO_NOTVICT); } } void unmount(struct char_data *ch) { struct char_data *victim; ch->specials.mount->specials.rider = 0; victim = ch->specials.mount; ch->specials.mount = 0; IS_CARRYING_W(victim) -= (GET_WEIGHT(ch) + IS_CARRYING_W(ch)); } ACMD(do_dismount) { int num; if (!ch->specials.mount) { send_to_char("Dismount? You are not even riding anything.\r\n",ch); return; } if (GET_SKILL(ch, SKILL_MOUNT) < (num = number(0,31))) { act("$n trys to dismount $N and falls on $s backside.", FALSE,ch,0,ch->specials.mount,TO_ROOM); act("$n trys to dismount you and falls on $s backside.", FALSE,ch,0,ch->specials.mount,TO_VICT); act("You try to dismount $N and fall on your backside.", FALSE,ch,0,ch->specials.mount,TO_CHAR); unmount(ch); GET_POS(ch) = POSITION_SITTING; if (num == 0 && (number(0,31) == 0) && (number(0,31) > GET_SKILL(ch, SKILL_MOUNT)) && (GET_SKILL(ch, SKILL_MOUNT) < 30)) { send_to_char("You realise how you can improve your dismounting technique\r\n.",ch); SET_SKILL(ch, SKILL_MOUNT,(GET_SKILL(ch,SKILL_MOUNT) + 1)); rmdamage(ch,GET_HEIGHT(ch->specials.mount)/number(5,20)); } } else { act("$n climbs off $N's back.",FALSE,ch,0,ch->specials.mount,TO_NOTVICT); act("$n climbs off your back.",FALSE,ch,0,ch->specials.mount,TO_VICT); act("You climb off $N's back.",FALSE,ch,0,ch->specials.mount,TO_CHAR); unmount(ch); } } ACMD(do_hitch) { ACMD(do_say); struct char_data *vict; struct obj_data *cart; argument_interpreter(argument, arg, buf2); if (!*arg){ send_to_char("Hitch what?\r\n", ch); return; } else if (!(cart = get_obj_in_list_vis(ch,arg,world[ch->in_room].contents))) { if (is_plural(arg)) sprintf(buf, "You can't seem to find any %s here.\r\n", arg); else sprintf(buf, "You can't seem to find any %s here.\r\n", make_plural(arg)); send_to_char(buf, ch); return;} if (!(vict = get_char_room_vis(ch, buf2))){ send_to_char("Hitch to what?\r\n", ch); return;} if (vict == ch){ send_to_char("Now why would you want to do that?\r\n", ch); return;} if (vict->specials.rider) { send_to_char("You can hitch carts to mounts.\r\n",ch); return; } if(!IS_CART(cart)){ send_to_char("You can't hitch that!\r\n",ch); return;} if (cart && vict){ if (IS_PULLING(vict)) { do_unhitch(ch,GET_NAME(vict),0,0); if (!IS_PULLING(vict)) return; } if (vict->master != ch && vict != ch && (GET_LEVEL(ch) < LEVEL_BUILDER)){ if (IS_MOB(vict)){ if (CAN_SPEAK(vict)){ act("$n slaps your wrist.",TRUE,vict,0,ch,TO_VICT); act("$n slaps $N's wrist.",TRUE,vict,0,ch,TO_NOTVICT); do_say(vict,"Hey watch it!",0,0);} else { act("$n shies away from $N.",TRUE,vict,0,ch,TO_NOTVICT); act("$n shies away from you.",TRUE,vict,0,ch,TO_VICT); } } else act("$n just tried to hitch a cart to you.",TRUE,ch,0,vict,TO_VICT); return; } if(IS_NPC(vict) && !IS_SET(vict->specials2.act, MOB_SENTINEL)) SET_BIT(vict->specials2.act, MOB_SENTINEL); hitch(ch,cart,vict,0); } return; } ACMD(do_give) { char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; char arg3[MAX_INPUT_LENGTH]; int amount, dotmode; struct char_data *vict; struct obj_data *obj, *next_obj; half_chop(argument, arg1, arg2); *arg3 = LOWER(*arg2); if (!*arg1) send_to_char("Give what to whom?\r\n", ch); else if (is_number(arg1)) { amount = atoi(arg1); if (!(vict = give_find_vict(ch, arg2))) return; if (!str_cmp("coins", arg2) || !str_cmp("coin", arg2) || !str_cmp("pennies", arg2) || !str_cmp("penny",arg2)) perform_give_gold(ch,vict, amount*10); else if (!str_cmp("groats", arg2) || !str_cmp("groat", arg2) ) perform_give_gold(ch,vict, amount*100); else if (!str_cmp("crowns", arg2) || !str_cmp("crown", arg2) ) perform_give_gold(ch,vict, amount*1000); else { /* code to give multiple items. anyone want to write it? -je */ send_to_char("Sorry, you can't do that (yet)...\r\n", ch); return; } } else { if (!(vict = give_find_vict(ch, argument))) return; if (IS_NPC(vict) && GET_LEVEL(ch) <= LEVEL_BUILDER){ act("$N refuses your kind offer.",FALSE,ch,0,vict,TO_CHAR); return;} dotmode = find_all_dots(argument); if (dotmode == FIND_ALL) { if (!ch->inventory) send_to_char("You don't seem to be holding anything.\r\n", ch); else for (obj = ch->inventory; obj; obj = next_obj) { next_obj = obj->next_content; perform_give(ch, vict, obj); } } else if (dotmode == FIND_ALLDOT) { if (!*argument) { send_to_char("All of what?\r\n", ch); return; } if (!(obj = get_obj_in_list_vis(ch, argument, ch->inventory))) { if(is_plural(argument)) sprintf(buf, "You don't seem to have any %s.\r\n", argument); else sprintf(buf, "You don't seem to have any %s.\r\n", make_plural(argument)); send_to_char(buf, ch); } else while (obj) { next_obj = get_obj_in_list_vis(ch, argument, obj->next_content); perform_give(ch, vict, obj); obj = next_obj; } } else { if (!(obj = get_obj_in_list_vis(ch, argument, ch->inventory))) { sprintf(buf, "You don't seem to have %s %s.\r\n", AN(argument), argument); send_to_char(buf, ch); } else perform_give(ch, vict, obj); } } } bool is_plural(char *arg) { char *loc; int i; /* this is a really simple minded algorithm - checks to see if last char is an 's' AJN 29th Nov 94 */ loc = arg; if (!*arg) return(FALSE); /* check exceptions */ for(i=0;strcmp(nonreg_plurals[i].singular,"\n");i++) { if (!strcmp(nonreg_plurals[i].plural,arg)) /*already plural*/ return(TRUE); else if (!strcmp(nonreg_plurals[i].singular,arg)) return(FALSE); } while (*loc != '\0') loc++; loc--; if (*loc == 's') return(TRUE); return(FALSE); }