#include <stdio.h> #include <string.h> #include "mud.h" /* * Local functions. */ void get_obj( CHAR_DATA * ch, OBJ_DATA * obj, OBJ_DATA * container ); bool remove_obj( CHAR_DATA * ch, int iWear, bool fReplace ); void wear_obj( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace, short wear_bit ); bool job_trigger( CHAR_DATA * victim, CHAR_DATA * ch, OBJ_DATA * obj ); void wear_obj_dispatch_fun( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace, int wear_loc ); void write_corpses( const CHAR_DATA * ch, const char *name ); /* * how resistant an object is to damage -Thoric */ short get_obj_resistance( const OBJ_DATA * obj ) { short resist = number_fuzzy( MAX_ITEM_IMPACT ); /* magical items are more resistant */ if( IS_OBJ_STAT( obj, ITEM_MAGIC ) ) resist += number_fuzzy( 12 ); /* 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; /* 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] ); return URANGE( 10, resist, 99 ); } char *obj_short( const OBJ_DATA * obj ) { static char buf[MAX_STRING_LENGTH]; if( obj->count > 1 ) { sprintf( buf, "%s (%d)", obj->short_descr, obj->count ); return buf; } return obj->short_descr; } void get_obj( CHAR_DATA * ch, OBJ_DATA * obj, OBJ_DATA * container ) { int weight = 0; if( !CAN_WEAR( obj, ITEM_TAKE ) && !IS_IMMORTAL( ch ) ) { send_to_char( "You can't take that.\r\n", 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.\r\n", ch ); return; } if( ch->carry_number + 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 ); /* Money weight shouldn't count */ if( obj->item_type != ITEM_MONEY ) { if( obj->in_obj ) { OBJ_DATA *tobj = obj->in_obj; int inobj = 1; bool checkweight = FALSE; /* need to make it check weight if its in a magic container */ if( tobj->item_type == ITEM_CONTAINER && IS_OBJ_STAT( tobj, ITEM_MAGIC ) ) checkweight = TRUE; while( tobj->in_obj ) { tobj = tobj->in_obj; inobj++; /* need to make it check weight if its in a magic container */ if( tobj->item_type == ITEM_CONTAINER && IS_OBJ_STAT( tobj, ITEM_MAGIC ) ) checkweight = TRUE; } /* need to check weight if not carried by ch or in a magic container. */ if( !tobj->carried_by || tobj->carried_by != ch || checkweight ) { if( ( ch->carry_weight + weight ) > can_carry_w( ch ) ) { act( AT_PLAIN, "$d: you can't carry that much weight.", ch, NULL, obj->name, TO_CHAR ); return; } } } else if( ch->carry_weight + weight > can_carry_w( ch ) ) { act( AT_PLAIN, "$d: you can't carry that much weight.", ch, NULL, obj->name, TO_CHAR ); return; } } 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, container, TO_CHAR ); act( AT_ACTION, "$n gets $p.", ch, obj, container, TO_ROOM ); obj_from_room( obj ); } if( obj->item_type == ITEM_MONEY ) { ch->gold += obj->value[0] * obj->count; extract_obj( obj ); } else { obj = obj_to_char( obj, ch ); } if( char_died( ch ) || obj_extracted( obj ) ) return; oprog_get_trigger( ch, obj ); } void do_get( CHAR_DATA * ch, char *argument ) { char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; OBJ_DATA *obj = NULL; OBJ_DATA *obj_next = NULL; OBJ_DATA *container = NULL; short number = 0; bool found = FALSE; argument = one_argument( argument, arg1 ); if( is_number( arg1 ) ) { number = atoi( arg1 ); if( number < 1 ) { send_to_char( "That was easy...\r\n", ch ); return; } if( ( ch->carry_number + number ) > can_carry_n( ch ) ) { send_to_char( "You can't carry that many.\r\n", 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?\r\n", 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' */ 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 { short cnt = 0; bool fAll = FALSE; char *chk = NULL; 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 ) || ch->carry_number >= can_carry_n( ch ) || ch->carry_weight >= 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.\r\n", 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.\r\n", 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.\r\n", ch ); return; } if( ch->carry_weight + container->weight > can_carry_w( ch ) ) { send_to_char( "It's too heavy for you to lift.\r\n", ch ); return; } break; case ITEM_CONTAINER: case ITEM_DROID_CORPSE: case ITEM_CORPSE_PC: case ITEM_CORPSE_NPC: break; } 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 ); if( IS_SET( sysdata.save_flags, SV_GET ) ) save_char_obj( ch ); } else { int cnt = 0; bool fAll = FALSE; char *chk = NULL; /* '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!\r\n", 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 ) || ch->carry_number >= can_carry_n( ch ) || ch->carry_weight >= can_carry_w( ch ) || ( number && cnt >= number ) ) { if( container->item_type == ITEM_CORPSE_PC ) write_corpses( NULL, container->short_descr + 14 ); if( found && IS_SET( sysdata.save_flags, SV_GET ) ) save_char_obj( ch ); 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 ); } 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 = NULL; OBJ_DATA *obj = NULL; OBJ_DATA *obj_next = NULL; short count = 0; int number = 0; 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...\r\n", 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?\r\n", 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.\r\n", 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( ch->carry_weight + container->weight > can_carry_w( ch ) ) { send_to_char( "It's too heavy for you to lift.\r\n", ch ); return; } } else { if( container->item_type != ITEM_CONTAINER ) { send_to_char( "That's not a container.\r\n", 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.\r\n", ch ); return; } if( obj == container ) { send_to_char( "You can't fold it into itself.\r\n", ch ); return; } if( !can_drop_obj( ch, obj ) ) { send_to_char( "You can't let go of it.\r\n", ch ); return; } if( ( IS_OBJ_STAT( container, ITEM_COVERING ) && ( get_obj_weight( obj ) / obj->count ) > ( ( get_obj_weight( container ) / container->count ) - container->weight ) ) ) { send_to_char( "It won't fit under there.\r\n", 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.\r\n", ch ); return; } separate_obj( obj ); separate_obj( container ); obj_from_char( obj ); obj = obj_to_obj( obj, container ); 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 ); } else { bool found = FALSE; int cnt = 0; bool fAll = FALSE; char *chk = NULL; 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; 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 ); } return; } void do_drop( CHAR_DATA * ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; OBJ_DATA *obj = NULL; OBJ_DATA *obj_next = NULL; bool found = FALSE; int number = 0; argument = one_argument( argument, arg ); if( is_number( arg ) ) { number = atoi( arg ); if( number < 1 ) { send_to_char( "That was easy...\r\n", ch ); return; } argument = one_argument( argument, arg ); } else number = 0; if( arg[0] == '\0' ) { send_to_char( "Drop what?\r\n", ch ); return; } if( ms_find_obj( ch ) ) return; if( number > 0 ) { /* 'drop NNNN coins' */ if( !str_cmp( arg, "credits" ) || !str_cmp( arg, "credit" ) ) { if( ch->gold < number ) { send_to_char( "You haven't got that many credits.\r\n", ch ); return; } ch->gold -= number; for( obj = ch->in_room->first_content; obj; obj = obj_next ) { obj_next = obj->next_content; switch ( obj->pIndexData->vnum ) { case OBJ_VNUM_MONEY_ONE: number += 1; extract_obj( obj ); break; case OBJ_VNUM_MONEY_SOME: number += obj->value[0]; extract_obj( obj ); break; } } act( AT_ACTION, "$n drops some credits.", ch, NULL, NULL, TO_ROOM ); obj_to_room( create_money( number ), ch->in_room ); send_to_char( "OK.\r\n", 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.\r\n", ch ); return; } if( !can_drop_obj( ch, obj ) ) { send_to_char( "You can't let go of it.\r\n", ch ); return; } separate_obj( obj ); 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 ); obj = obj_to_room( obj, ch->in_room ); oprog_drop_trigger( ch, obj ); /* mudprogs */ if( char_died( ch ) || obj_extracted( obj ) ) return; } else { int cnt = 0; char *chk = NULL; bool fAll = FALSE; if( !str_cmp( arg, "all" ) ) fAll = TRUE; else fAll = FALSE; if( number > 1 ) chk = arg; else chk = &arg[4]; 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( obj->pIndexData->progtypes & 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 ); } act( AT_ACTION, "$n drops $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You drop $p.", ch, obj, NULL, TO_CHAR ); obj = obj_to_room( obj, ch->in_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 = NULL; OBJ_DATA *obj = NULL; argument = one_argument( argument, arg1 ); 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?\r\n", ch ); return; } if( ms_find_obj( ch ) ) return; if( is_number( arg1 ) ) { /* 'give NNNN coins victim' */ int amount = atoi( arg1 ); if( amount <= 0 || ( str_cmp( arg2, "credits" ) && str_cmp( arg2, "credit" ) ) ) { send_to_char( "Sorry, you can't do that.\r\n", ch ); return; } argument = one_argument( argument, arg2 ); if( !str_cmp( arg2, "to" ) && argument[0] != '\0' ) argument = one_argument( argument, arg2 ); if( arg2[0] == '\0' ) { send_to_char( "Give what to whom?\r\n", ch ); return; } if( ( victim = get_char_room( ch, arg2 ) ) == NULL ) { send_to_char( "They aren't here.\r\n", ch ); return; } if( ch->gold < amount ) { send_to_char ( "Very generous of you, but you haven't got that many credits.\r\n", ch ); return; } ch->gold -= amount; victim->gold += amount; strcpy( buf, "$n gives you " ); strcat( buf, arg1 ); strcat( buf, ( amount > 1 ) ? " credits." : " credit." ); act( AT_GOLD, buf, ch, NULL, victim, TO_VICT ); act( AT_GOLD, "$n gives $N some credits.", ch, NULL, victim, TO_NOTVICT ); act( AT_GOLD, "You give $N some credits.", ch, NULL, victim, TO_CHAR ); send_to_char( "OK.\r\n", ch ); mprog_bribe_trigger( victim, ch, amount ); 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( ( obj = get_obj_carry( ch, arg1 ) ) == NULL ) { send_to_char( "You do not have that item.\r\n", ch ); return; } if( obj->wear_loc != WEAR_NONE ) { send_to_char( "You must remove it first.\r\n", ch ); return; } if( ( victim = get_char_room( ch, arg2 ) ) == NULL ) { send_to_char( "They aren't here.\r\n", ch ); return; } if( !can_drop_obj( ch, obj ) ) { send_to_char( "You can't let go of it.\r\n", ch ); return; } if( victim->carry_number + ( get_obj_number( obj ) / obj->count ) > can_carry_n( victim ) ) { act( AT_PLAIN, "$N has $S hands full.", ch, NULL, victim, TO_CHAR ); return; } if( victim->carry_weight + ( get_obj_weight( obj ) / obj->count ) > can_carry_w( victim ) ) { act( AT_PLAIN, "$N can't carry that much weight.", ch, NULL, victim, TO_CHAR ); return; } if( !can_see_obj( victim, obj ) ) { act( AT_PLAIN, "$N can't see it.", ch, NULL, victim, TO_CHAR ); return; } if( IS_OBJ_STAT( obj, ITEM_PROTOTYPE ) && !can_take_proto( victim ) ) { act( AT_PLAIN, "You cannot give that to $N!", ch, NULL, victim, TO_CHAR ); return; } separate_obj( obj ); 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 ); if( job_trigger( victim, ch, obj ) == FALSE ) 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 ); return; } static obj_ret damage_obj_default( OBJ_DATA * obj ) { make_scraps( obj ); return rOBJ_SCRAPPED; } static obj_ret damage_obj_armor( OBJ_DATA * obj ) { obj_ret objcode = rNONE; CHAR_DATA *ch = obj->carried_by; if( ch && obj->value[0] >= 1 ) { ch->armor += apply_ac( obj, obj->wear_loc ); } if( --obj->value[0] <= 0 ) { make_scraps( obj ); objcode = rOBJ_SCRAPPED; } else if( ch && obj->value[0] >= 1 ) { ch->armor -= apply_ac( obj, obj->wear_loc ); } return objcode; } static obj_ret damage_obj_container( OBJ_DATA * obj ) { obj_ret objcode = rNONE; if( --obj->value[3] <= 0 ) { make_scraps( obj ); objcode = rOBJ_SCRAPPED; } return objcode; } static obj_ret damage_obj_weapon( OBJ_DATA * obj ) { obj_ret objcode = rNONE; if( --obj->value[0] <= 0 ) { make_scraps( obj ); objcode = rOBJ_SCRAPPED; } return objcode; } /* * 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->carried_by; obj_ret 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 global_objcode; switch ( obj->item_type ) { default: objcode = damage_obj_default( obj ); break; case ITEM_CONTAINER: objcode = damage_obj_container( obj ); break; case ITEM_ARMOR: objcode = damage_obj_armor( obj ); break; case ITEM_WEAPON: objcode = damage_obj_weapon( obj ); break; } return objcode; } /* * Remove an object. */ bool remove_obj( CHAR_DATA * ch, int iWear, bool fReplace ) { OBJ_DATA *obj, *tmpobj; if( ( obj = get_eq_char( ch, iWear ) ) == NULL ) return TRUE; if( !fReplace && ch->carry_number + 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( character_skill_level( ch, gsn_dual_wield ) > 0 ) return TRUE; return FALSE; } /* * See if char can dual wield at this time -Thoric */ bool can_dual( CHAR_DATA * ch ) { bool wield = FALSE, nwield = FALSE; if( !could_dual( ch ) ) return FALSE; if( get_eq_char( ch, WEAR_WIELD ) ) wield = TRUE; /* Check for missile wield or dual wield */ if( get_eq_char( ch, WEAR_MISSILE_WIELD ) || get_eq_char( ch, WEAR_DUAL_WIELD ) ) nwield = TRUE; if( wield && nwield ) { send_to_char ( "You are already wielding two weapons... grow some more arms!\n\r", ch ); return FALSE; } if( ( wield || nwield ) && get_eq_char( ch, WEAR_SHIELD ) ) { send_to_char ( "You cannot dual wield, you're already holding a shield!\n\r", ch ); return FALSE; } if( ( wield || nwield ) && get_eq_char( ch, WEAR_HOLD ) ) { send_to_char ( "You cannot hold another weapon, you're already holding something in that hand!\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, short wear_loc ) { OBJ_DATA *otmp = 0; short bitlayers = 0; short 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; } static bool wear_obj_verify_layering( CHAR_DATA * ch, OBJ_DATA * obj, short loc ) { if( !can_layer( ch, obj, WEAR_BODY ) ) { send_to_char ( "It won't fit overtop of what you're already wearing.\r\n", ch ); return FALSE; } return TRUE; } static void generic_wear_obj( CHAR_DATA * ch, OBJ_DATA * obj, short wear_loc, const char *msg_toroom, const char *msg_tochar ) { if( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) ) { if( !obj->action_desc || obj->action_desc[0] == '\0' ) { act( AT_ACTION, msg_toroom, ch, obj, NULL, TO_ROOM ); act( AT_ACTION, msg_tochar, ch, obj, NULL, TO_CHAR ); } else actiondesc( ch, obj, NULL ); } equip_char( ch, obj, wear_loc ); oprog_wear_trigger( ch, obj ); } static void wear_obj_light( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace ) { if( !remove_obj( ch, WEAR_LIGHT, fReplace ) ) return; generic_wear_obj( ch, obj, WEAR_LIGHT, "$n holds $p as a light.", "You hold $p as your light." ); } static void wear_obj_finger( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace ) { 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 ) ) { generic_wear_obj( ch, obj, WEAR_FINGER_L, "$n slips $s left finger into $p.", "You slip your left finger into $p." ); return; } if( !get_eq_char( ch, WEAR_FINGER_R ) ) { generic_wear_obj( ch, obj, WEAR_FINGER_R, "$n slips $s right finger into $p.", "You slip your right finger into $p." ); return; } bug( "Wear_obj: no free finger.", 0 ); send_to_char( "You already wear something on both fingers.\r\n", ch ); } static void wear_obj_neck( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace ) { 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( !get_eq_char( ch, WEAR_NECK_1 ) ) { generic_wear_obj( ch, obj, WEAR_NECK_1, "$n wears $p around $s neck.", "You wear $p around your neck." ); return; } if( !get_eq_char( ch, WEAR_NECK_2 ) ) { generic_wear_obj( ch, obj, WEAR_NECK_2, "$n wears $p around $s neck.", "You wear $p around your neck." ); return; } bug( "Wear_obj: no free neck.", 0 ); send_to_char( "You already wear two neck items.\r\n", ch ); } static void wear_obj_body( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace ) { if( !wear_obj_verify_layering( ch, obj, WEAR_BODY ) ) return; generic_wear_obj( ch, obj, WEAR_BODY, "$n fits $p on $s body.", "You fit $p on your body." ); } static void wear_obj_head( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace ) { if( !remove_obj( ch, WEAR_HEAD, fReplace ) ) return; generic_wear_obj( ch, obj, WEAR_HEAD, "$n dons $p upon $s head.", "You don $p upon your head." ); } static void wear_obj_eyes( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace ) { if( !remove_obj( ch, WEAR_EYES, fReplace ) ) return; generic_wear_obj( ch, obj, WEAR_EYES, "$n places $p on $s eyes.", "You place $p on your eyes." ); } static void wear_obj_ears( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace ) { if( !remove_obj( ch, WEAR_EARS, fReplace ) ) return; generic_wear_obj( ch, obj, WEAR_EARS, "$n wears $p on $s ears.", "You wear $p on your ears." ); } static void wear_obj_legs( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace ) { if( !wear_obj_verify_layering( ch, obj, WEAR_LEGS ) ) return; generic_wear_obj( ch, obj, WEAR_LEGS, "$n slips into $p.", "You slip into $p." ); } static void wear_obj_feet( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace ) { if( !wear_obj_verify_layering( ch, obj, WEAR_FEET ) ) return; generic_wear_obj( ch, obj, WEAR_FEET, "$n wears $p on $s feet.", "You wear $p on your feet." ); } static void wear_obj_hands( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace ) { if( !wear_obj_verify_layering( ch, obj, WEAR_HANDS ) ) return; generic_wear_obj( ch, obj, WEAR_HANDS, "$n wears $p on $s hands.", "You wear $p on your hands." ); } static void wear_obj_arms( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace ) { if( !wear_obj_verify_layering( ch, obj, WEAR_ARMS ) ) return; generic_wear_obj( ch, obj, WEAR_ARMS, "$n wears $p on $s arms.", "You wear $p on your arms." ); } static void wear_obj_about( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace ) { if( !wear_obj_verify_layering( ch, obj, WEAR_ABOUT ) ) return; generic_wear_obj( ch, obj, WEAR_ABOUT, "$n wears $p about $s body.", "You wear $p about your body." ); } static void wear_obj_waist( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace ) { if( !wear_obj_verify_layering( ch, obj, WEAR_WAIST ) ) return; generic_wear_obj( ch, obj, WEAR_WAIST, "$n wears $p about $s waist.", "You wear $p about your waist." ); } static void wear_obj_wrist( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace ) { 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 ) ) { generic_wear_obj( ch, obj, WEAR_WRIST_L, "$n fits $p around $s left wrist.", "You fit $p around your left wrist." ); return; } if( !get_eq_char( ch, WEAR_WRIST_R ) ) { generic_wear_obj( ch, obj, WEAR_WRIST_R, "$n fits $p around $s right wrist.", "You fit $p around your right wrist." ); return; } bug( "Wear_obj: no free wrist.", 0 ); send_to_char( "You already wear two wrist items.\r\n", ch ); } static void wear_obj_shield( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace ) { if( !remove_obj( ch, WEAR_SHIELD, fReplace ) ) return; generic_wear_obj( ch, obj, WEAR_SHIELD, "$n uses $p as an energy shield.", "You use $p as an energy shield." ); } static void wear_obj_wield( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace ) { OBJ_DATA *tmpobj = NULL; if( !could_dual( ch ) ) { if( !remove_obj( ch, WEAR_MISSILE_WIELD, fReplace ) ) return; if( !remove_obj( ch, WEAR_WIELD, fReplace ) ) return; tmpobj = NULL; } else { OBJ_DATA *mw, *dw, *hd; tmpobj = get_eq_char( ch, WEAR_WIELD ); mw = get_eq_char( ch, WEAR_MISSILE_WIELD ); dw = get_eq_char( ch, WEAR_DUAL_WIELD ); hd = get_eq_char( ch, WEAR_HOLD ); if( tmpobj ) { if( !can_dual( ch ) ) return; 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( mw || dw ) { send_to_char( "You're already wielding two weapons.\n\r", ch ); return; } if( hd ) { send_to_char ( "You're already wielding a weapon AND holding something.\n\r", ch ); return; } if( !oprog_use_trigger( ch, obj, NULL, NULL, 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 ); } equip_char( ch, obj, WEAR_DUAL_WIELD ); oprog_wear_trigger( ch, obj ); return; } if( mw ) { if( !can_dual( ch ) ) return; if( get_obj_weight( obj ) + get_obj_weight( mw ) > str_app[get_curr_str( ch )].wield ) { send_to_char( "It is too heavy for you to wield.\n\r", ch ); return; } if( tmpobj || dw ) { send_to_char( "You're already wielding two weapons.\n\r", ch ); return; } if( hd ) { send_to_char ( "You're already wielding a weapon AND holding something.\n\r", ch ); return; } if( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) ) { act( AT_ACTION, "$n wields $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You wield $p.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_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 ) ) { act( AT_ACTION, "$n wields $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You wield $p.", ch, obj, NULL, TO_CHAR ); } equip_char( ch, obj, WEAR_WIELD ); oprog_wear_trigger( ch, obj ); } static void wear_obj_hold( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace ) { 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_DEVICE || obj->item_type == ITEM_FOOD || obj->item_type == ITEM_DRINK_CON || !oprog_use_trigger( ch, obj, NULL, NULL, 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 ); } /* * Wear one object. * Optional replacement of existing objects. * Big repetitive code, ick. * Restructured a bit to allow for specifying body location -Thoric * * Refactored by decomposing into smaller functions, and removed lots of * duplicate code. -Kai */ void wear_obj( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace, short wear_bit ) { char buf[MAX_STRING_LENGTH]; short bit, tmp; separate_obj( obj ); 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.\r\n", ch ); break; case ITEM_WIELD: send_to_char( "You cannot wield that.\r\n", ch ); break; default: sprintf( buf, "You cannot wear that on your %s.\r\n", 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 ) { wear_obj_light( ch, obj, fReplace ); return; } if( bit == -1 ) { if( fReplace ) send_to_char( "You can't wear, wield, or hold that.\r\n", ch ); return; } wear_obj_dispatch_fun( ch, obj, fReplace, 1 << bit ); } void wear_obj_dispatch_fun( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace, int wear_loc ) { switch ( wear_loc ) { default: bug( "wear_obj: uknown/unused item_wear bit %d", wear_loc ); if( fReplace ) send_to_char( "You can't wear, wield, or hold that.\r\n", ch ); break; case ITEM_WEAR_FINGER: wear_obj_finger( ch, obj, fReplace ); break; case ITEM_WEAR_NECK: wear_obj_neck( ch, obj, fReplace ); break; case ITEM_WEAR_BODY: wear_obj_body( ch, obj, fReplace ); break; case ITEM_WEAR_HEAD: wear_obj_head( ch, obj, fReplace ); break; case ITEM_WEAR_EYES: wear_obj_eyes( ch, obj, fReplace ); break; case ITEM_WEAR_EARS: wear_obj_ears( ch, obj, fReplace ); break; case ITEM_WEAR_LEGS: wear_obj_legs( ch, obj, fReplace ); break; case ITEM_WEAR_FEET: wear_obj_feet( ch, obj, fReplace ); break; case ITEM_WEAR_HANDS: wear_obj_hands( ch, obj, fReplace ); break; case ITEM_WEAR_ARMS: wear_obj_arms( ch, obj, fReplace ); break; case ITEM_WEAR_ABOUT: wear_obj_about( ch, obj, fReplace ); break; case ITEM_WEAR_WAIST: wear_obj_waist( ch, obj, fReplace ); break; case ITEM_WEAR_WRIST: wear_obj_wrist( ch, obj, fReplace ); break; case ITEM_WEAR_SHIELD: wear_obj_shield( ch, obj, fReplace ); break; case ITEM_WIELD: wear_obj_wield( ch, obj, fReplace ); break; case ITEM_HOLD: wear_obj_hold( ch, obj, fReplace ); break; } } void do_wear( CHAR_DATA * ch, char *argument ) { char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; OBJ_DATA *obj = NULL; short wear_bit = 0; 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?\r\n", 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 ); } return; } else { if( ( obj = get_obj_carry( ch, arg1 ) ) == NULL ) { send_to_char( "You do not have that item.\r\n", 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 = NULL, *obj_next = NULL; one_argument( argument, arg ); if( arg[0] == '\0' ) { send_to_char( "Remove what?\r\n", 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.\r\n", 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 = NULL; bool shovel = FALSE; short move = 0; one_argument( argument, arg ); if( arg[0] == '\0' ) { send_to_char( "What do you wish to bury?\r\n", ch ); return; } if( ms_find_obj( ch ) ) return; shovel = get_obj_type_char( ch, ITEM_SHOVEL ) ? TRUE : FALSE; obj = get_obj_list_rev( ch, arg, ch->in_room->last_content ); if( !obj ) { send_to_char( "You can't find it.\r\n", ch ); return; } separate_obj( obj ); if( !CAN_WEAR( obj, ITEM_TAKE ) ) { 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.\r\n", ch ); return; case SECT_WATER_SWIM: case SECT_WATER_NOSWIM: case SECT_UNDERWATER: send_to_char( "You cannot bury something here.\r\n", ch ); return; case SECT_AIR: send_to_char( "What? In the air?!\r\n", 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.\r\n", ch ); return; } move = ( obj->weight * 50 * ( shovel ? 1 : 5 ) ) / UMAX( 1, can_carry_w( ch ) ); move = URANGE( 2, move, 1000 ); if( move > ch->move ) { send_to_char ( "You don't have the energy to bury something of that size.\r\n", ch ); return; } ch->move -= move; 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; } /* 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 = NULL; 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( !IS_SET( ch->in_room->room_flags, ROOM_AUCTION ) ) { set_char_color( AT_LBLUE, ch ); send_to_char( "\r\nYou must go to an auction hall to do that!\r\n", ch ); return; } if( ( time_info.hour > 18 || time_info.hour < 9 ) && auction->item == NULL ) { set_char_color( AT_LBLUE, ch ); send_to_char( "\r\nThe auctioneer has retired for the evening...\r\n", ch ); return; } if( arg1[0] == '\0' ) { if( auction->item != NULL ) { AFFECT_DATA *paf = NULL; obj = auction->item; /* show item data here */ if( auction->bet > 0 ) sprintf( buf, "Current bid on this item is %d credits.\r\n", auction->bet ); else sprintf( buf, "No bids on this item have been received.\r\n" ); 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.\r\nIts weight is %d, value is %d.\r\n", obj->name, aoran( item_type_name( obj ) ), extra_bit_name( obj->extra_flags ), magic_bit_name( obj->magic_flags ), obj->weight, obj->cost ); set_char_color( AT_LBLUE, ch ); send_to_char( buf, ch ); sprintf( buf, "Worn on: %s\r\n", 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_ARMOR: ch_printf( ch, "Current armor class is %d. ( based on current condition )\r\n", obj->value[0] ); ch_printf( ch, "Maximum armor class is %d. ( based on top condition )\r\n", obj->value[1] ); 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:\r\n", ch ); show_list_to_char( obj->first_content, ch, TRUE, FALSE ); } if( IS_IMMORTAL( ch ) ) { sprintf( buf, "Seller: %s. Bidder: %s. Round: %d.\r\n", auction->seller->name, auction->buyer->name, ( auction->going + 1 ) ); send_to_char( buf, ch ); sprintf( buf, "Time left in round: %d.\r\n", auction->pulse ); send_to_char( buf, ch ); } return; } else { set_char_color( AT_LBLUE, ch ); send_to_char ( "\r\nThere is nothing being auctioned right now. What would you like to auction?\r\n", ch ); return; } } if( IS_IMMORTAL( ch ) && !str_cmp( arg1, "stop" ) ) { if( auction->item == NULL ) { send_to_char( "There is no auction to stop.\r\n", 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 */ { auction->buyer->gold += auction->bet; send_to_char( "Your money has been returned.\r\n", auction->buyer ); } return; } } if( !str_cmp( arg1, "bid" ) ) { if( auction->item != NULL ) { int newbet = 0; if( ch == auction->seller ) { send_to_char( "You can't bid on your own item!\r\n", ch ); return; } /* make - perhaps - a bet now */ if( argument[0] == '\0' ) { send_to_char( "Bid how much?\r\n", ch ); return; } newbet = parsebet( auction->bet, argument ); /* ch_printf( ch, "Bid: %d\r\n",newbet); */ if( newbet < auction->starting ) { send_to_char ( "You must place a bid that is higher than the starting bet.\r\n", 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 + 10000 ) ) { send_to_char ( "You must at least bid 10000 credits over the current bid.\r\n", ch ); return; } if( newbet > ch->gold ) { send_to_char( "You don't have that much money!\r\n", ch ); return; } if( newbet > 2000000000 ) { send_to_char( "You can't bid over 2 billion credits.\r\n", ch ); return; } /* the actual bet is OK! */ /* return the gold to the last buyer, if one exists */ if( auction->buyer != NULL && auction->buyer != auction->seller ) auction->buyer->gold += auction->bet; ch->gold -= newbet; /* substract the gold - 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 credits has been received on %s.\r\n", newbet, auction->item->short_descr ); talk_auction( buf ); return; } else { send_to_char( "There isn't anything being auctioned right now.\r\n", 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.\r\n", ch ); return; } if( obj->timer > 0 ) { send_to_char( "You can't auction objects that are decaying.\r\n", 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.\r\n", ch ); return; } if( atoi( arg2 ) < 0 ) { send_to_char ( "You can't auction something for less than 0 credits!\r\n", ch ); return; } 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_RARE_METAL: case ITEM_CRYSTAL: case ITEM_FABRIC: case ITEM_ARMOR: 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; 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 credits.", obj->short_descr, auction->starting ); 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, ( short ) ( 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 = NULL; ROOM_INDEX_DATA *to_room = NULL; 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", 0 ); extract_obj( obj ); fall_count = 0; return; } if( IS_SET( obj->in_room->room_flags, ROOM_NOFLOOR ) && CAN_GO( obj, DIR_DOWN ) && !IS_OBJ_STAT( obj, ITEM_MAGIC ) ) { pexit = get_exit( obj->in_room, DIR_DOWN ); 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 %ld", 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 = NULL; 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_WHITE, "$p falls on $n!", vch, obj, NULL, TO_ROOM ); act( AT_WHITE, "$p falls on you!", vch, obj, NULL, TO_CHAR ); damage( vch, vch, dam * vch->top_level, 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 ); } 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 ); } break; } } obj_fall( obj, TRUE ); } return; } bool job_trigger( CHAR_DATA * victim, CHAR_DATA * ch, OBJ_DATA * obj ) { char buf[MAX_STRING_LENGTH]; if( !IS_NPC( victim ) || !victim->pIndexData ) return FALSE; if( victim->pIndexData->vnum != MOB_VNUM_JOB_OFFICER ) return FALSE; if( IS_NPC( ch ) || !ch->pcdata ) return FALSE; if( !obj->pIndexData || obj->pIndexData->vnum != OBJ_VNUM_PACKAGE ) return FALSE; if( !victim->in_room || !victim->in_room->area || !victim->in_room->area->planet ) return FALSE; sprintf( buf, "package %s", victim->in_room->area->planet->name ); if( str_cmp( buf, obj->name ) ) return FALSE; snprintf( buf, MAX_STRING_LENGTH, "%s", "Thank you." ); do_say( victim, buf ); ch->gold += 1000; act( AT_GOLD, "$N gives you 1000 credits.", ch, NULL, victim, TO_CHAR ); act( AT_GOLD, "$N gives $n some credits.", ch, NULL, victim, TO_NOTVICT ); act( AT_GOLD, "You give $n some credits.", ch, NULL, victim, TO_VICT ); separate_obj( obj ); obj_from_char( obj ); extract_obj( obj ); return TRUE; }