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",
"oracle_ability": "whether or not a player is a wolf",
"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_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.",

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))
@event_listener("see", priority=10)
def on_see(evt, var, nick, victim):
if (users._get(victim) in DECEIT) ^ (users._get(nick) in DECEIT): # FIXME
def on_see(evt, var, seer, target):
if (seer in DECEIT) ^ (target in DECEIT):
if evt.data["role"] in var.SEEN_WOLF and evt.data["role"] not in var.SEEN_DEFAULT:
evt.data["role"] = "villager"
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
@event_listener("see")
def on_see(evt, var, nick, victim):
if users._get(victim) in var.ROLES["cursed villager"]: # FIXME
def on_see(evt, var, seer, target):
if target in var.ROLES["cursed villager"]:
evt.data["role"] = "wolf"
@event_listener("wolflist")

View File

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

View File

@ -58,11 +58,11 @@ def investigate(var, wrapper, message):
t2role = var.AMNESIAC_ROLES[target2.nick]
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"]
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"]
# 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
from src.utilities import *
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.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.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
@cmd("see", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("seer", "oracle", "augur"))
def see(cli, nick, chan, rest):
SEEN = setup_variables("seer")
@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."""
role = get_role(nick)
if nick in SEEN:
pm(cli, nick, messages["seer_fail"])
return
victim = get_victim(cli, nick, re.split(" +",rest)[0], False)
if not victim:
if wrapper.source in SEEN:
wrapper.send(messages["seer_fail"])
return
if victim == nick:
pm(cli, nick, messages["no_see_self"])
target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="no_see_self")
if target is None:
return
seer = users._get(nick) # FIXME
target = users._get(victim) # FIXME
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
evt.dispatch(var, "see", seer, target, frozenset({"info", "immediate"}))
if evt.prevent_default:
if not evt.dispatch(var, "see", wrapper.source, target, frozenset({"info", "immediate"})):
return
victim = evt.data["target"].nick
victimrole = get_role(victim)
vrole = victimrole # keep a copy for logging
if role != "augur":
if (victimrole in var.SEEN_WOLF and victimrole not in var.SEEN_DEFAULT):
victimrole = "wolf"
elif victimrole in var.SEEN_DEFAULT:
victimrole = var.DEFAULT_ROLE
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:
victimrole = "villager"
targrole = "villager"
evt = Event("see", {"role": victimrole})
evt.dispatch(var, nick, victim)
victimrole = evt.data["role"]
else:
if victimrole == "amnesiac":
victimrole = var.AMNESIAC_ROLES[victim]
evt = Event("see", {"role": targrole})
evt.dispatch(var, wrapper.source, target)
targrole = evt.data["role"]
evt = Event("investigate", {"role": victimrole})
evt.dispatch(cli, var, nick, victim)
victimrole = evt.data["role"]
wrapper.send(messages["seer_success"].format(target, targrole))
debuglog("{0} (seer) SEE: {1} ({2}) as {3}".format(wrapper.source, target, trole, targrole))
if role == "seer":
pm(cli, nick, (messages["seer_success"]).format(victim, victimrole))
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)
@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()
SEEN.add(wrapper.source)
# 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"
@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:
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)))
@event_listener("see")
def on_see(evt, var, seer, victim):
if victim in WILD_CHILDREN:
def on_see(evt, var, seer, target):
if target.nick in WILD_CHILDREN:
evt.data["role"] = "wild child"
@event_listener("rename_player")