Add sleepy events (mostly done)

Add back in var.DYING so that events can use it, also added del_player
event.
This commit is contained in:
skizzerz 2015-10-30 01:09:24 -05:00
parent 8dd2bf4e56
commit 9b23f38b65
2 changed files with 104 additions and 29 deletions

View File

@ -4,6 +4,7 @@ import random
import math
import src.settings as var
import botconfig
from src import events
@ -756,3 +757,67 @@ class SleepyMode(GameMode):
self.TEMPLATE_RESTRICTIONS["prophet"] = frozenset(self.ROLE_GUIDE.keys()) - {"priest", "blessed villager", "prophet"}
# this ensures that village drunk will always receive the gunner template
self.TEMPLATE_RESTRICTIONS["gunner"] = frozenset(self.ROLE_GUIDE.keys()) - {"village drunk", "cursed villager", "gunner"}
# disable wolfchat
self.RESTRICT_WOLFCHAT = 0x0f
self.having_nightmare = None
def startup(self):
events.add_listener("dullahan_targets", self.dullahan_targets)
events.add_listener("transition_night_begin", self.setup_nightmare)
events.add_listener("chk_nightdone", self.prolong_night)
events.add_listener("transition_day_begin", self.nightmare_kill)
events.add_listener("del_player", self.happy_fun_times)
def teardown(self):
events.remove_listener("dullahan_targets", self.dullahan_targets)
events.remove_listener("transition_night_begin", self.setup_nightmare)
events.remove_listener("chk_nightdone", self.prolong_night)
events.remove_listener("transition_day_begin", self.nightmare_kill)
events.remove_listener("del_player", self.happy_fun_times)
def dullahan_targets(self, evt, cli, var, dullahans, max_targets):
for dull in dullahans:
evt.data["targets"][dull] = set(var.ROLES["priest"])
def setup_nightmares(self, evt, cli, var):
if random.random() < 1/5:
self.having_nightmare = random.choice(var.list_players())
else:
self.having_nightmare = None
def prolong_night(self, evt, cli, var):
if self.having_nightmare is not None:
evt.data["actedcount"] = -1
def nightmare_kill(self, evt, cli, var):
if self.having_nightmare is not None:
var.DYING.add(self.having_nightmare)
def happy_fun_times(self, evt, cli, var, nick, nickrole, nicktpls, forced_death, end_game, death_triggers, killer_role, deadlist, original, ismain, refresh_pl):
if death_triggers:
if nickrole == "priest":
pl = evt.data["pl"]
seers = [p for p in var.list_players("seer") if p in pl]
harlots = [p for p in var.list_players("harlot") if p in pl]
cultists = [p for p in var.list_players("cultist") if p in pl]
total = sum(map(len, (seers, harlots, cultists)))
if total > 0:
cli.msg(botconfig.CHANNEL, ("The sky suddenly darkens as a thunderstorm appears from nowhere. The bell on the newly-abandoned church starts ringing " +
"in sinister tones, managing to perform \u0002{0}\u0002 tolls before the building is struck repeatedly by lightning, "
"setting it alight in a raging inferno...").format(total))
for seer in seers:
var.ROLE["seer"].remove(seer)
var.ROLE["doomsayer"].add(seer)
# TODO: message
for harlot in harlots:
var.ROLE["harlot"].remove(harlot)
var.ROLE["succubus"].add(harlot)
# TODO: message
for cultist in cultists:
var.ROLE["cultist"].remove(cultist)
var.ROLE["demoniac"].add(cultist)
# TODO: message
# NOTE: chk_win is called by del_player, don't need to call it here even though this has a chance of ending game
# vim: set expandtab:sw=4:ts=4:

View File

@ -3174,6 +3174,10 @@ def del_player(cli, nick, forced_death=False, devoice=True, end_game=True, death
cli.msg(botconfig.CHANNEL, tmsg)
debuglog(nick, "(mad scientist) KILL FAIL")
pl = refresh_pl(pl)
event = Event("del_player", {"pl": pl})
event.dispatch(cli, var, nick, nickrole, nicktpls, forced_death, end_game, death_triggers and var.PHASE in ("night", "day"), killer_role, deadlist, original, ismain, refresh_pl)
if devoice and (var.PHASE != "night" or not var.DEVOICE_DURING_NIGHT):
cmode.append(("-v", nick))
deadchat.append(nick)
@ -3719,6 +3723,9 @@ def rename_player(cli, prefix, nick):
if prefix in var.ENTRANCED_DYING:
var.ENTRANCED_DYING.remove(prefix)
var.ENTRANCED_DYING.add(nick)
if prefix in var.DYING:
var.DYING.remove(prefix)
var.DYING.add(nick)
if prefix in var.SICK:
var.SICK.remove(prefix)
var.SICK.add(nick)
@ -3944,6 +3951,7 @@ def begin_day(cli):
var.MISDIRECTED = copy.copy(var.TOBEMISDIRECTED)
var.ACTIVE_PROTECTIONS = defaultdict(list)
var.ENTRANCED_DYING = set()
var.DYING = set()
msg = ('The villagers must now vote for whom to lynch. '+
'Use "{0}lynch <nick>" to cast your vote. {1} votes '+
@ -4258,7 +4266,6 @@ def transition_day(cli, gameid=0):
onlybywolves.discard(monster)
wolfghostvictims = []
dead_vigilantes = set()
for k, d in var.OTHER_KILLS.items():
victims.append(d)
onlybywolves.discard(d)
@ -4267,9 +4274,10 @@ def transition_day(cli, gameid=0):
wolfghostvictims.append(d)
if k in var.ROLES["vigilante"]:
if var.get_role(d) not in var.WOLF_ROLES | {"monster", "succubus", "demoniac"}:
victims.append(k)
onlybywolves.discard(k)
dead_vigilantes.add(k)
var.DYING.add(k)
for v in var.ENTRANCED_DYING:
var.DYING.add(v)
# clear list so that it doesn't pm hunter / ghost about being able to kill again
var.OTHER_KILLS = {}
@ -4279,7 +4287,7 @@ def transition_day(cli, gameid=0):
onlybywolves.discard(d)
killers[d].append(k)
for player in var.ENTRANCED_DYING:
for player in var.DYING:
victims.append(player)
onlybywolves.discard(player)
@ -4352,7 +4360,7 @@ def transition_day(cli, gameid=0):
pl = var.list_players()
for v in pl:
if v in victims_set:
if v in var.ENTRANCED_DYING | dead_vigilantes:
if v in var.DYING:
continue # bypass protections
numkills = victims.count(v)
numtotems = var.PROTECTED.count(v)
@ -4440,7 +4448,7 @@ def transition_day(cli, gameid=0):
# can play. Harlot visiting wolf doesn't play special events if they die via other means since
# that assumes they die en route to the wolves (and thus don't shoot/give out gun/etc.)
for v in victims_set:
if v in var.ENTRANCED_DYING | dead_vigilantes:
if v in var.DYING:
victims.append(v)
elif v in var.ROLES["bodyguard"] and var.GUARDED.get(v) in victims_set:
vappend.append(v)
@ -4867,31 +4875,32 @@ def chk_nightdone(cli):
elif tu[1] < var.NIGHT_COUNT - 1:
nightroles.append(tc)
event = Event("chk_nightdone", {})
event = Event("chk_nightdone", {"actedcount": actedcount, "nightroles": nightroles})
event.dispatch(cli, var)
if var.PHASE == "night" and actedcount >= len(nightroles):
# check for assassins that have not yet targeted
# must be handled separately because assassin only acts on nights when their target is dead
# and silenced assassin shouldn't add to actedcount
for ass in var.ROLES["assassin"]:
if ass not in var.TARGETED.keys() | var.SILENCED:
return
if not var.DISEASED_WOLVES:
# flatten var.KILLS
kills = set()
for ls in var.KILLS.values():
if not isinstance(ls, str):
kills.update(ls)
else:
kills.add(ls)
# check if wolves are actually agreeing
# allow len(kills) == 0 through as that means that crow was dumb and observed instead
# of killingor alpha wolf was alone and chose to bite instead of kill
if not var.ANGRY_WOLVES and len(kills) > 1:
return
elif var.ANGRY_WOLVES and (len(kills) == 1 or len(kills) > 2):
return
if not event.prevent_default:
# check for assassins that have not yet targeted
# must be handled separately because assassin only acts on nights when their target is dead
# and silenced assassin shouldn't add to actedcount
for ass in var.ROLES["assassin"]:
if ass not in var.TARGETED.keys() | var.SILENCED:
return
if not var.DISEASED_WOLVES:
# flatten var.KILLS
kills = set()
for ls in var.KILLS.values():
if not isinstance(ls, str):
kills.update(ls)
else:
kills.add(ls)
# check if wolves are actually agreeing
# allow len(kills) == 0 through as that means that crow was dumb and observed instead
# of killingor alpha wolf was alone and chose to bite instead of kill
if not var.ANGRY_WOLVES and len(kills) > 1:
return
elif var.ANGRY_WOLVES and (len(kills) == 1 or len(kills) > 2):
return
for x, t in var.TIMERS.items():
t[0].cancel()
@ -7840,6 +7849,7 @@ def start(cli, nick, chan, forced = False, restart = ""):
var.CONSECRATING = set()
var.ENTRANCED = set()
var.ENTRANCED_DYING = set()
var.DYING = set()
var.PRAYED = {}
var.SICK = set()
var.DULLAHAN_TARGETS = {}