# -*- coding: utf-8 -*-
"""Ensaio do caminho completo do drop, sem client nem banco."""
import random
import sys
import time

sys.path.insert(0, "D:/RoshEmulator/server")
import entity_sim as E
import mundo


class JogadorFalso:
    def __init__(self, eid, nome, x, y):
        self.entity_id, self.nome = eid, nome
        self.x, self.y, self.z = x, y, 600.0
        self.recebido = []

    def enviar(self, frame):
        self.recebido.append(frame)
        return True


def op(frame):
    return "%02x %02x" % (frame[4], frame[5])


j = JogadorFalso(1000, "Testador", 8000.0, 6000.0)
mundo._jogadores[j.entity_id] = j          # entra no mundo sem socket

seq = [0]
def prox():
    seq[0] += 1
    return seq[0]

entregues = []
E.ENTREGAR_ITEM[0] = lambda jog, item, qtd: (entregues.append((item, qtd)) or True)

print("1. o monstro morre a 8010,6010 -- longe do jogador nao, perto")
sacos = E.largar(1001801, 8010.0, 6010.0, 600.0, dono=j.entity_id,
                 rnd=random.Random(3), log=print)
print("   sacos no chao: %d" % len(E.SACOS))
assert sacos, "a Aranha pequena devia largar alguma coisa com esta semente"

print()
print("2. um ciclo com o jogador longe (dentro da visao, fora do saque)")
j.x, j.y = 8200.0, 6200.0
j.recebido.clear()
E.rodar_sacos(prox, log=print)
print("   recebeu: %s" % [op(f) for f in j.recebido])
assert j.recebido and all(op(f) == "06 04" for f in j.recebido), "so devia ver os sacos aparecerem"
assert len(E.SACOS) == len(sacos), "nada devia ter sido apanhado a esta distancia"
assert not entregues

print()
print("3. o jogador CLICA no saco -- a recolha e a pedido, nao por proximidade")
# ATUALIZADO em 29/08. Este passo testava andar por cima e o saco vir sozinho. Deixou de ser
# assim: o jogador comparou com o oficial ("no nosso nao aparece essa mao pra coletar o
# item, ta coletando o carat so de chegar perto") e a recolha passou a ser o 06 03 que o
# client manda ao clicar. O teste seguia a implementacao velha e falhava por isso -- o codigo
# e que estava certo.
voltas = 0
while E.SACOS and voltas < 20:
    voltas += 1
    saco = next(iter(E.SACOS.values()))
    d = ((saco.x - j.x) ** 2 + (saco.y - j.y) ** 2) ** 0.5
    print("   saco %d esta a %.1f unidades -- a clicar nele" % (saco.id, d))
    j.recebido.clear()
    ok = E.apanhar_saco(saco.id, j, prox, log=print)
    print("   apanhou: %s   recebeu: %s" % (ok, [op(f) for f in j.recebido]))
    assert ok, "estava dentro do campo de visao, devia apanhar"
print("   sacos no chao: %d | entregue no inventario: %s" % (len(E.SACOS), entregues))
assert entregues, "devia ter apanhado"
assert not E.SACOS

print()
print("4. clicar num saco do outro lado do mapa NAO passa")
E.limpar_sacos()
longe = E.Saco(999999, 5, j.x + 5000.0, j.y, 0.0, dono=j.entity_id)
E.SACOS[longe.id] = longe
assert not E.apanhar_saco(longe.id, j, prox, log=print), "fora do campo de visao nao passa"
assert len(E.SACOS) == 1, "o saco tem de ficar no chao"
E.limpar_sacos()

print("5. saco de OUTRO dono nao pode ser apanhado")
E.largar(1001801, 8010.0, 6010.0, 600.0, dono=999999, rnd=random.Random(3), log=print)
antes = len(entregues)
for saco in list(E.SACOS.values()):
    E.apanhar_saco(saco.id, j, prox, log=print)
print("   sacos no chao: %d (devia continuar >0) | entregues novos: %d (devia ser 0)"
      % (len(E.SACOS), len(entregues) - antes))
assert E.SACOS and len(entregues) == antes

print()
print("6. e expira ao fim de %.0f s" % E.SEGUNDOS_SACO_NO_CHAO)
for s in E.SACOS.values():
    s.criado_em -= E.SEGUNDOS_SACO_NO_CHAO + 1
j.recebido.clear()
E.rodar_sacos(prox, log=print)
print("   sacos no chao: %d | recebeu: %s" % (len(E.SACOS), [op(f) for f in j.recebido]))
assert not E.SACOS

print()
print("TUDO PASSOU")
