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