Skip to content

Commit

Permalink
Lots of changes to support new table method.
Browse files Browse the repository at this point in the history
  • Loading branch information
augustjohnson committed Dec 1, 2024
1 parent 7ead314 commit 164a3c3
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 36 deletions.
19 changes: 19 additions & 0 deletions api_v2/migrations/0019_classfeatureitem_column.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 5.1.2 on 2024-12-01 15:06

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api_v2', '0018_characterclass_caster_type'),
]

operations = [
migrations.AddField(
model_name='classfeatureitem',
name='column',
field=models.BooleanField(default=False, help_text='Whether or not the field should be displayed as a column.'),
preserve_default=False,
),
]
22 changes: 22 additions & 0 deletions api_v2/migrations/0020_remove_classfeatureitem_column_and_more.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by Django 5.1.2 on 2024-12-01 15:11

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api_v2', '0019_classfeatureitem_column'),
]

operations = [
migrations.RemoveField(
model_name='classfeatureitem',
name='column',
),
migrations.AddField(
model_name='classfeatureitem',
name='column_value',
field=models.CharField(blank=True, help_text='The value that should be displayed in the table column (where applicable).', max_length=20, null=True),
),
]
71 changes: 38 additions & 33 deletions api_v2/models/characterclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

class ClassFeatureItem(models.Model):
"""This is the class for an individual class feature item, a subset of a class
feature. The name field is unused."""
feature."""

key = key_field()

Expand All @@ -26,6 +26,20 @@ class ClassFeatureItem(models.Model):
parent = models.ForeignKey('ClassFeature', on_delete=models.CASCADE)
level = models.IntegerField(validators=[MinValueValidator(0),MaxValueValidator(20)])

column_value = models.CharField(
# The value displayed in a column, or null if no value.
null=True,
blank=True,
max_length=20,
help_text='The value that should be displayed in the table column (where applicable).'
)

@property
def column(self):
# Represents whether or not this should be displaye as it's own column.
return self.column_value is not None


def __str__(self):
return "{} {} ({})".format(
self.parent.parent.name,
Expand All @@ -39,19 +53,26 @@ class ClassFeature(HasName, HasDescription, FromDocument):

parent = models.ForeignKey('CharacterClass',
on_delete=models.CASCADE)

def featureitem_data(self):
return self.classfeatureitem_set

def column(self):
return len(self.classfeatureitem_set.exclude(column_value=None))>0

def __str__(self):
return "{} ({})".format(self.name,self.parent.name)


class CharacterClass(HasName, FromDocument):
"""The model for a character class or subclass."""

subclass_of = models.ForeignKey('self',
default=None,
blank=True,
null=True,
on_delete=models.CASCADE)

hit_dice = models.CharField(
max_length=100,
default=None,
Expand All @@ -60,11 +81,18 @@ class CharacterClass(HasName, FromDocument):
choices=DIE_TYPES,
help_text='Dice notation hit dice option.')


saving_throws = models.ManyToManyField(Ability,
related_name="characterclass_saving_throws",
help_text='Saving throw proficiencies for this class.')

caster_type = models.CharField(
max_length=100,
default=None,
blank=True,
null=True,
choices=CASTER_TYPES,
help_text='Type of caster. Options are full, half, none.')

@property
@extend_schema_field(inline_serializer(
name="hit_points",
Expand Down Expand Up @@ -95,17 +123,6 @@ def is_subclass(self):
"""Returns whether the object is a subclass."""
return self.subclass_of is not None

caster_type = models.CharField(
max_length=100,
default=None,
blank=True,
null=True,
choices=CASTER_TYPES,
help_text='Type of caster. Options are full, half, none.'
)



@property
def features(self):
"""Returns the set of features that are related to this class."""
Expand All @@ -123,23 +140,9 @@ def features(self):
}
)
))
def levels(self):
"""Returns an array of level information for the given class."""
by_level = {}

for classfeature in self.classfeature_set.all():
for fl in classfeature.classfeatureitem_set.all():
if (str(fl.level)) not in by_level.keys():
by_level[str(fl.level)] = {}
by_level[str(fl.level)]['features'] = []

by_level[str(fl.level)]['features'].append(fl.parent.key)
by_level[str(fl.level)]['proficiency-bonus'] = self.proficiency_bonus(player_level=fl.level)
by_level[str(fl.level)]['level'] = fl.level

return by_level

def get_slots_by_player_level(self,level=1,full=True):


def get_slots_by_player_level(self,level,caster_type):
# full is for a full caster, not including cantrips.
# full=False is for a half caster.
if level<0: # Invalid player level.
Expand Down Expand Up @@ -193,10 +196,12 @@ def get_slots_by_player_level(self,level=1,full=True):
[0,4,3,3,3,2]
]

if full:
if caster_type=='FULL':
return full[level]
else:
if caster_type=='HALF':
return half[level]
else:
return []

def proficiency_bonus(self, player_level):
# Consider as part of enums
Expand Down
11 changes: 8 additions & 3 deletions api_v2/serializers/characterclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,28 @@
from .abstracts import GameContentSerializer
from .document import DocumentSerializer


class ClassFeatureItemSerializer(GameContentSerializer):
class Meta:
model = models.ClassFeatureItem
fields = ['name','desc','type']
fields = ['level','column_value']


class ClassFeatureSerializer(GameContentSerializer):
key = serializers.ReadOnlyField()
column = serializers.ReadOnlyField()
featureitem_data = ClassFeatureItemSerializer(
many=True, context={'request': {}}
)

class Meta:
model = models.ClassFeature
fields = ['key', 'name', 'desc']
fields = ['key', 'name', 'desc','column','featureitem_data']

class CharacterClassSerializer(GameContentSerializer):
key = serializers.ReadOnlyField()
features = ClassFeatureSerializer(
many=True, context={'request': {}})
levels = serializers.ReadOnlyField()
hit_points = serializers.ReadOnlyField()
document = DocumentSerializer()

Expand Down

0 comments on commit 164a3c3

Please sign in to comment.