Move a lot of duplicated logic into helper functions so that it is easy
to ensure that wolfchat restrictions are being consistently applied.
check_exchange still needs to be modified but everything else should be
ok.
- Correctly logic out bite interacting with harlot, immunized, and lycan:
- A harlot that isn't home does not get bit and refunds the bite unless
they visit a wolfteam member or visit the unprotected wolves' victim
(in either of those cases, they get bit instead of dying)
- A lycan or someone with a lycanthropy totem that gets bitten
immediately turns to wolf and refunds the bite. The regular wolf kill
still happens too, so this is essentially a freebie for alpha wolf.
- An immunized target dies per normal, but the death from the bite does
not stack with the death from a normal wolf kill for the purposes of
protection (meaning a single protection will guard against both).
- Fix nightdone check so that night doesn't end prematurely if alpha
would be eligible to bite but has already done so previously in the
game.
- Always apply host-based allows/denies even in var.ACCOUNTS_ONLY is set
- Fix display of mixed-mode allows/denies for a particular user
- Make -acc and -host switches operate more intelligently on both the
bare command as well as when given an argument
I cannot reproduce the bug locally, but this will force the socket to
close if it didn't for whatever reason, which is what seems like could
have caused the issue.
Didn't remove players from var.DISCONNECTED, leading to idling out every 10 seconds and getting lots of stasis while still being in the game
Didn't actually check whether the player was in channel or not
- Make bite able to end night
- Bite was always working even if the target was immunized
- Ensure protection applies when killing a target that was
immunized-but-bitten
- var.SHAMANS now properly stores who is actually receiving totem, as it
should. It now holds a tuple so it can still track the original target
for purposes of letting shaman know if target changed.
- properly reset all totem vars before handing them out so totems don't
last for multiple days.
- luck/misdirection now applies before exchange totem is checked, making
it consistent with every other role ever.
completely untested, but should be fine :)
A game mode is considered "hidden" if it doesn't have a `ROLE_GUIDE`
attribute. The `default` game mode was modified to have those
attributes, and is not hidden.
This change negatively impacts balance, assassin should in general never
be applied to any role the other team is required to kill in order to
win. Alpha wolf is the exception here, not the rule, since there is
counterplay involved with alpha biting GA (GA is likely immunized, can
guard self, game might end before turning, etc.) that simply does not
exist in other instances.
This reverts commit 3eb437fad6.
Not just from getting bitten by alpha wolf, but also from turning from
amnesiac, and also if in the default role rotation (this one currently
doesn't affect any game modes, but in the future it might).
This allows for things like making ADMINS/OWNERS take a full hostmask,
or fallowing/fdenying a full hostmask with wildcards. It also allows for
a distinction between two people that share a hostmask but have a
different ident.
stasis now checks all matching stasis and returns the highest amount
fallow/fdeny have two new options -acc and -host to explicitly specify
what type the argument is
-cmds in fallow/fdeny show commands from all matching masks, to bring it
in line with how actual allow/deny parsing works, before it would only
show the first match
All exceptions, if not caught, are unconditionally sent to `sys.stderr`.
We only need to use our own custom class with some modifications and we
can intercept all errors, even those in threads (which #151 was about).
The only real downside from this practice is that `cli` is not
accessible to us when the errors happen, so I used a hack to set it on
an instance variable. If anyone can find a better solution, please step
forward. For the time being, this will have to do.
If for some obscure reason this class breaks, `sys.__stderr__` holds the
original `sys.stderr`
This allows people to swap out an existing player from the game, and
join instead. Useful if, say, your home connection dropped, but your ZNC
is still online and you want to keep playing through your phone for
example. The player swapping and the one being swapped must be
identified to the same account for this to work. After the command has
been used, an implicit !myrole is performed, informing the player of
their role and templates. The on_nick handler has been decoupled into
two functions, where most of the logic is now in rename_player (which
swap uses).
Known issues: Hard drive space is left untouched.
Now `!roles` while in a game will have the same effect as `!roles n`
where n is the number of players that joined. Also got rid of string
concatenation.
Now restricted to adding/removing 900 seconds (15 minutes). There are no
valid reasons I can think of or that were given in -dev that would
require more time than this. 15 minutes is still likely too much and
from previous experience such long forced waits generally trigger a mass
exodus of players who would rather play a game than doing absolutely
nothing.
Alpha now can choose to either bite or kill, but not both. If other
wolves are alive, they can still kill as normal allowing both to happen
that night. Additional interactions were added to deal with visiting
harlots and to not accidentally kill bodyguards/GAs in the event that
they are bitten and would die from wolves (if
BODYGUARD/GUARDIAN_ANGEL_DIES_AT_NIGHT_CHANCE is set).
Things to consider for the future but didn't have time to do yet:
- Should we play a message in channel if alpha wolf successfully bites
someone at night?
- Avoid killing a bodyguard/GA if Fallen Angel is in play and said
bodyguard/GA was bitten that night.
- Should wolves avoid automatically killing people bitten on previous
nights (e.g. a bitten harlot wouldn't get nommed visiting wolves or
victims, bitten bodyguards/GAs wouldn't die from fallen angel, etc.)?
This way it's immediately obvious if it was a legit command or not. The
result of werecrow's observation is not announced, because it's possible
for the crow to be killed at night and this would take away that
strategy. For sorcerer, it does not even bother announcing the fact that
they observed, since they can tell the result immediately if they are
alive, so the message is pretty much redundant.
Also, minor fixes:
* Log kill by angry wolves properly, instead of the non-obvious hack
that @Vgr255 used.
* Add missing quotes in angry wolves wolfchat message.
Right now the only thing that still tracks accounts if DISABLE_ACCOUNTS
is True is stats stuff (in sqlite), as I'm unsure of how we want to
handle that for when accounts aren't enabled; likely track by nick but
unsure on that right now.
This further implements issue #112 but doesn't fix it entirely yet.
Decoupled ROLE_REVEAL from impacting !stats, added new STATS_TYPE.
ROLE_REVEAL is now a string:
- on = roles revealed on death
- off = roles not revealed on death
- team = user's team revealed on death but not their role
STATS_TYPE is also a string:
- default = stats are calculated as if a villager or nonplayer was
manually tracking who was what; this leads to !stats not revealing
any information that is not publicly known
- accurate = what it used to be with a couple modifications; all roles
are shown (VG and time lord are no longer lumped with villager),
alpha wolf and lycans turning are hidden, nothing else is hidden
(so you can see what amnesiac turned into or when clone turns)
- team = only shows number of people on each team, calculated the same
way as accurate
- disabled = stats are disabled, doing !stats only serves as a mass-ping
of alive players
Removed random_reveal/random_noreveal hack
- !fgame random=role reveal:on|off does the same thing as the hack used
to do.
Allow all game modes to take arguments (aka the blah in roles=blah).
- Allowed arguments are "role reveal" (on/off/team), "stats type"
(default/accurate/team/disabled), and "abstain"
(enabled/restricted/disabled).
- roles obviously still allows for taking individual roles as arguments
as well as specifying a default role, however this functionality is
not available for any other gamemode.
- if any custom options are set as a result of this or changing them in
game mode constructors, players will be informed of which options are
in play.
Performing !frole will force STATS_TYPE from default to accurate, this
is done because the default logic is based not on what roles are
currently in existence, but rather what roles the game was started with
and what transformations could have applied to them. !frole throws a
complete monkey wrench in that to the point where it is impossible to
nicely recover.
Clone and Traitor are now unconditionally blacklisted for amnesiac, as
the additional logic to support them in default !stats is incredibly
complex and as such was not done for this PR.
Matchmaker is conditionally blacklisted for amnesiac if amnesiacs turn
after the first night. It is an allowed choice (unless it appears on the
config blacklist) if amnesiacs turn night 1.
Turncoats initially start off village-aligned, but can change which team
they're on by using the !side command. Turncoats cannot change sides two
nights in a row, and can use !pass if they don't wish to change sides on
any given night.
Seers and detectives see turncoats as turncoats, augurs see them as
having a grey aura. I was initially toying with det and augur seeing
them as their currently-chosen side and for mystics of the opposite team
to detect them, but since they can flip-flop an unlimited number of
times a night that info would be useless at best and misleading at
worst.
These commands are completely useless, they just confuse people. I just
had someone ask me whether it would bring them back to the game, with
their role and everything. If an op wants to talk in the middle of the
game, there are other ways to do that. This isn't even being used
anymore.
Roles are revealed upon death, but not shown in !stats.
This will be used for the random game mode with a 50% chance.
The variant used is displayed when the game is started, and
admins can force a specific variant with !fgame.
Also, ignore conceal_roles in !stats, because partial role reveal
handles that now.
!fsend is a very dangerous command if abused (up there with exec), and
should be properly admin-only instead of allowed to be given out to
non-admins. Unlike fsay/fact, there is no easy way to restrict fsend
when a non-admin uses it.
_collections is the C implementation (and where defaultdict lies), and
is as such already loaded when the interpreter is launched. collections
imports a bunch of other useless stuff we're not interested in.
- You can now use "-cmds" to group by command rather than user. This is
useful to, say, check who is allowed to use !revealroles.
- The output is now sorted alphabetically, which should make visual
navigation much easier.
- The command character is no longer prefixed to the commands, as I feel
like it's just a waste of space.
- Long messages are now broken properly, using var.break_long_message().
After a discussion in ##werewolf-dev, we've decided that if a majority
of the players wants a game mode, there's no reason not to allow it.
If a game mode is broken, it can be commented out in the code.
This commit adds 3 new roles and changes the semantics of
kills/protections to work more like the impatience and pacifism totems.
- Add mystic and wolf mystic roles which can divine the number of
players still alive on the opposing team each night. These roles are
meant for games where role reveal is off as !stats gives the same info
otherwise.
- Add fallen angel which is a corrupted version of the guardian angel,
created when a guardian angel is bitten by alpha wolf. This role is
incredibly potent as they bypass all forms of protection on their
target. GAs corrupted this way also automatically gain the assassin
template.
- Protections/kills now stack and cancel each other out. As such, 2
kills but only 1 protection will result in the kill still happening.
- Fix help text for active alpha wolf to show the reworked bite command.
- If alpha bites someone who is going to die via other means that night,
refund the bite.
- If the bite was unsuccessful due to whatever reason and was refunded,
give a different message to alpha wolf to let them know that.
- Make adding more wolf roles in the future easier to do by replacing
some hardcoded lists with var.WOLF_ROLES.
- Piper can now only win during daytime (this includes transition_day as
well as chk_decision)
- There is now at most 1 piper in charming regardless of player count,
more than 1 is simply overpowered and impossible to balance
- Replaced all \XX, \XXX and \xXX syntax by \uXXXX syntax
- Replaced all single-quotes messages by double-quotes ones where it
makes sense
- Replace all {} in string literals by {0} syntax (explicit over
implicit)
- Use x.startswith(("a", "e", "i", "o", "u")) instead of x[0] in ("a",
"e", "i", "o", "u")
- Remove list comprehensions where a simple generator would work
(reduces memory consumption where we can)