Untitled

 avatar
unknown
python
5 months ago
8.3 kB
4
Indexable
cooldown('65 minutes', key=user.id, count=3)

class PokeCatch(View):
    MAX_BAIT = 3
    MAX_RETRY = 3
    MAX_ATTEMPT_RANGE = 5
    BAIT_CHANCE = 0.5

    def __init__(self, user_id):
        self.user_id = user_id
        self.pokemon = self.emoji = None
        self.attempts_count = self.retry_count = self.bait_count = 0
        self.max_attempts = pyrandom.randint(2, self.MAX_ATTEMPT_RANGE)

        self.items_db = SlashMongo("inventory", "items")
        self.daycare_db = SlashMongo("inventory", "daycare")
        self.emojis_db = SlashMongo("inventory", "emojis")

    def embed(self, desc, color=0x248046):
        return Message(description=desc, color=color)

    def generate_random_xp(self, min_xp=15, max_xp=25):
        return pyrandom.randint(min_xp, max_xp)

    def remaining(self, max_value, count_value):
        remaining = max_value - count_value
        return f"**`{remaining}`** sur **`{max_value}`** restants"

    def limit_reached(self, label, max_val):
        return self.embed(
            desc=(
                f"❌ **Limite atteinte**\n"
                f"Tu as atteint la limite de **{max_val} {label}**"
            ),
            color=0xFF0000
        )

    def calc_chance(self):
        base_chance = self.pokemon['weight'] * 0.2
        attempts_bonus = max((self.attempts_count - 1) * 0.02, 0)
        bait_penalty = self.bait_count * 0.03

        final_chance = base_chance + attempts_bonus - bait_penalty
        return min(max(final_chance, 0.05), 0.95) if pyrandom.random() >= 0.02 else 0.90

    async def validate_user(self, i):
        if i.user.id != self.user_id:
            await defer(i, action="create", ephemeral=True)
            respond_interaction(i, "❌ Vous ne pouvez pas cliquer.")
            return False
        return True

    @button(label="", style="success", emoji=emoji('pokeball', True))
    async def ball(self, i, b):
        if not await self.validate_user(i): return

        self.attempts_count += 1
        await self.launch_ball(i)

        if max(pyrandom.random(), 0.05) <= self.calc_chance():
            await self.handle_success(i)
        else:
            await self.handle_failure(i)

    async def launch_ball(self, i):
        await defer(i, action="update")

        embed = self.embed(
            desc=(
                f"**{user.display_name}**,\n"
                f"utilise une **Poké BALL** !"
            ),
            color=0x0094FF
        )
        respond_interaction(i, content=emoji('waiting'), embed=embed, components=None)
        await sleep(pyrandom.uniform(2, 4))

    async def handle_failure(self, i):
        if self.attempts_count > self.max_attempts:
            embed = self.embed(
                desc=f"**{self.pokemon['emoji_name']}** sauvage s'enfuit ! 😔",
                color=0xFF0000
            )
            respond_interaction(i, content=None, embed=embed, components=None)
            self.stop()
        else:
            embed = self.embed(
                desc=f"❌ **Oh non !**\nÉchec de la capture... **Try again !**",
                color=0xFF0000
            )
            respond_interaction(i, content=self.emoji, embed=embed, components=self)

    async def handle_success(self, i):
        await self.items_db.update_one(
            {
                "item_numb": str(self.pokemon["item_numb"]),
                "user_id": str(self.user_id)
            },
            {
                "$inc": {"count": 1}
            },
            upsert=True
        )

        xp_message = await self.add_xp_daycare()

        embed = self.embed(
            desc=(
                f"**Et Hop !** ✨\n\n"
                f"**{self.pokemon['emoji_name']}** est attrapé !\n{xp_message}"
            ),
            color=0xffac32
        )
        respond_interaction(i, content=emoji('success'), embed=embed, components=None)
        self.stop()

    @button(label="", style="secondary", emoji="🍖")
    async def bait(self, i, b):
        if not await self.validate_user(i): return

        await defer(i, action="update")

        if self.bait_count < self.MAX_BAIT:
            self.bait_count += 1
            bait_count = self.remaining(self.MAX_BAIT, self.bait_count)

            if pyrandom.random() < self.BAIT_CHANCE:
                self.max_attempts += 1

            embed = self.embed(
                desc=(
                    f"-# Peut réduire les chances de fuite,\n" 
                    f"-# mais rend la capture plus difficile.\n\n"
                    f"🍖 **Appâts:** {bait_count}"
                )
            )
        else:
            embed = self.limit_reached("appâts", self.MAX_BAIT)

        respond_interaction(i, embed=embed)

    @button(label="", style="primary", emoji="🔄")
    async def retry(self, i, b):
        if not await self.validate_user(i): return

        await defer(i, action="update")

        if self.retry_count < self.MAX_RETRY:
            self.retry_count += 1
            self.attempts_count = self.bait_count = 0
            await self.start_new_encounter(i)
        else:
            embed = self.limit_reached("relances", self.MAX_RETRY)
            respond_interaction(i, embed=embed)

    async def start_new_encounter(self, i):
        respond_interaction(i, content=emoji('random'), embed=None, components=None)
        await sleep(1)

        all_pokemon = await self.emojis_db.find({})
        weights = map(lambda p: p['weight'], all_pokemon)
        self.pokemon = pyrandom.choices(all_pokemon, weights)[0]

        captured_data = await self.items_db.find_one(
            {
                "item_numb": self.pokemon['item_numb'], 
                "user_id": str(self.user_id)
            }
        )

        is_captured = emoji('pokeball') if captured_data else ""
        self.emoji = f"<a:{self.pokemon['emoji_name']}:{self.pokemon['emoji_id']}>"

        embed = self.embed(
            desc=(
                f"{is_captured} **`{self.pokemon['emoji_name'].upper()}`** "
                f"`N°{self.pokemon['item_numb']}` **apparait !**\n\n"
                f"🔄 **Relances:** {self.remaining(self.MAX_RETRY, self.retry_count)}"
            )
        )
        respond_interaction(i, content=self.emoji, embed=embed, components=self)

    async def add_xp_daycare(self):
        daycare_data = await self.daycare_db.find_one({"user_id": str(self.user_id)})

        if daycare_data:
            xp_to_add = self.generate_random_xp()
            total_xp = int(daycare_data['xp']) + xp_to_add
            xp_required = int(daycare_data['xp_required'])

            await self.daycare_db.update_one(
                {
                    "user_id": str(self.user_id)
                },
                {
                    "$set": {"xp": str(total_xp)}
                }
            )
            evolution_msg = await self.check_evolve(total_xp, xp_required, daycare_data)

            xp_msg = (
                f"\n✨ Ton **{daycare_data['emoji_name']}** gagne **{xp_to_add} XP**\n"
                f"🔹 Total : **{total_xp} XP**.\n"
                f"🔹 Encore **{xp_required - total_xp} XP** pour évoluer."
            )

            return evolution_msg or xp_msg

        return ""

    async def check_evolve(self, total_xp, xp_required, daycare_data):
        if total_xp >= xp_required:
            new_pokemon_numb = pyrandom.choice(daycare_data['evolution_numb'])
            new_pokemon = await self.emojis_db.find_one({"item_numb": new_pokemon_numb})

            await self.daycare_db.delete_one({"user_id": str(self.user_id)})

            await self.items_db.update_one(
                {
                    "item_numb": str(new_pokemon['item_numb']), 
                    "user_id": str(self.user_id)
                }, 
                {
                    "$inc": {"count": 1}
                }, 
                upsert=True
            )

            return (
                f"\n✨ Ton {daycare_data['emoji_name']} a évolué "
                f"en **{new_pokemon['emoji_name']}** ! ✨"
            )

        return None

view = PokeCatch(user.id)
await view.start_new_encounter(interaction)
exit_code = await view.wait(scope=scope, timeout=300)
exit_code == "timeout" and set_error(f"**timeout**, {user.mention} !")
Editor is loading...
Leave a Comment