async def get_quest_v(self, channel, author, name): """gets a quest by name or id""" if not name: return quest_id = None if str(name).isnumeric(): quest_id = int(name) try: query = QuestTable.select() if quest_id is not None: query = query.where(QuestTable.id == quest_id) query = query.execute() result = [d for d in query] except: return await channel.send("No quest data available!") if quest_id is not None: return None if not result else result[0] quest_names = [q.name.lower() for q in result] if name.lower() not in quest_names: candidates = utils.get_match(quest_names, name, score_cutoff=70, isPartial=True, limit=20) if candidates[0] is None: return None name = await utils.prompt_match_result(self.bot, channel, author, name, candidates) return next((q for q in result if q.name is not None and q.name.lower() == name.lower()), None)
async def check_reward(self, ctx, quest, reward): complete_pool = [] reward = reward.lower().strip() if reward == 'encounter': any_encounter = f"{' or '.join([p.title() for p in quest.reward_pool['encounters']])} Encounter" complete_pool.append(any_encounter) elif 'stardust' in quest.reward_pool and reward in [ 'stardust', 'dust' ]: if len(quest.reward_pool['stardust']) > 0: r = f"{quest.reward_pool['stardust'][0]} stardust" complete_pool.append(r) else: if 'encounters' in quest.reward_pool: for e in quest.reward_pool['encounters']: complete_pool.append(e) if 'items' in quest.reward_pool: for item in quest.reward_pool['items']: r = f"{quest.reward_pool['items'][item][0]} {item}" complete_pool.append(r) candidates = utils.get_match(complete_pool, reward.strip(), score_cutoff=70, isPartial=True, limit=5) if candidates[0] is None: return None reward = await utils.prompt_match_result(self.bot, ctx.channel, ctx.message.author.id, reward, candidates) return reward
async def check_boss_cp(image, bot): height, width = image.shape maxy = round(height * .32) miny = round(height * .15) maxx = round(width * .84) minx = round(width * .16) gym_name_crop = image[miny:maxy, minx:maxx] gym_name_crop = cv2.bitwise_not(gym_name_crop) vals = [30, 40, 20] # This doesn't fully handle Alolan forms # For example, in one particular screenshot of an Alolan Marowak no boss was ever identified. # The img_text contained 'Marowak' but fuzzy match threshold was too high for that to match # Cut off can't be lower or else other issues arise (houndoom instead of absol for example) # Additionally, no match was ever made on the CP value as it never got a clear read. # Likely need to refactor this so that if an alolan species is read in, additional scans are made # To try and pick up the CP and make sure we have the right form for t in vals: thresh = cv2.threshold(gym_name_crop, t, 255, cv2.THRESH_BINARY)[1] thresh = cv2.GaussianBlur(thresh, (5, 5), 0) img_text = pytesseract.image_to_string(thresh, lang='eng', config='--psm 4') img_text = [ s for s in list(filter(None, img_text.split())) if len(s) > 3 ] if len(img_text) > 1: match = utils.get_match(bot.boss_list, img_text[1], score_cutoff=70) if match and match[0]: return match[0] if len(img_text) > 0: match = utils.get_match(list(raid_cp_list), img_text[0], score_cutoff=70) if match and match[0]: return raid_cp_chart[match[0]] for i in img_text: match = utils.get_match(bot.boss_list, i, score_cutoff=70) if match and match[0]: return match[0] match = utils.get_match(list(raid_cp_list), i, score_cutoff=70) if match and match[0]: return raid_cp_chart[match[0]] return None
def location_match(name, locations, threshold=75, is_partial=True, limit=None): match = utils.get_match([l.name for l in locations], name, threshold, is_partial, limit) if not isinstance(match, list): match = [match] return [(l, score) for l in locations for match_name, score in match if l.name == match_name]
def get_pokemon(cls, bot, argument, guild=None): argument = argument.lower() if 'shiny' in argument: shiny = True argument = argument.replace('shiny', '').strip() else: shiny = False if 'alolan' in argument: alolan = True argument = argument.replace('alolan', '').strip() else: alolan = False form = None detected_forms = [] form_check = None # this logic will fail for pokemon with multiple word name (e.g. Tapu Koko et al) arg_split = argument.split() candidates = [f for f in Pokemon._form_list if f in arg_split] for c in candidates: detected_forms.append(c) argument = argument.replace(c, '').strip() arg_split = argument.split() p_obj = None if arg_split: if len(arg_split) > 1: if 'unown' == arg_split[1] or 'spinda' == arg_split[1]: if arg_split[0] in Pokemon._form_dict[arg_split[1]]: detected_forms.append(arg_split[0]) p_obj = Pokemon.find_obj(arg_split[1].strip(',')) if not p_obj: if len(arg_split) > 0: p_obj = Pokemon.find_obj(arg_split[0].strip(',')) if not p_obj: pkmn_list = [p for p in Pokemon.get_pkmn_dict()] match = utils.get_match(pkmn_list, argument, score_cutoff=80)[0] else: match = p_obj['name'] if not match: return None form_list = Pokemon._form_dict.get(match, []) forms = [d for d in detected_forms if d in form_list] if forms: form = ' '.join(forms) return cls(bot, str(match), guild, shiny=shiny, alolan=alolan, form=form)
async def _parse_subscription_content(self, content, source, message=None): channel = message.channel author = message.author sub_list = [] error_list = [] raid_level_list = [str(n) for n in list(range(1, 6))] sub_type, target = content.split(' ', 1) if sub_type == 'gym': if message: channel = message.channel guild = message.guild gyms = self._get_gyms(guild.id) if gyms: gym_dict = {} for t in target.split(','): location_matching_cog = self.bot.cogs.get( 'LocationMatching') gym = await location_matching_cog.match_prompt( channel, author.id, t, gyms) if gym: if source == 'add': question_spec = 'would you like to be notified' else: question_spec = 'would you like to remove notifications' level = await utils.ask_list( self.bot, f"For {gym.name} which level raids {question_spec}?", channel, ['All'] + list(range(1, 6)), user_list=[author.id], multiple=True) if level: if 'All' in level: level = list(range(1, 6)) for l in level: gym_level_dict = gym_dict.get( l, { 'ids': [], 'names': [] }) gym_level_dict['ids'].append(gym.id) gym_level_dict['names'].append(gym.name) gym_dict[l] = gym_level_dict else: error_list.append(t) else: error_list.append(t) for l in gym_dict.keys(): entry = f"L{l} Raids at {', '.join(gym_dict[l]['names'])}" sub_list.append(('gym', l, entry, gym_dict[l]['ids'])) return sub_list, error_list if sub_type == 'item': result = RewardTable.select(RewardTable.name, RewardTable.quantity) result = result.objects(Reward) results = [o for o in result] item_names = [r.name.lower() for r in results] targets = target.split(',') for t in targets: candidates = utils.get_match(item_names, t, score_cutoff=60, isPartial=True, limit=20) name = await utils.prompt_match_result(self.bot, channel, author.id, t, candidates) if name is not None: sub_list.append((sub_type, name, name)) else: error_list.append(t) return sub_list, error_list if sub_type == 'wild': perfect_pattern = r'((100(\s*%)?|perfect)(\s*ivs?\b)?)' target, count = re.subn(perfect_pattern, '', target, flags=re.I) if count: sub_list.append((sub_type, 'perfect', 'Perfect IVs')) if sub_type == 'lure': result = LureTypeTable.select(LureTypeTable.name) result = result.objects(Lure) results = [o for o in result] lure_names = [r.name.lower() for r in results] targets = target.split(',') for t in targets: candidates = utils.get_match(lure_names, t, score_cutoff=60, isPartial=True, limit=20) name = await utils.prompt_match_result(self.bot, channel, author.id, t, candidates) if name is not None: sub_list.append((sub_type, name, name)) else: error_list.append(t) return sub_list, error_list if ',' in target: target = set([t.strip() for t in target.split(',')]) else: target = set([target]) if sub_type == 'raid': selected_levels = target.intersection(raid_level_list) for level in selected_levels: entry = f'L{level} Raids' target.remove(level) sub_list.append((sub_type, level, entry)) ex_pattern = r'^(ex([- ]*eligible)?)$' ex_r = re.compile(ex_pattern, re.I) matches = list(filter(ex_r.match, target)) if matches: entry = 'EX-Eligible Raids' for match in matches: target.remove(match) sub_list.append((sub_type, 'ex-eligible', entry)) remaining_list = [str(n) for n in list(range(6, 800))] other_numbers = target.intersection(remaining_list) for num in other_numbers: target.remove(num) error_list.append(num) for name in target: pkmn = Pokemon.get_pokemon(self.bot, name) if pkmn: sub_list.append((sub_type, pkmn.name, pkmn.name)) else: error_list.append(name) return sub_list, error_list