Skip to content

Commit

Permalink
feat(character): add concept to character profile (#59)
Browse files Browse the repository at this point in the history
  • Loading branch information
natelandau authored Sep 26, 2023
1 parent 26d811c commit af9e291
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 67 deletions.
14 changes: 5 additions & 9 deletions src/valentina/cogs/characters.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@
from discord.ext import commands
from loguru import logger

from valentina.constants import (
VALID_IMAGE_EXTENSIONS,
EmbedColor,
Emoji,
)
from valentina.constants import VALID_IMAGE_EXTENSIONS, EmbedColor, Emoji
from valentina.models.bot import Valentina
from valentina.utils import errors
from valentina.utils.converters import (
Expand Down Expand Up @@ -249,8 +245,8 @@ async def list_characters(
text += f"**{character.name}**\n"
text += "```\n"
text += f"Class: {character.char_class.name:<20} Created On: {character.created.split(' ')[0]}\n"
text += f"Owner: {character.owned_by.data['display_name']:<20} Lifetime XP: {character.data['experience']}\n"
text += f"Alive: {alive:<20} Active: {character.is_active}\n"
text += f"Alive: {alive:<20} Active: {character.is_active}\n"
text += f"Owner: {character.owned_by.data['display_name']:<20}\n"
text += "```\n"

embed = discord.Embed(description=text, color=EmbedColor.INFO.value)
Expand Down Expand Up @@ -317,8 +313,8 @@ async def kill_character(
if not is_confirmed:
return

updates: dict[str, str | int | bool] = {"is_active": False, "is_alive": False}
await self.bot.char_svc.update_or_add(ctx, character=character, data=updates)
character.kill()
self.bot.user_svc.purge_cache(ctx)

await self.bot.guild_svc.send_to_audit_log(ctx, title)
await confirmation_response_msg
Expand Down
6 changes: 4 additions & 2 deletions src/valentina/cogs/developer.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ async def create_test_characters(
number: Option(
int, description="The number of characters to create (default 1)", default=1
),
char_class: Option(
character_class: Option(
ValidCharacterClass,
name="char_class",
description="The character's class",
Expand All @@ -173,8 +173,10 @@ async def create_test_characters(

for _ in range(number):
# Assign a random class unless specified
if char_class is None:
if character_class is None:
char_class = CharacterClass.select().order_by(fn.Random()).limit(1).get()
else:
char_class = character_class

# Assign a random vampire clan
if char_class.name.lower() == "vampire":
Expand Down
10 changes: 0 additions & 10 deletions src/valentina/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,26 +262,16 @@ class XPMultiplier(Enum):
### Database Data Default Values ###
CHARACTER_DEFAULTS: dict[str, int | bool | None | str | list] = {
"is_alive": True,
"auspice": None,
"bio": None,
"breed": None,
"concept": None,
"date_of_birth": None,
"debug_character": False,
"demeanor": None,
"developer_character": False,
"essence": None,
"first_name": None,
"generation": None,
"is_active": False,
"last_name": None,
"nature": None,
"nickname": None,
"player_character": False,
"sire": None,
"storyteller_character": False,
"tradition": None,
"tribe": None,
"images": [],
}

Expand Down
6 changes: 6 additions & 0 deletions src/valentina/models/db_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,12 @@ def is_alive(self) -> bool:
"""Return True if the character is alive."""
return self.data.get("is_alive", True)

def kill(self) -> None:
"""Set the character as dead."""
self.data["is_alive"] = False
self.data["is_active"] = False
self.save()

def set_trait_value(self, trait: Trait | CustomTrait, value: int) -> None:
"""Set the character's value of a trait."""
if isinstance(trait, CustomTrait):
Expand Down
36 changes: 9 additions & 27 deletions src/valentina/views/character_sheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,30 +86,21 @@ def __embed1(
)

embed.add_field(name="Class", value=f"{character.class_name.title()}", inline=True)
embed.add_field(
name="Demeanor",
value=character.data["demeanor"] if character.data.get("demeanor") else "",
inline=True,
)
embed.add_field(
name="Nature",
value=character.data["nature"] if character.data.get("nature") else "",
inline=True,
)
embed.add_field(name="Concept", value=character.data.get("concept", ""), inline=True)

if character.class_name.lower() == "vampire":
embed.add_field(name="Clan", value=f"{character.clan.name}", inline=True)
embed.add_field(name="Generation", value=f"{character.data['generation']}", inline=True)
embed.add_field(name="Sire", value=f"{character.data['sire']}", inline=True)
embed.add_field(name="Clan", value=character.clan.name, inline=True)
embed.add_field(name="Generation", value=character.data.get("generation", ""), inline=True)
embed.add_field(name="Sire", value=character.data.get("sire", ""), inline=True)

if character.class_name.lower() == "mage":
embed.add_field(name="Tradition", value=f"{character.data['tradition']}", inline=True)
embed.add_field(name="Essence", value=f"{character.data['essence']}", inline=True)
embed.add_field(name="Tradition", value=character.data.get("tradition", ""), inline=True)
embed.add_field(name="Essence", value=character.data.get("essence", ""), inline=True)

if character.class_name.lower() == "werewolf":
embed.add_field(name="Tribe", value=f"{character.data['tribe']}", inline=True)
embed.add_field(name="Auspice", value=f"{character.data['auspice']}", inline=True)
embed.add_field(name="Breed", value=f"{character.data['breed']}", inline=True)
embed.add_field(name="Tribe", value=character.data.get("tribe", ""), inline=True)
embed.add_field(name="Auspice", value=character.data.get("auspice", ""), inline=True)
embed.add_field(name="Breed", value=character.data.get("breed", ""), inline=True)

embed.add_field(name="\u200b", value="**ATTRIBUTES**", inline=False)
for category, traits in __build_trait_display(char_traits, ["physical", "social", "mental"]):
Expand Down Expand Up @@ -161,15 +152,6 @@ def __embed2(
if character.data.get("bio"):
embed.add_field(name="**BIOGRAPHY**", value=character.data["bio"], inline=False)

embed.add_field(name="\u200b", value="**EXPERIENCE**", inline=False)
embed.add_field(name="Experience", value=f"`{character.data['experience']}`", inline=True)
embed.add_field(
name="Lifetime Experience", value=f"`{character.data['experience_total']}`", inline=True
)
embed.add_field(
name="Lifetime Cool Points", value=f"`{character.data['cool_points_total']}`", inline=True
)

if len(custom_sections) > 0:
embed.add_field(name="\u200b", value="**CUSTOM SECTIONS**", inline=False)
for section in custom_sections:
Expand Down
19 changes: 5 additions & 14 deletions src/valentina/views/modals.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ def __init__(self, character: Character, *args, **kwargs) -> None: # type: igno
self.confirmed: bool = False
self.character: Character = character
self.results: dict[str, str] = {
"concept": "",
"demeanor": "",
"nature": "",
"generation": "",
Expand All @@ -375,22 +376,12 @@ def __init__(self, character: Character, *args, **kwargs) -> None: # type: igno

self.add_item(
InputText(
label="demeanor",
value=self.character.data.get("demeanor", None),
placeholder="Enter a demeanor",
label="concept",
value=self.character.data.get("concept", None),
placeholder="Enter a concept",
required=False,
style=discord.InputTextStyle.short,
custom_id="demeanor",
)
)
self.add_item(
InputText(
label="nature",
value=self.character.data.get("nature", None),
placeholder="Enter a nature",
required=False,
style=discord.InputTextStyle.short,
custom_id="nature",
custom_id="concept",
)
)

Expand Down
34 changes: 34 additions & 0 deletions tests/test_characters.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@
class TestCharacterModel:
"""Test the character database model."""

def _clear_test_data(self) -> None:
"""Clear all test data from the database."""
for character in Character.select():
if character.id == 1:
continue
character.delete_instance(recursive=True, delete_nullable=True)

def test_character_add_custom_trait(self) -> None:
"""Test the add_custom_trait method.
Expand Down Expand Up @@ -251,6 +258,33 @@ def test_update_existing_trait_value(self, mock_ctx):
== 1
)

def test_kill_character(self):
"""Test character.kill()."""
self._clear_test_data()

# GIVEN a character
character = Character.create(
data={
"first_name": str(uuid4()).split("-")[0],
"last_name": "character",
"storyteller_character": True,
"is_alive": True,
"is_active": True,
},
char_class=1,
guild=1,
created_by=1,
owner_by=1,
clan=1,
)

# WHEN the kill method is called
character.kill()

# THEN check the character is killed correctly
assert not character.is_alive
assert not character.is_active

def test_character_traits_dict(self):
"""Test character.traits_dict.
Expand Down
6 changes: 1 addition & 5 deletions tests/test_user_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,10 +413,6 @@ def test_has_update_trait_permissions(
# THEN return the correct result
assert result is expected

# UNRESTRICTED = 0
# PLAYER_ONLY = 1 # Default
# STORYTELLER_ONLY = 2

@pytest.mark.asyncio()
@pytest.mark.parametrize(
("xp_permissions_value", "is_admin", "is_storyteller", "target_self", "expected"),
Expand Down Expand Up @@ -476,7 +472,7 @@ async def test_can_update_xp(
local_mock_ctx.bot = mock_bot

# CREATE DATABASE OBJECTS
calling_user = GuildUser.create(guild=mock_guild1.id, user=mock_author.id)
GuildUser.create(guild=mock_guild1.id, user=mock_author.id)
target_user = None if target_self else GuildUser.create(guild=mock_guild1.id, user=200)

# WHEN checking edit xp permissions
Expand Down

0 comments on commit af9e291

Please sign in to comment.