Пример #1
0
def get_drop_chances(weight_function=get_basic_weight,
                     only_droppable=False,
                     only_craftable=False):
    """Get the chances that each rarity can drop.

    Parameters
    ----------
    weight_function : function
        Function used to determine weight based on passed ShipBase.
    only_droppable : bool
        If True, only select from the ships which can be dropped.
    only_craftable : bool
        If True, only select from the ships which can be crafted.

    Returns
    -------
    list
        List of size 8, floats equalling percent the respective rarity can
        drop.
    """
    ships = ship_stats.get_all_ships(allow_remodel=False,
                                     only_droppable=only_droppable,
                                     only_craftable=only_craftable)

    total_pool = sum(weight_function(s) for s in ships)
    totals = [0] * 8
    for rarity in range(8):
        rtotal = sum(
            weight_function(s) for s in ships if s.rarity == rarity + 1)
        totals[rarity] = rtotal
    return list(map(lambda x: x / total_pool, totals))
Пример #2
0
def get_random_drop(owner,
                    weight_function=get_basic_weight,
                    only_droppable=False,
                    only_craftable=False):
    """Get a random ship drop, as a ShipInstance.

    Parameters
    ----------
    owner : int
        Discord ID of the owner of the drop.
    weight_function : function
        Function used to determine weight based on passed ShipBase.
    only_droppable : bool
        If True, only select from the ships which can be dropped.
    only_craftable : bool
        If True, only select from the ships which can be crafted.
    """
    ships = ship_stats.get_all_ships(allow_remodel=False,
                                     only_droppable=only_droppable,
                                     only_craftable=only_craftable)

    total_pool = sum(weight_function(s) for s in ships)
    val = random.randrange(total_pool)
    for ship in ships:
        val -= weight_function(ship)
        if (val <= 0):
            return ship_stats.ShipInstance.new(ship.sid, owner)
            break
    return ship_stats.ShipInstance.new(11, owner)
Пример #3
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)
Пример #4
0
async def show_birthdays(bdays, channels, mon, day):
    ship_names = []
    look = "%02d-%02d" % (day, mon)
    for k, v in bdays.items():
        if (v == look):
            ship_names.append(k)
    if (len(ship_names) > 0):
        ships = ship_stats.get_all_ships(allow_remodel=False)
        msg = "Happy birthday, %s!"
        files = []
        for sn in ship_names:
            for sb in ships:
                if (sb.name.lower() == sn.lower()):
                    bio = imggen.get_birthday_image(sb)
                    files.append((bio, sb.name))
        for c in channels:
            for ft in files:
                bio, sbname = ft
                f = discord.File(io.BytesIO(bio.getvalue()), filename="image.png")
                await c.send(file=f, content=(msg % sbname))
    else:
        msg = "There are no birthdays today. (%02d/%02d)" % (day, mon)
        send_task = [c.send(content=msg) for c in channels]
        await asyncio.gather(*send_task)
Пример #5
0
def get_craft_from_resources(owner, f, a, s, b):
    """Get a random ship craft given the resource amounts to use."""
    nnr = nearest_n_recipes(f, a, s, b)

    # this is complicated so here's a simple explanation:
    # in (n - 1) steps where n is # of recipes taken from above:
    #   - take closest remaining recipe based on distance
    #   - get % of total distance of remaining recipes closest takes up
    #   - remove closest from list, add it with its % to the final list
    #   - scale next steps' % based on how much % the previous steps' closest
    #        were
    # after, take the last remaining value and set its # so everything equals 1
    dist_map = list(map(lambda x: (x[0], math.sqrt(x[1])), nnr))
    final_map = []
    pcnt_left = 1.0
    for i in range(len(nnr) - 1):
        total_dist = sum(map(lambda x: x[1], dist_map))
        if (total_dist == 0):
            break
        dist_map_inv = list(
            map(lambda x: (x[0], pcnt_left * (total_dist - x[1]) / total_dist),
                dist_map))
        dist_map.sort(key=lambda x: -x[1])
        dist_map_inv.sort(key=lambda x: x[1])
        app = dist_map_inv.pop()
        pcnt_left -= app[1]
        final_map.append(app)
        dist_map.pop()
    total_pcnt = sum(map(lambda x: x[1], final_map))
    last = dist_map.pop()
    final_map.append((last[0], 1 - total_pcnt))

    weight_bonus_shiptype = list(
        map(lambda x: (x[0], int(x[1] * WEIGHT_BONUS_TYPE)), final_map))
    weight_bonus_rarity = list(
        map(lambda x: (x[0], int(x[1] * WEIGHT_BONUS_RARITY)), final_map))

    weight_boost = {}

    all_types = []
    for recipe, _m in final_map:
        all_types.extend(map(lambda x: x.discriminator, recipe.types))
    applicable_ships = set(
        ship_stats.get_all_ships(allow_remodel=False,
                                 only_craftable=True,
                                 type_discrims=all_types))

    # shiptype boost
    for recipe, weight_bonus in weight_bonus_shiptype:
        award_base = weight_bonus // len(applicable_ships)
        for s in applicable_ships:
            if (s.sid not in weight_boost):
                weight_boost[s.sid] = 0
            weight_boost[s.sid] += award_base

    # rarity boost (only for shiptypes above)
    # boost based on dist to rarity focus (max 2)
    for recipe, weight_bonus in weight_bonus_rarity:
        inv_dist = list(
            map(lambda x: (x, 2 - abs(recipe.rarityfocus - x.rarity)),
                applicable_ships))
        rarity_total = sum([x[1] for x in inv_dist if x[1] > 0])
        rarity_award = weight_bonus // rarity_total
        for s, rd in inv_dist:
            if (rd <= 0):
                continue
            weight_boost[s.sid] += rarity_award * rd

    def weight_function(ship):
        wb = ship.sid in weight_boost and weight_boost[ship.sid] > 0
        return (drophandler.get_basic_weight(ship) // (.5 if wb else 3)) \
            + (weight_boost[ship.sid] if wb else 0)

    drop = drophandler.get_random_drop(owner,
                                       weight_function=weight_function,
                                       only_craftable=True)
    return drop
Пример #6
0
async def on_ready():
    """Run when the bot initializes fully."""
    print("Ready on {} ({})".format(bot.user.name, bot.user.id))
    logging.info("Loading ships...")
    ship_stats.get_all_ships()  # add ships to cache
    logging.info("Ships loaded")