/****************************************************************************
* _______ _ ______ _______ _______ ______ *
* ( ____ \( \ ( __ \ |\ /|( ___ )( )|\ /|( __ \ *
* | ( \/| ( | ( \ )| ) ( || ( ) || () () || ) ( || ( \ ) *
* | (__ | | | | ) || (___) || (___) || || || || | | || | ) | *
* | __) | | | | | || ___ || ___ || |(_)| || | | || | | | *
* | ( | | | | ) || ( ) || ( ) || | | || | | || | ) | *
* | (____/\| (____/\| (__/ )| ) ( || ) ( || ) ( || (___) || (__/ ) *
* (_______/(_______/(______/ |/ \||/ \||/ \|(_______)(______/ *
* +-+-+-+ +-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+ *
* |T|h|e| |O|a|k|l|a|n|d| |C|h|r|o|n|i|c|l|e|s| *
* +-+-+-+ +-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+ *
* ------------------------------------------------------------------------- *
* EldhaMUD code (C) 2003-2005 by Robert Powell (Tommi) *
* EldhaMUD Team: Celest, Altere and Krelowyn *
* ------------------------------------------------------------------------- *
* *
****************************************************************************/
/****************************************************************************
* [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | \\._.// *
* -----------------------------------------------------------| (0...0) *
* SMAUG 1.4 (C) 1994, 1995, 1996, 1998 by Derek Snider | ).:.( *
* -----------------------------------------------------------| {o o} *
* SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, | / ' ' \ *
* Scryn, Rennard, Swordbearer, Gorog, Grishnakh, Nivek, |~'~.VxvxV.~'~*
* Tricops and Fireblade | *
* ------------------------------------------------------------------------ *
* 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 *
****************************************************************************/
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "./Headers/mud.h"
#include "./Headers/bet.h"
/*double sqrt( double x );*/
/*
* External functions
*/
void write_corpses args( ( CHAR_DATA * ch, char *name, OBJ_DATA * objrem ) );
void do_token_redeem( CHAR_DATA * ch, OBJ_DATA * obj );
/*
* Local functions.
*/
void get_obj args( ( CHAR_DATA * ch, OBJ_DATA * obj, OBJ_DATA * container ) );
bool remove_obj args( ( CHAR_DATA * ch, int iWear, bool fReplace ) );
void wear_obj args( ( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace, short wear_bit ) );
char *get_chance_verb args( ( OBJ_DATA * obj ) );
char *get_ed_number args( ( OBJ_DATA * obj, int number ) );
OBJ_DATA *recursive_note_find args( ( OBJ_DATA * obj, char *argument ) );
/*
* how resistant an object is to damage -Thoric
*/
short get_obj_resistance( OBJ_DATA * obj )
{
short 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 += ( obj->level / 5 );
/*
* 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 );
return URANGE( 10, resist, 99 );
}
void get_obj( CHAR_DATA * ch, OBJ_DATA * obj, OBJ_DATA * container )
{
CLAN_DATA *clan;
int weight;
int amt; /* gold per-race multipliers */
if( !CAN_WEAR( obj, ITEM_TAKE ) && ( ch->level < sysdata.level_getobjnotake ) )
{
send_to_char( "You can't take that.\n\r", ch );
return;
}
if( IS_SET( obj->magic_flags, ITEM_PKDISARMED ) && !IS_NPC( ch ) )
{
if( CAN_PKILL( ch ) && !get_timer( ch, TIMER_PKILLED ) )
{
if( ch->level - obj->value[5] > 5 || obj->value[5] - ch->level > 5 )
{
send_to_char_color( "\n\r&bA godly force freezes your outstretched hand.\n\r", ch );
return;
}
else
{
REMOVE_BIT( obj->magic_flags, ITEM_PKDISARMED );
obj->value[5] = 0;
}
}
else
{
send_to_char_color( "\n\r&BA godly force freezes your outstretched hand.\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( 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 );
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 )
{
if( container->item_type == ITEM_KEYRING && !IS_OBJ_STAT( container, ITEM_COVERING ) )
{
act( AT_ACTION, "You remove $p from $P", ch, obj, container, TO_CHAR );
act( AT_ACTION, "$n removes $p from $P", ch, obj, container, TO_ROOM );
}
else
{
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 );
}
if( IS_OBJ_STAT( container, ITEM_CLANCORPSE ) && !IS_NPC( ch ) && str_cmp( container->name + 7, ch->name ) )
container->value[5]++;
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 );
}
/*
* Clan storeroom checks
*/
if( xIS_SET( ch->in_room->room_flags, ROOM_CLANSTOREROOM ) && ( !container || container->carried_by == NULL ) )
{
/*
* if (!char_died) save_char_obj(ch);
*/
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 )
{
amt = obj->value[0];
/*
* The idea was to make some races more adroit at money handling,
* however, this resulted in elves dropping 1M gps and picking
* up 1.1M, repeating, and getting rich. The only solution would
* be to fuzzify the "drop coins" code, but that seems like it'd
* lead to more confusion than it warrants. -h
*
* When you work on this again, make it so that amt is NEVER multiplied
* by more than 1.0. Use less than 1.0 for ogre, orc, troll, etc.
* (Ie: a penalty rather than a bonus)
*/
#ifdef GOLD_MULT
switch ( ch->race )
{
case ( 1 ):
amt *= 1.1;
break; /* elf */
case ( 2 ):
amt *= 0.97;
break; /* dwarf */
case ( 3 ):
amt *= 1.02;
break; /* halfling */
case ( 4 ):
amt *= 1.08;
break; /* pixie */
case ( 6 ):
amt *= 0.92;
break; /* half-ogre */
case ( 7 ):
amt *= 0.94;
break; /* half-orc */
case ( 8 ):
amt *= 0.90;
break; /* half-troll */
case ( 9 ):
amt *= 1.04;
break; /* half-elf */
case ( 10 ):
amt *= 1.06;
break; /* gith */
}
#endif
ch->gold += amt;
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;
short 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( ( ch->carry_number + 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'
*/
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;
save_house_by_vnum( ch->in_room->vnum ); /* House Object Saving */
if( IS_SET( sysdata.save_flags, SV_GET ) )
save_char_obj( ch );
}
else
{
short cnt = 0;
bool fAll;
char *chk;
if( xIS_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->last_content; obj; obj = obj_next )
{
obj_next = obj->prev_content;
if( ( fAll || nifty_is_name( chk, obj->name ) ) && can_see_obj( ch, obj ) )
{
if( IS_OBJ_STAT( obj, ITEM_ONMAP ) )
{
if( ch->map != obj->map || ch->x != obj->x || ch->y != obj->y )
{
found = FALSE;
continue;
}
}
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.\n\r", ch );
else
act( AT_PLAIN, "I see no $T here.", ch, NULL, chk, TO_CHAR );
}
else
{
save_house_by_vnum( ch->in_room->vnum ); /* House Object Saving */
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( ch->carry_weight + 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:
case ITEM_KEYRING:
case ITEM_QUIVER:
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;
}
/*
* Killer/owner loot only if die to pkill blow --Blod
*/
/*
* Added check for immortal so IMMS can get things out of
* * corpses --Shaddai
*/
if( IS_OBJ_STAT( container, ITEM_CLANCORPSE )
&& !IS_NPC( ch ) && !IS_IMMORTAL( ch )
&& container->action_desc[0] != '\0'
&& str_cmp( name, ch->name ) && str_cmp( container->action_desc, ch->name ) )
{
send_to_char( "You did not inflict the death blow upon this corpse.\n\r", ch );
return;
}
if( IS_OBJ_STAT( container, ITEM_CLANCORPSE )
&& !IS_NPC( ch ) && str_cmp( name, ch->name ) && container->value[5] >= 3 )
{
send_to_char( "Frequent looting has left this corpse protected by the gods.\n\r", ch );
return;
}
if( IS_OBJ_STAT( container, ITEM_CLANCORPSE )
&& !IS_NPC( ch ) && IS_SET( ch->pcdata->flags, PCFLAG_DEADLY )
&& container->value[4] - ch->level < 6 && container->value[4] - ch->level > -6 )
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 );
/*
* Oops no wonder corpses were duping oopsie did I do that
* * --Shaddai
*/
if( container->item_type == ITEM_CORPSE_PC )
write_corpses( NULL, container->short_descr + 14, NULL );
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( IS_OBJ_STAT( container, ITEM_CLANCORPSE )
&& !IS_IMMORTAL( ch ) && !IS_NPC( ch ) && str_cmp( ch->name, container->name + 7 ) )
{
send_to_char( "The gods frown upon such wanton 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 )
|| 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, NULL );
if( found && IS_SET( sysdata.save_flags, SV_GET ) )
save_char_obj( ch );
return;
}
}
}
if( !found )
{
if( fAll )
{
if( container->item_type == ITEM_KEYRING && !IS_OBJ_STAT( container, ITEM_COVERING ) )
act( AT_PLAIN, "The $T holds no keys.", ch, NULL, arg2, TO_CHAR );
else
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
{
if( container->item_type == ITEM_KEYRING && !IS_OBJ_STAT( container, ITEM_COVERING ) )
act( AT_PLAIN, "The $T does not hold that key.", 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;
/*
* Oops no wonder corpses were duping oopsie did I do that
* * --Shaddai
*/
if( container->item_type == ITEM_CORPSE_PC )
write_corpses( NULL, container->short_descr + 14, NULL );
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;
short 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" ) || !str_cmp( arg2, "under" )
|| !str_cmp( arg2, "onto" ) || !str_cmp( arg2, "on" ) ) && 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( ch->carry_weight + 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
&& container->item_type != ITEM_KEYRING && container->item_type != ITEM_QUIVER )
{
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( container->item_type == ITEM_KEYRING && obj->item_type != ITEM_KEY )
{
send_to_char( "That's not a key.\n\r", ch );
return;
}
if( container->item_type == ITEM_QUIVER && obj->item_type != ITEM_PROJECTILE )
{
send_to_char( "That's not a projectile.\n\r", 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.\n\r", ch );
return;
}
/*
* note use of get_real_obj_weight
*/
if( ( get_real_obj_weight( obj ) / obj->count )
+ ( get_real_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;
if( container->item_type == ITEM_KEYRING && !IS_OBJ_STAT( container, ITEM_COVERING ) )
{
act( AT_ACTION, "$n slips $p onto $P.", ch, obj, container, TO_ROOM );
act( AT_ACTION, "You slip $p onto $P.", ch, obj, container, TO_CHAR );
}
else
{
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;
/*
* Oops no wonder corpses were duping oopsie did I do that
* * --Shaddai
*/
if( container->item_type == ITEM_CORPSE_PC )
write_corpses( NULL, container->short_descr + 14, NULL );
if( save_char )
save_char_obj( ch );
/*
* Clan storeroom check
*/
if( xIS_SET( ch->in_room->room_flags, ROOM_CLANSTOREROOM ) && container->carried_by == NULL )
{
/*
* if (!char_died && !save_char ) save_char_obj(ch);
*/
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 )
&& ( container->item_type != ITEM_KEYRING || obj->item_type == ITEM_KEY )
&& ( container->item_type != ITEM_QUIVER || obj->item_type == ITEM_PROJECTILE )
&& 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 );
if( container->item_type == ITEM_KEYRING )
{
act( AT_ACTION, "$n slips $p onto $P.", ch, obj, container, TO_ROOM );
act( AT_ACTION, "You slip $p onto $P.", ch, obj, container, TO_CHAR );
}
else
{
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 );
/*
* Oops no wonder corpses were duping oopsie did I do that
* * --Shaddai
*/
if( container->item_type == ITEM_CORPSE_PC )
write_corpses( NULL, container->short_descr + 14, NULL );
/*
* Clan storeroom check
*/
if( xIS_SET( ch->in_room->room_flags, ROOM_CLANSTOREROOM ) && container->carried_by == NULL )
{
/*
* if (!char_died && !save_char) save_char_obj(ch);
*/
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];
OBJ_DATA *obj;
OBJ_DATA *obj_next;
bool found;
CLAN_DATA *clan;
int number;
argument = one_argument( argument, arg );
if( is_number( arg ) )
{
number = atoi( arg );
if( number < 1 )
{
send_to_char( "That was easy...\n\r", ch );
return;
}
argument = one_argument( argument, arg );
}
else
number = 0;
if( arg[0] == '\0' )
{
send_to_char( "Drop what?\n\r", ch );
return;
}
if( ms_find_obj( ch ) )
return;
if( !IS_NPC( ch ) && xIS_SET( ch->act, PLR_LITTERBUG ) )
{
set_char_color( AT_YELLOW, ch );
send_to_char( "A godly force prevents you from dropping anything...\n\r", ch );
return;
}
if( xIS_SET( ch->in_room->room_flags, ROOM_NODROP ) && ch != supermob )
{
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 )
{
/*
* 'drop NNNN coins'
*/
if( !str_cmp( arg, "coins" ) || !str_cmp( arg, "coin" ) )
{
if( ch->gold < number )
{
send_to_char( "You haven't got that many coins.\n\r", 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 gold.", ch, NULL, NULL, TO_ROOM );
obj_to_room( create_money( number ), ch->in_room, ch );
save_house_by_vnum( ch->in_room->vnum ); /* House Object Saving */
send_to_char( "You let the gold slip from your hand.\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 );
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, ch );
oprog_drop_trigger( ch, obj ); /* mudprogs */
if( char_died( ch ) || obj_extracted( obj ) )
return;
/*
* Clan storeroom saving
*/
if( xIS_SET( ch->in_room->room_flags, ROOM_CLANSTOREROOM ) )
{
/*
* if (!char_died) save_char_obj(ch);
*/
for( clan = first_clan; clan; clan = clan->next )
if( clan->storeroom == ch->in_room->vnum )
save_clan_storeroom( ch, clan );
}
}
else
{
int cnt = 0;
char *chk;
bool fAll;
if( !str_cmp( arg, "all" ) )
fAll = TRUE;
else
fAll = FALSE;
if( number > 1 )
chk = arg;
else
chk = &arg[4];
/*
* 'drop all' or 'drop all.obj'
*/
if( xIS_SET( ch->in_room->room_flags, ROOM_NODROPALL ) || xIS_SET( ch->in_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 );
}
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, ch );
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 );
save_house_by_vnum( ch->in_room->vnum ); /* House Object Saving */
}
}
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, *questman;
OBJ_DATA *obj;
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?\n\r", ch );
return;
}
if( ms_find_obj( ch ) )
return;
if( is_number( arg1 ) )
{
/*
* 'give NNNN coins victim'
*/
int amount;
amount = atoi( arg1 );
if( amount <= 0 || ( str_cmp( arg2, "coins" ) && str_cmp( arg2, "coin" ) ) )
{
send_to_char( "Sorry, you can't do that.\n\r", 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?\n\r", ch );
return;
}
if( ( victim = get_char_room( ch, arg2 ) ) == NULL )
{
send_to_char( "They aren't here.\n\r", ch );
return;
}
if( ch->gold < amount )
{
send_to_char( "Very generous of you, but you haven't got that much gold.\n\r", ch );
return;
}
ch->gold -= amount;
victim->gold += amount;
strcpy( buf, "$n gives you " );
strcat( buf, arg1 );
strcat( buf, ( amount > 1 ) ? " coins." : " coin." );
act( AT_ACTION, buf, ch, NULL, victim, TO_VICT );
act( AT_ACTION, "$n gives $N some gold.", ch, NULL, victim, TO_NOTVICT );
act( AT_ACTION, "You give $N some gold.", ch, NULL, victim, TO_CHAR );
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.\n\r", ch );
return;
}
if( obj->wear_loc != WEAR_NONE )
{
send_to_char( "You must remove it first.\n\r", ch );
return;
}
if( ( victim = get_char_room( ch, arg2 ) ) == NULL )
{
send_to_char( "They aren't here.\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( obj->item_type == ITEM_QUESTTOKEN )
{
if( !str_prefix( "all.", arg1 ) )
{
send_to_char( "You cannot give all.token, this is to stop a crash, will fix it soon as possible\n\r", ch );
return;
}
for( questman = ch->in_room->first_person; questman != NULL; questman = questman->next_in_room )
if( IS_NPC( questman ) && xIS_SET( questman->act, ACT_QUESTMASTER ) )
break;
if( questman )
{
if( ( victim = get_char_room( ch, arg2 ) ) == questman )
{
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 );
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 );
do_token_redeem( ch, obj );
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 );
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;
}
/*
* 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;
int random_number;
ch = obj->carried_by;
objcode = rNONE;
separate_obj( obj );
if( !IS_NPC( ch ) && ( !IS_PKILL( ch ) || ( IS_PKILL( ch ) && !IS_SET( ch->pcdata->flags, PCFLAG_GAG ) ) ) )
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;
}
if( obj->item_type != ITEM_LIGHT )
oprog_damage_trigger( ch, obj );
else if( !in_arena( ch ) )
oprog_damage_trigger( ch, obj );
if( obj_extracted( obj ) )
return global_objcode;
switch ( obj->item_type )
{
default:
make_scraps( obj );
objcode = rOBJ_SCRAPPED;
break;
case ITEM_CONTAINER:
if( --obj->value[3] <= 0 )
{
if( !in_arena( ch ) )
{
make_scraps( obj );
objcode = rOBJ_SCRAPPED;
}
else
obj->value[3] = 1;
}
case ITEM_SHOVEL:
case ITEM_KEYRING:
case ITEM_QUIVER:
if( --obj->value[3] <= 0 )
{
if( !in_arena( ch ) )
{
make_scraps( obj );
objcode = rOBJ_SCRAPPED;
}
else
obj->value[3] = 1;
}
break;
case ITEM_LIGHT:
if( --obj->value[0] <= 0 )
{
if( !in_arena( ch ) )
{
make_scraps( obj );
objcode = rOBJ_SCRAPPED;
}
else
obj->value[0] = 1;
}
break;
case ITEM_ARMOR:
random_number = number_range( 0, 4 );
if( random_number == 1 )
{
if( --obj->value[3] <= 0 )
{
make_scraps( obj );
objcode = rOBJ_SCRAPPED;
}
}
break;
case ITEM_WEAPON:
random_number = number_range( 0, 4 );
if( random_number == 1 )
{
if( --obj->value[0] <= 0 )
{
make_scraps( obj );
objcode = rOBJ_SCRAPPED;
}
break;
}
}
if( ch != NULL )
save_char_obj( ch ); /* Stop scrap duping - Samson 1-2-00 */
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 ) || ch->pcdata->learned[gsn_dual_wield] )
return TRUE;
return FALSE;
}
/*
* Check for the ability to dual-wield under all conditions. -Orion
*
* Original version by Thoric.
*/
bool can_dual( CHAR_DATA * ch )
{
/*
* We must assume that when they come in, they are NOT wielding something. We
* take care of the actual value later. -Orion
*/
bool wielding[2], alreadyWielding = FALSE;
wielding[0] = FALSE;
wielding[1] = FALSE;
/*
* If they don't have the ability to dual-wield, why should we allow them to
* do so? -Orion
*/
if( !could_dual( ch ) )
return FALSE;
/*
* Get that true wielding value I mentioned earlier. If they're wielding and
* missile wielding, we can simply return FALSE. If not, set the values. -Orion
*/
if( get_eq_char( ch, WEAR_WIELD ) && get_eq_char( ch, WEAR_MISSILE_WIELD ) )
{
send_to_char( "You are already wielding two weapons... grow some more arms!\n\r", ch );
return FALSE;
}
else
{
/*
* Wield position. -Orion
*/
wielding[0] = get_eq_char( ch, WEAR_WIELD ) ? TRUE : FALSE;
/*
* Missile wield position. -Orion
*/
wielding[1] = get_eq_char( ch, WEAR_MISSILE_WIELD ) ? TRUE : FALSE;
}
/*
* Save some extra typing farther down. -Orion
*/
if( wielding[0] || wielding[1] )
alreadyWielding = TRUE;
/*
* If wielding and dual wielding, then they can't wear another weapon. Return
* FALSE. We can assume that dual wield will not be full if there is no wield
* slot already filled. -Orion
*/
if( wielding[0] && get_eq_char( ch, WEAR_DUAL_WIELD ) )
{
send_to_char( "You are already wielding two weapons... grow some more arms!\n\r", ch );
return FALSE;
}
/*
* If wielding or missile wielding and holding a shield, then we can return
* FALSE. -Orion
*/
if( alreadyWielding && 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 wielding or missile wielding and holding something, then we can return
* FALSE. -Orion
*/
if( alreadyWielding && 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;
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;
}
/*
* Wear one object.
* Optional replacement of existing objects.
* Big repetitive code, ick.
*
* Restructured a bit to allow for specifying body location -Thoric
* & Added support for layering on certain body locations
*/
void wear_obj( CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace, short wear_bit )
{
char buf[MAX_STRING_LENGTH];
OBJ_DATA *tmpobj = NULL;
short bit, tmp;
separate_obj( obj );
if( get_trust( ch ) < obj->level )
{
sprintf( buf, "You must be level %d to use this object.\n\r", obj->level );
send_to_char( buf, ch );
act( AT_ACTION, "$n tries to use $p, but is too inexperienced.", 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_WIELD:
case ITEM_MISSILE_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_LODGE_RIB:
act( AT_ACTION, "$p strikes you and deeply imbeds itself in your ribs!", ch, obj, NULL, TO_CHAR );
act( AT_ACTION, "$p strikes $n and deeply imbeds itself in $s ribs!", ch, obj, NULL, TO_ROOM );
equip_char( ch, obj, WEAR_LODGE_RIB );
break;
case ITEM_LODGE_ARM:
act( AT_ACTION, "$p strikes you and deeply imbeds itself in your arm!", ch, obj, NULL, TO_CHAR );
act( AT_ACTION, "$p strikes $n and deeply imbeds itself in $s arm!", ch, obj, NULL, TO_ROOM );
equip_char( ch, obj, WEAR_LODGE_ARM );
break;
case ITEM_LODGE_LEG:
act( AT_ACTION, "$p strikes you and deeply imbeds itself in your leg!", ch, obj, NULL, TO_CHAR );
act( AT_ACTION, "$p strikes $n and deeply imbeds itself in $s leg!", ch, obj, NULL, TO_ROOM );
equip_char( ch, obj, WEAR_LODGE_LEG );
break;
case ITEM_WEAR_FINGER:
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 ) )
{
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 ) )
{
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.", 0 );
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( !get_eq_char( ch, WEAR_NECK_1 ) )
{
if( !oprog_use_trigger( ch, obj, NULL, NULL, 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 ) )
{
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.", 0 );
send_to_char( "You already wear two neck items.\n\r", ch );
return;
case ITEM_WEAR_BODY:
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 ) )
{
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_HEAD:
if( !remove_obj( ch, WEAR_HEAD, fReplace ) )
return;
if( !oprog_use_trigger( ch, obj, NULL, NULL, 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( !remove_obj( ch, WEAR_EYES, fReplace ) )
return;
if( !oprog_use_trigger( ch, obj, NULL, NULL, 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_FACE:
if( !remove_obj( ch, WEAR_FACE, fReplace ) )
return;
if( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) )
{
act( AT_ACTION, "$n places $p on $s face.", ch, obj, NULL, TO_ROOM );
act( AT_ACTION, "You place $p on your face.", ch, obj, NULL, TO_CHAR );
}
equip_char( ch, obj, WEAR_FACE );
oprog_wear_trigger( ch, obj );
return;
case ITEM_WEAR_EARS:
if( !remove_obj( ch, WEAR_EARS, fReplace ) )
return;
if( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) )
{
act( AT_ACTION, "$n wears $p on $s ears.", ch, obj, NULL, TO_ROOM );
act( AT_ACTION, "You wear $p on your ears.", ch, obj, NULL, TO_CHAR );
}
equip_char( ch, obj, WEAR_EARS );
oprog_wear_trigger( ch, obj );
return;
case ITEM_WEAR_LEGS:
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 ) )
{
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( !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 ) )
{
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( !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 ) )
{
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( !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 ) )
{
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( !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 ) )
{
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_BACK:
if( !remove_obj( ch, WEAR_BACK, fReplace ) )
return;
if( !oprog_use_trigger( ch, obj, NULL, NULL, NULL ) )
{
act( AT_ACTION, "$n slings $p on $s back.", ch, obj, NULL, TO_ROOM );
act( AT_ACTION, "You sling $p on your back.", ch, obj, NULL, TO_CHAR );
}
equip_char( ch, obj, WEAR_BACK );
oprog_wear_trigger( ch, obj );
return;
case ITEM_WEAR_WAIST:
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 ) )
{
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( 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 ) )
{
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 ) )
{
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.", 0 );
send_to_char( "You already wear two wrist items.\n\r", ch );
return;
case ITEM_WEAR_ANKLE:
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 ) )
{
act( AT_ACTION, "$n fits $p around $s left ankle.", ch, obj, NULL, TO_ROOM );
act( AT_ACTION, "You fit $p around your left ankle.", 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 ) )
{
act( AT_ACTION, "$n fits $p around $s right ankle.", ch, obj, NULL, TO_ROOM );
act( AT_ACTION, "You fit $p around your right ankle.", ch, obj, NULL, TO_CHAR );
}
equip_char( ch, obj, WEAR_ANKLE_R );
oprog_wear_trigger( ch, obj );
return;
}
bug( "Wear_obj: no free ankle.", 0 );
send_to_char( "You already wear two ankle items.\n\r", ch );
return;
case ITEM_WEAR_SHIELD:
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 ) )
{
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:
case ITEM_WIELD:
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, *sd;
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 );
sd = get_eq_char( ch, WEAR_SHIELD );
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 || sd )
{
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 );
}
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( mw )
{
if( !can_dual( ch ) )
return;
if( 1 << bit == ITEM_MISSILE_WIELD )
{
send_to_char( "You're already wielding a missile weapon.\n\r", 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 || sd )
{
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 );
}
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_HOLD:
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 ) )
{
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;
short 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;
short 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 > ch->move )
{
send_to_char( "You don't have the energy to bury something of that size.\n\r", ch );
return;
}
ch->move -= 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 );
xSET_BIT( obj->extra_flags, ITEM_BURIED );
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;
if( !str_cmp( arg, "all" ) )
{
if( !ch->in_room->first_content )
{
send_to_char( "All what? There's nothing here!\n\r", ch );
return;
}
for( obj = ch->in_room->first_content; obj; obj = obj->next_content )
{
separate_obj( obj );
if( !CAN_WEAR( obj, ITEM_TAKE ) || !can_see_obj( ch, obj ) )
{
continue;
}
if( IS_SET( obj->magic_flags, ITEM_PKDISARMED ) && !IS_NPC( ch ) )
{
if( CAN_PKILL( ch ) && !get_timer( ch, TIMER_PKILLED ) )
{
if( ch->level - obj->value[5] > 5 || obj->value[5] - ch->level > 5 )
{
continue;
}
}
}
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
{
strcpy( name, "The God's" );
}
ch->gold += 1;
if( obj->item_type == ITEM_CORPSE_NPC || obj->item_type == ITEM_CORPSE_PC )
adjust_favor( ch, 5, 1 );
sprintf( buf, "%s give you one gold coin for sacrificing %s.\n\r", name, obj->short_descr );
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;
if( cur_obj == obj->serial )
global_objcode = rOBJ_SACCED;
extract_obj( obj );
}
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;
}
separate_obj( obj );
if( !CAN_WEAR( obj, ITEM_TAKE ) )
{
act( AT_PLAIN, "$p is not an acceptable sacrifice.", ch, obj, 0, TO_CHAR );
return;
}
if( IS_SET( obj->magic_flags, ITEM_PKDISARMED ) && !IS_NPC( ch ) )
{
if( CAN_PKILL( ch ) && !get_timer( ch, TIMER_PKILLED ) )
{
if( ch->level - obj->value[5] > 5 || obj->value[5] - ch->level > 5 )
{
send_to_char_color( "\n\r&bA godly force freezes your outstretched hand.\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
{
strcpy( name, "The God's" );
}
ch->gold += 1;
if( obj->item_type == ITEM_CORPSE_NPC || obj->item_type == ITEM_CORPSE_PC )
adjust_favor( ch, 5, 1 );
sprintf( buf, "%s give you one gold coin for your sacrifice.\n\r", name );
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;
if( cur_obj == obj->serial )
global_objcode = rOBJ_SACCED;
separate_obj( obj );
extract_obj( obj );
save_house_by_vnum( ch->in_room->vnum ); /* Prevent House Object Duplication */
return;
}
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( !IS_NPC( vch ) && xIS_SET( vch->act, PLR_WIZINVIS ) && 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", 0 );
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 );
if( staff->serial == cur_obj )
global_objcode = rOBJ_USED;
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", 0 );
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 );
if( wand->serial == cur_obj )
global_objcode = rOBJ_USED;
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];
short templvl;
OBJ_DATA *contents;
if( !clan )
{
bug( "save_clan_storeroom: Null clan pointer!", 0 );
return;
}
if( !ch )
{
bug( "save_clan_storeroom: Null ch pointer!", 0 );
return;
}
sprintf( filename, "%s%s.vault", CLAN_DIR, clan->filename );
if( ( fp = fopen( filename, "w" ) ) == NULL )
{
bug( "save_clan_storeroom: fopen", 0 );
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, FALSE );
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 arg3[MAX_INPUT_LENGTH];
char buf[MAX_STRING_LENGTH];
int i;
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
argument = one_argument( argument, arg3 );
set_char_color( AT_LBLUE, ch );
if( IS_NPC( ch ) ) /* NPC can be extracted at any time and thus can't auction! */
return;
if( ch->level < 3 )
{
send_to_char( "You must be at least level three to use the auction...\n\r", ch );
return;
}
if( ( time_info.hour > 18 || time_info.hour < 9 ) && auction->item == NULL && !IS_IMMORTAL( ch ) )
{
send_to_char( "\n\rThe auctioneer works between the hours of 9 AM and 6 PM\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, "\n\rCurrent bid on this item is %s gold.\n\r", num_punct( auction->bet ) );
else
sprintf( buf, "\n\rNo 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\n\rIts weight is %d, value is %d, and level is %d.\n\r",
obj->name, aoran( item_type_name( obj ) ), extra_bit_name( &obj->extra_flags ),
/*
* magic_bit_name( obj->magic_flags ), -- currently unused
*/
obj->weight, obj->cost, obj->level );
set_char_color( AT_LBLUE, ch );
send_to_char( buf, ch );
if( obj->item_type != ITEM_LIGHT && obj->wear_flags - 1 > 0 )
ch_printf( ch, "Item's wear location: %s\n\r", flag_string( obj->wear_flags - 1, w_flags ) );
set_char_color( AT_BLUE, ch );
switch ( obj->item_type )
{
case ITEM_CONTAINER:
case ITEM_KEYRING:
case ITEM_QUIVER:
ch_printf( ch, "%s appears to %s.\n\r", capitalize( obj->short_descr ),
obj->value[0] < 76 ? "have a small capacity" :
obj->value[0] < 150 ? "have a small to medium capacity" :
obj->value[0] < 300 ? "have a medium capacity" :
obj->value[0] < 500 ? "have a medium to large capacity" :
obj->value[0] < 751 ? "have a large capacity" : "have a giant capacity" );
break;
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_MISSILE_WEAPON:
case ITEM_WEAPON:
sprintf( buf, "Damage is %d to %d (average %d).%s\n\r",
obj->value[1], obj->value[2],
( obj->value[1] + obj->value[2] ) / 2,
IS_OBJ_STAT( obj, ITEM_POISONED ) ? "\n\rThis weapon is poisoned." : "" );
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->item_type == ITEM_KEYRING
|| obj->item_type == ITEM_QUIVER ) && 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 */
{
auction->buyer->gold += 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->level < auction->item->level )
{
send_to_char( "This object's level is too high for your use.\n\r", ch );
return;
}
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( arg2[0] == '\0' )
{
send_to_char( "Bid how much?\n\r", ch );
return;
}
newbet = parsebet( auction->bet, arg2 );
/*
* 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 ) )
{
send_to_char( "You must at least bid over the current bid.\n\r", ch );
return;
}
if( newbet > ch->gold )
{
send_to_char( "You don't have that much money!\n\r", ch );
return;
}
if( newbet > 2000000000 )
{
send_to_char( "You can't bid over 2 billion coins.\n\r", ch );
return;
}
/*
* Is it the item they really want to bid on? --Shaddai
*/
if( arg3[0] != '\0' && !nifty_is_name( arg3, auction->item->name ) )
{
send_to_char( "That item is not being auctioned right now.\n\r", 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 %s gold has been received on %s.\n\r", num_punct( newbet ), 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;
}
/*
* prevent repeat auction items
*/
for( i = 0; i < AUCTION_MEM && auction->history[i]; i++ )
{
if( auction->history[i] == obj->pIndexData )
{
send_to_char( "Such an item has been auctioned " "recently, try again later.\n\r", ch );
return;
}
}
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 gold!\n\r", 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_TREASURE:
case ITEM_POTION:
case ITEM_CONTAINER:
case ITEM_KEYRING:
case ITEM_QUIVER:
case ITEM_DRINK_CON:
case ITEM_FOOD:
case ITEM_COOK:
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_MISSILE_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;
auction->buyer = ch;
auction->seller = ch;
auction->pulse = PULSE_AUCTION;
auction->going = 0;
auction->starting = atoi( arg2 );
/*
* add the new item to the history
*/
if( AUCTION_MEM > 0 )
{
memmove( ( char * )auction->history + sizeof( OBJ_INDEX_DATA * ),
auction->history, ( AUCTION_MEM - 1 ) * sizeof( OBJ_INDEX_DATA * ) );
auction->history[0] = obj->pIndexData;
}
/*
* reset the history timer
*/
auction->hist_timer = 0;
if( auction->starting > 0 )
auction->bet = auction->starting;
sprintf( buf, "A new item is being auctioned: %s at %d gold.", 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 );
if( !IS_IMMORTAL( ch ) )
WAIT_STATE( ch, 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", 0 );
extract_obj( obj );
fall_count = 0;
return;
}
if( xIS_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 %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, NULL );
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( !xIS_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_WHITE, "$p falls on $n!", vch, obj, NULL, TO_ROOM );
act( AT_WHITE, "$p falls on you!", vch, obj, NULL, TO_CHAR );
if( IS_NPC( vch ) && xIS_SET( vch->act, ACT_HARDHAT ) )
act( AT_WHITE, "$p bounces harmlessly off your head!", vch, obj, NULL, TO_CHAR );
else
damage( vch, vch, dam * vch->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;
}
/* Scryn, by request of Darkur, 12/04/98 */
/* Reworked recursive_note_find to fix crash bug when the note was left
* blank. 7/6/98 -- Shaddai
*/
void do_findnote( CHAR_DATA * ch, char *argument )
{
OBJ_DATA *obj;
if( IS_NPC( ch ) )
{
send_to_char( "Huh?\n\r", ch );
return;
}
if( argument[0] == '\0' )
{
send_to_char( "You must specify at least one keyword.\n\r", ch );
return;
}
obj = recursive_note_find( ch->first_carrying, argument );
if( obj )
{
if( obj->in_obj )
{
obj_from_obj( obj );
obj = obj_to_char( obj, ch );
}
wear_obj( ch, obj, TRUE, -1 );
}
else
send_to_char( "Note not found.\n\r", ch );
return;
}
OBJ_DATA *recursive_note_find( OBJ_DATA * obj, char *argument )
{
OBJ_DATA *returned_obj;
bool match = TRUE;
char *argcopy;
char *subject;
char arg[MAX_INPUT_LENGTH];
char subj[MAX_STRING_LENGTH];
if( !obj )
return NULL;
switch ( obj->item_type )
{
case ITEM_PAPER:
if( ( subject = get_extra_descr( "_subject_", obj->first_extradesc ) ) == NULL )
break;
sprintf( subj, "%s", strlower( subject ) );
subject = strlower( subj );
argcopy = argument;
while( match )
{
argcopy = one_argument( argcopy, arg );
if( arg[0] == '\0' )
break;
if( !strstr( subject, arg ) )
match = FALSE;
}
if( match )
return obj;
break;
case ITEM_CONTAINER:
case ITEM_CORPSE_NPC:
case ITEM_CORPSE_PC:
if( obj->first_content )
{
returned_obj = recursive_note_find( obj->first_content, argument );
if( returned_obj )
return returned_obj;
}
break;
default:
break;
}
return recursive_note_find( obj->next_content, argument );
}
void do_rolldie( CHAR_DATA * ch, char *argument )
{
OBJ_DATA *die;
char output_string[MAX_STRING_LENGTH];
char roll_string[MAX_STRING_LENGTH];
char total_string[MAX_STRING_LENGTH];
char *verb;
/*
* char* face_string = NULL;
* char** face_table = NULL;
*/
int rollsum = 0;
int roll_count = 0;
int numsides;
int numrolls;
bool *face_seen_table = NULL;
if( IS_NPC( ch ) )
{
send_to_char( "Huh?\n\r", ch );
return;
}
if( ( die = get_eq_char( ch, WEAR_HOLD ) ) == NULL || die->item_type != ITEM_CHANCE )
{
ch_printf( ch, "You must be holding an item of chance!\n\r" );
return;
}
numrolls = ( is_number( argument ) ) ? atoi( argument ) : 1;
verb = get_chance_verb( die );
if( numrolls > 100 )
{
ch_printf( ch, "You can't %s more than 100 times!\n\r", verb );
return;
}
numsides = die->value[0];
if( numsides <= 1 )
{
ch_printf( ch, "There is no element of chance in this game!\n\r" );
return;
}
if( die->value[3] == 1 )
{
if( numrolls > numsides )
{
ch_printf( ch, "Nice try, but you can only %s %d times.\n\r", verb, numsides );
return;
}
face_seen_table = calloc( numsides, sizeof( bool ) );
if( !face_seen_table )
{
bug( "do_rolldie: cannot allocate memory for face_seen_table array, terminating.\n\r", 0 );
return;
}
}
sprintf( roll_string, " " );
while( roll_count++ < numrolls )
{
int current_roll;
char current_roll_string[MAX_STRING_LENGTH];
do
{
current_roll = number_range( 1, numsides );
}
while( die->value[3] == 1 && face_seen_table[current_roll - 1] == TRUE );
if( die->value[3] == 1 )
face_seen_table[current_roll - 1] = TRUE;
rollsum += current_roll;
if( roll_count > 1 )
strcat( roll_string, ", " );
if( numrolls > 1 && roll_count == numrolls )
strcat( roll_string, "and " );
if( die->value[1] == 1 )
{
char *face_name = get_ed_number( die, current_roll );
if( face_name )
{
char *face_name_copy = strdup( face_name ); /* Since I want to tokenize without modifying the original string */
sprintf( current_roll_string, "%s", strtok( face_name_copy, "\n" ) );
free( face_name_copy );
}
else
sprintf( current_roll_string, "%d", current_roll );
}
else
sprintf( current_roll_string, "%d", current_roll );
strcat( roll_string, current_roll_string );
}
if( numrolls > 1 && die->value[2] == 1 )
{
sprintf( total_string, ", for a total of %d", rollsum );
strcat( roll_string, total_string );
}
strcat( roll_string, ".\n\r" );
sprintf( output_string, "You %s%s", verb, roll_string );
act( AT_GREEN, output_string, ch, NULL, NULL, TO_CHAR );
sprintf( output_string, "$n %s%s", verb, roll_string );
act( AT_GREEN, output_string, ch, NULL, NULL, TO_ROOM );
if( face_seen_table )
free( face_seen_table );
return;
}
char *get_ed_number( OBJ_DATA * obj, int number )
{
EXTRA_DESCR_DATA *ed;
int count;
for( ed = obj->first_extradesc, count = 1; ed; ed = ed->next, count++ )
{
if( count == number )
return ed->description;
}
return NULL;
}
char *get_chance_verb( OBJ_DATA * obj )
{
return ( obj->action_desc[0] != '\0' ) ? obj->action_desc : "roll$q";
}
/*dice chance deal throw*/
/* Junk command installed by Samson 1-13-98
* Code courtesy of Stu, from the mailing list. Allows player to destroy an item in their inventory.
* Debugged and cleaned up on 4-16-01 by Samson.
*/
void do_junk( CHAR_DATA * ch, char *argument )
{
OBJ_DATA *obj, *obj_next;
bool found = FALSE;
if( !argument || argument[0] == '\0' )
{
send_to_char( "Junk what?\n\r", ch );
return;
}
for( obj = ch->first_carrying; obj; obj = obj_next )
{
obj_next = obj->next_content;
if( ( nifty_is_name( argument, obj->name ) ) && can_see_obj( ch, obj ) && obj->wear_loc == WEAR_NONE )
{
found = TRUE;
break;
}
}
if( found )
{
if( !can_drop_obj( ch, obj ) && ch->level < LEVEL_IMMORTAL )
{
send_to_char( "You cannot junk that, it's cursed!\n\r", ch );
return;
}
separate_obj( obj );
obj_from_char( obj );
extract_obj( obj );
act( AT_ACTION, "$n junks $p.", ch, obj, NULL, TO_ROOM );
act( AT_ACTION, "You junk $p.", ch, obj, NULL, TO_CHAR );
}
return;
}
/* Donate command installed by Samson 2-6-98
Coded by unknown author. Players can donate items for others to use. */
/* Modified by Whir for multiple donation rooms - 3/25/98 */
/* Slight bug corrected, objects weren't being seperated from each other - Whir 3-25-98 */
/* Updated to use internal Smaug random number generator - Samson 9-11-98 */
void do_donate( CHAR_DATA * ch, char *argument )
{
OBJ_DATA *obj;
if( !argument || argument[0] == '\0' )
{
send_to_char( "Donate what?\n\r", ch );
return;
}
if( ch->position == POS_FIGHTING )
{
send_to_char( "You cannot donate while fighting!\n\r", ch );
return;
}
if( !( obj = get_obj_carry( ch, argument ) ) )
{
send_to_char( "You do not have that!\n\r", ch );
return;
}
else
{
if( !can_drop_obj( ch, obj ) && ch->level < LEVEL_IMMORTAL )
{
send_to_char( "You cannot donate that, it's cursed!\n\r", ch );
return;
}
if( ( obj->item_type == ITEM_CORPSE_NPC ) || ( obj->item_type == ITEM_CORPSE_PC ) )
{
send_to_char( "You cannot donate corpses!\n\r", ch );
return;
}
if( obj->timer > 0 )
{
send_to_char( "You cannot donate that.\n\r", ch );
return;
}
if( xSET_BIT( obj->extra_flags, ITEM_DONATION ) )
{
send_to_char( "That item has already been donated once before.\n\r", ch );
return;
}
act( AT_ACTION, "You donate $p, how generous of you!", ch, obj, NULL, TO_CHAR );
send_to_char( "The Gods reward you with 10 gold for your generosity\n\r", ch );
ch->gold += 10;
separate_obj( obj );
obj->cost = 0;
xSET_BIT( obj->extra_flags, ITEM_DONATION );
obj_from_char( obj );
obj_to_room( obj, get_room_index( ROOM_VNUM_DONATION ), NULL );
/*
* Bleh. Forgot this to stop item duping. Samson 4-4-01
*/
save_char_obj( ch );
return;
}
}