/*************************************************************************** * Emud 2.2 by Igor van den Hoven, Michiel Lange, and Martin Bethlehem. * * * * MrMud 1.4 by David Bills and Dug Michael. * * * * Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * Original Diku Mud copyright (C) 1990 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeld, Tom Madsen, and Katje Nyboe. * ***************************************************************************/ #include "emud.h" #include <math.h> /* Local functions. */ bool get_obj args( ( CHAR_DATA *ch, OBJ_DATA *obj, OBJ_DATA *container, bool fDisplay ) ); bool put_obj args( ( CHAR_DATA *ch, OBJ_DATA *obj, OBJ_DATA *container, bool fDisplay ) ); bool drop_obj args( ( CHAR_DATA *ch, OBJ_DATA *obj, OBJ_DATA *container, bool fDisplay ) ); bool sacrifice_obj args( ( CHAR_DATA *ch, OBJ_DATA *obj, OBJ_DATA *container, bool fDisplay ) ); int get_cost args( ( CHAR_DATA *keeper, OBJ_DATA *obj, bool fBuy ) ); OBJ_DATA * find_char_corpse args( ( CHAR_DATA *ch, bool ) ); /* Determines if ch can wear an object based on class - Scandum 06-07-2002 */ bool class_allowed(OBJ_DATA *obj, CHAR_DATA *ch, bool fDisplay) { bool forbidden = FALSE; push_call("class_allowed(%p,%p,%p)",obj,ch,fDisplay); if (obj->pIndexData->class_flags == 0) { pop_call(); return TRUE; } switch (ch->class) { case CLASS_WARRIOR: forbidden = !IS_SET(obj->pIndexData->class_flags, FLAG_CLASS_WARRIOR); break; case CLASS_GLADIATOR: forbidden = !IS_SET(obj->pIndexData->class_flags, FLAG_CLASS_GLADIATOR); break; case CLASS_MARAUDER: forbidden = !IS_SET(obj->pIndexData->class_flags, FLAG_CLASS_MARAUDER); break; case CLASS_NINJA: forbidden = !IS_SET(obj->pIndexData->class_flags, FLAG_CLASS_NINJA); break; case CLASS_DRUID: forbidden = !IS_SET(obj->pIndexData->class_flags, FLAG_CLASS_DRUID); break; case CLASS_SORCERER: forbidden = !IS_SET(obj->pIndexData->class_flags, FLAG_CLASS_SORCERER); break; case CLASS_SHAMAN: forbidden = !IS_SET(obj->pIndexData->class_flags, FLAG_CLASS_SHAMAN); break; case CLASS_WARLOCK: forbidden = !IS_SET(obj->pIndexData->class_flags, FLAG_CLASS_WARLOCK); break; } if (forbidden) { if (fDisplay) { act("You are of the wrong class to use $p.", ch, obj, NULL, TO_CHAR); } pop_call(); return FALSE; } pop_call(); return TRUE; } bool could_dual( CHAR_DATA *ch ) { push_call("could_dual(%p)",ch); if (learned(ch, gsn_dual_wield)) { pop_call(); return TRUE; } if (rspec_req(ch, RSPEC_MULTI_ARMS)) { pop_call(); return TRUE; } pop_call(); return FALSE; } bool can_dual( CHAR_DATA *ch ) { push_call("can_dual(%p)",ch); if (!could_dual(ch)) { pop_call(); return FALSE; } if (get_eq_char(ch, WEAR_DUAL_WIELD)) { send_to_char( "You are already wielding two weapons!\n\r", ch ); pop_call(); return FALSE; } if (rspec_req(ch, RSPEC_MULTI_ARMS) || ch->race == RACE_KRAKEN) { pop_call(); return TRUE; } if (get_eq_char(ch, WEAR_SHIELD)) { send_to_char( "You cannot dual wield while holding a shield!\n\r", ch ); pop_call(); return FALSE; } if (get_eq_char(ch, WEAR_HOLD)) { send_to_char( "You cannot dual wield while holding something!\n\r", ch ); pop_call(); return FALSE; } pop_call(); return TRUE; } int count_total_objects( OBJ_DATA *container ) { int count; OBJ_DATA *obj; push_call("count_total_objects(%p)",container); for (count = 0, obj = container->first_content ; obj ; obj = obj->next_content) { count++; } pop_call(); return( count ); } int reinc_eq_level( CHAR_DATA *ch ) { if (IS_NPC(ch) || ch->pcdata->reincarnation == 0) { return ch->level; } return (ch->level * (1.0 + UMIN(10, ch->pcdata->reincarnation) * 0.058)); } int obj_eq_level( CHAR_DATA *ch, OBJ_DATA *obj ) { if (IS_NPC(ch) || ch->pcdata->reincarnation == 0) { return obj->level; } return ceilf(obj->level / (1.0 + UMIN(10, ch->pcdata->reincarnation) * 0.058)); } bool get_obj( CHAR_DATA *ch, OBJ_DATA *obj, OBJ_DATA *container, bool fDisplay ) { CHAR_DATA *rch; push_call("get_obj(%p,%p,%p,%p)",ch,obj,container,fDisplay); if (!IS_SET(obj->wear_flags, ITEM_TAKE)) { if (fDisplay) { send_to_char( "You cannot take that.\n\r", ch ); } pop_call(); return FALSE; } if (obj->item_type == ITEM_FURNITURE) { for (rch = ch->in_room->first_person ; rch ; rch = rch->next_in_room) { if (rch->furniture == obj) { if (fDisplay) { act("$N seems to be using $p", ch, obj, rch, TO_CHAR); } pop_call(); return FALSE; } } } if (ch->carry_number >= can_carry_n(ch)) { if (fDisplay) { act("You cannot carry that many items.", ch, NULL, NULL, TO_CHAR); } pop_call(); return FALSE; } if (container == NULL || container->carried_by != ch) { if (!IS_IMMORTAL(ch)) { if (ch->carry_weight + get_obj_weight(obj) > can_carry_w(ch)) { if (fDisplay) { act( "You cannot carry that much weight.", ch, NULL, NULL, TO_CHAR); } pop_call(); return FALSE; } } } obj_to_char(obj, ch); if (fDisplay) { if (container) { act( "You get $p from $P.", ch, obj, container, TO_CHAR ); act( "$n gets $p from $P.", ch, obj, container, TO_ROOM ); } else { act( "You get $p.", ch, obj, container, TO_CHAR ); act( "$n gets $p.", ch, obj, container, TO_ROOM ); } } if (!IS_NPC(ch) && IS_SET(obj->pIndexData->progtypes, TRIG_GET)) { OBJ_PROG *prg; for (prg = obj->pIndexData->first_prog ; prg ; prg = prg->next) { if (prg->trigger == TRIG_GET && number_percent() <= prg->percentage) { start_object_program( ch, obj, prg, ""); } } } if (obj && obj->item_type == ITEM_MONEY) { give_gold(ch, obj->value[0]); junk_obj(obj); } pop_call(); return TRUE; } bool put_obj( CHAR_DATA *ch, OBJ_DATA *obj, OBJ_DATA *container, bool fDisplay ) { push_call("put_obj(%p,%p,%p,%p)",ch,obj,container,fDisplay); if (obj == container) { if (fDisplay) { send_to_char( "You cannot fold it into itself.\n\r", ch ); } pop_call(); return FALSE; } if (!can_drop_obj(ch, obj)) { if (fDisplay) { send_to_char( "You cannot let go of it.\n\r", ch ); } pop_call(); return FALSE; } if (get_obj_weight(obj) + container->content_weight > container->value[0]) { if (fDisplay) { send_to_char( "It won't fit.\n\r", ch); } pop_call(); return FALSE; } if (count_total_objects(container) >= (container->value[3] ? container->value[3] : MAX_OBJECTS_IN_CONTAINER)) { if (fDisplay) { send_to_char( "There are too many items there already.\n\r", ch); } pop_call(); return FALSE; } if (obj->item_type == ITEM_CONTAINER) { if (fDisplay) { send_to_char( "You cannot put a container in a container.\n\r", ch); } pop_call(); return FALSE; } if (!IS_NPC(ch) && obj_eq_level(ch, container) - 5 > ch->level && container->in_room == NULL) { if (fDisplay) { ch_printf(ch, "You must be level %d to use this container.\n\r", obj_eq_level(ch, container) - 5); } pop_call(); return FALSE; } obj_to_obj( obj, container ); if (fDisplay) { act( "You put $p in $P.", ch, obj, container, TO_CHAR ); act( "$n puts $p in $P.", ch, obj, container, TO_ROOM ); } pop_call(); return TRUE; } bool drop_obj( CHAR_DATA *ch, OBJ_DATA *obj, OBJ_DATA *container, bool fDisplay ) { push_call("drop_obj(%p,%p,%p,%p)",ch,obj,container,fDisplay); if (!can_drop_obj(ch, obj)) { if (fDisplay) { send_to_char( "You cannot let go of it.\n\r", ch ); } pop_call(); return FALSE; } obj->sac_timer = OBJ_SAC_TIME; if (fDisplay) { act( "You drop $p.", ch, obj, NULL, TO_CHAR ); act( "$n drops $p.", ch, obj, NULL, TO_ROOM ); } obj_to_room( obj, ch->in_room->vnum ); if (!IS_NPC(ch) && IS_SET(obj->pIndexData->progtypes, TRIG_DROP)) { OBJ_PROG *prg; for (prg = obj->pIndexData->first_prog ; prg ; prg = prg->next) { if (prg->trigger == TRIG_DROP && number_percent() <= prg->percentage) { start_object_program( ch, obj, prg, ""); } } } pop_call(); return TRUE; } bool sacrifice_obj( CHAR_DATA *ch, OBJ_DATA *obj, OBJ_DATA *container, bool fDisplay ) { CHAR_DATA *rch; push_call("sacrifice_obj(%p,%p,%p,%p)",ch,obj,container,fDisplay); if (!IS_SET(obj->wear_flags, ITEM_TAKE)) { if (fDisplay) { act( "$p is not an acceptable sacrifice.", ch, obj, NULL, TO_CHAR); } pop_call(); return FALSE; } if (obj->item_type == ITEM_CORPSE_PC) { if (IS_NPC(ch) || ch->pcdata->pvnum != obj->owned_by) { if (fDisplay) { act("$p is not yours to sacrifice.", ch, obj, NULL, TO_CHAR); } pop_call(); return FALSE; } } if (obj->item_type == ITEM_FURNITURE) { for (rch = ch->in_room->first_person ; rch ; rch = rch->next_in_room) { if (rch->furniture == obj) { break; } } if (rch) { if (fDisplay) { act("$N seems to be using $p", ch, obj, rch, TO_CHAR); } pop_call(); return FALSE; } } give_gold(ch, obj->cost / 100 + 1); ch_printf(ch, "%s give%s you %d gold coin%s for %s.\n\r", capitalize(get_god_name(which_god(ch))), which_god(ch) ? "s" : "", obj->cost/100+1, (obj->cost/100+1) != 1 ? "s" : "", obj->short_descr); act("$n sacrifices $p to $T.", ch, obj, get_god_name(which_god(ch)), TO_ROOM); if (!IS_NPC(ch) && IS_SET(obj->pIndexData->progtypes, TRIG_SACRIFICE)) { OBJ_PROG *prg; for (prg = obj->pIndexData->first_prog ; prg ; prg = prg->next) { if (prg->trigger == TRIG_SACRIFICE && number_percent() <= prg->percentage) { start_object_program( ch, obj, prg, ""); } } } if (obj->first_content) { while (obj->first_content) { obj->first_content->sac_timer = OBJ_SAC_TIME; for (rch = ch->in_room->first_person ; rch ; rch = rch->next_in_room) { if (IS_NPC(rch) || !IS_SET(rch->act, PLR_QUIET)) { act(" $p falls out onto the floor.", rch, obj->first_content, NULL, TO_CHAR); } } obj_to_room(obj->first_content, ch->in_room->vnum); } } if (!IS_NPC(ch) && obj == ch->pcdata->corpse) { ch->pcdata->corpse = find_char_corpse(ch, TRUE); } junk_obj(obj); pop_call(); return TRUE; } void corpse_loot( CHAR_DATA *ch ) { push_call("corpse_loot(%p)",ch); while (ch->pcdata->corpse->first_content) { obj_to_char(ch->pcdata->corpse->first_content, ch); } act( "You get everything from $p.",ch, ch->pcdata->corpse, NULL, TO_CHAR ); act( "$n gets everything from $p.",ch, ch->pcdata->corpse, NULL, TO_ROOM ); junk_obj(ch->pcdata->corpse); ch->pcdata->corpse = find_char_corpse(ch, TRUE); save_char_obj(ch, NORMAL_SAVE); pop_call(); return; } void do_get( CHAR_DATA *ch, char *argument ) { char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; char buf1[MAX_INPUT_LENGTH]; char buf2[MAX_INPUT_LENGTH]; OBJ_DATA *obj = NULL; OBJ_DATA *obj_next = NULL; OBJ_DATA *container = NULL; OBJ_DATA *found_obj = NULL; bool clutter = FALSE; bool shrtd = FALSE; int amount = 1; int cnt = 0; int cnt_not_got = 0; int split = 0; push_call("do_get(%p,%p)",ch,argument); if (!check_blind(ch)) { pop_call(); return; } /* special approach for player corpses. */ if (!IS_NPC(ch) && ch->pcdata->corpse && ch->in_room->vnum == ch->pcdata->corpse_room) { corpse_loot(ch); pop_call(); return; } if (argument == NULL) { argument = "all npc_corpse"; split = UMAX(1, ch->gold); } if (*argument == 0) { send_to_char("Get what?\n\r", ch); pop_call(); return; } argument = one_argument( argument, arg1 ); if (is_number(arg1)) { amount = UMAX(1, atol(arg1)); argument = one_argument( argument, arg1 ); } argument = one_argument( argument, arg2 ); if (arg2[0] == '\0') { if (!IS_NPC(ch) && ch->fighting != NULL) { send_to_char( "You are too busy to pick anything up.\n\r", ch ); pop_call(); return; } if (strcasecmp(arg1, "all") && str_prefix("all.", arg1)) { if ((obj = get_obj_list(ch, arg1, ch->in_room->first_content)) == NULL) { act("You see no $T here.", ch, NULL, short_to_name(arg1, amount), TO_CHAR); pop_call(); return; } if (amount == 1) { get_obj(ch, obj, NULL, TRUE); pop_call(); return; } for ( ; shrtd <= 1 && !found_obj ; shrtd++) { for (obj = ch->in_room->first_content ; obj ; obj = obj_next) { obj_next = obj->next_content; if (!can_see_obj(ch, obj) || !IS_SET(obj->wear_flags, ITEM_TAKE)) { continue; } if (!shrtd && !is_name(arg1, obj->name)) { continue; } if (shrtd && !is_name_short(arg1, obj->name)) { continue; } if (found_obj == NULL) { found_obj = obj; } if (obj->short_descr != found_obj->short_descr) { continue; } if (get_obj(ch, obj, NULL, FALSE)) { cnt++; } else { cnt_not_got++; } if (cnt >= amount) { break; } } } if (found_obj) { sprintf(buf1, "You get %d %s.", cnt, short_to_name(found_obj->short_descr, cnt)); sprintf(buf2, "$n gets %d %s.", cnt, short_to_name(found_obj->short_descr, cnt)); act(buf1, ch, found_obj, NULL, TO_CHAR); act(buf2, ch, found_obj, NULL, TO_ROOM); } else { do_get(ch, arg1); } } else { /* 'get all' or 'get all.object' */ for ( ; shrtd <= 1 && !found_obj ; shrtd++) { for (obj = ch->in_room->first_content ; obj ; obj = obj_next) { obj_next = obj->next_content; if (!can_see_obj(ch, obj) || !IS_SET(obj->wear_flags, ITEM_TAKE)) { continue; } if (!shrtd && arg1[3] && !is_name(&arg1[4], obj->name)) { continue; } if (shrtd && arg1[3] && !is_name_short(&arg1[4], obj->name)) { continue; } if (found_obj == NULL) { found_obj = obj; } if (obj->short_descr != found_obj->short_descr) { clutter = TRUE; } if (get_obj(ch, obj, NULL, FALSE)) { cnt++; } else { cnt_not_got++; } } } if (found_obj == NULL) { if (arg1[3] == '\0') { send_to_char( "You see nothing here.\n\r", ch ); } else { act( "You see no $T here.", ch, NULL, short_to_name(&arg1[4], 0), TO_CHAR ); } } else { if (cnt_not_got > 0) { if (arg1[3] == '\0' || clutter) { ch_printf(ch, "You get all but %d of the items.\n\r", cnt_not_got); act("$n gets some items.", ch, NULL, NULL, TO_ROOM); } else { sprintf(buf1, "You get %d %s.", cnt, short_to_name(found_obj->short_descr, cnt)); sprintf(buf2, "$n gets %d %s.", cnt, short_to_name(found_obj->short_descr, cnt)); act(buf1, ch, found_obj, NULL, TO_CHAR); act(buf2, ch, found_obj, NULL, TO_ROOM); } } else { if (clutter) { if (arg1[3] == '\0') { act( "You get everything in the room.", ch, NULL, NULL, TO_CHAR); act( "$n gets everything in the room.", ch, NULL, NULL, TO_ROOM); } else { act("You get all the $T in the room.", ch, NULL, short_to_name(&arg1[4], cnt), TO_CHAR); act("$n gets all the $T in the room.", ch, NULL, short_to_name(&arg1[4], cnt), TO_ROOM); } } else { sprintf(buf1, "You get every %s in the room.", short_to_name(found_obj->short_descr, 1)); sprintf(buf2, "$n gets every %s in the room.", short_to_name(found_obj->short_descr, 1)); act(buf1, ch, found_obj, NULL, TO_CHAR); act(buf2, ch, found_obj, NULL, TO_ROOM); } } } } pop_call(); return; } else { /* "get <all|all.object|item> container" */ if ((container = get_obj_here(ch, arg2)) == NULL) { act( "You see no $T here.", ch, NULL, arg2, TO_CHAR ); pop_call(); return; } if (container->carried_by == NULL && !IS_NPC(ch) && ch->fighting != NULL) { send_to_char( "You are too busy to pick anything up.\n\r", ch ); pop_call(); return; } switch (container->item_type) { case ITEM_CONTAINER: break; case ITEM_CORPSE_NPC: if (container->owned_by && !pvnum_in_group(ch, container->owned_by)) { send_to_char( "You have no right to those items!\n\r", ch); pop_call(); return; } break; case ITEM_CORPSE_PC: if (IS_NPC(ch) || container->owned_by != ch->pcdata->pvnum) { send_to_char( "You have no right to those items.\n\r", ch ); pop_call(); return; } break; default: send_to_char( "That's not a container.\n\r", ch ); pop_call(); return; } if (IS_SET(container->value[1], CONT_CLOSED)) { act( "$p is closed.", ch, container, NULL, TO_CHAR ); pop_call(); return; } if (strcasecmp(arg1, "all") && str_prefix("all.", arg1)) { /* "get object container" */ if ((obj = get_obj_list(ch, arg1, container->first_content)) == NULL) { act("You see nothing like that in $p.", ch, container, NULL, TO_CHAR); pop_call(); return; } if (amount == 1) { get_obj(ch, obj, container, TRUE); pop_call(); return; } for ( ; shrtd <= 1 && !found_obj ; shrtd++) { for (obj = container->first_content ; obj ; obj = obj_next) { obj_next = obj->next_content; if (!can_see_obj(ch, obj) || !IS_SET(obj->wear_flags, ITEM_TAKE)) { continue; } if (!shrtd && !is_name(arg1, obj->name)) { continue; } if (shrtd && !is_name_short(arg1, obj->name)) { continue; } if (found_obj == NULL) { found_obj = obj; } if (obj->short_descr != found_obj->short_descr) { continue; } if (get_obj(ch, obj, container, FALSE)) { cnt++; } else { cnt_not_got++; } if (cnt >= amount) { break; } } } if (found_obj) { sprintf(buf1, "You get %d %s from $p.", cnt, short_to_name(found_obj->short_descr, cnt)); sprintf(buf2, "$n gets %d %s from $p", cnt, short_to_name(found_obj->short_descr, cnt)); act(buf1, ch, container, NULL, TO_CHAR); act(buf2, ch, container, NULL, TO_ROOM); } else { cat_sprintf(arg1, " %s", arg2); do_get(ch, arg1); } } else { /* "get all container" or "get all.object container" */ for ( ; shrtd <= 1 && !found_obj ; shrtd++) { for (obj = container->first_content ; obj ; obj = obj_next) { obj_next = obj->next_content; if (!can_see_obj(ch, obj) || !IS_SET(obj->wear_flags, ITEM_TAKE)) { continue; } if (!shrtd && arg1[3] && !is_name(&arg1[4], obj->name)) { continue; } if (shrtd && arg1[3] && !is_name_short(&arg1[4], obj->name)) { continue; } if (split) { if (!IS_SET(ch->act, PLR_AUTOLOOT) && obj->item_type != ITEM_MONEY) { continue; } } if (found_obj == NULL) { found_obj = obj; } if (obj->short_descr != found_obj->short_descr) { clutter = TRUE; } if (get_obj(ch, obj, container, FALSE)) { cnt++; } else { cnt_not_got++; } } } if (found_obj == NULL) { if (!split) { if (arg1[3] == '\0') { act( "You see nothing in $p.", ch, container, NULL, TO_CHAR ); } else { act("You see nothing like that in $p.", ch, container, NULL, TO_CHAR ); } } } else { if (cnt_not_got) { if (arg1[3] == '\0' || clutter) { ch_printf(ch, "You get all but %d of the items from %s.\n\r", cnt_not_got, container->short_descr); act("$n gets some items from $p.",ch,container,NULL,TO_ROOM); } else { sprintf(buf1, "You get %d %s from $p.", cnt, short_to_name(found_obj->short_descr, cnt)); sprintf(buf2, "$n gets %d %s from $p.", cnt, short_to_name(found_obj->short_descr, cnt)); act(buf1, ch, container, NULL, TO_CHAR); act(buf2, ch, container, NULL, TO_ROOM); } } else if (split && cnt == 1) { sprintf(buf1, "You get %s from $p.", found_obj->short_descr); sprintf(buf2, "$n gets %s from $p.", found_obj->short_descr); act(buf1, ch, container, NULL, TO_CHAR); act(buf2, ch, container, NULL, TO_ROOM); } else if (clutter) { if (arg1[3] == '\0') { act( "You get everything from $p.",ch, container, NULL, TO_CHAR ); act( "$n gets everything from $p.",ch, container, NULL, TO_ROOM ); } else { act( "You get all $T from $p.",ch, container, short_to_name(&arg1[4], 0), TO_CHAR ); act( "$n gets all $T from $p.",ch, container, short_to_name(&arg1[4], 0), TO_ROOM ); } } else { sprintf(buf1, "You get every %s from $p.", short_to_name(found_obj->short_descr, 1)); sprintf(buf2, "$n gets every %s from $p.", short_to_name(found_obj->short_descr, 1)); act(buf1, ch, container, NULL, TO_CHAR); act(buf2, ch, container, NULL, TO_ROOM); } if (IS_SET(ch->act, PLR_AUTO_SPLIT) && (ch->gold - split) >= 10 && split) { CHAR_DATA *gch; for (gch = ch->in_room->first_person ; gch ; gch = gch->next_in_room) { if (gch != ch && is_same_group(gch, ch) && !IS_NPC(gch)) { sprintf(buf1, "%d", ch->gold - split); do_split(ch, buf1); break; } } } } } } pop_call(); return; } void do_put( CHAR_DATA *ch, char *argument ) { char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; char buf1[MAX_INPUT_LENGTH]; char buf2[MAX_INPUT_LENGTH]; OBJ_DATA *container = NULL; OBJ_DATA *found_obj = NULL; OBJ_DATA *obj = NULL; OBJ_DATA *obj_next = NULL; bool shrtd = FALSE; bool clutter = FALSE; int amount = 1; int cnt = 0; int cnt_not_put = 0; push_call("do_put(%p,%p)",ch,argument); argument = one_argument( argument, arg1 ); if (is_number(arg1)) { amount = UMAX(1, atol(arg1)); argument = one_argument( argument, arg1 ); } argument = one_argument( argument, arg2 ); if (*arg1 == 0 || *arg2 == 0) { send_to_char( "Put what in what?\n\r", ch ); pop_call(); return; } if ((container = get_obj_here(ch, arg2)) == NULL) { act( "You see no $T here.", ch, NULL, arg2, TO_CHAR ); pop_call(); return; } if (container->item_type != ITEM_CONTAINER) { act("$p is not a container.", ch, container, NULL, TO_CHAR ); pop_call(); return; } if (IS_SET(container->value[1], CONT_CLOSED)) { act( "$p is closed.", ch, container, NULL, TO_CHAR ); pop_call(); return; } if (strcasecmp(arg1, "all") && str_prefix("all.", arg1)) { /* 'put obj container' */ if ((obj = get_obj_carry(ch, arg1)) == NULL) { send_to_char( "You do not have that item.\n\r", ch ); pop_call(); return; } if (amount == 1) { put_obj(ch, obj, container, TRUE); pop_call(); return; } for ( ; shrtd <= 1 && !found_obj ; shrtd++) { for (obj = ch->first_carrying ; obj ; obj = obj_next) { obj_next = obj->next_content; if (!can_see_obj(ch, obj) || obj->wear_loc != WEAR_NONE) { continue; } if (!shrtd && !is_name(arg1, obj->name)) { continue; } if (shrtd && !is_name_short(arg1, obj->name)) { continue; } if (found_obj == NULL) { found_obj = obj; } if (obj->short_descr != found_obj->short_descr) { continue; } if (put_obj(ch, obj, container, FALSE)) { cnt++; } else { cnt_not_put++; } if (cnt >= amount) { break; } } } if (found_obj) { sprintf(buf1, "You put %d %s into $p.", cnt, short_to_name(found_obj->short_descr, cnt)); sprintf(buf2, "$n puts %d %s into $p.", cnt, short_to_name(found_obj->short_descr, cnt)); act(buf1, ch, container, NULL, TO_CHAR); act(buf2, ch, container, NULL, TO_ROOM); } else { do_put(ch, arg1); } pop_call(); return; } else { /* 'put all container' or 'put all.obj container' */ for ( ; shrtd <= 1 && !found_obj ; shrtd++) { for (obj = ch->first_carrying ; obj ; obj = obj_next) { obj_next = obj->next_content; if (!can_see_obj(ch, obj) || obj->wear_loc != WEAR_NONE || obj == container) { continue; } if (!shrtd && arg1[3] && !is_name(&arg1[4], obj->name)) { continue; } if (shrtd && arg1[3] && !is_name_short(&arg1[4], obj->name)) { continue; } if (found_obj == NULL) { found_obj = obj; } if (obj->short_descr != found_obj->short_descr) { clutter = TRUE; } if (put_obj(ch, obj, container, FALSE)) { cnt++; } else { cnt_not_put++; } } } if (found_obj) { if (cnt_not_put > 0) { if (arg1[3] == '\0' || clutter) { sprintf(buf1, "You put all but %d of the items into $P.", cnt_not_put); sprintf(buf2, "$n puts some items into $P."); } else { sprintf(buf1, "You put %d %s into $P.", cnt, short_to_name(found_obj->short_descr, cnt)); sprintf(buf2, "$n puts %d %s into $P.", cnt, short_to_name(found_obj->short_descr, cnt)); } } else if (clutter) { if (arg1[3] == 0) { sprintf(buf1, "You put everything into $P."); sprintf(buf2, "$n puts everything into $P."); } else { sprintf(buf1, "You put all %s into $P.", short_to_name(&arg1[4], 0)); sprintf(buf2, "$n puts all %s into $P.", short_to_name(&arg1[4], 0)); } } else { sprintf(buf1, "You put all your %s into $P.", short_to_name(found_obj->short_descr, 0)); sprintf(buf2, "$n puts all $s %s into $P.", short_to_name(found_obj->short_descr, 0)); } act(buf1, ch, found_obj, container, TO_CHAR); act(buf2, ch, found_obj, container, TO_ROOM); } else { act( "You don't have $T.", ch, obj, arg1, TO_CHAR ); } } pop_call(); return; } void do_drop( CHAR_DATA *ch, char *argument ) { char arg1[MAX_INPUT_LENGTH]; char buf1[MAX_INPUT_LENGTH]; char buf2[MAX_INPUT_LENGTH]; OBJ_DATA *obj = NULL; OBJ_DATA *found_obj = NULL; OBJ_DATA *obj_next = NULL; bool shrtd = FALSE; bool clutter = FALSE; int amount = 1; int cnt = 0; int cnt_not_dropped = 0; push_call("do_drop(%p,%p)",ch,argument); argument = one_argument( argument, arg1 ); if (is_number(arg1)) { amount = UMAX(1, atol(arg1)); argument = one_argument( argument, arg1 ); } if (*arg1 == 0) { send_to_char( "Drop what?\n\r", ch ); pop_call(); return; } /* 'drop object' */ if (strcasecmp(arg1, "all") && str_prefix("all.", arg1)) { if ((obj = get_obj_carry(ch, arg1)) == NULL) { send_to_char( "You do not have that item.\n\r", ch ); pop_call(); return; } if (amount == 1) { drop_obj(ch, obj, NULL, TRUE); pop_call(); return; } for ( ; shrtd <= 1 && !found_obj ; shrtd++) { for (obj = ch->first_carrying ; obj ; obj = obj_next) { obj_next = obj->next_content; if (!can_see_obj(ch, obj) || obj->wear_loc != WEAR_NONE) { continue; } if (!shrtd && !is_name(arg1, obj->name)) { continue; } if (shrtd && !is_name_short(arg1, obj->name)) { continue; } if (found_obj == NULL) { found_obj = obj; } if (obj->short_descr != found_obj->short_descr) { continue; } if (drop_obj(ch, obj, NULL, FALSE)) { cnt++; } else { cnt_not_dropped++; } if (cnt >= amount) { break; } } } if (found_obj) { sprintf(buf1, "You drop %d %s.", cnt, short_to_name(found_obj->short_descr, cnt)); sprintf(buf2, "$n drops %d %s.", cnt, short_to_name(found_obj->short_descr, cnt)); act(buf1, ch, found_obj, NULL, TO_CHAR); act(buf2, ch, found_obj, NULL, TO_ROOM); } else { do_drop(ch, arg1); } pop_call(); return; } else { /* 'drop all' or 'drop all.object' */ for ( ; shrtd <= 1 && !found_obj ; shrtd++) { for (obj = ch->first_carrying ; obj ; obj = obj_next) { obj_next = obj->next_content; if (!can_see_obj(ch, obj) || obj->wear_loc != WEAR_NONE) { continue; } if (!shrtd && arg1[3] && !is_name(&arg1[4], obj->name)) { continue; } if (shrtd && arg1[3] && !is_name_short(&arg1[4], obj->name)) { continue; } if (found_obj == NULL) { found_obj = obj; } if (obj->short_descr != found_obj->short_descr) { clutter = TRUE; } if (drop_obj(ch, obj, NULL, FALSE)) { cnt++; } else { cnt_not_dropped++; } } } if (found_obj) { if (cnt_not_dropped > 0) { if (arg1[3] == '\0' || clutter) { sprintf(buf1, "You drop all but %d of the items.", cnt_not_dropped); sprintf(buf2, "$n drops some items."); } else { sprintf(buf1, "You drop %d %s.", cnt, short_to_name(found_obj->short_descr, cnt)); sprintf(buf2, "$n drops %d %s..", cnt, short_to_name(found_obj->short_descr, cnt)); } } else if (clutter) { if (arg1[3] == 0) { sprintf(buf1, "You drop everything."); sprintf(buf2, "$n drops everything."); } else { sprintf(buf1, "You drop all your %s.", short_to_name(&arg1[4], 0)); sprintf(buf2, "$n drops all $s %s.", short_to_name(&arg1[4], 0)); } } else { sprintf(buf1, "You drop all your %s.", short_to_name(found_obj->short_descr, 0)); sprintf(buf2, "$n drops all $s %s.", short_to_name(found_obj->short_descr, 0)); } act(buf1, ch, found_obj, NULL, TO_CHAR); act(buf2, ch, found_obj, NULL, TO_ROOM); } else { if (!found_obj) { if (arg1[3] == '\0' ) { act( "You are not carrying anything.", ch, NULL, NULL, TO_CHAR ); } else { act( "You are not carrying any $T.", ch, NULL, short_to_name(&arg1[4], 0), TO_CHAR ); } } } } pop_call(); return; } void do_give( CHAR_DATA *ch, char *argument ) { char arg1 [MAX_INPUT_LENGTH]; char arg2 [MAX_INPUT_LENGTH]; CHAR_DATA *victim; OBJ_DATA *obj; push_call("do_give(%p,%p)",ch,argument); if (!IS_NPC(ch) && who_fighting(ch) && !IS_NPC(ch->fighting->who)) { send_to_char( "You are too busy to give anything away.\n\r", ch ); pop_call(); return; } argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if ( arg1[0] == '\0' || arg2[0] == '\0' ) { send_to_char( "Give what to whom?\n\r", ch ); pop_call(); return; } if ( is_number( arg1 ) ) { /* 'give NNNN coins victim' */ int amount = atol(arg1); if (amount <= 0 || (strcasecmp(arg2, "coins") && strcasecmp(arg2, "coin"))) { send_to_char( "Sorry, you cannot do that.\n\r", ch ); pop_call(); return; } argument = one_argument( argument, arg2 ); if ( arg2[0] == '\0' ) { send_to_char( "Give what to whom?\n\r", ch ); pop_call(); return; } if ( ( victim = get_char_room( ch, arg2 ) ) == NULL ) { send_to_char( "They aren't here.\n\r", ch ); pop_call(); return; } if (!IS_NPC(victim) && who_fighting(victim) && !IS_NPC(victim->fighting->who)) { send_to_char( "They are too busy to take anything right now.\n\r", ch ); pop_call(); return; } if ( ch->gold < amount ) { send_to_char( "You haven't got that much gold.\n\r", ch ); pop_call(); return; } if (amount + victim->gold > victim->level * 1000000) { amount = victim->level * 1000000 - victim->gold; } ch->gold -= amount; if (!IS_NPC(victim)) { victim->gold += amount; } ch_printf(ch, "You give %s %d gold coins.\n\r", get_name(victim), amount); ch_printf(victim, "%s gives you %d gold coins.\n\r", capitalize(get_name(ch)), amount); act( "$n gives $N some gold.", ch, NULL, victim, TO_NOTVICT ); mprog_bribe_trigger(victim,ch,amount); pop_call(); return; } if ( ( obj = get_obj_carry( ch, arg1 ) ) == NULL ) { send_to_char( "You do not have that item.\n\r", ch ); pop_call(); return; } if ( obj->wear_loc != WEAR_NONE ) { send_to_char( "You must remove it first.\n\r", ch ); pop_call(); return; } if ( ( victim = get_char_room( ch, arg2 ) ) == NULL ) { send_to_char( "They aren't here.\n\r", ch ); pop_call(); return; } if (!can_drop_obj(ch, obj) && !IS_IMMORTAL(ch)) { send_to_char( "You cannot let go of it.\n\r", ch ); pop_call(); return; } if (!IS_IMMORTAL(ch)) { if (victim->carry_number >= can_carry_n(victim)) { act( "$N cannot carry that many items.", ch, NULL, victim, TO_CHAR ); pop_call(); return; } } if (!IS_IMMORTAL(ch)) { if (victim->carry_weight + get_obj_weight( obj ) > can_carry_w( victim ) ) { act( "$N cannot carry that much weight.", ch, NULL, victim, TO_CHAR ); pop_call(); return; } } if (!IS_IMMORTAL(ch)) { if ( !can_see_obj( victim, obj ) ) { act( "$N cannot see it.", ch, NULL, victim, TO_CHAR ); pop_call(); return; } } act( "You give $p to $N.", ch, obj, victim, TO_CHAR ); act( "$n gives you $p.", ch, obj, victim, TO_VICT ); act( "$n gives $p to $N.", ch, obj, victim, TO_NOTVICT ); /* Avoid multiple god chains - Scandum 14-04-2002 */ if (!IS_NPC(victim) && victim != ch) { if (obj->pIndexData->vnum >= 50 && obj->pIndexData->vnum <= 61) { OBJ_DATA *oldchain = get_eq_char(victim, WEAR_HEART); if (oldchain) { log_god_printf("%s replaced obj [%u] of %s with obj [%u]", ch->name, oldchain->pIndexData->vnum, victim->name, obj->pIndexData->vnum); junk_obj(oldchain); } obj_to_char(obj, victim); equip_char(victim, obj, WEAR_HEART); victim->pcdata->god = -1; victim->pcdata->god = which_god(victim); pop_call(); return; } } if (obj->item_type == ITEM_MONEY) { give_gold(victim, obj->value[0]); junk_obj(obj); } else { obj_to_char( obj, victim ); if (!IS_OBJ_STAT(obj,ITEM_FORGERY)) { mprog_give_trigger(victim,ch,obj); } } pop_call(); return; } void do_fill( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; OBJ_DATA *obj; OBJ_DATA *fountain; bool found; push_call("do_fill(%p,%p)",ch,argument); one_argument( argument, arg ); if (arg[0] == '\0') { send_to_char( "Fill what?\n\r", ch ); pop_call(); return; } if ((obj = get_obj_carry(ch, arg)) == NULL) { send_to_char( "You do not have that item.\n\r", ch ); pop_call(); return; } found = FALSE; for (fountain = ch->in_room->first_content ; fountain ; fountain = fountain->next_content) { if (fountain->item_type == ITEM_FOUNTAIN) { found = TRUE; break; } } if (!found) { send_to_char( "There is no fountain here!\n\r", ch ); pop_call(); return; } if (obj->item_type != ITEM_DRINK_CON) { send_to_char( "You cannot fill that.\n\r", ch ); pop_call(); return; } if (obj->value[1] != 0 && obj->value[2] != fountain->value[2]) { send_to_char( "There is already another liquid in it.\n\r", ch ); pop_call(); return; } if (obj->value[1] >= obj->value[0]) { send_to_char( "Your container is full.\n\r", ch ); pop_call(); return; } act( "You fill $p.", ch, obj, NULL, TO_CHAR ); obj->value[2] = fountain->value[2]; obj->value[1] = obj->value[0]; SET_BIT(obj->extra_flags, ITEM_MODIFIED); pop_call(); return; } void do_drink( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; OBJ_DATA *obj; int amount; int liquid; int cnt; push_call("do_drink(%p,%p)",ch,argument); if (!check_blind(ch)) { pop_call(); return; } one_argument( argument, arg ); if (arg[0] == '\0') { for (obj = ch->in_room->first_content ; obj ; obj = obj->next_content) { if (obj->item_type == ITEM_FOUNTAIN) { break; } } if (rspec_req(ch,RSPEC_VAMPIRIC)) { for (cnt = 0 ; cnt < MAX_LAST_LEFT ; cnt++) { if (IS_SET(ch->in_room->last_left_bits[cnt], TRACK_BLOOD)) { /* vampires drink blood-trails too */ send_to_char( "You lick blood from the ground.\n\r", ch ); act( "$n licks blood from the ground.", ch, NULL, NULL, TO_ROOM ); gain_condition( ch, COND_FULL, 2); gain_condition( ch, COND_THIRST, 2); REMOVE_BIT(ch->in_room->last_left_bits[cnt], TRACK_BLOOD); pop_call(); return; } } } if (obj == NULL) { send_to_char( "Drink what?\n\r", ch ); pop_call(); return; } } else { if ((obj = get_obj_here(ch, arg)) == NULL) { send_to_char( "You cannot find it.\n\r", ch ); pop_call(); return; } } if (!IS_NPC(ch) && ch->pcdata->condition[COND_DRUNK] > 10) { send_to_char( "You fail to reach your mouth. *Hic*\n\r", ch ); pop_call(); return; } switch (obj->item_type) { default: send_to_char( "You cannot drink from that.\n\r", ch ); pop_call(); return; case ITEM_DRINK_CON: case ITEM_FOUNTAIN: if (obj->item_type == ITEM_DRINK_CON && obj->value[1] <= 0) { send_to_char( "It is already empty.\n\r", ch ); pop_call(); return; } if ((liquid = obj->value[2]) >= LIQ_MAX) { log_printf( "do_drink(%s, i%d) bad liquid number %d.", get_name(ch), obj->pIndexData->vnum, liquid); liquid = obj->value[2] = 0; } act( "You drink $T from $p.", ch, obj, liq_table[liquid].liq_name, TO_CHAR ); act( "$n drinks $T from $p.", ch, obj, liq_table[liquid].liq_name, TO_ROOM ); if (obj->item_type == ITEM_DRINK_CON) { amount = UMIN(obj->value[1], number_range(1, 2)); } else { amount = number_range(1, 2); } if (!rspec_req(ch,RSPEC_VAMPIRIC)) { if (!IS_NPC(ch)) { if (ch->pcdata->condition[COND_DRUNK] <= 10) { gain_condition( ch, COND_DRUNK, amount * liq_table[liquid].liq_affect[COND_DRUNK] ); if (ch->pcdata->condition[COND_DRUNK] > 10) { send_to_char( "You feel drunk.\n\r", ch ); } } if (ch->pcdata->condition[COND_FULL] <= 40) { gain_condition( ch, COND_FULL, amount * liq_table[liquid].liq_affect[COND_FULL] ); if (ch->pcdata->condition[COND_FULL] > 40) { send_to_char( "You are full.\n\r", ch ); } } if (ch->pcdata->condition[COND_THIRST] <= 40) { gain_condition( ch, COND_THIRST, amount * liq_table[liquid].liq_affect[COND_THIRST] ); if (ch->pcdata->condition[COND_THIRST] > 40) { send_to_char( "You do not feel thirsty.\n\r", ch ); } } } if (obj->value[3] != 0) { /* The shit was poisoned ! */ AFFECT_DATA af; send_to_char( "You choke and gag.\n\r", ch ); act( "$n chokes and gags.", ch, NULL, NULL, TO_ROOM ); af.type = gsn_poison; af.duration = 3 * amount; af.location = APPLY_NONE; af.modifier = 0; af.bittype = AFFECT_TO_CHAR; af.bitvector = AFF_POISON; affect_join( ch, &af ); } } else { if (liquid == LIQ_BLOOD) { gain_condition(ch, COND_FULL, 5); gain_condition(ch, COND_THIRST, 5); } else if (liq_table[liquid].liq_affect[COND_DRUNK] > 0) { AFFECT_DATA af; act ("$n starts to smoke.", ch, NULL, NULL, TO_ROOM); act ("You start to smoke.", ch, NULL, NULL, TO_CHAR); af.type = gsn_poison; af.duration = 2 * amount; af.location = APPLY_NONE; af.modifier = 0; af.bittype = AFFECT_TO_CHAR; af.bitvector = AFF_POISON; affect_join( ch, &af); } } if (obj->item_type == ITEM_DRINK_CON) { SET_BIT(obj->extra_flags, ITEM_MODIFIED); obj->value[1] -= amount; if (obj->value[1] <= 0 && obj->value[0] <= 2) { send_to_char( "The empty container vanishes.\n\r", ch ); junk_obj( obj ); } } break; case ITEM_CORPSE_NPC: case ITEM_CORPSE_PC: if (rspec_req(ch, RSPEC_VAMPIRIC)) { if (obj->level > 1) { int wanted = 24; if (!IS_NPC(ch)) { wanted = 48 - ch->pcdata->condition[COND_THIRST]; } if ((wanted = UMIN(wanted, obj->level)) == 0) { ch_printf(ch, "You are too full to drink from %s.\n\r", obj->short_descr); } else { gain_condition(ch, COND_FULL, wanted); gain_condition(ch, COND_THIRST, wanted); if (ch->hit < ch->max_hit) { int heal = UMIN(wanted, ch->max_hit-ch->hit); ch_printf(ch,"You drink blood from %s, restoring %d hp.\n\r", obj->short_descr, heal); ch->hit += heal; } else { ch_printf(ch,"You drink blood from %s.\n\r",obj->short_descr); } obj->level -= wanted; act( "$n drinks blood from the $p.", ch, obj, NULL, TO_ROOM ); } /* the corpse remains, it's only drained! */ } else { ch_printf(ch,"There's no blood left in %s.\n\r", obj->short_descr); } break; } else { send_to_char("You cannot drink from that.\n\r",ch); break; } } pop_call(); return; } /* Forage for Gnomes - Chaos 8/17/98 */ /* or other foraging races */ void do_forage( CHAR_DATA *ch, char *argument ) { push_call("do_forage(%p,%p)",ch,argument); if (IS_NPC(ch) || !rspec_req(ch, RSPEC_FORAGE)) { send_to_char( "Your parents never taught you to find your own food.\n\r", ch ); pop_call(); return; } if (ch->in_room == NULL || (ch->in_room->sector_type != SECT_FIELD && ch->in_room->sector_type != SECT_FOREST && ch->in_room->sector_type != SECT_HILLS && ch->in_room->sector_type != SECT_MOUNTAIN )) { send_to_char( "There is no food to be found here.\n\r", ch ); pop_call(); return; } send_to_char( "You find enough food and water to satisfy yourself.\n\r", ch ); ch->pcdata->condition[COND_FULL] = 25; ch->pcdata->condition[COND_THIRST] = 30; pop_call(); return; } void do_eat( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; OBJ_DATA *obj; push_call("do_eat(%p,%p)",ch,argument); one_argument( argument, arg ); if (arg[0] == '\0') { send_to_char( "Eat what?\n\r", ch ); pop_call(); return; } if ((obj = get_obj_carry(ch, arg)) == NULL) { send_to_char( "You do not have that item.\n\r", ch ); pop_call(); return; } if (!IS_NPC(ch) && ch->fighting && ch->class != CLASS_NINJA) { send_to_char( "You may not do that while fighting.\n\r", ch); pop_call(); return; } if (obj->item_type != ITEM_FOOD && obj->item_type != ITEM_PILL) { send_to_char( "That's not edible.\n\r", ch ); pop_call(); return; } if (obj->item_type == ITEM_PILL) { if (cspec_req(ch, CSPEC_NO_PILLS)) { send_to_char( "You may not do that in your class.\n\r", ch); pop_call(); return; } if (obj->level > reinc_eq_level(ch)) { send_to_char( "You would over-dose if you ate that pill!\n\r", ch); pop_call(); return; } } if (!IS_NPC(ch) && ch->pcdata->condition[COND_FULL] > 40 && obj->item_type != ITEM_PILL) { send_to_char( "You are too full to eat more.\n\r", ch ); pop_call(); return; } if (ch->fighting != NULL && number_percent() > get_curr_dex(ch) * 2) { act( "You crumble $p.", ch, obj, NULL, TO_CHAR ); act( "$n crumbles $p.", ch, obj, NULL, TO_ROOM ); wait_state( ch, PULSE_VIOLENCE); junk_obj( obj ); pop_call(); return; } act( "You eat $p.", ch, obj, NULL, TO_CHAR ); act( "$n eats $p.", ch, obj, NULL, TO_ROOM ); switch ( obj->item_type ) { case ITEM_FOOD: if (!IS_NPC(ch) && !IS_UNDEAD(ch) && !rspec_req(ch, RSPEC_VAMPIRIC)) { int condition; condition = ch->pcdata->condition[COND_FULL]; gain_condition( ch, COND_FULL, obj->value[0] ); if ( condition == 0 && ch->pcdata->condition[COND_FULL] > 0 ) { send_to_char( "You are no longer hungry.\n\r", ch ); } else if ( ch->pcdata->condition[COND_FULL] > 40 ) { send_to_char( "You are full.\n\r", ch ); } } switch(obj->value[1]) { case FOOD_GARLIC: if (rspec_req(ch,RSPEC_VAMPIRIC)) { AFFECT_DATA af; act ("$n starts to smoke and sizzle.",ch,0,0,TO_ROOM); send_to_char("You smoke and sizzle.\n\r",ch); af.type = gsn_poison; af.duration = 3 * obj->value[0]; af.location = APPLY_NONE; af.modifier = 0; af.bittype = AFFECT_TO_CHAR; af.bitvector = AFF_POISON; affect_join(ch,&af); } break; } if (obj->value[3] != 0 && !rspec_req(ch, RSPEC_VAMPIRIC)) { /* The shit was poisoned! */ AFFECT_DATA af; send_to_char( "You choke and gag.\n\r", ch ); act( "$n chokes and gags.", ch, 0, 0, TO_ROOM ); af.type = gsn_poison; af.duration = 2 * obj->value[0]; af.location = APPLY_NONE; af.modifier = 0; af.bittype = AFFECT_TO_CHAR; af.bitvector = AFF_POISON; affect_join( ch, &af ); } break; case ITEM_PILL: obj_cast_spell( obj->value[1], obj->value[0], ch, ch, obj ); obj_cast_spell( obj->value[2], obj->value[0], ch, ch, obj ); obj_cast_spell( obj->value[3], obj->value[0], ch, ch, obj ); wait_state(ch, PULSE_VIOLENCE*2); break; } junk_obj( obj ); pop_call(); return; } /* Remove an object. */ bool remove_obj( CHAR_DATA *ch, int iWear, bool fReplace , bool fDisplay ) { OBJ_DATA *obj; push_call("remove_obj(%p,%p,%p,%p)",ch,iWear,fReplace,fDisplay); if ( ( obj = get_eq_char( ch, iWear ) ) == NULL ) { pop_call(); return TRUE; } if (!fReplace && ch->carry_number >= can_carry_n(ch)) { act( "You cannot carry that many items.", ch, NULL, NULL, TO_CHAR); pop_call(); return FALSE; } if ( !fReplace ) { pop_call(); return FALSE; } if (IS_SET(obj->extra_flags, ITEM_NOREMOVE)) { if (fDisplay) { act( "You cannot remove $p.", ch, obj, NULL, TO_CHAR ); } pop_call(); return FALSE; } unequip_char( ch, obj ); if (fDisplay) { act( "You stop using $p.", ch, obj, NULL, TO_CHAR ); act( "$n stops using $p.", ch, obj, NULL, TO_ROOM ); } pop_call(); return TRUE; } /* Wear one object. Optional replacement of existing objects. Big repetitive code, ick. */ bool wear_obj( CHAR_DATA *ch, OBJ_DATA *obj, bool fReplace, int location, bool fDisplay ) { OBJ_DATA *obj2, *tmpobj; push_call("wear_obj(%p,%p,%p,%p,%p)",ch,obj,fReplace,location,fDisplay); if (reinc_eq_level(ch) < obj->level) { if (fDisplay) { ch_printf(ch, "You must be level %d to use this object.\n\r", obj_eq_level(ch, obj)); act( "$n tries to use $p, but is too inexperienced.", ch, obj, NULL, TO_ROOM ); } pop_call(); return FALSE; } if ((obj2 = get_obj_wear_vnum(ch, obj->pIndexData->vnum)) != NULL) { if (obj2->pIndexData == obj->pIndexData) { if (fDisplay) { act("Wearing more than one $t will not help you.", ch, short_to_name(obj->short_descr, 1), NULL, TO_CHAR); } pop_call(); return FALSE; } } if (obj->owned_by) { if (IS_NPC(ch) || ch->pcdata->pvnum != obj->owned_by) { if (fDisplay) { send_to_char( "You cannot wear someone else's equipment!\n\r", ch); } pop_call(); return FALSE; } } if ((IS_OBJ_STAT(obj, ITEM_ANTI_EVIL) && IS_EVIL(ch)) || (IS_OBJ_STAT(obj, ITEM_ANTI_GOOD) && IS_GOOD(ch)) || (IS_OBJ_STAT(obj, ITEM_ANTI_NEUTRAL) && IS_NEUTRAL(ch))) { if (fDisplay) { act( "You are zapped by $p.", ch, obj, NULL, TO_CHAR ); act( "$n is zapped by $p.", ch, obj, NULL, TO_ROOM ); } pop_call(); return FALSE; } if (!class_allowed(obj, ch, fDisplay)) { pop_call(); return FALSE; } if ((location==ITEM_TAKE||location==-1) &&obj->item_type == ITEM_LIGHT ) { if ( !remove_obj( ch, WEAR_LIGHT, fReplace , fDisplay) ) { pop_call(); return FALSE; } if (fDisplay) { act( "You light $p and hold it.", ch, obj, NULL, TO_CHAR ); act( "$n lights $p and holds it.", ch, obj, NULL, TO_ROOM ); } equip_char( ch, obj, WEAR_LIGHT ); pop_call(); return TRUE; } if ((location == ITEM_WEAR_HEART || location == -1) && (obj->pIndexData->vnum >= 50 && obj->pIndexData->vnum <= 61)) { if (!remove_obj( ch, WEAR_HEART, fReplace , fDisplay)) { pop_call(); return FALSE; } equip_char( ch, obj, WEAR_HEART ); if (fDisplay) { act( "$p becomes one with your heart.", ch, obj, NULL, TO_CHAR ); act( "$p becomes one with $n's heart.", ch, obj, NULL, TO_ROOM ); } pop_call(); return TRUE; } if ((location == ITEM_WEAR_FINGER || location == -1) && CAN_WEAR(obj, ITEM_WEAR_FINGER)) { if (get_eq_char(ch, WEAR_FINGER_L) != NULL && get_eq_char(ch, WEAR_FINGER_R) != NULL && !remove_obj(ch, WEAR_FINGER_L, fReplace , fDisplay) && !remove_obj(ch, WEAR_FINGER_R, fReplace , fDisplay)) { pop_call(); return FALSE; } if (rspec_req(ch, RSPEC_MULTI_ARMS)) { if (fDisplay) { send_to_char("You cannot wear rings.\n\r", ch); } pop_call(); return FALSE; } if (get_eq_char(ch, WEAR_FINGER_L) == NULL) { equip_char(ch, obj, WEAR_FINGER_L); if (fDisplay) { act( "You slip $p onto your left finger.", ch, obj, NULL, TO_CHAR ); act( "$n slips $p onto $s left finger.", ch, obj, NULL, TO_ROOM ); } pop_call(); return TRUE; } if (get_eq_char(ch, WEAR_FINGER_R) == NULL) { equip_char( ch, obj, WEAR_FINGER_R ); if (fDisplay) { act( "You slip $p onto your right finger.", ch, obj, NULL, TO_CHAR ); act( "$n slips $p onto $s right finger.", ch, obj, NULL, TO_ROOM ); } pop_call(); return TRUE; } bug( "Wear_obj: no free finger.", 0 ); if (fDisplay) { send_to_char( "You already wear two rings.\n\r", ch ); } pop_call(); return FALSE; } if ((location == ITEM_WEAR_NECK || location == -1) && CAN_WEAR(obj, ITEM_WEAR_NECK)) { if (get_eq_char(ch, WEAR_NECK_1) != NULL && get_eq_char(ch, WEAR_NECK_2) != NULL && !remove_obj(ch, WEAR_NECK_1, fReplace , fDisplay) && !remove_obj(ch, WEAR_NECK_2, fReplace , fDisplay)) { pop_call(); return FALSE; } if (get_eq_char(ch, WEAR_NECK_1) == NULL) { equip_char( ch, obj, WEAR_NECK_1 ); if (fDisplay) { act( "You fasten $p around your neck.", ch, obj, NULL, TO_CHAR ); act( "$n fastens $p around $s neck.", ch, obj, NULL, TO_ROOM ); } pop_call(); return TRUE; } if (get_eq_char(ch, WEAR_NECK_2) == NULL) { equip_char( ch, obj, WEAR_NECK_2 ); if (fDisplay) { act( "You fasten $p around your neck.", ch, obj, NULL, TO_CHAR ); act( "$n fastens $p around $s neck.", ch, obj, NULL, TO_ROOM ); } pop_call(); return TRUE; } bug( "Wear_obj: no free neck.", 0 ); if (fDisplay) { send_to_char( "You already wear two neck items.\n\r", ch ); } pop_call(); return FALSE; } if ((location == ITEM_WEAR_BODY || location == -1) && CAN_WEAR(obj, ITEM_WEAR_BODY)) { if (!remove_obj(ch, WEAR_BODY, fReplace , fDisplay)) { pop_call(); return FALSE; } equip_char( ch, obj, WEAR_BODY ); if (fDisplay) { act( "You wear $p on your body.", ch, obj, NULL, TO_CHAR ); act( "$n wears $p on $s body.", ch, obj, NULL, TO_ROOM ); } pop_call(); return TRUE; } if ((location == ITEM_WEAR_HEAD || location == -1) && CAN_WEAR(obj, ITEM_WEAR_HEAD)) { if ( !remove_obj( ch, WEAR_HEAD, fReplace , fDisplay) ) { pop_call(); return FALSE; } equip_char( ch, obj, WEAR_HEAD ); if ( fDisplay ) { act( "You place $p on your head.", ch, obj, NULL, TO_CHAR ); act( "$n places $p on $s head.", ch, obj, NULL, TO_ROOM ); } pop_call(); return TRUE; } if ((location == ITEM_WEAR_LEGS || location == -1) && CAN_WEAR(obj, ITEM_WEAR_LEGS)) { if (!remove_obj(ch, WEAR_LEGS, fReplace , fDisplay)) { pop_call(); return FALSE; } equip_char( ch, obj, WEAR_LEGS ); if (fDisplay) { act( "You slip into $p.", ch, obj, NULL, TO_CHAR ); act( "$n slips into $p.", ch, obj, NULL, TO_ROOM ); } pop_call(); return TRUE; } if ((location == ITEM_WEAR_FEET || location == -1) && CAN_WEAR(obj, ITEM_WEAR_FEET)) { if (!remove_obj(ch, WEAR_FEET, fReplace, fDisplay)) { pop_call(); return FALSE; } equip_char(ch, obj, WEAR_FEET); if (fDisplay) { act( "You pull on $p.", ch, obj, NULL, TO_CHAR ); act( "$n pulls on $p.", ch, obj, NULL, TO_ROOM ); } pop_call(); return TRUE; } if ((location == ITEM_WEAR_HANDS || location == -1) && CAN_WEAR(obj, ITEM_WEAR_HANDS)) { if ( !remove_obj( ch, WEAR_HANDS, fReplace , fDisplay) ) { pop_call(); return FALSE; } equip_char( ch, obj, WEAR_HANDS ); if (fDisplay) { act( "You slip $p over your hands.", ch, obj, NULL, TO_CHAR ); act( "$n slips $p over $s hands.", ch, obj, NULL, TO_ROOM ); } pop_call(); return TRUE; } if ((location == ITEM_WEAR_ARMS || location == -1) && CAN_WEAR(obj, ITEM_WEAR_ARMS)) { if ( !remove_obj( ch, WEAR_ARMS, fReplace , fDisplay) ) { pop_call(); return FALSE; } equip_char( ch, obj, WEAR_ARMS ); if (fDisplay) { act( "You wear $p on your arms.", ch, obj, NULL, TO_CHAR ); act( "$n wears $p on $s arms.", ch, obj, NULL, TO_ROOM ); } pop_call(); return TRUE; } if ((location == ITEM_WEAR_ABOUT || location == -1) && CAN_WEAR(obj, ITEM_WEAR_ABOUT)) { if ( !remove_obj( ch, WEAR_ABOUT, fReplace , fDisplay) ) { pop_call(); return FALSE; } equip_char( ch, obj, WEAR_ABOUT ); if (fDisplay) { act( "You wrap $p about your body.", ch, obj, NULL, TO_CHAR ); act( "$n wraps $p about $s body.", ch, obj, NULL, TO_ROOM ); } pop_call(); return TRUE; } if ((location == ITEM_WEAR_WAIST || location == -1) && CAN_WEAR(obj, ITEM_WEAR_WAIST)) { if (!remove_obj( ch, WEAR_WAIST, fReplace , fDisplay) ) { pop_call(); return FALSE; } equip_char( ch, obj, WEAR_WAIST ); if (fDisplay) { act( "You fasten $p around your waist.", ch, obj, NULL, TO_CHAR ); act( "$n fastens $p around $s waist.", ch, obj, NULL, TO_ROOM ); } pop_call(); return TRUE; } if ((location == ITEM_WEAR_WRIST || location == -1) && CAN_WEAR(obj, ITEM_WEAR_WRIST)) { if (get_eq_char(ch, WEAR_WRIST_L) != NULL && get_eq_char(ch, WEAR_WRIST_R) != NULL && !remove_obj(ch, WEAR_WRIST_L, fReplace , fDisplay) && !remove_obj(ch, WEAR_WRIST_R, fReplace , fDisplay)) { pop_call(); return FALSE; } if ( get_eq_char( ch, WEAR_WRIST_L ) == NULL ) { equip_char( ch, obj, WEAR_WRIST_L ); if (fDisplay) { act( "You slide $p over your left wrist.", ch, obj, NULL, TO_CHAR ); act( "$n slides $p over $s left wrist.", ch, obj, NULL, TO_ROOM ); } pop_call(); return TRUE; } if ( get_eq_char( ch, WEAR_WRIST_R ) == NULL ) { equip_char( ch, obj, WEAR_WRIST_R ); if( fDisplay ) { act( "You slide $p over your right wrist.", ch, obj, NULL, TO_CHAR ); act( "$n slides $p over $s right wrist.", ch, obj, NULL, TO_ROOM ); } pop_call(); return TRUE; } bug( "Wear_obj: no free wrist.", 0 ); if( fDisplay ) { send_to_char( "You already wear two wrist items.\n\r", ch ); } pop_call(); return FALSE; } if ((location == ITEM_WEAR_SHIELD || location == -1) && CAN_WEAR( obj, ITEM_WEAR_SHIELD ) ) { if (get_eq_char(ch, WEAR_DUAL_WIELD) && !rspec_req(ch, RSPEC_MULTI_ARMS) && ch->race != RACE_KRAKEN) { if (fDisplay) { send_to_char("You cannot use a shield AND two weapons!\n\r", ch); } pop_call(); return FALSE; } if (!remove_obj(ch, WEAR_SHIELD, fReplace , fDisplay)) { pop_call(); return FALSE; } if (!IS_NPC(ch)) { if (!cspec_req(ch, CSPEC_SHIELD_ALLOWED)) { if (fDisplay) { send_to_char( "You cannot use that kind of armor.\n\r", ch); } pop_call(); return FALSE; } } equip_char( ch, obj, WEAR_SHIELD ); if (fDisplay) { act( "You strap $p to your arm.", ch, obj, NULL, TO_CHAR ); act( "$n straps $p to $s arm.", ch, obj, NULL, TO_ROOM ); } pop_call(); return TRUE; } if ((location == ITEM_WEAR_WIELD || location == -1) && CAN_WEAR(obj, ITEM_WEAR_WIELD)) { int skill; if (!could_dual(ch)) { if (!remove_obj(ch, WEAR_WIELD, fReplace, fDisplay)) { pop_call(); return FALSE; } tmpobj = NULL; } else { if ((tmpobj = get_eq_char(ch, WEAR_WIELD)) != NULL && get_eq_char(ch, WEAR_DUAL_WIELD)) { if (fDisplay) { send_to_char( "You're already wielding two weapons.\n\r", ch); } pop_call(); return FALSE; } } if (tmpobj) { if (can_dual(ch)) { if (get_obj_weight(obj) + get_obj_weight(tmpobj) > str_app[get_curr_str(ch)].wield) { if (fDisplay) { send_to_char( "It is too heavy for you to wield.\n\r", ch ); } pop_call(); return FALSE; } equip_char( ch, obj, WEAR_DUAL_WIELD ); if (fDisplay) { act( "You dual-wield $p.", ch, obj, NULL, TO_CHAR ); act( "$n dual-wields $p.", ch, obj, NULL, TO_ROOM ); } if (!fDisplay) { pop_call(); return TRUE; } if (obj->value[0]) { skill = weapon_skill(ch, obj->value[0]); switch (skill/20) { case 5: act("$p feels like a part of you.", ch, obj, NULL, TO_CHAR); break; case 4: act("You are mastered with $p.", ch, obj, NULL, TO_CHAR); break; case 3: act("You are skilled with $p.", ch, obj, NULL, TO_CHAR); break; case 2: act("$p feels clumsy in your hands.", ch, obj, NULL, TO_CHAR); break; case 1: act("You fumble and almost drop $p.", ch, obj, NULL, TO_CHAR); break; case 0: act("You wonder which end is up on $p.", ch, obj, NULL, TO_CHAR); break; } } } pop_call(); return TRUE; } if (get_obj_weight(obj) > str_app[get_curr_str(ch)].wield) { if (fDisplay) { send_to_char( "It is too heavy for you to wield.\n\r", ch ); } pop_call(); return FALSE; } equip_char( ch, obj, WEAR_WIELD ); if (fDisplay) { act( "You wield $p.", ch, obj, NULL, TO_CHAR ); act( "$n wields $p.", ch, obj, NULL, TO_ROOM ); } if (!fDisplay) { pop_call(); return TRUE; } if (obj->value[0]) { skill = weapon_skill(ch, obj->value[0]); switch (skill/20) { case 5: act("$p feels like a part of you.", ch, obj, NULL, TO_CHAR); break; case 4: act("You are mastered with $p.", ch, obj, NULL, TO_CHAR); break; case 3: act("You are skilled with $p.", ch, obj, NULL, TO_CHAR); break; case 2: act("$p feels clumsy in your hands.", ch, obj, NULL, TO_CHAR); break; case 1: act("You fumble and almost drop $p.", ch, obj, NULL, TO_CHAR); break; case 0: act("You wonder which end is up on $p.", ch, obj, NULL, TO_CHAR); break; } } pop_call(); return TRUE; } if ((location == ITEM_WEAR_HOLD || location == -1) && CAN_WEAR(obj, ITEM_WEAR_HOLD)) { if (get_eq_char(ch, WEAR_DUAL_WIELD) && !rspec_req(ch, RSPEC_MULTI_ARMS) && ch->race != RACE_KRAKEN) { if (fDisplay) { send_to_char("You cannot hold something AND two weapons!\n\r", ch); } pop_call(); return FALSE; } if (!remove_obj(ch, WEAR_HOLD, fReplace , fDisplay)) { pop_call(); return FALSE; } equip_char( ch, obj, WEAR_HOLD ); if (fDisplay) { act( "You hold $p in your hand.", ch, obj, NULL, TO_CHAR ); act( "$n holds $p in $s hand.", ch, obj, NULL, TO_ROOM ); } pop_call(); return TRUE; } if (fReplace && location != -1 && fDisplay) { act("You cannot wear $p in that location.", ch, obj, NULL, TO_CHAR); } else if (fReplace && fDisplay) { act("You cannot wear $p.", ch, obj, NULL, TO_CHAR); } pop_call(); return FALSE; } void do_wear( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; char local[MAX_INPUT_LENGTH]; OBJ_DATA *obj; OBJ_PROG *prg; int location; push_call("do_wear(%p,%p)",ch,argument); argument=one_argument( argument, arg ); one_argument( argument, local ); if (arg[0] == '\0') { send_to_char( "Wear what?\n\r", ch ); pop_call(); return; } if (!strcasecmp(arg, "all")) { OBJ_DATA *obj_next, *obj_old; bool foundi, tfound; int loc; foundi = FALSE; obj_old = NULL; for (obj = ch->first_carrying ; obj ; obj = obj_next) { /* Now always picks best and also lights - Scandum */ obj_next = obj->next_content; loc = 0; tfound = FALSE; if (obj->carried_by == NULL) { break; } if (obj->item_type == ITEM_LIGHT) { obj_old = get_eq_char(ch, WEAR_LIGHT); if ((obj_old == NULL || compare_obj(obj_old, obj) < 0) && !(IS_OBJ_STAT(obj, ITEM_ANTI_EVIL) && IS_EVIL(ch)) && !(IS_OBJ_STAT(obj, ITEM_ANTI_GOOD) && IS_GOOD(ch)) && !(IS_OBJ_STAT(obj, ITEM_ANTI_NEUTRAL) && IS_NEUTRAL(ch))) { if (wear_obj(ch, obj, TRUE, -1, FALSE)) { foundi = TRUE; tfound = TRUE; if (!IS_NPC(ch) && obj->carried_by && IS_SET(obj->pIndexData->progtypes, TRIG_WEAR)) { for (prg = obj->pIndexData->first_prog ; prg ; prg = prg->next) { if (prg->trigger == TRIG_WEAR && number_percent() <= prg->percentage) { start_object_program( ch, obj, prg, ""); } } } } } } if (obj->wear_loc == WEAR_NONE && can_see_obj(ch, obj)) { while (loc != -1 && !tfound) { loc = wear_flags_to_wear_loc(obj, loc); if (loc != -1) { obj_old = get_eq_char(ch, loc); if ((obj_old == NULL || compare_obj(obj_old, obj) < 0) && !(IS_OBJ_STAT(obj, ITEM_ANTI_EVIL) && IS_EVIL(ch)) && !(IS_OBJ_STAT(obj, ITEM_ANTI_GOOD) && IS_GOOD(ch)) && !(IS_OBJ_STAT(obj, ITEM_ANTI_NEUTRAL) && IS_NEUTRAL(ch))) { if (wear_obj(ch, obj, TRUE, -1, FALSE)) { foundi = TRUE; tfound = TRUE; if (!IS_NPC(ch) && obj->carried_by && IS_SET(obj->pIndexData->progtypes, TRIG_WEAR)) { for (prg = obj->pIndexData->first_prog ; prg ; prg = prg->next) { if (prg->trigger == TRIG_WEAR && number_percent() <= prg->percentage) { start_object_program( ch, obj, prg, ""); } } } } } loc++; } } } } if (foundi) { act( "You wear the best equipment that you have.",ch,NULL,NULL,TO_CHAR); act( "$n wears all $s equipment.", ch, NULL, NULL, TO_ROOM); } else { send_to_char( "You wear nothing new.\n\r", ch); } pop_call(); return; } else { if ((obj = get_obj_carry(ch, arg)) == NULL) { ch_printf(ch, "You do not have the item '%s'.\n\r", arg); pop_call(); return; } location=-1; if (!strcasecmp(local, "light")) location = ITEM_TAKE; if (!strcasecmp(local, "finger")) location = ITEM_WEAR_FINGER; if (!strcasecmp(local, "neck")) location = ITEM_WEAR_NECK; if (!strcasecmp(local, "body")) location = ITEM_WEAR_BODY; if (!strcasecmp(local, "head")) location = ITEM_WEAR_HEAD; if (!strcasecmp(local, "legs")) location = ITEM_WEAR_LEGS; if (!strcasecmp(local, "feet")) location = ITEM_WEAR_FEET; if (!strcasecmp(local, "hands")) location = ITEM_WEAR_HANDS; if (!strcasecmp(local, "arms")) location = ITEM_WEAR_ARMS; if (!strcasecmp(local, "shield")) location = ITEM_WEAR_SHIELD; if (!strcasecmp(local, "about")) location = ITEM_WEAR_ABOUT; if (!strcasecmp(local, "waist")) location = ITEM_WEAR_WAIST; if (!strcasecmp(local, "wrist")) location = ITEM_WEAR_WRIST; if (!strcasecmp(local, "wield")) location = ITEM_WEAR_WIELD; if (!strcasecmp(local, "hold")) location = ITEM_WEAR_HOLD; if (!strcasecmp(local, "heart")) location = ITEM_WEAR_HEART; if (wear_obj( ch, obj, TRUE, location , TRUE)) { if (!IS_NPC(ch) && IS_SET(obj->pIndexData->progtypes, TRIG_WEAR)) { for (prg = obj->pIndexData->first_prog ; prg ; prg = prg->next) { if (prg->trigger == TRIG_WEAR && number_percent() <= prg->percentage) { start_object_program( ch, obj, prg, ""); } } } } } pop_call(); return; } void do_remove( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; OBJ_PROG *prg; OBJ_DATA *obj; OBJ_DATA *obj_next; push_call("do_remove(%p,%p)",ch,argument); one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Remove what?\n\r", ch ); pop_call(); return; } /* all added by Trom */ if (!strcasecmp(arg, "all")) { act( "You remove all your equipment.",ch,NULL,NULL,TO_CHAR); act( "$n removes all $s equipment.", ch, NULL, NULL, TO_ROOM); for (obj = ch->first_carrying ; obj != NULL ; obj = obj_next) { obj_next = obj->next_content; if (obj->carried_by == NULL) { break; } if (obj->wear_loc != WEAR_NONE) { if (remove_obj(ch, obj->wear_loc,TRUE, FALSE)) { if (!IS_NPC(ch) && obj->carried_by && IS_SET(obj->pIndexData->progtypes, TRIG_REMOVE)) { for (prg = obj->pIndexData->first_prog ; prg != NULL ; prg = prg->next) { if (prg->trigger == TRIG_REMOVE && number_percent() <= prg->percentage) { start_object_program( ch, obj, prg, ""); } } } } } } } else { if ((obj = get_obj_wear( ch, arg ) ) == NULL ) { ch_printf(ch, "You do not have the item '%s'.\n\r", arg); pop_call(); return; } if (remove_obj( ch, obj->wear_loc, TRUE , TRUE)) { if (!IS_NPC(ch) && IS_SET(obj->pIndexData->progtypes, TRIG_REMOVE)) { for (prg = obj->pIndexData->first_prog ; prg != NULL ; prg = prg->next) { if (prg->trigger == TRIG_REMOVE && number_percent() <= prg->percentage) { start_object_program( ch, obj, prg, ""); } } } } } pop_call(); return; } void do_sacrifice( CHAR_DATA *ch, char *argument ) { char arg1[MAX_INPUT_LENGTH]; OBJ_DATA *obj = NULL; OBJ_DATA *obj_next = NULL; bool found = FALSE; bool shrtd = FALSE; int amount = 1; int cnt = 0; push_call("do_sacrifice(%p,%p)",ch,argument); argument = one_argument( argument, arg1 ); if (is_number(arg1)) { amount = UMAX(1, atol(arg1)); argument = one_argument( argument, arg1 ); } if (*arg1 == 0) { send_to_char("Sacrifice what?\n\r", ch); pop_call(); return; } if (!check_blind(ch)) { pop_call(); return; } if (strcasecmp(arg1, "all") && str_prefix("all.", arg1)) { if ((obj = get_obj_list(ch, arg1, ch->in_room->first_content)) == NULL) { send_to_char( "You cannot find it.\n\r", ch ); pop_call(); return; } for ( ; shrtd <= 1 && !found ; shrtd++) { for (obj = ch->in_room->first_content ; obj ; obj = obj_next) { obj_next = obj->next_content; if (!can_see_obj(ch, obj)) { continue; } if (!shrtd && !is_name(arg1, obj->name)) { continue; } if (shrtd && !is_name_short(arg1, obj->name)) { continue; } found = TRUE; if (obj->first_content) { obj_next = NULL; } if (sacrifice_obj(ch, obj, NULL, TRUE)) { if (++cnt >= amount) { break; } } } } pop_call(); return; } else { for ( ; shrtd <= 1 && !found ; shrtd++) { for (obj = ch->in_room->first_content ; obj ; obj = obj_next) { obj_next = obj->next_content; if (!can_see_obj(ch, obj) || !IS_SET(obj->wear_flags, ITEM_TAKE)) { continue; } if (!shrtd && arg1[3] && !is_name(&arg1[4], obj->name)) { continue; } if (shrtd && arg1[3] && !is_name_short(&arg1[4], obj->name)) { continue; } found = TRUE; if (obj->first_content) { obj_next = NULL; } sacrifice_obj(ch, obj, NULL, TRUE); } } if (found == FALSE) { if (arg1[3] == '\0') { send_to_char( "You see nothing here.\n\r", ch ); } else { act( "You see no $T here.", ch, NULL, short_to_name(&arg1[4], 0), TO_CHAR ); } } } pop_call(); return; } void do_quaff( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; OBJ_DATA *obj; push_call("do_quaff(%p,%p)",ch,argument); if(IS_SET(ch->in_room->room_flags, ROOM_SAFE)) { send_to_char( "You cannot do that here.\n\r", ch); pop_call(); return; } if (!IS_NPC(ch) && ch->fighting && ch->class != CLASS_MARAUDER) { send_to_char( "You may not do that while fighting.\n\r", ch); pop_call(); return; } if( cspec_req(ch, CSPEC_NO_QUAFF)) { send_to_char( "You may not do that in your class.\n\r", ch); pop_call(); return; } one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Quaff what?\n\r", ch ); pop_call(); return; } if ( ( obj = get_obj_carry( ch, arg ) ) == NULL ) { send_to_char( "You do not have that potion.\n\r", ch ); pop_call(); return; } if ( obj->item_type != ITEM_POTION ) { send_to_char( "You can quaff only potions.\n\r", ch ); pop_call(); return; } if (obj->level > reinc_eq_level(ch)) { send_to_char( "You are too low a level to use that potion!\n\r", ch); pop_call(); return; } if (ch->fighting && number_percent() > get_curr_dex(ch) * 2) { act( "You break $p.", ch, obj, NULL ,TO_CHAR ); act( "$n breaks $p.", ch, obj, NULL, TO_ROOM ); } else { act( "You quaff $p.", ch, obj, NULL ,TO_CHAR ); act( "$n quaffs $p.", ch, obj, NULL, TO_ROOM ); obj_cast_spell( obj->value[1], obj->value[0], ch, ch, obj ); obj_cast_spell( obj->value[2], obj->value[0], ch, ch, obj ); obj_cast_spell( obj->value[3], obj->value[0], ch, ch, obj ); } junk_obj( obj ); wait_state( ch, PULSE_VIOLENCE*2/3); pop_call(); return; } void do_recite( CHAR_DATA *ch, char *argument ) { char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; CHAR_DATA *victim; OBJ_DATA *scroll; OBJ_DATA *obj; push_call("do_recite(%p,%p)",ch,argument); if (IS_SET(ch->in_room->room_flags, ROOM_SAFE)) { send_to_char( "You cannot do that here.\n\r", ch); pop_call(); return; } argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if ((scroll = get_obj_carry(ch, arg1)) == NULL) { send_to_char("You do not have that scroll.\n\r", ch); pop_call(); return; } if (scroll->item_type != ITEM_SCROLL) { send_to_char( "You can recite only scrolls.\n\r", ch ); pop_call(); return; } if (scroll->level > reinc_eq_level(ch)) { send_to_char( "You are too low a level to recite that scroll!\n\r", ch); pop_call(); return; } obj = NULL; if (arg2[0] == '\0') { victim = ch; } else { if ((victim = get_char_room (ch, arg2)) == NULL && (obj = get_obj_here(ch, arg2)) == NULL) { send_to_char("You cannot find it.\n\r", ch); pop_call(); return; } } if (ch->fighting && number_percent() > learned(ch, gsn_scroll_mastery)) { if (number_percent() > learned(ch, gsn_recite) / 4) { send_to_char("You tear the scroll in two in the heat of combat.\n\r", ch); junk_obj(scroll); pop_call(); return; } } else if (ch->fighting) { check_improve(ch, gsn_scroll_mastery); } else { if (number_percent() > learned(ch, gsn_recite)) { switch (number_bits(2)) { case 0: send_to_char("Something in your throat prevents you from reciting the proper phrase.\n\r", ch); break; case 1: send_to_char("You bumble your words causing the spell to fizzle\n\r", ch); break; case 2: send_to_char("You mispronounce a syllable.\n\r", ch); break; case 3: send_to_char("You hesitate mid-way through the reciting and nothing happens.\n\r", ch); break; } junk_obj(scroll); pop_call(); return; } check_improve(ch, gsn_recite); } act( "You recite $p.", ch, scroll, NULL, TO_CHAR ); act( "$n recites $p.", ch, scroll, NULL, TO_ROOM ); wait_state(ch, skill_table[gsn_recite].beats); obj_cast_spell(scroll->value[1], scroll->value[0], ch, victim, obj); obj_cast_spell(scroll->value[2], scroll->value[0], ch, victim, obj); obj_cast_spell(scroll->value[3], scroll->value[0], ch, victim, obj); junk_obj(scroll); pop_call(); return; } void do_brandish( CHAR_DATA *ch, char *argument ) { CHAR_DATA *vch; CHAR_DATA *vch_next; OBJ_DATA *staff; int sn; push_call("do_brandish(%p,%p)",ch,argument); if (IS_SET(ch->in_room->room_flags, ROOM_SAFE)) { send_to_char( "You cannot do that here.\n\r", ch); pop_call(); return; } if (!IS_NPC(ch) && (ch->fighting || ch->position == POS_FIGHTING)) { send_to_char( "You may not do that while fighting.\n\r", ch); pop_call(); return; } if( cspec_req(ch, CSPEC_NO_BRANDISH)) { send_to_char( "You may not do that in your class.\n\r", ch); pop_call(); return; } if ((staff = get_eq_char(ch, WEAR_HOLD)) == NULL) { send_to_char( "You hold nothing in your hand.\n\r", ch ); pop_call(); return; } if (staff->item_type != ITEM_STAFF) { send_to_char( "You can brandish only with a staff.\n\r", ch ); pop_call(); return; } if (staff->level > reinc_eq_level(ch)) { send_to_char( "You are too low a level to brandish that staff!\n\r", ch); pop_call(); return; } if ((sn = staff->value[3]) < 0 || sn >= MAX_SKILL || skill_table[sn].spell_fun == 0) { bug( "Do_brandish in staff %d: bad sn %d.", staff->pIndexData->vnum, sn ); pop_call(); return; } wait_state(ch, skill_table[gsn_brandish].beats); if (staff->value[2] > 0) { act( "You brandish $p.", ch, staff, NULL, TO_CHAR ); act( "$n brandishes $p.", ch, staff, NULL, TO_ROOM ); if (number_percent() > learned(ch, gsn_brandish)) { act("You fail to invoke $p.", ch, staff, NULL, TO_CHAR); act("...and nothing happens.", ch, staff, NULL, TO_ROOM); } else { for (vch = ch->in_room->first_person ; vch ; vch = vch_next) { vch_next = vch->next_in_room; switch (skill_table[sn].target) { default: bug("Do_brandish: bad target for sn %d.", sn); pop_call(); return; case TAR_IGNORE: if (vch != ch) { continue; } break; case TAR_CHAR_OFFENSIVE: if (!IS_NPC(vch) && who_fighting(ch) && ch->fighting->who != vch) { continue; } break; case TAR_CHAR_DEFENSIVE: if (IS_NPC(ch) ? !IS_NPC(vch) : IS_NPC(vch)) { continue; } break; case TAR_CHAR_SELF: if (vch != ch) { continue; } break; } obj_cast_spell(staff->value[3], staff->value[0], ch, vch, staff); } check_improve(ch, gsn_brandish); } } if (--staff->value[2] <= 0) { act( "Your $p blazes bright and is gone.", ch, staff, NULL, TO_CHAR ); act( "$n's $p blazes bright and is gone.", ch, staff, NULL, TO_ROOM ); junk_obj( staff ); } pop_call(); return; } void do_zap( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; OBJ_DATA *wand; OBJ_DATA *obj; push_call("do_zap(%p,%p)",ch,argument); if (IS_SET(ch->in_room->room_flags, ROOM_SAFE)) { send_to_char( "You cannot do that here.\n\r", ch); pop_call(); return; } if ((ch->fighting != NULL || ch->position == POS_FIGHTING)) { send_to_char( "You may not do that while fighting.\n\r", ch); pop_call(); return; } one_argument( argument, arg ); if ((wand = get_eq_char(ch, WEAR_HOLD)) == NULL) { send_to_char( "You hold nothing in your hand.\n\r", ch ); pop_call(); return; } if (wand->item_type != ITEM_WAND) { send_to_char( "You can zap only with a wand.\n\r", ch ); pop_call(); return; } if (arg[0] == '\0' && ch->fighting == NULL) { send_to_char( "Zap whom or what?\n\r", ch ); pop_call(); return; } obj = NULL; if (arg[0] == '\0') { if (ch->fighting != NULL) { victim = who_fighting(ch); } else { send_to_char( "Zap whom or what?\n\r", ch ); pop_call(); return; } } else { if ((victim = get_char_room (ch, arg)) == NULL && (obj = get_obj_here(ch, arg)) == NULL) { send_to_char( "You cannot find it.\n\r", ch ); pop_call(); return; } } wait_state(ch, skill_table[gsn_zap].beats); if (wand->value[2] > 0) { if (victim != NULL) { act( "You zap $N with $p.", ch, wand, victim, TO_CHAR ); act( "$n zaps $N with $p.", ch, wand, victim, TO_ROOM ); } else { act( "You zap $P with $p.", ch, wand, obj, TO_CHAR ); act( "$n zaps $P with $p.", ch, wand, obj, TO_ROOM ); } if (number_percent() > learned(ch, gsn_zap)) { act("Your efforts with $p produce only smoke and sparks.", ch, wand, NULL, TO_CHAR); act("$n's efforts with $p produce only smoke and sparks.", ch, wand, NULL, TO_ROOM); } else { obj_cast_spell(wand->value[3], wand->value[0], ch, victim, obj); check_improve(ch, gsn_zap); } } if (--wand->value[2] <= 0) { act( "Your $p explodes into fragments.", ch, wand, NULL, TO_CHAR ); act( "$n's $p explodes into fragments.", ch, wand, NULL, TO_ROOM ); junk_obj( wand ); } pop_call(); return; } void do_steal( CHAR_DATA *ch, char *argument ) { char buf [MAX_STRING_LENGTH]; char arg1 [MAX_INPUT_LENGTH]; char arg2 [MAX_INPUT_LENGTH]; CHAR_DATA *victim; OBJ_DATA *obj; int percent, lag; push_call("do_steal(%p,%p)",ch,argument); if (IS_SET(ch->in_room->room_flags, ROOM_SAFE)) { send_to_char( "You cannot do that here.\n\r", ch); pop_call(); return; } if (find_keeper(ch) != NULL) { send_to_char( "You cannot steal in a shop!\n\r", ch); pop_call(); return; } argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if (arg1[0] == '\0' || arg2[0] == '\0') { send_to_char( "Steal what from whom?\n\r", ch ); pop_call(); return; } if ((victim = get_char_room(ch, arg2)) == NULL) { send_to_char( "They aren't here.\n\r", ch ); pop_call(); return; } if (victim == ch) { send_to_char( "That's pointless.\n\r", ch ); pop_call(); return; } if (victim->fighting || victim->position == POS_FIGHTING) { send_to_char( "Your victim is moving so fast, you cannot steal from them!\n\r", ch); pop_call(); return; } if (!IS_NPC(victim) && (!IS_NPC(ch) || IS_AFFECTED(ch, AFF_CHARM))) { if (!can_attack( ch, victim )) { send_to_char( "You may not steal from them.\n\r", ch); pop_call(); return; } if (victim->hit < victim->max_hit / 2) { send_to_char( "They are too suspicious to allow a theft right now.\n\r", ch); pop_call(); return; } } if (IS_AFFECTED( victim, AFF_CHARM) ) { send_to_char( "You cannot steal from someone's pet.\n\r", ch); pop_call(); return; } if (check_recently_fought(ch, victim)) { ch_printf(ch, "%s was recently fought. Try later.\n\r", capitalize(victim->short_descr)); pop_call(); return; } if (!IS_NPC(victim) && number_percent() < learned(victim, gsn_guard)) { wait_state(ch, skill_table[gsn_steal].beats * 2); send_to_char("They notice your attempt and brush your hand away.\n\r", ch); act("$n just tried to steal $t from you.\n\r", ch, arg1, victim, TO_VICT); check_improve(victim, gsn_guard); pop_call(); return; } if (IS_AWAKE(victim)) { percent = number_range(1, 200) - victim->distracted; } else { percent = number_range(1, 100); } if (percent > learned(ch, gsn_steal)) { send_to_char( "Oops.\n\r", ch ); act( "$n tried to steal from you.\n\r", ch, NULL, victim, TO_VICT ); act( "$n tried to steal from $N.\n\r", ch, NULL, victim, TO_NOTVICT ); lag = victim->wait; sprintf( buf, "%s is a bloody thief!", get_name( ch ) ); do_shout( victim, buf ); victim->wait = lag; wait_state(ch, skill_table[gsn_steal].beats * 2); if (!IS_NPC(ch)) { if (IS_NPC(victim)) { multi_hit( victim, ch, TYPE_UNDEFINED ); } else if (!IS_NPC(ch)) { if (!IS_SET(ch->act, PLR_THIEF)) { SET_BIT(ch->act, PLR_THIEF); send_to_char( "*** You are now a THIEF!! ***\n\r", ch ); save_char_obj(ch, NORMAL_SAVE); } } } pop_call(); return; } wait_state(ch, skill_table[gsn_steal].beats); if ( !strcasecmp( arg1, "coin" ) || !strcasecmp( arg1, "coins" ) || !strcasecmp( arg1, "gold" ) ) { int amount; amount = victim->gold / number_range(10, 100); if (amount <= 0) { send_to_char( "You couldn't get any gold.\n\r", ch ); pop_call(); return; } ch->gold += amount; victim->gold -= amount; ch_printf(ch, "Bingo! You got %d gold coins.\n\r", amount ); if (!IS_NPC(victim) && number_percent() < victim->pcdata->learned[gsn_guard]) { act("You notice $n taking $s hand out of your gold collection.", ch,NULL,victim,TO_VICT); } check_improve(ch, gsn_steal); pop_call(); return; } if ((obj = get_obj_carry_even_invis(victim, arg1)) == NULL) { send_to_char( "You cannot find it.\n\r", ch ); pop_call(); return; } if ( !can_drop_obj( ch, obj ) || IS_SET(obj->extra_flags, ITEM_INVENTORY) || obj->item_type == ITEM_CONTAINER || obj->level > reinc_eq_level(ch)) { send_to_char( "You cannot pry it away.\n\r", ch ); pop_call(); return; } if (ch->carry_number >= can_carry_n(ch)) { send_to_char( "You have your hands full.\n\r", ch ); pop_call(); return; } if ( ch->carry_weight + get_obj_weight( obj ) > can_carry_w( ch ) ) { send_to_char( "You cannot carry that much weight.\n\r", ch ); pop_call(); return; } obj_from_char( obj ); obj_to_char( obj, ch ); send_to_char( "Ok.\n\r", ch ); if (!IS_NPC(victim) && number_percent() < victim->pcdata->learned[gsn_guard]) { act("You notice $n has your $p in $s hands.", ch,obj,victim,TO_VICT); } check_improve(ch, gsn_steal); pop_call(); return; } /* * Shopping commands. */ CHAR_DATA *find_keeper( CHAR_DATA *ch ) { CHAR_DATA *keeper; push_call("find_keeper(%p)",ch); for (keeper = ch->in_room->first_person ; keeper ; keeper = keeper->next_in_room) { if (IS_NPC(keeper) && keeper->pIndexData->pShop) { break; } } pop_call(); return keeper; } int get_cost( CHAR_DATA *keeper, OBJ_DATA *obj, bool fBuy ) { SHOP_DATA *pShop; int cost; push_call("get_cost(%p,%p,%p)",keeper,obj,fBuy); pShop = keeper->pIndexData->pShop; if (fBuy) { cost = obj->cost * pShop->profit_buy / 100; } else { OBJ_DATA *obj2; int itype; cost = 0; for (cost = itype = 0 ; itype < MAX_TRADE ; itype++) { if (obj->item_type == pShop->buy_type[itype]) { cost = obj->cost * pShop->profit_sell / 100; break; } } for (obj2 = keeper->first_carrying ; obj2 ; obj2 = obj2->next_content) { if (obj->pIndexData == obj2->pIndexData) { cost = (cost*9)/10; } } } pop_call(); return cost; } int bargain( CHAR_DATA *ch, int cost ) { push_call("bargain(%p,%p)",ch,cost); cost = cost * (100 - learned(ch, gsn_bargain) / 4) / 100; pop_call(); return UMAX(1, cost); } void do_buy( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; char buf[MAX_INPUT_LENGTH]; push_call("do_buy(%p,%p)",ch,argument); if (IS_NPC(ch)) { pop_call(); return; } argument = one_argument(argument, arg); if (arg[0] == '\0') { send_to_char("Buy what?\n\r", ch); pop_call(); return; } if (IS_SET(ch->in_room->room_flags, ROOM_PET_SHOP)) { CHAR_DATA *keeper; CHAR_DATA *pet; ROOM_INDEX_DATA *pRoomIndexNext; ROOM_INDEX_DATA *in_room; if (IS_NPC(ch)) { pop_call(); return; } if ((keeper = find_keeper(ch)) == NULL) { send_to_char("There is nothing for sale here.\n\r",ch); pop_call(); return; } pRoomIndexNext = get_room_index(ch->in_room->vnum + 1); if (pRoomIndexNext == NULL) { bug("Do_buy: bad pet shop at vnum %u.", ch->in_room->vnum); send_to_char("There is nothing for sale here.\n\r", ch); pop_call(); return; } if (get_pets(ch) > 0) { ch_printf(ch, "%s%s tells you 'Sorry, only one pet at a time.'\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr)); pop_call(); return; } in_room = ch->in_room; char_from_room(ch); char_to_room(ch, pRoomIndexNext->vnum); pet = get_char_room(ch, arg); char_from_room(ch); char_to_room(ch, in_room->vnum); if (pet == NULL || pet->reset == NULL || pet->reset->arg3 != pRoomIndexNext->vnum) { ch_printf(ch, "%s%s tells you 'Sorry, you cannot buy that here.'\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr)); pop_call(); return; } if (ch->gold < bargain(ch, pet->level * pet->level * 100)) { ch_printf(ch, "%s%s tells you 'Sorry, you cannot afford that pet.'\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr)); pop_call(); return; } if (ch->level < pet->level) { ch_printf(ch, "%s%s tells you 'Sorry, you're not ready for that pet.'\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr)); pop_call(); return; } ch->gold -= bargain(ch, pet->level * pet->level * 100); pet = create_mobile( pet->pIndexData ); SET_BIT(pet->affected_by, AFF_CHARM); argument = one_argument(argument, arg); sprintf(buf, "%sA neck tag says 'I belong to %s'.\n\r", pet->description, get_name(ch)); STRFREE(pet->description ); pet->description = STRALLOC( buf ); char_to_room( pet, ch->in_room->vnum ); add_follower( pet, ch ); ch_printf(ch, "%s%s tells you 'Enjoy your pet.'\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr)); act( "$n bought $N as a pet.", ch, NULL, pet, TO_ROOM ); check_improve(ch, gsn_bargain); pop_call(); return; } else { CHAR_DATA *keeper; OBJ_DATA *obj, *found_obj; int cost, amount, total_cost, cnt; obj = NULL; found_obj = NULL; amount = 1; if ((keeper = find_keeper(ch)) == NULL) { send_to_char("There is nothing to purchase here.\n\r", ch); pop_call(); return; } /* handle morgue buying corpses */ if (!IS_NPC(ch) && IS_SET(ch->in_room->room_flags, ROOM_MORGUE) && is_name("corpse", arg)) { if ((obj = find_char_corpse(ch, FALSE)) != NULL) { if (obj->in_room == ch->in_room) { ch_printf(ch,"%s%s tells you 'But you have already bought your corpse!'\n\r", get_color_string(ch, COLOR_SPEACH, VT102_BOLD), capitalize(keeper->short_descr)); pop_call(); return; } cost = bargain(ch, obj->value[3]); ch_printf(ch,"%s%s tells you 'That'll be %d gold coins.'\n\r",get_color_string(ch, COLOR_SPEACH, VT102_BOLD), capitalize(keeper->short_descr), cost); if (cost > ch->gold) { ch_printf(ch,"%s%s tells you 'I'm afraid you cannot afford to buy your corpse.'\n\r",get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr)); pop_call(); return; } ch->gold -= cost; act("$n disappears and returns with your corpse.", keeper, NULL, ch, TO_VICT); act("$n disappears and returns with $N's corpse.", keeper, NULL, ch, TO_NOTVICT); ch->pcdata->corpse_room = ch->in_room->vnum; obj_to_room(obj, ch->in_room->vnum); save_char_obj(ch, NORMAL_SAVE); pop_call(); return; } else { ch_printf(ch, "%s%s tells you 'You don't have any corpses here, go make one!'\n\r",get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr)); pop_call(); return; } } if (is_number(arg) && argument[0] != '\0') { amount = UMAX(1, atol(arg)); strcpy(arg, argument); } if ((obj = get_obj_carry_keeper(keeper, arg, ch)) == NULL) { ch_printf(ch, "%s%s tells you 'I cannot sell you a %s.'\n\r",get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr), arg); pop_call(); return; } if (mud->time_info->hour < keeper->pIndexData->pShop->open_hour || mud->time_info->hour > keeper->pIndexData->pShop->close_hour) { int open = keeper->pIndexData->pShop->open_hour; int close = keeper->pIndexData->pShop->close_hour; ch_printf(ch, "%s%s tells you 'Sorry, my shop is closed.'\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr)); ch_printf(ch, "%s%s tells you 'I'll be open from %d %s till %d %s.'\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr), open % 12 != 0 ? open % 12 : 12, open >= 12 ? "pm" : "am", close % 12 != 0 ? close % 12 : 12, close >= 12 ? "pm" : "am"); pop_call(); return; } if ( !can_see( keeper, ch ) ) { sprintf(buf, "%s%s says 'I don't trade with folks I cannot see.'", get_color_code(ch, COLOR_SPEACH, VT102_DIM), capitalize(keeper->short_descr)); act(buf, keeper, NULL, NULL, TO_ROOM); pop_call(); return ; } cost = bargain(ch, get_cost(keeper, obj, TRUE)); if (ch->gold < cost) { ch_printf(ch, "%s%s tells you 'You cannot afford to buy %s.'\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr), obj->short_descr); pop_call(); return; } if (obj->level > reinc_eq_level(ch)) { ch_printf(ch, "%s%s tells you 'You cannot use %s yet.'\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr), obj->short_descr); pop_call(); return; } if (ch->carry_number >= can_carry_n(ch)) { send_to_char("You cannot carry that many items.\n\r", ch); pop_call(); return; } if (ch->carry_weight + get_obj_weight(obj) > can_carry_w(ch)) { send_to_char("You cannot carry that much weight.\n\r", ch); pop_call(); return; } found_obj = obj; for (total_cost = cnt = 0 ; cnt < amount ; cnt++) { if ((obj = get_obj_carry_keeper(keeper, arg, ch)) == NULL) { break; } if (ch->gold < total_cost + cost) { break; } if (ch->carry_number >= can_carry_n(ch)) { break; } if (ch->carry_weight + get_obj_weight(obj) > can_carry_w(ch)) { break; } if (obj->reset) { obj = create_object(obj->pIndexData, 0); } obj_to_char(obj, ch); total_cost += cost; } if (amount == 1) { ch_printf(ch, "You buy %s for %d gold.\n\r", obj->short_descr, total_cost); act("$n buys $p.", ch, found_obj, NULL, TO_ROOM); } else { ch_printf(ch, "You buy %d %s for %d gold.\n\r", cnt, short_to_name(found_obj->short_descr, cnt), total_cost); sprintf(buf, "$n buys %d %s.", cnt, short_to_name(found_obj->short_descr, cnt)); act(buf, ch, found_obj, NULL, TO_ROOM); } ch->gold -= total_cost; check_improve(ch, gsn_bargain); pop_call(); return; } } void do_list( CHAR_DATA *ch, char *argument ) { push_call("do_list(%p,%p)",ch,argument); if (IS_SET(ch->in_room->room_flags, ROOM_PET_SHOP)) { ROOM_INDEX_DATA *pRoomIndexNext; CHAR_DATA *pet; CHAR_DATA *keeper; bool found; if ((keeper = find_keeper(ch)) == NULL) { send_to_char( "There is nothing to purchase here.\n\r", ch); pop_call(); return; } pRoomIndexNext = get_room_index(ch->in_room->vnum + 1); if (pRoomIndexNext == NULL) { bug("do_list: bad pet shop at vnum %u.", ch->in_room->vnum); send_to_char("You cannot do that here.\n\r", ch); pop_call(); return; } found = FALSE; for (pet = pRoomIndexNext->first_person ; pet ; pet = pet->next_in_room) { if (pet->reset != NULL && pet->reset->arg3 == pRoomIndexNext->vnum) { if (!found ) { found = TRUE; ch_printf_color(ch, "{178}[{078}Level {018}Price {178}] {138}Pet\n\r"); } ch_printf_color(ch, "{178}[{078}%2d {018}%8d {178}] {138}%s.\n\r", pet->level, bargain(ch, pet->level * pet->level * 100), capitalize(pet->short_descr)); } } if (!found) { ch_printf(ch, "%s%s tells you 'Sorry, I'm all out of pets right now.\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr)); } pop_call(); return; } else { char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; CHAR_DATA *keeper; OBJ_DATA *obj, *oobj; int nrL, nrH, cost; bool found; cost = 0; found = FALSE; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if ((keeper = find_keeper(ch)) == NULL) { send_to_char( "There is nothing to purchase here.\n\r", ch); pop_call(); return; } if (!strcasecmp(arg1, "all")) { nrL = 1; nrH = 150; } else { nrL = 1; nrH = reinc_eq_level(ch); } if (is_number(arg1)) { nrL = URANGE(1, atol(arg1), 95); if (is_number(arg2)) { nrH = URANGE(nrL, atol(arg2), 95); } } for (obj = keeper->first_carrying ; obj ; obj = obj->next_content) { if (obj->wear_loc == WEAR_NONE && can_see_obj(ch, obj) && obj->level >= nrL && obj->level <= nrH && (cost = bargain(ch, get_cost(keeper, obj, TRUE))) > 0) { if (!found) { found = TRUE; ch_printf_color(ch, "{178} [{078}Level {018}Price {178}] {138}Item\n\r"); } for (oobj = keeper->first_carrying ; oobj != obj ; oobj = oobj->next_content) { if (oobj->wear_loc == WEAR_NONE && can_see_obj(ch, oobj) && oobj->level >= nrL && oobj->level <= nrH && get_cost(keeper, oobj, TRUE) > 0) { if (oobj->pIndexData->vnum == obj->pIndexData->vnum && !IS_SET(obj->extra_flags, ITEM_MODIFIED)) { break; } } } if (obj == oobj) { ch_printf_color(ch, "{178} [{078}%2d {018}%8d {178}]{138} %s.\n\r", obj_eq_level(ch, obj), cost, capitalize(obj->short_descr)); } } } if (IS_SET(ch->in_room->room_flags, ROOM_MORGUE) && (obj = find_char_corpse(ch, FALSE)) != NULL) { if (!found) { ch_printf_color(ch, "{178} [{078}Lv {018}Price {178}] {138}Item\n\r"); } ch_printf_color(ch, "{178} [{078}%2d {018}%8d {178}] {138}%s.\n\r", obj->level, bargain(ch, obj->value[3]), capitalize(obj->short_descr)); } else if (!found) { ch_printf_color(ch, "%s%s tells you 'Sorry, I have nothing here you would want.'\n\r", get_color_string(ch, COLOR_SPEACH, VT102_BOLD), capitalize(keeper->short_descr)); } pop_call(); return; } } void do_sell( CHAR_DATA *ch, char *argument ) { char buf[MAX_STRING_LENGTH]; char arg[MAX_INPUT_LENGTH]; CHAR_DATA *keeper; OBJ_DATA *obj; int cost; int sell_bargain; push_call("do_sell(%p,%p)",ch,argument); sell_bargain = 100 + learned(ch, gsn_bargain) / 4; one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Sell what?\n\r", ch ); pop_call(); return; } if ((keeper = find_keeper(ch)) == NULL) { send_to_char("You cannot do that here.\n\r", ch); pop_call(); return; } if ((obj = get_obj_carry(ch,arg)) == NULL) { ch_printf(ch, "%s%s tells you 'You don't have that item.'\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr)); pop_call(); return; } if (mud->time_info->hour < keeper->pIndexData->pShop->open_hour || mud->time_info->hour > keeper->pIndexData->pShop->close_hour) { ch_printf(ch, "%s%s tells you 'Sorry, my shop is closed.'\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr)); ch_printf(ch, "%s%s tells you 'I'll be open from %d %s till %d %s.'\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr), keeper->pIndexData->pShop->open_hour %12, keeper->pIndexData->pShop->open_hour < 11 ? "am" : "pm", keeper->pIndexData->pShop->close_hour%12, keeper->pIndexData->pShop->close_hour < 11 ? "am" : "pm"); pop_call(); return; } if (!can_see(keeper, ch)) { sprintf(buf, "%s%s says 'I don't trade with folks I cannot see!'", get_color_code(ch, COLOR_SPEACH, VT102_DIM), capitalize(keeper->short_descr)); act(buf, keeper, NULL, NULL, TO_ROOM); pop_call(); return ; } if (!can_drop_obj(ch, obj)) { send_to_char( "You cannot let go of it.\n\r", ch ); pop_call(); return; } if (obj->owned_by) { send_to_char( "You cannot sell personalized equipment.\n\r", ch ); pop_call(); return; } if ((cost = sell_bargain * get_cost(keeper, obj, FALSE) / 100) < 1) { act( "$n looks uninterested in $p.", keeper, obj, ch, TO_VICT ); pop_call(); return; } if (IS_SET(obj->extra_flags, ITEM_MODIFIED)) { act( "$n looks uninterested in $p.", keeper, obj, ch, TO_VICT ); pop_call(); return; } sprintf(buf, "You sell $p for %d gold %s.", cost, short_to_name("coin", cost)); act( buf, ch, obj, NULL, TO_CHAR ); act( "$n sells $p.", ch, obj, NULL, TO_ROOM ); give_gold(ch, cost); obj_to_char(obj, keeper); check_improve(ch, gsn_bargain); pop_call(); return; } void do_value( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *keeper; OBJ_DATA *obj; int cost; int sell_bargain; push_call("do_value(%p,%p)",ch,argument); sell_bargain = 100 + learned(ch, gsn_bargain) / 4; one_argument( argument, arg ); if (arg[0] == '\0') { send_to_char("Value what?\n\r", ch); pop_call(); return; } if ((keeper = find_keeper(ch)) == NULL) { send_to_char("You cannot do that here.\n\r",ch); pop_call(); return; } if ((obj = get_obj_carry(ch, arg)) == NULL) { ch_printf(ch, "%s%s tells you 'You don't have that item.'\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr)); pop_call(); return; } if (!can_drop_obj(ch, obj)) { send_to_char( "You cannot let go of it.\n\r", ch ); pop_call(); return; } if ((cost = sell_bargain * get_cost(keeper, obj, FALSE) / 100) < 1 || IS_SET(obj->extra_flags, ITEM_MODIFIED)) { act( "$n looks uninterested in $p.", keeper, obj, ch, TO_VICT ); pop_call(); return; } ch_printf(ch, "%s%s tells you 'I'll give you %d gold coins for %s.'\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr), cost, obj->short_descr); pop_call(); return; } void do_evaluate( CHAR_DATA *ch, char *argument ) { char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; char msg [MAX_INPUT_LENGTH]; CHAR_DATA *keeper; OBJ_DATA *obj1; OBJ_DATA *obj2; int value1; int value2; push_call("do_evaluate(%p,%p)",ch,argument); argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if ((keeper = find_keeper(ch)) == NULL) { send_to_char("You cannot do that here.\n\r", ch); pop_call(); return; } if ( arg1[0] == '\0' ) { send_to_char( "Evaluate what to what?\n\r", ch ); pop_call(); return; } if ((obj1 = get_obj_carry_keeper(keeper, arg1, ch)) == NULL) { ch_printf(ch, "%s%s tells you 'I don't have a %s.'\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr), arg1); pop_call(); return; } if (arg2[0] == '\0') { for (obj2 = ch->first_carrying ; obj2 ; obj2 = obj2->next_content) { if (obj2->wear_loc != WEAR_NONE && can_see_obj(ch, obj2) && obj1->wear_flags == obj2->wear_flags) { break; } } if (obj2 == NULL) { ch_printf(ch, "%s%s tells you 'You aren't wearing anything similar.'\n\r", get_color_string(ch, COLOR_SPEACH, VT102_BOLD), capitalize(keeper->short_descr)); pop_call(); return; } } else { if ((obj2 = get_obj_carry(ch, arg2)) == NULL) { send_to_char("You do not have that item.\n\r", ch); pop_call(); return; } } value1 = obj_level_estimate(obj1->pIndexData); value2 = obj_level_estimate(obj2->pIndexData); if ( value1 == value2 ) { sprintf(msg, "%s and %s look about the same.", obj1->short_descr, obj2->short_descr); } else if ( value1 > value2 ) { sprintf(msg, "%s looks better than %s.", obj1->short_descr, obj2->short_descr); } else { sprintf(msg, "%s looks worse than %s.", obj1->short_descr, obj2->short_descr); } ch_printf(ch, "%s%s tells you '%s'\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr), msg); pop_call(); return; } void do_snatch( CHAR_DATA *ch, char *argument ) { bool snatched; int cnt; push_call("do_snatch(%p,%p)",ch,argument); if (!check_blind(ch)) { pop_call(); return; } cnt = multi( ch, gsn_snatch ); if ( cnt == -1 ) { send_to_char( "You cannot snatch things.\n\r", ch ); pop_call(); return; } if (argument[0] == '\0') { send_to_char("Snatch what?\n\r",ch); pop_call(); return; } if (IS_SET(ch->in_room->room_flags, ROOM_SAFE)) { send_to_char( "You cannot do that here.\n\r", ch); pop_call(); return; } if (multi(ch,gsn_snatch)==-1 && !IS_NPC(ch)) { pop_call(); return; } snatched = number_percent() < learned(ch, gsn_snatch); if (snatched) { SET_BIT(mud->flags, MUD_SKIPOUTPUT); } do_get(ch, argument); if (snatched) { REMOVE_BIT(mud->flags, MUD_SKIPOUTPUT); ch_printf(ch, "Your snatch was unseen by human eyes.\n\r"); check_improve(ch, gsn_snatch); } pop_call(); return; } void do_identify( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; push_call("do_identify(%p,%p)",ch,argument); argument = one_argument( argument, arg ); { CHAR_DATA *keeper; OBJ_DATA *obj; int cost; if ((keeper = find_keeper(ch)) == NULL) { send_to_char( "You must be in a shop to have items identified.\n\r", ch ); pop_call(); return; } if (arg[0] == '\0') { send_to_char( "Have what identified?\n\r", ch ); pop_call(); return; } if (ch->in_room->vnum == ROOM_VNUM_IDENTIFY) { if ((obj = get_obj_here(ch, arg)) == NULL) { ch_printf(ch, "%s%s tells you 'You don't seem to have a '%s' on you.'\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr), arg); pop_call(); return; } } else { if ((obj = get_obj_carry_keeper(keeper, arg, ch)) == NULL) { ch_printf(ch, "%s%s tells you 'I cannot identify a %s for you.'\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr), arg); pop_call(); return; } } cost = bargain(ch, get_cost(keeper, obj, TRUE)); if (cost < 1) { ch_printf(ch, "%s%s tells you 'I cannot identify a %s for you.'\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr), arg); pop_call(); return; } cost = URANGE(10, cost / 10, 10000); if (ch->gold < cost) { ch_printf(ch, "%s%s tells you 'It costs you %d gold to identify %s.'\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr), cost, obj->short_descr); pop_call(); return; } if (obj->level > reinc_eq_level(ch)) { ch_printf(ch, "%s%s tells you 'You cannot use %s yet.'\n\r", get_color_string(ch,COLOR_SPEACH,VT102_BOLD), capitalize(keeper->short_descr), obj->short_descr); pop_call(); return; } act( "You have $p identified.", ch, obj, NULL, TO_CHAR ); act( "$n has $p identified.", ch, obj, NULL, TO_ROOM ); ch->gold -= cost; keeper->gold += cost; spell_identify(0, keeper->level, ch, obj, TAR_OBJ_INV); pop_call(); return; } } OBJ_DATA * find_char_corpse (CHAR_DATA *ch, bool method) { OBJ_DATA *corpse; push_call("find_char_corpse(%p,%p)",ch,method); /* find the player's first corpse with objects in it */ if (method) { for (corpse = obj_index[OBJ_VNUM_CORPSE_PC]->first_instance ; corpse ; corpse = corpse->next_instance) { if (corpse->first_content && corpse->owned_by == ch->pcdata->pvnum && !IS_SET(corpse->extra_flags, ITEM_NOT_VALID)) { break; } } } else { corpse = ch->pcdata->corpse; } if (corpse != NULL) { OBJ_DATA *obj; if (ch->level <= 25) { corpse->value[3] = ch->level * ch->level * 65; } else { corpse->value[3] = ch->level * ch->level * ch->level; for (obj = corpse->first_content ; obj ; obj = obj->next_content) { corpse->value[3] += obj->cost / 10; } } } pop_call(); return corpse; } void do_engrave( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; OBJ_DATA *obj; AFFECT_DATA *paf; int cost, stat; push_call("do_engrave(%p,%p)",ch,argument); if (IS_NPC(ch)) { pop_call(); return; } if (ch->in_room->vnum != ROOM_VNUM_BLACKSMITH) { send_to_char( "You are not at the blacksmith.\n\r", ch); pop_call(); return; } if (argument[0] == '\0') { send_to_char( "You must engrave an object.\n\r", ch); pop_call(); return; } obj = get_obj_here(ch, argument); if (obj == NULL) { send_to_char( "You do not have that object.\n\r", ch); pop_call(); return; } if (obj->owned_by) { send_to_char( "You cannot engrave that object.\n\r", ch); pop_call(); return; } if (ch->level < 10) { send_to_char( "You are not experienced enough to engrave objects.\n\r", ch); pop_call(); return; } stat = 1; cost = 10000; if (ch->level > 25) { stat = 2; cost = 100000; } if (ch->level > 45) { stat = 3; cost = 1000000; } if (ch->level > 70) { stat = 4; cost = 10000000; } cost = bargain(ch, cost); if (ch->gold < cost) { send_to_char( "You do not have enough gold to engrave objects.\n\r", ch); pop_call(); return; } switch(obj->item_type) { case ITEM_ARMOR: ALLOCMEM(paf, AFFECT_DATA, 1); paf->location = APPLY_AC; paf->modifier = 0-stat; paf->type = skill_lookup( "enhance object" ); paf->duration = -1; paf->bitvector = 0; LINK( paf, obj->first_affect, obj->last_affect, next, prev ); break; case ITEM_WEAPON: ALLOCMEM(paf, AFFECT_DATA, 1); paf->location = APPLY_HITROLL; paf->modifier = stat; paf->type = skill_lookup( "enhance object" ); paf->duration = -1; paf->bitvector = 0; LINK( paf, obj->first_affect, obj->last_affect, next, prev ); break; case ITEM_CONTAINER: obj->value[0] += stat * 100; obj->value[3] += obj->value[3] ? stat*10 : MAX_OBJECTS_IN_CONTAINER + stat*10; break; default: send_to_char( "You cannot engrave that kind of an object.\n\r", ch); pop_call(); return; } SET_BIT(obj->extra_flags, ITEM_MODIFIED); obj->owned_by = ch->pcdata->pvnum; ch->gold -= cost; sprintf( arg, "%s of %s", obj->pIndexData->short_descr, capitalize( ch->name )); STRFREE(obj->short_descr ); obj->short_descr = STRALLOC( arg ); char_reset( ch ); send_to_char( "It is engraved.\n\r", ch); pop_call(); return; } int wear_flags_to_wear_loc( OBJ_DATA *obj, int last) { push_call("wear_flags_to_wear_loc(%p,%p)",obj,last); if( last == 1 || last<1 ) { if( (obj->wear_flags & 2) == 2) { pop_call(); return( 1 ); } } if( last == 2 || last<1 ) { if( (obj->wear_flags & 2) == 2) { pop_call(); return( 2 ); } } if( last == 3 || last<1 ) { if( (obj->wear_flags & 4) == 4) { pop_call(); return( 3 ); } } if( last == 4 || last<1 ) { if( (obj->wear_flags & 4) == 4) { pop_call(); return( 4 ); } } if( last == 5 || last<1 ) { if( (obj->wear_flags & 8) == 8) { pop_call(); return( 5 ); } } if( last == 6 || last<1 ) { if( (obj->wear_flags & 16) == 16) { pop_call(); return( 6 ); } } if( last == 7 || last<1 ) { if( (obj->wear_flags & 32) == 32) { pop_call(); return( 7 ); } } if( last == 8 || last<1 ) { if( (obj->wear_flags & 64) == 64) { pop_call(); return( 8 ); } } if( last == 9 || last<1 ) { if( (obj->wear_flags & 128) == 128) { pop_call(); return( 9 ); } } if( last == 10 || last<1 ) { if( (obj->wear_flags & 256) == 256) { pop_call(); return( 10 ); } } if( last == 11 || last<1 ) { if( (obj->wear_flags & 512) == 512) { pop_call(); return( 11 ); } } if( last == 12 || last<1 ) { if( (obj->wear_flags & 1024) == 1024) { pop_call(); return( 12 ); } } if( last == 13 || last<1 ) { if( (obj->wear_flags & 2048) == 2048) { pop_call(); return( 13 ); } } if( last == 14 || last<1 ) { if( (obj->wear_flags & 4096) == 4096) { pop_call(); return( 14 ); } } if( last == 15 || last<1 ) { if( (obj->wear_flags & 4096) == 4096) { pop_call(); return( 15 ); } } if( last == 16 || last<1 ) { if( (obj->wear_flags & 8192) == 8192) { pop_call(); return( 16 ); } } if( last == 17 || last<1 ) { if( (obj->wear_flags & 16384) == 16384) { pop_call(); return( 17 ); } } pop_call(); return( -1 ); } void do_plant( CHAR_DATA *ch, char *argument ) { char arg1 [MAX_INPUT_LENGTH]; char arg2 [MAX_INPUT_LENGTH]; CHAR_DATA *victim; OBJ_DATA *obj; push_call("do_plant(%p,%p)",ch,argument); if (!IS_NPC(ch) && who_fighting(ch) && !IS_NPC(ch->fighting->who)) { send_to_char( "You are too busy to plant anything on someone.\n\r", ch ); pop_call(); return; } argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if (arg1[0] == '\0' || arg2[0] == '\0') { send_to_char( "Plant what on whom?\n\r", ch ); pop_call(); return; } if (learned(ch, gsn_plant) == 0) { send_to_char( "They would just get mad at you.\n\r", ch); pop_call(); return; } if ((obj = get_obj_carry(ch, arg1)) == NULL) { send_to_char( "You do not have that item.\n\r", ch ); pop_call(); return; } if (obj->wear_loc != WEAR_NONE) { send_to_char( "You must remove it first.\n\r", ch ); pop_call(); return; } if ((victim = get_char_room(ch, arg2)) == NULL) { send_to_char( "They aren't here.\n\r", ch ); pop_call(); return; } if (!can_drop_obj(ch, obj)) { send_to_char( "You cannot let go of it.\n\r", ch ); pop_call(); return; } if (find_keeper(ch) == victim) { send_to_char( "You may only sell items to a shop keeper.\n\r", ch ); pop_call(); return; } if (victim->carry_weight + get_obj_weight(obj) > can_carry_w(victim)) { act( "$N cannot carry that much weight.", ch, NULL, victim, TO_CHAR ); pop_call(); return; } if (!can_attack(ch, victim)) { send_to_char( "You should leave them alone.\n\r", ch); pop_call(); return; } obj_from_char( obj ); obj_to_char( obj, victim ); act( "You attempt to plant $p on $N.", ch, obj, victim, TO_CHAR ); if (number_percent() > learned(ch, gsn_plant)) { act( "$n tries to plant $p on $N.", ch, obj, victim, TO_NOTVICT ); act( "$n plants $p on you!", ch, obj, victim, TO_VICT ); send_to_char("ACK!!! You were seen!\n\r",ch); } else { check_improve(ch, gsn_plant); } pop_call(); return; } void do_forge( CHAR_DATA *ch, char *argument ) { char arg1 [MAX_INPUT_LENGTH]; OBJ_DATA *obj; push_call("do_forge(%p,%p)",ch,argument); if (!IS_NPC(ch) && who_fighting(ch) && !IS_NPC( ch->fighting->who )) { send_to_char( "You are too busy to forge anything!\n\r", ch ); pop_call(); return; } argument = one_argument( argument, arg1 ); if (strlen(argument) > 50) { *(argument+50) = '\0'; } if ( arg1[0] == '\0' || argument[0] == '\0' ) { send_to_char( "Forge what item into what?\n\r", ch ); pop_call(); return; } if ((obj = get_obj_carry(ch, arg1)) == NULL) { send_to_char( "You do not have that item.\n\r", ch ); pop_call(); return; } wait_state( ch, skill_table[gsn_forge].beats ); if (obj->owned_by) { send_to_char("You cannot forge personalized equipment.\n\r", ch); pop_call(); return; } if (!IS_NPC(ch) && number_percent() >= learned(ch, gsn_forge)) { if (number_percent() < 50) { act("Your attempt at forgery has destroyed $p.",ch,obj,NULL,TO_CHAR); junk_obj(obj); } else { act("Your attempt at forgery has failed.",ch,obj,NULL,TO_CHAR); } wait_state( ch, skill_table[gsn_forge].beats ); } else if (IS_OBJ_STAT(obj, ITEM_FORGERY)) { send_to_char("That object is already a forgery!\n\r",ch); } else { int i; smash_tilde( argument ); if (!strcasecmp(argument, "all")) { send_to_char( "You cannot forge something into that.\n\r", ch); pop_call(); return; } if (!str_infix(" all", argument) || !str_infix("all ", argument)) { send_to_char( "You cannot forge something into that.\n\r", ch); pop_call(); return; } /* only allowing alphas now - Scandum */ for (i = 0 ; argument[i] != '\0' ; i++) { if (ispunct(argument[i]) || isdigit(argument[i])) { send_to_char("You cannot forge something into that.\n\r", ch ); log_printf("Bad forge attempt by %s: %s", ch->name, argument); pop_call(); return; } } wait_state( ch, skill_table[gsn_forge].beats ); /* Place i<vnum> back in the name list - Scandum */ sprintf(arg1, "%s i%u", argument, obj->pIndexData->vnum); RESTRING(obj->name, arg1); RESTRING(obj->short_descr, argument); sprintf(arg1, "%s is here.", capitalize(argument)); RESTRING(obj->long_descr, arg1); RESTRING(obj->description, ""); SET_BIT(obj->extra_flags,ITEM_FORGERY); send_to_char("You sit down, take your time...and make a decent forgery.\n\r",ch); check_improve(ch, gsn_forge); } pop_call(); return; } void do_make_poison( CHAR_DATA *ch, char *argument ) { char arg1 [MAX_INPUT_LENGTH]; char arg2 [MAX_INPUT_LENGTH]; OBJ_DATA *obj; int idmgL, idmgH, cdmgL, cdmgH, cdurL, cdurH, ptype, level; POISON_DATA *pd; push_call("do_make_poison(%p,%p)",ch,argument); idmgL = idmgH = cdmgL = cdmgH = cdurL = cdurH = 0; if (!IS_NPC(ch) && multi(ch, gsn_make_poison) == -1) { send_to_char( "You never learned to make poisons.\n\r", ch ); pop_call(); return; } argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if (*arg1 != 'm' && *arg1 != 'c') { send_to_char( "Make what kind of poison? Clear or murky?\n\r", ch ); pop_call(); return; } if (*arg2 != 'p' && *arg2 != 'b' && *arg2 != 'g') { send_to_char( "Make what color of poison? Blue, purple, or green?\n\r", ch ); pop_call(); return; } if ((obj = get_obj_wear(ch, argument)) == NULL) { if ((obj = get_obj_carry(ch, argument)) == NULL) { send_to_char( "You do not have that item.\n\r", ch ); pop_call(); return; } } if (obj->poison != NULL) { send_to_char( "That object is already poisoned.\n\r", ch ); pop_call(); return; } level = UMIN(obj->level, multi_skill_level(ch, gsn_make_poison)); /* (Reminder) shoot and eat don't check poison yet - Scandum */ if (obj->item_type != ITEM_WEAPON && obj->item_type != ITEM_AMMO) { send_to_char( "That item is not a weapon or arrow.\n\r", ch ); pop_call(); return; } wait_state( ch, skill_table[gsn_make_poison].beats ); if (*arg2 == 'b') { ptype ='B'; idmgL = 0; idmgH = 0; cdmgL = level/3; cdmgH = 2*level/3; cdurL = 4; cdurH = 8; } else if (*arg2 == 'p') { ptype ='P'; idmgL = 3*level/2; idmgH = 3*level; cdmgL = 0; cdmgH = 0; cdurL = 0; cdurH = 0; } else { ptype ='G'; idmgL = level; idmgH = 3*level/2; cdmgL = level/5; cdmgH = level/2; cdurL = 2; cdurH = 4; } if (number_percent() > learned(ch, gsn_make_poison)) { send_to_char( "You poison yourself!\n\r", ch ); ALLOCMEM(pd, POISON_DATA, 1); pd->next = ch->poison; ch->poison = pd; pd->for_npc = FALSE; pd->poison_type = ptype; pd->instant_damage_low = idmgL; pd->instant_damage_high = idmgH; pd->constant_damage_low = cdmgL; pd->constant_damage_high = cdmgH; pd->constant_duration = number_range( cdurL, cdurH ); pd->poisoner = ch->pcdata->pvnum; pd->owner = ch->pcdata->pvnum; pop_call(); return; } if (obj->item_type == ITEM_AMMO) { idmgL /= 2; idmgH /= 2; cdmgL /= 3; cdmgH /= 3; cdurL /= 2; cdurH /= 2; } ch_printf(ch, "You make a %s %s poison and place it on %s.\n\r", (*arg1 == 'c') ? "clear" : "murky", (*arg2 == 'p') ? "purple" : (*arg2 == 'g') ? "green" : "blue", obj->short_descr ); SET_BIT(obj->extra_flags, ITEM_MODIFIED); ALLOCMEM(pd, POISON_DATA, 1); pd->next = NULL; obj->poison = pd; pd->for_npc = (*arg1 == 'c') ? FALSE : TRUE; pd->poison_type = ptype; pd->instant_damage_low = idmgL; pd->instant_damage_high = idmgH; pd->constant_damage_low = cdmgL; pd->constant_damage_high = cdmgH; pd->constant_duration = number_range( cdurL, cdurH ); pd->owner = IS_NPC(ch) ? 0 : ch->pcdata->pvnum; pd->poisoner = IS_NPC(ch) ? 0 : ch->pcdata->pvnum; check_improve(ch, gsn_make_poison); pop_call(); return; } void do_make_flash( CHAR_DATA *ch, char *argument ) { push_call("do_make_flash(%p,%p)",ch,argument); if (!IS_NPC(ch) && multi(ch, gsn_flash_powder) == -1) { send_to_char( "You cannot make flash powder.\n\r", ch ); pop_call(); return; } if (IS_AFFECTED(ch, AFF2_HAS_FLASH)) { send_to_char( "You already have some flash powder hidden away.\n\r",ch); pop_call(); return; } if (IS_NPC(ch) || number_percent() < ch->pcdata->learned[gsn_flash_powder]) { SET_BIT(ch->affected2_by, 0-AFF2_HAS_FLASH); send_to_char( "You make some flash powder and hide it about your person.\n\r", ch); check_improve(ch, gsn_flash_powder); } else { send_to_char( "BOOM! You accidentally put together the wrong components.\n\r", ch); damage(ch, ch, number_range(1,80), TYPE_UNDEFINED); } pop_call(); return; } /* * DO_BANK * * This code manages the character's bank account in pcdata. * * Presto ?-?-97 */ void do_bank( CHAR_DATA *ch, char *argument ) { CHAR_DATA *target; char choice[MAX_STRING_LENGTH]; char buf[MAX_STRING_LENGTH]; char amt[MAX_STRING_LENGTH]; char arg[MAX_STRING_LENGTH]; int amount = 0; int account_max = 0; int targets_max = 0; push_call("do_bank(%p,%p)",ch,argument); if (!IS_SET(ch->in_room->room_flags, ROOM_BANK)) { send_to_char("You're not in a bank.\n\r", ch); pop_call(); return; } account_max = (ch->level + 5 + UMIN(ch->pcdata->reincarnation, 10)*5) * 2000000; ch->pcdata->account = URANGE(0, ch->pcdata->account, account_max); argument = one_argument(argument, choice); argument = one_argument(argument, amt); if (!strcasecmp(amt, "all")) { amount = -1; } else { amount = atoi(amt); if (amount < 0) { amount = 0; } } if (*choice == '\0' || *choice == ' ') { *choice = 'b'; } switch (*choice) { case 'd': if (amount == -1) { amount = ch->gold; } if (amount > ch->gold) { send_to_char("You don't have that much gold.\n\r", ch); pop_call(); return; } else if (amount == 0) { send_to_char("What good would that do?\n\r", ch); pop_call(); return; } else { if (ch->pcdata->account + amount > account_max) { amount = account_max - ch->pcdata->account; } ch->gold -= amount; ch->pcdata->account += amount; sprintf(buf, "You deposit %d gold coins into your account.\n\rYour account balance is now %d gold coins.\n\r", amount, ch->pcdata->account); send_to_char(buf, ch); } break; case 'w': if (amount == -1) { amount = ch->pcdata->account; } if (amount > ch->pcdata->account) { send_to_char("You don't have that much gold in your account.\n\r", ch); pop_call(); return; } else if (amount == 0) { send_to_char("What good would that do?\n\r", ch); pop_call(); return; } else { if (ch->gold + amount > ch->level*1000000) { send_to_char("You cannot carry that much gold.\n\r", ch); amount = ch->level*1000000 - ch->gold; } ch->gold += amount; ch->pcdata->account -= amount; sprintf(buf, "You withdraw %d gold coins from your account.\n\rYour account balance is now %d gold coins.\n\r", amount, ch->pcdata->account); send_to_char(buf, ch); } break; case 'b': sprintf(buf, "You have %d gold coins in your account.\n\r", ch->pcdata->account); send_to_char(buf, ch); break; case 't': case 'T': argument = one_argument(argument, arg); if (*arg == '\0') { send_to_char("Transfer money to whom?\n\r", ch); pop_call(); return; } if ((target = get_char_room(ch, arg)) == NULL) { send_to_char("They must be in the bank with you.\n\r", ch); pop_call(); return; } if (IS_NPC(target)) { send_to_char("Only players have accounts, silly.\n\r", ch); pop_call(); return; } if (amount == -1) { amount = ch->pcdata->account; } if (ch->pcdata->account < amount) { send_to_char("You don't have enough gold in your account.\n\r", ch); pop_call(); return; } else if (amount == 0) { send_to_char("What good would that do?\n\r", ch); pop_call(); return; } targets_max = (target->level + 5 + UMIN(target->pcdata->reincarnation, 10)*5) * 2000000; if (target->pcdata->account + amount > targets_max) { send_to_char("Their account cannot hold that much.\n\r", ch); amount = targets_max - target->pcdata->account; } ch->pcdata->account -= amount; target->pcdata->account += amount; ch_printf(ch, "You transfer %d coins into %s's account.\n\rYour account balance is now %d gold coins.\n\r", amount, target->name, ch->pcdata->account); ch_printf(target, "%s transfers %d coins into your account.\n\rYour account balance is now %d gold coins.\n\r", ch->name, amount, target->pcdata->account); break; default: send_to_char("Usage: bank <deposit/withdraw/balance/transfer> [amount] [target]\n\r", ch); break; } pop_call(); return; } int give_gold(CHAR_DATA* ch, int amount) { int num; push_call("give_gold(%p,%p)",ch,amount); if (!IS_NPC(ch) && ch->pcdata->clan && ch->pcdata->clan->tax > 0 && ch->pcdata->clan->tax <= 100) { num = (float) amount * ((float) ch->pcdata->clan->tax / 100); if (num > 0 && ch->pcdata->clan->coffers < max_coffer(ch->pcdata->clan)) { if (ch->pcdata->clan->coffers + num > max_coffer(ch->pcdata->clan)) { num = max_coffer(ch->pcdata->clan) - ch->pcdata->clan->coffers; } ch->pcdata->clan->coffers += num; amount -= num; ch->gold += amount; pop_call(); return num; } else { ch->gold += amount; pop_call(); return 0; } } else { ch->gold += amount; } pop_call(); return 0; } void do_enter( CHAR_DATA *ch, char *argument) { OBJ_DATA *portal; int destination, old_room; CHAR_DATA *fch, *fch_next; char buf[MAX_INPUT_LENGTH]; push_call("do_enter(%p,%p)",ch,argument); if (argument[0] == '\0') { send_to_char("Enter what?\n\r", ch); pop_call(); return; } if (ch->move < 2) { send_to_char("You are too exhaused.\n\r", ch); pop_call(); return; } old_room = ch->in_room->vnum; portal = get_obj_list(ch, argument, ch->in_room->first_content); if (portal == NULL) { send_to_char("You cannot find it.\n\r", ch); pop_call(); return; } if (portal->item_type != ITEM_PORTAL) { send_to_char("You cannot seem to find a way in.\n\r", ch); pop_call(); return; } if (IS_SET(portal->value[2], GATE_RANDOM)) { destination = get_random_room_index(ch, 1, MAX_VNUM-1)->vnum; } else if (IS_SET(portal->value[2], GATE_RANDOM_AREA)) { destination = get_random_room_index(ch, portal->pIndexData->area->low_r_vnum, portal->pIndexData->area->hi_r_vnum)->vnum; } else { destination = portal->value[3]; } if (get_room_index(destination) == NULL || destination == ch->in_room->vnum) { act("$p doesn't seem to go anywhere.", ch, portal, NULL, TO_CHAR); pop_call(); return; } if (IS_SET(portal->value[2], GATE_STEP_THROUGH)) { act("You step through $p.", ch, portal, NULL, TO_CHAR); sprintf(buf, " steps through %s and vanishes.\n\r", portal->short_descr); } else if (IS_SET(portal->value[2], GATE_STEP_INTO)) { act("You step into $p.", ch, portal, NULL, TO_CHAR); sprintf(buf, " steps into %s and vanishes.\n\r", portal->short_descr); } else { act("You enters $p.", ch, portal, NULL, TO_CHAR); sprintf(buf, " enters %s and vanishes.\n\r", portal->short_descr); } show_who_can_see(ch, buf); if (IS_SET(portal->value[2], GATE_GOWITH)) { act("$p fades out of existance.", ch, portal, NULL, TO_ROOM); obj_from_room(portal); obj_to_room(portal, destination); } char_to_room(ch, destination); show_who_can_see(ch, buf); ch->move--; do_look(ch, "auto"); if (portal->value[0] > 0) { portal->value[0]--; SET_BIT(portal->extra_flags, ITEM_MODIFIED); } mprog_greet_trigger(ch); if (IS_SET(portal->value[2], GATE_GOWITH)) { obj_to_room(portal, ch->in_room->vnum); pop_call(); return; } if (ch->in_room->vnum == old_room) { pop_call(); return; } for (fch = room_index[old_room]->first_person ; fch ; fch = fch_next) { fch_next = fch->next_in_room; if (fch->in_room != room_index[old_room]) { fch_next = room_index[old_room]->first_person; continue; } if (fch->master == ch && fch->position == POS_STANDING) { act("You follow $N.", fch, NULL, ch, TO_CHAR); do_enter(fch, argument); } } if (IS_SET(portal->value[2], GATE_GOWITH)) { if ((fch = room_index[old_room]->first_person) != NULL) { act("$p fades out of existance.", fch, portal, NULL, TO_CHAR); act("$p fades out of existence.", fch, portal, NULL, TO_ROOM); } obj_to_room(portal, ch->in_room->vnum); } if (portal->value[0] == 0 && (fch = room_index[portal->in_room->vnum]->first_person) != NULL) { act("$p fades out of existance.", fch, portal, NULL, TO_CHAR); act("$p fades out of existence.", fch, portal, NULL, TO_ROOM); junk_obj(portal); } pop_call(); return; } void search_inventory( CHAR_DATA *ch, OBJ_DATA *search_obj, char *argument ) { OBJ_DATA *obj; push_call("search_inventory(%p,%p,%p)",ch,search_obj,argument); for (obj = search_obj ; obj ; obj = obj->next_content) { if (obj->first_content) { search_inventory(ch, obj->first_content, argument); } if (can_see_obj(ch, obj) && is_multi_name_list_short(argument, short_to_name(obj->short_descr, 1))) { if (obj->in_obj) { ch_printf(ch, "%s%s is inside %s.\n\r", get_color_string(ch, COLOR_OBJECTS, VT102_BOLD), capitalize(obj->short_descr), obj->in_obj->short_descr); } else if (obj->wear_loc != WEAR_NONE) { ch_printf(ch, "%s%s is being worn.\n\r", get_color_string(ch, COLOR_OBJECTS, VT102_BOLD), capitalize(obj->short_descr)); } else { ch_printf(ch, "%s%s is carried.\n\r", get_color_string(ch, COLOR_OBJECTS, VT102_BOLD), capitalize(obj->short_descr)); } } } pop_call(); return; } void do_search( CHAR_DATA *ch, char *argument) { push_call("do_search(%p,%p)",ch,argument); if (argument[0] == '\0') { send_to_char("Search what?\n\r", ch); pop_call(); return; } act("You rummage through your belongings.", ch, NULL, NULL, TO_CHAR); /* act("$n rummages through $s belongings.", ch, NULL, NULL, TO_ROOM); */ search_inventory(ch, ch->first_carrying, argument); pop_call(); return; }