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: 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) 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: 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) await resp_cont.post() except: ewutils.logMsg("Error in event tick for server {}".format(id_server))
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
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
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(
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, 'Check out the guide for help: https://ew.krakissi.net/guide/') # 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 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 == '!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 == '!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)) # 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 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
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 weather_tick(id_server = None): if id_server != None: try: market_data = EwMarket(id_server = 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_server(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 = 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 order(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 ewutils.send_message( cmd.client, cmd.message.channel, ewutils.formatMessage(cmd.message.author, response)) market_data = EwMarket(id_server=cmd.message.server.id) poi = ewmap.fetch_poi_if_coordless(cmd.message.channel.name) if poi is None or len(poi.vendors) == 0: # 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.chname_to_poi.get(cmd.message.channel.name) district_data = EwDistrict(district=poi.id_poi, id_server=cmd.message.server.id) if district_data.is_degraded(): 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 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 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 if poi.is_subzone: district_data = EwDistrict(district=poi.mother_district, id_server=cmd.message.server.id) else: district_data = EwDistrict(district=poi.id_poi, id_server=cmd.message.server.id) if district_data.controlling_faction != "": # prices are halved for the controlling gang if district_data.controlling_faction == user_data.faction: value /= 2 # and 4 times as much for enemy gangsters elif user_data.faction != "": value *= 4 # 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 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 > user_data.slimes: # Not enough money. response = "A {} costs {:,} slime, and you only have {:,}.".format( name, value, user_data.slimes) else: if item_type == ewcfg.it_food: food_ordered = True food_items = ewitem.inventory( id_user=cmd.message.author.id, id_server=cmd.message.server.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_weapon_possession( ): response = "How are you planning to feed a weapon?" 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.message.server.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) 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'): 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.message.server.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 {:,} slime down on the counter at {} for {}.".format( value, 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)) 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 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 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(): 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: mutations = user_data.get_mutations() if random.randrange(5) == 0 and ewcfg.mutation_id_stickyfingers in mutations: value = 0 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 ) 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)) else: other_items_held = ewitem.inventory( id_user = user_data.id_user, id_server = cmd.guild.id, item_type_filter = item_type ) if len(other_items_held) >= ewcfg.generic_inv_limit: response = ewcfg.str_generic_inv_limit.format(item_type) 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 = -1, stack_size = 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))
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, 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