Added RosterLinks to remove card_id from setup process
Add SelectStartingPitcher dropdown New .sync function
This commit is contained in:
parent
a4af7652fc
commit
073bd04b4b
145
cogs/gameplay.py
145
cogs/gameplay.py
@ -3,23 +3,27 @@ from typing import Literal
|
|||||||
|
|
||||||
import discord
|
import discord
|
||||||
from discord import app_commands
|
from discord import app_commands
|
||||||
|
from discord import SelectOption
|
||||||
from discord.app_commands import Choice
|
from discord.app_commands import Choice
|
||||||
from discord.ext import commands, tasks
|
from discord.ext import commands, tasks
|
||||||
import pygsheets
|
import pygsheets
|
||||||
|
|
||||||
|
from sqlmodel import or_
|
||||||
|
|
||||||
from api_calls import db_get
|
from api_calls import db_get
|
||||||
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, manual_end_game, popouts, show_defense_cards, singles, strikeouts, triples, undo_play, update_game_settings, walks
|
from command_logic.logic_gameplay import advance_runners, bunts, chaos, complete_game, doubles, flyballs, get_full_roster_from_sheets, get_lineups_from_sheets, checks_log_interaction, complete_play, get_scorebug_embed, hit_by_pitch, homeruns, is_game_over, manual_end_game, popouts, read_lineup, show_defense_cards, singles, starting_pitcher_dropdown_view, strikeouts, triples, undo_play, update_game_settings, walks
|
||||||
from dice import ab_roll
|
from dice import ab_roll
|
||||||
from exceptions import GameNotFoundException, TeamNotFoundException, PlayNotFoundException, GameException, log_exception
|
from exceptions import GameNotFoundException, GoogleSheetsException, 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
|
from helpers import DEFENSE_LITERAL, PD_PLAYERS_ROLE_NAME, get_channel, team_role, user_has_role, random_gif, random_from_list
|
||||||
|
|
||||||
# from in_game import ai_manager
|
# from in_game import ai_manager
|
||||||
from in_game.ai_manager import get_starting_pitcher, get_starting_lineup
|
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.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_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 in_game.gameplay_queries import get_and_cache_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.buttons import Confirm, ScorebugButtons, ask_confirm
|
||||||
|
from utilities.dropdown import DropdownView, SelectStartingPitcher
|
||||||
|
|
||||||
|
|
||||||
CLASSIC_EMBED = True
|
CLASSIC_EMBED = True
|
||||||
@ -122,19 +126,22 @@ class Gameplay(commands.Cog):
|
|||||||
group_new_game = app_commands.Group(name='new-game', description='Start a new baseball game')
|
group_new_game = app_commands.Group(name='new-game', description='Start a new baseball game')
|
||||||
|
|
||||||
@group_new_game.command(name='mlb-campaign', description='Start a new MLB campaign game against an AI')
|
@group_new_game.command(name='mlb-campaign', description='Start a new MLB campaign game against an AI')
|
||||||
@app_commands.describe(
|
@app_commands.choices(
|
||||||
sp_card_id='Light gray number to the left of the pitcher\'s name on your depth chart'
|
league=[
|
||||||
|
Choice(value='minor-league', name='Minor League'),
|
||||||
|
Choice(value='flashback', name='Flashback'),
|
||||||
|
Choice(value='major-league', name='Major League'),
|
||||||
|
Choice(value='hall-of-fame', name='Hall of Fame')
|
||||||
|
],
|
||||||
|
roster=[
|
||||||
|
Choice(value='1', name='Primary'),
|
||||||
|
Choice(value='2', name='Secondary'),
|
||||||
|
Choice(value='3', name='Ranked')
|
||||||
|
]
|
||||||
)
|
)
|
||||||
@app_commands.choices(league=[
|
|
||||||
Choice(value='minor-league', name='Minor League'),
|
|
||||||
Choice(value='flashback', name='Flashback'),
|
|
||||||
Choice(value='major-league', name='Major League'),
|
|
||||||
Choice(value='hall-of-fame', name='Hall of Fame')
|
|
||||||
])
|
|
||||||
@app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME)
|
@app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME)
|
||||||
async def new_game_mlb_campaign_command(
|
async def new_game_mlb_campaign_command(
|
||||||
self, interaction: discord.Interaction, league: Choice[str], away_team_abbrev: str, home_team_abbrev: str, sp_card_id: int
|
self, interaction: discord.Interaction, league: Choice[str], away_team_abbrev: str, home_team_abbrev: str, roster: Choice[str]):
|
||||||
):
|
|
||||||
await interaction.response.defer()
|
await interaction.response.defer()
|
||||||
|
|
||||||
with Session(engine) as session:
|
with Session(engine) as session:
|
||||||
@ -212,6 +219,8 @@ class Gameplay(commands.Cog):
|
|||||||
this_game = Game(
|
this_game = Game(
|
||||||
away_team_id=away_team.id,
|
away_team_id=away_team.id,
|
||||||
home_team_id=home_team.id,
|
home_team_id=home_team.id,
|
||||||
|
away_roster_id=69 if away_team.is_ai else int(roster.value),
|
||||||
|
home_roster_id=69 if home_team.is_ai else int(roster.value),
|
||||||
channel_id=interaction.channel_id,
|
channel_id=interaction.channel_id,
|
||||||
season=current['season'],
|
season=current['season'],
|
||||||
week=week_num,
|
week=week_num,
|
||||||
@ -223,44 +232,9 @@ class Gameplay(commands.Cog):
|
|||||||
game_info_log = f'{league.name} game between {away_team.description} and {home_team.description} / first message: {this_game.first_message}'
|
game_info_log = f'{league.name} game between {away_team.description} and {home_team.description} / first message: {this_game.first_message}'
|
||||||
logger.info(game_info_log)
|
logger.info(game_info_log)
|
||||||
|
|
||||||
# Get Human SP card
|
|
||||||
human_sp_card = await get_card_or_none(session, card_id=sp_card_id)
|
|
||||||
if human_sp_card is None:
|
|
||||||
await interaction.channel.send(
|
|
||||||
f'Uh oh. I can\'t find a card with ID {sp_card_id}. Will you double check that before we get started?'
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
if human_sp_card.team_id != human_team.id:
|
|
||||||
logger.error(f'Card_id {sp_card_id} does not belong to {human_team.abbrev} in Game {this_game.id}')
|
|
||||||
await interaction.channel.send(
|
|
||||||
f'Uh oh. Card ID {sp_card_id} is {human_sp_card.player.name} and belongs to {human_sp_card.team.sname}. Will you double check that before we get started?'
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
await get_and_cache_position(session, human_sp_card, 'P')
|
|
||||||
|
|
||||||
legal_data = await legal_check([sp_card_id], difficulty_name=league.value)
|
|
||||||
if not legal_data['legal']:
|
|
||||||
await interaction.edit_original_response(
|
|
||||||
content=f'It looks like this is a Ranked Legal game and {human_sp_card.player.name_with_desc} is not legal in {league.name} games. You can start a new game once you pick a new SP.'
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
human_sp_lineup = Lineup(
|
|
||||||
team_id=human_team.id,
|
|
||||||
player_id=human_sp_card.player.id,
|
|
||||||
card_id=sp_card_id,
|
|
||||||
position='P',
|
|
||||||
batting_order=10,
|
|
||||||
is_fatigued=False,
|
|
||||||
game=this_game
|
|
||||||
)
|
|
||||||
# session.add(human_sp_lineup)
|
|
||||||
|
|
||||||
# Get AI SP
|
# Get AI SP
|
||||||
await interaction.edit_original_response(
|
await interaction.edit_original_response(
|
||||||
content=f'{ai_team.gmname} is looking for a SP to counter {human_sp_card.player.name}...'
|
content=f'{ai_team.gmname} is looking for a Starting Pitcher...'
|
||||||
)
|
)
|
||||||
ai_sp_lineup = await get_starting_pitcher(
|
ai_sp_lineup = await get_starting_pitcher(
|
||||||
session,
|
session,
|
||||||
@ -282,9 +256,17 @@ class Gameplay(commands.Cog):
|
|||||||
team=ai_team,
|
team=ai_team,
|
||||||
game=this_game,
|
game=this_game,
|
||||||
league_name=league.value,
|
league_name=league.value,
|
||||||
sp_name=human_sp_card.player.name
|
sp_name=ai_sp_lineup.player.name
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Check for last game settings
|
||||||
|
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()
|
||||||
|
|
||||||
|
if len(g_query) > 0:
|
||||||
|
last_game = g_query[0]
|
||||||
|
this_game.auto_roll = last_game.auto_roll
|
||||||
|
this_game.roll_buttons = last_game.roll_buttons
|
||||||
|
|
||||||
# Commit game and lineups
|
# Commit game and lineups
|
||||||
session.add(this_game)
|
session.add(this_game)
|
||||||
session.commit()
|
session.commit()
|
||||||
@ -306,6 +288,13 @@ class Gameplay(commands.Cog):
|
|||||||
value=this_game.team_lineup(session, ai_team)
|
value=this_game.team_lineup(session, ai_team)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Get pitchers from rosterlinks
|
||||||
|
done = await get_full_roster_from_sheets(session, interaction, self.sheets, this_game, human_team, roster.value)
|
||||||
|
logger.info(f'done: {done}')
|
||||||
|
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)
|
||||||
|
|
||||||
await final_message.edit(
|
await final_message.edit(
|
||||||
content=f'{away_role.mention} @ {home_role.mention} is set!\n\n'
|
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 lineups with the `/read-lineup` command!',
|
||||||
@ -347,22 +336,16 @@ class Gameplay(commands.Cog):
|
|||||||
|
|
||||||
@app_commands.command(name='read-lineup', description='Import a saved lineup for this channel\'s PD game.')
|
@app_commands.command(name='read-lineup', description='Import a saved lineup for this channel\'s PD game.')
|
||||||
@app_commands.describe(
|
@app_commands.describe(
|
||||||
roster='Which roster to pull from your sheet?',
|
|
||||||
lineup='Which handedness lineup are you using?'
|
lineup='Which handedness lineup are you using?'
|
||||||
)
|
)
|
||||||
@app_commands.choices(
|
@app_commands.choices(
|
||||||
roster=[
|
|
||||||
Choice(value='1', name='Primary'),
|
|
||||||
Choice(value='2', name='Secondary'),
|
|
||||||
Choice(value='3', name='Ranked')
|
|
||||||
],
|
|
||||||
lineup=[
|
lineup=[
|
||||||
Choice(value='1', name='v Right'),
|
Choice(value='1', name='v Right'),
|
||||||
Choice(value='2', name='v Left')
|
Choice(value='2', name='v Left')
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME)
|
@app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME)
|
||||||
async def read_lineup_command(self, interaction: discord.Interaction, roster: Choice[str], lineup: Choice[str]):
|
async def read_lineup_command(self, interaction: discord.Interaction, lineup: Choice[str]):
|
||||||
await interaction.response.defer()
|
await interaction.response.defer()
|
||||||
|
|
||||||
with Session(engine) as session:
|
with Session(engine) as session:
|
||||||
@ -373,48 +356,23 @@ class Gameplay(commands.Cog):
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
lineup_team = this_game.away_team if this_game.ai_team == 'home' else this_game.home_team
|
this_team = this_game.away_team if this_game.ai_team == 'home' else this_game.home_team
|
||||||
if interaction.user.id != lineup_team.gmid:
|
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.')
|
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.')
|
await interaction.edit_original_response(content='Bruh. Only GMs of the active teams can pull lineups.')
|
||||||
return
|
return
|
||||||
|
|
||||||
existing_lineups = get_game_lineups(
|
this_play = await read_lineup(
|
||||||
session=session,
|
session,
|
||||||
|
interaction,
|
||||||
this_game=this_game,
|
this_game=this_game,
|
||||||
specific_team=lineup_team,
|
lineup_team=this_team,
|
||||||
is_active=True
|
sheets_auth=self.sheets,
|
||||||
|
lineup=lineup,
|
||||||
|
league_name=this_game.game_type
|
||||||
)
|
)
|
||||||
if len(existing_lineups) > 1:
|
if this_play is not None:
|
||||||
await interaction.edit_original_response(
|
await self.post_play(session, interaction, this_play)
|
||||||
f'It looks like the {lineup_team.sname} already have a lineup. Run `/substitution` to make changes.'
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
await interaction.edit_original_response(content='Okay, let\'s put this lineup card together...')
|
|
||||||
|
|
||||||
if this_game.away_team == lineup_team:
|
|
||||||
this_game.away_roster_id = int(roster.value)
|
|
||||||
else:
|
|
||||||
this_game.home_roster_id = int(roster.value)
|
|
||||||
|
|
||||||
session.add(this_game)
|
|
||||||
|
|
||||||
human_lineups = await get_lineups_from_sheets(session, self.sheets, this_game, this_team=lineup_team, lineup_num=lineup.name, roster_num=int(roster.value))
|
|
||||||
|
|
||||||
await interaction.edit_original_response(content='Heard from sheets, pulling in scouting data...')
|
|
||||||
|
|
||||||
for batter in human_lineups:
|
|
||||||
session.add(batter)
|
|
||||||
|
|
||||||
session.commit()
|
|
||||||
|
|
||||||
for batter in human_lineups:
|
|
||||||
if batter.position != 'DH':
|
|
||||||
await get_and_cache_position(session, batter.card, batter.position)
|
|
||||||
|
|
||||||
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')
|
@app_commands.command(name='gamestate', description='Post the current game state')
|
||||||
async def gamestate_command(self, interaction: discord.Interaction, include_lineups: bool = False):
|
async def gamestate_command(self, interaction: discord.Interaction, include_lineups: bool = False):
|
||||||
@ -585,7 +543,6 @@ class Gameplay(commands.Cog):
|
|||||||
|
|
||||||
await self.complete_and_post_play(session, interaction, this_play)
|
await self.complete_and_post_play(session, interaction, this_play)
|
||||||
|
|
||||||
|
|
||||||
@group_log.command(name='bunt', description='Bunts: sacrifice, bad, popout, double-play, defense')
|
@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']):
|
async def log_sac_bunt(self, interaction: discord.Interaction, bunt_type: Literal['sacrifice', 'bad', 'popout', 'double-play', 'defense']):
|
||||||
with Session(engine) as session:
|
with Session(engine) as session:
|
||||||
|
|||||||
@ -92,47 +92,46 @@ class Owner(commands.Cog):
|
|||||||
@commands.is_owner()
|
@commands.is_owner()
|
||||||
async def sync(self, ctx: Context, guilds: Greedy[Object], spec: Optional[Literal['~', "*", '!']] = None) -> None:
|
async def sync(self, ctx: Context, guilds: Greedy[Object], spec: Optional[Literal['~', "*", '!']] = None) -> None:
|
||||||
"""
|
"""
|
||||||
!sync -> global sync
|
!sync
|
||||||
!sync ~ -> sync current guild
|
This takes all global commands within the CommandTree and sends them to Discord. (see CommandTree for more info.)
|
||||||
!sync * -> copies all global app commands to current guild and syncs
|
!sync ~
|
||||||
!sync id_1 id_2 -> syncs guilds with id 1 and 2
|
This will sync all guild commands for the current contexts guild.
|
||||||
|
!sync *
|
||||||
|
This command copies all global commands to the current guild (within the CommandTree) and syncs.
|
||||||
|
!sync ^
|
||||||
|
This command will remove all guild commands from the CommandTree and syncs, which effectively removes all commands from the guild.
|
||||||
|
!sync 123 456 789
|
||||||
|
This command will sync the 3 guild ids we passed: 123, 456 and 789. Only their guilds and guild-bound commands.
|
||||||
"""
|
"""
|
||||||
logger.info(f'{ctx.author.name} has initiated a sync from guild ID {ctx.guild.id}')
|
logger.info(f'{ctx.author.name} has initiated a sync from guild ID {ctx.guild.id}')
|
||||||
if not guilds:
|
if not guilds:
|
||||||
if spec == "~":
|
if spec == "~":
|
||||||
fmt = await ctx.bot.tree.sync(guild=ctx.guild)
|
synced = await ctx.bot.tree.sync(guild=ctx.guild)
|
||||||
elif spec == "*":
|
elif spec == "*":
|
||||||
ctx.bot.tree.copy_global_to(guild=ctx.guild)
|
ctx.bot.tree.copy_global_to(guild=ctx.guild)
|
||||||
fmt = await ctx.bot.tree.sync(guild=ctx.guild)
|
synced = await ctx.bot.tree.sync(guild=ctx.guild)
|
||||||
elif spec == '!':
|
elif spec == "^":
|
||||||
fmt = await ctx.bot.tree.sync()
|
ctx.bot.tree.clear_commands(guild=ctx.guild)
|
||||||
await ctx.send(f'Synced {len(fmt)} commands globally.')
|
await ctx.bot.tree.sync(guild=ctx.guild)
|
||||||
|
synced = []
|
||||||
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:
|
else:
|
||||||
fmt = await ctx.bot.tree.sync()
|
synced = await ctx.bot.tree.sync()
|
||||||
|
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
f"Synced {len(fmt)} commands {'globally' if spec is None else 'to the current guild.'}"
|
f"Synced {len(synced)} commands {'globally' if spec is None else 'to the current guild.'}"
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
fmt = 0
|
ret = 0
|
||||||
for guild in guilds:
|
for guild in guilds:
|
||||||
try:
|
try:
|
||||||
await ctx.bot.tree.sync(guild=guild)
|
await ctx.bot.tree.sync(guild=guild)
|
||||||
except discord.HTTPException:
|
except discord.HTTPException:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
fmt += 1
|
ret += 1
|
||||||
|
|
||||||
await ctx.send(f"Synced the tree to {fmt}/{len(guilds)} guilds.")
|
await ctx.send(f"Synced the tree to {ret}/{len(guilds)}.")
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot):
|
async def setup(bot):
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
import discord
|
import discord
|
||||||
|
from discord import SelectOption
|
||||||
|
from discord.app_commands import Choice
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from sqlmodel import Session, select, func
|
from sqlmodel import Session, select, func
|
||||||
from sqlalchemy import delete
|
from sqlalchemy import delete
|
||||||
@ -11,10 +13,10 @@ from api_calls import db_delete, db_get, db_post
|
|||||||
from exceptions import *
|
from exceptions import *
|
||||||
from helpers import DEFENSE_LITERAL, SBA_COLOR, get_channel
|
from helpers import DEFENSE_LITERAL, SBA_COLOR, get_channel
|
||||||
from in_game.game_helpers import legal_check
|
from in_game.game_helpers import legal_check
|
||||||
from in_game.gameplay_models import BattingCard, Game, Lineup, PositionRating, Team, Play
|
from in_game.gameplay_models import BattingCard, Game, Lineup, PositionRating, RosterLink, 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 in_game.gameplay_queries import get_and_cache_position, get_available_pitchers, get_card_or_none, get_channel_game_or_none, get_db_ready_decisions, get_db_ready_plays, get_game_lineups, 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.buttons import ButtonOptions, Confirm, ask_confirm
|
||||||
from utilities.dropdown import DropdownView, SelectViewDefense
|
from utilities.dropdown import DropdownView, SelectStartingPitcher, SelectViewDefense
|
||||||
from utilities.embeds import image_embed
|
from utilities.embeds import image_embed
|
||||||
from utilities.pages import Pagination
|
from utilities.pages import Pagination
|
||||||
|
|
||||||
@ -226,6 +228,63 @@ async def get_scorebug_embed(session: Session, this_game: Game, full_length: boo
|
|||||||
return embed
|
return embed
|
||||||
|
|
||||||
|
|
||||||
|
def starting_pitcher_dropdown_view(session: Session, this_game: Game, human_team: Team):
|
||||||
|
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,
|
||||||
|
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'
|
||||||
|
)
|
||||||
|
return DropdownView(dropdown_objects=[sp_selection])
|
||||||
|
|
||||||
|
|
||||||
|
async def read_lineup(session: Session, interaction: discord.Interaction, this_game: Game, lineup_team: Team, sheets_auth, lineup: Choice[str], league_name: str):
|
||||||
|
"""
|
||||||
|
Commits lineups and rosterlinks
|
||||||
|
"""
|
||||||
|
existing_lineups = get_game_lineups(
|
||||||
|
session=session,
|
||||||
|
this_game=this_game,
|
||||||
|
specific_team=lineup_team,
|
||||||
|
is_active=True
|
||||||
|
)
|
||||||
|
if len(existing_lineups) > 1:
|
||||||
|
await interaction.edit_original_response(
|
||||||
|
f'It looks like the {lineup_team.sname} already have a lineup. Run `/substitution` to make changes.'
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
await interaction.edit_original_response(content='Okay, let\'s put this lineup card together...')
|
||||||
|
|
||||||
|
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.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)
|
||||||
|
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
for batter in human_lineups:
|
||||||
|
if batter.position != 'DH':
|
||||||
|
await get_and_cache_position(session, batter.card, batter.position)
|
||||||
|
|
||||||
|
return this_game.initialize_play(session)
|
||||||
|
|
||||||
|
|
||||||
def get_obc(on_first = None, on_second = None, on_third = None) -> int:
|
def get_obc(on_first = None, on_second = None, on_third = None) -> int:
|
||||||
if on_third is not None:
|
if on_third is not None:
|
||||||
if on_second is not None:
|
if on_second is not None:
|
||||||
@ -415,7 +474,7 @@ 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]:
|
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'sheets: {sheets}')
|
logger.debug(f'get_lineups_from_sheets - sheets: {sheets}')
|
||||||
|
|
||||||
this_sheet = sheets.open_by_key(this_team.gsheet)
|
this_sheet = sheets.open_by_key(this_team.gsheet)
|
||||||
logger.debug(f'this_sheet: {this_sheet}')
|
logger.debug(f'this_sheet: {this_sheet}')
|
||||||
@ -446,7 +505,7 @@ async def get_lineups_from_sheets(session: Session, sheets, this_game: Game, thi
|
|||||||
logger.debug(f'lineup_cells: {lineup_cells}')
|
logger.debug(f'lineup_cells: {lineup_cells}')
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
logger.error(f'Could not pull roster for {this_team.abbrev}: {e}')
|
logger.error(f'Could not pull roster for {this_team.abbrev}: {e}')
|
||||||
raise ValueError(f'Uh oh. Looks like your roster might not be saved. I am reading blanks when I try to get the card IDs')
|
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')
|
||||||
|
|
||||||
all_lineups = []
|
all_lineups = []
|
||||||
all_pos = []
|
all_pos = []
|
||||||
@ -491,10 +550,60 @@ async def get_lineups_from_sheets(session: Session, sheets, this_game: Game, thi
|
|||||||
return all_lineups
|
return all_lineups
|
||||||
|
|
||||||
|
|
||||||
|
async def get_full_roster_from_sheets(session: Session, interaction: discord.Interaction, sheets, this_game: Game, this_team: Team, roster_num: int) -> list[RosterLink]:
|
||||||
|
"""
|
||||||
|
Commits roster links
|
||||||
|
"""
|
||||||
|
logger.debug(f'get_full_roster_from_sheets - sheets: {sheets}')
|
||||||
|
|
||||||
|
this_sheet = sheets.open_by_key(this_team.gsheet)
|
||||||
|
|
||||||
|
this_sheet = sheets.open_by_key(this_team.gsheet)
|
||||||
|
logger.debug(f'this_sheet: {this_sheet}')
|
||||||
|
|
||||||
|
r_sheet = this_sheet.worksheet_by_title('My Rosters')
|
||||||
|
logger.debug(f'r_sheet: {r_sheet}')
|
||||||
|
|
||||||
|
if roster_num == 1:
|
||||||
|
l_range = 'B3:B28'
|
||||||
|
elif roster_num == 2:
|
||||||
|
l_range = 'B29:B54'
|
||||||
|
else:
|
||||||
|
l_range = 'B55:B80'
|
||||||
|
|
||||||
|
roster_message = await interaction.channel.send(content='I\'m diving into Sheets - wish me luck.')
|
||||||
|
|
||||||
|
logger.info(f'l_range: {l_range}')
|
||||||
|
raw_cells = r_sheet.range(l_range)
|
||||||
|
logger.info(f'raw_cells: {raw_cells}')
|
||||||
|
|
||||||
|
await roster_message.edit(content='Got your roster, now to find these cards in your collection...')
|
||||||
|
|
||||||
|
try:
|
||||||
|
card_ids = [row[0].value for row in raw_cells]
|
||||||
|
logger.info(f'card_ids: {card_ids}')
|
||||||
|
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 roster might not be saved. I am reading blanks when I try to get the card IDs')
|
||||||
|
|
||||||
|
for x in card_ids:
|
||||||
|
this_card = await get_card_or_none(session, card_id=x)
|
||||||
|
session.add(RosterLink(
|
||||||
|
game=this_game,
|
||||||
|
card=this_card,
|
||||||
|
team=this_team
|
||||||
|
))
|
||||||
|
|
||||||
|
session.commit()
|
||||||
|
await roster_message.edit(content='Your roster is logged and scouting data is available.')
|
||||||
|
return session.exec(select(RosterLink).where(RosterLink.game == this_game, RosterLink.team == this_team)).all()
|
||||||
|
|
||||||
|
|
||||||
async def checks_log_interaction(session: Session, interaction: discord.Interaction, command_name: str) -> tuple[Game, Team, Play]:
|
async def checks_log_interaction(session: Session, interaction: discord.Interaction, command_name: str) -> tuple[Game, Team, Play]:
|
||||||
"""
|
"""
|
||||||
Commits this_play
|
Commits this_play
|
||||||
"""
|
"""
|
||||||
|
logger.info(f'log interaction checks for {interaction.user.name} in channel {interaction.channel.name}')
|
||||||
await interaction.response.defer(thinking=True)
|
await interaction.response.defer(thinking=True)
|
||||||
this_game = get_channel_game_or_none(session, interaction.channel_id)
|
this_game = get_channel_game_or_none(session, interaction.channel_id)
|
||||||
if this_game is None:
|
if this_game is None:
|
||||||
|
|||||||
@ -31,6 +31,10 @@ class CardLegalityException(GameException):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class CardNotFoundException(GameException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class GameNotFoundException(GameException):
|
class GameNotFoundException(GameException):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -65,3 +69,7 @@ class MultipleHumanTeamsException(GameException):
|
|||||||
|
|
||||||
class NoHumanTeamsException(GameException):
|
class NoHumanTeamsException(GameException):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class GoogleSheetsException(GameException):
|
||||||
|
pass
|
||||||
|
|||||||
@ -47,6 +47,16 @@ class GameCardsetLink(SQLModel, table=True):
|
|||||||
cardset: 'Cardset' = Relationship(back_populates='game_links')
|
cardset: 'Cardset' = Relationship(back_populates='game_links')
|
||||||
|
|
||||||
|
|
||||||
|
class RosterLink(SQLModel, table=True):
|
||||||
|
game_id: int | None = Field(default=None, foreign_key='game.id', primary_key=True)
|
||||||
|
card_id: int | None = Field(default=None, foreign_key='card.id', primary_key=True)
|
||||||
|
team_id: int = Field(index=True, foreign_key='team.id')
|
||||||
|
|
||||||
|
game: 'Game' = Relationship(back_populates='roster_links')
|
||||||
|
card: 'Card' = Relationship()
|
||||||
|
team: 'Team' = Relationship()
|
||||||
|
|
||||||
|
|
||||||
class TeamBase(SQLModel):
|
class TeamBase(SQLModel):
|
||||||
id: int = Field(primary_key=True)
|
id: int = Field(primary_key=True)
|
||||||
abbrev: str = Field(index=True)
|
abbrev: str = Field(index=True)
|
||||||
@ -110,6 +120,7 @@ class Game(SQLModel, table=True):
|
|||||||
auto_roll: bool | None = Field(default=False)
|
auto_roll: bool | None = Field(default=False)
|
||||||
|
|
||||||
cardset_links: list[GameCardsetLink] = Relationship(back_populates='game', cascade_delete=True)
|
cardset_links: list[GameCardsetLink] = Relationship(back_populates='game', cascade_delete=True)
|
||||||
|
roster_links: list[RosterLink] = Relationship(back_populates='game', cascade_delete=True)
|
||||||
away_team: Team = Relationship(
|
away_team: Team = Relationship(
|
||||||
# back_populates='away_games',
|
# back_populates='away_games',
|
||||||
# sa_relationship_kwargs={
|
# sa_relationship_kwargs={
|
||||||
|
|||||||
@ -6,7 +6,8 @@ from typing import Literal
|
|||||||
import pydantic
|
import pydantic
|
||||||
from sqlalchemy import func
|
from sqlalchemy import func
|
||||||
from api_calls import db_get, db_post
|
from api_calls import db_get, db_post
|
||||||
from in_game.gameplay_models import CACHE_LIMIT, BatterScouting, BatterScoutingBase, BattingCard, BattingCardBase, BattingRatings, BattingRatingsBase, Card, CardBase, Lineup, PitcherScouting, PitchingCard, PitchingCardBase, PitchingRatings, PitchingRatingsBase, Player, PlayerBase, PositionRating, PositionRatingBase, Session, Team, TeamBase, select, or_, Game, Play
|
from sqlmodel import col
|
||||||
|
from in_game.gameplay_models import CACHE_LIMIT, BatterScouting, BatterScoutingBase, BattingCard, BattingCardBase, BattingRatings, BattingRatingsBase, Card, CardBase, Lineup, PitcherScouting, PitchingCard, PitchingCardBase, PitchingRatings, PitchingRatingsBase, Player, PlayerBase, PositionRating, PositionRatingBase, RosterLink, Session, Team, TeamBase, select, or_, Game, Play
|
||||||
from exceptions import DatabaseError, PositionNotFoundException, log_exception, PlayNotFoundException
|
from exceptions import DatabaseError, PositionNotFoundException, log_exception, PlayNotFoundException
|
||||||
|
|
||||||
|
|
||||||
@ -797,3 +798,36 @@ async def post_game_rewards(session: Session, winning_team: Team, losing_team: T
|
|||||||
await db_post(f'teams/{losing_team.id}/money/{loss_reward["money"]}')
|
await db_post(f'teams/{losing_team.id}/money/{loss_reward["money"]}')
|
||||||
|
|
||||||
return win_string, loss_string
|
return win_string, loss_string
|
||||||
|
|
||||||
|
|
||||||
|
def get_available_subs(session: Session, this_game: Game, this_team: Team) -> list[Card]:
|
||||||
|
team_lineups = session.exec(select(Lineup).where(Lineup.game == this_game, Lineup.team == this_team)).all()
|
||||||
|
used_card_ids = [x.card.id for x in team_lineups]
|
||||||
|
|
||||||
|
all_roster_links = session.exec(select(RosterLink).where(RosterLink.game == this_game, RosterLink.team == this_team)).all()
|
||||||
|
|
||||||
|
return [x.card for x in all_roster_links if x.card_id not in used_card_ids]
|
||||||
|
|
||||||
|
|
||||||
|
def get_available_pitchers(session: Session, this_game: Game, this_team: Team, sort: Literal['starter-desc', 'closer-desc'] = 'closer-desc') -> list[Card]:
|
||||||
|
logger.info(f'getting available pitchers for team {this_team.id} in game {this_game.id}')
|
||||||
|
all_subs = get_available_subs(session, this_game, this_team)
|
||||||
|
logger.info(f'all_subs: {all_subs}')
|
||||||
|
pitchers = [x for x in all_subs if x.pitcherscouting is not None]
|
||||||
|
logger.info(f'pitchers: {pitchers}')
|
||||||
|
|
||||||
|
def sort_by_pow(this_card: Card):
|
||||||
|
s_pow = this_card.pitcherscouting.pitchingcard.starter_rating
|
||||||
|
r_pow = this_card.pitcherscouting.pitchingcard.relief_rating
|
||||||
|
c_pow = this_card.pitcherscouting.pitchingcard.closer_rating
|
||||||
|
|
||||||
|
if sort == 'starter-desc':
|
||||||
|
r_val = (s_pow * 3) + r_pow
|
||||||
|
else:
|
||||||
|
r_val = (c_pow * 10) - (r_pow * 5) - (s_pow * 3)
|
||||||
|
|
||||||
|
return r_val
|
||||||
|
|
||||||
|
pitchers.sort(key=sort_by_pow, reverse=True)
|
||||||
|
|
||||||
|
return pitchers
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import pytest
|
import pytest
|
||||||
from sqlmodel import Session, SQLModel, create_engine
|
from sqlmodel import Session, SQLModel, create_engine, select
|
||||||
from sqlmodel.pool import StaticPool
|
from sqlmodel.pool import StaticPool
|
||||||
|
|
||||||
from typing import Literal
|
from typing import Literal
|
||||||
from in_game.gameplay_models import BatterScouting, BattingCard, BattingRatings, Card, Cardset, Game, GameCardsetLink, Lineup, ManagerAi, PitcherScouting, PitchingCard, PitchingRatings, Play, Team, Player
|
from in_game.gameplay_models import BatterScouting, BattingCard, BattingRatings, Card, Cardset, Game, GameCardsetLink, Lineup, ManagerAi, PitcherScouting, PitchingCard, PitchingRatings, Play, RosterLink, Team, Player
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name='session')
|
@pytest.fixture(name='session')
|
||||||
@ -231,6 +231,30 @@ def session_fixture():
|
|||||||
|
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
|
g1_t1_cards = session.exec(select(Card).where(Card.team_id == 31)).all()
|
||||||
|
g1_t2_cards = session.exec(select(Card).where(Card.team_id == 400)).all()
|
||||||
|
g2_t1_cards = session.exec(select(Card).where(Card.team_id == 69)).all()
|
||||||
|
g2_t2_cards = session.exec(select(Card).where(Card.team_id == 420)).all()
|
||||||
|
|
||||||
|
for card in [*g1_t1_cards, *g1_t2_cards]:
|
||||||
|
session.add(RosterLink(
|
||||||
|
game_id=1,
|
||||||
|
card_id=card.id,
|
||||||
|
team_id=card.team_id
|
||||||
|
))
|
||||||
|
for card in [*g2_t1_cards, *g2_t2_cards]:
|
||||||
|
session.add(RosterLink(
|
||||||
|
game_id=3,
|
||||||
|
card_id=card.id,
|
||||||
|
team_id=card.team_id
|
||||||
|
))
|
||||||
|
# session.add(RosterLink(
|
||||||
|
# game_id=3,
|
||||||
|
# card_id=12,
|
||||||
|
# team_id=420
|
||||||
|
# ))
|
||||||
|
|
||||||
|
session.commit()
|
||||||
all_ai = ManagerAi.create_ai(session)
|
all_ai = ManagerAi.create_ai(session)
|
||||||
|
|
||||||
yield session
|
yield session
|
||||||
|
|||||||
@ -109,19 +109,19 @@ def test_delete_game(session: Session):
|
|||||||
assert len(bad_links) == 0
|
assert len(bad_links) == 0
|
||||||
|
|
||||||
|
|
||||||
async def test_get_scorebug(session: Session):
|
# async def test_get_scorebug(session: Session):
|
||||||
game_1 = session.get(Game, 1)
|
# 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)
|
# scorebug = await get_scorebug_embed(session, game_1)
|
||||||
|
|
||||||
assert scorebug.title == 'CornBelters @ Black Bears - Minor League'
|
# assert scorebug.title == 'CornBelters @ Black Bears - Minor League'
|
||||||
assert scorebug.color.value == int('a6ce39', 16)
|
# assert scorebug.color.value == int('a6ce39', 16)
|
||||||
|
|
||||||
game_3 = session.get(Game, 3)
|
# 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)
|
# scorebug = await get_scorebug_embed(session, game_3)
|
||||||
|
|
||||||
assert '0 Outs' in scorebug.fields[0].value
|
# assert '0 Outs' in scorebug.fields[0].value
|
||||||
|
|
||||||
|
|
||||||
def test_sum_function(session: Session):
|
def test_sum_function(session: Session):
|
||||||
|
|||||||
32
tests/gameplay_models/test_rosterlinks_model.py
Normal file
32
tests/gameplay_models/test_rosterlinks_model.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import pytest
|
||||||
|
from sqlmodel import Session, select, func
|
||||||
|
|
||||||
|
from in_game.gameplay_models import Game, RosterLink
|
||||||
|
from in_game.gameplay_queries import get_available_subs
|
||||||
|
from tests.factory import session_fixture
|
||||||
|
|
||||||
|
def test_get_rosterlinks(session: Session):
|
||||||
|
game_1 = session.get(Game, 1)
|
||||||
|
g1_links = session.exec(select(RosterLink).where(RosterLink.game == game_1)).all()
|
||||||
|
|
||||||
|
assert len(g1_links) == 20
|
||||||
|
|
||||||
|
home_team = game_1.home_team
|
||||||
|
home_roster = session.exec(select(RosterLink).where(RosterLink.game == game_1, RosterLink.team == home_team)).all()
|
||||||
|
|
||||||
|
assert len(home_roster) == 10
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_available_subs(session: Session):
|
||||||
|
this_game = session.get(Game, 3)
|
||||||
|
home_team = this_game.home_team
|
||||||
|
home_roster = session.exec(select(RosterLink).where(RosterLink.game == this_game, RosterLink.team == home_team)).all()
|
||||||
|
|
||||||
|
assert len(home_roster) == 11
|
||||||
|
|
||||||
|
cards = get_available_subs(session, this_game, this_game.home_team)
|
||||||
|
|
||||||
|
assert len(cards) == 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,9 +1,15 @@
|
|||||||
|
from typing import List
|
||||||
import discord
|
import discord
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from discord import SelectOption
|
||||||
|
from discord.utils import MISSING
|
||||||
from sqlmodel import Session
|
from sqlmodel import Session
|
||||||
|
|
||||||
from in_game.gameplay_models import Lineup, Play
|
from exceptions import CardNotFoundException, log_exception
|
||||||
|
from in_game.game_helpers import legal_check
|
||||||
|
from in_game.gameplay_models import Game, Lineup, Play, Team
|
||||||
|
from in_game.gameplay_queries import get_and_cache_position, get_card_or_none
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger('discord_app')
|
logger = logging.getLogger('discord_app')
|
||||||
@ -84,3 +90,59 @@ class SelectViewDefense(discord.ui.Select):
|
|||||||
)
|
)
|
||||||
|
|
||||||
await interaction.response.edit_message(content=None, embed=self.embed, view=new_view)
|
await interaction.response.edit_message(content=None, embed=self.embed, view=new_view)
|
||||||
|
|
||||||
|
|
||||||
|
class SelectStartingPitcher(discord.ui.Select):
|
||||||
|
def __init__(self, this_game: Game, this_team: Team, session: Session, league_name: str, custom_id: str = MISSING, placeholder: str | None = None, options: List[SelectOption] = ...) -> None:
|
||||||
|
logger.info(f'Inside SelectStartingPitcher init function')
|
||||||
|
self.game = this_game
|
||||||
|
self.team = this_team
|
||||||
|
self.session = session
|
||||||
|
self.league_name = league_name
|
||||||
|
super().__init__(custom_id=custom_id, placeholder=placeholder, options=options)
|
||||||
|
|
||||||
|
async def callback(self, interaction: discord.Interaction):
|
||||||
|
logger.info(f'SelectStartingPitcher - selection: {self.values[0]}')
|
||||||
|
|
||||||
|
# Get Human SP card
|
||||||
|
human_sp_card = await get_card_or_none(self.session, card_id=self.values[0])
|
||||||
|
if human_sp_card is None:
|
||||||
|
log_exception(CardNotFoundException, f'Card ID {self.values[0]} not found')
|
||||||
|
|
||||||
|
if human_sp_card.team_id != self.team.id:
|
||||||
|
logger.error(f'Card_id {self.values[0]} does not belong to {self.team.abbrev} in Game {self.game.id}')
|
||||||
|
await interaction.channel.send(
|
||||||
|
f'Uh oh. Card ID {self.values[0]} is {human_sp_card.player.name} and belongs to {human_sp_card.team.sname}. Will you double check that before we get started?'
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
await get_and_cache_position(self.session, human_sp_card, 'P')
|
||||||
|
|
||||||
|
legal_data = await legal_check([self.values[0]], difficulty_name=self.league_name)
|
||||||
|
if not legal_data['legal']:
|
||||||
|
await interaction.edit_original_response(
|
||||||
|
content=f'It looks like this is a Ranked Legal game and {human_sp_card.player.name_with_desc} is not legal in {self.league_name} games. You can start a new game once you pick a new SP.'
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
human_sp_lineup = Lineup(
|
||||||
|
team_id=self.team.id,
|
||||||
|
player_id=human_sp_card.player.id,
|
||||||
|
card_id=self.values[0],
|
||||||
|
position='P',
|
||||||
|
batting_order=10,
|
||||||
|
is_fatigued=False,
|
||||||
|
game=self.game
|
||||||
|
)
|
||||||
|
self.session.add(human_sp_lineup)
|
||||||
|
self.session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
await interaction.response.edit_message(
|
||||||
|
content=f'The {self.team.lname} are starting {human_sp_card.player.name_with_desc}',
|
||||||
|
view=None
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user