home · contact · privacy
Recalc FOVs and their map view results only on relevant changes.
[plomrogue2] / plomrogue / game.py
index 47f09d161ceff332b2e8ad43f086161d9ad75854..6e8afdf83182dded8a25c735b94dc7cdc2a7095a 100755 (executable)
@@ -117,6 +117,7 @@ class Game(GameBase):
     def __init__(self, save_file, *args, **kwargs):
         super().__init__(*args, **kwargs)
         self.changed = True
+        self.changed_fovs = True
         self.io = GameIO(self, save_file)
         self.tasks = {}
         self.thing_types = {}
@@ -213,32 +214,38 @@ class Game(GameBase):
         """Send out game state data relevant to clients."""
 
         # TODO: limit to connection_id if provided
+        print('DEBUG send_gamestate')
         self.io.send('TURN ' + str(self.turn))
         from plomrogue.mapping import FovMap
         import multiprocessing
-        pool = multiprocessing.Pool()
-        players = []
         c_ids = [c_id for c_id in self.sessions]
-        for c_id in c_ids:
-            players += [self.get_player(c_id)]
+        # Only recalc FOVs for players with ._fov = None
         player_fovs = []
-        for player in players:
-            player.prepare_multiprocessible_fov_stencil()
+        player_fov_ids = []
+        for c_id in c_ids:
+            player = self.get_player(c_id)
+            if player._fov:
+                continue
+            player.prepare_multiprocessible_fov_stencil() #!
             player_fovs += [player._fov]
-        new_fovs = pool.map(FovMap.init_terrain, [fov for fov in player_fovs])
-        for i in range(len(players)):
-            players[i]._fov = new_fovs[i]
-        pool.close()
-        pool.join()
+            player_fov_ids += [player.id_]
+        if len(player_fovs) > 0:
+            print('DEBUG regenerating FOVs')
+            pool = multiprocessing.Pool()
+            new_fovs = pool.map(FovMap.init_terrain, [fov for fov in player_fovs])  #!
+            pool.close()
+            pool.join()
+        for i in range(len(player_fov_ids)):
+            id_ = player_fov_ids[i]
+            player = self.get_thing(id_)
+            player._fov = new_fovs[i]
         for c_id in c_ids:
             player = self.get_player(c_id)
-            visible_terrain = player.fov_stencil_map()
             self.io.send('FOV %s' % quote(player.fov_stencil.terrain), c_id)
             self.io.send('MAP %s %s %s' % (self.get_map_geometry_shape(),
                                            player.fov_stencil.geometry.size,
-                                           quote(visible_terrain)), c_id)
-            visible_control = player.fov_stencil_map('control')
-            self.io.send('MAP_CONTROL %s' % quote(visible_control), c_id)
+                                           quote(player.visible_terrain)), c_id)
+            self.io.send('MAP_CONTROL %s' % quote(player.visible_control), c_id)
             for t in [t for t in self.things if player.fov_test(*t.position)]:
                 target_yx = player.fov_stencil.target_yx(*t.position)
                 self.io.send('THING %s %s %s %s %s' % (target_yx, t.type_,
@@ -288,6 +295,7 @@ class Game(GameBase):
                 if hasattr(t, 'name'):
                     self.io.send('CHAT ' + quote(t.name + ' left the map.'))
                 self.things.remove(t)
+                self.changed_fovs = True
                 to_delete += [connection_id]
         for connection_id in to_delete:
             del self.sessions[connection_id]
@@ -304,6 +312,9 @@ class Game(GameBase):
                     for connection_id in [c_id for c_id in self.sessions
                                           if self.sessions[c_id]['thing_id'] == t.id_]:
                         self.io.send('PLAY_ERROR ' + quote(str(e)), connection_id)
+        if self.changed_fovs:
+            for t in [t for t in self.things]:
+                t.invalidate_map_view()
         if self.changed:
             self.turn += 1
             # send_gamestate() can be rather expensive, due to among other reasons
@@ -312,6 +323,7 @@ class Game(GameBase):
                datetime.datetime.now() -self.send_gamestate_interval:
                 self.send_gamestate()
                 self.changed = False
+                self.changed_fovs = False
                 self.save()
                 self.last_send_gamestate = datetime.datetime.now()