diff --git a/messages/en.json b/messages/en.json index 1d67358..af30e5f 100644 --- a/messages/en.json +++ b/messages/en.json @@ -162,6 +162,7 @@ "command_ratelimited": "This command is rate-limited. Please wait a while before using it again.", "stats": "{0}It is currently {4}. There {3} {1}, and {2}.", "daylight_warning": "\u0002As the sun sinks inexorably toward the horizon, turning the lanky pine trees into fire-edged silhouettes, the villagers are reminded that very little time remains for them to reach a decision; if darkness falls before they have done so, the majority will win the vote. No one will be lynched if there are no votes or an even split.\u0002", + "daylight_warning_killtie": "\u0002As the sun sinks inexorably toward the horizon, turning the lanky pine trees into fire-edged silhouettes, the villagers are reminded that very little time remains for them to reach a decision; if darkness falls before they have done so, the plurality will win the vote. Ties for plurality will cause all tied players to be lynched, but no one will be lynched if there are no votes.\u0002", "sunset": "As the sun sets, the villagers agree to retire to their beds and wait for morning.", "twilight_warning": "\u0002A few villagers awake early and notice it is still dark outside. The night is almost over and there are still whispers heard in the village.\u0002", "sunrise": "Night lasted \u0002{0:0>2}:{1:0>2}\u0002. It is now daytime. The villagers awake, thankful for surviving the night, and search the village... ", diff --git a/src/gamemodes.py b/src/gamemodes.py index 875060b..44fec11 100644 --- a/src/gamemodes.py +++ b/src/gamemodes.py @@ -1366,8 +1366,8 @@ class MudkipMode(GameMode): super().__init__(arg) self.ABSTAIN_ENABLED = False # SHAMAN , CRAZED SHAMAN , WOLF SHAMAN - self.TOTEM_CHANCES = { "death": ( 4 , 1 , 0 ), - "protection": ( 0 , 1 , 4 ), + self.TOTEM_CHANCES = { "death": ( 5 , 1 , 0 ), + "protection": ( 0 , 1 , 5 ), "silence": ( 0 , 1 , 0 ), "revealing": ( 0 , 1 , 0 ), "desperation": ( 0 , 1 , 0 ), @@ -1378,9 +1378,9 @@ class MudkipMode(GameMode): "exchange": ( 0 , 1 , 0 ), "lycanthropy": ( 0 , 1 , 0 ), "luck": ( 0 , 1 , 0 ), - "pestilence": ( 4 , 1 , 0 ), - "retribution": ( 2 , 1 , 2 ), - "misdirection": ( 0 , 1 , 4 ), + "pestilence": ( 5 , 1 , 0 ), + "retribution": ( 0 , 1 , 0 ), + "misdirection": ( 0 , 1 , 5 ), "deceit": ( 0 , 1 , 0 ), } self.ROLE_INDEX = ( 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ) @@ -1396,8 +1396,7 @@ class MudkipMode(GameMode): "wolf" : ( 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 ), "doomsayer" : ( 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ), "wolf shaman" : ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 ), - "cultist" : ( 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ), - "minion" : ( 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ), + "cultist" : ( 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ), # neutral roles "jester" : ( 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ), "succubus" : ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 ), @@ -1405,6 +1404,41 @@ class MudkipMode(GameMode): "assassin" : ( 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 ), }) + self.recursion_guard = False + def startup(self): + events.add_listener("chk_decision", self.chk_decision) + events.add_listener("daylight_warning", self.daylight_warning) + + def teardown(self): + events.remove_listener("chk_decision", self.chk_decision) + events.remove_listener("daylight_warning", self.daylight_warning) + + def chk_decision(self, evt, cli, var, force): + # If everyone is voting, end day here with the person with plurality being voted. If there's a tie, + # kill all tied players rather than hanging. The intent of this is to benefit village team in the event + # of a stalemate, as they could use the extra help (especially in 5p). + if self.recursion_guard: + # in here, this means we're in a child chk_decision event called from this one + # the only thing we need to do is ensure we don't turn into nighttime prematurely + evt.data["transition_night"] = lambda cli: None + return + + avail = len(evt.params.voters) + voted = sum(map(len, evt.data["votelist"].values())) + if avail != voted: + return + + maxv = max(evt.data["numvotes"].values()) + # make a copy in case an event mutates it in recursive calls + tovote = [p for p, n in evt.data["numvotes"].items() if n == maxv] + self.recursion_guard = True + for p in tovote: + chk_decision(cli, force=p) + self.recursion_guard = False + evt.data["transition_night"](cli) + + def daylight_warning(self, evt, var): + evt.data["message"] = "daylight_warning_killtie" # vim: set sw=4 expandtab: diff --git a/src/wolfgame.py b/src/wolfgame.py index 010c000..18faa2e 100644 --- a/src/wolfgame.py +++ b/src/wolfgame.py @@ -1722,7 +1722,9 @@ def hurry_up(cli, gameid, change): chan = botconfig.CHANNEL if not change: - cli.msg(chan, messages["daylight_warning"]) + event = Event("daylight_warning", {"message": "daylight_warning"}) + event.dispatch(var) + cli.msg(chan, event.data["message"]) return var.DAY_ID = 0