From a2dd0fd189a046751b98614e5ee3dd866b690805 Mon Sep 17 00:00:00 2001 From: skizzerz Date: Sat, 9 Dec 2017 11:21:04 -0600 Subject: [PATCH] Balance tweaks for new mode - Remove minion entirely, keeping cultist at 8p instead. - Cultist swaps with doomsayer at 9p, so there's still only 2 wolfteam until 11p. Doomsayer is powerful enough already, don't need another wolfteam in there. - Get rid of retribution totems. Shaman is now 50/50 death/pestilence and wolf shaman is 50/50 protection/misdirection. - Make stalemates benefit village by allowing tied votes to lynch all tied people instead of nobody. Day ends once everyone votes, even if there is no majority vote. In that case, the plurality of votes is considered rather than majority. --- messages/en.json | 1 + src/gamemodes.py | 48 +++++++++++++++++++++++++++++++++++++++++------- src/wolfgame.py | 4 +++- 3 files changed, 45 insertions(+), 8 deletions(-) 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