Search code examples
pythondiscorddiscord.py

Conditional role-giving in discord.py


I'm new to Python. I'm coding a mini-game for a Discord server. I want to make a command that changes the role of members depending on their role, and sends the message "You cannot kill {mention}, he is immortal.", if the argument mentions a player who does not have one of the roles: "3 lives", "2 life", 1 life", or "dead". I tried using a list and a "not in" operator:

elif role.name not in ['3 lives', '2 lives', '1 life', 'Dead']:
        await ctx.send("You can't kill {}, he/she is immortal".format(victim.mention))
        break

But the function was called even when the victim didn't have those roles. Here is my code:

# $kill command
@client.command(name = 'kill')
@commands.has_any_role('3 lives', '2 lives', '1 life')
@commands.cooldown(1, 57600, commands.BucketType.user)
async def kill(ctx, victim: discord.Member):
    for role in victim.roles:
        #if you try to kill yourself 
        if victim == ctx.message.author: 
            await ctx.reply("You can't kill yourself.")
            kill.reset_cooldown(ctx)
            break

        #if you try to kill dead
        elif role.name == 'Dead': 
            await ctx.reply("You can't kill {}, this user is already dead.".format(victim.mention))
            kill.reset_cooldown(ctx)
            break
        
        else:
            #makes people have 2 lives
            if role.name == '3 lives': 
                newrole = discord.utils.get(victim.guild.roles, name='2 lives')
                await victim.add_roles(newrole)                    
                await victim.remove_roles(role)
                await ctx.reply("You attacked {}, now this user has 2 lives.".format(victim.mention))
                break

            #makes people have 1 life
            elif role.name == '2 lives': 
                newrole = discord.utils.get(victim.guild.roles, name='1 life')
                await victim.add_roles(newrole)
                await victim.remove_roles(role)
                await ctx.reply("You attacked {}, now this user has 1 life".format(victim.mention))
                break

            #makes people dead
            elif role.name == '1 life': 
                newrole = discord.utils.get(victim.guild.roles, name='Dead')
                await victim.add_roles(newrole)
                await victim.remove_roles(role)
                await ctx.reply("You attacked {}, now this user is dead.".format(victim.mention))
                break

Update 1: The condition that should notify about the impossibility of killing a member who does not have the roles "3 life", "2 life", "1 life" or "Dead" was always true, since it checked for the presence of other roles that do not belong to the list of available for killing , including @everyone.


Solution

  • Fixed it, it definitely works.

    check1 = discord.utils.get(victim.roles, name = '3 lives')
    check2 = discord.utils.get(victim.roles, name = '2 lives')
    check3 = discord.utils.get(victim.roles, name = '1 lives')
    check4 = discord.utils.get(victim.roles, name = 'Dead')
    check_all = [check1, check2, check3, check4]
    
    #if you try to kill immortal
    elif not any(check_all):
        await ctx.reply("You can't kill {}, this user is immortal.".format(victim.mention))
        attack.reset_cooldown(ctx)
        break