/**************************************************************************/
// skill_ke.cpp - skills written by Kerenos
/***************************************************************************
* The Dawn of Time v1.69r (c)1997-2004 Michael Garratt *
* >> A number of people have contributed to the Dawn codebase, with the *
* majority of code written by Michael Garratt - www.dawnoftime.org *
* >> To use this source code, you must fully comply with the dawn license *
* in licenses.txt... In particular, you may not remove this copyright *
* notice. *
**************************************************************************/
#include "include.h"
#include "o_lookup.h"
#include "db.h"
#include "ictime.h"
// Prototype declarations
HERB_DATA *find_herb( char_data * ch, char *herb );
void entangle( char_data *ch, char_data *victim );
void dismount( char_data *);
void flourish_totemstaff_guardian( char_data *ch, OBJ_DATA *obj );
void flourish_totemstaff_spirit( char_data *ch, OBJ_DATA *obj );
void forage_food( char_data *ch );
void forage_herbs( char_data *ch );
int get_birthmonth( char_data *ch );
int calculate_season( void );
char *format_obj_to_char_new( OBJ_DATA *obj, char_data *ch, bool fShort );
DECLARE_DO_FUN( do_cast );
char * const month_name [] =
{
"Winter", "the Winter Storm", "the Frost Blight",
"the Return","Blight","the Dragon",
"Light", "the Sun", "the Heat",
"the Great War", "the Shadows", "the Long Shadows",
};
/**************************************************************************/
// Kerenos - Sept 98
void do_forage( char_data *ch, char *argument )
{
if ( IS_NULLSTR( argument ))
{
ch->println( "Syntax: forage [food/herbs]" );
return;
}
if ( !str_prefix( argument, "food" ))
{
forage_food( ch );
return;
}
if ( !str_prefix( argument, "herbs" ))
{
forage_herbs( ch );
return;
}
ch->println( "Syntax: forage [food/herbs]" );
return;
}
/**************************************************************************/
void forage_food( char_data *ch )
{
OBJ_INDEX_DATA *pObjIndex;
OBJ_DATA *pObj;
int chance;
chance = get_skill( ch, gsn_forage )+10;
if ( chance < 11){
ch->println("You don't know how to forage for food.");
return;
}
// make it easier for newbies
if (ch->level<30)
chance+=ch->level;
if ( ch->in_room->sector_type == SECT_INSIDE
|| ch->in_room->sector_type == SECT_CITY
|| ch->in_room->sector_type == SECT_WATER_NOSWIM
|| ch->in_room->sector_type == SECT_UNDERWATER
|| ch->in_room->sector_type == SECT_CAVE
|| ch->in_room->sector_type == SECT_SWAMP
|| ch->in_room->sector_type == SECT_AIR ) {
ch->println("You cannot find any foodstuffs around here.");
return;
}
if (chance<number_range(0,105)){
ch->wrapln("You forage around for something to eat but didnt manage to find "
"any suitable foodstuffs here.");
#ifdef unix
WAIT_STATE( ch, PULSE_PER_SECOND *number_range(3,5));
#endif
return;
}
if (( pObjIndex = get_obj_index( OBJ_VNUM_MUSHROOM )) == NULL ) {
ch->println("Food item non-existant, please report this with a note to admin.");
return;
}
pObj = create_object( pObjIndex);
// Free up old object names and descriptions
free_string( pObj->description );
free_string( pObj->name );
free_string( pObj->short_descr );
// Make food timer 24 hours for perishable foods, no stockpiling allowed :)
pObj->timer = 24;
// Change food desc according to terrain type
switch ( ch->in_room->sector_type ) {
case SECT_FIELD:
pObj->description = str_dup( "You see a bunch of eldeberries here." );
pObj->short_descr = str_dup( "a bunch of eldeberries" );
pObj->name = str_dup( "eldeberries bunch" );
break;
case SECT_FOREST:
pObj->description = str_dup( "You see a handful of hazelnuts." );
pObj->short_descr = str_dup( "a handful of hazelnuts" );
pObj->name = str_dup( "hazelnuts" );
break;
case SECT_HILLS:
pObj->description = str_dup( "Some wild berries are here." );
pObj->short_descr = str_dup( "some wild berries" );
pObj->name = str_dup( "berries wild" );
break;
case SECT_MOUNTAIN:
pObj->description = str_dup( "You see a tangy wild root." );
pObj->short_descr = str_dup( "a tangy wild root" );
pObj->name = str_dup( "root wild tangy" );
break;
case SECT_WATER_SWIM:
pObj->description = str_dup( "You look upon a fresh, dead trout." );
pObj->short_descr = str_dup( "a fresh, dead trout" );
pObj->name = str_dup( "trout" );
break;
case SECT_DESERT:
pObj->description = str_dup( "You see a pulpy cactus heart here, looks good enough to eat." );
pObj->short_descr = str_dup( "the heart of a cactus" );
pObj->name = str_dup( "cactus heart pulp" );
break;
}
// Send the message to the world!
#ifdef unix
WAIT_STATE( ch, PULSE_PER_SECOND * number_range(6, 10));
#endif
obj_to_room( pObj, ch->in_room );
ch->println("You found something to eat.");
act( "$n seems to be searching for something.", ch, NULL, NULL, TO_ROOM );
check_improve( ch, gsn_forage, true, 2 );
return;
}
/**************************************************************************/
void forage_herbs( char_data *ch )
{
OBJ_INDEX_DATA *pHerb;
OBJ_DATA *herb_obj;
HERB_DATA *herb;
int vnum, chance, num = 0;
static vn_int vnum_field[500]; // show me a mud ever with more than 500 herbs
bool found = false;
chance = get_skill( ch, gsn_forage );
if ( chance < 1 ){
ch->println( "You don't know how to forage." );
return;
}
if ( IS_AFFECTED(ch, AFF_BLIND) ) {
ch->println( "You can't see a thing." );
return;
}
for( herb = herb_list; herb; herb = herb->next )
{
if ( ch->in_room->sector_type != herb->sector )
continue;
if ( herb->continent )
{
if ( ch->in_room->area->continent != herb->continent ){
continue;
}
}
if ( herb->area >= 0 )
{
if ( ch->in_room->area->vnum != herb->area )
continue;
}
if ( herb->season >=0 )
{
if ( calculate_season() != herb->season )
continue;
}
if ( timefield_table[herb->timefield].lowhour != -1 )
{
if ( time_info.hour < timefield_table[herb->timefield].lowhour
|| time_info.hour > timefield_table[herb->timefield].highhour )
continue;
}
if (( chance + modifier_table[herb->difficulty].modifier ) < number_percent())
continue;
found = true;
vnum_field[num] = herb->vnum_result;
num++;
}
int seconds_lag = number_range(6, 10);
#ifdef WIN32
seconds_lag =1;
#endif
ch->println( "You look around for herbs..." );
WAIT_STATE( ch, PULSE_PER_SECOND *seconds_lag);
if ( !found )
{
ch->println(seconds_lag, "You didn't find anything that resembled a useful herb." );
return;
}
vnum = vnum_field[number_range( 0, num-1 )];
if (( pHerb = get_obj_index( vnum )) == NULL ) {
ch->println(seconds_lag, "You didn't find anything that resembled a useful herb." );
return;
}
herb_obj = create_object( pHerb);
//??herb_obj->timer = 96;
obj_to_char( herb_obj, ch );
ch->printlnf( seconds_lag, "You found %s!", format_obj_to_char_new( herb_obj, ch, true));
// act is seen before the player finds out they found something - but will do for now :)
act( "$n has found an herb.", ch, NULL, NULL, TO_ROOM );
check_improve( ch, gsn_forage, true, 2 );
return;
}
/**************************************************************************/
void do_cook( char_data *ch, char *argument )
{
OBJ_DATA *obj;
OBJ_DATA *fire;
OBJ_DATA *cookware;
ROOM_INDEX_DATA *pIndexRoom = ch->in_room;
char arg[MIL];
int chance;
bool foundfire = false;
bool foundpan = false;
chance = get_skill( ch, gsn_cook ) + 30;
if ( chance < 31){
ch->println("You don't know the first thing about cooking.");
return;
}
one_argument( argument, arg );
if IS_NULLSTR( arg ) {
ch->println("What do you wish to cook?");
return;
}
if (( obj = get_obj_carry( ch, arg )) == NULL ) {
ch->println("You are not carrying that.");
return;
}
if ( obj->item_type != ITEM_FOOD ) {
ch->println("You can only cook foodstuffs.");
return;
}
if ( obj->timer == 0 ) {
act( "$p appears to be cooked already.", ch, obj, NULL, TO_CHAR );
return;
}
for ( fire = pIndexRoom->contents; fire; fire = fire->next_content ) {
if ( fire->pIndexData->vnum == OBJ_VNUM_FIRE ) {
foundfire = true;
break;
}
}
if ( !foundfire ) {
ch->println("There needs to be a fire for you to cook properly.");
return;
}
for ( cookware = ch->carrying; cookware; cookware = cookware->next_content )
{
if ( !str_cmp( cookware->pIndexData->material, "cookware" )
&& cookware->wear_loc == WEAR_HOLD ) {
foundpan = true;
break;
}
}
if ( !foundpan ) {
ch->println("You need to hold a cooking pot of some kind to cook the food.");
return;
}
if ( chance < number_percent() ) {
act( "You fail miserably attempting to cook $p, ruining it completely.", ch, obj, NULL, TO_CHAR );
extract_obj( obj );
check_improve( ch, gsn_cook, false, 3 );
WAIT_STATE( ch, skill_table[gsn_cook].beats/2 );
return;
}
act( "You busy yourself cooking $p, and do it to perfection!", ch, obj, NULL, TO_CHAR );
act( "$n busies $mself cooking $p.", ch, obj, NULL, TO_ROOM );
obj->timer = 0;
if ( obj->pIndexData->vnum == OBJ_VNUM_SLICE ) {
replace_string( obj->description, "A slice of cooked meat lies here." );
replace_string( obj->short_descr, "a slice of cooked meat" );
replace_string( obj->name, "slice meat cooked" );
}
check_improve( ch, gsn_cook, true, 4 );
WAIT_STATE( ch, skill_table[gsn_cook].beats );
return;
}
/**************************************************************************/
void do_flip( char_data *ch, char *argument )
{
int face = number_range( 0, 1);
bool spam = false;
OBJ_INDEX_DATA *coinIndex;
OBJ_DATA *coin;
if ( IS_NULLSTR( argument )) {
ch->println("What do you want to flip, a silver or a gold coin?");
return;
}
if ( ch->desc && ch->desc->repeat>5 )
spam = true;
if ( is_name( argument, "silver" ))
{
if ( ch->silver < 1 ) {
ch->println("You have no silver coins to flip.");
return;
}
coinIndex = get_obj_index( OBJ_VNUM_SILVER_ONE );
coin = create_object( coinIndex);
ch->silver -= 1;
free_string( coin->description );
if ( face ) {
act( "$n flips a coin high into the air and lands showing heads.", ch, NULL, NULL, TO_ROOM );
ch->println("You flip a coin high into the air. It lands showing heads.");
coin->description = str_dup( "You see a silver coin showing heads." );
} else {
act( "$n flips a coin high into the air and lands showing tails.", ch, NULL, NULL, TO_ROOM );
ch->println("You flip a coin high into the air. It lands showing tails.");
coin->description = str_dup( "You see a silver coin showing tails." );
}
if ( !IS_OOC(ch) ) { obj_to_room( coin, ch->in_room ); }
}
else if ( is_name( argument, "gold" ))
{
if ( ch->gold < 1 ) {
ch->println("You have no gold coins to flip.");
return;
}
coinIndex = get_obj_index( OBJ_VNUM_GOLD_ONE );
coin = create_object( coinIndex);
ch->gold -= 1;
free_string( coin->description );
if ( face ) {
act( "$n flips a coin high into the air and lands showing heads.", ch, NULL, NULL, TO_ROOM );
ch->println("You flip a coin high into the air. It lands showing heads.");
coin->description = str_dup( "You see a gold coin showing heads." );
} else {
act( "$n flips a coin high into the air and lands showing tails.", ch, NULL, NULL, TO_ROOM );
ch->println("You flip a coin high into the air. It lands showing tails.");
coin->description = str_dup( "You see a gold coin showing tails." );
}
if ( !IS_OOC(ch)) { obj_to_room( coin, ch->in_room ); }
}
else
{
ch->println("What do you want to flip, a silver or a gold coin?");
}
if ( spam )
WAIT_STATE( ch, PULSE_PER_SECOND * 10 );
}
/**************************************************************************/
void do_hobble( char_data *ch, char *argument )
{
char_data * victim;
OBJ_DATA * obj;
char arg[MIL];
int chance;
if ((chance = get_skill(ch,gsn_hobble)) == 0)
{
do_huh(ch,"");
return;
}
one_argument( argument, arg );
obj = ( get_eq_char( ch, WEAR_WIELD ));
if ( !obj ) {
ch->println("You need to wield a mace to hobble someone.");
return;
}
if ( obj ) {
if ( obj->value[0] != WEAPON_MACE ) {
ch->println("You are not wielding a mace.");
return;
}
}
if( IS_RIDING( ch )) {
ch->println("You cannot reach your opponents legs while mounted.");
return;
}
if ( IS_NULLSTR( arg )) {
if (( victim = ch->fighting ) == NULL ) {
ch->println("But you aren't fighting anyone!");
return;
}
}
else if (( victim = get_char_room( ch, arg )) == NULL ) {
ch->printlnf("You can't seem to find '%s' here.", arg);
return;
}
if(ch == victim)
{
ch->println("Yeah, right.");
return;
}
if ( is_safe( ch, victim ))
return;
if ( !can_initiate_combat( ch, victim, CIT_GENERAL )) return;
if ( IS_AFFECTED( ch, AFF_CHARM ) && ch->master == victim ) {
act("But $N is your friend!",ch,NULL,victim,TO_CHAR);
return;
}
// INSERT WEAPON SPECIALIZATION CHECK HERE
if ( get_skill( ch,gsn_hobble ) > number_percent() ) {
act( "You `Bsmash`x $p against $N's legs!", ch, obj, victim, TO_CHAR );
act( "$n `Bsmashes`x $p against $N's legs!", ch, obj, victim, TO_NOTVICT );
act( "$n `Bsmashes`x $p on your legs!", ch, obj, victim, TO_VICT );
if ( damage( ch, victim, number_range( 1, ch->level / 2 ), gsn_hobble, DAM_BASH, true)) {
victim->position = POS_RESTING;
DAZE_STATE( victim, skill_table[gsn_hobble].beats*2/3 );
victim->move -= number_range(( ch->level/5 ), ch->level);
}
check_improve( ch, gsn_hobble, true, 1 );
WAIT_STATE( ch, skill_table[gsn_hobble].beats );
}
else {
damage( ch, victim, 0, gsn_hobble, DAM_BASH, false );
check_improve( ch, gsn_hobble, false, 1 );
ch->println("You swing wildly and don't manage to connect the blow.");
act("$n tries to hobble $N but misses completely.", ch, NULL, victim, TO_NOTVICT);
act("You deftly evade $n's attempt to hobble you.", ch, NULL, victim, TO_VICT );
WAIT_STATE( ch, skill_table[gsn_hobble].beats );
}
return;
}
/**************************************************************************/
void do_shieldcleave( char_data *ch, char *argument )
{
char_data * victim;
OBJ_DATA * obj;
OBJ_DATA * shield;
char arg[MIL];
int chance;
if ((chance = get_skill(ch,gsn_shieldcleave)) == 0)
{
do_huh(ch,"");
return;
}
one_argument( argument, arg );
obj = ( get_eq_char( ch, WEAR_WIELD ));
if ( !obj ) {
ch->println("You need to wield an axe to cleave a shield.");
return;
}
if ( obj ) {
if ( obj->value[0] != WEAPON_AXE ) {
ch->println("You are not wielding an axe.");
return;
}
}
if (( victim = ch->fighting ) == NULL ) {
ch->println("You aren't fighting anyone.");
return;
}
if(ch == victim)
{
ch->println("Yeah, right.");
return;
}
shield = ( get_eq_char( victim, WEAR_SHIELD ));
if ( !shield ) {
ch->println("Your opponent is not wearing a shield.");
return;
}
if ( IS_AFFECTED( ch, AFF_CHARM ) && ch->master == victim ) {
act("But $N is your friend!",ch,NULL,victim,TO_CHAR);
return;
}
if ( is_safe( ch, victim ))
return;
// INSERT WEAPON SPECIALIZATION CHECK HERE
if ( get_skill( ch,gsn_shieldcleave ) > number_percent() ) {
chance = 40;
if IS_WEAPON_STAT( obj, WEAPON_SHARP ) chance += 10;
if IS_WEAPON_STAT( obj, WEAPON_VORPAL ) chance += 20;
if IS_WEAPON_STAT( obj, WEAPON_FROST ) chance += 10;
if IS_WEAPON_STAT( obj, WEAPON_FLAMING ) chance += 5;
if IS_WEAPON_STAT( obj, WEAPON_SHOCKING ) chance += 5;
if IS_OBJ_STAT( shield, OBJEXTRA_BLESS ) chance -= 25;
if IS_OBJ_STAT( shield, OBJEXTRA_MAGIC ) chance -= 20;
if IS_OBJ_STAT( shield, OBJEXTRA_GLOW ) chance -= 5;
if IS_OBJ_STAT( shield, OBJEXTRA_CHAOS ) chance -= number_range(1,25);
if IS_OBJ_STAT( shield, OBJEXTRA_HUM ) chance -= 5;
if IS_OBJ_STAT( shield, OBJEXTRA_NONMETAL ) chance += 10;
if IS_OBJ_STAT( shield, OBJEXTRA_BURN_PROOF ) chance -= 35;
if ( number_range( 1, 100 ) < chance ) {
ch->println("Your axe `Bslices`x through the shield like butter.");
act("$n `Bslices`x right through $N's shield.", ch, NULL, victim, TO_NOTVICT);
act("$n has `Bdestroyed`x your shield.", ch, NULL, victim, TO_VICT);
extract_obj( shield );
} else {
act( "$N's shield withstands your blow!", ch, obj, victim, TO_CHAR );
act( "$n smashes against $N's shield without effect!", ch, obj, victim, TO_NOTVICT );
act( "Your shield resonates agains $N's swing, but holds firm.", ch, obj, victim, TO_VICT );
}
check_improve( ch, gsn_shieldcleave, true, 1 );
WAIT_STATE( ch, skill_table[gsn_shieldcleave].beats );
}
else {
check_improve( ch, gsn_shieldcleave, false, 1 );
ch->println("You swing wildly and don't manage to connect the blow.");
act("$n tries to cleave $N's shield and misses completely.", ch, NULL, victim, TO_NOTVICT);
victim->println("You manage to avoid your shield being cleaved in two.");
WAIT_STATE( ch, skill_table[gsn_shieldcleave].beats );
}
return;
}
/**************************************************************************/
void do_hurl( char_data *ch, char *argument )
{
char arg[MIL];
char_data *victim = NULL;
OBJ_DATA *dagger = NULL;
int dam;
int chance;
chance = get_skill( ch, gsn_hurl );
if ( chance < 1)
{
do_huh(ch,"");
return;
}
dagger = get_eq_char( ch, WEAR_WIELD );
if ( !dagger )
{
ch->println("You have to have your dagger readied in your hand.");
return;
}
if ( dagger->value[0] != WEAPON_DAGGER )
{
ch->println("You may only hurl daggers.");
return;
}
if ( !can_drop_obj( ch, dagger ))
{
ch->println("You can't let go of that.");
return;
}
one_argument( argument, arg );
if ( arg[0] == '\0')
{
victim = ch->fighting;
if ( victim == NULL )
{
ch->println("But you aren't fighting anyone!");
return;
}
}
else if (( victim = get_char_room( ch, arg )) == NULL )
{
ch->println("They aren't here.");
return;
}
if(ch == victim)
{
ch->println("Yeah, right.");
return;
}
if ( is_safe( ch, victim ))
return;
if ( IS_AFFECTED( ch, AFF_CHARM ) && ch->master == victim ) {
act("But $N is your friend!",ch,NULL,victim,TO_CHAR);
return;
}
WAIT_STATE( ch, skill_table[gsn_hurl].beats );
act( "$n hurls $p at $N.", ch, dagger, victim, TO_NOTVICT );
act( "You hurl $p at $N.", ch, dagger, victim, TO_CHAR );
act( "$n hurls $p at you.", ch, dagger, victim, TO_VICT );
if (( ch->level + 5 ) < dagger->level
|| number_percent() >= 10 + get_skill( ch, gsn_hurl ) * 4/5 )
{
act( "$p misses $N and lands on the ground.", ch, dagger, victim, TO_CHAR );
act( "$n hurls $p but it misses and lands on the ground.", ch, dagger, NULL, TO_ROOM );
obj_from_char( dagger );
obj_to_room( dagger, ch->in_room );
check_improve( ch, gsn_hurl, false, 1 );
if ( IS_OBJ_STAT( dagger, OBJEXTRA_MELT_DROP ))
{
act( "$p dissolves into smoke.", ch, dagger, NULL, TO_ROOM );
extract_obj( dagger );
}
}
else
{
chance = number_range(1,10);
switch (chance)
{
case 1:
case 2:
case 3:
case 4:
case 5:
obj_from_char( dagger );
dam = dice( dagger->value[1], dagger->value[2] );
if (damage( ch, victim, dam, gsn_hurl, DAM_PIERCE, true ))
{
if ( get_eq_char( victim, WEAR_LODGED_ARM ) != NULL ) {
obj_to_room( dagger, ch->in_room );
act( "$p doesn't lodge into your arm.", ch, dagger, victim, TO_VICT );
act( "$p hurts $N but doesn't succesfully lodge.", ch, dagger, victim, TO_CHAR );
if ( IS_OBJ_STAT( dagger, OBJEXTRA_MELT_DROP ))
{
act( "$p dissolves into smoke.", ch, dagger, NULL, TO_ROOM );
extract_obj( dagger );
}
}
else
{
obj_to_char( dagger, victim );
SET_BIT( dagger->extra_flags, OBJEXTRA_LODGED );
dagger->wear_flags = OBJWEAR_TAKE | OBJWEAR_LODGED_ARM;
wear_obj( victim, dagger, true, false);
dagger->wear_flags = OBJWEAR_TAKE | OBJWEAR_WIELD;
}
}
else
{
obj_to_room( dagger, ch->in_room );
if ( IS_OBJ_STAT( dagger, OBJEXTRA_MELT_DROP ))
{
act( "$p dissolves into smoke.", ch, dagger, NULL, TO_ROOM );
extract_obj( dagger );
}
}
check_improve( ch, gsn_hurl, true, 1 );
break;
case 6:
case 7:
case 8:
obj_from_char( dagger );
dam = 3 * ( dice( dagger->value[1], dagger->value[2] )/2);
if ( damage( ch, victim, dam, gsn_hurl, DAM_PIERCE, true ))
{
if ( get_eq_char( victim, WEAR_LODGED_LEG ) != NULL ) {
obj_to_room( dagger, ch->in_room );
act( "$p doesn't lodge into your leg.", ch, dagger, victim, TO_VICT );
act( "$p hurts $N but doesn't succesfully lodge.", ch, dagger, victim, TO_CHAR );
if ( IS_OBJ_STAT( dagger, OBJEXTRA_MELT_DROP ))
{
act( "$p dissolves into smoke.", ch, dagger, NULL, TO_ROOM );
extract_obj( dagger );
}
}
else
{
obj_to_char( dagger, victim );
SET_BIT( dagger->extra_flags, OBJEXTRA_LODGED );
dagger->wear_flags = OBJWEAR_TAKE | OBJWEAR_LODGED_LEG;
wear_obj( victim, dagger, true, false);
dagger->wear_flags = OBJWEAR_TAKE | OBJWEAR_WIELD;
}
}
else
{
obj_to_room( dagger, ch->in_room );
if ( IS_OBJ_STAT( dagger, OBJEXTRA_MELT_DROP ))
{
act( "$p dissolves into smoke.", ch, dagger, NULL, TO_ROOM );
extract_obj( dagger );
}
}
check_improve( ch, gsn_hurl, true, 1 );
break;
case 9:
case 10:
obj_from_char( dagger );
dam = 2 * ( dice( dagger->value[1], dagger->value[2] ));
if ( damage( ch, victim, dam, gsn_hurl, DAM_PIERCE, true ))
{
if ( get_eq_char( victim, WEAR_LODGED_RIB ) != NULL ) {
obj_to_room( dagger, ch->in_room );
act( "$p doesn't lodge into your rib.", ch, dagger, victim, TO_VICT );
act( "$p hurts $N but doesn't succesfully lodge.", ch, dagger, victim, TO_CHAR );
if ( IS_OBJ_STAT( dagger, OBJEXTRA_MELT_DROP ))
{
act( "$p dissolves into smoke.", ch, dagger, NULL, TO_ROOM );
extract_obj( dagger );
}
}
else
{
obj_to_char( dagger, victim );
SET_BIT( dagger->extra_flags, OBJEXTRA_LODGED );
dagger->wear_flags = OBJWEAR_TAKE | OBJWEAR_LODGED_RIB;
wear_obj( victim, dagger, true, false);
dagger->wear_flags = OBJWEAR_TAKE | OBJWEAR_WIELD;
}
}
else
{
obj_to_room( dagger, ch->in_room );
if ( IS_OBJ_STAT( dagger, OBJEXTRA_MELT_DROP ))
{
act( "$p dissolves into smoke.", ch, dagger, NULL, TO_ROOM );
extract_obj( dagger );
}
}
check_improve( ch, gsn_hurl, true, 1 );
break;
}
}
return;
}
/**************************************************************************/
void do_entangle( char_data *ch, char *)
{
char_data *victim;
OBJ_DATA *whip, *vObj;
int chance,hth,ch_weapon,vict_weapon,ch_vict_weapon;
hth = 0;
if ((chance = get_skill(ch,gsn_entangle)) == 0)
{
do_huh(ch,"");
return;
}
whip = get_eq_char( ch, WEAR_WIELD );
if ( !whip )
{
ch->println("You must be wielding a whip to entangle.");
return;
}
if ( whip->value[0] != WEAPON_WHIP )
{
ch->println("You must be wielding a whip to entangle.");
return;
}
if (( victim = ch->fighting ) == NULL )
{
ch->println("You aren't fighting anyone.");
return;
}
if (( vObj = get_eq_char( victim, WEAR_WIELD ) ) == NULL )
if (( vObj = get_eq_char( victim, WEAR_SECONDARY) ) == NULL )
{
ch->println("Your opponent is not wielding a weapon.");
return;
}
if(ch == victim)
{
ch->println("Yeah, right.");
return;
}
// find weapon skills
ch_weapon = get_weapon_skill(ch,get_weapon_sn(ch));
vict_weapon = get_weapon_skill(victim,get_weapon_sn(victim));
ch_vict_weapon = get_weapon_skill(ch,get_weapon_sn(victim));
// skill
chance = chance * ch_weapon/100;
chance += (ch_vict_weapon/2 - vict_weapon) / 2;
// quickness/agility vs. strength
chance += (ch->modifiers[STAT_QU] + ch->modifiers[STAT_AG])/2;
chance -= 2 * victim->modifiers[STAT_ST];
// level
chance += (ch->level - victim->level) * 2;
// and now the attack
if (number_percent() < chance)
{
WAIT_STATE( ch, skill_table[gsn_entangle].beats );
entangle( ch, victim );
check_improve(ch,gsn_entangle,true,1);
}
else
{
WAIT_STATE(ch,skill_table[gsn_entangle].beats);
act("You fail to grab their weapon.",ch,NULL,NULL,TO_CHAR);
act("$n tries to entangle your weapon, but fails.",ch,NULL,victim,TO_VICT);
act("$n tries to entangle $N's weapon, but fails.",ch,NULL,victim,TO_NOTVICT);
check_improve(ch,gsn_entangle,false,1);
}
return;
}
/**************************************************************************/
void do_dervish( char_data *ch, char * )
{
char_data *pChar;
char_data *pChar_next = NULL;
OBJ_DATA *spear;
bool found = false;
int chance;
if ( get_skill(ch,gsn_dervish) == 0 )
{
do_huh(ch,"");
return;
}
spear = get_eq_char( ch, WEAR_WIELD );
if ( !spear )
{
ch->println("You must be wielding a spear to perform this dance.");
return;
}
if ( spear->value[0] != WEAPON_SPEAR )
{
ch->println("You must be wielding a spear to perform this dance.");
return;
}
act( "$n holds $p firmly and begins to whirl about like a dervish...", ch, spear, NULL, TO_ROOM );
act( "You hold $p firmly and begin to whirl like a maddened dervish...", ch, spear, NULL, TO_CHAR );
for ( pChar = ch->in_room->people; pChar; pChar = pChar_next )
{
chance = get_skill( ch, gsn_dervish );
pChar_next = pChar->next_in_room;
if ( is_safe( ch, pChar ))
continue;
if ( IS_AFFECTED( ch, AFF_CHARM )
&& ch->master == pChar )
continue;
if ( IS_IMMORTAL( pChar )
&& INVIS_LEVEL(pChar)>= LEVEL_IMMORTAL )
continue;
if ( is_same_group( ch, pChar ))
{
if ( number_percent() < 75 )
continue;
}
if (number_percent() < chance)
{
act( "With a crazed look, $n turns towards YOU!", ch, NULL, pChar, TO_VICT );
one_hit( ch, pChar, gsn_dervish, false );
if ( pChar != ch )
found = true;
}
}
if ( !found )
{
ch->println("You feel dizzy, and a tiny bit embarassed.");
if (( number_percent() < 10 ) && !IS_IMMORTAL( ch ))
{
act( "$n drops $p.", ch, spear, NULL, TO_ROOM );
act( "You drop $p.", ch, spear, NULL, TO_CHAR );
obj_from_char( spear );
obj_to_room( spear, ch->in_room );
check_improve( ch, gsn_dervish, false, 1 );
}
}
else
check_improve( ch, gsn_dervish, true, 1 );
WAIT_STATE( ch, skill_table[gsn_dervish].beats );
ch->move = int( ch->move * 0.9 );
if ( number_percent() < 25 )
{
act( "$n loses $s balance and falls into a heap.", ch, NULL, NULL, TO_ROOM );
ch->println("You lose your balance and fall into a heap.");
ch->position = POS_RESTING;
}
return;
}
/**************************************************************************/
void do_cutoff( char_data *ch, char * )
{
if ( get_skill( ch, gsn_cutoff) == 0 ) {
do_huh(ch,"");
return;
}
if ( ch->position != POS_FIGHTING ) {
ch->println("You can only use this during combat.");
return;
}
if ( !IS_SET( ch->dyn, DYN_IS_CUTTING_OFF )) {
ch->println("You will now cut off fleeing or retreating enemies.");
SET_BIT( ch->dyn, DYN_IS_CUTTING_OFF );
} else {
ch->println("You will no longer cut off fleeing or retreating enemies.");
REMOVE_BIT( ch->dyn, DYN_IS_CUTTING_OFF );
}
return;
}
/**************************************************************************/
void do_sheathe( char_data *ch, char * )
{
OBJ_DATA *weapon = get_eq_char( ch, WEAR_WIELD );
if ( get_eq_char( ch, WEAR_SHEATHED ) != NULL )
{
ch->println("You already have a weapon sheathed, use draw to remove it.");
return;
}
if ( !weapon )
{
ch->println("You must be wielding a weapon in order to sheathe it.");
return;
}
if ( weapon->value[0] == WEAPON_EXOTIC
|| weapon->value[0] == WEAPON_STAFF
|| weapon->value[0] == WEAPON_SPEAR
|| weapon->value[0] == WEAPON_POLEARM )
{
ch->println("You cannot sheathe that weapon.");
return;
}
if ( IS_WEAPON_STAT(weapon,WEAPON_TWO_HANDS)) {
act ( "$p is too large to be sheathed properly.", ch, weapon, NULL, TO_CHAR );
return;
}
if ( !IS_IMMORTAL( ch) && IS_SET( weapon->extra_flags, OBJEXTRA_NOREMOVE) )
{
act( "You can't remove $p.", ch, weapon, NULL, TO_CHAR );
return;
}
unequip_char( ch, weapon );
weapon->wear_loc = WEAR_SHEATHED;
act( "With a flourish, you sheathe $p.", ch, weapon, NULL, TO_CHAR );
act( "With a flourish, $n sheathes $p.", ch, weapon, NULL, TO_ROOM );
return;
}
/**************************************************************************/
DECLARE_DO_FUN( do_stand );
/**************************************************************************/
void do_draw( char_data *ch, char * )
{
OBJ_DATA *weapon = get_eq_char( ch, WEAR_SHEATHED );
if ( !weapon )
{
ch->println("You don't have a weapon sheathed.");
return;
}
if ( get_eq_char( ch, WEAR_WIELD ) != NULL )
{
ch->println("You must have a free hand to draw a weapon.");
return;
}
if ( !IS_IMMORTAL(ch) && IS_SET( weapon->extra_flags, OBJEXTRA_NOREMOVE ))
{
act( "You can't remove $p.", ch, weapon, NULL, TO_CHAR );
return;
}
if ( ch->position < POS_STANDING )
{
do_stand(ch, "");
if(ch->position < POS_STANDING){
return;
}
}
equip_char( ch, weapon, WEAR_WIELD );
act( "You draw $p with unequaled grace.", ch, weapon, NULL, TO_CHAR );
act( "$n draws $p.", ch, weapon, NULL, TO_ROOM );
return;
}
/**************************************************************************/
void do_conceal( char_data *ch, char * )
{
OBJ_DATA *weapon = get_eq_char( ch, WEAR_WIELD );
if ( !IS_IMMORTAL( ch ))
{
if ( ch->specialization != SPECIALIZE_DAGGER )
{
do_huh(ch,"");
return;
}
}
if ( get_eq_char( ch, WEAR_CONCEALED ) != NULL )
{
ch->println("You may only have one weapon concealed.");
return;
}
if ( !weapon )
{
ch->println("You must be wielding your dagger in order to conceal it.");
return;
}
if ( weapon->value[0] != WEAPON_DAGGER )
{
ch->println("You can only conceal daggers.");
return;
}
if ( !IS_IMMORTAL(ch) && IS_SET( weapon->extra_flags, OBJEXTRA_NOREMOVE) )
{
act( "You can't remove $p.", ch, weapon, NULL, TO_CHAR );
return;
}
unequip_char( ch, weapon );
weapon->wear_loc = WEAR_CONCEALED;
act( "When no one is looking, you secretly conceal $p.", ch, weapon, NULL, TO_CHAR );
return;
}
/**************************************************************************/
// CELRION
void do_charge( char_data *ch, char *argument )
{
char arg[MIL], dir[MIL];
char_data *victim = NULL;
char_data *mount;
OBJ_DATA *polearm = NULL;
ROOM_INDEX_DATA *in_room;
ROOM_INDEX_DATA *to_room = NULL;
EXIT_DATA *pexit;
int door;
int chance;
int dam;
chance = get_skill( ch, gsn_charge );
if ( chance < 1)
{
do_huh(ch,"");
return;
}
if ( !IS_RIDING( ch ))
{
ch->println("You need to be mounted to charge.");
return;
}
mount = ch->mounted_on;
polearm = get_eq_char( ch, WEAR_WIELD );
if ( !polearm )
{
ch->println("You need to wield a polearm first.");
return;
}
if ( polearm->value[0] != WEAPON_POLEARM )
{
ch->println("You can only charge with polearms.");
return;
}
//Insert Specialization check (somewhere near here at least)
argument = one_argument ( argument, dir );
one_argument ( argument, arg );
if (arg[0] == '\0')
{
ch->println("Charge who or what?");
return;
}
door = dir_lookup( dir );
if ( door == -1 )
{
ch->printlnf("'%s' is an invalid direction.", dir);
ch->println("Syntax: charge <direction> <name>");
return;
}
in_room = ch->in_room;
if ( ( pexit = in_room->exit[door] ) == NULL
|| ( to_room = pexit->u1.to_room ) == NULL
|| !can_see_room(ch,pexit->u1.to_room))
{
ch->println("Alas, you cannot go that way.");
return;
}
if (IS_SET(pexit->exit_info, EX_CLOSED)
&& (!IS_AFFECTED(ch, AFF_PASS_DOOR) || IS_SET(pexit->exit_info,EX_NOPASS))
&& !IS_SET(TRUE_CH(ch)->act, PLR_HOLYWALK))
{
act( "The $d is closed.", ch, NULL, pexit->keyword, TO_CHAR );
return;
}
switch (door)
{
case 4:
act( "$n charges upward!", ch, NULL, NULL, TO_ROOM);
break;
case 5:
act( "$n charges down!", ch, NULL, NULL, TO_ROOM);
break;
default:
act( "$n charges to the $T!", ch, NULL, dir_name[door], TO_ROOM);
break;
}
act( "You charge $T!", ch, NULL, dir_name[door], TO_CHAR );
char_from_room(ch);
char_to_room(ch, to_room);
char_from_room(mount);
char_to_room(mount, to_room);
if ((victim = get_char_room(ch,arg)) == NULL)
{
ch->println("They aren't here.");
act( "$n charges into the room and looks around quizzically.", ch, NULL, NULL, TO_ROOM);
return;
}
if(ch == victim)
{
ch->println("Yeah, right.");
return;
}
if( is_safe (ch, victim) )
return;
if ( !can_initiate_combat( ch, victim, CIT_GENERAL )) return;
if ( IS_AFFECTED( ch, AFF_CHARM ) && ch->master == victim ) {
act("But $N is your friend!",ch,NULL,victim,TO_CHAR);
return;
}
//Stole chance mods from bash, I liked 'em.
chance += ch->modifiers[STAT_ST];
chance -= victim->modifiers[STAT_QU];
chance -= GET_AC(victim,AC_PIERCE) /25;
if (IS_SET(mount->off_flags,OFF_FAST) || IS_AFFECTED(mount,AFF_HASTE))
chance += 10;
if (IS_SET(victim->off_flags,OFF_FAST) || IS_AFFECTED(victim,AFF_HASTE))
chance -= 30;
chance += (((ch->level + mount->level)/2) - victim->level);
if (!IS_NPC(victim) && chance < get_skill(victim,gsn_dodge) )
chance -= 3 * (get_skill(victim,gsn_dodge) - chance);
//Move suckdown, also if tired then chance is slashed greatly.
if( mount->move < mount->max_move/2 ) chance /= 2;
if( !IS_NPC (ch) && ch->pcdata->tired > 16 ) chance /= 2;
//Actually hitting at this point.
if (number_percent() < chance )
{
act("$n charges into the room and hits you with $p!", ch,polearm, victim,TO_VICT);
act("You charge into the room and slam $N!",ch,NULL,victim,TO_CHAR);
act("$n charges into the room and slams right into $N!", ch,NULL,victim,TO_NOTVICT);
check_improve(ch,gsn_charge,true,1);
DAZE_STATE(victim, 3 * PULSE_VIOLENCE);
WAIT_STATE(ch,skill_table[gsn_charge].beats);
if( IS_RIDING (victim))
{
if ( number_range(1,3) > 1)
{
dismount(victim);
victim->position = POS_RESTING;
act("You have been dismounted!", ch, NULL, victim, TO_VICT );
act("$N has been dismounted!", ch, NULL, victim, TO_NOTVICT );
act("You have dismounted $N!", ch, NULL, victim, TO_CHAR );
}
}
dam = 3 * ( dice( polearm->value[1], polearm->value[2] ));
dam += 2 * ch->size + chance/10;
damage( ch, victim, dam, gsn_charge, DAM_PIERCE, true );
//Stole damage from bash but moreso.
}
else
{
damage(ch,victim,0,gsn_charge,DAM_BASH,false);
act("You charge into the room and miss $N completely!",
ch,NULL,victim,TO_CHAR);
act("$n charges at $N and completely misses!",
ch,NULL,victim,TO_NOTVICT);
act("$n charges right past you, in a vain attempt to hit you!",
ch,NULL,victim,TO_VICT);
check_improve(ch,gsn_charge,false,1);
WAIT_STATE(ch,skill_table[gsn_charge].beats * 3/2);
}
mount->move -= mount->move / 3;
}
/**************************************************************************/
void do_overhead( char_data *ch, char *argument )
{
char_data * victim;
OBJ_DATA * axe;
OBJ_DATA * helm;
char arg[MIL];
int chance, dam;
if ((chance = get_skill(ch,gsn_shieldcleave)) == 0)
{
do_huh(ch,"");
return;
}
one_argument( argument, arg );
axe = ( get_eq_char( ch, WEAR_WIELD ));
if ( !axe ) {
ch->println("You need to wield an axe to do an overhead swing.");
return;
}
if ( axe ) {
if ( axe->value[0] != WEAPON_AXE )
{
ch->println("You are not wielding an axe.");
return;
}
}
if (( victim = ch->fighting ) == NULL ) {
ch->println("You aren't fighting anyone.");
return;
}
if(ch == victim)
{
ch->println("Yeah, right.");
return;
}
helm = ( get_eq_char( victim, WEAR_HEAD ));
if ( IS_AFFECTED( ch, AFF_CHARM ) && ch->master == victim ) {
act("But $N is your friend!",ch,NULL,victim,TO_CHAR);
return;
}
if ( is_safe( ch, victim ))
return;
// INSERT WEAPON SPECIALIZATION CHECK HERE
dam = dice( axe->value[1], axe->value[2] );
if ( helm )
{
if ( get_skill( ch, gsn_overhead ) > number_percent() )
{
chance = 50;
if IS_WEAPON_STAT( axe, WEAPON_SHARP ) chance += 10;
if IS_WEAPON_STAT( axe, WEAPON_VORPAL ) chance += 20;
if IS_WEAPON_STAT( axe, WEAPON_FROST ) chance += 10;
if IS_WEAPON_STAT( axe, WEAPON_FLAMING ) chance += 5;
if IS_WEAPON_STAT( axe, WEAPON_SHOCKING ) chance += 5;
if IS_OBJ_STAT( helm, OBJEXTRA_BLESS ) chance -= 25;
if IS_OBJ_STAT( helm, OBJEXTRA_MAGIC ) chance -= 20;
if IS_OBJ_STAT( helm, OBJEXTRA_GLOW ) chance -= 5;
if IS_OBJ_STAT( helm, OBJEXTRA_CHAOS ) chance -= number_range(1,25);
if IS_OBJ_STAT( helm, OBJEXTRA_HUM ) chance -= 5;
if IS_OBJ_STAT( helm, OBJEXTRA_NONMETAL ) chance += 10;
if IS_OBJ_STAT( helm, OBJEXTRA_BURN_PROOF ) chance -= 35;
if ( number_range( 1, 100 ) < chance )
{
helm->condition -= axe->level;
if ( helm->condition <= 0 )
{
act( "Your axe `Bslices`x through $p, destroying it.", ch, helm, NULL, TO_CHAR );
act( "$n `Bslices`x $p.", ch, helm, NULL, TO_NOTVICT );
act( "$n has `Bdestroyed`x $p.", ch, helm, victim, TO_VICT );
extract_obj( helm );
dam *= 3/2;
}
else
{
act( "Your axe dents $p worn by your opponent.", ch, helm, NULL, TO_CHAR );
act( "$n dents your $p.", ch, helm, victim, TO_VICT );
dam *= 3/4;
}
}
else
{
act( "$N's helm remains unscathed!", ch, NULL, victim, TO_CHAR );
act( "$p resonates agains $N's swing, but holds firm.", ch, axe, victim, TO_VICT );
dam /= 2;
}
check_improve( ch, gsn_overhead, true, 1 );
WAIT_STATE( ch, skill_table[gsn_overhead].beats );
}
else
{
check_improve( ch, gsn_overhead, false, 1 );
act( "$N deftly evades your blow.", ch, NULL, victim, TO_CHAR );
act( "$n tries to split $N in two but misses.", ch, NULL, victim, TO_NOTVICT);
act( "$n tries to split you in two but misses.", ch, NULL, victim, TO_VICT );
WAIT_STATE( ch, skill_table[gsn_overhead].beats );
}
}
else
{
if ( get_skill( ch, gsn_overhead ) > number_percent())
{
dam *= 3/2;
check_improve( ch, gsn_overhead, true, 1 );
WAIT_STATE( ch, skill_table[gsn_overhead].beats );
}
else
{
dam *= 0;
check_improve( ch, gsn_overhead, false, 1 );
WAIT_STATE( ch, skill_table[gsn_overhead].beats * 3/2 );
act( "$N deftly evades your blow.", ch, NULL, victim, TO_CHAR );
act( "$n tries to split $N in two but misses.", ch, NULL, victim, TO_NOTVICT);
act( "$n tries to split you in two but misses.", ch, NULL, victim, TO_VICT );
}
}
if ( dam )
damage( ch, victim, dam, gsn_overhead, DAM_BASH, true );
else
damage( ch, victim, dam, gsn_overhead, DAM_BASH, false );
return;
}
/**************************************************************************/
void do_boneshatter( char_data *ch, char *argument )
{
char_data * victim;
OBJ_DATA * mace;
char arg[MIL];
int chance;
if ((chance = get_skill(ch,gsn_boneshatter)) == 0)
{
do_huh(ch,"");
return;
}
one_argument( argument, arg );
mace = ( get_eq_char( ch, WEAR_WIELD ));
if ( !mace ) {
ch->println("You need to wield a mace to shatter bones.");
return;
}
if ( mace ) {
if ( mace->value[0] != WEAPON_MACE ) {
ch->println("You are not wielding a mace.");
return;
}
}
if ( IS_NULLSTR( arg )) {
if (( victim = ch->fighting ) == NULL ) {
ch->println("But you aren't fighting anyone!");
return;
}
}
else if (( victim = get_char_room( ch, arg )) == NULL ) {
ch->printlnf("You can't seem to find '%s' here.", arg);
return;
}
if(ch == victim)
{
ch->println("Yeah, right.");
return;
}
if ( is_safe( ch, victim ))
return;
if ( IS_AFFECTED( ch, AFF_CHARM ) && ch->master == victim ) {
act("But $N is your friend!",ch,NULL,victim,TO_CHAR);
return;
}
// INSERT WEAPON SPECIALIZATION CHECK HERE
if ( get_skill( ch,gsn_boneshatter ) > ( number_percent() + 20 ))
{
act( "You smash $p against $N.", ch, mace, victim, TO_CHAR );
act( "$n smashes $p against $N!", ch, mace, victim, TO_NOTVICT );
act( "$n smashes $p against you!", ch, mace, victim, TO_VICT );
if ( damage( ch, victim, dice( mace->value[1], mace->value[2] ),
gsn_boneshatter, DAM_BASH, true ))
{
AFFECT_DATA af;
if ( !is_affected( victim, gsn_boneshatter )) {
af.where = WHERE_AFFECTS;
af.type = gsn_boneshatter;
af.level = ch->level;
af.duration = ch->level/10;
af.modifier = -10;
af.bitvector = 0;
af.location = APPLY_ST;
affect_to_char( victim, &af );
af.where = WHERE_AFFECTS;
af.modifier = -10;
af.bitvector = 0;
af.location = APPLY_AG;
affect_to_char( victim, &af );
act( "You hear the sickening sound of bones crunching.", ch, NULL, NULL, TO_CHAR );
act( "PAIN! The sickening sound of your bones crunching overwhelms you.", ch, NULL, victim, TO_VICT );
act( "$N looks like $e is in a world of pain.", ch, NULL, victim, TO_NOTVICT );
}
victim->position = POS_RESTING;
DAZE_STATE( victim, skill_table[gsn_boneshatter].beats*2/3 );
}
check_improve( ch, gsn_boneshatter, true, 1 );
WAIT_STATE( ch, skill_table[gsn_boneshatter].beats );
}
else
{
damage( ch, victim, 0, gsn_boneshatter, DAM_BASH, false );
check_improve( ch, gsn_boneshatter, false, 1 );
ch->println("You swing wildly and don't manage to connect the blow.");
WAIT_STATE( ch, skill_table[gsn_boneshatter].beats );
}
return;
}
/**************************************************************************/
void do_bury( char_data *ch, char *argument )
{
OBJ_DATA *obj;
OBJ_DATA *contents;
OBJ_DATA *shovel;
bool fshovel = false;
char arg[MIL];
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
ch->println("Bury what?");
return;
}
for ( shovel = ch->carrying; shovel; shovel = shovel->next_content )
{
if ( !str_cmp( shovel->pIndexData->material, "shovel" )
&& ( shovel->wear_loc == WEAR_HOLD
|| shovel->wear_loc == WEAR_WIELD )) {
fshovel = true;
break;
}
}
if ( !fshovel ) {
ch->println("You must be holding a shovel to dig with.");
return;
}
obj = get_obj_list( ch, arg, ch->in_room->contents );
if ( obj == NULL )
{
act( "I see not $T here.", ch, NULL, arg, TO_CHAR );
return;
}
if ( !IS_OUTSIDE( ch )
|| ch->in_room->sector_type == SECT_CITY
|| ch->in_room->sector_type == SECT_UNDERWATER
|| ch->in_room->sector_type == SECT_WATER_SWIM
|| ch->in_room->sector_type == SECT_WATER_NOSWIM
|| ch->in_room->sector_type == SECT_AIR ) {
ch->println("You can't bury anything here.");
return;
}
if ( obj->item_type == ITEM_FURNITURE // prevent stupid item burials
|| obj->item_type == ITEM_PORTAL
|| obj->item_type == ITEM_TOKEN
|| obj->item_type == ITEM_FOUNTAIN
|| obj->item_type == ITEM_BOAT )
{
ch->println("You can't bury that.");
return;
}
if ( !IS_NPC( ch ))
{
if ( !IS_IMMORTAL( ch ))
{
++ch->pcdata->tired;
WAIT_STATE( ch, 36 );
}
if ( obj->item_type == ITEM_CORPSE_PC
|| obj->item_type == ITEM_CORPSE_NPC )
{
act( "You dig a grave and place $p within.", ch, obj, NULL, TO_CHAR );
act( "$n digs a grave and places $p within.", ch, obj, NULL, TO_ROOM );
++ch->pcdata->tired; // graves are tiresome :)
}
else
{
act( "You dig a hole and place $p within.", ch, obj, NULL, TO_CHAR );
act( "$n digs a hole and places $p within.", ch, obj, NULL, TO_ROOM );
}
}
// Set corpse and all it's potential items as buried
SET_BIT( obj->extra2_flags, OBJEXTRA2_BURIED );
// Only set PC_CORPSE items as buried since NPC_CORPSE items poof when the corpse does
// Container contents dont need to be flagged as buried
if ( obj->item_type == ITEM_CORPSE_PC )
{
for ( contents = obj->contains; contents; contents = contents->next_content )
{
SET_BIT( contents->extra2_flags, OBJEXTRA2_BURIED );
}
}
return;
}
/**************************************************************************/
void do_dig( char_data *ch, char * )
{
OBJ_DATA *obj;
OBJ_DATA *pcCorpse;
OBJ_DATA *shovel;
bool found = false;
bool fshovel = false;
for ( shovel = ch->carrying; shovel; shovel = shovel->next_content )
{
if ( !str_cmp( shovel->pIndexData->material, "shovel" )
&& ( shovel->wear_loc == WEAR_HOLD
|| shovel->wear_loc == WEAR_WIELD )) {
fshovel = true;
break;
}
}
if ( !fshovel )
{
ch->println("You must be holding a shovel to dig with.");
return;
}
if ( !IS_OUTSIDE( ch )
|| ch->in_room->sector_type == SECT_CITY
|| ch->in_room->sector_type == SECT_UNDERWATER
|| ch->in_room->sector_type == SECT_WATER_SWIM
|| ch->in_room->sector_type == SECT_WATER_NOSWIM
|| ch->in_room->sector_type == SECT_AIR )
{
ch->println("You can't dig here.");
return;
}
for ( obj = ch->in_room->contents; obj; obj = obj->next_content )
{
if ( IS_SET( obj->extra2_flags, OBJEXTRA2_BURIED ))
{
REMOVE_BIT( obj->extra2_flags, OBJEXTRA2_BURIED );
found = true;
if ( obj->item_type == ITEM_CORPSE_PC )
{
for ( pcCorpse = obj->contains; pcCorpse; pcCorpse = pcCorpse->next_content )
{
REMOVE_BIT( pcCorpse->extra2_flags, OBJEXTRA2_BURIED );
}
}
}
}
if ( !IS_NPC( ch )) {
if ( !IS_IMMORTAL( ch )) {
++ch->pcdata->tired;
WAIT_STATE( ch, 36 );
}
act( "You begin to dig.", ch, NULL, NULL, TO_CHAR );
act( "$n begins to dig.", ch, NULL, NULL, TO_ROOM );
}
if ( found ) {
act( "You have unearthed something.", ch, NULL, NULL, TO_CHAR );
act( "$n has unearthed something.", ch, NULL, NULL, TO_ROOM );
}
}
/**************************************************************************/
void do_shadow( char_data *ch, char *argument )
{
char arg[MIL];
char_data *victim;
int chance = get_skill( ch, gsn_shadow );
one_argument( argument, arg );
if ( chance < 1 )
{
ch->println("Your attempts at shadowing someone would be useless.");
return;
}
if ( arg[0] == '\0' )
{
ch->println("Who do you want to shadow?");
return;
}
if (( victim = get_char_room( ch, arg )) == NULL )
{
ch->println("They aren't here.");
return;
}
if ( IS_AFFECTED(ch, AFF_CHARM) && ch->master != NULL )
{
ch->println("You're too busy following someone else.");
return;
}
if ( victim == ch )
{
if ( ch->master == NULL )
{
ch->println("You stalk yourself like a fool.");
return;
}
SET_BIT( ch->dyn, DYN_SILENTLY );
stop_follower(ch);
REMOVE_BIT( ch->dyn, DYN_SILENTLY );
return;
}
if (IS_IMMORTAL(victim))
{
ch->println("Ok.");
return;
}
if ( ch->master != NULL )
{
SET_BIT( ch->dyn, DYN_SILENTLY );
stop_follower( ch );
REMOVE_BIT( ch->dyn, DYN_SILENTLY );
}
SET_BIT( ch->dyn, DYN_SILENTLY );
add_follower( ch, victim );
REMOVE_BIT( ch->dyn, DYN_SILENTLY );
ch->println("Ok.");
if ( chance > number_percent() )
{
check_improve( ch, gsn_shadow, true, 2 );
}
else
{
check_improve( ch, gsn_shadow, false, 4 );
victim->println("You have a feeling someone is following you.");
}
return;
}
/**************************************************************************/
void do_cannibalize( char_data *ch, char * )
{
int chance = get_skill( ch, gsn_cannibalize );
int gain = UMIN( 50, ch->level * 5 );
if ( chance < 1 )
{
do_huh( ch, "" );
return;
}
if (ch->fighting != NULL)
{
ch->println("You cannot do this while fighting.");
return;
}
gain += UMAX( -25, chance - 75 );
if ( (ch->hit) <= gain )
{
ch->println("You would surely die if you tried this now.");
return;
}
ch->println("You draw magical power from your life force.");
act( "$n is enveloped in a cold blue aura.", ch, NULL, NULL, TO_ROOM );
ch->hit -= gain;
ch->mana += gain;
WAIT_STATE( ch, 18 );
check_improve( ch, gsn_cannibalize, true, 1 );
return;
}
/**************************************************************************/
void do_fork( char_data *ch, char *argument )
{
int mana, roll;
REMOVE_BIT( ch->dyn, DYN_SUCCESS_CAST );
do_cast(ch,argument);
roll = number_percent();
if ( IS_SET( ch->dyn, DYN_SUCCESS_CAST ) && roll < get_skill(ch,gsn_fork) / 4 )
{
ch->println("You successfully forked the spell!");
mana = ch->mana;
do_cast( ch, argument );
ch->mana = mana - (roll / 6);
check_improve(ch,gsn_fork,true,1);
}
return;
}
/**************************************************************************/
void do_flourish( char_data *ch, char *argument )
{
OBJ_DATA * obj = get_eq_char( ch, WEAR_WIELD );
if ( !obj ){
ch->println( "You are not wielding a druidic staff." );
return;
}
if(obj->pIndexData->vnum==OBJ_VNUM_DRUIDSTAFF){
ch->println( "Your druidstaff has no additional powers." );
}else if (obj->pIndexData->vnum==OBJ_VNUM_TOTEMSTAFF){
if ( !str_cmp( argument, "totemguardian" )){
flourish_totemstaff_guardian( ch, obj );
}
if ( !str_cmp( argument, "totemspirit" )){
flourish_totemstaff_spirit( ch, obj );
}
}
return;
}
/**************************************************************************/
void flourish_totemstaff_guardian( char_data *ch, OBJ_DATA *obj )
{
MOB_INDEX_DATA *pMob;
char_data *totem;
int vnum;
int month = get_birthmonth( ch );
int foo, i; // reusable piece of junk generic var
if ( month < 0 )
{
ch->println( "You have not chosen your age yet. Type help setage to see how this is done." );
return;
}
vnum = MOB_VNUM_TOTEM_BEAR + month; // Bear = 60 and is used as an offset
if (( pMob = get_mob_index( vnum )) == NULL )
{
ch->printf( "Vnum %d not found for your totem mob, please report to the admin.", vnum );
return;
}
// Make the mob
totem = create_mobile( pMob, UMIN( ch->level, 99));
totem->level = UMIN( ch->level, 99);
// determine it's hitpoints
foo = dice( mob_balance_lookup( totem->level, 0 ),
mob_balance_lookup( totem->level, 1 ));
totem->max_hit = foo + mob_balance_lookup( totem->level, 2 );
totem->hit = totem->max_hit;
// determine it's AC
foo = mob_balance_lookup( totem->level, MOB_BALANCE_AC );
for ( i = 0; i < 4; i++ )
totem->armor[i] = foo;
// determine it's damage
totem->damage[DICE_NUMBER] = mob_balance_lookup( totem->level, MOB_BALANCE_NUM_DAM_DIE );
totem->damage[DICE_TYPE] = mob_balance_lookup( totem->level, MOB_BALANCE_DAM_DIE_TYPE );
totem->damage[DICE_BONUS] = mob_balance_lookup( totem->level, MOB_BALANCE_DAM_BONUS );
// set it to follow the druid
add_follower( totem, ch );
totem->leader = ch;
ch->println( "You flourish your druidstaff which pulsates with a greenish glow and vanishes from your hands." );
act( "$n flourishes $s druidstaff which pulsates in a greenish glow.", ch, obj, NULL, TO_ROOM );
char_to_room( totem, ch->in_room); // send mob to summoner
act( "$n has suddenly arrived.", totem, NULL, NULL, TO_ROOM );
act("$N looks at you with adoring eyes.", ch, NULL, totem, TO_CHAR );
SET_BIT( totem->affected_by, AFF_CHARM );
extract_obj( obj ); // nuke the staff
return;
}
/**************************************************************************/
void flourish_totemstaff_spirit( char_data *ch, OBJ_DATA *)
{
ch->println("flourish_totemstaff_spirit(): not yet implemented.");
}
/**************************************************************************/
void do_herblore( char_data *ch, char *argument )
{
char arg[MIL];
OBJ_DATA *herb;
HERB_DATA *h;
int chance = get_skill( ch, gsn_herblore);
int skillroll;
if ( IS_OOC( ch ))
{
ch->println( "Not in an OOC room." );
return;
}
if ( chance == 0 )
{
ch->println( "You know nothing about herbs." );
return;
}
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
ch->println( "Learn about which herb?" );
return;
}
herb = get_obj_list( ch, argument, ch->carrying );
if ( herb == NULL )
{
ch->println( "You don't have that herb." );
return;
}
if ( herb->item_type != ITEM_HERB )
{
ch->println( "That is not an herb." );
return;
}
h = find_herb( ch, arg );
if ( !h )
{
ch->println( "You couldn't learn anything from that particular herb." );
return;
}
skillroll = number_range( 1, 100 );
if ( skillroll > ( chance - h->difficulty ))
{
ch->println( "You couldn't learn anything useful." );
check_improve( ch, gsn_herblore, false, 2 );
return;
}
switch (number_range( 1, 5 ))
{
case (1):
ch->printlnf( "%s only grows %s.",
h->name,
sector_desc[h->sector].name );
break;
case (2):
if ( !h->continent) {
ch->printlnf( "%s is prolific, and can be found in any continent of %s.",
h->name, capitalize(game_settings->realm_name));
}else{
ch->printlnf( "%s is indigenous to %s.",
h->name,
h->continent->name );
}
break;
case (3):
if ( h->month == -1 )
{
ch->printlnf( "%s is a perennial plant.",
h->name );
}
else
{
ch->printlnf( "%s only grows in the month of %s.",
h->name,
month_name[h->month] );
}
break;
case (4):
if ( h->season == -1 )
{
ch->printlnf( "%s is a perennial plant.",
h->name );
}
else
{
ch->printlnf( "%s only grows during the season of %s.",
h->name,
season_table[h->season].name );
}
break;
case (5):
if ( timefield_table[h->timefield].lowhour == -1 )
{
ch->printlnf( "%s may be harvested successfully at any time of the day or night.",
h->name );
}
else
{
ch->printlnf( "%s can only be successfully harvested %s.",
h->name,
timefield_table[h->timefield].name );
}
break;
}
act( "$n studies $p.", ch, herb, NULL, TO_ROOM );
WAIT_STATE( ch, skill_table[gsn_herblore].beats );
check_improve( ch, gsn_herblore, true, 5 );
return;
}
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/