/****************************************************************************
* [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. *
* ------------------------------------------------------------------------ *
* Informational module *
****************************************************************************/
#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include "mud.h"
/*
* Needed in the do_ignore function. -Orion
*/
// bool check_parse_name args( ( char *name, bool newchar ) );
/*
* Keep players from defeating examine progs -Druid
* False = do not trigger
* True = Trigger
*/
bool EXA_prog_trigger = TRUE;
/* Had to add unknowns because someone added new positions and didn't
* update them. Just a band-aid till I have time to fix it right.
* This was found thanks to mud@mini.axcomp.com pointing it out :)
* --Shaddai
*/
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> ",
"<dual wielded> ",
"<worn on ears> ",
"<worn on eyes> ",
"<missile wielded> ",
"<worn on back> ",
"<worn over face> ",
"<worn around ankle> ",
"<worn around ankle> ",
"<BUG Inform Nivek> ",
"<BUG Inform Nivek> ",
"<BUG Inform Nivek> "
};
/*
* Local functions.
*/
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 ) );
void show_condition args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
//Similar Helpfile Snippet Declarations
sh_int str_similarity( const char *astr, const char *bstr );
sh_int str_prefix_level( const char *astr, const char *bstr );
void similar_help_files(CHAR_DATA *ch, char *argument);
char *format_obj_to_char( OBJ_DATA *obj, CHAR_DATA *ch, bool fShort )
{
static char buf[MAX_STRING_LENGTH];
bool glowsee = FALSE;
if ( !IS_NPC(ch) && ch->pcdata->questobj > 0 && obj->pIndexData->vnum == ch->pcdata->questobj)
strcat( buf, "[TARGET] " );
/* can see glowing invis items in the dark */
if ( IS_OBJ_STAT(obj, ITEM_GLOW) && IS_OBJ_STAT(obj, ITEM_INVIS)
&& !IS_AFFECTED(ch, AFF_TRUESIGHT) && !IS_AFFECTED(ch, AFF_DETECT_INVIS) )
glowsee = TRUE;
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, "&Y(&OMagical&Y)&D " );
if ( !glowsee && IS_OBJ_STAT(obj, ITEM_GLOW) )
strcat( buf, "&Y(&WGlowing&Y)&D " );
if ( IS_OBJ_STAT(obj, ITEM_HUM) )
strcat( buf, "&Y(&pHumming&Y)&D " );
if ( IS_OBJ_STAT(obj, ITEM_HIDDEN) )
strcat( buf, "(Hidden) " );
if ( IS_OBJ_STAT(obj, ITEM_BURIED) )
strcat( buf, "(Buried) " );
if ( IS_IMMORTAL(ch)
&& IS_OBJ_STAT(obj, ITEM_PROTOTYPE) )
strcat( buf, "&Y(&RPROTO&Y)&D " );
if ( IS_AFFECTED(ch, AFF_DETECTTRAPS)
&& is_trapped(obj) )
strcat( buf, "(Trap) " );
if ( fShort )
{
if ( glowsee && !IS_IMMORTAL(ch) )
strcat( buf, "the faint glow of something" );
else
if ( obj->short_descr )
strcat( buf, obj->short_descr );
}
else
{
if ( glowsee )
strcat( buf, "You see the faint glow of something nearby." );
if ( obj->description )
strcat( buf, obj->description );
}
return buf;
}
/*
* Some increasingly freaky hallucinated objects -Thoric
* (Hats off to Albert Hoffman's "problem child")
*/
char *hallucinated_object( int ms, bool fShort )
{
int sms = URANGE( 1, (ms+10)/5, 20 );
if ( fShort )
switch( number_range( 6-URANGE(1,sms/2,5), sms ) )
{
case 1:
return "a sword";
case 2:
return "a stick";
case 3:
return "something shiny";
case 4:
return "something";
case 5:
return "something interesting";
case 6:
return "something colorful";
case 7:
return "something that looks cool";
case 8:
return "a nifty thing";
case 9:
return "a cloak of flowing colors";
case 10:
return "a mystical flaming sword";
case 11:
return "a swarm of insects";
case 12:
return "a deathbane";
case 13:
return "a figment of your imagination";
case 14:
return "your gravestone";
case 15:
return "the long lost boots of Ranger Thoric";
case 16:
return "a glowing tome of arcane knowledge";
case 17:
return "a long sought secret";
case 18:
return "the meaning of it all";
case 19:
return "the answer";
case 20:
return "the key to life, the universe and everything";
}
switch( number_range( 6-URANGE(1,sms/2,5), sms ) )
{
case 1:
return "A nice looking sword catches your eye.";
case 2:
return "The ground is covered in small sticks.";
case 3:
return "Something shiny catches your eye.";
case 4:
return "Something catches your attention.";
case 5:
return "Something interesting catches your eye.";
case 6:
return "Something colorful flows by.";
case 7:
return "Something that looks cool calls out to you.";
case 8:
return "A nifty thing of great importance stands here.";
case 9:
return "A cloak of flowing colors asks you to wear it.";
case 10:
return "A mystical flaming sword awaits your grasp.";
case 11:
return "A swarm of insects buzzes in your face!";
case 12:
return "The extremely rare Deathbane lies at your feet.";
case 13:
return "A figment of your imagination is at your command.";
case 14:
return "You notice a gravestone here... upon closer examination, it reads your name.";
case 15:
return "The long lost boots of Ranger Thoric lie off to the side.";
case 16:
return "A glowing tome of arcane knowledge hovers in the air before you.";
case 17:
return "A long sought secret of all mankind is now clear to you.";
case 18:
return "The meaning of it all, so simple, so clear... of course!";
case 19:
return "The answer. One. It's always been One.";
case 20:
return "The key to life, the universe and everything awaits your hand.";
}
return "Whoa!!!";
}
/* This is the punct snippet from Desden el Chaman Tibetano - Nov 1998
Email: jlalbatros@mx2.redestb.es
*/
char *num_punct(int foo)
{
int nindex, index_new, rest;
char buf[16];
static char buf_new[16];
sprintf(buf,"%d",foo);
rest = strlen(buf)%3;
for (nindex=index_new=0;nindex<strlen(buf);nindex++,index_new++)
{
if (nindex!=0 && (nindex-rest)%3==0 )
{
buf_new[index_new]=',';
index_new++;
buf_new[index_new]=buf[nindex];
}
else
buf_new[index_new] = buf[nindex];
}
buf_new[index_new]='\0';
return buf_new;
}
/*
* 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 **prgpstrShow;
int *prgnShow;
int *pitShow;
char *pstrShow;
OBJ_DATA *obj;
int nShow;
int iShow;
int count, offcount, tmp, ms, cnt;
bool fCombine;
if ( !ch->desc )
return;
/*
* if there's no list... then don't do all this crap! -Thoric
*/
if ( !list )
{
if ( fShowNothing )
{
if ( IS_NPC(ch) || xIS_SET(ch->act, PLR_COMBINE) )
send_to_char( " ", ch );
set_char_color( AT_OBJECT, ch );
send_to_char( "Nothing.\n\r", ch );
}
return;
}
/*
* Alloc space for output lines.
*/
count = 0;
for ( obj = list; obj; obj = obj->next_content )
count++;
ms = (ch->mental_state ? ch->mental_state : 1)
* (IS_NPC(ch) ? 1 : (ch->pcdata->condition[COND_DRUNK] ? (ch->pcdata->condition[COND_DRUNK]/12) : 1));
/*
* If not mentally stable...
*/
if ( abs(ms) > 40 )
{
offcount = URANGE( -(count), (count * ms) / 100, count*2 );
if ( offcount < 0 )
offcount += number_range(0, abs(offcount));
else
if ( offcount > 0 )
offcount -= number_range(0, offcount);
}
else
offcount = 0;
if ( count + offcount <= 0 )
{
if ( fShowNothing )
{
if ( IS_NPC(ch) || xIS_SET(ch->act, PLR_COMBINE) )
send_to_char( " ", ch );
set_char_color( AT_OBJECT, ch );
send_to_char( "Nothing.\n\r", ch );
}
return;
}
CREATE( prgpstrShow, char*, count + ((offcount > 0) ? offcount : 0) );
CREATE( prgnShow, int, count + ((offcount > 0) ? offcount : 0) );
CREATE( pitShow, int, count + ((offcount > 0) ? offcount : 0) );
nShow = 0;
tmp = (offcount > 0) ? offcount : 0;
cnt = 0;
/*
* Format the list of objects.
*/
for ( obj = list; obj; obj = obj->next_content )
{
if ( offcount < 0 && ++cnt > (count + offcount) )
break;
if ( tmp > 0 && number_bits(1) == 0 )
{
prgpstrShow [nShow] = str_dup( hallucinated_object(ms, fShort) );
prgnShow [nShow] = 1;
pitShow [nShow] = number_range( ITEM_LIGHT, ITEM_BOOK );
nShow++;
--tmp;
}
if ( obj->wear_loc == WEAR_NONE
&& can_see_obj( ch, obj )
&& (obj->item_type != ITEM_TRAP || IS_AFFECTED(ch, AFF_DETECTTRAPS) ) )
{
pstrShow = format_obj_to_char( obj, ch, fShort );
fCombine = FALSE;
if ( IS_NPC(ch) || xIS_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] += obj->count;
fCombine = TRUE;
break;
}
}
}
pitShow[nShow] = obj->item_type;
/*
* Couldn't combine, or didn't want to.
*/
if ( !fCombine )
{
prgpstrShow [nShow] = str_dup( pstrShow );
prgnShow [nShow] = obj->count;
nShow++;
}
}
}
if ( tmp > 0 )
{
int x;
for ( x = 0; x < tmp; x++ )
{
prgpstrShow [nShow] = str_dup( hallucinated_object(ms, fShort) );
prgnShow [nShow] = 1;
pitShow [nShow] = number_range( ITEM_LIGHT, ITEM_BOOK );
nShow++;
}
}
/*
* Output the formatted list. -Color support by Thoric
*/
for ( iShow = 0; iShow < nShow; iShow++ )
{
switch(pitShow[iShow])
{
default:
set_char_color( AT_OBJECT, ch );
break;
case ITEM_BLOOD:
set_char_color( AT_BLOOD, ch );
break;
case ITEM_MONEY:
case ITEM_TREASURE:
set_char_color( AT_YELLOW, ch );
break;
case ITEM_COOK:
case ITEM_FOOD:
set_char_color( AT_HUNGRY, ch );
break;
case ITEM_DRINK_CON:
case ITEM_FOUNTAIN:
set_char_color( AT_THIRSTY, ch );
break;
case ITEM_FIRE:
set_char_color( AT_FIRE, ch );
break;
case ITEM_SCROLL:
case ITEM_WAND:
case ITEM_STAFF:
set_char_color( AT_MAGIC, ch );
break;
}
if ( fShowNothing )
send_to_char( " ", ch );
send_to_char( prgpstrShow[iShow], ch );
/* if ( IS_NPC(ch) || xIS_SET(ch->act, PLR_COMBINE) ) */
{
if ( prgnShow[iShow] != 1 )
ch_printf( ch, " (%d)", prgnShow[iShow] );
}
send_to_char( "\n\r", ch );
DISPOSE( prgpstrShow[iShow] );
}
if ( fShowNothing && nShow == 0 )
{
if ( IS_NPC(ch) || xIS_SET(ch->act, PLR_COMBINE) )
send_to_char( " ", ch );
set_char_color( AT_OBJECT, ch );
send_to_char( "Nothing.\n\r", ch );
}
/*
* Clean up.
*/
DISPOSE( prgpstrShow );
DISPOSE( prgnShow );
DISPOSE( pitShow );
return;
}
/*
* Show fancy descriptions for certain spell affects -Thoric
*/
void show_visible_affects_to_char( CHAR_DATA *victim, CHAR_DATA *ch )
{
char buf[MAX_STRING_LENGTH];
char name[MAX_STRING_LENGTH];
if ( IS_NPC( victim ) )
strcpy( name, victim->short_descr );
else
strcpy( name, victim->name);
name[0] = toupper(name[0]);
if ( IS_AFFECTED(victim, AFF_SANCTUARY) )
{
set_char_color( AT_WHITE, ch );
if ( IS_GOOD(victim) )
ch_printf( ch, "%s glows with an aura of divine radiance.\n\r", name );
else if ( IS_EVIL(victim) )
ch_printf( ch, "%s shimmers beneath an aura of dark energy.\n\r", name );
else
ch_printf( ch, "%s is shrouded in flowing shadow and light.\n\r", name );
}
if ( IS_AFFECTED(victim, AFF_FIRESHIELD) )
{
set_char_color( AT_FIRE, ch );
ch_printf( ch, "%s is engulfed within a blaze of mystical flame.\n\r", name );
}
if ( IS_AFFECTED(victim, AFF_SHOCKSHIELD) )
{
set_char_color( AT_BLUE, ch );
ch_printf( ch, "%s is surrounded by cascading torrents of energy.\n\r", name );
}
if ( IS_AFFECTED(victim, AFF_ACIDMIST) )
{
set_char_color( AT_GREEN, ch );
ch_printf( ch, "%s is visible through a cloud of churning mist.\n\r", name );
}
/*Scryn 8/13*/
if ( IS_AFFECTED(victim, AFF_ICESHIELD) )
{
set_char_color( AT_LBLUE, ch );
ch_printf( ch, "%s is ensphered by shards of glistening ice.\n\r", name );
}
if ( IS_AFFECTED(victim, AFF_CHARM) )
{
set_char_color( AT_MAGIC, ch );
ch_printf( ch, "%s wanders in a dazed, zombie-like state.\n\r", name );
}
if ( !IS_NPC(victim) && !victim->desc
&& victim->switched && IS_AFFECTED(victim->switched, AFF_POSSESS) )
{
set_char_color( AT_MAGIC, ch );
strcpy( buf, PERS( victim, ch, FALSE ) );
strcat( buf, " appears to be in a deep trance...\n\r" );
}
}
void show_char_to_char_0( CHAR_DATA *victim, CHAR_DATA *ch )
{
char buf[MAX_STRING_LENGTH];
char buf1[MAX_STRING_LENGTH];
char message[MAX_STRING_LENGTH];
buf[0] = '\0';
set_char_color( AT_PERSON, ch );
if ( !IS_NPC(victim) && !victim->desc )
{
if ( !victim->switched )
send_to_char_color( "&P[(Link Dead)] ", ch );
else if ( !IS_AFFECTED(victim, AFF_POSSESS) )
strcat( buf, "(Switched) " );
}
if ( IS_NPC(victim) && IS_AFFECTED(victim, AFF_POSSESS) && IS_IMMORTAL(ch)
&& victim->desc )
{
sprintf( buf1, "(%s)",victim->desc->original->name );
strcat( buf, buf1 );
}
if ( !IS_NPC(victim)
&& xIS_SET(victim->act, PLR_AFK) )
strcat( buf, "[AFK] ");
if ( (!IS_NPC(victim) && xIS_SET(victim->act, PLR_WIZINVIS))
|| (IS_NPC(victim) && xIS_SET(victim->act, ACT_MOBINVIS)) )
{
if (!IS_NPC(victim))
sprintf( buf1,"(Invis %d) ", victim->pcdata->wizinvis );
else
sprintf( buf1,"(Mobinvis %d) ", victim->mobinvis);
strcat( buf, buf1 );
}
if (IS_NPC(victim) && !IS_NPC(ch) && ch->pcdata->questmob > 0 && victim->pIndexData->vnum == ch->pcdata->questmob)
strcat( buf, "[TARGET] ");
if ( !IS_NPC( victim) )
{
if ( IS_IMMORTAL( victim ) && victim->level > 50 )
send_to_char_color( "&P(&WImmortal&P) ", ch );
if ( victim->pcdata->clan
&& IS_SET( victim->pcdata->flags, PCFLAG_DEADLY )
&& victim->pcdata->clan->badge
&& ( victim->pcdata->clan->clan_type != CLAN_ORDER
&& victim->pcdata->clan->clan_type != CLAN_GUILD ) )
ch_printf_color( ch, "%s ", victim->pcdata->clan->badge );
else if ( CAN_PKILL( victim ) && victim->level < 51 )
send_to_char_color( "&P(&wUnclanned&P) ", ch );
}
set_char_color( AT_PERSON, ch );
if ( IS_AFFECTED(victim, AFF_INVISIBLE) )
strcat( buf, "(Invis) " );
if ( IS_AFFECTED(victim, AFF_HIDE) )
strcat( buf, "(Hide) " );
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_NEUTRAL(victim) && ( IS_AFFECTED(ch, AFF_DETECT_EVIL) ))
strcat( buf, "(Grey Aura) " );
if ( IS_GOOD(victim) && ( IS_AFFECTED(ch, AFF_DETECT_EVIL) ))
strcat( buf, "(White Aura) " );
if ( IS_AFFECTED(victim, AFF_BERSERK) )
strcat( buf, "(B) " );
if ( !IS_NPC(victim) && xIS_SET(victim->act, PLR_ATTACKER ) )
strcat( buf, "(A) " );
if ( !IS_NPC(victim) && xIS_SET(victim->act, PLR_KILLER ) )
strcat( buf, "(K) " );
if ( !IS_NPC(victim) && xIS_SET(victim->act, PLR_THIEF ) )
strcat( buf, "(T) " );
if ( !IS_NPC(victim) && xIS_SET(victim->act, PLR_LITTERBUG ) )
strcat( buf, "(L) " );
if ( IS_NPC(victim) && IS_IMMORTAL(ch)
&& xIS_SET(victim->act, ACT_PROTOTYPE) )
strcat( buf, "(P) " );
if ( IS_NPC(victim) && ch->mount && ch->mount == victim
&& ch->in_room == ch->mount->in_room )
strcat( buf, "(Mount) " );
if ( victim->desc && victim->desc->connected == CON_EDITING )
strcat( buf, "(W) " );
if ( victim->morph != NULL )
strcat (buf, "(Morphed) ");
set_char_color( AT_PERSON, ch );
if ((victim->position == victim->defposition && victim->long_descr[0] != '\0')
|| ( victim->morph && victim->morph->morph &&
victim->morph->morph->defpos == victim->position ) )
{
if ( victim->morph != NULL )
{
if ( !IS_IMMORTAL(ch) )
{
if ( victim->morph->morph != NULL)
strcat ( buf, victim->morph->morph->long_desc );
else
strcat ( buf, victim->long_descr );
}
else
{
strcat (buf, PERS(victim, ch, FALSE) );
if ( !IS_NPC(victim) && !xIS_SET(ch->act, PLR_BRIEF) )
strcat( buf, victim->pcdata->title );
strcat( buf, ".\n\r" );
}
}
else
strcat (buf, victim->long_descr);
send_to_char( buf, ch );
show_visible_affects_to_char( victim, ch );
return;
}
else
{
if ( victim->morph != NULL && victim->morph->morph != NULL &&
!IS_IMMORTAL( ch ) )
strcat( buf, MORPHPERS( victim, ch, FALSE ) );
else
strcat( buf, PERS( victim, ch, FALSE ) );
}
if ( !IS_NPC(victim) && !xIS_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;
/* Furniture ideas taken from ROT
Furniture 1.01 is provided by Xerves
Info rewrite for sleeping/resting/standing/sitting on Objects -- Xerves */
case POS_SLEEPING:
if (victim->on != NULL)
{
if (IS_SET(victim->on->value[2],SLEEP_AT))
{
sprintf(message,"&P is sleeping at %s.",
victim->on->short_descr);
strcat(buf,message);
}
else if (IS_SET(victim->on->value[2],SLEEP_ON))
{
sprintf(message,"&P is sleeping on %s.",
victim->on->short_descr);
strcat(buf,message);
}
else
{
sprintf(message, "&P is sleeping in %s.",
victim->on->short_descr);
strcat(buf,message);
}
}
else
{
if (ch->position == POS_SITTING
|| ch->position == POS_RESTING )
strcat( buf, "&P is sleeping nearby.&G" );
else
strcat( buf, "&P is deep in slumber here.&G" );
}
break;
case POS_RESTING:
if (victim->on != NULL)
{
if (IS_SET(victim->on->value[2],REST_AT))
{
sprintf(message,"&P is resting at %s.",
victim->on->short_descr);
strcat(buf,message);
}
else if (IS_SET(victim->on->value[2],REST_ON))
{
sprintf(message,"&P is resting on %s.",
victim->on->short_descr);
strcat(buf,message);
}
else
{
sprintf(message, "&P is resting in %s.",
victim->on->short_descr);
strcat(buf,message);
}
}
else
{
if (ch->position == POS_RESTING)
strcat ( buf, "&P is sprawled out alongside you.&G" );
else
if (ch->position == POS_MOUNTED)
strcat ( buf, "&P is sprawled out at the foot of your mount.&G" );
else
strcat (buf, "&P is sprawled out here.&G" );
}
break;
case POS_SITTING:
if (victim->on != NULL)
{
if (IS_SET(victim->on->value[2],SIT_AT))
{
sprintf(message,"&P is sitting at %s.",
victim->on->short_descr);
strcat(buf,message);
}
else if (IS_SET(victim->on->value[2],SIT_ON))
{
sprintf(message,"&P is sitting on %s.",
victim->on->short_descr);
strcat(buf,message);
}
else
{
sprintf(message, "&P is sitting in %s.",
victim->on->short_descr);
strcat(buf,message);
}
}
else
strcat(buf, "&P is sitting here.");
break;
case POS_STANDING:
if (victim->on != NULL)
{
if (IS_SET(victim->on->value[2],STAND_AT))
{
sprintf(message,"&P is standing at %s.",
victim->on->short_descr);
strcat(buf,message);
}
else if (IS_SET(victim->on->value[2],STAND_ON))
{
sprintf(message,"&P is standing on %s.",
victim->on->short_descr);
strcat(buf,message);
}
else
{
sprintf(message, "&P is standing in %s.",
victim->on->short_descr);
strcat(buf,message);
}
}
else
if ( IS_IMMORTAL(victim) )
strcat( buf, "&P is here before you.&G" );
else
if ( ( victim->in_room->sector_type == SECT_UNDERWATER )
&& !IS_AFFECTED(victim, AFF_AQUA_BREATH) && !IS_NPC(victim) )
strcat( buf, "&P is drowning here.&G" );
else
if ( victim->in_room->sector_type == SECT_UNDERWATER )
strcat( buf, "&P is here in the water.&G" );
else
if ( ( victim->in_room->sector_type == SECT_OCEANFLOOR )
&& !IS_AFFECTED(victim, AFF_AQUA_BREATH) && !IS_NPC(victim) )
strcat( buf, "&P is drowning here.&G" );
else
if ( victim->in_room->sector_type == SECT_OCEANFLOOR )
strcat( buf, "&P is standing here in the water.&G" );
else
if ( IS_AFFECTED(victim, AFF_FLOATING)
|| IS_AFFECTED(victim, AFF_FLYING) )
strcat( buf, "&P is hovering here.&G" );
else
strcat( buf, "&P is standing here.&G" );
break;
case POS_SHOVE:
strcat( buf, " is being shoved around." );
break;
case POS_DRAG:
strcat( buf, " is being dragged around." );
break;
case POS_MOUNTED:
strcat( buf, " is here, upon " );
if ( !victim->mount )
strcat( buf, "thin air???" );
else
if ( victim->mount == ch )
strcat( buf, "your back." );
else
if ( victim->in_room == victim->mount->in_room )
{
strcat( buf, PERS( victim->mount, ch, FALSE ) );
strcat( buf, "." );
}
else
strcat( buf, "someone who left??" );
break;
case POS_FIGHTING:
case POS_EVASIVE:
case POS_DEFENSIVE:
case POS_AGGRESSIVE:
case POS_BERSERK:
strcat( buf, " is here, fighting " );
if ( !victim->fighting )
{
strcat( buf, "thin air???" );
/* some bug somewhere.... kinda hackey fix -h */
if(! victim->mount)
victim->position = POS_STANDING;
else
victim->position = POS_MOUNTED;
}
else if ( who_fighting( victim ) == ch )
strcat( buf, "YOU!" );
else if ( victim->in_room == victim->fighting->who->in_room )
{
strcat( buf, PERS( victim->fighting->who, ch, FALSE ) );
strcat( buf, "." );
}
else
strcat( buf, "someone who left??" );
break;
}
strcat( buf, "\n\r" );
buf[0] = UPPER(buf[0]);
send_to_char( buf, ch );
show_visible_affects_to_char( victim, ch );
return;
}
void show_char_to_char_1( CHAR_DATA *victim, CHAR_DATA *ch )
{
OBJ_DATA *obj;
int iWear;
bool found;
if ( can_see( victim, ch, FALSE ) && !IS_NPC( ch ) && !xIS_SET( ch->act, PLR_WIZINVIS ) )
{
act( AT_ACTION, "$n looks at you.", ch, NULL, victim, TO_VICT );
if ( victim != ch )
act( AT_ACTION, "$n looks at $N.", ch, NULL, victim, TO_NOTVICT );
else
act( AT_ACTION, "$n looks at $mself.", ch, NULL, victim, TO_NOTVICT );
}
if ( victim->description[0] != '\0' )
{
if ( victim->morph != NULL && victim->morph->morph != NULL)
send_to_char ( victim->morph->morph->description , ch );
else
send_to_char (victim->description, ch);
}
else
{
if ( victim->morph != NULL && victim->morph->morph != NULL)
send_to_char ( victim->morph->morph->description , ch );
else if ( IS_NPC( victim ) )
act( AT_PLAIN, "You see nothing special about $M.", ch, NULL, victim, TO_CHAR );
else if ( ch != victim )
act( AT_PLAIN, "$E isn't much to look at...", ch, NULL, victim, TO_CHAR );
else
act( AT_PLAIN, "You're not much to look at...", ch, NULL, NULL, TO_CHAR );
}
show_race_line( ch, victim );
show_condition( ch, victim );
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 );
if ( victim != ch )
act( AT_PLAIN, "$N is using:", ch, NULL, victim, TO_CHAR );
else
act( AT_PLAIN, "You are using:", ch, NULL, NULL, TO_CHAR );
found = TRUE;
}
if( (!IS_NPC(victim)) && (victim->race>0) && (victim->race<MAX_PC_RACE))
send_to_char(race_table[victim->race]->where_name[iWear], ch);
else
send_to_char( where_name[iWear], ch );
send_to_char( format_obj_to_char( obj, ch, TRUE ), ch );
send_to_char( "\n\r", ch );
}
}
/*
* Crash fix here by Thoric
*/
if ( IS_NPC(ch) || victim == ch )
return;
if ( IS_IMMORTAL( ch ) )
{
if ( IS_NPC( victim ) )
ch_printf( ch, "\n\rMobile #%d '%s' ",
victim->pIndexData->vnum,
victim->name );
else
ch_printf( ch, "\n\r%s ", victim->name );
ch_printf( ch, "is a level %d %s %s.\n\r",
victim->level,
IS_NPC(victim)?victim->race<MAX_NPC_RACE&&victim->race>=0?
npc_race[victim->race]:"unknown":victim->race<MAX_PC_RACE&&
race_table[victim->race]->race_name&&
race_table[victim->race]->race_name[0] != '\0'?
race_table[victim->race]->race_name:"unknown",
IS_NPC(victim)?victim->class<MAX_NPC_CLASS&&victim->class>=0?
npc_class[victim->class] : "unknown":victim->class<MAX_PC_CLASS&&
class_table[victim->class]->who_name&&
class_table[victim->class]->who_name[0] != '\0'?
class_table[victim->class]->who_name:"unknown");
/* Fix so it shows what is in class table
victim->race<MAX_NPC_RACE&&victim->race>=0?npc_race[victim->race] : "unknown",
victim->class<MAX_NPC_CLASS&&victim->class>=0?npc_class[victim->class] : "unknown" );
*/
}
if ( number_percent( ) < LEARNED(ch, gsn_peek) )
{
ch_printf( ch, "\n\rYou peek at %s inventory:\n\r",
victim->sex == 1 ? "his" : victim->sex == 2 ? "her" : "its" );
show_list_to_char( victim->first_carrying, ch, TRUE, TRUE );
learn_from_success( ch, gsn_peek );
}
else
if ( ch->pcdata->learned[gsn_peek] > 0 )
learn_from_failure( ch, gsn_peek );
return;
}
void show_char_to_char( CHAR_DATA *list, CHAR_DATA *ch )
{
CHAR_DATA *rch;
for ( rch = list; rch; rch = rch->next_in_room )
{
if ( rch == ch )
continue;
if ( can_see( ch, rch, FALSE ) )
{
show_char_to_char_0( rch, ch );
}
else if ( room_is_dark( ch->in_room )
&& IS_AFFECTED(ch, AFF_INFRARED )
&& !(!IS_NPC(rch) && IS_IMMORTAL(rch)) )
{
set_char_color( AT_BLOOD, ch );
send_to_char( "The red form of a living creature is here.\n\r", ch );
}
}
return;
}
bool check_blind( CHAR_DATA *ch )
{
if ( !IS_NPC(ch) && xIS_SET(ch->act, PLR_HOLYLIGHT) )
return TRUE;
if ( IS_AFFECTED(ch, AFF_TRUESIGHT) )
return TRUE;
if ( IS_AFFECTED(ch, AFF_BLIND) )
{
send_to_char( "You can't see a thing!\n\r", ch );
return FALSE;
}
return TRUE;
}
/*
* Returns classical DIKU door direction based on text in arg -Thoric
*/
int get_door( char *arg )
{
int door;
if ( !str_cmp( arg, "n" ) || !str_cmp( arg, "north" ) )
door = 0;
else if ( !str_cmp( arg, "e" ) || !str_cmp( arg, "east" ) )
door = 1;
else if ( !str_cmp( arg, "s" ) || !str_cmp( arg, "south" ) )
door = 2;
else if ( !str_cmp( arg, "w" ) || !str_cmp( arg, "west" ) )
door = 3;
else if ( !str_cmp( arg, "u" ) || !str_cmp( arg, "up" ) )
door = 4;
else if ( !str_cmp( arg, "d" ) || !str_cmp( arg, "down" ) )
door = 5;
else if ( !str_cmp( arg, "ne" ) || !str_cmp( arg, "northeast" ) )
door = 6;
else if ( !str_cmp( arg, "nw" ) || !str_cmp( arg, "northwest" ) )
door = 7;
else if ( !str_cmp( arg, "se" ) || !str_cmp( arg, "southeast" ) )
door = 8;
else if ( !str_cmp( arg, "sw" ) || !str_cmp( arg, "southwest" ) )
door = 9;
else
door = -1;
return door;
}
void do_look( CHAR_DATA *ch, char *argument )
{
char arg [MAX_INPUT_LENGTH];
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char arg3 [MAX_INPUT_LENGTH];
EXIT_DATA *pexit;
CHAR_DATA *victim;
OBJ_DATA *obj;
ROOM_INDEX_DATA *original;
char *pdesc;
sh_int door;
int number, cnt;
char dir_n[50];
char dir_e[50];
char dir_s[50];
char dir_w[50];
char dir_u[50];
char dir_d[50];
char dir_ne[50];
char dir_nw[50];
char dir_se[50];
char dir_sw[50];
char dir_sm[50];
char *exitcolor;
strncpy( dir_n, "&z-", 50 );
strncpy( dir_e, "&z-", 50 );
strncpy( dir_s, "&z-", 50 );
strncpy( dir_w, "&z-", 50 );
strncpy( dir_u, "&z-", 50 );
strncpy( dir_d, "&z-", 50 );
strncpy( dir_ne, "&z -", 50 );
strncpy( dir_nw, "&z- ", 50 );
strncpy( dir_se, "&z -", 50 );
strncpy( dir_sw, "&z- ", 50 );
strncpy( dir_sm, "&z-", 50 );
if ( !ch->desc )
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)
&& !xIS_SET(ch->act, PLR_HOLYLIGHT)
&& !IS_AFFECTED(ch, AFF_TRUESIGHT)
&& room_is_dark( ch->in_room ) )
{
set_char_color( AT_DGREY, ch );
send_to_char( "It is pitch black ... \n\r", ch );
show_char_to_char( ch->in_room->first_person, ch );
return;
}
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
argument = one_argument( argument, arg3 );
if ( arg1[0] == '\0' || !str_cmp( arg1, "auto" ) )
{
if( IS_PLR_FLAG( ch, PLR_ONMAP ) || IS_ACT_FLAG( ch, ACT_ONMAP ) )
{
display_map( ch );
#ifdef DRAGONFLIGHT
if( !ch->inflight )
{
#endif
show_list_to_char( ch->in_room->first_content, ch, FALSE, FALSE );
show_char_to_char( ch->in_room->first_person, ch );
#ifdef DRAGONFLIGHT
}
#endif
return;
}
/* 'look' or 'look auto' */
for( pexit = ch->in_room->first_exit; pexit; pexit = pexit->next )
{
if( ( pexit->to_room
&& !IS_SET (pexit->exit_info, EX_HIDDEN)
&& !IS_SET (pexit->exit_info, EX_SECRET))
|| (IS_SET (pexit->exit_info, EX_SECRET)
&& !IS_SET (pexit->exit_info, EX_CLOSED)))
{
exitcolor = "&Y";
if( IS_SET( pexit->exit_info, EX_WINDOW ) )
exitcolor = "&C";
if( IS_SET( pexit->exit_info, EX_SECRET ) )
exitcolor = "&b";
if( IS_SET( pexit->exit_info, EX_CLOSED ) )
exitcolor = "&z";
if( IS_SET( pexit->exit_info, EX_LOCKED ) )
exitcolor = "&R";
if( pexit->vdir == DIR_NORTH )
snprintf( dir_n, 50, "%sN", exitcolor );
if( pexit->vdir == DIR_EAST )
snprintf( dir_e, 50, "%sE", exitcolor );
if( pexit->vdir == DIR_SOUTH )
snprintf( dir_s, 50, "%sS", exitcolor );
if( pexit->vdir == DIR_WEST )
snprintf( dir_w, 50, "%sW", exitcolor );
if( pexit->vdir == DIR_UP )
snprintf( dir_u, 50, "%sU", exitcolor );
if( pexit->vdir == DIR_DOWN )
snprintf( dir_d, 50, "%sD", exitcolor );
if( pexit->vdir == DIR_NORTHEAST )
snprintf( dir_ne, 50, "%sNE", exitcolor );
if( pexit->vdir == DIR_NORTHWEST )
snprintf( dir_nw, 50, "%sNW", exitcolor );
if( pexit->vdir == DIR_SOUTHEAST )
snprintf( dir_se, 50, "%sSE", exitcolor );
if( pexit->vdir == DIR_SOUTHWEST )
snprintf( dir_sw, 50, "%sSW", exitcolor );
}
}
if( xIS_SET( ch->act, PLR_COMPASS ) )
{
send_to_char( "\n\r", ch );
set_char_color( AT_RMNAME, ch );
ch_printf( ch, "%-50s", ch->in_room->name );
send_mip_room( ch, ch->in_room->name );
strncat( dir_nw, " ", 50 );
ch_printf_color( ch, " %s", dir_nw );
strncat( dir_n, " ", 50 );
ch_printf_color( ch, " %s", dir_n );
ch_printf_color( ch, " %s\n\r", dir_ne );
send_to_char( "&z-<----------------------------------------------->- ", ch );
strncat( dir_w, "", 50 );
ch_printf_color( ch, " %s", dir_w );
send_to_char( "&z<-", ch );
strncat( dir_u, "&z-(&Y&W*&z)", 50 );
ch_printf_color( ch, "%s", dir_u );
strncat( dir_d, "&z-", 50 );
send_to_char( "&z-", ch );
ch_printf_color( ch, "%s", dir_d );
send_to_char( "&z>", ch );
ch_printf_color( ch, "%s\n\r", dir_e );
send_to_char( " ", ch );
strncat( dir_sw, " ", 50 );
ch_printf_color( ch, " %s", dir_sw );
strncat( dir_s, " ", 50 );
ch_printf_color( ch, " %s", dir_s );
ch_printf_color( ch, " %s", dir_se );
send_to_char( "\n\r", ch );
/* Room flag display installed by Samson 12-10-97 */
if( !IS_NPC(ch) && IS_IMMORTAL(ch) && IS_SET( ch->pcdata->flags, PCFLAG_AUTOFLAGS ) )
{
set_char_color( AT_BLUE, ch );
ch_printf( ch, "[Area Flags: %s]\n\r", flag_string( ch->in_room->area->flags, area_flags ) );
set_char_color( AT_BLUE, ch );
ch_printf( ch, "[Room Flags: %s]\n\r", ext_flag_string( &ch->in_room->room_flags, r_flags ) );
}
/* Room Sector display written and installed by Samson 12-10-97 */
if( !IS_NPC(ch) && IS_IMMORTAL(ch) && IS_SET( ch->pcdata->flags, PCFLAG_SECTORD ) )
{
set_char_color( AT_BLUE, ch );
ch_printf( ch, "[Sector Type: %s]\n\r", sec_flags[ch->in_room->sector_type] );
}
/* Area name and filename display installed by Samson 12-13-97 */
if( !IS_NPC(ch) && IS_IMMORTAL(ch) && IS_SET( ch->pcdata->flags, PCFLAG_ANAME ) )
{
set_char_color( AT_BLUE, ch );
ch_printf( ch, "[Area name: %s] ", ch->in_room->area->name );
if ( ch->level >= LEVEL_CREATOR )
ch_printf( ch, "[Area filename: %s]\n\r", ch->in_room->area->filename );
else
send_to_char( "\n\r", ch );
}
set_char_color( AT_RMDESC, ch );
/*
}
else
{*/
if ( !IS_NPC(ch) && xIS_SET(ch->act, PLR_AUTOMAP) ) /* maps */
{
do_mapper(ch, "7");
return;
}
/* set_char_color( AT_RMNAME, ch );
send_to_char( ch->in_room->name, ch );
*/ send_to_char( "\n\r", ch );
if ( !IS_NPC(ch) && !xIS_SET(ch->act, PLR_BRIEF) )
{
set_char_color( AT_RMDESC, ch );
send_to_char( ch->in_room->description, ch );
}
}
if ( !IS_NPC(ch) && xIS_SET(ch->act, PLR_AUTOEXIT) )
do_exits( ch, "auto" );
show_list_to_char( ch->in_room->first_content, ch, FALSE, FALSE );
show_char_to_char( ch->in_room->first_person, ch );
return;
}
if ( !str_cmp( arg1, "under" ) )
{
int count;
/* 'look under' */
if ( arg2[0] == '\0' )
{
send_to_char( "Look beneath 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;
}
if ( !CAN_WEAR( obj, ITEM_TAKE ) && ch->level < sysdata.level_getobjnotake )
{
send_to_char( "You can't seem to get a grip on it.\n\r", ch );
return;
}
if ( ch->carry_weight + obj->weight > can_carry_w( ch ) )
{
send_to_char( "It's too heavy for you to look under.\n\r", ch );
return;
}
count = obj->count;
obj->count = 1;
act( AT_PLAIN, "You lift $p and look beneath it:", ch, obj, NULL, TO_CHAR );
act( AT_PLAIN, "$n lifts $p and looks beneath it:", ch, obj, NULL, TO_ROOM );
obj->count = count;
if ( IS_OBJ_STAT( obj, ITEM_COVERING ) )
show_list_to_char( obj->first_content, ch, TRUE, TRUE );
else
send_to_char( "Nothing.\n\r", ch );
if( EXA_prog_trigger )
oprog_examine_trigger( ch, obj );
return;
}
if ( !str_cmp( arg1, "i" ) || !str_cmp( arg1, "in" ) )
{
int count;
/* '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 );
if( EXA_prog_trigger )
oprog_examine_trigger( ch, obj );
break;
}
/* exam addition for the new liquidtable -Nopey */
{
if (obj->value[2] > 17)
obj->value[2] = 17;
LIQ_TABLE *liq = get_liq_vnum(obj->value[2]);
ch_printf(ch, "It's %s full of a %s liquid.",
obj->value[1] < obj->value[0] / 4 ? "less than" :
obj->value[1] < 3 * obj->value[0] / 4 ? "about" : "more than",
liq->color );
}
if( EXA_prog_trigger )
oprog_examine_trigger( ch, obj );
break;
case ITEM_PORTAL:
for ( pexit = ch->in_room->first_exit; pexit; pexit = pexit->next )
{
if ( pexit->vdir == DIR_PORTAL
&& IS_SET(pexit->exit_info, EX_PORTAL) )
{
if ( room_is_private( pexit->to_room ) && ch->level < sysdata.level_override_private )
{
set_char_color( AT_WHITE, ch );
send_to_char( "The room ahead is private!\n\r", ch );
return;
}
if( IS_EXIT_FLAG( pexit, EX_OVERLAND ) )
{
original = ch->in_room;
enter_map( ch, pexit->x, pexit->y, -1 );
leave_map( ch, NULL, original );
}
else
{
original = ch->in_room;
char_from_room( ch );
char_to_room( ch, pexit->to_room );
do_look( ch, "auto" );
char_from_room( ch );
char_to_room( ch, original );
}
return;
}
}
send_to_char( "You see swirling chaos...\n\r", ch );
break;
case ITEM_CONTAINER:
case ITEM_QUIVER:
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;
}
case ITEM_KEYRING:
count = obj->count;
obj->count = 1;
if ( obj->item_type == ITEM_CONTAINER )
act( AT_PLAIN, "$p contains:", ch, obj, NULL, TO_CHAR );
else
act( AT_PLAIN, "$p holds:", ch, obj, NULL, TO_CHAR );
obj->count = count;
show_list_to_char( obj->first_content, ch, TRUE, TRUE );
if( EXA_prog_trigger )
oprog_examine_trigger( ch, obj );
break;
}
return;
}
if ( (pdesc=get_extra_descr(arg1, ch->in_room->first_extradesc)) != NULL )
{
send_to_char_color( pdesc, ch );
return;
}
door = get_door(arg1);
if ( (pexit=find_door(ch, arg1, TRUE)) != NULL )
{
if ( IS_SET(pexit->exit_info, EX_CLOSED)
&& !IS_SET(pexit->exit_info, EX_WINDOW) )
{
if ( (IS_SET(pexit->exit_info, EX_SECRET)
|| IS_SET(pexit->exit_info, EX_DIG)) && door != -1 )
send_to_char( "Nothing special there.\n\r", ch );
else
act( AT_PLAIN, "The $d is closed.", ch, NULL, pexit->keyword, TO_CHAR );
return;
}
if ( IS_SET( pexit->exit_info, EX_BASHED ) )
act(AT_RED, "The $d has been bashed from its hinges!",ch, NULL, pexit->keyword, TO_CHAR);
if ( pexit->description && pexit->description[0] != '\0' )
send_to_char( pexit->description, ch );
else
send_to_char( "Nothing special there.\n\r", ch );
/*
* Ability to look into the next room -Thoric
*/
if ( pexit->to_room
&& ( IS_AFFECTED( ch, AFF_SCRYING )
|| ch->class == CLASS_THIEF
|| IS_SET( pexit->exit_info, EX_xLOOK )
|| get_trust(ch) >= LEVEL_IMMORTAL ) )
{
if ( !IS_SET( pexit->exit_info, EX_xLOOK )
&& get_trust( ch ) < LEVEL_IMMORTAL )
{
set_char_color( AT_MAGIC, ch );
send_to_char( "You attempt to scry...\n\r", ch );
/*
* Change by Narn, Sept 96 to allow characters who don't have the
* scry spell to benefit from objects that are affected by scry.
*/
if (!IS_NPC(ch) )
{
int percent = LEARNED(ch, skill_lookup("scry") );
if ( !percent )
{
if ( ch->class == CLASS_THIEF )
percent = 95;
else
percent = 55; /* 95 was too good -Thoric */
}
if ( number_percent( ) > percent )
{
send_to_char( "You fail.\n\r", ch );
return;
}
}
}
if ( room_is_private( pexit->to_room ) && ch->level < sysdata.level_override_private )
{
set_char_color( AT_WHITE, ch );
send_to_char( "The room ahead is private!\n\r", ch );
return;
}
if( IS_EXIT_FLAG( pexit, EX_OVERLAND ) )
{
original = ch->in_room;
enter_map( ch, pexit->x, pexit->y, -1 );
leave_map( ch, NULL, original );
}
else
{
original = ch->in_room;
char_from_room( ch );
char_to_room( ch, pexit->to_room );
do_look( ch, "auto" );
char_from_room( ch );
char_to_room( ch, original );
}
}
return;
}
else
if ( door != -1 )
{
send_to_char( "Nothing special there.\n\r", ch );
return;
}
if ( (victim = get_char_room(ch, arg1)) != NULL )
{
show_char_to_char_1( victim, ch );
return;
}
/* finally fixed the annoying look 2.obj desc bug -Thoric */
number = number_argument( arg1, arg );
for ( cnt = 0, obj = ch->last_carrying; obj; obj = obj->prev_content )
{
if ( can_see_obj( ch, obj ) )
{
if ( (pdesc=get_extra_descr(arg, obj->first_extradesc)) != NULL )
{
if ( (cnt += obj->count) < number )
continue;
send_to_char_color( pdesc, ch );
if( EXA_prog_trigger )
oprog_examine_trigger( ch, obj );
return;
}
if ( (pdesc=get_extra_descr(arg, obj->pIndexData->first_extradesc)) != NULL )
{
if ( (cnt += obj->count) < number )
continue;
send_to_char_color( pdesc, ch );
if( EXA_prog_trigger )
oprog_examine_trigger( ch, obj );
return;
}
if ( nifty_is_name_prefix( arg, obj->name ) )
{
if ( (cnt += obj->count) < number )
continue;
pdesc = get_extra_descr( obj->name, obj->pIndexData->first_extradesc );
if ( !pdesc )
pdesc = get_extra_descr( obj->name, obj->first_extradesc );
if ( !pdesc )
send_to_char_color( "You see nothing special.\r\n", ch );
else
send_to_char_color( pdesc, ch );
if( EXA_prog_trigger )
oprog_examine_trigger( ch, obj );
return;
}
}
}
for ( obj = ch->in_room->last_content; obj; obj = obj->prev_content )
{
if ( can_see_obj( ch, obj ) )
{
if ( (pdesc=get_extra_descr(arg, obj->first_extradesc)) != NULL )
{
if ( (cnt += obj->count) < number )
continue;
send_to_char_color( pdesc, ch );
if( EXA_prog_trigger )
oprog_examine_trigger( ch, obj );
return;
}
if ( (pdesc=get_extra_descr(arg, obj->pIndexData->first_extradesc)) != NULL )
{
if ( (cnt += obj->count) < number )
continue;
send_to_char_color( pdesc, ch );
if( EXA_prog_trigger )
oprog_examine_trigger( ch, obj );
return;
}
if ( nifty_is_name_prefix( arg, obj->name ) )
{
if ( (cnt += obj->count) < number )
continue;
pdesc = get_extra_descr( obj->name, obj->pIndexData->first_extradesc );
if ( !pdesc )
pdesc = get_extra_descr( obj->name, obj->first_extradesc );
if ( !pdesc )
send_to_char( "You see nothing special.\r\n", ch );
else
send_to_char_color( pdesc, ch );
if( EXA_prog_trigger )
oprog_examine_trigger( ch, obj );
return;
}
}
}
send_to_char( "You do not see that here.\n\r", ch );
return;
}
void show_race_line( CHAR_DATA *ch, CHAR_DATA *victim )
{
char buf[MAX_STRING_LENGTH];
int feet, inches;
if ( !IS_NPC(victim) && (victim != ch) )
{
feet = victim->height / 12;
inches = victim->height % 12;
sprintf( buf, "%s is %d'%d\" and weighs %d pounds.\n\r", PERS(victim, ch, FALSE), feet, inches, victim->weight );
send_to_char( buf, ch);
return;
}
if ( !IS_NPC(victim) && (victim == ch) )
{
feet = victim->height / 12;
inches = victim->height % 12;
sprintf( buf, "You are %d'%d\" and weigh %d pounds.\n\r", feet, inches, victim->weight );
send_to_char( buf, ch);
return;
}
}
void show_condition( CHAR_DATA *ch, CHAR_DATA *victim )
{
char buf[MAX_STRING_LENGTH];
int percent;
if ( victim->max_hit > 0 )
percent = ( 100 * victim->hit ) / victim->max_hit;
else
percent = -1;
if ( victim != ch )
{
strcpy( buf, PERS(victim, ch, FALSE) );
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" );
}
else
{
strcpy( buf, "You" );
if ( percent >= 100 )
strcat( buf, " are in perfect health.\n\r" );
else if ( percent >= 90 )
strcat( buf, " are slightly scratched.\n\r");
else if ( percent >= 80 )
strcat( buf, " have a few bruises.\n\r" );
else if ( percent >= 70 )
strcat( buf, " have some cuts.\n\r" );
else if ( percent >= 60 )
strcat( buf, " have several wounds.\n\r" );
else if ( percent >= 50 )
strcat( buf, " have many nasty wounds.\n\r");
else if ( percent >= 40 )
strcat( buf, " are bleeding freely.\n\r" );
else if ( percent >= 30 )
strcat( buf, " are covered in blood.\n\r" );
else if ( percent >= 20 )
strcat( buf, " are leaking guts.\n\r" );
else if ( percent >= 10 )
strcat( buf, " are almost dead.\n\r" );
else
strcat( buf, " are DYING.\n\r" );
}
buf[0] = UPPER(buf[0]);
send_to_char( buf, ch );
return;
}
/* A much simpler version of look, this function will show you only
the condition of a mob or pc, or if used without an argument, the
same you would see if you enter the room and have config +brief.
-- Narn, winter '96
*/
void do_glance( CHAR_DATA *ch, char *argument )
{
char arg1 [MAX_INPUT_LENGTH];
CHAR_DATA *victim;
bool brief;
if ( !ch->desc )
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;
set_char_color( AT_ACTION, ch );
argument = one_argument( argument, arg1 );
if ( arg1[0] == '\0' )
{
if ( xIS_SET(ch->act, PLR_BRIEF) )
brief = TRUE;
else
brief = FALSE;
xSET_BIT( ch->act, PLR_BRIEF );
do_look( ch, "auto" );
if ( !brief )
xREMOVE_BIT(ch->act, PLR_BRIEF);
return;
}
if ( ( victim = get_char_room( ch, arg1 ) ) == NULL )
{
send_to_char( "They're not here.\n\r", ch );
return;
}
else
{
if ( can_see( victim, ch, FALSE ) )
{
act( AT_ACTION, "$n glances at you.", ch, NULL, victim, TO_VICT );
act( AT_ACTION, "$n glances at $N.", ch, NULL, victim, TO_NOTVICT );
}
if ( IS_IMMORTAL( ch ) && victim != ch )
{
if ( IS_NPC( victim ) )
ch_printf( ch, "Mobile #%d '%s' ",
victim->pIndexData->vnum, victim->name );
else
ch_printf( ch, "%s ", victim->name );
ch_printf( ch, "is a level %d %s %s.\n\r",
victim->level,
IS_NPC(victim)?victim->race<MAX_NPC_RACE&&victim->race>=0?
npc_race[victim->race] : "unknown":victim->race<MAX_PC_RACE&&
race_table[victim->race]->race_name&&
race_table[victim->race]->race_name[0] != '\0'?
race_table[victim->race]->race_name:"unknown",
IS_NPC(victim)?victim->class<MAX_NPC_CLASS&&victim->class>=0?
npc_class[victim->class] : "unknown":victim->class<MAX_PC_CLASS&&
class_table[victim->class]->who_name&&
class_table[victim->class]->who_name[0] != '\0'?
class_table[victim->class]->who_name:"unknown");
/* New Change
victim->race<MAX_NPC_RACE&&victim->race>=0?npc_race[victim->race] : "unknown",
victim->class<MAX_NPC_CLASS&&victim->class>=0?npc_class[victim->class] : "unknown" );
*/
}
show_condition( ch, victim );
return;
}
return;
}
void do_examine( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
char arg[MAX_INPUT_LENGTH];
OBJ_DATA *obj;
BOARD_DATA *board;
sh_int dam;
if ( !argument )
{
bug( "do_examine: null argument.", 0);
return;
}
if ( !ch )
{
bug( "do_examine: null ch.", 0);
return;
}
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
send_to_char( "Examine what?\n\r", ch );
return;
}
EXA_prog_trigger = FALSE;
do_look( ch, arg );
EXA_prog_trigger = TRUE;
/*
* Support for looking at boards, checking equipment conditions,
* and support for trigger positions by Thoric
*/
if ( (obj = get_obj_here(ch, arg)) != NULL )
{
if ( (board = get_board(obj)) != NULL )
{
if ( board->num_posts )
ch_printf( ch, "There are about %d notes posted here. Type 'note list' to list them.\n\r", board->num_posts );
else
send_to_char( "There aren't any notes posted here.\n\r", ch );
}
switch ( obj->item_type )
{
default:
break;
case ITEM_ARMOR:
if ( obj->value[1] == 0 )
obj->value[1] = obj->value[0];
if ( obj->value[1] == 0 )
obj->value[1] = 1;
dam = (sh_int) ((obj->value[0] * 10) / obj->value[1]);
strcpy( buf, "As you look more closely, you notice that it is ");
if (dam >= 10)
strcat( buf, "in superb condition.");
else if (dam == 9)
strcat( buf, "in very good condition.");
else if (dam == 8)
strcat( buf, "in good shape.");
else if (dam == 7)
strcat( buf, "showing a bit of wear.");
else if (dam == 6)
strcat( buf, "a little run down.");
else if (dam == 5)
strcat( buf, "in need of repair.");
else if (dam == 4)
strcat( buf, "in great need of repair.");
else if (dam == 3)
strcat( buf, "in dire need of repair.");
else if (dam == 2)
strcat( buf, "very badly worn.");
else if (dam == 1)
strcat( buf, "practically worthless.");
else if (dam <= 0)
strcat( buf, "broken.");
strcat( buf, "\n\r" );
send_to_char( buf, ch );
break;
case ITEM_WEAPON:
dam = INIT_WEAPON_CONDITION - obj->value[0];
strcpy( buf, "As you look more closely, you notice that it is ");
if (dam == 0)
strcat( buf, "in superb condition.");
else if (dam == 1)
strcat( buf, "in excellent condition.");
else if (dam == 2)
strcat( buf, "in very good condition.");
else if (dam == 3)
strcat( buf, "in good shape.");
else if (dam == 4)
strcat( buf, "showing a bit of wear.");
else if (dam == 5)
strcat( buf, "a little run down.");
else if (dam == 6)
strcat( buf, "in need of repair.");
else if (dam == 7)
strcat( buf, "in great need of repair.");
else if (dam == 8)
strcat( buf, "in dire need of repair.");
else if (dam == 9)
strcat( buf, "very badly worn.");
else if (dam == 10)
strcat( buf, "practically worthless.");
else if (dam == 11)
strcat( buf, "almost broken.");
else if (dam == 12)
strcat( buf, "broken.");
strcat( buf, "\n\r" );
send_to_char( buf, ch );
break;
case ITEM_COOK:
strcpy( buf, "As you examine it carefully you notice that it " );
dam = obj->value[2];
if (dam >= 3)
strcat( buf, "is burned to a crisp.");
else if (dam == 2)
strcat( buf, "is a little over cooked.");
else if (dam == 1)
strcat( buf, "is perfectly roasted.");
else
strcat( buf, "is raw.");
strcat( buf, "\n\r" );
send_to_char( buf, ch );
case ITEM_FOOD:
if ( obj->timer > 0 && obj->value[1] > 0 )
dam = (obj->timer * 10) / obj->value[1];
else
dam = 10;
if ( obj->item_type == ITEM_FOOD )
strcpy( buf, "As you examine it carefully you notice that it " );
else
strcpy( buf, "Also it " );
if (dam >= 10)
strcat( buf, "is fresh.");
else if (dam == 9)
strcat( buf, "is nearly fresh.");
else if (dam == 8)
strcat( buf, "is perfectly fine.");
else if (dam == 7)
strcat( buf, "looks good.");
else if (dam == 6)
strcat( buf, "looks ok.");
else if (dam == 5)
strcat( buf, "is a little stale.");
else if (dam == 4)
strcat( buf, "is a bit stale.");
else if (dam == 3)
strcat( buf, "smells slightly off.");
else if (dam == 2)
strcat( buf, "smells quite rank.");
else if (dam == 1)
strcat( buf, "smells revolting!");
else if (dam <= 0)
strcat( buf, "is crawling with maggots!");
strcat( buf, "\n\r" );
send_to_char( buf, ch );
break;
case ITEM_SWITCH:
case ITEM_LEVER:
case ITEM_PULLCHAIN:
if ( IS_SET( obj->value[0], TRIG_UP ) )
send_to_char( "You notice that it is in the up position.\n\r", ch );
else
send_to_char( "You notice that it is in the down position.\n\r", ch );
break;
case ITEM_BUTTON:
if ( IS_SET( obj->value[0], TRIG_UP ) )
send_to_char( "You notice that it is depressed.\n\r", ch );
else
send_to_char( "You notice that it is not depressed.\n\r", ch );
break;
case ITEM_CORPSE_PC:
case ITEM_CORPSE_NPC:
{
sh_int timerfrac = obj->timer;
if ( obj->item_type == ITEM_CORPSE_PC )
timerfrac = (int)obj->timer / 8 + 1;
switch (timerfrac)
{
default:
send_to_char( "This corpse has recently been slain.\n\r", ch );
break;
case 4:
send_to_char( "This corpse was slain a little while ago.\n\r", ch );
break;
case 3:
send_to_char( "A foul smell rises from the corpse, and it is covered in flies.\n\r", ch );
break;
case 2:
send_to_char( "A writhing mass of maggots and decay, you can barely go near this corpse.\n\r", ch );
break;
case 1:
case 0:
send_to_char( "Little more than bones, there isn't much left of this corpse.\n\r", ch );
break;
}
}
case ITEM_CONTAINER:
if ( IS_OBJ_STAT( obj, ITEM_COVERING ) )
break;
case ITEM_DRINK_CON:
case ITEM_QUIVER:
send_to_char( "When you look inside, you see:\n\r", ch );
case ITEM_KEYRING:
EXA_prog_trigger = FALSE;
sprintf( buf, "in %s",arg );
do_look( ch, buf );
EXA_prog_trigger = TRUE;
break;
}
if ( IS_OBJ_STAT( obj, ITEM_COVERING ) )
{
EXA_prog_trigger = FALSE;
sprintf( buf, "under %s", arg );
do_look( ch, buf );
EXA_prog_trigger = TRUE;
}
oprog_examine_trigger( ch, obj );
if ( char_died(ch) || obj_extracted(obj) )
return;
check_for_trap( ch, obj, TRAP_EXAMINE );
}
return;
}
void do_exits( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
EXIT_DATA *pexit;
bool found, closed=FALSE, locked=FALSE, DT=FALSE;
bool fAuto;
int spaces;
set_char_color( AT_EXITS, ch );
fAuto = !str_cmp( argument, "auto" );
if ( !check_blind(ch) )
return;
strcpy( buf, fAuto ? "&WExits:" : "&WObvious exits:\n\r" );
found = FALSE;
for ( pexit = ch->in_room->first_exit; pexit; pexit = pexit->next )
{
if ( pexit->to_room
&& !IS_SET(pexit->exit_info, EX_SECRET)
&& (!IS_SET(pexit->exit_info, EX_WINDOW)
|| IS_SET(pexit->exit_info, EX_ISDOOR))
&& !IS_SET(pexit->exit_info, EX_HIDDEN) )
{
found = TRUE;
closed = IS_SET(pexit->exit_info, EX_CLOSED);
locked = (IS_SET(pexit->exit_info, EX_LOCKED) || IS_SET(pexit->exit_info, EX_BOLTED) );
DT = ((IS_IMMORTAL(ch) || IS_AFFECTED(ch, AFF_DETECTTRAPS)) && xIS_SET(pexit->to_room->room_flags, ROOM_DEATH));
if ( fAuto )
{
sprintf( buf, "%s %s" "%s" "&W" "%s", buf,
DT? "&R***" : !closed ? "" : locked ? "&R[&W" : "[",
DT ? strupper(dir_name[pexit->vdir]): dir_name[pexit->vdir],
DT? "&R***&W" : !closed ? "" : locked ? "&R]&W" : "]");
}
else
{
/* I don't want to underline spaces, so I'll calculate the number we need */
spaces = 5 - strlen (dir_name[pexit->vdir]);
if (spaces < 0)
spaces = 0;
sprintf( buf + strlen(buf), "%s" "%*s - %s\n\r",
capitalize( dir_name[pexit->vdir] ),
spaces, /* number of spaces */
"",
DT ? "&RYou sense an aura of imminent doom this way&W" : locked ? "&R[&WClosed and Locked/Barred&R]&W" : closed ? "[Closed]" : room_is_dark( pexit->to_room ) ? "Too dark to tell" : pexit->to_room->name );
}
}
}
if ( !found )
strcat( buf, fAuto ? " none.\n\r" : "None.\n\r" );
else
if ( fAuto )
strcat( buf, ".\n\r" );
send_to_char( buf, ch );
return;
}
char * const day_name [] =
{
"Monday", "Tuesday", "Wedensday", "Thursday", "Friday",
"Saturday", "Sunday"
};
char * const month_name [] =
{
"January", "Febuary", "March", "April",
"May", "June", "July", "August", "September",
"October", "November", "December"
};
void do_time( CHAR_DATA *ch, char *argument )
{
extern char str_boot_time[];
char *suf;
int day;
day = time_info.day + 1;
if ( day > 4 && day < 20 )
suf = "th";
else if ( day % 10 == 1 )
suf = "st";
else if ( day % 10 == 2 )
suf = "nd";
else if ( day % 10 == 3 )
suf = "rd";
else
suf = "th";
set_char_color( AT_YELLOW, ch );
ch_printf( ch,
"It is %d o'clock %s, %s the %d%s of %s in the year %d.\n\r"
"The mud started up at: %s\r"
"The system time (E.S.T.): %s\r",
(time_info.hour % 12 == 0) ? 12 : time_info.hour % 12,
time_info.hour >= 12 ? "pm" : "am",
day_name[day % 7],
day, suf,
month_name[time_info.month],
time_info.year,
str_boot_time,
(char *) ctime( ¤t_time ));
if( sysdata.CLEANPFILES )
ch_printf( ch, "\n\rNext pfile cleanup is scheduled for: %s\n\r", (char *)ctime( &new_pfile_time_t ) );
return;
}
/*
* Produce a description of the weather based on area weather using
* the following sentence format:
* <combo-phrase> and <single-phrase>.
* Where the combo-phrase describes either the precipitation and
* temperature or the wind and temperature. The single-phrase
* describes either the wind or precipitation depending upon the
* combo-phrase.
* Last Modified: July 31, 1997
* Fireblade - Under Construction
*/
void do_weather(CHAR_DATA *ch, char *argument)
{
char *combo, *single;
char buf[MAX_INPUT_LENGTH];
int temp, precip, wind;
if( !IS_PLR_FLAG( ch, PLR_ONMAP ) )
{
if ( !xIS_OUTSIDE(ch) || INDOOR_SECTOR(ch->in_room->sector_type) )
{
send_to_char( "You can't see the sky from here.\n\r", ch );
return;
}
}
if ( !xIS_OUTSIDE(ch) )
{
ch_printf(ch, "You can't see the sky from here.\n\r");
return;
}
temp = (ch->in_room->area->weather->temp + 3*weath_unit - 1)/
weath_unit;
precip = (ch->in_room->area->weather->precip + 3*weath_unit - 1)/
weath_unit;
wind = (ch->in_room->area->weather->wind + 3*weath_unit - 1)/
weath_unit;
if ( precip >= 3 )
{
combo = preciptemp_msg[precip][temp];
single = wind_msg[wind];
}
else
{
combo = windtemp_msg[wind][temp];
single = precip_msg[precip];
}
sprintf(buf, "%s and %s.\n\r", combo, single);
set_char_color(AT_BLUE, ch);
ch_printf(ch, buf);
}
/*
* Moved into a separate function so it can be used for other things
* ie: online help editing -Thoric
*/
HELP_DATA *get_help( CHAR_DATA *ch, char *argument )
{
char argall[MAX_INPUT_LENGTH];
char argone[MAX_INPUT_LENGTH];
char argnew[MAX_INPUT_LENGTH];
HELP_DATA *pHelp;
int lev;
if ( argument[0] == '\0' )
argument = "summary";
if ( isdigit(argument[0]) )
{
lev = number_argument( argument, argnew );
argument = argnew;
}
else
lev = -2;
/*
* Tricky argument handling so 'help a b' doesn't match a.
*/
argall[0] = '\0';
while ( argument[0] != '\0' )
{
argument = one_argument( argument, argone );
if ( argall[0] != '\0' )
strcat( argall, " " );
strcat( argall, argone );
}
for ( pHelp = first_help; pHelp; pHelp = pHelp->next )
{
if ( pHelp->level > get_trust( ch ) )
continue;
if ( lev != -2 && pHelp->level != lev )
continue;
if ( is_name( argall, pHelp->keyword ) )
return pHelp;
}
return NULL;
}
/*
* LAWS command
*/
void do_laws( CHAR_DATA *ch, char *argument )
{
char buf[1024];
if ( argument == NULL)
do_help( ch, "laws" );
else
{
sprintf( buf, "law %s", argument );
do_help( ch, buf );
}
}
// Ranks by number of matches between two whole words. Coded for the Similar Helpfiles
// Snippet by Senir.
sh_int str_similarity( const char *astr, const char *bstr )
{
sh_int matches=0;
if (!astr || !bstr)
return matches;
for ( ; *astr; astr++)
{
if ( LOWER(*astr) == LOWER(*bstr) )
matches++;
if (++bstr == '\0')
return matches;
}
return matches;
}
// Ranks by number of matches until there's a nonmatching character between two words.
// Coded for the Similar Helpfiles Snippet by Senir.
sh_int str_prefix_level( const char *astr, const char *bstr )
{
sh_int matches=0;
if (!astr || !bstr)
return matches;
for ( ; *astr; astr++)
{
if ( LOWER(*astr) == LOWER(*bstr) )
matches++;
else
return matches;
if (++bstr == '\0')
return matches;
}
return matches;
}
// Main function of Similar Helpfiles Snippet by Senir. It loops through all of the
// helpfiles, using the string matching function defined to find the closest matching
// helpfiles to the argument. It then checks for singles. Then, if matching helpfiles
// are found at all, it loops through and prints out the closest matching helpfiles.
// If its a single(there's only one), it opens the helpfile.
void similar_help_files(CHAR_DATA *ch, char *argument)
{
HELP_DATA *pHelp=NULL;
char buf[MAX_STRING_LENGTH];
char *extension;
sh_int lvl=0;
bool single=FALSE;
send_to_pager_color( "&C&BSimilar Help Files:\n\r", ch);
for ( pHelp = first_help; pHelp; pHelp=pHelp->next)
{
buf[0]='\0';
extension=pHelp->keyword;
if (pHelp->level > get_trust(ch))
continue;
while ( extension[0] != '\0' )
{
extension= one_argument(extension, buf);
if ( str_similarity(argument, buf) > lvl)
{
lvl=str_similarity(argument, buf);
single=TRUE;
}
else if ( str_similarity(argument, buf) == lvl && lvl > 0)
{
single=FALSE;
}
}
}
if (lvl==0)
{
send_to_pager_color( "&C&GNo similar help files.\n\r", ch);
return;
}
for ( pHelp = first_help; pHelp; pHelp=pHelp->next)
{
buf[0]='\0';
extension=pHelp->keyword;
while ( extension[0] != '\0' )
{
extension=one_argument(extension, buf);
if ( str_similarity(argument, buf) >= lvl
&& pHelp->level <= get_trust(ch))
{
if (single)
{
send_to_pager_color( "&C&GOpening only similar helpfile.&C\n\r", ch);
do_help( ch, buf);
return;
}
pager_printf_color(ch, "&C&G %s\n\r", pHelp->keyword);
break;
}
}
}
return;
}
/*
* Now this is cleaner
*/
void do_help( CHAR_DATA *ch, char *argument )
{
HELP_DATA *pHelp;
set_pager_color( AT_HELP, ch );
if ( (pHelp = get_help( ch, argument )) == NULL )
{
// Looks better printing out the missed argument before going to similar
// helpfiles. - Senir
pager_printf_color( ch, "&C&wNo help on \'%s\' found.\n\r", argument );
similar_help_files(ch, argument);
return;
}
/* Make newbies do a help start. --Shaddai */
if ( !IS_NPC(ch) && !str_cmp( argument, "start" ) )
SET_BIT(ch->pcdata->flags, PCFLAG_HELPSTART);
set_pager_color( AT_HELP, ch );
if ( pHelp->level >= 0 && str_cmp( argument, "imotd" ) )
{
send_to_pager( pHelp->keyword, ch );
send_to_pager( "\n\r", ch );
}
/*
* Strip leading '.' to allow initial blanks.
*/
if ( pHelp->text[0] == '.' )
send_to_pager_color( pHelp->text+1, ch );
else
send_to_pager_color( pHelp->text , ch );
return;
}
void do_news( CHAR_DATA *ch, char *argument )
{
set_pager_color( AT_NOTE, ch );
do_help( ch, "news" );
}
extern char * help_greeting; /* so we can edit the greeting online */
/*
* Help editor -Thoric
*/
void do_hedit( CHAR_DATA *ch, char *argument )
{
HELP_DATA *pHelp;
if ( !ch->desc )
{
send_to_char( "You have no descriptor.\n\r", ch );
return;
}
switch( ch->substate )
{
default:
break;
case SUB_HELP_EDIT:
if ( (pHelp = ch->dest_buf) == NULL )
{
bug( "hedit: sub_help_edit: NULL ch->dest_buf", 0 );
stop_editing( ch );
return;
}
if ( help_greeting == pHelp->text )
help_greeting = NULL;
STRFREE( pHelp->text );
pHelp->text = copy_buffer( ch );
if ( !help_greeting )
help_greeting = pHelp->text;
stop_editing( ch );
return;
}
if ( (pHelp = get_help(ch, argument)) == NULL ) /* new help */
{
HELP_DATA *tHelp;
char argnew[MAX_INPUT_LENGTH];
int lev;
bool new_help = TRUE;
for ( tHelp=first_help; tHelp; tHelp = tHelp->next )
if ( !str_cmp( argument, tHelp->keyword) )
{
pHelp = tHelp;
new_help = FALSE;
break;
}
if ( new_help )
{
if ( isdigit(argument[0]) )
{
lev = number_argument( argument, argnew );
argument = argnew;
}
else
lev = get_trust(ch);
CREATE( pHelp, HELP_DATA, 1 );
pHelp->keyword = STRALLOC( strupper(argument) );
pHelp->text = STRALLOC( "" );
pHelp->level = lev;
add_help( pHelp );
}
}
ch->substate = SUB_HELP_EDIT;
ch->dest_buf = pHelp;
start_editing( ch, pHelp->text );
}
/*
* Stupid leading space muncher fix -Thoric
*/
char *help_fix( char *text )
{
char *fixed;
if ( !text )
return "";
fixed = strip_cr(text)
;
if ( fixed[0] == ' ' )
fixed[0]
= '.';
return fixed;
}
void do_hset( CHAR_DATA *ch, char *argument )
{
HELP_DATA *pHelp;
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
smash_tilde( argument );
argument = one_argument( argument, arg1 );
if ( arg1[0] == '\0' )
{
send_to_char( "Syntax: hset <field> [value] [help page]\n\r", ch );
send_to_char( "\n\r", ch );
send_to_char( "Field being one of:\n\r", ch );
send_to_char( " level keyword remove save\n\r", ch );
return;
}
if ( !str_cmp( arg1, "save" ) )
{
FILE *fpout;
log_string_plus( "Saving help.are...", LOG_NORMAL, LEVEL_GREATER );
rename( "help.are", "help.are.bak" );
fclose( fpReserve );
if ( ( fpout = fopen( "help.are", "w" ) ) == NULL )
{
bug( "hset save: fopen", 0 );
perror( "help.are" );
fpReserve = fopen( NULL_FILE, "r" );
return;
}
fprintf( fpout, "#HELPS\n\n" );
for ( pHelp = first_help; pHelp; pHelp = pHelp->next )
fprintf( fpout, "%d %s~\n%s~\n\n",
pHelp->level, pHelp->keyword, help_fix(pHelp->text) );
fprintf( fpout, "0 $~\n\n\n#$\n" );
fclose( fpout );
fpReserve = fopen( NULL_FILE, "r" );
send_to_char( "Saved.\n\r", ch );
return;
}
if ( str_cmp( arg1, "remove" ) )
argument = one_argument( argument, arg2 );
if ( (pHelp = get_help(ch, argument)) == NULL )
{
send_to_char( "Cannot find help on that subject.\n\r", ch );
return;
}
if ( !str_cmp( arg1, "remove" ) )
{
UNLINK( pHelp, first_help, last_help, next, prev );
STRFREE( pHelp->text );
STRFREE( pHelp->keyword );
DISPOSE( pHelp );
send_to_char( "Removed.\n\r", ch );
return;
}
if ( !str_cmp( arg1, "level" ) )
{
pHelp->level = atoi( arg2 );
send_to_char( "Done.\n\r", ch );
return;
}
if ( !str_cmp( arg1, "keyword" ) )
{
STRFREE( pHelp->keyword );
pHelp->keyword = STRALLOC( strupper(arg2) );
send_to_char( "Done.\n\r", ch );
return;
}
do_hset( ch, "" );
}
void do_hl( CHAR_DATA *ch, char *argument )
{
send_to_char( "If you want to use HLIST, spell it out.\n\r", ch );
return;
}
/*
* Show help topics in a level range -Thoric
* Idea suggested by Gorog
* prefix keyword indexing added by Fireblade
*/
void do_hlist( CHAR_DATA *ch, char *argument )
{
int min, max, minlimit, maxlimit, cnt;
char arg[MAX_INPUT_LENGTH];
HELP_DATA *help;
bool minfound, maxfound;
char *idx;
maxlimit = get_trust(ch);
minlimit = maxlimit >= LEVEL_GREATER ? -1 : 0;
min = minlimit;
max = maxlimit;
idx = NULL;
minfound = FALSE;
maxfound = FALSE;
for ( argument = one_argument(argument, arg); arg[0] != '\0';
argument = one_argument(argument, arg))
{
if( !isdigit(arg[0]) )
{
if ( idx )
{
set_char_color(AT_GREEN, ch);
ch_printf(ch, "You may only use a single keyword to index the list.\n\r");
return;
}
idx = STRALLOC(arg);
}
else
{
if ( !minfound )
{
min = URANGE(minlimit, atoi(arg), maxlimit);
minfound = TRUE;
}
else
if ( !maxfound )
{
max = URANGE(minlimit, atoi(arg), maxlimit);
maxfound = TRUE;
}
else
{
set_char_color(AT_GREEN, ch);
ch_printf(ch, "You may only use two level limits.\n\r");
return;
}
}
}
if ( min > max )
{
int temp = min;
min = max;
max = temp;
}
set_pager_color( AT_GREEN, ch );
pager_printf( ch, "Help Topics in level range %d to %d:\n\r\n\r", min, max );
for ( cnt = 0, help = first_help; help; help = help->next )
if ( help->level >= min && help->level <= max
&& (!idx || nifty_is_name_prefix(idx, help->keyword)) )
{
pager_printf( ch, " %3d %s\n\r", help->level, help->keyword );
++cnt;
}
if ( cnt )
pager_printf( ch, "\n\r%d pages found.\n\r", cnt );
else
send_to_char( "None found.\n\r", ch );
if ( idx )
STRFREE(idx);
return;
}
/*
* New do_who with WHO REQUEST, clan, race and homepage support. -Thoric
*
* Latest version of do_who eliminates redundant code by using linked lists.
* Shows imms separately, indicates guest and retired immortals.
* Narn, Oct/96
*
* Who group by Altrag, Feb 28/97
*/
struct whogr_s
{
struct whogr_s *next;
struct whogr_s *follower;
struct whogr_s *l_follow;
DESCRIPTOR_DATA *d;
int indent;
}
*first_whogr, *last_whogr;
struct whogr_s *find_whogr(DESCRIPTOR_DATA *d, struct whogr_s *first)
{
struct whogr_s *whogr, *whogr_t;
for (whogr = first; whogr; whogr = whogr->next)
if (whogr->d == d)
return whogr;
else if (whogr->follower && (whogr_t = find_whogr(d, whogr->follower)))
return whogr_t;
return NULL;
}
void indent_whogr(CHAR_DATA *looker, struct whogr_s *whogr, int ilev)
{
for ( ; whogr; whogr = whogr->next )
{
if (whogr->follower)
{
int nlev = ilev;
CHAR_DATA *wch =
(whogr->d->original ? whogr->d->original : whogr->d->character);
if (can_see(looker, wch, TRUE) && !IS_IMMORTAL(wch))
nlev += 3;
indent_whogr(looker, whogr->follower, nlev);
}
whogr->indent = ilev;
}
}
/* This a great big mess to backwards-structure the ->leader character
fields */
void create_whogr(CHAR_DATA *looker)
{
DESCRIPTOR_DATA *d;
CHAR_DATA *wch;
struct whogr_s *whogr, *whogr_t;
int dc = 0, wc = 0;
while ((whogr = first_whogr) != NULL)
{
first_whogr = whogr->next;
DISPOSE(whogr);
}
first_whogr = last_whogr = NULL;
/* Link in the ones without leaders first */
for (d = last_descriptor; d; d = d->prev)
{
if (d->connected != CON_PLAYING && d->connected != CON_EDITING)
continue;
++dc;
wch = (d->original ? d->original : d->character);
if (!wch->leader || wch->leader == wch || !wch->leader->desc ||
IS_NPC(wch->leader) || IS_IMMORTAL(wch) || IS_IMMORTAL(wch->leader))
{
CREATE(whogr, struct whogr_s, 1);
if (!last_whogr)
first_whogr = last_whogr = whogr;
else
{
last_whogr->next = whogr;
last_whogr = whogr;
}
whogr->next = NULL;
whogr->follower = whogr->l_follow = NULL;
whogr->d = d;
whogr->indent = 0;
++wc;
}
}
/* Now for those who have leaders.. */
while (wc < dc)
for (d = last_descriptor; d; d = d->prev)
{
if (d->connected != CON_PLAYING && d->connected != CON_EDITING)
continue;
if (find_whogr(d, first_whogr))
continue;
wch = (d->original ? d->original : d->character);
if (wch->leader && wch->leader != wch && wch->leader->desc &&
!IS_NPC(wch->leader) && !IS_IMMORTAL(wch) &&
!IS_IMMORTAL(wch->leader) &&
(whogr_t = find_whogr(wch->leader->desc, first_whogr)))
{
CREATE(whogr, struct whogr_s, 1);
if (!whogr_t->l_follow)
whogr_t->follower = whogr_t->l_follow = whogr;
else
{
whogr_t->l_follow->next = whogr;
whogr_t->l_follow = whogr;
}
whogr->next = NULL;
whogr->follower = whogr->l_follow = NULL;
whogr->d = d;
whogr->indent = 0;
++wc;
}
}
/* Set up indentation levels */
indent_whogr(looker, first_whogr, 0);
/* And now to linear link them.. */
for (whogr_t = NULL, whogr = first_whogr; whogr; )
if (whogr->l_follow)
{
whogr->l_follow->next = whogr;
whogr->l_follow = NULL;
if (whogr_t)
whogr_t->next = whogr = whogr->follower;
else
first_whogr = whogr = whogr->follower;
}
else
{
whogr_t = whogr;
whogr = whogr->next;
}
}
void do_who( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
char clan_name[MAX_INPUT_LENGTH];
char council_name[MAX_INPUT_LENGTH];
char invis_str[MAX_INPUT_LENGTH];
char char_name[MAX_INPUT_LENGTH];
char *extra_title;
char class_text[MAX_INPUT_LENGTH];
char const *sex;
char const *race;
struct whogr_s *whogr, *whogr_p;
DESCRIPTOR_DATA *d;
int iClass, iRace;
int iLevelLower;
int iLevelUpper;
int nNumber;
int nMatch;
bool rgfClass[MAX_CLASS];
bool rgfRace[MAX_RACE];
bool fClassRestrict;
bool fRaceRestrict;
bool fImmortalOnly;
bool fLeader;
bool fPkill;
bool fShowHomepage;
bool fClanMatch; /* SB who clan (order),who guild, and who council */
bool fCouncilMatch;
bool fDeityMatch;
bool fGroup;
CLAN_DATA *pClan = NULL;
COUNCIL_DATA *pCouncil = NULL;
DEITY_DATA *pDeity = NULL;
FILE *whoout = NULL;
/*
#define WT_IMM 0;
#define WT_MORTAL 1;
#define WT_DEADLY 2;
*/
WHO_DATA *cur_who = NULL;
WHO_DATA *next_who = NULL;
WHO_DATA *first_mortal = NULL;
WHO_DATA *first_imm = NULL;
WHO_DATA *first_deadly = NULL;
WHO_DATA *first_grouped = NULL;
WHO_DATA *first_groupwho = NULL;
/*
* Set default arguments.
*/
iLevelLower = 0;
iLevelUpper = MAX_LEVEL;
fClassRestrict = FALSE;
fRaceRestrict = FALSE;
fImmortalOnly = FALSE;
fPkill = FALSE;
fShowHomepage = FALSE;
fClanMatch = FALSE; /* SB who clan (order), who guild, who council */
fCouncilMatch = FALSE;
fDeityMatch = FALSE;
fGroup = FALSE; /* Alty who group */
fLeader = FALSE;
for ( iClass = 0; iClass < MAX_CLASS; iClass++ )
rgfClass[iClass] = FALSE;
for ( iRace = 0; iRace < MAX_RACE; iRace++ )
rgfRace[iRace] = FALSE;
#ifdef REQWHOARG
/*
* The who command must have at least one argument because we often
* have up to 500 players on. Too much spam if a player accidentally
* types "who" with no arguments. --Gorog
*/
if ( ch && argument[0] == '\0' )
{
send_to_pager_color(
"\n\r&GYou must specify at least one argument.\n\rUse 'who 1' to view the entire who list.\n\r", ch);
return;
}
#endif
/*
* Parse arguments.
*/
nNumber = 0;
for ( ;; )
{
char arg[MAX_STRING_LENGTH];
argument = one_argument( argument, arg );
if ( arg[0] == '\0' )
break;
if ( is_number( arg ) )
{
switch ( ++nNumber )
{
case 1:
iLevelLower = atoi( arg );
break;
case 2:
iLevelUpper = atoi( arg );
break;
default:
send_to_char( "Only two level numbers allowed.\n\r", ch );
return;
}
}
else
{
if ( strlen(arg) < 3 )
{
send_to_char( "Arguments must be longer than that.\n\r", ch );
return;
}
/*
* Look for classes to turn on.
*/
if ( !str_cmp( arg, "deadly" ) || !str_cmp( arg, "pkill" ) )
fPkill = TRUE;
else
if ( !str_cmp( arg, "imm" ) || !str_cmp( arg, "gods" ) )
fImmortalOnly = TRUE;
else
if ( !str_cmp( arg, "leader" ) )
fLeader = TRUE;
else
if ( !str_cmp( arg, "www" ) )
fShowHomepage = TRUE;
else
if ( !str_cmp( arg, "group" ) && ch )
fGroup = TRUE;
else /* SB who clan (order), guild, council */
if ( ( pClan = get_clan (arg) ) )
fClanMatch = TRUE;
else
if ( ( pCouncil = get_council (arg) ) )
fCouncilMatch = TRUE;
else
if ( ( pDeity = get_deity (arg) ) )
fDeityMatch = TRUE;
else
{
for ( iClass = 0; iClass < MAX_CLASS; iClass++ )
{
if ( !str_cmp( arg, class_table[iClass]->who_name ) )
{
rgfClass[iClass] = TRUE;
break;
}
}
if ( iClass != MAX_CLASS )
fClassRestrict = TRUE;
for ( iRace = 0; iRace < MAX_RACE; iRace++ )
{
if ( !str_cmp( arg, race_table[iRace]->race_name ) )
{
rgfRace[iRace] = TRUE;
break;
}
}
if ( iRace != MAX_RACE )
fRaceRestrict = TRUE;
if ( iClass == MAX_CLASS && iRace == MAX_RACE
&& fClanMatch == FALSE
&& fCouncilMatch == FALSE
&& fDeityMatch == FALSE )
{
send_to_char( "That's not a class, race, order, guild,"
" council or deity.\n\r", ch );
return;
}
}
}
}
/*
* Now find matching chars.
*/
nMatch = 0;
buf[0] = '\0';
if ( ch )
set_pager_color( AT_GREEN, ch );
else
{
if ( fShowHomepage )
whoout = fopen( WEBWHO_FILE, "w" );
else
whoout = fopen( WHO_FILE, "w" );
if ( !whoout )
{
bug( "do_who: cannot open who file!" );
return;
}
}
/* start from last to first to get it in the proper order */
if (fGroup)
{
create_whogr(ch);
whogr = first_whogr;
d = whogr->d;
}
else
{
whogr = NULL;
d = last_descriptor;
}
whogr_p = NULL;
for ( ; d; whogr_p = whogr, whogr = (fGroup ? whogr->next : NULL),
d = (fGroup ? (whogr ? whogr->d : NULL) : d->prev))
{
CHAR_DATA *wch;
char const *class;
if ( (d->connected != CON_PLAYING && d->connected != CON_EDITING)
|| !can_see( ch, d->character, TRUE ) || d->original)
continue;
wch = d->original ? d->original : d->character;
if ( wch->level < iLevelLower
|| wch->level > iLevelUpper
|| ( fPkill && !CAN_PKILL( wch ) )
|| ( fImmortalOnly && wch->level < LEVEL_IMMORTAL )
|| ( fClassRestrict && !rgfClass[wch->class] )
|| ( fRaceRestrict && !rgfRace[wch->race] )
|| ( fClanMatch && ( pClan != wch->pcdata->clan )) /* SB */
|| ( fCouncilMatch && ( pCouncil != wch->pcdata->council )) /* SB */
|| ( fDeityMatch && ( pDeity != wch->pcdata->deity )) )
continue;
if ( fLeader && !(wch->pcdata->council &&
((wch->pcdata->council->head2 &&
!str_cmp(wch->pcdata->council->head2, wch->name)) ||
(wch->pcdata->council->head &&
!str_cmp(wch->pcdata->council->head, wch->name)))) &&
!(wch->pcdata->clan && ((wch->pcdata->clan->deity &&
!str_cmp(wch->pcdata->clan->deity,wch->name) )
|| (wch->pcdata->clan->leader
&& !str_cmp(wch->pcdata->clan->leader, wch->name ) )
|| (wch->pcdata->clan->number1
&& !str_cmp(wch->pcdata->clan->number1, wch->name ) )
|| (wch->pcdata->clan->number2
&& !str_cmp(wch->pcdata->clan->number2, wch->name )))))
continue;
if (fGroup && !wch->leader &&
!IS_SET(wch->pcdata->flags, PCFLAG_GROUPWHO) &&
(!whogr_p || !whogr_p->indent))
continue;
nMatch++;
if ( fShowHomepage
&& wch->pcdata->homepage
&& wch->pcdata->homepage[0] != '\0' )
sprintf( char_name, "<A HREF=\"%s\">%s</A>",
show_tilde( wch->pcdata->homepage ), wch->name );
else
strcpy( char_name, wch->name );
sprintf( class_text, "%s%2d ", NOT_AUTHED(wch) ? "N" : " ", wch->level/*, class_table[wch->class]->who_name */);
class = class_text;
switch ( wch->sex )
{
case SEX_MALE:
sex = "M";
break;
case SEX_FEMALE:
sex = "F";
break;
case SEX_NEUTRAL:
sex = "N";
break;
}
switch ( wch->level )
{
default:
break;
case MAX_LEVEL - 0:
class = " IMP";
break;
case MAX_LEVEL - 1:
class = " Imm";
break;
case MAX_LEVEL - 2:
class = " Imm";
break;
case MAX_LEVEL - 3:
class = " Imm";
break;
case MAX_LEVEL - 4:
class = " Imm";
break;
case MAX_LEVEL - 5:
class = " Imm";
break;
case MAX_LEVEL - 6:
class = " Imm";
break;
case MAX_LEVEL - 7:
class = " Imm";
break;
case MAX_LEVEL - 8:
class = " Imm";
break;
case MAX_LEVEL - 9:
class = " Imm";
break;
case MAX_LEVEL - 10:
class = " Imm";
break;
case MAX_LEVEL - 11:
class = " Imm";
break;
case MAX_LEVEL - 12:
class = " Imm";
break;
case MAX_LEVEL - 13:
class = " Imm";
break;
case MAX_LEVEL - 14:
class = " Imm";
break;
case MAX_LEVEL - 15:
class = " AV";
break;
}
switch ( wch->race )
{
case 0:
race = "Hum";
break;
case 1:
race = "Elf";
break;
case 2:
race = "Dwa";
break;
case 3:
race = "Hal";
break;
case 4:
race = "Pix";
break;
case 5:
race = "Min";
break;
case 6:
race = "Orc";
break;
case 7:
race = "Ogr";
break;
case 8:
race = "Tro";
break;
case 9:
race = "Gia";
break;
case 10:
race = "Git";
break;
case 11:
race = "Dro";
break;
case 12:
race = "Dra";
break;
case 13:
race = "liz";
break;
case 14:
race = "Gno";
break;
}
if ( !str_cmp( wch->name, sysdata.guild_overseer ) )
extra_title = " [Overseer of Guilds]";
else if ( !str_cmp( wch->name, sysdata.guild_advisor ) )
extra_title = " [Advisor to Guilds]";
else
extra_title = "";
if ( IS_RETIRED( wch ) )
class = "Retired";
else if ( IS_GUEST( wch ) )
class = "Guest";
else if ( wch->pcdata->clan
&& !str_cmp( wch->name, wch->pcdata->clan->leader )
&& wch->pcdata->clan->leadrank[0] != '\0' )
class = wch->pcdata->clan->leadrank;
else if ( wch->pcdata->clan
&& !str_cmp( wch->name, wch->pcdata->clan->number1 )
&& wch->pcdata->clan->onerank[0] != '\0' )
class = wch->pcdata->clan->onerank;
else if ( wch->pcdata->clan
&& !str_cmp( wch->name, wch->pcdata->clan->number2 )
&& wch->pcdata->clan->tworank[0] != '\0' )
class = wch->pcdata->clan->tworank;
else if ( wch->pcdata->rank && wch->pcdata->rank[0] != '\0' )
class = wch->pcdata->rank;
if ( wch->pcdata->clan )
{
CLAN_DATA *pclan = wch->pcdata->clan;
if ( pclan->clan_type == CLAN_GUILD )
strcpy( clan_name, " <" );
else
strcpy( clan_name, " (" );
if ( pclan->clan_type == CLAN_ORDER )
{
if ( !str_cmp( wch->name, pclan->deity ) )
strcat( clan_name, "Deity, Order of " );
else
if ( !str_cmp( wch->name, pclan->leader ) )
strcat( clan_name, "Leader, Order of " );
else
if ( !str_cmp( wch->name, pclan->number1 ) )
strcat( clan_name, "Number One, Order of " );
else
if ( !str_cmp( wch->name, pclan->number2 ) )
strcat( clan_name, "Number Two, Order of " );
else
strcat( clan_name, "Order of " );
}
else
if ( pclan->clan_type == CLAN_GUILD )
{
if ( !str_cmp( wch->name, pclan->leader ) )
strcat( clan_name, "Leader, " );
if ( !str_cmp( wch->name, pclan->number1 ) )
strcat( clan_name, "First, " );
if ( !str_cmp( wch->name, pclan->number2 ) )
strcat( clan_name, "Second, " );
}
else
{
if ( !str_cmp( wch->name, pclan->deity ) )
strcat( clan_name, "Deity of " );
else
if ( !str_cmp( wch->name, pclan->leader ) )
strcat( clan_name, "Leader of " );
else
if ( !str_cmp( wch->name, pclan->number1 ) )
strcat( clan_name, "Number One " );
else
if ( !str_cmp( wch->name, pclan->number2 ) )
strcat( clan_name, "Number Two " );
}
strcat( clan_name, pclan->name );
if ( pclan->clan_type == CLAN_GUILD )
strcat( clan_name, ">" );
else
strcat( clan_name, ")" );
}
else
clan_name[0] = '\0';
if ( wch->pcdata->council )
{
strcpy( council_name, " [" );
if ( wch->pcdata->council->head2 == NULL )
{
if (!str_cmp (wch->name, wch->pcdata->council->head))
strcat (council_name, "Head of ");
}
else
{
if (!str_cmp (wch->name, wch->pcdata->council->head)
|| !str_cmp ( wch->name, wch->pcdata->council->head2) )
strcat (council_name, "Co-Head of ");
}
strcat( council_name, wch->pcdata->council_name );
strcat( council_name, "]" );
}
else
council_name[0] = '\0';
if ( xIS_SET(wch->act, PLR_WIZINVIS) )
sprintf( invis_str, "(%d) ", wch->pcdata->wizinvis );
else
invis_str[0] = '\0';
sprintf( buf, "%*s%-3s &W%-10s&D%-20s &B%-3s &P%-1s &Y%-10s&D %d &R%-3s%s%s%s%s%s%s&D\n\r",
(fGroup ? whogr->indent : 0), "",
class, //level
char_name,
wch->pcdata->title,
race,
sex,
wch->in_room->area->name,
wch->remorts,
IS_SET(wch->pcdata->flags, PCFLAG_HELPER) ? "&R[&WHELPER&R]&D " : "",
(wch->desc && wch->desc->connected) ? "[W] " : "",
xIS_SET(wch->act, PLR_AFK) ? "[AFK] " : "",
xIS_SET(wch->act, PLR_ATTACKER) ? "(A) " : "",
xIS_SET(wch->act, PLR_KILLER) ? "(K) " : "",
xIS_SET(wch->act, PLR_THIEF) ? "(T) " : "",
invis_str); //robert
/*
* This is where the old code would display the found player to the ch.
* What we do instead is put the found data into a linked list
*/
/* First make the structure. */
CREATE( cur_who, WHO_DATA, 1 );
cur_who->text = str_dup( buf );
if ( wch->level > 50 && IS_IMMORTAL( wch ) )
cur_who->type = WT_IMM;
else if ( fGroup )
if ( wch->leader || (whogr_p && whogr_p->indent) )
cur_who->type = WT_GROUPED;
else
cur_who->type = WT_GROUPWHO;
else if ( CAN_PKILL( wch ) )
cur_who->type = WT_DEADLY;
else
cur_who->type = WT_MORTAL;
/* Then put it into the appropriate list. */
switch ( cur_who->type )
{
case WT_MORTAL:
cur_who->next = first_mortal;
first_mortal = cur_who;
break;
case WT_DEADLY:
cur_who->next = first_deadly;
first_deadly = cur_who;
break;
case WT_GROUPED:
cur_who->next = first_grouped;
first_grouped = cur_who;
break;
case WT_GROUPWHO:
cur_who->next = first_groupwho;
first_groupwho = cur_who;
break;
case WT_IMM:
cur_who->next = first_imm;
first_imm = cur_who;
break;
}
}
/* Ok, now we have three separate linked lists and what remains is to
* display the information and clean up.
*/
/*
* Two extras now for grouped and groupwho (wanting group). -- Alty
*/
send_to_pager( "\n\r[Lvl][Name]----[Title]-----------[Race][Sex][Loc][Rem]\n\r", ch );
for ( cur_who = first_mortal; cur_who; cur_who = next_who )
{
if ( !ch )
fprintf( whoout, "%s", cur_who->text );
else
send_to_pager( cur_who->text, ch );
next_who = cur_who->next;
DISPOSE( cur_who->text );
DISPOSE( cur_who );
}
if ( first_deadly )
{
if ( !ch )
fprintf( whoout, "%s", "\n\r-------------------------------[ DEADLY CHARACTERS ]-------------------------\n\r\n\r" );
else
send_to_pager( "\n\r-------------------------------[ DEADLY CHARACTERS ]--------------------------\n\r\n\r", ch );
}
for ( cur_who = first_deadly; cur_who; cur_who = next_who )
{
if ( !ch )
fprintf( whoout, "%s", cur_who->text );
else
send_to_pager( cur_who->text, ch );
next_who = cur_who->next;
DISPOSE( cur_who->text );
DISPOSE( cur_who );
}
if (first_grouped)
{
/* if ( !ch )
fprintf( whoout, "%s", "\n\r-----------------------------[ GROUPED CHARACTERS ]---------------------------\n\r\n\r" );
else*/
send_to_pager( "\n\r-----------------------------[ GROUPED CHARACTERS ]---------------------------\n\r\n\r", ch );
}
for ( cur_who = first_grouped; cur_who; cur_who = next_who )
{
/* if ( !ch )
fprintf( whoout, cur_who->text );
else*/
send_to_pager( cur_who->text, ch );
next_who = cur_who->next;
DISPOSE( cur_who->text );
DISPOSE( cur_who );
}
if (first_groupwho)
{
if ( !ch )
fprintf( whoout, "%s", "\n\r-------------------------------[ WANTING GROUP ]------------------------------\n\r\n\r" );
else
send_to_pager( "\n\r-------------------------------[ WANTING GROUP ]------------------------------\n\r\n\r", ch );
}
for ( cur_who = first_groupwho; cur_who; cur_who = next_who )
{
if ( !ch )
fprintf( whoout, "%s", cur_who->text );
else
send_to_pager( cur_who->text, ch );
next_who = cur_who->next;
DISPOSE( cur_who->text );
DISPOSE( cur_who );
}
if ( first_imm )
{
if ( !ch )
fprintf( whoout, "%s", "\n\r-----------------------------------[ IMMORTALS ]-----------------------------\n\r\n\r" );
else
send_to_pager( "\n\r-----------------------------------[ IMMORTALS ]------------------------------\n\r\n\r", ch );
}
for ( cur_who = first_imm; cur_who; cur_who = next_who )
{
if ( !ch )
fprintf( whoout, "%s", cur_who->text );
else
send_to_pager( cur_who->text, ch );
next_who = cur_who->next;
DISPOSE( cur_who->text );
DISPOSE( cur_who );
}
if ( !ch )
{
fprintf( whoout, "%d player%s.\n\r", nMatch, nMatch == 1 ? "" : "s" );
fclose( whoout );
return;
}
set_char_color( AT_YELLOW, ch );
ch_printf( ch, "%d player%s.\n\r", nMatch, nMatch == 1 ? "" : "s" );
return;
}
void do_compare( CHAR_DATA *ch, char *argument )
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
OBJ_DATA *obj1;
OBJ_DATA *obj2;
int value1;
int value2;
char *msg;
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
if ( arg1[0] == '\0' )
{
send_to_char( "Compare what to what?\n\r", ch );
return;
}
if ( ( obj1 = get_obj_carry( ch, arg1 ) ) == NULL )
{
send_to_char( "You do not have that item.\n\r", ch );
return;
}
if ( arg2[0] == '\0' )
{
for ( obj2 = ch->first_carrying; obj2; obj2 = obj2->next_content )
{
if ( obj2->wear_loc != WEAR_NONE
&& can_see_obj( ch, obj2 )
&& obj1->item_type == obj2->item_type
&& ( obj1->wear_flags & obj2->wear_flags & ~ITEM_TAKE) != 0 )
break;
}
if ( !obj2 )
{
send_to_char( "You aren't wearing anything comparable.\n\r", ch );
return;
}
}
else
{
if ( ( obj2 = get_obj_carry( ch, arg2 ) ) == NULL )
{
send_to_char( "You do not have that item.\n\r", ch );
return;
}
}
msg = NULL;
value1 = 0;
value2 = 0;
if ( obj1 == obj2 )
{
msg = "You compare $p to itself. It looks about the same.";
}
else if ( obj1->item_type != obj2->item_type )
{
msg = "You can't compare $p and $P.";
}
else
{
switch ( obj1->item_type )
{
default:
msg = "You can't compare $p and $P.";
break;
case ITEM_ARMOR:
value1 = obj1->value[0];
value2 = obj2->value[0];
break;
case ITEM_WEAPON:
value1 = obj1->value[1] + obj1->value[2];
value2 = obj2->value[1] + obj2->value[2];
break;
}
}
if ( !msg )
{
if ( value1 == value2 )
msg = "$p and $P look about the same.";
else if ( value1 > value2 )
msg = "$p looks better than $P.";
else
msg = "$p looks worse than $P.";
}
act( AT_PLAIN, msg, ch, obj1, obj2, TO_CHAR );
return;
}
void do_where( CHAR_DATA *ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
CHAR_DATA *victim;
DESCRIPTOR_DATA *d;
bool found;
one_argument( argument, arg );
if ( arg[0]!='\0'
&& (victim=get_char_world(ch, arg)) && !IS_NPC(victim)
&& IS_SET(victim->pcdata->flags, PCFLAG_DND)
&& get_trust(ch) < get_trust(victim) )
{
act( AT_PLAIN, "You didn't find any $T.", ch, NULL, arg, TO_CHAR );
return;
}
set_pager_color( AT_PERSON, ch );
if ( arg[0] == '\0' )
{
pager_printf( ch, "\n\rPlayers near you in %s:\n\r", ch->in_room->area->name );
found = FALSE;
for ( d = first_descriptor; d; d = d->next )
if ( (d->connected == CON_PLAYING || d->connected == CON_EDITING )
&& ( victim = d->character ) != NULL
&& !IS_NPC(victim)
&& victim->in_room
&& victim->in_room->area == ch->in_room->area
&& can_see( ch, victim, TRUE )
&& ( get_trust(ch) >= get_trust(victim)
|| !IS_SET(victim->pcdata->flags, PCFLAG_DND) )
) /* if victim has the DND flag ch must outrank them */
{
found = TRUE;
/* if ( CAN_PKILL( victim ) )
set_pager_color( AT_PURPLE, ch );
else
set_pager_color( AT_PERSON, ch );
*/
pager_printf_color( ch, "&P%-13s ", victim->name );
if ( IS_IMMORTAL( victim ) && victim->level > 50 )
send_to_pager_color( "&P(&WImmortal&P)\t", ch );
else if ( CAN_PKILL( victim ) && victim->pcdata->clan
&& victim->pcdata->clan->clan_type != CLAN_ORDER
&& victim->pcdata->clan->clan_type != CLAN_GUILD )
pager_printf_color( ch, "%-18s\t", victim->pcdata->clan->badge );
else if ( CAN_PKILL( victim ) )
send_to_pager_color( "(&wUnclanned&P)\t", ch );
else
send_to_pager( "\t\t\t", ch );
pager_printf_color( ch, "&P%s\n\r", victim->in_room->name );
}
if ( !found )
send_to_char( "None\n\r", ch );
}
else
{
found = FALSE;
for ( victim = first_char; victim; victim = victim->next )
if ( victim->in_room
&& victim->in_room->area == ch->in_room->area
&& !IS_AFFECTED(victim, AFF_HIDE)
&& !IS_AFFECTED(victim, AFF_SNEAK)
&& can_see( ch, victim, TRUE )
&& is_name( arg, victim->name ) )
{
found = TRUE;
pager_printf( ch, "%-28s %s\n\r",
PERS(victim, ch, TRUE), victim->in_room->name );
break;
}
if ( !found )
act( AT_PLAIN, "You didn't find any $T.", ch, NULL, arg, TO_CHAR );
}
return;
}
void do_consider( CHAR_DATA *ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
CHAR_DATA *victim;
char *msg;
int diff;
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
send_to_char( "Consider killing whom?\n\r", ch );
return;
}
if ( ( victim = get_char_room( ch, arg ) ) == NULL )
{
send_to_char( "They're not here.\n\r", ch );
return;
}
if ( victim == ch )
{
send_to_char( "You decide you're pretty sure you could take yourself in a fight.\n\r", ch );
return;
}
diff = victim->level - ch->level;
if ( diff <= -10 )
msg = "You are far more experienced than $N.";
else if ( diff <= -5 )
msg = "$N is not nearly as experienced as you.";
else if ( diff <= -2 )
msg = "You are more experienced than $N.";
else if ( diff <= 1 )
msg = "You are just about as experienced as $N.";
else if ( diff <= 4 )
msg = "You are not nearly as experienced as $N.";
else if ( diff <= 9 )
msg = "$N is far more experienced than you!";
else
msg = "$N would make a great teacher for you!";
act( AT_CONSIDER, msg, ch, NULL, victim, TO_CHAR );
diff = (int) (victim->max_hit - ch->max_hit) / 6;
if ( diff <= -200)
msg = "$N looks like a feather!";
else if ( diff <= -150)
msg = "You could kill $N with your hands tied!";
else if ( diff <= -100)
msg = "Hey! Where'd $N go?";
else if ( diff <= -50)
msg = "$N is a wimp.";
else if ( diff <= 0)
msg = "$N looks weaker than you.";
else if ( diff <= 50)
msg = "$N looks about as strong as you.";
else if ( diff <= 100)
msg = "It would take a bit of luck...";
else if ( diff <= 150)
msg = "It would take a lot of luck, and equipment!";
else if ( diff <= 200)
msg = "Why don't you dig a grave for yourself first?";
else
msg = "$N is built like a TANK!";
act( AT_CONSIDER, msg, ch, NULL, victim, TO_CHAR );
return;
}
/*
* Place any skill types you don't want them to be able to practice
* normally in this list. Separate each with a space.
* (Uses an is_name check). -- Altrag
*/
#define CANT_PRAC "Tongue"
void do_practice( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
int sn;
if ( IS_NPC(ch) )
return;
if ( argument[0] == '\0' )
{
int col;
sh_int lasttype, cnt;
col = cnt = 0;
lasttype = SKILL_SPELL;
set_pager_color( AT_MAGIC, ch );
for ( sn = 0; sn < top_sn; sn++ )
{
if ( !skill_table[sn]->name )
break;
if ( strcmp(skill_table[sn]->name, "reserved") == 0
&& ( IS_IMMORTAL(ch) || CAN_CAST(ch) ) )
{
if ( col % 3 != 0 )
send_to_pager( "\n\r", ch );
// set_pager_color( AT_DGREY, ch );
send_to_pager_color(
" &Y----------------------------------[&CSpells&Y]----------------------------------&D\n\r", ch);
col = 0;
}
if ( skill_table[sn]->type != lasttype )
{
if ( !cnt )
send_to_pager( " (none)\n\r", ch );
else
if ( col % 3 != 0 )
send_to_pager( "&D\n\r", ch );
// set_pager_color( AT_CYAN, ch );
pager_printf_color( ch,
" &Y----------------------------------&C%ss&Y----------------------------------\n\r",
skill_tname[skill_table[sn]->type]);
col = cnt = 0;
}
lasttype = skill_table[sn]->type;
if (!IS_IMMORTAL(ch)
&& ( skill_table[sn]->guild != CLASS_NONE
&& ( !IS_GUILDED(ch)
|| (ch->pcdata->clan->class != skill_table[sn]->guild) ) ) )
continue;
if ( ch->level < skill_table[sn]->skill_level[ch->class]
|| (!IS_IMMORTAL(ch) && skill_table[sn]->skill_level[ch->class] == 0) )
continue;
if ( ch->pcdata->learned[sn] <= 0 && SPELL_FLAG(skill_table[sn], SF_SECRETSKILL) )
continue;
++cnt;
// set_pager_color( AT_ORANGE, ch );
pager_printf( ch, "&c%20.20s", skill_table[sn]->name );
if ( ch->pcdata->learned[sn] > 0 )
set_pager_color( AT_YELLOW, ch );
pager_printf( ch, "&Y %3d%%&D ", ch->pcdata->learned[sn] );
if ( ++col % 3 == 0 )
send_to_pager( "\n\r", ch );
}
if ( col % 3 != 0 )
send_to_pager( "&D\n\r", ch );
set_pager_color( AT_GREEN, ch );
pager_printf( ch, "You have %d practice sessions left.\n\r",
ch->practice );
}
else
{
CHAR_DATA *mob;
int adept;
bool can_prac = TRUE;
if ( !IS_AWAKE(ch) )
{
send_to_char( "In your dreams, or what?\n\r", ch );
return;
}
for ( mob = ch->in_room->first_person; mob; mob = mob->next_in_room )
if ( IS_NPC(mob) && xIS_SET(mob->act, ACT_PRACTICE) )
break;
if ( !mob )
{
send_to_char( "You can't do that here.\n\r", ch );
return;
}
if ( ch->practice <= 0 )
{
act( AT_TELL, "$n tells you 'You must earn some more practice sessions.'",
mob, NULL, ch, TO_VICT );
return;
}
sn = skill_lookup( argument );
if ( ch->pcdata->learned[sn] <= 0 && SPELL_FLAG(skill_table[sn], SF_SECRETSKILL) )
{
send_to_char("$n tells you 'You cannot practice that untill someone teaches you...'", ch);
return;
}
if ( can_prac && ( ( sn == -1 ) || ( !IS_NPC(ch) && ch->level < skill_table[sn]->skill_level[ch->class])))
{
act( AT_TELL, "$n tells you 'You're not ready to learn that yet...'", mob, NULL, ch, TO_VICT );
return;
}
if ( is_name( skill_tname[skill_table[sn]->type], CANT_PRAC ) )
{
act( AT_TELL, "$n tells you 'I do not know how to teach that.'",
mob, NULL, ch, TO_VICT );
return;
}
/*
* Skill requires a special teacher
*/
if ( skill_table[sn]->teachers && skill_table[sn]->teachers[0] != '\0' )
{
sprintf( buf, "%d", mob->pIndexData->vnum );
if ( !is_name( buf, skill_table[sn]->teachers ) )
{
act( AT_TELL, "$n tells you, 'I know not know how to teach that.'",
mob, NULL, ch, TO_VICT );
return;
}
}
/*
* Guild checks - right now, cant practice guild skills - done on
* induct/outcast
*/
/*
if ( !IS_NPC(ch) && !IS_GUILDED(ch)
&& skill_table[sn]->guild != CLASS_NONE)
{
act( AT_TELL, "$n tells you 'Only guild members can use that..'"
mob, NULL, ch, TO_VICT );
return;
}
if ( !IS_NPC(ch) && skill_table[sn]->guild != CLASS_NONE
&& ch->pcdata->clan->class != skill_table[sn]->guild )
{
act( AT_TELL, "$n tells you 'That can not be used by your guild.'"
mob, NULL, ch, TO_VICT );
return;
}
*/
if ( !IS_NPC(ch) && skill_table[sn]->guild != CLASS_NONE)
{
act( AT_TELL, "$n tells you 'That is only for members of guilds...'",
mob, NULL, ch, TO_VICT );
return;
}
/*
* Disabled for now
if ( mob->level < skill_table[sn]->skill_level[ch->class]
|| mob->level < skill_table[sn]->skill_level[mob->class] )
{
act( AT_TELL, "$n tells you 'You must seek another to teach you that...'",
mob, NULL, ch, TO_VICT );
return;
}
*/
adept = class_table[ch->class]->skill_adept * 0.55;
if ( ch->pcdata->learned[sn] >= adept )
{
act( AT_TELL, "$n, You'll have to practice it on your own now...",
ch, NULL, ch, TO_CHAR );
sprintf( buf, "$n tells you, 'I've taught you everything I can about %s.'",
skill_table[sn]->name );
act( AT_TELL, buf, mob, NULL, ch, TO_VICT );
}
else
{
ch->practice--;
ch->pcdata->learned[sn] += int_app[get_curr_int(ch)].learn;
act( AT_ACTION, "You practice $T.",
ch, NULL, skill_table[sn]->name, TO_CHAR );
act( AT_ACTION, "$n practices $T.",
ch, NULL, skill_table[sn]->name, TO_ROOM );
if ( ch->pcdata->learned[sn] >= adept )
{
ch->pcdata->learned[sn] = adept;
act( AT_TELL,
"$n tells you. 'You'll have to practice it on your own now...'",
mob, NULL, ch, TO_VICT );
}
}
}
return;
}
void do_wimpy( CHAR_DATA *ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
int wimpy;
set_char_color( AT_YELLOW, ch );
one_argument( argument, arg );
if ( !str_cmp( arg, "max" ) )
{
if ( IS_PKILL( ch ) )
wimpy = (int) ch->max_hit / 2.25;
else
wimpy = (int) ch->max_hit / 1.2;
}
else
if ( arg[0] == '\0' )
wimpy = (int) ch->max_hit / 5;
else
wimpy = atoi( arg );
if ( wimpy < 0 )
{
send_to_char( "Your courage exceeds your wisdom.\n\r", ch );
return;
}
if ( IS_PKILL( ch ) && wimpy > (int) ch->max_hit / 2.25 )
{
send_to_char( "Such cowardice ill becomes you.\n\r", ch );
return;
}
else if ( wimpy > (int) ch->max_hit / 1.2 )
{
send_to_char( "Such cowardice ill becomes you.\n\r", ch );
return;
}
ch->wimpy = wimpy;
ch_printf( ch, "Wimpy set to %d hit points.\n\r", wimpy );
return;
}
void do_password( CHAR_DATA *ch, char *argument )
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
char *pArg;
char *pwdnew;
char *p;
char cEnd;
if ( IS_NPC(ch) )
return;
/*
* Can't use one_argument here because it smashes case.
* So we just steal all its code. Bleagh.
*/
pArg = arg1;
while ( isspace(*argument) )
argument++;
cEnd = ' ';
if ( *argument == '\'' || *argument == '"' )
cEnd = *argument++;
while ( *argument != '\0' )
{
if ( *argument == cEnd )
{
argument++;
break;
}
*pArg++ = *argument++;
}
*pArg = '\0';
pArg = arg2;
while ( isspace(*argument) )
argument++;
cEnd = ' ';
if ( *argument == '\'' || *argument == '"' )
cEnd = *argument++;
while ( *argument != '\0' )
{
if ( *argument == cEnd )
{
argument++;
break;
}
*pArg++ = *argument++;
}
*pArg = '\0';
if ( arg1[0] == '\0' || arg2[0] == '\0' )
{
send_to_char( "Syntax: password <new> <again>.\n\r", ch );
send_to_char( "Syntax: password <new> <again>.\n\r", ch );
return;
}
/* This should stop all the mistyped password problems --Shaddai */
if ( strcmp( arg1, arg2 ))
{
send_to_char("Passwords don't match try again.\n\r", ch );
return;
}
if ( strlen(arg2) < 5 )
{
send_to_char( "New password must be at least five characters long.\n\r", ch );
return;
}
if (arg1[0] == '!' || arg2[0] == '!')
{
send_to_char( "New password cannot begin with the '!' character.",ch);
return;
}
/*
* No tilde allowed because of player file format.
*/
pwdnew = smaug_crypt( arg2 );
for ( p = pwdnew; *p != '\0'; p++ )
{
if ( *p == '~' )
{
send_to_char( "New password not acceptable, try again.\n\r", ch );
return;
}
}
DISPOSE( ch->pcdata->pwd );
ch->pcdata->pwd = str_dup( pwdnew );
if ( IS_SET(sysdata.save_flags, SV_PASSCHG) )
save_char_obj( ch );
if ( ch->desc && ch->desc->host[0] != '\0' )
sprintf(log_buf, "%s changing password from site %s\n", ch->name, ch->desc->host );
else
sprintf(log_buf, "%s changing thier password with no descriptor!", ch->name);
log_string( log_buf );
send_to_char( "Ok.\n\r", ch );
return;
}
void do_socials( CHAR_DATA *ch, char *argument )
{
int iHash;
int col = 0;
SOCIALTYPE *social;
set_pager_color( AT_PLAIN, ch );
for ( iHash = 0; iHash < 27; iHash++ )
for ( social = social_index[iHash]; social; social = social->next )
{
pager_printf( ch, "%-12s", social->name );
if ( ++col % 6 == 0 )
send_to_pager( "\n\r", ch );
}
if ( col % 6 != 0 )
send_to_pager( "\n\r", ch );
return;
}
void do_commands( CHAR_DATA *ch, char *argument )
{
int col;
bool found;
int hash;
CMDTYPE *command;
col = 0;
set_pager_color( AT_PLAIN, ch );
if ( argument[0] == '\0' )
{
for ( hash = 0; hash < 126; hash++ )
for ( command = command_hash[hash]; command; command = command->next )
if ( command->level < LEVEL_HERO
&& command->level <= get_trust( ch )
&& (command->name[0] != 'm'
|| command->name[1] != 'p') )
{
pager_printf( ch, "%-12s", command->name );
if ( ++col % 6 == 0 )
send_to_pager( "\n\r", ch );
}
if ( col % 6 != 0 )
send_to_pager( "\n\r", ch );
}
else
{
found = FALSE;
for ( hash = 0; hash < 126; hash++ )
for ( command = command_hash[hash]; command; command = command->next )
if ( command->level < LEVEL_HERO
&& command->level <= get_trust( ch )
&& !str_prefix(argument, command->name)
&& (command->name[0] != 'm'
|| command->name[1] != 'p') )
{
pager_printf( ch, "%-12s", command->name );
found = TRUE;
if ( ++col % 6 == 0 )
send_to_pager( "\n\r", ch );
}
if ( col % 6 != 0 )
send_to_pager( "\n\r", ch );
if ( !found )
ch_printf( ch, "No command found under %s.\n\r", argument);
}
return;
}
void do_channels( CHAR_DATA *ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
one_argument( argument, arg );
if ( IS_NPC( ch ) )
return;
if ( arg[0] == '\0' )
{
if ( !IS_NPC(ch) && xIS_SET(ch->act, PLR_SILENCE) )
{
set_char_color( AT_GREEN, ch );
send_to_char( "You are silenced.\n\r", ch );
return;
}
/* Channels everyone sees regardless of affiliation --Blodkai */
send_to_char_color( "\n\r &gPublic channels (severe penalties for abuse)&G:\n\r ", ch );
/*( ch_printf_color( ch, "%s", !IS_SET( ch->deaf, CHANNEL_RACETALK )?
" &G+RACETALK" :
" &g-racetalk" ); */
ch_printf_color( ch, "%s", !IS_SET( ch->deaf, CHANNEL_GOSSIP ) ?
" &G+GOSSIP" :
" &g-gossip" );
ch_printf_color( ch, "%s", !IS_SET( ch->deaf, CHANNEL_OOC ) ?
" &G+OOC" :
" &g-ooc" );
ch_printf_color( ch, "%s", !IS_SET( ch->deaf, CHANNEL_FLAME ) ?
" &G+FLAME" :
" &g-flame" );
ch_printf_color( ch, "%s", !IS_SET( ch->deaf, CHANNEL_SAYTO ) ?
" &G+SAYTO" :
" &g-sayto" );
ch_printf_color( ch, "%s", !IS_SET( ch->deaf, CHANNEL_MUSIC ) ?
" &G+MUSIC" :
" &g-music" );
ch_printf_color( ch, "%s", !IS_SET( ch->deaf, CHANNEL_ASK ) ?
" &G+ASK" :
" &g-ask" );
ch_printf_color( ch, "%s", !IS_SET( ch->deaf, CHANNEL_YELL ) ?
" &G+YELL" :
" &g-yell" );
ch_printf_color( ch, "%s", !IS_SET( ch->deaf, CHANNEL_NEWBIE) ?
" &G+NEWBIE" :
" &g-newbie" );
if ( get_trust( ch ) > 2 && !NOT_AUTHED( ch ) )
ch_printf_color( ch, "%s", !IS_SET( ch->deaf, CHANNEL_AUCTION ) ?
" &G+AUCTION" :
" &g-auction" );
if ( IS_HERO( ch ) )
ch_printf_color( ch, "%s", !IS_SET( ch->deaf, CHANNEL_AVTALK ) ?
" &G+AVATAR" :
" &g-avatar" );
/* For organization channels (orders, clans, guilds, councils) */
send_to_char_color( "\n\r &gPrivate channels (severe penalties for abuse)&G:\n\r ", ch );
ch_printf_color( ch, "%s", !IS_SET( ch->deaf, CHANNEL_TELLS ) ?
" &G+TELLS" :
" &g-tells" );
ch_printf_color( ch, "%s", !IS_SET( ch->deaf, CHANNEL_WHISPER ) ?
" &G+WHISPER" :
" &g-whisper" );
if ( !IS_NPC( ch ) && ch->pcdata->clan )
{
if ( ch->pcdata->clan->clan_type == CLAN_ORDER )
send_to_char_color( !IS_SET( ch->deaf, CHANNEL_ORDER ) ?
" &G+ORDER" : " &g-order", ch );
else if ( ch->pcdata->clan->clan_type == CLAN_GUILD )
send_to_char_color( !IS_SET( ch->deaf, CHANNEL_GUILD ) ?
" &G+GUILD" : " &g-guild", ch );
else
send_to_char_color( !IS_SET( ch->deaf, CHANNEL_CLAN ) ?
" &G+CLAN" : " &g-clan", ch );
}
if ( !IS_NPC( ch ) && ch->pcdata->council )
ch_printf_color( ch, "%s", !IS_SET( ch->deaf, CHANNEL_COUNCIL)?
" &G+COUNCIL" :
" &g-council" );
/* Immortal channels */
if ( IS_IMMORTAL( ch ) )
{
send_to_char_color( "\n\r &gImmortal Channels&G:\n\r ", ch );
send_to_char_color( !IS_SET( ch->deaf, CHANNEL_IMMTALK ) ?
" &G+IMMTALK" : " &g-immtalk", ch );
/* send_to_char_color( !IS_SET( ch->deaf, CHANNEL_PRAY ) ?
" &G+PRAY" : " &g-pray", ch ); */
if ( get_trust( ch ) >= sysdata.muse_level )
send_to_char_color( !IS_SET( ch->deaf, CHANNEL_HIGHGOD ) ?
" &G+MUSE" : " &g-muse", ch );
send_to_char_color( !IS_SET( ch->deaf, CHANNEL_MONITOR ) ?
" &G+MONITOR" : " &g-monitor", ch );
send_to_char_color( !IS_SET( ch->deaf, CHANNEL_AUTH ) ?
" &G+AUTH" : " &g-auth", ch );
}
if ( get_trust( ch ) >= sysdata.log_level )
{
send_to_char_color( !IS_SET( ch->deaf, CHANNEL_LOG ) ?
" &G+LOG" : " &g-log", ch);
send_to_char_color( !IS_SET( ch->deaf, CHANNEL_BUILD) ?
" &G+BUILD" : " &g-build", ch );
send_to_char_color( !IS_SET( ch->deaf, CHANNEL_COMM ) ?
" &G+COMM" : " &g-comm", ch );
send_to_char_color( !IS_SET (ch->deaf, CHANNEL_WARN)
? " &G+WARN" : " &g-warn", ch);
if ( get_trust( ch ) >= sysdata.think_level )
send_to_char_color( !IS_SET( ch->deaf, CHANNEL_HIGH ) ?
" &G+HIGH" : " &g-high", ch );
}
send_to_char( "\n\r", ch );
}
else
{
bool fClear;
bool ClearAll;
int bit;
bit=0;
ClearAll = FALSE;
if ( arg[0] == '+' )
fClear = TRUE;
else if ( arg[0] == '-' )
fClear = FALSE;
else
{
send_to_char( "Channels -channel or +channel?\n\r", ch );
return;
}
if ( !str_cmp( arg+1, "auction" ) )
bit = CHANNEL_AUCTION;
else if ( !str_cmp( arg+1, "traffic" ) )
bit = CHANNEL_TRAFFIC;
else if ( !str_cmp( arg+1, "gossip" ) )
bit = CHANNEL_GOSSIP;
else if ( !str_cmp( arg+1, "clan" ) )
bit = CHANNEL_CLAN;
else if ( !str_cmp( arg+1, "council" ) )
bit = CHANNEL_COUNCIL;
else if ( !str_cmp( arg+1, "guild" ) )
bit = CHANNEL_GUILD;
else if ( !str_cmp( arg+1, "ooc" ) )
bit = CHANNEL_OOC;
else if ( !str_cmp( arg+1, "tells" ) )
bit = CHANNEL_TELLS;
else if ( !str_cmp( arg+1, "immtalk" ) )
bit = CHANNEL_IMMTALK;
else if ( !str_cmp( arg+1, "log" ) )
bit = CHANNEL_LOG;
else if ( !str_cmp( arg+1, "build" ) )
bit = CHANNEL_BUILD;
else if ( !str_cmp( arg+1, "high" ) )
bit = CHANNEL_HIGH;
else if ( !str_cmp( arg+1, "pray" ) )
bit = CHANNEL_PRAY;
else if ( !str_cmp( arg+1, "avatar" ) )
bit = CHANNEL_AVTALK;
else if ( !str_cmp( arg+1, "monitor" ) )
bit = CHANNEL_MONITOR;
else if ( !str_cmp( arg+1, "auth" ) )
bit = CHANNEL_AUTH;
else if ( !str_cmp( arg+1, "newbie" ) )
bit = CHANNEL_NEWBIE;
else if ( !str_cmp( arg+1, "music" ) )
bit = CHANNEL_MUSIC;
else if ( !str_cmp( arg+1, "muse" ) )
bit = CHANNEL_HIGHGOD;
else if ( !str_cmp( arg+1, "ask" ) )
bit = CHANNEL_ASK;
else if ( !str_cmp( arg+1, "shout" ) )
bit = CHANNEL_SHOUT;
else if ( !str_cmp( arg+1, "yell" ) )
bit = CHANNEL_YELL;
else if ( !str_cmp( arg+1, "comm" ) )
bit = CHANNEL_COMM;
else if ( !str_cmp (arg+1, "warn" ) )
bit = CHANNEL_WARN;
else if ( !str_cmp( arg+1, "order" ) )
bit = CHANNEL_ORDER;
else if ( !str_cmp( arg+1, "flame" ) )
bit = CHANNEL_FLAME;
else if ( !str_cmp( arg+1, "sayto" ) )
bit = CHANNEL_SAYTO;
else if ( !str_cmp( arg+1, "whisper" ) )
bit = CHANNEL_WHISPER;
else if ( !str_cmp( arg+1, "racetalk" ) )
bit = CHANNEL_RACETALK;
else if ( !str_cmp( arg+1, "all" ) )
ClearAll = TRUE;
else
{
send_to_char( "Set or clear which channel?\n\r", ch );
return;
}
if (( fClear ) && ( ClearAll ))
{
REMOVE_BIT (ch->deaf, CHANNEL_RACETALK);
REMOVE_BIT (ch->deaf, CHANNEL_AUCTION);
REMOVE_BIT (ch->deaf, CHANNEL_GOSSIP);
REMOVE_BIT (ch->deaf, CHANNEL_OOC);
REMOVE_BIT (ch->deaf, CHANNEL_FLAME);
REMOVE_BIT (ch->deaf, CHANNEL_PRAY);
REMOVE_BIT (ch->deaf, CHANNEL_TRAFFIC);
REMOVE_BIT (ch->deaf, CHANNEL_MUSIC);
REMOVE_BIT (ch->deaf, CHANNEL_ASK);
REMOVE_BIT (ch->deaf, CHANNEL_SHOUT);
REMOVE_BIT (ch->deaf, CHANNEL_YELL);
/* if (ch->pcdata->clan)
REMOVE_BIT (ch->deaf, CHANNEL_CLAN);
if (ch->pcdata->council)
REMOVE_BIT (ch->deaf, CHANNEL_COUNCIL);
if (ch->pcdata->guild)
REMOVE_BIT (ch->deaf, CHANNEL_GUILD);
*/
if (ch->level >= LEVEL_IMMORTAL)
REMOVE_BIT (ch->deaf, CHANNEL_AVTALK);
/*
if (ch->level >= sysdata.log_level )
REMOVE_BIT (ch->deaf, CHANNEL_COMM);
*/
}
else if ((!fClear) && (ClearAll))
{
SET_BIT (ch->deaf, CHANNEL_RACETALK);
SET_BIT (ch->deaf, CHANNEL_AUCTION);
SET_BIT (ch->deaf, CHANNEL_TRAFFIC);
SET_BIT (ch->deaf, CHANNEL_GOSSIP);
SET_BIT (ch->deaf, CHANNEL_OOC);
SET_BIT (ch->deaf, CHANNEL_PRAY);
SET_BIT (ch->deaf, CHANNEL_MUSIC);
SET_BIT (ch->deaf, CHANNEL_ASK);
SET_BIT (ch->deaf, CHANNEL_SHOUT);
SET_BIT (ch->deaf, CHANNEL_FLAME);
SET_BIT (ch->deaf, CHANNEL_YELL);
/* if (ch->pcdata->clan)
SET_BIT (ch->deaf, CHANNEL_CLAN);
if (ch->pcdata->council)
SET_BIT (ch->deaf, CHANNEL_COUNCIL);
if ( IS_GUILDED(ch) )
SET_BIT (ch->deaf, CHANNEL_GUILD);
*/
if (ch->level >= LEVEL_IMMORTAL)
SET_BIT (ch->deaf, CHANNEL_AVTALK);
/*
if (ch->level >= sysdata.log_level)
SET_BIT (ch->deaf, CHANNEL_COMM);
*/
}
else if (fClear)
{
REMOVE_BIT (ch->deaf, bit);
}
else
{
SET_BIT (ch->deaf, bit);
}
send_to_char( "Ok.\n\r", ch );
}
return;
}
/*
* display WIZLIST file -Thoric
*/
void do_wizlist( CHAR_DATA *ch, char *argument )
{
set_pager_color( AT_IMMORT, ch );
show_file( ch, WIZLIST_FILE );
}
/*
* Contributed by Grodyn.
* Display completely overhauled, 2/97 -- Blodkai
*/
void do_config( CHAR_DATA *ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
if ( IS_NPC(ch) )
return;
one_argument( argument, arg );
set_char_color( AT_GREEN, ch );
if ( arg[0] == '\0' )
{
set_char_color( AT_DGREEN, ch );
send_to_char( "\n\rConfigurations ", ch );
set_char_color( AT_GREEN, ch );
send_to_char( "(use 'config +/- <keyword>' to toggle, see 'help config')\n\r\n\r", ch );
set_char_color( AT_DGREEN, ch );
send_to_char( "Display: ", ch );
set_char_color( AT_GREY, ch );
ch_printf( ch, "%-12s %-12s %-12s %-12s\n\r %-12s %-12s %-12s %-12s\n\r", // %-12s %-12s
IS_SET( ch->pcdata->flags, PCFLAG_PAGERON ) ? "[+] PAGER"
: "[-] pager",
IS_SET( ch->pcdata->flags, PCFLAG_GAG ) ? "[+] GAG"
: "[-] gag",
xIS_SET( ch->act, PLR_BRIEF ) ? "[+] BRIEF"
: "[-] brief",
xIS_SET( ch->act, PLR_COMBINE ) ? "[+] COMBINE"
: "[-] combine",
xIS_SET( ch->act, PLR_BLANK ) ? "[+] BLANK"
: "[-] blank",
xIS_SET( ch->act, PLR_PROMPT ) ? "[+] PROMPT"
: "[-] prompt",
xIS_SET( ch->act, PLR_ANSI ) ? "[+] ANSI"
: "[-] ansi",
xIS_SET( ch->act, PLR_RIP ) ? "[+] RIP"
: "[-] rip");
/* xIS_SET( ch->act, PLR_COMPASS ) ? "[+] COMPASS"
: "[-] compass",
xIS_SET( ch->act, PLR_AUTOMAP) ? "[+] MAP"
: "[-] map" ); */
set_char_color( AT_DGREEN, ch );
send_to_char( "\n\r\n\rAuto: ", ch );
set_char_color( AT_GREY, ch );
ch_printf( ch, "%-12s %-12s %-12s %-12s",
xIS_SET(ch->act, PLR_AUTOSAC ) ? "[+] AUTOSAC"
: "[-] autosac",
xIS_SET(ch->act, PLR_AUTOGOLD ) ? "[+] AUTOGOLD"
: "[-] autogold",
xIS_SET(ch->act, PLR_AUTOLOOT ) ? "[+] AUTOLOOT"
: "[-] autoloot",
xIS_SET(ch->act, PLR_AUTOEXIT ) ? "[+] AUTOEXIT"
: "[-] autoexit" );
set_char_color( AT_DGREEN, ch );
send_to_char( "\n\r\n\rSafeties: ", ch );
set_char_color( AT_GREY, ch );
ch_printf( ch, "%-12s %-12s",
IS_SET( ch->pcdata->flags, PCFLAG_NORECALL ) ? "[+] NORECALL"
: "[-] norecall",
IS_SET( ch->pcdata->flags, PCFLAG_NOSUMMON ) ? "[+] NOSUMMON"
: "[-] nosummon" );
if ( !IS_SET( ch->pcdata->flags, PCFLAG_DEADLY ) )
ch_printf( ch, " %-12s %-12s",
xIS_SET(ch->act, PLR_SHOVEDRAG ) ? "[+] DRAG"
: "[-] drag",
xIS_SET(ch->act, PLR_NICE ) ? "[+] NICE"
: "[-] nice" );
set_char_color( AT_DGREEN, ch );
send_to_char( "\n\r\n\rMisc: ", ch );
set_char_color( AT_GREY, ch );
ch_printf( ch, "%-12s %-12s %-12s",
xIS_SET(ch->act, PLR_TELNET_GA ) ? "[+] TELNETGA"
: "[-] telnetga",
IS_SET( ch->pcdata->flags, PCFLAG_GROUPWHO ) ? "[+] GROUPWHO"
: "[-] groupwho",
IS_SET( ch->pcdata->flags, PCFLAG_NOINTRO ) ? "[+] NOINTRO"
: "[-] nointro" );
set_char_color( AT_DGREEN, ch );
send_to_char( "\n\r\n\rSettings: ", ch );
set_char_color( AT_GREY, ch );
ch_printf_color( ch, "Pager Length (%d) Wimpy (&W%d&w)",
ch->pcdata->pagerlen,
ch->wimpy );
if ( IS_IMMORTAL( ch ) )
{
set_char_color( AT_DGREEN, ch );
send_to_char( "\n\r\n\rImmortal toggles: ", ch );
set_char_color( AT_GREY, ch );
ch_printf( ch, "Roomvnum [%s]",
xIS_SET(ch->act, PLR_ROOMVNUM ) ? "+"
: " ");
}
/* Config option for Room Flag display added by Samson 12-10-97 */
/* Config option for Sector Type display added by Samson 12-10-97 */
/* Config option Area name and filename added by Samson 12-13-97 */
if( IS_IMMORTAL( ch ) )
{
set_char_color( AT_DGREEN, ch );
send_to_char( "\n\rMore Immortal toggles: ", ch );
set_char_color( AT_GREY, ch );
ch_printf( ch, "Roomflags [%s] Sectortypes [%s] Filename [%s]\n\r",
IS_SET(ch->pcdata->flags, PCFLAG_AUTOFLAGS) ? "+"
: " ",
IS_SET(ch->pcdata->flags, PCFLAG_SECTORD) ? "+"
: " ",
IS_SET(ch->pcdata->flags, PCFLAG_ANAME) ? "+"
: " " );
}
set_char_color( AT_DGREEN, ch );
send_to_char( "\n\r\n\rSentences imposed on you (if any):", ch );
set_char_color( AT_YELLOW, ch );
ch_printf( ch, "\n\r%s%s%s%s%s%s",
xIS_SET(ch->act, PLR_SILENCE ) ?
" For your abuse of channels, you are currently silenced.\n\r" : "",
xIS_SET(ch->act, PLR_NO_EMOTE ) ?
" The gods have removed your emotes.\n\r" : "",
xIS_SET(ch->act, PLR_NO_TELL ) ?
" You are not permitted to send 'tells' to others.\n\r" : "",
xIS_SET(ch->act, PLR_LITTERBUG )?
" A convicted litterbug. You cannot drop anything.\n\r" : "",
xIS_SET(ch->act, PLR_THIEF ) ?
" A proven thief, you will be hunted by the authorities.\n\r" : "",
xIS_SET(ch->act, PLR_KILLER ) ?
" For the crime of murder you are sentenced to death...\n\r" : "" );
}
else
{
bool fSet;
int bit = 0;
if ( arg[0] == '+' )
fSet = TRUE;
else if ( arg[0] == '-' )
fSet = FALSE;
else
{
send_to_char( "Config -option or +option?\n\r", ch );
return;
}
if ( !str_prefix( arg+1, "autoexit" ) )
bit = PLR_AUTOEXIT;
else if ( !str_prefix( arg+1, "autoloot" ) )
bit = PLR_AUTOLOOT;
else if ( !str_prefix( arg+1, "autosac" ) )
bit = PLR_AUTOSAC;
else if ( !str_prefix( arg+1, "autogold" ) )
bit = PLR_AUTOGOLD;
else if ( !str_prefix( arg+1, "blank" ) )
bit = PLR_BLANK;
else if ( !str_prefix( arg+1, "brief" ) )
bit = PLR_BRIEF;
else if ( !str_prefix( arg+1, "combine" ) )
bit = PLR_COMBINE;
else if ( !str_prefix( arg+1, "prompt" ) )
bit = PLR_PROMPT;
else if ( !str_prefix( arg+1, "telnetga" ) )
bit = PLR_TELNET_GA;
else if ( !str_prefix( arg+1, "ansi" ) )
bit = PLR_ANSI;
else if ( !str_prefix( arg+1, "rip" ) )
bit = PLR_RIP;
else if ( !str_prefix( arg+1, "compass" ) )
bit = PLR_COMPASS;
else if (!str_prefix( arg+1, "map" ) )
bit = PLR_AUTOMAP; /* maps */
/* else if ( !str_prefix( arg+1, "flee" ) ) bit = PLR_FLEE; */
else if ( !str_prefix( arg+1, "nice" ) )
bit = PLR_NICE;
else if ( !str_prefix( arg+1, "drag" ) )
bit = PLR_SHOVEDRAG;
else if ( IS_IMMORTAL( ch )
&& !str_prefix( arg+1, "vnum" ) )
bit = PLR_ROOMVNUM;
if (bit)
{
if ( (bit == PLR_FLEE || bit == PLR_NICE || bit == PLR_SHOVEDRAG)
&& IS_SET( ch->pcdata->flags, PCFLAG_DEADLY ) )
{
send_to_char( "Pkill characters can not config that option.\n\r", ch );
return;
}
if ( fSet )
xSET_BIT (ch->act, bit);
else
xREMOVE_BIT(ch->act, bit);
send_to_char( "Ok.\n\r", ch );
return;
}
else
{
if ( !str_prefix( arg+1, "norecall" ) )
bit = PCFLAG_NORECALL;
else if ( !str_prefix( arg+1, "nointro" ) )
bit = PCFLAG_NOINTRO;
else if ( !str_prefix( arg+1, "nosummon" ) )
bit = PCFLAG_NOSUMMON;
else if ( !str_prefix( arg+1, "gag" ) )
bit = PCFLAG_GAG;
else if ( !str_prefix( arg+1, "pager" ) )
bit = PCFLAG_PAGERON;
else if ( IS_IMMORTAL ( ch )
&& ( !str_prefix( arg+1, "roomflags" ) ) )
bit = PCFLAG_AUTOFLAGS;
else if ( IS_IMMORTAL ( ch )
&& ( !str_prefix( arg+1, "sectortypes" ) ) )
bit = PCFLAG_SECTORD;
else if ( IS_IMMORTAL ( ch )
&& ( !str_prefix( arg+1, "filename" ) ) )
bit = PCFLAG_ANAME;
else if ( !str_prefix( arg+1, "groupwho" ) )
bit = PCFLAG_GROUPWHO;
else if ( !str_prefix( arg+1, "@hgflag_" ) )
bit = PCFLAG_HIGHGAG;
else
{
send_to_char( "Config which option?\n\r", ch );
return;
}
if ( fSet )
SET_BIT (ch->pcdata->flags, bit);
else
REMOVE_BIT (ch->pcdata->flags, bit);
send_to_char( "Ok.\n\r", ch );
return;
}
}
return;
}
void do_credits( CHAR_DATA *ch, char *argument )
{
do_help( ch, "credits" );
}
extern int top_area;
/*
* New do_areas, written by Fireblade, last modified - 4/27/97
*
* Syntax: area -> lists areas in alphanumeric order
* area <a> -> lists areas with soft max less than
* parameter a
* area <a> <b> -> lists areas with soft max bewteen
* numbers a and b
* area old -> list areas in order loaded
*
*/
void do_areas( CHAR_DATA *ch, char *argument )
{
char *header_string1 = "\n\r| Author | Area"
" | "
"Recommended | Enforced |\n\r";
char *header_string2 = "----------------+-----------------"
"-------------------+----"
"---------+------------\n\r";
char *print_string = "| %-13s | %-34s | %4d - %-4d | %3d - "
"%-3d |\n\r";
AREA_DATA *pArea;
int lower_bound = 0;
int upper_bound = MAX_LEVEL + 1;
/* make sure is to init. > max area level */
char arg[MAX_STRING_LENGTH];
argument = one_argument(argument,arg);
if(arg[0] != '\0')
{
if(!is_number(arg))
{
if(!strcmp(arg,"old"))
{
set_pager_color( AT_PLAIN, ch );
send_to_pager(header_string1, ch);
send_to_pager(header_string2, ch);
for (pArea = first_area; pArea;pArea = pArea->next)
{
pager_printf(ch, print_string,
pArea->author, pArea->name,
pArea->low_soft_range,
pArea->hi_soft_range,
pArea->low_hard_range,
pArea->hi_hard_range);
}
return;
}
else
{
send_to_char("Area may only be followed by numbers, or 'old'.\n\r", ch);
return;
}
}
upper_bound = atoi(arg);
lower_bound = upper_bound;
argument = one_argument(argument,arg);
if(arg[0] != '\0')
{
if(!is_number(arg))
{
send_to_char("Area may only be followed by numbers.\n\r", ch);
return;
}
upper_bound = atoi(arg);
argument = one_argument(argument,arg);
if(arg[0] != '\0')
{
send_to_char("Only two level numbers allowed.\n\r",ch);
return;
}
}
}
if(lower_bound > upper_bound)
{
int swap = lower_bound;
lower_bound = upper_bound;
upper_bound = swap;
}
set_pager_color( AT_PLAIN, ch );
send_to_char("----------------+--------------------------------------+-------------+------------", ch);
send_to_pager(header_string1, ch);
send_to_pager(header_string2, ch);
for (pArea = first_area_name; pArea; pArea = pArea->next_sort_name)
{
if (pArea->hi_soft_range >= lower_bound
&& pArea->low_soft_range <= upper_bound)
{
pager_printf(ch, print_string,
pArea->author, pArea->name,
pArea->low_soft_range,
pArea->hi_soft_range,
pArea->low_hard_range,
pArea->hi_hard_range);
}
}
send_to_char("----------------+--------------------------------------+-------------+------------\n\r", ch);
return;
}
void do_afk( CHAR_DATA *ch, char *argument )
{
if ( IS_NPC(ch) )
return;
if xIS_SET(ch->act, PLR_AFK)
{
xREMOVE_BIT(ch->act, PLR_AFK);
send_to_char( "You are no longer afk.\n\r", ch );
/* act(AT_GREY,"$n is no longer afk.", ch, NULL, NULL, TO_ROOM);*/
act(AT_GREY,"$n is no longer afk.", ch, NULL, NULL, TO_CANSEE);
}
else
{
xSET_BIT(ch->act, PLR_AFK);
send_to_char( "You are now afk.\n\r", ch );
/* act(AT_GREY,"$n is now afk.", ch, NULL, NULL, TO_ROOM);*/
act(AT_GREY,"$n is now afk.", ch, NULL, NULL, TO_CANSEE);
return;
}
}
void do_slist( CHAR_DATA *ch, char *argument )
{
int sn, i, lFound;
char skn[MAX_INPUT_LENGTH];
char buf[MAX_INPUT_LENGTH];
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
int lowlev, hilev;
sh_int lasttype = SKILL_SPELL;
if ( IS_NPC(ch) )
return;
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
lowlev=1;
hilev=100;
if (arg1[0]!='\0')
lowlev=atoi(arg1);
if ((lowlev<1) || (lowlev>LEVEL_IMMORTAL))
lowlev=1;
if (arg2[0]!='\0')
hilev=atoi(arg2);
if ((hilev<0) || (hilev>=LEVEL_IMMORTAL))
hilev=LEVEL_HERO;
if(lowlev>hilev)
lowlev=hilev;
set_pager_color( AT_MAGIC, ch );
send_to_pager("SPELL & SKILL LIST\n\r",ch);
send_to_pager("------------------\n\r",ch);
for (i=lowlev; i <= hilev; i++)
{
lFound= 0;
sprintf(skn,"Spell");
for ( sn = 0; sn < top_sn; sn++ )
{
if ( !skill_table[sn]->name )
break;
if ( skill_table[sn]->type != lasttype )
{
lasttype = skill_table[sn]->type;
strcpy( skn, skill_tname[lasttype] );
}
if ( ch->pcdata->learned[sn] <= 0
&& SPELL_FLAG(skill_table[sn], SF_SECRETSKILL) )
continue;
if(i==skill_table[sn]->skill_level[ch->class] )
{
if( !lFound )
{
lFound=1;
pager_printf( ch, "Level %d\n\r", i );
}
switch (skill_table[sn]->minimum_position)
{
default:
sprintf(buf, "Invalid");
bug( "do_slist: skill with invalid minpos, skill=%s",
skill_table[sn]->name );
break;
case POS_DEAD:
sprintf(buf, "any");
break;
case POS_MORTAL:
sprintf(buf, "mortally wounded");
break;
case POS_INCAP:
sprintf(buf, "incapacitated");
break;
case POS_STUNNED:
sprintf(buf, "stunned");
break;
case POS_SLEEPING:
sprintf(buf, "sleeping");
break;
case POS_RESTING:
sprintf(buf, "resting");
break;
case POS_STANDING:
sprintf(buf, "standing");
break;
case POS_FIGHTING:
sprintf(buf, "fighting");
break;
case POS_EVASIVE:
sprintf(buf, "fighting (evasive)"); /* Fighting style support -haus */
break;
case POS_DEFENSIVE:
sprintf(buf, "fighting (defensive)");
break;
case POS_AGGRESSIVE:
sprintf(buf, "fighting (aggressive)");
break;
case POS_BERSERK:
sprintf(buf, "fighting (berserk)");
break;
case POS_MOUNTED:
sprintf(buf, "mounted");
break;
case POS_SITTING:
sprintf(buf, "sitting");
break;
}
pager_printf(ch, "%7s: %20.20s \t Current: %-3d Max: %-3d MinPos: %s \n\r",
skn, skill_table[sn]->name,
ch->pcdata->learned[sn],
skill_table[sn]->skill_adept[ch->class],
buf );
}
}
}
return;
}
void do_whois( CHAR_DATA *ch, char *argument)
{
CHAR_DATA *victim;
char buf[MAX_STRING_LENGTH];
char buf2[MAX_STRING_LENGTH];
buf[0] = '\0';
if(IS_NPC(ch))
return;
if(argument[0] == '\0')
{
send_to_pager("You must input the name of an online character.\n\r", ch);
return;
}
strcat(buf, "0.");
strcat(buf, argument);
if( ( ( victim = get_char_world(ch, buf) ) == NULL ))
{
send_to_pager("No such character online.\n\r", ch);
return;
}
if(IS_NPC(victim))
{
send_to_pager("That's not a player!\n\r", ch);
return;
}
set_pager_color( AT_GREY, ch );
pager_printf(ch, "\n\r'%s%s.'\n\r %s is a %s level %d %s %s, %d years of age.\n\r",
victim->name,
victim->pcdata->title,
victim->sex == SEX_MALE ? "He" :
victim->sex == SEX_FEMALE ? "She" : "It",
victim->sex == SEX_MALE ? "male" :
victim->sex == SEX_FEMALE ? "female" : "neutral",
victim->level,
capitalize(race_table[victim->race]->race_name),
class_table[victim->class]->who_name,
get_age(victim) );
pager_printf(ch, " %s is a %sdeadly player",
victim->sex == SEX_MALE ? "He" :
victim->sex == SEX_FEMALE ? "She" : "It",
IS_SET(victim->pcdata->flags, PCFLAG_DEADLY) ? "" : "non-");
if ( victim->pcdata->clan )
{
if ( victim->pcdata->clan->clan_type == CLAN_ORDER )
send_to_pager( ", and belongs to the Order ", ch );
else
if ( victim->pcdata->clan->clan_type == CLAN_GUILD )
send_to_pager( ", and belongs to the ", ch );
else
send_to_pager( ", and belongs to Clan ", ch );
send_to_pager( victim->pcdata->clan->name, ch );
}
send_to_pager( ".\n\r", ch );
if(victim->pcdata->council)
pager_printf(ch, " %s holds a seat on: %s\n\r",
victim->sex == SEX_MALE ? "He" :
victim->sex == SEX_FEMALE ? "She" : "It",
victim->pcdata->council->name );
if(victim->pcdata->deity)
pager_printf(ch, " %s has found succor in the deity %s.\n\r",
victim->sex == SEX_MALE ? "He" :
victim->sex == SEX_FEMALE ? "She" : "It",
victim->pcdata->deity->name);
if(victim->pcdata->homepage && victim->pcdata->homepage[0] != '\0')
pager_printf(ch, " %s homepage can be found at %s\n\r",
victim->sex == SEX_MALE ? "His" :
victim->sex == SEX_FEMALE ? "Her" : "Its",
show_tilde( victim->pcdata->homepage ) );
if(victim->pcdata->bio && victim->pcdata->bio[0] != '\0')
pager_printf(ch, " %s's personal bio:\n\r%s",
victim->name,
victim->pcdata->bio);
else
pager_printf(ch, " %s has yet to create a bio.\n\r",
victim->name );
if(IS_IMMORTAL(ch))
{
send_to_pager("-------------------\n\r", ch);
send_to_pager("Info for immortals:\n\r", ch);
if ( mip_enabled( victim ) )
pager_printf( ch, "%s's client is: %s (sec_code: %s)\n\r",
victim->name, victim->pcdata->mip_ver, victim->pcdata->sec_code );
if ( victim->pcdata->authed_by && victim->pcdata->authed_by[0] != '\0' )
pager_printf(ch, "%s was authorized by %s.\n\r",
victim->name, victim->pcdata->authed_by );
pager_printf(ch, "%s has killed %d mobiles, and been killed by a mobile %d times.\n\r",
victim->name, victim->pcdata->mkills, victim->pcdata->mdeaths );
if ( victim->pcdata->pkills || victim->pcdata->pdeaths )
pager_printf(ch, "%s has killed %d players, and been killed by a player %d times.\n\r",
victim->name, victim->pcdata->pkills, victim->pcdata->pdeaths );
if ( victim->pcdata->illegal_pk )
pager_printf(ch, "%s has committed %d illegal player kills.\n\r",
victim->name, victim->pcdata->illegal_pk );
pager_printf(ch, "%s is %shelled at the moment.\n\r",
victim->name,
(victim->pcdata->release_date == 0) ? "not " : "");
if (victim->pcdata->nuisance )
{
pager_printf_color( ch, "&RNuisance &cStage: (&R%d&c/%d) Power: &w%d &cTime: &w%s.\n\r", victim->pcdata->nuisance->flags,
MAX_NUISANCE_STAGE, victim->pcdata->nuisance->power,
ctime(&victim->pcdata->nuisance->time));
}
if(victim->pcdata->release_date != 0)
pager_printf(ch, "%s was helled by %s, and will be released on %24.24s.\n\r",
victim->sex == SEX_MALE ? "He" :
victim->sex == SEX_FEMALE ? "She" : "It",
victim->pcdata->helled_by,
ctime(&victim->pcdata->release_date));
if(get_trust(victim) < get_trust(ch))
{
sprintf(buf2, "list %s", buf);
do_comment(ch, buf2);
}
if(xIS_SET(victim->act, PLR_SILENCE) || xIS_SET(victim->act, PLR_NO_EMOTE)
|| xIS_SET(victim->act, PLR_NO_TELL) || xIS_SET(victim->act, PLR_THIEF)
|| xIS_SET(victim->act, PLR_KILLER) )
{
sprintf(buf2, "This player has the following flags set:");
if(xIS_SET(victim->act, PLR_SILENCE))
strcat(buf2, " silence");
if(xIS_SET(victim->act, PLR_NO_EMOTE))
strcat(buf2, " noemote");
if(xIS_SET(victim->act, PLR_NO_TELL) )
strcat(buf2, " notell");
if(xIS_SET(victim->act, PLR_THIEF) )
strcat(buf2, " thief");
if(xIS_SET(victim->act, PLR_KILLER) )
strcat(buf2, " killer");
strcat(buf2, ".\n\r");
send_to_pager(buf2, ch);
}
if ( victim->desc && victim->desc->host[0]!='\0' ) /* added by Gorog */
{
sprintf (buf2, "%s's IP info: %s ", victim->name, victim->desc->host);
strcat (buf2, "\n\r");
send_to_pager(buf2, ch);
}
}
}
void do_pager( CHAR_DATA *ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
if ( IS_NPC(ch) )
return;
set_char_color( AT_NOTE, ch );
argument = one_argument(argument, arg);
if ( !*arg )
{
if ( IS_SET(ch->pcdata->flags, PCFLAG_PAGERON) )
{
send_to_char( "Pager disabled.\n\r", ch );
do_config(ch, "-pager");
}
else
{
ch_printf( ch, "Pager is now enabled at %d lines.\n\r", ch->pcdata->pagerlen );
do_config(ch, "+pager");
}
return;
}
if ( !is_number(arg) )
{
send_to_char( "Set page pausing to how many lines?\n\r", ch );
return;
}
ch->pcdata->pagerlen = atoi(arg);
if ( ch->pcdata->pagerlen < 5 )
ch->pcdata->pagerlen = 5;
ch_printf( ch, "Page pausing set to %d lines.\n\r", ch->pcdata->pagerlen );
return;
}
/*
* The ignore command allows players to ignore up to MAX_IGN
* other players. Players may ignore other characters whether
* they are online or not. This is to prevent people from
* spamming someone and then logging off quickly to evade
* being ignored.
* Syntax:
* ignore - lists players currently ignored
* ignore none - sets it so no players are ignored
* ignore <player> - start ignoring player if not already
* ignored otherwise stop ignoring player
* ignore reply - start ignoring last player to send a
* tell to ch, to deal with invis spammers
* Last Modified: June 26, 1997
* - Fireblade
*/
void do_ignore(CHAR_DATA *ch, char *argument)
{
char arg[MAX_INPUT_LENGTH];
IGNORE_DATA *temp, *next;
char fname[1024];
struct stat fst;
CHAR_DATA *victim;
if(IS_NPC(ch))
return;
argument = one_argument(argument, arg);
sprintf(fname, "%s%c/%s", PLAYER_DIR,
tolower(arg[0]), capitalize(arg));
victim = NULL;
/* If no arguements, then list players currently ignored */
if(arg[0] == '\0')
{
set_char_color(AT_DIVIDER, ch);
ch_printf(ch, "\n\r----------------------------------------\n\r");
set_char_color(AT_DGREEN, ch);
ch_printf(ch, "You are currently ignoring:\n\r");
set_char_color(AT_DIVIDER, ch);
ch_printf(ch, "----------------------------------------\n\r");
set_char_color(AT_IGNORE, ch);
if(!ch->pcdata->first_ignored)
{
ch_printf(ch, "\t no one\n\r");
return;
}
for(temp = ch->pcdata->first_ignored; temp;
temp = temp->next)
{
ch_printf(ch,"\t - %s\n\r",temp->name);
}
return;
}
/* Clear players ignored if given arg "none" */
else if(!strcmp(arg, "none"))
{
for(temp = ch->pcdata->first_ignored; temp; temp = next)
{
next = temp->next;
UNLINK(temp, ch->pcdata->first_ignored,
ch->pcdata->last_ignored,
next, prev);
STRFREE(temp->name);
DISPOSE(temp);
}
set_char_color(AT_IGNORE, ch);
ch_printf(ch, "You now ignore no one.\n\r");
return;
}
/* Prevent someone from ignoring themself... */
else if(!strcmp(arg, "self") || nifty_is_name(arg, ch->name))
{
set_char_color(AT_IGNORE, ch);
ch_printf(ch, "Did you type something?\n\r");
return;
}
else
{
int i;
/* get the name of the char who last sent tell to ch */
if(!strcmp(arg, "reply"))
{
if(!ch->reply)
{
set_char_color(AT_IGNORE, ch);
ch_printf(ch, "They're not here.\n\r");
return;
}
else
{
strcpy(arg, ch->reply->name);
}
}
/* Loop through the linked list of ignored players */
/* keep track of how many are being ignored */
for(temp = ch->pcdata->first_ignored, i = 0; temp;
temp = temp->next, i++)
{
/* If the argument matches a name in list remove it */
if(!strcmp(temp->name, capitalize(arg)))
{
UNLINK(temp, ch->pcdata->first_ignored,
ch->pcdata->last_ignored,
next, prev);
set_char_color(AT_IGNORE, ch);
ch_printf(ch,"You no longer ignore %s.\n\r",
temp->name);
STRFREE(temp->name);
DISPOSE(temp);
return;
}
}
/* if there wasn't a match check to see if the name */
/* is valid. This if-statement may seem like overkill */
/* but it is intended to prevent people from doing the*/
/* spam and log thing while still allowing ya to */
/* ignore new chars without pfiles yet... */
if( stat(fname, &fst) == -1 &&
(!(victim = get_char_world(ch, arg)) ||
IS_NPC(victim) ||
strcmp(capitalize(arg),victim->name) != 0))
{
set_char_color(AT_IGNORE, ch);
ch_printf(ch,"No player exists by that"
" name.\n\r");
return;
}
if(victim)
{
strcpy(capitalize(arg),victim->name);
}
if (!check_parse_name( capitalize(arg), TRUE ))
{
set_char_color( AT_IGNORE, ch );
send_to_char( "No player exists by that name.\n\r", ch );
return;
}
/* If its valid and the list size limit has not been */
/* reached create a node and at it to the list */
if(i < MAX_IGN)
{
IGNORE_DATA *new;
CREATE(new, IGNORE_DATA, 1);
new->name = STRALLOC(capitalize(arg));
new->next = NULL;
new->prev = NULL;
LINK(new, ch->pcdata->first_ignored,
ch->pcdata->last_ignored, next, prev);
set_char_color(AT_IGNORE, ch);
ch_printf(ch,"You now ignore %s.\n\r", new->name);
return;
}
else
{
set_char_color(AT_IGNORE, ch);
ch_printf(ch,"You may only ignore %d players.\n\r",
MAX_IGN);
return;
}
}
}
/*
* This function simply checks to see if ch is ignoring ign_ch.
* Last Modified: October 10, 1997
* - Fireblade
*/
bool is_ignoring(CHAR_DATA *ch, CHAR_DATA *ign_ch)
{
IGNORE_DATA *temp;
if(IS_NPC(ch) || IS_NPC(ign_ch))
return FALSE;
for(temp = ch->pcdata->first_ignored; temp; temp = temp->next)
{
if(nifty_is_name(temp->name, ign_ch->name))
return TRUE;
}
return FALSE;
}
/* Version info -- Scryn */
void do_version(CHAR_DATA* ch, char* argument)
{
if(IS_NPC(ch))
return;
set_char_color(AT_YELLOW, ch);
ch_printf(ch, "SMAUG %s.%s\n\r", SMAUG_VERSION_MAJOR, SMAUG_VERSION_MINOR);
if(IS_IMMORTAL(ch))
ch_printf(ch, "Compiled on %s at %s.\n\r", __DATE__, __TIME__);
return;
}
/***************************************************************************
* Shows mana and blood (if vampire) requirements to cast a spell. *
* Created by Desden, el Chaman Tibetano - Jun 1999 *
* Snippets page: http://luisso.net/smaug_snippets.htm *
* Email: jose@luisso.net *
***************************************************************************/
void do_mana( CHAR_DATA *ch, char *argument)
{
SKILLTYPE *skill=NULL;
char arg1[MAX_INPUT_LENGTH];
int sn;
int col = 0;
argument=one_argument(argument, arg1);
if (IS_NPC(ch))
{
send_to_char("Mobs cannot use this command.\n\r", ch);
return;
}
if (arg1[0]=='\0')
{
if(IS_VAMPIRE(ch))
send_to_char("Syntax: blood all\n\r blood <spell>\n\r",ch);
else
send_to_char("Syntax: mana all\n\r mana <spell>\n\r",ch);
return;
}
if(!strcmp(arg1,"all"))
{
set_pager_color(AT_YELLOW,ch);
if(IS_VAMPIRE(ch))
send_to_pager(" BLOOD REQUIRED TO CAST\n\r", ch);
else
send_to_pager(" MANA REQUIRED TO CAST\n\r", ch);
send_to_pager(" -----------------------\n\r", ch);
for ( sn = 0; sn < top_sn ; sn++ )
{
skill=get_skilltype(sn);
if(ch->pcdata->learned[sn] < 1 ||
!skill->name || !skill->min_mana )
continue;
if(ch->level>=skill->skill_level[ch->class] )
{
if(IS_VAMPIRE(ch))
{
if(ch->pcdata->condition[COND_BLOODTHIRST] >= BLOOD)
pager_printf_color(ch, "&Y%-22.22s:%4d ",
skill->name, BLOOD);
else
pager_printf_color(ch, "&R%-22.22s:%4d ",
skill->name, BLOOD);
}
else
{
if(ch->mana >= MANA)
pager_printf_color(ch, "&Y%-22.22s:%4d ", skill->name, MANA );
else
pager_printf_color(ch, "&R%-22.22s:%4d ",
skill->name, MANA );
}
if(++col % 3 == 0)
pager_printf(ch,"\n\r");
}
}
pager_printf(ch,"\n\r");
}
else
{
if((sn =skill_lookup( arg1)) > 0)
{
skill=get_skilltype(sn);
if(!skill->min_mana)
{
ch_printf(ch, "%s, '%s' doesn't use %s points.\n\r", ch->name, skill->name, IS_VAMPIRE(ch)?"blood":"mana");
return;
}
if(ch->pcdata->learned[sn] < 1)
{
if ( ch->level < skill->skill_level[ch->class] )
{
send_to_char( "You have not enough level to cast it.\n\r", ch );
return;
}
else
{
send_to_char("You must practice a spell before using it.\n\r",ch);
return;
}
}
pager_printf(ch,"You need %d %s points to cast '%s' with success.\n\r",IS_VAMPIRE(ch)?BLOOD:MANA,IS_VAMPIRE(ch)?"blood":"mana", skill->name);
}
else
ch_printf(ch, "That is not a spell or a skill.\n\r");
}
return;
}