Greetings once again.  If you liked Cargo Version 2, You'll love this one.  It's a skill 
to allow engineers to build thier own ships.  You build a ship with the 
designship command(which for single room starfighters is all you need). For multi-room ships
you build it with designship, then use the addroom command to build other rooms.
I've include comments for porting to SWFoTE so if you use it most of that work is done for you
I may have missed a few detetails though.  
If it's too confusing having porting instructions right in the code let me know...and it 
won't be in other snippets..likewise if you like it let me know too.

The syntax of the commands is:

designship <number of rooms> <ship name>
addroom <direction> <room type>

also you'll want to create a helpfile listing the possible roomtypes...see do_addroom for 
details.

--------
standard disclaimer - I am in no way responsible for any adverse affects of this code on 
                      anything ever.
--------
support - this code is provided as is with no warrenty expressed or implied. 
          However if you have problems installing or using it, I will try to answer
          your questions to the best of my ability.
--------
contact - ortluk@hotmail.com I take questions comments, constructive critisism 
          (on anything but my spelling)
--------
Ok, all that aside on to the code..
-----------------------------------------
First off this code is meant to work with my cargo v2 snippet if you don't already have it you 
should get it(or remove/adapt all of the cargo/import/export/resource stuff).

firstly it uses the ROOM_IMPORT flag again. and since I forgot to give instructions in either
cargo snippet as to how to add it I will give them here. 
So if .....
A. you know how
B. you already have the flag or one you'll use instead
or
C. someone else already added the flag for you because i was too lazy to tell you before.

you can skip this section.
---------------------------------------

in Mud.h find all of the #define ROOM_XXX    BVXX things. and add or replace an unused one with
#define ROOM_IMPORT   BVXX

the XX should be whatever bit you use I think i used BV11 or 12 I can't remember for sure.
take not of which flag is right before and after the one you chose.

then in build.c find the 
char const *room_flags = {
section...i think that's what it is..look for the list of room flags anyways and add/replace 
with 
"import"

make sure you put it right after the flag that was before it in mud.h 
(hope you took note of it)

That should give you the room_flag
-----------------------------------------
ok now to the good stuff

---------
in mud.h
---------
find where SHIP_LIST and stuff is defined and add

#define PSHIP_AREA            "pships.are" 

If using swfote you may want to use the ship area that is already there if so use this line instead.
#define PSHIP_AREA      SHIP_AREA

if not using swfote search for ship_types and add
PLAYER_SHIP

search for
SHIP_DATA *ship_from_cockpit( int vnum );

with all those definitions add

SHIP_DATA *ship_from_room    args(( int vnum ));
void wipe_resets             args(( AREA_DATA *pArea, ROOM_INDEX_DATA *pRoom ));

note - the previous function already exsists in swfote

in 
struct ship_data 
add

int lastbuilt;

find 
extern sh_int gsn_makeblade;
in that section add

extern sh_int gsn_shipdesign;

then find the DECLARE_DO_FUN section
and add

DECLARE_DO_FUN( do_designship );
DECLARE_DO_FUN( do_addroom );

------------
in space.c
------------

add this functions -
SHIP_DATA *ship_from_room( int vnum )
{
    SHIP_DATA *ship;
    
    for ( ship = first_ship; ship; ship = ship->next )
       if ( vnum >= ship->firstroom && vnum <= ship->lastroom)
         return ship;
    return NULL;
}


in save_ship add with other fprintf statements -
fprintf(fp, "Lastbuilt   %d\n", ship->lastbuilt);

in fread_ship with other KEY statements in the case 'L': section add
KEY( "Lastbuilt", ship->lastbuilt, fread_number(fp));

in destroy_ship 
with other declarations add

char logbuf[MAX_INPUT_LENGTH];
AREA_DATA *tarea;

and at the end add

/* this section borrowed and modified from swfote...thanx guys it works great on
   my version of swrip...but for some reason on another swr i used it on it 
   crashes the mud...any in insight would be great thanks */
    if ( ship->type == PLAYER_SHIP )
    {
        resetship(ship);
        room = get_room_index(ship->firstroom);
        if(room != NULL)
        {
            tarea = room->area;
            if (tarea != NULL)
            {
              /*log_string("deleting_rooms"); debugging logs uncomment if needed*/
              for(roomnum=ship->firstroom;roomnum<ship->lastroom+1;roomnum++)
              {
                   room = get_room_index( roomnum );
                   if(!room){
                      bug("destroy_ship: NULL room",0);
                      continue;
                   }else{
                      wipe_resets(room->area, room);
                      delete_room(room);
                   }
              }
              log_string ("destroy_ship: rooms deleted");
              fold_area( tarea, tarea->filename, FALSE );
           }
        }
        sprintf(logbuf ,"Ship Deleted: %s",ship->name);
        log_string(logbuf);
        extract_ship( ship );
        ship_to_room( ship , 46 );
        ship->location = 46;
        ship->shipyard = 46;
        if (ship->starsystem)
            ship_from_starsystem( ship, ship->starsystem );

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

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

        write_ship_list();
    }

-----------
in db.c
-----------
find 
sh_int  gsn_makeblade;

in that section add
sh_int  gsn_shipdesign;

find
ASSIGN_GSN(gsn_makeblade, "makeblade");
and in that section someplace add
ASSIGN_GSN(gsn_shipdesign, "ship design");

-----------
tables.c
-----------
in the proper places add -

if (!str_cmp(name, "do_addroom"))         return do_addroom;
if (!str_cmp(name, "do_designship"))      return do_designship;
if (skill == do_addroom)                 return "do_addroom";
if (skill == do_designship)              return "do_designship";

---------------
in Makefile
---------------
in the O_FILES = section add

designship.o

in the C_FILES = section add

designship.c

+-----------------------+
| New file designship.c |
+-----------------------+
------------------------------------- cut here ------------------------------------------

/**********************************************************************************
*Designship.c - Ship design skill for Engineers                                   *
*Coded By     - Ortluk  ortluk@hotmail.com                                        *
*Written for  - SWR 1.0  and derivitives                                          *
**********************************************************************************/
/* NOTE - If using SWFoTE you will have to change the ship classes and a couple of the ship 
   variables. I think I commented most of them.  Also if not using SWFoTE you can remove 
   the parts commented about SWFoTE */

#include <math.h>
#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "mud.h"

void    destroy_ship( SHIP_DATA *ship );
void    write_ship_list args( ( void ) );

int reserve_rooms(int firstroom, int numrooms)
{
    AREA_DATA *tarea;
    ROOM_INDEX_DATA *room;
    int i;

    for ( tarea = first_area; tarea; tarea = tarea->next )
        if ( !str_cmp( PSHIP_AREA, tarea->filename ) )
          break;

    for (i = firstroom; i<firstroom + numrooms; i ++)
    {
        room = make_room(i);
        if (!room)
        {
           bug("reserve_rooms: make_room failed");
           return -1;
        }
        room->area = tarea;
        SET_BIT(room->room_flags, ROOM_SPACECRAFT);
     }
 fold_area(tarea, tarea->filename, TRUE);
 return i;
}
int find_pvnum_block(int num_needed)
{
  bool counting = FALSE;
  int count = 0;
  AREA_DATA *tarea;
  int lrange;
  int trange;
  int vnum;
  int startvnum = -1;
  ROOM_INDEX_DATA *room;

    for ( tarea = first_area; tarea; tarea = tarea->next )
        if ( !str_cmp( PSHIP_AREA, tarea->filename ) )
          break;
    lrange = tarea->low_r_vnum;
    trange = tarea->hi_r_vnum;
    for ( vnum = lrange; vnum <= trange; vnum++ )
    {
          if ( (room = get_room_index( vnum )) == NULL )
          {
            if(!counting)
            {
                counting = TRUE;
                startvnum = vnum;
            }
            count++;
            if(count == num_needed+1)
              break;
        }
        else if(counting)
        {
            counting = FALSE;
            count = 0;
            startvnum = -1;
        }
    }
  return startvnum;
}

/* this function borrowed from SWRip codebase thanx guys - comment it out if you already 
have one*/
void transship(SHIP_DATA *ship, int destination)
{
    int origShipyard;


    if ( !ship )
        return;

     origShipyard = ship->shipyard;

     ship->shipyard = destination;
     ship->shipstate = SHIP_DOCKED;

     extract_ship( ship );
     ship_to_room( ship , ship->shipyard );

     ship->location = ship->shipyard;
     ship->lastdoc = ship->shipyard;

     ship->shipyard = origShipyard;

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

     save_ship(ship);
}

void do_designship( CHAR_DATA *ch, char *argument )
{
    char arg[MAX_INPUT_LENGTH];
    char arg1[MAX_INPUT_LENGTH];
    char filename[MAX_STRING_LENGTH];
    int chance, numrooms, class;
    bool checktool, checkdura, checkcir, checksuper;
    ROOM_INDEX_DATA *room;
    OBJ_DATA *obj;
    SHIP_DATA *ship;
    PLANET_DATA *planet;
    int vnum, steel, lommite, cost,fee;

    argument = one_argument( argument, arg );

    strcpy (arg1, argument);
    switch( ch->substate )
    {
        default:

                if ( !is_number(arg) || arg1[0] == '\0' )
                {
                    send_to_char("&RUsage: &Gdesignship &C<&cnumber of rooms&C> <&cname of ship&C>&w\r\n",ch);
                    return;
                }
                numrooms = atoi(arg);
                if (numrooms > 100 || numrooms < 1)
                {
                   send_to_char("&RNumber of rooms MUST be between 1 and 100&C&w",ch);
                   return;
                }
                for ( ship = first_ship; ship; ship = ship->next )
                {
                   if(!str_cmp(ship->name,argument))
                   {
                     send_to_char("&CThat ship name is already in use. Choose another.\r\n",ch);
                     return;
                   }
                }

                checktool   = FALSE;
                checkdura  = FALSE;
                checkcir     = FALSE;
                checksuper = FALSE;          

                /*used import flag to avoid adding an extra shipyard flg. 
                   it can be changed if you don't have my cargo snippet - Ortluk 
                   Also if you're installing in swfote you can uncomment the first if statement 
                   and comment the second one out to use the shipyard flag instead*/
                
/*              if( !IS_SET(ch->in_room->room_flags2, ROOM_SHIPYARD))*/
                if ( !IS_SET(ch->in_room->room_flags, ROOM_IMPORT)) 
                {
                   send_to_char("You can't build that here!! Try a spaceport\r\n",ch);
                   return;
                }

/* uncomment these lines if swfote 
                if (numrooms > 100)
                   class = SHIP_DESTROYER;
                else if(numrooms > 75)
                   class = SHIP_DREADNAUGHT;
                else if(numrooms > 50)
                   class = SHIP_CRUISER;
                else if(numrooms > 25)
                   class = SHIP_CORVETTE;
                else if(numrooms > 15)
                   class = SHIP_FRIGATE;
                else if(numrooms > 5)
                   class = SHIP_FREIGHTER;
                else if (numrooms > 1) 
                   class = SHIP_SHUTTLE;
                else 
                   class = SHIP_FIGHTER; */

/* comment these for swfote */
                if(numrooms > 25)
                   class = CAPITAL_SHIP;
                else if (numrooms > 5) 
                   class = MIDSIZE_SHIP;
                else 
                   class = FIGHTER_SHIP;

                /* these values come from  cargo v2 */
                 lommite = class * 50 + 10;
                 steel = class * 100 + 100;
                 planet = ch->in_room->area->planet;
                 if ( !planet )
                 {
                     send_to_char("&RAnd where do you think you're going to get the resources to build your ship?&C&w",ch);
                     return;
                 }

                 /* make sure the planet has the resources to build the ship */
                 if ( planet->resource[CARGO_LOMMITE] < lommite)
                 {
                     send_to_char("&RYou'll Have to wait till they either import or produce more lommite&C&w\r\n",ch);
                     return;
                 }
             
                 if (planet->resource[CARGO_STEEL] < steel )
                 {
                     send_to_char("&RYou'll Have to wait till they either import or produce more steel&C&w\r\n",ch);
                     return;
                 }             
                 cost = 10;
                 if (planet->import[CARGO_STEEL] > 0)
                    cost += planet->import[CARGO_STEEL] +  planet->import[CARGO_STEEL] / 2;
                 else if (planet->export[CARGO_STEEL] > 0)
                    cost += planet->export[CARGO_STEEL];
                 else
                    cost += 10;

                 if (planet->import[CARGO_LOMMITE] > 0)
                    cost += planet->import[CARGO_LOMMITE] +  planet->import[CARGO_LOMMITE] / 2;
                 else if (planet->export[CARGO_LOMMITE] > 0)
                    cost += planet->export[CARGO_LOMMITE];
                 else
                    cost += 10;

                 cost *= lommite + steel;
                 fee = cost * ((class +1) * 10);
                 cost += fee;
                 if (ch->gold < cost)
                 {
                     send_to_char("&RYou can't afford the materials to build that.\r\n",  ch);
                     return;
                 }

                 for ( obj = ch->last_carrying; obj; obj = obj->prev_content )  
                 {
                   if (obj->item_type == ITEM_TOOLKIT)
                     checktool = TRUE;
                   if (obj->item_type == ITEM_CIRCUIT)
                     checkcir = TRUE;
                   if (obj->item_type == ITEM_SUPERCONDUCTOR)
                     checksuper = TRUE;              
                 }
                 
                 if (!checktool)
                 {
                    send_to_char("&RI'd like to see you build a ship with no tools.\r\n",ch);
                    return;
                 }
                 if (!checkcir)
                 {
                    send_to_char("&RYou could really use a circuit to for the control systems.\r\n",ch);
                    return;
                 }
                 if (!checksuper)
                 {
                    send_to_char("&RSuch advanced circuitry requires a superconducter to work properly.\r\n",ch);
                    return;
                 }

                chance = IS_NPC(ch) ? ch->top_level
                         : (int) (ch->pcdata->learned[gsn_shipdesign]);
                if ( number_percent( ) < chance )
                {
                   send_to_char( "&GYou begin the LONG process of building a ship.\n\r", ch);
                   act( AT_PLAIN, "$n takes $s tools and starts constructing a ship.\r\n",ch,
                         NULL, argument , TO_ROOM );
                   add_timer ( ch , TIMER_DO_FUN , 25 , do_designship , 1 );
                   ch->dest_buf = str_dup(arg);
                   ch->dest_buf_2 = str_dup(arg1);
                   return;
                }
                send_to_char("&RYou can't figure out how to fit the parts together.\n\r",ch);
                learn_from_failure( ch, gsn_shipdesign );
                return;

        case 1:
                if ( !ch->dest_buf )
                {
                    bug("null ch->dest_buf", 0);
                     return;
                }
                if ( !ch->dest_buf_2 )
                {
                     bug("null ch->dest_buf2",0);
                     return;
                }
                strcpy(arg, ch->dest_buf);
                DISPOSE( ch->dest_buf);
                strcpy(arg1, ch->dest_buf_2);
                DISPOSE( ch->dest_buf_2);
                break;

        case SUB_TIMER_DO_ABORT:
                DISPOSE( ch->dest_buf );
                DISPOSE( ch->dest_buf_2 );
                ch->substate = SUB_NONE;
                send_to_char("&RYou are interupted and fail to finish your work.\n\r", ch);
                return;
    }
    ch->substate = SUB_NONE;
    numrooms = atoi(arg);

    if(numrooms > 25)
       class = CAPITAL_SHIP;
    else if (numrooms > 5) 
       class = MIDSIZE_SHIP;
    else 
    class = FIGHTER_SHIP;
                
    /* these values come from  cargo v2 */
    lommite = class * 50 + 10;
    steel = class * 100 + 100;
    planet = ch->in_room->area->planet;
    if ( !planet )
    {
       send_to_char("&RYou must have been moved...I'd complain.&C&w",ch);
       return;
    }

    cost = 10;
    if (planet->import[CARGO_STEEL] > 0)
       cost += planet->import[CARGO_STEEL] +  planet->import[CARGO_STEEL] / 2;
    else if (planet->export[CARGO_STEEL] > 0)
       cost += planet->export[CARGO_STEEL];
    else
       cost += 10;
   
    
    if (planet->import[CARGO_LOMMITE] > 0)
       cost += planet->import[CARGO_LOMMITE] +  planet->import[CARGO_LOMMITE] / 2;
    else if (planet->export[CARGO_LOMMITE] > 0)
       cost += planet->export[CARGO_LOMMITE];
    else
       cost += 10;

    cost *= lommite + steel;
    fee = cost * ((class +1) * 10);
    cost += fee; 
    if (ch->gold < cost)
    {
        send_to_char("&RYou can't afford the materials....Stop that THIEF!!!\r\n", ch);
        return;
    }
    ch->gold -= cost;
    planet->resource[CARGO_STEEL] -= steel;
    planet->resource[CARGO_LOMMITE] -= lommite;

    checktool   = FALSE;
    checkdura  = FALSE;
    checkcir     = FALSE;
    checksuper = FALSE;          

    for ( obj = ch->last_carrying; obj; obj = obj->prev_content )
    {
       if (obj->item_type == ITEM_TOOLKIT)
          checktool = TRUE;
       if (obj->item_type == ITEM_DURASTEEL && checkdura == FALSE)
       {
          checkdura = TRUE;
          separate_obj( obj );
          obj_from_char( obj );
       }
       if (obj->item_type == ITEM_CIRCUIT && checkcir == FALSE)
       {
          checkcir = TRUE;
          separate_obj( obj );
          obj_from_char( obj );
       }
       if (obj->item_type == ITEM_SUPERCONDUCTOR && checksuper == FALSE)
       {
          checksuper = TRUE;
          separate_obj( obj );
          obj_from_char( obj );
       }

    }

/* ok so far so good...everything is cool...try to build the ship */

   vnum = find_pvnum_block(numrooms);
   if (vnum < 0)
   {
       bug ( "player ship area out of vnums",0);
       send_to_char("Not enough vnums report to a coder.\r\n",ch);
       return;
   }
   if (reserve_rooms(vnum, numrooms) < 0)
   {
       bug("do_designship: reserve_rooms failed",0);
       send_to_char("Couldn't build your rooms report to coder.\r\n",ch);
       return;
   }
   sprintf( filename, "%d.pship",vnum);

   CREATE( ship, SHIP_DATA, 1 );
   LINK( ship, first_ship, last_ship, next, prev );
   ship->filename = STRALLOC( filename );
   ship->name = STRALLOC ( arg1 );
   ship->owner =  STRALLOC (ch->name);
   ship->copilot       = STRALLOC( "" );
   ship->pilot         = STRALLOC( "" );
   ship->home          = STRALLOC( "" );
   ship->type          =  PLAYER_SHIP;

/* you may want to adjust these to balance ships with your imm built ones 
   I use an array of maximum ship stats for the different classes of ships
   that's another project though */

   ship->maxenergy = (class + 1) * 50 * ch->pcdata->learned[gsn_shipdesign] ;
   ship->energy = ship->maxenergy;
   ship->maxhull = (class + 1) * 10 * ch->pcdata->learned[gsn_shipdesign] ;
   ship->maxshield = (class + 1) * 5 * ch->pcdata->learned[gsn_shipdesign];
   ship->realspeed = 2 * ch->pcdata->learned[gsn_shipdesign] / (class + 1);
   ship->hyperspeed = ch->pcdata->learned[gsn_shipdesign] + (class +1) * 20;
   ship->lasers = (class + 1) * (ch->pcdata->learned[gsn_shipdesign] / 20);
   ship->manuever = ch->pcdata->learned[gsn_shipdesign] * 2 / (class + 1);
   ship->comm = ch->pcdata->learned[gsn_shipdesign] * 2 / (class + 1);
   ship->sensor = ch->pcdata->learned[gsn_shipdesign] * 2 / (class + 1);
   ship->maxcargo = ch->pcdata->learned[gsn_shipdesign];
   ship->upgrades = 0; 
   ship->upgradeslots = ch->pcdata->learned[gsn_shipdesign]/5;

   ship->hull = ship->maxhull;
   ship->in_room=NULL;
   ship->currjump=NULL;
   ship->target0=NULL;
   ship->target1=NULL;
   ship->target2=NULL;
   ship->class=class;
   ship->firstroom = vnum;
   ship->lastroom = vnum + numrooms -1;
   ship->entrance = vnum;
   ship->lastbuilt = vnum;
   if (numrooms == 1)
   {
      ship->cockpit = vnum;
      ship->navseat = vnum;
      ship->gunseat = vnum;
      ship->pilotseat = vnum;
      ship->engineroom = vnum;
      ship->coseat = vnum;
   }
 
   gain_exp(ch, 10000, ENGINEERING_ABILITY);

/* I added this fee to balance the cost of building ships with that of selling them so as to 
   keep engis from making too much money too fast from just building and selling ships
*/
   ch_printf( ch, "The planet's Government has assesed a Licence Fee of %d credits.\r\n",  fee);
   ch_printf( ch , "&WYou gain 10000 engineering experience.\r\n" );
   learn_from_success(ch, gsn_shipdesign);
   transship(ship, ch->in_room->vnum);
   act( AT_PLAIN, "$n finishes building new ship, and climbs inside.", ch,
         NULL, argument , TO_ROOM );
   room = get_room_index(vnum);
   if (!room)
   {
      bug ("designship..no such room",0);
      return;
   }
   if (room->name)
     STRFREE( room->name );

   if (numrooms > 1)
      room->name = STRALLOC( "Entrance Ramp" );
   else
      room->name = STRALLOC( "Cockpit" );
   fold_area (room->area, room->area->filename, TRUE);
   save_ship(ship);
   write_ship_list();
   char_from_room( ch );
   char_to_room(ch, get_room_index(vnum));

}

void do_addroom(CHAR_DATA *ch, char *argument)
{
   char arg[MAX_INPUT_LENGTH];
   char arg1[MAX_INPUT_LENGTH];
   char buf[MAX_STRING_LENGTH];
   ROOM_INDEX_DATA *room;
   SHIP_DATA *ship;
   bool match, tset;
   int tmplvl;

   match = FALSE;
   argument = one_argument(argument, arg);
   argument = one_argument(argument, arg1);
   
   if (arg[0] == '\0' || arg1[0] =='\0')
   {
     send_to_char("Usage: addroom <direction> <type>\r\n",ch);
     send_to_char("   HELP addroom for a list of room types and costs\r\n",ch);
     return;
   }
   
   ship = ship_from_room(ch->in_room->vnum);

   if (!ship)
   {
      send_to_char("You can only add rooms to your ships.\r\n",ch);
      return;
   }
   if (!check_pilot(ch, ship))
   {
      send_to_char("You don't have permission to build on this ship\r\n",ch);
      return;
   }
   if (!argument)
   {
      send_to_char("You really should name your room\r\n",ch);
      return;
   }
   if (ship->lastbuilt == ship->lastroom || ship->lastbuilt < ship->firstroom)
   {
      send_to_char("You have no more rooms to build on this ship\r\n",ch);
      if (ship->lastbuilt < ship->firstroom)
      {
         ship->lastbuilt = ship->lastroom;
         save_ship(ship);
      }
      return;
   }
   room = get_room_index( ship->lastbuilt + 1 );

   if(!room)
   {
      bug("addroom: no such room", 0);
      return;
   }
  
   if ( !str_cmp(arg1, "cockpit"))
   {
      if (ship->class > MIDSIZE_SHIP)
      {
         send_to_char("Ships of this size don't have cockpits\r\n",ch);
         return;
      }
      if (ch->gold < 3000)
      {
         send_to_char( "You haven't got the money for a cockpit...it's gonna be hard to fly this one\r\n",ch );
         return;
      }

      ship->pilotseat = room->vnum;
      ship->coseat = room->vnum;
      ship->navseat = room->vnum;
      ship->gunseat = room->vnum;
      match = TRUE;
      ch->gold -= 3000;
      if(room->name)
        STRFREE(room->name);
      room->name = STRALLOC("Cockpit");
   }
   if (!str_cmp(arg1, "pilot"))
   {
      if (ch->gold < 1000)
      {
         send_to_char( "You haven't got the money for a that!\r\n",ch );
         return;
      }
      ch->gold -= 1000;
      ship->pilotseat = room->vnum;
      match = TRUE;
      if(room->name)
        STRFREE(room->name);
      room->name = STRALLOC("Pilot's Station");

   }
   if (!str_cmp(arg1, "nav"))
   {
      if (ch->gold < 1000)
      {
         send_to_char( "You haven't got the money for a that!\r\n",ch );
         return;
      }
      ch->gold -= 1000;
      ship->navseat = room->vnum;
      match = TRUE;
      if(room->name)
        STRFREE(room->name);
      room->name = STRALLOC("Navigator's Station");
   }
   if (!str_cmp(arg1, "gun"))
   {
      if (ch->gold < 1000)
      {
         send_to_char( "You haven't got the money for a that!\r\n",ch );
         return;
      }
      ch->gold -= 1000;
      match = TRUE;
      ship->gunseat = room->vnum;
      if(room->name)
        STRFREE(room->name);
      room->name = STRALLOC("Gunner's Station");
   }
   if (!str_cmp(arg1, "copilot"))
   {
      if (ch->gold < 1000)
      {
         send_to_char( "You haven't got the money for a that!\r\n",ch );
         return;
      }
      ch->gold -= 1000;
      match = TRUE;
      ship->coseat = room->vnum;
      if(room->name)
        STRFREE(room->name);
      room->name = STRALLOC("Co-Pilot's Station");
   }
   if (!str_cmp(arg1, "engine"))
   {
      if (ch->gold < 1000)
      {
         send_to_char( "You haven't got the money for a that!\r\n",ch );
         return;
      }
      ch->gold -= 1000;
      match = TRUE;
      ship->engineroom = room->vnum;
      if(room->name)
        STRFREE(room->name);
      room->name = STRALLOC("The Engine Room");
   }
   if (!str_cmp(arg1, "turret"))
   {
      if( ship->class == FIGHTER_SHIP)
      {
         send_to_char("starfighters are too small to have turrets\r\n",ch);
         return;
      }
/* Remove these comments if you have 
    support for more than 2 Turrets(my mud has 10, as does swfote) 
    also add sections for other classes of ships */
      
/*     if (ship->class == MIDSIZE_SHIP)        
     {*/
         if (ship->turret1 == 0)
         {
            tset = TRUE;
            ship->turret1 = room->vnum;
         }
         else if(ship->turret2 == 0)
         {
            tset = TRUE;
            ship->turret2 = room->vnum;
         }
/*      }   

      if (ship->class == CAPITAL_SHIP)
      {
         if (ship->turret1 == 0)
         {
            tset = TRUE;
            ship->turret1 = room->vnum;
         }
         else if(ship->turret2 == 0)
         {
            tset = TRUE;
            ship->turret2 = room->vnum;
         }
         else if(ship->turret3 == 0)
         {
            tset = TRUE;
            ship->turret3 = room->vnum;
         }
         else if(ship->turret4 == 0)
         {
            tset = TRUE;
            ship->turret4 = room->vnum;
         }
         else if(ship->turret5 == 0)
         {
            tset = TRUE;
            ship->turret5 = room->vnum;
         }
         else if(ship->turret6 == 0)
         {
            tset = TRUE;
            ship->turret6 = room->vnum;
         }
         else if(ship->turret7 == 0)
         {
            tset = TRUE;
            ship->turret7 = room->vnum;
         }
         else if(ship->turret8 == 0)
         {
            tset = TRUE;
            ship->turret8 = room->vnum;
         }
         else if(ship->turret9 == 0)
         {
            tset = TRUE;
            ship->turret9 = room->vnum;
         }
         else if(ship->turret0 == 0)
         {
            tset = TRUE;
            ship->turret0 = room->vnum;
         }
      } */
      if (!tset)
      {
         send_to_char("There is no more room for turrets\r\n",ch);
         return;
      }
      if (ch->gold < 10000)
      {
         send_to_char( "You haven't got the money for a that!\r\n",ch );
         return;
      }
      ch->gold -= 10000;
      match = TRUE;    
      if(room->name)
        STRFREE(room->name);
      room->name = STRALLOC("Turret");
   }
   if (!str_cmp(arg1, "hanger"))
   {
      if(ship->class < MIDSIZE_SHIP)
      {
         send_to_char("Starfighters don't have hangers!!\r\n",ch);
         return;
      }
      if (ship->hanger != 0)
      {
         send_to_char("sorry only one hanger per ship\r\n", ch);
         return;
      }
      if (ch->gold < 5000)
      {
         send_to_char( "You haven't got the money for a that!\r\n",ch );
         return;
      }
      ch->gold -= 5000;

      match = TRUE;    
      ship->hanger = room->vnum;
      if(room->name)
        STRFREE(room->name);
      room->name = STRALLOC("The Hanger");
   }
   if (!str_cmp(arg1, "workshop"))
   {
      if (ch->gold < 10000)
      {
         send_to_char( "You haven't got the money for a that!\r\n",ch );
         return;
      }
      ch->gold -= 10000;
      match = TRUE;    
      SET_BIT(room->room_flags, ROOM_FACTORY);
      if(room->name)
        STRFREE(room->name);
      room->name = STRALLOC("A Workshop");
   }
   if (!str_cmp(arg1, "meditate"))
   {
      if (ch->gold < 100000)
      {
         send_to_char( "You haven't got the money for a that!\r\n",ch );
         return;
      }
      ch->gold -= 100000;

      match = TRUE;    
      SET_BIT(room->room_flags, ROOM_SILENCE);
      SET_BIT(room->room_flags, ROOM_SAFE);
      if(room->name)
        STRFREE(room->name);
      room->name = STRALLOC("A Quiet Meditation Chamber");
   }
   if (!str_cmp(arg1, "hotel"))
   {
      if (ch->gold < 5000)
      {
         send_to_char( "You haven't got the money for a that!\r\n",ch );
         return;
      }
      ch->gold -= 5000;

      match = TRUE;    
      SET_BIT(room->room_flags, ROOM_HOTEL);
      if(room->name)
        STRFREE(room->name);
      room->name = STRALLOC("The Passenger's Lounge");
   }
   if (!str_cmp(arg1, "home"))
   {
      if (ch->gold < 10000)
      {
         send_to_char( "You haven't got the money for a that!\r\n",ch );
         return;
      }
      ch->gold -= 10000;

     match = TRUE;    
     SET_BIT(room->room_flags, ROOM_EMPTY_HOME);
     SET_BIT(room->room_flags, ROOM_HOTEL);   
     if(room->name)
       STRFREE(room->name);
     room->name = STRALLOC("An Empty Apartment");

   }
   if (!str_cmp(arg1, "turbolift"))
   {
      if (ch->gold < 500)
      {
         send_to_char( "You haven't got the money for a that!\r\n",ch );
         return;
      }
      ch->gold -= 500;

     match = TRUE;
     if(room->name)
       STRFREE(room->name);
     room->name = STRALLOC("A Turbolift");
   }
   if (!str_cmp(arg1, "corridor"))
   {
      if (ch->gold < 500)
      {
         send_to_char( "You haven't got the money for a that!\r\n",ch );
         return;
      }
      ch->gold -= 500;

     match = TRUE;
     if(room->name)
       STRFREE(room->name);
     room->name = STRALLOC("A Corridor");
   }
    
   if (!match)
   {
      send_to_char("&RNo such room type\r\n", ch);
      return;
   }
   if ( !str_cmp(arg, "n") || !str_cmp(arg, "north") ||
        !str_cmp(arg, "s") || !str_cmp(arg, "south") ||
        !str_cmp(arg, "e") || !str_cmp(arg, "east") ||
        !str_cmp(arg, "w") || !str_cmp(arg, "west") ||
        !str_cmp(arg, "sw") || !str_cmp(arg, "southwest") ||
        !str_cmp(arg, "nw") || !str_cmp(arg, "northwest") ||
        !str_cmp(arg, "se") || !str_cmp(arg, "southeast") ||
        !str_cmp(arg, "ne") || !str_cmp(arg, "northeast") ||
        !str_cmp(arg, "u") || !str_cmp(arg, "up") ||
        !str_cmp(arg, "d") || !str_cmp(arg, "down"))
  {
     if (get_exit(room, get_dir(arg)))
     {
        send_to_char("There is already an exit in that direction\r\n",ch);
        return;
     }
     else
     {
        sprintf( buf, "bexit %s %d", arg, room->vnum);
        tmplvl=ch->top_level;
        ch->top_level = 110;
        do_redit(ch, buf);
        ch->top_level= tmplvl;
     }
  }
  else
  {
     send_to_char("Not a valid direction\r\n",ch);
     return;
  }
ship->lastbuilt = room->vnum;
save_ship(ship);
fold_area( room->area, room->area->filename, TRUE );
}

void do_decorate( CHAR_DATA *ch, char *argument)
{
   SHIP_DATA *ship;
   ROOM_INDEX_DATA *room;
   AREA_DATA *tarea;
   int tmplvl;

   room = ch->in_room;
   if(!room)
   {
      bug("do_decorate: Trying to decorate NULL room",0);
      return;
   }
    
   ship = ship_from_room( room->vnum );

   if (!ship)
   {
      send_to_char("&RYou can only do this on ships currently\r\n&C&w",ch);
      return;
   }
   
   if(!check_pilot(ch, ship))
   {
      send_to_char("&RTry asking the owner first&C&w\r\n",ch);
      return;
   }
  
   if( ship->type != PLAYER_SHIP )
   {
      send_to_char("Currently you can only decorate custom ships...\r\n",ch);
      send_to_char("Petition the imms for a change of policy if ya don't like it\r\n",ch);
      return;
   }
/*possible security hole...temporarily sets the char to level 110 so they can use redit 
  desc..might want to either figure out another way to do this or make sure your dangerous
  imm commands check to make sure it's not coming from redit */
   
   tarea = room->area;
   tmplvl = ch->top_level;
   ch->top_level = 110;
   do_redit(ch, "desc");
   ch->top_level = tmplvl;
   fold_area(tarea, tarea->filename, FALSE);
   return;
}
/* this was added by request from the implementor of the mud i player tested it on
   gives engis an alternative to selling the ships to keep the vnums free and to 
   make some of the expense of building it back. 
   Note - You may also want to adjust do_sellship to severely cut the price on 
          player ships to give them a reson to recycle rather than sell.
*/

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

   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 ) && !IS_IMMORTAL(ch) )
   {
        send_to_char( "&RThat isn't your ship!" ,ch );
        return;
   }

   if ( ship->type != PLAYER_SHIP )
   {
       send_to_char("You can only recycle custom built ships\r\n",ch);
       return;
   }

   price = get_ship_value( ship );

    price /= 10;
    ch->gold += price;
    ch_printf(ch, "&GYou receive %ld credits from recycling your ship.\n\r" , price -  price/10);
    send_to_char("\r\nSeveral heavy droids chop up and carry off your ship.\r\n",ch);

    act( AT_PLAIN, "$n walks over to a terminal and makes a credit transaction.",ch,
       NULL, argument , TO_ROOM );
    act( AT_PLAIN, "Several heavy droids chop up and carry off a ship.",ch,
       NULL, argument , TO_ROOM );
    transship(ship, 45);
    destroy_ship(ship);
}



-------------------------------------- cut here --------------------------------

ok that has the code installed...next 

you need to create and install the area pships.are  be liberal with the number of 
vnums you use. just build a firstroom, lastroom, firstmob, lastmob, firstobj, lastobj
use aset to change the filename to pships.are (no need to create an area if you intend to use the ship are in swfote)

savea 
installa pships.are
folda pships.are

make clean
make

then copyover if you have it...reboot if not.

then 
cedit designship create do_designship
cedit addroom create do_addroom
cedit recycle create do_recycle
cedit decorate create do_decorate
cedit designship level 100
cedit addroom level 100
cedit recycle level 1
cedit decorate level 1
cedit save

I set recycle and decorate to level one to allow the customer of the engi to redecorate the
rooms...and to remove the ship when they're done with it it can of course be any level you 
choose

then use sset to create the skill and set it's guild/level/code/teachers 
I'm sure you know how.

then finnaly test it and let the players have at it.
players will appriciate helpfiles for it.
especially for addroom.
and some kind of notice encouracging recycling is also recomended.

Enjoy.

One final note - you can control where players build ships and the cost of doing so 
by adjusting the imports/exports of a planet..designship uses steel and lommite