async def raise_dice(self, m): char = self.get_player_char(m.author.id) dice = m.content[9:].split(' ') try: test = [int(d) for d in dice] except: raise FeedbackError( "Invalid values. Syntax is, for example, `dq raise 4 5`.") if len(dice) > 2: raise FeedbackError("You must raise with one or two values.") cdice = char.dice try: for d in dice: cdice.remove(d) except: raise FeedbackError( "You don't have those values in your dice pool!") char.dice = cdice vstring = ' and '.join(dice) await m.reply( f"Raised with {vstring}!\n\n{char.print_list(char.dice_list,'DicePool')}", mention_author=False)
async def call(self, m): char = self.get_player_char(m.author.id) dice = m.content[8:].split(' ') try: test = [int(d) for d in dice] except: raise FeedbackError( "Invalid values. Syntax is, for example, `dq call 4 5`.") cdice = char.dice try: for d in dice: cdice.remove(d) except: raise FeedbackError( "You don't have those values in your dice pool!") char.dice = cdice vstring = str(sum(test)) if len(dice) < 2: reply = f"Counter! Use {vstring} as one of your dice on your next raise." elif len(dice) < 3: reply = f"Called with {vstring}!\nBlock or Dodge!" else: reply = f"Called with {vstring}!\nHit! Take {len(dice)} consequence dice!" reply = f"```js\n{reply}\n\nDicePool:\n{char.dice_list}```" await m.reply(reply, mention_author=False)
async def roll_consequences(self, m): char = self.get_player_char(m.author.id) cqs = char.consequences if len(cqs) < 1: raise FeedbackError("There are consequences in your pool!") reply = ["Rolled your consequence pool!", '', "```js"] ones = 0 two = [0, 0] for c in cqs: amt, die = self.parse_dice(c[1]) rolls = self.r(amt, die) two = sorted(rolls + two, key=lambda x: 0 - x)[:2] ones += rolls.count(1) reply += [ f"{c[2]} ({amt}d{die}): {','.join([str(r) for r in rolls])}" ] reply += ['', f"{str(two[0]+two[1])} = {two[0]} + {two[1]}"] if ones: reply += [f"Rolled {str(ones)} one[s]!"] reply += ["```"] char.clear_consequences() await m.reply("\n".join(reply), mention_author=False)
def get_player_char(self, pid): c = next((char for char in self.characters if char.player and int(char.player) == int(pid)), None) if c: return c raise FeedbackError( "Set your character first! (`dq set char [their name]`)")
def parse_dice(self, dice): try: amt, die = dice.split('d') amt = int(amt) die = int(die) if amt < 1 or die < 1: raise except Exception as e: raise FeedbackError("Invalid roll!") return amt, die
def select_consequence(self, c): if len(c) == 1: c = next((con for con in self.consequences if con[0] == c), None) else: c = next((con for con in self.consequences if con[2].lower().startswith(c.lower())), None) if c: return c raise FeedbackError("Couldn't find that consequence")
def select_move(self, c): if len(c) == 1: m = next((con for con in self.moves if con[0] == c), None) else: m = next((con for con in self.moves if con[2].lower().startswith(c.lower())), None) if m: return m raise FeedbackError("Couldn't find that move")
async def view_dpools(self, m): chars = [c for c in self.characters if len(c.dice)] if not len(chars): raise FeedbackError("No dice pools are active.") reply = ["```js", '_'] for c in chars: reply += [c.name + ':', c.dice_list] reply += ["```"] await m.reply("\n".join(reply), mention_author=False)
async def minus(self, m): char = self.get_player_char(m.author.id) dice = m.content[5:].split(' ') try: test = [int(d) for d in dice] except: raise FeedbackError( "Invalid values. Syntax is, for example, `dq - 4 5`.") cdice = char.dice try: for d in dice: cdice.remove(d) except: raise FeedbackError( "You don't have those values in your dice pool!") char.dice = cdice await m.reply( f"Removed!\n\n{char.print_list(char.dice_list,'DicePool')}", mention_author=False)
async def roll_move(self, m): char = self.get_player_char(m.author.id) move = char.select_move(m.content[8:]) if move[3] == 1: raise FeedbackError("That move has been used already!") amt, die = self.parse_dice(move[1]) rolls = [str(r) for r in self.r(amt, die)] char.set_move_as_used(move) await m.reply( f"Rolled {move[2]} ({amt}d{die}):\n`{', '.join(rolls)}`\n\n{char.print_list(char.move_list,'Moves')}", mention_author=False)
def select_char(self, indicator): if len(indicator) == 1: c = next( (char for char in self.characters if char.char_id == indicator), None) else: c = next((char for char in self.characters if char.name.lower().startswith(indicator.lower())), None) if c: return c raise FeedbackError("Couldn't find that character")
def add_move(self, c): dice = 'd'.join(str(d) for d in self.bot.parse_dice(c.split(' ')[0])) if not len(c.split(' ')) > 1: raise FeedbackError( "You must include a label for your move! eg, `dq +m 2d6 Body`") c = c[c.index(' ') + 1:] char_id = self.bot.get_next_char_id('moves', self.db_id) cursor = self.bot.db.cursor() cursor.execute( "INSERT INTO moves(name, dice, char_id, character_id, used) VALUES (?,?,?,?,0)", [self.clean_string(c), dice, char_id, self.db_id]) self.bot.db.commit() cursor.close()
def get_next_char_id(self, table="characters", character_id=None): chars = string.ascii_uppercase + string.ascii_lowercase if table == "characters": cur = self.db.execute( "SELECT char_id FROM characters WHERE active = 1 ORDER BY char_id" ) if table == "consequences": cur = self.db.execute( "SELECT char_id FROM consequences WHERE character_id = ? ORDER BY char_id", [character_id]) if table == "moves": cur = self.db.execute( "SELECT char_id FROM moves WHERE character_id = ? ORDER BY char_id", [character_id]) char_ids = [c[0] for c in cur.fetchall()] cur.close() for char in chars: if char not in char_ids: return char raise FeedbackError("Too many active " + table + "!")
async def clear(self, m): for command, method in self.clear_commands: if m.content[9:] == command: await method(m) return raise FeedbackError("Clear what? (dpools/cpools/pools)")