Update gauntlet get SP for new objects

Handle gamestates without full lineups
Added /set command for lineup and SP
Fixed uncapped hit bugs
Added league_name property to Games
Fix get_team for gauntlets
Fixed SelectSP dropdown bug
This commit is contained in:
Cal Corum 2024-12-27 16:12:25 -06:00
parent 3db25b177a
commit 724b8922f2
7 changed files with 225 additions and 78 deletions

View File

@ -1,3 +1,4 @@
import asyncio
import logging
from typing import Literal
@ -8,12 +9,13 @@ from discord.app_commands import Choice
from discord.ext import commands, tasks
import pygsheets
import sqlalchemy
from sqlmodel import or_
from api_calls import db_get
from command_logic.logic_gameplay import advance_runners, bunts, chaos, complete_game, doubles, flyballs, frame_checks, get_full_roster_from_sheets, get_lineups_from_sheets, checks_log_interaction, complete_play, get_scorebug_embed, groundballs, hit_by_pitch, homeruns, is_game_over, lineouts, manual_end_game, new_game_conflicts, popouts, read_lineup, show_defense_cards, singles, starting_pitcher_dropdown_view, steals, strikeouts, sub_batter_dropdown_view, triples, undo_play, update_game_settings, walks, xchecks, activate_last_play
from dice import ab_roll
from exceptions import GameNotFoundException, GoogleSheetsException, TeamNotFoundException, PlayNotFoundException, GameException, log_exception
from exceptions import GameNotFoundException, GoogleSheetsException, LineupsMissingException, TeamNotFoundException, PlayNotFoundException, GameException, log_exception
import gauntlets
from helpers import DEFENSE_LITERAL, PD_PLAYERS_ROLE_NAME, get_channel, team_role, user_has_role, random_gif, random_from_list
@ -21,7 +23,7 @@ from helpers import DEFENSE_LITERAL, PD_PLAYERS_ROLE_NAME, get_channel, team_rol
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 Lineup, Play, Session, engine, player_description, select, Game
from in_game.gameplay_queries import get_position, get_available_pitchers, get_channel_game_or_none, get_active_games_by_team, get_game_lineups, get_team_or_none, get_card_or_none
from in_game.gameplay_queries import get_one_lineup, get_position, get_available_pitchers, 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, ScorebugButtons, ask_confirm
from utilities.dropdown import DropdownView, SelectStartingPitcher
@ -62,7 +64,11 @@ class Gameplay(commands.Cog):
if this_play is None:
logger.info(f'this_play is None, searching for game in channel {interaction.channel.id}')
this_game = get_channel_game_or_none(session, interaction.channel.id)
this_play = activate_last_play(session, this_game)
try:
this_play = activate_last_play(session, this_game)
except Exception as e:
this_play = this_game.initialize_play(session)
if this_play is None:
log_exception(PlayNotFoundException, f'Attempting to display gamestate, but cannot find current play')
@ -312,13 +318,20 @@ class Gameplay(commands.Cog):
await final_message.edit(
content=f'{away_role.mention} @ {home_role.mention} is set!\n\n'
f'Go ahead and set lineups with the `/read-lineup` command!',
f'Go ahead and set your lineup with the `/set lineup` command!',
embed=embed
)
@group_new_game.command(name='gauntlet', description='Start a new Gauntlet game against an AI')
@app_commands.choices(
roster=[
Choice(value='1', name='Primary'),
Choice(value='2', name='Secondary'),
Choice(value='3', name='Ranked')
]
)
@app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME)
async def new_game_gauntlet_command(self, interaction: discord.Interaction):
async def new_game_gauntlet_command(self, interaction: discord.Interaction, roster: Choice[str]):
await interaction.response.defer()
with Session(engine) as session:
@ -401,7 +414,7 @@ class Gameplay(commands.Cog):
logger.info(f'opponent: {ai_team}')
ai_role = await team_role(interaction, ai_team)
human_role = await team_role(interaction, human_team)
human_role = await team_role(interaction, main_team)
away_role = ai_role if is_home else human_role
home_role = human_role if is_home else ai_role
@ -423,22 +436,24 @@ class Gameplay(commands.Cog):
week=current['week'],
first_message=None if interaction.message is None else interaction.message.channel.id,
ai_team='away' if is_home else 'home',
away_roster_id=69 if is_home else int(roster.value),
home_roster_id=int(roster.value) if is_home else 69,
game_type=game_code
)
logger.info(
f'Game {this_game.id} between {human_team.abbrev} and {ai_team.abbrev} is initializing!'
f'Game between {human_team.abbrev} and {ai_team.abbrev} is initializing!'
)
# Get AI SP
await interaction.edit_original_response(
content=f'{ai_team.gmname} is looking for a Starting Pitcher...'
)
ai_sp_lineup = await get_starting_pitcher(
ai_sp_lineup = await gauntlets.get_starting_pitcher(
session,
ai_team,
this_game,
is_home=True if not is_home else False,
league_name=game_code
this_event,
this_run
)
logger.info(f'Chosen SP in Game {this_game.id}: {ai_sp_lineup.player.name_with_desc}')
await interaction.edit_original_response(
@ -454,14 +469,10 @@ class Gameplay(commands.Cog):
session,
team=ai_team,
game=this_game,
league_name=game_code,
league_name=f'gauntlet-{this_event["id"]}',
sp_name=ai_sp_lineup.player.name
)
await interaction.edit_original_response(
content=f'Creating this game for {t_role.mention}:\n{this_game}'
)
# Check for last game settings
logger.info(f'Checking human team\'s automation preferences...')
g_query = session.exec(select(Game).where(or_(Game.home_team == human_team, Game.away_team == human_team)).order_by(Game.id.desc()).limit(1)).all()
@ -491,8 +502,8 @@ class Gameplay(commands.Cog):
# Get pitchers from rosterlinks
done = await get_full_roster_from_sheets(session, interaction, self.sheets, this_game, human_team, 1)
if done:
sp_view = starting_pitcher_dropdown_view(session, this_game, human_team)
await interaction.channel.send(content=f'### {human_team.lname} Starting Pitcher', view=sp_view)
sp_view = starting_pitcher_dropdown_view(session, this_game, human_team, game_type=f'gauntlet-{this_event["id"]}')
sp_message = await interaction.channel.send(content=f'### {human_team.lname} Starting Pitcher', view=sp_view)
await final_message.edit(
content=f'{away_role.mention} @ {home_role.mention} is set!',
@ -535,7 +546,9 @@ class Gameplay(commands.Cog):
else:
await ctx.send(f'It stays. For now.')
@app_commands.command(name='read-lineup', description='Import a saved lineup for this channel\'s PD game.')
group_set_rosters = app_commands.Group(name='set', description='Set SP and lineup')
@group_set_rosters.command(name='lineup', description='Import a saved lineup for this channel\'s PD game.')
@app_commands.describe(
lineup='Which handedness lineup are you using?'
)
@ -563,18 +576,85 @@ class Gameplay(commands.Cog):
await interaction.edit_original_response(content='Bruh. Only GMs of the active teams can pull lineups.')
return
this_play = await read_lineup(
session,
interaction,
this_game=this_game,
lineup_team=this_team,
sheets_auth=self.sheets,
lineup=lineup,
league_name=this_game.game_type
)
logger.info(f'lineup: {lineup} / value: {lineup.value} / name: {lineup.name}')
try:
this_play = await read_lineup(
session,
interaction,
this_game=this_game,
lineup_team=this_team,
sheets_auth=self.sheets,
lineup_num=int(lineup.value),
league_name=this_game.game_type
)
except LineupsMissingException as e:
await interaction.edit_original_response(content='Run `/set starting-pitcher` to select your SP')
return
if this_play is not None:
await self.post_play(session, interaction, this_play)
@group_set_rosters.command(name='starting-pitcher')
@app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME)
async def set_starting_pitcher(self, interaction: discord.Interaction):
await interaction.response.defer()
with Session(engine) as session:
this_game = get_channel_game_or_none(session, interaction.channel_id)
if this_game is None:
await interaction.edit_original_response(
content=f'Hm. I don\'t see a game going on in this channel. Am I drunk?'
)
return
this_team = this_game.human_team
if interaction.user.id != this_team.gmid:
logger.info(f'{interaction.user.name} tried to run a command in Game {this_game.id} when they aren\'t a GM in the game.')
await interaction.edit_original_response(content='Bruh. Only GMs of the active teams can pull lineups.')
return
try:
check_sp = get_one_lineup(session, this_game, this_team, position='P')
except sqlalchemy.exc.NoResultFound as e:
# if 'NoResultFound' not in str(e):
# logger.error(f'Error checking for existing sp: {e}')
# log_exception(e, 'Unable to check your lineup for an existing SP')
# else:
logger.info(f'No pitcher in game, good to go')
check_sp = None
if check_sp is not None:
logger.info(f'Already an SP in Game {this_game.id}, asking if we should swap')
swap_sp = await ask_confirm(
interaction,
question=f'{check_sp.player.name} is already scheduled to start this game - would you like to switch?',
label_type='yes'
)
if not swap_sp:
logger.info(f'No swap being made')
await interaction.edit_original_response(content=f'We will leave {check_sp.player.name} on the lineup card.')
return
session.delete(check_sp)
session.commit()
sp_view = starting_pitcher_dropdown_view(session, this_game, this_team, game_type=this_game.league_name)
await interaction.edit_original_response(content=f'### {this_team.lname} Starting Pitcher', view=sp_view)
await sp_view.wait()
if not sp_view.values:
await interaction.edit_original_response(content=f'Run `/set starting-pitcher` command again to select your SP', view=None)
for x in range(15):
try:
this_play = this_game.initialize_play(session)
await self.post_play(session, interaction, this_play)
return
except LineupsMissingException as e:
logger.info(f'Waiting for SP to be set in game {this_game.id}')
await asyncio.sleep(2)
@app_commands.command(name='gamestate', description='Post the current game state')
async def gamestate_command(self, interaction: discord.Interaction, include_lineups: bool = False):
await interaction.response.defer(ephemeral=True, thinking=True)
@ -588,7 +668,17 @@ class Gameplay(commands.Cog):
return
this_play = this_game.current_play_or_none(session)
await self.post_play(session, interaction, this_play, full_length=include_lineups)
try:
await self.post_play(session, interaction, this_play, full_length=include_lineups)
except LineupsMissingException as e:
logger.info(f'Could not post full scorebug embed, posting lineups')
ai_team = this_game.away_team if this_game.ai_team == 'away' else this_game.home_team
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)
)
@app_commands.command(name='settings-ingame', description='Change in-game settings')
@app_commands.describe(

View File

@ -261,14 +261,14 @@ async def get_scorebug_embed(session: Session, this_game: Game, full_length: boo
return embed
def starting_pitcher_dropdown_view(session: Session, this_game: Game, human_team: Team):
def starting_pitcher_dropdown_view(session: Session, this_game: Game, human_team: Team, game_type: str = None):
pitchers = get_available_pitchers(session, this_game, human_team, sort='starter-desc')
logger.info(f'sorted pitchers: {pitchers}')
sp_selection = SelectStartingPitcher(
this_game=this_game,
this_team=human_team,
session=session,
league_name=this_game.game_type,
league_name=this_game.game_type if game_type is None else game_type,
options=[SelectOption(label=f'{x.player.name_with_desc} (S{x.pitcherscouting.pitchingcard.starter_rating}/R{x.pitcherscouting.pitchingcard.relief_rating})', value=x.id) for x in pitchers],
placeholder='Select your starting pitcher'
)
@ -289,7 +289,7 @@ def sub_batter_dropdown_view(session: Session, this_game: Game, human_team: Team
return DropdownView(dropdown_objects=[bat_selection])
async def read_lineup(session: Session, interaction: discord.Interaction, this_game: Game, lineup_team: Team, sheets_auth, lineup: Choice[str], league_name: str):
async def read_lineup(session: Session, interaction: discord.Interaction, this_game: Game, lineup_team: Team, sheets_auth, lineup_num: int, league_name: str):
"""
Commits lineups and rosterlinks
"""
@ -309,17 +309,10 @@ async def read_lineup(session: Session, interaction: discord.Interaction, this_g
session.add(this_game)
human_lineups = await get_lineups_from_sheets(session, sheets_auth, this_game, this_team=lineup_team, lineup_num=lineup.name, roster_num=this_game.away_roster_id if this_game.home_team.is_ai else this_game.home_roster_id)
human_lineups = await get_lineups_from_sheets(session, sheets_auth, this_game, this_team=lineup_team, lineup_num=lineup_num, roster_num=this_game.away_roster_id if this_game.home_team.is_ai else this_game.home_roster_id)
await interaction.edit_original_response(content='Heard from sheets, pulling in scouting data...')
legal_data = await legal_check([lineup.card.id for lineup in human_lineups], difficulty_name=league_name)
if not legal_data['legal']:
await interaction.edit_original_response(
content=f'It looks like this is a Ranked Legal game and {legal_data["error_string"]} is not legal in {league_name} games. You can start a new game once you update this lineup.'
)
return None
for batter in human_lineups:
session.add(batter)
@ -531,14 +524,15 @@ def complete_play(session:Session, this_play: Play):
async def get_lineups_from_sheets(session: Session, sheets, this_game: Game, this_team: Team, lineup_num: int, roster_num: int) -> list[Lineup]:
logger.debug(f'get_lineups_from_sheets - sheets: {sheets}')
logger.info(f'get_lineups_from_sheets - sheets: {sheets}')
this_sheet = sheets.open_by_key(this_team.gsheet)
logger.debug(f'this_sheet: {this_sheet}')
logger.info(f'this_sheet: {this_sheet}')
r_sheet = this_sheet.worksheet_by_title('My Rosters')
logger.debug(f'r_sheet: {r_sheet}')
logger.info(f'r_sheet: {r_sheet}')
logger.info(f'lineup_num: {roster_num}')
if lineup_num == 1:
row_start = 9
row_end = 17
@ -546,20 +540,21 @@ async def get_lineups_from_sheets(session: Session, sheets, this_game: Game, thi
row_start = 18
row_end = 26
if roster_num == 1:
logger.info(f'roster_num: {roster_num}')
if int(roster_num) == 1:
l_range = f'H{row_start}:I{row_end}'
elif roster_num == 2:
elif int(roster_num) == 2:
l_range = f'J{row_start}:K{row_end}'
else:
l_range = f'L{row_start}:M{row_end}'
logger.debug(f'l_range: {l_range}')
logger.info(f'l_range: {l_range}')
raw_cells = r_sheet.range(l_range)
logger.debug(f'raw_cells: {raw_cells}')
logger.info(f'raw_cells: {raw_cells}')
try:
lineup_cells = [(row[0].value, int(row[1].value)) for row in raw_cells]
logger.debug(f'lineup_cells: {lineup_cells}')
logger.info(f'lineup_cells: {lineup_cells}')
except ValueError as e:
logger.error(f'Could not pull roster for {this_team.abbrev}: {e}')
log_exception(GoogleSheetsException, f'Uh oh. Looks like your lineup might not be saved. I am reading blanks when I try to get the card IDs')
@ -596,7 +591,7 @@ async def get_lineups_from_sheets(session: Session, sheets, this_game: Game, thi
)
all_lineups.append(this_lineup)
legal_data = await legal_check([card_ids], difficulty_name=this_game.game_type)
legal_data = await legal_check([card_ids], difficulty_name=this_game.league_name)
logger.debug(f'legal_data: {legal_data}')
if not legal_data['legal']:
raise CardLegalityException(f'The following cards appear to be illegal for this game mode:\n{legal_data["error_string"]}')
@ -1366,7 +1361,7 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
logger.info(f'trail_safe_range: {trail_safe_range}')
if trail_base == 3 and outfielder.position != 'CF':
of_mod = 2 if outfielder.position == 'LF' else -2
of_mod = -2 if outfielder.position == 'LF' else 2
logger.info(f'{outfielder.position} to 3B mod: {of_mod}')
trail_safe_range += of_mod
@ -1732,7 +1727,7 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
lead_runner_embed.add_field(name='Runner Not Held', value='+1')
logger.info(f'runner was not held, +1 to lead safe range: {lead_safe_range}')
if lead_safe_range > run_resp.min_safe:
if lead_safe_range < run_resp.min_safe:
logger.info(f'AI is not advancing with lead runner')
return this_play
@ -1771,23 +1766,34 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
trail_safe_range += 1
logger.info(f'Trail runner not held, +1 to safe range: {trail_safe_range}')
trail_strings = at_third_strings(trail_safe_range)
trail_runner_embed.add_field(name='', value='', inline=False)
trail_runner_embed.add_field(name='Safe Range', value=trail_strings['safe'])
trail_runner_embed.add_field(name='Out Range', value=trail_strings['out'])
await interaction.channel.send(embeds=[lead_runner_embed, trail_runner_embed])
is_defense_throwing = await ask_confirm(
interaction=interaction,
question=f'{lead_runner.player.name} is advancing {TO_BASE[lead_base]} with a safe range of **1->{safe_range}**! Is the defense throwing?',
question=f'{lead_runner.player.name} is advancing {TO_BASE[lead_base]} with a safe range of **1->{lead_safe_range if lead_base == 3 else {lead_safe_range - 1}}**! Is the defense throwing?',
label_type='yes'
)
# Human defense is throwing for lead runner
# Human defense is not throwing for lead runner
if not is_defense_throwing:
logger.info(f'Defense is not throwing for lead runner')
if this_play.on_second == lead_runner:
this_play.rbi += 1
this_play.on_second_final = 4
log_run_scored(session, lead_runner, this_play)
elif this_play.on_first == lead_runner:
this_play.on_first_final = 3
if this_play.double:
this_play.rbi += 1
this_play.on_first_final = 4
log_run_scored(session, lead_runner, this_play)
else:
this_play.on_first_final = 3
return this_play
@ -1853,6 +1859,7 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
# Ball is going to lead base, ask if safe
logger.info(f'Throw is going to lead base')
await interaction.channel.send(content=None, embeds=this_roll.embeds)
runner_thrown_out = await out_at_home(lead_safe_range) if lead_base == 4 else await out_at_base(lead_safe_range, trail_runner, trail_base)
runner_thrown_out = await ask_confirm(
interaction=interaction,

View File

@ -47,6 +47,10 @@ class PlayNotFoundException(GameException):
pass
class PlayerNotFoundException(GameException):
pass
class PlayInitException(GameException):
pass

View File

@ -8,12 +8,13 @@ import discord
from sqlmodel import Session
from discord import SelectOption
from exceptions import *
from in_game import ai_manager
import helpers
from helpers import RARITY, get_or_create_role, send_to_channel, get_channel
from api_calls import db_get, db_post, db_delete, db_patch
from in_game.gameplay_models import Team
from in_game.gameplay_queries import get_team_or_none
from in_game.gameplay_models import Lineup, Team
from in_game.gameplay_queries import get_player_or_none, get_team_or_none, get_or_create_ai_card, get_player_id_from_dict
from utilities.dropdown import DropdownView, SelectPokemonEvolution
@ -252,22 +253,31 @@ async def build_lineup(this_team, this_game, this_event, sp_name):
return await ai_manager.build_lineup(this_team, this_game.id, f'gauntlet-{this_event["id"]}', sp_name)
async def get_starting_pitcher(this_team, this_game, this_event, this_run):
async def get_starting_pitcher(session, this_team, this_game, this_event, this_run):
sp_rank = (games_played(this_run) % 5) + 1
starter = await db_get(f'teams/{this_team["id"]}/sp/gauntlet-{this_event["id"]}?sp_rank={sp_rank}')
starter = await db_get(f'teams/{this_team.id}/sp/gauntlet-{this_event["id"]}?sp_rank={sp_rank}')
logger.info(f'starter: {starter}')
this_player = await get_player_or_none(session, get_player_id_from_dict(starter))
if this_player is None:
log_exception(PlayerNotFoundException, 'Could not pull the AI\'s starting pitcher')
# get player card; create one if none found
card_id = await ai_manager.get_or_create_card(starter, this_team)
logger.info(f'SP this_player: {this_player}')
this_card = await get_or_create_ai_card(
session,
this_player,
this_team
)
return {
'game_id': this_game.id,
'team_id': this_team['id'],
'player_id': starter['player_id'],
'card_id': card_id,
'position': 'P',
'batting_order': 10,
'after_play': 0
}
return Lineup(
team=this_team,
player=this_player,
card=this_card,
position='P',
batting_order=10,
is_fatigued=False,
game=this_game
)
async def run_draft(interaction: discord.Interaction, main_team: Team, this_event, draft_team: Team = None):

View File

@ -244,6 +244,14 @@ class Game(SQLModel, table=True):
raise NoHumanTeamsException
else:
raise MultipleHumanTeamsException
@property
def league_name(self):
if 'gauntlet' in self.game_type:
parts = self.game_type.split('-')
return f'{parts[0]}-{parts[1]}'
else:
return self.game_type
class ManagerAi(ManagerAiBase, table=True):
@ -300,7 +308,7 @@ class ManagerAi(ManagerAiBase, table=True):
def check_jump(self, session: Session, this_game: Game, to_base: Literal[2, 3, 4]) -> JumpResponse:
logger.info(f'Checking jump to {to_base} in Game {this_game.id}')
this_resp = JumpResponse()
this_resp = JumpResponse(min_safe=20)
this_play = this_game.current_play_or_none(session)
if this_play is None:
raise GameException(f'No game found while checking for jump')
@ -401,7 +409,11 @@ class ManagerAi(ManagerAiBase, table=True):
elif this_play.inning_num > 7 and self.steal >= 5:
this_resp.min_safe = 6
elif self.steal > 5:
this_resp.min_safe = 7
this_resp.min_safe = 7
elif self.steal > 2:
this_resp.min_safe = 8
else:
this_resp.min_safe = 10
runner_card = runner.card.batterscouting.battingcard
jump_safe_range = runner_card.steal_low - 9
@ -434,6 +446,7 @@ class ManagerAi(ManagerAiBase, table=True):
else:
this_resp.min_safe += 2
logger.info(f'tag_from_second response: {this_resp}')
return this_resp
def tag_from_third(self, session: Session, this_game: Game) -> TagResponse:
@ -459,6 +472,7 @@ class ManagerAi(ManagerAiBase, table=True):
if this_play.starting_outs == 1:
this_resp.min_safe -= 2
logger.info(f'tag_from_third response: {this_resp}')
return this_resp
def throw_at_uncapped(self, session: Session, this_game: Game) -> ThrowResponse:
@ -498,6 +512,7 @@ class ManagerAi(ManagerAiBase, table=True):
this_resp.at_trail_runner = True
this_resp.trail_max_safe_delta = -4
logger.info(f'throw_at_uncapped response: {this_resp}')
return this_resp
def uncapped_advance(self, session: Session, this_game: Game, lead_base: int, trail_base: int) -> UncappedRunResponse:
@ -546,6 +561,7 @@ class ManagerAi(ManagerAiBase, table=True):
if this_resp.trail_min_safe < 1:
this_resp.min_safe = 1
logger.info(f'Uncapped advance response: {this_resp}')
return this_resp
def defense_alignment(self, session: Session, this_game: Game) -> DefenseResponse:
@ -611,6 +627,7 @@ class ManagerAi(ManagerAiBase, table=True):
if len(this_resp.ai_note) == 0 and this_play.on_base_code > 0:
this_resp.ai_note += f'- play straight up\n'
logger.info(f'Defense alignment response: {this_resp}')
return this_resp
def gb_decide_run(self, session: Session, this_game: Game) -> RunResponse:
@ -623,6 +640,7 @@ class ManagerAi(ManagerAiBase, table=True):
aggression = self.ahead_aggression - 5 if ai_rd > 0 else self.behind_aggression - 5
this_resp.min_safe = 15 - aggression # TODO: write this algorithm
logger.info(f'gb_decide_run response: {this_resp}')
return this_resp
def gb_decide_throw(self, session: Session, this_game: Game, runner_speed: int, defender_range: int) -> ThrowResponse:
@ -637,6 +655,7 @@ class ManagerAi(ManagerAiBase, table=True):
if (runner_speed - 4 + defender_range) <= (10 + aggression):
this_resp.at_lead_runner = True
logger.info(f'gb_decide_throw response: {this_resp}')
return this_resp

View File

@ -62,6 +62,8 @@ def get_active_games_by_team(session: Session, team: Team) -> list[Game]:
async def get_team_or_none(
session: Session, team_id: int | None = None, gm_id: int | None = None, team_abbrev: str | None = None, skip_cache: bool = False, main_team: bool = None, gauntlet_team: bool = None, include_packs: bool = False) -> Team | None:
logger.info(f'Getting team or none / team_id: {team_id} / gm_id: {gm_id} / team_abbrev: {team_abbrev} / skip_cache: {skip_cache} / main_team: {main_team} / gauntlet_team: {gauntlet_team}')
this_team = None
if gm_id is not None:
if main_team is None and gauntlet_team is None:
main_team = True
@ -69,19 +71,25 @@ async def get_team_or_none(
elif main_team == gauntlet_team:
log_exception(KeyError, 'Must select either main_team or gauntlet_team')
logger.info(f'main_team: {main_team} / gauntlet_team: {gauntlet_team}')
if team_id is None and gm_id is None and team_abbrev is None:
log_exception(KeyError, 'One of "team_id", "gm_id", or "team_abbrev" must be included in search')
if not skip_cache:
if team_id is not None:
logger.info(f'Getting team by team_id: {team_id}')
this_team = session.get(Team, team_id)
else:
if gm_id is not None:
logger.info(f'Getting team by gm_id: {gm_id}')
for team in session.exec(select(Team).where(Team.gmid == gm_id)).all():
if ('gauntlet' in team.abbrev.lower() and gauntlet_team) or ('gauntlet' not in team.abbrev.lower() and main_team):
logger.info(f'Found the team: {team}')
this_team = team
break
logger.info(f'post loop, this_team: {this_team}')
else:
logger.info(f'Getting team by abbrev: {team_abbrev}')
this_team = session.exec(select(Team).where(func.lower(Team.abbrev) == team_abbrev.lower())).one_or_none()
if this_team is not None:
@ -113,8 +121,10 @@ async def get_team_or_none(
elif gm_id is not None:
t_query = await db_get('teams', params=[('gm_id', gm_id), ('inc_packs', include_packs)])
if t_query['count'] != 0:
for team in [x for x in t_query['teams'] if 'gauntlet' not in x['abbrev'].lower()]:
return cache_team(team)
for team in t_query['teams']:
logger.info(f'in t_query loop / team: {team} / gauntlet_team: {gauntlet_team} / main_team: {main_team}')
if (gauntlet_team and 'gauntlet' in team['abbrev'].lower()) or (main_team and 'gauntlet' not in team['abbrev'].lower()):
return cache_team(team)
elif team_abbrev is not None:
t_query = await db_get('teams', params=[('abbrev', team_abbrev), ('inc_packs', include_packs)])
@ -484,10 +494,11 @@ async def get_card_or_none(session: Session, card_id: int, skip_cache: bool = Fa
logger.info(f'Caching card ID {card_id} now')
this_card = cache_card(c_query)
if this_player.pos_1 not in ['SP', 'RP']:
this_card.batterscouting = await shared_get_scouting(session, this_card, 'batter')
else:
all_pos = [x for x in [this_player.pos_1, this_player.pos_2, this_player.pos_3, this_player.pos_3, this_player.pos_4, this_player.pos_5, this_player.pos_6, this_player.pos_7, this_player.pos_8] if x is not None]
if 'SP' in all_pos or 'RP' in all_pos:
this_card.pitcherscouting = await shared_get_scouting(session, this_card, 'pitcher')
if any(item in all_pos for item in ['DH', 'C', '1B', '2B', '3B', 'SS', 'LF', 'CF', 'RF']):
this_card.batterscouting = await shared_get_scouting(session, this_card, 'batter')
session.add(this_card)
session.commit()

View File

@ -107,6 +107,7 @@ class SelectStartingPitcher(discord.ui.Select):
super().__init__(custom_id=custom_id, placeholder=placeholder, options=options)
async def callback(self, interaction: discord.Interaction):
await interaction.response.defer()
logger.info(f'SelectStartingPitcher - selection: {self.values[0]}')
# Get Human SP card
@ -142,11 +143,16 @@ class SelectStartingPitcher(discord.ui.Select):
self.session.add(human_sp_lineup)
self.session.commit()
logger.info(f'trying to delete interaction: {interaction}')
try:
# await interaction.delete_original_response()
await interaction.edit_original_response(
content=f'The {self.team.lname} are starting **{human_sp_card.player.name_with_desc}**!\n\nRun `/set lineup` to import your lineup and `/gamestate` if you are ready to play.',
view=None
)
except Exception as e:
log_exception(e, 'Couldn\'t clean up after selecting sp')
await interaction.response.edit_message(
content=f'The {self.team.lname} are starting **{human_sp_card.player.name_with_desc}**!\n\nRun `/read-lineup` when you are ready to begin.',
view=None
)
class SelectSubPosition(discord.ui.Select):