def getPriceBase(cmd): # based on stock success user_data = EwUser( member=cmd.message.author ) # market rates average to 1000. This fomula calculates prices to specification based on that amount. kfc = EwStock(stock='kfc', id_server=user_data.id_server) tcb = EwStock(stock='tacobell', id_server=user_data.id_server) hut = EwStock(stock='pizzahut', id_server=user_data.id_server) if abs(kfc.market_rate - 1000) > abs(tcb.market_rate - 1000) and abs( kfc.market_rate - 1000) > abs(hut.market_rate - 1000): return kfc.market_rate * 201 elif abs(tcb.market_rate - 1000) > abs(hut.market_rate - 1000): return tcb.market_rate * 201 else: return hut.market_rate * 201
async def update_stocks(id_server=None): if id_server: exchange_data = EwDistrict(district=ewcfg.poi_id_stockexchange, id_server=id_server) resp_cont = EwResponseContainer(ewcfg.get_client(), id_server=id_server) for stock in ewcfg.stocks: s = EwStock(id_server, stock) # we don't update stocks when they were just added # or when shamblers have degraded it if s.timestamp != 0 and not exchange_data.is_degraded(): s.timestamp = int(time.time()) market_response = await stock_market_tick(s, id_server) resp_cont.add_channel_response(ewcfg.channel_stockexchange, market_response) await resp_cont.post()
async def rate(cmd): user_data = EwUser(member=cmd.message.author) if user_data.life_state == ewcfg.life_state_shambler: response = "You lack the higher brain functions required to {}.".format(cmd.tokens[0]) return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) response = "" if cmd.message.channel.name != ewcfg.channel_stockexchange: # Only allowed in the stock exchange. response = "You must go to the Slime Stock Exchange to check the current stock exchange rates ." return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) else: poi = poi_static.id_to_poi.get(user_data.poi) district_data = EwDistrict(district=poi.id_poi, id_server=user_data.id_server) 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 fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) stock = "" if cmd.tokens_count > 0: stock = ewutils.flattenTokenListToString(cmd.tokens[1:]) if stock in ewcfg.stocks: stock = EwStock(id_server=cmd.guild.id, stock=stock) response = "The current value of {stock} stocks is {cred:,} SlimeCoin per 1000 Shares.".format(stock=ewcfg.stock_names.get(stock.id_stock), cred=stock.exchange_rate) elif stock == "": for stock in ewcfg.stocks: stock = EwStock(id_server=cmd.guild.id, stock=stock) response += "\nThe current value of {stock} stocks is {cred:,} SlimeCoin per 1000 Shares.".format(stock=ewcfg.stock_names.get(stock.id_stock), cred=stock.exchange_rate) else: response = "That's not a valid stock name, please use a proper one, you c**t: {}".format(ewutils.formatNiceList(ewcfg.stocks)) # Send the response to the player. await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
def get_user_shares_str(id_server=None, stock=None, id_user=None): response = "" if id_server != None and stock != None and id_user != None: user_data = EwUser(id_server=id_server, id_user=id_user) stock = EwStock(id_server=id_server, stock=stock) shares = market_utils.getUserTotalShares(id_server=user_data.id_server, stock=stock.id_stock, id_user=user_data.id_user) shares_value = round(shares * (stock.exchange_rate / 1000.0)) response = "You have {shares:,} shares in {stock}".format( shares=shares, stock=ewcfg.stock_names.get(stock.id_stock)) # if user_data.poi == ewcfg.poi_id_downtown: response += ", currently valued at {coin:,} SlimeCoin.".format( coin=shares_value) # else: # response += "." return response
async def menu(cmd): user_data = EwUser(member=cmd.message.author, data_level=2) if user_data.life_state == ewcfg.life_state_shambler and user_data.poi != ewcfg.poi_id_nuclear_beach_edge: response = "You lack the higher brain functions required to {}.".format(cmd.tokens[0]) return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) market_data = EwMarket(id_server=cmd.guild.id) # poi = ewmap.fetch_poi_if_coordless(cmd.message.channel.name) poi = poi_static.id_to_poi.get(user_data.poi) if user_data.poi == ewcfg.poi_id_clinicofslimoplasty: response = "Try {}browse. The menu is in the zines.".format(ewcfg.cmd_prefix) elif poi is None or len(poi.vendors) == 0 or ewutils.channel_name_is_poi(cmd.message.channel.name) == False: # Only allowed in the food court. response = "There’s nothing to buy here. If you want to purchase some items, go to a sub-zone with a vendor in it, like the food court, the speakeasy, or the bazaar." else: poi = poi_static.id_to_poi.get(user_data.poi) mother_district_data = None for mother_poi in poi.mother_districts: mother_poi_data = poi_static.id_to_poi.get(mother_poi) if mother_poi_data.is_district: # One of the mother pois was a district, get its controlling faction mother_district_data = EwDistrict(district=mother_poi, id_server=user_data.id_server) break else: # One of the mother pois was a street, get the father district of that street and its controlling faction father_poi = mother_poi_data.father_district mother_district_data = EwDistrict(district=father_poi, id_server=user_data.id_server) break district_data = EwDistrict(district=poi.id_poi, id_server=user_data.id_server) # mother_district_data = EwDistrict(district = destination_poi.id_poi, id_server = user_data.id_server) shambler_multiplier = 1 # for speakeasy during shambler times if district_data.is_degraded() and poi.id_poi != ewcfg.poi_id_nuclear_beach_edge: if poi.id_poi == ewcfg.poi_id_speakeasy: shambler_multiplier = 4 else: response = "{} has been degraded by shamblers. You can't {} here anymore.".format(poi.str_name, cmd.tokens[0]) return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) controlling_faction = poi_utils.get_subzone_controlling_faction(user_data.poi, user_data.id_server) response = "{} Menu:\n\n".format(poi.str_name) vendors_list = poi.vendors for vendor in vendors_list: if vendor == ewcfg.vendor_secretbodega: if user_data.freshness < ewcfg.freshnesslevel_4: continue else: response += '\nThe hipster behind the counter nearly falls out of his chair after laying eyes on the sheer, unadulterated freshness before him.\n"S-Sir! Your outfit... i-it is positively ***on fleek!!*** As I see you are a fashion enthusiast like myself, let me show you the good stuff…"\n' items = [] # If the vendor is the bazaar get the current rotation of items from the market_data vendor_inv = vendors.vendor_inv[vendor] if vendor != ewcfg.vendor_bazaar else market_data.bazaar_wares.values() for item_name in vendor_inv: item_item = static_items.item_map.get(item_name) food_item = static_food.food_map.get(item_name) cosmetic_item = static_cosmetics.cosmetic_map.get(item_name) furniture_item = static_items.furniture_map.get(item_name) weapon_item = static_weapons.weapon_map.get(item_name) relic_item = static_relic.relic_map.get(item_name) if relic_item is not None: if relic_utils.canCreateRelic(item_name, cmd.guild.id) == None: continue # increase profits for the stock market stock_data = None if vendor in ewcfg.vendor_stock_map: stock = ewcfg.vendor_stock_map.get(vendor) stock_data = EwStock(id_server=user_data.id_server, stock=stock) value = 0 if item_item: value = item_item.price if food_item: value = food_item.price if cosmetic_item: value = cosmetic_item.price if furniture_item: value = furniture_item.price if weapon_item: value = weapon_item.price if relic_item: value = relic_item.price if stock_data != None: value *= (stock_data.exchange_rate / ewcfg.default_stock_exchange_rate) ** 0.2 # multiply by 4 is speakeasy is shambled value *= shambler_multiplier if mother_district_data != None: if controlling_faction != "": # prices are halved for the controlling gang if controlling_faction == user_data.faction: value /= 2 # and 4 times as much for enemy gangsters elif user_data.faction != "": value *= 4 if vendor == ewcfg.vendor_breakroom and user_data.faction == ewcfg.faction_slimecorp: value = 0 value = int(value) if value != 0: items.append('{} ({:,})'.format(item_name, value)) else: items.append(item_name) response += "**{}**: *{}*\n".format(vendor, ewutils.formatNiceList(names=items)) if vendor == ewcfg.vendor_bodega: if user_data.freshness < ewcfg.freshnesslevel_1: response += "\nThe hipster behind the counter is utterly repulsed by the fashion disaster in front of him. Looks like you just aren’t fresh enough for him." if user_data.has_soul == 0: if vendor == ewcfg.vendor_dojo: response += "\n\nThe Dojo master looks at your soulless form with pity." elif vendor == ewcfg.vendor_bar: response += "\n\nThe bartender, sensing your misery, asks if you're okay." elif vendor == ewcfg.vendor_diner: response += "\n\nThe cook gives you a concerned look as he throws down another helping of flapjacks." elif vendor == ewcfg.vendor_seafood: response += "\n\nThe waiter sneers at how soulless and unkempt you look. You try to ignore him." elif vendor == ewcfg.vendor_bazaar: response += "\n\nAll the shops seem so lively. You wish you had a soul so you could be like them." elif vendor == ewcfg.vendor_beachresort or vendor == ewcfg.vendor_countryclub: response += "\n\nEverything looks so fancy here, but it doesn't really appeal to you since you don't have a soul." elif vendor == ewcfg.vendor_bodega: if user_data.freshness < ewcfg.freshnesslevel_1: response += ".. and you probably never will be." elif vendor == ewcfg.vendor_glocksburycomics: response += "\n\nThe cashier here tries to start up a conversation about life being worth living. You're having none of it." elif vendor == ewcfg.vendor_basedhardware: response += "\n\nSo many industrial metals here... You contemplate which you could use to kill yourself..." elif vendor == ewcfg.vendor_wafflehouse: response += "\n\nNot even waffles could hope to make your emptiness go away." elif vendor == ewcfg.vendor_greencakecafe: response += "\n\nThe barista behind the counter pauses to look at your soulless misery for a second, but decides you're not worth it and gets back to work." elif vendor == ewcfg.vendor_slimypersuits: response += "\n\nYour mere presence in here ruins the cheery atmosphere." # Send the response to the player. await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
async def order(cmd): user_data = EwUser(member=cmd.message.author) mutations = user_data.get_mutations() if user_data.life_state == ewcfg.life_state_shambler and user_data.poi != ewcfg.poi_id_nuclear_beach_edge: response = "You lack the higher brain functions required to {}.".format(cmd.tokens[0]) return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) market_data = EwMarket(id_server=cmd.guild.id) currency_used = 'slime' current_currency_amount = user_data.slimes # poi = ewmap.fetch_poi_if_coordless(cmd.message.channel.name) poi = poi_static.id_to_poi.get(user_data.poi) if poi is None or len(poi.vendors) == 0 or ewutils.channel_name_is_poi(cmd.message.channel.name) == False: # Only allowed in the food court. response = "There’s nothing to buy here. If you want to purchase some items, go to a sub-zone with a vendor in it, like the food court, the speakeasy, or the bazaar." else: poi = poi_static.id_to_poi.get(user_data.poi) district_data = EwDistrict(district=poi.id_poi, id_server=user_data.id_server) shambler_multiplier = 1 # for speakeasy during shambler times if district_data.is_degraded(): if poi.id_poi == ewcfg.poi_id_speakeasy: shambler_multiplier = 4 else: response = "{} has been degraded by shamblers. You can't {} here anymore.".format(poi.str_name, cmd.tokens[0]) return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) # value = ewutils.flattenTokenListToString(cmd.tokens[1:2]) # if cmd.tokens_count > 1: # value = cmd.tokens[1] # value = value.lower() value = None togo = False if cmd.tokens_count > 1: for token in cmd.tokens[1:]: if token.startswith('<@') == False and token.lower() not in "togo": # togo can be spelled together or separate value = token break for token in cmd.tokens[1:]: if token.lower() in "togo": # lets people get away with just typing only to or only go (or only t etc.) but whatever togo = True break # Finds the item if it's an EwGeneralItem. if value == "mylittleponyfigurine": value = random.choice(static_items.furniture_pony) item = static_items.item_map.get(value) item_type = ewcfg.it_item if item != None: item_id = item.id_item name = item.str_name # Finds the item if it's an EwFood item. if item == None: item = static_food.food_map.get(value) item_type = ewcfg.it_food if item != None: item_id = item.id_food name = item.str_name # Finds the item if it's an EwCosmeticItem. if item == None: item = static_cosmetics.cosmetic_map.get(value) item_type = ewcfg.it_cosmetic if item != None: item_id = item.id_cosmetic name = item.str_name if item == None: item = static_items.furniture_map.get(value) item_type = ewcfg.it_furniture if item != None: item_id = item.id_furniture name = item.str_name if item_id in static_items.furniture_pony: item.vendors = [ewcfg.vendor_bazaar] if item == None: item = static_weapons.weapon_map.get(value) item_type = ewcfg.it_weapon if item != None: item_id = item.id_weapon name = item.str_weapon if item == None: item = static_relic.relic_map.get(value) item_type = ewcfg.it_relic if item != None and relic_utils.canCreateRelic(item.id_relic, cmd.guild.id): item_id = item.id_relic name = item.str_name elif item != None: item = None if item != None: item_type = item.item_type # Gets a vendor that the item is available and the player currently located in try: current_vendor = (set(item.vendors).intersection(set(poi.vendors))).pop() except: current_vendor = None # Check if the item is available in the current bazaar item rotation if current_vendor == ewcfg.vendor_bazaar: if item_id not in market_data.bazaar_wares.values(): if item_id in static_items.furniture_pony and "mylittleponyfigurine" in market_data.bazaar_wares.values(): pass else: current_vendor = None if current_vendor is None or len(current_vendor) < 1: response = "Check the {} for a list of items you can {}.".format(ewcfg.cmd_menu, ewcfg.cmd_order) else: response = "" value = item.price premium_purchase = True if item_id in ewcfg.premium_items else False if premium_purchase: togo = True # Just in case they order a premium food item, don't make them eat it right then and there. if ewcfg.cd_premium_purchase > (int(time.time()) - user_data.time_lastpremiumpurchase): response = "That item is in very limited stock! The vendor asks that you refrain from purchasing it for a day or two." return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) elif ewcfg.cd_new_player > (int(time.time()) - user_data.time_joined): response = "You've only been in the city for a few days. The vendor doesn't trust you with that item very much..." return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) stock_data = None company_data = None # factor in the current stocks for vendor in item.vendors: if vendor in ewcfg.vendor_stock_map: stock = ewcfg.vendor_stock_map.get(vendor) company_data = EwCompany(id_server=user_data.id_server, stock=stock) stock_data = EwStock(id_server=user_data.id_server, stock=stock) if stock_data is not None: value *= (stock_data.exchange_rate / ewcfg.default_stock_exchange_rate) ** 0.2 controlling_faction = poi_utils.get_subzone_controlling_faction(user_data.poi, user_data.id_server) if controlling_faction != "": # prices are halved for the controlling gang if controlling_faction == user_data.faction: value /= 2 # and 4 times as much for enemy gangsters elif user_data.faction != "": value *= 4 # raise shambled speakeasy price 4 times value *= shambler_multiplier # Raise the price for togo ordering. This gets lowered back down later if someone does togo ordering on a non-food item by mistake. if togo: value *= 1.5 if current_vendor == ewcfg.vendor_breakroom and user_data.faction == ewcfg.faction_slimecorp: value = 0 value = int(value) food_ordered = False target_data = None # Kingpins eat free. if (user_data.life_state == ewcfg.life_state_kingpin or user_data.life_state == ewcfg.life_state_grandfoe) and item_type == ewcfg.it_food: value = 0 if value > current_currency_amount: # Not enough money. response = "A {} costs {:,} {}, and you only have {:,}.".format(name, value, currency_used, current_currency_amount) else: mutations = user_data.get_mutations() if random.randrange(5) == 0 and ewcfg.mutation_id_stickyfingers in mutations: value = 0 user_data.change_crime(n=ewcfg.cr_larceny_points) inv_response = bknd_item.check_inv_capacity(user_data=user_data, item_type=item_type, return_strings=True, pronoun="You") if inv_response != "" and (item_type != ewcfg.it_food or togo): return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, inv_response)) if item_type == ewcfg.it_food: food_ordered = True target = None target_data = None if not togo: # cant order togo for someone else, you can just give it to them in person if cmd.mentions_count == 1: target = cmd.mentions[0] if target.id == cmd.message.author.id: target = None if target != None: target_data = EwUser(member=target) if target_data.life_state == ewcfg.life_state_corpse and target_data.get_possession(): response = "How are you planning to feed them while they're possessing you?" return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) elif target_data.poi != user_data.poi: response = "You can't order anything for them because they aren't here!" return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) elif item_type == ewcfg.it_weapon: if user_data.life_state == ewcfg.life_state_corpse: response = "Ghosts can't hold weapons." return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) item_props = itm_utils.gen_item_props(item) # Only food should have the value multiplied. If someone togo orders a non-food item by mistake, lower it back down. if not food_ordered and togo: value = int(value / 1.5) if currency_used == 'slime': user_data.change_slimes(n=-value, source=ewcfg.source_spending) if company_data is not None: company_data.recent_profits += value company_data.persist() if item.str_name == "arcade cabinet": item_props['furniture_desc'] = random.choice(ewcfg.cabinets_list) elif item.item_type == ewcfg.it_furniture: if "custom" in item_props.get('id_furniture'): if cmd.tokens_count < 4 or cmd.tokens[2] == "" or cmd.tokens[3] == "": response = "You need to specify the customization text before buying a custom item. Come on, isn't that self-evident? (!order [custom item] \"custom name\" \"custom description\")" return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) else: customname = cmd.tokens[2] if len(customname) > 32: response = "That name is too long. ({:,}/32)".format(len(customname)) return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) customdesc = cmd.tokens[3] if len(customdesc) > 500: response = "That description is too long. ({:,}/500)".format(len(customdesc)) return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) name = item_props['furniture_name'] = item_props['furniture_name'].format(custom=customname) item_props['furniture_desc'] = customdesc item_props['furniture_look_desc'] = item_props['furniture_look_desc'].format(custom=customname) item_props['furniture_place_desc'] = item_props['furniture_place_desc'].format(custom=customname) id_item = bknd_item.item_create( item_type=item_type, id_user=cmd.message.author.id, id_server=cmd.guild.id, stack_max=-1, stack_size=0, item_props=item_props ) if value == 0: response = "You swipe a {} from the counter at {}.".format(name, current_vendor) else: response = "You slam {:,} {} down on the counter at {} for {}.".format(value, currency_used, current_vendor, name) if food_ordered and not togo: item_data = EwItem(id_item=id_item) # Eat food on the spot! if target_data != None: target_player_data = EwPlayer(id_user=target_data.id_user) if value == 0: response = "You swipe a {} from the counter at {} and give it to {}.".format(name, current_vendor, target_player_data.display_name) else: response = "You slam {:,} slime down on the counter at {} for {} and give it to {}.".format(value, current_vendor, name, target_player_data.display_name) response += "\n\n*{}*: ".format(target_player_data.display_name) + target_data.eat(item_data) target_data.persist() else: if value == 0: response = "You swipe a {} from the counter at {} and eat it right on the spot.".format(name, current_vendor) else: response = "You slam {:,} slime down on the counter at {} for {} and eat it right on the spot.".format(value, current_vendor, name) user_player_data = EwPlayer(id_user=user_data.id_user) response += "\n\n*{}*: ".format(user_player_data.display_name) + user_data.eat(item_data) user_data.persist() if premium_purchase: user_data.time_lastpremiumpurchase = int(time.time()) user_data.persist() else: response = "Check the {} for a list of items you can {}.".format(ewcfg.cmd_menu, ewcfg.cmd_order) # Send the response to the player. await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
async def withdraw(cmd): user_data = EwUser(member=cmd.message.author) if user_data.life_state == ewcfg.life_state_shambler: response = "You lack the higher brain functions required to {}.".format(cmd.tokens[0]) return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) time_now = round(time.time()) market_data = EwMarket(id_server=cmd.message.author.guild.id) if market_data.clock < 6 or market_data.clock >= 20: response = ewcfg.str_exchange_closed return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) if cmd.message.channel.name != ewcfg.channel_stockexchange: # or user_data.poi != ewcfg.poi_id_downtown: # Only allowed in the stock exchange. response = ewcfg.str_exchange_channelreq.format(currency="SlimeCoin", action="withdraw") return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) poi = poi_static.id_to_poi.get(user_data.poi) district_data = EwDistrict(district=poi.id_poi, id_server=user_data.id_server) 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 fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) if user_data.life_state == ewcfg.life_state_corpse: # Disallow withdraws from ghosts. response = "Your slimebroker can't confirm your identity while you're dead." return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) else: value = None stock = None if cmd.tokens_count > 1: value = ewutils.getIntToken(cmd.tokens[1:], allow_all=True) for token in cmd.tokens[1:]: if token.lower() in ewcfg.stocks: stock = token.lower() break if stock != None: stock = EwStock(id_server=cmd.guild.id, stock=stock) total_shares = market_utils.getUserTotalShares(id_server=user_data.id_server, stock=stock.id_stock, id_user=user_data.id_user) if value != None: if value < 0: value = total_shares if value <= 0: value = None if value != None: if value <= total_shares: exchange_rate = (stock.exchange_rate / 1000.0) shares = value slimecoin = round(value * exchange_rate) if user_data.time_lastinvest + ewcfg.cd_invest > time_now: # Limit frequency of withdrawals response = ewcfg.str_exchange_busy.format(action="withdraw") else: user_data.change_slimecoin(n=slimecoin, coinsource=ewcfg.coinsource_withdraw) total_shares -= shares user_data.time_lastinvest = time_now stock.total_shares -= shares response = "You exchange {shares:,} shares in {stock} for {coins:,} SlimeCoin.".format(coins=slimecoin, shares=shares, stock=ewcfg.stock_names.get(stock.id_stock)) user_data.persist() stock.timestamp = round(time.time()) stock.persist() market_utils.updateUserTotalShares(id_server=user_data.id_server, stock=stock.id_stock, id_user=user_data.id_user, shares=total_shares) else: response = "You don't have that many shares in {stock} to exchange.".format(stock=ewcfg.stock_names.get(stock.id_stock)) else: response = ewcfg.str_exchange_specify.format(currency="SlimeCoin", action="withdraw") else: response = "That's not a valid stock name, please use a proper one, you c**t: {}".format(ewutils.formatNiceList(names=ewcfg.stocks)) await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
async def invest(cmd): user_data = EwUser(member=cmd.message.author) if user_data.life_state == ewcfg.life_state_shambler: response = "You lack the higher brain functions required to {}.".format(cmd.tokens[0]) return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) time_now = round(time.time()) market_data = EwMarket(id_server=cmd.message.author.guild.id) if cmd.message.channel.name != ewcfg.channel_stockexchange: # or user_data.poi != ewcfg.poi_id_downtown: # Only allowed in the stock exchange. response = ewcfg.str_exchange_channelreq.format(currency="SlimeCoin", action="invest") return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) poi = poi_static.id_to_poi.get(user_data.poi) district_data = EwDistrict(district=poi.id_poi, id_server=user_data.id_server) 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 fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) if market_data.clock < 6 or market_data.clock >= 20: response = ewcfg.str_exchange_closed return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) if user_data.time_lastinvest + ewcfg.cd_invest > time_now: # Limit frequency of investments. response = ewcfg.str_exchange_busy.format(action="invest") return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) if user_data.life_state == ewcfg.life_state_corpse: # Disallow invests from ghosts. response = "Your slimebroker can't confirm your identity while you're dead." return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) if user_data.life_state == ewcfg.life_state_kingpin: # Disallow investments by RF and CK kingpins. response = "You need that money to buy more videogames." return await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response)) else: value = None stock = None if cmd.tokens_count > 1: value = ewutils.getIntToken(cmd.tokens, allow_all=True) for token in cmd.tokens[1:]: if token.lower() in ewcfg.stocks: stock = token.lower() break if value != None: if value < 0: value = user_data.slimecoin if value <= 0: value = None if value != None: if stock != None: stock = EwStock(id_server=cmd.guild.id, stock=stock) # basic exchange rate / 1000 = 1 share exchange_rate = (stock.exchange_rate / 1000.0) cost_total = round(value * 1.05) # gets the highest value possible where the player can still pay the fee if value == user_data.slimecoin: while cost_total > user_data.slimecoin: value -= cost_total - value cost_total = round(value * 1.05) # The user can only buy a whole number of shares, so adjust their cost based on the actual number of shares purchased. net_shares = round(value / exchange_rate) if user_data.slimecoin < cost_total: response = "You don't have enough SlimeCoin. ({:,}/{:,})".format(user_data.slimecoin, cost_total) elif value > user_data.slimecoin: response = "You don't have that much SlimeCoin to invest." elif net_shares == 0: response = "You don't have enough SlimeCoin to buy a share in {stock}".format(stock=ewcfg.stock_names.get(stock.id_stock)) else: user_data.change_slimecoin(n=-cost_total, coinsource=ewcfg.coinsource_invest) shares = market_utils.getUserTotalShares(id_server=user_data.id_server, stock=stock.id_stock, id_user=user_data.id_user) shares += net_shares market_utils.updateUserTotalShares(id_server=user_data.id_server, stock=stock.id_stock, id_user=user_data.id_user, shares=shares) user_data.time_lastinvest = time_now stock.total_shares += net_shares response = "You invest {coin:,} SlimeCoin and receive {shares:,} shares in {stock}. Your slimebroker takes his nominal fee of {fee:,} SlimeCoin.".format(coin=value, shares=net_shares, stock=ewcfg.stock_names.get(stock.id_stock), fee=(cost_total - value)) user_data.persist() stock.timestamp = round(time.time()) stock.persist() else: response = "That's not a valid stock name, please use a proper one, you c**t: {}".format(ewutils.formatNiceList(names=ewcfg.stocks)) else: response = ewcfg.str_exchange_specify.format(currency="SlimeCoin", action="invest") # Send the response to the player. await fe_utils.send_message(cmd.client, cmd.message.channel, fe_utils.formatMessage(cmd.message.author, response))
async def stock_market_tick(stock_data, id_server): market_data = EwMarket(id_server=id_server) company_data = EwCompany(id_server=id_server, stock=stock_data.id_stock) crashstate = EwGamestate(id_server=id_server, id_state='stockcrashdive').bit # Nudge the value back to stability. market_rate = stock_data.market_rate if market_rate >= 1030: market_rate -= 10 elif market_rate <= 970: market_rate += 10 # Invest/Withdraw effects coin_rate = 0 #stock_at_last_tick = EwStock(id_server=id_server, stock=stock_data.id_stock, timestamp=market_data.time_lasttick) #latest_stock = EwStock(id_server=id_server, stock=stock_data.id_stock) if stock_data.previous_entry != 0: total_shares = [stock_data.total_shares, stock_data.previous_entry[4]] else: total_shares = [ stock_data.total_shares, EwStock(id_server=id_server, stock=stock_data.id_stock, timestamp=market_data.time_lasttick).total_shares ] # Add profit bonus. profits = company_data.recent_profits profit_bonus = profits / 100 # - 1 * ((latest_stock.exchange_rate / ewcfg.default_stock_exchange_rate) ** 0.2) profit_bonus = min(50, max(profit_bonus, -50)) market_rate += (profit_bonus / 2) if total_shares[0] != total_shares[1]: # Positive if net investment, negative if net withdrawal. coin_change = (total_shares[0] - total_shares[1]) coin_rate = ((coin_change * 1.0) / total_shares[1] if total_shares[1] != 0 else 1) if coin_rate > 1.0: coin_rate = 1.0 elif coin_rate < -0.5: coin_rate = -0.5 coin_rate = round((coin_rate * ewcfg.max_iw_swing) if coin_rate > 0 else ( coin_rate * 2 * ewcfg.max_iw_swing)) market_rate += coin_rate # Tick down the boombust cooldown. if stock_data.boombust < 0: stock_data.boombust += 1 elif stock_data.boombust > 0: stock_data.boombust -= 1 # Adjust the market rate. fluctuation = 0 # (random.randrange(5) - 2) * 100 noise = (random.randrange(19) - 9) * 2 subnoise = (random.randrange(13) - 6) # Some extra excitement! if noise == 0 and subnoise == 0: boombust = (random.randrange(3) - 1) * 200 if crashstate == 1 and boombust > 0: boombust = -boombust # If a boombust occurs shortly after a previous boombust, make sure it's the opposite effect. (Boom follows bust, bust follows boom.) if (stock_data.boombust > 0 and boombust > 0) or (stock_data.boombust < 0 and boombust < 0): boombust *= -1 if boombust != 0: stock_data.boombust = ewcfg.cd_boombust if boombust < 0: stock_data.boombust *= -1 else: boombust = 0 market_rate += fluctuation + noise + subnoise + boombust if market_rate > 500 and crashstate == 1: market_rate = round(market_rate / 1.25) if market_rate < 300: market_rate = (300 + noise + subnoise) # percentage = ((market_rate / 10) - 100) # percentage_abs = percentage * -1 exchange_rate_increase = round( (market_rate - ewcfg.default_stock_market_rate) * min(stock_data.exchange_rate, ewcfg.default_stock_exchange_rate) / ewcfg.default_stock_market_rate) percentage = exchange_rate_increase / stock_data.exchange_rate percentage_abs = percentage * -1 # negative exchange rate causes problems, duh # exchange_rate_increase = max(exchange_rate_increase, -stock_data.exchange_rate + 1000) points = abs(exchange_rate_increase / 1000.0) stock_data.exchange_rate += exchange_rate_increase stock_data.market_rate = market_rate # Give some indication of how the market is doing to the users. response = ewcfg.stock_emotes.get( stock_data.id_stock) + ' ' + ewcfg.stock_names.get( stock_data.id_stock) + ' ' if stock_data.exchange_rate < 1000: response += 'has gone bankrupt!' if stock_data.total_shares > 0: majority_shareholder = get_majority_shareholder( stock=stock_data.id_stock, id_server=id_server) player_data = EwPlayer(id_user=majority_shareholder) shares = getUserTotalShares(stock=stock_data.id_stock, id_user=majority_shareholder, id_server=stock_data.id_server) shares_lost = round(shares * 0.9) stock_data.total_shares -= shares_lost updateUserTotalShares(stock=stock_data.id_stock, id_user=majority_shareholder, id_server=stock_data.id_server, shares=shares - shares_lost) response += ' The majority shareholder {} is held responsible. SlimeCorp seizes 90% of their shares in the company to pay for the damages.'.format( player_data.display_name) stock_data.exchange_rate = 10000 else: response += ' SlimeCorp pumps several billion slimecoin into bailing the company out and a new image campaign.' stock_data.exchange_rate = ewcfg.default_stock_exchange_rate stock_data.market_rate = ewcfg.default_stock_market_rate else: # Market is up ... if market_rate > 1200: response += 'is skyrocketing!!! Slime stock is up {p:.3g} points!!!'.format( p=points) elif market_rate > 1100: response += 'is booming! Slime stock is up {p:.3g} points!'.format( p=points) elif market_rate > 1000: response += 'is doing well. Slime stock is up {p:.3g} points.'.format( p=points) # Market is down ... elif market_rate < 800: response += 'is plummeting!!! Slime stock is down {p:.3g} points!!!'.format( p=points) elif market_rate < 900: response += 'is stagnating! Slime stock is down {p:.3g} points!'.format( p=points) elif market_rate < 1000: response += 'is a bit sluggish. Slime stock is down {p:.3g} points.'.format( p=points) # Perfectly balanced else: response += 'is holding steady. No change in slime stock value.' response += ' ' + ewcfg.stock_emotes.get(stock_data.id_stock) stock_data.persist() company_data.total_profits += company_data.recent_profits company_data.recent_profits = 0 company_data.persist() # Send the announcement. return response