def click_inv(slot=0,key='left'):
    '''click on an inventory slot

    Keyword arguments:
    slot -- slot number to click
    key -- mouse key to click'''
    slot_rxy = (slot % 4)*42,(slot // 4)*36
    start_xy = hi.rrg(581,5,570,592),hi.rrg(228,5,218,235)
    hi.human_move_to(sum_i(slot_rxy,start_xy,win_xy))
    hi.human_click(None,key)
def random_point(boxes,gaussian_rand = True):
    '''randomly select a point from a box or list of boxes. chance of choosing a box weighted based on size

    Keywork Arguments:
    boxes -- a box or list of boxes to click in
    gaussian_rand -- use gaussian point spread or evenly spread
    '''
    #Determine pixels per box and total possible pixel choices
    pxl_amnts = [(box[2] - box[0])*(box[3] - box[1]) for box in boxes]
    total_pxls = sum(pxl_amnts)
    
    box_rand = random.uniform(0,1)

    #find selected box
    pxls_checked = 0
    for box_id,pxls in enumerate(pxl_amnts):
        pxls_checked += pxls
        if pxls_checked/total_pxls >= box_rand: #if box chosen

            #return random point in box
            if gaussian_rad:
                return [boxes[box_id][i] + hi.rrg(
                                                             (boxes[box_id][i+2]-boxes[box_id][i])/2, (boxes[box_id][i+2]-boxes[box_id][i])/3, boxes[box_id][i],boxes[box_id][i+2]
                                                             ) for i in range(2)]
            return [boxes[box_id][i] + random.randint(0,boxes[box_id][i+2]-boxes[box_id][i]) for i in range(2)]
def fix_compass():
    '''Adjusts the compass to be north if it is not already.'''
    #if north facing compass pointer not seen
    view = screenshot(compass_box)
    if(match_template(view,compass_im)[1] < 0.985):
        
        click_rxy = [ hi.rrg((compass_box[i]+compass_box[i+2])/2,(compass_box[i]+compass_box[i+2])/3.5,compass_box[i],compass_box[i+2]) for i in range(2)] #where to click relative to center of compass
        hi.human_click(sum_i(win_xy,click_rxy))
    def exec(self,click_box_id=None,error = False):
        '''try to perform click task

        Keyword arguments:
        click_box_id -- the index of the click box that should be use in the list of click boxes
                        or None for random box (default None)
        error -- if fail, raise error instead of return none (default = False)
        '''

        #find reference image location
        if not self.is_positioned():
            return False
        img_xy = self.get_img_xy()
        if img_xy == None:
            return False

        #try to click on right area
        for i in range(5):
            
            box = None
            if click_box_id == None:
                box = self.click_boxes[random.randint(0,len(self.click_boxes)-1)]
            else:
                box = self.click_boxes[click_box_id]
            click_rxy = [ hi.rrg((box[i]+box[i+2])/2,
                                 (box[i]+box[i+2])/3.5,
                                 box[i],
                                 box[i+2]) for i in range(2)]
            
            fix_compass()
            hi.human_move_to(sum_i(win_xy,img_xy,click_rxy))
            if self.action_text == None or get_text_xy(self.action_text,(0,3,450,22)):
                hi.human_click(key=self.key)
                return True
            time.sleep(hi.rrg(0.25,0.1,0.175,2))
        if error:
            raise botException("failed to click")
        return False
def travel_to(xy,area=None,wait_speed=1,max_time=15,return_early=False,readjust=True,error = False):
    '''return if succesfully moved to position xy of area by clicking the minimap 

    Keyword arguments:
    xy -- game area coordinates to move to
    area -- name of player's game area, or None to find name using get_area (default None)
    wait_speed -- time between map clicks (default 0.5)
    max_time -- time before an issue has occured and should return False (default 15.0)
    return_early -- return on last click instead of once in position (default False)
                    using True can cause character to not be perfectly positioned
    readjust -- readjust if not at xy after last click when not returning early
                this can be needed on slower computers or when running
    error -- if fail, raise error instead of return none (default = False)
    '''

    start_time = time.time()
    
    if area==None:
        area = get_area()
    start_xy = get_xy(area)
    
    #click on map till click on proper value
    while not click_on_map(xy,get_xy(area)):
        time.sleep(hi.rrg(4,1,3,5)*wait_speed)
        if(time.time() - start_time > max_time):#return False if taking too long
            break

    else:
        if not return_early:

            wait_to_move(area,5)            
            cur_xy = get_stop_xy(area)
            
            if( cur_xy != xy and readjust): #readjust if not in position
                click_on_map(xy,cur_xy)
                get_stop_xy()
        return True
    return False