246 lines
9.6 KiB
Python
246 lines
9.6 KiB
Python
import logging
|
|
import discord
|
|
from typing import Coroutine, Literal
|
|
|
|
from dice import ab_roll, jump_roll
|
|
from in_game.gameplay_models import Game, Play, Team
|
|
|
|
|
|
logger = logging.getLogger('discord_app')
|
|
|
|
class Confirm(discord.ui.View):
|
|
def __init__(self, responders: list, timeout: float = 300.0, label_type: Literal['yes', 'confirm'] = 'confirm'):
|
|
super().__init__(timeout=timeout)
|
|
if not isinstance(responders, list):
|
|
raise TypeError('responders must be a list')
|
|
self.value = None
|
|
self.responders = responders
|
|
if label_type == 'yes':
|
|
self.confirm.label = 'Yes'
|
|
self.cancel.label = 'No'
|
|
|
|
# When the confirm button is pressed, set the inner value to `True` and
|
|
# stop the View from listening to more input.
|
|
# We also send the user an ephemeral message that we're confirming their choice.
|
|
@discord.ui.button(label='Confirm', style=discord.ButtonStyle.green)
|
|
async def confirm(self, interaction: discord.Interaction, button: discord.ui.Button):
|
|
if interaction.user not in self.responders:
|
|
await interaction.response.send_message(
|
|
content='Get out of here',
|
|
ephemeral=True,
|
|
delete_after=10.0
|
|
)
|
|
|
|
self.value = True
|
|
self.clear_items()
|
|
self.stop()
|
|
|
|
# This one is similar to the confirmation button except sets the inner value to `False`
|
|
@discord.ui.button(label='Cancel', style=discord.ButtonStyle.grey)
|
|
async def cancel(self, interaction: discord.Interaction, button: discord.ui.Button):
|
|
if interaction.user not in self.responders:
|
|
await interaction.response.send_message(
|
|
content='Get out of here',
|
|
ephemeral=True,
|
|
delete_after=10.0
|
|
)
|
|
|
|
self.value = False
|
|
self.clear_items()
|
|
self.stop()
|
|
|
|
|
|
class ButtonOptions(discord.ui.View):
|
|
def __init__(self, responders: list, timeout: float = 300.0, labels=None):
|
|
super().__init__(timeout=timeout)
|
|
if not isinstance(responders, list):
|
|
raise TypeError('responders must be a list')
|
|
self.value = None
|
|
self.responders = responders
|
|
self.options = labels
|
|
for count, x in enumerate(labels):
|
|
if count == 0:
|
|
self.option1.label = x
|
|
if x is None or x.lower() == 'na' or x == 'N/A':
|
|
self.remove_item(self.option1)
|
|
if count == 1:
|
|
self.option2.label = x
|
|
if x is None or x.lower() == 'na' or x == 'N/A':
|
|
self.remove_item(self.option2)
|
|
if count == 2:
|
|
self.option3.label = x
|
|
if x is None or x.lower() == 'na' or x == 'N/A':
|
|
self.remove_item(self.option3)
|
|
if count == 3:
|
|
self.option4.label = x
|
|
if x is None or x.lower() == 'na' or x == 'N/A':
|
|
self.remove_item(self.option4)
|
|
if count == 4:
|
|
self.option5.label = x
|
|
if x is None or x.lower() == 'na' or x == 'N/A':
|
|
self.remove_item(self.option5)
|
|
|
|
@discord.ui.button(label='Option 1', style=discord.ButtonStyle.primary)
|
|
async def option1(self, interaction: discord.Interaction, button: discord.ui.Button):
|
|
if interaction.user not in self.responders:
|
|
await interaction.response.send_message(
|
|
content='Get out of here',
|
|
ephemeral=True,
|
|
delete_after=10.0
|
|
)
|
|
|
|
self.value = self.options[0]
|
|
self.clear_items()
|
|
self.stop()
|
|
|
|
@discord.ui.button(label='Option 2', style=discord.ButtonStyle.primary)
|
|
async def option2(self, interaction: discord.Interaction, button: discord.ui.Button):
|
|
if interaction.user not in self.responders:
|
|
await interaction.response.send_message(
|
|
content='Get out of here',
|
|
ephemeral=True,
|
|
delete_after=10.0
|
|
)
|
|
|
|
self.value = self.options[1]
|
|
self.clear_items()
|
|
self.stop()
|
|
|
|
@discord.ui.button(label='Option 3', style=discord.ButtonStyle.primary)
|
|
async def option3(self, interaction: discord.Interaction, button: discord.ui.Button):
|
|
if interaction.user not in self.responders:
|
|
await interaction.response.send_message(
|
|
content='Get out of here',
|
|
ephemeral=True,
|
|
delete_after=10.0
|
|
)
|
|
|
|
self.value = self.options[2]
|
|
self.clear_items()
|
|
self.stop()
|
|
|
|
@discord.ui.button(label='Option 4', style=discord.ButtonStyle.primary)
|
|
async def option4(self, interaction: discord.Interaction, button: discord.ui.Button):
|
|
if interaction.user not in self.responders:
|
|
await interaction.response.send_message(
|
|
content='Get out of here',
|
|
ephemeral=True,
|
|
delete_after=10.0
|
|
)
|
|
|
|
self.value = self.options[3]
|
|
self.clear_items()
|
|
self.stop()
|
|
|
|
@discord.ui.button(label='Option 5', style=discord.ButtonStyle.primary)
|
|
async def option5(self, interaction: discord.Interaction, button: discord.ui.Button):
|
|
if interaction.user not in self.responders:
|
|
await interaction.response.send_message(
|
|
content='Get out of here',
|
|
ephemeral=True,
|
|
delete_after=10.0
|
|
)
|
|
|
|
self.value = self.options[4]
|
|
self.clear_items()
|
|
self.stop()
|
|
|
|
|
|
async def ask_confirm(interaction: discord.Interaction, question: str, label_type: Literal['yes', 'confirm'] = 'confirm', timeout: int = 60, delete_question: bool = True, custom_confirm_label: str = None, custom_cancel_label: str = None, embed: discord.Embed = None, delete_embed: bool = False) -> bool:
|
|
"""
|
|
button_callbacks: keys are button values, values are async functions
|
|
"""
|
|
try:
|
|
view = Confirm(responders=[interaction.user], timeout=timeout, label_type=label_type)
|
|
except AttributeError:
|
|
view = Confirm(responders=[interaction.author], timeout=timeout, label_type=label_type)
|
|
if custom_confirm_label:
|
|
view.confirm.label = custom_confirm_label
|
|
if custom_cancel_label:
|
|
view.cancel.label = custom_cancel_label
|
|
|
|
q_message = await interaction.channel.send(question, view=view)
|
|
await view.wait()
|
|
|
|
if view.value:
|
|
if delete_question:
|
|
await q_message.delete()
|
|
else:
|
|
await q_message.edit(content=question, view=None)
|
|
return True
|
|
|
|
else:
|
|
if delete_question:
|
|
await q_message.delete()
|
|
else:
|
|
await q_message.edit(content=question, view=None)
|
|
return False
|
|
|
|
|
|
class ScorebugButtons(discord.ui.View):
|
|
def __init__(self, play: Play, embed: discord.Embed, timeout: float = 30):
|
|
super().__init__(timeout=timeout)
|
|
self.value = None
|
|
self.batting_team = play.batter.team
|
|
self.pitching_team = play.pitcher.team
|
|
self.pitcher_card_url = play.pitcher.player.pitcher_card_url
|
|
self.batter_card_url = play.batter.player.batter_card_url
|
|
self.team = play.batter.team
|
|
self.play = play
|
|
self.had_chaos = False
|
|
self.embed = embed
|
|
|
|
if play.on_base_code == 0:
|
|
self.remove_item(self.button_jump)
|
|
|
|
async def interaction_check(self, interaction: discord.Interaction[discord.Client]) -> bool:
|
|
logger.info(f'user id: {interaction.user.id} / batting_team: {self.batting_team}')
|
|
if interaction.user.id == self.batting_team.gmid:
|
|
logger.info(f'User {interaction.user.id} rolling in Game {self.play.game.id}')
|
|
return True
|
|
elif self.batting_team.is_ai and interaction.user.id == self.pitching_team.gmid:
|
|
logger.info(f'User {interaction.user.id} rolling for AI in Game {self.play.game.id}')
|
|
return True
|
|
|
|
logger.info(f'User {interaction.user.id} rejected in Game {self.play.game.id}')
|
|
await interaction.response.send_message(
|
|
content='Get out of here',
|
|
ephemeral=True,
|
|
delete_after=5.0
|
|
)
|
|
return False
|
|
|
|
# async def on_timeout(self) -> Coroutine[Any, Any, None]:
|
|
# await self.interaction
|
|
|
|
@discord.ui.button(label='Roll AB', style=discord.ButtonStyle.primary)
|
|
async def button_ab(self, interaction: discord.Interaction, button: discord.ui.Button):
|
|
logger.info(f'User {interaction.user.id} rolling AB in Game {self.play.game.id}')
|
|
|
|
this_roll = ab_roll(self.team, self.play.game, allow_chaos=not self.had_chaos)
|
|
if this_roll.is_chaos:
|
|
self.had_chaos = True
|
|
else:
|
|
button.disabled = True
|
|
|
|
await interaction.channel.send(content=None, embeds=this_roll.embeds)
|
|
|
|
if this_roll.d_six_one > 3:
|
|
logger.info(f'ScorebugButton - updating embed card to pitcher')
|
|
self.embed.set_image(url=self.pitcher_card_url)
|
|
logger.debug(f'embed image url: {self.embed.image}')
|
|
|
|
logger.debug(f'new embed: {self.embed}')
|
|
await interaction.response.edit_message(view=self, embed=self.embed)
|
|
|
|
@discord.ui.button(label='Check Jump', style=discord.ButtonStyle.secondary)
|
|
async def button_jump(self, interaction: discord.Interaction, button: discord.ui.Button):
|
|
logger.info(f'User {interaction.user.id} rolling jump in Game {self.play.game.id}')
|
|
|
|
this_roll = jump_roll(self.team, self.play.game)
|
|
button.disabled = True
|
|
|
|
await interaction.channel.send(content=None, embeds=this_roll.embeds)
|
|
await interaction.response.edit_message(view=self)
|
|
|