diff --git a/dat/outfit.xml b/dat/outfit.xml
index c4d047a..4d5d2ba 100644
--- a/dat/outfit.xml
+++ b/dat/outfit.xml
@@ -391,4 +391,17 @@
 <cargo>-15</cargo>
 </specific>
 </outfit>
+<outfit name="Star Map">
+<general>
+<max>1</max>
+<tech>4</tech>
+<mass>0</mass>
+<price>7000</price>
+<description>A Star Map will give you details about all systems up to 2 jumps away. It's a great way to discover parts of the universe.</description>
+<gfx_store>map</gfx_store>
+</general>
+<specific type="map">
+<radius>2</radius>
+</specific>
+</outfit>
 </Outfits>
diff --git a/gfx/outfit/store/map.png b/gfx/outfit/store/map.png
new file mode 100644
index 0000000..3fb936a
Binary files /dev/null and b/gfx/outfit/store/map.png differ
diff --git a/src/llua.c b/src/llua.c
index 441a345..89fc5b7 100644
--- a/src/llua.c
+++ b/src/llua.c
@@ -191,7 +191,7 @@ static int space_jumpDist(lua_State* L) {
   else
     goal = cur_system->name;
 
-  s = map_getJumpPath(&jumps, start, goal);
+  s = map_getJumpPath(&jumps, start, goal, 1);
   free(s);
 
   lua_pushnumber(L, jumps);
diff --git a/src/map.c b/src/map.c
index 074b5ee..36ed00c 100644
--- a/src/map.c
+++ b/src/map.c
@@ -282,7 +282,7 @@ static void map_mouse(SDL_Event* event, double mx, double my) {
           if(map_path)
             free(map_path);
           map_path = map_getJumpPath(&map_npath,
-              cur_system->name, sys->name);
+              cur_system->name, sys->name, 0);
 
           if(map_npath == 0)
             hyperspace_target = -1;
@@ -540,7 +540,7 @@ static void A_freeList(SysNode* first) {
   free(p);
 }
 
-StarSystem** map_getJumpPath(int* njumps, char* sysstart, char* sysend) {
+StarSystem** map_getJumpPath(int* njumps, char* sysstart, char* sysend, int ignore_known) {
   int i, cost;
 
   StarSystem* sys, *ssys, *esys, **res;
@@ -556,7 +556,7 @@ StarSystem** map_getJumpPath(int* njumps, char* sysstart, char* sysend) {
   esys = system_get(sysend);    /* End. */
 
   /* System target must be known. */
-  if(!sys_isKnown(esys)) {
+  if(!ignore_known && !sys_isKnown(esys)) {
     if(space_sysReachable(esys)) { /* Can we still reach it? */
       res = malloc(sizeof(StarSystem*));
       (*njumps) = 1;
@@ -582,7 +582,7 @@ StarSystem** map_getJumpPath(int* njumps, char* sysstart, char* sysend) {
     for(i = 0; i < cur->sys->njumps; i++) {
       sys = &systems_stack[cur->sys->jumps[i]];
 
-      if(!sys_isKnown(sys)) continue;
+      if(!ignore_known && !sys_isKnown(sys)) continue;
 
       neighbour = A_newNode(sys, NULL);
 
@@ -617,4 +617,44 @@ StarSystem** map_getJumpPath(int* njumps, char* sysstart, char* sysend) {
   return res;
 }
 
+/* Marks maps around a radius of current system as known. */
+int map_map(char* targ_sys, int r) {
+  int i, dep;
+  StarSystem* sys, *jsys;
+  SysNode* closed, *open, *cur, *neighbour;
+
+  A_gc = NULL;
+  open = closed = NULL;
+
+  if(targ_sys == NULL) sys = cur_system;
+  else sys = system_get(targ_sys);
+  sys_setFlag(sys, SYSTEM_KNOWN);
+  open = A_newNode(sys, NULL);
+  open->r = 0;
+
+  while((cur = A_lowest(open)) != NULL) {
+    /* Mark system as known and go to next. */
+    sys = cur->sys;
+    dep = cur->r;
+    sys_setFlag(sys, SYSTEM_KNOWN);
+    open = A_rm(open, sys);
+    closed = A_add(closed, cur);
+    
+    /* Check it's jumps. */
+    for(i = 0; i < sys->njumps; i++) {
+      jsys = &systems_stack[cur->sys->jumps[i]];
+
+      /* System has already been parsed or is too deep. */
+      if((A_in(closed, jsys) != NULL) || (dep+1 > r))
+        continue;
+
+      /* Create new node and such. */
+      neighbour = A_newNode(jsys, NULL);
+      neighbour->r = dep+1;
+      open = A_add(open, neighbour);
+    }
+  }
+  A_freeList(A_gc);
+  return 0;
+}
 
diff --git a/src/map.h b/src/map.h
index 3520f6b..93983f6 100644
--- a/src/map.h
+++ b/src/map.h
@@ -9,5 +9,6 @@ void map_clear(void);
 void map_jump(void);
 
 /* Manipulate universe stuff. */
-StarSystem** map_getJumpPath(int* njumps, char* sysstart, char* sysend);
+StarSystem** map_getJumpPath(int* njumps, char* sysstart, char* sysend, int ignore_known);
+int map_map(char* targ_sys, int r);
 
diff --git a/src/outfit.c b/src/outfit.c
index 8b294a3..84d8225 100644
--- a/src/outfit.c
+++ b/src/outfit.c
@@ -35,6 +35,7 @@ static void outfit_parseSLauncher(Outfit* tmp, const xmlNodePtr parent);
 static void outfit_parseSAmmo(Outfit* tmp, const xmlNodePtr parent);
 static void outfit_parseSMod(Outfit* tmp, const xmlNodePtr parent);
 static void outfit_parseSAfterburner(Outfit* tmp, const xmlNodePtr parent);
+static void outfit_parseSMap(Outfit* tmp, const xmlNodePtr parent);
 
 /* Return an outfit. */
 Outfit* outfit_get(const char* name) {
@@ -128,6 +129,10 @@ int outfit_isAfterburner(const Outfit* o) {
   return (o->type == OUTFIT_TYPE_AFTERBURNER);
 }
 
+int outfit_isMap(const Outfit* o) {
+  return(o->type == OUTFIT_TYPE_MAP);
+}
+
 /* Get the outfit graphics. */
 glTexture* outfit_gfx(const Outfit* o) {
   if(outfit_isWeapon(o)) return o->u.blt.gfx_space;
@@ -189,7 +194,8 @@ const char* outfit_typename[] = {
   "Bolt Turret",
   "Beam Turret",
   "Ship Modification",
-  "Afterburner"
+  "Afterburner",
+  "Map"
 };
 
 const char* outfit_getType(const Outfit* o) {
@@ -204,17 +210,19 @@ const char* outfit_typenamebroad[] = {
   "Ammo",
   "Turret",
   "Modification",
-  "Afterburner"
+  "Afterburner",
+  "Map"
 };
 
 const char* outfit_getTypeBroad(const Outfit* o) {
   int i = 0;
-  if(outfit_isWeapon(o))      i = 1;
-  else if(outfit_isLauncher(o))   i = 2;
-  else if(outfit_isAmmo(o))     i = 3;
-  else if(outfit_isTurret(o))    i = 4;
-  else if(outfit_isMod(o))     i = 5;
-  else if(outfit_isAfterburner(o)) i = 6;
+  if(outfit_isWeapon(o))            i = 1;
+  else if(outfit_isLauncher(o))     i = 2;
+  else if(outfit_isAmmo(o))         i = 3;
+  else if(outfit_isTurret(o))       i = 4;
+  else if(outfit_isMod(o))          i = 5;
+  else if(outfit_isAfterburner(o))  i = 6;
+  else if(outfit_isMap(o))          i = 7;
 
   return outfit_typenamebroad[i];
 }
@@ -250,6 +258,7 @@ static OutfitType outfit_strToOutfitType(char* buf) {
   O_CMP("turret beam",                OUTFIT_TYPE_TURRET_BEAM);
   O_CMP("modification",               OUTFIT_TYPE_MODIFICATION);
   O_CMP("afterburner",                OUTFIT_TYPE_AFTERBURNER);
+  O_CMP("map",                        OUTFIT_TYPE_MAP);
 
   WARN("Invalid outfit type '%s'", buf);
   return OUTFIT_TYPE_NULL;
@@ -421,6 +430,16 @@ static void outfit_parseSAfterburner(Outfit* tmp, const xmlNodePtr parent) {
   } while((node = node->next));
 }
 
+static void outfit_parseSMap(Outfit* tmp, const xmlNodePtr parent) {
+  xmlNodePtr node;
+  node = parent->children;
+
+  do {
+    if(xml_isNode(node, "radius"))
+      tmp->u.map.radius = xml_getInt(node);
+  } while(xml_nextNode(node));
+}
+
 /* Parse and return Outfits from parent node. */
 static Outfit* outfit_parse(const xmlNodePtr parent) {
   Outfit* tmp = CALLOC_L(Outfit);
@@ -479,6 +498,8 @@ static Outfit* outfit_parse(const xmlNodePtr parent) {
         outfit_parseSMod(tmp, node);
       else if(outfit_isAfterburner(tmp))
         outfit_parseSAfterburner(tmp, node);
+      else if(outfit_isMap(tmp))
+        outfit_parseSMap(tmp, node);
     }
   } while((node = node->next));
 #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 1c20f70..33952cf 100644
--- a/src/outfit.h
+++ b/src/outfit.h
@@ -24,7 +24,8 @@ typedef enum OutfitType_ {
   OUTFIT_TYPE_TURRET_BOLT,
   OUTFIT_TYPE_TURRET_BEAM,
   OUTFIT_TYPE_MODIFICATION,
-  OUTFIT_TYPE_AFTERBURNER
+  OUTFIT_TYPE_AFTERBURNER,
+  OUTFIT_TYPE_MAP
 } OutfitType;
 
 typedef enum DamageType_ {
@@ -112,6 +113,9 @@ typedef struct Outfit_ {
       double speed_perc, speed_abs;     /* Percent and absolute speed bonus. */
       double energy;                    /* Energy used while active. */
     } afb;
+    struct { /* Map. */
+      double radius;                    /* Amount of systems to add */
+    } map;
   } u;
 } Outfit;
 
@@ -129,6 +133,7 @@ int outfit_isAmmo(const Outfit* o);
 int outfit_isTurret(const Outfit* o);
 int outfit_isMod(const Outfit* o);
 int outfit_isAfterburner(const Outfit* o);
+int outfit_isMap(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 a55fc96..2c84215 100644
--- a/src/pilot.c
+++ b/src/pilot.c
@@ -10,6 +10,7 @@
 #include "spfx.h"
 #include "rng.h"
 #include "hook.h"
+#include "map.h"
 #include "pilot.h"
 
 #define XML_ID    "Fleets" /* XML section identifier. */
@@ -533,6 +534,12 @@ int pilot_addOutfit(Pilot* pilot, Outfit* outfit, int quantity) {
 
   q = quantity;
 
+  /* Special case if it's a map. */
+  if(outfit_isMap(outfit)) {
+    map_map(NULL, outfit->u.map.radius);
+    return 1; /* Must return 1 for paying purposes. */
+  }
+
   /* Does outfit already exist? */
   for(i = 0; i < pilot->noutfits; i++)
     if(strcmp(outfit->name, pilot->outfits[i].outfit->name)==0) {