/************************************************************************
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);
}
}
}