Overhaul succubus (first pass)
This commit is contained in:
parent
5331cda68f
commit
810d2ba3cc
@ -753,7 +753,6 @@
|
|||||||
"dullahan_die_success": "Before dying, \u0002{0}\u0002 snaps a whip made of a human spine at \u0002{1}\u0002, killing them. The village mourns the loss of a{2} \u0002{3}\u0002.",
|
"dullahan_die_success": "Before dying, \u0002{0}\u0002 snaps a whip made of a human spine at \u0002{1}\u0002, killing them. The village mourns the loss of a{2} \u0002{3}\u0002.",
|
||||||
"dullahan_die_success_noreveal": "Before dying, \u0002{0}\u0002 snaps a whip made of a human spine at \u0002{1}\u0002, killing them.",
|
"dullahan_die_success_noreveal": "Before dying, \u0002{0}\u0002 snaps a whip made of a human spine at \u0002{1}\u0002, killing them.",
|
||||||
"entranced_revert_win": "You are no longer entranced. \u0002Your win conditions have reset to normal.\u0002",
|
"entranced_revert_win": "You are no longer entranced. \u0002Your win conditions have reset to normal.\u0002",
|
||||||
"succubus_die_kill": "As the last remaining succubus dies, a foul curse causes {0} to wither away and die in front of the astonished village.",
|
|
||||||
"player_sick": "You woke up today not feeling very well, you think it best to stay home for the remainder of the day and night.",
|
"player_sick": "You woke up today not feeling very well, you think it best to stay home for the remainder of the day and night.",
|
||||||
"consecrating_no_vote": "You are consecrating someone today and cannot participate in the vote.",
|
"consecrating_no_vote": "You are consecrating someone today and cannot participate in the vote.",
|
||||||
"illness_no_vote": "You are staying home due to your illness and cannot participate in the vote.",
|
"illness_no_vote": "You are staying home due to your illness and cannot participate in the vote.",
|
||||||
@ -763,7 +762,6 @@
|
|||||||
"blessed_notify_target": "You suddenly feel very safe.",
|
"blessed_notify_target": "You suddenly feel very safe.",
|
||||||
"consecrate_fail": "\u0002{0}\u0002 is not currently playing or is not dead.",
|
"consecrate_fail": "\u0002{0}\u0002 is not currently playing or is not dead.",
|
||||||
"consecrate_success": "You have consecrated the body of \u0002{0}\u0002.",
|
"consecrate_success": "You have consecrated the body of \u0002{0}\u0002.",
|
||||||
"no_acting_on_succubus": "You may not {0} a succubus.",
|
|
||||||
"coin_toss": "\u0002{0}\u0002 tosses a coin into the air...",
|
"coin_toss": "\u0002{0}\u0002 tosses a coin into the air...",
|
||||||
"coin_land": "The coin lands on \u0002{0}\u0002.",
|
"coin_land": "The coin lands on \u0002{0}\u0002.",
|
||||||
"coin_choices": [
|
"coin_choices": [
|
||||||
|
@ -48,14 +48,13 @@ brokentotem = set() # type: Set[users.User]
|
|||||||
# 1. Expand var.TOTEM_ORDER and upate var.TOTEM_CHANCES to account for the new width
|
# 1. Expand var.TOTEM_ORDER and upate var.TOTEM_CHANCES to account for the new width
|
||||||
# 2. Add the role to var.ROLE_GUIDE
|
# 2. Add the role to var.ROLE_GUIDE
|
||||||
# 3. Add the role to whatever other holding vars are necessary based on what it does
|
# 3. Add the role to whatever other holding vars are necessary based on what it does
|
||||||
# 4. Setup initial variables and events with setup_variables(rolename, knows_totem, get_tags)
|
# 4. Setup initial variables and events with setup_variables(rolename, knows_totem)
|
||||||
# knows_totem is a bool and keyword-only. get_tags is a function in the form get_tags(var, totem)
|
# knows_totem is a bool and keyword-only
|
||||||
# and should return a set
|
|
||||||
# 5. Implement custom events if the role does anything else beyond giving totems.
|
# 5. Implement custom events if the role does anything else beyond giving totems.
|
||||||
#
|
#
|
||||||
# Modifying this file to add new totems or new shaman roles is generally never required
|
# Modifying this file to add new totems or new shaman roles is generally never required
|
||||||
|
|
||||||
def setup_variables(rolename, *, knows_totem, get_tags):
|
def setup_variables(rolename, *, knows_totem):
|
||||||
"""Setup role variables and shared events."""
|
"""Setup role variables and shared events."""
|
||||||
TOTEMS = UserDict() # type: Dict[users.User, str]
|
TOTEMS = UserDict() # type: Dict[users.User, str]
|
||||||
LASTGIVEN = UserDict() # type: Dict[users.User, users.User]
|
LASTGIVEN = UserDict() # type: Dict[users.User, users.User]
|
||||||
@ -178,14 +177,6 @@ def setup_variables(rolename, *, knows_totem, get_tags):
|
|||||||
evt.data["target_messages"].append(messages["shaman_totem"].format(actor_totem))
|
evt.data["target_messages"].append(messages["shaman_totem"].format(actor_totem))
|
||||||
TOTEMS[target] = actor_totem
|
TOTEMS[target] = actor_totem
|
||||||
|
|
||||||
@event_listener("succubus_visit")
|
|
||||||
def on_succubus_visit(evt, var, succubus, target):
|
|
||||||
if target in SHAMANS and SHAMANS[target][1] in get_all_players(("succubus",)):
|
|
||||||
tags = get_tags(var, TOTEMS[target])
|
|
||||||
if "beneficial" not in tags:
|
|
||||||
target.send(messages["retract_totem_succubus"].format(SHAMANS[target][1]))
|
|
||||||
del SHAMANS[target]
|
|
||||||
|
|
||||||
if knows_totem:
|
if knows_totem:
|
||||||
@event_listener("myrole")
|
@event_listener("myrole")
|
||||||
def on_myrole(evt, var, user):
|
def on_myrole(evt, var, user):
|
||||||
@ -206,16 +197,14 @@ def get_totem_target(var, wrapper, message, lastgiven):
|
|||||||
|
|
||||||
return target
|
return target
|
||||||
|
|
||||||
def give_totem(var, wrapper, target, prefix, tags, role, msg):
|
def give_totem(var, wrapper, target, prefix, role, msg):
|
||||||
"""Give a totem to a player. Return the value of SHAMANS[user]."""
|
"""Give a totem to a player. Return the value of SHAMANS[user]."""
|
||||||
|
|
||||||
orig_target = target
|
orig_target = target
|
||||||
orig_role = get_main_role(orig_target)
|
orig_role = get_main_role(orig_target)
|
||||||
|
|
||||||
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True},
|
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
||||||
action="give a totem{0} to".format(msg))
|
if not evt.dispatch(var, wrapper.source, target):
|
||||||
|
|
||||||
if not evt.dispatch(var, "totem", wrapper.source, target, frozenset(tags)):
|
|
||||||
return
|
return
|
||||||
|
|
||||||
target = evt.data["target"]
|
target = evt.data["target"]
|
||||||
|
@ -41,7 +41,7 @@ def guard(cli, nick, chan, rest):
|
|||||||
|
|
||||||
# self-guard ignores luck/misdirection/exchange totem
|
# self-guard ignores luck/misdirection/exchange totem
|
||||||
evt = Event("targeted_command", {"target": target, "misdirection": (angel is not target), "exchange": (angel is not target)})
|
evt = Event("targeted_command", {"target": target, "misdirection": (angel is not target), "exchange": (angel is not target)})
|
||||||
if not evt.dispatch(var, "guard", angel, target, frozenset({"beneficial"})):
|
if not evt.dispatch(var, angel, target):
|
||||||
return
|
return
|
||||||
victim = evt.data["target"].nick
|
victim = evt.data["target"].nick
|
||||||
GUARDED[nick] = victim
|
GUARDED[nick] = victim
|
||||||
|
@ -27,7 +27,7 @@ def target(var, wrapper, message):
|
|||||||
return
|
return
|
||||||
|
|
||||||
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
||||||
if not evt.dispatch(var, "target", wrapper.source, target, frozenset({"detrimental"})):
|
if not evt.dispatch(var, wrapper.source, target):
|
||||||
return
|
return
|
||||||
target = evt.data["target"]
|
target = evt.data["target"]
|
||||||
|
|
||||||
@ -132,17 +132,6 @@ def on_del_player(evt, var, player, mainrole, allroles, death_triggers):
|
|||||||
evt.params.del_player(target, end_game=False, killer_role=mainrole, deadlist=evt.params.deadlist, original=evt.params.original, ismain=False)
|
evt.params.del_player(target, end_game=False, killer_role=mainrole, deadlist=evt.params.deadlist, original=evt.params.original, ismain=False)
|
||||||
evt.data["pl"] = evt.params.refresh_pl(aevt.data["pl"])
|
evt.data["pl"] = evt.params.refresh_pl(aevt.data["pl"])
|
||||||
|
|
||||||
@event_listener("succubus_visit")
|
|
||||||
def on_succubus_visit(evt, var, actor, target):
|
|
||||||
if target in TARGETED and TARGETED[target] in get_all_players(("succubus",)):
|
|
||||||
msg = messages["no_target_succubus"].format(TARGETED[target])
|
|
||||||
del TARGETED[target]
|
|
||||||
if target in get_all_players(("village drunk",)):
|
|
||||||
victim = random.choice(list(get_all_players() - get_all_players(("succubus",)) - {target}))
|
|
||||||
msg += messages["drunk_target"].format(victim)
|
|
||||||
TARGETED[target] = victim
|
|
||||||
target.send(msg)
|
|
||||||
|
|
||||||
@event_listener("myrole")
|
@event_listener("myrole")
|
||||||
def on_myrole(evt, var, user):
|
def on_myrole(evt, var, user):
|
||||||
if user in get_all_players(("assassin",)):
|
if user in get_all_players(("assassin",)):
|
||||||
|
@ -26,7 +26,7 @@ def see(var, wrapper, message):
|
|||||||
return
|
return
|
||||||
|
|
||||||
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
||||||
if not evt.dispatch(var, "identify", wrapper.source, target, frozenset({"info", "immediate"})):
|
if not evt.dispatch(var, wrapper.source, target):
|
||||||
return
|
return
|
||||||
|
|
||||||
target = evt.data["target"]
|
target = evt.data["target"]
|
||||||
|
@ -15,10 +15,7 @@ from src.events import Event
|
|||||||
|
|
||||||
from src.roles._shaman_helper import setup_variables, get_totem_target, give_totem
|
from src.roles._shaman_helper import setup_variables, get_totem_target, give_totem
|
||||||
|
|
||||||
def get_tags(var, totem):
|
TOTEMS, LASTGIVEN, SHAMANS = setup_variables("crazed shaman", knows_totem=False)
|
||||||
return set()
|
|
||||||
|
|
||||||
TOTEMS, LASTGIVEN, SHAMANS = setup_variables("crazed shaman", knows_totem=False, get_tags=get_tags)
|
|
||||||
|
|
||||||
@command("give", "totem", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("crazed shaman",))
|
@command("give", "totem", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("crazed shaman",))
|
||||||
def crazed_shaman_totem(var, wrapper, message):
|
def crazed_shaman_totem(var, wrapper, message):
|
||||||
@ -28,9 +25,7 @@ def crazed_shaman_totem(var, wrapper, message):
|
|||||||
if not target:
|
if not target:
|
||||||
return
|
return
|
||||||
|
|
||||||
totem = TOTEMS[wrapper.source]
|
SHAMANS[wrapper.source] = give_totem(var, wrapper, target, prefix="You", role="crazed shaman", msg="")
|
||||||
|
|
||||||
SHAMANS[wrapper.source] = give_totem(var, wrapper, target, prefix="You", tags=get_tags(var, totem), role="crazed shaman", msg="")
|
|
||||||
|
|
||||||
@event_listener("player_win")
|
@event_listener("player_win")
|
||||||
def on_player_win(evt, var, user, role, winner, survived):
|
def on_player_win(evt, var, user, role, winner, survived):
|
||||||
@ -47,16 +42,11 @@ def on_transition_day_begin(evt, var):
|
|||||||
if shaman in LASTGIVEN:
|
if shaman in LASTGIVEN:
|
||||||
if LASTGIVEN[shaman] in ps:
|
if LASTGIVEN[shaman] in ps:
|
||||||
ps.remove(LASTGIVEN[shaman])
|
ps.remove(LASTGIVEN[shaman])
|
||||||
levt = Event("get_random_totem_targets", {"targets": ps})
|
|
||||||
levt.dispatch(var, shaman)
|
|
||||||
ps = levt.data["targets"]
|
|
||||||
if ps:
|
if ps:
|
||||||
target = random.choice(ps)
|
target = random.choice(ps)
|
||||||
dispatcher = MessageDispatcher(shaman, shaman)
|
dispatcher = MessageDispatcher(shaman, shaman)
|
||||||
|
|
||||||
tags = get_tags(var, TOTEMS[shaman])
|
SHAMANS[shaman] = give_totem(var, dispatcher, target, prefix=messages["random_totem_prefix"], role="crazed shaman", msg="")
|
||||||
|
|
||||||
SHAMANS[shaman] = give_totem(var, dispatcher, target, prefix=messages["random_totem_prefix"], tags=tags, role="crazed shaman", msg="")
|
|
||||||
else:
|
else:
|
||||||
LASTGIVEN[shaman] = None
|
LASTGIVEN[shaman] = None
|
||||||
elif shaman not in SHAMANS:
|
elif shaman not in SHAMANS:
|
||||||
|
@ -25,7 +25,7 @@ def investigate(var, wrapper, message):
|
|||||||
return
|
return
|
||||||
|
|
||||||
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
||||||
if not evt.dispatch(var, "identify", wrapper.source, target, frozenset({"info", "immediate"})):
|
if not evt.dispatch(var, wrapper.source, target):
|
||||||
return
|
return
|
||||||
|
|
||||||
target = evt.data["target"]
|
target = evt.data["target"]
|
||||||
|
@ -31,7 +31,7 @@ def see(var, wrapper, message):
|
|||||||
return
|
return
|
||||||
|
|
||||||
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
||||||
evt.dispatch(var, "see", wrapper.source, target, frozenset({"detrimental", "immediate"}))
|
evt.dispatch(var, wrapper.source, target)
|
||||||
if evt.prevent_default:
|
if evt.prevent_default:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ def dullahan_kill(var, wrapper, message):
|
|||||||
|
|
||||||
orig = target
|
orig = target
|
||||||
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
||||||
evt.dispatch(var, "kill", wrapper.source, target, frozenset({"detrimental"}))
|
evt.dispatch(var, wrapper.source, target)
|
||||||
if evt.prevent_default:
|
if evt.prevent_default:
|
||||||
return
|
return
|
||||||
target = evt.data["target"]
|
target = evt.data["target"]
|
||||||
@ -186,12 +186,10 @@ def on_role_assignment(evt, var, gamemode, pl):
|
|||||||
|
|
||||||
@event_listener("succubus_visit")
|
@event_listener("succubus_visit")
|
||||||
def on_succubus_visit(evt, var, succubus, target):
|
def on_succubus_visit(evt, var, succubus, target):
|
||||||
if target in TARGETS and succubus in TARGETS[target]:
|
succubi = get_all_players(("succubus",))
|
||||||
TARGETS[target].remove(succubus)
|
if target in TARGETS and TARGETS[target].intersection(succubi):
|
||||||
|
TARGETS[target].difference_update(succubi)
|
||||||
target.send(messages["dullahan_no_kill_succubus"])
|
target.send(messages["dullahan_no_kill_succubus"])
|
||||||
if target in KILLS and KILLS[target] in get_all_players(("succubus",)):
|
|
||||||
target.send(messages["no_kill_succubus"].format(KILLS[target]))
|
|
||||||
del KILLS[target]
|
|
||||||
|
|
||||||
@event_listener("myrole")
|
@event_listener("myrole")
|
||||||
def on_myrole(evt, var, user):
|
def on_myrole(evt, var, user):
|
||||||
|
@ -28,7 +28,7 @@ def hvisit(var, wrapper, message):
|
|||||||
return
|
return
|
||||||
|
|
||||||
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
||||||
evt.dispatch(var, "visit", wrapper.source, target, frozenset({"immediate"}))
|
evt.dispatch(var, wrapper.source, target)
|
||||||
if evt.prevent_default:
|
if evt.prevent_default:
|
||||||
return
|
return
|
||||||
target = evt.data["target"]
|
target = evt.data["target"]
|
||||||
|
@ -26,7 +26,7 @@ def hunter_kill(var, wrapper, message):
|
|||||||
|
|
||||||
orig = target
|
orig = target
|
||||||
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
||||||
evt.dispatch(var, "kill", wrapper.source, target, frozenset({"detrimental"}))
|
evt.dispatch(var, wrapper.source, target)
|
||||||
if evt.prevent_default:
|
if evt.prevent_default:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -125,13 +125,6 @@ def on_transition_night_end(evt, var):
|
|||||||
to_send = "hunter_simple"
|
to_send = "hunter_simple"
|
||||||
hunter.send(messages[to_send], "Players: " + ", ".join(p.nick for p in pl), sep="\n")
|
hunter.send(messages[to_send], "Players: " + ", ".join(p.nick for p in pl), sep="\n")
|
||||||
|
|
||||||
@event_listener("succubus_visit")
|
|
||||||
def on_succubus_visit(evt, var, succubus, target):
|
|
||||||
if target in KILLS and KILLS[target] in get_all_players(("succubus",)):
|
|
||||||
target.send(messages["no_kill_succubus"].format(KILLS[target]))
|
|
||||||
del KILLS[target]
|
|
||||||
HUNTERS.discard(target)
|
|
||||||
|
|
||||||
@event_listener("begin_day")
|
@event_listener("begin_day")
|
||||||
def on_begin_day(evt, var):
|
def on_begin_day(evt, var):
|
||||||
KILLS.clear()
|
KILLS.clear()
|
||||||
|
@ -38,13 +38,13 @@ def investigate(var, wrapper, message):
|
|||||||
return
|
return
|
||||||
|
|
||||||
evt = Event("targeted_command", {"target": target1, "misdirection": True, "exchange": True})
|
evt = Event("targeted_command", {"target": target1, "misdirection": True, "exchange": True})
|
||||||
evt.dispatch(var, "identify", wrapper.source, target1, frozenset({"info", "immediate"}))
|
evt.dispatch(var, wrapper.source, target1)
|
||||||
if evt.prevent_default:
|
if evt.prevent_default:
|
||||||
return
|
return
|
||||||
target1 = evt.data["target"]
|
target1 = evt.data["target"]
|
||||||
|
|
||||||
evt = Event("targeted_command", {"target": target2, "misdirection": True, "exchange": True})
|
evt = Event("targeted_command", {"target": target2, "misdirection": True, "exchange": True})
|
||||||
evt.dispatch(var, "identify", wrapper.source, target2, frozenset({"info", "immediate"}))
|
evt.dispatch(var, wrapper.source, target2)
|
||||||
if evt.prevent_default:
|
if evt.prevent_default:
|
||||||
return
|
return
|
||||||
target2 = evt.data["target"]
|
target2 = evt.data["target"]
|
||||||
|
@ -26,7 +26,7 @@ def see(var, wrapper, message):
|
|||||||
return
|
return
|
||||||
|
|
||||||
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
||||||
if not evt.dispatch(var, "see", wrapper.source, target, frozenset({"info", "immediate"})):
|
if not evt.dispatch(var, wrapper.source, target):
|
||||||
return
|
return
|
||||||
|
|
||||||
target = evt.data["target"]
|
target = evt.data["target"]
|
||||||
|
@ -43,14 +43,14 @@ def charm(var, wrapper, message):
|
|||||||
orig2 = target2
|
orig2 = target2
|
||||||
|
|
||||||
evt1 = Event("targeted_command", {"target": target1, "misdirection": True, "exchange": True})
|
evt1 = Event("targeted_command", {"target": target1, "misdirection": True, "exchange": True})
|
||||||
evt1.dispatch(var, "charm", wrapper.source, target1, frozenset({"detrimental"}))
|
evt1.dispatch(var, wrapper.source, target1)
|
||||||
if evt1.prevent_default:
|
if evt1.prevent_default:
|
||||||
return
|
return
|
||||||
target1 = evt1.data["target"]
|
target1 = evt1.data["target"]
|
||||||
|
|
||||||
if target2 is not None:
|
if target2 is not None:
|
||||||
evt2 = Event("targeted_command", {"target": target2, "misdirection": True, "exchange": True})
|
evt2 = Event("targeted_command", {"target": target2, "misdirection": True, "exchange": True})
|
||||||
evt2.dispatch(var, "charm", wrapper.source, target2, frozenset({"detrimental"}))
|
evt2.dispatch(var, wrapper.source, target2)
|
||||||
if evt2.prevent_default:
|
if evt2.prevent_default:
|
||||||
return
|
return
|
||||||
target2 = evt2.data["target"]
|
target2 = evt2.data["target"]
|
||||||
|
@ -26,7 +26,7 @@ def see(var, wrapper, message):
|
|||||||
return
|
return
|
||||||
|
|
||||||
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
||||||
if not evt.dispatch(var, "see", wrapper.source, target, frozenset({"info", "immediate"})):
|
if not evt.dispatch(var, wrapper.source, target):
|
||||||
return
|
return
|
||||||
|
|
||||||
target = evt.data["target"]
|
target = evt.data["target"]
|
||||||
|
@ -15,13 +15,7 @@ from src.events import Event
|
|||||||
|
|
||||||
from src.roles._shaman_helper import setup_variables, get_totem_target, give_totem
|
from src.roles._shaman_helper import setup_variables, get_totem_target, give_totem
|
||||||
|
|
||||||
def get_tags(var, totem):
|
TOTEMS, LASTGIVEN, SHAMANS = setup_variables("shaman", knows_totem=True)
|
||||||
tags = set()
|
|
||||||
if totem in var.BENEFICIAL_TOTEMS:
|
|
||||||
tags.add("beneficial")
|
|
||||||
return tags
|
|
||||||
|
|
||||||
TOTEMS, LASTGIVEN, SHAMANS = setup_variables("shaman", knows_totem=True, get_tags=get_tags)
|
|
||||||
|
|
||||||
@command("give", "totem", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("shaman",))
|
@command("give", "totem", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("shaman",))
|
||||||
def shaman_totem(var, wrapper, message):
|
def shaman_totem(var, wrapper, message):
|
||||||
@ -31,9 +25,7 @@ def shaman_totem(var, wrapper, message):
|
|||||||
if not target:
|
if not target:
|
||||||
return
|
return
|
||||||
|
|
||||||
totem = TOTEMS[wrapper.source]
|
SHAMANS[wrapper.source] = give_totem(var, wrapper, target, prefix="You", role="shaman", msg=" of {0}".format(TOTEMS[wrapper.source]))
|
||||||
|
|
||||||
SHAMANS[wrapper.source] = give_totem(var, wrapper, target, prefix="You", tags=get_tags(var, totem), role="shaman", msg=" of {0}".format(totem))
|
|
||||||
|
|
||||||
@event_listener("transition_day_begin", priority=4)
|
@event_listener("transition_day_begin", priority=4)
|
||||||
def on_transition_day_begin(evt, var):
|
def on_transition_day_begin(evt, var):
|
||||||
@ -45,16 +37,11 @@ def on_transition_day_begin(evt, var):
|
|||||||
if shaman in LASTGIVEN:
|
if shaman in LASTGIVEN:
|
||||||
if LASTGIVEN[shaman] in ps:
|
if LASTGIVEN[shaman] in ps:
|
||||||
ps.remove(LASTGIVEN[shaman])
|
ps.remove(LASTGIVEN[shaman])
|
||||||
levt = Event("get_random_totem_targets", {"targets": ps})
|
|
||||||
levt.dispatch(var, shaman)
|
|
||||||
ps = levt.data["targets"]
|
|
||||||
if ps:
|
if ps:
|
||||||
target = random.choice(ps)
|
target = random.choice(ps)
|
||||||
dispatcher = MessageDispatcher(shaman, shaman)
|
dispatcher = MessageDispatcher(shaman, shaman)
|
||||||
|
|
||||||
tags = get_tags(var, TOTEMS[shaman])
|
SHAMANS[shaman] = give_totem(var, dispatcher, target, prefix=messages["random_totem_prefix"], role="shaman", msg=" of {0}".format(TOTEMS[shaman]))
|
||||||
|
|
||||||
SHAMANS[shaman] = give_totem(var, dispatcher, target, prefix=messages["random_totem_prefix"], tags=tags, role="shaman", msg=" of {0}".format(TOTEMS[shaman]))
|
|
||||||
else:
|
else:
|
||||||
LASTGIVEN[shaman] = None
|
LASTGIVEN[shaman] = None
|
||||||
elif shaman not in SHAMANS:
|
elif shaman not in SHAMANS:
|
||||||
|
@ -14,7 +14,6 @@ from src.messages import messages
|
|||||||
from src.events import Event
|
from src.events import Event
|
||||||
|
|
||||||
ENTRANCED = UserSet() # type: Set[users.User]
|
ENTRANCED = UserSet() # type: Set[users.User]
|
||||||
ENTRANCED_DYING = UserSet() # type: Set[users.User]
|
|
||||||
VISITED = UserDict() # type: Dict[users.User, users.User]
|
VISITED = UserDict() # type: Dict[users.User, users.User]
|
||||||
PASSED = UserSet() # type: Set[users.User]
|
PASSED = UserSet() # type: Set[users.User]
|
||||||
ALL_SUCC_IDLE = True
|
ALL_SUCC_IDLE = True
|
||||||
@ -32,7 +31,7 @@ def hvisit(var, wrapper, message):
|
|||||||
return
|
return
|
||||||
|
|
||||||
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": False})
|
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": False})
|
||||||
evt.dispatch(var, "visit", wrapper.source, target, frozenset({"detrimental", "immediate"}))
|
evt.dispatch(var, wrapper.source, target)
|
||||||
if evt.prevent_default:
|
if evt.prevent_default:
|
||||||
return
|
return
|
||||||
target = evt.data["target"]
|
target = evt.data["target"]
|
||||||
@ -55,16 +54,6 @@ def hvisit(var, wrapper, message):
|
|||||||
revt = Event("succubus_visit", {})
|
revt = Event("succubus_visit", {})
|
||||||
revt.dispatch(var, wrapper.source, target)
|
revt.dispatch(var, wrapper.source, target)
|
||||||
|
|
||||||
# TODO: split these into hag and alpha wolf when they are split off
|
|
||||||
if target.nick in var.HEXED and users._get(var.LASTHEXED[target.nick]) in get_all_players(("succubus",)): # FIXME
|
|
||||||
target.send(messages["retract_hex_succubus"].format(var.LASTHEXED[target.nick]))
|
|
||||||
var.TOBESILENCED.remove(wrapper.source.nick)
|
|
||||||
var.HEXED.remove(target.nick)
|
|
||||||
del var.LASTHEXED[target.nick]
|
|
||||||
if users._get(var.BITE_PREFERENCES.get(target.nick), allow_none=True) in get_all_players(("succubus",)): # FIXME
|
|
||||||
target.send(messages["no_kill_succubus"].format(var.BITE_PREFERENCES[target.nick]))
|
|
||||||
del var.BITE_PREFERENCES[target.nick]
|
|
||||||
|
|
||||||
debuglog("{0} (succubus) VISIT: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
|
debuglog("{0} (succubus) VISIT: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
|
||||||
|
|
||||||
@command("pass", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("succubus",))
|
@command("pass", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("succubus",))
|
||||||
@ -85,58 +74,6 @@ def on_harlot_visit(evt, var, harlot, victim):
|
|||||||
victim.send(messages["succubus_harlot_success"].format(harlot))
|
victim.send(messages["succubus_harlot_success"].format(harlot))
|
||||||
ENTRANCED.add(harlot)
|
ENTRANCED.add(harlot)
|
||||||
|
|
||||||
@event_listener("get_random_totem_targets")
|
|
||||||
def on_get_random_totem_targets(evt, var, shaman):
|
|
||||||
if shaman in ENTRANCED:
|
|
||||||
for succubus in get_all_players(("succubus",)):
|
|
||||||
if succubus in evt.data["targets"]:
|
|
||||||
evt.data["targets"].remove(succubus)
|
|
||||||
|
|
||||||
@event_listener("chk_decision")
|
|
||||||
def on_chk_decision(evt, var, force):
|
|
||||||
for votee, voters in evt.data["votelist"].items():
|
|
||||||
if votee in get_all_players(("succubus",)):
|
|
||||||
for vtr in ENTRANCED:
|
|
||||||
if vtr in voters:
|
|
||||||
evt.data["numvotes"][votee] -= evt.data["weights"][votee][vtr]
|
|
||||||
evt.data["weights"][votee][vtr] = 0
|
|
||||||
|
|
||||||
def _kill_entranced_voters(var, votelist, not_lynching, votee):
|
|
||||||
voters = set(itertools.chain(*votelist.values()))
|
|
||||||
if not get_all_players(("succubus",)) & (voters | not_lynching):
|
|
||||||
# none of the succubi voted (or there aren't any succubi), so short-circuit
|
|
||||||
return
|
|
||||||
# kill off everyone entranced that did not follow one of the succubi's votes or abstain
|
|
||||||
# unless a succubus successfully voted the target, then people that didn't follow are spared
|
|
||||||
for x in ENTRANCED:
|
|
||||||
if x.nick not in var.DEAD:
|
|
||||||
ENTRANCED_DYING.add(x)
|
|
||||||
|
|
||||||
for other_votee, other_voters in votelist.items():
|
|
||||||
if get_all_players(("succubus",)) & set(other_voters):
|
|
||||||
if votee is other_votee:
|
|
||||||
ENTRANCED_DYING.clear()
|
|
||||||
return
|
|
||||||
|
|
||||||
ENTRANCED_DYING.difference_update(other_voters)
|
|
||||||
|
|
||||||
if get_all_players(("succubus",)) & not_lynching:
|
|
||||||
if votee is None:
|
|
||||||
ENTRANCED_DYING.clear()
|
|
||||||
return
|
|
||||||
|
|
||||||
ENTRANCED_DYING.difference_update(not_lynching)
|
|
||||||
|
|
||||||
@event_listener("chk_decision_lynch", priority=5)
|
|
||||||
def on_chk_decision_lynch(evt, var, voters):
|
|
||||||
# a different event may override the original votee, but people voting along with succubus
|
|
||||||
# won't necessarily know that, so base whether or not they risk death on the person originally voted
|
|
||||||
_kill_entranced_voters(var, evt.params.votelist, evt.params.not_lynching, evt.params.original_votee)
|
|
||||||
|
|
||||||
@event_listener("chk_decision_abstain")
|
|
||||||
def on_chk_decision_abstain(evt, var, not_lynching):
|
|
||||||
_kill_entranced_voters(var, evt.params.votelist, not_lynching, None)
|
|
||||||
|
|
||||||
# entranced logic should run after team wins have already been determined (aka run last)
|
# entranced logic should run after team wins have already been determined (aka run last)
|
||||||
@event_listener("player_win", priority=6)
|
@event_listener("player_win", priority=6)
|
||||||
def on_player_win(evt, var, user, role, winner, survived):
|
def on_player_win(evt, var, user, role, winner, survived):
|
||||||
@ -153,15 +90,23 @@ def on_player_win(evt, var, user, role, winner, survived):
|
|||||||
def on_chk_win(evt, var, rolemap, mainroles, lpl, lwolves, lrealwolves):
|
def on_chk_win(evt, var, rolemap, mainroles, lpl, lwolves, lrealwolves):
|
||||||
lsuccubi = len(rolemap.get("succubus", ()))
|
lsuccubi = len(rolemap.get("succubus", ()))
|
||||||
lentranced = len([x for x in ENTRANCED if x.nick not in var.DEAD])
|
lentranced = len([x for x in ENTRANCED if x.nick not in var.DEAD])
|
||||||
if lsuccubi and var.PHASE == "day" and lpl - lsuccubi == lentranced:
|
if var.PHASE == "day" and lpl - lsuccubi == lentranced:
|
||||||
evt.data["winner"] = "succubi"
|
evt.data["winner"] = "succubi"
|
||||||
evt.data["message"] = messages["succubus_win"].format(plural("succubus", lsuccubi), plural("has", lsuccubi), plural("master's", lsuccubi))
|
evt.data["message"] = messages["succubus_win"].format(plural("succubus", lsuccubi), plural("has", lsuccubi), plural("master's", lsuccubi))
|
||||||
|
|
||||||
@event_listener("can_exchange")
|
@event_listener("exchange_roles")
|
||||||
def on_can_exchange(evt, var, actor, target):
|
def on_exchange_roles(evt, var, actor, target, actor_role, target_role):
|
||||||
if actor in get_all_players(("succubus",)) or target in get_all_players(("succubus",)):
|
del VISITED[:actor:]
|
||||||
evt.prevent_default = True
|
del VISITED[:target:]
|
||||||
evt.stop_processing = True
|
PASSED.discard(actor)
|
||||||
|
PASSED.discard(target)
|
||||||
|
|
||||||
|
if actor in ENTRANCED:
|
||||||
|
ENTRANCED.remove(actor)
|
||||||
|
actor.send(messages["no_longer_entranced"])
|
||||||
|
if target in ENTRANCED:
|
||||||
|
ENTRANCED.remove(target)
|
||||||
|
target.send(messages["no_longer_entranced"])
|
||||||
|
|
||||||
@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):
|
||||||
@ -173,13 +118,10 @@ def on_del_player(evt, var, user, mainrole, allroles, death_triggers):
|
|||||||
if var.PHASE == "night" and var.GAMEPHASE == "night":
|
if var.PHASE == "night" and var.GAMEPHASE == "night":
|
||||||
if VISITED[user] in ENTRANCED:
|
if VISITED[user] in ENTRANCED:
|
||||||
ENTRANCED.discard(VISITED[user])
|
ENTRANCED.discard(VISITED[user])
|
||||||
ENTRANCED_DYING.discard(VISITED[user])
|
|
||||||
VISITED[user].send(messages["entranced_revert_win"])
|
VISITED[user].send(messages["entranced_revert_win"])
|
||||||
del VISITED[user]
|
del VISITED[user]
|
||||||
|
|
||||||
# if all succubi are dead, one of two things happen:
|
# if all succubi idled out (every last one of them), un-entrance people
|
||||||
# 1. if all succubi idled out (every last one of them), un-entrance people
|
|
||||||
# 2. otherwise, kill all entranced people immediately, they still remain entranced (and therefore lose)
|
|
||||||
# death_triggers is False for an idle-out, so we use that to determine which it is
|
# death_triggers is False for an idle-out, so we use that to determine which it is
|
||||||
if death_triggers:
|
if death_triggers:
|
||||||
ALL_SUCC_IDLE = False
|
ALL_SUCC_IDLE = False
|
||||||
@ -189,36 +131,6 @@ def on_del_player(evt, var, user, mainrole, allroles, death_triggers):
|
|||||||
while ENTRANCED:
|
while ENTRANCED:
|
||||||
e = ENTRANCED.pop()
|
e = ENTRANCED.pop()
|
||||||
e.send(messages["entranced_revert_win"])
|
e.send(messages["entranced_revert_win"])
|
||||||
elif entranced_alive:
|
|
||||||
msg = []
|
|
||||||
# Run in two loops so we can play the message for everyone dying at once before we actually
|
|
||||||
# kill any of them off (if we killed off first, the message order would be wrong wrt death chains)
|
|
||||||
comma = ""
|
|
||||||
if var.ROLE_REVEAL in ("on", "team"):
|
|
||||||
comma = ","
|
|
||||||
for e in entranced_alive:
|
|
||||||
if var.ROLE_REVEAL in ("on", "team"):
|
|
||||||
role = get_reveal_role(e)
|
|
||||||
an = "n" if role.startswith(("a", "e", "i", "o", "u")) else ""
|
|
||||||
msg.append("\u0002{0}\u0002, a{1} \u0002{2}\u0002".format(e, an, role))
|
|
||||||
else:
|
|
||||||
msg.append("\u0002{0}\u0002".format(e))
|
|
||||||
if len(msg) == 1:
|
|
||||||
channels.Main.send(messages["succubus_die_kill"].format(msg[0] + comma))
|
|
||||||
elif len(msg) == 2:
|
|
||||||
channels.Main.send(messages["succubus_die_kill"].format(msg[0] + comma + " and " + msg[1] + comma))
|
|
||||||
else:
|
|
||||||
channels.Main.send(messages["succubus_die_kill"].format(", ".join(msg[:-1]) + ", and " + msg[-1] + comma))
|
|
||||||
for e in entranced_alive:
|
|
||||||
# to ensure we do not double-kill someone, notify all child deaths that we'll be
|
|
||||||
# killing off everyone else that is entranced so they don't need to bother
|
|
||||||
dlc = list(evt.params.deadlist)
|
|
||||||
dlc.extend(entranced_alive - {e})
|
|
||||||
debuglog("{0} (succubus) SUCCUBUS DEATH KILL: {1} ({2})".format(user, e, get_main_role(e)))
|
|
||||||
evt.params.del_player(e, end_game=False, killer_role="succubus",
|
|
||||||
deadlist=dlc, original=evt.params.original, ismain=False)
|
|
||||||
evt.data["pl"] = evt.params.refresh_pl(evt.data["pl"])
|
|
||||||
ENTRANCED_DYING.clear()
|
|
||||||
|
|
||||||
@event_listener("transition_day_resolve", priority=1)
|
@event_listener("transition_day_resolve", priority=1)
|
||||||
def on_transition_day_resolve(evt, var, victim):
|
def on_transition_day_resolve(evt, var, victim):
|
||||||
@ -255,17 +167,6 @@ def on_chk_nightdone(evt, var):
|
|||||||
evt.data["actedcount"] += len(VISITED) + len(PASSED)
|
evt.data["actedcount"] += len(VISITED) + len(PASSED)
|
||||||
evt.data["nightroles"].extend(get_all_players(("succubus",)))
|
evt.data["nightroles"].extend(get_all_players(("succubus",)))
|
||||||
|
|
||||||
@event_listener("targeted_command")
|
|
||||||
def on_targeted_command(evt, var, name, actor, orig_target, tags):
|
|
||||||
if "beneficial" not in tags and actor in ENTRANCED and evt.data["target"] in get_all_players(("succubus",)):
|
|
||||||
try:
|
|
||||||
what = evt.params.action
|
|
||||||
except AttributeError:
|
|
||||||
what = name
|
|
||||||
actor.send(messages["no_acting_on_succubus"].format(what))
|
|
||||||
evt.stop_processing = True
|
|
||||||
evt.prevent_default = True
|
|
||||||
|
|
||||||
@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):
|
||||||
succubi = get_all_players(("succubus",))
|
succubi = get_all_players(("succubus",))
|
||||||
@ -287,17 +188,8 @@ def on_transition_night_end(evt, var):
|
|||||||
@event_listener("begin_day")
|
@event_listener("begin_day")
|
||||||
def on_begin_day(evt, var):
|
def on_begin_day(evt, var):
|
||||||
VISITED.clear()
|
VISITED.clear()
|
||||||
ENTRANCED_DYING.clear()
|
|
||||||
PASSED.clear()
|
PASSED.clear()
|
||||||
|
|
||||||
@event_listener("transition_day", priority=2)
|
|
||||||
def on_transition_day(evt, var):
|
|
||||||
for v in ENTRANCED_DYING:
|
|
||||||
var.DYING.add(v) # indicate that the death bypasses protections
|
|
||||||
evt.data["victims"].append(v)
|
|
||||||
evt.data["onlybywolves"].discard(v)
|
|
||||||
# we do not add to killers as retribution totem should not work on entranced not following succubus
|
|
||||||
|
|
||||||
@event_listener("get_special")
|
@event_listener("get_special")
|
||||||
def on_get_special(evt, var):
|
def on_get_special(evt, var):
|
||||||
evt.data["win_stealers"].update(get_players(("succubus",)))
|
evt.data["win_stealers"].update(get_players(("succubus",)))
|
||||||
@ -318,7 +210,6 @@ def on_reset(evt, var):
|
|||||||
global ALL_SUCC_IDLE
|
global ALL_SUCC_IDLE
|
||||||
ALL_SUCC_IDLE = True
|
ALL_SUCC_IDLE = True
|
||||||
ENTRANCED.clear()
|
ENTRANCED.clear()
|
||||||
ENTRANCED_DYING.clear()
|
|
||||||
VISITED.clear()
|
VISITED.clear()
|
||||||
PASSED.clear()
|
PASSED.clear()
|
||||||
|
|
||||||
@ -327,7 +218,4 @@ def on_revealroles(evt, var, wrapper):
|
|||||||
if ENTRANCED:
|
if ENTRANCED:
|
||||||
evt.data["output"].append("\u0002entranced players\u0002: {0}".format(", ".join(p.nick for p in ENTRANCED)))
|
evt.data["output"].append("\u0002entranced players\u0002: {0}".format(", ".join(p.nick for p in ENTRANCED)))
|
||||||
|
|
||||||
if ENTRANCED_DYING:
|
|
||||||
evt.data["output"].append("\u0002dying entranced players\u0002: {0}".format(", ".join(p.nick for p in ENTRANCED_DYING)))
|
|
||||||
|
|
||||||
# vim: set sw=4 expandtab:
|
# vim: set sw=4 expandtab:
|
||||||
|
@ -40,7 +40,7 @@ def vg_kill(var, wrapper, message):
|
|||||||
|
|
||||||
orig = target
|
orig = target
|
||||||
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": False})
|
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": False})
|
||||||
evt.dispatch(var, "kill", wrapper.source, target, frozenset({"detrimental"}))
|
evt.dispatch(var, wrapper.source, target)
|
||||||
if evt.prevent_default:
|
if evt.prevent_default:
|
||||||
return
|
return
|
||||||
target = evt.data["target"]
|
target = evt.data["target"]
|
||||||
|
@ -21,7 +21,7 @@ def vigilante_kill(var, wrapper, message):
|
|||||||
|
|
||||||
orig = target
|
orig = target
|
||||||
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
||||||
evt.dispatch(var, "kill", wrapper.source, target, frozenset({"detrimental"}))
|
evt.dispatch(var, wrapper.source, target)
|
||||||
if evt.prevent_default:
|
if evt.prevent_default:
|
||||||
return
|
return
|
||||||
target = evt.data["target"]
|
target = evt.data["target"]
|
||||||
@ -107,12 +107,6 @@ def on_transition_night_end(evt, var):
|
|||||||
to_send = "vigilante_simple"
|
to_send = "vigilante_simple"
|
||||||
vigilante.send(messages[to_send], "Players: " + ", ".join(p.nick for p in pl), sep="\n")
|
vigilante.send(messages[to_send], "Players: " + ", ".join(p.nick for p in pl), sep="\n")
|
||||||
|
|
||||||
@event_listener("succubus_visit")
|
|
||||||
def on_succubus_visit(evt, var, succubus, target):
|
|
||||||
if target in KILLS and KILLS[target] in get_all_players(("succubus",)):
|
|
||||||
target.send(messages["no_kill_succubus"].format(KILLS[target]))
|
|
||||||
del KILLS[target]
|
|
||||||
|
|
||||||
@event_listener("begin_day")
|
@event_listener("begin_day")
|
||||||
def on_begin_day(evt, var):
|
def on_begin_day(evt, var):
|
||||||
KILLS.clear()
|
KILLS.clear()
|
||||||
|
@ -74,7 +74,7 @@ def wolf_kill(cli, nick, chan, rest):
|
|||||||
target = users._get(victim) # 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, "kill", wolf, target, frozenset({"detrimental"}))
|
evt.dispatch(var, wolf, target)
|
||||||
if evt.prevent_default:
|
if evt.prevent_default:
|
||||||
return
|
return
|
||||||
victim = evt.data["target"].nick
|
victim = evt.data["target"].nick
|
||||||
@ -437,16 +437,6 @@ def on_transition_night_end(evt, var):
|
|||||||
if var.ALPHA_ENABLED and role == "alpha wolf" and wolf.nick not in var.ALPHA_WOLVES: # FIXME: Fix once var.ALPHA_WOLVES holds User instances
|
if var.ALPHA_ENABLED and role == "alpha wolf" and wolf.nick not in var.ALPHA_WOLVES: # FIXME: Fix once var.ALPHA_WOLVES holds User instances
|
||||||
wolf.send(messages["wolf_bite"])
|
wolf.send(messages["wolf_bite"])
|
||||||
|
|
||||||
@event_listener("succubus_visit")
|
|
||||||
def on_succubus_visit(evt, var, succubus, target):
|
|
||||||
if get_all_players(("succubus",)).intersection(users._get(x) for x in KILLS.get(target.nick, ())): # FIXME: once KILLS holds User instances
|
|
||||||
for s in get_all_players(("succubus",)):
|
|
||||||
if s.nick in KILLS[target.nick]:
|
|
||||||
target.send(messages["no_kill_succubus"].format(succubus))
|
|
||||||
KILLS[target.nick].remove(s.nick)
|
|
||||||
if not KILLS[target.nick]:
|
|
||||||
del KILLS[target.nick]
|
|
||||||
|
|
||||||
@event_listener("begin_day")
|
@event_listener("begin_day")
|
||||||
def on_begin_day(evt, var):
|
def on_begin_day(evt, var):
|
||||||
KILLS.clear()
|
KILLS.clear()
|
||||||
|
@ -15,13 +15,7 @@ from src.events import Event
|
|||||||
|
|
||||||
from src.roles._shaman_helper import setup_variables, get_totem_target, give_totem
|
from src.roles._shaman_helper import setup_variables, get_totem_target, give_totem
|
||||||
|
|
||||||
def get_tags(var, totem):
|
TOTEMS, LASTGIVEN, SHAMANS = setup_variables("wolf shaman", knows_totem=True)
|
||||||
tags = set()
|
|
||||||
if totem in var.BENEFICIAL_TOTEMS:
|
|
||||||
tags.add("beneficial")
|
|
||||||
return tags
|
|
||||||
|
|
||||||
TOTEMS, LASTGIVEN, SHAMANS = setup_variables("wolf shaman", knows_totem=True, get_tags=get_tags)
|
|
||||||
|
|
||||||
@command("give", "totem", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("wolf shaman",))
|
@command("give", "totem", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("wolf shaman",))
|
||||||
def wolf_shaman_totem(var, wrapper, message):
|
def wolf_shaman_totem(var, wrapper, message):
|
||||||
@ -31,9 +25,7 @@ def wolf_shaman_totem(var, wrapper, message):
|
|||||||
if not target:
|
if not target:
|
||||||
return
|
return
|
||||||
|
|
||||||
totem = TOTEMS[wrapper.source]
|
SHAMANS[wrapper.source] = give_totem(var, wrapper, target, prefix="You", role="wolf shaman", msg=" of {0}".format(TOTEMS[wrapper.source]))
|
||||||
|
|
||||||
SHAMANS[wrapper.source] = give_totem(var, wrapper, target, prefix="You", tags=get_tags(var, totem), role="wolf shaman", msg=" of {0}".format(totem))
|
|
||||||
|
|
||||||
relay_wolfchat_command(wrapper.client, wrapper.source.nick, messages["shaman_wolfchat"].format(wrapper.source, target), ("wolf shaman",), is_wolf_command=True)
|
relay_wolfchat_command(wrapper.client, wrapper.source.nick, messages["shaman_wolfchat"].format(wrapper.source, target), ("wolf shaman",), is_wolf_command=True)
|
||||||
|
|
||||||
@ -47,16 +39,11 @@ def on_transition_day_begin(evt, var):
|
|||||||
if shaman in LASTGIVEN:
|
if shaman in LASTGIVEN:
|
||||||
if LASTGIVEN[shaman] in ps:
|
if LASTGIVEN[shaman] in ps:
|
||||||
ps.remove(LASTGIVEN[shaman])
|
ps.remove(LASTGIVEN[shaman])
|
||||||
levt = Event("get_random_totem_targets", {"targets": ps})
|
|
||||||
levt.dispatch(var, shaman)
|
|
||||||
ps = levt.data["targets"]
|
|
||||||
if ps:
|
if ps:
|
||||||
target = random.choice(ps)
|
target = random.choice(ps)
|
||||||
dispatcher = MessageDispatcher(shaman, shaman)
|
dispatcher = MessageDispatcher(shaman, shaman)
|
||||||
|
|
||||||
tags = get_tags(var, TOTEMS[shaman])
|
SHAMANS[shaman] = give_totem(var, dispatcher, target, prefix=messages["random_totem_prefix"], role="wolf shaman", msg=" of {0}".format(TOTEMS[shaman]))
|
||||||
|
|
||||||
SHAMANS[shaman] = give_totem(var, dispatcher, target, prefix=messages["random_totem_prefix"], tags=tags, role="wolf shaman", msg=" of {0}".format(TOTEMS[shaman]))
|
|
||||||
relay_wolfchat_command(shaman.client, shaman.nick, messages["shaman_wolfchat"].format(shaman, target), ("wolf shaman",), is_wolf_command=True)
|
relay_wolfchat_command(shaman.client, shaman.nick, messages["shaman_wolfchat"].format(shaman, target), ("wolf shaman",), is_wolf_command=True)
|
||||||
else:
|
else:
|
||||||
LASTGIVEN[shaman] = None
|
LASTGIVEN[shaman] = None
|
||||||
|
@ -3717,9 +3717,6 @@ def check_exchange(cli, actor, nick):
|
|||||||
user = users._get(actor) # FIXME
|
user = users._get(actor) # FIXME
|
||||||
target = users._get(nick) # FIXME
|
target = users._get(nick) # FIXME
|
||||||
|
|
||||||
event = Event("can_exchange", {})
|
|
||||||
if not event.dispatch(var, user, target):
|
|
||||||
return False # some roles such as succubus cannot be affected by exchange totem
|
|
||||||
if nick in var.EXCHANGED:
|
if nick in var.EXCHANGED:
|
||||||
var.EXCHANGED.remove(nick)
|
var.EXCHANGED.remove(nick)
|
||||||
actor_role = get_role(actor)
|
actor_role = get_role(actor)
|
||||||
@ -3926,7 +3923,7 @@ def shoot(var, wrapper, message):
|
|||||||
|
|
||||||
# get actual victim
|
# get actual victim
|
||||||
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
evt = Event("targeted_command", {"target": target, "misdirection": True, "exchange": True})
|
||||||
if not evt.dispatch(var, "shoot", wrapper.source, target, frozenset({"detrimental"})):
|
if not evt.dispatch(var, wrapper.source, target):
|
||||||
return
|
return
|
||||||
|
|
||||||
target = evt.data["target"]
|
target = evt.data["target"]
|
||||||
@ -3995,12 +3992,6 @@ def shoot(var, wrapper, message):
|
|||||||
wrapper.send(messages["gunner_suicide_no_reveal"].format(wrapper.source))
|
wrapper.send(messages["gunner_suicide_no_reveal"].format(wrapper.source))
|
||||||
del_player(wrapper.source, killer_role="villager") # blame explosion on villager's shoddy gun construction or something
|
del_player(wrapper.source, killer_role="villager") # blame explosion on villager's shoddy gun construction or something
|
||||||
|
|
||||||
def is_safe(nick, victim): # replace calls to this with targeted_command event when splitting roles
|
|
||||||
from src.roles import succubus
|
|
||||||
user = users._get(nick) # FIXME
|
|
||||||
target = users._get(victim) # FIXME
|
|
||||||
return user in succubus.ENTRANCED and target in get_all_players(("succubus",))
|
|
||||||
|
|
||||||
@cmd("bless", chan=False, pm=True, playing=True, silenced=True, phases=("day",), roles=("priest",))
|
@cmd("bless", chan=False, pm=True, playing=True, silenced=True, phases=("day",), roles=("priest",))
|
||||||
def bless(cli, nick, chan, rest):
|
def bless(cli, nick, chan, rest):
|
||||||
"""Bless a player, preventing them from being killed for the remainder of the game."""
|
"""Bless a player, preventing them from being killed for the remainder of the game."""
|
||||||
@ -4083,9 +4074,6 @@ def observe(cli, nick, chan, rest):
|
|||||||
else:
|
else:
|
||||||
pm(cli, nick, messages["no_observe_wolf"])
|
pm(cli, nick, messages["no_observe_wolf"])
|
||||||
return
|
return
|
||||||
if is_safe(nick, victim):
|
|
||||||
pm(cli, nick, messages["no_acting_on_succubus"].format("observe"))
|
|
||||||
return
|
|
||||||
victim = choose_target(nick, victim)
|
victim = choose_target(nick, victim)
|
||||||
if check_exchange(cli, nick, victim):
|
if check_exchange(cli, nick, victim):
|
||||||
return
|
return
|
||||||
@ -4263,9 +4251,6 @@ def bite_cmd(cli, nick, chan, rest):
|
|||||||
if not victim:
|
if not victim:
|
||||||
pm(cli, nick, messages["bite_error"])
|
pm(cli, nick, messages["bite_error"])
|
||||||
return
|
return
|
||||||
if is_safe(nick, victim):
|
|
||||||
pm(cli, nick, messages["no_acting_on_succubus"].format("bite"))
|
|
||||||
return
|
|
||||||
|
|
||||||
vrole = get_role(victim)
|
vrole = get_role(victim)
|
||||||
actual = choose_target(nick, victim)
|
actual = choose_target(nick, victim)
|
||||||
@ -4351,10 +4336,6 @@ def hex_target(cli, nick, chan, rest):
|
|||||||
pm(cli, nick, messages["no_multiple_hex"].format(victim))
|
pm(cli, nick, messages["no_multiple_hex"].format(victim))
|
||||||
return
|
return
|
||||||
|
|
||||||
if is_safe(nick, victim):
|
|
||||||
pm(cli, nick, messages["no_acting_on_succubus"].format("hex"))
|
|
||||||
return
|
|
||||||
|
|
||||||
victim = choose_target(nick, victim)
|
victim = choose_target(nick, victim)
|
||||||
if in_wolflist(nick, victim):
|
if in_wolflist(nick, victim):
|
||||||
pm(cli, nick, messages["no_hex_wolf"])
|
pm(cli, nick, messages["no_hex_wolf"])
|
||||||
@ -4386,10 +4367,6 @@ def curse(cli, nick, chan, rest):
|
|||||||
victim = get_victim(cli, nick, re.split(" +",rest)[0], False)
|
victim = get_victim(cli, nick, re.split(" +",rest)[0], False)
|
||||||
if not victim:
|
if not victim:
|
||||||
return
|
return
|
||||||
if is_safe(nick, victim):
|
|
||||||
pm(cli, nick, messages["no_acting_on_succubus"].format("curse"))
|
|
||||||
return
|
|
||||||
|
|
||||||
# There may actually be valid strategy in cursing other wolfteam members,
|
# There may actually be valid strategy in cursing other wolfteam members,
|
||||||
# but for now it is not allowed. If someone seems suspicious and shows as
|
# but for now it is not allowed. If someone seems suspicious and shows as
|
||||||
# villager across multiple nights, safes can use that as a tell that the
|
# villager across multiple nights, safes can use that as a tell that the
|
||||||
@ -4461,7 +4438,7 @@ def clone(cli, nick, chan, rest):
|
|||||||
var.ROLE_COMMAND_EXCEPTIONS.add("clone")
|
var.ROLE_COMMAND_EXCEPTIONS.add("clone")
|
||||||
|
|
||||||
@event_listener("targeted_command", priority=9)
|
@event_listener("targeted_command", priority=9)
|
||||||
def on_targeted_command(evt, var, name, actor, orig_target, tags):
|
def on_targeted_command(evt, var, actor, orig_target):
|
||||||
if evt.data["misdirection"]:
|
if evt.data["misdirection"]:
|
||||||
evt.data["target"] = users._get(choose_target(actor.nick, evt.data["target"].nick)) # FIXME
|
evt.data["target"] = users._get(choose_target(actor.nick, evt.data["target"].nick)) # FIXME
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user