home · contact · privacy
To client, add map examining cursor.
authorChristian Heller <c.heller@plomlompom.de>
Tue, 9 Apr 2019 22:31:16 +0000 (00:31 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Tue, 9 Apr 2019 22:31:16 +0000 (00:31 +0200)
new/example_client.py
new/plomrogue/mapping.py
new/plomrogue/tasks.py

index 1b1d55fb3a0a81039f6fa009224ca061d63fdbfc..234ed768ed53df4e6d93ccdf110c9cd42c404a70 100755 (executable)
@@ -5,14 +5,14 @@ import threading
 from plomrogue.parser import ArgError, Parser
 from plomrogue.commands import cmd_MAP, cmd_THING_POS, cmd_PLAYER_ID
 from plomrogue.game import Game, WorldBase
-from plomrogue.mapping import MapBase
+from plomrogue.mapping import MapHex
 from plomrogue.io import PlomSocket
 from plomrogue.things import ThingBase
 import types
 import queue
 
 
-class Map(MapBase):
+class ClientMap(MapHex):
 
     def y_cut(self, map_lines, center_y, view_height):
         map_height = len(map_lines)
@@ -72,13 +72,13 @@ class World(WorldBase):
         on any update, even before we actually receive map data.
         """
         super().__init__(*args, **kwargs)
-        self.map_ = Map()
+        self.map_ = ClientMap()
         self.player_inventory = []
         self.player_id = 0
         self.pickable_items = []
 
     def new_map(self, yx):
-        self.map_ = Map(yx)
+        self.map_ = ClientMap(yx)
 
     @property
     def player(self):
@@ -347,6 +347,11 @@ class PickableItemsWidget(ItemsSelectorWidget):
 
 class MapWidget(Widget):
 
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.examine_mode = False
+        self.examine_pos = (0, 0)
+
     def draw(self):
 
         def annotated_terrain():
@@ -361,6 +366,10 @@ class MapWidget(Widget):
                     terrain_as_list[pos_i] = (symbol, '+')
                 else:
                     terrain_as_list[pos_i] = symbol
+            if self.examine_mode:
+                pos_i = self.tui.game.world.map_.\
+                        get_position_index(self.examine_pos)
+                terrain_as_list[pos_i] = (terrain_as_list[pos_i][0], '?')
             return terrain_as_list
 
         def pad_or_cut_x(lines):
@@ -401,6 +410,8 @@ class MapWidget(Widget):
 
         annotated_terrain = annotated_terrain()
         center = self.tui.game.world.player.position
+        if self.examine_mode:
+            center = self.examine_pos
         lines = self.tui.game.world.map_.format_to_view(annotated_terrain,
                                                         center, self.size)
         pad_or_cut_x(lines)
@@ -456,6 +467,7 @@ class TUI:
                 self.item_pointer = len(selectables) - 1
             if key == 'c':
                 switch_widgets(widget, map_widget)
+                map_widget.examine_mode = False
             elif key == 'j':
                 self.item_pointer += 1
             elif key == 'k' and self.item_pointer > 0:
@@ -472,6 +484,13 @@ class TUI:
             trigger = widget.check_updates[0]
             self.to_update[trigger] = True
 
+        def move_examiner(direction):
+            start_pos = map_widget.examine_pos
+            new_examine_pos = self.game.world.map_.move(start_pos, direction)
+            if new_examine_pos:
+                map_widget.examine_pos = new_examine_pos
+            self.to_update['map'] = True
+
         setup_screen(stdscr)
         curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_RED)
         curses.init_pair(2, curses.COLOR_BLACK, curses.COLOR_GREEN)
@@ -546,25 +565,42 @@ class TUI:
                         for w in top_widgets:
                             w.ensure_freshness(True)
                 elif map_widget.visible:
-                    if key == 'w':
+                    if key == '?':
+                        map_widget.examine_mode = not map_widget.examine_mode
+                        map_widget.examine_pos = self.game.world.player.position
+                        self.to_update['map'] = True
+                    elif key == 'p':
+                        self.socket.send('GET_PICKABLE_ITEMS')
+                        self.item_pointer = 0
+                        switch_widgets(map_widget, pickable_items_widget)
+                    elif key == 'i':
+                        self.item_pointer = 0
+                        switch_widgets(map_widget, inventory_widget)
+                    elif map_widget.examine_mode:
+                        if key == 'w':
+                            move_examiner('UPLEFT')
+                        elif key == 'e':
+                            move_examiner('UPRIGHT')
+                        elif key == 's':
+                            move_examiner('LEFT')
+                        elif key == 'd':
+                            move_examiner('RIGHT')
+                        elif key == 'x':
+                            move_examiner('DOWNLEFT')
+                        elif key == 'c':
+                            move_examiner('DOWNRIGHT')
+                    elif key == 'w':
                         self.socket.send('TASK:MOVE UPLEFT')
                     elif key == 'e':
                         self.socket.send('TASK:MOVE UPRIGHT')
-                    if key == 's':
+                    elif key == 's':
                         self.socket.send('TASK:MOVE LEFT')
                     elif key == 'd':
                         self.socket.send('TASK:MOVE RIGHT')
-                    if key == 'x':
+                    elif key == 'x':
                         self.socket.send('TASK:MOVE DOWNLEFT')
                     elif key == 'c':
                         self.socket.send('TASK:MOVE DOWNRIGHT')
-                    elif key == 'p':
-                        self.socket.send('GET_PICKABLE_ITEMS')
-                        self.item_pointer = 0
-                        switch_widgets(map_widget, pickable_items_widget)
-                    elif key == 'i':
-                        self.item_pointer = 0
-                        switch_widgets(map_widget, inventory_widget)
                 elif pickable_items_widget.visible:
                     pick_or_drop_menu('p', pickable_items_widget,
                                       self.game.world.pickable_items,
index 64dad7c8a5ac0490c1f440dc3909876de4d5aa36..c9398d47ef515f4d8e085005485b94fb82b450b9 100644 (file)
@@ -2,12 +2,28 @@ from plomrogue.errors import ArgError
 
 
 
-class MapBase:
+class Map:
 
     def __init__(self, size=(0, 0)):
         self.size = size
         self.terrain = '?'*self.size_i
 
+    def __getitem__(self, yx):
+        return self.terrain[self.get_position_index(yx)]
+
+    def __setitem__(self, yx, c):
+        pos_i = self.get_position_index(yx)
+        if type(c) == str:
+            self.terrain = self.terrain[:pos_i] + c + self.terrain[pos_i + 1:]
+        else:
+            self.terrain[pos_i] = c
+
+    def __iter__(self):
+        """Iterate over YX position coordinates."""
+        for y in range(self.size[0]):
+            for x in range(self.size[1]):
+                yield (y, x)
+
     @property
     def size_i(self):
         return self.size[0] * self.size[1]
@@ -26,25 +42,6 @@ class MapBase:
     def get_position_index(self, yx):
         return yx[0] * self.size[1] + yx[1]
 
-
-class Map(MapBase):
-
-    def __getitem__(self, yx):
-        return self.terrain[self.get_position_index(yx)]
-
-    def __setitem__(self, yx, c):
-        pos_i = self.get_position_index(yx)
-        if type(c) == str:
-            self.terrain = self.terrain[:pos_i] + c + self.terrain[pos_i + 1:]
-        else:
-            self.terrain[pos_i] = c
-
-    def __iter__(self):
-        """Iterate over YX position coordinates."""
-        for y in range(self.size[0]):
-            for x in range(self.size[1]):
-                yield (y, x)
-
     def lines(self):
         width = self.size[1]
         for y in range(self.size[0]):
@@ -69,10 +66,9 @@ class Map(MapBase):
             return self.neighbors_to[pos]
         for direction in self.get_directions():
             neighbors[direction] = None
-            try:
-                neighbors[direction] = self.move(pos, direction)
-            except GameError:
-                pass
+            neighbor_pos = self.move(pos, direction)
+            if neighbor_pos:
+                neighbors[direction] = neighbor_pos
         self.neighbors_to[pos] = neighbors
         return neighbors
 
@@ -88,7 +84,7 @@ class Map(MapBase):
         new_pos = mover(start_pos)
         if new_pos[0] < 0 or new_pos[1] < 0 or \
                 new_pos[0] >= self.size[0] or new_pos[1] >= self.size[1]:
-            raise GameError('would move outside map bounds')
+            return None
         return new_pos
 
 
index 6f2f1be9ee4397630059c35eece39ebd48bda99f..c54d0899b98ecb56ec2c4fe422ec357086951df2 100644 (file)
@@ -37,6 +37,8 @@ class Task_MOVE(Task):
 
     def check(self):
         test_pos = self.thing.world.map_.move(self.thing.position, self.args[0])
+        if test_pos is None:
+            raise GameError('would move outside map bounds')
         if self.thing.world.map_[test_pos] != '.':
             raise GameError('%s would move into illegal terrain' % self.thing.id_)
         for t in self.thing.world.things: