Пример #1
0
    def __init__(self, game_actions):
        self.actions = game_actions

        from controllers.walk_mode import WalkMode
        self.walk_mode = WalkMode(self.actions)

        from controllers.debug_action import DebugAction
        self.debug_action = DebugAction(self.actions)

        self.set_actions()
Пример #2
0
class UserController(GameActionsProperties, object):

    error_messages = {
        ActionError.IllegalMove:          "You can't move there.",
        ActionError.IllegalTeleport:      "You can't teleport there.",
        ActionError.SwapTargetResists:    "The creature resists your swap attempt.",
        ActionError.NoSwapTarget:         "There isn't a creature there to swap with.",
        ActionError.PassageLeadsNoWhere:  "This passage doesn't seem to lead anywhere.",
        ActionError.NoPassage:            "This location doesn't have a passage.",
        ActionError.NoItemsOnGround:      "There aren't any items here to pick up.",
    }

    def __init__(self, game_actions):
        self.actions = game_actions

        from controllers.walk_mode import WalkMode
        self.walk_mode = WalkMode(self.actions)

        from controllers.debug_action import DebugAction
        self.debug_action = DebugAction(self.actions)

        self.set_actions()

    def set_actions(self):
        self.actions_funcs = {
            '+':                     partial(self.debug_action.sight_change, 1),
            '-':                     partial(self.debug_action.sight_change, -1),
            Key.CLOSE_WINDOW:        self.quit,
        }

        unfinalized_actions = {
            Bind.Debug_Commands:     self.debug_action.ask_action,
            Bind.Quit:               self.quit,
            Bind.Save:               self.save,
            Bind.Attack:             self.attack,
            Bind.Redraw:             self.redraw,
            Bind.History:            self.print_history,
            Bind.Look_Mode:          self.look,
            Bind.Help:               self.help_screen,
            Bind.Equipment:          self.equipment,
            Bind.Backpack:           self.backpack,
            Bind.Pick_Up_Items:      self.pickup_items,
            Bind.Drop_Items:         self.drop_items,
            Bind.Walk_Mode:          self.init_walk_mode,
            Bind.Show_Vision:        self.show_vision,
            Bind.Ascend:             self.ascend,
            Bind.Descend:            self.descend,

            Bind.SouthWest:          partial(self.act_to_dir, Dir.SouthWest),
            Bind.South:              partial(self.act_to_dir, Dir.South),
            Bind.SouthEast:          partial(self.act_to_dir, Dir.SouthEast),
            Bind.West:               partial(self.act_to_dir, Dir.West),
            Bind.Stay:               self.wait,
            Bind.East:               partial(self.act_to_dir, Dir.East),
            Bind.NorthWest:          partial(self.act_to_dir, Dir.NorthWest),
            Bind.North:              partial(self.act_to_dir, Dir.North),
            Bind.NorthEast:          partial(self.act_to_dir, Dir.NorthEast),

            Bind.Instant_SouthWest:  partial(self.init_walk_mode, Dir.SouthWest),
            Bind.Instant_South:      partial(self.init_walk_mode, Dir.South),
            Bind.Instant_SouthEast:  partial(self.init_walk_mode, Dir.SouthEast),
            Bind.Instant_West:       partial(self.init_walk_mode, Dir.West),
            Bind.Instant_Stay:       partial(self.init_walk_mode, Dir.Stay),
            Bind.Instant_East:       partial(self.init_walk_mode, Dir.East),
            Bind.Instant_NorthWest:  partial(self.init_walk_mode, Dir.NorthWest),
            Bind.Instant_North:      partial(self.init_walk_mode, Dir.North),
            Bind.Instant_NorthEast:  partial(self.init_walk_mode, Dir.NorthEast),
        }

        for keys, action in unfinalized_actions.items():
            for key in keys:
                self.actions_funcs[key] = action

    def _act(self):
        if self.walk_mode.is_walk_mode_active():
            feedback = self.walk_mode.continue_walk()
        else:
            key = self.io.get_key()
            if key in self.actions_funcs:
                feedback = self.actions_funcs[key]()
            else:
                self.io.msg("Undefined key: {}".format(key))
                feedback = None

        if feedback is None:
            assert not self.actions.already_acted(), \
                "Player did something but user_controller got no feedback from the game from it."

        return feedback

    def act(self):
        while True:
            feedback = self._act()
            if feedback is None and not self.actions.already_acted():
                continue

            assert feedback.type != ActionError.AlreadyActed, "Player attempted to act twice."
            assert feedback.type != ActionError.PlayerAction, "Player was denied a player only action."

            if feedback.type in ActionError:
                if feedback.type in self.error_messages:
                    self.io.msg(self.error_messages[feedback.type])
                else:
                    self.io.msg(feedback.type, feedback.params)
            elif feedback.type in (Action.Move, Action.Teleport, Action.Swap, Action.Spawn):
                items = self.actions.view_floor_items()

                if self.actions.get_passage():
                    self.io.msg("There is a {} here.".format(self.actions.get_tile().name))

                if len(items) == 1:
                    self.io.msg("A {} is lying here.".format(items[0].name))
                elif 1 < len(items) <= 10:
                    self.io.msg("There are several items lying here.")
                elif 10 < len(items):
                    self.io.msg("There is a stack of items lying here.")

            if self.actions.already_acted():
                return

    def act_to_dir(self, direction):
        return self.actions.act_to_dir(direction)

    def wait(self):
        return self.actions.wait()

    def look(self):
        coord = self.coord
        drawline_flag = False
        direction = Dir.Stay
        while True:
            new_coord = add_vector(coord, direction)
            if self.actions.level.is_legal(new_coord):
                coord = new_coord
            self.io.msg(self.actions.level.look_information(coord))
            if drawline_flag:
                self.io.draw_line(self.coord, coord, ("*", Pair.Yellow))
                self.io.draw_line(coord, self.coord, ("*", Pair.Yellow))
                self.io.msg("LoS: {}".format(self.actions.level.check_los(self.coord, coord)))
            if coord != self.coord:
                symbol, (foreground, background) = self.actions.level.visible_char(coord)
                char = symbol, (foreground, Color.Green)
                self.io.draw_char(char, coord)
                self.io.draw_char(self.actions.level.visible_char(self.coord), self.coord, reverse=True)
            key = self.io.get_key()
            self.actions.redraw()
            direction = Dir.Stay
            if key in Bind.Directions:
                direction = Dir.from_key[key]
            elif key == 'd':
                drawline_flag = not drawline_flag
            elif key == 'b':
                from generic_algorithms import bresenham
                for coord in bresenham(self.actions.level.get_coord(self.coord), coord):
                    self.io.msg(coord)
            elif key == 's':
                if coord in self.actions.level.creatures:
                    self.actions.game.register_status_texts(self.actions.level.creatures[coord])
            elif key in Bind.Cancel or key in Bind.Look_Mode:
                break

    def quit(self, dont_ask=True):
        query = "Do you wish to end the game? [{}]".format(Bind.Strong_Yes)
        if dont_ask or self.io.get_key(query) in Bind.Strong_Yes:
            self.actions.quit()

    def save(self, dont_ask=True):
        query = "Do you wish to save the game? [{}]".format(Bind.Yes)
        if dont_ask or self.io.get_key(query) in Bind.Yes:
            self.io.msg("Saving...")
            self.io.refresh()
            self.io.msg(self.actions.save())

    def attack(self):
        query = "Specify attack direction, {} to abort".format(Bind.Cancel.key)
        key = self.io.get_key(query, keys=Bind.Directions + Bind.Cancel)
        if key in Bind.Directions:
            return self.actions.attack(Dir.from_key[key])

    def redraw(self):
        self.actions.redraw()

    def descend(self):
        location = self.actions.get_passage()
        if location not in (None, LevelLocation.Passage_Up):
            return self.actions.enter_passage()
        else:
            return self.debug_action.teleport_to_location(LevelLocation.Passage_Down)
            #return "You don't find any downwards passage."

    def ascend(self):
        location = self.actions.get_passage()
        if location != LevelLocation.Passage_Up:
            return self.debug_action.teleport_to_location(LevelLocation.Passage_Up)
            #return "You don't find any upwards passage."
        else:
            return self.actions.enter_passage()

    def show_vision(self):
        GameConf.clearly_show_vision = not GameConf.clearly_show_vision
        self.actions.redraw()

    def print_history(self):
        header = "History"
        lines_view(self.io.whole_window, build_lines(reversed(self.io.message_bar.history)), header=header)

    def equipment(self):
        return interface.inventory.equipment(self.actions)

    def backpack(self):
        return interface.inventory.backpack(self.actions)

    def pickup_items(self):
        return interface.inventory.pickup_items(self.actions)

    def drop_items(self):
        return interface.inventory.drop_items(self.actions)

    def init_walk_mode(self, instant_direction=None):
        return self.walk_mode.init_walk_mode(instant_direction)

    def help_screen(self):
        help_screen(self.io)
        self.actions.redraw()