Adding constants
This commit is contained in:
		
							parent
							
								
									eb0c79ef1d
								
							
						
					
					
						commit
						61049c2343
					
				@ -1,6 +1,7 @@
 | 
				
			|||||||
import bisect
 | 
					import bisect
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
from collections import defaultdict
 | 
					from collections import defaultdict
 | 
				
			||||||
 | 
					from operator import attrgetter
 | 
				
			||||||
from random import choice
 | 
					from random import choice
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import discord
 | 
					import discord
 | 
				
			||||||
@ -16,6 +17,7 @@ from redbot.core import commands
 | 
				
			|||||||
from werewolf import roles
 | 
					from werewolf import roles
 | 
				
			||||||
from redbot.core.utils.menus import menu, prev_page, next_page, close_menu
 | 
					from redbot.core.utils.menus import menu, prev_page, next_page, close_menu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from werewolf.constants import ROLE_CATEGORY_DESCRIPTIONS
 | 
				
			||||||
from werewolf.role import Role
 | 
					from werewolf.role import Role
 | 
				
			||||||
 | 
					
 | 
				
			||||||
log = logging.getLogger("red.fox_v3.werewolf.builder")
 | 
					log = logging.getLogger("red.fox_v3.werewolf.builder")
 | 
				
			||||||
@ -25,104 +27,40 @@ log = logging.getLogger("red.fox_v3.werewolf.builder")
 | 
				
			|||||||
ROLE_DICT = {name: cls for name, cls in roles.__dict__.items() if isinstance(cls, type)}
 | 
					ROLE_DICT = {name: cls for name, cls in roles.__dict__.items() if isinstance(cls, type)}
 | 
				
			||||||
ROLE_LIST = sorted(
 | 
					ROLE_LIST = sorted(
 | 
				
			||||||
    [cls for cls in ROLE_DICT.values()],
 | 
					    [cls for cls in ROLE_DICT.values()],
 | 
				
			||||||
    key=lambda x: x.alignment,
 | 
					    key=attrgetter('alignment'),
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
log.debug(f"{ROLE_DICT=}")
 | 
					log.debug(f"{ROLE_DICT=}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Town, Werewolf, Neutral
 | 
				
			||||||
ALIGNMENT_COLORS = [0x008000, 0xFF0000, 0xC0C0C0]
 | 
					ALIGNMENT_COLORS = [0x008000, 0xFF0000, 0xC0C0C0]
 | 
				
			||||||
# TOWN_ROLES = [(idx, role) for idx, r_tuple in enumerate(ROLE_LIST) if role.alignment == 1]
 | 
					 | 
				
			||||||
# WW_ROLES = [(idx, role) for idx, r_tuple in enumerate(ROLE_LIST) if role.alignment == 2]
 | 
					 | 
				
			||||||
# OTHER_ROLES = [
 | 
					 | 
				
			||||||
#     (idx, role) for idx, r_tuple in enumerate(ROLE_LIST) if role.alignment not in [0, 1]
 | 
					 | 
				
			||||||
# ]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
ROLE_PAGES = []
 | 
					ROLE_PAGES = []
 | 
				
			||||||
PAGE_GROUPS = [0]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ROLE_CATEGORIES = {
 | 
					 | 
				
			||||||
    1: "Random",
 | 
					 | 
				
			||||||
    2: "Investigative",
 | 
					 | 
				
			||||||
    3: "Protective",
 | 
					 | 
				
			||||||
    4: "Government",
 | 
					 | 
				
			||||||
    5: "Killing",
 | 
					 | 
				
			||||||
    6: "Power (Special night action)",
 | 
					 | 
				
			||||||
    11: "Random",
 | 
					 | 
				
			||||||
    12: "Deception",
 | 
					 | 
				
			||||||
    15: "Killing",
 | 
					 | 
				
			||||||
    16: "Support",
 | 
					 | 
				
			||||||
    21: "Benign",
 | 
					 | 
				
			||||||
    22: "Evil",
 | 
					 | 
				
			||||||
    23: "Killing",
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CATEGORY_COUNT = []
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def role_embed(idx, role, color):
 | 
					def role_embed(idx, role: Role, color):
 | 
				
			||||||
    embed = discord.Embed(
 | 
					    embed = discord.Embed(
 | 
				
			||||||
        title=f"**{idx}** - {role.__name__}",
 | 
					        title=f"**{idx}** - {role.__name__}",
 | 
				
			||||||
        description=role.game_start_message,
 | 
					        description=role.game_start_message,
 | 
				
			||||||
        color=color,
 | 
					        color=color,
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					    if role.icon_url is not None:
 | 
				
			||||||
 | 
					        embed.set_thumbnail(url=role.icon_url)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    embed.add_field(
 | 
					    embed.add_field(
 | 
				
			||||||
        name="Alignment", value=["Town", "Werewolf", "Neutral"][role.alignment - 1], inline=True
 | 
					        name="Alignment", value=["Town", "Werewolf", "Neutral"][role.alignment - 1], inline=False
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    embed.add_field(name="Multiples Allowed", value=str(not role.unique), inline=True)
 | 
					    embed.add_field(name="Multiples Allowed", value=str(not role.unique), inline=False)
 | 
				
			||||||
    embed.add_field(
 | 
					    embed.add_field(
 | 
				
			||||||
        name="Role Type", value=", ".join(ROLE_CATEGORIES[x] for x in role.category), inline=True
 | 
					        name="Role Types",
 | 
				
			||||||
 | 
					        value=", ".join(ROLE_CATEGORY_DESCRIPTIONS[x] for x in role.category),
 | 
				
			||||||
 | 
					        inline=False,
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    embed.add_field(name="Random Option", value=str(role.rand_choice), inline=True)
 | 
					    embed.add_field(name="Random Option", value=str(role.rand_choice), inline=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return embed
 | 
					    return embed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def setup():
 | 
					 | 
				
			||||||
    # Roles
 | 
					 | 
				
			||||||
    last_alignment = ROLE_LIST[0].alignment
 | 
					 | 
				
			||||||
    for idx, role in enumerate(ROLE_LIST):
 | 
					 | 
				
			||||||
        if role.alignment != last_alignment and len(ROLE_PAGES) - 1 not in PAGE_GROUPS:
 | 
					 | 
				
			||||||
            PAGE_GROUPS.append(len(ROLE_PAGES) - 1)
 | 
					 | 
				
			||||||
            last_alignment = role.alignment
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ROLE_PAGES.append(role_embed(idx, role, ALIGNMENT_COLORS[role.alignment - 1]))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Random Town Roles
 | 
					 | 
				
			||||||
    if len(ROLE_PAGES) - 1 not in PAGE_GROUPS:
 | 
					 | 
				
			||||||
        PAGE_GROUPS.append(len(ROLE_PAGES) - 1)
 | 
					 | 
				
			||||||
    for k, v in ROLE_CATEGORIES.items():
 | 
					 | 
				
			||||||
        if 0 < k <= 6:
 | 
					 | 
				
			||||||
            ROLE_PAGES.append(
 | 
					 | 
				
			||||||
                discord.Embed(title="RANDOM:Town Role", description=f"Town {v}", color=0x008000)
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
            CATEGORY_COUNT.append(k)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Random WW Roles
 | 
					 | 
				
			||||||
    if len(ROLE_PAGES) - 1 not in PAGE_GROUPS:
 | 
					 | 
				
			||||||
        PAGE_GROUPS.append(len(ROLE_PAGES) - 1)
 | 
					 | 
				
			||||||
    for k, v in ROLE_CATEGORIES.items():
 | 
					 | 
				
			||||||
        if 10 < k <= 16:
 | 
					 | 
				
			||||||
            ROLE_PAGES.append(
 | 
					 | 
				
			||||||
                discord.Embed(
 | 
					 | 
				
			||||||
                    title="RANDOM:Werewolf Role",
 | 
					 | 
				
			||||||
                    description=f"Werewolf {v}",
 | 
					 | 
				
			||||||
                    color=0xFF0000,
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
            CATEGORY_COUNT.append(k)
 | 
					 | 
				
			||||||
    # Random Neutral Roles
 | 
					 | 
				
			||||||
    if len(ROLE_PAGES) - 1 not in PAGE_GROUPS:
 | 
					 | 
				
			||||||
        PAGE_GROUPS.append(len(ROLE_PAGES) - 1)
 | 
					 | 
				
			||||||
    for k, v in ROLE_CATEGORIES.items():
 | 
					 | 
				
			||||||
        if 20 < k <= 26:
 | 
					 | 
				
			||||||
            ROLE_PAGES.append(
 | 
					 | 
				
			||||||
                discord.Embed(
 | 
					 | 
				
			||||||
                    title=f"RANDOM:Neutral Role", description="Neutral {v}", color=0xC0C0C0
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
            CATEGORY_COUNT.append(k)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
Example code:
 | 
					Example code:
 | 
				
			||||||
0 = Villager
 | 
					0 = Villager
 | 
				
			||||||
@ -189,15 +127,15 @@ async def parse_code(code, game):
 | 
				
			|||||||
    return decode
 | 
					    return decode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async def encode(roles, rand_roles):
 | 
					async def encode(role_list, rand_roles):
 | 
				
			||||||
    """Convert role list to code"""
 | 
					    """Convert role list to code"""
 | 
				
			||||||
    out_code = ""
 | 
					    out_code = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    digit_sort = sorted(role for role in roles if role < 10)
 | 
					    digit_sort = sorted(role for role in role_list if role < 10)
 | 
				
			||||||
    for role in digit_sort:
 | 
					    for role in digit_sort:
 | 
				
			||||||
        out_code += str(role)
 | 
					        out_code += str(role)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    digit_sort = sorted(role for role in roles if 10 <= role < 100)
 | 
					    digit_sort = sorted(role for role in role_list if 10 <= role < 100)
 | 
				
			||||||
    if digit_sort:
 | 
					    if digit_sort:
 | 
				
			||||||
        out_code += "-"
 | 
					        out_code += "-"
 | 
				
			||||||
        for role in digit_sort:
 | 
					        for role in digit_sort:
 | 
				
			||||||
@ -229,51 +167,6 @@ async def encode(roles, rand_roles):
 | 
				
			|||||||
    return out_code
 | 
					    return out_code
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async def next_group(
 | 
					 | 
				
			||||||
    ctx: commands.Context,
 | 
					 | 
				
			||||||
    pages: list,
 | 
					 | 
				
			||||||
    controls: dict,
 | 
					 | 
				
			||||||
    message: discord.Message,
 | 
					 | 
				
			||||||
    page: int,
 | 
					 | 
				
			||||||
    timeout: float,
 | 
					 | 
				
			||||||
    emoji: str,
 | 
					 | 
				
			||||||
):
 | 
					 | 
				
			||||||
    perms = message.channel.permissions_for(ctx.me)
 | 
					 | 
				
			||||||
    if perms.manage_messages:  # Can manage messages, so remove react
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            await message.remove_reaction(emoji, ctx.author)
 | 
					 | 
				
			||||||
        except discord.NotFound:
 | 
					 | 
				
			||||||
            pass
 | 
					 | 
				
			||||||
    page = bisect.bisect_right(PAGE_GROUPS, page)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if page == len(PAGE_GROUPS):
 | 
					 | 
				
			||||||
        page = PAGE_GROUPS[0]
 | 
					 | 
				
			||||||
    else:
 | 
					 | 
				
			||||||
        page = PAGE_GROUPS[page]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return await menu(ctx, pages, controls, message=message, page=page, timeout=timeout)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
async def prev_group(
 | 
					 | 
				
			||||||
    ctx: commands.Context,
 | 
					 | 
				
			||||||
    pages: list,
 | 
					 | 
				
			||||||
    controls: dict,
 | 
					 | 
				
			||||||
    message: discord.Message,
 | 
					 | 
				
			||||||
    page: int,
 | 
					 | 
				
			||||||
    timeout: float,
 | 
					 | 
				
			||||||
    emoji: str,
 | 
					 | 
				
			||||||
):
 | 
					 | 
				
			||||||
    perms = message.channel.permissions_for(ctx.me)
 | 
					 | 
				
			||||||
    if perms.manage_messages:  # Can manage messages, so remove react
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            await message.remove_reaction(emoji, ctx.author)
 | 
					 | 
				
			||||||
        except discord.NotFound:
 | 
					 | 
				
			||||||
            pass
 | 
					 | 
				
			||||||
    page = PAGE_GROUPS[bisect.bisect_left(PAGE_GROUPS, page) - 1]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return await menu(ctx, pages, controls, message=message, page=page, timeout=timeout)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def role_from_alignment(alignment):
 | 
					def role_from_alignment(alignment):
 | 
				
			||||||
    return [
 | 
					    return [
 | 
				
			||||||
        role_embed(idx, role, ALIGNMENT_COLORS[role.alignment - 1])
 | 
					        role_embed(idx, role, ALIGNMENT_COLORS[role.alignment - 1])
 | 
				
			||||||
@ -316,11 +209,11 @@ def say_role_list(code_list, rand_roles):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    for role in rand_roles:
 | 
					    for role in rand_roles:
 | 
				
			||||||
        if 0 < role <= 6:
 | 
					        if 0 < role <= 6:
 | 
				
			||||||
            role_dict[f"Town {ROLE_CATEGORIES[role]}"] += 1
 | 
					            role_dict[f"Town {ROLE_CATEGORY_DESCRIPTIONS[role]}"] += 1
 | 
				
			||||||
        if 10 < role <= 16:
 | 
					        if 10 < role <= 16:
 | 
				
			||||||
            role_dict[f"Werewolf {ROLE_CATEGORIES[role]}"] += 1
 | 
					            role_dict[f"Werewolf {ROLE_CATEGORY_DESCRIPTIONS[role]}"] += 1
 | 
				
			||||||
        if 20 < role <= 26:
 | 
					        if 20 < role <= 26:
 | 
				
			||||||
            role_dict[f"Neutral {ROLE_CATEGORIES[role]}"] += 1
 | 
					            role_dict[f"Neutral {ROLE_CATEGORY_DESCRIPTIONS[role]}"] += 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for k, v in role_dict.items():
 | 
					    for k, v in role_dict.items():
 | 
				
			||||||
        embed.add_field(name=k, value=f"Count: {v}", inline=True)
 | 
					        embed.add_field(name=k, value=f"Count: {v}", inline=True)
 | 
				
			||||||
@ -332,15 +225,69 @@ class GameBuilder:
 | 
				
			|||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        self.code = []
 | 
					        self.code = []
 | 
				
			||||||
        self.rand_roles = []
 | 
					        self.rand_roles = []
 | 
				
			||||||
        setup()
 | 
					        self.page_groups = [0]
 | 
				
			||||||
 | 
					        self.category_count = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.setup()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def setup(self):
 | 
				
			||||||
 | 
					        # Roles
 | 
				
			||||||
 | 
					        last_alignment = ROLE_LIST[0].alignment
 | 
				
			||||||
 | 
					        for idx, role in enumerate(ROLE_LIST):
 | 
				
			||||||
 | 
					            if role.alignment != last_alignment and len(ROLE_PAGES) - 1 not in self.page_groups:
 | 
				
			||||||
 | 
					                self.page_groups.append(len(ROLE_PAGES) - 1)
 | 
				
			||||||
 | 
					                last_alignment = role.alignment
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ROLE_PAGES.append(role_embed(idx, role, ALIGNMENT_COLORS[role.alignment - 1]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Random Town Roles
 | 
				
			||||||
 | 
					        if len(ROLE_PAGES) - 1 not in self.page_groups:
 | 
				
			||||||
 | 
					            self.page_groups.append(len(ROLE_PAGES) - 1)
 | 
				
			||||||
 | 
					        for k, v in ROLE_CATEGORY_DESCRIPTIONS.items():
 | 
				
			||||||
 | 
					            if 0 < k <= 9:
 | 
				
			||||||
 | 
					                ROLE_PAGES.append(
 | 
				
			||||||
 | 
					                    discord.Embed(
 | 
				
			||||||
 | 
					                        title="RANDOM:Town Role",
 | 
				
			||||||
 | 
					                        description=f"Town {v}",
 | 
				
			||||||
 | 
					                        color=ALIGNMENT_COLORS[0],
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                self.category_count.append(k)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Random WW Roles
 | 
				
			||||||
 | 
					        if len(ROLE_PAGES) - 1 not in self.page_groups:
 | 
				
			||||||
 | 
					            self.page_groups.append(len(ROLE_PAGES) - 1)
 | 
				
			||||||
 | 
					        for k, v in ROLE_CATEGORY_DESCRIPTIONS.items():
 | 
				
			||||||
 | 
					            if 10 < k <= 19:
 | 
				
			||||||
 | 
					                ROLE_PAGES.append(
 | 
				
			||||||
 | 
					                    discord.Embed(
 | 
				
			||||||
 | 
					                        title="RANDOM:Werewolf Role",
 | 
				
			||||||
 | 
					                        description=f"Werewolf {v}",
 | 
				
			||||||
 | 
					                        color=ALIGNMENT_COLORS[1],
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                self.category_count.append(k)
 | 
				
			||||||
 | 
					        # Random Neutral Roles
 | 
				
			||||||
 | 
					        if len(ROLE_PAGES) - 1 not in self.page_groups:
 | 
				
			||||||
 | 
					            self.page_groups.append(len(ROLE_PAGES) - 1)
 | 
				
			||||||
 | 
					        for k, v in ROLE_CATEGORY_DESCRIPTIONS.items():
 | 
				
			||||||
 | 
					            if 20 < k <= 29:
 | 
				
			||||||
 | 
					                ROLE_PAGES.append(
 | 
				
			||||||
 | 
					                    discord.Embed(
 | 
				
			||||||
 | 
					                        title=f"RANDOM:Neutral Role",
 | 
				
			||||||
 | 
					                        description=f"Neutral {v}",
 | 
				
			||||||
 | 
					                        color=ALIGNMENT_COLORS[2],
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                self.category_count.append(k)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def build_game(self, ctx: commands.Context):
 | 
					    async def build_game(self, ctx: commands.Context):
 | 
				
			||||||
        new_controls = {
 | 
					        new_controls = {
 | 
				
			||||||
            "⏪": prev_group,
 | 
					            "⏪": self.prev_group,
 | 
				
			||||||
            "⬅": prev_page,
 | 
					            "⬅": prev_page,
 | 
				
			||||||
            "☑": self.select_page,
 | 
					            "☑": self.select_page,
 | 
				
			||||||
            "➡": next_page,
 | 
					            "➡": next_page,
 | 
				
			||||||
            "⏩": next_group,
 | 
					            "⏩": self.next_group,
 | 
				
			||||||
            "📇": self.list_roles,
 | 
					            "📇": self.list_roles,
 | 
				
			||||||
            "❌": close_menu,
 | 
					            "❌": close_menu,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -391,8 +338,53 @@ class GameBuilder:
 | 
				
			|||||||
                pass
 | 
					                pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if page >= len(ROLE_LIST):
 | 
					        if page >= len(ROLE_LIST):
 | 
				
			||||||
            self.rand_roles.append(CATEGORY_COUNT[page - len(ROLE_LIST)])
 | 
					            self.rand_roles.append(self.category_count[page - len(ROLE_LIST)])
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self.code.append(page)
 | 
					            self.code.append(page)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return await menu(ctx, pages, controls, message=message, page=page, timeout=timeout)
 | 
					        return await menu(ctx, pages, controls, message=message, page=page, timeout=timeout)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def next_group(
 | 
				
			||||||
 | 
					        self,
 | 
				
			||||||
 | 
					        ctx: commands.Context,
 | 
				
			||||||
 | 
					        pages: list,
 | 
				
			||||||
 | 
					        controls: dict,
 | 
				
			||||||
 | 
					        message: discord.Message,
 | 
				
			||||||
 | 
					        page: int,
 | 
				
			||||||
 | 
					        timeout: float,
 | 
				
			||||||
 | 
					        emoji: str,
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
 | 
					        perms = message.channel.permissions_for(ctx.me)
 | 
				
			||||||
 | 
					        if perms.manage_messages:  # Can manage messages, so remove react
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                await message.remove_reaction(emoji, ctx.author)
 | 
				
			||||||
 | 
					            except discord.NotFound:
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					        page = bisect.bisect_right(self.page_groups, page)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if page == len(self.page_groups):
 | 
				
			||||||
 | 
					            page = self.page_groups[0]
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            page = self.page_groups[page]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return await menu(ctx, pages, controls, message=message, page=page, timeout=timeout)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def prev_group(
 | 
				
			||||||
 | 
					        self,
 | 
				
			||||||
 | 
					        ctx: commands.Context,
 | 
				
			||||||
 | 
					        pages: list,
 | 
				
			||||||
 | 
					        controls: dict,
 | 
				
			||||||
 | 
					        message: discord.Message,
 | 
				
			||||||
 | 
					        page: int,
 | 
				
			||||||
 | 
					        timeout: float,
 | 
				
			||||||
 | 
					        emoji: str,
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
 | 
					        perms = message.channel.permissions_for(ctx.me)
 | 
				
			||||||
 | 
					        if perms.manage_messages:  # Can manage messages, so remove react
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                await message.remove_reaction(emoji, ctx.author)
 | 
				
			||||||
 | 
					            except discord.NotFound:
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					        page = self.page_groups[bisect.bisect_left(self.page_groups, page) - 1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return await menu(ctx, pages, controls, message=message, page=page, timeout=timeout)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										91
									
								
								werewolf/constants.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								werewolf/constants.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,91 @@
 | 
				
			|||||||
 | 
					"""
 | 
				
			||||||
 | 
					Role Constants
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Role Alignment guide as follows:
 | 
				
			||||||
 | 
					        Town: 1
 | 
				
			||||||
 | 
					        Werewolf: 2
 | 
				
			||||||
 | 
					        Neutral: 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Additional alignments may be added when warring factions are added
 | 
				
			||||||
 | 
					        (Rival werewolves, cultists, vampires)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Role Category enrollment guide as follows (See Role.category):
 | 
				
			||||||
 | 
					        Town:
 | 
				
			||||||
 | 
					        1: Random, 2: Investigative, 3: Protective, 4: Government,
 | 
				
			||||||
 | 
					        5: Killing, 6: Power (Special night action)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Werewolf:
 | 
				
			||||||
 | 
					        11: Random, 12: Deception, 15: Killing, 16: Support
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Neutral:
 | 
				
			||||||
 | 
					        21: Benign, 22: Evil, 23: Killing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Example category:
 | 
				
			||||||
 | 
					        category = [1, 5, 6] Could be Veteran
 | 
				
			||||||
 | 
					        category = [1, 5] Could be Bodyguard
 | 
				
			||||||
 | 
					        category = [11, 16] Could be Werewolf Silencer
 | 
				
			||||||
 | 
					        category = [22] Could be Blob (non-killing)
 | 
				
			||||||
 | 
					        category = [22, 23] Could be Serial-Killer
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ALIGNMENT_TOWN = 1
 | 
				
			||||||
 | 
					ALIGNMENT_WEREWOLF = 2
 | 
				
			||||||
 | 
					ALIGNMENT_NEUTRAL = 3
 | 
				
			||||||
 | 
					ALIGNMENT_MAP = {"Town": 1, "Werewolf": 2, "Neutral": 3}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# 0-9: Town Role Categories
 | 
				
			||||||
 | 
					# 10-19: Werewolf Role Categories
 | 
				
			||||||
 | 
					# 20-29: Neutral Role Categories
 | 
				
			||||||
 | 
					CATEGORY_TOWN_RANDOM = 1
 | 
				
			||||||
 | 
					CATEGORY_TOWN_INVESTIGATIVE = 2
 | 
				
			||||||
 | 
					CATEGORY_TOWN_PROTECTIVE = 3
 | 
				
			||||||
 | 
					CATEGORY_TOWN_GOVERNMENT = 4
 | 
				
			||||||
 | 
					CATEGORY_TOWN_KILLING = 5
 | 
				
			||||||
 | 
					CATEGORY_TOWN_POWER = 6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CATEGORY_WW_RANDOM = 11
 | 
				
			||||||
 | 
					CATEGORY_WW_DECEPTION = 12
 | 
				
			||||||
 | 
					CATEGORY_WW_KILLING = 15
 | 
				
			||||||
 | 
					CATEGORY_WW_SUPPORT = 16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CATEGORY_NEUTRAL_BENIGN = 21
 | 
				
			||||||
 | 
					CATEGORY_NEUTRAL_EVIL = 22
 | 
				
			||||||
 | 
					CATEGORY_NEUTRAL_KILLING = 23
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ROLE_CATEGORY_DESCRIPTIONS = {
 | 
				
			||||||
 | 
					    CATEGORY_TOWN_RANDOM: "Random",
 | 
				
			||||||
 | 
					    CATEGORY_TOWN_INVESTIGATIVE: "Investigative",
 | 
				
			||||||
 | 
					    CATEGORY_TOWN_PROTECTIVE: "Protective",
 | 
				
			||||||
 | 
					    CATEGORY_TOWN_GOVERNMENT: "Government",
 | 
				
			||||||
 | 
					    CATEGORY_TOWN_KILLING: "Killing",
 | 
				
			||||||
 | 
					    CATEGORY_TOWN_POWER: "Power (Special night action)",
 | 
				
			||||||
 | 
					    CATEGORY_WW_RANDOM: "Random",
 | 
				
			||||||
 | 
					    CATEGORY_WW_DECEPTION: "Deception",
 | 
				
			||||||
 | 
					    CATEGORY_WW_KILLING: "Killing",
 | 
				
			||||||
 | 
					    CATEGORY_WW_SUPPORT: "Support",
 | 
				
			||||||
 | 
					    CATEGORY_NEUTRAL_BENIGN: "Benign",
 | 
				
			||||||
 | 
					    CATEGORY_NEUTRAL_EVIL: "Evil",
 | 
				
			||||||
 | 
					    CATEGORY_NEUTRAL_KILLING: "Killing",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					Listener Actions Priority Guide
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Action priority guide as follows (see listeners.py for wolflistener):
 | 
				
			||||||
 | 
					        _at_night_start
 | 
				
			||||||
 | 
					        0. No Action
 | 
				
			||||||
 | 
					        1. Detain actions (Jailer/Kidnapper)
 | 
				
			||||||
 | 
					        2. Group discussions and choose targets
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        _at_night_end
 | 
				
			||||||
 | 
					        0. No Action
 | 
				
			||||||
 | 
					        1. Self actions (Veteran)
 | 
				
			||||||
 | 
					        2. Target switching and role blocks (bus driver, witch, escort)
 | 
				
			||||||
 | 
					        3. Protection / Preempt actions (bodyguard/framer)
 | 
				
			||||||
 | 
					        4. Non-disruptive actions (seer/silencer)
 | 
				
			||||||
 | 
					        5. Disruptive actions (Killing)
 | 
				
			||||||
 | 
					        6. Role altering actions (Cult / Mason / Shifter)
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
@ -639,14 +639,14 @@ class Game:
 | 
				
			|||||||
        await target.role.visit(source)
 | 
					        await target.role.visit(source)
 | 
				
			||||||
        await self._at_visit(target, source)
 | 
					        await self._at_visit(target, source)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def visit(self, target_id, source):
 | 
					    async def visit(self, target_id, source) -> Union[Player, None]:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Night visit target_id
 | 
					        Night visit target_id
 | 
				
			||||||
        Returns a target for role information (i.e. Seer)
 | 
					        Returns a target for role information (i.e. Seer)
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if source.role.blocked:
 | 
					        if source.role.blocked:
 | 
				
			||||||
            # Blocker handles text
 | 
					            # Blocker handles text
 | 
				
			||||||
            return
 | 
					            return None
 | 
				
			||||||
        target = await self.get_night_target(target_id, source)
 | 
					        target = await self.get_night_target(target_id, source)
 | 
				
			||||||
        await self._visit(target, source)
 | 
					        await self._visit(target, source)
 | 
				
			||||||
        return target
 | 
					        return target
 | 
				
			||||||
@ -786,10 +786,10 @@ class Game:
 | 
				
			|||||||
        if not target.alive:  # Still dead after notifying
 | 
					        if not target.alive:  # Still dead after notifying
 | 
				
			||||||
            await self.dead_perms(self.village_channel, target.member)
 | 
					            await self.dead_perms(self.village_channel, target.member)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def get_night_target(self, target_id, source=None):
 | 
					    async def get_night_target(self, target_id, source=None) -> Player:
 | 
				
			||||||
        return self.players[target_id]  # ToDo check source
 | 
					        return self.players[target_id]  # ToDo check source
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def get_day_target(self, target_id, source=None):
 | 
					    async def get_day_target(self, target_id, source=None) -> Player:
 | 
				
			||||||
        return self.players[target_id]  # ToDo check source
 | 
					        return self.players[target_id]  # ToDo check source
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def set_code(self, ctx: commands.Context, game_code):
 | 
					    async def set_code(self, ctx: commands.Context, game_code):
 | 
				
			||||||
@ -829,7 +829,7 @@ class Game:
 | 
				
			|||||||
            # Sorted players, now assign id's
 | 
					            # Sorted players, now assign id's
 | 
				
			||||||
            await self.players[idx].assign_id(idx)
 | 
					            await self.players[idx].assign_id(idx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def get_player_by_member(self, member):
 | 
					    async def get_player_by_member(self, member: discord.Member):
 | 
				
			||||||
        for player in self.players:
 | 
					        for player in self.players:
 | 
				
			||||||
            if player.member == member:
 | 
					            if player.member == member:
 | 
				
			||||||
                return player
 | 
					                return player
 | 
				
			||||||
 | 
				
			|||||||
@ -26,6 +26,8 @@ class Role(WolfListener):
 | 
				
			|||||||
        category = [1, 5, 6] Could be Veteran
 | 
					        category = [1, 5, 6] Could be Veteran
 | 
				
			||||||
        category = [1, 5] Could be Bodyguard
 | 
					        category = [1, 5] Could be Bodyguard
 | 
				
			||||||
        category = [11, 16] Could be Werewolf Silencer
 | 
					        category = [11, 16] Could be Werewolf Silencer
 | 
				
			||||||
 | 
					        category = [22] Could be Blob (non-killing)
 | 
				
			||||||
 | 
					        category = [22, 23] Could be Serial-Killer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Action priority guide as follows (on_event function):
 | 
					    Action priority guide as follows (on_event function):
 | 
				
			||||||
@ -44,10 +46,12 @@ class Role(WolfListener):
 | 
				
			|||||||
        6. Role altering actions (Cult / Mason / Shifter)
 | 
					        6. Role altering actions (Cult / Mason / Shifter)
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rand_choice = False  # Determines if it can be picked as a random role (False for unusually disruptive roles)
 | 
					    # Determines if it can be picked as a random role (False for unusually disruptive roles)
 | 
				
			||||||
 | 
					    rand_choice = False  # TODO: Rework random with categories
 | 
				
			||||||
 | 
					    town_balance = 0  # Guess at power level and it's balance on the town
 | 
				
			||||||
    category = [0]  # List of enrolled categories (listed above)
 | 
					    category = [0]  # List of enrolled categories (listed above)
 | 
				
			||||||
    alignment = 0  # 1: Town, 2: Werewolf, 3: Neutral
 | 
					    alignment = 0  # 1: Town, 2: Werewolf, 3: Neutral
 | 
				
			||||||
    channel_id = ""  # Empty for no private channel
 | 
					    channel_name = ""  # Empty for no private channel
 | 
				
			||||||
    unique = False  # Only one of this role per game
 | 
					    unique = False  # Only one of this role per game
 | 
				
			||||||
    game_start_message = (
 | 
					    game_start_message = (
 | 
				
			||||||
        "Your role is **Default**\n"
 | 
					        "Your role is **Default**\n"
 | 
				
			||||||
@ -68,28 +72,9 @@ class Role(WolfListener):
 | 
				
			|||||||
        self.blocked = False
 | 
					        self.blocked = False
 | 
				
			||||||
        self.properties = {}  # Extra data for other roles (i.e. arsonist)
 | 
					        self.properties = {}  # Extra data for other roles (i.e. arsonist)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # self.action_list = [
 | 
					 | 
				
			||||||
        #     (self._at_game_start, 1),  # (Action, Priority)
 | 
					 | 
				
			||||||
        #     (self._at_day_start, 0),
 | 
					 | 
				
			||||||
        #     (self._at_voted, 0),
 | 
					 | 
				
			||||||
        #     (self._at_kill, 0),
 | 
					 | 
				
			||||||
        #     (self._at_hang, 0),
 | 
					 | 
				
			||||||
        #     (self._at_day_end, 0),
 | 
					 | 
				
			||||||
        #     (self._at_night_start, 0),
 | 
					 | 
				
			||||||
        #     (self._at_night_end, 0),
 | 
					 | 
				
			||||||
        #     (self._at_visit, 0),
 | 
					 | 
				
			||||||
        # ]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __repr__(self):
 | 
					    def __repr__(self):
 | 
				
			||||||
        return self.__class__.__name__
 | 
					        return self.__class__.__name__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # async def on_event(self, event, data):
 | 
					 | 
				
			||||||
    #     """
 | 
					 | 
				
			||||||
    #     See Game class for event guide
 | 
					 | 
				
			||||||
    #     """
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    #     await self.action_list[event][0](data)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    async def assign_player(self, player):
 | 
					    async def assign_player(self, player):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Give this role a player
 | 
					        Give this role a player
 | 
				
			||||||
@ -110,7 +95,7 @@ class Role(WolfListener):
 | 
				
			|||||||
    async def see_alignment(self, source=None):
 | 
					    async def see_alignment(self, source=None):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Interaction for investigative roles attempting
 | 
					        Interaction for investigative roles attempting
 | 
				
			||||||
        to see alignment (Village, Werewolf Other)
 | 
					        to see alignment (Village, Werewolf, Other)
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return "Other"
 | 
					        return "Other"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -128,37 +113,13 @@ class Role(WolfListener):
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        return "Default"
 | 
					        return "Default"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @wolflistener("at_game_start", priority=1)
 | 
					    @wolflistener("at_game_start", priority=2)
 | 
				
			||||||
    async def _at_game_start(self):
 | 
					    async def _at_game_start(self):
 | 
				
			||||||
        if self.channel_id:
 | 
					        if self.channel_name:
 | 
				
			||||||
            await self.game.register_channel(self.channel_id, self)
 | 
					            await self.game.register_channel(self.channel_name, self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await self.player.send_dm(self.game_start_message)  # Maybe embeds eventually
 | 
					        await self.player.send_dm(self.game_start_message)  # Maybe embeds eventually
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # async def _at_day_start(self, data=None):
 | 
					 | 
				
			||||||
    #     pass
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # async def _at_voted(self, data=None):
 | 
					 | 
				
			||||||
    #     pass
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # async def _at_kill(self, data=None):
 | 
					 | 
				
			||||||
    #     pass
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # async def _at_hang(self, data=None):
 | 
					 | 
				
			||||||
    #     pass
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # async def _at_day_end(self, data=None):
 | 
					 | 
				
			||||||
    #     pass
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # async def _at_night_start(self, data=None):
 | 
					 | 
				
			||||||
    #     pass
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # async def _at_night_end(self, data=None):
 | 
					 | 
				
			||||||
    #     pass
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # async def _at_visit(self, data=None):
 | 
					 | 
				
			||||||
    #     pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    async def kill(self, source):
 | 
					    async def kill(self, source):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Called when someone is trying to kill you!
 | 
					        Called when someone is trying to kill you!
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,7 @@
 | 
				
			|||||||
import logging
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from werewolf.constants import ALIGNMENT_TOWN, ALIGNMENT_WEREWOLF, CATEGORY_TOWN_INVESTIGATIVE, \
 | 
				
			||||||
 | 
					    CATEGORY_TOWN_RANDOM
 | 
				
			||||||
from werewolf.listener import wolflistener
 | 
					from werewolf.listener import wolflistener
 | 
				
			||||||
from werewolf.night_powers import pick_target
 | 
					from werewolf.night_powers import pick_target
 | 
				
			||||||
from werewolf.role import Role
 | 
					from werewolf.role import Role
 | 
				
			||||||
@ -8,9 +10,12 @@ log = logging.getLogger("red.fox_v3.werewolf.role.seer")
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Seer(Role):
 | 
					class Seer(Role):
 | 
				
			||||||
    rand_choice = True  # Determines if it can be picked as a random role (False for unusually disruptive roles)
 | 
					    rand_choice = True
 | 
				
			||||||
    category = [1, 2]  # List of enrolled categories (listed above)
 | 
					    category = [
 | 
				
			||||||
    alignment = 1  # 1: Town, 2: Werewolf, 3: Neutral
 | 
					        CATEGORY_TOWN_RANDOM,
 | 
				
			||||||
 | 
					        CATEGORY_TOWN_INVESTIGATIVE,
 | 
				
			||||||
 | 
					    ]  # List of enrolled categories (listed above)
 | 
				
			||||||
 | 
					    alignment = ALIGNMENT_TOWN  # 1: Town, 2: Werewolf, 3: Neutral
 | 
				
			||||||
    channel_id = ""  # Empty for no private channel
 | 
					    channel_id = ""  # Empty for no private channel
 | 
				
			||||||
    unique = False  # Only one of this role per game
 | 
					    unique = False  # Only one of this role per game
 | 
				
			||||||
    game_start_message = (
 | 
					    game_start_message = (
 | 
				
			||||||
@ -46,23 +51,23 @@ class Seer(Role):
 | 
				
			|||||||
    async def see_alignment(self, source=None):
 | 
					    async def see_alignment(self, source=None):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Interaction for investigative roles attempting
 | 
					        Interaction for investigative roles attempting
 | 
				
			||||||
        to see team (Village, Werewolf Other)
 | 
					        to see team (Village, Werewolf, Other)
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return "Village"
 | 
					        return ALIGNMENT_TOWN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def get_role(self, source=None):
 | 
					    async def get_role(self, source=None):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Interaction for powerful access of role
 | 
					        Interaction for powerful access of role
 | 
				
			||||||
        Unlikely to be able to deceive this
 | 
					        Unlikely to be able to deceive this
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return "Villager"
 | 
					        return "Seer"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def see_role(self, source=None):
 | 
					    async def see_role(self, source=None):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Interaction for investigative roles.
 | 
					        Interaction for investigative roles.
 | 
				
			||||||
        More common to be able to deceive these roles
 | 
					        More common to be able to deceive these roles
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return "Villager"
 | 
					        return "Seer"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @wolflistener("at_night_start", priority=2)
 | 
					    @wolflistener("at_night_start", priority=2)
 | 
				
			||||||
    async def _at_night_start(self):
 | 
					    async def _at_night_start(self):
 | 
				
			||||||
@ -84,9 +89,9 @@ class Seer(Role):
 | 
				
			|||||||
        if target:
 | 
					        if target:
 | 
				
			||||||
            alignment = await target.role.see_alignment(self.player)
 | 
					            alignment = await target.role.see_alignment(self.player)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if alignment == "Werewolf":
 | 
					        if alignment == ALIGNMENT_WEREWOLF:
 | 
				
			||||||
            out = "Your insight reveals this player to be a **Werewolf!**"
 | 
					            out = "Your insight reveals this player to be a **Werewolf!**"
 | 
				
			||||||
        else:
 | 
					        else: # Don't reveal neutrals
 | 
				
			||||||
            out = "You fail to find anything suspicious about this player..."
 | 
					            out = "You fail to find anything suspicious about this player..."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await self.player.send_dm(out)
 | 
					        await self.player.send_dm(out)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,6 @@
 | 
				
			|||||||
import logging
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from werewolf.constants import ALIGNMENT_NEUTRAL, CATEGORY_NEUTRAL_BENIGN
 | 
				
			||||||
from werewolf.listener import wolflistener
 | 
					from werewolf.listener import wolflistener
 | 
				
			||||||
from werewolf.night_powers import pick_target
 | 
					from werewolf.night_powers import pick_target
 | 
				
			||||||
from werewolf.role import Role
 | 
					from werewolf.role import Role
 | 
				
			||||||
@ -46,8 +47,9 @@ class Shifter(Role):
 | 
				
			|||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rand_choice = False  # Determines if it can be picked as a random role (False for unusually disruptive roles)
 | 
					    rand_choice = False  # Determines if it can be picked as a random role (False for unusually disruptive roles)
 | 
				
			||||||
    category = [22]  # List of enrolled categories (listed above)
 | 
					    town_balance = -3
 | 
				
			||||||
    alignment = 3  # 1: Town, 2: Werewolf, 3: Neutral
 | 
					    category = [CATEGORY_NEUTRAL_BENIGN]  # List of enrolled categories (listed above)
 | 
				
			||||||
 | 
					    alignment = ALIGNMENT_NEUTRAL  # 1: Town, 2: Werewolf, 3: Neutral
 | 
				
			||||||
    channel_id = ""  # Empty for no private channel
 | 
					    channel_id = ""  # Empty for no private channel
 | 
				
			||||||
    unique = False  # Only one of this role per game
 | 
					    unique = False  # Only one of this role per game
 | 
				
			||||||
    game_start_message = (
 | 
					    game_start_message = (
 | 
				
			||||||
@ -81,7 +83,7 @@ class Shifter(Role):
 | 
				
			|||||||
    async def see_alignment(self, source=None):
 | 
					    async def see_alignment(self, source=None):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Interaction for investigative roles attempting
 | 
					        Interaction for investigative roles attempting
 | 
				
			||||||
        to see alignment (Village, Werewolf, Other)
 | 
					        to see alignment (Village, Werewolf,, Other)
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return "Other"
 | 
					        return "Other"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,6 @@
 | 
				
			|||||||
import logging
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from werewolf.constants import ALIGNMENT_WEREWOLF, CATEGORY_WW_KILLING, CATEGORY_WW_RANDOM
 | 
				
			||||||
from werewolf.listener import wolflistener
 | 
					from werewolf.listener import wolflistener
 | 
				
			||||||
from werewolf.role import Role
 | 
					from werewolf.role import Role
 | 
				
			||||||
from werewolf.votegroups.wolfvote import WolfVote
 | 
					from werewolf.votegroups.wolfvote import WolfVote
 | 
				
			||||||
@ -9,9 +10,10 @@ log = logging.getLogger("red.fox_v3.werewolf.role.vanillawerewolf")
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class VanillaWerewolf(Role):
 | 
					class VanillaWerewolf(Role):
 | 
				
			||||||
    rand_choice = True
 | 
					    rand_choice = True
 | 
				
			||||||
    category = [11, 15]
 | 
					    town_balance = -6
 | 
				
			||||||
    alignment = 2  # 1: Town, 2: Werewolf, 3: Neutral
 | 
					    category = [CATEGORY_WW_RANDOM, CATEGORY_WW_KILLING]
 | 
				
			||||||
    channel_id = "werewolves"
 | 
					    alignment = ALIGNMENT_WEREWOLF  # 1: Town, 2: Werewolf, 3: Neutral
 | 
				
			||||||
 | 
					    channel_name = "werewolves"
 | 
				
			||||||
    unique = False
 | 
					    unique = False
 | 
				
			||||||
    game_start_message = (
 | 
					    game_start_message = (
 | 
				
			||||||
        "Your role is **Werewolf**\n"
 | 
					        "Your role is **Werewolf**\n"
 | 
				
			||||||
@ -40,14 +42,14 @@ class VanillaWerewolf(Role):
 | 
				
			|||||||
        Interaction for investigative roles attempting
 | 
					        Interaction for investigative roles attempting
 | 
				
			||||||
        to see team (Village, Werewolf Other)
 | 
					        to see team (Village, Werewolf Other)
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return "Werewolf"
 | 
					        return ALIGNMENT_WEREWOLF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def get_role(self, source=None):
 | 
					    async def get_role(self, source=None):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Interaction for powerful access of role
 | 
					        Interaction for powerful access of role
 | 
				
			||||||
        Unlikely to be able to deceive this
 | 
					        Unlikely to be able to deceive this
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return "Werewolf"
 | 
					        return "VanillaWerewolf"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def see_role(self, source=None):
 | 
					    async def see_role(self, source=None):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
@ -56,12 +58,12 @@ class VanillaWerewolf(Role):
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        return "Werewolf"
 | 
					        return "Werewolf"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @wolflistener("at_game_start", priority=1)
 | 
					    @wolflistener("at_game_start", priority=2)
 | 
				
			||||||
    async def _at_game_start(self):
 | 
					    async def _at_game_start(self):
 | 
				
			||||||
        if self.channel_id:
 | 
					        if self.channel_name:
 | 
				
			||||||
            log.debug("Wolf has channel_id: " + self.channel_id)
 | 
					            log.debug("Wolf has channel_name: " + self.channel_name)
 | 
				
			||||||
            await self.game.register_channel(
 | 
					            await self.game.register_channel(
 | 
				
			||||||
                self.channel_id, self, WolfVote
 | 
					                self.channel_name, self, WolfVote
 | 
				
			||||||
            )  # Add VoteGroup WolfVote
 | 
					            )  # Add VoteGroup WolfVote
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await self.player.send_dm(self.game_start_message)
 | 
					        await self.player.send_dm(self.game_start_message)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,14 +1,20 @@
 | 
				
			|||||||
import logging
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from werewolf.constants import ALIGNMENT_TOWN, CATEGORY_TOWN_RANDOM
 | 
				
			||||||
from werewolf.role import Role
 | 
					from werewolf.role import Role
 | 
				
			||||||
 | 
					
 | 
				
			||||||
log = logging.getLogger("red.fox_v3.werewolf.role.villager")
 | 
					log = logging.getLogger("red.fox_v3.werewolf.role.villager")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Villager(Role):
 | 
					class Villager(Role):
 | 
				
			||||||
    rand_choice = True  # Determines if it can be picked as a random role (False for unusually disruptive roles)
 | 
					
 | 
				
			||||||
    category = [1]  # List of enrolled categories (listed above)
 | 
					    # Determines if it can be picked as a random role (False for unusually disruptive roles)
 | 
				
			||||||
    alignment = 1  # 1: Town, 2: Werewolf, 3: Neutral
 | 
					    rand_choice = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    town_balance = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    category = [CATEGORY_TOWN_RANDOM]  # List of enrolled categories (listed above)
 | 
				
			||||||
 | 
					    alignment = ALIGNMENT_TOWN  # 1: Town, 2: Werewolf, 3: Neutral
 | 
				
			||||||
    channel_id = ""  # Empty for no private channel
 | 
					    channel_id = ""  # Empty for no private channel
 | 
				
			||||||
    unique = False  # Only one of this role per game
 | 
					    unique = False  # Only one of this role per game
 | 
				
			||||||
    game_start_message = (
 | 
					    game_start_message = (
 | 
				
			||||||
@ -23,9 +29,9 @@ class Villager(Role):
 | 
				
			|||||||
    async def see_alignment(self, source=None):
 | 
					    async def see_alignment(self, source=None):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Interaction for investigative roles attempting
 | 
					        Interaction for investigative roles attempting
 | 
				
			||||||
        to see team (Village, Werewolf Other)
 | 
					        to see team (Village, Werewolf, Other)
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return "Village"
 | 
					        return ALIGNMENT_TOWN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def get_role(self, source=None):
 | 
					    async def get_role(self, source=None):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
				
			|||||||
@ -33,7 +33,7 @@ class Werewolf(Cog):
 | 
				
			|||||||
        default_guild = {
 | 
					        default_guild = {
 | 
				
			||||||
            "role_id": None,
 | 
					            "role_id": None,
 | 
				
			||||||
            "category_id": None,
 | 
					            "category_id": None,
 | 
				
			||||||
            "channel_id": None,
 | 
					            "channel_name": None,
 | 
				
			||||||
            "log_channel_id": None,
 | 
					            "log_channel_id": None,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user