/
lib/banish/
lib/d/coronos/
lib/d/coronos/w/alena/
lib/d/coronos/w/angel/
lib/d/coronos/w/angel/caves/
lib/d/coronos/w/angel/caves/monst/
lib/d/coronos/w/angel/city/chambers/
lib/d/coronos/w/angel/city/monst/
lib/d/coronos/w/angel/city/obj/
lib/d/coronos/w/angel/city/streets/
lib/d/coronos/w/angel/farms/plains/
lib/d/coronos/w/angel/monst/
lib/d/tempus/
lib/d/tempus/w/angel/
lib/d/tempus/w/kingbill/
lib/d/tempus/w/mirak/
lib/d/tempus/w/mirak/monst/
lib/d/tempus/w/mirak/obj/
lib/d/tempus/w/relgar/planes/baat/
lib/d/tempus/w/sarak/
lib/d/tempus/w/serepion/mon/
lib/d/tempus/w/valrejn/
lib/doc/
lib/doc/domains/
lib/doc/efun/
lib/include/fn_specs/
lib/info/
lib/inherit/base/
lib/log/
lib/log/mailbox/
lib/log/main/
lib/news/
lib/obj/party/
lib/objects/componen/
lib/open/
lib/open/party/
lib/open/paste/
lib/open/spells/
lib/open/valrejn/
lib/players/
lib/players/alena/
lib/players/alena/obj/
lib/players/alena/open/
lib/players/alena/private/
lib/players/angel/
lib/players/angel/obj/
lib/players/ash/
lib/players/biggs/
lib/players/biggs/food/
lib/players/biggs/gobkeep/
lib/players/biggs/mnstr/
lib/players/biggs/town/caves/
lib/players/biggs/town/tower/
lib/players/biggs/wpns/
lib/players/calris/
lib/players/deathurg/
lib/players/deathurg/open/
lib/players/deathurg/private/thief/
lib/players/dogberry/
lib/players/dogberry/library/
lib/players/dogberry/open/
lib/players/epsilon/
lib/players/epsilon/private/
lib/players/farewell/
lib/players/hippo/
lib/players/hippo/open/
lib/players/hippo/tools/
lib/players/jimpa/
lib/players/josh/
lib/players/josh/room/
lib/players/josh/room/mage/dungeon/
lib/players/josh/room/mage/dungeon/obj/
lib/players/josh/wep/
lib/players/kingbill/
lib/players/metatron/
lib/players/miette/
lib/players/mirak/
lib/players/mirak/open/
lib/players/parsilan/
lib/players/relgar/
lib/players/relgar/private/
lib/players/sarak/
lib/players/sarak/bugs/
lib/players/sarak/feelings/
lib/players/sarak/magical/
lib/players/sarak/minotaur/island/
lib/players/sarak/open/
lib/players/sarak/private/
lib/players/serepion/
lib/players/serepion/open/
lib/players/serepion/private/
lib/players/spike/
lib/players/spike/open/
lib/players/spike/private/
lib/players/spike/seaworld/
lib/players/valrejn/
lib/players/valrejn/open/
lib/players/valrejn/private/
lib/players/virus/
lib/players/wrath/
lib/players/wrath/arm/
lib/players/wrath/mon/
lib/players/wrath/room/
lib/players/wrath/room/entry/
lib/players/wrath/room/zolgath/
lib/players/wrath/weap/
lib/players/zil/
lib/room/
lib/room/city/arena/
lib/room/city/creator/
lib/room/city/garden/monst/
lib/room/city/library/
lib/room/city/library/open/books/
lib/room/city/shop/
lib/room/death/
lib/room/death/open/
lib/room/island/
lib/room/keeps/
lib/room/registry/
lib/room/ships/crew/
lib/room/ships/open/
lib/room/ships/open/types/bounty/
lib/room/ships/open/types/nebula/
lib/room/ships/open/types/phoenix/
lib/secure/udp_cmd_/
lib/skills/
lib/skills/fighter/
lib/skills/psionici/
lib/skills/thief/
lib/usr/
lib/usr/creators/
lib/usr/no_banis/
lib/usr/players/
/* v5.00 SHIPS 'AHOY!
 * (c) Angel, Feb 1995.
 * Original code from Angel, Jan 1995
 * Based on similar concept of automatic shuttle craft from numerous TREKmuds
 */


#include <mudlib.h>
/*****************************************************************************/
/* Global Defines */
#define SHIP_NAME        capitalize((string)this_object()->query_ship_name())
#define NAME             (string)this_player()->query_name()



#define PORTS_OF_CALL    ({\
({ "angel's workroom", "/players/angel/workroom", ({ 100, 200, 300, }),    }),\
({ "tempus square",    "/room/city/square",       ({ 200, 100, 100, }),    }),\
({ "tempus jetty",     "/room/city/jetty",        ({ 300, 100, 200, }),    }),\
                         })



#define DESTINATION_FILE "/room/city/ships/room"

#define SCI_FI
#ifdef  SCI_FI
#define DESTINATION_NAME "empty space"
#define SCRIPT_FILE      "/room/ships/space.txt"
#else
#define DESTINATION_NAME "the high seas"
#define SCRIPT_FILE      "/room/ships/sea.txt"
#endif  /* SCI_FI */


#ifdef SCI_FI
#define MAX_WARP       10
#define WARP_SPEED     10
#define IMPULSE_POWER  4
#endif /* SCI_FI */



#define WAIT_TIME        30             /* seconds until we go again       */
#define PLACE            0              /* array element for place name    */
#define FILE             1              /* array element for file name     */
#define XYZ		2		/* array element for xyz coords */
#define X                0              /* array elements of x xyz co-arr  */
#define Y                1              /* array elements of y xyz co-arr  */
#define Z                2              /* array elements of z xyz co-arr  */




/***************************************************************************/
status automated;                       /* does the ship go by itself?     */
status waiting;                         /* is the ship waiting to go?      */

int counter;                            /* for automated travel array      */
int distance;                           /* distance to target              */
int timer;                              /* heart beat timer                */
int speed;                              /* how fast we're going            */
int x1, y1, z1, x2, y2, z2;             /* handy coord ints                */

int *my_coordinates;                    /* where I am now                  */
int *destination_coordinates;           /* where I am going to dock        */
int *old_destination_coordinates;       /* where I was docked before       */

string destination;                     /* name of the place we're off to  */
string destination_file;                /* file of the place we're off to  */
string ship_name;                       /* name of the ship!               */



/***************************************************************************/
/* Prototypes */
void msg(string str);
void ship_travel(int *coords);

int calc_distance(int *coordinates1, int *coordinates2);
int square_root(int i);

status ship_board(string str);
status ship_disembark();
status ship_engage();
status ship_input(string str);



/***************************************************************************/
inherit ROOM;
void reset(status arg) {
  string txt;
  int i, j, k;
  mixed *data;

#define SHORT          1  
#define LONG           2
#define ITEMS          3
#define WEATHER        4
#define SMELL          5
#define LISTEN         6

  if(arg) return;

  txt = read_bytes(SCRIPT_FILE, 0, file_size(SCRIPT_FILE));
  data = explode(txt, "#");
  set_short   (data[SHORT]  );
  write("Short: "+this_object()->query_short()+"\n");
  set_long    (data[LONG]   );
  write("Long: "+this_object()->query_long()+"\n");
  set_items   (data[ITEMS]  );
  write("Items: "+data[ITEMS]+"\n");
  write("Weather: "+data[WEATHER]+"\n");
  sscanf(data[WEATHER], "%d,%d,%d", i, j, k);
  set_weather(i, j, k);
  set_smell   (data[SMELL]  );
  set_listen  (data[LISTEN] );
}
  



/***************************************************************************/
/* Actions */
void init() {
  ::init();

  if(environment() && present(this_player(), environment()))
    add_action("ship_board", "board");

  else {
    add_action("ship_disembark", "disembark");
    add_action("ship_disembark", "leave");

    if(!automated) {
#ifdef SCI_FI
        add_action("ship_engage", "engage");
#endif /* SCI_FI */

      add_action("ship_input", "input");
      add_action("ship_input", "enter");
    }
  }
}


status ship_board(string str) {
  if(id(str)) {
    write("You board the "+SHIP_NAME+".\n");
    this_player()->move_player("onto the "+SHIP_NAME+"#"+
                    file_name(this_object()));
    return 1;
  }
  notify_fail("Board what?\n");
  return 0;
}

status ship_disembark() {
  if(!waiting) return 0;
  write("You disembark from the "+SHIP_NAME+".\n");
  this_player()->move_player("the ship#"+file_name(environment()));
  return 1;
}

status ship_input(string str) {
  int i, j;
  int x, y, z;
  string tmp;

#ifdef SCI_FI
  /* Input Warp Speed */
  if(sscanf(str, "warp %d", i) == 1) {
    if(i >= MAX_WARP) {
      write("The computer chirps: Exceeding maximum warp capability.\n"+
            "                     Enter warp speed again.\n");
      return 1;
    }  
    write("You enter warp "+i+" into the conn.\n");
    say(NAME+" engages the warp engines.\n");
    speed = i*WARP_SPEED;
    return 1;
  }

  /* Input Impulse Speed */
  else if(sscanf(str, "impulse %d/%d", i, j) == 2) {
    write("You slow the engines down to "+i+"/"+j+" impulse power.\n");
    say(NAME+" engages the impulse engines.\n");
    speed = (IMPULSE_POWER * i)/j;
    return 1;
  }

  /* Input Travel Coordinates */
  else if(sscanf(str, "%dx %dy %dz", x, y, z) == 3) {
    write("The computer chirps: Coordinates ["+x+", "+y+", "+z+"] entered.\n");
    say(NAME+" programmes some coordinates into the conn.\n",this_player());
    destination_coordinates = ({ x, y, z, });
    ship_travel(destination_coordinates);
    return 1;
  }
#endif /* SCI_FI */

  /* Input Travel Place */
  if(sscanf(str, "place %s", str) == 1) {
    for(i=0; i<sizeof(PORTS_OF_CALL); i++) {
      if(str == PORTS_OF_CALL[i][PLACE]) {
        destination_coordinates = PORTS_OF_CALL[i][XYZ];
        destination_file        = PORTS_OF_CALL[i][FILE];
        destination             = PORTS_OF_CALL[i][NAME];

#ifdef SCI_FI        
        write("Computer chirps: Destination "+capitalize(str)+" recognised\n"+
          "Plotting parabolic course ["+destination_coordinates[X]+"x, "+
                                       destination_coordinates[Y]+"y, "+
                                       destination_coordinates[Z]+"z] to "+
          capitalize(destination)+".\n");
#else
        write("You prepare to travel to "+capitalize(destination)+"\n");
#endif /* SCI_FI */
        ship_travel(destination_coordinates);
        return 1;
        break;
      }
    }
  }

#ifdef SCI_FI
  else {
    write("The computer chirps: Incorrect input.\n");
    return 1;
  }
#endif /* SCI_FI */

  return 0;
}


status ship_engage() {
  if(!destination_coordinates) {
    notify_fail("Computer chirps: Error. No destination entered.\n");
    return 0;
  }
  write("Computer chirps: Engines engaged.\n");
  waiting = 0;
  set_heart_beat(1);
  return 1;
}




/***************************************************************************/
/* Heart Beat Fn's */
void heart_beat() {
  timer ++;

  if(automated && waiting) {
    if(timer > WAIT_TIME) {
      waiting = 0; 
      timer   = 0;
      ship_travel(destination_coordinates);
    }
  }

  if(timer >= distance) {
    move_object(this_object(), destination_file);
    msg("The "+SHIP_NAME+" slows down and docks at "+destination+"\n");
    old_destination_coordinates = destination_coordinates;
    my_coordinates = destination_coordinates;
    timer = 0;
    waiting = 1;
    if(!automated) set_heart_beat(0);
    else {
      counter += 1;
/*
      destination_coordinates = [counter][2];
*/
    }
  }
}

/***************************************************************************/
/* Misc Fns */
void ship_travel(int *coords) {
  int i;

  for(i=0; i<sizeof(PORTS_OF_CALL); i++) {
    if(coords == PORTS_OF_CALL[i][XYZ]) {
      timer   = 0;
      msg("The "+SHIP_NAME+" drops its moorings and heads for "+
          PORTS_OF_CALL[i][PLACE]+".\n");
      waiting  = 0;
      distance = calc_distance(coords, destination_coordinates);
      if(!automated)  set_heart_beat(1);
      move_object(this_object(), DESTINATION_FILE);
      break;
    }
  }
}



int calc_distance(int *coordinates1, int *coordinates2) {
  x1 = coordinates1[X];  y1 = coordinates1[Y];  z1 = coordinates1[Z];
  x2 = coordinates2[X];  y2 = coordinates2[Y];  z2 = coordinates2[Z];
  return square_root(
     ((x2-x1) * (x2-x1)) + 
     ((y2-y1) * (y2-y1)) +
     ((z2-z1) * (z2-z1)));
}



int square_root(int i) {  return to_int(sqrt(to_float(i)));  }
void msg(string str)   {  tell_room(this_object(), str);     }

/* Query Fn's */
string query_ship_name() {
  if(!ship_name) ship_name = "Ganges";
  return ship_name;
}