Skip to content

Commit

Permalink
- Fix insight special action button (#453)
Browse files Browse the repository at this point in the history
- Pluralize multiple chest rewards
- Prevent negaverse from stealing certain equipment rarities
- Don't expose monster name in ephemeral responses on hard mode
- Defer action buttons before any hard calculations to reduce likelihood of unknown interaction errors Resolves #447
- Fix backpack equip when wielding a two handed weapon
  • Loading branch information
TrustyJAID authored Feb 26, 2024
1 parent 4823374 commit 7fbe3ac
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 35 deletions.
5 changes: 4 additions & 1 deletion adventure/adventure.py
Original file line number Diff line number Diff line change
Expand Up @@ -2665,7 +2665,10 @@ async def _reward(self, ctx: commands.Context, userlist, amount: int, modif: flo
word = "has" if len(userlist) == 1 else "have"
if special:
chest_str = special.get_ansi()
chest_type = box(_("{chest_str} treasure chest!").format(chest_str=chest_str), lang="ansi")
if len(special) > 1:
chest_type = box(_("{chest_str} treasure chests!").format(chest_str=chest_str), lang="ansi")
else:
chest_type = box(_("{chest_str} treasure chest!").format(chest_str=chest_str), lang="ansi")
phrase += _(
"\n{b_reward} {word} been awarded {xp} xp and found "
"{cp} {currency_name} (split based on stats). "
Expand Down
2 changes: 1 addition & 1 deletion adventure/backpack.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ async def backpack_equip(self, ctx: commands.Context, *, equip_item: EquipableIt
author=escape(ctx.author.display_name),
item=str(equip),
slot=slot,
put=getattr(c, equip.slot.name),
put=getattr(c, equip.slot.char_slot),
),
lang="ansi",
)
Expand Down
14 changes: 10 additions & 4 deletions adventure/charsheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import time
from copy import copy
from datetime import date, datetime
from typing import Any, Dict, List, MutableMapping, Optional, Tuple, Union
from typing import Any, Dict, List, MutableMapping, Optional, Set, Tuple, Union

import discord
from beautifultable import ALIGN_LEFT, BeautifulTable
Expand Down Expand Up @@ -728,10 +728,16 @@ def _sort(item):
final.append(sorted(tmp[slot_name], key=_sort))
return final

async def looted(self, how_many: int = 1, exclude: set = None) -> List[Tuple[str, int]]:
if exclude is None:
async def looted(self, how_many: int = 1, exclude: Set[Union[str, Rarities]] = set()) -> List[Tuple[str, int]]:
if not exclude:
exclude = {Rarities.normal, Rarities.rare, Rarities.epic, Rarities.forged}
exclude.add("forged")
else:
for rarity in exclude:
if isinstance(rarity, Rarities):
exclude.add(rarity)
else:
exclude.add(Rarities.get_from_name(rarity))
exclude.add(Rarities.forged)
items = [i for n, i in self.backpack.items() if i.rarity not in exclude]
looted_so_far = 0
looted = []
Expand Down
74 changes: 46 additions & 28 deletions adventure/game_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,17 @@ async def send_response(self, interaction: discord.Interaction):

choice = random.choice(choices[heroclass] + choices["hero"])
choice = choice.replace("$pet", pet)
choice = choice.replace("$monster", self.view.challenge)
choice = choice.replace("$monster", self.view.challenge_name())
weapon = c.get_weapons()
choice = choice.replace("$weapon", weapon)
god = await self.view.cog.config.god_name()
if await self.view.cog.config.guild(interaction.guild).god_name():
god = await self.view.cog.config.guild(interaction.guild).god_name()
choice = choice.replace("$god", god)
await interaction.response.send_message(box(choice, lang="ansi"), ephemeral=True)
await smart_embed(message=box(choice, lang="ansi"), ephemeral=True, interaction=interaction)

async def callback(self, interaction: discord.Interaction):
"""Skip to previous track"""
await interaction.response.defer()
user = interaction.user
for x in ["magic", "talk", "pray", "run"]:
if user in getattr(self.view, x, []):
Expand All @@ -70,7 +70,7 @@ async def callback(self, interaction: discord.Interaction):
await self.send_response(interaction)
await self.view.update()
else:
await interaction.response.send_message("You are already fighting this monster.", ephemeral=True)
await smart_embed(message="You are already fighting this monster.", ephemeral=True, interaction=interaction)


class MagicButton(discord.ui.Button):
Expand Down Expand Up @@ -100,17 +100,17 @@ async def send_response(self, interaction: discord.Interaction):

choice = random.choice(choices[heroclass] + choices["hero"])
choice = choice.replace("$pet", pet)
choice = choice.replace("$monster", self.view.challenge)
choice = choice.replace("$monster", self.view.challenge_name())
weapon = c.get_weapons()
choice = choice.replace("$weapon", weapon)
god = await self.view.cog.config.god_name()
if await self.view.cog.config.guild(interaction.guild).god_name():
god = await self.view.cog.config.guild(interaction.guild).god_name()
choice = choice.replace("$god", god)
await interaction.response.send_message(box(choice, lang="ansi"), ephemeral=True)
await smart_embed(message=box(choice, lang="ansi"), ephemeral=True, interaction=interaction)

async def callback(self, interaction: discord.Interaction):
"""Skip to previous track"""
await interaction.response.defer()
user = interaction.user
for x in ["fight", "talk", "pray", "run"]:
if user in getattr(self.view, x, []):
Expand All @@ -120,7 +120,9 @@ async def callback(self, interaction: discord.Interaction):
await self.send_response(interaction)
await self.view.update()
else:
await interaction.response.send_message("You have already cast a spell at this monster.", ephemeral=True)
await smart_embed(
message="You have already cast a spell at this monster.", ephemeral=True, interaction=interaction
)


class TalkButton(discord.ui.Button):
Expand Down Expand Up @@ -150,17 +152,17 @@ async def send_response(self, interaction: discord.Interaction):

choice = random.choice(choices[heroclass] + choices["hero"])
choice = choice.replace("$pet", pet)
choice = choice.replace("$monster", self.view.challenge)
choice = choice.replace("$monster", self.view.challenge_name())
weapon = c.get_weapons()
choice = choice.replace("$weapon", weapon)
god = await self.view.cog.config.god_name()
if await self.view.cog.config.guild(interaction.guild).god_name():
god = await self.view.cog.config.guild(interaction.guild).god_name()
choice = choice.replace("$god", god)
await interaction.response.send_message(box(choice, lang="ansi"), ephemeral=True)
await smart_embed(message=box(choice, lang="ansi"), ephemeral=True, interaction=interaction)

async def callback(self, interaction: discord.Interaction):
"""Skip to previous track"""
await interaction.response.defer()
user = interaction.user
for x in ["fight", "magic", "pray", "run"]:
if user in getattr(self.view, x, []):
Expand All @@ -170,7 +172,9 @@ async def callback(self, interaction: discord.Interaction):
await self.send_response(interaction)
await self.view.update()
else:
await interaction.response.send_message("You are already talking to this monster.", ephemeral=True)
await smart_embed(
message="You are already talking to this monster.", ephemeral=True, interaction=interaction
)


class PrayButton(discord.ui.Button):
Expand Down Expand Up @@ -200,17 +204,17 @@ async def send_response(self, interaction: discord.Interaction):

choice = random.choice(choices[heroclass] + choices["hero"])
choice = choice.replace("$pet", pet)
choice = choice.replace("$monster", self.view.challenge)
choice = choice.replace("$monster", self.view.challenge_name())
weapon = c.get_weapons()
choice = choice.replace("$weapon", weapon)
god = await self.view.cog.config.god_name()
if await self.view.cog.config.guild(interaction.guild).god_name():
god = await self.view.cog.config.guild(interaction.guild).god_name()
choice = choice.replace("$god", god)
await interaction.response.send_message(box(choice, lang="ansi"), ephemeral=True)
await smart_embed(message=box(choice, lang="ansi"), ephemeral=True, interaction=interaction)

async def callback(self, interaction: discord.Interaction):
"""Skip to previous track"""
await interaction.response.defer()
user = interaction.user
for x in ["fight", "magic", "talk", "run"]:
if user in getattr(self.view, x, []):
Expand All @@ -220,8 +224,10 @@ async def callback(self, interaction: discord.Interaction):
await self.send_response(interaction)
await self.view.update()
else:
await interaction.response.send_message(
"You are already praying for help against this monster.", ephemeral=True
await smart_embed(
message="You are already praying for help against this monster.",
ephemeral=True,
interaction=interaction,
)


Expand Down Expand Up @@ -252,14 +258,14 @@ async def send_response(self, interaction: discord.Interaction):

choice = random.choice(choices[heroclass] + choices["hero"])
choice = choice.replace("$pet", pet)
choice = choice.replace("$monster", self.view.challenge)
choice = choice.replace("$monster", self.view.challenge_name())
weapon = c.get_weapons()
choice = choice.replace("$weapon", weapon)
god = await self.view.cog.config.god_name()
if await self.view.cog.config.guild(interaction.guild).god_name():
god = await self.view.cog.config.guild(interaction.guild).god_name()
choice = choice.replace("$god", god)
await interaction.response.send_message(box(choice, lang="ansi"), ephemeral=True)
await smart_embed(message=box(choice, lang="ansi"), ephemeral=True, interaction=interaction)

async def callback(self, interaction: discord.Interaction):
"""Skip to previous track"""
Expand All @@ -272,7 +278,9 @@ async def callback(self, interaction: discord.Interaction):
await self.send_response(interaction)
await self.view.update()
else:
await interaction.response.send_message("You have already run from this monster.", ephemeral=True)
await smart_embed(
message="You have already run from this monster.", ephemeral=True, interaction=interaction
)


class SpecialActionButton(discord.ui.Button):
Expand All @@ -288,7 +296,7 @@ def __init__(
self.label_name = "Special Action"

async def send_cooldown(self, interaction: discord.Interaction, c: Character, cooldown_time: int):
cooldown_time = int((c.heroclass["cooldown"]) + cooldown_time)
cooldown_time = int(c.heroclass["cooldown"])
msg = _(
"Your hero is currently recovering from the last time "
"they used this skill or they have just changed their heroclass. "
Expand Down Expand Up @@ -324,6 +332,7 @@ async def send_cleric(self, interaction: discord.Interaction, c: Character):
async def send_insight(self, interaction: discord.Interaction, c: Character):
user = interaction.user
if c.heroclass["ability"]:
log.debug("Psychic in use already")
await self.send_in_use(interaction)
return
cooldown_time = max(300, (900 - max((c.luck + c.total_cha) * 2, 0)))
Expand All @@ -339,8 +348,8 @@ async def send_insight(self, interaction: discord.Interaction, c: Character):
good = False
msg = _("Another hero has already done a better job than you.")
await smart_embed(
interaction,
_("Another hero has already done a better job than you."),
message=msg,
interaction=interaction,
ephemeral=True,
cog=self.view.cog,
)
Expand All @@ -357,7 +366,7 @@ async def send_insight(self, interaction: discord.Interaction, c: Character):
if good:
session = self.view
if roll <= 0.4:
return await smart_embed(interaction, _("You suck."), cog=self.view.cog)
return await smart_embed(interaction=interaction, message=_("You suck."), cog=self.view.cog)
msg = ""
if session.no_monster:
if roll >= 0.4:
Expand Down Expand Up @@ -475,8 +484,8 @@ async def send_insight(self, interaction: discord.Interaction, c: Character):
cog=self.view.cog,
interaction=interaction,
)
else:
await self.send_cooldown(interaction, c, cooldown_time)
else:
await self.send_cooldown(interaction, c, cooldown_time)

async def send_rage(self, interaction: discord.Interaction, c: Character):
user = interaction.user
Expand Down Expand Up @@ -558,7 +567,7 @@ async def not_in_adventure(self, interaction: discord.Interaction):
return

async def callback(self, interaction: discord.Interaction):
"""Skip to previous track"""
await interaction.response.defer()
user = interaction.user
if not self.view.in_adventure(user):
await self.not_in_adventure(interaction)
Expand All @@ -568,7 +577,9 @@ async def callback(self, interaction: discord.Interaction):
c = await Character.from_json(self.view.ctx, self.view.cog.config, user, self.view.cog._daily_bonus)
except Exception as exc:
log.exception("Error with the new character sheet", exc_info=exc)
await interaction.response.send_message(_("There was an error loading your character."), ephemeral=True)
await smart_embed(
message=_("There was an error loading your character."), ephemeral=True, interaction=interaction
)
return
if not c.hc.has_action:
available_classes = humanize_list([c.class_name for c in HeroClasses if c.has_action], style="or")
Expand All @@ -580,6 +591,7 @@ async def callback(self, interaction: discord.Interaction):
if c.hc is HeroClasses.cleric:
await self.send_cleric(interaction, c)
if c.hc is HeroClasses.psychic:
log.debug("Psychic used special action")
await self.send_insight(interaction, c)
if c.hc is HeroClasses.berserker:
await self.send_rage(interaction, c)
Expand Down Expand Up @@ -643,6 +655,7 @@ def __init__(self, **kwargs):
self.pray: List[discord.Member] = []
self.run: List[discord.Member] = []
self.transcended: bool = kwargs.pop("transcended", False)
self.insight: Tuple[float, Character] = (0, None)
self.start_time = datetime.now()
self.easy_mode = kwargs.get("easy_mode", False)
self.no_monster = kwargs.get("no_monster", False)
Expand Down Expand Up @@ -682,6 +695,11 @@ def in_adventure(self, user: discord.Member) -> bool:
)
return bool(user.id in participants_ids)

def challenge_name(self):
if self.easy_mode:
return self.challenge
return _("Unknown creature")

async def interaction_check(self, interaction: discord.Interaction):
"""Just extends the default reaction_check to use owner_ids"""
if interaction.guild is not None:
Expand Down
2 changes: 1 addition & 1 deletion adventure/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ async def smart_embed(


def check_running_adventure(ctx):
for (guild_id, session) in ctx.bot.get_cog("Adventure")._sessions.items():
for guild_id, session in ctx.bot.get_cog("Adventure")._sessions.items():
user_ids: list = []
options = ["fight", "magic", "talk", "pray", "run"]
for i in options:
Expand Down

0 comments on commit 7fbe3ac

Please sign in to comment.