async def remove(self, ctx, *, arg): '''Removes N tokens from the bag''' r = re.match(r'([0-9]+) (.+)$', arg) if not r: raise ArgumentParsingError( "Must be of the format `number token_name`") token = r.group(2) count = int(r.group(1)) if self.init_tracker is None: await ctx.send(NO_INIT_TRACKER_MESSAGE) return in_bag = self.init_tracker.count_token(token) removed = self.init_tracker.remove_token(token, count) if removed < count: await ctx.send( f"You asked to remove {count} {token} tokens, but only {removed} were in the bag (0 left)" ) elif removed < in_bag: await ctx.send( f"Removed {removed} {token} tokens from the bag ({in_bag - removed} left)" ) else: await ctx.send( f"Removed all {removed} {token} tokens from the bag (0 left)")
async def convert(cls, ctx, argument): parsed_time = { _UNITS.get(m.group('unit').lower(), 'seconds'): int(m.group('val')) for m in _TIMEREG.finditer(argument) } if not parsed_time: raise ArgumentParsingError( f'Could not parse "{argument}" to a valid time.') return cls(**parsed_time)
async def cast(self, ctx, *, spell_str: str): r = re.match(r'([0-9]+)[ ]?(.+)?', spell_str) if not r: raise ArgumentParsingError("Usage: skill_points [spell_name]") skill_points: int = int(r.group(1)) spell: Optional[Spell] = None if r.group(2): library = self.bot.get_cog('LibraryCog') spell = library.lookup_spell(r.group(2)) # Look up spell in the library roll = dice.roll_under(skill_points) embed = EmbedSpell(ctx, spell=spell, cast=roll) await ctx.send(embed=embed)
async def weapon(self, ctx, *, arg): weapon_regex = r'([^0-9]+) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)( ignore)?$' r = re.match(weapon_regex, arg) if not r: raise ArgumentParsingError("Argument should be `weapon name 1 2 3 4 5 6 7 [ignore]`") weapon_name = r.group(1) damage_table = [int(r.group(2)), int(r.group(3)), int(r.group(4)), int(r.group(5)), int(r.group(6)), int(r.group(7)), int(r.group(8))] ignore_armor = r.group(9) is not None weapon = Weapon(damage_table, name=weapon_name, ignore_armor=ignore_armor) library = self.bot.get_cog('LibraryCog') library.add_temp_weapon(weapon) await ctx.send(f"Added weapon `{weapon_name}` damage `{damage_table}` ignore_armor={ignore_armor}")
async def _parse_translate_argument( context: Context, raw_argument: str ) -> Optional[Union[DeeplApiLanguage, discord.Member]]: raw_argument = raw_argument.upper() try: return DeeplApiLanguage(raw_argument) except ValueError: pass try: converter: MemberConverter = MemberConverter() member: discord.Member = await converter.convert(context, raw_argument) return member except Exception as e: print(f"{e!r}") raise ArgumentParsingError( f"Could not parse {raw_argument} as a language or member")
async def add(self, ctx, *, arg): if self.init_tracker is None: await ctx.send(NO_INIT_TRACKER_MESSAGE) return tokens = re.findall(r'([0-9]+) ([^0-9]+)', arg) if tokens == []: raise ArgumentParsingError( 'Argument should be of the form "NUM Token NUM Token"') output_string = "" for (count, token) in tokens: try: count = int(count) token = token.rstrip() self.init_tracker.add_token(token, count) output_string += f"Added {count} {token} tokens.\n" except Exception as e: print(e) output_string = f"Unable to parse: {arg}" await ctx.send(output_string)
async def convert(cls, ctx, argument): try: return cls.from_str(argument) except ValueError: raise ArgumentParsingError( f'Could not parse "{argument}" to a valid date.')
async def damage(self, ctx, *, arg_str): # DEFINE REGEXPS DAMAGE_REGEXP_TWO_INTS = re.compile("(.+) ([+-]?[0-9]+) ([+-]?[0-9]+)") DAMAGE_REGEXP_BONUS_ONLY = re.compile("(.+) ([+-]?[0-9]+)") DAMAGE_REGEXP_ARMOR_BONUS = re.compile( f"(.+) {ARMOR_REGEXP_STRING} ([+-]?[0-9]+)", flags=re.IGNORECASE) DAMAGE_REGEXP_ARMOR = re.compile(f"(.+) ({ARMOR_REGEXP_STRING})", flags=re.IGNORECASE) DAMAGE_REGEXP_NONE = re.compile("(.+)") # initialize regexp_matched = False armor = '' bonus = 0 # weapon, armor offset, bonus offset match = DAMAGE_REGEXP_TWO_INTS.match(arg_str) if match: regexp_matched = True weapon_name = match.group(1) armor = match.group(2) bonus = int(match.group(3)) match = DAMAGE_REGEXP_ARMOR_BONUS.match(arg_str) if not regexp_matched and match: regexp_matched = True weapon_name = match.group(1) armor = match.group(2) bonus = int(match.group(3)) match = DAMAGE_REGEXP_ARMOR.match(arg_str) if not regexp_matched and match: regexp_matched = True weapon_name = match.group(1) armor = match.group(2) bonus = 0 match = DAMAGE_REGEXP_BONUS_ONLY.match(arg_str) if not regexp_matched and match: regexp_matched = True weapon_name = match.group(1) armor = "No" bonus = int(match.group(2)) match = DAMAGE_REGEXP_NONE.match(arg_str) if not regexp_matched and match: regexp_matched = True weapon_name = match.group(1) armor = "No" bonus = 0 if not regexp_matched: raise ArgumentParsingError( "Unable to parse the inputs. Please check what you wrote.") library = self.bot.get_cog('LibraryCog') weapon = library.lookup_weapon(weapon_name) if weapon is None: raise BadArgument( f"Unable to find a weapon definition for `{weapon_name}`. Check your spelling?" ) embed = EmbedDamage(ctx, weapon, armor, bonus) await ctx.send(embed=embed)
async def roll(self, ctx, *, query: str): """Rolls the dice""" CHARACTER_REGEXP = re.compile("char(acter)?( [^0-9][^ ]*)?( [0-9]+)?") D2_REGEXP = re.compile("1?d2([+-][0-9]+)?$") D3_REGEXP = re.compile("1?d3([+-][0-9]+)?$") D6_REGEXP = re.compile("1?d6([+-][0-9]+)?$") TWO_D6_REGEXP = re.compile("2d6([+-][0-9]+)?$") D20_REGEXP = re.compile("1?d20([+-][0-9]+)?$") D66_REGEXP = re.compile("d66$") # initialize regexp_matched = False modifier = 0 match = CHARACTER_REGEXP.match(query) if match: if match.group(2): key = match.group(2).lstrip() else: key = 'base' if match.group(3): bg_roll = int(match.group(3).lstrip()) else: bg_roll = dice.roll_d66() regexp_matched = True library = self.bot.get_cog('LibraryCog') compendium = library.find_compendium(key) if compendium: background = compendium.lookup_background(bg_roll) if background: character = Character.generate(compendium, background) embed = EmbedCharacter(ctx, character) await ctx.send(embed=embed) else: await ctx.send( "BACKGROUND d66 = `{bg_roll}`\n_No background found..._" ) else: await ctx.send(f"No compendium found for `{key}`") match = D66_REGEXP.match(query) if match: regexp_matched = True total = dice.roll_d66() await ctx.send(f"d66 = `{total}`") match = D2_REGEXP.match(query) if not regexp_matched and match: regexp_matched = True roll = dice.roll_d2() if match.group(1): modifier = int(match.group(1)) await ctx.send( f"d2 ({roll}){modifier_string(modifier)} = `{roll+modifier}`") match = D3_REGEXP.match(query) if not regexp_matched and match: regexp_matched = True roll = dice.roll_d3() if match.group(1): modifier = int(match.group(1)) await ctx.send( f"d3 ({roll}){modifier_string(modifier)} = `{roll+modifier}`") match = D6_REGEXP.match(query) if not regexp_matched and match: regexp_matched = True roll = dice.roll_d6() if match.group(1): modifier = int(match.group(1)) await ctx.send( f"d6 ({roll}){modifier_string(modifier)} = `{roll+modifier}`") match = TWO_D6_REGEXP.match(query) if not regexp_matched and match: regexp_matched = True r1, r2, total = dice.roll_2d6() if match.group(1): modifier = int(match.group(1)) await ctx.send( f"2d6 ({r1}+{r2}){modifier_string(modifier)} = `{total+modifier}`" ) match = D20_REGEXP.match(query) if not regexp_matched and match: regexp_matched = True roll = dice.roll_d20() if match.group(1): modifier = int(match.group(1)) await ctx.send( f"d20 ({roll}){modifier_string(modifier)} = `{roll+modifier}`") if not regexp_matched: raise ArgumentParsingError( f"Unable to understand your command: `{query}`")