Advertisement
imbued

Bomber SRM Setup Finder

Jul 3rd, 2020
2,556
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 33.43 KB | None | 0 0
  1. """
  2.  
  3. EDIT THE INFORMATION AT THE BOTTOM
  4.  
  5. - CODE CURRENTLY ASSUMES MAX OF 15 ESS TURNS ALLOWED (can easily edit this by changing Max_ESS_Count hardcoded in find_ranked_collision_solutions() function)
  6. - SIDEHOPS ARE NOT FULLY IMPLEMENTED YET
  7.  
  8. """
  9.  
  10.  
  11. def sortFirst(val):
  12.     return val[0]  
  13.  
  14.  
  15. def col(normal_vector_angle, movement_angle):
  16.    
  17.    
  18.     """
  19.    
  20.    This function takes the normal_vector_angle of a wall and the movement_angle
  21.    that you collided into it with and returns the collision angle that you get
  22.    by moving into it with this movement angle
  23.    
  24.    """
  25.  
  26.    
  27.     angle_diff = abs(normal_vector_angle - movement_angle)
  28.    
  29.     if angle_diff > 0x8000:
  30.                
  31.         collision_angle = abs(0x10000 - angle_diff )
  32.         print(hex(collision_angle))
  33.                
  34.     elif angle_diff <= 0x8000 and angle_diff >= 0:
  35.                    
  36.         collision_angle = angle_diff
  37.         print(hex(collision_angle))
  38.                    
  39.     else:
  40.         print("UHHHHHHHH??????")
  41.        
  42.     return
  43.  
  44.  
  45. def find_goal_collision_angles_40_bit(value_string):
  46.    
  47.     # if seahorse, then value_string = '0x24', for example
  48.    
  49.     """
  50.    
  51.    This function gives us the goal collision angles for a given item that needs
  52.    the 0x40 bit to be 0
  53.    
  54.    """
  55.    
  56.     if len(value_string) != 4 or value_string[0] != '0':
  57.         print('invalid input into find_goal_collision_angles() function')
  58.    
  59.     seahorse_list = []
  60.     for i in range(256):
  61.         string = hex(i)
  62.         if len(string) == 3:
  63.             new_string = '0x0' + string[2]
  64.         elif len(string) == 4:
  65.             new_string = string
  66.         else:
  67.             print("ERROR!!!!!!!!!!!!!!!!!!!!!!!!!!!???????????????????????????")
  68.        
  69.         collision_value = value_string + new_string[2:4]
  70.        
  71.         if len(collision_value) != 6:
  72.             print(collision_value)
  73.        
  74.         # If the 0x40 bit is 0, then add the value:
  75.         if collision_value[4] != '4' and collision_value[4] != '5' and collision_value[4] != '6' and collision_value[4] != '7' and collision_value[4] != 'c' and collision_value[4] != 'd' and collision_value[4] != 'e' and collision_value[4] != 'f':
  76.             seahorse_list.append(int(collision_value, 16))
  77.             #seahorse_list.append(collision_value)
  78.     if len(seahorse_list) != 128:
  79.         print("??????????????")
  80.    
  81.     return seahorse_list
  82.  
  83.  
  84. def find_goal_collision_angles_20_bit(value_string):
  85.    
  86.     # if seahorse, then value_string = '0x24', for example
  87.    
  88.     """
  89.    
  90.    This function gives us the goal collision angles for a given item that needs
  91.    the 0x20 bit to be 0
  92.    
  93.    """
  94.    
  95.     if len(value_string) != 4 or value_string[0] != '0':
  96.         print('invalid input into find_goal_collision_angles() function')
  97.    
  98.     seahorse_list = []
  99.     for i in range(256):
  100.         string = hex(i)
  101.         if len(string) == 3:
  102.             new_string = '0x0' + string[2]
  103.         elif len(string) == 4:
  104.             new_string = string
  105.         else:
  106.             print("ERROR!!!!!!!!!!!!!!!!!!!!!!!!!!!???????????????????????????")
  107.        
  108.         collision_value = value_string + new_string[2:4]
  109.        
  110.         if len(collision_value) != 6:
  111.             print(collision_value)
  112.        
  113.         # If the 0x20 bit is 0, then add the value:
  114.         if collision_value[4] != '2' and collision_value[4] != '3' and collision_value[4] != '6' and collision_value[4] != '7' and collision_value[4] != 'a' and collision_value[4] != 'b' and collision_value[4] != 'e' and collision_value[4] != 'f':
  115.             seahorse_list.append(int(collision_value, 16))
  116.             #seahorse_list.append(collision_value)
  117.     if len(seahorse_list) != 128:
  118.         print("??????????????")
  119.    
  120.     return seahorse_list
  121.  
  122.  
  123. def find_valid_goal_angles(goal_collision_angle_list, normal_vector_angle_list):
  124.    
  125.     """
  126.    
  127.    a normal vector angle is the angle you get by targeting a given wall
  128.    
  129.    
  130.    This function takes a list of normal vector angles and a list of goal collision
  131.    angles and returns a list of all in the form (goal_angle, normal_angle, goal_collision_angle)
  132.    where goal_angle is an angle that can be used to collide into a wall with a normal vector angle
  133.    of normal_angle to get a collision angle of goal_collision_angle
  134.    
  135.    """
  136.    
  137.     valid_goal_angle_list = []
  138.    
  139.     for normal_vector_angle in normal_vector_angle_list:
  140.         for i in range(65536):
  141.            
  142.             angle_diff = abs(normal_vector_angle - i)
  143.            
  144.             if angle_diff > 0x8000:
  145.            
  146.                 collision_angle = abs(0x10000 - angle_diff )
  147.            
  148.             elif angle_diff <= 0x8000 and angle_diff >= 0:
  149.                
  150.                 collision_angle = angle_diff
  151.                
  152.             else:
  153.                 print("UHHHHHHHH??????")
  154.            
  155.             if collision_angle in goal_collision_angle_list:
  156.                
  157.                 valid_goal_angle_list.append((i, normal_vector_angle, collision_angle))
  158.                
  159.    
  160.     return valid_goal_angle_list
  161.  
  162. ###############################################################################
  163.  
  164. def right_sidehop_angles(angle, camera_angle):
  165.    
  166.     angle_list = []
  167.    
  168.     cardinal_list = [(camera_angle - 0xC000)%(0x10000), (camera_angle - 0x8000)%(0x10000), (camera_angle - 0x4000)%(0x10000), camera_angle]
  169.    
  170.     cardinal_list.sort()
  171.    
  172.     ################# Find Nearest Cardinal (the one movement snaps to)
  173.    
  174.     initial_sidehop_angle = (angle - 0x4000)%(0x10000)
  175.    
  176.     diff_list = []
  177.     for cardinal_angle in cardinal_list:
  178.         diff_list.append(abs((initial_sidehop_angle - cardinal_angle)%(0x10000)))
  179.        
  180.     min_diff = min(diff_list)
  181.    
  182.     if min_diff != 0x2000:
  183.         for cardinal_angle in cardinal_list:
  184.             if abs((initial_sidehop_angle - cardinal_angle)%(0x10000)) == min_diff:
  185.                 nearest_cardinal = cardinal_angle
  186.     elif min_diff == 0x2000:
  187.         closest_list = []
  188.         for cardinal_angle in cardinal_list:
  189.             if abs((initial_sidehop_angle - cardinal_angle)%(0x10000)) == min_diff:
  190.                 closest_list.append(cardinal_angle)
  191.        
  192.        
  193.         # subtract 1 to break the tie (we want the lower one)
  194.         new_diff_list = []
  195.         for cardinal_angle in closest_list:
  196.             new_diff_list.append(abs((initial_sidehop_angle - 1 - cardinal_angle)%(0x10000)))
  197.            
  198.         new_min_diff = min(new_diff_list)
  199.        
  200.         for cardinal_angle in closest_list:
  201.             if abs((initial_sidehop_angle - 1 - cardinal_angle)%(0x10000)) == new_min_diff:
  202.                 nearest_cardinal = cardinal_angle
  203.        
  204.     ###########################################################################
  205.    
  206.     nearest_cardinal_index = cardinal_list.index(nearest_cardinal)
  207.    
  208.     # TAP SIDEHOP
  209.     # 1 frame window
  210.     angle_list.append((initial_sidehop_angle + 5*0x12C)%(0x10000))
  211.    
  212.    
  213.    
  214.     # 1 Frame Hold Sidehop
  215.     if abs((initial_sidehop_angle - nearest_cardinal)%(0x10000)) <= 0x12C:
  216.        
  217.         # 1 frame window
  218.         angle_list.append((nearest_cardinal + 4*0x12C)%(0x10000))
  219.        
  220.     elif abs((initial_sidehop_angle - nearest_cardinal)%(0x10000)) > 0x12C:
  221.        
  222.         if nearest_cardinal_index != 3:
  223.        
  224.             if initial_sidehop_angle > nearest_cardinal:
  225.                
  226.                 # 1 frame window
  227.                 angle_list.append((initial_sidehop_angle - 0x12C + 4*0x012C)%(0x10000))
  228.    
  229.             elif initial_sidehop_angle < nearest_cardinal:
  230.                
  231.                 # 1 frame window
  232.                 angle_list.append((initial_sidehop_angle + 0x12C + 4*0x012C)%(0x10000))
  233.                
  234.         elif nearest_cardinal_index == 3:
  235.            
  236.             if initial_sidehop_angle > nearest_cardinal or initial_sidehop_angle < cardinal_list[0]:
  237.                
  238.                 # 1 frame window
  239.                 angle_list.append((initial_sidehop_angle - 0x12C + 4*0x012C)%(0x10000))
  240.            
  241.             elif initial_sidehop_angle < nearest_cardinal and initial_sidehop_angle > cardinal_list[2]:
  242.                
  243.                 # 1 frame window
  244.                 angle_list.append((initial_sidehop_angle + 0x12C + 4*0x012C)%(0x10000))
  245.                
  246.                
  247.                
  248.                
  249.    
  250.     # 2 Frame Hold Sidehop
  251.     if abs((initial_sidehop_angle - nearest_cardinal)%(0x10000)) <= 0x12C:
  252.        
  253.         # 1 frame window
  254.         angle_list.append((nearest_cardinal + 3*0x12C)%(0x10000))
  255.        
  256.     elif abs((initial_sidehop_angle - nearest_cardinal)%(0x10000)) > 0x12C:
  257.        
  258.         if nearest_cardinal_index != 3:
  259.            
  260.        
  261.             if initial_sidehop_angle > nearest_cardinal:
  262.                
  263.                 if abs(((initial_sidehop_angle - 0x12C)%(0x10000) - nearest_cardinal)%(0x10000)) <= 0x12C:
  264.                    
  265.                     # 1 frame window
  266.                     angle_list.append((nearest_cardinal + 3*0x12C)%(0x10000))
  267.                
  268.                 elif abs(((initial_sidehop_angle - 0x12C)%(0x10000) - nearest_cardinal)%(0x10000)) > 0x12C:
  269.                
  270.                     # 1 frame window
  271.                     angle_list.append((initial_sidehop_angle - 2*0x12C + 3*0x012C)%(0x10000))
  272.    
  273.             elif initial_sidehop_angle < nearest_cardinal:
  274.                
  275.                 if abs(((initial_sidehop_angle + 0x12C)%(0x10000) - nearest_cardinal)%(0x10000)) <= 0x12C:
  276.                    
  277.                     # 1 frame window
  278.                     angle_list.append((nearest_cardinal + 3*0x12C)%(0x10000))
  279.                
  280.                 elif abs(((initial_sidehop_angle + 0x12C)%(0x10000) - nearest_cardinal)%(0x10000)) > 0x12C:
  281.                
  282.                     # 1 frame window
  283.                     angle_list.append((initial_sidehop_angle + 2*0x12C + 3*0x012C)%(0x10000))
  284.                
  285.                
  286.         elif nearest_cardinal_index == 3:
  287.            
  288.             if initial_sidehop_angle > nearest_cardinal or initial_sidehop_angle < cardinal_list[0]:
  289.                
  290.                 if abs(((initial_sidehop_angle - 0x12C)%(0x10000) - nearest_cardinal)%(0x10000)) <= 0x12C:
  291.                    
  292.                     # 1 frame window
  293.                     angle_list.append((nearest_cardinal + 3*0x12C)%(0x10000))
  294.                
  295.                 elif abs(((initial_sidehop_angle - 0x12C)%(0x10000) - nearest_cardinal)%(0x10000)) > 0x12C:
  296.                
  297.                     # 1 frame window
  298.                     angle_list.append((initial_sidehop_angle - 2*0x12C + 3*0x012C)%(0x10000))
  299.                
  300.            
  301.             elif initial_sidehop_angle < nearest_cardinal and initial_sidehop_angle > cardinal_list[2]:
  302.                
  303.                 if abs(((initial_sidehop_angle + 0x12C)%(0x10000) - nearest_cardinal)%(0x10000)) <= 0x12C:
  304.                    
  305.                     # 1 frame window
  306.                     angle_list.append((nearest_cardinal + 3*0x12C)%(0x10000))
  307.                
  308.                 elif abs(((initial_sidehop_angle + 0x12C)%(0x10000) - nearest_cardinal)%(0x10000)) > 0x12C:
  309.                
  310.                     # 1 frame window
  311.                     angle_list.append((initial_sidehop_angle + 2*0x12C + 3*0x012C)%(0x10000))
  312.      
  313.     """
  314.  
  315.    TODO
  316.  
  317.    """            
  318.                
  319.     # 3 frame hold sidehop
  320.    
  321.     # 4 frame hold sidehop
  322.    
  323.     # 5 frame hold sidehop (true hold sidehop)
  324.                
  325.    
  326.     return angle_list
  327.  
  328.  
  329. ###############################################################################
  330.    
  331. def left_sidehop_angles(angle, camera_angle):
  332.    
  333.     angle_list = []
  334.    
  335.     cardinal_list = [(camera_angle - 0xC000)%(0x10000), (camera_angle - 0x8000)%(0x10000), (camera_angle - 0x4000)%(0x10000), camera_angle]
  336.    
  337.     cardinal_list.sort()
  338.    
  339.     ################# Find Nearest Cardinal (the one movement snaps to)
  340.    
  341.     initial_sidehop_angle = (angle - 0x4000)%(0x10000)
  342.    
  343.     diff_list = []
  344.     for cardinal_angle in cardinal_list:
  345.         diff_list.append(abs((initial_sidehop_angle - cardinal_angle)%(0x10000)))
  346.        
  347.     min_diff = min(diff_list)
  348.    
  349.     if min_diff != 0x2000:
  350.         for cardinal_angle in cardinal_list:
  351.             if abs((initial_sidehop_angle - cardinal_angle)%(0x10000)) == min_diff:
  352.                 nearest_cardinal = cardinal_angle
  353.     elif min_diff == 0x2000:
  354.         closest_list = []
  355.         for cardinal_angle in cardinal_list:
  356.             if abs((initial_sidehop_angle - cardinal_angle)%(0x10000)) == min_diff:
  357.                 closest_list.append(cardinal_angle)
  358.        
  359.        
  360.         # subtract 1 to break the tie (we want the lower one)
  361.         new_diff_list = []
  362.         for cardinal_angle in closest_list:
  363.             new_diff_list.append(abs((initial_sidehop_angle - 1 - cardinal_angle)%(0x10000)))
  364.            
  365.         new_min_diff = min(new_diff_list)
  366.        
  367.         for cardinal_angle in closest_list:
  368.             if abs((initial_sidehop_angle - 1 - cardinal_angle)%(0x10000)) == new_min_diff:
  369.                 nearest_cardinal = cardinal_angle
  370.        
  371.     ###########################################################################
  372.    
  373.     nearest_cardinal_index = cardinal_list.index(nearest_cardinal)
  374.    
  375.     # TAP SIDEHOP
  376.     # 1 frame window
  377.     angle_list.append((initial_sidehop_angle - 5*0x12C)%(0x10000))
  378.    
  379.    
  380.    
  381.     # 1 Frame Hold Sidehop
  382.     if abs((initial_sidehop_angle - nearest_cardinal)%(0x10000)) <= 0x12C:
  383.        
  384.         # 1 frame window
  385.         angle_list.append((nearest_cardinal - 4*0x12C)%(0x10000))
  386.        
  387.     elif abs((initial_sidehop_angle - nearest_cardinal)%(0x10000)) > 0x12C:
  388.        
  389.         if nearest_cardinal_index != 3:
  390.        
  391.             if initial_sidehop_angle > nearest_cardinal:
  392.                
  393.                 # 1 frame window
  394.                 angle_list.append((initial_sidehop_angle - 0x12C - 4*0x012C)%(0x10000))
  395.    
  396.             elif initial_sidehop_angle < nearest_cardinal:
  397.                
  398.                 # 1 frame window
  399.                 angle_list.append((initial_sidehop_angle + 0x12C - 4*0x012C)%(0x10000))
  400.                
  401.         elif nearest_cardinal_index == 3:
  402.            
  403.             if initial_sidehop_angle > nearest_cardinal or initial_sidehop_angle < cardinal_list[0]:
  404.                
  405.                 # 1 frame window
  406.                 angle_list.append((initial_sidehop_angle - 0x12C - 4*0x012C)%(0x10000))
  407.            
  408.             elif initial_sidehop_angle < nearest_cardinal and initial_sidehop_angle > cardinal_list[2]:
  409.                
  410.                 # 1 frame window
  411.                 angle_list.append((initial_sidehop_angle + 0x12C - 4*0x012C)%(0x10000))
  412.                
  413.                
  414.                
  415.                
  416.    
  417.     # 2 Frame Hold Sidehop
  418.     if abs((initial_sidehop_angle - nearest_cardinal)%(0x10000)) <= 0x12C:
  419.        
  420.         # 1 frame window
  421.         angle_list.append((nearest_cardinal - 3*0x12C)%(0x10000))
  422.        
  423.     elif abs((initial_sidehop_angle - nearest_cardinal)%(0x10000)) > 0x12C:
  424.        
  425.         if nearest_cardinal_index != 3:
  426.            
  427.        
  428.             if initial_sidehop_angle > nearest_cardinal:
  429.                
  430.                 if abs(((initial_sidehop_angle - 0x12C)%(0x10000) - nearest_cardinal)%(0x10000)) <= 0x12C:
  431.                    
  432.                     # 1 frame window
  433.                     angle_list.append((nearest_cardinal - 3*0x12C)%(0x10000))
  434.                
  435.                 elif abs(((initial_sidehop_angle - 0x12C)%(0x10000) - nearest_cardinal)%(0x10000)) > 0x12C:
  436.                
  437.                     # 1 frame window
  438.                     angle_list.append((initial_sidehop_angle - 2*0x12C - 3*0x012C)%(0x10000))
  439.    
  440.             elif initial_sidehop_angle < nearest_cardinal:
  441.                
  442.                 if abs(((initial_sidehop_angle + 0x12C)%(0x10000) - nearest_cardinal)%(0x10000)) <= 0x12C:
  443.                    
  444.                     # 1 frame window
  445.                     angle_list.append((nearest_cardinal - 3*0x12C)%(0x10000))
  446.                
  447.                 elif abs(((initial_sidehop_angle + 0x12C)%(0x10000) - nearest_cardinal)%(0x10000)) > 0x12C:
  448.                
  449.                     # 1 frame window
  450.                     angle_list.append((initial_sidehop_angle + 2*0x12C - 3*0x012C)%(0x10000))
  451.                
  452.                
  453.         elif nearest_cardinal_index == 3:
  454.            
  455.             if initial_sidehop_angle > nearest_cardinal or initial_sidehop_angle < cardinal_list[0]:
  456.                
  457.                 if abs(((initial_sidehop_angle - 0x12C)%(0x10000) - nearest_cardinal)%(0x10000)) <= 0x12C:
  458.                    
  459.                     # 1 frame window
  460.                     angle_list.append((nearest_cardinal - 3*0x12C)%(0x10000))
  461.                
  462.                 elif abs(((initial_sidehop_angle - 0x12C)%(0x10000) - nearest_cardinal)%(0x10000)) > 0x12C:
  463.                
  464.                     # 1 frame window
  465.                     angle_list.append((initial_sidehop_angle - 2*0x12C - 3*0x012C)%(0x10000))
  466.                
  467.            
  468.             elif initial_sidehop_angle < nearest_cardinal and initial_sidehop_angle > cardinal_list[2]:
  469.                
  470.                 if abs(((initial_sidehop_angle + 0x12C)%(0x10000) - nearest_cardinal)%(0x10000)) <= 0x12C:
  471.                    
  472.                     # 1 frame window
  473.                     angle_list.append((nearest_cardinal - 3*0x12C)%(0x10000))
  474.                
  475.                 elif abs(((initial_sidehop_angle + 0x12C)%(0x10000) - nearest_cardinal)%(0x10000)) > 0x12C:
  476.                
  477.                     # 1 frame window
  478.                     angle_list.append((initial_sidehop_angle + 2*0x12C - 3*0x012C)%(0x10000))
  479.      
  480.     """
  481.  
  482.    TODO
  483.  
  484.    """            
  485.                
  486.     # 3 frame hold sidehop
  487.    
  488.     # 4 frame hold sidehop
  489.    
  490.     # 5 frame hold sidehop (true hold sidehop)
  491.                
  492.    
  493.     return angle_list
  494.  
  495.  
  496.  
  497.  
  498. ###############################################################################
  499.  
  500. def find_ranked_collision_solutions(initial_angle_list, camera_angle, goal_angle_list, filename):
  501.    
  502.     """
  503.    
  504.    The idea is to have goal_angle_list = find_valid_goal_angles(find_goal_collision_angles('0x24'), oceanside_room4_normal_vector_angle_list)
  505.    if doing seahorse (item 0x24)
  506.    
  507.    It is assumed that initial_angle_list = [initial_angle, short_chest_angle] (would be extremely easy to change this but I see no point atm)
  508.    
  509.    """
  510.    
  511.     Max_ESS_Count = 15
  512.    
  513.     cardinal_list = [(camera_angle - 0xC000)%(0x10000), (camera_angle - 0x8000)%(0x10000), (camera_angle - 0x4000)%(0x10000), camera_angle]
  514.  
  515.    
  516.     walk_angle_list = []
  517.    
  518.     # add all directions from walking to the initial angle list
  519.     for cardinal_angle in cardinal_list:
  520.         for i in range(5):
  521.             walk_angle_list.append((cardinal_angle + (i+1)*0xBB8)%(0x10000) )
  522.             walk_angle_list.append((cardinal_angle - (i+1)*0xBB8)%(0x10000) )
  523.            
  524.    
  525.     #initial_angle_list_list = [initial_angle_list, cardinal_list, walk_angle_list]        
  526.    
  527.    
  528.     # add all 4 cardinal directions and all walk angles to the initial angle list
  529.     #initial_angle_list = initial_angle_list + cardinal_list + walk_angle_list        
  530.    
  531.     # for angles in initial_angle_list (namely initial angle and short chest cs angle and wall angles)
  532.     solution_list = []
  533.     cup_solution_list = []
  534.     sidehop_solution_list = []
  535.    
  536.    
  537.     # for angles in cardinal_list
  538.     solution_list_cardinal = []
  539.     cup_solution_list_cardinal = []
  540.     sidehop_solution_list_cardinal = []
  541.    
  542.     # for angles in walk_angle_list
  543.     solution_list_walk = []
  544.     cup_solution_list_walk = []
  545.     sidehop_solution_list_walk = []
  546.    
  547.    
  548.     with open(filename, "a") as file:
  549.        
  550.         #######################################################################
  551.         #######################################################################
  552.         #######################################################################
  553.         #######################################################################
  554.         #######################################################################
  555.    
  556.         for initial_angle in initial_angle_list:
  557.            
  558.             print(hex(initial_angle))
  559.            
  560.             if initial_angle > 65535 or initial_angle < 0 or isinstance(initial_angle, int) == False:
  561.                 print('Error: The initial angle is not a valid input')
  562.            
  563.             #for i in range(8192):
  564.             for i in range(Max_ESS_Count):
  565.                 for entry in goal_angle_list:
  566.                    
  567.                     angle = entry[0]
  568.                     normal_vector_angle = entry[1]
  569.                     collision_angle = entry[2]
  570.                    
  571.                     if (initial_angle + i*1800)%65536 == angle:
  572.                         solution_list.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', ''))
  573.                        
  574.                     if (initial_angle - i*1800)%65536 == angle:
  575.                         solution_list.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', ''))
  576.  
  577.                     if (initial_angle + 0x12C + i*1800)%65536 == angle:
  578.                         cup_solution_list.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '1 c-up (target) Left and', ''))
  579.                    
  580.                     if (initial_angle + 0x12C - i*1800)%65536 == angle:
  581.                         cup_solution_list.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '1 c-up (target) Left and', ''))
  582.  
  583.                     if (initial_angle - 0x12C + i*1800)%65536 == angle:
  584.                         cup_solution_list.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '1 c-up (target) Right and', ''))
  585.                    
  586.                     if (initial_angle - 0x12C - i*1800)%65536 == angle:
  587.                         cup_solution_list.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '1 c-up (target) Right and', ''))
  588.                        
  589.                     if (initial_angle + 0x3C0 + i*1800)%65536 == angle:
  590.                         cup_solution_list.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '1 c-up (no target) Left and', ''))
  591.                    
  592.                     if (initial_angle + 0x3C0 - i*1800)%65536 == angle:
  593.                         cup_solution_list.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '1 c-up (no target) Left and', ''))
  594.  
  595.                     if (initial_angle - 0x3C0 + i*1800)%65536 == angle:
  596.                         cup_solution_list.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '1 c-up (no target) Right and', ''))
  597.                    
  598.                     if (initial_angle - 0x3C0 - i*1800)%65536 == angle:
  599.                         cup_solution_list.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '1 c-up (no target) Right and', ''))
  600.  
  601.                     ##### Here I am hard coding in the walls from bomber's hideout to allow which walls you can sidehop into
  602.                    
  603.                     for right_sidehop_angle in right_sidehop_angles((initial_angle - i*1800)%(0x10000), camera_angle):
  604.                        
  605.                         if 0x0000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0x4000:
  606.                        
  607.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0xC000):
  608.                                
  609.                                 sidehop_solution_list.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  610.                                
  611.                         elif 0x4000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0x8000:
  612.                    
  613.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0x4000):
  614.                                
  615.                                 sidehop_solution_list.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  616.                        
  617.                         elif 0x8000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0xC000:
  618.                    
  619.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x8000 or normal_vector_angle == 0x4000):
  620.                                
  621.                                 sidehop_solution_list.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  622.        
  623.                         elif 0xC000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0x10000:
  624.                    
  625.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x8000 or normal_vector_angle == 0xC000):
  626.                                
  627.                                 sidehop_solution_list.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  628.                        
  629.                         ###
  630.                        
  631.                         if 0x0000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0x4000:
  632.                        
  633.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0xC000):
  634.                                
  635.                                 sidehop_solution_list.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  636.                                
  637.                         elif 0x4000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0x8000:
  638.                    
  639.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0x4000):
  640.                                
  641.                                 sidehop_solution_list.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  642.                        
  643.                         elif 0x8000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0xC000:
  644.                    
  645.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x8000 or normal_vector_angle == 0x4000):
  646.                                
  647.                                 sidehop_solution_list.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  648.        
  649.                         elif 0xC000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0x10000:
  650.                    
  651.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x8000 or normal_vector_angle == 0xC000):
  652.                                
  653.                                 sidehop_solution_list.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  654.                        
  655.                 ###### Now Left Sidehops
  656.                    
  657.                     for left_sidehop_angle in left_sidehop_angles((initial_angle - i*1800)%(0x10000), camera_angle):
  658.                        
  659.                         if 0x0000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0x4000:
  660.                        
  661.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x4000 or normal_vector_angle == 0x8000):
  662.                                
  663.                                 sidehop_solution_list.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  664.                                
  665.                         elif 0x4000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0x8000:
  666.                    
  667.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x8000 or normal_vector_angle == 0xC000):
  668.                                
  669.                                 sidehop_solution_list.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  670.                        
  671.                         elif 0x8000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0xC000:
  672.                    
  673.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0xC000):
  674.                                
  675.                                 sidehop_solution_list.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  676.        
  677.                         elif 0xC000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0x10000:
  678.                    
  679.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0x4000):
  680.                                
  681.                                 sidehop_solution_list.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  682.                    
  683.                         ###
  684.                        
  685.                     for left_sidehop_angle in left_sidehop_angles((initial_angle + i*1800)%(0x10000), camera_angle):
  686.                        
  687.                         if 0x0000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0x4000:
  688.                        
  689.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x4000 or normal_vector_angle == 0x8000):
  690.                                
  691.                                 sidehop_solution_list.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  692.                                
  693.                         elif 0x4000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0x8000:
  694.                    
  695.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x8000 or normal_vector_angle == 0xC000):
  696.                                
  697.                                 sidehop_solution_list.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  698.                        
  699.                         elif 0x8000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0xC000:
  700.                    
  701.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0xC000):
  702.                                
  703.                                 sidehop_solution_list.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  704.        
  705.                         elif 0xC000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0x10000:
  706.                    
  707.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0x4000):
  708.                                
  709.                                 sidehop_solution_list.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  710.        
  711.         ##### Now sort and then write to file
  712.        
  713.        
  714.         solution_list.sort(key=sortFirst)
  715.         cup_solution_list.sort(key=sortFirst)
  716.         sidehop_solution_list.sort(key=sortFirst)
  717.        
  718.         file.write("------------------------------------------------------------------------------------------------------------------------ SETUPS USING: initial_angle OR short_chest_angle OR wall angle\n")
  719.         file.write("----- SETUPS WITHOUT c-up OR sidehops\n")
  720.        
  721.         for entry in solution_list:
  722.            
  723.             # if (entry[1] in walk_list) == True:
  724.            
  725.             #file.write("%d = %s is a working initial angle with %d %s ESS turns for goal angle %d = %s\n" %(entry[1], hex(entry[1]), entry[0], entry[3], entry[2], hex(entry[2])))
  726.             file.write("%s is a working initial angle with %s %d %s ESS turns %s for a goal angle of %s which can collide into a wall with normal vector angle %s to get collision angle %s\n" %(hex(entry[1]), entry[6], entry[0], entry[3], entry[7], hex(entry[2]), hex(entry[4]), hex(entry[5])))
  727.        
  728.         file.write("------------------------------------------------------------------------------------------\n")
  729.         file.write("----- SETUPS WITH c-up\n")
  730.        
  731.         for entry in cup_solution_list:
  732.            
  733.             # if (entry[1] in walk_list) == True:
  734.            
  735.             #file.write("%d = %s is a working initial angle with %d %s ESS turns for goal angle %d = %s\n" %(entry[1], hex(entry[1]), entry[0], entry[3], entry[2], hex(entry[2])))
  736.             file.write("%s is a working initial angle with %s %d %s ESS turns %s for a goal angle of %s which can collide into a wall with normal vector angle %s to get collision angle %s\n" %(hex(entry[1]), entry[6], entry[0], entry[3], entry[7], hex(entry[2]), hex(entry[4]), hex(entry[5])))
  737.        
  738.         file.write("------------------------------------------------------------------------------------------\n")
  739.         file.write("----- SETUPS WITH sidehops\n")
  740.        
  741.         for entry in sidehop_solution_list:
  742.            
  743.             # if (entry[1] in walk_list) == True:
  744.            
  745.             #file.write("%d = %s is a working initial angle with %d %s ESS turns for goal angle %d = %s\n" %(entry[1], hex(entry[1]), entry[0], entry[3], entry[2], hex(entry[2])))
  746.             file.write("%s is a working initial angle with %s %d %s ESS turns %s for a goal angle of %s which can collide into a wall with normal vector angle %s to get collision angle %s\n" %(hex(entry[1]), entry[6], entry[0], entry[3], entry[7], hex(entry[2]), hex(entry[4]), hex(entry[5])))
  747.        
  748.         #######################################################################
  749.         #######################################################################
  750.         #######################################################################
  751.         #######################################################################
  752.         #######################################################################
  753.        
  754.        
  755.         #######################################################################
  756.         #######################################################################
  757.         #######################################################################
  758.         #######################################################################
  759.         #######################################################################
  760.    
  761.         for initial_angle in cardinal_list:
  762.            
  763.             print(hex(initial_angle))
  764.            
  765.             if initial_angle > 65535 or initial_angle < 0 or isinstance(initial_angle, int) == False:
  766.                 print('Error: The initial angle is not a valid input')
  767.            
  768.             #for i in range(8192):
  769.             for i in range(Max_ESS_Count):
  770.                 for entry in goal_angle_list:
  771.                    
  772.                     angle = entry[0]
  773.                     normal_vector_angle = entry[1]
  774.                     collision_angle = entry[2]
  775.                    
  776.                     if (initial_angle + i*1800)%65536 == angle:
  777.                         solution_list_cardinal.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', ''))
  778.                        
  779.                     if (initial_angle - i*1800)%65536 == angle:
  780.                         solution_list_cardinal.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', ''))
  781.  
  782.                     if (initial_angle + 0x12C + i*1800)%65536 == angle:
  783.                         cup_solution_list_cardinal.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '1 c-up (target) Left and', ''))
  784.                    
  785.                     if (initial_angle + 0x12C - i*1800)%65536 == angle:
  786.                         cup_solution_list_cardinal.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '1 c-up (target) Left and', ''))
  787.  
  788.                     if (initial_angle - 0x12C + i*1800)%65536 == angle:
  789.                         cup_solution_list_cardinal.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '1 c-up (target) Right and', ''))
  790.                    
  791.                     if (initial_angle - 0x12C - i*1800)%65536 == angle:
  792.                         cup_solution_list_cardinal.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '1 c-up (target) Right and', ''))
  793.                        
  794.                     if (initial_angle + 0x3C0 + i*1800)%65536 == angle:
  795.                         cup_solution_list_cardinal.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '1 c-up (no target) Left and', ''))
  796.                    
  797.                     if (initial_angle + 0x3C0 - i*1800)%65536 == angle:
  798.                         cup_solution_list_cardinal.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '1 c-up (no target) Left and', ''))
  799.  
  800.                     if (initial_angle - 0x3C0 + i*1800)%65536 == angle:
  801.                         cup_solution_list_cardinal.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '1 c-up (no target) Right and', ''))
  802.                    
  803.                     if (initial_angle - 0x3C0 - i*1800)%65536 == angle:
  804.                         cup_solution_list_cardinal.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '1 c-up (no target) Right and', ''))
  805.  
  806.                     ##### Here I am hard coding in the walls from bomber's hideout to allow which walls you can sidehop into
  807.                    
  808.                     for right_sidehop_angle in right_sidehop_angles((initial_angle - i*1800)%(0x10000), camera_angle):
  809.                        
  810.                         if 0x0000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0x4000:
  811.                        
  812.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0xC000):
  813.                                
  814.                                 sidehop_solution_list_cardinal.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  815.                                
  816.                         elif 0x4000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0x8000:
  817.                    
  818.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0x4000):
  819.                                
  820.                                 sidehop_solution_list_cardinal.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  821.                        
  822.                         elif 0x8000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0xC000:
  823.                    
  824.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x8000 or normal_vector_angle == 0x4000):
  825.                                
  826.                                 sidehop_solution_list_cardinal.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  827.        
  828.                         elif 0xC000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0x10000:
  829.                    
  830.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x8000 or normal_vector_angle == 0xC000):
  831.                                
  832.                                 sidehop_solution_list_cardinal.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  833.                        
  834.                         ###
  835.                        
  836.                         if 0x0000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0x4000:
  837.                        
  838.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0xC000):
  839.                                
  840.                                 sidehop_solution_list_cardinal.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  841.                                
  842.                         elif 0x4000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0x8000:
  843.                    
  844.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0x4000):
  845.                                
  846.                                 sidehop_solution_list_cardinal.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  847.                        
  848.                         elif 0x8000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0xC000:
  849.                    
  850.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x8000 or normal_vector_angle == 0x4000):
  851.                                
  852.                                 sidehop_solution_list_cardinal.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  853.        
  854.                         elif 0xC000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0x10000:
  855.                    
  856.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x8000 or normal_vector_angle == 0xC000):
  857.                                
  858.                                 sidehop_solution_list_cardinal.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  859.                        
  860.                 ###### Now Left Sidehops
  861.                    
  862.                     for left_sidehop_angle in left_sidehop_angles((initial_angle - i*1800)%(0x10000), camera_angle):
  863.                        
  864.                         if 0x0000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0x4000:
  865.                        
  866.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x4000 or normal_vector_angle == 0x8000):
  867.                                
  868.                                 sidehop_solution_list_cardinal.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  869.                                
  870.                         elif 0x4000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0x8000:
  871.                    
  872.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x8000 or normal_vector_angle == 0xC000):
  873.                                
  874.                                 sidehop_solution_list_cardinal.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  875.                        
  876.                         elif 0x8000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0xC000:
  877.                    
  878.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0xC000):
  879.                                
  880.                                 sidehop_solution_list_cardinal.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  881.        
  882.                         elif 0xC000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0x10000:
  883.                    
  884.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0x4000):
  885.                                
  886.                                 sidehop_solution_list_cardinal.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  887.                    
  888.                         ###
  889.                        
  890.                     for left_sidehop_angle in left_sidehop_angles((initial_angle + i*1800)%(0x10000), camera_angle):
  891.                        
  892.                         if 0x0000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0x4000:
  893.                        
  894.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x4000 or normal_vector_angle == 0x8000):
  895.                                
  896.                                 sidehop_solution_list_cardinal.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  897.                                
  898.                         elif 0x4000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0x8000:
  899.                    
  900.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x8000 or normal_vector_angle == 0xC000):
  901.                                
  902.                                 sidehop_solution_list_cardinal.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  903.                        
  904.                         elif 0x8000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0xC000:
  905.                    
  906.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0xC000):
  907.                                
  908.                                 sidehop_solution_list_cardinal.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  909.        
  910.                         elif 0xC000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0x10000:
  911.                    
  912.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0x4000):
  913.                                
  914.                                 sidehop_solution_list_cardinal.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  915.        
  916.         ##### Now sort and then write to file
  917.        
  918.        
  919.         solution_list_cardinal.sort(key=sortFirst)
  920.         cup_solution_list_cardinal.sort(key=sortFirst)
  921.         sidehop_solution_list_cardinal.sort(key=sortFirst)
  922.        
  923.         file.write("------------------------------------------------------------------------------------------\n")
  924.         file.write("------------------------------------------------------------------------------------------------------------------------ SETUPS USING: cardinal directions (based on camera_angle)\n")
  925.         file.write("----- SETUPS WITHOUT c-up OR sidehops\n")
  926.        
  927.         for entry in solution_list_cardinal:
  928.            
  929.             # if (entry[1] in walk_list) == True:
  930.            
  931.             #file.write("%d = %s is a working initial angle with %d %s ESS turns for goal angle %d = %s\n" %(entry[1], hex(entry[1]), entry[0], entry[3], entry[2], hex(entry[2])))
  932.             file.write("%s is a working initial angle with %s %d %s ESS turns %s for a goal angle of %s which can collide into a wall with normal vector angle %s to get collision angle %s\n" %(hex(entry[1]), entry[6], entry[0], entry[3], entry[7], hex(entry[2]), hex(entry[4]), hex(entry[5])))
  933.        
  934.         file.write("------------------------------------------------------------------------------------------\n")
  935.         file.write("----- SETUPS WITH c-up\n")
  936.        
  937.         for entry in cup_solution_list_cardinal:
  938.            
  939.             # if (entry[1] in walk_list) == True:
  940.            
  941.             #file.write("%d = %s is a working initial angle with %d %s ESS turns for goal angle %d = %s\n" %(entry[1], hex(entry[1]), entry[0], entry[3], entry[2], hex(entry[2])))
  942.             file.write("%s is a working initial angle with %s %d %s ESS turns %s for a goal angle of %s which can collide into a wall with normal vector angle %s to get collision angle %s\n" %(hex(entry[1]), entry[6], entry[0], entry[3], entry[7], hex(entry[2]), hex(entry[4]), hex(entry[5])))
  943.        
  944.         file.write("------------------------------------------------------------------------------------------\n")
  945.         file.write("----- SETUPS WITH sidehops\n")
  946.        
  947.         for entry in sidehop_solution_list_cardinal:
  948.            
  949.             # if (entry[1] in walk_list) == True:
  950.            
  951.             #file.write("%d = %s is a working initial angle with %d %s ESS turns for goal angle %d = %s\n" %(entry[1], hex(entry[1]), entry[0], entry[3], entry[2], hex(entry[2])))
  952.             file.write("%s is a working initial angle with %s %d %s ESS turns %s for a goal angle of %s which can collide into a wall with normal vector angle %s to get collision angle %s\n" %(hex(entry[1]), entry[6], entry[0], entry[3], entry[7], hex(entry[2]), hex(entry[4]), hex(entry[5])))
  953.        
  954.         #######################################################################
  955.         #######################################################################
  956.         #######################################################################
  957.         #######################################################################
  958.         #######################################################################
  959.        
  960.         #######################################################################
  961.         #######################################################################
  962.         #######################################################################
  963.         #######################################################################
  964.         #######################################################################
  965.    
  966.         for initial_angle in walk_angle_list:
  967.            
  968.             print(hex(initial_angle))
  969.            
  970.             if initial_angle > 65535 or initial_angle < 0 or isinstance(initial_angle, int) == False:
  971.                 print('Error: The initial angle is not a valid input')
  972.            
  973.             #for i in range(8192):
  974.             for i in range(Max_ESS_Count):
  975.                 for entry in goal_angle_list:
  976.                    
  977.                     angle = entry[0]
  978.                     normal_vector_angle = entry[1]
  979.                     collision_angle = entry[2]
  980.                    
  981.                     if (initial_angle + i*1800)%65536 == angle:
  982.                         solution_list_walk.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', ''))
  983.                        
  984.                     if (initial_angle - i*1800)%65536 == angle:
  985.                         solution_list_walk.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', ''))
  986.  
  987.                     if (initial_angle + 0x12C + i*1800)%65536 == angle:
  988.                         cup_solution_list_walk.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '1 c-up (target) Left and', ''))
  989.                    
  990.                     if (initial_angle + 0x12C - i*1800)%65536 == angle:
  991.                         cup_solution_list_walk.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '1 c-up (target) Left and', ''))
  992.  
  993.                     if (initial_angle - 0x12C + i*1800)%65536 == angle:
  994.                         cup_solution_list_walk.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '1 c-up (target) Right and', ''))
  995.                    
  996.                     if (initial_angle - 0x12C - i*1800)%65536 == angle:
  997.                         cup_solution_list_walk.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '1 c-up (target) Right and', ''))
  998.                        
  999.                     if (initial_angle + 0x3C0 + i*1800)%65536 == angle:
  1000.                         cup_solution_list_walk.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '1 c-up (no target) Left and', ''))
  1001.                    
  1002.                     if (initial_angle + 0x3C0 - i*1800)%65536 == angle:
  1003.                         cup_solution_list_walk.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '1 c-up (no target) Left and', ''))
  1004.  
  1005.                     if (initial_angle - 0x3C0 + i*1800)%65536 == angle:
  1006.                         cup_solution_list_walk.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '1 c-up (no target) Right and', ''))
  1007.                    
  1008.                     if (initial_angle - 0x3C0 - i*1800)%65536 == angle:
  1009.                         cup_solution_list_walk.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '1 c-up (no target) Right and', ''))
  1010.  
  1011.                     ##### Here I am hard coding in the walls from bomber's hideout to allow which walls you can sidehop into
  1012.                    
  1013.                     for right_sidehop_angle in right_sidehop_angles((initial_angle - i*1800)%(0x10000), camera_angle):
  1014.                        
  1015.                         if 0x0000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0x4000:
  1016.                        
  1017.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0xC000):
  1018.                                
  1019.                                 sidehop_solution_list_walk.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  1020.                                
  1021.                         elif 0x4000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0x8000:
  1022.                    
  1023.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0x4000):
  1024.                                
  1025.                                 sidehop_solution_list_walk.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  1026.                        
  1027.                         elif 0x8000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0xC000:
  1028.                    
  1029.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x8000 or normal_vector_angle == 0x4000):
  1030.                                
  1031.                                 sidehop_solution_list_walk.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  1032.        
  1033.                         elif 0xC000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0x10000:
  1034.                    
  1035.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x8000 or normal_vector_angle == 0xC000):
  1036.                                
  1037.                                 sidehop_solution_list_walk.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  1038.                        
  1039.                         ###
  1040.                        
  1041.                         if 0x0000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0x4000:
  1042.                        
  1043.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0xC000):
  1044.                                
  1045.                                 sidehop_solution_list_walk.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  1046.                                
  1047.                         elif 0x4000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0x8000:
  1048.                    
  1049.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0x4000):
  1050.                                
  1051.                                 sidehop_solution_list_walk.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  1052.                        
  1053.                         elif 0x8000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0xC000:
  1054.                    
  1055.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x8000 or normal_vector_angle == 0x4000):
  1056.                                
  1057.                                 sidehop_solution_list_walk.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  1058.        
  1059.                         elif 0xC000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0x10000:
  1060.                    
  1061.                             if right_sidehop_angle == angle and (normal_vector_angle == 0x8000 or normal_vector_angle == 0xC000):
  1062.                                
  1063.                                 sidehop_solution_list_walk.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Right Sidehop'))
  1064.                        
  1065.                 ###### Now Left Sidehops
  1066.                    
  1067.                     for left_sidehop_angle in left_sidehop_angles((initial_angle - i*1800)%(0x10000), camera_angle):
  1068.                        
  1069.                         if 0x0000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0x4000:
  1070.                        
  1071.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x4000 or normal_vector_angle == 0x8000):
  1072.                                
  1073.                                 sidehop_solution_list_walk.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  1074.                                
  1075.                         elif 0x4000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0x8000:
  1076.                    
  1077.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x8000 or normal_vector_angle == 0xC000):
  1078.                                
  1079.                                 sidehop_solution_list_walk.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  1080.                        
  1081.                         elif 0x8000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0xC000:
  1082.                    
  1083.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0xC000):
  1084.                                
  1085.                                 sidehop_solution_list_walk.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  1086.        
  1087.                         elif 0xC000 <= (initial_angle - i*1800)%(0x10000) and (initial_angle - i*1800)%(0x10000) < 0x10000:
  1088.                    
  1089.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0x4000):
  1090.                                
  1091.                                 sidehop_solution_list_walk.append((i, initial_angle, angle, 'Right', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  1092.                    
  1093.                         ###
  1094.                        
  1095.                     for left_sidehop_angle in left_sidehop_angles((initial_angle + i*1800)%(0x10000), camera_angle):
  1096.                        
  1097.                         if 0x0000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0x4000:
  1098.                        
  1099.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x4000 or normal_vector_angle == 0x8000):
  1100.                                
  1101.                                 sidehop_solution_list_walk.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  1102.                                
  1103.                         elif 0x4000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0x8000:
  1104.                    
  1105.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x8000 or normal_vector_angle == 0xC000):
  1106.                                
  1107.                                 sidehop_solution_list_walk.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  1108.                        
  1109.                         elif 0x8000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0xC000:
  1110.                    
  1111.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0xC000):
  1112.                                
  1113.                                 sidehop_solution_list_walk.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  1114.        
  1115.                         elif 0xC000 <= (initial_angle + i*1800)%(0x10000) and (initial_angle + i*1800)%(0x10000) < 0x10000:
  1116.                    
  1117.                             if left_sidehop_angle == angle and (normal_vector_angle == 0x0000 or normal_vector_angle == 0x4000):
  1118.                                
  1119.                                 sidehop_solution_list_walk.append((i, initial_angle, angle, 'Left', normal_vector_angle, collision_angle, '', 'and a Left Sidehop'))
  1120.        
  1121.         ##### Now sort and then write to file
  1122.        
  1123.        
  1124.         solution_list_walk.sort(key=sortFirst)
  1125.         cup_solution_list_walk.sort(key=sortFirst)
  1126.         sidehop_solution_list_walk.sort(key=sortFirst)
  1127.        
  1128.         file.write("------------------------------------------------------------------------------------------\n")
  1129.         file.write("------------------------------------------------------------------------------------------------------------------------ SETUPS USING: walk angles (based on camera_angle)\n")
  1130.         file.write("----- SETUPS WITHOUT c-up OR sidehops\n")
  1131.        
  1132.         for entry in solution_list_walk:
  1133.            
  1134.             # if (entry[1] in walk_list) == True:
  1135.            
  1136.             #file.write("%d = %s is a working initial angle with %d %s ESS turns for goal angle %d = %s\n" %(entry[1], hex(entry[1]), entry[0], entry[3], entry[2], hex(entry[2])))
  1137.             file.write("%s is a working initial angle with %s %d %s ESS turns %s for a goal angle of %s which can collide into a wall with normal vector angle %s to get collision angle %s\n" %(hex(entry[1]), entry[6], entry[0], entry[3], entry[7], hex(entry[2]), hex(entry[4]), hex(entry[5])))
  1138.        
  1139.         file.write("------------------------------------------------------------------------------------------\n")
  1140.         file.write("----- SETUPS WITH c-up\n")
  1141.        
  1142.         for entry in cup_solution_list_walk:
  1143.            
  1144.             # if (entry[1] in walk_list) == True:
  1145.            
  1146.             #file.write("%d = %s is a working initial angle with %d %s ESS turns for goal angle %d = %s\n" %(entry[1], hex(entry[1]), entry[0], entry[3], entry[2], hex(entry[2])))
  1147.             file.write("%s is a working initial angle with %s %d %s ESS turns %s for a goal angle of %s which can collide into a wall with normal vector angle %s to get collision angle %s\n" %(hex(entry[1]), entry[6], entry[0], entry[3], entry[7], hex(entry[2]), hex(entry[4]), hex(entry[5])))
  1148.        
  1149.         file.write("------------------------------------------------------------------------------------------\n")
  1150.         file.write("----- SETUPS WITH sidehops\n")
  1151.        
  1152.         for entry in sidehop_solution_list_walk:
  1153.            
  1154.             # if (entry[1] in walk_list) == True:
  1155.            
  1156.             #file.write("%d = %s is a working initial angle with %d %s ESS turns for goal angle %d = %s\n" %(entry[1], hex(entry[1]), entry[0], entry[3], entry[2], hex(entry[2])))
  1157.             file.write("%s is a working initial angle with %s %d %s ESS turns %s for a goal angle of %s which can collide into a wall with normal vector angle %s to get collision angle %s\n" %(hex(entry[1]), entry[6], entry[0], entry[3], entry[7], hex(entry[2]), hex(entry[4]), hex(entry[5])))
  1158.        
  1159.         #######################################################################
  1160.         #######################################################################
  1161.         #######################################################################
  1162.         #######################################################################
  1163.         #######################################################################
  1164.        
  1165.        
  1166.        
  1167.        
  1168.         print("Done.")
  1169.  
  1170.  
  1171.  
  1172. def find_walk_angles(camera_angle):
  1173.    
  1174.     cardinal_list = [(camera_angle - 0xC000)%(0x10000), (camera_angle - 0x8000)%(0x10000), (camera_angle - 0x4000)%(0x10000), camera_angle]
  1175.  
  1176.     for cardinal_angle in cardinal_list:
  1177.         for i in range(5):
  1178.             print('Walking angle ' + hex((cardinal_angle + (i+1)*0xBB8)%(0x10000)) + ' is obtained by walking in cardinal direction ' + hex(cardinal_angle) + ' and walking to Link`s Left for %d frames.' %(i+1))
  1179.             print('Walking angle ' + hex((cardinal_angle - (i+1)*0xBB8)%(0x10000)) + ' is obtained by walking in cardinal direction ' + hex(cardinal_angle) + ' and walking to Link`s Right for %d frames.' %(i+1))
  1180.     return
  1181.  
  1182. def find_walk_angle(camera_angle, walk_angle):
  1183.    
  1184.     """
  1185.    
  1186.    EXAMPLE:
  1187.        
  1188.        find_walk_angle(0x3ddf, 0x1ab7)
  1189.    
  1190.    """
  1191.    
  1192.     cardinal_list = [(camera_angle - 0xC000)%(0x10000), (camera_angle - 0x8000)%(0x10000), (camera_angle - 0x4000)%(0x10000), camera_angle]
  1193.    
  1194.     for cardinal_angle in cardinal_list:
  1195.         for i in range(5):
  1196.            
  1197.             if (cardinal_angle + (i+1)*0xBB8)%(0x10000) == walk_angle:
  1198.                 print('Walking angle ' + hex((cardinal_angle + (i+1)*0xBB8)%(0x10000)) + ' is obtained by walking in cardinal direction ' + hex(cardinal_angle) + ' and walking to Link`s Left for %d frames.' %(i+1))
  1199.             elif (cardinal_angle - (i+1)*0xBB8)%(0x10000) == walk_angle:
  1200.                 print('Walking angle ' + hex((cardinal_angle - (i+1)*0xBB8)%(0x10000)) + ' is obtained by walking in cardinal direction ' + hex(cardinal_angle) + ' and walking to Link`s Right for %d frames.' %(i+1))
  1201.     return
  1202.  
  1203. ###############################################################################
  1204.    
  1205. bomber_normal_vector_angle_list = [0x0000, 0x4000, 0x8000, 0xC000]
  1206.  
  1207. #initial_angle = 0x3880
  1208. #camera_angle = 0x388F
  1209. #short_chest_angle = 0x2DCD
  1210.  
  1211. #initial_angle = 0x3DD1
  1212. #camera_angle = 0x3DDF
  1213. #short_chest_angle = 0x331E
  1214.  
  1215.  
  1216. initial_angle = 0x4258
  1217. camera_angle = 0x4250
  1218. short_chest = 0x4D14
  1219.  
  1220.  
  1221.  
  1222. #initial_angle = 0x38F8
  1223. #camera_angle = 0x38FE
  1224. #short_chest_angle = 0x2E3D
  1225.  
  1226. initial_angle_list = [initial_angle, short_chest_angle, 0x0000, 0x4000, 0x8000, 0xC000]
  1227.  
  1228. name_of_file = "kyle 0x63"
  1229. complete_name = name_of_file + ".txt"  
  1230.  
  1231.  
  1232. ##### UNCOMMENT THIS IF YOU WANT TO DO A BUNCH OF ITEMS AT ONCE
  1233. """
  1234. ### Observatory 1 (plus or minus a few items)
  1235.  
  1236. list_40_bit = ['0x17', '0x07', '0x08', '0x52', '0x0C', '0x33', '0x39', '0x4C', '0x57', '0x2E', '0x4E', '0x25', '0x5A', '0x29', '0x2A', '0x2B', '0x2C']
  1237. list_20_bit = ['0x63', '0x73', '0x6C']
  1238.  
  1239.  
  1240. ### Observatory 2
  1241.  
  1242. #list_40_bit = ['0x52', '0x54', '0x2E']
  1243. #list_20_bit = ['0x24', '0x07', '0x63', '0x4B']
  1244.  
  1245. ###############################################################################
  1246.  
  1247. data_file_name = "data.txt"
  1248.  
  1249. with open(data_file_name, "a") as file:
  1250.    file.write("Initial Angle: " + hex(initial_angle) + "\n")
  1251.    file.write("Camera Angle: " + hex(camera_angle) + "\n")
  1252.    file.write("Short Chest Cutscene Angle: " + hex(short_chest_angle) + "\n")
  1253.    file.write("\n")
  1254.    
  1255.    ### Add walk angles
  1256.    
  1257.    cardinal_list = [(camera_angle - 0xC000)%(0x10000), (camera_angle - 0x8000)%(0x10000), (camera_angle - 0x4000)%(0x10000), camera_angle]
  1258.  
  1259.    for cardinal_angle in cardinal_list:
  1260.        for i in range(5):
  1261.            file.write('Walking angle ' + hex((cardinal_angle + (i+1)*0xBB8)%(0x10000)) + ' is obtained by walking in cardinal direction ' + hex(cardinal_angle) + ' and walking to Link`s Left for %d frames.' %(i+1) + '\n')
  1262.            file.write('Walking angle ' + hex((cardinal_angle - (i+1)*0xBB8)%(0x10000)) + ' is obtained by walking in cardinal direction ' + hex(cardinal_angle) + ' and walking to Link`s Right for %d frames.' %(i+1) + '\n')
  1263.  
  1264.  
  1265.  
  1266. ###############################################################################
  1267.  
  1268. for item in list_40_bit:
  1269.    
  1270.    print("Item Value: " + item)
  1271.    
  1272.    goal_angle_list = find_valid_goal_angles(find_goal_collision_angles_40_bit(item), bomber_normal_vector_angle_list)
  1273.    
  1274.    complete_name = item + ".txt"  
  1275.    
  1276.    find_ranked_collision_solutions(initial_angle_list, camera_angle, goal_angle_list, complete_name)
  1277.  
  1278. for item in list_20_bit:
  1279.    
  1280.    print("Item Value: " + item)
  1281.    
  1282.    goal_angle_list = find_valid_goal_angles(find_goal_collision_angles_20_bit(item), bomber_normal_vector_angle_list)
  1283.  
  1284.    complete_name = item + ".txt"  
  1285.    
  1286.    find_ranked_collision_solutions(initial_angle_list, camera_angle, goal_angle_list, complete_name)
  1287. """
  1288.  
  1289.  
  1290.  
  1291. ##### USE THIS IF YOU WANT TO DO ONE ITEM AT A TIME
  1292.  
  1293. #goal_angle_list = find_valid_goal_angles(find_goal_collision_angles_40_bit('0x17'), bomber_normal_vector_angle_list)
  1294. goal_angle_list = find_valid_goal_angles(find_goal_collision_angles_20_bit('0x63'), bomber_normal_vector_angle_list)
  1295.  
  1296.  
  1297. find_ranked_collision_solutions(initial_angle_list, camera_angle, goal_angle_list, complete_name)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement