Skip to content

Commit

Permalink
Merge pull request #500 from open5e/499-v2-challenge-rating-missing-f…
Browse files Browse the repository at this point in the history
…rom-creatures

499 v2 challenge rating missing from creatures
  • Loading branch information
augustjohnson authored Aug 4, 2024
2 parents 514d2ee + c737fb0 commit 2b29152
Show file tree
Hide file tree
Showing 13 changed files with 5,811 additions and 2 deletions.
25 changes: 25 additions & 0 deletions api_v2/migrations/0110_auto_20240804_1331.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 3.2.20 on 2024-08-04 13:31

import django.core.validators
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api_v2', '0109_alter_creature_passive_perception'),
]

operations = [
migrations.AddField(
model_name='creature',
name='challenge_rating_decimal',
field=models.DecimalField(decimal_places=3, default=0, help_text='Challenge Rating field as a decimal number.', max_digits=10, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(30)]),
preserve_default=False,
),
migrations.AddField(
model_name='creature',
name='experience_points_integer',
field=models.IntegerField(help_text='Optional override for calculated XP based on CR.', null=True, validators=[django.core.validators.MinValueValidator(0)]),
),
]
68 changes: 68 additions & 0 deletions api_v2/models/creature.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""The model for a creature."""
from fractions import Fraction

from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator
Expand Down Expand Up @@ -57,6 +58,21 @@ class Creature(Object, Abilities, Senses, HasLanguage, HasSpeed, FromDocument):
help_text="Conditions that this creature is immune to."
)

challenge_rating_decimal = models.DecimalField(
null=False,
max_digits=10,
decimal_places=3,
validators=[MinValueValidator(0),MaxValueValidator(30)],
help_text="Challenge Rating field as a decimal number."
)

experience_points_integer = models.IntegerField(
null=True,
blank=True,
validators=[MinValueValidator(0)],
help_text="Optional override for calculated XP based on CR."
)

def as_text(self):
text = self.name + '\n'
for action in self.creatureaction_set.all():
Expand All @@ -76,6 +92,58 @@ def creatureset(self):
'''Helper method to rename and return creaturesets.'''
return self.creaturesets.all()

@property
def challenge_rating_text(self):
'''Challenge rating as text string representation of a fraction or integer. '''
return str(Fraction(self.challenge_rating_decimal))

@property
def experience_points(self):
if self.experience_points_integer is not None:
return self.experience_points_integer
else:
xp_by_cr_lookup = {
"0":0,
"1/8":25,
"1/4":50,
"1/2":100,
"1":200,
"2":450,
"3":700,
"4":1100,
"5":1800,
"6":2300,
"7":2900,
"8":3900,
"9":5000,
"10":5900,
"11":7200,
"12":8400,
"13":10000,
"14":11500,
"15":13000,
"16":15000,
"17":18000,
"18":20000,
"19":22000,
"20":25000,
"21":33000,
"22":41000,
"23":50000,
"24":62000,
"25":75000,
"26":90000,
"27":105000,
"28":120000,
"29":135000,
"30":155000,
}

try:
return xp_by_cr_lookup[str(Fraction(self.challenge_rating_decimal))]
except:
return None


class CreatureAction(HasName, HasDescription):
"""Describes an action available to a creature."""
Expand Down
12 changes: 11 additions & 1 deletion api_v2/serializers/creature.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ class CreatureSerializer(GameContentSerializer):
size = SizeSerializer(read_only=True, context={'request': {}})
speed = serializers.SerializerMethodField()
all_speed = serializers.SerializerMethodField()
challenge_rating_text = serializers.SerializerMethodField()
experience_points = serializers.SerializerMethodField()


class Meta:
'''Serializer meta options.'''
Expand All @@ -130,6 +133,9 @@ class Meta:
'armor_class',
'hit_points',
'hit_dice',
'challenge_rating_decimal',
'challenge_rating_text',
'experience_points',
'ability_scores',
'modifiers',
'saving_throws',
Expand Down Expand Up @@ -206,7 +212,6 @@ def get_speed(self, creature):
entries = creature.get_speed().items()
return { key: value for key, value in entries if value is not None }


def get_all_speed(self, creature):
'''Implicit speed helper method.'''
return creature.get_all_speed()
Expand All @@ -219,6 +224,11 @@ def get_actions(self, creature):
result.append(action_obj)
return result

def get_challenge_rating_text(self, creature):
return creature.challenge_rating_text

def get_experience_points(self, creature):
return creature.experience_points

class CreatureTypeSerializer(GameContentSerializer):
'''Serializer for the Creature Type object'''
Expand Down
2 changes: 2 additions & 0 deletions api_v2/views/creature.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class Meta:
'name': ['iexact', 'exact'],
'document__key': ['in','iexact','exact'],
'size': ['exact'],
'challenge_rating_decimal': ['exact','lt','lte','gt','gte'],
'armor_class': ['exact','lt','lte','gt','gte'],
'ability_score_strength': ['exact','lt','lte','gt','gte'],
'ability_score_dexterity': ['exact','lt','lte','gt','gte'],
Expand Down Expand Up @@ -69,6 +70,7 @@ class CreatureTypeViewSet(viewsets.ReadOnlyModelViewSet):
queryset = models.CreatureType.objects.all().order_by('pk')
serializer_class = serializers.CreatureTypeSerializer


class CreatureSetViewSet(viewsets.ReadOnlyModelViewSet):
"""
list: API endpoint for returning a list of creature sets, which is similar to tags.
Expand Down
Loading

0 comments on commit 2b29152

Please sign in to comment.