X-Git-Url: https://plomlompom.com/repos/feed.xml?a=blobdiff_plain;f=rogue_chat_curses.py;h=b098e0451456112f0e74508b6364417808cba73e;hb=1bb87f7a1151a6f244974c99cd7c392eeb0a8a35;hp=2783e24087afdc38666504daa59124f0d74c682d;hpb=ad0f7c6c7b5c204fd0ebbddc57e05079e93a9530;p=plomrogue2 diff --git a/rogue_chat_curses.py b/rogue_chat_curses.py index 2783e24..b098e04 100755 --- a/rogue_chat_curses.py +++ b/rogue_chat_curses.py @@ -27,6 +27,14 @@ mode_helps = { 'short': 'name thing', 'long': 'Give name to/change name of thing here.' }, + 'command_thing': { + 'short': 'command thing', + 'long': 'Enter a command to the thing you carry. Enter nothing to return to play mode.' + }, + 'take_thing': { + 'short': 'take thing', + 'long': 'You see a list of things which you could pick up. Enter the target thing\'s index, or, to leave, nothing.' + }, 'admin_thing_protect': { 'short': 'change thing protection', 'long': 'Change protection character for thing here.' @@ -130,12 +138,12 @@ class PlomSocketClient(PlomSocket): pass # we assume socket will be known as dead by now def cmd_TURN(game, n): - game.info_db = {} - game.info_hints = [] + game.annotations = {} game.turn = n game.things = [] game.portals = {} game.turn_complete = False + game.fov = '' cmd_TURN.argtypes = 'int:nonneg' def cmd_LOGIN_OK(game): @@ -151,6 +159,11 @@ def cmd_ADMIN_OK(game): game.tui.do_refresh = True cmd_ADMIN_OK.argtypes = '' +def cmd_REPLY(game, msg): + game.tui.log_msg('#MUSICPLAYER: ' + msg) + game.tui.do_refresh = True +cmd_REPLY.argtypes = 'string' + def cmd_CHAT(game, msg): game.tui.log_msg('# ' + msg) game.tui.do_refresh = True @@ -215,10 +228,9 @@ cmd_MAP_CONTROL.argtypes = 'string' def cmd_GAME_STATE_COMPLETE(game): if game.tui.mode.name == 'post_login_wait': game.tui.switch_mode('play') - if game.tui.mode.shows_info: - game.tui.query_info() game.turn_complete = True game.tui.do_refresh = True + game.tui.info_cached = None cmd_GAME_STATE_COMPLETE.argtypes = '' def cmd_PORTAL(game, position, msg): @@ -241,12 +253,8 @@ def cmd_ARGUMENT_ERROR(game, msg): game.tui.do_refresh = True cmd_ARGUMENT_ERROR.argtypes = 'string' -def cmd_ANNOTATION_HINT(game, position): - game.info_hints += [position] -cmd_ANNOTATION_HINT.argtypes = 'yx_tuple:nonneg' - def cmd_ANNOTATION(game, position, msg): - game.info_db[position] = msg + game.annotations[position] = msg if game.tui.mode.shows_info: game.tui.do_refresh = True cmd_ANNOTATION.argtypes = 'yx_tuple:nonneg string' @@ -254,6 +262,8 @@ cmd_ANNOTATION.argtypes = 'yx_tuple:nonneg string' def cmd_TASKS(game, tasks_comma_separated): game.tasks = tasks_comma_separated.split(',') game.tui.mode_write.legal = 'WRITE' in game.tasks + game.tui.mode_command_thing.legal = 'COMMAND' in game.tasks + game.tui.mode_take_thing.legal = 'PICK_UP' in game.tasks cmd_TASKS.argtypes = 'string' def cmd_THING_TYPE(game, thing_type, symbol_hint): @@ -287,6 +297,7 @@ class Game(GameBase): self.register_command(cmd_ADMIN_OK) self.register_command(cmd_PONG) self.register_command(cmd_CHAT) + self.register_command(cmd_REPLY) self.register_command(cmd_PLAYER_ID) self.register_command(cmd_TURN) self.register_command(cmd_THING) @@ -298,7 +309,6 @@ class Game(GameBase): self.register_command(cmd_MAP_CONTROL) self.register_command(cmd_PORTAL) self.register_command(cmd_ANNOTATION) - self.register_command(cmd_ANNOTATION_HINT) self.register_command(cmd_GAME_STATE_COMPLETE) self.register_command(cmd_ARGUMENT_ERROR) self.register_command(cmd_GAME_ERROR) @@ -309,8 +319,7 @@ class Game(GameBase): self.register_command(cmd_RANDOM_COLORS) self.map_content = '' self.player_id = -1 - self.info_db = {} - self.info_hints = [] + self.annotations = {} self.portals = {} self.terrains = {} @@ -385,14 +394,17 @@ class TUI: mode_post_login_wait = Mode('post_login_wait', is_intro=True) mode_password = Mode('password', has_input_prompt=True) mode_name_thing = Mode('name_thing', has_input_prompt=True, shows_info=True) + mode_command_thing = Mode('command_thing', has_input_prompt=True) + mode_take_thing = Mode('take_thing', has_input_prompt=True) is_admin = False tile_draw = False def __init__(self, host): import os import json - self.mode_play.available_modes = ["chat", "study", "edit", "admin_enter"] - self.mode_play.available_actions = ["move", "take_thing", "drop_thing", + self.mode_play.available_modes = ["chat", "study", "edit", "admin_enter", + "command_thing", "take_thing"] + self.mode_play.available_actions = ["move", "drop_thing", "teleport", "door", "consume"] self.mode_study.available_modes = ["chat", "play", "admin_enter", "edit"] self.mode_study.available_actions = ["toggle_map_mode", "move_explorer"] @@ -429,12 +441,13 @@ class TUI: 'switch_to_edit': 'E', 'switch_to_write': 'm', 'switch_to_name_thing': 'N', + 'switch_to_command_thing': 'O', 'switch_to_admin_enter': 'A', 'switch_to_control_pw_type': 'C', 'switch_to_control_tile_type': 'Q', 'switch_to_admin_thing_protect': 'T', 'flatten': 'F', - 'take_thing': 'z', + 'switch_to_take_thing': 'z', 'drop_thing': 'u', 'teleport': 'p', 'consume': 'C', @@ -522,14 +535,9 @@ class TUI: if len(self.log) > 100: self.log = self.log[-100:] - def query_info(self): - self.send('GET_ANNOTATION ' + str(self.explorer)) - def restore_input_values(self): - if self.mode.name == 'annotate' and self.explorer in self.game.info_db: - info = self.game.info_db[self.explorer] - if info != '(none)': - self.input_ = info + if self.mode.name == 'annotate' and self.explorer in self.game.annotations: + self.input_ = self.game.annotations[self.explorer] elif self.mode.name == 'portal' and self.explorer in self.game.portals: self.input_ = self.game.portals[self.explorer] elif self.mode.name == 'password': @@ -583,8 +591,6 @@ class TUI: if self.mode.shows_info or self.mode.name == 'control_tile_draw': player = self.game.get_thing(self.game.player_id) self.explorer = YX(player.position.y, player.position.x) - if self.mode.shows_info: - self.query_info() if self.mode.is_single_char_entry: self.show_help = True if self.mode.name == 'waiting_for_server': @@ -594,6 +600,19 @@ class TUI: self.send('LOGIN ' + quote(self.login_name)) else: self.log_msg('@ enter username') + elif self.mode.name == 'take_thing': + self.log_msg('selectable things:') + player = self.game.get_thing(self.game.player_id) + selectables = [t for t in self.game.things + if t != player and t.type_ != 'Player' + and t.position == player.position] + if len(selectables) == 0: + self.log_msg('none') + else: + for t in selectables: + self.log_msg(str(t.id_) + ' ' + self.get_thing_info(t)) + elif self.mode.name == 'command_thing': + self.send('TASK:COMMAND ' + quote('HELP')) elif self.mode.name == 'admin_enter': self.log_msg('@ enter admin password:') elif self.mode.name == 'control_pw_type': @@ -624,6 +643,51 @@ class TUI: curses.init_color(2, rand(0), rand(0), rand(0)) self.do_refresh = True + def get_info(self): + if self.info_cached: + return self.info_cached + pos_i = self.explorer.y * self.game.map_geometry.size.x + self.explorer.x + info_to_cache = '' + if len(self.game.fov) > pos_i and self.game.fov[pos_i] != '.': + info_to_cache += 'outside field of view' + else: + terrain_char = self.game.map_content[pos_i] + terrain_desc = '?' + if terrain_char in self.game.terrains: + terrain_desc = self.game.terrains[terrain_char] + info_to_cache += 'TERRAIN: "%s" / %s\n' % (terrain_char, + terrain_desc) + protection = self.game.map_control_content[pos_i] + if protection == '.': + protection = 'unprotected' + info_to_cache += 'PROTECTION: %s\n' % protection + for t in self.game.things: + if t.position == self.explorer: + info_to_cache += 'THING: %s' % self.get_thing_info(t) + protection = t.protection + if protection == '.': + protection = 'none' + info_to_cache += ' / protection: %s\n' % protection + if self.explorer in self.game.portals: + info_to_cache += 'PORTAL: ' +\ + self.game.portals[self.explorer] + '\n' + else: + info_to_cache += 'PORTAL: (none)\n' + if self.explorer in self.game.annotations: + info_to_cache += 'ANNOTATION: ' +\ + self.game.annotations[self.explorer] + self.info_cached = info_to_cache + return self.info_cached + + def get_thing_info(self, t): + info = '%s / %s' %\ + (t.type_, self.game.thing_types[t.type_]) + if hasattr(t, 'thing_char'): + info += t.thing_char + if hasattr(t, 'name'): + info += ' (%s)' % t.name + return info + def loop(self, stdscr): import datetime @@ -678,9 +742,8 @@ class TUI: def move_explorer(direction): target = self.game.map_geometry.move_yx(self.explorer, direction) if target: + self.info_cached = None self.explorer = target - if self.mode.shows_info: - self.query_info() if self.tile_draw: self.send_tile_control_command() else: @@ -699,42 +762,7 @@ class TUI: safe_addstr(max_y - i - 1, self.window_width, lines[i]) def draw_info(): - if not self.game.turn_complete: - return - pos_i = self.explorer.y * self.game.map_geometry.size.x + self.explorer.x - info = 'MAP VIEW: %s\n' % self.map_mode - if self.game.fov[pos_i] != '.': - info += 'outside field of view' - else: - terrain_char = self.game.map_content[pos_i] - terrain_desc = '?' - if terrain_char in self.game.terrains: - terrain_desc = self.game.terrains[terrain_char] - info += 'TERRAIN: "%s" / %s\n' % (terrain_char, terrain_desc) - protection = self.game.map_control_content[pos_i] - if protection == '.': - protection = 'unprotected' - info += 'PROTECTION: %s\n' % protection - for t in self.game.things: - if t.position == self.explorer: - protection = t.protection - if protection == '.': - protection = 'none' - info += 'THING: %s / %s' % (t.type_, - self.game.thing_types[t.type_]) - if hasattr(t, 'thing_char'): - info += t.thing_char - if hasattr(t, 'name'): - info += ' (%s)' % t.name - info += ' / protection: %s\n' % protection - if self.explorer in self.game.portals: - info += 'PORTAL: ' + self.game.portals[self.explorer] + '\n' - else: - info += 'PORTAL: (none)\n' - if self.explorer in self.game.info_db: - info += 'ANNOTATION: ' + self.game.info_db[self.explorer] - else: - info += 'ANNOTATION: waiting …' + info = 'MAP VIEW: %s\n%s' % (self.map_mode, self.get_info()) lines = msg_into_lines_of_width(info, self.window_width) height_header = 2 for i in range(len(lines)): @@ -776,14 +804,15 @@ class TUI: map_lines_split += [[c + ' ' for c in self.game.map_content[start:end]]] if self.map_mode == 'terrain + annotations': - for p in self.game.info_hints: + for p in self.game.annotations: map_lines_split[p.y][p.x] = 'A ' elif self.map_mode == 'terrain + things': for p in self.game.portals.keys(): original = map_lines_split[p.y][p.x] map_lines_split[p.y][p.x] = original[0] + 'P' used_positions = [] - for t in self.game.things: + + def draw_thing(t, used_positions): symbol = self.game.thing_types[t.type_] meta_char = ' ' if hasattr(t, 'thing_char'): @@ -792,6 +821,11 @@ class TUI: meta_char = '+' map_lines_split[t.position.y][t.position.x] = symbol + meta_char used_positions += [t.position] + + for t in [t for t in self.game.things if t.type_ != 'Player']: + draw_thing(t, used_positions) + for t in [t for t in self.game.things if t.type_ == 'Player']: + draw_thing(t, used_positions) player = self.game.get_thing(self.game.player_id) if self.mode.shows_info or self.mode.name == 'control_tile_draw': map_lines_split[self.explorer.y][self.explorer.x] = '??' @@ -898,6 +932,7 @@ class TUI: 'drop_thing': 'DROP', 'door': 'DOOR', 'move': 'MOVE', + 'command': 'COMMAND', 'consume': 'INTOXICATE', } @@ -960,6 +995,20 @@ class TUI: self.login_name = self.input_ self.send('LOGIN ' + quote(self.input_)) self.input_ = "" + elif self.mode.name == 'take_thing' and key == '\n': + if self.input_ == '': + self.log_msg('@ aborted') + else: + self.send('TASK:PICK_UP ' + quote(self.input_)) + self.input_ = '' + self.switch_mode('play') + elif self.mode.name == 'command_thing' and key == '\n': + if self.input_ == '': + self.log_msg('@ aborted') + self.switch_mode('play') + elif task_action_on('command'): + self.send('TASK:COMMAND ' + quote(self.input_)) + self.input_ = "" elif self.mode.name == 'control_pw_pw' and key == '\n': if self.input_ == '': self.log_msg('@ aborted') @@ -1049,8 +1098,6 @@ class TUI: elif self.mode.name == 'play': if self.mode.mode_switch_on_key(self, key): continue - elif key == self.keys['take_thing'] and task_action_on('take_thing'): - self.send('TASK:PICK_UP') elif key == self.keys['drop_thing'] and task_action_on('drop_thing'): self.send('TASK:DROP') elif key == self.keys['door'] and task_action_on('door'):