Added AbRoll and JumpRoll
Added auto_roll and roll_buttons to Game Added log chaos
This commit is contained in:
parent
baffabfe4c
commit
f7685ff0e3
@ -8,7 +8,8 @@ from discord.ext import commands, tasks
|
||||
import pygsheets
|
||||
|
||||
from api_calls import db_get
|
||||
from command_logic.logic_gameplay import advance_runners, bunts, complete_game, doubles, flyballs, get_lineups_from_sheets, checks_log_interaction, complete_play, hit_by_pitch, homeruns, is_game_over, popouts, show_defense_cards, singles, strikeouts, triples, undo_play, walks
|
||||
from command_logic.logic_gameplay import advance_runners, bunts, chaos, complete_game, doubles, flyballs, get_lineups_from_sheets, checks_log_interaction, complete_play, get_scorebug_embed, hit_by_pitch, homeruns, is_game_over, popouts, show_defense_cards, singles, strikeouts, triples, undo_play, update_game_settings, walks
|
||||
from dice import ab_roll
|
||||
from exceptions import GameNotFoundException, TeamNotFoundException, PlayNotFoundException, GameException, log_exception
|
||||
from helpers import DEFENSE_LITERAL, PD_PLAYERS_ROLE_NAME, get_channel, team_role, user_has_role, random_gif, random_from_list
|
||||
|
||||
@ -18,7 +19,7 @@ from in_game.game_helpers import PUBLIC_FIELDS_CATEGORY_NAME, legal_check
|
||||
from in_game.gameplay_models import Lineup, Play, Session, engine, player_description, select, Game
|
||||
from in_game.gameplay_queries import get_and_cache_position, get_channel_game_or_none, get_active_games_by_team, get_game_lineups, get_team_or_none, get_card_or_none
|
||||
|
||||
from utilities.buttons import Confirm, ask_confirm
|
||||
from utilities.buttons import Confirm, ScorebugButtons, ask_confirm
|
||||
|
||||
|
||||
CLASSIC_EMBED = True
|
||||
@ -51,7 +52,9 @@ class Gameplay(commands.Cog):
|
||||
await ctx.send(f'{error[:1600]}')
|
||||
|
||||
async def post_play(self, session: Session, interaction: discord.Interaction, this_play: Play, buffer_message: str = None):
|
||||
logger.info(f'post_play - Posting new play')
|
||||
if is_game_over(this_play):
|
||||
logger.info(f'Game {this_play.game.id} seems to be over')
|
||||
await interaction.edit_original_response(content=f'Looks like this one is over!')
|
||||
submit_game = await ask_confirm(
|
||||
interaction=interaction,
|
||||
@ -61,6 +64,7 @@ class Gameplay(commands.Cog):
|
||||
)
|
||||
|
||||
if submit_game:
|
||||
logger.info(f'post_play - is_game_over - {interaction.user.display_name} rejected game completion')
|
||||
await complete_game(session, interaction, this_play)
|
||||
return
|
||||
else:
|
||||
@ -74,22 +78,45 @@ class Gameplay(commands.Cog):
|
||||
await self.post_play(session, interaction, this_play)
|
||||
await interaction.channel.send(content=f'I let Cal know his bot is stupid')
|
||||
|
||||
elif buffer_message is not None:
|
||||
scorebug_buttons, this_ab_roll = None, None
|
||||
|
||||
if this_play.game.roll_buttons and interaction.user.id in [this_play.game.away_team.gmid, this_play.game.home_team.gmid]:
|
||||
scorebug_buttons = ScorebugButtons(this_play)
|
||||
|
||||
if this_play.on_base_code == 0 and this_play.game.auto_roll and not this_play.batter.team.is_ai:
|
||||
this_ab_roll = ab_roll(this_play.batter.team, this_play.game, allow_chaos=False)
|
||||
scorebug_buttons = None
|
||||
|
||||
scorebug_embed = await get_scorebug_embed(session, this_play.game, full_length=False, classic=CLASSIC_EMBED)
|
||||
if this_ab_roll is not None and this_ab_roll.d_six_one > 3:
|
||||
scorebug_embed.set_image(url=this_play.pitcher.player.pitcher_card_url)
|
||||
|
||||
if buffer_message is not None:
|
||||
await interaction.edit_original_response(
|
||||
content=buffer_message
|
||||
)
|
||||
await interaction.channel.send(
|
||||
content=None,
|
||||
embed=this_play.game.get_scorebug_embed(session, full_length=False, classic=CLASSIC_EMBED)
|
||||
embed=scorebug_embed,
|
||||
view=scorebug_buttons
|
||||
)
|
||||
else:
|
||||
await interaction.edit_original_response(
|
||||
content=None,
|
||||
embed=this_play.game.get_scorebug_embed(session, full_length=False, classic=CLASSIC_EMBED)
|
||||
embed=scorebug_embed,
|
||||
view=scorebug_buttons
|
||||
)
|
||||
|
||||
if this_ab_roll is not None:
|
||||
await interaction.channel.send(
|
||||
content=None,
|
||||
embeds=this_ab_roll.embeds
|
||||
)
|
||||
|
||||
async def complete_and_post_play(self, session: Session, interaction: discord.Interaction, this_play: Play, buffer_message: str = None):
|
||||
next_play = complete_play(session, this_play)
|
||||
logger.info(f'Completed play {this_play.id}')
|
||||
|
||||
await self.post_play(session, interaction, next_play, buffer_message)
|
||||
|
||||
group_new_game = app_commands.Group(name='new-game', description='Start a new baseball game')
|
||||
@ -272,7 +299,8 @@ class Gameplay(commands.Cog):
|
||||
away_role = await team_role(interaction, away_team)
|
||||
home_role = await team_role(interaction, home_team)
|
||||
|
||||
embed = this_game.get_scorebug_embed(session).clear_fields()
|
||||
embed = await get_scorebug_embed(session, this_game)
|
||||
embed.clear_fields()
|
||||
embed.add_field(
|
||||
name=f'{ai_team.abbrev} Lineup',
|
||||
value=this_game.team_lineup(session, ai_team)
|
||||
@ -296,7 +324,7 @@ class Gameplay(commands.Cog):
|
||||
try:
|
||||
await ctx.send(
|
||||
content=None,
|
||||
embed=this_game.get_scorebug_embed(session, full_length=True)
|
||||
embed=await get_scorebug_embed(session, this_game, full_length=True)
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f'Unable to display scorebug while forcing game to end: {e}')
|
||||
@ -385,7 +413,8 @@ class Gameplay(commands.Cog):
|
||||
if batter.position != 'DH':
|
||||
await get_and_cache_position(session, batter.card, batter.position)
|
||||
|
||||
await interaction.edit_original_response(content=None, embed=this_game.get_scorebug_embed(session))
|
||||
this_play = this_game.initialize_play(session)
|
||||
await self.post_play(session, interaction, this_play)
|
||||
|
||||
@app_commands.command(name='gamestate', description='Post the current game state')
|
||||
async def gamestate_command(self, interaction: discord.Interaction, include_lineups: bool = False):
|
||||
@ -399,10 +428,25 @@ class Gameplay(commands.Cog):
|
||||
)
|
||||
return
|
||||
|
||||
await interaction.edit_original_response(
|
||||
content=None,
|
||||
embed=this_game.get_scorebug_embed(session, full_length=include_lineups)
|
||||
this_play = this_game.current_play_or_none(session)
|
||||
await self.post_play(session, interaction, this_play)
|
||||
|
||||
@app_commands.command(name='settings-ingame', description='Change in-game settings')
|
||||
@app_commands.describe(
|
||||
roll_buttons='Display the "Roll AB" and "Check Jump" buttons along with the scorebug',
|
||||
auto_roll='When there are no baserunners, automatically roll the next AB'
|
||||
)
|
||||
async def game_settings_command(self, interaction: discord.Interaction, roll_buttons: bool = None, auto_roll: bool = None):
|
||||
with Session(engine) as session:
|
||||
this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='settings-ingame')
|
||||
|
||||
await interaction.edit_original_response(content=None, embed=await update_game_settings(
|
||||
session,
|
||||
interaction,
|
||||
this_game,
|
||||
roll_buttons=roll_buttons,
|
||||
auto_roll=auto_roll
|
||||
))
|
||||
|
||||
group_log = app_commands.Group(name='log', description='Log a play in this channel\'s game')
|
||||
|
||||
@ -427,10 +471,10 @@ class Gameplay(commands.Cog):
|
||||
with Session(engine) as session:
|
||||
this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log single')
|
||||
|
||||
logger.info(f'log single {single_type} - this_play: {this_play}')
|
||||
this_play = await singles(session, interaction, this_play, single_type)
|
||||
logger.info(f'log single {single_type} - this_play: {this_play}')
|
||||
|
||||
await self.complete_and_post_play(session, interaction, this_play, buffer_message='Double logged' if ((this_play.on_first or this_play.on_second) and single_type == 'uncapped') else None)
|
||||
await self.complete_and_post_play(session, interaction, this_play, buffer_message='Single logged' if ((this_play.on_first or this_play.on_second) and single_type == 'uncapped') else None)
|
||||
|
||||
# complete_play(session, this_play)
|
||||
|
||||
@ -438,12 +482,12 @@ class Gameplay(commands.Cog):
|
||||
# await interaction.edit_original_response(content='Single logged')
|
||||
# await interaction.channel.send(
|
||||
# content=None,
|
||||
# embed=this_play.game.get_scorebug_embed(session, full_length=False, classic=CLASSIC_EMBED)
|
||||
# embed=await get_scorebug_embed(session, this_play.game, full_length=False, classic=CLASSIC_EMBED)
|
||||
# )
|
||||
# else:
|
||||
# await interaction.edit_original_response(
|
||||
# content=None,
|
||||
# embed=this_play.game.get_scorebug_embed(session, full_length=False, classic=CLASSIC_EMBED)
|
||||
# embed=await get_scorebug_embed(session, this_play.game, full_length=False, classic=CLASSIC_EMBED)
|
||||
# )
|
||||
|
||||
@group_log.command(name='double', description='Doubles: **, ***, uncapped')
|
||||
@ -516,6 +560,23 @@ class Gameplay(commands.Cog):
|
||||
|
||||
await self.complete_and_post_play(session, interaction, this_play)
|
||||
|
||||
@group_log.command(name='chaos', description='Chaos: wild-pitch, passed-ball, balk, pickoff')
|
||||
async def log_chaos(self, interaction: discord.Interaction, chaos_type: Literal['wild-pitch', 'passed-ball', 'balk', 'pickoff']):
|
||||
with Session(engine) as session:
|
||||
this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log hit-by-pitch')
|
||||
|
||||
if this_play.on_base_code == 0:
|
||||
await interaction.edit_original_response(
|
||||
content=f'There cannot be chaos when the bases are empty.'
|
||||
)
|
||||
return
|
||||
|
||||
logger.info(f'log chaos - this_play: {this_play}')
|
||||
this_play = await chaos(session, interaction, this_play, chaos_type)
|
||||
|
||||
await self.complete_and_post_play(session, interaction, this_play)
|
||||
|
||||
|
||||
@group_log.command(name='bunt', description='Bunts: sacrifice, bad, popout, double-play, defense')
|
||||
async def log_sac_bunt(self, interaction: discord.Interaction, bunt_type: Literal['sacrifice', 'bad', 'popout', 'double-play', 'defense']):
|
||||
with Session(engine) as session:
|
||||
@ -548,6 +609,7 @@ class Gameplay(commands.Cog):
|
||||
await self.post_play(session, interaction, this_play)
|
||||
|
||||
group_show = app_commands.Group(name='show-card', description='Display the player card for an active player')
|
||||
|
||||
@group_show.command(name='defense', description='Display a defender\'s player card')
|
||||
async def show_defense_command(self, interaction: discord.Interaction, position: DEFENSE_LITERAL):
|
||||
with Session(engine) as session:
|
||||
|
||||
@ -107,11 +107,14 @@ class Owner(commands.Cog):
|
||||
elif spec == '!':
|
||||
fmt = await ctx.bot.tree.sync()
|
||||
await ctx.send(f'Synced {len(fmt)} commands globally.')
|
||||
ctx.bot.tree.clear_commands(guild=ctx.guild)
|
||||
await ctx.send(f'Cleared all local commands.')
|
||||
|
||||
if len(fmt) > 0:
|
||||
ctx.bot.tree.copy_global_to(guild=ctx.guild)
|
||||
fmt = await ctx.bot.tree.sync(guild=ctx.guild)
|
||||
await ctx.send(f'Synced global commands to this guild.')
|
||||
|
||||
ctx.bot.tree.clear_commands(guild=ctx.guild)
|
||||
await ctx.send(f'Cleared all local commands.')
|
||||
else:
|
||||
fmt = await ctx.bot.tree.sync()
|
||||
|
||||
|
||||
@ -9,9 +9,9 @@ from typing import Literal
|
||||
|
||||
from api_calls import db_delete, db_get, db_post
|
||||
from exceptions import *
|
||||
from helpers import DEFENSE_LITERAL, get_channel
|
||||
from helpers import DEFENSE_LITERAL, SBA_COLOR, get_channel
|
||||
from in_game.game_helpers import legal_check
|
||||
from in_game.gameplay_models import Game, Lineup, Team, Play
|
||||
from in_game.gameplay_models import BattingCard, Game, Lineup, PositionRating, Team, Play
|
||||
from in_game.gameplay_queries import get_and_cache_position, get_card_or_none, get_channel_game_or_none, get_db_ready_decisions, get_db_ready_plays, get_last_team_play, get_one_lineup, get_player_id_from_dict, get_player_name_from_dict, get_player_or_none, get_sorted_lineups, get_team_or_none, get_players_last_pa, post_game_rewards
|
||||
from utilities.buttons import ButtonOptions, Confirm, ask_confirm
|
||||
from utilities.dropdown import DropdownOptions, DropdownView, SelectViewDefense
|
||||
@ -33,6 +33,196 @@ AT_BASE = {
|
||||
}
|
||||
|
||||
|
||||
async def get_scorebug_embed(session: Session, this_game: Game, full_length: bool = True, classic: bool = True) -> discord.Embed:
|
||||
gt_string = ' - Unlimited'
|
||||
if this_game.game_type == 'minor-league':
|
||||
gt_string = ' - Minor League'
|
||||
elif this_game.game_type == 'major-league':
|
||||
gt_string = ' - Major League'
|
||||
elif this_game.game_type == 'hall-of-fame':
|
||||
gt_string = ' - Hall of Fame'
|
||||
elif 'gauntlet' in this_game.game_type:
|
||||
gt_string = ' - Gauntlet'
|
||||
elif 'flashback' in this_game.game_type:
|
||||
gt_string = ' - Flashback'
|
||||
elif 'exhibition' in this_game.game_type:
|
||||
gt_string = ' - Exhibition'
|
||||
logger.info(f'gameplay_models - Game.get_scorebug_embed - this_game: {this_game} / gt_string: {gt_string}')
|
||||
|
||||
embed = discord.Embed(
|
||||
title=f'{this_game.away_team.sname} @ {this_game.home_team.sname}{gt_string}',
|
||||
color=int(SBA_COLOR, 16)
|
||||
)
|
||||
|
||||
curr_play = this_game.current_play_or_none(session)
|
||||
|
||||
if curr_play is None:
|
||||
try:
|
||||
curr_play = this_game.initialize_play(session)
|
||||
except LineupsMissingException as e:
|
||||
logger.debug(f'gameplay_models - Game.get_scorebug_embed - Could not initialize play')
|
||||
|
||||
if curr_play is not None:
|
||||
embed.add_field(
|
||||
name='Game State',
|
||||
value=curr_play.scorebug_ascii,
|
||||
inline=False
|
||||
)
|
||||
|
||||
def steal_string(batting_card: BattingCard) -> str:
|
||||
steal_string = '-/- (---)'
|
||||
if batting_card.steal_jump > 0:
|
||||
jump_chances = round(batting_card.steal_jump * 36)
|
||||
|
||||
if jump_chances == 6:
|
||||
good_jump = 7
|
||||
elif jump_chances == 5:
|
||||
good_jump = 6
|
||||
elif jump_chances == 4:
|
||||
good_jump = 5
|
||||
elif jump_chances == 3:
|
||||
good_jump = 4
|
||||
elif jump_chances == 2:
|
||||
good_jump = 3
|
||||
elif jump_chances == 1:
|
||||
good_jump = 2
|
||||
elif jump_chances == 7:
|
||||
good_jump = '4,5'
|
||||
elif jump_chances == 8:
|
||||
good_jump = '4,6'
|
||||
elif jump_chances == 9:
|
||||
good_jump = '3-5'
|
||||
elif jump_chances == 10:
|
||||
good_jump = '2-5'
|
||||
elif jump_chances == 11:
|
||||
good_jump = '6,7'
|
||||
elif jump_chances == 12:
|
||||
good_jump = '4-6'
|
||||
elif jump_chances == 13:
|
||||
good_jump = '2,4-6'
|
||||
elif jump_chances == 14:
|
||||
good_jump = '3-6'
|
||||
elif jump_chances == 15:
|
||||
good_jump = '2-6'
|
||||
elif jump_chances == 16:
|
||||
good_jump = '2,5-6'
|
||||
elif jump_chances == 17:
|
||||
good_jump = '3,5-6'
|
||||
elif jump_chances == 18:
|
||||
good_jump = '4-6'
|
||||
elif jump_chances == 19:
|
||||
good_jump = '2,4-7'
|
||||
elif jump_chances == 20:
|
||||
good_jump = '3-7'
|
||||
elif jump_chances == 21:
|
||||
good_jump = '2-7'
|
||||
elif jump_chances == 22:
|
||||
good_jump = '2-7,12'
|
||||
elif jump_chances == 23:
|
||||
good_jump = '2-7,11'
|
||||
elif jump_chances == 24:
|
||||
good_jump = '2,4-8'
|
||||
elif jump_chances == 25:
|
||||
good_jump = '3-8'
|
||||
elif jump_chances == 26:
|
||||
good_jump = '2-8'
|
||||
elif jump_chances == 27:
|
||||
good_jump = '2-8,12'
|
||||
elif jump_chances == 28:
|
||||
good_jump = '2-8,11'
|
||||
elif jump_chances == 29:
|
||||
good_jump = '3-9'
|
||||
elif jump_chances == 30:
|
||||
good_jump = '2-9'
|
||||
elif jump_chances == 31:
|
||||
good_jump = '2-9,12'
|
||||
elif jump_chances == 32:
|
||||
good_jump = '2-9,11'
|
||||
elif jump_chances == 33:
|
||||
good_jump = '2-10'
|
||||
elif jump_chances == 34:
|
||||
good_jump = '3-11'
|
||||
elif jump_chances == 35:
|
||||
good_jump = '2-11'
|
||||
else:
|
||||
good_jump = '2-12'
|
||||
steal_string = f'{"*" if batting_card.steal_auto else ""}{good_jump}/- ({batting_card.steal_high}-{batting_card.steal_low})'
|
||||
return steal_string
|
||||
|
||||
baserunner_string = ''
|
||||
if curr_play.on_first is not None:
|
||||
runcard = curr_play.on_first.card.batterscouting.battingcard
|
||||
baserunner_string += f'On First: {curr_play.on_first.player.name_card_link('batting')}\nSteal: {steal_string(runcard)}, Run: {runcard.running}\n'
|
||||
if curr_play.on_second is not None:
|
||||
runcard = curr_play.on_second.card.batterscouting.battingcard
|
||||
baserunner_string += f'On Second: {curr_play.on_second.player.name_card_link('batting')}\nSteal: {steal_string(runcard)}, Run: {runcard.running}\n'
|
||||
if curr_play.on_third is not None:
|
||||
runcard = curr_play.on_third.card.batterscouting.battingcard
|
||||
baserunner_string += f'On Third: {curr_play.on_third.player.name_card_link('batting')}\nSteal: {steal_string(runcard)}, Run: {runcard.running}\n'
|
||||
logger.info(f'gameplay_models - Game.get_scorebug_embed - baserunner_string: {baserunner_string}')
|
||||
|
||||
pit_string = f'{curr_play.pitcher.player.name_card_link('pitching')}'
|
||||
bat_string = f'{curr_play.batter.player.name_card_link('batting')}'
|
||||
if len(baserunner_string) > 0:
|
||||
pitchingcard = curr_play.pitcher.card.pitcherscouting.pitchingcard
|
||||
pit_string += f'\nHold: {pitchingcard.hold}, WP: {pitchingcard.wild_pitch}, Bk: {pitchingcard.balk}'
|
||||
|
||||
# battingcard = curr_play.batter.card.batterscouting.battingcard
|
||||
# bat_string += f'\nBunt: {battingcard.bunting}, HnR: {battingcard.hit_and_run}'
|
||||
|
||||
embed.add_field(
|
||||
name='Pitcher',
|
||||
value=pit_string
|
||||
)
|
||||
embed.add_field(
|
||||
name='Batter',
|
||||
value=bat_string
|
||||
)
|
||||
embed.set_image(url=curr_play.batter.player.batter_card_url)
|
||||
|
||||
if len(baserunner_string) > 0:
|
||||
embed.add_field(name=' ', value=' ', inline=False)
|
||||
embed.add_field(name='Baserunners', value=baserunner_string)
|
||||
|
||||
c_query = session.exec(select(PositionRating).where(PositionRating.player_id == curr_play.catcher.card.player.id, PositionRating.position == 'C', PositionRating.variant == curr_play.catcher.card.variant)).all()
|
||||
if len(c_query) > 0:
|
||||
catcher_rating = c_query[0]
|
||||
else:
|
||||
log_exception(PositionNotFoundException, f'No catcher rating found for {curr_play.catcher.card.player.name}')
|
||||
|
||||
cat_string = f'{curr_play.catcher.player.name_card_link('batter')}\nArm: {catcher_rating.arm}'
|
||||
embed.add_field(name='Catcher', value=cat_string)
|
||||
|
||||
ai_note = curr_play.ai_note
|
||||
logger.info(f'gameplay_models - Game.get_scorebug_embed - ai_note: {ai_note}')
|
||||
if len(ai_note) > 0:
|
||||
gm_name = this_game.home_team.gmname if this_game.ai_team == 'home' else this_game.away_team.gmname
|
||||
embed.add_field(name=f'{gm_name} will...', value=ai_note, inline=False)
|
||||
else:
|
||||
embed.add_field(name=' ', value=' ', inline=False)
|
||||
|
||||
if full_length:
|
||||
embed.add_field(
|
||||
name=f'{this_game.away_team.abbrev} Lineup',
|
||||
value=this_game.team_lineup(session, this_game.away_team)
|
||||
)
|
||||
embed.add_field(
|
||||
name=f'{this_game.home_team.abbrev} Lineup',
|
||||
value=this_game.team_lineup(session, this_game.home_team)
|
||||
)
|
||||
else:
|
||||
embed.add_field(
|
||||
name=f'{this_game.away_team.abbrev} Lineup',
|
||||
value=this_game.team_lineup(session, this_game.away_team)
|
||||
)
|
||||
embed.add_field(
|
||||
name=f'{this_game.home_team.abbrev} Lineup',
|
||||
value=this_game.team_lineup(session, this_game.home_team)
|
||||
)
|
||||
|
||||
return embed
|
||||
|
||||
|
||||
def get_obc(on_first = None, on_second = None, on_third = None) -> int:
|
||||
if on_third is not None:
|
||||
if on_second is not None:
|
||||
@ -1193,6 +1383,46 @@ async def bunts(session: Session, interaction: discord.Interaction, this_play: P
|
||||
return this_play
|
||||
|
||||
|
||||
async def chaos(session: Session, interaction: discord.Interaction, this_play: Play, chaos_type: Literal['wild-pitch', 'passed-ball', 'balk', 'pickoff']):
|
||||
"""
|
||||
Commits this_play
|
||||
"""
|
||||
this_play.pa, this_play.ab = 0, 0
|
||||
|
||||
if chaos_type == 'wild-pitch':
|
||||
this_play = advance_runners(session, this_play, 1)
|
||||
this_play.rbi = 0
|
||||
this_play.wild_pitch = 1
|
||||
|
||||
elif chaos_type == 'passed-ball':
|
||||
this_play = advance_runners(session, this_play, 1)
|
||||
this_play.rbi = 0
|
||||
this_play.passed_ball = 1
|
||||
|
||||
elif chaos_type == 'balk':
|
||||
this_play = advance_runners(session, this_play, 1)
|
||||
this_play.rbi = 0
|
||||
this_play.balk = 1
|
||||
|
||||
elif chaos_type == 'pickoff':
|
||||
this_play = advance_runners(session, this_play, 0)
|
||||
this_play.pick_off = 1
|
||||
this_play.outs = 1
|
||||
|
||||
if this_play.on_third:
|
||||
this_play.on_third_final = None
|
||||
elif this_play.on_second:
|
||||
this_play.on_second_final = None
|
||||
elif this_play.on_first:
|
||||
this_play.on_first_final = None
|
||||
|
||||
session.add(this_play)
|
||||
session.commit()
|
||||
|
||||
session.refresh(this_play)
|
||||
return this_play
|
||||
|
||||
|
||||
def activate_last_play(session: Session, this_game: Game) -> Play:
|
||||
p_query = session.exec(select(Play).where(Play.game == this_game).order_by(Play.id.desc()).limit(1)).all()
|
||||
|
||||
@ -1596,3 +1826,29 @@ async def complete_game(session: Session, interaction: discord.Interaction, this
|
||||
session.commit()
|
||||
|
||||
logger.info(f'Just ended game {game_id}')
|
||||
|
||||
|
||||
async def update_game_settings(session: Session, interaction: discord.Interaction, this_game: Game, roll_buttons: bool = None, auto_roll: bool = None) -> discord.Embed:
|
||||
if roll_buttons is not None:
|
||||
this_game.roll_buttons = roll_buttons
|
||||
if auto_roll is not None:
|
||||
this_game.auto_roll = auto_roll
|
||||
|
||||
session.add(this_game)
|
||||
session.commit()
|
||||
session.refresh(this_game)
|
||||
|
||||
this_team = this_game.away_team if this_game.away_team.gmid == interaction.user.id else this_game.home_team
|
||||
embed = this_team.embed
|
||||
|
||||
embed.title = f'Game Settings - {this_team.lname}'
|
||||
embed.add_field(
|
||||
name='Roll Buttons',
|
||||
value=f'{"ON" if this_game.roll_buttons else "OFF"}'
|
||||
)
|
||||
embed.add_field(
|
||||
name='Auto Roll',
|
||||
value=f'{"ON" if this_game.auto_roll else "OFF"}'
|
||||
)
|
||||
|
||||
return embed
|
||||
|
||||
162
dice.py
162
dice.py
@ -1,13 +1,33 @@
|
||||
import logging
|
||||
import discord
|
||||
import random
|
||||
|
||||
import pydantic
|
||||
|
||||
from helpers import INFIELD_X_CHART, OUTFIELD_X_CHART
|
||||
from in_game.gameplay_models import Game, Team
|
||||
|
||||
logger = logging.getLogger('discord_app')
|
||||
|
||||
|
||||
def get_dice_embed(team: dict = None, embed_title: str = None):
|
||||
class DiceRoll(pydantic.BaseModel):
|
||||
model_config = pydantic.ConfigDict(arbitrary_types_allowed=True)
|
||||
roll_message: str | None = None
|
||||
embeds: list[discord.Embed] | None = None
|
||||
|
||||
|
||||
class AbRoll(DiceRoll):
|
||||
is_chaos: bool = False
|
||||
d_six_one: int | None = None
|
||||
d_six_two: int | None = None
|
||||
d_six_three: int | None = None
|
||||
d_twenty: int | None = None
|
||||
|
||||
|
||||
def get_dice_embed(team: Team = None, embed_title: str = None):
|
||||
if team:
|
||||
embed = discord.Embed(
|
||||
color=int(team["dice_color"], 16) if 'dice_color' in team else int(team["color"], 16)
|
||||
color=int(team.color, 16)
|
||||
)
|
||||
else:
|
||||
embed = discord.Embed(
|
||||
@ -20,7 +40,7 @@ def get_dice_embed(team: dict = None, embed_title: str = None):
|
||||
return embed
|
||||
|
||||
|
||||
def sa_fielding_roll(pos_code: str, team: dict) -> [discord.Embed]:
|
||||
def sa_fielding_roll(pos_code: str, team: dict) -> list[discord.Embed]:
|
||||
"""
|
||||
Make a Super Advanced fielding check.
|
||||
"""
|
||||
@ -622,40 +642,50 @@ def sa_fielding_roll(pos_code: str, team: dict) -> [discord.Embed]:
|
||||
'#heading=h.fpjqmiv10r8l'
|
||||
|
||||
# Build range note
|
||||
if d_twenty <= 2:
|
||||
if d_twenty == 1:
|
||||
range_note = '```\n' \
|
||||
' 1 | 2 | 3 | 4 | 5\n' \
|
||||
'G3 ------SI1------\n' \
|
||||
'G3# ------SI1------\n' \
|
||||
'```\n'
|
||||
elif d_twenty == 3:
|
||||
elif d_twenty == 2:
|
||||
range_note = '```\n' \
|
||||
' 1 | 2 | 3 | 4 | 5\n' \
|
||||
'--G3--- ----SI1----\n' \
|
||||
'G2# ------SI1------\n' \
|
||||
'```\n'
|
||||
elif d_twenty == 4:
|
||||
elif d_twenty <= 4:
|
||||
range_note = '```\n' \
|
||||
' 1 | 2 | 3 | 4 | 5\n' \
|
||||
'----G3----- --SI1--\n' \
|
||||
'G2# G3# ----SI1----\n' \
|
||||
'```\n'
|
||||
elif d_twenty <= 6:
|
||||
elif d_twenty == 5:
|
||||
range_note = '```\n' \
|
||||
' 1 | 2 | 3 | 4 | 5\n' \
|
||||
'------G3------- SI1\n' \
|
||||
'G2 --G3#-- --SI1--\n' \
|
||||
'```\n'
|
||||
elif d_twenty == 7:
|
||||
elif d_twenty == 6:
|
||||
range_note = '```\n' \
|
||||
' 1 | 2 | 3 | 4 | 5\n' \
|
||||
'--------G3---------\n' \
|
||||
'G1 G2# G3# --SI1--\n' \
|
||||
'```\n'
|
||||
elif d_twenty <= 9:
|
||||
elif d_twenty <= 8:
|
||||
range_note = '```\n' \
|
||||
' 1 | 2 | 3 | 4 | 5\n' \
|
||||
'G2 ------G3-------\n' \
|
||||
'G1 G2 --G3#-- SI1\n' \
|
||||
'```\n'
|
||||
elif d_twenty == 9:
|
||||
range_note = '```\n' \
|
||||
' 1 | 2 | 3 | 4 | 5\n' \
|
||||
'G1 G2 G3 --G3#--\n' \
|
||||
'```\n'
|
||||
elif d_twenty == 10:
|
||||
range_note = '```\n' \
|
||||
' 1 | 2 | 3 | 4 | 5\n' \
|
||||
'--G1--- G2 --G3#--\n' \
|
||||
'```\n'
|
||||
elif d_twenty <= 12:
|
||||
range_note = '```\n' \
|
||||
' 1 | 2 | 3 | 4 | 5\n' \
|
||||
'G1 G2 ----G3-----\n' \
|
||||
'--G1--- G2 G3 G3#\n' \
|
||||
'```\n'
|
||||
elif d_twenty == 13:
|
||||
range_note = '```\n' \
|
||||
@ -670,12 +700,12 @@ def sa_fielding_roll(pos_code: str, team: dict) -> [discord.Embed]:
|
||||
elif d_twenty <= 16:
|
||||
range_note = '```\n' \
|
||||
' 1 | 2 | 3 | 4 | 5\n' \
|
||||
'--G1--- ----G2-----\n' \
|
||||
'----G1----- G2 G3\n' \
|
||||
'```\n'
|
||||
elif d_twenty <= 18:
|
||||
range_note = '```\n' \
|
||||
' 1 | 2 | 3 | 4 | 5\n' \
|
||||
'----G1----- --G2---\n' \
|
||||
'------G1------- G3\n' \
|
||||
'```\n'
|
||||
elif d_twenty == 19:
|
||||
range_note = '```\n' \
|
||||
@ -791,3 +821,99 @@ def frame_plate_check(team: dict, game_id: int):
|
||||
roll_embed.set_footer(text="This result will be logged automatically")
|
||||
|
||||
return {'embed': roll_embed, 'is_walk': d_twenty <= this_ump['walk_d20']}
|
||||
|
||||
|
||||
def ab_roll(this_team: Team, this_game: Game, allow_chaos: bool = True) -> AbRoll:
|
||||
"""
|
||||
Make an AB roll
|
||||
"""
|
||||
d_twenty = random.randint(1, 20)
|
||||
d_twenty_two = random.randint(1, 20)
|
||||
flag = None
|
||||
|
||||
if allow_chaos:
|
||||
if d_twenty == 1:
|
||||
flag = 'wild pitch'
|
||||
elif d_twenty == 2:
|
||||
if random.randint(1, 2) == 1:
|
||||
flag = 'balk'
|
||||
else:
|
||||
flag = 'passed ball'
|
||||
|
||||
if flag:
|
||||
roll_message = f'```md\nCheck {flag}```\n' \
|
||||
f'{flag.title()} roll```md\n# {d_twenty_two}\nDetails: [1d20 ({d_twenty_two})]```\n'
|
||||
embed = get_dice_embed(this_team, f'Chaos roll for the {this_team.sname}', roll_message)
|
||||
embed.set_footer(
|
||||
text='If the chaos roll fails, ignore future chaos until a new batter comes to the plate.'
|
||||
)
|
||||
# return {'is_chaos': True, 'embeds': [embed]}
|
||||
return AbRoll(
|
||||
roll_message=roll_message,
|
||||
is_chaos=True,
|
||||
embeds=[embed]
|
||||
)
|
||||
|
||||
logger.info(f'Pre-AB roll')
|
||||
this_roll = AbRoll(
|
||||
d_six_one=random.randint(1, 6),
|
||||
d_six_two=random.randint(1, 6),
|
||||
d_six_three=random.randint(1, 6),
|
||||
d_twenty=random.randint(1, 20)
|
||||
)
|
||||
logger.info(f'AB roll base: {this_roll}')
|
||||
|
||||
this_roll.roll_message = f'```md\n# {this_roll.d_six_one},{this_roll.d_six_two + this_roll.d_six_three},{this_roll.d_twenty}\nDetails:[1d6;2d6;1d20 ({this_roll.d_six_one} - {this_roll.d_six_two} {this_roll.d_six_three} - {this_roll.d_twenty})]```'
|
||||
|
||||
logger.info(f'AB roll with message: {this_roll}')
|
||||
|
||||
embed = get_dice_embed(this_team)
|
||||
embed.add_field(
|
||||
name=f'At bat roll for the {this_team.sname}',
|
||||
value=this_roll.roll_message
|
||||
)
|
||||
|
||||
this_roll.embeds = [embed]
|
||||
|
||||
# if d_six_one == 6 and d_six_two + d_six_three > 6:
|
||||
# roll_message += f'\n**Check injury for pitcher injury rating {13 - d_six_two - d_six_three}**\n' \
|
||||
# f'Oops! All injuries!'
|
||||
|
||||
|
||||
logger.info(f'Game {this_game.id} | Team {this_team.id} ({this_team.abbrev}): {this_roll.roll_message}')
|
||||
return this_roll
|
||||
|
||||
|
||||
def jump_roll(this_team: Team, this_game: Game) -> list[discord.Embed]:
|
||||
"""
|
||||
Check for a baserunner's jump before stealing
|
||||
"""
|
||||
d_six_one = random.randint(1, 6)
|
||||
d_six_two = random.randint(1, 6)
|
||||
d_twenty = random.randint(1, 20)
|
||||
d_twenty_two = random.randint(1, 20)
|
||||
flag = None
|
||||
|
||||
if d_twenty == 1:
|
||||
flag = 'pickoff'
|
||||
elif d_twenty == 2:
|
||||
flag = 'balk'
|
||||
|
||||
if not flag:
|
||||
roll_message = f'```md\n# {d_six_one + d_six_two}\n'\
|
||||
f'Details:[2d6 ({d_six_one} {d_six_two})]```'
|
||||
else:
|
||||
roll_message = f'```md\nCheck {flag}```\n' \
|
||||
f'{flag.title()} roll```md\n# {d_twenty_two}\nDetails: [1d20 ({d_twenty_two})]```'
|
||||
|
||||
embed = get_dice_embed(this_team)
|
||||
embed.add_field(
|
||||
name=f'Jump check for the {this_team.sname}',
|
||||
value=roll_message
|
||||
)
|
||||
|
||||
|
||||
logger.info(f'Game {this_game.id} | Team {this_team.id} ({this_team.abbrev}): {roll_message}')
|
||||
return [embed]
|
||||
|
||||
|
||||
|
||||
@ -106,6 +106,8 @@ class Game(SQLModel, table=True):
|
||||
first_message: str | None = Field(default=None)
|
||||
ai_team: str | None = Field(default=None)
|
||||
game_type: str
|
||||
roll_buttons: bool | None = Field(default=False)
|
||||
auto_roll: bool | None = Field(default=True)
|
||||
|
||||
cardset_links: list[GameCardsetLink] = Relationship(back_populates='game', cascade_delete=True)
|
||||
away_team: Team = Relationship(
|
||||
@ -151,94 +153,191 @@ class Game(SQLModel, table=True):
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_scorebug_embed(self, session: Session, full_length: bool = True, classic: bool = True) -> discord.Embed:
|
||||
gt_string = ' - Unlimited'
|
||||
if self.game_type == 'minor-league':
|
||||
gt_string = ' - Minor League'
|
||||
elif self.game_type == 'major-league':
|
||||
gt_string = ' - Major League'
|
||||
elif self.game_type == 'hall-of-fame':
|
||||
gt_string = ' - Hall of Fame'
|
||||
elif 'gauntlet' in self.game_type:
|
||||
gt_string = ' - Gauntlet'
|
||||
elif 'flashback' in self.game_type:
|
||||
gt_string = ' - Flashback'
|
||||
elif 'exhibition' in self.game_type:
|
||||
gt_string = ' - Exhibition'
|
||||
logger.info(f'gameplay_models - Game.get_scorebug_embed - this_game: {self} / gt_string: {gt_string}')
|
||||
# async def get_scorebug_embed(self, session: Session, full_length: bool = True, classic: bool = True) -> discord.Embed:
|
||||
# gt_string = ' - Unlimited'
|
||||
# if self.game_type == 'minor-league':
|
||||
# gt_string = ' - Minor League'
|
||||
# elif self.game_type == 'major-league':
|
||||
# gt_string = ' - Major League'
|
||||
# elif self.game_type == 'hall-of-fame':
|
||||
# gt_string = ' - Hall of Fame'
|
||||
# elif 'gauntlet' in self.game_type:
|
||||
# gt_string = ' - Gauntlet'
|
||||
# elif 'flashback' in self.game_type:
|
||||
# gt_string = ' - Flashback'
|
||||
# elif 'exhibition' in self.game_type:
|
||||
# gt_string = ' - Exhibition'
|
||||
# logger.info(f'gameplay_models - Game.get_scorebug_embed - this_game: {self} / gt_string: {gt_string}')
|
||||
|
||||
embed = discord.Embed(
|
||||
title=f'{self.away_team.sname} @ {self.home_team.sname}{gt_string}',
|
||||
color=int(SBA_COLOR, 16)
|
||||
)
|
||||
# embed = discord.Embed(
|
||||
# title=f'{self.away_team.sname} @ {self.home_team.sname}{gt_string}',
|
||||
# color=int(SBA_COLOR, 16)
|
||||
# )
|
||||
|
||||
curr_play = self.current_play_or_none(session)
|
||||
# curr_play = self.current_play_or_none(session)
|
||||
|
||||
if curr_play is None:
|
||||
try:
|
||||
curr_play = self.initialize_play(session)
|
||||
except LineupsMissingException as e:
|
||||
logger.debug(f'gameplay_models - Game.get_scorebug_embed - Could not initialize play')
|
||||
# if curr_play is None:
|
||||
# try:
|
||||
# curr_play = self.initialize_play(session)
|
||||
# except LineupsMissingException as e:
|
||||
# logger.debug(f'gameplay_models - Game.get_scorebug_embed - Could not initialize play')
|
||||
|
||||
if curr_play is not None:
|
||||
embed.add_field(
|
||||
name='Game State',
|
||||
value=curr_play.scorebug_ascii,
|
||||
inline=False
|
||||
)
|
||||
# if curr_play is not None:
|
||||
# embed.add_field(
|
||||
# name='Game State',
|
||||
# value=curr_play.scorebug_ascii,
|
||||
# inline=False
|
||||
# )
|
||||
|
||||
if classic:
|
||||
embed.add_field(
|
||||
name='Pitcher',
|
||||
value=curr_play.pitcher.player.name_card_link('pitching')
|
||||
)
|
||||
embed.add_field(
|
||||
name='Batter',
|
||||
value=curr_play.batter.player.name_card_link('batting')
|
||||
)
|
||||
# def steal_string(batting_card: BattingCard) -> str:
|
||||
# steal_string = '-/- (---)'
|
||||
# if batting_card.steal_jump > 0:
|
||||
# jump_chances = round(batting_card.steal_jump * 36)
|
||||
|
||||
baserunner_string = ''
|
||||
if curr_play.on_first is not None:
|
||||
baserunner_string += f'On First: {curr_play.on_first.player.name_card_link('batting')}\n'
|
||||
if curr_play.on_second is not None:
|
||||
baserunner_string += f'On Second: {curr_play.on_second.player.name_card_link('batting')}\n'
|
||||
if curr_play.on_third is not None:
|
||||
baserunner_string += f'On Third: {curr_play.on_third.player.name_card_link('batting')}'
|
||||
logger.info(f'gameplay_models - Game.get_scorebug_embed - baserunner_string: {baserunner_string}')
|
||||
# if jump_chances == 6:
|
||||
# good_jump = 7
|
||||
# elif jump_chances == 5:
|
||||
# good_jump = 6
|
||||
# elif jump_chances == 4:
|
||||
# good_jump = 5
|
||||
# elif jump_chances == 3:
|
||||
# good_jump = 4
|
||||
# elif jump_chances == 2:
|
||||
# good_jump = 3
|
||||
# elif jump_chances == 1:
|
||||
# good_jump = 2
|
||||
# elif jump_chances == 7:
|
||||
# good_jump = '4,5'
|
||||
# elif jump_chances == 8:
|
||||
# good_jump = '4,6'
|
||||
# elif jump_chances == 9:
|
||||
# good_jump = '3-5'
|
||||
# elif jump_chances == 10:
|
||||
# good_jump = '2-5'
|
||||
# elif jump_chances == 11:
|
||||
# good_jump = '6,7'
|
||||
# elif jump_chances == 12:
|
||||
# good_jump = '4-6'
|
||||
# elif jump_chances == 13:
|
||||
# good_jump = '2,4-6'
|
||||
# elif jump_chances == 14:
|
||||
# good_jump = '3-6'
|
||||
# elif jump_chances == 15:
|
||||
# good_jump = '2-6'
|
||||
# elif jump_chances == 16:
|
||||
# good_jump = '2,5-6'
|
||||
# elif jump_chances == 17:
|
||||
# good_jump = '3,5-6'
|
||||
# elif jump_chances == 18:
|
||||
# good_jump = '4-6'
|
||||
# elif jump_chances == 19:
|
||||
# good_jump = '2,4-7'
|
||||
# elif jump_chances == 20:
|
||||
# good_jump = '3-7'
|
||||
# elif jump_chances == 21:
|
||||
# good_jump = '2-7'
|
||||
# elif jump_chances == 22:
|
||||
# good_jump = '2-7,12'
|
||||
# elif jump_chances == 23:
|
||||
# good_jump = '2-7,11'
|
||||
# elif jump_chances == 24:
|
||||
# good_jump = '2,4-8'
|
||||
# elif jump_chances == 25:
|
||||
# good_jump = '3-8'
|
||||
# elif jump_chances == 26:
|
||||
# good_jump = '2-8'
|
||||
# elif jump_chances == 27:
|
||||
# good_jump = '2-8,12'
|
||||
# elif jump_chances == 28:
|
||||
# good_jump = '2-8,11'
|
||||
# elif jump_chances == 29:
|
||||
# good_jump = '3-9'
|
||||
# elif jump_chances == 30:
|
||||
# good_jump = '2-9'
|
||||
# elif jump_chances == 31:
|
||||
# good_jump = '2-9,12'
|
||||
# elif jump_chances == 32:
|
||||
# good_jump = '2-9,11'
|
||||
# elif jump_chances == 33:
|
||||
# good_jump = '2-10'
|
||||
# elif jump_chances == 34:
|
||||
# good_jump = '3-11'
|
||||
# elif jump_chances == 35:
|
||||
# good_jump = '2-11'
|
||||
# else:
|
||||
# good_jump = '2-12'
|
||||
# steal_string = f'{"*" if batting_card.steal_auto else ""}{good_jump}/- ({batting_card.steal_high}-{batting_card.steal_low})'
|
||||
# return steal_string
|
||||
|
||||
if len(baserunner_string) > 0:
|
||||
embed.add_field(name=' ', value=' ', inline=False)
|
||||
embed.add_field(name='Baserunners', value=baserunner_string)
|
||||
embed.add_field(name='Catcher', value=curr_play.catcher.player.name_card_link('batter'))
|
||||
# baserunner_string = ''
|
||||
# if curr_play.on_first is not None:
|
||||
# runcard = curr_play.on_first.card.batterscouting.battingcard
|
||||
# baserunner_string += f'On First: {curr_play.on_first.player.name_card_link('batting')}\nSteal: {steal_string(runcard)}, Run: {runcard.running}'
|
||||
# if curr_play.on_second is not None:
|
||||
# baserunner_string += f'On Second: {curr_play.on_second.player.name_card_link('batting')}\nSteal: {steal_string(runcard)}, Run: {runcard.running}'
|
||||
# if curr_play.on_third is not None:
|
||||
# baserunner_string += f'On Third: {curr_play.on_third.player.name_card_link('batting')}\nSteal: {steal_string(runcard)}, Run: {runcard.running}'
|
||||
# logger.info(f'gameplay_models - Game.get_scorebug_embed - baserunner_string: {baserunner_string}')
|
||||
|
||||
ai_note = curr_play.ai_note
|
||||
logger.info(f'gameplay_models - Game.get_scorebug_embed - ai_note: {ai_note}')
|
||||
if len(ai_note) > 0:
|
||||
gm_name = self.home_team.gmname if self.ai_team == 'home' else self.away_team.gmname
|
||||
embed.add_field(name=f'{gm_name} will...', value=ai_note, inline=False)
|
||||
else:
|
||||
embed.add_field(name=' ', value=' ', inline=False)
|
||||
# pit_string = f'{curr_play.pitcher.player.name_card_link('pitching')}'
|
||||
# bat_string = f'{curr_play.batter.player.name_card_link('batting')}'
|
||||
# if len(baserunner_string) > 0:
|
||||
# pitchingcard = curr_play.pitcher.card.pitcherscouting.pitchingcard
|
||||
# pit_string += f'\nHold: {pitchingcard.hold}, WP: {pitchingcard.wild_pitch}, Bk: {pitchingcard.balk}'
|
||||
|
||||
if full_length:
|
||||
embed.add_field(
|
||||
name=f'{self.away_team.abbrev} Lineup',
|
||||
value=self.team_lineup(session, self.away_team)
|
||||
)
|
||||
embed.add_field(
|
||||
name=f'{self.home_team.abbrev} Lineup',
|
||||
value=self.team_lineup(session, self.home_team)
|
||||
)
|
||||
else:
|
||||
embed.add_field(
|
||||
name=f'{self.away_team.abbrev} Lineup',
|
||||
value=self.team_lineup(session, self.away_team)
|
||||
)
|
||||
embed.add_field(
|
||||
name=f'{self.home_team.abbrev} Lineup',
|
||||
value=self.team_lineup(session, self.home_team)
|
||||
)
|
||||
# # battingcard = curr_play.batter.card.batterscouting.battingcard
|
||||
# # bat_string += f'\nBunt: {battingcard.bunting}, HnR: {battingcard.hit_and_run}'
|
||||
|
||||
return embed
|
||||
# embed.add_field(
|
||||
# name='Pitcher',
|
||||
# value=pit_string
|
||||
# )
|
||||
# embed.add_field(
|
||||
# name='Batter',
|
||||
# value=bat_string
|
||||
# )
|
||||
|
||||
# if len(baserunner_string) > 0:
|
||||
# embed.add_field(name=' ', value=' ', inline=False)
|
||||
# embed.add_field(name='Baserunners', value=baserunner_string)
|
||||
|
||||
# c_query = session.exec(select(PositionRating).where(PositionRating.player_id == curr_play.catcher.card.player.id, PositionRating.position == 'C', PositionRating.variant == curr_play.catcher.card.variant)).all()
|
||||
# if len(c_query) > 0:
|
||||
# catcher_rating = c_query[0]
|
||||
# else:
|
||||
# log_exception(PositionNotFoundException, f'No catcher rating found for {curr_play.catcher.card.player.name}')
|
||||
|
||||
# cat_string = f'{curr_play.catcher.player.name_card_link('batter')}\nArm: {catcher_rating.arm}'
|
||||
# embed.add_field(name='Catcher', value=cat_string)
|
||||
|
||||
# ai_note = curr_play.ai_note
|
||||
# logger.info(f'gameplay_models - Game.get_scorebug_embed - ai_note: {ai_note}')
|
||||
# if len(ai_note) > 0:
|
||||
# gm_name = self.home_team.gmname if self.ai_team == 'home' else self.away_team.gmname
|
||||
# embed.add_field(name=f'{gm_name} will...', value=ai_note, inline=False)
|
||||
# else:
|
||||
# embed.add_field(name=' ', value=' ', inline=False)
|
||||
|
||||
# if full_length:
|
||||
# embed.add_field(
|
||||
# name=f'{self.away_team.abbrev} Lineup',
|
||||
# value=self.team_lineup(session, self.away_team)
|
||||
# )
|
||||
# embed.add_field(
|
||||
# name=f'{self.home_team.abbrev} Lineup',
|
||||
# value=self.team_lineup(session, self.home_team)
|
||||
# )
|
||||
# else:
|
||||
# embed.add_field(
|
||||
# name=f'{self.away_team.abbrev} Lineup',
|
||||
# value=self.team_lineup(session, self.away_team)
|
||||
# )
|
||||
# embed.add_field(
|
||||
# name=f'{self.home_team.abbrev} Lineup',
|
||||
# value=self.team_lineup(session, self.home_team)
|
||||
# )
|
||||
|
||||
# return embed
|
||||
|
||||
def initialize_play(self, session: Session):
|
||||
"""
|
||||
@ -655,6 +754,24 @@ class Player(PlayerBase, table=True):
|
||||
def name_with_desc(self):
|
||||
return f'{self.description} {self.name}'
|
||||
|
||||
@property
|
||||
def batter_card_url(self):
|
||||
if 'batting' in self.image:
|
||||
return self.image
|
||||
elif 'batting' in self.image2:
|
||||
return self.image2
|
||||
else:
|
||||
return None
|
||||
|
||||
@property
|
||||
def pitcher_card_url(self):
|
||||
if 'pitching' in self.image:
|
||||
return self.image
|
||||
elif 'pitching' in self.image2:
|
||||
return self.image2
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def player_description(player: Player = None, player_dict: dict = None) -> str:
|
||||
if player is None and player_dict is None:
|
||||
@ -1110,6 +1227,13 @@ class Play(PlayBase, table=True):
|
||||
|
||||
@property
|
||||
def could_walkoff(self) -> bool:
|
||||
if self.inning_half == 'bot' and self.on_third is not None:
|
||||
runs_needed = self.away_score - self.home_score + 1
|
||||
|
||||
if runs_needed == 2 or (self.home_score - self.away_score == 9):
|
||||
return True
|
||||
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
|
||||
@ -204,23 +204,23 @@ sample_ratings_query = {
|
||||
}
|
||||
|
||||
|
||||
async def test_create_scouting(session: Session):
|
||||
this_card = await get_card_or_none(session, card_id=1405)
|
||||
# async def test_create_scouting(session: Session):
|
||||
# this_card = await get_card_or_none(session, card_id=1405)
|
||||
|
||||
assert this_card.player.id == 395
|
||||
assert this_card.team.id == 31
|
||||
assert this_card.batterscouting.battingcard_id == sample_ratings_query["ratings"][0]['battingcard']['id']
|
||||
|
||||
# this_scouting = await get_batter_scouting_or_none(session, this_card)
|
||||
|
||||
# assert this_scouting.battingcard_id == sample_ratings_query["ratings"][0]['battingcard']['id']
|
||||
|
||||
# this_card = await get_card_or_none(session, card_id=1406)
|
||||
|
||||
# assert this_card.player.id == 161
|
||||
# assert this_card.player.id == 395
|
||||
# assert this_card.team.id == 31
|
||||
# assert this_card.batterscouting.battingcard_id == sample_ratings_query["ratings"][0]['battingcard']['id']
|
||||
|
||||
# this_scouting = await get_pitcher_scouting_or_none(session, this_card)
|
||||
# # this_scouting = await get_batter_scouting_or_none(session, this_card)
|
||||
|
||||
# assert this_scouting.pitchingcard_id == 4294
|
||||
# # assert this_scouting.battingcard_id == sample_ratings_query["ratings"][0]['battingcard']['id']
|
||||
|
||||
# # this_card = await get_card_or_none(session, card_id=1406)
|
||||
|
||||
# # assert this_card.player.id == 161
|
||||
# # assert this_card.team.id == 31
|
||||
|
||||
# # this_scouting = await get_pitcher_scouting_or_none(session, this_card)
|
||||
|
||||
# # assert this_scouting.pitchingcard_id == 4294
|
||||
|
||||
|
||||
@ -42,21 +42,21 @@ async def test_get_or_create_ai_card(session: Session):
|
||||
assert new_card_2.id == 42
|
||||
|
||||
|
||||
async def test_get_card_or_none(session: Session):
|
||||
card_1 = session.get(Card, 1)
|
||||
new_card_1 = await get_card_or_none(session, card_id=card_1.id)
|
||||
# async def test_get_card_or_none(session: Session):
|
||||
# card_1 = session.get(Card, 1)
|
||||
# new_card_1 = await get_card_or_none(session, card_id=card_1.id)
|
||||
|
||||
assert card_1.created == new_card_1.created
|
||||
# assert card_1.created == new_card_1.created
|
||||
|
||||
assert session.get(Player, 538) is None
|
||||
assert session.get(Team, 55) is None
|
||||
# assert session.get(Player, 538) is None
|
||||
# assert session.get(Team, 55) is None
|
||||
|
||||
new_card_2 = await get_card_or_none(session, card_id=55555)
|
||||
print(f'new_card_2: {new_card_2}\nplayer: {new_card_2.player}\nteam: {new_card_2.team}')
|
||||
# new_card_2 = await get_card_or_none(session, card_id=55555)
|
||||
# print(f'new_card_2: {new_card_2}\nplayer: {new_card_2.player}\nteam: {new_card_2.team}')
|
||||
|
||||
assert new_card_2 is not None
|
||||
assert new_card_2.player_id == 538
|
||||
assert new_card_2.team_id == 55
|
||||
assert session.get(Player, 538) is not None
|
||||
assert session.get(Team, 55) is not None
|
||||
# assert new_card_2 is not None
|
||||
# assert new_card_2.player_id == 538
|
||||
# assert new_card_2.team_id == 55
|
||||
# assert session.get(Player, 538) is not None
|
||||
# assert session.get(Team, 55) is not None
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ from sqlalchemy import delete as sadelete
|
||||
from sqlalchemy.sql.functions import sum, count
|
||||
from sqlmodel import Session, delete, func
|
||||
|
||||
from command_logic.logic_gameplay import complete_play, homeruns, is_game_over, singles, strikeouts, undo_play
|
||||
from command_logic.logic_gameplay import complete_play, get_scorebug_embed, homeruns, is_game_over, singles, strikeouts, undo_play
|
||||
from in_game.gameplay_models import Game, Lineup, GameCardsetLink, Play, Team, select
|
||||
from in_game.gameplay_queries import get_channel_game_or_none, get_active_games_by_team, get_db_ready_decisions
|
||||
from tests.factory import session_fixture
|
||||
@ -109,15 +109,17 @@ def test_delete_game(session: Session):
|
||||
assert len(bad_links) == 0
|
||||
|
||||
|
||||
def test_get_scorebug(session: Session):
|
||||
async def test_get_scorebug(session: Session):
|
||||
game_1 = session.get(Game, 1)
|
||||
scorebug = game_1.get_scorebug_embed(session)
|
||||
# scorebug = game_1.get_scorebug_embed(session)
|
||||
scorebug = await get_scorebug_embed(session, game_1)
|
||||
|
||||
assert scorebug.title == 'CornBelters @ Black Bears - Minor League'
|
||||
assert scorebug.color.value == int('a6ce39', 16)
|
||||
|
||||
game_3 = session.get(Game, 3)
|
||||
scorebug = game_3.get_scorebug_embed(session)
|
||||
# scorebug = game_3.get_scorebug_embed(session)
|
||||
scorebug = await get_scorebug_embed(session, game_3)
|
||||
|
||||
assert '0 Outs' in scorebug.fields[0].value
|
||||
|
||||
|
||||
19
tests/other/test_dice.py
Normal file
19
tests/other/test_dice.py
Normal file
@ -0,0 +1,19 @@
|
||||
import pytest
|
||||
from sqlmodel import Session, select, func
|
||||
|
||||
from dice import ab_roll
|
||||
from in_game.gameplay_models import Game
|
||||
from tests.factory import session_fixture
|
||||
|
||||
|
||||
def test_ab_roll(session: Session):
|
||||
game_1 = session.get(Game, 1)
|
||||
play_2 = game_1.initialize_play(session)
|
||||
|
||||
this_roll = ab_roll(game_1.away_team, game_1, allow_chaos=False)
|
||||
|
||||
assert this_roll.d_six_one is not None
|
||||
assert this_roll.d_six_two is not None
|
||||
assert this_roll.d_six_three is not None
|
||||
assert this_roll.d_twenty is not None
|
||||
assert this_roll.roll_message is not None
|
||||
@ -1,5 +1,12 @@
|
||||
import logging
|
||||
import discord
|
||||
from typing import Literal
|
||||
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'):
|
||||
@ -18,7 +25,11 @@ class Confirm(discord.ui.View):
|
||||
@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:
|
||||
return
|
||||
await interaction.response.send_message(
|
||||
content='Get out of here',
|
||||
ephemeral=True,
|
||||
delete_after=10.0
|
||||
)
|
||||
|
||||
self.value = True
|
||||
self.clear_items()
|
||||
@ -28,7 +39,11 @@ class Confirm(discord.ui.View):
|
||||
@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:
|
||||
return
|
||||
await interaction.response.send_message(
|
||||
content='Get out of here',
|
||||
ephemeral=True,
|
||||
delete_after=10.0
|
||||
)
|
||||
|
||||
self.value = False
|
||||
self.clear_items()
|
||||
@ -68,7 +83,11 @@ class ButtonOptions(discord.ui.View):
|
||||
@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:
|
||||
return
|
||||
await interaction.response.send_message(
|
||||
content='Get out of here',
|
||||
ephemeral=True,
|
||||
delete_after=10.0
|
||||
)
|
||||
|
||||
self.value = self.options[0]
|
||||
self.clear_items()
|
||||
@ -77,7 +96,11 @@ class ButtonOptions(discord.ui.View):
|
||||
@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:
|
||||
return
|
||||
await interaction.response.send_message(
|
||||
content='Get out of here',
|
||||
ephemeral=True,
|
||||
delete_after=10.0
|
||||
)
|
||||
|
||||
self.value = self.options[1]
|
||||
self.clear_items()
|
||||
@ -86,7 +109,11 @@ class ButtonOptions(discord.ui.View):
|
||||
@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:
|
||||
return
|
||||
await interaction.response.send_message(
|
||||
content='Get out of here',
|
||||
ephemeral=True,
|
||||
delete_after=10.0
|
||||
)
|
||||
|
||||
self.value = self.options[2]
|
||||
self.clear_items()
|
||||
@ -95,7 +122,11 @@ class ButtonOptions(discord.ui.View):
|
||||
@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:
|
||||
return
|
||||
await interaction.response.send_message(
|
||||
content='Get out of here',
|
||||
ephemeral=True,
|
||||
delete_after=10.0
|
||||
)
|
||||
|
||||
self.value = self.options[3]
|
||||
self.clear_items()
|
||||
@ -104,7 +135,11 @@ class ButtonOptions(discord.ui.View):
|
||||
@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:
|
||||
return
|
||||
await interaction.response.send_message(
|
||||
content='Get out of here',
|
||||
ephemeral=True,
|
||||
delete_after=10.0
|
||||
)
|
||||
|
||||
self.value = self.options[4]
|
||||
self.clear_items()
|
||||
@ -140,3 +175,61 @@ async def ask_confirm(interaction: discord.Interaction, question: str, label_typ
|
||||
else:
|
||||
await question.edit(content=question, view=None)
|
||||
return False
|
||||
|
||||
|
||||
class ScorebugButtons(discord.ui.View):
|
||||
def __init__(self, play: Play, timeout: float = 30):
|
||||
super().__init__(timeout=timeout)
|
||||
self.value = None
|
||||
self.batting_team = play.batter.team
|
||||
self.pitching_team = play.pitcher.team
|
||||
self.team = play.batter.team
|
||||
self.play = play
|
||||
self.had_chaos = False
|
||||
|
||||
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)
|
||||
await interaction.response.edit_message(view=self)
|
||||
|
||||
@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)
|
||||
await interaction.response.edit_message(view=self)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user