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 bleedSlimes(id_server = None): if id_server != None: try: client = get_client() server = client.get_server(id_server) conn_info = databaseConnect() conn = conn_info.get('conn') cursor = conn.cursor(); cursor.execute("SELECT id_user FROM users WHERE id_server = %s AND {bleed_storage} > 1".format( bleed_storage = ewcfg.col_bleed_storage ), ( id_server, )) users = cursor.fetchall() total_bled = 0 deathreport = "" resp_cont = EwResponseContainer(id_server = id_server) for user in users: user_data = EwUser(id_user = user[0], id_server = id_server) slimes_to_bleed = user_data.bleed_storage * (1 - .5 ** (ewcfg.bleed_tick_length / ewcfg.bleed_half_life)) slimes_to_bleed = max(slimes_to_bleed, ewcfg.bleed_tick_length * 1000) slimes_to_bleed = min(slimes_to_bleed, user_data.bleed_storage) slimes_dropped = user_data.totaldamage + user_data.slimes district_data = EwDistrict(id_server = id_server, district = user_data.poi) #round up or down, randomly weighted remainder = slimes_to_bleed - int(slimes_to_bleed) if random.random() < remainder: slimes_to_bleed += 1 slimes_to_bleed = int(slimes_to_bleed) if slimes_to_bleed >= 1: user_data.bleed_storage -= slimes_to_bleed user_data.change_slimes(n = - slimes_to_bleed, source = ewcfg.source_bleeding) if user_data.slimes < 0: user_data.die(cause = ewcfg.cause_bleeding) #user_data.change_slimes(n = -slimes_dropped / 10, source = ewcfg.source_ghostification) player_data = EwPlayer(id_server = user_data.id_server, id_user = user_data.id_user) deathreport = "{skull} *{uname}*: You have succumbed to your wounds. {skull}".format(skull = ewcfg.emote_slimeskull, uname = player_data.display_name) resp_cont.add_channel_response(ewcfg.channel_sewers, deathreport) user_data.persist() district_data.change_slimes(n = slimes_to_bleed, source = ewcfg.source_bleeding) district_data.persist() total_bled += slimes_to_bleed await ewrolemgr.updateRoles(client = client, member = server.get_member(user_data.id_user)) await resp_cont.post() conn.commit() finally: # Clean up the database handles. cursor.close() databaseClose(conn_info)
async def event_tick(id_server): time_now = int(time.time()) resp_cont = ewutils.EwResponseContainer(id_server=id_server) if True: data = ewutils.execute_sql_query( "SELECT {id_event} FROM world_events WHERE {time_expir} <= %s AND {time_expir} > 0 AND id_server = %s" .format( id_event=ewcfg.col_id_event, time_expir=ewcfg.col_time_expir, ), ( time_now, id_server, )) for row in data: event_data = EwWorldEvent(id_event=row[0]) event_def = ewcfg.event_type_to_def.get(event_data.event_type) response = event_def.str_event_end if event_data.event_type == ewcfg.event_type_minecollapse: user_data = EwUser( id_user=event_data.event_props.get('id_user'), id_server=id_server) if user_data.poi == event_data.event_props.get('poi'): user_data.change_slimes(n=-(user_data.slimes * 0.5)) user_data.persist() player_data = EwPlayer(id_user=user_data.id_user) response = "*{}*: You have lost an arm and a leg in a mining accident. Tis but a scratch.".format( player_data.display_name) if len(response) > 0: poi = event_data.event_props.get('poi') channel = event_data.event_props.get('channel') if channel != None: resp_cont.add_channel_response(channel, response) elif poi != None: poi_def = ewcfg.id_to_poi.get(poi) if poi_def != None: resp_cont.add_channel_response(poi_def.channel, response) else: for ch in ewcfg.hideout_channels: resp_cont.add_channel_response(ch, response) delete_world_event(event_data.id_event) await resp_cont.post() else: ewutils.logMsg("Error in event tick for server {}".format(id_server))
async def zine_dm_commands(cmd): tokens_count = len(cmd.tokens) cmd_text = cmd.tokens[0].lower() if tokens_count >= 1 else "" player = EwPlayer(id_user=cmd.message.author.id) user_data = EwUser(id_user=cmd.message.author.id, id_server=player.id_server) server = ewcfg.server_list[user_data.id_server] member_object = server.get_member(player.id_user) cmd.message.author = member_object cmd.message.server = server dm = True if cmd_text in [ewcfg.cmd_beginmanuscript, ewcfg.cmd_beginmanuscript_alt_1, ewcfg.cmd_beginmanuscript_alt_2]: return await begin_manuscript(cmd, dm) elif cmd_text in [ewcfg.cmd_setpenname, ewcfg.cmd_setpenname_alt_1]: return await set_pen_name(cmd, dm) elif cmd_text in [ewcfg.cmd_settitle, ewcfg.cmd_settitle_alt_1]: return await set_title(cmd, dm) elif cmd_text in [ewcfg.cmd_setgenre]: return await set_genre(cmd, dm) elif cmd_text in [ewcfg.cmd_editpage]: return await edit_page(cmd, dm) elif cmd_text in [ewcfg.cmd_viewpage]: return await view_page(cmd, dm) elif cmd_text in [ewcfg.cmd_checkmanuscript]: return await check_manuscript(cmd, dm) elif cmd_text in [ewcfg.cmd_publishmanuscript]: return await publish_manuscript(cmd, dm) elif cmd_text in [ewcfg.cmd_readbook]: return await read_book(cmd, dm) elif cmd_text in [ewcfg.cmd_nextpage, ewcfg.cmd_nextpage_alt_1]: return await next_page(cmd, dm) elif cmd_text in [ewcfg.cmd_previouspage, ewcfg.cmd_previouspage_alt_1, ewcfg.cmd_previouspage_alt_2]: return await previous_page(cmd, dm) elif cmd_text in [ewcfg.cmd_rate, ewcfg.cmd_rate_alt_1, ewcfg.cmd_rate_alt_2]: return await rate_zine(cmd) elif cmd_text in [ewcfg.cmd_accept, ewcfg.cmd_refuse]: return elif cmd_text in (ewcfg.cmd_setpages, ewcfg.cmd_setpages_alt_1, ewcfg.cmd_setpages_alt_2): return await set_length(cmd, dm)
async def begin_cataclysm(user_data): player_data = EwPlayer(user_data.id_user) player_name = player_data.display_name client = ewutils.get_client() server = client.get_guild(user_data.id_server) auditorium_channel = ewutils.get_channel(server, 'auditorium') responses = [ "@everyone", "You point the sword towards the heavens, making your prescense known. ENDLESS WAR begins to shudder as he witnesses what's about to happen...", "Dark clouds begin to assemble in the skies above. Buildings around you begin to lose their color. The ground begins to shake, and a sense of dread envelops you as you grip the handle of the cold metal sword.", "All of the wicked things you've ever done have come back to haunt you. But you've made your bed, and now you have to lie in it.", "All of the sins and hatred you've brought forth will be spun into form. But you knew that, and you lept toward the darkness anyways.", "With blade in hand, you unleash an unparalleled wave of anguish and dread over the city of Neo Los Angeles City AKA Neo Milw-", "**The sword snaps in two.**", "Wow. Just wow. No seriously, what the f**k did you think was gonna happen? I swear, people get so hopped up when they hear about shit like the Negaslime, like the Endless Rock, that they delude themselves into thinking that everything in this game has to be some kind of history-altering cataclysm. Not this time, dumbass. You've endured countless acts of BDSM Sadomasochism, and for what? Well, I'll tell you plain and simple: It was all for f*****g **NOTHING**.", "Yeah yeah, you've been taken for a fool, everyone laugh at the dummy, and then we can all go home and pretend like this whole 'Swilldermuk' thing never happened, right? No, f**k you. You are gonna sit here and listen to me ramble off about how much of a f*****g retard you are. I swear to god, the nerve that some people have, to think that they can play this race to the bottom and intentionally let themselves get pranked, it's just absolutely *disgusting*. Tell me, {}, you've been pranked so much... Who exactly is it that you've pranked? Can you name even one person? I thought not.".format(player_name), "This whole event, it was all about NOT getting pranked, about one-upping your bros and seeing the stupid ass retarded look on their face when you blew a goddamn airhorn right in their eardrums. But you? You're just a pathetic whipping boy who turned this whole thing upside down. You probably think I'm being a bit mean here don't you? But let's be real, I'm just stating the God's honest truth when I say this: You enjoy pain. You enjoy being whipped and beaten. The way you get your rocks off is when someone deliberately humiliates you, all for their own personal gain. Consider all of this a wake up call.", "You thought that you could just get away with being a disgusting sexfiend in public. You thought that when all of this was over, you'd get a nice item for your uh, what were your efforts again? Oh that's right, standing around waiting for credence to build up and then opening your body to unspeakable acts of debauchery. No strategy. No brains. No soul. You're just as bad, if not worse than the people who cowardly stood inside their apartments, waiting for all this to blow over. And so here we are, at the end of the road, pontificating over how badly you f****d everything up. Where do we go from here?", "How are you gonna reconcile with the fact that all your scars were for naught? 'How am I supposed to COPE', you might be thinking? Well, for starters, stop being such a reprehensible freak. I'm dead serious. All those times you let people further and further drain your credence, it was just abysmal and agonizing to watch. You don't have to apologize to anyone, you don't have to be put in a cage or any of that shit, because God knows how much you'd f*****g *enjoy it*. Just remember this. On this day, April 7th, in the year of our lord, two thousand and twenty, you, {}, were f*****g cringey, embarassing, and above all retarded. Commit it to memory. Tell your grandkids about it one day, even. It'll be a story for the ages.".format(player_name), "Now, as for everyone else reading this: Do your part, do your DUTY, even, and !pointandlaugh at {}, while you still can. It's what they f*****g deserve.".format(player_name), ] for i in range(len(responses)): response = responses[i] if response == responses[1]: await ewutils.send_message(client, auditorium_channel, ewutils.formatMessage(player_data, response)) else: await ewutils.send_message(client, auditorium_channel, response) if i >= 7: await asyncio.sleep(20) else: await asyncio.sleep(10)
async def order(cmd): user_data = EwUser(member=cmd.message.author) 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 ewutils.send_message( cmd.client, cmd.message.channel, ewutils.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 = ewcfg.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 = ewcfg.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( ) and poi.id_poi != ewcfg.poi_id_nuclear_beach_edge: 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 ewutils.send_message( cmd.client, cmd.message.channel, ewutils.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(ewcfg.furniture_pony) item = ewcfg.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 = ewcfg.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 = ewcfg.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 = ewcfg.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 ewcfg.furniture_pony: item.vendors = [ewcfg.vendor_bazaar] if item == None: item = ewcfg.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_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 ewcfg.furniture_pony and "mylittleponyfigurine" in market_data.bazaar_wares.values( ): pass else: current_vendor = None if current_vendor == ewcfg.vendor_downpourlaboratory: currency_used = 'brainz' current_currency_amount = user_data.gvs_currency 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 ewutils.send_message( cmd.client, cmd.message.channel, ewutils.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 ewutils.send_message( cmd.client, cmd.message.channel, ewutils.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 = ewutils.get_subzone_controlling_faction( user_data.poi, user_data.id_server) if controlling_faction != "" and poi.id_poi != ewcfg.poi_id_nuclear_beach_edge: # 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: if item_type == ewcfg.it_food: food_ordered = True food_items = ewitem.inventory( id_user=cmd.message.author.id, id_server=cmd.guild.id, item_type_filter=ewcfg.it_food) 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 ewutils.send_message( cmd.client, cmd.message.channel, ewutils.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 ewutils.send_message( cmd.client, cmd.message.channel, ewutils.formatMessage( cmd.message.author, response)) if len(food_items) >= user_data.get_food_capacity( ) and target_data == None and togo: # user_data never got persisted so the player won't lose money unnecessarily response = "You can't carry any more food than that." return await ewutils.send_message( cmd.client, cmd.message.channel, ewutils.formatMessage(cmd.message.author, response)) elif item_type == ewcfg.it_weapon: weapons_held = ewitem.inventory( id_user=user_data.id_user, id_server=cmd.guild.id, item_type_filter=ewcfg.it_weapon) has_weapon = False # Thrown weapons are stackable if ewcfg.weapon_class_thrown in item.classes: # Check the player's inventory for the weapon and add amount to stack size. Create a new item the max stack size has been reached for wep in weapons_held: weapon = EwItem(id_item=wep.get("id_item")) if weapon.item_props.get( "weapon_type" ) == item.id_weapon and weapon.stack_size < weapon.stack_max: has_weapon = True weapon.stack_size += 1 weapon.persist() if value == 0: response = "You swipe a {} from the counter at {}.".format( item.str_weapon, current_vendor) else: response = "You slam {:,} slime down on the counter at {} for {}.".format( value, current_vendor, item.str_weapon) user_data.change_slimes( n=-value, source=ewcfg.source_spending) user_data.persist() return await ewutils.send_message( cmd.client, cmd.message.channel, ewutils.formatMessage( cmd.message.author, response)) if has_weapon == False: if len(weapons_held ) >= user_data.get_weapon_capacity(): response = "You can't carry any more weapons." return await ewutils.send_message( cmd.client, cmd.message.channel, ewutils.formatMessage( cmd.message.author, response)) elif user_data.life_state == ewcfg.life_state_corpse: response = "Ghosts can't hold weapons." return await ewutils.send_message( cmd.client, cmd.message.channel, ewutils.formatMessage( cmd.message.author, response)) item_props = ewitem.gen_item_props(item) customtext = cmd.message.content[(len(cmd.tokens[0]) + len(cmd.tokens[1]) + 2):] if item.item_type == ewcfg.it_furniture and "custom" in item_props.get( 'id_furniture'): if customtext == "": response = "You need to specify the customization text before buying a custom item. Come on, isn't that self-evident?" return await ewutils.send_message( cmd.client, cmd.message.channel, ewutils.formatMessage(cmd.message.author, response)) # 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) elif currency_used == 'brainz': user_data.gvs_currency -= value 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'): item_props['furniture_name'] = item_props[ 'furniture_name'].format(custom=customtext) item_props['furniture_desc'] = item_props[ 'furniture_desc'].format(custom=customtext) item_props['furniture_look_desc'] = item_props[ 'furniture_look_desc'].format( custom=customtext) item_props['furniture_place_desc'] = item_props[ 'furniture_place_desc'].format( custom=customtext) item.str_name = item.str_name.format( custom=customtext) id_item = ewitem.item_create( item_type=item_type, id_user=cmd.message.author.id, id_server=cmd.guild.id, stack_max=20 if item_type == ewcfg.it_weapon and ewcfg.weapon_class_thrown in item.classes else -1, stack_size=1 if item_type == ewcfg.it_weapon and ewcfg.weapon_class_thrown in item.classes else 0, item_props=item_props) if value == 0: response = "You swipe a {} from the counter at {}.".format( item.str_name, current_vendor) else: response = "You slam {:,} {} down on the counter at {} for {}.".format( value, currency_used, current_vendor, item.str_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( item.str_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, item.str_name, target_player_data.display_name) response += "\n\n*{}*: ".format( target_player_data.display_name ) + target_data.eat(item_data) target_data.persist() asyncio.ensure_future( ewutils.decrease_food_multiplier( user_data.id_user)) else: if value == 0: response = "You swipe a {} from the counter at {} and eat it right on the spot.".format( item.str_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, item.str_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() asyncio.ensure_future( ewutils.decrease_food_multiplier( user_data.id_user)) 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 ewutils.send_message( cmd.client, cmd.message.channel, ewutils.formatMessage(cmd.message.author, response))
async def event_tick(id_server): time_now = int(time.time()) resp_cont = ewutils.EwResponseContainer(id_server=id_server) try: data = ewutils.execute_sql_query( "SELECT {id_event} FROM world_events WHERE {time_expir} <= %s AND {time_expir} > 0 AND id_server = %s" .format( id_event=ewcfg.col_id_event, time_expir=ewcfg.col_time_expir, ), ( time_now, id_server, )) for row in data: try: event_data = EwWorldEvent(id_event=row[0]) event_def = ewcfg.event_type_to_def.get(event_data.event_type) response = event_def.str_event_end if event_def else "" if event_data.event_type == ewcfg.event_type_minecollapse: user_data = EwUser( id_user=event_data.event_props.get('id_user'), id_server=id_server) mutations = user_data.get_mutations() if user_data.poi == event_data.event_props.get('poi'): player_data = EwPlayer(id_user=user_data.id_user) response = "*{}*: You have lost an arm and a leg in a mining accident. Tis but a scratch.".format( player_data.display_name) if random.randrange(4) == 0: response = "*{}*: Big John arrives just in time to save you from your mining accident!\nhttps://cdn.discordapp.com/attachments/431275470902788107/743629505876197416/mine2.jpg".format( player_data.display_name) else: if ewcfg.mutation_id_lightminer in mutations: response = "*{}*: You instinctively jump out of the way of the collapsing shaft, not a scratch on you. Whew, really gets your blood pumping.".format( player_data.display_name) else: user_data.change_slimes( n=-(user_data.slimes * 0.5)) user_data.persist() # check if any void connections have expired, if so pop it and create a new one elif event_data.event_type == ewcfg.event_type_voidconnection: void_poi = ewcfg.id_to_poi.get(ewcfg.poi_id_thevoid) void_poi.neighbors.pop(event_data.event_props.get('poi'), "") create_void_connection(id_server) if len(response) > 0: poi = event_data.event_props.get('poi') channel = event_data.event_props.get('channel') if channel != None: # in shambaquarium the event happens in the user's DMs if event_data.event_type == ewcfg.event_type_shambaquarium: client = ewutils.get_client() channel = client.get_guild(id_server).get_member( int(channel)) resp_cont.add_channel_response(channel, response) elif poi != None: poi_def = ewcfg.id_to_poi.get(poi) if poi_def != None: resp_cont.add_channel_response( poi_def.channel, response) else: for ch in ewcfg.hideout_channels: resp_cont.add_channel_response(ch, response) delete_world_event(event_data.id_event) except: ewutils.logMsg( "Error in event tick for server {}".format(id_server)) await resp_cont.post() except: ewutils.logMsg("Error in event tick for server {}".format(id_server))
def 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) # 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) total_shares = [latest_stock.total_shares, stock_at_last_tick.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 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 < 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 = int(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 inventory(id_user="", id_server=None, conn=None, cursor=None): our_cursor = False our_conn = False items = [] try: # Get database handles if they weren't passed. if (cursor == None): if (conn == None): conn = ewutils.databaseConnect() our_conn = True cursor = conn.cursor() our_cursor = True player = EwPlayer(id_user=id_user, id_server=id_server, conn=conn, cursor=cursor) if player.id_server != None: cursor.execute( "SELECT {}, {}, {}, {}, {} FROM items WHERE {} = %s AND {} = %s" .format(ewcfg.col_id_item, ewcfg.col_item_type, ewcfg.col_soulbound, ewcfg.col_stack_max, ewcfg.col_stack_size, ewcfg.col_id_user, ewcfg.col_id_server), (player.id_user, player.id_server)) for row in cursor: id_item = row[0] item_type = row[1] soulbound = (row[2] == 1) stack_max = row[3] stack_size = row[4] item_def = ewcfg.item_def_map.get(item_type) if (item_def != None): items.append({ 'id_item': id_item, 'item_type': item_type, 'soulbound': soulbound, 'stack_max': stack_max, 'stack_size': stack_size, 'item_def': item_def }) for item in items: item_def = item.get('item_def') id_item = item.get('id_item') name = item_def.str_name quantity = 0 if item.get('stack_max') > 0: quantity = item.get('stack_size') item['quantity'] = quantity # Name requires variable substitution. Look up the item properties. if name.find('{') >= 0: item_inst = EwItem(id_item=id_item, conn=conn, cursor=cursor) if item_inst != None and item_inst.id_item >= 0: name = name.format_map(item_inst.item_props) if name.find('{') >= 0: name = name.format_map(item_inst.item_props) item['name'] = name finally: # Clean up the database handles. if (our_cursor): cursor.close() if (our_conn): conn.close() return items
return url.format("ghost") return "" if len(sys.argv) >= 3: id_server = sys.argv[1] id_user = sys.argv[2] else: print("<p><i>Nothing but dust...</i></p>") sys.exit(0) print("<article class=story>") user_data = EwUser(id_user=id_user, id_server=id_server) player = EwPlayer(id_user=id_user) # Floating profile section print( "<div class=profile_float><img src=\"{avatar_url}\" class=profile_avatar>". format(avatar_url=player.avatar)) print("<table>") print("<tr><td>Faction</td><td>{icon}{faction}</td></tr>".format( icon=faction(user_data.faction, user_data.life_state), faction=user_data.faction)) print( "<tr><td>Slime</td><td>{slime:,}</td></tr>".format(slime=user_data.slimes)) print("<tr><td>SlimeCoin</td><td>{slimecoin:,}</td></tr>".format( slimecoin=user_data.slimecoin)) print("<tr><td>Bounty</td><td>{bounty:,}</td></tr>".format(
def explode(damage = 0, district_data = None, market_data = None): id_server = district_data.id_server poi = district_data.name if market_data == None: market_data = EwMarket(id_server = district_data.id_server) client = get_client() server = client.get_server(id_server) resp_cont = EwResponseContainer(id_server = id_server) response = "" channel = ewcfg.id_to_poi.get(poi).channel life_states = [ewcfg.life_state_juvenile, ewcfg.life_state_enlisted, ewcfg.life_state_executive] users = district_data.get_players_in_district(life_states = life_states) enemies = district_data.get_enemies_in_district() # damage players for user in users: user_data = EwUser(id_user = user, id_server = id_server) mutations = user_data.get_mutations() user_weapon = None user_weapon_item = None if user_data.weapon >= 0: user_weapon_item = EwItem(id_item = user_data.weapon) user_weapon = ewcfg.weapon_map.get(user_weapon_item.item_props.get("weapon_type")) # apply defensive mods slimes_damage_target = damage * ewwep.damage_mod_defend( shootee_data = user_data, shootee_mutations = mutations, shootee_weapon = user_weapon, market_data = market_data ) # apply sap armor sap_armor = ewwep.get_sap_armor(shootee_data = user_data, sap_ignored = 0) slimes_damage_target *= sap_armor slimes_damage_target = int(max(0, slimes_damage_target)) player_data = EwPlayer(id_user = user_data.id_user) response = "{} is blown back by the explosion’s sheer force! They lose {:,} slime!!".format(player_data.display_name, slimes_damage_target) resp_cont.add_channel_response(channel, response) slimes_damage = slimes_damage_target if user_data.slimes < slimes_damage + user_data.bleed_storage: # die in the explosion district_data.change_slimes(n = user_data.slimes, source = ewcfg.source_killing) district_data.persist() slimes_dropped = user_data.totaldamage + user_data.slimes explode_damage = slime_bylevel(user_data.slimelevel) user_data.die(cause = ewcfg.cause_killing) #user_data.change_slimes(n = -slimes_dropped / 10, source = ewcfg.source_ghostification) user_data.persist() response = "Alas, {} was caught too close to the blast. They are consumed by the flames, and die in the explosion.".format(player_data.display_name) resp_cont.add_channel_response(channel, response) if ewcfg.mutation_id_spontaneouscombustion in mutations: sub_explosion = explode(explode_damage, district_data) resp_cont.add_response_container(sub_explosion) resp_cont.add_member_to_update(server.get_member(user_data.id_user)) else: # survive slime_splatter = 0.5 * slimes_damage district_data.change_slimes(n = slime_splatter, source = ewcfg.source_killing) district_data.persist() slimes_damage -= slime_splatter user_data.bleed_storage += slimes_damage user_data.change_slimes(n = -slime_splatter, source = ewcfg.source_killing) user_data.persist() # damage enemies for enemy in enemies: enemy_data = EwEnemy(id_enemy = enemy, id_server = id_server) response = "{} is blown back by the explosion’s sheer force! They lose {:,} slime!!".format(enemy_data.display_name, damage) resp_cont.add_channel_response(channel, response) slimes_damage_target = damage # apply sap armor sap_armor = ewwep.get_sap_armor(shootee_data = enemy_data, sap_ignored = 0) slimes_damage_target *= sap_armor slimes_damage_target = int(max(0, slimes_damage_target)) slimes_damage = slimes_damage_target if enemy_data.slimes < slimes_damage + enemy_data.bleed_storage: # die in the explosion district_data.change_slimes(n = enemy_data.slimes, source = ewcfg.source_killing) district_data.persist() # slimes_dropped = enemy_data.totaldamage + enemy_data.slimes # explode_damage = ewutils.slime_bylevel(enemy_data.level) response = "Alas, {} was caught too close to the blast. They are consumed by the flames, and die in the explosion.".format(enemy_data.display_name) resp_cont.add_response_container(ewhunting.drop_enemy_loot(enemy_data, district_data)) resp_cont.add_channel_response(channel, response) enemy_data.life_state = ewcfg.enemy_lifestate_dead enemy_data.persist() else: # survive slime_splatter = 0.5 * slimes_damage district_data.change_slimes(n = slime_splatter, source = ewcfg.source_killing) district_data.persist() slimes_damage -= slime_splatter enemy_data.bleed_storage += slimes_damage enemy_data.change_slimes(n = -slime_splatter, source = ewcfg.source_killing) enemy_data.persist() return resp_cont
def inventory(id_user="", id_server=None, item_type_filter=None): items = [] try: player = EwPlayer(id_user=id_user, id_server=id_server) conn_info = ewutils.databaseConnect() conn = conn_info.get('conn') cursor = conn.cursor() sql = "SELECT {}, {}, {}, {}, {} FROM items WHERE {} = %s AND {} = %s" if item_type_filter != None: sql += " AND {} = '{}'".format(ewcfg.col_item_type, item_type_filter) if player.id_server != None: cursor.execute( sql.format(ewcfg.col_id_item, ewcfg.col_item_type, ewcfg.col_soulbound, ewcfg.col_stack_max, ewcfg.col_stack_size, ewcfg.col_id_user, ewcfg.col_id_server), (player.id_user, player.id_server)) for row in cursor: id_item = row[0] item_type = row[1] soulbound = (row[2] == 1) stack_max = row[3] stack_size = row[4] item_def = ewcfg.item_def_map.get(item_type) if (item_def != None): items.append({ 'id_item': id_item, 'item_type': item_type, 'soulbound': soulbound, 'stack_max': stack_max, 'stack_size': stack_size, 'item_def': item_def }) for item in items: item_def = item.get('item_def') id_item = item.get('id_item') name = item_def.str_name quantity = 0 if item.get('stack_max') > 0: quantity = item.get('stack_size') item['quantity'] = quantity # Name requires variable substitution. Look up the item properties. if name.find('{') >= 0: item_inst = EwItem(id_item=id_item) if item_inst != None and item_inst.id_item >= 0: name = name.format_map(item_inst.item_props) if name.find('{') >= 0: name = name.format_map(item_inst.item_props) item['name'] = name finally: # Clean up the database handles. cursor.close() ewutils.databaseClose(conn_info) return items
async def burnSlimes(id_server = None): if id_server != None: time_now = int(time.time()) client = get_client() server = client.get_server(id_server) results = {} # Get users with burning effect data = execute_sql_query("SELECT {id_user}, {value}, {source} from status_effects WHERE {id_status} = %s and {id_server} = %s".format( id_user = ewcfg.col_id_user, value = ewcfg.col_value, id_status = ewcfg.col_id_status, id_server = ewcfg.col_id_server, source = ewcfg.col_source ), ( ewcfg.status_burning_id, id_server )) deathreport = "" resp_cont = EwResponseContainer(id_server = id_server) for result in data: user_data = EwUser(id_user = result[0], id_server = id_server) slimes_dropped = user_data.totaldamage + user_data.slimes # Deal 10% of total slime to burn every second slimes_to_burn = math.ceil(int(float(result[1])) * ewcfg.burn_tick_length / ewcfg.time_expire_burn) killer_data = EwUser(id_server = id_server, id_user=result[2]) # Damage stats ewstats.change_stat(user = killer_data, metric = ewcfg.stat_lifetime_damagedealt, n = slimes_to_burn) # Player died if user_data.slimes - slimes_to_burn < 0: weapon = ewcfg.weapon_map.get(ewcfg.weapon_id_molotov) player_data = EwPlayer(id_server = user_data.id_server, id_user = user_data.id_user) killer = EwPlayer(id_server = id_server, id_user=killer_data.id_user) # Kill stats ewstats.increment_stat(user = killer_data, metric = ewcfg.stat_kills) ewstats.track_maximum(user = killer_data, metric = ewcfg.stat_biggest_kill, value = int(slimes_dropped)) if killer_data.slimelevel > user_data.slimelevel: ewstats.increment_stat(user = killer_data, metric = ewcfg.stat_lifetime_ganks) elif killer_data.slimelevel < user_data.slimelevel: ewstats.increment_stat(user = killer_data, metric = ewcfg.stat_lifetime_takedowns) # Collect bounty coinbounty = int(user_data.bounty / ewcfg.slimecoin_exchangerate) # 100 slime per coin if user_data.slimes >= 0: killer_data.change_slimecoin(n = coinbounty, coinsource = ewcfg.coinsource_bounty) # Kill player user_data.id_killer = killer_data.id_user user_data.die(cause = ewcfg.cause_burning) #user_data.change_slimes(n = -slimes_dropped / 10, source = ewcfg.source_ghostification) deathreport = "You were {} by {}. {}".format(weapon.str_killdescriptor, killer.display_name, ewcfg.emote_slimeskull) deathreport = "{} ".format(ewcfg.emote_slimeskull) + formatMessage(server.get_member(user_data.id_user), deathreport) resp_cont.add_channel_response(ewcfg.channel_sewers, deathreport) user_data.trauma = weapon.id_weapon user_data.persist() await ewrolemgr.updateRoles(client = client, member = server.get_member(user_data.id_user)) else: user_data.change_slimes(n = -slimes_to_burn, source = ewcfg.source_damage) user_data.persist() await resp_cont.post()
async def explode(damage = 0, district_data = None): id_server = district_data.id_server poi = district_data.name client = get_client() server = client.get_server(id_server) resp_cont = EwResponseContainer(id_server = id_server) response = "" channel = ewcfg.id_to_poi.get(poi).channel life_states = [ewcfg.life_state_juvenile, ewcfg.life_state_enlisted, ewcfg.life_state_executive] users = district_data.get_players_in_district(life_states = life_states) enemies = district_data.get_enemies_in_district() # damage players for user in users: user_data = EwUser(id_user = user, id_server = id_server) mutations = user_data.get_mutations() if True: player_data = EwPlayer(id_user = user_data.id_user) response = "{} is blown back by the explosion’s sheer force! They lose {} slime!!".format(player_data.display_name, damage) resp_cont.add_channel_response(channel, response) slimes_damage = damage if user_data.slimes < slimes_damage + user_data.bleed_storage: # die in the explosion district_data.change_slimes(n = user_data.slimes, source = ewcfg.source_killing) district_data.persist() slimes_dropped = user_data.totaldamage + user_data.slimes explode_damage = slime_bylevel(user_data.slimelevel) user_data.die(cause = ewcfg.cause_killing) #user_data.change_slimes(n = -slimes_dropped / 10, source = ewcfg.source_ghostification) user_data.persist() response = "Alas, {} was caught too close to the blast. They are consumed by the flames, and die in the explosion.".format(player_data.display_name) resp_cont.add_channel_response(channel, response) if ewcfg.mutation_id_spontaneouscombustion in mutations: sub_explosion = await explode(explode_damage, district_data) resp_cont.add_response_container(sub_explosion) await ewrolemgr.updateRoles(client = client, member = server.get_member(user_data.id_user)) else: # survive slime_splatter = 0.5 * slimes_damage district_data.change_slimes(n = slime_splatter, source = ewcfg.source_killing) district_data.persist() slimes_damage -= slime_splatter user_data.bleed_storage += slimes_damage user_data.change_slimes(n = -slime_splatter, source = ewcfg.source_killing) user_data.persist() # damage enemies for enemy in enemies: enemy_data = EwEnemy(id_enemy = enemy, id_server = id_server) if True: response = "{} is blown back by the explosion’s sheer force! They lose {} slime!!".format(enemy_data.display_name, damage) resp_cont.add_channel_response(channel, response) slimes_damage = damage if enemy_data.slimes < slimes_damage + enemy_data.bleed_storage: # die in the explosion district_data.change_slimes(n = enemy_data.slimes, source = ewcfg.source_killing) district_data.persist() # slimes_dropped = enemy_data.totaldamage + enemy_data.slimes # explode_damage = ewutils.slime_bylevel(enemy_data.level) response = "Alas, {} was caught too close to the blast. They are consumed by the flames, and die in the explosion.".format(enemy_data.display_name) response += "\n\n" + ewhunting.drop_enemy_loot(enemy_data, district_data) resp_cont.add_channel_response(channel, response) enemy_data.life_state = ewcfg.enemy_lifestate_dead enemy_data.persist() else: # survive slime_splatter = 0.5 * slimes_damage district_data.change_slimes(n = slime_splatter, source = ewcfg.source_killing) district_data.persist() slimes_damage -= slime_splatter enemy_data.bleed_storage += slimes_damage enemy_data.change_slimes(n = -slime_splatter, source = ewcfg.source_killing) enemy_data.persist() return resp_cont
async def weather_tick(id_server=None): if id_server != None: try: market_data = EwMarket(id_server=id_server) if market_data.weather == ewcfg.weather_sunny: exposed_pois = [] exposed_pois.extend(ewcfg.capturable_districts) exposed_pois.extend(ewcfg.outskirts) exposed_pois = tuple(exposed_pois) users = ewutils.execute_sql_query( "SELECT id_user FROM users WHERE id_server = %s AND {poi} IN %s AND {life_state} > 0" .format(poi=ewcfg.col_poi, life_state=ewcfg.col_life_state), (id_server, exposed_pois)) for user in users: try: user_data = EwUser(id_user=user[0], id_server=id_server) if user_data.life_state == ewcfg.life_state_kingpin: continue else: mutations = user_data.get_mutations() if ewcfg.mutation_id_airlock in mutations: user_data.hunger -= min(user_data.hunger, 5) except: ewutils.logMsg( "Error occurred in weather tick for server {}". format(id_server)) if market_data.weather != ewcfg.weather_bicarbonaterain: return exposed_pois = [] exposed_pois.extend(ewcfg.capturable_districts) exposed_pois.extend(ewcfg.outskirts) exposed_pois = tuple(exposed_pois) client = ewutils.get_client() server = client.get_guild(id_server) users = ewutils.execute_sql_query( "SELECT id_user FROM users WHERE id_server = %s AND {poi} IN %s AND {life_state} > 0" .format(poi=ewcfg.col_poi, life_state=ewcfg.col_life_state), (id_server, exposed_pois)) deathreport = "" resp_cont = ewutils.EwResponseContainer(id_server=id_server) for user in users: user_data = EwUser(id_user=user[0], id_server=id_server) if user_data.life_state == ewcfg.life_state_kingpin: continue user_poi = ewcfg.id_to_poi.get(user_data.poi) player_data = EwPlayer(id_server=user_data.id_server, id_user=user_data.id_user) protected = False slimeoid_protected = False if user_data.weapon >= 0: weapon_item = EwItem(id_item=user_data.weapon) if weapon_item.item_props.get( 'weapon_type') in ewcfg.rain_protection: protected = True cosmetics = ewitem.inventory( id_user=user_data.id_user, id_server=id_server, item_type_filter=ewcfg.it_cosmetic) for cosmetic in cosmetics: cosmetic_data = EwItem(id_item=cosmetic.get('id_item')) if cosmetic_data.item_props.get( 'id_cosmetic') in ewcfg.rain_protection: if cosmetic_data.item_props.get('adorned') == 'true': protected = True elif cosmetic_data.item_props.get( 'slimeoid') == 'true': slimeoid_protected = True if not protected: if user_data.life_state == ewcfg.life_state_shambler: slime_gain = (ewcfg.slimes_shambler - user_data.slimes) / 10 slime_gain = max(0, int(slime_gain)) user_data.change_slimes(n=slime_gain, source=ewcfg.source_weather) else: if random.random() < 0.01: user_data.degradation += 1 user_data.persist() if not slimeoid_protected: slimeoid_data = EwSlimeoid(id_user=user_data.id_user, id_server=id_server) if slimeoid_data.life_state != ewcfg.slimeoid_state_active: continue slimeoid_response = "" if random.randrange(10) < slimeoid_data.level: slimeoid_response = "*{uname}*: {slname} cries out in pain, as it's hit by the bicarbonate rain.".format( uname=player_data.display_name, slname=slimeoid_data.name) else: item_props = { 'context': ewcfg.context_slimeoidheart, 'subcontext': slimeoid_data.id_slimeoid, 'item_name': "Heart of {}".format(slimeoid_data.name), 'item_desc': "A poudrin-like crystal. If you listen carefully you can hear something that sounds like a faint heartbeat." } ewitem.item_create(id_user=str(user_data.id_user), id_server=id_server, item_type=ewcfg.it_item, item_props=item_props) slimeoid_data.die() slimeoid_data.persist() slimeoid_response = "*{uname}*: {slname} lets out a final whimper as it's dissolved by the bicarbonate rain. {skull} You quickly pocket its heart.".format( uname=player_data.display_name, slname=slimeoid_data.name, skull=ewcfg.emote_slimeskull) resp_cont.add_channel_response(user_poi.channel, slimeoid_response) for poi in exposed_pois: district_data = EwDistrict(district=poi, id_server=id_server) slimes_to_erase = district_data.slimes * 0.01 * ewcfg.weather_tick_length slimes_to_erase = max(slimes_to_erase, ewcfg.weather_tick_length * 1000) slimes_to_erase = min(district_data.slimes, slimes_to_erase) #round up or down, randomly weighted remainder = slimes_to_erase - int(slimes_to_erase) if random.random() < remainder: slimes_to_erase += 1 slimes_to_erase = int(slimes_to_erase) district_data.change_slimes(n=-slimes_to_erase, source=ewcfg.source_weather) district_data.persist() enemies = ewutils.execute_sql_query( "SELECT id_enemy FROM enemies WHERE id_server = %s AND {poi} IN %s AND {life_state} = %s AND {weathertype} != %s" .format(poi=ewcfg.col_enemy_poi, life_state=ewcfg.col_enemy_life_state, weathertype=ewcfg.col_enemy_weathertype), (id_server, exposed_pois, ewcfg.enemy_lifestate_alive, ewcfg.enemy_weathertype_rainresist)) for enemy in enemies: enemy_data = EwEnemy(id_enemy=enemy[0]) enemy_poi = ewcfg.id_to_poi.get(enemy_data.poi) slimes_to_erase = enemy_data.slimes * 0.01 * ewcfg.weather_tick_length slimes_to_erase = max(slimes_to_erase, ewcfg.weather_tick_length * 1000) slimes_to_erase = min(enemy_data.slimes, slimes_to_erase) #round up or down, randomly weighted remainder = slimes_to_erase - int(slimes_to_erase) if random.random() < remainder: slimes_to_erase += 1 slimes_to_erase = int(slimes_to_erase) enemy_data.change_slimes(n=-slimes_to_erase, source=ewcfg.source_weather) enemy_data.persist() response = "{name} takes {slimeloss:,} damage from the bicarbonate rain.".format( name=enemy_data.display_name, slimeloss=slimes_to_erase) resp_cont.add_channel_response(enemy_poi.channel, response) if enemy_data.slimes <= 0: ewhunting.delete_enemy(enemy_data) deathreport = "{skull} {name} is dissolved by the bicarbonate rain. {skull}".format( skull=ewcfg.emote_slimeskull, name=enemy_data.display_name) resp_cont.add_channel_response(enemy_poi.channel, deathreport) await resp_cont.post() except: ewutils.logMsg( "Error occurred in weather tick for server {}".format( id_server))
async def on_message(message): time_now = int(time.time()) ewcfg.set_client(client) """ do not interact with our own messages """ if message.author.id == client.user.id or message.author.bot == True: return if message.server != None: # Note that the user posted a message. active_map = active_users_map.get(message.server.id) if active_map == None: active_map = {} active_users_map[message.server.id] = active_map active_map[message.author.id] = True # Update player information. ewplayer.player_update( member = message.author, server = message.server ) content_tolower = message.content.lower() re_awoo = re.compile('.*![a]+[w]+o[o]+.*') # update the player's time_last_action which is used for kicking AFK players out of subzones if message.server != None: try: ewutils.execute_sql_query("UPDATE users SET {time_last_action} = %s WHERE id_user = %s AND id_server = %s".format( time_last_action = ewcfg.col_time_last_action ), ( int(time.time()), message.author.id, message.server.id )) except: ewutils.logMsg('server {}: failed to update time_last_action for {}'.format(message.server.id, message.author.id)) user_data = EwUser(member = message.author) statuses = user_data.getStatusEffects() if ewcfg.status_strangled_id in statuses: strangle_effect = EwStatusEffect(id_status=ewcfg.status_strangled_id, user_data=user_data) source = EwPlayer(id_user=strangle_effect.source, id_server=message.server.id) response = "You manage to break {}'s garrote wire!".format(source.display_name) user_data.clear_status(ewcfg.status_strangled_id) return await ewutils.send_message(client, message.channel, ewutils.formatMessage(message.author, response)) if message.content.startswith(ewcfg.cmd_prefix) or message.server == None or len(message.author.roles) < 2: """ Wake up if we need to respond to messages. Could be: message starts with ! direct message (server == None) user is new/has no roles (len(roles) < 2) """ #Ignore users with weird characters in their name try: message.author.display_name[:3].encode('utf-8').decode('ascii') except UnicodeError: return await ewutils.send_message(client, message.channel, ewutils.formatMessage(message.author, "We don't take kindly to moon runes around here.")) # tokenize the message. the command should be the first word. try: tokens = shlex.split(message.content) # it's split with shlex now because shlex regards text within quotes as a single token except: tokens = message.content.split(' ') # if splitting via shlex doesnt work (odd number of quotes), use the old splitting method so it doesnt give an exception tokens_count = len(tokens) cmd = tokens[0].lower() if tokens_count >= 1 else "" # remove mentions to us mentions = list(filter(lambda user : user.id != client.user.id, message.mentions)) mentions_count = len(mentions) # Create command object cmd_obj = ewcmd.EwCmd( tokens = tokens, message = message, client = client, mentions = mentions ) """ Handle direct messages. """ if message.server == None: playermodel = ewplayer.EwPlayer(id_user = message.author.id) usermodel = EwUser(id_user=message.author.id, id_server= playermodel.id_server) poi = ewcfg.id_to_poi.get(usermodel.poi) # Direct message the player their inventory. if ewitem.cmd_is_inventory(cmd): return await ewitem.inventory_print(cmd_obj) elif cmd == ewcfg.cmd_inspect: return await ewitem.item_look(cmd_obj) elif poi.is_apartment: return await ewapt.aptCommands(cmd=cmd_obj) else: time_last = last_helped_times.get(message.author.id, 0) # Only send the help doc once every thirty seconds. There's no need to spam it. if (time_now - time_last) > 30: last_helped_times[message.author.id] = time_now await ewutils.send_message(client, message.channel, ewcfg.generic_help_response) # Nothing else to do in a DM. return # assign the appropriate roles to a user with less than @everyone, faction, location if len(message.author.roles) < 3: await ewrolemgr.updateRoles(client = client, member = message.author) user_data = EwUser(member = message.author) if user_data.arrested: return mutations = user_data.get_mutations() # Scold/ignore offline players. if message.author.status == discord.Status.offline: if ewcfg.mutation_id_chameleonskin not in mutations or cmd not in ewcfg.offline_cmds: response = "You cannot participate in the ENDLESS WAR while offline." return await ewutils.send_message(client, message.channel, ewutils.formatMessage(message.author, response)) if user_data.time_lastoffline > time_now - ewcfg.time_offline: if ewcfg.mutation_id_chameleonskin not in mutations or cmd not in ewcfg.offline_cmds: response = "You are too paralyzed by ENDLESS WAR's judgemental stare to act." return await ewutils.send_message(client, message.channel, ewutils.formatMessage(message.author, response)) # Ignore stunned players if ewcfg.status_stunned_id in statuses: return # Check the main command map for the requested command. global cmd_map cmd_fn = cmd_map.get(cmd) if user_data.poi in ewcfg.tutorial_pois: return await ewdungeons.tutorial_cmd(cmd_obj) elif cmd_fn != None: # Execute found command return await cmd_fn(cmd_obj) # FIXME debug # Test item creation elif debug == True and cmd == (ewcfg.cmd_prefix + 'createtestitem'): item_id = ewitem.item_create( item_type = 'medal', id_user = message.author.id, id_server = message.server.id, item_props = { 'medal_name': 'Test Award', 'medal_desc': '**{medal_name}**: *Awarded to Krak by Krak for testing shit.*' } ) ewutils.logMsg('Created item: {}'.format(item_id)) item = EwItem(id_item = item_id) item.item_props['test'] = 'meow' item.persist() item = EwItem(id_item = item_id) await ewutils.send_message(client, message.channel, ewutils.formatMessage(message.author, ewitem.item_look(item))) # Creates a poudrin elif debug == True and cmd == (ewcfg.cmd_prefix + 'createpoudrin'): for item in ewcfg.item_list: if item.context == "poudrin": ewitem.item_create( item_type = ewcfg.it_item, id_user = message.author.id, id_server = message.server.id, item_props = { 'id_item': item.id_item, 'context': item.context, 'item_name': item.str_name, 'item_desc': item.str_desc, } ), ewutils.logMsg('Created item: {}'.format(item.id_item)) item = EwItem(id_item = item.id_item) item.persist() else: pass await ewutils.send_message(client, message.channel, ewutils.formatMessage(message.author, "Poudrin created.")) # Gives the user some slime elif debug == True and cmd == (ewcfg.cmd_prefix + 'getslime'): user_data = EwUser(member = message.author) user_initial_level = user_data.slimelevel response = "You get 100,000 slime!" levelup_response = user_data.change_slimes(n = 100000) was_levelup = True if user_initial_level < user_data.slimelevel else False if was_levelup: response += " {}".format(levelup_response) user_data.persist() await ewutils.send_message(client, message.channel, ewutils.formatMessage(message.author, response)) elif debug == True and cmd == (ewcfg.cmd_prefix + 'getcoin'): user_data = EwUser(member=message.author) user_data.change_slimecoin(n=1000000000, coinsource=ewcfg.coinsource_spending) response = "You get 1,000,000,000 slimecoin!" user_data.persist() await ewutils.send_message(client, message.channel, ewutils.formatMessage(message.author, response)) # Deletes all items in your inventory. elif debug == True and cmd == (ewcfg.cmd_prefix + 'clearinv'): user_data = EwUser(member = message.author) ewitem.item_destroyall(id_server = message.server.id, id_user = message.author.id) response = "You destroy every single item in your inventory." user_data.persist() await ewutils.send_message(client, message.channel, ewutils.formatMessage(message.author, response)) elif debug == True and cmd == (ewcfg.cmd_prefix + 'createapple'): item_id = ewitem.item_create( id_user = message.author.id, id_server = message.server.id, item_type = ewcfg.it_food, item_props = { 'id_food': "direapples", 'food_name': "Dire Apples", 'food_desc': "This sure is a illegal Dire Apple!", 'recover_hunger': 500, 'str_eat': "You chomp into this illegal Dire Apple.", 'time_expir': int(time.time() + ewcfg.farm_food_expir) } ) ewutils.logMsg('Created item: {}'.format(item_id)) item = EwItem(id_item = item_id) item.item_props['test'] = 'meow' item.persist() await ewutils.send_message(client, message.channel, ewutils.formatMessage(message.author, "Apple created.")) elif debug == True and cmd == (ewcfg.cmd_prefix + 'createhat'): patrician_rarity = 20 patrician_smelted = random.randint(1, patrician_rarity) patrician = False if patrician_smelted == 1: patrician = True items = [] for cosmetic in ewcfg.cosmetic_items_list: if patrician and cosmetic.rarity == ewcfg.rarity_patrician: items.append(cosmetic) elif not patrician and cosmetic.rarity == ewcfg.rarity_plebeian: items.append(cosmetic) item = items[random.randint(0, len(items) - 1)] item_id = ewitem.item_create( item_type = ewcfg.it_cosmetic, id_user = message.author.id, id_server = message.server.id, item_props = { 'id_cosmetic': item.id_cosmetic, 'cosmetic_name': item.str_name, 'cosmetic_desc': item.str_desc, 'rarity': item.rarity, 'adorned': 'false' } ) ewutils.logMsg('Created item: {}'.format(item_id)) item = EwItem(id_item = item_id) item.item_props['test'] = 'meow' item.persist() await ewutils.send_message(client, message.channel, ewutils.formatMessage(message.author, "Hat created.")) elif debug == True and cmd == (ewcfg.cmd_prefix + 'createfood'): item = ewcfg.food_list[random.randint(0, len(ewcfg.food_list) - 1)] item_id = ewitem.item_create( item_type = ewcfg.it_food, id_user = message.author.id, id_server = message.server.id, item_props = { 'id_food': item.id_food, 'food_name': item.str_name, 'food_desc': item.str_desc, 'recover_hunger': item.recover_hunger, 'str_eat': item.str_eat, 'time_expir': item.time_expir } ) ewutils.logMsg('Created item: {}'.format(item_id)) item = EwItem(id_item = item_id) item.item_props['test'] = 'meow' item.persist() await ewutils.send_message(client, message.channel, ewutils.formatMessage(message.author, "Food created.")) # FIXME debug # Test item deletion elif debug == True and cmd == (ewcfg.cmd_prefix + 'delete'): items = ewitem.inventory( id_user = message.author.id, id_server = message.server.id ) for item in items: ewitem.item_delete( id_item = item.get('id_item') ) await ewutils.send_message(client, message.channel, ewutils.formatMessage(message.author, 'ok')) # AWOOOOO elif re_awoo.match(cmd): return await ewcmd.cmd_howl(cmd_obj) # Debug command to override the role of a user elif debug == True and cmd == (ewcfg.cmd_prefix + 'setrole'): response = "" if mentions_count == 0: response = 'Set who\'s role?' else: roles_map = ewutils.getRoleMap(message.server.roles) role_target = tokens[1] role = roles_map.get(role_target) if role != None: for user in mentions: try: await client.replace_roles(user, role) except: ewutils.logMsg('Failed to replace_roles for user {} with {}.'.format(user.display_name, role.name)) response = 'Done.' else: response = 'Unrecognized role.' await ewutils.send_message(client, cmd.message.channel, ewutils.formatMessage(message.author, response)) elif debug == True and cmd == (ewcfg.cmd_prefix + 'getrowdy'): response = "You get rowdy. F**k. YES!" user_data = EwUser(member=message.author) user_data.life_state = ewcfg.life_state_enlisted user_data.faction = ewcfg.faction_rowdys user_data.time_lastenlist = time_now + ewcfg.cd_enlist user_data.persist() await ewutils.send_message(client, message.channel, ewutils.formatMessage(message.author, response)) elif debug == True and cmd == (ewcfg.cmd_prefix + 'getkiller'): response = "You uh... 'get' killer. Sure." user_data = EwUser(member=message.author) user_data.life_state = ewcfg.life_state_enlisted user_data.faction = ewcfg.faction_killers user_data.time_lastenlist = time_now + ewcfg.cd_enlist user_data.persist() await ewutils.send_message(client, message.channel, ewutils.formatMessage(message.author, response)) # Toggles rain on and off elif debug == True and cmd == (ewcfg.cmd_prefix + 'toggledownfall'): market_data = EwMarket(id_server=message.server.id) if market_data.weather == ewcfg.weather_bicarbonaterain: newweather = ewcfg.weather_sunny market_data.weather = newweather response = "Bicarbonate rain turned OFF. Weather was set to {}.".format(newweather) else: market_data.weather = ewcfg.weather_bicarbonaterain response = "Bicarbonate rain turned ON." market_data.persist() await ewutils.send_message(client, message.channel, ewutils.formatMessage(message.author, response)) elif debug == True and cmd == (ewcfg.cmd_prefix + 'dayforward'): market_data = EwMarket(id_server=message.server.id) market_data.day += 1 market_data.persist() response = "Time has progressed 1 day forward manually." if ewutils.check_fursuit_active(market_data.id_server): response += "\nIt's a full moon!" await ewutils.send_message(client, message.channel, ewutils.formatMessage(message.author, response)) elif debug == True and cmd == (ewcfg.cmd_prefix + 'hourforward'): market_data = EwMarket(id_server=message.server.id) market_data.clock += 1 response = "Time has progressed 1 hour forward manually." if market_data.clock >= 24 or market_data.clock < 0: market_data.clock = 0 market_data.day += 1 response += "\nMidnight has come. 1 day progressed forward." if ewutils.check_fursuit_active(market_data.id_server): response += "\nIt's a full moon!" market_data.persist() await ewutils.send_message(client, message.channel, ewutils.formatMessage(message.author, response)) # didn't match any of the command words. else: """ couldn't process the command. bail out!! """ """ bot rule 0: be cute """ randint = random.randint(1,3) msg_mistake = "ENDLESS WAR is growing frustrated." if randint == 2: msg_mistake = "ENDLESS WAR denies you his favor." elif randint == 3: msg_mistake = "ENDLESS WAR pays you no mind." msg = await ewutils.send_message(client, cmd_obj.message.channel, msg_mistake) await asyncio.sleep(2) try: await client.delete_message(msg) except: pass elif content_tolower.find(ewcfg.cmd_howl) >= 0 or content_tolower.find(ewcfg.cmd_howl_alt1) >= 0 or re_awoo.match(content_tolower): """ Howl if !howl is in the message at all. """ return await ewcmd.cmd_howl(ewcmd.EwCmd( message = message, client = client ))
def move(self): resp_cont = ewutils.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 = 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 = ewcfg.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 = ewutils.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 = ewcfg.id_to_poi.get(self.poi) resp_cont.add_channel_response(poi_data.channel, response) return resp_cont