Skip to content

Commit c35b026

Browse files
AmbratolmAmbratolm
authored andcommitted
Improved Help Cog: div into about/cmds & isol table cmds
1 parent 9574554 commit c35b026

File tree

5 files changed

+225
-122
lines changed

5 files changed

+225
-122
lines changed

bot/cogs/game_cogs/combat_cog.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def __init__(self, bot: ActBot):
2121
self.bot = bot
2222

2323
@app_commands.guild_only()
24-
@app_commands.command(description="Attack a member")
24+
@app_commands.command(description="Engage in battle with another member")
2525
async def attack(self, interaction: Interaction, member: Member):
2626
# Check guild & member
2727
if not interaction.guild or not isinstance(interaction.user, Member):

bot/cogs/game_cogs/profile_cog.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
from enum import Enum
21
from typing import Callable
32

4-
from discord import Color, Embed, Guild, Interaction, Member, User, app_commands
5-
from discord.ext.commands import Cog, GroupCog
6-
from humanize import intcomma, naturalsize, naturaltime
7-
from odmantic import query
3+
from discord import Embed, Interaction, Member, User, app_commands
4+
from discord.ext.commands import GroupCog
5+
from humanize import intcomma, naturaltime
86

97
from bot.main import ActBot
108
from bot.ui import EmbedX

bot/cogs/game_cogs/table_cog.py

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
from discord import Embed, Interaction, app_commands
2+
from discord.ext.commands import GroupCog
3+
from humanize import intcomma
4+
from tabulate import tabulate
5+
6+
from bot.main import ActBot
7+
from bot.ui import EmbedX
8+
from db.actor import Actor
9+
from db.item import Item
10+
from db.main import ActToml
11+
from utils.misc import numsign
12+
13+
14+
# ----------------------------------------------------------------------------------------------------
15+
# * Table Cog
16+
# ----------------------------------------------------------------------------------------------------
17+
class TableCog(
18+
GroupCog,
19+
group_name="table",
20+
description="Show data tables",
21+
):
22+
def __init__(self, bot: ActBot):
23+
self.bot = bot
24+
25+
@app_commands.guild_only()
26+
@app_commands.command(description="View table of items")
27+
async def items(
28+
self,
29+
interaction: Interaction,
30+
):
31+
await interaction.response.defer()
32+
33+
def format_stat_name(name: str):
34+
if "max_" in name:
35+
name = name.replace("max_", "")
36+
return f"M{name[0].upper()}"
37+
return name[0].upper()
38+
39+
output = tabulate(
40+
[
41+
(
42+
item.name,
43+
" ".join(
44+
f"{numsign(intcomma(value))}{format_stat_name(name)}"
45+
for name, value in item.effective_stats().items()
46+
),
47+
item.price,
48+
)
49+
for item in ActToml.load_dict(Item).values()
50+
],
51+
headers=["Item", "Stats", "Price"],
52+
colalign=["right", "left", "left"],
53+
tablefmt="simple_outline",
54+
)
55+
await interaction.followup.send(
56+
embed=self.table_embed(emoji="📦", title="Items", desc=output)
57+
)
58+
59+
@app_commands.guild_only()
60+
@app_commands.command(description="View table of levels")
61+
async def levels(
62+
self,
63+
interaction: Interaction,
64+
min: int = 0,
65+
max: int = 10,
66+
):
67+
await interaction.response.defer()
68+
await interaction.followup.send(
69+
embed=self.table_embed(
70+
emoji="🏅",
71+
title="Levels",
72+
desc=tabulate(
73+
Actor.level_xp_gold_table(min, max),
74+
headers=["Level", "Experience", "Gold"],
75+
colalign=["right", "left", "left"],
76+
tablefmt="simple_outline",
77+
),
78+
)
79+
)
80+
81+
@app_commands.guild_only()
82+
@app_commands.command(description="View table of ranks")
83+
async def ranks(
84+
self,
85+
interaction: Interaction,
86+
min: int = 0,
87+
max: int = 10,
88+
):
89+
await interaction.response.defer()
90+
await interaction.followup.send(
91+
embed=self.table_embed(
92+
emoji="🏆",
93+
title="Ranks",
94+
desc=tabulate(
95+
[(rank.name, elo) for rank, elo in Actor.rank_elo_table(min, max)],
96+
headers=["Rank", "Elo"],
97+
colalign=["right", "left"],
98+
tablefmt="simple_outline",
99+
),
100+
)
101+
)
102+
103+
@app_commands.guild_only()
104+
@app_commands.command(description="View table of roles")
105+
async def roles(
106+
self,
107+
interaction: Interaction,
108+
min: int = 0,
109+
max: int = 10,
110+
):
111+
await interaction.response.defer()
112+
output = "_No roles found in this server._"
113+
guild = interaction.guild
114+
roles = (
115+
sorted(guild.roles, key=lambda role: role.position, reverse=True)
116+
if guild
117+
else []
118+
)
119+
if roles:
120+
output_list = []
121+
for role in roles:
122+
output_list.append((role.name, len(role.members)))
123+
output = tabulate(
124+
output_list,
125+
headers=["Role", "Members"],
126+
colalign=["right", "left"],
127+
tablefmt="simple_outline",
128+
)
129+
await interaction.followup.send(
130+
embed=self.table_embed(emoji="🎭", title="Roles", desc=output)
131+
)
132+
133+
# ----------------------------------------------------------------------------------------------------
134+
135+
def table_embed(self, emoji: str, title: str, desc: str) -> Embed:
136+
return EmbedX.info(emoji=emoji, title=title, description=f"```{desc}```")

bot/cogs/help_cog.py

Lines changed: 73 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -1,136 +1,95 @@
1-
from discord import Color, Embed, Interaction, Member, app_commands
2-
from discord.ext.commands import Cog
3-
from humanize import intcomma
4-
from tabulate import tabulate
1+
from collections import defaultdict
2+
3+
from discord import Interaction, Member, app_commands
4+
from discord.ext.commands import GroupCog
55

66
from bot.main import ActBot
77
from bot.ui import EmbedX
8-
from db.actor import Actor
9-
from db.item import Item
10-
from db.main import ActToml
11-
from utils.misc import numsign
128

139

1410
# ----------------------------------------------------------------------------------------------------
1511
# * Help Cog
1612
# ----------------------------------------------------------------------------------------------------
17-
class HelpCog(Cog, description="Provide help and information interface."):
13+
class HelpCog(
14+
GroupCog, group_name="help", description="Provide help and information interface."
15+
):
1816
def __init__(self, bot: ActBot):
1917
self.bot = bot
2018

2119
# ----------------------------------------------------------------------------------------------------
22-
# * Commands
23-
# ----------------------------------------------------------------------------------------------------
24-
@app_commands.command(description="View all commands")
25-
async def help(self, interaction: Interaction):
26-
all_cmds = self.bot.tree.get_commands()
27-
embed = Embed(
28-
title=f"🤖 {self.bot.title} v{self.bot.version}",
29-
description=(f"{self.bot.description}\n\n"),
30-
color=Color.blue(),
20+
21+
@app_commands.command(description="Learn about the bot")
22+
async def about(self, interaction: Interaction):
23+
embed = EmbedX.info(
24+
emoji="🤖",
25+
title=f"{self.bot.title} v{self.bot.version}",
26+
description=self.bot.description,
3127
)
32-
for cmd in all_cmds:
33-
# Check if command has administrator requirement in default_permissions
34-
admin_required = False
35-
if hasattr(cmd, "default_permissions") and cmd.default_permissions:
36-
admin_required = cmd.default_permissions.administrator
37-
if not admin_required or (
38-
isinstance(interaction.user, Member)
39-
and interaction.user.guild_permissions.administrator
40-
):
41-
embed.add_field(
42-
name=f"/{cmd.name}",
43-
value=(
44-
cmd.description
45-
if not isinstance(cmd, app_commands.commands.ContextMenu)
46-
else ""
47-
),
48-
inline=False,
49-
)
5028
if self.bot.user:
5129
embed.set_thumbnail(url=self.bot.user.display_avatar)
52-
await interaction.response.send_message(embed=embed, ephemeral=True)
30+
await interaction.response.send_message(
31+
embed=embed,
32+
ephemeral=True,
33+
)
5334

54-
# ----------------------------------------------------------------------------------------------------
55-
# * Table
56-
# ----------------------------------------------------------------------------------------------------
57-
@app_commands.guild_only
58-
@app_commands.command(description="View table of data")
59-
@app_commands.choices(
60-
data=[
61-
app_commands.Choice(name="📦 Items", value="items"),
62-
app_commands.Choice(name="🏅 Levels", value="levels"),
63-
app_commands.Choice(name="🏆 Ranks", value="ranks"),
64-
app_commands.Choice(name="🎭 Roles", value="roles"),
65-
]
35+
@app_commands.command(
36+
description="View a comprehensive list of all available commands"
6637
)
67-
async def table(
68-
self,
69-
interaction: Interaction,
70-
data: app_commands.Choice[str],
71-
min: int = 0,
72-
max: int = 10,
73-
):
74-
await interaction.response.defer()
75-
output = " "
76-
match data.value:
77-
case "items":
38+
async def commands(self, interaction: Interaction):
39+
# Initialize embed
40+
embed = EmbedX.info(emoji="🔷", title=f"Commands")
7841

79-
def format_stat_name(name: str):
80-
if "max_" in name:
81-
name = name.replace("max_", "")
82-
return f"M{name[0].upper()}"
83-
return name[0].upper()
42+
# Group commands by category/module
43+
command_groups: dict[str, list[app_commands.Command]] = defaultdict(list)
44+
for cmd in self.bot.tree.get_commands():
45+
# Extract category (you might want to customize this based on your bot's structure)
46+
category = getattr(cmd, "category", "Root")
47+
if isinstance(cmd, app_commands.Group):
48+
category = f"📂 {cmd.name.capitalize()}"
49+
command_groups[category].append(cmd)
8450

85-
output = tabulate(
86-
[
87-
(
88-
item.name,
89-
" ".join(
90-
f"{numsign(intcomma(value))}{format_stat_name(name)}"
91-
for name, value in item.effective_stats().items()
92-
),
93-
item.price,
94-
)
95-
for item in ActToml.load_dict(Item).values()
96-
],
97-
headers=["Item", "Stats", "Price"],
98-
colalign=["right", "left", "left"],
99-
tablefmt="simple_outline",
100-
)
101-
case "levels":
102-
output = tabulate(
103-
Actor.level_xp_gold_table(min, max),
104-
headers=["Level", "Experience", "Gold"],
105-
colalign=["right", "left", "left"],
106-
tablefmt="simple_outline",
107-
)
108-
case "ranks":
109-
output = tabulate(
110-
[(rank.name, elo) for rank, elo in Actor.rank_elo_table(min, max)],
111-
headers=["Rank", "Elo"],
112-
colalign=["right", "left"],
113-
tablefmt="simple_outline",
114-
)
115-
case "roles":
116-
guild = interaction.guild
117-
roles = (
118-
sorted(guild.roles, key=lambda role: role.position, reverse=True)
119-
if guild
120-
else []
51+
# Check if user is admin for permission filtering
52+
is_admin = (
53+
isinstance(interaction.user, Member)
54+
and interaction.user.guild_permissions.administrator
55+
)
56+
57+
# Build command list for each category
58+
for category, commands in sorted(command_groups.items()):
59+
command_lines = []
60+
for cmd in sorted(commands, key=lambda x: x.name):
61+
# Skip admin commands for non-admins
62+
admin_required = (
63+
getattr(cmd, "default_permissions", None)
64+
and cmd.default_permissions.administrator
12165
)
122-
if roles:
123-
output_list = []
124-
for role in roles:
125-
output_list.append((role.name, len(role.members)))
126-
output = tabulate(
127-
output_list,
128-
headers=["Role", "Members"],
129-
colalign=["right", "left"],
130-
tablefmt="simple_outline",
66+
if admin_required and not is_admin:
67+
continue
68+
69+
# Format command description
70+
cmd_line = ""
71+
if isinstance(cmd, app_commands.Group): # Handle command groups
72+
cmd_line = "\n".join(
73+
[
74+
f"- `/{cmd.name} {subcmd.name}`: {subcmd.description}"
75+
for subcmd in cmd.commands
76+
]
13177
)
13278
else:
133-
output = "_No roles found in this server._"
134-
await interaction.followup.send(
135-
embed=EmbedX.info(emoji="", title=data.name, description=f"```{output}```")
136-
)
79+
cmd_line = f"- `/{cmd.name}`: {(
80+
cmd.description
81+
if not isinstance(cmd, app_commands.ContextMenu)
82+
else "Context Menu"
83+
)}"
84+
85+
command_lines.append(cmd_line)
86+
87+
if command_lines: # Only add field if there are visible commands
88+
embed.add_field(
89+
name=category, value="\n".join(command_lines), inline=False
90+
)
91+
92+
# Send
93+
if self.bot.user:
94+
embed.set_thumbnail(url=self.bot.user.display_avatar)
95+
await interaction.response.send_message(embed=embed, ephemeral=True)

pyproject.toml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
[project]
22
name = "ACT"
3-
version = "0.0.1"
4-
description = "Assistant of Comon Tech"
3+
version = "0.1"
4+
description = """
5+
**A**ssistant of **C**omon **T**ech.
6+
Your AI Companion for Social Chat & RPG Adventures.
7+
📧 Support Server: [Discord.gg/fpqMWc2zbr](https://discord.gg/fpqMWc2zbr)
8+
📜 Source Code: [Github.com/Comon-tech/ACT](https://github.com/Comon-tech/ACT)
9+
10+
© **Comon** 2025
11+
📩 Server: [Discord.gg/eqSU46Y7xW](https://discord.gg/eqSU46Y7xW)
12+
🌐 Website: [Comon.tech](https://www.comon.tech)
13+
📜 Github: [Github.com/Comon-tech](https://github.com/Comon-tech)
14+
"""
515
readme = "README.md"
616
requires-python = ">=3.13"
717
dependencies = [

0 commit comments

Comments
 (0)