home · contact · privacy
Improve map handling between client and server, add map scrolling.
authorChristian Heller <c.heller@plomlompom.de>
Thu, 24 Jan 2019 04:08:28 +0000 (05:08 +0100)
committerChristian Heller <c.heller@plomlompom.de>
Thu, 24 Jan 2019 04:08:28 +0000 (05:08 +0100)
client-curses.py
server_/game.py

index 93b190bd76723b81e120c4d4c975f7407d7b8997..4981a331963e5eae773cb06f53892df99b74a782 100755 (executable)
@@ -9,7 +9,7 @@ import game_common
 
 class MapSquare(game_common.Map):
 
-    def list_terrain_to_lines(self, terrain_as_list):
+    def list_terrain_to_lines(self, terrain_as_list, center, size):
         terrain = ''.join(terrain_as_list)
         map_lines = []
         start_cut = 0
@@ -17,12 +17,27 @@ class MapSquare(game_common.Map):
             limit = start_cut + self.size[1]
             map_lines += [terrain[start_cut:limit]]
             start_cut = limit
+        if len(map_lines) > size[0] and center[0] > size[0] / 2:
+            diff = len(map_lines) - size[0]
+            if center[0] > len(map_lines) - size[0] / 2:
+                map_lines = map_lines[diff:]
+            else:
+                start = center[0] - int(size[0] / 2)
+                map_lines = map_lines[start:start + size[0]]
+        if self.size[1] > size[1] and center[1] > size[1] / 2:
+            if center[1] > self.size[1] - size[1] / 2:
+                cut_start = self.size[1] - size[1]
+                cut_end = None
+            else:
+                cut_start = center[1] - int(size[1] / 2)
+                cut_end = cut_start + size[1]
+            map_lines = [line[cut_start:cut_end] for line in map_lines]
         return map_lines
 
 
 class MapHex(game_common.Map):
 
-    def list_terrain_to_lines(self, terrain_as_list):
+    def list_terrain_to_lines(self, terrain_as_list, center, size):
         new_terrain_list = [' ']
         x = 0
         y = 0
@@ -35,7 +50,23 @@ class MapHex(game_common.Map):
                 y += 1
                 if y % 2 == 0:
                     new_terrain_list += [' ']
-        return ''.join(new_terrain_list).split('\n')
+        map_lines = ''.join(new_terrain_list).split('\n')
+        if len(map_lines) > size[0] and center[0] > size[0] / 2:
+            diff = len(map_lines) - size[0]
+            if center[0] > len(map_lines) - size[0] / 2:
+                map_lines = map_lines[diff:]
+            else:
+                start = center[0] - int(size[0] / 2)
+                map_lines = map_lines[start:start + size[0]]
+        if self.size[1]*2 > size[1] and center[1]*4 > size[1]:
+            if center[1]*2 > self.size[1]*2 - size[1] / 2:
+                cut_start = self.size[1] * 2 - size[1]
+                cut_end = None
+            else:
+                cut_start = center[1]*2 - int(size[1] / 2)
+                cut_end = cut_start + size[1]
+            map_lines = [line[cut_start:cut_end] for line in map_lines]
+        return map_lines
 
 
 map_manager = game_common.MapManager(globals())
@@ -52,6 +83,7 @@ class World(game_common.World):
         super().__init__(*args, **kwargs)
         self.game = game
         self.map_ = self.game.map_manager.get_map_class('Hex')()
+        self.player_position = (0, 0)
 
 
 class Game(game_common.CommonCommandsMixin):
@@ -89,7 +121,6 @@ class Game(game_common.CommonCommandsMixin):
     def cmd_NEW_TURN(self, n):
         """Set self.turn to n, empty self.things."""
         self.world.turn = n
-        self.tui.turn.do_update = True
         self.world.things = []
     cmd_NEW_TURN.argtypes = 'int:nonneg'
 
@@ -97,7 +128,12 @@ class Game(game_common.CommonCommandsMixin):
         self.world.map_.set_line(y, terrain_line)
     cmd_VISIBLE_MAP_LINE.argtypes = 'int:nonneg string'
 
-    def cmd_VISIBLE_MAP_COMPLETE(self):
+    def cmd_PLAYER_POS(self, yx):
+        self.world.player_position = yx
+    cmd_PLAYER_POS.argtypes = 'yx_tuple:pos'
+
+    def cmd_GAME_STATE_COMPLETE(self):
+        self.tui.turn.do_update = True
         self.tui.map_.do_update = True
 
 
@@ -208,7 +244,8 @@ class MapWidget(Widget):
             for t in self.tui.game.world.things:
                 pos_i = self.tui.game.world.map_.get_position_index(t.position)
                 terrain_as_list[pos_i] = self.tui.game.symbol_for_type(t.type_)
-            lines = self.tui.game.world.map_.list_terrain_to_lines(terrain_as_list)
+            center = self.tui.game.world.player_position
+            lines = self.tui.game.world.map_.list_terrain_to_lines(terrain_as_list, center, self.size)
             line_width = self.size[1]
             for line in lines:
                 if line_width > len(line):
index 015c8cbcc67cfb76b683bb76091203ef221b96ca..df6a9f24a9314c41ae32ec38292ab8ece824425a 100644 (file)
@@ -2,6 +2,7 @@ import sys
 sys.path.append('../')
 import game_common
 import server_.map_
+from parser import ArgError
 
 
 class GameError(Exception):
@@ -206,7 +207,9 @@ class Game(game_common.CommonCommandsMixin):
             self.io.send('THING_TYPE %s %s' % (thing.id_, thing.type_))
             self.io.send('THING_POS %s %s' % (thing.id_,
                                               stringify_yx(thing.position)))
-        self.io.send('VISIBLE_MAP_COMPLETE')
+        player = self.world.get_player()
+        self.io.send('PLAYER_POS %s' % (stringify_yx(player.position)))
+        self.io.send('GAME_STATE_COMPLETE')
 
     def proceed(self):
         """Send turn finish signal, run game world, send new world data.
@@ -272,7 +275,7 @@ class Game(game_common.CommonCommandsMixin):
         self.proceed()
 
     def cmd_GET_GAMESTATE(self, connection_id):
-        """Send game state jto caller."""
+        """Send game state to caller."""
         self.send_gamestate(connection_id)
 
     def cmd_ECHO(self, msg, connection_id):