This commit is contained in:
commit
c0e85b87ec
|
@ -158,6 +158,7 @@ these folks are helping me a *ton* via patreon, and i cannot possibly thank them
|
|||
- Evie Diver
|
||||
- iliana etaoin
|
||||
- yooori
|
||||
- Bend
|
||||
|
||||
## Attribution
|
||||
|
||||
|
|
2
games.py
2
games.py
|
@ -30,7 +30,6 @@ def config():
|
|||
return json.load(config_file)
|
||||
|
||||
|
||||
|
||||
class player(object):
|
||||
def __init__(self, json_string):
|
||||
self.stlats = json.loads(json_string)
|
||||
|
@ -791,4 +790,3 @@ def search_team(search_term):
|
|||
|
||||
teams.append(team_json)
|
||||
return teams
|
||||
|
||||
|
|
|
@ -34,11 +34,16 @@ def statements():
|
|||
ROUND(total_bases*1.0 / (plate_appearances - (walks_taken + sacrifices)*1.0),3) as SLG,
|
||||
ROUND((walks_taken + hits)*1.0/plate_appearances*1.0,3) as OBP,
|
||||
ROUND((walks_taken + hits)*1.0/plate_appearances*1.0,3) + ROUND(total_bases*1.0 / (plate_appearances - (walks_taken + sacrifices)*1.0),3) as OPS
|
||||
FROM stats WHERE plate_appearances > 8""",
|
||||
FROM stats WHERE plate_appearances > """,
|
||||
"bat_base_req": 3,
|
||||
"avg" : ["ORDER BY BA DESC;", "bat_base"],
|
||||
"slg" : ["ORDER BY SLG DESC;", "bat_base"],
|
||||
"obp" : ["ORDER BY OBP DESC;", "bat_base"],
|
||||
"ops" : ["ORDER BY OPS DESC;", "bat_base"],
|
||||
"bat_count_base": "SELECT name, team_name,\n\tplate_appearances - (walks_taken + sacrifices) as ABs,\nwalks_taken as BB,\nhits as H,\nhome_runs as HR,\nrbis as RBIs,\nstrikeouts_taken as K,\nsacrifices\nFROM stats WHERE plate_appearances > 8",
|
||||
"home runs": ["ORDER BY HR DESC;", "bat_count_base"],
|
||||
"walks drawn": ["ORDER BY BB DESC;", "bat_count_base"],
|
||||
"bat_count_base_req" : 3,
|
||||
"pitch_base" : """SELECT name, team_name,
|
||||
ROUND(((outs_pitched*1.0)/3.0),1) as IP,
|
||||
ROUND(runs_allowed*27.0/(outs_pitched*1.0),3) as ERA,
|
||||
|
@ -46,8 +51,9 @@ FROM stats WHERE plate_appearances > 8""",
|
|||
ROUND(walks_allowed*27.0/(outs_pitched*1.0),3) as BBper9,
|
||||
ROUND(strikeouts_given*27.0/(outs_pitched*1.0),3) as Kper9,
|
||||
ROUND(strikeouts_given*1.0/walks_allowed*1.0,3) as KperBB
|
||||
FROM stats WHERE outs_pitched > 20
|
||||
FROM stats WHERE outs_pitched >
|
||||
""",
|
||||
"pitch_base_req": 2,
|
||||
"era" : ["ORDER BY ERA ASC;", "pitch_base"],
|
||||
"whip" : ["ORDER BY WHIP ASC;", "pitch_base"],
|
||||
"kper9" : ["ORDER BY Kper9 DESC;", "pitch_base"],
|
||||
|
@ -85,6 +91,9 @@ def state(league_name):
|
|||
return json.load(state_file)
|
||||
|
||||
def init_league_db(league):
|
||||
if os.path.exists(os.path.join(data_dir, league_dir, league.name, f"{league.name}.db")):
|
||||
os.remove(os.path.join(data_dir, league_dir, league.name, f"{league.name}.db"))
|
||||
|
||||
conn = create_connection(league.name)
|
||||
|
||||
player_stats_table_check_string = """ CREATE TABLE IF NOT EXISTS stats (
|
||||
|
@ -169,7 +178,7 @@ def add_stats(league_name, player_game_stats_list):
|
|||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
def get_stats(league_name, stat, is_batter=True):
|
||||
def get_stats(league_name, stat, is_batter=True, day = 10):
|
||||
conn = create_connection(league_name)
|
||||
stats = None
|
||||
if conn is not None:
|
||||
|
@ -177,7 +186,8 @@ def get_stats(league_name, stat, is_batter=True):
|
|||
c=conn.cursor()
|
||||
|
||||
if stat in statements().keys():
|
||||
c.execute(statements()[statements()[stat][1]]+"\n"+statements()[stat][0])
|
||||
req_number = str(day * int(statements()[statements()[stat][1]+"_req"]))
|
||||
c.execute(statements()[statements()[stat][1]]+req_number+"\n"+statements()[stat][0])
|
||||
stats = c.fetchall()
|
||||
conn.close()
|
||||
return stats
|
||||
|
|
17
leagues.py
17
leagues.py
|
@ -89,11 +89,13 @@ class league_structure(object):
|
|||
tournaments.append(tourney)
|
||||
return tournaments
|
||||
|
||||
def find_team(self, team_name):
|
||||
def find_team(self, team_search):
|
||||
for subleague in iter(self.league.keys()):
|
||||
for division in iter(self.league[subleague].keys()):
|
||||
if team_name in self.league[subleague][division]:
|
||||
return (subleague, division)
|
||||
for team in self.league[subleague][division]:
|
||||
if team.name == team_search.name:
|
||||
return (subleague, division)
|
||||
return (None, None)
|
||||
|
||||
def teams_in_league(self):
|
||||
teams = []
|
||||
|
@ -417,7 +419,7 @@ class league_structure(object):
|
|||
|
||||
def stat_embed(self, stat_name):
|
||||
this_embed = Embed(color=Color.purple(), title=f"{self.name} Season {self.season} {stat_name} Leaders")
|
||||
stats = league_db.get_stats(self.name, stat_name.lower())
|
||||
stats = league_db.get_stats(self.name, stat_name.lower(), day = self.day)
|
||||
if stats is None:
|
||||
return None
|
||||
else:
|
||||
|
@ -548,6 +550,13 @@ def save_league(this_league):
|
|||
json.dump(league_json_string, league_file, indent=4)
|
||||
league_db.save_league(this_league)
|
||||
|
||||
def save_league_as_new(this_league):
|
||||
league_db.init_league_db(this_league)
|
||||
with open(os.path.join(data_dir, league_dir, this_league.name, f"{this_league.name}.league"), "w") as league_file:
|
||||
league_json_string = jsonpickle.encode(this_league.league, keys=True)
|
||||
json.dump(league_json_string, league_file, indent=4)
|
||||
league_db.save_league(this_league)
|
||||
|
||||
def load_league_file(league_name):
|
||||
if league_db.league_exists(league_name):
|
||||
state = league_db.state(league_name)
|
||||
|
|
139
the_prestige.py
139
the_prestige.py
|
@ -146,6 +146,12 @@ class StartGameCommand(Command):
|
|||
await msg.channel.send("Make sure you put an integer after the -d flag.")
|
||||
return
|
||||
|
||||
weather_name = None
|
||||
if "-w " in command.split("\n")[0]:
|
||||
weather_name = command.split("\n")[0].split("-w ")[1].split("-")[0].strip()
|
||||
elif "--weather " in command.split("\n")[0]:
|
||||
weather_name = command.split("\n")[0].split("--weather ")[1].split("-")[0].strip()
|
||||
|
||||
innings = None
|
||||
try:
|
||||
team_name1 = command.split("\n")[1].strip()
|
||||
|
@ -183,8 +189,11 @@ class StartGameCommand(Command):
|
|||
game.teams['away'].set_pitcher(rotation_slot = day)
|
||||
game.teams['home'].set_pitcher(rotation_slot = day)
|
||||
channel = msg.channel
|
||||
await msg.delete()
|
||||
|
||||
if weather_name is not None and weather_name in weather.all_weathers().keys():
|
||||
game.weather = weather.all_weathers()[weather_name](game)
|
||||
|
||||
|
||||
game_task = asyncio.create_task(watch_game(channel, game, user=msg.author, league=league))
|
||||
await game_task
|
||||
else:
|
||||
|
@ -202,7 +211,6 @@ class StartRandomGameCommand(Command):
|
|||
return
|
||||
|
||||
channel = msg.channel
|
||||
await msg.delete()
|
||||
await channel.send("Rolling the bones... This might take a while.")
|
||||
teamslist = games.get_all_teams()
|
||||
|
||||
|
@ -1116,8 +1124,114 @@ class LeagueForceStopCommand(Command):
|
|||
await msg.channel.send("League halted, boss. We hope you did that on purpose.")
|
||||
return
|
||||
await msg.channel.send("That league either doesn't exist or isn't in the active list. So, huzzah?")
|
||||
|
||||
|
||||
|
||||
class LeagueSwapTeamCommand(Command):
|
||||
name = "leagueswapteam"
|
||||
template = "m;leagueswapteam [league name]\n[team to remove]\n[team to add]"
|
||||
description = "Adds a team to a league, removing the old one in the process. Can only be executed by a league owner, and only before the start of a new season."
|
||||
|
||||
async def execute(self, msg, command):
|
||||
league_name = command.split("\n")[0].strip()
|
||||
if league_exists(league_name):
|
||||
league = leagues.load_league_file(league_name)
|
||||
if league.day != 1:
|
||||
await msg.channel.send("That league hasn't finished its current season yet, chief. Either reset it, or be patient.")
|
||||
return
|
||||
if (league.owner is not None and msg.author.id in league.owner) or (league.owner is not None and msg.author.id in config()["owners"]):
|
||||
try:
|
||||
team_del = get_team_fuzzy_search(command.split("\n")[1].strip())
|
||||
team_add = get_team_fuzzy_search(command.split("\n")[2].strip())
|
||||
except IndexError:
|
||||
await msg.channel.send("Three lines, boss. Make sure you give us the team to remove, then the team to add.")
|
||||
return
|
||||
if team_add.name == team_del.name:
|
||||
await msg.channel.send("Quit being cheeky. The teams have to be different.")
|
||||
return
|
||||
|
||||
if team_del is None or team_add is None:
|
||||
await msg.channel.send("We couldn't find one or both of those teams, boss. Try again.")
|
||||
return
|
||||
subleague, division = league.find_team(team_del)
|
||||
|
||||
if subleague is None or division is None:
|
||||
await msg.channel.send("That first team isn't in that league, chief. So, that's good, right?")
|
||||
return
|
||||
|
||||
if league.find_team(team_add)[0] is not None:
|
||||
await msg.channel.send("That second team is already in that league, chief. No doubles.")
|
||||
return
|
||||
|
||||
for index in range(0, len(league.league[subleague][division])):
|
||||
if league.league[subleague][division][index].name == team_del.name:
|
||||
league.league[subleague][division].pop(index)
|
||||
league.league[subleague][division].append(team_add)
|
||||
league.schedule = {}
|
||||
league.generate_schedule()
|
||||
leagues.save_league_as_new(league)
|
||||
await msg.channel.send(embed=league.standings_embed())
|
||||
await msg.channel.send("Paperwork signed, stamped, copied, and faxed up to the goddess. Xie's pretty quick with this stuff.")
|
||||
else:
|
||||
await msg.channel.send("That league isn't yours, chief.")
|
||||
else:
|
||||
await msg.channel.send("We can't find that league.")
|
||||
|
||||
class LeagueRenameCommand(Command):
|
||||
name = "leaguerename"
|
||||
template = "m;leaguerename [league name]\n[old subleague/division name]\n[new subleague/division name]"
|
||||
description = "Changes the name of an existing subleague or division. Can only be executed by a league owner, and only before the start of a new season."
|
||||
|
||||
async def execute(self, msg, command):
|
||||
league_name = command.split("\n")[0].strip()
|
||||
if league_exists(league_name):
|
||||
league = leagues.load_league_file(league_name)
|
||||
if league.day != 1:
|
||||
await msg.channel.send("That league hasn't finished its current season yet, chief. Either reset it, or be patient.")
|
||||
return
|
||||
if (league.owner is not None and msg.author.id in league.owner) or (league.owner is not None and msg.author.id in config()["owners"]):
|
||||
try:
|
||||
old_name = command.split("\n")[1].strip()
|
||||
new_name = command.split("\n")[2].strip()
|
||||
except IndexError:
|
||||
await msg.channel.send("Three lines, boss. Make sure you give us the old name, then the new name, on their own lines.")
|
||||
return
|
||||
|
||||
if old_name == new_name:
|
||||
await msg.channel.send("Quit being cheeky. They have to be different names, clearly.")
|
||||
|
||||
|
||||
found = False
|
||||
for subleague in league.league.keys():
|
||||
if subleague == new_name:
|
||||
found = True
|
||||
break
|
||||
for division in league.league[subleague]:
|
||||
if division == new_name:
|
||||
found = True
|
||||
break
|
||||
if found:
|
||||
await msg.channel.send(f"{new_name} is already present in that league, chief. They have to be different.")
|
||||
|
||||
found = False
|
||||
for subleague in league.league.keys():
|
||||
if subleague == old_name:
|
||||
league.league[new_name] = league.league.pop(old_name)
|
||||
found = True
|
||||
break
|
||||
for division in league.league[subleague]:
|
||||
if division == old_name:
|
||||
league.league[subleague][new_name] = league.league[subleague].pop(old_name)
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
await msg.channel.send(f"We couldn't find {old_name} anywhere in that league, boss.")
|
||||
return
|
||||
leagues.save_league_as_new(league)
|
||||
await msg.channel.send(embed=league.standings_embed())
|
||||
await msg.channel.send("Paperwork signed, stamped, copied, and faxed up to the goddess. Xie's pretty quick with this stuff.")
|
||||
else:
|
||||
await msg.channel.send("That league isn't yours, chief.")
|
||||
else:
|
||||
await msg.channel.send("We can't find that league.")
|
||||
|
||||
|
||||
commands = [
|
||||
|
@ -1153,6 +1267,8 @@ commands = [
|
|||
LeagueScheduleCommand(),
|
||||
LeagueTeamScheduleCommand(),
|
||||
LeagueRegenerateScheduleCommand(),
|
||||
LeagueSwapTeamCommand(),
|
||||
LeagueRenameCommand(),
|
||||
LeagueForceStopCommand(),
|
||||
CreditCommand(),
|
||||
RomanCommand(),
|
||||
|
@ -1161,6 +1277,7 @@ commands = [
|
|||
DraftPlayerCommand()
|
||||
]
|
||||
|
||||
watching = False
|
||||
client = discord.Client()
|
||||
gamesarray = []
|
||||
active_tournaments = []
|
||||
|
@ -1168,6 +1285,7 @@ active_leagues = []
|
|||
active_standings = {}
|
||||
setupmessages = {}
|
||||
|
||||
|
||||
thread1 = threading.Thread(target=main_controller.update_loop)
|
||||
thread1.start()
|
||||
|
||||
|
@ -1196,10 +1314,13 @@ def config():
|
|||
|
||||
@client.event
|
||||
async def on_ready():
|
||||
global watching
|
||||
db.initialcheck()
|
||||
print(f"logged in as {client.user} with token {config()['token']} to {len(client.guilds)} servers")
|
||||
watch_task = asyncio.create_task(game_watcher())
|
||||
await watch_task
|
||||
if not watching:
|
||||
watching = True
|
||||
watch_task = asyncio.create_task(game_watcher())
|
||||
await watch_task
|
||||
|
||||
|
||||
@client.event
|
||||
|
@ -1396,7 +1517,7 @@ async def watch_game(channel, newgame, user = None, league = None):
|
|||
main_controller.master_games_dic[id] = (newgame, state_init, discrim_string)
|
||||
|
||||
def prepare_game(newgame, league = None, weather_name = None):
|
||||
if weather_name is None:
|
||||
if weather_name is None and newgame.weather.name == "Sunny":
|
||||
weathers = weather.all_weathers()
|
||||
newgame.weather = weathers[random.choice(list(weathers.keys()))](newgame)
|
||||
|
||||
|
@ -1575,7 +1696,7 @@ async def tourney_round_watcher(channel, tourney, games_list, filter_url, finals
|
|||
|
||||
if finals: #if this last round was finals
|
||||
embed = discord.Embed(color = discord.Color.dark_purple(), title = f"{winner_list[0]} win the {tourney.name} finals!")
|
||||
if tourney.day > tourney.league.day:
|
||||
if tourney.league is not None and tourney.day > tourney.league.day:
|
||||
tourney.league.day = tourney.day
|
||||
await channel.send(embed=embed)
|
||||
tourney.winner = get_team_fuzzy_search(winner_list[0])
|
||||
|
@ -2005,7 +2126,7 @@ async def league_day_watcher(channel, league, games_list, filter_url, last = Fal
|
|||
else:
|
||||
league.active = False
|
||||
|
||||
if league.autoplay == 0 or config()["game_freeze"]: #if number of series to autoplay has been reached
|
||||
if league.autoplay <= 0 or config()["game_freeze"]: #if number of series to autoplay has been reached
|
||||
if league in active_standings.keys():
|
||||
await active_standings[league].unpin()
|
||||
active_standings[league] = await channel.send(embed=league.standings_embed())
|
||||
|
|
30
weather.py
30
weather.py
|
@ -5,7 +5,7 @@ from gametext import appearance_outcomes, base_string
|
|||
class Weather:
|
||||
def __init__(self, game):
|
||||
self.name = "Sunny"
|
||||
self.emoji = "🌞" + "\uFE00"
|
||||
self.emoji = "🌞"
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.emoji} {self.name}"
|
||||
|
@ -38,18 +38,18 @@ class Weather:
|
|||
pass
|
||||
|
||||
|
||||
class Supernova(Weather): # todo
|
||||
class Supernova(Weather):
|
||||
def __init__(self, game):
|
||||
self.name = "Supernova"
|
||||
self.emoji = "🌟" + "\uFE00"
|
||||
self.emoji = "🌟"
|
||||
|
||||
def modify_atbat_stats(self, roll):
|
||||
roll["pitch_stat"] *= 0.9
|
||||
|
||||
class Midnight(Weather): # todo
|
||||
class Midnight(Weather):
|
||||
def __init__(self, game):
|
||||
self.name = "Midnight"
|
||||
self.emoji = "🕶" + "\uFE00"
|
||||
self.emoji = "🕶"
|
||||
|
||||
def modify_steal_stats(self, roll):
|
||||
roll["run_stars"] *= 2
|
||||
|
@ -57,7 +57,7 @@ class Midnight(Weather): # todo
|
|||
class SlightTailwind(Weather):
|
||||
def __init__(self, game):
|
||||
self.name = "Slight Tailwind"
|
||||
self.emoji = "🏌️♀️" + "\uFE00"
|
||||
self.emoji = "🏌️♀️"
|
||||
|
||||
def activate(self, game, result):
|
||||
if game.top_of_inning:
|
||||
|
@ -82,7 +82,7 @@ class SlightTailwind(Weather):
|
|||
class HeavySnow(Weather):
|
||||
def __init__(self, game):
|
||||
self.name = "Heavy Snow"
|
||||
self.emoji = "❄" + "\uFE00"
|
||||
self.emoji = "❄"
|
||||
self.counter_away = random.randint(0,len(game.teams['away'].lineup)-1)
|
||||
self.counter_home = random.randint(0,len(game.teams['home'].lineup)-1)
|
||||
|
||||
|
@ -127,7 +127,7 @@ class HeavySnow(Weather):
|
|||
class Twilight(Weather):
|
||||
def __init__(self,game):
|
||||
self.name = "Twilight"
|
||||
self.emoji = "👻" + "\uFE00"
|
||||
self.emoji = "👻"
|
||||
|
||||
def modify_atbat_roll(self, outcome, roll, defender):
|
||||
error_line = - (math.log(defender.stlats["defense_stars"] + 1)/50) + 1
|
||||
|
@ -143,12 +143,12 @@ class Twilight(Weather):
|
|||
if "error" in result.keys():
|
||||
state["update_text"] = f"{result['batter']}'s hit goes ethereal, and {result['defender']} can't catch it! {result['batter']} reaches base safely."
|
||||
if this_game.last_update[1] > 0:
|
||||
state["update_text"] += f"{this_game.last_update[1]} runs scored!"
|
||||
state["update_text"] += f" {this_game.last_update[1]} runs scored!"
|
||||
|
||||
class ThinnedVeil(Weather):
|
||||
def __init__(self,game):
|
||||
self.name = "Thinned Veil"
|
||||
self.emoji = "🌌" + "\uFE00"
|
||||
self.emoji = "🌌"
|
||||
|
||||
def activate(self, game, result):
|
||||
if result["ishit"]:
|
||||
|
@ -163,7 +163,7 @@ class ThinnedVeil(Weather):
|
|||
class HeatWave(Weather):
|
||||
def __init__(self,game):
|
||||
self.name = "Heat Wave"
|
||||
self.emoji = "🌄" + "\uFE00"
|
||||
self.emoji = "🌄"
|
||||
|
||||
self.counter_away = random.randint(2,4)
|
||||
self.counter_home = random.randint(2,4)
|
||||
|
@ -225,7 +225,7 @@ class Drizzle(Weather):
|
|||
placed_player = game.teams[next_team].lineup[(game.teams[next_team].lineup_position-1) % len(game.teams[next_team].lineup)]
|
||||
|
||||
state["update_emoji"] = self.emoji
|
||||
state["update_text"] += f'Due to inclement weather, {placed_player.name} is placed on second base.'
|
||||
state["update_text"] += f' Due to inclement weather, {placed_player.name} is placed on second base.'
|
||||
|
||||
|
||||
class Sun2(Weather):
|
||||
|
@ -327,9 +327,9 @@ class Feedback(Weather):
|
|||
|
||||
def all_weathers():
|
||||
weathers_dic = {
|
||||
#"Supernova" : Supernova,
|
||||
#"Midnight": Midnight,
|
||||
#"Slight Tailwind": SlightTailwind,
|
||||
"Supernova" : Supernova,
|
||||
"Midnight": Midnight,
|
||||
"Slight Tailwind": SlightTailwind,
|
||||
"Heavy Snow": HeavySnow,
|
||||
"Twilight" : Twilight,
|
||||
"Thinned Veil" : ThinnedVeil,
|
||||
|
|
Loading…
Reference in a new issue