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 <syslog.h>
#include "define.h"
#include "struct.h"


/*
 *   
 */


inline int modify_delay( char_data* ch, int delay )
{
  int slow  = is_set( ch->affected_by, AFF_SLOW );
  int haste = is_set( ch->affected_by, AFF_HASTE );

  if( slow-haste == -1 ) {
    return 2*delay/3;
    }
  else if( slow-haste == 1 ) {
    return 3*delay/2;
    } 

  return delay;
}


/*
 *
 */


void struggle_web( char_data* ch )
{
  affect_data* affect;

  for( int i = 0; ; i++ ) {
    if( i > ch->affected ) {
      bug( "Execute_Web: Entangled Character with no affect." );
      remove_bit( ch->affected_by, AFF_ENTANGLED );
      return;
      }
    if( ch->affected[i]->type == AFF_ENTANGLED ) {
      affect = ch->affected[i];
      break;
      }
    }

  if( roll_dice( 2,7 )+number_range( 0, affect->level ) < ch->Strength( ) )
    strip_affect( ch, AFF_ENTANGLED );
}


void passive_action( char_data* ch )
{
  command_data*   cmd;

  if( ch->cast != NULL ) {
    spell_update( ch );
    return;
    }

  for( ; ; ) {
    if( ( cmd = pop( ch->cmd_queue ) ) == NULL )
      break;
    assign_bit( &ch->status, STAT_ORDERED, cmd->ordered );
    interpret( ch, cmd->string );
    remove_bit( &ch->status, STAT_ORDERED );
    delete cmd;
    if( ch->link != NULL )
      ch->link->idle = 0;
    if( ch->active.time != -1 )
      return;
    }

  check_wimpy( ch );

  if( is_set( ch->affected_by, AFF_ENTANGLED ) ) {
    struggle_web( ch );
    add_queue( &ch->active, 32 );
    return;
    }

  if( ch->position < POS_STANDING
    && ( ch->fighting != NULL
    || !is_empty( ch->aggressive ) ) ) {
    jump_feet( ch );
    add_queue( &ch->active, 32 );
    }    
}


void execute_leap( event_data* event )
{
  char_data* ch      = (char_data*) event->owner;
  char_data* victim  = (char_data*) event->pointer;

  extract( event );

  if( ch->position <= POS_SLEEPING ) 
    return;

  if( ch->fighting != NULL || ch->active.time != -1 )
    return;

  ch->shown = 1;

  passive_action( ch );

  if( ch->active.time != -1 )
    return; 

  leap_message( ch, victim );

  ch->fighting = victim;
  react_attack( ch, victim );

  fight_round( ch );
}


void fight_round( char_data* ch )
{
  int time;

  ch->fighting->shown = 1;

  time = ( ch->species != NULL ? mob_round( ch, ch->fighting ) 
    : player_round( ch, ch->fighting ) );

  if( !ch->Is_Valid( ) )
    return;

  time = modify_delay( ch, time );

  if( ch->species != NULL )
    add_round( ch->species, time );

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


void next_action( event_data* event )
{
  char_data*  ch  = (char_data*) event->owner;

  if( ch->position <= POS_SLEEPING ) 
    return;

  ch->shown = 1;

  passive_action( ch );

  if( !ch->Is_Valid( ) || ch->active.time != -1 
    || ( ch->fighting == NULL && is_empty( ch->aggressive ) ) )
    return;

  if( ch->fighting != NULL ) 
    fight_round( ch );
  else
    init_attack( ch, ch->aggressive[0] );
}


/*
 *   WANDER EVENT
 */


void execute_wander( event_data* event )
{
  char_data*     ch  = (char_data*) event->owner;
  exit_data*   exit;

  if( is_set( &ch->status, STAT_ALERT ) && number_range( 0, 30 ) == 0 )
    remove_bit( &ch->status, STAT_ALERT );

  if(  ch->position == POS_STANDING
    && ch->leader == NULL
    && ( exit = random_movable_exit( ch ) ) != NULL
    && !is_set( &exit->to_room->room_flags, RFLAG_NO_MOB )
    && ( !is_set( &ch->species->act_flags, ACT_STAY_AREA )
    || exit->to_room->area == ch->in_room->area ) )
    move_char( ch, exit->direction, FALSE );

  if( ch->Is_Valid( ) ) 
    delay_wander( event );
}


void delay_wander( event_data* event )
{
  char_data*      ch  = (char_data*) event->owner;
  int         wander  = ch->species->wander;
 
  add_queue( event, number_range( wander/10, wander ) );
}


/*
 *   DROWN EVENT
 */


void execute_drown( event_data* event )
{
  char_data* ch = (char_data*) event->owner;

  if( !is_set( ch->affected_by, AFF_WATER_BREATHING ) ) {
    send( ch, "You try to breath but just swallow water.\n\r" );
    send_seen( ch, "%s is drowning!\n\r", ch );
    if( inflict( ch, NULL, 5, "drowning" ) )
      return;
    }

  add_queue( event, number_range( 50, 75 ) );
}