chess_rpg_backend/game/models.py

229 lines
6.5 KiB
Python
Raw Normal View History

2022-06-05 13:09:27 +03:00
import random
import uuid
2022-06-05 13:09:27 +03:00
from django.core.files import File
from django.core.validators import (
MinValueValidator,
MaxValueValidator,
MinLengthValidator,
MaxLengthValidator,
)
from django.db import models
2022-06-05 13:09:27 +03:00
from django.conf import settings
from common.generators import generate_charset
from game.services.jwt import sign_jwt
2022-06-11 23:34:55 +03:00
HER0_TYPES = [
("WIZARD", "wizard"),
("ARCHER", "archer"),
("WARRIOR", "warrior"),
("KING", "king"),
]
HER0_IMAGE_TYPES = [("DIE", "die"), ("IDLE", "idle"), ("ATTACK", "attack")]
class Player(models.Model):
"""base model to handle and store users"""
2022-06-05 13:09:27 +03:00
ton_wallet = models.CharField(
verbose_name="TON wallet",
validators=[MinLengthValidator(48), MaxLengthValidator(48)],
max_length=48,
unique=True,
)
name = models.CharField(max_length=100, blank=True)
2022-06-05 13:09:27 +03:00
created = models.DateTimeField(auto_now_add=True)
def save(
self, force_insert=False, force_update=False, using=None, update_fields=None
):
2022-06-08 19:03:38 +03:00
"""saves user and creates deck for him with 16 heroes"""
2022-06-05 13:09:27 +03:00
super(Player, self).save()
PlayerAuthSession.objects.create(player=self)
2022-06-08 19:03:38 +03:00
deck = Deck.objects.create(player=self)
2022-06-05 13:09:27 +03:00
types = (
2022-06-11 23:34:55 +03:00
["KING"]
+ ["ARCHER" for _ in range(4)]
2022-06-05 13:09:27 +03:00
+ ["WARRIOR" for _ in range(6)]
+ ["WIZARD" for _ in range(2)]
2022-06-11 23:34:55 +03:00
+ [random.choice(HER0_TYPES[:3])[0] for _ in range(3)]
2022-06-05 13:09:27 +03:00
)
for t in types:
hero = Hero()
hero.player = self
hero.type = t
2022-06-11 23:34:55 +03:00
hero.health = random.randint(0, 10)
hero.attack = random.randint(0, 10)
hero.speed = random.randint(0, 10)
2022-06-05 13:09:27 +03:00
2022-06-11 23:34:55 +03:00
hero.save()
HeroInDeck.objects.create(deck=deck, hero=hero)
2022-06-08 19:03:38 +03:00
def get_last_deck(self):
return Deck.objects.filter(player=self).last()
def get_auth_session(self):
return PlayerAuthSession.objects.get(player=self).jit
def get_refresh_token(self):
return sign_jwt({"jit": self.get_auth_session(), "type": "refresh"})
def get_access_token(self):
return sign_jwt({"id": self.id, "type": "access"}, t_life=3600)
def __str__(self):
return self.name
class Meta:
indexes = [models.Index(fields=["ton_wallet"])]
2022-06-05 13:09:27 +03:00
ordering = ["-created"]
2022-06-06 20:15:45 +03:00
db_table = "player"
verbose_name = "player"
verbose_name_plural = "players"
class Hero(models.Model):
"""Model to store heroes and their stats, connected to player"""
2022-06-06 20:15:45 +03:00
uuid = models.UUIDField(
default=uuid.uuid4, editable=False, unique=True, primary_key=True
)
2022-06-05 13:09:27 +03:00
player = models.ForeignKey(
Player,
on_delete=models.CASCADE,
related_name="heroes",
related_query_name="hero",
)
added = models.DateTimeField(auto_now_add=True)
2022-06-04 19:30:54 +03:00
type = models.CharField(blank=False, choices=HER0_TYPES, max_length=7)
2022-06-11 23:34:55 +03:00
idle_img_f = models.ForeignKey(
"HeroImageSet", on_delete=models.CASCADE, related_name="idle_image_fkey"
)
attack_img_f = models.ForeignKey(
"HeroImageSet", on_delete=models.CASCADE, related_name="attack_image_fkey"
)
die_img_f = models.ForeignKey(
"HeroImageSet", on_delete=models.CASCADE, related_name="die_image_fkey"
)
health = models.IntegerField(
validators=[MinValueValidator(1), MaxValueValidator(10)], blank=False
)
2022-06-05 13:09:27 +03:00
attack = models.IntegerField(
validators=[MinValueValidator(1), MaxValueValidator(10)], blank=False
2022-06-05 13:09:27 +03:00
)
speed = models.IntegerField(
validators=[MinValueValidator(1), MaxValueValidator(10)], blank=False
)
2022-06-11 23:34:55 +03:00
def idle_img(self):
return self.idle_img_f.image.url
def attack_img(self):
return self.attack_img_f.image.url
def die_img(self):
return self.die_img_f.image.url
def __str__(self):
return f"{self.type} {self.player.name}"
2022-06-11 23:34:55 +03:00
def save(
self, force_insert=False, force_update=False, using=None, update_fields=None
):
self.idle_img_f = random.choice(
[x for x in HeroImageSet.objects.filter(hero_type=self.type, type="IDLE")]
)
self.attack_img_f = random.choice(
[x for x in HeroImageSet.objects.filter(hero_type=self.type, type="ATTACK")]
)
self.die_img_f = random.choice(
[x for x in HeroImageSet.objects.filter(hero_type=self.type, type="DIE")]
)
super(Hero, self).save()
class Meta:
indexes = [models.Index(fields=["uuid"])]
ordering = ["-added"]
2022-06-06 20:15:45 +03:00
db_table = "hero"
verbose_name = "hero"
verbose_name_plural = "heroes"
2022-06-06 20:15:45 +03:00
2022-06-11 23:34:55 +03:00
class HeroImageSet(models.Model):
type = models.CharField(max_length=10, choices=HER0_IMAGE_TYPES)
hero_type = models.CharField(blank=False, choices=HER0_TYPES, max_length=7)
image = models.ImageField(upload_to="uploads/")
def __str__(self):
return f"{self.hero_type} {self.type} image"
2022-06-06 20:15:45 +03:00
class Deck(models.Model):
player = models.ForeignKey(
Player,
on_delete=models.CASCADE,
related_name="decks",
related_query_name="deck",
)
def __str__(self):
2022-06-07 23:54:26 +03:00
return f"{self.player.name}'s deck"
2022-06-06 20:15:45 +03:00
def get_heroes(self):
return [x.hero for x in HeroInDeck.objects.filter(deck=self)]
2022-06-07 23:54:26 +03:00
def heroes(self):
# added for better DRF view
return self.get_heroes()
def score(self):
return sum([x.attack + x.health + x.speed for x in self.get_heroes()])
2022-06-06 20:15:45 +03:00
class Meta:
db_table = "deck"
verbose_name = "deck"
verbose_name_plural = "decks"
class HeroInDeck(models.Model):
deck = models.ForeignKey(
Deck,
on_delete=models.CASCADE,
related_name="hero_in_deck",
related_query_name="heroes",
)
hero = models.OneToOneField(
Hero,
on_delete=models.CASCADE,
related_name="hero_in_deck",
related_query_name="decks",
)
class Meta:
db_table = "hero_in_deck"
verbose_name = "Hero in deck"
verbose_name_plural = "Heroes in decks"
class PlayerAuthSession(models.Model):
player = models.OneToOneField(
Player, unique_for_month=True, on_delete=models.CASCADE
)
jit = models.CharField(max_length=30)
def save(
self, force_insert=False, force_update=False, using=None, update_fields=None
):
self.jit = generate_charset(30)
super(PlayerAuthSession, self).save(
force_insert=force_insert,
force_update=force_update,
using=using,
update_fields=update_fields,
)