Browse Source

fixed some bugs and added game logging capabilities

master
jcao219 14 years ago
parent
commit
006754de51
  1. 6
      var.py
  2. 6
      wolfbot.py
  3. 135
      wolfgame.py

6
var.py

@ -10,6 +10,7 @@ DAY_TIME_LIMIT = 0
START_WITH_DAY = False START_WITH_DAY = False
KILL_IDLE_TIME = 300 KILL_IDLE_TIME = 300
WARN_IDLE_TIME = 180 WARN_IDLE_TIME = 180
LOG_FILENAME = "gamelog.txt"
# HIT MISS SUICIDE # HIT MISS SUICIDE
GUN_CHANCES = ( 5/7 , 1/7 , 1/7 ) GUN_CHANCES = ( 5/7 , 1/7 , 1/7 )
@ -41,7 +42,7 @@ AWAY = [] # cloaks of people who are away.
ROLE_INDICES = {0 : "seer", ROLE_INDICES = {0 : "seer",
1 : "wolf", 1 : "wolf",
2 : "cursed", 2 : "cursed villager",
3 : "village drunk", 3 : "village drunk",
4 : "harlot", 4 : "harlot",
5 : "traitor", 5 : "traitor",
@ -105,7 +106,7 @@ def game_mode(name):
CHANGEABLE_ROLES = { "seers" : INDEX_OF_ROLE["seer"], CHANGEABLE_ROLES = { "seers" : INDEX_OF_ROLE["seer"],
"wolves" : INDEX_OF_ROLE["wolf"], "wolves" : INDEX_OF_ROLE["wolf"],
"cursed" : INDEX_OF_ROLE["cursed"], "cursed villager" : INDEX_OF_ROLE["cursed villager"],
"drunks" : INDEX_OF_ROLE["village drunk"], "drunks" : INDEX_OF_ROLE["village drunk"],
"harlots" : INDEX_OF_ROLE["harlot"], "harlots" : INDEX_OF_ROLE["harlot"],
"traitors" : INDEX_OF_ROLE["traitor"], "traitors" : INDEX_OF_ROLE["traitor"],
@ -196,7 +197,6 @@ def add_away(clk):
def update_role_stats(clk, role, won, iwon): def update_role_stats(clk, role, won, iwon):
with conn: with conn:
wins, iwins, totalgames = 0, 0, 0 wins, iwins, totalgames = 0, 0, 0

6
wolfbot.py

@ -28,8 +28,12 @@ import traceback
def on_privmsg(cli, rawnick, chan, msg): def on_privmsg(cli, rawnick, chan, msg):
if chan != botconfig.NICK: #not a PM if chan != botconfig.NICK: #not a PM
if "" in wolfgame.COMMANDS.keys():
for fn in wolfgame.COMMANDS[""]:
fn(cli, rawnick, chan, msg)
# Now that is always called first.
for x in wolfgame.COMMANDS.keys(): for x in wolfgame.COMMANDS.keys():
if not x or msg.lower().startswith(botconfig.CMD_CHAR+x): if x and msg.lower().startswith(botconfig.CMD_CHAR+x):
h = msg[len(x)+1:] h = msg[len(x)+1:]
if not h or h[0] == " " or not x: if not h or h[0] == " " or not x:
for fn in wolfgame.COMMANDS[x]: for fn in wolfgame.COMMANDS[x]:

135
wolfgame.py

@ -10,6 +10,7 @@
from oyoyo.parse import parse_nick from oyoyo.parse import parse_nick
import var import var
import botconfig import botconfig
from wolfgamelogger import WolfgameLogger
import decorators import decorators
from datetime import datetime, timedelta from datetime import datetime, timedelta
import threading import threading
@ -91,6 +92,8 @@ def connect_callback(cli):
var.GRAVEYARD_LOCK = threading.RLock() var.GRAVEYARD_LOCK = threading.RLock()
var.GAME_ID = 0 var.GAME_ID = 0
var.LOGGER = WolfgameLogger(var.LOG_FILENAME)
if botconfig.DEBUG_MODE: if botconfig.DEBUG_MODE:
var.NIGHT_TIME_LIMIT = 0 # 90 var.NIGHT_TIME_LIMIT = 0 # 90
var.DAY_TIME_LIMIT = 0 var.DAY_TIME_LIMIT = 0
@ -154,8 +157,8 @@ def reset(cli):
dict.clear(var.DEAD_USERS) dict.clear(var.DEAD_USERS)
@pmcmd("fbye", "fdie", admin_only=True) @pmcmd("fdie", "fbye", admin_only=True)
@cmd("fbye", "fdie", admin_only=True) @cmd("fdie", "fbye", admin_only=True)
def forced_exit(cli, nick, *rest): # Admin Only def forced_exit(cli, nick, *rest): # Admin Only
"""Forces the bot to close""" """Forces the bot to close"""
@ -332,6 +335,8 @@ def fjoin(cli, nick, chan, rest):
@cmd("fleave","fquit","fdel", admin_only=True) @cmd("fleave","fquit","fdel", admin_only=True)
def fleave(cli, nick, chan, rest): def fleave(cli, nick, chan, rest):
if var.PHASE == "none":
cli.notice(nick, "No game is running.")
for a in re.split(" +",rest): for a in re.split(" +",rest):
a = a.strip() a = a.strip()
if not a: if not a:
@ -346,6 +351,9 @@ def fleave(cli, nick, chan, rest):
cli.msg(chan, ("\u0002{0}\u0002 is forcing"+ cli.msg(chan, ("\u0002{0}\u0002 is forcing"+
" \u0002{1}\u0002 to leave.").format(nick, a)) " \u0002{1}\u0002 to leave.").format(nick, a))
cli.msg(chan, "Appears (s)he was a \02{0}\02.".format(var.get_role(a))) cli.msg(chan, "Appears (s)he was a \02{0}\02.".format(var.get_role(a)))
if var.PHASE in ("day", "night"):
var.LOGGER.logMessage("{0} is forcing {1} to leave.".format(nick, a))
var.LOGGER.logMessage("Appears (s)he was a {0}.".format(var.get_role(a)))
del_player(cli, a) del_player(cli, a)
@ -405,10 +413,12 @@ def stats(cli, nick, chan, rest):
message.append("\u0002{0}\u0002 {1}".format(count if count else "\u0002no\u0002", var.plural(role))) message.append("\u0002{0}\u0002 {1}".format(count if count else "\u0002no\u0002", var.plural(role)))
else: else:
message.append("\u0002{0}\u0002 {1}".format(count, role)) message.append("\u0002{0}\u0002 {1}".format(count, role))
cli.msg(chan, "{0}: There {3} {1}, and {2}.".format(nick, stats_mssg = "{0}: There {3} {1}, and {2}.".format(nick,
", ".join(message[0:-1]), ", ".join(message[0:-1]),
message[-1], message[-1],
vb)) vb)
cli.msg(chan, stats_mssg)
var.LOGGER.logMessage(stats_mssg)
@ -434,11 +444,14 @@ def hurry_up(cli, gameid=0):
found_dup = True found_dup = True
if maxfound[0] > 0 and not found_dup: if maxfound[0] > 0 and not found_dup:
cli.msg(chan, "The sun sets.") cli.msg(chan, "The sun sets.")
var.LOGGER.logMessage("The sun sets.")
var.VOTES[maxfound[1]] = [None] * votesneeded var.VOTES[maxfound[1]] = [None] * votesneeded
chk_decision(cli) # Induce a lynch chk_decision(cli) # Induce a lynch
else: else:
cli.msg(chan, ("As the sun sets, the villagers agree to "+ cli.msg(chan, ("As the sun sets, the villagers agree to "+
"retire to their beds and wait for morning.")) "retire to their beds and wait for morning."))
var.LOGGER.logMessage(("As the sun sets, the villagers agree to "+
"retire to their beds and wait for morning."))
transition_night(cli) transition_night(cli)
@ -468,9 +481,9 @@ def chk_decision(cli):
votesneeded = avail // 2 + 1 votesneeded = avail // 2 + 1
for votee, voters in iter(var.VOTES.items()): for votee, voters in iter(var.VOTES.items()):
if len(voters) >= votesneeded: if len(voters) >= votesneeded:
cli.msg(botconfig.CHANNEL, lmsg = random.choice(var.LYNCH_MESSAGES).format(votee, var.get_role(votee))
random.choice(var.LYNCH_MESSAGES).format( cli.msg(botconfig.CHANNEL, lmsg)
votee, var.get_role(votee))) var.LOGGER.logMessage(lmsg.replace("\02", ""))
if del_player(cli, votee, True): if del_player(cli, votee, True):
transition_night(cli) transition_night(cli)
@ -532,11 +545,13 @@ def stop_game(cli, winner = ""):
nitemin, nitesec = var.NIGHT_TIMEDELTA.seconds // 60, var.NIGHT_TIMEDELTA.seconds % 60 nitemin, nitesec = var.NIGHT_TIMEDELTA.seconds // 60, var.NIGHT_TIMEDELTA.seconds % 60
total = var.DAY_TIMEDELTA + var.NIGHT_TIMEDELTA total = var.DAY_TIMEDELTA + var.NIGHT_TIMEDELTA
tmin, tsec = total.seconds // 60, total.seconds % 60 tmin, tsec = total.seconds // 60, total.seconds % 60
cli.msg(chan, ("Game lasted \u0002{0:0>2}:{1:0>2}\u0002. " + gameend_msg = ("Game lasted \u0002{0:0>2}:{1:0>2}\u0002. " +
"\u0002{2:0>2}:{3:0>2}\u0002 was day. " + "\u0002{2:0>2}:{3:0>2}\u0002 was day. " +
"\u0002{4:0>2}:{5:0>2}\u0002 was night. ").format(tmin, tsec, "\u0002{4:0>2}:{5:0>2}\u0002 was night. ").format(tmin, tsec,
daymin, daysec, daymin, daysec,
nitemin, nitesec)) nitemin, nitesec)
cli.msg(chan, gameend_msg)
var.LOGGER.logMessage(gameend_msg.replace("\02", "")+"\n")
roles_msg = [] roles_msg = []
@ -570,6 +585,7 @@ def stop_game(cli, winner = ""):
for x in ppl: for x in ppl:
plrl.append((x, role)) plrl.append((x, role))
var.LOGGER.saveToFile()
for plr, rol in plrl: for plr, rol in plrl:
if plr not in var.USERS: # he died TODO: when a player leaves, count the game as lost for him if plr not in var.USERS: # he died TODO: when a player leaves, count the game as lost for him
@ -624,24 +640,33 @@ def chk_win(cli):
len(var.ROLES["werecrow"])) == lpl / 2: len(var.ROLES["werecrow"])) == lpl / 2:
cli.msg(chan, ("Game over! There are the same number of wolves as "+ cli.msg(chan, ("Game over! There are the same number of wolves as "+
"villagers. The wolves eat everyone, and win.")) "villagers. The wolves eat everyone, and win."))
var.LOGGER.logMessage(("Game over! There are the same number of wolves as "+
"villagers. The wolves eat everyone, and win."))
village_win = False village_win = False
elif (len(var.ROLES["wolf"])+ elif (len(var.ROLES["wolf"])+
#len(var.ROLES["traitor"])+ #len(var.ROLES["traitor"])+
len(var.ROLES["werecrow"])) > lpl / 2: len(var.ROLES["werecrow"])) > lpl / 2:
cli.msg(chan, ("Game over! There are more wolves than "+ cli.msg(chan, ("Game over! There are more wolves than "+
"villagers. The wolves eat everyone, and win.")) "villagers. The wolves eat everyone, and win."))
var.LOGGER.logMessage(("Game over! There are more wolves than "+
"villagers. The wolves eat everyone, and win."))
village_win = False village_win = False
elif (not var.ROLES["wolf"] and elif (not var.ROLES["wolf"] and
not var.ROLES["traitor"] and not var.ROLES["traitor"] and
not var.ROLES["werecrow"]): not var.ROLES["werecrow"]):
cli.msg(chan, ("Game over! All the wolves are dead! The villagers "+ cli.msg(chan, ("Game over! All the wolves are dead! The villagers "+
"chop them up, BBQ them, and have a hearty meal.")) "chop them up, BBQ them, and have a hearty meal."))
var.LOGGER.logMessage(("Game over! All the wolves are dead! The villagers "+
"chop them up, BBQ them, and have a hearty meal."))
village_win = True village_win = True
elif not len(var.ROLES["wolf"]) and var.ROLES["traitor"]: elif not len(var.ROLES["wolf"]) and var.ROLES["traitor"]:
chk_traitor(cli) chk_traitor(cli)
cli.msg(chan, ('\u0002The villagers, during their celebrations, are '+ cli.msg(chan, ('\u0002The villagers, during their celebrations, are '+
'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'))
var.LOGGER.logMessage(('\u0002The villagers, during their celebrations, are '+
'frightened as they hear a loud howl. The wolves are '+
'not gone!\u0002'))
return False return False
else: else:
return False return False
@ -760,10 +785,13 @@ def reaper(cli, gameid):
@cmd("") # update last said @cmd("") # update last said
def update_last_said(cli, nick, *rest): def update_last_said(cli, nick, chan, rest):
if var.PHASE not in ("join", "none"): if var.PHASE not in ("join", "none"):
var.LAST_SAID_TIME[nick] = datetime.now() var.LAST_SAID_TIME[nick] = datetime.now()
if var.PHASE not in ("none", "join"):
var.LOGGER.log("<{0}> {1}".format(nick, rest))
@hook("join") @hook("join")
@ -794,6 +822,7 @@ def goat(cli, nick, chan, rest):
cli.msg(chan, ("\u0002{0}\u0002's goat walks by "+ cli.msg(chan, ("\u0002{0}\u0002's goat walks by "+
"and kicks \u0002{1}\u0002.").format(nick, "and kicks \u0002{1}\u0002.").format(nick,
rest.strip())) rest.strip()))
var.LOGGER.logMessage("{0}'s goat walks by and kicks {1}.".format(nick, rest.strip()))
var.GOATED = True var.GOATED = True
@ -899,9 +928,10 @@ def leave(cli, what, nick, why=""):
"Appears (s)he was a \u0002{1}\u0002.") "Appears (s)he was a \u0002{1}\u0002.")
msg = msg.format(nick, var.get_role(nick)) msg = msg.format(nick, var.get_role(nick))
cli.msg(botconfig.CHANNEL, msg) cli.msg(botconfig.CHANNEL, msg)
var.LOGGER.logMessage(msg.replace("\02", ""))
del_player(cli, nick) del_player(cli, nick)
_ = cmd("quit", "leave")(lambda cli, nick, *rest: leave(cli, botconfig.CMD_CHAR+"quit", nick)) _ = cmd("quit", "leave")(lambda cli, nick, chan, rest: leave(cli, botconfig.CMD_CHAR+"quit", nick, ""))
_.__doc__ = "Quits the game" _.__doc__ = "Quits the game"
#Functions decorated with hook do not parse the nick by default #Functions decorated with hook do not parse the nick by default
hook("part")(lambda cli, nick, *rest: leave(cli, "part", parse_nick(nick)[0])) hook("part")(lambda cli, nick, *rest: leave(cli, "part", parse_nick(nick)[0]))
@ -923,9 +953,11 @@ def begin_day(cli):
var.HVISITED = {} var.HVISITED = {}
var.GUARDED = {} var.GUARDED = {}
cli.msg(chan, ("The villagers must now vote for whom to lynch. "+ msg = ("The villagers must now vote for whom to lynch. "+
'Use "{0}lynch <nick>" to cast your vote. {1} votes '+ 'Use "{0}lynch <nick>" to cast your vote. {1} votes '+
'are required to lynch.').format(botconfig.CMD_CHAR, len(var.list_players()) // 2 + 1)) 'are required to lynch.').format(botconfig.CMD_CHAR, len(var.list_players()) // 2 + 1)
cli.msg(chan, msg)
var.LOGGER.logMessage(msg)
if var.DAY_TIME_LIMIT > 0: # Time limit enabled if var.DAY_TIME_LIMIT > 0: # Time limit enabled
var.DAY_ID = timetime() var.DAY_ID = timetime()
@ -1046,6 +1078,8 @@ def transition_day(cli, gameid=0):
dead.append(harlot) dead.append(harlot)
for gangel in var.ROLES["guardian angel"]: for gangel in var.ROLES["guardian angel"]:
if var.GUARDED.get(gangel) in var.ROLES["wolf"]+var.ROLES["werecrow"]: if var.GUARDED.get(gangel) in var.ROLES["wolf"]+var.ROLES["werecrow"]:
if victim == gangel:
continue # already dead.
r = random.random() r = random.random()
if r < var.GUARDIAN_ANGEL_DIES_CHANCE: if r < var.GUARDIAN_ANGEL_DIES_CHANCE:
message.append(("\u0002{0}\u0002, a guardian angel, "+ message.append(("\u0002{0}\u0002, a guardian angel, "+
@ -1067,6 +1101,8 @@ def transition_day(cli, gameid=0):
# "The drunk's pet tiger probably ate him.").format(crow)) # "The drunk's pet tiger probably ate him.").format(crow))
# dead.append(crow) # dead.append(crow)
cli.msg(chan, "\n".join(message)) cli.msg(chan, "\n".join(message))
for msg in message:
var.LOGGER.logMessage(msg.replace("\02", ""))
for deadperson in dead: for deadperson in dead:
if not del_player(cli, deadperson): if not del_player(cli, deadperson):
return return
@ -1121,6 +1157,7 @@ def vote(cli, nick, chan, rest):
var.VOTES[voted].append(nick) var.VOTES[voted].append(nick)
cli.msg(chan, ("\u0002{0}\u0002 votes for "+ cli.msg(chan, ("\u0002{0}\u0002 votes for "+
"\u0002{1}\u0002.").format(nick, voted)) "\u0002{1}\u0002.").format(nick, voted))
var.LOGGER.logMessage("{0} votes for {1}.".format(nick, voted))
chk_decision(cli) chk_decision(cli)
elif not rest: elif not rest:
cli.notice(nick, "Not enough parameters.") cli.notice(nick, "Not enough parameters.")
@ -1138,6 +1175,7 @@ def retract(cli, nick, chan, rest):
elif nick not in var.list_players(): elif nick not in var.list_players():
cli.notice(nick, "You're not currently playing.") cli.notice(nick, "You're not currently playing.")
return return
if var.PHASE != "day": if var.PHASE != "day":
cli.notice(nick, ("Lynching is only allowed during the day. "+ cli.notice(nick, ("Lynching is only allowed during the day. "+
"Please wait patiently for morning.")) "Please wait patiently for morning."))
@ -1150,6 +1188,7 @@ def retract(cli, nick, chan, rest):
if not var.VOTES[voter]: if not var.VOTES[voter]:
del var.VOTES[voter] del var.VOTES[voter]
cli.msg(chan, "\u0002{0}\u0002 retracted his/her vote.".format(nick)) cli.msg(chan, "\u0002{0}\u0002 retracted his/her vote.".format(nick))
var.LOGGER.logMessage("{0} retracted his/her vote.".format(nick))
break break
else: else:
cli.notice(nick, "You haven't voted yet.") cli.notice(nick, "You haven't voted yet.")
@ -1165,6 +1204,7 @@ def shoot(cli, nick, chan, rest):
elif nick not in var.list_players(): elif nick not in var.list_players():
cli.notice(nick, "You're not currently playing.") cli.notice(nick, "You're not currently playing.")
return return
if var.PHASE != "day": if var.PHASE != "day":
cli.notice(nick, ("Shooting is only allowed during the day. "+ cli.notice(nick, ("Shooting is only allowed during the day. "+
"Please wait patiently for morning.")) "Please wait patiently for morning."))
@ -1196,32 +1236,44 @@ def shoot(cli, nick, chan, rest):
if rand <= chances[0]: if rand <= chances[0]:
cli.msg(chan, ("\u0002{0}\u0002 shoots \u0002{1}\u0002 with "+ cli.msg(chan, ("\u0002{0}\u0002 shoots \u0002{1}\u0002 with "+
"a silver bullet!").format(nick, victim)) "a silver bullet!").format(nick, victim))
var.LOGGER.logMessage("{0} shoots {1} with a silver bullet!".format(nick, victim))
victimrole = var.get_role(victim) victimrole = var.get_role(victim)
if victimrole in ("wolf", "werecrow"): if victimrole in ("wolf", "werecrow"):
cli.msg(chan, ("\u0002{0}\u0002 is a wolf, and is dying from "+ cli.msg(chan, ("\u0002{0}\u0002 is a wolf, and is dying from "+
"the silver bullet.").format(victim)) "the silver bullet.").format(victim))
var.LOGGER.logMessage(("{0} is a wolf, and is dying from the "+
"silver bullet.").format(victim))
if not del_player(cli, victim): if not del_player(cli, victim):
return return
elif random.random() <= var.MANSLAUGHTER_CHANCE: elif random.random() <= var.MANSLAUGHTER_CHANCE:
cli.msg(chan, ("\u0002{0}\u0002 is a not a wolf "+ cli.msg(chan, ("\u0002{0}\u0002 is a not a wolf "+
"but was accidentally fatally injured.").format(victim)) "but was accidentally fatally injured.").format(victim))
cli.msg(chan, "Appears (s)he was a \u0002{0}\u0002.".format(victimrole)) cli.msg(chan, "Appears (s)he was a \u0002{0}\u0002.".format(victimrole))
var.LOGGER.logMessage("{0} is not a wolf but was accidentally fatally injured.".format(victim))
var.LOGGER.logMessage("Appears (s)he was a {0}.".format(victimrole))
if not del_player(cli, victim): if not del_player(cli, victim):
return return
else: else:
cli.msg(chan, ("\u0002{0}\u0002 is a villager and is injured but "+ cli.msg(chan, ("\u0002{0}\u0002 is a villager and is injured but "+
"will have a full recovery. S/He will be resting "+ "will have a full recovery. S/He will be resting "+
"for the day.").format(victim)) "for the day.").format(victim))
var.LOGGER.logMessage(("{0} is a villager and is injured but "+
"will have a full recovery. S/He will be resting "+
"for the day").format(victim))
if victim not in var.WOUNDED: if victim not in var.WOUNDED:
var.WOUNDED.append(victim) var.WOUNDED.append(victim)
chk_decision(cli) chk_decision(cli)
chk_win(cli) chk_win(cli)
elif rand <= chances[0] + chances[1]: elif rand <= chances[0] + chances[1]:
cli.msg(chan, "\u0002{0}\u0002 is a lousy shooter. S/He missed!".format(nick)) cli.msg(chan, "\u0002{0}\u0002 is a lousy shooter. S/He missed!".format(nick))
var.LOGGER.logMessage("{0} is a lousy shooter. S/He missed!".format(nick))
else: else:
cli.msg(chan, ("\u0002{0}\u0002 should clean his/her weapons more often. "+ cli.msg(chan, ("\u0002{0}\u0002 should clean his/her weapons more often. "+
"The gun exploded and killed him/her!").format(nick)) "The gun exploded and killed him/her!").format(nick))
cli.msg(chan, "Appears that (s)he was a \u0002{0}\u0002.".format(var.get_role(nick))) cli.msg(chan, "Appears that (s)he was a \u0002{0}\u0002.".format(var.get_role(nick)))
var.LOGGER.logMessage(("{0} should clean his/her weapers more often. "+
"The gun exploded and killed him/her!").format(nick))
var.LOGGER.logMessage("Appears that (s)he was a {0}.".format(var.get_role(nick)))
if not del_player(cli, nick): if not del_player(cli, nick):
return # Someone won. return # Someone won.
@ -1629,10 +1681,12 @@ def transition_night(cli):
continue continue
cli.msg(g, gun_msg) cli.msg(g, gun_msg)
cli.msg(chan, (daydur_msg + "It is now nighttime. All players "+ dmsg = (daydur_msg + "It is now nighttime. All players "+
"check for PMs from me for instructions. "+ "check for PMs from me for instructions. "+
"If you did not receive one, simply sit back, "+ "If you did not receive one, simply sit back, "+
"relax, and wait patiently for morning.")) "relax, and wait patiently for morning.").replace("\02", "")
cli.msg(chan, dmsg)
var.LOGGER.logMessage(dmsg)
# cli.msg(chan, "DEBUG: "+str(var.ROLES)) # cli.msg(chan, "DEBUG: "+str(var.ROLES))
if not var.ROLES["wolf"]: # Probably something interesting going on. if not var.ROLES["wolf"]: # Probably something interesting going on.
@ -1706,7 +1760,7 @@ def start(cli, nick, chan, rest):
wvs = (addroles[var.INDEX_OF_ROLE["wolf"]] + wvs = (addroles[var.INDEX_OF_ROLE["wolf"]] +
addroles[var.INDEX_OF_ROLE["traitor"]]) addroles[var.INDEX_OF_ROLE["traitor"]])
if len(villagers) < (sum(addroles) - addroles[var.INDEX_OF_ROLE["gunner"]] - if len(villagers) < (sum(addroles) - addroles[var.INDEX_OF_ROLE["gunner"]] -
addroles[var.INDEX_OF_ROLE["cursed"]]): addroles[var.INDEX_OF_ROLE["cursed villager"]]):
cli.msg(chan, "There are too few players in the "+ cli.msg(chan, "There are too few players in the "+
"game to use the custom roles.") "game to use the custom roles.")
elif not wvs: elif not wvs:
@ -1725,7 +1779,7 @@ def start(cli, nick, chan, rest):
var.CURSED = [] var.CURSED = []
var.GUNNERS = {} var.GUNNERS = {}
villager_roles = ("gunner", "cursed") villager_roles = ("gunner", "cursed villager")
for i, count in enumerate(addroles): for i, count in enumerate(addroles):
role = var.ROLE_INDICES[i] role = var.ROLE_INDICES[i]
if role in villager_roles: if role in villager_roles:
@ -1738,15 +1792,15 @@ def start(cli, nick, chan, rest):
# Now for the villager roles # Now for the villager roles
# Select cursed (just a villager) # Select cursed (just a villager)
if var.ROLES["cursed"]: if var.ROLES["cursed villager"]:
possiblecursed = pl[:] possiblecursed = pl[:]
for cannotbe in (var.ROLES["wolf"] + var.ROLES["werecrow"] + for cannotbe in (var.ROLES["wolf"] + var.ROLES["werecrow"] +
var.ROLES["seer"]): # confusing (Traitor can be cursed apparently) var.ROLES["seer"]): # confusing (Traitor can be cursed apparently)
# but not in the Perl howlbot code # but not in the Perl howlbot code
possiblecursed.remove(cannotbe) possiblecursed.remove(cannotbe)
var.CURSED = random.sample(possiblecursed, len(var.ROLES["cursed"])) var.CURSED = random.sample(possiblecursed, len(var.ROLES["cursed villager"]))
del var.ROLES["cursed"] del var.ROLES["cursed villager"]
# Select gunner (also a villager) # Select gunner (also a villager)
if var.ROLES["gunner"]: if var.ROLES["gunner"]:
@ -1781,6 +1835,25 @@ def start(cli, nick, chan, rest):
var.DAY_START_TIME = None var.DAY_START_TIME = None
var.NIGHT_START_TIME = None var.NIGHT_START_TIME = None
var.LOGGER.log("Game Start")
var.LOGGER.log("***")
var.LOGGER.log("ROLES: ")
for rol in var.ROLES:
r = []
for rw in var.plural(rol).split(" "):
rwu = rw[0].upper()
if len(rw) > 1:
rwu += rw[1:]
r.append(rwu)
r = " ".join(r)
var.LOGGER.log("{0}: {1}".format(r, ", ".join(var.ROLES[rol])))
if var.CURSED:
var.LOGGER.log("Cursed Villagers: "+", ".join(var.CURSED))
if var.GUNNERS:
var.LOGGER.log("Villagers With Bullets: "+", ".join([x+"("+str(y)+")" for x,y in var.GUNNERS.items()]))
var.LOGGER.log("***")
if not var.START_WITH_DAY: if not var.START_WITH_DAY:
transition_night(cli) transition_night(cli)
@ -1794,6 +1867,13 @@ def start(cli, nick, chan, rest):
@hook("error")
def on_error(cli, pfx, msg):
if msg.endswith("(Excess Flood)"):
restart_program(cli, "excess flood")
@cmd("wait") @cmd("wait")
def wait(cli, nick, chan, rest): def wait(cli, nick, chan, rest):
"""Increase the wait time (before !start can be used)""" """Increase the wait time (before !start can be used)"""
@ -1858,6 +1938,7 @@ def reset_game(cli, nick, chan, rest):
cli.notice(nick, "No game is currently running.") cli.notice(nick, "No game is currently running.")
return return
cli.msg(chan, "\u0002{0}\u0002 has forced the game to stop.".format(nick)) cli.msg(chan, "\u0002{0}\u0002 has forced the game to stop.".format(nick))
var.LOGGER.logMessage("{0} has forced the game to stop.".format(nick))
if var.PHASE != "join": if var.PHASE != "join":
stop_game(cli) stop_game(cli)
else: else:
@ -1872,6 +1953,7 @@ def pm_rules(cli, nick, rest):
def show_rules(cli, nick, chan, rest): def show_rules(cli, nick, chan, rest):
"""Displays the rules""" """Displays the rules"""
cli.msg(chan, var.RULES) cli.msg(chan, var.RULES)
var.LOGGER.logMessage(var.RULES)
@pmcmd("help", raw_nick = True) @pmcmd("help", raw_nick = True)
@ -1888,6 +1970,8 @@ def get_help(cli, rnick, rest):
found = True found = True
for fn in c[cname]: for fn in c[cname]:
if fn.__doc__: if fn.__doc__:
if nick == botconfig.CHANNEL:
var.LOGGER.logMessage(botconfig.CMD_CHAR+cname+": "+fn.__doc__)
cli.msg(nick, botconfig.CMD_CHAR+cname+": "+fn.__doc__) cli.msg(nick, botconfig.CMD_CHAR+cname+": "+fn.__doc__)
return return
else: else:
@ -1960,7 +2044,10 @@ def show_admins(cli, nick, chan, rest):
def coin(cli, nick, chan, rest): def coin(cli, nick, chan, rest):
"""It's a bad idea to base any decisions on this command.""" """It's a bad idea to base any decisions on this command."""
cli.msg(chan, "\2{0}\2 tosses a coin into the air...".format(nick)) cli.msg(chan, "\2{0}\2 tosses a coin into the air...".format(nick))
cli.msg(chan, "The coin lands on \2{0}\2.".format("heads" if random.random() < 0.5 else "tails")) var.LOGGER.logMessage("{0} tosses a coin into the air...".format(nick))
cmsg = "The coin lands on \2{0}\2.".format("heads" if random.random() < 0.5 else "tails")
cli.msg(chan, cmsg)
var.LOGGER.logMessage(cmsg)
@cmd("flastgame", admin_only=True) @cmd("flastgame", admin_only=True)
@ -2087,7 +2174,7 @@ if botconfig.DEBUG_MODE:
cli.msg(chan, "The syntax is incorrect.") cli.msg(chan, "The syntax is incorrect.")
return return
who = rst.pop(0).strip().lower() who = rst.pop(0).strip().lower()
who.replace("_", " ") who = who.replace("_", " ")
if (who not in var.ROLES or not var.ROLES[who]) and (who != "gunner" if (who not in var.ROLES or not var.ROLES[who]) and (who != "gunner"
or var.PHASE in ("none", "join")): or var.PHASE in ("none", "join")):
@ -2150,7 +2237,7 @@ if botconfig.DEBUG_MODE:
var.GUNNERS[who] = math.ceil(var.SHOTS_MULTIPLIER * len(pl)) var.GUNNERS[who] = math.ceil(var.SHOTS_MULTIPLIER * len(pl))
if who not in pl: if who not in pl:
var.ROLES["villager"].append(who) var.ROLES["villager"].append(who)
elif rol == "cursed": elif rol == "cursed villager":
var.CURSED.append(who) var.CURSED.append(who)
if who not in pl: if who not in pl:
var.ROLES["villager"].append(who) var.ROLES["villager"].append(who)

Loading…
Cancel
Save