def make_purchase(self, buyer, amount): """ Khajit has wares, if you have coin. Args: buyer (PlayerOrNpc): the buyer amount (int): How much they're buying Returns: the amount they paid Raises: PayError if they can't afford stuff """ if amount > self.amount: raise PayError( "You want to buy %s, but there is only %s for sale." % (amount, self.amount)) cost = self.price * amount character = buyer.player.char_ob if cost > character.currency: raise PayError( "You cannot afford to pay %s when you only have %s silver." % (cost, character.currency)) character.pay_money(cost) self.amount -= amount self.save() self.record_sale(buyer, amount) self.send_goods(buyer, amount) self.pay_owner(buyer, amount, cost) return cost
def make_purchase(self, buyer, amount): """ Khajit has wares, if you have coin. Args: buyer (PlayerOrNpc): the buyer amount (int): How much they're buying Returns: the amount they paid Raises: PayError if they can't afford stuff """ if amount > self.amount: raise PayError("You want to buy %s, but there is only %s for sale." % (amount, self.amount)) cost = self.price * amount self.amount -= amount if self.broker_type == self.SALE: self.send_goods(buyer, amount) self.pay_owner(buyer, amount, cost) else: self.send_goods(self.owner, amount) self.pay_seller(buyer, amount, cost) if self.amount: self.save() self.record_sale(buyer, amount) else: self.delete() return cost
def change_price(self, new_price): """Changes the price to new_price. If we have an existing sale by that price, merge with it.""" if self.broker_type == self.PURCHASE: buyer = self.owner_character original_cost = new_price * self.amount new_cost = self.price * self.amount to_pay = original_cost - new_cost if to_pay > buyer.currency: raise PayError( "You cannot afford to pay %s when you only have %s silver." % (to_pay, buyer.currency)) self.owner_character.pay_money(to_pay) try: other_sale = self.owner.brokered_sales.get( sale_type=self.sale_type, price=new_price, crafting_material_type=self.crafting_material_type, broker_type=self.broker_type, ) other_sale.amount += self.amount other_sale.save() self.delete() except BrokeredSale.DoesNotExist: self.price = new_price self.save()
def pay_xp(self, value): """Attempts to spend xp""" if value < 0: raise ValueError("Attempted to spend negative xp.") if self.xp < value: raise PayError( "You tried to spend %s xp, but only have %s available." % (value, self.xp)) self.xp -= value self.msg("You spend %s xp and have %s remaining." % (value, self.xp))
def pay_money(self, amount, receiver=None): """ A method to pay money from this object, possibly to a receiver. All checks should be done before this, and messages also sent outside. This just transfers the money itself. :type self: ObjectDB :param amount: int :param receiver: ObjectDB """ currency = self.currency amount = round(amount, 2) if amount > currency: from server.utils.exceptions import PayError raise PayError("pay_money called without checking sufficient funds in character. Not enough.") self.currency -= amount if receiver: receiver.currency += amount return True
def make_purchase(self): """Buys some amount from a sale""" sale_type = self.get_sale_type() if len(self.rhslist) != 2: raise self.BrokerError( "You must ask for both an amount and a price.") amount = self.get_amount(self.rhslist[0]) price = self.get_amount(self.rhslist[1], "price") character = self.caller.player.char_ob cost = price * amount if cost > character.currency: raise PayError( "You cannot afford to pay %s when you only have %s silver." % (cost, character.currency)) material_type = None if sale_type == BrokeredSale.ACTION_POINTS: from evennia.server.models import ServerConfig disabled = ServerConfig.objects.conf(key="DISABLE_AP_TRANSFER") if disabled: raise self.BrokerError( "Action Point sales are temporarily disabled.") elif sale_type == BrokeredSale.CRAFTING_MATERIALS: from world.dominion.models import CraftingMaterialType try: material_type = CraftingMaterialType.objects.get( name__iexact=self.lhs) except CraftingMaterialType.DoesNotExist: raise self.BrokerError( "Could not find a material by the name '%s'." % self.lhs) if "nosell" in (material_type.acquisition_modifiers or ""): raise self.BrokerError( "You can't put contraband on the broker! Seriously, how are you still alive?" ) character.pay_money(cost) dompc = self.caller.player_ob.Dominion sell_orders = BrokeredSale.objects.filter( broker_type=BrokeredSale.SALE, price__lte=price, sale_type=sale_type, amount__gt=0, crafting_material_type=material_type).order_by('price') purchase, created = dompc.brokered_sales.get_or_create( price=price, sale_type=sale_type, crafting_material_type=material_type, broker_type=BrokeredSale.PURCHASE) if not created: original = amount amount += purchase.amount else: original = 0 for order in sell_orders: if amount > 0: seller = order.owner if seller != dompc and order.owner.player.roster.current_account != self.caller.roster.current_account: if amount > order.amount: buyamount = order.amount else: buyamount = amount order.make_purchase(dompc, buyamount) self.msg("You have bought %s %s from %s for %s silver." % (buyamount, order.material_name, seller, order.price * buyamount)) amount -= buyamount if order.price < price: character.pay_money(-(price - order.price) * buyamount) purchase.amount = amount purchase.save() if amount == 0: purchase.delete() created = None if created: self.msg( "You have placed an order for %s %s for %s silver each and %s total." % (amount, purchase.material_name, price, purchase.amount * price)) else: if amount > 0: self.msg( "Added %s to the existing order of %s for %s silver each and %s total." % (original, purchase.material_name, price, purchase.amount * price))