Added range embeds to uncapped hits
Update gbA with runner on 3rd
This commit is contained in:
parent
c3c88af14a
commit
fa109442c2
@ -1,5 +1,6 @@
|
||||
|
||||
import asyncio
|
||||
import copy
|
||||
import logging
|
||||
import discord
|
||||
from discord import SelectOption
|
||||
@ -10,7 +11,7 @@ from sqlalchemy import delete
|
||||
from typing import Literal
|
||||
|
||||
from api_calls import db_delete, db_get, db_post
|
||||
from dice import d_twenty_roll, frame_plate_check, sa_fielding_roll
|
||||
from dice import DTwentyRoll, d_twenty_roll, frame_plate_check, sa_fielding_roll
|
||||
from exceptions import *
|
||||
from helpers import DEFENSE_LITERAL, SBA_COLOR, get_channel
|
||||
from in_game.game_helpers import legal_check
|
||||
@ -35,6 +36,13 @@ AT_BASE = {
|
||||
3: 'at third',
|
||||
4: 'at home'
|
||||
}
|
||||
RANGE_CHECKS = {
|
||||
1: 3,
|
||||
2: 7,
|
||||
3: 11,
|
||||
4: 15,
|
||||
5: 19
|
||||
}
|
||||
|
||||
|
||||
async def get_scorebug_embed(session: Session, this_game: Game, full_length: bool = True, classic: bool = True) -> discord.Embed:
|
||||
@ -1303,17 +1311,247 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
|
||||
this_game = this_play.game
|
||||
outfielder = await show_outfield_cards(session, interaction, this_play)
|
||||
logger.info(f'throw from {outfielder.player.name_with_desc}')
|
||||
|
||||
this_roll = d_twenty_roll(this_play.batter.team, this_play.game)
|
||||
block_roll = d_twenty_roll(this_play.catcher.team, this_play.game)
|
||||
|
||||
def_team = this_play.pitcher.team
|
||||
runner_bc = get_batter_card(this_lineup=lead_runner)
|
||||
of_rating = await get_position(session, this_card=outfielder.card, position=outfielder.position)
|
||||
defense_embed = def_team.embed
|
||||
defense_embed.description = f'{outfielder.player.name}\'s Throw'
|
||||
trail_bc = get_batter_card(this_lineup=trail_runner)
|
||||
logger.info(f'trail runner batting card: {trail_bc}')
|
||||
c_rating = await get_position(session, this_play.catcher.card, position='C')
|
||||
runner_embed = this_play.batter.team.embed
|
||||
runner_embed.add_field(name=f'{outfielder.position} Arm', value=f'{"+" if of_rating.arm > 0 else ""}{of_rating.arm}')
|
||||
|
||||
safe_range = None
|
||||
|
||||
def_alignment = this_play.managerai.defense_alignment(session, this_play.game)
|
||||
lead_bc = get_batter_card(this_lineup=lead_runner)
|
||||
logger.info(f'lead runner batting card: {lead_bc}')
|
||||
|
||||
lead_safe_range = lead_bc.running + of_rating.arm
|
||||
logger.info(f'lead_safe_range: {lead_safe_range}')
|
||||
|
||||
# Build lead runner embed
|
||||
lead_runner_embed = copy.deepcopy(runner_embed)
|
||||
lead_runner_embed.title = f'{lead_runner.player.name} To {"Home" if lead_base == 4 else "Third"}'
|
||||
lead_runner_embed.description = f'{outfielder.team.abbrev} {outfielder.position} {outfielder.player.name}\'s Throw'
|
||||
lead_runner_embed.add_field(name=f'Runner Speed', value=lead_runner.card.batterscouting.battingcard.running)
|
||||
|
||||
if this_play.starting_outs == 2:
|
||||
logger.info(f'Adding 2 for 2 outs')
|
||||
lead_safe_range += 2
|
||||
lead_runner_embed.add_field(name='2-Out Mod', value=f'+2')
|
||||
|
||||
if lead_base == 3 and outfielder.position != 'CF':
|
||||
of_mod = -2 if outfielder.position == 'LF' else 2
|
||||
logger.info(f'{outfielder.position} to 3B mod: {of_mod}')
|
||||
|
||||
lead_safe_range += of_mod
|
||||
lead_runner_embed.add_field(name=f'{outfielder.position} Mod', value=f'{"+" if of_mod > 0 else ""}{of_mod}')
|
||||
logger.info(f'lead_runner_embed: {lead_runner_embed}')
|
||||
|
||||
# Build trail runner embed
|
||||
trail_runner_embed = copy.deepcopy(runner_embed)
|
||||
trail_bc = get_batter_card(this_lineup=trail_runner)
|
||||
trail_runner_embed.title = f'{trail_runner.player.name} To {"Third" if trail_base == 3 else "Second"}'
|
||||
trail_runner_embed.description = f'{outfielder.team.abbrev} {outfielder.position} {outfielder.player.name}\'s Throw'
|
||||
|
||||
trail_runner_embed.add_field(name=f'Runner Speed', value=trail_bc.running)
|
||||
logger.info(f'trail runner batting card: {trail_bc}')
|
||||
|
||||
trail_safe_range = trail_bc.running - 5 + of_rating.arm
|
||||
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
|
||||
logger.info(f'{outfielder.position} to 3B mod: {of_mod}')
|
||||
|
||||
trail_safe_range += of_mod
|
||||
trail_runner_embed.add_field(name=f'{outfielder.position} Mod', value=f'{"+" if of_mod > 0 else ""}{of_mod}', inline=False)
|
||||
|
||||
trail_runner_embed.add_field(name='Trail Runner', value='-5')
|
||||
|
||||
def at_home_strings(safe_range: int):
|
||||
safe_string = f'1{" - " if safe_range > 1 else ""}'
|
||||
if safe_range > 1:
|
||||
if safe_range <= 20:
|
||||
safe_string += f'{safe_range - 1}'
|
||||
else:
|
||||
safe_string += f'20'
|
||||
|
||||
if safe_range == 20:
|
||||
out_string = 'None'
|
||||
catcher_string = '20'
|
||||
elif safe_range > 20:
|
||||
out_string = 'None'
|
||||
catcher_string = 'None'
|
||||
elif safe_range == 19:
|
||||
out_string = 'None'
|
||||
catcher_string = '19 - 20'
|
||||
elif safe_range == 18:
|
||||
out_string = f'20'
|
||||
catcher_string = '18 - 19'
|
||||
else:
|
||||
out_string = f'{safe_range + 2} - 20'
|
||||
catcher_string = f'{safe_range} - {safe_range + 1}'
|
||||
logger.info(f'safe: {safe_string} / catcher: {catcher_string} / out: {out_string}')
|
||||
|
||||
return {'safe': safe_string, 'catcher': catcher_string, 'out': out_string}
|
||||
|
||||
def at_third_strings(safe_range: int):
|
||||
safe_string = f'1{" - " if safe_range > 1 else ""}'
|
||||
if safe_range > 1:
|
||||
if safe_range <= 20:
|
||||
safe_string += f'{safe_range}'
|
||||
else:
|
||||
safe_string += f'20'
|
||||
|
||||
if safe_range > 19:
|
||||
out_string = '20'
|
||||
else:
|
||||
out_string = f'{safe_range + 1} - 20'
|
||||
logger.info(f'safe: {safe_string} / out: {out_string}')
|
||||
|
||||
return {'safe': safe_string, 'out': out_string}
|
||||
|
||||
async def out_at_home(safe_range: int):
|
||||
if this_roll.d_twenty in [safe_range, safe_range + 1]:
|
||||
logger.info(f'Roll of {this_roll.d_twenty} is a catcher check with safe range of {safe_range}')
|
||||
|
||||
is_block_plate = await ask_confirm(
|
||||
interaction,
|
||||
question=f'Looks like **{this_play.catcher.player.name}** has a chance to block the plate! Is that correct?',
|
||||
label_type='yes',
|
||||
delete_question=False
|
||||
)
|
||||
|
||||
if is_block_plate:
|
||||
logger.info(f'Looks like a block the plate check')
|
||||
await interaction.channel.send(content=None, embeds=block_roll.embeds)
|
||||
|
||||
if block_roll.d_twenty > RANGE_CHECKS[c_rating]:
|
||||
logger.info(f'Roll of {this_roll.d_twenty} is OUT {AT_BASE[4]}')
|
||||
runner_thrown_out = True
|
||||
q_text = f'Looks like **{lead_runner.player.name}** is OUT {AT_BASE[4]}!'
|
||||
else:
|
||||
logger.info(f'Roll of {this_roll.d_twenty} is SAFE {AT_BASE[4]}')
|
||||
runner_thrown_out = False
|
||||
q_text = f'Looks like **{lead_runner.player.name}** is SAFE {AT_BASE[4]}!'
|
||||
else:
|
||||
runner_thrown_out = await ask_confirm(
|
||||
interaction=interaction,
|
||||
question=f'Was **{lead_runner.player.name}** thrown out {AT_BASE[4]}?',
|
||||
label_type='yes',
|
||||
)
|
||||
else:
|
||||
logger.info(f'Roll of {this_roll.d_twenty} has a clear result with safe range of {safe_range}')
|
||||
if this_roll.d_twenty > safe_range:
|
||||
logger.info(f'Roll of {this_roll.d_twenty} is OUT {AT_BASE[4]}')
|
||||
runner_thrown_out = True
|
||||
q_text = f'Looks like **{lead_runner.player.name}** is OUT {AT_BASE[4]}!'
|
||||
else:
|
||||
logger.info(f'Roll of {this_roll.d_twenty} is SAFE {AT_BASE[4]}')
|
||||
runner_thrown_out = False
|
||||
q_text = f'Looks like **{lead_runner.player.name}** is SAFE {AT_BASE[4]}!'
|
||||
|
||||
is_correct = await ask_confirm(
|
||||
interaction,
|
||||
question=f'{q_text} Is that correct?',
|
||||
label_type='yes',
|
||||
delete_question=False
|
||||
)
|
||||
|
||||
if not is_correct:
|
||||
logger.warning(f'{interaction.user.name} says call is incorrect; runner is {"not " if runner_thrown_out else ""}thrown out')
|
||||
runner_thrown_out = not runner_thrown_out
|
||||
|
||||
return runner_thrown_out
|
||||
|
||||
async def out_at_base(safe_range: int, this_runner: Lineup, this_base: int):
|
||||
if this_roll.d_twenty > safe_range:
|
||||
logger.info(f'Roll of {this_roll.d_twenty} is OUT {AT_BASE[this_base]}')
|
||||
runner_thrown_out = True
|
||||
q_text = f'Looks like **{this_runner.player.name}** is OUT {AT_BASE[this_base]}!'
|
||||
else:
|
||||
logger.info(f'Roll of {this_roll.d_twenty} is SAFE {AT_BASE[this_base]}')
|
||||
runner_thrown_out = False
|
||||
q_text = f'Looks like **{this_runner.player.name}** is SAFE {AT_BASE[this_base]}!'
|
||||
|
||||
is_correct = await ask_confirm(
|
||||
interaction,
|
||||
question=f'{q_text} Is that correct?',
|
||||
label_type='yes',
|
||||
delete_question=False
|
||||
)
|
||||
|
||||
if not is_correct:
|
||||
logger.warning(f'{interaction.user.name} says call is incorrect; runner is {"not " if runner_thrown_out else ""}thrown out')
|
||||
runner_thrown_out = not runner_thrown_out
|
||||
|
||||
return runner_thrown_out
|
||||
|
||||
# Either there is no AI team or the AI is pitching
|
||||
if not this_game.ai_team or not this_play.ai_is_batting:
|
||||
# Build lead runner embed
|
||||
# Check for lead runner hold
|
||||
if (lead_runner == this_play.on_second and def_alignment.hold_second) or (lead_runner == this_play.on_first and def_alignment.hold_first):
|
||||
lead_safe_range -= 1
|
||||
logger.info(f'Lead runner was held, -1 to safe range: {lead_safe_range}')
|
||||
lead_runner_embed.add_field(name='Runner Held', value='-1')
|
||||
else:
|
||||
logger.info(f'Lead runner was not held, +1 to safe range: {lead_safe_range}')
|
||||
lead_safe_range += 1
|
||||
lead_runner_embed.add_field(name='Runner Not Held', value='+1')
|
||||
|
||||
lead_runner_embed.add_field(name='', value='', inline=False)
|
||||
|
||||
if lead_base == 4:
|
||||
logger.info(f'lead base is 4, building strings')
|
||||
lead_strings = at_home_strings(lead_safe_range)
|
||||
|
||||
lead_runner_embed.add_field(name='Safe Range', value=lead_strings['safe'])
|
||||
lead_runner_embed.add_field(name='Catcher Check', value=lead_strings['catcher'])
|
||||
lead_runner_embed.add_field(name='Out Range', value=lead_strings['out'])
|
||||
|
||||
else:
|
||||
logger.info(f'lead base is 3, building strings')
|
||||
lead_strings = at_third_strings(lead_safe_range)
|
||||
|
||||
lead_runner_embed.add_field(name='Safe Range', value=lead_strings['safe'])
|
||||
lead_runner_embed.add_field(name='Out Range', value=lead_strings['out'])
|
||||
|
||||
# Build trail runner embed
|
||||
if (trail_runner == this_play.on_first and def_alignment.hold_first):
|
||||
trail_safe_range -= 1
|
||||
logger.info(f'Trail runner was held, -1 to safe range: {trail_safe_range}')
|
||||
trail_runner_embed.add_field(name='Runner Held', value='-1')
|
||||
elif (trail_runner == this_play.on_first and not def_alignment.hold_first):
|
||||
trail_safe_range += 1
|
||||
logger.info(f'Trail runner was not held, +1 to safe range: {trail_safe_range}')
|
||||
trail_runner_embed.add_field(name='Runner Not Held', value='+1')
|
||||
else:
|
||||
logger.info('Trail runner was not from first base, no hold modifier')
|
||||
|
||||
trail_runner_embed.add_field(name='', value='', inline=False)
|
||||
|
||||
logger.info(f'Building strings for trail runner')
|
||||
safe_string = f'1{" - " if trail_safe_range > 1 else ""}'
|
||||
if trail_safe_range > 1:
|
||||
if trail_safe_range < 20:
|
||||
safe_string += f'{trail_safe_range}'
|
||||
else:
|
||||
logger.info(f'capping safe range at 19')
|
||||
trail_safe_range = 19
|
||||
safe_string += f'19'
|
||||
|
||||
out_string = f'{trail_safe_range + 1} - 20'
|
||||
logger.info(f'safe: {safe_string} / out: {out_string}')
|
||||
|
||||
trail_runner_embed.add_field(name='Safe Range', value=safe_string)
|
||||
trail_runner_embed.add_field(name='Out Range', value=out_string)
|
||||
|
||||
await interaction.channel.send(embeds=[lead_runner_embed, trail_runner_embed])
|
||||
|
||||
is_lead_running = await ask_confirm(
|
||||
interaction=interaction,
|
||||
question=f'Is **{lead_runner.player.name}** being sent {TO_BASE[lead_base]}?',
|
||||
@ -1322,7 +1560,6 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
|
||||
|
||||
if is_lead_running:
|
||||
throw_resp = None
|
||||
def_alignment = this_play.managerai.defense_alignment(session, this_play.game)
|
||||
|
||||
if this_game.ai_team:
|
||||
throw_resp = this_play.managerai.throw_at_uncapped(session, this_game)
|
||||
@ -1341,7 +1578,7 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
|
||||
return this_play
|
||||
|
||||
else:
|
||||
await interaction.channel.send(content=f'{outfielder.player.name} is throwing {TO_BASE[lead_base]}!')
|
||||
await interaction.channel.send(content=f'**{outfielder.player.name}** is throwing {TO_BASE[lead_base]}!')
|
||||
|
||||
else:
|
||||
throw_for_lead = await ask_confirm(
|
||||
@ -1358,7 +1595,7 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
|
||||
this_play.on_second_final = 4
|
||||
log_run_scored(session, lead_runner, this_play)
|
||||
return this_play
|
||||
|
||||
|
||||
# Human runner is advancing, defense is throwing
|
||||
trail_advancing = await ask_confirm(
|
||||
interaction=interaction,
|
||||
@ -1366,24 +1603,13 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
|
||||
label_type='yes'
|
||||
)
|
||||
|
||||
lead_bc = get_batter_card(this_lineup=lead_runner)
|
||||
logger.info(f'lead runner batting card: {lead_bc}')
|
||||
|
||||
lead_safe_range = lead_bc.running + of_rating.arm + 1
|
||||
if lead_runner == this_play.on_second:
|
||||
lead_safe_range -= 2 if def_alignment.hold_second else 0
|
||||
elif lead_runner == this_play.on_first:
|
||||
lead_safe_range -= 2 if def_alignment.hold_first else 0
|
||||
logger.info(f'lead_safe_range: {lead_safe_range}')
|
||||
|
||||
# Trail runner is advancing
|
||||
if trail_advancing:
|
||||
trail_safe = trail_bc.running - 5 + of_rating.arm
|
||||
logger.info(f'trail_safe: {trail_safe}')
|
||||
|
||||
throw_lead = False
|
||||
if this_game.ai_team:
|
||||
|
||||
if throw_resp.at_trail_runner and trail_safe <= throw_resp.trail_max_safe and trail_safe <= throw_resp.trail_max_safe_delta - lead_safe_range:
|
||||
if throw_resp.at_trail_runner and trail_safe_range <= throw_resp.trail_max_safe and trail_safe_range <= throw_resp.trail_max_safe_delta - lead_safe_range:
|
||||
logger.info(f'defense throwing at trail runner {AT_BASE[trail_base]}')
|
||||
await interaction.channel.send(f'**{outfielder.player.name}** will throw {TO_BASE[trail_base]}!')
|
||||
throw_lead = False
|
||||
@ -1404,10 +1630,12 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
|
||||
|
||||
# Throw is going to lead runner
|
||||
if throw_lead:
|
||||
logger.info(f'Throw is going to lead base')
|
||||
try:
|
||||
await question.delete()
|
||||
except (discord.NotFound, UnboundLocalError):
|
||||
pass
|
||||
|
||||
if this_play.on_first == trail_runner:
|
||||
this_play.on_first_final += 1
|
||||
elif this_play.batter == trail_runner:
|
||||
@ -1422,16 +1650,12 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
|
||||
except (discord.NotFound, UnboundLocalError):
|
||||
pass
|
||||
|
||||
runner_thrown_out = await ask_confirm(
|
||||
interaction=interaction,
|
||||
question=f'**{trail_runner.player.name}**\'s safe range is 1 -> {trail_safe} - were they thrown out {AT_BASE[trail_base]}?',
|
||||
label_type='yes',
|
||||
custom_confirm_label=f'Out {AT_BASE[trail_base]}',
|
||||
custom_cancel_label=f'Safe {AT_BASE[trail_base]}'
|
||||
)
|
||||
await interaction.channel.send(content=None, embeds=this_roll.embeds)
|
||||
runner_thrown_out = await out_at_base(trail_safe_range, trail_runner, trail_base)
|
||||
|
||||
# Trail runner is thrown out
|
||||
if runner_thrown_out:
|
||||
logger.info(f'logging one one additional out for trail runner')
|
||||
# Log out on play
|
||||
this_play.outs += 1
|
||||
|
||||
@ -1442,7 +1666,9 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
|
||||
this_play.batter_final = None
|
||||
|
||||
# Advance lead runner extra base
|
||||
logger.info(f'advancing lead runner')
|
||||
if this_play.on_second == lead_runner:
|
||||
logger.info(f'run scored from second')
|
||||
this_play.rbi += 1
|
||||
this_play.on_second_final = 4
|
||||
log_run_scored(session, lead_runner, this_play)
|
||||
@ -1450,19 +1676,15 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
|
||||
elif this_play.on_first == lead_runner:
|
||||
this_play.on_first_final += 1
|
||||
if this_play.on_first_final > 3:
|
||||
logger.info(f'run scored from first')
|
||||
this_play.rbi += 1
|
||||
log_run_scored(session, lead_runner, this_play)
|
||||
|
||||
return this_play
|
||||
|
||||
# Ball is going to lead base, ask if safe
|
||||
runner_thrown_out = await ask_confirm(
|
||||
interaction=interaction,
|
||||
question=f'**{lead_runner.player.name}**\'s safe range is 1 -> {lead_safe_range} - were they thrown out {AT_BASE[lead_base]}?',
|
||||
label_type='yes',
|
||||
custom_confirm_label=f'Out {AT_BASE[lead_base]}',
|
||||
custom_cancel_label=f'Safe {AT_BASE[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, lead_runner, lead_base)
|
||||
|
||||
# Lead runner is thrown out
|
||||
if runner_thrown_out:
|
||||
@ -1489,28 +1711,60 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
|
||||
elif this_play.ai_is_batting:
|
||||
run_resp = this_play.managerai.uncapped_advance(session, this_game, lead_base, trail_base)
|
||||
|
||||
runner_held = await ask_confirm(
|
||||
lead_runner_held = await ask_confirm(
|
||||
interaction=interaction,
|
||||
question=f'Was **{lead_runner.player.name}** held before the pitch?',
|
||||
question=f'Was **{lead_runner.player.name}** held at {"second" if lead_runner == this_play.on_second else "first"} before the pitch?',
|
||||
label_type='yes'
|
||||
)
|
||||
safe_range = runner_bc.running + of_rating.arm - 1
|
||||
if runner_held:
|
||||
safe_range -= 1
|
||||
if lead_runner_held:
|
||||
lead_safe_range -= 1
|
||||
lead_runner_embed.add_field(name='Runner Held', value='-1')
|
||||
logger.info(f'runner was held, -1 to lead safe range: {lead_safe_range}')
|
||||
else:
|
||||
safe_range += 1
|
||||
|
||||
if this_play.starting_outs == 2:
|
||||
safe_range += 2
|
||||
lead_safe_range += 1
|
||||
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_base == 3:
|
||||
if outfielder.position == 'RF':
|
||||
safe_range += 2
|
||||
elif outfielder.position == 'LF':
|
||||
safe_range -= 2
|
||||
|
||||
if 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
|
||||
|
||||
logger.info(f'Building embeds')
|
||||
|
||||
lead_runner_embed.add_field(name='', value='', inline=False)
|
||||
|
||||
if lead_base == 4:
|
||||
logger.info(f'lead base is 4, building strings')
|
||||
lead_strings = at_home_strings(lead_safe_range)
|
||||
|
||||
lead_runner_embed.add_field(name='Safe Range', value=lead_strings['safe'])
|
||||
lead_runner_embed.add_field(name='Catcher Check', value=lead_strings['catcher'])
|
||||
lead_runner_embed.add_field(name='Out Range', value=lead_strings['out'])
|
||||
|
||||
else:
|
||||
logger.info(f'lead base is 3, building strings')
|
||||
lead_strings = at_third_strings(lead_safe_range)
|
||||
|
||||
lead_runner_embed.add_field(name='Safe Range', value=lead_strings['safe'])
|
||||
lead_runner_embed.add_field(name='Out Range', value=lead_strings['out'])
|
||||
|
||||
if trail_runner == this_play.on_first:
|
||||
trail_runner_held = await ask_confirm(
|
||||
interaction=interaction,
|
||||
question=f'Was **{trail_runner.player.name}** held at first before the pitch?',
|
||||
label_type='yes'
|
||||
)
|
||||
logger.info(f'Trail runner held: {trail_runner_held}')
|
||||
if trail_runner_held:
|
||||
trail_runner_embed.add_field(name='Runner Held', value=f'-1')
|
||||
trail_safe_range -= 1
|
||||
logger.info(f'Trail runner held, -1 to safe range: {trail_safe_range}')
|
||||
else:
|
||||
trail_runner_embed.add_field(name='Runner Not Held', value='+1')
|
||||
trail_safe_range += 1
|
||||
logger.info(f'Trail runner not held, +1 to safe range: {trail_safe_range}')
|
||||
|
||||
await interaction.channel.send(embeds=[lead_runner_embed, trail_runner_embed])
|
||||
|
||||
is_defense_throwing = await ask_confirm(
|
||||
interaction=interaction,
|
||||
@ -1533,7 +1787,7 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
|
||||
# Human throw is not being cut off
|
||||
if run_resp.send_trail:
|
||||
await interaction.channel.send(
|
||||
f'**{trail_runner.player.name}** is advancing {TO_BASE[trail_base]} as the trail runner with a safe range of 1->{trail_bc.running - 5 + of_rating.arm}!',
|
||||
f'**{trail_runner.player.name}** is advancing {TO_BASE[trail_base]} as the trail runner!',
|
||||
)
|
||||
is_throwing_lead = await ask_confirm(
|
||||
interaction=interaction,
|
||||
@ -1554,23 +1808,22 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
|
||||
|
||||
# Throw is going to trail runner
|
||||
else:
|
||||
is_trail_out = await ask_confirm(
|
||||
interaction=interaction,
|
||||
question=f'Was **{trail_runner.player.name}** thrown out {AT_BASE[trail_base]}?',
|
||||
label_type='yes'
|
||||
)
|
||||
runner_thrown_out = await out_at_base(trail_safe_range, trail_runner, trail_base)
|
||||
|
||||
if is_trail_out:
|
||||
if runner_thrown_out:
|
||||
logger.info(f'Runner was thrown out')
|
||||
# Log out on play
|
||||
this_play.outs += 1
|
||||
|
||||
# Remove trail runner
|
||||
logger.info(f'Remove trail runner')
|
||||
if this_play.on_first == trail_runner:
|
||||
this_play.on_first_final = None
|
||||
else:
|
||||
this_play.batter_final = None
|
||||
|
||||
# Advance lead runner extra base
|
||||
logger.info(f'Advance lead runner extra base')
|
||||
if this_play.on_second == lead_runner:
|
||||
this_play.rbi += 1
|
||||
this_play.on_second_final = 4
|
||||
@ -1588,23 +1841,25 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
|
||||
await interaction.channel.send(content=f'**{trail_runner.player.name}** is NOT trailing to {TO_BASE[trail_base]}.')
|
||||
|
||||
# Ball is going to lead base, ask if safe
|
||||
is_lead_out = await ask_confirm(
|
||||
logger.info(f'Throw is going to lead base')
|
||||
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,
|
||||
question=f'Was **{lead_runner.player.name}** thrown out {AT_BASE[lead_base]}?',
|
||||
label_type='yes',
|
||||
)
|
||||
|
||||
# Lead runner is thrown out
|
||||
if is_lead_out:
|
||||
if runner_thrown_out:
|
||||
logger.info(f'Lead runner is thrown out.')
|
||||
this_play.outs += 1
|
||||
|
||||
if this_play.on_second == lead_runner:
|
||||
logger.info(f'setting lead runner on_second_final')
|
||||
this_play.on_second_final = None if is_lead_out else lead_base
|
||||
this_play.on_second_final = None if runner_thrown_out else lead_base
|
||||
elif this_play.on_first == lead_runner:
|
||||
logger.info(f'setting lead runner on_first')
|
||||
this_play.on_first_final = None if is_lead_out else lead_base
|
||||
this_play.on_first_final = None if runner_thrown_out else lead_base
|
||||
else:
|
||||
log_exception(LineupsMissingException, f'Could not find lead runner to set final destination')
|
||||
|
||||
@ -2393,8 +2648,6 @@ def undo_play(session: Session, this_play: Play):
|
||||
logger.warning(f'Deleting lineup IDs: {new_player_ids}')
|
||||
session.exec(delete(Lineup).where(Lineup.id.in_(new_player_ids)))
|
||||
|
||||
# TODO: check for runners that scored in previous play, find their last AB, and set run and e_run to 0
|
||||
|
||||
session.commit()
|
||||
|
||||
try:
|
||||
@ -2901,6 +3154,7 @@ async def manual_end_game(session: Session, interaction: discord.Interaction, th
|
||||
|
||||
async def groundballs(session: Session, interaction: discord.Interaction, this_play: Play, groundball_letter: Literal['a', 'b', 'c']):
|
||||
if this_play.on_base_code == 2 and groundball_letter in ['a', 'b']:
|
||||
logger.info(f'Groundball {groundball_letter} with runner on second')
|
||||
to_right_side = await ask_confirm(
|
||||
interaction,
|
||||
question=f'Was that ball hit to either 1B or 2B?',
|
||||
@ -2909,12 +3163,38 @@ async def groundballs(session: Session, interaction: discord.Interaction, this_p
|
||||
this_play = gb_result_6(session, this_play, to_right_side)
|
||||
|
||||
elif this_play.on_base_code in [3, 6] and groundball_letter in ['a', 'b']:
|
||||
to_mif = await ask_confirm(
|
||||
interaction,
|
||||
question=f'Was that ball hit to either 2B or SS?',
|
||||
label_type='yes'
|
||||
)
|
||||
this_play = gb_result_5(session, this_play, to_mif)
|
||||
logger.info(f'Groundball {groundball_letter} with runner on third')
|
||||
def_alignment = this_play.managerai.defense_alignment(session, this_play.game)
|
||||
|
||||
if this_play.game.ai_team is not None and this_play.pitcher.team.is_ai and def_alignment.infield_in:
|
||||
logger.info(f'AI on defense, hit to MIF, playing in')
|
||||
this_play = gb_result_7(session, this_play)
|
||||
|
||||
else:
|
||||
logger.info(f'Checking if hit to MIF')
|
||||
to_mif = await ask_confirm(
|
||||
interaction,
|
||||
question=f'Was that ball hit to either 2B or SS?',
|
||||
label_type='yes'
|
||||
)
|
||||
|
||||
if not to_mif:
|
||||
logger.info(f'Not to a MIF, gb 7')
|
||||
this_play = gb_result_7(session, this_play)
|
||||
|
||||
else:
|
||||
logger.info(f'AI batting, hit to MIF')
|
||||
mif_playing_in = await ask_confirm(
|
||||
interaction,
|
||||
question=f'Were they playing in?',
|
||||
label_type='yes',
|
||||
)
|
||||
if mif_playing_in:
|
||||
logger.info(f'playing in, gb 7')
|
||||
this_play = gb_result_7(session, this_play)
|
||||
else:
|
||||
logger.info(f'playing back, gb 5')
|
||||
this_play = gb_result_5(session, this_play, to_mif)
|
||||
|
||||
else:
|
||||
this_play = await gb_letter(session, interaction, this_play, groundball_letter.upper(), 'None', False)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user