Пример #1
0
 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")
Пример #2
0
    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))
Пример #3
0
 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 + "```"))
Пример #4
0
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))
Пример #5
0
    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))
Пример #6
0
    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))
Пример #7
0
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"
Пример #8
0
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
Пример #9
0
 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))
Пример #10
0
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)
Пример #11
0
    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))