From edc9ec1ed9be4aaa2777041a1096d52eed90cfdd Mon Sep 17 00:00:00 2001 From: "Vgr E.Barry" Date: Sun, 17 Aug 2014 16:03:14 -0400 Subject: [PATCH] Added nolynch/abstain command Features: - Added var.NO_LYNCH - Tweaked hurry_up to count not-lynching players - Makes day end without a lynch if enough players abstain - Consider pacifists and not-lynching as equal for lynching calculation (in chk_decision and hurry_up) - Add "x players have refrained from voting" in !votes - Added actual nolynch/abstain command, which is a toggle to no_lynch or not - Make !voting automatically remove the player from the no-lynchers - Make !retract remove the player from no-lynchers --- modules/wolfgame.py | 63 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/modules/wolfgame.py b/modules/wolfgame.py index 4ca1967..8fc213e 100644 --- a/modules/wolfgame.py +++ b/modules/wolfgame.py @@ -73,6 +73,7 @@ var.AFTER_FLASTGAME = None var.PHASE = "none" # "join", "day", or "night" var.TIMERS = {} var.DEAD = [] +var.NO_LYNCH = [] var.ORIGINAL_SETTINGS = {} @@ -205,6 +206,7 @@ def reset(cli): var.DEAD = [] var.ROLES = {"person" : []} var.JOINED_THIS_GAME = [] + var.NO_LYNCH = [] reset_settings() @@ -733,6 +735,7 @@ def hurry_up(cli, gameid, change): pl = var.list_players() avail = len(pl) - len(var.WOUNDED) - len(var.ASLEEP) votesneeded = avail // 2 + 1 + not_lynching = len(var.NO_LYNCH) found_dup = False maxfound = (0, "") @@ -745,7 +748,7 @@ def hurry_up(cli, gameid, change): for v in voters: weight = 1 imp_count = sum([1 if p == v else 0 for p in var.IMPATIENT]) - pac_count = sum([1 if p == v else 0 for p in var.PACIFISTS]) + pac_count = sum([1 if p == v else 0 for p in (var.PACIFISTS + var.NO_LYNCH)]) if pac_count > imp_count: weight = 0 # more pacifists than impatience totems elif imp_count == pac_count and v not in var.VOTES[votee]: @@ -794,6 +797,11 @@ def chk_decision(cli, force = ""): pl = var.list_players() avail = len(pl) - len(var.WOUNDED) - len(var.ASLEEP) votesneeded = avail // 2 + 1 + not_lynching = len(var.NO_LYNCH) + len(var.PACIFISTS) + if not_lynching >= votesneeded: + cli.msg(botconfig.CHANNEL, "The villagers have agreed to refrain from lynching for today.") + transition_night(cli) + return aftermessage = None votelist = copy.deepcopy(var.VOTES) for votee, voters in votelist.items(): @@ -804,7 +812,7 @@ def chk_decision(cli, force = ""): for v in voters: weight = 1 imp_count = sum([1 if p == v else 0 for p in var.IMPATIENT]) - pac_count = sum([1 if p == v else 0 for p in var.PACIFISTS]) + pac_count = sum([1 if p == v else 0 for p in (var.PACIFISTS + var.NO_LYNCH)]) if pac_count > imp_count: weight = 0 # more pacifists than impatience totems elif imp_count == pac_count and v not in var.VOTES[votee]: @@ -941,9 +949,14 @@ def show_votes(cli, nick, chan, rest): pl = var.list_players() avail = len(pl) - len(var.WOUNDED) - len(var.ASLEEP) votesneeded = avail // 2 + 1 + not_voting = len(var.NO_LYNCH) + if not_voting == 1: + plural = " has" + else: + plural = "s have" the_message = ('{}: \u0002{}\u0002 players, \u0002{}\u0002 votes ' 'required to lynch, \u0002{}\u0002 players available to ' - 'vote.').format(nick, len(pl), votesneeded, avail) + 'vote. \u0002{}\u0002 player{} refrained from voting.').format(nick, len(pl), votesneeded, avail, not_voting, plural) if chan == nick: pm(cli, nick, the_message) @@ -1563,6 +1576,8 @@ def del_player(cli, nick, forced_death = False, devoice = True, end_game = True, if not var.VOTES[k]: # no more votes on that person del var.VOTES[k] break # can only vote once + if nick in var.NO_LYNCH: + var.NO_LYNCH.remove(nick) if nick in var.WOUNDED: var.WOUNDED.remove(nick) @@ -1963,6 +1978,10 @@ def on_nick(cli, prefix, nick): cli.msg(chan, ("\02{0}\02 has returned to "+ "the village.").format(nick)) + if prefix in var.NO_LYNCH: + var.NO_LYNCH.remove(prefix) + var.NO_LYNCH.append(nick) + def leave(cli, what, nick, why=""): nick, _, _, cloak = parse_nick(nick) @@ -2160,6 +2179,7 @@ def transition_day(cli, gameid=0): var.INVESTIGATED = [] var.WOUNDED = [] var.DAY_START_TIME = datetime.now() + var.NO_LYNCH = [] var.DAY_COUNT += 1 var.FIRST_DAY = (var.DAY_COUNT == 1) havetotem = copy.copy(var.LASTGIVEN) @@ -2585,6 +2605,38 @@ def chk_nightdone(cli): if var.PHASE == "night": # Double check transition_day(cli) +@cmd("nolynch", "no_lynch", "nl", "novote", "abstain") +def no_lynch(cli, nick, chan, rest): + """Allow someone to refrain from voting for the day""" + if chan == botconfig.CHANNEL: + if var.PHASE in ("none", "join"): + cli.notice(nick, "No game is currently running.") + return + elif nick not in var.list_players() or nick in var.DISCONNECTED.keys(): + cli.notice(nick, "You're not currently playing.") + return + if var.PHASE != "day": + cli.notice(nick, "Lynching is only during the day. Please wait patiently for morning.") + return + if nick in var.WOUNDED: + cli.msg(chan, "{0}: You are wounded and resting, thus you are unable to vote for the day.".format(nick)) + return + if nick in var.NO_LYNCH: + var.NO_LYNCH.remove(nick) + cli.msg(chan, "{0}: You chose to vote for someone today. You may use '{1}lynch nick'.".format(nick, botconfig.CMD_CHAR)) + return + candidates = var.VOTES.keys() + for voter in list(candidates): + if nick in var.VOTES[voter]: + var.VOTES[voter].remove(nick) + if not var.VOTES[voter]: + del var.VOTES[voter] + var.NO_LYNCH.append(nick) + cli.msg(chan, "{0}: You chose to vote for nobody.".format(nick)) + + chk_decision(cli) + return + @cmd("lynch", "vote", "v") def vote(cli, nick, chann_, rest): """Use this to vote for a candidate to be lynched""" @@ -2614,6 +2666,8 @@ def vote(cli, nick, chann_, rest): "After recovering, you notice that you are still in your bed. " + "That entire sequence of events must have just been a dream...") return + if nick in var.NO_LYNCH: + var.NO_LYNCH.remove(nick) pl = var.list_players() pl_l = [x.strip().lower() for x in pl] @@ -2920,6 +2974,9 @@ def retract(cli, nick, chann_, rest): cli.notice(nick, ("Lynching is only allowed during the day. "+ "Please wait patiently for morning.")) return + if nick in var.NO_LYNCH: + var.NO_LYNCH.remove(nick) + cli.msg(chan, "\u0002{0}\u0002's mind changed and will vote for today".format(nick)) candidates = var.VOTES.keys() for voter in list(candidates):