Ejemplo n.º 1
0
    def accept_duel(self, bot: Bot, source: User, **rest: Any) -> None:
        """
        Accepts any active duel requests you've received.

        How to use: !accept
        """

        if source.id not in self.duel_targets:
            bot.whisper(source,
                        "You are not being challenged to a duel by anyone.")
            return

        with DBManager.create_session_scope() as db_session:
            requestor = User.find_by_id(db_session,
                                        self.duel_targets[source.id])
            if not requestor:
                bot.whisper(
                    source,
                    "The user who challenged you is gone, I don't know where they went!"
                )
                return

            duel_price = self.duel_request_price[self.duel_targets[source.id]]

            if not source.can_afford(duel_price) or not requestor.can_afford(
                    duel_price):
                bot.whisper(
                    source,
                    f"Your duel request with {requestor} was cancelled due to one of you not having enough points.",
                )
                bot.whisper(
                    requestor,
                    f"Your duel request with {source} was cancelled due to one of you not having enough points.",
                )

                del self.duel_requests[requestor.id]
                del self.duel_request_price[requestor.id]
                del self.duel_begin_time[requestor.id]
                del self.duel_targets[source.id]

                return

            source.points -= duel_price
            requestor.points -= duel_price
            winning_pot = int(duel_price *
                              (1.0 - self.settings["duel_tax"] / 100))
            participants = [source, requestor]
            winner = random.choice(participants)
            participants.remove(winner)
            loser = participants.pop()
            winner.points += duel_price
            winner.points += winning_pot

            # Persist duel statistics
            winner.duel_stats.won(winning_pot)
            loser.duel_stats.lost(duel_price)

            arguments = {
                "winner": winner.name,
                "loser": loser.name,
                "total_pot": duel_price,
                "extra_points": winning_pot,
            }

            if duel_price > 0:
                message = self.get_phrase("message_won_points", **arguments)
                if duel_price >= 500 and self.settings["show_on_clr"]:
                    bot.websocket_manager.emit(
                        "notification",
                        {"message": f"{winner} won the duel vs {loser}"})
            else:
                message = self.get_phrase("message_won", **arguments)
            bot.say(message)

            del self.duel_requests[requestor.id]
            del self.duel_request_price[requestor.id]
            del self.duel_begin_time[requestor.id]
            del self.duel_targets[source.id]

            HandlerManager.trigger("on_duel_complete",
                                   winner=winner,
                                   loser=loser,
                                   points_won=winning_pot,
                                   points_bet=duel_price)
Ejemplo n.º 2
0
    def initiate_duel(self, bot: Bot, source: User, message: str,
                      **rest: Any) -> bool:
        """
        Initiate a duel with a user.
        You can also bet points on the winner.
        By default, the maximum amount of points you can spend is 420.

        How to use: !duel USERNAME POINTS_TO_BET
        """

        if message is None:
            return False

        max_pot = self.settings["max_pot"]

        msg_split = message.split()
        input = msg_split[0]

        with DBManager.create_session_scope() as db_session:
            user = User.find_by_user_input(db_session, input)
            if user is None:
                # No user was found with this username
                return False

            duel_price = 0
            if len(msg_split) > 1:
                try:
                    duel_price = int(msg_split[1])
                    if duel_price < 0:
                        return False

                    if duel_price > max_pot:
                        duel_price = max_pot
                except ValueError:
                    pass

            if source.id in self.duel_requests:
                currently_duelling = User.find_by_id(
                    db_session, self.duel_requests[source.id])
                if currently_duelling is None:
                    del self.duel_requests[source.id]
                    return False

                bot.whisper(
                    source,
                    f"You already have a duel request active with {currently_duelling}. Type !cancelduel to cancel your duel request.",
                )
                return False

            if user == source:
                # You cannot duel yourself
                return False

            if user.last_active is None or (
                    utils.now() - user.last_active) > timedelta(minutes=5):
                bot.whisper(
                    source,
                    "This user has not been active in chat within the last 5 minutes. Get them to type in chat before sending another challenge",
                )
                return False

            if not user.can_afford(duel_price) or not source.can_afford(
                    duel_price):
                bot.whisper(
                    source,
                    f"You or your target do not have more than {duel_price} points, therefore you cannot duel for that amount.",
                )
                return False

            if user.id in self.duel_targets:
                challenged_by = User.find_by_id(db_session,
                                                self.duel_requests[user.id])
                bot.whisper(
                    source,
                    f"This person is already being challenged by {challenged_by}. Ask them to answer the offer by typing !deny or !accept",
                )
                return False

            self.duel_targets[user.id] = source.id
            self.duel_requests[source.id] = user.id
            self.duel_request_price[source.id] = duel_price
            self.duel_begin_time[source.id] = utils.now()
            bot.whisper(
                user,
                f"You have been challenged to a duel by {source} for {duel_price} points. You can either !accept or !deny this challenge.",
            )
            bot.whisper(source,
                        f"You have challenged {user} for {duel_price} points")

        return True