/**************************************************************************** * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | \\._.// * * -----------------------------------------------------------| (0...0) * * SMAUG 1.0 (C) 1994, 1995, 1996 by Derek Snider | ).:.( * * -----------------------------------------------------------| {o o} * * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, | / ' ' \ * * Scryn, Rennard, Swordbearer, Gorog, Grishnakh and Tricops |~'~.VxvxV.~'~* * ------------------------------------------------------------------------ * * 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{rfeldt, Tom Madsen, and Katja Nyboe. * * ------------------------------------------------------------------------ * * Object manipulation module * ****************************************************************************/ /* * $Log: act_obj.c,v $ * Revision 1.59 2004/04/06 22:00:08 dotd * use gcc __attribute__((format)) for custom printf functions, and fix all the resulting warnings (hundreds of them), thanks * to Samson for disconvering this nifty GCC extension * * Revision 1.58 2003/12/25 07:25:14 dotd * deity typos * * Revision 1.57 2003/12/21 17:20:53 dotd * cleaned up some compiler warnings from g++ * * Revision 1.56 2003/12/06 01:14:34 dotd * clean up warnings generated by new -W compiler flags * * Revision 1.55 2003/08/29 03:56:02 dotd * don't count max carry number when picking up money, only weight * * Revision 1.54 2003/08/29 03:45:09 dotd * allow giving more than sh_int can hold * * Revision 1.53 2003/08/22 01:02:51 dotd * junk all really doesn't work, switch to junk all.really * * Revision 1.52 2003/07/29 23:08:13 dotd * auction currency fix from Vladaar * * Revision 1.51 2003/03/07 04:12:54 dotd * change some money logs from MONITOR to DEBUG * * Revision 1.50 2003/03/06 03:55:22 dotd * make 'junk all' tell people to do 'junk all really' so people don't wax * all their eq on accident * * Revision 1.49 2003/03/06 02:50:07 dotd * currency tweaks, horde type monies now have the horde calculation in * * Revision 1.48 2003/03/01 05:09:56 dotd * move a barb check to above the obj_to_char, so we don't have to futz with * it and cause problems, might fix a crash bug * * Revision 1.47 2003/01/26 23:43:53 dotd * some groundwork for db backend, add xxx_exists_index to replace * get_xxx_index (so the db can use an optimized query instead of returning * the whole structure), add vnum to char_data and obj_data so you don't need * to access the index (and thus you don't have to query the db), make * create_xxx take a vnum instead of an index (so create_xxx can query the db * or use a caching layer) * * Revision 1.46 2003/01/01 00:49:18 dotd * handle money weights in corpses/ground, let people pick up as much as they * can carry instead of nothing at all * * Revision 1.45 2002/12/31 00:10:17 dotd * removed some nasty dependencies by moving tables.h and magic.h into * tables.c, had to add function prototypes in a lot of places * * Revision 1.44 2002/10/27 20:39:05 dotd * don't use objindex affects for anything, instead copy them to new * instances of obj and use them there, this fixes the dispelling/enchanting * problem and just makes sense * * Revision 1.43 2002/10/12 20:06:08 dotd * ANSI C error fixes, almost everything compiles with -ansi and/or -pedantic * now. Also removed some of the CVS log comments * * Revision 1.42 2002/08/11 16:45:00 dotd * anti class eq bits re-done another time, if hell exists i now know what it * will be for me * * Revision 1.41 2002/08/10 20:15:34 dotd * added function name to last_carried_by for better tracking * * Revision 1.40 2002/07/24 17:07:44 dotd * ego divide by zero fix * * Revision 1.39 2002/07/09 05:33:02 dotd * remove sacrifice inventory search * * Revision 1.38 2002/07/05 18:37:41 dotd * change progs to use extended bits from SMAUG1.4 so we can have more * added QUEST_PROG and quest triggers * * Revision 1.37 2002/07/03 00:54:40 dotd * char_ego update * * Revision 1.36 2002/06/26 22:53:46 dotd * solaris null var/printf fix * * Revision 1.35 2002/06/22 02:54:50 dotd * quest triggers hook points: objgive, objplace, mobkill * * Revision 1.34 2002/06/15 14:38:10 dotd * money_weight() function, use in get_obj to handle getting money * * Revision 1.33 2002/06/15 03:48:01 dotd * carry_n and carry_w funtions to replace ch->carry_number and * ch->carry_weight so that special weights like gold can be handled * * Revision 1.32 2002/06/12 01:03:47 dotd * can_wear_obj god please make this the last only_classs fix * * Revision 1.31 2002/06/11 23:41:43 dotd * barbarian magic check updated with glow, bless, hum, and invis checks * * Revision 1.30 2002/06/09 20:04:54 dotd * don't pass container (even though it's null) to act * * Revision 1.29 2002/06/09 15:36:22 dotd * brittle weapons scrap when used * * Revision 1.28 2002/06/09 15:15:40 dotd * make_scraps takes quiet argument to control displaying messages * * Revision 1.27 2002/02/09 16:34:03 dotd * added severity levels to log_prinf_plus() * * Revision 1.26 2002/02/09 15:48:21 dotd * added log severity to log_string() * * Revision 1.25 2002/02/09 00:05:57 dotd * update obj->last_carried_by on create_money's * * Revision 1.24 2002/02/06 02:01:51 dotd * *** empty log message *** * * Revision 1.23 2002/02/02 06:03:19 dotd * anti item flag updates, spellfail/skillfail tweaks, anticlass armor now * gives a bit more penalty to multis * * Revision 1.22 2002/01/22 04:17:20 dotd * *** empty log message *** * * Revision 1.21 2002/01/13 19:09:43 dotd * give carry weigth/number fix * * Revision 1.20 2002/01/13 06:35:41 dotd * *** empty log message *** * * Revision 1.19 2002/01/13 03:16:23 dotd * ItemSave returns bool instead of int * * Revision 1.18 2002/01/03 03:37:59 dotd * ItemSave, disintegrate updates * * Revision 1.17 2002/01/03 03:12:01 dotd * spell_disintegrate * * Revision 1.16 2002/01/01 22:29:46 dotd * split christen/currency/property stuff from mud.h into separate header * files, tweaks to currency functions * * Revision 1.15 2001/12/22 04:28:46 dotd * changed ch->pcdata->learned[sn] to LEARNED(ch, sn) * * Revision 1.14 2001/11/30 19:00:38 dotd * *** empty log message *** * * Revision 1.13 2001/06/12 04:47:26 dotd * fix to prevent mobs from scavenging too much money * * Revision 1.12 2001/06/09 18:18:21 dotd * misc changes * * Revision 1.11 2001/05/24 00:27:11 dotd * give gold fixed * * Revision 1.10 2001/05/22 02:57:35 dotd * removal of dead wood * * Revision 1.9 2001/05/09 01:25:12 dotd * revision touch * * Revision 1.7 2001/04/01 16:57:58 dotd * covering fix * * Revision 1.6 2001/03/11 01:39:39 dotd * litter check on npc's, they don't have litterbug flag * * Revision 1.5 2001/03/11 01:34:35 dotd * rewrote do_give so it handles all.obj and x obj and just plain all * * Revision 1.4 2001/02/18 01:15:29 dotd * missile weapon updates * * Revision 1.3 2001/02/18 01:02:58 dotd * missile weapon updates * * Revision 1.2 2001/02/17 16:11:17 dotd * notching missiles * * Revision 1.1.1.1 2001/02/03 04:23:42 dotd * DOTDII Sources * * Revision 1.15 1999/11/08 20:00:21 cvs * added default dale combat messages by race -heath * * Revision 1.14 1999/08/15 20:15:37 cvs * recycle lists, some misc bugs * * Revision 1.13 1999/06/29 04:35:38 cvs * donation room fixes * * Revision 1.12 1999/05/23 18:40:54 garil * *** empty log message *** * * Revision 1.11 1999/04/27 02:26:57 garil * currency updates * * Revision 1.10 1999/02/24 15:54:06 garil * *** empty log message *** * * Revision 1.9 1999/02/23 01:22:36 garil * major currency updates * * Revision 1.8 1999/02/08 00:56:56 garil * lots of misc bug fixes * * Revision 1.7 1999/01/04 20:14:17 dotd * removed the wizinvis flag * * Revision 1.6 1998/12/16 20:00:26 dotd * currency updates * * Revision 1.5 1998/12/16 19:10:00 dotd * added rcs id and log keywords * */ /*static char rcsid[] = "$Id: act_obj.c,v 1.59 2004/04/06 22:00:08 dotd Exp $";*/ #include <sys/types.h> #include <stdio.h> #include <string.h> #include <time.h> #include "mud.h" #include "bet.h" #include "gsn.h" #include "currency.h" #include "quest.h" /*double sqrt( double x );*/ /* * Local functions. */ void wear_obj args( ( CHAR_DATA *ch, OBJ_DATA *obj, bool fReplace, sh_int wear_bit ) ); DECLARE_DO_FUN(do_donate); DECLARE_DO_FUN(do_junk); DECLARE_DO_FUN(do_drop); /* * how resistant an object is to damage -Thoric */ sh_int get_obj_resistance( OBJ_DATA *obj ) { sh_int resist; resist = number_fuzzy(MAX_ITEM_IMPACT); /* magical items are more resistant */ if ( IS_OBJ_STAT( obj, ITEM_MAGIC ) ) resist += number_fuzzy(12); /* metal objects are definately stronger */ if ( IS_OBJ_STAT( obj, ITEM_METAL ) ) resist += number_fuzzy(5); /* organic objects are most likely weaker */ if ( IS_OBJ_STAT( obj, ITEM_ORGANIC ) ) resist -= number_fuzzy(5); /* blessed objects should have a little bonus */ if ( IS_OBJ_STAT( obj, ITEM_BLESS ) ) resist += number_fuzzy(5); /* lets make store inventory pretty tough */ if ( IS_OBJ_STAT( obj, ITEM_INVENTORY ) ) resist += 20; /* okay... let's add some bonus/penalty for item level... */ resist += (number_fuzzy(30) / 10) - 2; /* and lasty... take armor or weapon's condition into consideration */ if (obj->item_type == ITEM_ARMOR || obj->item_type == ITEM_WEAPON) resist += (obj->value[0] / 2) - 2; resist += 10; return URANGE(10, resist, 599); } bool ItemSave( OBJ_DATA *obj, int sn) { AFFECT_DATA *paf; int num; if (obj->carried_by && in_arena(obj->carried_by)) return(TRUE); /* obj fails save automatically it brittle */ if (IS_OBJ_STAT2(obj, ITEM2_BRITTLE) && number_range(1,10)!=1) return(FALSE); /* this is to keep immune objects from getting dammaged */ if (IS_OBJ_STAT2(obj, ITEM2_IMMUNE)) return(TRUE); /* this is to give resistant magic items a better chance to save */ if (IS_OBJ_STAT2(obj, ITEM2_RESISTANT) && number_percent()>50) return(TRUE); num = number_range(1,20); if (num <= 1) return(FALSE); if (num >= 20) return(TRUE); for (paf=obj->first_affect; paf; paf=paf->next) { if (paf->location == APPLY_SAVING_SPELL || paf->location == APPLY_SAVING_ALL) num -= paf->modifier; if (paf->location != APPLY_NONE) num += 1; if (paf->location == APPLY_HITROLL) num += paf->modifier; } if (obj->item_type != ITEM_ARMOR) num += 1; if (IS_OBJ_STAT(obj, ITEM_METAL)) num += 1; if (IS_OBJ_STAT(obj, ITEM_ORGANIC)) num -= 1; if (IS_OBJ_STAT(obj, ITEM_MAGIC)) num += 1; if (IS_OBJ_STAT(obj, ITEM_BLESS)) num += 1; if (obj->christened) num += 1; if (num <= 1) return(FALSE); if (num >= 20) return(TRUE); if (num >= number_range(1,18)) return(TRUE); return(FALSE); } bool barbarian_magic_check(CHAR_DATA *ch, OBJ_DATA *obj) { if (IS_NPC(ch) || IS_IMMORTAL(ch) || !IS_ACTIVE(ch, CLASS_BARBARIAN)) return(FALSE); if (IS_OBJ_STAT(obj, ITEM_MAGIC) || IS_OBJ_STAT(obj, ITEM_GLOW) || IS_OBJ_STAT(obj, ITEM_HUM) || IS_OBJ_STAT(obj, ITEM_BLESS) || IS_OBJ_STAT(obj, ITEM_INVIS)) return(TRUE); return(FALSE); } void get_obj( CHAR_DATA *ch, OBJ_DATA *obj, OBJ_DATA *container ) { CLAN_DATA *clan; int weight, number = 0; if ( !CAN_WEAR(obj, ITEM_TAKE) && (GetMaxLevel(ch) < sysdata.level_getobjnotake ) ) { send_to_char( "You can't take that.\n\r", ch ); return; } if ( IS_OBJ_STAT( obj, ITEM_PROTOTYPE ) && !can_take_proto( ch ) ) { send_to_char( "A godly force prevents you from getting close to it.\n\r", ch ); return; } if (barbarian_magic_check(ch, obj)) { act( AT_ACTION, "You sense magic on $p and drop it.", ch, obj, container, TO_CHAR ); act( AT_ACTION, "$n recoils from $p and drops it.", ch, obj, container, TO_ROOM ); return; } if ( obj->item_type != ITEM_MONEY && carry_n(ch) + get_obj_number( obj ) > can_carry_n( ch ) ) { act( AT_PLAIN, "$d: you can't carry that many items.", ch, NULL, obj->name, TO_CHAR ); return; } if ( IS_OBJ_STAT( obj, ITEM_COVERING ) ) weight = obj->weight; else weight = get_obj_weight( obj ); if ( carry_w(ch) + weight > can_carry_w( ch ) ) { if ( obj->item_type == ITEM_MONEY ) number = max_carry_money(ch, obj->value[2]); if ( !number ) { act( AT_PLAIN, "$d: you can't carry that much weight.", ch, NULL, obj->name, TO_CHAR ); return; } else { /* Fix for money weight -Garil 12/31/2002 * split the money into two new objects, extract the old, * and give the player one of the new objects */ char buf[128]; OBJ_DATA *new_obj; new_obj = create_money( obj->value[0]-number, obj->value[2] ); snprintf(buf, 127, "get_obj1 %d %s", obj->vnum, obj->name); new_obj->last_carried_by = str_dup(buf); if (container) obj_to_obj( new_obj, container ); else obj_to_room( new_obj, obj->in_room ); new_obj = create_money( number, obj->value[2] ); snprintf(buf, 127, "get_obj2 %d %s", obj->vnum, obj->name); new_obj->last_carried_by = str_dup(buf); if (container) obj_to_obj( new_obj, container ); else obj_to_room( new_obj, obj->in_room ); extract_obj( obj ); obj = new_obj; } } if ( container ) { act( AT_ACTION, IS_OBJ_STAT(container, ITEM_COVERING) ? "You get $p from beneath $P." : "You get $p from $P.", ch, obj, container, TO_CHAR ); act( AT_ACTION, IS_OBJ_STAT(container, ITEM_COVERING) ? "$n gets $p from beneath $P." : "$n gets $p from $P.", ch, obj, container, TO_ROOM ); obj_from_obj( obj ); } else { act( AT_ACTION, "You get $p.", ch, obj, NULL, TO_CHAR ); act( AT_ACTION, "$n gets $p.", ch, obj, NULL, TO_ROOM ); obj_from_room( obj ); } /* Clan storeroom checks */ if ( IS_SET(ch->in_room->room_flags, ROOM_CLANSTOREROOM) && (!container || container->carried_by == NULL) ) for ( clan = first_clan; clan; clan = clan->next ) if ( clan->storeroom == ch->in_room->vnum ) save_clan_storeroom(ch, clan); if ( obj->item_type != ITEM_CONTAINER ) check_for_trap( ch, obj, TRAP_GET ); if ( char_died(ch) ) return; if ( obj->item_type == ITEM_MONEY ) { int value; if (obj->vnum == OBJ_VNUM_MONEY_ONE || obj->vnum == OBJ_VNUM_MONEY_SOME) value = obj->value[0]; else value = horde_worth(ch, obj->value[0]); if (value >= 10000) log_printf_plus(LOG_DEBUG, LEVEL_IMMORTAL, SEV_DEBUG, "%s got %d of type:%d coins (room %d, last carried by: %s)", GET_NAME(ch), value, obj->value[2], ch->in_room->vnum, obj->last_carried_by?obj->last_carried_by:"nobody"); GET_MONEY(ch, obj->value[2]) += value; extract_obj( obj ); } else { obj = obj_to_char( obj, ch ); if ( char_died(ch) || obj_extracted(obj) ) return; oprog_get_trigger(ch, obj); } return; } void do_get( CHAR_DATA *ch, char *argument ) { char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; OBJ_DATA *obj; OBJ_DATA *obj_next; OBJ_DATA *container; int number; bool found; argument = one_argument( argument, arg1 ); if ( is_number(arg1) ) { number = atoi(arg1); if ( number < 1 ) { send_to_char( "That was easy...\n\r", ch ); return; } if ( (carry_n(ch) + number) > can_carry_n(ch) ) { send_to_char( "You can't carry that many.\n\r", ch ); return; } argument = one_argument( argument, arg1 ); } else number = 0; argument = one_argument( argument, arg2 ); /* munch optional words */ if ( !str_cmp( arg2, "from" ) && argument[0] != '\0' ) argument = one_argument( argument, arg2 ); /* Get type. */ if ( arg1[0] == '\0' ) { send_to_char( "Get what?\n\r", ch ); return; } if ( ms_find_obj(ch) ) return; if ( arg2[0] == '\0' ) { if ( number <= 1 && str_cmp( arg1, "all" ) && str_prefix( "all.", arg1 ) ) { /* 'get obj' */ if ( IS_DONATION(ch->in_room) ) obj = get_obj_list( ch, arg1, DONATION_ROOM()->first_content ); else obj = get_obj_list( ch, arg1, ch->in_room->first_content ); if ( !obj ) { act( AT_PLAIN, "I see no $T here.", ch, NULL, arg1, TO_CHAR ); return; } separate_obj(obj); get_obj( ch, obj, NULL ); if ( char_died(ch) ) return; if ( IS_SET( sysdata.save_flags, SV_GET ) ) save_char_obj( ch ); } else { sh_int cnt = 0; bool fAll; char *chk; if ( IS_SET( ch->in_room->room_flags, ROOM_DONATION ) ) { send_to_char( "The gods frown upon such a display of greed!\n\r", ch ); return; } if ( !str_cmp(arg1, "all") ) fAll = TRUE; else fAll = FALSE; if ( number > 1 ) chk = arg1; else chk = &arg1[4]; /* 'get all' or 'get all.obj' */ found = FALSE; for ( obj = ch->in_room->first_content; obj; obj = obj_next ) { obj_next = obj->next_content; if ( ( fAll || nifty_is_name( chk, obj->name ) ) && can_see_obj( ch, obj ) ) { found = TRUE; if ( number && (cnt + obj->count) > number ) split_obj( obj, number - cnt ); cnt += obj->count; get_obj( ch, obj, NULL ); if ( char_died(ch) || carry_n(ch) >= can_carry_n( ch ) || carry_w(ch) >= can_carry_w( ch ) || (number && cnt >= number) ) { if ( IS_SET(sysdata.save_flags, SV_GET) && !char_died(ch) ) save_char_obj(ch); return; } } } if ( !found ) { if ( fAll ) send_to_char( "I see nothing here.\n\r", ch ); else act( AT_PLAIN, "I see no $T here.", ch, NULL, chk, TO_CHAR ); } else if ( IS_SET( sysdata.save_flags, SV_GET ) ) save_char_obj( ch ); } } else { /* 'get ... container' */ if ( !str_cmp( arg2, "all" ) || !str_prefix( "all.", arg2 ) ) { send_to_char( "You can't do that.\n\r", ch ); return; } if ( ( container = get_obj_here( ch, arg2 ) ) == NULL ) { act( AT_PLAIN, "I see no $T here.", ch, NULL, arg2, TO_CHAR ); return; } switch ( container->item_type ) { default: if ( !IS_OBJ_STAT( container, ITEM_COVERING ) ) { send_to_char( "That's not a container.\n\r", ch ); return; } if ( carry_w(ch) + container->weight > can_carry_w( ch ) ) { send_to_char( "It's too heavy for you to lift.\n\r", ch ); return; } break; case ITEM_CONTAINER: case ITEM_CORPSE_NPC: break; case ITEM_CORPSE_PC: { char name[MAX_INPUT_LENGTH]; CHAR_DATA *gch; char *pd; if ( IS_NPC(ch) ) { send_to_char( "You can't do that.\n\r", ch ); return; } pd = container->short_descr; pd = one_argument( pd, name ); pd = one_argument( pd, name ); pd = one_argument( pd, name ); pd = one_argument( pd, name ); if ( IS_OBJ_STAT( container, ITEM_CLANCORPSE ) && !IS_NPC(ch) && (get_timer( ch, TIMER_PKILLED ) > 0 ) && str_cmp( name, ch->name ) ) { send_to_char( "You cannot loot from that corpse...yet.\n\r", ch ); return; } if ( IS_OBJ_STAT( container, ITEM_CLANCORPSE ) && !IS_NPC(ch) && IS_SET( ch->pcdata->flags, PCFLAG_DEADLY ) ) break; if ( str_cmp( name, ch->name ) && !IS_IMMORTAL(ch) ) { bool fGroup; fGroup = FALSE; for ( gch = first_char; gch; gch = gch->next ) { if ( !IS_NPC(gch) && is_same_group( ch, gch ) && !str_cmp( name, gch->name ) ) { fGroup = TRUE; break; } } if ( !fGroup ) { send_to_char( "That's someone else's corpse.\n\r", ch ); return; } } } } if ( !IS_OBJ_STAT(container, ITEM_COVERING ) && IS_SET(container->value[1], CONT_CLOSED) ) { act( AT_PLAIN, "The $d is closed.", ch, NULL, container->name, TO_CHAR ); return; } if ( number <= 1 && str_cmp( arg1, "all" ) && str_prefix( "all.", arg1 ) ) { /* 'get obj container' */ obj = get_obj_list( ch, arg1, container->first_content ); if ( !obj ) { act( AT_PLAIN, IS_OBJ_STAT(container, ITEM_COVERING) ? "I see nothing like that beneath the $T." : "I see nothing like that in the $T.", ch, NULL, arg2, TO_CHAR ); return; } separate_obj(obj); get_obj( ch, obj, container ); check_for_trap( ch, container, TRAP_GET ); if ( char_died(ch) ) return; if ( IS_SET( sysdata.save_flags, SV_GET ) ) save_char_obj( ch ); } else { int cnt = 0; bool fAll; char *chk; /* 'get all container' or 'get all.obj container' */ if ( IS_OBJ_STAT( container, ITEM_DONATION ) ) { send_to_char( "The gods frown upon such an act of greed!\n\r", ch ); return; } if ( !str_cmp(arg1, "all") ) fAll = TRUE; else fAll = FALSE; if ( number > 1 ) chk = arg1; else chk = &arg1[4]; found = FALSE; for ( obj = container->first_content; obj; obj = obj_next ) { obj_next = obj->next_content; if ( ( fAll || nifty_is_name( chk, obj->name ) ) && can_see_obj( ch, obj ) ) { found = TRUE; if ( number && (cnt + obj->count) > number ) split_obj( obj, number - cnt ); cnt += obj->count; get_obj( ch, obj, container ); if ( char_died(ch) || carry_n(ch) >= can_carry_n( ch ) || carry_w(ch) >= can_carry_w( ch ) || (number && cnt >= number) ) return; } } if ( !found ) { if ( fAll ) act( AT_PLAIN, IS_OBJ_STAT(container, ITEM_COVERING) ? "I see nothing beneath the $T." : "I see nothing in the $T.", ch, NULL, arg2, TO_CHAR ); else act( AT_PLAIN, IS_OBJ_STAT(container, ITEM_COVERING) ? "I see nothing like that beneath the $T." : "I see nothing like that in the $T.", ch, NULL, arg2, TO_CHAR ); } else check_for_trap( ch, container, TRAP_GET ); if ( char_died(ch) ) return; if ( found && IS_SET( sysdata.save_flags, SV_GET ) ) save_char_obj( ch ); } } return; } void do_put( CHAR_DATA *ch, char *argument ) { char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; OBJ_DATA *container; OBJ_DATA *obj; OBJ_DATA *obj_next; CLAN_DATA *clan; sh_int count; int number; bool save_char = FALSE; argument = one_argument( argument, arg1 ); if ( is_number(arg1) ) { number = atoi(arg1); if ( number < 1 ) { send_to_char( "That was easy...\n\r", ch ); return; } argument = one_argument( argument, arg1 ); } else number = 0; argument = one_argument( argument, arg2 ); /* munch optional words */ if ( (!str_cmp(arg2, "into") || !str_cmp(arg2, "inside") || !str_cmp(arg2, "in")) && argument[0] != '\0' ) argument = one_argument( argument, arg2 ); if ( arg1[0] == '\0' || arg2[0] == '\0' ) { send_to_char( "Put what in what?\n\r", ch ); return; } if ( ms_find_obj(ch) ) return; if ( !str_cmp( arg2, "all" ) || !str_prefix( "all.", arg2 ) ) { send_to_char( "You can't do that.\n\r", ch ); return; } if ( ( container = get_obj_here( ch, arg2 ) ) == NULL ) { act( AT_PLAIN, "I see no $T here.", ch, NULL, arg2, TO_CHAR ); return; } if ( !container->carried_by && IS_SET( sysdata.save_flags, SV_PUT ) ) save_char = TRUE; if ( IS_OBJ_STAT(container, ITEM_COVERING) ) { if ( carry_w(ch) + container->weight > can_carry_w( ch ) ) { send_to_char( "It's too heavy for you to lift.\n\r", ch ); return; } } else { if ( container->item_type != ITEM_CONTAINER ) { send_to_char( "That's not a container.\n\r", ch ); return; } if ( IS_SET(container->value[1], CONT_CLOSED) ) { act( AT_PLAIN, "The $d is closed.", ch, NULL, container->name, TO_CHAR ); return; } } if ( number <= 1 && str_cmp( 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 ); return; } if ( obj == container ) { send_to_char( "You can't fold it into itself.\n\r", ch ); return; } if ( !can_drop_obj( ch, obj ) ) { send_to_char( "You can't let go of it.\n\r", ch ); return; } if ( IS_OBJ_STAT(container, ITEM_COVERING) && (get_obj_weight( obj ) / obj->count) > (get_obj_weight( container ) / container->count)) { send_to_char( "It won't fit under there.\n\r", ch ); return; } if ( (get_obj_weight( obj ) / obj->count) + (get_obj_weight( container ) / container->count) > container->value[0] ) { send_to_char( "It won't fit.\n\r", ch ); return; } separate_obj(obj); separate_obj(container); obj_from_char( obj ); obj = obj_to_obj( obj, container ); check_for_trap ( ch, container, TRAP_PUT ); if ( char_died(ch) ) return; count = obj->count; obj->count = 1; act( AT_ACTION, IS_OBJ_STAT( container, ITEM_COVERING ) ? "$n hides $p beneath $P." : "$n puts $p in $P.", ch, obj, container, TO_ROOM ); act( AT_ACTION, IS_OBJ_STAT( container, ITEM_COVERING ) ? "You hide $p beneath $P." : "You put $p in $P.", ch, obj, container, TO_CHAR ); obj->count = count; if ( save_char ) save_char_obj(ch); /* Clan storeroom check */ if ( IS_SET(ch->in_room->room_flags, ROOM_CLANSTOREROOM) && container->carried_by == NULL) for ( clan = first_clan; clan; clan = clan->next ) if ( clan->storeroom == ch->in_room->vnum ) save_clan_storeroom(ch, clan); } else { bool found = FALSE; int cnt = 0; bool fAll; char *chk; if ( !str_cmp(arg1, "all") ) fAll = TRUE; else fAll = FALSE; if ( number > 1 ) chk = arg1; else chk = &arg1[4]; separate_obj(container); /* 'put all container' or 'put all.obj container' */ for ( obj = ch->first_carrying; obj; obj = obj_next ) { obj_next = obj->next_content; if ( ( fAll || nifty_is_name( chk, obj->name ) ) && can_see_obj( ch, obj ) && obj->wear_loc == WEAR_NONE && obj != container && can_drop_obj( ch, obj ) && get_obj_weight( obj ) + get_obj_weight( container ) <= container->value[0] ) { if ( number && (cnt + obj->count) > number ) split_obj( obj, number - cnt ); cnt += obj->count; obj_from_char( obj ); act( AT_ACTION, "$n puts $p in $P.", ch, obj, container, TO_ROOM ); act( AT_ACTION, "You put $p in $P.", ch, obj, container, TO_CHAR ); obj = obj_to_obj( obj, container ); found = TRUE; check_for_trap( ch, container, TRAP_PUT ); if ( char_died(ch) ) return; if ( number && cnt >= number ) break; } } /* * Don't bother to save anything if nothing was dropped -Thoric */ if ( !found ) { if ( fAll ) act( AT_PLAIN, "You are not carrying anything.", ch, NULL, NULL, TO_CHAR ); else act( AT_PLAIN, "You are not carrying any $T.", ch, NULL, chk, TO_CHAR ); return; } if ( save_char ) save_char_obj(ch); /* Clan storeroom check */ if ( IS_SET(ch->in_room->room_flags, ROOM_CLANSTOREROOM) && container->carried_by == NULL ) for ( clan = first_clan; clan; clan = clan->next ) if ( clan->storeroom == ch->in_room->vnum ) save_clan_storeroom(ch, clan); } return; } void do_drop( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH], buf[128]; OBJ_DATA *obj; OBJ_DATA *obj_next; ROOM_INDEX_DATA *room; bool found; CLAN_DATA *clan; int number; if ( ch->last_cmd == do_donate && DONATION_ROOM()) room = DONATION_ROOM(); else room = ch->in_room; argument = one_argument( argument, arg ); if ( is_number(arg) ) { number = atoi(arg); if ( number < 1 ) { send_to_char( "That was easy, try giving at least one...\n\r", ch ); return; } argument = one_argument( argument, arg ); } else number = 0; if ( arg[0] == '\0' ) { if ( ch->last_cmd == do_donate && DONATION_ROOM()) send_to_char( "Donate what?\n\r", ch ); else if ( ch->last_cmd == do_junk) send_to_char( "Junk what?\n\r", ch ); else send_to_char( "Drop what?\n\r", ch ); return; } if ( ms_find_obj(ch) ) return; if ( ch->last_cmd != do_junk && (IS_SET( room->room_flags, ROOM_NODROP ) || (!IS_NPC(ch) && IS_SET( ch->act, PLR_LITTERBUG)) ) ) { set_char_color( AT_MAGIC, ch ); send_to_char( "A magical force stops you!\n\r", ch ); set_char_color( AT_TELL, ch ); send_to_char( "Someone tells you, 'No littering here!'\n\r", ch ); return; } if ( number > 0 && !(ch->last_cmd == do_junk) ) { int type; /* 'drop NNNN coins' */ if ( (type=get_currency_type(arg)) ) { if ( GET_MONEY(ch,type) < number ) { ch_printf(ch, "You haven't got that much %s.\n\r", curr_types[type] ); return; } GET_MONEY(ch,type) -= number; for ( obj = room->first_content; obj; obj = obj_next ) { obj_next = obj->next_content; switch ( obj->vnum ) { case OBJ_VNUM_MONEY_ONE: if (obj->value[2]==type) { number += 1; extract_obj( obj ); } break; case OBJ_VNUM_MONEY_SOME: if (obj->value[2]==type) { number += obj->value[0]; extract_obj( obj ); } break; } } act( AT_ACTION, "$n drops some $T.", ch, NULL, curr_types[type], TO_ROOM ); obj = create_money(number, type); snprintf(buf, 127, "drop %d %s", ch->vnum, ch->name); obj->last_carried_by = str_dup(buf); obj_to_room( obj, room ); send_to_char( "Ok.\n\r", ch ); if ( IS_SET( sysdata.save_flags, SV_DROP ) ) save_char_obj( ch ); return; } } if ( number <= 1 && str_cmp( arg, "all" ) && str_prefix( "all.", arg ) ) { /* 'drop obj' */ if ( ( obj = get_obj_carry( ch, arg ) ) == NULL ) { send_to_char( "You do not have that item.\n\r", ch ); return; } if ( !can_drop_obj( ch, obj ) ) { send_to_char( "You can't let go of it.\n\r", ch ); return; } separate_obj( obj ); if ( ch->last_cmd == do_donate && DONATION_ROOM()) { act( AT_ACTION, "$n donates $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You donate $p.", ch, obj, NULL, TO_CHAR ); } else if ( ch->last_cmd == do_junk) { act( AT_ACTION, "$n junks $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You junk $p.", ch, obj, NULL, TO_CHAR ); } else { act( AT_ACTION, "$n drops $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You drop $p.", ch, obj, NULL, TO_CHAR ); } obj_from_char( obj ); if (ch->last_cmd == do_junk) { extract_obj(obj); return; } obj = obj_to_room( obj, room ); quest_trigger_objplace(ch, obj, room); oprog_drop_trigger ( ch, obj ); /* mudprogs */ if( char_died(ch) || obj_extracted(obj) ) return; /* Clan storeroom saving */ if ( IS_SET(room->room_flags, ROOM_CLANSTOREROOM) ) for ( clan = first_clan; clan; clan = clan->next ) if ( clan->storeroom == room->vnum ) save_clan_storeroom(ch, clan); } else { int cnt = 0; char *chk; bool fAll; if ( !str_cmp(arg, "all") ) { if ( ch->last_cmd == do_junk ) { send_to_char("Use 'junk all.really' if you're sure.\n\r", ch); return; } fAll = TRUE; } else if ( !str_cmp(arg, "all.really") && ch->last_cmd == do_junk ) fAll = TRUE; else fAll = FALSE; if ( number > 1 ) chk = arg; else chk = &arg[4]; /* 'drop all' or 'drop all.obj' */ if ( IS_SET( room->room_flags, ROOM_NODROPALL ) || IS_SET( room->room_flags, ROOM_CLANSTOREROOM ) ) { send_to_char( "You can't seem to do that here...\n\r", ch ); return; } found = FALSE; for ( obj = ch->first_carrying; obj; obj = obj_next ) { obj_next = obj->next_content; if ( (fAll || nifty_is_name( chk, obj->name ) ) && can_see_obj( ch, obj ) && obj->wear_loc == WEAR_NONE && can_drop_obj( ch, obj ) ) { found = TRUE; if ( HAS_PROG(obj->pIndexData, DROP_PROG) && obj->count > 1 ) { ++cnt; separate_obj( obj ); obj_from_char( obj ); if ( !obj_next ) obj_next = ch->first_carrying; } else { if ( number && (cnt + obj->count) > number ) split_obj( obj, number - cnt ); cnt += obj->count; obj_from_char( obj ); } if ( ch->last_cmd == do_donate && DONATION_ROOM()) { act( AT_ACTION, "$n donates $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You donate $p.", ch, obj, NULL, TO_CHAR ); } else if ( ch->last_cmd == do_junk) { act( AT_ACTION, "$n junks $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You junk $p.", ch, obj, NULL, TO_CHAR ); } else { act( AT_ACTION, "$n drops $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You drop $p.", ch, obj, NULL, TO_CHAR ); } if (ch->last_cmd == do_junk) { extract_obj(obj); } else { obj = obj_to_room( obj, room ); quest_trigger_objplace(ch, obj, room); oprog_drop_trigger( ch, obj ); /* mudprogs */ } if ( char_died(ch) ) return; if ( number && cnt >= number ) break; } } if ( !found ) { if ( fAll ) act( AT_PLAIN, "You are not carrying anything.", ch, NULL, NULL, TO_CHAR ); else act( AT_PLAIN, "You are not carrying any $T.", ch, NULL, chk, TO_CHAR ); } } if ( IS_SET( sysdata.save_flags, SV_DROP ) ) save_char_obj( ch ); /* duping protector */ return; } void do_give( CHAR_DATA *ch, char *argument ) { char arg1 [MAX_INPUT_LENGTH]; char arg2 [MAX_INPUT_LENGTH]; char buf [MAX_INPUT_LENGTH]; CHAR_DATA *victim; OBJ_DATA *obj; int number; int type; OBJ_DATA *obj_next; bool fAll = FALSE, found = FALSE; char *chk; sh_int cnt = 0; argument = one_argument( argument, arg1 ); if ( is_number(arg1) ) { number = atoi(arg1); if ( number < 1 ) { send_to_char( "That was easy...\n\r", ch ); return; } argument = one_argument( argument, arg1 ); } else number = 0; argument = one_argument( argument, arg2 ); if ( !str_cmp( arg2, "to" ) && argument[0] != '\0' ) argument = one_argument( argument, arg2 ); if ( arg1[0] == '\0' || arg2[0] == '\0' ) { send_to_char( "Give what to whom?\n\r", ch ); return; } if ( ms_find_obj(ch) ) return; if ( number && (type = get_currency_type(arg1))) { if ( ( victim = get_char_room( ch, arg2 ) ) == NULL ) { send_to_char( "They aren't here.\n\r", ch ); return; } if ( victim == ch ) { send_to_char("Riiiiight... give yourself money.\n\r", ch); return; } if ( GET_MONEY(ch,type) < number ) { ch_printf(ch, "Very generous of you, but you haven't got that much %s.\n\r", curr_types[type] ); return; } if ((money_weight(number, type)+carry_w(victim)) >= can_carry_w( victim )) { act( AT_ACTION, "$N can't carry any more.", ch, NULL, victim, TO_CHAR ); return; } GET_MONEY(ch,type) -= number; GET_MONEY(victim,type) += number; sprintf(buf, "$n gives you %d %s coins.", number, curr_types[type]); act( AT_ACTION, buf, ch, NULL, victim, TO_VICT ); sprintf(buf, "$n gives $N some %s coins.", curr_types[type]); act( AT_ACTION, buf, ch, NULL, victim, TO_NOTVICT ); sprintf(buf, "You give $N %d %s coins.", number, curr_types[type]); act( AT_ACTION, buf, ch, NULL, victim, TO_CHAR ); send_to_char( "OK.\n\r", ch ); mprog_bribe_trigger( victim, ch, number ); if ( IS_SET( sysdata.save_flags, SV_GIVE ) && !char_died(ch) ) save_char_obj(ch); if ( IS_SET( sysdata.save_flags, SV_RECEIVE ) && !char_died(victim) ) save_char_obj(victim); return; } if ( ( victim = get_char_room( ch, arg2 ) ) == NULL ) { send_to_char( "They aren't here.\n\r", ch ); return; } if ( victim == ch ) { send_to_char("Riiiight.... give yourself stuff...\n\r", ch); return; } chk = arg1; if ( !str_cmp(arg1, "all") ) { fAll = TRUE; number = 0; } else if ( !str_prefix("all.", arg1) ) { chk = &arg1[4]; number = 0; } else if ( !number) number = 1; for ( obj = ch->first_carrying; obj; obj = obj_next ) { obj_next = obj->next_content; if ( ( fAll || nifty_is_name( chk, obj->name ) ) && can_see_obj( ch, obj ) ) { if ( !can_drop_obj( ch, obj ) ) { act( AT_PLAIN, "You cannot let go of $p.", ch, obj, NULL, TO_CHAR ); continue; } if ( obj->wear_loc != WEAR_NONE ) { send_to_char( "You must remove it first.\n\r", ch ); continue; } if ( !can_see_obj( victim, obj) ) { act( AT_PLAIN, "$N can't see it.", ch, NULL, victim, TO_CHAR ); continue; } if (barbarian_magic_check(victim, obj)) { act( AT_PLAIN, "$N refuses to take it.", ch, NULL, victim, TO_CHAR ); act( AT_PLAIN, "$n tries to give $N $p but $E refuses to take it.", ch, obj, victim, TO_ROOM ); act( AT_PLAIN, "$n tries to give you $p but you sense magic and refuse.", ch, obj, victim, TO_VICT ); continue; } if ( IS_OBJ_STAT( obj, ITEM_PROTOTYPE ) && !can_take_proto( victim ) ) { act( AT_PLAIN, "You cannot give $p to $N!", ch, obj, victim, TO_CHAR ); continue; } if ((number+carry_n(victim)) >= can_carry_n( victim ) || ((obj->weight*number)+carry_w(victim)) >= can_carry_w( victim )) { act( AT_ACTION, "$N can't carry any more.", ch, NULL, victim, TO_CHAR ); return; } found = TRUE; if ( number && (cnt + obj->count) > number ) split_obj( obj, number - cnt ); cnt += obj->count; obj_from_char( obj ); act( AT_ACTION, "$n gives $p to $N.", ch, obj, victim, TO_NOTVICT ); act( AT_ACTION, "$n gives you $p.", ch, obj, victim, TO_VICT ); act( AT_ACTION, "You give $p to $N.", ch, obj, victim, TO_CHAR ); obj = obj_to_char( obj, victim ); quest_trigger_objgive(ch, obj, victim); mprog_give_trigger( victim, ch, obj ); if ( IS_SET( sysdata.save_flags, SV_GIVE ) && !char_died(ch) ) save_char_obj(ch); if ( IS_SET( sysdata.save_flags, SV_RECEIVE ) && !char_died(victim) ) save_char_obj(victim); if (char_died(ch) || char_died(victim) || (number && cnt >= number)) return; } } if ( !found ) { if ( fAll ) send_to_char( "You had nothing to give them.\n\r", ch ); else act(AT_PLAIN, "You have no $T.", ch, NULL, chk, TO_CHAR ); } } /* * Damage an object. -Thoric * Affect player's AC if necessary. * Make object into scraps if necessary. * Send message about damaged object. */ obj_ret damage_obj( OBJ_DATA *obj ) { CHAR_DATA *ch; obj_ret objcode; ch = obj->carried_by; objcode = rNONE; separate_obj( obj ); if ( ch ) act( AT_OBJECT, "($p gets damaged)", ch, obj, NULL, TO_CHAR ); else if ( obj->in_room && ( ch = obj->in_room->first_person ) != NULL ) { act( AT_OBJECT, "($p gets damaged)", ch, obj, NULL, TO_ROOM ); act( AT_OBJECT, "($p gets damaged)", ch, obj, NULL, TO_CHAR ); ch = NULL; } oprog_damage_trigger(ch, obj); if ( obj_extracted(obj) ) return rNONE; if (IS_OBJ_STAT2(obj, ITEM2_BRITTLE)) { make_scraps( obj, FALSE ); return rOBJ_SCRAPPED; } switch( obj->item_type ) { default: make_scraps( obj, FALSE ); objcode = rOBJ_SCRAPPED; break; case ITEM_CONTAINER: if (--obj->value[3] <= 0) { make_scraps( obj, FALSE ); objcode = rOBJ_SCRAPPED; } break; case ITEM_ARMOR: if ( ch && obj->value[0] >= 1 ) ch->armor += apply_ac( obj, obj->wear_loc ); if (--obj->value[0] <= 0) { if ( !IS_PKILL( ch ) && !in_arena( ch ) ) { make_scraps( obj, FALSE ); objcode = rOBJ_SCRAPPED; } else obj->value[0] = 1; } else if ( ch && obj->value[0] >= 1 ) ch->armor -= apply_ac( obj, obj->wear_loc ); break; case ITEM_WEAPON: if (--obj->value[0] <= 0) { if ( !IS_PKILL( ch ) && !in_arena( ch ) ) { make_scraps( obj, FALSE ); objcode = rOBJ_SCRAPPED; } else obj->value[0] = 1; } break; } return objcode; } /* * Remove an object. */ bool remove_obj( CHAR_DATA *ch, int iWear, bool fReplace ) { OBJ_DATA *obj, *tmpobj = NULL; if ( ( obj = get_eq_char( ch, iWear ) ) == NULL ) return TRUE; if ( !fReplace && carry_n(ch) + get_obj_number( obj ) > can_carry_n( ch ) ) { act( AT_PLAIN, "$d: you can't carry that many items.", ch, NULL, obj->name, TO_CHAR ); return FALSE; } if ( !fReplace ) return FALSE; if ( IS_OBJ_STAT(obj, ITEM_NOREMOVE) ) { act( AT_PLAIN, "You can't remove $p.", ch, obj, NULL, TO_CHAR ); return FALSE; } if ( obj == get_eq_char( ch, WEAR_WIELD ) && ( tmpobj = get_eq_char( ch, WEAR_DUAL_WIELD)) != NULL ) tmpobj->wear_loc = WEAR_WIELD; unequip_char( ch, obj ); act( AT_ACTION, "$n stops using $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You stop using $p.", ch, obj, NULL, TO_CHAR ); oprog_remove_trigger( ch, obj ); return TRUE; } /* * See if char could be capable of dual-wielding -Thoric */ bool could_dual( CHAR_DATA *ch ) { if ( IS_NPC(ch) ) return TRUE; if ( LEARNED(ch, gsn_dual_wield) ) return TRUE; return FALSE; } /* * See if char can dual wield at this time -Thoric */ bool can_dual( CHAR_DATA *ch ) { if ( !could_dual(ch) ) return FALSE; if ( get_eq_char( ch, WEAR_DUAL_WIELD ) ) { send_to_char( "You are already wielding two weapons!\n\r", ch ); return FALSE; } if ( get_eq_char( ch, WEAR_SHIELD ) ) { send_to_char( "You cannot dual wield while holding a shield!\n\r", ch ); return FALSE; } if ( get_eq_char( ch, WEAR_HOLD ) ) { send_to_char( "You cannot dual wield while holding something!\n\r", ch ); return FALSE; } return TRUE; } /* * Check to see if there is room to wear another object on this location * (Layered clothing support) */ bool can_layer( CHAR_DATA *ch, OBJ_DATA *obj, sh_int wear_loc ) { OBJ_DATA *otmp; sh_int bitlayers = 0; sh_int objlayers = obj->pIndexData->layers; for ( otmp = ch->first_carrying; otmp; otmp = otmp->next_content ) if ( otmp->wear_loc == wear_loc ) { if ( !otmp->pIndexData->layers ) { return FALSE; } else { bitlayers |= otmp->pIndexData->layers; } } if ( (bitlayers && !objlayers) || bitlayers > objlayers ) return FALSE; if ( !bitlayers || ((bitlayers & ~objlayers) == bitlayers) ) return TRUE; return FALSE; } int item_ego( OBJ_DATA *obj ) { int obj_ego; obj_ego = obj->rent; if ( strstr(obj->name,"scroll") || strstr(obj->name,"potion") || strstr(obj->name,"bag") || strstr(obj->name,"key") ) { return(0); } if (obj_ego < 0) obj_ego = 50000; if (obj_ego > 100000) obj_ego /= 250; else if (obj_ego < 5000) obj_ego /= 200; else obj_ego /= 500; return(obj_ego + number_range(1,6)); } int char_ego( CHAR_DATA *ch ) { int p_ego, tmp; if (!IS_NPC(ch)) { p_ego = GetMaxLevel(ch)+HowManyClasses(ch); if (p_ego>45) p_ego *= (p_ego-44); if (p_ego>40) p_ego += (p_ego-40); if (p_ego>30) p_ego += (p_ego-30); if (p_ego>20) p_ego += (p_ego-20); /* if (p_ego > 40) p_ego += (p_ego-39); else if (p_ego > 20) p_ego += (p_ego-20); */ } else { p_ego = 10000; } tmp = get_curr_int(ch)+get_curr_wis(ch)+get_curr_cha(ch); tmp /= 3; tmp *= GET_HIT(ch); tmp /= UMAX(1,GET_MAX_HIT(ch)); return(p_ego + tmp + number_range(1,6)); } bool obj_is_anti_class(CHAR_DATA *ch, OBJ_DATA *obj) { sh_int i; bool cflag = FALSE; for (i = FIRST_CLASS; i < MAX_CLASS; i++) { if (IS_ACTIVE(ch, i)) { cflag = FALSE; switch (i) { case CLASS_NONE: case LAST_CLASS: /* bugger */ break; case CLASS_MAGE: case CLASS_SORCERER: if (IS_OBJ_STAT(obj, ITEM_ANTI_MAGE)) cflag = TRUE; break; case CLASS_CLERIC: if (IS_OBJ_STAT(obj, ITEM_ANTI_CLERIC)) cflag = TRUE; break; case CLASS_THIEF: if (IS_OBJ_STAT(obj, ITEM_ANTI_THIEF)) cflag = TRUE; break; case CLASS_WARRIOR: if (IS_OBJ_STAT(obj, ITEM_ANTI_WARRIOR)) cflag = TRUE; break; case CLASS_VAMPIRE: if (IS_OBJ_STAT(obj, ITEM_ANTI_VAMPIRE)) cflag = TRUE; break; case CLASS_DRUID: if (IS_OBJ_STAT(obj, ITEM_ANTI_DRUID)) cflag = TRUE; break; case CLASS_RANGER: if (IS_OBJ_STAT2(obj, ITEM2_ANTI_RANGER)) cflag = TRUE; break; case CLASS_AMAZON: if (IS_OBJ_STAT2(obj, ITEM2_ANTI_AMAZON)) cflag = TRUE; break; case CLASS_PALADIN: if (IS_OBJ_STAT2(obj, ITEM2_ANTI_PALADIN)) cflag = TRUE; break; case CLASS_BARBARIAN: if (IS_OBJ_STAT2(obj, ITEM2_ANTI_BARBARIAN)) cflag = TRUE; break; case CLASS_PSIONIST: if (IS_OBJ_STAT2(obj, ITEM2_ANTI_PSI)) cflag = TRUE; break; case CLASS_ARTIFICER: if (IS_OBJ_STAT2(obj, ITEM2_ANTI_ARTIFICER)) cflag = TRUE; break; case CLASS_MONK: if (IS_OBJ_STAT2(obj, ITEM2_ANTI_MONK)) cflag = TRUE; break; case CLASS_NECROMANCER: if (IS_OBJ_STAT2(obj, ITEM2_ANTI_NECROMANCER)) cflag = TRUE; break; case CLASS_ANTIPALADIN: if (IS_OBJ_STAT2(obj, ITEM2_ANTI_APALADIN)) cflag = TRUE; break; } if (cflag && IS_OBJ_STAT2(obj, ITEM2_ONLY_CLASS)) return FALSE; if (!cflag && !IS_OBJ_STAT2(obj, ITEM2_ONLY_CLASS)) return FALSE; } } return TRUE; } int can_wear_obj(CHAR_DATA *ch, OBJ_DATA *obj) { if (ch->sex == SEX_MALE && IS_OBJ_STAT2(obj, ITEM2_ANTI_MEN)) return FALSE; if (ch->sex == SEX_FEMALE && IS_OBJ_STAT2(obj, ITEM2_ANTI_WOMEN)) return FALSE; if (ch->sex == SEX_NEUTRAL && IS_OBJ_STAT2(obj, ITEM2_ANTI_NEUTER)) return FALSE; if (obj_is_anti_class(ch, obj)) return FALSE; return TRUE; } /* * Wear one object. * Optional replacement of existing objects. * Big repetitive code, ick. * Restructured a bit to allow for specifying body location -Thoric */ void wear_obj( CHAR_DATA *ch, OBJ_DATA *obj, bool fReplace, sh_int wear_bit ) { char buf[MAX_STRING_LENGTH]; OBJ_DATA *tmpobj; sh_int bit, tmp; separate_obj( obj ); if ( char_ego( ch ) < item_ego( obj ) ) { sprintf( buf, "You can't figure out how to use it.\n\r" ); send_to_char( buf, ch ); act( AT_ACTION, "$n tries to use $p, but can't figure it out.", ch, obj, NULL, TO_ROOM ); return; } if (barbarian_magic_check(ch, obj)) { act( AT_PLAIN, "You sense magic on $p and drop it.", ch, obj, NULL, TO_CHAR ); act( AT_PLAIN, "$n recoils from $p and drops it.", ch, obj, NULL, TO_ROOM ); obj_from_char(obj); obj_to_room(obj, ch->in_room); return; } if ( !can_wear_obj(ch, obj)) { act( AT_MAGIC, "You are forbidden to use that item.", ch, NULL, NULL, TO_CHAR ); act( AT_ACTION, "$n tries to use $p, but is forbidden to do so.", ch, obj, NULL, TO_ROOM ); return; } if ( wear_bit > -1 ) { bit = wear_bit; if ( !CAN_WEAR(obj, 1 << bit) ) { if ( fReplace ) { switch( 1 << bit ) { case ITEM_HOLD: send_to_char( "You cannot hold that.\n\r", ch ); break; case ITEM_MISSILE_WIELD: case ITEM_WIELD: send_to_char( "You cannot wield that.\n\r", ch ); break; default: sprintf( buf, "You cannot wear that on your %s.\n\r", w_flags[bit] ); send_to_char( buf, ch ); } } return; } } else { for ( bit = -1, tmp = 1; tmp < 31; tmp++ ) { if ( CAN_WEAR(obj, 1 << tmp) ) { bit = tmp; break; } } } /* currently cannot have a light in non-light position */ if ( obj->item_type == ITEM_LIGHT ) { if ( !remove_obj( ch, WEAR_LIGHT, fReplace ) ) return; if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) ) { act( AT_ACTION, "$n holds $p as a light.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You hold $p as your light.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_LIGHT ); oprog_wear_trigger( ch, obj ); return; } if ( bit == -1 ) { if ( fReplace ) send_to_char( "You can't wear, wield, or hold that.\n\r", ch ); return; } switch ( 1 << bit ) { default: bug( "wear_obj: uknown/unused item_wear bit %d", bit ); if ( fReplace ) send_to_char( "You can't wear, wield, or hold that.\n\r", ch ); return; case ITEM_WEAR_FINGER: if ( !HAS_BODYPART(ch, PART_FINGERS) ) { send_to_char("How? You have no fingers!\n\r", ch); return; } if ( get_eq_char( ch, WEAR_FINGER_L ) && get_eq_char( ch, WEAR_FINGER_R ) && !remove_obj( ch, WEAR_FINGER_L, fReplace ) && !remove_obj( ch, WEAR_FINGER_R, fReplace ) ) return; if ( !get_eq_char( ch, WEAR_FINGER_L ) ) { if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n slips $s left finger into $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You slip your left finger into $p.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_FINGER_L ); oprog_wear_trigger( ch, obj ); return; } if ( !get_eq_char( ch, WEAR_FINGER_R ) ) { if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n slips $s right finger into $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You slip your right finger into $p.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_FINGER_R ); oprog_wear_trigger( ch, obj ); return; } bug( "Wear_obj: no free finger." ); send_to_char( "You already wear something on both fingers.\n\r", ch ); return; case 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 ) && !remove_obj( ch, WEAR_NECK_2, fReplace ) ) return; if ( !HAS_BODYPART(ch, PART_HEAD) ) { send_to_char("How? You have no neck, no head for that matter!\n\r", ch); return; } if ( !get_eq_char( ch, WEAR_NECK_1 ) ) { if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n wears $p around $s neck.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You wear $p around your neck.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_NECK_1 ); oprog_wear_trigger( ch, obj ); return; } if ( !get_eq_char( ch, WEAR_NECK_2 ) ) { if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n wears $p around $s neck.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You wear $p around your neck.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_NECK_2 ); oprog_wear_trigger( ch, obj ); return; } bug( "Wear_obj: no free neck." ); send_to_char( "You already wear two neck items.\n\r", ch ); return; case ITEM_WEAR_BODY: /* if ( !remove_obj( ch, WEAR_BODY, fReplace ) ) return; */ if ( !can_layer( ch, obj, WEAR_BODY ) ) { send_to_char( "It won't fit overtop of what you're already wearing.\n\r", ch ); return; } if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n fits $p on $s body.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You fit $p on your body.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_BODY ); oprog_wear_trigger( ch, obj ); return; case ITEM_WEAR_BACK: /* if ( !remove_obj( ch, WEAR_BACK, fReplace ) ) return; */ if ( !can_layer( ch, obj, WEAR_BACK ) ) { send_to_char( "It won't fit overtop of what you're already wearing.\n\r", ch ); return; } if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n fits $p on $s back.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You fit $p on your back.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_BACK ); oprog_wear_trigger( ch, obj ); return; case ITEM_WEAR_HEAD: if ( !HAS_BODYPART(ch, PART_HEAD) ) { send_to_char("How? You have no head!\n\r", ch); return; } if ( !remove_obj( ch, WEAR_HEAD, fReplace ) ) return; if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n dons $p upon $s head.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You don $p upon your head.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_HEAD ); oprog_wear_trigger( ch, obj ); return; case ITEM_WEAR_EYES: if ( !HAS_BODYPART(ch, PART_EYE) && !HAS_BODYPART(ch, PART_EYESTALKS)) { send_to_char("How? You have no eyes!\n\r", ch); return; } if ( !remove_obj( ch, WEAR_EYES, fReplace ) ) return; if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n places $p on $s eyes.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You place $p on your eyes.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_EYES ); oprog_wear_trigger( ch, obj ); return; case ITEM_WEAR_NOSE: if ( !HAS_BODYPART(ch, PART_HEAD) && !HAS_BODYPART(ch, PART_BEAK)) { send_to_char("How? You have no nose!\n\r", ch); return; } if ( !remove_obj( ch, WEAR_NOSE, fReplace ) ) return; if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n places $p in $s nose.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You place $p in your nose.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_NOSE ); oprog_wear_trigger( ch, obj ); return; case ITEM_WEAR_EARS: if ( !HAS_BODYPART(ch, PART_EAR) ) { send_to_char("How? You have no ears!\n\r", ch); return; } if ( get_eq_char( ch, WEAR_EAR_L ) != NULL && get_eq_char( ch, WEAR_EAR_R ) != NULL && !remove_obj( ch, WEAR_EAR_L, fReplace ) && !remove_obj( ch, WEAR_EAR_R, fReplace ) ) return; if ( !get_eq_char( ch, WEAR_EAR_L ) ) { if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n wears $p on $s ear.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You wear $p on your ear.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_EAR_L ); oprog_wear_trigger( ch, obj ); return; } if ( !get_eq_char( ch, WEAR_EAR_R ) ) { if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n wears $p on $s ear.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You wear $p on your ear.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_EAR_R ); oprog_wear_trigger( ch, obj ); return; } bug( "Wear_obj: no free ear." ); send_to_char( "You already wear two ear items.\n\r", ch ); return; case ITEM_WEAR_LEGS: /* if ( !remove_obj( ch, WEAR_LEGS, fReplace ) ) return; */ if ( !HAS_BODYPART(ch, PART_LEGS) ) { send_to_char("How? You have no legs!\n\r", ch); return; } if ( !can_layer( ch, obj, WEAR_LEGS ) ) { send_to_char( "It won't fit overtop of what you're already wearing.\n\r", ch ); return; } if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n slips into $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You slip into $p.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_LEGS ); oprog_wear_trigger( ch, obj ); return; case ITEM_WEAR_FEET: /* if ( !remove_obj( ch, WEAR_FEET, fReplace ) ) return; */ if ( !HAS_BODYPART(ch, PART_FEET) ) { send_to_char("How? You have no feet!\n\r", ch); return; } if ( !can_layer( ch, obj, WEAR_FEET ) ) { send_to_char( "It won't fit overtop of what you're already wearing.\n\r", ch ); return; } if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n wears $p on $s feet.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You wear $p on your feet.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_FEET ); oprog_wear_trigger( ch, obj ); return; case ITEM_WEAR_HANDS: /* if ( !remove_obj( ch, WEAR_HANDS, fReplace ) ) return; */ if ( !HAS_BODYPART(ch, PART_HANDS) ) { send_to_char("How? You have no hands!\n\r", ch); return; } if ( !can_layer( ch, obj, WEAR_HANDS ) ) { send_to_char( "It won't fit overtop of what you're already wearing.\n\r", ch ); return; } if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n wears $p on $s hands.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You wear $p on your hands.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_HANDS ); oprog_wear_trigger( ch, obj ); return; case ITEM_WEAR_ARMS: /* if ( !remove_obj( ch, WEAR_ARMS, fReplace ) ) return; */ if ( !HAS_BODYPART(ch, PART_ARMS) ) { send_to_char("How? You have no arms!\n\r", ch); return; } if ( !can_layer( ch, obj, WEAR_ARMS ) ) { send_to_char( "It won't fit overtop of what you're already wearing.\n\r", ch ); return; } if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n wears $p on $s arms.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You wear $p on your arms.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_ARMS ); oprog_wear_trigger( ch, obj ); return; case ITEM_WEAR_ABOUT: /* if ( !remove_obj( ch, WEAR_ABOUT, fReplace ) ) return; */ if ( !can_layer( ch, obj, WEAR_ABOUT ) ) { send_to_char( "It won't fit overtop of what you're already wearing.\n\r", ch ); return; } if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n wears $p about $s body.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You wear $p about your body.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_ABOUT ); oprog_wear_trigger( ch, obj ); return; case ITEM_WEAR_WAIST: /* if ( !remove_obj( ch, WEAR_WAIST, fReplace ) ) return; */ if ( !can_layer( ch, obj, WEAR_WAIST ) ) { send_to_char( "It won't fit overtop of what you're already wearing.\n\r", ch ); return; } if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n wears $p about $s waist.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You wear $p about your waist.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_WAIST ); oprog_wear_trigger( ch, obj ); return; case ITEM_WEAR_WRIST: if ( !HAS_BODYPART(ch, PART_ARMS) && !HAS_BODYPART(ch, PART_HANDS)) { send_to_char("How? You have no wrists!\n\r", ch); return; } if ( get_eq_char( ch, WEAR_WRIST_L ) && get_eq_char( ch, WEAR_WRIST_R ) && !remove_obj( ch, WEAR_WRIST_L, fReplace ) && !remove_obj( ch, WEAR_WRIST_R, fReplace ) ) return; if ( !get_eq_char( ch, WEAR_WRIST_L ) ) { if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n fits $p around $s left wrist.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You fit $p around your left wrist.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_WRIST_L ); oprog_wear_trigger( ch, obj ); return; } if ( !get_eq_char( ch, WEAR_WRIST_R ) ) { if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n fits $p around $s right wrist.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You fit $p around your right wrist.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_WRIST_R ); oprog_wear_trigger( ch, obj ); return; } bug( "Wear_obj: no free wrist." ); send_to_char( "You already wear two wrist items.\n\r", ch ); return; case ITEM_WEAR_SHIELD: if ( !HAS_BODYPART(ch, PART_HANDS) && !HAS_BODYPART(ch, PART_CLAWS) ) { send_to_char("How? You have no hands!\n\r", ch); return; } if ( get_eq_char( ch, WEAR_DUAL_WIELD ) || (get_eq_char( ch, WEAR_WIELD ) && get_eq_char( ch, WEAR_MISSILE_WIELD)) ) { send_to_char( "You can't use a shield AND two weapons!\n\r", ch ); return; } if ( !remove_obj( ch, WEAR_SHIELD, fReplace ) ) return; if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n uses $p as a shield.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You use $p as a shield.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_SHIELD ); oprog_wear_trigger( ch, obj ); return; case ITEM_MISSILE_WIELD: { OBJ_DATA *fw; if (obj->item_type!=ITEM_PROJECTILE) { act(AT_PLAIN,"$p is not a valid missile.",ch,obj,NULL,TO_CHAR); return; } if ( !HAS_BODYPART(ch, PART_HANDS) ) { send_to_char("How? You have no hands!\n\r", ch); return; } fw = get_eq_char(ch, WEAR_WIELD); if (!fw || fw->item_type != ITEM_MISSILE_WEAPON) { send_to_char("You must be wielding the projectile weapon you want to load.\n\r",ch); return; } if (get_curr_str(ch) < fw->value[0]) { sprintf(log_buf,"(%s) can't load (%s) because it requires (%d) strength to wield", GET_NAME(ch), fw->name, fw->value[0]); log_string_plus(log_buf, LOG_MONITOR, LEVEL_IMMORTAL, SEV_DEBUG); send_to_char("You aren't strong enough to draw such a mighty weapon.\n\r",ch); return; } if (obj->value[2] != fw->value[3]) { act(AT_PLAIN,"You can't load $p in that sort of weapon.",ch,obj,NULL,TO_CHAR); return; } if ( !remove_obj( ch, WEAR_MISSILE_WIELD, fReplace ) ) return; if ( get_obj_weight( obj ) > str_app[get_curr_str(ch)].wield ) { send_to_char( "It is too heavy for you to wield.\n\r", ch ); return; } if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n loads $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You load $p.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_MISSILE_WIELD ); WAIT_STATE(ch, PULSE_VIOLENCE*3); oprog_wear_trigger( ch, obj ); return; } case ITEM_WIELD: if ( !HAS_BODYPART(ch, PART_HANDS) ) { send_to_char("How? You have no hands!\n\r", ch); return; } if ( !could_dual(ch) ) { if ( !remove_obj( ch, WEAR_MISSILE_WIELD, fReplace ) ) return; if ( !remove_obj( ch, WEAR_WIELD, fReplace ) ) return; tmpobj = NULL; } else { if ( (tmpobj=get_eq_char(ch, WEAR_WIELD)) != NULL && (get_eq_char(ch, WEAR_MISSILE_WIELD) || get_eq_char(ch, WEAR_DUAL_WIELD) ) ) { send_to_char( "You're already wielding something.\n\r", ch ); return; } } if ( tmpobj ) { if ( can_dual(ch) ) { if ( get_obj_weight( obj ) + get_obj_weight( tmpobj ) > str_app[get_curr_str(ch)].wield ) { send_to_char( "It is too heavy for you to wield.\n\r", ch ); return; } if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n dual-wields $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You dual-wield $p.", ch, obj, NULL, TO_CHAR ); } if ( 1 << bit == ITEM_MISSILE_WIELD ) equip_char( ch, obj, WEAR_MISSILE_WIELD ); else equip_char( ch, obj, WEAR_DUAL_WIELD ); oprog_wear_trigger( ch, obj ); } return; } if ( get_obj_weight( obj ) > str_app[get_curr_str(ch)].wield ) { send_to_char( "It is too heavy for you to wield.\n\r", ch ); return; } if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n wields $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You wield $p.", ch, obj, NULL, TO_CHAR ); } if ( 1 << bit == ITEM_MISSILE_WIELD ) equip_char( ch, obj, WEAR_MISSILE_WIELD ); else equip_char( ch, obj, WEAR_WIELD ); oprog_wear_trigger( ch, obj ); return; case ITEM_WEAR_ANKLE: if ( !HAS_BODYPART(ch, PART_LEGS) ) { send_to_char("How? You have no ankles!\n\r", ch); return; } if ( get_eq_char( ch, WEAR_ANKLE_L ) && get_eq_char( ch, WEAR_ANKLE_R ) && !remove_obj( ch, WEAR_ANKLE_L, fReplace ) && !remove_obj( ch, WEAR_ANKLE_R, fReplace ) ) return; if ( !get_eq_char( ch, WEAR_ANKLE_L ) ) { if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n slips $s left ankle into $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You slip your left ankle into $p.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_ANKLE_L ); oprog_wear_trigger( ch, obj ); return; } if ( !get_eq_char( ch, WEAR_ANKLE_R ) ) { if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) && !actiondesc(ch,obj,NULL) ) { act( AT_ACTION, "$n slips $s right ankle into $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You slip your right ankle into $p.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_ANKLE_R ); oprog_wear_trigger( ch, obj ); return; } bug( "Wear_obj: no free ankle." ); send_to_char( "You already wear something on both ankles.\n\r", ch ); return; case ITEM_HOLD: if ( !HAS_BODYPART(ch, PART_HANDS) && !HAS_BODYPART(ch, PART_CLAWS) ) { send_to_char("How? You have no hands!\n\r", ch); return; } if ( get_eq_char( ch, WEAR_DUAL_WIELD ) || (get_eq_char( ch, WEAR_WIELD ) && get_eq_char( ch, WEAR_MISSILE_WIELD)) ) { send_to_char( "You cannot hold something AND two weapons!\n\r", ch ); return; } if ( !remove_obj( ch, WEAR_HOLD, fReplace ) ) return; if ( obj->item_type == ITEM_WAND || obj->item_type == ITEM_STAFF || obj->item_type == ITEM_FOOD || obj->item_type == ITEM_COOK || obj->item_type == ITEM_PILL || obj->item_type == ITEM_POTION || obj->item_type == ITEM_SCROLL || obj->item_type == ITEM_DRINK_CON || obj->item_type == ITEM_BLOOD || obj->item_type == ITEM_PIPE || obj->item_type == ITEM_HERB || obj->item_type == ITEM_KEY || !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) ) { if (!actiondesc(ch,obj,NULL)) { act( AT_ACTION, "$n holds $p in $s hands.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You hold $p in your hands.", ch, obj, NULL, TO_CHAR ); } } equip_char( ch, obj, WEAR_HOLD ); oprog_wear_trigger( ch, obj ); return; } } void do_wear( CHAR_DATA *ch, char *argument ) { char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; OBJ_DATA *obj; sh_int wear_bit; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if ( (!str_cmp(arg2, "on") || !str_cmp(arg2, "upon") || !str_cmp(arg2, "around")) && argument[0] != '\0' ) argument = one_argument( argument, arg2 ); if ( arg1[0] == '\0' ) { send_to_char( "Wear, wield, or hold what?\n\r", ch ); return; } if ( ms_find_obj(ch) ) return; if ( !str_cmp( arg1, "all" ) ) { OBJ_DATA *obj_next; for ( obj = ch->first_carrying; obj; obj = obj_next ) { obj_next = obj->next_content; if ( obj->wear_loc == WEAR_NONE && can_see_obj( ch, obj ) ) { wear_obj( ch, obj, FALSE, -1 ); if (char_died(ch)) return; } } return; } else { if ( ( obj = get_obj_carry( ch, arg1 ) ) == NULL ) { send_to_char( "You do not have that item.\n\r", ch ); return; } if ( arg2[0] != '\0' ) wear_bit = get_wflag(arg2); else wear_bit = -1; wear_obj( ch, obj, TRUE, wear_bit ); } return; } void do_remove( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; OBJ_DATA *obj, *obj_next; one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Remove what?\n\r", ch ); return; } if ( ms_find_obj(ch) ) return; if ( !str_cmp( arg, "all" ) ) /* SB Remove all */ { for ( obj = ch->first_carrying; obj != NULL ; obj = obj_next ) { obj_next = obj->next_content; if ( obj->wear_loc != WEAR_NONE && can_see_obj ( ch, obj ) ) remove_obj ( ch, obj->wear_loc, TRUE ); } return; } if ( ( obj = get_obj_wear( ch, arg ) ) == NULL ) { send_to_char( "You are not using that item.\n\r", ch ); return; } if ( (obj_next=get_eq_char(ch, obj->wear_loc)) != obj ) { act( AT_PLAIN, "You must remove $p first.", ch, obj_next, NULL, TO_CHAR ); return; } remove_obj( ch, obj->wear_loc, TRUE ); return; } void do_bury( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; OBJ_DATA *obj; bool shovel; sh_int move; one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "What do you wish to bury?\n\r", ch ); return; } if ( ms_find_obj(ch) ) return; shovel = FALSE; for ( obj = ch->first_carrying; obj; obj = obj->next_content ) if ( obj->item_type == ITEM_SHOVEL ) { shovel = TRUE; break; } obj = get_obj_list_rev( ch, arg, ch->in_room->last_content ); if ( !obj ) { send_to_char( "You can't find it.\n\r", ch ); return; } separate_obj(obj); if ( !CAN_WEAR(obj, ITEM_TAKE) ) { if ( !IS_OBJ_STAT( obj, ITEM_CLANCORPSE ) || IS_NPC(ch) || !IS_SET( ch->pcdata->flags, PCFLAG_DEADLY ) ) { act( AT_PLAIN, "You cannot bury $p.", ch, obj, 0, TO_CHAR ); return; } } switch( ch->in_room->sector_type ) { case SECT_CITY: case SECT_INSIDE: send_to_char( "The floor is too hard to dig through.\n\r", ch ); return; case SECT_WATER_SWIM: case SECT_WATER_NOSWIM: case SECT_UNDERWATER: send_to_char( "You cannot bury something here.\n\r", ch ); return; case SECT_AIR: send_to_char( "What? In the air?!\n\r", ch ); return; } if ( obj->weight > (UMAX(5, (can_carry_w(ch) / 10))) && !shovel ) { send_to_char( "You'd need a shovel to bury something that big.\n\r", ch ); return; } move = (obj->weight * 50 * (shovel ? 1 : 5)) / UMAX(1, can_carry_w(ch)); move = URANGE( 2, move, 1000 ); if ( move > GET_MOVE(ch) ) { send_to_char( "You don't have the energy to bury something of that size.\n\r", ch ); return; } GET_MOVE(ch) -= move; if ( obj->item_type == ITEM_CORPSE_NPC || obj->item_type == ITEM_CORPSE_PC ) adjust_favor( ch, 6, 1 ); act( AT_ACTION, "You solemnly bury $p...", ch, obj, NULL, TO_CHAR ); act( AT_ACTION, "$n solemnly buries $p...", ch, obj, NULL, TO_ROOM ); SET_BIT( obj->extra_flags, ITEM_BURRIED ); WAIT_STATE( ch, URANGE( 10, move / 2, 100 ) ); return; } void do_sacrifice( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; char buf[MAX_STRING_LENGTH]; char name[50]; OBJ_DATA *obj; one_argument( argument, arg ); if ( arg[0] == '\0' || !str_cmp( arg, ch->name ) ) { act( AT_ACTION, "$n offers $mself to $s deity, who graciously declines.", ch, NULL, NULL, TO_ROOM ); send_to_char( "Your deity appreciates your offer and may accept it later.\n\r", ch ); return; } if ( ms_find_obj(ch) ) return; obj = get_obj_list_rev( ch, arg, ch->in_room->last_content ); if ( !obj ) { send_to_char( "You can't find it.\n\r", ch ); return; } if ( !IS_NPC( ch ) && ch->pcdata->deity && ch->pcdata->deity->name[0] != '\0' ) { strcpy( name, ch->pcdata->deity->name ); } else if ( !IS_NPC( ch ) && IS_GUILDED(ch) && sysdata.guild_overseer[0] != '\0' ) { strcpy( name, sysdata.guild_overseer ); } else if ( !IS_NPC( ch ) && ch->pcdata->clan && ch->pcdata->clan->deity[0] != '\0' ) { strcpy( name, ch->pcdata->clan->deity ); } else { if (!IS_IMMORTAL(ch)) { send_to_char("You do not have a deity to sacrifice it to.\n\r", ch); return; } strcpy( name, "Nobody"); } separate_obj(obj); if ( !CAN_WEAR(obj, ITEM_TAKE) ) { act( AT_PLAIN, "$p is not an acceptable sacrifice.", ch, obj, 0, TO_CHAR ); return; } GET_MONEY(ch,obj->currtype) += 1; if ( obj->item_type == ITEM_CORPSE_NPC || obj->item_type == ITEM_CORPSE_PC ) adjust_favor( ch, 5, 1 ); sprintf( buf, "%s gives you one %s coin for your sacrifice.\n\r", name, curr_types[obj->currtype] ); send_to_char( buf, ch ); sprintf( buf, "$n sacrifices $p to %s.", name ); act( AT_ACTION, buf, ch, obj, NULL, TO_ROOM ); oprog_sac_trigger( ch, obj ); if ( obj_extracted(obj) ) return; separate_obj( obj ); extract_obj( obj ); return; } void do_use( CHAR_DATA *ch, char *argument ) { char arg1[MAX_INPUT_LENGTH]; CHAR_DATA *vch; OBJ_DATA *obj; ch_ret retcode; argument = one_argument( argument, arg1 ); if ( !*arg1 ) { send_to_char("Use what?\n\r", ch); return; } if ( ( obj = get_eq_char( ch, WEAR_HOLD ) ) == NULL ) { send_to_char( "You hold nothing in your hand.\n\r", ch ); return; } if ( !nifty_is_name( arg1, obj->name ) ) { send_to_char( "You do not hold that in your hand.\n\r", ch ); return; } if ( obj->item_type == ITEM_STAFF ) { CHAR_DATA *vch_next; int sn; if ( ( sn = obj->value[3] ) < 0 || sn >= top_sn || skill_table[sn]->spell_fun == NULL ) { bug( "Do_use(staff): bad sn %d.", sn ); return; } WAIT_STATE( ch, 2 * PULSE_VIOLENCE ); if ( obj->value[2] > 0 ) { if ( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) ) { act( AT_MAGIC, "$n brandishes $p.", ch, obj, NULL, TO_ROOM ); act( AT_MAGIC, "You brandish $p.", ch, obj, NULL, TO_CHAR ); } for ( vch = ch->in_room->first_person; vch; vch = vch_next ) { vch_next = vch->next_in_room; if ( !IS_NPC( vch ) && vch->pcdata->wizinvis >= LEVEL_IMMORTAL ) continue; else switch ( skill_table[sn]->target ) { default: bug( "Do_use(staff): bad target for sn %d.", sn ); return; case TAR_IGNORE: if ( vch != ch ) continue; break; case TAR_CHAR_OFFENSIVE: if ( IS_NPC(ch) ? IS_NPC(vch) : !IS_NPC(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; } retcode = obj_cast_spell( obj->value[3], obj->value[0], ch, vch, NULL ); if ( retcode == rCHAR_DIED || retcode == rBOTH_DIED ) { bug( "do_use(staff): char died" ); return; } } } if ( --obj->value[2] <= 0 ) { act( AT_MAGIC, "$p blazes bright and vanishes from $n's hands!", ch, obj, NULL, TO_ROOM ); act( AT_MAGIC, "$p blazes bright and is gone!", ch, obj, NULL, TO_CHAR ); extract_obj( obj ); } return; } else if ( obj->item_type == ITEM_WAND ) { char arg[MAX_INPUT_LENGTH]; OBJ_DATA *obj2; one_argument( argument, arg ); if ( arg[0] == '\0' && !ch->fighting ) { send_to_char( "Zap whom or what?\n\r", ch ); return; } obj2 = NULL; if ( arg[0] == '\0' ) { if ( ch->fighting ) { vch = who_fighting( ch ); } else { send_to_char( "Zap whom or what?\n\r", ch ); return; } } else { if ( ( vch = get_char_room ( ch, arg ) ) == NULL && ( obj2 = get_obj_here ( ch, arg ) ) == NULL ) { send_to_char( "You can't find it.\n\r", ch ); return; } } WAIT_STATE( ch, 1 * PULSE_VIOLENCE ); if ( obj->value[2] > 0 ) { if ( vch ) { if ( !oprog_use_trigger( ch, obj, vch, NULL, NULL ) ) { act( AT_MAGIC, "$n aims $p at $N.", ch, obj, vch, TO_ROOM ); act( AT_MAGIC, "You aim $p at $N.", ch, obj, vch, TO_CHAR ); } } else { if ( !oprog_use_trigger( ch, obj, NULL, obj2, NULL ) ) { act( AT_MAGIC, "$n aims $p at $P.", ch, obj, obj2, TO_ROOM ); act( AT_MAGIC, "You aim $p at $P.", ch, obj, obj2, TO_CHAR ); } } retcode = obj_cast_spell( obj->value[3], obj->value[0], ch, vch, obj2 ); if ( retcode == rCHAR_DIED || retcode == rBOTH_DIED ) { bug( "do_use(wand): char died" ); return; } } if ( --obj->value[2] <= 0 ) { act( AT_MAGIC, "$p explodes into fragments.", ch, obj, NULL, TO_ROOM ); act( AT_MAGIC, "$p explodes into fragments.", ch, obj, NULL, TO_CHAR ); extract_obj( obj ); } return; } send_to_char("You cannot use that.\n\r", ch); } void do_brandish( CHAR_DATA *ch, char *argument ) { CHAR_DATA *vch; CHAR_DATA *vch_next; OBJ_DATA *staff; ch_ret retcode; int sn; if ( ( staff = get_eq_char( ch, WEAR_HOLD ) ) == NULL ) { send_to_char( "You hold nothing in your hand.\n\r", ch ); return; } if ( staff->item_type != ITEM_STAFF ) { send_to_char( "You can brandish only with a staff.\n\r", ch ); return; } if ( ( sn = staff->value[3] ) < 0 || sn >= top_sn || skill_table[sn]->spell_fun == NULL ) { bug( "Do_brandish: bad sn %d.", sn ); return; } WAIT_STATE( ch, 2 * PULSE_VIOLENCE ); if ( staff->value[2] > 0 ) { if ( !oprog_use_trigger( ch, staff, NULL, NULL, NULL ) ) { act( AT_MAGIC, "$n brandishes $p.", ch, staff, NULL, TO_ROOM ); act( AT_MAGIC, "You brandish $p.", ch, staff, NULL, TO_CHAR ); } for ( vch = ch->in_room->first_person; vch; vch = vch_next ) { vch_next = vch->next_in_room; if (char_died(vch)) continue; if ( !IS_NPC( vch ) && vch->pcdata->wizinvis >= LEVEL_IMMORTAL ) continue; else switch ( skill_table[sn]->target ) { default: bug( "Do_brandish: bad target for sn %d.", sn ); return; case TAR_IGNORE: if ( vch != ch ) continue; break; case TAR_CHAR_OFFENSIVE: if ( IS_NPC(ch) ? IS_NPC(vch) : !IS_NPC(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; } retcode = obj_cast_spell( staff->value[3], staff->value[0], ch, vch, NULL ); if ( retcode == rCHAR_DIED || retcode == rBOTH_DIED ) { bug( "do_brandish: char died" ); return; } } } if ( --staff->value[2] <= 0 ) { act( AT_MAGIC, "$p blazes bright and vanishes from $n's hands!", ch, staff, NULL, TO_ROOM ); act( AT_MAGIC, "$p blazes bright and is gone!", ch, staff, NULL, TO_CHAR ); extract_obj( staff ); } return; } void do_zap( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; OBJ_DATA *wand; OBJ_DATA *obj; ch_ret retcode; one_argument( argument, arg ); if ( arg[0] == '\0' && !ch->fighting ) { send_to_char( "Zap whom or what?\n\r", ch ); return; } if ( ( wand = get_eq_char( ch, WEAR_HOLD ) ) == NULL ) { send_to_char( "You hold nothing in your hand.\n\r", ch ); return; } if ( wand->item_type != ITEM_WAND ) { send_to_char( "You can zap only with a wand.\n\r", ch ); return; } obj = NULL; if ( arg[0] == '\0' ) { if ( ch->fighting ) { victim = who_fighting( ch ); } else { send_to_char( "Zap whom or what?\n\r", ch ); return; } } else { if ( ( victim = get_char_room ( ch, arg ) ) == NULL && ( obj = get_obj_here ( ch, arg ) ) == NULL ) { send_to_char( "You can't find it.\n\r", ch ); return; } } WAIT_STATE( ch, 1 * PULSE_VIOLENCE ); if ( wand->value[2] > 0 ) { if ( victim ) { if ( !oprog_use_trigger( ch, wand, victim, NULL, NULL ) ) { act( AT_MAGIC, "$n aims $p at $N.", ch, wand, victim, TO_ROOM ); act( AT_MAGIC, "You aim $p at $N.", ch, wand, victim, TO_CHAR ); } } else { if ( !oprog_use_trigger( ch, wand, NULL, obj, NULL ) ) { act( AT_MAGIC, "$n aims $p at $P.", ch, wand, obj, TO_ROOM ); act( AT_MAGIC, "You aim $p at $P.", ch, wand, obj, TO_CHAR ); } } retcode = obj_cast_spell( wand->value[3], wand->value[0], ch, victim, obj ); if ( retcode == rCHAR_DIED || retcode == rBOTH_DIED ) { bug( "do_zap: char died" ); return; } } if ( --wand->value[2] <= 0 ) { act( AT_MAGIC, "$p explodes into fragments.", ch, wand, NULL, TO_ROOM ); act( AT_MAGIC, "$p explodes into fragments.", ch, wand, NULL, TO_CHAR ); extract_obj( wand ); } return; } /* * Save items in a clan storage room -Scryn & Thoric */ void save_clan_storeroom( CHAR_DATA *ch, CLAN_DATA *clan ) { FILE *fp; char filename[256]; /* sh_int templvl; */ OBJ_DATA *contents; if ( !clan ) { bug( "save_clan_storeroom: Null clan pointer!" ); return; } if ( !ch ) { bug ("save_clan_storeroom: Null ch pointer!"); return; } sprintf( filename, "%s%s.vault", CLAN_DIR, clan->filename ); if ( ( fp = fopen( filename, "w" ) ) == NULL ) { bug( "save_clan_storeroom: fopen" ); perror( filename ); } else { /* templvl = ch->level; ch->level = LEVEL_HERO; */ /* make sure EQ doesn't get lost */ contents = ch->in_room->last_content; if (contents) fwrite_obj(ch, contents, fp, 0, OS_CARRY ); fprintf( fp, "#END\n" ); /* ch->level = templvl; */ fclose( fp ); return; } return; } /* put an item on auction, or see the stats on the current item or bet */ void do_auction (CHAR_DATA *ch, char *argument) { OBJ_DATA *obj; char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; char buf[MAX_STRING_LENGTH]; argument = one_argument (argument, arg1); if (IS_NPC(ch)) /* NPC can be extracted at any time and thus can't auction! */ return; if ( ( time_info.hour > 18 || time_info.hour < 9 ) && auction->item == NULL ) { set_char_color ( AT_LBLUE, ch ); send_to_char ( "\n\rThe auctioneer has retired for the evening...\n\r", ch ); return; } if (arg1[0] == '\0') { if (auction->item != NULL) { AFFECT_DATA *paf; obj = auction->item; /* show item data here */ if (auction->bet > 0) sprintf (buf, "Current bid on this item is %d %s.\n\r",auction->bet,curr_types[auction->currtype]); else sprintf (buf, "No bids on this item have been received.\n\r"); set_char_color ( AT_BLUE, ch ); send_to_char (buf,ch); /* spell_identify (0, LEVEL_HERO - 1, ch, auction->item); */ sprintf( buf, "Object '%s' is %s, special properties: %s %s %s.\n\rIts weight is %d, value is %d %s.\n\r", obj->name, aoran( item_type_name( obj ) ), flag_string(obj->extra_flags, o_flags), flag_string(obj->extra_flags2, o2_flags), flag_string(obj->magic_flags, mag_flags), obj->weight, obj->cost, curr_types[obj->currtype]); set_char_color( AT_LBLUE, ch ); send_to_char( buf, ch ); sprintf( buf, "Worn on: %s\n\r", flag_string(obj->wear_flags -1, w_flags ) ); send_to_char( buf, ch ); set_char_color( AT_BLUE, ch ); switch ( obj->item_type ) { case ITEM_PILL: case ITEM_SCROLL: case ITEM_POTION: sprintf( buf, "Level %d spells of:", obj->value[0] ); send_to_char( buf, ch ); if ( obj->value[1] >= 0 && obj->value[1] < top_sn ) { send_to_char( " '", ch ); send_to_char( skill_table[obj->value[1]]->name, ch ); send_to_char( "'", ch ); } if ( obj->value[2] >= 0 && obj->value[2] < top_sn ) { send_to_char( " '", ch ); send_to_char( skill_table[obj->value[2]]->name, ch ); send_to_char( "'", ch ); } if ( obj->value[3] >= 0 && obj->value[3] < top_sn ) { send_to_char( " '", ch ); send_to_char( skill_table[obj->value[3]]->name, ch ); send_to_char( "'", ch ); } send_to_char( ".\n\r", ch ); break; case ITEM_WAND: case ITEM_STAFF: sprintf( buf, "Has %d(%d) charges of level %d", obj->value[1], obj->value[2], obj->value[0] ); send_to_char( buf, ch ); if ( obj->value[3] >= 0 && obj->value[3] < top_sn ) { send_to_char( " '", ch ); send_to_char( skill_table[obj->value[3]]->name, ch ); send_to_char( "'", ch ); } send_to_char( ".\n\r", ch ); break; case ITEM_WEAPON: sprintf( buf, "Damage is %d to %d (average %d).\n\r", obj->value[1], obj->value[2], ( obj->value[1] + obj->value[2] ) / 2 ); send_to_char( buf, ch ); break; case ITEM_ARMOR: sprintf( buf, "Armor class is %d.\n\r", obj->value[0] ); send_to_char( buf, ch ); break; } /* for ( paf = obj->pIndexData->first_affect; paf; paf = paf->next ) showaffect( ch, paf ); */ for ( paf = obj->first_affect; paf; paf = paf->next ) showaffect( ch, paf ); if ( ( obj->item_type == ITEM_CONTAINER ) && ( obj->first_content ) ) { set_char_color( AT_OBJECT, ch ); send_to_char( "Contents:\n\r", ch ); show_list_to_char( obj->first_content, ch, TRUE, FALSE ); } if (IS_IMMORTAL(ch)) { sprintf(buf, "Seller: %s. Bidder: %s. Round: %d.\n\r", auction->seller->name, auction->buyer->name, (auction->going + 1)); send_to_char(buf, ch); sprintf(buf, "Time left in round: %d.\n\r", auction->pulse); send_to_char(buf, ch); } return; } else { set_char_color ( AT_LBLUE, ch ); send_to_char ( "\n\rThere is nothing being auctioned right now. What would you like to auction?\n\r", ch ); return; } } if ( IS_IMMORTAL(ch) && !str_cmp(arg1,"stop")) { if (auction->item == NULL) { send_to_char ("There is no auction to stop.\n\r",ch); return; } else /* stop the auction */ { set_char_color ( AT_LBLUE, ch ); sprintf (buf,"Sale of %s has been stopped by an Immortal.", auction->item->short_descr); talk_auction (buf); obj_to_char (auction->item, auction->seller); if ( IS_SET( sysdata.save_flags, SV_AUCTION ) ) save_char_obj(auction->seller); auction->item = NULL; if (auction->buyer != NULL && auction->buyer != auction->seller) /* return money to the buyer */ { GET_MONEY(auction->buyer, auction->currtype) += auction->bet; send_to_char ("Your money has been returned.\n\r",auction->buyer); } return; } } if (!str_cmp(arg1,"bid") ) { if (auction->item != NULL) { int newbet; if ( ch == auction->seller) { send_to_char("You can't bid on your own item!\n\r", ch); return; } /* make - perhaps - a bet now */ if (argument[0] == '\0') { send_to_char ("Bid how much?\n\r",ch); return; } newbet = parsebet (auction->bet, argument); /* ch_printf( ch, "Bid: %d\n\r",newbet); */ if (newbet < auction->starting) { send_to_char("You must place a bid that is higher than the starting bet.\n\r", ch); return; } /* to avoid slow auction, use a bigger amount than 100 if the bet is higher up - changed to 10000 for our high economy */ if (newbet < (auction->bet + 1000)) { send_to_char ("You must at least bid 10000 coins over the current bid.\n\r",ch); return; } if (newbet > GET_MONEY(ch,auction->currtype)) { ch_printf(ch, "You don't have that much %s!\n\r",curr_types[auction->currtype]); return; } if (newbet > 2000000000) { send_to_char("You can't bid over 2 billion coins.\n\r", ch); return; } /* the actual bet is OK! */ /* return the money to the last buyer, if one exists */ if (auction->buyer != NULL && auction->buyer != auction->seller) GET_MONEY(auction->buyer,auction->currtype) += auction->bet; GET_MONEY(ch,auction->currtype) -= newbet; /* substract the money - important :) */ if ( IS_SET( sysdata.save_flags, SV_AUCTION ) ) save_char_obj(ch); auction->buyer = ch; auction->bet = newbet; auction->going = 0; auction->pulse = PULSE_AUCTION; /* start the auction over again */ sprintf (buf,"A bid of %d %s has been received on %s.\n\r",newbet,curr_types[auction->currtype],auction->item->short_descr); talk_auction (buf); return; } else { send_to_char ("There isn't anything being auctioned right now.\n\r",ch); return; } } /* finally... */ if ( ms_find_obj(ch) ) return; obj = get_obj_carry (ch, arg1); /* does char have the item ? */ if (obj == NULL) { send_to_char ("You aren't carrying that.\n\r",ch); return; } if (obj->timer > 0) { send_to_char ("You can't auction objects that are decaying.\n\r", ch); return; } argument = one_argument (argument, arg2); if (arg2[0] == '\0') { auction->starting = 0; strcpy(arg2, "0"); } if ( !is_number(arg2) ) { send_to_char("You must input a number at which to start the auction.\n\r", ch); return; } if ( atoi(arg2) < 0 ) { send_to_char("You can't auction something for less than 0 coins!\n\r", ch); return; } auction->currtype = get_currency_type(argument); if (auction->item == NULL) switch (obj->item_type) { default: act (AT_TELL, "You cannot auction $Ts.",ch, NULL, item_type_name (obj), TO_CHAR); return; /* insert any more item types here... items with a timer MAY NOT BE AUCTIONED! */ case ITEM_LIGHT: case ITEM_TREASURE: case ITEM_POTION: case ITEM_CONTAINER: case ITEM_DRINK_CON: case ITEM_FOOD: case ITEM_PEN: case ITEM_BOAT: case ITEM_PILL: case ITEM_PIPE: case ITEM_HERB_CON: case ITEM_INCENSE: case ITEM_FIRE: case ITEM_RUNEPOUCH: case ITEM_MAP: case ITEM_BOOK: case ITEM_RUNE: case ITEM_MATCH: case ITEM_HERB: case ITEM_WEAPON: case ITEM_ARMOR: case ITEM_STAFF: case ITEM_WAND: case ITEM_SCROLL: separate_obj(obj); obj_from_char (obj); if ( IS_SET( sysdata.save_flags, SV_AUCTION ) ) save_char_obj(ch); auction->item = obj; auction->bet = 0; if (auction->currtype == CURR_NONE) auction->currtype = obj->currtype; auction->buyer = ch; auction->seller = ch; auction->pulse = PULSE_AUCTION; auction->going = 0; auction->starting = atoi(arg2); if (auction->starting > 0) auction->bet = auction->starting; sprintf (buf, "A new item is being auctioned: %s at %d %s.", obj->short_descr, auction->starting, curr_types[auction->currtype]); talk_auction (buf); return; } /* switch */ else { act (AT_TELL, "Try again later - $p is being auctioned right now!",ch,auction->item,NULL,TO_CHAR); WAIT_STATE( ch, 1.5 * PULSE_VIOLENCE ); return; } } /* Make objects in rooms that are nofloor fall - Scryn 1/23/96 */ void obj_fall( OBJ_DATA *obj, bool through ) { EXIT_DATA *pexit; ROOM_INDEX_DATA *to_room; static int fall_count; char buf[MAX_STRING_LENGTH]; static bool is_falling; /* Stop loops from the call to obj_to_room() -- Altrag */ if ( !obj->in_room || is_falling ) return; if (fall_count > 30) { bug( "object falling in loop more than 30 times" ); extract_obj(obj); fall_count = 0; return; } if ( IS_SET( obj->in_room->room_flags, ROOM_NOFLOOR ) && (pexit = get_exit(obj->in_room, DIR_DOWN)) && !IS_OBJ_STAT( obj, ITEM_MAGIC ) ) { to_room = pexit->to_room; if (through) fall_count++; else fall_count = 0; if (obj->in_room == to_room) { sprintf(buf, "Object falling into same room, room %d", to_room->vnum); bug( buf, 0 ); extract_obj( obj ); return; } if (obj->in_room->first_person) { act( AT_PLAIN, "$p falls far below...", obj->in_room->first_person, obj, NULL, TO_ROOM ); act( AT_PLAIN, "$p falls far below...", obj->in_room->first_person, obj, NULL, TO_CHAR ); } obj_from_room( obj ); is_falling = TRUE; obj = obj_to_room( obj, to_room ); is_falling = FALSE; if (obj->in_room->first_person) { act( AT_PLAIN, "$p falls from above...", obj->in_room->first_person, obj, NULL, TO_ROOM ); act( AT_PLAIN, "$p falls from above...", obj->in_room->first_person, obj, NULL, TO_CHAR ); } if (!IS_SET( obj->in_room->room_flags, ROOM_NOFLOOR ) && through ) { /* int dam = (int)9.81*sqrt(fall_count*2/9.81)*obj->weight/2; */ int dam = fall_count*obj->weight/2; /* Damage players */ if ( obj->in_room->first_person && number_percent() > 15 ) { CHAR_DATA *rch; CHAR_DATA *vch = NULL; int chcnt = 0; for ( rch = obj->in_room->first_person; rch; rch = rch->next_in_room, chcnt++ ) if ( number_range( 0, chcnt ) == 0 ) vch = rch; act( AT_PLAIN, "$p falls on $n!", vch, obj, NULL, TO_ROOM ); act( AT_PLAIN, "$p falls on you!", vch, obj, NULL, TO_CHAR ); damage( vch, vch, dam*GetMaxLevel(vch), TYPE_UNDEFINED ); } /* Damage objects */ switch( obj->item_type ) { case ITEM_WEAPON: case ITEM_ARMOR: if ( (obj->value[0] - dam) <= 0 ) { if (obj->in_room->first_person) { act( AT_PLAIN, "$p is destroyed by the fall!", obj->in_room->first_person, obj, NULL, TO_ROOM ); act( AT_PLAIN, "$p is destroyed by the fall!", obj->in_room->first_person, obj, NULL, TO_CHAR ); } make_scraps(obj, TRUE); } else obj->value[0] -= dam; break; default: if ( (dam*15) > get_obj_resistance(obj) ) { if (obj->in_room->first_person) { act( AT_PLAIN, "$p is destroyed by the fall!", obj->in_room->first_person, obj, NULL, TO_ROOM ); act( AT_PLAIN, "$p is destroyed by the fall!", obj->in_room->first_person, obj, NULL, TO_CHAR ); } make_scraps(obj, TRUE); } break; } } obj_fall( obj, TRUE ); } return; } void do_donate( CHAR_DATA *ch, char *argument ) { do_drop( ch, argument ); } void do_junk( CHAR_DATA *ch, char *argument ) { do_drop( ch, argument ); } void do_nickname( CHAR_DATA *ch, char *argument ) { char arg1[MAX_INPUT_LENGTH]; OBJ_DATA *obj; argument = one_argument( argument, arg1 ); if ( arg1[0] == '\0' ) { send_to_char( "Nickname what?\n\r", ch ); return; } if ( ( obj = get_obj_carry( ch, arg1 ) ) == NULL ) { send_to_char( "You do not have that item.\n\r", ch ); return; } if ( argument[0] == '\0' ) { send_to_char( "Give it what nickname?\n\r", ch ); return; } if ( obj->nickname ) STRFREE(obj->nickname); obj->nickname = STRALLOC(argument); act(AT_MAGIC, "You give $p the nickname '$T'", ch, obj, obj->nickname, TO_CHAR); }