async def force_trade(ctx, *, arg): global sess, sheet, client if sess == None or sess.phase != 2: return sets = [x.strip() for x in arg.split(',')] if len(sets) < 2: await ctx.send( 'Please input a second set. (\">propose_trade set1, set2\")') return set1 = utils.code_to_name(sets[0]) set2 = utils.code_to_name(sets[1]) if set1 not in sess.taken: await ctx.send(f'Invalid trade. No one has taken {set1} yet.') return if set2 not in sess.taken: await ctx.send(f'Invalid trade. No one has taken {set2} yet.') return p1_pindex = utils.name_to_pindex(sess, sess.taken[set1]) player1 = sess.players[p1_pindex] p2_pindex = utils.name_to_pindex(sess, sess.taken[set2]) player2 = sess.players[p2_pindex] p1_can_have_s2 = utils.check_legality(sess, player1, set2, trade_sets=(set1, set2)) p2_can_have_s1 = utils.check_legality(sess, player2, set1, trade_sets=(set1, set2)) if not (p1_can_have_s2 and p2_can_have_s1): await ctx.send('The trade is invalid.') return sess.taken[set2] = player1.name sess.taken[set1] = player2.name player1.sets.remove(set1) player2.sets.remove(set2) player1.sets.add(set2) player2.sets.add(set1) client.login() ws = sheet.worksheet(sess.name) set1_cells = ws.findall(set1) set2_cells = ws.findall(set2) for cell in set1_cells: ws.update_cell(cell.row, cell.col, set2) for cell in set2_cells: ws.update_cell(cell.row, cell.col, set1) await ctx.send('The trade has been accepted and processed.')
async def propose_trade(ctx, *, arg): global sess if sess == None or sess.phase != 2: return sets = [x.strip() for x in arg.split(',')] if len(sets) < 2: await ctx.send( 'Please input a second set. (\">propose_trade set1, set2\")') return set1 = utils.code_to_name(sets[0]) set2 = utils.code_to_name(sets[1]) p1_pindex = utils.uid_to_pindex(sess, ctx.author.id) player1 = sess.players[p1_pindex] if set1 not in player1.sets: await ctx.send(f'Invalid trade. You do not have {set1}.') return if set2 not in sess.taken: await ctx.send(f'Invalid trade. No one has taken {set2} yet.') return p2_pindex = utils.name_to_pindex(sess, sess.taken[set2]) player2 = sess.players[p2_pindex] trade_message = await ctx.send( f'[{player1.name}] offers [{set1}] for [{set2}] \n \ {ctx.guild.get_member(player2.uid).mention}, please accept or deny this trade by reacting to this message.' ) await trade_message.add_reaction('\N{THUMBS UP SIGN}') await trade_message.add_reaction('\N{THUMBS DOWN SIGN}')
async def player_sets(ctx, name: str): global sess if sess == None or sess.phase < 2: return pindex = utils.name_to_pindex(sess, name) owned = sess.players[pindex].sets await ctx.send(f"{name}'s sets: {owned}")
async def force_choose_set(ctx, *, arg): global sess, sheet, client if sess == None or sess.phase != 2: return arg_list = [x.strip() for x in arg.split(',')] user_name = arg_list[0] set_name = arg_list[1] pindex = utils.name_to_pindex(sess, user_name) if pindex != sess.curr_player: await ctx.send("It is not that player's turn.") return chosen_set = utils.code_to_name(set_name) if chosen_set not in sess.sets: await ctx.send(f'{chosen_set} is not a legal set.') return player = sess.players[pindex] if not utils.check_legality(sess, player, chosen_set): if chosen_set in sess.taken.keys(): owner_name = sess.taken[chosen_set] owner_pindex = utils.name_to_pindex(sess, owner_name) owner = ctx.guild.get_member(sess.players[owner_pindex].uid) await ctx.send(f'Sorry, that set is taken by {owner.mention}.') else: await ctx.send( f'Sorry, the set exclusion rule prevents that player from taking {chosen_set}.' ) return sess.taken[chosen_set] = player.name player.sets.add(chosen_set) client.login() utils.update_gsheet(sess, sheet, player.name, chosen_set) await ctx.send('Choice accepted.') phase_over = utils.increment_curr_player(sess) if phase_over: await ctx.send('Set draft complete. Enjoy your matches!') return next_player = sess.players[sess.curr_player] next_player = ctx.guild.get_member(sess.players[sess.curr_player].uid) await ctx.send( f'{next_player.mention} please choose a set. (\">choose_set x\")')
async def choose_set(ctx, *, arg): global sess, sheet, client if sess == None or sess.phase != 2: return pindex = utils.uid_to_pindex(sess, ctx.author.id) if pindex != sess.curr_player: await ctx.send('It is not your turn.') return set_name = arg chosen_set = utils.code_to_name(set_name) if chosen_set not in sess.sets: await ctx.send(f'{chosen_set} is not a legal set.') return player = sess.players[pindex] if not utils.check_legality(sess, player, chosen_set): if chosen_set in sess.taken.keys(): owner_name = sess.taken[chosen_set] owner_pindex = utils.name_to_pindex(sess, owner_name) owner = ctx.guild.get_member(sess.players[owner_pindex].uid) await ctx.send(f'Sorry, that set is taken by {owner.mention}.') else: await ctx.send( f'Sorry, the set exclusion rule prevents you from taking {chosen_set}.' ) return sess.taken[chosen_set] = player.name player.sets.add(chosen_set) client.login() utils.update_gsheet(sess, sheet, player.name, chosen_set) # TODO: WRITE DATA TO JSON FILE FOR THE SETS VISUALIZER GUI IF WE WANT BOT TO HOST utils.update_picks_file(player.name, chosen_set) # # # # # # # # # # # # # # # # await ctx.send('Choice accepted.') phase_over = utils.increment_curr_player(sess) if phase_over: # Move to phase 3 sess.phase = 3 await ctx.send('Set draft complete. Enjoy your matches!') return next_player = sess.players[sess.curr_player] next_player = ctx.guild.get_member(sess.players[sess.curr_player].uid) await ctx.send( f'{next_player.mention} please choose a set. (\">choose_set x\")')
async def claim_user(ctx, *, arg): global sess if sess == None or sess.phase != 0: return name = arg pindex = utils.name_to_pindex(sess, name) if pindex == 'Not found.': return player = sess.players[pindex] if player.uid == -1: player.uid = ctx.author.id await ctx.send(f'Successfully claimed {name}.') else: await ctx.send('Sorry this user has already been claimed.')
async def on_reaction_add(reaction, user): global sess, sheet, client #check that it is reacted by the right person, is valid, and process it message = reaction.message if not message.mentions: return is_reactor_p2 = (user.id == message.mentions[0].id) is_valid_reaction = (reaction.emoji == '\N{THUMBS UP SIGN}' or reaction.emoji == '\N{THUMBS DOWN SIGN}') is_trade_post = any(r.me for r in message.reactions) if not (is_reactor_p2 and is_valid_reaction and is_trade_post): return channel = reaction.message.channel brackets = [ p.split(']')[0] for p in message.content.split('[') if ']' in p ] player1 = sess.players[utils.name_to_pindex(sess, brackets[0])] player2 = sess.players[utils.uid_to_pindex(sess, user.id)] set1 = brackets[1] set2 = brackets[2] p1_member = channel.guild.get_member(player1.uid) trade_string = f'{p1_member.mention} your trade offer of [{set1}] for [{set2}]' if reaction.emoji == '\N{THUMBS UP SIGN}': p1_has_s1 = set1 in player1.sets p2_has_s2 = set2 in player2.sets p1_can_have_s2 = utils.check_legality(sess, player1, set2, trade_sets=(set1, set2)) p2_can_have_s1 = utils.check_legality(sess, player2, set1, trade_sets=(set1, set2)) if not (p1_has_s1 and p2_has_s2 and p1_can_have_s2 and p2_can_have_s1): await message.delete() await channel.send(trade_string + ' is invalid.') else: sess.taken[set2] = player1.name sess.taken[set1] = player2.name player1.sets.remove(set1) player2.sets.remove(set2) player1.sets.add(set2) player2.sets.add(set1) client.login() ws = sheet.worksheet(sess.name) set1_cells = ws.findall(set1) set2_cells = ws.findall(set2) for cell in set1_cells: ws.update_cell(cell.row, cell.col, set2) for cell in set2_cells: ws.update_cell(cell.row, cell.col, set1) # We have to do the same thing now to our json file: utils.trade_picks_file(player1.name, set1, player2.name, set2) # # # # # # # # # # # # # # # await message.delete() await channel.send(trade_string + ' has been accepted and processed.') if reaction.emoji == '\N{THUMBS DOWN SIGN}': await message.delete() await channel.send(trade_string + ' has been declined.')
async def choose_position(ctx, pos: int): global sess, sheet, client if sess == None or sess.phase != 1: return if utils.uid_to_pindex(sess, ctx.author.id) != sess.curr_player: await ctx.send('It is not your turn.') return if pos < 1 or pos > len(sess.players): await ctx.send('Invalid position.') return pos_index = pos - 1 if sess.pick_draft[pos_index] == None: sess.pick_draft[pos_index] = sess.players[sess.curr_player].name await ctx.send('Choice accepted.') sess.curr_player += 1 if sess.curr_player == len(sess.players) - 1: #Make last player choose the remaining position for i, p in enumerate(sess.pick_draft): if not p: last_pos = i break sess.pick_draft[last_pos] = sess.players[sess.curr_player].name #Reorder players new_order = [ utils.name_to_pindex(sess, n) for n in sess.pick_draft ] sess.players = [sess.players[i] for i in new_order] #Setup the session's Google worksheet num_players = len(sess.players) total_picks = num_players * sess.num_picks num_rows = 1 + total_picks # 1 header row + num of total picks num_cols = 7 + num_players # 4 cols for picks + 3 spacer + player sets client.login() ws = sheet.add_worksheet(title=sess.name, rows=num_rows, cols=num_cols) ws.update_cell(1, 1, 'Round') ws.update_cell(1, 2, 'Pick') ws.update_cell(1, 3, 'Player') ws.update_cell(1, 4, 'Set') round_list = ws.range(f'A2:A{total_picks + 1}') pick_list = ws.range(f'B2:B{total_picks + 1}') player_list = ws.range(f'C2:C{total_picks + 1}') # TODO: Go back and clean this b/c the 1-indexing is unnecessary now for i in range(1, total_picks + 1): round_num = math.ceil(i / num_players) round_list[i - 1].value = round_num pick_list[i - 1].value = i next_pindex = (i - 1) % num_players if round_num % 2 == 0: next_pindex = -(next_pindex + 1) player_list[i - 1].value = sess.players[next_pindex].name ws.update_cells(round_list) ws.update_cells(pick_list) ws.update_cells(player_list) for i in range(num_players): ws.update_cell(1, i + 8, sess.players[i].name) # Move to phase 2 sess.phase = 2 sess.curr_player = 0 # CREATE EMPTY PICKS FILE: FACILITATES AUTOMATED WEB GUI utils.make_empty_picks_file(sess.players) # # # # # # # # # # # # # # # # # await ctx.send('Beginning set draft.') first_player = ctx.guild.get_member(sess.players[0].uid) await ctx.send( f'{first_player.mention} please choose a set. (\">choose_set x\")' ) else: next_player = ctx.guild.get_member( sess.players[sess.curr_player].uid) await ctx.send( f'{next_player.mention} please select your draft position. (\">choose_position n\")' ) else: await ctx.send( f'Sorry, that position is taken by {sess.pick_draft[pos_index]}.')