📄 act_info.c
字号:
/***************************************************************************
* Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. *
* *
* Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* *
* In order to use any part of this Merc Diku Mud, you must comply with *
* both the original Diku license in 'license.doc' as well the Merc *
* license in 'license.txt'. In particular, you may not remove either of *
* these copyright notices. *
* *
* Much time and thought has gone into this software and you are *
* benefitting. We hope that you share your changes too. What goes *
* around, comes around. *
***************************************************************************/
#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"
//#ifdef WIN32s
//#define crypt(d,s) strcpy(d,s)
//#endif
char * const where_name [] =
{
"<used as light> ",
"<worn on finger> ",
"<worn on finger> ",
"<worn around neck> ",
"<worn around neck> ",
"<worn on body> ",
"<worn on head> ",
"<worn on legs> ",
"<worn on feet> ",
"<worn on hands> ",
"<worn on arms> ",
"<worn as shield> ",
"<worn about body> ",
"<worn about waist> ",
"<worn around wrist> ",
"<worn around wrist> ",
"<wielded> ",
"<held> "
};
/*
* Local functions.
*/
char * format_obj_to_char args( ( OBJ_DATA *obj, CHAR_DATA *ch,
bool fShort ) );
void show_list_to_char args( ( OBJ_DATA *list, CHAR_DATA *ch,
bool fShort, bool fShowNothing ) );
void show_char_to_char_0 args( ( CHAR_DATA *victim, CHAR_DATA *ch ) );
void show_char_to_char_1 args( ( CHAR_DATA *victim, CHAR_DATA *ch ) );
void show_char_to_char args( ( CHAR_DATA *list, CHAR_DATA *ch ) );
bool check_blind args( ( CHAR_DATA *ch ) );
char *format_obj_to_char( OBJ_DATA *obj, CHAR_DATA *ch, bool fShort )
{
static char buf[MAX_STRING_LENGTH];
buf[0] = '\0';
if ( IS_OBJ_STAT(obj, ITEM_INVIS) ) strcat( buf, "(Invis) " );
if ( IS_AFFECTED(ch, AFF_DETECT_EVIL)
&& IS_OBJ_STAT(obj, ITEM_EVIL) ) strcat( buf, "(Red Aura) " );
if ( IS_AFFECTED(ch, AFF_DETECT_MAGIC)
&& IS_OBJ_STAT(obj, ITEM_MAGIC) ) strcat( buf, "(Magical) " );
if ( IS_OBJ_STAT(obj, ITEM_GLOW) ) strcat( buf, "(Glowing) " );
if ( IS_OBJ_STAT(obj, ITEM_HUM) ) strcat( buf, "(Humming) " );
if ( fShort )
{
if ( obj->short_descr != NULL )
strcat( buf, obj->short_descr );
}
else
{
if ( obj->description != NULL )
strcat( buf, obj->description );
}
return buf;
}
/*
* Show a list to a character.
* Can coalesce duplicated items.
*/
void show_list_to_char( OBJ_DATA *list, CHAR_DATA *ch, bool fShort, bool fShowNothing )
{
char buf[MAX_STRING_LENGTH];
char **prgpstrShow;
int *prgnShow;
char *pstrShow;
OBJ_DATA *obj;
int nShow;
int iShow;
int count;
bool fCombine;
if ( ch->desc == NULL )
return;
/*
* Alloc space for output lines.
*/
count = 0;
for ( obj = list; obj != NULL; obj = obj->next_content )
count++;
prgpstrShow = alloc_mem( count * sizeof(char *) );
prgnShow = alloc_mem( count * sizeof(int) );
nShow = 0;
/*
* Format the list of objects.
*/
for ( obj = list; obj != NULL; obj = obj->next_content )
{
if ( obj->wear_loc == WEAR_NONE && can_see_obj( ch, obj ) )
{
pstrShow = format_obj_to_char( obj, ch, fShort );
fCombine = FALSE;
if ( IS_NPC(ch) || IS_SET(ch->act, PLR_COMBINE) )
{
/*
* Look for duplicates, case sensitive.
* Matches tend to be near end so run loop backwords.
*/
for ( iShow = nShow - 1; iShow >= 0; iShow-- )
{
if ( !strcmp( prgpstrShow[iShow], pstrShow ) )
{
prgnShow[iShow]++;
fCombine = TRUE;
break;
}
}
}
/*
* Couldn't combine, or didn't want to.
*/
if ( !fCombine )
{
prgpstrShow [nShow] = str_dup( pstrShow );
prgnShow [nShow] = 1;
nShow++;
}
}
}
/*
* Output the formatted list.
*/
for ( iShow = 0; iShow < nShow; iShow++ )
{
if ( IS_NPC(ch) || IS_SET(ch->act, PLR_COMBINE) )
{
if ( prgnShow[iShow] != 1 )
{
sprintf( buf, "(%2d) ", prgnShow[iShow] );
send_to_char( buf, ch );
}
else
{
send_to_char( " ", ch );
}
}
send_to_char( prgpstrShow[iShow], ch );
send_to_char( "\n\r", ch );
free_string( prgpstrShow[iShow] );
}
if ( fShowNothing && nShow == 0 )
{
if ( IS_NPC(ch) || IS_SET(ch->act, PLR_COMBINE) )
send_to_char( " ", ch );
send_to_char( "Nothing.\n\r", ch );
}
/*
* Clean up.
*/
free_mem( prgpstrShow, count * sizeof(char *) );
free_mem( prgnShow, count * sizeof(int) );
return;
}
void show_char_to_char_0( CHAR_DATA *victim, CHAR_DATA *ch )
{
char buf[MAX_STRING_LENGTH];
buf[0] = '\0';
if ( IS_AFFECTED(victim, AFF_INVISIBLE) ) strcat( buf, "(Invis) " );
if ( IS_AFFECTED(victim, AFF_HIDE) ) strcat( buf, "(Hide) " );
if ( IS_AFFECTED(victim, AFF_CHARM) ) strcat( buf, "(Charmed) " );
if ( IS_AFFECTED(victim, AFF_PASS_DOOR) ) strcat( buf, "(Translucent) ");
if ( IS_AFFECTED(victim, AFF_FAERIE_FIRE) ) strcat( buf, "(Pink Aura) " );
if ( IS_EVIL(victim)
&& IS_AFFECTED(ch, AFF_DETECT_EVIL) ) strcat( buf, "(Red Aura) " );
if ( IS_AFFECTED(victim, AFF_SANCTUARY) ) strcat( buf, "(White Aura) " );
if ( !IS_NPC(victim) && IS_SET(victim->act, PLR_KILLER ) )
strcat( buf, "(KILLER) " );
if ( !IS_NPC(victim) && IS_SET(victim->act, PLR_THIEF ) )
strcat( buf, "(THIEF) " );
if ( victim->position == POS_STANDING && victim->long_descr[0] != '\0' )
{
strcat( buf, victim->long_descr );
send_to_char( buf, ch );
return;
}
strcat( buf, PERS( victim, ch ) );
if ( !IS_NPC(victim) && !IS_SET(ch->act, PLR_BRIEF) )
strcat( buf, victim->pcdata->title );
switch ( victim->position )
{
case POS_DEAD: strcat( buf, " is DEAD!!" ); break;
case POS_MORTAL: strcat( buf, " is mortally wounded." ); break;
case POS_INCAP: strcat( buf, " is incapacitated." ); break;
case POS_STUNNED: strcat( buf, " is lying here stunned." ); break;
case POS_SLEEPING: strcat( buf, " is sleeping here." ); break;
case POS_RESTING: strcat( buf, " is resting here." ); break;
case POS_STANDING: strcat( buf, " is here." ); break;
case POS_FIGHTING:
strcat( buf, " is here, fighting " );
if ( victim->fighting == NULL )
strcat( buf, "thin air??" );
else if ( victim->fighting == ch )
strcat( buf, "YOU!" );
else if ( victim->in_room == victim->fighting->in_room )
{
strcat( buf, PERS( victim->fighting, ch ) );
strcat( buf, "." );
}
else
strcat( buf, "somone who left??" );
break;
}
strcat( buf, "\n\r" );
buf[0] = UPPER(buf[0]);
send_to_char( buf, ch );
return;
}
void show_char_to_char_1( CHAR_DATA *victim, CHAR_DATA *ch )
{
char buf[MAX_STRING_LENGTH];
OBJ_DATA *obj;
int iWear;
int percent;
bool found;
if ( can_see( victim, ch ) )
{
act( "$n looks at you.", ch, NULL, victim, TO_VICT );
act( "$n looks at $N.", ch, NULL, victim, TO_NOTVICT );
}
if ( victim->description[0] != '\0' )
{
send_to_char( victim->description, ch );
}
else
{
act( "You see nothing special about $M.", ch, NULL, victim, TO_CHAR );
}
if ( victim->max_hit > 0 )
percent = ( 100 * victim->hit ) / victim->max_hit;
else
percent = -1;
strcpy( buf, PERS(victim, ch) );
if ( percent >= 100 ) strcat( buf, " is in perfect health.\n\r" );
else if ( percent >= 90 ) strcat( buf, " is slightly scratched.\n\r" );
else if ( percent >= 80 ) strcat( buf, " has a few bruises.\n\r" );
else if ( percent >= 70 ) strcat( buf, " has some cuts.\n\r" );
else if ( percent >= 60 ) strcat( buf, " has several wounds.\n\r" );
else if ( percent >= 50 ) strcat( buf, " has many nasty wounds.\n\r" );
else if ( percent >= 40 ) strcat( buf, " is bleeding freely.\n\r" );
else if ( percent >= 30 ) strcat( buf, " is covered in blood.\n\r" );
else if ( percent >= 20 ) strcat( buf, " is leaking guts.\n\r" );
else if ( percent >= 10 ) strcat( buf, " is almost dead.\n\r" );
else strcat( buf, " is DYING.\n\r" );
buf[0] = UPPER(buf[0]);
send_to_char( buf, ch );
found = FALSE;
for ( iWear = 0; iWear < MAX_WEAR; iWear++ )
{
if ( ( obj = get_eq_char( victim, iWear ) ) != NULL
&& can_see_obj( ch, obj ) )
{
if ( !found )
{
send_to_char( "\n\r", ch );
act( "$N is using:", ch, NULL, victim, TO_CHAR );
found = TRUE;
}
send_to_char( where_name[iWear], ch );
send_to_char( format_obj_to_char( obj, ch, TRUE ), ch );
send_to_char( "\n\r", ch );
}
}
if ( victim != ch
&& !IS_NPC(ch)
&& number_percent( ) < ch->pcdata->learned[gsn_peek] )
{
send_to_char( "\n\rYou peek at the inventory:\n\r", ch );
show_list_to_char( victim->carrying, ch, TRUE, TRUE );
}
return;
}
void show_char_to_char( CHAR_DATA *list, CHAR_DATA *ch )
{
CHAR_DATA *rch;
for ( rch = list; rch != NULL; rch = rch->next_in_room )
{
if ( rch == ch )
continue;
if ( !IS_NPC(rch)
&& IS_SET(rch->act, PLR_WIZINVIS)
&& get_trust( ch ) < get_trust( rch ) )
continue;
if ( can_see( ch, rch ) )
{
show_char_to_char_0( rch, ch );
}
else if ( room_is_dark( ch->in_room )
&& IS_AFFECTED(rch, AFF_INFRARED ) )
{
send_to_char( "You see glowing red eyes watching YOU!\n\r", ch );
}
}
return;
}
bool check_blind( CHAR_DATA *ch )
{
if ( !IS_NPC(ch) && IS_SET(ch->act, PLR_HOLYLIGHT) )
return TRUE;
if ( IS_AFFECTED(ch, AFF_BLIND) )
{
send_to_char( "You can't see a thing!\n\r", ch );
return FALSE;
}
return TRUE;
}
void do_look( CHAR_DATA *ch, char *argument )
{
char buf [MAX_STRING_LENGTH];
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
EXIT_DATA *pexit;
CHAR_DATA *victim;
OBJ_DATA *obj;
char *pdesc;
int door;
if ( !IS_NPC( ch ) && ch->desc == NULL )
return;
if ( ch->position < POS_SLEEPING )
{
send_to_char( "You can't see anything but stars!\n\r", ch );
return;
}
if ( ch->position == POS_SLEEPING )
{
send_to_char( "You can't see anything, you're sleeping!\n\r", ch );
return;
}
if ( !check_blind( ch ) )
return;
if ( !IS_NPC(ch)
&& !IS_SET(ch->act, PLR_HOLYLIGHT)
&& room_is_dark( ch->in_room ) )
{
send_to_char( "It is pitch black ... \n\r", ch );
show_char_to_char( ch->in_room->people, ch );
return;
}
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
if ( arg1[0] == '\0' || !str_cmp( arg1, "auto" ) )
{
/* 'look' or 'look auto' */
send_to_char( ch->in_room->name, ch );
if ( IS_HERO(ch) )
{
static char *szSectorTypes[] = { "inside", "city", "field", "forest",
"hills", "mountain", "water/swim", "water/boat", "error(8)", "air",
"desert", "error(11)" };
sprintf(buf, "\n\r#%4d <%s> %s%s%s%s%s%s%s%s%s", ch->in_room->vnum,
szSectorTypes[ch->in_room->sector_type],
(ch->in_room->room_flags & 1) ? "[DARK]" : "",
(ch->in_room->room_flags & 4) ? "[NO MOB]" : "",
(ch->in_room->room_flags & 8) ? "[INDOORS]" : "",
(ch->in_room->room_flags & 512) ? "[PRIVATE]" : "",
(ch->in_room->room_flags & 1024) ? "[SAFE]" : "",
(ch->in_room->room_flags & 2048) ? "[SOLITARY]" : "",
(ch->in_room->room_flags & 4096) ? "[PET SHOP]" : "",
(ch->in_room->room_flags & 8192) ? "[NO RECALL]" : "",
(ch->in_room->room_flags & 16384) ? "[PEACEFUL]" : "");
send_to_char( buf, ch );
}
send_to_char( "\n\r", ch );
if ( !IS_NPC(ch) && IS_SET(ch->act, PLR_AUTOEXIT) )
do_exits( ch, "auto" );
if ( arg1[0] == '\0'
|| ( !IS_NPC(ch) && !IS_SET(ch->act, PLR_BRIEF) ) )
send_to_char( ch->in_room->description, ch );
show_list_to_char( ch->in_room->contents, ch, FALSE, FALSE );
show_char_to_char( ch->in_room->people, ch );
return;
}
if ( !str_cmp( arg1, "i" ) || !str_cmp( arg1, "in" ) )
{
/* 'look in' */
if ( arg2[0] == '\0' )
{
send_to_char( "Look in what?\n\r", ch );
return;
}
if ( ( obj = get_obj_here( ch, arg2 ) ) == NULL )
{
send_to_char( "You do not see that here.\n\r", ch );
return;
}
switch ( obj->item_type )
{
default:
send_to_char( "That is not a container.\n\r", ch );
break;
case ITEM_DRINK_CON:
if ( obj->value[1] <= 0 )
{
send_to_char( "It is empty.\n\r", ch );
break;
}
sprintf( buf, "It's %s full of a %s liquid.\n\r",
obj->value[1] < obj->value[0] / 4
? "less than" :
obj->value[1] < 3 * obj->value[0] / 4
? "about" : "more than",
liq_table[obj->value[2]].liq_color
);
send_to_char( buf, ch );
break;
case ITEM_CONTAINER:
case ITEM_CORPSE_NPC:
case ITEM_CORPSE_PC:
if ( IS_SET(obj->value[1], CONT_CLOSED) )
{
send_to_char( "It is closed.\n\r", ch );
break;
}
act( "$p contains:", ch, obj, NULL, TO_CHAR );
show_list_to_char( obj->contains, ch, TRUE, TRUE );
break;
}
return;
}
if ( ( victim = get_char_room( ch, arg1 ) ) != NULL )
{
show_char_to_char_1( victim, ch );
return;
}
for ( obj = ch->carrying; obj != NULL; obj = obj->next_content )
{
if ( can_see_obj( ch, obj ) )
{
pdesc = get_extra_descr( arg1, obj->extra_descr );
if ( pdesc != NULL )
{
send_to_char( pdesc, ch );
return;
}
pdesc = get_extra_descr( arg1, obj->pIndexData->extra_descr );
if ( pdesc != NULL )
{
send_to_char( pdesc, ch );
return;
}
}
if ( is_name( arg1, obj->name ) )
{
send_to_char( obj->description, ch );
return;
}
}
for ( obj = ch->in_room->contents; obj != NULL; obj = obj->next_content )
{
if ( can_see_obj( ch, obj ) )
{
pdesc = get_extra_descr( arg1, obj->extra_descr );
if ( pdesc != NULL )
{
send_to_char( pdesc, ch );
return;
}
pdesc = get_extra_descr( arg1, obj->pIndexData->extra_descr );
if ( pdesc != NULL )
{
send_to_char( pdesc, ch );
return;
}
}
if ( is_name( arg1, obj->name ) )
{
send_to_char( obj->description, ch );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -