Generate rogue-style levels with rooms.
authorNeil Moore <neil@s-z.org>
Wed, 28 May 2008 04:51:20 +0000 (00:51 -0400)
committerNeil Moore <neil@s-z.org>
Wed, 28 May 2008 04:51:20 +0000 (00:51 -0400)
New method level.Level.make_room_map to make such a map.
Generate such maps 90% of the time (otherwise use pick_tile{,_1}).

Rooms are unconnected currently.

Check for already-wielded object in AppUI.try_wield()
Clear the messages after each keypress in the main event loop.

level.py
roguelike.py
things.py

index 045604f..0fc1d51 100644 (file)
--- a/level.py
+++ b/level.py
@@ -42,6 +42,36 @@ class Level (object):
     def stair_available(self, stair):
         self.unconnected_stairs.add(stair)
 
+    def make_room_map(self, nrooms = 5, nstairs = 2):
+        self.grid = [ [ loc.Wall(self,i,j)
+            for j in xrange(self.w) ]
+            for i in xrange(self.h) ]
+        rooms = [ [ None for j in xrange(self.w) ] for i in xrange(self.h) ]
+
+        st_rooms = set(random.sample(xrange(nrooms), nstairs))
+
+        for rno in xrange(nrooms):
+            rh = random.randint(3, self.h/4)
+            rw = random.randint(3, self.w/4)
+            ry = random.randint(0, self.h - rh)
+            rx = random.randint(0, self.w - rw)
+            while rooms[ry][rx]:
+                rh = random.randint(3, self.h/4)
+                rw = random.randint(3, self.w/4)
+                ry = random.randint(0, self.h - rh)
+                rx = random.randint(0, self.w - rw)
+            for i in xrange(ry+1, ry+rh-1):
+                for j in xrange(rx+1, rx+rw-1):
+                    rooms[i][j] = rno
+                    if rno in st_rooms and i == ry + rh//2 and j == rx + rw//2:
+                        self.grid[i][j] = loc.Stair(self, i, j)
+                    else:
+                        self.grid[i][j] = loc.Floor(self, i, j)
+        
+        for row in self.grid:
+            for tile in row:
+                self.activate(tile)
+
     def __init__(self, filename=None, height=None, width=None, name=None):
         self.active_tiles = set()
         self.invalid_tiles = set()
@@ -51,7 +81,6 @@ class Level (object):
         self.needs_full_repaint = True
         self.filename = None
 
-        self.pick_tile = random.choice((self.pick_tile_1, self.pick_tile))
 
         if filename:
             assert height == width == name == None, \
@@ -63,9 +92,15 @@ class Level (object):
             self.w = width
             self.name = name or ""
 
-            self.grid = [ [ self.activate(self.pick_tile(i,j))
-                for j in xrange(self.w) ]
-                for i in xrange(self.h) ]
+            if random.random() < 0.1:
+                self.pick_tile = random.choice(
+                        (self.pick_tile_1, self.pick_tile))
+
+                self.grid = [ [ self.activate(self.pick_tile(i,j))
+                    for j in xrange(self.w) ]
+                    for i in xrange(self.h) ]
+            else:
+                self.make_room_map()
 
         random.shuffle(self.unconnected_drops)
 
index 1bb5352..c5070b9 100755 (executable)
@@ -188,6 +188,9 @@ class AppUI:
         if not it.wieldable():
             self.message("%s is not wieldable" % (it,))
             return False
+        if it.wielded:
+            self.message("%s already wielded" % (it,))
+            return False
         if self.player.wield(it):
             self.message("Wielded %s in %s" % (it,it.wielded[1]))
             return True
@@ -296,6 +299,7 @@ class AppUI:
             self.level().draw()
             self.mainpanel.window().refresh()
             c = self.stdscr.getch()
+            self.message()
 
             if self.mapped(c):
                 if not self.perform(c):
index 8d1bf5d..8bd431f 100644 (file)
--- a/things.py
+++ b/things.py
@@ -149,6 +149,7 @@ class Item(Thing):
             self.wielded[0].unwield(self)
 
 slotabbrevs = { 'hand': 'H', 'arm': 'A', 'body': 'B' }
+
 class Creature(Thing):
     def __init__(self, location=None):
         Thing.__init__(self, location)