예제 #1
0
class Plate(Model):
    name = CharField(max_length=100, unique=True)
    description = TextField(max_length=4000, blank=True, null=True)
    picture_sets = M2M(to=PictureSet, related_name='plates', blank=True)
    armor_class_bonus = PositiveSmallIntegerField(blank=True, null=True)
    parrying = PositiveSmallIntegerField(blank=True, null=True)
    endurance = PositiveSmallIntegerField()
    weight = DecimalField(max_digits=10, decimal_places=1)

    mod_max_agility = PositiveSmallIntegerField(blank=True, null=True)
    mod_max_movement = CharField(max_length=2, blank=True, null=True)

    mod_pickpocketing = DecimalField(max_digits=3,
                                     decimal_places=2,
                                     blank=True,
                                     null=True)
    mod_lockpicking = DecimalField(max_digits=3,
                                   decimal_places=2,
                                   blank=True,
                                   null=True)
    mod_sneaking_towns = DecimalField(max_digits=3,
                                      decimal_places=2,
                                      blank=True,
                                      null=True)
    mod_sneaking_wilderness = DecimalField(max_digits=3,
                                           decimal_places=2,
                                           blank=True,
                                           null=True)
    mod_hiding_towns = DecimalField(max_digits=3,
                                    decimal_places=2,
                                    blank=True,
                                    null=True)
    mod_hiding_wilderness = DecimalField(max_digits=3,
                                         decimal_places=2,
                                         blank=True,
                                         null=True)
    mod_climbing = DecimalField(max_digits=3,
                                decimal_places=2,
                                blank=True,
                                null=True)
    mod_traps = DecimalField(max_digits=3,
                             decimal_places=2,
                             blank=True,
                             null=True)
    allowed_profiles = M2M(
        to=Profile,
        limit_choices_to=Q(status='player'),
        related_name='allowed_plates',
        blank=True,
    )
    sorting_number = DecimalField(max_digits=3, decimal_places=2)

    def __str__(self):
        return self.name

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

    class Meta:
        ordering = ['sorting_number']
예제 #2
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']
예제 #3
0
class Shield(Model):
    name = CharField(max_length=100, unique=True)
    description = TextField(max_length=4000, blank=True, null=True)
    picture_sets = M2M(to=PictureSet, related_name='shields', blank=True)
    # enemies_no do skasowania
    enemies_no = PositiveSmallIntegerField()
    armor_class_bonus_close_combat = PositiveSmallIntegerField(
        blank=True,
        null=True,
    )
    armor_class_bonus_distance_combat = PositiveSmallIntegerField(
        blank=True,
        null=True,
    )
    weight = DecimalField(max_digits=10, decimal_places=1)

    allowed_profiles = M2M(
        to=Profile,
        limit_choices_to=Q(status='player'),
        related_name='allowed_shields',
        blank=True,
    )
    sorting_number = DecimalField(max_digits=3, decimal_places=2)

    def __str__(self):
        return self.name

    class Meta:
        ordering = ['sorting_number']
예제 #4
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}]"
예제 #5
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)
예제 #6
0
class Thread(Model):
    objects = ThreadManager()
    
    title = CharField(max_length=100, unique=True)
    kind = CharField(max_length=15, choices=THREAD_KINDS)
    known_directly = M2M(to=Profile, related_name='threads_known_directly')     # known_directly also use instead of inform_gm in Plans
    created_at = DateTimeField(auto_now_add=True)
    # Announcement
    followers = M2M(to=Profile, related_name='threads_followed', blank=True)
    tags = M2M(to=ThreadTag, related_name='threads', blank=True)
    # Debate
    is_ended = BooleanField(default=False)                                      # also Demands instead of is_done
    is_exclusive = BooleanField(default=False)
    
    class Meta:
        ordering = ['created_at']
    
    def __str__(self):
        return self.title
    
    def informables(self):
        if self.kind == 'Announcement':
            qs = Profile.active_players.all()
        elif self.kind == 'Debate':
            qs = Profile.living.all()
        else:
            qs = Profile.objects.none()
        return qs.exclude(id__in=self.known_directly.all())

    def get_absolute_url(self):
        return f'/communications/thread:{self.pk}/None/#page-bottom'
예제 #7
0
class Synergy(Model):
    name = CharField(max_length=100)
    skills = M2M(to=Skill, related_name='skills')
    allowed_profiles = M2M(
        to=Profile,
        limit_choices_to=Q(status='player'),
        related_name='allowed_synergies',
        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 = 'Synergy'
        verbose_name_plural = 'Synergies'
예제 #8
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)
예제 #9
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
예제 #10
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']
예제 #11
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
예제 #12
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
예제 #13
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'
예제 #14
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'
예제 #15
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']
예제 #16
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
예제 #17
0
class PictureSet(Model):
    objects = PictureSetManager()

    title = CharField(max_length=200)
    pictures = M2M(to=Picture, related_name='picture_sets', blank=True)

    class Meta:
        ordering = ['title']

    def __str__(self):
        return self.title
예제 #18
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
예제 #19
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
예제 #20
0
class BiographyPacket(InfoPacket):
    """A class for per-Persona info that may be visible to Players."""
    author = FK(to=Profile,
                related_name='authored_bio_packets',
                on_delete=PROTECT,
                null=True,
                blank=True)
    acquired_by = M2M(to=Profile, related_name='biography_packets', blank=True)
    picture_sets = M2M(to=PictureSet,
                       related_name='biography_packets',
                       blank=True)
    order_no = SmallIntegerField(default=1)

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

    def informables(self):
        qs = Profile.active_players.all()
        qs = qs.exclude(id__in=self.acquired_by.all())
        qs = qs.exclude(id=self.author_id)
        return qs
예제 #21
0
class Perk(Model):
    """A class describing a special ability of an item or a skill level."""
    name = CharField(max_length=50, unique=True, blank=True, null=True)
    description = TextField(max_length=4000, blank=True, null=True)
    modifiers = M2M(to=Modifier, related_name='perks', blank=True)
    cost = TextField(max_length=1000, blank=True, null=True)

    def __str__(self):
        return self.name

    class Meta:
        ordering = ['name', 'description']
예제 #22
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']
예제 #23
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'
예제 #24
0
class SkillType(Model):
    """A classification category for Skills."""
    kinds = M2M(to=SkillKind, related_name='skill_types', blank=True)
    name = CharField(max_length=100, unique=True)
    sorting_name = CharField(max_length=101, blank=True, null=True)

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

    def __str__(self):
        kinds = "|".join([str(kind) for kind in self.kinds.all()])
        return f"[{kinds}] {self.name}"

    class Meta:
        ordering = ['sorting_name']
예제 #25
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']
예제 #26
0
class TimeUnit(Model):
    objects = TimeUnitManager()

    # Fields for all proxies
    date_start = FK(
        to=Date,
        related_name='timeunits_started',
        on_delete=PROTECT,
        verbose_name='Date start (year of the encompassing unit)',
        #  TODO - blank and null are only for recreating events - delete later
        blank=True,
        null=True,
    )
    date_end = FK(
        to=Date,
        related_name='timeunits_ended',
        on_delete=PROTECT,
        verbose_name='Date end (year of the encompassing unit)',
        blank=True,
        null=True,
    )
    in_timeunit = FK(
        to='self',
        related_name='timeunits',
        on_delete=PROTECT,
        blank=True,
        null=True,
    )
    date_in_period = CharField(max_length=99, blank=True, null=True)
    date_in_era = CharField(max_length=99, blank=True, null=True)
    date_in_chronology = CharField(max_length=99, blank=True, null=True)
    description_short = TextField(blank=True, null=True)
    description_long = TextField(blank=True, null=True)

    # Fields for TimeSpan & HistoryEvent proxies
    known_short_desc = M2M(
        to=Profile,
        related_name='timeunits_known_short_desc',
        # limit_choices_to=PLAYERS,
        limit_choices_to=Q(status='player'),
        blank=True,
    )
    known_long_desc = M2M(
        to=Profile,
        related_name='timeunits_long_desc',
        # limit_choices_to=PLAYERS,
        limit_choices_to=Q(status='player'),
        blank=True,
    )

    # Fields for TimeSpan proxy
    name = CharField(max_length=256, blank=True, null=True)
    name_genetive = CharField(max_length=256, blank=True, null=True)

    # Fields for HistoryEvent & GameEvent proxies
    plot_threads = M2M(to=PlotThread, related_name='events', blank=True)
    locations = M2M(to=Location, related_name='events', blank=True)
    audio = FK(
        to=Audio,
        related_name='events',
        on_delete=PROTECT,
        blank=True,
        null=True,
    )

    # GameEvent proxy
    game = FK(
        to=GameSession,
        related_name='game_events',
        on_delete=PROTECT,
        blank=True,
        null=True,
    )
    event_no_in_game = PositiveSmallIntegerField(
        validators=[MinValueValidator(1)],
        blank=True,
        null=True,
    )
    known_directly = M2M(
        to=Profile,
        related_name='events_known_directly',
        # limit_choices_to=PLAYERS,
        limit_choices_to=Q(status='player'),
        blank=True,
    )
    known_indirectly = M2M(
        to=Profile,
        related_name='events_known_indirectly',
        # limit_choices_to=PLAYERS,
        limit_choices_to=Q(status='player'),
        blank=True,
    )
    picture_sets = M2M(to=PictureSet, related_name='events', blank=True)
    # debates = M2M(to=Debate, related_name='events', blank=True)
    debates = M2M(to=Thread, related_name='events', blank=True)

    class Meta:
        ordering = ['date_start']
        verbose_name_plural = '* Time Units (Time spans, History events, Game events)'

    def __str__(self):
        res = str(self.name)
        if self.in_timeunit and self.date_start:
            res += f' ({self.date_start.year}-)'
            if self.date_end:
                res = res[:-1] + f'{self.date_end.year}' + res[-1]
            if not self.timeunits.all():
                res = res[:-1] + res[-1]
            res = res[:-1] + f' | {self.in_timeunit.name_genetive}' + res[-1]
        return res

    def informables(self):
        qs = Profile.active_players.all()
        qs = qs.exclude(id__in=(self.known_directly.all()
                                | self.known_indirectly.all()))
        return qs
예제 #27
0
class MapPacket(InfoPacket):
    acquired_by = M2M(to=Profile, related_name='map_packets', blank=True)
    picture_sets = M2M(to=PictureSet, related_name='map_packets')