def unfreeze(user_id,victim_id):
    """This function allows the innkeeper to unfreeze frozen victims.
    The function assumes both players are participants, of which the casting user is an innkeeper. Make sure to have filtered this out already.
    The other user does not need to be frozen.
    The function returns a Mailbox.

    Keyword arguments:
    user_id -> the innkeeper who unfrozes a player
    victim_id -> the frozen player who is about to be unfrozen"""

    uses = int(db_get(user_id,'uses'))
    if uses < 1:
        return Mailbox().respond("I am sorry! You currently don't have the ability to unfreeze anyone!",True)

    user_channel = int(db_get(user_id,'channel'))
    user_undead = int(db_get(user_id,'undead'))

    victim_frozen = int(db_get(victim_id,'frozen'))
    victim_abducted = int(db_get(victim_id,'abducted'))

    if user_undead == 1:
        return Mailbox().msg("I'm sorry! You are undead, meaning that you can no longer unfreeze people!",user_channel,True)
    if victim_abducted == 1:
        return Mailbox().msg("You wanted to warm up <@{}>... but you weren't able to find them! That is strange...",user_channel,True)
    if victim_frozen == 0:
        return Mailbox().msg("This player isn't frozen! Please choose another target.",user_channel,True)

    db_set(user_id,'uses',uses - 1)
    db_set(victim_id,'frozen',0)

    answer = Mailbox().msg("You have successfully unfrozen <@{}>!".format(victim_id),user_channel)
    answer.unfreeze(victim_id)

    answer.dm("Great news, <@{}>! You have been unfrozen by an **Innkeeper**! You can now take part with the town again!".format(victim_id),victim_id)
    return answer.log("The **Innkeeper** <@{}> has unfrozen <@{}>.".format(user_id,victim_id))
def aura(user_id,victim_id):
    """This function allows the aura teller to inspect if a given user is among the wolf pack or not.
    The function assumes the player is an aura teller and has the correct role, so make sure to have filtered this out already.
    The function returns a Mailbox.

    user_id -> the player who casts the spell
    victim_id -> the player who is being searched"""

    uses = int(db_get(user_id,'uses'))
    if uses < 1:
        return Mailbox().respond("I am sorry! You currently don't have the ability to see this player!",True)

    victim_role = db_get(victim_id,"role")
    victim_frozen = int(db_get(victim_id,'frozen'))
    victim_abducted = int(db_get(victim_id,'abducted'))

    user_channel = int(db_get(user_id,"channel"))
    user_undead = int(db_get(user_id,'undead'))

    if user_undead == 1:
        return Mailbox().dm("You are undead! This means that you can no longer inspect players. I\'m sorry!",user_id)
    if victim_abducted == 1:
        return Mailbox().msg("You tried to inspect <@{}>... but their aura seemed empty! Almost as if they weren't there!\nYou decided to inspect someone else.",user_channel,True)
    if victim_frozen == 1:
        return Mailbox().msg("You have tried to inspect <@{}>, but it turns out you couldn\'t see their aura all the way through the ice! Luckily, you had the opportunity to try again.",user_channel,True)

    db_set(user_id,'uses',uses - 1)

    if victim_role in wolf_pack:
        answer = Mailbox().msg("🐺 - <@{}> has a **RED AURA** - they are taking part in the wolf pack!".format(victim_id),user_channel)
        return answer.log("The **Aura Teller** <@{}> has inspected the **{}** <@{}>, and found out they were part of the wolf pack!".format(user_id,victim_role,victim_id))

    answer = Mailbox().msg("🐶 - <@{}> has a **GREEN AURA** - they are not taking part in the wolf pack.".format(victim_id),user_channel)
    return answer.log("The **Aura Teller** <@{}> has inspected <@{}>, who, being the **{}**, wasn't part of the wolf pack.".format(user_id,victim_id,victim_role))
Example #3
0
def dog_follow(user_id,role):
    """This function allows the dog to choose a role to become.
    The function assumes the player is a cupid and has provided a role, so make sure to have filtered this out already.
    The role does not need to be Innocent, Cursed Civilian or Werewolf yet.
    The function returns a Mailbox.

    user_id -> the dog who chooses a role
    role -> the role they'd like to be"""

    uses = int(db_get(user_id,'uses'))
    if uses < 1:
        return Mailbox().respond("I am sorry! You currently cannot choose a role to become!",True)

    user_channel = int(db_get(user_id,'channel'))

    if role not in ['Innocent', 'Cursed Civilian', 'Werewolf']:
        return Mailbox().msg("I'm sorry, <{}>. Being a dog lets you choose a role, but it doesn't mean you can become ANYTHING.".format(user_id),user_channel,True)

    db_set(user_id,'uses',uses - 1)

    answer = Mailbox().msg("You have chosen to become the **{}**!".format(role),user_channel)
    answer.log("The **Dog** <@{}> has chosen to become a")

    if role == 'Innocent':
        answer.log_add('n **Innocent**!').dm("You have chosen to become an **Innocent**. Protect the town, kill all those wolves!",user_id)
    if role == 'Cursed Civilian':
        answer.log_add(' **Cursed Civilian**!').dm("You have chosen to become a **Cursed Civilian**! You will be part of the town... for now.",user_id)
    if role == 'Werewolf':
        answer.log_add(' **Werewolf**!').dm("You have chosen to become a **Werewolf**! You will now join the wolf pack!",user_channel)
        # TODO: Add dog to wolf channel

    db_set(user_id,'role',role)
    return answer
def nightly_kill(user_id,victim_id):
    """This function adds a kill to the kill queue based on the user's role.  
    This function is applicable for roles like the assassin, the lone wolf, the priest, the thing and the white werewolf.  
    NOTICE: This function is meant for people who kill solo! Teams should receive a poll.
    Evaluating whether the kill should actually be applied isn't needed, as this is evaluated at the start of the day.
    The function assumes the player is a participant and has the correct role, so make sure to have filtered this out already.  
    The function returns a Mailbox.

    user_id -> the player who will initiate the attack
    victim_id -> the player who shall be \"attacked\""""

    uses = int(db_get(user_id,'uses'))
    if uses < 1:
        return Mailbox().respond("I am sorry! You currently don't have this ability available!",True)

    if user_id == victim_id:
        return Mailbox().respond("I am sorry, but you cannot attempt suicide!\nNot because it's not an option, no, just because we want to see you SUFFER!",True)

    # TODO: Prevent targeting of abducted/frozen players.
    if int(db_get(user_id,'undead')) == 1 or db_get(user_id,'role') == 'Undead':
        return Mailbox().respond("I am sorry! Now that you are Undead, you can no longer use this power.",True)
    if int(db_get(victim_id,'abducted')) == 1:
        return Mailbox().respond("You attempted to attack <@{}>... but they don't seem to be around in town! That is strange.".format(victim_id),True)
    if int(db_get(user_id,'frozen')) == 1:
        return Mailbox().respond("You wanted to pay a visit to <@{}>... but it seems they were frozen! Try again, please.".format(victim_id),True)

    user_role = db_get(user_id,'role')
    user_channel = int(db_get(user_id,'channel'))

    db_set(user_id,'uses',uses - 1)
    db.add_kill(victim_id,user_role,user_id)

    answer = Mailbox().msg(ctory.kill_acceptance(victim_id),user_channel)
    return answer.log("The **{}** <@{}> has chosen to pay <@{}> a visit tonight.".format(user_role,user_id,victim_id))
def ignite(user_id):
    """This function ignites all powdered players that aren't pyromancer.
    The function assumes the player is a participant and has the correct role, so make sure to have filtered this out already.
    The function returns a Mailbox.

    user_id -> the player who ignites all powdered players"""

    uses = int(db_get(user_id,'uses'))
    if uses < 1:
        return Mailbox().respond("I am sorry! You currently cannot ignite anyone!",True)
    db_set(user_id,'uses',uses - 1)

    user_role = db_get(user_id,'role')
    user_channel = db_get(user_id,'channel')
    user_undead = int(db_get(user_id,'undead'))

    if user_undead == 1:
        answer = Mailbox().log("<@{}>, an undead **{}**, has pretended to ignite all powdered players.".format(user_id,user_role))
        answer.dm("Hey, you are undead, so your power won\'t work. But at least this won\'t blow your cover!",user_id)
        return answer.msg("Okay! All powdered players will die tomorrow.",user_channel)

    # Ignite all living players.
    for user in db.player_list(True,True):
        if db.isParticipant(user) and db_get(user,'role') != 'Pyromancer':
            db.add_kill(int(user),'Pyromancer',user_id)

    answer = Mailbox().log("The **{}** <@{}> has ignited all powdered players!".format(user_role,user_id))
    return answer.msg("Okay! All powdered players will die tomorrow.",user_channel)
Example #6
0
def disguise(user_id,victim_id,role):
    """This fuction is taking the tanner's action of disguising people.
    The function assumes the player is a participant and has the correct role, so make sure to have filtered this out already.  
    The function returns a Mailbox.  

    user_id -> the player who casts the spell
    victim_id -> the player upon whom the spell is cast
    role -> the role the player should be disguised as"""

    uses = int(db_get(user_id,'uses'))
    if uses < 1:
        return Mailbox().respond("I am sorry! You currently don't have the ability to disguise anyone!",True)
    db_set(user_id,'uses',uses - 1)

    user_channel = int(db_get(user_id,'channel'))
    user_role = db_get(user_id,'role')
    victim_role = db_get(user_id,'role')

    db_set(victim_id,'fakerole',role)
    answer = Mailbox().msg("You have successfully disguised <@{}> as the **{}**!".format(victim_id,role),user_channel)
    
    if uses - 1 > 0:
        answer.msg("You can disguise **{}** more players!".format(uses-1),user_channel,True)
    else:
        answer.msg("That\'s it for today! You can\'t disguise any more players.",user_channel,True)
    
    return answer.log("**{}** <@{}> has disguised <@{}>, the **{}**, as the **{}**!".format(user_role,user_id,victim_id,victim_role,role))
Example #7
0
def instant_death(user_id,
                  role,
                  deathType,
                  answer=Mailbox().log(''),
                  recursive=''):
    """Eliminate the given user."""

    # If the user was reporter or mayor, get rid of that.
    if dy.get_mayor() == user_id:
        dy.kill_mayor()
        answer.remove_proms(user_id)
    if dy.get_reporter() == user_id:
        dy.kill_reporter()
        answer.remove_proms(user_id)

    for channel_id in db.get_secret_channels("Graveyard"):
        answer.edit_cc(channel_id, user_id, 1)

    # Change all channel settings
    for channel_id in db.channel_change_all(user_id, 1, 4):
        answer.edit_cc(channel_id, user_id, 4)
    for channel_id in db.channel_change_all(user_id, 2, 4):
        answer.edit_cc(channel_id, user_id, 4)
    for channel_id in db.channel_change_all(user_id, 5, 4):
        answer.edit_cc(channel_id, user_id, 4)

    # Change abducted settings
    for channel_id in db.channel_change_all(user_id, 3, 7):
        answer.edit_cc(channel_id, user_id, 7)
    for channel_id in db.channel_change_all(user_id, 6, 7):
        answer.edit_cc(channel_id, user_id, 7)

    for channel_id in db.get_secret_channels("Market"):
        answer.edit_cc(channel_id, user_id, 4)

    for channel_id in db.get_secret_channels("Reporter"):
        if int(db_get(user_id, 'undead')) == 1:
            answer.msg(
                "{} - <@{}> had the role of the `Undead`!".format(
                    db_get(user_id, 'emoji'), user_id), channel_id)
        else:
            answer.msg(
                "{} - <@{}> had the role of the `{}`!".format(
                    db_get(user_id, 'emoji'), user_id,
                    db_get(user_id, 'role')), channel_id)

    # Kill that user already!
    db_set(user_id, 'role', 'Dead')
    db_set(user_id, 'fakerole', 'Dead')

    answer.spam(unip + 'kill <@{}>'.format(user_id))

    if int(db_get(user_id, 'abducted')) != 1 and role not in ["Barber"]:
        db.insert_deadie(user_id, deathType)

    # Kill all standoffs
    for taker in db.get_standoff(user_id):
        answer = attack(taker[1], taker[2], taker[3], answer, recursive)

    return answer
Example #8
0
def disguise(user_id, victim_id, role):
    """This fuction is taking the tanner's action of disguising people.
    The function assumes the player is a participant and has the correct role, so make sure to have filtered this out already.
    The function returns a Mailbox.

    user_id -> the player who casts the spell
    victim_id -> the player upon whom the spell is cast
    role -> the role the player should be disguised as"""

    uses = int(db_get(user_id, 'uses'))
    if uses < 1:
        return Mailbox().respond(
            "I am sorry! You currently don't have the ability to disguise anyone!",
            True)

    user_channel = int(db_get(user_id, 'channel'))
    user_role = db_get(user_id, 'role')
    user_undead = int(db_get(user_id, 'undead'))

    victim_role = db_get(victim_id, 'role')
    victim_frozen = int(db_get(victim_id, 'frozen'))
    victim_abducted = int(db_get(victim_id, 'abducted'))

    if user_undead == 1:
        return Mailbox().dm(
            "I am sorry! You are undead, meaning you can no longer disguise people!",
            user_id, True)
    if victim_abducted == 1:
        return Mailbox().msg(
            "After having finished your great disguise, it seems like you couldn\'t find your target! Where have they gone off to?",
            user_channel, True)
    if victim_frozen == 1:
        return Mailbox().msg(
            "I am sorry, but <@{}> is too cold for that! You\'ll need a lot more than warm suit to get \'em warmed up."
            .format(victim_id), user_channel, True)

    db_set(user_id, 'uses', uses - 1)

    db_set(victim_id, 'fakerole', role)
    answer = Mailbox().msg(
        "You have successfully disguised <@{}> as the **{}**!".format(
            victim_id, role), user_channel)

    if uses - 1 > 0:
        answer.msg("You can disguise **{}** more players!".format(uses - 1),
                   user_channel, True)
    else:
        answer.msg(
            "That\'s it for today! You can\'t disguise any more players.",
            user_channel, True)

    answer.log(
        "**{}** <@{}> has disguised <@{}>, the **{}**, as the **{}**!".format(
            user_role, user_id, victim_id, victim_role, role))
    if victim_role == role:
        answer.log_add(
            "\n...does that sound stupid? *Of course!* But how are they supposed to know?"
        )
    return answer
Example #9
0
def powder(user_id, victim_id):
    """This function powders a player if they are alive and not a pyromancer.
    The function assumes the player is a participant and has the correct role, so make sure to have filtered this out already.
    The function returns a Mailbox.

    user_id -> the player who powders the victim
    victim_id -> the player who is powdered"""

    uses = int(db_get(user_id, 'uses'))
    if uses < 1:
        return Mailbox().respond(
            "I am sorry! You currently cannot powder anyone!", True)

    user_role = db_get(user_id, 'role')
    user_channel = db_get(user_id, 'channel')
    user_undead = int(db_get(user_id, 'undead'))

    victim_role = db_get(victim_id, 'role')
    victim_powdered = int(db_get(victim_id, 'powdered'))
    victim_frozen = int(db_get(victim_id, 'frozen'))
    victim_abducted = int(db_get(victim_id, 'abducted'))

    if victim_id == user_id:
        return Mailbox().respond("I'm sorry, bud, you can't powder yourself.")
    if victim_abducted == 1:
        return Mailbox().msg(
            "You have attempted to powder <@{}>... but you cannot find them! Have they left the town?"
            .format(victim_id), user_channel, True)
    if victim_frozen == 1:
        return Mailbox().msg(
            "You tried to powder <@{}>... but it's not so easy to powder an ice cube! Let's try someone else."
            .format(victim_id), user_channel, True)
    if victim_role == 'Pyromancer':
        return Mailbox().msg(
            "I am sorry, <@{}>, but you cannot powder a pyromancer!".format(
                user_id), user_channel, True)
    if victim_powdered == 1:
        return Mailbox().msg(
            "I am terribly sorry, but <@{}> has already been powdered! Please choose another victim."
            .format(victim_id), user_channel, True)

    db_set(user_id, 'uses', uses - 1)

    # Powder the player
    answer = Mailbox().msg(
        "You have successfully powdered <@{}>!".format(victim_id),
        user_channel)
    if user_undead == 1:
        answer.log("<@{}>, an undead, has pretended to powder <@{}>.".format(
            user_id, victim_id))
        return answer.dm(
            "Hey, you are undead, so your powers no longer work... but here\'s a little help to keep up your cover!",
            user_id)

    db_set(victim_id, 'powdered', 1)
    return answer.log("The **{}** <@{}> has powdered the **{}** <@{}>!".format(
        user_role, user_id, victim_role, victim_id))
Example #10
0
def freeze_all(user_id):
    """This function allows the ice king to potentially freeze all their guessed players.
    The function assumes the ice king is a participant, so make sure to have filtered this out already.
    The function returns a Mailbox.

    Keyword arguments:
    user_id -> the ice king's id"""

    uses = int(db_get(user_id,'uses'))
    if uses < 1:
        return Mailbox().respond("I am sorry! You currently don't have the ability to submit a freezing list!",True)
    db_set(user_id,'uses',uses - 1)

    user_channel = int(db_get(user_id,'channel'))
    user_undead = int(db_get(user_id,'undead'))
    correct = 0
    incorrect = 0

    for frozone in db.get_freezers(user_id):
        if not db.isParticipant(frozone[0]) or int(db_get(frozone[0],'abducted')) == 1:
            db.delete_freezer(user_id,frozone[0])
        elif frozone[1] != db_get(frozone[0],'role'):
            incorrect += 1
        else:
            correct += 1

    if user_undead == 1:
        answer = Mailbox().msg("You have submitted a list that contains {} players. The result was **unsuccessful**. ".format(correct+incorrect),user_channel)
        answer.msg_add("This means that at least one role was incorrect!")
        answer.log("The **Undead** <@{}> has pretended to submit a freeze list.".format(user_id))
        answer.dm("Hey, you're **Undead**, so this list would've failed anyway - but this helps a little to keep up your cover! 😉",user_id)
        return answer

    if incorrect > 0:
        answer = Mailbox().msg("You have submitted a list that contains {} players. The result was **unsuccessful**. ".format(correct+incorrect),user_channel)
        answer.msg_add("This means that at least one role was incorrect!")
        answer.log("The **Ice King** <@{}> has submitted an **unsuccessful** freeze list. ".format(user_id))
        answer.log_add("The list contained {} guesses, of which {} were correct.".format(incorrect+correct,correct))
        return answer

    # This will execute if all users on the list are correct.
    answer = Mailbox().msg("You have submitted a list that contains {} players. The result was **successful**!\n".format(correct),user_channel)
    if correct > 4:
        answer.msg_add("Congratulations! You guessed them all correctly! ").msg_react('🎉')
    answer.msg_add("Your guessed users will now be frozen.")


    for supersuit in db.get_freezers(user_id):
        db_set(supersuit[0],'frozen',1)
        db.delete_freezer(user_id,supersuit[0])

        for channel_id in db.freeze(user_id):
            answer.edit_cc(channel_id,supersuit[0],2)

    # TODO: Give players access to frozen realm.

    return answer
Example #11
0
def add_activity(user_id,user_name):
    """Increase the activity score of a player."""
    c.execute("SELECT * FROM 'activity' WHERE id =?",(user_id,))
    if c.fetchone() == None:
        c.execute("INSERT INTO 'inventory'('id','name') VALUES (?,?);",(user_id,user_name))
        c.execute("INSERT INTO 'activity'('id','name') VALUES (?,?);",(user_id,user_name))
        c.execute("INSERT INTO 'users'('id','name') VALUES (?,?);",(user_id,user_name))
    c.execute("UPDATE 'activity' SET spam_activity = spam_activity + 1 WHERE id =?",(user_id,))
    conn.commit()
    db_set(user_id,'name',user_name)
Example #12
0
def see(user_id,victim_id):
    """This function allows the user to see a given player of their choice.
    The function assumes the player is a participant and has the correct role, so make sure to have filtered this out already.
    The function returns a Mailbox.

    user_id -> the player who casts the spell
    victim_id -> the player who is being searched"""

    uses = int(db_get(user_id,'uses'))
    if uses < 1:
        return Mailbox().respond("I am sorry! You currently don't have the ability to see this player!",True)

    victim_emoji = db_get(victim_id,"emoji")
    victim_fakerole = db_get(victim_id,"fakerole")
    victim_role = db_get(victim_id,"role")
    victim_frozen = int(db_get(victim_id,'frozen'))
    victim_abducted = int(db_get(user_id,'abducted'))

    user_channel = int(db_get(user_id,"channel"))
    user_undead = int(db_get(user_id,'undead'))
    user_role = db_get(user_id,"role")

    if user_undead == 1:
        return Mailbox().dm("You are undead! This means that you can no longer inspect players. I\'m sorry!",user_id)
    if victim_abducted == 1:
        return Mailbox().msg("You tried to see <@{}>... but you couldn\'t find them! Almost as if they had disappeared in thin air!\nWhat happened?",user_channel,True)
    if victim_frozen == 1:
        return Mailbox().msg("You have tried to inspect <@{}>, but it turns out you couldn\'t reach them through the ice! Luckily, you had the opportunity to try again.",user_channel,True)

    db_set(user_id,'uses',uses - 1)

    # Follow this procedure if the user has been enchanted.
    # It ensures there is a 40% chance they get their guess wrong.
    if int(db_get(user_id,"enchanted")) == 1 and random.random() < 0.6:
        answer = Mailbox().msg("*NOTE: You are enchanted, your result has a 40% chance of showing as the Flute player*\n{} - <@{}> has the role of the `Flute Player`!".format(victim_emoji,victim_id),user_channel)
        answer.log("<@{0}> has attempted to see the role of <@{1}>. However, being enchanted made <@{1}> show as the **Flute Player!**".format(user_id,victim_id))

        # Easter egg
        if victim_role == "Flute Player":
            answer.log("<@{}> has seen the role of <@{}> (**Flute Player**) due to their enchantment effects. But hey! They don't need to know they actually *are* a **Flute Player**!. 😉".format(user_id, victim_id))

        return answer

    # TODO: Add undead thing.

    elif int(db_get(user_id,"enchanted")) == 1:
        answer = Mailbox().msg("*NOTE: You are enchanted, your result has a 40% chance of showing as the Flute player*\n{} - <@{}> has the role of the `{}`!".format(victim_emoji,victim_id,victim_fakerole),user_channel)
    else:
        answer = Mailbox().msg("{} - <@{}> has the role of the `{}`!".format(victim_emoji,victim_id,victim_fakerole),user_channel)

    if victim_fakerole != victim_role:
        answer.log("<@{}>, the town's **{}**, has attempted to see <@{}>, the **{}**. ".format(user_id,user_role,victim_id,victim_role))
        return answer.log_add("However, they were disguised and appeared to be the **{}**!".format(victim_fakerole))

    return answer.log("<@{}>, a **{}**, has seen the role of <@{}>, who had the role of the **{}**!".format(user_id,user_role,victim_id,victim_role))
Example #13
0
def night():
    """Start the second part of the day.  
    The function assumes all polls have been evaluated, and that looking after attacks can begin.  
    The function returns a Mailbox."""
    threat = db.get_kill()
    answer = Mailbox().log("**Results from daily deaths:**")

    if dy.get_stage() == "Night":
        return Mailbox().respond("Sure, man. Whatever.")

    while threat != None:

        answer = roles.attack(threat[1],threat[2],threat[3],answer)
        threat = db.get_kill()

    for player in db.player_list(True):
        # Give potential night uses
        user_role = db_get(player,'role')
        for i in range(len(roles.night_users)):
            if user_role in roles.night_users[i]:
                # Give one-time users their one-time power
                if i == 0:
                    if dy.day_number() == 0:
                        db_set(player,'uses',1)
                    break

                if user_role in ['White Werewolf'] and dy.day_number() % 2 == 0:
                    i = 1

                db_set(player,'uses',i)
                answer.msg(power.power(user_role),db_get(player,'channel'))
                break

    answer.story(evening.evening(db.get_deadies()))
    db.delete_deadies()

    # Add polls
    for player in db.player_list():
        if db_get(player,'role') in pos.wolf_pack:
            for channel_id in db.get_secret_channels('Werewolf'):
                answer.new_poll(channel_id,'wolf',db.random_wolf(),story_text('wolf'))
            break
    for player in db.player_list():
        if db_get(player,'role') == 'Cult Leader':
            for channel_id in db.get_secret_channels('Cult_Leader'):
                answer.new_poll(channel_id,'cult',db.random_cult(),story_text('cult'))
            break
    for channel_id in db.get_secret_channels('Swamp'):
        answer.new_poll(channel_id,'thing','',story_text('thing'))

    answer.log("```Night {}```".format(dy.day_number()))
    dy.set_stage("Night")

    return answer
Example #14
0
    def freeze(self, user_id):
        """Freeze a user.  
        This function alters the Mailbox, so 'add' and react commands may not work as intended."""
        db_set(user_id, 'frozen', 1)
        self.spam("<@{}> was frozen.".format(user_id))
        to_freeze = channel_change_all(user_id, 1, 2)

        for channel_id in get_secret_channels('Frozen_Realm'):
            self.edit_cc(channel_id, user_id, 1)
        for channel_id in to_freeze:
            self.edit_cc(channel_id, user_id, 2)
        return self
Example #15
0
    def abduct(self, user_id):
        """Abduct a user.  
        This function alters the Mailbox, so 'add' and react commands may not work as intended."""
        db_set(user_id, 'abducted', 1)
        self.spam("<@{}> has been abducted.".format(user_id))

        for channel_id in channel_change_all(user_id, 1, 3):
            self.edit_cc(channel_id, user_id, 3)
        for channel_id in channel_change_all(user_id, 5, 6):
            self.edit_cc(channel_id, user_id, 6)
        for channel_id in get_secret_channels('Swamp'):
            self.edit_cc(channel_id, user_id, 1)
        return self
Example #16
0
    def unabduct(self, user_id):
        """Unabduct a user.  
        This function alters the Mailbox, so 'add' and react commands may not work as intended."""
        db_set(user_id, 'abducted', 0)
        self.spam("<@{}> is no longer abducted.".format(user_id))

        for channel_id in channel_change_all(user_id, 3, 1):
            self.edit_cc(channel_id, user_id, 1)
        for channel_id in channel_change_all(user_id, 6, 5):
            self.edit_cc(channel_id, user_id, 5)
        for channel_id in channel_change_all(user_id, 7, 4):
            self.edit_cc(channel_id, user_id, 4)
        return self
Example #17
0
def silence(user_id, victim_id):
    """This fuction is taking grandma's action of silencing people.
    The function assumes the player is a participant and has the correct role, so make sure to have filtered this out already.
    The function returns a Mailbox.

    user_id -> the grandma who silences the victim
    victim_id -> the player who shall be silenced"""

    uses = int(db_get(user_id, 'uses'))
    if uses < 1:
        return Mailbox().respond(
            "I am sorry! You currently don't have the ability to silence anyone!",
            True)

    user_channel = int(db_get(user_id, 'channel'))
    user_undead = int(db_get(user_id, 'undead'))

    victim_frozen = int(db_get(victim_id, 'frozen'))
    victim_abducted = int(db_get(victim_id, 'abducted'))

    if user_undead == 1:
        return Mailbox().dm(
            "I am sorry! You are undead, meaning you can no longer silence people!",
            user_id)
    if victim_abducted == 1:
        return Mailbox().msg(
            "It seems like <@{}> has disappeared! Oh well, at least then they won't make any noises either.",
            user_channel, True)
    if victim_frozen == 1:
        return Mailbox().msg(
            "Don't worry. <@{}>'s so cold, that they probably won't make any noise tomorrow."
            .format(victim_id), user_channel, True)

    db_set(user_id, 'uses', uses - 1)

    db_set(victim_id, 'votes', 0)
    answer = Mailbox().msg(
        "You have successfully silenced <@{}>!".format(victim_id),
        user_channel)

    if uses - 1 > 0:
        answer.msg(
            "You can silence **{}** more players tonight!".format(uses - 1),
            user_channel, True)
    else:
        answer.msg(
            "That\'s it for tonight! You can\'t silence any more players.",
            user_channel, True)

    return answer.log("**Grandma** <@{}> has silenced <@{}>.".format(
        user_id, victim_id))
Example #18
0
def pight():
    """This function takes care of all properties that need to happen in the first wave of the end of the day.
    The function returns a Mailbox."""

    if dy.get_stage() == "Night":
        return [
            Mailbox().respond(
                "Whaddaya mean, `{}pight`? It already **is** night, bud.".
                format(config.universal_prefix))
        ]

    answer = Mailbox(True)
    for user_id in db.player_list():
        user_role = db_get(user_id, 'role')

        # Remove potential day uses
        for i in range(len(roles.day_users)):
            if user_role in roles.day_users[i]:
                if i > 0:
                    db_set(user_id, 'uses', 0)
                break

        # Give the user their votes back
        db_set(user_id, 'votes', 1)
        if user_role == "Immortal":
            db_set(user_id, 'votes', 3)
        if user_role == "Idiot ":
            db_set(user_id, 'votes', 0)

    return [answer]
Example #19
0
def day():
    """Start the second part of the day.  
    The function assumes all polls have been evaluated, and that looking after attacks can begin.  
    The function returns a Mailbox."""
    threat = db.get_kill()
    answer = Mailbox().log("**Results from night attacks:**")

    if dy.get_stage() == "Day":
        return Mailbox().respond("Sure, man. Whatever.")

    while threat != None:

        answer = roles.attack(threat[1], threat[2], threat[3], answer)
        threat = db.get_kill()

    for player in db.player_list(True):
        # Give potential day uses
        user_role = db_get(player, 'role')
        for i in range(len(roles.day_users)):
            if user_role in roles.day_users[i]:
                # Give one-time users their one-time power
                if i == 0:
                    if dy.day_number() == 0:
                        db_set(player, 'uses', 1)
                    break

                db_set(player, 'uses', i)
                answer.msg(power.power(user_role), db_get(player, 'channel'))
                break

    answer.story(morning.story_time(db.get_deadies()))
    db.delete_deadies()
    db.delete_hookers()

    # Add polls
    if dy.day_number() != 0:
        answer.new_poll(dy.voting_booth(), 'lynch', '', story_text('lynch'))
    if dy.get_mayor() == 0:
        answer.new_poll(dy.voting_booth(), 'Mayor', '', story_text('Mayor'))
    elif dy.get_reporter() == 0:
        answer.new_poll(dy.voting_booth(), 'Reporter', '',
                        story_text('Reporter'))

    dy.next_day()
    dy.set_stage('Day')
    answer.log("```Day {}```".format(dy.day_number()))

    return answer
Example #20
0
def seek(user_id,victim_id,role):
    """This fuction allows the crowd seeker to inspect players.
    The function assumes the player is a participant and has the correct role, so make sure to have filtered this out already.
    The function returns a Mailbox.

    user_id -> the player who casts the spell
    victim_id -> the player upon whom the spell is cast
    role -> the role the player will be checked as"""

    uses = int(db_get(user_id,'uses'))
    if uses < 1:
        return Mailbox().respond("I am sorry! You currently don't have the ability to seek anyone!",True)

    user_channel = int(db_get(user_id,'channel'))
    user_role = db_get(user_id,'role')
    user_undead = int(db_get(user_id,'undead'))

    victim_role = db_get(victim_id,'role')
    victim_frozen = int(db_get(victim_id,'frozen'))
    victim_abducted = int(db_get(victim_id,'abducted'))

    if user_undead == 1:
        return Mailbox().dm("I am sorry! You are undead, meaning you can no longer seek players!",user_id,True)
    if victim_abducted == 1:
        return Mailbox().msg("You appear to be unable to find <@{}> among the crowds! Where could they be?".format(victim_id),user_channel,True)
    if victim_frozen == 1:
        return Mailbox().msg("<@{}> was isolated from the crowd, and has gotten too cold to seek. Please try someone else!".format(victim_id),user_channel,True)

    db_set(user_id,'uses',uses - 1)
    answer = Mailbox()

    if role == victim_role:
        answer.msg("{} - <@{}> has the role of the **{}**!".format(db_get(victim_id,'emoji'),victim_id,role),user_channel)
        answer.log("The **Crowd Seeker** <@{}> has seen <@{}> as the **{}**!".format(user_id,victim_id,role))
    else:
        answer.msg("{} - <@{}> does **NOT** have the role of the **{}**.".format(db_get(victim_id,'emoji'),victim_id,role),user_channel)
        answer.log("The **Crowd Seeker** <@{}> guessed incorrectly that <@{}> would be the **{}**.".format(user_id,victim_id,role))

    if uses - 1 > 0:
        answer.msg("You can seek **{}** more time".format(uses-1),user_channel,True)
        if uses - 1 > 1:
            answer.msg_add("s")
        answer.msg_add("!")
    else:
        answer.msg("That\'s it for today! You cannot seek any more players.",user_channel,True)

    return answer
Example #21
0
def test_database():
    reset.reset(True)
    assert db.count_categories() == 0
    assert db.get_category() == None
    assert db.get_columns() == []
    assert db.poll_list() == []
    db.signup(1, 'Randium003', u':smirk:')
    assert db.get_user(1) == (1, u'Randium003', u':smirk:', 0, game_log,
                              'Spectator', 'Spectator', 0, 1, 0, 0, 0, 0, 0, 0,
                              0, 0, -1, 0, '', 0, 0, 0)
    assert db.db_get(1, 'channel') == game_log
    assert db.isParticipant(1) == False
    assert db.isParticipant(1, True) == True
    assert db.isParticipant(2) == False
    assert db.isParticipant(2, True) == False
    db.db_set(1, 'frozen', 1)
    assert db.poll_list() == [(1, u':smirk:', 1, 0)]

    db.add_category('24')
    assert db.count_categories() == 1
    assert db.get_category() == 24
    assert db.get_columns() == [(1, )]
    assert db.channel_get('1234555') == None
    db.add_channel('1234555', 1)
    assert db.get_category() == 24
    db.add_channel('12211', 1)
    assert db.get_category() == 24
    assert db.channel_get('1234555') == (u'1234555', u'1', u'0')
    assert db.channel_change_all(1, 0, 1) == [u'1234555', u'12211']
    assert db.channel_get('1234555') == (u'1234555', u'1', u'1')
    assert db.channel_get('12211') == (u'12211', u'1', u'1')
    db.set_user_in_channel('1234555', 1, 2)
    assert db.channel_get('1234555') == (u'1234555', u'1', u'2')
    assert db.channel_get('1234555', 1) == '2'
    assert db.channel_change_all(1, 2, 3) == [u'1234555']
    assert db.unabduct(1) == [u'1234555']
    db.signup(420, "BenTechy66", ":poop:")
    assert db.channel_get('12211') == (u'12211', u'1', u'1', u'0')
    assert db.freeze('1') == [u'1234555', u'12211']
    assert db.abduct('420') == []

    for i in range(max_channels_per_category - 2):
        assert db.get_category() == 24
        db.add_channel(10 * i, 608435446804 + 7864467 * i)
    assert db.count_categories() == 1
    assert db.get_category() == None
    reset.reset(True)
Example #22
0
def cupid_kiss(user_id,victim_id,voluntarily = True):
    """This function makes the cupid fall in love with a partner.
    The function assumes the player is a cupid and has the correct role, so make sure to have filtered this out already.
    The function returns a Mailbox.

    user_id -> the cupid who casts the spell
    victim_id -> the player who's falling in love with the cupid"""

    uses = int(db_get(user_id,'uses'))
    if uses < 1:
        return Mailbox().respond("I am sorry! You currently cannot choose someone to fall in love with!",True)

    user_channel = int(db_get(user_id,'channel'))

    victim_role = db_get(victim_id,'role')
    victim_frozen = int(db_get(victim_id,'frozen'))
    victim_abducted = int(db_get(victim_id,'abducted'))
    victim_undead = int(db_get(victim_id,'undead'))

    # If involuntary, make the cupid choose again.
    if voluntarily == False and (victim_id == user_id or victim_abducted == 1 or victim_frozen == 1):
        return False 

    if victim_id == user_id:
        return Mailbox().respond("So you wanna fall in love with yourself, huh? Too bad, your partner really has to be someone ELSE.")
    if victim_abducted == 1:
        return Mailbox().msg("You wanted to throw an arrow at your target... but you cannot find them! It's almost as if they had disappeared from this town!",user_channel,True)
    if victim_frozen == 1:
        return Mailbox().msg("Your love arrows just do not seem to be able to reach your chosen lover! They are frozen! Please try someone else.",user_channel,True)

    db_set(user_id,'uses',uses - 1)

    answer = Mailbox().edit_cc(user_channel,victim_id,1).msg("Welcome, <@{}>!".format(victim_id),user_channel)
    answer.log("The **Cupid** <@{}> has chosen to fall in love with <@{}>.".format(user_id,victim_id))
    answer.dm("Hello there, <@{}>! The **Cupid** <@{}> has chosen to fall in love with you!\n".format(victim_id,user_id),victim_id)
    answer.dm_add("For the rest of the game, you two will remain partners. Be open and honest, as you cannot win if the other dies!\n")
    answer.dm_add("Good luck!")

    if victim_undead == 1:
        answer.msg_add("<@{}>, while pretending to be a **{}**, is secretly an **Undead**!".format(victim_id,victim_role))
    else:
        answer.msg_add("<@{}>, the town's favourite **{}**, has decided to trust <@{}>.".format(victim_id,victim_role,user_id))

    return answer.msg_add("\nTogether, they will survive this town!")
Example #23
0
def enchant(user_id,victim_id):
    """This function allows the flute player to enchant targets.
    The function assumes both players are participants, of which the casting user is a flute player. Make sure to have filtered this out already.
    The function returns a Mailbox.

    Keyword arguments:
    user_id -> the flute player who enchants the player
    victim_id -> the player who's enchanted"""

    uses = int(db_get(user_id,'uses'))
    if uses < 1:
        return Mailbox().respond("I am sorry! You currently don't have the ability to enchant anyone!",True)

    user_channel = int(db_get(user_id,'channel'))
    user_undead = int(db_get(user_id,'undead'))

    victim_frozen = int(db_get(victim_id,'frozen'))
    victim_abducted = int(db_get(victim_id,'abducted'))
    victim_enchanted = int(db_get(victim_id,'enchanted'))

    if db_get(victim_id,'role') == 'Flute Player':
        return Mailbox().msg("You cannot enchant a flute player, sorry.",user_channel,True)
    if victim_abducted == 1:
        return Mailbox().msg("You wanted to warm up <@{}>... but you weren't able to find them! That is strange...",user_channel,True)
    if victim_frozen == 1:
        return Mailbox().msg("You failed to enchant your target, as they were frozen to the bone!.",user_channel,True)
    if victim_enchanted == 1:
        return Mailbox().msg("I am terribly sorry, but you cannot enchant a player who already *IS* enchanted!",user_channel,True)

    answer = Mailbox().msg("You have successfully enchanted <@{}>!".format(victim_id),user_channel)
    db_set(user_id,'uses',uses - 1)

    if user_undead == 1:
        answer.dm("You're an Undead, so you can't actually enchant anyone... but this will help you keep up your cover!",user_id)
        answer.log("The **Undead** <@{}> has pretended to enchant <@{}>.".format(user_id,victim_id))
    else:
        for channel_id in db.get_secret_channels('Flute_Victims'):
            answer.edit_cc(channel_id,victim_id,1)
            answer.msg("<@{}> has been enchanted! Please welcome them to the circle of the enchanted ones.".format(victim_id),channel_id)
        answer.log("The **Flute Player** <@{}> has enchanted <@{}>.".format(user_id,victim_id))
        db_set(victim_id,'enchanted',1)

    return answer
Example #24
0
    def suspend(self, user_id):
        """Suspend a user.  
        This function alters the Mailbox, so 'add' and react commands may not work as intended."""
        db_set(user_id, 'role', 'Suspended')
        self.spam("<@{}> has been suspended.".format(user_id))

        for channel_id in channel_change_all(user_id, 1, 8):
            self.edit_cc(channel_id, user_id, 8)
        for channel_id in channel_change_all(user_id, 2, 8):
            self.edit_cc(channel_id, user_id, 8)
        for channel_id in channel_change_all(user_id, 3, 8):
            self.edit_cc(channel_id, user_id, 8)
        for channel_id in channel_change_all(user_id, 4, 8):
            self.edit_cc(channel_id, user_id, 8)
        for channel_id in channel_change_all(user_id, 5, 8):
            self.edit_cc(channel_id, user_id, 8)
        for channel_id in channel_change_all(user_id, 6, 8):
            self.edit_cc(channel_id, user_id, 8)
        for channel_id in channel_change_all(user_id, 7, 8):
            self.edit_cc(channel_id, user_id, 8)
        return self
Example #25
0
def see(user_id,victim_id):
    """This function allows the user to see a given player of their choice.
    The function assumes the player is a participant and has the correct role, so make sure to have filtered this out already.  
    The function returns a Mailbox.  

    user_id -> the player who casts the spell
    victim_id -> the player who is being searched"""

    uses = int(db_get(user_id,'uses'))
    if uses < 1:
        return Mailbox().respond("I am sorry! You currently don't have the ability to see this player!",True)
    db_set(user_id,'uses',uses - 1)

    victim_emoji = db_get(victim_id,"emoji")
    victim_fakerole = db_get(victim_id,"fakerole")
    victim_role = db_get(victim_id,"role")

    user_channel = int(db_get(user_id,"channel"))
    user_role = db_get(victim_id,"role")

    # Follow this procedure if the user has been enchanted.
    if int(db_get(user_id,"echanted")) == 1 and random.random() < 0.6:
        answer = Mailbox().msg("{} - <@{}> has the role of the `Flute Player`!".format(victim_emoji,victim_id),user_channel)
        answer.log("<@{0}> has attempted to see the role of <@{1}>. However, their enchantment effect worked, showing <@{1}> as the **Flute Player!**".format(user_id,victim_id))

        # Easter egg
        if victim_role == "Flute Player":
            answer.log("I mean, <@{}> *is* a **Flute Player**, so it wouldn't really matter. But hey! They don't need to know. 😉")
        
        return answer

    answer = Mailbox().msg("{} - <@{}> has the role of the `{}`!".format(victim_emoji,victim_id,victim_fakerole),user_channel)
    
    if victim_fakerole != victim_role:
        answer.log("<@{}>, the town's **{}**, has attempted to see <@{}>, the **{}**. ".format(user_id,user_role,victim_id,victim_role))
        return answer.log_add("However, they were disguised and appeared to be the **{}**!".format(victim_fakerole))

    return answer.log("<@{}>, a **{}**, has seen the role of <@{}>, who had the role of the **{}**!".format(user_id,user_role,victim_id,victim_role))
Example #26
0
def nightly_kill(user_id,victim_id):
    """This function adds a kill to the kill queue based on the user's role.
    This function is applicable for roles like the assassin, the lone wolf, the priest, the thing and the white werewolf.
    Evaluating whether the kill should actually be applied isn't needed, as this is evaluated at the start of the day.  
    The function assumes the player is a participant and has the correct role, so make sure to have filtered this out already.  
    The function returns a Mailbox.  
    
    user_id -> the player who will initiate the attack
    victim_id -> the player who shall be \"attacked\""""

    uses = int(db_get(user_id,'uses'))
    if uses < 1:
        return Mailbox().respond("I am sorry! You currently don't have this ability available!",True)
    db_set(user_id,'uses',uses - 1)

    user_role = db_get(user_id,'role')
    user_channel = int(db_get(user_id,'channel'))

    # Add kill to the kill queue
    db.add_kill(victim_id,user_role,user_id)

    answer = Mailbox().msg(ctory.kill_acceptance(victim_id),user_channel)
    return answer.log("The **{}** <@{}> has chosen to pay a visit to <@{}> tonight.".format(user_role,user_id,victim_id))
Example #27
0
def purify(user_id,victim_id):
    """This function allows the priestess to purify targets.
    The function assumes both players are participants, and that the casting user is a priestess. Make sure to have filtered this out beforehand.
    The function returns a Mailbox."""

    uses = int(db_get(user_id,'uses'))
    if uses < 1:
        return Mailbox().respond("I am sorry! You currently don't have the ability to purify anyone!",True)

    user_channel = int(db_get(user_id,'channel'))
    user_undead = int(db_get(user_id,'undead'))

    victim_role = db_get(victim_id,'role')
    victim_frozen = int(db_get(victim_id,'frozen'))
    victim_abducted = int(db_get(victim_id,'abducted'))

    if user_undead == 1:
        return Mailbox().msg("I am sorry! You cannot purify anyone while you're **Undead**!",user_channel,True)
    if victim_abducted == 1:
        return Mailbox().msg("You have attempted to purify <@{}>... but your powers cannot locate them! Strange...".format(victim_id),user_channel,True)
    if victim_frozen == 1:
        return Mailbox().msg("You wanted to purify <@{}>, but you were unable to reach them through the thick layer of ice surrounding them".format(victim_id),user_channel,True)

    answer = Mailbox()
    db_set(user_id,'uses',uses - 1)

    if victim_role in ['Cursed Civilian','Sacred Wolf']:
        answer.msg("Your powers' results were **positive**. They are no longer cursed civilians or sacred wolves!",user_channel)
        answer.log("The **Priestess** <@{}> has purified the **{}** <@{}>.".format(user_id,victim_role,victim_id))
        if victim_role == 'Cursed Civilian':
            db_set(victim_id,'role','Innocent')
            answer.dm(rolestory.to_innocent(victim_id,'Cursed Civilian'),victim_id)
        if victim_role == 'Sacred Wolf':
            db_set(victim_id,'role','Werewolf')
            answer.dm("This message yet needs to be written!",victim_id) # TODO
    elif victim_role in ['Innocent','Werewolf']:
        answer.msg("Your powers' results were **neutral**. They were already innocent or a werewolf!",user_channel)
        answer.log("The **Priestess** <@{}> has attempted to purify the **{}** <@{}>.".format(user_id,victim_role,victim_id))
    else:
        answer.msg("Your powers' results were **negative**. They weren't cursed civilians or sacred wolves, so they couldn't be purified!",user_channel)
        answer.log("The **Priestess** <@{}> has ineffectively attempted to purify the **{}** <@{}>.".format(user_id,victim_role,victim_id))

    return answer
Example #28
0
def start_game():
    """This function is triggered at the start of the game. If successful, the function returns a Mailbox.
    If unsuccessful, the function still returns a Mailbox, but will also confirm the error in the console."""

    # Make sure there isn't already a game going on!
    if dy.get_stage() != "NA":
        print("ERROR: According to " + dy.dynamic_config +
              ", there's already a game going on!")
        return Mailbox().respond(
            "I'm sorry! A game cannot be started while there's another one going on already!"
        )

    # Choose the roles out of the given role-pool
    role_pool = []
    for choice in view_roles():
        for i in range(choice.amount):
            role_pool.append(choice.role)

    if len(db.player_list()) > len(role_pool):
        print(
            "The game cannot be started while there are less roles available than that there are participants signed up."
        )
        return Mailbox().respond("Not enough roles to distribute available!",
                                 True)

    # If there are enough roles available, make a selection, evaluate the selection, and, if accepted, distribute the roles.
    if not pos.valid_distribution(role_pool, True):
        return Mailbox().respond(
            "I am sorry, but I cannot use an invalid distribution to start the game!",
            True)

    answer = Mailbox(True)

    attempts = 0
    while attempts < 1000:
        attempts += 1
        chosen_roles = random.sample(role_pool, len(db.player_list()))

        if pos.valid_distribution(chosen_roles, True) == True:

            answer.create_cc("Graveyard", 0, [], [], True)
            answer.create_cc("Market", 0, [], [], True)
            answer.create_cc("Reporter", 0, [], [], True)

            # Assign the roles to all users.
            user_list = db.player_list()

            for i in range(len(user_list)):
                user_id = user_list[i]
                user_role = chosen_roles[i]

                db_set(user_id, 'role', user_role)
                db_set(user_id, 'fakerole', user_role)
                db_set(user_id, 'channel', config.game_log)

                answer.log(
                    "{} - <@{}> has received the role of the `{}`!".format(
                        db_get(user_id, 'emoji'), user_id, user_role))
                answer.dm(
                    "This message is giving you your role for season `{}` of the *Werewolves* game.\n\n"
                    .format(config.season), user_id)
                answer.dm_add('Your role is `{}`.\n\n'.format(user_role))
                answer.dm_add(
                    "**You are not allowed to share a screenshot of this message!** "
                )
                answer.dm_add(
                    "You can claim whatever you want about your role, but you may under **NO** "
                )
                answer.dm_add(
                    "circumstances show this message in any way to any other participants.\n"
                )
                answer.dm_add(
                    "We hope you are happy with the role you gained, and we hope you'll enjoy the game as much as we do.\n\n"
                )
                answer.dm_add("Good luck... 🌕")

                if user_role in pos.personal_secrets:
                    answer.create_sc(user_id, user_role)
                if user_role in pos.shared_secrets:
                    answer.add_to_sc(user_id, user_role)

                if user_role == "Cult Member":
                    answer.add_to_sc(user_id, "Cult Leader")
                if user_role in pos.wolf_pack:
                    answer.add_to_sc(user_id, "Werewolf")
                if user_role == "Bloody Butcher":
                    answer.add_to_sc(user_id, "Butcher")
                if user_role == "Devil":
                    answer.add_to_sc(user_id, "Demon")
                if user_role == "Vampire":
                    answer.add_to_sc(user_id, "Undead")
                if user_role == "Witch":
                    db_set(user_id, 'uses', 3)

            answer.story(
                'The current distribution is {}'.format(chosen_roles))  # TODO
            answer.story(
                'I know, I know. That looks ugly as hell. We\'re trying to make it look good!'
            )

            if "Flute Player" in chosen_roles:
                answer.create_cc("Flute_Victims", 0, [], [], True)

            # If the four horsemen are part of the game, assign numbers to all players.
            if "Horseman" in chosen_roles:
                nothorse_table = [
                    user_id for user_id in db.player_list()
                    if db_get(user_id, 'role') != 'Horseman'
                ]
                horse_table = [
                    user_id for user_id in db.player_list()
                    if db_get(user_id, 'role') == 'Horseman'
                ]

                nothorse_table.shuffle()
                horse_table.shuffle()

                for i in range(4):
                    db_set(horse_table[i], 'horseman', i + 1)

                for i in range(16):
                    db_set(nothorse_table[i], 'horseman', (i % 4) + 1)

            # Reset the day timer
            dy.reset_day()
            dy.set_stage('Night')

            return answer.respond(
                "Very well! The game will start tomorrow morning.")

    answer.respond("Timeout reached! Your distribution is too crazy!", True)
    return answer
Example #29
0
def pay():
    """This function takes care of all properties that need to happen in the first wave of the end of the night.
    The function returns a Mailbox."""

    if dy.get_stage() == "Day":
        return [
            Mailbox().respond(
                "Whaddaya mean, `{}pay`? It already **is** day, bud.".format(
                    config.universal_prefix))
        ]

    answer = Mailbox()
    answer_table = [Mailbox(True)]
    for user_id in db.player_list():
        user_role = db_get(user_id, 'role')

        # Remove potential night uses
        for i in range(len(roles.night_users)):
            if user_role in roles.night_users[i]:
                if i > 0:
                    db_set(user_id, 'uses', 0)
                break

        # Force Cupid to fall in love
        if user_role == "Cupid" and db_get(user_id, 'uses') > 0:
            chosen = False
            attempts = 0

            while not chosen and attempts < 1000:
                forced_victim = random.choice(db.player_list(True, True))
                chosen = cupid_kiss(user_id, forced_victim, False)

            answer_table.append(chosen)

        # Force Dog to become Innocent
        if user_role == "Dog" and db_get(user_id, 'uses') > 0:
            db_set(user_id, 'role', "Innocent")
            answer.msg(
                "You haven't chosen a role! That's why you have now become and **Innocent**!",
                db_get(user_id, 'channel'))
            answer.log(
                "The **Dog** <@{}> didn't choose a role last night and turned into an **Innocent**!"
                .format(user_id))

        # Remove hooker effects
        db_set(user_id, 'sleepingover', 0)
        for standoff in db.get_standoff(user_id):
            if standoff[2] == 'Hooker':
                db.delete_standoff(standoff[0])

        # Force Look-Alike to become Innocent
        if user_role == "Look-Alike":
            db_set(user_id, 'role', "Innocent")
            answer.msg(
                "You haven't chosen a role! That's why you have now become an **Innocent**!",
                db_get(user_id, 'channel'))
            answer.log(
                "The **Dog** <@{}> didn't choose a role last night and turned into an **Innocent**!"
                .format(user_id))

        # Remove tanner disguises
        db_set(user_id, 'fakerole', user_role)

        # Remove zombie tag
        db_set(user_id, 'bitten', 0)

    answer_table.append(answer)
    return answer_table
Example #30
0
def attack(user_id, role, murderer, answer=Mailbox().log(''), recursive='\n'):
    """This functions attacks the given player with the given role.  
    The effects are immediate, but they can be used in all scenarios, as only\
    standoffs are executed during this attack."""

    if role == 'Inactive':
        answer.log_add(recursive + success + skull +
                       "<@{}> was killed due to inactivity.".format(user_id))
        return instant_death(user_id, role, 'Inactive', answer,
                             recursive + next)

    # Prevent Pyromancer from causing way too long lines
    # No, I didn't add this during debugging.
    # Yes, that means I planned to design it this terribly.
    if role == 'Pyromancer' and int(db_get(user_id, 'powdered')) != 1:
        return answer

    user_role = db_get(user_id, 'role')
    answer.log_add(recursive + failure)

    try:
        demonized = False
        if int(db_get(user_id, 'demonized')) == 1:
            demonized = True

        undead = False
        if int(db_get(user_id, 'undead')) == 1 or user_role == 'Undead':
            undead = True
            demonized = False
    except Exception:
        demonized = False
        undead = False

    # End function if player is dead (exit condition for recursion)
    if user_role in ['Dead', 'Spectator', 'Suspended', None, 'Unknown']:
        return answer.log_add(recursive + success +
                              '<@{}> was already dead!'.format(user_id))

    if role == 'Cupid':
        answer.log_add(recursive + success + skull +
                       '<@{}> committed suicide.'.format(user_id))
        answer = instant_death(user_id, role, 'Cupid', answer,
                               recursive + next)
        if int(db_get(user_id, 'abducted')) != int(db_get(
                murderer, 'abducted')):
            answer.dm("Abducted or not, you know your lover has deceased! ",
                      user_id)
            answer.dm_add(
                "You couldn't handle the pain, and that's why you decided to put an end to it.\n"
            )
            answer.dm_add("Your story ends here.")
        elif int(db_get(user_id, 'frozen')) == 1:
            answer.dm(
                "Even though your heart has become cold from the ice surrounding you, ",
                user_id)
            answer.dm_add(
                "but it got even colder when you saw the dead body of <@{}> being carried away.\n"
                .format(murderer))
            answer.dm_add(
                "It was at this moment where the ice got even colder...")
        else:
            answer.dm(
                "You couldn't bear the sight of your lover, <@{}>, ".format(
                    murderer), user_id)
            answer.dm_add(
                "lying dead in your arms. This is why you have decided to end it all!\n"
            )
            answer.dm_add(
                "Let\'s just hope this isn\'t like Romeo and Juliet...")
        answer.dm_add(
            "**Your lover, <@{}>, has died. In response, you have committed suicide.**"
            .format(murderer))
        return answer

    if role == 'Fortune Teller':
        if not undead:
            answer.dm(
                "Your idol, the fortune teller <@{}>, has deceased. ".format(
                    murderer), db_get(user_id, 'channel'))
            answer.dm_add(
                "They were a great inspiration to you, and that's why ")
            answer.dm_add("you've decided to get in their footsteps!\n")
            answer.dm_add("**You have turned into a Fortune Teller. Find and ")
            answer.dm_add(
                "eliminate all werewolves, solo players and other enemies!**")
            answer.log_add(recursive + success +
                           '<@{}> became a fortune teller.')
        else:
            answer.dm(
                "Your idol, the fortune teller <@{}>, has deceased. ".format(
                    murderer), user_id)
            answer.dm_add("They were a great inspiration to you... ")
            answer.dm_add(
                "back when you were alive, at least. Now, your undead heart is as cold as it has ever been, "
            )
            answer.dm_add("and nothing will happen to you.\n")
            answer.dm_add(
                "**The rules have changed. You will remain Undead.**")
            answer.log_add(recursive + success +
                           '<@{}> failed to become a fortune teller.')
            db_set(user_id, 'role', 'Fortune Teller')
        return answer

    if role == 'Horseman' and user_role == 'Horseman':
        horse_number = db_get(user_id, 'horseman')
        apocalypse_ready = True
        for player in db.player_list():
            if int(db_get(player, 'horseman')) != 0:
                apocalypse_ready = False
            if int(db_get(player, 'horseman')) == horse_number:
                db_set(player, 'horseman', 0)
        answer.log_add(recursive + success +
                       '<@{}> was united.'.format(user_id))

        if horse_number != 0:
            for channel_id in db.get_secret_channels('Horseman'):
                answer.msg(
                    '**Horseman #{} has been united!**'.format(horse_number),
                    channel_id)

        if apocalypse_ready:
            for player in db.player_list():
                if db_get(player, 'role') == 'Horseman':
                    answer.log_add(recursive + next + failure)
                    answer.log_add(recursive + next + success +
                                   '<@{}> has joined the **Apocalypse**!')
                    db_set(player, 'horseman', 5)

                    answer.secret_dm(
                        'All Horsemen are united! This means that the **APOCALYPSE** can be unleashed!',
                        'Horseman')
            answer.story('Oh no! The Apocalypse has been unleashed!')
        return answer

    # End if user is frozen.
    if int(db_get(user_id, 'frozen')) == 1:
        return answer.log_add(
            recursive + success +
            '<@{}> was frozen and thus protected.'.format(user_id))

    if role == "Devil":
        if user_role == 'Devil':
            answer.log_add(recursive + success +
                           '<@{}> did not die to their own wage.')
            return answer
        answer.log_add(recursive + success + skull +
                       '<@{}> was killed by the wager.')
        answer = instant_death(user_id, role, 'Wager', answer,
                               recursive + next)
        return answer

    # Let all zombies kill all other zombies.
    if role == "Zombie":
        answer.log_add(recursive + success + skull +
                       '<@{}> has decayed.'.format(user_id))
        answer = instant_death(user_id, role, 'Zombie', answer,
                               recursive + next)
        return answer

    # Kill abducted players (or The Thing himself)
    if role == "The Thing":
        answer.log_add(recursive + success + skull +
                       '<@{}> drowned in the swamp.'.format(user_id))
        # TODO: kill the player (BUT NOT THROUGH THE SUICIDE FUNCTION)
        return answer

    # End if user is immortal.
    if user_role == "Immortal":
        answer.log_add(recursive + success +
                       '<@{}> is immortal.'.format(user_id))
        return answer

    # End if user is abducted.
    if int(db_get(user_id, 'abducted')) == 1:
        return answer.log_add(
            recursive + success +
            '<@{}> was abucted and thus protected.'.format(user_id))

    # Kill lynch!
    if role == "Innocent":
        replacements = [
            standoff for standoff in db.get_standoff(user_id)
            if standoff[2] == 'Executioner'
        ]

        if replacements == []:
            answer.log_add(recursive + success + skull +
                           '<@{}> was killed by an angry mob.'.format(user_id))
            answer = instant_death(user_id, role, 'Lynch', answer,
                                   recursive + next)

        else:
            answer.log_add(recursive + success +
                           '<@{}> escaped death as the Executioner.')

            if user_role == 'Executioner':
                db_set(user_id, 'role', 'Innocent')

            for standoff in replacements:
                db.delete_standoff(standoff[0])
                answer = instant_death(standoff[1], standoff[2], 'Lynch',
                                       answer, recursive + next)

        return answer

    # Kill whoever stands in the barber's way!
    if role == "Barber":
        if user_role != 'Idiot':
            answer.log_add(recursive + success + skull +
                           '<@{}> was cut to death.'.format(user_id))
            answer = instant_death(user_id, role, 'Barber', answer,
                                   recursive + next)
            answer.story(barber_kill_story(murderer, user_id))

        else:
            msg = "*\"Tomorrow, at noon, right here. You got that?\"* Yup, it definitely seemed like <@{}> ".format(
                user_id)
            msg += "remembered the barber\'s appointment.\nIt was only today that it turned out - they had forgotten "
            msg += "about it! Good thing for them, for <@{}> had the intent to cut a little far below the hairline...\n".format(
                murderer)
            msg += "**<@{0}>, the Barber, has failed to execute <@{1}>, the Idiot! <@{0}> will now continue the game ".format(
                murderer, user_id)
            msg += "as a regular Innocent, and <@{}> as an even better Idiot, as they are no longer allowed to vote.**".format(
                user_id)
            answer.story(msg).log_add(
                recursive + success +
                '<@{}> failed to give <@{}> a \"haircut\".'.format(
                    murderer, user_id))
            db_set(user_id, 'role', 'Idiot ')

        return answer

    # Save users if they have souls to spare.
    souls = int(db_get(user_id, 'souls'))
    if souls > 0:
        db_set(user_id, 'souls', souls - 1)
        answer.log_add(recursive + success +
                       '<@{}> lost a soul.'.format(user_id))
        return answer

    # End if the user sleeps with another.
    if role == "Hooker" and not demonized:
        answer.log_add(recursive + success + skull +
                       '<@{}> was slept with <@{}>.'.format(user_id, murderer))
        answer = instant_death(user_id, role, 'Hooker', answer,
                               recursive + next)
        return answer

    # End if player dies in someone else's place.
    if role == "Executioner":
        answer.log_add(recursive + success + skull +
                       '<@{}> was executed.'.format(user_id))
        answer = instant_death(user_id, role, 'Executioner', answer,
                               recursive + next)
        return answer

    # End if player dies in someone else's place.
    if role == "Huntress" and not demonized:
        answer.log_add(recursive + success + skull +
                       '<@{}> was shot.'.format(user_id))
        answer = instant_death(user_id, role, 'Huntress', answer,
                               recursive + next)
        return answer

    # Check if user has an amulet.
    if db.has_amulet(user_id) and role not in ['Hooker']:
        return answer.log_add(
            recursive + success +
            "<@{}> was protected by their amulet.".format(user_id))

    # Protect apocalypse horsemen
    if int(db_get(user_id, 'horseman')) == 5:
        return answer.log_add(
            '<@{}> was protected by the Apocalypse.'.format(user_id))

    # Kill assassinations
    if role == 'Assassin' and not demonized:
        answer.log_add(recursive + success + skull +
                       '<@{}> was assassinated.'.format(user_id))
        answer = instant_death(user_id, role, 'Assassin', answer,
                               recursive + next)
        return answer
    if role == 'Cult Leader' and not demonized:
        answer.log_add(recursive + success + skull +
                       '<@{}> was killed by the cult.'.format(user_id))
        answer = instant_death(user_id, role, 'Cult', answer, recursive + next)
        return answer
    if role == 'Priest' and not demonized:
        if user_role in pos.wolf_team:
            answer.log_add(recursive + success + skull +
                           '<@{}> was holified.'.format(user_id))
            answer = instant_death(user_id, role, 'Priest', answer,
                                   recursive + next)
        else:
            answer.log_add(recursive + success + skull +
                           '<@{}> holified themselves.'.format(murderer))
            answer = instant_death(user_id, role, 'Priest', answer,
                                   recursive + next)
        return answer
    if role == 'Witch' and not demonized:
        answer.log_add(recursive + success + skull +
                       '<@{}> was poisoned.'.format(user_id))
        answer = instant_death(user_id, role, 'Witch', answer,
                               recursive + next)
        return answer

    # Kill wolf attacked
    if role in ['Werewolf', 'Lone Wolf', 'White Werewolf']:
        if user_role == 'Runner':
            answer.log_add(recursive + success +
                           '<@{}> outran a wolf attack.'.format(user_id))
            answer.dm('You. Are. EXHAUSTED.\n', user_id)
            answer.dm_add(
                'Last night may have been the worst night of your life! ')
            answer.dm_add(
                'You\'re still alive, however. And that\'s what counts. ')
            answer.dm_add(
                'Let\'s hope that, whatever those creatures were, won\'t attack again tomorrow night!\n'
            )
            answer.dm_add(
                '**Last night, you have been attacked by a wolf. You have become a regular Innocent.**'
            )
            db_set(user_id, 'role', 'Innocent')
            return answer
        if user_role == 'Cursed Civilian':
            answer.dm(
                "The curse that went around you, had been a little itchy lately... and it kept getting worse! ",
                user_id)
            answer.dm_add(
                "It got worse and worse, and you couldn't help but notice how hair started growing everywhere!\n"
            )
            answer.dm_add(
                "Last night, you were waking up by the grunts of a what sounded like a wolf! "
            )
            answer.dm_add(
                "You thought your days were over, but the wolf did not attack. Instead, "
            )
            answer.dm_add(
                "the wolf watched as your nails grew longer, your ears became spiky and your smell "
            )
            answer.dm_add(
                "slowly improved... and you looked just like one of the silhouettes in the shadow, "
            )
            answer.dm_add(
                "waiting for you to join them in the beautiful night's sky...\n"
            )
            answer.dm_add(
                "**You have been visited by wolves last night, and your curse made you turn "
            )
            answer.dm_add(
                "into a werewolf. Devour all villagers and win the game!**")

            db_set(user_id, 'role', 'Werewolf')
            answer.log_add(recursive + success +
                           '<@{}> has turned into a Werewolf!'.format(user_id))

            for channel_id in db.get_secret_channels('Werewolf'):
                answer.edit_cc(channel_id, user_id, 1)
                answer.msg("**ARRROOOO!\nWelcome, <@{}>!**".format(user_id),
                           channel_id)
                answer.msg_add(
                    "Last night, the **cursed civilian** <@{}> was attacked by wolves, "
                    .format(user_id))
                answer.msg_add(
                    "and has now become a **werewolf**! Please, welcome this new member "
                )
                answer.msg_add("of the wolf pack!")
            return answer
        if not demonized:
            answer.log_add(recursive + success + skull +
                           '<@{}> was eaten by a werewolf.'.format(user_id))
            answer = instant_death(user_id, role, 'Werewolf', answer,
                                   recursive + next)
            return answer

    # Kill solo attacked
    if role == 'Demon' and not demonized:
        answer.log_add(recursive + success + skull +
                       '<@{}> was sent to hell.'.format(user_id))
        answer = instant_death(user_id, role, 'Demon', answer,
                               recursive + next)
        return answer
    if role == 'Horseman' and not demonized:
        answer.log_add(recursive + success + skull +
                       '<@{}> was apocalypsed.'.format(user_id))
        answer = instant_death(user_id, role, 'Horseman', answer,
                               recursive + next)
        return answer
    if role == 'Pyromancer' and not demonized:
        answer.log_add(recursive + success + skull +
                       '<@{}> went up in flames.'.format(user_id))
        answer = instant_death(user_id, role, 'Pyromancer', answer,
                               recursive + next)
        return answer

    # Assume they were supposed to be killed, but that they are demonized. Let's turn them undead!
    answer.log_add(recursive + success + skull + '<@{}> has become undead.')

    db_set(user_id, 'undead', 1)
    answer.dm(
        "Last night, you didn't feel to well and decided to go out, to take a walk. ",
        user_id)
    answer.dm_add(
        "As soon as you stepped out the door, you felt like it was a bad idea - and it was!\n"
    )
    answer.dm_add(
        "The last thing you can remember is the sound of someone approaching you from behind, "
    )
    answer.dm_add(
        "the sound of a skull cracking open, and then - **NOTHING**.\n\n")
    answer.dm_add("Is this the end?\n\n")
    answer.dm_add(
        "It doesn't appear so. You wake up in a graveyard. A few cold and grim silhouettes "
    )
    answer.dm_add(
        "stand in front of you. You are surrounded, but it feels more... welcoming. "
    )
    answer.dm_add("And then the truth arrives.\n")
    answer.dm_add(
        "The **{}** you once were, is dead. Their soul could not rest, and that is you. "
    )
    answer.dm_add("The remainders of something that wasn't ready to die.\n")
    answer.dm_add(
        "**You have become Undead. Murder everyone that isn't an undead or a vampire."
    )

    for channel_id in db.get_secret_channels('Undead'):
        answer.edit_cc(channel_id, user_id, 1)
        answer.msg(
            "Last night, <@{}>, a **{}** has died! Please welcome them in the realm of the Undead!",
            channel_id)

    if user_role not in pos.pretenders:
        db_set(user_id, 'role', 'Undead')
        answer.dm_add("**")
    else:
        answer.dm_add(
            " Your former teammates do not know you are Undead, so make use of this advantage.**"
        )

    return answer