Convert and split seer, oracle and augur in three files with a shared helper

This commit is contained in:
Vgr E. Barry 2018-04-23 15:15:09 -04:00
parent 745a1dc68a
commit 38721fd59b
11 changed files with 244 additions and 166 deletions

View File

@ -463,7 +463,6 @@
"seer_ability": "the role of a player", "seer_ability": "the role of a player",
"oracle_ability": "whether or not a player is a wolf", "oracle_ability": "whether or not a player is a wolf",
"augur_ability": "which team a player is on", "augur_ability": "which team a player is on",
"seer_role_bug": "??? (this is a bug, please report to admins)",
"seer_role_info": "You are {0} \u0002{1}\u0002. It is your job to detect the wolves, you may have a vision once per night. Use \"see <nick>\" to see {2}.", "seer_role_info": "You are {0} \u0002{1}\u0002. It is your job to detect the wolves, you may have a vision once per night. Use \"see <nick>\" to see {2}.",
"seer_simple": "You are {0} \u0002{1}\u0002.", "seer_simple": "You are {0} \u0002{1}\u0002.",
"harlot_info": "You are a \u0002harlot\u0002. You may spend the night with one person per round. If you visit a victim of a wolf, or visit a wolf, you will die. Use \"visit <nick>\" to visit a player or \"pass\" to stay home tonight.", "harlot_info": "You are a \u0002harlot\u0002. You may spend the night with one person per round. If you visit a victim of a wolf, or visit a wolf, you will die. Use \"visit <nick>\" to visit a player or \"pass\" to stay home tonight.",

69
src/roles/_seer_helper.py Normal file
View File

@ -0,0 +1,69 @@
import re
import random
import src.settings as var
from src.utilities import *
from src import users, channels, debuglog, errlog, plog
from src.decorators import cmd, event_listener
from src.containers import UserList, UserSet, UserDict, DefaultUserDict
from src.functions import get_players, get_all_players, get_main_role
from src.messages import messages
from src.events import Event
def setup_variables(rolename):
SEEN = UserSet()
@event_listener("del_player")
def on_del_player(evt, var, user, mainrole, allroles, death_triggers):
SEEN.discard(user)
@event_listener("night_acted")
def on_acted(evt, var, user, actor):
if user in SEEN:
evt.data["acted"] = True
@event_listener("get_special")
def on_get_special(evt, var):
evt.data["special"].update(get_players((rolename,)))
@event_listener("exchange_roles")
def on_exchange(evt, var, actor, target, actor_role, target_role):
if actor_role == rolename and target_role != rolename:
SEEN.discard(actor)
elif target_role == rolename and actor_role != rolename:
SEEN.discard(target)
@event_listener("chk_nightdone")
def on_chk_nightdone(evt, var):
evt.data["actedcount"] += len(SEEN)
evt.data["nightroles"].extend(get_all_players((rolename,)))
@event_listener("transition_night_end", priority=2)
def on_transition_night_end(evt, var):
for seer in get_all_players((rolename,)):
pl = get_players()
random.shuffle(pl)
pl.remove(seer) # remove self from list
a = "a"
if rolename.startswith(("a", "e", "i", "o", "u")):
a = "an"
what = messages[rolename + "_ability"]
to_send = "seer_role_info"
if seer.prefers_simple():
to_send = "seer_simple"
seer.send(messages[to_send].format(a, rolename, what), "Players: " + ", ".join(p.nick for p in pl), sep="\n")
@event_listener("begin_day")
def on_begin_day(evt, var):
SEEN.clear()
@event_listener("reset")
def on_reset(evt, var):
SEEN.clear()
return SEEN
# vim: set sw=4 expandtab:

View File

@ -225,8 +225,8 @@ def give_totem(var, wrapper, target, prefix, tags, role, msg):
return UserList((target, orig_target)) return UserList((target, orig_target))
@event_listener("see", priority=10) @event_listener("see", priority=10)
def on_see(evt, var, nick, victim): def on_see(evt, var, seer, target):
if (users._get(victim) in DECEIT) ^ (users._get(nick) in DECEIT): # FIXME if (seer in DECEIT) ^ (target in DECEIT):
if evt.data["role"] in var.SEEN_WOLF and evt.data["role"] not in var.SEEN_DEFAULT: if evt.data["role"] in var.SEEN_WOLF and evt.data["role"] not in var.SEEN_DEFAULT:
evt.data["role"] = "villager" evt.data["role"] = "villager"
else: else:

53
src/roles/augur.py Normal file
View File

@ -0,0 +1,53 @@
import re
import random
import src.settings as var
from src.utilities import *
from src import users, channels, debuglog, errlog, plog
from src.decorators import command, event_listener
from src.containers import UserList, UserSet, UserDict, DefaultUserDict
from src.functions import get_players, get_all_players, get_main_role, get_target
from src.messages import messages
from src.events import Event
from src.roles._seer_helper import setup_variables
SEEN = setup_variables("augur")
@command("see", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("augur",))
def see(var, wrapper, message):
"""Use your paranormal powers to determine the role or alignment of a player."""
if wrapper.source in SEEN:
wrapper.send(messages["seer_fail"])
return
target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="no_see_self")
if target is None:
return
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
if not evt.dispatch(var, "identify", wrapper.source, target, frozenset({"info", "immediate"})):
return
target = evt.data["target"]
targrole = get_main_role(target)
trole = targrole # keep a copy for logging
if targrole == "amnesiac":
targrole = var.AMNESIAC_ROLES[target.nick]
evt = Event("investigate", {"role": targrole})
evt.dispatch(var, wrapper.source, target)
targrole = evt.data["role"]
aura = "blue"
if targrole in var.WOLFTEAM_ROLES:
aura = "red"
elif targrole in var.TRUE_NEUTRAL_ROLES:
aura = "grey"
wrapper.send(messages["augur_success"].format(target, aura))
debuglog("{0} (augur) SEE: {1} ({2}) as {3} ({4} aura)".format(wrapper.source, target, trole, targrole, aura))
SEEN.add(wrapper.source)
# vim: set sw=4 expandtab:

View File

@ -13,8 +13,8 @@ from src.messages import messages
from src.events import Event from src.events import Event
@event_listener("see") @event_listener("see")
def on_see(evt, var, nick, victim): def on_see(evt, var, seer, target):
if users._get(victim) in var.ROLES["cursed villager"]: # FIXME if target in var.ROLES["cursed villager"]:
evt.data["role"] = "wolf" evt.data["role"] = "wolf"
@event_listener("wolflist") @event_listener("wolflist")

View File

@ -5,47 +5,42 @@ import random
import src.settings as var import src.settings as var
from src.utilities import * from src.utilities import *
from src import users, channels, debuglog, errlog, plog from src import users, channels, debuglog, errlog, plog
from src.functions import get_players, get_all_players from src.functions import get_players, get_all_players, get_main_role, get_target
from src.decorators import cmd, event_listener from src.decorators import command, event_listener
from src.containers import UserList, UserSet, UserDict, DefaultUserDict from src.containers import UserList, UserSet, UserDict, DefaultUserDict
from src.messages import messages from src.messages import messages
from src.events import Event from src.events import Event
INVESTIGATED = set() INVESTIGATED = UserSet()
@cmd("id", chan=False, pm=True, playing=True, silenced=True, phases=("day",), roles=("detective",)) @command("id", chan=False, pm=True, playing=True, silenced=True, phases=("day",), roles=("detective",))
def investigate(cli, nick, chan, rest): def investigate(var, wrapper, message):
"""Investigate a player to determine their exact role.""" """Investigate a player to determine their exact role."""
if nick in INVESTIGATED: if wrapper.source in INVESTIGATED:
pm(cli, nick, messages["already_investigated"]) wrapper.send(messages["already_investigated"])
return
victim = get_victim(cli, nick, re.split(" +",rest)[0], False)
if not victim:
return return
if victim == nick: target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="no_investigate_self")
pm(cli, nick, messages["no_investigate_self"]) if target is None:
return return
det = users._get(nick) # FIXME
target = users._get(victim) # FIXME
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True}) evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
evt.dispatch(var, "identify", det, target, frozenset({"info", "immediate"})) if not evt.dispatch(var, "identify", wrapper.source, target, frozenset({"info", "immediate"})):
if evt.prevent_default:
return return
victim = evt.data["target"].nick
vrole = get_role(victim)
if vrole == "amnesiac":
vrole = var.AMNESIAC_ROLES[victim]
evt = Event("investigate", {"role": vrole}) target = evt.data["target"]
evt.dispatch(cli, var, nick, victim) targrole = get_main_role(target)
vrole = evt.data["role"]
INVESTIGATED.add(nick) if targrole == "amnesiac":
pm(cli, nick, (messages["investigate_success"]).format(victim, vrole)) targrole = var.AMNESIAC_ROLES[target.nick]
debuglog("{0} ({1}) ID: {2} ({3})".format(nick, get_role(nick), victim, vrole))
evt = Event("investigate", {"role": targrole})
evt.dispatch(var, wrapper.source, target)
targrole = evt.data["role"]
INVESTIGATED.add(wrapper.source)
wrapper.send(messages["investigate_success"].format(target, targrole))
debuglog("{0} (detective) ID: {1} ({2})".format(wrapper.source, target, targrole))
if random.random() < var.DETECTIVE_REVEALED_CHANCE: # a 2/5 chance (should be changeable in settings) if random.random() < var.DETECTIVE_REVEALED_CHANCE: # a 2/5 chance (should be changeable in settings)
# The detective's identity is compromised! # The detective's identity is compromised!
@ -56,18 +51,17 @@ def investigate(cli, nick, chan, rest):
else: else:
wcroles = var.WOLF_ROLES | {"traitor"} wcroles = var.WOLF_ROLES | {"traitor"}
mass_privmsg(cli, list_players(wcroles), messages["detective_reveal"].format(nick)) wolves = get_all_players(wcroles)
debuglog("{0} ({1}) PAPER DROP".format(nick, get_role(nick))) if wolves:
for wolf in wolves:
wolf.queue_message(messages["detective_reveal"].format(wrapper.source))
wolf.send_messages()
@event_listener("rename_player") debuglog("{0} (detective) PAPER DROP".format(wrapper.source))
def on_rename(evt, var, prefix, nick):
if prefix in INVESTIGATED:
INVESTIGATED.remove(prefix)
INVESTIGATED.add(nick)
@event_listener("del_player") @event_listener("del_player")
def on_del_player(evt, var, user, mainrole, allroles, death_triggers): def on_del_player(evt, var, user, mainrole, allroles, death_triggers):
INVESTIGATED.discard(user.nick) INVESTIGATED.discard(user)
@event_listener("get_special") @event_listener("get_special")
def on_get_special(evt, var): def on_get_special(evt, var):
@ -76,9 +70,9 @@ def on_get_special(evt, var):
@event_listener("exchange_roles") @event_listener("exchange_roles")
def on_exchange(evt, var, actor, target, actor_role, target_role): def on_exchange(evt, var, actor, target, actor_role, target_role):
if actor_role == "detective" and target_role != "detective": if actor_role == "detective" and target_role != "detective":
INVESTIGATED.discard(actor.nick) INVESTIGATED.discard(actor)
elif target_role == "detective" and actor_role != "detective": elif target_role == "detective" and actor_role != "detective":
INVESTIGATED.discard(target.nick) INVESTIGATED.discard(target)
@event_listener("transition_night_end", priority=2) @event_listener("transition_night_end", priority=2)
def on_transition_night_end(evt, var): def on_transition_night_end(evt, var):

View File

@ -58,11 +58,11 @@ def investigate(var, wrapper, message):
t2role = var.AMNESIAC_ROLES[target2.nick] t2role = var.AMNESIAC_ROLES[target2.nick]
evt = Event("investigate", {"role": t1role}) evt = Event("investigate", {"role": t1role})
evt.dispatch(wrapper.client, var, wrapper.source.nick, target1.nick) # FIXME evt.dispatch(var, wrapper.source, target1)
t1role = evt.data["role"] t1role = evt.data["role"]
evt = Event("investigate", {"role": t2role}) evt = Event("investigate", {"role": t2role})
evt.dispatch(wrapper.client, var, wrapper.source.nick, target2.nick) # FIXME evt.dispatch(var, wrapper.source, target2)
t2role = evt.data["role"] t2role = evt.data["role"]
# FIXME: make a standardized way of getting team affiliation, and make # FIXME: make a standardized way of getting team affiliation, and make

55
src/roles/oracle.py Normal file
View File

@ -0,0 +1,55 @@
import re
import random
import src.settings as var
from src.utilities import *
from src import users, channels, debuglog, errlog, plog
from src.decorators import command, event_listener
from src.containers import UserList, UserSet, UserDict, DefaultUserDict
from src.functions import get_players, get_all_players, get_main_role, get_target
from src.messages import messages
from src.events import Event
from src.roles._seer_helper import setup_variables
SEEN = setup_variables("oracle")
@command("see", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("oracle",))
def see(var, wrapper, message):
"""Use your paranormal powers to determine the role or alignment of a player."""
if wrapper.source in SEEN:
wrapper.send(messages["seer_fail"])
return
target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="no_see_self")
if target is None:
return
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
if not evt.dispatch(var, "see", wrapper.source, target, frozenset({"info", "immediate"})):
return
target = evt.data["target"]
targrole = get_main_role(target)
trole = targrole # keep a copy for logging
if targrole in var.SEEN_WOLF and targrole not in var.SEEN_DEFAULT:
targrole = "wolf"
elif targrole in var.SEEN_DEFAULT:
targrole = var.DEFAULT_ROLE
if var.DEFAULT_SEEN_AS_VILL:
targrole = "villager"
evt = Event("see", {"role": targrole})
evt.dispatch(var, wrapper.source, target)
targrole = evt.data["role"]
iswolf = False
if targrole in var.SEEN_WOLF and targrole not in var.SEEN_DEFAULT:
iswolf = True
wrapper.send(messages["oracle_success"].format(target, "" if iswolf else "\u0002not\u0002 ", "\u0002" if iswolf else ""))
debuglog("{0} (oracle) SEE: {1} ({2}) (Wolf: {3})".format(wrapper.source, target, trole, str(iswolf)))
SEEN.add(wrapper.source)
# vim: set sw=4 expandtab:

View File

@ -4,141 +4,49 @@ import random
import src.settings as var import src.settings as var
from src.utilities import * from src.utilities import *
from src import users, channels, debuglog, errlog, plog from src import users, channels, debuglog, errlog, plog
from src.decorators import cmd, event_listener from src.decorators import command, event_listener
from src.containers import UserList, UserSet, UserDict, DefaultUserDict from src.containers import UserList, UserSet, UserDict, DefaultUserDict
from src.functions import get_players, get_all_players, get_main_role from src.functions import get_players, get_all_players, get_main_role, get_target
from src.messages import messages from src.messages import messages
from src.events import Event from src.events import Event
SEEN = set() from src.roles._seer_helper import setup_variables
# FIXME: this needs to be split into seer.py, oracle.py, and augur.py SEEN = setup_variables("seer")
@cmd("see", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("seer", "oracle", "augur"))
def see(cli, nick, chan, rest): @command("see", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("seer",))
def see(var, wrapper, message):
"""Use your paranormal powers to determine the role or alignment of a player.""" """Use your paranormal powers to determine the role or alignment of a player."""
role = get_role(nick) if wrapper.source in SEEN:
if nick in SEEN: wrapper.send(messages["seer_fail"])
pm(cli, nick, messages["seer_fail"])
return
victim = get_victim(cli, nick, re.split(" +",rest)[0], False)
if not victim:
return return
if victim == nick: target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="no_see_self")
pm(cli, nick, messages["no_see_self"]) if target is None:
return return
seer = users._get(nick) # FIXME
target = users._get(victim) # FIXME
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True}) evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
evt.dispatch(var, "see", seer, target, frozenset({"info", "immediate"})) if not evt.dispatch(var, "see", wrapper.source, target, frozenset({"info", "immediate"})):
if evt.prevent_default:
return return
victim = evt.data["target"].nick
victimrole = get_role(victim)
vrole = victimrole # keep a copy for logging
if role != "augur": target = evt.data["target"]
if (victimrole in var.SEEN_WOLF and victimrole not in var.SEEN_DEFAULT): targrole = get_main_role(target)
victimrole = "wolf" trole = targrole # keep a copy for logging
elif victimrole in var.SEEN_DEFAULT:
victimrole = var.DEFAULT_ROLE
if var.DEFAULT_SEEN_AS_VILL:
victimrole = "villager"
evt = Event("see", {"role": victimrole}) if targrole in var.SEEN_WOLF and targrole not in var.SEEN_DEFAULT:
evt.dispatch(var, nick, victim) targrole = "wolf"
victimrole = evt.data["role"] elif targrole in var.SEEN_DEFAULT:
else: targrole = var.DEFAULT_ROLE
if victimrole == "amnesiac": if var.DEFAULT_SEEN_AS_VILL:
victimrole = var.AMNESIAC_ROLES[victim] targrole = "villager"
evt = Event("investigate", {"role": victimrole}) evt = Event("see", {"role": targrole})
evt.dispatch(cli, var, nick, victim) evt.dispatch(var, wrapper.source, target)
victimrole = evt.data["role"] targrole = evt.data["role"]
if role == "seer": wrapper.send(messages["seer_success"].format(target, targrole))
pm(cli, nick, (messages["seer_success"]).format(victim, victimrole)) debuglog("{0} (seer) SEE: {1} ({2}) as {3}".format(wrapper.source, target, trole, targrole))
debuglog("{0} ({1}) SEE: {2} ({3}) as {4}".format(nick, role, victim, vrole, victimrole))
elif role == "oracle":
iswolf = False
if (victimrole in var.SEEN_WOLF and victimrole not in var.SEEN_DEFAULT):
iswolf = True
pm(cli, nick, (messages["oracle_success"]).format(victim, "" if iswolf else "\u0002not\u0002 ", "\u0002" if iswolf else ""))
debuglog("{0} ({1}) SEE: {2} ({3}) (Wolf: {4})".format(nick, role, victim, vrole, str(iswolf)))
elif role == "augur":
aura = "blue"
if victimrole in var.WOLFTEAM_ROLES:
aura = "red"
elif victimrole in var.TRUE_NEUTRAL_ROLES:
aura = "grey"
pm(cli, nick, (messages["augur_success"]).format(victim, aura))
debuglog("{0} ({1}) SEE: {2} ({3}) as {4} ({5} aura)".format(nick, role, victim, vrole, victimrole, aura))
SEEN.add(nick) SEEN.add(wrapper.source)
@event_listener("rename_player")
def on_rename(evt, var, prefix, nick):
if prefix in SEEN:
SEEN.remove(prefix)
SEEN.add(nick)
@event_listener("del_player")
def on_del_player(evt, var, user, mainrole, allroles, death_triggers):
SEEN.discard(user.nick)
@event_listener("night_acted")
def on_acted(evt, var, user, actor):
if user.nick in SEEN:
evt.data["acted"] = True
@event_listener("get_special")
def on_get_special(evt, var):
evt.data["special"].update(get_players(("seer", "oracle", "augur")))
@event_listener("exchange_roles")
def on_exchange(evt, var, actor, target, actor_role, target_role):
if actor_role in ("seer", "oracle", "augur"):
SEEN.discard(actor.nick)
@event_listener("chk_nightdone")
def on_chk_nightdone(evt, var):
evt.data["actedcount"] += len(SEEN)
evt.data["nightroles"].extend(get_all_players(("seer", "oracle", "augur")))
@event_listener("transition_night_end", priority=2)
def on_transition_night_end(evt, var):
for seer in get_players(("seer", "oracle", "augur")):
pl = get_players()
random.shuffle(pl)
role = get_main_role(seer)
pl.remove(seer) # remove self from list
a = "a"
if role in ("oracle", "augur"):
a = "an"
if role == "seer":
what = messages["seer_ability"]
elif role == "oracle":
what = messages["oracle_ability"]
elif role == "augur":
what = messages["augur_ability"]
else:
what = messages["seer_role_bug"]
to_send = "seer_role_info"
if seer.prefers_simple():
to_send = "seer_simple"
seer.send(messages[to_send].format(a, role, what), "Players: " + ", ".join(p.nick for p in pl), sep="\n")
@event_listener("begin_day")
def on_begin_day(evt, var):
SEEN.clear()
@event_listener("reset")
def on_reset(evt, var):
SEEN.clear()
# vim: set sw=4 expandtab: # vim: set sw=4 expandtab:

View File

@ -29,7 +29,7 @@ def on_get_final_role(evt, cli, var, nick, role):
evt.data["role"] = "traitor" evt.data["role"] = "traitor"
@event_listener("update_stats", priority=1) @event_listener("update_stats", priority=1)
def on_update_stats1(evt, var, player, mainrole, revealroles, allroles): def on_update_stats1(evt, var, player, mainrole, revealrole, allroles):
if mainrole == var.DEFAULT_ROLE and var.HIDDEN_TRAITOR: if mainrole == var.DEFAULT_ROLE and var.HIDDEN_TRAITOR:
evt.data["possible"].add("traitor") evt.data["possible"].add("traitor")

View File

@ -36,8 +36,8 @@ def choose_idol(cli, nick, chan, rest):
debuglog("{0} (wild child) IDOLIZE: {1} ({2})".format(nick, victim, get_role(victim))) debuglog("{0} (wild child) IDOLIZE: {1} ({2})".format(nick, victim, get_role(victim)))
@event_listener("see") @event_listener("see")
def on_see(evt, var, seer, victim): def on_see(evt, var, seer, target):
if victim in WILD_CHILDREN: if target.nick in WILD_CHILDREN:
evt.data["role"] = "wild child" evt.data["role"] = "wild child"
@event_listener("rename_player") @event_listener("rename_player")