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
Agora é a hora boa, a hora que nosso site vai separar os meninos dos homens.
Os homens estão no trabalho e os meninos estão em casa atacando os coitados que estão ocupados…
Primeiro, a url que leva ao coro comer no centro.
url(r'^alvos/atacar/(\d+)/$', djangowars.views.luta.atacar),
Agora que vem a parte boa, a view que calcula o fight.
Vou colocá-la no arquivo views/luta.py:
#view da luta def atacar(request, alvo_id): if not request.user.is_authenticated(): return redirect('pagina_de_login') #verifica se esta sendo passado um alvo valido alvo = get_object_or_404(Player, pk=alvo_id) #pega o nosso jogador da sessao jogador = request.user.get_profile() #verifica se a experiencia do alvo eh menor que 60% da experiencia do atacante if jogador.experiencia * 0.6 > alvo.experiencia: return redirect(alvos) #atualiza o alvo e o jogador alvo.refresh() jogador.refresh() #verifica se o nosso jogador possui raiva para atacar if jogador.raiva_atual == 0: return redirect(alvos) #verifica se o nosso jogador esta "morto" if jogador.hp == 0: return redirect(alvos) #verifica se o alvo esta 'morto' if alvo.hp == 0: return redirect(alvos) #salva o hp inicial do jogador e do alvo para fazer um pequeno relatorio no final jogador_hp = jogador.hp alvo_hp = alvo.hp #pega o valor da arma do jogador if jogador.arma_ativa: jogador_arma = jogador.arma_ativa.poder else: jogador_arma = 1 #pega o valor da armadura do jogador if jogador.armadura_ativa: jogador_armadura = jogador.armadura_ativa.poder else: jogador_armadura = 1 #pega o valor da arma do alvo if alvo.arma_ativa: alvo_arma = alvo.arma_ativa.poder else: alvo_arma = 1 #pega o valor da armadura do alvo if alvo.armadura_ativa: alvo_armadura = alvo.armadura_ativa.poder else: alvo_armadura = 1 #agora o bicho vai pegar! #a luta dura 5 turnos for turno in [1, 2, 3, 4, 5]: #primeiro o jogador ataca ataque = randint(jogador.ataque/3, jogador.ataque) defesa = randint(alvo.defesa/3, alvo.defesa) #calcula o dano dano = ataque * jogador_arma - defesa * alvo_armadura if dano > 0: alvo.hp = alvo.hp - dano #agora o alvo ataca ataque = randint(alvo.ataque/3, alvo.ataque) defesa = randint(jogador.defesa/3, jogador.defesa) #calcula o dano dano = ataque * alvo_arma - defesa * jogador_armadura if dano > 0: jogador.hp = jogador.hp - dano #verifica se alguem morreu no combate if jogador.hp == 0 or alvo.hp == 0: break #descobrindo quem perdeu if jogador.hp == 0: vitoria = False elif alvo.hp == 0: vitoria = True elif alvo_hp - alvo.hp > jogador_hp - jogador.hp: vitoria = True else: vitoria = False #se o jogador ganhou, tira dinheiro do alvo e da ao jogador if vitoria: grana = alvo.carteira * ( randint(10, 90)/100.0 ) #entre 10% e 90% do valor da carteira grana = round(grana) alvo.carteira = alvo.carteira - grana jogador.carteira = jogador.carteira + grana #ganha 10% da experiencia do adversario jogador.experiencia = jogador.experiencia + alvo.experiencia * 0.1 else: grana = jogador.carteira * ( randint(10, 90)/100.0 ) #entre 10% e 90% do valor da carteira grana = round(grana) alvo.carteira = alvo.carteira + grana jogador.carteira = jogador.carteira - grana #ganha 10% da experiencia do adversario alvo.experiencia = alvo.experiencia + jogador.experiencia * 0.1 # o nosso atacante perde 1 de raiva jogador.raiva_atual = jogador.raiva_atual - 1 #verifica se alguem deu level up alvo.level_up() jogador.level_up() #salva todas as alteracoes no banco de dados alvo.save() jogador.save() #exibe o template com o resultado da luta return render_to_response("atacar.html", {"player": jogador, "vida": jogador.vida * 10, "alvo": alvo, "vitoria": vitoria, "grana": grana, "jogador_hp": jogador_hp, "alvo_hp": alvo_hp})
É grande, mas é bem fácil de compreender:
1 – a gente verifica se está sendo passado um jogador válido
2 – verifica se o alvo tem o mínimo de experiência requisitada. Assim, se algum jogador tentar criar uma URL na mão, não vai atacar um jogador mais fraco.
3 – verifica se tem raiva o suficiente para atacar
4 – verifica se nem o alvo e nem o jogador estão mortos. Morto não pode atacar e nem ser atacado, a não ser que sejam zumbis ou vampiros ou mumias.
5 – salva quanto de hp cada um tem antes de começar a luta. Fazemos isso para saber quem perdeu mais hp no final do combate.
6 – pegamos o poder da arma e da armadura do jogador e do alvo.
7 – pequeno loop da luta. as lutas duram 5 turnos
8 – verifica quem venceu. quem morrer, perde. quem perder mais hp, perde
9 – calcula a quantidade de dinheiro que o vencedor rouba do perdedor
10 – tira um ponto de raiva do atacante
11 – verifica se alguem deu level_up
12 – salva tudo
13 – exibe template.
O loop da luta é bem mobral.
Randomiza um número entre um terço do atributo ataque e o ataque inteiro e multiplica esse valor na arma.
Faz o mesmo para a defesa e multiplica o valor na armadura.
A diferença entre o resultado do ataque e o resultado da defesa é o dano que o atacante causa no defensor.
Sussa demais, né?
Eu poderia tentar algo mais parecido com sistemas de RPG de mesa, mas queremos um jogo simples.
Para finalizar, mostramos o template.
atacar.html
<div class="container"> <p> Informações do usuário: Nível {{ player.nivel }} | Energia {{ player.energia_atual }}/{{ player.energia }} | Raiva {{ player.raiva_atual }}/{{ player.raiva }} HP: {{ player.hp }}/{{ vida }} | Carteira {{ player.carteira }} </p> <!--lista de alvos--> Você atacou <b>{{ alvo.user.username }}</b><br /> Resultado da luta: {% if vitoria %}<b>VITÓRIA!</b>{% else %}<b>DERROTA!</b>{% endif %}<br /> Seu Hp inicial: <b>{{ jogador_hp }}</b>, Hp final: <b>{{ player.hp }}</b><br /> Hp inicial de {{ alvo.user.username }}: <b>{{ alvo_hp }}</b>, Hp final: <b>{{ alvo.hp }}</b><br /> {% if vitoria %} Você recebeu: <b>{{ grana }}</b><br /> {% else %} Você perdeu: <b>{{ grana }}</b><br /> {% endif %} </div> <!-- /container -->
O código fonte de toda essa gambiarra desse maravilhoso jogo encontra-se em:
https://github.com/frenetic/django-wars
Lá na linha 109 o certo é:
alvo_armadura = alvo.armadura_ativa.poder
Tá ficando massa!
na verdade, tá quase certo
na linha 109 era pra ser
alvo_arma = alvo.arma_ativa.poder
mas ao invés de escrever “alvo_arma” eu só escrevi “alvo”.
Que burro, dá zero pra mim…
Vou corrigir aqui no post e depois coloco no github
Na linha 155, o certo é:
elif alvo_hp – alvo.hp > jogador_hp – jogador.hp:
vitoria = True
else:
vitoria = False
OMG! :O
como que eu confundi saporra?
Corrigindo e colocando no GitHub 😀
As alterações foram feitas na postagem e no código lá no GitHub.
Valeu Diego!