Skip to content
This repository has been archived by the owner on Oct 29, 2022. It is now read-only.

Implemented some Sects & Violets roles and the fgame command #1

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
2d86388
Minor edits
Picowchew Jan 2, 2021
21e0b3c
Removed repeated lines
Picowchew Jan 2, 2021
8514f0a
Added n1_addendum for Slayer and prefix to the character text
Picowchew Jan 2, 2021
ecd5f25
Removed ‘2’, since this seems to be for pointer_player instead of dur…
Picowchew Jan 2, 2021
20d4b74
Updated the game_packs variable
Picowchew Jan 2, 2021
a24518d
Removed hyphens, which would alter the logs (and other bot text), but…
Picowchew Jan 2, 2021
6ab58d8
Edits for the implementation of the fgame command
Picowchew Jan 2, 2021
e862554
Edits due to changes in GameChooser.py
Picowchew Jan 2, 2021
617b6fe
Edits due to changes in GameChooser.py and removed a repeated line
Picowchew Jan 2, 2021
8d17b49
Edits due to changes in GameChooser.py and removed an extra check
Picowchew Jan 2, 2021
66c806a
Edits for the implementation of Sects & Violets and the fgame command
Picowchew Jan 2, 2021
22133b9
Implemented the fgame command
Picowchew Jan 2, 2021
5c79b60
Added Sects & Violets tokens
Picowchew Jan 2, 2021
6f33c56
Added cropped Sects & Violets tokens
Picowchew Jan 2, 2021
395bae3
Added images for Sects & Violets
Picowchew Jan 2, 2021
9ceff22
Added emoji for Sects & Violets
Picowchew Jan 2, 2021
3c362ec
Added ampersand for Sects & Violets
Picowchew Jan 2, 2021
002af83
Added alias for Sects & Violets
Picowchew Jan 2, 2021
43a0536
Edits for the implementation of Sects & Violets and Bad Moon Rising
Picowchew Jan 2, 2021
36f341e
Edits for the implementation of Sects & Violets and updated the game_…
Picowchew Jan 2, 2021
d283f66
Edits for the implementation of Sects & Violets and added ‘#’ to the …
Picowchew Jan 2, 2021
ad12c03
Edits for the implementation of Sects & Violets and changed arbitrary…
Picowchew Jan 2, 2021
3a16abc
Edits for the implementation of Sects & Violets
Picowchew Jan 2, 2021
c3fe1e9
Implemented some Sects & Violets abilities
Picowchew Jan 2, 2021
a7d5d8d
Implemented some Sects & Violets roles
Picowchew Jan 2, 2021
cfe0674
Added self._brief_string and self._action to all of the Sects & Viole…
Picowchew Jan 5, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added bot_assets/plain_emojis/custom_skull.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
74 changes: 48 additions & 26 deletions botc/BOTCUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
MAX_MESSAGE_LEN = Config["misc"]["MAX_MESSAGE_LEN"]
MAX_MESSAGE_LEN = int(MAX_MESSAGE_LEN)

with open('botc/game_text.json') as json_file:
with open('botc/game_text.json') as json_file:
documentation = json.load(json_file)
x_emoji = documentation["cmd_warnings"]["x_emoji"]
player_not_found = documentation["cmd_warnings"]["player_not_found"]
Expand All @@ -22,6 +22,7 @@
requires_one_target_str = documentation["cmd_warnings"]["requires_one_target_str"]
requires_two_targets_str = documentation["cmd_warnings"]["requires_two_targets_str"]
requires_different_targets_str = documentation["cmd_warnings"]["requires_different_targets_str"]
requires_more_than_three_alive_players_str = documentation["cmd_warnings"]["requires_more_than_three_alive_players_str"]
changes_not_allowed = documentation["cmd_warnings"]["changes_not_allowed"]
unique_ability_used = documentation["cmd_warnings"]["unique_ability_used"]
not_under_status = documentation["cmd_warnings"]["not_under_status"]
Expand All @@ -37,13 +38,13 @@ class Targets(list):
def __init__(self, target_list):
self.target_list = target_list
self.target_nb = len(self.target_list)

def __len__(self):
return len(self.target_list)

def __iter__(self):
yield from self.target_list

def __getitem__(self, index):
return list.__getitem__(self.target_list, index)

Expand Down Expand Up @@ -81,7 +82,7 @@ def get_players_from_role_name(character_name_enum):
if player.role.ego_self.name == character_name_enum.value:
ret.append(player)
return ret

@staticmethod
def get_all_minions():
"""Return the list of players that are minions, using true_self"""
Expand Down Expand Up @@ -112,7 +113,7 @@ def get_random_player_excluding(player):
def get_role_list(edition, category):
"""Get the entire list of an edition and a category"""
return [role_class() for role_class in edition.__subclasses__() if issubclass(role_class, category)]

@staticmethod
def get_player_from_id(userid):
"""Find a player object from a user ID"""
Expand All @@ -122,11 +123,11 @@ def get_player_from_id(userid):
for player in game.sitting_order:
if player.user.id == userid:
return player

@staticmethod
def get_player_from_string(string):
"""Find a player object from user input string.
Code inspired from belungawhale's discord werewolf project.
Code inspired from belungawhale's discord werewolf project.
"""
import globvars
game = globvars.master_state.game
Expand Down Expand Up @@ -202,7 +203,7 @@ class NotDay(commands.CheckFailure):


class NotDawn(commands.CheckFailure):
"""Raised when a command user used the command during another phase than
"""Raised when a command user used the command during another phase than
dawn when not supposed to
"""
pass
Expand Down Expand Up @@ -273,6 +274,11 @@ class NoRepeatTargets(AbilityForbidden):
pass


class MustBeMoreThanThreeAlivePlayers(AbilityForbidden):
"""There must be more than three alive players for the ability to be used"""
pass


class GameLogic:
"""Game logic decorators to be used on ability methods in character classes"""

Expand All @@ -284,11 +290,11 @@ def inner(self, player, targets):
if target.user.id == player.user.id:
raise NoSelfTargetting(no_self_targetting_str.format(player.user.mention, x_emoji))
return func(self, player, targets)
return inner
return inner

@staticmethod
def requires_status(status_effect):
"""Decorator for abilities that require the player to be under a specific status.
"""Decorator for abilities that require the player to be under a specific status.
Decorator factory that creates decorators based on the status type.

@status_effect: StatusList enum object
Expand All @@ -303,19 +309,19 @@ def inner(self, player, targets):

@staticmethod
def unique_ability(ability_type):
"""Decorator for unique abilities to be used once per game. Decorator factory that
"""Decorator for unique abilities to be used once per game. Decorator factory that
creates decorators based on the ability type.

@ability_type: ActionTypes() enum object
"""
def decorator(func):
def inner(self, player, targets):
from botc import Flags, ActionTypes
# Slayer's unique "slay" ability. Everyone may use it publicy once.
# Slayer's unique "slay" ability. Everyone may use it publicly once.
if ability_type == ActionTypes.slay:
if not player.role.ego_self.inventory.has_item_in_inventory(Flags.slayer_unique_attempt):
raise UniqueAbilityError(unique_ability_used.format(player.user.mention, x_emoji))
# Future roles that have a unique ability must go into elif blocks, or else the uncaught
# Future roles that have a unique ability must go into elif blocks, or else the uncaught
# ones will automatically trigger an assertion error.
else:
assert 0, "Unique ability check went wrong."
Expand All @@ -342,7 +348,7 @@ def inner(self, player, targets):
raise ChangesNotAllowed(changes_not_allowed.format(player.user.mention, x_emoji))
return func(self, player, targets)
return inner

@staticmethod
def changes_not_allowed_dawn(func):
"""Decorator for abilities that cannot modify targets after inputting them"""
Expand All @@ -352,7 +358,7 @@ def inner(self, player, targets):
raise ChangesNotAllowed(changes_not_allowed.format(player.user.mention, x_emoji))
return func(self, player, targets)
return inner

@staticmethod
def requires_one_target(func):
"""Decorator for abilities that require one target"""
Expand All @@ -361,7 +367,7 @@ def inner(self, player, targets):
raise MustBeOneTarget(requires_one_target_str.format(player.user.mention, x_emoji))
return func(self, player, targets)
return inner

@staticmethod
def requires_two_targets(func):
"""Decorator for abilities that require two targets"""
Expand All @@ -370,7 +376,7 @@ def inner(self, player, targets):
raise MustBeTwoTargets(requires_two_targets_str.format(player.user.mention, x_emoji))
return func(self, player, targets)
return inner

@staticmethod
def requires_different_targets(func):
"""Decorator for abilities that do not allow repeat players in the targets"""
Expand All @@ -381,6 +387,16 @@ def inner(self, player, targets):
return func(self, player, targets)
return inner

@staticmethod
def requires_more_than_three_alive_players(func):
"""Decorator for abilities that require more than three players to be alive"""
def inner(self, player, targets):
import globvars
if globvars.master_state.game.nb_alive_players == 3:
raise MustBeMoreThanThreeAlivePlayers(requires_more_than_three_alive_players_str.format(player.user.mention, x_emoji))
return func(self, player, targets)
return inner


# ========== CONVERTERS ============================================================
# ----------------------------------------------------------------------------------
Expand Down Expand Up @@ -421,16 +437,22 @@ class RoleConverter(commands.Converter):

async def convert(self, ctx, argument):
"""
Find a role name amongst the botc pack.
Find a role name amongst the botc pack.
Return the role class if it is found, else return None

The game_packs variable is coded in the following way:

{'botc': {'game_obj': <botc.Game.Game object at 0x1187bffd0>, 'gamemodes': {'trouble-brewing':
[Baron Obj, Butler Obj, Chef Obj, Drunk Obj, Empath Obj, Fortune Teller Obj, Imp Obj,
Investigator Obj, Librarian Obj, Mayor Obj, Monk Obj, Poisoner Obj, Ravenkeeper Obj,
Recluse Obj, Saint Obj, Scarlet Woman Obj, Slayer Obj, Soldier Obj, Undertaker Obj,
Virgin Obj, Washerwoman Obj]}}}
{'botc': {'game_obj': Blood on the Clocktower, 'formatter': <botc.setups.BOTCFormatter object at 0x1187bffd0>,
'gamemodes': {'trouble-brewing': [Baron Obj, Butler Obj, Chef Obj, Drunk Obj, Empath Obj, Fortune Teller Obj,
Imp Obj, Investigator Obj, Librarian Obj, Mayor Obj, Monk Obj, Poisoner Obj, Ravenkeeper Obj, Recluse Obj,
Saint Obj, Scarlet Woman Obj, Slayer Obj, Soldier Obj, Spy Obj, Undertaker Obj, Virgin Obj, Washerwoman Obj],
'bad-moon-rising': [Assassin Obj, Chambermaid Obj, Courtier Obj, Devil's Advocate Obj, Exorcist Obj, Fool Obj,
Gambler Obj, Godfather Obj, Goon Obj, Gossip Obj, Grandmother Obj, Innkeeper Obj, Lunatic Obj, Mastermind Obj,
Minstrel Obj, Moonchild Obj, Pacifist Obj, Po Obj, Professor Obj, Pukka Obj, Sailor Obj, Shabaloth Obj,
Tea Lady Obj, Tinker Obj, Zombuul Obj], 'sects-&-violets': [Artist Obj, Barber Obj, Cerenovus Obj,
Clockmaker Obj, Dreamer Obj, Evil Twin Obj, Fang Gu Obj, Flowergirl Obj, Juggler Obj, Klutz Obj,
Mathematician Obj, Mutant Obj, No Dashii Obj, Oracle Obj, Philosopher Obj, Pit-Hag Obj, Sage Obj, Savant Obj,
Seamstress Obj, Snake Charmer Obj, Sweetheart Obj, Town Crier Obj, Vigormortis Obj, Vortox Obj, Witch Obj]}}}
"""
import globvars
editions = globvars.master_state.game_packs["botc"]["gamemodes"]
Expand Down Expand Up @@ -476,4 +498,4 @@ def pick(self, category):
weights = lore[category]["weights"]
)
return chosen[0]

Loading