Example #1
0
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))
Example #2
0
	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
Example #3
0
	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
Example #4
0
        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(
Example #5
0
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
		))
Example #6
0
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
Example #7
0
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()	
Example #8
0
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))
Example #9
0
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))
Example #10
0
async def order(cmd):
	user_data = EwUser(member = cmd.message.author)
	mutations = user_data.get_mutations()
	if user_data.life_state == ewcfg.life_state_shambler and user_data.poi != ewcfg.poi_id_nuclear_beach_edge:
		response = "You lack the higher brain functions required to {}.".format(cmd.tokens[0])
		return await 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))
Example #11
0
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
Example #12
0
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