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
This commit is contained in:
Vgr E.Barry 2014-08-17 16:03:14 -04:00 committed by nyuszika7h
parent c823689dbd
commit edc9ec1ed9

View File

@ -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):