diff --git a/src/settings.py b/src/settings.py index 0752d9c..907f18a 100644 --- a/src/settings.py +++ b/src/settings.py @@ -131,6 +131,9 @@ DETECTIVE_REVEALED_CHANCE = 2/5 SHARPSHOOTER_CHANCE = 1/5 # if sharpshooter is enabled, chance that a gunner will become a sharpshooter instead FALLEN_ANGEL_KILLS_GUARDIAN_ANGEL_CHANCE = 1/2 + # HALF FULL +PROPHET_REVEALED_CHANCE = ( 2/5 , 4/5 ) + AMNESIAC_NIGHTS = 3 # amnesiac gets to know their actual role on this night ALPHA_WOLF_NIGHTS = 3 # alpha wolf turns the target into a wolf after this many nights (note the night they are bitten is considered night 1) @@ -433,7 +436,9 @@ def irc_equals(nick1, nick2): def plural(role): bits = role.split() - bits[-1] = {"person": "people", "wolf": "wolves"}.get(bits[-1], bits[-1] + "s") + bits[-1] = {"person": "people", + "wolf": "wolves", + "succubus": "succubi"}.get(bits[-1], bits[-1] + "s") return " ".join(bits) def list_players(roles = None): diff --git a/src/wolfgame.py b/src/wolfgame.py index f595366..55ecdc3 100644 --- a/src/wolfgame.py +++ b/src/wolfgame.py @@ -5550,11 +5550,101 @@ def investigate(cli, nick, chan, rest): @cmd("pray", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("prophet",)) def pray(cli, nick, chan, rest): - """Receive divine visions of something or someone.""" + """Receive divine visions of who has a role.""" # this command may be used multiple times in the course of the night, however it only needs - # to be used once to count towards ending night (additional uses don't count) + # to be used once to count towards ending night (additional uses don't count extra) + if nick in var.PRAYED and var.PRAYED[nick][0] == 2: + pm(cli, nick, "You are exhausted and unable to receive any more visions tonight.") + return + elif nick not in var.PRAYED: + # [number of times prayed tonight, current target, target role, {target: [roles]}] + var.PRAYED[nick] = [0, None, None, defaultdict(set)] - pass + if var.PRAYED[nick][0] == 0: + what = re.split(" +", rest)[0] + if not what: + pm(cli, nick, "Not enough arguments.") + return + # complete this as a match with other roles (so "cursed" can match "cursed villager" for instance) + role, _ = complete_match(what.lower(), var.ROLE_GUIDE.keys()) + if role is None: + # typo, let them fix it + pm(cli, nick, "\u0002{0}\u0002 is not a valid role.".format(what)) + return + + # get a list of all roles actually in the game, including roles that amnesiacs will be turning into + # (amnesiacs are special since they're also listed as amnesiac; that way a prophet can see both who the + # amnesiacs themselves are as well as what they'll become) + pl = var.list_players() + valid_roles = set(r for r, p in var.ROLES.items() if p) | set(r for p, r in var.AMNESIAC_ROLES.items() if p in pl) + + if role in valid_roles: + # looking for a specific role, as opposed to whatever we decide to randomly give them + # this sees through amnesiac, so the amnesiac's final role counts as their role + # also, if we're the only person with that role, say so and don't allow a second vision + people = set(var.ROLES[role]) | set(p for p, r in var.AMNESIAC_ROLES.items() if p in pl and r == role) + if len(people) == 1 and nick in people: + pm(cli, nick, "You receive a vision that are the only \u0002{0}\u0002.".format(role)) + var.PRAYED[nick][0] = 2 + debuglog("{0} ({1}) PRAY {2} - ONLY".format(nick, var.get_role(nick), role)) + chk_nightdone(cli) + return + # select someone with the role that we haven't looked at before for this particular role + prevlist = (p for p, rl in var.PRAYED[nick][3] if role in rl) + for p in prevlist: + people.discard(p) + if len(people) == 0 or (len(people) == 1 and nick in people): + pm(cli, nick, "You receive a vision that there are no other \u0002{0}\u0002.".format(var.plural(role))) + var.PRAYED[nick][0] = 2 + debuglog("{0} ({1}) PRAY {2} - NO OTHER".format(nick, var.get_role(nick), role)) + chk_nightdone(cli) + return + target = random.choice(people) + var.PRAYED[nick][0] = 1 + var.PRAYED[nick][1] = target + var.PRAYED[nick][2] = role + var.PRAYED[nick][3][target].add(role) + half = random.sample(pl, math.ceil(len(pl) / 2)) + if target not in half: + half[0] = target + if len(half) > 1: + msg = "You receive a vision that at least one of these people is a \u0002{0}\u0002: ".format(role) + if len(half) > 2: + msg += "{0}, and {1}.".format(", ".join(half[:-1]), half[-1]) + else: + msg += "{0} and {1}.".format(half[0], half[1]) + pm(cli, nick, msg) + debuglog("{0} ({1}) PRAY {2} ({3}) - HALF".format(nick, var.get_role(nick), role, target)) + if random.random() < var.PROPHET_REVEALED_CHANCE[0]: + pm(cli, target, "You receive a vision that \u0002{0}\u0002 is the prophet!".format(nick)) + debuglog("{0} ({1}) PRAY REVEAL".format(nick, var.get_role(nick), role)) + var.PRAYED[nick][0] = 2 + else: + # only one, go straight to second chance + pm(cli, nick, "You receive a vision that \u0002{0}\u0002 is a \u0002{1}\u0002.".format(target, role)) + debuglog("{0} ({1}) PRAY {2} ({3}) - FULL".format(nick, var.get_role(nick), role, target)) + if random.random() < var.PROPHET_REVEALED_CHANCE[1]: + pm(cli, target, "You receive a vision that \u0002{0}\u0002 is the prophet!".format(nick)) + debuglog("{0} ({1}) PRAY REVEAL".format(nick, var.get_role(nick), role)) + else: + # role is not in this game, this still counts as a successful activation of the power! + pm(cli, nick, "You receive a vision that there are no \u0002{0}\u0002.".format(var.plural(role))) + debuglog("{0} ({1}) PRAY {2} - NONE".format(nick, var.get_role(nick), role)) + var.PRAYED[nick][0] = 2 + elif var.PRAYED[nick][1] is None: + # the previous vision revealed the prophet, so they cannot receive any more visions tonight + pm(cli, nick, "You are still recovering from your previous vision and are unable to receive any more visions tonight.") + return + else: + # continuing a praying session from this night to obtain more information, give them the actual person + var.PRAYED[nick][0] = 2 + pm(cli, nick, "You receive a vision that \u0002{0}\u0002 is a \u0002{1}\u0002.".format(var.PRAYED[nick][1], var.PRAYED[nick][2])) + debuglog("{0} ({1}) PRAY {2} ({3}) - FULL".format(nick, var.get_role(nick), role, target)) + if random.random() < var.PROPHET_REVEALED_CHANCE[1]: + pm(cli, target, "You receive a vision that \u0002{0}\u0002 is the prophet!".format(nick)) + debuglog("{0} ({1}) PRAY REVEAL".format(nick, var.get_role(nick), role)) + + chk_nightdone(cli) @cmd("visit", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("harlot",)) def hvisit(cli, nick, chan, rest):