from django.db import models class Scene(models.Model): title = models.CharField(max_length=120) slug = models.SlugField(unique=True) body = models.TextField() class Meta: ordering = ["id"] def __str__(self) -> str: return self.title class Item(models.Model): SLOT_WEAPON = "weapon" SLOT_ARMOR = "armor" SLOT_TRINKET = "trinket" SLOT_CHOICES = [ (SLOT_WEAPON, "Weapon"), (SLOT_ARMOR, "Armor"), (SLOT_TRINKET, "Trinket"), ] name = models.CharField(max_length=120) slot = models.CharField(max_length=20, choices=SLOT_CHOICES) power = models.PositiveIntegerField(default=0) description = models.TextField() def __str__(self) -> str: return self.name class Choice(models.Model): SKILL_VIGOR = "vigor" SKILL_FOCUS = "focus" SKILL_ALCHEMY = "alchemy" SKILL_CHOICES = [ (SKILL_VIGOR, "Vigor"), (SKILL_FOCUS, "Focus"), (SKILL_ALCHEMY, "Alchemy"), ] scene = models.ForeignKey(Scene, related_name="choices", on_delete=models.CASCADE) text = models.CharField(max_length=200) next_scene = models.ForeignKey( Scene, related_name="incoming_choices", on_delete=models.SET_NULL, null=True, blank=True, ) required_skill = models.CharField(max_length=20, choices=SKILL_CHOICES, blank=True) difficulty = models.PositiveIntegerField(null=True, blank=True) success_scene = models.ForeignKey( Scene, related_name="success_from", on_delete=models.SET_NULL, null=True, blank=True, ) fail_scene = models.ForeignKey( Scene, related_name="fail_from", on_delete=models.SET_NULL, null=True, blank=True, ) reward_item = models.ForeignKey( Item, related_name="reward_choices", on_delete=models.SET_NULL, null=True, blank=True, ) class Meta: ordering = ["id"] def __str__(self) -> str: return f"{self.scene.title}: {self.text}" class Character(models.Model): BACKGROUND_WARDEN = "warden" BACKGROUND_SCOUR = "scour" BACKGROUND_ALCHEMIST = "alchemist" BACKGROUND_CHOICES = [ (BACKGROUND_WARDEN, "Warden of the North"), (BACKGROUND_SCOUR, "Scour of the Roads"), (BACKGROUND_ALCHEMIST, "Herb-born Alchemist"), ] name = models.CharField(max_length=80) background = models.CharField(max_length=20, choices=BACKGROUND_CHOICES) level = models.PositiveIntegerField(default=1) vigor = models.PositiveIntegerField(default=3) focus = models.PositiveIntegerField(default=3) alchemy = models.PositiveIntegerField(default=3) perk_points = models.PositiveIntegerField(default=1) current_scene = models.ForeignKey( Scene, on_delete=models.SET_NULL, null=True, blank=True ) def __str__(self) -> str: return self.name class Quest(models.Model): STATUS_ACTIVE = "active" STATUS_COMPLETE = "complete" STATUS_FAILED = "failed" STATUS_CHOICES = [ (STATUS_ACTIVE, "Active"), (STATUS_COMPLETE, "Complete"), (STATUS_FAILED, "Failed"), ] character = models.ForeignKey( Character, related_name="quests", on_delete=models.CASCADE ) title = models.CharField(max_length=140) summary = models.TextField() status = models.CharField(max_length=20, choices=STATUS_CHOICES, default=STATUS_ACTIVE) class Meta: ordering = ["id"] def __str__(self) -> str: return self.title class InventoryItem(models.Model): character = models.ForeignKey( Character, related_name="inventory", on_delete=models.CASCADE ) item = models.ForeignKey(Item, related_name="inventory_items", on_delete=models.CASCADE) equipped = models.BooleanField(default=False) class Meta: ordering = ["id"] def __str__(self) -> str: return f"{self.character.name} - {self.item.name}" class StoryEntry(models.Model): OUTCOME_SUCCESS = "success" OUTCOME_FAIL = "fail" OUTCOME_NEUTRAL = "neutral" OUTCOME_CHOICES = [ (OUTCOME_SUCCESS, "Success"), (OUTCOME_FAIL, "Fail"), (OUTCOME_NEUTRAL, "Neutral"), ] character = models.ForeignKey( Character, related_name="story_entries", on_delete=models.CASCADE ) scene = models.ForeignKey(Scene, related_name="story_entries", on_delete=models.CASCADE) choice_text = models.CharField(max_length=200) outcome = models.CharField(max_length=20, choices=OUTCOME_CHOICES) roll = models.PositiveIntegerField(null=True, blank=True) total = models.PositiveIntegerField(null=True, blank=True) created_at = models.DateTimeField(auto_now_add=True) class Meta: ordering = ["-created_at"] def __str__(self) -> str: return f"{self.character.name} - {self.choice_text}"