Ejemplo n.º 1
0
    async def copulate(self, ctx:utils.Context, user:discord.Member):
        """Lets you... um... heck someone"""

        # Check for the most common catches
        text_processor = utils.random_text.RandomText('copulate', ctx.author, user)
        text = text_processor.process(check_for_instigator=False)
        if text:
            return await ctx.send(text)

        # Check if they are related
        x = utils.FamilyTreeMember.get(ctx.author.id, ctx.family_guild_id)
        y = utils.FamilyTreeMember.get(user.id, ctx.family_guild_id)
        async with ctx.channel.typing():
            relationship = x.get_relation(y)
        if relationship is None or relationship.casefold() == 'partner' or self.bot.allows_incest(ctx.guild.id):
            pass
        else:
            return await ctx.send(text_processor.target_is_family())

        # Ping out a message for them
        await ctx.send(text_processor.valid_target())

        # Wait for a response
        try:
            check = utils.AcceptanceCheck(user.id, ctx.channel.id).check
            m = await self.bot.wait_for('message', check=check, timeout=60.0)
            response = check(m)
        except asyncio.TimeoutError:
            return await ctx.send(text_processor.request_timeout(), ignore_error=True)

        # Process response
        if response == "NO":
            return await ctx.send(text_processor.request_denied())
        await ctx.send(text_processor.request_accepted())
Ejemplo n.º 2
0
    async def propose(self, ctx: utils.Context, *,
                      target: utils.converters.UnblockedMember):
        """Lets you propose to another Discord user"""

        # Variables we're gonna need for later
        instigator = ctx.author
        instigator_tree = utils.FamilyTreeMember.get(instigator.id,
                                                     ctx.family_guild_id)
        target_tree = utils.FamilyTreeMember.get(target.id,
                                                 ctx.family_guild_id)

        # Manage output strings
        text_processor = utils.random_text.RandomText('propose', instigator,
                                                      target)
        text = text_processor.process()
        if text:
            return await ctx.send(text)

        # See if our user is already married
        if instigator_tree._partner:
            return await ctx.send(text_processor.instigator_is_unqualified())

        # See if the *target* is already married
        if target_tree._partner:
            return await ctx.send(text_processor.target_is_unqualified())

        # See if they're already related
        async with ctx.channel.typing():
            relation = instigator_tree.get_relation(target_tree)
        if relation and not self.bot.allows_incest(ctx.guild.id):
            return await ctx.send(text_processor.target_is_family())

        # Check the size of their trees
        max_family_members = self.bot.guild_settings[
            ctx.guild.id]['max_family_members']
        async with ctx.channel.typing():
            if instigator_tree.family_member_count + target_tree.family_member_count > max_family_members:
                return await ctx.send(
                    f"If you added {target.mention} to your family, you'd have over {max_family_members} in your family, so I can't allow you to do that. Sorry!"
                )

        # Neither are married, set up the proposal
        await ctx.send(text_processor.valid_target())
        await self.bot.proposal_cache.add(instigator, target, 'MARRIAGE')

        # Wait for a response
        check = utils.AcceptanceCheck(target.id, ctx.channel.id)
        try:
            await check.wait_for_response(self.bot)
        except utils.AcceptanceCheck.TIMEOUT:
            return await ctx.send(text_processor.request_timeout(),
                                  ignore_error=True)

        # They said no
        if check.response == 'NO':
            await self.bot.proposal_cache.remove(instigator, target)
            return await ctx.send(text_processor.request_denied(),
                                  ignore_error=True)

        # They said yes!
        async with self.bot.database() as db:
            await db.marry(instigator, target, ctx.family_guild_id)
        await ctx.send(text_processor.request_accepted(), ignore_error=True)

        # Cache values locally
        instigator_tree._partner = target.id
        target_tree._partner = instigator.id

        # Ping em off over redis
        async with self.bot.redis() as re:
            await re.publish_json('TreeMemberUpdate',
                                  instigator_tree.to_json())
            await re.publish_json('TreeMemberUpdate', target_tree.to_json())

        # Remove users from proposal cache
        await self.bot.proposal_cache.remove(instigator, target)
Ejemplo n.º 3
0
    async def makeparent(self, ctx: utils.Context, *,
                         target: utils.converters.UnblockedMember):
        """Picks a user that you want to be your parent"""

        # Variables we're gonna need for later
        instigator = ctx.author
        instigator_tree = utils.FamilyTreeMember.get(instigator.id,
                                                     ctx.family_guild_id)
        target_tree = utils.FamilyTreeMember.get(target.id,
                                                 ctx.family_guild_id)

        # Manage output strings
        text_processor = utils.random_text.RandomText('makeparent', instigator,
                                                      target)
        text = text_processor.process()
        if text:
            return await ctx.send(text)

        # See if our user already has a parent
        if instigator_tree._parent:
            return await ctx.send(text_processor.instigator_is_unqualified())

        # See if they're already related
        async with ctx.channel.typing():
            relation = instigator_tree.get_relation(target_tree)
        if relation and not self.bot.allows_incest(ctx.guild.id):
            return await ctx.send(text_processor.target_is_family())

        # Manage children
        if ctx.original_author_id not in self.bot.owner_ids:
            children_amount = await self.get_max_children_for_member(
                ctx.guild, target)
            if len(target_tree._children) >= children_amount:
                return await ctx.send(
                    "They're currently at the maximum amount of children you can have - see `m!perks` for more information."
                )

        # Check the size of their trees
        if ctx.original_author_id not in self.bot.owner_ids:
            max_family_members = self.bot.get_max_family_members(ctx.guild)
            async with ctx.channel.typing():
                if instigator_tree.family_member_count + target_tree.family_member_count > max_family_members:
                    return await ctx.send(
                        f"If you added {target.mention} to your family, you'd have over {max_family_members} in your family, so I can't allow you to do that. Sorry!"
                    )

        # Valid request - ask the other person
        if not target.bot:
            await ctx.send(text_processor.valid_target())
        await self.bot.proposal_cache.add(instigator, target, 'MAKEPARENT')
        check = utils.AcceptanceCheck(target.id, ctx.channel.id)
        try:
            await check.wait_for_response(self.bot)
        except utils.AcceptanceCheck.TIMEOUT:
            return await ctx.send(text_processor.request_timeout(),
                                  ignore_error=True)

        # They said no
        if check.response == 'NO':
            await self.bot.proposal_cache.remove()
            return await ctx.send(text_processor.request_denied(),
                                  ignore_error=True)

        # They said yes
        async with self.bot.database() as db:
            try:
                await db(
                    'INSERT INTO parents (child_id, parent_id, guild_id, timestamp) VALUES ($1, $2, $3, $4)',
                    instigator.id, target.id, ctx.family_guild_id, dt.utcnow())
            except asyncpg.UniqueViolationError:
                return await ctx.send(
                    "I ran into an error saving your family data - please try again later."
                )
        await ctx.send(text_processor.request_accepted(), ignore_error=True)

        # Cache
        instigator_tree._parent = target.id
        target_tree._children.append(instigator.id)

        # Ping em off over redis
        async with self.bot.redis() as re:
            await re.publish_json('TreeMemberUpdate',
                                  instigator_tree.to_json())
            await re.publish_json('TreeMemberUpdate', target_tree.to_json())

        # Uncache
        await self.bot.proposal_cache.remove(instigator, target)
Ejemplo n.º 4
0
    async def adopt(self, ctx: utils.Context, *,
                    target: utils.converters.UnblockedMember):
        """Adopt another user into your family"""

        # Variables we're gonna need for later
        instigator = ctx.author
        instigator_tree = utils.FamilyTreeMember.get(instigator.id,
                                                     ctx.family_guild_id)
        target_tree = utils.FamilyTreeMember.get(target.id,
                                                 ctx.family_guild_id)

        # Manage output strings
        text_processor = utils.random_text.RandomText('adopt', instigator,
                                                      target)
        text = text_processor.process()
        if text:
            return await ctx.send(text)

        # See if our user already has a parent
        if target_tree._parent:
            return await ctx.send(text_processor.target_is_unqualified())

        # See if the target is a bot
        if target.bot:
            return await ctx.send(text_processor.target_is_bot())

        # See if they're already related
        async with ctx.channel.typing():
            relation = instigator_tree.get_relation(target_tree)
        if relation and not self.bot.allows_incest(ctx.guild.id):
            return await ctx.send(text_processor.target_is_family())

        # Manage children
        if self.bot.is_server_specific:
            guild_max_children = self.bot.guild_settings[
                ctx.guild.id]['max_children']
            if guild_max_children:
                gold_children_amount = max([
                    amount if int(role_id) in ctx.author._roles else 0
                    for role_id, amount in guild_max_children.items()
                ])
            else:
                gold_children_amount = 0
        else:
            gold_children_amount = 0
        normal_children_amount = self.bot.config['max_children'][
            await utils.checks.get_patreon_tier(self.bot, ctx.author)]
        children_amount = min([
            max([
                gold_children_amount, normal_children_amount,
                self.bot.config['max_children'][0]
            ]), self.bot.config['max_children'][-1]
        ])
        if len(instigator_tree._children) >= children_amount:
            return await ctx.send(
                f"You're currently at the maximum amount of children you can have - see `m!perks` for more information."
            )

        # Check the size of their trees
        max_family_members = self.bot.guild_settings[
            ctx.guild.id]['max_family_members']
        async with ctx.channel.typing():
            if instigator_tree.family_member_count + target_tree.family_member_count > max_family_members:
                return await ctx.send(
                    f"If you added {target.mention} to your family, you'd have over {max_family_members} in your family, so I can't allow you to do that. Sorry!"
                )

        # No parent, send request
        await ctx.send(text_processor.valid_target())
        await self.bot.proposal_cache.add(instigator, target, 'ADOPT')

        # Wait for a response
        check = utils.AcceptanceCheck(target.id, ctx.channel.id)
        try:
            await check.wait_for_response(self.bot)
        except utils.AcceptanceCheck.TIMEOUT:
            return await ctx.send(text_processor.request_timeout(),
                                  ignore_error=True)

        # Valid response recieved, see what their answer was
        if check.response == 'NO':
            await self.bot.proposal_cache.remove(instigator, target)
            return await ctx.send(text_processor.request_denied(),
                                  ignore_error=True)

        # Database it up
        async with self.bot.database() as db:
            await db(
                'INSERT INTO parents (parent_id, child_id, guild_id, timestamp) VALUES ($1, $2, $3, $4)',
                instigator.id, target.id, ctx.family_guild_id, dt.utcnow())

        # Add family caching
        instigator_tree._children.append(target.id)
        target_tree._parent = instigator_tree.id

        # Ping em off over redis
        async with self.bot.redis() as re:
            await re.publish_json('TreeMemberUpdate',
                                  instigator_tree.to_json())
            await re.publish_json('TreeMemberUpdate', target_tree.to_json())

        # Uncache
        await self.bot.proposal_cache.remove(instigator, target)

        # Output to user
        await ctx.send(text_processor.request_accepted(), ignore_error=True)