Merge remote-tracking branch 'upstream/indev' into indev

This commit is contained in:
Elijah Steres 2021-01-02 06:22:20 -05:00
commit d3ac6caa70
3 changed files with 182 additions and 47 deletions

118
games.py
View File

@ -24,22 +24,13 @@ def config():
return json.load(config_file) return json.load(config_file)
def all_weathers(): def all_weathers():
if not os.path.exists("weather_config.json"): weathers_dic = {
#generate default config #"Supernova" : weather("Supernova", "🌟"),
super_weather_json = jsonpickle.encode(weather("Supernova", "🌟")) "Midnight": weather("Midnight", "🕶"),
mid_weather_json = jsonpickle.encode(weather("Midnight", "🕶")) "Slight Tailwind": weather("Slight Tailwind", "🏌️‍♀️"),
config_dic = { "Heavy Snow": weather("Heavy Snow", "")
"Supernova" : super_weather_json, }
"Midnight": mid_weather_json return weathers_dic
}
with open("weather_config.json", "w") as config_file:
json.dump(config_dic, config_file, indent=4)
with open("weather_config.json") as config_file:
weather_dic = {}
for weather_json in json.load(config_file).values():
this_weather = jsonpickle.decode(weather_json, classes=weather)
weather_dic[this_weather.name] = this_weather
return weather_dic
class appearance_outcomes(Enum): class appearance_outcomes(Enum):
@ -107,21 +98,46 @@ class team(object):
self.score = 0 self.score = 0
self.slogan = None self.slogan = None
def find_player(self, name):
for index in range(0,len(self.lineup)):
if self.lineup[index].name == name:
return (self.lineup[index], index, self.lineup)
for index in range(0,len(self.rotation)):
if self.rotation[index].name == name:
return (self.rotation[index], index, self.rotation)
else:
return (None, None, None)
def swap_player(self, name): def swap_player(self, name):
if len(self.lineup) > 1: this_player, index, roster = self.find_player(name)
for index in range(0,len(self.lineup)): if this_player is not None and len(roster) > 1:
if self.lineup[index].name == name: if roster == self.lineup:
if self.add_pitcher(self.lineup[index]): if self.add_pitcher(this_player):
self.lineup.pop(index) roster.pop(index)
return True return True
if len(self.rotation) > 1: else:
for index in range(0,len(self.rotation)): if self.add_lineup(this_player)[0]:
if self.rotation[index].name == name: self.rotation.pop(index)
if self.add_lineup(self.rotation[index])[0]: return True
self.rotation.pop(index)
return True
return False return False
def delete_player(self, name):
this_player, index, roster = self.find_player(name)
if this_player is not None and len(roster) > 1:
roster.pop(index)
return True
else:
return False
def slide_player(self, name, new_spot):
this_player, index, roster = self.find_player(name)
if this_player is not None and new_spot < len(roster):
roster.pop(index)
roster.insert(new_spot-1, this_player)
return True
else:
return False
def add_lineup(self, new_player): def add_lineup(self, new_player):
if len(self.lineup) < 20: if len(self.lineup) < 20:
self.lineup.append(new_player) self.lineup.append(new_player)
@ -197,8 +213,13 @@ class game(object):
def get_batter(self): def get_batter(self):
if self.top_of_inning: if self.top_of_inning:
bat_team = self.teams["away"] bat_team = self.teams["away"]
counter = self.weather.counter_away
else: else:
bat_team = self.teams["home"] bat_team = self.teams["home"]
counter = self.weather.counter_home
if self.weather.name == "Heavy Snow" and counter == bat_team.lineup_position:
return bat_team.pitcher
return bat_team.lineup[bat_team.lineup_position % len(bat_team.lineup)] return bat_team.lineup[bat_team.lineup_position % len(bat_team.lineup)]
def get_pitcher(self): def get_pitcher(self):
@ -459,14 +480,26 @@ class game(object):
def batterup(self): def batterup(self):
scores_to_add = 0 scores_to_add = 0
result = self.at_bat() result = self.at_bat()
self.get_batter()
if self.top_of_inning: if self.top_of_inning:
offense_team = self.teams["away"] offense_team = self.teams["away"]
weather_count = self.weather.counter_away
defense_team = self.teams["home"] defense_team = self.teams["home"]
else: else:
offense_team = self.teams["home"] offense_team = self.teams["home"]
weather_count = self.weather.counter_home
defense_team = self.teams["away"] defense_team = self.teams["away"]
if self.weather.name == "Slight Tailwind" and "mulligan" not in self.last_update[0].keys() and not result["ishit"] and result["text"] != appearance_outcomes.walk:
mulligan_roll_target = -((((self.get_batter().stlats["batting_stars"])-7)/7)**2)+1
if random.random() > mulligan_roll_target:
result["mulligan"] = True
return (result, 0)
if self.weather.name == "Heavy Snow" and weather_count == offense_team.lineup_position and "snow_atbat" not in self.last_update[0].keys():
result["snow_atbat"] = True
result["text"] = f"{offense_team.lineup[offense_team.lineup_position % len(offense_team.lineup)].name}'s hands are too cold! {self.get_batter().name} is forced to bat!"
return (result, 0)
defenders = defense_team.lineup.copy() defenders = defense_team.lineup.copy()
defenders.append(defense_team.pitcher) defenders.append(defense_team.pitcher)
defender = random.choice(defenders) #pitcher can field outs now :3 defender = random.choice(defenders) #pitcher can field outs now :3
@ -556,12 +589,21 @@ class game(object):
for base in self.bases.keys(): for base in self.bases.keys():
self.bases[base] = None self.bases[base] = None
self.outs = 0 self.outs = 0
if self.top_of_inning and self.weather.name == "Heavy Snow" and self.weather.counter_away < self.teams["away"].lineup_position:
self.weather.counter_away = self.pitcher_insert(self.teams["away"])
if not self.top_of_inning: if not self.top_of_inning:
if self.weather.name == "Heavy Snow" and self.weather.counter_home < self.teams["home"].lineup_position:
self.weather.counter_home = self.pitcher_insert(self.teams["home"])
self.inning += 1 self.inning += 1
if self.inning > self.max_innings and self.teams["home"].score != self.teams["away"].score: #game over if self.inning > self.max_innings and self.teams["home"].score != self.teams["away"].score: #game over
self.over = True self.over = True
self.top_of_inning = not self.top_of_inning self.top_of_inning = not self.top_of_inning
def pitcher_insert(self, this_team):
rounds = math.ceil(this_team.lineup_position / len(this_team.lineup))
position = random.randint(0, len(this_team.lineup)-1)
return rounds * len(this_team.lineup) + position
def end_of_game_report(self): def end_of_game_report(self):
return { return {
@ -604,19 +646,9 @@ class game(object):
else: else:
inningtext = "bottom" inningtext = "bottom"
updatestring = f"{self.last_update[0]['batter']} {self.last_update[0]['text'].value} {self.last_update[0]['defender']}{punc}\n" updatestring = "this isn't used but i don't want to break anything"
if self.last_update[1] > 0: return "this isn't used but i don't want to break anything"
updatestring += f"{self.last_update[1]} runs scored!"
return f"""Last update: {updatestring}
Score: {self.teams['away'].score} - {self.teams['home'].score}.
Current inning: {inningtext} of {self.inning}. {self.outs} outs.
Pitcher: {self.get_pitcher().name}
Batter: {self.get_batter().name}
Bases: 3: {str(self.bases[3])} 2: {str(self.bases[2])} 1: {str(self.bases[1])}
"""
else: else:
return f"""Game over! Final score: **{self.teams['away'].score} - {self.teams['home'].score}** return f"""Game over! Final score: **{self.teams['away'].score} - {self.teams['home'].score}**
Last update: {self.last_update[0]['batter']} {self.last_update[0]['text'].value} {self.last_update[0]['defender']}{punc}""" Last update: {self.last_update[0]['batter']} {self.last_update[0]['text'].value} {self.last_update[0]['defender']}{punc}"""
@ -735,7 +767,7 @@ def search_team(search_term):
return None return None
teams.append(team_json) teams.append(team_json)
return teams return teams
def base_string(base): def base_string(base):
if base == 1: if base == 1:
@ -754,6 +786,8 @@ class weather(object):
def __init__(self, new_name, new_emoji): def __init__(self, new_name, new_emoji):
self.name = new_name self.name = new_name
self.emoji = new_emoji self.emoji = new_emoji
self.counter_away = 0
self.counter_home = 0
def __str__(self): def __str__(self):
return f"{self.emoji} {self.name}" return f"{self.emoji} {self.name}"

View File

@ -93,6 +93,19 @@ def update_loop():
state["update_emoji"] = "💎" state["update_emoji"] = "💎"
state["update_text"] = updatestring state["update_text"] = updatestring
elif "mulligan" in this_game.last_update[0].keys():
updatestring = ""
punc = ""
if this_game.last_update[0]["defender"] != "":
punc = ", "
state["update_emoji"] = "🏌️‍♀️"
state["update_text"] = f"{this_game.last_update[0]['batter']} would have gone out, but they took a mulligan!"
elif "snow_atbat" in this_game.last_update[0].keys():
state["update_emoji"] = ""
state["update_text"] = this_game.last_update[0]["text"]
else: else:
updatestring = "" updatestring = ""
punc = "" punc = ""

View File

@ -295,8 +295,8 @@ class CreditCommand(Command):
await msg.channel.send("Our avatar was graciously provided to us, with permission, by @HetreaSky on Twitter.") await msg.channel.send("Our avatar was graciously provided to us, with permission, by @HetreaSky on Twitter.")
class SwapPlayerCommand(Command): class SwapPlayerCommand(Command):
name = "swap" name = "swapsection"
template = """m;swap template = """m;swapsection
[team name] [team name]
[player name]""" [player name]"""
description = "Swaps a player from lineup to rotation, or from rotation to lineup. Requires team ownership." description = "Swaps a player from lineup to rotation, or from rotation to lineup. Requires team ownership."
@ -308,16 +308,98 @@ class SwapPlayerCommand(Command):
if team is None: if team is None:
await msg.channel.send("Can't find that team, boss. Typo?") await msg.channel.send("Can't find that team, boss. Typo?")
return return
elif owner_id != msg.author.id or msg.author.id not in config()["owners"]: elif owner_id != msg.author.id and msg.author.id not in config()["owners"]:
await msg.channel.send("You're not authorized to mess with this team. Sorry, boss.") await msg.channel.send("You're not authorized to mess with this team. Sorry, boss.")
return return
elif not team.swap_player(player_name): elif not team.swap_player(player_name):
await msg.channel.send("Either we can't find that player, or they're your last member of that side of the roster. Can't field an empty lineup, chief.") await msg.channel.send("Either we can't find that player, you've got no space on the other side, or they're your last member of that side of the roster. Can't field an empty lineup, and we *do* have rules, chief.")
return return
else: else:
await msg.channel.send(embed=build_team_embed(team)) await msg.channel.send(embed=build_team_embed(team))
games.update_team(team) games.update_team(team)
await msg.channel.send("Paperwork signed, stamped, and copied.") await msg.channel.send("Paperwork signed, stamped, copied, and faxed up to the goddess. Xie's pretty quick with this stuff.")
class MovePlayerCommand(Command):
name = "move"
template = """m;move
[team name]
[player name]
[new lineup/rotation position number] (indexed with 1 being the top)"""
description = "Moves a player in your lineup or rotation. Requires team ownership."
async def execute(self, msg, command):
team_name = command.split("\n")[1].strip()
player_name = command.split("\n")[2].strip()
team, owner_id = games.get_team_and_owner(team_name)
try:
new_pos = int(command.split("\n")[3].strip())
except ValueError:
await msg.channel.send("Hey, quit being cheeky. We're just trying to help. Third line has to be a natural number, boss.")
return
if owner_id != msg.author.id and msg.author.id not in config()["owners"]:
await msg.channel.send("You're not authorized to mess with this team. Sorry, boss.")
return
elif not team.slide_player(player_name, new_pos):
await msg.channel.send("You either gave us a number that was bigger than your current roster, or we couldn't find the player on the team. Try again.")
return
else:
await msg.channel.send(embed=build_team_embed(team))
games.update_team(team)
await msg.channel.send("Paperwork signed, stamped, copied, and faxed up to the goddess. Xie's pretty quick with this stuff.")
class AddPlayerCommand(Command):
name = "addplayer"
template = """m;addplayer pitcher (or m;addplayer batter)
[team name]
[player name]"""
description = "Recruits a new player to your team, as either a pitcher or a batter. Requires team ownership."
async def execute(self, msg, command):
team_name = command.split("\n")[1].strip()
player_name = command.split("\n")[2].strip()
team, owner_id = games.get_team_and_owner(team_name)
if owner_id != msg.author.id and msg.author.id not in config()["owners"]:
await msg.channel.send("You're not authorized to mess with this team. Sorry, boss.")
return
new_player = games.player(ono.get_stats(player_name))
if "batter" in command.split("\n")[0]:
if not team.add_lineup(new_player)[0]:
await msg.channel.send("Too many batters 🎶")
return
elif "pitcher" in command.split("\n")[0]:
if not team.add_pitcher(new_player):
await msg.channel.send("8 pitchers is quite enough, we think.")
return
await msg.channel.send(embed=build_team_embed(team))
games.update_team(team)
await msg.channel.send("Paperwork signed, stamped, copied, and faxed up to the goddess. Xie's pretty quick with this stuff.")
class DeletePlayerCommand(Command):
name = "removeplayer"
template = """m;removeplayer
[team name]
[player name]"""
async def execute(self, msg, command):
team_name = command.split("\n")[1].strip()
player_name = command.split("\n")[2].strip()
team, owner_id = games.get_team_and_owner(team_name)
if owner_id != msg.author.id and msg.author.id not in config()["owners"]:
await msg.channel.send("You're not authorized to mess with this team. Sorry, boss.")
return
if not team.delete_player(player_name):
await msg.channel.send("We've got bad news: that player isn't on your team. The good news is that... that player isn't on your team?")
return
else:
await msg.channel.send(embed=build_team_embed(team))
games.update_team(team)
await msg.channel.send("Paperwork signed, stamped, copied, and faxed up to the goddess. Xie's pretty quick with this stuff.")
class HelpCommand(Command): class HelpCommand(Command):
name = "help" name = "help"
@ -386,6 +468,9 @@ commands = [
SaveTeamCommand(), SaveTeamCommand(),
ImportCommand(), ImportCommand(),
SwapPlayerCommand(), SwapPlayerCommand(),
MovePlayerCommand(),
AddPlayerCommand(),
DeletePlayerCommand(),
DeleteTeamCommand(), DeleteTeamCommand(),
ShowTeamCommand(), ShowTeamCommand(),
ShowAllTeamsCommand(), ShowAllTeamsCommand(),
@ -635,6 +720,9 @@ async def watch_game(channel, newgame, user = None, league = None):
"start_delay" : 5, "start_delay" : 5,
"end_delay" : 10 "end_delay" : 10
} }
if newgame.weather.name == "Heavy Snow":
newgame.weather.counter_away = random.randint(0,len(newgame.teams['away'].lineup)-1)
newgame.weather.counter_home = random.randint(0,len(newgame.teams['home'].lineup)-1)
if league is not None: if league is not None:
discrim_string = league discrim_string = league