2020-12-26 09:46:42 +00:00
import discord , json , math , os , roman , games , asyncio
2020-12-20 00:08:09 +00:00
import database as db
2020-12-20 01:26:05 +00:00
import onomancer as ono
2020-12-20 00:08:09 +00:00
2020-12-27 08:42:09 +00:00
class Command :
def isauthorized ( self , user ) :
return True
2020-12-20 00:08:09 +00:00
2020-12-27 08:42:09 +00:00
async def execute ( self , msg , command ) :
2020-12-22 20:02:28 +00:00
return
2020-12-27 08:42:09 +00:00
class IntroduceCommand ( Command ) :
name = " introduce "
template = " "
description = " "
2020-12-22 20:02:28 +00:00
2020-12-27 08:42:09 +00:00
def isauthorized ( self , user ) :
return user . id in config ( ) [ " owners " ]
2020-12-20 01:26:05 +00:00
2020-12-27 08:42:09 +00:00
async def execute ( self , msg , command ) :
text = """ **Your name, favorite team, and pronouns**: Matteo Prestige, CHST, they/them ***only.*** There ' s more than one of us up here, after all.
* * What are you majoring in ( wrong answers only ) * * : Economics .
* * Your favorite and least favorite beverage , without specifying which * * : Vanilla milkshakes , chocolate milkshakes .
* * Favorite non - Mild Low team * * : The Mills . We hope they ' re treating Ren alright.
* * If you were a current blaseball player , who would you be * * : We refuse to answer this question .
* * Your hobbies / interests * * : Minigolf , blaseball , felony insider trading .
Our avatar was graciously provided to us , with permission , by @HetreaSky on Twitter .
"""
await msg . channel . send ( text )
2020-12-20 05:13:23 +00:00
2020-12-27 09:03:41 +00:00
class CountActiveGamesCommand ( Command ) :
name = " countactivegames "
template = " "
description = " "
2020-12-22 20:02:28 +00:00
2020-12-27 09:03:41 +00:00
def isauthorized ( self , user ) :
return user . id in config ( ) [ " owners " ]
2020-12-20 01:26:05 +00:00
2020-12-27 09:03:41 +00:00
async def execute ( self , msg , command ) :
await msg . channel . send ( f " There ' s { len ( gamesarray ) } active games right now, boss. " )
2020-12-20 05:13:23 +00:00
2020-12-27 08:42:09 +00:00
class RomanCommand ( Command ) :
name = " roman "
template = " m;roman [number] "
description = " Converts any natural number less than 4,000,000 into roman numerals. This one is just for fun. "
2020-12-20 05:13:23 +00:00
2020-12-27 08:42:09 +00:00
async def execute ( self , msg , command ) :
2020-12-20 10:28:47 +00:00
try :
2020-12-27 08:42:09 +00:00
await msg . channel . send ( roman . roman_convert ( command ) )
2020-12-20 10:28:47 +00:00
except ValueError :
2020-12-27 08:42:09 +00:00
await msg . channel . send ( f " \" { command } \" isn ' t an integer in Arabic numerals. " )
class IdolizeCommand ( Command ) :
name = " idolize "
template = " m;idolize [name] "
description = " Records any name as your idol, used elsewhere. There ' s a limit of 70 characters. That should be *plenty*. "
2020-12-20 10:28:47 +00:00
2020-12-27 08:42:09 +00:00
async def execute ( self , msg , command ) :
if ( command . startswith ( " meme " ) ) :
2020-12-20 12:25:25 +00:00
meme = True
2020-12-27 08:42:09 +00:00
command = command . split ( " " , 1 ) [ 1 ]
2020-12-20 12:25:25 +00:00
else :
meme = False
2020-12-27 08:42:09 +00:00
player_name = discord . utils . escape_mentions ( command )
2020-12-22 20:15:18 +00:00
if len ( player_name ) > = 70 :
await msg . channel . send ( " That name is too long. Please keep it below 70 characters, for my sake and yours. " )
return
2020-12-23 23:02:55 +00:00
try :
player_json = ono . get_stats ( player_name )
db . designate_player ( msg . author , json . loads ( player_json ) )
if not meme :
await msg . channel . send ( f " { player_name } is now your idol. " )
else :
await msg . channel . send ( f " { player_name } is now { msg . author . display_name } ' s idol. " )
await msg . channel . send ( f " Reply if { player_name } is your idol also. " )
except :
2020-12-27 01:28:36 +00:00
await msg . channel . send ( " Something went wrong. Tell xvi. " )
2020-12-20 12:25:25 +00:00
2020-12-27 08:42:09 +00:00
class ShowIdolCommand ( Command ) :
name = " showidol "
template = " m;showidol "
description = " Displays your idol ' s name and stars in a nice discord embed. "
async def execute ( self , msg , command ) :
2020-12-20 12:25:25 +00:00
try :
player_json = db . get_user_player ( msg . author )
embed = build_star_embed ( player_json )
embed . set_footer ( text = msg . author . display_name )
await msg . channel . send ( embed = embed )
except :
await msg . channel . send ( " We can ' t find your idol. Looked everywhere, too. " )
2020-12-27 08:42:09 +00:00
class ShowPlayerCommand ( Command ) :
name = " showplayer "
template = " m;showplayer [name] "
description = " Displays any name ' s stars in a nice discord embed. "
async def execute ( self , msg , command ) :
2020-12-24 09:51:38 +00:00
player_name = json . loads ( ono . get_stats ( command . split ( " " , 1 ) [ 1 ] ) )
await msg . channel . send ( embed = build_star_embed ( player_name ) )
2020-12-27 08:42:09 +00:00
class StartGameCommand ( Command ) :
name = " startgame "
template = " m;startgame [away] [home] [innings] "
description = """ To start a game with premade teams, use this command at the top of a list, with lines seperated by newlines (shift+enter in discord, or copy+paste from notepad)
- the first line is the away team ' s name
- the second is the home team ' s name
- the third is the number of innings , which must be greater than 2. """
2020-12-24 09:51:38 +00:00
2020-12-27 08:42:09 +00:00
async def execute ( self , msg , command ) :
2020-12-27 05:52:34 +00:00
if config ( ) [ " game_freeze " ] :
2020-12-27 01:02:39 +00:00
await msg . channel . send ( " Patch incoming. We ' re not allowing new games right now. " )
return
2020-12-26 05:17:49 +00:00
2020-12-24 10:18:29 +00:00
try :
team1 = games . get_team ( command . split ( " \n " ) [ 1 ] )
team2 = games . get_team ( command . split ( " \n " ) [ 2 ] )
innings = int ( command . split ( " \n " ) [ 3 ] )
except IndexError :
await msg . channel . send ( " We need four lines: startgame, away team, home team, and the number of innings. " )
return
except :
2020-12-27 01:02:39 +00:00
await msg . channel . send ( " Something about that command tripped us up. Either we couldn ' t find a team, or you gave us a bad number of innings. " )
2020-12-26 05:27:14 +00:00
return
if innings < 2 :
await msg . channel . send ( " Anything less than 2 innings isn ' t even an outing. Try again. " )
return
2020-12-27 01:27:03 +00:00
2020-12-27 01:02:39 +00:00
elif innings > 30 and msg . author . id not in config ( ) [ " owners " ] :
await msg . channel . send ( " Y ' all can ' t behave, so we ' ve limited games to 30 innings. Ask xvi to start it with more if you really want to. " )
2020-12-27 01:56:10 +00:00
return
2020-12-24 10:18:29 +00:00
if team1 is not None and team2 is not None :
game = games . game ( msg . author . name , team1 , team2 , length = innings )
2020-12-27 03:53:32 +00:00
channel = msg . channel
2020-12-27 05:52:34 +00:00
user_mention = msg . author . mention
2020-12-27 03:53:32 +00:00
await msg . delete ( )
2020-12-27 05:52:34 +00:00
if len ( gamesarray ) > = 45 :
await channel . send ( f " We ' re running 45 games right now, and Discord probably isn ' t very pleased about it. You ' re at # { len ( gamesqueue ) + 1 } in the list. \n We ' ll ping you when it ' s ready, chief. " )
gamesqueue . append ( ( channel , game , user_mention ) )
return
2020-12-27 03:53:32 +00:00
game_task = asyncio . create_task ( watch_game ( channel , game ) )
2020-12-24 10:18:29 +00:00
await game_task
2020-12-22 06:56:33 +00:00
2020-12-27 08:42:09 +00:00
class SetupGameCommand ( Command ) :
name = " setupgame "
template = " m;setupgame "
description = " Begins setting up a 3-inning pickup game. Pitchers, lineups, and team names are given during the setup process by anyone able to type in that channel. Idols are easily signed up via emoji during the process. The game will start automatically after setup. "
async def execute ( self , msg , command ) :
2020-12-26 06:07:10 +00:00
if len ( gamesarray ) > 45 :
2020-12-27 01:42:25 +00:00
await msg . channel . send ( " We ' re running 45 games and we doubt Discord will be happy with any more. These edit requests don ' t come cheap. " )
2020-12-26 05:17:49 +00:00
return
2020-12-27 01:02:39 +00:00
elif config ( ) [ " game_freeze " ] :
await msg . channel . send ( " Patch incoming. We ' re not allowing new games right now. " )
2020-12-27 01:18:27 +00:00
return
2020-12-26 05:17:49 +00:00
2020-12-23 01:20:58 +00:00
for game in gamesarray :
2020-12-27 02:36:39 +00:00
if game . name == msg . author . name :
2020-12-26 05:17:49 +00:00
await msg . channel . send ( " You ' ve already got a game in progress! Wait a tick, boss. " )
2020-12-23 01:20:58 +00:00
return
2020-12-24 09:51:38 +00:00
try :
2020-12-27 08:42:09 +00:00
inningmax = int ( command )
2020-12-24 09:51:38 +00:00
except :
inningmax = 3
game_task = asyncio . create_task ( setup_game ( msg . channel , msg . author , games . game ( msg . author . name , games . team ( ) , games . team ( ) , length = inningmax ) ) )
2020-12-23 01:20:58 +00:00
await game_task
2020-12-27 08:42:09 +00:00
class SaveTeamCommand ( Command ) :
name = " saveteam "
template = " m;saveteam [name] [slogan] [players] "
description = """ To save an entire team, send this command at the top of a list, with lines seperated by newlines (shift+enter in discord, or copy+paste from notepad)
- the first line of the list is your team ' s name (cannot contain emoji)
- the second is your team ' s slogan
- the rest of the lines are your players ' names
- the last player is designated your pitcher
if you did it correctly , you ' ll get a team embed with a prompt to confirm. Hit the 👍 and it ' ll be saved . """
async def execute ( self , msg , command ) :
if db . get_team ( command . split ( " \n " ) [ 0 ] ) == None :
2020-12-26 09:46:42 +00:00
save_task = asyncio . create_task ( save_team_batch ( msg , command ) )
await save_task
else :
name = command . split ( ' \n ' , 1 ) [ 1 ] . split ( ' \n ' ) [ 0 ]
await msg . channel . send ( f " { name } already exists. Try a new name, maybe? " )
2020-12-22 06:56:33 +00:00
2020-12-27 08:42:09 +00:00
class ShowTeamCommand ( Command ) :
name = " showteam "
template = " m;showteam [name] "
description = " You can view any saved team with this command "
async def execute ( self , msg , command ) :
2020-12-27 09:32:19 +00:00
team_name = command . strip ( )
team = games . get_team ( team_name )
2020-12-24 09:51:38 +00:00
if team is not None :
await msg . channel . send ( embed = build_team_embed ( team ) )
else :
2020-12-27 09:32:19 +00:00
teams = games . search_team ( team_name . lower ( ) )
if len ( teams ) == 1 :
await msg . channel . send ( embed = build_team_embed ( teams [ 0 ] ) )
else :
await msg . channel . send ( " Can ' t find that team, boss. Typo? " )
2020-12-21 09:46:12 +00:00
2020-12-27 08:42:09 +00:00
class ShowAllTeamsCommand ( Command ) :
name = " showallteams "
template = " m;showallteams "
description = " This displays a paginated list of all teams available for `startgame` "
async def execute ( self , msg , command ) :
2020-12-26 09:46:42 +00:00
list_task = asyncio . create_task ( team_pages ( msg , games . get_all_teams ( ) ) )
await list_task
2020-12-27 08:42:09 +00:00
class SearchTeamsCommand ( Command ) :
name = " searchteams "
template = " m;searchteams [searchterm] "
description = " Displays paginated list of all teams whose names contain `searchterm` "
async def execute ( self , msg , command ) :
search_term = command . strip ( )
2020-12-26 10:09:49 +00:00
if len ( search_term ) > 30 :
await msg . channel . send ( " Team names can ' t even be that long, chief. Try something shorter. " )
return
list_task = asyncio . create_task ( team_pages ( msg , games . search_team ( search_term ) , search_term = search_term ) )
2020-12-26 09:46:42 +00:00
await list_task
2020-12-27 08:42:09 +00:00
class CreditCommand ( Command ) :
name = " credit "
template = " m;credit "
description = " Shows artist credit for matteo ' s avatar. "
async def execute ( self , msg , command ) :
2020-12-20 05:17:05 +00:00
await msg . channel . send ( " Our avatar was graciously provided to us, with permission, by @HetreaSky on Twitter. " )
2020-12-20 05:13:23 +00:00
2020-12-27 08:42:09 +00:00
class HelpCommand ( Command ) :
name = " help "
template = " m;help [command] "
description = " Displays a list of all commands, or the description of the given command if one is present. "
async def execute ( self , msg , command ) :
query = command . strip ( )
if query == " " :
2020-12-26 21:35:18 +00:00
text = " Here ' s everything we know how to do; use `m;help [command]` for more info: "
2020-12-27 08:42:09 +00:00
for comm in commands :
if comm . isauthorized ( msg . author ) :
text + = f " \n - { comm . name } "
2020-12-26 21:35:18 +00:00
else :
2020-12-27 08:42:09 +00:00
try :
comm = next ( c for c in commands if c . name == query and c . isauthorized ( msg . author ) )
text = f " ` { comm . template } ` \n { comm . description } "
except :
2020-12-26 21:35:18 +00:00
text = " Can ' t find that command, boss; try checking the list with `m;help`. "
await msg . channel . send ( text )
2020-12-27 08:42:09 +00:00
commands = [
IntroduceCommand ( ) ,
2020-12-27 09:03:41 +00:00
CountActiveGamesCommand ( ) ,
2020-12-27 08:42:09 +00:00
IdolizeCommand ( ) ,
ShowIdolCommand ( ) ,
ShowPlayerCommand ( ) ,
SetupGameCommand ( ) ,
SaveTeamCommand ( ) ,
ShowTeamCommand ( ) ,
ShowAllTeamsCommand ( ) ,
SearchTeamsCommand ( ) ,
StartGameCommand ( ) ,
CreditCommand ( ) ,
RomanCommand ( ) ,
HelpCommand ( )
]
2020-12-26 21:35:18 +00:00
2020-12-27 08:42:09 +00:00
client = discord . Client ( )
gamesarray = [ ]
2020-12-27 09:03:41 +00:00
gamesqueue = [ ]
2020-12-27 08:42:09 +00:00
setupmessages = { }
2020-12-26 21:35:18 +00:00
2020-12-27 08:42:09 +00:00
def config ( ) :
if not os . path . exists ( " config.json " ) :
#generate default config
config_dic = {
" token " : " " ,
" owners " : [
0000
] ,
" prefix " : [ " m; " , " m! " ] ,
" soulscream channel id " : 0 ,
" game_freeze " : 0
}
with open ( " config.json " , " w " ) as config_file :
json . dump ( config_dic , config_file , indent = 4 )
print ( " please fill in bot token and any bot admin discord ids to the new config.json file! " )
quit ( )
else :
with open ( " config.json " ) as config_file :
return json . load ( config_file )
2020-12-20 05:13:23 +00:00
2020-12-27 08:42:09 +00:00
@client.event
async def on_ready ( ) :
db . initialcheck ( )
print ( f " logged in as { client . user } with token { config ( ) [ ' token ' ] } " )
@client.event
async def on_reaction_add ( reaction , user ) :
if reaction . message in setupmessages . keys ( ) :
game = setupmessages [ reaction . message ]
try :
if str ( reaction . emoji ) == " 🔼 " and not user == client . user :
new_player = games . player ( ono . get_stats ( db . get_user_player ( user ) [ " name " ] ) )
game . teams [ " away " ] . add_lineup ( new_player )
await reaction . message . channel . send ( f " { new_player } { new_player . star_string ( ' batting_stars ' ) } takes spot # { len ( game . teams [ ' away ' ] . lineup ) } on the away lineup. " )
elif str ( reaction . emoji ) == " 🔽 " and not user == client . user :
new_player = games . player ( ono . get_stats ( db . get_user_player ( user ) [ " name " ] ) )
game . teams [ " home " ] . add_lineup ( new_player )
await reaction . message . channel . send ( f " { new_player } { new_player . star_string ( ' batting_stars ' ) } takes spot # { len ( game . teams [ ' home ' ] . lineup ) } on the home lineup. " )
except :
await reaction . message . channel . send ( f " { user . display_name } , we can ' t find your idol. Maybe you don ' t have one yet? " )
@client.event
async def on_message ( msg ) :
if msg . author == client . user :
return
command_b = False
for prefix in config ( ) [ " prefix " ] :
if msg . content . startswith ( prefix ) :
command_b = True
command = msg . content . split ( prefix , 1 ) [ 1 ]
if not command_b :
return
if msg . channel . id == config ( ) [ " soulscream channel id " ] :
try :
await msg . channel . send ( ono . get_scream ( msg . author . nick ) )
except TypeError or AttributeError :
await msg . channel . send ( ono . get_scream ( msg . author . name ) )
except AttributeError :
await msg . channel . send ( ono . get_scream ( msg . author . name ) )
else :
try :
comm = next ( c for c in commands if command . startswith ( c . name ) )
await comm . execute ( msg , command [ len ( comm . name ) : ] )
except StopIteration :
return
2020-12-20 00:08:09 +00:00
2020-12-22 06:56:33 +00:00
async def start_game ( channel ) :
msg = await channel . send ( " Play ball! " )
await asyncio . sleep ( 4 )
newgame = games . debug_game ( )
gamesarray . append ( newgame )
while not newgame . over :
state = newgame . gamestate_update_full ( )
if not state . startswith ( " Game over " ) :
await msg . edit ( content = state )
2020-12-22 12:59:46 +00:00
await asyncio . sleep ( 3 )
2020-12-22 06:56:33 +00:00
await channel . send ( state )
gamesarray . pop ( )
2020-12-23 01:20:58 +00:00
async def setup_game ( channel , owner , newgame ) :
newgame . owner = owner
await channel . send ( f " Game sucessfully created! \n Start any commands for this game with ` { newgame . name } ` so I know who ' s talking about what. " )
await asyncio . sleep ( 1 )
await channel . send ( " Who ' s pitching for the away team? " )
def input ( msg ) :
return msg . content . startswith ( newgame . name ) and msg . channel == channel #if author or willing participant and in correct channel
while newgame . teams [ " home " ] . pitcher == None :
def nameinput ( msg ) :
return msg . content . startswith ( newgame . name ) and msg . channel == channel #if author or willing participant and in correct channel
2020-12-27 01:18:27 +00:00
2020-12-23 01:20:58 +00:00
while newgame . teams [ " away " ] . pitcher == None :
try :
namemsg = await client . wait_for ( ' message ' , check = input )
new_pitcher_name = discord . utils . escape_mentions ( namemsg . content . split ( f " { newgame . name } " ) [ 1 ] )
if len ( new_pitcher_name ) > 70 :
await channel . send ( " That player name is too long, chief. 70 or less. " )
else :
new_pitcher = games . player ( ono . get_stats ( new_pitcher_name ) )
newgame . teams [ " away " ] . set_pitcher ( new_pitcher )
await channel . send ( f " { new_pitcher } { new_pitcher . star_string ( ' pitching_stars ' ) } , pitching for the away team! \n Now, the home team ' s pitcher. Same dance, folks. " )
except NameError :
await channel . send ( " Uh. " )
try :
namemsg = await client . wait_for ( ' message ' , check = input )
new_pitcher_name = discord . utils . escape_mentions ( namemsg . content . split ( f " { newgame . name } " ) [ 1 ] )
if len ( new_pitcher_name ) > 70 :
await channel . send ( " That player name is too long, chief. 70 or less. " )
else :
new_pitcher = games . player ( ono . get_stats ( new_pitcher_name ) )
newgame . teams [ " home " ] . set_pitcher ( new_pitcher )
await channel . send ( f " And { new_pitcher } { new_pitcher . star_string ( ' pitching_stars ' ) } , pitching for the home team. " )
except :
await channel . send ( " Uh. " )
#pitchers assigned!
team_join_message = await channel . send ( f """ Now, the lineups! I need somewhere between 1 and 12 batters. Cloning helps a lot with this sort of thing.
React to this message with 🔼 to have your idol join the away team , or 🔽 to have them join the home team .
You can also enter names like you did for the pitchers , with a slight difference : ` away [ name ] ` or ` home [ name ] ` instead of just the name .
Creator , type ` { newgame . name } done ` to finalize lineups . """ )
await team_join_message . add_reaction ( " 🔼 " )
await team_join_message . add_reaction ( " 🔽 " )
setupmessages [ team_join_message ] = newgame
#emoji_task = asyncio.create_task(watch_for_reacts(team_join_message, ready, newgame))
#msg_task = asyncio.create_task(watch_for_messages(channel, ready, newgame))
#await asyncio.gather(
# watch_for_reacts(team_join_message, newgame),
# watch_for_messages(channel, newgame)
# )
def messagecheck ( msg ) :
return ( msg . content . startswith ( newgame . name ) ) and msg . channel == channel and msg . author != client . user
while not newgame . ready :
2020-12-27 01:09:19 +00:00
try :
msg = await client . wait_for ( ' message ' , timeout = 120.0 , check = messagecheck )
except asyncio . TimeoutError :
await channel . send ( " Game timed out. 120 seconds between players is a bit much, see? " )
2020-12-27 02:15:19 +00:00
del setupmessages [ team_join_message ]
del newgame
2020-12-27 01:09:19 +00:00
return
2020-12-23 01:20:58 +00:00
new_player = None
if msg . author == newgame . owner and msg . content == f " { newgame . name } done " :
if newgame . teams [ ' home ' ] . finalize ( ) and newgame . teams [ ' away ' ] . finalize ( ) :
newgame . ready = True
break
else :
side = None
if msg . content . split ( f " { newgame . name } " ) [ 1 ] . split ( " " , 1 ) [ 0 ] == " home " :
side = " home "
elif msg . content . split ( f " { newgame . name } " ) [ 1 ] . split ( " " , 1 ) [ 0 ] == " away " :
side = " away "
if side is not None :
new_player_name = discord . utils . escape_mentions ( msg . content . split ( f " { newgame . name } " ) [ 1 ] . split ( " " , 1 ) [ 1 ] )
if len ( new_player_name ) > 70 :
await channel . send ( " That player name is too long, chief. 70 or less. " )
else :
new_player = games . player ( ono . get_stats ( new_player_name ) )
try :
if new_player is not None :
newgame . teams [ side ] . add_lineup ( new_player )
await channel . send ( f " { new_player } { new_player . star_string ( ' batting_stars ' ) } takes spot # { len ( newgame . teams [ side ] . lineup ) } on the { side } lineup. " )
except :
True
del setupmessages [ team_join_message ] #cleanup!
await channel . send ( " Name the away team, creator. " )
def ownercheck ( msg ) :
return msg . author == newgame . owner
while newgame . teams [ " home " ] . name == None :
while newgame . teams [ " away " ] . name == None :
newname = await client . wait_for ( ' message ' , check = ownercheck )
if len ( newname . content ) < 30 :
newgame . teams [ ' away ' ] . name = newname . content
await channel . send ( f " Stepping onto the field, the visitors: { newname . content } ! \n Finally, the home team, and we can begin. " )
else :
await channel . send ( " Hey, keep these to 30 characters or less please. Discord messages have to stay short. " )
newname = await client . wait_for ( ' message ' , check = ownercheck )
if len ( newname . content ) < 30 :
newgame . teams [ ' home ' ] . name = newname . content
await channel . send ( f " Next on the diamond, your home team: { newname . content } ! " )
else :
await channel . send ( " Hey, keep these to 30 characters or less please. Discord messages have to stay short. " )
await asyncio . sleep ( 3 )
await channel . send ( f " ** { newgame . teams [ ' away ' ] . name } at { newgame . teams [ ' home ' ] . name } ** " )
game_task = asyncio . create_task ( watch_game ( channel , newgame ) )
await game_task
async def watch_game ( channel , game ) :
2020-12-22 12:59:46 +00:00
blank_emoji = discord . utils . get ( client . emojis , id = 790899850295509053 )
empty_base = discord . utils . get ( client . emojis , id = 790899850395779074 )
2020-12-26 01:47:24 +00:00
occupied_base = discord . utils . get ( client . emojis , id = 790899850320543745 )
2020-12-24 09:51:38 +00:00
out_emoji = discord . utils . get ( client . emojis , id = 791578957241778226 )
in_emoji = discord . utils . get ( client . emojis , id = 791578957244792832 )
2020-12-27 01:18:27 +00:00
2020-12-23 01:20:58 +00:00
newgame = game
2020-12-26 01:47:24 +00:00
embed = await channel . send ( " Starting... " )
2020-12-26 05:17:49 +00:00
await asyncio . sleep ( 1 )
await embed . pin ( )
await asyncio . sleep ( 1 )
2020-12-27 02:36:39 +00:00
gamesarray . append ( newgame )
2020-12-26 05:08:45 +00:00
pause = 0
top_of_inning = True
2020-12-27 01:23:44 +00:00
victory_lap = False
2020-12-26 05:08:45 +00:00
while not newgame . over or newgame . top_of_inning != top_of_inning :
state = newgame . gamestate_display_full ( )
2020-12-22 12:59:46 +00:00
new_embed = discord . Embed ( color = discord . Color . purple ( ) , title = f " { newgame . teams [ ' away ' ] . name } at { newgame . teams [ ' home ' ] . name } " )
2020-12-27 01:35:38 +00:00
2020-12-22 12:59:46 +00:00
new_embed . add_field ( name = newgame . teams [ ' away ' ] . name , value = newgame . teams [ ' away ' ] . score , inline = True )
new_embed . add_field ( name = newgame . teams [ ' home ' ] . name , value = newgame . teams [ ' home ' ] . score , inline = True )
2020-12-27 01:35:38 +00:00
2020-12-26 05:08:45 +00:00
if top_of_inning :
2020-12-27 02:06:33 +00:00
new_embed . add_field ( name = " Inning: " , value = f " 🔼 { newgame . inning } / { newgame . max_innings } " , inline = True )
2020-12-27 01:43:18 +00:00
new_embed . set_footer ( text = f " { newgame . teams [ ' away ' ] . name } batting. " )
2020-12-22 12:59:46 +00:00
else :
2020-12-27 02:06:33 +00:00
new_embed . add_field ( name = " Inning: " , value = f " 🔽 { newgame . inning } / { newgame . max_innings } " , inline = True )
2020-12-27 01:43:18 +00:00
new_embed . set_footer ( text = f " { newgame . teams [ ' home ' ] . name } batting. " )
2020-12-27 01:35:38 +00:00
2020-12-26 05:08:45 +00:00
new_embed . add_field ( name = " Outs: " , value = f " { str ( out_emoji ) * newgame . outs + str ( in_emoji ) * ( 2 - newgame . outs ) } " , inline = False )
2020-12-22 12:59:46 +00:00
new_embed . add_field ( name = " Pitcher: " , value = newgame . get_pitcher ( ) , inline = False )
new_embed . add_field ( name = " Batter: " , value = newgame . get_batter ( ) , inline = False )
2020-12-26 05:08:45 +00:00
if state == " Game not started. " :
new_embed . add_field ( name = " 🍿 " , value = " Play blall! " , inline = False )
2020-12-27 01:18:27 +00:00
2020-12-26 05:08:45 +00:00
elif newgame . top_of_inning != top_of_inning :
pause = 2
new_embed . set_field_at ( 4 , name = " Pitcher: " , value = " - " , inline = False )
new_embed . set_field_at ( 5 , name = " Batter: " , value = " - " , inline = False )
if newgame . top_of_inning :
2020-12-27 02:06:33 +00:00
new_embed . set_field_at ( 2 , name = " Inning: " , value = f " 🔽 { newgame . inning - 1 } / { newgame . max_innings } " )
2020-12-26 05:08:45 +00:00
if pause == 1 :
if newgame . top_of_inning :
new_embed . add_field ( name = " 🍿 " , value = f " Top of { newgame . inning } . { newgame . teams [ ' away ' ] . name } batting! " , inline = False )
else :
2020-12-27 01:23:44 +00:00
if newgame . inning > = newgame . max_innings :
if newgame . teams [ " home " ] . score > newgame . teams [ " away " ] . score : #if home team is winning at the bottom of the last inning
victory_lap = True
2020-12-26 05:08:45 +00:00
new_embed . add_field ( name = " 🍿 " , value = f " Bottom of { newgame . inning } . { newgame . teams [ ' home ' ] . name } batting! " , inline = False )
2020-12-27 01:18:27 +00:00
2020-12-26 05:08:45 +00:00
if pause != 1 and state != " Game not started. " :
punc = " "
if newgame . last_update [ 0 ] [ " defender " ] != " " :
2020-12-27 01:18:27 +00:00
punc = " . "
2020-12-26 05:08:45 +00:00
2020-12-27 07:06:43 +00:00
if " fc_out " in newgame . last_update [ 0 ] . keys ( ) :
name , base_string = newgame . last_update [ 0 ] [ ' fc_out ' ]
updatestring = f " { newgame . last_update [ 0 ] [ ' batter ' ] } { newgame . last_update [ 0 ] [ ' text ' ] . value . format ( name , base_string ) } { newgame . last_update [ 0 ] [ ' defender ' ] } { punc } "
else :
updatestring = f " { newgame . last_update [ 0 ] [ ' batter ' ] } { newgame . last_update [ 0 ] [ ' text ' ] . value } { newgame . last_update [ 0 ] [ ' defender ' ] } { punc } "
2020-12-26 05:08:45 +00:00
if newgame . last_update [ 1 ] > 0 :
updatestring + = f " { newgame . last_update [ 1 ] } runs scored! "
2020-12-22 12:59:46 +00:00
2020-12-26 05:08:45 +00:00
new_embed . add_field ( name = " 🏏 " , value = updatestring , inline = False )
2020-12-22 12:59:46 +00:00
2020-12-26 01:47:24 +00:00
basemessage = str ( blank_emoji )
2020-12-22 12:59:46 +00:00
if newgame . bases [ 2 ] is not None :
2020-12-26 01:47:24 +00:00
basemessage + = str ( occupied_base ) + " \n "
2020-12-22 12:59:46 +00:00
else :
2020-12-26 01:47:24 +00:00
basemessage + = str ( empty_base ) + " \n "
2020-12-27 01:18:27 +00:00
2020-12-22 12:59:46 +00:00
basemessage_b = " "
if newgame . bases [ 3 ] is not None :
2020-12-26 01:47:24 +00:00
basemessage + = str ( occupied_base )
2020-12-22 12:59:46 +00:00
else :
2020-12-26 01:47:24 +00:00
basemessage + = str ( empty_base )
basemessage + = str ( blank_emoji )
2020-12-22 12:59:46 +00:00
if newgame . bases [ 1 ] is not None :
2020-12-26 01:47:24 +00:00
basemessage + = str ( occupied_base )
2020-12-22 12:59:46 +00:00
else :
2020-12-26 01:47:24 +00:00
basemessage + = str ( empty_base )
new_embed . add_field ( name = " Bases: " , value = basemessage , inline = False )
2020-12-27 01:35:38 +00:00
new_embed . add_field ( name = " Weather: " , value = " 🌟 Supernova " , inline = False )
2020-12-22 12:59:46 +00:00
2020-12-27 01:18:27 +00:00
await embed . edit ( content = None , embed = new_embed )
2020-12-26 05:08:45 +00:00
top_of_inning = newgame . top_of_inning
if pause < = 1 :
newgame . gamestate_update_full ( )
2020-12-27 01:18:27 +00:00
2020-12-26 05:08:45 +00:00
pause - = 1
await asyncio . sleep ( 6 )
2020-12-27 03:53:32 +00:00
title_string = f " { newgame . teams [ ' away ' ] . name } at { newgame . teams [ ' home ' ] . name } ended after { newgame . inning - 1 } innings "
2020-12-27 02:21:43 +00:00
if ( newgame . inning - 1 ) > newgame . max_innings : #if extra innings
title_string + = f " with { newgame . inning - ( newgame . max_innings + 1 ) } extra innings. "
2020-12-27 01:23:44 +00:00
else :
title_string + = " . "
2020-12-27 01:18:27 +00:00
2020-12-27 01:23:44 +00:00
final_embed = discord . Embed ( color = discord . Color . dark_purple ( ) , title = title_string )
2020-12-26 05:08:45 +00:00
scorestring = f " { newgame . teams [ ' away ' ] . score } to { newgame . teams [ ' home ' ] . score } \n "
2020-12-22 12:59:46 +00:00
if newgame . teams [ ' away ' ] . score > newgame . teams [ ' home ' ] . score :
2020-12-26 05:08:45 +00:00
scorestring + = f " { newgame . teams [ ' away ' ] . name } wins! "
2020-12-22 12:59:46 +00:00
else :
2020-12-27 01:23:44 +00:00
scorestring + = f " { newgame . teams [ ' home ' ] . name } wins "
if victory_lap :
scorestring + = " with a victory lap! "
else :
scorestring + = f " , shaming { newgame . teams [ ' away ' ] . name } ! "
2020-12-26 05:08:45 +00:00
2020-12-27 01:23:44 +00:00
2020-12-26 05:08:45 +00:00
final_embed . add_field ( name = " Final score: " , value = scorestring )
await embed . edit ( content = None , embed = final_embed )
2020-12-27 01:18:27 +00:00
2020-12-26 05:17:49 +00:00
await embed . unpin ( )
2020-12-27 02:36:39 +00:00
gamesarray . pop ( gamesarray . index ( newgame ) ) #cleanup is important!
2020-12-26 09:46:42 +00:00
newgame . add_stats ( )
2020-12-22 12:59:46 +00:00
del newgame
2020-12-27 05:52:34 +00:00
if len ( gamesqueue ) > 0 :
channel , game , user_mention = gamesqueue . pop ( 0 )
queue_task = asyncio . create_task ( play_from_queue ( channel , game , user_mention ) )
await queue_task
async def play_from_queue ( channel , game , user_mention ) :
await channel . send ( f " { user_mention } , your game ' s ready. " )
game_task = asyncio . create_task ( watch_game ( channel , game ) )
await game_task
2020-12-27 01:18:27 +00:00
2020-12-24 09:51:38 +00:00
def build_team_embed ( team ) :
embed = discord . Embed ( color = discord . Color . purple ( ) , title = team . name )
lineup_string = " "
for player in team . lineup :
lineup_string + = f " { player . name } { player . star_string ( ' batting_stars ' ) } \n "
2020-12-26 01:38:03 +00:00
embed . add_field ( name = " Pitcher: " , value = f " { team . pitcher . name } { team . pitcher . star_string ( ' pitching_stars ' ) } " , inline = False )
2020-12-24 09:51:38 +00:00
embed . add_field ( name = " Lineup: " , value = lineup_string , inline = False )
embed . set_footer ( text = team . slogan )
return embed
2020-12-20 00:08:09 +00:00
2020-12-20 12:25:25 +00:00
def build_star_embed ( player_json ) :
starkeys = { " batting_stars " : " Batting " , " pitching_stars " : " Pitching " , " baserunning_stars " : " Baserunning " , " defense_stars " : " Defense " }
embed = discord . Embed ( color = discord . Color . purple ( ) , title = player_json [ " name " ] )
for key in starkeys . keys ( ) :
2020-12-20 19:05:31 +00:00
embedstring = " "
2020-12-20 12:25:25 +00:00
starstring = str ( player_json [ key ] )
2020-12-27 01:18:01 +00:00
starnum = int ( starstring [ 0 ] )
addhalf = " .5 " in starstring
2020-12-21 05:23:02 +00:00
embedstring + = " ⭐ " * starnum
2020-12-20 12:25:25 +00:00
if addhalf :
embedstring + = " ✨ "
2020-12-27 01:18:01 +00:00
elif starnum == 0 : # why check addhalf twice, amirite
embedstring + = " ⚪️ "
2020-12-20 12:25:25 +00:00
embed . add_field ( name = starkeys [ key ] , value = embedstring , inline = False )
return embed
2020-12-24 09:51:38 +00:00
async def save_team_batch ( message , command ) :
newteam = games . team ( )
#try:
roster = command . split ( " \n " , 1 ) [ 1 ] . split ( " \n " )
newteam . name = roster [ 0 ] #first line is team name
newteam . slogan = roster [ 1 ] #second line is slogan
for rosternum in range ( 2 , len ( roster ) - 1 ) :
if roster [ rosternum ] != " " :
2020-12-26 05:27:14 +00:00
if len ( roster [ rosternum ] ) > 70 :
await channel . send ( f " { roster [ rosternum ] } is too long, chief. 70 or less. " )
return
2020-12-26 23:12:38 +00:00
newteam . add_lineup ( games . player ( ono . get_stats ( roster [ rosternum ] . rstrip ( ) ) ) )
2020-12-26 05:27:14 +00:00
if len ( roster [ len ( roster ) - 1 ] ) > 70 :
await channel . send ( f " { roster [ len ( roster ) - 1 ] } is too long, chief. 70 or less. " )
return
2020-12-26 23:12:38 +00:00
newteam . set_pitcher ( games . player ( ono . get_stats ( roster [ len ( roster ) - 1 ] . rstrip ( ) ) ) ) #last line is pitcher name
2020-12-21 05:23:02 +00:00
2020-12-24 09:51:38 +00:00
if len ( newteam . name ) > 30 :
2020-12-24 10:41:19 +00:00
await message . channel . send ( " Team names have to be less than 30 characters! Try again. " )
2020-12-24 09:51:38 +00:00
return
elif len ( newteam . slogan ) > 100 :
2020-12-24 10:41:19 +00:00
await message . channel . send ( " We ' ve given you 100 characters for the slogan. Discord puts limits on us and thus, we put limits on you. C ' est la vie. " )
return
2020-12-24 09:51:38 +00:00
await message . channel . send ( embed = build_team_embed ( newteam ) )
checkmsg = await message . channel . send ( " Does this look good to you, boss? " )
await checkmsg . add_reaction ( " 👍 " )
await checkmsg . add_reaction ( " 👎 " )
def react_check ( react , user ) :
return user == message . author and react . message == checkmsg
try :
react , user = await client . wait_for ( ' reaction_add ' , timeout = 20.0 , check = react_check )
if react . emoji == " 👍 " :
await message . channel . send ( " You got it, chief. Saving now. " )
2020-12-27 02:53:46 +00:00
games . save_team ( newteam , message . author . id )
2020-12-24 09:51:38 +00:00
await message . channel . send ( " Saved! Thank you for flying Air Matteo. We hope you had a pleasant data entry. " )
return
elif react . emoji == " 👎 " :
await message . channel . send ( " Message received. Pumping brakes, turning this car around. Try again, chief. " )
return
except asyncio . TimeoutError :
await message . channel . send ( " Look, I don ' t have all day. 20 seconds is long enough, right? Try again. " )
return
#except:
#await message.channel.send("uh.")
2020-12-26 09:46:42 +00:00
2020-12-26 10:09:49 +00:00
async def team_pages ( msg , all_teams , search_term = None ) :
2020-12-26 09:46:42 +00:00
pages = [ ]
page_max = math . ceil ( len ( all_teams ) / 25 )
2020-12-26 10:09:49 +00:00
if search_term is not None :
2020-12-26 10:23:01 +00:00
title_text = f " All teams matching \" { search_term } \" : "
2020-12-26 10:09:49 +00:00
else :
title_text = " All Teams "
2020-12-26 09:46:42 +00:00
for page in range ( 0 , page_max ) :
2020-12-26 10:09:49 +00:00
embed = discord . Embed ( color = discord . Color . purple ( ) , title = title_text )
2020-12-26 09:46:42 +00:00
embed . set_footer ( text = f " Page { page + 1 } of { page_max } " )
for i in range ( 0 , 25 ) :
try :
embed . add_field ( name = all_teams [ i + 25 * page ] . name , value = all_teams [ i + 25 * page ] . slogan )
except :
break
pages . append ( embed )
teams_list = await msg . channel . send ( embed = pages [ 0 ] )
current_page = 0
if page_max > 1 :
await teams_list . add_reaction ( " ◀ " )
await teams_list . add_reaction ( " ▶ " )
def react_check ( react , user ) :
return user == msg . author and react . message == teams_list
while True :
try :
2020-12-27 01:09:19 +00:00
react , user = await client . wait_for ( ' reaction_add ' , timeout = 60.0 , check = react_check )
2020-12-26 09:46:42 +00:00
if react . emoji == " ◀ " and current_page > 0 :
current_page - = 1
2020-12-27 08:21:48 +00:00
await react . remove ( user )
2020-12-27 01:11:05 +00:00
elif react . emoji == " ▶ " and current_page < ( page_max - 1 ) :
2020-12-26 09:46:42 +00:00
current_page + = 1
2020-12-27 08:21:48 +00:00
await react . remove ( user )
2020-12-26 09:46:42 +00:00
await teams_list . edit ( embed = pages [ current_page ] )
except asyncio . TimeoutError :
return
2020-12-26 10:23:01 +00:00
client . run ( config ( ) [ " token " ] )