Skip to content

Commit

Permalink
feat(campaign): set campaign from discord channel category (#157)
Browse files Browse the repository at this point in the history
  • Loading branch information
natelandau authored Jun 18, 2024
1 parent de16c09 commit d9486f6
Show file tree
Hide file tree
Showing 10 changed files with 74 additions and 46 deletions.
5 changes: 3 additions & 2 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# Todo List

- [ ] Campaign: add notes in channel without needing a command
- [ ] Campaign: Delete book channel when book is deleted
- [ ] Campaign: View any campaign, not just active one
- [ ] CharGen: Add backgrounds to freebie point picker
- [ ] CharGen: Add changelings
- [ ] CharGen: Add ghouls
Expand All @@ -14,16 +12,19 @@
- [ ] Gameplay: Button to create macro from rolling traits
- [ ] Refactor: Move testable logic out of cogs and to services or db models
- [ ] Statistics: Pull stats based on timeframe
- [ ] Statistics: Track per book stats
- [ ] Storyteller: Add notes
- [ ] Tests: Increase coverage
- [x] Campaign: Add books to campaigns. Books contain chapters.
- [x] Campaign: Associate characters with campaigns
- [x] Campaign: create channels for each character
- [x] Campaign: Delete book channel when book is deleted
- [x] Campaign: Delete channels when campaign is deleted
- [x] Campaign: If only one campaign, always set it as active
- [x] Campaign: Improve campaign paginator view
- [x] Campaign: Renumber chapters
- [x] Campaign: Rework campaigns to be the backbone of gameplay
- [x] Campaign: View any campaign, not just active one
- [x] Character: assign to other campaign
- [x] Character: rethink inventory
- [x] CharGen: Add edges for hunters
Expand Down
14 changes: 7 additions & 7 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 16 additions & 17 deletions src/valentina/cogs/campaign.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
ValidChapterNumber,
ValidYYYYMMDD,
)
from valentina.utils.discord_utils import book_from_channel
from valentina.utils.discord_utils import book_from_channel, campaign_from_channel
from valentina.utils.helpers import truncate_string
from valentina.views import (
BookModal,
Expand Down Expand Up @@ -193,7 +193,7 @@ async def current_date(
),
) -> None:
"""Set current date of a campaign."""
campaign = await ctx.fetch_active_campaign()
campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()

campaign.date_in_game = date
await campaign.save()
Expand Down Expand Up @@ -242,7 +242,7 @@ async def delete_campaign(
@campaign.command(name="view", description="View a campaign")
async def view_campaign(self, ctx: ValentinaContext) -> None:
"""View a campaign."""
campaign = await ctx.fetch_active_campaign()
campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()

cv = CampaignViewer(ctx, campaign, max_chars=1000)
paginator = await cv.display()
Expand Down Expand Up @@ -374,7 +374,7 @@ async def create_npc(
),
) -> None:
"""Create a new NPC."""
active_campaign = await ctx.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()

modal = NPCModal(title=truncate_string("Create new NPC", 45))
await ctx.send_modal(modal)
Expand Down Expand Up @@ -419,7 +419,7 @@ async def list_npcs(
),
) -> None:
"""List all NPCs."""
active_campaign = await ctx.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()

if len(active_campaign.npcs) == 0:
await present_embed(
Expand Down Expand Up @@ -465,7 +465,7 @@ async def edit_npc(
if not await self.check_permissions(ctx):
return

active_campaign = await ctx.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()
try:
npc = active_campaign.npcs[index]
except IndexError:
Expand Down Expand Up @@ -528,7 +528,7 @@ async def delete_npc(
if not await self.check_permissions(ctx):
return

active_campaign = await ctx.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()
try:
npc = active_campaign.npcs[index]
except IndexError:
Expand Down Expand Up @@ -570,7 +570,7 @@ async def create_book(
if not await self.check_permissions(ctx):
return

active_campaign = await ctx.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()

modal = BookModal(title=truncate_string("Create new book", 45))
await ctx.send_modal(modal)
Expand Down Expand Up @@ -619,7 +619,7 @@ async def list_books(
),
) -> None:
"""List all books."""
active_campaign = await ctx.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()
all_books = await active_campaign.fetch_books()

if len(all_books) == 0:
Expand Down Expand Up @@ -669,7 +669,7 @@ async def edit_book(
if not await self.check_permissions(ctx):
return

active_campaign = await ctx.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()
original_name = book.name

modal = BookModal(title=truncate_string(f"Edit book {book.name}", 45), book=book)
Expand Down Expand Up @@ -721,7 +721,7 @@ async def delete_book(
if not await self.check_permissions(ctx):
return

active_campaign = await ctx.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()

title = f"Delete book `{book.number}. {book.name}` from `{active_campaign.name}`"
is_confirmed, interaction, confirmation_embed = await confirm_action(
Expand Down Expand Up @@ -774,7 +774,7 @@ async def renumber_books(
)
return

active_campaign = await ctx.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()
original_number = book.number

title = (
Expand Down Expand Up @@ -1120,7 +1120,7 @@ async def create_note(
),
) -> None:
"""Create a new note."""
active_campaign = await ctx.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()

modal = NoteModal(title=truncate_string("Create new note", 45))
await ctx.send_modal(modal)
Expand Down Expand Up @@ -1161,8 +1161,7 @@ async def list_notes(
),
) -> None:
"""List all notes."""
guild = await Guild.get(ctx.guild.id, fetch_links=True)
active_campaign = await guild.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()

if len(active_campaign.notes) == 0:
await present_embed(
Expand Down Expand Up @@ -1204,7 +1203,7 @@ async def edit_note(
),
) -> None:
"""Edit a note."""
active_campaign = await ctx.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()
note = active_campaign.notes[index]

modal = NoteModal(title=truncate_string("Edit note", 45), note=note)
Expand Down Expand Up @@ -1253,7 +1252,7 @@ async def delete_note(
if not await self.check_permissions(ctx):
return

active_campaign = await ctx.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()
note = active_campaign.notes[index]

title = f"Delete note: `{note.name}` from `{active_campaign.name}`"
Expand Down
7 changes: 4 additions & 3 deletions src/valentina/cogs/experience.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
ValidCharacterObject,
ValidCharTrait,
)
from valentina.utils.discord_utils import campaign_from_channel
from valentina.utils.helpers import get_trait_multiplier, get_trait_new_value
from valentina.views import confirm_action, present_embed

Expand Down Expand Up @@ -61,7 +62,7 @@ async def xp_add(
)
return

active_campaign = await ctx.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()

title = f"Add `{amount}` xp to `{user.name}`"
description = "View experience with `/user_info`"
Expand Down Expand Up @@ -110,7 +111,7 @@ async def cp_add(
)
return

active_campaign = await ctx.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()

title = f"Add `{amount}` cool {p.plural_noun('point', amount)} to `{user.name}`"
description = "View cool points with `/user_info`"
Expand Down Expand Up @@ -189,7 +190,7 @@ async def xp_spend(

# Make the updates
user = await User.get(ctx.author.id)
active_campaign = await ctx.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()

await user.spend_campaign_xp(active_campaign, upgrade_cost)
trait.value = new_trait_value
Expand Down
8 changes: 4 additions & 4 deletions src/valentina/cogs/gameplay.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
select_macro,
)
from valentina.utils.converters import ValidTraitFromID
from valentina.utils.discord_utils import character_from_channel
from valentina.utils.discord_utils import campaign_from_channel, character_from_channel
from valentina.utils.perform_roll import perform_roll
from valentina.views import present_embed

Expand Down Expand Up @@ -65,7 +65,7 @@ async def throw(
character = await character_from_channel(ctx) or await ctx.fetch_active_character()

if desperation > 0:
active_campaign = await ctx.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()
if active_campaign.desperation == 0 or desperation > 5: # noqa: PLR2004
await present_embed(
ctx,
Expand Down Expand Up @@ -130,7 +130,7 @@ async def traits(
)

if desperation > 0:
active_campaign = await ctx.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()
if active_campaign.desperation == 0 or desperation > 5: # noqa: PLR2004
await present_embed(
ctx,
Expand Down Expand Up @@ -210,7 +210,7 @@ async def roll_macro(
raise commands.BadArgument(msg)

if desperation > 0:
active_campaign = await ctx.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()
if active_campaign.desperation == 0 or desperation > 5: # noqa: PLR2004
await present_embed(
ctx,
Expand Down
5 changes: 3 additions & 2 deletions src/valentina/cogs/storyteller.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
ValidImageURL,
ValidTraitCategory,
)
from valentina.utils.discord_utils import campaign_from_channel
from valentina.utils.helpers import (
fetch_data_from_url,
)
Expand Down Expand Up @@ -92,7 +93,7 @@ def __init__(self, bot: Valentina) -> None:
@storyteller.command(name="set_danger", description="Set the danger level")
async def set_danger(self, ctx: ValentinaContext, danger: int) -> None:
"""Set the danger level for a campaign."""
campaign = await ctx.fetch_active_campaign()
campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()

title = f"Set danger level to {danger}"
is_confirmed, interaction, confirmation_embed = await confirm_action(ctx, title, audit=True)
Expand All @@ -108,7 +109,7 @@ async def set_danger(self, ctx: ValentinaContext, danger: int) -> None:
@storyteller.command(name="set_desperation", description="Set the desperation level")
async def set_desperation(self, ctx: ValentinaContext, desperation: int) -> None:
"""Set the desperation level for a campaign."""
campaign = await ctx.fetch_active_campaign()
campaign = await campaign_from_channel(ctx) or await ctx.fetch_active_campaign()

title = f"Set desperation level to {desperation}"
is_confirmed, interaction, confirmation_embed = await confirm_action(ctx, title, audit=True)
Expand Down
16 changes: 10 additions & 6 deletions src/valentina/utils/autocomplete.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
)
from valentina.models import AWSService, Campaign, ChangelogParser, Character, Guild, User
from valentina.models.bot import Valentina
from valentina.utils.discord_utils import book_from_channel, character_from_channel
from valentina.utils.discord_utils import (
book_from_channel,
campaign_from_channel,
character_from_channel,
)
from valentina.utils.helpers import truncate_string

MAX_OPTION_LENGTH = 99
Expand Down Expand Up @@ -117,7 +121,7 @@ async def select_book(ctx: discord.AutocompleteContext) -> list[OptionChoice]:
"""
# Fetch the active campaign
guild = await Guild.get(ctx.interaction.guild.id, fetch_links=True)
active_campaign = await guild.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await guild.fetch_active_campaign()
books = await active_campaign.fetch_books()

if not active_campaign:
Expand Down Expand Up @@ -214,7 +218,7 @@ async def select_chapter_old(
"""
# Fetch the active campaign
guild = await Guild.get(ctx.interaction.guild.id, fetch_links=True)
active_campaign = await guild.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await guild.fetch_active_campaign()

if not active_campaign:
return [OptionChoice("No active campaign", 1000)]
Expand Down Expand Up @@ -508,7 +512,7 @@ async def select_desperation_dice(

# Fetch the active campaign
guild = await Guild.get(ctx.interaction.guild.id, fetch_links=True)
active_campaign = await guild.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await guild.fetch_active_campaign()
desperation_dice = active_campaign.desperation

if not active_campaign:
Expand Down Expand Up @@ -568,7 +572,7 @@ async def select_note(ctx: discord.AutocompleteContext) -> list[OptionChoice]:
"""
# Fetch the active campaign
guild = await Guild.get(ctx.interaction.guild.id, fetch_links=True)
active_campaign = await guild.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await guild.fetch_active_campaign()

if not active_campaign:
return [OptionChoice("No active campaign", 1000)]
Expand Down Expand Up @@ -596,7 +600,7 @@ async def select_npc(ctx: discord.AutocompleteContext) -> list[OptionChoice]:
"""
# Fetch the active campaign
guild = await Guild.get(ctx.interaction.guild.id, fetch_links=True)
active_campaign = await guild.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await guild.fetch_active_campaign()

if not active_campaign:
return [OptionChoice("No active campaign", 1000)]
Expand Down
6 changes: 3 additions & 3 deletions src/valentina/utils/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
Guild,
InventoryItem,
)
from valentina.utils.discord_utils import book_from_channel
from valentina.utils.discord_utils import book_from_channel, campaign_from_channel


class CampaignChapterConverter(Converter):
Expand All @@ -37,7 +37,7 @@ class CampaignChapterConverter(Converter):
async def convert(self, ctx: commands.Context, argument: str) -> CampaignChapter:
"""Validate and normalize traits."""
guild = await Guild.get(ctx.guild.id, fetch_links=True)
active_campaign = await guild.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await guild.fetch_active_campaign()

try:
chapter_number = int(argument)
Expand Down Expand Up @@ -100,7 +100,7 @@ class ValidBookNumber(Converter):
async def convert(self, ctx: commands.Context, argument: str) -> int:
"""Validate and normalize book numbers."""
guild = await Guild.get(ctx.guild.id, fetch_links=True)
active_campaign = await guild.fetch_active_campaign()
active_campaign = await campaign_from_channel(ctx) or await guild.fetch_active_campaign()
campaign_book_numbers = [x.number for x in await active_campaign.fetch_books()]

try:
Expand Down
Loading

0 comments on commit d9486f6

Please sign in to comment.