From: Fili <cybom@NETROPOLIS.NET>
Subject: Ferry Code

This code release is hopefully one of many from the DarkStar codebase.
This one is in response to the previously posted ferry code (Snippets
page) that I spent hours trying to implement (So sue me, I was lazy and
didn't want to rewrite it then :) ) I then had a chat with my lead
programmer, and we rewrote the code so that it worked. Anyways, for your
viewing pleasure, ferry.c:

/***************************************************************************
* ferry.c                                               Added to CircleMUD *
* Security level 3                                                         *
* Base Programming: Shadowbeam of Darkstar: The Knight of Darkness         *
* Multiple Ferry Enhancement: Fili of Darkstar: The Knight of Darkness     *
* Create_Exit & Remove_Exit Bugfixes: George Greer                         *
* (DARKSTAR: telnet://mdarkstar.ml.org:7007, http://mdarkstar.home.ml.org) *
*                                                                          *
* Use of code requires credit in credit file and that you mail Fili at:    *
* cybom@netropolis.net                                                     *
***************************************************************************/

#include "conf.h"
#include "sysdep.h"

#include "structs.h"
#include "utils.h"
#include "comm.h"
#include "db.h"

#define NUM_OF_FERRYS 2 // Change as needed


/*******************Externals and Other Globals*******************/

extern struct room_data *world;
extern struct time_info_data time_info;

int created = FALSE;

struct ferry_info {
	int f_from_room;   //VNUM of one of the Ferry's docks
	int ferry_room;    //VNUM of the Ferry room
	int f_to_room;     //VNUM of the other of the Ferry's docks
	int f_from_room_dir_from_room; //Direction from FROM_ROOM to the ferry
	int f_from_room_dir_from_ferry;//Direction from the ferry to FROM_ROOM
	int f_to_room_dir_from_room;   //Direction from TO_ROOM to the ferry
	int f_to_room_dir_from_ferry;  //Direction from the ferry to TO_ROOM
	int f_time_arrive_from_room;   //Time the ferry arrives at FROM_ROOM
	int f_time_arrive_from_room2;  //See f_time_arrive_from_room
	int f_time_leave_from_room;    //Time the ferry leaves FROM_ROOM
	int f_time_leave_from_room2;   //See f_time_leave_from_room
	int f_time_arrive_to_room;     //Time the ferry arrives at TO_ROOM
	int f_time_arrive_to_room2;    //See f_time_arrive_to_room
	int f_time_leave_to_room;      //Time the ferry leaves TO_ROOM
	int f_time_leave_to_room2;     //See f_time_leave_to_room
	char *arrive_messg_from;   // Message sent to ferry at arrival at FROM_ROOM
	char *arrive_dock_from;    // Message sent to dock at arrival at FROM_ROOM
	char *leave_messg_from;    // Message sent to ferry when leaving FROM_ROOM
	char *leave_dock_from;     // Message sent to dock when leaving FROM_ROOM
	char *arrive_messg_to;     // Message sent to ferry at arrival at TO_ROOM
	char *arrive_dock_to;      // Message sent to dock at arrival at TO_ROOM
	char *leave_messg_to;      // Message sent to ferry when leaving TO_ROOM
	char *leave_dock_to;       // Message sent to dock when leaving TO_ROOM
};

struct ferry_info ferrys[NUM_OF_FERRYS]; 

/*******************Ferry Initializations*******************/

//This is the block of code used for initializing a ferry
void init_ferry(void)
{
	//The ferry between Myrrak and the Mainland
	ferrys[0].f_from_room = 1000;
	ferrys[0].ferry_room = 1333;
	ferrys[0].f_to_room = 6006;
	ferrys[0].f_from_room_dir_from_room = WEST;
	ferrys[0].f_from_room_dir_from_ferry = EAST;
	ferrys[0].f_to_room_dir_from_room = EAST;
	ferrys[0].f_to_room_dir_from_ferry = WEST;
	ferrys[0].f_time_arrive_from_room = 1;
	ferrys[0].f_time_arrive_from_room2 = 13;
	ferrys[0].f_time_leave_from_room = 3;
	ferrys[0].f_time_leave_from_room2 = 15;
	ferrys[0].f_time_arrive_to_room = 7;
	ferrys[0].f_time_arrive_to_room2 = 19;
	ferrys[0].f_time_leave_to_room = 9;
	ferrys[0].f_time_leave_to_room2 = 21;
	ferrys[0].arrive_messg_from = "The ferry docks and a gangplank is extended\r\n";
	ferrys[0].arrive_dock_from = "The ferry from the Mainland docks and a gangplank is extended\r\n";
	ferrys[0].arrive_messg_to = "The ferry docks and a gangplank is extended\r\n";
	ferrys[0].arrive_dock_to = "The ferry from Myrrak docks and a gangplank is extended\r\n";
	ferrys[0].leave_messg_from = "The ferry raises its sail and gangplank is hauled aboard\r\n";
	ferrys[0].leave_dock_from = "The ferry raises its sail and gangplank is hauled aboard\r\n";
	ferrys[0].leave_messg_to = "The ferry raises its sail and gangplank is hauled aboard\r\n";
	ferrys[0].leave_dock_to = "The ferry raises its sail and gangplank is hauled aboard\r\n";

	//The Magic Circle from Tristak to the Green Leaf Inn
	ferrys[1].f_from_room = 1331;
	ferrys[1].ferry_room = 1332;
	ferrys[1].f_to_room = 15090;
	ferrys[1].f_from_room_dir_from_room = DOWN;
	ferrys[1].f_from_room_dir_from_ferry = UP;
	ferrys[1].f_to_room_dir_from_room = DOWN;
	ferrys[1].f_to_room_dir_from_ferry = UP;
	ferrys[1].f_time_arrive_from_room = 1;
	ferrys[1].f_time_arrive_from_room2 = 13;
	ferrys[1].f_time_leave_from_room = 3;
	ferrys[1].f_time_leave_from_room2 = 15;
	ferrys[1].f_time_arrive_to_room = 7;
	ferrys[1].f_time_arrive_to_room2 = 19;
	ferrys[1].f_time_leave_to_room = 9;
	ferrys[1].f_time_leave_to_room2 = 21;
	ferrys[1].arrive_messg_from = "You see the world appear above you\r\n";
	ferrys[1].arrive_dock_from = "A large blue portal appears below you\r\n";
	ferrys[1].arrive_messg_to = "You see the world appear above you\r\n";
	ferrys[1].arrive_dock_to = "A large blue portal appears below you\r\n";
	ferrys[1].leave_messg_from = "You see the world disappear above you\r\n";
	ferrys[1].leave_dock_from = "The portal disappears\r\n";
	ferrys[1].leave_messg_to = "You see the world disappear above you\r\n";
	ferrys[1].leave_dock_to = "The portal disappears\r\n";

}

/*******************FUNCTIONS*******************/


void create_exit(int vnum_from, int vnum_to, int from_dir)
{
  char cebuf[128];
  int rnum_from, rnum_to;

  if ((rnum_from = real_room(vnum_from)) == NOWHERE) {
    sprintf(cebuf, "SYSERR: Ferry: Couldn't find the 'from' room #%d.", vnum_from);
    log(cebuf);
  } else if ((rnum_to = real_room(vnum_to)) == NOWHERE) {
    sprintf(cebuf, "SYSERR: Ferry: Couldn't find the 'to' room #%d.", vnum_to);
    log(cebuf);
  } else if (world[rnum_from].dir_option[from_dir] == NULL) {
    CREATE(world[rnum_from].dir_option[from_dir], struct room_direction_data, 1);
    world[rnum_from].dir_option[from_dir]->to_room = rnum_to;
  } else {
    sprintf(cebuf, "SYSERR: Ferry overwriting exit in room #%d.", world[rnum_from].number);
    log(cebuf);
    world[rnum_from].dir_option[from_dir]->to_room = rnum_to;
  }
}

void remove_exit(int vnum_from, int vnum_to, int from_dir)
{
  char rebuf[128];
  int rnum_from, rnum_to;

  if ((rnum_from = real_room(vnum_from)) == NOWHERE) {
    sprintf(rebuf, "SYSERR: Ferry: Couldn't find the 'from' room #%d.", vnum_from);
    log(rebuf);
  } else if ((rnum_to = real_room(vnum_to)) == NOWHERE) {
    sprintf(rebuf, "SYSERR: Ferry: Couldn't find the 'to' room #%d.", vnum_to);
    log(rebuf);
  } else if (world[rnum_from].dir_option[from_dir] == NULL) {
    sprintf(rebuf, "SYSERR: Trying to remove non-existant exit in room #%d.", world[rnum_from].number);
    log(rebuf);
  } else {
    free(world[rnum_from].dir_option[from_dir]);
    world[rnum_from].dir_option[from_dir] = NULL;
  }
}



void update_ferry(void) {
	int onferrynum = 0; // Ferry cycle #

	for(onferrynum = 0; onferrynum < NUM_OF_FERRYS; onferrynum++)
	{
	   if(time_info.hours == ferrys[onferrynum].f_time_arrive_from_room){ 
	      create_exit(ferrys[onferrynum].f_from_room, ferrys[onferrynum].ferry_room, ferrys[onferrynum].f_from_room_dir_from_room);
	      create_exit(ferrys[onferrynum].ferry_room, ferrys[onferrynum].f_from_room, ferrys[onferrynum].f_from_room_dir_from_ferry);
	      send_to_room(ferrys[onferrynum].leave_dock_from, real_room(ferrys[onferrynum].f_from_room));
	      send_to_room(ferrys[onferrynum].arrive_messg_from, real_room(ferrys[onferrynum].ferry_room));
		}

	   if(time_info.hours == ferrys[onferrynum].f_time_arrive_to_room){
	      create_exit(ferrys[onferrynum].f_to_room, ferrys[onferrynum].ferry_room, ferrys[onferrynum].f_to_room_dir_from_room);
	      create_exit(ferrys[onferrynum].ferry_room, ferrys[onferrynum].f_to_room, ferrys[onferrynum].f_to_room_dir_from_ferry);
	      send_to_room(ferrys[onferrynum].arrive_dock_to, real_room(ferrys[onferrynum].f_from_room));
	      send_to_room(ferrys[onferrynum].arrive_messg_to, real_room(ferrys[onferrynum].ferry_room));
		}

	   if(time_info.hours == ferrys[onferrynum].f_time_leave_from_room){
	      remove_exit(ferrys[onferrynum].f_from_room, ferrys[onferrynum].ferry_room, ferrys[onferrynum].f_from_room_dir_from_room);
	      remove_exit(ferrys[onferrynum].ferry_room, ferrys[onferrynum].f_from_room, ferrys[onferrynum].f_from_room_dir_from_ferry);
	      send_to_room(ferrys[onferrynum].leave_dock_from, real_room(ferrys[onferrynum].f_from_room));
	      send_to_room(ferrys[onferrynum].leave_messg_from, real_room(ferrys[onferrynum].ferry_room));
		}

	   if(time_info.hours == ferrys[onferrynum].f_time_leave_to_room){
	      remove_exit(ferrys[onferrynum].f_to_room, ferrys[onferrynum].ferry_room, ferrys[onferrynum].f_to_room_dir_from_room);
	      remove_exit(ferrys[onferrynum].ferry_room, ferrys[onferrynum].f_to_room, ferrys[onferrynum].f_to_room_dir_from_ferry);
	      send_to_room(ferrys[onferrynum].leave_dock_to, real_room(ferrys[onferrynum].f_to_room));
	      send_to_room(ferrys[onferrynum].leave_messg_to, real_room(ferrys[onferrynum].ferry_room));
		}
	   // Code for the second depart time...
	   if(time_info.hours == ferrys[onferrynum].f_time_arrive_from_room2){ 
	      create_exit(ferrys[onferrynum].f_from_room, ferrys[onferrynum].ferry_room, ferrys[onferrynum].f_from_room_dir_from_room);
	      create_exit(ferrys[onferrynum].ferry_room, ferrys[onferrynum].f_from_room, ferrys[onferrynum].f_from_room_dir_from_ferry);
	      send_to_room(ferrys[onferrynum].leave_dock_from, real_room(ferrys[onferrynum].f_from_room));
	      send_to_room(ferrys[onferrynum].arrive_messg_from, real_room(ferrys[onferrynum].ferry_room));
		}

	   if(time_info.hours == ferrys[onferrynum].f_time_arrive_to_room2){
	      create_exit(ferrys[onferrynum].f_to_room, ferrys[onferrynum].ferry_room, ferrys[onferrynum].f_to_room_dir_from_room);
	      create_exit(ferrys[onferrynum].ferry_room, ferrys[onferrynum].f_to_room, ferrys[onferrynum].f_to_room_dir_from_ferry);
	      send_to_room(ferrys[onferrynum].arrive_dock_to, real_room(ferrys[onferrynum].f_from_room));
	      send_to_room(ferrys[onferrynum].arrive_messg_to, real_room(ferrys[onferrynum].ferry_room));
		}

	   if(time_info.hours == ferrys[onferrynum].f_time_leave_from_room2){
	      remove_exit(ferrys[onferrynum].f_from_room, ferrys[onferrynum].ferry_room, ferrys[onferrynum].f_from_room_dir_from_room);
	      remove_exit(ferrys[onferrynum].ferry_room, ferrys[onferrynum].f_from_room, ferrys[onferrynum].f_from_room_dir_from_ferry);
	      send_to_room(ferrys[onferrynum].leave_dock_from, real_room(ferrys[onferrynum].f_from_room));
	      send_to_room(ferrys[onferrynum].leave_messg_from, real_room(ferrys[onferrynum].ferry_room));
		}

	   if(time_info.hours == ferrys[onferrynum].f_time_leave_to_room2){
	      remove_exit(ferrys[onferrynum].f_to_room, ferrys[onferrynum].ferry_room, ferrys[onferrynum].f_to_room_dir_from_room);
	      remove_exit(ferrys[onferrynum].ferry_room, ferrys[onferrynum].f_to_room, ferrys[onferrynum].f_to_room_dir_from_ferry);
	      send_to_room(ferrys[onferrynum].leave_dock_to, real_room(ferrys[onferrynum].f_to_room));
	      send_to_room(ferrys[onferrynum].leave_messg_to, real_room(ferrys[onferrynum].ferry_room));
		}

	}
   return;
}

In comm.c, in void heartbeat:
AFTER:
  if (!(pulse % (SECS_PER_MUD_HOUR * PASSES_PER_SEC))) {
    weather_and_time(1);
    affect_update();
    point_update();
    fflush(player_fl);

ADD:
    update_ferry();
