You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
326 lines
9.8 KiB
326 lines
9.8 KiB
from random import random
|
|
from typing import Iterable
|
|
|
|
from django.conf import settings
|
|
from django.db import models
|
|
from django.db.models import QuerySet
|
|
from django.utils import timezone
|
|
|
|
from .utils.doba import Doba
|
|
|
|
|
|
class Stanoviste(models.Model):
|
|
class Meta:
|
|
db_table = "hra_stanoviste"
|
|
verbose_name = "Stanoviště"
|
|
verbose_name_plural = "Stanoviště"
|
|
|
|
user = models.OneToOneField(
|
|
settings.AUTH_USER_MODEL, blank=False, null=False, unique=True,
|
|
verbose_name="uživatel", on_delete=models.PROTECT,
|
|
help_text="Stanoviště musí být přihlášena, aby se nedala přepínat stanoviště",
|
|
)
|
|
|
|
nazev = models.CharField(
|
|
"název", max_length=256, blank=False, null=False,
|
|
help_text="zobrazovaný název stanoviště",
|
|
)
|
|
|
|
verejny_text = models.TextField(
|
|
"veřejný text", max_length=256, blank=False, null=False,
|
|
help_text="zobrazovaný název stanoviště",
|
|
)
|
|
|
|
poradi = models.IntegerField(
|
|
"pořadí", blank=False, null=False,
|
|
help_text="číselné označení stanoviště (aby hráči věděli, že našli všechny)",
|
|
)
|
|
|
|
template = models.CharField(
|
|
"template", max_length=256, blank=False, null=False, default="base.html",
|
|
help_text="template tohoto stanoviště (co vidí tým)",
|
|
)
|
|
|
|
|
|
class Tym(models.Model):
|
|
class Meta:
|
|
db_table = "hra_tym"
|
|
verbose_name = "Tým"
|
|
verbose_name_plural = "Týmy"
|
|
|
|
user = models.OneToOneField(
|
|
settings.AUTH_USER_MODEL, blank=False, null=False, unique=True,
|
|
verbose_name="uživatel", on_delete=models.PROTECT,
|
|
)
|
|
|
|
nazev = models.CharField(
|
|
"název týmu", max_length=256, blank=False, null=False,
|
|
)
|
|
|
|
hraci = models.CharField(
|
|
"hráči", max_length=256, blank=True, null=True,
|
|
help_text="seznam hráčů v týmu",
|
|
)
|
|
|
|
start = models.DateTimeField(
|
|
"začátek hry", blank=False, null=False, default=timezone.now,
|
|
help_text="čas, kdy tým začal",
|
|
)
|
|
|
|
delta = models.FloatField(
|
|
"přidaný čas", blank=False, null=False, default=0,
|
|
help_text="čas (v hodinách), o který se tým posunul svými akcemi",
|
|
)
|
|
|
|
def nastav_a_uloz(self, attr_name: str, value: object) -> "Tym":
|
|
self.__setattr__(attr_name, value)
|
|
self.save()
|
|
return self
|
|
|
|
@property
|
|
def doba(self) -> Doba:
|
|
return Doba((timezone.now() - self.start).total_seconds() / 60 * settings.TIME_SPEED + self.delta)
|
|
|
|
def pricti_cas_a_uloz(self, cas: int) -> "Tym":
|
|
self.delta += cas
|
|
self.save()
|
|
return self
|
|
|
|
# Inventář
|
|
tk_nalezena = models.FloatField(
|
|
"čas nalezení třídní knihy", blank=True, null=True, default=None,
|
|
help_text="čas (v hodinách), kdy tým nalezl třídní knihu (pro pořadí a rozhodnutí, zda ji tým už nalezl)",
|
|
)
|
|
|
|
ma_penize = models.BooleanField(
|
|
"má tým peníze", blank=False, null=False, default=False,
|
|
help_text="zda si tým vzal peníze a neztratil je",
|
|
)
|
|
|
|
ds_bad = models.FloatField(
|
|
"čas chybného založení ds", blank=True, null=True, default=None,
|
|
help_text="čas, kdy tým špatným způsobem požádal o datovou schránku",
|
|
)
|
|
|
|
ma_ds = models.BooleanField(
|
|
"má tým ds", blank=False, null=False, default=False,
|
|
help_text="zda si tým založil datovou schránku",
|
|
)
|
|
|
|
pocet_bananu = models.IntegerField(
|
|
"počet banánů", blank=False, null=False, default=0,
|
|
help_text="kolik vlastní tým bánánů",
|
|
)
|
|
|
|
vi_o_zadosti = models.BooleanField(
|
|
"ví tým o finální žádosti", blank=False, null=False, default=False,
|
|
help_text="ví tým o tom, že potřebuje žádost o náhled do archivů",
|
|
)
|
|
|
|
vi_o_mesici = models.BooleanField(
|
|
"ví tým o svitu měsíce", blank=False, null=False, default=False,
|
|
help_text="ví tým o tom, že žádost o náhled do archivů se může podávat pouze za svitu měsíce",
|
|
)
|
|
|
|
vi_o_mase = models.BooleanField(
|
|
"ví o tom, že v jídelně už není banán", blank=False, null=False, default=False,
|
|
help_text="už se ptali v jídelně na další banán a zjistili, že je jen MaSo",
|
|
)
|
|
|
|
@property
|
|
def vyzvednute_zadosti(self) -> QuerySet["Zadost"]:
|
|
return self.zadosti.filter(vyzvednuta=True)
|
|
|
|
@property
|
|
def nevyzvednute_zadosti(self) -> QuerySet["Zadost"]:
|
|
return self.zadosti.filter(studijni__isnull=False, vyzvednuta=False)
|
|
|
|
def ma_platnou_zadost(self, zadost_typ: str) -> bool:
|
|
return self.vyzvednute_zadosti.filter(typ=zadost_typ, plati=True).count() > 0
|
|
|
|
@property
|
|
def ma_platnou_zadost_o_banan(self) -> bool:
|
|
""" Protože django templates jsou hloupé """
|
|
return self.vyzvednute_zadosti.filter(typ=Zadost.TYP_BANAN, plati=True).count() > 0
|
|
|
|
@property
|
|
def ma_platnou_zadost_o_vege(self) -> bool:
|
|
""" Protože django templates jsou hloupé """
|
|
return self.vyzvednute_zadosti.filter(typ=Zadost.TYP_VEGE, plati=True).count() > 0
|
|
|
|
def zadosti_na_internatu(self, doba: Doba) -> QuerySet["Zadost"]:
|
|
return self.zadosti.filter(vyzvednuta=False, internat__isnull=False, internat__lte=doba)
|
|
|
|
def zadosti_na_poste(self, doba: Doba) -> QuerySet["Zadost"]:
|
|
return self.zadosti.filter(posta__isnull=False, posta__lte=doba, internat__isnull=False, internat__gt=doba)
|
|
|
|
@staticmethod
|
|
def studijni_otevreno_nejdrive(doba: Doba) -> Doba:
|
|
if not ( # copy-paste z logika.py
|
|
doba.cas < 8 or
|
|
doba.cas > 15 or
|
|
doba.den_v_tydnu >= 6 or
|
|
(doba.den_v_tydnu == 5 and doba.cas > 13)
|
|
):
|
|
return doba
|
|
|
|
if doba.cas > 15 or (doba.den_v_tydnu == 5 and doba.cas > 13):
|
|
doba += Doba.DEN - doba.cas + 8
|
|
else:
|
|
doba = Doba(doba.den*Doba.DEN + 8)
|
|
if doba.den_v_tydnu == 6:
|
|
doba += 2*Doba.DEN
|
|
elif doba.den_v_tydnu == 7:
|
|
doba += Doba.DEN
|
|
return doba
|
|
|
|
@staticmethod
|
|
def doruceni(doba: Doba) -> Doba:
|
|
doba += Doba.DEN - doba.cas + 8
|
|
while True:
|
|
if doba.den_v_tydnu == 6 or doba.den_v_tydnu == 7:
|
|
doba += Doba.DEN
|
|
else:
|
|
if random() > 1/3:
|
|
doba += Doba.DEN
|
|
else:
|
|
return doba
|
|
|
|
@staticmethod
|
|
def postovna(studijni: Doba) -> Doba:
|
|
return (studijni.den + (settings.POSTOVNA_DEN_V_TYDNU - studijni.den_v_tydnu + 7) % 7) * Doba.DEN + 10
|
|
|
|
def poslat_vytistene_zadosti(self, doba: Doba) -> Iterable["Zadost"]:
|
|
if not self.ma_penize:
|
|
return ()
|
|
self.ma_penize = False
|
|
self.save()
|
|
zadosti = self.zadosti.filter(vytistena=True)
|
|
for zadost in zadosti:
|
|
zadost.vytistena = False
|
|
|
|
studijni = self.doruceni(doba)
|
|
zadost.studijni = studijni
|
|
posta = Doba((studijni.den + (settings.POSTOVNA_DEN_V_TYDNU - studijni.den_v_tydnu + 7) % 7) * Doba.DEN + 10)
|
|
zadost.posta = posta
|
|
zadost.internat = self.doruceni(posta)
|
|
|
|
if zadost.typ == Zadost.TYP_TK:
|
|
zadost.plati = Zadost.plati_tk(doba)
|
|
if zadost.typ == Zadost.TYP_ZADOST:
|
|
zadost.plati = False
|
|
zadost.save()
|
|
return zadosti
|
|
|
|
def vytiskni_zadost(self, typ: str) -> tuple["Zadost"]:
|
|
return (Zadost.objects.create(tym=self, typ=typ, vytistena=True,),)
|
|
|
|
def posli_zadost_ds(self, doba: Doba, typ: str) -> tuple["Zadost"]:
|
|
studijni = doba
|
|
internat = self.studijni_otevreno_nejdrive(doba)
|
|
if typ == Zadost.TYP_TK:
|
|
return (Zadost.objects.create(tym=self, typ=typ, studijni=studijni, internat=internat, plati=Zadost.plati_tk(doba)),)
|
|
return (Zadost.objects.create(
|
|
tym=self, typ=typ, studijni=studijni, internat=internat, plati=typ != Zadost.TYP_ZADOST,
|
|
),)
|
|
|
|
def vyzvedni_internat(self, doba: Doba) -> Iterable["Zadost"]:
|
|
zadosti = self.zadosti_na_internatu(doba)
|
|
for zadost in zadosti:
|
|
zadost.vyzvednuta = True
|
|
zadost.save()
|
|
if zadost.typ == Zadost.TYP_TK:
|
|
self.vi_o_mesici = True
|
|
self.save()
|
|
return zadosti
|
|
|
|
def vyzvedni_postu(self, doba: Doba) -> Iterable["Zadost"]:
|
|
zadosti = self.zadosti_na_poste(doba)
|
|
for zadost in zadosti:
|
|
zadost.vyzvednuta = True
|
|
zadost.save()
|
|
if zadost.typ == Zadost.TYP_TK:
|
|
self.vi_o_mesici = True
|
|
self.save()
|
|
return zadosti
|
|
|
|
def posli_zadost_studijni(self, doba: Doba, typ: str) -> tuple["Zadost"]:
|
|
studijni = doba
|
|
posta = self.postovna(studijni)
|
|
internat = self.doruceni(doba)
|
|
return (Zadost.objects.create(
|
|
tym=self, typ=typ, studijni=studijni, posta=posta, internat=internat,
|
|
plati=typ != Zadost.TYP_TK and typ != Zadost.TYP_ZADOST,
|
|
),)
|
|
|
|
ovesna_kase = models.IntegerField(
|
|
blank=False, null=False, default=0,
|
|
)
|
|
|
|
|
|
class Zadost(models.Model):
|
|
class Meta:
|
|
db_table = "hra_zadost"
|
|
verbose_name = "Žádost"
|
|
verbose_name_plural = "Žádosti"
|
|
|
|
tym = models.ForeignKey(Tym, related_name="zadosti", blank=False, null=False, on_delete=models.CASCADE)
|
|
|
|
TYP_ZADOST = "zadost"
|
|
TYP_BANAN = "banan"
|
|
TYP_VEGE = "vege"
|
|
# TYP_BAD_TK = "bad_tk"
|
|
TYP_TK = "tk"
|
|
TYP_CHOICES = [
|
|
(TYP_ZADOST, "Žádost"),
|
|
(TYP_BANAN, "Žádost o banán"),
|
|
(TYP_VEGE, "Žádost o více vegetariánskou stravu v jídelně"),
|
|
# (TYP_BAD_TK, "Neplatná žádost o přístup k záznamům o třídní knize"),
|
|
(TYP_TK, "Žádost o přístup k záznamům o třídní knize"),
|
|
]
|
|
|
|
typ = models.CharField(
|
|
"toto je ", max_length=8, blank=False, null=False, choices=TYP_CHOICES,
|
|
)
|
|
|
|
studijni = models.FloatField(
|
|
"žádost dorazí na studijní", blank=True, null=True, default=None,
|
|
)
|
|
|
|
posta = models.FloatField(
|
|
"tým si může žádost vyzvednout na internátu od", blank=True, null=True, default=None,
|
|
help_text="(do self.internat)",
|
|
)
|
|
|
|
internat = models.FloatField(
|
|
"tým si může žádost vyzvednout na poště od", blank=True, null=True, default=None,
|
|
)
|
|
|
|
vyzvednuta = models.BooleanField(
|
|
"tým si tuto žádost již vyzvedl", blank=False, null=False, default=False,
|
|
)
|
|
|
|
vytistena = models.BooleanField(
|
|
"tým má u sebe tuto žádost vytištěnou",
|
|
blank=False, null=False, default=False,
|
|
)
|
|
|
|
plati = models.BooleanField(
|
|
"tato žádost platí", blank=False, null=False, default=True,
|
|
help_text="Aktuálně má uplatnění pouze u Žádosti o přístup k záznamům o třídní knize",
|
|
)
|
|
@staticmethod
|
|
def plati_tk(doba: Doba) -> bool:
|
|
return (
|
|
not doba.je_nov and
|
|
doba.je_noc and
|
|
doba.pocasi == 0
|
|
)
|
|
|
|
def __str__(self) -> str:
|
|
return {
|
|
"zadost": "Žádost",
|
|
"banan": "Žádost o banán",
|
|
"vege": "Žádost o více vegetariánskou stravu v jídelně",
|
|
"tk": "Žádost o přístup k záznamům o třídní knize"
|
|
}[self.typ]
|
|
|