Player description update & bugfixes

Fixed trail runners not advancing for uncapped doubles and steals of home
This commit is contained in:
Cal Corum 2023-10-21 15:30:14 -05:00
parent baf8ddb664
commit 72d6129b17
6 changed files with 382 additions and 291 deletions

View File

@ -18,20 +18,18 @@ db = SqliteDatabase(
}
)
# 2022, 2023, Mario
MINOR_CARDSET_PARAMS = [('cardset_id', 8), ('cardset_id', 9), ('cardset_id', 3)]
# 2018, Mario
MINOR_CARDSET_PARAMS = [('cardset_id', 8), ('cardset_id', 13)]
# 2013, 2019, 2022, 2023, Mario
# 2018, 2023, Mario, 2013
MAJOR_CARDSET_PARAMS = [
('cardset_id', 8), ('cardset_id', 6), ('cardset_id', 5),
('cardset_id', 3), ('cardset_id', 4),
('cardset_id', 9), ('cardset_id', 10)
('cardset_id', 9), ('cardset_id', 8), ('cardset_id', 6), ('cardset_id', 13)
]
# 2008, 2012, 2013, 2016, 2019, 2021, 2022, 2023, Mario
HOF_CARDSET_PARAMS = [
('cardset_id', 1), ('cardset_id', 3), ('cardset_id', 4), ('cardset_id', 5), ('cardset_id', 6), ('cardset_id', 7),
('cardset_id', 8), ('cardset_id', 9), ('cardset_id', 10), ('cardset_id', 11), ('cardset_id', 12)
('cardset_id', 8), ('cardset_id', 9), ('cardset_id', 10), ('cardset_id', 11), ('cardset_id', 12), ('cardset_id', 13)
]
# 2008, 2012, 2013, 2016
@ -223,101 +221,104 @@ async def build_lineup_graded(team_object: dict, vs_hand: str, league_name: str,
return batting_order
async def build_lineup(team_object: dict, game_id: int, league_name: str, vs_hand: str = 'r') -> list:
players = {
'C': None,
'1B': None,
'2B': None,
'3B': None,
'SS': None,
'LF': None,
'CF': None,
'RF': None,
'DH': None
}
p_names = []
rest_name = None
async def build_lineup(team_object: dict, game_id: int, league_name: str, sp_name: str, vs_hand: str = 'r') -> list:
# players = {
# 'C': None,
# '1B': None,
# '2B': None,
# '3B': None,
# 'SS': None,
# 'LF': None,
# 'CF': None,
# 'RF': None,
# 'DH': None
# }
# p_names = []
# rest_name = None
#
# set_params = [('cardset_id_exclude', 2)]
# if team_object['id'] == 58:
# set_params = []
# elif league_name == 'minor-league':
# set_params = copy.deepcopy(MINOR_CARDSET_PARAMS)
# elif league_name == 'major-league':
# set_params = copy.deepcopy(MAJOR_CARDSET_PARAMS)
# elif league_name == 'hall-of-fame':
# set_params = copy.deepcopy(HOF_CARDSET_PARAMS)
# elif 'gauntlet-1' in league_name:
# set_params = copy.deepcopy(MINOR_CARDSET_PARAMS)
# elif 'gauntlet-2' in league_name:
# set_params = random.sample(GAUNTLET2_PARAMS, 2)
#
# # Pull players sorted by current cost
# try:
# params = [
# ('mlbclub', team_object['lname']), ('pos_include', 'C'), ('pos_include', '1B'), ('pos_include', '2B'),
# ('pos_include', '3B'), ('pos_include', 'SS'), ('pos_include', 'LF'), ('pos_include', 'CF'),
# ('pos_include', 'RF'), ('pos_include', 'DH'), ('inc_dex', False), ('sort_by', 'cost-desc'), ('limit', 50)
# ]
# params.extend(set_params)
# p_query = await db_get(
# endpoint='players',
# params=params,
# timeout=10
# )
# all_players = p_query['players']
# except ConnectionError as e:
# raise ConnectionError(f'Error pulling batters for the {team_object["lname"]}. Cal help plz.')
#
# logging.info(f'build_lineup - eligible batter count: {len(all_players)}')
#
# # Choose starting nine & position
# # In order of cost:
# # Try to add to pos_1; if unavailable, try remaining pos; if unavailable, add to DH
# # If all pos unavailable; note player's pos_1 and check if incumbent can move; if so, check for new incumbent
# # and recurse
# # If not possible, pass player and continue
# for guy in all_players:
# placed = False
# if guy['p_name'] not in p_names and guy['p_name'] != rest_name:
# for pos in [
# guy['pos_1'], guy['pos_2'], guy['pos_3'], guy['pos_4'], guy['pos_5'], guy['pos_6'], guy['pos_7'],
# guy['pos_8']
# ]:
# if pos is None or pos in ['SP', 'RP', 'CP']:
# break
#
# if random.randint(1, 10) == 10 and rest_name is None and False:
# logging.info(f'Resting {guy["p_name"]} in game {game_id}')
# rest_name = guy['p_name']
# elif players[pos] is None:
# players[pos] = guy
# p_names.append(guy["p_name"])
# placed = True
# break
#
# if not placed and rest_name != guy['p_name']:
# if players['DH'] is None:
# players['DH'] = guy
# p_names.append(guy["p_name"])
# else:
# logging.info(f'build_lineup - could not place {guy["p_name"]} in {team_object["sname"]} lineup')
# else:
# logging.info(f'build_lineup - {guy["p_name"]} already in lineup')
#
# if None in players.values():
# bad_pos = {x for x in players if players[x] is None}
# raise ValueError(f'Could not find a {bad_pos} for the {team_object["sname"]}')
#
# logging.info(f'build_lineup - {players}')
#
# # Sort players into lineup
# # Pseudo-random? Patterns? Something to mix up lineups
# # 421356789 or [123 (rand)][456 (rand)][789 (rand)] (optional: chance to flip 3/4 and 6/7)
#
# # [ (<pos>, <player_obj>), (<pos>, <player_obj>), etc. ]
# sorted_players = sorted(players.items(), key=lambda x: x[1]['cost'], reverse=True)
set_params = [('cardset_id_exclude', 2)]
if team_object['id'] == 58:
set_params = []
elif league_name == 'minor-league':
set_params = copy.deepcopy(MINOR_CARDSET_PARAMS)
elif league_name == 'major-league':
set_params = copy.deepcopy(MAJOR_CARDSET_PARAMS)
elif league_name == 'hall-of-fame':
set_params = copy.deepcopy(HOF_CARDSET_PARAMS)
elif 'gauntlet-1' in league_name:
set_params = copy.deepcopy(MINOR_CARDSET_PARAMS)
elif 'gauntlet-2' in league_name:
set_params = random.sample(GAUNTLET2_PARAMS, 2)
# Pull players sorted by current cost
try:
params = [
('mlbclub', team_object['lname']), ('pos_include', 'C'), ('pos_include', '1B'), ('pos_include', '2B'),
('pos_include', '3B'), ('pos_include', 'SS'), ('pos_include', 'LF'), ('pos_include', 'CF'),
('pos_include', 'RF'), ('pos_include', 'DH'), ('inc_dex', False), ('sort_by', 'cost-desc'), ('limit', 50)
]
params.extend(set_params)
p_query = await db_get(
endpoint='players',
params=params,
timeout=10
)
all_players = p_query['players']
except ConnectionError as e:
raise ConnectionError(f'Error pulling batters for the {team_object["lname"]}. Cal help plz.')
logging.info(f'build_lineup - eligible batter count: {len(all_players)}')
# Choose starting nine & position
# In order of cost:
# Try to add to pos_1; if unavailable, try remaining pos; if unavailable, add to DH
# If all pos unavailable; note player's pos_1 and check if incumbent can move; if so, check for new incumbent
# and recurse
# If not possible, pass player and continue
for guy in all_players:
placed = False
if guy['p_name'] not in p_names and guy['p_name'] != rest_name:
for pos in [
guy['pos_1'], guy['pos_2'], guy['pos_3'], guy['pos_4'], guy['pos_5'], guy['pos_6'], guy['pos_7'],
guy['pos_8']
]:
if pos is None or pos in ['SP', 'RP', 'CP']:
break
if random.randint(1, 10) == 10 and rest_name is None and False:
logging.info(f'Resting {guy["p_name"]} in game {game_id}')
rest_name = guy['p_name']
elif players[pos] is None:
players[pos] = guy
p_names.append(guy["p_name"])
placed = True
break
if not placed and rest_name != guy['p_name']:
if players['DH'] is None:
players['DH'] = guy
p_names.append(guy["p_name"])
else:
logging.info(f'build_lineup - could not place {guy["p_name"]} in {team_object["sname"]} lineup')
else:
logging.info(f'build_lineup - {guy["p_name"]} already in lineup')
if None in players.values():
bad_pos = {x for x in players if players[x] is None}
raise ValueError(f'Could not find a {bad_pos} for the {team_object["sname"]}')
logging.info(f'build_lineup - {players}')
# Sort players into lineup
# Pseudo-random? Patterns? Something to mix up lineups
# 421356789 or [123 (rand)][456 (rand)][789 (rand)] (optional: chance to flip 3/4 and 6/7)
lineups = []
# [ (<pos>, <player_obj>), (<pos>, <player_obj>), etc. ]
sorted_players = sorted(players.items(), key=lambda x: x[1]['cost'], reverse=True)
l_query = await db_get(f'teams/{team_object["id"]}/lineup/{league_name}?pitcher_name={sp_name}')
sorted_players = l_query['array']
logging.info(f'sorted_players: {sorted_players}')
grp_1 = sorted_players[:3]
grp_2 = sorted_players[3:6]
@ -326,15 +327,18 @@ async def build_lineup(team_object: dict, game_id: int, league_name: str, vs_han
random.shuffle(grp_2)
random.shuffle(grp_3)
lineups = []
i = 1
for x in [grp_1, grp_2, grp_3]:
logging.info(f'group: {x}')
for y in x:
card_id = await get_or_create_card(y[1], team_object)
logging.info(f'y: {y}')
card_id = await get_or_create_card(y[1]['player'], team_object)
lineups.append({
'game_id': game_id,
'team_id': team_object['id'],
'player_id': y[1]['player_id'],
'player_id': y[1]['player']['player_id'],
'card_id': card_id,
'position': y[0],
'batting_order': i,
@ -348,83 +352,79 @@ async def build_lineup(team_object: dict, game_id: int, league_name: str, vs_han
async def get_starting_pitcher(team_object: dict, game_id: int, is_home: bool, league_name: str = None) -> dict:
set_params = [('cardset_id_exclude', 2)]
if league_name == 'minor-league':
set_params = copy.deepcopy(MINOR_CARDSET_PARAMS)
elif league_name == 'major-league':
set_params = copy.deepcopy(MAJOR_CARDSET_PARAMS)
elif league_name == 'hall-of-fame':
set_params = copy.deepcopy(HOF_CARDSET_PARAMS)
elif league_name == 'gauntlet-1':
set_params = copy.deepcopy(MINOR_CARDSET_PARAMS)
elif 'gauntlet-2' in league_name:
set_params = random.sample(GAUNTLET2_PARAMS)
params = [
('mlbclub', team_object['lname']), ('pos_include', 'SP'), ('pos_exclude', 'RP'),
('inc_dex', False), ('sort_by', 'cost-desc'), ('limit', 5)
]
counter = 0
logging.info(f'params: {params}')
while counter < 2:
logging.info(f'counter: {counter}')
counter += 1
# Pull starters sorted by current cost
logging.info(f'counter: {counter} / params: {params}')
try:
params.extend(set_params)
pitchers = await db_get(
endpoint='players',
params=params,
timeout=10
)
logging.info(f'pitchers: {pitchers}')
except ConnectionError as e:
logging.error(f'Could not get pitchers for {team_object["lname"]}: {e}')
raise ConnectionError(f'Error pulling starting pitchers for the {team_object["lname"]}. Cal help plz.')
if pitchers['count'] == 0:
logging.info(f'pitchers is None')
del params
params = [
('mlbclub', team_object['lname']), ('pos_include', 'SP'),
('inc_dex', False), ('sort_by', 'cost-desc'), ('limit', 5)
]
else:
break
logging.info(f'build_lineup - eligible starting pitcher count: {len(pitchers)}')
if pitchers['count'] == 0:
raise DatabaseError(f'Could not find any SP for {team_object["abbrev"]}. Seems like a Cal issue.')
# set_params = [('cardset_id_exclude', 2)]
# if league_name == 'minor-league':
# set_params = copy.deepcopy(MINOR_CARDSET_PARAMS)
# elif league_name == 'major-league':
# set_params = copy.deepcopy(MAJOR_CARDSET_PARAMS)
# elif league_name == 'hall-of-fame':
# set_params = copy.deepcopy(HOF_CARDSET_PARAMS)
# elif league_name == 'gauntlet-1':
# set_params = copy.deepcopy(MINOR_CARDSET_PARAMS)
# elif 'gauntlet-2' in league_name:
# set_params = random.sample(GAUNTLET2_PARAMS)
#
# params = [
# ('mlbclub', team_object['lname']), ('pos_include', 'SP'), ('pos_exclude', 'RP'),
# ('inc_dex', False), ('sort_by', 'cost-desc'), ('limit', 5)
# ]
# counter = 0
# logging.info(f'params: {params}')
# while counter < 2:
# logging.info(f'counter: {counter}')
# counter += 1
# # Pull starters sorted by current cost
# logging.info(f'counter: {counter} / params: {params}')
# try:
# params.extend(set_params)
# pitchers = await db_get(
# endpoint='players',
# params=params,
# timeout=10
# )
# logging.info(f'pitchers: {pitchers}')
# except ConnectionError as e:
# logging.error(f'Could not get pitchers for {team_object["lname"]}: {e}')
# raise ConnectionError(f'Error pulling starting pitchers for the {team_object["lname"]}. Cal help plz.')
#
# if pitchers['count'] == 0:
# logging.info(f'pitchers is None')
# del params
# params = [
# ('mlbclub', team_object['lname']), ('pos_include', 'SP'),
# ('inc_dex', False), ('sort_by', 'cost-desc'), ('limit', 5)
# ]
# else:
# break
#
# logging.info(f'build_lineup - eligible starting pitcher count: {len(pitchers)}')
# if pitchers['count'] == 0:
# raise DatabaseError(f'Could not find any SP for {team_object["abbrev"]}. Seems like a Cal issue.')
d_100 = random.randint(1, 100)
starter = None
if is_home:
if d_100 <= 30:
starter = pitchers['players'][0]
elif d_100 <= 55 and pitchers['count'] > 1:
starter = pitchers['players'][1]
elif d_100 <= 75 and pitchers['count'] > 2:
starter = pitchers['players'][2]
elif d_100 <= 90 and pitchers['count'] > 3:
starter = pitchers['players'][3]
elif pitchers['count'] == 5:
starter = pitchers['players'][4]
sp_rank = 1
elif d_100 <= 55:
sp_rank = 2
elif d_100 <= 75:
sp_rank = 3
elif d_100 <= 90:
sp_rank = 4
else:
starter = pitchers['players'][0]
sp_rank = 5
else:
if d_100 <= 50:
starter = pitchers['players'][0]
elif d_100 <= 75 and pitchers['count'] > 1:
starter = pitchers['players'][1]
elif d_100 <= 85 and pitchers['count'] > 2:
starter = pitchers['players'][2]
elif d_100 <= 95 and pitchers['count'] > 3:
starter = pitchers['players'][3]
elif pitchers['count'] == 5:
starter = pitchers['players'][4]
sp_rank = 1
elif d_100 <= 75:
sp_rank = 2
elif d_100 <= 85:
sp_rank = 3
elif d_100 <= 95:
sp_rank = 4
else:
starter = pitchers['players'][0]
sp_rank = 5
starter = await db_get(f'teams/{team_object["id"]}/sp/{league_name}?sp_rank={sp_rank}')
# get player card; create one if none found
card_id = await get_or_create_card(starter, team_object)

View File

@ -20,7 +20,7 @@ from dice import sa_fielding_roll
from helpers import SBA_PLAYERS_ROLE_NAME, PD_PLAYERS_ROLE_NAME, random_conf_gif, SBA_SEASON, PD_SEASON, IMAGES, \
get_team_embed, Confirm, get_pos_abbrev, SBA_COLOR, get_roster_lineups, Question, give_packs, send_to_channel, \
get_channel, get_or_create_role, team_role, get_cal_user, get_card_embeds, ButtonOptions, get_ratings_guide, \
get_team_by_owner, get_roster_sheet, get_role
get_team_by_owner, get_roster_sheet, get_role, player_desc, player_pcard, player_bcard
from gameplay_helpers import *
from db_calls import db_get, db_patch, db_post, db_delete, get_team_by_abbrev
from db_calls_gameplay import StratGame, StratPlay, StratLineup, StratManagerAi, get_sba_team, get_sba_player, \
@ -223,8 +223,10 @@ class Gameplay(commands.Cog):
if curr_play is None:
away_lineup = await get_team_lineups(game.id, game.away_team_id)
home_lineup = await get_team_lineups(game.id, game.home_team_id)
logging.info(f'away_lineup: {away_lineup}')
logging.info(f'home_lineup: {home_lineup}')
if not away_lineup or not home_lineup:
if len(away_lineup) < 200 or len(home_lineup) < 200:
game_state = {
'error': True,
'away_lineup': away_lineup,
@ -237,7 +239,7 @@ class Gameplay(commands.Cog):
else:
logging.info(f'looking for home ({game.home_team_id}) pitcher in Game {game.id}')
pitcher = get_one_lineup(game.id, team_id=game.home_team_id, position='P')
logging.info(f'pitcher: {pitcher}')
logging.debug(f'pitcher: {pitcher}')
curr_play = post_play({
'game_id': game.id,
'play_num': 1,
@ -386,10 +388,7 @@ class Gameplay(commands.Cog):
# embed.add_field(name='Matchup', value=f'Pitcher: \nvs\nBatter: ', inline=False)
embed.add_field(name='Pitcher', value=f'{pitcher_string}')
embed.add_field(name='Batter', value=f'{batter_string}')
if game_state['batter']['image2']:
embed.set_image(url=game_state["batter"]["image2"])
else:
embed.set_image(url=game_state["batter"]["image"])
embed.set_image(url=player_bcard(game_state['batter']))
baserunner_string = ''
if game_state['curr_play'].on_first:
@ -433,7 +432,7 @@ class Gameplay(commands.Cog):
embed.add_field(
name='SUBSTITUTION',
value=f'The {game_state["pitcher"]["team"]["sname"]} have brought in '
f'{ai_data["sub"]["description"]} to pitch.'
f'{player_desc(ai_data["sub"])} to pitch'
)
# AI Team is batting
@ -967,10 +966,12 @@ class Gameplay(commands.Cog):
# )
@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')
@commands.has_any_role(PD_PLAYERS_ROLE_NAME)
async def new_game_campaign_command(
self, interaction: discord.Interaction, league: Literal['Minor League', 'Major League', 'Hall of Fame'],
away_team_abbrev: str, home_team_abbrev: str, num_innings: Literal[9, 3]):
away_team_abbrev: str, home_team_abbrev: str, num_innings: Literal[9, 3], sp_card_id: int):
await interaction.response.defer()
conflict = get_one_game(channel_id=interaction.channel.id, active=True)
@ -1036,6 +1037,7 @@ class Gameplay(commands.Cog):
return
ai_team = away_team if away_team['is_ai'] else home_team
human_team = away_team if home_team['is_ai'] else home_team
if interaction.user.id not in [away_team['gmid'], home_team['gmid']]:
await interaction.edit_original_response(
@ -1045,34 +1047,38 @@ class Gameplay(commands.Cog):
if 'Minor' in league:
league_name = 'minor-league'
elif 'Major' in league:
can_play = False
for x in interaction.user.roles:
if x.name == 'PD - Major League':
can_play = True
if not can_play:
await interaction.edit_original_response(
content=f'Ope. Looks like you haven\'t received the **PD - Major League** role, yet!\n\n'
f'To play **Major League** games, you need to defeat all 30 MLB teams in the Minor League '
f'campaign. You can see your progress with `/record`.\n\n'
f'If you have completed the Minor League campaign, go ping Cal to get your new role!')
return
league_name = 'major-league'
else:
can_play = False
for x in interaction.user.roles:
if x.name == 'PD - Hall of Fame':
can_play = True
if not can_play:
await interaction.edit_original_response(
content=f'Ope. Looks like you haven\'t received the **PD - Hall of Fame** role, yet!\n\n'
f'To play **Hall of Fame** games, you need to defeat all 30 MLB teams in the Minor League '
f'and Major League campaign. You can see your progress with `/record`.\n\n'
f'If you have completed the Major League campaign, go ping Cal to get your new role!')
return
league_name = 'hall-of-fame'
await interaction.edit_original_response(
content=f'Bonus star for speed running the Minor Leagues. The Major League campaign will release soon!')
return
# elif 'Major' in league:
# can_play = False
# for x in interaction.user.roles:
# if x.name == 'PD - Major League':
# can_play = True
#
# if not can_play:
# await interaction.edit_original_response(
# content=f'Ope. Looks like you haven\'t received the **PD - Major League** role, yet!\n\n'
# f'To play **Major League** games, you need to defeat all 30 MLB teams in the Minor League '
# f'campaign. You can see your progress with `/record`.\n\n'
# f'If you have completed the Minor League campaign, go ping Cal to get your new role!')
# return
# league_name = 'major-league'
# else:
# can_play = False
# for x in interaction.user.roles:
# if x.name == 'PD - Hall of Fame':
# can_play = True
#
# if not can_play:
# await interaction.edit_original_response(
# content=f'Ope. Looks like you haven\'t received the **PD - Hall of Fame** role, yet!\n\n'
# f'To play **Hall of Fame** games, you need to defeat all 30 MLB teams in the Minor League '
# f'and Major League campaign. You can see your progress with `/record`.\n\n'
# f'If you have completed the Major League campaign, go ping Cal to get your new role!')
# return
# league_name = 'hall-of-fame'
this_game = post_game({
'away_team_id': away_team['id'],
@ -1091,27 +1097,39 @@ class Gameplay(commands.Cog):
)
away_role = await team_role(interaction, away_team)
home_role = await team_role(interaction, home_team)
all_lineups = []
# Get AI Lineup
try:
await interaction.edit_original_response(
content=f'I am getting a lineup card from the {ai_team["sname"]}...'
)
logging.info(f'new-game - calling lineup for {ai_team["abbrev"]}')
all_lineups = await ai_manager.build_lineup(ai_team, this_game.id, league_name)
logging.info(f'new-game - got lineup for {ai_team["abbrev"]}')
except Exception as e:
patch_game(this_game.id, active=False)
logging.error(f'could not start an AI game with {ai_team["sname"]}: {e}')
await interaction.edit_original_response(
content=f'Looks like the {ai_team["sname"]} lineup card didn\'t come through clearly. I\'ll sort '
f'this out with {ai_team["gmname"]} and {get_cal_user(interaction).mention}. I\'ll end '
f'this game - why don\'t you play against somebody else for now?'
# Get Human SP
human_sp_card = await db_get(f'cards', object_id=sp_card_id)
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_team["player"]["p_name"]} and belongs to '
f'{human_sp_card["team"]["sname"]}. Will you double check that before we get started?')
return
if this_game.game_type in ['major-league', 'hall-of-fame']:
l_check = await legal_check([human_sp_card['id']])
if not l_check['legal']:
await interaction.edit_original_response(
content=f'It looks like this is a Ranked Legal game and {player_desc(human_sp_card["player"])} is '
f'not legal in Ranked. You can start a new game once you get a new SP.'
)
return
all_lineups.append({
'game_id': this_game.id,
'team_id': human_team['id'],
'player_id': human_sp_card['player']['player_id'],
'card_id': sp_card_id,
'position': 'P',
'batting_order': 10,
'after_play': 0
})
# Get AI Starting Pitcher
try:
await interaction.edit_original_response(
@ -1130,11 +1148,12 @@ class Gameplay(commands.Cog):
league_name
)
all_lineups.append(starter)
ai_sp = await db_get('players', object_id=starter['player_id'])
this_card = await db_get(f'cards', object_id=starter['card_id'])
await interaction.channel.send(
content=f'The {ai_team["sname"]} are starting **{this_card["player"]["description"]}**:\n\n'
f'{this_card["player"]["image"]}'
content=f'The {ai_team["sname"]} are starting **{player_desc(this_card["player"])}**:\n\n'
f'{player_pcard(this_card["player"])}'
)
except Exception as e:
@ -1147,6 +1166,29 @@ class Gameplay(commands.Cog):
)
return
# Get AI Lineup
try:
await interaction.edit_original_response(
content=f'I am getting a lineup card from the {ai_team["sname"]}...'
)
logging.info(f'new-game - calling lineup for {ai_team["abbrev"]}')
batters = await ai_manager.build_lineup(
ai_team, this_game.id, league_name, sp_name=ai_sp['p_name']
)
all_lineups.extend(batters)
logging.info(f'new-game - got lineup for {ai_team["abbrev"]}')
except Exception as e:
patch_game(this_game.id, active=False)
logging.error(f'could not start an AI game with {ai_team["sname"]}: {e}')
await interaction.edit_original_response(
content=f'Looks like the {ai_team["sname"]} lineup card didn\'t come through clearly. I\'ll sort '
f'this out with {ai_team["gmname"]} and {get_cal_user(interaction).mention}. I\'ll end '
f'this game - why don\'t you play against somebody else for now?'
)
return
logging.debug(f'Setting lineup for {ai_team["sname"]} in PD game')
logging.info(f'lineups: {all_lineups}')
post_lineups(all_lineups)
@ -1472,7 +1514,7 @@ class Gameplay(commands.Cog):
this_card = await db_get(f'cards', object_id=starter['card_id'])
await interaction.channel.send(
content=f'The {opponent["sname"]} are starting **{this_card["player"]["description"]}**:\n\n'
content=f'The {opponent["sname"]} are starting **{player_desc(this_card["player"])}**:\n\n'
f'{this_card["player"]["image"]}'
)
@ -1529,7 +1571,7 @@ class Gameplay(commands.Cog):
get_pitching_decisions(this_game)
await ctx.send(random_conf_gif())
@app_commands.command(name='endgame', description='End game in this channel')
@app_commands.command(name='end-game', description='End game in this channel')
@app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME)
async def end_game_command(self, interaction: discord.Interaction):
await interaction.response.defer()
@ -1564,6 +1606,13 @@ class Gameplay(commands.Cog):
Top 9th inning or earlier and not 10-run lead
"""
if latest_play is None:
patch_game(this_game.id, active=False)
await interaction.edit_original_response(
content='Roger dodger - it is game over.'
)
return
valid_end = False
if latest_play.starting_outs == 0:
if latest_play.inning_half == 'top':
@ -1991,19 +2040,18 @@ class Gameplay(commands.Cog):
)
@app_commands.command(
name='readlineup',
name='read-lineup',
description='Import a saved lineup directly from the team sheet for PD games'
)
@app_commands.describe(
team_abbrev='The 2- to 4-digit abbreviation for the team being set',
roster='Which roster to pull from your sheet?',
lineup='Which handedness lineup are you using?',
sp_card_id='Light gray number to the left of the pitcher\'s name on your depth chart'
lineup='Which handedness lineup are you using?'
)
@app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME)
async def read_lineup_command(
self, interaction: discord.Interaction, team_abbrev: str, roster: Literal['Primary', 'Secondary', 'Ranked'],
lineup: Literal['v Right', 'v Left'], sp_card_id: int):
lineup: Literal['v Right', 'v Left']):
this_game = get_one_game(channel_id=interaction.channel_id, active=True)
if not this_game:
await interaction.response.send_message(f'I dont\'t see an active game in this channel!')
@ -2029,8 +2077,8 @@ class Gameplay(commands.Cog):
)
return
existing_lineups = await get_team_lineups(this_game.id, lineup_team['id'])
if existing_lineups:
existing_lineups = await get_team_lineups(this_game.id, lineup_team['id'], as_string=False)
if len(existing_lineups) > 1:
await interaction.response.send_message(
f'It looks like the {lineup_team["sname"]} already have a lineup. Run `/substitution` to make changes.'
)
@ -2089,55 +2137,53 @@ class Gameplay(commands.Cog):
else:
patch_game(this_game.id, home_roster_num=roster_num)
if lineup_team['is_ai']:
starter = starting_pitcher(lineup_team, self.bot, True if this_game.ai_team == 'home' else False)
this_card = await db_get(f'cards', object_id=int(starter))
all_lineups.append({
'game_id': this_game.id,
'team_id': lineup_team['id'],
'player_id': this_card['player']['player_id'],
'card_id': starter,
'position': 'P',
'batting_order': 10,
'after_play': 0
})
all_pos.append('P')
else:
this_card = await db_get(f'cards', object_id=sp_card_id)
logging.debug(f'this_card: {this_card}')
if this_card['team']['id'] != lineup_team['id']:
logging.error(
f'Card_id {sp_card_id} does not belong to {lineup_team["abbrev"]} in Game {this_game.id}'
)
await interaction.channel.send(
f'Uh oh. Card ID {sp_card_id} is {this_card["player"]["p_name"]} and belongs to '
f'{this_card["team"]["sname"]}. Will you double check that before we get started?')
return
else:
card_ids.append(str(sp_card_id))
all_lineups.append({
'game_id': this_game.id,
'team_id': lineup_team['id'],
'player_id': this_card['player']['player_id'],
'card_id': sp_card_id,
'position': 'P',
'batting_order': 10,
'after_play': 0
})
all_pos.append('P')
# if lineup_team['is_ai']:
# starter = starting_pitcher(lineup_team, self.bot, True if this_game.ai_team == 'home' else False)
# this_card = await db_get(f'cards', object_id=int(starter))
# all_lineups.append({
# 'game_id': this_game.id,
# 'team_id': lineup_team['id'],
# 'player_id': this_card['player']['player_id'],
# 'card_id': starter,
# 'position': 'P',
# 'batting_order': 10,
# 'after_play': 0
# })
# all_pos.append('P')
# else:
# this_card = await db_get(f'cards', object_id=sp_card_id)
# logging.debug(f'this_card: {this_card}')
#
# if this_card['team']['id'] != lineup_team['id']:
# logging.error(
# f'Card_id {sp_card_id} does not belong to {lineup_team["abbrev"]} in Game {this_game.id}'
# )
# await interaction.channel.send(
# f'Uh oh. Card ID {sp_card_id} is {this_card["player"]["p_name"]} and belongs to '
# f'{this_card["team"]["sname"]}. Will you double check that before we get started?')
# return
#
# else:
# card_ids.append(str(sp_card_id))
# all_lineups.append({
# 'game_id': this_game.id,
# 'team_id': lineup_team['id'],
# 'player_id': this_card['player']['player_id'],
# 'card_id': sp_card_id,
# 'position': 'P',
# 'batting_order': 10,
# 'after_play': 0
# })
# all_pos.append('P')
# Check roster legality
if this_game.game_type in ['major-league', 'hall-of-fame']:
l_string = "&card_id=".join(card_ids)
legality = await db_post(f'cards/legal-check/ranked?card_id={l_string}')
if legality['count'] > 0:
il_string = "\n- ".join(legality['bad_cards'])
l_check = await legal_check(card_ids)
if not l_check['legal']:
await interaction.edit_original_response(
content=f'It looks like this is a Ranked Legal game and I see the following cards as illegal. '
f'Please adjust your lineup and re-submit!\n\n'
f'- {il_string}'
f'- {l_check["error_string"]}'
)
return
@ -2159,12 +2205,6 @@ class Gameplay(commands.Cog):
# return
# else:
if 'P' not in all_pos:
await interaction.channel.send(
content=f'Please enter the Starting pitcher using the `/starting-pitcher` command'
)
return
try:
await interaction.channel.send(content=None, embed=await self.get_game_state_embed(this_game))
except IntegrityError as e:
@ -2749,6 +2789,7 @@ class Gameplay(commands.Cog):
# Safe at home and third
else:
batter_to_base = 3
await question.delete()
# No: Safe at home?
@ -2938,12 +2979,17 @@ class Gameplay(commands.Cog):
advance_runners(this_play.id, 0)
if running_type == 'stolen-base':
if to_base == 'Home' and this_play.on_third:
if to_base == 4 and this_play.on_third:
patch_play(
this_play.id, sb=1, on_third_final=4, runner_id=this_play.on_third.id, catcher_id=catcher.id
)
if this_play.on_second:
advance_one_runner(this_play.id, 2, 1)
if this_play.on_first:
advance_one_runner(this_play.id, 1, 1)
elif to_base == 3 and this_play.on_second:
if not this_play.on_third:
advance_runners(this_play.id, 1, is_error=True)
patch_play(
this_play.id, sb=1, on_second_final=3, runner_id=this_play.on_second.id, catcher_id=catcher.id
)
@ -2978,10 +3024,14 @@ class Gameplay(commands.Cog):
return
if running_type == 'steal-plus-overthrow':
if to_base == 'Home' and this_play.on_third:
if to_base == 4 and this_play.on_third:
patch_play(
this_play.id, sb=1, on_third_final=4, runner_id=this_play.on_third.id, catcher_id=catcher.id
)
if this_play.on_second:
advance_one_runner(this_play.id, 2, 2)
if this_play.on_first:
advance_one_runner(this_play.id, 1, 2)
elif to_base == 3 and this_play.on_second:
advance_runners(this_play.id, 1)
if not this_play.on_third:
@ -3018,13 +3068,18 @@ class Gameplay(commands.Cog):
patch_play(this_play.id, error=1)
elif running_type == 'caught-stealing':
if to_base == 'Home' and this_play.on_third:
if to_base == 4 and this_play.on_third:
patch_play(
this_play.id, cs=1, on_third_final=False, runner_id=this_play.on_third.id,
catcher_id=catcher.id, outs=1
)
if this_play.on_second:
advance_one_runner(this_play.id, 2, 1)
if this_play.on_first:
advance_one_runner(this_play.id, 1, 1)
elif to_base == 3 and this_play.on_second:
if not this_play.on_third:
advance_runners(this_play.id, 1)
patch_play(
this_play.id, cs=1, on_second_final=False, runner_id=this_play.on_second.id,
catcher_id=catcher.id, outs=1

View File

@ -515,7 +515,7 @@ class Players(commands.Cog):
await interaction.response.defer()
c_query = await db_get('cards', object_id=card_id)
if c_query:
c_string = f'Card ID {card_id} is a {c_query["player"]["description"]}'
c_string = f'Card ID {card_id} is a {helpers.player_desc(c_query["player"])}'
if c_query['team'] is not None:
c_string += f' owned by the {c_query["team"]["sname"]}'
if c_query["pack"] is not None:

View File

@ -4,7 +4,7 @@ import random
import db_calls_gameplay
from db_calls_gameplay import StratGame, StratPlay, StratLineup, StratManagerAi, patch_play, advance_runners, \
complete_play, get_team_lineups, get_or_create_bullpen, get_player, get_sheets, make_sub
from db_calls import db_get
from db_calls import db_get, db_post
def single_onestar(this_play: StratPlay, comp_play: bool = True):
@ -163,3 +163,15 @@ def get_pitcher(this_game: StratGame, this_play: StratPlay):
p_team_id = this_game.home_team_id
return db_calls_gameplay.get_one_lineup(this_game.id, team_id=p_team_id, position='P', active=True)
async def legal_check(card_ids: list):
l_string = "&card_id=".join(card_ids)
legality = await db_post(f'cards/legal-check/ranked?card_id={l_string}')
r_val = {'legal': True, 'error_string': None}
if legality['count'] > 0:
r_val['legal'] = False
r_val['error_string'] = "\n- ".join(legality['bad_cards'])
return r_val

View File

@ -295,9 +295,9 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
for y in all_players:
if include_links:
name_string = f'[{y["description"]}]({y["image"]})'
name_string = f'[{helpers.player_desc(y)}]({y["image"]})'
else:
name_string = f'{y["description"]}'
name_string = f'{helpers.player_desc(y)}'
all_str[y['rarity']['name']] += f'{name_string}\n'
for z in helpers.get_all_pos(y):
all_str[z] += f'{name_string}\n'

View File

@ -3008,3 +3008,27 @@ async def confirm_pack_purchase(interaction, owner_team, num_packs, total_cost,
return None
else:
return question
def player_desc(this_player) -> str:
if this_player['p_name'] in this_player['description']:
return this_player['description']
return f'{this_player["description"]} {this_player["p_name"]}'
def player_pcard(this_player):
if 'pitching' in this_player['image']:
return this_player['image']
elif 'pitching' in this_player['image2']:
return this_player['image2']
else:
return None
def player_bcard(this_player):
if 'batting' in this_player['image']:
return this_player['image']
elif 'batting' in this_player['image2']:
return this_player['image2']
else:
return None