swr2.0/
swr2.0/area/
swr2.0/boards/
swr2.0/clans/
swr2.0/doc/
swr2.0/planets/
swr2.0/spacecraft/
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "mud.h"
#include "vector3.h"
#include "vector3_aux.h"

/* Increase this to make hyper travel faster. */
#define HYPERSPEED_MULTIPLIER 2

SHIP_DATA *first_ship = NULL;
SHIP_DATA *last_ship = NULL;

MISSILE_DATA *first_missile = NULL;
MISSILE_DATA *last_missile = NULL;

SPACE_DATA *first_starsystem = NULL;
SPACE_DATA *last_starsystem = NULL;

/* local routines */
static void handle_ship_collision( void );
static void fread_ship( SHIP_DATA * ship, FILE * fp );
static bool load_ship_file( const char *shipfile );
void write_ship_list( void );
static void fread_starsystem( SPACE_DATA * starsystem, FILE * fp );
static bool load_starsystem( const char *starsystemfile );
static void resetship( SHIP_DATA * ship );
static void landship( SHIP_DATA * ship, char *arg );
static void launchship( SHIP_DATA * ship );
static void echo_to_room_dnr( int ecolor, ROOM_INDEX_DATA * room,
    const char *argument );
static ch_ret drive_ship( CHAR_DATA * ch, SHIP_DATA * ship,
    EXIT_DATA * xit, int fall );
static bool autofly( SHIP_DATA * ship );
static void ship_untarget_all( SHIP_DATA *ship );
static void transship( SHIP_DATA *ship, int vnum );

/* from act_info.c */
bool is_online( const char *argument );

void echo_to_room_dnr( int ecolor, ROOM_INDEX_DATA * room,
    const char *argument )
{
  CHAR_DATA *vic = NULL;

  if( room == NULL )
    return;

  for( vic = room->first_person; vic; vic = vic->next_in_room )
  {
    set_char_color( ecolor, vic );
    send_to_char( argument, vic );
  }
}

bool laserfire_hits( SHIP_DATA * ship, SHIP_DATA * target, int chance )
{
  char buf[MAX_STRING_LENGTH];

  if( number_percent() > chance )
  {
    sprintf( buf, "Lasers fire from %s at you but miss.", ship->name );
    echo_to_cockpit( AT_ORANGE, target, buf );
    sprintf( buf, "The ship's lasers fire at %s but miss.", target->name );
    echo_to_cockpit( AT_ORANGE, ship, buf );
    sprintf( buf, "Laserfire from %s barely misses %s.",
	ship->name, target->name );
    echo_to_system( AT_ORANGE, ship, buf, target );
    return FALSE;
  }

  sprintf( buf, "Laserfire from %s hits %s.", ship->name, target->name );
  echo_to_system( AT_ORANGE, ship, buf, target );
  sprintf( buf, "You are hit by lasers from %s!", ship->name );
  echo_to_cockpit( AT_BLOOD, target, buf );
  sprintf( buf, "Your ship's lasers hit %s!.", target->name );
  echo_to_cockpit( AT_YELLOW, ship, buf );
  echo_to_ship( AT_RED, target,
      "A small explosion vibrates through the ship." );

  return TRUE;
}


bool missile_launcher_can_be_fired( const CHAR_DATA * ch,
    const SHIP_DATA * ship )
{
  if( ship->missilestate == MISSILE_DAMAGED )
  {
    send_to_char( "&RThe ships missile launchers are dammaged.\r\n", ch );
    return FALSE;
  }

  if( ship->missiles <= 0 )
  {
    send_to_char( "&RYou have no missiles to fire!\r\n", ch );
    return FALSE;
  }

  if( ship->missilestate != MISSILE_READY )
  {
    send_to_char( "&RThe missiles are still reloading.\r\n", ch );
    return FALSE;
  }

  if( ship->target == NULL )
  {
    send_to_char( "&RYou need to choose a target first.\r\n", ch );
    return FALSE;
  }

  return TRUE;
}

bool laser_can_be_fired( const CHAR_DATA * ch, const SHIP_DATA * ship )
{
  if( ship->laserstate == LASER_DAMAGED )
  {
    send_to_char( "&RThe ships main laser is damaged.\r\n", ch );
    return FALSE;
  }

  if( ship->laserstate >= ship->lasers )
  {
    send_to_char( "&RThe lasers are still recharging.\r\n", ch );
    return FALSE;
  }

  if( ship->target == NULL )
  {
    send_to_char( "&RYou need to choose a target first.\r\n", ch );
    return FALSE;
  }

  return TRUE;
}

bool turret_can_be_fired( const CHAR_DATA * ch, const TURRET_DATA * turret )
{
  if( turret->laserstate == LASER_DAMAGED )
  {
    send_to_char( "&RThe turret is damaged.\r\n", ch );
    return FALSE;
  }

  if( turret->laserstate > 1 )
  {
    send_to_char( "&RThe lasers are still recharging.\r\n", ch );
    return FALSE;
  }

  if( turret->target == NULL )
  {
    send_to_char( "&RYou need to choose a target first.\r\n", ch );
    return FALSE;
  }

  return TRUE;
}

void ship_acquire_target( SHIP_DATA * ship, SHIP_DATA * target )
{
  char buf[MAX_STRING_LENGTH];
  ship->target = target;
  sprintf( buf, "You are being targetted by %s.", ship->name );
  echo_to_cockpit( AT_BLOOD, target, buf );
}

int laser_hit_modifier( const SHIP_DATA * ship, const SHIP_DATA * target )
{
  int chance = 0;
  chance += target->model * 5;
  chance -= target->manuever / 10;
  chance -= target->currspeed / 20;
  chance -= ( abs( ( int ) ( target->pos.x - ship->pos.x ) ) / 70 );
  chance -= ( abs( ( int ) ( target->pos.y - ship->pos.y ) ) / 70 );
  chance -= ( abs( ( int ) ( target->pos.z - ship->pos.z ) ) / 70 );
  chance = URANGE( 10, chance, 90 );

  return chance;
}

int missile_hit_modifier( const SHIP_DATA * ship, const SHIP_DATA * target )
{
  int chance = 0;
  chance -= target->manuever / 5;
  chance -= target->currspeed / 20;
  chance += target->model * target->model * 2;
  chance -= ( abs( ( int ) ( target->pos.x - ship->pos.x ) ) / 100 );
  chance -= ( abs( ( int ) ( target->pos.y - ship->pos.y ) ) / 100 );
  chance -= ( abs( ( int ) ( target->pos.z - ship->pos.z ) ) / 100 );
  chance += ( 30 );
  chance = URANGE( 20, chance, 80 );

  return chance;
}

PLANET_DATA *find_planet_in_range( SHIP_DATA * ship, int distance )
{
  PLANET_DATA *planet = NULL;

  if( ship->starsystem )
  {
    for( planet = ship->starsystem->first_planet;
	planet; planet = planet->next_in_system )
    {
      if( ship_distance_to_planet( ship, planet ) <= distance )
      {
	break;
      }
    }
  }

  return planet;
}

SHIP_DATA *find_ship_in_range( SHIP_DATA * ship, int distance )
{
  SHIP_DATA *target = NULL;

  if( ship->starsystem )
  {
    for( target = ship->starsystem->first_ship; target;
	target = target->next_in_starsystem )
    {
      if( target != ship && ship_distance_to_ship( ship, target ) <= 500 )
      {
	break;
      }
    }
  }

  return target;
}

void ship_jump_to_lightspeed( SHIP_DATA * ship )
{
  char buf[MAX_STRING_LENGTH];
  sprintf( buf, "%s disappears from your scanner.", ship->name );
  echo_to_system( AT_YELLOW, ship, buf, NULL );

  ship_from_starsystem( ship, ship->starsystem );
  ship->shipstate = SHIP_HYPERSPACE;

  echo_to_ship( AT_YELLOW, ship,
      "The ship lurches slightly as it makes the jump to lightspeed." );
  echo_to_cockpit( AT_YELLOW, ship,
      "The stars become streaks of light as you enter hyperspace." );

  ship->energy -= ( 100 + ship->hyperdistance );
  vector_copy( &ship->pos, &ship->jump );
}

void missile_explode( MISSILE_DATA * missile )
{
  if( missile->target->chaff_released <= 0 )
  {
    SHIP_DATA *ship = missile->fired_from;
    SHIP_DATA *target = missile->target;
    char buf[MAX_STRING_LENGTH];
    CHAR_DATA *ch = NULL;
    bool ch_found = FALSE;

    echo_to_room( AT_YELLOW, ship->gunseat,
	"Your missile hits its target dead on!" );
    echo_to_cockpit( AT_BLOOD, target, "The ship is hit by a missile." );
    echo_to_ship( AT_RED, target,
	"A loud explosion shakes the ship violently!" );
    sprintf( buf, "You see a small explosion as %s is hit by a missile",
	target->name );
    echo_to_system( AT_ORANGE, target, buf, ship );

    for( ch = first_char; ch; ch = ch->next )
    {
      if( !IS_NPC( ch ) && nifty_is_name( missile->fired_by, ch->name ) )
      {
	ch_found = TRUE;
	break;
      }
    }

    damage_ship( target, 30, 50, ch_found ? ch : NULL );
    extract_missile( missile );
  }
  else
  {
    echo_to_room( AT_YELLOW, missile->fired_from->gunseat,
	"Your missile explodes harmlessly in a cloud of chaff!" );
    echo_to_cockpit( AT_YELLOW, missile->target,
	"A missile explodes in your chaff." );
    extract_missile( missile );
  }
}

void move_missiles( void )
{
  MISSILE_DATA *missile = NULL;
  MISSILE_DATA *m_next = NULL;

  for( missile = first_missile; missile; missile = m_next )
  {
    SHIP_DATA *target = missile->target;

    m_next = missile->next;

    if( target && target->starsystem
	&& target->starsystem == missile->starsystem )
    {
      missile_set_course_to_ship( missile, target );	/* home in */
      missile_move( missile );

      if( missile_distance_to_ship( missile, target ) <= 20 )
      {
	missile_explode( missile );
      }
      else
      {
	missile->age++;

	if( missile->age >= 50 )
	{
	  extract_missile( missile );
	}
      }
    }
    else
    {
      extract_missile( missile );
    }
  }
}

void ship_crash_with_star( SHIP_DATA * ship, const char *star_name )
{
  char buf[MAX_STRING_LENGTH];
  echo_to_cockpit( AT_BLOOD + AT_BLINK, ship,
      "You fly directly into the sun." );
  sprintf( buf, "%s flys directly into %s!", ship->name, star_name );
  echo_to_system( AT_ORANGE, ship, buf, NULL );
  destroy_ship( ship, NULL );
}

void ship_begin_orbit( SHIP_DATA * ship, const PLANET_DATA * planet )
{
  char buf[MAX_STRING_LENGTH];
  sprintf( buf, "You begin orbitting %s.", planet->name );
  echo_to_cockpit( AT_YELLOW, ship, buf );
  sprintf( buf, "%s begins orbiting %s.", ship->name, planet->name );
  echo_to_system( AT_ORANGE, ship, buf, NULL );
  ship->currspeed = 0;
}

void move_ships( void )
{
  SHIP_DATA *ship = NULL;
  SHIP_DATA *nextship = NULL;

  for( ship = first_ship; ship; ship = nextship )
  {
    nextship = ship->next;

    if( !ship->starsystem )
      continue;

    ship_move( ship );

    if( autofly( ship ) )
      continue;

    if( ship->starsystem->star1 && strcmp( ship->starsystem->star1, "" )
	&& vector_distance( &ship->pos,
	  &ship->starsystem->star1_pos ) < 10 )
    {
      ship_crash_with_star( ship, ship->starsystem->star1 );
      continue;
    }

    if( ship->starsystem->star2 && strcmp( ship->starsystem->star2, "" )
	&& vector_distance( &ship->pos,
	  &ship->starsystem->star2_pos ) < 10 )
    {
      ship_crash_with_star( ship, ship->starsystem->star2 );
      continue;
    }

    if( ship->currspeed > 0 )
    {
      PLANET_DATA *planet = find_planet_in_range( ship, 10 );

      if( planet )
      {
	ship_begin_orbit( ship, planet );
      }
    }
  }

  handle_ship_collision();
}

void handle_ship_collision( void )
{
  SHIP_DATA *ship = NULL;
  SHIP_DATA *nextship = NULL;

  for( ship = first_ship; ship; ship = nextship )
  {
    nextship = ship->next;

    if( ship->collision )
    {
      echo_to_cockpit( AT_WHITE + AT_BLINK, ship,
	  "You have collided with another ship!" );
      echo_to_ship( AT_RED, ship,
	  "A loud explosion shakes the ship violently!" );
      damage_ship( ship, ship->collision, ship->collision, NULL );
      ship->collision = 0;
    }
  }
}

void ship_handle_autofly_combat( SHIP_DATA * ship )
{
  int chance = 100;
  SHIP_DATA *target = ship->target;
  int shots = 0;

  for( shots = 0; shots <= ship->lasers; shots++ )
  {
    if( !ship->target )
      break;

    if( ship->shipstate != SHIP_HYPERSPACE && ship->energy > 25
	&& ship->target->starsystem == ship->starsystem
	&& ship_distance_to_ship( ship, target ) <= 1000
	&& ship->laserstate < ship->lasers )
    {
      if( ship->ship_class == SPACE_STATION
	  || ship_is_facing_ship( ship, target ) )
      {
	chance += laser_hit_modifier( ship, target );

	if( laserfire_hits( ship, target, chance ) )
	{
	  if( autofly( target ) )
	    target->target = ship;

	  damage_ship( target, 5, 10, NULL );
	}

	ship->laserstate++;
      }
    }
  }
}

void ship_reload_missiles( SHIP_DATA * ship )
{
  if( ship->missilestate == MISSILE_RELOAD_2 )
  {
    ship->missilestate = MISSILE_READY;
    if( ship->missiles > 0 )
      echo_to_room( AT_YELLOW, ship->gunseat,
	  "Missile launcher reloaded." );
  }

  if( ship->missilestate == MISSILE_RELOAD )
  {
    ship->missilestate = MISSILE_RELOAD_2;
  }

  if( ship->missilestate == MISSILE_FIRED )
    ship->missilestate = MISSILE_RELOAD;
}

void ship_update_laserstate( SHIP_DATA * ship )
{
  TURRET_DATA *turret = NULL;

  for( turret = ship->first_turret; turret; turret = turret->next )
  {
    if( turret->laserstate > 0 )
    {
      ship->energy -= turret->laserstate;
      turret->laserstate = 0;
    }
  }

  if( ship->laserstate > 0 )
  {
    ship->energy -= ship->laserstate;
    ship->laserstate = 0;
  }
}

void recharge_ships( void )
{
  SHIP_DATA *ship = NULL;
  SHIP_DATA *nextship = NULL;

  for( ship = first_ship; ship; ship = nextship )
  {
    nextship = ship->next;

    ship_update_laserstate( ship );
    ship_reload_missiles( ship );

    if( autofly( ship ) && ship->starsystem
	&& ship->target && ship->laserstate != LASER_DAMAGED )
    {
      ship_handle_autofly_combat( ship );
    }
  }
}

void ship_update_energy( SHIP_DATA * ship )
{
  if( ship->starsystem )
  {
    if( ship->energy > 0
	&& ship->shipstate == SHIP_DISABLED
	&& ship->ship_class != SPACE_STATION )
    {
      ship->energy -= 100;
    }
    else if( ship->energy > 0 )
    {
      ship->energy += 5 + ship->model * 2;
    }
    else
    {
      destroy_ship( ship, NULL );
    }
  }
}

void ship_update_shipstate( SHIP_DATA * ship )
{
  if( ship->shipstate == SHIP_BUSY_3 )
  {
    echo_to_room( AT_YELLOW, ship->pilotseat, "Manuever complete." );
    ship->shipstate = SHIP_READY;
  }

  if( ship->shipstate == SHIP_BUSY_2 )
    ship->shipstate = SHIP_BUSY_3;

  if( ship->shipstate == SHIP_BUSY )
    ship->shipstate = SHIP_BUSY_2;

  if( ship->shipstate == SHIP_LAND_2 )
    landship( ship, ship->dest );

  if( ship->shipstate == SHIP_LAND )
    ship->shipstate = SHIP_LAND_2;

  if( ship->shipstate == SHIP_LAUNCH_2 )
    launchship( ship );

  if( ship->shipstate == SHIP_LAUNCH )
    ship->shipstate = SHIP_LAUNCH_2;
}

void ship_drop_from_hyperspace( SHIP_DATA * ship )
{
  ship_to_starsystem( ship, ship->currjump );

  if( ship->starsystem == NULL )
  {
    echo_to_cockpit( AT_RED, ship,
	"Ship lost in Hyperspace. Make new calculations." );
  }
  else
  {
    char buf[MAX_STRING_LENGTH];
    echo_to_room( AT_YELLOW, ship->pilotseat, "Hyperjump complete." );
    echo_to_ship( AT_YELLOW, ship,
	"The ship lurches slightly as it comes out of hyperspace." );
    sprintf( buf, "%s enters the starsystem at %.0f %.0f %.0f",
	ship->name, ship->pos.x, ship->pos.y, ship->pos.z );
    echo_to_system( AT_YELLOW, ship, buf, NULL );
    ship->shipstate = SHIP_READY;
    STRFREE( ship->home );
    ship->home = STRALLOC( ship->starsystem->name );
  }
}

void ship_update_hyperspace( SHIP_DATA * ship )
{
  if( ship->shipstate == SHIP_HYPERSPACE )
  {
    ship->hyperdistance -= ship->hyperspeed * HYPERSPEED_MULTIPLIER;

    if( ship->hyperdistance <= 0 )
    {
      ship_drop_from_hyperspace( ship );
    }
    else
    {
      char buf[MAX_STRING_LENGTH];
      sprintf( buf, "%d", ship->hyperdistance );
      echo_to_room_dnr( AT_YELLOW, ship->pilotseat,
	  "Remaining jump distance: " );
      echo_to_room( AT_WHITE, ship->pilotseat, buf );
    }
  }
}

void ship_update_shields( SHIP_DATA * ship )
{
  ship->shield = UMAX( 0, ship->shield - 1 - ship->model / 5 );

  if( ship->autorecharge
      && ship->maxshield > ship->shield && ship->energy > 100 )
  {
    int recharge =
      UMIN( ship->maxshield - ship->shield, 10 + ship->model * 2 );
    recharge = UMIN( recharge, ship->energy - 100 );
    recharge = UMAX( 1, recharge );
    ship->shield += recharge;
    ship->energy -= recharge;
  }

  if( ship->shield > 0 )
  {
    if( ship->energy < 200 )
    {
      ship->shield = 0;
      echo_to_cockpit( AT_RED, ship,
	  "The ships shields fizzle and die." );
      ship->autorecharge = FALSE;
    }
  }
}

void ship_show_space_prompt( const SHIP_DATA * ship )
{
  if( ship->starsystem && ship->currspeed > 0 )
  {
    char buf[MAX_STRING_LENGTH];
    sprintf( buf, "%d", ship->currspeed );
    echo_to_room_dnr( AT_BLUE, ship->pilotseat, "Speed: " );
    echo_to_room_dnr( AT_LBLUE, ship->pilotseat, buf );
    sprintf( buf, "%.0f %.0f %.0f", ship->pos.x, ship->pos.y, ship->pos.z );
    echo_to_room_dnr( AT_BLUE, ship->pilotseat, "  Coords: " );
    echo_to_room( AT_LBLUE, ship->pilotseat, buf );
  }
}

void ship_echo_proximity_alert( const SHIP_DATA * ship,
    const char *target_name,
    const Vector3 * target_position )
{
  char buf[MAX_STRING_LENGTH];
  sprintf( buf, "Proximity alert: %s  %.0f %.0f %.0f", target_name,
      target_position->x, target_position->y, target_position->z );
  echo_to_room( AT_RED, ship->pilotseat, buf );
}

void ship_check_proximity( const SHIP_DATA * ship )
{
  if( ship->starsystem )
  {
    double too_close = ship->currspeed + 50;
    SHIP_DATA *target = NULL;

    for( target = ship->starsystem->first_ship; target;
	target = target->next_in_starsystem )
    {
      double target_too_close = too_close + target->currspeed;

      if( target != ship
	  && ship_distance_to_ship( ship, target ) < target_too_close )
      {
	ship_echo_proximity_alert( ship, target->name, &target->pos );
      }
    }

    too_close = ship->currspeed + 100;

    if( ship->starsystem->star1 && strcmp( ship->starsystem->star1, "" )
	&& vector_distance( &ship->pos, &ship->starsystem->star1_pos )
	< too_close )
    {
      ship_echo_proximity_alert( ship, ship->starsystem->star1,
	  &ship->starsystem->star1_pos );
    }

    if( ship->starsystem->star2 && strcmp( ship->starsystem->star2, "" )
	&& vector_distance( &ship->pos, &ship->starsystem->star2_pos )
	< too_close )
    {
      ship_echo_proximity_alert( ship, ship->starsystem->star2,
	  &ship->starsystem->star2_pos );
    }
  }
}

void ship_show_combat_prompt( SHIP_DATA * ship )
{
  if( ship->target )
  {
    char buf[MAX_STRING_LENGTH];
    sprintf( buf, "%s   %.0f %.0f %.0f", ship->target->name,
	ship->target->pos.x, ship->target->pos.y,
	ship->target->pos.z );
    echo_to_room_dnr( AT_BLUE, ship->pilotseat, "Target: " );
    echo_to_room( AT_LBLUE, ship->pilotseat, buf );

    if( ship->starsystem != ship->target->starsystem )
      ship->target = NULL;
  }
}

void ship_warn_on_low_fuel( const SHIP_DATA * ship )
{
  if( ship->energy < 100 && ship->starsystem )
  {
    echo_to_cockpit( AT_RED, ship, "Warning: Ship fuel low." );
  }
}

void ship_update_autotrack( SHIP_DATA * ship )
{
  if( ship->autotrack && ship->target && ship->ship_class < SPACE_STATION )
  {
    SHIP_DATA *target = ship->target;
    double too_close = ship->currspeed + 10;
    double target_too_close = too_close + target->currspeed;

    if( target != ship && ship->shipstate == SHIP_READY &&
	ship_distance_to_ship( ship, target ) < target_too_close )
    {
      ship_turn_180( ship );
      ship->energy -= ship->currspeed / 10;
      echo_to_room( AT_RED, ship->pilotseat,
	  "Autotrack: Evading to avoid collision!\r\n" );

      if( ship->manuever > 100 )
	ship->shipstate = SHIP_BUSY_3;
      else if( ship->manuever > 50 )
	ship->shipstate = SHIP_BUSY_2;
      else
	ship->shipstate = SHIP_BUSY;
    }
    else if( !ship_is_facing_ship( ship, ship->target ) )
    {
      ship_set_course_to_ship( ship, target );
      ship->energy -= ship->currspeed / 10;
      echo_to_room( AT_BLUE, ship->pilotseat,
	  "Autotracking target... setting new course.\r\n" );

      if( ship->manuever > 100 )
	ship->shipstate = SHIP_BUSY_3;
      else if( ship->manuever > 50 )
	ship->shipstate = SHIP_BUSY_2;
      else
	ship->shipstate = SHIP_BUSY;
    }
  }
}

void spacestation_regenerate_missiles( SHIP_DATA * ship )
{
  if( ship->ship_class == SPACE_STATION && ship->target == NULL )
  {
    if( ship->missiles < ship->maxmissiles )
      ship->missiles++;
  }
}

void ship_respawn_mob_ship( SHIP_DATA * ship )
{
  if( ( ship->ship_class == SPACE_STATION
	|| ship->type == MOB_SHIP ) && ship->home )
  {
    /* 4% chance of respawning mob ship or space station. */
    if( number_range( 1, 25 ) == 25 )
    {
      ship_to_starsystem( ship, starsystem_from_name( ship->home ) );
      vector_init( &ship->pos );
      vector_randomize( &ship->pos, -5000, 5000 );
      vector_set( &ship->head, 1, 1, 1 );
      ship->autopilot = TRUE;
    }
  }
}

void ship_handle_autoflying_clanship( SHIP_DATA * ship, CLAN_DATA * clan )
{
  SHIP_DATA *target = NULL;

  for( target = ship->starsystem->first_ship; target;
      target = target->next_in_starsystem )
  {
    int targetok = 0;
    ROOM_INDEX_DATA *room = NULL;
    char buf[MAX_STRING_LENGTH];

    if( autofly( target ) && !str_cmp( ship->owner, target->owner ) )
    {
      targetok = 1;
    }

    for( room = target->first_room; room; room = room->next_in_ship )
    {
      CHAR_DATA *passenger = NULL;

      for( passenger = room->first_person; passenger;
	  passenger = passenger->next_in_room )
      {
	if( !IS_NPC( passenger ) && passenger->pcdata )
	{
	  if( passenger->pcdata->clan == clan )
	  {
	    targetok = 1;
	  }
	  else if( passenger->pcdata->clan
	      && passenger->pcdata->clan != clan
	      && targetok == 0 )
	  {
	    if( nifty_is_name( passenger->pcdata->clan->name,
		  clan->atwar ) )
	    {
	      targetok = -1;
	    }
	  }
	}
      }
    }

    if( targetok == 1 && target->target )
    {
      ship_acquire_target( ship, target->target );
      break;
    }

    if( targetok == 0 && target->target )
    {
      if( !str_cmp( target->target->owner, clan->name ) )
      {
	targetok = -1;
      }
      else if( nifty_is_name( target->owner, clan->atwar ) )
      {
	targetok = -1;
      }
      else
      {
	for( room = target->target->first_room; room;
	    room = room->next_in_ship )
	{
	  CHAR_DATA *passenger = NULL;

	  for( passenger = room->first_person;
	      passenger; passenger = passenger->next_in_room )
	  {
	    if( !IS_NPC( passenger )
		&& passenger->pcdata
		&& passenger->pcdata->clan == clan )
	    {
	      targetok = -1;
	    }
	  }
	}
      }
    }

    if( targetok >= 0 )
      continue;

    sprintf( buf, "You are being scanned by %s.", ship->name );
    echo_to_cockpit( AT_WHITE, target, buf );
    ship_acquire_target( ship, target );
    break;
  }
}

void ship_fire_missile( SHIP_DATA * ship, SHIP_DATA * target )
{
  char buf[MAX_STRING_LENGTH];
  new_missile( ship, target, NULL );
  ship->missiles--;
  sprintf( buf, "Incoming missile from %s.", ship->name );
  echo_to_cockpit( AT_BLOOD, target, buf );
  sprintf( buf, "%s fires a missile towards %s.", ship->name, target->name );
  echo_to_system( AT_ORANGE, target, buf, NULL );

  if( ship->ship_class == SPACE_STATION )
    ship->missilestate = MISSILE_RELOAD_2;
  else
    ship->missilestate = MISSILE_FIRED;
}

void ship_handle_autoflying_has_target( SHIP_DATA * ship )
{
  SHIP_DATA *target = ship->target;
  ship->autotrack = TRUE;

  if( ship->ship_class != SPACE_STATION )
    ship->currspeed = ship->realspeed;

  if( ship->energy > 200 )
    ship->autorecharge = TRUE;

  if( ship->shipstate != SHIP_HYPERSPACE
      && ship->energy > 200
      && ship->hyperspeed > 0
      && ship->target->starsystem == ship->starsystem
      && ship_distance_to_ship( ship, target ) > 5000
      && number_bits( 2 ) == 0 )
  {
    ship->currjump = ship->starsystem;
    ship->hyperdistance = 1;

    ship_jump_to_lightspeed( ship );
  }

  if( ship->shipstate != SHIP_HYPERSPACE && ship->energy > 25
      && ship->missilestate == MISSILE_READY
      && ship->target->starsystem == ship->starsystem
      && ship_distance_to_ship( ship, target ) <= 1200 && ship->missiles > 0 )
  {
    if( ship->ship_class == SPACE_STATION
	|| ship_is_facing_ship( ship, target ) )
    {
      int chance = 100 + missile_hit_modifier( ship, target );

      if( number_percent() > chance )
      {

      }
      else
      {
	ship_fire_missile( ship, target );
      }
    }
  }

  if( ship->missilestate == MISSILE_DAMAGED )
    ship->missilestate = MISSILE_READY;

  if( ship->laserstate == LASER_DAMAGED )
    ship->laserstate = LASER_READY;

  if( ship->shipstate == SHIP_DISABLED )
    ship->shipstate = SHIP_READY;
}

void ship_handle_autoflying( SHIP_DATA * ship )
{
  if( autofly( ship ) )
  {
    if( ship->starsystem )
    {
      if( ship->target )
      {
	ship_handle_autoflying_has_target( ship );
      }
      else
      {
	CLAN_DATA *clan = NULL;
	CLAN_DATA *shipclan = NULL;

	ship->currspeed = 0;

	for( clan = first_clan; clan; clan = clan->next )
	  if( !str_cmp( ship->owner, clan->name ) )
	    shipclan = clan;

	if( shipclan )
	{
	  ship_handle_autoflying_clanship( ship, shipclan );
	}
      }
    }
    else
    {
      ship_respawn_mob_ship( ship );
    }
  }
}

void update_space( void )
{
  SHIP_DATA *ship = 0;
  SHIP_DATA *nextship = 0;

  for( ship = first_ship; ship; ship = nextship )
  {
    nextship = ship->next;

    ship_update_energy( ship );

    if( ship->chaff_released > 0 )
      ship->chaff_released = FALSE;

    ship_update_hyperspace( ship );
    ship_update_shipstate( ship );
    ship_update_shields( ship );
    ship_show_space_prompt( ship );
    ship_check_proximity( ship );
    ship_show_combat_prompt( ship );
    ship_warn_on_low_fuel( ship );

    ship->energy = URANGE( 0, ship->energy, ship->maxenergy );
  }

  for( ship = first_ship; ship; ship = ship->next )
  {
    ship_update_autotrack( ship );
    ship_handle_autoflying( ship );
    spacestation_regenerate_missiles( ship );
  }
}

void write_starsystem_list( void )
{
  SPACE_DATA *tstarsystem = NULL;
  FILE *fpout = NULL;
  char filename[256];

  sprintf( filename, "%s%s", SPACE_DIR, SPACE_LIST );
  fpout = fopen( filename, "w" );

  if( !fpout )
  {
    bug( "FATAL: cannot open starsystem.lst for writing!\r\n", 0 );
    return;
  }

  for( tstarsystem = first_starsystem; tstarsystem;
      tstarsystem = tstarsystem->next )
    fprintf( fpout, "%s\n", tstarsystem->filename );

  fprintf( fpout, "$\n" );
  fclose( fpout );
}


/*
 * Get pointer to space structure from starsystem name.
 */
SPACE_DATA *starsystem_from_name( const char *name )
{
  SPACE_DATA *starsystem = NULL;

  for( starsystem = first_starsystem; starsystem;
      starsystem = starsystem->next )
    if( !str_cmp( name, starsystem->name ) )
      return starsystem;

  for( starsystem = first_starsystem; starsystem;
      starsystem = starsystem->next )
    if( !str_prefix( name, starsystem->name ) )
      return starsystem;

  return NULL;
}

/*
 * Get pointer to space structure from the dock vnun.
 */
SPACE_DATA *starsystem_from_room( const ROOM_INDEX_DATA * room )
{
  SHIP_DATA *ship = NULL;
  ROOM_INDEX_DATA *sRoom = NULL;

  if( room == NULL )
    return NULL;

  if( room->area != NULL && room->area->planet != NULL )
    return room->area->planet->starsystem;

  for( ship = first_ship; ship; ship = ship->next )
  {
    for( sRoom = ship->first_room; sRoom; sRoom = sRoom->next_in_ship )
    {
      if( room == sRoom )
      {
	return ship->starsystem;
      }
    }
  }

  return NULL;
}


/*
 * Save a starsystem's data to its data file
 */
void save_starsystem( const SPACE_DATA * starsystem )
{
  FILE *fp = NULL;
  char filename[256];

  if( !starsystem )
  {
    bug( "save_starsystem: null starsystem pointer!", 0 );
    return;
  }

  if( !starsystem->filename || starsystem->filename[0] == '\0' )
  {
    bug( "save_starsystem: %s has no filename", starsystem->name );
    return;
  }

  sprintf( filename, "%s%s", SPACE_DIR, starsystem->filename );

  if( ( fp = fopen( filename, "w" ) ) == NULL )
  {
    bug( "save_starsystem: fopen", 0 );
    perror( filename );
  }
  else
  {
    fprintf( fp, "#SPACE\n" );
    fprintf( fp, "Name         %s~\n", starsystem->name );
    fprintf( fp, "Filename     %s~\n", starsystem->filename );
    fprintf( fp, "Star1        %s~\n", starsystem->star1 );
    fprintf( fp, "Star2        %s~\n", starsystem->star2 );
    fprintf( fp, "S1x          %.0f\n", starsystem->star1_pos.x );
    fprintf( fp, "S1y          %.0f\n", starsystem->star1_pos.y );
    fprintf( fp, "S1z          %.0f\n", starsystem->star1_pos.z );
    fprintf( fp, "S2x          %.0f\n", starsystem->star2_pos.x );
    fprintf( fp, "S2y          %.0f\n", starsystem->star2_pos.y );
    fprintf( fp, "S2z          %.0f\n", starsystem->star2_pos.z );
    fprintf( fp, "End\n\n" );
    fprintf( fp, "#END\n" );
  }

  fclose( fp );
}

/*
 * Read in actual starsystem data.
 */
void fread_starsystem( SPACE_DATA * starsystem, FILE * fp )
{
  char buf[MAX_STRING_LENGTH];
  bool fMatch = FALSE;

  for( ;; )
  {
    const char *word = feof( fp ) ? "End" : fread_word( fp );
    fMatch = FALSE;

    switch ( UPPER( word[0] ) )
    {
      case '*':
	fMatch = TRUE;
	fread_to_eol( fp );
	break;

      case 'E':
	if( !str_cmp( word, "End" ) )
	{
	  if( !starsystem->name )
	    starsystem->name = STRALLOC( "" );
	  if( !starsystem->star1 )
	    starsystem->star1 = STRALLOC( "" );
	  if( !starsystem->star2 )
	    starsystem->star2 = STRALLOC( "" );
	  return;
	}
	break;

      case 'F':
	KEY( "Filename", starsystem->filename, fread_string( fp ) );
	break;

      case 'N':
	KEY( "Name", starsystem->name, fread_string( fp ) );
	break;

      case 'S':
	KEY( "Star1", starsystem->star1, fread_string( fp ) );
	KEY( "Star2", starsystem->star2, fread_string( fp ) );
	KEY( "S1x", starsystem->star1_pos.x, fread_number( fp ) );
	KEY( "S1y", starsystem->star1_pos.y, fread_number( fp ) );
	KEY( "S1z", starsystem->star1_pos.z, fread_number( fp ) );
	KEY( "S2x", starsystem->star2_pos.x, fread_number( fp ) );
	KEY( "S2y", starsystem->star2_pos.y, fread_number( fp ) );
	KEY( "S2z", starsystem->star2_pos.z, fread_number( fp ) );
    }

    if( !fMatch )
    {
      sprintf( buf, "Fread_starsystem: no match: %s", word );
      bug( buf, 0 );
    }
  }
}

/*
 * Load a starsystem file
 */

SPACE_DATA *starsystem_create( void )
{
  SPACE_DATA *starsystem = NULL;

  CREATE( starsystem, SPACE_DATA, 1 );

  starsystem->next = NULL;
  starsystem->prev = NULL;
  starsystem->first_planet = NULL;
  starsystem->last_planet = NULL;
  starsystem->first_ship = NULL;
  starsystem->last_ship = NULL;
  starsystem->first_missile = NULL;
  starsystem->last_missile = NULL;
  starsystem->filename = NULL;
  starsystem->name = NULL;
  starsystem->star1 = NULL;
  starsystem->star2 = NULL;
  vector_init( &starsystem->star1_pos );
  vector_init( &starsystem->star2_pos );
  starsystem->crash = 0;

  return starsystem;
}

bool load_starsystem( const char *starsystemfile )
{
  char filename[256];
  FILE *fp = NULL;
  bool found = FALSE;

  sprintf( filename, "%s%s", SPACE_DIR, starsystemfile );

  if( ( fp = fopen( filename, "r" ) ) != NULL )
  {
    SPACE_DATA *starsystem = starsystem_create();
    LINK( starsystem, first_starsystem, last_starsystem, next, prev );
    found = TRUE;

    for( ;; )
    {
      const char *word = NULL;
      char letter = fread_letter( fp );

      if( letter == '*' )
      {
	fread_to_eol( fp );
	continue;
      }

      if( letter != '#' )
      {
	bug( "Load_starsystem_file: # not found.", 0 );
	break;
      }

      word = fread_word( fp );

      if( !str_cmp( word, "SPACE" ) )
      {
	fread_starsystem( starsystem, fp );
	break;
      }
      else if( !str_cmp( word, "END" ) )
      {
	break;
      }
      else
      {
	char buf[MAX_STRING_LENGTH];

	sprintf( buf, "Load_starsystem_file: bad section: %s.", word );
	bug( buf, 0 );
	break;
      }
    }

    fclose( fp );
  }

  return found;
}

/*
 * Load in all the starsystem files.
 */
void load_space( void )
{
  FILE *fpList = NULL;
  char starsystemlist[256];

  sprintf( starsystemlist, "%s%s", SPACE_DIR, SPACE_LIST );

  if( ( fpList = fopen( starsystemlist, "r" ) ) == NULL )
  {
    perror( starsystemlist );
    exit( 1 );
  }

  for( ;; )
  {
    const char *filename = feof( fpList ) ? "$" : fread_word( fpList );

    if( filename[0] == '$' )
      break;

    if( !load_starsystem( filename ) )
    {
      bug( "Cannot load starsystem file: %s", filename );
    }
  }

  fclose( fpList );
}

void do_setstarsystem( CHAR_DATA * ch, char *argument )
{
  char arg1[MAX_INPUT_LENGTH];
  char arg2[MAX_INPUT_LENGTH];
  SPACE_DATA *starsystem;

  if( IS_NPC( ch ) )
  {
    send_to_char( "Huh?\r\n", ch );
    return;
  }

  argument = one_argument( argument, arg1 );
  argument = one_argument( argument, arg2 );

  if( arg2[0] == '\0' || arg1[0] == '\0' )
  {
    send_to_char( "Usage: setstarsystem <starsystem> <field> <values>\r\n",
	ch );
    send_to_char( "\r\nField being one of:\r\n", ch );
    send_to_char( "name filename\r\n", ch );
    send_to_char( "star1 s1x s1y s1z\r\n", ch );
    send_to_char( "star2 s2x s2y s2z\r\n", ch );
    send_to_char( "", ch );
    return;
  }

  starsystem = starsystem_from_name( arg1 );
  if( !starsystem )
  {
    send_to_char( "No such starsystem.\r\n", ch );
    return;
  }

  if( !str_cmp( arg2, "s1x" ) )
  {
    starsystem->star1_pos.x = atoi( argument );
    send_to_char( "Done.\r\n", ch );
    save_starsystem( starsystem );
    return;
  }
  if( !str_cmp( arg2, "s1y" ) )
  {
    starsystem->star1_pos.y = atoi( argument );
    send_to_char( "Done.\r\n", ch );
    save_starsystem( starsystem );
    return;
  }
  if( !str_cmp( arg2, "s1z" ) )
  {
    starsystem->star1_pos.z = atoi( argument );
    send_to_char( "Done.\r\n", ch );
    save_starsystem( starsystem );
    return;
  }

  if( !str_cmp( arg2, "s2x" ) )
  {
    starsystem->star2_pos.x = atoi( argument );
    send_to_char( "Done.\r\n", ch );
    save_starsystem( starsystem );
    return;
  }
  if( !str_cmp( arg2, "s2y" ) )
  {
    starsystem->star2_pos.y = atoi( argument );
    send_to_char( "Done.\r\n", ch );
    save_starsystem( starsystem );
    return;
  }
  if( !str_cmp( arg2, "s2z" ) )
  {
    starsystem->star2_pos.z = atoi( argument );
    send_to_char( "Done.\r\n", ch );
    save_starsystem( starsystem );
    return;
  }


  if( !str_cmp( arg2, "name" ) )
  {
    if( *argument == '\0' )
    {
      ch_printf( ch, "You must choose a name.\r\n" );
      return;
    }

    if( starsystem_from_name( argument ) )
    {
      ch_printf( ch, "A starsystem with that name already exists.\r\n" );
      return;
    }

    STRFREE( starsystem->name );
    starsystem->name = STRALLOC( argument );
    send_to_char( "Done.\r\n", ch );
    save_starsystem( starsystem );
    return;
  }

  if( !str_cmp( arg2, "star1" ) )
  {
    STRFREE( starsystem->star1 );
    starsystem->star1 = STRALLOC( argument );
    send_to_char( "Done.\r\n", ch );
    save_starsystem( starsystem );
    return;
  }

  if( !str_cmp( arg2, "star2" ) )
  {
    STRFREE( starsystem->star2 );
    starsystem->star2 = STRALLOC( argument );
    send_to_char( "Done.\r\n", ch );
    save_starsystem( starsystem );
    return;
  }

  do_setstarsystem( ch, STRLIT_EMPTY );
}

void showstarsystem( const CHAR_DATA * ch, const SPACE_DATA * starsystem )
{
  PLANET_DATA *planet;

  ch_printf( ch, "Starsystem:%s     Filename: %s\r\n",
      starsystem->name, starsystem->filename );
  ch_printf( ch, "Star1: %s   Coordinates: %.0f %.0f %.0f\r\n",
      starsystem->star1,
      starsystem->star1_pos.x,
      starsystem->star1_pos.y, starsystem->star1_pos.z );
  ch_printf( ch, "Star2: %s   Coordinates: %.0f %.0f %.0f\r\n",
      starsystem->star2,
      starsystem->star2_pos.x,
      starsystem->star2_pos.y, starsystem->star2_pos.z );
  for( planet = starsystem->first_planet; planet;
      planet = planet->next_in_system )
    ch_printf( ch, "Planet: %s   Coordinates: %.0f %.0f %.0f\r\n",
	planet->name, planet->pos.x, planet->pos.y, planet->pos.z );
  return;
}

void do_showstarsystem( CHAR_DATA * ch, char *argument )
{
  SPACE_DATA *starsystem;

  starsystem = starsystem_from_name( argument );

  if( starsystem == NULL )
    send_to_char( "&RNo such starsystem.\r\n", ch );
  else
    showstarsystem( ch, starsystem );

}

void do_starsystems( CHAR_DATA * ch, char *argument )
{
  SPACE_DATA *starsystem;
  int count = 0;

  for( starsystem = first_starsystem; starsystem;
      starsystem = starsystem->next )
  {
    set_char_color( AT_NOTE, ch );
    ch_printf( ch, "%s\r\n", starsystem->name );
    count++;
  }

  if( !count )
  {
    send_to_char( "There are no starsystems currently formed.\r\n", ch );
    return;
  }
}

void echo_to_ship( int color, const SHIP_DATA * ship, const char *argument )
{
  ROOM_INDEX_DATA *room;

  for( room = ship->first_room; room; room = room->next_in_ship )
    echo_to_room( color, room, argument );

}

void echo_to_cockpit( int color, const SHIP_DATA * ship,
    const char *argument )
{
  TURRET_DATA *turret;

  echo_to_room( color, ship->pilotseat, argument );

  if( ship->pilotseat != ship->gunseat )
    echo_to_room( color, ship->gunseat, argument );

  if( ship->pilotseat != ship->viewscreen
      && ship->viewscreen != ship->gunseat )
    echo_to_room( color, ship->viewscreen, argument );

  for( turret = ship->first_turret; turret; turret = turret->next )
    if( turret->room )
      echo_to_room( color, turret->room, argument );
}

void echo_to_system( int color, const SHIP_DATA * ship,
    const char *argument, const SHIP_DATA * ignore )
{
  SHIP_DATA *target = NULL;

  if( !ship->starsystem )
    return;

  for( target = ship->starsystem->first_ship; target;
      target = target->next_in_starsystem )
  {
    if( target != ship && target != ignore )
      echo_to_cockpit( color, target, argument );
  }
}

void write_ship_list()
{
  SHIP_DATA *tship = NULL;
  FILE *fpout = NULL;
  char filename[256];

  sprintf( filename, "%s%s", SHIP_DIR, SHIP_LIST );
  fpout = fopen( filename, "w" );

  if( !fpout )
  {
    bug( "FATAL: cannot open ship.lst for writing!\r\n", 0 );
    return;
  }

  for( tship = first_ship; tship; tship = tship->next )
    if( tship->type != MOB_SHIP && tship->owner && tship->owner[0] != '\0' )
      fprintf( fpout, "%s\n", tship->filename );

  fprintf( fpout, "$\n" );
  fclose( fpout );
}

SHIP_DATA *ship_in_room( const ROOM_INDEX_DATA * room, const char *name )
{
  SHIP_DATA *ship = NULL;

  if( !room )
    return NULL;

  for( ship = room->first_ship; ship; ship = ship->next_in_room )
    if( !str_cmp( name, ship->name ) )
      if( ship->owner && ship->owner[0] != '\0' )
	if( get_clan( ship->owner ) || is_online( ship->owner )
	    || is_online( ship->pilot ) || is_online( ship->copilot ) )
	  return ship;

  for( ship = room->first_ship; ship; ship = ship->next_in_room )
    if( nifty_is_name( name, ship->name ) )
      if( ship->owner && ship->owner[0] != '\0' )
	if( get_clan( ship->owner ) || is_online( ship->owner )
	    || is_online( ship->pilot ) || is_online( ship->copilot ) )
	  return ship;

  for( ship = room->first_ship; ship; ship = ship->next_in_room )
    if( !str_prefix( name, ship->name ) )
      if( ship->owner && ship->owner[0] != '\0' )
	if( get_clan( ship->owner ) || is_online( ship->owner )
	    || is_online( ship->pilot ) || is_online( ship->copilot ) )
	  return ship;

  for( ship = room->first_ship; ship; ship = ship->next_in_room )
    if( nifty_is_name_prefix( name, ship->name ) )
      if( ship->owner && ship->owner[0] != '\0' )
	if( get_clan( ship->owner ) || is_online( ship->owner )
	    || is_online( ship->pilot ) || is_online( ship->copilot ) )
	  return ship;

  return NULL;
}

/*
 * Get pointer to ship structure from ship name.
 */
SHIP_DATA *get_ship( const char *name )
{
  SHIP_DATA *ship = NULL;

  for( ship = first_ship; ship; ship = ship->next )
    if( !str_cmp( name, ship->name ) )
      return ship;

  for( ship = first_ship; ship; ship = ship->next )
    if( nifty_is_name( name, ship->name ) )
      return ship;

  for( ship = first_ship; ship; ship = ship->next )
    if( !str_prefix( name, ship->name ) )
      return ship;

  for( ship = first_ship; ship; ship = ship->next )
    if( nifty_is_name_prefix( name, ship->name ) )
      return ship;

  return NULL;
}

/*
 * Checks if ships in a starsystem and returns poiner if it is.
 */
SHIP_DATA *get_ship_here( const char *name, const SPACE_DATA * starsystem )
{
  SHIP_DATA *ship = NULL;

  if( starsystem == NULL )
    return NULL;

  for( ship = starsystem->first_ship; ship; ship = ship->next_in_starsystem )
    if( !str_cmp( name, ship->name ) )
      return ship;

  for( ship = starsystem->first_ship; ship; ship = ship->next_in_starsystem )
    if( nifty_is_name( name, ship->name ) )
      return ship;

  for( ship = starsystem->first_ship; ship; ship = ship->next_in_starsystem )
    if( !str_prefix( name, ship->name ) )
      return ship;

  for( ship = starsystem->first_ship; ship; ship = ship->next_in_starsystem )
    if( nifty_is_name_prefix( name, ship->name ) )
      return ship;

  return NULL;
}


SHIP_DATA *ship_from_pilot( const char *name )
{
  SHIP_DATA *ship = NULL;

  for( ship = first_ship; ship; ship = ship->next )
    if( !str_cmp( name, ship->pilot ) )
      return ship;
  if( !str_cmp( name, ship->copilot ) )
    return ship;
  if( !str_cmp( name, ship->owner ) )
    return ship;

  return NULL;
}


/*
 * Get pointer to ship structure from cockpit, or entrance ramp vnum.
 */

SHIP_DATA *ship_from_room( const ROOM_INDEX_DATA * room )
{
  SHIP_DATA *ship = NULL;
  ROOM_INDEX_DATA *sRoom = NULL;

  if( room == NULL )
    return NULL;

  for( ship = first_ship; ship; ship = ship->next )
    for( sRoom = ship->first_room; sRoom; sRoom = sRoom->next_in_ship )
      if( room == sRoom )
	return ship;

  return NULL;
}

SHIP_DATA *ship_from_cockpit( const ROOM_INDEX_DATA * room )
{
  SHIP_DATA *ship = NULL;
  TURRET_DATA *turret = NULL;

  if( room == NULL )
    return NULL;

  for( ship = first_ship; ship; ship = ship->next )
  {
    if( room == ship->pilotseat )
      return ship;
    if( room == ship->gunseat )
      return ship;
    if( room == ship->viewscreen )
      return ship;
    for( turret = ship->first_turret; turret; turret = turret->next )
      if( room == turret->room )
	return ship;
  }

  return NULL;
}

SHIP_DATA *ship_from_pilotseat( const ROOM_INDEX_DATA * room )
{
  SHIP_DATA *ship = NULL;

  if( room == NULL )
    return NULL;

  for( ship = first_ship; ship; ship = ship->next )
    if( room == ship->pilotseat )
      return ship;

  return NULL;
}

SHIP_DATA *ship_from_gunseat( const ROOM_INDEX_DATA * room )
{
  SHIP_DATA *ship;

  if( room == NULL )
    return NULL;

  for( ship = first_ship; ship; ship = ship->next )
    if( room == ship->gunseat )
      return ship;

  return NULL;
}

SHIP_DATA *ship_from_entrance( const ROOM_INDEX_DATA * room )
{
  SHIP_DATA *ship;

  if( room == NULL )
    return NULL;

  for( ship = first_ship; ship; ship = ship->next )
    if( room == ship->entrance )
      return ship;

  return NULL;
}

SHIP_DATA *ship_from_engine( const ROOM_INDEX_DATA * room )
{
  SHIP_DATA *ship;

  if( room == NULL )
    return NULL;

  for( ship = first_ship; ship; ship = ship->next )
    if( room == ship->engine )
      return ship;

  return NULL;
}

SHIP_DATA *ship_from_turret( const ROOM_INDEX_DATA * room )
{
  SHIP_DATA *ship;
  TURRET_DATA *turret;

  if( room == NULL )
    return NULL;

  for( ship = first_ship; ship; ship = ship->next )
  {
    if( room == ship->gunseat )
      return ship;
    for( turret = ship->first_turret; turret; turret = turret->next )
      if( room == turret->room )
	return ship;
  }

  return NULL;
}

void save_ship( const SHIP_DATA * ship )
{
  FILE *fp;
  char filename[256];
  char buf[MAX_STRING_LENGTH];
  ROOM_INDEX_DATA *room;

  if( !ship )
  {
    bug( "save_ship: null ship pointer!", 0 );
    return;
  }

  if( ship->type == MOB_SHIP )
    return;

  if( !ship->filename || ship->filename[0] == '\0' )
  {
    sprintf( buf, "save_ship: %s has no filename", ship->name );
    bug( buf, 0 );
    return;
  }

  sprintf( filename, "%s%s", SHIP_DIR, ship->filename );

  if( ( fp = fopen( filename, "w" ) ) == NULL )
  {
    bug( "save_ship: fopen", 0 );
    perror( filename );
  }
  else
  {
    fprintf( fp, "#SHIP\n" );
    fprintf( fp, "Name         %s~\n", ship->name );
    fprintf( fp, "Filename     %s~\n", ship->filename );
    for( room = ship->first_room; room; room = room->next_in_ship )
      fprintf( fp, "Description  %s~\n", room->description );
    fprintf( fp, "Owner        %s~\n", ship->owner );
    fprintf( fp, "Pilot        %s~\n", ship->pilot );
    fprintf( fp, "Copilot      %s~\n", ship->copilot );
    fprintf( fp, "Model        %d\n", ship->model );
    fprintf( fp, "Class        %d\n", ship->ship_class );
    fprintf( fp, "Tractorbeam  %d\n", ship->tractorbeam );
    fprintf( fp, "Shipyard     %d\n", ship->shipyard );
    fprintf( fp, "Laserstate   %d\n", ship->laserstate );
    fprintf( fp, "Lasers       %d\n", ship->lasers );
    fprintf( fp, "Missiles     %d\n", ship->missiles );
    fprintf( fp, "Maxmissiles  %d\n", ship->maxmissiles );
    fprintf( fp, "Lastdoc      %d\n", ship->lastdoc );
    fprintf( fp, "Shield       %d\n", ship->shield );
    fprintf( fp, "Maxshield    %d\n", ship->maxshield );
    fprintf( fp, "Hull         %d\n", ship->hull );
    fprintf( fp, "Maxhull      %d\n", ship->maxhull );
    fprintf( fp, "Maxenergy    %d\n", ship->maxenergy );
    fprintf( fp, "Hyperspeed   %d\n", ship->hyperspeed );
    fprintf( fp, "Chaff        %d\n", ship->chaff );
    fprintf( fp, "Maxchaff     %d\n", ship->maxchaff );
    fprintf( fp, "Realspeed    %d\n", ship->realspeed );
    fprintf( fp, "Type         %d\n", ship->type );
    fprintf( fp, "Shipstate    %d\n", ship->shipstate );
    fprintf( fp, "Missilestate %d\n", ship->missilestate );
    fprintf( fp, "Energy       %d\n", ship->energy );
    fprintf( fp, "Manuever     %d\n", ship->manuever );
    fprintf( fp, "Home         %s~\n", ship->home );
    fprintf( fp, "End\n\n" );
    fprintf( fp, "#END\n" );
  }
  fclose( fp );
}


/*
 * Read in actual ship data.
 */
void fread_ship( SHIP_DATA * ship, FILE * fp )
{
  bool fMatch = FALSE;
  int dIndex = 0;

  for( ;; )
  {
    const char *word = feof( fp ) ? "End" : fread_word( fp );
    fMatch = FALSE;

    switch ( UPPER( word[0] ) )
    {
      case '*':
	fMatch = TRUE;
	fread_to_eol( fp );
	break;

      case 'C':
	KEY( "Class", ship->ship_class, fread_number( fp ) );
	KEY( "Copilot", ship->copilot, fread_string( fp ) );
	KEY( "Chaff", ship->chaff, fread_number( fp ) );
	break;

      case 'D':
	if( dIndex < MAX_SHIP_ROOMS )
	  KEY( "Description", ship->description[dIndex++],
	      fread_string( fp ) );
	break;

      case 'E':
	KEY( "Energy", ship->energy, fread_number( fp ) );
	if( !str_cmp( word, "End" ) )
	{
	  if( !ship->home )
	    ship->home = STRALLOC( "" );
	  if( !ship->name )
	    ship->name = STRALLOC( "" );
	  if( !ship->owner )
	    ship->owner = STRALLOC( "" );
	  if( !ship->copilot )
	    ship->copilot = STRALLOC( "" );
	  if( !ship->pilot )
	    ship->pilot = STRALLOC( "" );
	  if( ship->shipstate != SHIP_DISABLED )
	    ship->shipstate = SHIP_DOCKED;
	  if( ship->laserstate != LASER_DAMAGED )
	    ship->laserstate = LASER_READY;
	  if( ship->missilestate != MISSILE_DAMAGED )
	    ship->missilestate = MISSILE_READY;
	  if( ship->shipyard <= 0 )
	    ship->shipyard = ROOM_LIMBO_SHIPYARD;
	  if( ship->lastdoc <= 0 )
	    ship->lastdoc = ship->shipyard;

	  ship->autopilot = FALSE;
	  ship->hatchopen = FALSE;
	  ship->starsystem = NULL;
	  ship->energy = ship->maxenergy;
	  ship->hull = ship->maxhull;
	  ship->in_room = NULL;
	  ship->next_in_room = NULL;
	  ship->prev_in_room = NULL;
	  ship->first_turret = NULL;
	  ship->last_turret = NULL;
	  ship->first_hangar = NULL;
	  ship->last_hangar = NULL;
	  create_ship_rooms( ship );
	  return;
	}
	break;

      case 'F':
	KEY( "Filename", ship->filename, fread_string_nohash( fp ) );
	break;

      case 'H':
	KEY( "Home", ship->home, fread_string( fp ) );
	KEY( "Hyperspeed", ship->hyperspeed, fread_number( fp ) );
	KEY( "Hull", ship->hull, fread_number( fp ) );
	break;

      case 'L':
	KEY( "Lasers", ship->lasers, fread_number( fp ) );
	KEY( "Laserstate", ship->lasers, fread_number( fp ) );
	KEY( "Lastdoc", ship->lastdoc, fread_number( fp ) );
	break;

      case 'M':
	KEY( "Model", ship->model, fread_number( fp ) );
	KEY( "Manuever", ship->manuever, fread_number( fp ) );
	KEY( "Maxmissiles", ship->maxmissiles, fread_number( fp ) );
	KEY( "Missiles", ship->missiles, fread_number( fp ) );
	KEY( "Maxshield", ship->maxshield, fread_number( fp ) );
	KEY( "Maxenergy", ship->maxenergy, fread_number( fp ) );
	KEY( "Missilestate", ship->missilestate, fread_number( fp ) );
	KEY( "Maxhull", ship->maxhull, fread_number( fp ) );
	KEY( "Maxchaff", ship->maxchaff, fread_number( fp ) );
	break;

      case 'N':
	KEY( "Name", ship->name, fread_string( fp ) );
	break;

      case 'O':
	KEY( "Owner", ship->owner, fread_string( fp ) );
	break;

      case 'P':
	KEY( "Pilot", ship->pilot, fread_string( fp ) );
	break;

      case 'R':
	KEY( "Realspeed", ship->realspeed, fread_number( fp ) );
	break;

      case 'S':
	KEY( "Shipyard", ship->shipyard, fread_number( fp ) );
	KEY( "Shield", ship->shield, fread_number( fp ) );
	KEY( "Shipstate", ship->shipstate, fread_number( fp ) );
	break;

      case 'T':
	KEY( "Type", ship->type, fread_number( fp ) );
	KEY( "Tractorbeam", ship->tractorbeam, fread_number( fp ) );
	break;
    }

    if( !fMatch )
    {
      bug( "Fread_ship: no match: %s", word );
    }
  }
}

/*
 * Load a ship file
 */

bool load_ship_file( const char *shipfile )
{
  char filename[256];
  SHIP_DATA *ship = ship_create();
  FILE *fp = NULL;
  bool found = FALSE;
  CLAN_DATA *clan = NULL;

  sprintf( filename, "%s%s", SHIP_DIR, shipfile );

  if( ( fp = fopen( filename, "r" ) ) != NULL )
  {
    found = TRUE;

    for( ;; )
    {
      const char *word;
      char letter = fread_letter( fp );

      if( letter == '*' )
      {
	fread_to_eol( fp );
	continue;
      }

      if( letter != '#' )
      {
	bug( "Load_ship_file: # not found.", 0 );
	break;
      }

      word = fread_word( fp );

      if( !str_cmp( word, "SHIP" ) )
      {
	fread_ship( ship, fp );
	break;
      }
      else if( !str_cmp( word, "END" ) )
	break;
      else
      {
	char buf[MAX_STRING_LENGTH];

	sprintf( buf, "Load_ship_file: bad section: %s.", word );
	bug( buf, 0 );
	break;
      }
    }

    fclose( fp );
  }

  if( !( found ) )
  {
    DISPOSE( ship );
  }
  else
  {
    LINK( ship, first_ship, last_ship, next, prev );

    if( ship->ship_class == SPACE_STATION || ship->type == MOB_SHIP )
    {
      ship->energy = ship->maxenergy;
      ship->chaff = ship->maxchaff;
      ship->hull = ship->maxhull;

      ship->laserstate = LASER_READY;
      ship->missilestate = LASER_READY;

      ship->missiles = ship->maxmissiles;

      ship_to_starsystem( ship, starsystem_from_name( ship->home ) );
      vector_init( &ship->pos );
      vector_randomize( &ship->pos, -5000, 5000 );
      vector_set( &ship->head, 1, 1, 1 );
      ship->autopilot = TRUE;
      ship->autorecharge = TRUE;
      ship->shield = ship->maxshield;
    }
    else
    {
      ship_to_room( ship, ship->lastdoc );
      ship->location = ship->lastdoc;
    }

    if( ship->type != MOB_SHIP
	&& ( clan = get_clan( ship->owner ) ) != NULL )
    {
      if( ship->ship_class <= SPACE_STATION )
	clan->spacecraft++;
      else
	clan->vehicles++;
    }
  }

  return found;
}

/*
 * Load in all the ship files.
 */
void load_ships()
{
  FILE *fpList = NULL;
  char shiplist[256];

  sprintf( shiplist, "%s%s", SHIP_DIR, SHIP_LIST );

  if( ( fpList = fopen( shiplist, "r" ) ) == NULL )
  {
    perror( shiplist );
    exit( 1 );
  }

  for( ;; )
  {
    const char *filename = feof( fpList ) ? "$" : fread_word( fpList );

    if( filename[0] == '$' )
      break;

    if( !load_ship_file( filename ) )
    {
      bug( "Cannot load ship file: %s", filename );
    }
  }

  fclose( fpList );
}

void resetship( SHIP_DATA * ship )
{
  ship->shipstate = SHIP_READY;

  if( ship->ship_class != SPACE_STATION && ship->type != MOB_SHIP )
  {
    extract_ship( ship );
    ship_to_room( ship, ship->lastdoc );
    ship->location = ship->lastdoc;
    ship->shipstate = SHIP_DOCKED;
    STRFREE( ship->home );
    ship->home = STRALLOC( "" );
  }

  if( ship->starsystem )
    ship_from_starsystem( ship, ship->starsystem );

  ship->currspeed = 0;
  ship->energy = ship->maxenergy;
  ship->chaff = ship->maxchaff;
  ship->hull = ship->maxhull;
  ship->shield = 0;

  ship->laserstate = LASER_READY;
  ship->missilestate = LASER_READY;

  ship->currjump = NULL;
  ship->target = NULL;

  ship->hatchopen = FALSE;

  ship->missiles = ship->maxmissiles;
  ship->autorecharge = FALSE;
  ship->autotrack = FALSE;
  ship->autospeed = FALSE;

  save_ship( ship );
}

void do_resetship( CHAR_DATA * ch, char *argument )
{
  SHIP_DATA *ship = get_ship( argument );

  if( ship == NULL )
  {
    send_to_char( "&RNo such ship!", ch );
    return;
  }

  resetship( ship );

  if( ( ship->ship_class == SPACE_STATION || ship->type == MOB_SHIP )
      && ship->home )
  {
    ship_to_starsystem( ship, starsystem_from_name( ship->home ) );
    vector_init( &ship->pos );
    vector_randomize( &ship->pos, -5000, 5000 );
    ship->shipstate = SHIP_READY;
    ship->autopilot = TRUE;
    ship->autorecharge = TRUE;
    ship->shield = ship->maxshield;
  }
}

void do_setship( CHAR_DATA * ch, char *argument )
{
  char arg1[MAX_INPUT_LENGTH];
  char arg2[MAX_INPUT_LENGTH];
  SHIP_DATA *ship = NULL;
  int tempnum = 0;
  ROOM_INDEX_DATA *roomindex = NULL;

  if( IS_NPC( ch ) || !ch->pcdata )
    return;

  if( !ch->desc )
    return;

  argument = one_argument( argument, arg1 );
  argument = one_argument( argument, arg2 );

  if( arg1[0] == '\0' || arg2[0] == '\0' || arg1[0] == '\0' )
  {
    send_to_char( "Usage: setship <ship> <field> <values>\r\n", ch );
    send_to_char( "\r\nField being one of:\r\n", ch );
    send_to_char( "name owner copilot pilot home\r\n", ch );
    send_to_char( "manuever speed hyperspeed tractorbeam\r\n", ch );
    send_to_char( "lasers missiles shield hull energy chaff\r\n", ch );
    send_to_char( "lastdoc class\r\n", ch );
    return;
  }

  ship = get_ship( arg1 );

  if( !ship )
  {
    send_to_char( "No such ship.\r\n", ch );
    return;
  }

  if( !str_cmp( arg2, "owner" ) )
  {
    CLAN_DATA *clan;
    if( ship->type != MOB_SHIP
	&& ( clan = get_clan( ship->owner ) ) != NULL )
    {
      if( ship->ship_class <= SPACE_STATION )
	clan->spacecraft--;
      else
	clan->vehicles--;
    }
    STRFREE( ship->owner );
    ship->owner = STRALLOC( argument );
    send_to_char( "Done.\r\n", ch );
    save_ship( ship );
    if( ship->type != MOB_SHIP
	&& ( clan = get_clan( ship->owner ) ) != NULL )
    {
      if( ship->ship_class <= SPACE_STATION )
	clan->spacecraft++;
      else
	clan->vehicles++;
    }
    return;
  }

  if( !str_cmp( arg2, "home" ) )
  {
    STRFREE( ship->home );
    ship->home = STRALLOC( argument );
    send_to_char( "Done.\r\n", ch );
    save_ship( ship );
    return;
  }

  if( !str_cmp( arg2, "pilot" ) )
  {
    STRFREE( ship->pilot );
    ship->pilot = STRALLOC( argument );
    send_to_char( "Done.\r\n", ch );
    save_ship( ship );
    return;
  }

  if( !str_cmp( arg2, "copilot" ) )
  {
    STRFREE( ship->copilot );
    ship->copilot = STRALLOC( argument );
    send_to_char( "Done.\r\n", ch );
    save_ship( ship );
    return;
  }


  if( !str_cmp( arg2, "shipyard" ) )
  {
    tempnum = atoi( argument );
    roomindex = get_room_index( tempnum );
    if( roomindex == NULL )
    {
      send_to_char( "That room doesn't exist.", ch );
      return;
    }
    ship->shipyard = tempnum;
    send_to_char( "Done.\r\n", ch );
    save_ship( ship );
    return;
  }

  if( !str_cmp( arg2, "name" ) )
  {
    if( *argument == '\0' )
    {
      ch_printf( ch, "Blank name not allowed.\r\n" );
      return;
    }

    if( get_ship( argument ) )
    {
      ch_printf( ch, "A ship with that name already exists.\r\n" );
      return;
    }

    STRFREE( ship->name );
    ship->name = STRALLOC( argument );
    send_to_char( "Done.\r\n", ch );
    save_ship( ship );
    return;
  }

  if( !str_cmp( arg2, "manuever" ) )
  {
    ship->manuever = URANGE( 0, atoi( argument ), 120 );
    send_to_char( "Done.\r\n", ch );
    save_ship( ship );
    return;
  }

  if( !str_cmp( arg2, "lasers" ) )
  {
    ship->lasers = URANGE( 0, atoi( argument ), 10 );
    send_to_char( "Done.\r\n", ch );
    save_ship( ship );
    return;
  }

  if( !str_cmp( arg2, "class" ) )
  {
    ship->ship_class = URANGE( 0, atoi( argument ), 9 );
    send_to_char( "Done.\r\n", ch );
    save_ship( ship );
    return;
  }

  if( !str_cmp( arg2, "lastdoc" ) )
  {
    ship->lastdoc = URANGE( 0, atoi( argument ), 9 );
    send_to_char( "Done.\r\n", ch );
    save_ship( ship );
    return;
  }


  if( !str_cmp( arg2, "missiles" ) )
  {
    ship->maxmissiles = URANGE( 0, atoi( argument ), 255 );
    ship->missiles = URANGE( 0, atoi( argument ), 255 );
    send_to_char( "Done.\r\n", ch );
    save_ship( ship );
    return;
  }

  if( !str_cmp( arg2, "speed" ) )
  {
    ship->realspeed = URANGE( 0, atoi( argument ), 150 );
    send_to_char( "Done.\r\n", ch );
    save_ship( ship );
    return;
  }

  if( !str_cmp( arg2, "tractorbeam" ) )
  {
    ship->tractorbeam = URANGE( 0, atoi( argument ), 255 );
    send_to_char( "Done.\r\n", ch );
    save_ship( ship );
    return;
  }

  if( !str_cmp( arg2, "hyperspeed" ) )
  {
    ship->hyperspeed = URANGE( 0, atoi( argument ), 255 );
    send_to_char( "Done.\r\n", ch );
    save_ship( ship );
    return;
  }

  if( !str_cmp( arg2, "shield" ) )
  {
    ship->maxshield = URANGE( 0, atoi( argument ), 1000 );
    send_to_char( "Done.\r\n", ch );
    save_ship( ship );
    return;
  }

  if( !str_cmp( arg2, "hull" ) )
  {
    ship->hull = URANGE( 1, atoi( argument ), 20000 );
    ship->maxhull = URANGE( 1, atoi( argument ), 20000 );
    send_to_char( "Done.\r\n", ch );
    save_ship( ship );
    return;
  }

  if( !str_cmp( arg2, "energy" ) )
  {
    ship->energy = URANGE( 1, atoi( argument ), 30000 );
    ship->maxenergy = URANGE( 1, atoi( argument ), 30000 );
    send_to_char( "Done.\r\n", ch );
    save_ship( ship );
    return;
  }

  if( !str_cmp( arg2, "chaff" ) )
  {
    ship->chaff = URANGE( 0, atoi( argument ), 25 );
    ship->maxchaff = URANGE( 0, atoi( argument ), 25 );
    send_to_char( "Done.\r\n", ch );
    save_ship( ship );
    return;
  }

  do_setship( ch, STRLIT_EMPTY );
}

void do_showship( CHAR_DATA * ch, char *argument )
{
  SHIP_DATA *ship = NULL;

  if( IS_NPC( ch ) )
  {
    send_to_char( "Huh?\r\n", ch );
    return;
  }

  if( argument[0] == '\0' )
  {
    send_to_char( "Usage: showship <ship>\r\n", ch );
    return;
  }

  ship = get_ship( argument );
  if( !ship )
  {
    send_to_char( "No such ship.\r\n", ch );
    return;
  }
  set_char_color( AT_YELLOW, ch );
  ch_printf( ch, "%s %s : %s\r\nFilename: %s\r\n",
      ship->type == PLAYER_SHIP ? "Player" : "Mob",
      ship->ship_class == SPACECRAFT ? model[ship->model].name :
      ( ship->ship_class == SPACE_STATION ? "Space Station" :
	( ship->ship_class == AIRCRAFT ? "Aircraft" :
	  ( ship->ship_class == BOAT ? "Boat" :
	    ( ship->ship_class == SUBMARINE ? "Submatine" :
	      ( ship->ship_class ==
		LAND_VEHICLE ? "land vehicle" : "Unknown" ) ) ) ) ),
      ship->name, ship->filename );
  ch_printf( ch, "Home: %s\r\nOwner: %s   Pilot: %s   Copilot: %s\r\n",
      ship->home, ship->owner, ship->pilot, ship->copilot );
  ch_printf( ch, "Location: %d   Lastdoc: %d   Shipyard: %d\r\n",
      ship->location, ship->lastdoc, ship->shipyard );
  ch_printf( ch, "Tractor Beam: %d  ", ship->tractorbeam );
  ch_printf( ch, "Lasers: %d  Laser Condition: %s\r\n",
      ship->lasers,
      ship->laserstate == LASER_DAMAGED ? "Damaged" : "Good" );
  ch_printf( ch, "Missiles: %d/%d  Condition: %s\r\n",
      ship->missiles,
      ship->maxmissiles,
      ship->missilestate == MISSILE_DAMAGED ? "Damaged" : "Good" );
  ch_printf( ch, "Hull: %d/%d  Ship Condition: %s\r\n",
      ship->hull,
      ship->maxhull,
      ship->shipstate == SHIP_DISABLED ? "Disabled" : "Running" );

  ch_printf( ch, "Shields: %d/%d   Energy(fuel): %d/%d   Chaff: %d/%d\r\n",
      ship->shield,
      ship->maxshield,
      ship->energy, ship->maxenergy, ship->chaff, ship->maxchaff );
  ch_printf( ch, "Current Coordinates: %.0f %.0f %.0f\r\n",
      ship->pos.x, ship->pos.y, ship->pos.z );
  ch_printf( ch, "Current Heading: %.2f %.2f %.2f\r\n",
      ship->head.x, ship->head.y, ship->head.z );
  ch_printf( ch, "Speed: %d/%d   Hyperspeed: %d\r\n  Manueverability: %d",
      ship->currspeed, ship->realspeed, ship->hyperspeed,
      ship->manuever );
  return;
}

void do_ships( CHAR_DATA * ch, char *argument )
{
  SHIP_DATA *ship = NULL;
  int count = 0;

  if( IS_NPC( ch ) )
    return;

  send_to_char
    ( "&YThe following ships are owned by you or by your organization:\r\n",
      ch );
  send_to_char( "\r\n&WShip                               Location\r\n", ch );

  for( ship = first_ship; ship; ship = ship->next )
  {
    if( str_cmp( ship->owner, ch->name ) )
    {
      if( !ch->pcdata || !ch->pcdata->clan
	  || str_cmp( ship->owner, ch->pcdata->clan->name )
	  || ship->ship_class > SPACE_STATION )
	continue;
    }

    if( ship->type == MOB_SHIP )
      continue;
    set_char_color( AT_BLUE, ch );

    if( ship->in_room )
    {
      if( ship->in_room->area && ship->in_room->area->planet )
	ch_printf( ch, "%s  -%s (%s)\r\n", ship->name,
	    ship->in_room->name,
	    ship->in_room->area->planet->name );
      else
	ch_printf( ch, "%s  -%s\r\n", ship->name, ship->in_room->name );
    }
    else
      ch_printf( ch, "%s\r\n", ship->name );

    count++;
  }

  if( !count )
  {
    send_to_char( "There are no ships owned by you.\r\n", ch );
  }
}

void do_speeders( CHAR_DATA * ch, char *argument )
{
  SHIP_DATA *ship = NULL;
  int count = 0;

  if( IS_NPC( ch ) )
    return;

  send_to_char
    ( "&YThe following are owned by you or by your organization:\r\n", ch );
  send_to_char( "\r\n&WVehicle                            Location\r\n", ch );
  for( ship = first_ship; ship; ship = ship->next )
  {
    if( str_cmp( ship->owner, ch->name ) )
    {
      if( !ch->pcdata || !ch->pcdata->clan
	  || str_cmp( ship->owner, ch->pcdata->clan->name )
	  || ship->ship_class <= SPACE_STATION )
	continue;
    }
    if( ship->location != ch->in_room->vnum
	|| ship->ship_class <= SPACE_STATION )
      continue;

    if( ship->type == MOB_SHIP )
      continue;
    set_char_color( AT_BLUE, ch );

    if( ship->in_room )
    {
      if( ship->in_room->area && ship->in_room->area
	  && ship->in_room->area->planet )
	ch_printf( ch, "%s  -%s (%s)\r\n", ship->name,
	    ship->in_room->name,
	    ship->in_room->area->planet->name );
      else
	ch_printf( ch, "%s  -%s\r\n", ship->name, ship->in_room->name );
    }
    else
      ch_printf( ch, "%s\r\n", ship->name );

    count++;
  }

  if( !count )
  {
    send_to_char( "There are no land or air vehicles owned by you.\r\n",
	ch );
  }
}

void do_allspeeders( CHAR_DATA * ch, char *argument )
{
  SHIP_DATA *ship = NULL;
  int count = 0;

  send_to_char
    ( "&Y\r\nThe following sea/land/air vehicles are currently formed:\r\n",
      ch );
  send_to_char( "\r\n&WVehicle                            Owner\r\n", ch );

  for( ship = first_ship; ship; ship = ship->next )
  {
    if( ship->ship_class <= SPACE_STATION )
      continue;

    if( ship->type == MOB_SHIP )
      continue;

    set_char_color( AT_BLUE, ch );
    ch_printf( ch, "%-35s %-15s\r\n", ship->name, ship->owner );

    count++;
  }

  if( !count )
  {
    send_to_char( "There are none currently formed.\r\n", ch );
    return;
  }
}

void do_allships( CHAR_DATA * ch, char *argument )
{
  SHIP_DATA *ship;
  int count = 0;
  send_to_char( "&Y\r\nThe following ships are currently formed:\r\n", ch );

  send_to_char( "\r\n&WShip                               Owner\r\n", ch );

  for( ship = first_ship; ship; ship = ship->next )
  {
    if( ship->ship_class > SPACE_STATION )
      continue;

    if( ship->type == MOB_SHIP )
      continue;
    set_char_color( AT_BLUE, ch );

    ch_printf( ch, "%-35s %-15s\r\n", ship->name, ship->owner );

    count++;
  }

  if( !count )
  {
    send_to_char( "There are no ships currently formed.\r\n", ch );
    return;
  }
}

void ship_to_starsystem( SHIP_DATA * ship, SPACE_DATA * starsystem )
{
  if( starsystem == NULL || ship == NULL )
    return;

  LINK( ship, starsystem->first_ship, starsystem->last_ship,
      next_in_starsystem, prev_in_starsystem );

  ship->starsystem = starsystem;
}

void new_missile( SHIP_DATA * ship, SHIP_DATA * target, CHAR_DATA * ch )
{
  SPACE_DATA *starsystem = NULL;
  MISSILE_DATA *missile = NULL;

  if( ship == NULL )
    return;

  if( target == NULL )
    return;

  if( ( starsystem = ship->starsystem ) == NULL )
    return;

  CREATE( missile, MISSILE_DATA, 1 );
  LINK( missile, first_missile, last_missile, next, prev );

  vector_init( &missile->pos );
  vector_init( &missile->head );

  missile->target = target;
  missile->fired_from = ship;

  if( ch )
    missile->fired_by = STRALLOC( ch->name );
  else
    missile->fired_by = STRALLOC( "" );

  missile->age = 0;
  missile->speed = 200;

  vector_copy( &missile->pos, &ship->pos );
  missile_set_course_to_ship( missile, target );

  if( starsystem->first_missile == NULL )
    starsystem->first_missile = missile;

  if( starsystem->last_missile )
  {
    starsystem->last_missile->next_in_starsystem = missile;
    missile->prev_in_starsystem = starsystem->last_missile;
  }

  starsystem->last_missile = missile;
  missile->starsystem = starsystem;
}

void ship_from_starsystem( SHIP_DATA * ship, SPACE_DATA * starsystem )
{
  if( starsystem == NULL || ship == NULL )
    return;

  UNLINK( ship, starsystem->first_ship, starsystem->last_ship,
      next_in_starsystem, prev_in_starsystem );

  ship->starsystem = NULL;
}

void extract_missile( MISSILE_DATA * missile )
{
  SPACE_DATA *starsystem = NULL;

  if( missile == NULL )
    return;

  if( ( starsystem = missile->starsystem ) != NULL )
  {
    if( starsystem->last_missile == missile )
      starsystem->last_missile = missile->prev_in_starsystem;

    if( starsystem->first_missile == missile )
      starsystem->first_missile = missile->next_in_starsystem;

    if( missile->prev_in_starsystem )
      missile->prev_in_starsystem->next_in_starsystem =
	missile->next_in_starsystem;

    if( missile->next_in_starsystem )
      missile->next_in_starsystem->prev_in_starsystem =
	missile->prev_in_starsystem;

    missile->starsystem = NULL;
    missile->next_in_starsystem = NULL;
    missile->prev_in_starsystem = NULL;
  }

  UNLINK( missile, first_missile, last_missile, next, prev );

  missile->target = NULL;
  missile->fired_from = NULL;

  if( missile->fired_by )
    STRFREE( missile->fired_by );

  DISPOSE( missile );
}

bool check_pilot( const CHAR_DATA * ch, const SHIP_DATA * ship )
{
  if( !str_cmp( ch->name, ship->owner ) || !str_cmp( ch->name, ship->pilot )
      || !str_cmp( ch->name, ship->copilot ) )
    return TRUE;

  if( !IS_NPC( ch ) && ch->pcdata && ch->pcdata->clan )
  {
    if( !str_cmp( ch->pcdata->clan->name, ship->owner ) )
    {
      if( clan_char_has_permission( ch->pcdata->clan, ch, CLAN_PERM_PILOT ) )
	return TRUE;
    }
  }

  return FALSE;
}

bool extract_ship( SHIP_DATA * ship )
{
  ROOM_INDEX_DATA *room;

  if( ( room = ship->in_room ) != NULL )
  {
    UNLINK( ship, room->first_ship, room->last_ship, next_in_room,
	prev_in_room );
    ship->in_room = NULL;
  }
  return TRUE;
}

void damage_ship( SHIP_DATA * ship, int min, int max, CHAR_DATA * ch )
{
  int damg = number_range( min, max );

  if( ship->shield > 0 )
  {
    int shield_dmg = UMIN( ship->shield, damg );
    damg -= shield_dmg;
    ship->shield -= shield_dmg;
    if( ship->shield == 0 )
      echo_to_cockpit( AT_BLOOD, ship, "Shields down..." );
  }

  if( damg > 0 )
  {
    if( number_range( 1, 100 ) <= 5 && ship->shipstate != SHIP_DISABLED )
    {
      echo_to_cockpit( AT_BLOOD + AT_BLINK, ship,
	  "Ship's drive DAMAGED!" );
      ship->shipstate = SHIP_DISABLED;
    }

    if( number_range( 1, 100 ) <= 5 && ship->missilestate != MISSILE_DAMAGED
	&& ship->maxmissiles > 0 )
    {
      echo_to_room( AT_BLOOD + AT_BLINK, ship->gunseat,
	  "Ship's missile launcher DAMAGED!" );
      ship->missilestate = MISSILE_DAMAGED;
    }

    if( number_range( 1, 100 ) <= 2 && ship->laserstate != LASER_DAMAGED )
    {
      echo_to_room( AT_BLOOD + AT_BLINK, ship->gunseat,
	  "Lasers DAMAGED!" );
      ship->laserstate = LASER_DAMAGED;
    }
  }

  ship->hull -= damg * 5;

  if( ship->hull <= 0 )
  {
    destroy_ship( ship, ch );
    return;
  }

  if( ship->hull <= ship->maxhull / 20 )
    echo_to_cockpit( AT_BLOOD + AT_BLINK, ship,
	"WARNING! Ship hull severely damaged!" );
}

void ship_clear_turret_targets( SHIP_DATA * ship )
{
  TURRET_DATA *turret = NULL;

  for( turret = ship->first_turret; turret; turret = turret->next )
  {
    turret->target = NULL;
  }
}

void ship_free_room_descriptions( SHIP_DATA * ship )
{
  size_t dIndex = 0;

  for( dIndex = 0; dIndex < MAX_SHIP_ROOMS; dIndex++ )
  {
    if( ship->description[dIndex] )
    {
      STRFREE( ship->description[dIndex] );
    }
  }
}

void ship_untarget_by_attackers( const SHIP_DATA * ship )
{
  SHIP_DATA *att = NULL;

  for( att = first_ship; att; att = att->next )
  {
    TURRET_DATA *turret = NULL;

    if( att->target == ship )
    {
      att->target = NULL;
    }

    for( turret = att->first_turret; turret; turret = turret->next )
    {
      if( turret->target == ship )
      {
	turret->target = NULL;
      }
    }
  }
}

void ship_untarget_by_missiles( const SHIP_DATA * ship )
{
  MISSILE_DATA *missile = NULL;
  MISSILE_DATA *m_next = NULL;

  for( missile = first_missile; missile; missile = m_next )
  {
    m_next = missile->next;

    if( missile->target && missile->target == ship )
      extract_missile( missile );

    if( missile->fired_from && missile->fired_from == ship )
      extract_missile( missile );
  }
}

void destroy_ship_kill_characters( const SHIP_DATA * ship,
    CHAR_DATA * killer )
{
  ROOM_INDEX_DATA *room = NULL;

  for( room = ship->first_room; room; room = room->next_in_ship )
  {
    CHAR_DATA *rch = room->first_person;

    while( rch )
    {
      bool survived = FALSE;

      if( !IS_NPC( rch ) && ship->starsystem
	  && ship->starsystem->last_planet
	  && ship->starsystem->last_planet->area )
      {
	ROOM_INDEX_DATA *pRoom = NULL;
	OBJ_DATA *scraps = NULL;
	int rnum = 0;
	int tnum =
	  number_range( 0,
	      ship->starsystem->last_planet->wilderness +
	      ship->starsystem->last_planet->farmland );

	for( pRoom = ship->starsystem->last_planet->area->first_room;
	    pRoom; pRoom = pRoom->next_in_area )
	  if( pRoom->sector_type != SECT_CITY
	      && pRoom->sector_type != SECT_DUNNO
	      && pRoom->sector_type != SECT_INSIDE
	      && pRoom->sector_type != SECT_UNDERGROUND )
	  {
	    if( rnum++ < tnum )
	      continue;

	    char_from_room( rch );
	    char_to_room( rch, pRoom );

	    if( !IS_IMMORTAL( rch ) )
	      rch->hit = -1;

	    update_pos( rch );
	    echo_to_room( AT_WHITE, rch->in_room,
		"There is loud explosion as an escape pod hits the earth." );

	    scraps =
	      create_object( get_obj_index( OBJ_VNUM_SCRAPS ) );
	    scraps->timer = 15;
	    STRFREE( scraps->short_descr );
	    scraps->short_descr = STRALLOC( "a battered escape pod" );
	    STRFREE( scraps->description );
	    scraps->description =
	      STRALLOC
	      ( "The smoking shell of an escape pod litters the earth.\r\n" );
	    obj_to_room( scraps, pRoom );

	    survived = TRUE;
	    break;
	  }
      }

      if( !survived && IS_IMMORTAL( rch ) )
      {
	char_from_room( rch );
	char_to_room( rch, get_room_index( wherehome( rch ) ) );
	survived = TRUE;
      }

      if( !survived )
      {
	if( killer )
	{
	  raw_kill( killer, rch );
	}
	else
	{
	  raw_kill( rch, rch );
	}
      }

      rch = room->first_person;
    }

    room_extract_contents( room );
  }
}

void destroy_ship( SHIP_DATA * ship, CHAR_DATA * killer )
{
  char buf[MAX_STRING_LENGTH];
  CLAN_DATA *clan = NULL;

  sprintf( buf, "%s explodes in a blinding flash of light!", ship->name );
  echo_to_system( AT_WHITE + AT_BLINK, ship, buf, NULL );

  sprintf( buf, "%s destroyed by %s", ship->name,
      killer ? killer->name : "(none)" );
  log_string( buf );
  echo_to_ship( AT_WHITE, ship,
      "The ship is shaken by a FATAL explosion. You realize it's escape or perish." );
  echo_to_ship( AT_WHITE, ship,
      "The last thing you remember is reaching for the escape pod release lever." );
  echo_to_ship( AT_WHITE + AT_BLINK, ship, "A blinding flash of light." );
  echo_to_ship( AT_WHITE, ship, "And then darkness...." );

  destroy_ship_kill_characters( ship, killer );

  if( ship->starsystem )
    ship_from_starsystem( ship, ship->starsystem );

  extract_ship( ship );

  clan = get_clan( ship->owner );

  if( clan )
  {
    clan_decrease_vehicles_owned( clan, ship );
  }

  STRFREE( ship->owner );
  STRFREE( ship->pilot );
  STRFREE( ship->copilot );
  STRFREE( ship->home );
  ship->owner = STRALLOC( "" );
  ship->pilot = STRALLOC( "" );
  ship->copilot = STRALLOC( "" );
  ship->home = STRALLOC( "" );
  ship->target = NULL;

  ship_clear_turret_targets( ship );
  ship_free_room_descriptions( ship );

  UNLINK( ship, first_ship, last_ship, next, prev );

  ship_untarget_by_attackers( ship );
  ship_untarget_by_missiles( ship );

  write_ship_list();
}

bool ship_to_room( SHIP_DATA * ship, long vnum )
{
  ROOM_INDEX_DATA *shipto = NULL;

  if( ( shipto = get_room_index( vnum ) ) == NULL )
    return FALSE;

  LINK( ship, shipto->first_ship, shipto->last_ship, next_in_room,
      prev_in_room );
  ship->in_room = shipto;
  return TRUE;
}

void do_board( CHAR_DATA * ch, char *argument )
{
  ROOM_INDEX_DATA *fromroom;
  ROOM_INDEX_DATA *toroom;
  SHIP_DATA *ship;

  if( !argument || argument[0] == '\0' )
  {
    send_to_char( "Board what?\r\n", ch );
    return;
  }

  if( ( ship = ship_in_room( ch->in_room, argument ) ) == NULL )
  {
    act( AT_PLAIN, "I see no $T here.", ch, NULL, argument, TO_CHAR );
    return;
  }

  if( IS_SET( ch->act, ACT_MOUNTED ) )
  {
    act( AT_PLAIN, "You can't go in there riding THAT.", ch, NULL, argument,
	TO_CHAR );
    return;
  }

  fromroom = ch->in_room;

  if( ( toroom = ship->entrance ) != NULL )
  {
    if( !ship->hatchopen )
    {
      send_to_char( "&RThe hatch is closed!\r\n", ch );
      return;
    }

    if( toroom->tunnel > 0 )
    {
      CHAR_DATA *ctmp;
      int count = 0;

      for( ctmp = toroom->first_person; ctmp; ctmp = ctmp->next_in_room )
	if( ++count >= toroom->tunnel )
	{
	  send_to_char( "There is no room for you in there.\r\n", ch );
	  return;
	}
    }

    if( ship->shipstate == SHIP_LAUNCH || ship->shipstate == SHIP_LAUNCH_2 )
    {
      send_to_char( "&rThat ship has already started launching!\r\n",
	  ch );
      return;
    }

    act( AT_PLAIN, "$n enters $T.", ch, NULL, ship->name, TO_ROOM );
    act( AT_PLAIN, "You enter $T.", ch, NULL, ship->name, TO_CHAR );
    char_from_room( ch );
    char_to_room( ch, toroom );
    act( AT_PLAIN, "$n enters the ship.", ch, NULL, argument, TO_ROOM );
    do_look( ch, STRLIT_AUTO );

  }
  else
    send_to_char( "That ship has no entrance!\r\n", ch );
}

void do_leaveship( CHAR_DATA * ch, char *argument )
{
  ROOM_INDEX_DATA *fromroom;
  ROOM_INDEX_DATA *toroom;
  SHIP_DATA *ship;

  fromroom = ch->in_room;

  if( ( ship = ship_from_entrance( fromroom ) ) == NULL )
  {
    send_to_char( "I see no exit here.\r\n", ch );
    return;
  }

  if( ship->ship_class == SPACE_STATION )
  {
    send_to_char( "You can't do that here.\r\n", ch );
    return;
  }

  if( ship->lastdoc != ship->location )
  {
    send_to_char( "&rMaybe you should wait until the ship lands.\r\n", ch );
    return;
  }

  if( ship->shipstate != SHIP_DOCKED && ship->shipstate != SHIP_DISABLED )
  {
    send_to_char( "&rPlease wait till the ship is properly docked.\r\n",
	ch );
    return;
  }

  if( !ship->hatchopen )
  {
    send_to_char( "&RYou need to open the hatch first", ch );
    return;
  }

  if( ( toroom = get_room_index( ship->location ) ) != NULL )
  {
    act( AT_PLAIN, "$n exits the ship.", ch, NULL, argument, TO_ROOM );
    act( AT_PLAIN, "You exit the ship.", ch, NULL, argument, TO_CHAR );
    char_from_room( ch );
    char_to_room( ch, toroom );
    act( AT_PLAIN, "$n steps out of a ship.", ch, NULL, argument, TO_ROOM );
    do_look( ch, STRLIT_AUTO );
  }
  else
    send_to_char( "The exit doesn't seem to be working properly.\r\n", ch );
}

void do_launch( CHAR_DATA * ch, char *argument )
{
  int chance = 0;
  long price = 0;
  SHIP_DATA *ship = NULL;
  char buf[MAX_STRING_LENGTH];

  if( ( ship = ship_from_pilotseat( ch->in_room ) ) == NULL )
  {
    send_to_char
      ( "&RYou must be in the pilots seat of a ship to do that!\r\n", ch );
    return;
  }

  if( ship->ship_class > SPACE_STATION )
  {
    send_to_char( "&RThis isn't a spacecraft!\r\n", ch );
    return;
  }

  if( autofly( ship ) )
  {
    send_to_char
      ( "&RThe ship is set on autopilot, you'll have to turn it off first.\r\n",
	ch );
    return;
  }

  if( ship->ship_class == SPACE_STATION )
  {
    send_to_char( "You can't do that here.\r\n", ch );
    return;
  }

  if( !check_pilot( ch, ship ) )
  {
    send_to_char
      ( "&RHey, thats not your ship! Try renting a public one.\r\n", ch );
    return;
  }

  if( ship->lastdoc != ship->location )
  {
    send_to_char( "&rYou don't seem to be docked right now.\r\n", ch );
    return;
  }

  if( ship->shipstate != SHIP_DOCKED && ship->shipstate != SHIP_DISABLED )
  {
    send_to_char( "The ship is not docked right now.\r\n", ch );
    return;
  }

  chance = character_skill_level( ch, gsn_spacecraft );

  if( number_percent() < chance )
  {
    price = 20;
    price += ( ship->maxhull - ship->hull );

    if( ship->missiles )
      price += ( 50 * ( ship->maxmissiles - ship->missiles ) );

    if( ship->shipstate == SHIP_DISABLED )
      price += 200;

    if( ship->missilestate == MISSILE_DAMAGED )
      price += 100;

    if( ship->laserstate == LASER_DAMAGED )
      price += 50;

    if( ch->pcdata && ch->pcdata->clan
	&& !str_cmp( ch->pcdata->clan->name, ship->owner ) )
    {
      if( ch->pcdata->clan->funds < price )
      {
	ch_printf( ch,
	    "&R%s doesn't have enough funds to prepare this ship for launch.\r\n",
	    ch->pcdata->clan->name );
	return;
      }

      ch->pcdata->clan->funds -= price;
      ch_printf( ch,
	  "&GIt costs %s %ld credits to ready this ship for launch.\r\n",
	  ch->pcdata->clan->name, price );
    }
    else
    {
      if( ch->gold < price )
      {
	ch_printf( ch,
	    "&RYou don't have enough funds to prepare this ship for launch.\r\n" );
	return;
      }

      ch->gold -= price;
      ch_printf( ch,
	  "&GYou pay %ld credits to ready the ship for launch.\r\n",
	  price );
    }

    ship->energy = ship->maxenergy;
    ship->chaff = ship->maxchaff;
    ship->missiles = ship->maxmissiles;
    ship->shield = 0;
    ship->autorecharge = FALSE;
    ship->autotrack = FALSE;
    ship->autospeed = FALSE;
    ship->hull = ship->maxhull;
    ship->missilestate = MISSILE_READY;
    ship->laserstate = LASER_READY;
    ship->shipstate = SHIP_DOCKED;

    if( ship->hatchopen )
    {
      ship->hatchopen = FALSE;
      sprintf( buf, "The hatch on %s closes.", ship->name );
      echo_to_room( AT_YELLOW, get_room_index( ship->location ), buf );
      echo_to_room( AT_YELLOW, ship->entrance, "The hatch slides shut." );
      sound_to_room( ship->entrance, "!!SOUND(door)" );
      sound_to_room( get_room_index( ship->location ), "!!SOUND(door)" );
    }

    set_char_color( AT_GREEN, ch );
    send_to_char( "Launch sequence initiated.\r\n", ch );
    act( AT_PLAIN, "$n starts up the ship and begins the launch sequence.",
	ch, NULL, argument, TO_ROOM );
    echo_to_ship( AT_YELLOW, ship,
	"The ship hums as it lifts off the ground." );
    sprintf( buf, "%s begins to launch.", ship->name );
    echo_to_room( AT_YELLOW, get_room_index( ship->location ), buf );
    ship->shipstate = SHIP_LAUNCH;
    ship->currspeed = ship->realspeed;
    learn_from_success( ch, gsn_spacecraft );
    return;
  }

  set_char_color( AT_RED, ch );
  send_to_char( "You fail to work the controls properly!\r\n", ch );
}

void launchship( SHIP_DATA * ship )
{
  char buf[MAX_STRING_LENGTH];
  SHIP_DATA *source = NULL;
  ROOM_INDEX_DATA *room = NULL;

  ship_to_starsystem( ship, starsystem_from_room( ship->in_room ) );

  if( ship->starsystem == NULL )
  {
    echo_to_room( AT_YELLOW, ship->pilotseat,
	"Launch path blocked .. Launch aborted." );
    echo_to_ship( AT_YELLOW, ship,
	"The ship slowly sets back back down on the landing pad." );
    sprintf( buf, "%s slowly sets back down.", ship->name );
    echo_to_room( AT_YELLOW, get_room_index( ship->location ), buf );
    ship->shipstate = SHIP_DOCKED;
    return;
  }

  source = ship_from_room( ship->in_room );
  extract_ship( ship );

  ship->location = 0;

  if( ship->shipstate != SHIP_DISABLED )
    ship->shipstate = SHIP_READY;

  vector_randomize( &ship->head, -1, 2 );
  vector_normalize( &ship->head );

  if( ( room = get_room_index( ship->lastdoc ) ) != NULL &&
      room->area && room->area->planet && room->area->planet->starsystem
      && room->area->planet->starsystem == ship->starsystem )
  {
    vector_copy( &ship->pos, &room->area->planet->pos );
  }
  else if( source )
  {
    vector_copy( &ship->pos, &source->pos );
  }

  ship->energy -= ( 100 + 10 * ship->model );

  ship_move( ship );		/* move it away */

  echo_to_room( AT_GREEN, ship->pilotseat, "Launch complete.\r\n" );
  echo_to_ship( AT_YELLOW, ship,
      "The ship leaves the platform far behind as it flies into space." );
  sprintf( buf, "%s enters the starsystem at %.0f %.0f %.0f", ship->name,
      ship->pos.x, ship->pos.y, ship->pos.z );
  echo_to_system( AT_YELLOW, ship, buf, NULL );
  sprintf( buf, "%s lifts off into space.", ship->name );
  echo_to_room( AT_YELLOW, get_room_index( ship->lastdoc ), buf );
}


void do_land( CHAR_DATA * ch, char *argument )
{
  char arg[MAX_INPUT_LENGTH];
  char arg1[MAX_INPUT_LENGTH];
  int chance = 0;
  SHIP_DATA *ship = NULL;
  SHIP_DATA *target = NULL;
  PLANET_DATA *planet = NULL;
  bool pfound = FALSE;
  ROOM_INDEX_DATA *room = NULL;
  bool rfound = FALSE;

  strcpy( arg, argument );
  argument = one_argument( argument, arg1 );

  if( ( ship = ship_from_pilotseat( ch->in_room ) ) == NULL )
  {
    send_to_char
      ( "&RYou must be in the pilots seat of a ship to do that!\r\n", ch );
    return;
  }

  if( ship->ship_class > SPACE_STATION )
  {
    send_to_char( "&RThis isn't a spacecraft!\r\n", ch );
    return;
  }

  if( autofly( ship ) )
  {
    send_to_char
      ( "&RYou'll have to turn off the ships autopilot first.\r\n", ch );
    return;
  }

  if( ship->ship_class == SPACE_STATION )
  {
    send_to_char( "&RYou can't land space stations.\r\n", ch );
    return;
  }

  if( ship->shipstate == SHIP_DISABLED )
  {
    send_to_char( "&RThe ships drive is disabled. Unable to land.\r\n",
	ch );
    return;
  }
  if( ship->shipstate == SHIP_DOCKED )
  {
    send_to_char( "&RThe ship is already docked!\r\n", ch );
    return;
  }

  if( ship->shipstate == SHIP_HYPERSPACE )
  {
    send_to_char( "&RYou can only do that in realspace!\r\n", ch );
    return;
  }

  if( ship->shipstate != SHIP_READY )
  {
    send_to_char
      ( "&RPlease wait until the ship has finished its current maneuver.\r\n",
	ch );
    return;
  }

  if( ship->starsystem == NULL )
  {
    send_to_char( "&RThere's nowhere to land around here!", ch );
    return;
  }

  if( ship->energy < ( 25 + 5 * ship->model ) )
  {
    send_to_char( "&RTheres not enough fuel!\r\n", ch );
    return;
  }

  if( arg[0] == '\0' )
  {
    set_char_color( AT_CYAN, ch );
    ch_printf( ch, "%s", "Land where?\r\n\r\nChoices: \r\n" );

    for( target = ship->starsystem->first_ship; target;
	target = target->next_in_starsystem )
    {
      if( target->ship_class == SPACE_STATION && target != ship )
	ch_printf( ch, "%s    %.0f %.0f %.0f\r\n         ",
	    target->name,
	    target->pos.x, target->pos.y, target->pos.z );
    }

    for( planet = ship->starsystem->first_planet; planet;
	planet = planet->next_in_system )
      ch_printf( ch, "%s   %.0f %.0f %.0f\r\n", planet->name, planet->pos.x,
	  planet->pos.y, planet->pos.z );

    ch_printf( ch, "\r\nYour Coordinates: %.0f %.0f %.0f\r\n",
	ship->pos.x, ship->pos.y, ship->pos.z );
    return;
  }

  for( planet = ship->starsystem->first_planet; planet;
      planet = planet->next_in_system )
  {
    if( !str_prefix( arg1, planet->name ) )
    {
      pfound = TRUE;

      if( !planet->area )
      {
	send_to_char
	  ( "&RThat planet doesn't have any landing areas.\r\n", ch );
	return;
      }

      if( ship_distance_to_planet( ship, planet ) > 200 )
      {
	send_to_char
	  ( "&RThat planet is too far away! You'll have to fly a little closer.\r\n",
	    ch );
	return;
      }

      if( argument[0] != '\0' )
	for( room = planet->area->first_room; room;
	    room = room->next_in_area )
	{
	  if( IS_SET( room->room_flags, ROOM_CAN_LAND )
	      && !str_prefix( argument, room->name ) )
	  {
	    rfound = TRUE;
	    break;
	  }
	}

      if( !rfound )
      {
	send_to_char
	  ( "&CPlease type the location after the planet name.\r\n",
	    ch );
	ch_printf( ch, "Possible choices for %s:\r\n\r\n",
	    planet->name );
	for( room = planet->area->first_room; room;
	    room = room->next_in_area )
	  if( IS_SET( room->room_flags, ROOM_CAN_LAND ) )
	    ch_printf( ch, "%s\r\n", room->name );
	return;
      }

      break;
    }
  }

  if( !pfound )
  {
    target = get_ship_here( arg, ship->starsystem );

    if( target != NULL )
    {
      if( target == ship )
      {
	send_to_char( "&RYou can't land your ship inside itself!\r\n",
	    ch );
	return;
      }
      if( target->ship_class != SPACE_STATION )
      {
	send_to_char
	  ( "&RThat ship has no hangar for you to land in!\r\n", ch );
	return;
      }

      if( ship_distance_to_ship( ship, target ) > 200 )
      {
	send_to_char
	  ( "&R That ship is too far away! You'll have to fly a little closer.\r\n",
	    ch );
	return;
      }
    }
    else
    {
      send_to_char( "&RI don't see that here.\r\n&W", ch );
      do_land( ch, STRLIT_EMPTY );
      return;
    }
  }

  chance = character_skill_level( ch, gsn_spacecraft );

  if( number_percent() < chance )
  {
    set_char_color( AT_GREEN, ch );
    send_to_char( "Landing sequence initiated.\r\n", ch );
    act( AT_PLAIN, "$n begins the landing sequence.", ch,
	NULL, "", TO_ROOM );
    echo_to_ship( AT_YELLOW, ship,
	"The ship slowly begins its landing approach." );
    ship->dest = STRALLOC( arg );
    ship->shipstate = SHIP_LAND;
    ship->currspeed = 0;
    if( number_percent() == 23 )
    {
      send_to_char
	( "Your experience makes you feel more coordinated than before.\r\n",
	  ch );
      ch->perm_dex++;
      ch->perm_dex = UMIN( ch->perm_dex, 25 );
    }

    learn_from_success( ch, gsn_spacecraft );
    return;
  }

  send_to_char( "You fail to work the controls properly.\r\n", ch );
}

void landship( SHIP_DATA * ship, char *argument )
{
  SHIP_DATA *target = 0;
  char buf[MAX_STRING_LENGTH];
  int destination = 0;
  char arg[MAX_INPUT_LENGTH];
  char arg1[MAX_INPUT_LENGTH];
  PLANET_DATA *planet = NULL;
  ROOM_INDEX_DATA *room = NULL;

  strcpy( arg, argument );
  argument = one_argument( argument, arg1 );

  for( planet = ship->starsystem->first_planet; planet;
      planet = planet->next_in_system )
  {
    if( !str_prefix( arg1, planet->name ) )
    {
      if( !planet->area )
	continue;
      for( room = planet->area->first_room; room;
	  room = room->next_in_area )
      {
	if( IS_SET( room->room_flags, ROOM_CAN_LAND )
	    && !str_prefix( argument, room->name ) )
	{
	  destination = room->vnum;
	  break;
	}
      }
      break;
    }
  }

  if( !destination )
  {
    target = get_ship_here( arg, ship->starsystem );
    if( target != ship && target != NULL )
      destination = 0;
    destination = 0;		/* landing on ships is disabled */
  }

  if( !ship_to_room( ship, destination ) )
  {
    echo_to_room( AT_YELLOW, ship->pilotseat,
	"Could not complete approach. Landing aborted." );
    echo_to_ship( AT_YELLOW, ship,
	"The ship pulls back up out of its landing sequence." );
    if( ship->shipstate != SHIP_DISABLED )
      ship->shipstate = SHIP_READY;
    return;
  }

  echo_to_room( AT_YELLOW, ship->pilotseat, "Landing sequence complete." );
  echo_to_ship( AT_YELLOW, ship,
      "You feel a slight thud as the ship sets down on the ground." );
  sprintf( buf, "%s disappears from your scanner.", ship->name );
  echo_to_system( AT_YELLOW, ship, buf, NULL );

  ship->location = destination;
  ship->lastdoc = ship->location;
  if( ship->shipstate != SHIP_DISABLED )
    ship->shipstate = SHIP_DOCKED;
  ship_from_starsystem( ship, ship->starsystem );

  sprintf( buf, "%s lands on the platform.", ship->name );
  echo_to_room( AT_YELLOW, get_room_index( ship->location ), buf );

  ship->energy = ship->energy - 25 - 5 * ship->model;

  save_ship( ship );
}

void do_accelerate( CHAR_DATA * ch, char *argument )
{
  int chance = 0;
  int change = 0;
  SHIP_DATA *ship = NULL;
  char buf[MAX_STRING_LENGTH];

  if( ( ship = ship_from_pilotseat( ch->in_room ) ) == NULL )
  {
    send_to_char( "&RYou must be at the controls of a ship to do that!\r\n",
	ch );
    return;
  }

  if( ship->ship_class > SPACE_STATION )
  {
    send_to_char( "&RThis isn't a spacecraft!\r\n", ch );
    return;
  }

  if( autofly( ship ) )
  {
    send_to_char
      ( "&RYou'll have to turn off the ships autopilot first.\r\n", ch );
    return;
  }

  if( ship->ship_class == SPACE_STATION )
  {
    send_to_char( "&RPlatforms can't move!\r\n", ch );
    return;
  }

  if( ship->shipstate == SHIP_HYPERSPACE )
  {
    send_to_char( "&RYou can only do that in realspace!\r\n", ch );
    return;
  }

  if( ship->shipstate == SHIP_DISABLED )
  {
    send_to_char
      ( "&RThe ships drive is disabled. Unable to accelerate.\r\n", ch );
    return;
  }

  if( ship->shipstate == SHIP_DOCKED )
  {
    send_to_char( "&RYou can't do that until after you've launched!\r\n",
	ch );
    return;
  }

  if( ship->energy <
      abs( ( atoi( argument ) - abs( ship->currspeed ) ) / 10 ) )
  {
    send_to_char( "&RTheres not enough fuel!\r\n", ch );
    return;
  }

  chance = character_skill_level( ch, gsn_spacecraft );

  if( number_percent() >= chance )
  {
    send_to_char( "&RYou fail to work the controls properly.\r\n", ch );
    return;
  }

  change = atoi( argument );
  act( AT_PLAIN, "$n manipulates the ships controls.", ch,
      NULL, argument, TO_ROOM );

  if( change > ship->currspeed )
  {
    send_to_char( "&GAccelerating\r\n", ch );
    echo_to_cockpit( AT_YELLOW, ship, "The ship begins to accelerate." );
    sprintf( buf, "%s begins to speed up.", ship->name );
    echo_to_system( AT_ORANGE, ship, buf, NULL );
  }

  if( change < ship->currspeed )
  {
    send_to_char( "&GDecelerating\r\n", ch );
    echo_to_cockpit( AT_YELLOW, ship, "The ship begins to slow down." );
    sprintf( buf, "%s begins to slow down.", ship->name );
    echo_to_system( AT_ORANGE, ship, buf, NULL );
  }

  ship->energy -= abs( ( change - abs( ship->currspeed ) ) / 10 );
  ship->currspeed = URANGE( 0, change, ship->realspeed );
  learn_from_success( ch, gsn_spacecraft );
}

void do_trajectory( CHAR_DATA * ch, char *argument )
{
  char buf[MAX_STRING_LENGTH];
  char arg2[MAX_INPUT_LENGTH];
  char arg3[MAX_INPUT_LENGTH];
  int chance = 0;
  SHIP_DATA *ship = NULL;
  Vector3 vec;
  vector_init( &vec );

  if( ( ship = ship_from_pilotseat( ch->in_room ) ) == NULL )
  {
    send_to_char( "&RYou must be at the healm of a ship to do that!\r\n",
	ch );
    return;
  }

  if( ship->ship_class > SPACE_STATION )
  {
    send_to_char( "&RThis isn't a spacecraft!\r\n", ch );
    return;
  }

  if( autofly( ship ) )
  {
    send_to_char
      ( "&RYou'll have to turn off the ships autopilot first.\r\n", ch );
    return;
  }

  if( ship->shipstate == SHIP_DISABLED )
  {
    send_to_char( "&RThe ships drive is disabled. Unable to manuever.\r\n",
	ch );
    return;
  }

  if( ship->ship_class == SPACE_STATION )
  {
    send_to_char( "&RPlatforms can't turn!\r\n", ch );
    return;
  }

  if( ship->shipstate == SHIP_HYPERSPACE )
  {
    send_to_char( "&RYou can only do that in realspace!\r\n", ch );
    return;
  }

  if( ship->shipstate == SHIP_DOCKED )
  {
    send_to_char( "&RYou can't do that until after you've launched!\r\n",
	ch );
    return;
  }

  if( ship->shipstate != SHIP_READY )
  {
    send_to_char
      ( "&RPlease wait until the ship has finished its current maneuver.\r\n",
	ch );
    return;
  }

  if( ship->energy < ( ship->currspeed / 10 ) )
  {
    send_to_char( "&RTheres not enough fuel!\r\n", ch );
    return;
  }

  chance = character_skill_level( ch, gsn_spacecraft );

  if( number_percent() > chance )
  {
    send_to_char( "&RYou fail to work the controls properly.\r\n", ch );
    return;
  }

  argument = one_argument( argument, arg2 );
  argument = one_argument( argument, arg3 );

  vector_set( &vec, atof( arg2 ), atof( arg3 ), atof( argument ) );

  if( vector_distance( &ship->pos, &vec ) < 1 )
  {
    ch_printf( ch, "The ship is already at %.0f %.0f %.0f !",
	vec.x, vec.y, vec.z );
  }

  ship_set_course( ship, &vec );
  ship->energy -= ( ship->currspeed / 10 );

  ch_printf( ch, "&GNew course set, approaching %.0f %.0f %.0f.\r\n",
      vec.x, vec.y, vec.z );
  act( AT_PLAIN, "$n manipulates the ships controls.", ch, NULL, argument,
      TO_ROOM );

  echo_to_cockpit( AT_YELLOW, ship, "The ship begins to turn.\r\n" );
  sprintf( buf, "%s turns altering its present course.", ship->name );
  echo_to_system( AT_ORANGE, ship, buf, NULL );

  if( ship->manuever > 100 )
    ship->shipstate = SHIP_BUSY_3;
  else if( ship->manuever > 50 )
    ship->shipstate = SHIP_BUSY_2;
  else
    ship->shipstate = SHIP_BUSY;

  learn_from_success( ch, gsn_spacecraft );
}

void do_buyship( CHAR_DATA * ch, char *argument )
{
  long price = 0;
  SHIP_DATA *ship = NULL;
  SHIP_PROTOTYPE *prototype = NULL;
  char shipname[MAX_STRING_LENGTH];
  char ships_buf[MAX_STRING_LENGTH];
  char vehicles_buf[MAX_STRING_LENGTH];

  snprintf( ships_buf, MAX_STRING_LENGTH, "%s", "ships" );
  snprintf( vehicles_buf, MAX_STRING_LENGTH, "%s", "vehicles" );

  if( IS_NPC( ch ) || !ch->pcdata )
  {
    send_to_char( "&ROnly players can do that!\r\n", ch );
    return;
  }

  if( !ch->in_room ||
      ( !IS_SET( ch->in_room->room_flags, ROOM_SHIPYARD )
	&& !IS_SET( ch->in_room->room_flags, ROOM_GARAGE ) ) )
  {
    send_to_char
      ( "&RYou must be in a shipyard or garage to purchase transportation.\r\n",
	ch );
    return;
  }

  prototype = get_ship_prototype( argument );

  if( prototype == NULL )
  {
    send_to_char( "&RThat model does not exist.\r\n", ch );

    if( IS_SET( ch->in_room->room_flags, ROOM_SHIPYARD ) )
      do_prototypes( ch, ships_buf );
    else
      do_prototypes( ch, vehicles_buf );

    return;
  }

  if( IS_SET( ch->in_room->room_flags, ROOM_SHIPYARD )
      && prototype->ship_class > SPACE_STATION )
  {
    send_to_char( "&RThats not a ship prototype.\r\n", ch );
    do_prototypes( ch, ships_buf );
    return;
  }

  if( IS_SET( ch->in_room->room_flags, ROOM_GARAGE )
      && prototype->ship_class <= SPACE_STATION )
  {
    send_to_char( "&RThats not a vehicle prototype.\r\n", ch );
    do_prototypes( ch, vehicles_buf );
    return;
  }

  price = get_prototype_value( prototype );

  if( ch->gold < price )
  {
    ch_printf( ch,
	"&RThat type of ship costs %ld. You don't have enough credits!\r\n",
	price );
    return;
  }

  ch->gold -= price;
  ch_printf( ch, "&GYou pay %ld credits to purchace the ship.\r\n", price );

  act( AT_PLAIN,
      "$n walks over to a terminal and makes a credit transaction.", ch,
      NULL, argument, TO_ROOM );
  ship = make_ship( prototype );
  ship_to_room( ship, ch->in_room->vnum );
  ship->location = ch->in_room->vnum;
  ship->lastdoc = ch->in_room->vnum;
  sprintf( shipname, "%ss %s %s", ch->name, prototype->name, ship->filename );

  STRFREE( ship->owner );
  ship->owner = STRALLOC( ch->name );
  STRFREE( ship->name );
  ship->name = STRALLOC( shipname );
  save_ship( ship );
}

void do_clanbuyship( CHAR_DATA * ch, char *argument )
{
  long price;
  SHIP_DATA *ship;
  CLAN_DATA *clan;
  SHIP_PROTOTYPE *prototype;
  char shipname[MAX_STRING_LENGTH];
  char ships_buf[MAX_STRING_LENGTH];
  char vehicles_buf[MAX_STRING_LENGTH];

  snprintf( ships_buf, MAX_STRING_LENGTH, "%s", "ships" );
  snprintf( vehicles_buf, MAX_STRING_LENGTH, "%s", "vehicles" );

  if( IS_NPC( ch ) || !ch->pcdata )
  {
    send_to_char( "&ROnly players can do that!\r\n", ch );
    return;
  }
  if( !ch->pcdata->clan )
  {
    send_to_char( "&RYou aren't a member of any organizations!\r\n", ch );
    return;
  }

  clan = ch->pcdata->clan;

  if( !clan_char_has_permission( clan, ch, CLAN_PERM_BUYSHIP ) )
  {
    send_to_char
      ( "&RYour organization hasn't seen fit to bestow you with that ability.\r\n",
	ch );
    return;
  }

  if( !ch->in_room ||
      ( !IS_SET( ch->in_room->room_flags, ROOM_SHIPYARD )
	&& !IS_SET( ch->in_room->room_flags, ROOM_GARAGE ) ) )
  {
    send_to_char
      ( "&RYou must be in a shipyard or garage to purchase transportation.\r\n",
	ch );
    return;
  }


  prototype = get_ship_prototype( argument );
  if( prototype == NULL )
  {
    send_to_char( "&RThat model does not exist.\r\n", ch );
    if( IS_SET( ch->in_room->room_flags, ROOM_SHIPYARD ) )
      do_prototypes( ch, ships_buf );
    else
      do_prototypes( ch, vehicles_buf );
    return;
  }

  if( IS_SET( ch->in_room->room_flags, ROOM_SHIPYARD )
      && prototype->ship_class > SPACE_STATION )
  {
    send_to_char( "&RThats not a ship prototype.\r\n", ch );
    do_prototypes( ch, ships_buf );
    return;
  }
  if( IS_SET( ch->in_room->room_flags, ROOM_GARAGE )
      && prototype->ship_class <= SPACE_STATION )
  {
    send_to_char( "&RThats not a vehicle prototype.\r\n", ch );
    do_prototypes( ch, vehicles_buf );
    return;
  }

  price = get_prototype_value( prototype );

  if( clan->funds < price )
  {
    ch_printf( ch,
	"&RThat type of ship costs %ld. Your organization can't afford it!\r\n",
	price );
    return;
  }

  clan->funds -= price;
  ch_printf( ch,
      "&GYou pay %ld credits from clan funds to purchace the ship.\r\n",
      price );

  act( AT_PLAIN,
      "$n walks over to a terminal and makes a credit transaction.", ch,
      NULL, argument, TO_ROOM );

  ship = make_ship( prototype );
  ship_to_room( ship, ch->in_room->vnum );
  ship->location = ch->in_room->vnum;
  ship->lastdoc = ch->in_room->vnum;

  sprintf( shipname, "%s %s %s", clan->name, prototype->name,
      ship->filename );

  STRFREE( ship->owner );
  ship->owner = STRALLOC( clan->name );
  STRFREE( ship->name );
  ship->name = STRALLOC( shipname );
  save_ship( ship );

  if( ship->ship_class <= SPACE_STATION )
    clan->spacecraft++;
  else
    clan->vehicles++;
}

void do_sellship( CHAR_DATA * ch, char *argument )
{
  long price;
  SHIP_DATA *ship;

  return;

  ship = ship_in_room( ch->in_room, argument );
  if( !ship )
  {
    act( AT_PLAIN, "I see no $T here.", ch, NULL, argument, TO_CHAR );
    return;
  }

  if( str_cmp( ship->owner, ch->name ) )
  {
    send_to_char( "&RThat isn't your ship!", ch );
    return;
  }

  price = 100;

  ch->gold += ( price - price / 10 );
  ch_printf( ch, "&GYou receive %ld credits from selling your ship.\r\n",
      price - price / 10 );

  act( AT_PLAIN,
      "$n walks over to a terminal and makes a credit transaction.", ch,
      NULL, argument, TO_ROOM );

  STRFREE( ship->owner );
  ship->owner = STRALLOC( "" );
  save_ship( ship );

}

void do_info( CHAR_DATA * ch, char *argument )
{
  SHIP_DATA *ship;
  SHIP_DATA *target;

  if( ( ship = ship_from_cockpit( ch->in_room ) ) == NULL )
  {
    if( argument[0] == '\0' )
    {
      act( AT_PLAIN, "Which ship do you want info on?.", ch, NULL, NULL,
	  TO_CHAR );
      return;
    }

    ship = ship_in_room( ch->in_room, argument );
    if( !ship )
    {
      act( AT_PLAIN, "I see no $T here.", ch, NULL, argument, TO_CHAR );
      return;
    }

    target = ship;
  }
  else if( argument[0] == '\0' )
    target = ship;
  else
    target = get_ship_here( argument, ship->starsystem );

  if( target == NULL )
  {
    send_to_char
      ( "&RI don't see that here.\r\nTry the radar, or type info by itself for info on this ship.\r\n",
	ch );
    return;
  }

  ch_printf( ch, "%s%s : %s\r\n",
      target->type == PLAYER_SHIP ? "" : "MOB ",
      target->ship_class == SPACECRAFT ? model[ship->model].name :
      ( target->ship_class == SPACE_STATION ? "Space Station" :
	( target->ship_class == AIRCRAFT ? "Aircraft" :
	  ( target->ship_class == BOAT ? "Boat" :
	    ( target->ship_class == SUBMARINE ? "Submatine" :
	      ( target->ship_class ==
		LAND_VEHICLE ? "land vehicle" : "Unknown" ) ) ) ) ),
      target->name );
  ch_printf( ch, "Owner: %s   Pilot: %s   Copilot: %s\r\n", target->owner,
      target->pilot, target->copilot );
  ch_printf( ch, "Laser cannons: %d  ", target->lasers );
  ch_printf( ch, "Maximum Missiles: %d  ", target->maxmissiles );
  ch_printf( ch, "Max Chaff: %d\r\n", target->maxchaff );
  ch_printf( ch, "Max Hull: %d  ", target->maxhull );
  ch_printf( ch, "Max Shields: %d   Max Energy(fuel): %d\r\n",
      target->maxshield, target->maxenergy );
  ch_printf( ch, "Maximum Speed: %d   Hyperspeed: %d   Manuever: %d\r\n",
      target->realspeed, target->hyperspeed, target->manuever );

  act( AT_PLAIN, "$n checks various gages and displays on the control panel.",
      ch, NULL, argument, TO_ROOM );

}

void do_autorecharge( CHAR_DATA * ch, char *argument )
{
  int chance;
  SHIP_DATA *ship;
  int recharge;


  if( ( ship = ship_from_gunseat( ch->in_room ) ) == NULL )
  {
    send_to_char
      ( "&RYou must be at the shield controls of a ship to do that!\r\n",
	ch );
    return;
  }

  if( autofly( ship ) )
  {
    send_to_char
      ( "&RYou'll have to turn off the ships autopilot first.\r\n", ch );
    return;
  }

  chance = character_skill_level( ch, gsn_spacecraft );

  if( number_percent() > chance )
  {
    send_to_char( "&RYou fail to work the controls properly.\r\n", ch );
    return;
  }

  act( AT_PLAIN, "$n flips a switch on the control panel.", ch,
      NULL, argument, TO_ROOM );

  if( !str_cmp( argument, "on" ) )
  {
    ship->autorecharge = TRUE;
    send_to_char( "&GYou power up the shields.\r\n", ch );
    echo_to_cockpit( AT_YELLOW, ship, "Shields ON. Autorecharge ON." );
  }
  else if( !str_cmp( argument, "off" ) )
  {
    ship->autorecharge = FALSE;
    send_to_char( "&GYou shutdown the shields.\r\n", ch );
    echo_to_cockpit( AT_YELLOW, ship,
	"Shields OFF. Shield strength set to 0. Autorecharge OFF." );
    ship->shield = 0;
  }
  else if( !str_cmp( argument, "idle" ) )
  {
    ship->autorecharge = FALSE;
    send_to_char( "&GYou let the shields idle.\r\n", ch );
    echo_to_cockpit( AT_YELLOW, ship,
	"Autorecharge OFF. Shields IDLEING." );
  }
  else
  {
    if( ship->autorecharge == TRUE )
    {
      ship->autorecharge = FALSE;
      send_to_char( "&GYou toggle the shields.\r\n", ch );
      echo_to_cockpit( AT_YELLOW, ship,
	  "Autorecharge OFF. Shields IDLEING." );
    }
    else
    {
      ship->autorecharge = TRUE;
      send_to_char( "&GYou toggle the shields.\r\n", ch );
      echo_to_cockpit( AT_YELLOW, ship, "Shields ON. Autorecharge ON" );
    }
  }

  if( ship->autorecharge )
  {
    recharge =
      URANGE( 0, ship->maxshield - ship->shield, 20 + ship->model * 10 );
    recharge = UMIN( recharge, ship->energy * 5 + 100 );
    ship->shield += recharge;
    ship->energy -= ( recharge * 5 );
  }

  learn_from_success( ch, gsn_spacecraft );

}

void do_autopilot( CHAR_DATA * ch, char *argument )
{
  SHIP_DATA *ship;

  if( ( ship = ship_from_pilotseat( ch->in_room ) ) == NULL )
  {
    send_to_char
      ( "&RYou must be at the pilot controls of a ship to do that!\r\n",
	ch );
    return;
  }

  if( !check_pilot( ch, ship ) )
  {
    send_to_char( "&RHey! Thats not your ship!\r\n", ch );
    return;
  }

  if( ship->target )
  {
    send_to_char( "&RNot while the ship is enganged with an enemy!\r\n",
	ch );
    return;
  }


  act( AT_PLAIN, "$n flips a switch on the control panel.", ch,
      NULL, argument, TO_ROOM );

  if( ship->autopilot == TRUE )
  {
    ship->autopilot = FALSE;
    send_to_char( "&GYou toggle the autopilot.\r\n", ch );
    echo_to_cockpit( AT_YELLOW, ship, "Autopilot OFF." );
  }
  else
  {
    ship->autopilot = TRUE;
    ship->autorecharge = TRUE;
    send_to_char( "&GYou toggle the autopilot.\r\n", ch );
    echo_to_cockpit( AT_YELLOW, ship, "Autopilot ON." );
  }

}

void do_openhatch( CHAR_DATA * ch, char *argument )
{
  SHIP_DATA *ship;
  char buf[MAX_STRING_LENGTH];

  if( !argument || argument[0] == '\0' || !str_cmp( argument, "hatch" ) )
  {
    ship = ship_from_entrance( ch->in_room );
    if( ship == NULL )
    {
      send_to_char( "&ROpen what?\r\n", ch );
      return;
    }
    else
    {
      if( !ship->hatchopen )
      {

	if( ship->ship_class == SPACE_STATION )
	{
	  send_to_char( "&RTry one of the docking bays!\r\n", ch );
	  return;
	}
	if( ship->location != ship->lastdoc ||
	    ( ship->shipstate != SHIP_DOCKED
	      && ship->shipstate != SHIP_DISABLED ) )
	{
	  send_to_char( "&RPlease wait till the ship lands!\r\n",
	      ch );
	  return;
	}
	ship->hatchopen = TRUE;
	send_to_char( "&GYou open the hatch.\r\n", ch );
	act( AT_PLAIN, "$n opens the hatch.", ch, NULL, argument,
	    TO_ROOM );
	sprintf( buf, "The hatch on %s opens.", ship->name );
	echo_to_room( AT_YELLOW, get_room_index( ship->location ),
	    buf );
	return;
      }
      else
      {
	send_to_char( "&RIt's already open.\r\n", ch );
	return;
      }
    }
  }

  ship = ship_in_room( ch->in_room, argument );
  if( !ship )
  {
    act( AT_PLAIN, "I see no $T here.", ch, NULL, argument, TO_CHAR );
    return;
  }

  if( ship->shipstate != SHIP_DOCKED && ship->shipstate != SHIP_DISABLED )
  {
    send_to_char( "&RThat ship has already started to launch", ch );
    return;
  }

  if( !check_pilot( ch, ship ) )
  {
    send_to_char( "&RHey! Thats not your ship!\r\n", ch );
    return;
  }

  if( !ship->hatchopen )
  {
    ship->hatchopen = TRUE;
    act( AT_PLAIN, "You open the hatch on $T.", ch, NULL, ship->name,
	TO_CHAR );
    act( AT_PLAIN, "$n opens the hatch on $T.", ch, NULL, ship->name,
	TO_ROOM );
    echo_to_room( AT_YELLOW, ship->entrance,
	"The hatch opens from the outside." );
    return;
  }

  send_to_char( "&GIts already open!\r\n", ch );

}


void do_closehatch( CHAR_DATA * ch, char *argument )
{
  SHIP_DATA *ship;
  char buf[MAX_STRING_LENGTH];

  if( !argument || argument[0] == '\0' || !str_cmp( argument, "hatch" ) )
  {
    ship = ship_from_entrance( ch->in_room );
    if( ship == NULL )
    {
      send_to_char( "&RClose what?\r\n", ch );
      return;
    }
    else
    {

      if( ship->ship_class == SPACE_STATION )
      {
	send_to_char( "&RTry one of the docking bays!\r\n", ch );
	return;
      }
      if( ship->hatchopen )
      {
	ship->hatchopen = FALSE;
	send_to_char( "&GYou close the hatch.\r\n", ch );
	act( AT_PLAIN, "$n closes the hatch.", ch, NULL, argument,
	    TO_ROOM );
	sprintf( buf, "The hatch on %s closes.", ship->name );
	echo_to_room( AT_YELLOW, get_room_index( ship->location ),
	    buf );
	return;
      }
      else
      {
	send_to_char( "&RIt's already closed.\r\n", ch );
	return;
      }
    }
  }

  ship = ship_in_room( ch->in_room, argument );
  if( !ship )
  {
    act( AT_PLAIN, "I see no $T here.", ch, NULL, argument, TO_CHAR );
    return;
  }

  if( ship->shipstate != SHIP_DOCKED && ship->shipstate != SHIP_DISABLED )
  {
    send_to_char( "&RThat ship has already started to launch", ch );
    return;
  }
  else
  {
    if( ship->hatchopen )
    {
      ship->hatchopen = FALSE;
      act( AT_PLAIN, "You close the hatch on $T.", ch, NULL, ship->name,
	  TO_CHAR );
      act( AT_PLAIN, "$n closes the hatch on $T.", ch, NULL, ship->name,
	  TO_ROOM );
      echo_to_room( AT_YELLOW, ship->entrance,
	  "The hatch is closed from outside." );

      return;
    }
    else
    {
      send_to_char( "&RIts already closed.\r\n", ch );
      return;
    }
  }


}

void do_status( CHAR_DATA * ch, char *argument )
{
  int chance;
  SHIP_DATA *ship;
  SHIP_DATA *target;

  if( ( ship = ship_from_cockpit( ch->in_room ) ) == NULL )
  {
    send_to_char
      ( "&RYou must be in the cockpit, turret or engineroom of a ship to do that!\r\n",
	ch );
    return;
  }

  if( argument[0] == '\0' )
    target = ship;
  else
    target = get_ship_here( argument, ship->starsystem );

  if( target == NULL )
  {
    send_to_char
      ( "&RI don't see that here.\r\nTry the radar, or type status by itself for your ships status.\r\n",
	ch );
    return;
  }

  chance = character_skill_level( ch, gsn_spacecraft );

  if( number_percent() > chance )
  {
    send_to_char( "&RYou cant figure out what the readout means.\r\n", ch );
    return;
  }

  act( AT_PLAIN, "$n checks various gages and displays on the control panel.",
      ch, NULL, argument, TO_ROOM );

  ch_printf( ch, "&W%s:\r\n", target->name );
  ch_printf( ch, "&OCurrent Coordinates:&Y %.0f %.0f %.0f\r\n",
      target->pos.x, target->pos.y, target->pos.z );
  ch_printf( ch, "&OCurrent Heading:&Y %.2f %.2f %.2f\r\n",
      target->head.x, target->head.y, target->head.z );
  ch_printf( ch, "&OCurrent Speed:&Y %d&O/%d\r\n",
      target->currspeed, target->realspeed );
  ch_printf( ch, "&OHull:&Y %d&O/%d  Ship Condition:&Y %s\r\n",
      target->hull,
      target->maxhull,
      target->shipstate == SHIP_DISABLED ? "Disabled" : "Running" );
  ch_printf( ch, "&OShields:&Y %d&O/%d   Energy(fuel):&Y %d&O/%d\r\n",
      target->shield,
      target->maxshield, target->energy, target->maxenergy );
  ch_printf( ch, "&OLaser Condition:&Y %s  &OCurrent Target:&Y %s\r\n",
      target->laserstate == LASER_DAMAGED ? "Damaged" : "Good",
      target->target ? target->target->name : "none" );
  ch_printf( ch, "\r\n&OMissiles:&Y %d&O/%d  Condition:&Y %s&w\r\n",
      ship->missiles, ship->maxmissiles,
      ship->missilestate == MISSILE_DAMAGED ? "Damaged" : "Good" );

  learn_from_success( ch, gsn_spacecraft );


}

void do_hyperspace( CHAR_DATA * ch, char *argument )
{
  int chance = 0;
  SHIP_DATA *ship = 0;
  SHIP_DATA *eShip = 0;

  if( ( ship = ship_from_pilotseat( ch->in_room ) ) == NULL )
  {
    send_to_char( "&RYou must be in control of a ship to do that!\r\n",
	ch );
    return;
  }

  if( ship->ship_class > SPACE_STATION )
  {
    send_to_char( "&RThis isn't a spacecraft!\r\n", ch );
    return;
  }

  if( autofly( ship ) )
  {
    send_to_char
      ( "&RYou'll have to turn off the ships autopilot first.\r\n", ch );
    return;
  }

  if( ship->ship_class == SPACE_STATION )
  {
    send_to_char( "&RPlatforms can't move!\r\n", ch );
    return;
  }

  if( ship->hyperspeed == 0 )
  {
    send_to_char( "&RThis ship is not equipped with a hyperdrive!\r\n",
	ch );
    return;
  }

  if( ship->shipstate == SHIP_HYPERSPACE )
  {
    send_to_char( "&RYou are already travelling lightspeed!\r\n", ch );
    return;
  }

  if( ship->shipstate == SHIP_DISABLED )
  {
    send_to_char( "&RThe ships drive is disabled. Unable to manuever.\r\n",
	ch );
    return;
  }

  if( ship->shipstate == SHIP_DOCKED )
  {
    send_to_char( "&RYou can't do that until after you've launched!\r\n",
	ch );
    return;
  }

  if( ship->shipstate != SHIP_READY )
  {
    send_to_char
      ( "&RPlease wait until the ship has finished its current maneuver.\r\n",
	ch );
    return;
  }

  if( !ship->currjump )
  {
    send_to_char( "&RYou need to calculate your jump first!\r\n", ch );
    return;
  }

  if( ship->energy < ( 200 + ship->hyperdistance ) )
  {
    send_to_char( "&RTheres not enough fuel!\r\n", ch );
    return;
  }

  if( ship->currspeed <= 0 )
  {
    send_to_char( "&RYou need to speed up a little first!\r\n", ch );
    return;
  }

  if( ( eShip = find_ship_in_range( ship, 500 ) ) )
  {
    ch_printf( ch,
	"&RYou are too close to %s to make the jump to lightspeed.\r\n",
	eShip->name );
    return;
  }

  chance = character_skill_level( ch, gsn_spacecraft );

  if( number_percent() > chance )
  {
    send_to_char( "&RYou can't figure out which lever to use.\r\n", ch );
    return;
  }

  send_to_char( "&GYou push forward the hyperspeed lever.\r\n", ch );
  act( AT_PLAIN, "$n pushes a lever forward on the control panel.", ch,
      NULL, argument, TO_ROOM );

  ship_jump_to_lightspeed( ship );

  learn_from_success( ch, gsn_spacecraft );
}


void do_target( CHAR_DATA * ch, char *argument )
{
  char arg[MAX_INPUT_LENGTH];
  int chance;
  SHIP_DATA *ship;
  SHIP_DATA *target;
  char buf[MAX_STRING_LENGTH];
  TURRET_DATA *turret = NULL;

  strcpy( arg, argument );

  switch ( ch->substate )
  {
    default:
      if( ( ship = ship_from_turret( ch->in_room ) ) == NULL )
      {
	send_to_char
	  ( "&RYou must be in the gunners seat or turret of a ship to do that!\r\n",
	    ch );
	return;
      }

      if( ship->ship_class > SPACE_STATION )
      {
	send_to_char( "&RThis isn't a spacecraft!\r\n", ch );
	return;
      }

      if( ship->shipstate == SHIP_HYPERSPACE )
      {
	send_to_char( "&RYou can only do that in realspace!\r\n", ch );
	return;
      }

      if( !ship->starsystem )
      {
	send_to_char
	  ( "&RYou can't do that until you've finished launching!\r\n",
	    ch );
	return;
      }

      if( autofly( ship ) )
      {
	send_to_char
	  ( "&RYou'll have to turn off the ships autopilot first....\r\n",
	    ch );
	return;
      }

      if( arg[0] == '\0' )
      {
	send_to_char( "&RYou need to specify a target!\r\n", ch );
	return;
      }

      if( !str_cmp( arg, "none" ) )
      {
	send_to_char( "&GTarget set to none.\r\n", ch );
	ship->target = NULL;
	return;
      }

      target = get_ship_here( arg, ship->starsystem );

      if( target == NULL )
      {
	send_to_char( "&RThat ship isn't here!\r\n", ch );
	return;
      }

      if( target == ship )
      {
	send_to_char( "&RYou can't target your own ship!\r\n", ch );
	return;
      }

      if( !str_cmp( target->owner, ship->owner )
	  && str_cmp( target->owner, "" ) )
      {
	send_to_char
	  ( "&RThat ship has the same owner... try targetting an enemy ship instead!\r\n",
	    ch );
	return;
      }

      if( ship_distance_to_ship( ship, target ) > 5000 )
      {
	send_to_char( "&RThat ship is too far away to target.\r\n", ch );
	return;
      }

      chance = character_skill_level( ch, gsn_weaponsystems );

      if( number_percent() < chance )
      {
	send_to_char( "&GTracking target.\r\n", ch );
	act( AT_PLAIN,
	    "$n makes some adjustments on the targeting computer.", ch,
	    NULL, argument, TO_ROOM );
	add_timer( ch, TIMER_DO_FUN, 1, do_target, 1 );
	ch->dest_buf = str_dup( arg );
	return;
      }

      send_to_char( "&RYou fail to work the controls properly.\r\n", ch );
      learn_from_failure( ch, gsn_weaponsystems );
      return;

    case 1:
      if( !ch->dest_buf )
	return;
      strcpy( arg, ( const char * ) ch->dest_buf );
      DISPOSE( ch->dest_buf );
      break;

    case SUB_TIMER_DO_ABORT:
      DISPOSE( ch->dest_buf );
      ch->substate = SUB_NONE;
      send_to_char
	( "&RYour concentration is broken. You fail to lock onto your target.\r\n",
	  ch );
      return;
  }

  ch->substate = SUB_NONE;

  if( ( ship = ship_from_turret( ch->in_room ) ) == NULL )
  {
    return;
  }

  target = get_ship_here( arg, ship->starsystem );

  if( target == NULL || target == ship )
  {
    send_to_char
      ( "&RThe ship has left the starsytem. Targeting aborted.\r\n", ch );
    return;
  }

  if( ch->in_room == ship->gunseat )
  {
    ship->target = target;
  }
  else
  {
    for( turret = ship->first_turret; turret; turret = turret->next )
      if( turret->room == ch->in_room )
	break;

    if( !turret )
      return;

    turret->target = target;
  }

  send_to_char( "&GTarget Locked.\r\n", ch );
  sprintf( buf, "You are being targetted by %s.", ship->name );
  echo_to_cockpit( AT_BLOOD, target, buf );

  learn_from_success( ch, gsn_weaponsystems );

  if( autofly( target ) && !target->target )
  {
    ship_acquire_target( target, ship );
  }
}

void do_fire( CHAR_DATA * ch, char *argument )
{
  int chance = 0;
  SHIP_DATA *ship = NULL;
  SHIP_DATA *target = NULL;
  TURRET_DATA *turret = NULL;
  int skill_level = 0;

  if( ( ship = ship_from_turret( ch->in_room ) ) == NULL )
  {
    send_to_char
      ( "&RYou must be in the gunners chair or turret of a ship to do that!\r\n",
	ch );
    return;
  }

  if( ship->ship_class > SPACE_STATION )
  {
    send_to_char( "&RThis isn't a spacecraft!\r\n", ch );
    return;
  }

  if( ship->shipstate == SHIP_HYPERSPACE )
  {
    send_to_char( "&RYou can only do that in realspace!\r\n", ch );
    return;
  }

  if( ship->starsystem == NULL )
  {
    send_to_char
      ( "&RYou can't do that until after you've finished launching!\r\n",
	ch );
    return;
  }

  if( ship->energy < 5 )
  {
    send_to_char( "&RTheres not enough energy left to fire!\r\n", ch );
    return;
  }

  if( autofly( ship ) )
  {
    send_to_char
      ( "&RYou'll have to turn off the ships autopilot first.\r\n", ch );
    return;
  }

  skill_level = character_skill_level( ch, gsn_weaponsystems )
    + ch->perm_dex * 2 + character_skill_level( ch, gsn_spacecombat ) / 2;

  chance = IS_NPC( ch ) ? 100 : skill_level;

  if( !str_prefix( argument, "lasers" ) )
  {
    if( ch->in_room == ship->gunseat )
    {
      if( !laser_can_be_fired( ch, ship ) )
      {
	return;
      }

      target = ship->target;
    }
    else
    {
      for( turret = ship->first_turret; turret; turret = turret->next )
	if( turret->room == ch->in_room )
	  break;

      if( !turret )
      {
	send_to_char( "&RThis turret is out of order.\r\n", ch );
	return;
      }

      if( !turret_can_be_fired( ch, turret ) )
      {
	return;
      }

      target = turret->target;
    }

    if( target->starsystem != ship->starsystem )
    {
      send_to_char( "&RYour target seems to have left.\r\n", ch );
      ship->target = NULL;
      return;
    }

    if( ship_distance_to_ship( target, ship ) > 1000 )
    {
      send_to_char( "&RThat ship is out of laser range.\r\n", ch );
      return;
    }

    if( ship->ship_class < SPACE_STATION
	&& !ship_is_facing_ship( ship, target ) && !turret )
    {
      send_to_char
	( "&RThe main laser can only fire forward. You'll need to turn your ship!\r\n",
	  ch );
      return;
    }

    if( ch->in_room == ship->gunseat )
      ship->laserstate++;
    else
      turret->laserstate++;

    chance += laser_hit_modifier( ship, target );

    act( AT_PLAIN, "$n presses the fire button.", ch,
	NULL, argument, TO_ROOM );

    if( !laserfire_hits( ship, target, chance ) )
    {
      return;
    }

    learn_from_success( ch, gsn_spacecombat );

    if( turret )
      damage_ship( target, 15, 25, ch );
    else
      damage_ship( target, 5, 10, ch );

    if( target->starsystem && autofly( target ) && target->target != ship )
    {
      ship_acquire_target( target, ship );
    }

    return;
  }

  if( !str_prefix( argument, "missile" ) )
  {
    if( !missile_launcher_can_be_fired( ch, ship ) )
    {
      return;
    }

    target = ship->target;

    if( ship->target->starsystem != ship->starsystem )
    {
      send_to_char( "&RYour target seems to have left.\r\n", ch );
      ship->target = NULL;
      return;
    }

    if( ship_distance_to_ship( ship, target ) > 1000 )
    {
      send_to_char( "&RThat ship is out of missile range.\r\n", ch );
      return;
    }

    if( ship->ship_class < SPACE_STATION
	&& !ship_is_facing_ship( ship, target ) )
    {
      send_to_char
	( "&RMissiles can only fire in a forward. You'll need to turn your ship!\r\n",
	  ch );
      return;
    }

    chance += missile_hit_modifier( ship, target );

    act( AT_PLAIN, "$n presses the fire button.", ch,
	NULL, argument, TO_ROOM );

    if( number_percent() > chance )
    {
      send_to_char( "&RYou fail to lock onto your target!", ch );
      ship->missilestate = MISSILE_RELOAD_2;
      return;
    }

    echo_to_cockpit( AT_YELLOW, ship, "Missiles launched." );
    ship_fire_missile( ship, target );
    learn_from_success( ch, gsn_weaponsystems );

    if( ship->ship_class == SPACE_STATION )
      ship->missilestate = MISSILE_RELOAD;
    else
      ship->missilestate = MISSILE_FIRED;

    if( autofly( target ) && target->target != ship )
    {
      ship_acquire_target( target, ship );
    }

    return;
  }

  send_to_char( "&RYou can't fire that!\r\n", ch );
}


void do_calculate( CHAR_DATA * ch, char *argument )
{
  char arg1[MAX_INPUT_LENGTH];
  char arg2[MAX_INPUT_LENGTH];
  char arg3[MAX_INPUT_LENGTH];
  int chance = 0, count = 0;
  SHIP_DATA *ship = NULL;
  PLANET_DATA *planet = NULL;

  argument = one_argument( argument, arg1 );
  argument = one_argument( argument, arg2 );
  argument = one_argument( argument, arg3 );

  if( ( ship = ship_from_pilotseat( ch->in_room ) ) == NULL )
  {
    send_to_char( "&RYou must be in control of a ship to do that!\r\n",
	ch );
    return;
  }

  if( ship->ship_class > SPACE_STATION )
  {
    send_to_char( "&RThis isn't a spacecraft!\r\n", ch );
    return;
  }

  if( autofly( ship ) )
  {
    send_to_char
      ( "&RYou'll have to turn off the ships autopilot first....\r\n", ch );
    return;
  }

  if( ship->ship_class == SPACE_STATION )
  {
    send_to_char( "&RAnd what exactly are you going to calculate...?\r\n",
	ch );
    return;
  }

  if( ship->hyperspeed == 0 )
  {
    send_to_char( "&RThis ship is not equipped with a hyperdrive!\r\n",
	ch );
    return;
  }

  if( ship->shipstate == SHIP_DOCKED )
  {
    send_to_char( "&RYou can't do that until after you've launched!\r\n",
	ch );
    return;
  }

  if( ship->starsystem == NULL )
  {
    send_to_char( "&RYou can only do that in realspace.\r\n", ch );
    return;
  }

  if( argument[0] == '\0' )
  {
    SPACE_DATA *starsystem = NULL;
    send_to_char
      ( "&WFormat: Calculate <starsystem> <entry x> <entry y> <entry z>\r\n&wPossible destinations:\r\n",
	ch );
    for( starsystem = first_starsystem; starsystem;
	starsystem = starsystem->next )
    {
      set_char_color( AT_NOTE, ch );
      ch_printf( ch, "%s ----- ", starsystem->name );
      count++;
    }
    if( !count )
    {
      send_to_char( "No Starsystems found.\r\n", ch );
    }
    return;
  }
  chance = character_skill_level( ch, gsn_spacecraft );

  if( number_percent() > chance )
  {
    send_to_char( "&RYou cant seem to figure the charts out today.\r\n",
	ch );
    return;
  }

  ship->currjump = starsystem_from_name( arg1 );
  vector_set( &ship->jump, atoi( arg2 ), atoi( arg3 ), atoi( argument ) );

  if( ship->currjump == NULL )
  {
    send_to_char
      ( "&RYou can't seem to find that starsytem on your charts.\r\n", ch );
    return;
  }
  else
  {
    SPACE_DATA *starsystem = ship->currjump;

    if( starsystem->star1 && strcmp( starsystem->star1, "" ) &&
	vector_distance( &ship->jump, &starsystem->star1_pos ) < 300 )
    {
      echo_to_cockpit( AT_RED, ship,
	  "WARNING.. Jump coordinates too close to stellar object." );
      echo_to_cockpit( AT_RED, ship, "WARNING.. Hyperjump NOT set." );
      ship->currjump = NULL;
      return;
    }
    else if( starsystem->star2 && strcmp( starsystem->star2, "" ) &&
	vector_distance( &ship->jump, &starsystem->star2_pos ) < 300 )
    {
      echo_to_cockpit( AT_RED, ship,
	  "WARNING.. Jump coordinates too close to stellar object." );
      echo_to_cockpit( AT_RED, ship, "WARNING.. Hyperjump NOT set." );
      ship->currjump = NULL;
      return;
    }

    for( planet = starsystem->first_planet; planet;
	planet = planet->next_in_system )
      if( vector_distance( &ship->jump, &planet->pos ) < 300 )
      {
	echo_to_cockpit( AT_RED, ship,
	    "WARNING.. Jump coordinates too close to stellar object." );
	echo_to_cockpit( AT_RED, ship, "WARNING.. Hyperjump NOT set." );
	ship->currjump = NULL;
	return;
      }

    vector_randomize( &ship->jump, -250, 250 );
  }

  if( ship->starsystem == ship->currjump )
    ship->hyperdistance = number_range( 0, 200 );
  else
    ship->hyperdistance = number_range( 500, 1000 );

  send_to_char
    ( "&GHyperspace course set. Ready for the jump to lightspeed.\r\n", ch );
  act( AT_PLAIN, "$n does some calculations using the ships computer.", ch,
      NULL, argument, TO_ROOM );

  learn_from_success( ch, gsn_spacecraft );
  WAIT_STATE( ch, 2 * PULSE_VIOLENCE );
}

void do_recharge( CHAR_DATA * ch, char *argument )
{
  int recharge;
  int chance;
  SHIP_DATA *ship;


  if( ( ship = ship_from_gunseat( ch->in_room ) ) == NULL )
  {
    send_to_char
      ( "&RYou must be at the shield controls of a ship to do that!\r\n",
	ch );
    return;
  }

  if( autofly( ship ) )
  {
    send_to_char( "&R...\r\n", ch );
    return;
  }

  if( ship->shipstate == SHIP_DISABLED )
  {
    send_to_char( "&RThe ships drive is disabled. Unable to manuever.\r\n",
	ch );
    return;
  }

  if( ship->energy < 100 )
  {
    send_to_char( "&RTheres not enough energy!\r\n", ch );
    return;
  }

  chance = character_skill_level( ch, gsn_spacecraft );

  if( number_percent() > chance )
  {
    send_to_char( "&RYou fail to work the controls properly.\r\n", ch );
    return;
  }

  send_to_char( "&GRecharging shields..\r\n", ch );
  act( AT_PLAIN, "$n pulls back a lever on the control panel.", ch,
      NULL, argument, TO_ROOM );

  learn_from_success( ch, gsn_spacecraft );

  recharge = UMIN( ship->maxshield - ship->shield, ship->energy * 5 + 100 );
  recharge = URANGE( 0, recharge, 20 + ship->model * 10 );
  ship->shield += recharge;
  ship->energy -= ( recharge * 5 );
}


void do_repairship( CHAR_DATA * ch, char *argument )
{
  char arg[MAX_INPUT_LENGTH];
  int chance, change;
  SHIP_DATA *ship;

  strcpy( arg, argument );

  switch ( ch->substate )
  {
    default:
      if( ( ship = ship_from_engine( ch->in_room ) ) == NULL )
      {
	send_to_char
	  ( "&RYou must be in the engine room of a ship to do that!\r\n",
	    ch );
	return;
      }

      if( str_cmp( argument, "hull" ) && str_cmp( argument, "drive" ) &&
	  str_cmp( argument, "launcher" ) && str_cmp( argument, "laser" ) )
      {
	send_to_char( "&RYou need to spceify something to repair:\r\n",
	    ch );
	send_to_char( "&rTry: hull, drive, launcher, laser\r\n", ch );
	return;
      }

      chance = character_skill_level( ch, gsn_shipmaintenance );

      if( number_percent() < chance )
      {
	send_to_char( "&GYou begin your repairs\r\n", ch );
	act( AT_PLAIN, "$n begins repairing the ships $T.", ch,
	    NULL, argument, TO_ROOM );
	if( !str_cmp( arg, "hull" ) )
	  add_timer( ch, TIMER_DO_FUN, 15, do_repairship, 1 );
	else
	  add_timer( ch, TIMER_DO_FUN, 5, do_repairship, 1 );
	ch->dest_buf = str_dup( arg );
	return;
      }
      send_to_char( "&RYou fail to locate the source of the problem.\r\n",
	  ch );
      return;

    case 1:
      if( !ch->dest_buf )
	return;
      strcpy( arg, ( const char * ) ch->dest_buf );
      DISPOSE( ch->dest_buf );
      break;

    case SUB_TIMER_DO_ABORT:
      DISPOSE( ch->dest_buf );
      ch->substate = SUB_NONE;
      send_to_char
	( "&RYou are distracted and fail to finish your repairs.\r\n", ch );
      return;
  }

  ch->substate = SUB_NONE;

  if( ( ship = ship_from_engine( ch->in_room ) ) == NULL )
  {
    return;
  }

  if( !str_cmp( arg, "hull" ) )
  {
    change = URANGE( 0,
	number_range( character_skill_level
	  ( ch, gsn_shipmaintenance ) / 2,
	  character_skill_level( ch,
	    gsn_shipmaintenance ) ),
	( ship->maxhull - ship->hull ) );
    ship->hull += change;
    ch_printf( ch,
	"&GRepair complete. Hull strength increased by %d points.\r\n",
	change );
  }

  if( !str_cmp( arg, "drive" ) )
  {
    if( ship->location == ship->lastdoc )
      ship->shipstate = SHIP_DOCKED;
    else
      ship->shipstate = SHIP_READY;
    send_to_char( "&GShips drive repaired.\r\n", ch );
  }

  if( !str_cmp( arg, "launcher" ) )
  {
    ship->missilestate = MISSILE_READY;
    send_to_char( "&GMissile launcher repaired.\r\n", ch );
  }

  if( !str_cmp( arg, "laser" ) )
  {
    ship->laserstate = LASER_READY;
    send_to_char( "&GMain laser repaired.\r\n", ch );
  }

  act( AT_PLAIN, "$n finishes the repairs.", ch, NULL, argument, TO_ROOM );

  learn_from_success( ch, gsn_shipmaintenance );

}


void do_addpilot( CHAR_DATA * ch, char *argument )
{
  SHIP_DATA *ship;

  if( ( ship = ship_from_cockpit( ch->in_room ) ) == NULL )
  {
    send_to_char( "&RYou must be in the cockpit of a ship to do that!\r\n",
	ch );
    return;
  }

  if( ship->ship_class == SPACE_STATION )
  {
    send_to_char( "&RYou can't do that here.\r\n", ch );
    return;
  }

  if( str_cmp( ship->owner, ch->name ) )
  {

    if( !IS_NPC( ch ) && ch->pcdata && ch->pcdata->clan
	&& !str_cmp( ch->pcdata->clan->name, ship->owner ) )
      if( clan_char_is_leader( ch->pcdata->clan, ch ) )
	;
      else
      {
	send_to_char( "&RThat isn't your ship!", ch );
	return;
      }
    else
    {
      send_to_char( "&RThat isn't your ship!", ch );
      return;
    }

  }

  if( argument[0] == '\0' )
  {
    send_to_char( "&RAdd which pilot?\r\n", ch );
    return;
  }

  if( str_cmp( ship->pilot, "" ) )
  {
    if( str_cmp( ship->copilot, "" ) )
    {
      send_to_char( "&RYou are ready have a pilot and copilot..\r\n",
	  ch );
      send_to_char( "&RTry rempilot first.\r\n", ch );
      return;
    }

    STRFREE( ship->copilot );
    ship->copilot = STRALLOC( argument );
    send_to_char( "Copilot Added.\r\n", ch );
    save_ship( ship );
    return;

    return;
  }

  STRFREE( ship->pilot );
  ship->pilot = STRALLOC( argument );
  send_to_char( "Pilot Added.\r\n", ch );
  save_ship( ship );

}

void do_rempilot( CHAR_DATA * ch, char *argument )
{
  SHIP_DATA *ship;

  if( ( ship = ship_from_cockpit( ch->in_room ) ) == NULL )
  {
    send_to_char( "&RYou must be in the cockpit of a ship to do that!\r\n",
	ch );
    return;
  }

  if( ship->ship_class == SPACE_STATION )
  {
    send_to_char( "&RYou can't do that here.\r\n", ch );
    return;
  }

  if( str_cmp( ship->owner, ch->name ) )
  {

    if( !IS_NPC( ch ) && ch->pcdata && ch->pcdata->clan
	&& !str_cmp( ch->pcdata->clan->name, ship->owner ) )
      if( clan_char_is_leader( ch->pcdata->clan, ch ) )
	;
      else
      {
	send_to_char( "&RThat isn't your ship!", ch );
	return;
      }
    else
    {
      send_to_char( "&RThat isn't your ship!", ch );
      return;
    }

  }

  if( argument[0] == '\0' )
  {
    send_to_char( "&RRemove which pilot?\r\n", ch );
    return;
  }

  if( !str_cmp( ship->pilot, argument ) )
  {
    STRFREE( ship->pilot );
    ship->pilot = STRALLOC( "" );
    send_to_char( "Pilot Removed.\r\n", ch );
    save_ship( ship );
    return;
  }

  if( !str_cmp( ship->copilot, argument ) )
  {
    STRFREE( ship->copilot );
    ship->copilot = STRALLOC( "" );
    send_to_char( "Copilot Removed.\r\n", ch );
    save_ship( ship );
    return;
  }

  send_to_char( "&RThat person isn't listed as one of the ships pilots.\r\n",
      ch );

}

void do_radar( CHAR_DATA * ch, char *argument )
{
  SHIP_DATA *target = NULL;
  int chance = 0;
  SHIP_DATA *ship = NULL;
  MISSILE_DATA *missile = NULL;
  PLANET_DATA *planet = NULL;

  if( ( ship = ship_from_cockpit( ch->in_room ) ) == NULL )
  {
    send_to_char
      ( "&RYou must be in the cockpit or turret of a ship to do that!\r\n",
	ch );
    return;
  }

  if( ship->ship_class > SPACE_STATION )
  {
    send_to_char( "&RThis isn't a spacecraft!\r\n", ch );
    return;
  }

  if( ship->shipstate == SHIP_DOCKED )
  {
    send_to_char( "&RWait until after you launch!\r\n", ch );
    return;
  }

  if( ship->shipstate == SHIP_HYPERSPACE )
  {
    send_to_char( "&RYou can only do that in realspace!\r\n", ch );
    return;
  }

  if( ship->starsystem == NULL )
  {
    send_to_char
      ( "&RYou can't do that unless the ship is flying in realspace!\r\n",
	ch );
    return;
  }

  chance = character_skill_level( ch, gsn_spacecraft );

  if( number_percent() > chance )
  {
    send_to_char( "&RYou fail to work the controls properly.\r\n", ch );
    return;
  }

  act( AT_PLAIN, "$n checks the radar.", ch, NULL, argument, TO_ROOM );

  set_char_color( AT_WHITE, ch );
  ch_printf( ch, "%s\r\n\r\n", ship->starsystem->name );

  if( ship->starsystem->star1 && str_cmp( ship->starsystem->star1, "" ) )
    ch_printf( ch, "&Y%s   %.0f %.0f %.0f [Distance %.0f]\r\n",
	ship->starsystem->star1,
	ship->starsystem->star1_pos.x,
	ship->starsystem->star1_pos.y,
	ship->starsystem->star1_pos.z,
	vector_distance( &ship->pos, &ship->starsystem->star1_pos ) );

  if( ship->starsystem->star2 && str_cmp( ship->starsystem->star2, "" ) )
    ch_printf( ch, "&Y%s   %.0f %.0f %.0f [Distance %.0f]\r\n",
	ship->starsystem->star2,
	ship->starsystem->star2_pos.x,
	ship->starsystem->star2_pos.y,
	ship->starsystem->star2_pos.z,
	vector_distance( &ship->pos, &ship->starsystem->star2_pos ) );

  for( planet = ship->starsystem->first_planet; planet;
      planet = planet->next_in_system )
    ch_printf( ch, "&G%s   %.0f %.0f %.0f [Distance %.0f]\r\n",
	planet->name,
	planet->pos.x,
	planet->pos.y,
	planet->pos.z, ship_distance_to_planet( ship, planet ) );
  ch_printf( ch, "\r\n" );

  for( target = ship->starsystem->first_ship;
      target; target = target->next_in_starsystem )
  {
    if( target != ship )
      ch_printf( ch, "&C%s    %.0f %.0f %.0f [Distance %.0f]\r\n",
	  target->name,
	  target->pos.x,
	  target->pos.y,
	  target->pos.z, ship_distance_to_ship( ship, target ) );
  }

  ch_printf( ch, "\r\n" );

  for( missile = ship->starsystem->first_missile; missile;
      missile = missile->next_in_starsystem )
  {
    ch_printf( ch, "&RA Missile    %.0f %.0f %.0f [Distance %.0f]\r\n",
	missile->pos.x,
	missile->pos.y,
	missile->pos.z, missile_distance_to_ship( missile, ship ) );
  }

  ch_printf( ch, "\r\n&WYour Coordinates: %.0f %.0f %.0f\r\n",
      ship->pos.x, ship->pos.y, ship->pos.z );

  learn_from_success( ch, gsn_spacecraft );
}

void do_autotrack( CHAR_DATA * ch, char *argument )
{
  SHIP_DATA *ship;
  int chance;

  if( ( ship = ship_from_pilotseat( ch->in_room ) ) == NULL )
  {
    send_to_char( "&RYou must be at the controls of a ship to do that!\r\n",
	ch );
    return;
  }

  if( ship->ship_class > SPACE_STATION )
  {
    send_to_char( "&RThis isn't a spacecraft!\r\n", ch );
    return;
  }


  if( ship->ship_class == SPACE_STATION )
  {
    send_to_char( "&RSpace Stations don't have autotracking systems!\r\n",
	ch );
    return;
  }

  if( autofly( ship ) )
  {
    send_to_char
      ( "&RYou'll have to turn off the ships autopilot first....\r\n", ch );
    return;
  }

  chance = character_skill_level( ch, gsn_spacecraft );
  if( number_percent() > chance )
  {
    send_to_char( "&RYour notsure which switch to flip.\r\n", ch );
    return;
  }

  act( AT_PLAIN, "$n flips a switch on the control panel.", ch,
      NULL, argument, TO_ROOM );
  if( ship->autotrack )
  {
    ship->autotrack = FALSE;
    echo_to_cockpit( AT_YELLOW, ship, "Autotracking off." );
  }
  else
  {
    ship->autotrack = TRUE;
    echo_to_cockpit( AT_YELLOW, ship, "Autotracking on." );
  }

  learn_from_success( ch, gsn_spacecraft );

}

void do_closebay( CHAR_DATA * ch, char *argument )
{
}
void do_openbay( CHAR_DATA * ch, char *argument )
{
}

void do_tractorbeam( CHAR_DATA * ch, char *argument )
{
}

void do_fly( CHAR_DATA * ch, char *argument )
{
}

void do_drive( CHAR_DATA * ch, char *argument )
{
  int dir;
  SHIP_DATA *ship;

  if( ( ship = ship_from_pilotseat( ch->in_room ) ) == NULL )
  {
    send_to_char
      ( "&RYou must be in the drivers seat of a land vehicle to do that!\r\n",
	ch );
    return;
  }

  if( ship->ship_class != LAND_VEHICLE )
  {
    send_to_char( "&RThis isn't a land vehicle!\r\n", ch );
    return;
  }


  if( ship->shipstate == SHIP_DISABLED )
  {
    send_to_char( "&RThe drive is disabled.\r\n", ch );
    return;
  }

  if( ship->energy < 1 )
  {
    send_to_char( "&RTheres not enough fuel!\r\n", ch );
    return;
  }

  if( ( dir = get_door( argument ) ) == -1 )
  {
    send_to_char( "Usage: drive <direction>\r\n", ch );
    return;
  }

  drive_ship( ch, ship, get_exit( get_room_index( ship->location ), dir ),
      0 );

}

ch_ret drive_ship( CHAR_DATA * ch, SHIP_DATA * ship, EXIT_DATA * pexit,
    int fall )
{
  ROOM_INDEX_DATA *in_room = NULL;
  ROOM_INDEX_DATA *to_room = NULL;
  ROOM_INDEX_DATA *from_room = NULL;
  ROOM_INDEX_DATA *original = NULL;
  char buf[MAX_STRING_LENGTH];
  const char *txt = NULL;
  const char *dtxt = NULL;
  ch_ret retcode = rNONE;
  short door = 0, distance = 0;
  bool drunk = FALSE;
  CHAR_DATA *rch = NULL;
  CHAR_DATA *next_rch = NULL;

  if( !IS_NPC( ch ) )
    if( IS_DRUNK( ch, 2 ) && ( ch->position != POS_SHOVE )
	&& ( ch->position != POS_DRAG ) )
      drunk = TRUE;

  if( drunk && !fall )
  {
    door = number_door();
    pexit = get_exit( get_room_index( ship->location ), door );
  }

#ifdef DEBUG
  if( pexit )
  {
    sprintf( buf, "drive_ship: %s to door %d", ch->name, pexit->vdir );
    log_string( buf );
  }
#endif

  in_room = get_room_index( ship->location );
  from_room = in_room;

  if( !pexit || ( to_room = pexit->to_room ) == NULL )
  {
    if( drunk )
      send_to_char( "You drive into a wall in your drunken state.\r\n",
	  ch );
    else
      send_to_char( "Alas, you cannot go that way.\r\n", ch );
    return rNONE;
  }

  door = pexit->vdir;
  distance = pexit->distance;

  if( IS_SET( pexit->exit_info, EX_WINDOW )
      && !IS_SET( pexit->exit_info, EX_ISDOOR ) )
  {
    send_to_char( "Alas, you cannot go that way.\r\n", ch );
    return rNONE;
  }

  if( IS_SET( pexit->exit_info, EX_PORTAL ) && IS_NPC( ch ) )
  {
    act( AT_PLAIN, "Mobs can't use portals.", ch, NULL, NULL, TO_CHAR );
    return rNONE;
  }

  if( IS_SET( pexit->exit_info, EX_NOMOB ) && IS_NPC( ch ) )
  {
    act( AT_PLAIN, "Mobs can't enter there.", ch, NULL, NULL, TO_CHAR );
    return rNONE;
  }

  if( IS_SET( pexit->exit_info, EX_CLOSED )
      && ( IS_SET( pexit->exit_info, EX_NOPASSDOOR ) ) )
  {
    if( !IS_SET( pexit->exit_info, EX_SECRET )
	&& !IS_SET( pexit->exit_info, EX_DIG ) )
    {
      if( drunk )
      {
	act( AT_PLAIN, "$n drives into the $d in $s drunken state.",
	    ch, NULL, pexit->keyword, TO_ROOM );
	act( AT_PLAIN, "You drive into the $d in your drunken state.",
	    ch, NULL, pexit->keyword, TO_CHAR );
      }
      else
	act( AT_PLAIN, "The $d is closed.", ch, NULL,
	    pexit->keyword, TO_CHAR );
    }
    else
    {
      if( drunk )
	send_to_char( "You hit a wall in your drunken state.\r\n", ch );
      else
	send_to_char( "Alas, you cannot go that way.\r\n", ch );
    }

    return rNONE;
  }

  if( room_is_private( ch, to_room ) )
  {
    send_to_char( "That room is private right now.\r\n", ch );
    return rNONE;
  }

  if( !fall )
  {
    if( IS_SET( to_room->room_flags, ROOM_INDOORS )
	|| IS_SET( to_room->room_flags, ROOM_SPACECRAFT )
	|| to_room->sector_type == SECT_INSIDE )
    {
      send_to_char( "You can't drive indoors!\r\n", ch );
      return rNONE;
    }

    if( in_room->sector_type == SECT_AIR
	|| to_room->sector_type == SECT_AIR
	|| IS_SET( pexit->exit_info, EX_FLY ) )
    {
      if( ship->ship_class > AIRCRAFT )
      {
	send_to_char( "You'd need to fly to go there.\r\n", ch );
	return rNONE;
      }
    }

    if( in_room->sector_type == SECT_WATER_NOSWIM
	|| to_room->sector_type == SECT_WATER_NOSWIM
	|| to_room->sector_type == SECT_WATER_SWIM
	|| to_room->sector_type == SECT_UNDERWATER
	|| to_room->sector_type == SECT_OCEANFLOOR )
    {
      if( ship->ship_class != BOAT && ship->ship_class != SUBMARINE )
      {
	send_to_char( "You'd need a boat to go there.\r\n", ch );
	return rNONE;
      }
    }

    if( to_room->sector_type == SECT_UNDERWATER
	|| to_room->sector_type == SECT_OCEANFLOOR )
    {
      if( ship->ship_class != SUBMARINE )
      {
	send_to_char( "You'd need a submarine to go there.\r\n", ch );
	return rNONE;
      }
    }

    if( IS_SET( pexit->exit_info, EX_CLIMB ) )
    {
      if( ship->ship_class > AIRCRAFT )
      {
	send_to_char( "You need to fly or climb to get up there.\r\n",
	    ch );
	return rNONE;
      }
    }
  }

  if( to_room->tunnel > 0 )
  {
    CHAR_DATA *ctmp;
    int count = 0;

    for( ctmp = to_room->first_person; ctmp; ctmp = ctmp->next_in_room )
      if( ++count >= to_room->tunnel )
      {
	send_to_char( "There is no room for you in there.\r\n", ch );
	return rNONE;
      }
  }

  if( fall )
    txt = "falls";
  else if( !txt )
  {
    if( ship->ship_class < BOAT )
      txt = "fly";
    else if( ship->ship_class <= SUBMARINE )
    {
      txt = "float";
    }
    else if( ship->ship_class > SUBMARINE )
    {
      txt = "drive";
    }
  }

  sprintf( buf, "$n %ss the vehicle $T.", txt );
  act( AT_ACTION, buf, ch, NULL, dir_name[door], TO_ROOM );
  sprintf( buf, "You %s the vehicle $T.", txt );
  act( AT_ACTION, buf, ch, NULL, dir_name[door], TO_CHAR );
  sprintf( buf, "%s %ss %s.", ship->name, txt, dir_name[door] );
  echo_to_room( AT_ACTION, get_room_index( ship->location ), buf );

  extract_ship( ship );
  ship_to_room( ship, to_room->vnum );
  ship->location = to_room->vnum;
  ship->lastdoc = ship->location;

  if( fall )
    txt = "falls";
  else if( ship->ship_class < BOAT )
    txt = "flys in";
  else if( ship->ship_class < LAND_VEHICLE )
  {
    txt = "floats in";
  }
  else if( ship->ship_class == LAND_VEHICLE )
  {
    txt = "drives in";
  }

  switch ( door )
  {
    default:
      dtxt = "somewhere";
      break;

    case 0:
      dtxt = "the south";
      break;

    case 1:
      dtxt = "the west";
      break;

    case 2:
      dtxt = "the north";
      break;

    case 3:
      dtxt = "the east";
      break;

    case 4:
      dtxt = "below";
      break;

    case 5:
      dtxt = "above";
      break;

    case 6:
      dtxt = "the south-west";
      break;

    case 7:
      dtxt = "the south-east";
      break;

    case 8:
      dtxt = "the north-west";
      break;

    case 9:
      dtxt = "the north-east";
      break;
  }

  sprintf( buf, "%s %s from %s.", ship->name, txt, dtxt );
  echo_to_room( AT_ACTION, get_room_index( ship->location ), buf );

  for( rch = ch->in_room->last_person; rch; rch = next_rch )
  {
    next_rch = rch->prev_in_room;
    original = rch->in_room;
    char_from_room( rch );
    char_to_room( rch, to_room );
    do_look( rch, STRLIT_AUTO );
    char_from_room( rch );
    char_to_room( rch, original );
  }

  return retcode;
}

void do_bomb( CHAR_DATA * ch, char *argument )
{
}

void do_chaff( CHAR_DATA * ch, char *argument )
{
  int chance;
  SHIP_DATA *ship;


  if( ( ship = ship_from_gunseat( ch->in_room ) ) == NULL )
  {
    send_to_char
      ( "&RYou must be at the weapon controls of a ship to do that!\r\n",
	ch );
    return;
  }

  if( ship->ship_class > SPACE_STATION )
  {
    send_to_char( "&RThis isn't a spacecraft!\r\n", ch );
    return;
  }


  if( autofly( ship ) )
  {
    send_to_char( "&RYou'll have to turn the autopilot off first...\r\n",
	ch );
    return;
  }

  if( ship->shipstate == SHIP_HYPERSPACE )
  {
    send_to_char( "&RYou can only do that in realspace!\r\n", ch );
    return;
  }
  if( ship->shipstate == SHIP_DOCKED )
  {
    send_to_char( "&RYou can't do that until after you've launched!\r\n",
	ch );
    return;
  }
  if( ship->chaff <= 0 )
  {
    send_to_char( "&RYou don't have any chaff to release!\r\n", ch );
    return;
  }

  chance = character_skill_level( ch, gsn_weaponsystems );

  if( number_percent() > chance )
  {
    send_to_char( "&RYou can't figure out which switch it is.\r\n", ch );
    return;
  }

  ship->chaff--;

  ship->chaff_released++;

  send_to_char( "You flip the chaff release switch.\r\n", ch );
  act( AT_PLAIN, "$n flips a switch on the control pannel", ch,
      NULL, argument, TO_ROOM );
  echo_to_cockpit( AT_YELLOW, ship,
      "A burst of chaff is released from the ship." );

  learn_from_success( ch, gsn_weaponsystems );

}

bool autofly( SHIP_DATA * ship )
{
  return ship->type == MOB_SHIP || ship->autopilot;
}

void do_rentship( CHAR_DATA * ch, char *argument )
{
}

SHIP_DATA *ship_create( void )
{
  size_t n = 0;
  SHIP_DATA *s = NULL;
  CREATE( s, SHIP_DATA, 1 );

  s->next = NULL;
  s->prev = NULL;
  s->next_in_starsystem = NULL;
  s->prev_in_starsystem = NULL;
  s->next_in_room = NULL;
  s->prev_in_room = NULL;
  s->in_room = NULL;
  s->first_room = NULL;
  s->last_room = NULL;
  s->pilotseat = NULL;
  s->gunseat = NULL;
  s->viewscreen = NULL;
  s->engine = NULL;
  s->entrance = NULL;
  s->starsystem = NULL;
  s->first_turret = NULL;
  s->last_turret = NULL;
  s->first_hangar = NULL;
  s->last_hangar = NULL;
  s->filename = NULL;
  s->name = NULL;
  s->home = NULL;
  s->owner = NULL;
  s->pilot = NULL;
  s->copilot = NULL;
  s->dest = NULL;
  s->type = 0;
  s->ship_class = 0;
  s->model = 0;
  s->hyperspeed = 0;
  s->hyperdistance = 0;
  s->realspeed = 0;
  s->currspeed = 0;
  s->shipstate = SHIP_READY;
  s->laserstate = LASER_READY;
  s->missilestate = MISSILE_READY;
  s->missiles = 0;
  s->maxmissiles = 0;
  s->lasers = 0;
  s->tractorbeam = 0;
  s->manuever = 0;
  s->hatchopen = FALSE;
  s->autorecharge = FALSE;
  s->autotrack = FALSE;
  s->autospeed = FALSE;
  s->maxenergy = 0;
  s->energy = 0;
  s->shield = 0;
  s->maxshield = 0;
  s->hull = 0;
  s->maxhull = 0;
  s->location = 0;
  s->lastdoc = 0;
  s->shipyard = 0;
  s->collision = 0;
  s->target = NULL;
  s->currjump = NULL;
  s->chaff = 0;
  s->maxchaff = 0;
  s->chaff_released = FALSE;
  s->autopilot = FALSE;

  vector_init( &s->pos );
  vector_init( &s->head );
  vector_init( &s->jump );

  for( n = 0; n < MAX_SHIP_ROOMS; ++n )
    s->description[n] = NULL;

  return s;
}

void ship_untarget_all( SHIP_DATA *ship )
{
  TURRET_DATA *turret = NULL;

  ship->target = NULL;

  for( turret = ship->first_turret; turret; turret = turret->next )
    {
      turret->target = NULL;
    }
}

void transship( SHIP_DATA *ship, int vnum )
{
  if( get_room_index( vnum ) )
    {
      ship_untarget_by_attackers( ship );
      ship_untarget_by_missiles( ship );

      if( ship->starsystem )
	ship_from_starsystem( ship, ship->starsystem );

      extract_ship( ship );
      ship_to_room( ship, vnum );
      ship->shipstate = SHIP_DOCKED;
      ship->location = vnum;
      ship->lastdoc = vnum;
      ship_untarget_all( ship );
      save_ship( ship );
    }
}

void do_transship( CHAR_DATA *ch, char *argument )
{
  char shipname[MAX_INPUT_LENGTH];
  SHIP_DATA *ship = NULL;
  int vnum = 0;

  argument = one_argument( argument, shipname );

  if( *argument == '\0' || *shipname == '\0' )
    {
      ch_printf( ch, "Usage: transship <ship> <destination vnum>\r\n" );
      return;
    }

  if( !( ship = get_ship( shipname ) ) )
    {
      ch_printf( ch, "Can't find a ship with that name.\r\n" );
      return;
    }

  vnum = strtol( argument, 0, 10 );

  if( !get_room_index( vnum ) )
    {
      ch_printf( ch, "No room with that vnum.\r\n" );
      return;
    }

  transship( ship, vnum );
  ch_printf( ch, "Ship successfully transferred to new location.\r\n" );
}