/*************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * _/ _/_/_/ _/ _/ _/ ACK! MUD is modified * * _/_/ _/ _/ _/ _/ Merc2.0/2.1/2.2 code * * _/ _/ _/ _/_/ _/ (c)Stephen Dooley 1994 * * _/_/_/_/ _/ _/ _/ "This mud has not been * * _/ _/ _/_/_/ _/ _/ _/ tested on animals." * * * * * * Much time and thought has gone into this software and you are * * benefitting. We hope that you share your changes too. What goes * * around, comes around. * ***************************************************************************/ #if defined(macintosh) #include <types.h> #else #include <sys/types.h> #endif #include <stdio.h> #include <string.h> #include <time.h> #include <malloc.h> #include "merc.h" #define NOWHERE -1 bool check_valid_ride ( CHAR_DATA * ch ); bool deathmatch; char * const compass_name [] = { "north", "east", "south", "west", "up", "down" }; char * const dir_name [] = { "to the North", "to the East", "to the South", "to the West", "Up", "Down" }; /* rev_name used to indicate where ch has come from when entering -S- */ char * const rev_name [] = { "the South", "the West", "the North", "the East", "Below", "Above" }; const sh_int rev_dir [] = { 2, 3, 0, 1, 5, 4 }; const sh_int movement_loss [SECT_MAX] = { 1, 2, 2, 3, 4, 6, 4, 1, 6, 10, 6 }; /* * Local functions. */ int find_door args( ( CHAR_DATA *ch, char *arg ) ); bool has_key args( ( CHAR_DATA *ch, int key ) ); /* struct fol_data { struct fol_data *next; CHAR_DATA *ch; }; struct fol_data *fol_stack; struct fol_data *fol_free; */ void move_char( CHAR_DATA *ch, int door ) { CHAR_DATA *fch; CHAR_DATA *fch_next; ROOM_INDEX_DATA *in_room; ROOM_INDEX_DATA *to_room; EXIT_DATA *pexit; char buf[MAX_STRING_LENGTH]; char move_buf[MAX_STRING_LENGTH]; /* struct fol_data *fol = NULL; */ char tmp[MAX_STRING_LENGTH]; int need_movement; char door_name_leave[MSL]; char door_name_enter[MSL]; buf[0] = '\0'; move_buf[0] = '\0'; door_name_leave[0] = '\0'; door_name_leave[0] = '\0'; tmp[0] = '\0'; if ( door < 0 || door > 5 ) { bug( "Do_move: bad door %d.", door ); ch->using_named_door = FALSE; return; } if ( !IS_NPC( ch ) && ( ( ch->stance == STANCE_AMBUSH ) || ( ch->stance == STANCE_AC_BEST ) ) ) { send_to_char( "You step out of the shadows.\n\r", ch ); ch->stance = STANCE_WARRIOR; ch->stance_ac_mod = 0; ch->stance_dr_mod = 0; ch->stance_hr_mod = 0; act( "$n steps out of the Shadows!", ch, NULL, NULL, TO_ROOM ); } if ( IS_NPC( ch ) ) ch->using_named_door = TRUE; in_room = ch->in_room; if ( ( pexit = in_room->exit[door] ) == NULL || ( to_room = pexit->to_room ) == NULL || ( ( str_cmp( pexit->keyword, "" ) ) && ( ch->using_named_door == FALSE ) ) ) { send_to_char( "Alas, you cannot go that way.\n\r", ch ); ch->using_named_door = FALSE; return; } if ( str_cmp( pexit->keyword, "" ) ) { if ( pexit->keyword[0] == '^' ) { sprintf( door_name_leave, "through the %s", pexit->keyword + 1); sprintf( door_name_enter, "the %s", pexit->keyword + 1); } else { sprintf( door_name_leave, "through the %s", pexit->keyword ); sprintf( door_name_enter, "the %s", pexit->keyword ); } } else { sprintf( door_name_leave, "%s", dir_name[door] ); sprintf( door_name_enter, "%s", rev_name[door] ); } if ( IS_SET( in_room->affected_by, ROOM_BV_ENCAPS ) || IS_SET( to_room->affected_by, ROOM_BV_ENCAPS ) ) { if ( IS_NPC( ch ) && IS_SET( ch->act, ACT_INTELLIGENT ) ) { if ( ch->mana > mana_cost( ch, skill_lookup( "room dispel" ) ) ) do_cast( ch, "room dispel" ); } else { send_to_char( "A barely visible energy web stops your movement!\n\r", ch ); ch->using_named_door = FALSE; return; } } if ( IS_SET( in_room->affected_by, ROOM_BV_HOLD ) ) { if ( IS_NPC( ch ) && IS_SET( ch->act, ACT_INTELLIGENT ) ) { if ( ch->mana > mana_cost( ch, skill_lookup( "room dispel" ) ) ) do_cast( ch, "room dispel" ); } else { send_to_char( "A fleeting vision of bars appears before the exit, and stops your movement!\n\r", ch ); ch->using_named_door = FALSE; return; } } if ( IS_SET(pexit->exit_info, EX_CLOSED) ) { if ( !IS_AFFECTED(ch, AFF_PASS_DOOR) && ( !item_has_apply( ch, ITEM_APPLY_PASS_DOOR ) ) ) { if ( IS_SET( pexit->exit_info, EX_NODETECT ) ) send_to_char( "Alas, you cannot go that way.\n\r", ch ); else act( "The $d is closed.", ch, NULL, pexit->keyword, TO_CHAR ); ch->using_named_door = FALSE; return; } else if ( IS_SET( pexit->exit_info, EX_PASSPROOF ) ) { if ( IS_SET( pexit->exit_info, EX_NODETECT ) ) send_to_char( "Alas, you cannot go that way.\n\r", ch ); else act( "You don't seem to be able to pass through $d.", ch, NULL, pexit->keyword, TO_CHAR ); ch->using_named_door = FALSE; return; } } if ( IS_AFFECTED(ch, AFF_CHARM) && ch->master != NULL && in_room == ch->master->in_room ) { send_to_char( "What? And leave your beloved master?\n\r", ch ); ch->using_named_door = FALSE; return; } if ( room_is_private( to_room ) && !IS_IMMORTAL(ch) ) { send_to_char( "That room is private right now.\n\r", ch ); ch->using_named_door = FALSE; return; } /* need 1 move if riding - Celestian */ if (ch->position == POS_RIDING ) { need_movement = 1; if (IS_RIDING(ch)) { if (!IS_AWAKE(ch->riding)) { send_to_char("Your mount ignores you completely.\r\n", ch); ch->using_named_door = FALSE; return; } if ((ch->riding)->position != POS_STANDING) { act("$N twists $S head around and looks at you quizzically.", ch, 0, ch->riding, TO_CHAR); act("$N looks quizzically at $n.", ch, 0, ch->riding, TO_CHAR); ch->using_named_door = FALSE; return; } } else { send_to_char("Bummer, looks like your mount gave you the slip.\r\n", ch); ch->position = POS_STANDING; update_pos(ch); ch->using_named_door = FALSE; return; } } if ( IS_SET( pexit->exit_info, EX_IMMORTAL ) && !IS_IMMORTAL( ch ) ) { send_to_char( "Only an Immortal may use that exit.\n\r", ch ); ch->using_named_door = FALSE; return; } /* Int Mobs need to be able to handle climbs */ if ( IS_SET( pexit->exit_info, EX_CLIMB ) && IS_NPC(ch) && !IS_AFFECTED( ch, AFF_FLYING ) ) { if ( ch->mana > mana_cost( ch, skill_lookup( "fly" ) ) ) { do_cast( ch, "fly" ); } else { send_to_char( "Looks like you'd have to climb up there.\n\r", ch ); ch->using_named_door = FALSE; return; } } if (!IS_NPC(ch) && ch->pcdata->learned[gsn_climb] == 0 && IS_SET( pexit->exit_info, EX_CLIMB ) && !IS_AFFECTED( ch, AFF_FLYING ) && !item_has_apply( ch, ITEM_APPLY_FLY ) ) { send_to_char( "You'd need to be able to fly or climb to go that way!\n\r", ch ); ch->using_named_door = FALSE; return; } if ( !IS_NPC(ch) ) { int iClass; int iRace; int iClan; int move; /* Check if room is a guild-only one... */ for ( iClass = 0; iClass < MAX_CLASS; iClass++ ) { if ( ch->lvl[iClass] == -1 && to_room->vnum == class_table[iClass].guild && !IS_IMMORTAL( ch ) ) { send_to_char( "You aren't allowed in there.\n\r", ch ); ch->using_named_door = FALSE; return; } } /* Check if room is a race-only one... */ for ( iRace = 0; iRace < MAX_RACE; iRace++ ) { if ( iRace != ch->race && to_room->vnum == race_table[iRace].race_room && !IS_IMMORTAL( ch ) ) { send_to_char( "You aren't allowed in there.\n\r", ch ); ch->using_named_door = FALSE; return; } } /* Check if room is a clan-only one... */ for ( iClan = 0; iClan < MAX_CLAN; iClan++ ) { if ( iClan != ch->pcdata->clan && to_room->vnum == clan_table[iClan].clan_room && !IS_IMMORTAL( ch ) ) { send_to_char( "You aren't allowed in there.\n\r", ch ); ch->using_named_door = FALSE; return; } } if ( to_room->vnum == ROOM_VNUM_BUILDER && ( !IS_IMMORTAL( ch ) && !IS_SET( ch->act, PLR_BUILDER ) ) ) { send_to_char( "The Portal allows entrance to builders only.\n\r", ch ); ch->using_named_door = FALSE; return; } if ( to_room->vnum == ROOM_VNUM_CLAN && ( IS_NPC( ch ) || ( ( !IS_IMMORTAL( ch ) ) && ( !IS_SET( ch->pcdata->pflags, PFLAG_CLAN_BOSS ) ) ) ) ) { send_to_char( "Only Clan Bosses may enter this room.\n\r", ch ); ch->using_named_door = FALSE; return; } if ( in_room->sector_type == SECT_AIR || to_room->sector_type == SECT_AIR ) { if ( ( ( !IS_AFFECTED(ch, AFF_FLYING) ) && ( !item_has_apply( ch, ITEM_APPLY_FLY ) ) ) && ( ( ch->riding != NULL ) && ( !IS_SET( ch->riding->affected_by, AFF_FLYING ) ) ) ) { if ( ( IS_NPC( ch ) ) && ( IS_SET( ch->act, ACT_INTELLIGENT ) ) && ( ch->mana > mana_cost( ch, skill_lookup( "fly" ) ) ) ) { do_cast( ch, "fly" ); } else { send_to_char( "You can't fly.\n\r", ch ); ch->using_named_door = FALSE; return; } } } if ( in_room->sector_type == SECT_WATER_NOSWIM || to_room->sector_type == SECT_WATER_NOSWIM ) { OBJ_DATA *obj; bool found; /* * Look for a boat. */ found = FALSE; /* * Suggestion for flying above water by Sludge */ if ( ( IS_AFFECTED( ch, AFF_FLYING ) ) || ( item_has_apply( ch, ITEM_APPLY_FLY) ) ) found = TRUE; if ( ( ch->riding != NULL ) && ( IS_SET( ch->riding->affected_by, AFF_FLYING ) ) ) found = TRUE; for ( obj = ch->first_carry; obj != NULL; obj = obj->next_in_carry_list ) { if ( obj->item_type == ITEM_BOAT ) { found = TRUE; break; } } if ( !found ) { if ( ( IS_NPC( ch ) ) && ( IS_SET( ch->act, ACT_INTELLIGENT ) ) && ( ch->mana > mana_cost( ch, skill_lookup( "fly" ) ) ) ) { do_cast( ch, "fly" ); } else { send_to_char( "You need a boat to go there.\n\r", ch ); ch->using_named_door = FALSE; return; } } } move = movement_loss[UMIN(SECT_MAX-1, in_room->sector_type)] + movement_loss[UMIN(SECT_MAX-1, to_room->sector_type)] ; if ( IS_AFFECTED( ch, AFF_FLYING )|| item_has_apply( ch, ITEM_APPLY_FLY) ) move=1; if ( ch->move < move ) { send_to_char( "You are too exhausted.\n\r", ch ); ch->using_named_door = FALSE; return; } WAIT_STATE( ch, 1 ); ch->move -= move; } /* Mount code - Celestian */ if ( ch->position == POS_RIDING) { if (check_valid_ride(ch)) { sprintf(tmp, "You ride %s on %s.\n\r", door_name_leave, ch->riding->short_descr); send_to_char(tmp, ch); sprintf(tmp, "$n rides %s on %s.", door_name_leave, ch->riding->short_descr); } } /* if ( ( !IS_AFFECTED(ch, AFF_SNEAK) && !item_has_apply( ch, ITEM_APPLY_SNEAK ) ) && ( IS_NPC(ch) || !IS_SET(ch->act, PLR_WIZINVIS) ) ) */ { if ( IS_SET( pexit->exit_info, EX_CLIMB ) ) /* dir_name[door] */ act( "$n climbs $T.", ch, NULL, door_name_leave, TO_ROOM ); else if ( IS_SET( pexit->exit_info, EX_CLOSED ) ) /* using passdoor */ { sprintf( buf, "$L$n floats %s.", door_name_leave ); act( buf, ch, NULL, pexit->keyword, TO_ROOM ); } else { if ( IS_NPC( ch ) || ( !IS_NPC( ch ) && ( IS_WOLF( ch ) && ( IS_SHIFTED( ch ) || IS_RAGED( ch ) ) ) ) ) sprintf( move_buf, "$L$n %s $T.", "wanders" ); else if ( ch->riding == NULL ) { sprintf( move_buf, "$L%s$n %s $T.", get_ruler_title( ch->pcdata->ruler_rank, ch->login_sex ), ch->pcdata->room_exit ); } else if ( ch->riding != NULL ) { sprintf( move_buf, "$L%s$n rides $T on %s.", get_ruler_title( ch->pcdata->ruler_rank, ch->login_sex ), ch->riding->short_descr ); } act( move_buf, ch, NULL, door_name_leave, TO_ROOM ); } } char_from_room( ch ); char_to_room( ch, to_room ); /* Mount code - Celestian */ if (IS_RIDING(ch)) { char_from_room( ch->riding ); char_to_room( ch->riding, to_room ); if ((ch->riding)->in_room->vnum == NOWHERE) { ch->using_named_door = FALSE; return; } } /* if ( ( !IS_AFFECTED(ch, AFF_SNEAK) && !item_has_apply( ch, ITEM_APPLY_SNEAK ) ) && ( IS_NPC(ch) || !IS_SET(ch->act, PLR_WIZINVIS) ) ) */ { if ( IS_NPC( ch ) || ( !IS_NPC( ch ) && ( IS_WOLF( ch ) && ( IS_SHIFTED( ch ) || IS_RAGED( ch ) ) ) ) ) sprintf( move_buf, "$L$n %s $T.", "wanders in from" ); else if ( ch->riding == NULL ) { sprintf( move_buf, "$L%s$n %s $T.", get_ruler_title( ch->pcdata->ruler_rank, ch->login_sex ), ch->pcdata->room_enter ); } else if ( ch->riding != NULL ) { sprintf( move_buf, "$L%s$n rides in from $T on %s.", get_ruler_title( ch->pcdata->ruler_rank, ch->login_sex ), ch->riding->short_descr ); } act( move_buf, ch, NULL, door_name_enter, TO_ROOM ); } do_look( ch, "auto" ); if ( in_room != to_room ) { for ( fch = in_room->first_person; fch != NULL; fch = fch_next ) { fch_next = fch->next_in_room; if ( fch->master == ch && fch->position == POS_STANDING ) { act( "You follow $N.", fch, NULL, ch, TO_CHAR ); fch->using_named_door = TRUE; move_char( fch, door ); } } } if ( !IS_NPC( ch ) && IS_VAMP( ch ) && !IS_IMMORTAL( ch ) ) check_vamp( ch ); /* burn the vampire! */ mprog_entry_trigger(ch); mprog_greet_trigger(ch); ch->using_named_door = FALSE; return; } void do_north( CHAR_DATA *ch, char *argument ) { move_char( ch, DIR_NORTH ); return; } void do_east( CHAR_DATA *ch, char *argument ) { move_char( ch, DIR_EAST ); return; } void do_south( CHAR_DATA *ch, char *argument ) { move_char( ch, DIR_SOUTH ); return; } void do_west( CHAR_DATA *ch, char *argument ) { move_char( ch, DIR_WEST ); return; } void do_up( CHAR_DATA *ch, char *argument ) { move_char( ch, DIR_UP ); return; } void do_down( CHAR_DATA *ch, char *argument ) { move_char( ch, DIR_DOWN ); return; } int find_door( CHAR_DATA *ch, char *arg ) { EXIT_DATA *pexit; 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 { for ( door = 0; door <= 5; door++ ) { if ( ( pexit = ch->in_room->exit[door] ) != NULL && IS_SET(pexit->exit_info, EX_ISDOOR) && pexit->keyword != NULL && is_name( arg, pexit->keyword ) ) return door; } act( "I see no $T here.", ch, NULL, arg, TO_CHAR ); return -1; } if ( ( ( pexit = ch->in_room->exit[door] ) == NULL ) || ( str_cmp( pexit->keyword, "" ) && !is_name( arg, pexit->keyword ) ) ) { act( "I see no door $T here.", ch, NULL, arg, TO_CHAR ); return -1; } if ( !IS_SET(pexit->exit_info, EX_ISDOOR) ) { send_to_char( "You can't do that.\n\r", ch ); return -1; } return door; } void do_open( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; OBJ_DATA *obj; int door; one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Open what?\n\r", ch ); return; } if ( ( obj = get_obj_here( ch, arg ) ) != NULL ) { /* 'open object' */ if ( obj->item_type != ITEM_CONTAINER ) { send_to_char( "That's not a container.\n\r", ch ); return; } if ( !IS_SET(obj->value[1], CONT_CLOSED) ) { send_to_char( "It's already open.\n\r", ch ); return; } if ( !IS_SET(obj->value[1], CONT_CLOSEABLE) ) { send_to_char( "You can't do that.\n\r", ch ); return; } if ( IS_SET(obj->value[1], CONT_LOCKED) ) { send_to_char( "It's locked.\n\r", ch ); return; } REMOVE_BIT(obj->value[1], CONT_CLOSED); send_to_char( "Ok.\n\r", ch ); act( "$n opens $p.", ch, obj, NULL, TO_ROOM ); return; } if ( ( door = find_door( ch, arg ) ) >= 0 ) { /* 'open door' */ ROOM_INDEX_DATA *to_room; EXIT_DATA *pexit; EXIT_DATA *pexit_rev; pexit = ch->in_room->exit[door]; if ( !IS_SET(pexit->exit_info, EX_CLOSED) ) { send_to_char( "It's already open.\n\r", ch ); return; } if ( IS_SET(pexit->exit_info, EX_LOCKED) ) { send_to_char( "It's locked.\n\r", ch ); return; } REMOVE_BIT(pexit->exit_info, EX_CLOSED); act( "$n opens the $d.", ch, NULL, pexit->keyword, TO_ROOM ); send_to_char( "Ok.\n\r", ch ); /* open the other side */ if ( ( to_room = pexit->to_room ) != NULL && ( pexit_rev = to_room->exit[rev_dir[door]] ) != NULL && pexit_rev->to_room == ch->in_room ) { CHAR_DATA *rch; REMOVE_BIT( pexit_rev->exit_info, EX_CLOSED ); for ( rch = to_room->first_person; rch != NULL; rch = rch->next_in_room ) act( "The $d opens.", rch, NULL, pexit_rev->keyword, TO_CHAR ); } } return; } void do_close( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; OBJ_DATA *obj; int door; one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Close what?\n\r", ch ); return; } if ( ( obj = get_obj_here( ch, arg ) ) != NULL ) { /* 'close object' */ if ( obj->item_type != ITEM_CONTAINER ) { send_to_char( "That's not a container.\n\r", ch ); return; } if ( IS_SET(obj->value[1], CONT_CLOSED) ) { send_to_char( "It's already closed.\n\r", ch ); return; } if ( !IS_SET(obj->value[1], CONT_CLOSEABLE) ) { send_to_char( "You can't do that.\n\r", ch ); return; } SET_BIT(obj->value[1], CONT_CLOSED); send_to_char( "Ok.\n\r", ch ); act( "$n closes $p.", ch, obj, NULL, TO_ROOM ); return; } if ( ( door = find_door( ch, arg ) ) >= 0 ) { /* 'close door' */ ROOM_INDEX_DATA *to_room; EXIT_DATA *pexit; EXIT_DATA *pexit_rev; pexit = ch->in_room->exit[door]; if ( IS_SET(pexit->exit_info, EX_CLOSED) ) { send_to_char( "It's already closed.\n\r", ch ); return; } SET_BIT(pexit->exit_info, EX_CLOSED); act( "$n closes the $d.", ch, NULL, pexit->keyword, TO_ROOM ); send_to_char( "Ok.\n\r", ch ); /* close the other side */ if ( ( to_room = pexit->to_room ) != NULL && ( pexit_rev = to_room->exit[rev_dir[door]] ) != 0 && pexit_rev->to_room == ch->in_room ) { CHAR_DATA *rch; SET_BIT( pexit_rev->exit_info, EX_CLOSED ); for ( rch = to_room->first_person; rch != NULL; rch = rch->next_in_room ) act( "The $d closes.", rch, NULL, pexit_rev->keyword, TO_CHAR ); } } return; } bool has_key( CHAR_DATA *ch, int key ) { OBJ_DATA *obj; for ( obj = ch->first_carry; obj != NULL; obj = obj->next_in_carry_list ) { if ( obj->pIndexData->vnum == key ) return TRUE; } return FALSE; } void do_lock( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; OBJ_DATA *obj; int door; one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Lock what?\n\r", ch ); return; } if ( ( obj = get_obj_here( ch, arg ) ) != NULL ) { /* 'lock object' */ if ( obj->item_type != ITEM_CONTAINER ) { send_to_char( "That's not a container.\n\r", ch ); return; } if ( !IS_SET(obj->value[1], CONT_CLOSED) ) { send_to_char( "It's not closed.\n\r", ch ); return; } if ( obj->value[2] < 0 ) { send_to_char( "It can't be locked.\n\r", ch ); return; } if ( !has_key( ch, obj->value[2] ) ) { send_to_char( "You lack the key.\n\r", ch ); return; } if ( IS_SET(obj->value[1], CONT_LOCKED) ) { send_to_char( "It's already locked.\n\r", ch ); return; } SET_BIT(obj->value[1], CONT_LOCKED); send_to_char( "*Click*\n\r", ch ); act( "$n locks $p.", ch, obj, NULL, TO_ROOM ); return; } if ( ( door = find_door( ch, arg ) ) >= 0 ) { /* 'lock door' */ ROOM_INDEX_DATA *to_room; EXIT_DATA *pexit; EXIT_DATA *pexit_rev; pexit = ch->in_room->exit[door]; if ( !IS_SET(pexit->exit_info, EX_CLOSED) ) { send_to_char( "It's not closed.\n\r", ch ); return; } if ( pexit->key < 0 ) { send_to_char( "It can't be locked.\n\r", ch ); return; } if ( !has_key( ch, pexit->key) ) { send_to_char( "You lack the key.\n\r", ch ); return; } if ( IS_SET(pexit->exit_info, EX_LOCKED) ) { send_to_char( "It's already locked.\n\r", ch ); return; } SET_BIT(pexit->exit_info, EX_LOCKED); send_to_char( "*Click*\n\r", ch ); act( "$n locks the $d.", ch, NULL, pexit->keyword, TO_ROOM ); /* lock the other side */ if ( ( to_room = pexit->to_room ) != NULL && ( pexit_rev = to_room->exit[rev_dir[door]] ) != 0 && pexit_rev->to_room == ch->in_room ) { SET_BIT( pexit_rev->exit_info, EX_LOCKED ); } } return; } void do_unlock( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; OBJ_DATA *obj; int door; one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Unlock what?\n\r", ch ); return; } if ( ( obj = get_obj_here( ch, arg ) ) != NULL ) { /* 'unlock object' */ if ( obj->item_type != ITEM_CONTAINER ) { send_to_char( "That's not a container.\n\r", ch ); return; } if ( !IS_SET(obj->value[1], CONT_CLOSED) ) { send_to_char( "It's not closed.\n\r", ch ); return; } if ( obj->value[2] < 0 ) { send_to_char( "It can't be unlocked.\n\r", ch ); return; } if ( !has_key( ch, obj->value[2] ) ) { send_to_char( "You lack the key.\n\r", ch ); return; } if ( !IS_SET(obj->value[1], CONT_LOCKED) ) { send_to_char( "It's already unlocked.\n\r", ch ); return; } REMOVE_BIT(obj->value[1], CONT_LOCKED); send_to_char( "*Click*\n\r", ch ); act( "$n unlocks $p.", ch, obj, NULL, TO_ROOM ); return; } if ( ( door = find_door( ch, arg ) ) >= 0 ) { /* 'unlock door' */ ROOM_INDEX_DATA *to_room; EXIT_DATA *pexit; EXIT_DATA *pexit_rev; pexit = ch->in_room->exit[door]; if ( !IS_SET(pexit->exit_info, EX_CLOSED) ) { send_to_char( "It's not closed.\n\r", ch ); return; } if ( pexit->key < 0 ) { send_to_char( "It can't be unlocked.\n\r", ch ); return; } if ( !has_key( ch, pexit->key) ) { send_to_char( "You lack the key.\n\r", ch ); return; } if ( !IS_SET(pexit->exit_info, EX_LOCKED) ) { send_to_char( "It's already unlocked.\n\r", ch ); return; } REMOVE_BIT(pexit->exit_info, EX_LOCKED); send_to_char( "*Click*\n\r", ch ); act( "$n unlocks the $d.", ch, NULL, pexit->keyword, TO_ROOM ); /* unlock the other side */ if ( ( to_room = pexit->to_room ) != NULL && ( pexit_rev = to_room->exit[rev_dir[door]] ) != NULL && pexit_rev->to_room == ch->in_room ) { REMOVE_BIT( pexit_rev->exit_info, EX_LOCKED ); } } return; } void do_pick( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *gch; OBJ_DATA *obj; int door; one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Pick what?\n\r", ch ); return; } WAIT_STATE( ch, skill_table[gsn_pick_lock].beats ); /* look for guards */ for ( gch = ch->in_room->first_person; gch; gch = gch->next_in_room ) { if ( IS_NPC(gch) && IS_AWAKE(gch) && ch->level + 5 < gch->level ) { act( "$N is standing too close to the lock.", ch, NULL, gch, TO_CHAR ); return; } } if ( !IS_NPC(ch) && number_percent( ) > ch->pcdata->learned[gsn_pick_lock] ) { send_to_char( "You failed.\n\r", ch); return; } if ( ( obj = get_obj_here( ch, arg ) ) != NULL ) { /* 'pick object' */ if ( obj->item_type != ITEM_CONTAINER ) { send_to_char( "That's not a container.\n\r", ch ); return; } if ( !IS_SET(obj->value[1], CONT_CLOSED) ) { send_to_char( "It's not closed.\n\r", ch ); return; } if ( obj->value[2] < 0 ) { send_to_char( "It can't be unlocked.\n\r", ch ); return; } if ( !IS_SET(obj->value[1], CONT_LOCKED) ) { send_to_char( "It's already unlocked.\n\r", ch ); return; } if ( IS_SET(obj->value[1], CONT_PICKPROOF) ) { send_to_char( "You failed.\n\r", ch ); return; } REMOVE_BIT(obj->value[1], CONT_LOCKED); send_to_char( "*Click*\n\r", ch ); act( "$n picks $p.", ch, obj, NULL, TO_ROOM ); return; } if ( ( door = find_door( ch, arg ) ) >= 0 ) { /* 'pick door' */ ROOM_INDEX_DATA *to_room; EXIT_DATA *pexit; EXIT_DATA *pexit_rev; pexit = ch->in_room->exit[door]; if ( !IS_SET(pexit->exit_info, EX_CLOSED) ) { send_to_char( "It's not closed.\n\r", ch ); return; } if ( pexit->key < 0 ) { send_to_char( "It can't be picked.\n\r", ch ); return; } if ( !IS_SET(pexit->exit_info, EX_LOCKED) ) { send_to_char( "It's already unlocked.\n\r", ch ); return; } if ( IS_SET(pexit->exit_info, EX_PICKPROOF) ) { send_to_char( "You failed.\n\r", ch ); return; } REMOVE_BIT(pexit->exit_info, EX_LOCKED); send_to_char( "*Click*\n\r", ch ); act( "$n picks the $d.", ch, NULL, pexit->keyword, TO_ROOM ); /* pick the other side */ if ( ( to_room = pexit->to_room ) != NULL && ( pexit_rev = to_room->exit[rev_dir[door]] ) != NULL && pexit_rev->to_room == ch->in_room ) { REMOVE_BIT( pexit_rev->exit_info, EX_LOCKED ); } } return; } void do_stand( CHAR_DATA *ch, char *argument ) { switch ( ch->position ) { case POS_SLEEPING: if ( IS_AFFECTED(ch, AFF_SLEEP) ) { send_to_char( "You can't wake up!\n\r", ch ); return; } send_to_char( "You wake and stand up.\n\r", ch ); act( "$n wakes and stands up.", ch, NULL, NULL, TO_ROOM ); ch->position = POS_STANDING; break; case POS_RESTING: send_to_char( "You stand up.\n\r", ch ); act( "$n stands up.", ch, NULL, NULL, TO_ROOM ); if ( ch->sitting != NULL ) { ch->sitting->value[1]--; ch->sitting = NULL; } ch->position = POS_STANDING; break; case POS_STANDING: send_to_char( "You are already standing.\n\r", ch ); break; case POS_FIGHTING: send_to_char( "You are already fighting!\n\r", ch ); break; case POS_RIDING: send_to_char( "Dismount first!\n\r", ch ); break; } return; } void do_rest( CHAR_DATA *ch, char *argument ) { OBJ_DATA *furn=NULL; bool sit; sit = FALSE; if ( argument[0] != '\0' ) { furn = get_obj_here( ch, argument ); if ( furn == NULL || furn->item_type != ITEM_FURNITURE ) { send_to_char( "You can't rest on that!\n\r", ch ); return; } if ( furn->value[1] >= furn->value[0] ) { send_to_char( "It's full already!\n\r", ch ); return; } sit = TRUE; } switch ( ch->position ) { case POS_SLEEPING: send_to_char( "You are already sleeping.\n\r", ch ); break; case POS_RESTING: send_to_char( "You are already resting.\n\r", ch ); break; case POS_STANDING: if ( sit==FALSE ) { send_to_char( "You rest.\n\r", ch ); act( "$n rests.", ch, NULL, NULL, TO_ROOM ); } else { ch->sitting = furn; act( "$n rests on $p", ch, furn, NULL, TO_ROOM ); act( "You rest on $p", ch, furn, NULL, TO_CHAR ); ch->sitting->value[1]++; } ch->position = POS_RESTING; break; case POS_FIGHTING: send_to_char( "You are already fighting!\n\r", ch ); break; case POS_RIDING: send_to_char( "Dismount first!\n\r", ch ); break; } return; } void do_sleep( CHAR_DATA *ch, char *argument ) { switch ( ch->position ) { case POS_SLEEPING: send_to_char( "You are already sleeping.\n\r", ch ); break; case POS_RESTING: case POS_STANDING: send_to_char( "You sleep.\n\r", ch ); act( "$n sleeps.", ch, NULL, NULL, TO_ROOM ); ch->position = POS_SLEEPING; break; case POS_FIGHTING: send_to_char( "You are already fighting!\n\r", ch ); break; case POS_RIDING: send_to_char( "Dismount first!\n\r", ch ); break; } return; } void do_wake( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; one_argument( argument, arg ); if ( arg[0] == '\0' ) { do_stand( ch, argument ); return; } if ( !IS_AWAKE(ch) ) { send_to_char( "You are asleep yourself!\n\r", ch ); return; } if ( ( victim = get_char_room( ch, arg ) ) == NULL ) { send_to_char( "They aren't here.\n\r", ch ); return; } if ( IS_AWAKE(victim) ) { act( "$N is already awake.", ch, NULL, victim, TO_CHAR ); return; } if ( IS_AFFECTED(victim, AFF_SLEEP) ) { act( "You can't wake $M!", ch, NULL, victim, TO_CHAR ); return; } act( "You wake $M.", ch, NULL, victim, TO_CHAR ); act( "$n wakes you.", ch, NULL, victim, TO_VICT ); victim->position = POS_STANDING; return; } void do_shadowform( CHAR_DATA *ch, char *argument ) { AFFECT_DATA af; send_to_char( "You attempt to take on shadow form.\n\r", ch ); act( "$n tries to take on shadow form.", ch, NULL, NULL, TO_ROOM ); affect_strip( ch, gsn_sneak ); if ( IS_NPC(ch) || number_percent( ) < ch->pcdata->learned[gsn_shadow] ) { af.type = gsn_sneak; af.duration = ch->level; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_SNEAK; affect_to_char( ch, &af ); } return; } void do_sneak( CHAR_DATA *ch, char *argument ) { AFFECT_DATA af; send_to_char( "You attempt to move silently.\n\r", ch ); affect_strip( ch, gsn_sneak ); if ( IS_NPC(ch) || number_percent( ) < ch->pcdata->learned[gsn_sneak] ) { af.type = gsn_sneak; af.duration = ch->level; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_SNEAK; affect_to_char( ch, &af ); } return; } void do_hide( CHAR_DATA *ch, char *argument ) { send_to_char( "You attempt to hide.\n\r", ch ); if ( IS_AFFECTED(ch, AFF_HIDE) ) REMOVE_BIT(ch->affected_by, AFF_HIDE); if ( IS_NPC(ch) || number_percent( ) < ch->pcdata->learned[gsn_hide] ) SET_BIT(ch->affected_by, AFF_HIDE); return; } /* * Contributed by Alander. */ void do_visible( CHAR_DATA *ch, char *argument ) { affect_strip ( ch, gsn_invis ); affect_strip ( ch, gsn_mass_invis ); affect_strip ( ch, gsn_sneak ); REMOVE_BIT ( ch->affected_by, AFF_HIDE ); REMOVE_BIT ( ch->affected_by, AFF_INVISIBLE ); REMOVE_BIT ( ch->affected_by, AFF_SNEAK ); send_to_char( "You become more visible again.\n\r", ch ); return; } void do_clan_recall( CHAR_DATA *ch, char *argument ) { ROOM_INDEX_DATA *location; if ( IS_NPC( ch ) ) return; if (deathmatch) { send_to_char("Not during a DEATHMATCH!!!\n\r", ch ); return; } if ( ch->pcdata->clan == 0 ) { send_to_char( "You must be in a clan to use this command!!\n\r", ch ); return; } else location = get_room_index( clan_table[ch->pcdata->clan].clan_room ); if ( location == NULL ) { send_to_char( "You are well lost, like.\n\r", ch ); return; } if ( IS_SET(ch->in_room->room_flags, ROOM_NO_RECALL) || IS_AFFECTED(ch, AFF_CURSE) ) { send_to_char( "Some strange force prevents your transport.\n\r", ch ); return; } if ( ch->in_room == location ) { send_to_char( "You didn't have far to go, did you?\n\r", ch ); return; } if ( ch->fighting != NULL ) { send_to_char( "You can't use this command when fighting!!\n\r", ch ); return; } act( "$n is engulfed in a stream of red light!!", ch, NULL, NULL, TO_ROOM ); send_to_char( "You are engulfed in a stream of red light, carrying you home!\n\r", ch ); char_from_room( ch ); char_to_room( ch, location ); if ( ch->riding != NULL ) { char_from_room( ch->riding ); char_to_room( ch->riding, location ); } act( "$n arrives, carried upon a stream of red light!!", ch, NULL, NULL, TO_ROOM ); do_look( ch, "auto" ); return; } void do_recall( CHAR_DATA *ch, char *argument ) { char buf[MAX_STRING_LENGTH]; CHAR_DATA *victim; ROOM_INDEX_DATA *location; int recall_index; act( "$n makes the Holy Sign for transportation!", ch, 0, 0, TO_ROOM ); buf[0] = '\0'; /* FIXME: Need to check if NPC is charmed - if so find * owner's recall location..... -S- */ /* if ( IS_NPC( ch ) || ch->level < 6 ) */ if ( IS_VAMP( ch ) ) location = get_room_index( VAMPIRE_RECALL ); else location = get_room_index( ROOM_VNUM_TEMPLE ); if ( !IS_NPC( ch ) ) location = get_room_index( ch->pcdata->recall_vnum ); if ( deathmatch ) { recall_index = number_range( ROOM_VNUM_DM_RECALL, ROOM_VNUM_DM_RECALL + 35); location = get_room_index( recall_index ); if ( ch->hit > 250 ) { send_to_char( "@@lYou wince in pain as you feel your molecules disperse, then reform.@@N\n\r", ch ); ch->hit -= 200; } else { send_to_char( "Your molecules begin to disperse, then reform quickly, leaving you here.\n\r", ch ); return; } } /* Only recall to midgaard now... */ /* else location = get_room_index( race_table[ch->race].recall ); */ if ( location == NULL ) { send_to_char( "You are completely lost.\n\r", ch ); return; } if ( ch->in_room == location ) return; if ( IS_SET(ch->in_room->room_flags, ROOM_NO_RECALL) || IS_AFFECTED(ch, AFF_CURSE) ) { send_to_char( "Some strange force prevents your recall.\n\r", ch ); return; } if ( ( victim = ch->fighting ) != NULL ) { int lose; if ( number_bits( 1 ) == 0 ) { WAIT_STATE( ch, 4 ); lose = ( ch->level / 4 ) +1; lose = UMIN( lose, ch->exp ); gain_exp( ch, 0 - lose ); sprintf( buf, "You failed! You lose %d exps.\n\r", lose ); send_to_char( buf, ch ); return; } lose = ( ch->level / 4 ) +25; lose = UMIN( lose, ch->exp ); gain_exp( ch, 0 - lose ); sprintf( buf, "You recall from combat! You lose %d exps.\n\r", lose ); send_to_char( buf, ch ); stop_fighting( ch, TRUE ); } ch->move = (ch->move > 10) ? ( ch->move - 10 ) : 0; act( "$n is engulfed by a stream of blue light!", ch, NULL, NULL, TO_ROOM ); char_from_room( ch ); char_to_room( ch, location ); if ( ch->riding != NULL ) { char_from_room( ch->riding ); char_to_room( ch->riding, location ); } act( "$n arrives, carried by a stream of blue light!", ch, NULL, NULL, TO_ROOM ); do_look( ch, "auto" ); return; } void do_train( CHAR_DATA *ch, char *argument ) { char buf[MAX_STRING_LENGTH]; char buf2[20]; CHAR_DATA *mob; int hp_gain = 0; int mana_gain = 0; sh_int *pAbility; int pMax = 0; char *pOutput; int cost,cost1,cost2,cost3,cost4,cost5; /* Urrgghh */ buf[0] = '\0'; buf2[0] = '\0'; if ( IS_NPC(ch) ) { send_to_char( "Not for NPCs. Sorry.\n\r", ch ); return; } /* * Check for trainer. */ for ( mob = ch->in_room->first_person; mob; mob = mob->next_in_room ) { if ( IS_NPC(mob) && IS_SET(mob->act, ACT_TRAIN) ) break; } if ( mob == NULL ) { send_to_char( "You can't do that here.\n\r", ch ); return; } if ( argument[0] == '\0' ) { sprintf( buf, "You have %d practice sessions.\n\r", ch->practice ); send_to_char( buf, ch ); argument = "foo"; } cost = 4; if ( !str_cmp( argument, "str" ) ) { if ( class_table[ch->class].attr_prime == APPLY_STR ) cost = 3; pAbility = &ch->pcdata->perm_str; pMax = ch->pcdata->max_str; pOutput = "strength"; } else if ( !str_cmp( argument, "int" ) ) { if ( class_table[ch->class].attr_prime == APPLY_INT ) cost = 3; pAbility = &ch->pcdata->perm_int; pMax = ch->pcdata->max_int; pOutput = "intelligence"; } else if ( !str_cmp( argument, "wis" ) ) { if ( class_table[ch->class].attr_prime == APPLY_WIS ) cost = 3; pAbility = &ch->pcdata->perm_wis; pMax = ch->pcdata->max_wis; pOutput = "wisdom"; } else if ( !str_cmp( argument, "dex" ) ) { if ( class_table[ch->class].attr_prime == APPLY_DEX ) cost = 3; pAbility = &ch->pcdata->perm_dex; pMax = ch->pcdata->max_dex; pOutput = "dexterity"; } else if ( !str_cmp( argument, "con" ) ) { if ( class_table[ch->class].attr_prime == APPLY_CON ) cost = 3; pAbility = &ch->pcdata->perm_con; pMax = ch->pcdata->max_con; pOutput = "constitution"; } else if ( !str_cmp( argument, "hp" ) ) { pAbility = &ch->max_hit; pOutput = "number of hit points"; cost = 4; /* this is pracs per "train hp" */ hp_gain = 1; /* this is hp gained per "train hp" */ } else if ( !str_cmp( argument, "mana" ) ) { pAbility = &ch->max_mana; pOutput = "amount of mana"; cost =5; mana_gain = 1; } else { /* Work out the costs... */ cost1=4 ;cost2=4 ;cost3=4 ;cost4=4 ;cost5=4; if ( class_table[ch->class].attr_prime == APPLY_STR ) cost1 = 3; if ( class_table[ch->class].attr_prime == APPLY_INT ) cost2 = 3; if ( class_table[ch->class].attr_prime == APPLY_WIS ) cost3 = 3; if ( class_table[ch->class].attr_prime == APPLY_DEX ) cost4 = 3; if ( class_table[ch->class].attr_prime == APPLY_CON ) cost5 = 3; strcpy( buf, "You can train: hp (4) mana (5)" ); if ( ch->pcdata->perm_str < ch->pcdata->max_str ) { strcat( buf, " str" ); sprintf( buf2, " (%d)", cost1 ); strcat( buf, buf2 ); } if ( ch->pcdata->perm_int < ch->pcdata->max_int ) { strcat( buf, " int" ); sprintf( buf2, " (%d)", cost2 ); strcat( buf, buf2 ); } if ( ch->pcdata->perm_wis < ch->pcdata->max_wis ) { strcat( buf, " wis" ); sprintf( buf2, " (%d)", cost3 ); strcat( buf, buf2 ); } if ( ch->pcdata->perm_dex < ch->pcdata->max_dex ) { strcat( buf, " dex" ); sprintf( buf2, " (%d)", cost4 ); strcat( buf, buf2 ); } if ( ch->pcdata->perm_con < ch->pcdata->max_con ) { strcat( buf, " con" ); sprintf( buf2, " (%d)", cost5 ); strcat( buf, buf2 ); } if ( buf[strlen(buf)-1] != ':' ) { strcat( buf, ".\n\r" ); send_to_char( buf, ch ); } return; } if ( !str_cmp( argument, "hp" ) ) { if ( cost > ch->practice ) { send_to_char( "You don't have enough practices.\n\r", ch ); return; } ch->practice -= cost; *pAbility += hp_gain; ch->pcdata->hp_from_gain += 1; act( "Your $T increases!", ch, NULL, pOutput, TO_CHAR ); act( "$n's $T increases!", ch, NULL, pOutput, TO_ROOM ); return; } if ( !str_cmp( argument, "mana" ) ) { if ( cost > ch->practice ) { send_to_char( "You don't have enough practices.\n\r", ch ); return; } ch->practice -= cost; *pAbility += mana_gain; ch->pcdata->mana_from_gain += 1; act( "Your $T increases!", ch, NULL, pOutput, TO_CHAR ); act( "$n's $T increases!", ch, NULL, pOutput, TO_ROOM ); return; } if ( *pAbility >= pMax ) { act( "Your $T is already at maximum.", ch, NULL, pOutput, TO_CHAR ); return; } if ( cost > ch->practice ) { send_to_char( "You don't have enough practices.\n\r", ch ); return; } ch->practice-= cost; *pAbility+= 1; act( "Your $T increases!", ch, NULL, pOutput, TO_CHAR ); act( "$n's $T increases!", ch, NULL, pOutput, TO_ROOM ); return; } void do_guild( CHAR_DATA *ch, char *argument ) { send_to_char( "This command is no longer employed here!\n\r", ch ); return; } void do_halls( CHAR_DATA *ch, char *argument ) /* Quite a lot of the following code derives from the original * MERC2.2 code, although the tweaks are my own. * -- Stephen */ { CHAR_DATA *victim; /* Remember to limit use of this command to immorts! */ if (ch->level < 81) { send_to_char( "Huh?\n\r", ch); return; } act( "$n prepares to return to the Halls of the Immortals!", ch, 0, 0, TO_ROOM ); /* Check is immort is fighting. * Stop fight if they are! */ if ( ( victim = ch->fighting ) != NULL ) { stop_fighting( ch, TRUE ); } act( "$n vanishes into a beam of energy!", ch, NULL, NULL, TO_ROOM ); char_from_room( ch ); char_to_room( ch, get_room_index(1015) ); act( "$n steps out of the energy beam!", ch, NULL, NULL, TO_ROOM ); do_look( ch, "auto" ); return; } void do_smash( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; int door; int best; int cnt; bool joke; /* Was it unlocked to start with? */ joke = FALSE; one_argument( argument, arg ); best = -1; if ( !IS_NPC( ch ) ) for ( cnt = 0; cnt < MAX_CLASS; cnt++ ) if ( ch->lvl[cnt] >= skill_table[gsn_smash].skill_level[cnt] ) best = cnt; else best = ch->level; if ( best == -1 ) { send_to_char( "You don't know of such a skill.\n\r", ch ); return; } if ( arg[0] == '\0' ) { send_to_char( "Smash what?\n\r", ch ); return; } if ( ( door = find_door( ch, arg ) ) >= 0 ) { /* 'open door' */ ROOM_INDEX_DATA *to_room; EXIT_DATA *pexit; EXIT_DATA *pexit_rev; pexit = ch->in_room->exit[door]; if ( !IS_SET(pexit->exit_info, EX_CLOSED) ) { send_to_char( "It's already open.\n\r", ch ); return; } if ( ( 2*number_percent() > ch->pcdata->learned[gsn_smash] ) || ( IS_SET(pexit->exit_info, EX_SMASHPROOF) ) ) { act( "$n tries to smash the $d, but fails.", ch, NULL, pexit->keyword, TO_ROOM ); send_to_char( "You failed!\n\r", ch ); return; } if ( IS_SET(pexit->exit_info, EX_LOCKED) ) REMOVE_BIT( pexit->exit_info, EX_LOCKED ); else joke = TRUE; REMOVE_BIT(pexit->exit_info, EX_CLOSED); act( "$n smashes opens the $d.", ch, NULL, pexit->keyword, TO_ROOM ); act( "You smash open the $d.", ch, NULL, pexit->keyword, TO_CHAR ); if ( joke ) { act( "The $d was already unlocked!!!", ch, NULL, pexit->keyword, TO_ROOM ); act( "The $d was already unlocked!!!", ch, NULL, pexit->keyword, TO_CHAR ); act( "$n tumbles through $d!!!", ch, NULL, pexit->keyword, TO_ROOM ); act( "You tumble through $d!!!", ch, NULL, pexit->keyword, TO_CHAR ); } /* open the other side */ if ( ( to_room = pexit->to_room ) != NULL && ( pexit_rev = to_room->exit[rev_dir[door]] ) != NULL && pexit_rev->to_room == ch->in_room ) { CHAR_DATA *rch; if ( IS_SET(pexit_rev->exit_info, EX_LOCKED) ) REMOVE_BIT( pexit_rev->exit_info, EX_LOCKED ); REMOVE_BIT( pexit_rev->exit_info, EX_CLOSED ); for ( rch = to_room->first_person; rch != NULL; rch = rch->next_in_room ) act( "The $d is smashed open.", rch, NULL, pexit_rev->keyword, TO_CHAR ); if ( joke ) { char_from_room( ch ); char_to_room( ch, to_room ); act( "$n tumbles into the room, head over heels!", ch, NULL, NULL, TO_ROOM ); do_look( ch, "" ); } } } return; } void do_scan( CHAR_DATA *ch, char *argument ) /* Informs ch if there are any (N)PCs in the 6 adjacent rooms. * I'm sure this could be written better.... ;) * -- Stephen */ { ROOM_INDEX_DATA *location; int door; char buf[MAX_INPUT_LENGTH]; char person[MAX_INPUT_LENGTH]; CHAR_DATA *d; bool found = FALSE; buf[0] = '\0'; person[0] = '\0'; act( "$n looks all around for anyone else.", ch, NULL, NULL, TO_ROOM ); send_to_char( "You look around.\n\r", ch ); location = ch->in_room; for ( door = 0; door < 6; door++ ) { EXIT_DATA *pexit; if ( ( pexit = location->exit[door] ) == 0 || pexit->to_room == NULL || IS_SET( pexit->exit_info, EX_CLOSED) || ( str_cmp( pexit->keyword, "" ) ) || ( pexit->to_room->vnum == ch->in_room->vnum ) ) { /* Then this direction is "invalid" */ continue; } else { for ( d = pexit->to_room->first_person; d != NULL; d = d->next_in_room ) { if ( ( pexit->to_room->vnum == d->in_room->vnum ) && can_see( ch, d ) ) { found = TRUE; /* bit here to set person to (N)PC name */ if ( IS_NPC( d ) ) { sprintf( person, "%s (NPC)", d->short_descr); } else { sprintf( person, "%s", PERS( d, ch ) ); } sprintf( buf, "%s : %s\n\r", dir_name[door], person ); send_to_char( buf, ch ); } } if ( ( pexit->to_room->affected_by != 0 ) && ( ( is_affected( ch, skill_lookup( "detect magic" ) ) ) || ( item_has_apply( ch, ITEM_APPLY_DET_MAG ) ) ) ) { sprintf( buf, "The room %s has a @@rMagical@@N Affect!!!\n\r", dir_name[door] ); send_to_char( buf, ch ); } } } if ( !found ) { send_to_char( "You fail to spot anyone around you.\n\r", ch ); } return; } void do_enter( CHAR_DATA *ch, char *argument ) { OBJ_DATA *portal; ROOM_INDEX_DATA *to_room; OBJ_DATA *foo; OBJ_DATA * foo_next; int door; if ( argument[0] == '\0' ) { send_to_char( "Enter what?\n\r", ch ); return; } portal = get_obj_here( ch, argument ); if ( portal == NULL || portal->item_type != ITEM_PORTAL || portal->value[2] == 0 ) { /* look for a keyworded door */ if ( ( door = find_door( ch, argument ) ) >= 0 ) { /* enterable exit */ ch->using_named_door = TRUE; move_char( ch, door ); return; } else { /* send_to_char( "You can't enter that!\n\r", ch ); */ return; } return; } if ( ( to_room = get_room_index( portal->value[0] ) ) == NULL ) { send_to_char( "Nothing happens.\n\r", ch ); return; } if ( ( IS_SET( ch->in_room->room_flags, ROOM_NO_PORTAL ) || IS_SET( to_room->room_flags, ROOM_NO_PORTAL ) ) && number_range( 0, 100 ) < 75 ) { act( "The anti-magic zone causes the portal to @@eIMPLODE@@N!!!", ch, NULL, NULL, TO_ROOM); send_to_char( "The anti-magic zone causes the portal to @@eIMPLODE@@N!!!", ch); extract_obj( portal ); /* Now check if there is a corresponding portal in to_room */ for ( foo = to_room->first_content; foo != NULL; foo = foo_next ) { foo_next = foo->next_in_room; if ( foo->item_type == ITEM_PORTAL && foo->value[0] == ch->in_room->vnum ) break; extract_obj ( foo ); } return; } act( "$n enters $p.", ch, portal, NULL, TO_ROOM ); act( "You enter $p.", ch, portal, NULL, TO_CHAR ); /* Now check if there is a corresponding portal in to_room */ for ( foo = to_room->first_content; foo != NULL; foo = foo->next_in_room ) if ( foo->item_type == ITEM_PORTAL && foo->value[0] == ch->in_room->vnum ) break; char_from_room( ch ); char_to_room( ch, to_room ); if ( foo == NULL ) act( "A glowing sphere forms, and $n steps out!", ch, NULL, NULL, TO_ROOM ); else act( "$n steps out of $p.", ch, foo, NULL, TO_ROOM ); do_look( ch, "" ); return; } void do_scout ( CHAR_DATA *ch, char *argument ) { ROOM_INDEX_DATA *loc; ROOM_INDEX_DATA *tmploc; int door; int depth = 0; int counter; CHAR_DATA *target; char buf[MAX_INPUT_LENGTH]; char pre[MAX_INPUT_LENGTH]; buf[0] = '\0'; pre[0] = '\0'; if ( !IS_NPC(ch) && ch->pcdata->learned[gsn_scout] == 0 ) { send_to_char( "You are not trained in this skill!\n\r", ch ); return; } if ( !IS_NPC(ch) ) { /* depth is the number of rooms AWAY from your present location */ if ( ch->pcdata->learned[gsn_scout] > 78 ) depth = 4; else if ( ch->pcdata->learned[gsn_scout] > 64 ) depth = 3; else if ( ch->pcdata->learned[gsn_scout] > 40 ) depth = 2; else depth = 1; } act( "$n looks all around for anyone else.", ch, NULL, NULL, TO_ROOM ); send_to_char( "You look around.\n\r", ch ); while ( depth > 0 ) { loc = ch->in_room; for ( door = 0; door < 6; door++ ) { tmploc = loc; /* get the room */ for ( counter = 0; counter < depth; counter++ ) { if ( tmploc->exit[door] == 0 || tmploc->exit[door]->to_room == NULL || IS_SET( tmploc->exit[door]->exit_info, EX_CLOSED ) || ( str_cmp( tmploc->exit[door]->keyword, "" ) ) ) break; tmploc = tmploc->exit[door]->to_room; } /* if room didn't exist */ if ( counter < depth ) continue; for ( target = tmploc->first_person; target != NULL; target = target->next_in_room ) { if ( target->in_room->vnum == ch->in_room->vnum ) break; if ( !can_see( ch, target ) ) continue; if ( depth == 1 ) sprintf( pre, "%s : ", dir_name[door] ); else if ( depth == 2 ) sprintf( pre, "Far %s : ", dir_name[door] ); else if ( depth == 3 ) sprintf( pre, "Very Far %s : ", dir_name[door] ); else if ( depth == 4 ) sprintf( pre, "Distant %s : ", dir_name[door] ); if ( IS_NPC( target ) ) sprintf( buf, "%s%s\n\r", pre, target->short_descr ); else sprintf( buf, "%s%s\n\r", pre, target->name ); send_to_char( buf, ch ); } } depth = depth - 1; } }