/*
* Projectile code taken from SMAUG 1.4
*/
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include "mud.h"
char *rev_exit( sh_int vdir );
char *myobj( OBJ_DATA *obj );
/*
* Basically the same guts as do_scan() from above (please keep them in
* sync) used to find the victim we're firing at. -Thoric
*/
CHAR_DATA *scan_for_victim( CHAR_DATA *ch, EXIT_DATA *pexit, char *name )
{
CHAR_DATA *victim;
ROOM_INDEX_DATA *was_in_room;
sh_int dist, dir;
sh_int max_dist = 10;
if ( IS_AFFECTED(ch, AFF_BLIND) || !pexit )
return NULL;
was_in_room = ch->in_room;
if ( IS_VAMPIRE(ch) && time_info.hour < 21 && time_info.hour > 5 )
max_dist = 1;
if ( ch->level < 50 ) --max_dist;
if ( ch->level < 40 ) --max_dist;
if ( ch->level < 30 ) --max_dist;
for ( dist = 1; dist <= max_dist; )
{
if ( IS_SET(pexit->exit_info, EX_CLOSED) )
break;
if ( room_is_private( pexit->to_room )
&& ch->level < LEVEL_GOD )
break;
char_from_room( ch );
char_to_room( ch, pexit->to_room );
if ( (victim=get_char_room(ch, name)) != NULL )
{
char_from_room(ch);
char_to_room(ch, was_in_room);
return victim;
}
switch( ch->in_room->sector_type )
{
default: dist++; break;
case SECT_AIR:
if ( number_percent() < 80 ) dist++; break;
case SECT_INSIDE:
case SECT_FIELD:
case SECT_UNDERGROUND:
dist++; break;
case SECT_FOREST:
case SECT_CITY:
case SECT_DESERT:
case SECT_HILLS:
dist += 2; break;
case SECT_WATER_SWIM:
case SECT_WATER_NOSWIM:
dist += 3; break;
case SECT_MOUNTAIN:
case SECT_UNDERWATER:
case SECT_OCEANFLOOR:
dist += 4; break;
}
if ( dist >= max_dist )
break;
dir = pexit->vdir;
if ( (pexit=get_exit(ch->in_room, dir)) == NULL )
break;
}
char_from_room(ch);
char_to_room(ch, was_in_room);
return NULL;
}
/*
* Search inventory for an appropriate projectile to fire.
* Also search open quivers. -Thoric
*/
OBJ_DATA *find_projectile( CHAR_DATA *ch, int type )
{
OBJ_DATA *obj, *obj2;
for ( obj = ch->last_carrying; obj; obj = obj->prev_content )
{
if ( can_see_obj(ch, obj) )
{
if ( obj->item_type == ITEM_QUIVER && !IS_SET(obj->value[1], CONT_CLOSED) )
{
for ( obj2 = obj->last_content; obj2; obj2 = obj2->prev_content )
{
if ( obj2->item_type == ITEM_PROJECTILE
&& obj2->value[3] == type )
return obj2;
}
}
if ( obj->item_type == ITEM_PROJECTILE && obj->value[3] == type )
return obj;
}
}
return NULL;
}
ch_ret spell_attack( int, int, CHAR_DATA *, void * );
/*
* Perform the actual attack on a victim -Thoric
*/
ch_ret ranged_got_target( CHAR_DATA *ch, CHAR_DATA *victim, OBJ_DATA *weapon,
OBJ_DATA *projectile, sh_int dist, sh_int dt, char *stxt, sh_int color )
{
if ( IS_SET(ch->in_room->room_flags, ROOM_SAFE) )
{
/* safe room, bubye projectile */
if ( projectile )
{
ch_printf(ch, "Your %s is blasted from existance by a godly presense.",
myobj(projectile) );
act( color, "A godly presence smites $p!", ch, projectile, NULL, TO_ROOM );
extract_obj(projectile);
}
else
{
ch_printf(ch, "Your %s is blasted from existance by a godly presense.",
stxt );
act( color, "A godly presence smites $t!", ch, aoran(stxt), NULL, TO_ROOM );
}
return rNONE;
}
if ( IS_NPC(victim) && IS_SET(victim->act, ACT_SENTINEL)
&& ch->in_room != victim->in_room )
{
/*
* letsee, if they're high enough.. attack back with fireballs
* long distance or maybe some minions... go herne! heh..
*
* For now, just always miss if not in same room -Thoric
*/
if ( projectile )
{
learn_from_failure( ch, gsn_missile_weapons );
/* 50% chance of projectile getting lost */
if ( number_percent() < 25 )
extract_obj(projectile);
else
{
if ( projectile->in_obj )
obj_from_obj(projectile);
if ( projectile->carried_by )
obj_from_char(projectile);
obj_to_room(projectile, victim->in_room);
}
}
return damage( ch, victim, 0, dt );
}
if ( number_percent() > 30 || (projectile && weapon) )
{
if ( projectile )
global_retcode = projectile_hit(ch, victim, weapon, projectile, dist );
else
global_retcode = spell_attack( dt, ch->level, ch, victim );
}
else
{
learn_from_failure( ch, gsn_missile_weapons );
global_retcode = damage( ch, victim, 0, dt );
if ( projectile )
{
/* 50% chance of getting lost */
if ( number_percent() < 50 )
extract_obj(projectile);
else
{
if ( projectile->in_obj )
obj_from_obj(projectile);
if ( projectile->carried_by )
obj_from_char(projectile);
obj_to_room(projectile, victim->in_room);
}
}
}
return global_retcode;
}
/*
* Generic use ranged attack function -Thoric & Tricops
*/
ch_ret ranged_attack( CHAR_DATA *ch, char *argument, OBJ_DATA *weapon,
OBJ_DATA *projectile, sh_int dt, sh_int range )
{
CHAR_DATA *victim, *vch;
EXIT_DATA *pexit;
ROOM_INDEX_DATA *was_in_room;
char arg[MAX_INPUT_LENGTH];
char arg1[MAX_INPUT_LENGTH];
char temp[MAX_INPUT_LENGTH];
char buf[MAX_STRING_LENGTH];
SKILLTYPE *skill = NULL;
sh_int dir = -1, dist = 0, color = AT_GREY;
char *dtxt = "somewhere";
char *stxt = "burst of energy";
int count;
if ( argument && argument[0] != '\0' && argument[0] == '\''){
one_argument( argument, temp );
argument = temp;
}
argument = one_argument(argument, arg);
argument = one_argument(argument, arg1);
if ( arg[0] == '\0' )
{
send_to_char( "Where? At who?\n\r", ch );
return rNONE;
}
victim = NULL;
/* get an exit or a victim */
if ( (pexit = find_door(ch, arg, TRUE)) == NULL )
{
if ( (victim=get_char_room(ch, arg)) == NULL )
{
send_to_char( "Aim in what direction?\n\r", ch );
return rNONE;
}
else
{
if ( who_fighting(ch) == victim )
{
send_to_char( "They are too close to release that type of attack!\n\r", ch );
return rNONE;
}
if ( !IS_NPC(ch) && !IS_NPC(victim) )
{
send_to_char("Pkill like a real pkiller.\n\r", ch );
return rNONE;
}
}
}
else
dir = pexit->vdir;
/* check for ranged attacks from private rooms, etc */
if ( !victim )
{
if ( IS_SET(ch->in_room->room_flags, ROOM_PRIVATE)
|| IS_SET(ch->in_room->room_flags, ROOM_SOLITARY) )
{
send_to_char( "You cannot perform a ranged attack from a private room.\n\r", ch );
return rNONE;
}
if ( ch->in_room->tunnel > 0 )
{
count = 0;
for ( vch = ch->in_room->first_person; vch; vch = vch->next_in_room )
++count;
if ( count >= ch->in_room->tunnel )
{
send_to_char( "This room is too cramped to perform such an attack.\n\r", ch );
return rNONE;
}
}
}
if ( IS_VALID_SN(dt) )
skill = skill_table[dt];
if ( pexit && !pexit->to_room )
{
send_to_char( "Are you expecting to fire through a wall!?\n\r", ch );
return rNONE;
}
/* Check for obstruction */
if ( pexit && IS_SET(pexit->exit_info, EX_CLOSED) )
{
if ( IS_SET(pexit->exit_info, EX_SECRET)
|| IS_SET(pexit->exit_info, EX_DIG) )
send_to_char( "Are you expecting to fire through a wall!?\n\r", ch );
else
send_to_char( "Are you expecting to fire through a door!?\n\r", ch );
return rNONE;
}
vch = NULL;
if ( pexit && arg1[0] != '\0' )
{
if ( (vch=scan_for_victim(ch, pexit, arg1)) == NULL )
{
send_to_char( "You cannot see your target.\n\r", ch );
return rNONE;
}
/* don't allow attacks on mobs stuck in another area?
if ( IS_NPC(vch) && xIS_SET(vch->act, ACT_STAY_AREA)
&& ch->in_room->area != vch->in_room->area) )
{
}
*/
/*don't allow attacks on mobs that are in a no-missile room --Shaddai */
/* if ( IS_SET(vch->in_room->room_flags, ROOM_NOMISSILE) )
{
send_to_char( "You can't get a clean shot off.\n\r", ch );
return rNONE;
}*/
if ( !IS_NPC(ch) && !IS_NPC(vch) )
{
send_to_char("Pkill like a real pkiller.\n\r", ch );
return rNONE;
}
/* can't properly target someone heavily in battle */
if ( vch->num_fighting > max_fight(vch) )
{
send_to_char( "There is too much activity there for you to get a clear shot.\n\r", ch );
return rNONE;
}
}
if ( vch ) {
if ( !IS_NPC( vch ) && !IS_NPC( ch ) &&
IS_SET(ch->act, PLR_NICE ) )
{
send_to_char( "Your too nice to do that!\n\r", ch );
return rNONE;
}
if ( vch && is_safe(ch, vch) )
return rNONE;
}
was_in_room = ch->in_room;
if ( projectile )
{
separate_obj(projectile);
if ( pexit )
{
if ( weapon )
{
act( AT_GREY, "You fire $p $T.", ch, projectile, dir_name[dir], TO_CHAR );
act( AT_GREY, "$n fires $p $T.", ch, projectile, dir_name[dir], TO_ROOM );
}
else
{
act( AT_GREY, "You throw $p $T.", ch, projectile, dir_name[dir], TO_CHAR );
act( AT_GREY, "$n throw $p $T.", ch, projectile, dir_name[dir], TO_ROOM );
}
}
else
{
if ( weapon )
{
act( AT_GREY, "You fire $p at $N.", ch, projectile, victim, TO_CHAR );
act( AT_GREY, "$n fires $p at $N.", ch, projectile, victim, TO_NOTVICT );
act( AT_GREY, "$n fires $p at you!", ch, projectile, victim, TO_VICT );
}
else
{
act( AT_GREY, "You throw $p at $N.", ch, projectile, victim, TO_CHAR );
act( AT_GREY, "$n throws $p at $N.", ch, projectile, victim, TO_NOTVICT );
act( AT_GREY, "$n throws $p at you!", ch, projectile, victim, TO_VICT );
}
}
}
else
if ( skill )
{
if ( skill->noun_damage && skill->noun_damage[0] != '\0' )
stxt = skill->noun_damage;
else
stxt = skill->name;
/* a plain "spell" flying around seems boring */
if ( !str_cmp(stxt, "spell") )
stxt = "magical burst of energy";
if ( skill->type == SKILL_SPELL )
{
color = AT_MAGIC;
if ( pexit )
{
act( AT_MAGIC, "You release $t $T.", ch, aoran(stxt), dir_name[dir], TO_CHAR );
act( AT_MAGIC, "$n releases $s $t $T.", ch, stxt, dir_name[dir], TO_ROOM );
}
else
{
act( AT_MAGIC, "You release $t at $N.", ch, aoran(stxt), victim, TO_CHAR );
act( AT_MAGIC, "$n releases $s $t at $N.", ch, stxt, victim, TO_NOTVICT );
act( AT_MAGIC, "$n releases $s $t at you!", ch, stxt, victim, TO_VICT );
}
}
}
else
{
bug( "Ranged_attack: no projectile, no skill dt %d", dt );
return rNONE;
}
/* victim in same room */
if ( victim )
{
// check_illegal_pk( ch, victim );
// check_attacker( ch, victim );
if ( !check_pk_ok(victim,ch) )
return rNONE;
return ranged_got_target( ch, victim, weapon, projectile,
0, dt, stxt, color );
}
/* assign scanned victim */
victim = vch;
/* reverse direction text from move_char */
dtxt = rev_exit(pexit->vdir);
while ( dist <= range )
{
char_from_room(ch);
char_to_room(ch, pexit->to_room);
if ( IS_SET(pexit->exit_info, EX_CLOSED) )
{
/* whadoyahknow, the door's closed */
if ( projectile )
sprintf(buf,"You see your %s pierce a door in the distance to the %s.",
myobj(projectile), dir_name[dir] );
else
sprintf(buf, "You see your %s hit a door in the distance to the %s.",
stxt, dir_name[dir] );
act( color, buf, ch, NULL, NULL, TO_CHAR );
if ( projectile )
{
sprintf(buf,"$p flies in from %s and implants itself solidly in the %sern door.",
dtxt, dir_name[dir] );
act( color, buf, ch, projectile, NULL, TO_ROOM );
}
else
{
sprintf(buf, "%s flies in from %s and implants itself solidly in the %sern door.",
aoran(stxt), dtxt, dir_name[dir] );
buf[0] = UPPER(buf[0]);
act( color, buf, ch, NULL, NULL, TO_ROOM );
}
break;
}
/* no victim? pick a random one */
if ( !victim )
{
for ( vch = ch->in_room->first_person; vch; vch = vch->next_in_room )
{
if ( ((IS_NPC(ch) && !IS_NPC(vch))
|| (!IS_NPC(ch) && IS_NPC(vch)))
&& number_bits(1) == 0 )
{
victim = vch;
break;
}
}
if ( victim && is_safe(ch, victim) )
{
char_from_room(ch);
char_to_room(ch, was_in_room);
return rNONE;
}
}
/* In the same room as our victim? */
if ( victim && ch->in_room == victim->in_room )
{
if ( projectile )
act( color, "$p flies in from $T.", ch, projectile, dtxt, TO_ROOM );
else
act( color, "$t flies in from $T.", ch, aoran(stxt), dtxt, TO_ROOM );
/* get back before the action starts */
char_from_room(ch);
char_to_room(ch, was_in_room);
// check_illegal_pk( ch, victim );
// check_attacker( ch, victim );
if ( !check_pk_ok(victim,ch) )
return rNONE;
return ranged_got_target( ch, victim, weapon, projectile,
dist, dt, stxt, color );
}
if ( dist == range )
{
if ( projectile )
{
act( color, "Your $t falls harmlessly to the ground to the $T.",
ch, myobj(projectile), dir_name[dir], TO_CHAR );
act( color, "$p flies in from $T and falls harmlessly to the ground here.",
ch, projectile, dtxt, TO_ROOM );
if ( projectile->in_obj )
obj_from_obj(projectile);
if ( projectile->carried_by )
obj_from_char(projectile);
obj_to_room(projectile, ch->in_room);
}
else
{
act( color, "Your $t fizzles out harmlessly to the $T.", ch, stxt, dir_name[dir], TO_CHAR );
act( color, "$t flies in from $T and fizzles out harmlessly.",
ch, aoran(stxt), dtxt, TO_ROOM );
}
break;
}
if ( ( pexit = get_exit( ch->in_room, dir ) ) == NULL )
{
if ( projectile )
{
act( color, "Your $t hits a wall and bounces harmlessly to the ground to the $T.",
ch, myobj(projectile), dir_name[dir], TO_CHAR );
act( color, "$p strikes the $Tsern wall and falls harmlessly to the ground.",
ch, projectile, dir_name[dir], TO_ROOM );
if ( projectile->in_obj )
obj_from_obj(projectile);
if ( projectile->carried_by )
obj_from_char(projectile);
obj_to_room(projectile, ch->in_room);
}
else
{
act( color, "Your $t harmlessly hits a wall to the $T.",
ch, stxt, dir_name[dir], TO_CHAR );
act( color, "$t strikes the $Tsern wall and falls harmlessly to the ground.",
ch, aoran(stxt), dir_name[dir], TO_ROOM );
}
break;
}
if ( projectile )
act( color, "$p flies in from $T.", ch, projectile, dtxt, TO_ROOM );
else
act( color, "$t flies in from $T.", ch, aoran(stxt), dtxt, TO_ROOM );
dist++;
}
char_from_room( ch );
char_to_room( ch, was_in_room );
return rNONE;
}
/*
* Fire <direction> <target>
*
* Fire a projectile from a missile weapon (bow, crossbow, etc)
*
* Design by Thoric, coding by Thoric and Tricops.
*
* Support code (see projectile_hit(), quiver support, other changes to
* fight.c, etc by Thoric.
*/
void do_fire( CHAR_DATA *ch, char *argument )
{
OBJ_DATA *arrow;
OBJ_DATA *bow;
sh_int max_dist;
if ( argument[0] == '\0' || !str_cmp(argument, " ") )
{
send_to_char( "Fire where at who?\n\r", ch );
return;
}
if ( IS_SET( ch->in_room->room_flags, ROOM_SAFE ) )
{
set_char_color( AT_MAGIC, ch );
send_to_char( "A magical force prevents you from attacking.\n\r", ch );
return;
}
/*
* Find the projectile weapon
*/
if ( (bow=get_eq_char(ch, WEAR_MISSILE_WIELD)) != NULL )
if ( !(bow->item_type == ITEM_MISSILE_WEAPON) )
bow = NULL;
if ( !bow )
{
send_to_char( "You are not wielding a missile weapon.\n\r", ch );
return;
}
/* modify maximum distance based on bow-type and ch's class/str/etc */
max_dist = URANGE( 1, bow->value[4], 10 );
if ( (arrow=find_projectile(ch, bow->value[3])) == NULL )
{
char *msg = "You have nothing to fire...\n\r";
switch( bow->value[3] )
{
case DAM_BOLT: msg = "You have no bolts...\n\r"; break;
case DAM_ARROW: msg = "You have no arrows...\n\r"; break;
case DAM_DART: msg = "You have no darts...\n\r"; break;
case DAM_STONE: msg = "You have no slingstones...\n\r"; break;
case DAM_PEA: msg = "You have no peas...\n\r"; break;
}
send_to_char( msg, ch );
return;
}
/* handle the ranged attack */
ranged_attack( ch, argument, bow, arrow, TYPE_HIT + arrow->value[3], max_dist );
return;
}
/*
* Attempt to fire at a victim.
* Returns FALSE if no attempt was made
*/
bool mob_fire( CHAR_DATA *ch, char *name )
{
OBJ_DATA *arrow;
OBJ_DATA *bow;
sh_int max_dist;
if ( IS_SET( ch->in_room->room_flags, ROOM_SAFE ) )
return FALSE;
if ( (bow=get_eq_char(ch, WEAR_MISSILE_WIELD)) != NULL )
if ( !(bow->item_type == ITEM_MISSILE_WEAPON) )
bow = NULL;
if ( !bow )
return FALSE;
/* modify maximum distance based on bow-type and ch's class/str/etc */
max_dist = URANGE( 1, bow->value[4], 10 );
if ( (arrow=find_projectile(ch, bow->value[3])) == NULL )
return FALSE;
ranged_attack( ch, name, bow, arrow, TYPE_HIT + arrow->value[3], max_dist );
return TRUE;
}
/*------------------------------------------------------------
* Fighting Styles - haus
*/
/*
void do_style( CHAR_DATA *ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
char buf[MAX_INPUT_LENGTH];
int percent;
if ( IS_NPC(ch) )
return;
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
ch_printf_color( ch, "&wAdopt which fighting style? (current: %s&w)\n\r",
ch->style == STYLE_BERSERK ? "&Rberserk" :
ch->style == STYLE_AGGRESSIVE ? "&Raggressive" :
ch->style == STYLE_DEFENSIVE ? "&Ydefensive" :
ch->style == STYLE_EVASIVE ? "&Yevasive" :
"standard" );
return;
}
if( !str_prefix(arg, "evasive") ){
if( ch->level < skill_table[gsn_style_evasive]->skill_level[ch->class])
{
send_to_char( "You have not yet learned enough to fight evasively.\n\r",ch);
return;
}
WAIT_STATE( ch, skill_table[gsn_style_evasive]->beats );
if( number_percent() < LEARNED(ch, gsn_style_evasive) ){
success
if(ch->fighting){
ch->position = POS_EVASIVE;
learn_from_success(ch,gsn_style_evasive);
if ( IS_PKILL( ch ) )
act( AT_ACTION, "$n falls back into an evasive stance.",
ch, NULL, NULL, TO_ROOM );
}
ch->style = STYLE_EVASIVE;
send_to_char( "You adopt an evasive fighting style.\n\r",ch);
return;
} else {
failure
send_to_char( "You nearly trip in a lame attempt to adopt an evasive fighting style.\n\r",ch);
return;
}
} else if( !str_prefix(arg, "defensive")){
if( ch->level < skill_table[gsn_style_defensive]->skill_level[ch->class])
{
send_to_char( "You have not yet learned enough to fight defensively.\n\r",ch);
return;
}
WAIT_STATE( ch, skill_table[gsn_style_defensive]->beats );
if( number_percent() < LEARNED(ch, gsn_style_defensive) ){
success
if(ch->fighting) {
ch->position = POS_DEFENSIVE;
learn_from_success(ch,gsn_style_defensive);
if ( IS_PKILL( ch ) )
act( AT_ACTION, "$n moves into a defensive posture.",
ch, NULL, NULL, TO_ROOM );
}
ch->style = STYLE_DEFENSIVE;
send_to_char( "You adopt a defensive fighting style.\n\r",ch);
return;
} else {
failure
send_to_char( "You nearly trip in a lame attempt to adopt a defensive fighting style.\n\r",ch);
return;
}
} else if( !str_prefix(arg,"standard")){
if( ch->level < skill_table[gsn_style_standard]->skill_level[ch->class])
{
send_to_char( "You have not yet learned enough to fight in the standard style.\n\r",ch);
return;
}
WAIT_STATE( ch, skill_table[gsn_style_standard]->beats );
if( number_percent() < LEARNED(ch, gsn_style_standard) ){
success
if(ch->fighting) {
ch->position = POS_FIGHTING;
learn_from_success(ch,gsn_style_standard);
if ( IS_PKILL( ch ) )
act( AT_ACTION, "$n switches to a standard fighting style.",
ch, NULL, NULL, TO_ROOM );
}
ch->style = STYLE_FIGHTING;
send_to_char( "You adopt a standard fighting style.\n\r",ch);
return;
} else {
failure
send_to_char( "You nearly trip in a lame attempt to adopt a standard fighting style.\n\r",ch);
return;
}
} else if( !str_prefix(arg,"aggressive")){
if( ch->level < skill_table[gsn_style_aggressive]->skill_level[ch->class])
{
send_to_char( "You have not yet learned enough to fight aggressively.\n\r",ch);
return;
}
WAIT_STATE( ch, skill_table[gsn_style_aggressive]->beats );
if( number_percent() < LEARNED(ch, gsn_style_aggressive) ){
success
if(ch->fighting) {
ch->position = POS_AGGRESSIVE;
learn_from_success(ch,gsn_style_aggressive);
if ( IS_PKILL( ch ) )
act( AT_ACTION, "$n assumes an aggressive stance.",
ch, NULL, NULL, TO_ROOM );
}
ch->style = STYLE_AGGRESSIVE;
send_to_char( "You adopt an aggressive fighting style.\n\r",ch);
return;
} else {
failure
send_to_char( "You nearly trip in a lame attempt to adopt an aggressive fighting style.\n\r",ch);
return;
}
} else if( !str_prefix(arg,"berserk")){
if( ch->level < skill_table[gsn_style_berserk]->skill_level[ch->class])
{
send_to_char( "You have not yet learned enough to fight as a berserker.\n\r",ch);
return;
}
WAIT_STATE( ch, skill_table[gsn_style_berserk]->beats );
if( number_percent() < LEARNED(ch, gsn_style_berserk) ){
success
if(ch->fighting) {
ch->position = POS_BERSERK;
learn_from_success(ch,gsn_style_berserk);
if ( IS_PKILL( ch ) )
act( AT_ACTION, "$n enters a wildly aggressive style.",
ch, NULL, NULL, TO_ROOM );
}
ch->style = STYLE_BERSERK;
send_to_char( "You adopt a berserk fighting style.\n\r",ch);
return;
} else {
failure
send_to_char( "You nearly trip in a lame attempt to adopt a berserk fighting style.\n\r",ch);
return;
}
}
send_to_char( "Adopt which fighting style?\n\r",ch);
return;
}
*/
char *rev_exit( sh_int vdir )
{
switch( vdir )
{
default: return "somewhere";
case 0: return "the south";
case 1: return "the west";
case 2: return "the north";
case 3: return "the east";
case 4: return "below";
case 5: return "above";
case 6: return "the southwest";
case 7: return "the southeast";
case 8: return "the northwest";
case 9: return "the northeast";
}
return "<???>";
}
/*
* Function to strip off the "a" or "an" or "the" or "some" from an object's
* short description for the purpose of using it in a sentence sent to
* the owner of the object. (Ie: an object with the short description
* "a long dark blade" would return "long dark blade" for use in a sentence
* like "Your long dark blade". The object name isn't always appropriate
* since it contains keywords that may not look proper. -Thoric
*/
char *myobj( OBJ_DATA *obj )
{
if ( !str_prefix("a ", obj->short_descr) )
return obj->short_descr + 2;
if ( !str_prefix("an ", obj->short_descr) )
return obj->short_descr + 3;
if ( !str_prefix("the ", obj->short_descr) )
return obj->short_descr + 4;
if ( !str_prefix("some ", obj->short_descr) )
return obj->short_descr + 5;
return obj->short_descr;
}