tfe-1.0/area/
tfe-1.0/files/
tfe-1.0/logs/
tfe-1.0/logs/immortal/
tfe-1.0/logs/mob/
tfe-1.0/logs/object/
tfe-1.0/logs/player/
tfe-1.0/logs/room/
tfe-1.0/notes/clans/
tfe-1.0/player/
tfe-1.0/prev/
tfe-1.0/prev/area/
tfe-1.0/prev/player/
tfe-1.0/prev/rooms/
tfe-1.0/rooms/
tfe-1.0/src-gc/
tfe-1.0/src-msvc/
tfe-1.0/src-unix/
tfe-1.0/www/
tfe-1.0/www/html/
#include <ctype.h>
#include <sys/types.h>
#include <stdio.h>
#include "define.h"
#include "struct.h"


/*
 *   CONSTANTS
 */


#define  MOVE_FLEE        -1
#define  MOVE_SLITHERS     0
#define  MOVE_SNEAK        1
#define  MOVE_WALK         2
#define  MOVE_FLY          3
#define  MOVE_SWIM         4
#define  MOVE_FLOAT        5
#define  MOVE_WADE         6


const char* leaving_verb [] = { "slithers", "sneaks", "leaves", "flies",
  "swims", "floats", "wades" }; 

const char* leaving_action [] = { "slither", "sneak", "leave", "fly",
  "swim", "float", "wade" };

const char* arriving_verb [] = { "slithers in", "sneaks in", "arrives",
  "flies in", "swims in", "floats in", "wades in" };


const direction_type dir_table [] =
{ 
  { "north", 2, "the south",  "to the north"  },
  { "east",  3, "the west",   "to the east"   },
  { "south", 0, "the north",  "to the south"  },
  { "west",  1, "the east",   "to the west"   },
  { "up",    5, "below",      "above you"     },
  { "down",  4, "above",      "below you"     },
  { "extra", 6, "??",         "??"            }
};


char_data* leader = NULL;


/*
 *   LOCAL FUNCTIONS
 */


bool        passes_drunk      ( char_data* );
bool        trigger_entering  ( char_data*, room_data*, int );
bool        trigger_leaving   ( char_data*, room_data*, int, action_data*& );
bool        can_enter         ( char_data*, room_data* );
bool        can_leave         ( char_data*, int, bool );
bool        handle_terrain    ( char_data*, room_data*, room_data*,
                                int&, int& );
bool        is_exhausted      ( char_data*, int&, int );
int         get_motion        ( char_data* );
int         find_door         ( char_data*, char* );
exit_data*  valid_exit        ( char_data*, int );
void        act_leader        ( const char*, char_data* );
void        add_delays        ( char_data*, int& );

#define rd  room_data
#define cd  char_data

void   arrival_message   ( cd*, rd*, exit_data*, int, action_data* );
void   leaving_message   ( cd*, rd*, exit_data*, int, action_data* );
void   leaving_self      ( cd*, exit_data*, int, action_data* );
void   leaving_other     ( cd*, cd*, rd*, exit_data*, int, action_data* );

#undef rd
#undef cd


/*
 *   MOVEMENT ABILITIES
 */


bool char_data :: can_float( )
{
  if( is_set( affected_by, AFF_FLOAT ) )
    return TRUE;

  return FALSE;
}


bool char_data :: can_swim( )
{
  if( can_breath_underwater( ) )
    return TRUE;

  if( species != NULL )
    return is_set( &species->act_flags, ACT_CAN_SWIM );

  return( shdata->skill[SKILL_SWIMMING] != 0 );
} 


bool char_data :: can_fly( )
{
  if( species == NULL )
    return FALSE;

  return is_set( &species->act_flags, ACT_CAN_FLY );
} 


bool char_data :: can_breath_underwater( )
{
  if( species != NULL )
    return is_set( &species->act_flags, ACT_CAN_SWIM );

  return FALSE;
}


bool can_climb( char_data* ch )
{
  if( ch->species != NULL
    && !is_set( &ch->species->act_flags, ACT_CAN_CLIMB ) )
    return FALSE;
  
  return TRUE;
}


/*
 *   CAN MOVE ROUTINE
 */ 


bool Char_Data :: Can_Move( exit_data* exit )
{
  if( is_set( &exit->exit_info, EX_CLOSED ) 
    && !is_set( affected_by, AFF_PASS_DOOR ) )
    return FALSE;

  if( Size( ) > exit->to_room->size )
    return FALSE;

  if( pcdata == NULL
    && ( is_set( &species->act_flags, ACT_SENTINEL )
    || is_set( &exit->to_room->room_flags, RFLAG_NO_MOB )
    || ( is_set( &species->act_flags, ACT_STAY_AREA )
    && exit->to_room->area != in_room->area ) ) )
    return FALSE;

  return TRUE;
}


/*
 *   MAIN MOVEMENT ROUTINE
 */


void move_char( char_data* ch, int door, bool flee )
{
  action_data*   action;
  char_data*   follower;
  room_data*    in_room  = ch->in_room;
  room_data*    to_room;
  exit_data*       exit;
  char_array*      list  = NULL;
  int              move;
  int              type;

  ch->shown = 1;

  if( ch->rider != NULL ) {
    move_char( ch->rider, door, flee );
    return;
    }

  if( ( exit = valid_exit( ch, door ) ) == NULL 
    || !can_leave( ch, door, flee ) )
    return;

  to_room = exit->to_room;

  if(  !can_enter( ch, to_room ) 
    || !handle_terrain( ch, in_room, to_room, move, type ) )
    return;

  add_delays( ch, move );

  if(   is_exhausted( ch, move, type ) 
    || !trigger_leaving( ch, in_room, door, action )
    || !passes_drunk( ch ) )
    return;

  if( ch->mount != NULL )
    ch->mount->move -= move;
  else
    ch->move -= move;

  if( flee )
    type = MOVE_FLEE;

  if( leader == NULL ) {
    leader = ch;
    list = followers( ch, ch->array );
    }

  leaving_message( ch, in_room, exit, type, action );
  make_tracks( ch, in_room, door );

  ch->From( );
  ch->To( to_room );

  if( ch->mount != NULL ) {
    ch->mount->From( );
    ch->mount->To( to_room );
    }

  ch->room_position = dir_table[door].reverse;

  arrival_message( ch, to_room, exit, type, action );

  if( list != NULL ) {
    for( int i = 0; i < *list; i++ ) 
      if( ( follower = list->list[i] ) != leader
        && follower->leader->in_room != follower->in_room
        && follower->position == POS_STANDING )
        move_char( follower, door, FALSE );

    for( int i = 0; i < *list; i++ ) {
      follower = list->list[i];
      if( follower->in_room == to_room ) {
        send( "\n\r", follower );
        show_room( follower, to_room, TRUE, TRUE );
        }
      }

    for( int i = 0; i < *list; i++ ) {
      follower = list->list[i];
      if( follower->in_room == to_room ) 
        trigger_entering( follower, to_room, dir_table[door].reverse );
      remove_bit( &follower->status, STAT_FOLLOWER );
      }

    delete list;
    }

  if( leader == ch ) 
    leader = NULL;

  if( ch->active.time == -1 )
    add_queue( &ch->active, 5 );
}


/* 
 *   MESSAGE ROUTINES
 */


bool group_message( char_data* ch, char_data* actor )
{
  if( actor == leader || !is_set( &actor->status, STAT_FOLLOWER ) ) 
    return FALSE;    

  if( ch->pcdata == NULL
    || !is_set( &ch->pcdata->message, MSG_GROUP_MOVE ) )
    return TRUE;
  
  if( actor->Seen( ch ) ) {
    if( actor->leader == ch ) 
      send( ch, "%s follows you.\n\r", actor );
    else
      send( ch, "%s follows %s.\n\r", actor, actor->leader );
    }

  return TRUE;
}


void arrival_message( char_data* ch, room_data* room, exit_data* exit,
  int type, action_data* )
{
  char_data*        rch;
  room_data*    to_room;
  int              back  = dir_table[ exit->direction ].reverse;

  if( type == MOVE_FLEE ) {
    if( ch->mount != NULL ) 
      fsend( *ch->array,
        "%s, riding %s, charges blindly in, fleeing something %s.\n\r",
        ch, ch->mount, dir_table[back].where );
    else
      fsend( *ch->array,
        "%s arrives, obviously fleeing something %s.\n\r",
        ch, dir_table[back].where );
    return;
    }

  for( int i = 0; i < room->contents; i++ )  
    if( ( rch = character( room->contents[i] ) ) != NULL
      && rch != ch && rch->link != NULL
      && rch->position > POS_SLEEPING
      && !group_message( rch, ch ) ) {
      if( ch->Seen( rch ) ) {
        if( ch->mount != NULL ) 
          send( rch, "%s riding %s has arrived.\n\r", ch, ch->mount );
        else 
          send( rch, "%s %s from %s.\n\r", ch,
            arriving_verb[type],
            dir_table[ exit->direction ].arrival_msg );
        }
      /*
      else if( can_hear( rch ) ) 
        send( rch, "You hear someone or something arrive.\n\r" );
      */
      }

  for( int i = 0; i < room->exits; i++ ) {
    to_room = room->exits[i]->to_room;
    for( int j = 0; j < to_room->contents; j++ )  
      if( ( rch = character( to_room->contents[j] ) ) != NULL
        && is_set( rch->affected_by, AFF_SENSE_DANGER ) )
        send( rch, "You sense %s %s.\n\r", ch,
          dir_table[ exit->direction ].where );
    }

  return;
}


/* 
 *   LEAVING MESSAGES
 */


const char* leaving_msg [] =
{
  "to_char",  "You $t $T.\n\r",
  "to_room",  "$1 $t $T.\n\r",
  ""
};


void leaving_message( char_data* ch, room_data* room, exit_data* exit,
  int type,  action_data* action )
{
  char_data* rch;

  if( type == MOVE_FLEE ) {
    if( ch->mount != NULL ) {
      send( ch, "Fleeing the battle, you ride %s %s.\n\r",
        ch->mount, dir_table[ exit->direction ].name );
      send( *ch->array, "Fleeing the battle, %s rides %s %s.\n\r",
        ch, ch->mount, dir_table[ exit->direction ].name );
      }
    else {
      send( ch, "You flee %s.\n\r", dir_table[ exit->direction ].name );
      send( *ch->array, "%s blindly flees %s.\n\r", ch,
        dir_table[ exit->direction ].name );
      }
    return;
    }

  leaving_self( ch, exit, type, action );

  for( int i = 0; i < room->contents; i++ ) 
    if( ( rch = character( room->contents[i] ) ) != NULL
      && ch != rch && rch->link != NULL
      && rch->position > POS_SLEEPING
      && !group_message( rch, ch ) ) 
      leaving_other( rch, ch, room, exit, type, action );
}


void leaving_self( char_data* ch, exit_data* exit,
  int type, action_data* action )
{
  if( ch->mount != NULL ) {
    send( ch, "You ride %s %s.\n\r", ch->mount,
      dir_table[ exit->direction ].name );
    } 
  else if( leader != NULL && leader != ch ) {
    send( ch, "You follow %s.\n\r", ch->leader );
    } 
  else if( is_set( &exit->exit_info, EX_CLOSED ) ) {
    send( ch, "You %s through %s!\n\r",
      exit->direction == DIR_UP
      || exit->direction == DIR_DOWN ? "climb" : "step",
      exit->name );      
    }
  else {
    act( ch, prog_msg( action, leaving_msg[0], leaving_msg[1] ),
      ch, NULL, leaving_action[type],
      dir_table[ exit->direction ].name );
    }
      
  return;
}


void leaving_other( char_data* rch, char_data* ch, room_data* room,
  exit_data* exit, int type, action_data* action )
{
  if( !ch->Seen( rch ) ) {
    /*
    if( can_hear( rch, ch ) ) 
      send( rch, "You hear someone or something leave %s.\n\r", 
        dir_table[door].name );
	*/
    return;
    }

  if( is_set( &exit->exit_info, EX_CLOSED ) ) {
    send( rch, "%s %s %s passing through %s!\n\r",
      ch, leaving_verb[type], dir_table[ exit->direction ].name, 
      exit->name );
    }
  else if( ch->mount == NULL ) {
    act( rch, prog_msg( action, leaving_msg[2], leaving_msg[3] ),
      ch, NULL,leaving_verb[type],
      dir_table[ exit->direction ].name );
    }
  else {
    send( rch, "%s rides %s %s.\n\r", ch, ch->mount,
      dir_table[ exit->direction ].name );
    }
}


/*
 *   SUBROUTINES OF MAIN MOVEMENT FUNCTION
 */


bool can_leave( char_data* ch, int door, bool flee )
{
  char_data*    rch;
  bool        after;

  if( is_set( ch->affected_by, AFF_ENTANGLED ) ) {
    send( "You are entangled in a web and quite stuck.\n\r", ch );
    act_leader(
      "** %s is entangled in a web and unable to follow you. **\n\r", ch );
    return FALSE;
    }

  if( flee )
    return TRUE;

  if( opponent( ch ) != NULL ) {
    send( "You can't walk away from a battle - use flee.\n\r", ch );
    act_leader( "** %s is fighting and unable to follow you. **\n\r", ch );  
    return FALSE;
    }

  after = TRUE;
  for( int i = 0; i < *ch->array; i++ ) { 
    if( ( rch = character( ch->array->list[i] ) ) != NULL ) {
      if( rch == ch ) {
        after = FALSE; 
        continue;
        }
      if( includes( rch->aggressive, ch )
        && rch->Size( ) > max( SIZE_GNOME,
        ch->Size( )-2 ) && rch->position >= POS_FIGHTING && ( ( after
        && rch->room_position == door ) || ( !after
        && ch->room_position != door ) ) 
        && !is_set( ch->affected_by, AFF_ENTANGLED ) ) {
        send( ch, "%s is blocking your exit %s.\n\r", rch,
          dir_table[door].name );
        return FALSE;
        }
      }    
    }

  return TRUE;
}


exit_data* valid_exit( char_data* ch, int door )
{
  exit_data* exit = exit_direction( ch->in_room, door );

  if( exit == NULL || !exit->Seen( ch ) ) {
    if( ch->in_room->Seen( ch ) )
      send( ch, "You see no exit %s.\n\r", 
        dir_table[ door ].where );
    else { 
      fsend( ch, "You attempt to move %s but find yourself unable to.\n\r",
        dir_table[door].name );
      fsend_seen( ch,
        "%s attempts to move %s and runs straight into a wall.",
        ch, dir_table[door].name );
      }
    return NULL;
    }

  if( is_set( &exit->exit_info, EX_CLOSED )
    && !is_set( ch->affected_by, AFF_PASS_DOOR ) ) {
    send( ch, "%s is closed.\n\r", exit );
    return NULL;
    }

  if( is_set( &exit->exit_info, EX_REQUIRES_CLIMB ) 
    && !can_climb( ch ) && !ch->can_fly( ) ) {
    act_leader( "** %s is unable to climb so can't follow you. **\n\r", ch );
    send( ch, "Leaving %s requires you to climb which you are incapable\
 of.\n\r", dir_table[door].name );
    return NULL;
    }   

  return exit;
}


bool can_enter( char_data* ch, room_data* room )
{
  if( ch->pcdata != NULL && room->area->status != AREA_OPEN
    && room->area->status != AREA_IMMORTAL
    && !is_apprentice( ch ) ) {
    send( ch, "That area is not open to players yet.\n\r" );
    return FALSE;
    }

  if( ch->Size( ) > room->size ) {
    send( ch, "You are too large to fit in there.\n\r" );
    act_leader( "** %s is too large to follow you there. **\n\r", ch );
    return FALSE;
    }
  
  if( ch->mount != NULL ) {
    if( ch->mount->Size( ) > room->size ) {
      send( ch, "%s is too large to fit in there.\n\r", ch->mount );
      return FALSE;
      }
    if( IS_SET( room->room_flags, RFLAG_NO_MOUNT ) ) {
      send( "You can not go there while mounted.\n\r", ch );
      return FALSE;
      }
    } 

  return TRUE;
}


/*
 *   DRUNK ROUTINE
 */


const char *drunk_message[] = {
  "You stumble and barely stay on your feet.\n\r",
  "$n stumbles and barely stays on $m feet.",

  "The ground moves quickly sending you reeling.\n\r",
  "$n staggers, obviously intoxicated.",

  "Your legs give way to gravity.\n\r",
  "$n suddenly sits down and looks quite surprised.",

  "You stumble.\n\r",
  "$n has had too much to drink and falls to the ground.",

  "You trip over your left foot.\n\r",
  "The feet of $n decide to fight and down $s falls."
  };


bool passes_drunk( char_data* ch )
{
//  int i;
  /*
  if( !IS_DRUNK( ch ) || number_range( 1, 20 ) < 18 || ch->mount != NULL )
    return TRUE;

  i = number_range( 0, 4 );

  send( ch, drunk_message[2*i] );
  act_room( drunk_message[2*i+1], ch, NULL, NULL, TO_ROOM );

  if( i <= 1 )
    return TRUE;

  ch->position  = POS_RESTING;
  ch->hit      -= 2;

  update_pos( ch );   
  */
  return TRUE;
}


/*
 *   EXHAUSTION
 */


void add_delays( char_data* ch, int& move )
{
  int   flag  [] = { PLR_TRACK, PLR_SEARCHING, PLR_SNEAK };
  int   cost  [] = { 2, 3, 2 };
  int      i;

  if( ch->pcdata == NULL ) 
    return;

  for( i = 0; i < 3; i++ ) 
    if( is_set( ch->pcdata->pfile->flags, flag[i] ) ) 
      move += cost[i];
}


bool is_exhausted( char_data* ch, int& move, int type )
{
  if( type == MOVE_SWIM && ch->pcdata != NULL )
    move *= 12-ch->shdata->skill[ SKILL_SWIMMING ];

  if( ch->mount != NULL ) {
    if( ch->mount->move < move ) {
      send( ch, "Your mount is exhausted.\n\r" );
      return TRUE;
      }
    }
  else {
    if( ch->move < move ) {
      send( "You are too exhausted.\n\r", ch );
      act_leader( "** %s is too exhausted to follow you. **\n\r", ch );
      return TRUE;
      }
    }

  return FALSE;
}


/*
 *   TERRAIN FUNCTIONS
 */


int get_motion( char_data* ch )
{
  if( ch->can_float( ) ) 
    return MOVE_FLOAT;

  if( ch->can_fly( ) ) 
    return MOVE_FLY;

  if( ch->species != NULL
    && is_set( &ch->species->act_flags, ACT_SLITHERS ) ) 
    return MOVE_SLITHERS;

  if( ch->pcdata != NULL
    && is_set( ch->pcdata->pfile->flags, PLR_SNEAK ) ) {
      ch->improve_skill( SKILL_SNEAK );
      return MOVE_SNEAK;
    }

  return MOVE_WALK;
}


bool handle_terrain( char_data* ch, room_data* from, room_data* to,
  int& move, int& type )
{
  char_data*   mount  = ch->mount;

  type = get_motion( mount == NULL ? ch : mount );
  
  switch( type ) {
    case MOVE_FLOAT:   move = 1;  break;
    case MOVE_FLY:     move = 3;  break;
    default:
      move = int( ( terrain[ from->sector_type ].movement_cost
        +terrain[ to->sector_type ].movement_cost )
        *( 1+5.*ch->contents.weight/ch->Capacity( ) )/3 );
    }

  if( to->sector_type == SECT_AIR ) {
    if( type == MOVE_FLY )
      return TRUE;
    if( mount != NULL ) {
      send( ch, "Your mount does not know how to fly.\n\r" );
      }
    else {
      send( ch, "You can't fly.\n\r" );
      act_leader(
        "** %s is unable to fly so does not follow you. **\n\r", ch );
      }
    return FALSE;
    }

  if(  to->sector_type == SECT_WATER_SURFACE 
    || to->sector_type == SECT_RIVER ) { 
    if( type <= MOVE_WALK ) {
      if( mount != NULL ) { 
        if( !mount->can_swim( ) ) {
          send( ch, "Your mount does not know how to swim.\n\r" );
          return FALSE;
          }
        }
      else {
        if( !ch->can_swim( ) ) {
          send( ch, "You don't know how to swim or fly.\n\r" );
          act_leader(
            "** %s can not swim or fly so fails to follow you. **\n\r", ch );
          return FALSE; 
          }
        }
      type = MOVE_SWIM;
      ch->improve_skill( SKILL_SWIMMING );
      }
    return TRUE;
    }   
  
  if( to->sector_type == SECT_UNDERWATER ) {
    if( mount != NULL ) {
      send( ch, "You can't ride underwater.\n\r" );
      return FALSE;
      }
    if( !ch->can_swim( ) ) {
      send( ch, "You don't how to swim.\n\r" );
      act_leader( "** %s can not swim so fails to follow you. **\n\r", ch ); 
      return FALSE;
      }
    type = MOVE_SWIM;
    return TRUE;
    }

  if( from->sector_type == SECT_SHALLOWS ) {
    type = ( ch->species != NULL
      && is_set( &ch->species->act_flags, ACT_CAN_SWIM ) )
      ? MOVE_SWIM : MOVE_WADE;
    return TRUE;
    }

  return TRUE;
}


/*
 *   ENTERING/LEAVNG TRIGGERS
 */


bool trigger_leaving( char_data *ch, room_data *room, int door,
  action_data*& action )
{
  char_data*       npc;
  mprog_data*    mprog;
  bool          result = TRUE;

  for( int i = 0; i < *ch->array; i++ ) { 
    if( ( npc = mob( ch->array->list[i] ) ) == NULL
      || npc->pcdata != NULL || npc->position < POS_RESTING
      || npc == ch )
      continue; 
    for( mprog = npc->species->mprog; mprog != NULL; mprog = mprog->next ) 
      if( mprog->trigger == MPROG_TRIGGER_LEAVING
        && ( mprog->value == door || mprog->value == -1 ) ) {
        var_ch   = ch;
        var_mob  = npc;
        var_room = room;
        if( !execute( mprog ) || ch->in_room != room )
          return FALSE;
        }
    }
 
  for( action = ch->in_room->action; action != NULL; action = action->next )
    if( action->trigger == TRIGGER_LEAVING 
      && is_set( &action->flags, door ) ) {
      var_ch   = ch;
      var_room = room;
      result = execute( action );
      if( ch->in_room != room ) 
        return FALSE;
      if( result )
        return TRUE;
      }

  return result;
}


bool trigger_entering( char_data *ch, room_data *room, int door )
{
  action_data*   action;
  char_data*        npc;
  mprog_data*     mprog;
//  obj_data*         obj;
//  obj_data*    obj_next;
//  oprog_data*     oprog;

  for( int i = 0; i < room->contents; i++ ) {
    if( ( npc = mob( room->contents[i] ) ) == NULL
      || npc == ch || npc->position < POS_RESTING ) 
      continue;
    for( mprog = npc->species->mprog; mprog != NULL; mprog = mprog->next ) 
      if( mprog->trigger == MPROG_TRIGGER_ENTRY
        && ( mprog->value == door || mprog->value == -1 ) )  {
        var_ch = ch;
        var_mob = npc;
        var_room = room;
        execute( mprog );
        if( ch->in_room != room )
          return FALSE;
        }
    }

  for( action = room->action; action != NULL; action = action->next )
    if( action->trigger == TRIGGER_ENTERING
      && is_set( &action->flags, door ) ) {
      var_ch   = ch; 
      var_room = room;
      execute( action );
      if( ch->in_room != room )
        return FALSE;
      break;
      }

  /*
  for( obj = room->contents; obj != NULL; obj = obj_next ) {
    obj_next = obj->next_content;
    for( oprog = obj->pIndexData->oprog; oprog != NULL; oprog = oprog->next ) 
      if( oprog->trigger == OPROG_TRIGGER_ENTERING ) {
        var_ch = ch;
        var_obj = obj;
        var_room = room;
        execute( oprog );
        if( ch->in_room != room )
          return FALSE;
        }
    }
  */

  return TRUE;
}


/*
 *   LEADER MESSAGE ROUTINES
 */


void act_leader( const char* text, char_data* follower )
{
  char buf [ MAX_INPUT_LENGTH ];

  if( leader == NULL )
    return;

  sprintf( buf, text, follower->Name( leader ) );
  buf[3] = toupper( buf[3] );
  send( buf, leader ); 

  return;
}


/*
 *   DO MOVE FUNCTIONS
 */


void do_north( char_data* ch, char* )
{
  move_char( ch, DIR_NORTH, FALSE );
  return;
}


void do_east( char_data *ch, char* )
{
  move_char( ch, DIR_EAST, FALSE );
  return;
}


void do_south( char_data *ch, char* )
{
  move_char( ch, DIR_SOUTH, FALSE );
  return;
}


void do_west( char_data* ch, char* )
{
  move_char( ch, DIR_WEST, FALSE );
  return;
}


void do_up( char_data *ch, char* )
{
  move_char( ch, DIR_UP, FALSE );
  return;
}


void do_down( char_data *ch, char* )
{
  move_char( ch, DIR_DOWN, FALSE );
  return;
};



/*
-------------------------------------------------------------------------
*/


void do_search( char_data* ch, char* argument )
{
  action_data*  action;
  room_data*      room  = ch->in_room;

  if( not_player( ch ) )
    return;

  if( toggle( ch, argument, "Searching",
    ch->pcdata->pfile->flags, PLR_SEARCHING ) ) {
    send( "[Searching increases movement point cost by 3 per\
 move.]\n\r", ch );
    return;
    }

  for( action = ch->in_room->action; action != NULL; action = action->next )
    if( action->trigger == TRIGGER_SEARCHING 
      && ( ( *action->target == '\0' && *argument == '\0' )
      || ( *argument != '\0' && is_name( argument, action->target ) ) ) ) {
      var_ch   = ch;
      var_room = ch->in_room;
      if( !execute( action ) || ch->in_room != room ) 
        return;
      break;
      }

  if( *argument == '\0' ) 
    send( "You rummage around but find nothing interesting.\n\r", ch );
  else
    send( "Whatever that is, searching it results in nothing\
 interesting.\n\r", ch ); 
}

  
/*
 *   SPEED WALKING
 */


bool speed_walking( char_data* ch, char* argument )
{
  int i;

  for( i = 0; argument[i] != '\0'; i++ ) {
    switch( toupper( argument[i] ) ) {
      case 'S':
      case 'N':
      case 'U':
      case 'D':
      case 'E':
      case 'W':
        break;

      default:
        return FALSE;
      }
    }

  send( ch, "Speed walking is not yet implemented.\n\r" );
  
  return TRUE;
}