home · contact · privacy
Add surrounding maps of new terrain type ~.
authorChristian Heller <c.heller@plomlompom.de>
Fri, 26 Apr 2019 01:45:07 +0000 (03:45 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Fri, 26 Apr 2019 01:45:07 +0000 (03:45 +0200)
new/plomrogue/commands.py
new/plomrogue/game.py
new/plomrogue/things.py

index f9aa5fa1281d3e0a56d55ca797ad725ab61aa1f1..fc3a8a0d52d4fe66a7301f10812a834c2b854d1d 100644 (file)
@@ -10,10 +10,10 @@ def cmd_GET_GAMESTATE(game, connection_id):
     """Send game state to caller."""
     game.send_gamestate(connection_id)
 
-def cmd_MAP(game, yx):
-    """Create new map of size yx and only '?' cells."""
-    game.world.new_map((0,0), yx)
-cmd_MAP.argtypes = 'yx_tuple:pos'
+def cmd_MAP(game, big_yx, small_yx):
+    """Create new map of size small_yx at pos big_yx and only '?' cells."""
+    game.world.new_map(big_yx, small_yx)
+cmd_MAP.argtypes = 'yx_tuple yx_tuple:pos'
 
 def cmd_THING_TYPE(game, i, type_):
     t_old = game.world.get_thing(i)
@@ -59,9 +59,9 @@ def cmd_GET_PICKABLE_ITEMS(game, connection_id):
     else:
         game.io.send('PICKABLE_ITEMS ,')
 
-def cmd_TERRAIN_LINE(game, y, terrain_line):
-    game.world.maps[(0,0)].set_line(y, terrain_line)
-cmd_TERRAIN_LINE.argtypes = 'int:nonneg string'
+def cmd_TERRAIN_LINE(game, big_yx, y, terrain_line):
+    game.world.maps[big_yx].set_line(y, terrain_line)
+cmd_TERRAIN_LINE.argtypes = 'yx_tuple int:nonneg string'
 
 def cmd_PLAYER_ID(game, id_):
     # TODO: test whether valid thing ID
@@ -90,9 +90,13 @@ def cmd_SAVE(game):
     save_file_name = game.io.game_file_name + '.save'
     with open(save_file_name, 'w') as f:
         write(f, 'TURN %s' % game.world.turn)
-        write(f, 'MAP ' + stringify_yx(game.world.maps[(0,0)].size))
-        for y, line in game.world.maps[(0,0)].lines():
-            write(f, 'TERRAIN_LINE %5s %s' % (y, quote(line)))
+        for map_pos in game.world.maps:
+            write(f, 'MAP ' + stringify_yx(map_pos) + ' ' +
+                  stringify_yx(game.world.maps[(0,0)].size))
+        for map_pos in game.world.maps:
+            for y, line in game.world.maps[map_pos].lines():
+                 write(f, 'TERRAIN_LINE %s %5s %s' % (stringify_yx(map_pos),
+                                                      y, quote(line)))
         for thing in game.world.things:
             write(f, 'THING_TYPE %s %s' % (thing.id_, thing.type_))
             write(f, 'THING_POS %s %s %s' % (thing.id_,
index 18f45d88bad84df15138e20f26382b04a089dd67..eda54ae6db68a2ace43c7def87bea8b1f73a09f7 100755 (executable)
@@ -117,20 +117,22 @@ class World(WorldBase):
         self.turn = 0
         self.maps = {}
         self.new_map((0,0), yx)
-        #self.new_map((0,1), yx)
-        #self.new_map((1,1), yx)
-        #self.new_map((1,0), yx)
-        #self.new_map((1,-1), yx)
-        #self.new_map((0,-1), yx)
-        #self.new_map((-1,-1), yx)
-        #self.new_map((-1,0), yx)
-        #self.new_map((-1,1), yx)
-        for pos in self.maps[(0,0)]:
-            if 0 in pos or (yx[0] - 1) == pos[0] or (yx[1] - 1) == pos[1]:
-                self.maps[(0,0)][pos] = '#'
-                continue
-            self.maps[(0,0)][pos] = random.choice(('.', '.', '.', '.', 'x'))
-
+        self.new_map((0,1), yx)
+        self.new_map((1,1), yx)
+        self.new_map((1,0), yx)
+        self.new_map((1,-1), yx)
+        self.new_map((0,-1), yx)
+        self.new_map((-1,-1), yx)
+        self.new_map((-1,0), yx)
+        self.new_map((-1,1), yx)
+        for map_pos in self.maps:
+            map_ = self.maps[map_pos]
+            if (0,0) == map_pos:
+                for pos in map_:
+                    map_[pos] = random.choice(('.', '.', '.', '.', 'x'))
+            else:
+                for pos in map_:
+                    map_[pos] = '~'
         player = add_thing_at_random('human')
         self.player_id = player.id_
         add_thing_at_random('monster')
@@ -185,7 +187,7 @@ class Game:
 
         self.io.send('TURN ' + str(self.world.turn))
         visible_map = self.world.player.get_visible_map()
-        self.io.send('MAP ' + stringify_yx(visible_map.size))
+        self.io.send('MAP ' + stringify_yx([0,0]) + ' ' + stringify_yx(visible_map.size))
         for y, line in visible_map.lines():
             self.io.send('VISIBLE_MAP_LINE %5s %s' % (y, quote(line)))
         visible_things, offset = self.world.player.get_visible_things()
index 408448e3bad13814b89baab733cb2907ee346a52..b64584182f31e3b322a3cd2b1c0e7f6c5a144fde 100644 (file)
@@ -45,7 +45,7 @@ class ThingAnimate(Thing):
         super().__init__(*args, **kwargs)
         self.set_task('WAIT')
         self._last_task_result = None
-        self._radius = 16
+        self._radius = 8
         self.unset_surroundings()
 
     def move_on_dijkstra_map(self, own_pos, targets):
@@ -202,24 +202,40 @@ class ThingAnimate(Thing):
     def get_surrounding_map(self):
         if self._surrounding_map is not None:
             return self._surrounding_map
-        offset = self.get_surroundings_offset()
+
+        def pan_and_scan(size_of_axis, pos, offset):
+            big_pos = 0
+            small_pos = pos + offset
+            if small_pos < 0:
+                big_pos = -1
+                small_pos = size_of_axis + small_pos
+            elif small_pos >= size_of_axis:
+                big_pos = 1
+                small_pos = small_pos - size_of_axis
+            return big_pos, small_pos
+
         add_line = self.must_fix_indentation()
         self._surrounding_map = self.world.game.\
                                 map_type(size=(self._radius*2+1+int(add_line),
                                                self._radius*2+1))
+        size = self.world.maps[(0,0)].size
+        offset = self.get_surroundings_offset()
         for pos in self._surrounding_map:
-            offset_pos = (pos[0] + offset[0], pos[1] + offset[1])
-            if offset_pos[0] >= 0 and \
-               offset_pos[0] < self.world.maps[(0,0)].size[0] and \
-               offset_pos[1] >= 0 and \
-               offset_pos[1] < self.world.maps[(0,0)].size[1]:
-                self._surrounding_map[pos] = self.world.maps[(0,0)][offset_pos]
+            big_y, small_y = pan_and_scan(size[0], pos[0], offset[0])
+            big_x, small_x = pan_and_scan(size[1], pos[1], offset[1])
+            big_yx = (big_y, big_x)
+            small_yx = (small_y, small_x)
+            self._surrounding_map[pos] = self.world.maps[big_yx][small_yx]
         return self._surrounding_map
 
     def get_stencil(self):
         if self._stencil is not None:
             return self._stencil
-        m = self.get_surrounding_map()
+        surrounding_map = self.get_surrounding_map()
+        m = surrounding_map.new_from_shape(' ')
+        for pos in surrounding_map:
+            if surrounding_map[pos] in {'.', '~'}:
+                m[pos] = '.'
         offset = self.get_surroundings_offset()
         fov_center = (self.position[1][0] - offset[0],
                       self.position[1][1] - offset[1])
@@ -235,16 +251,28 @@ class ThingAnimate(Thing):
         return m
 
     def get_visible_things(self):
+
+        def calc_pos_in_fov(big_pos, small_pos, offset, size_of_axis):
+            pos = small_pos - offset
+            if big_pos == -1:
+                pos = small_pos - size_of_axis - offset
+            elif big_pos == 1:
+                pos = small_pos + size_of_axis - offset
+            return pos
+
         stencil = self.get_stencil()
         offset = self.get_surroundings_offset()
         visible_things = []
+        size = self.world.maps[(0,0)].size
+        fov_size = self.get_surrounding_map().size
         for thing in self.world.things:
-            if abs(thing.position[1][0] - self.position[1][0]) > self._radius or\
-               abs(thing.position[1][1] - self.position[1][1]) > self._radius:
+            big_pos = thing.position[0]
+            small_pos = thing.position[1]
+            pos_y = calc_pos_in_fov(big_pos[0], small_pos[0], offset[0], size[0])
+            pos_x = calc_pos_in_fov(big_pos[1], small_pos[1], offset[1], size[1])
+            if pos_y < 0 or pos_x < 0 or pos_y >= fov_size[0] or pos_x >= fov_size[1]:
                 continue
-            offset_pos = (thing.position[1][0] - offset[0],
-                          thing.position[1][1] - offset[1])
-            if (not thing.in_inventory) and stencil[offset_pos] == '.':
+            if (not thing.in_inventory) and stencil[(pos_y, pos_x)] == '.':
                 visible_things += [thing]
         return visible_things, offset