paper-dynasty-discord/gauntlets.py
Cal Corum 4be6afb541 Add API timeout/retry logic and fix get_team_by_owner for PostgreSQL
- Add APITimeoutError exception and retry logic to db_get
- Add timeout handling to db_post, db_put, db_patch, db_delete
- Fix get_team_by_owner to prefer non-gauntlet team (PostgreSQL migration fix)
- Code formatting cleanup (black)
2026-01-31 15:52:14 -06:00

2575 lines
95 KiB
Python

import copy
import datetime
import logging
import random
from typing import Literal
import discord
from sqlmodel import Session
from discord import SelectOption
from exceptions import *
from in_game import ai_manager
import helpers
from helpers import RARITY, get_or_create_role, send_to_channel, get_channel
from api_calls import db_get, db_post, db_delete, db_patch
from in_game.gameplay_models import Lineup, Team
from in_game.gameplay_queries import (
get_player_or_none,
get_team_or_none,
get_or_create_ai_card,
get_player_id_from_dict,
)
from utilities.dropdown import DropdownView, SelectPokemonEvolution
logger = logging.getLogger("discord_app")
async def wipe_team(
this_team: Team,
interaction: discord.Interaction,
delete_team: bool = False,
delete_runs: bool = False,
):
await interaction.edit_original_response(content=f"Looking for cards...")
# Delete cards
# c_query = await db_get('cards', params=[('team_id', this_team['id'])])
# await interaction.edit_original_response(content=f'Found {c_query["count"]} cards; deleting cards...')
# for x in c_query['cards']:
# await db_delete('cards', object_id=x['id'])
c_query = await db_post(f"cards/wipe-team/{this_team.id}")
# Delete packs
await interaction.edit_original_response(
content=f"Done deleting cards; searching for packs..."
)
p_query = await db_get("packs", params=[("team_id", this_team.id)])
await interaction.edit_original_response(
content=f"Found {p_query['count']} packs; deleting packs..."
)
for x in p_query["packs"]:
await db_delete("packs", object_id=x["id"])
# Delete team
if delete_team:
await interaction.edit_original_response(
content=f"Done deleting packs; now deleting team..."
)
await db_delete("teams", object_id=this_team.id)
await interaction.edit_original_response(
content=f"Team is deleted; now finding the run..."
)
if delete_runs:
r_query = await db_get(
"gauntletruns", params=[("team_id", this_team.id), ("is_active", True)]
)
await interaction.edit_original_response(
content=f"Found {r_query['count']} runs; deleting now..."
)
for x in r_query["runs"]:
await db_delete("gauntletruns", object_id=x["id"])
def get_game_code(this_team, this_event, this_run):
return f"gauntlet-{this_event['id']}-run-{this_run['id']}"
def games_played(this_run):
return this_run["wins"] + this_run["losses"]
def is_home_team(this_team, this_event, this_run):
if this_event["id"] in [1, 2]:
return True
return False
async def get_opponent(session: Session, this_team, this_event, this_run) -> Team:
gp = games_played(this_run)
if this_event["id"] == 1:
if gp == 0:
t_id = 30
elif gp == 1:
t_id = 12
elif gp == 2:
t_id = 15
elif gp == 3:
t_id = 13
elif gp == 4:
t_id = 6
elif gp == 5:
t_id = 4
elif gp == 6:
t_id = 23
elif gp == 7:
t_id = 16
elif gp == 8:
t_id = 2
elif gp == 9:
t_id = 14
elif gp == 10:
t_id = 58
else:
raise KeyError(f"Huh...I have no idea who you should be playing right now.")
elif this_event["id"] == 2:
if gp == 0:
t_id = 23
elif gp == 1:
t_id = 15
elif gp == 2:
t_id = 24
elif gp == 3:
t_id = 25
elif gp == 4:
t_id = 18
elif gp == 5:
t_id = 6
elif gp == 6:
t_id = 16
elif gp == 7:
t_id = 2
elif gp == 8:
t_id = 5
elif gp == 9:
t_id = 9
elif gp == 10:
t_id = 28
else:
raise KeyError(f"Huh...I have no idea who you should be playing right now.")
elif this_event["id"] == 3:
if gp == 0:
t_id = 28
elif gp == 1:
t_id = 7
elif gp == 2:
t_id = 15
elif gp == 3:
t_id = 6
elif gp == 4:
t_id = 21
elif gp == 5:
t_id = 23
elif gp == 6:
t_id = 24
elif gp == 7:
t_id = 13
elif gp == 8:
t_id = 4
elif gp == 9:
t_id = 2
elif gp == 10:
t_id = 19
else:
raise KeyError(f"Huh...I have no idea who you should be playing right now.")
elif this_event["id"] == 4:
if gp == 0:
t_id = 3
elif gp == 1:
t_id = 1
elif gp == 2:
t_id = 24
elif gp == 3:
t_id = 25
elif gp == 4:
t_id = 21
elif gp == 5:
t_id = 16
elif gp == 6:
t_id = 30
elif gp == 7:
t_id = 29
elif gp == 8:
t_id = 10
elif gp == 9:
t_id = 8
elif gp == 10:
t_id = 79
else:
raise KeyError(f"Hmm...I do not know who you should be playing right now.")
elif this_event["id"] == 5:
if gp == 0:
t_id = 15
elif gp == 1:
t_id = 10
elif gp == 2:
t_id = 28
elif gp == 3:
t_id = 30
elif gp == 4:
t_id = 7
elif gp == 5:
t_id = 22
elif gp == 6:
t_id = 23
elif gp == 7:
t_id = 2
elif gp == 8:
t_id = 14
elif gp == 9:
t_id = 4
elif gp == 10:
t_id = 19
else:
raise KeyError(f"Hmm...I do not know who you should be playing right now.")
elif this_event["id"] == 6:
if gp == 0:
t_id = 18
elif gp == 1:
t_id = 6
elif gp == 2:
t_id = 17
elif gp == 3:
t_id = 21
elif gp == 4:
t_id = 4
elif gp == 5:
t_id = 23
elif gp == 6:
t_id = 5
elif gp == 7:
t_id = 3
elif gp == 8:
t_id = 19
elif gp == 9:
t_id = 27
elif gp == 10:
t_id = 25
else:
raise KeyError(f"Hmm...I do not know who you should be playing right now.")
elif this_event["id"] == 7:
if gp == 0:
t_id = 10
elif gp == 1:
t_id = 20
elif gp == 2:
t_id = 25
elif gp == 3:
t_id = 27
elif gp == 4:
t_id = 6
elif gp == 5:
t_id = 5
elif gp == 6:
t_id = 4
elif gp == 7:
t_id = 16
elif gp == 8:
t_id = 13
elif gp == 9:
t_id = 30
elif gp == 10:
t_id = 17
else:
raise KeyError(f"Hmm...I do not know who you should be playing right now.")
elif this_event["id"] == 8:
if gp == 0:
teams = [6, 9] # White Sox and Rockies
elif gp == 1:
teams = [22, 30, 20, 2] # Pirates, Nats, A's, Braves
elif gp == 2:
teams = [3, 15, 12] # Orioles, Marlins, Royals
elif gp == 3:
teams = [17, 8, 13] # Twins, Guardians, Angels
elif gp == 4:
teams = [13, 1, 28] # Angels, Dbacks, Rangers
elif gp == 5:
teams = [26, 27] # Cardinals, Rays
elif gp == 6:
teams = [7, 25, 4] # Reds, Giants, Red Sox
elif gp == 7:
teams = [24, 23, 19] # Mariners, Padres, Yankees
elif gp == 8:
teams = [18, 21, 11] # Mets, Phillies, Astros
elif gp == 9:
teams = [14, 29, 16] # Dodgers, Blue Jays, Brewers
elif gp == 10:
teams = [5, 10] # Cubs, Tigers
else:
raise KeyError(f"Hmm...I do not know who you should be playing right now.")
t_id = teams[random.randint(0, len(teams) - 1)]
elif this_event["id"] == 9:
gp_to_tid = {
0: 7,
1: 4,
2: 19,
3: 22,
4: 30,
5: 3,
6: 2,
7: 1,
8: 26,
9: 20,
10: 6,
}
try:
t_id = gp_to_tid[gp]
except KeyError:
raise KeyError(
f"Hmm...I do not know who you should be playing with {gp} games played."
)
else:
return None
this_team = await get_team_or_none(session, team_id=t_id)
logger.info(f"Gauntlet opponent: {this_team}")
return await get_team_or_none(session, t_id)
async def build_lineup(this_team, this_game, this_event, sp_name):
return await ai_manager.build_lineup(
this_team, this_game.id, f"gauntlet-{this_event['id']}", sp_name
)
async def get_starting_pitcher(session, this_team, this_game, this_event, this_run):
sp_rank = (games_played(this_run) % 5) + 1
starter = await db_get(
f"teams/{this_team.id}/sp/gauntlet-{this_event['id']}?sp_rank={sp_rank}"
)
logger.info(f"starter: {starter}")
this_player = await get_player_or_none(session, get_player_id_from_dict(starter))
if this_player is None:
log_exception(
PlayerNotFoundException, "Could not pull the AI's starting pitcher"
)
# get player card; create one if none found
logger.info(f"SP this_player: {this_player}")
this_card = await get_or_create_ai_card(session, this_player, this_team)
return Lineup(
team=this_team,
player=this_player,
card=this_card,
position="P",
batting_order=10,
is_fatigued=False,
game=this_game,
)
async def run_draft(
interaction: discord.Interaction,
main_team: Team,
this_event,
draft_team: Team = None,
):
logger.info(
f"Starting draft for {main_team.abbrev if draft_team is None else draft_team.abbrev}"
)
if this_event["id"] == 1:
embed_title = f"{main_team.lname} - {this_event['name']} Draft"
embed_description = f"{this_event['name']}"
base_params = copy.deepcopy(ai_manager.GAUNTLET1_PARAMS)
base_params.extend([("limit", 8), ("cardset_id", 8)])
elif this_event["id"] == 2:
embed_title = f"{main_team.lname} - {this_event['name']} Draft"
embed_description = f"{this_event['name']}"
base_params = copy.deepcopy(ai_manager.GAUNTLET2_PARAMS)
base_params.extend([("limit", 8)])
elif this_event["id"] == 3:
embed_title = f"{main_team.lname} - {this_event['name']} Draft"
embed_description = f"{this_event['name']}"
base_params = [
("cardset_id", 8),
("cardset_id", 13),
("cardset_id", 14),
("cardset_id", 15),
("limit", 8),
]
elif this_event["id"] == 4:
embed_title = f"{main_team.lname} - {this_event['name']} Draft"
embed_description = f"{this_event['name']}"
base_params = [
("cardset_id", 3),
("cardset_id", 4),
("cardset_id", 6),
("cardset_id", 16),
("cardset_id", 15),
("limit", 8),
]
elif this_event["id"] == 5:
embed_title = f"{main_team.lname} - {this_event['name']} Draft"
embed_description = f"{this_event['name']}"
base_params = [
("cardset_id", 17),
("cardset_id", 18),
("cardset_id", 19),
("cardset_id", 16),
("cardset_id", 8),
("limit", 8),
]
elif this_event["id"] == 6:
embed_title = f"{main_team.lname} - {this_event['name']} Draft"
embed_description = f"{this_event['name']}"
base_params = [
("cardset_id", 20),
("cardset_id", 21),
("cardset_id", 22),
("cardset_id", 16),
("cardset_id", 8),
("limit", 8),
]
elif this_event["id"] == 7:
embed_title = f"{main_team.lname} - {this_event['name']} Draft"
embed_description = f"{this_event['name']}"
base_params = [
("cardset_id", 5),
("cardset_id", 1),
("cardset_id", 3),
("cardset_id", 4),
("cardset_id", 23),
("cardset_id", 22),
("limit", 4),
]
elif this_event["id"] == 8:
embed_title = f"{main_team.lname} - {this_event['name']} Draft"
embed_description = f"{this_event['name']}"
base_params = [
("cardset_id", 24),
("cardset_id", 25),
("cardset_id", 22),
("cardset_id", 23),
("limit", 8),
]
elif this_event["id"] == 9:
embed_title = f"{main_team.lname} - {this_event['name']} Draft"
embed_description = f"{this_event['name']}"
base_params = [
("cardset_id", 27),
("cardset_id", 28),
("cardset_id", 29),
("limit", 8),
]
else:
logger.error(f"run_draft - Event ID {this_event['id']} not recognized")
raise KeyError(f"Draft data not found for Gauntlet {this_event['id']}")
if draft_team is None:
# Post draft team linked to main team
draft_team = await db_post(
"teams",
payload={
"abbrev": f"Gauntlet-{main_team.abbrev}",
"sname": main_team.sname,
"lname": main_team.lname,
"gmid": main_team.gmid,
"gmname": main_team.gmname,
"gsheet": "NONE",
"logo": main_team.logo if main_team.logo else None,
"color": main_team.color if main_team.color else None,
"season": main_team.season,
"has_guide": main_team.has_guide,
},
)
all_players = []
p_names = []
counts = {
"SP": 0,
"RP": 0,
"CP": 0,
"C": 0,
"1B": 0,
"2B": 0,
"3B": 0,
"SS": 0,
"LF": 0,
"CF": 0,
"RF": 0,
"DH": 0,
"Hall of Fame": 0,
"MVP": 0,
"All-Star": 0,
"Starter": 0,
"Reserve": 0,
"Replacement": 0,
}
max_counts = {
"Hall of Fame": 1,
"MVP": 1,
"All-Star": 3,
"Starter": 9,
"Reserve": 7,
"Replacement": 5,
}
if this_event["id"] in [1, 2]:
max_counts["MVP"] = 2
elif this_event["id"] in [5, 6, 8, 9]:
# Handle draft_team as either Team object or dict
dt_season = (
draft_team.season if isinstance(draft_team, Team) else draft_team["season"]
)
dt_id = draft_team.id if isinstance(draft_team, Team) else draft_team["id"]
g_query = await db_get(
"games",
params=[
("season", dt_season),
("team1_id", dt_id),
("gauntlet_id", this_event["id"]),
],
)
if g_query["count"] > 4:
game_count = g_query["count"]
if game_count <= 14:
max_counts = {
"Hall of Fame": 1,
"MVP": 1,
"All-Star": 3,
"Starter": 10,
"Reserve": 7,
"Replacement": 4,
}
elif game_count <= 24:
max_counts = {
"Hall of Fame": 1,
"MVP": 1,
"All-Star": 4,
"Starter": 10,
"Reserve": 7,
"Replacement": 3,
}
elif game_count <= 34:
max_counts = {
"Hall of Fame": 1,
"MVP": 2,
"All-Star": 4,
"Starter": 10,
"Reserve": 7,
"Replacement": 2,
}
elif game_count <= 49:
max_counts = {
"Hall of Fame": 2,
"MVP": 2,
"All-Star": 4,
"Starter": 10,
"Reserve": 7,
"Replacement": 1,
}
elif game_count <= 64:
max_counts = {
"Hall of Fame": 2,
"MVP": 2,
"All-Star": 4,
"Starter": 11,
"Reserve": 7,
"Replacement": 0,
}
elif game_count <= 79:
max_counts = {
"Hall of Fame": 2,
"MVP": 2,
"All-Star": 5,
"Starter": 11,
"Reserve": 6,
"Replacement": 0,
}
elif game_count <= 99:
max_counts = {
"Hall of Fame": 2,
"MVP": 3,
"All-Star": 5,
"Starter": 11,
"Reserve": 5,
"Replacement": 0,
}
elif game_count <= 119:
max_counts = {
"Hall of Fame": 2,
"MVP": 3,
"All-Star": 5,
"Starter": 12,
"Reserve": 4,
"Replacement": 0,
}
elif game_count <= 139:
max_counts = {
"Hall of Fame": 2,
"MVP": 3,
"All-Star": 6,
"Starter": 12,
"Reserve": 3,
"Replacement": 0,
}
elif game_count <= 164:
max_counts = {
"Hall of Fame": 2,
"MVP": 4,
"All-Star": 6,
"Starter": 12,
"Reserve": 2,
"Replacement": 0,
}
elif game_count <= 189:
max_counts = {
"Hall of Fame": 3,
"MVP": 4,
"All-Star": 6,
"Starter": 12,
"Reserve": 1,
"Replacement": 0,
}
elif game_count <= 219:
max_counts = {
"Hall of Fame": 3,
"MVP": 4,
"All-Star": 6,
"Starter": 13,
"Reserve": 0,
"Replacement": 0,
}
elif game_count <= 249:
max_counts = {
"Hall of Fame": 3,
"MVP": 4,
"All-Star": 7,
"Starter": 12,
"Reserve": 0,
"Replacement": 0,
}
else:
max_counts = {
"Hall of Fame": 3,
"MVP": 5,
"All-Star": 7,
"Starter": 11,
"Reserve": 0,
"Replacement": 0,
}
logger.info(f"gauntlets.py - run_draft / max_counts: {max_counts}")
round_num = 1
counter = 0
view = helpers.Confirm([interaction.user])
if this_event["id"] == 1:
view.confirm.label = "Let's a-Go!"
else:
view.confirm.label = "Let's Go!"
intro_embed = await get_embed(this_event=this_event)
intro_embed.title += " - Are you ready?"
await interaction.edit_original_response(content=None, embed=intro_embed, view=view)
await view.wait()
if not view.value:
await interaction.edit_original_response(
content=None, embed=intro_embed, view=None
)
await interaction.channel.send("You'll be back")
raise ZeroDivisionError()
else:
await interaction.edit_original_response(
content=None, embed=intro_embed, view=None
)
def get_embeds(include_links=True, round_num=1):
top_embed = helpers.get_team_embed(f"{embed_title} - Round {round_num}")
top_embed.description = f"Rarity Counts"
bot_embed = helpers.get_team_embed(f"{embed_title} - Round {round_num}")
bot_embed.description = f"Current Roster"
all_str = {
"Hall of Fame": "",
"MVP": "",
"All-Star": "",
"Starter": "",
"Reserve": "",
"Replacement": "",
"C": "",
"1B": "",
"2B": "",
"3B": "",
"SS": "",
"LF": "",
"CF": "",
"RF": "",
"DH": "",
"SP": "",
"RP": "",
"CP": "",
}
for y in all_players:
if include_links:
name_string = f"[{helpers.player_desc(y)}]({y['image']})"
else:
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"
if max_counts["Hall of Fame"] > 0:
top_embed.add_field(
name=f"HoFs ({counts['Hall of Fame']}/{max_counts['Hall of Fame']})",
value=all_str["Hall of Fame"],
inline=False,
)
if max_counts["MVP"] > 0:
top_embed.add_field(
name=f"MVPs ({counts['MVP']}/{max_counts['MVP']})",
value=all_str["MVP"],
inline=False,
)
if max_counts["All-Star"] > 0:
top_embed.add_field(
name=f"All-Stars ({counts['All-Star']}/{max_counts['All-Star']})",
value=all_str["All-Star"],
inline=False,
)
if max_counts["Starter"] > 0:
top_embed.add_field(
name=f"Starters ({counts['Starter']}/{max_counts['Starter']})",
value=all_str["Starter"],
inline=False,
)
if max_counts["Reserve"] > 0:
top_embed.add_field(
name=f"Reserves ({counts['Reserve']}/{max_counts['Reserve']})",
value=all_str["Reserve"],
inline=False,
)
if max_counts["Replacement"] > 0:
top_embed.add_field(
name=f"Replacements ({counts['Replacement']}/{max_counts['Replacement']})",
value=all_str["Replacement"],
inline=False,
)
bot_embed.add_field(name=f"Catcher", value=all_str["C"], inline=False)
bot_embed.add_field(name=f"First Base", value=all_str["1B"], inline=False)
bot_embed.add_field(name=f"Second Base", value=all_str["2B"], inline=False)
bot_embed.add_field(name=f"Third Base", value=all_str["3B"], inline=False)
bot_embed.add_field(name=f"Shortstop", value=all_str["SS"], inline=False)
bot_embed.add_field(name=f"Left Field", value=all_str["LF"], inline=False)
bot_embed.add_field(name=f"Center Field", value=all_str["CF"], inline=False)
bot_embed.add_field(name=f"Right Field", value=all_str["RF"], inline=False)
bot_embed.add_field(
name=f"Designated Hitter", value=all_str["DH"], inline=False
)
bot_embed.add_field(name=f"Starting Pitcher", value=all_str["SP"], inline=False)
bot_embed.add_field(name=f"Relief Pitcher", value=all_str["RP"], inline=False)
bot_embed.add_field(name=f"Closing Pitcher", value=all_str["CP"], inline=False)
return [top_embed, bot_embed]
logger.info(f"getting last message")
last_message = await interaction.channel.send(
content=None, embeds=get_embeds(include_links=False)
)
async def draft_loop():
round_num = 1
counter = 0
while round_num <= 26 and counter < 50:
counter += 1
params = copy.deepcopy(base_params)
logger.info(
f"gauntlets.py - run_draft - event_id {this_event['id']} / round_num: {round_num} / counter: {counter} / counts: {counts} / max_counts: {max_counts}"
)
# Set rarity based on remaining counts
if counts["Hall of Fame"] < max_counts["Hall of Fame"]:
params.extend(
[("min_rarity", RARITY["HoF"]), ("max_rarity", RARITY["HoF"])]
)
elif counts["MVP"] < max_counts["MVP"]:
params.extend(
[("min_rarity", RARITY["MVP"]), ("max_rarity", RARITY["MVP"])]
)
elif counts["All-Star"] < max_counts["All-Star"]:
params.extend(
[
("min_rarity", RARITY["All-Star"]),
("max_rarity", RARITY["All-Star"]),
]
)
elif counts["Starter"] < max_counts["Starter"]:
params.extend(
[
("min_rarity", RARITY["Starter"]),
("max_rarity", RARITY["Starter"]),
]
)
elif counts["Reserve"] < max_counts["Reserve"]:
params.extend(
[
("min_rarity", RARITY["Reserve"]),
("max_rarity", RARITY["Reserve"]),
]
)
else:
params.extend(
[
("min_rarity", RARITY["Replacement"]),
("max_rarity", RARITY["Replacement"]),
]
)
this_batch = []
for x in ["SP", "RP", "IF", "OF"]:
# Slot 1 - SP
if x == "SP":
if counts["SP"] > 5:
slot_params = [("pos_exc", "SP")]
if counts["RP"] > 7:
slot_params = [("pos_exc", "RP")]
else:
slot_params = [("pos_inc", "SP")]
# if counts['SP'] > 5:
# slot_params = [('pos_exc', 'SP')]
# elif counts['RP'] < 6:
# slot_params = [('pos_inc', 'RP')]
# else:
# slot_params = [('pos_exc', 'SP'), ('pos_exc', 'RP')]
# Slot 2 - RP
elif x == "RP":
logger.info(f"counts[RP]: {counts['RP']}")
if counts["RP"] > 7:
slot_params = [("pos_exc", "RP")]
if counts["SP"] > 5:
slot_params = [("pos_exc", "SP")]
else:
slot_params = [("pos_inc", "RP")]
# Slot 3 - IF
elif x == "IF":
slot_params = []
for y in ["1B", "2B", "3B", "SS", "C"]:
if (counts[y] > 1) and 0 in [
counts["C"],
counts["1B"],
counts["2B"],
counts["3B"],
counts["SS"],
]:
slot_params.append(("pos_exc", y))
elif (y == "C" and counts["C"] < 3) or (
y != "C" and counts[y] < 4
):
slot_params.append(("pos_inc", y))
# if counts['C'] < 2:
# slot_params.append(('pos_inc', 'C'))
# if len(slot_params) == 0:
# slot_params = [('pos_exc', 'C'), ('pos_exc', '1B'), ('pos_exc', '2B'), ('pos_exc', '3B'),
# ('pos_exc', 'SS')]
# Slot 4 - OF
else:
slot_params = []
for y in ["LF", "CF", "RF"]:
if counts[y] > 4:
slot_params.append(("pos_exc", y))
elif counts[y] > 1 and 0 in [
counts["LF"],
counts["CF"],
counts["RF"],
]:
slot_params.append(("pos_exc", y))
elif counts[y] < 5:
slot_params.append(("pos_inc", y))
# if len(slot_params) == 0:
# slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')]
logger.info(f"this_batch: {this_batch}")
logger.info(f"slot_params: {slot_params}")
logger.info(f"params: {params}")
# No position explicitly requested or denied
if len(slot_params) == 0:
if (counts["SP"] + counts["RP"]) > (
counts["C"]
+ counts["1B"]
+ counts["2B"]
+ counts["SS"]
+ counts["LF"]
+ counts["CF"]
+ counts["RF"]
):
pos_counts = [
("C", counts["C"]),
("1B", counts["1B"]),
("2B", counts["2B"]),
("3B", counts["3B"]),
("SS", counts["SS"]),
("LF", counts["LF"]),
("CF", counts["CF"]),
("RF", counts["RF"]),
]
pos_counts.sort(key=lambda z: z[1])
slot_params = [("pos_inc", pos_counts[0][0])]
else:
if counts["SP"] >= counts["RP"]:
slot_params = [("pos_inc", "RP")]
else:
slot_params = [("pos_inc", "SP")]
slot_params.extend(params)
p_query = await db_get("players/random", params=slot_params, timeout=10)
# Fallback for Event 9 RP shortage
if this_event["id"] == 9 and x == "RP" and p_query["count"] < 3:
logger.warning(
f"Low RP count ({p_query['count']}) in Event 9, expanding cardsets to 24, 25, 26"
)
fallback_params = [p for p in slot_params if p[0] != "cardset_id"]
fallback_params.extend(
[("cardset_id", 24), ("cardset_id", 25), ("cardset_id", 26)]
)
p_query = await db_get(
"players/random", params=fallback_params, timeout=10
)
logger.info(
f"Fallback query returned {p_query['count']} RP options"
)
if p_query["count"] > 0:
# test_player_list = ''
# for z in p_query['players']:
# test_player_list += f'{z["rarity"]["name"]} - {z["description"]} - {helpers.get_all_pos(x)}\n'
# Collect 1 cards with no repeat player names
for i in p_query["players"]:
if i["p_name"] not in p_names and i not in this_batch:
this_batch.append(i)
break
if len(this_batch) < 4:
logger.error(f"Pulled less than 4 players in gauntlet draft")
p_query = await db_get("players/random", params=params, timeout=10)
for i in p_query["players"]:
if i["p_name"] not in p_names and i not in this_batch:
this_batch.append(i)
if len(this_batch) >= 4:
break
if len(this_batch) < 4:
raise KeyError(
f"This is embarassing, but I couldn't find enough players for you to draft from."
)
# Present choices and capture selection
p_choice = await helpers.get_choice_from_cards(
interaction, this_batch, delete_message=True
)
# Add player to list and update counts
p_names.append(p_choice["p_name"])
counts[p_choice["rarity"]["name"]] += 1
all_players.append(p_choice)
if p_choice["pos_1"] in ["SP", "RP"]:
counts[p_choice["pos_1"]] += 1
else:
for x in helpers.get_all_pos(p_choice):
if x in counts:
counts[x] += 1
# Update roster embed
round_num += 1
await last_message.edit(
content=None,
embeds=get_embeds(include_links=False, round_num=round_num),
)
logger.info(f"going into draft")
backyard_round = None
custom_player_round = None
if this_event["id"] == 1:
mario_round = None
while round_num <= 26 and counter < 50:
counter += 1
params = copy.deepcopy(base_params)
# Set rarity param based on round number
if round_num == 1:
params.extend(
[("min_rarity", RARITY["MVP"]), ("max_rarity", RARITY["MVP"])]
)
elif round_num == 2:
params.extend(
[
("min_rarity", RARITY["All-Star"]),
("max_rarity", RARITY["All-Star"]),
]
)
elif round_num <= 5:
params.extend(
[
("min_rarity", RARITY["Starter"]),
("max_rarity", RARITY["Starter"]),
]
)
elif round_num == 6:
if random.randint(1, 2) == 1:
params = [
("min_rarity", RARITY["MVP"]),
("max_rarity", RARITY["MVP"]),
("cardset_id", 8),
]
mario_round = 6
else:
params.extend(
[
("min_rarity", RARITY["MVP"]),
("max_rarity", RARITY["MVP"]),
("pos_exc", "RP"),
]
)
elif round_num == 7:
if random.randint(1, 2) == 1 and mario_round is None:
params = [
("min_rarity", RARITY["All-Star"]),
("max_rarity", RARITY["All-Star"]),
("cardset_id", 8),
]
mario_round = 7
else:
params.extend(
[
("min_rarity", RARITY["All-Star"]),
("max_rarity", RARITY["All-Star"]),
]
)
elif round_num == 8:
if mario_round is None:
params = [
("min_rarity", RARITY["Starter"]),
("max_rarity", RARITY["Starter"]),
("cardset_id", 8),
]
mario_round = 12
else:
params.extend(
[
("min_rarity", RARITY["Starter"]),
("max_rarity", RARITY["Starter"]),
]
)
elif round_num <= 11:
params.extend(
[
("min_rarity", RARITY["Starter"]),
("max_rarity", RARITY["Starter"]),
]
)
elif round_num <= 15:
params.extend(
[
("min_rarity", RARITY["Reserve"]),
("max_rarity", RARITY["Reserve"]),
]
)
elif round_num <= 18:
params.extend(
[
("min_rarity", RARITY["Replacement"]),
("max_rarity", RARITY["Replacement"]),
]
)
elif round_num == 19:
params.extend(
[
("min_rarity", RARITY["All-Star"]),
("max_rarity", RARITY["All-Star"]),
]
)
elif round_num <= 21:
params.extend(
[
("min_rarity", RARITY["Starter"]),
("max_rarity", RARITY["Starter"]),
]
)
elif round_num <= 24:
params.extend(
[
("min_rarity", RARITY["Reserve"]),
("max_rarity", RARITY["Reserve"]),
]
)
elif round_num <= 26:
params.extend(
[
("min_rarity", RARITY["Replacement"]),
("max_rarity", RARITY["Replacement"]),
]
)
this_batch = []
for x in ["SP", "RP", "IF", "OF"]:
# Slot 1 - SP
if x == "SP":
if counts["SP"] < 6:
slot_params = [("pos_inc", "SP")]
elif counts["RP"] < 6:
slot_params = [("pos_inc", "RP")]
else:
slot_params = [("pos_exc", "SP"), ("pos_exc", "RP")]
# Slot 2 - RP
elif x == "RP":
logger.info(f"counts[RP]: {counts['RP']}")
if counts["RP"] < 8:
slot_params = [("pos_inc", "RP")]
elif counts["SP"] < 4:
slot_params = [("pos_inc", "SP")]
else:
slot_params = [("pos_exc", "SP"), ("pos_exc", "RP")]
# Slot 3 - IF
elif x == "IF":
slot_params = []
for y in ["1B", "2B", "3B", "SS"]:
if (counts[y] == 2 or counts[y] == 3) and 0 not in [
counts["C"],
counts["1B"],
counts["2B"],
counts["3B"],
counts["SS"],
counts["LF"],
counts["CF"],
counts["RF"],
]:
slot_params.append(("pos_inc", y))
elif counts[y] < 4:
slot_params.append(("pos_inc", y))
if counts["C"] < 2:
slot_params.append(("pos_inc", "C"))
if len(slot_params) == 0:
slot_params = [
("pos_exc", "C"),
("pos_exc", "1B"),
("pos_exc", "2B"),
("pos_exc", "3B"),
("pos_exc", "SS"),
]
# Slot 4 - OF
else:
slot_params = []
for y in ["LF", "CF", "RF"]:
if counts[y] > 4:
pass
elif counts[y] > 2 and 0 not in [
counts["LF"],
counts["CF"],
counts["RF"],
]:
slot_params.append(("pos_inc", y))
elif counts[y] < 3:
slot_params.append(("pos_inc", y))
if len(slot_params) == 0:
slot_params = [
("pos_exc", "LF"),
("pos_exc", "CF"),
("pos_exc", "RF"),
]
logger.info(f"this_batch: {this_batch}")
logger.info(f"slot_params: {slot_params}")
logger.info(f"params: {params}")
slot_params.extend(params)
p_query = await db_get("players/random", params=slot_params, timeout=10)
if p_query["count"] > 0:
# test_player_list = ''
# for z in p_query['players']:
# test_player_list += f'{z["rarity"]["name"]} - {z["description"]} - {helpers.get_all_pos(x)}\n'
# Collect 1 cards with no repeat player names
for i in p_query["players"]:
if i["p_name"] not in p_names and i not in this_batch:
this_batch.append(i)
break
if len(this_batch) < 4:
logger.error(f"Pulled less than 4 players in gauntlet draft")
p_query = await db_get("players/random", params=params, timeout=10)
for i in p_query["players"]:
if i["p_name"] not in p_names and i not in this_batch:
this_batch.append(i)
if len(this_batch) >= 4:
break
if len(this_batch) < 4:
raise KeyError(
f"This is embarassing, but I couldn't find enough players for you to draft from."
)
# Present choices and capture selection
p_choice = await helpers.get_choice_from_cards(
interaction, this_batch, delete_message=True
)
# Add player to list and update counts
p_names.append(p_choice["p_name"])
counts[p_choice["rarity"]["name"]] += 1
all_players.append(p_choice)
if p_choice["pos_1"] in ["SP", "RP"]:
counts[p_choice["pos_1"]] += 1
else:
for x in helpers.get_all_pos(p_choice):
if x in counts:
counts[x] += 1
# Update roster embed
round_num += 1
await last_message.edit(
content=None, embeds=get_embeds(include_links=False)
)
elif this_event["id"] == 2:
while round_num <= 26 and counter < 50:
counter += 1
params = copy.deepcopy(base_params)
# Set rarity param based on round number
if round_num == 1:
params.extend(
[("min_rarity", RARITY["MVP"]), ("max_rarity", RARITY["MVP"])]
)
elif round_num == 2:
params.extend(
[
("min_rarity", RARITY["All-Star"]),
("max_rarity", RARITY["All-Star"]),
]
)
elif round_num <= 5:
params.extend(
[
("min_rarity", RARITY["Starter"]),
("max_rarity", RARITY["Starter"]),
]
)
elif round_num == 6:
params.extend(
[
("min_rarity", RARITY["MVP"]),
("max_rarity", RARITY["MVP"]),
("pos_exc", "RP"),
]
)
elif round_num == 7:
params.extend(
[
("min_rarity", RARITY["All-Star"]),
("max_rarity", RARITY["All-Star"]),
]
)
elif round_num <= 11:
params.extend(
[
("min_rarity", RARITY["Starter"]),
("max_rarity", RARITY["Starter"]),
]
)
elif round_num <= 15:
params.extend(
[
("min_rarity", RARITY["Reserve"]),
("max_rarity", RARITY["Reserve"]),
]
)
elif round_num <= 18:
params.extend(
[
("min_rarity", RARITY["Replacement"]),
("max_rarity", RARITY["Replacement"]),
]
)
elif round_num == 19:
params.extend(
[
("min_rarity", RARITY["All-Star"]),
("max_rarity", RARITY["All-Star"]),
]
)
elif round_num <= 21:
params.extend(
[
("min_rarity", RARITY["Starter"]),
("max_rarity", RARITY["Starter"]),
]
)
elif round_num <= 24:
params.extend(
[
("min_rarity", RARITY["Reserve"]),
("max_rarity", RARITY["Reserve"]),
]
)
elif round_num <= 26:
params.extend(
[
("min_rarity", RARITY["Replacement"]),
("max_rarity", RARITY["Replacement"]),
]
)
this_batch = []
for x in ["SP", "RP", "IF", "OF"]:
# Slot 1 - SP
if x == "SP":
if counts["SP"] > 5:
slot_params = [("pos_exc", "RP")]
if counts["RP"] > 7:
slot_params = [("pos_exc", "SP")]
else:
slot_params = [("pos_inc", "SP")]
# if counts['SP'] > 5:
# slot_params = [('pos_exc', 'SP')]
# elif counts['RP'] < 6:
# slot_params = [('pos_inc', 'RP')]
# else:
# slot_params = [('pos_exc', 'SP'), ('pos_exc', 'RP')]
# Slot 2 - RP
elif x == "RP":
logger.info(f"counts[RP]: {counts['RP']}")
if counts["RP"] > 7:
slot_params = [("pos_exc", "RP")]
if counts["SP"] > 5:
slot_params = [("pos_exc", "SP")]
else:
slot_params = [("pos_inc", "RP")]
# Slot 3 - IF
elif x == "IF":
slot_params = []
for y in ["1B", "2B", "3B", "SS", "C"]:
if (counts[y] > 1) and 0 in [
counts["C"],
counts["1B"],
counts["2B"],
counts["3B"],
counts["SS"],
]:
slot_params.append(("pos_exc", y))
elif (y == "C" and counts["C"] < 3) or (
y != "C" and counts[y] < 4
):
slot_params.append(("pos_inc", y))
# if counts['C'] < 2:
# slot_params.append(('pos_inc', 'C'))
# if len(slot_params) == 0:
# slot_params = [('pos_exc', 'C'), ('pos_exc', '1B'), ('pos_exc', '2B'), ('pos_exc', '3B'),
# ('pos_exc', 'SS')]
# Slot 4 - OF
else:
slot_params = []
for y in ["LF", "CF", "RF"]:
if counts[y] > 4:
slot_params.append(("pos_exc", y))
elif counts[y] > 1 and 0 in [
counts["LF"],
counts["CF"],
counts["RF"],
]:
slot_params.append(("pos_exc", y))
elif counts[y] < 5:
slot_params.append(("pos_inc", y))
# if len(slot_params) == 0:
# slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')]
logger.info(f"this_batch: {this_batch}")
logger.info(f"slot_params: {slot_params}")
logger.info(f"params: {params}")
# No position explicitly requested or denied
if len(slot_params) == 0:
if (counts["SP"] + counts["RP"]) > (
counts["C"]
+ counts["1B"]
+ counts["2B"]
+ counts["SS"]
+ counts["LF"]
+ counts["CF"]
+ counts["RF"]
):
pos_counts = [
("C", counts["C"]),
("1B", counts["1B"]),
("2B", counts["2B"]),
("3B", counts["3B"]),
("SS", counts["SS"]),
("LF", counts["LF"]),
("CF", counts["CF"]),
("RF", counts["RF"]),
]
pos_counts.sort(key=lambda z: z[1])
slot_params = [("pos_inc", pos_counts[0][0])]
else:
if counts["SP"] >= counts["RP"]:
slot_params = [("pos_inc", "RP")]
else:
slot_params = [("pos_inc", "SP")]
slot_params.extend(params)
p_query = await db_get("players/random", params=slot_params, timeout=10)
if p_query["count"] > 0:
# test_player_list = ''
# for z in p_query['players']:
# test_player_list += f'{z["rarity"]["name"]} - {z["description"]} - {helpers.get_all_pos(x)}\n'
# Collect 1 cards with no repeat player names
for i in p_query["players"]:
if i["p_name"] not in p_names and i not in this_batch:
this_batch.append(i)
break
if len(this_batch) < 4:
logger.error(f"Pulled less than 4 players in gauntlet draft")
p_query = await db_get("players/random", params=params, timeout=10)
for i in p_query["players"]:
if i["p_name"] not in p_names and i not in this_batch:
this_batch.append(i)
if len(this_batch) >= 4:
break
if len(this_batch) < 4:
raise KeyError(
f"This is embarassing, but I couldn't find enough players for you to draft from."
)
# Present choices and capture selection
p_choice = await helpers.get_choice_from_cards(
interaction, this_batch, delete_message=True
)
# Add player to list and update counts
p_names.append(p_choice["p_name"])
counts[p_choice["rarity"]["name"]] += 1
all_players.append(p_choice)
if p_choice["pos_1"] in ["SP", "RP"]:
counts[p_choice["pos_1"]] += 1
else:
for x in helpers.get_all_pos(p_choice):
if x in counts:
counts[x] += 1
# Update roster embed
round_num += 1
await last_message.edit(
content=None, embeds=get_embeds(include_links=False)
)
elif this_event["id"] == 3:
while round_num <= 26 and counter < 50:
logger.info(f"round {round_num}")
counter += 1
params = copy.deepcopy(base_params)
# Set rarity param based on round number
if round_num == 1:
params.extend(
[("min_rarity", RARITY["HoF"]), ("max_rarity", RARITY["HoF"])]
)
elif round_num == 2:
params.extend(
[
("min_rarity", RARITY["All-Star"]),
("max_rarity", RARITY["All-Star"]),
]
)
elif round_num <= 5:
params.extend(
[
("min_rarity", RARITY["Starter"]),
("max_rarity", RARITY["Starter"]),
]
)
elif round_num == 6:
params.extend(
[
("min_rarity", RARITY["MVP"]),
("max_rarity", RARITY["MVP"]),
("pos_exc", "RP"),
]
)
elif round_num == 7:
params.extend(
[
("min_rarity", RARITY["All-Star"]),
("max_rarity", RARITY["All-Star"]),
]
)
elif round_num <= 11:
params.extend(
[
("min_rarity", RARITY["Starter"]),
("max_rarity", RARITY["Starter"]),
]
)
elif round_num <= 15:
params.extend(
[
("min_rarity", RARITY["Reserve"]),
("max_rarity", RARITY["Reserve"]),
]
)
elif round_num <= 18:
params.extend(
[
("min_rarity", RARITY["Replacement"]),
("max_rarity", RARITY["Replacement"]),
]
)
elif round_num == 19:
params.extend(
[
("min_rarity", RARITY["All-Star"]),
("max_rarity", RARITY["All-Star"]),
]
)
elif round_num <= 21:
params.extend(
[
("min_rarity", RARITY["Starter"]),
("max_rarity", RARITY["Starter"]),
]
)
elif round_num <= 24:
params.extend(
[
("min_rarity", RARITY["Reserve"]),
("max_rarity", RARITY["Reserve"]),
]
)
elif round_num <= 26:
params.extend(
[
("min_rarity", RARITY["Replacement"]),
("max_rarity", RARITY["Replacement"]),
]
)
logger.info(f"starting position loop")
this_batch = []
for x in ["SP", "RP", "IF", "OF"]:
# Slot 1 - SP
if x == "SP":
if counts["SP"] > 5:
slot_params = [("pos_exc", "RP")]
if counts["RP"] > 7:
slot_params = [("pos_exc", "SP")]
else:
slot_params = [("pos_inc", "SP")]
# if counts['SP'] > 5:
# slot_params = [('pos_exc', 'SP')]
# elif counts['RP'] < 6:
# slot_params = [('pos_inc', 'RP')]
# else:
# slot_params = [('pos_exc', 'SP'), ('pos_exc', 'RP')]
# Slot 2 - RP
elif x == "RP":
logger.info(f"counts[RP]: {counts['RP']}")
if counts["RP"] > 7:
slot_params = [("pos_exc", "RP")]
if counts["SP"] > 5:
slot_params = [("pos_exc", "SP")]
else:
slot_params = [("pos_inc", "RP")]
# Slot 3 - IF
elif x == "IF":
slot_params = []
for y in ["1B", "2B", "3B", "SS", "C"]:
if (counts[y] > 1) and 0 in [
counts["C"],
counts["1B"],
counts["2B"],
counts["3B"],
counts["SS"],
]:
slot_params.append(("pos_exc", y))
elif (y == "C" and counts["C"] < 3) or (
y != "C" and counts[y] < 4
):
slot_params.append(("pos_inc", y))
# if counts['C'] < 2:
# slot_params.append(('pos_inc', 'C'))
# if len(slot_params) == 0:
# slot_params = [('pos_exc', 'C'), ('pos_exc', '1B'), ('pos_exc', '2B'), ('pos_exc', '3B'),
# ('pos_exc', 'SS')]
# Slot 4 - OF
else:
slot_params = []
for y in ["LF", "CF", "RF"]:
if counts[y] > 4:
slot_params.append(("pos_exc", y))
elif counts[y] > 1 and 0 in [
counts["LF"],
counts["CF"],
counts["RF"],
]:
slot_params.append(("pos_exc", y))
elif counts[y] < 5:
slot_params.append(("pos_inc", y))
# if len(slot_params) == 0:
# slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')]
logger.info(f"this_batch: {this_batch}")
logger.info(f"slot_params: {slot_params}")
logger.info(f"params: {params}")
# No position explicitly requested or denied
if len(slot_params) == 0:
if (counts["SP"] + counts["RP"]) > (
counts["C"]
+ counts["1B"]
+ counts["2B"]
+ counts["SS"]
+ counts["LF"]
+ counts["CF"]
+ counts["RF"]
):
pos_counts = [
("C", counts["C"]),
("1B", counts["1B"]),
("2B", counts["2B"]),
("3B", counts["3B"]),
("SS", counts["SS"]),
("LF", counts["LF"]),
("CF", counts["CF"]),
("RF", counts["RF"]),
]
pos_counts.sort(key=lambda z: z[1])
slot_params = [("pos_inc", pos_counts[0][0])]
else:
if counts["SP"] >= counts["RP"]:
slot_params = [("pos_inc", "RP")]
else:
slot_params = [("pos_inc", "SP")]
slot_params.extend(params)
p_query = await db_get("players/random", params=slot_params, timeout=10)
if p_query["count"] > 0:
# test_player_list = ''
# for z in p_query['players']:
# test_player_list += f'{z["rarity"]["name"]} - {z["description"]} - {helpers.get_all_pos(x)}\n'
# Collect 1 cards with no repeat player names
for i in p_query["players"]:
if i["p_name"] not in p_names and i not in this_batch:
this_batch.append(i)
break
if len(this_batch) < 4:
logger.error(f"Pulled less than 4 players in gauntlet draft")
p_query = await db_get("players/random", params=params, timeout=10)
for i in p_query["players"]:
if i["p_name"] not in p_names and i not in this_batch:
this_batch.append(i)
if len(this_batch) >= 4:
break
if len(this_batch) < 4:
raise KeyError(
f"This is embarassing, but I couldn't find enough players for you to draft from."
)
# Present choices and capture selection
p_choice = await helpers.get_choice_from_cards(
interaction, this_batch, delete_message=True
)
# Add player to list and update counts
p_names.append(p_choice["p_name"])
counts[p_choice["rarity"]["name"]] += 1
all_players.append(p_choice)
if p_choice["pos_1"] in ["SP", "RP"]:
counts[p_choice["pos_1"]] += 1
else:
for x in helpers.get_all_pos(p_choice):
if x in counts:
counts[x] += 1
# Update roster embed
round_num += 1
await last_message.edit(
content=None, embeds=get_embeds(include_links=False)
)
elif this_event["id"] == 4:
while round_num <= 26 and counter < 50:
counter += 1
params = copy.deepcopy(base_params)
# Set rarity param based on round number
if round_num == 1:
params.extend(
[("min_rarity", RARITY["HoF"]), ("max_rarity", RARITY["HoF"])]
)
elif round_num == 2:
params.extend(
[
("min_rarity", RARITY["All-Star"]),
("max_rarity", RARITY["All-Star"]),
]
)
elif round_num <= 5:
params.extend(
[
("min_rarity", RARITY["Starter"]),
("max_rarity", RARITY["Starter"]),
]
)
elif round_num == 6:
if random.randint(1, 2) == 1:
params = [
("min_rarity", RARITY["MVP"]),
("max_rarity", RARITY["MVP"]),
("cardset_id", 16),
]
backyard_round = 6
else:
params.extend(
[
("min_rarity", RARITY["MVP"]),
("max_rarity", RARITY["MVP"]),
("pos_exc", "RP"),
]
)
elif round_num == 7:
if random.randint(1, 2) == 1 and backyard_round is None:
params = [
("min_rarity", RARITY["All-Star"]),
("max_rarity", RARITY["All-Star"]),
("cardset_id", 16),
]
backyard_round = 7
else:
params.extend(
[
("min_rarity", RARITY["All-Star"]),
("max_rarity", RARITY["All-Star"]),
]
)
elif round_num == 8:
if backyard_round is None:
params = [
("min_rarity", RARITY["Starter"]),
("max_rarity", RARITY["Starter"]),
("cardset_id", 16),
]
backyard_round = 8
else:
params.extend(
[
("min_rarity", RARITY["Starter"]),
("max_rarity", RARITY["Starter"]),
]
)
elif round_num <= 11:
params.extend(
[
("min_rarity", RARITY["Starter"]),
("max_rarity", RARITY["Starter"]),
]
)
elif round_num <= 15:
params.extend(
[
("min_rarity", RARITY["Reserve"]),
("max_rarity", RARITY["Reserve"]),
]
)
elif round_num <= 18:
params.extend(
[
("min_rarity", RARITY["Replacement"]),
("max_rarity", RARITY["Replacement"]),
]
)
elif round_num == 19:
params.extend(
[
("min_rarity", RARITY["All-Star"]),
("max_rarity", RARITY["All-Star"]),
]
)
elif round_num <= 21:
params.extend(
[
("min_rarity", RARITY["Starter"]),
("max_rarity", RARITY["Starter"]),
]
)
elif round_num <= 24:
params.extend(
[
("min_rarity", RARITY["Reserve"]),
("max_rarity", RARITY["Reserve"]),
]
)
elif round_num <= 26:
params.extend(
[
("min_rarity", RARITY["Replacement"]),
("max_rarity", RARITY["Replacement"]),
]
)
this_batch = []
for x in ["SP", "RP", "IF", "OF"]:
# Slot 1 - SP
if x == "SP":
if counts["SP"] > 5:
slot_params = [("pos_exc", "SP")]
if counts["RP"] > 7:
slot_params = [("pos_exc", "RP")]
else:
slot_params = [("pos_inc", "SP")]
# if counts['SP'] > 5:
# slot_params = [('pos_exc', 'SP')]
# elif counts['RP'] < 6:
# slot_params = [('pos_inc', 'RP')]
# else:
# slot_params = [('pos_exc', 'SP'), ('pos_exc', 'RP')]
# Slot 2 - RP
elif x == "RP":
logger.info(f"counts[RP]: {counts['RP']}")
if counts["RP"] > 7:
slot_params = [("pos_exc", "RP")]
if counts["SP"] > 5:
slot_params = [("pos_exc", "SP")]
else:
slot_params = [("pos_inc", "RP")]
# Slot 3 - IF
elif x == "IF":
slot_params = []
for y in ["1B", "2B", "3B", "SS", "C"]:
if (counts[y] > 1) and 0 in [
counts["C"],
counts["1B"],
counts["2B"],
counts["3B"],
counts["SS"],
]:
slot_params.append(("pos_exc", y))
elif (y == "C" and counts["C"] < 3) or (
y != "C" and counts[y] < 4
):
slot_params.append(("pos_inc", y))
# if counts['C'] < 2:
# slot_params.append(('pos_inc', 'C'))
# if len(slot_params) == 0:
# slot_params = [('pos_exc', 'C'), ('pos_exc', '1B'), ('pos_exc', '2B'), ('pos_exc', '3B'),
# ('pos_exc', 'SS')]
# Slot 4 - OF
else:
slot_params = []
for y in ["LF", "CF", "RF"]:
if counts[y] > 4:
slot_params.append(("pos_exc", y))
elif counts[y] > 1 and 0 in [
counts["LF"],
counts["CF"],
counts["RF"],
]:
slot_params.append(("pos_exc", y))
elif counts[y] < 5:
slot_params.append(("pos_inc", y))
# if len(slot_params) == 0:
# slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')]
logger.info(f"this_batch: {this_batch}")
logger.info(f"slot_params: {slot_params}")
logger.info(f"params: {params}")
# No position explicitly requested or denied
if len(slot_params) == 0:
if (counts["SP"] + counts["RP"]) > (
counts["C"]
+ counts["1B"]
+ counts["2B"]
+ counts["SS"]
+ counts["LF"]
+ counts["CF"]
+ counts["RF"]
):
pos_counts = [
("C", counts["C"]),
("1B", counts["1B"]),
("2B", counts["2B"]),
("3B", counts["3B"]),
("SS", counts["SS"]),
("LF", counts["LF"]),
("CF", counts["CF"]),
("RF", counts["RF"]),
]
pos_counts.sort(key=lambda z: z[1])
slot_params = [("pos_inc", pos_counts[0][0])]
else:
if counts["SP"] >= counts["RP"]:
slot_params = [("pos_inc", "RP")]
else:
slot_params = [("pos_inc", "SP")]
slot_params.extend(params)
p_query = await db_get("players/random", params=slot_params, timeout=10)
if p_query["count"] > 0:
# test_player_list = ''
# for z in p_query['players']:
# test_player_list += f'{z["rarity"]["name"]} - {z["description"]} - {helpers.get_all_pos(x)}\n'
# Collect 1 cards with no repeat player names
for i in p_query["players"]:
if i["p_name"] not in p_names and i not in this_batch:
this_batch.append(i)
break
if len(this_batch) < 4:
logger.error(f"Pulled less than 4 players in gauntlet draft")
p_query = await db_get("players/random", params=params, timeout=10)
for i in p_query["players"]:
if i["p_name"] not in p_names and i not in this_batch:
this_batch.append(i)
if len(this_batch) >= 4:
break
if len(this_batch) < 4:
raise KeyError(
f"This is embarassing, but I couldn't find enough players for you to draft from."
)
# Present choices and capture selection
p_choice = await helpers.get_choice_from_cards(
interaction, this_batch, delete_message=True
)
# Add player to list and update counts
p_names.append(p_choice["p_name"])
counts[p_choice["rarity"]["name"]] += 1
all_players.append(p_choice)
if p_choice["pos_1"] in ["SP", "RP"]:
counts[p_choice["pos_1"]] += 1
else:
for x in helpers.get_all_pos(p_choice):
if x in counts:
counts[x] += 1
# Update roster embed
round_num += 1
await last_message.edit(
content=None, embeds=get_embeds(include_links=False)
)
elif this_event["id"] in [5, 6, 8, 9]:
await draft_loop()
elif this_event["id"] == 7:
round_num = 1
counter = 0
while round_num <= 26 and counter < 50:
counter += 1
params = copy.deepcopy(base_params)
logger.info(
f"gauntlets.py - run_draft - event_id {this_event['id']} / round_num: {round_num} / counter: {counter} / counts: {counts} / max_counts: {max_counts}"
)
# Set rarity based on remaining counts
if counts["Hall of Fame"] < max_counts["Hall of Fame"]:
params.extend(
[("min_rarity", RARITY["HoF"]), ("max_rarity", RARITY["HoF"])]
)
elif counts["MVP"] < max_counts["MVP"]:
params.extend(
[("min_rarity", RARITY["MVP"]), ("max_rarity", RARITY["MVP"])]
)
elif counts["All-Star"] < max_counts["All-Star"]:
params.extend(
[
("min_rarity", RARITY["All-Star"]),
("max_rarity", RARITY["All-Star"]),
]
)
elif counts["Starter"] < max_counts["Starter"]:
if counts["Starter"] < 5:
params = [("cardset_id", 23), ("limit", 16)]
params.extend(
[
("min_rarity", RARITY["Starter"]),
("max_rarity", RARITY["Starter"]),
]
)
elif counts["Reserve"] < max_counts["Reserve"]:
params.extend(
[
("min_rarity", RARITY["Reserve"]),
("max_rarity", RARITY["Reserve"]),
]
)
else:
params.extend(
[
("min_rarity", RARITY["Replacement"]),
("max_rarity", RARITY["Replacement"]),
]
)
this_batch = []
for x in ["SP", "RP", "IF", "OF"]:
# Slot 1 - SP
if x == "SP":
if counts["SP"] > 5:
slot_params = [("pos_exc", "SP")]
if counts["RP"] > 7:
slot_params = [("pos_exc", "RP")]
else:
slot_params = [("pos_inc", "SP")]
# if counts['SP'] > 5:
# slot_params = [('pos_exc', 'SP')]
# elif counts['RP'] < 6:
# slot_params = [('pos_inc', 'RP')]
# else:
# slot_params = [('pos_exc', 'SP'), ('pos_exc', 'RP')]
# Slot 2 - RP
elif x == "RP":
logger.info(f"counts[RP]: {counts['RP']}")
if counts["RP"] > 7:
slot_params = [("pos_exc", "RP")]
if counts["SP"] > 5:
slot_params = [("pos_exc", "SP")]
else:
slot_params = [("pos_inc", "RP")]
# Slot 3 - IF
elif x == "IF":
slot_params = []
for y in ["1B", "2B", "3B", "SS", "C"]:
if (counts[y] > 1) and 0 in [
counts["C"],
counts["1B"],
counts["2B"],
counts["3B"],
counts["SS"],
]:
slot_params.append(("pos_exc", y))
elif (y == "C" and counts["C"] < 3) or (
y != "C" and counts[y] < 4
):
slot_params.append(("pos_inc", y))
# if counts['C'] < 2:
# slot_params.append(('pos_inc', 'C'))
# if len(slot_params) == 0:
# slot_params = [('pos_exc', 'C'), ('pos_exc', '1B'), ('pos_exc', '2B'), ('pos_exc', '3B'),
# ('pos_exc', 'SS')]
# Slot 4 - OF
else:
slot_params = []
for y in ["LF", "CF", "RF"]:
if counts[y] > 4:
slot_params.append(("pos_exc", y))
elif counts[y] > 1 and 0 in [
counts["LF"],
counts["CF"],
counts["RF"],
]:
slot_params.append(("pos_exc", y))
elif counts[y] < 5:
slot_params.append(("pos_inc", y))
# if len(slot_params) == 0:
# slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')]
logger.info(f"this_batch: {this_batch}")
logger.info(f"slot_params: {slot_params}")
logger.info(f"params: {params}")
# No position explicitly requested or denied
if len(slot_params) == 0:
if (counts["SP"] + counts["RP"]) > (
counts["C"]
+ counts["1B"]
+ counts["2B"]
+ counts["SS"]
+ counts["LF"]
+ counts["CF"]
+ counts["RF"]
):
pos_counts = [
("C", counts["C"]),
("1B", counts["1B"]),
("2B", counts["2B"]),
("3B", counts["3B"]),
("SS", counts["SS"]),
("LF", counts["LF"]),
("CF", counts["CF"]),
("RF", counts["RF"]),
]
pos_counts.sort(key=lambda z: z[1])
slot_params = [("pos_inc", pos_counts[0][0])]
else:
if counts["SP"] >= counts["RP"]:
slot_params = [("pos_inc", "RP")]
else:
slot_params = [("pos_inc", "SP")]
slot_params.extend(params)
p_query = await db_get("players/random", params=slot_params, timeout=10)
if p_query["count"] > 0:
for i in p_query["players"]:
if i["p_name"] not in p_names and i not in this_batch:
if (
i["cardset"]["id"] == 23
and "420420" not in i["strat_code"]
):
pass
else:
this_batch.append(i)
break
if len(this_batch) < 4:
logger.error(f"Pulled less than 4 players in gauntlet draft")
p_query = await db_get("players/random", params=params, timeout=10)
for i in p_query["players"]:
if i["p_name"] not in p_names and i not in this_batch:
this_batch.append(i)
if len(this_batch) >= 4:
break
if len(this_batch) < 4:
raise KeyError(
f"This is embarassing, but I couldn't find enough players for you to draft from."
)
# Present choices and capture selection
p_choice = await helpers.get_choice_from_cards(
interaction, this_batch, delete_message=True
)
# Add player to list and update counts
p_names.append(p_choice["p_name"])
counts[p_choice["rarity"]["name"]] += 1
all_players.append(p_choice)
if p_choice["pos_1"] in ["SP", "RP"]:
counts[p_choice["pos_1"]] += 1
else:
for x in helpers.get_all_pos(p_choice):
if x in counts:
counts[x] += 1
# Update roster embed
round_num += 1
await last_message.edit(
content=None,
embeds=get_embeds(include_links=False, round_num=round_num),
)
else:
logger.error(f"run_draft - No draft logic for Event ID {this_event['id']}")
raise KeyError(f"Draft data not found for Gauntlet {this_event['id']}")
if len(all_players) < 26:
raise KeyError(
f"I gotta be honest - I shit the bed here and wasn't able to get you enough players to fill "
f"a team. I have to wipe this team, but please draft again after you tell Cal his bot sucks."
)
# Handle draft_team as either Team object or dict
draft_team_id = draft_team.id if isinstance(draft_team, Team) else draft_team["id"]
this_pack = await db_post(
"packs/one",
payload={
"team_id": draft_team_id,
"pack_type_id": 2,
"open_time": datetime.datetime.timestamp(datetime.datetime.now()) * 1000,
},
)
await db_post(
"cards",
payload={
"cards": [
{
"player_id": x["player_id"],
"team_id": draft_team_id,
"pack_id": this_pack["id"],
}
for x in all_players
]
},
)
await db_post(
"gauntletruns",
payload={"team_id": draft_team_id, "gauntlet_id": this_event["id"]},
)
final_embed = get_embeds(False)[0]
final_embed.title = f"{main_team.lname} - {this_event['name']} Draft"
if main_team.logo:
final_embed.set_thumbnail(url=main_team.logo)
return final_embed
async def get_embed(this_run=None, this_event=None, this_team=None):
logger.info(f"get_embed - this_run:\n{this_run}\n\nthis_event:\n{this_event}")
if this_run is None and this_event is None:
raise KeyError("Must provide either a run or an event to get_embed")
if this_run is not None:
this_event = this_run["gauntlet"]
embed = helpers.image_embed(
image_url=this_event["url"],
title=f"{this_event['name']}",
)
if this_run is not None and this_run["team"]["logo"]:
embed.set_thumbnail(url=this_run["team"]["logo"])
embed.description = this_run["team"]["lname"]
embed.add_field(name="Event Info", value=this_event["short_desc"], inline=False)
if this_run is not None:
embed.add_field(
name="Current Record",
value=f"{this_run['wins']}-{this_run['losses']}",
inline=False,
)
r_query = await db_get(
"gauntletrewards", params=[("gauntlet_id", this_event["id"])]
)
reward_string = ""
for x in r_query["rewards"]:
if this_run is not None:
if this_run["wins"] >= x["win_num"] and this_run["losses"] <= x["loss_max"]:
reward_string += "✅️ "
elif this_run["losses"] > x["loss_max"]:
reward_string += ""
else:
reward_string += ""
reward_string += f"{x['win_num']}{'-0' if x['loss_max'] == 0 else ' Wins'}: "
if x["reward"]["money"]:
reward_string += f" {x['reward']['money']}\n"
elif x["reward"]["player"]:
reward_string += f" {x['reward']['player']['description']}\n"
elif x["reward"]["pack_type"]:
reward_string += f" {x['reward']['pack_type']['name']} Pack\n"
if len(reward_string) > 0:
embed.add_field(name="Rewards", value=reward_string)
if this_team is not None:
run_query = await db_get(
"gauntletruns",
params=[("team_id", this_team["id"]), ("gauntlet_id", this_event["id"])],
)
record_name = f"{this_team['abbrev'].split('-')[1]} Record"
else:
run_query = await db_get(
"gauntletruns", params=[("gauntlet_id", this_event["id"])]
)
record_name = f"League Record"
record_value = ""
if run_query["count"] > 0:
max_wins, victories, perfects = 0, 0, 0
record_value += f"Attempts: {run_query['count']}\n"
for x in run_query["runs"]:
if x["wins"] > max_wins:
max_wins = x["wins"]
if x["wins"] == 10:
victories += 1
if x["losses"] == 0:
perfects += 1
if victories > 0:
record_value += f"Victories: {victories}\n10-0 Runs: {perfects}"
else:
record_value += f"Most Wins: {max_wins}"
embed.add_field(name=record_name, value=record_value)
if this_run is not None:
embed.add_field(
name="Team Sheet",
value=helpers.get_roster_sheet(this_run["team"]),
inline=False,
)
return embed
async def end_run(
this_run,
this_event,
this_team: Team,
bot=None,
main_team=None,
force_end: bool = False,
):
l_message = (
f"Tough loss. That brings your {this_event['name']} record to "
f"**{this_run['wins']}-{this_run['losses']}**. "
)
if this_run["losses"] == 2 or force_end:
l_message += "That's the end of this run - better luck next time!"
this_run = await db_patch(
"gauntletruns", object_id=this_run["id"], params=[("ended", True)]
)
c_query = await db_post(f"cards/wipe-team/{this_team.id}")
# Send news-ticker message for natural run completion (2 losses), not for manual resets
if bot and main_team and this_run["losses"] == 2 and not force_end:
team_name = (
main_team.lname
if isinstance(main_team, Team)
else main_team.get("lname", "Unknown Team")
)
await send_to_channel(
bot,
"pd-news-ticker",
content=f"The **{team_name}**'s **{this_event['name']} Gauntlet** run has ended "
f"with a final record of {this_run['wins']}-{this_run['losses']}.",
)
return l_message
async def evolve_pokemon(this_team: Team, channel, responders):
c_query = await db_get(
"cards", params=[("team_id", this_team.id), ("order_by", "new"), ("limit", 26)]
)
logger.info(f"received {c_query['count']} cards, searching now")
evolvable_mons = [
x
for x in c_query["cards"]
if x["player"]["cardset"]["id"] in [23]
and x["player"]["fangr_id"] is not None
and len(x["player"]["fangr_id"]) > 3
]
logger.info(f"evolvable_mons: {evolvable_mons}")
if len(evolvable_mons) > 0:
evo_target_options = [
SelectOption(
label=f"{x['player']['rarity']['name']} | {x['player']['p_name']}",
value=x["id"],
)
for x in evolvable_mons
]
view = DropdownView(
dropdown_objects=[
SelectPokemonEvolution(
options=evo_target_options,
this_team=this_team,
responders=responders,
)
]
)
await channel.send(
content="What? One of your pokemon is ready to evolve!\n\n-# The selected pokemon will be removed from your team and replaced with its evolution",
view=view,
)
else:
await channel.send("All of your Pokemon are fully evolved!")
async def post_result(
run_id: int,
is_win: bool,
this_team: Team,
bot,
channel,
responders: list[discord.User] = None,
):
this_run = await db_get("gauntletruns", object_id=run_id)
this_event = await db_get("events", object_id=this_run["gauntlet"]["id"])
t_query = await db_get(
"teams", params=[("abbrev", f"{this_team.abbrev.replace('Gauntlet-', '')}")]
)
main_team = t_query["teams"][0]
if is_win:
this_run = await db_patch(
"gauntletruns",
object_id=this_run["id"],
params=[
("wins", this_run["wins"] + 1),
("ended", this_run["wins"] + 1 == 10),
],
)
r_query = await db_get(
"gauntletrewards",
params=[
("gauntlet_id", this_event["id"]),
("win_num", this_run["wins"]),
("loss_max", this_run["losses"]),
],
)
reward_string = ""
for x in r_query["rewards"]:
if x["reward"]["money"]:
await db_post(f"teams/{main_team['id']}/money/{x['reward']['money']}")
reward_string += f"- {x['reward']['money']}\n"
elif x["reward"]["player"]:
this_pack = await db_post(
"packs/one",
payload={
"team_id": main_team["id"],
"pack_type_id": 4,
"open_time": datetime.datetime.timestamp(
datetime.datetime.now()
)
* 1000,
},
)
await helpers.give_cards_to_team(
main_team,
player_ids=[x["reward"]["player"]["player_id"]],
pack_id=this_pack["id"],
)
reward_string += f"- {helpers.player_desc(x['reward']['player'])}\n"
elif x["reward"]["pack_type"] and this_event["id"] in [3, 4, 5, 6, 8, 9]:
if this_event["id"] == 3:
cardset_id = 13
team_id = 58
elif this_event["id"] == 4:
cardset_id = 16
team_id = 79
elif this_event["id"] == 5:
cardset_id = 17
team_id = None
if x["reward"]["pack_type"]["id"] == 9:
cardset_id = 18
elif this_event["id"] == 6:
cardset_id = 20
team_id = None
if x["reward"]["pack_type"]["id"] == 9:
cardset_id = 21
elif this_event["id"] == 8:
cardset_id = 24
team_id = None
if x["reward"]["pack_type"]["id"] == 9:
cardset_id = 25
elif this_event["id"] == 9:
cardset_id = 27
team_id = None
if x["reward"]["pack_type"]["id"] == 9:
cardset_id = 26
await db_post(
"packs",
payload={
"packs": [
{
"team_id": main_team["id"],
"pack_type_id": x["reward"]["pack_type"]["id"],
"pack_cardset_id": cardset_id,
"pack_team_id": team_id
if x["reward"]["pack_type"]["id"] == 8
else None,
}
]
},
)
reward_string += f"- 1x {x['reward']['pack_type']['name']} Pack"
elif x["reward"]["pack_type"] and this_event["id"] in [7]:
if this_event["id"] == 7:
cardset_id = 23
team_id = 91
await db_post(
"packs",
payload={
"packs": [
{
"team_id": main_team["id"],
"pack_type_id": x["reward"]["pack_type"]["id"],
"pack_cardset_id": cardset_id
if x["reward"]["pack_type"]["id"] != 8
else None,
"pack_team_id": team_id
if x["reward"]["pack_type"]["id"] == 8
else None,
}
]
},
)
reward_string += f"- 1x {x['reward']['pack_type']['name']} Pack"
elif x["reward"]["pack_type"]:
await helpers.give_packs(main_team, 1, x["reward"]["pack_type"])
reward_string += f"- 1x {x['reward']['pack_type']['name']} Pack"
if this_run["wins"] == 10:
choas_role = await get_or_create_role(
channel, "CHOAS ALERT", mentionable=True
)
await send_to_channel(
bot,
"pd-network-news",
content=f"{choas_role.mention}\n\nThe **{this_team.lname}** have completed the "
f"**{this_event['name']} Gauntlet** with a record of {this_run['wins']}-"
f"{this_run['losses']}!",
)
final_message = (
f"That's number 10! Way to go - you have completed the **{this_event['name']} Gauntlet** "
f"with a record of {this_run['wins']}-{this_run['losses']}! "
)
c_query = await db_post(f"cards/wipe-team/{this_team.id}")
else:
final_message = (
f"Big win there! Your {this_event['name']} record is now **{this_run['wins']}-"
f"{this_run['losses']}**. "
)
if len(reward_string) > 0:
final_message += f"You earned the following rewards:\n{reward_string}"
final_message += f"\n\nGo share the highlights in {get_channel(channel, 'pd-news-ticker').mention}!"
await channel.send(content=final_message, embed=await get_embed(this_run))
else:
# this_run = await db_patch(
# 'gauntletruns',
# object_id=this_run['id'],
# params=[('losses', this_run['losses'] + 1), ('ended', this_run['losses'] + 1 == 2)]
# )
# l_message = f'Tough loss. That brings your {this_event["name"]} record to ' \
# f'**{this_run["wins"]}-{this_run["losses"]}**. '
# if this_run['losses'] == 2:
# l_message += 'That\'s the end of this run - better luck next time!'
# c_query = await db_post(f'cards/wipe-team/{this_team["id"]}')
#
this_run = await db_patch(
"gauntletruns",
object_id=this_run["id"],
params=[("losses", this_run["losses"] + 1)],
)
l_message = await end_run(this_run, this_event, this_team, bot, main_team)
await channel.send(content=l_message, embed=await get_embed(this_run))
# Evolve a card!
logger.info(
f"Post-game evolution check: Gauntlet ID {this_run['id']} / Wins: {this_run['wins']} / Losses: {this_run['losses']}"
)
if this_event["id"] == 7 and this_run["wins"] < 10 and this_run["losses"] < 2:
logger.info(f"trying to evolve now")
await evolve_pokemon(this_team, channel, responders)