Add alternate win condition if only lovers are alive
The message could use a better phrasing, but anyway this works.
This commit is contained in:
parent
26e7acc8f8
commit
04180bc036
@ -16,6 +16,39 @@ def game_mode(name, minp, maxp, likelihood = 0):
|
|||||||
|
|
||||||
reset_roles = lambda i: OrderedDict([(role, (0,) * len(i)) for role in var.ROLE_GUIDE])
|
reset_roles = lambda i: OrderedDict([(role, (0,) * len(i)) for role in var.ROLE_GUIDE])
|
||||||
|
|
||||||
|
def get_lovers():
|
||||||
|
lovers = []
|
||||||
|
pl = var.list_players()
|
||||||
|
for lover in var.LOVERS:
|
||||||
|
done = None
|
||||||
|
for i, lset in enumerate(lovers):
|
||||||
|
if lover in pl and lover in lset:
|
||||||
|
if done is not None: # plot twist! two clusters turn out to be linked!
|
||||||
|
done.update(lset)
|
||||||
|
for lvr in var.LOVERS[lover]:
|
||||||
|
if lvr in pl:
|
||||||
|
done.add(lvr)
|
||||||
|
|
||||||
|
lset.clear()
|
||||||
|
continue
|
||||||
|
|
||||||
|
for lvr in var.LOVERS[lover]:
|
||||||
|
if lvr in pl:
|
||||||
|
lset.add(lvr)
|
||||||
|
done = lset
|
||||||
|
|
||||||
|
if done is None and lover in pl:
|
||||||
|
lovers.append(set())
|
||||||
|
lovers[-1].add(lover)
|
||||||
|
for lvr in var.LOVERS[lover]:
|
||||||
|
if lvr in pl:
|
||||||
|
lovers[-1].add(lvr)
|
||||||
|
|
||||||
|
while set() in lovers:
|
||||||
|
lovers.remove(set())
|
||||||
|
|
||||||
|
return lovers
|
||||||
|
|
||||||
class GameMode:
|
class GameMode:
|
||||||
def __init__(self, arg=""):
|
def __init__(self, arg=""):
|
||||||
if not arg:
|
if not arg:
|
||||||
@ -64,6 +97,23 @@ class GameMode:
|
|||||||
def teardown(self):
|
def teardown(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Here so any game mode can use it
|
||||||
|
def lovers_chk_win(self, evt, var, lpl, lwolves, lrealwolves):
|
||||||
|
winner = evt.data["winner"]
|
||||||
|
if winner is not None and winner.startswith("@"):
|
||||||
|
return # fool won, lovers can't win even if they would
|
||||||
|
all_lovers = get_lovers()
|
||||||
|
if len(all_lovers) != 1:
|
||||||
|
return # we need exactly one cluster alive for this to trigger
|
||||||
|
|
||||||
|
lovers = all_lovers[0]
|
||||||
|
|
||||||
|
if len(lovers) == lpl:
|
||||||
|
evt.data["winner"] = "lovers"
|
||||||
|
evt.data["message"] = "Game over! All of the remaining villagers are in love with each other! All of them win."
|
||||||
|
evt.data["players"] = ["{0} ({1})".format(x, var.get_role(x)) for x in lovers]
|
||||||
|
evt.data["winners"] = list(lovers)
|
||||||
|
|
||||||
@game_mode("roles", minp = 4, maxp = 35)
|
@game_mode("roles", minp = 4, maxp = 35)
|
||||||
class ChangedRolesMode(GameMode):
|
class ChangedRolesMode(GameMode):
|
||||||
"""Example: !fgame roles=wolf:1,seer:0,guardian angel:1"""
|
"""Example: !fgame roles=wolf:1,seer:0,guardian angel:1"""
|
||||||
@ -398,6 +448,12 @@ class MatchmakerMode(GameMode):
|
|||||||
"mad scientist" : [i >= 18 for i in self.ROLE_INDEX],
|
"mad scientist" : [i >= 18 for i in self.ROLE_INDEX],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
def startup(self):
|
||||||
|
events.add_listener("chk_win", self.lovers_chk_win, 1)
|
||||||
|
|
||||||
|
def teardown(self):
|
||||||
|
events.remove_listener("chk_win", self.lovers_chk_win, 1)
|
||||||
|
|
||||||
@game_mode("random", minp = 8, maxp = 24, likelihood = 0)
|
@game_mode("random", minp = 8, maxp = 24, likelihood = 0)
|
||||||
class RandomMode(GameMode):
|
class RandomMode(GameMode):
|
||||||
"""Completely random and hidden roles."""
|
"""Completely random and hidden roles."""
|
||||||
@ -430,9 +486,11 @@ class RandomMode(GameMode):
|
|||||||
|
|
||||||
def startup(self):
|
def startup(self):
|
||||||
events.add_listener("role_attribution", self.role_attribution, 1)
|
events.add_listener("role_attribution", self.role_attribution, 1)
|
||||||
|
events.add_listener("chk_win", self.lovers_chk_win, 1)
|
||||||
|
|
||||||
def teardown(self):
|
def teardown(self):
|
||||||
events.remove_listener("role_attribution", self.role_attribution, 1)
|
events.remove_listener("role_attribution", self.role_attribution, 1)
|
||||||
|
events.remove_listener("chk_win", self.lovers_chk_win, 1)
|
||||||
|
|
||||||
def role_attribution(self, evt, cli, chk_win_conditions, var, villagers):
|
def role_attribution(self, evt, cli, chk_win_conditions, var, villagers):
|
||||||
lpl = len(villagers) - 1
|
lpl = len(villagers) - 1
|
||||||
|
@ -2275,7 +2275,7 @@ def chk_traitor(cli):
|
|||||||
"frightened as they hear a loud howl. The wolves are "+
|
"frightened as they hear a loud howl. The wolves are "+
|
||||||
"not gone!\u0002")
|
"not gone!\u0002")
|
||||||
|
|
||||||
def stop_game(cli, winner = "", abort = False):
|
def stop_game(cli, winner = "", abort = False, winners = None):
|
||||||
chan = botconfig.CHANNEL
|
chan = botconfig.CHANNEL
|
||||||
if abort:
|
if abort:
|
||||||
cli.msg(chan, "The role attribution failed 3 times. Game was canceled.")
|
cli.msg(chan, "The role attribution failed 3 times. Game was canceled.")
|
||||||
@ -2369,7 +2369,8 @@ def stop_game(cli, winner = "", abort = False):
|
|||||||
# Only update if someone actually won, "" indicates everyone died or abnormal game stop
|
# Only update if someone actually won, "" indicates everyone died or abnormal game stop
|
||||||
if winner != "":
|
if winner != "":
|
||||||
plrl = {}
|
plrl = {}
|
||||||
winners = []
|
if winners is None:
|
||||||
|
winners = []
|
||||||
for role,ppl in var.ORIGINAL_ROLES.items():
|
for role,ppl in var.ORIGINAL_ROLES.items():
|
||||||
if role in var.TEMPLATE_RESTRICTIONS.keys():
|
if role in var.TEMPLATE_RESTRICTIONS.keys():
|
||||||
continue
|
continue
|
||||||
@ -2426,7 +2427,7 @@ def stop_game(cli, winner = "", abort = False):
|
|||||||
iwon = False
|
iwon = False
|
||||||
elif rol == "fool" and "@" + splr == winner:
|
elif rol == "fool" and "@" + splr == winner:
|
||||||
iwon = True
|
iwon = True
|
||||||
elif splr in var.LOVERS and splr in survived and len([x for x in var.LOVERS[splr] if x in survived]) > 0:
|
elif winner != "lovers" and splr in var.LOVERS and splr in survived and len([x for x in var.LOVERS[splr] if x in survived]) > 0:
|
||||||
for lvr in var.LOVERS[splr]:
|
for lvr in var.LOVERS[splr]:
|
||||||
if lvr not in survived:
|
if lvr not in survived:
|
||||||
# cannot win with dead lover (if splr in survived and lvr is not, that means lvr idled out)
|
# cannot win with dead lover (if splr in survived and lvr is not, that means lvr idled out)
|
||||||
@ -2622,7 +2623,7 @@ def chk_win_conditions(lpl, lwolves, lcubs, lrealwolves, lmonsters, ltraitors, l
|
|||||||
ltraitors = len(var.ROLES.get("traitor", ()))
|
ltraitors = len(var.ROLES.get("traitor", ()))
|
||||||
return chk_win_conditions(lpl, lwolves, lcubs, lrealwolves, lmonsters, ltraitors, lpipers, cli, end_game)
|
return chk_win_conditions(lpl, lwolves, lcubs, lrealwolves, lmonsters, ltraitors, lpipers, cli, end_game)
|
||||||
|
|
||||||
event = Event("chk_win", {"winner": winner, "message": message})
|
event = Event("chk_win", {"winner": winner, "message": message, "players": [], "winners": None})
|
||||||
event.dispatch(var, lpl, lwolves, lrealwolves)
|
event.dispatch(var, lpl, lwolves, lrealwolves)
|
||||||
winner = event.data["winner"]
|
winner = event.data["winner"]
|
||||||
message = event.data["message"]
|
message = event.data["message"]
|
||||||
@ -2631,7 +2632,7 @@ def chk_win_conditions(lpl, lwolves, lcubs, lrealwolves, lmonsters, ltraitors, l
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
if end_game:
|
if end_game:
|
||||||
players = []
|
players = event.data["players"]
|
||||||
if winner == "monsters":
|
if winner == "monsters":
|
||||||
for plr in var.ROLES["monster"]:
|
for plr in var.ROLES["monster"]:
|
||||||
players.append("{0} ({1})".format(plr, var.get_role(plr)))
|
players.append("{0} ({1})".format(plr, var.get_role(plr)))
|
||||||
@ -2648,7 +2649,7 @@ def chk_win_conditions(lpl, lwolves, lcubs, lrealwolves, lmonsters, ltraitors, l
|
|||||||
debuglog("WIN:", winner)
|
debuglog("WIN:", winner)
|
||||||
debuglog("PLAYERS:", ", ".join(players))
|
debuglog("PLAYERS:", ", ".join(players))
|
||||||
cli.msg(chan, message)
|
cli.msg(chan, message)
|
||||||
stop_game(cli, winner)
|
stop_game(cli, winner, winners=event.data["winners"])
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def del_player(cli, nick, forced_death = False, devoice = True, end_game = True, death_triggers = True, killer_role = "", deadlist = [], original = "", cmode = [], ismain = True):
|
def del_player(cli, nick, forced_death = False, devoice = True, end_game = True, death_triggers = True, killer_role = "", deadlist = [], original = "", cmode = [], ismain = True):
|
||||||
|
Loading…
Reference in New Issue
Block a user