game.tui.switch_mode('post_login_wait')
game.tui.send('GET_GAMESTATE')
game.tui.log_msg('@ welcome!')
- game.tui.log_msg('@ hint: see top of terminal for how to get help.')
- game.tui.log_msg('@ hint: enter study mode to understand your environment.')
cmd_LOGIN_OK.argtypes = ''
def cmd_ADMIN_OK(game):
self.disconnected = False
self.game.thing_types = {}
self.game.terrains = {}
+ self.is_admin = False
time.sleep(0.1) # give potential SSL negotation some time …
self.socket.send('TASKS')
self.socket.send('TERRAINS')
self.log_msg('@ finished tile protection drawing.')
self.draw_face = False
self.tile_draw = False
+ self.ascii_draw_stage = 0
+ self.full_ascii_draw = ''
if mode_name == 'command_thing' and\
(not self.game.player.carrying or
not self.game.player.carrying.commandable):
for i in range(len(self.selectables)):
self.log_msg(str(i) + ': ' + self.selectables[i])
elif self.mode.name == 'enter_design':
- self.log_msg('@ The design you enter must be %s lines of max %s '
- 'characters width each'
- % (self.game.player.carrying.design[0].y,
- self.game.player.carrying.design[0].x))
if self.game.player.carrying.type_ == 'Hat':
+ self.log_msg('@ The design you enter must be %s lines of max %s '
+ 'characters width each'
+ % (self.game.player.carrying.design[0].y,
+ self.game.player.carrying.design[0].x))
self.log_msg('@ Legal characters: ' + self.game.players_hat_chars)
self.log_msg('@ (Eat cookies to extend the ASCII characters available for drawing.)')
+ else:
+ self.log_msg('@ Width of first line determines maximum width for remaining design')
+ self.log_msg('@ Finish design by entering an empty line (multiple space characters do not count as empty)')
elif self.mode.name == 'command_thing':
self.send('TASK:COMMAND ' + quote('HELP'))
elif self.mode.name == 'control_pw_pw':
self.restore_input_values()
def set_default_colors(self):
- curses.init_color(1, 1000, 1000, 1000)
- curses.init_color(2, 0, 0, 0)
+ if curses.can_change_color():
+ curses.init_color(7, 1000, 1000, 1000)
+ curses.init_color(0, 0, 0, 0)
self.do_refresh = True
def set_random_colors(self):
import random
return int(offset + random.random()*375)
- curses.init_color(1, rand(625), rand(625), rand(625))
- curses.init_color(2, rand(0), rand(0), rand(0))
+ if curses.can_change_color():
+ curses.init_color(7, rand(625), rand(625), rand(625))
+ curses.init_color(0, rand(0), rand(0), rand(0))
self.do_refresh = True
def get_info(self):
self.size = YX(*stdscr.getmaxyx())
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)
+ self.left_window_width = min(52, int(self.size.x / 2))
+ self.right_window_width = self.size.x - self.left_window_width
def recalc_input_lines():
if not self.mode.has_input_prompt:
else:
self.input_lines = msg_into_lines_of_width(input_prompt
+ self.input_ + '█',
- self.window_width)
+ self.right_window_width)
def move_explorer(direction):
target = self.game.map_geometry.move_yx(self.explorer, direction)
def draw_history():
lines = []
for line in self.log:
- lines += msg_into_lines_of_width(line, self.window_width)
+ lines += msg_into_lines_of_width(line, self.right_window_width)
lines.reverse()
height_header = 2
max_y = self.size.y - len(self.input_lines)
for i in range(len(lines)):
if (i >= max_y - height_header):
break
- safe_addstr(max_y - i - 1, self.window_width, lines[i])
+ safe_addstr(max_y - i - 1, self.left_window_width, lines[i])
def draw_info():
info = 'MAP VIEW: %s\n%s' % (self.map_mode, self.get_info())
- lines = msg_into_lines_of_width(info, self.window_width)
+ lines = msg_into_lines_of_width(info, self.right_window_width)
height_header = 2
for i in range(len(lines)):
y = height_header + i
if y >= self.size.y - len(self.input_lines):
break
- safe_addstr(y, self.window_width, lines[i])
+ safe_addstr(y, self.left_window_width, lines[i])
def draw_input():
y = self.size.y - len(self.input_lines)
for i in range(len(self.input_lines)):
- safe_addstr(y, self.window_width, self.input_lines[i])
+ safe_addstr(y, self.left_window_width, self.input_lines[i])
y += 1
def draw_stats():
stats = 'ENERGY: %s BLADDER: %s' % (self.game.energy,
self.game.bladder_pressure)
- safe_addstr(0, self.window_width, stats)
+ safe_addstr(0, self.left_window_width, stats)
def draw_mode():
help = "hit [%s] for help" % self.keys['help']
if self.mode.has_input_prompt:
help = "enter /help for help"
- safe_addstr(1, self.window_width,
+ safe_addstr(1, self.left_window_width,
'MODE: %s – %s' % (self.mode.short_desc, help))
def draw_map():
for line in map_lines_split:
self.map_lines += [''.join(line)]
window_center = YX(int(self.size.y / 2),
- int(self.window_width / 2))
+ int(self.left_window_width / 2))
center = self.game.player.position
if self.mode.shows_info or self.mode.name == 'control_tile_draw':
center = self.explorer
map_y = max(0, self.offset.y)
map_x = max(0, self.offset.x)
while term_y < self.size.y and map_y < len(self.map_lines):
- to_draw = self.map_lines[map_y][map_x:self.window_width + self.offset.x]
+ to_draw = self.map_lines[map_y][map_x:self.left_window_width + self.offset.x]
safe_addstr(term_y, term_x, to_draw)
term_y += 1
map_y += 1
+ def draw_names():
+ players = [t for t in self.game.things if t.type_ == 'Player']
+ players.sort(key=lambda t: len(t.name))
+ players.reverse()
+ shrink_offset = max(0, (self.size.y - self.left_window_width // 2) // 2)
+ y = 0
+ for t in players:
+ offset_y = y - shrink_offset
+ max_len = max(5, (self.left_window_width // 2) - (offset_y * 2) - 8)
+ name = t.name[:]
+ if len(name) > max_len:
+ name = name[:max_len - 1] + '…'
+ safe_addstr(y, 0, '@%s:%s' % (t.thing_char, name))
+ y += 1
+ if y >= self.size.y:
+ break
+
def draw_face_popup():
t = self.game.get_thing(self.draw_face)
if not t or not hasattr(t, 'face'):
self.draw_face = False
return
- start_x = self.window_width - 10
- t_char = ' '
- if hasattr(t, 'thing_char'):
- t_char = t.thing_char
+ start_x = self.left_window_width - 10
def draw_body_part(body_part, end_y):
- safe_addstr(end_y - 4, start_x, ' _[ @' + t_char + ' ]_ ')
- safe_addstr(end_y - 3, start_x, '| |')
+ safe_addstr(end_y - 3, start_x, '----------')
safe_addstr(end_y - 2, start_x, '| ' + body_part[0:6] + ' |')
safe_addstr(end_y - 1, start_x, '| ' + body_part[6:12] + ' |')
safe_addstr(end_y, start_x, '| ' + body_part[12:18] + ' |')
if hasattr(t, 'face'):
- draw_body_part(t.face, self.size.y - 2)
+ draw_body_part(t.face, self.size.y - 3)
if hasattr(t, 'hat'):
- draw_body_part(t.hat, self.size.y - 5)
- safe_addstr(self.size.y - 1, start_x, '| |')
+ draw_body_part(t.hat, self.size.y - 6)
+ safe_addstr(self.size.y - 2, start_x, '----------')
+ name = t.name[:]
+ if len(name) > 7:
+ name = name[:6 - 1] + '…'
+ safe_addstr(self.size.y - 1, start_x,
+ '@%s:%s' % (t.thing_char, name))
def draw_help():
content = "%s help\n\n%s\n\n" % (self.mode.short_desc,
content += self.mode.list_available_modes(self)
for i in range(self.size.y):
safe_addstr(i,
- self.window_width * (not self.mode.has_input_prompt),
- ' ' * self.window_width)
+ self.left_window_width * (not self.mode.has_input_prompt),
+ ' ' * self.left_window_width)
lines = []
for line in content.split('\n'):
- lines += msg_into_lines_of_width(line, self.window_width)
+ lines += msg_into_lines_of_width(line, self.right_window_width)
for i in range(len(lines)):
if i >= self.size.y:
break
safe_addstr(i,
- self.window_width * (not self.mode.has_input_prompt),
+ self.left_window_width * (not self.mode.has_input_prompt),
lines[i])
def draw_screen():
draw_map()
if self.show_help:
draw_help()
- if self.draw_face and self.mode.name in {'chat', 'play'}:
- draw_face_popup()
+ if self.mode.name in {'chat', 'play'}:
+ draw_names()
+ if self.draw_face:
+ draw_face_popup()
def pick_selectable(task_name):
try:
self.input_ = ''
self.switch_mode('play')
- def enter_ascii_art(command, height, width, with_pw=False):
- if len(self.input_) > width:
- self.log_msg('? wrong input length, '
+ def enter_ascii_art(command, height, width,
+ with_pw=False, with_size=False):
+ if with_size and self.ascii_draw_stage == 0:
+ width = len(self.input_)
+ if width > 36:
+ self.log_msg('? input too long, must be max 36; try again')
+ # TODO: move max width mechanism server-side
+ return
+ old_size = self.game.player.carrying.design[0]
+ if width != old_size.x:
+ # TODO: save remaining design?
+ self.game.player.carrying.design[1] = ''
+ self.game.player.carrying.design[0] = YX(old_size.y, width)
+ elif len(self.input_) > width:
+ self.log_msg('? input too long, '
'must be max %s; try again' % width)
return
- if len(self.input_) < width:
- self.input_ += ' ' * (width - len(self.input_))
self.log_msg(' ' + self.input_)
- self.full_ascii_draw += self.input_
+ if with_size and self.input_ in {'', ' '}\
+ and self.ascii_draw_stage > 0:
+ height = self.ascii_draw_stage
+ else:
+ if with_size:
+ height = self.ascii_draw_stage + 2
+ if len(self.input_) < width:
+ self.input_ += ' ' * (width - len(self.input_))
+ self.full_ascii_draw += self.input_
+ if with_size:
+ old_size = self.game.player.carrying.design[0]
+ self.game.player.carrying.design[0] = YX(height, old_size.x)
self.ascii_draw_stage += 1
if self.ascii_draw_stage < height:
self.restore_input_values()
else:
+ if with_pw and with_size:
+ self.send('%s_SIZE %s %s' % (command, YX(height, width),
+ quote(self.password)))
if with_pw:
self.send('%s %s %s' % (command, quote(self.full_ascii_draw),
quote(self.password)))
'dance': 'DANCE',
}
- curses.curs_set(False) # hide cursor
+ curses.curs_set(0) # hide cursor
curses.start_color()
self.set_default_colors()
- curses.init_pair(1, 1, 2)
+ curses.init_pair(1, 7, 0)
+ if not curses.can_change_color():
+ self.log_msg('@ unfortunately, your terminal does not seem to '
+ 'support re-definition of colors; you might miss out '
+ 'on some color effects')
stdscr.timeout(10)
reset_screen_size()
self.explorer = YX(0, 0)
self.restore_input_values()
elif self.mode.has_input_prompt and key != '\n': # Return key
self.input_ += key
- max_length = self.window_width * self.size.y - len(input_prompt) - 1
+ max_length = self.right_window_width * self.size.y - len(input_prompt) - 1
if len(self.input_) > max_length:
self.input_ = self.input_[:max_length]
elif key == self.keys['help'] and not self.mode.is_single_char_entry:
elif self.mode.name == 'enter_face' and key == '\n':
enter_ascii_art('PLAYER_FACE', 3, 6)
elif self.mode.name == 'enter_design' and key == '\n':
- enter_ascii_art('THING_DESIGN',
- self.game.player.carrying.design[0].y,
- self.game.player.carrying.design[0].x, True)
+ if self.game.player.carrying.type_ == 'Hat':
+ enter_ascii_art('THING_DESIGN',
+ self.game.player.carrying.design[0].y,
+ self.game.player.carrying.design[0].x, True)
+ else:
+ enter_ascii_art('THING_DESIGN',
+ self.game.player.carrying.design[0].y,
+ self.game.player.carrying.design[0].x,
+ True, True)
elif self.mode.name == 'take_thing' and key == '\n':
pick_selectable('PICK_UP')
elif self.mode.name == 'drop_thing' and key == '\n':