From ad243df816dfcd26d0291a46a49bf8b428dfb645 Mon Sep 17 00:00:00 2001 From: Milo Weinberg Date: Wed, 19 Jun 2024 19:08:50 -0400 Subject: [PATCH] Fix quest_completed + reduce code duplication --- bot/cogs/commands/econ.py | 49 +---------------- bot/cogs/core/database.py | 4 +- bot/cogs/core/quests.py | 110 +++++++++++++++++++++++++------------- bot/data/text/en.json | 2 +- 4 files changed, 78 insertions(+), 87 deletions(-) diff --git a/bot/cogs/commands/econ.py b/bot/cogs/commands/econ.py index b2250268..835b5fda 100644 --- a/bot/cogs/commands/econ.py +++ b/bot/cogs/commands/econ.py @@ -2283,54 +2283,7 @@ async def daily_quest(self, ctx: Ctx): quest = await self.quests.fetch_user_daily_quest(ctx.author.id) - quest_text = ctx.l.econ.daily_quests.mapping[quest.key] - quest_emoji = ( - emoji_getter := ( - lambda cur, path: emoji_getter(cur[path.pop(0)], path) if path else cur - ) - )(self.d.emojis, quest.emoji.split(".")) - - close_to_completion = (quest.value / (quest.target_value + 0.1)) > 0.75 - encouragements = ( - ctx.l.econ.daily_quests.encouragements.done - if quest.done - else ctx.l.econ.daily_quests.encouragements.close - if close_to_completion - else ctx.l.econ.daily_quests.encouragements.far - ) - - title_message = ( - ctx.l.econ.daily_quests.completed if quest.done else ctx.l.econ.daily_quests.current - ) - - embed = discord.Embed( - title=title_message.format( - quest_title=quest_text.title.format( - target=quest.target_value, - emoji=quest_emoji, - ), - ), - description="\n".join([ - ctx.l.econ.daily_quests.progress.format( - progress=quest_text.progress.format( - value=quest.value, - target=quest.target_value, - encouragement=random.choice(encouragements), - ), - ), - ctx.l.econ.daily_quests.reward.format( - reward_amount=quest.reward_amount, - reward_emoji=emojify_item(self.d, quest.reward_item), - ), - ctx.l.econ.daily_quests.expires_at.format( - expires_at=discord.utils.format_dt( - quest.day.datetime + datetime.timedelta(days=1), - "R", - ), - ), - ]), - color=self.bot.embed_color, - ) + embed = self.quests.get_quest_embed(ctx, quest) await ctx.send(embed=embed) diff --git a/bot/cogs/core/database.py b/bot/cogs/core/database.py index 542214b0..624b3b6d 100644 --- a/bot/cogs/core/database.py +++ b/bot/cogs/core/database.py @@ -885,7 +885,7 @@ async def fetch_user_daily_quest(self, user_id: int) -> UserQuest: ) if db_quest is None: - random_quest_values = await self.quests.get_random_quest(user_id) + random_quest_values = await self.quests.get_random_quest_to_store(user_id) await self.db.execute( ( @@ -954,7 +954,7 @@ async def update_user_daily_quest( async def mark_daily_quest_as_done(self, user_id: int, key: str) -> None: await self.db.execute( - "UPDATE daily_quests SET done = true WHERE user_id = $1 AND active_quest_key = $2", + "UPDATE daily_quests SET done = true WHERE user_id = $1 AND key = $2", user_id, key, ) diff --git a/bot/cogs/core/quests.py b/bot/cogs/core/quests.py index 95f5690b..33982c33 100644 --- a/bot/cogs/core/quests.py +++ b/bot/cogs/core/quests.py @@ -1,4 +1,5 @@ import asyncio +import datetime import math import random import typing @@ -9,6 +10,7 @@ from discord.ext import commands from bot.utils.ctx import CustomContext +from bot.utils.misc import emojify_item from bot.villager_bot import VillagerBotCluster from common.models.data import Quest from common.models.db.quests import UserQuest as DbUserQuest @@ -39,21 +41,71 @@ def __init__(self, bot: VillagerBotCluster): def db(self) -> "Database": return typing.cast("Database", self.bot.get_cog("Database")) - async def fetch_calc_difficulty_multiplier( - self, - user_id: int, - quest_def: Quest, - ) -> float | None: - pickaxe = await self.db.fetch_pickaxe(user_id) - pickaxe_level = len(self.d.mining.pickaxes) - self.d.mining.pickaxes.index(pickaxe) + def get_quest_embed(self, loc: CustomContext | commands.Context | discord.User, quest: UserQuest): + lang = self.bot.l["en"] + if isinstance(loc, CustomContext | commands.Context): + lang = loc.l - return eval( - quest_def.difficulty_eval_multi, - {"pickaxe_level": pickaxe_level, "ceil": math.ceil}, - {}, + quest_text = lang.econ.daily_quests.mapping[quest.key] + quest_emoji = ( + emoji_getter := ( + lambda cur, path: emoji_getter(cur[path.pop(0)], path) if path else cur + ) + )(self.d.emojis, quest.emoji.split(".")) + + close_to_completion = (quest.value / (quest.target_value + 0.1)) > 0.75 + encouragements = ( + lang.econ.daily_quests.encouragements.done + if quest.done + else lang.econ.daily_quests.encouragements.close + if close_to_completion + else lang.econ.daily_quests.encouragements.far + ) + + title_message = ( + lang.econ.daily_quests.completed if quest.done else lang.econ.daily_quests.current ) - async def get_random_quest(self, user_id: int) -> typing.TypedDict( + if quest.done: + description = lang.econ.daily_quests.rewarded.format( + reward_amount=quest.reward_amount, + reward_emoji=emojify_item(self.d, quest.reward_item), + ) + else: + description = "\n".join([ + lang.econ.daily_quests.progress.format( + progress=quest_text.progress.format( + value=quest.value, + target=quest.target_value, + encouragement=random.choice(encouragements), + ), + ), + lang.econ.daily_quests.reward.format( + reward_amount=quest.reward_amount, + reward_emoji=emojify_item(self.d, quest.reward_item), + ), + lang.econ.daily_quests.expires_at.format( + expires_at=discord.utils.format_dt( + quest.day.datetime + datetime.timedelta(days=1), + "R", + ), + ), + ]) + + embed = discord.Embed( + title=title_message.format( + quest_title=quest_text.title.format( + target=quest.target_value, + emoji=quest_emoji, + ), + ), + description=description, + color=self.bot.embed_color, + ) + + return embed + + async def get_random_quest_to_store(self, user_id: int) -> typing.TypedDict( "RandomQuest", { "key": str, @@ -69,7 +121,13 @@ async def get_random_quest(self, user_id: int) -> typing.TypedDict( variant_idx = random.randint(0, len(quest_def.targets) - 1) variant = quest_def.targets[variant_idx] - difficulty_multi = await self.fetch_calc_difficulty_multiplier(user_id, quest_def) + pickaxe = await self.db.fetch_pickaxe(user_id) + pickaxe_level = len(self.d.mining.pickaxes) - self.d.mining.pickaxes.index(pickaxe) + difficulty_multi = eval( + quest_def.difficulty_eval_multi, + {"pickaxe_level": pickaxe_level, "ceil": math.ceil}, + {}, + ) return { "key": quest_key, @@ -79,7 +137,7 @@ async def get_random_quest(self, user_id: int) -> typing.TypedDict( "difficulty_multi": difficulty_multi, } - async def send_quest_completed_notification( + async def quest_completed( self, loc: CustomContext | commands.Context | discord.User, quest: UserQuest ) -> None: user_id: int @@ -96,27 +154,7 @@ async def send_quest_completed_notification( assert quest.reward_item == "emerald" await self.db.balance_add(user_id, quest.reward_amount) - lang = self.bot.l["en"] - if isinstance(loc, CustomContext | commands.Context): - lang = loc.l - - quest_emoji: str = "" if quest.emoji is None else self.d.emojis[quest.emoji] - quest_text = lang.econ.daily_quests.mapping[quest.key] - - embed = discord.Embed( - title=lang.econ.daily_quests.completed.format( - quest_title=quest_text.title.format( - target=quest.target_value, - emoji=quest_emoji, - ), - ), - description=lang.econ.daily_quests.reward.format( - reward=quest.reward_amount, - emoji=self.d.emojis.emerald, - ), - color=self.bot.embed_color, - ) - + embed = self.get_quest_embed(loc, quest) await loc.send(embed=embed) def _get_user_quest_from_db_quest(self, db_quest: DbUserQuest) -> UserQuest: @@ -163,7 +201,7 @@ async def update_user_daily_quest( ) if target_met and not db_quest["done"]: - asyncio.create_task(self.send_quest_completed_notification(loc, quest)) + asyncio.create_task(self.quest_completed(loc, quest)) async def fetch_user_daily_quest(self, user_id: int) -> UserQuest: db_quest = await self.db.fetch_user_daily_quest(user_id) diff --git a/bot/data/text/en.json b/bot/data/text/en.json index fccf151f..28a6ed17 100644 --- a/bot/data/text/en.json +++ b/bot/data/text/en.json @@ -2169,7 +2169,7 @@ }, "completed": "Quest completed: {quest_title}!", "current": "Current daily quest: {quest_title}", - "rewarded": "You have been rewarded {reward}{emoji}", + "rewarded": "You have been rewarded {reward_amount}{reward_emoji}!", "progress": "**Progress:** {progress}", "reward": "**Reward:** {reward_amount}x {reward_emoji}", "expires_at": "**Expires:** {expires_at}",