Merge of doom
[koperkapel.git] / koperkapel / generators / maps.py
index bbb6d1384b8e59c4ee35c7b4a48576c58e2f3f38..6e6bdbdc1915f61627fb1c5872979bfe75fa5d54 100644 (file)
@@ -6,12 +6,18 @@ import json
 import os
 
 ATTRIBUTE_MAP = {
-    '#': {'base': 'cwall',
-          'behaviour': [],
-         },
-    ' ': {'base': 'floor',
-          'behaviour': ['walk', 'fly'],
-         },
+    ' ': {'floor': {'base': 'floor',
+                    'behaviour': ['walk', 'fly'],
+                    },
+          },
+    'o': {'tunnels': {'base': 'underground',
+                      'behaviour': [],
+                      }
+          },
+    '-': {'tunnels': {'base': 'tunnel',
+                      'behaviour': ['walk', ],
+                      },
+          },
 }
 
 
@@ -71,24 +77,25 @@ class Room:
                 target_rooms[index].link_passage(
                     other_tile[index], this_tile[index])
 
-    def link_passage(self, local_tile, foriegn_tile):
+    def link_passage(self, local_tile, foreign_tile):
         """ Link a passage between two rooms
         :param local_tile: tile in this room to which we wish to link
-        :param foriegn_tile: tile in another room to which we wish to link
+        :param foreign_tile: tile in another room to which we wish to link
         :return:
         """
-        self.passages.append([local_tile, foriegn_tile])
+        self.passages.append([local_tile, foreign_tile])
 
     def render_region(self, region, room_dist, region_size, tile_map, x, y):
         """ Check if a region is in this room and return the required tiles
         :param region: Region that we wish to render
         :param room_dist: Tile separation distance from other rooms
         :param region_size: Region size in tiles
+        :param tile_map: Tile map to update
+        :param x: X coordinate
+        :param y: Y coordinate
         :return:
         """
         if region in self.coordinates:
-            print(region)
-            print(self.region)
             print(self.coordinates)
             for ht in range(room_dist, region_size - room_dist):
                 for wt in range(room_dist, region_size - room_dist):
@@ -127,6 +134,10 @@ class Room:
                     #         self.map[h * self.region_size + ht]\
                     #             [w * self.region_size + wt] = ' '
 
+def random_cardinal():
+    """Return a random cardinal direction for random walks."""
+    return random.choice([(0, 1), (0, -1), (1, 0), (-1, 0)])
+
 
 class LevelGenerator:
     width = 0
@@ -164,16 +175,17 @@ class LevelGenerator:
         for region in regions_selected:
             self.rooms[region].connect_rooms(
                 [self.rooms[i] for i in regions_selected])
-            self.generate_tiles(region)
+            self.generate_room(region)
         region_coordinates_selected = [p for p in self.region_coordinates if
                                        p[0] in regions_selected]
         print('Coords: %s' % str(region_coordinates_selected))
         for coord in region_coordinates_selected:
             print(str(coord))
-            # self.rooms[coord[0]].render_region(
-            #     coord[1], self.dist_from_other_rooms, self.region_size,
-            #     self.map2, coord[1][0] * self.region_size,
-            #     coord[1][1] * self.region_size)
+            self.rooms[coord[0]].render_region(
+                coord[1], self.dist_from_other_rooms, self.region_size,
+                self.map2, coord[1][0] * self.region_size,
+                coord[1][1] * self.region_size)
+        # self.generate_underlayer()
 
     def generate_rooms(self):
         """ Generate a random level region map
@@ -209,15 +221,59 @@ class LevelGenerator:
                         increment_region = True
                 self.region_map[h][w] = update_value
                 if increment_region:
-                    r = Room([h, w], self.regions)
+                    r = Room([h, w], update_value)
                     self.rooms.append(r)
                     self.region_coordinates.append([update_value, [h, w]])
                     self.regions += 1
                 else:
-                    self.rooms[-1].add_region([h, w])
+                    for r in self.rooms:
+                        if r.region == update_value:
+                            r.add_region([h, w])
                     self.region_coordinates.append([update_value, [h, w]])
 
+    def generate_underlayer(self):
+        """Generate a small mess of tunnels to have something."""
+        width = len(self.map[0])
+        height = len(self.map)
+        row = ['o' for x in range(width)]
+        self.underlayer = [row[:] for x in range(height)]
+        # we create a set of biased random walks to create the tunnel network
+        for walk in range(random.randint(3, 6)):
+            x = width // 2 + random.randint(-8, 8)
+            y = height // 2 + random.randint(-8, 8)
+            dir_x, dir_y = random_cardinal()
+            max_steps = random.randint(40, width * height // 4)
+            for step in range(20, max_steps):
+                if 0 < x < width - 1:
+                    if 0 < y < height - 1:
+                        self.underlayer[y][x] = '-'
+                if random.random() > 0.7:
+                   dir_x, dir_y = random_cardinal()
+                x += dir_x
+                y += dir_y
+
     def generate_tiles(self, region_selected):
+        """Generate a small mess of tunnels to have something."""
+        width = len(self.map[0])
+        height = len(self.map)
+        row = ['o' for x in range(width)]
+        self.underlayer = [row[:] for x in range(height)]
+        # we create a set of biased random walks to create the tunnel network
+        for walk in range(random.randint(3, 6)):
+            x = width // 2 + random.randint(-8, 8)
+            y = height // 2 + random.randint(-8, 8)
+            dir_x, dir_y = random_cardinal()
+            max_steps = random.randint(40, width * height // 4)
+            for step in range(20, max_steps):
+                if 0 < x < width - 1:
+                    if 0 < y < height - 1:
+                        self.underlayer[y][x] = '-'
+                if random.random() > 0.7:
+                   dir_x, dir_y = random_cardinal()
+                x += dir_x
+                y += dir_y
+
+    def generate_room(self, region_selected):
         """
         :param region_selected:
         :return:
@@ -271,6 +327,13 @@ class LevelGenerator:
             file.write(''.join(l))
             file.write('\n')
         print('-----------------')
+        try:
+            for l in self.underlayer:
+                print(''.join(l))
+                file.write(''.join(l))
+                file.write('\n')
+        except AttributeError:
+            pass
         file.close()
         for l in self.region_map:
             # self._to_json()
@@ -278,15 +341,18 @@ class LevelGenerator:
 
     def _to_json(self):
         level = {}
+        level['tileset'] = 'bunker'
         level['tiles'] = []
-        for l in self.map:
+        for l, lu in zip(self.map, self.underlayer):
             row = []
-            for t in l:
-                row.append(ATTRIBUTE_MAP[t])
+            for t1, t2 in zip(l, lu):
+                tile = ATTRIBUTE_MAP[t1].copy()
+                tile.update(ATTRIBUTE_MAP[t2])
+                row.append(tile)
             level['tiles'].append(row)
-        name = os.path.join(os.path.dirname(__file__), '..', 'levels', 'map.json')
-        # FIXME: Do a lot better here 
+        # FIXME: Do a lot better here
         # Crude hack so the level is written into the levels folder
+        name = os.path.join(os.path.dirname(__file__), '..', 'levels', 'map.json')
         f = open(name, 'w')
         json.dump(level, f)
         f.close()