Exemple #1
0
class Demand(Model):
    author = FK(to=Profile, related_name='authored_demands', on_delete=CASCADE)
    addressee = FK(to=Profile,
                   related_name='received_demands',
                   on_delete=CASCADE)
    text = TextField()
    date_created = DateTimeField(auto_now_add=True)
    image = ImageField(upload_to='contact_pics', blank=True, null=True)
    is_done = BooleanField(default=False)

    class Meta:
        ordering = ['-date_created']

    def __str__(self):
        text = self.text
        return f'{text[0:50] + "..." if len(str(text)) > 50 else text}'

    def save(self, *args, **kwargs):
        first_save = True if not self.pk else False
        super().save(*args, **kwargs)

        if first_save and self.image:
            img = Image.open(self.image.path)
            if img.height > 700 or img.width > 700:
                output_size = (700, 700)
                img.thumbnail(output_size)
                img.save(self.image.path)
Exemple #2
0
class Statement(Model):
    text = TextField()
    thread = FK(to=Thread, related_name='statements', on_delete=CASCADE)
    author = FK(to=Profile, related_name='statements', on_delete=PROTECT)
    image = ImageField(upload_to='post_pics', blank=True, null=True)
    seen_by = M2M(to=Profile, related_name='statements_seen', blank=True)
    created_at = DateTimeField(auto_now_add=True)
    # Announcement
    options = M2M(to=Option, related_name='threads', blank=True)

    class Meta:
        ordering = ['created_at']

    def __str__(self):
        text = self.text
        return f'{text[:100]}...' if len(str(text)) > 100 else text
    
    def save(self, *args, **kwargs):
        first_save = True if not self.pk else False
        super().save(*args, **kwargs)
        if first_save and self.image:
            img = Image.open(self.image.path)
            if img.height > 700 or img.width > 700:
                output_size = (700, 700)
                img.thumbnail(output_size)
                img.save(self.image.path)
Exemple #3
0
class NewsAnswer(Model):
    text = TextField()
    news = FK(to=News, related_name='news_answers', on_delete=CASCADE)
    author = FK(to=Profile, related_name='news_answers', on_delete=CASCADE)
    image = ImageField(blank=True, null=True, upload_to='news_pics')
    seen_by = M2M(to=Profile, related_name='news_answers_seen', blank=True)
    created_at = DateTimeField(
        # auto_now_add=True
    )

    survey_options = M2M(to=SurveyOption, related_name='threads', blank=True)

    class Meta:
        ordering = ['created_at']

    def __str__(self):
        return self.text[:100] + '...' if len(str(self.text)) > 100 else self.text

    def save(self, *args, **kwargs):
        first_save = True if not self.pk else False
        super().save(*args, **kwargs)
        if first_save and self.image:
            img = Image.open(self.image.path)
            if img.height > 700 or img.width > 700:
                output_size = (700, 700)
                img.thumbnail(output_size)
                img.save(self.image.path)
Exemple #4
0
class Character(Model):
    objects = CharacterManager()

    profile = OneToOne(to=Profile, on_delete=CASCADE)
    first_name = FK(to=FirstName,
                    related_name='characters',
                    on_delete=PROTECT,
                    blank=True,
                    null=True)
    family_name = FK(to=FamilyName,
                     related_name='characters',
                     on_delete=PROTECT,
                     blank=True,
                     null=True)
    cognomen = CharField(max_length=250, blank=True, null=True)
    description = TextField(blank=True, null=True)
    frequented_locations = M2M(to=Location,
                               related_name='frequented_by_characters',
                               blank=True)
    biography_packets = M2M(to=BiographyPacket,
                            related_name='characters',
                            blank=True)
    dialogue_packets = M2M(to=DialoguePacket,
                           related_name='characters',
                           blank=True)

    # USE: profile.characters_known_directly.all()
    # for characters that the profile knows directly
    known_directly = M2M(to=Profile,
                         related_name='characters_known_directly',
                         blank=True)
    known_indirectly = M2M(to=Profile,
                           related_name='characters_known_indirectly',
                           blank=True)
    sorting_name = CharField(max_length=250, blank=True, null=True)

    class Meta:
        ordering = ['sorting_name']
        verbose_name = '* CHARACTER'
        verbose_name_plural = '* CHARACTERS'

    def __str__(self):
        name = f"{self.first_name} " if self.first_name else ""
        family_name = f"{self.family_name} " if self.family_name else ""
        cognomen = f"{self.cognomen} " if self.cognomen else ""
        return f"{name}{family_name}{cognomen}".strip()

    def save(self, *args, **kwargs):
        self.sorting_name = create_sorting_name(self.__str__())
        super().save(*args, **kwargs)

    def all_known(self):
        return self.known_directly.all() | self.known_indirectly.all()

    def informables(self):
        qs = Profile.active_players.all()
        qs = qs.exclude(id__in=self.all_known())
        qs = qs.exclude(character__id=self.pk)
        return qs
Exemple #5
0
class ProfileKlass(Model):
    profile = FK(to=Profile, related_name='profile_klasses', on_delete=PROTECT)
    klass = FK(to=Klass, related_name='profile_klasses', on_delete=PROTECT)
    title = CharField(max_length=200, blank=True, null=True)
    experience = PositiveSmallIntegerField()

    def __str__(self):
        return f'{self.profile}: {self.klass.name}'

    class Meta:
        ordering = ['profile__character__first_name']
        verbose_name = 'Profile Klass'
        verbose_name_plural = 'Profile Klasses'
Exemple #6
0
class Skill(Model):
    name = CharField(max_length=100, unique=True)
    tested_trait = CharField(max_length=50, blank=True, null=True)
    image = ImageField(upload_to='site_features_pics', blank=True, null=True)
    allowed_profiles = M2M(
        to=Profile,
        limit_choices_to=Q(status='player'),
        related_name='allowed_skills',
        blank=True,
    )
    group = FK(to=SkillGroup,
               related_name='skills',
               on_delete=PROTECT,
               blank=True,
               null=True)
    types = M2M(to=SkillType, related_name='skills', blank=True)
    sorting_name = CharField(max_length=101, blank=True, null=True)

    def __str__(self):
        return str(self.name)

    def save(self, *args, **kwargs):
        if self.name:
            self.sorting_name = create_sorting_name(self.name)
        super().save(*args, **kwargs)

    def short_name(self):
        return rid_of_special_chars(self.name)

    class Meta:
        ordering = ['sorting_name']
Exemple #7
0
class Modifier(Model):
    """Ex. factor and value combine into: +2 KP, -1 TRAF, +2 OBR, etc."""
    sign = CharField(max_length=5, choices=SIGN_CHOICES, blank=True, null=True)
    value_number = DecimalField(max_digits=10,
                                decimal_places=2,
                                blank=True,
                                null=True)
    value_percent = DecimalField(max_digits=3,
                                 decimal_places=2,
                                 validators=PERCENTAGE_VALIDATOR,
                                 blank=True,
                                 null=True)
    factor = FK(to=Factor, related_name='modifiers', on_delete=PROTECT)
    condition = CharField(max_length=200, blank=True, null=True)

    def __str__(self):
        sign = ""
        if self.sign:
            sign = "+" if self.sign == "plus" else "-"
        if self.value_number:
            value = str(self.value_number).rstrip('0').rstrip('.')
        else:
            value = str(
                float(self.value_percent) * 100).rstrip('0').rstrip('.') + "%"
        condition = f" [{self.condition}]" if self.condition else ""
        return f"{sign}{value} {self.factor.name}{condition}"

    class Meta:
        ordering = [
            'sign', 'value_number', 'value_percent', 'factor', 'condition'
        ]
Exemple #8
0
class Achievement(Model):
    name = CharField(max_length=100)
    description = TextField()
    profile = FK(to=Profile, related_name='achievements', on_delete=PROTECT)

    def __str__(self):
        return self.name
Exemple #9
0
class AuxiliaryNameGroup(Model):
    """A class for storing info about social or local specifics of a name.
    This may serve to differentiate names within a "big" location indicated in
    name.affix_group.name_group, ex.
        1)
        name_group ~ Fehzan,
        auxiliary_name_group ~ social_group='Royal names' or location='Ketra'
        2)
        name_group ~ Altankara | Nowa Altankara | Bastos | Skadia,
        auxiliary_name_group ~ location='Skadia'
    The 'color' attribute is intended to help distinguish these visually within
    a NameGroup on site.
    """
    objects = AuxiliaryNameGroupManager()

    color = CharField(max_length=100, blank=True, null=True)
    location = FK(to=Location, blank=True, null=True, on_delete=PROTECT)
    social_info = TextField(help_text='Social group indication if no location',
                            blank=True,
                            null=True)

    class Meta:
        ordering = ['social_info', 'location']

    def __str__(self):
        return f"{self.location or self.social_info}"
Exemple #10
0
class CharacterGroup(Model):
    """A mnodel for storing default knowledge packet sets for groups of
     characters. These should be automatically added to the knowlege packets of
     a newly created Character that belongs to a CharacterGroup (by signals).
    """
    name = CharField(max_length=250)
    author = FK(
        to=Profile,
        related_name='character_groups_authored',
        on_delete=SET_NULL,
        blank=True,
        null=True,
    )
    characters = M2M(to=Character, related_name='character_groups')
    default_knowledge_packets = M2M(
        to=KnowledgePacket,
        related_name='character_group_defaults',
        blank=True,
    )
    default_skills = M2M(to=Skill,
                         related_name='character_group_defaults',
                         blank=True)
    order_no = SmallIntegerField(default=1)

    class Meta:
        ordering = ['order_no', 'name']
        unique_together = ('name', 'author')
        verbose_name = '* CHARACTER GROUP'
        verbose_name_plural = '* CHARACTER GROUPS'

    def __str__(self):
        return f"{self.name} [{self.author}]"
Exemple #11
0
class EliteKlass(Model):
    name = CharField(max_length=100, unique=True)
    elite_profession = FK(
        to=EliteProfession,
        related_name='elite_klasses',
        on_delete=PROTECT,
    )
    description = TextField(max_length=4000, blank=True, null=True)
    start_perks = TextField(max_length=4000, blank=True, null=True)
    allowed_profiles = M2M(
        to=Profile,
        limit_choices_to=Q(status='player'),
        related_name='allowed_elite_klasses',
        blank=True,
    )
    sorting_name = CharField(max_length=250, blank=True, null=True)

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        if self.name:
            self.sorting_name = create_sorting_name(self.name)
        super().save(*args, **kwargs)

    def short_name(self):
        return rid_of_special_chars(self.name)

    class Meta:
        ordering = ['sorting_name']
        verbose_name = 'Elite klass'
        verbose_name_plural = 'Elite klasses'
Exemple #12
0
class Weapon(Model):
    weapon_type = FK(to=WeaponType, related_name='weapons', on_delete=PROTECT)
    name = CharField(max_length=100, unique=True)
    description = TextField(max_length=4000, blank=True, null=True)
    picture_sets = M2M(to=PictureSet, related_name='weapons', blank=True)

    # -------------------# TODO marked for removal [in 2023]-------------------
    delay = PositiveSmallIntegerField()
    damage_big_dices = CharField(max_length=10, blank=True, null=True)
    damage_big_add = PositiveSmallIntegerField(blank=True, null=True)
    # -------------------------------------------------------------------------

    damage_small_dices = CharField(max_length=10, blank=True, null=True)
    damage_small_add = PositiveSmallIntegerField(blank=True, null=True)
    damage_type = CharField(max_length=10, choices=DAMAGE_TYPES)
    special = TextField(max_length=4000, blank=True, null=True)
    range = CharField(max_length=100, blank=True, null=True)
    size = CharField(max_length=5, choices=SIZES)
    trait = CharField(max_length=10, choices=TRAITS)
    avg_price_value = PositiveSmallIntegerField(blank=True, null=True)
    avg_price_currency = CharField(max_length=5,
                                   choices=CURRENCIES,
                                   blank=True,
                                   null=True)
    avg_weight = DecimalField(max_digits=10, decimal_places=1)
    allowed_profiles = M2M(
        to=Profile,
        limit_choices_to=Q(status='player'),
        related_name='allowed_weapons',
        blank=True,
    )
    sorting_name = CharField(max_length=250, blank=True, null=True)

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        if self.name:
            self.sorting_name = create_sorting_name(self.name)
        super().save(*args, **kwargs)

    def short_name(self):
        return rid_of_special_chars(self.name)

    def damage_summary(self):
        damage_small = str(self.damage_small_dices)
        # if self.damage_small_add:
        #     damage_small += ('+' + str(self.damage_small_add))
        # damage_big = str(self.damage_big_dices)
        # if self.damage_big_add:
        #     damage_big += ('+' + str(self.damage_big_add))
        damage_small_add = ""
        if self.damage_small_add:
            damage_small_add += ("+" + str(self.damage_small_add))
        return f"{self.damage_small_dices}{damage_small_add}"

    class Meta:
        ordering = ['sorting_name']
Exemple #13
0
class SkillGroup(Model):
    """A loose grouping category for Skills."""
    name = CharField(max_length=100, unique=True)
    type = FK(to=SkillType, related_name='skill_groups', on_delete=PROTECT)

    def __str__(self):
        return self.name

    class Meta:
        ordering = ['name']
Exemple #14
0
class AudioSet(Model):
    title = CharField(max_length=200)
    description = TextField(max_length=500, blank=True, null=True)
    main_audio = FK(to=Audio, on_delete=PROTECT)
    audios = M2M(to=Audio, related_name='audio_sets', blank=True)

    class Meta:
        ordering = ['title']

    def __str__(self):
        return self.title
Exemple #15
0
class FamilyName(Model):
    form = CharField(max_length=250, unique=True)
    info = TextField(blank=True, null=True)
    locations = M2M(to=Location, related_name="family_names", blank=True)
    group = FK(to=FamilyNameGroup, on_delete=PROTECT, blank=True, null=True)

    class Meta:
        ordering = ['group', 'form']

    def __str__(self):
        return self.form
Exemple #16
0
class Item(Model):
    name = CharField(max_length=250)
    description = TextField()
    amount = PositiveSmallIntegerField(default=1)
    weight = DecimalField(max_digits=10, decimal_places=2, default=0)
    storage = FK(to=ItemStorage, related_name='items', on_delete=CASCADE)

    def __str__(self):
        return f'{self.name} [{self.storage.name}]'

    class Meta:
        ordering = ['name']
Exemple #17
0
class Option(Model):
    author = FK(to=Profile, related_name='options', on_delete=CASCADE)
    text = CharField(max_length=50)
    voters_yes = M2M(to=Profile, related_name='options_votes_yes', blank=True)
    voters_no = M2M(to=Profile, related_name='options_votes_no', blank=True)
    
    class Meta:
        ordering = ['text']
    
    def __str__(self):
        text = self.text
        return f'{text[:100]}...' if len(str(text)) > 100 else text
Exemple #18
0
class ThreadTag(Model):
    title = CharField(max_length=20)
    author = FK(to=Profile, related_name='thread_tags', on_delete=CASCADE)
    color = CharField(max_length=7, default='#000000')
    kind = CharField(max_length=15, choices=THREAD_KINDS)

    class Meta:
        ordering = ['kind', 'author', 'title']
        unique_together = ['title', 'author', 'kind']

    def __str__(self):
        return f"#{self.title}"
Exemple #19
0
class Level(Model):
    profile_klass = FK(to=ProfileKlass,
                       related_name='levels',
                       on_delete=CASCADE)
    achievements = M2M(to=Achievement, related_name='levels', blank=True)
    level_number = PositiveSmallIntegerField()
    level_mods = TextField()

    def __str__(self):
        return f'{self.profile_klass} [{self.level_number}]'

    class Meta:
        ordering = ['profile_klass', 'level_number']
Exemple #20
0
class FirstName(Model):
    objects = FirstNameManager()

    form = CharField(max_length=250, unique=True)
    form_2 = CharField(max_length=250, blank=True, null=True)
    info = TextField(blank=True, null=True)
    is_ancient = BooleanField(default=False)
    # FK fields nullable to allow creation of Character via registration form
    affix_group = FK(to=AffixGroup,
                     related_name='first_names',
                     on_delete=PROTECT,
                     blank=True,
                     null=True)
    auxiliary_group = FK(to=AuxiliaryNameGroup,
                         on_delete=PROTECT,
                         blank=True,
                         null=True)

    class Meta:
        ordering = ['auxiliary_group', 'form']

    def __str__(self):
        return self.form
Exemple #21
0
class News(Model):
    objects = NewsManager()
    
    title = CharField(max_length=100, unique=True)
    topic = FK(to=Topic, related_name='news', on_delete=CASCADE)
    allowed_profiles = M2M(to=Profile, related_name='allowed_news')
    created_at = DateTimeField(auto_now_add=True)
    followers = M2M(to=Profile, related_name='followed_news', blank=True)

    def __str__(self):
        return self.title[:50] + '...' if len(str(self.title)) > 100 else self.title

    class Meta:
        verbose_name = 'News'
        verbose_name_plural = 'News'
Exemple #22
0
class SurveyOption(Model):
    objects = SurveyOptionManager()
    
    author = FK(to=Profile, related_name='survey_options_authored',
                on_delete=CASCADE)
    option_text = CharField(max_length=50)
    yes_voters = M2M(to=Profile, related_name='survey_yes_votes', blank=True)
    no_voters = M2M(to=Profile, related_name='survey_no_votes', blank=True)
    
    class Meta:
        ordering = ['option_text']
    
    def __str__(self):
        return self.option_text[:100] + '...' if len(
            str(self.option_text)) > 100 else self.option_text
Exemple #23
0
class AffixGroup(Model):
    objects = AffixGroupManager()

    affix = CharField(max_length=100)
    type = CharField(max_length=20, choices=NAME_TYPES, default='MALE')
    name_group = FK(to=NameGroup,
                    related_name='affix_groups',
                    on_delete=PROTECT)

    class Meta:
        ordering = ['name_group', 'type', 'affix']
        unique_together = ('affix', 'type', 'name_group')

    def __str__(self):
        return f"[{self.name_group}] | {self.type} | {self.affix}"
Exemple #24
0
class DemandAnswer(Model):
    demand = FK(to=Demand, related_name='demand_answers', on_delete=CASCADE)
    author = FK(to=Profile, related_name='demand_answers', on_delete=CASCADE)
    text = TextField()
    date_posted = DateTimeField(auto_now_add=True)
    image = ImageField(upload_to='contact_pics', blank=True, null=True)

    class Meta:
        ordering = ['date_posted']

    def save(self, *args, **kwargs):
        first_save = True if not self.pk else False
        super().save(*args, **kwargs)

        if first_save and self.image:
            img = Image.open(self.image.path)
            if img.height > 700 or img.width > 700:
                output_size = (700, 700)
                img.thumbnail(output_size)
                img.save(self.image.path)

    def __str__(self):
        text = self.text
        return f'{text[0:100] + "..." if len(str(text)) > 100 else text}'
Exemple #25
0
class Klass(Model):
    name = CharField(max_length=100, unique=True)
    profession = FK(to=Profession, related_name='klasses', on_delete=PROTECT)
    description = TextField(max_length=4000, blank=True, null=True)
    start_perks = TextField(max_length=4000, blank=True, null=True)
    lvl_1 = CharField(max_length=500, blank=True, null=True)
    lvl_2 = CharField(max_length=500, blank=True, null=True)
    lvl_3 = CharField(max_length=500, blank=True, null=True)
    lvl_4 = CharField(max_length=500, blank=True, null=True)
    lvl_5 = CharField(max_length=500, blank=True, null=True)
    lvl_6 = CharField(max_length=500, blank=True, null=True)
    lvl_7 = CharField(max_length=500, blank=True, null=True)
    lvl_8 = CharField(max_length=500, blank=True, null=True)
    lvl_9 = CharField(max_length=500, blank=True, null=True)
    lvl_10 = CharField(max_length=500, blank=True, null=True)
    lvl_11 = CharField(max_length=500, blank=True, null=True)
    lvl_12 = CharField(max_length=500, blank=True, null=True)
    lvl_13 = CharField(max_length=500, blank=True, null=True)
    lvl_14 = CharField(max_length=500, blank=True, null=True)
    lvl_15 = CharField(max_length=500, blank=True, null=True)
    lvl_16 = CharField(max_length=500, blank=True, null=True)
    lvl_17 = CharField(max_length=500, blank=True, null=True)
    lvl_18 = CharField(max_length=500, blank=True, null=True)
    lvl_19 = CharField(max_length=500, blank=True, null=True)
    lvl_20 = CharField(max_length=500, blank=True, null=True)
    allowed_profiles = M2M(
        to=Profile,
        limit_choices_to=Q(status='player'),
        related_name='allowed_klasses',
        blank=True,
    )
    sorting_name = CharField(max_length=250, blank=True, null=True)

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        if self.name:
            self.sorting_name = create_sorting_name(self.name)
        super().save(*args, **kwargs)

    def short_name(self):
        return rid_of_special_chars(self.name)

    class Meta:
        ordering = ['sorting_name']
        verbose_name = 'Klass'
        verbose_name_plural = 'Klasses'
Exemple #26
0
class SynergyLevel(Model):
    synergy = FK(to=Synergy, related_name='synergy_levels', on_delete=PROTECT)
    level = CharField(max_length=10, choices=S_LEVELS[1:])
    description = TextField(max_length=4000, blank=True, null=True)
    perks = M2M(to=Perk, related_name='synergy_levels', blank=True)
    acquired_by = M2M(to=Profile, related_name='synergy_levels', blank=True)
    sorting_name = CharField(max_length=250, blank=True, null=True)

    def __str__(self):
        return f'{str(self.synergy.name)} [{self.level}]'

    def save(self, *args, **kwargs):
        self.sorting_name = create_sorting_name(self.__str__())
        super().save(*args, **kwargs)

    class Meta:
        ordering = ['sorting_name']
Exemple #27
0
class ItemStorage(Model):
    name = CharField(max_length=250)
    description = TextField()
    owners = M2M(to=Profile, related_name='item_storages')
    location = FK(
        to=SecondaryLocation,
        related_name='item_storages',
        on_delete=PROTECT,
        blank=True,
        null=True,
    )

    def __str__(self):
        return f'{self.name}: {", ".join([o for o in self.owners.all()])}'

    class Meta:
        ordering = ['name']
Exemple #28
0
class GameSession(Model):
    game_no = IntegerField(null=True)
    title = CharField(max_length=200)
    chapter = FK(
        to=Chapter,
        related_name='game_sessions',
        on_delete=PROTECT,
        blank=True,
        null=True,
    )
    date = DateField(blank=True, null=True)

    class Meta:
        ordering = ['game_no']
        verbose_name = 'II. Game session'

    def __str__(self):
        return self.title
Exemple #29
0
class KnowledgePacket(InfoPacket):
    """A class for info packets that might be shared among multiple Skills."""
    author = FK(
        to=Profile,
        related_name='authored_kn_packets',
        on_delete=PROTECT,
        null=True,
        blank=True,
    )
    acquired_by = M2M(to=Profile, related_name='knowledge_packets', blank=True)
    skills = M2M(to=Skill, related_name='knowledge_packets')
    picture_sets = M2M(to=PictureSet,
                       related_name='knowledge_packets',
                       blank=True)

    def informables(self):
        qs = Profile.active_players.all()
        qs = qs.exclude(id__in=self.acquired_by.all())
        return qs
Exemple #30
0
class Picture(Model):
    """An overlay model to create contextual descriptions for Image objects.
    One Image object may have multiple descriptions depending on the context
    in which it was seen and to whom it is known. This allows to create
    multiple overlays for one image with varying descriptions and types.
    """
    image = FK(to=PictureImage, related_name='used_in_pics', on_delete=CASCADE)
    type = CharField(max_length=20, choices=IMG_TYPES)
    description = CharField(max_length=200, blank=True, null=True)
    sorting_name = CharField(max_length=250, blank=True, null=True)

    class Meta:
        ordering = ['type', 'sorting_name']

    def __str__(self):
        return f"[{self.type.upper()}] {self.description}"

    def save(self, *args, **kwargs):
        self.sorting_name = create_sorting_name(self.description)
        super().save(*args, **kwargs)