2020-03-18 16:15:32 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								from  __future__  import  annotations  
						 
					
						
							
								
									
										
										
										
											2022-04-07 10:42:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  abc  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  math  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  numbers  
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  typing  
						 
					
						
							
								
									
										
										
										
											2021-06-08 14:15:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  random  
						 
					
						
							
								
									
										
										
										
											2020-03-18 16:15:32 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-11 16:37:18 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								from  schema  import  Schema ,  And ,  Or ,  Optional  
						 
					
						
							
								
									
										
										
										
											2022-05-09 07:18:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								from  Utils  import  get_fuzzy_results  
						 
					
						
							
								
									
										
										
										
											2022-02-05 15:49:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-07 10:42:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  AssembleOptions ( abc . ABCMeta ) :  
						 
					
						
							
								
									
										
										
										
											2021-04-14 17:51:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  __new__ ( mcs ,  name ,  bases ,  attrs ) : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        options  =  attrs [ " options " ]  =  { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        name_lookup  =  attrs [ " name_lookup " ]  =  { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 19:03:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        # merge parent class options 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  base  in  bases : 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-30 16:31:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  getattr ( base ,  " options " ,  None ) : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 21:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                options . update ( base . options ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-09 09:15:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                name_lookup . update ( base . name_lookup ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        new_options  =  { name [ 7 : ] . lower ( ) :  option_id  for  name ,  option_id  in  attrs . items ( )  if 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-21 00:47:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                       name . startswith ( " option_ " ) } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 02:28:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-26 01:12:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        assert  " random "  not  in  new_options ,  " Choice option  ' random '  cannot be manually assigned. " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        assert  len ( new_options )  ==  len ( set ( new_options . values ( ) ) ) ,  " same ID cannot be used twice. Try alias? " 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 02:28:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        attrs [ " name_lookup " ] . update ( { option_id :  name  for  name ,  option_id  in  new_options . items ( ) } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        options . update ( new_options ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-21 00:47:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        # apply aliases, without name_lookup 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        options . update ( { name [ 6 : ] . lower ( ) :  option_id  for  name ,  option_id  in  attrs . items ( )  if 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        name . startswith ( " alias_ " ) } ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 01:02:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # auto-validate schema on __init__ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  " schema "  in  attrs . keys ( ) : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 15:49:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  " __init__ "  in  attrs : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                def  validate_decorator ( func ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    def  validate ( self ,  * args ,  * * kwargs ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        ret  =  func ( self ,  * args ,  * * kwargs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        self . value  =  self . schema . validate ( self . value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        return  ret 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  validate 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-01 03:42:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 15:49:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                attrs [ " __init__ " ]  =  validate_decorator ( attrs [ " __init__ " ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                # construct an __init__ that calls parent __init__ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                cls  =  super ( AssembleOptions ,  mcs ) . __new__ ( mcs ,  name ,  bases ,  attrs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                def  meta__init__ ( self ,  * args ,  * * kwargs ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    super ( cls ,  self ) . __init__ ( * args ,  * * kwargs ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-19 01:02:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    self . value  =  self . schema . validate ( self . value ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-30 19:49:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 15:49:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                cls . __init__  =  meta__init__ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  cls 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-30 19:49:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-14 17:51:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  super ( AssembleOptions ,  mcs ) . __new__ ( mcs ,  name ,  bases ,  attrs ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-01 03:42:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-27 16:47:47 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								T  =  typing . TypeVar ( ' T ' )  
						 
					
						
							
								
									
										
										
										
											2021-08-03 19:03:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-27 16:47:47 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  Option ( typing . Generic [ T ] ,  metaclass = AssembleOptions ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    value :  T 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-03 14:47:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    default  =  0 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 16:29:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    # convert option_name_long into Name Long as display_name, otherwise name_long is the result. 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 19:03:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    # Handled in get_option_name() 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 16:29:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto_display_name  =  False 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 19:03:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    # can be weighted between selections 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    supports_weighting  =  True 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-01 00:47:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    # filled by AssembleOptions: 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    name_lookup :  typing . Dict [ int ,  str ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    options :  typing . Dict [ str ,  int ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 19:03:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  __repr__ ( self )  - >  str : 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 19:09:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  f " { self . __class__ . __name__ } ( { self . get_current_option_name ( ) } ) " 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-07 10:42:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  __hash__ ( self )  - >  int : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  hash ( self . value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-09 09:15:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @property 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  current_key ( self )  - >  str : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  self . name_lookup [ self . value ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 19:09:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  get_current_option_name ( self )  - >  str : 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-09 09:15:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        """ For display purposes. """ 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 19:09:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  self . get_option_name ( self . value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-31 22:14:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @classmethod 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-01 00:47:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  get_option_name ( cls ,  value :  T )  - >  str : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 16:29:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  cls . auto_display_name : 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-31 22:14:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  cls . name_lookup [ value ] . replace ( " _ " ,  "   " ) . title ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 19:03:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-31 22:14:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  cls . name_lookup [ value ] 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-01 00:47:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  __int__ ( self )  - >  T : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 19:03:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  __bool__ ( self )  - >  bool : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  bool ( self . value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-14 08:38:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @classmethod 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-07 10:42:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  from_any ( cls ,  data :  typing . Any )  - >  Option [ T ] : 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-14 08:38:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        raise  NotImplementedError 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-07 10:42:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  NumericOption ( Option [ int ] ,  numbers . Integral ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # note: some of the `typing.Any`` here is a result of unresolved issue in python standards 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # `int` is not a `numbers.Integral` according to the official typestubs 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # (even though isinstance(5, numbers.Integral) == True) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # https://github.com/python/typing/issues/272 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # https://github.com/python/mypy/issues/3186 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # https://github.com/microsoft/pyright/issues/1575 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __eq__ ( self ,  other :  typing . Any )  - >  bool : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  isinstance ( other ,  NumericOption ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  self . value  ==  other . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  typing . cast ( bool ,  self . value  ==  other ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __lt__ ( self ,  other :  typing . Union [ int ,  NumericOption ] )  - >  bool : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  isinstance ( other ,  NumericOption ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  self . value  <  other . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  self . value  <  other 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __le__ ( self ,  other :  typing . Union [ int ,  NumericOption ] )  - >  bool : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  isinstance ( other ,  NumericOption ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  self . value  < =  other . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  self . value  < =  other 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __gt__ ( self ,  other :  typing . Union [ int ,  NumericOption ] )  - >  bool : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  isinstance ( other ,  NumericOption ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  self . value  >  other . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  self . value  >  other 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __bool__ ( self )  - >  bool : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  bool ( self . value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __int__ ( self )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __mul__ ( self ,  other :  typing . Any )  - >  typing . Any : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  isinstance ( other ,  NumericOption ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  self . value  *  other . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  self . value  *  other 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __rmul__ ( self ,  other :  typing . Any )  - >  typing . Any : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  isinstance ( other ,  NumericOption ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  other . value  *  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  other  *  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __sub__ ( self ,  other :  typing . Any )  - >  typing . Any : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  isinstance ( other ,  NumericOption ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  self . value  -  other . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  self . value  -  other 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __rsub__ ( self ,  left :  typing . Any )  - >  typing . Any : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  isinstance ( left ,  NumericOption ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  left . value  -  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  left  -  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __add__ ( self ,  other :  typing . Any )  - >  typing . Any : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  isinstance ( other ,  NumericOption ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  self . value  +  other . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  self . value  +  other 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __radd__ ( self ,  left :  typing . Any )  - >  typing . Any : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  isinstance ( left ,  NumericOption ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  left . value  +  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  left  +  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __truediv__ ( self ,  other :  typing . Any )  - >  typing . Any : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  isinstance ( other ,  NumericOption ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  self . value  /  other . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  self . value  /  other 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __rtruediv__ ( self ,  left :  typing . Any )  - >  typing . Any : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  isinstance ( left ,  NumericOption ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  left . value  /  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  left  /  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __abs__ ( self )  - >  typing . Any : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  abs ( self . value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __and__ ( self ,  other :  typing . Any )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  self . value  &  int ( other ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __ceil__ ( self )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  math . ceil ( self . value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __floor__ ( self )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  math . floor ( self . value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __floordiv__ ( self ,  other :  typing . Any )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  self . value  / /  int ( other ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __invert__ ( self )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ~ ( self . value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __lshift__ ( self ,  other :  typing . Any )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  self . value  <<  int ( other ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __mod__ ( self ,  other :  typing . Any )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  self . value  %  int ( other ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __neg__ ( self )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  - ( self . value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __or__ ( self ,  other :  typing . Any )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  self . value  |  int ( other ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __pos__ ( self )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  + ( self . value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __pow__ ( self ,  exponent :  numbers . Complex ,  modulus :  typing . Optional [ numbers . Integral ]  =  None )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  not  ( modulus  is  None ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            assert  isinstance ( exponent ,  numbers . Integral ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  pow ( self . value ,  exponent ,  modulus )   # type: ignore 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  self . value  * *  exponent   # type: ignore 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __rand__ ( self ,  other :  typing . Any )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  int ( other )  &  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __rfloordiv__ ( self ,  other :  typing . Any )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  int ( other )  / /  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __rlshift__ ( self ,  other :  typing . Any )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  int ( other )  <<  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __rmod__ ( self ,  other :  typing . Any )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  int ( other )  %  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __ror__ ( self ,  other :  typing . Any )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  int ( other )  |  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __round__ ( self ,  ndigits :  typing . Optional [ int ]  =  None )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  round ( self . value ,  ndigits ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __rpow__ ( self ,  base :  typing . Any )  - >  typing . Any : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  base  * *  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __rrshift__ ( self ,  other :  typing . Any )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  int ( other )  >>  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __rshift__ ( self ,  other :  typing . Any )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  self . value  >>  int ( other ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __rxor__ ( self ,  other :  typing . Any )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  int ( other )  ^  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __trunc__ ( self )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  math . trunc ( self . value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __xor__ ( self ,  other :  typing . Any )  - >  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  self . value  ^  int ( other ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  Toggle ( NumericOption ) :  
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    option_false  =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    option_true  =  1 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-03 14:47:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    default  =  0 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __init__ ( self ,  value :  int ) : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-26 01:12:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        assert  value  ==  0  or  value  ==  1 ,  " value of Toggle can only be 0 or 1 " 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        self . value  =  value 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 16:15:32 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @classmethod 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  from_text ( cls ,  text :  str )  - >  Toggle : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 22:09:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  text  ==  " random " : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  cls ( random . choice ( list ( cls . name_lookup ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        elif  text . lower ( )  in  { " off " ,  " 0 " ,  " false " ,  " none " ,  " null " ,  " no " } : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  cls ( 0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  cls ( 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-14 08:38:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @classmethod 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  from_any ( cls ,  data :  typing . Any ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  type ( data )  ==  str : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  cls . from_text ( data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  cls ( data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-31 22:52:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @classmethod 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  get_option_name ( cls ,  value ) : 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 19:09:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  [ " No " ,  " Yes " ] [ int ( value ) ] 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-06 06:18:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    __hash__  =  Option . __hash__   # see https://docs.python.org/3/reference/datamodel.html#object.__hash__ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 01:00:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  DefaultOnToggle ( Toggle ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    default  =  1 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-03 14:47:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 19:03:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-07 10:42:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  Choice ( NumericOption ) :  
						 
					
						
							
								
									
										
										
										
											2022-02-02 16:29:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto_display_name  =  True 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 19:03:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  __init__ ( self ,  value :  int ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . value :  int  =  value 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 16:15:32 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @classmethod 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  from_text ( cls ,  text :  str )  - >  Choice : 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-09 09:15:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        text  =  text . lower ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-30 13:22:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  text  ==  " random " : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  cls ( random . choice ( list ( cls . name_lookup ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 15:49:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  option_name ,  value  in  cls . options . items ( ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  option_name  ==  text : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  cls ( value ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 16:15:32 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        raise  KeyError ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            f ' Could not find option  " { text } "  for  " { cls . __name__ } " ,  ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            f ' known options are  { " ,  " . join ( f " { option } "  for  option  in  cls . name_lookup . values ( ) ) } ' ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 16:15:32 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-14 08:38:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @classmethod 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 17:46:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  from_any ( cls ,  data :  typing . Any )  - >  Choice : 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-08 19:53:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  type ( data )  ==  int  and  data  in  cls . options . values ( ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  cls ( data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  cls . from_text ( str ( data ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-14 08:38:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-30 16:31:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  __eq__ ( self ,  other ) : 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-04 17:53:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  isinstance ( other ,  self . __class__ ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  other . value  ==  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        elif  isinstance ( other ,  str ) : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 03:29:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            assert  other  in  self . options ,  f " compared against a str that could never be equal.  { self }  ==  { other } " 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-30 16:31:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  other  ==  self . current_key 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-30 23:07:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        elif  isinstance ( other ,  int ) : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 03:29:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            assert  other  in  self . name_lookup ,  f " compared against an int that could never be equal.  { self }  ==  { other } " 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-30 16:31:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  other  ==  self . value 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        elif  isinstance ( other ,  bool ) : 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-30 16:31:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  other  ==  bool ( self . value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            raise  TypeError ( f " Can ' t compare  { self . __class__ . __name__ }  with  { other . __class__ . __name__ } " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-30 23:07:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  __ne__ ( self ,  other ) : 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-04 17:53:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  isinstance ( other ,  self . __class__ ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  other . value  !=  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        elif  isinstance ( other ,  str ) : 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-01 03:42:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            assert  other  in  self . options ,  f " compared against a str that could never be equal.  { self }  !=  { other } " 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-30 23:07:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  other  !=  self . current_key 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        elif  isinstance ( other ,  int ) : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 03:29:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            assert  other  in  self . name_lookup ,  f " compared against am int that could never be equal.  { self }  !=  { other } " 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-30 23:07:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  other  !=  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        elif  isinstance ( other ,  bool ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  other  !=  bool ( self . value ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 19:42:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        elif  other  is  None : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  False 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-30 23:07:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            raise  TypeError ( f " Can ' t compare  { self . __class__ . __name__ }  with  { other . __class__ . __name__ } " ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 15:39:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-06 17:03:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    __hash__  =  Option . __hash__   # see https://docs.python.org/3/reference/datamodel.html#object.__hash__ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-07 10:42:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  Range ( NumericOption ) :  
						 
					
						
							
								
									
										
										
										
											2021-06-08 14:15:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    range_start  =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    range_end  =  1 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 15:39:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __init__ ( self ,  value :  int ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  value  <  self . range_start : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            raise  Exception ( f " { value }  is lower than minimum  { self . range_start }  for option  { self . __class__ . __name__ } " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        elif  value  >  self . range_end : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            raise  Exception ( f " { value }  is higher than maximum  { self . range_end }  for option  { self . __class__ . __name__ } " ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 21:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        self . value  =  value 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 14:15:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @classmethod 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  from_text ( cls ,  text :  str )  - >  Range : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 14:48:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        text  =  text . lower ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  text . startswith ( " random " ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  text  ==  " random-low " : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  cls ( int ( round ( random . triangular ( cls . range_start ,  cls . range_end ,  cls . range_start ) ,  0 ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            elif  text  ==  " random-high " : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  cls ( int ( round ( random . triangular ( cls . range_start ,  cls . range_end ,  cls . range_end ) ,  0 ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-12 21:05:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            elif  text  ==  " random-middle " : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  cls ( int ( round ( random . triangular ( cls . range_start ,  cls . range_end ) ,  0 ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-15 19:59:40 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            elif  text . startswith ( " random-range- " ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                textsplit  =  text . split ( " - " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                try : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 15:49:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    random_range  =  [ int ( textsplit [ len ( textsplit )  -  2 ] ) ,  int ( textsplit [ len ( textsplit )  -  1 ] ) ] 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-15 19:59:40 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                except  ValueError : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    raise  ValueError ( f " Invalid random range  { text }  for option  { cls . __name__ } " ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 15:49:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                random_range . sort ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  random_range [ 0 ]  <  cls . range_start  or  random_range [ 1 ]  >  cls . range_end : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    raise  Exception ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        f " { random_range [ 0 ] } - { random_range [ 1 ] }  is outside allowed range  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        f " { cls . range_start } - { cls . range_end }  for option  { cls . __name__ } " ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-15 19:59:40 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  text . startswith ( " random-range-low " ) : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 15:49:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    return  cls ( int ( round ( random . triangular ( random_range [ 0 ] ,  random_range [ 1 ] ,  random_range [ 0 ] ) ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-15 19:59:40 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                elif  text . startswith ( " random-range-middle " ) : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 15:49:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    return  cls ( int ( round ( random . triangular ( random_range [ 0 ] ,  random_range [ 1 ] ) ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-15 19:59:40 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                elif  text . startswith ( " random-range-high " ) : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 15:49:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    return  cls ( int ( round ( random . triangular ( random_range [ 0 ] ,  random_range [ 1 ] ,  random_range [ 1 ] ) ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-15 19:59:40 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                else : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 15:49:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    return  cls ( int ( round ( random . randint ( random_range [ 0 ] ,  random_range [ 1 ] ) ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-04 01:37:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            elif  text  ==  " random " : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 14:48:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  cls ( random . randint ( cls . range_start ,  cls . range_end ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-04 01:37:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                raise  Exception ( f " random text  \" { text } \"  did not resolve to a recognized pattern. Acceptable values are: random, random-high, random-middle, random-low, random-range-low-<min>-<max>, random-range-middle-<min>-<max>, random-range-high-<min>-<max>, or random-range-<min>-<max>. " ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-07 10:42:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        elif  text  ==  " default "  and  hasattr ( cls ,  " default " ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  cls ( cls . default ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-14 16:50:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        elif  text  ==  " high " : 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-07 10:42:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  cls ( cls . range_end ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-14 16:50:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        elif  text  ==  " low " : 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-07 10:42:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  cls ( cls . range_start ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-14 16:50:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        elif  cls . range_start  ==  0  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                and  hasattr ( cls ,  " default " )  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                and  cls . default  !=  0  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                and  text  in  ( " true " ,  " false " ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            # these are the conditions where "true" and "false" make sense 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  text  ==  " true " : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  cls ( cls . default ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else :   # "false" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  cls ( 0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 15:39:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  cls ( int ( text ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 14:15:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @classmethod 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  from_any ( cls ,  data :  typing . Any )  - >  Range : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  type ( data )  ==  int : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  cls ( data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  cls . from_text ( str ( data ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 16:15:32 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-07 10:42:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @classmethod 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  get_option_name ( cls ,  value :  int )  - >  str : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 19:42:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  str ( value ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 15:39:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-07 10:42:30 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  __str__ ( self )  - >  str : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 21:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  str ( self . value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 15:39:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-11 22:01:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  VerifyKeys :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    valid_keys  =  frozenset ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    valid_keys_casefold :  bool  =  False 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 20:49:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    convert_name_groups :  bool  =  False 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    verify_item_name :  bool  =  False 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    verify_location_name :  bool  =  False 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-06 16:37:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    value :  typing . Any 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-11 22:01:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @classmethod 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  verify_keys ( cls ,  data ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  cls . valid_keys : 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-15 21:20:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            data  =  set ( data ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-11 22:01:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            dataset  =  set ( word . casefold ( )  for  word  in  data )  if  cls . valid_keys_casefold  else  set ( data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            extra  =  dataset  -  cls . valid_keys 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  extra : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                raise  Exception ( f " Found unexpected key  { ' ,  ' . join ( extra ) }  in  { cls } .  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                f " Allowed keys:  { cls . valid_keys } . " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-06 16:37:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  verify ( self ,  world ) : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 20:49:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  self . convert_name_groups  and  self . verify_item_name : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            new_value  =  type ( self . value ) ( )   # empty container of whatever value is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  item_name  in  self . value : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                new_value  | =  world . item_name_groups . get ( item_name ,  { item_name } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            self . value  =  new_value 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-06 16:37:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  self . verify_item_name : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  item_name  in  self . value : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  item_name  not  in  world . item_names : 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-09 17:03:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    picks  =  get_fuzzy_results ( item_name ,  world . item_names ,  limit = 1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-06 16:37:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    raise  Exception ( f " Item  { item_name }  from option  { self }   " 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-26 02:28:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                    f " is not a valid item name from  { world . game } .  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                    f " Did you mean  ' { picks [ 0 ] [ 0 ] } '  ( { picks [ 0 ] [ 1 ] } % sure) " ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-06 16:37:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        elif  self . verify_location_name : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  location_name  in  self . value : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 20:49:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  location_name  not  in  world . location_names : 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-09 17:03:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    picks  =  get_fuzzy_results ( location_name ,  world . location_names ,  limit = 1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-06 16:37:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    raise  Exception ( f " Location  { location_name }  from option  { self }   " 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-26 02:28:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                    f " is not a valid location name from  { world . game } .  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                    f " Did you mean  ' { picks [ 0 ] [ 0 ] } '  ( { picks [ 0 ] [ 1 ] } % sure) " ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-06 16:37:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-11 22:01:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-27 16:47:47 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  OptionDict ( Option [ typing . Dict [ str ,  typing . Any ] ] ,  VerifyKeys ) :  
						 
					
						
							
								
									
										
										
										
											2021-05-09 17:46:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    default  =  { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    supports_weighting  =  False 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 17:46:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __init__ ( self ,  value :  typing . Dict [ str ,  typing . Any ] ) : 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-30 19:49:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        self . value  =  value 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 17:46:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @classmethod 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  from_any ( cls ,  data :  typing . Dict [ str ,  typing . Any ] )  - >  OptionDict : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  type ( data )  ==  dict : 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-15 21:20:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            cls . verify_keys ( data ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 17:46:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  cls ( data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            raise  NotImplementedError ( f " Cannot Convert from non-dictionary, got  { type ( data ) } " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 19:09:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  get_option_name ( self ,  value ) : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 19:42:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  " ,  " . join ( f " { key } :  { v } "  for  key ,  v  in  value . items ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 17:46:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-30 19:49:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  __contains__ ( self ,  item ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  item  in  self . value 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-08 15:39:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-30 19:49:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-25 04:13:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  ItemDict ( OptionDict ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    verify_item_name  =  True 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __init__ ( self ,  value :  typing . Dict [ str ,  int ] ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  any ( item_count  <  1  for  item_count  in  value . values ( ) ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            raise  Exception ( " Cannot have non-positive item counts. " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        super ( ItemDict ,  self ) . __init__ ( value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-27 16:47:47 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  OptionList ( Option [ typing . List [ typing . Any ] ] ,  VerifyKeys ) :  
						 
					
						
							
								
									
										
											 
										
											
												Ocarina of Time (#64)
* first commit (not including OoT data files yet)
* added some basic options
* rule parser works now at least
* make sure to commit everything this time
* temporary change to BaseClasses for oot
* overworld location graph builds mostly correctly
* adding oot data files
* commenting out world options until later since they only existed to make the RuleParser work
* conversion functions between AP ids and OOT ids
* world graph outputs
* set scrub prices
* itempool generates, entrances connected, way too many options added
* fixed set_rules and set_shop_rules
* temp baseclasses changes
* Reaches the fill step now, old event-based system retained in case the new way breaks
* Song placements and misc fixes everywhere
* temporary changes to make oot work
* changed root exits for AP fill framework
* prevent infinite recursion due to OoT sharing usage of the address field
* age reachability works hopefully, songs are broken again
* working spoiler log generation on beatable-only
* Logic tricks implemented
* need this for logic tricks
* fixed map/compass being placed on Serenade location
* kill unreachable events before filling the world
* add a bunch of utility functions to prepare for rom patching
* move OptionList into generic options
* fixed some silly bugs with OptionList
* properly seed all random behavior (so far)
* ROM generation working
* fix hints trying to get alttp dungeon hint texts
* continue fixing hints
* add oot to network data package
* change item and location IDs to 66000 and 67000 range respectively
* push removed items to precollected items
* fixed various issues with cross-contamination with multiple world generation
* reenable glitched logic (hopefully)
* glitched world files age-check fix
* cleaned up some get_locations calls
* added token shuffle and scrub shuffle, modified some options slightly to make the parsing work
* reenable MQ dungeons
* fix forest mq exception
* made targeting style an option for now, will be cosmetic later
* reminder to move targeting to cosmetics
* some oot option maintenance
* enabled starting time of day
* fixed issue breaking shop slots in multiworld generation
* added "off" option for text shuffle and hints
* shopsanity functionality restored
* change patch file extension
* remove unnecessary utility functions + imports
* update MIT license
* change option to "patch_uncompressed_rom" instead of "compress_rom"
* compliance with new AutoWorld systems
* Kill only internal events, remove non-internal big poe event in code
* re-add the big poe event and handle it correctly
* remove extra method in Range option
* fix typo
* Starting items, starting with consumables option
* do not remove nonexistent item
* move set_shop_rules to after shop items are placed
* some cleanup
* add retries for song placement
* flagged Skull Mask and Mask of Truth as advancement items
* update OoT to use LogicMixin
* Fixed trying to assign starting items from the wrong players
* fixed song retry step
* improved option handling, comments, and starting item replacements
* DefaultOnToggle writes Yes or No to spoiler
* enable compression of output if Compress executable is present
* clean up compression
* check whether (de)compressor exists before running the process
* allow specification of rom path in host.yaml
* check if decompressed file already exists before decompressing again
* fix triforce hunt generation
* rename all the oot state functions with prefix
* OoT: mark triforce pieces as completion goal for triforce hunt
* added overworld and any-dungeon shuffle for dungeon items
* Hide most unshuffled locations and events from the list of locations in spoiler
* build oot option ranges with a generic function instead of defining each separately
* move oot output-type control to host.yaml instead of individual yamls
* implement dungeon song shuffle
* minor improvements to overworld dungeon item shuffle
* remove random ice trap names in shops, mostly to avoid maintaining a massive censor list
* always output patch file to folder, remove option to generate ROM in preparation for removal
* re-add the fix for infinite recursion due to not being light or dark world
* change AP-sendable to Ocarina of Time model, since the triforce piece has some extra code apparently
* oot: remove item_names and location_names
* oot: minor fixes
* oot: comment out ROM patching
* oot: only add CollectionState objects on creation if actually needed
* main entrance shuffle method and entrances-based rules
* fix entrances based rules
* disable master quest and big poe count options for client compatibility
* use get_player_name instead of get_player_names
* fix OptionList
* fix oot options for new option system
* new coop section in oot rom: expand player names to 16 bytes, write AP_PLAYER_NAME at end of PLAYER_NAMES
* fill AP player name in oot rom with 0 instead of 0xDF
* encode player name with ASCII for fixed-width
* revert oot player name array to 8 bytes per name
* remove Pierre location if fast scarecrow is on
* check player name length
* "free_scarecrow" not "fast_scarecrow"
* OoT locations now properly store the AP ID instead of the oot internal ID
* oot __version__ updates in lockstep with AP version
* pull in unmodified oot cosmetic files
* also grab JSONDump since it's needed apparently
* gather extra needed methods, modify imports
* delete cosmetics log, replace all instances of SettingsList with OOTWorld
* cosmetic options working, except for sound effects (due to ear-safe issues)
* SFX, Music, and Fanfare randomization reenabled
* move OoT data files into the worlds folder
* move Compress and Decompress into oot data folder
* Replace get_all_state with custom method to avoid the cache
* OoT ROM: increment item counter before setting incoming item/player values to 0, preventing desync issues
* set data_version to 0
* make Kokiri Sword shuffle off by default
* reenable "Random Choice" for various cosmetic options
* kill Ruto's Letter turnin if open fountain
also fix for shopsanity
* place Buy Goron/Zora Tunic first in shop shuffle
* make ice traps appear as other items instead of breaking generation
* managed to break ice traps on non-major-only
* only handle ice traps if they are on
* fix shopsanity for non-oot games, and write player name instead of player number
* light arrows hint uses player name instead of player number
* Reenable "skip child zelda" option
* fix entrances_based_rules
* fix ganondorf hint if starting with light arrows
* fix dungeonitem shuffle and shopsanity interaction
* remove has_all_of, has_any_of, count_of in BaseClasses, replace usage with has_all, has_any, has_group
* force local giveable item on ZL if skip_child_zelda and shuffle_song_items is any
* keep bosses and bombchu bowling chus out of data package
* revert workaround for infinite recursion and fix it properly
* fix shared shop id caches during patching process
* fix shop text box overflows, as much as possible
* add default oot host.yaml option
* add .apz5, .n64, .z64 to gitignore
* Properly document and name all (functioning) OOT options
* clean up some imports
* remove unnecessary files from oot's data
* fix typo in gitignore
* readd the Compress and Decompress utilities, since they are needed for generation
* cleanup of imports and some minor optimizations
* increase shop offset for item IDs to 0xCB
* remove shop item AP ids entirely
* prevent triforce pieces for other players from being received by yourself
* add "excluded" property to Location
* Hint system adapted and reenabled; hints still unseeded
* make hints deterministic with lists instead of sets
* do not allow hints to point to Light Arrows on non-vanilla bridge
* foreign locations hint as their full name in OoT rather than their region
* checkedLocations now stores hint names by player ID, so that the same location in different worlds can have hints associated
* consolidate versioning in Utils
* ice traps appear as major items rather than any progression item
* set prescription and claim check as defaults for adult trade item settings
* add oot options to playerSettings
* allow case-insensitive logic tricks in yaml
* fix oot shopsanity option formatting
* Write OoT override info even if local item, enabling local checks to show up immediately in the client
* implement CollectionState.can_live_dmg for oot glitched logic
* filter item names for invalid characters when patching shops
* make ice traps appear according to the settings of the world they are shuffled into, rather than the original world
* set hidden-spoiler items and locations with Shop items to events
* make GF carpenters, Gerudo Card, Malon, ZL, and Impa events if the relevant settings are enabled, preventing them from appearing in the client on game start
* Fix oot Glitched and No Logic generation
* fix indenting
* Greatly reduce displayed cosmetic options
* Change oot data version to 1
* add apz5 distribution to webhost
* print player name if an ALttP dungeon contains a good item for OoT world
* delete unneeded commented code
* remove OcarinaSongs import to satisfy lint
											 
										 
										
											2021-09-02 08:35:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    default  =  [ ] 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    supports_weighting  =  False 
							 
						 
					
						
							
								
									
										
											 
										
											
												Ocarina of Time (#64)
* first commit (not including OoT data files yet)
* added some basic options
* rule parser works now at least
* make sure to commit everything this time
* temporary change to BaseClasses for oot
* overworld location graph builds mostly correctly
* adding oot data files
* commenting out world options until later since they only existed to make the RuleParser work
* conversion functions between AP ids and OOT ids
* world graph outputs
* set scrub prices
* itempool generates, entrances connected, way too many options added
* fixed set_rules and set_shop_rules
* temp baseclasses changes
* Reaches the fill step now, old event-based system retained in case the new way breaks
* Song placements and misc fixes everywhere
* temporary changes to make oot work
* changed root exits for AP fill framework
* prevent infinite recursion due to OoT sharing usage of the address field
* age reachability works hopefully, songs are broken again
* working spoiler log generation on beatable-only
* Logic tricks implemented
* need this for logic tricks
* fixed map/compass being placed on Serenade location
* kill unreachable events before filling the world
* add a bunch of utility functions to prepare for rom patching
* move OptionList into generic options
* fixed some silly bugs with OptionList
* properly seed all random behavior (so far)
* ROM generation working
* fix hints trying to get alttp dungeon hint texts
* continue fixing hints
* add oot to network data package
* change item and location IDs to 66000 and 67000 range respectively
* push removed items to precollected items
* fixed various issues with cross-contamination with multiple world generation
* reenable glitched logic (hopefully)
* glitched world files age-check fix
* cleaned up some get_locations calls
* added token shuffle and scrub shuffle, modified some options slightly to make the parsing work
* reenable MQ dungeons
* fix forest mq exception
* made targeting style an option for now, will be cosmetic later
* reminder to move targeting to cosmetics
* some oot option maintenance
* enabled starting time of day
* fixed issue breaking shop slots in multiworld generation
* added "off" option for text shuffle and hints
* shopsanity functionality restored
* change patch file extension
* remove unnecessary utility functions + imports
* update MIT license
* change option to "patch_uncompressed_rom" instead of "compress_rom"
* compliance with new AutoWorld systems
* Kill only internal events, remove non-internal big poe event in code
* re-add the big poe event and handle it correctly
* remove extra method in Range option
* fix typo
* Starting items, starting with consumables option
* do not remove nonexistent item
* move set_shop_rules to after shop items are placed
* some cleanup
* add retries for song placement
* flagged Skull Mask and Mask of Truth as advancement items
* update OoT to use LogicMixin
* Fixed trying to assign starting items from the wrong players
* fixed song retry step
* improved option handling, comments, and starting item replacements
* DefaultOnToggle writes Yes or No to spoiler
* enable compression of output if Compress executable is present
* clean up compression
* check whether (de)compressor exists before running the process
* allow specification of rom path in host.yaml
* check if decompressed file already exists before decompressing again
* fix triforce hunt generation
* rename all the oot state functions with prefix
* OoT: mark triforce pieces as completion goal for triforce hunt
* added overworld and any-dungeon shuffle for dungeon items
* Hide most unshuffled locations and events from the list of locations in spoiler
* build oot option ranges with a generic function instead of defining each separately
* move oot output-type control to host.yaml instead of individual yamls
* implement dungeon song shuffle
* minor improvements to overworld dungeon item shuffle
* remove random ice trap names in shops, mostly to avoid maintaining a massive censor list
* always output patch file to folder, remove option to generate ROM in preparation for removal
* re-add the fix for infinite recursion due to not being light or dark world
* change AP-sendable to Ocarina of Time model, since the triforce piece has some extra code apparently
* oot: remove item_names and location_names
* oot: minor fixes
* oot: comment out ROM patching
* oot: only add CollectionState objects on creation if actually needed
* main entrance shuffle method and entrances-based rules
* fix entrances based rules
* disable master quest and big poe count options for client compatibility
* use get_player_name instead of get_player_names
* fix OptionList
* fix oot options for new option system
* new coop section in oot rom: expand player names to 16 bytes, write AP_PLAYER_NAME at end of PLAYER_NAMES
* fill AP player name in oot rom with 0 instead of 0xDF
* encode player name with ASCII for fixed-width
* revert oot player name array to 8 bytes per name
* remove Pierre location if fast scarecrow is on
* check player name length
* "free_scarecrow" not "fast_scarecrow"
* OoT locations now properly store the AP ID instead of the oot internal ID
* oot __version__ updates in lockstep with AP version
* pull in unmodified oot cosmetic files
* also grab JSONDump since it's needed apparently
* gather extra needed methods, modify imports
* delete cosmetics log, replace all instances of SettingsList with OOTWorld
* cosmetic options working, except for sound effects (due to ear-safe issues)
* SFX, Music, and Fanfare randomization reenabled
* move OoT data files into the worlds folder
* move Compress and Decompress into oot data folder
* Replace get_all_state with custom method to avoid the cache
* OoT ROM: increment item counter before setting incoming item/player values to 0, preventing desync issues
* set data_version to 0
* make Kokiri Sword shuffle off by default
* reenable "Random Choice" for various cosmetic options
* kill Ruto's Letter turnin if open fountain
also fix for shopsanity
* place Buy Goron/Zora Tunic first in shop shuffle
* make ice traps appear as other items instead of breaking generation
* managed to break ice traps on non-major-only
* only handle ice traps if they are on
* fix shopsanity for non-oot games, and write player name instead of player number
* light arrows hint uses player name instead of player number
* Reenable "skip child zelda" option
* fix entrances_based_rules
* fix ganondorf hint if starting with light arrows
* fix dungeonitem shuffle and shopsanity interaction
* remove has_all_of, has_any_of, count_of in BaseClasses, replace usage with has_all, has_any, has_group
* force local giveable item on ZL if skip_child_zelda and shuffle_song_items is any
* keep bosses and bombchu bowling chus out of data package
* revert workaround for infinite recursion and fix it properly
* fix shared shop id caches during patching process
* fix shop text box overflows, as much as possible
* add default oot host.yaml option
* add .apz5, .n64, .z64 to gitignore
* Properly document and name all (functioning) OOT options
* clean up some imports
* remove unnecessary files from oot's data
* fix typo in gitignore
* readd the Compress and Decompress utilities, since they are needed for generation
* cleanup of imports and some minor optimizations
* increase shop offset for item IDs to 0xCB
* remove shop item AP ids entirely
* prevent triforce pieces for other players from being received by yourself
* add "excluded" property to Location
* Hint system adapted and reenabled; hints still unseeded
* make hints deterministic with lists instead of sets
* do not allow hints to point to Light Arrows on non-vanilla bridge
* foreign locations hint as their full name in OoT rather than their region
* checkedLocations now stores hint names by player ID, so that the same location in different worlds can have hints associated
* consolidate versioning in Utils
* ice traps appear as major items rather than any progression item
* set prescription and claim check as defaults for adult trade item settings
* add oot options to playerSettings
* allow case-insensitive logic tricks in yaml
* fix oot shopsanity option formatting
* Write OoT override info even if local item, enabling local checks to show up immediately in the client
* implement CollectionState.can_live_dmg for oot glitched logic
* filter item names for invalid characters when patching shops
* make ice traps appear according to the settings of the world they are shuffled into, rather than the original world
* set hidden-spoiler items and locations with Shop items to events
* make GF carpenters, Gerudo Card, Malon, ZL, and Impa events if the relevant settings are enabled, preventing them from appearing in the client on game start
* Fix oot Glitched and No Logic generation
* fix indenting
* Greatly reduce displayed cosmetic options
* Change oot data version to 1
* add apz5 distribution to webhost
* print player name if an ALttP dungeon contains a good item for OoT world
* delete unneeded commented code
* remove OcarinaSongs import to satisfy lint
											 
										 
										
											2021-09-02 08:35:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												MC: 1.17 support (#120)
* MC: add death_link option
* Minecraft: 1.17 advancements and logic support
* Update Minecraft tracker to 1.17
* Minecraft: add tests for new advancements
* removed jdk/forge download install out of iss and into MinecraftClient.py using flag --install
* Add required_bosses option
choices are none, ender_dragon, wither, both
postgame advancements are set according to the required boss for completion
* fix docstring for PostgameAdvancements
* Minecraft: add starting_items
List of dicts: item, amount, nbt
* Update descriptions for AdvancementGoal and EggShardsRequired
* Minecraft: fix tests for required_bosses attribute
* Minecraft: updated logic for various dragon-related advancements
Split the logic into can_respawn and can_kill dragon
Free the End, Monsters Hunted, The End Again still require both respawn and kill, since the player needs to kill and be credited with the kill
You Need a Mint and Is It a Plane now require only respawn, since the dragon need only be alive; if killed out of logic, it's ok
The Next Generation only requires kill, since the egg spawns regardless of whether the player was credited with the kill or not
* Minecraft client: ignore prereleases unless --prerelease flag is on
* explicitly state all defaults
change structure shuffle and structure compass defaults to true
update install tutorial to point to player-settings page, as well as removing instructions for manual install
* Minecraft client: add Minecraft version check
Adds a minecraft_version field in the apmc, and downloads only mods which contain that version in the name of the .jar file.
This ensures that the client remains compatible even if new mods are released for later versions, since they won't download a mod for a later version than the apmc says.
Co-authored-by: Kono Tyran <Kono.Tyran@gmail.com>
											 
										 
										
											2021-11-30 20:37:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  __init__ ( self ,  value :  typing . List [ typing . Any ] ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . value  =  value  or  [ ] 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        super ( OptionList ,  self ) . __init__ ( ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												Ocarina of Time (#64)
* first commit (not including OoT data files yet)
* added some basic options
* rule parser works now at least
* make sure to commit everything this time
* temporary change to BaseClasses for oot
* overworld location graph builds mostly correctly
* adding oot data files
* commenting out world options until later since they only existed to make the RuleParser work
* conversion functions between AP ids and OOT ids
* world graph outputs
* set scrub prices
* itempool generates, entrances connected, way too many options added
* fixed set_rules and set_shop_rules
* temp baseclasses changes
* Reaches the fill step now, old event-based system retained in case the new way breaks
* Song placements and misc fixes everywhere
* temporary changes to make oot work
* changed root exits for AP fill framework
* prevent infinite recursion due to OoT sharing usage of the address field
* age reachability works hopefully, songs are broken again
* working spoiler log generation on beatable-only
* Logic tricks implemented
* need this for logic tricks
* fixed map/compass being placed on Serenade location
* kill unreachable events before filling the world
* add a bunch of utility functions to prepare for rom patching
* move OptionList into generic options
* fixed some silly bugs with OptionList
* properly seed all random behavior (so far)
* ROM generation working
* fix hints trying to get alttp dungeon hint texts
* continue fixing hints
* add oot to network data package
* change item and location IDs to 66000 and 67000 range respectively
* push removed items to precollected items
* fixed various issues with cross-contamination with multiple world generation
* reenable glitched logic (hopefully)
* glitched world files age-check fix
* cleaned up some get_locations calls
* added token shuffle and scrub shuffle, modified some options slightly to make the parsing work
* reenable MQ dungeons
* fix forest mq exception
* made targeting style an option for now, will be cosmetic later
* reminder to move targeting to cosmetics
* some oot option maintenance
* enabled starting time of day
* fixed issue breaking shop slots in multiworld generation
* added "off" option for text shuffle and hints
* shopsanity functionality restored
* change patch file extension
* remove unnecessary utility functions + imports
* update MIT license
* change option to "patch_uncompressed_rom" instead of "compress_rom"
* compliance with new AutoWorld systems
* Kill only internal events, remove non-internal big poe event in code
* re-add the big poe event and handle it correctly
* remove extra method in Range option
* fix typo
* Starting items, starting with consumables option
* do not remove nonexistent item
* move set_shop_rules to after shop items are placed
* some cleanup
* add retries for song placement
* flagged Skull Mask and Mask of Truth as advancement items
* update OoT to use LogicMixin
* Fixed trying to assign starting items from the wrong players
* fixed song retry step
* improved option handling, comments, and starting item replacements
* DefaultOnToggle writes Yes or No to spoiler
* enable compression of output if Compress executable is present
* clean up compression
* check whether (de)compressor exists before running the process
* allow specification of rom path in host.yaml
* check if decompressed file already exists before decompressing again
* fix triforce hunt generation
* rename all the oot state functions with prefix
* OoT: mark triforce pieces as completion goal for triforce hunt
* added overworld and any-dungeon shuffle for dungeon items
* Hide most unshuffled locations and events from the list of locations in spoiler
* build oot option ranges with a generic function instead of defining each separately
* move oot output-type control to host.yaml instead of individual yamls
* implement dungeon song shuffle
* minor improvements to overworld dungeon item shuffle
* remove random ice trap names in shops, mostly to avoid maintaining a massive censor list
* always output patch file to folder, remove option to generate ROM in preparation for removal
* re-add the fix for infinite recursion due to not being light or dark world
* change AP-sendable to Ocarina of Time model, since the triforce piece has some extra code apparently
* oot: remove item_names and location_names
* oot: minor fixes
* oot: comment out ROM patching
* oot: only add CollectionState objects on creation if actually needed
* main entrance shuffle method and entrances-based rules
* fix entrances based rules
* disable master quest and big poe count options for client compatibility
* use get_player_name instead of get_player_names
* fix OptionList
* fix oot options for new option system
* new coop section in oot rom: expand player names to 16 bytes, write AP_PLAYER_NAME at end of PLAYER_NAMES
* fill AP player name in oot rom with 0 instead of 0xDF
* encode player name with ASCII for fixed-width
* revert oot player name array to 8 bytes per name
* remove Pierre location if fast scarecrow is on
* check player name length
* "free_scarecrow" not "fast_scarecrow"
* OoT locations now properly store the AP ID instead of the oot internal ID
* oot __version__ updates in lockstep with AP version
* pull in unmodified oot cosmetic files
* also grab JSONDump since it's needed apparently
* gather extra needed methods, modify imports
* delete cosmetics log, replace all instances of SettingsList with OOTWorld
* cosmetic options working, except for sound effects (due to ear-safe issues)
* SFX, Music, and Fanfare randomization reenabled
* move OoT data files into the worlds folder
* move Compress and Decompress into oot data folder
* Replace get_all_state with custom method to avoid the cache
* OoT ROM: increment item counter before setting incoming item/player values to 0, preventing desync issues
* set data_version to 0
* make Kokiri Sword shuffle off by default
* reenable "Random Choice" for various cosmetic options
* kill Ruto's Letter turnin if open fountain
also fix for shopsanity
* place Buy Goron/Zora Tunic first in shop shuffle
* make ice traps appear as other items instead of breaking generation
* managed to break ice traps on non-major-only
* only handle ice traps if they are on
* fix shopsanity for non-oot games, and write player name instead of player number
* light arrows hint uses player name instead of player number
* Reenable "skip child zelda" option
* fix entrances_based_rules
* fix ganondorf hint if starting with light arrows
* fix dungeonitem shuffle and shopsanity interaction
* remove has_all_of, has_any_of, count_of in BaseClasses, replace usage with has_all, has_any, has_group
* force local giveable item on ZL if skip_child_zelda and shuffle_song_items is any
* keep bosses and bombchu bowling chus out of data package
* revert workaround for infinite recursion and fix it properly
* fix shared shop id caches during patching process
* fix shop text box overflows, as much as possible
* add default oot host.yaml option
* add .apz5, .n64, .z64 to gitignore
* Properly document and name all (functioning) OOT options
* clean up some imports
* remove unnecessary files from oot's data
* fix typo in gitignore
* readd the Compress and Decompress utilities, since they are needed for generation
* cleanup of imports and some minor optimizations
* increase shop offset for item IDs to 0xCB
* remove shop item AP ids entirely
* prevent triforce pieces for other players from being received by yourself
* add "excluded" property to Location
* Hint system adapted and reenabled; hints still unseeded
* make hints deterministic with lists instead of sets
* do not allow hints to point to Light Arrows on non-vanilla bridge
* foreign locations hint as their full name in OoT rather than their region
* checkedLocations now stores hint names by player ID, so that the same location in different worlds can have hints associated
* consolidate versioning in Utils
* ice traps appear as major items rather than any progression item
* set prescription and claim check as defaults for adult trade item settings
* add oot options to playerSettings
* allow case-insensitive logic tricks in yaml
* fix oot shopsanity option formatting
* Write OoT override info even if local item, enabling local checks to show up immediately in the client
* implement CollectionState.can_live_dmg for oot glitched logic
* filter item names for invalid characters when patching shops
* make ice traps appear according to the settings of the world they are shuffled into, rather than the original world
* set hidden-spoiler items and locations with Shop items to events
* make GF carpenters, Gerudo Card, Malon, ZL, and Impa events if the relevant settings are enabled, preventing them from appearing in the client on game start
* Fix oot Glitched and No Logic generation
* fix indenting
* Greatly reduce displayed cosmetic options
* Change oot data version to 1
* add apz5 distribution to webhost
* print player name if an ALttP dungeon contains a good item for OoT world
* delete unneeded commented code
* remove OcarinaSongs import to satisfy lint
											 
										 
										
											2021-09-02 08:35:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @classmethod 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  from_text ( cls ,  text :  str ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  cls ( [ option . strip ( )  for  option  in  text . split ( " , " ) ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @classmethod 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  from_any ( cls ,  data :  typing . Any ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  type ( data )  ==  list : 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-15 21:20:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            cls . verify_keys ( data ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												Ocarina of Time (#64)
* first commit (not including OoT data files yet)
* added some basic options
* rule parser works now at least
* make sure to commit everything this time
* temporary change to BaseClasses for oot
* overworld location graph builds mostly correctly
* adding oot data files
* commenting out world options until later since they only existed to make the RuleParser work
* conversion functions between AP ids and OOT ids
* world graph outputs
* set scrub prices
* itempool generates, entrances connected, way too many options added
* fixed set_rules and set_shop_rules
* temp baseclasses changes
* Reaches the fill step now, old event-based system retained in case the new way breaks
* Song placements and misc fixes everywhere
* temporary changes to make oot work
* changed root exits for AP fill framework
* prevent infinite recursion due to OoT sharing usage of the address field
* age reachability works hopefully, songs are broken again
* working spoiler log generation on beatable-only
* Logic tricks implemented
* need this for logic tricks
* fixed map/compass being placed on Serenade location
* kill unreachable events before filling the world
* add a bunch of utility functions to prepare for rom patching
* move OptionList into generic options
* fixed some silly bugs with OptionList
* properly seed all random behavior (so far)
* ROM generation working
* fix hints trying to get alttp dungeon hint texts
* continue fixing hints
* add oot to network data package
* change item and location IDs to 66000 and 67000 range respectively
* push removed items to precollected items
* fixed various issues with cross-contamination with multiple world generation
* reenable glitched logic (hopefully)
* glitched world files age-check fix
* cleaned up some get_locations calls
* added token shuffle and scrub shuffle, modified some options slightly to make the parsing work
* reenable MQ dungeons
* fix forest mq exception
* made targeting style an option for now, will be cosmetic later
* reminder to move targeting to cosmetics
* some oot option maintenance
* enabled starting time of day
* fixed issue breaking shop slots in multiworld generation
* added "off" option for text shuffle and hints
* shopsanity functionality restored
* change patch file extension
* remove unnecessary utility functions + imports
* update MIT license
* change option to "patch_uncompressed_rom" instead of "compress_rom"
* compliance with new AutoWorld systems
* Kill only internal events, remove non-internal big poe event in code
* re-add the big poe event and handle it correctly
* remove extra method in Range option
* fix typo
* Starting items, starting with consumables option
* do not remove nonexistent item
* move set_shop_rules to after shop items are placed
* some cleanup
* add retries for song placement
* flagged Skull Mask and Mask of Truth as advancement items
* update OoT to use LogicMixin
* Fixed trying to assign starting items from the wrong players
* fixed song retry step
* improved option handling, comments, and starting item replacements
* DefaultOnToggle writes Yes or No to spoiler
* enable compression of output if Compress executable is present
* clean up compression
* check whether (de)compressor exists before running the process
* allow specification of rom path in host.yaml
* check if decompressed file already exists before decompressing again
* fix triforce hunt generation
* rename all the oot state functions with prefix
* OoT: mark triforce pieces as completion goal for triforce hunt
* added overworld and any-dungeon shuffle for dungeon items
* Hide most unshuffled locations and events from the list of locations in spoiler
* build oot option ranges with a generic function instead of defining each separately
* move oot output-type control to host.yaml instead of individual yamls
* implement dungeon song shuffle
* minor improvements to overworld dungeon item shuffle
* remove random ice trap names in shops, mostly to avoid maintaining a massive censor list
* always output patch file to folder, remove option to generate ROM in preparation for removal
* re-add the fix for infinite recursion due to not being light or dark world
* change AP-sendable to Ocarina of Time model, since the triforce piece has some extra code apparently
* oot: remove item_names and location_names
* oot: minor fixes
* oot: comment out ROM patching
* oot: only add CollectionState objects on creation if actually needed
* main entrance shuffle method and entrances-based rules
* fix entrances based rules
* disable master quest and big poe count options for client compatibility
* use get_player_name instead of get_player_names
* fix OptionList
* fix oot options for new option system
* new coop section in oot rom: expand player names to 16 bytes, write AP_PLAYER_NAME at end of PLAYER_NAMES
* fill AP player name in oot rom with 0 instead of 0xDF
* encode player name with ASCII for fixed-width
* revert oot player name array to 8 bytes per name
* remove Pierre location if fast scarecrow is on
* check player name length
* "free_scarecrow" not "fast_scarecrow"
* OoT locations now properly store the AP ID instead of the oot internal ID
* oot __version__ updates in lockstep with AP version
* pull in unmodified oot cosmetic files
* also grab JSONDump since it's needed apparently
* gather extra needed methods, modify imports
* delete cosmetics log, replace all instances of SettingsList with OOTWorld
* cosmetic options working, except for sound effects (due to ear-safe issues)
* SFX, Music, and Fanfare randomization reenabled
* move OoT data files into the worlds folder
* move Compress and Decompress into oot data folder
* Replace get_all_state with custom method to avoid the cache
* OoT ROM: increment item counter before setting incoming item/player values to 0, preventing desync issues
* set data_version to 0
* make Kokiri Sword shuffle off by default
* reenable "Random Choice" for various cosmetic options
* kill Ruto's Letter turnin if open fountain
also fix for shopsanity
* place Buy Goron/Zora Tunic first in shop shuffle
* make ice traps appear as other items instead of breaking generation
* managed to break ice traps on non-major-only
* only handle ice traps if they are on
* fix shopsanity for non-oot games, and write player name instead of player number
* light arrows hint uses player name instead of player number
* Reenable "skip child zelda" option
* fix entrances_based_rules
* fix ganondorf hint if starting with light arrows
* fix dungeonitem shuffle and shopsanity interaction
* remove has_all_of, has_any_of, count_of in BaseClasses, replace usage with has_all, has_any, has_group
* force local giveable item on ZL if skip_child_zelda and shuffle_song_items is any
* keep bosses and bombchu bowling chus out of data package
* revert workaround for infinite recursion and fix it properly
* fix shared shop id caches during patching process
* fix shop text box overflows, as much as possible
* add default oot host.yaml option
* add .apz5, .n64, .z64 to gitignore
* Properly document and name all (functioning) OOT options
* clean up some imports
* remove unnecessary files from oot's data
* fix typo in gitignore
* readd the Compress and Decompress utilities, since they are needed for generation
* cleanup of imports and some minor optimizations
* increase shop offset for item IDs to 0xCB
* remove shop item AP ids entirely
* prevent triforce pieces for other players from being received by yourself
* add "excluded" property to Location
* Hint system adapted and reenabled; hints still unseeded
* make hints deterministic with lists instead of sets
* do not allow hints to point to Light Arrows on non-vanilla bridge
* foreign locations hint as their full name in OoT rather than their region
* checkedLocations now stores hint names by player ID, so that the same location in different worlds can have hints associated
* consolidate versioning in Utils
* ice traps appear as major items rather than any progression item
* set prescription and claim check as defaults for adult trade item settings
* add oot options to playerSettings
* allow case-insensitive logic tricks in yaml
* fix oot shopsanity option formatting
* Write OoT override info even if local item, enabling local checks to show up immediately in the client
* implement CollectionState.can_live_dmg for oot glitched logic
* filter item names for invalid characters when patching shops
* make ice traps appear according to the settings of the world they are shuffled into, rather than the original world
* set hidden-spoiler items and locations with Shop items to events
* make GF carpenters, Gerudo Card, Malon, ZL, and Impa events if the relevant settings are enabled, preventing them from appearing in the client on game start
* Fix oot Glitched and No Logic generation
* fix indenting
* Greatly reduce displayed cosmetic options
* Change oot data version to 1
* add apz5 distribution to webhost
* print player name if an ALttP dungeon contains a good item for OoT world
* delete unneeded commented code
* remove OcarinaSongs import to satisfy lint
											 
										 
										
											2021-09-02 08:35:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  cls ( data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  cls . from_text ( str ( data ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  get_option_name ( self ,  value ) : 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 21:53:52 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  " ,  " . join ( map ( str ,  value ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-30 19:49:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  __contains__ ( self ,  item ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  item  in  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-27 16:47:47 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  OptionSet ( Option [ typing . Set [ str ] ] ,  VerifyKeys ) :  
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    default  =  frozenset ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    supports_weighting  =  False 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  __init__ ( self ,  value :  typing . Union [ typing . Set [ str ,  typing . Any ] ,  typing . List [ str ,  typing . Any ] ] ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        self . value  =  set ( value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        super ( OptionSet ,  self ) . __init__ ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @classmethod 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  from_text ( cls ,  text :  str ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  cls ( [ option . strip ( )  for  option  in  text . split ( " , " ) ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @classmethod 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  from_any ( cls ,  data :  typing . Any ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  type ( data )  ==  list : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-06 16:37:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            cls . verify_keys ( data ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  cls ( data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        elif  type ( data )  ==  set : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-06 16:37:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            cls . verify_keys ( data ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  cls ( data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  cls . from_text ( str ( data ) ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												Ocarina of Time (#64)
* first commit (not including OoT data files yet)
* added some basic options
* rule parser works now at least
* make sure to commit everything this time
* temporary change to BaseClasses for oot
* overworld location graph builds mostly correctly
* adding oot data files
* commenting out world options until later since they only existed to make the RuleParser work
* conversion functions between AP ids and OOT ids
* world graph outputs
* set scrub prices
* itempool generates, entrances connected, way too many options added
* fixed set_rules and set_shop_rules
* temp baseclasses changes
* Reaches the fill step now, old event-based system retained in case the new way breaks
* Song placements and misc fixes everywhere
* temporary changes to make oot work
* changed root exits for AP fill framework
* prevent infinite recursion due to OoT sharing usage of the address field
* age reachability works hopefully, songs are broken again
* working spoiler log generation on beatable-only
* Logic tricks implemented
* need this for logic tricks
* fixed map/compass being placed on Serenade location
* kill unreachable events before filling the world
* add a bunch of utility functions to prepare for rom patching
* move OptionList into generic options
* fixed some silly bugs with OptionList
* properly seed all random behavior (so far)
* ROM generation working
* fix hints trying to get alttp dungeon hint texts
* continue fixing hints
* add oot to network data package
* change item and location IDs to 66000 and 67000 range respectively
* push removed items to precollected items
* fixed various issues with cross-contamination with multiple world generation
* reenable glitched logic (hopefully)
* glitched world files age-check fix
* cleaned up some get_locations calls
* added token shuffle and scrub shuffle, modified some options slightly to make the parsing work
* reenable MQ dungeons
* fix forest mq exception
* made targeting style an option for now, will be cosmetic later
* reminder to move targeting to cosmetics
* some oot option maintenance
* enabled starting time of day
* fixed issue breaking shop slots in multiworld generation
* added "off" option for text shuffle and hints
* shopsanity functionality restored
* change patch file extension
* remove unnecessary utility functions + imports
* update MIT license
* change option to "patch_uncompressed_rom" instead of "compress_rom"
* compliance with new AutoWorld systems
* Kill only internal events, remove non-internal big poe event in code
* re-add the big poe event and handle it correctly
* remove extra method in Range option
* fix typo
* Starting items, starting with consumables option
* do not remove nonexistent item
* move set_shop_rules to after shop items are placed
* some cleanup
* add retries for song placement
* flagged Skull Mask and Mask of Truth as advancement items
* update OoT to use LogicMixin
* Fixed trying to assign starting items from the wrong players
* fixed song retry step
* improved option handling, comments, and starting item replacements
* DefaultOnToggle writes Yes or No to spoiler
* enable compression of output if Compress executable is present
* clean up compression
* check whether (de)compressor exists before running the process
* allow specification of rom path in host.yaml
* check if decompressed file already exists before decompressing again
* fix triforce hunt generation
* rename all the oot state functions with prefix
* OoT: mark triforce pieces as completion goal for triforce hunt
* added overworld and any-dungeon shuffle for dungeon items
* Hide most unshuffled locations and events from the list of locations in spoiler
* build oot option ranges with a generic function instead of defining each separately
* move oot output-type control to host.yaml instead of individual yamls
* implement dungeon song shuffle
* minor improvements to overworld dungeon item shuffle
* remove random ice trap names in shops, mostly to avoid maintaining a massive censor list
* always output patch file to folder, remove option to generate ROM in preparation for removal
* re-add the fix for infinite recursion due to not being light or dark world
* change AP-sendable to Ocarina of Time model, since the triforce piece has some extra code apparently
* oot: remove item_names and location_names
* oot: minor fixes
* oot: comment out ROM patching
* oot: only add CollectionState objects on creation if actually needed
* main entrance shuffle method and entrances-based rules
* fix entrances based rules
* disable master quest and big poe count options for client compatibility
* use get_player_name instead of get_player_names
* fix OptionList
* fix oot options for new option system
* new coop section in oot rom: expand player names to 16 bytes, write AP_PLAYER_NAME at end of PLAYER_NAMES
* fill AP player name in oot rom with 0 instead of 0xDF
* encode player name with ASCII for fixed-width
* revert oot player name array to 8 bytes per name
* remove Pierre location if fast scarecrow is on
* check player name length
* "free_scarecrow" not "fast_scarecrow"
* OoT locations now properly store the AP ID instead of the oot internal ID
* oot __version__ updates in lockstep with AP version
* pull in unmodified oot cosmetic files
* also grab JSONDump since it's needed apparently
* gather extra needed methods, modify imports
* delete cosmetics log, replace all instances of SettingsList with OOTWorld
* cosmetic options working, except for sound effects (due to ear-safe issues)
* SFX, Music, and Fanfare randomization reenabled
* move OoT data files into the worlds folder
* move Compress and Decompress into oot data folder
* Replace get_all_state with custom method to avoid the cache
* OoT ROM: increment item counter before setting incoming item/player values to 0, preventing desync issues
* set data_version to 0
* make Kokiri Sword shuffle off by default
* reenable "Random Choice" for various cosmetic options
* kill Ruto's Letter turnin if open fountain
also fix for shopsanity
* place Buy Goron/Zora Tunic first in shop shuffle
* make ice traps appear as other items instead of breaking generation
* managed to break ice traps on non-major-only
* only handle ice traps if they are on
* fix shopsanity for non-oot games, and write player name instead of player number
* light arrows hint uses player name instead of player number
* Reenable "skip child zelda" option
* fix entrances_based_rules
* fix ganondorf hint if starting with light arrows
* fix dungeonitem shuffle and shopsanity interaction
* remove has_all_of, has_any_of, count_of in BaseClasses, replace usage with has_all, has_any, has_group
* force local giveable item on ZL if skip_child_zelda and shuffle_song_items is any
* keep bosses and bombchu bowling chus out of data package
* revert workaround for infinite recursion and fix it properly
* fix shared shop id caches during patching process
* fix shop text box overflows, as much as possible
* add default oot host.yaml option
* add .apz5, .n64, .z64 to gitignore
* Properly document and name all (functioning) OOT options
* clean up some imports
* remove unnecessary files from oot's data
* fix typo in gitignore
* readd the Compress and Decompress utilities, since they are needed for generation
* cleanup of imports and some minor optimizations
* increase shop offset for item IDs to 0xCB
* remove shop item AP ids entirely
* prevent triforce pieces for other players from being received by yourself
* add "excluded" property to Location
* Hint system adapted and reenabled; hints still unseeded
* make hints deterministic with lists instead of sets
* do not allow hints to point to Light Arrows on non-vanilla bridge
* foreign locations hint as their full name in OoT rather than their region
* checkedLocations now stores hint names by player ID, so that the same location in different worlds can have hints associated
* consolidate versioning in Utils
* ice traps appear as major items rather than any progression item
* set prescription and claim check as defaults for adult trade item settings
* add oot options to playerSettings
* allow case-insensitive logic tricks in yaml
* fix oot shopsanity option formatting
* Write OoT override info even if local item, enabling local checks to show up immediately in the client
* implement CollectionState.can_live_dmg for oot glitched logic
* filter item names for invalid characters when patching shops
* make ice traps appear according to the settings of the world they are shuffled into, rather than the original world
* set hidden-spoiler items and locations with Shop items to events
* make GF carpenters, Gerudo Card, Malon, ZL, and Impa events if the relevant settings are enabled, preventing them from appearing in the client on game start
* Fix oot Glitched and No Logic generation
* fix indenting
* Greatly reduce displayed cosmetic options
* Change oot data version to 1
* add apz5 distribution to webhost
* print player name if an ALttP dungeon contains a good item for OoT world
* delete unneeded commented code
* remove OcarinaSongs import to satisfy lint
											 
										 
										
											2021-09-02 08:35:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  get_option_name ( self ,  value ) : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-22 15:25:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  " ,  " . join ( sorted ( value ) ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												Ocarina of Time (#64)
* first commit (not including OoT data files yet)
* added some basic options
* rule parser works now at least
* make sure to commit everything this time
* temporary change to BaseClasses for oot
* overworld location graph builds mostly correctly
* adding oot data files
* commenting out world options until later since they only existed to make the RuleParser work
* conversion functions between AP ids and OOT ids
* world graph outputs
* set scrub prices
* itempool generates, entrances connected, way too many options added
* fixed set_rules and set_shop_rules
* temp baseclasses changes
* Reaches the fill step now, old event-based system retained in case the new way breaks
* Song placements and misc fixes everywhere
* temporary changes to make oot work
* changed root exits for AP fill framework
* prevent infinite recursion due to OoT sharing usage of the address field
* age reachability works hopefully, songs are broken again
* working spoiler log generation on beatable-only
* Logic tricks implemented
* need this for logic tricks
* fixed map/compass being placed on Serenade location
* kill unreachable events before filling the world
* add a bunch of utility functions to prepare for rom patching
* move OptionList into generic options
* fixed some silly bugs with OptionList
* properly seed all random behavior (so far)
* ROM generation working
* fix hints trying to get alttp dungeon hint texts
* continue fixing hints
* add oot to network data package
* change item and location IDs to 66000 and 67000 range respectively
* push removed items to precollected items
* fixed various issues with cross-contamination with multiple world generation
* reenable glitched logic (hopefully)
* glitched world files age-check fix
* cleaned up some get_locations calls
* added token shuffle and scrub shuffle, modified some options slightly to make the parsing work
* reenable MQ dungeons
* fix forest mq exception
* made targeting style an option for now, will be cosmetic later
* reminder to move targeting to cosmetics
* some oot option maintenance
* enabled starting time of day
* fixed issue breaking shop slots in multiworld generation
* added "off" option for text shuffle and hints
* shopsanity functionality restored
* change patch file extension
* remove unnecessary utility functions + imports
* update MIT license
* change option to "patch_uncompressed_rom" instead of "compress_rom"
* compliance with new AutoWorld systems
* Kill only internal events, remove non-internal big poe event in code
* re-add the big poe event and handle it correctly
* remove extra method in Range option
* fix typo
* Starting items, starting with consumables option
* do not remove nonexistent item
* move set_shop_rules to after shop items are placed
* some cleanup
* add retries for song placement
* flagged Skull Mask and Mask of Truth as advancement items
* update OoT to use LogicMixin
* Fixed trying to assign starting items from the wrong players
* fixed song retry step
* improved option handling, comments, and starting item replacements
* DefaultOnToggle writes Yes or No to spoiler
* enable compression of output if Compress executable is present
* clean up compression
* check whether (de)compressor exists before running the process
* allow specification of rom path in host.yaml
* check if decompressed file already exists before decompressing again
* fix triforce hunt generation
* rename all the oot state functions with prefix
* OoT: mark triforce pieces as completion goal for triforce hunt
* added overworld and any-dungeon shuffle for dungeon items
* Hide most unshuffled locations and events from the list of locations in spoiler
* build oot option ranges with a generic function instead of defining each separately
* move oot output-type control to host.yaml instead of individual yamls
* implement dungeon song shuffle
* minor improvements to overworld dungeon item shuffle
* remove random ice trap names in shops, mostly to avoid maintaining a massive censor list
* always output patch file to folder, remove option to generate ROM in preparation for removal
* re-add the fix for infinite recursion due to not being light or dark world
* change AP-sendable to Ocarina of Time model, since the triforce piece has some extra code apparently
* oot: remove item_names and location_names
* oot: minor fixes
* oot: comment out ROM patching
* oot: only add CollectionState objects on creation if actually needed
* main entrance shuffle method and entrances-based rules
* fix entrances based rules
* disable master quest and big poe count options for client compatibility
* use get_player_name instead of get_player_names
* fix OptionList
* fix oot options for new option system
* new coop section in oot rom: expand player names to 16 bytes, write AP_PLAYER_NAME at end of PLAYER_NAMES
* fill AP player name in oot rom with 0 instead of 0xDF
* encode player name with ASCII for fixed-width
* revert oot player name array to 8 bytes per name
* remove Pierre location if fast scarecrow is on
* check player name length
* "free_scarecrow" not "fast_scarecrow"
* OoT locations now properly store the AP ID instead of the oot internal ID
* oot __version__ updates in lockstep with AP version
* pull in unmodified oot cosmetic files
* also grab JSONDump since it's needed apparently
* gather extra needed methods, modify imports
* delete cosmetics log, replace all instances of SettingsList with OOTWorld
* cosmetic options working, except for sound effects (due to ear-safe issues)
* SFX, Music, and Fanfare randomization reenabled
* move OoT data files into the worlds folder
* move Compress and Decompress into oot data folder
* Replace get_all_state with custom method to avoid the cache
* OoT ROM: increment item counter before setting incoming item/player values to 0, preventing desync issues
* set data_version to 0
* make Kokiri Sword shuffle off by default
* reenable "Random Choice" for various cosmetic options
* kill Ruto's Letter turnin if open fountain
also fix for shopsanity
* place Buy Goron/Zora Tunic first in shop shuffle
* make ice traps appear as other items instead of breaking generation
* managed to break ice traps on non-major-only
* only handle ice traps if they are on
* fix shopsanity for non-oot games, and write player name instead of player number
* light arrows hint uses player name instead of player number
* Reenable "skip child zelda" option
* fix entrances_based_rules
* fix ganondorf hint if starting with light arrows
* fix dungeonitem shuffle and shopsanity interaction
* remove has_all_of, has_any_of, count_of in BaseClasses, replace usage with has_all, has_any, has_group
* force local giveable item on ZL if skip_child_zelda and shuffle_song_items is any
* keep bosses and bombchu bowling chus out of data package
* revert workaround for infinite recursion and fix it properly
* fix shared shop id caches during patching process
* fix shop text box overflows, as much as possible
* add default oot host.yaml option
* add .apz5, .n64, .z64 to gitignore
* Properly document and name all (functioning) OOT options
* clean up some imports
* remove unnecessary files from oot's data
* fix typo in gitignore
* readd the Compress and Decompress utilities, since they are needed for generation
* cleanup of imports and some minor optimizations
* increase shop offset for item IDs to 0xCB
* remove shop item AP ids entirely
* prevent triforce pieces for other players from being received by yourself
* add "excluded" property to Location
* Hint system adapted and reenabled; hints still unseeded
* make hints deterministic with lists instead of sets
* do not allow hints to point to Light Arrows on non-vanilla bridge
* foreign locations hint as their full name in OoT rather than their region
* checkedLocations now stores hint names by player ID, so that the same location in different worlds can have hints associated
* consolidate versioning in Utils
* ice traps appear as major items rather than any progression item
* set prescription and claim check as defaults for adult trade item settings
* add oot options to playerSettings
* allow case-insensitive logic tricks in yaml
* fix oot shopsanity option formatting
* Write OoT override info even if local item, enabling local checks to show up immediately in the client
* implement CollectionState.can_live_dmg for oot glitched logic
* filter item names for invalid characters when patching shops
* make ice traps appear according to the settings of the world they are shuffled into, rather than the original world
* set hidden-spoiler items and locations with Shop items to events
* make GF carpenters, Gerudo Card, Malon, ZL, and Impa events if the relevant settings are enabled, preventing them from appearing in the client on game start
* Fix oot Glitched and No Logic generation
* fix indenting
* Greatly reduce displayed cosmetic options
* Change oot data version to 1
* add apz5 distribution to webhost
* print player name if an ALttP dungeon contains a good item for OoT world
* delete unneeded commented code
* remove OcarinaSongs import to satisfy lint
											 
										 
										
											2021-09-02 08:35:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-30 19:49:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  __contains__ ( self ,  item ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  item  in  self . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												Ocarina of Time (#64)
* first commit (not including OoT data files yet)
* added some basic options
* rule parser works now at least
* make sure to commit everything this time
* temporary change to BaseClasses for oot
* overworld location graph builds mostly correctly
* adding oot data files
* commenting out world options until later since they only existed to make the RuleParser work
* conversion functions between AP ids and OOT ids
* world graph outputs
* set scrub prices
* itempool generates, entrances connected, way too many options added
* fixed set_rules and set_shop_rules
* temp baseclasses changes
* Reaches the fill step now, old event-based system retained in case the new way breaks
* Song placements and misc fixes everywhere
* temporary changes to make oot work
* changed root exits for AP fill framework
* prevent infinite recursion due to OoT sharing usage of the address field
* age reachability works hopefully, songs are broken again
* working spoiler log generation on beatable-only
* Logic tricks implemented
* need this for logic tricks
* fixed map/compass being placed on Serenade location
* kill unreachable events before filling the world
* add a bunch of utility functions to prepare for rom patching
* move OptionList into generic options
* fixed some silly bugs with OptionList
* properly seed all random behavior (so far)
* ROM generation working
* fix hints trying to get alttp dungeon hint texts
* continue fixing hints
* add oot to network data package
* change item and location IDs to 66000 and 67000 range respectively
* push removed items to precollected items
* fixed various issues with cross-contamination with multiple world generation
* reenable glitched logic (hopefully)
* glitched world files age-check fix
* cleaned up some get_locations calls
* added token shuffle and scrub shuffle, modified some options slightly to make the parsing work
* reenable MQ dungeons
* fix forest mq exception
* made targeting style an option for now, will be cosmetic later
* reminder to move targeting to cosmetics
* some oot option maintenance
* enabled starting time of day
* fixed issue breaking shop slots in multiworld generation
* added "off" option for text shuffle and hints
* shopsanity functionality restored
* change patch file extension
* remove unnecessary utility functions + imports
* update MIT license
* change option to "patch_uncompressed_rom" instead of "compress_rom"
* compliance with new AutoWorld systems
* Kill only internal events, remove non-internal big poe event in code
* re-add the big poe event and handle it correctly
* remove extra method in Range option
* fix typo
* Starting items, starting with consumables option
* do not remove nonexistent item
* move set_shop_rules to after shop items are placed
* some cleanup
* add retries for song placement
* flagged Skull Mask and Mask of Truth as advancement items
* update OoT to use LogicMixin
* Fixed trying to assign starting items from the wrong players
* fixed song retry step
* improved option handling, comments, and starting item replacements
* DefaultOnToggle writes Yes or No to spoiler
* enable compression of output if Compress executable is present
* clean up compression
* check whether (de)compressor exists before running the process
* allow specification of rom path in host.yaml
* check if decompressed file already exists before decompressing again
* fix triforce hunt generation
* rename all the oot state functions with prefix
* OoT: mark triforce pieces as completion goal for triforce hunt
* added overworld and any-dungeon shuffle for dungeon items
* Hide most unshuffled locations and events from the list of locations in spoiler
* build oot option ranges with a generic function instead of defining each separately
* move oot output-type control to host.yaml instead of individual yamls
* implement dungeon song shuffle
* minor improvements to overworld dungeon item shuffle
* remove random ice trap names in shops, mostly to avoid maintaining a massive censor list
* always output patch file to folder, remove option to generate ROM in preparation for removal
* re-add the fix for infinite recursion due to not being light or dark world
* change AP-sendable to Ocarina of Time model, since the triforce piece has some extra code apparently
* oot: remove item_names and location_names
* oot: minor fixes
* oot: comment out ROM patching
* oot: only add CollectionState objects on creation if actually needed
* main entrance shuffle method and entrances-based rules
* fix entrances based rules
* disable master quest and big poe count options for client compatibility
* use get_player_name instead of get_player_names
* fix OptionList
* fix oot options for new option system
* new coop section in oot rom: expand player names to 16 bytes, write AP_PLAYER_NAME at end of PLAYER_NAMES
* fill AP player name in oot rom with 0 instead of 0xDF
* encode player name with ASCII for fixed-width
* revert oot player name array to 8 bytes per name
* remove Pierre location if fast scarecrow is on
* check player name length
* "free_scarecrow" not "fast_scarecrow"
* OoT locations now properly store the AP ID instead of the oot internal ID
* oot __version__ updates in lockstep with AP version
* pull in unmodified oot cosmetic files
* also grab JSONDump since it's needed apparently
* gather extra needed methods, modify imports
* delete cosmetics log, replace all instances of SettingsList with OOTWorld
* cosmetic options working, except for sound effects (due to ear-safe issues)
* SFX, Music, and Fanfare randomization reenabled
* move OoT data files into the worlds folder
* move Compress and Decompress into oot data folder
* Replace get_all_state with custom method to avoid the cache
* OoT ROM: increment item counter before setting incoming item/player values to 0, preventing desync issues
* set data_version to 0
* make Kokiri Sword shuffle off by default
* reenable "Random Choice" for various cosmetic options
* kill Ruto's Letter turnin if open fountain
also fix for shopsanity
* place Buy Goron/Zora Tunic first in shop shuffle
* make ice traps appear as other items instead of breaking generation
* managed to break ice traps on non-major-only
* only handle ice traps if they are on
* fix shopsanity for non-oot games, and write player name instead of player number
* light arrows hint uses player name instead of player number
* Reenable "skip child zelda" option
* fix entrances_based_rules
* fix ganondorf hint if starting with light arrows
* fix dungeonitem shuffle and shopsanity interaction
* remove has_all_of, has_any_of, count_of in BaseClasses, replace usage with has_all, has_any, has_group
* force local giveable item on ZL if skip_child_zelda and shuffle_song_items is any
* keep bosses and bombchu bowling chus out of data package
* revert workaround for infinite recursion and fix it properly
* fix shared shop id caches during patching process
* fix shop text box overflows, as much as possible
* add default oot host.yaml option
* add .apz5, .n64, .z64 to gitignore
* Properly document and name all (functioning) OOT options
* clean up some imports
* remove unnecessary files from oot's data
* fix typo in gitignore
* readd the Compress and Decompress utilities, since they are needed for generation
* cleanup of imports and some minor optimizations
* increase shop offset for item IDs to 0xCB
* remove shop item AP ids entirely
* prevent triforce pieces for other players from being received by yourself
* add "excluded" property to Location
* Hint system adapted and reenabled; hints still unseeded
* make hints deterministic with lists instead of sets
* do not allow hints to point to Light Arrows on non-vanilla bridge
* foreign locations hint as their full name in OoT rather than their region
* checkedLocations now stores hint names by player ID, so that the same location in different worlds can have hints associated
* consolidate versioning in Utils
* ice traps appear as major items rather than any progression item
* set prescription and claim check as defaults for adult trade item settings
* add oot options to playerSettings
* allow case-insensitive logic tricks in yaml
* fix oot shopsanity option formatting
* Write OoT override info even if local item, enabling local checks to show up immediately in the client
* implement CollectionState.can_live_dmg for oot glitched logic
* filter item names for invalid characters when patching shops
* make ice traps appear according to the settings of the world they are shuffled into, rather than the original world
* set hidden-spoiler items and locations with Shop items to events
* make GF carpenters, Gerudo Card, Malon, ZL, and Impa events if the relevant settings are enabled, preventing them from appearing in the client on game start
* Fix oot Glitched and No Logic generation
* fix indenting
* Greatly reduce displayed cosmetic options
* Change oot data version to 1
* add apz5 distribution to webhost
* print player name if an ALttP dungeon contains a good item for OoT world
* delete unneeded commented code
* remove OcarinaSongs import to satisfy lint
											 
										 
										
											2021-09-02 08:35:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-21 00:47:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								local_objective  =  Toggle   # local triforce pieces, local dungeon prizes etc.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 16:15:32 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  Accessibility ( Choice ) :  
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """ Set rules for reachability of your items/locations. 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Locations :  ensure  everything  can  be  reached  and  acquired . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Items :  ensure  all  logically  relevant  items  can  be  acquired . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Minimal :  ensure  what  is  needed  to  reach  your  goal  can  be  acquired . """ 
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 16:29:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    display_name  =  " Accessibility " 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    option_locations  =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    option_items  =  1 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    option_minimal  =  2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    alias_none  =  2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    default  =  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-11 00:13:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  ProgressionBalancing ( Range ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ A system that can move progression earlier, to try and prevent the player from getting stuck and bored early. 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ 0 - 99 ,  default  50 ]  A  lower  setting  means  more  getting  stuck .  A  higher  setting  means  less  getting  stuck . """ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    default  =  50 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    range_start  =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    range_end  =  99 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 16:29:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    display_name  =  " Progression Balancing " 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								common_options  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    " progression_balancing " :  ProgressionBalancing , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    " accessibility " :  Accessibility 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  ItemSet ( OptionSet ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    verify_item_name  =  True 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 20:49:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    convert_name_groups  =  True 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  LocalItems ( ItemSet ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ Forces these items to be in their native world. """ 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 16:29:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    display_name  =  " Local Items " 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 16:15:32 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  NonLocalItems ( ItemSet ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ Forces these items to be outside their native world. """ 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 16:29:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    display_name  =  " Not Local Items " 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-25 04:13:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  StartInventory ( ItemDict ) :  
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """ Start with these items. """ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    verify_item_name  =  True 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 16:29:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    display_name  =  " Start Inventory " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  StartHints ( ItemSet ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ Start with these item ' s locations prefilled into the !hint command. """ 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 16:29:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    display_name  =  " Start Hints " 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-03 14:40:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  StartLocationHints ( OptionSet ) :  
						 
					
						
							
								
									
										
										
										
											2021-11-17 16:44:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    """ Start with these locations and their item prefilled into the !hint command """ 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 16:29:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    display_name  =  " Start Location Hints " 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-20 09:40:17 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    verify_location_name  =  True 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-03 14:40:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  ExcludeLocations ( OptionSet ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ Prevent these locations from having an important item """ 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 16:29:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    display_name  =  " Excluded Locations " 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    verify_location_name  =  True 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-01 16:36:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  PriorityLocations ( OptionSet ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ Prevent these locations from having an unimportant item """ 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 16:29:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    display_name  =  " Priority Locations " 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-01 16:36:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    verify_location_name  =  True 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-01 19:37:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  DeathLink ( Toggle ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ When you die, everyone dies. Of course the reverse is true too. """ 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-02 16:29:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    display_name  =  " Death Link " 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-01 19:37:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 15:49:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  ItemLinks ( OptionList ) :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ Share part of your item pool with other players. """ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    default  =  [ ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    schema  =  Schema ( [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            " name " :  And ( str ,  len ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            " item_pool " :  [ And ( str ,  len ) ] , 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-11 16:37:18 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            Optional ( " exclude " ) :  [ And ( str ,  len ) ] , 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-15 07:41:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            " replacement_item " :  Or ( And ( str ,  len ) ,  None ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Optional ( " local_items " ) :  [ And ( str ,  len ) ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Optional ( " non_local_items " ) :  [ And ( str ,  len ) ] 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 15:49:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-15 07:41:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    @staticmethod 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    def  verify_items ( items :  typing . List [ str ] ,  item_link :  str ,  pool_name :  str ,  world ,  allow_item_groups :  bool  =  True )  - >  typing . Set : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        pool  =  set ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  item_name  in  items : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  item_name  not  in  world . item_names  and  ( not  allow_item_groups  or  item_name  not  in  world . item_name_groups ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                picks  =  get_fuzzy_results ( item_name ,  world . item_names ,  limit = 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                picks_group  =  get_fuzzy_results ( item_name ,  world . item_name_groups . keys ( ) ,  limit = 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                picks_group  =  f "  or  ' { picks_group [ 0 ] [ 0 ] } '  ( { picks_group [ 0 ] [ 1 ] } % sure) "  if  allow_item_groups  else  " " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                raise  Exception ( f " Item  { item_name }  from item link  { item_link }   " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                f " is not a valid item from  { world . game }  for  { pool_name } .  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                f " Did you mean  ' { picks [ 0 ] [ 0 ] } '  ( { picks [ 0 ] [ 1 ] } % sure) { picks_group } " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  allow_item_groups : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                pool  | =  world . item_name_groups . get ( item_name ,  { item_name } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                pool  | =  { item_name } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  pool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-06 16:37:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    def  verify ( self ,  world ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        super ( ItemLinks ,  self ) . verify ( world ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 15:17:24 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        existing_links  =  set ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-06 16:37:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  link  in  self . value : 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 15:17:24 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  link [ " name " ]  in  existing_links : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                raise  Exception ( f " You cannot have more than one link named  { link [ ' name ' ] } . " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            existing_links . add ( link [ " name " ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-15 07:41:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            pool  =  self . verify_items ( link [ " item_pool " ] ,  link [ " name " ] ,  " item_pool " ,  world ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            local_items  =  set ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            non_local_items  =  set ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-11 16:37:18 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  " exclude "  in  link : 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-15 07:41:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                pool  - =  self . verify_items ( link [ " exclude " ] ,  link [ " name " ] ,  " exclude " ,  world ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  link [ " replacement_item " ] : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                self . verify_items ( [ link [ " replacement_item " ] ] ,  link [ " name " ] ,  " replacement_item " ,  world ,  False ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  " local_items "  in  link : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                local_items  =  self . verify_items ( link [ " local_items " ] ,  link [ " name " ] ,  " local_items " ,  world ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                local_items  & =  pool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  " non_local_items "  in  link : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                non_local_items  =  self . verify_items ( link [ " non_local_items " ] ,  link [ " name " ] ,  " non_local_items " ,  world ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                non_local_items  & =  pool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            intersection  =  local_items . intersection ( non_local_items ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  intersection : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                raise  Exception ( f " item_link  { link [ ' name ' ] }  has  { intersection }  items in both its local_items and non_local_items pool. " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-06 16:37:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 15:49:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								per_game_common_options  =  {  
						 
					
						
							
								
									
										
										
										
											2021-12-28 18:43:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    * * common_options ,   # can be overwritten per-game 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    " local_items " :  LocalItems , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    " non_local_items " :  NonLocalItems , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    " start_inventory " :  StartInventory , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    " start_hints " :  StartHints , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-03 14:40:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    " start_location_hints " :  StartLocationHints , 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-01 16:36:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    " exclude_locations " :  ExcludeLocations , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    " priority_locations " :  PriorityLocations , 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 15:49:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    " item_links " :  ItemLinks 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 16:15:32 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								if  __name__  ==  " __main__ " :  
						 
					
						
							
								
									
										
										
										
											2021-07-04 16:18:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    from  worlds . alttp . Options  import  Logic 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 16:15:32 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    import  argparse 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-17 00:17:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-30 18:00:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    map_shuffle  =  Toggle 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    compass_shuffle  =  Toggle 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 15:49:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    key_shuffle  =  Toggle 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    big_key_shuffle  =  Toggle 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 01:00:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    hints  =  Toggle 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 16:15:32 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    test  =  argparse . Namespace ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    test . logic  =  Logic . from_text ( " no_logic " ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-30 18:00:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    test . map_shuffle  =  map_shuffle . from_text ( " ON " ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    test . hints  =  hints . from_text ( ' OFF ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    try : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        test . logic  =  Logic . from_text ( " overworld_glitches_typo " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    except  KeyError  as  e : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( e ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 16:15:32 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    try : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        test . logic_owg  =  Logic . from_text ( " owg " ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 16:15:32 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    except  KeyError  as  e : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( e ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-30 18:00:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  test . map_shuffle : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( " map_shuffle is on " ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 06:43:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print ( f " Hints are  { bool ( test . hints ) } " ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 16:15:32 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    print ( test )