/* 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;
}