Ejemplo n.º 1
0
async def fleet(ctx):
    """Base command for fleet management, shows the current fleet."""
    if (not setting('features.fleets_enabled')):
        await ctx.send("That feature is not enabled.")
        return
    if (not ctx.invoked_subcommand):
        did = ctx.author.id
        fleet = userinfo.UserFleet.instance(1, did)
        if(len(fleet.ships) > 0):
            ins = fleet.get_ship_instances()
            fleet_lvl = sum(x.level for x in ins) // len(ins)

            embed = discord.Embed(title=namesub("%s's <fleet.title>") % str(ctx.author))
            embed.color = 524358
            flag = ins.pop(0)
            embed.add_field(name=namesub('<ship.title>'), value=flag.base().stype + " "
                            + flag.base().name + " (*)\n" +
                            "\n".join([x.base().stype + " " + x.base().name
                                       for x in ins]), inline=True)
            ins.insert(0, flag)
            embed.add_field(name="Level", value="\n".join(
                [str(x.level) for x in ins]), inline=True)
            embed.add_field(name="ID", value="\n".join(
                ["%04d" % (x.invid) for x in ins]), inline=True)
            embed.set_footer(text=namesub("<fleet.title> level %d") % fleet_lvl)

            await ctx.send(embed=embed)
        else:
            await ctx.send(namesub("<fleet.title> %s is empty!" % (1)))
Ejemplo n.º 2
0
async def f_add(ctx, shipid: int):
    """Add a ship to the user's fleet."""
    if (not setting('features.fleets_enabled')):
        await ctx.send("That feature is not enabled.")
        return
    did = ctx.author.id
    fleet = userinfo.UserFleet.instance(1, did)
    inv = userinfo.get_user_inventory(did)
    ins = [x for x in inv.inventory if x.invid == shipid]
    if (len(ins) > 0):
        ins = ins.pop()
        if (shipid not in fleet.ships):
            if (not fleet.has_similar(ins.sid)):
                if (len(fleet.ships) < setting('fleets.fleet_capacity')):
                    fleet.ships.append(shipid)
                    fleet.update()
                    await ctx.send(namesub("Added %s to <fleet> %s\n\n%s: *%s*") % (
                        ins.base().name, 1, ins.base().name,
                        ins.base().get_quote('fleet_join')))
                else:
                    await ctx.send(namesub("<fleet.title> %s is full!" % (1)))
            else:
                await ctx.send(namesub("You already have another %s in <fleet> %s!")
                               % (ins.base().name, 1))
        else:
            await ctx.send(namesub("%s is already in <fleet> %s!") % (ins.base().name, 1))
    else:
        await ctx.send(namesub("<ship.title> with ID %s not found in your inventory") % (
            shipid))
Ejemplo n.º 3
0
async def cooldowns(ctx):
    """Show how much time left the user has before performing actions."""
    did = ctx.author.id
    cd_check = []
    if (setting('features.drop_enabled')):
        cd_check.append(("Last_Drop", "Drop", DROP_COOLDOWN))
    if (setting('features.training_enabled')):
        cd_check.append(("Last_Training", namesub("<fleet.title> Training"), TRAINING_COOLDOWN))
    if (setting('features.crafting_enabled')):
        cd_check.append(("Last_Craft", "Crafting", CRAFTING_COOLDOWN))
    if (len(cd_check) == 0):
        await ctx.send("That feature is not enabled.")
        return
    msg = "Current cooldowns for %s:\n" % ctx.author.display_name
    msg += "```\n"
    for cd, name, cd_s in cd_check:
        t = userinfo.check_cooldown(did, cd, cd_s, set_if_off=False)
        if (t > 0):
            hrs = t // 3600
            min = t // 60 % 60
            sec = t % 60
            msg += "%s: %dh%02dm%02ds remaining\n" % (name, hrs, min, sec)
        else:
            msg += "%s: Available!\n" % (name)
    msg += "```"
    await ctx.send(msg)
Ejemplo n.º 4
0
async def remodel(ctx, shipid: int):
    """Remodel the given ship."""
    if (not setting('features.levels_enabled')):
        await ctx.send("That feature is not enabled.")
        return
    did = ctx.author.id
    inv = userinfo.get_user_inventory(did)
    ins = [x for x in inv.inventory if x.invid == shipid]
    if (len(ins) > 0):
        ship_instance = ins.pop()
        base = ship_instance.base()
        if (base.remodels_into):
            if (ship_instance.is_remodel_ready()):
                old_name = base.name
                ship_instance.sid = base.remodels_into
                base = ship_instance.base()
                new_name = base.name
                userinfo.update_ship_sid(ship_instance)
                image_file = imggen.generate_ship_card(ctx.bot, ship_instance)
                await ctx.send(file=discord.File(
                    io.BytesIO(image_file.getvalue()),
                    filename="image.png"),
                               content="%s: *%s*" % (new_name,
                                                     base.get_quote('remodel')
                                                     ))
                logging.info("[Remodel] %s (%s) remodelled %s into %s" %
                             (str(ctx.author), did, old_name, new_name))
            else:
                await ctx.send("%s isn't ready for a remodel just yet." % (
                    base.name))
        else:
            await ctx.send("%s doesn't have another remodel." % (base.name))
    else:
        await ctx.send(namesub("<ship.title> with ID %s not found in your inventory") % (
            shipid))
Ejemplo n.º 5
0
async def f_clear(ctx):
    """Clear a user's fleet."""
    if (not setting('features.fleets_enabled')):
        await ctx.send("That feature is not enabled.")
        return
    did = ctx.author.id
    fleet = userinfo.UserFleet.instance(1, did)
    fleet.ships = []
    fleet.update()
    await ctx.send(namesub("Cleared <fleet> %s!") % (1))
Ejemplo n.º 6
0
async def f_flag(ctx, flagship: int):
    """Set the flagship for the user's fleet."""
    if (not setting('features.fleets_enabled')):
        await ctx.send("That feature is not enabled.")
        return
    did = ctx.author.id
    fleet = userinfo.UserFleet.instance(1, did)
    inv = userinfo.get_user_inventory(did)
    ins = [x for x in inv.inventory if x.invid == flagship]
    if (len(ins) > 0):
        ins = ins.pop()
        cancel = False
        if (len(fleet.ships) > 0):
            old_flag = fleet.ships.pop(0)
            if (not old_flag == flagship):
                if (flagship in fleet.ships):
                    fleet.ships.remove(flagship)
                else:
                    if (len(fleet.ships) > setting('fleets.fleet_capacity')):
                        cancel = True
                        await ctx.send(namesub("<fleet.title> %s is full!") % (1))
                    if ins.sid in map(lambda x: [y for y in inv.inventory
                                                 if y.invid == x].pop().sid,
                                      fleet.ships):
                        cancel = True
                        await ctx.send(namesub("You already have another %s in <fleet> "
                                               "%s!") % (ins.base().name, 1))
                fleet.ships.append(old_flag)
            else:
                cancel = True
                await ctx.send(namesub("%s is already <flagship> of <fleet> %s!") % (
                    ins.base().name, 1))
            fleet.ships.insert(0, flagship)
        else:
            fleet.ships = [flagship, ]
        if (not cancel):
            fleet.update()
            await ctx.send(namesub("Set %s as the <flagship> of <fleet> %s\n\n%s: *%s*") % (
                ins.base().name, 1, ins.base().name,
                ins.base().get_quote('fleet_join')))
    else:
        await ctx.send(namesub("<ship.title> with ID %s not found in your inventory") % (
            flagship))
Ejemplo n.º 7
0
async def f_rem(ctx, shipid: int):
    """Remove a ship from a user's fleet."""
    if (not setting('features.fleets_enabled')):
        await ctx.send("That feature is not enabled.")
        return
    did = ctx.author.id
    fleet = userinfo.UserFleet.instance(1, did)
    inv = userinfo.get_user_inventory(did)
    ins = [x for x in inv.inventory if x.invid == shipid]
    if (len(ins) > 0):
        ins = ins.pop()
        base = ins.base()
        if (shipid in fleet.ships):
            fleet.ships.remove(shipid)
            fleet.update()
            await ctx.send(namesub("Removed %s from <fleet> %s!") % (base.name, 1))
        else:
            await ctx.send(namesub("%s isn't in <fleet> %s!") % (base.name, 1))
    else:
        await ctx.send(namesub("<ship.title> with ID %s not found in your inventory") % (
            shipid))
Ejemplo n.º 8
0
async def f_set(ctx, *ships):
    """Set the user's fleet to the given ships."""
    if (not setting('features.fleets_enabled')):
        await ctx.send("That feature is not enabled.")
        return
    did = ctx.author.id
    fleet = userinfo.UserFleet.instance(1, did)
    inv = userinfo.get_user_inventory(did)
    sids_raw = map(int, ships)
    sids_raw = [x for x in sids_raw if x >
                0 and x in map(lambda n: n.invid, inv.inventory)]
    # check for no dupes while still keeping order
    sids = []
    for x in sids_raw:
        if x in sids:
            continue
        sid = [y for y in inv.inventory if y.invid == x].pop().sid
        if sid in map(lambda y: [z for z in inv.inventory if z.invid == y]
                      .pop().sid, sids):
            continue
        sids.append(x)
    if (len(sids) == 0):
        await ctx.send(namesub("Please include at least one valid <ship.title> ID"))
    elif(len(sids) > setting('fleets.fleet_capacity')):
        await ctx.send(namesub("Too many <ship_plural> in the <fleet>!"))
    else:
        fleet.ships = sids
        fleet.update()
        strs = fleet_strings(inv, fleet)
        flag = strs.pop(0)
        line_base = [x for x in inv.inventory if x.invid ==
                     sids[0]].pop().base()
        if (len(strs) > 0):
            await ctx.send(namesub("Set <fleet> %s to: <flagship.title> %s, <ship_plural> %s\n\n%s: *%s*")
                           % (1, flag, ", ".join(strs), line_base.name,
                              line_base.get_quote('fleet_join')))
        else:
            await ctx.send(namesub("Set <fleet> %s to: <flagship.title> %s\n\n%s: *%s*")
                           % (1, flag, line_base.name,
                              line_base.get_quote('fleet_join')))
Ejemplo n.º 9
0
async def craft(ctx, fuel: int, ammo: int, steel: int, bauxite: int):
    """Craft a random ship based on the user's inputted resources."""
    did = ctx.author.id
    user = userinfo.get_user(did)
    if (not setting('features.crafting_enabled') or not setting('features.resources_enabled')):
        await ctx.send("That feature is not enabled.")
        return
    if (userinfo.has_space_in_inventory(did)):
        cd = userinfo.check_cooldown(
            did, 'Last_Craft', CRAFTING_COOLDOWN, set_if_off=False)
        if (cd == 0):
            min_craft = setting('resources.min_crafting')
            if (fuel >= min_craft[0] and ammo >= min_craft[1] and
                    steel >= min_craft[2] and bauxite >= min_craft[3]):
                if (user.has_enough(fuel, ammo, steel, bauxite)):
                    craft = craftinghandler.get_craft_from_resources(
                        did, fuel, ammo, steel, bauxite)
                    user.mod_fuel(-fuel)
                    user.mod_ammo(-ammo)
                    user.mod_steel(-steel)
                    user.mod_bauxite(-bauxite)
                    inv = userinfo.get_user_inventory(did)
                    inv.add_to_inventory(craft)
                    # set cooldown
                    userinfo.check_cooldown(
                        did, 'Last_Craft', CRAFTING_COOLDOWN, set_if_off=True)
                    image_file = imggen.generate_ship_card(ctx.bot, craft)
                    ship_base = craft.base()
                    await ctx.send(
                        file=discord.File(io.BytesIO(image_file.getvalue()),
                                          filename="image.png"),
                        content="%s just crafted %s!\n\n%s: *%s*" % (
                            ctx.author.display_name, ship_base.name,
                            ship_base.name, ship_base.get_quote('intro')))
                    logging.info("[Craft] %s (%s) crafted %s using recipe "
                                 "%s/%s/%s/%s" %
                                 (str(ctx.author), did, ship_base.name,
                                  fuel, ammo, steel, bauxite))
                else:
                    await ctx.send("Not enough resources!")
            else:
                await ctx.send("Use at least 30 of each resource")
        else:
            min = cd // 60
            sec = cd % 60
            await ctx.send("You have %dm%02ds remaining until you can craft "
                           "another ship" % (min, sec))
    else:
        await ctx.send(namesub("Your inventory is full! You can scrap a <ship.title> with "
                       "`%sscrap [<ship.title> ID]`") % COMMAND_PREFIX)
Ejemplo n.º 10
0
async def add_ship(ctx, user: discord.Member, ship_name):
    """Admin command to add a ship to a user's inventory."""
    inv = userinfo.get_user_inventory(user.id)
    targ = None
    for ship in ship_stats.get_all_ships():
        if (ship.name.lower() == ship_name.lower() or ship.name.lower()
                .replace(' ', '_') == ship_name.lower()):
            targ = ship
            break
    if (targ):
        ins = ship_stats.ShipInstance.new(targ.sid, user.id)
        inv.add_to_inventory(ins)
        await ctx.send("Added %s to %s's inventory" % (targ.name, str(user)))
        logging.info("[ADMIN_ADD] Added %s to %s's (%s) inventory" %
                     (targ.name, str(user), user.id))
    else:
        await ctx.send(namesub("Cannot find <ship.title> '%s'") % ship_name)
Ejemplo n.º 11
0
async def show(ctx, shipid: int):
    """Show the specified ship from the user's inventory."""
    did = ctx.author.id
    inv = userinfo.get_user_inventory(did)
    ins = [x for x in inv.inventory if x.invid == shipid]
    if (len(ins) > 0):
        ship_instance = ins.pop()
        base = ship_instance.base()
        image_file = imggen.generate_ship_card(ctx.bot, ship_instance)
        if (ship_instance.level > setting('levels.level_cap')):
            quote = base.get_quote('married')
        else:
            quote = base.get_quote('idle')
        await ctx.send(file=discord.File(io.BytesIO(image_file.getvalue()),
                                         filename="image.png"),
                       content="%s: *%s*" % (base.name, quote))
    else:
        await ctx.send(namesub("<ship.title> with ID %s not found in your inventory") % (
            shipid))
Ejemplo n.º 12
0
async def scrap(ctx, shipid: int):
    """Scrap the given ship from the user's inventory."""
    did = ctx.author.id
    user = userinfo.get_user(did)
    inv = userinfo.get_user_inventory(did)
    ins = [x for x in inv.inventory if x.invid == shipid]
    if (len(ins) > 0):
        ship_instance = ins.pop()
        base = ship_instance.base()
        user.mod_fuel(setting_random('resources.scrap_gain.fuel'))
        user.mod_ammo(setting_random('resources.scrap_gain.ammo'))
        user.mod_steel(setting_random('resources.scrap_gain.steel'))
        user.mod_bauxite(setting_random('resources.scrap_gain.bauxite'))
        inv.remove_from_inventory(shipid)
        await ctx.send("Scrapped %s... <:roosad:434916104268152853>" % (
            base.name))
        logging.info("[Scrap] %s (%s) scrapped ship %s with inv id %s" %
                     (str(ctx.author), did, base.name, shipid))
    else:
        await ctx.send(namesub("<ship.title> with ID %s not found in your inventory") % (
            shipid))
Ejemplo n.º 13
0
async def drop(ctx):
    """Drop a random ship for the user."""
    did = ctx.author.id
    if (not setting('features.drop_enabled')):
        await ctx.send("That feature is not enabled.")
        return
    if (userinfo.has_space_in_inventory(did)):
        cd = userinfo.check_cooldown(did, 'Last_Drop', DROP_COOLDOWN)
        if (cd == 0):
            drop = drophandler.get_random_drop(did, only_droppable=True)
            ship_base = drop.base()
            ship_name = ship_base.name
            ship_rarity = ship_base.rarity
            rarity = setting('rarities')
            inv = userinfo.get_user_inventory(did)
            inv.add_to_inventory(drop)
            image_file = imggen.generate_ship_card(ctx.bot, drop)

            await ctx.send(
                file=discord.File(
                    io.BytesIO(image_file.getvalue()),
                    filename="image.png"),
                content="%s got %s! (%s)\n\n%s: *%s*" % (
                        ctx.author.display_name, ship_name,
                        rarity[ship_rarity - 1], ship_name,
                        ship_base.get_quote('intro')))
            logging.info("[Drop] %s (%s) received %s from a drop" %
                         (str(ctx.author), did, ship_name))
        else:
            hrs = cd // 3600
            min = cd // 60 % 60
            sec = cd % 60
            await ctx.send("You have %dh%02dm%02ds remaining until you can"
                           " get your next drop" % (hrs, min, sec))
    else:
        await ctx.send(namesub("Your inventory is full! You can scrap a <ship.title> with"
                       " `%sscrap [<ship.title> ID]`") % COMMAND_PREFIX)
Ejemplo n.º 14
0
async def marry(ctx, shipid: int):
    """Allow the user to marry a level 99 ship, increasing its level cap."""
    if (not setting('features.marriage_enabled') or not setting('features.levels_enabled')):
        await ctx.send("This feature is not enabled.")
    did = ctx.author.id
    user = userinfo.get_user(did)
    inv = userinfo.get_user_inventory(did)
    ins = [x for x in inv.inventory if x.invid == shipid]
    if (len(ins) > 0):
        ship_instance = ins.pop()
        base = ship_instance.base()
        if (ship_instance.level == setting('levels.level_cap')):
            ring_req = setting('levels.marriage_ring_required')
            rings = user.rings
            if (rings > 0 or not ring_req):
                ship_instance.level = setting('levels.level_cap') + 1
                ship_instance.exp = 0
                ship_instance.add_exp(0)
                if (ring_req):
                    user.use_ring()
                ship_name = base.name
                image_file = imggen.generate_ship_card(ctx.bot, ship_instance)
                await ctx.send(file=discord.File(
                    io.BytesIO(image_file.getvalue()), filename="image.png"),
                               content="%s: *%s*" % (ship_name,
                                                     base.get_quote('married')
                                                     ))
                logging.info("[Marriage] %s (%s) married their %s" %
                             (str(ctx.author), did, ship_name))
            else:
                await ctx.send("You don't have any more rings.")
        else:
            await ctx.send("%s isn't ready for marriage yet." % (base.name))
    else:
        await ctx.send(namesub("<ship.title> with ID %s not found in your inventory") % (
            shipid))
Ejemplo n.º 15
0
async def train(ctx, dif: int=-1):
    """Train a user's fleet given the difficulty, or show training options."""
    did = ctx.author.id
    difs = fleet_training.ALL_DIFFICULTIES
    if (not setting('features.training_enabled') or not setting('features.levels_enabled')
            or not setting('features.fleets_enabled')):
        await ctx.send("That feature is not enabled.")
        return
    if (dif == -1):
        description = "Difficulties:\n"
        description += "\n".join([namesub("#%s. %s: Min <flagship> level %s, Recommended"
                                  " <fleet> level %s.") % (x + 1,
                                                           difs[x].name,
                                                           difs[x].min_flag,
                                                           difs[x].avg_lvl)
                                  for x in range(len(difs))])
        footer = "Type %strain (#) to train a fleet with a difficulty" % (
            COMMAND_PREFIX)
        embed = discord.Embed(title=namesub("<fleet.title> Training"), description=description)
        embed.set_footer(text=footer)

        await ctx.send(embed=embed)
    else:
        if (dif > 0 and dif <= len(difs)):
            dif_targ = difs[dif - 1]
            fleet = userinfo.UserFleet.instance(1, did)
            if (len(fleet.ships) > 0):
                ins = fleet.get_ship_instances()
                flag = ins[0]
                if (flag.level >= dif_targ.min_flag):
                    rsc = dif_targ.resource_costs(fleet)
                    rsc = tuple(map(int, rsc))
                    user = userinfo.get_user(did)
                    if (user.has_enough(*rsc)):
                        cd = userinfo.check_cooldown(
                            did, "Last_Training", TRAINING_COOLDOWN)
                        if (cd == 0):
                            # conditions passed
                            rank = dif_targ.rank_training(fleet)

                            exp_rew_base = rank.exp_mult \
                                * dif_targ.exp_reward_base
                            exp_rew_split = rank.exp_mult \
                                * dif_targ.exp_reward_split

                            exp = [exp_rew_base] * len(ins)
                            exp_per = exp_rew_split // len(ins) + 1
                            exp[0] += exp_per
                            exp = list(map(lambda x: x + exp_per, exp))

                            lvl_dif = [x.level for x in ins]
                            for i in range(len(ins)):
                                ins[i].add_exp(exp[i])
                                lvl_dif[i] = ins[i].level - lvl_dif[i]

                            user.mod_fuel(-rsc[0])
                            user.mod_ammo(-rsc[1])
                            user.mod_steel(-rsc[2])
                            user.mod_bauxite(-rsc[3])

                            embed = discord.Embed(title="Training %s" % (
                                "Success" if rank.is_success else "Failed"))
                            embed.color = 65280 if rank.is_success \
                                else 16711680
                            embed.description = "Rank %s | %s Difficulty" % (
                                rank.symbol, dif_targ.name)
                            flag = ins.pop(0)
                            embed.add_field(name="EXP Gain", value=flag.base(
                            ).name + " (*)\n" + "\n".join([x.base().name
                                                           for x in ins]),
                                                           inline=True)
                            embed.add_field(
                                name="--------", value="\n".join(["+%g EXP" % x
                                                                  for x in exp]
                                                                 ))
                            ins.insert(0, flag)
                            embed.add_field(name="--------", value="\n".join(
                                ["Level %s (+%s)" % (ins[i].level, lvl_dif[i])
                                 for i in range(len(ins))]))
                            if (setting('features.resources_enabled')):
                                embed.set_footer(
                                    text=namesub("Used %g <fuel>, %g <ammo>, %g <steel>, %g "
                                                 "<bauxite>") % rsc)

                            await ctx.send(embed=embed)
                            logging.info("[Training] %s (%s) completed "
                                         "training level %s with rank %s" % (
                                            str(ctx.author), did,
                                            dif_targ.name,
                                            rank.symbol))
                        else:
                            hrs = cd // 3600
                            min = cd // 60 % 60
                            sec = cd % 60
                            await ctx.send(namesub("You have %dh%02dm%02ds remaining "
                                                   "until you can train your <fleet> "
                                                   "again") % (hrs, min, sec))
                    else:
                        await ctx.send(namesub("Not enough resources! (Required: %g "
                                       "<fuel>, %g <ammo>, %g <steel>, %g <bauxite>)")
                                       % rsc)
                else:
                    await ctx.send(namesub("<flagship.title> isn't a high enough level! "
                                   "(Needs to be at least %s)") % (
                                       dif_targ.min_flag))
            else:
                await ctx.send(namesub("<fleet.title> %s is empty!") % (1))
        else:
            await ctx.send("No such difficulty #%s" % dif)
Ejemplo n.º 16
0
def generate_ship_card(bot, ship_instance):
    """Return a BytesIO object of a card image of the given ship.

    Parameters
    ----------
    bot : discord.ext.commands.Bot
        The bot being run.
    ship_instance : ShipInstance
        The ship to display.
    """
    base = ship_instance.base()

    img = ship_stats.get_rarity_backdrop(base.rarity)

    layout = CONFIG_DATA['ship_card']
    obj_small_identifier = layout['small_identifier']
    obj_name = layout['name']
    obj_class_name = layout['class_name']
    obj_level_indicator = layout['level_indicator']
    obj_level_progress = layout['level_progress']
    obj_next_remodel = layout['next_remodel']
    obj_owned_by = layout['owned_by']
    obj_main_image = layout['main_image']

    use_damaged = False  # TODO make this check if ship is damaged

    img_full = base.get_cg(dmg=use_damaged)

    if (obj_main_image['enabled']):
        img_w, img_h = img_full.size
        targ_width = int(obj_main_image['targ_height'] * (img_w / img_h))
        x_offset = int(obj_main_image['x_offset'] - (targ_width / 2))
        img_full = img_full.resize((targ_width, obj_main_image['targ_height']),
                                   Image.BICUBIC)
        img.paste(
            img_full, (x_offset, obj_main_image['y_offset']), mask=img_full)

    if (ship_instance.level > setting('levels.level_cap')):
        ring = Image.open(small_ico_ring_img)
        ring = ring.resize((60, 60))
        img.paste(ring, (20, 20), mask=ring)

    if (obj_name['enabled']):
        draw_object(img, obj_name, base.name)
    if (obj_class_name['enabled']):
        draw_object(img, obj_class_name, "%s %s" % (base.class_name,
                                                    ship_stats.get_ship_type(base.stype).full_name))
    if (setting('features.levels_enabled')):
        if (obj_level_indicator['enabled']):
            draw_object(img, obj_level_indicator, "Level %s" %
                        (ship_instance.level))
        if (obj_level_progress['enabled'] and (ship_instance.level > 1 or ship_instance.exp > 0)
                and ship_instance.level != setting('levels.level_cap') and ship_instance.level < setting('levels.level_cap_married')):
            exp = ship_instance.exp
            req = ship_instance.exp_req()
            draw_object(img, obj_level_progress, "%s / %s EXP (%.02f%%)" %
                        (exp, req, 100.0 * exp / req))
        if (base.remodels_into and obj_next_remodel['enabled']):
            r_base = ship_stats.ShipBase.instance(base.remodels_into)
            draw_object(img, obj_next_remodel, "Next Remodel: %s (Level %s)" % (
                r_base.name, base.remodel_level))

    if (obj_small_identifier['enabled']):
        draw_object(img, obj_small_identifier, "%s-%04d" %
                    (base.stype, ship_instance.invid))

    if (obj_owned_by['enabled']):
        display_name = "Unknown User"
        for g in bot.guilds:
            owner = g.get_member(ship_instance.owner)
            if (owner):
                display_name = "%s#%s" % (owner.name, owner.discriminator)
                break
        draw_object(img, obj_owned_by, namesub("Part of %s's <fleet.title>" % (display_name)))

    r = io.BytesIO(b'')
    img.save(r, format="PNG")
    return r
Ejemplo n.º 17
0
def generate_inventory_screen(member, page, only_dupes=False):
    """Return a BytesIO object of the user's inventory image.

    Parameters
    ----------
    member : discord.Member
        The user to generate the inventory of.
    page : int
        The page to show.
    only_dupes : bool
        If True, only display ships which the user has two or more of.
    """
    discord_id = member.id
    user = userinfo.get_user(discord_id)
    inv = userinfo.get_user_inventory(discord_id)
    layout = CONFIG_DATA['inventory']
    w, h = layout['image_size']
    antialias_value = 2
    w *= antialias_value
    h *= antialias_value
    sx, sy = layout['per_row'], layout['per_column']
    cw = int(w / sx)
    ch = int(h / sy)
    h += layout['lower_padding'] * antialias_value

    ship_pool = inv.inventory
    if (only_dupes):
        new_pool = []
        first_bases = {}
        for s in ship_pool:
            first_bases[s.sid] = s.base().get_first_base()
        for i in range(len(ship_pool)):
            s = ship_pool.pop(0)
            if (first_bases[s.sid].sid in map(lambda x:
                                              first_bases[x.sid].sid, new_pool)
                or first_bases[s.sid].sid in map(lambda x:
                                                 first_bases[x.sid].sid,
                                                 ship_pool)):
                new_pool.append(s)
        ship_pool = new_pool

    ships_per_page = sx * sy
    pages_needed = (len(ship_pool) // ships_per_page) + \
        (0 if len(ship_pool) % ships_per_page == 0 and len(ship_pool) > 0
         else 1)
    if (page < 1):
        page = 1
    elif (page > pages_needed):
        page = pages_needed

    img = Image.new(size=(w, h), mode="RGB", color=(255, 255, 255))

    draw = ImageDraw.Draw(img)
    shade = False
    indx = 0
    indx += (ships_per_page * (page - 1))
    for xi in range(sx):
        for yi in range(sy):
            ship = ship_pool[indx] if indx < len(ship_pool) else None

            shade_color = (("filled_color1" if shade else "filled_color2")
                           if ship else ("empty_color1" if shade else "empty_color2"))
            rbg = None

            if (ship):
                rbg = ship_stats.get_rarity_backdrop(ship.base().rarity)
                rbg = rbg.resize((cw, ch))
                fleet = userinfo.UserFleet.instance(1, discord_id)
                if (ship.invid in fleet.ships):
                    flag = fleet.ships.index(ship.invid) == 0
                    if flag:
                        shade_color = 'flag_border_color'
                    else:
                        shade_color = "fleet_color1" if shade else "fleet_color2"
                elif (ship.base().has_seasonal_cg()):
                    shade_color = "seasonal_color1" if shade else "seasonal_color2"

            shade_color = tuple(layout[shade_color])

            x, y = (xi * cw, yi * ch)
            draw.rectangle((x, y, x + cw, y + ch), fill=shade_color)
            if (rbg):
                img.paste(rbg, (x, y))
            if (ship):
                base = ship.base()
                font = ImageFont.truetype("fonts/trebucbd.ttf", ch * 1 // 2)
                num_str = "%s-%04d" % (base.stype, ship.invid)
                draw_squish_text(img, (x + cw * 3 // 4, y + ch * 1 // 4), num_str,
                                 font, cw * 7 // 16 - 2, color=(0, 0, 0))

                if (setting('features.levels_enabled')):
                    if (setting('features.marriage_enabled') and ship.level > setting('levels.level_cap')):
                        ring = Image.open(small_ico_ring_img)
                        ring = ring.resize((ch // 3 - 4, ch // 3 - 4))
                        ring_loc = (x + cw * 8 // 9 - 2, y + ch * 5 // 8 + 2)
                        draw.ellipse(
                            (ring_loc, tuple(map(sum, zip(ring_loc, ring.size)))), fill=(0, 0, 0))
                        img.paste(ring, ring_loc, mask=ring)
                    font = ImageFont.truetype(
                        "fonts/trebucbd.ttf", ch * 3 // 8)
                    lvl_str = "Lv. %02d" % (ship.level)
                    draw_squish_text(img, (x + 2 + cw * 11 // 16, y + ch * 3 // 4 - 2),
                                     lvl_str, font, cw // 3 - 4, color=(0, 0, 0))
                    if (ship.is_remodel_ready()):
                        draw.rectangle((x + cw // 2 + 2, y + ch * 9 // 16, x + cw * 31 // 32, y + ch * 15 // 16),
                                       outline=(50, 0, 250), width=2)

                cir_start_x = x + 3
                cir_start_y = y + 3
                use_damaged = False  # TODO check if use damaged image
                ico = base.get_cg(ico=True, dmg=use_damaged)
                ico = ico.resize((int(ch * 1.5) - 6, ch - 6), Image.BILINEAR)
                pxls = ico.load()
                grad_start = int(ico.size[0] * 0.75)
                grad_end = ico.size[0]
                for ix in range(grad_start, grad_end):
                    for iy in range(ico.size[1]):
                        fade_amt = (ix - grad_start) / (grad_end - grad_start)
                        fade_amt *= fade_amt
                        new_alpha = int(pxls[ix, iy][3] * (1 - fade_amt))
                        pxls[ix, iy] = pxls[ix, iy][:3] + (new_alpha,)
                img.paste(ico, (cir_start_x, cir_start_y), ico)

                draw.rectangle((x, y, x + cw - 1,
                                y + ch - 1), outline=shade_color, width=3)
            shade = not shade
            indx += 1
        if(sy % 2 == 0):
            shade = not shade

    draw = ImageDraw.Draw(img)
    # start position of footer
    x, y = (0, layout['image_size'][1] * antialias_value)
    fw, fh = (w, layout['lower_padding'] * antialias_value)  # size of footer

    display_name = "%s#%s" % (member.name, member.discriminator)
    font = ImageFont.truetype("fonts/framd.ttf", fh * 3 // 4)
    o_txt = namesub("<ship_plural.title>") if not only_dupes else "Dupes"
    draw.text((x + 10, y + fh // 8), "%s's %s" % (display_name, o_txt),
              font=font, fill=(0, 0, 0))

    font = ImageFont.truetype("fonts/framdit.ttf", fh // 2)
    pg_txt = "Page %s of %s" % (page, pages_needed)
    pgw, pgh = draw.textsize(pg_txt, font=font)
    pgx, pgy = (fw - pgw - 2, y + fh - pgh - 2)
    draw.text((pgx, pgy), pg_txt, font=font, fill=(50, 50, 50))

    font = ImageFont.truetype("fonts/trebucbd.ttf", fh * 3 // 8)
    rsc_x, rsc_y = (fw * 21 // 32, y + 1)

    txt_fuel = "%05d" % (user.fuel)
    txt_ammo = "%05d" % (user.ammo)
    txt_steel = "%05d" % (user.steel)
    txt_bauxite = "%05d" % (user.bauxite)
    txt_ships = "%03d / %03d" % (len(ship_pool), user.shipslots)
    txt_rings = "%01d" % (user.rings)

    txt_w, txt_h = draw.textsize(txt_fuel, font)

    ico_size = (fh * 3 // 8 + 2, fh * 3 // 8 + 2)
    if (setting('features.resources_enabled')):
        ico_fuel = Image.open(DIR_PATH + '/icons/fuel.png').resize(ico_size,
                                                                   Image.LINEAR)
        ico_ammo = Image.open(DIR_PATH + '/icons/ammo.png').resize(ico_size,
                                                                   Image.LINEAR)
        ico_steel = Image.open(DIR_PATH + '/icons/steel.png').resize(ico_size,
                                                                     Image.LINEAR)
        ico_bauxite = Image.open(DIR_PATH + '/icons/bauxite.png') \
            .resize(ico_size, Image.LINEAR)
    ico_ships = Image.open(DIR_PATH + '/icons/ship.png').resize(ico_size,
                                                                Image.LINEAR)
    if (setting('features.marriage_enabled') and setting('levels.marriage_ring_required')):
        ico_rings = Image.open(DIR_PATH + '/icons/marriagepapers.png') \
            .resize(ico_size, Image.LINEAR)

    x_off = ico_size[0] + txt_w + 6
    y_off = ico_size[1] + 2
    toff_x, toff_y = (ico_size[0] + 2, (ico_size[1] - txt_h) // 2)

    if (setting('features.resources_enabled')):
        draw.text((rsc_x + toff_x, rsc_y + toff_y), txt_fuel, font=font,
                  fill=(0, 0, 0))
        draw.text((rsc_x + toff_x, rsc_y + toff_y + y_off), txt_ammo, font=font,
                  fill=(0, 0, 0))
        draw.text((rsc_x + toff_x + x_off, rsc_y + toff_y), txt_steel, font=font,
                  fill=(0, 0, 0))
        draw.text((rsc_x + toff_x + x_off, rsc_y + toff_y + y_off), txt_bauxite,
                  font=font, fill=(0, 0, 0))
    draw.text((rsc_x + toff_x + x_off * 2, rsc_y + toff_y), txt_ships,
              font=font, fill=(0, 0, 0))
    if (setting('features.marriage_enabled') and setting('levels.marriage_ring_required')):
        draw.text((rsc_x + toff_x + int(x_off * 3.5), rsc_y + toff_y), txt_rings,
                  font=font, fill=(0, 0, 0))

    if (setting('features.resources_enabled')):
        img.paste(ico_fuel, (rsc_x, rsc_y), mask=ico_fuel)
        img.paste(ico_ammo, (rsc_x, rsc_y + y_off), mask=ico_fuel)
        img.paste(ico_steel, (rsc_x + x_off, rsc_y), mask=ico_fuel)
        img.paste(ico_bauxite, (rsc_x + x_off, rsc_y + y_off), mask=ico_fuel)
    img.paste(ico_ships, (rsc_x + x_off * 2, rsc_y), mask=ico_ships)
    if (setting('features.marriage_enabled') and setting('levels.marriage_ring_required')):
        img.paste(ico_rings, (rsc_x + int(x_off * 3.5), rsc_y), mask=ico_rings)

    img = img.resize((w // antialias_value, h //
                      antialias_value), Image.ANTIALIAS)

    r = io.BytesIO()
    img.save(r, format="PNG")
    return r
Ejemplo n.º 18
0
import datetime
import subprocess
import logging
from settings import setting, namesub, setting_random

COMMAND_PREFIX = setting('command_prefix')

bot = commands.Bot(command_prefix=COMMAND_PREFIX, case_insensitive=True,
                   activity=discord.Game(type=0, name=setting('bot_playing')))

DROP_COOLDOWN = setting('cooldowns.drop')
CRAFTING_COOLDOWN = setting('cooldowns.craft')
TRAINING_COOLDOWN = setting('cooldowns.train')


@bot.command(help=namesub("Show a <ship.title> from your inventory"), usage="[Ship ID]")
async def show(ctx, shipid: int):
    """Show the specified ship from the user's inventory."""
    did = ctx.author.id
    inv = userinfo.get_user_inventory(did)
    ins = [x for x in inv.inventory if x.invid == shipid]
    if (len(ins) > 0):
        ship_instance = ins.pop()
        base = ship_instance.base()
        image_file = imggen.generate_ship_card(ctx.bot, ship_instance)
        if (ship_instance.level > setting('levels.level_cap')):
            quote = base.get_quote('married')
        else:
            quote = base.get_quote('idle')
        await ctx.send(file=discord.File(io.BytesIO(image_file.getvalue()),
                                         filename="image.png"),