# -*- coding: utf-8 -*-
"""Ensaio dos itens de missao: so caem a quem tem a missao, e vao direto a mochila.

    python tools/teste_drop_missao.py

Nao precisa de client nem de banco.
"""
import os
import random
import sys

RAIZ = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(RAIZ, "server"))
import data_files as D                                              # noqa: E402
import entity_sim as E                                              # noqa: E402

D.carregar()
itens = dict((r["item_id"], str(r.get("nome") or "")) for r in D.tabela("Item"))
mobs = dict((r["mob_id"], str(r.get("nome") or "")) for r in D.tabela("Mob"))

# Uma missao de recolha real da tabela, para o ensaio nao depender de dados inventados.
alvo = None
for r in D.tabela("QuestDrop"):
    if r.get("quest_id") and r.get("mob_id") in mobs:
        alvo = r
        break
if alvo is None:
    raise SystemExit("QuestDrop.ini vazio -- corre tools/importar_drop_missao.py --aplicar")

MOB, ITEM, QUEST = alvo["mob_id"], alvo["item_id"], alvo["quest_id"]
print("missao de ensaio: %s larga %s (missao %s, chance %s%%)"
      % (mobs.get(MOB, "?"), itens.get(ITEM, "?"), QUEST, alvo.get("chance")))
print()

rnd = random.Random(4)

print("1. SEM a missao aceite -- 3000 abates")
n = sum(len(E.sortear_drop_missao(MOB, set(), rnd)) for _ in range(3000))
print("   itens de missao largados: %d" % n)
assert n == 0, "sem missao nao pode cair nada"

print()
print("2. COM a missao aceite -- 3000 abates")
n = sum(len(E.sortear_drop_missao(MOB, {QUEST}, rnd)) for _ in range(3000))
print("   itens de missao largados: %d  (%.0f%%, a tabela diz %s%%)"
      % (n, 100.0 * n / 3000, alvo.get("chance")))
assert n > 0

print()
print("3. com OUTRA missao aceite (nao esta) -- 3000 abates")
n = sum(len(E.sortear_drop_missao(MOB, {QUEST + 999999}, rnd)) for _ in range(3000))
print("   itens de missao largados: %d" % n)
assert n == 0, "so a missao certa deve fazer cair"

print()
print("4. a taxa drop_missao do Rate.ini desliga tudo")
r = D.indice("Rate", "codigo")["drop_missao"]
antes = r["multiplicador"]
r["multiplicador"] = 0.0
n = sum(len(E.sortear_drop_missao(MOB, {QUEST}, rnd)) for _ in range(3000))
r["multiplicador"] = antes
print("   com drop_missao=0.000: %d   (de volta a %.3f)" % (n, antes))
assert n == 0

print()
print("5. o DropPermitido NAO bloqueia item de missao")
print("   filtro do saque geral: %s" % E.itens_permitidos())
print("   e mesmo assim o item %d cai: %s"
      % (ITEM, bool(E.sortear_drop_missao(MOB, {QUEST}, random.Random(1)) or
                    E.sortear_drop_missao(MOB, {QUEST}, random.Random(2)))))

print()
print("6. e NAO passa pelo chao -- o largar() nunca cria saco de item de missao")
E.limpar_sacos()
for _ in range(200):
    E.largar(MOB, 100.0, 100.0, 0.0, rnd=rnd, log=lambda *a: None, nivel_jogador=10)
dos_sacos = set(s.item_id for s in E.SACOS.values())
print("   itens que foram para o chao em 200 abates: %s"
      % sorted(itens.get(i, i) for i in dos_sacos))
assert ITEM not in dos_sacos, "item de missao nao pode aparecer no chao"
E.limpar_sacos()

print()
print("TUDO PASSOU")
