2021-02-21 08:03:25 +00:00
import random
2021-02-21 18:02:47 +00:00
import math
2021-02-21 23:15:23 +00:00
from gametext import appearance_outcomes , base_string
2021-02-21 08:03:25 +00:00
class Weather :
2021-02-21 18:02:47 +00:00
def __init__ ( self , game ) :
2021-02-21 08:03:25 +00:00
self . name = " Sunny "
self . emoji = " 🌞 " + " \uFE00 "
def __str__ ( self ) :
return f " { self . emoji } { self . name } "
2021-02-21 23:15:23 +00:00
def modify_atbat_stats ( self , player_rolls ) :
# Activates before batting
2021-02-21 08:03:25 +00:00
pass
2021-02-21 23:15:23 +00:00
def modify_steal_stats ( self , roll ) :
pass
def modify_atbat_roll ( self , outcome , roll , defender ) :
# activates after batter roll
pass
def activate ( self , game , result ) :
# activates after the batter calculation. modify result, or just return another thing
2021-02-21 08:03:25 +00:00
pass
def on_choose_next_batter ( self , game ) :
pass
2021-02-21 23:15:23 +00:00
def on_flip_inning ( self , game ) :
2021-02-21 18:02:47 +00:00
pass
2021-02-21 23:15:23 +00:00
def modify_top_of_inning_message ( self , game , state ) :
2021-02-21 18:02:47 +00:00
pass
2021-02-21 23:15:23 +00:00
def modify_atbat_message ( self , game , state ) :
2021-02-21 18:02:47 +00:00
pass
2021-02-21 23:15:23 +00:00
2021-02-21 08:03:25 +00:00
class Supernova ( Weather ) : # todo
2021-02-21 18:02:47 +00:00
def __init__ ( self , game ) :
2021-02-21 08:03:25 +00:00
self . name = " Supernova "
self . emoji = " 🌟 " + " \uFE00 "
2021-02-21 18:02:47 +00:00
def modify_atbat_stats ( self , roll ) :
roll [ " pitch_stat " ] * = 0.9
2021-02-21 08:03:25 +00:00
class Midnight ( Weather ) : # todo
2021-02-21 18:02:47 +00:00
def __init__ ( self , game ) :
2021-02-21 08:03:25 +00:00
self . name = " Midnight "
self . emoji = " 🕶 " + " \uFE00 "
2021-02-21 18:02:47 +00:00
def modify_steal_stats ( self , roll ) :
roll [ " run_stars " ] * = 2
2021-02-21 08:03:25 +00:00
class SlightTailwind ( Weather ) :
2021-02-21 18:02:47 +00:00
def __init__ ( self , game ) :
2021-02-21 08:03:25 +00:00
self . name = " Slight Tailwind "
self . emoji = " 🏌️♀️ " + " \uFE00 "
2021-02-21 18:02:47 +00:00
2021-02-21 08:03:25 +00:00
def activate ( self , game , result ) :
if game . top_of_inning :
offense_team = game . teams [ " away " ]
weather_count = self . counter_away
defense_team = game . teams [ " home " ]
else :
offense_team = game . teams [ " home " ]
weather_count = self . counter_home
defense_team = game . teams [ " away " ]
if " mulligan " not in game . last_update [ 0 ] . keys ( ) and not result [ " ishit " ] and result [ " text " ] != appearance_outcomes . walk :
mulligan_roll_target = - ( ( ( ( self . get_batter ( ) . stlats [ " batting_stars " ] ) - 5 ) / 6 ) * * 2 ) + 1
if random . random ( ) > mulligan_roll_target and self . get_batter ( ) . stlats [ " batting_stars " ] < = 5 :
2021-02-21 23:15:23 +00:00
result . clear ( )
result . update ( {
" text " : f " { this_game . last_update [ 0 ] [ ' batter ' ] } would have gone out, but they took a mulligan! " ,
" text_only " : True ,
" weather_message " : True ,
} )
2021-02-21 08:03:25 +00:00
class HeavySnow ( Weather ) :
2021-02-21 18:02:47 +00:00
def __init__ ( self , game ) :
2021-02-21 08:03:25 +00:00
self . name = " Heavy Snow "
self . emoji = " ❄ " + " \uFE00 "
2021-02-21 18:02:47 +00:00
self . counter_away = random . randint ( 0 , len ( game . teams [ ' away ' ] . lineup ) - 1 )
self . counter_home = random . randint ( 0 , len ( game . teams [ ' home ' ] . lineup ) - 1 )
2021-02-21 08:03:25 +00:00
2021-02-21 23:15:23 +00:00
self . swapped_batter_data = None
2021-02-21 08:03:25 +00:00
2021-02-21 23:15:23 +00:00
def activate ( self , game , result ) :
if self . swapped_batter_data :
original , sub = self . swapped_batter_data
self . swapped_batter_data = None
2021-02-21 08:03:25 +00:00
result . clear ( )
result . update ( {
2021-02-21 19:56:27 +00:00
" snow_atbat " : True ,
2021-02-21 23:15:23 +00:00
" text " : f " { original . name } ' s hands are too cold! { sub . name } is forced to bat! " ,
2021-02-21 08:03:25 +00:00
" text_only " : True ,
2021-02-21 19:12:34 +00:00
" weather_message " : True ,
2021-02-21 08:03:25 +00:00
} )
def on_flip_inning ( self , game ) :
if game . top_of_inning and self . counter_away < game . teams [ " away " ] . lineup_position :
2021-02-21 23:15:23 +00:00
self . counter_away = self . pitcher_insert_index ( game . teams [ " away " ] )
2021-02-21 08:03:25 +00:00
if not game . top_of_inning and self . counter_home < game . teams [ " home " ] . lineup_position :
2021-02-21 23:15:23 +00:00
self . counter_home = self . pitcher_insert_index ( game . teams [ " home " ] )
def pitcher_insert_index ( 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
2021-02-21 08:03:25 +00:00
def on_choose_next_batter ( self , game ) :
if game . top_of_inning :
bat_team = game . teams [ " away " ]
counter = self . counter_away
else :
bat_team = game . teams [ " home " ]
counter = self . counter_home
2021-02-21 23:15:23 +00:00
if bat_team . lineup_position == counter :
self . swapped_batter_data = ( game . current_batter , bat_team . pitcher ) # store this to generate the message during activate()
2021-02-21 08:03:25 +00:00
game . current_batter = bat_team . pitcher
class Twilight ( Weather ) :
2021-02-21 18:02:47 +00:00
def __init__ ( self , game ) :
2021-02-21 08:03:25 +00:00
self . name = " Twilight "
self . emoji = " 👻 " + " \uFE00 "
2021-02-21 18:02:47 +00:00
def modify_atbat_roll ( self , outcome , roll , defender ) :
error_line = - ( math . log ( defender . stlats [ " defense_stars " ] + 1 ) / 50 ) + 1
error_roll = random . random ( )
if error_roll > error_line :
outcome [ " error " ] = True
2021-02-21 19:12:34 +00:00
outcome [ " weather_message " ] = True
2021-02-21 18:02:47 +00:00
outcome [ " defender " ] = defender
roll [ " pb_system_stat " ] = 0.1
2021-02-21 23:15:23 +00:00
def modify_atbat_message ( self , this_game , state ) :
result = this_game . last_update [ 0 ]
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! "
2021-02-21 08:03:25 +00:00
class ThinnedVeil ( Weather ) :
2021-02-21 18:02:47 +00:00
def __init__ ( self , game ) :
2021-02-21 08:03:25 +00:00
self . name = " Thinned Veil "
self . emoji = " 🌌 " + " \uFE00 "
def activate ( self , game , result ) :
if result [ " ishit " ] :
if result [ " text " ] == appearance_outcomes . homerun or result [ " text " ] == appearance_outcomes . grandslam :
result [ " veil " ] = True
2021-02-21 23:15:23 +00:00
def modify_atbat_message ( self , game , state ) :
if " veil " in game . last_update [ 0 ] . keys ( ) :
state [ " update_emoji " ] = self . emoji
state [ " update_text " ] + = f " { game . last_update [ 0 ] [ ' batter ' ] } ' s will manifests on { base_string ( game . last_update [ 1 ] ) } base. "
2021-02-21 08:03:25 +00:00
class HeatWave ( Weather ) :
2021-02-21 18:02:47 +00:00
def __init__ ( self , game ) :
2021-02-21 08:03:25 +00:00
self . name = " Heat Wave "
self . emoji = " 🌄 " + " \uFE00 "
2021-02-21 23:15:23 +00:00
self . counter_away = random . randint ( 2 , 4 )
self . counter_home = random . randint ( 2 , 4 )
self . swapped_pitcher_data = None
2021-02-21 08:03:25 +00:00
def on_flip_inning ( self , game ) :
2021-02-21 23:15:23 +00:00
original_pitcher = game . get_pitcher ( )
2021-02-21 08:03:25 +00:00
if game . top_of_inning :
bat_team = game . teams [ " home " ]
counter = self . counter_home
2021-02-21 18:02:47 +00:00
else :
bat_team = game . teams [ " away " ]
counter = self . counter_away
2021-02-21 08:03:25 +00:00
2021-02-21 23:15:23 +00:00
if game . inning == counter :
2021-02-21 08:03:25 +00:00
if game . top_of_inning :
self . counter_home = self . counter_home - ( self . counter_home % 5 ) + 5 + random . randint ( 1 , 4 ) #rounds down to last 5, adds up to next 5. then adds a random number 2<=x<=5 to determine next pitcher
else :
self . counter_away = self . counter_away - ( self . counter_away % 5 ) + 5 + random . randint ( 1 , 4 )
2021-02-21 23:15:23 +00:00
#swap, accounting for teams where where someone's both batter and pitcher
2021-02-21 08:03:25 +00:00
tries = 0
2021-02-21 23:15:23 +00:00
while game . get_pitcher ( ) == original_pitcher and tries < 3 :
2021-02-21 08:03:25 +00:00
bat_team . set_pitcher ( use_lineup = True )
tries + = 1
2021-02-21 23:15:23 +00:00
if game . get_pitcher ( ) != original_pitcher :
self . swapped_pitcher_data = ( original_pitcher , game . get_pitcher ( ) )
def modify_top_of_inning_message ( self , game , state ) :
if self . swapped_pitcher_data :
original , sub = self . swapped_pitcher_data
self . swapped_pitcher_data = None
state [ " update_emoji " ] = self . emoji
state [ " update_text " ] + = f ' { original } is exhausted from the heat. { sub } is forced to pitch! '
2021-02-21 08:03:25 +00:00
class Drizzle ( Weather ) :
2021-02-21 18:02:47 +00:00
def __init__ ( self , game ) :
2021-02-21 08:03:25 +00:00
self . name = " Drizzle "
self . emoji = " 🌧 "
def on_flip_inning ( self , game ) :
if game . top_of_inning :
next_team = " away "
else :
next_team = " home "
lineup = game . teams [ next_team ] . lineup
game . bases [ 2 ] = lineup [ ( game . teams [ next_team ] . lineup_position - 1 ) % len ( lineup ) ]
2021-02-21 23:15:23 +00:00
def modify_top_of_inning_message ( self , game , state ) :
if game . top_of_inning :
next_team = " away "
else :
next_team = " home "
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. '
2021-02-21 08:03:25 +00:00
class Sun2 ( Weather ) :
2021-02-21 18:02:47 +00:00
def __init__ ( self , game ) :
2021-02-21 08:03:25 +00:00
self . name = " Sun 2 "
2021-02-21 18:02:47 +00:00
2021-02-21 08:03:25 +00:00
def activate ( self , game ) :
for teamtype in game . teams :
team = game . teams [ teamtype ]
if team . score > = 10 :
team . score - = 10
# no win counting yet :(
result . clear ( )
result . update ( {
2021-02-21 18:02:47 +00:00
" text " : " The {} collect 10! Sun 2 smiles. " . format ( team . name ) ,
2021-02-21 08:03:25 +00:00
" text_only " : True ,
2021-02-21 23:15:23 +00:00
" weather_message " : True
2021-02-21 08:03:25 +00:00
} )
class NameSwappyWeather ( Weather ) :
2021-02-21 18:02:47 +00:00
def __init__ ( self , game ) :
2021-02-21 08:03:25 +00:00
self . name = " Literacy "
2021-02-21 19:12:34 +00:00
self . emoji = " 📚 "
2021-02-21 08:03:25 +00:00
self . activation_chance = 0.01
2021-02-21 18:02:47 +00:00
2021-02-21 19:12:34 +00:00
def activate ( self , game , result ) :
2021-02-21 08:03:25 +00:00
if random . random ( ) < self . activation_chance :
teamtype = random . choice ( [ " away " , " home " ] )
team = game . teams [ teamtype ]
player = random . choice ( team . lineup )
old_player_name = player . name
if ' ' in player . name :
names = player . name . split ( " " )
first_first_letter = names [ 0 ] [ 0 ]
last_first_letter = names [ - 1 ] [ 0 ]
2021-02-21 19:12:34 +00:00
names [ 0 ] = last_first_letter + names [ 0 ] [ 1 : ]
names [ - 1 ] = first_first_letter + names [ - 1 ] [ 1 : ]
2021-02-21 08:03:25 +00:00
player . name = ' ' . join ( names )
else :
#name is one word, so turn 'bartholemew' into 'martholebew'
first_letter = player . name [ 0 ]
last_letter = player . name [ - 1 ]
2021-02-21 19:12:34 +00:00
player . name = last_letter + player . name [ 1 : - 1 ] + last_letter
book_adjectives = [ " action-packed " , " historical " , " friendly " , " rude " , " mystery " , " thriller " , " horror " , " sci-fi " , " fantasy " , " spooky " , " romantic " ]
book_types = [ " novel " , " novella " , " poem " , " anthology " , " fan fiction " , " tablet " , " carving " , " autobiography " ]
book = " {} {} " . format ( random . choice ( book_adjectives ) , random . choice ( book_types ) )
2021-02-21 08:03:25 +00:00
result . clear ( )
result . update ( {
2021-02-21 19:12:34 +00:00
" text " : " {} stopped to read a {} and became Literate! {} is now {} ! " . format ( old_player_name , book , old_player_name , player . name ) ,
2021-02-21 08:03:25 +00:00
" text_only " : True ,
2021-02-21 19:12:34 +00:00
" weather_message " : True
2021-02-21 08:03:25 +00:00
} )
2021-02-21 19:12:34 +00:00
2021-02-21 08:03:25 +00:00
class Feedback ( Weather ) :
2021-02-21 18:02:47 +00:00
def __init__ ( self , game ) :
2021-02-21 08:03:25 +00:00
self . name = " Feedback "
2021-02-21 19:12:34 +00:00
self . emoji = " 🎤 "
2021-02-21 19:56:27 +00:00
self . activation_chance = 0.02
2021-02-21 08:03:25 +00:00
self . swap_batter_vs_pitcher_chance = 0.8
2021-02-21 18:02:47 +00:00
2021-02-21 08:03:25 +00:00
def activate ( self , game , result ) :
if random . random ( ) < self . activation_chance :
# feedback time
player1 = None
player2 = None
2021-02-21 19:56:27 +00:00
team1 = game . teams [ " home " ]
team2 = game . teams [ " away " ]
2021-02-21 08:03:25 +00:00
if random . random ( ) < self . swap_batter_vs_pitcher_chance :
# swapping batters
# theoretically this could swap players already on base :(
2021-02-21 19:56:27 +00:00
team1 = game . teams [ " home " ]
team2 = game . teams [ " away " ]
homePlayerIndex = random . randint ( 0 , len ( team1 . lineup ) - 1 )
awayPlayerIndex = random . randint ( 0 , len ( team2 . lineup ) - 1 )
2021-02-21 08:03:25 +00:00
2021-02-21 19:56:27 +00:00
player1 = team1 . lineup [ homePlayerIndex ]
player2 = team2 . lineup [ awayPlayerIndex ]
2021-02-21 08:03:25 +00:00
2021-02-21 19:56:27 +00:00
team1 . lineup [ homePlayerIndex ] = player2
team2 . lineup [ awayPlayerIndex ] = player1
2021-02-21 08:03:25 +00:00
else :
# swapping pitchers
2021-02-21 19:56:27 +00:00
player1 = team1 . pitcher
player2 = team2 . pitcher
team1 . pitcher = player2
team2 . pitcher = player1
2021-02-21 08:03:25 +00:00
result . clear ( )
result . update ( {
" text " : " {} and {} switched teams in the feedback! " . format ( player1 . name , player2 . name ) ,
" text_only " : True ,
2021-02-21 19:12:34 +00:00
" weather_message " : True ,
2021-02-21 08:03:25 +00:00
} )
def all_weathers ( ) :
weathers_dic = {
#"Supernova" : Supernova,
#"Midnight": Midnight,
#"Slight Tailwind": SlightTailwind,
2021-02-21 23:15:23 +00:00
" Heavy Snow " : HeavySnow ,
" Twilight " : Twilight ,
" Thinned Veil " : ThinnedVeil ,
" Heat Wave " : HeatWave ,
" Drizzle " : Drizzle ,
2021-02-21 19:56:27 +00:00
# "Sun 2": Sun2,
2021-02-21 23:15:23 +00:00
" Feedback " : Feedback ,
" Literacy " : NameSwappyWeather ,
2021-02-21 08:03:25 +00:00
}
return weathers_dic