/***************************************************************************** * DikuMUD (C) 1990, 1991 by: * * Sebastian Hammer, Michael Seifert, Hans Henrik Staefeldt, Tom Madsen, * * and Katja Nyboe. * *---------------------------------------------------------------------------* * MERC 2.1 (C) 1992, 1993 by: * * Michael Chastain, Michael Quan, and Mitchell Tse. * *---------------------------------------------------------------------------* * SMAUG 1.4 (C) 1994, 1995, 1996, 1998 by: Derek Snider. * * Team: Thoric, Altrag, Blodkai, Narn, Haus, Scryn, Rennard, Swordbearer, * * gorog, Grishnakh, Nivek, Tricops, and Fireblade. * *---------------------------------------------------------------------------* * SMAUG 1.7 FUSS by: Samson and others of the SMAUG community. * * Their contributions are greatly appreciated. * *---------------------------------------------------------------------------* * LoP (C) 2006, 2007, 2008 by: the LoP team. * *---------------------------------------------------------------------------* * Informational module * *****************************************************************************/ #include <ctype.h> #include <stdio.h> #include <string.h> #include "h/mud.h" #include "h/sha256.h" bool check_parse_name( char *name, bool newchar ); CMDF( do_dig ); CMDF( do_detrap ); CMDF( do_pushup ); CMDF( do_situp ); /* * Keep players from defeating examine progs -Druid * False = do not trigger * True = Trigger */ bool EXA_prog_trigger = true; /* Local functions. */ void show_char_to_char_0( CHAR_DATA *victim, CHAR_DATA *ch ); void show_char_to_char_1( CHAR_DATA *victim, CHAR_DATA *ch ); void show_char_to_char( CHAR_DATA *list, CHAR_DATA *ch ); bool check_blind( CHAR_DATA *ch ); void show_condition( CHAR_DATA *ch, CHAR_DATA *victim ); char *format_obj_to_char( OBJ_DATA *obj, CHAR_DATA *ch, bool fShort ) { static char buf[MSL]; bool glowsee = false; 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_immortal( ch ) ) snprintf( buf, sizeof( buf ), "[%d]", obj->pIndexData->vnum ); if( is_obj_stat( obj, ITEM_INVIS ) ) mudstrlcat( buf, "(Invis) ", sizeof( buf ) ); if( IS_AFFECTED( ch, AFF_DETECT_EVIL ) || xIS_SET( ch->act, PLR_HOLYLIGHT ) ) { if( is_obj_stat( obj, ITEM_ANTI_EVIL ) ) { if( !is_obj_stat( obj, ITEM_ANTI_NEUTRAL ) ) { if( is_obj_stat( obj, ITEM_ANTI_GOOD ) ) mudstrlcat( buf, "(Smouldering Red-White) ", sizeof( buf ) ); else mudstrlcat( buf, "(Flaming Red) ", sizeof( buf ) ); } else if( !is_obj_stat( obj, ITEM_ANTI_GOOD ) ) mudstrlcat( buf, "(Smouldering Red-Grey) ", sizeof( buf ) ); } else { if( is_obj_stat( obj, ITEM_ANTI_NEUTRAL ) ) { if( !is_obj_stat( obj, ITEM_ANTI_GOOD ) ) mudstrlcat( buf, "(Flaming Grey) ", sizeof( buf ) ); else mudstrlcat( buf, "(Smouldering Grey-White) ", sizeof( buf ) ); } else if( is_obj_stat( obj, ITEM_ANTI_GOOD ) ) mudstrlcat( buf, "(Flaming White) ", sizeof( buf ) ); } } if( ( IS_AFFECTED( ch, AFF_DETECT_MAGIC ) || xIS_SET( ch->act, PLR_HOLYLIGHT ) ) && is_obj_stat( obj, ITEM_MAGIC ) ) mudstrlcat( buf, "(Magical) ", sizeof( buf ) ); if( !glowsee && is_obj_stat( obj, ITEM_GLOW ) ) mudstrlcat( buf, "(Glowing) ", sizeof( buf ) ); if( is_obj_stat( obj, ITEM_HIDDEN ) ) mudstrlcat( buf, "(Hidden) ", sizeof( buf ) ); if( is_obj_stat( obj, ITEM_BURIED ) ) mudstrlcat( buf, "(Buried) ", sizeof( buf ) ); if( is_immortal( ch ) && is_obj_stat( obj, ITEM_PROTOTYPE ) ) mudstrlcat( buf, "(PROTO) ", sizeof( buf ) ); if( ( IS_AFFECTED( ch, AFF_DETECTTRAPS ) || xIS_SET( ch->act, PLR_HOLYLIGHT ) ) && is_trapped( obj ) ) mudstrlcat( buf, "(Trap) ", sizeof( buf ) ); if( fShort ) { if( glowsee && !is_immortal( ch ) ) mudstrlcpy( buf, "the faint glow of something", sizeof( buf ) ); else if( obj->short_descr ) mudstrlcat( buf, obj->short_descr, sizeof( buf ) ); } else { if( glowsee && !is_immortal( ch ) ) mudstrlcpy( buf, "You see the faint glow of something nearby.", sizeof( buf ) ); else if( obj->description ) mudstrlcat( buf, obj->description, sizeof( buf ) ); } if( obj->owner && obj->owner[0] != '\0' ) { char buf2[MSL]; sprintf( buf2, " owned by %s", obj->owner ); strcat( buf, buf2 ); } 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!!!"; } /* Copy of num_punct, only changed to handle doubles */ char *double_punct( double foo ) { int index_new, rest, x; unsigned int nindex; char buf[MIL]; static char buf_new[MIL]; snprintf( buf, sizeof( buf ), "%.f", foo ); rest = strlen( buf ) % 3; for( nindex = index_new = 0; nindex < strlen( buf ); nindex++, index_new++ ) { x = nindex - rest; if( nindex != 0 && ( x % 3 ) == 0 ) buf_new[index_new++] = ','; buf_new[index_new] = buf[nindex]; } buf_new[index_new] = '\0'; return buf_new; } /* * This is the punct snippet from Desden el Chaman Tibetano - Nov 1998 * Email: jlalbatros@mx2.redestb.es */ char *num_punct( int foo ) { int index_new, rest, x; unsigned int nindex; char buf[16]; static char buf_new[16]; snprintf( buf, sizeof( buf ), "%d", foo ); rest = strlen( buf ) % 3; for( nindex = index_new = 0; nindex < strlen( buf ); nindex++, index_new++ ) { x = nindex - rest; if( nindex != 0 && ( x % 3 ) == 0 ) buf_new[index_new++] = ','; buf_new[index_new] = buf[nindex]; } buf_new[index_new] = '\0'; return buf_new; } char *un_num_punct( unsigned int foo ) { int index_new, rest, x; unsigned int nindex; char buf[16]; static char buf_new[16]; snprintf( buf, sizeof( buf ), "%u", foo ); rest = strlen( buf ) % 3; for( nindex = index_new = 0; nindex < strlen( buf ); nindex++, index_new++ ) { x = nindex - rest; if( nindex != 0 && ( x % 3 ) == 0 ) buf_new[index_new++] = ','; 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; char *pstrShow; OBJ_DATA *obj; int count, offcount, tmp, ms, cnt; int *prgnShow, *pitShow, nShow, iShow; 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.\r\n", 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.\r\n", 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] = STRALLOC( hallucinated_object( ms, fShort ) ); prgnShow[nShow] = 1; pitShow[nShow] = number_range( 0, ITEM_TYPE_MAX - 1 ); nShow++; --tmp; } if( obj->wear_loc == WEAR_NONE && ( can_see_obj( ch, obj ) || ( is_obj_stat( obj, ITEM_INVIS ) && is_obj_stat( obj, ITEM_GLOW ) && !is_obj_stat( obj, ITEM_BURIED ) && !is_obj_stat( obj, ITEM_HIDDEN ) ) ) && ( 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] = STRALLOC( pstrShow ); prgnShow[nShow] = obj->count; nShow++; } } } if( tmp > 0 ) { int x; for( x = 0; x < tmp; x++ ) { prgpstrShow[nShow] = STRALLOC( hallucinated_object( ms, fShort ) ); prgnShow[nShow] = 1; pitShow[nShow] = number_range( 0, ITEM_TYPE_MAX - 1 ); 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: case ITEM_FISH: 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( prgnShow[iShow] != 1 ) ch_printf( ch, " (%d)", prgnShow[iShow] ); send_to_char( "\r\n", ch ); STRFREE( 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.\r\n", ch ); } DISPOSE( prgpstrShow ); DISPOSE( prgnShow ); DISPOSE( pitShow ); } /* Show fancy descriptions for certain spell affects - Thoric */ void show_visible_affects_to_char( CHAR_DATA *victim, CHAR_DATA *ch ) { char name[MSL]; if( is_npc( victim ) ) mudstrlcpy( name, victim->short_descr, sizeof( name ) ); else mudstrlcpy( name, victim->name, sizeof( 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.\r\n", name ); else if( is_evil( victim ) ) ch_printf( ch, "%s shimmers beneath an aura of dark energy.\r\n", name ); else ch_printf( ch, "%s is shrouded in flowing shadow and light.\r\n", 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.\r\n", name ); } if( IS_AFFECTED( victim, AFF_SHOCKSHIELD ) ) { set_char_color( AT_BLUE, ch ); ch_printf( ch, "%s is surrounded by cascading torrents of energy.\r\n", 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.\r\n", 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.\r\n", name ); } if( IS_AFFECTED( victim, AFF_VENOMSHIELD ) ) { set_char_color( AT_GREEN, ch ); ch_printf( ch, "%s is enshrouded in a choking cloud of gas.\r\n", name ); } if( IS_AFFECTED( victim, AFF_CHARM ) ) { set_char_color( AT_MAGIC, ch ); ch_printf( ch, "%s wanders in a dazed, zombie-like state.\r\n", name ); } } void show_affects_to_char( CHAR_DATA *victim, CHAR_DATA *ch ) { char name[MSL]; if( is_npc( victim ) ) mudstrlcpy( name, victim->short_descr, sizeof( name ) ); else mudstrlcpy( name, victim->name, sizeof( name ) ); name[0] = toupper( name[0] ); if( is_npc( ch ) || xIS_SET( ch->act, PLR_GROUPAFFECTS ) ) { /* Show a single line message */ if( !IS_AFFECTED( victim, AFF_SANCTUARY ) && !IS_AFFECTED( victim, AFF_FIRESHIELD ) && !IS_AFFECTED( victim, AFF_SHOCKSHIELD ) && !IS_AFFECTED( victim, AFF_ACIDMIST ) && !IS_AFFECTED( victim, AFF_ICESHIELD ) && !IS_AFFECTED( victim, AFF_VENOMSHIELD ) && !IS_AFFECTED( victim, AFF_CHARM ) ) return; ch_printf( ch, "%s%s &[magic]is affected by: ", victim->sex == SEX_MALE ? color_str( AT_MALE, ch ) : victim->sex == SEX_FEMALE ? color_str( AT_FEMALE, ch ) : color_str( AT_PERSON, ch ), name ); if( IS_AFFECTED( victim, AFF_SANCTUARY ) ) send_to_char( "&[white]Sanctuary ", ch ); if( IS_AFFECTED( victim, AFF_FIRESHIELD ) ) send_to_char( "&[fire]Fireshield ", ch ); if( IS_AFFECTED( victim, AFF_SHOCKSHIELD ) ) send_to_char( "&[blue]Shockshield ", ch ); if( IS_AFFECTED( victim, AFF_ACIDMIST ) ) send_to_char( "&[green]Acidmist ", ch ); if( IS_AFFECTED( victim, AFF_ICESHIELD ) ) send_to_char( "&[lblue]Iceshield ", ch ); if( IS_AFFECTED( victim, AFF_VENOMSHIELD ) ) send_to_char( "&[green]Venomshield ", ch ); if( IS_AFFECTED( victim, AFF_CHARM ) ) send_to_char( "&[magic]Charm ", ch ); send_to_char( "\r\n", ch ); return; } show_visible_affects_to_char( victim, ch ); } void show_char_to_char_0( CHAR_DATA *victim, CHAR_DATA *ch ) { TIMER *timer; char buf[MSL], buf1[MSL]; char *person; buf[0] = '\0'; person = color_str( AT_PERSON, ch ); if( victim->sex == SEX_MALE ) person = color_str( AT_MALE, ch ); if( victim->sex == SEX_FEMALE ) person = color_str( AT_FEMALE, ch ); set_char_color( AT_PERSON, ch ); if( is_immortal( ch ) && is_npc( victim ) ) { snprintf( buf1, sizeof( buf1 ), "%s[&W%d%s]", person, victim->pIndexData->vnum, person ); mudstrlcat( buf, buf1, sizeof( buf ) ); } if( !is_npc( victim ) && !victim->desc ) { snprintf( buf1, sizeof( buf1 ), "%s[&W(Link Dead)%s] ", person, person ); mudstrlcat( buf, buf1, sizeof( buf ) ); } if( !is_npc( victim ) && xIS_SET( victim->act, PLR_AFK ) ) { snprintf( buf1, sizeof( buf1 ), "%s[&WAFK%s] ", person, person ); mudstrlcat( buf, buf1, sizeof( buf ) ); } if( ( !is_npc( victim ) && xIS_SET( victim->act, PLR_WIZINVIS ) ) || ( is_npc( victim ) && xIS_SET( victim->act, ACT_MOBINVIS ) ) ) { if( !is_npc( victim ) ) snprintf( buf1, sizeof( buf1 ), "%s(Invis &W%d%s) ", person, victim->pcdata->wizinvis, person ); else snprintf( buf1, sizeof( buf1 ), "%s(Mobinvis &W%d%s) ", person, victim->mobinvis, person ); mudstrlcat( buf, buf1, sizeof( buf ) ); } if( !is_npc( victim ) ) { if( is_immortal( victim ) ) { if( is_retired( victim ) ) snprintf( buf1, sizeof( buf1 ), "%s(&WRetired%s) ", person, person ); else if( is_guest( victim ) ) snprintf( buf1, sizeof( buf1 ), "%s(&WGuest%s) ", person, person ); else snprintf( buf1, sizeof( buf1 ), "%s(&WImmortal%s) ", person, person ); mudstrlcat( buf, buf1, sizeof( buf ) ); } if( victim->pcdata->clan && xIS_SET( victim->pcdata->flags, PCFLAG_DEADLY ) && victim->pcdata->clan->badge && victim->pcdata->clan->clan_type == CLAN_PLAIN ) { snprintf( buf1, sizeof( buf1 ), "%s%s%s ", person, victim->pcdata->clan->badge, person ); mudstrlcat( buf, buf1, sizeof( buf ) ); } else if( can_pkill( victim ) && !is_immortal( victim ) ) { snprintf( buf1, sizeof( buf1 ), "%s(&WUnclanned%s) ", person, person ); mudstrlcat( buf, buf1, sizeof( buf ) ); } } if( IS_AFFECTED( victim, AFF_INVISIBLE ) ) { snprintf( buf1, sizeof( buf1 ), "%s(&WInvis%s) ", person, person ); mudstrlcat( buf, buf1, sizeof( buf ) ); } if( IS_AFFECTED( victim, AFF_HIDE ) ) { snprintf( buf1, sizeof( buf1 ), "%s(&WHide%s) ", person, person ); mudstrlcat( buf, buf1, sizeof( buf ) ); } if( IS_AFFECTED( victim, AFF_PASS_DOOR ) ) { snprintf( buf1, sizeof( buf1 ), "%s(&WTranslucent%s) ", person, person ); mudstrlcat( buf, buf1, sizeof( buf ) ); } if( IS_AFFECTED( victim, AFF_FAERIE_FIRE ) ) { snprintf( buf1, sizeof( buf1 ), "%s(&PPink Aura%s) ", person, person ); mudstrlcat( buf, buf1, sizeof( buf ) ); } if( IS_AFFECTED( ch, AFF_DETECT_EVIL ) ) { if( is_evil( victim ) ) snprintf( buf1, sizeof( buf1 ), "%s(&RRed Aura%s) ", person, person ); if( is_neutral( victim ) ) snprintf( buf1, sizeof( buf1 ), "%s(&zGrey Aura%s) ", person, person ); if( is_good( victim ) ) snprintf( buf1, sizeof( buf1 ), "%s(&WWhite Aura%s) ", person, person ); mudstrlcat( buf, buf1, sizeof( buf ) ); } if( IS_AFFECTED( victim, AFF_BERSERK ) ) { snprintf( buf1, sizeof( buf1 ), "%s(&RWild-eyed%s) ", person, person ); mudstrlcat( buf, buf1, sizeof( buf ) ); } if( is_npc( victim ) && is_immortal( ch ) && xIS_SET( victim->act, ACT_PROTOTYPE ) ) { snprintf( buf1, sizeof( buf1 ), "%s(&WPROTO%s) ", person, person ); mudstrlcat( buf, buf1, sizeof( buf ) ); } if( is_npc( victim ) && ch->mount && ch->mount == victim && ch->in_room == ch->mount->in_room ) { snprintf( buf1, sizeof( buf1 ), "%s(&WMount%s) ", person, person ); mudstrlcat( buf, buf1, sizeof( buf ) ); } if( victim->desc && victim->desc->connected == CON_EDITING ) { snprintf( buf1, sizeof( buf1 ), "%s(&WWriting%s) ", person, person ); mudstrlcat( buf, buf1, sizeof( buf ) ); } if( victim->morph ) { snprintf( buf1, sizeof( buf1 ), "%s(&WMorphed%s) ", person, person ); mudstrlcat( buf, buf1, sizeof( buf ) ); } if( ( victim->position == victim->defposition && victim->long_descr[0] != '\0' ) || ( victim->morph && victim->morph->morph && victim->morph->morph->defpos == victim->position ) ) { if( victim->morph ) { if( !is_immortal( ch ) ) { if( victim->morph->morph ) mudstrlcat( buf, victim->morph->morph->long_desc, sizeof( buf ) ); else mudstrlcat( buf, victim->long_descr, sizeof( buf ) ); } else { mudstrlcat( buf, PERS( victim, ch ), sizeof( buf ) ); if( !is_npc( victim ) && !xIS_SET( ch->act, PLR_BRIEF ) ) mudstrlcat( buf, victim->pcdata->title, sizeof( buf ) ); mudstrlcat( buf, ".\r\n", sizeof( buf ) ); } } else mudstrlcat( buf, victim->long_descr, sizeof( buf ) ); send_to_char( buf, ch ); show_affects_to_char( victim, ch ); return; } else { if( victim->morph && victim->morph->morph && !is_immortal( ch ) ) mudstrlcat( buf, MORPHPERS( victim, ch ), sizeof( buf ) ); else mudstrlcat( buf, PERS( victim, ch ), sizeof( buf ) ); } if( !is_npc( victim ) && !xIS_SET( ch->act, PLR_BRIEF ) ) mudstrlcat( buf, victim->pcdata->title, sizeof( buf ) ); mudstrlcat( buf, person, sizeof( buf ) ); if( ( timer = get_timerptr( victim, TIMER_DO_FUN ) ) ) { if( timer->do_fun == do_cast ) mudstrlcat( buf, " is here chanting.", sizeof( buf ) ); else if( timer->do_fun == do_dig ) mudstrlcat( buf, " is here digging.", sizeof( buf ) ); else if( timer->do_fun == do_search ) mudstrlcat( buf, " is searching for something.", sizeof( buf ) ); else if( timer->do_fun == do_detrap ) mudstrlcat( buf, " is working with a trap here.", sizeof( buf ) ); else if( timer->do_fun == do_pushup ) mudstrlcat( buf, " is doing pushups.", sizeof( buf ) ); else if( timer->do_fun == do_situp ) mudstrlcat( buf, " is doing situps.", sizeof( buf ) ); else mudstrlcat( buf, " is doing something.", sizeof( buf ) ); } else { switch( victim->position ) { case POS_DEAD: mudstrlcat( buf, " is DEAD!!", sizeof( buf ) ); break; case POS_MORTAL: mudstrlcat( buf, " is mortally wounded.", sizeof( buf ) ); break; case POS_INCAP: mudstrlcat( buf, " is incapacitated.", sizeof( buf ) ); break; case POS_STUNNED: mudstrlcat( buf, " is lying here stunned.", sizeof( buf ) ); break; case POS_SLEEPING: if( ch->position == POS_SITTING || ch->position == POS_RESTING ) mudstrlcat( buf, " is sleeping nearby.", sizeof( buf ) ); else mudstrlcat( buf, " is deep in slumber here.", sizeof( buf ) ); break; case POS_RESTING: if( ch->position == POS_RESTING ) mudstrlcat( buf, " is sprawled out alongside you.", sizeof( buf ) ); else if( ch->position == POS_MOUNTED ) mudstrlcat( buf, " is sprawled out at the foot of your mount.", sizeof( buf ) ); else mudstrlcat( buf, " is sprawled out here.", sizeof( buf ) ); break; case POS_SITTING: if( ch->position == POS_SITTING ) mudstrlcat( buf, " sits here with you.", sizeof( buf ) ); else if( ch->position == POS_RESTING ) mudstrlcat( buf, " sits nearby as you lie around.", sizeof( buf ) ); else mudstrlcat( buf, " sits upright here.", sizeof( buf ) ); break; case POS_STANDING: if( is_immortal( victim ) ) mudstrlcat( buf, " is here before you.", sizeof( buf ) ); else if( ( victim->in_room->sector_type == SECT_UNDERWATER || victim->in_room->sector_type == SECT_OCEANFLOOR ) && !IS_AFFECTED( victim, AFF_AQUA_BREATH ) && !is_npc( victim ) ) mudstrlcat( buf, " is drowning here.", sizeof( buf ) ); else if( victim->in_room->sector_type == SECT_UNDERWATER ) mudstrlcat( buf, " is here in the water.", sizeof( buf ) ); else if( victim->in_room->sector_type == SECT_OCEANFLOOR ) mudstrlcat( buf, " is standing here in the water.", sizeof( buf ) ); else if( IS_AFFECTED( victim, AFF_FLOATING ) || IS_AFFECTED( victim, AFF_FLYING ) ) mudstrlcat( buf, " is hovering here.", sizeof( buf ) ); else mudstrlcat( buf, " is standing here.", sizeof( buf ) ); break; case POS_SHOVE: mudstrlcat( buf, " is being shoved around.", sizeof( buf ) ); break; case POS_DRAG: mudstrlcat( buf, " is being dragged around.", sizeof( buf ) ); break; case POS_MOUNTED: mudstrlcat( buf, " is here, upon ", sizeof( buf ) ); if( !victim->mount ) mudstrlcat( buf, "thin air???", sizeof( buf ) ); else if( victim->mount == ch ) mudstrlcat( buf, "your back.", sizeof( buf ) ); else if( victim->in_room == victim->mount->in_room ) { mudstrlcat( buf, PERS( victim->mount, ch ), sizeof( buf ) ); mudstrlcat( buf, ".", sizeof( buf ) ); } else mudstrlcat( buf, "someone who left??", sizeof( buf ) ); break; case POS_FIGHTING: case POS_EVASIVE: case POS_DEFENSIVE: case POS_AGGRESSIVE: case POS_BERSERK: mudstrlcat( buf, " is here, fighting ", sizeof( buf ) ); if( !victim->fighting ) { mudstrlcat( buf, "thin air???", sizeof( buf ) ); /* 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 ) mudstrlcat( buf, "YOU!", sizeof( buf ) ); else if( victim->in_room == victim->fighting->who->in_room ) { mudstrlcat( buf, PERS( victim->fighting->who, ch ), sizeof( buf ) ); mudstrlcat( buf, ".", sizeof( buf ) ); } else mudstrlcat( buf, "someone who left??", sizeof( buf ) ); break; } } mudstrlcat( buf, "\r\n", sizeof( buf ) ); buf[0] = UPPER( buf[0] ); send_to_char( buf, ch ); show_affects_to_char( victim, ch ); } void show_char_to_char_1( CHAR_DATA *victim, CHAR_DATA *ch ) { OBJ_DATA *obj; int iWear; bool found; if( can_see( victim, ch ) && !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 ) { if( victim->morph && victim->morph->morph && victim->morph->morph->description ) send_to_char( victim->morph->morph->description, ch ); else send_to_char( victim->description, ch ); } else { if( victim->morph && victim->morph->morph && victim->morph->morph->description ) 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 < WEAR_MAX; iWear++ ) { if( ( obj = get_eq_char( victim, iWear ) ) && can_see_obj( ch, obj ) ) { if( !found ) { send_to_char( "\r\n", 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 ) && race_table[victim->race] && race_table[victim->race]->where_name[iWear] ) 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( "\r\n", ch ); } } /* Crash fix here by Thoric */ if( is_npc( ch ) || victim == ch ) return; if( is_immortal( ch ) ) { if( is_npc( victim ) ) ch_printf( ch, "\r\nMobile #%d '%s' ", victim->pIndexData->vnum, victim->name ); else ch_printf( ch, "\r\n%s ", victim->name ); ch_printf( ch, "is level %d", victim->level ); if( !is_npc( victim ) ) ch_printf( ch, " and a %s %s", dis_race_name( victim->race ), dis_class_name( victim->Class ) ); send_to_char( ".\r\n", ch ); } if( number_percent( ) < LEARNED( ch, gsn_peek ) ) { ch_printf( ch, "\r\nYou peek at %s inventory:\r\n", 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 ) ) 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.\r\n", ch ); } } } 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!\r\n", 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 show_compass( CHAR_DATA *ch ) { EXIT_DATA *pexit; char first[50], last[50]; char dir_n[50], dir_e[50], dir_s[50], dir_w[50], dir_u[50], dir_d[50], dir_ne[50]; char dir_nw[50], dir_se[50], dir_sw[50]; bool found = false; if( !ch || !ch->in_room ) { bug( "%s: NULL ch or NULL ch->in_room", __FUNCTION__ ); return; } if( is_npc( ch ) || !xIS_SET( ch->act, PLR_COMPASS ) || !ch->in_room->first_exit ) return; dir_nw[0] = dir_n[0] = dir_ne[0] = '\0'; dir_e[0] = dir_u[0] = dir_d[0] = dir_e[0] = '\0'; dir_sw[0] = dir_s[0] = dir_se[0] = '\0'; strcpy( dir_nw, "----" ); strcpy( dir_n, "---" ); strcpy( dir_ne, "----" ); strcpy( dir_w, "---" ); strcpy( dir_u, "---" ); strcpy( dir_d, "---" ); strcpy( dir_e, "---" ); strcpy( dir_sw, "----" ); strcpy( dir_s, "---" ); strcpy( dir_se, "----" ); for( pexit = ch->in_room->first_exit; pexit; pexit = pexit->next ) { if( !pexit->to_room ) continue; /* Don't show closed and hidden doors */ if( xIS_SET( pexit->exit_info, EX_CLOSED ) && xIS_SET( pexit->exit_info, EX_HIDDEN ) ) continue; /* Don't show secret doors */ if( xIS_SET( pexit->exit_info, EX_SECRET ) ) continue; found = true; /* Default */ snprintf( first, sizeof( first ), "%s", "-" ); snprintf( last, sizeof( last ), "%s", "-" ); if( xIS_SET( pexit->exit_info, EX_CLOSED ) ) { snprintf( first, sizeof( first ), "%s", "(" ); snprintf( last, sizeof( last ), "%s", ")" ); } if( xIS_SET( pexit->exit_info, EX_WINDOW ) ) { snprintf( first, sizeof( first ), "%s", "[" ); snprintf( last, sizeof( last ), "%s", "]" ); } if( pexit->vdir == DIR_NORTHWEST ) sprintf( dir_nw, "%sNW%s", first, last ); if( pexit->vdir == DIR_NORTH ) sprintf( dir_n, "%sN%s", first, last ); if( pexit->vdir == DIR_NORTHEAST ) sprintf( dir_ne, "%sNE%s", first, last ); if( pexit->vdir == DIR_EAST ) sprintf( dir_e, "%sE%s", first, last ); if( pexit->vdir == DIR_UP ) sprintf( dir_u, "%sU%s", first, last ); if( pexit->vdir == DIR_DOWN ) sprintf( dir_d, "%sD%s", first, last ); if( pexit->vdir == DIR_WEST ) sprintf( dir_w, "%sW%s", first, last ); if( pexit->vdir == DIR_SOUTHWEST ) sprintf( dir_sw, "%sSW%s", first, last ); if( pexit->vdir == DIR_SOUTH ) sprintf( dir_s, "%sS%s", first, last ); if( pexit->vdir == DIR_SOUTHEAST ) sprintf( dir_se, "%sSE%s", first, last ); } if( !found ) return; ch_printf( ch, "&W%s&w------&W%s&w------&W%s\r\n", dir_nw, dir_n, dir_ne ); ch_printf( ch, "&W%s&w---&W%s&w<-&G*&w->&W%s&w---&W%s\r\n", dir_w, dir_u, dir_d, dir_e ); ch_printf( ch, "&W%s&w------&W%s&w------&W%s\r\n", dir_sw, dir_s, dir_se ); } void do_look( CHAR_DATA *ch, char *argument ) { char arg[MIL], arg1[MIL], arg2[MIL], arg3[MIL]; EXIT_DATA *pexit; CHAR_DATA *victim = NULL; OBJ_DATA *obj; ROOM_INDEX_DATA *original; char *pdesc; short door; int number, cnt; bool darkroom = false; if( !ch->desc ) return; if( ch->position < POS_SLEEPING ) { send_to_char( "You can't see anything but stars!\r\n", ch ); return; } if( ch->position == POS_SLEEPING ) { send_to_char( "You can't see anything, you're sleeping!\r\n", ch ); return; } if( !check_blind( ch ) ) return; if( !ch->in_room ) { send_to_char( "Your in a NULL room?\r\n", ch ); bug( "%s: %s is in a NULL room!", __FUNCTION__, ch->name ); return; } if( !is_npc( ch ) && !xIS_SET( ch->act, PLR_HOLYLIGHT ) && !IS_AFFECTED( ch, AFF_TRUESIGHT ) && room_is_dark( ch->in_room ) ) darkroom = true; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); argument = one_argument( argument, arg3 ); if( arg1[0] == '\0' || !str_cmp( arg1, "auto" ) ) { if( !darkroom ) { set_char_color( AT_RMNAME, ch ); send_to_char( ch->in_room->name, ch ); send_to_char( "\r\n", ch ); set_char_color( AT_RMDESC, ch ); if( arg1[0] == '\0' || ( !is_npc( ch ) && !xIS_SET( ch->act, PLR_BRIEF ) ) ) send_to_char( ch->in_room->description, ch ); show_compass( ch ); if( !is_npc( ch ) && xIS_SET( ch->act, PLR_AUTOEXIT ) ) do_exits( ch, "auto" ); if( !is_npc( ch ) && is_immortal( ch ) && !xIS_EMPTY( ch->in_room->room_flags ) ) ch_printf( ch, "&cRoom flags: &w%s\r\n", ext_flag_string( &ch->in_room->room_flags, r_flags ) ); } else { set_char_color( AT_DGREY, ch ); send_to_char( "It is pitch black...\r\n", ch ); } 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; if( arg2[0] == '\0' ) { send_to_char( "Look beneath what?\r\n", ch ); return; } if( !( obj = get_obj_here( ch, arg2 ) ) ) { send_to_char( "You do not see that here.\r\n", ch ); return; } if( can_wear( obj, ITEM_NO_TAKE ) && get_trust( ch ) < sysdata.perm_getobjnotake ) { send_to_char( "You can't seem to get a grip on it.\r\n", ch ); return; } if( ch->carry_weight + obj->weight > can_carry_w( ch ) ) { send_to_char( "It's too heavy for you to look under.\r\n", 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.\r\n", ch ); if( EXA_prog_trigger ) oprog_examine_trigger( ch, obj ); return; } if( !str_cmp( arg1, "i" ) || !str_cmp( arg1, "in" ) ) { int count; if( arg2[0] == '\0' ) { send_to_char( "Look in what?\r\n", ch ); return; } if( !( obj = get_obj_here( ch, arg2 ) ) ) { send_to_char( "You do not see that here.\r\n", ch ); return; } switch( obj->item_type ) { default: send_to_char( "That is not a container.\r\n", ch ); break; case ITEM_DRINK_CON: if( obj->value[1] <= 0 ) { send_to_char( "It is empty.\r\n", ch ); if( EXA_prog_trigger ) oprog_examine_trigger( ch, obj ); break; } ch_printf( ch, "It's %s of a %s liquid.\r\n", ( obj->value[1] < ( obj->value[0] / 4 ) && obj->value[1] < 5 ) ? "almost out" : obj->value[1] < ( obj->value[0] / 2 ) ? "less then half full" : obj->value[1] < obj->value[0] ? "less then full" : "full", ( obj->value[2] >= 0 && obj->value[2] < LIQ_MAX ) ? liq_table[obj->value[2]].liq_color : "?Unknown?" ); 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 && xIS_SET( pexit->exit_info, EX_PORTAL ) ) { if( room_is_private( pexit->to_room ) && get_trust( ch ) < sysdata.perm_override_private ) { set_char_color( AT_WHITE, ch ); send_to_char( "That room is private buster!\r\n", 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...\r\n", 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.\r\n", 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 ) ) ) { send_to_char( pdesc, ch ); return; } door = get_door( arg1 ); if( ( pexit = find_door( ch, arg1, true ) ) ) { if( xIS_SET( pexit->exit_info, EX_CLOSED ) && !xIS_SET( pexit->exit_info, EX_WINDOW ) ) { if( ( xIS_SET( pexit->exit_info, EX_SECRET ) || xIS_SET( pexit->exit_info, EX_DIG ) ) && door != -1 ) send_to_char( "Nothing special there.\r\n", ch ); else act( AT_PLAIN, "The $d is closed.", ch, NULL, pexit->keyword, TO_CHAR ); return; } if( xIS_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.\r\n", ch ); /* Ability to look into the next room - Thoric */ if( pexit->to_room && ( IS_AFFECTED( ch, AFF_SCRYING ) || xIS_SET( pexit->exit_info, EX_xLOOK ) || get_trust( ch ) >= PERM_IMM ) ) { if( !xIS_SET( pexit->exit_info, EX_xLOOK ) && get_trust( ch ) < PERM_IMM ) { set_char_color( AT_MAGIC, ch ); send_to_char( "You attempt to scry...\r\n", 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 ) percent = 55; if( number_percent( ) > percent ) { send_to_char( "You fail.\r\n", ch ); return; } } } if( room_is_private( pexit->to_room ) && get_trust( ch ) < sysdata.perm_override_private ) { set_char_color( AT_WHITE, ch ); send_to_char( "That room is private buster!\r\n", 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; } else if( door != -1 ) { send_to_char( "Nothing special there.\r\n", ch ); return; } if( ( victim = get_char_room( ch, arg1 ) ) ) { 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 ) ) ) { if( ( cnt += obj->count ) < number ) continue; send_to_char( pdesc, ch ); if( EXA_prog_trigger ) oprog_examine_trigger( ch, obj ); return; } if( ( pdesc = get_extra_descr( arg, obj->pIndexData->first_extradesc ) ) ) { if( ( cnt += obj->count ) < number ) continue; send_to_char( 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( 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 ) ) ) { if( ( cnt += obj->count ) < number ) continue; send_to_char( pdesc, ch ); if( EXA_prog_trigger ) oprog_examine_trigger( ch, obj ); return; } if( ( pdesc = get_extra_descr( arg, obj->pIndexData->first_extradesc ) ) ) { if( ( cnt += obj->count ) < number ) continue; send_to_char( 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( pdesc, ch ); if( EXA_prog_trigger ) oprog_examine_trigger( ch, obj ); return; } } } send_to_char( "You do not see that here.\r\n", ch ); } void show_race_line( CHAR_DATA *ch, CHAR_DATA *victim ) { int feet, inches; if( !is_npc( victim ) && ( victim != ch ) ) { feet = victim->height / 12; inches = victim->height % 12; ch_printf( ch, "%s is %d'%d\" and weighs %d pounds.\r\n", PERS( victim, ch ), feet, inches, victim->weight ); return; } if( !is_npc( victim ) && ( victim == ch ) ) { feet = victim->height / 12; inches = victim->height % 12; ch_printf( ch, "You are %d'%d\" and weigh %d pounds.\r\n", feet, inches, victim->weight ); return; } } void show_condition( CHAR_DATA *ch, CHAR_DATA *victim ) { char buf[MSL]; int percent; if( victim->max_hit > 0 ) percent = ( 100 * victim->hit ) / victim->max_hit; else percent = -1; if( victim != ch ) { mudstrlcpy( buf, PERS( victim, ch ), sizeof( buf ) ); if( percent >= 100 ) mudstrlcat( buf, " is in perfect health.\r\n", sizeof( buf ) ); else if( percent >= 90 ) mudstrlcat( buf, " is slightly scratched.\r\n", sizeof( buf ) ); else if( percent >= 80 ) mudstrlcat( buf, " has a few bruises.\r\n", sizeof( buf ) ); else if( percent >= 70 ) mudstrlcat( buf, " has some cuts.\r\n", sizeof( buf ) ); else if( percent >= 60 ) mudstrlcat( buf, " has several wounds.\r\n", sizeof( buf ) ); else if( percent >= 50 ) mudstrlcat( buf, " has many nasty wounds.\r\n", sizeof( buf ) ); else if( percent >= 40 ) mudstrlcat( buf, " is bleeding freely.\r\n", sizeof( buf ) ); else if( percent >= 30 ) mudstrlcat( buf, " is covered in blood.\r\n", sizeof( buf ) ); else if( percent >= 20 ) mudstrlcat( buf, " is leaking guts.\r\n", sizeof( buf ) ); else if( percent >= 10 ) mudstrlcat( buf, " is almost dead.\r\n", sizeof( buf ) ); else mudstrlcat( buf, " is DYING.\r\n", sizeof( buf ) ); } else { mudstrlcpy( buf, "You", sizeof( buf ) ); if( percent >= 100 ) mudstrlcat( buf, " are in perfect health.\r\n", sizeof( buf ) ); else if( percent >= 90 ) mudstrlcat( buf, " are slightly scratched.\r\n", sizeof( buf ) ); else if( percent >= 80 ) mudstrlcat( buf, " have a few bruises.\r\n", sizeof( buf ) ); else if( percent >= 70 ) mudstrlcat( buf, " have some cuts.\r\n", sizeof( buf ) ); else if( percent >= 60 ) mudstrlcat( buf, " have several wounds.\r\n", sizeof( buf ) ); else if( percent >= 50 ) mudstrlcat( buf, " have many nasty wounds.\r\n", sizeof( buf ) ); else if( percent >= 40 ) mudstrlcat( buf, " are bleeding freely.\r\n", sizeof( buf ) ); else if( percent >= 30 ) mudstrlcat( buf, " are covered in blood.\r\n", sizeof( buf ) ); else if( percent >= 20 ) mudstrlcat( buf, " are leaking guts.\r\n", sizeof( buf ) ); else if( percent >= 10 ) mudstrlcat( buf, " are almost dead.\r\n", sizeof( buf ) ); else mudstrlcat( buf, " are DYING.\r\n", sizeof( buf ) ); } buf[0] = UPPER( buf[0] ); send_to_char( buf, ch ); return; } CMDF( do_glance ) { char arg1[MIL]; CHAR_DATA *victim; bool brief; if( !ch->desc ) return; if( ch->position < POS_SLEEPING ) { send_to_char( "You can't see anything but stars!\r\n", ch ); return; } if( ch->position == POS_SLEEPING ) { send_to_char( "You can't see anything, you're sleeping!\r\n", 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 ) ) ) { send_to_char( "They're not here.\r\n", 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 ); } 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 level %d", victim->level ); if( !is_npc( victim ) ) ch_printf( ch, " and a %s %s", dis_race_name( victim->race ), dis_class_name( victim->Class ) ); send_to_char( ".\r\n", ch ); } show_condition( ch, victim ); return; } return; } void do_examine( CHAR_DATA *ch, char *argument ) { char buf[MSL], arg[MIL]; OBJ_DATA *obj; short dam; if( !ch ) { bug( "%s: null ch.", __FUNCTION__ ); return; } one_argument( argument, arg ); if( !arg || arg[0] == '\0' ) { send_to_char( "Examine what?\r\n", ch ); return; } EXA_prog_trigger = false; do_look( ch, arg ); EXA_prog_trigger = true; /* * Support for checking equipment conditions and support for trigger positions by Thoric */ if( ( obj = get_obj_here( ch, arg ) ) ) { 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 = ( short )( ( obj->value[0] * 10 ) / obj->value[1] ); send_to_char( "As you look more closely, you notice that it is ", ch ); if( dam >= 10 ) send_to_char( "in superb condition.", ch ); else if( dam == 9 ) send_to_char( "in very good condition.", ch ); else if( dam == 8 ) send_to_char( "in good shape.", ch ); else if( dam == 7 ) send_to_char( "showing a bit of wear.", ch ); else if( dam == 6 ) send_to_char( "a little run down.", ch ); else if( dam == 5 ) send_to_char( "in need of repair.", ch ); else if( dam == 4 ) send_to_char( "in great need of repair.", ch ); else if( dam == 3 ) send_to_char( "in dire need of repair.", ch ); else if( dam == 2 ) send_to_char( "very badly worn.", ch ); else if( dam == 1 ) send_to_char( "practically worthless.", ch ); else if( dam <= 0 ) send_to_char( "broken.", ch ); send_to_char( "\r\n", ch ); break; case ITEM_WEAPON: dam = INIT_WEAPON_CONDITION - obj->value[0]; send_to_char( "As you look more closely, you notice that it is ", ch ); if( dam == 0 ) send_to_char( "in superb condition.", ch ); else if( dam == 1 ) send_to_char( "in excellent condition.", ch ); else if( dam == 2 ) send_to_char( "in very good condition.", ch ); else if( dam == 3 ) send_to_char( "in good shape.", ch ); else if( dam == 4 ) send_to_char( "showing a bit of wear.", ch ); else if( dam == 5 ) send_to_char( "a little run down.", ch ); else if( dam == 6 ) send_to_char( "in need of repair.", ch ); else if( dam == 7 ) send_to_char( "in great need of repair.", ch ); else if( dam == 8 ) send_to_char( "in dire need of repair.", ch ); else if( dam == 9 ) send_to_char( "very badly worn.", ch ); else if( dam == 10 ) send_to_char( "practically worthless.", ch ); else if( dam == 11 ) send_to_char( "almost broken.", ch ); else if( dam == 12 ) send_to_char( "broken.", ch ); send_to_char( "\r\n", ch ); break; case ITEM_COOK: send_to_char( "As you examine it carefully you notice that it ", ch ); dam = obj->value[2]; if( dam >= 3 ) send_to_char( "is burned to a crisp.", ch ); else if( dam == 2 ) send_to_char( "is a little over cooked.", ch ); else if( dam == 1 ) send_to_char( "is perfectly roasted.", ch ); else send_to_char( "is raw.", ch ); send_to_char( "\r\n", ch ); break; case ITEM_FOOD: send_to_char( "As you examine it carefully you notice that it ", ch ); if( obj->timer > 0 && obj->value[1] > 0 ) dam = ( obj->timer * 10 ) / obj->value[1]; else dam = 10; if( dam >= 10 ) send_to_char( "is fresh.", ch ); else if( dam == 9 ) send_to_char( "is nearly fresh.", ch ); else if( dam == 8 ) send_to_char( "is perfectly fine.", ch ); else if( dam == 7 ) send_to_char( "looks good.", ch ); else if( dam == 6 ) send_to_char( "looks ok.", ch ); else if( dam == 5 ) send_to_char( "is a little stale.", ch ); else if( dam == 4 ) send_to_char( "is a bit stale.", ch ); else if( dam == 3 ) send_to_char( "smells slightly off.", ch ); else if( dam == 2 ) send_to_char( "smells quite rank.", ch ); else if( dam == 1 ) send_to_char( "smells revolting!", ch ); else if( dam <= 0 ) send_to_char( "is crawling with maggots!", ch ); send_to_char( "\r\n", 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.\r\n", ch ); else send_to_char( "You notice that it is in the down position.\r\n", ch ); break; case ITEM_BUTTON: if( IS_SET( obj->value[0], TRIG_UP ) ) send_to_char( "You notice that it is depressed.\r\n", ch ); else send_to_char( "You notice that it isn't depressed.\r\n", ch ); break; case ITEM_CORPSE_PC: case ITEM_CORPSE_NPC: { short 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.\r\n", ch ); break; case 4: send_to_char( "This corpse was slain a little while ago.\r\n", ch ); break; case 3: send_to_char( "A foul smell rises from the corpse, and it is covered in flies.\r\n", ch ); break; case 2: send_to_char( "A writhing mass of maggots and decay, you can barely go near this corpse.\r\n", ch ); break; case 1: case 0: send_to_char( "Little more than bones, there isn't much left of this corpse.\r\n", 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:\r\n", ch ); case ITEM_KEYRING: EXA_prog_trigger = false; snprintf( buf, sizeof( buf ), "in %s", arg ); do_look( ch, buf ); EXA_prog_trigger = true; break; } if( is_obj_stat( obj, ITEM_COVERING ) ) { EXA_prog_trigger = false; snprintf( buf, sizeof( buf ), "under %s", arg ); do_look( ch, buf ); EXA_prog_trigger = true; } oprog_examine_trigger( ch, obj ); if( char_died( ch ) ) return; check_for_trap( ch, obj, TRAP_EXAMINE ); } } void do_exits( CHAR_DATA *ch, char *argument ) { EXIT_DATA *pexit; bool found, fAuto, door, window; set_char_color( AT_EXITS, ch ); if( !check_blind( ch ) ) return; if( !ch->in_room ) { send_to_char( "Your in a NULL room?\r\n", ch ); bug( "%s: %s is in a NULL room!", __FUNCTION__, ch->name ); 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 ... \r\n", ch ); return; } fAuto = !str_cmp( argument, "auto" ); send_to_char( fAuto ? "Exits:" : "Obvious exits:\r\n", ch ); found = false; for( pexit = ch->in_room->first_exit; pexit; pexit = pexit->next ) { if( !pexit->to_room ) continue; if( xIS_SET( pexit->exit_info, EX_HIDDEN ) ) continue; door = window = false; if( xIS_SET( pexit->exit_info, EX_ISDOOR ) && xIS_SET( pexit->exit_info, EX_CLOSED ) ) door = true; if( xIS_SET( pexit->exit_info, EX_WINDOW ) ) window = true; found = true; ch_printf( ch, "%s%s%s%s", fAuto ? " " : "", door ? "(" : window ? "[" : "", capitalize( dir_name[pexit->vdir] ), door ? ")" : window ? "]" : "" ); if( !fAuto ) ch_printf( ch, " - %s\r\n", room_is_dark( pexit->to_room ) ? "Too dark to tell" : pexit->to_room->name ); } if( !found ) ch_printf( ch, "%sNone.\r\n", fAuto ? " " : "" ); else if( fAuto ) send_to_char( ".\r\n", ch ); return; } char *show_weather( AREA_DATA *area ) { char *combo, *single; static char buf[MSL]; int temp, precip, wind; temp = ( area->weather->temp + ( 3 * weath_unit ) - 1 ) / weath_unit; precip = ( area->weather->precip + ( 3 * weath_unit ) - 1 ) / weath_unit; wind = ( area->weather->wind + ( 3 * weath_unit ) - 1 ) / weath_unit; if( temp < 0 || temp > 6 ) { bug( "%s: temp is %d when it should be 0 - 6.", __FUNCTION__, temp ); return "(Bad Temp)"; } if( precip < 0 || precip > 6 ) { bug( "%s: precip is %d when it should be 0 - 6.", __FUNCTION__, precip ); return "(Bad Precip)"; } if( wind < 0 || wind > 6 ) { bug( "%s: wind is %d when it should be 0 - 6.", __FUNCTION__, wind ); return "(Bad Wind)"; } if( precip >= 3 ) { combo = preciptemp_msg[precip][temp]; single = wind_msg[wind]; } else { combo = windtemp_msg[wind][temp]; single = precip_msg[precip]; } snprintf( buf, sizeof( buf ), "%s and %s.", combo, single ); return buf; } CMDF( do_weather ) { if( !is_outside( ch ) ) { send_to_char( "You can't see the sky from here.\r\n", ch ); return; } set_char_color( AT_BLUE, ch ); ch_printf( ch, "%s\r\n", show_weather( ch->in_room->area ) ); } /* * 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; typedef struct who_data WHO_DATA; struct who_data { WHO_DATA *prev, *next; char *text; int type; }; #define WT_MORTAL 0 #define WT_DEADLY 1 #define WT_IMM 2 #define WT_GROUPED 3 #define WT_GROUPWHO 4 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->character; if( can_see( looker, wch ) && !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 ) ) { 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->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->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; } } CMDF( do_who ) { CLAN_DATA *pClan = NULL; COUNCIL_DATA *pCouncil = NULL; DEITY_DATA *pDeity = NULL; DESCRIPTOR_DATA *d; WHO_DATA *cur_who = NULL, *next_who = NULL, *first_mortal = NULL, *first_imm = NULL; WHO_DATA *first_deadly = NULL, *first_grouped = NULL, *first_groupwho = NULL; char buf[MSL], clan_name[MIL], nation_name[MIL], council_name[MIL], invis_str[MIL], char_name[MIL]; char class_text[MIL], *w1, *w2; struct whogr_s *whogr, *whogr_p; int iClass, iRace, iLevelLower = 0, iLevelUpper = MAX_LEVEL, nNumber, nMatch; bool rgfClass[MAX_CLASS], rgfRace[MAX_RACE], fClassRestrict = false, fRaceRestrict = false; bool fImmortalOnly = false, fLeader = false, fPkill = false, fGroup = false; bool fShowHomepage = false, fClanMatch = false, fCouncilMatch = false, fDeityMatch = false; if( !ch ) return; w1 = color_str( AT_WHO, ch ); w2 = color_str( AT_WHO2, ch ); /* Set default arguments. */ for( iClass = 0; iClass < MAX_CLASS; iClass++ ) rgfClass[iClass] = false; for( iRace = 0; iRace < MAX_RACE; iRace++ ) rgfRace[iRace] = false; /* Parse arguments. */ nNumber = 0; while( argument && argument[0] != '\0' ) { char arg[MSL]; 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.\r\n", ch ); return; } } else { if( strlen( arg ) < 3 ) { send_to_char( "Arguments must be longer than that.\r\n", 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 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( class_table[iClass] && !str_cmp( arg, class_table[iClass]->name ) ) { rgfClass[iClass] = true; break; } } if( iClass != MAX_CLASS ) fClassRestrict = true; for( iRace = 0; iRace < MAX_RACE; iRace++ ) { if( race_table[iRace] && !str_cmp( arg, race_table[iRace]->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, clan, nation, council or deity.\r\n", ch ); return; } } } } /* Now find matching chars. */ nMatch = 0; buf[0] = '\0'; set_pager_color( AT_WHO, ch ); /* 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 ) ) continue; wch = d->character; if( wch->level < iLevelLower || wch->level > iLevelUpper || ( fPkill && !can_pkill( wch ) ) || ( fImmortalOnly && get_trust( wch ) < PERM_IMM ) || ( fClassRestrict && !rgfClass[wch->Class] ) || ( fRaceRestrict && !rgfRace[wch->race] ) || ( fClanMatch && ( pClan != wch->pcdata->clan ) ) || ( fCouncilMatch && ( pCouncil != wch->pcdata->council ) ) || ( fDeityMatch && ( pDeity != wch->pcdata->deity ) ) ) continue; if( fLeader && ( !wch->pcdata->council || ( str_cmp( wch->pcdata->council->head2, wch->name ) && str_cmp( wch->pcdata->council->head, wch->name ) ) ) && ( !wch->pcdata->clan || ( str_cmp( wch->pcdata->clan->leader, wch->name ) && str_cmp( wch->pcdata->clan->number1, wch->name ) && str_cmp( wch->pcdata->clan->number2, wch->name ) ) ) ) continue; if( fGroup && !wch->leader && !xIS_SET( wch->pcdata->flags, PCFLAG_GROUPWHO ) && ( !whogr_p || !whogr_p->indent ) ) continue; nMatch++; mudstrlcpy( char_name, wch->name, sizeof( char_name ) ); /* Base Info For Class Info */ if( class_table[wch->Class] && class_table[wch->Class]->name ) snprintf( class_text, sizeof( class_text ), "%s%2d %s", not_authed( wch ) ? "N" : " ", wch->level, class_table[wch->Class]->name ); else snprintf( class_text, sizeof( class_text ), "%s%2d", not_authed( wch ) ? "N" : " ", wch->level ); Class = class_text; /* Some extra things that override base info */ if( wch->level == MAX_LEVEL ) Class = "Avatar"; if( get_trust( wch ) == PERM_IMP ) Class = "Implementor"; else if( get_trust( wch ) == PERM_HEAD ) Class = "Head"; else if( get_trust( wch ) == PERM_LEADER ) Class = "Leader"; else if( get_trust( wch ) == PERM_BUILDER ) Class = "Builder"; else if( get_trust( wch ) == PERM_IMM ) Class = "Immortal"; /* These override all the base and extra for class info */ 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 ) Class = wch->pcdata->clan->leadrank; else if( wch->pcdata->clan && !str_cmp( wch->name, wch->pcdata->clan->number1 ) && wch->pcdata->clan->onerank ) Class = wch->pcdata->clan->onerank; else if( wch->pcdata->clan && !str_cmp( wch->name, wch->pcdata->clan->number2 ) && wch->pcdata->clan->tworank ) Class = wch->pcdata->clan->tworank; else if( wch->pcdata->rank ) Class = wch->pcdata->rank; if( wch->pcdata->clan ) { CLAN_DATA *pclan = wch->pcdata->clan; mudstrlcpy( clan_name, w1, sizeof( clan_name ) ); mudstrlcat( clan_name, " <", sizeof( clan_name ) ); mudstrlcat( clan_name, w2, sizeof( clan_name ) ); if( !str_cmp( wch->name, pclan->leader ) ) mudstrlcat( clan_name, "Leader of ", sizeof( clan_name ) ); else if( !str_cmp( wch->name, pclan->number1 ) ) mudstrlcat( clan_name, "Number One ", sizeof( clan_name ) ); else if( !str_cmp( wch->name, pclan->number2 ) ) mudstrlcat( clan_name, "Number Two ", sizeof( clan_name ) ); mudstrlcat( clan_name, pclan->name, sizeof( clan_name ) ); mudstrlcat( clan_name, w1, sizeof( clan_name ) ); mudstrlcat( clan_name, ">", sizeof( clan_name ) ); } else clan_name[0] = '\0'; if( wch->pcdata->nation ) { CLAN_DATA *nation = wch->pcdata->nation; mudstrlcpy( nation_name, w1, sizeof( nation_name ) ); mudstrlcat( nation_name, " [", sizeof( nation_name ) ); mudstrlcat( nation_name, w2, sizeof( nation_name ) ); mudstrlcat( nation_name, nation->name, sizeof( nation_name ) ); mudstrlcat( nation_name, w1, sizeof( nation_name ) ); mudstrlcat( nation_name, "]", sizeof( nation_name ) ); } else nation_name[0] = '\0'; if( wch->pcdata->council && wch->pcdata->council->name ) { mudstrlcpy( council_name, w1, sizeof( council_name ) ); mudstrlcat( council_name, " [", sizeof( council_name ) ); mudstrlcat( council_name, w2, sizeof( council_name ) ); if( !wch->pcdata->council->head2 ) { if( !str_cmp( wch->name, wch->pcdata->council->head ) ) mudstrlcat( council_name, "Head of ", sizeof( council_name ) ); } else { if( !str_cmp( wch->name, wch->pcdata->council->head ) || !str_cmp( wch->name, wch->pcdata->council->head2 ) ) mudstrlcat( council_name, "Co-Head of ", sizeof( council_name ) ); } mudstrlcat( council_name, wch->pcdata->council->name, sizeof( council_name ) ); mudstrlcat( council_name, w1, sizeof( council_name ) ); mudstrlcat( council_name, "]", sizeof( council_name ) ); } else council_name[0] = '\0'; if( xIS_SET( wch->act, PLR_WIZINVIS ) ) snprintf( invis_str, sizeof( invis_str ), "(%d) ", wch->pcdata->wizinvis ); else invis_str[0] = '\0'; snprintf( buf, sizeof( buf ), "%*s%-15s %s%s%s%s%s%s.&D%s%s%s\r\n", ( fGroup ? whogr->indent : 0 ), "", Class, invis_str, ( wch->desc && wch->desc->connected ) ? "[WRITING] " : "", xIS_SET( wch->act, PLR_AFK ) ? "[AFK] " : "", wch->sex == SEX_FEMALE ? color_str( AT_FEMALE, ch ) : wch->sex == SEX_MALE ? color_str( AT_MALE, ch ) : "", char_name, wch->pcdata->title, clan_name, nation_name, council_name ); /* * 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 = STRALLOC( buf ); if( 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 */ if( first_mortal ) pager_printf( ch, "\r\n%s~`~.~`~.~`~.~`~.~`~.~`~.~`~[ %sPEACEFUL CHARACTERS %s]~`~.~`~.~`~.~`~.~`~.~`~.~`~\r\n\r\n", w1, w2, w1 ); for( cur_who = first_mortal; cur_who; cur_who = next_who ) { send_to_pager( cur_who->text, ch ); next_who = cur_who->next; STRFREE( cur_who->text ); DISPOSE( cur_who ); } if( first_deadly ) pager_printf( ch, "\r\n%s~`~.~`~.~`~.~`~.~`~.~`~.~`~[ %sDEADLY CHARACTERS %s]~`~.~`~.~`~.~`~.~`~.~`~.~`~\r\n\r\n", w1, w2, w1 ); for( cur_who = first_deadly; cur_who; cur_who = next_who ) { send_to_pager( cur_who->text, ch ); next_who = cur_who->next; STRFREE( cur_who->text ); DISPOSE( cur_who ); } if( first_grouped ) pager_printf( ch, "\r\n%s~`~.~`~.~`~.~`~.~`~.~`~.~`~[ %sGROUPED CHARACTERS %s]~`~.~`~.~`~.~`~.~`~.~`~.~`~\r\n\r\n", w1, w2, w1 ); for( cur_who = first_grouped; cur_who; cur_who = next_who ) { send_to_pager( cur_who->text, ch ); next_who = cur_who->next; STRFREE( cur_who->text ); DISPOSE( cur_who ); } if( first_groupwho ) pager_printf( ch, "\r\n%s~`~.~`~.~`~.~`~.~`~.~`~.~`~[ %sWANTING GROUP %s]~`~.~`~.~`~.~`~.~`~.~`~.~`~\r\n\r\n", w1, w2, w1 ); for( cur_who = first_groupwho; cur_who; cur_who = next_who ) { send_to_pager( cur_who->text, ch ); next_who = cur_who->next; STRFREE( cur_who->text ); DISPOSE( cur_who ); } if( first_imm ) pager_printf( ch, "\r\n%s~`~.~`~.~`~.~`~.~`~.~`~.~`~[ %sIMMORTALS %s]~`~.~`~.~`~.~`~.~`~.~`~.~`~\r\n\r\n", w1, w2, w1 ); for( cur_who = first_imm; cur_who; cur_who = next_who ) { send_to_pager( cur_who->text, ch ); next_who = cur_who->next; STRFREE( cur_who->text ); DISPOSE( cur_who ); } pager_printf( ch, "%s%d %splayer%s.\r\n", w2, nMatch, w1, nMatch == 1 ? "" : "s" ); } #undef WT_MORTAL #undef WT_DEADLY #undef WT_IMM #undef WT_GROUPED #undef WT_GROUPWHO CMDF( do_compare ) { char arg1[MIL], arg2[MIL], *msg; OBJ_DATA *obj1, *obj2; int value1, value2; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if( !arg1 || arg1[0] == '\0' ) { send_to_char( "Compare what to what?\r\n", ch ); return; } if( !( obj1 = get_obj_carry( ch, arg1 ) ) ) { send_to_char( "You do not have that item.\r\n", ch ); return; } if( !arg2 || 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 && xSAME_BITS( obj1->wear_flags, obj2->wear_flags ) ) break; } if( !obj2 ) { send_to_char( "You aren't wearing anything comparable.\r\n", ch ); return; } } else { if( !( obj2 = get_obj_carry( ch, arg2 ) ) ) { send_to_char( "You do not have that item.\r\n", 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 ); } CMDF( do_where ) { CHAR_DATA *victim; DESCRIPTOR_DATA *d; bool found = false; set_pager_color( AT_PERSON, ch ); if( !argument || argument[0] == '\0' ) { pager_printf( ch, "\r\nPlayers near you in %s:\r\n", ch->in_room->area->name ); for( d = first_descriptor; d; d = d->next ) { if( !d->character ) continue; if( ( victim = d->character ) && !is_npc( victim ) && victim != ch && victim->in_room && victim->in_room->area == ch->in_room->area && can_see( ch, victim ) && ( get_trust( ch ) >= get_trust( victim ) || !xIS_SET( victim->pcdata->flags, PCFLAG_DND ) ) ) { found = true; pager_printf( ch, "&P%-13s ", victim->name ); if( is_immortal( victim ) ) send_to_pager( "&P(&WImmortal&P) ", ch ); else if( can_pkill( victim ) && victim->pcdata->clan && victim->pcdata->clan->clan_type == CLAN_PLAIN ) pager_printf( ch, "%-18s ", victim->pcdata->clan->badge ); else if( can_pkill( victim ) ) send_to_pager( "(&wUnclanned&P) ", ch ); else send_to_pager( " ", ch ); pager_printf( ch, "&P%s\r\n", victim->in_room->name ); } } if( !found ) send_to_char( "None\r\n", ch ); } else { for( victim = first_char; victim; victim = victim->next ) { if( victim != ch && victim->in_room && victim->in_room->area == ch->in_room->area && can_see( ch, victim ) && is_name( argument, victim->name ) ) { found = true; pager_printf( ch, "%-28s %s\r\n", PERS( victim, ch ), victim->in_room->name ); break; } } if( !found ) act( AT_PLAIN, "You didn't find any $T.", ch, NULL, argument, TO_CHAR ); } } CMDF( do_consider ) { CHAR_DATA *victim; int diff; char *msg; if( !argument || argument[0] == '\0' ) { send_to_char( "Consider killing whom?\r\n", ch ); return; } if( !( victim = get_char_room( ch, argument ) ) ) { send_to_char( "They're not here.\r\n", ch ); return; } if( victim == ch ) { send_to_char( "You're pretty sure you could take yourself in a fight.\r\n", ch ); return; } diff = ch->level - victim->level; if( diff >= 10 ) msg = "You're alot more experienced than $N."; else if( diff >= 5 ) msg = "You're more experienced than $N."; else if( diff >= 1 ) msg = "You're a little more experienced than $N."; else if( diff == 0 ) msg = "You're as experienced as $N."; else if( diff <= -10 ) msg = "$N is alot more experienced than you."; else if( diff <= -5 ) msg = "$N is more experienced than you."; else if( diff <= -1 ) msg = "$N is a little more experienced than you."; act( AT_CONSIDER, msg, ch, NULL, victim, TO_CHAR ); diff = ( int )get_hitroll( ch ) - get_hitroll( victim ); if( diff >= 10 ) msg = "You're able to hit alot more often than $N."; else if( diff >= 5 ) msg = "You're able to hit more often than $N."; else if( diff >= 1 ) msg = "You're able to hit a little more often than $N."; else if( diff == 0 ) msg = "You're able to hit as often as $N."; else if( diff <= -10 ) msg = "$N is able to hit alot more often than you."; else if( diff <= -5 ) msg = "$N is able to hit more often than you."; else if( diff <= -1 ) msg = "$N is able to hit a little more often than you."; act( AT_CONSIDER, msg, ch, NULL, victim, TO_CHAR ); diff = ( int )get_damroll( ch ) - get_damroll( victim ); if( diff >= 10 ) msg = "You're able to do alot more damage than $N."; else if( diff >= 5 ) msg = "You're able to do more damage than $N."; else if( diff >= 1 ) msg = "You're able to do a little more damage than $N."; else if( diff == 0 ) msg = "You're able to do as much damage as $N."; else if( diff <= -10 ) msg = "$N is able to do alot more damage than you."; else if( diff <= -5 ) msg = "$N is able to do more damage than you."; else if( diff <= -1 ) msg = "$N is able to do a little more damage than you."; act( AT_CONSIDER, msg, ch, NULL, victim, TO_CHAR ); diff = ( int )get_ac( ch ) - get_ac( victim ); if( diff >= 500 ) msg = "You're alot better armored than $N."; else if( diff >= 250 ) msg = "You're better armored than $N."; else if( diff >= 1 ) msg = "You're a little better armored than $N."; else if( diff == 0 ) msg = "You're as armored as $N."; else if( diff <= -500 ) msg = "$N is alot better armored than you."; else if( diff <= -250 ) msg = "$N is better armored than you."; else if( diff <= -1 ) msg = "$N is a little better armored than you."; act( AT_CONSIDER, msg, ch, NULL, victim, TO_CHAR ); diff = ( int )( ch->max_hit - victim->max_hit ); if( diff >= 500 ) msg = "You're able to take alot more damage than $N."; else if( diff >= 250 ) msg = "You're able to take more damage than $N."; else if( diff >= 1 ) msg = "You're able to take a little more damage than $N."; else if( diff == 0 ) msg = "You're able to take as much damage as $N."; else if( diff <= -500 ) msg = "$N is able to take alot more damage than you."; else if( diff <= -250 ) msg = "$N is able to take more damage than you."; else if( diff <= -1 ) msg = "$N is able to take a little more damage than you."; act( AT_CONSIDER, msg, ch, NULL, victim, TO_CHAR ); } void do_wimpy( CHAR_DATA *ch, char *argument ) { int wimpy; if( !argument || argument[0] == '\0' ) wimpy = ( int )ch->max_hit / 5; else if( !str_cmp( argument, "max" ) ) wimpy = ( int )( ch->max_hit / 2.25 ); else wimpy = atoi( argument ); set_char_color( AT_YELLOW, ch ); if( wimpy < 0 || wimpy > ( ch->max_hit / 2.25 ) ) { ch_printf( ch, "Wimpy range for you is 0 to %d\r\n", ( int )( ch->max_hit / 2.25 ) ); return; } ch->wimpy = wimpy; ch_printf( ch, "Wimpy set to %d hit points.\r\n", wimpy ); } CMDF( do_password ) { char arg1[MIL], arg2[MIL]; char *pArg, *pwdnew; 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 || arg1[0] == '\0' || !arg2 || arg2[0] == '\0' ) { send_to_char( "Usage: password <new> <again>.\r\n", ch ); return; } /* This should stop all the mistyped password problems --Shaddai */ if( strcmp( arg1, arg2 ) ) { send_to_char( "Passwords don't match try again.\r\n", ch ); return; } if( strlen( arg2 ) < 5 ) { send_to_char( "New password must be at least five characters long.\r\n", ch ); return; } if( arg1[0] == '!' || arg2[0] == '!' ) { send_to_char( "New password can't begin with the '!' character.", ch ); return; } pwdnew = sha256_crypt( arg2 ); /* SHA-256 Encryption */ STRSET( ch->pcdata->pwd, pwdnew ); if( xIS_SET( sysdata.save_flags, SV_PASSCHG ) ) save_char_obj( ch ); if( ch->desc && ch->desc->host[0] != '\0' ) log_printf( "%s changing password from site %s\n", ch->name, ch->desc->host ); else log_printf( "%s changing thier password with no descriptor!", ch->name ); send_to_char( "Ok.\r\n", ch ); } /* display WIZLIST file - Thoric */ CMDF( do_wizlist ) { set_pager_color( AT_IMMORT, ch ); show_file( ch, WIZLIST_FILE ); } CMDF( do_config ) { char arg[MIL]; if( !ch || is_npc( ch ) ) return; one_argument( argument, arg ); set_char_color( AT_GREEN, ch ); if( !arg || arg[0] == '\0' ) { send_to_char( "\r\n&[dgreen]Configurations ", ch ); send_to_char( "&[green](use 'config <keyword>' to toggle, see 'help config')\r\n\r\n", ch ); send_to_char( "&[dgreen]Display: ", ch ); set_char_color( AT_GREY, ch ); ch_printf( ch, "Pager(%c) Gag(%c) Brief(%c) Combine(%c)\r\n", xIS_SET( ch->pcdata->flags, PCFLAG_PAGERON ) ? 'X' : ' ', xIS_SET( ch->pcdata->flags, PCFLAG_GAG ) ? 'X' : ' ', xIS_SET( ch->act, PLR_BRIEF ) ? 'X' : ' ', xIS_SET( ch->act, PLR_COMBINE ) ? 'X' : ' ' ); ch_printf( ch, " Blank(%c) Prompt(%c) Ansi(%c) KeepAlive(%c)\r\n", xIS_SET( ch->act, PLR_BLANK ) ? 'X' : ' ', xIS_SET( ch->act, PLR_PROMPT ) ? 'X' : ' ', xIS_SET( ch->act, PLR_ANSI ) ? 'X' : ' ', xIS_SET( ch->act, PLR_K_LIVE ) ? 'X' : ' ' ); ch_printf( ch, " Hints(%c) Compass(%c) Groupaffects(%c)\r\n", !xIS_SET( ch->act, PLR_NOHINTS ) ? 'X' : ' ', xIS_SET( ch->act, PLR_COMPASS ) ? 'X' : ' ', xIS_SET( ch->act, PLR_GROUPAFFECTS ) ? 'X' : ' ' ); set_char_color( AT_DGREEN, ch ); send_to_char( "\r\nAuto: ", ch ); set_char_color( AT_GREY, ch ); ch_printf( ch, "AutoSac(%c) AutoGold(%c) AutoLoot(%c) AutoExit(%c)\r\n", xIS_SET( ch->act, PLR_AUTOSAC ) ? 'X' : ' ', xIS_SET( ch->act, PLR_AUTOGOLD ) ? 'X' : ' ', xIS_SET( ch->act, PLR_AUTOLOOT ) ? 'X' : ' ', xIS_SET( ch->act, PLR_AUTOEXIT ) ? 'X' : ' ' ); ch_printf( ch, " Suicide(%c) AutoSplit(%c)\r\n", xIS_SET( ch->act, PLR_SUICIDE ) ? 'X' : ' ', xIS_SET( ch->act, PLR_AUTOSPLIT ) ? 'X' : ' ' ); set_char_color( AT_DGREEN, ch ); send_to_char( "\r\nSafeties: ", ch ); set_char_color( AT_GREY, ch ); ch_printf( ch, "NoRecall(%c) NoSummon(%c) Solo(%c) NoAssist(%c)\r\n", xIS_SET( ch->pcdata->flags, PCFLAG_NORECALL ) ? 'X' : ' ', xIS_SET( ch->pcdata->flags, PCFLAG_NOSUMMON ) ? 'X' : ' ', xIS_SET( ch->act, PLR_SOLO ) ? 'X' : ' ', xIS_SET( ch->act, PLR_NOASSIST ) ? 'X' : ' ' ); ch_printf( ch, " SmartSac(%c) NoInduct(%c)", xIS_SET( ch->act, PLR_SMARTSAC ) ? 'X' : ' ', xIS_SET( ch->act, PLR_NOINDUCT ) ? 'X' : ' ' ); if( !xIS_SET( ch->pcdata->flags, PCFLAG_DEADLY ) ) ch_printf( ch, " Drag(%c) Nice(%c)", xIS_SET( ch->act, PLR_SHOVEDRAG ) ? 'X' : ' ', xIS_SET( ch->act, PLR_NICE ) ? 'X' : ' ' ); set_char_color( AT_DGREEN, ch ); send_to_char( "\r\n\r\nMisc: ", ch ); set_char_color( AT_GREY, ch ); ch_printf( ch, "TelnetGA(%c) GroupWho(%c) NoIntro(%c)", xIS_SET( ch->act, PLR_TELNET_GA ) ? 'X' : ' ', xIS_SET( ch->pcdata->flags, PCFLAG_GROUPWHO ) ? 'X' : ' ', xIS_SET( ch->pcdata->flags, PCFLAG_NOINTRO ) ? 'X' : ' ' ); set_char_color( AT_DGREEN, ch ); send_to_char( "\r\n\r\nSettings: ", ch ); set_char_color( AT_GREY, ch ); ch_printf( ch, "KeepAlive Time (%d) Pager Length (%d) Wimpy (&W%d&w)", ch->pcdata->kltime, ch->pcdata->pagerlen, ch->wimpy ); set_char_color( AT_DGREEN, ch ); send_to_char( "\r\n\r\nSentences imposed on you (if any):", ch ); set_char_color( AT_YELLOW, ch ); ch_printf( ch, "\r\n%s%s%s", xIS_SET( ch->act, PLR_SILENCE ) ? " For your abuse of channels, you are currently silenced.\r\n" : "", xIS_SET( ch->act, PLR_NO_EMOTE ) ? " The gods have removed your emotes.\r\n" : "", xIS_SET( ch->act, PLR_NO_TELL ) ? " You aren't permitted to send 'tells' to others.\r\n" : "" ); } else { if( !str_prefix( arg, "ansi" ) ) xTOGGLE_BIT( ch->act, PLR_ANSI ); else if( !str_prefix( arg, "autoexit" ) ) xTOGGLE_BIT( ch->act, PLR_AUTOEXIT ); else if( !str_prefix( arg, "autogold" ) ) xTOGGLE_BIT( ch->act, PLR_AUTOGOLD ); else if( !str_prefix( arg, "autosplit" ) ) xTOGGLE_BIT( ch->act, PLR_AUTOSPLIT ); else if( !str_prefix( arg, "smartsac" ) ) xTOGGLE_BIT( ch->act, PLR_SMARTSAC ); else if( !str_prefix( arg, "autoloot" ) ) xTOGGLE_BIT( ch->act, PLR_AUTOLOOT ); else if( !str_prefix( arg, "autosac" ) ) xTOGGLE_BIT( ch->act, PLR_AUTOSAC ); else if( !str_prefix( arg, "blank" ) ) xTOGGLE_BIT( ch->act, PLR_BLANK ); else if( !str_prefix( arg, "groupaffects" ) ) xTOGGLE_BIT( ch->act, PLR_GROUPAFFECTS ); else if( !str_prefix( arg, "brief" ) ) xTOGGLE_BIT( ch->act, PLR_BRIEF ); else if( !str_prefix( arg, "combine" ) ) xTOGGLE_BIT( ch->act, PLR_COMBINE ); else if( !str_prefix( arg, "compass" ) ) xTOGGLE_BIT( ch->act, PLR_COMPASS ); else if( !str_prefix( arg, "hints" ) ) xTOGGLE_BIT( ch->act, PLR_NOHINTS ); else if( !str_prefix( arg, "noassist" ) ) xTOGGLE_BIT( ch->act, PLR_NOASSIST ); else if( !str_prefix( arg, "prompt" ) ) xTOGGLE_BIT( ch->act, PLR_PROMPT ); else if( !str_prefix( arg, "solo" ) ) xTOGGLE_BIT( ch->act, PLR_SOLO ); else if( !str_prefix( arg, "noinduct" ) ) xTOGGLE_BIT( ch->act, PLR_NOINDUCT ); else if( !str_prefix( arg, "suicide" ) ) xTOGGLE_BIT( ch->act, PLR_SUICIDE ); else if( !str_prefix( arg, "telnetga" ) ) xTOGGLE_BIT( ch->act, PLR_TELNET_GA ); else if( !str_prefix( arg, "keepalive" ) ) xTOGGLE_BIT( ch->act, PLR_K_LIVE ); else if ( !str_prefix( arg, "flee" ) ) { if( xIS_SET( ch->pcdata->flags, PCFLAG_DEADLY ) ) { send_to_char( "Pkill characters can't config that option.\r\n", ch ); return; } else xTOGGLE_BIT( ch->act, PLR_FLEE ); } else if( !str_prefix( arg, "nice" ) ) { if( xIS_SET( ch->pcdata->flags, PCFLAG_DEADLY ) ) { send_to_char( "Pkill characters can't config that option.\r\n", ch ); return; } else xTOGGLE_BIT( ch->act, PLR_NICE ); } else if( !str_prefix( arg, "drag" ) ) { if( xIS_SET( ch->pcdata->flags, PCFLAG_DEADLY ) ) { send_to_char( "Pkill characters can't config that option.\r\n", ch ); return; } else xTOGGLE_BIT( ch->act, PLR_SHOVEDRAG ); } else if( !str_prefix( arg, "norecall" ) ) xTOGGLE_BIT( ch->pcdata->flags, PCFLAG_NORECALL ); else if( !str_prefix( arg, "nointro" ) ) xTOGGLE_BIT( ch->pcdata->flags, PCFLAG_NOINTRO ); else if( !str_prefix( arg, "nosummon" ) ) xTOGGLE_BIT( ch->pcdata->flags, PCFLAG_NOSUMMON ); else if( !str_prefix( arg, "gag" ) ) xTOGGLE_BIT( ch->pcdata->flags, PCFLAG_GAG ); else if( !str_prefix( arg, "pager" ) ) xTOGGLE_BIT( ch->pcdata->flags, PCFLAG_PAGERON ); else if( !str_prefix( arg, "groupwho" ) ) xTOGGLE_BIT( ch->pcdata->flags, PCFLAG_GROUPWHO ); else { send_to_char( "Config which option?\r\n", ch ); return; } /* Send ok message */ send_to_char( "Ok.\r\n", ch ); } return; } extern int top_area; /* New do_areas, written by Fireblade, last modified - 12/23/2007 */ CMDF( do_areas ) { char *header_string1 = "\r\n Author | Area | Recommended | Enforced\r\n"; char *header_string2 = "-------------+--------------------------------------+-------------+-----------\r\n"; char *print_string = "%-12s | %-36s | %4d - %-4d | %3d - %-3d \r\n"; AREA_DATA *pArea; int lower_bound = 0; int upper_bound = MAX_LEVEL + 1; char arg[MSL]; argument = one_argument( argument, arg ); if( arg && arg[0] != '\0' ) { if( is_number( arg ) ) { upper_bound = atoi( arg ); lower_bound = upper_bound; argument = one_argument( argument, arg ); if( arg && arg[0] != '\0' ) { if( is_number( arg ) ) { upper_bound = atoi( arg ); argument = one_argument( argument, arg ); } } } } if( lower_bound > upper_bound ) { int swap = lower_bound; lower_bound = upper_bound; upper_bound = swap; } 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( arg && arg[0] != '\0' && !is_number( arg ) && pArea->name && pArea->name[0] != '\0' && str_prefix( arg, pArea->name ) ) continue; 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 ); } } } CMDF( do_afk ) { if( is_npc( ch ) ) return; xTOGGLE_BIT( ch->act, PLR_AFK ); if( !xIS_SET( ch->act, PLR_AFK ) ) { send_to_char( "You are no longer afk.\r\n", ch ); act( AT_GREY, "$n is no longer afk.", ch, NULL, NULL, TO_CANSEE ); #ifdef IMC if( IMCIS_SET( IMCFLAG( ch ), IMC_AFK ) ) { IMCREMOVE_BIT( IMCFLAG( ch ), IMC_AFK ); send_to_char( "You are no longer AFK to IMC2.\r\n", ch ); } #endif } else { send_to_char( "You are now afk.\r\n", ch ); act( AT_GREY, "$n is now afk.", ch, NULL, NULL, TO_CANSEE ); #ifdef IMC if( !IMCIS_SET( IMCFLAG( ch ), IMC_AFK ) ) { IMCSET_BIT( IMCFLAG( ch ), IMC_AFK ); send_to_char( "You are now AFK to IMC2.\r\n", ch ); } #endif } } CMDF( do_slist ) { char skn[MIL], buf[MIL], arg1[MIL], arg2[MIL]; int sn, i, lFound, lowlev, hilev, max = 0; short lasttype = SKILL_SPELL; if( is_npc( ch ) ) return; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); lowlev = 1; hilev = MAX_LEVEL; if( arg1[0] != '\0' ) lowlev = atoi( arg1 ); if( ( lowlev < 1 ) || ( lowlev > MAX_LEVEL ) ) lowlev = 1; if( arg2[0] != '\0' ) hilev = atoi( arg2 ); if( ( hilev < 0 ) || ( hilev > MAX_LEVEL ) ) hilev = MAX_LEVEL; if( lowlev > hilev ) lowlev = hilev; set_pager_color( AT_MAGIC, ch ); send_to_pager( "SPELL & SKILL LIST\r\n", ch ); send_to_pager( "------------------\r\n", ch ); for( i = lowlev; i <= hilev; i++ ) { lFound = 0; snprintf( skn, sizeof( skn ), "%s", "Spell" ); for( sn = 0; sn < top_sn; sn++ ) { if( !skill_table[sn] || !skill_table[sn]->name ) continue; if( ch->pcdata->learned[sn] <= 0 && SPELL_FLAG( skill_table[sn], SF_SECRETSKILL ) ) continue; if( ( ch->Class == -1 || i != skill_table[sn]->skill_level[ch->Class] ) && ( ch->race == -1 || i != skill_table[sn]->race_level[ch->race] ) ) continue; if( skill_table[sn]->type != lasttype ) { lasttype = skill_table[sn]->type; mudstrlcpy( skn, skill_tname[lasttype], sizeof( skn ) ); } if( !lFound ) { lFound = 1; pager_printf( ch, "Level %d\r\n", i ); } switch( skill_table[sn]->minimum_position ) { default: snprintf( buf, sizeof( buf ), "%s", "Invalid" ); bug( "%s: skill with invalid minpos, skill = %s", __FUNCTION__, skill_table[sn]->name ); break; case POS_DEAD: snprintf( buf, sizeof( buf ), "%s", "any" ); break; case POS_MORTAL: snprintf( buf, sizeof( buf ), "%s", "mortally wounded" ); break; case POS_INCAP: snprintf( buf, sizeof( buf ), "%s", "incapacitated" ); break; case POS_STUNNED: snprintf( buf, sizeof( buf ), "%s", "stunned" ); break; case POS_SLEEPING: snprintf( buf, sizeof( buf ), "%s", "sleeping" ); break; case POS_RESTING: snprintf( buf, sizeof( buf ), "%s", "resting" ); break; case POS_STANDING: snprintf( buf, sizeof( buf ), "%s", "standing" ); break; case POS_FIGHTING: snprintf( buf, sizeof( buf ), "%s", "fighting" ); break; case POS_EVASIVE: snprintf( buf, sizeof( buf ), "%s", "fighting (evasive)" ); /* Fighting style support -haus */ break; case POS_DEFENSIVE: snprintf( buf, sizeof( buf ), "%s", "fighting (defensive)" ); break; case POS_AGGRESSIVE: snprintf( buf, sizeof( buf ), "%s", "fighting (aggressive)" ); break; case POS_BERSERK: snprintf( buf, sizeof( buf ), "%s", "fighting (berserk)" ); break; case POS_MOUNTED: snprintf( buf, sizeof( buf ), "%s", "mounted" ); break; case POS_SITTING: snprintf( buf, sizeof( buf ), "%s", "sitting" ); break; } if( i == skill_table[sn]->race_level[ch->race] ) max = skill_table[sn]->race_adept[ch->race]; if( i == skill_table[sn]->skill_level[ch->Class] && max < skill_table[sn]->skill_adept[ch->Class] ) max = skill_table[sn]->skill_adept[ch->Class]; pager_printf( ch, "%7s: %20.20s Current: %-3d Max: %-3d MinPos: %s\r\n", skn, skill_table[sn]->name, ch->pcdata->learned[sn], max, buf ); } } } CMDF( do_whois ) { CHAR_DATA *victim; char buf[MSL], *s1, *s2; buf[0] = '\0'; if( is_npc( ch ) ) return; s1 = color_str( AT_SCORE, ch ); s2 = color_str( AT_SCORE2, ch ); if( !argument || argument[0] == '\0' ) { send_to_pager( "You must input the name of an online character.\r\n", ch ); return; } mudstrlcat( buf, "0.", sizeof( buf ) ); mudstrlcat( buf, argument, sizeof( buf ) ); if( !( victim = get_char_world( ch, buf ) ) ) { send_to_pager( "No such character online.\r\n", ch ); return; } if( is_npc( victim ) ) { send_to_pager( "That's not a player!\r\n", ch ); return; } set_pager_color( AT_SCORE, ch ); pager_printf( ch, "\r\n%s%s%s.\r\n", victim->sex == SEX_MALE ? color_str( AT_MALE, ch ) : victim->sex == SEX_FEMALE ? color_str( AT_FEMALE, ch ) : "", victim->name, victim->pcdata->title ); pager_printf( ch, "%s%s is a level %s%d %s", s1, victim->sex == SEX_MALE ? "He" : victim->sex == SEX_FEMALE ? "She" : "It", s2, victim->level, capitalize( dis_race_name( victim->race ) ) ); pager_printf( ch, " %s%s, %s%d %syears of age.\r\n", capitalize( dis_class_name( victim->Class ) ), s1, s2, get_age( victim ), s1 ); pager_printf( ch, "%s%s is a %sdeadly player", s1, victim->sex == SEX_MALE ? "He" : victim->sex == SEX_FEMALE ? "She" : "It", xIS_SET( victim->pcdata->flags, PCFLAG_DEADLY ) ? "" : "non-" ); if( victim->pcdata->clan ) pager_printf( ch, ", and belongs to Clan %s%s%s", s2, victim->pcdata->clan->name ? victim->pcdata->clan->name : "(Unknown)", s1 ); send_to_pager( ".\r\n", ch ); if( victim->pcdata->council ) pager_printf( ch, "%s%s holds a seat on: %s%s\r\n", s1, victim->sex == SEX_MALE ? "He" : victim->sex == SEX_FEMALE ? "She" : "It", s2, victim->pcdata->council->name ? victim->pcdata->council->name : "(Unknown)" ); if( victim->pcdata->deity ) pager_printf( ch, "%s%s has found succor in the deity %s%s%s.\r\n", s1, victim->sex == SEX_MALE ? "He" : victim->sex == SEX_FEMALE ? "She" : "It", s2, victim->pcdata->deity->name ? victim->pcdata->deity->name : "(Unknown)", s1 ); if( victim->pcdata->homepage ) pager_printf( ch, "%s%s homepage can be found at %s%s\r\n", s1, victim->sex == SEX_MALE ? "His" : victim->sex == SEX_FEMALE ? "Her" : "Its", s2, show_tilde( victim->pcdata->homepage ) ); if( victim->pcdata->bio ) pager_printf( ch, "%s%s%s's personal bio:\r\n%s%s", s2, victim->name, s1, s2, victim->pcdata->bio ); else pager_printf( ch, "%s%s %shas yet to create a bio.\r\n", s2, victim->name, s1 ); if( is_immortal( ch ) ) { pager_printf( ch, "%s.~`~.~`~.~`~.~`~.~`~.~`~.~`~%sImmortal Info%s~`~.~`~.~`~.~`~.~`~.~`~.~`~.~`~.~`~.\r\n", s1, s2, s1 ); if( victim->pcdata->email ) pager_printf( ch, "%sEmail: %s%s\r\n", s1, s2, victim->pcdata->email ); if( victim->pcdata->msn ) pager_printf( ch, "%sMSN: %s%s\r\n", s1, s2, victim->pcdata->msn ); if( victim->pcdata->yahoo ) pager_printf( ch, "%sYahoo: %s%s\r\n", s1, s2, victim->pcdata->yahoo ); if( victim->pcdata->gtalk ) pager_printf( ch, "%sGTalk: %s%s\r\n", s1, s2, victim->pcdata->gtalk ); if( victim->pcdata->authed_by ) pager_printf( ch, "%s%s %swas authorized by %s%s%s.\r\n", s2, victim->name, s1, s2, victim->pcdata->authed_by, s1 ); pager_printf( ch, "%s%s %shas killed %s%u %smobiles, and been killed by a mobile %s%u %stimes.\r\n", s2, victim->name, s1, s2, victim->pcdata->mkills, s1, s2, victim->pcdata->mdeaths, s1 ); if( victim->pcdata->pkills || victim->pcdata->pdeaths ) pager_printf( ch, "%s%s %shas killed %s%u %splayers, and been killed by a player %s%u %stimes.\r\n", s2, victim->name, s1, s2, victim->pcdata->pkills, s1, s2, victim->pcdata->pdeaths, s1 ); if( xIS_SET( victim->act, PLR_SILENCE ) || xIS_SET( victim->act, PLR_NO_EMOTE ) || xIS_SET( victim->act, PLR_NO_TELL ) ) { pager_printf( ch, "%sThis player has the following flags set:%s", s1, s2 ); if( xIS_SET( victim->act, PLR_SILENCE ) ) send_to_pager( " silence", ch ); if( xIS_SET( victim->act, PLR_NO_EMOTE ) ) send_to_pager( " noemote", ch ); if( xIS_SET( victim->act, PLR_NO_TELL ) ) send_to_pager( " notell", ch ); pager_printf( ch, "%s.\r\n", s1 ); } if( victim->desc && victim->desc->host[0] != '\0' ) /* added by Gorog */ pager_printf( ch, "%s%s%s's IP info: %s%s\r\n", s2, victim->name, s1, s2, victim->desc->host ); } } CMDF( do_pager ) { char arg[MIL]; if( is_npc( ch ) ) return; set_char_color( AT_NOTE, ch ); argument = one_argument( argument, arg ); if( !arg || arg[0] == '\0' ) { xTOGGLE_BIT( ch->pcdata->flags, PCFLAG_PAGERON ); if( xIS_SET( ch->pcdata->flags, PCFLAG_PAGERON ) ) ch_printf( ch, "Pager is now enabled at %d lines.\r\n", ch->pcdata->pagerlen ); else send_to_char( "Pager disabled.\r\n", ch ); return; } if( !is_number( arg ) ) { send_to_char( "Set page pausing to how many lines?\r\n", ch ); return; } ch->pcdata->pagerlen = UMAX( 5, atoi( arg ) ); ch_printf( ch, "Page pausing set to %d lines.\r\n", ch->pcdata->pagerlen ); } CMDF( do_klive ) { char arg[MIL]; if( is_npc( ch ) ) return; set_char_color( AT_NOTE, ch ); argument = one_argument( argument, arg ); if( !arg || arg[0] == '\0' ) { xTOGGLE_BIT( ch->act, PLR_K_LIVE ); if( xIS_SET( ch->act, PLR_K_LIVE ) ) ch_printf( ch, "KeepAlive time is now set to %d min%s.\r\n", ch->pcdata->kltime, ch->pcdata->kltime == 1 ? "" : "s" ); else send_to_char( "KeepAlive disabled.\r\n", ch ); return; } if( !is_number( arg ) ) { send_to_char( "Set time to how long ( 1 - 10 )?\r\n", ch ); return; } ch->pcdata->kltime = URANGE( 1, atoi( arg ), 10 ); ch_printf( ch, "KeepAlive time is now set to %d min%s.\r\n", ch->pcdata->kltime, ch->pcdata->kltime == 1 ? "" : "s" ); } /* * The ignore command allows players to ignore 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. * Usage: * 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 * - Fireblade */ CMDF( do_ignore ) { char arg[MIL]; IGNORE_DATA *temp, *next, *inew; CHAR_DATA *victim = NULL; if( is_npc( ch ) ) return; argument = one_argument( argument, arg ); /* If no arguements, then list players currently ignored */ if( !arg || arg[0] == '\0' ) { set_char_color( AT_DIVIDER, ch ); send_to_char( "\r\n----------------------------------------\r\n", ch ); set_char_color( AT_DGREEN, ch ); send_to_char( "You are currently ignoring:\r\n", ch ); set_char_color( AT_DIVIDER, ch ); send_to_char( "----------------------------------------\r\n", ch ); set_char_color( AT_IGNORE, ch ); if( !ch->pcdata->first_ignored ) send_to_char( " - No one\r\n", ch ); else { for( temp = ch->pcdata->first_ignored; temp; temp = temp->next ) ch_printf( ch, " - %s\r\n", temp->name ); } return; } set_char_color( AT_IGNORE, ch ); /* Clear players ignored if given arg "none" */ 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 ); } send_to_char( "You no longer ignore anyone.\r\n", ch ); return; } /* Prevent someone from ignoring themself... */ else if( !strcmp( arg, "self" ) || nifty_is_name( arg, ch->name ) ) { send_to_char( "Did you type something?\r\n", ch ); return; } /* get the name of the char who last sent tell to ch */ if( !strcmp( arg, "reply" ) ) { if( !ch->reply ) { send_to_char( "They're not here.\r\n", ch ); return; } else mudstrlcpy( arg, ch->reply->name, sizeof( arg ) ); } /* Loop through the linked list of ignored players */ for( temp = ch->pcdata->first_ignored; temp; temp = temp->next ) { /* 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 ); ch_printf( ch, "You no longer ignore %s.\r\n", temp->name ); STRFREE( temp->name ); DISPOSE( temp ); return; } } if( !( victim = get_char_world( ch, arg ) ) || is_npc( victim ) || strcmp( capitalize( arg ), victim->name ) != 0 ) { if( victim || !valid_pfile( arg ) ) { send_to_char( "No player exists by that name.\r\n", ch ); return; } } if( victim ) mudstrlcpy( arg, capitalize( victim->name ), sizeof( arg ) ); if( !check_parse_name( capitalize( arg ), true ) ) { send_to_char( "No player exists by that name.\r\n", ch ); return; } CREATE( inew, IGNORE_DATA, 1 ); inew->name = STRALLOC( capitalize( arg ) ); inew->next = NULL; inew->prev = NULL; LINK( inew, ch->pcdata->first_ignored, ch->pcdata->last_ignored, next, prev ); ch_printf( ch, "You now ignore %s.\r\n", inew->name ); } /* * 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 */ CMDF( do_version ) { set_char_color( AT_YELLOW, ch ); send_to_char( "DikuMUD\r\nMERC 2.1\r\nSMAUG 1.4\r\n", ch ); ch_printf( ch, "SMAUG %s.%s\r\n", SMAUG_VERSION_MAJOR, SMAUG_VERSION_MINOR ); ch_printf( ch, "LOP %s.%s\r\n", LOP_VERSION_MAJOR, LOP_VERSION_MINOR ); ch_printf( ch, "Last Compiled on %s at %s.\r\n", __DATE__, __TIME__ ); } /* * This code is so that if you are leading a group or have others following * you, you may use it to leave them behind while you do something without * them having to sit */ CMDF( do_solo ) { if( !ch || is_npc( ch ) ) return; set_pager_color( AT_WHITE, ch ); xTOGGLE_BIT( ch->act, PLR_SOLO ); ch_printf( ch, "You will %s allow others to follow you.\n\r", xIS_SET( ch->act, PLR_SOLO ) ? "not" : "now" ); act_printf( AT_GREY, ch, NULL, NULL, TO_ROOM, "$n will %s allow others to follow $m.", xIS_SET( ch->act, PLR_SOLO ) ? "not" : "now"); }