Ejemplo n.º 1
0
    def go_to_other_location(self, handler: Handler, new_location, direction: Point, player: Player):
        if new_location is None:
            return CANT_MOVE_DIRECTION

        if direction == SOUTH:
            pass
        elif direction == EAST:
            pass
        elif direction == WEST:
            pass
        elif direction == NORTH:
            ninja = handler.get_livings(NinjaDude, 1)[0]
            ninja.tell(player, "You want to pass huh? The king doesn't like to be disturbed.")
            ninja.tell(player, "Wait, are you looking to face me? Ha ha ha... Yeah not gonna happen.")
            ninja.tell(player, "If you want to pass hear, you should at least have all shiny steel armor "
                               "and some decent weaponry.")
            return CANT_PASS
        elif direction in DIRECTIONS:
            return CANT_MOVE_DIRECTION
        else:
            return CANT_JUMP_LOCATION

        action = GoAction(player, player.location, new_location, create_leave_message(self))
        action.can_do = CAN_GO_TO_LOCATION
        handler.do_action(action)
        return action.try_action(handler)
Ejemplo n.º 2
0
 def on_take(self, handler: Handler, item: Item, new_holder: Holder):
     if not isinstance(new_holder, Player):
         # If something else took the item we don't care. However, it's possible that this causes bugs so be careful
         return
     player = new_holder
     if isinstance(item, Wallet):
         if player[EventsObject].been_introduced_to_furry:
             handler.get_livings(OtherPerson, 1)[0].tell(player, "Hey that's not yours!")
             player.send_message("You set the wallet back on the ground.")
             player.items.remove(item)
             item.change_holder(player, player.location)
             return
         friend = player[PlayerFriend]
         player[EventsObject].been_introduced_to_furry = True  # has now been introduced
         player.send_message(Message("You throw all of {}'s cash at the furry monster.",
                                     named_variables=[friend]))
         player.send_wait(0.2)
         player.send_message("The furry monster fainted. You ga-")
         friend.tell(player, "THANK YOU, THANK YOU!!! You just saved my life from the furry monster!")
         friend.tell(player, "You can keep my wallet. It doesn't have much left anyway.")
         friend.tell(player, "Oh, and I met this really awesome person. If you go west past the double doors,"
                             " you'll find her.")
         player.send_wait(0.5)
         friend.tell(player,
                     "She's pretty shy so you can use the yell command to yell out to her.")
         friend.tell(player, "Well, 'shy' isn't really the word. Good luck.")
Ejemplo n.º 3
0
 def go_to_other_location(self, handler: Handler, new_location, direction: Point, player: Player) -> CanDo:
     if new_location is None:
         return CANT_MOVE_DIRECTION
     # debug("point: {}".format(str(direction)))
     if direction == SOUTH:
         return False, "The double doors won't open."
     elif direction == EAST:
         # done
         pass
     elif direction == WEST:
         # DONE go west to (-1, 1) -> Get sword from Laura
         pass
     elif direction == NORTH:
         # DONE go north to entrance of spider web forest
         pass
     elif direction == UP or direction == DOWN:
         return CANT_MOVE_DIRECTION
     else:
         return CANT_JUMP_LOCATION
     # player.send_message(create_leave_message(self)) < original code which was moved into GoAction's _do_action
     #
     # previous_location = player.location  # I know this is self, but shut up. I've already done this for 4 of these
     # player.location = new_location
     #
     # player.location.on_enter(player, previous_location, handler)
     action = GoAction(player, player.location, new_location, create_leave_message(self))
     action.can_do = CAN_GO_TO_LOCATION
     handler.do_action(action)
     return action.try_action(handler)
Ejemplo n.º 4
0
    def update(
            self,
            handler: Handler):  # not overridden - handled by a BattleManager
        """
        Assuming should_update returns True, this should be called every frame
        :param handler: The handler object
        """
        assert self.should_update(), "You shouldn't be calling update."
        assert self.current_turn is not None, "this shouldn't be None unless start hasn't been called before. (Bad)"

        if not self.current_turn.is_started:
            self.current_turn.start(self)

        self.current_turn.update(self, handler)

        if self.current_turn.is_done:
            if self.__is_done():
                self.has_ended = True
                from textadventure.battling.actions import BattleEnd
                end_action = BattleEnd(
                    self,
                    self.get_alive_teams()
                    [0])  # TODO make a safer way to get winning team
                handler.do_action(end_action)
                assert end_action.can_do[
                    0], "We aren't prepared for this. Why would you cancel it?"
                end_action.try_action(
                    handler)  # calling this will display results
                return
            self.current_turn = self.__next_turn(self.current_turn)
Ejemplo n.º 5
0
    def _handle_command(self, handler: Handler, sender: CommandSender, command_input: CommandInput) -> InputHandleType:
        if not isinstance(sender, Player):
            sender.send_message("This must be an error. A {} shouldn't be trying to attack.".format(type(sender)))
        player = sender

        manager = handler.get_managers(BattleManager, 1)[0]  # get the BattleManager, there should be 1
        battles = manager.get_battles(player)
        assert len(battles) <= 1, "The player can only by in one battle"
        battle = None
        if len(battles) > 0:
            battle = battles[0]
        # now we have the battle that the player is currently in which could be None

        if battle is None:  # the player isn't in a battle
            first_arg = command_input.get_arg(0, False)  # remember this is a list containing the first arg at [0]
            # ignore_unimportant_before is False (^)because we want to get everything the player typed after the command

            if not first_arg:  # there isn't a first argument
                player.send_message("Who would you like to battle?")
                return InputHandleType.HANDLED
            reference = " ".join(first_arg)
            challenged = player.location.get_referenced_entity(handler, reference)
            if challenged is None:
                player.send_message(Message("Cannot find entity named: '{}' in your current location.",
                                            named_variables=[reference]))
                return InputHandleType.HANDLED
            challenge_action = EntityChallengeAction(player, challenged)
            handler.do_action(challenge_action)
            challenge_action.try_action(handler)
            return InputHandleType.HANDLED

        # now we know the player is in a battle since Battle isn't None
        assert not battle.has_ended, "For whatever reason, we received at battle that was ended."
        if not battle.has_started:
            player.send_message("Sorry, for whatever reason the battle hasn't started yet. This could be an error.")
            return InputHandleType.HANDLED
        turn = battle.current_turn
        assert turn is not None, "The battle is started and there's no current_turn ??? That would be an error."
        user = turn.get_target(player)
        assert isinstance(user.move_chooser, SetMoveChooser), "We need the player's MoveChooser to be a SetMoveChooser."

        first_arg = command_input.get_arg(0)
        if not first_arg:
            return self.__class__.send_options(player, user)
        try:
            number = int(first_arg[0])
            # now that we know the first argument is a number, the player wants to choose a move
            return self.__class__.choose_option_from_number(battle, number, player, user)
        except ValueError:
            pass  # the first argument was not a number so lets test for something else now
        if first_arg[0].lower() == "members":
            return self.__class__.send_members(battle, player)

        self.send_help(player)
        return InputHandleType.HANDLED
Ejemplo n.º 6
0
    def go_to_other_location(self, handler: Handler, new_location, direction: Point, player: Player) -> CanDo:
        if not player[EventsObject].been_introduced_to_furry:
            return False, "You should probably try to save your friend."
        if new_location is None:
            return CANT_MOVE_DIRECTION

        if direction == WEST:
            action = GoAction(player, player.location, new_location, create_leave_message(self))
            action.can_do = CAN_GO_TO_LOCATION
            handler.do_action(action)
            return action.try_action(handler)
        elif direction in DIRECTIONS:
            return CANT_MOVE_DIRECTION
        return CANT_JUMP_LOCATION
Ejemplo n.º 7
0
    def go_to_other_location(self, handler: Handler, new_location, direction: Point, player: Player):
        if new_location is None:
            return CANT_MOVE_DIRECTION

        if direction == EAST:
            pass
        elif direction in DIRECTIONS:
            return CANT_MOVE_DIRECTION
        else:
            return CANT_JUMP_LOCATION

        action = GoAction(player, player.location, new_location, create_leave_message(self))
        action.can_do = CAN_GO_TO_LOCATION
        handler.do_action(action)
        return action.try_action(handler)
Ejemplo n.º 8
0
 def start(self, handler: Handler):
     """
     Call this method when you want the battle to start.
     Calling this will add this instance to the handler's input_handlers
     :param handler: The Handler object
     """
     from textadventure.battling.actions import BattleStart
     self.current_turn = self.__next_turn(
         None
     )  # set current_turn so not None when a manager handles the action
     battle_start = BattleStart(
         self
     )  # probably uses current_turn to add effects to the entities/targets
     handler.do_action(battle_start)
     battle_start.try_action(handler)
Ejemplo n.º 9
0
    def on_yell(self, handler: Handler, player: Player, command_input: CommandInput, is_there_response=False):
        if player[EventsObject].knows_laura:
            super().on_yell(handler, player, command_input, False)
        else:
            super().on_yell(handler, player, command_input, True)
            player.send_message("You feel a hand go over your mouth.")
            player.send_message("You see a rock coming at your fa-")
            player.clear_screen()

            player.send_wait(1)
            laura = handler.get_livings(LauraPerson, 1)[0]
            laura.tell(player, "Who are you?")
            player.send_wait(0.5)
            laura.tell(player, Message("You have {}'s wallet! What did you do to them?",
                                       named_variables=[player[PlayerFriend]]))
            player.send_wait(0.3)
            player.tell(player, "He's my fri-")
            laura.tell(player, "Lies!")
            player.send_wait(1.2)
            player.clear_screen()

            player.send_wait(1)
            laura.tell(player, Message("Hi I'm {}. Sorry about that. Everything is cleared up now.",
                                       named_variables=[laura]))
            player[EventsObject].knows_laura = True  # make sure this code isn't run for the player again
            sword = Sword(SwordType.WOODEN)  # we just need this variable to reference in named_variables
            sword.change_holder(None, player.location)
            laura.tell(player, Message("How about for all your troubles I'll give you this {}. Take it.",
                                       named_variables=[sword]))
            Sword(SwordType.CHINESE_STEEL).change_holder(None, player.location)
Ejemplo n.º 10
0
    def go_to_other_location(self, handler: Handler, new_location, direction: Point, player: Player):
        if new_location is None:
            return CANT_MOVE_DIRECTION

        if direction == EAST:
            assert False, "Shouldn't happen yet. Remove assert if ready."
            pass  # to fo stuff here
        elif direction == WEST:
            pass
        elif direction in DIRECTIONS:
            return CANT_MOVE_DIRECTION
        else:
            return CANT_JUMP_LOCATION

        action = GoAction(player, player.location, new_location, create_leave_message(self))
        action.can_do = CAN_GO_TO_LOCATION
        handler.do_action(action)
        return action.try_action(handler)
Ejemplo n.º 11
0
    def go_to_other_location(self, handler: Handler, new_location, direction: Point, player: Player) -> CanDo:
        if new_location is None:
            return CANT_MOVE_DIRECTION

        if direction == SOUTH:
            pass  # back to entrance/double doors
        elif direction == NORTH:
            # Going through, so check if the player has cleared the spider webs
            if not player[EventsObject].has_cleared_spider_webs_at_entrance:
                return False, "You can't get through, there are too many spider webs."
            pass
        elif direction in DIRECTIONS:
            return CANT_MOVE_DIRECTION
        else:
            return CANT_JUMP_LOCATION

        action = GoAction(player, player.location, new_location, create_leave_message(self))
        action.can_do = CAN_GO_TO_LOCATION
        handler.do_action(action)
        return action.try_action(handler)
Ejemplo n.º 12
0
    def start(self):
        assert self.handler is None, "If self.handler isn't None, then start must have been called before this."

        players = self.create_players()
        for player in players:
            self.init_player(player)

        locations = self.game.create_locations()

        input_handlers = list(self.game.create_custom_input_handlers())
        input_handlers.extend(self.game.create_input_handlers())

        managers = list(self.game.create_custom_managers())
        managers.extend(self.game.create_managers())

        message = "Unable to load data."
        savable = None
        data = load_data(self.save_path.get_handler_path())
        if not isinstance(data, str):
            if isinstance(data, HandlerSavable):
                savable = data
                message = "Loaded data successfully."
            else:
                message = "Tried to load data for handler and got: {}".format(data)
        self.handler = Handler(list(players), locations, input_handlers, managers, self.save_path, savable,
                               player_handler=self.player_handler)
        self.handler.broadcast(message)

        self.game.add_other(self.handler)

        self.handler.start()
        for player in self.handler.get_players():
            if player.is_new:
                player.location = self.game.get_starting_location(self.handler, player)
            else:
                player.savable.on_load(player, self.handler)

            player.location.on_enter(player, None, self.handler)
Ejemplo n.º 13
0
    def player_go(handler: Handler, player: Player, first_argument: str) -> InputHandleType:
        # note that first_argument doesn't have to be a single word
        point = get_point(handler, player, first_argument)
        if point is None:
            player.send_message("Cannot find location: \"" + first_argument + "\"")
            return InputHandleType.HANDLED
        new_location = handler.get_point_location(point)
        if new_location == player.location:
            player.send_message("You're already in that location!")
            return InputHandleType.HANDLED

        result = player.location.go_to_other_location(handler, new_location, point - player.location.point, player)
        if not result[0]:
            player.send_message(result[1])
        return InputHandleType.HANDLED
Ejemplo n.º 14
0
    def get_entities(self,
                     handler: Handler,
                     entity_type: Type[T] = Entity) -> List[T]:
        """
        Gets the list of entities in this location, including players

        :param handler: the handler object
        :param entity_type: The type of the entity you are looking for. Defaults to Entity (gets all types of entities)
        :return: The list of entities in this location
        """
        r = []
        for entity in handler.get_entities():
            if entity.location == self and isinstance(entity, entity_type):
                r.append(entity)

        return r
Ejemplo n.º 15
0
 def _handle_command(self, handler: Handler, sender: CommandSender, command_input: CommandInput):
     result = handler.save(sender)
     sender.send_message(Message(result[1], message_type=MessageType.IMMEDIATE))
     return InputHandleType.HANDLED
Ejemplo n.º 16
0
class Main:
    """
    Used to initialize a CustomGame object along with constructing a Handler object making initializing a game\
    a lot simpler and more abstract
    """
    def __init__(self, game: CustomGame, custom_managers: List[Manager], save_path: SavePath, rest=0.0, clean=False,
                 player_handler: PlayerHandler = None):
        """
        Note: Custom managers do not yet call on_action when an action happens. This may be easily implemented in the
        future but, is not needed as of right now

        :param game: The custom game that this helps initialize
        :param custom_managers: List of managers that will be updated before handler. Note these managers should NOT
                                be related to the game and should not alter game play at all. They should only be
                                cosmetic or should help with things unrelated to the game
        :param rest: The amount of time to wait between each update. If this is not 0, calling update will pause the
                     program
        :param clean: True if the program shouldn't attempt to load any data which will overwrite existing data when
                      saving
        """
        self.game = game

        self.handler = None
        """Member that is initialized when start is called"""
        self.custom_managers = custom_managers
        self.save_path = save_path if save_path is not None else SavePath(Path("./save.dat.d"))
        self.rest = rest
        self.clean = clean
        self.player_handler = player_handler

    def create_players(self) -> List[Player]:
        """
        The method that is called on the start of a game and normally where you add players that are ready to play\
        the game right away. (Usually client side)

        The default implementation returns an empty list

        When this method is called, self.handler will not be None

        Note: When overriding this is not meant to return a list of subclasses of Player. It should only be used to
        create players that will start in the game. (Normally there should be just one) (If this Main instance controls
        a server, then the list would probably be empty)

        :return: A list of players to add immediately
        """
        return []

    def init_player(self, player: Player):
        """
        A method that is used for each player that joins no matter if they are new or not and no matter when they join.

        Note that this should NOT be overridden. Since this calls self.on_player_start. You can change that when
        creating this object

        Note that self.handler may be null and player.location may be null. This method should not try to set location

        :param player: The player that has just joined
        """
        if player.is_new:
            self.game.new_player(player)

    def start(self):
        assert self.handler is None, "If self.handler isn't None, then start must have been called before this."

        players = self.create_players()
        for player in players:
            self.init_player(player)

        locations = self.game.create_locations()

        input_handlers = list(self.game.create_custom_input_handlers())
        input_handlers.extend(self.game.create_input_handlers())

        managers = list(self.game.create_custom_managers())
        managers.extend(self.game.create_managers())

        message = "Unable to load data."
        savable = None
        data = load_data(self.save_path.get_handler_path())
        if not isinstance(data, str):
            if isinstance(data, HandlerSavable):
                savable = data
                message = "Loaded data successfully."
            else:
                message = "Tried to load data for handler and got: {}".format(data)
        self.handler = Handler(list(players), locations, input_handlers, managers, self.save_path, savable,
                               player_handler=self.player_handler)
        self.handler.broadcast(message)

        self.game.add_other(self.handler)

        self.handler.start()
        for player in self.handler.get_players():
            if player.is_new:
                player.location = self.game.get_starting_location(self.handler, player)
            else:
                player.savable.on_load(player, self.handler)

            player.location.on_enter(player, None, self.handler)

    def update(self):
        self.handler.update()
        for manager in self.custom_managers:
            manager.update(self.handler)

        time.sleep(self.rest)

    def end(self):
        """
        Method that should not be overridden. It will call on_end
        """
        self.on_end()

    def on_end(self):
        """
        Method that is called by end(). This should be overridden.
        """
        pass