Exemple #1
0
async def pay(ctx, target_location, amount):
    if not config['game_ongoing']: return

    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 King"
                       .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, ))

    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))
Exemple #2
0
async def team(ctx):
    if not config['game_ongoing']: return
    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 King)"
                       .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 + "```"))
Exemple #3
0
def on_new_day():
    if not config['game_ongoing']:
        return
    print("A new day dawns...")
    print("Moving teams")
    # Each team tries to move to a new location!
    progress_log = []
    for i in range(1, 4):
        progress_log.append(team_attempt_move(i))
    progress_log.append("\n")
    # Send coins to players
    print("Updating player shares")
    update_shares()
    print("Paying players")
    pay_players()

    # Send daily message to progress-announcements channel
    with sql.connect(
        (Path(__file__).parent / 'model' / 'internal.sqlite3').resolve(),
            timeout=30) as conn:
        msg = []
        msg.append("A new day has begun! Welcome to day **{}**!\n".format(
            helpers.get_game_day()))
        msg.append("Here's what's happened since yesterday:\n")
        msg.append("```\n")
        if helpers.get_game_day() == 1:
            msg.append("The race began! All teams are currently in London\n")
        else:
            msg.append("\n".join(progress_log))
        msg.append("```\n")

        # FIXME hardcoded team names...
        msg.append(
            "**Argent Boars**, here are your destination options for today:\n")
        msg.append(next_location_table(1))
        msg.append("And for you, **Azure Wolves**:\n")
        msg.append(next_location_table(2))
        msg.append("Finally, **Crimson Stallions**:\n")
        msg.append(next_location_table(3))
        msg.append(
            "You've all already received your salaries and refunds, so get booking and good luck!"
        )
        c = conn.cursor()
        log = models.Log()
        log.date = str(datetime.now())
        log.game_day = helpers.get_game_day()
        log.msg = ''.join(msg)
        log.target_channel_id = config['channels']['progress-announcements']
        # I hate this but it's better than my hackosaurus workaround
        c.execute(
            "INSERT INTO Log(date, game_day, msg, sent, target_channel_id) VALUES (?,?,?,?,?)",
            (log.date, log.game_day, log.msg, log.sent, log.target_channel_id))

        conn.commit()
Exemple #4
0
async def check_for_new_logs():
    while True:
        if helpers.get_game_day(
        ) > config['game_length'] and config['game_ongoing']:
            await end_game()
        t = models.Team_list()
        t.custom_load("team_id > ?", (0, ))
        for team in t.items:
            if team.current_location_id == 0 and config['game_ongoing']:
                await end_game()

        logs = models.Log_list()
        logs.custom_load("sent = ?", (0, ))
        if len(logs.items) > 0:
            logging.info("Found {} new logs, attempting to send...".format(
                len(logs.items)))
            # Try to send them and die inside.
            try:
                for log in logs.items:
                    ch = get(client.get_all_channels(),
                             id=log.target_channel_id)
                    await ch.send(log.msg)
                    log.sent = 1
                    log.update()
                models.save()
            except AttributeError:
                logging.error(
                    "We can't see the channel yet. We'll get 'em next time.")
        await asyncio.sleep(5)
Exemple #5
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))
Exemple #6
0
def pay_players():
    teams = models.Team_list()
    teams.custom_load("team_id > ?", (0, ))
    for t in teams.items:
        # load all the players
        players = models.Player_list()
        players.custom_load("team_id = ?",
                            (t.team_id, ))  # Still the dumb Loadall HACK

        total_team_shares = sum([p.shares for p in players.items])
        share_value = config['daily_team_coins'] // total_team_shares
        # pay 'em
        for player in players.items:
            # add daily salary
            player.coins += share_value * player.shares
            # get  THIS PLAYER's payments from TODAY for THIS PLAYER's TEAM that
            # WEREN'T put toward the current location (for refunds)
            models.c.execute(
                "SELECT SUM(amount) FROM Payment p LEFT JOIN LocationEdge le ON(p.location_edge = le.edge_id) WHERE player_id = ? AND team_id = ? AND time = ? AND end_location_id != ?",
                (player.player_id, player.team_id, helpers.get_game_day() - 1,
                 t.current_location_id))

            refund = models.c.fetchone()[0]
            if refund is None:
                refund = 0
            player.coins += int(refund * (config['refund_percentage'] / 100))

            player.update()
    models.save()
Exemple #7
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))
Exemple #8
0
async def me(ctx):
    if not config['game_ongoing']: return
    member = ctx.message.author
    try:
        p = models.Player()
        p.custom_load("discord_id = ?", (member.id, ))
        await ctx.send("{}, you have **{}** coins".format(
            member.mention, p.coins))
        if p.last_active_day != helpers.get_game_day():
            p.last_active_day = helpers.get_game_day()
            p.update()
            models.save()
    except Exception:
        # Show error if user isn't actually playing
        await ctx.send("I... don't believe you're playing, {}\n\
            (If you think this is a mistake, please talk to a Lord or the King)"
                       .format(member.mention))
Exemple #9
0
def ten_minute_warning():
    if not config['game_ongoing']: return
    l = models.Log()
    l.date = str(datetime.now())
    l.game_day = helpers.get_game_day()
    l.msg = "10 minutes remaining in the day! Get those payments in!!!"
    l.target_channel_id = config['channels']['progress-announcements']
    l.insert()
    models.save()
Exemple #10
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"
Exemple #11
0
def update_shares():
    players = models.Player_list()
    players.load_all()
    for player in players.items:
        days_since_active = helpers.get_game_day() - player.last_active_day
        if days_since_active < len(config['afk_falloff']):
            player.shares = config['afk_falloff'][days_since_active]
        else:
            player.shares = 0
        player.update()
    models.save()
Exemple #12
0
async def sabotage(ctx, target_team, target_location, amount):
    if not config['game_ongoing']: return
    # 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 King"
            .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:
        t.custom_load("name = ? COLLATE NOCASE",
                      (target_team, ))  # TODO make this more user-friendly
    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, ))

    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))