diff --git a/cogs/gameplay.py b/cogs/gameplay.py index 85c23e1..65eeb27 100644 --- a/cogs/gameplay.py +++ b/cogs/gameplay.py @@ -24,7 +24,7 @@ from helpers import CARDSETS, DEFENSE_LITERAL, DEFENSE_NO_PITCHER_LITERAL, PD_PL from in_game.ai_manager import get_starting_pitcher, get_starting_lineup from in_game.game_helpers import PUBLIC_FIELDS_CATEGORY_NAME, legal_check from in_game.gameplay_models import GameCardsetLink, Lineup, Play, Session, engine, player_description, select, Game -from in_game.gameplay_queries import get_cardset_or_none, get_one_lineup, get_plays_by_pitcher, get_position, get_channel_game_or_none, get_active_games_by_team, get_game_lineups, get_team_or_none +from in_game.gameplay_queries import get_all_positions, get_cardset_or_none, get_one_lineup, get_plays_by_pitcher, get_position, get_channel_game_or_none, get_active_games_by_team, get_game_lineups, get_team_or_none from utilities.buttons import Confirm, ScorebugButtons, ask_confirm, ask_with_buttons from utilities.dropdown import DropdownView @@ -395,9 +395,11 @@ class Gameplay(commands.Cog): session.commit() await final_message.edit(content=f'The {ai_team.sname} lineup is in, pulling in scouting data...') - for batter in batter_lineups: - if batter.position != 'DH': - await get_position(session, batter.card, batter.position) + for batter in batter_lineups: + await get_all_positions( + session=session, + this_card=batter.card + ) logger.info(f'Pulling team roles') away_role = await team_role(interaction, this_game.away_team) @@ -616,8 +618,10 @@ class Gameplay(commands.Cog): await final_message.edit(content=f'The {ai_team.sname} lineup is in, pulling in scouting data...') for batter in batter_lineups: - if batter.position != 'DH': - await get_position(session, batter.card, batter.position) + await get_all_positions( + session=session, + this_card=batter.card + ) embed = await get_scorebug_embed(session, this_game) embed.clear_fields() @@ -768,8 +772,10 @@ class Gameplay(commands.Cog): await final_message.edit(content=f'The {ai_team.sname} lineup is in, pulling in scouting data...') for batter in batter_lineups: - if batter.position != 'DH': - await get_position(session, batter.card, batter.position) + await get_all_positions( + session=session, + this_card=batter.card + ) logger.info(f'Pulling team roles') away_role = await team_role(interaction, this_game.away_team) diff --git a/command_logic/logic_gameplay.py b/command_logic/logic_gameplay.py index f490c98..b398741 100644 --- a/command_logic/logic_gameplay.py +++ b/command_logic/logic_gameplay.py @@ -1361,6 +1361,16 @@ async def flyballs(session: Session, interaction: discord.Interaction, this_play elif result == 'catcher': catcher_rating = await get_position(session, this_play.catcher.card, 'C') this_roll = d_twenty_roll(this_play.catcher.team, this_play.game) + + runner_embed = this_play.batter.team.embed + runner_embed.title = f'{this_play.on_third.player.name} To Home' + runner_embed.description = f'{this_play.catcher.team.abbrev} C {this_play.catcher.player.name} Blocking the Plate' + + runner_embed.add_field( + name='Catcher Range', + value=catcher_rating.range + ) + runner_embed.add_field(name='', value='', inline=False) if catcher_rating.range == 1: safe_range = 3 @@ -1372,11 +1382,43 @@ async def flyballs(session: Session, interaction: discord.Interaction, this_play safe_range = 15 elif catcher_rating.range == 5: safe_range = 19 + + runner_embed.add_field( + name='Safe Range', + value=f'1 - {safe_range}' + ) + out_range = f'{safe_range + 1}' + if safe_range < 19: + out_range += f' - 20' - out_at_home = True - + runner_embed.add_field( + name='Out Range', + value=out_range + ) + await interaction.channel.send( + content=None, + embed=runner_embed + ) + await interaction.channel.send(content=None, embeds=this_roll.embeds) + if this_roll.d_twenty <= safe_range: - out_at_home = False + logger.info(f'Roll of {this_roll.d_twenty} is SAFE {AT_BASE[4]}') + out_at_home = False + q_text = f'Looks like **{runner.name}** is SAFE {AT_BASE[4]}!' + else: + logger.info(f'Roll of {this_roll.d_twenty} is OUT {AT_BASE[4]}') + out_at_home = True + q_text = f'Looks like **{runner.name}** is OUT {AT_BASE[4]}!' + + is_correct = await ask_confirm( + interaction=interaction, + question=f'{q_text} Is that correct?', + label_type='yes' + ) + + if not is_correct: + logger.info(f'{interaction.user.name} says this result is incorrect - setting out_at_home to {not out_at_home}') + out_at_home = not out_at_home if out_at_home: num_outs += 1 @@ -1518,6 +1560,7 @@ async def frame_checks(session: Session, interaction: discord.Interaction, this_ return this_play +@log_errors async def check_uncapped_advance(session: Session, interaction: discord.Interaction, this_play: Play, lead_runner: Lineup, lead_base: int, trail_runner: Lineup, trail_base: int): this_game = this_play.game outfielder = await show_outfield_cards(session, interaction, this_play) @@ -1650,6 +1693,17 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact logger.info(f'Roll of {this_roll.d_twenty} is SAFE {AT_BASE[4]}') runner_thrown_out = False q_text = f'Looks like **{lead_runner.player.name}** is SAFE {AT_BASE[4]}!' + + is_correct = await ask_confirm( + interaction=interaction, + question=f'{q_text} Is that correct?', + label_type='yes' + ) + + if not is_correct: + logger.info(f'{interaction.user.name} says this result is incorrect - setting runner_thrown_out to {not runner_thrown_out}') + runner_thrown_out = not runner_thrown_out + else: runner_thrown_out = await ask_confirm( interaction=interaction, @@ -1940,7 +1994,7 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact else: this_play.on_first_final = lead_base if lead_base == 4: - log_run_scored(session, this_play.on_second, this_play) + log_run_scored(session, this_play.on_first, this_play) else: log_exception(LineupsMissingException, f'Could not find lead runner to set final destination') @@ -2123,10 +2177,22 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact if this_play.on_second == lead_runner: logger.info(f'setting lead runner on_second_final') - this_play.on_second_final = None if runner_thrown_out else lead_base + + if runner_thrown_out: + this_play.on_second_final = None + else: + this_play.on_second_final = lead_base + if lead_base == 4: + log_run_scored(session, this_play.on_second, this_play) elif this_play.on_first == lead_runner: - logger.info(f'setting lead runner on_first') - this_play.on_first_final = None if runner_thrown_out else lead_base + logger.info(f'setting lead runner on_first_final') + + if runner_thrown_out: + this_play.on_first_final = None + else: + this_play.on_first_final = lead_base + if lead_base == 4: + log_run_scored(session, this_play.on_first, this_play) else: log_exception(LineupsMissingException, f'Could not find lead runner to set final destination') @@ -2973,7 +3039,7 @@ async def xchecks(session: Session, interaction: discord.Interaction, this_play: elif hit_result == 'TR' and error_result is None: this_play = await triples(session, interaction, this_play) else: - this_play.ab, this_play.hit, this_play.error, this_play.triple = 1, 1, 1, 1 + this_play.ab, this_play.hit, this_play.error, this_play.run, this_play.triple, this_play.batter_final = 1, 1, 1, 1, 1, 4 this_play = advance_runners(session, this_play, num_bases=4, earned_bases=3) session.add(this_play) diff --git a/in_game/gameplay_queries.py b/in_game/gameplay_queries.py index 398c614..9b243a1 100644 --- a/in_game/gameplay_queries.py +++ b/in_game/gameplay_queries.py @@ -591,6 +591,56 @@ async def get_position(session: Session, this_card: Card, position: Literal['P', log_exception(PositionNotFoundException, f'{position} ratings not found for {this_card.player.name_with_desc}') +async def get_all_positions(session: Session, this_card: Card, skip_cache: bool = False) -> int: + logger.info(f'Pulling all position ratings for {this_card.player.name_with_desc} / skip_cache: {skip_cache}') + + if not skip_cache: + all_pos = session.exec(select(PositionRating).where(PositionRating.player_id == this_card.player.id, PositionRating.variant == this_card.variant)).all() + logger.info(f'Ratings found: {len(all_pos)}') + + should_repull = False + + for position in all_pos: + logger.info(f'we found a cached position rating: {position} / created: {position.created}') + tdelta = datetime.datetime.now() - position.created + logger.debug(f'tdelta: {tdelta}') + if tdelta.total_seconds() >= CACHE_LIMIT: + session.delete(position) + session.commit() + should_repull = True + + if not should_repull: + logger.info(f'Returning {len(all_pos)}') + return len(all_pos) + + p_query = await db_get('cardpositions', params=[('player_id', this_card.player.id)]) + + if p_query['count'] == 0: + logger.info(f'No positions received, returning 0') + return 0 + + def cache_pos(json_data: dict) -> PositionRating: + if 'id' in json_data: + del json_data['id'] + valid_pos = PositionRatingBase.model_validate(json_data, from_attributes=True) + db_pos = PositionRating.model_validate(valid_pos) + session.add(db_pos) + session.commit() + session.refresh(db_pos) + return db_pos + + added_count = 0 + for json_data in p_query['positions']: + logger.info(f'Processing: {json_data}') + json_data['player_id'] = get_player_id_from_dict(json_data['player']) + this_pos = cache_pos(json_data) + + session.add(this_pos) + added_count += 1 + + return added_count + + async def get_or_create_ai_card(session: Session, player: Player, team: Team, skip_cache: bool = False, dev_mode: bool = False) -> Card: logger.info(f'Getting or creating card for {player.name_with_desc} on the {team.sname} / skip_cache: {skip_cache}') if not team.is_ai: