/************************************************************************ Realms of Aurealis James Rhone aka Vall of RoA objects.c Activities dealing with the manipulation of objects are in this file... get/put/eat/etc ******** Heavily modified and expanded ******** *** BE AWARE OF ALL RIGHTS AND RESERVATIONS *** ******** Heavily modified and expanded ******** All rights reserved henceforth. Please note that no guarantees are associated with any code from Realms of Aurealis. All code which has been released to the general public has been done so with an 'as is' pretense. RoA is based on both Diku and CircleMUD and ALL licenses from both *MUST* be adhered to as well as the RoA license. *** Read, Learn, Understand, Improve *** *************************************************************************/ #include "conf.h" #include "sysdep.h" #include "structures.h" #include "utils.h" #include "comm.h" #include "interpreter.h" #include "acmd.h" #include "handler.h" #include "db.h" #include "magic.h" #include "mudlimits.h" #include "fight.h" #include "affect.h" #include "quest.h" #include "lists.h" #include "global.h" #include "boards.h" #include "htown.h" #include "plshop.h" #include "nature.h" #include "darkenelf.h" /* extern variables */ extern struct str_app_type str_app[]; extern struct htown_data htowns[]; extern char *drinks[]; extern int drink_aff[][3]; extern char *dirs[NUM_OF_DIRS]; extern char *comm_dirs[NUM_OF_DIRS]; extern char *rev_dir_str[NUM_OF_DIRS]; // external functions void do_room_dump(chdata *ch, obdata *obj); int check_room_affects(chdata *ch, int room); int ManyObjs(char *arg, char *ptr); /* (RoA) for obj_hits decrements hit total on object, checks if object has been rendered useless and unequips if so */ void damage_object(obdata *ob, chdata *ch) { int slot; if (!ob) return; if (MAX_OBJ_HITS(ob) == -1) return; /* indestructable */ if (OBJ_HITS(ob)-- > 0) { // should send message notifying ch that obj has been damaged return; } /* else the object is <= 1 hits */ OBJ_HITS(ob) = 0; if (ch) /* a player is carrying or has it as eq */ { if (ob->carried_by && ob->carried_by != ch) { log("SYSERR: Invalid carrier in damage_object."); return; } if (ob->carried_by) /* in inventory */ { act("%B$p has been damaged beyond repair!%0", TRUE, ch, ob, 0,TO_CHAR); return; } else { for (slot = 0; slot < MAX_WEAR; slot++) if (ob == EQ(ch, slot)) break; if (slot == MAX_WEAR) { log("SYSERR: Invalid equipment slot in damage_object."); return; } act("%B$p has been damaged beyond repair!%0", TRUE, ch, ob, 0,TO_CHAR); obj_to_char(unequip_char(ch, slot, TRUE), ch); } } else /* its lying around on the ground */ { act("$p decays into nothingness.",TRUE,0,ob,0,TO_ROOM); extract_obj(ob); } } ACMD(do_quaff) { obdata *temp; int i; BOOL equipped = FALSE; one_argument(argument, buf); if (!(temp = get_obj_in_list_vis(ch, buf, ch->carrying))) { temp = EQ(ch, W_HOLD); equipped = TRUE; if (!temp || !isname(buf, temp->name)) { act("You do not have that item.", FALSE, ch, 0, 0, TO_CHAR); return; } } if (temp->type_flag != ITEM_POTION) { act("You can only quaff potions.", FALSE, ch, 0, 0, TO_CHAR); return; } act("$n quaffs $p.", TRUE, ch, temp, 0, TO_ROOM); act("You quaff $p which dissolves.", FALSE, ch, temp, 0, TO_CHAR); for (i = 1; i < 4; i++) if (temp->value[i] >= 1) { if (number(1, 101) < SUCCESS_RATE(temp)) do_cast_spell(temp->value[i], ch, "", SPELL_TYPE_POTION, ch, NULL); else act("$p has no affect on you.", FALSE, ch, temp, 0, TO_CHAR); } if (equipped) unequip_char(ch, W_HOLD, TRUE); extract_obj(temp); } ACMD(do_recite) { obdata *scroll, *obj; chdata *victim; int i, bits; BOOL equipped = FALSE; BOOL passed = TRUE; obj = 0; victim = 0; argument = one_argument(argument, buf); if (!(scroll = get_obj_in_list_vis(ch, buf, ch->carrying))) { scroll = EQ(ch, W_HOLD); equipped = TRUE; if ((scroll == 0) || !isname(buf, scroll->name)) { act("You do not have that item.", FALSE, ch, 0, 0, TO_CHAR); return; } } if (scroll->type_flag != ITEM_SCROLL) { act("Recite is normally used for scrolls.", FALSE, ch, 0, 0, TO_CHAR); return; } if (ROOM_FLAGGED(ch->in_room, NO_MAGIC)) { send_to_char("The atmosphere surrounding you prevents the use of magic.\n\r",ch); return; } if (*argument) { bits = generic_find(argument, FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_OBJ_EQUIP | FIND_CHAR_ROOM, ch, &victim, &obj); if (!bits) { send_to_char("No such thing around to recite the scroll on.\n\r", ch); return; } } else victim = ch; act("$n recites $p.", TRUE, ch, scroll, 0, TO_ROOM); act("You recite $p which dissolves.", FALSE, ch, scroll, 0, TO_CHAR); if (equipped) unequip_char(ch, W_HOLD, TRUE); for (i = 1; i < 4; i++) if (scroll->value[i] >= 1) { passed = TRUE; if (SPELL_FLAGGED(scroll->value[i], S_VIOLENT)) { if (ROOM_FLAGGED(ch->in_room, PEACEFUL)) { send_to_char("A force beyond comprehension counteracts violence in this area.\n\r",ch); passed = FALSE; } if (GET_GSKILL(ch, GSKILL_RUNIC) < number(1, 101)) { act("You fail to decipher $p.", FALSE, ch, scroll, 0, TO_CHAR); passed = FALSE; } if (ch && victim && passed) { passed = check_truce(ch, victim); if (IS_PC(victim) && IS_PC(ch) && !IN_ARENA(ch) && (!IS_ASSASSIN(victim) || !IS_ASSASSIN(ch))) { send_to_char("%1Assassin vs Assassin ONLY%0.\n\r",ch); passed = FALSE; } } } /* made it through the checks ok */ if (passed && spell_info[scroll->value[i]].spell_pointer) { if (number(1, 101) < SUCCESS_RATE(scroll)) do_cast_spell(scroll->value[i], ch, "", SPELL_TYPE_SCROLL, victim, obj); else act("$p fails.", FALSE, ch, scroll, victim, TO_CHAR); } } extract_obj(scroll); } // moved here from misc... since use is primarily objects... 6/30/98 -jtrhone // split up a bit as well... 6/30/98 -jtrhone void do_use_staff(chdata *ch, obdata *stick) { act("$n taps $p three times on the ground.", TRUE, ch, stick, 0, TO_ROOM); act("You tap $p three times on the ground.", FALSE, ch, stick, 0, TO_CHAR); if (stick->value[2] > 0) /* Is there any charges left? */ { /* check if spell is violent here */ if (SPELL_FLAGGED(stick->value[3], S_VIOLENT) && ROOM_FLAGGED(ch->in_room, PEACEFUL)) { send_to_char("Violence is not allowed here.\n\r",ch); return; } stick->value[2]--; if (number(1, 101) < SUCCESS_RATE(stick)) do_cast_spell(stick->value[3], ch, "", SPELL_TYPE_STAFF, 0, 0); else act("$p fails.", FALSE, ch, stick, 0, TO_CHAR); /* delay character a bit to eliminate machinegun affect */ WAIT_STATE(ch, (PULSE_VIOLENCE * 2)); } else act("$p seems powerless.", TRUE, ch, stick, 0, TO_CHAR); } void do_use_wand(chdata *ch, obdata *stick, char *arg) { chdata *tch; obdata *tob; int bits; bits = generic_find(arg, FIND_CHAR_ROOM | FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_OBJ_EQUIP, ch, &tch, &tob); if (bits) { if (bits == FIND_CHAR_ROOM) { act("$n points $p at $N.", TRUE, ch, stick, tch, TO_ROOM); act("You point $p at $N.", FALSE, ch, stick, tch, TO_CHAR); } else { act("$n points $p at $P.", TRUE, ch, stick, tob, TO_ROOM); act("You point $p at $P.", FALSE, ch, stick, tob, TO_CHAR); } if (stick->value[2] > 0) /* Is there any charges left? */ { /* check if spell is violent here */ if (SPELL_FLAGGED(stick->value[3], S_VIOLENT)) { if (ROOM_FLAGGED(ch->in_room, PEACEFUL)) { send_to_char("This area is strangely protected against violence.\n\r", ch); return; } if (tch && IS_PC(tch)) if (!IS_ASSASSIN(ch) || !IS_ASSASSIN(tch)) { send_to_char("You must be an assassin.\n\r",ch); return; } } stick->value[2]--; if (number(1, 101) < SUCCESS_RATE(stick)) do_cast_spell(stick->value[3], ch, "", SPELL_TYPE_WAND, tch, tob); else act("$p fails.", FALSE, ch, stick, 0, TO_CHAR); /* delay character a bit to eliminate machinegun affect */ WAIT_STATE(ch, (PULSE_VIOLENCE * 2)); } else act("$p seems powerless.", TRUE, ch, stick, 0, TO_CHAR); } else send_to_char("What should the wand be pointed at?\n\r", ch); } void do_use_portal(chdata *ch, obdata *stick) { int rnum; if (FIGHTING(ch) || GET_POS(ch) == POS_FIGHTING) { act("You cannot concentrate enough while fighting!", FALSE, ch, 0, 0, TO_CHAR); return; } act("$n calls forth the power of $p.", TRUE, ch, stick, 0, TO_ROOM); act("You call forth the power of $p.", FALSE, ch, stick, 0, TO_CHAR); if (ROOM_FLAGGED(ch->in_room, NO_RECALL) || IN_ARENA(ch)) { send_to_char("The atmosphere surrounding you prevents teleportation.\n\r",ch); return; } /* are there any charges left? */ if (stick->value[2] > 0 && (rnum = real_room(stick->value[3])) > 0) { if (ZONE_FLAGGED(world[rnum].zone, Z_LOCKED | Z_CLOSED)) { send_to_char("Sorry, destination down for construction.\n\r",ch); return; } stick->value[2]--; if (number(1, 101) < SUCCESS_RATE(stick)) { act("$n suddenly vanishes!", TRUE, ch, 0, 0, TO_ROOM); char_from_room(ch); char_to_room(ch, rnum); act("$n suddenly arrives grasping $p!", TRUE, ch, stick, 0, TO_ROOM); act("Using $p has teleported you!", FALSE, ch, stick, 0, TO_CHAR); do_look_at_room(ch, 0, 0); if (check_room_affects(ch, ch->in_room) == CHAR_DIED) return; if (check_death_trap(ch, NULL)) return; float_sink_char(ch); } else act("$p fails.", FALSE, ch, stick, 0, TO_CHAR); } else act("$p seems powerless.", TRUE, ch, stick, 0, TO_CHAR); } void do_use_gem(chdata *ch, obdata *stick) { int num, size; if (FIGHTING(ch) || GET_POS(ch) == POS_FIGHTING) { act("You cannot concentrate enough while fighting!", FALSE, ch, 0, 0, TO_CHAR); return; } act("$n calls forth the power of $p.", TRUE, ch, stick, 0, TO_ROOM); act("You call forth the power of $p.", FALSE, ch, stick, 0, TO_CHAR); /* are there any charges left? */ if (stick->value[1] > 0) { stick->value[1]--; if (number(1, 101) < SUCCESS_RATE(stick)) { num = MAX(1, stick->value[2]); size = MAX(1, stick->value[3]); GET_MANA(ch) += dice(num, size); GET_MANA(ch) = MIN(GET_MANA(ch), GET_MAX_MANA(ch)); act("$p %B%6glows%0 briefly in your hands!", TRUE, ch, stick, 0, TO_CHAR); act("$p %B%6glows%0 briefly in $n's hands!", TRUE, ch, stick, 0, TO_ROOM); } else act("$p fails.", FALSE, ch, stick, 0, TO_CHAR); } else act("$p seems powerless.", TRUE, ch, stick, 0, TO_CHAR); // for now, one use only on harmonic gems stick = unequip_char(ch, W_HOLD, FALSE); extract_obj(stick); } // to teach madepts (and similar classes eventually) skills/spells void do_use_tome(chdata *ch, obdata *stick) { int i, num, learned; if (FIGHTING(ch) || GET_POS(ch) == POS_FIGHTING) { act("You cannot concentrate enough while fighting!", FALSE, ch, 0, 0, TO_CHAR); return; } // must be a class which can aquire along the way, eventually all? if (!IS_NAT_MADEPT(ch) && !IS_IMMORTAL(ch)) { act("You gain nothing from studying $p.", TRUE, ch, stick, 0, TO_CHAR); return; } act("You study $p.", TRUE, ch, stick, 0, TO_CHAR); act("$n studies $p.", TRUE, ch, stick, 0, TO_ROOM); // scan all 4 skill slots, learn each based on success rate (and soon runic skill) for (num = learned = i = 0; i < 4; i++) if (stick->value[i] > 0 && stick->value[i] < MAX_SKILLS) { num++; if (!ch->skills[stick->value[i]].learned || IS_IMMORTAL(ch)) { learned++; if (number(1, 101) < SUCCESS_RATE(stick)) { sprintf(buf, "You learn %%B%%6%s%%0 from $p.", skill_names[stick->value[i]]); act(buf, FALSE, ch, stick, 0, TO_CHAR); act("$n's eyes widen slightly as $e studies $p.", TRUE, ch, stick, 0, TO_ROOM); // set skill to learned ch->skills[stick->value[i]].learned = TRUE; } // then wax that one off tome stick->value[i] = 0; } } if (!num) act("$p seems useless.", TRUE, ch, stick, 0, TO_CHAR); else if (!learned) act("You learn nothing new from $p.", TRUE, ch, stick, 0, TO_CHAR); else if (num == learned) // they learned everything possible... { act("$p crumbles into nothingness.", TRUE, ch, stick, 0, TO_CHAR); stick = unequip_char(ch, W_HOLD, FALSE); extract_obj(stick); } } ACMD(do_use) { obdata *stick = 0; char *argu = argument; skip_spaces(&argu); one_argument(argu, arg); if (!EQ(ch, W_HOLD) || !isname(arg, EQ(ch, W_HOLD)->name)) { act("You do not hold that item in your hand.", FALSE, ch, 0, 0, TO_CHAR); return; } if (ROOM_FLAGGED(ch->in_room, NO_MAGIC)) { send_to_char("The atmosphere surrounding you prevents the use of magic.\n\r",ch); return; } stick = EQ(ch, W_HOLD); switch(ITEM_TYPE(stick)) { case ITEM_STAFF: do_use_staff(ch, stick); break; case ITEM_WAND: do_use_wand(ch, stick, argu); break; case ITEM_PORTAL: do_use_portal(ch, stick); break; case ITEM_GEM: do_use_gem(ch, stick); break; case ITEM_TOME: do_use_tome(ch, stick); break; default: send_to_char("That item fails to respond.\n\r", ch); break; } } void perform_put(chdata *ch, obdata *obj, obdata *container) { if (GET_OBJ_WEIGHT(container) + GET_OBJ_WEIGHT(obj) > container->value[0]) act("$p won't fit in $P.", FALSE, ch, obj, container, TO_CHAR); else { obj_from_char(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); } } void perform_silent_put(chdata *ch, obdata *obj, obdata *container) { if (GET_OBJ_WEIGHT(container) + GET_OBJ_WEIGHT(obj) > container->value[0]) act("$p won't fit in $P.", FALSE, ch, obj, container, TO_CHAR); else { obj_from_char(obj); obj_to_obj(obj, container); } } // Reworked to handle ManyObjs() func. 08/10/98 -callahan ACMD(do_put) { char arg1[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH], multarg[MAX_INPUT_LENGTH]; obdata *obj, *next_obj, *container; chdata *tmp_char; int obj_dotmode, cont_dotmode, amount; two_arguments(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.\n\r", ch); else if (!*arg1) send_to_char("Put what in what?\n\r", ch); else if (!*arg2) { sprintf(buf, "What do you want to put %s in?\n\r", ((obj_dotmode != FIND_INDIV) ? "them" : "it")); S2C(); } 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.\n\r", arg2); S2C(); } else if (ITEM_TYPE(container) != ITEM_CONTAINER) { act("$p is not a container.", FALSE, ch, container, 0, TO_CHAR); } else if (IS_SET(container->value[1], CONT_CLOSED)) { send_to_char("You'd better open it first!\n\r", ch); } else { if (obj_dotmode == FIND_ALL) { /* "put all <container>" case */ /* check and make sure the guy has something first */ if (container == ch->carrying && !ch->carrying->next_content) send_to_char("You don't seem to have anything to put in it.\n\r", ch); else for (obj = ch->carrying; 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->carrying))) { sprintf(buf, "You don't seem to have any %ss.\n\r", arg1); S2C(); } 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 ((amount = ManyObjs(arg1, multarg)) != 0) { strcpy(arg1, multarg); while (amount) { if (!(obj = get_obj_in_list_vis(ch, arg1, ch->carrying))) { SendChar(tprintf("You aren't carrying %s %s.\n\r", AN(arg1), arg1), ch); return; } perform_put(ch, obj, container); amount--; } } else { if (!(obj = get_obj_in_list_vis(ch, arg1, ch->carrying))) { sprintf(buf, "You aren't carrying %s %s.\n\r", AN(arg1), arg1); S2C(); } else if (obj == container) send_to_char("You cannot put that in itself :).\n\r", ch); else perform_put(ch, obj, container); } } } } } int can_take_obj(chdata *ch, obdata *obj) { if (IS_CARRYING_N(ch) >= CAN_CARRY_N(ch)) { act("You cannot carry that many items.",FALSE, ch, obj, 0,TO_CHAR); return FALSE; } else if ((IS_CARRYING_W(ch) + GET_OBJ_WEIGHT(obj)) > CAN_CARRY_W(ch)) { act("You cannot carry that much weight.",FALSE, ch, obj, 0,TO_CHAR); return FALSE; } else if (!(CAN_WEAR(obj, ITEM_TAKE))) { act("You are unable to take $p.",FALSE, ch, obj, 0, TO_CHAR); return FALSE; } return TRUE; } void get_check_money(chdata *ch, obdata *obj) { if ((ITEM_TYPE(obj) == ITEM_MONEY) && (obj->value[0] > 0)) { obj_from_char(obj); if (obj->value[0] > 1) { sprintf(buf, "There were %d %s.\n\r", obj->value[0], currency_name_plural); S2C(); } GET_GOLD(ch) += obj->value[0]; extract_obj(obj); } } void perform_get_from_container(chdata *ch, obdata *obj,obdata *cont, int mode) { 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.\n\r", OBJS(obj, ch)); else { obj_from_obj(obj); obj_to_char(obj, ch); 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); if (IS_CORPSE(cont) && (cont->plr_num > 0) && (IS_PC(ch) || (IS_NPC(ch) && CHARMED(ch))) && cont->plr_num != GET_IDNUM(ch)) { sprintf(buf, "PLRUPD: %s looted %s at %d.",GET_NAME(ch), cont->shdesc, world[ch->in_room].number); mudlog(buf, BRF, LEV_IMM, TRUE); } // check object they just got in case of immediate quest reward qcheck_obj_get(ch, obj); } } } // Reworked to handle ManyObjs() func. 08/10/98 -callahan void get_from_container(chdata *ch, obdata *cont, char *arg, int mode) { obdata *obj, *next_obj; int obj_dotmode, found = 0, amount; char multarg[MAX_STRING_LENGTH]; obj_dotmode = find_all_dots(arg); if (IS_SET(cont->value[1], CONT_CLOSED)) act("$p is closed.", FALSE, ch, cont, 0, TO_CHAR); else if (obj_dotmode == FIND_ALL) { for (obj = cont->contains; obj; obj = next_obj) { next_obj = obj->next_content; if (CAN_SEE_OBJ(ch, obj)) { found = TRUE; 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?\n\r", ch); return; } 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 = TRUE; perform_get_from_container(ch, obj, cont, mode); } obj = next_obj; } if (!found) { sprintf(buf, "You can't find any %ss in $p.", arg); act(buf, FALSE, ch, cont, 0, TO_CHAR); } } else { if ((amount = ManyObjs(arg, multarg)) != 0) { strcpy(arg, multarg); while (amount) { 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); return; } perform_get_from_container(ch, obj, cont, mode); amount--; } } 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(chdata *ch, obdata *obj) { if (can_take_obj(ch, obj) && !INVALID_ROOM(obj->in_room)) { obj_from_room(obj); obj_to_char(obj, ch); 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); // check object they just got in case of immediate quest reward qcheck_obj_get(ch, obj); return TRUE; } return FALSE; } // Modified for ManyObjs() func. 08/10/98 -callahan void get_from_room(chdata *ch, char *arg) { obdata *obj, *next_obj; int dotmode, found = 0, amount; char multarg[MAX_INPUT_LENGTH]; 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)) { found = TRUE; perform_get_from_room(ch, obj); } } if (!found) SendChar("There doesn't seem to be anything here.\n\r", ch); } else if (dotmode == FIND_ALLDOT) { if (!*arg) { SendChar("Get all of what?\n\r", ch); return; } if (!(obj = get_obj_in_list_vis(ch, arg, world[ch->in_room].contents))) { sprintf(buf, "You don't see any %ss here.\n\r", arg); S2C(); } 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 ((amount = ManyObjs(arg, multarg)) != 0) { strcpy(arg, multarg); while (amount) { if (!(obj = get_obj_in_list_vis(ch, arg, world[InRoom(ch)].contents))) { SendChar(tprintf("You don't see %s %s here.\n\r", AN(arg), arg), ch); return; } perform_get_from_room(ch, obj); amount--; } } else { if (!(obj = get_obj_in_list_vis(ch, arg, world[ch->in_room].contents))) { sprintf(buf, "You don't see %s %s here.\n\r", AN(arg), arg); S2C(); } else perform_get_from_room(ch, obj); } } } ACMD(do_get) { char arg1[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH]; int cont_dotmode, found = 0, mode; obdata *cont, *next_cont; chdata *tmp_char; if (IS_CARRYING_N(ch) >= CAN_CARRY_N(ch)) send_to_char("Your arms are already full!\n\r", ch); else { two_arguments(argument, arg1, arg2); if (!*arg1) send_to_char("Get what?\n\r", ch); else { if (!*arg2) get_from_room(ch, arg1); else { cont_dotmode = find_all_dots(arg2); /* use all in inv. and on ground */ if (cont_dotmode == FIND_ALL) { for (cont = ch->carrying; cont; cont = cont->next_content) if (ITEM_TYPE(cont) == ITEM_CONTAINER) { found = TRUE; 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) && ITEM_TYPE(cont) == ITEM_CONTAINER) { found = TRUE; get_from_container(ch, cont, arg1, FIND_OBJ_ROOM); } if (!found) SendChar("You can't seem to find any containers.\n\r", ch); } else if (cont_dotmode == FIND_ALLDOT) { if (!*arg2) { SendChar("Get from all of what?\n\r", ch); return; } cont = get_obj_in_list_vis(ch, arg2, ch->carrying); while (cont) { found = TRUE; next_cont = get_obj_in_list_vis(ch, arg2, cont->next_content); if (ITEM_TYPE(cont) != ITEM_CONTAINER) 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 = TRUE; next_cont = get_obj_in_list_vis(ch, arg2, cont->next_content); if (ITEM_TYPE(cont) != ITEM_CONTAINER) 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) { sprintf(buf, "You can't seem to find any %ss here.\n\r", arg2); S2C(); } } 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.\n\r", AN(arg2), arg2); S2C(); } else if (ITEM_TYPE(cont) != ITEM_CONTAINER) act("$p is not a container.", FALSE, ch, cont, 0, TO_CHAR); else get_from_container(ch, cont, arg1, mode); } } } } } // modified for runtime currency names 11/28/97 -jtrhone void perform_drop_gold(chdata *ch, int amount, byte mode, int don_room) { obdata *obj; if (amount <= 0) send_to_char("Heh heh heh.. we are jolly funny today, eh?\n\r", ch); else if (GET_GOLD(ch) < amount) send_to_char("You don't have that much!\n\r", ch); else { if (mode != SCMD_JUNK) { obj = create_money(amount); if (mode == SCMD_DONATE) { sprintf(buf, "You donate some %s!\n\r", currency_name_plural); S2C(); sprintf(buf, "$n donates some %s!", currency_name_plural); act(buf, FALSE, ch, 0, 0, TO_ROOM); sprintf(buf, "Some %s suddenly fade into view!\n\r", currency_name_plural); send_to_room_not_busy(buf, don_room); /* log this here JRhone */ if (IS_IMMORTAL(ch)) { sprintf(buf, "%s has donated %d %s.",GET_NAME(ch),amount, currency_name_plural); mudlog(buf, BRF, MAX(LEV_IMM, GET_INVIS_LEV(ch)), TRUE); } obj_to_room(obj, don_room); } else // mode == SCMD_DROP { sprintf(buf, "You drop some %s.\n\r", currency_name_plural); S2C(); sprintf(buf, "$n drops some %s.", currency_name_plural); act(buf, FALSE, ch, 0, 0, TO_ROOM); if (IS_IMMORTAL(ch)) { sprintf(buf, "%s has dropped %d %s.",GET_NAME(ch), amount, currency_name_plural); mudlog(buf, BRF, MAX(LEV_IMM, GET_INVIS_LEV(ch)), TRUE); } if (ROOM_FLAGGED2(ch->in_room, DUMP)) do_room_dump(ch, obj); else float_sink_gold(obj, ch->in_room); } } else // mode == SCMD_JUNK { sprintf(buf, "$n junks some %s?!?", currency_name_plural); act(buf, FALSE, ch, 0, 0, TO_ROOM); sprintf(buf, "You junk some %s?!?\n\r", currency_name_plural); S2C(); } GET_GOLD(ch) -= amount; } } #define VANISH(mode) ((mode == SCMD_DONATE || mode == SCMD_JUNK) ? \ " It vanishes in a puff of smoke!" : "") int perform_drop(chdata *ch, obdata *obj, byte mode, char *sname, sh_int RDR) { int value; int vnum = GET_OBJ_VNUM(obj); if (IS_SET(OBJ_EXTRAS(obj), ITEM_NODROP) && GET_LEVEL(ch) < LEV_IMM) { sprintf(buf, "You can't %s %s, it must be CURSED!\n\r", sname, OBJS(obj, ch)); S2C(); return 0; } if ((mode == SCMD_DONATE) && IS_SET(OBJ_EXTRAS(obj), ITEM_NODONATE)) { sprintf(buf, "You can't donate %s.\n\r", OBJS(obj, ch)); S2C(); return 0; } sprintf(buf, "You %s %s.%s\n\r", sname, OBJS(obj, ch), VANISH(mode)); S2C(); sprintf(buf, "$n %ss $p.%s", sname, VANISH(mode)); act(buf, TRUE, ch, obj, 0, TO_ROOM); obj_from_char(obj); switch(mode) { case SCMD_DROP: if (ROOM_FLAGGED2(ch->in_room, DUMP)) { do_room_dump(ch, obj); return 0; } float_sink_object(obj, ch->in_room); /* replaces obj_to_room RoA*/ if (IS_IMMORTAL(ch)) { sprintf(buf, "%s dropped [%d] %s at %d.",GET_NAME(ch),vnum, obj->shdesc, world[ch->in_room].number); mudlog(buf, BRF, MAX(LEV_IMM, GET_INVIS_LEV(ch)), TRUE); } return 0; break; case SCMD_DONATE: SET_BIT(OBJ_EXTRAS2(obj), ITEM_NOAUCTION); obj_to_room(obj, RDR); /* log this here JRhone */ if (IS_IMMORTAL(ch)) { sprintf(buf, "%s donated [%d] %s.",GET_NAME(ch),vnum,obj->shdesc); mudlog(buf, BRF, MAX(LEV_IMM, GET_INVIS_LEV(ch)), TRUE); } send_to_room("Something suddenly appears amidst a flash of light!\n\r", RDR); return 0; break; case SCMD_JUNK: value = MAX(1, MIN(200, obj->cost >> 4)); extract_obj(obj); return value; break; default: log("SYSERR: Incorrect argument passed to perform_drop"); break; } return 0; } ACMD(do_drop) { obdata *obj, *next_obj; byte mode = SCMD_DROP; int dotmode, amount = 0, num; char *sname, multarg[MAX_INPUT_LENGTH]; int don_room = 0, home_don_room = 0; int don_count = 0, don_num = 0, i; switch (subcmd) { case SCMD_JUNK: sname = "junk"; mode = SCMD_JUNK; break; case SCMD_DONATE: if (IS_NPC(ch)) return; sname = "donate"; mode = SCMD_DONATE; for (i = 0; i < top_of_world; i++) if (!ZONE_FLAGGED(world[i].zone, Z_CLOSED) && !ZONE_IDLE(world[i].zone) && !ZONE_FREED(world[i].zone) && !ZONE_FLAGGED(world[i].zone, Z_LOCKED) && ROOM_FLAGGED2(i, DONATION)) { if ((htowns[GET_HTOWN(ch)].rvnum / 100) == world[i].zone) home_don_room = i; don_count++; } if (don_count <= 0) { send_to_char("Sorry, you can't donate anything right now.\n\r", ch); return; } if (!(don_room = home_don_room)) { don_num = number(1, don_count); for(i = 0, don_count = 0; i < top_of_world; i++) if (!ZONE_FLAGGED(world[i].zone, Z_CLOSED) && !ZONE_IDLE(world[i].zone) && !ZONE_FREED(world[i].zone) && !ZONE_FLAGGED(world[i].zone, Z_LOCKED) && ROOM_FLAGGED2(i, DONATION)) { don_count++; if (don_count == don_num) break; } don_room = i; } break; default: sname = "drop"; break; } argument = one_argument(argument, arg); if (!*arg) { sprintf(buf, "What do you want to %s?\n\r", sname); S2C(); return; } else if (is_number(arg)) { amount = atoi(arg); argument = one_argument(argument, arg); if (!str_cmp(currency_name_plural, arg) || !str_cmp(currency_name, arg)) perform_drop_gold(ch, amount, mode, don_room); else { /* code to drop multiple items. anyone want to write it? -je */ send_to_char("Sorry, you can't do that (yet)...\n\r", 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("To protect you from accidents, you cannot junk everything.\n\r", ch); else send_to_char("You cannot donate everything in your inventory.\n\r", ch); return; } if (dotmode == FIND_ALL) { if (!ch->carrying) send_to_char("You don't seem to be carrying anything.\n\r", ch); else for (obj = ch->carrying; obj; obj = next_obj) { next_obj = obj->next_content; amount += perform_drop(ch, obj, mode, sname, don_room); } } else if (dotmode == FIND_ALLDOT) { if (!*arg) { sprintf(buf, "What do you want to %s all of?\n\r", sname); S2C(); return; } if (!(obj = get_obj_in_list_vis(ch, arg, ch->carrying))) { sprintf(buf, "You don't seem to have any %ss.\n\r", arg); S2C(); } while (obj) { next_obj = get_obj_in_list_vis(ch, arg, obj->next_content); amount += perform_drop(ch, obj, mode, sname, don_room); obj = next_obj; } } else { if ((num = ManyObjs(arg, multarg)) != 0) { strcpy(arg, multarg); while (num) { if (!(obj = get_obj_in_list_vis(ch, arg, ch->carrying))) { SendChar(tprintf("You don't seem to have %s %s.\n\r", AN(arg), arg), ch); return; } amount += perform_drop(ch, obj, mode, sname, don_room); num--; } } else { if (!(obj = get_obj_in_list_vis(ch, arg, ch->carrying))) { sprintf(buf, "You don't seem to have %s %s.\n\r", AN(arg), arg); S2C(); } else amount += perform_drop(ch, obj, mode, sname, don_room); } } } if (amount && (subcmd == SCMD_JUNK)) { send_to_char("You have been rewarded by the gods!\n\r", ch); act("$n has been rewarded by the gods!", TRUE, ch, 0, 0, TO_ROOM); GET_GOLD(ch) += amount; } } // The actual give -roa // 9/21/97, check for character quests on gives -roa void perform_give(chdata *ch, chdata *vict, obdata *obj, BOOL calc_weight) { int vnum = GET_OBJ_VNUM(obj); plshop *ptr; if (IS_SET(OBJ_EXTRAS(obj), ITEM_NODROP) && !IS_IMMORTAL(ch)) { act("You can't let go of $p!! Yeech!", FALSE, ch, obj, 0, TO_CHAR); return; } // updated to not always check #, and weight 1/22/98 -jtrhone if (calc_weight) { 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; } } if (IS_PC(vict) && PRF2_FLAGGED(vict, PRF2_NOGIVE)) { send_to_char("Some unknown force prevents you from doing that.\n\r",ch); sprintf(buf, "SYSUPD: %s failed giving %s to %s.",GET_NAME(ch), obj->shdesc, GET_NAME(vict)); mudlog(buf, BUG, LEV_IMM, TRUE); return; } if (MOB_FLAGGED(vict, MOB_PLSHOPKEEP)) { if (!(ptr = in_own_shop(ch)) || (GET_MOB_VNUM(vict) != ptr->shopkeep_vnum)) { send_to_char("Some unknown force prevents you from doing that.\n\r",ch); sprintf(buf, "SYSUPD: %s failed giving %s to %s.",GET_NAME(ch), obj->shdesc, GET_NAME(vict)); mudlog(buf, BUG, LEV_IMM, TRUE); return; } } 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); // check to see if they just gave quest object back to questor mob -roa qcheck_obj_give(ch, vict, obj); // check object they just got in case of immediate quest reward qcheck_obj_get(ch, obj); /* log this here -roa */ if (IS_IMMORTAL(ch)) { sprintf(buf, "%s gave [%d] %s to %s at %d.",GET_NAME(ch),vnum, obj->shdesc, GET_NAME(vict), world[ch->in_room].number); mudlog(buf, BRF, MAX(LEV_IMM, GET_INVIS_LEV(ch)), TRUE); } } /* utility function for give */ chdata *give_find_vict(chdata *ch, char *arg1) { chdata *vict; char arg2[MAX_INPUT_LENGTH]; strcpy(buf, arg1); two_arguments(buf, arg1, arg2); if (!*arg1) { send_to_char("Give what to who?\n\r", ch); return NULL; } else if (!*arg2) { send_to_char("To who?\n\r", ch); return NULL; } else if (!(vict = get_char_room_vis(ch, arg2))) { send_to_char("No-one by that name here.\n\r", ch); return NULL; } else if (vict == ch) { send_to_char("What's the point of that?\n\r", ch); return NULL; } else return vict; } void perform_give_gold(chdata *ch, chdata *vict, int amount) { if (amount <= 0) { send_to_char("Heh heh heh ... we are jolly funny today, eh?\n\r", ch); return; } if ((GET_GOLD(ch) < amount) && (IS_NPC(ch) || (GET_LEVEL(ch) < LEV_GOD))) { send_to_char("You haven't got that much!\n\r", ch); return; } sprintf(buf, "You give $M %d %s.", amount, currency_name_plural); act(buf, TRUE, ch, 0, vict, TO_CHAR); sprintf(buf, "%s gives you %d %s.\n\r", PERS(ch, vict), amount, currency_name_plural); send_to_char(buf, vict); sprintf(buf, "$n gives some %s to $N.", currency_name_plural); act(buf, TRUE, ch, 0, vict, TO_NOTVICT); if (IS_NPC(ch) || (GET_LEVEL(ch) < LEV_GOD)) GET_GOLD(ch) -= amount; GET_GOLD(vict) += amount; } // Reworked for ManyObjs() func. 08/10/98 -callahan ACMD(do_give) { char arg1[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH], multarg[MAX_INPUT_LENGTH]; int amount = 0, dotmode, num; chdata *vict; obdata *obj, *next_obj; half_chop(argument, arg1, arg2); if (!*arg1) { send_to_char("Give what to who?\n\r", ch); return; } else if (is_number(arg1)) { amount = atoi(arg1); if (!(vict = give_find_vict(ch, arg2))) { send_to_char("Give what to who?\n\r", ch); return; } // cannot give normally to shopkeep mob if (!IS_IMMORTAL(ch) && MOB_FLAGGED(vict, MOB_PLSHOPKEEP)) { send_to_char("Use shopdeposit and shopwithdraw for gold transfers.\n\r", ch); return; } if (!str_cmp(currency_name_plural, arg2) || !str_cmp(currency_name, arg2)) perform_give_gold(ch, vict, amount); else { /* code to give multiple items. anyone want to write it? -je */ send_to_char("Sorry, you can't do that (yet)...\n\r", ch); return; } } else { if (!(vict = give_find_vict(ch, argument))) { send_to_char("Give what to who?\n\r", ch); return; } // cannot give normally to shopkeep mob if (!IS_IMMORTAL(ch) && MOB_FLAGGED(vict, MOB_PLSHOPKEEP)) { send_to_char("Use shopgive and shoptake for item transfers.\n\r", ch); return; } dotmode = find_all_dots(argument); if (dotmode == FIND_ALL) { if (!ch->carrying) send_to_char("You don't seem to be holding anything.\n\r", ch); else for (obj = ch->carrying; obj; obj = next_obj) { next_obj = obj->next_content; perform_give(ch, vict, obj, TRUE); } } else if (dotmode == FIND_ALLDOT) { if (!*argument) { send_to_char("All of what?\n\r", ch); return; } if (!(obj = get_obj_in_list_vis(ch, argument, ch->carrying))) { sprintf(buf, "You don't seem to have any %ss.\n\r", argument); S2C(); } else while (obj) { next_obj = get_obj_in_list_vis(ch, argument, obj->next_content); perform_give(ch, vict, obj, TRUE); obj = next_obj; } } else { if ((num = ManyObjs(argument, multarg)) != 0) { strcpy(argument, multarg); while (num) { if (!(obj = get_obj_in_list_vis(ch, argument, ch->carrying))) { SendChar(tprintf("You don't seem to have %s %s.\n\r", AN(argument), argument), ch); return; } perform_give(ch, vict, obj, TRUE); num--; } } else { if (!(obj = get_obj_in_list_vis(ch, argument, ch->carrying))) { sprintf(buf, "You don't seem to have %s %s.\n\r", AN(argument), argument); S2C(); } else perform_give(ch, vict, obj, TRUE); } } } } // *_*_*_*_*_*_*_*_*_* OLD act.obj2.c starts here *_*_*_*_*_*_*_*_* void weight_change_object(obdata *obj, int weight) { obdata *tmp_obj; chdata *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."); } } // pull the first name from an objects alias list void name_from_drinkcon(obdata *obj) { int i; char *new_name; for (i = 0; (*((obj->name) + i) != ' ') && (*((obj->name) + i) != '\0'); i++) ; if (*((obj->name) + i) == ' ') { new_name = str_dup((obj->name) + i + 1); if (GET_OBJ_RNUM(obj) < 0 || GET_OBJ_RNUM(obj) >= top_of_objt || obj->name != obj_proto[GET_OBJ_RNUM(obj)].name) free_log(obj->name, "name_from_drinkcon"); obj->name = new_name; } } // add a name to the front of the objects alias list. void name_to_drinkcon(obdata *obj, int type) { char *new_name; extern char *drinknames[]; CREATE(new_name, char, strlen(obj->name) + strlen(drinknames[type]) + 2); sprintf(new_name, "%s %s", drinknames[type], obj->name); if (GET_OBJ_RNUM(obj) < 0 || GET_OBJ_RNUM(obj) >= top_of_objt || obj->name != obj_proto[GET_OBJ_RNUM(obj)].name) free_log(obj->name, "name_to_drinkcon"); obj->name = new_name; } ACMD(do_drink) { obdata *temp; struct affected_type af; int amount = 0, weight; int on_ground = FALSE; one_argument(argument, arg); if (!*arg) { send_to_char("Drink from what?\n\r", 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 = TRUE; } if ((ITEM_TYPE(temp) != ITEM_DRINKCON) && (ITEM_TYPE(temp) != ITEM_FOUNTAIN)) { send_to_char("You can't drink from that!\n\r", ch); return; } if (on_ground && (ITEM_TYPE(temp) == ITEM_DRINKCON)) { send_to_char("You have to be holding that to drink from it.\n\r", ch); return; } if (IS_PC(ch)) if ((GET_COND(ch, DRUNK) > 10) && (GET_COND(ch, THIRST) > 0)) { send_to_char("You can't seem to get close enough to your mouth.\n\r", ch); act("$n tries to drink but misses $s mouth!", TRUE, ch, 0, 0, TO_ROOM); return; } if (IS_PC(ch)) if ((GET_COND(ch, FULL) > 20) && (GET_COND(ch, THIRST) > 0)) { send_to_char("Your stomach can't contain anymore!\n\r", ch); return; } if (!temp->value[1]) { send_to_char("It's empty.\n\r", ch); return; } if (subcmd == SCMD_DRINK) { if (temp->type_flag != ITEM_FOUNTAIN) { sprintf(buf, "$n drinks %s from $p.", drinks[temp->value[2]]); act(buf, TRUE, ch, temp, 0, TO_ROOM); } sprintf(buf, "You drink the %s.\n\r", drinks[temp->value[2]]); S2C(); if (IS_PC(ch)) if (drink_aff[temp->value[2]][DRUNK] > 0) amount = (25-GET_COND(ch, THIRST)) / drink_aff[temp->value[2]][DRUNK]; else amount = number(3, 10); } else { act("$n sips from the $o.", TRUE, ch, temp, 0, TO_ROOM); sprintf(buf, "It tastes like %s.\n\r", drinks[temp->value[2]]); S2C(); amount = 1; } amount = MIN(amount, temp->value[1]); /* You can't subtract more than the object weighs */ weight = MIN(amount, temp->weight); weight_change_object(temp, -weight); /* Subtract amount */ gain_condition(ch, DRUNK, (int)((int)drink_aff[temp->value[2]][DRUNK]*amount) / 4); gain_condition(ch, FULL, (int)((int)drink_aff[temp->value[2]][FULL]*amount) / 4); gain_condition(ch, THIRST, (int)((int)drink_aff[temp->value[2]][THIRST]*amount) / 4); if (IS_PC(ch)) if (GET_COND(ch, DRUNK) > 10) send_to_char("You feel drunk.\n\r", ch); if (IS_PC(ch)) if (GET_COND(ch, THIRST) > 20) send_to_char("You are no longer thirsty.\n\r", ch); if (IS_PC(ch)) if (GET_COND(ch, FULL) > 20) send_to_char("You are full.\n\r", ch); /* if it was poisoned ! */ if (temp->value[3]) { send_to_char("Oops, that tasted rather strange!\n\r", ch); act("$n chokes and utters some strange sounds.", TRUE, ch, 0, 0, TO_ROOM); if (!affected_by_spell(ch, SKILL_CLEANSE)) { af.type = SPELL_POISON; af.duration = amount * 3; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_POISON; af.bitvector2 = 0; affect_join(ch, &af, FALSE, FALSE); } else { act("You resist the poison!",TRUE, ch, 0, 0, TO_CHAR); act("$n resists the poison!",TRUE, ch, 0, 0, TO_ROOM); } } /* empty the container, and no longer poison. */ temp->value[1] -= amount; if (!temp->value[1]) { temp->value[2] = 0; temp->value[3] = 0; name_from_drinkcon(temp); } } ACMD(do_eat) { obdata *food; struct affected_type af; int amount; one_argument(argument, arg); if (!*arg) { send_to_char("Eat what?\n\r", ch); return; } if (!(food = get_obj_in_list_vis(ch, arg, ch->carrying))) { send_to_char("You don't seem to have any.\n\r", ch); return; } if (subcmd == SCMD_TASTE && ((ITEM_TYPE(food) == ITEM_DRINKCON) || (ITEM_TYPE(food) == ITEM_FOUNTAIN))) { do_drink(ch, argument, 0, SCMD_SIP); return; } if ((ITEM_TYPE(food) != ITEM_FOOD) && (GET_LEVEL(ch) < LEV_GOD)) { send_to_char("You can't eat THAT!\n\r", ch); return; } if (IS_PC(ch)) 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); } 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 ? food->value[0] : 1); gain_condition(ch, FULL, amount); if (IS_PC(ch)) if (GET_COND(ch, FULL) > 20) act("You are full.", FALSE, ch, 0, 0, TO_CHAR); if (food->value[3] && (GET_LEVEL(ch) < LEV_IMM)) { /* The food was poisoned ! */ send_to_char("Oops, that tasted rather strange!\n\r", ch); act("$n coughs and utters some strange sounds.", FALSE, ch, 0, 0, TO_ROOM); af.type = SPELL_POISON; af.duration = amount * 2; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF_POISON; af.bitvector2 = 0; affect_join(ch, &af, FALSE, FALSE); } if (IS_IMMORTAL(ch)) { sprintf(buf, "%s ate -> [%d] %s",GET_NAME(ch), obj_index[food->item_number].vnum, food->shdesc); mudlog(buf, NRM, GET_LEVEL(ch),TRUE); } if (subcmd == SCMD_EAT) extract_obj(food); else if (!(--food->value[0])) { send_to_char("There's nothing left now.\n\r", ch); extract_obj(food); } } ACMD(do_pour) { char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; obdata *from_obj = NULL; obdata *to_obj = NULL; int amount; 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 (from_obj->type_flag != 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?\n\r", ch); return; } if (!(to_obj = get_obj_in_list_vis(ch, arg1, ch->carrying))) { send_to_char("You can't find it!\n\r", ch); return; } if (ITEM_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 any '%s' here.\n\r", arg2); S2C(); return; } if (ITEM_TYPE(from_obj) != ITEM_FOUNTAIN) { act("You can't fill something from $p.", FALSE, ch, from_obj, 0, TO_CHAR); return; } } if (from_obj->value[1] == 0) { act("$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, -from_obj->value[1]); /* Empty */ from_obj->value[1] = 0; from_obj->value[2] = 0; from_obj->value[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 ((to_obj->type_flag != ITEM_DRINKCON) && (to_obj->type_flag != 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 ((to_obj->value[1] != 0) && (to_obj->value[2] != from_obj->value[2])) { act("There is already another liquid in it!", FALSE, ch, 0, 0, TO_CHAR); return; } if (!(to_obj->value[1] < to_obj->value[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[from_obj->value[2]], arg2); S2C(); } 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 (to_obj->value[1] == 0) name_to_drinkcon(to_obj, from_obj->value[2]); /* First same type liq. */ to_obj->value[2] = from_obj->value[2]; /* Then how much to pour */ from_obj->value[1] -= (amount = (to_obj->value[0] - to_obj->value[1])); to_obj->value[1] = to_obj->value[0]; if (from_obj->value[1] < 0) { /* There was too little */ to_obj->value[1] += from_obj->value[1]; amount += from_obj->value[1]; from_obj->value[1] = 0; from_obj->value[2] = 0; from_obj->value[3] = 0; name_from_drinkcon(from_obj); } /* Then the poison boogie */ to_obj->value[3] = (to_obj->value[3] || from_obj->value[3]); /* And the weight boogie */ weight_change_object(from_obj, -amount); weight_change_object(to_obj, amount); /* Add weight */ return; } // updated for slot revamp 5/28/98 -jtrhone void wear_message(chdata *ch, obdata *obj, int where) { char *wear_messages[][2] = { { "$n wears $p on $s head.", "You wear $p on your head." }, { "$n covers $s face with $p.", "You cover your face with $p." }, { "$n wears $p on $s right ear.", "You wear $p on your right ear." }, { "$n wears $p on $s left ear.", "You wear $p on your left ear." }, { "$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 around $s waist.", "You wear $p around your waist." }, { "$n wears $p about $s body." , "You wear $p around your body." }, { "$n wears $p on $s arms.", "You wear $p on your arms." }, { "$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 puts $p on $s hands.", "You put $p on your hands." }, { "$n slides $p onto $s right hand.", "You slide $p onto your right hand." }, { "$n slides $p onto $s right hand.", "You slide $p onto your right hand." }, { "$n slides $p onto $s left hand.", "You slide $p onto your left hand." }, { "$n slides $p onto $s left hand.", "You slide $p onto your left hand." }, { "$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 wields $p.", "You wield $p." }, { "$n grabs $p.", "You grab $p." } }; if (obj->wear_mesg && str_cmp(obj->wear_mesg, "BLANK")) act(obj->wear_mesg, TRUE, ch, obj, 0, TO_ROOM); else act(wear_messages[where][0], TRUE, ch, obj, 0, TO_ROOM); act(wear_messages[where][1], FALSE, ch, obj, 0, TO_CHAR); } // tighened up in anticipation of eq slot revamp 5/28/98 -jtrhone // and updated 5/28/98 -jtrhone BOOL perform_wear(chdata *ch, obdata *obj, int where) { extern int monk_restricts[MAX_WEAR]; int vnum = 0; int i; // what flags need to be set on obj to wear in this position int wear_bitvectors[] = { ITEM_WEAR_HEAD, ITEM_WEAR_FACE, ITEM_WEAR_EARS, ITEM_WEAR_EARS, ITEM_WEAR_NECK, ITEM_WEAR_NECK, ITEM_WEAR_BODY, ITEM_WEAR_WAIST, ITEM_WEAR_ABOUT, ITEM_WEAR_ARMS, ITEM_WEAR_WRIST, ITEM_WEAR_WRIST, ITEM_WEAR_HANDS, ITEM_WEAR_FINGER, ITEM_WEAR_FINGER, ITEM_WEAR_FINGER, ITEM_WEAR_FINGER, ITEM_WEAR_LEGS, ITEM_WEAR_FEET, ITEM_WIELD, ITEM_TAKE }; // updated to support wvectors char *already_wearing[] = { "You're already wearing something on your head.\n\r", "You're already wearing something on your face.\n\r", "You're already wearing something on both of your ears.\n\r", "You're already wearing something on both of your ears.\n\r", "You can't wear anything else around your neck.\n\r", "You can't wear anything else around your neck.\n\r", "You're already wearing something on your body.\n\r", "You already have something around your waist.\n\r", "You're already wearing something about your body.\n\r", "You're already wearing something on your arms.\n\r", "You're already wearing something around both of your wrists.\n\r", "You're already wearing something around both of your wrists.\n\r", "You're already wearing something on your hands.\n\r", "Your fingers are full of rings.\n\r", "Your fingers are full of rings.\n\r", "Your fingers are full of rings.\n\r", "Your fingers are full of rings.\n\r", "You're already wearing something on your legs.\n\r", "You're already wearing something on your feet.\n\r", "You're already wielding a weapon.\n\r", "You already have something in your offhand.\n\r" }; /* first, make sure that the object can be worn there*/ if (!CAN_WEAR(obj, wear_bitvectors[where])) { act("You can't wear $p there.", FALSE, ch, obj, 0, TO_CHAR); return FALSE; } /* CHECK TO SEE IF OBJECT IS VALID OBJECT FROM AN OPEN ZONE >> ROA */ vnum = GET_OBJ_VNUM(obj); if (GET_LEVEL(ch) < LEV_IMM && IS_PC(ch)) if (!vnum || ZONE_FLAGGED((vnum/100), Z_CLOSED)) { send_to_char("That object is an %6INVALID%0 object.\n\r",ch); send_to_char("Please note where and how you got it and immediatly\n\r",ch); send_to_char("report it to a GOD+... Thanx.\n\r",ch); sprintf(buf, "%s has an INVALID object: [%d] %s", GET_NAME(ch), vnum, obj->shdesc); mudlog(buf, BRF, LEV_IMM, TRUE); return FALSE; } // updated to support wvectors 5/28/98 -jtrhone /* for neck, ear, and wrist, try pos 2 if pos 1 is already full */ switch (where) { case W_EAR_R: case W_NECK_1: case W_WRIST_R: if (EQ(ch, where) || WV_FLAGGED(ch, (1 << where))) where++; default: break; } // for rings now, scan for empty slot if (where == W_FINGER_R1 && (EQ(ch, where) || WV_FLAGGED(ch, (1 << where)))) if (EQ(ch, ++where) || WV_FLAGGED(ch, (1 << where))) // FINGER_R2 if (EQ(ch, ++where) || WV_FLAGGED(ch, (1 << where))) // FINGER_L1 where++; // cannot where if already something there if (EQ(ch, where) || WV_FLAGGED(ch, (1 << where))) { send_to_char(already_wearing[where], ch); return FALSE; } // also check wvflags on object to see if char has something there... for (i = 0; i < MAX_WEAR; i++) if (WV_FLAGGED(obj, (1 << i)) && (EQ(ch, i) || WV_FLAGGED(ch, (1 << i)))) { send_to_char(already_wearing[i], ch); return FALSE; } /* check level for object ROA James Rhone */ if (GET_LEVEL(ch) < obj->min_level) { send_to_char("That object is too powerful for you to use.\n\r",ch); return FALSE; } /* lets check restricts on monshai -roa */ if (IS_NAT_MONK(ch) && !IS_IMMORTAL(ch)) if (GET_LEVEL(ch) >= monk_restricts[where]) { send_to_char("You, Monshai, are not allowed to do such.\n\r",ch); return FALSE; } if (IS_NAT_MONK(ch) && !IS_IMMORTAL(ch) && ITEM_TYPE(obj) == ITEM_WEAPON && where == W_HOLD) { send_to_char("You, Monshai, are not allowed to do such.\n\r",ch); return FALSE; } wear_message(ch, obj, where); obj_from_char(obj); // equip_char will set wvector flags on char... if (equip_char(ch, obj, where, TRUE)) { // only light if in held spot... 6/4/98 -jtrhone if (obj == EQ(ch, W_HOLD) && OBJ_LIGHT(obj) && LIGHT_TIME(obj)) do_light(ch, "", 0, 0); return TRUE; } else return FALSE; } int find_eq_pos(chdata *ch, obdata *obj, char *arg) { int where = -1; static char *keywords[] = { "head", "face", "ear", "!RESERVED!", "neck", "!RESERVED!", "body", "waist", "about", "arms", "wrist", "!RESERVED!", "hands", "finger", "!RESERVED!", "!RESERVED!", "!RESERVED!", "legs", "feet", "!RESERVED!", "!RESERVED!", "\n" }; // if they didnt supply an argument, pick a best fit if (!arg || !*arg) { if (CAN_WEAR(obj, ITEM_WEAR_HEAD)) where = W_HEAD; if (CAN_WEAR(obj, ITEM_WEAR_FACE)) where = W_FACE; if (CAN_WEAR(obj, ITEM_WEAR_EARS)) where = W_EAR_R; if (CAN_WEAR(obj, ITEM_WEAR_NECK)) where = W_NECK_1; if (CAN_WEAR(obj, ITEM_WEAR_BODY)) where = W_BODY; if (CAN_WEAR(obj, ITEM_WEAR_WAIST)) where = W_WAIST; if (CAN_WEAR(obj, ITEM_WEAR_ABOUT)) where = W_ABOUT; if (CAN_WEAR(obj, ITEM_WEAR_ARMS)) where = W_ARMS; if (CAN_WEAR(obj, ITEM_WEAR_WRIST)) where = W_WRIST_R; if (CAN_WEAR(obj, ITEM_WEAR_HANDS)) where = W_HANDS; if (CAN_WEAR(obj, ITEM_WEAR_FINGER)) where = W_FINGER_R1; if (CAN_WEAR(obj, ITEM_WEAR_LEGS)) where = W_LEGS; if (CAN_WEAR(obj, ITEM_WEAR_FEET)) where = W_FEET; } else if ((where = search_block(arg, keywords, FALSE)) < 0) { sprintf(buf, "'%s'? What part of your body is THAT?\n\r", arg); S2C(); } return where; } // tighened up in anticipation of eq slot revamp 5/28/98 -jtrhone ACMD(do_wear) { char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; obdata *obj, *next_obj; int where, dotmode, items_worn = 0; two_arguments(argument, arg1, arg2); if (!*arg1) { send_to_char("Wear what?\n\r", 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!\n\r", ch); return; } if (dotmode == FIND_ALL) { for (obj = ch->carrying; obj; obj = next_obj) { next_obj = obj->next_content; if ((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.\n\r", ch); } else if (dotmode == FIND_ALLDOT) { if (!*arg1) { send_to_char("Wear all of what?\n\r", ch); return; } if (!(obj = get_obj_in_list_vis(ch, arg1, ch->carrying))) { sprintf(buf, "You don't seem to have any %ss.\n\r", arg1); S2C(); } 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.\n\r", AN(arg1), arg1); S2C(); } 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); } } } // tighened up in anticipation of eq slot revamp 5/28/98 -jtrhone ACMD(do_wield) { obdata *obj; one_argument(argument, arg); if (!*arg) { send_to_char("Wield what?\n\r", ch); return; } if (!(obj = get_obj_in_list(arg, ch->carrying))) { sprintf(buf, "You don't seem to have %s %s.\n\r", AN(arg), arg); S2C(); return; } if (!CAN_WEAR(obj, ITEM_WIELD)) send_to_char("You can't wield that.\n\r", ch); else if (GET_OBJ_WEIGHT(obj) > str_app[TRUE_STRENGTH(ch)].wield_w) send_to_char("It's too heavy for you to use.\n\r", ch); else perform_wear(ch, obj, W_WIELD); } // tighened up in anticipation of eq slot revamp 5/28/98 -jtrhone ACMD(do_grab) { obdata *obj; one_argument(argument, arg); if (!*arg) { send_to_char("Hold what?\n\r", ch); return; } if (!(obj = get_obj_in_list(arg, ch->carrying))) { sprintf(buf, "You don't seem to have %s %s.\n\r", AN(arg), arg); S2C(); return; } if (CAN_WEAR(obj, ITEM_HOLD) || (IS_THIEF(ch) && OBJ_FLAGGED(obj, ITEM_THIEF_HOLD))) { if (!CAN_WEAR(obj, ITEM_HOLD)) { sprintf(buf, "You use %s as a secondary weapon.\n\r",obj->shdesc); S2C(); } perform_wear(ch, obj, W_HOLD); } else send_to_char("That item may not be held in an offhand.\n\r",ch); } // remove a particular object from ch inventory... updated to deal with poisons/thieves // 4/17/98 -jtrhone void perform_remove(chdata *ch, int pos) { obdata *obj; if (!(obj = EQ(ch, pos))) { log("Error in perform_remove: bad pos passed."); return; } if (IS_CARRYING_N(ch) >= CAN_CARRY_N(ch)) act("$p: your inventory is too full!", FALSE, ch, obj, 0, TO_CHAR); else { // if they remove their instrument, they cant play anymore... if (OBJ_FLAGGED(obj, ITEM_INSTRUM) && PLAYING(ch)) do_finish(ch, " tune", 0, 0); // if they remove their poison, they have to stop brewing if (pos == W_HOLD && IS_LIQCONT(obj) && affected_by_spell(ch, SKILL_BREW)) affect_from_char(ch, SKILL_BREW); act("You stop using $p.", FALSE, ch, obj, 0, TO_CHAR); if (obj->rem_mesg && str_cmp(obj->rem_mesg, "BLANK")) act(obj->rem_mesg, TRUE, ch, obj, 0, TO_ROOM); else act("$n stops using $p.", TRUE, ch, obj, 0, TO_ROOM); obj_to_char(unequip_char(ch, pos, TRUE), ch); } } // former do_remove, now do_unqeuip 4/14/98 -jtrhone ACMD(do_unequip) { obdata *obj; int i, dotmode, found; one_argument(argument, arg); if (!*arg) { send_to_char("Unequip what?\n\r", ch); return; } dotmode = find_all_dots(arg); if (dotmode == FIND_ALL) { found = 0; for (i = 0; i < MAX_WEAR; i++) if (EQ(ch, i)) { perform_remove(ch, i); found = 1; } if (!found) send_to_char("You're not using anything.\n\r", ch); } else if (dotmode == FIND_ALLDOT) { if (!*arg) send_to_char("Unequip all of what?\n\r", ch); else { found = 0; for (i = 0; i < MAX_WEAR; i++) if (EQ(ch, i) && CAN_SEE_OBJ(ch, EQ(ch, i)) && isname(arg, EQ(ch, i)->name)) { perform_remove(ch, i); found = 1; } if (!found) { sprintf(buf, "You don't seem to be using any %ss.\n\r", arg); S2C(); } } } else { if (!(obj = get_object_in_equip_vis(ch, arg, ch->equipment, &i))) { sprintf(buf, "You don't seem to be using %s %s.\n\r", AN(arg), arg); S2C(); } else perform_remove(ch, i); } } ACMD(do_throw) { int num, size, plus, dam, wasin, toroom, dir; chdata *victim; obdata *obj; char *argu = argument; char dirstr[MAX_INPUT_LENGTH], tarstr[MAX_INPUT_LENGTH]; BOOL same_room = FALSE; extern int successful_hit(chdata *ch, chdata *vict); extern int spell_adjust_damage(chdata *vict, int dam); if (!(obj = EQ(ch, W_WIELD))) { send_to_char("You must be wielding something first!\n\r",ch); return; } if (!THROWABLE(obj)) { act("Unfortunately, you cannot throw $p.",FALSE,ch,obj,0,TO_CHAR); return; } skip_spaces(&argu); if (!*argu) { act("Usage: throw <direction> <target>.",FALSE,ch,0,0,TO_CHAR); return; } if (strlen(argu) >= MAX_INPUT_LENGTH) { act("Argument too long, please rephrase.",FALSE,ch,0,0,TO_CHAR); return; } half_chop(argu, dirstr, tarstr); if (!*tarstr) { // could mean to throw it at target in room -roa if (!(victim = get_char_room_vis(ch, dirstr))) { act("Usage: throw <direction> <target>.",FALSE,ch,0,0,TO_CHAR); act(" throw <target>.",FALSE,ch,0,0,TO_CHAR); return; } else same_room = TRUE; } if (!same_room) { dir = search_block(dirstr, comm_dirs, FALSE); if (dir < 0 || dir > NUM_OF_DIRS) { act("Usage: throw <direction> <target>.",FALSE,ch,0,0,TO_CHAR); return; } if (!EXIT(ch, dir) || EXIT(ch, dir)->to_room <= NOWHERE || EXIT_CLOSED(EXIT(ch, dir))) { act("You cannot throw anything in that direction.",FALSE,ch,0,0,TO_CHAR); return; } toroom = EXIT(ch, dir)->to_room; wasin = ch->in_room; char_from_room(ch); char_to_room(ch, toroom); victim = get_char_room_vis(ch, tarstr); char_from_room(ch); char_to_room(ch, wasin); if (!victim) { act("Throw at whom?",FALSE,ch,0,0,TO_CHAR); return; } } if (!check_mortal_combat(ch, victim)) return; if (!check_truce(ch, victim)) return; if (MOB_FLAGGED(victim, MOB_MEMORY)) remember(victim, ch); if (IS_NPC(victim)) HUNTING(victim) = ch; num = obj->throw_numdam; size = obj->throw_sizedam; plus = obj->throw_plusdam; num = MAX(1, num); size = MAX(1, size); plus = MAX(0, plus); dam = dice(num, size) + plus; dam = spell_adjust_damage(victim, dam); if (!same_room) { // send messages to both rooms sprintf(buf, "$n throws $p %s at $N.",dirs[dir]); act(buf,TRUE,ch,obj,victim,TO_ROOM); sprintf(buf, "You throw $p %s at $N.",dirs[dir]); act(buf,TRUE,ch,obj,victim,TO_CHAR); } else { act("You throw $p at $N!",TRUE,ch,obj,victim,TO_CHAR); act("$n throws $p at $N!",TRUE,ch,obj,victim,TO_ROOM); } obj = unequip_char(ch, W_WIELD, FALSE); if (successful_hit(ch, victim)) { obj_to_char(obj, victim); act("$p hits $N!",TRUE,ch,obj,victim,TO_NOTVICT); if (!same_room) { sprintf(buf, "$n gets hit by $p from %s!", rev_dir_str[dir]); act(buf, TRUE,victim,obj,0,TO_ROOM); sprintf(buf, "You get hit by $p from %s!", rev_dir_str[dir]); act(buf, TRUE,victim,obj,0,TO_CHAR); } else { act("$n hits you with $p!",TRUE,ch,obj,victim,TO_VICT); } GET_HIT(victim) -= dam; update_pos(victim); if (GET_POS(victim) == POS_DEAD) die(victim, FALSE); } else { if (!same_room) { obj_to_room(obj, toroom); sprintf(buf, "$p flies by $n from %s!", rev_dir_str[dir]); act(buf, TRUE,victim,obj,0,TO_ROOM); sprintf(buf, "$p flies by you from %s!", rev_dir_str[dir]); act(buf, TRUE,victim,obj,0,TO_CHAR); } else { obj_to_room(obj, ch->in_room); act("$p misses $N!",TRUE,ch,obj,victim,TO_NOTVICT); } } }