Merge pull request #80 from lykoss/new-rolesets
<+jacob1> !moo , is someone going to press the Merge pull request button on https://github.com/lykoss/lykos/pull/80 eventually or do I have to :P Rolesets are picked randomly + 4 new rolesets
This commit is contained in:
commit
6e372566c6
@ -69,10 +69,7 @@ var.PLAYERS = {}
|
||||
var.DCED_PLAYERS = {}
|
||||
var.ADMIN_TO_PING = None
|
||||
var.AFTER_FLASTGAME = None
|
||||
var.PHASE = "none" # "join", "day", or "night"
|
||||
var.TIMERS = {}
|
||||
var.DEAD = []
|
||||
var.NO_LYNCH = []
|
||||
|
||||
var.ORIGINAL_SETTINGS = {}
|
||||
|
||||
@ -81,15 +78,12 @@ var.LAST_SAID_TIME = {}
|
||||
var.GAME_START_TIME = datetime.now() # for idle checker only
|
||||
var.CAN_START_TIME = 0
|
||||
var.GRAVEYARD_LOCK = threading.RLock()
|
||||
var.GAME_ID = 0
|
||||
var.STARTED_DAY_PLAYERS = 0
|
||||
|
||||
var.DISCONNECTED = {} # players who got disconnected
|
||||
|
||||
var.LOGGER = WolfgameLogger(var.LOG_FILENAME, var.BARE_LOG_FILENAME)
|
||||
|
||||
var.JOINED_THIS_GAME = [] # keeps track of who already joined this game at least once (cloaks)
|
||||
|
||||
var.OPPED = False # Keeps track of whether the bot is opped
|
||||
|
||||
if botconfig.DEBUG_MODE:
|
||||
@ -207,13 +201,16 @@ def reset_modes_timers(cli):
|
||||
cmodes.append(("-q", deadguy+"!*@*"))
|
||||
mass_mode(cli, cmodes)
|
||||
|
||||
def reset(cli):
|
||||
var.PHASE = "none"
|
||||
def reset():
|
||||
var.PHASE = "none" # "join", "day", or "night"
|
||||
var.GAME_ID = 0
|
||||
var.DEAD = []
|
||||
var.ROLES = {"person" : []}
|
||||
var.JOINED_THIS_GAME = []
|
||||
var.JOINED_THIS_GAME = [] # keeps track of who already joined this game at least once (cloaks)
|
||||
var.NO_LYNCH = []
|
||||
var.FGAMED = False
|
||||
var.CURRENT_GAMEMODE = "default"
|
||||
var.GAMEMODE_VOTES = {} #list of players who have used !game
|
||||
|
||||
reset_settings()
|
||||
|
||||
@ -221,6 +218,7 @@ def reset(cli):
|
||||
dict.clear(var.PLAYERS)
|
||||
dict.clear(var.DCED_PLAYERS)
|
||||
dict.clear(var.DISCONNECTED)
|
||||
reset()
|
||||
|
||||
def make_stasis(nick, penalty):
|
||||
try:
|
||||
@ -244,7 +242,7 @@ def forced_exit(cli, nick, *rest): # Admin Only
|
||||
stop_game(cli)
|
||||
else:
|
||||
reset_modes_timers(cli)
|
||||
reset(cli)
|
||||
reset()
|
||||
|
||||
cli.quit("Forced quit from "+nick)
|
||||
|
||||
@ -259,7 +257,7 @@ def restart_program(cli, nick, *rest):
|
||||
stop_game(cli)
|
||||
else:
|
||||
reset_modes_timers(cli)
|
||||
reset(cli)
|
||||
reset()
|
||||
|
||||
cli.quit("Forced restart from "+nick)
|
||||
raise SystemExit
|
||||
@ -531,7 +529,7 @@ def kill_join(cli, chan):
|
||||
pl.sort(key=lambda x: x.lower())
|
||||
msg = 'PING! {0}'.format(", ".join(pl))
|
||||
reset_modes_timers(cli)
|
||||
reset(cli)
|
||||
reset()
|
||||
cli.msg(chan, msg)
|
||||
cli.msg(chan, 'The current game took too long to start and ' +
|
||||
'has been canceled. If you are still active, ' +
|
||||
@ -1130,123 +1128,128 @@ def stop_game(cli, winner = ""):
|
||||
elif len(lovers) > 2:
|
||||
cli.msg(chan, "The lovers were {0}, and {1}".format(", ".join(lovers[0:-1]), lovers[-1]))
|
||||
|
||||
plrl = {}
|
||||
winners = []
|
||||
for role,ppl in var.ORIGINAL_ROLES.items():
|
||||
if role in var.TEMPLATE_RESTRICTIONS.keys():
|
||||
continue
|
||||
for x in ppl:
|
||||
if x != None:
|
||||
if role == "amnesiac" and x in var.AMNESIACS:
|
||||
plrl[x] = var.FINAL_ROLES[x]
|
||||
elif role != "amnesiac" and x in var.FINAL_ROLES: # role swap
|
||||
plrl[x] = var.FINAL_ROLES[x]
|
||||
else:
|
||||
plrl[x] = role
|
||||
for plr, rol in plrl.items():
|
||||
orol = rol # original role, since we overwrite rol in case of clone
|
||||
splr = plr # plr stripped of the (dced) bit at the front, since other dicts don't have that
|
||||
if plr.startswith("(dced)") and plr[6:] in var.DCED_PLAYERS.keys():
|
||||
acc = var.DCED_PLAYERS[plr[6:]]["account"]
|
||||
splr = plr[6:]
|
||||
elif plr in var.PLAYERS.keys():
|
||||
acc = var.PLAYERS[plr]["account"]
|
||||
else:
|
||||
acc = "*" #probably fjoin'd fake
|
||||
|
||||
if rol == "clone":
|
||||
# see if they became a different role
|
||||
if splr in var.FINAL_ROLES:
|
||||
rol = var.FINAL_ROLES[splr]
|
||||
|
||||
won = False
|
||||
iwon = False
|
||||
# determine if this player's team won
|
||||
if rol in var.WOLFTEAM_ROLES: # the player was wolf-aligned
|
||||
if winner == "wolves":
|
||||
won = True
|
||||
elif rol in var.TRUE_NEUTRAL_ROLES:
|
||||
# true neutral roles never have a team win (with exception of monsters), only individual wins
|
||||
if winner == "monsters" and rol == "monster":
|
||||
won = True
|
||||
elif rol in ("amnesiac", "vengeful ghost"):
|
||||
if var.DEFAULT_ROLE == "villager" and winner == "villagers":
|
||||
won = True
|
||||
elif var.DEFAULT_ROLE == "cultist" and winner == "wolves":
|
||||
won = True
|
||||
else:
|
||||
if winner == "villagers":
|
||||
won = True
|
||||
|
||||
survived = var.list_players()
|
||||
if plr.startswith("(dced)"):
|
||||
# You get NOTHING! You LOSE! Good DAY, sir!
|
||||
won = False
|
||||
iwon = False
|
||||
elif rol == "fool" and "@" + splr == winner:
|
||||
iwon = True
|
||||
elif rol == "monster" and splr in survived and winner == "monsters":
|
||||
iwon = True
|
||||
elif splr in var.LOVERS and splr in survived:
|
||||
for lvr in var.LOVERS[splr]:
|
||||
if lvr in plrl:
|
||||
lvrrol = plrl[lvr]
|
||||
elif ("(dced)" + lvr) in plrl:
|
||||
lvrrol = plrl["(dced)" + lvr]
|
||||
if lvrrol == "clone" and lvr in var.FINAL_ROLES:
|
||||
lvrrol = var.FINAL_ROLES[lvr]
|
||||
|
||||
if lvr in survived and not winner.startswith("@") and winner != "monsters":
|
||||
iwon = True
|
||||
break
|
||||
elif lvr in survived and winner.startswith("@") and winner == "@" + lvr and var.LOVER_WINS_WITH_FOOL:
|
||||
iwon = True
|
||||
break
|
||||
elif lvr in survived and winner == "monsters" and lvrrol == "monster":
|
||||
iwon = True
|
||||
break
|
||||
|
||||
if plr.startswith("(dced)"):
|
||||
won = False
|
||||
iwon = False
|
||||
elif rol == "crazed shaman" or rol == "clone":
|
||||
# For clone, this means they ended game while being clone and not some other role
|
||||
if splr in survived and not winner.startswith("@") and winner != "monsters":
|
||||
iwon = True
|
||||
elif rol == "vengeful ghost":
|
||||
if not winner.startswith("@") and winner != "monsters":
|
||||
if won and splr in survived:
|
||||
iwon = True
|
||||
elif splr in var.VENGEFUL_GHOSTS and var.VENGEFUL_GHOSTS[splr] == "villagers" and winner == "wolves":
|
||||
won = True
|
||||
iwon = True
|
||||
elif splr in var.VENGEFUL_GHOSTS and var.VENGEFUL_GHOSTS[splr] == "wolves" and winner == "villagers":
|
||||
won = True
|
||||
iwon = True
|
||||
elif rol == "lycan" or splr in var.LYCANS:
|
||||
if splr in var.LYCANS and winner == "wolves":
|
||||
won = True
|
||||
elif splr not in var.LYCANS and winner == "villagers":
|
||||
won = True
|
||||
else:
|
||||
won = False
|
||||
if not iwon:
|
||||
iwon = won and splr in survived
|
||||
elif rol == "jester" and splr in var.JESTERS:
|
||||
iwon = True
|
||||
elif not iwon:
|
||||
iwon = won and splr in survived # survived, team won = individual win
|
||||
|
||||
if acc != "*":
|
||||
var.update_role_stats(acc, orol, won, iwon)
|
||||
|
||||
if won or iwon:
|
||||
winners.append(splr)
|
||||
|
||||
size = len(survived) + len(var.DEAD)
|
||||
# Only update if someone actually won, "" indicates everyone died or abnormal game stop
|
||||
if winner != "":
|
||||
var.update_game_stats(size, winner)
|
||||
plrl = {}
|
||||
winners = []
|
||||
for role,ppl in var.ORIGINAL_ROLES.items():
|
||||
if role in var.TEMPLATE_RESTRICTIONS.keys():
|
||||
continue
|
||||
for x in ppl:
|
||||
if x != None:
|
||||
if role == "amnesiac" and x in var.AMNESIACS:
|
||||
plrl[x] = var.FINAL_ROLES[x]
|
||||
elif role != "amnesiac" and x in var.FINAL_ROLES: # role swap
|
||||
plrl[x] = var.FINAL_ROLES[x]
|
||||
else:
|
||||
plrl[x] = role
|
||||
for plr, rol in plrl.items():
|
||||
orol = rol # original role, since we overwrite rol in case of clone
|
||||
splr = plr # plr stripped of the (dced) bit at the front, since other dicts don't have that
|
||||
if plr.startswith("(dced)") and plr[6:] in var.DCED_PLAYERS.keys():
|
||||
acc = var.DCED_PLAYERS[plr[6:]]["account"]
|
||||
splr = plr[6:]
|
||||
elif plr in var.PLAYERS.keys():
|
||||
acc = var.PLAYERS[plr]["account"]
|
||||
else:
|
||||
acc = "*" #probably fjoin'd fake
|
||||
|
||||
if rol == "clone":
|
||||
# see if they became a different role
|
||||
if splr in var.FINAL_ROLES:
|
||||
rol = var.FINAL_ROLES[splr]
|
||||
|
||||
won = False
|
||||
iwon = False
|
||||
# determine if this player's team won
|
||||
if rol in var.WOLFTEAM_ROLES: # the player was wolf-aligned
|
||||
if winner == "wolves":
|
||||
won = True
|
||||
elif rol in var.TRUE_NEUTRAL_ROLES:
|
||||
# true neutral roles never have a team win (with exception of monsters), only individual wins
|
||||
if winner == "monsters" and rol == "monster":
|
||||
won = True
|
||||
elif rol in ("amnesiac", "vengeful ghost"):
|
||||
if var.DEFAULT_ROLE == "villager" and winner == "villagers":
|
||||
won = True
|
||||
elif var.DEFAULT_ROLE == "cultist" and winner == "wolves":
|
||||
won = True
|
||||
else:
|
||||
if winner == "villagers":
|
||||
won = True
|
||||
|
||||
survived = var.list_players()
|
||||
if plr.startswith("(dced)"):
|
||||
# You get NOTHING! You LOSE! Good DAY, sir!
|
||||
won = False
|
||||
iwon = False
|
||||
elif rol == "fool" and "@" + splr == winner:
|
||||
iwon = True
|
||||
elif rol == "monster" and splr in survived and winner == "monsters":
|
||||
iwon = True
|
||||
elif splr in var.LOVERS and splr in survived:
|
||||
for lvr in var.LOVERS[splr]:
|
||||
lvrrol = "" #somehow lvrrol wasn't set and caused a crash once
|
||||
if lvr in plrl:
|
||||
lvrrol = plrl[lvr]
|
||||
elif ("(dced)" + lvr) in plrl:
|
||||
lvrrol = plrl["(dced)" + lvr]
|
||||
if lvrrol == "clone" and lvr in var.FINAL_ROLES:
|
||||
lvrrol = var.FINAL_ROLES[lvr]
|
||||
|
||||
if lvr in survived and not winner.startswith("@") and winner != "monsters":
|
||||
iwon = True
|
||||
break
|
||||
elif lvr in survived and winner.startswith("@") and winner == "@" + lvr and var.LOVER_WINS_WITH_FOOL:
|
||||
iwon = True
|
||||
break
|
||||
elif lvr in survived and winner == "monsters" and lvrrol == "monster":
|
||||
iwon = True
|
||||
break
|
||||
|
||||
if plr.startswith("(dced)"):
|
||||
won = False
|
||||
iwon = False
|
||||
elif rol == "crazed shaman" or rol == "clone":
|
||||
# For clone, this means they ended game while being clone and not some other role
|
||||
if splr in survived and not winner.startswith("@") and winner != "monsters":
|
||||
iwon = True
|
||||
elif rol == "vengeful ghost":
|
||||
if not winner.startswith("@") and winner != "monsters":
|
||||
if won and splr in survived:
|
||||
iwon = True
|
||||
elif splr in var.VENGEFUL_GHOSTS and var.VENGEFUL_GHOSTS[splr] == "villagers" and winner == "wolves":
|
||||
won = True
|
||||
iwon = True
|
||||
elif splr in var.VENGEFUL_GHOSTS and var.VENGEFUL_GHOSTS[splr] == "wolves" and winner == "villagers":
|
||||
won = True
|
||||
iwon = True
|
||||
elif rol == "lycan" or splr in var.LYCANS:
|
||||
if splr in var.LYCANS and winner == "wolves":
|
||||
won = True
|
||||
elif splr not in var.LYCANS and winner == "villagers":
|
||||
won = True
|
||||
else:
|
||||
won = False
|
||||
if not iwon:
|
||||
iwon = won and splr in survived
|
||||
elif rol == "jester" and splr in var.JESTERS:
|
||||
iwon = True
|
||||
elif not iwon:
|
||||
iwon = won and splr in survived # survived, team won = individual win
|
||||
|
||||
if acc != "*":
|
||||
var.update_role_stats(acc, orol, won, iwon)
|
||||
for role in var.TEMPLATE_RESTRICTIONS.keys():
|
||||
if plr in var.ORIGINAL_ROLES[role]:
|
||||
var.update_role_stats(acc, role, won, iwon)
|
||||
if splr in var.LOVERS:
|
||||
var.update_role_stats(acc, "lover", won, iwon)
|
||||
|
||||
if won or iwon:
|
||||
winners.append(splr)
|
||||
|
||||
var.update_game_stats(var.CURRENT_GAMEMODE, len(survived) + len(var.DEAD), winner)
|
||||
|
||||
# spit out the list of winners
|
||||
winners.sort()
|
||||
@ -1264,9 +1267,9 @@ def stop_game(cli, winner = ""):
|
||||
var.PHASE = "writing files"
|
||||
|
||||
var.LOGGER.saveToFile()
|
||||
reset(cli)
|
||||
reset()
|
||||
|
||||
# This must be after reset(cli)
|
||||
# This must be after reset()
|
||||
if var.AFTER_FLASTGAME:
|
||||
var.AFTER_FLASTGAME()
|
||||
var.AFTER_FLASTGAME = None
|
||||
@ -1285,7 +1288,7 @@ def chk_win(cli, end_game = True):
|
||||
if lpl == 0:
|
||||
#cli.msg(chan, "No more players remaining. Game ended.")
|
||||
reset_modes_timers(cli)
|
||||
reset(cli)
|
||||
reset()
|
||||
return True
|
||||
return False
|
||||
|
||||
@ -1313,7 +1316,7 @@ def chk_win(cli, end_game = True):
|
||||
|
||||
if lpl < 1:
|
||||
message = "Game over! There are no players remaining. Nobody wins."
|
||||
winner = ""
|
||||
winner = "none"
|
||||
elif lwolves == lpl / 2:
|
||||
if len(var.ROLES["monster"]) > 0:
|
||||
plural = "s" if len(var.ROLES["monster"]) > 1 else ""
|
||||
@ -1674,6 +1677,10 @@ def del_player(cli, nick, forced_death = False, devoice = True, end_game = True,
|
||||
var.WOUNDED.remove(nick)
|
||||
if nick in var.ASLEEP:
|
||||
var.ASLEEP.remove(nick)
|
||||
if nick in var.PLAYERS:
|
||||
cloak = var.PLAYERS[nick]["cloak"]
|
||||
if cloak in var.GAMEMODE_VOTES:
|
||||
del var.GAMEMODE_VOTES[cloak]
|
||||
chk_decision(cli)
|
||||
elif var.PHASE == "night" and ret:
|
||||
chk_nightdone(cli)
|
||||
@ -2202,6 +2209,8 @@ def leave_game(cli, nick, chan, rest):
|
||||
var.ORIGINAL_ROLES[r].remove(nick)
|
||||
var.ORIGINAL_ROLES[r].append("(dced)"+nick)
|
||||
make_stasis(nick, var.LEAVE_STASIS_PENALTY)
|
||||
if nick in var.PLAYERS:
|
||||
var.DCED_PLAYERS[nick] = var.PLAYERS.pop(nick)
|
||||
|
||||
del_player(cli, nick, death_triggers = False)
|
||||
|
||||
@ -4826,13 +4835,14 @@ def cgamemode(cli, arg):
|
||||
if modeargs[0] in var.GAME_MODES.keys():
|
||||
md = modeargs.pop(0)
|
||||
try:
|
||||
gm = var.GAME_MODES[md](*modeargs)
|
||||
gm = var.GAME_MODES[md][0](*modeargs)
|
||||
for attr in dir(gm):
|
||||
val = getattr(gm, attr)
|
||||
if (hasattr(var, attr) and not callable(val)
|
||||
and not attr.startswith("_")):
|
||||
var.ORIGINAL_SETTINGS[attr] = getattr(var, attr)
|
||||
setattr(var, attr, val)
|
||||
var.CURRENT_GAMEMODE = md
|
||||
return True
|
||||
except var.InvalidModeException as e:
|
||||
cli.msg(botconfig.CHANNEL, "Invalid mode: "+str(e))
|
||||
@ -4875,9 +4885,24 @@ def start(cli, nick, forced = False):
|
||||
return
|
||||
|
||||
if len(villagers) > var.MAX_PLAYERS:
|
||||
cli.msg(chan, "{0}: At most \u0002{1}\u0002 players may play in this game mode.".format(nick, var.MAX_PLAYERS))
|
||||
cli.msg(chan, "{0}: At most \u0002{1}\u0002 players may play.".format(nick, var.MAX_PLAYERS))
|
||||
return
|
||||
|
||||
if not var.FGAMED:
|
||||
votes = {} #key = gamemode, not cloak
|
||||
for gamemode in var.GAMEMODE_VOTES.values():
|
||||
if len(villagers) >= var.GAME_MODES[gamemode][1] and len(villagers) <= var.GAME_MODES[gamemode][2]:
|
||||
votes[gamemode] = votes.get(gamemode, 0) + 1
|
||||
voted = [gamemode for gamemode in votes if votes[gamemode] == max(votes.values()) and votes[gamemode] >= len(villagers)/2]
|
||||
if len(voted):
|
||||
cgamemode(cli, random.choice(voted))
|
||||
else:
|
||||
possiblegamemodes = []
|
||||
for gamemode in var.GAME_MODES.keys():
|
||||
if len(villagers) >= var.GAME_MODES[gamemode][1] and len(villagers) <= var.GAME_MODES[gamemode][2] and var.GAME_MODES[gamemode][3] > 0:
|
||||
possiblegamemodes += [gamemode]*(var.GAME_MODES[gamemode][3]+votes.get(gamemode, 0)*15)
|
||||
cgamemode(cli, random.choice(possiblegamemodes))
|
||||
|
||||
for index in range(len(var.ROLE_INDEX) - 1, -1, -1):
|
||||
if var.ROLE_INDEX[index] <= len(villagers):
|
||||
addroles = {k:v[index] for k,v in var.ROLE_GUIDE.items()}
|
||||
@ -5032,7 +5057,7 @@ def start(cli, nick, forced = False):
|
||||
var.SPECIAL_ROLES["goat herder"] = [ nick ]
|
||||
|
||||
cli.msg(chan, ("{0}: Welcome to Werewolf, the popular detective/social party "+
|
||||
"game (a theme of Mafia).").format(", ".join(pl)))
|
||||
"game (a theme of Mafia). Using the \002{1}\002 game mode.").format(", ".join(pl), var.CURRENT_GAMEMODE))
|
||||
cli.mode(chan, "+m")
|
||||
|
||||
var.ORIGINAL_ROLES = copy.deepcopy(var.ROLES) # Make a copy
|
||||
@ -5382,7 +5407,7 @@ def reset_game(cli, nick, chan, rest):
|
||||
stop_game(cli)
|
||||
else:
|
||||
reset_modes_timers(cli)
|
||||
reset(cli)
|
||||
reset()
|
||||
|
||||
|
||||
@pmcmd("rules")
|
||||
@ -5616,23 +5641,25 @@ def listroles(cli, nick, chan, rest):
|
||||
#prepend player count if called without any arguments
|
||||
if not len(rest[0]) and pl > 0:
|
||||
txt += " {0}: There {1} \u0002{2}\u0002 playing.".format(nick, "is" if pl == 1 else "are", pl)
|
||||
if var.PHASE in ["night", "day"]:
|
||||
txt += " Using the {0} game mode.".format(var.CURRENT_GAMEMODE)
|
||||
|
||||
#read game mode to get roles for
|
||||
if len(rest[0]) and not rest[0].isdigit():
|
||||
#check for valid roleset ("roles" roleset is treated as invalid)
|
||||
#check for valid game mode ("roles" gamemode is treated as invalid)
|
||||
if rest[0] != "roles" and rest[0] in var.GAME_MODES.keys():
|
||||
mode = var.GAME_MODES[rest[0]]()
|
||||
mode = var.GAME_MODES[rest[0]][0]()
|
||||
if hasattr(mode, "ROLE_INDEX"):
|
||||
roleindex = getattr(mode, "ROLE_INDEX")
|
||||
if hasattr(mode, "ROLE_GUIDE"):
|
||||
roleguide = getattr(mode, "ROLE_GUIDE")
|
||||
rest.pop(0)
|
||||
else:
|
||||
txt += " {0}: {1} is not a valid roleset.".format(nick, rest[0])
|
||||
txt += " {0}: {1} is not a valid game mode.".format(nick, rest[0])
|
||||
rest = []
|
||||
roleindex = {}
|
||||
|
||||
#number of players to print the roleset for
|
||||
#number of players to print the game mode for
|
||||
if len(rest) and rest[0].isdigit():
|
||||
index = int(rest[0])
|
||||
for i in range(len(roleindex)-1, -1, -1):
|
||||
@ -5824,38 +5851,45 @@ def game_stats(cli, nick, chan, rest):
|
||||
if (chan != nick and var.LAST_GSTATS and var.GSTATS_RATE_LIMIT and
|
||||
var.LAST_GSTATS + timedelta(seconds=var.GSTATS_RATE_LIMIT) >
|
||||
datetime.now()):
|
||||
cli.notice(nick, ('This command is rate-limited. Please wait a while '
|
||||
'before using it again.'))
|
||||
cli.notice(nick, ("This command is rate-limited. Please wait a while "
|
||||
"before using it again."))
|
||||
return
|
||||
|
||||
if chan != nick:
|
||||
var.LAST_GSTATS = datetime.now()
|
||||
|
||||
if var.PHASE not in ('none', 'join'):
|
||||
cli.notice(nick, 'Wait until the game is over to view stats.')
|
||||
cli.notice(nick, "Wait until the game is over to view stats.")
|
||||
return
|
||||
|
||||
gamemode = var.CURRENT_GAMEMODE
|
||||
rest = rest.strip().split()
|
||||
# Check for gamemode
|
||||
if len(rest) and not rest[0].isdigit():
|
||||
gamemode = rest[0]
|
||||
if gamemode not in var.GAME_MODES.keys():
|
||||
cli.notice(nick, "{0} is not a valid game mode".format(gamemode))
|
||||
return
|
||||
rest.pop(0)
|
||||
# Check for invalid input
|
||||
if len(rest) and rest[0].isdigit() and (
|
||||
int(rest[0]) > var.GAME_MODES[gamemode][2] or int(rest[0]) < var.GAME_MODES[gamemode][1]):
|
||||
cli.notice(nick, "Please enter an integer between "+\
|
||||
"{0} and {1}.".format(var.GAME_MODES[gamemode][1], var.GAME_MODES[gamemode][2]))
|
||||
return
|
||||
|
||||
# List all games sizes and totals if no size is given
|
||||
if not rest:
|
||||
if not len(rest):
|
||||
if chan == nick:
|
||||
pm(cli, nick, var.get_game_totals())
|
||||
pm(cli, nick, var.get_game_totals(gamemode))
|
||||
else:
|
||||
cli.msg(chan, var.get_game_totals())
|
||||
|
||||
return
|
||||
|
||||
# Check for invalid input
|
||||
rest = rest.strip()
|
||||
if not rest.isdigit() or int(rest) > var.MAX_PLAYERS or int(rest) < var.MIN_PLAYERS:
|
||||
cli.notice(nick, ('Please enter an integer between {} and '
|
||||
'{}.').format(var.MIN_PLAYERS, var.MAX_PLAYERS))
|
||||
return
|
||||
|
||||
# Attempt to find game stats for the given game size
|
||||
if chan == nick:
|
||||
pm(cli, nick, var.get_game_stats(int(rest)))
|
||||
cli.msg(chan, var.get_game_totals(gamemode))
|
||||
else:
|
||||
cli.msg(chan, var.get_game_stats(int(rest)))
|
||||
# Attempt to find game stats for the given game size
|
||||
if chan == nick:
|
||||
pm(cli, nick, var.get_game_stats(gamemode, int(rest[0])))
|
||||
else:
|
||||
cli.msg(chan, var.get_game_stats(gamemode, int(rest[0])))
|
||||
|
||||
|
||||
@pmcmd('gamestats', 'gstats')
|
||||
@ -5923,6 +5957,52 @@ def player_stats(cli, nick, chan, rest):
|
||||
def player_stats_pm(cli, nick, rest):
|
||||
player_stats(cli, nick, nick, rest)
|
||||
|
||||
@cmd('game', raw_nick = True)
|
||||
def game(cli, nick, chan, rest):
|
||||
nick, _, __, cloak = parse_nick(nick)
|
||||
if var.PHASE == "none":
|
||||
cli.notice(nick, "No game is currently running.")
|
||||
return
|
||||
if var.PHASE != "join":
|
||||
cli.notice(nick, "Werewolf is already in play.")
|
||||
return
|
||||
if nick not in var.list_players():
|
||||
cli.notice(nick, "You're currently not playing.")
|
||||
return
|
||||
|
||||
if rest:
|
||||
gamemode = rest.lower().split()[0]
|
||||
else:
|
||||
gamemodes = ", ".join(["\002{}\002".format(gamemode) if len(var.list_players()) in range(var.GAME_MODES[gamemode][1],
|
||||
var.GAME_MODES[gamemode][2]+1) else gamemode for gamemode in var.GAME_MODES.keys() if gamemode != "roles"])
|
||||
cli.notice(nick, "No game mode specified. Available game modes: " + gamemodes)
|
||||
return
|
||||
|
||||
if gamemode not in var.GAME_MODES.keys():
|
||||
#players can vote by only using partial name
|
||||
matches = 0
|
||||
possiblegamemode = gamemode
|
||||
for mode in var.GAME_MODES.keys():
|
||||
if mode.startswith(gamemode) and mode != "roles":
|
||||
possiblegamemode = mode
|
||||
matches += 1
|
||||
if matches != 1:
|
||||
cli.notice(nick, "\002{0}\002 is not a valid game mode.".format(gamemode))
|
||||
return
|
||||
else:
|
||||
gamemode = possiblegamemode
|
||||
|
||||
if gamemode != "roles":
|
||||
var.GAMEMODE_VOTES[cloak] = gamemode
|
||||
cli.msg(chan, "\002{0}\002 votes for the \002{1}\002 game mode.".format(nick, gamemode))
|
||||
else:
|
||||
cli.notice(nick, "You can't vote for that game mode.")
|
||||
|
||||
def game_help(args=''):
|
||||
return "Votes to make a specific game mode more likely. Available game mode setters: " +\
|
||||
", ".join(["\002{}\002".format(gamemode) if len(var.list_players()) in range(var.GAME_MODES[gamemode][1], var.GAME_MODES[gamemode][2]+1)
|
||||
else gamemode for gamemode in var.GAME_MODES.keys() if gamemode != "roles"])
|
||||
game.__doc__ = game_help
|
||||
|
||||
@cmd("fpull", admin_only=True)
|
||||
def fpull(cli, nick, chan, rest):
|
||||
@ -6076,13 +6156,26 @@ if botconfig.DEBUG_MODE or botconfig.ALLOWED_NORMAL_MODE_COMMANDS:
|
||||
cli.notice(nick, 'You\'re currently not playing.')
|
||||
return
|
||||
|
||||
rest = rest.strip().lower()
|
||||
|
||||
if rest:
|
||||
if cgamemode(cli, rest):
|
||||
rest = mode = rest.strip().lower()
|
||||
if rest not in var.GAME_MODES.keys() and not rest.startswith("roles"):
|
||||
rest = rest.split()[0]
|
||||
#players can vote by only using partial name
|
||||
matches = 0
|
||||
for gamemode in var.GAME_MODES.keys():
|
||||
if gamemode.startswith(rest):
|
||||
mode = gamemode
|
||||
matches += 1
|
||||
if matches != 1:
|
||||
cli.notice(nick, "\002{0}\002 is not a valid game mode.".format(rest))
|
||||
return
|
||||
|
||||
if cgamemode(cli, mode):
|
||||
cli.msg(chan, ('\u0002{}\u0002 has changed the game settings '
|
||||
'successfully.').format(nick))
|
||||
|
||||
var.FGAMED = True
|
||||
else:
|
||||
cli.notice(nick, fgame.__doc__())
|
||||
|
||||
def fgame_help(args=''):
|
||||
args = args.strip()
|
||||
@ -6090,7 +6183,10 @@ if botconfig.DEBUG_MODE or botconfig.ALLOWED_NORMAL_MODE_COMMANDS:
|
||||
if not args:
|
||||
return 'Available game mode setters: ' + ', '.join(var.GAME_MODES.keys())
|
||||
elif args in var.GAME_MODES.keys():
|
||||
return var.GAME_MODES[args].__doc__
|
||||
if hasattr(var.GAME_MODES[args][0], "__doc__"):
|
||||
return var.GAME_MODES[args][0].__doc__
|
||||
else:
|
||||
return "Game mode {0} has no doc string".format(args)
|
||||
else:
|
||||
return 'Game mode setter \u0002{}\u0002 not found.'.format(args)
|
||||
|
||||
|
@ -283,9 +283,9 @@ def break_long_message(phrases, joinstr = " "):
|
||||
return message
|
||||
|
||||
class InvalidModeException(Exception): pass
|
||||
def game_mode(name):
|
||||
def game_mode(name, minp, maxp, likelihood = 0):
|
||||
def decor(c):
|
||||
GAME_MODES[name] = c
|
||||
GAME_MODES[name] = (c, minp, maxp, likelihood)
|
||||
return c
|
||||
return decor
|
||||
|
||||
@ -296,11 +296,12 @@ def reset_roles(index):
|
||||
return newguide
|
||||
|
||||
# TODO: implement more game modes
|
||||
@game_mode("roles")
|
||||
@game_mode("roles", minp = 4, maxp = 35)
|
||||
class ChangedRolesMode(object):
|
||||
"""Example: !fgame roles=wolf:1,seer:0,guardian angel:1"""
|
||||
|
||||
def __init__(self, arg = ""):
|
||||
self.MAX_PLAYERS = 35
|
||||
self.ROLE_GUIDE = ROLE_GUIDE.copy()
|
||||
self.ROLE_INDEX = (MIN_PLAYERS,)
|
||||
pairs = arg.split(",")
|
||||
@ -338,19 +339,76 @@ class ChangedRolesMode(object):
|
||||
except ValueError:
|
||||
raise InvalidModeException("A bad value was used in mode roles.")
|
||||
|
||||
@game_mode("default")
|
||||
@game_mode("default", minp = 4, maxp = 24, likelihood = 15)
|
||||
class DefaultMode(object):
|
||||
"""Default game mode."""
|
||||
def __init__(self):
|
||||
# No extra settings, just an explicit way to revert to default settings
|
||||
pass
|
||||
|
||||
@game_mode("foolish", minp = 8,maxp = 24, likelihood = 7)
|
||||
class FoolishMode(object):
|
||||
"""Contains the fool, be careful not to lynch them!"""
|
||||
def __init__(self):
|
||||
self.ROLE_INDEX = ( 8 , 9 , 10 , 11 , 12 , 15 , 17 , 20 , 21 , 22 , 24 )
|
||||
self.ROLE_GUIDE = reset_roles(self.ROLE_INDEX)
|
||||
self.ROLE_GUIDE.update({# village roles
|
||||
"oracle" : ( 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
"harlot" : ( 1 , 1 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 ),
|
||||
"bodyguard" : ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 ),
|
||||
"augur" : ( 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
"hunter" : ( 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
"shaman" : ( 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
# wolf roles
|
||||
"wolf" : ( 1 , 1 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 ),
|
||||
"traitor" : ( 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2 , 2 , 2 ),
|
||||
"wolf cub" : ( 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
"sorcerer" : ( 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
# neutral roles
|
||||
"clone" : ( 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
"fool" : ( 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
# templates
|
||||
"cursed villager" : ( 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
"gunner" : ( 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 2 , 2 ),
|
||||
"sharpshooter" : ( 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
"mayor" : ( 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
})
|
||||
|
||||
@game_mode("mad", minp = 7, maxp = 22, likelihood = 7)
|
||||
class MadMode(object):
|
||||
"""This game mode has mad scientist and many things that may kill you."""
|
||||
def __init__(self):
|
||||
self.ROLE_INDEX = ( 7 , 8 , 10 , 12 , 14 , 15 , 17 , 18 , 20 )
|
||||
self.ROLE_GUIDE = reset_roles(self.ROLE_INDEX)
|
||||
self.ROLE_GUIDE.update({# village roles
|
||||
"seer" : ( 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
"mad scientist" : ( 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
"detective" : ( 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
"guardian angel" : ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ),
|
||||
"hunter" : ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 ),
|
||||
"harlot" : ( 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 ),
|
||||
"village drunk" : ( 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
# wolf roles
|
||||
"wolf" : ( 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 ),
|
||||
"traitor" : ( 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
"werecrow" : ( 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
"wolf cub" : ( 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 2 ),
|
||||
"cultist" : ( 1 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
# neutral roles
|
||||
"vengeful ghost" : ( 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 ),
|
||||
"jester" : ( 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 ),
|
||||
# templates
|
||||
"cursed villager" : ( 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
"gunner" : ( 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
"sharpshooter" : ( 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
"assassin" : ( 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 ),
|
||||
})
|
||||
|
||||
# evilvillage is broken, disable for now
|
||||
#@game_mode("evilvillage")
|
||||
#@game_mode("evilvillage", minp = 6, maxp = 18)
|
||||
class EvilVillageMode(object):
|
||||
"""Majority of the village is wolf aligned, safes must secretly try to kill the wolves."""
|
||||
def __init__(self):
|
||||
self.MIN_PLAYERS = 6
|
||||
self.MAX_PLAYERS = 18
|
||||
self.DEFAULT_ROLE = "cultist"
|
||||
self.ROLE_INDEX = ( 6 , 10 , 15 )
|
||||
self.ROLE_GUIDE = reset_roles(self.ROLE_INDEX)
|
||||
@ -368,11 +426,10 @@ class EvilVillageMode(object):
|
||||
"fool" : ( 0 , 1 , 1 ),
|
||||
})
|
||||
|
||||
@game_mode("classic")
|
||||
@game_mode("classic", minp = 4, maxp = 21, likelihood = 4)
|
||||
class ClassicMode(object):
|
||||
"""Classic game mode from before all the changes."""
|
||||
def __init__(self):
|
||||
self.MIN_PLAYERS = 4
|
||||
self.MAX_PLAYERS = 21
|
||||
self.ROLE_INDEX = ( 4 , 6 , 8 , 10 , 12 , 15 , 17 , 18 , 20 )
|
||||
self.ROLE_GUIDE = reset_roles(self.ROLE_INDEX)
|
||||
self.ROLE_GUIDE.update({# village roles
|
||||
@ -390,11 +447,10 @@ class ClassicMode(object):
|
||||
"gunner" : ( 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
})
|
||||
|
||||
@game_mode("rapidfire")
|
||||
@game_mode("rapidfire", minp = 6, maxp = 24, likelihood = 0)
|
||||
class RapidFireMode(object):
|
||||
"""Many roles that lead to multiple chain deaths."""
|
||||
def __init__(self):
|
||||
self.MIN_PLAYERS = 6
|
||||
self.MAX_PLAYERS = 25
|
||||
self.SHARPSHOOTER_CHANCE = 1
|
||||
self.DAY_TIME_LIMIT = 480
|
||||
self.DAY_TIME_WARN = 360
|
||||
@ -423,11 +479,41 @@ class RapidFireMode(object):
|
||||
"sharpshooter" : ( 0 , 0 , 1 , 1 , 1 , 1 , 1 ),
|
||||
})
|
||||
|
||||
@game_mode("noreveal")
|
||||
class NoRevealMode(object):
|
||||
@game_mode("drunkfire", minp = 8, maxp = 17, likelihood = 0)
|
||||
class DrunkFireMode(object):
|
||||
"""Most players get a gun, quickly shoot all the wolves!"""
|
||||
def __init__(self):
|
||||
self.SHARPSHOOTER_CHANCE = 1
|
||||
self.DAY_TIME_LIMIT = 480
|
||||
self.DAY_TIME_WARN = 360
|
||||
self.SHORT_DAY_LIMIT = 240
|
||||
self.SHORT_DAY_WARN = 180
|
||||
self.NIGHT_TIME_LIMIT = 60
|
||||
self.NIGHT_TIME_WARN = 40 # HIT MISS SUICIDE HEADSHOT
|
||||
self.GUN_CHANCES = ( 3/7 , 3/7 , 1/7 , 4/5 )
|
||||
self.WOLF_GUN_CHANCES = ( 4/7 , 3/7 , 0/7 , 1 )
|
||||
self.ROLE_INDEX = ( 8 , 10 , 12 , 14 , 16 )
|
||||
self.ROLE_GUIDE = reset_roles(self.ROLE_INDEX)
|
||||
self.ROLE_GUIDE.update({# village roles
|
||||
"seer" : ( 1 , 1 , 1 , 2 , 2 ),
|
||||
"village drunk" : ( 2 , 3 , 4 , 4 , 5 ),
|
||||
# wolf roles
|
||||
"wolf" : ( 1 , 2 , 2 , 3 , 3 ),
|
||||
"traitor" : ( 1 , 1 , 1 , 1 , 2 ),
|
||||
"hag" : ( 0 , 0 , 1 , 1 , 1 ),
|
||||
# neutral roles
|
||||
"crazed shaman" : ( 0 , 0 , 1 , 1 , 1 ),
|
||||
# templates
|
||||
"cursed villager" : ( 1 , 1 , 1 , 1 , 1 ),
|
||||
"assassin" : ( 0 , 0 , 0 , 1 , 1 ),
|
||||
"gunner" : ( 5 , 6 , 7 , 8 , 9 ),
|
||||
"sharpshooter" : ( 2 , 2 , 3 , 3 , 4 ),
|
||||
})
|
||||
|
||||
@game_mode("noreveal", minp = 4, maxp = 21, likelihood = 0)
|
||||
class NoRevealMode(object):
|
||||
"""Roles are not revealed when players die."""
|
||||
def __init__(self):
|
||||
self.MIN_PLAYERS = 4
|
||||
self.MAX_PLAYERS = 21
|
||||
self.ROLE_REVEAL = False
|
||||
self.ROLE_INDEX = ( 4 , 6 , 8 , 10 , 12 , 15 , 17 , 19 )
|
||||
self.ROLE_GUIDE = reset_roles(self.ROLE_INDEX)
|
||||
@ -452,14 +538,38 @@ class NoRevealMode(object):
|
||||
"cursed villager" : ( 0 , 1 , 1 , 1 , 1 , 1 , 2 , 2 ),
|
||||
})
|
||||
|
||||
@game_mode("amnesia")
|
||||
class AmnesiaMode(object):
|
||||
@game_mode("lycan", minp = 7, maxp = 21, likelihood = 1)
|
||||
class LycanMode(object):
|
||||
"""Many lycans will turn into wolves. Hunt them down before the wolves overpower the village."""
|
||||
def __init__(self):
|
||||
self.ROLE_INDEX = ( 7 , 9 , 10 , 12 , 15 , 17 , 20 )
|
||||
self.ROLE_GUIDE = reset_roles(self.ROLE_INDEX)
|
||||
self.ROLE_GUIDE.update({# village roles
|
||||
"seer" : ( 1 , 1 , 1 , 1 , 1 , 1 , 1 ),
|
||||
"guardian angel" : ( 0 , 0 , 1 , 1 , 1 , 1 , 1 ),
|
||||
"detective" : ( 0 , 0 , 0 , 0 , 1 , 1 , 1 ),
|
||||
"matchmaker" : ( 0 , 0 , 0 , 0 , 1 , 1 , 1 ),
|
||||
"hunter" : ( 1 , 1 , 2 , 2 , 2 , 2 , 2 ),
|
||||
# wolf roles
|
||||
"wolf" : ( 1 , 2 , 2 , 2 , 2 , 2 , 2 ),
|
||||
"traitor" : ( 0 , 0 , 0 , 0 , 1 , 1 , 1 ),
|
||||
# neutral roles
|
||||
"clone" : ( 0 , 1 , 1 , 1 , 1 , 2 , 2 ),
|
||||
"lycan" : ( 1 , 2 , 2 , 3 , 4 , 4 , 5 ),
|
||||
# templates
|
||||
"cursed villager" : ( 1 , 1 , 1 , 2 , 2 , 2 , 2 ),
|
||||
"gunner" : ( 0 , 0 , 0 , 0 , 0 , 1 , 1 ),
|
||||
"sharpshooter" : ( 0 , 0 , 0 , 0 , 0 , 1 , 1 ),
|
||||
"mayor" : ( 0 , 0 , 1 , 1 , 1 , 1 , 1 ),
|
||||
})
|
||||
|
||||
@game_mode("amnesia", minp = 10, maxp = 24, likelihood = 0)
|
||||
class AmnesiaMode(object):
|
||||
"""Everyone gets assigned a random role on night 3."""
|
||||
def __init__(self):
|
||||
self.MIN_PLAYERS = 10
|
||||
self.MAX_PLAYERS = 24
|
||||
self.DEFAULT_ROLE = "cultist"
|
||||
self.HIDDEN_AMNESIAC = False
|
||||
self.ROLE_INDEX = range(self.MIN_PLAYERS, self.MAX_PLAYERS + 1)
|
||||
self.ROLE_INDEX = range(10, 25)
|
||||
self.ROLE_GUIDE = reset_roles(self.ROLE_INDEX)
|
||||
self.ROLE_GUIDE.update({
|
||||
"wolf" : [2 for i in self.ROLE_INDEX],
|
||||
@ -469,13 +579,12 @@ class AmnesiaMode(object):
|
||||
|
||||
# Credits to Metacity for designing and current name
|
||||
# Blame arkiwitect for the original name of KrabbyPatty
|
||||
@game_mode("aleatoire")
|
||||
@game_mode("aleatoire", minp = 4, maxp = 24, likelihood = 3)
|
||||
class AleatoireMode(object):
|
||||
"""Game mode created by Metacity and balanced by woffle."""
|
||||
def __init__(self):
|
||||
self.MIN_PLAYERS = 4
|
||||
self.MAX_PLAYERS = 24
|
||||
self.SHARPSHOOTER_CHANCE = 1
|
||||
# SHAMAN CRAZED SHAMAN
|
||||
# SHAMAN , CRAZED SHAMAN
|
||||
self.TOTEM_CHANCES = { "death": ( 4/20 , 1/15 ),
|
||||
"protection": ( 8/20 , 1/15 ),
|
||||
"silence": ( 2/20 , 1/15 ),
|
||||
@ -584,8 +693,8 @@ with conn:
|
||||
'UNIQUE(player, role))'))
|
||||
|
||||
|
||||
c.execute(('CREATE TABLE IF NOT EXISTS gamestats (size SMALLINT, villagewins SMALLINT, ' +
|
||||
'wolfwins SMALLINT, totalgames SMALLINT, UNIQUE(size))'))
|
||||
c.execute(('CREATE TABLE IF NOT EXISTS gamestats (gamemode TEXT, size SMALLINT, villagewins SMALLINT, ' +
|
||||
'wolfwins SMALLINT, monsterwins SMALLINT, foolwins SMALLINT, totalgames SMALLINT, UNIQUE(gamemode, size))'))
|
||||
|
||||
|
||||
if OPT_IN_PING:
|
||||
@ -671,27 +780,31 @@ def update_role_stats(acc, role, won, iwon):
|
||||
c.execute("INSERT OR REPLACE INTO rolestats VALUES (?,?,?,?,?)",
|
||||
(acc, role, wins, iwins, total))
|
||||
|
||||
def update_game_stats(size, winner):
|
||||
def update_game_stats(gamemode, size, winner):
|
||||
with conn:
|
||||
vwins, wwins, total = 0, 0, 0
|
||||
vwins, wwins, mwins, fwins, total = 0, 0, 0, 0, 0
|
||||
|
||||
c.execute("SELECT villagewins, wolfwins, totalgames FROM gamestats "+
|
||||
"WHERE size=?", (size,))
|
||||
c.execute("SELECT villagewins, wolfwins, monsterwins, foolwins, totalgames "+
|
||||
"FROM gamestats WHERE gamemode=? AND size=?", (gamemode, size))
|
||||
row = c.fetchone()
|
||||
if row:
|
||||
vwins, wwins, total = row
|
||||
vwins, wwins, mwins, fwins, total = row
|
||||
|
||||
if winner == "wolves":
|
||||
wwins += 1
|
||||
elif winner == "villagers":
|
||||
vwins += 1
|
||||
elif winner == "monsters":
|
||||
mwins += 1
|
||||
elif winner.startswith("@"):
|
||||
fwins += 1
|
||||
total += 1
|
||||
|
||||
c.execute("INSERT OR REPLACE INTO gamestats VALUES (?,?,?,?)",
|
||||
(size, vwins, wwins, total))
|
||||
c.execute("INSERT OR REPLACE INTO gamestats VALUES (?,?,?,?,?,?,?)",
|
||||
(gamemode, size, vwins, wwins, mwins, fwins, total))
|
||||
|
||||
def get_player_stats(acc, role):
|
||||
if role.lower() not in [k.lower() for k in ROLE_GUIDE.keys()]:
|
||||
if role.lower() not in [k.lower() for k in ROLE_GUIDE.keys()] and role != "lover":
|
||||
return "No such role: {0}".format(role)
|
||||
with conn:
|
||||
c.execute("SELECT player FROM rolestats WHERE player=? COLLATE NOCASE", (acc,))
|
||||
@ -723,27 +836,31 @@ def get_player_totals(acc):
|
||||
else:
|
||||
return "\u0002{0}\u0002 has not played any games.".format(acc)
|
||||
|
||||
def get_game_stats(size):
|
||||
def get_game_stats(gamemode, size):
|
||||
with conn:
|
||||
for row in c.execute("SELECT * FROM gamestats WHERE size=?", (size,)):
|
||||
msg = "\u0002{0}\u0002 player games | Village wins: {1} (%d%%), Wolf wins: {2} (%d%%), Total games: {3}".format(*row)
|
||||
return msg % (round(row[1]/row[3] * 100), round(row[2]/row[3] * 100))
|
||||
for row in c.execute("SELECT * FROM gamestats WHERE gamemode=? AND size=?", (gamemode, size)):
|
||||
msg = "\u0002%d\u0002 player games | Village wins: %d (%d%%), Wolf wins: %d (%d%%)" % (row[1], row[2], round(row[2]/row[6] * 100), row[3], round(row[3]/row[6] * 100))
|
||||
if row[4] > 0:
|
||||
msg += ", Monster wins: %d (%d%%)" % (row[4], round(row[4]/row[6] * 100))
|
||||
if row[5] > 0:
|
||||
msg += ", Fool wins: %d (%d%%)" % (row[5], round(row[5]/row[6] * 100))
|
||||
return msg + ", Total games: {0}".format(row[6])
|
||||
else:
|
||||
return "No stats for \u0002{0}\u0002 player games.".format(size)
|
||||
|
||||
def get_game_totals():
|
||||
def get_game_totals(gamemode):
|
||||
size_totals = []
|
||||
total = 0
|
||||
with conn:
|
||||
for size in range(MIN_PLAYERS, MAX_PLAYERS + 1):
|
||||
c.execute("SELECT size, totalgames FROM gamestats WHERE size=?", (size,))
|
||||
c.execute("SELECT size, totalgames FROM gamestats WHERE gamemode=? AND size=?", (gamemode, size))
|
||||
row = c.fetchone()
|
||||
if row:
|
||||
size_totals.append("\u0002{0}p\u0002: {1}".format(*row))
|
||||
total += row[1]
|
||||
|
||||
if len(size_totals) == 0:
|
||||
return "No games have been played."
|
||||
return "No games have been played in the {0} game mode.".format(gamemode)
|
||||
else:
|
||||
return "Total games ({0}) | {1}".format(total, ", ".join(size_totals))
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user