Add deadchat and wolfchat restrictions
This commit is contained in:
parent
9f4b205c72
commit
2127b217b7
@ -62,6 +62,25 @@ QUIET_PREFIX = "" # "" or "~q:"
|
||||
# The bot will automatically toggle those modes of people joining
|
||||
AUTO_TOGGLE_MODES = ""
|
||||
|
||||
# The following is a bitfield, and they can be mixed together
|
||||
# Defaults to none of these, can be changed on a per-game-mode basis
|
||||
|
||||
RESTRICT_WOLFCHAT = 0x00
|
||||
|
||||
### DO NOT CHANGE THESE!
|
||||
### They are for easier code interpretation/modification
|
||||
|
||||
RW_DISABLE_NIGHT = 0x01 # Disable during night (commands are still relayed)
|
||||
RW_DISABLE_DAY = 0x02 # Disable during day (commands are still relayed)
|
||||
RW_ONLY_KILL_CMD = 0x04 # Only relay kill commands when wolfchat is disabled
|
||||
RW_ONLY_SAME_CMD = 0x08 # Only relay commands to other people who have access to the same command
|
||||
RW_WOLVES_ONLY_CHAT = 0x10 # Non-wolves cannot participate in wolfchat (commands still relayed as applicable)
|
||||
RW_NO_INTERACTION = 0x20 # Do not relay commands to/from non-wolves regardless of other settings
|
||||
RW_REM_NON_WOLVES = 0x40 # Remove non-wolves from wolfchat entirely (can be killed, do not count towards wolf win condition, do not show in wolflist, etc.)
|
||||
RW_TRAITOR_NON_WOLF = 0x80 # Consider traitor as a non-wolf for the purposes of the above restrictions (if unset, traitor is treated the same as wolf cub)
|
||||
|
||||
ENABLE_DEADCHAT = True # dead players can communicate with each other
|
||||
|
||||
DYNQUIT_DURING_GAME = False # are dynamic quit messages used while a game is in progress? Note that true will break certain stats scrapers
|
||||
|
||||
GOAT_HERDER = True
|
||||
|
150
src/wolfgame.py
150
src/wolfgame.py
@ -1078,23 +1078,30 @@ def join_timer_handler(cli):
|
||||
else:
|
||||
cli.who(botconfig.CHANNEL)
|
||||
|
||||
@cmd("join", "j", phases=("none", "join"))
|
||||
@cmd("join", "j")
|
||||
def join(cli, nick, chan, rest):
|
||||
"""Either starts a new game of Werewolf or joins an existing game that has not started yet."""
|
||||
if var.ACCOUNTS_ONLY:
|
||||
if nick in var.USERS and (not var.USERS[nick]["account"] or var.USERS[nick]["account"] == "*"):
|
||||
cli.notice(nick, "You are not logged in to NickServ.")
|
||||
return
|
||||
if join_player(cli, nick, chan) and rest and not var.FGAMED:
|
||||
gamemode = rest.lower().split()[0]
|
||||
if gamemode not in var.GAME_MODES.keys():
|
||||
match, _ = complete_match(gamemode, var.GAME_MODES.keys() - {"roles"})
|
||||
if not match:
|
||||
if var.PHASE in ("none", "join"):
|
||||
if var.ACCOUNTS_ONLY:
|
||||
if nick in var.USERS and (not var.USERS[nick]["account"] or var.USERS[nick]["account"] == "*"):
|
||||
cli.notice(nick, "You are not logged in to NickServ.")
|
||||
return
|
||||
gamemode = match
|
||||
if gamemode != "roles":
|
||||
var.GAMEMODE_VOTES[nick] = gamemode
|
||||
cli.msg(chan, "\u0002{0}\u0002 votes for the \u0002{1}\u0002 game mode.".format(nick, gamemode))
|
||||
if join_player(cli, nick, chan) and rest and not var.FGAMED:
|
||||
gamemode = rest.lower().split()[0]
|
||||
if gamemode not in var.GAME_MODES.keys():
|
||||
match, _ = complete_match(gamemode, var.GAME_MODES.keys() - {"roles"})
|
||||
if not match:
|
||||
return
|
||||
gamemode = match
|
||||
if gamemode != "roles":
|
||||
var.GAMEMODE_VOTES[nick] = gamemode
|
||||
cli.msg(chan, "\u0002{0}\u0002 votes for the \u0002{1}\u0002 game mode.".format(nick, gamemode))
|
||||
|
||||
else: # join deadchat
|
||||
if chan == nick and nick not in var.list_players() and nick not in var.DEADCHAT_PLAYERS:
|
||||
mass_privmsg(cli, var.DEADCHAT_PLAYERS, "{0} has joined the dead chat.".format(nick))
|
||||
pm(cli, nick, "You are now in the dead chat. Players: {0}".format(", ".join(var.DEADCHAT_PLAYERS)))
|
||||
var.DEADCHAT_PLAYERS.add(nick)
|
||||
|
||||
def join_player(cli, player, chan, who = None, forced = False):
|
||||
if who is None:
|
||||
@ -1407,12 +1414,18 @@ def stats(cli, nick, chan, rest):
|
||||
if nick == chan:
|
||||
_nick = ""
|
||||
|
||||
if chan == nick and nick in pl and var.get_role(nick) in var.WOLFCHAT_ROLES:
|
||||
badguys = set(var.WOLFCHAT_ROLES)
|
||||
if var.RESTRICT_WOLFCHAT & var.RW_REM_NON_WOLVES:
|
||||
badguys = set(var.WOLF_ROLES)
|
||||
if not var.RESTRICT_WOLFCHAT & var.RW_TRAITOR_NON_WOLF:
|
||||
badguys.update(var.ROLES["traitor"])
|
||||
|
||||
if chan == nick and nick in pl and var.get_role(nick) in badguys:
|
||||
ps = pl[:]
|
||||
random.shuffle(ps)
|
||||
for i, player in enumerate(ps):
|
||||
prole = var.get_role(player)
|
||||
if prole in var.WOLFCHAT_ROLES:
|
||||
if prole in badguys:
|
||||
cursed = ""
|
||||
if player in var.ROLES["cursed villager"]:
|
||||
cursed = "cursed "
|
||||
@ -3646,6 +3659,12 @@ def leave_game(cli, nick, chan, rest):
|
||||
else:
|
||||
population = (" New player count: \u0002{0}\u0002").format(lpl)
|
||||
else:
|
||||
if chan == nick and nick not in var.list_players() and nick in var.DEADCHAT_PLAYERS:
|
||||
var.DEADCHAT_PLAYERS.remove(nick)
|
||||
pm(cli, nick, "You have left the dead chat.")
|
||||
mass_privmsg(cli, var.DEADCHAT_PLAYERS, "{0} has left the dead chat.".format(nick))
|
||||
return
|
||||
|
||||
dur = int(var.START_QUIT_DELAY - (datetime.now() - var.GAME_START_TIME).total_seconds())
|
||||
if var.START_QUIT_DELAY and dur > 0:
|
||||
cli.notice(nick, "The game already started! If you still want to quit, try again in {0} second{1}.".format(dur, "" if dur == 1 else "s"))
|
||||
@ -5235,6 +5254,11 @@ def kill(cli, nick, chan, rest):
|
||||
|
||||
if role in wolfroles:
|
||||
wolfchatwolves = var.list_players(var.WOLFCHAT_ROLES)
|
||||
if var.RESTRICT_WOLFCHAT & var.RW_REM_NON_WOLVES:
|
||||
wolfchatwolves = var.list_players(var.WOLF_ROLES)
|
||||
if not var.RESTRICT_WOLFCHAT & var.RW_TRAITOR_NON_WOLF:
|
||||
wolfchatwolves.extend(var.ROLES["traitor"])
|
||||
|
||||
if victim in wolfchatwolves or victim2 in wolfchatwolves:
|
||||
pm(cli, nick, "You may only kill villagers, not other wolves.")
|
||||
return
|
||||
@ -5275,6 +5299,15 @@ def kill(cli, nick, chan, rest):
|
||||
pm(cli, nick, 'You are angry tonight and may kill a second target. Use "kill <nick1> and <nick2>" to select multiple targets.')
|
||||
|
||||
wolfchatwolves = var.list_players(var.WOLFCHAT_ROLES)
|
||||
if var.RESTRICT_WOLFCHAT & var.RW_ONLY_SAME_CMD:
|
||||
wolfchatwolves = var.list_players(wolfroles)
|
||||
if var.RESTRICT_WOLFCHAT & var.RW_ONLY_KILL_CMD: # bypass the above one if relevant
|
||||
wolfchatwolves = var.list_players(var.WOLFCHAT_ROLES)
|
||||
if var.RESTRICT_WOLFCHAT & (var.RW_NO_INTERACTION | var.RW_REM_NON_WOLVES):
|
||||
wolfchatwolves = var.list_players(var.WOLF_ROLES)
|
||||
if not var.RESTRICT_WOLFCHAT & var.RW_TRAITOR_NON_WOLF:
|
||||
wolfchatwolves.extend(var.ROLES["traitor"])
|
||||
|
||||
if nick in wolfchatwolves:
|
||||
for wolf in wolfchatwolves:
|
||||
if wolf != nick:
|
||||
@ -5383,9 +5416,21 @@ def observe(cli, nick, chan, rest):
|
||||
"to \u0002{0}'s\u0002 house. You will return after "+
|
||||
"collecting your observations when day begins.").format(victim))
|
||||
wolfchatwolves = var.list_players(var.WOLFCHAT_ROLES)
|
||||
wolves = var.list_players(var.WOLF_ROLES)
|
||||
if not var.RESTRICT_WOLFCHAT & var.RW_TRAITOR_NON_WOLF:
|
||||
wolves.extend(var.ROLES["traitor"])
|
||||
if var.RESTRICT_WOLFCHAT & var.RW_ONLY_SAME_CMD:
|
||||
if var.RESTRICT_WOLFCHAT & (var.RW_NO_INTERACTION | var.RW_REM_NON_WOLVES):
|
||||
wolfchatwolves = var.ROLES["werecrow"]
|
||||
else:
|
||||
wolfchatwolves = var.ROLES["werecrow"] | var.ROLES["sorcerer"]
|
||||
if var.RESTRICT_WOLFCHAT & var.RW_ONLY_KILL_CMD:
|
||||
wolfchatwolves = []
|
||||
|
||||
for wolf in wolfchatwolves:
|
||||
if wolf != nick:
|
||||
pm(cli, wolf, "\u0002{0}\u0002 is observing \u0002{1}\u0002.".format(nick, victim))
|
||||
|
||||
elif role == "sorcerer":
|
||||
vrole = var.get_role(victim)
|
||||
if vrole == "amnesiac":
|
||||
@ -5397,6 +5442,7 @@ def observe(cli, nick, chan, rest):
|
||||
else:
|
||||
pm(cli, nick, ("After casting your ritual, you determine that \u0002{0}\u0002 " +
|
||||
"does not have paranormal senses.").format(victim))
|
||||
|
||||
debuglog("{0} ({1}) OBSERVE: {2} ({3})".format(nick, role, victim, var.get_role(victim)))
|
||||
chk_nightdone(cli)
|
||||
|
||||
@ -5649,7 +5695,13 @@ def bite_cmd(cli, nick, chan, rest):
|
||||
vrole = var.get_role(victim)
|
||||
actual = choose_target(nick, victim)
|
||||
|
||||
if vrole in var.WOLFCHAT_ROLES:
|
||||
wolfchatwolves = var.list_players(var.WOLFCHAT_ROLES)
|
||||
if var.RESTRICT_WOLFCHAT & (var.RW_NO_INTERACTION | var.RW_REM_NON_WOLVES):
|
||||
wolfchatwolves = var.list_players(var.WOLF_ROLES)
|
||||
if not var.RESTRICT_WOLFCHAT & var.RW_TRAITOR_NON_WOLF:
|
||||
wolfchatwolves.extend(var.ROLES["traitor"])
|
||||
|
||||
if victim in wolfchatwolves:
|
||||
pm(cli, nick, "You may not bite other wolves.")
|
||||
return
|
||||
|
||||
@ -5662,8 +5714,11 @@ def bite_cmd(cli, nick, chan, rest):
|
||||
del var.KILLS[nick]
|
||||
|
||||
pm(cli, nick, "You have chosen to bite \u0002{0}\u0002.".format(victim))
|
||||
wolfchat = var.list_players(var.WOLFCHAT_ROLES)
|
||||
for wolf in wolfchat:
|
||||
if var.RESTRICT_WOLFCHAT & var.RW_ONLY_SAME_CMD:
|
||||
wolfchatwolves = var.ROLES["alpha wolf"]
|
||||
if var.RESTRICT_WOLFCHAT & var.RW_ONLY_KILL_CMD:
|
||||
wolfchatwolves = []
|
||||
for wolf in wolfchatwolves:
|
||||
if wolf != nick:
|
||||
pm(cli, wolf, "\u0002{0}\u0002 has chosen to bite \u0002{1}\u0002.".format(nick, victim))
|
||||
|
||||
@ -5869,7 +5924,11 @@ def hex_target(cli, nick, chan, rest):
|
||||
if check_exchange(cli, nick, victim):
|
||||
return
|
||||
vrole = var.get_role(victim)
|
||||
if vrole in var.WOLFCHAT_ROLES:
|
||||
wolfchatwolves = var.list_players(var.WOLFCHAT_ROLES)
|
||||
if var.RESTRICT_WOLFCHAT & var.RW_REM_NON_WOLVES:
|
||||
wolfchatwolves = []
|
||||
|
||||
if victim in wolfchatwolves:
|
||||
pm(cli, nick, "Hexing another wolf would be a waste.")
|
||||
return
|
||||
|
||||
@ -5879,7 +5938,12 @@ def hex_target(cli, nick, chan, rest):
|
||||
|
||||
pm(cli, nick, "You have cast a hex on \u0002{0}\u0002.".format(victim))
|
||||
|
||||
wolfchatwolves = var.list_players(var.WOLFCHAT_ROLES)
|
||||
if var.RESTRICT_WOLFCHAT & (var.RW_ONLY_KILL_CMD | var.RW_NO_INTERACTION | var.RW_REM_NON_WOLVES):
|
||||
wolfchatwolves = []
|
||||
elif var.RESTRICT_WOLFCHAT & var.RW_ONLY_SAME_CMD:
|
||||
wolfchatwolves = var.ROLES["hag"]
|
||||
else:
|
||||
wolfchatwolves = var.list_players(var.WOLFCHAT_ROLES)
|
||||
for wolf in wolfchatwolves:
|
||||
if wolf != nick:
|
||||
pm(cli, wolf, "\u0002{0}\u0002 has cast a hex on \u0002{1}\u0002.".format(nick, victim))
|
||||
@ -6130,30 +6194,54 @@ def mass_privmsg(cli, targets, msg, notice=False, privmsg=False):
|
||||
|
||||
@cmd("", chan=False, pm=True)
|
||||
def relay(cli, nick, chan, rest):
|
||||
"""Let the wolves talk to each other through the bot"""
|
||||
"""Wolfchat and Deadchat"""
|
||||
if rest.startswith("\u0001PING"):
|
||||
cli.notice(nick, rest)
|
||||
return
|
||||
if var.PHASE not in ("night", "day"):
|
||||
return
|
||||
|
||||
if nick in var.list_players() and nick in getattr(var, "IDLE_WARNED_PM", ()):
|
||||
pl = var.list_players()
|
||||
|
||||
if nick in pl and nick in getattr(var, "IDLE_WARNED_PM", ()):
|
||||
cli.msg(nick, ("\u0002You have been idling in {0} for a while. Please say something in {0} "
|
||||
"or you will be declared dead.\u0002").format(botconfig.CHANNEL))
|
||||
var.IDLE_WARNED_PM.add(nick)
|
||||
|
||||
badguys = var.list_players(var.WOLFCHAT_ROLES)
|
||||
if len(badguys) > 1:
|
||||
if nick in badguys:
|
||||
badguys.remove(nick) # remove self from list
|
||||
wolves = var.list_players(var.WOLF_ROLES)
|
||||
|
||||
if nick not in pl:
|
||||
if var.ENABLE_DEADCHAT and nick in var.DEADCHAT_PLAYERS:
|
||||
if rest.startswith("\u0001ACTION"):
|
||||
rest = rest[7:-1]
|
||||
mass_privmsg(cli, [guy for guy in badguys
|
||||
if guy in var.PLAYERS], "* \u0002{0}\u0002{1}".format(nick, rest))
|
||||
mass_privmsg(cli, [x for x in var.DEADCHAT_PLAYERS if x != nick],
|
||||
"* \u0002{0}\u0002{1}".format(nick, rest))
|
||||
else:
|
||||
mass_privmsg(cli, [guy for guy in badguys
|
||||
if guy in var.PLAYERS], "\u0002{0}\u0002 says: {1}".format(nick, rest))
|
||||
mass_privmsg(cli, [x for x in var.DEADCHAT_PLAYERS if x != nick],
|
||||
"\u0002{0}\u0002 says: {1}".format(nick, rest))
|
||||
|
||||
elif nick in badguys and len(badguys) > 1:
|
||||
# handle wolfchat toggles
|
||||
if not var.RESTRICT_WOLFCHAT & var.RW_TRAITOR_NON_WOLF:
|
||||
wolves.extend(var.ROLES["traitor"])
|
||||
if var.PHASE == "night" and var.RESTRICT_WOLFCHAT & var.RW_DISABLE_NIGHT:
|
||||
return
|
||||
elif var.PHASE == "day" and var.RESTRICT_WOLFCHAT & var.RW_DISABLE_DAY:
|
||||
return
|
||||
elif nick not in wolves and var.RESTRICT_WOLFCHAT & var.RW_WOLVES_ONLY_CHAT:
|
||||
return
|
||||
elif nick not in wolves and var.RESTRICT_WOLFCHAT & var.RW_REM_NON_WOLVES:
|
||||
return
|
||||
|
||||
badguys.remove(nick)
|
||||
if rest.startswith("\u0001ACTION"):
|
||||
rest = rest[7:-1]
|
||||
mass_privmsg(cli, [x for x in badguys if x in var.PLAYERS],
|
||||
"* \u0002{0}\u0002{1}".format(nick, rest))
|
||||
else:
|
||||
mass_privmsg(cli, [x for x in badguys if x in var.PLAYERS],
|
||||
"\u0002{0}\u0002 says: {1}".format(nick, rest))
|
||||
|
||||
def transition_night(cli):
|
||||
if var.PHASE == "night":
|
||||
@ -7085,6 +7173,8 @@ def start(cli, nick, chan, forced = False, restart = ""):
|
||||
var.BLESSED = set()
|
||||
var.PRIESTS = set()
|
||||
|
||||
var.DEADCHAT_PLAYERS = set()
|
||||
|
||||
for role, count in addroles.items():
|
||||
if role in var.TEMPLATE_RESTRICTIONS.keys():
|
||||
var.ROLES[role] = [None] * count
|
||||
|
Loading…
x
Reference in New Issue
Block a user