コード例 #1
0
ファイル: miniscape.py プロジェクト: coizioc/miniscape
    async def trade(self, ctx, *args):
        """Trades to a person a number of a given object for a given price."""
        if has_post_permission(ctx.guild.id, ctx.channel.id):
            if len(args) < 4:
                await ctx.send(
                    'Arguments missing. '
                    'Syntax is `~trade [name] [number] [item] [offer]`.')
                return

            try:
                trade = {
                    'user1': ctx.author.id,
                    'user2': args[0],
                    'amount1': args[1],
                    'amount2': args[-1],
                    'item1': ' '.join(args[2:-1]),
                    'item2': 'coins'
                }
                ctx.bot.trade_manager.add_trade(ctx, trade)
            except TradeError as e:
                await ctx.send(e.msg)
                return

            name = args[0]
            for member in ctx.guild.members:
                if name.lower() in member.name.lower():
                    name_member = member
                    break

            offer = users.parse_int(args[-1])
            number = users.parse_int(args[1])
            itemid = items.find_by_name(' '.join(args[2:-1]))
            name = get_display_name(ctx.author)
            offer_formatted = '{:,}'.format(offer)
            out = (
                f'{items.SHOP_HEADER}{name.title()} wants to sell {name_member.mention} '
                f'{items.add_plural(number, itemid)} for {offer_formatted} coins. '
                f'To accept this offer, reply to this post with a :thumbsup:. '
                f'Otherwise, this offer will expire in one minute.')
            msg = await ctx.send(out)

            if await self.confirm(ctx, msg, out, timeout=60):
                price = {"0": offer}
                users.update_inventory(name_member.id, price, remove=True)
                users.update_inventory(ctx.author.id, price)
                loot = {itemid: number}
                users.update_inventory(ctx.author.id, loot, remove=True)
                users.update_inventory(name_member.id, loot)

                buyer_name = get_display_name(name_member)
                await ctx.send(
                    f'{items.SHOP_HEADER}{name.title()} successfully sold '
                    f'{items.add_plural(number, itemid)} to {buyer_name} for '
                    f'{offer_formatted} coins!')
            ctx.bot.trade_manager.reset_trade(trade, ctx.author.id,
                                              name_member.id)
コード例 #2
0
ファイル: miniscape.py プロジェクト: coizioc/miniscape
 async def sellall(self, ctx, maxvalue=None):
     """Sells all items in the player's inventory (below a certain value) for gold pieces."""
     if has_post_permission(ctx.guild.id, ctx.channel.id):
         name = get_display_name(ctx.author)
         if maxvalue is not None:
             value = users.get_value_of_inventory(ctx.author.id,
                                                  under=maxvalue)
             users.update_inventory(ctx.author.id, value * ["0"])
             users.clear_inventory(ctx.author.id, under=maxvalue)
             value_formatted = '{:,}'.format(value)
             maxvalue_formatted = '{:,}'.format(users.parse_int(maxvalue))
             name = get_display_name(ctx.author)
             out = f"All items in {name}'s inventory worth under {maxvalue_formatted} coins "\
                   f"sold for {value_formatted} coins!"
         else:
             value = users.get_value_of_inventory(ctx.author.id)
             users.update_inventory(ctx.author.id, value * ["0"])
             users.clear_inventory(ctx.author.id)
             value_formatted = '{:,}'.format(value)
             out = f"All items in {name}'s inventory "\
                   f"sold for {value_formatted} coins!"
         await ctx.send(out)
コード例 #3
0
ファイル: other.py プロジェクト: coizioc/miniscape
    async def deathmatch(self, ctx, opponent='rand', bet=None):
        """Allows users to duke it out in a 1v1 match."""
        author = ctx.user_object
        author_name = author.plain_name
        if bet is not None:
            if author.is_ironman:
                await ctx.send('Ironmen cannot start staked deathmatches.')
                return
            try:
                bet = users.parse_int(bet)
            except ValueError:
                await ctx.send(f'{bet} does not represent a valid number.')
            bet_formatted = '{:,}'.format(bet)
            if not author.has_item_amount_by_name('coins', bet):
                await ctx.send(f'You do not have {bet_formatted} coins.')
                return
            try:
                opponent_member = parse_name(ctx.message.guild, opponent)
                opponent_obj = User.objects.get(id=opponent_member.id)
                opponent_name = opponent_obj.plain_name
            except NameError:
                await ctx.send(f'{opponent} not found in server.')
                return
            except AmbiguousInputError as members:
                await ctx.send(
                    f'Input {opponent} can refer to multiple people ({members})'
                )
                return
            if opponent_obj == author:
                await ctx.send('You cannot fight yourself.')
                return
            if opponent_obj.is_ironman:
                await ctx.send(
                    'You cannot start a staked deathmatch with an ironman.')
                return
            if not opponent_obj.has_item_amount_by_name('coins', bet):
                await ctx.send(
                    f'{opponent_name} does not have {bet_formatted} coins.')
                return
            author.update_inventory({'0': bet}, remove=True)
            out = f'Deathmatch set up between {author_name} and {opponent_member.mention} with bet ' \
                  f'{bet_formatted} coins! To confirm this match, {opponent_name} must react to ' \
                  f'this message with a :thumbsup: in the next minute. If a minute passes or if the ' \
                  f'challenger reacts to this message, the deathmatch will be cancelled and the deposit ' \
                  f'refunded.'
            msg = await ctx.send(out)
            await msg.add_reaction('\N{THUMBS UP SIGN}')

            while True:
                try:
                    reaction, user = await self.bot.wait_for('reaction_add',
                                                             timeout=60)
                    if str(reaction.emoji) == '👍' and user == opponent_member:
                        opponent_obj.update_inventory({'0': bet}, remove=True)
                        deathmatch_messages, winner = dm.do_deathmatch(
                            author, opponent_obj, bet=bet_formatted)
                        for message in deathmatch_messages[:-1]:
                            await msg.edit(content=message)
                            await asyncio.sleep(1)
                        winner.update_inventory({'0': 2 * bet})
                        return
                    elif user == ctx.author:
                        author.update_inventory({'0': bet})
                        await msg.edit(
                            content=
                            f'{author_name} has declined their challenge and '
                            f'the deposit of {bet_formatted} coins has been returned.'
                        )
                        return
                except asyncio.TimeoutError:
                    author.update_inventory({'0': bet})
                    await msg.edit(
                        content=
                        f'One minute has passed and the deathmatch has been cancelled. '
                        f'The deposit of {bet_formatted} coins has been returned.'
                    )
                    return
        else:
            try:
                opponent_member = parse_name(ctx.message.guild, opponent)
                opponent_obj = User.objects.get(id=opponent_member.id)
            except NameError:
                await ctx.send(f'{opponent} not found in server.')
                return
            except AmbiguousInputError as members:
                await ctx.send(
                    f'Input {opponent} can refer to multiple people ({members})'
                )
                return
            msg = await ctx.send(dm.DEATHMATCH_HEADER)
            deathmatch_messages, winner = dm.do_deathmatch(
                author, opponent_obj)
            for message in deathmatch_messages[:-1]:
                await msg.edit(content=message)
                await asyncio.sleep(2)
コード例 #4
0
    def __is_trade_valid(self):
        # Make sure our second user (the recipient of the items) is a real user here
        name = self.curr_trade['user2']
        for member in self.ctx.guild.members:
            if name.lower() in member.name.lower():
                self.name_member = member
                break
        else:
            raise TradeError(f'{name} not found in server.')

        # Check if either user is an Ironman
        if True in users.read_user_multi(self.curr_trade['user1'],
                                         self.name_member.id,
                                         key=users.IRONMAN_KEY):
            raise TradeError('Ironmen Cannot trade')

        # Make sure our second user (the recipient of the items) is a real user here
        name = self.curr_trade['user2']
        for member in self.ctx.guild.members:
            if name.lower() in member.name.lower():
                self.name_member = member
                break
        else:
            raise TradeError(f'{name} not found in server.')

        # Make sure they actually provided a number
        try:
            self.number = int(self.curr_trade['amount1'])
            if self.number < 0:
                raise ValueError
        except ValueError:
            raise TradeError(
                f'{self.curr_trade["amount1"]} is not a valid number.')

        # Check that the other one is a number too
        try:
            self.offer = users.parse_int(self.curr_trade['amount2'])
        except ValueError:
            raise TradeError(
                f'{self.curr_trade["amount2"]} is not a valid offer.')

        # Make sure the item is valid
        try:
            self.itemid = items.find_by_name(self.curr_trade['item1'])
        except KeyError:
            raise TradeError(
                f'{self.curr_trade["item1"]} is not a valid item.')

        # Make sure user actually has the item and quantity
        if not users.item_in_inventory(self.curr_trade['user1'], self.itemid,
                                       self.number):
            raise TradeError(
                f'You do not have {items.add_plural(self.number, self.itemid)} '
                f'in your inventory.')

        # Check that it's tradeable
        if not items.is_tradable(self.itemid):
            raise TradeError(
                f'You can not trade this item. ({items.get_attr(itemid)})')

        # Check user2 has enough coins
        if not users.item_in_inventory(self.name_member.id, "0", self.offer):
            raise TradeError(f'{get_display_name(name_member)} does not have '
                             f'enough gold to buy this many items.')

        # Check that neither user is trading
        if not self._active_traders.isdisjoint(
            {self.curr_trade['user1'], self.name_member.id}):
            raise TradeError(
                "Each user can only have one active trade at a time")

        # Check that the user isn't him/herself
        if self.curr_trade['user1'] == self.name_member.id:
            raise TradeError("You cannot trade with yourself.")

        return True