Django Wars [Parte 13]: Associando players a armas e armaduras

O Django Wars foi idealizado e desenvolvido no Django 1.4. Algumas funcionalidades aqui descritas podem não funcionar ou funcionar de forma diferente em outras versões do Django

Já temos as informações do jogador no modelo Player, e já temos as informações das armas e armaduras.
Mas como vamos fazer para saber quais armas e armaduras o jogador possui em seu inventório?
Como vamos fazer para saber qual arma e qual armadura ele está usando neste exato momento?
Para isso vamos criar um relacionamento entre as armas e o usuário e entre as armaduras e o usuário.

Este relacionamento será criado no modelo Player, utilizando um campo do tipo ManyToManyField.
Para definir as armas e armaduras que estão sendo utilizadas no momento, utilizaremos um simples campo ForeignKey.
Então, indo na app players, alteraremos o arquivo models.py para ficar assim:

from django.db import models
#importamos o modelo de usuario do Django para "extende-lo"
from django.contrib.auth.models import User
from django.db.models.signals import post_save

#importamos as armas e armaduras
from djangowars.itens.models import Arma, Armadura


# Create your models here.
class Player(models.Model):
    #fazendo o relacionamento entre o usuario Django e o player
    #Docs: https://docs.djangoproject.com/en/1.4/topics/auth/#storing-additional-information-about-users
    user = models.OneToOneField(User)
    
    #campos que definem o player do jogo
    carteira = models.FloatField(default=0) #dinheiro na mao
    banco = models.FloatField(default=0) #dinheiro no banco
    
    ataque = models.PositiveSmallIntegerField(default=10)
    defesa = models.PositiveSmallIntegerField(default=10)
    vida = models.PositiveSmallIntegerField(default=10)
    energia = models.PositiveSmallIntegerField(default=20) #energia para fazer roubos
    raiva = models.PositiveSmallIntegerField(default=5) #raiiva para atacar outros players
    
    hp = models.PositiveIntegerField(default=100) #hp = vida * 10
    energia_atual = models.PositiveIntegerField(default=20)
    raiva_atual = models.PositiveIntegerField(default=5)
    
    nivel = models.PositiveSmallIntegerField(default=1)
    experiencia = models.PositiveIntegerField(default=0)
    
    hp_update = models.DateTimeField(auto_now_add=True) # 1 de hp a cada 2 minutos
    energia_update = models.DateTimeField(auto_now_add=True) # 1 de energia a cada minuto
    raiva_update = models.DateTimeField(auto_now_add=True) # 1 de raiva a cada 5 minutos

    #relacionamentos
    armas = models.ManyToManyField(Arma)
    armaduras = models.ManyToManyField(Armadura)

    #itens ativos
    arma_ativa = models.ForeignKey(Arma, null=True, related_name="+")
    armadura_ativa = models.ForeignKey(Armadura, null=True, related_name="+")


# funcao que cria o player toda vez que um usuario for criado pelo Django.contrib.auth
def cria_user_player(sender, instance, created, **kwargs):
    if created:
        Player.objects.create(user=instance)

#configurando o signal que detecta quando um usuario eh criado
#ao detectar, executa a funcao acima (cria_user_payer) para termos o
# "perfil" do jogador ligado ao usuario
# vide documentacao: https://docs.djangoproject.com/en/1.4/topics/auth/#storing-additional-information-about-users
post_save.connect(cria_user_player, sender=User) # USER = importado na linha 3

Vale a pena notar que, para os campos arma_ativa e armadura_ativa, o campo opicional related_name foi desativado (setado com o valor +).
Isso faz com que o Django não crie um relacionamento no sentido ao contrário. Ou seja, da tabela arma (ou armadura) para o usuário.

Por fim, basta atualizar o banco de dados.

python manage.py syncdb

O código do projeto até agora encontra-se aqui:
https://github.com/frenetic/django-wars

One thought on “Django Wars [Parte 13]: Associando players a armas e armaduras

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *