async def scramble(self, ctx): # TODO fix rate limiting issue becuase I think it's breaking more things. guild = ctx.message.guild logging.info(guild) players = models.Player_list() players.load_all() for p in players.items: old_team_id = p.team_id # Pick a number & update player team_id = randint(1, 3) if old_team_id != team_id: p.team_id = team_id p.update() old_team = models.Team() old_team.load(old_team_id) team = models.Team() team.load(team_id) # Clear/Assign role old_team_role = get(guild.roles, name=old_team.name) team_role = get(guild.roles, name=team.name) member = guild.get_member(int(p.discord_id)) if member is None: logging.info( "Player w/ id {} not found. Maybe they left the server.".format(p.discord_id)) continue await member.remove_roles(old_team_role, reason="Automated Team Scramble") await member.add_roles(team_role, reason="Automated Team Scramble") logging.info("{} (ID:{}) moved from {} to {}".format( member.nick if member.nick is not None else member.name, p.discord_id, old_team.name, team.name)) await asyncio.sleep(1) models.save() logging.info("Scramble complete")
async def pay(self, ctx, target_location, amount): amount = int(amount) # dumb. member = ctx.message.author p = models.Player() try: p.custom_load("discord_id = ?", (member.id, )) except Exception: await ctx.send("I don't have you listed as a player, {}\n\ If you believe this is an error, please talk to a Lord or the Monarch" .format(member.mention)) return # Make sure player has enough coins!!! if amount < 1: await ctx.send("You can't pay 0 or negative coins, {}".format( member.mention)) return elif amount > p.coins: await ctx.send("{}, you don't have enough coins!".format( member.mention)) return # Get team, current location id, available locations t = models.Team() t.load(p.team_id) current_loc = t.current_location_id avail_locs = graphanalyzer.get_next_location_list(t.team_id) # Make sure it's a valid target location. if target_location.lower() not in (name.lower() for name in avail_locs.keys()): await ctx.send( "I don't think {} is a valid location. Maybe you mistyped it?". format(target_location)) return # Get the ID for the target location... target_loc = models.Location() target_loc.custom_load("name = ? COLLATE NOCASE", (target_location, )) # target_loc.load((current_loc + 1) % 51) # Hax for Paris edge = models.LocationEdge() edge.custom_load("start_location_id = ? AND end_location_id = ?", ( current_loc, target_loc.location_id, )) # Store the payment in the db payment = models.Payment() payment.player_id = p.player_id payment.team_id = p.team_id payment.amount = amount payment.location_edge = edge.edge_id payment.time = helpers.get_game_day() payment.insert() # Remove coins from player's account. p.coins -= amount p.last_active_day = helpers.get_game_day() p.update() models.save() # Send confirmation message. await ctx.send("{} has paid **{}** coins toward **{}**".format( member.mention, amount, target_loc.name))
async def team(self, ctx): # Prints the player's team's current funding for the day, # As well as current location, # And total distance remaining. member = ctx.message.author try: p = models.Player() p.custom_load("discord_id = ?", (member.id, )) if p.last_active_day != helpers.get_game_day(): p.last_active_day = helpers.get_game_day() p.update() models.save() except Exception: await ctx.send("I don't think you're playing, {}\n\ (If you think this is a mistake, please talk to a Lord or the Monarch)" .format(member.mention)) return t = models.Team() t.load(p.team_id) l = models.Location() l.load(t.current_location_id) funding_table = paymentreducer.get_funding_table( p.team_id, helpers.get_game_day()) await ctx.send( "Your team is in **{}**, with at least **{}km** to go!\nHere is how today's funding is going:\n{}" .format( l.name, graphanalyzer.dijkstra(graphanalyzer.graph, t.current_location_id, 0), "```" + funding_table + "```"))
async def on_member_join(member): pa_chan = get(member.guild.text_channels, name="player-assignments") ins_chan = get(member.guild.text_channels, name="instructions") # Assign the new member to one of the three teams randomly # FIXME Get number of teams through the DB and not hardcode a 3 team_id = randint(1, 3) t = models.Team() t.load(team_id) # Add flair to user role = get(member.guild.roles, name=t.name) await member.add_roles(role) # Create new Player record. p = models.Player() # First check if they already exist try: p.custom_load("discord_id = ?", (member.id, )) t.load(p.team_id) await pa_chan.send("Welcome back, {}! the **{}** missed you!".format( member.mention, t.name)) return except Exception: pass p.discord_id = member.id p.team_id = team_id p.coins = config['starting_coins'] p.last_active_day = helpers.get_game_day() p.shares = 100 p.insert() models.save() # Post message to player-assignments channel await pa_chan.send("Welcome, {}! You have been assigned to the **{}**!\n\ Make sure to check out the {} and good luck!".format( member.mention, t.name, ins_chan.mention))
async def spectate(self, ctx): member = ctx.message.author if helpers.get_game_day( ) > config['latest_spectate_day'] and config['game_ongoing']: await ctx.send( "Sorry, {}, it's too late to switch to spectator mode".format( member.mention)) return player = models.Player() team = models.Team() try: player.custom_load("discord_id = ?", (str(member.id), )) team.load(player.team_id) except Exception as e: await ctx.send( "I think you're already out of the game, {}. If you think this was a mistake, please talk to a Lord or the Monarch" .format(member.mention)) logging.error(e) return # Remove flair from user role = get(member.guild.roles, name=team.name) await member.remove_roles(role, reason='Player left game') # Add spectator role role = get(member.guild.roles, name='Spectator') await member.add_roles(role, reason='Player left game') player.delete() models.save() logging.info("{} has switched to spectating".format(member.id)) await ctx.send("{}, you're now a spectator. Enjoy the show!".format( member.mention))
async def join(self, ctx): member = ctx.message.author if config['game_ongoing']: await ctx.send( "Sorry, {}, you can't join the game while it's ongoing!". format(member.mention)) return p = models.Player() # Make sure player doesn't already exist try: p.custom_load('discord_id = ?', (member.id, )) await ctx.send( "I think you're already playing, {}. If you think this is an error, please talk to a Lord or the Monarch" .format(member.mention)) return except Exception: pass # Pick a team team_id = randint(1, 3) team = models.Team() team.load(team_id) # Add flair to user role = get(member.guild.roles, name=team.name) await member.add_roles(role, reason='Player joined game') # Remove spectator role role = get(member.guild.roles, name='Spectator') if role in member.roles: await member.remove_roles(role, reason='Player joined game') # Create new player p.discord_id = member.id p.team_id = team_id p.coins = config['starting_coins'] p.last_active_day = 0 p.shares = 100 p.insert() models.save() logging.info("{} has joined the {}".format(member.id, team.name)) await ctx.send( "{}, you've been added to the **{}**! Good Luck!".format( member.mention, team.name))
def team_attempt_move(team_id): process_log = "" # Load team. t = models.Team() t.load(team_id) flns = paymentreducer.get_funding_list(team_id, helpers.get_game_day() - 1, False) fl = paymentreducer.get_funding_list(team_id, helpers.get_game_day() - 1, True) # Check for best-funded succesful path new_loc = t.current_location_id biggest_funding = -1 was_sabotaged = False for k, v in flns.items(): le = models.LocationEdge() le.load(k) if v >= le.weight and v > biggest_funding: new_loc = le.end_location_id biggest_funding = v if fl[k] < le.weight: was_sabotaged = True else: was_sabotaged = False if biggest_funding == -1: process_log = "The {} didn't raise enough to book passage anywhere...".format( t.name) else: l = models.Location() l.load(new_loc) if was_sabotaged: process_log = "The {} tried to travel to {}, but someone sabotaged them and they were stopped by the Black Cats!".format( t.name, l.name) else: t.current_location_id = new_loc t.update() process_log = "The {} have successfully reached {}!".format( t.name, l.name) models.save() return process_log + "\n"
def get_next_location_list(team_id): locations = {} team = models.Team() team.load(team_id) edges = models.LocationEdge_list() edges.custom_load("start_location_id = ?", (team.current_location_id, )) # Load end locations ls = models.Location_list() # HACK HACK HACK ls.custom_load( "location_id IN ({})".format(','.join(["?"] * len(edges.items))), [x.end_location_id for x in edges.items]) # MUCH BIGGER HACK that could have been solved with a join instead but why bother for l in ls.items: locations[l.name] = list( filter(lambda x: x.end_location_id == l.location_id, edges.items))[0].weight return locations
async def validateteams(self, ctx): bad, missing = 0, 0 guild = ctx.message.guild logging.info(guild) players = models.Player_list() players.load_all() for p in players.items: member = guild.get_member(int(p.discord_id)) t = models.Team() t.load(p.team_id) if member is None: logging.info( "Player w/ id {} not found. Maybe they left the server.".format(p.discord_id)) missing += 1 else: if member.top_role.name != t.name: logging.error("{} (ID:{})'s role is {}, but it should be {}".format( member.nick if member.nick is not None else member.name, p.discord_id, member.top_role.name, t.name )) bad += 1 logging.info("Validation done. {}/{} roles are correct. ({} missing)".format( len(players.items)-bad-missing, len(players.items)-missing, missing))
def get_funding_table(team_id, day=-1): # Return a string to display the team's funding progress. # IGNORES SABOTAGE. #f = get_funding_list(team_id, day=helpers.get_game_day(), show_sabotage=False) f = get_funding_list(team_id, day, show_sabotage=False) if len(f.keys()) == 0: return "No payments have been made yet today!" t = models.Team() t.load(team_id) tab = [] row_format = "{:<18}{:<8}{:<8}\n" tab.append(row_format.format('Location', 'Toll', 'Paid')) tab.append("-" * (34) + "\n") # FIXME toooo many queries for k, v in f.items(): le = models.LocationEdge() le.load(k) l = models.Location() l.load(le.end_location_id) tab.append(row_format.format(l.name, le.weight, v)) return "".join(tab)
async def sabotage(self, ctx, target_team, target_location, amount): # just pay() but with negative coins and another team amount = int(amount) # still dumb member = ctx.message.author p = models.Player() try: p.custom_load("discord_id = ?", (member.id, )) except Exception: await ctx.send( "Gonna be hard to sabotage when I don't have you listed as a player, {}\n\ If you believe this is a mistake, please talk to a Lord or the Monarch" .format(member.mention)) return # Mke sure player has enough coins if amount < 1: await ctx.send("You can't pay 0 or negative coins, {}".format( member.mention)) return elif amount > p.coins: await ctx.send("{}, you don't have enough coins!".format( member.mention)) return t = models.Team() try: # TODO make this more user-friendly t.custom_load("name = ? COLLATE NOCASE", (target_team, )) except Exception: await ctx.send( "I don't think {} is a real team, {}. Make sure you type the full name!" .format(target_team, member.mention)) return if t.team_id == p.team_id: await ctx.send( "You can't sabotage your own team, {}!!! They won't like you for that!" .format(member.mention)) return current_loc = t.current_location_id avail_locs = graphanalyzer.get_next_location_list(t.team_id) # Validate target location... if target_location.lower() not in (name.lower() for name in avail_locs.keys()): await ctx.send( "I don't think {} is a valid location. Maybe a typo?".format( target_location)) return # Get id for the target location... location = models.Location() location.custom_load("name = ? COLLATE NOCASE", (target_location, )) # location.load((current_loc + 1) % 51) # Hax for Paris edge = models.LocationEdge() edge.custom_load("start_location_id = ? AND end_location_id = ?", (current_loc, location.location_id)) # Store the payment! payment = models.Payment() payment.player_id = p.player_id payment.team_id = t.team_id payment.amount = -amount # VERY IMPORTANT DIFFERENCE payment.location_edge = edge.edge_id payment.time = helpers.get_game_day() payment.insert() # Remove coins from the player's account p.coins -= amount p.last_active_day = helpers.get_game_day() p.update() models.save() # Send confirmation message. await ctx.send( "{} has paid **{}** coins to sabotage the **{}'** trip to **{}**". format(member.mention, amount, t.name, location.name))