paper-dynasty-discord/cogs/gameplay.py
Cal Corum 97519fc8d5 Move db creation to entry
Nearing completion of new-game mlb-campaign
2024-10-13 00:25:29 -05:00

203 lines
9.5 KiB
Python

import enum
import logging
from typing import Literal
import discord
from discord import app_commands
from discord.app_commands import Choice
from discord.ext import commands
from api_calls import db_get
from helpers import PD_PLAYERS_ROLE_NAME, team_role, user_has_role
from in_game import ai_manager
from in_game.game_helpers import PUBLIC_FIELDS_CATEGORY_NAME, legal_check
from in_game.data_cache import get_pd_team
from in_game.gameplay_models import Lineup, Session, engine, get_player, player_description, select, Game, get_team
from in_game.gameplay_queries import get_channel_game_or_none, get_games_by_team_id
class Gameplay(commands.Cog):
def __init__(self, bot):
self.bot = bot
async def cog_command_error(self, ctx, error):
await ctx.send(f'{error}\n\nRun !help <command_name> to see the command requirements')
async def slash_error(self, ctx, error):
await ctx.send(f'{error[:1600]}')
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')
@app_commands.describe(
sp_card_id='Light gray number to the left of the pitcher\'s name on your depth chart'
)
@app_commands.choices(league=[
Choice(name='minor-league', value='Minor League'),
Choice(name='flashback', value='Flashback'),
Choice(name='major-league', value='Major League'),
Choice(name='hall-of-fame', value='Hall of Fame')
])
@app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME)
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
):
await interaction.response.defer()
with Session(engine) as session:
conflict = get_channel_game_or_none(session, interaction.channel_id)
if conflict is not None:
await interaction.edit_original_response(
content=f'Ope. There is already a game going on in this channel. Please wait for it to complete '
f'before starting a new one.'
)
return
# await interaction.edit_original_response(content=f'Now to check that you\'re in the right channel category...')
if interaction.channel.category is None or interaction.channel.category.name != PUBLIC_FIELDS_CATEGORY_NAME:
await interaction.edit_original_response(
content=f'Why don\'t you head down to one of the Public Fields that way other humans can help if anything '
f'pops up?'
)
return
# await interaction.edit_original_response(content=f'Now to find this away team **{away_team_abbrev.upper()}**')
try:
away_team = await get_team(session, team_abbrev=away_team_abbrev)
except LookupError as e:
await interaction.edit_original_response(
content=f'Hm. I\'m not sure who **{away_team_abbrev}** is - check on that and try again!'
)
return
try:
home_team = await get_team(session, team_abbrev=home_team_abbrev)
except LookupError as e:
await interaction.edit_original_response(
content=f'Hm. I\'m not sure who **{home_team_abbrev}** is - check on that and try again!'
)
return
if not away_team.is_ai ^ home_team.is_ai:
await interaction.edit_original_response(
content=f'I don\'t see an AI team in this MLB Campaign game. Run `/new-game mlb-campaign` again with an AI for a campaign game or `/new-game <ranked / unlimited>` for a PvP game.'
)
return
ai_team = away_team if away_team.is_ai else home_team
human_team = away_team if home_team.is_ai else away_team
conflict_games = get_games_by_team_id(session, team_id=human_team.id)
if len(conflict_games) > 0:
await interaction.edit_original_response(
content=f'Ope. The {human_team.sname} are already playing over in {interaction.guild.get_channel(conflict_games[0].channel_id).mention}'
)
return
current = await db_get('current')
week_num = current['week']
logging.info(f'gameplay - new_game_mlb_campaign - Season: {current["season"]} / Week: {week_num} / Away Team: {away_team.description} / Home Team: {home_team.description}')
def role_error(required_role: str, league_name: str, lower_league: str):
return f'Ope. Looks like you haven\'t received the **{required_role}** role, yet!\n\nTo play **{league_name}** games, you need to defeat all 30 MLB teams in the {lower_league} campaign. You can see your progress with `/record`.\n\nIf you have completed the {lower_league} campaign, go ping Cal to get your new role!'
if league.name == 'flashback':
if not user_has_role(interaction.user, 'PD - Major League'):
await interaction.edit_original_response(
content=role_error('PD - Major League', league_name='Flashback', lower_league='Minor League')
)
return
elif league.name == 'major-league':
if not user_has_role(interaction.user, 'PD - Major League'):
await interaction.edit_original_response(
content=role_error('PD - Major League', league_name='Major League', lower_league='Minor League')
)
return
elif league.name == 'hall-of-fame':
if not user_has_role(interaction.user, 'PD - Hall of Fame'):
await interaction.edit_original_response(
content=role_error('PD - Hall of Fame', league_name='Hall of Fame', lower_league='Major League')
)
return
this_game = Game(
away_team_id=away_team.id,
home_team_id=home_team.id,
channel_id=interaction.channel_id,
season=current['season'],
week_num=week_num,
first_message=None if interaction.message is None else interaction.message.channel.id,
ai_team='away' if away_team.is_ai else 'home',
game_type=league.name
)
# session.add(this_game)
# session.commit()
# session.refresh(this_game)
game_info_log = f'Game {this_game.id} ({league.value}) between {away_team.description} and {home_team.description} / first message: {this_game.first_message}'
logging.info(game_info_log)
await interaction.channel.send(content=game_info_log)
# Get Human SP card
human_sp_card = await db_get('cards', object_id=sp_card_id)
id_key = 'id'
if 'player_id' in human_sp_card['player']:
id_key = 'player_id'
human_sp_player = await get_player(session, human_sp_card['player'][id_key])
if human_sp_card['team']['id'] != human_team.id:
logging.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_player.name} and belongs to {human_sp_card["team"]["sname"]}. Will you double check that before we get started?'
)
return
legal_data = await legal_check([sp_card_id], 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 {player_description(human_sp_player)} is not legal in {league.value} 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_player.id,
card_id=sp_card_id,
position='P',
batting_order=10,
is_fatigued=False,
game=this_game
)
# Get AI SP
await interaction.edit_original_response(
content=f'{ai_team.gmname} is looking for a SP to counter {human_sp_player.name}...'
)
starter = await ai_manager.get_starting_pitcher(
ai_team,
this_game.id,
True if home_team['is_ai'] else False,
league.name
)
# Get AI Lineup
# Commit game and lineups
# session.add(this_game)
# session.commit()
# session.refresh(this_game)
away_role = await team_role(interaction, away_team)
home_role = await team_role(interaction, home_team)
await interaction.channel.send(
content=f'{away_role.mention} @ {home_role.mention} is set!\n\n'
f'Go ahead and set lineups with the `/read-lineup` command!',
# embed=this_game.get_scorebug(full_length=False)
)
async def setup(bot):
await bot.add_cog(Gameplay(bot))