/****************************************************************************
* [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"
BOOK_DATA *first_book;
BOOK_DATA *last_book;
/* handler.c */
extern char *get_room_description(CHAR_DATA *ch, char *descr);
/* clan.c */
extern CLAN_MEMBER *get_member(char *name, CLAN_DATA *clan);
extern int top_help;
char *help_greeting;
/*
* 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 ) );
char* get_talent_rank args( ( CHAR_DATA *ch) );
/* act_wiz.c */
int get_permit_flag args( ( char *argument ) );
char *format_obj_to_char( OBJ_DATA *obj, CHAR_DATA *ch, bool fShort )
{
static char buf[MAX_STRING_LENGTH];
char buf2[MAX_STRING_LENGTH];
buf[0] = '\0';
if (!obj->short_descr) {
sprintf(buf, "a bugged item, report to an imm");
return buf;
}
if ( obj->condition < obj->weight*30
&& obj->item_type != ITEM_TREASURE ) strcat( buf, "&Rdamaged&W, ");
if (!IS_OBJ_STAT(obj, ITEM_NO_TAKE)
&& !xIS_EMPTY(obj->parts)) {
if (obj->size > ch->height + ch->height * .50) strcat(buf, "huge, ");
else if (obj->size < ch->height - ch->height * .50) strcat(buf, "tiny, ");
else if (obj->size > ch->height + ch->height * .30) strcat(buf, "large, ");
else if (obj->size < ch->height - ch->height * .30) strcat(buf, "small, ");
}
if (obj->raw_mana > 100 && IS_AFFECTED(ch, AFF_DETECT_MAGIC))
strcat(buf, "&pmagically charged&w, ");
if ( IS_OBJ_STAT(obj, ITEM_INVIS) ) strcat( buf, "invisible, ");
if ( (IS_AFFECTED(ch, AFF_DETECT_EVIL) )
&& IS_OBJ_STAT(obj, ITEM_EVIL) ) strcat( buf, "&Revil&W, " );
if ((IS_AFFECTED(ch, AFF_DETECT_EVIL))
&& IS_OBJ_STAT(obj, ITEM_BLESS) ) strcat( buf, "&Bblessed&W, ");
if ( IS_AFFECTED(ch, AFF_DETECT_MAGIC)
&& IS_OBJ_STAT(obj, ITEM_MAGIC) )
strcat( buf, "&Bmagical&w, " );
if ( IS_OBJ_STAT(obj, ITEM_GLOW) )
strcat( buf, "&Yglowing&w, " );
if ( IS_OBJ_STAT(obj, ITEM_DARK))
strcat( buf, "&zshadowed&w, " );
if ( IS_OBJ_STAT(obj, ITEM_HUM) )
strcat( buf, "&Chumming&w, " );
if ( IS_OBJ_STAT(obj, ITEM_HIDDEN) )
strcat( buf, "&ghidden&w, " );
if ( IS_OBJ_STAT(obj, ITEM_BURIED) )
strcat( buf, "&Oburied&w, " );
if ( IS_OBJ_STAT(obj, ITEM_DREAMWORLD))
strcat( buf, "&pimaginary&w, " );
if ( IS_OBJ_STAT(obj, ITEM_PROTOTYPE) )
strcat( buf, "&WPROTOTYPE&w, " );
if ( IS_AFFECTED(ch, AFF_DETECTTRAPS)
&& is_trapped(obj) )
strcat( buf, "&RTRAPPED&w " );
if (obj->gem) {
if (obj->gem->name) {
one_argument(obj->gem->name, buf2);
} else {
sprintf(buf2, "gem-studded");
}
sprintf(buf2, "%s-studded ", buf2);
strcat(buf, buf2 );
}
if ( fShort )
{
if ( obj->short_descr )
strcat( buf, myobj(obj) );
sprintf(buf, aoran(buf));
}
else
{
if ( obj->short_descr )
strcat( buf, myobj(obj) );
if (ch->in_obj && ch->in_obj != obj->in_obj) {
if (obj != ch->in_obj) {
strcat(buf, " is outside the ");
strcat(buf, myobj(ch->in_obj));
strcat(buf, ".");
} else {
strcat(buf, " is carrying you.");
}
} else
strcat(buf, " is here.");
sprintf(buf, capitalize(aoran(buf)));
}
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 "&zSto&prmbri&znger&w";
case 13: return "a figment of your imagination";
case 14: return "your gravestone";
case 15: return "the &YApple of D&Oi&Ys&Wc&Yo&Or&Yd&w";
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 "A black runesword moans with power and chaotic energy.";
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 most beautiful sparkling apple hangs in the air.";
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!!!";
}
/*
* 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->carried_by
|| (obj != obj->carried_by->main_hand
&& obj != obj->carried_by->off_hand))
&& (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_PLAIN, 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, " (x %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 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_NPC(victim) && ch->curr_talent[TAL_SEEKING] >= 80
&& victim->pcdata->name_disguise)
ch_printf(ch, "&W...shimmering with the image of %s.\n\r",
victim->pcdata->name_disguise);
if (victim->shield)
ch_printf(ch, "&W...surrounded by a shield of %s.\n\r",
magic_table[victim->shield]);
if (IS_AFFECTED(victim, AFF_BEAUTY))
send_to_char("...surrounded by an eerie aura of beauty and attraction.\n\r", ch);
if (IS_AFFECTED(victim, AFF_FEAR))
send_to_char("...surrounded by an aura of fear and loathing.\n\r", ch);
if (IS_AFFECTED(victim, AFF_UNHOLY)) {
set_char_color(AT_DGREY, ch);
switch(number_range(1,5)) {
default:
send_to_char("...emanating an unholy aura", ch);
break;
case 1:
send_to_char("...surrounded by the stench of death", ch);
break;
case 2:
send_to_char("...feeling of dread and horror", ch);
break;
case 3:
send_to_char("...shrouded in terrible shadow", ch);
break;
}
send_to_char(".\n\r", ch);
} else if (IS_AFFECTED(victim, AFF_HOLY) ) {
set_char_color( AT_WHITE, ch );
ch_printf( ch, "...glowing with an aura of divine radiance.\n\r");
}
if ( IS_AFFECTED(victim, AFF_HOLD) )
{
set_char_color( AT_CYAN, ch);
ch_printf(ch, "...held firmly in place.\n\r");
}
}
void show_char_to_char_0( CHAR_DATA *victim, CHAR_DATA *ch )
{
char buf[MAX_STRING_LENGTH];
char buf2[MAX_STRING_LENGTH];
buf[0] = '\0';
if (IS_NPC(victim)) {
if ( !IS_NPC(ch) && xIS_SET(ch->act, PLR_HOLYLIGHT) )
if(IS_NPC(victim)) /* ha tagith - i didnt forget this time */
ch_printf(ch, "[%d] ", victim->pIndexData->vnum);
if (!xIS_SET(victim->act, ACT_NAMED)) send_to_char("A ", ch);
} else
send_to_char("The ", ch);
set_char_color( AT_PERSON, ch );
if ( !IS_NPC(victim) && !victim->desc )
{
if ( !victim->switched )
send_to_char_color( "&PLINK-DEAD&W, ", ch );
else if ( !IS_AFFECTED(victim, AFF_POSSESS) )
strcat( buf, "switched, " );
}
if ( (!IS_NPC(victim) && xIS_SET(victim->act, PLR_WIZINVIS))
|| (IS_NPC(victim) && xIS_SET(victim->act, ACT_MOBINVIS)) )
{
sprintf( buf,"&W&Yinvisible&W, ");
}
set_char_color( AT_PERSON, ch );
if ( IS_AFFECTED(victim, AFF_GLOW) )
strcat( buf, "&W&Yglowing&W, ");
if ( IS_AFFECTED(victim, AFF_DARK) )
strcat( buf, "&W&zshadowed&W, " );
if ( IS_AFFECTED(victim, AFF_FLAMING) )
strcat( buf, "&W&Rflaming&W, " );
if ( IS_AFFECTED(victim, AFF_INVISIBLE) )
strcat( buf, "&W&Yinvisible&W, " );
if ( IS_AFFECTED(victim, AFF_HIDE) )
strcat( buf, "&W&ghidden,&W ");
if ( IS_AFFECTED(victim, AFF_PASS_DOOR) )
strcat( buf, "&W&btranslucent&W, ");
if ( IS_AFFECTED(victim, AFF_FAERIE_FIRE) )
strcat( buf, "&W&Pfaerie fired&W, ");
if ( IS_AFFECTED(victim, AFF_BERSERK) )
strcat( buf, "&W&Rwild-eyed&W, " );
if ( IS_AFFECTED(ch, AFF_DREAMWORLD)
&& !IS_AFFECTED(victim, AFF_DREAMWORLD) ) {
if (!IS_AWAKE(victim)) {
strcat( buf, "&W&Bsleeping&W, ");
} else
strcat( buf, "&W&Cwaking&W, " );
}
if ( IS_AFFECTED(victim, AFF_DREAMWORLD) )
strcat( buf, "&W&pdreaming&W, " );
if ( victim->desc && victim->desc->connected == CON_EDITING )
strcat( buf, "&W&Cwriting&W " );
if (!IS_NPC(victim)) {
if (victim->species) {
strcat( buf, victim->species);
}
} else {
strcat(buf, victim->short_descr);
}
if (IS_AFFECTED(ch, AFF_VOID)
&& !IS_AFFECTED(victim, AFF_VOID)
&& !IS_AFFECTED(victim, AFF_DREAMWORLD))
strcat( buf, "&W&C, in the real world&W" );
if ( IS_AFFECTED(victim, AFF_VOID) )
strcat( buf, "&b&z, in the Void&W" );
if ( xIS_SET(victim->act, ACT_PROTOTYPE) )
strcat( buf, "&W&Y PROTOTYPE&W");
if ( ch->mount && ch->mount == victim
&& ch->in_room == ch->mount->in_room )
strcat( buf, "&W, which you are riding&W" );
if ( !IS_NPC(victim)
&& xIS_SET(victim->act, PLR_AFK) )
strcat( buf, "&G, who is idle&W");
if (!IS_NPC(victim)) {
strcat( buf, ", ");
strcat( buf, PERS(victim, ch));
}
switch ( victim->position )
{
case POS_DEAD: strcat( buf, " is &RDEAD&W!!" ); break;
case POS_MORTAL: strcat( buf, " is &rmortally wounded&W." ); break;
case POS_INCAP: strcat( buf, " is &rincapacitated&W." ); break;
case POS_STUNNED: strcat( buf, " is lying here &Runconscious&W." ); break;
case POS_SLEEPING:
if (ch->position == POS_SITTING
|| ch->position == POS_RESTING )
strcat( buf, " is sleeping nearby." );
else
strcat( buf, " is deep in slumber here." );
break;
case POS_RESTING:
if (ch->position == POS_RESTING)
strcat ( buf, " is sprawled out alongside you." );
else
if (ch->position == POS_MOUNTED)
strcat ( buf, " is sprawled out at the foot of your mount." );
else
strcat (buf, " is sprawled out here." );
break;
case POS_SITTING:
if ((ch->position == POS_SITTING)
|| (ch->position == POS_KNEELING))
strcat( buf, " sits here with you." );
else
if (ch->position == POS_RESTING)
strcat( buf, " sits nearby as you lie around." );
else
strcat( buf, " sits upright here." );
break;
case POS_KNEELING:
if ((ch->position == POS_KNEELING)
|| (ch->position == POS_SITTING))
strcat( buf, " is kneeling beside you." );
else
strcat( buf, " is kneeling here." );
break;
case POS_SQUATTING:
strcat( buf, " is squatted down here." );
break;
case POS_SWIMMING:
strcat( buf, " is swimming here." );
break;
case POS_FLYING:
strcat( buf, " is flying here." );
break;
case POS_STANDING:
if (victim->in_obj) {
strcat( buf, " is in " );
strcat(buf, aoran(myobj(victim->in_obj)));
} else if ( ( victim->in_room->sector_type == SECT_UNDERWATER )
&& !IS_AFFECTED(victim, AFF_AQUA_BREATH) && !IS_NPC(victim))
strcat( buf, " is &Rdrowning here&W" );
else if ( IS_UNDERWATER(victim) )
strcat( buf, " is here in the water" );
else if ( ( victim->in_room->sector_type == SECT_OCEANFLOOR )
&& !IS_AFFECTED(victim, AFF_AQUA_BREATH) && !IS_NPC(victim) )
strcat( buf, " is&R drowning here&W" );
else if (victim->wait && victim->last_taken) {
strcat(buf, " is ");
strcat(buf, victim->last_taken);
strcat(buf, " here");
} else if (IS_AFFECTED(victim, AFF_FLYING) )
strcat( buf, " is hovering here" );
else
strcat( buf, " is standing here" );
if (IS_SET(victim->mood, MOOD_READY))
strcat(buf, " ready to fight!");
else
strcat(buf, ".");
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 ) );
strcat( buf, "." );
}
else
strcat( buf, "someone who left??" );
break;
}
if (victim->fur_pos > FURNITURE_NONE)
{
if (victim->on)
sprintf (buf2, " %s %s %s %s.",
PERS(victim, ch), pos_string(victim),
fur_pos_string(victim->fur_pos),
victim->on->short_descr );
strcat (buf, buf2);
}
strcat( buf, "\n\r" );
send_to_char( buf, ch );
if (!xIS_SET(ch->act, PLR_BRIEF))
show_visible_affects_to_char( victim, ch );
return;
}
void show_char_to_char_2(CHAR_DATA *ch, CHAR_DATA *victim) {
show_race_line(ch, victim);
if ( victim->description != NULL ) {
send_to_char (victim->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);
}
/* Format a coloring description of the character. */
if (!IS_NPC(victim)) {
ch_printf(ch, "%s with", capitalize(aoran(victim->nation->name)));
if (victim->pcdata->eyes)
ch_printf(ch, " %s eyes", victim->pcdata->eyes);
if (victim->pcdata->hair)
ch_printf(ch, ", %s hair", victim->pcdata->hair);
if (victim->pcdata->skin_color) {
ch_printf(ch, ", %s", victim->pcdata->skin_color);
if (victim->pcdata->skin_type)
ch_printf(ch, " %s", victim->pcdata->skin_type);
else
send_to_char(" skin", ch);
}
if (victim->pcdata->extra_color) {
ch_printf(ch, ", and %s", victim->pcdata->extra_color);
if (victim->pcdata->extra_type)
ch_printf(ch, " %s", victim->pcdata->extra_type);
else
send_to_char(" spots", ch);
}
send_to_char(".\n\r", ch);
}
}
void show_char_to_char_1( CHAR_DATA *victim, CHAR_DATA *ch )
{
char buf2[MAX_STRING_LENGTH];
if ( can_see( victim, ch )
&& !IS_NPC( ch )
&& !xIS_SET( ch->act, PLR_WIZINVIS )
&& (ch->curr_talent[TAL_SEEKING] < 70
|| victim->curr_talent[TAL_SEEKING] > 70) )
{
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 );
}
show_char_to_char_2(ch, victim);
if (victim->fur_pos > FURNITURE_NONE)
{
if (victim->on)
sprintf (buf2, "%s %s %s %s.\n",
PERS(victim, ch), pos_string(victim),
fur_pos_string(victim->fur_pos),
victim->on->short_descr );
send_to_char (buf2, ch );
}
show_condition( ch, victim );
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 );
show_equip(victim, ch);
/*
* Crash fix here by Thoric
*/
if ( IS_NPC(ch) || victim == ch )
return;
if ( number_percent( ) < ch->curr_talent[TAL_SEEKING] )
{
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 );
use_magic(ch, TAL_SEEKING, 1);
}
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 );
}
}
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) ||
(!can_use_bodypart(ch, BP_REYE) &&
!can_use_bodypart(ch, BP_LEYE)))
{
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];
char roomdesc[MAX_STRING_LENGTH]; /* Generated Descs -- Scion */
EXIT_DATA *pexit;
CHAR_DATA *victim;
OBJ_DATA *obj;
ROOM_INDEX_DATA *original;
char *pdesc;
bool doexaprog;
sh_int door;
int number, cnt;
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)
&& !IS_AFFECTED(ch, AFF_INFRARED)
&& 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 );
doexaprog = str_cmp( "noprog", arg2 ) && str_cmp( "noprog", arg3 );
if ( arg1[0] == '\0' || !str_cmp( arg1, "auto" ) )
{
/* 'look' or 'look auto' */
set_char_color( AT_WHITE, ch );
/* make life easier - shogar */
if ( !IS_NPC(ch) && IS_SET(ch->pcdata->permissions, PERMIT_BUILD) )
ch_printf(ch,"[%d] ",ch->in_room->vnum);
/* let's show your position here -keo */
if (ch->in_obj) {
send_to_char("Riding", ch);
} else if (IS_UNDERWATER(ch)) {
send_to_char("Swimming", ch);
} else if (IS_AFFECTED(ch, AFF_FLYING)) {
send_to_char("Flying", ch);
} else if (IS_SET(ch->in_room->room_flags, ROOM_NOFLOOR)) {
send_to_char("Falling", ch);
} else {
switch (ch->position) {
case POS_RESTING:
send_to_char("Resting", ch);
break;
case POS_SITTING:
send_to_char("Sitting", ch);
break;
case POS_KNEELING:
send_to_char("Kneeling", ch);
break;
case POS_SQUATTING:
send_to_char("Squatting", ch);
break;
case POS_STANDING:
send_to_char("Standing", ch);
break;
case POS_MOUNTED:
send_to_char("Riding", ch);
break;
default:
send_to_char("Walking", ch);
}
}
send_to_char(" in ", ch);
if (IS_AFFECTED(ch, AFF_VOID))
send_to_char("the Void", ch);
else
send_to_char( ch->in_room->name, ch );
if (IS_AFFECTED(ch, AFF_DREAMWORLD))
send_to_char(" &P[&pDreamworld&P]&W", ch);
send_to_char( "\n\r", ch );
/* Room Desc Colors, to make things more interesting -keo */
if (!IS_OUTSIDE(ch)) {
if (ch->in_room->sector_type == SECT_LAVA)
set_char_color(AT_RED, ch);
else if (ch->in_room->sector_type == SECT_DUNNO)
set_char_color(AT_DGREY, ch);
else if (!IS_UNDERWATER(ch))
set_char_color(AT_GREY, ch);
else
set_char_color(AT_BLUE, ch);
} else if (time_info.hour>6 && time_info.hour<=18
&& !IS_SET(sysdata.quest, QUEST_ETERNAL_NIGHT)) {
/* Day Colors */
switch(ch->in_room->sector_type) {
default:
set_char_color(AT_YELLOW, ch);
break;
case SECT_FOREST:
case SECT_SWAMP:
set_char_color(AT_GREEN, ch);
break;
case SECT_MOUNTAIN:
case SECT_ICE:
set_char_color(AT_WHITE, ch);
break;
case SECT_WATER_SWIM:
case SECT_WATER_NOSWIM:
set_char_color(AT_BLUE, ch);
break;
case SECT_AIR:
set_char_color(AT_LBLUE, ch);
break;
case SECT_DUNNO:
set_char_color(AT_PURPLE, ch);
break;
}
} else {
/* Night colors */
switch(ch->in_room->sector_type) {
default:
set_char_color(AT_BLUE, ch);
break;
case SECT_FOREST:
case SECT_SWAMP:
set_char_color(AT_DGREEN, ch);
break;
case SECT_MOUNTAIN:
set_char_color(AT_DGREY, ch);
break;
case SECT_WATER_SWIM:
case SECT_WATER_NOSWIM:
set_char_color(AT_DBLUE, ch);
break;
case SECT_AIR:
set_char_color(AT_CYAN, ch);
break;
case SECT_DUNNO:
set_char_color(AT_DGREY, ch);
break;
}
}
/* Generated Descriptions -- Scion */
if ((!IS_NPC(ch) && !xIS_SET(ch->act, PLR_BRIEF)) || IS_NPC(ch)) {
strcpy(roomdesc, get_room_description(ch, roomdesc));
send_to_char(roomdesc, ch);
}
if (!IS_NPC(ch) && xIS_SET(ch->act, PLR_LONG_EXIT))
do_exits(ch, "" );
else if ( !IS_NPC(ch) && xIS_SET(ch->act, PLR_AUTOEXIT) )
do_exits( ch, "auto" );
if (!ch->in_room->pShop)
show_list_to_char( ch->in_room->first_content, ch, FALSE, FALSE );
if (ch->in_obj)
show_list_to_char(ch->in_obj->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 ( 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 ( doexaprog ) 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 ( doexaprog ) oprog_examine_trigger( ch, obj );
break;
}
ch_printf( ch, "It's %s full of a %s liquid.\n\r",
obj->value[1] < obj->value[0] / 4
? "less than" :
obj->value[1] < 3 * obj->value[0] / 4
? "about" : "more than",
liq_table[obj->value[2]].liq_color
);
if ( doexaprog ) 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 )) {
set_char_color( AT_WHITE, ch );
send_to_char( "That room is private buster!\n\r", ch );
return;
}
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:
if ( IS_SET(obj->value[1], CONT_CLOSED) )
{
send_to_char( "It is closed.\n\r", ch );
break;
}
case ITEM_CORPSE_NPC:
case ITEM_CORPSE_PC:
case ITEM_FURNITURE:
case ITEM_VEHICLE:
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 ( doexaprog ) 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
&& ( TALENT(ch, TAL_SEEKING) >= 10
|| IS_SET( pexit->exit_info, EX_xLOOK ) ) )
{
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 )
{
if (doexaprog)
show_char_to_char_1( victim, ch );
else
show_char_to_char_2( ch, victim );
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 ( doexaprog ) 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 ( doexaprog ) oprog_examine_trigger( ch, obj );
return;
}
if ( nifty_is_name_prefix( arg, obj->name ) )
{
if ( (cnt += obj->count) < number )
continue;
send_to_char(obj->description, ch);
send_to_char("\n\r", ch);
pdesc = get_extra_descr( obj->name, obj->pIndexData->first_extradesc );
if ( !pdesc )
pdesc = get_extra_descr( obj->name, obj->first_extradesc );
if ( !pdesc ) {
int diff=obj->weight-(obj->condition / 50);
if (diff < -32)
act(AT_PLAIN, "$p is in the best condition it could possibly be.", ch, obj, NULL, TO_CHAR);
else if (diff < -16)
act(AT_PLAIN, "$p has been enhanced to withstand much damage.", ch, obj, NULL, TO_CHAR);
else if (diff < -8)
act(AT_PLAIN, "$p looks very strong.", ch, obj, NULL, TO_CHAR);
else if (diff < -4)
act(AT_PLAIN, "$p seems like it would be able to withstand significant damage.", ch, obj, NULL, TO_CHAR);
else if (diff < -2)
act(AT_PLAIN, "$p looks somewhat stronger than normal.", ch, obj, NULL, TO_CHAR);
else if (diff < 1)
act(AT_PLAIN, "$p is in perfect condition.", ch, obj, NULL, TO_CHAR);
else if (diff < 2)
act(AT_PLAIN, "$p is slightly damaged.", ch, obj, NULL, TO_CHAR);
else if (diff < 4)
act(AT_PLAIN, "$p is somewhat damaged.", ch, obj, NULL, TO_CHAR);
else if (diff < 8)
act(AT_PLAIN, "$p is pretty damaged.", ch, obj, NULL, TO_CHAR);
else if (diff < 16)
act(AT_PLAIN, "$p is damaged.", ch, obj, NULL, TO_CHAR);
else if (diff < 32)
act(AT_PLAIN, "$p is severly damaged.", ch, obj, NULL, TO_CHAR);
else
act(AT_PLAIN, "$p is falling apart!", ch, obj, NULL, TO_CHAR);
} else
send_to_char_color( pdesc, ch );
if (obj->item_type == ITEM_BOOK)
{
EXTRA_DESCR_DATA *ed;
send_to_char( "Contents:\n\r", ch );
for ( ed = obj->first_extradesc; ed; ed = ed->next )
{
send_to_char( ed->keyword, ch );
if ( ed->next )
send_to_char( "\n\r", ch );
}
send_to_char( "\n\r", ch );
}
if ( doexaprog ) 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 ( doexaprog ) 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 ( doexaprog ) 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 ( doexaprog ) 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))
ch_printf(ch, "%s is %s %s.\n\r", PERS(victim, ch),
aoran(victim->pcdata->type), victim->species);
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), 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) );
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 ) )
{
act( AT_ACTION, "$n glances at you.", ch, NULL, victim, TO_VICT );
act( AT_ACTION, "$n glances at $N.", ch, NULL, victim, TO_NOTVICT );
}
show_char_to_char_2(ch,victim);
}
show_condition( ch, victim );
return;
}
void do_examine( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
char arg[MAX_INPUT_LENGTH];
OBJ_DATA *obj;
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;
}
sprintf( buf, "%s noprog", arg );
do_look( ch, buf );
/*
* Support for looking at boards, checking equipment conditions,
* and support for trigger positions by Thoric
*/
if ( (obj = get_obj_here(ch, arg)) != NULL )
{
ch_printf(ch, "%s\n\r", obj->description);
switch (obj->item_type) {
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 == 1) 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_FURNITURE:
case ITEM_QUIVER:
send_to_char( "When you look inside, you see:\n\r", ch );
case ITEM_KEYRING:
sprintf( buf, "in %s noprog", arg );
do_look( ch, buf );
break;
}
if ( IS_OBJ_STAT( obj, ITEM_COVERING ) )
{
sprintf( buf, "under %s noprog", arg );
do_look( ch, buf );
}
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;
bool fAuto;
set_char_color( AT_EXITS, ch );
buf[0] = '\0';
fAuto = !str_cmp( argument, "auto" );
if ( !check_blind(ch) )
return;
strcpy( buf, fAuto ? "Exits:" : "Obvious 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_HIDDEN)
|| ch->curr_talent[TAL_SEEKING] >= 65 ) )
{
found = TRUE;
if ( fAuto )
{
strcat( buf, " " );
/* make life easier - shogar */
if ( !IS_NPC(ch) && xIS_SET(ch->act, PLR_HOLYLIGHT) )
sprintf(buf+strlen(buf),"[%d]-",pexit->to_room->vnum);
if (!IS_SET(pexit->exit_info, EX_SECRET)
|| ch->curr_talent[TAL_SEEKING] >= 80) {
if (IS_SET(pexit->exit_info, EX_CLOSED))
strcat( buf, "&O#&w");
strcat( buf, dir_name[pexit->vdir] );
}
}
else
{
if ( !IS_NPC(ch) && xIS_SET(ch->act, PLR_HOLYLIGHT) )
sprintf( buf + strlen(buf), "[%-5d] %-1s%-5s - %s\n\r",
pexit->to_room->vnum,
IS_SET(pexit->exit_info, EX_CLOSED)
? "&O#&w" : "&w",
capitalize( dir_name[pexit->vdir] ),
pexit->to_room->name
);
else
sprintf( buf + strlen(buf), "%-1s%-5s - %s\n\r",
IS_SET(pexit->exit_info, EX_CLOSED)
? "&O#&w" : "&w",
capitalize( dir_name[pexit->vdir] ),
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;
}
/*
To: Scion
From: Keolah
Date: Thu Jul 29 16:40:35 1999
Subject: months and days
Days:
Vannes (Sun), Kelivan (mountain), Vesevan (star), Tativan (tree),
Retivan (water), Daltavan (song), Vestivan (wind)
Months:
Brykena (change), Relithoves (sleet), Vestejen (gale), Tatarmyr (bloom),
Sesiddet (traveling), Heygavan (summer), Veseveret (blue star),
Vankampa (glitter), Dalteyves (thunder), Nastarmath (autumn),
Retsoves (rain), Kinrelth (snow)
*/
char * const day_name [] =
{
"Kelivan", "Vesevan", "Tativan", "Retivan", "Daltevan", "Vestivan", "Vannes"
};
char * const month_name [] =
{
"Brykena", "Relithoves", "Vestejan", "Tatarmyr",
"Sesiddet", "Heygavan", "Veseveret", "Vankampa", "Dalteyves",
"Nastarmath", "Retsoves", "Kinrelth"
};
void do_time( CHAR_DATA *ch, char *argument )
{
extern char str_boot_time[];
extern char reboot_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 on %s, the %d%s of the Month of %s, the year %d.\n\r"
"The mud started up at: %s\r"
"The system time (E.S.T.): %s\r"
"Next Reboot is set for: %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 ),
reboot_time
);
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)
{
int climate;
AREA_DATA *tarea = ch->in_room->area;
char *combo, *single;
char buf[MAX_INPUT_LENGTH];
int temp, precip, wind, mana;
MOON_DATA *moon;
if (!argument || argument[0] == '\0') {
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;
mana = (ch->in_room->area->weather->mana + 3*weath_unit -1)/
weath_unit;
if ( IS_OUTSIDE(ch) )
{
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);
if (IS_SET(sysdata.quest, QUEST_ETERNAL_NIGHT)) {
sprintf(buf, "The sky lies black under eternal night.\n\r");
} else {
if (precip >= 3)
sprintf(buf, "%s\n\r", cloudyday_msg[(int) time_info.hour/4]);
else
sprintf(buf, "%s\n\r", clearday_msg[(int) time_info.hour/4]);
}
ch_printf(ch, buf);
moon = first_moon;
while (moon) {
if ((moon->up)
&& (!str_cmp(moon->world, ch->in_room->area->resetmsg))) {
sprintf(buf, "%s %s moon hangs in the sky.\n\r",
capitalize(aoran(moon->color)), moon_phase[moon->phase]);
ch_printf(ch, buf);
}
moon= moon->next;
}
} else
ch_printf(ch, "You can't see the sky from here.\n\r");
mana = URANGE(0, mana, 5);
temp = URANGE(0, temp, 5);
if (ch->mana > (int)ch->max_mana/20) {
sprintf(buf, "%s.\r\n", manatemp_msg[mana][temp]);
ch_printf(ch, buf);
}
return;
}
/* Let you alter the weather in one area based on
* your effectivity in the appropriate talent
*/
if (!str_cmp(argument, "warmer")
&& ch->curr_talent[TAL_FIRE] >= 30) {
climate = tarea->weather->climate_temp * 100 - 200;
if (tarea->weather->temp >= climate + TALENT(ch, TAL_FIRE)) {
send_to_char("You can't make this area any hotter.\n\r", ch);
return;
}
tarea->weather->temp += 10;
send_to_char("&RYou heat up the area a bit.\n\r", ch);
use_magic(ch, TAL_FIRE, 250);
return;
} else if (!str_cmp(argument, "colder")
&& ch->curr_talent[TAL_FROST] >= 30) {
climate = tarea->weather->climate_temp * 100 - 200;
if (tarea->weather->temp <= climate - TALENT(ch, TAL_FROST)) {
send_to_char("You can't make this area any colder.\n\r", ch);
return;
}
tarea->weather->temp -= 10;
send_to_char("&CYou bring a winter chill to the region.\n\r", ch);
use_magic(ch, TAL_FROST, 250);
return;
} else if (!str_cmp(argument, "windier")
&& ch->curr_talent[TAL_WIND] >= 30) {
climate = tarea->weather->climate_wind * 100 - 200;
if (tarea->weather->wind >= climate + TALENT(ch, TAL_WIND)) {
send_to_char("You can't make this area any windier.\n\r", ch);
return;
}
tarea->weather->wind += 10;
send_to_char("&cYou whip up the winds in the area.\n\r", ch);
use_magic(ch, TAL_WIND, 250);
return;
} else if (!str_cmp(argument, "stiller")
&& ch->curr_talent[TAL_WIND] >= 50) {
climate = tarea->weather->climate_precip * 100 - 200;
if (tarea->weather->precip <= climate - TALENT(ch, TAL_WIND)) {
send_to_char("You can't make the wind in this area any stiller.\n\r", ch);
return;
}
tarea->weather->precip += 10;
send_to_char("&cYou calm the winds in the region.\n\r", ch);
use_magic(ch, TAL_WIND, 250);
return;
} else if (!str_cmp(argument, "wetter")
&& ch->curr_talent[TAL_WATER] >= 30) {
climate = tarea->weather->climate_precip * 100 - 200;
if (tarea->weather->precip >= climate + TALENT(ch, TAL_WATER)) {
send_to_char("You can't make this area any wetter.\n\r", ch);
return;
}
tarea->weather->precip += 10;
send_to_char("&BYou build up moisture in the air.\n\r", ch);
use_magic(ch, TAL_WATER, 250);
return;
} else if (!str_cmp(argument, "drier")
&& ch->curr_talent[TAL_FIRE] >= 60) {
climate = tarea->weather->climate_precip * 100 - 200;
if (tarea->weather->precip <= climate - TALENT(ch, TAL_FIRE)) {
send_to_char("You can't make this area any drier.\n\r", ch);
return;
}
tarea->weather->precip -= 10;
send_to_char("&YYou evaporate moisture in the air.\n\r", ch);
use_magic(ch, TAL_FIRE, 250);
return;
} else {
send_to_char("You can do no such thing to the weather.\n\r", ch);
return;
}
}
/* A more internal version of do_weather that returns the weather
* string instead of sending it to the char. Used for generated
* room descriptions -- Scion
*/
char *get_weather_string(CHAR_DATA *ch, char *weather)
{
char *combo, *single;
char buf[MAX_INPUT_LENGTH];
char magic[MAX_INPUT_LENGTH];
int temp, precip, wind, mana;
MOON_DATA *moon;
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;
mana = (ch->in_room->area->weather->mana + 3*weath_unit -1)/
weath_unit;
if ( IS_OUTSIDE(ch) )
{
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);
if (IS_SET(sysdata.quest, QUEST_ETERNAL_NIGHT)) {
sprintf(magic, "The sky lies black under eternal night.\n\r");
} else {
if (precip >= 3)
sprintf(magic, "%s\n\r", cloudyday_msg[(int) time_info.hour/4]);
else
sprintf(magic, "%s\n\r", clearday_msg[(int) time_info.hour/4]);
}
strcat(buf, magic);
moon = first_moon;
while (moon) {
if ((moon->up)
&& (!str_cmp(moon->world, ch->in_room->area->resetmsg))) {
sprintf(magic, "%s %s moon hangs in the sky.\n\r",
capitalize(aoran(moon->color)), moon_phase[moon->phase]);
strcat(buf, magic);
}
moon= moon->next;
}
} else
strcpy(buf, "");
/* Were getting crashes when this hit 6 for some reason -- Scion */
mana = URANGE(0, mana, 5);
if (ch->mana > (int)ch->max_mana/20) {
sprintf(magic, " %s.\r\n", manatemp_msg[mana][temp]);
}
strcat(buf, magic);
weather = STRALLOC(buf);
return weather;
}
/*
* 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->permit && !IS_SET(ch->pcdata->permissions, pHelp->permit ))
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_new_help( ch, "rules" );
else
{
sprintf( buf, "rules_%s", argument );
do_new_help( ch, buf );
}
}
void do_who( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
char invis_str[MAX_INPUT_LENGTH];
char rank_text[MAX_INPUT_LENGTH];
DESCRIPTOR_DATA *d;
int nMatch = 0;
CHAR_DATA *wch;
char *rank;
send_to_pager( "\n\r&Y Elkandu in the Planes\n\r\n\r", ch);
for (d = first_descriptor;d;d = d->next) {
if (d->connected != CON_PLAYING && d->connected != CON_EDITING)
continue;
if (!d->character) continue;
wch = d->character;
sprintf( rank_text, "%s",
(get_talent_rank(wch)) );
rank = rank_text;
if (get_char_worth(wch) >= 2000
&& ( wch->pcdata->rank && wch->pcdata->rank[0] != '\0' ))
rank = wch->pcdata->rank;
else if (IS_SET( wch->pcdata->flags, PCFLAG_ANONYMOUS))
rank = "&zAnonymous";
if ( xIS_SET(wch->act, PLR_WIZINVIS) )
sprintf( invis_str, " &R(&WInvis %d&R)&w", wch->pcdata->wizinvis);
else
invis_str[0] = '\0';
sprintf( buf, "^x&C[&W%s&C] &w%s %s%s%s%s%s%s%s\n\r",
const_color_align( rank, 12, ALIGN_CENTER ),
wch->pcdata->title,
invis_str,
(wch->desc && wch->desc->connected) ? " &Y[&WWRITING&Y]&w " : "",
IS_AFFECTED(wch, AFF_DREAMWORLD) ? "&P[&pDreamworld&P]&w " : "",
IS_AFFECTED(wch, AFF_VOID) ? " &b[&zVoid&b]&w " : "",
xIS_SET(wch->act, PLR_OOC) ? " &Y[&WOOC&Y]&w " : "",
xIS_SET(wch->act, PLR_AFK) ? " &Y[&WIDLE&Y]&w " : "",
xIS_SET(wch->act, PLR_BOUNTY) ? " &R(&WBOUNTY&R)&w " : ""
);
nMatch++;
send_to_char(buf, ch);
}
send_to_pager( "&x\n\r", ch );
set_char_color( AT_YELLOW, ch );
ch_printf( ch, "&Y[&WThere %s &Y%d player%s&W on %s.&Y]&w\n\r",
nMatch == 1 ? "is" : "are", nMatch, nMatch == 1 ? "" : "s", sysdata.mud_name );
return;
}
/* This command SUCKS! It's misleading enough to be dangerous to morts. -- Scion
* Re-written Jan 25, 2001 by Keolah
*/
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 diff;
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 )
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->cost;
value2 = obj2->cost;
break;
case ITEM_WEAPON:
value1 = obj1->cost;
value2 = obj2->cost;
break;
}
}
diff = abs(value1 - value2);
if ( !msg )
{
if ( diff < 100000 )
msg = "$p and $P look about the same value.";
else if ( value1 > value2 ) {
if (diff > 500000 ) {
msg = "$p looks far more valuable than $P.";
} else {
msg = "$p looks more valuable than $P.";
}
} else {
if (diff > 500000 ) {
msg = "$p looks far less valuable than $P.";
} else {
msg = "$p looks less valuable than $P.";
}
}
}
act( AT_PLAIN, msg, ch, obj1, obj2, TO_CHAR );
return;
}
void do_where( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
DESCRIPTOR_DATA *d;
bool found;
if (ch->curr_talent[TAL_SEEKING] < 40) {
ch_printf(ch, "You are in %s.", ch->in_room->name);
return;
}
set_pager_color( AT_PERSON, ch );
pager_printf( ch, "Elkandu who you can Seek right now:\n\r" );
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
|| ch->curr_talent[TAL_SEEKING] >= 60)
&& (!str_cmp(victim->in_room->area->resetmsg,
ch->in_room->area->resetmsg)
|| ch->curr_talent[TAL_SEEKING] >= 80)
&& (!IS_SET(victim->in_room->room_flags, ROOM_NO_ASTRAL)
|| ch->curr_talent[TAL_SEEKING] >= 90)
&& can_see( ch, victim ) )
{
found = TRUE;
pager_printf_color( ch, "%-15s&P ", PERS(victim, ch) );
pager_printf_color( ch, "%-20s ", victim->in_room->name);
pager_printf_color( ch, "%-15s ", victim->in_room->area->name);
pager_printf_color( ch, "%-10s\n\r", victim->in_room->area->resetmsg);
}
if ( !found )
send_to_char( "None\n\r", ch );
return;
}
/* Recoded by Keolah Oct 12 2000 */
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;
}
diff = get_char_worth(victim);
if ( diff < 200 ) msg = "$N is probably not worth killing.";
else if ( diff < 500 ) msg = "$N appears inexperienced.";
else if ( diff < 1000) msg = "$N seems to move with confidence.";
else if ( diff < 1500) msg = "$N appears experienced and confident.";
else if ( diff < 2000) msg = "$N moves with a deadly grace and power.";
else msg = "$N radiates an aura of power and command.";
/* diff = get_char_worth(victim) - get_char_worth(ch);
if ( diff < -150) msg = "$N is as weak as a feather!";
else if ( diff < -100) msg = "You could kill $N with your hands tied!";
else if ( diff < -50) msg = "Piece of cake.";
else if ( diff < -20) msg = "$N is a wimp.";
else if ( diff < 0) msg = "$N looks weaker than you.";
else if ( diff < 20) msg = "$N looks about as strong as you.";
else if ( diff < 50) msg = "It would take a bit of luck...";
else if ( diff < 100) msg = "It would take a lot of luck, and great equipment!";
else if ( diff < 150) msg = "Why don't you dig a grave for yourself first?";
else msg = "It'd be easier to kill Keolah with your head chopped off.";
*/ act( AT_CONSIDER, msg, ch, NULL, victim, TO_CHAR );
act( AT_CONSIDER, "$n looks at you very closely...", ch, NULL, victim, TO_VICT );
act( AT_CONSIDER, "$n looks at $N very closely.", ch, NULL, victim, TO_NOTVICT );
return;
}
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
&& ( CAN_CAST(ch) ) )
{
if ( col % 3 != 0 )
send_to_pager( "\n\r", ch );
set_pager_color( AT_MAGIC, ch );
send_to_pager_color(
" ----------------------------------[&CSpells&B]----------------------------------\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( "\n\r", ch );
set_pager_color( AT_MAGIC, ch );
pager_printf_color( ch,
" ----------------------------------&C%ss&B----------------------------------\n\r",
skill_tname[skill_table[sn]->type]);
col = cnt = 0;
}
lasttype = skill_table[sn]->type;
if (skill_available(ch, sn) == FALSE)
continue;
if ((LEARNED(ch, sn) < 1) && SPELL_FLAG(skill_table[sn], SF_SECRETSKILL))
continue;
if (lasttype != SKILL_SPELL && LEARNED(ch, sn) < 1)
continue;
++cnt;
set_pager_color( AT_MAGIC, ch );
pager_printf( ch, "%20.20s", skill_table[sn]->name );
if ( LEARNED(ch, sn) > 0 )
set_pager_color( AT_SCORE, ch );
pager_printf( ch, " %3d%% ", LEARNED(ch, sn) );
if ( ++col % 3 == 0 )
send_to_pager( "\n\r", ch );
}
if ( col % 3 != 0 )
send_to_pager( "\n\r", ch );
set_pager_color( AT_MAGIC, ch );
}
else
{
CHAR_DATA *mob;
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;
}
sn = skill_lookup( argument );
can_prac = skill_available(ch, sn);
if (can_prac == FALSE) {
act( AT_TELL, "$n tells you 'You cannot learn any such skill...'",
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;
}
}
if ( LEARNED(ch, sn) >= 1 )
{
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->pcdata->learned[sn]+= number_range(1, 15);
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 );
}
}
return;
}
void do_password( CHAR_DATA *ch, char *argument )
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
char *pwdnew;
char *p;
if ( IS_NPC(ch) )
return;
argument = one_argument_retain_case(argument, arg1);
argument = one_argument_retain_case(argument, arg2);
if ( arg1[0] == '\0' || arg2[0] == '\0' )
{
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;
}
/*
* No tilde allowed because of player file format.
*/
pwdnew = crypt( arg2, ch->name );
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 );
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->permit == 0 )
{
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->permit == 0
&& !str_prefix(argument, command->name) )
{
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;
}
/*
* 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 %-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",
IS_SET( ch->pcdata->flags, PCFLAG_NOBEEP ) ? "[+] NOBEEP"
: "[-] nobeep",
IS_SET( ch->pcdata->flags, PCFLAG_ANONYMOUS) ? "[+] ANONYMOUS"
: "[-] anonymous",
xIS_SET(ch->act, PLR_NOHUNGER ) ? "[+] NOHUNGER"
: "[-] nohunger",
xIS_SET(ch->act, PLR_OOC ) ? "[+] OOC"
: "[-] ooc",
xIS_SET(ch->act, PLR_LONG_EXIT ) ? "[+] LONGEXIT"
: "[-] longexit");
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_AUTOSEX ) ? "[+] AUTOSEX"
: "[-] autosex",
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_SPAR ) ? "[+] SPAR"
: "[-] spar",
xIS_SET(ch->act, PLR_DEFENSE ) ? "[+] DEFENSE"
: "[-] defense" );
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",
xIS_SET(ch->act, PLR_TELNET_GA ) ? "[+] TELNETGA"
: "[-] telnetga",
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)",
ch->pcdata->pagerlen );
if ( IS_SET(ch->pcdata->permissions, PERMIT_BUILD) )
{
set_char_color( AT_DGREEN, ch );
send_to_char( "\n\r\n\rImmortal toggles: ", ch );
set_char_color( AT_GREY, ch );
ch_printf( ch, "%-12s\n\r ",
xIS_SET( ch->act, PLR_ROOMVNUM ) ? "[+] VNUM"
: "[-] vnum" );
}
set_char_color( AT_DGREEN, ch );
send_to_char( "\n\r\n\rTalent toggles: ", ch );
if ( ch->curr_talent[TAL_ILLUSION] >= 70 )
{
set_char_color( AT_GREY, ch );
ch_printf( ch, "%-12s ",
IS_SET( ch->pcdata->flags, PCFLAG_MASK ) ? "[+] AURAMASK"
: "[-] auramask" );
}
if ( ch->curr_talent[TAL_MIND] >= 90 )
{
set_char_color( AT_GREY, ch );
ch_printf( ch, "%-12s ",
IS_SET( ch->pcdata->flags, PCFLAG_SHIELD ) ? "[+] MINDSHIELD"
: "[-] mindshield" );
}
ch_printf(ch, "\n\r");
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, "autosex") ) bit = PLR_AUTOSEX;
else if ( !str_prefix( arg+1, "longexit" ) ) bit = PLR_LONG_EXIT;
else if ( !str_prefix( arg+1, "nohunger" ) ) bit = PLR_NOHUNGER;
else if ( !str_prefix( arg+1, "defense" ) ) bit = PLR_DEFENSE;
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, "ooc" ) ) bit = PLR_OOC;
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, "vnum" ) ) bit = PLR_ROOMVNUM;
if (bit)
{
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 ( !str_prefix( arg+1, "spar" ) ) bit = PCFLAG_SPAR;
else if ( !str_prefix( arg+1, "nobeep" ) ) bit = PCFLAG_NOBEEP;
else if ( !str_prefix( arg+1, "anonymous" ) ) bit = PCFLAG_ANONYMOUS;
else if ( ch->curr_talent[TAL_ILLUSION] >= 70
&& !str_prefix( arg+1, "auramask" ) ) bit = PCFLAG_MASK;
else if ( ch->curr_talent[TAL_MIND] >= 90
&& !str_prefix( arg+1, "mindshield")) bit = PCFLAG_SHIELD;
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_new_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 <world> -> lists areas on a given world
* area old -> list areas in order loaded
*
*/
void do_areas( CHAR_DATA *ch, char *argument )
{
char *header_string1 = "\n\r Author | Area"
" | "
"World\n\r";
char *header_string2 = "-------------+-----------------"
"---------------------+----"
"---------+-----------\n\r";
char *print_string = "%-12s | %-36s | %11s | \n\r";
AREA_DATA *pArea;
bool fWorld;
if(!argument || argument[0] != '\0')
{
if(!strcmp(argument,"all")) {
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->resetmsg);
}
return;
} else {
fWorld = TRUE;
}
}
set_pager_color( AT_PLAIN, 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 (!fWorld || !str_cmp(argument, pArea->resetmsg))
{
pager_printf(ch, print_string,
pArea->author, pArea->name,
pArea->resetmsg);
}
}
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 idle.\n\r", ch );
act(AT_GREY,"$n is no longer idle.", ch, NULL, NULL, TO_CANSEE);
}
else
{
xSET_BIT(ch->act, PLR_AFK);
send_to_char( "You are idling.\n\r", ch );
act(AT_GREY,"$n is idling.", ch, NULL, NULL, TO_CANSEE);
return;
}
}
void do_whois( CHAR_DATA *ch, char *argument) {
CHAR_DATA *victim;
char buf[MAX_STRING_LENGTH];
char buf2[MAX_STRING_LENGTH];
CLAN_DATA *clan;
CLAN_MEMBER *chm;
DESCRIPTOR_DATA *d;
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;
}
for (d = first_descriptor;d;d = d->next) {
if (!d->character) continue;
if (!str_prefix(argument, d->character->name)) break;
}
if (!d) {
send_to_char("No such person is online.\n\r", ch);
return;
}
victim = d->character;
set_pager_color( AT_GREY, ch );
pager_printf(ch, "\n\r%s %s\n\r %s is a %s %s %s, %d years of age, with %d hours of playing time.\n\r",
victim->name,
victim->pcdata->family ? victim->pcdata->family : "",
victim->sex == SEX_MALE ? "He" :
victim->sex == SEX_FEMALE ? "She" :
victim->sex == SEX_HERMAPH ? "Shi" : "It",
victim->sex == SEX_MALE ? "male" :
victim->sex == SEX_FEMALE ? "female" :
victim->sex == SEX_HERMAPH ? "hermaphrodite" : "neuter",
victim->pcdata->type ? victim->pcdata->type : "normal",
victim->species,
victim->pcdata->age_adjust,
((victim->played + (current_time - victim->logon)) / 3600));
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" :
victim->sex == SEX_HERMAPH ? "Hir" : "Its",
show_tilde( victim->pcdata->homepage ) );
if (xIS_SET(victim->act, PLR_BOUNTY)) {
pager_printf(ch, " %s has a total bounty of %d coins.\r\n",
victim->sex == SEX_MALE ? "He" :
victim->sex == SEX_FEMALE ? "She" :
victim->sex == SEX_HERMAPH ? "Shi" : "It",
victim->pcdata->bounty);
}
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 won %d spars, and lost %d.\n\r",
victim->name, victim->pcdata->pkills, victim->pcdata->pdeaths );
if ( victim->pcdata->rkills || victim->pcdata->rdeaths )
pager_printf(ch, "%s has killed %d players, and been killed by a player %d times.\n\r",
victim->name, victim->pcdata->rkills, victim->pcdata->rdeaths );
for (clan = first_clan;clan;clan = clan->next) {
if ((chm = get_member(victim->name, clan)) == NULL)
continue;
if ((!xIS_SET(chm->flags, CL_SECRET)
&& clan->ext_sec <= 3)
|| IS_SET(ch->pcdata->permissions, PERMIT_SECURITY))
pager_printf(ch, "%s&w of %s&w.\n\r",
chm->title, clan->title);
}
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 );
pager_printf(ch, "---------\n\r", ch);
if (victim->first_abit) {
BIT_DATA *bit;
for (bit = victim->first_abit; bit; bit = bit->next) {
if (strlen(bit->desc) > 3)
pager_printf(ch, "%s\r\n", bit->desc);
}
}
if (victim->pcdata->first_qbit) {
BIT_DATA *bit;
for (bit = victim->pcdata->first_qbit; bit; bit = bit->next) {
if (strlen(bit->desc) > 3)
pager_printf(ch, "%s\r\n", bit->desc);
}
}
if(IS_SET(ch->pcdata->permissions, PERMIT_CHANNEL)) {
send_to_pager("-------------------\n\r", ch);
pager_printf(ch, "%s is %shelled at the moment.\n\r",
victim->name,
(victim->pcdata->release_date == 0) ? "not " : "");
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(xIS_SET(victim->act, PLR_NO_CHANNEL) || 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_NO_CHANNEL))
strcat(buf2, " nochannel");
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, victim->desc->user);
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;
}
char *get_talent_rank(CHAR_DATA *ch) {
int max = 0;
int i;
if (ch->pcdata->inborn > -1) {
if (ch->curr_talent[ch->pcdata->inborn] < 10)
return capitalize(ch->species);
return talent_rank[ch->pcdata->inborn][(int)
(UMIN(ch->curr_talent[ch->pcdata->inborn], 120)-10)/10];
} else {
for (i = 0;i < MAX_DEITY;i++) {
if (ch->curr_talent[i] >= ch->curr_talent[max]) max = i;
}
if (ch->curr_talent[max] < 10)
return capitalize(ch->species);
return talent_rank[max][(int)
(UMIN(ch->curr_talent[max], 120)-10)/10];
}
}
/* RANDOM BOOKS */
#if defined(KEY)
#undef KEY
#endif
#define KEY( literal, field, value ) \
if ( !str_cmp( word, literal ) ) \
{ \
field = value; \
fMatch = TRUE; \
break; \
} \
void add_book(BOOK_DATA *book) {
BOOK_DATA *temp_book;
if (!book && !book->name) return;
book->next = NULL;
book->prev = NULL;
temp_book = NULL;
for(temp_book = first_book; temp_book; temp_book = temp_book->next) {
if(strcasecmp(book->name, temp_book->name) < 0) {
INSERT(book, temp_book, first_book, next, prev);
break;
}
}
if (!temp_book) {
LINK(book, first_book, last_book, next, prev);
}
}
void delete_book(BOOK_DATA *book) {
UNLINK(book, first_book, last_book, next, prev);
STRFREE(book->name);
STRFREE(book->title);
STRFREE(book->text);
DISPOSE(book);
}
void save_books() {
FILE *fpout;
BOOK_DATA *book;
if ( (fpout=fopen( BOOK_FILE, "w" )) == NULL ) {
perror( BOOK_FILE );
return;
}
for (book = first_book;book;book = book->next) {
fprintf( fpout, "\n#BOOK\n" );
fprintf( fpout, "Name %s~\n", book->name );
fprintf( fpout, "Title %s~\n", book->title );
fprintf( fpout, "Text %s~\n", book->text );
}
fprintf( fpout, "#END\n" );
fclose( fpout );
}
void load_books( void ) {
FILE *fp;
BOOK_DATA *book;
char *word;
bool done=FALSE;
bool fMatch=FALSE;
if ((fp=fopen(BOOK_FILE, "r"))==NULL) {
bug( "Load_books: no books found!", 0);
return;
}
first_book = NULL;
book = NULL;
while (!done) {
if (feof( fp )) {
break;
} else {
word=fread_word( fp );
}
switch(UPPER(word[0])) {
case '#':
if (!str_cmp("#BOOK", word)) {
if (book) add_book(book);
CREATE(book, BOOK_DATA, 1);
book->title = NULL;
book->text = NULL;
book->name = NULL;
continue;
} else if (!str_cmp(word, "#END")) {
add_book(book);
done=TRUE;
continue;
}
case 'N':
KEY( "Name", book->name, fread_string(fp));
break;
case 'T':
KEY( "Text", book->text, fread_string(fp));
KEY( "Title", book->title, fread_string(fp));
break;
default:
bug("Unknown book keyword: %s", word);
}
}
fclose(fp);
return;
}
void do_set_book(CHAR_DATA *ch, char *argument) {
char buf[MAX_STRING_LENGTH];
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
BOOK_DATA *book;
BOOK_DATA *temp_book;
int i, n;
bool found;
switch( ch->substate )
{
default:
break;
case SUB_HELP_EDIT:
if ( (book = ch->dest_buf) == NULL )
{
bug( "set_help: sub_help_edit: NULL ch->dest_buf", 0 );
stop_editing( ch );
return;
}
STRFREE( book->text );
book->text = copy_buffer( ch );
stop_editing( ch );
return;
case SUB_OBJ_EXTRA:
if ( (book = ch->dest_buf) == NULL )
{
bug( "set_help: sub_help_edit: NULL ch->dest_buf", 0 );
stop_editing( ch );
return;
}
STRFREE( book->title );
book->title = copy_buffer( ch );
stop_editing( ch );
return;
}
argument = one_argument(argument, arg1);
argument = one_argument(argument, arg2);
if (!str_cmp(arg1, "add")) {
if (str_cmp(arg2, "book")) {
send_to_char("Syntax: setbook add book <title>\n\r", ch);
return;
}
if (!argument) {
send_to_char("Name the book what?\n\r", ch);
return;
}
CREATE (book, BOOK_DATA, 1);
book->name = STRALLOC(argument);
add_book(book);
i = 0;
for (temp_book = first_book;temp_book;temp_book = temp_book->next) {
i++;
if (temp_book == book) break;
}
sprintf(buf, "Book %s created - number %d.\n\r", book->name, i);
send_to_char(buf, ch);
log_string(buf);
return;
} else if (!str_cmp(arg1, "list")) {
if (!first_book) {
send_to_char("There are no books.\n\r", ch);
return;
}
i = 0;
for (book = first_book;book;book = book->next) {
i++;
ch_printf(ch, "&C%d&c: %s\n\r", i, book->name);
}
return;
} else if (!str_cmp(arg1, "count")) {
if (!first_book) {
send_to_char("There are no books.\n\r", ch);
return;
}
i = 0;
for (book = first_book;book;book = book->next)
i++;
ch_printf(ch, "&cThere are &C%d &cbooks.\n\r", i);
return;
} else if (!str_cmp(arg1, "find")) {
found = FALSE;
i = 0;
for (book = first_book;book;book = book->next) {
i++;
if (is_name(arg2, book->name)
|| is_name(argument, book->name)) {
ch_printf(ch, "&C%d&c: %s\n\r", i, book->name);
found = TRUE;
}
}
if (!found)
send_to_char("No matching books found.\n\r", ch);
return;
} else if (!str_cmp(arg1, "save")) {
save_books();
send_to_char("Books saved.\n\r", ch);
return;
} else if (!str_cmp(arg1, "load")) {
load_books();
send_to_char("Books loaded.\n\r", ch);
return;
}
if (arg2 && arg2[0] != '\0') {
i = atoi(arg2);
n = 0;
for (book = first_book;book;book = book->next) {
n++;
if (n == i) break;
}
if (!book) {
ch_printf(ch, "&cBook &C%d &cnot found.\n\r", i);
return;
}
if (!str_cmp(arg1, "edit")) {
ch->substate = SUB_HELP_EDIT;
ch->dest_buf = book;
start_editing( ch, book->text );
return;
}
if (!str_cmp(arg1, "show")) {
ch_printf(ch, "&C%d: %s\n\r", i, book->name);
ch_printf(ch, "&C&c%s", book->title);
ch_printf(ch, "&z&W%s\n\r", book->text);
return;
}
if (!str_cmp(arg1, "name")) {
UNLINK(book, first_book, last_book, next, prev);
STRFREE(book->name);
book->name = STRALLOC(argument);
add_book(book);
i = 0;
for (temp_book = first_book;temp_book;temp_book = temp_book->next) {
i++;
if (temp_book == book) break;
}
ch_printf(ch, "&cBook name changed to &C%s&c, number is now %d.\n\r", book->name,i);
return;
}
if (!str_cmp(arg1, "title")) {
ch->substate = SUB_OBJ_EXTRA;
ch->dest_buf = book;
start_editing( ch, book->title );
return;
}
if (!str_cmp(arg1, "delete")) {
delete_book(book);
ch_printf(ch, "&cBook &C%d &cdeleted.\n\r", i);
return;
}
}
send_to_char("\n\rSyntax: setbook <add|edit|delete|text|title> <number>", ch);
send_to_char("\n\r setbook <save|list>\n\r", ch);
}
/* NEW SERRIYAN DREAMS HELP FILE SYSTEM */
/* Compares two strings and returns how many letters match */
int best_match(const char *astr, const char *bstr) {
int match, a, b;
if (!astr) return 0;
if (!bstr) return 0;
match = 0;
for (a = 0;astr[a] != '\0';a++) {
for (b = a;bstr[b] != '\0';b++) {
if (astr[a] == bstr[b]) {
match++;
if (a == b) match++;
break;
}
}
}
return match;
}
/* Add a help file to the help hash table */
void add_new_help(NEW_HELP_DATA *help) {
int hash, x;
NEW_HELP_DATA *tmp;
if ( !help ) return;
if ( !help->name ) return;
for (x = 0; help->name[x] != '\0'; x++)
help->name[x] = LOWER(help->name[x]);
hash = help->name[0] % 126;
if ((tmp = help_hash[hash]) == NULL) {
help->next = help_hash[hash];
help_hash[hash] = help;
return;
}
for (; tmp; tmp = tmp->next)
if (!tmp->next) {
tmp->next = help;
help->next = NULL;
}
top_help++;
return;
}
void free_new_help(NEW_HELP_DATA *help) {
STRFREE(help->name);
STRFREE(help->text);
DISPOSE(help);
}
void unlink_new_help(NEW_HELP_DATA *help ) {
NEW_HELP_DATA *tmp, *tmp_next;
int hash;
if (!help) return;
hash = help->name[0] % 126;
if (help == (tmp=help_hash[hash])) {
help_hash[hash] = tmp->next;
return;
}
for (;tmp;tmp = tmp_next) {
tmp_next = tmp->next;
if (help == tmp_next) {
tmp->next = tmp_next->next;
return;
}
}
top_help--;
}
void save_new_helps() {
FILE *fpout;
NEW_HELP_DATA *help;
int x;
if ( (fpout=fopen( HELP_FILE, "w" )) == NULL ) {
perror( HELP_FILE );
return;
}
for (x = 0; x < 126; x++) {
for (help = help_hash[x]; help; help = help->next) {
if (!help->name || help->name[0] == '\0')
continue;
fprintf( fpout, "\n#HELP\n" );
fprintf( fpout, "Name %s~\n", help->name );
fprintf( fpout, "Text %s~\n", help->text );
fprintf( fpout, "End\n\n" );
}
}
fprintf( fpout, "#END\n" );
fclose( fpout );
}
void load_new_helps( void ) {
FILE *fp;
NEW_HELP_DATA *help;
char *word;
bool done=FALSE;
bool fMatch=FALSE;
if ((fp=fopen(HELP_FILE, "r"))==NULL) {
bug( "Load_helps: no helps found!", 0);
return;
}
while (!done) {
if (feof( fp )) {
break;
} else {
word=fread_word( fp );
}
switch(UPPER(word[0])) {
case '#':
if (!str_cmp("#HELP", word)) {
CREATE(help, NEW_HELP_DATA, 1);
help->name = NULL;
help->text = NULL;
continue;
} else if (!str_cmp(word, "#END")) {
done=TRUE;
continue;
}
case 'E':
if (!str_cmp(word, "End")) {
if (!help->name) {
free_new_help(help);
return;
}
if ( !str_cmp( help->name, "greeting" ) )
help_greeting = help->text;
add_new_help(help);
}
break;
case 'N':
KEY( "Name", help->name, fread_string(fp));
break;
case 'T':
KEY( "Text", help->text, fread_string(fp));
break;
default:
bug("Unknown help keyword: %s", word);
}
}
fclose(fp);
return;
}
void do_set_help(CHAR_DATA *ch, char *argument) {
char buf[MAX_STRING_LENGTH];
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
NEW_HELP_DATA *help;
int hash;
switch( ch->substate )
{
default:
break;
case SUB_HELP_EDIT:
if ( (help = ch->dest_buf) == NULL )
{
bug( "set_help: sub_help_edit: NULL ch->dest_buf", 0 );
stop_editing( ch );
return;
}
if ( help_greeting == help->text )
help_greeting = NULL;
STRFREE( help->text );
help->text = copy_buffer( ch );
if ( !help_greeting )
help_greeting = help->text;
stop_editing( ch );
return;
}
argument = one_argument(argument, arg1);
argument = one_argument(argument, arg2);
if (!str_cmp(arg1, "add")) {
if (arg2 && arg2[0] != '\0') {
CREATE (help, NEW_HELP_DATA, 1);
help->name = STRALLOC(arg2);
add_new_help(help);
sprintf(buf, "Help for %s created.\n\r", arg2);
send_to_char(buf, ch);
log_string(buf);
return;
}
} else if (!str_cmp(arg1, "save")) {
save_new_helps();
send_to_char("Help files saved.\n\r", ch);
return;
} else if (!str_cmp(arg1, "load")) {
load_new_helps();
send_to_char("Help files loaded.\n\r", ch);
return;
} else if (!str_cmp(arg1, "convert")) {
HELP_DATA *old_help;
for (old_help = first_help;old_help;old_help = old_help->next) {
CREATE(help, NEW_HELP_DATA, 1);
help->name = STRALLOC(old_help->keyword);
help->text = STRALLOC(old_help->text);
add_new_help(help);
}
send_to_char("All help files converted successfully.\n\rPlease double-check to make sure everything went properly.", ch);
return;
}
if (arg2 && arg2[0] != '\0') {
hash = LOWER(arg2[0]) % 126;
for (help = help_hash[hash];help;help = help->next )
if (!str_cmp(arg2, help->name)) break;
if (!help) {
ch_printf(ch, "&cNo help found for &C%s.\n\r",
arg2);
return;
}
if (!str_cmp(arg1, "edit")) {
ch->substate = SUB_HELP_EDIT;
ch->dest_buf = help;
start_editing( ch, help->text );
return;
}
if (!str_cmp(arg1, "text")) {
sprintf(arg2, "%s\n\r", argument);
STRFREE(help->text);
help->text = STRALLOC(arg2);
ch_printf(ch, "&cHelp text for &C%s &cchanged.\n\r",
arg2);
return;
}
if (!str_cmp(arg1, "append")) {
sprintf(arg2, "%s%s\n\r", help->text, argument);
STRFREE(help->text);
help->text = STRALLOC(arg2);
ch_printf(ch, "&CHelp text for &C%s &cappended.\n\r",
help->name);
return;
}
if (!str_cmp(arg1, "delete")) {
unlink_new_help(help);
free_new_help(help);
ch_printf(ch, "&cHelp for &C%s &cdeleted.\n\r",
arg2);
return;
}
if (!str_cmp(arg1, "rename")) {
if (!argument || argument[0] == '\0') {
send_to_char("Rename it to what?\n\r", ch);
return;
}
unlink_new_help(help);
STRFREE(help->name);
help->name = STRALLOC(argument);
add_new_help(help);
ch_printf(ch, "&cHelp for &C%s &crenamed to &C%s.\n\r",
arg2, argument);
return;
}
}
send_to_char("\n\rSyntax: sethelp <add|edit|rename|delete|text|append> <name>", ch);
send_to_char("\n\r sethelp save\n\r", ch);
}
/* Searches for a help file, and displays the best match */
void do_new_help(CHAR_DATA *ch, char *argument) {
int hash, match, i;
NEW_HELP_DATA *help, *best;
if (!argument || argument[0] == '\0') {
send_to_char("&cAll help files:&C\n\r", ch);
for (hash = 0; hash < 126; hash++)
for (help = help_hash[hash];help;help = help->next ) {
ch_printf(ch, "%-15s", help->name);
if (++i % 5 == 0)
send_to_char("\n\r", ch);
}
send_to_char("\n\r", ch);
return;
}
if (argument[1] == '\0') {
ch_printf(ch, "&cHelp files starting with &C%c:\n\r",
argument[0]);
for (help = help_hash[LOWER(argument[0]) % 126];help;help = help->next ) {
ch_printf(ch, "%-15s", help->name);
if (++i % 5 == 0)
send_to_char("\n\r", ch);
}
send_to_char("\n\r", ch);
return;
}
if ( !IS_NPC(ch) && !str_cmp( argument, "newbie" ) )
SET_BIT(ch->pcdata->flags, PCFLAG_HELPSTART);
hash = LOWER(argument[0]) % 126;
match = i = 0;
help = best = NULL;
for (help = help_hash[hash];help;help = help->next ) {
i = best_match(argument, help->name);
if (i > match) {
match = i;
best = help;
if (i >= strlen(argument))
ch_printf(ch, "&cPossible match: &C%s&c, with match quality of &C%d.\n\r",
help->name, i);
} else if (i >= strlen(argument)*1.5) {
ch_printf(ch, "&cPossible match: &C%s&c, with match quality of &C%d.\n\r",
help->name, i);
}
}
if (!best) {
ch_printf(ch, "&cUnable to find help for &C%s.\n\r",
argument);
return;
}
ch_printf(ch, "&cBest match: &C%s&c, with match quality of &C%d.\n\r",
best->name, match);
ch_printf(ch, "&z&W%s\n\r", best->text);
}
void do_story(CHAR_DATA *ch, char *argument) {
do_new_help(ch, "story");
}
void do_news(CHAR_DATA *ch, char *argument) {
do_new_help(ch, "news_latest");
}