diff --git a/dat/outfit.xml b/dat/outfit.xml
index a64d6a7..8d39786 100644
--- a/dat/outfit.xml
+++ b/dat/outfit.xml
@@ -656,5 +656,16 @@ By adding quite a dense layer of Plasteel to your ship you can increase it's stu
   <specific type="fighter">
    <ship>Lancelot</ship>
   </specific>
- </outfit>
+</outfit>
+ <outfit name="Large Civilian Vessel License">
+  <general>
+   <max>1</max>
+   <tech>8</tech>
+   <mass>0</mass>
+   <price>75000</price>
+   <gfx_store>license</gfx_store>
+   <description>This license will authorize you to buy Cruise Ship and Bulk Carrier class ships.</description>
+  </general>
+  <specific type="license" />
+</outfit>
 </Outfits>
diff --git a/dat/ship.xml b/dat/ship.xml
index 12059eb..351c55c 100644
--- a/dat/ship.xml
+++ b/dat/ship.xml
@@ -326,6 +326,7 @@
   <price>900000</price>
   <fabricator>Melendez Corp</fabricator>
   <tech>5</tech>
+  <license>Large Civilian Vessel License</license>
   <description>A heavy liner specialized in freighting cargo all over the universe.  Also has good accomodations for passengers depending on the model allowing for enjoyable cruises.  Was a favorite target of pirates until they added stock turrets to the new models which can now defend themselves properly.</description>
   <movement>
    <thrust>100</thrust>
diff --git a/gfx/outfit/store/license.png b/gfx/outfit/store/license.png
new file mode 100644
index 0000000..adb8406
Binary files /dev/null and b/gfx/outfit/store/license.png differ
diff --git a/src/land.c b/src/land.c
index e6afc6c..a28a573 100644
--- a/src/land.c
+++ b/src/land.c
@@ -270,7 +270,7 @@ static void outfits_open(void) {
 
   /* The descriptive text. */
   window_addText(wid, 40+300+20, -60,
-                 80, 140, 0, "txtSDesc", &gl_smallFont, &cDConsole,
+                 80, 160, 0, "txtSDesc", &gl_smallFont, &cDConsole,
                  "Name:\n"
                  "Type:\n"
                  "Owned:\n"
@@ -279,12 +279,13 @@ static void outfits_open(void) {
                  "Free Space:\n"
                  "\n"
                  "Price:\n"
-                 "Money:\n");
+                 "Money:\n"
+                 "License:\n");
 
   window_addText(wid, 40+300+40+60, -60,
-                 250, 140, 0, "txtDDesc", &gl_smallFont, &cBlack, NULL);
+                 250, 160, 0, "txtDDesc", &gl_smallFont, &cBlack, NULL);
 
-  window_addText(wid, 20+300+40, -220,
+  window_addText(wid, 20+300+40, -240,
                  OUTFITS_WIDTH-400, 180, 0, "txtDescription",
                  &gl_smallFont, NULL, NULL);
 
@@ -327,14 +328,14 @@ static void outfits_update(unsigned int wid, char* str) {
   (void)str;
   char* outfitname;
   Outfit* outfit;
-  char buf[128], buf2[16], buf3[16];
+  char buf[PATH_MAX], buf2[16], buf3[16];
 
   outfitname = toolkit_getList(wid, "iarOutfits");
   if(strcmp(outfitname, "None")==0) { /* No outfits. */
     window_modifyImage(wid, "imgOutfit", NULL);
     window_disableButton(wid, "btnBuyOutfit");
     window_disableButton(wid, "btnSellOutfit");
-    snprintf(buf, 128,
+    snprintf(buf, PATH_MAX,
         "None\n"
         "NA\n"
         "NA\n"
@@ -343,6 +344,7 @@ static void outfits_update(unsigned int wid, char* str) {
         "%d\n"
         "\n"
         "NA\n"
+        "MA\m"
         "NA\n",
         pilot_freeSpace(player));
     window_modifyText(wid, "txtDDesc", buf);
@@ -368,7 +370,7 @@ static void outfits_update(unsigned int wid, char* str) {
   window_modifyText(wid, "txtDescription", outfit->description);
   credits2str(buf2, outfit->price,  2);
   credits2str(buf3, player->credits, 2);
-  snprintf(buf, 128,
+  snprintf(buf, PATH_MAX,
            "%s\n"
            "%s\n"
            "%d\n"
@@ -377,14 +379,16 @@ static void outfits_update(unsigned int wid, char* str) {
            "%d\n"
            "\n"
            "%s SCred\n"
-           "%s SCred\n",
+           "%s SCred\n"
+           "%s\n",
            outfit->name,
            outfit_getType(outfit),
            player_outfitOwned(outfitname),
            outfit->mass,
            pilot_freeSpace(player),
            buf2,
-           buf3);
+           buf3,
+           (outfit->license != NULL) ? outfit->license : "None");
 
   window_modifyText(wid, "txtDDesc", buf);
 }
@@ -425,11 +429,25 @@ static int outfit_canBuy(Outfit* outfit, int q, int errmsg) {
     }
     return 0;
   }
+  /* Map alrady mapped. */
   else if(outfit_isMap(outfit) && map_isMapped(NULL, outfit->u.map.radius)) {
     if(errmsg != 0)
       dialogue_alert("You already own this map.");
     return 0;
   }
+  /* Already has license. */
+  else if(outfit_isLicense(outfit) && player_hasLicense(outfit->name)) {
+    if(errmsg != 0)
+      dialogue_alert("You already have this license.");
+    return 0;
+  }
+  /* Needs license. */
+  else if((outfit->license != NULL) && !player_hasLicense(outfit->name)) {
+    if(errmsg != 0)
+      dialogue_alert("You need the '%s' license to buy this outfit.",
+          outfit->license);
+    return 0;
+  }
 
   return 1;
 }
@@ -561,23 +579,24 @@ static void shipyard_open(void) {
 
   /* Text. */
   window_addText(wid, 40+300+40, -55,
-                 80, 96, 0, "txtSDesc", &gl_smallFont, &cDConsole,
+                 80, 128, 0, "txtSDesc", &gl_smallFont, &cDConsole,
                  "Name:\n"
                  "Class:\n"
                  "Fabricator:\n"
                  "\n"
                  "Price:\n"
-                 "Money:\n");
+                 "Money:\n"
+                 "License:\n");
 
   window_addText(wid, 40+300+40+80, -55,
-                 130, 96, 0, "txtDDesc", &gl_smallFont, &cBlack, NULL);
+                 130, 128, 0, "txtDDesc", &gl_smallFont, &cBlack, NULL);
 
 
-  window_addText(wid, 20+310+40, -175,
+  window_addText(wid, 20+310+40, -55-128-20,
                  SHIPYARD_WIDTH-(20+310+40) - 20, 185, 0, "txtDescription",
                  &gl_smallFont, NULL, NULL);
 
-  /* Setup the ships to buy/sell. */
+  /* Set up the ships to buy/sell. */
   ships = ship_getTech(&nships, land_planet->tech, PLANET_TECH_MAX);
 
   if(nships <= 0) {
@@ -614,7 +633,7 @@ static void shipyard_update(unsigned int wid, char* str) {
   (void)str;
   char* shipname;
   Ship* ship;
-  char buf[80], buf2[16], buf3[16];
+  char buf[PATH_MAX], buf2[16], buf3[16];
 
   shipname = toolkit_getList(wid, "iarShipyard");
 
@@ -623,12 +642,13 @@ static void shipyard_update(unsigned int wid, char* str) {
     window_modifyImage(wid, "imgTarget", NULL);
     window_disableButton(wid, "btnBuyShip");
     window_disableButton(wid, "btnInfoShip");
-    snprintf(buf, 80,
+    snprintf(buf, PATH_MAX,
         "None\n"
         "NA\n"
         "NA\n"
         "\n"
         "NA\n"
+        "NA\n"
         "NA\n");
     window_modifyText(wid, "txtDDesc", buf);
     return;
@@ -644,18 +664,20 @@ static void shipyard_update(unsigned int wid, char* str) {
 
   credits2str(buf2, ship->price,   2);
   credits2str(buf3, player->credits, 2);
-  snprintf(buf, 80,
+  snprintf(buf, PATH_MAX,
            "%s\n"
            "%s\n"
            "%s\n"
            "\n"
            "%s SCred\n"
-           "%s SCred\n",
+           "%s SCred\n"
+           "%s\n",
            ship->name,
            ship_class(ship),
            ship->fabricator,
            buf2,
-           buf3);
+           buf3,
+           (ship->license != NULL) ? ship->license : "None");
 
   window_modifyText(wid, "txtDDesc", buf);
 
@@ -686,6 +708,13 @@ static void shipyard_buy(unsigned int wid, char* str) {
     return;
   }
 
+  /* Must have enough credits. */
+  if((ship->license != NULL) && !player_hasLicense(ship->license)) {
+    dialogue_alert("You do not have the '%s' license required to buy this ship.",
+        ship->license);
+    return;
+  }
+
   if(pilot_cargoUsed(player) > ship->cap_cargo) {
     dialogue_alert("You won't have space to move your current cargo onto the new ship.");
     return;
diff --git a/src/outfit.c b/src/outfit.c
index b6ee512..d3c05cc 100644
--- a/src/outfit.c
+++ b/src/outfit.c
@@ -40,6 +40,7 @@ static void outfit_parseSJammer(Outfit* tmp, const xmlNodePtr parent);
 static void outfit_parseSFighterBay(Outfit* tmp, const xmlNodePtr parent);
 static void outfit_parseSFighter(Outfit* tmp, const xmlNodePtr parent);
 static void outfit_parseSMap(Outfit* tmp, const xmlNodePtr parent);
+static void outfit_parseSLicense(Outfit* tmp, const xmlNodePtr parent);
 
 /* Return an outfit. */
 Outfit* outfit_get(const char* name) {
@@ -302,6 +303,14 @@ int outfit_isMap(const Outfit* o) {
   return(o->type == OUTFIT_TYPE_MAP);
 }
 
+/**
+ * @brief Check if outfit is a licence.
+ *    @param o Outfit to check.
+ *    @return 1 if o is a map.
+ */
+int outfit_isLicense(const Outfit* o) {
+  return (o->type == OUTFIT_TYPE_LICENSE);
+}
 
 /**
  * @fn glTexture* outfit_gfx(const Outfit* o)
@@ -446,7 +455,8 @@ const char* outfit_getType(const Outfit* o) {
     "Jammer",
     "Fighter Bay",
     "Fighter",
-    "Map"
+    "Map",
+    "License"
   };
 
   return outfit_typename[o->type];
@@ -471,6 +481,7 @@ const char* outfit_getTypeBroad(const Outfit* o) {
   else if(outfit_isFighterBay(o))   return "Fighter Bay";
   else if(outfit_isFighter(o))      return "Fighter";
   else if(outfit_isMap(o))          return "Map";
+  else if(outfit_isLicense(o))      return "License";
   else                              return "Unknown";  
 }
 
@@ -505,10 +516,11 @@ static OutfitType outfit_strToOutfitType(char* buf) {
   O_CMP("missile swarm smart ammo",   OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO);
   O_CMP("modification",               OUTFIT_TYPE_MODIFICATION);
   O_CMP("afterburner",                OUTFIT_TYPE_AFTERBURNER);
-  O_CMP("map",                        OUTFIT_TYPE_MAP);
   O_CMP("fighter bay",                OUTFIT_TYPE_FIGHTER_BAY);
   O_CMP("fighter",                    OUTFIT_TYPE_FIGHTER);
   O_CMP("jammer",                     OUTFIT_TYPE_JAMMER);
+  O_CMP("map",                        OUTFIT_TYPE_MAP);
+  O_CMP("license",                    OUTFIT_TYPE_LICENSE);
 
   WARN("Invalid outfit type '%s'", buf);
   return OUTFIT_TYPE_NULL;
@@ -835,6 +847,19 @@ static void outfit_parseSMap(Outfit* tmp, const xmlNodePtr parent) {
     WARN("Outfit '%s' missing/invalid 'radius' element", tmp->name);
 }
 
+/**
+ * @brief Parses the license tidbits of the outfit.
+ *    @param tmp Outfit to finish loading.
+ *    @param parent Outfit's parent node.
+ */
+static void outfit_parseSLicense(Outfit* tmp, const xmlNodePtr parent) {
+  /* Licenses have no specific tidbits. */
+  (void)tmp;
+  (void)parent;
+
+
+}
+
 /* Parses the jammer tidbits of the outfit. */
 static void outfit_parseSJammer(Outfit* tmp, const xmlNodePtr parent) {
   xmlNodePtr node;
@@ -876,6 +901,7 @@ static int outfit_parse(Outfit* tmp, const xmlNodePtr parent) {
       do {
         xmlr_int(cur, "max", tmp->max);
         xmlr_int(cur, "tech", tmp->tech);
+        xmlr_strd(cur, "license", tmp->license);
         xmlr_int(cur, "mass", tmp->mass);
         xmlr_int(cur, "price", tmp->price);
         xmlr_strd(cur, "description", tmp->description);
@@ -923,6 +949,8 @@ static int outfit_parse(Outfit* tmp, const xmlNodePtr parent) {
         outfit_parseSFighter(tmp, node);
       else if(outfit_isMap(tmp))
         outfit_parseSMap(tmp, node);
+      else if (outfit_isLicense(tmp))
+        outfit_parseSLicense(tmp, node);
     }
   } while(xml_nextNode(node));
 #define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name)
diff --git a/src/outfit.h b/src/outfit.h
index b6ea718..daa958f 100644
--- a/src/outfit.h
+++ b/src/outfit.h
@@ -37,6 +37,7 @@ typedef enum OutfitType_ {
   OUTFIT_TYPE_FIGHTER_BAY,                /**< Contains other ships. */
   OUTFIT_TYPE_FIGHTER,                    /**< Ship contained in FIGHTER BAY. */
   OUTFIT_TYPE_MAP,                        /**< Give the player more knowledge about systems. */
+  OUTFIT_TYPE_LICENSE,                    /**< License that allows player to buy special stuff. */
   OUTFIT_TYPE_SENTINEL                    /**< Indicates last type. */
 } OutfitType;
 
@@ -231,6 +232,7 @@ typedef struct Outfit_ {
   /* General specs. */
   int max;                  /**< Max amount one can own. */
   int tech;                 /**< Tech needed to sell it. */
+  int license;              /**< Licenses needed to buy it. */
   int mass;                 /**< How much weapon capacity is needed. */
 
   /* Store stuff. */
@@ -277,6 +279,7 @@ int outfit_isJammer(const Outfit* o);
 int outfit_isFighterBay(const Outfit* o);
 int outfit_isFighter(const Outfit* o);
 int outfit_isMap(const Outfit* o);
+int outfit_isLicense(const Outfit* o);
 const char* outfit_getType(const Outfit* o);
 const char* outfit_getTypeBroad(const Outfit* o);
 
diff --git a/src/pilot.c b/src/pilot.c
index 1289844..c493041 100644
--- a/src/pilot.c
+++ b/src/pilot.c
@@ -59,6 +59,7 @@ extern double player_faceHyperspace(void);
 extern void player_dead(void);
 extern void player_destroyed(void);
 extern int gui_load(const char* name);
+extern void player_addLicense(char* license);
 /* Internal. */
 static int pilot_getStackPos(const unsigned int id);
 static void pilot_shootWeapon(Pilot* p, PilotOutfit* w);
@@ -915,7 +916,14 @@ int pilot_addOutfit(Pilot* pilot, Outfit* outfit, int quantity) {
 
   /* Special case if it's a map. */
   if(outfit_isMap(outfit)) {
-    map_map(NULL, outfit->u.map.radius);
+    if(pilot == player) /* Only player can get it. */
+      map_map(NULL, outfit->u.map.radius);
+    return 1; /* Must return 1 for paying purposes. */
+  }
+  /* Special case if it's a license. */
+  else if(outfit_isLicense(outfit)) {
+    if(pilot == player) /* Only player can get it. */
+      player_addLicense(outfit->name);
     return 1; /* Must return 1 for paying purposes. */
   }
 
diff --git a/src/player.c b/src/player.c
index 15536b3..7c75571 100644
--- a/src/player.c
+++ b/src/player.c
@@ -58,6 +58,10 @@ static double player_px, player_py, player_vx, player_vy, player_dir; /**< More
 static int player_credits = 0;          /**< Temp hack on create. */
 static char* player_mission = NULL;     /**< More hack. */
 
+/* Licenses. */
+static char** player_licenses = NULL; /**< Licenses player has. */
+static int player_nlicenses = 0;      /**< Number of licenses player has. */
+
 /*
  * Player sounds.
  */
@@ -226,6 +230,7 @@ static void gui_cleanup(void);
 static int player_saveShip(xmlTextWriterPtr writer, Pilot* ship, char* loc);
 static int player_parse(xmlNodePtr parent);
 static int player_parseDone(xmlNodePtr parent);
+static int player_parseLicenses(xmlNodePtr parent);
 static int player_parseShip(xmlNodePtr parent, int is_player);
 
 /* Externed. */
@@ -631,6 +636,15 @@ void player_cleanup(void) {
     missions_mdone  = 0;
   }
 
+  /* Clean up licenses. */
+  if(player_nlicenses > 0) {
+    for(i = 0; i < player_nlicenses; i++)
+      free(player_licenses[i]);
+    free(player_licenses);
+    player_licenses = NULL;
+    player_nlicenses = 0;
+  }
+
   pilots_cleanAll();
   if(player != NULL) {
     pilot_free(player);
@@ -2320,27 +2334,63 @@ int player_missionAlreadyDone(int id) {
   return 0;
 }
 
+/**
+ * @brief Check to see if player has license.
+ *    @param license License to check to see if the player has.
+ *    @return 1 if has license, 0 if doesn't.
+ */
+int player_hasLicense(char* license) {
+  int i;
+  for(i = 0; i < player_nlicenses; i++)
+    if(strcmp(license, player_licenses[i])==0)
+      return 1;
+  return 0;
+}
+
+/**
+ * @brief Give the player a license.
+ *    @brief license License to give the player.
+ */
+void player_addLicense(char* license) {
+  /* Player already has license. */
+  if(player_hasLicense(license))
+    return;
+
+  /* Add the license. */
+  player_nlicenses++;
+  player_licenses = realloc(player_licenses, sizeof(char*)*player_nlicenses);
+  player_licenses[player_nlicenses-1] = strdup(license);
+}
+
 /* Save the player in a freaking xmlfile. */
 int player_save(xmlTextWriterPtr writer) {
   int i;
   MissionData* m;
 
   xmlw_startElem(writer, "player");
+  
+  /* Standard player details. */
   xmlw_attr(writer, "name", player_name);
-
   xmlw_elem(writer, "rating", "%f", player_crating);
-  xmlw_elem(writer, "scred", "%d", player->credits);
+  xmlw_elem(writer, "credits", "%d", player->credits);
   xmlw_elem(writer, "time", "%d", ltime_get());
 
+  /* Current ship. */
   xmlw_elem(writer, "location", land_planet->name);
   player_saveShip(writer, player, NULL); /* Current ship. */
 
+  /* Ships. */
   xmlw_startElem(writer, "ships");
   for(i = 0; i < player_nstack; i++)
     player_saveShip(writer, player_stack[i], player_lstack[i]);
-
   xmlw_endElem(writer); /* Player. */
 
+  /* Licenses. */
+  xmlw_startElem(writer, "licenses");
+  for(i = 0; i < player_nlicenses; i++)
+    xmlw_elem(writer, "license", player_licenses[i]);
+  xmlw_endElem(writer) /* "license" */
+
   /* Mission the player has done. */
   xmlw_startElem(writer, "missions_done");
 
@@ -2466,15 +2516,16 @@ static int player_parse(xmlNodePtr parent) {
     if(xml_isNode(node, "ship"))
       player_parseShip(node, 1);
 
-    if(xml_isNode(node, "ships")) {
+    else if(xml_isNode(node, "ships")) {
       cur = node->xmlChildrenNode;
       do {
         if(xml_isNode(cur, "ship"))
           player_parseShip(cur, 0);
       } while(xml_nextNode(cur));
     }
-    if(xml_isNode(node, "missions_done"))
-      player_parseDone(node);
+    else if(xml_isNode(node, "licenses"))
+      player_parseLicenses(node);
+
   } while(xml_nextNode(node));
 
   /* Set global thingies. */
@@ -2513,6 +2564,24 @@ static int player_parseDone(xmlNodePtr parent) {
   return 0;
 }
 
+/**
+ * @brief Parse player's licenses.
+ *    @param parent Node of the licenses.
+ *    @return 0 on success.
+ */
+static int player_parseLicenses(xmlNodePtr parent) {
+  xmlNodePtr node;
+
+  node = parent->xmlChildrenNode;
+
+  do {
+    if(xml_isNode(node, "license"))
+      player_addLicense(xml_get(node));
+  } while(xml_nextNode(node));
+
+  return 0;
+}
+
 static int player_parseShip(xmlNodePtr parent, int is_player) {
   char* name, *model, *loc, *q, *id;
   int i, n;
diff --git a/src/player.h b/src/player.h
index d44f496..293c0d2 100644
--- a/src/player.h
+++ b/src/player.h
@@ -71,6 +71,10 @@ void    player_rmShip(char* shipname);
 void player_missionFinished(int id);
 int player_missionAlreadyDone(int id);
 
+/* Licenses. */
+void player_addLicense(char* license);
+int player_hasLicense(char* license);
+
 /* Keybind actions. */
 void player_targetHostile(void);
 void player_targetNext(void);
diff --git a/src/ship.c b/src/ship.c
index 4001c4e..5f29bcc 100644
--- a/src/ship.c
+++ b/src/ship.c
@@ -273,8 +273,9 @@ static Ship* ship_parse(xmlNodePtr parent) {
     if(xml_isNode(node, "class")) {
       tmp->class = ship_classFromString(xml_get(node));
     }
-    xmlr_int(node, "price", tmp->price);
-    xmlr_int(node, "tech", tmp->tech);
+    xmlr_int( node, "price", tmp->price);
+    xmlr_int( node, "tech", tmp->tech);
+    xmlr_strd(node, "license", tmp->license);
     xmlr_strd(node, "fabricator", tmp->fabricator);
     xmlr_strd(node, "description", tmp->description);
     if(xml_isNode(node, "movement")) {
diff --git a/src/ship.h b/src/ship.h
index d4830ae..f42dc9e 100644
--- a/src/ship.h
+++ b/src/ship.h
@@ -52,10 +52,11 @@ typedef struct Ship_ {
   ShipClass class; /* Ship class. */
 
   /* Store stuff. */
-  unsigned int price; /* Price! */
-  int tech;
-  char* fabricator;   /* Manufacturer. */
-  char* description;  /* Sales pitch. */
+  unsigned int price; /**< Price! */
+  int tech;           /**< Tech needed for it to be availabe. See space.c */
+  char* license;      /**< License needed to buy it. */
+  char* fabricator;   /**< Manufacturer. */
+  char* description;  /**< Sales pitch. */
 
   /* Movement. */
   double thrust, turn, speed;