1
Fork 0
mirror of https://github.com/wlinator/luminara.git synced 2024-10-02 18:23:12 +00:00

refactor: Optimize coinflip command

This commit is contained in:
wlinator 2024-09-22 16:45:26 +02:00
parent 360454c152
commit b8139a9432
2 changed files with 105 additions and 52 deletions

View file

@ -85,7 +85,6 @@
"coinflip_flipping_animation_3": "\ud83e\ude99 Flipping.", "coinflip_flipping_animation_3": "\ud83e\ude99 Flipping.",
"coinflip_flipping_author": "flipping a Coin", "coinflip_flipping_author": "flipping a Coin",
"coinflip_flipping_description": "the coin is in the air...", "coinflip_flipping_description": "the coin is in the air...",
"coinflip_invalid_prediction_author": "Invalid Prediction",
"coinflip_invalid_prediction_description": "please enter a valid prediction ('heads'/'h' or 'tails'/'t').", "coinflip_invalid_prediction_description": "please enter a valid prediction ('heads'/'h' or 'tails'/'t').",
"coinflip_result_author": "Coin Flip Result", "coinflip_result_author": "Coin Flip Result",
"coinflip_result_description": "the coin landed on **{0}**.", "coinflip_result_description": "the coin landed on **{0}**.",
@ -163,6 +162,7 @@
"error_actionable_hierarchy_bot": "I don't have permission to perform this action on this user due to role hierarchy.", "error_actionable_hierarchy_bot": "I don't have permission to perform this action on this user due to role hierarchy.",
"error_actionable_hierarchy_user": "you don't have permission to perform this action on this user due to role hierarchy.", "error_actionable_hierarchy_user": "you don't have permission to perform this action on this user due to role hierarchy.",
"error_actionable_self": "you can't perform this action on yourself.", "error_actionable_self": "you can't perform this action on yourself.",
"error_already_flipping_coin_description": "you already have a coinflip running.",
"error_already_playing_blackjack": "you already have a game of blackjack running.", "error_already_playing_blackjack": "you already have a game of blackjack running.",
"error_birthdays_disabled_author": "Birthdays Disabled", "error_birthdays_disabled_author": "Birthdays Disabled",
"error_birthdays_disabled_description": "birthdays are disabled in this server.", "error_birthdays_disabled_description": "birthdays are disabled in this server.",

View file

@ -1,20 +1,25 @@
import asyncio import asyncio
import random import random
import discord
from discord import app_commands
from discord.ext import commands from discord.ext import commands
import lib.format import lib.format
from lib.client import Luminara from lib.client import Luminara
from lib.const import CONST from lib.const import CONST
from lib.exceptions import LumiException
from ui.embeds import Builder from ui.embeds import Builder
ACTIVE_COINFLIPS: dict[int, bool] = {}
class Coinflip(commands.Cog): class Coinflip(commands.Cog):
def __init__(self, bot: Luminara) -> None: def __init__(self, bot: Luminara) -> None:
self.bot: Luminara = bot self.bot: Luminara = bot
self.coinflip.usage = lib.format.generate_usage(self.coinflip) self.coinflip.usage = lib.format.generate_usage(self.coinflip)
@commands.hybrid_command( @commands.command(
name="coinflip", name="coinflip",
aliases=["cf"], aliases=["cf"],
) )
@ -22,6 +27,7 @@ class Coinflip(commands.Cog):
async def coinflip( async def coinflip(
self, self,
ctx: commands.Context[Luminara], ctx: commands.Context[Luminara],
*,
prediction: str | None = None, prediction: str | None = None,
) -> None: ) -> None:
""" """
@ -32,73 +38,120 @@ class Coinflip(commands.Cog):
ctx : commands.Context[Luminara] ctx : commands.Context[Luminara]
The context of the command. The context of the command.
prediction : str, optional prediction : str, optional
The predicted outcome ('heads'/'h' or 'tails'/'t'). The predicted outcome ('heads', 'h', 'tails', or 't').
""" """
result = random.choice(["heads", "tails"])
if prediction: if prediction:
prediction = prediction.lower() prediction = prediction.lower()
if prediction not in ["heads", "h", "tails", "t"]: if prediction in ["h", "head"]:
embed = Builder.create_embed( prediction = "heads"
Builder.ERROR, elif prediction in ["t", "tail"]:
user_name=ctx.author.name, prediction = "tails"
author_text=CONST.STRINGS["coinflip_invalid_prediction_author"],
description=CONST.STRINGS["coinflip_invalid_prediction_description"],
)
await ctx.send(embed=embed)
return
flip_embed = Builder.create_embed( await self._coinflip(ctx, prediction)
Builder.INFO,
user_name=ctx.author.name,
author_text=CONST.STRINGS["coinflip_flipping_author"],
description=CONST.STRINGS["coinflip_flipping_description"],
)
flip_message = await ctx.send(embed=flip_embed)
await asyncio.sleep(1) @app_commands.command(name="coinflip", description="Flip a coin. Optionally predict the outcome.")
@app_commands.guild_only()
@app_commands.choices(
prediction=[
app_commands.Choice(name="Heads", value="heads"),
app_commands.Choice(name="Tails", value="tails"),
],
)
async def coinflip_slash(
self,
interaction: discord.Interaction,
prediction: app_commands.Choice[str] | None = None,
) -> None:
"""
Flip a coin. Optionally predict the outcome.
Parameters
----------
interaction : discord.Interaction
The interaction of the command.
prediction : app_commands.Choice[str], optional
The predicted outcome ('heads' or 'tails').
"""
await self._coinflip(interaction, prediction.value if prediction else None)
async def _coinflip(self, ctx: commands.Context[Luminara] | discord.Interaction, prediction: str | None) -> None:
if isinstance(ctx, commands.Context):
author = ctx.author
reply = ctx.reply
else:
author = ctx.user
reply = ctx.followup.send
if author.id in ACTIVE_COINFLIPS:
raise LumiException(CONST.STRINGS["error_already_flipping_coin_description"])
ACTIVE_COINFLIPS[author.id] = True
try:
result = random.choice(["heads", "tails"])
if prediction and prediction not in ["heads", "tails"]:
raise LumiException(CONST.STRINGS["coinflip_invalid_prediction_description"])
for animation in (
CONST.STRINGS["coinflip_flipping_animation_1"],
CONST.STRINGS["coinflip_flipping_animation_2"],
CONST.STRINGS["coinflip_flipping_animation_3"],
):
flip_embed = Builder.create_embed( flip_embed = Builder.create_embed(
Builder.INFO, Builder.INFO,
user_name=ctx.author.name, user_name=author.name,
author_text=CONST.STRINGS["coinflip_flipping_author"], author_text=CONST.STRINGS["coinflip_flipping_author"],
description=animation, description=CONST.STRINGS["coinflip_flipping_description"],
) )
await flip_message.edit(embed=flip_embed)
await asyncio.sleep(0.5)
if prediction: if isinstance(ctx, commands.Context):
predicted_correctly = (prediction.startswith("h") and result == "heads") or ( flip_message = await reply(embed=flip_embed)
prediction.startswith("t") and result == "tails" else:
) await ctx.response.send_message(embed=flip_embed)
if predicted_correctly: flip_message = await ctx.original_response()
await asyncio.sleep(1)
if flip_message is not None:
flip_embed.description = f"**{author.name}** " + CONST.STRINGS["coinflip_flipping_animation_1"]
await flip_message.edit(embed=flip_embed)
await asyncio.sleep(0.5)
flip_embed.description = f"**{author.name}** " + CONST.STRINGS["coinflip_flipping_animation_2"]
await flip_message.edit(embed=flip_embed)
await asyncio.sleep(0.5)
flip_embed.description = f"**{author.name}** " + CONST.STRINGS["coinflip_flipping_animation_3"]
await flip_message.edit(embed=flip_embed)
await asyncio.sleep(0.5)
if prediction:
predicted_correctly = prediction == result
embed_type = Builder.SUCCESS if predicted_correctly else Builder.ERROR
author_text = CONST.STRINGS[
"coinflip_correct_prediction_author" if predicted_correctly else "coinflip_wrong_prediction_author"
]
description = CONST.STRINGS[
"coinflip_correct_prediction_description"
if predicted_correctly
else "coinflip_wrong_prediction_description"
].format(result)
embed = Builder.create_embed( embed = Builder.create_embed(
Builder.SUCCESS, embed_type,
user_name=ctx.author.name, user_name=author.name,
author_text=CONST.STRINGS["coinflip_correct_prediction_author"], author_text=author_text,
description=CONST.STRINGS["coinflip_correct_prediction_description"].format(result), description=description,
) )
else: else:
embed = Builder.create_embed( embed = Builder.create_embed(
Builder.ERROR, Builder.INFO,
user_name=ctx.author.name, user_name=author.name,
author_text=CONST.STRINGS["coinflip_wrong_prediction_author"], author_text=CONST.STRINGS["coinflip_result_author"],
description=CONST.STRINGS["coinflip_wrong_prediction_description"].format(result), description=CONST.STRINGS["coinflip_result_description"].format(result),
) )
else:
embed = Builder.create_embed(
Builder.INFO,
user_name=ctx.author.name,
author_text=CONST.STRINGS["coinflip_result_author"],
description=CONST.STRINGS["coinflip_result_description"].format(result),
)
await flip_message.edit(embed=embed) if flip_message is not None:
await flip_message.edit(embed=embed)
finally:
del ACTIVE_COINFLIPS[author.id]
async def setup(bot: Luminara) -> None: async def setup(bot: Luminara) -> None: