Part 2 of 2
And as thus we sat in darkness, Each one busy in his prayers, “We are lost!” the captain shouted, As he staggered down the stairs. But his little daughter whispered, As she took his icy hand, “Isn’t God upon the ocean, Just the same as on the land?” Then we kissed the little maiden, And we spoke in better cheer; And we anchored safe in harbor When the morn was shining clear.
This commit is contained in:
parent
69f72499ef
commit
dbad8d1f09
@ -432,7 +432,7 @@
|
|||||||
"day_lasted": "Day lasted \u0002{0:0>2}:{1:0>2}\u0002. ",
|
"day_lasted": "Day lasted \u0002{0:0>2}:{1:0>2}\u0002. ",
|
||||||
"fallen_angel_turn": "As the moonlight filters through your window, you think back on the past few days. Your power has been growing, but the villagers you protect subconsciously detected your shift and have been keeping more distant from you. Grinning with wicked resolve, you vow to show them what fools they have been as you take to the skies once more with an unholy vengeance. Soon they will know true fear.",
|
"fallen_angel_turn": "As the moonlight filters through your window, you think back on the past few days. Your power has been growing, but the villagers you protect subconsciously detected your shift and have been keeping more distant from you. Grinning with wicked resolve, you vow to show them what fools they have been as you take to the skies once more with an unholy vengeance. Soon they will know true fear.",
|
||||||
"bitten_turn": "As you prepare for bed, you watch in horror as your body starts growing a coat of fur! Sudden realization hits you as you grin with your now muzzled face; that mysterious bite earlier slowly changed you into a werewolf! You feel bigger, stronger, faster, and ready to seize the night as you stealthily exit your home and search for the rest of your pack...",
|
"bitten_turn": "As you prepare for bed, you watch in horror as your body starts growing a coat of fur! Sudden realization hits you as you grin with your now muzzled face; that mysterious bite earlier slowly changed you into a werewolf! You feel bigger, stronger, faster, and ready to seize the night as you stealthily exit your home and search for the rest of your pack...",
|
||||||
"bitten_turn_wolfchat": "\u0002{0}\u0002 is now a \u0002{1}\u0002!",
|
"wolfchat_new_member": "\u0002{0}\u0002 is now a \u0002{1}\u0002!",
|
||||||
"amnesia_clear": "Your amnesia clears and you now remember that you are a{0} \u0002{1}\u0002!",
|
"amnesia_clear": "Your amnesia clears and you now remember that you are a{0} \u0002{1}\u0002!",
|
||||||
"amnesia_wolfchat": "\u0002{0}\u0002 is now a \u0002{1}\u0002!",
|
"amnesia_wolfchat": "\u0002{0}\u0002 is now a \u0002{1}\u0002!",
|
||||||
"wolf_notify": "You are a \u0002wolf\u0002. It is your job to kill all the villagers. Use \"kill <nick>\" to kill a villager.",
|
"wolf_notify": "You are a \u0002wolf\u0002. It is your job to kill all the villagers. Use \"kill <nick>\" to kill a villager.",
|
||||||
|
@ -24,12 +24,12 @@ class Event:
|
|||||||
self.name = name
|
self.name = name
|
||||||
self.data = data
|
self.data = data
|
||||||
|
|
||||||
def dispatch(self, *args):
|
def dispatch(self, *args, **kwargs):
|
||||||
if self.name not in EVENT_CALLBACKS:
|
if self.name not in EVENT_CALLBACKS:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
for item in list(EVENT_CALLBACKS[self.name]):
|
for item in list(EVENT_CALLBACKS[self.name]):
|
||||||
item[1](self, *args)
|
item[1](self, *args, **kwargs)
|
||||||
if self.stop_processing:
|
if self.stop_processing:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -1055,14 +1055,63 @@ class MaelstromMode(GameMode):
|
|||||||
self.LOVER_WINS_WITH_FOOL = True
|
self.LOVER_WINS_WITH_FOOL = True
|
||||||
self.MAD_SCIENTIST_SKIPS_DEAD_PLAYERS = 0 # always make it happen
|
self.MAD_SCIENTIST_SKIPS_DEAD_PLAYERS = 0 # always make it happen
|
||||||
self.ALWAYS_PM_ROLE = True
|
self.ALWAYS_PM_ROLE = True
|
||||||
|
# clone is pointless in this mode
|
||||||
|
# dullahan doesn't really work in this mode either, if enabling anyway special logic to determine kill list
|
||||||
|
# needs to be added above for when dulls are added during the game
|
||||||
|
# matchmaker is conditionally enabled during night 1 only
|
||||||
|
self.roles = list(var.ROLE_GUIDE.keys() - var.TEMPLATE_RESTRICTIONS.keys() - {"amnesiac", "clone", "dullahan", "matchmaker"})
|
||||||
|
|
||||||
def startup(self):
|
def startup(self):
|
||||||
events.add_listener("role_attribution", self.role_attribution)
|
events.add_listener("role_attribution", self.role_attribution)
|
||||||
events.add_listener("transition_night_begin", self.transition_night_begin)
|
events.add_listener("transition_night_begin", self.transition_night_begin)
|
||||||
|
events.add_listener("join", self.on_join)
|
||||||
|
|
||||||
def teardown(self):
|
def teardown(self):
|
||||||
events.remove_listener("role_attribution", self.role_attribution)
|
events.remove_listener("role_attribution", self.role_attribution)
|
||||||
events.remove_listener("transition_night_begin", self.transition_night_begin)
|
events.remove_listener("transition_night_begin", self.transition_night_begin)
|
||||||
|
events.remove_listener("join", self.on_join)
|
||||||
|
|
||||||
|
def on_join(self, evt, cli, var, nick, chan, rest, forced=False):
|
||||||
|
if var.PHASE != "day" or (nick != chan and chan != botconfig.CHANNEL):
|
||||||
|
return
|
||||||
|
if not forced and evt.data["join_player"](cli, nick, botconfig.CHANNEL, sanity=False):
|
||||||
|
self._on_join(cli, var, nick, chan)
|
||||||
|
evt.prevent_default = True
|
||||||
|
elif forced:
|
||||||
|
# in fjoin, handle this differently
|
||||||
|
jp = evt.data["join_player"]
|
||||||
|
evt.data["join_player"] = lambda cli, nick, chan, who=None, forced=False: jp(cli, nick, chan, who=who, forced=forced, sanity=False) and self._on_join(cli, var, nick, chan)
|
||||||
|
|
||||||
|
def _on_join(self, cli, var, nick, chan):
|
||||||
|
role = random.choice(self.roles)
|
||||||
|
var.ROLES[role].add(nick)
|
||||||
|
var.ORIGINAL_ROLES[role].add(nick)
|
||||||
|
var.FINAL_ROLES[nick] = role
|
||||||
|
if role == "doctor":
|
||||||
|
lpl = len(var.list_players())
|
||||||
|
var.DOCTORS[nick] = math.ceil(var.DOCTOR_IMMUNIZATION_MULTIPLIER * lpl)
|
||||||
|
# let them know their role
|
||||||
|
# FIXME: this is fugly
|
||||||
|
from src.decorators import COMMANDS
|
||||||
|
COMMANDS["myrole"][0].caller(cli, nick, chan, "")
|
||||||
|
# if they're a wolfchat role, alert the other wolves
|
||||||
|
if role in var.WOLFCHAT_ROLES:
|
||||||
|
relay_wolfchat_command(cli, nick, messages["wolfchat_new_member"].format(nick, role), var.WOLFCHAT_ROLES, is_wolf_command=True, is_kill_command=True)
|
||||||
|
# TODO: make this part of !myrole instead, no reason we can't give out wofllist in that
|
||||||
|
wolves = var.list_players(var.WOLFCHAT_ROLES)
|
||||||
|
pl = var.list_players()
|
||||||
|
random.shuffle(pl)
|
||||||
|
pl.remove(nick)
|
||||||
|
for i, player in enumerate(pl):
|
||||||
|
prole = var.get_role(player)
|
||||||
|
if prole in var.WOLFCHAT_ROLES:
|
||||||
|
cursed = ""
|
||||||
|
if player in var.ROLES["cursed villager"]:
|
||||||
|
cursed = "cursed "
|
||||||
|
pl[i] = "\u0002{0}\u0002 ({1}{2})".format(player, cursed, prole)
|
||||||
|
elif player in var.ROLES["cursed villager"]:
|
||||||
|
pl[i] = player + " (cursed)"
|
||||||
|
pm(cli, nick, "Players: " + ", ".join(pl))
|
||||||
|
|
||||||
def role_attribution(self, evt, cli, chk_win_conditions, var, villagers):
|
def role_attribution(self, evt, cli, chk_win_conditions, var, villagers):
|
||||||
self.chk_win_conditions = chk_win_conditions
|
self.chk_win_conditions = chk_win_conditions
|
||||||
@ -1112,13 +1161,10 @@ class MaelstromMode(GameMode):
|
|||||||
|
|
||||||
wolves = var.WOLF_ROLES - {"wolf cub"}
|
wolves = var.WOLF_ROLES - {"wolf cub"}
|
||||||
addroles[random.choice(list(wolves))] += 1 # make sure there's at least one wolf role
|
addroles[random.choice(list(wolves))] += 1 # make sure there's at least one wolf role
|
||||||
# clone is pointless in this mode
|
roles = self.roles[:]
|
||||||
# dullahan doesn't really work in this mode either, if enabling anyway special logic to determine kill list
|
if do_templates:
|
||||||
# needs to be added above for when dulls are added during the game
|
|
||||||
roles = list(var.ROLE_GUIDE.keys() - var.TEMPLATE_RESTRICTIONS.keys() - {"amnesiac", "clone", "dullahan"})
|
|
||||||
if not do_templates:
|
|
||||||
# mm only works night 1, do_templates is also only true n1
|
# mm only works night 1, do_templates is also only true n1
|
||||||
roles.remove("matchmaker")
|
self.roles.append("matchmaker")
|
||||||
while lpl:
|
while lpl:
|
||||||
addroles[random.choice(roles)] += 1
|
addroles[random.choice(roles)] += 1
|
||||||
lpl -= 1
|
lpl -= 1
|
||||||
|
@ -1118,6 +1118,14 @@ def deadchat_pref(cli, nick, chan, rest):
|
|||||||
@cmd("join", "j", pm=True)
|
@cmd("join", "j", pm=True)
|
||||||
def join(cli, nick, chan, rest):
|
def join(cli, nick, chan, rest):
|
||||||
"""Either starts a new game of Werewolf or joins an existing game that has not started yet."""
|
"""Either starts a new game of Werewolf or joins an existing game that has not started yet."""
|
||||||
|
# keep this and the event in fjoin() in sync
|
||||||
|
evt = Event("join", {
|
||||||
|
"join_player": join_player,
|
||||||
|
"join_deadchat": join_deadchat,
|
||||||
|
"vote_gamemode": vote_gamemode
|
||||||
|
})
|
||||||
|
if not evt.dispatch(cli, var, nick, chan, rest, forced=False):
|
||||||
|
return
|
||||||
if var.PHASE in ("none", "join"):
|
if var.PHASE in ("none", "join"):
|
||||||
if chan == nick:
|
if chan == nick:
|
||||||
return
|
return
|
||||||
@ -1125,25 +1133,25 @@ def join(cli, nick, chan, rest):
|
|||||||
if nick in var.USERS and (not var.USERS[nick]["account"] or var.USERS[nick]["account"] == "*"):
|
if nick in var.USERS and (not var.USERS[nick]["account"] or var.USERS[nick]["account"] == "*"):
|
||||||
cli.notice(nick, messages["not_logged_in"])
|
cli.notice(nick, messages["not_logged_in"])
|
||||||
return
|
return
|
||||||
if join_player(cli, nick, chan) and rest:
|
if evt.data["join_player"](cli, nick, chan) and rest:
|
||||||
vote_gamemode(cli, nick, chan, rest.lower().split()[0], False)
|
evt.data["vote_gamemode"](cli, nick, chan, rest.lower().split()[0], False)
|
||||||
|
|
||||||
else: # join deadchat
|
else: # join deadchat
|
||||||
if chan == nick and nick != botconfig.NICK:
|
if chan == nick and nick != botconfig.NICK:
|
||||||
join_deadchat(cli, nick)
|
evt.data["join_deadchat"](cli, nick)
|
||||||
|
|
||||||
def join_player(cli, player, chan, who = None, forced = False):
|
def join_player(cli, player, chan, who=None, forced=False, *, sanity=True):
|
||||||
if who is None:
|
if who is None:
|
||||||
who = player
|
who = player
|
||||||
|
|
||||||
pl = var.list_players()
|
pl = var.list_players()
|
||||||
if chan != botconfig.CHANNEL:
|
if chan != botconfig.CHANNEL:
|
||||||
return
|
return False
|
||||||
|
|
||||||
if not var.OPPED:
|
if not var.OPPED:
|
||||||
cli.notice(who, messages["bot_not_opped"].format(chan))
|
cli.notice(who, messages["bot_not_opped"].format(chan))
|
||||||
cli.msg("ChanServ", "op " + botconfig.CHANNEL)
|
cli.msg("ChanServ", "op " + botconfig.CHANNEL)
|
||||||
return
|
return False
|
||||||
|
|
||||||
if player in var.USERS:
|
if player in var.USERS:
|
||||||
ident = var.USERS[player]["ident"]
|
ident = var.USERS[player]["ident"]
|
||||||
@ -1155,7 +1163,7 @@ def join_player(cli, player, chan, who = None, forced = False):
|
|||||||
host = None
|
host = None
|
||||||
acc = None
|
acc = None
|
||||||
else:
|
else:
|
||||||
return # Not normal
|
return False # Not normal
|
||||||
if not acc or acc == "*" or var.DISABLE_ACCOUNTS:
|
if not acc or acc == "*" or var.DISABLE_ACCOUNTS:
|
||||||
acc = None
|
acc = None
|
||||||
|
|
||||||
@ -1174,11 +1182,10 @@ def join_player(cli, player, chan, who = None, forced = False):
|
|||||||
cli.notice(who, messages["stasis"].format(
|
cli.notice(who, messages["stasis"].format(
|
||||||
"you are" if player == who else player + " is", stasis,
|
"you are" if player == who else player + " is", stasis,
|
||||||
"s" if stasis != 1 else ""))
|
"s" if stasis != 1 else ""))
|
||||||
return
|
return False
|
||||||
|
|
||||||
cmodes = [("+v", player)]
|
cmodes = [("+v", player)]
|
||||||
if var.PHASE == "none":
|
if var.PHASE == "none":
|
||||||
|
|
||||||
if var.AUTO_TOGGLE_MODES and player in var.USERS and var.USERS[player]["modes"]:
|
if var.AUTO_TOGGLE_MODES and player in var.USERS and var.USERS[player]["modes"]:
|
||||||
for mode in var.USERS[player]["modes"]:
|
for mode in var.USERS[player]["modes"]:
|
||||||
cmodes.append(("-"+mode, player))
|
cmodes.append(("-"+mode, player))
|
||||||
@ -1210,13 +1217,16 @@ def join_player(cli, player, chan, who = None, forced = False):
|
|||||||
|
|
||||||
elif player in pl:
|
elif player in pl:
|
||||||
cli.notice(who, messages["already_playing"].format("You" if who == player else "They"))
|
cli.notice(who, messages["already_playing"].format("You" if who == player else "They"))
|
||||||
return True
|
# if we're not doing insane stuff, return True so that one can use !join to vote for a game mode
|
||||||
|
# even if they are already joined. If we ARE doing insane stuff, return False to indicate that
|
||||||
|
# the player was not successfully joined by this call.
|
||||||
|
return sanity
|
||||||
elif len(pl) >= var.MAX_PLAYERS:
|
elif len(pl) >= var.MAX_PLAYERS:
|
||||||
cli.notice(who, messages["too_many_players"])
|
cli.notice(who, messages["too_many_players"])
|
||||||
return
|
return False
|
||||||
elif var.PHASE != "join":
|
elif sanity and var.PHASE != "join":
|
||||||
cli.notice(who, messages["game_already_running"])
|
cli.notice(who, messages["game_already_running"])
|
||||||
return
|
return False
|
||||||
else:
|
else:
|
||||||
if acc is not None and not botconfig.DEBUG_MODE:
|
if acc is not None and not botconfig.DEBUG_MODE:
|
||||||
for user in pl:
|
for user in pl:
|
||||||
@ -1228,7 +1238,6 @@ def join_player(cli, player, chan, who = None, forced = False):
|
|||||||
cli.notice(who, msg.format(user, "their", ""))
|
cli.notice(who, msg.format(user, "their", ""))
|
||||||
return
|
return
|
||||||
|
|
||||||
var.ROLES["person"].add(player)
|
|
||||||
var.ALL_PLAYERS.append(player)
|
var.ALL_PLAYERS.append(player)
|
||||||
if not is_fake_nick(player) or not botconfig.DEBUG_MODE:
|
if not is_fake_nick(player) or not botconfig.DEBUG_MODE:
|
||||||
if var.AUTO_TOGGLE_MODES and var.USERS[player]["modes"]:
|
if var.AUTO_TOGGLE_MODES and var.USERS[player]["modes"]:
|
||||||
@ -1238,6 +1247,13 @@ def join_player(cli, player, chan, who = None, forced = False):
|
|||||||
var.USERS[player]["modes"] = set()
|
var.USERS[player]["modes"] = set()
|
||||||
mass_mode(cli, cmodes, [])
|
mass_mode(cli, cmodes, [])
|
||||||
cli.msg(chan, messages["player_joined"].format(player, len(pl) + 1))
|
cli.msg(chan, messages["player_joined"].format(player, len(pl) + 1))
|
||||||
|
if not sanity:
|
||||||
|
# Abandon Hope All Ye Who Enter Here
|
||||||
|
leave_deadchat(cli, player)
|
||||||
|
var.SPECTATING_DEADCHAT.discard(player)
|
||||||
|
var.SPECTATING_WOLFCHAT.discard(player)
|
||||||
|
return True
|
||||||
|
var.ROLES["person"].add(player)
|
||||||
if not is_fake_nick(player):
|
if not is_fake_nick(player):
|
||||||
hostmask = ident + "@" + host
|
hostmask = ident + "@" + host
|
||||||
if hostmask not in var.JOINED_THIS_GAME and (not acc or acc not in var.JOINED_THIS_GAME_ACCS):
|
if hostmask not in var.JOINED_THIS_GAME and (not acc or acc not in var.JOINED_THIS_GAME_ACCS):
|
||||||
@ -1287,9 +1303,17 @@ def kill_join(cli, chan):
|
|||||||
var.AFTER_FLASTGAME = None
|
var.AFTER_FLASTGAME = None
|
||||||
|
|
||||||
|
|
||||||
@cmd("fjoin", admin_only=True, phases=("none", "join"))
|
@cmd("fjoin", admin_only=True)
|
||||||
def fjoin(cli, nick, chan, rest):
|
def fjoin(cli, nick, chan, rest):
|
||||||
"""Forces someone to join a game."""
|
"""Forces someone to join a game."""
|
||||||
|
# keep this and the event in def join() in sync
|
||||||
|
evt = Event("join", {
|
||||||
|
"join_player": join_player,
|
||||||
|
"join_deadchat": join_deadchat,
|
||||||
|
"vote_gamemode": vote_gamemode
|
||||||
|
})
|
||||||
|
if not evt.dispatch(cli, var, nick, chan, rest, forced=True):
|
||||||
|
return
|
||||||
noticed = False
|
noticed = False
|
||||||
fake = False
|
fake = False
|
||||||
if not var.OPPED:
|
if not var.OPPED:
|
||||||
@ -1297,7 +1321,7 @@ def fjoin(cli, nick, chan, rest):
|
|||||||
cli.msg("ChanServ", "op " + botconfig.CHANNEL)
|
cli.msg("ChanServ", "op " + botconfig.CHANNEL)
|
||||||
return
|
return
|
||||||
if not rest.strip():
|
if not rest.strip():
|
||||||
join_player(cli, nick, chan, forced=True)
|
evt.data["join_player"](cli, nick, chan, forced=True)
|
||||||
|
|
||||||
for tojoin in re.split(" +",rest):
|
for tojoin in re.split(" +",rest):
|
||||||
tojoin = tojoin.strip()
|
tojoin = tojoin.strip()
|
||||||
@ -1309,7 +1333,7 @@ def fjoin(cli, nick, chan, rest):
|
|||||||
break
|
break
|
||||||
fake = True
|
fake = True
|
||||||
for i in range(int(first), int(last)+1):
|
for i in range(int(first), int(last)+1):
|
||||||
join_player(cli, str(i), chan, forced=True, who=nick)
|
evt.data["join_player"](cli, str(i), chan, forced=True, who=nick)
|
||||||
continue
|
continue
|
||||||
if not tojoin:
|
if not tojoin:
|
||||||
continue
|
continue
|
||||||
@ -1330,7 +1354,7 @@ def fjoin(cli, nick, chan, rest):
|
|||||||
elif botconfig.DEBUG_MODE:
|
elif botconfig.DEBUG_MODE:
|
||||||
fake = True
|
fake = True
|
||||||
if tojoin != botconfig.NICK:
|
if tojoin != botconfig.NICK:
|
||||||
join_player(cli, tojoin, chan, forced=True, who=nick)
|
evt.data["join_player"](cli, tojoin, chan, forced=True, who=nick)
|
||||||
else:
|
else:
|
||||||
cli.notice(nick, messages["not_allowed"])
|
cli.notice(nick, messages["not_allowed"])
|
||||||
if fake:
|
if fake:
|
||||||
@ -6636,7 +6660,7 @@ def transition_night(cli):
|
|||||||
var.ROLES[chumprole].remove(chump)
|
var.ROLES[chumprole].remove(chump)
|
||||||
var.ROLES[newrole].add(chump)
|
var.ROLES[newrole].add(chump)
|
||||||
var.FINAL_ROLES[chump] = newrole
|
var.FINAL_ROLES[chump] = newrole
|
||||||
relay_wolfchat_command(cli, chump, messages["bitten_turn_wolfchat"].format(chump, newrole), var.WOLF_ROLES, is_wolf_command=True, is_kill_command=True)
|
relay_wolfchat_command(cli, chump, messages["wolfchat_new_member"].format(chump, newrole), var.WOLF_ROLES, is_wolf_command=True, is_kill_command=True)
|
||||||
|
|
||||||
# convert amnesiac
|
# convert amnesiac
|
||||||
if var.NIGHT_COUNT == var.AMNESIAC_NIGHTS:
|
if var.NIGHT_COUNT == var.AMNESIAC_NIGHTS:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user