home · contact · privacy
Make keybindings configurable.
[plomrogue2-experiments] / new2 / rogue_chat_curses.py
index 6d0f8b77f8518f16b224c0afb761438793a63180..bb3dac263e84670c8f9ef851f8b87844d6b9e4a6 100755 (executable)
@@ -6,7 +6,7 @@ import threading
 from plomrogue.io_tcp import PlomSocket
 from plomrogue.game import GameBase
 from plomrogue.parser import Parser
-from plomrogue.mapping import YX
+from plomrogue.mapping import YX, MapGeometrySquare, MapGeometryHex
 from plomrogue.things import ThingBase
 from plomrogue.misc import quote
 
@@ -42,10 +42,27 @@ def cmd_THING_NAME(game, thing_id, name):
     t.name = name
 cmd_THING_NAME.argtypes = 'int:nonneg string'
 
-def cmd_MAP(game, size, content):
-    game.map_geometry.size = size
+def cmd_MAP(game, geometry, size, content):
+    map_geometry_class = globals()['MapGeometry' + geometry]
+    game.map_geometry = map_geometry_class(size)
     game.map_content = content
-cmd_MAP.argtypes = 'yx_tuple:pos string'
+    if type(game.map_geometry) == MapGeometrySquare:
+        game.tui.movement_keys = {
+            game.tui.keys['square_move_up']: 'UP',
+            game.tui.keys['square_move_left']: 'LEFT',
+            game.tui.keys['square_move_down']: 'DOWN',
+            game.tui.keys['square_move_right']: 'RIGHT',
+        }
+    elif type(game.map_geometry) == MapGeometryHex:
+        game.tui.movement_keys = {
+            game.tui.keys['hex_move_upleft']: 'UPLEFT',
+            game.tui.keys['hex_move_upright']: 'UPRIGHT',
+            game.tui.keys['hex_move_right']: 'RIGHT',
+            game.tui.keys['hex_move_downright']: 'DOWNRIGHT',
+            game.tui.keys['hex_move_downleft']: 'DOWNLEFT',
+            game.tui.keys['hex_move_left']: 'LEFT',
+        }
+cmd_MAP.argtypes = 'string:map_geometry yx_tuple:pos string'
 
 def cmd_GAME_STATE_COMPLETE(game):
     game.info_db = {}
@@ -56,9 +73,9 @@ def cmd_GAME_STATE_COMPLETE(game):
         game.tui.query_info()
     player = game.get_thing(game.player_id, False)
     if player.position in game.portals:
-        host, port = game.portals[player.position].split(':')
-        game.tui.teleport_target_host = host
-        game.tui.teleport_target_port = port
+        #host, port = game.portals[player.position].split(':')
+        game.tui.teleport_target_host = game.portals[player.position]
+        game.tui.teleport_target_port = 5000
         game.tui.switch_mode('teleport')
     game.turn_complete = True
     game.tui.do_refresh = True
@@ -113,6 +130,11 @@ class Game(GameBase):
         self.info_db = {}
         self.portals = {}
 
+    def get_string_options(self, string_option_type):
+        if string_option_type == 'map_geometry':
+            return ['Hex', 'Square']
+        return None
+
     def get_command(self, command_name):
         from functools import partial
         f = partial(self.commands[command_name], self)
@@ -131,6 +153,8 @@ class TUI:
             self.is_intro = is_intro
 
     def __init__(self, host, port):
+        import os
+        import json
         self.host = host
         self.port = port
         self.mode_play = self.Mode('play')
@@ -149,7 +173,32 @@ class TUI:
         self.log = []
         self.do_refresh = True
         self.queue = queue.Queue()
+        self.login_name = None
         self.switch_mode('waiting_for_server')
+        self.keys = {
+            'switch_to_chat': 'C',
+            'switch_to_play': 'P',
+            'switch_to_annotate': 'E',
+            'switch_to_portal': 'p',
+            'switch_to_study': '?',
+            'switch_to_edit': 'E',
+            'flatten': 'f',
+            'hex_move_upleft': 'w',
+            'hex_move_upright': 'e',
+            'hex_move_right': 'd',
+            'hex_move_downright': 'c',
+            'hex_move_downleft': 'x',
+            'hex_move_left': 's',
+            'square_move_up': 'w',
+            'square_move_left': 'a',
+            'square_move_down': 's',
+            'square_move_right': 'd',
+        }
+        if os.path.isfile('config.json'):
+            with open('config.json', 'r') as f:
+                keys_conf = json.loads(f.read())
+            for k in keys_conf:
+                self.keys[k] = keys_conf[k]
         curses.wrapper(self.loop)
 
     def flash(self):
@@ -178,11 +227,14 @@ class TUI:
         if self.mode.name == 'waiting_for_server':
             self.log_msg('@ waiting for server …')
         elif self.mode.name == 'login':
-            self.log_msg('@ enter username')
+            if self.login_name:
+                self.send('LOGIN ' + quote(self.login_name))
+            else:
+                self.log_msg('@ enter username')
         elif self.mode.name == 'teleport':
             self.log_msg("@ May teleport to %s:%s" % (self.teleport_target_host,
                                                       self.teleport_target_port));
-            self.log_msg("@ Enter 'YES!' to affirm.");
+            self.log_msg("@ Enter 'YES!' to enthusiastically affirm.");
         elif self.mode.name == 'annotate' and self.explorer in self.game.info_db:
             info = self.game.info_db[self.explorer]
             if info != '(none)':
@@ -193,21 +245,21 @@ class TUI:
     def help(self):
         self.log_msg("HELP:");
         self.log_msg("chat mode commands:");
-        self.log_msg("  :nick NAME - re-name yourself to NAME");
-        self.log_msg("  :msg USER TEXT - send TEXT to USER");
-        self.log_msg("  :help - show this help");
-        self.log_msg("  :p or :play - switch to play mode");
-        self.log_msg("  :? or :study - switch to study mode");
+        self.log_msg("  /nick NAME - re-name yourself to NAME");
+        self.log_msg("  /msg USER TEXT - send TEXT to USER");
+        self.log_msg("  /help - show this help");
+        self.log_msg("  /P or /play - switch to play mode");
+        self.log_msg("  /? or /study - switch to study mode");
         self.log_msg("commands common to study and play mode:");
-        self.log_msg("  w,a,s,d - move");
-        self.log_msg("  c - switch to chat mode");
+        self.log_msg("  %s - move" % ','.join(self.movement_keys));
+        self.log_msg("  %s - switch to chat mode" % self.keys['switch_to_chat']);
         self.log_msg("commands specific to play mode:");
-        self.log_msg("  e - write following ASCII character");
-        self.log_msg("  f - flatten surroundings");
-        self.log_msg("  ? - switch to study mode");
+        self.log_msg("  %s - write following ASCII character" % self.keys['switch_to_edit']);
+        self.log_msg("  %s - flatten surroundings" % self.keys['flatten']);
+        self.log_msg("  %s - switch to study mode" % self.keys['switch_to_study']);
         self.log_msg("commands specific to study mode:");
-        self.log_msg("  e - annotate terrain");
-        self.log_msg("  p - switch to play mode");
+        self.log_msg("  %s - annotate terrain" % self.keys['switch_to_annotate']);
+        self.log_msg("  %s - switch to play mode" % self.keys['switch_to_play']);
 
     def loop(self, stdscr):
 
@@ -271,7 +323,7 @@ class TUI:
 
         def reset_screen_size():
             self.size = YX(*stdscr.getmaxyx())
-            self.size = self.size - YX(self.size.y % 2, 0)
+            self.size = self.size - YX(self.size.y % 4, 0)
             self.size = self.size - YX(0, self.size.x % 4)
             self.window_width = int(self.size.x / 2)
 
@@ -348,17 +400,24 @@ class TUI:
             if self.mode.shows_info:
                 map_lines_split[self.explorer.y][self.explorer.x] = '?'
             map_lines = []
-            for line in map_lines_split:
-                map_lines += [''.join(line)]
-            map_center = YX(int(self.game.map_geometry.size.y / 2),
-                            int(self.game.map_geometry.size.x / 2))
+            if type(self.game.map_geometry) == MapGeometryHex:
+                indent = 0
+                for line in map_lines_split:
+                    map_lines += [indent*' ' + ' '.join(line)]
+                    indent = 0 if indent else 1
+            else:
+                for line in map_lines_split:
+                    map_lines += [' '.join(line)]
             window_center = YX(int(self.size.y / 2),
                                int(self.window_width / 2))
             player = self.game.get_thing(self.game.player_id, False)
             center = player.position
             if self.mode.shows_info:
                 center = self.explorer
+            center = YX(center.y, center.x * 2)
             offset = center - window_center
+            if type(self.game.map_geometry) == MapGeometryHex and offset.y % 2:
+                offset += YX(0, 1)
             term_y = max(0, -offset.y)
             term_x = max(0, -offset.x)
             map_y = max(0, offset.y)
@@ -415,25 +474,26 @@ class TUI:
                 if len(self.input_) > max_length:
                     self.input_ = self.input_[:max_length]
             elif self.mode == self.mode_login and key == '\n':
+                self.login_name = self.input_
                 self.send('LOGIN ' + quote(self.input_))
                 self.input_ = ""
             elif self.mode == self.mode_chat and key == '\n':
-                if self.input_[0] == ':':
-                    if self.input_ in {':p', ':play'}:
+                if self.input_[0] == '/':
+                    if self.input_ in {'/P', '/play'}:
                         self.switch_mode('play')
-                    elif self.input_ in {':?', ':study'}:
+                    elif self.input_ in {'/?', '/study'}:
                         self.switch_mode('study')
-                    if self.input_ == ':help':
+                    elif self.input_ == '/help':
                         self.help()
-                    if self.input_ == ':reconnect':
+                    elif self.input_ == '/reconnect':
                         reconnect()
-                    elif self.input_.startswith(':nick'):
+                    elif self.input_.startswith('/nick'):
                         tokens = self.input_.split(maxsplit=1)
                         if len(tokens) == 2:
                             self.send('LOGIN ' + quote(tokens[1]))
                         else:
                             self.log_msg('? need login name')
-                    elif self.input_.startswith(':msg'):
+                    elif self.input_.startswith('/msg'):
                         tokens = self.input_.split(maxsplit=2)
                         if len(tokens) == 3:
                             self.send('QUERY %s %s' % (quote(tokens[1]),
@@ -467,39 +527,27 @@ class TUI:
                     self.switch_mode('play')
                 self.input_ = ''
             elif self.mode == self.mode_study:
-                if key == 'c':
+                if key == self.keys['switch_to_chat']:
                     self.switch_mode('chat')
-                elif key == 'p':
+                elif key == self.keys['switch_to_play']:
                     self.switch_mode('play')
-                elif key == 'A':
+                elif key == self.keys['switch_to_annotate']:
                     self.switch_mode('annotate', keep_position=True)
-                elif key == 'P':
+                elif key == self.keys['switch_to_portal']:
                     self.switch_mode('portal', keep_position=True)
-                elif key == 'w':
-                    move_explorer('UP')
-                elif key == 'a':
-                    move_explorer('LEFT')
-                elif key == 's':
-                    move_explorer('DOWN')
-                elif key == 'd':
-                    move_explorer('RIGHT')
+                elif key in self.movement_keys:
+                    move_explorer(self.movement_keys[key])
             elif self.mode == self.mode_play:
-                if key == 'c':
+                if key == self.keys['switch_to_chat']:
                     self.switch_mode('chat')
-                elif key == '?':
+                elif key == self.keys['switch_to_study']:
                     self.switch_mode('study')
-                if key == 'e':
+                if key == self.keys['switch_to_edit']:
                     self.switch_mode('edit')
-                elif key == 'f':
+                elif key == self.keys['flatten']:
                     self.send('TASK:FLATTEN_SURROUNDINGS')
-                elif key == 'w':
-                    self.send('TASK:MOVE UP')
-                elif key == 'a':
-                    self.send('TASK:MOVE LEFT')
-                elif key == 's':
-                    self.send('TASK:MOVE DOWN')
-                elif key == 'd':
-                    self.send('TASK:MOVE RIGHT')
+                elif key in self.movement_keys:
+                    self.send('TASK:MOVE ' + self.movement_keys[key])
             elif self.mode == self.mode_edit:
                 self.send('TASK:WRITE ' + key)
                 self.switch_mode('play')