Exemple #1
0
async def one_eye_dm(id_user = None, id_server = None, poi = None):
    poi_obj = poi_static.id_to_poi.get(poi)
    client = ewutils.get_client()
    server = client.get_guild(id_server)

    server = client.get_guild(str(id_server))

    server = client.get_guild(int(id_server))

    id_player = EwPlayer(id_user=id_user, id_server=id_server)

    if poi_obj.pvp:
        try:
            recipients = bknd_core.execute_sql_query(
                "SELECT {id_user} FROM mutations WHERE {id_server} = %s AND {mutation} = %s and {data} = %s".format(
                    data=ewcfg.col_mutation_data,
                    id_server=ewcfg.col_id_server,
                    id_user=ewcfg.col_id_user,
                    mutation=ewcfg.col_id_mutation,
                ), (
                    id_server,
                    ewcfg.mutation_id_oneeyeopen,
                    str(id_user),
                ))
            for recipient in recipients:
                member = server.get_member(int(recipient[0]))
                mutation = EwMutation(id_server=id_server, id_user=recipient[0], id_mutation=ewcfg.mutation_id_oneeyeopen)
                mutation.data = ""
                mutation.persist()
                await fe_utils.send_message(client, member, fe_utils.formatMessage(member, "{} is stirring...".format(id_player.display_name)))

        except:
            ewutils.logMsg("Failed to do OEO notificaitons for {}.".format(id_user))
Exemple #2
0
async def lobbywarning(cmd):
    playermodel = EwPlayer(id_user=cmd.message.author.id)
    usermodel = EwUser(id_server=playermodel.id_server,
                       id_user=cmd.message.author.id)

    poi = poi_static.id_to_poi.get(usermodel.poi)
    if poi.is_apartment:
        response = "Try that in a DM to ENDLESS WAR or in your apartment."
    else:
        response = "You're not in an apartment."
    return await fe_utils.send_message(
        cmd.client, cmd.message.channel,
        fe_utils.formatMessage(cmd.message.author, response))
Exemple #3
0
async def toss_squatters(user_id=None, server_id=None, keepKeys=False):
    player_info = EwPlayer(id_user=user_id)
    apt_info = EwApartment(id_user=user_id, id_server=server_id)

    client = ewutils.get_client()
    server = client.get_guild(server_id)

    member_data = server.get_member(player_info.id_user)

    if player_info.id_server != None and member_data != None:
        try:
            conn_info = bknd_core.databaseConnect()
            conn = conn_info.get('conn')
            cursor = conn.cursor()
            client = ewutils.get_client()

            # get all players visiting an evicted apartment and kick them out
            cursor.execute(
                "SELECT {} FROM users WHERE {} = %s AND {} = %s".format(
                    ewcfg.col_id_user,
                    ewcfg.col_visiting,
                    ewcfg.col_id_server,
                ), (
                    member_data.id,
                    server_id,
                ))

            squatters = cursor.fetchall()
            key_1 = EwItem(id_item=apt_info.key_1).id_owner
            key_2 = EwItem(id_item=apt_info.key_2).id_owner
            for squatter in squatters:
                sqt_data = EwUser(id_user=squatter[0],
                                  id_server=player_info.id_server)
                if keepKeys and (sqt_data.id_user == key_1
                                 or sqt_data.id_user == key_2):
                    pass
                else:
                    server = ewcfg.server_list[sqt_data.id_server]
                    member_object = server.get_member(squatter[0])
                    sqt_data.poi = sqt_data.poi[3:] if sqt_data.poi[
                        3:] in poi_static.id_to_poi.keys() else sqt_data.poi
                    sqt_data.visiting = ewcfg.location_id_empty
                    sqt_data.persist()
                    await ewrolemgr.updateRoles(client=client,
                                                member=member_object)
        finally:
            # Clean up the database handles.
            cursor.close()
            bknd_core.databaseClose(conn_info)
async def tracker(cmd):
    user_data = EwUser(member=cmd.message.author)
    mutations = user_data.get_mutations()

    if ewcfg.mutation_id_oneeyeopen not in mutations:
        response = "Your third eye is tucked snugly into your forehead. Actually, who are you fooling? You don't have a third eye. What, are you stupid?"
    else:
        mutation = EwMutation(id_server=cmd.message.guild.id, id_user=cmd.message.author.id, id_mutation=ewcfg.mutation_id_oneeyeopen)
        if mutation.data == "":
            response = "Your third eye isn't tracking anyone right now."
        else:
            target = EwPlayer(id_server=cmd.message.guild.id, id_user=mutation.data)
            response = "You're tracking {} right now. LOL, they're lookin pretty dumb over there.".format(target.display_name)

    return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
Exemple #5
0
async def order(cmd):
    user_data = EwUser(member=cmd.message.author)
    mutations = user_data.get_mutations()
    if user_data.life_state == ewcfg.life_state_shambler and user_data.poi != ewcfg.poi_id_nuclear_beach_edge:
        response = "You lack the higher brain functions required to {}.".format(cmd.tokens[0])
        return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))

    market_data = EwMarket(id_server=cmd.guild.id)
    currency_used = 'slime'
    current_currency_amount = user_data.slimes
    # poi = ewmap.fetch_poi_if_coordless(cmd.message.channel.name)
    poi = poi_static.id_to_poi.get(user_data.poi)
    if poi is None or len(poi.vendors) == 0 or ewutils.channel_name_is_poi(cmd.message.channel.name) == False:
        # Only allowed in the food court.
        response = "There’s nothing to buy here. If you want to purchase some items, go to a sub-zone with a vendor in it, like the food court, the speakeasy, or the bazaar."
    else:
        poi = poi_static.id_to_poi.get(user_data.poi)
        district_data = EwDistrict(district=poi.id_poi, id_server=user_data.id_server)

        shambler_multiplier = 1  # for speakeasy during shambler times

        if district_data.is_degraded():
            if poi.id_poi == ewcfg.poi_id_speakeasy:
                shambler_multiplier = 4
            else:
                response = "{} has been degraded by shamblers. You can't {} here anymore.".format(poi.str_name, cmd.tokens[0])
                return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
        # value = ewutils.flattenTokenListToString(cmd.tokens[1:2])

        # if cmd.tokens_count > 1:
        #	value = cmd.tokens[1]
        #	value = value.lower()

        value = None

        togo = False
        if cmd.tokens_count > 1:
            for token in cmd.tokens[1:]:
                if token.startswith('<@') == False and token.lower() not in "togo":  # togo can be spelled together or separate
                    value = token
                    break

            for token in cmd.tokens[1:]:
                if token.lower() in "togo":  # lets people get away with just typing only to or only go (or only t etc.) but whatever
                    togo = True
                    break

        # Finds the item if it's an EwGeneralItem.

        if value == "mylittleponyfigurine":
            value = random.choice(static_items.furniture_pony)

        item = static_items.item_map.get(value)

        item_type = ewcfg.it_item
        if item != None:
            item_id = item.id_item
            name = item.str_name

        # Finds the item if it's an EwFood item.
        if item == None:
            item = static_food.food_map.get(value)
            item_type = ewcfg.it_food
            if item != None:
                item_id = item.id_food
                name = item.str_name

        # Finds the item if it's an EwCosmeticItem.
        if item == None:
            item = static_cosmetics.cosmetic_map.get(value)
            item_type = ewcfg.it_cosmetic
            if item != None:
                item_id = item.id_cosmetic
                name = item.str_name

        if item == None:
            item = static_items.furniture_map.get(value)
            item_type = ewcfg.it_furniture
            if item != None:
                item_id = item.id_furniture
                name = item.str_name
                if item_id in static_items.furniture_pony:
                    item.vendors = [ewcfg.vendor_bazaar]

        if item == None:
            item = static_weapons.weapon_map.get(value)
            item_type = ewcfg.it_weapon
            if item != None:
                item_id = item.id_weapon
                name = item.str_weapon

        if item == None:
            item = static_relic.relic_map.get(value)
            item_type = ewcfg.it_relic
            if item != None and relic_utils.canCreateRelic(item.id_relic, cmd.guild.id):
                item_id = item.id_relic
                name = item.str_name
            elif item != None:
                item = None


        if item != None:
            item_type = item.item_type
            # Gets a vendor that the item is available and the player currently located in
            try:
                current_vendor = (set(item.vendors).intersection(set(poi.vendors))).pop()
            except:
                current_vendor = None

            # Check if the item is available in the current bazaar item rotation
            if current_vendor == ewcfg.vendor_bazaar:
                if item_id not in market_data.bazaar_wares.values():
                    if item_id in static_items.furniture_pony and "mylittleponyfigurine" in market_data.bazaar_wares.values():
                        pass
                    else:
                        current_vendor = None


            if current_vendor is None or len(current_vendor) < 1:
                response = "Check the {} for a list of items you can {}.".format(ewcfg.cmd_menu, ewcfg.cmd_order)

            else:
                response = ""

                value = item.price

                premium_purchase = True if item_id in ewcfg.premium_items else False
                if premium_purchase:
                    togo = True  # Just in case they order a premium food item, don't make them eat it right then and there.

                    if ewcfg.cd_premium_purchase > (int(time.time()) - user_data.time_lastpremiumpurchase):
                        response = "That item is in very limited stock! The vendor asks that you refrain from purchasing it for a day or two."
                        return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))

                    elif ewcfg.cd_new_player > (int(time.time()) - user_data.time_joined):
                        response = "You've only been in the city for a few days. The vendor doesn't trust you with that item very much..."
                        return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))

                stock_data = None
                company_data = None
                # factor in the current stocks
                for vendor in item.vendors:
                    if vendor in ewcfg.vendor_stock_map:
                        stock = ewcfg.vendor_stock_map.get(vendor)
                        company_data = EwCompany(id_server=user_data.id_server, stock=stock)
                        stock_data = EwStock(id_server=user_data.id_server, stock=stock)

                if stock_data is not None:
                    value *= (stock_data.exchange_rate / ewcfg.default_stock_exchange_rate) ** 0.2

                controlling_faction = poi_utils.get_subzone_controlling_faction(user_data.poi, user_data.id_server)

                if controlling_faction != "":
                    # prices are halved for the controlling gang
                    if controlling_faction == user_data.faction:
                        value /= 2

                    # and 4 times as much for enemy gangsters
                    elif user_data.faction != "":
                        value *= 4

                # raise shambled speakeasy price 4 times
                value *= shambler_multiplier

                # Raise the price for togo ordering. This gets lowered back down later if someone does togo ordering on a non-food item by mistake.
                if togo:
                    value *= 1.5

                if current_vendor == ewcfg.vendor_breakroom and user_data.faction == ewcfg.faction_slimecorp:
                    value = 0

                value = int(value)

                food_ordered = False
                target_data = None

                # Kingpins eat free.
                if (user_data.life_state == ewcfg.life_state_kingpin or user_data.life_state == ewcfg.life_state_grandfoe) and item_type == ewcfg.it_food:
                    value = 0

                if value > current_currency_amount:
                    # Not enough money.
                    response = "A {} costs {:,} {}, and you only have {:,}.".format(name, value, currency_used, current_currency_amount)
                else:
                    mutations = user_data.get_mutations()
                    if random.randrange(5) == 0 and ewcfg.mutation_id_stickyfingers in mutations:
                        value = 0
                        user_data.change_crime(n=ewcfg.cr_larceny_points)

                    inv_response = bknd_item.check_inv_capacity(user_data=user_data, item_type=item_type, return_strings=True, pronoun="You")
                    if inv_response != "" and (item_type != ewcfg.it_food or togo):
                        return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, inv_response))

                    if item_type == ewcfg.it_food:
                        food_ordered = True

                        target = None
                        target_data = None
                        if not togo:  # cant order togo for someone else, you can just give it to them in person
                            if cmd.mentions_count == 1:
                                target = cmd.mentions[0]
                                if target.id == cmd.message.author.id:
                                    target = None

                        if target != None:
                            target_data = EwUser(member=target)
                            if target_data.life_state == ewcfg.life_state_corpse and target_data.get_possession():
                                response = "How are you planning to feed them while they're possessing you?"
                                return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
                            elif target_data.poi != user_data.poi:
                                response = "You can't order anything for them because they aren't here!"
                                return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))

                    elif item_type == ewcfg.it_weapon:

                        if user_data.life_state == ewcfg.life_state_corpse:
                            response = "Ghosts can't hold weapons."
                            return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))

                    item_props = itm_utils.gen_item_props(item)

                    # Only food should have the value multiplied. If someone togo orders a non-food item by mistake, lower it back down.
                    if not food_ordered and togo:
                        value = int(value / 1.5)

                    if currency_used == 'slime':
                        user_data.change_slimes(n=-value, source=ewcfg.source_spending)

                    if company_data is not None:
                        company_data.recent_profits += value
                        company_data.persist()

                    if item.str_name == "arcade cabinet":
                        item_props['furniture_desc'] = random.choice(ewcfg.cabinets_list)
                    elif item.item_type == ewcfg.it_furniture:
                        if "custom" in item_props.get('id_furniture'):
                            if cmd.tokens_count < 4 or cmd.tokens[2] == "" or cmd.tokens[3] == "":
                                response = "You need to specify the customization text before buying a custom item. Come on, isn't that self-evident? (!order [custom item] \"custom name\" \"custom description\")"
                                return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
                            else:
                                customname = cmd.tokens[2]

                                if len(customname) > 32:
                                    response = "That name is too long. ({:,}/32)".format(len(customname))
                                    return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))

                                customdesc = cmd.tokens[3]

                                if len(customdesc) > 500:
                                    response = "That description is too long. ({:,}/500)".format(len(customdesc))
                                    return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))

                                name = item_props['furniture_name'] = item_props['furniture_name'].format(custom=customname)
                                item_props['furniture_desc'] = customdesc
                                item_props['furniture_look_desc'] = item_props['furniture_look_desc'].format(custom=customname)
                                item_props['furniture_place_desc'] = item_props['furniture_place_desc'].format(custom=customname)

                    id_item = bknd_item.item_create(
                        item_type=item_type,
                        id_user=cmd.message.author.id,
                        id_server=cmd.guild.id,
                        stack_max=-1,
                        stack_size=0,
                        item_props=item_props
                    )

                    if value == 0:
                        response = "You swipe a {} from the counter at {}.".format(name, current_vendor)
                    else:
                        response = "You slam {:,} {} down on the counter at {} for {}.".format(value, currency_used, current_vendor, name)

                    if food_ordered and not togo:
                        item_data = EwItem(id_item=id_item)

                        # Eat food on the spot!
                        if target_data != None:

                            target_player_data = EwPlayer(id_user=target_data.id_user)

                            if value == 0:
                                response = "You swipe a {} from the counter at {} and give it to {}.".format(name, current_vendor, target_player_data.display_name)
                            else:
                                response = "You slam {:,} slime down on the counter at {} for {} and give it to {}.".format(value, current_vendor, name, target_player_data.display_name)

                            response += "\n\n*{}*: ".format(target_player_data.display_name) + target_data.eat(item_data)
                            target_data.persist()
                            
                        else:

                            if value == 0:
                                response = "You swipe a {} from the counter at {} and eat it right on the spot.".format(name, current_vendor)
                            else:
                                response = "You slam {:,} slime down on the counter at {} for {} and eat it right on the spot.".format(value, current_vendor, name)

                            user_player_data = EwPlayer(id_user=user_data.id_user)

                            response += "\n\n*{}*: ".format(user_player_data.display_name) + user_data.eat(item_data)
                            user_data.persist()

                    if premium_purchase:
                        user_data.time_lastpremiumpurchase = int(time.time())

                    user_data.persist()

        else:
            response = "Check the {} for a list of items you can {}.".format(ewcfg.cmd_menu, ewcfg.cmd_order)

    # Send the response to the player.
    await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
Exemple #6
0
async def complete_trade(cmd):
    user_data = EwUser(member=cmd.message.author)
    if user_data.life_state == ewcfg.life_state_shambler:
        response = "You lack the higher brain functions required to {}.".format(cmd.tokens[0])
        return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))

    user_trade = ewutils.active_trades.get(user_data.id_user)

    if user_trade != None and len(user_trade) > 0 and user_trade.get("state") > ewcfg.trade_state_proposed:
        user_trade["state"] = ewcfg.trade_state_complete

        trader_id = user_trade.get("trader")
        if ewutils.active_trades.get(trader_id).get("state") != ewcfg.trade_state_complete:
            partner_player = EwPlayer(id_user=trader_id, id_server=user_data.id_server)
            response = "You tell {} that you're ready to finish the trade.".format(partner_player.display_name)

        else:
            trade_partner = EwUser(id_user=trader_id, id_server=user_data.id_server)

            # items this player is offering
            items_offered = {}

            # items the other player is offering
            trader_items_offered = {}

            for item in ewutils.trading_offers.get(user_data.id_user):
                if items_offered.get(item.get("item_type")) != None:
                    items_offered[item.get("item_type")] += 1
                else:
                    items_offered[item.get("item_type")] = 1

            for item in ewutils.trading_offers.get(trade_partner.id_user):
                if trader_items_offered.get(item.get("item_type")) != None:
                    trader_items_offered[item.get("item_type")] += 1
                else:
                    trader_items_offered[item.get("item_type")] = 1

            # check items currently held + items being given to the player - items the player is giving
            # check other user's inventory capacity
            for item_type in items_offered:
                it_held = bknd_item.inventory(
                    id_user=trade_partner.id_user,
                    id_server=trade_partner.id_server,
                    item_type_filter=item_type
                )

                if item_type == ewcfg.it_food:
                    if (len(it_held) + items_offered[ewcfg.it_food] - trader_items_offered.get(ewcfg.it_food, 0)) > trade_partner.get_food_capacity():
                        response = "They can't carry any more food items."
                        return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
                elif item_type == ewcfg.it_weapon:
                    if (len(it_held) + items_offered[ewcfg.it_weapon] - trader_items_offered.get(ewcfg.it_weapon, 0)) > trade_partner.get_weapon_capacity():
                        response = "They can't carry any more weapon items."
                        return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
                else:
                    if (len(it_held) + items_offered[item_type] - trader_items_offered.get(item_type, 0)) > ewcfg.generic_inv_limit:
                        response = "They can't carry any more {}s.".format(item_type)
                        return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))

            # check own user's inventory capacity
            for item_type in trader_items_offered:
                it_held = bknd_item.inventory(
                    id_user=user_data.id_user,
                    id_server=user_data.id_server,
                    item_type_filter=item_type
                )

                if item_type == ewcfg.it_food:
                    if (len(it_held) + trader_items_offered[ewcfg.it_food] - items_offered.get(ewcfg.it_food, 0)) > user_data.get_food_capacity():
                        response = "You can't carry any more food items."
                        return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
                elif item_type == ewcfg.it_weapon:
                    if (len(it_held) + trader_items_offered[ewcfg.it_weapon] - items_offered.get(ewcfg.it_weapon, 0)) > user_data.get_weapon_capacity():
                        response = "You can't carry any more weapon items."
                        return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
                else:
                    if (len(it_held) + trader_items_offered.get(item_type) - items_offered.get(item_type, 0)) > ewcfg.generic_inv_limit:
                        response = "You can't carry any more {}s.".format(item_type)
                        return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))

            for item in list(ewutils.trading_offers.get(user_data.id_user)):
                if item.get("id_item") == user_data.weapon:
                    user_data.weapon = -1
                    user_data.persist()
                elif item.get("id_item") == user_data.sidearm:
                    user_data.sidearm = -1
                    user_data.persist()
                elif item.get("item_type") == ewcfg.it_cosmetic:
                    cosmetic = EwItem(id_item=item.get("id_item"))
                    cosmetic.item_props["adorned"] = 'false'
                    cosmetic.item_props["slimeoid"] = 'false'
                    cosmetic.persist()

                bknd_item.give_item(id_item=item.get("id_item"), id_user=trade_partner.id_user, id_server=trade_partner.id_server)

            for item in list(ewutils.trading_offers.get(trade_partner.id_user)):
                if item.get("id_item") == trade_partner.weapon:
                    trade_partner.weapon = -1
                    trade_partner.persist()
                elif item.get("id_item") == trade_partner.sidearm:
                    trade_partner.sidearm = -1
                    user_data.persist()
                elif item.get("item_type") == ewcfg.it_cosmetic:
                    cosmetic = EwItem(id_item=item.get("id_item"))
                    cosmetic.item_props["adorned"] = 'false'
                    cosmetic.item_props["slimeoid"] = 'false'
                    cosmetic.persist()

                bknd_item.give_item(id_item=item.get("id_item"), id_user=user_data.id_user, id_server=user_data.id_server)

            ewutils.active_trades[user_data.id_user] = {}
            ewutils.active_trades[trade_partner.id_user] = {}

            ewutils.trading_offers[user_data.id_user] = []
            ewutils.trading_offers[trade_partner.id_user] = []

            response = "You shake hands to commemorate another successful deal. That is their hand, right?"
    else:
        response = "You're not trading with anyone right now."

    await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
Exemple #7
0
async def trade(cmd):
    user_data = EwUser(member=cmd.message.author)
    if user_data.life_state == ewcfg.life_state_shambler:
        response = "You lack the higher brain functions required to {}.".format(cmd.tokens[0])
        return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))

    user_trade = ewutils.active_trades.get(user_data.id_user)

    if user_trade != None and len(user_trade) > 0:
        if user_trade.get("state") > ewcfg.trade_state_proposed:

            stacking = True if 'stack' in ewutils.flattenTokenListToString(cmd.tokens[1:]).lower() else False
            sort_by_name = True if 'name' in ewutils.flattenTokenListToString(cmd.tokens[1:]).lower() else False

            stacked_item_map = {}

            # print info about the current trade
            trade_partner = EwPlayer(id_user=user_trade.get("trader"), id_server=user_data.id_server)

            # print player's offers
            response = "Your offers:\n"
            items = ewutils.trading_offers.get(user_data.id_user) if not sort_by_name else sorted(ewutils.trading_offers.get(user_data.id_user), key=lambda item: item.get("name").lower)
            for item in items:
                if not stacking:
                    response_part = "{id_item}: {name} {quantity}\n".format(id_item=item.get("id_item"), name=item.get("name"), quantity=(" x{:,}".format(item.get("quantity")) if (item.get("quantity") > 1) else ""))

                    if len(response) + len(response_part) > 1492:
                        await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
                        response = ""

                    response += response_part

                else:
                    if item.get("name") in stacked_item_map:
                        stacked_item = stacked_item_map.get(item.get("name"))
                        stacked_item["quantity"] += item.get("quantity")
                    else:
                        stacked_item_map[item.get("name")] = deepcopy(item)

            if stacking:
                item_names = stacked_item_map.keys() if not sort_by_name else sorted(stacked_item_map.keys())

                for item_name in item_names:
                    item = stacked_item_map.get(item_name)
                    quantity = item.get('quantity')
                    response_part = "{soulbound_style}{name}{soulbound_style}{quantity}\n".format(
                        name=item.get('name'),
                        soulbound_style=("**" if item.get('soulbound') else ""),
                        quantity=(" **x{:,}**".format(quantity) if (quantity > 0) else "")
                    )

                    if len(response) + len(response_part) > 1492:
                        await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
                        response = ""

                    response += response_part

            if user_trade.get("state") == ewcfg.trade_state_complete:
                response_part = "**You are ready to complete the trade.**"

                if len(response) + len(response_part) > 1492:
                    await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
                    response = ""

                response += response_part

            await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))

            # print partner's offers
            stacked_item_map = {}

            response = trade_partner.display_name + "'s offers:\n"
            items = ewutils.trading_offers.get(trade_partner.id_user) if not sort_by_name else sorted(ewutils.trading_offers.get(trade_partner.id_user), key=lambda item: item.get("name").lower)
            for item in items:
                if not stacking:
                    response_part = "{id_item}: {name} {quantity}\n".format(id_item=item.get("id_item"), name=item.get("name"), quantity=(" x{:,}".format(item.get("quantity")) if (item.get("quantity") > 1) else ""))

                    if len(response) + len(response_part) > 1492:
                        await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
                        response = ""

                    response += response_part

                else:
                    if item.get("name") in stacked_item_map:
                        stacked_item = stacked_item_map.get(item.get("name"))
                        stacked_item["quantity"] += item.get("quantity")
                    else:
                        stacked_item_map[item.get("name")] = deepcopy(item)

            if stacking:
                item_names = stacked_item_map.keys() if not sort_by_name else sorted(stacked_item_map.keys())

                for item_name in item_names:
                    item = stacked_item_map.get(item_name)
                    quantity = item.get('quantity')
                    response_part = "{soulbound_style}{name}{soulbound_style}{quantity}\n".format(
                        name=item.get('name'),
                        soulbound_style=("**" if item.get('soulbound') else ""),
                        quantity=(" **x{:,}**".format(quantity) if (quantity > 0) else "")
                    )

                    if len(response) + len(response_part) > 1492:
                        await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
                        response = ""

                    response += response_part

            if ewutils.active_trades.get(trade_partner.id_user).get("state") == ewcfg.trade_state_complete:
                response_part = '**They are ready to complete the trade.**'

                if len(response) + len(response_part) > 1492:
                    await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
                    response = ""

                response += response_part

            await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))

    else:
        if cmd.mentions_count == 0:
            return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, "Who do you want to trade with?"))

        if cmd.mentions_count > 1:
            return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, "You can only trade with one person at a time."))

        trade_partner = EwUser(member=cmd.mentions[0])

        if user_data.id_user == trade_partner.id_user:
            return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, "Huh?"))

        if user_data.poi != trade_partner.poi:
            return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, "You must be in the same location as someone to trade with them."))

        if ewutils.active_trades.get(trade_partner.id_user) != None and len(ewutils.active_trades.get(trade_partner.id_user)) > 0:
            return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, "Wait for them to finish their business before trying to trade with them."))

        ewutils.active_trades[user_data.id_user] = {"state": ewcfg.trade_state_proposed, "trader": trade_partner.id_user}
        ewutils.active_trades[trade_partner.id_user] = {"state": ewcfg.trade_state_proposed, "trader": user_data.id_user}

        await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.mentions[0], "{user} wants to trade with you. Do you {accept} or {refuse}?".format(user=cmd.message.author.display_name, accept=ewcfg.cmd_accept, refuse=ewcfg.cmd_refuse)))

        accepted = False

        try:
            member = cmd.mentions[0]
            msg = await cmd.client.wait_for('message', timeout=30, check=lambda message: message.author == member and
                                                                                         message.content.lower() in [ewcfg.cmd_accept, ewcfg.cmd_refuse])

            if msg != None and msg.content.lower() == ewcfg.cmd_accept:
                accepted = True
        except:
            accepted = False

        if accepted:
            ewutils.active_trades[user_data.id_user] = {"state": ewcfg.trade_state_ongoing, "trader": trade_partner.id_user}
            ewutils.active_trades[trade_partner.id_user] = {"state": ewcfg.trade_state_ongoing, "trader": user_data.id_user}

            ewutils.trading_offers[user_data.id_user] = []

            ewutils.trading_offers[trade_partner.id_user] = []

            response = "You both head into a shady alleyway nearby to conduct your business."

        else:
            ewutils.active_trades[user_data.id_user] = {}
            ewutils.active_trades[trade_partner.id_user] = {}
            response = "They didn't respond in time."

        await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
Exemple #8
0
async def rent_time(id_server=None):
    try:
        conn_info = bknd_core.databaseConnect()
        conn = conn_info.get('conn')
        cursor = conn.cursor()
        client = ewutils.get_client()
        if id_server != None:
            # get all players with apartments. If a player is evicted, thir rent is 0, so this will not affect any bystanders.
            cursor.execute(
                "SELECT apartment.rent, users.id_user FROM users INNER JOIN apartment ON users.id_user=apartment.id_user WHERE users.id_server = %s AND apartment.id_server = %s AND apartment.rent > 0"
                .format(), (
                    id_server,
                    id_server,
                ))

            landowners = cursor.fetchall()

            for landowner in landowners:
                owner_id_user = int(landowner[1])
                owner_rent_price = landowner[0]

                user_data = EwUser(id_user=owner_id_user, id_server=id_server)
                user_poi = poi_static.id_to_poi.get(user_data.poi)
                poi = poi_static.id_to_poi.get(user_data.apt_zone)

                if owner_rent_price > user_data.slimecoin:

                    if (user_poi.is_apartment
                            and user_data.visiting == ewcfg.location_id_empty):
                        user_data.poi = user_data.apt_zone  # toss out player
                        user_data.persist()
                        server = ewcfg.server_list[user_data.id_server]
                        member_object = server.get_member(owner_id_user)

                        await ewrolemgr.updateRoles(client=client,
                                                    member=member_object)
                        player = EwPlayer(id_user=owner_id_user)
                        response = "{} just got evicted. Point and laugh, everyone.".format(
                            player.display_name)
                        await fe_utils.send_message(
                            client, fe_utils.get_channel(server, poi.channel),
                            response)

                    user_data = EwUser(id_user=owner_id_user,
                                       id_server=id_server)
                    user_apt = EwApartment(id_user=owner_id_user,
                                           id_server=id_server)
                    poi = poi_static.id_to_poi.get(user_data.apt_zone)

                    toss_items(id_user=str(user_data.id_user) + 'closet',
                               id_server=user_data.id_server,
                               poi=poi)
                    toss_items(id_user=str(user_data.id_user) + 'fridge',
                               id_server=user_data.id_server,
                               poi=poi)
                    toss_items(id_user=str(user_data.id_user) + 'decorate',
                               id_server=user_data.id_server,
                               poi=poi)

                    user_data.apt_zone = ewcfg.location_id_empty
                    user_data.persist()
                    user_apt.rent = 0
                    user_apt.poi = " "
                    user_apt.persist()

                    await toss_squatters(user_id=user_data.id_user,
                                         server_id=id_server)

                else:
                    user_data.change_slimecoin(
                        n=-owner_rent_price,
                        coinsource=ewcfg.coinsource_spending)
                    user_data.persist()
    finally:
        cursor.close()
        bknd_core.databaseClose(conn_info)
Exemple #9
0
async def stock_market_tick(stock_data, id_server):
    market_data = EwMarket(id_server=id_server)
    company_data = EwCompany(id_server=id_server, stock=stock_data.id_stock)
    crashstate = EwGamestate(id_server=id_server,
                             id_state='stockcrashdive').bit

    # Nudge the value back to stability.
    market_rate = stock_data.market_rate
    if market_rate >= 1030:
        market_rate -= 10
    elif market_rate <= 970:
        market_rate += 10

    # Invest/Withdraw effects
    coin_rate = 0
    #stock_at_last_tick = EwStock(id_server=id_server, stock=stock_data.id_stock, timestamp=market_data.time_lasttick)
    #latest_stock = EwStock(id_server=id_server, stock=stock_data.id_stock)
    if stock_data.previous_entry != 0:
        total_shares = [stock_data.total_shares, stock_data.previous_entry[4]]
    else:
        total_shares = [
            stock_data.total_shares,
            EwStock(id_server=id_server,
                    stock=stock_data.id_stock,
                    timestamp=market_data.time_lasttick).total_shares
        ]

    # Add profit bonus.
    profits = company_data.recent_profits
    profit_bonus = profits / 100  # - 1 * ((latest_stock.exchange_rate / ewcfg.default_stock_exchange_rate) ** 0.2)
    profit_bonus = min(50, max(profit_bonus, -50))
    market_rate += (profit_bonus / 2)

    if total_shares[0] != total_shares[1]:
        # Positive if net investment, negative if net withdrawal.
        coin_change = (total_shares[0] - total_shares[1])
        coin_rate = ((coin_change * 1.0) /
                     total_shares[1] if total_shares[1] != 0 else 1)

        if coin_rate > 1.0:
            coin_rate = 1.0
        elif coin_rate < -0.5:
            coin_rate = -0.5

        coin_rate = round((coin_rate *
                           ewcfg.max_iw_swing) if coin_rate > 0 else (
                               coin_rate * 2 * ewcfg.max_iw_swing))

    market_rate += coin_rate

    # Tick down the boombust cooldown.
    if stock_data.boombust < 0:
        stock_data.boombust += 1
    elif stock_data.boombust > 0:
        stock_data.boombust -= 1

    # Adjust the market rate.
    fluctuation = 0  # (random.randrange(5) - 2) * 100
    noise = (random.randrange(19) - 9) * 2
    subnoise = (random.randrange(13) - 6)

    # Some extra excitement!
    if noise == 0 and subnoise == 0:
        boombust = (random.randrange(3) - 1) * 200

        if crashstate == 1 and boombust > 0:
            boombust = -boombust

        # If a boombust occurs shortly after a previous boombust, make sure it's the opposite effect. (Boom follows bust, bust follows boom.)
        if (stock_data.boombust > 0
                and boombust > 0) or (stock_data.boombust < 0
                                      and boombust < 0):
            boombust *= -1

        if boombust != 0:
            stock_data.boombust = ewcfg.cd_boombust

            if boombust < 0:
                stock_data.boombust *= -1
    else:
        boombust = 0

    market_rate += fluctuation + noise + subnoise + boombust

    if market_rate > 500 and crashstate == 1:
        market_rate = round(market_rate / 1.25)

    if market_rate < 300:
        market_rate = (300 + noise + subnoise)

    # percentage = ((market_rate / 10) - 100)
    # percentage_abs = percentage * -1

    exchange_rate_increase = round(
        (market_rate - ewcfg.default_stock_market_rate) *
        min(stock_data.exchange_rate, ewcfg.default_stock_exchange_rate) /
        ewcfg.default_stock_market_rate)

    percentage = exchange_rate_increase / stock_data.exchange_rate
    percentage_abs = percentage * -1

    # negative exchange rate causes problems, duh
    # exchange_rate_increase = max(exchange_rate_increase, -stock_data.exchange_rate + 1000)

    points = abs(exchange_rate_increase / 1000.0)

    stock_data.exchange_rate += exchange_rate_increase
    stock_data.market_rate = market_rate

    # Give some indication of how the market is doing to the users.
    response = ewcfg.stock_emotes.get(
        stock_data.id_stock) + ' ' + ewcfg.stock_names.get(
            stock_data.id_stock) + ' '

    if stock_data.exchange_rate < 1000:
        response += 'has gone bankrupt!'
        if stock_data.total_shares > 0:
            majority_shareholder = get_majority_shareholder(
                stock=stock_data.id_stock, id_server=id_server)
            player_data = EwPlayer(id_user=majority_shareholder)
            shares = getUserTotalShares(stock=stock_data.id_stock,
                                        id_user=majority_shareholder,
                                        id_server=stock_data.id_server)
            shares_lost = round(shares * 0.9)
            stock_data.total_shares -= shares_lost
            updateUserTotalShares(stock=stock_data.id_stock,
                                  id_user=majority_shareholder,
                                  id_server=stock_data.id_server,
                                  shares=shares - shares_lost)
            response += ' The majority shareholder {} is held responsible. SlimeCorp seizes 90% of their shares in the company to pay for the damages.'.format(
                player_data.display_name)
            stock_data.exchange_rate = 10000
        else:
            response += ' SlimeCorp pumps several billion slimecoin into bailing the company out and a new image campaign.'
            stock_data.exchange_rate = ewcfg.default_stock_exchange_rate
            stock_data.market_rate = ewcfg.default_stock_market_rate
    else:
        # Market is up ...
        if market_rate > 1200:
            response += 'is skyrocketing!!! Slime stock is up {p:.3g} points!!!'.format(
                p=points)
        elif market_rate > 1100:
            response += 'is booming! Slime stock is up {p:.3g} points!'.format(
                p=points)
        elif market_rate > 1000:
            response += 'is doing well. Slime stock is up {p:.3g} points.'.format(
                p=points)
        # Market is down ...
        elif market_rate < 800:
            response += 'is plummeting!!! Slime stock is down {p:.3g} points!!!'.format(
                p=points)
        elif market_rate < 900:
            response += 'is stagnating! Slime stock is down {p:.3g} points!'.format(
                p=points)
        elif market_rate < 1000:
            response += 'is a bit sluggish. Slime stock is down {p:.3g} points.'.format(
                p=points)
        # Perfectly balanced
        else:
            response += 'is holding steady. No change in slime stock value.'

    response += ' ' + ewcfg.stock_emotes.get(stock_data.id_stock)

    stock_data.persist()

    company_data.total_profits += company_data.recent_profits
    company_data.recent_profits = 0
    company_data.persist()

    # Send the announcement.
    return response
Exemple #10
0
def can_slimeoid_battle(challenger: EwUser = None,
                        challengee=None,
                        challenger_slimeoid: EwSlimeoid = None,
                        challengee_slimeoid: EwSlimeoid = None,
                        bet: int = 0):
    response = ""
    time_now = int(time.time())
    # Gotta have a challenger, otherwise do nothing
    if challenger:
        challenger_data = challenger
        challenger_player = EwPlayer(id_user=challenger_data.id_user)
        ally_slimeoid = None
        target_slimeoid = None

        # If supplied a slimeoid, use that - otherwise we just grab it
        if challenger_slimeoid:
            ally_slimeoid = challenger_slimeoid
        else:
            ally_slimeoid = EwSlimeoid(member=challenger)

        # Challenger

        if ally_slimeoid.life_state != ewcfg.slimeoid_state_active:
            response = "You do not have a Slimeoid ready to battle with!"

        elif challenger_data.life_state == ewcfg.life_state_corpse:
            response = "Your Slimeoid won't battle for you while you're dead."

        elif (time_now -
              ally_slimeoid.time_defeated) < ewcfg.cd_slimeoiddefeated:
            time_until = ewcfg.cd_slimeoiddefeated - (
                time_now - ally_slimeoid.time_defeated)
            response = "Your Slimeoid is still recovering from its last defeat! It'll be ready in {} seconds.".format(
                int(time_until))

        elif ewutils.active_slimeoidbattles.get(ally_slimeoid.id_slimeoid):
            response = "You are already in the middle of a challenge."

        elif challengee:
            if isinstance(challengee, EwEnemy):
                challengee_data = challengee
                is_pvp = False
            else:
                challengee_data = challengee
                challengee_player = EwPlayer(id_user=challengee.id_user)

            if challengee_slimeoid:
                target_slimeoid = challengee_slimeoid
            else:
                target_slimeoid = EwSlimeoid(member=challengee)

            if target_slimeoid.life_state != ewcfg.slimeoid_state_active:
                response = "{} does not have a Slimeoid ready to battle with!".format(
                    challengee_player.
                    display_name if is_pvp else challengee_data.display_name)

            elif challenger_data.poi != challengee_data.poi:
                response = "Both slimeoid trainers must be in the same place."

            elif challenger_data.slimes < bet or challenger_data.slimes < 0:
                response = "You don't have enough slime!"
            elif challengee_data.slimes < bet or challengee_data.slimes < 0:
                response = "They don't have enough slime!"

            elif challengee_data.life_state == ewcfg.life_state_corpse:
                response = "{}'s Slimeoid won't battle for them while they're dead.".format(
                    challengee_player.display_name).replace("@", "\{at\}")

            elif (time_now -
                  target_slimeoid.time_defeated) < ewcfg.cd_slimeoiddefeated:
                time_until = ewcfg.cd_slimeoiddefeated - (
                    time_now - target_slimeoid.time_defeated)
                response = "{}'s Slimeoid is still recovering from its last defeat! It'll be ready in {} seconds.".format(
                    challengee_player.display_name, int(time_until))

            elif ewutils.active_slimeoidbattles.get(
                    target_slimeoid.id_slimeoid):
                response = "They are already in the middle of a challenge."

        return response
Exemple #11
0
    def move(self):
        resp_cont = EwResponseContainer(id_server=self.id_server)
        abs_x = abs(self.velocity[0])
        abs_y = abs(self.velocity[1])
        abs_sum = abs_x + abs_y
        if abs_sum == 0:
            return resp_cont

        if random.random() * abs_sum < abs_x:
            move = [self.velocity[0] / abs_x, 0]
        else:
            move = [0, self.velocity[1] / abs_y]

        move_vector = ewutils.EwVector2D(move)
        position_vector = ewutils.EwVector2D(self.coords)

        destination_vector = position_vector.add(move_vector)

        # global sb_games
        game_data = sports_utils.sb_games.get(self.id_game)

        player_data = EwPlayer(id_user=self.id_user)
        response = ""
        ball_contact = False
        for i in range(-1, 2):
            for j in range(-1, 2):
                neighbor_direction = [i, j]
                neighbor_vector = ewutils.EwVector2D(neighbor_direction)
                if move_vector.scalar_product(neighbor_vector) > 0:
                    neighbor_position = position_vector.add(neighbor_vector)
                    if neighbor_position.vector == game_data.ball_coords:
                        ball_contact = True
                        break

        if ball_contact:
            game_data.ball_velocity = [
                round(5 * self.velocity[0]),
                round(5 * self.velocity[1])
            ]
            game_data.last_contact = self.id_player
            self.velocity = [0, 0]
            response = "{} has kicked the ball in direction {}!".format(
                player_data.display_name, game_data.ball_velocity)

        elif game_data.coords_free(destination_vector.vector):
            self.coords = destination_vector.vector

        elif game_data.out_of_bounds(destination_vector.vector):
            self.velocity = [0, 0]
            response = "{} has walked against the outer bounds and stopped at {}.".format(
                player_data.display_name, self.coords)
        else:
            vel = self.velocity

            for p in game_data.players:
                if p.coords == destination_vector.vector:
                    self.velocity = p.velocity
                    p.velocity = vel
                    other_player_data = EwPlayer(id_user=p.id_user)
                    response = "{} has collided with {}.".format(
                        player_data.display_name,
                        other_player_data.display_name)
                    break

        if len(response) > 0:
            poi_data = poi_static.id_to_poi.get(game_data.poi)
            resp_cont.add_channel_response(poi_data.channel, response)

        return resp_cont
Exemple #12
0
    def move_ball(self):
        resp_cont = EwResponseContainer(id_server=self.id_server)
        abs_x = abs(self.ball_velocity[0])
        abs_y = abs(self.ball_velocity[1])
        abs_sum = abs_x + abs_y
        if abs_sum == 0:
            return resp_cont

        move = [self.ball_velocity[0], self.ball_velocity[1]]
        whole_move_vector = ewutils.EwVector2D(move)

        response = ""
        while abs_sum != 0:
            if random.random() * abs_sum < abs_x:
                part_move = [move[0] / abs_x, 0]
            else:
                part_move = [0, move[1] / abs_y]

            move_vector = ewutils.EwVector2D(part_move)
            position_vector = ewutils.EwVector2D(self.ball_coords)

            destination_vector = position_vector.add(move_vector)

            player_contact = False
            for i in range(-1, 2):
                for j in range(-1, 2):
                    neighbor_direction = [i, j]
                    neighbor_vector = ewutils.EwVector2D(neighbor_direction)
                    if move_vector.scalar_product(neighbor_vector) > 0:
                        neighbor_position = position_vector.add(
                            neighbor_vector)
                        player = self.player_at_coords(
                            neighbor_position.vector)
                        if player != -1:
                            self.ball_velocity = [0, 0]
                            self.last_contact = player
                            player_contact = True
                            break

            if player_contact:
                break

            elif self.coords_free(destination_vector.vector):
                self.ball_coords = destination_vector.vector
            elif self.out_of_bounds(destination_vector.vector):
                for i in range(2):
                    if part_move[i] != 0:
                        whole_move_vector.vector[i] *= -1
                        self.ball_velocity[i] *= -1

            if self.is_goal():

                global sb_slimeballerid_to_player

                scoring_player = sb_slimeballerid_to_player.get(
                    self.last_contact)
                if scoring_player != None:
                    player_data = EwPlayer(id_user=scoring_player.id_user)
                else:
                    player_data = None

                if self.is_goal_purple():

                    if player_data != None:
                        response = "{} scored a goal for the pink team!".format(
                            player_data.display_name)
                    else:
                        response = "The pink team scored a goal!"
                    self.score_pink += 1
                elif self.is_goal_pink():

                    if player_data != None:
                        response = "{} scored a goal for the purple team!".format(
                            player_data.display_name)
                    else:
                        response = "The purple team scored a goal!"
                    self.score_purple += 1

                self.ball_velocity = [0, 0]
                self.ball_coords = get_starting_position("")
                self.last_contact = -1
                break

            else:
                whole_move_vector = whole_move_vector.subtract(move_vector)
                abs_x = abs(whole_move_vector.vector[0])
                abs_y = abs(whole_move_vector.vector[1])
                abs_sum = abs_x + abs_y
                move = whole_move_vector.vector

        for i in range(2):
            if self.ball_velocity[i] > 0:
                self.ball_velocity[i] -= 1
            elif self.ball_velocity[i] < 0:
                self.ball_velocity[i] += 1

        if len(response) > 0:
            poi_data = poi_static.id_to_poi.get(self.poi)
            resp_cont.add_channel_response(poi_data.channel, response)

        return resp_cont
Exemple #13
0
def format_ad_response(ad_data):
    sponsor_player = EwPlayer(id_user=ad_data.id_sponsor)
    sponsor_disclaimer = "Paid for by {}".format(sponsor_player.display_name)
    ad_response = "A billboard catches your eye:\n\n{}\n\n*{}*".format(ad_data.content, sponsor_disclaimer)

    return ad_response
Exemple #14
0
async def battle_slimeoids(id_s1, id_s2, channel, battle_type):
    # fetch slimeoid data
    challengee_slimeoid = EwSlimeoid(id_slimeoid=id_s1)
    challenger_slimeoid = EwSlimeoid(id_slimeoid=id_s2)

    # fetch player data
    challengee = EwPlayer(id_user=int(challengee_slimeoid.id_user))
    challenger = EwPlayer(id_user=int(challenger_slimeoid.id_user))

    client = ewutils.get_client()

    # calculate starting hp
    s1hpmax = 50 + (challengee_slimeoid.level * 20)
    s2hpmax = 50 + (challenger_slimeoid.level * 20)

    # calculate starting sap
    s1sapmax = challengee_slimeoid.level * 2
    s2sapmax = challenger_slimeoid.level * 2

    # initialize combat data for challengee
    s1_combat_data = EwSlimeoidCombatData(
        name=str(challengee_slimeoid.name),
        weapon=sl_static.offense_map.get(challengee_slimeoid.weapon),
        armor=sl_static.defense_map.get(challengee_slimeoid.armor),
        special=sl_static.special_map.get(challengee_slimeoid.special),
        legs=sl_static.mobility_map.get(challengee_slimeoid.legs),
        brain=sl_static.brain_map.get(challengee_slimeoid.ai),
        hue=hue_static.hue_map.get(challengee_slimeoid.hue),
        coating=challengee_slimeoid.coating,
        moxie=challengee_slimeoid.atk + 1,
        grit=challengee_slimeoid.defense + 1,
        chutzpah=challengee_slimeoid.intel + 1,
        hpmax=s1hpmax,
        hp=s1hpmax,
        sapmax=s1sapmax,
        sap=s1sapmax,
        slimeoid=challengee_slimeoid,
        owner=challengee,
    )

    # initialize combat data for challenger
    s2_combat_data = EwSlimeoidCombatData(
        name=str(challenger_slimeoid.name),
        weapon=sl_static.offense_map.get(challenger_slimeoid.weapon),
        armor=sl_static.defense_map.get(challenger_slimeoid.armor),
        special=sl_static.special_map.get(challenger_slimeoid.special),
        legs=sl_static.mobility_map.get(challenger_slimeoid.legs),
        brain=sl_static.brain_map.get(challenger_slimeoid.ai),
        hue=hue_static.hue_map.get(challenger_slimeoid.hue),
        coating=challenger_slimeoid.coating,
        moxie=challenger_slimeoid.atk + 1,
        grit=challenger_slimeoid.defense + 1,
        chutzpah=challenger_slimeoid.intel + 1,
        hpmax=s2hpmax,
        hp=s2hpmax,
        sapmax=s2sapmax,
        sap=s2sapmax,
        slimeoid=challenger_slimeoid,
        owner=challenger,
    )

    s1_combat_data.apply_weapon_matchup(s2_combat_data)
    s2_combat_data.apply_weapon_matchup(s1_combat_data)

    s1_combat_data.apply_hue_matchup(s2_combat_data)
    s2_combat_data.apply_hue_matchup(s1_combat_data)

    # decide which slimeoid gets to move first
    s1_active = False
    in_range = False

    if challengee_slimeoid.defense > challenger_slimeoid.defense:
        s1_active = True
    elif challengee_slimeoid.defense == challenger_slimeoid.defense:
        coinflip = random.randrange(1, 3)
        if coinflip == 1:
            s1_active = True

    # flavor text for arena battles
    if battle_type == ewcfg.battle_type_arena:
        response = "**{} sends {} out into the Battle Arena!**".format(
            challenger.display_name, s2_combat_data.name)
        await fe_utils.send_message(client, channel, response)
        await asyncio.sleep(1)
        response = "**{} sends {} out into the Battle Arena!**".format(
            challengee.display_name, s1_combat_data.name)
        await fe_utils.send_message(client, channel, response)
        await asyncio.sleep(1)
        response = "\nThe crowd erupts into cheers! The battle between {} and {} has begun! :crossed_swords:".format(
            s1_combat_data.name, s2_combat_data.name)
        #		response += "\n{} {} {} {} {} {}".format(str(s1moxie),str(s1grit),str(s1chutzpah),str(challengee_slimeoid.weapon),str(challengee_slimeoid.armor),str(challengee_slimeoid.special))
        #		response += "\n{} {} {} {} {} {}".format(str(s2moxie),str(s2grit),str(s2chutzpah),str(challenger_slimeoid.weapon),str(challenger_slimeoid.armor),str(challenger_slimeoid.special))
        #		response += "\n{}, {}".format(str(challengee_resistance),str(challengee_weakness))
        #		response += "\n{}, {}".format(str(challenger_resistance),str(challenger_weakness))
        await fe_utils.send_message(client, channel, response)
        await asyncio.sleep(3)

    turncounter = 100
    # combat loop
    while s1_combat_data.hp > 0 and s2_combat_data.hp > 0 and turncounter > 0:
        # Limit the number of turns in battle.
        turncounter -= 1

        response = ""
        battlecry = random.randrange(1, 4)

        first_turn = (turncounter % 2) == 1

        # slimeoids regenerate their sap every odd turn
        if first_turn:
            s1_combat_data.sap = s1_combat_data.sapmax - s1_combat_data.hardened_sap
            s2_combat_data.sap = s2_combat_data.sapmax - s2_combat_data.hardened_sap

        # assign active and passive role for the turn
        if s1_active:
            active_data = s1_combat_data
            passive_data = s2_combat_data
        else:
            active_data = s2_combat_data
            passive_data = s1_combat_data

        # obtain action and how much sap to spend on it for both slimeoids
        active_strat, active_sap_spend = active_data.brain.get_strat(
            combat_data=active_data,
            active=True,
            in_range=in_range,
            first_turn=first_turn)
        passive_strat, passive_sap_spend = passive_data.brain.get_strat(
            combat_data=passive_data,
            active=False,
            in_range=in_range,
            first_turn=first_turn)

        # potentially add brain-based flavor text
        if active_strat == ewcfg.slimeoid_strat_attack and battlecry == 1:
            if (active_data.hpmax / active_data.hp) > 3:
                response = active_data.brain.str_battlecry_weak.format(
                    slimeoid_name=active_data.name)
            else:
                response = active_data.brain.str_battlecry.format(
                    slimeoid_name=active_data.name)
            await fe_utils.send_message(client, channel, response)
            await asyncio.sleep(1)

        elif active_strat == ewcfg.slimeoid_strat_evade and battlecry == 1:
            if (active_data.hpmax / active_data.hp) > 3:
                response = active_data.brain.str_movecry_weak.format(
                    slimeoid_name=active_data.name)
            else:
                response = active_data.brain.str_movecry.format(
                    slimeoid_name=active_data.name)
            await fe_utils.send_message(client, channel, response)
            await asyncio.sleep(1)

        # announce active slimeoid's chosen action
        response = ""
        if active_strat == ewcfg.slimeoid_strat_attack:
            if in_range:
                response = "{} attempts to strike {} in close combat!".format(
                    active_data.name, passive_data.name)
            else:
                response = "{} attempts to strike {} from a distance!".format(
                    active_data.name, passive_data.name)

        elif active_strat == ewcfg.slimeoid_strat_evade:
            if in_range:
                response = "{} attempts to avoid being hit, while gaining distance from {}.".format(
                    active_data.name, passive_data.name)
            else:
                response = "{} attempts to avoid being hit, while closing the distance to {}.".format(
                    active_data.name, passive_data.name)

        elif active_strat == ewcfg.slimeoid_strat_block:
            response = "{} focuses on blocking incoming attacks.".format(
                active_data.name)

        response += " (**{} sap**)".format(active_sap_spend)

        await fe_utils.send_message(client, channel, response)
        await asyncio.sleep(1)

        # announce passive slimeoid's chosen action
        response = ""
        if passive_strat == ewcfg.slimeoid_strat_attack:
            if in_range:
                response = "{} attempts to strike {} in close combat!".format(
                    passive_data.name, active_data.name)
            else:
                response = "{} attempts to strike {} from a distance!".format(
                    passive_data.name, active_data.name)

        elif passive_strat == ewcfg.slimeoid_strat_evade:
            if in_range:
                response = "{} attempts to avoid being hit, while gaining distance from {}.".format(
                    passive_data.name, active_data.name)
            else:
                response = "{} attempts to avoid being hit, while closing the distance to {}.".format(
                    passive_data.name, active_data.name)

        elif passive_strat == ewcfg.slimeoid_strat_block:
            response = "{} focuses on blocking incoming attacks.".format(
                passive_data.name)

        response += " (**{} sap**)".format(passive_sap_spend)

        await fe_utils.send_message(client, channel, response)
        await asyncio.sleep(1)

        # if the chosen actions are in direct competition, the roll is opposed. only one of them can succeed
        # otherwise both actions are resolved separately
        roll_opposed = False

        if active_strat == ewcfg.slimeoid_strat_attack:
            roll_opposed = passive_strat in [
                ewcfg.slimeoid_strat_evade, ewcfg.slimeoid_strat_block
            ]
        elif active_strat == ewcfg.slimeoid_strat_evade:
            roll_opposed = passive_strat in [
                ewcfg.slimeoid_strat_attack, ewcfg.slimeoid_strat_evade
            ]
        elif active_strat == ewcfg.slimeoid_strat_block:
            roll_opposed = passive_strat in [ewcfg.slimeoid_strat_attack]

        active_dos = active_data.attempt_action(strat=active_strat,
                                                sap_spend=active_sap_spend,
                                                in_range=in_range)

        # simultaneous attacks are a special case. the passive slimeoid only rolls the dice, after the active slimeoid's attack has been resolved
        if passive_strat != ewcfg.slimeoid_strat_attack:
            passive_dos = passive_data.attempt_action(
                strat=passive_strat,
                sap_spend=passive_sap_spend,
                in_range=in_range)
            if roll_opposed:
                active_dos -= passive_dos
                passive_dos = -active_dos

                # on an opposed roll, priority for the next turn (the active role) is passed to the winner of the roll
                if active_dos < 0:
                    s1_active = not s1_active
        else:
            passive_dos = 0

        # resolve active slimeoid's attack
        if active_strat == ewcfg.slimeoid_strat_attack:
            # the attack was successful
            if active_dos > 0:
                # calculate damage
                if in_range:
                    damage = int(active_dos * 30 /
                                 (passive_data.hardened_sap + 1))
                else:
                    damage = int(active_dos * 20)

                response = active_data.execute_attack(passive_data, damage,
                                                      in_range)
                await fe_utils.send_message(client, channel, response)
                await asyncio.sleep(1)

                response = passive_data.take_damage(active_data, damage,
                                                    active_dos, in_range)
                if len(response) > 0:
                    await fe_utils.send_message(client, channel, response)
                    await asyncio.sleep(1)

            elif not roll_opposed:
                response = "{} whiffs its attack!".format(active_data.name)
                await fe_utils.send_message(client, channel, response)
                await asyncio.sleep(1)
            elif passive_strat == ewcfg.slimeoid_strat_evade:
                response = "{} dodges {}'s attack!".format(
                    passive_data.name, active_data.name)
                await fe_utils.send_message(client, channel, response)
                await asyncio.sleep(1)
            elif passive_strat == ewcfg.slimeoid_strat_block:
                response = "{} blocks {}'s attack!".format(
                    passive_data.name, active_data.name)
                await fe_utils.send_message(client, channel, response)
                await asyncio.sleep(1)

        # if the active slimeoid's attack killed the passive slimeoid
        if passive_data.hp <= 0:
            break

        if passive_strat == ewcfg.slimeoid_strat_attack:
            passive_dos = passive_data.attempt_action(
                strat=passive_strat,
                sap_spend=passive_sap_spend,
                in_range=in_range)

            if roll_opposed:
                active_dos -= passive_dos
                passive_dos = -active_dos

                if active_dos < 0:
                    s1_active = not s1_active

        # resolve passive slimeoid's attack
        if passive_strat == ewcfg.slimeoid_strat_attack:
            # attack was successful
            if passive_dos > 0:
                # calculate damage
                if in_range:
                    damage = int(passive_dos * 30 /
                                 (active_data.hardened_sap + 1))
                else:
                    damage = int(passive_dos * 20)

                response = passive_data.execute_attack(active_data, damage,
                                                       in_range)
                await fe_utils.send_message(client, channel, response)
                await asyncio.sleep(1)

                response = active_data.take_damage(passive_data, damage,
                                                   passive_dos, in_range)
                if len(response) > 0:
                    await fe_utils.send_message(client, channel, response)
                    await asyncio.sleep(1)

            elif not roll_opposed:
                response = "{} whiffs its attack!".format(passive_data.name)
                await fe_utils.send_message(client, channel, response)
                await asyncio.sleep(1)
            elif active_strat == ewcfg.slimeoid_strat_evade:
                response = "{} dodges {}'s attack!".format(
                    active_data.name, passive_data.name)
                await fe_utils.send_message(client, channel, response)
                await asyncio.sleep(1)
            elif active_strat == ewcfg.slimeoid_strat_block:
                response = "{} blocks {}'s attack!".format(
                    active_data.name, passive_data.name)
                await fe_utils.send_message(client, channel, response)
                await asyncio.sleep(1)

        # resolve active slimeoid's movement
        if active_strat == ewcfg.slimeoid_strat_evade:
            if active_dos > 0:
                response = active_data.change_distance(passive_data, in_range)
                in_range = not in_range
                await fe_utils.send_message(client, channel, response)
                await asyncio.sleep(1)
            elif active_dos == 0 and passive_strat == ewcfg.slimeoid_strat_evade:
                in_range = not in_range
                response = "{} and {} circle each other, looking for an opening...".format(
                    active_data.name, passive_data.name)
                await fe_utils.send_message(client, channel, response)
                await asyncio.sleep(1)

        # resolve active slimeoid's defense
        if active_strat == ewcfg.slimeoid_strat_block:
            if active_dos > 0:
                response = active_data.harden_sap(active_dos)
                await fe_utils.send_message(client, channel, response)
                await asyncio.sleep(1)

        # resolve passive slimeoid's movement
        if passive_strat == ewcfg.slimeoid_strat_evade:
            if passive_dos > 0:
                response = passive_data.change_distance(active_data, in_range)
                in_range = not in_range
                await fe_utils.send_message(client, channel, response)
                await asyncio.sleep(1)

        # resolve passive slimeoid's defense
        if passive_strat == ewcfg.slimeoid_strat_block:
            if passive_dos > 0:
                response = passive_data.harden_sap(passive_dos)
                await fe_utils.send_message(client, channel, response)
                await asyncio.sleep(1)

        # re-fetch slimeoid data
        challenger_slimeoid = EwSlimeoid(id_slimeoid=id_s2)
        challengee_slimeoid = EwSlimeoid(id_slimeoid=id_s1)

        s1_combat_data.slimeoid = challengee_slimeoid
        s2_combat_data.slimeoid = challenger_slimeoid

        # Check if slimeoids have died during the fight
        if challenger_slimeoid.life_state == ewcfg.slimeoid_state_dead:
            s2_combat_data.hp = 0
        elif challengee_slimeoid.life_state == ewcfg.slimeoid_state_dead:
            s1_combat_data.hp = 0

        await asyncio.sleep(2)

    # the challengee has lost
    if s1_combat_data.hp <= 0:
        result = -1
        response = "\n" + s1_combat_data.legs.str_defeat.format(
            slimeoid_name=s1_combat_data.name)
        response += " {}".format(ewcfg.emote_slimeskull)
        response += "\n" + s2_combat_data.brain.str_victory.format(
            slimeoid_name=s2_combat_data.name)

        challenger_slimeoid = EwSlimeoid(id_slimeoid=id_s2)
        challengee_slimeoid = EwSlimeoid(id_slimeoid=id_s1)

        # Losing slimeoid loses clout and has a time_defeated cooldown.
        if channel.name == ewcfg.channel_arena:
            challengee_slimeoid.clout = calculate_clout_loss(
                challengee_slimeoid.clout)
            challengee_slimeoid.time_defeated = int(time.time())
            challengee_slimeoid.persist()

        if channel.name == ewcfg.channel_arena:
            challenger_slimeoid.clout = calculate_clout_gain(
                challenger_slimeoid.clout)
            challenger_slimeoid.persist()

        await fe_utils.send_message(client, channel, response)
        await asyncio.sleep(2)
    # the challenger has lost
    else:
        result = 1
        response = "\n" + s2_combat_data.legs.str_defeat.format(
            slimeoid_name=s2_combat_data.name)
        response += " {}".format(ewcfg.emote_slimeskull)
        response += "\n" + s1_combat_data.brain.str_victory.format(
            slimeoid_name=s1_combat_data.name)

        challenger_slimeoid = EwSlimeoid(id_slimeoid=id_s2)
        challengee_slimeoid = EwSlimeoid(id_slimeoid=id_s1)

        # store defeated slimeoid's defeat time in the database
        if channel.name == ewcfg.channel_arena:
            challenger_slimeoid.clout = calculate_clout_loss(
                challenger_slimeoid.clout)
            challenger_slimeoid.time_defeated = int(time.time())
            challenger_slimeoid.persist()

        if channel.name == ewcfg.channel_arena:
            challengee_slimeoid.clout = calculate_clout_gain(
                challengee_slimeoid.clout)
            challengee_slimeoid.persist()

        await fe_utils.send_message(client, channel, response)
        await asyncio.sleep(2)
    return result
Exemple #15
0
def can_slimeoid_battle(challenger: EwUser = None,
                        challengee=None,
                        challenger_slimeoid: EwSlimeoid = None,
                        challengee_slimeoid: EwSlimeoid = None,
                        bet: int = 0):
    response = ""
    time_now = int(time.time())
    # Gotta have a challenger, otherwise do nothing
    if challenger:
        challenger_data = challenger
        challenger_player = EwPlayer(id_user=challenger_data.id_user)
        ally_slimeoid = None
        target_slimeoid = None

        # If supplied a slimeoid, use that - otherwise we just grab it
        if challenger_slimeoid:
            ally_slimeoid = challenger_slimeoid
        else:
            ally_slimeoid = EwSlimeoid(member=challenger)

        # Challenger

        # Check for slimeoid's type - for flavor text
        if ally_slimeoid.sltype == ewcfg.sltype_nega:
            slimeoidtype = "Negaslimeoid"
        else:
            slimeoidtype = "Slimeoid"

        if ally_slimeoid.life_state != ewcfg.slimeoid_state_active:
            response = "You do not have a Slimeoid ready to battle with!"

        # Checks if the player is dead and if they're trying to battle with a slimeoid
        elif challenger_data.life_state == ewcfg.life_state_corpse and ally_slimeoid.sltype != ewcfg.sltype_nega:
            response = "Your Slimeoid won't battle for you while you're dead."

        elif (time_now -
              ally_slimeoid.time_defeated) < ewcfg.cd_slimeoiddefeated:
            time_until = ewcfg.cd_slimeoiddefeated - (
                time_now - ally_slimeoid.time_defeated)
            response = "Your {} is still recovering from its last defeat! It'll be ready in {} seconds.".format(
                slimeoidtype, int(time_until))

        elif ewutils.active_slimeoidbattles.get(ally_slimeoid.id_slimeoid):
            response = "You are already in the middle of a challenge."

        elif challengee:
            # If the opponent isn't a player, set pvp to false. Set data.
            if isinstance(challengee, EwEnemy):
                challengee_data = challengee
                is_pvp = False
            else:
                challengee_data = challengee
                challengee_player = EwPlayer(id_user=challengee.id_user)
                is_pvp = True

            if challengee_slimeoid:
                target_slimeoid = challengee_slimeoid
            else:
                target_slimeoid = EwSlimeoid(member=challengee)

            # Check for slimeoid's type - for flavor text.
            if target_slimeoid.sltype == ewcfg.sltype_nega:
                slimeoidtype = "Negaslimeoid"
            else:
                slimeoidtype = "Slimeoid"

            # If slimeoid isn't alive, then they can't battle.
            if target_slimeoid.life_state != ewcfg.slimeoid_state_active:
                response = "{} does not have a Slimeoid ready to battle with!".format(
                    challengee_player.
                    display_name if is_pvp else challengee_data.display_name)

            elif challenger_data.poi != challengee_data.poi:
                response = "Both players must be in the same place."

            # Checks if each player has enough slime if there is a bet
            elif (challenger_data.slimes < bet
                  or challenger_data.slimes < 0) and bet != 0:
                response = "You don't have enough slime!"
            elif (challengee_data.slimes < bet
                  or challengee_data.slimes < 0) and bet != 0:
                response = "They don't have enough slime!"

            # If a player is a ghost and has a living slimeoid, then they can't battle.
            elif challengee_data.life_state == ewcfg.life_state_corpse and challengee_slimeoid.sltype != ewcfg.sltype_nega:
                response = "{}'s Slimeoid won't battle for them while they're dead.".format(
                    challengee_player.display_name).replace("@", "\{at\}")

            elif (time_now -
                  target_slimeoid.time_defeated) < ewcfg.cd_slimeoiddefeated:
                time_until = ewcfg.cd_slimeoiddefeated - (
                    time_now - target_slimeoid.time_defeated)
                response = "{}'s {} is still recovering from its last defeat! It'll be ready in {} seconds.".format(
                    challengee_player.display_name, slimeoidtype,
                    int(time_until))

            elif ewutils.active_slimeoidbattles.get(
                    target_slimeoid.id_slimeoid):
                response = "They are already in the middle of a challenge."

        return response