# -*- coding: utf-8 -*-
"""Confere as formulas da ficha contra as 7 capturas de tela do servidor OFICIAL (nivel 1).

O jogo TRUNCA os inteiros e ARREDONDA os decimais na hora de desenhar, entao a comparacao
aceita as duas leituras.
"""
import sys
sys.path.insert(0, r"D:\RoshEmulator\server")
import db

# transcrito das capturas de tela do oficial, todos os personagens em nivel 1
FICHA = {
    100: dict(For=10, Des=7,  Vit=10, Int=7,  Sab=6, hp=190, mp=60,  reg_hp=13, reg_mp=1,
              evasao=6, bloqueio=8, atq_min=19, mais_min=3,  atq_max=25, mais_max=9,
              prot=67, mais_prot=46, mag_min=8,  mais_mag_min=0,  mag_max=8,  mais_mag_max=0,
              mag_prot=18, crit=5.2, mult=1.2, vel=0.91, arma=1001),
    200: dict(For=9,  Des=7,  Vit=10, Int=7,  Sab=7, hp=190, mp=91,  reg_hp=13, reg_mp=2,
              evasao=6, bloqueio=8, atq_min=14, mais_min=2,  atq_max=19, mais_max=8,
              prot=72, mais_prot=51, mag_min=9,  mais_mag_min=0,  mag_max=9,  mais_mag_max=0,
              mag_prot=19, crit=5.2, mult=1.2, vel=1.10, arma=5001),
    300: dict(For=7,  Des=11, Vit=6,  Int=8,  Sab=8, hp=150, mp=80,  reg_hp=10, reg_mp=2,
              evasao=7, bloqueio=9, atq_min=15, mais_min=4,  atq_max=17, mais_max=6,
              prot=63, mais_prot=42, mag_min=11, mais_mag_min=0,  mag_max=11, mais_mag_max=0,
              mag_prot=19, crit=7.1, mult=1.2, vel=1.57, arma=9001),
    400: dict(For=5,  Des=9,  Vit=7,  Int=10, Sab=9, hp=160, mp=90,  reg_hp=11, reg_mp=3,
              evasao=8, bloqueio=8, atq_min=11, mais_min=4,  atq_max=16, mais_max=9,
              prot=56, mais_prot=35, mag_min=27, mais_mag_min=8,  mag_max=39, mais_mag_max=20,
              mag_prot=19, crit=6.1, mult=1.2, vel=0.85, arma=15001),
    500: dict(For=9,  Des=10, Vit=7,  Int=8,  Sab=7, hp=160, mp=70,  reg_hp=11, reg_mp=2,
              evasao=7, bloqueio=8, atq_min=19, mais_min=8,  atq_max=25, mais_max=13,
              prot=58, mais_prot=37, mag_min=10, mais_mag_min=0,  mag_max=10, mais_mag_max=0,
              mag_prot=19, crit=6.6, mult=1.2, vel=0.78, arma=13001),
    600: dict(For=6,  Des=8,  Vit=6,  Int=11, Sab=9, hp=150, mp=90,  reg_hp=10, reg_mp=3,
              evasao=6, bloqueio=8, atq_min=11, mais_min=4,  atq_max=15, mais_max=9,
              prot=54, mais_prot=33, mag_min=30, mais_mag_min=8,  mag_max=35, mais_mag_max=13,
              mag_prot=19, crit=5.7, mult=1.2, vel=0.85, arma=16001),
    800: dict(For=10, Des=5,  Vit=9,  Int=7,  Sab=9, hp=189, mp=117, reg_hp=13, reg_mp=3,
              evasao=5, bloqueio=8, atq_min=20, mais_min=10, atq_max=28, mais_max=18,
              prot=58, mais_prot=37, mag_min=10, mais_mag_min=0,  mag_max=10, mais_mag_max=0,
              mag_prot=19, crit=4.3, mult=1.2, vel=0.62, arma=23001),
}

MAGICAS = (400, 600)


def formulas(f):
    """As formulas candidatas, todas a partir das cinco caracteristicas."""
    mag = (dict(int_=3.08, sab=0.48, base=-16.20) if f["_classe"] in MAGICAS
           else dict(int_=1.54, sab=0.48, base=-4.80))
    return {
        "reg_hp":   f["Vit"] * 0.75 + 6.25,
        "reg_mp":   f["Sab"] * 0.55 - 1.75,
        "evasao":   f["Des"] * 0.05 + 6.5,
        "bloqueio": f["Des"] * 0.1 + 8.0,
        "mag_prot": f["Sab"] * 0.3 + 17.0,
        "crit":     f["Des"] * 0.452 + 2.08,
        "atq_mag_base": f["Int"] * mag["int_"] + f["Sab"] * mag["sab"] + mag["base"],
    }


def ok_int(calc, mostrado):
    return int(calc) == mostrado or round(calc) == mostrado


def main():
    falhas = 0
    print("campo          " + " ".join(f"{c:>13}" for c in sorted(FICHA)))
    linhas = {}
    for cl, f in FICHA.items():
        f["_classe"] = cl
        a = db.atributos_do_item(f["arma"], 0)
        calc = formulas(f)
        res = {}
        for campo in ("reg_hp", "reg_mp", "evasao", "bloqueio", "mag_prot"):
            res[campo] = (calc[campo], f[campo], ok_int(calc[campo], f[campo]))
        res["crit"] = (calc["crit"], f["crit"], abs(round(calc["crit"], 1) - f["crit"]) < 0.051)
        # ataque fisico e magico: base + o que a arma soma (o jogo mostra o "(+N)")
        res["arma_fis_min"] = (a["dano_min"], f["mais_min"], ok_int(a["dano_min"], f["mais_min"]))
        res["arma_fis_max"] = (a["dano_max"], f["mais_max"], ok_int(a["dano_max"], f["mais_max"]))
        res["arma_mag_min"] = (a["dano_mag_min"], f["mais_mag_min"],
                               ok_int(a["dano_mag_min"], f["mais_mag_min"]))
        res["arma_mag_max"] = (a["dano_mag_max"], f["mais_mag_max"],
                               ok_int(a["dano_mag_max"], f["mais_mag_max"]))
        res["vel"] = (a["vel_ataque"], f["vel"], abs(round(a["vel_ataque"], 2) - f["vel"]) < 0.006)
        b = calc["atq_mag_base"]
        res["atq_mag_min"] = (b + a["dano_mag_min"], f["mag_min"],
                              ok_int(b + a["dano_mag_min"], f["mag_min"]))
        res["atq_mag_max"] = (b + a["dano_mag_max"], f["mag_max"],
                              ok_int(b + a["dano_mag_max"], f["mag_max"]))
        linhas[cl] = res
    for campo in linhas[100]:
        saida = []
        for cl in sorted(FICHA):
            v, esp, bom = linhas[cl][campo]
            if not bom:
                falhas += 1
            saida.append(f"{v:7.2f}/{esp:<3}{'ok' if bom else 'XX'}")
        print(f"{campo:14} " + " ".join(saida))
    print()
    print("FALHAS:", falhas, "de", len(linhas[100]) * 7)


if __name__ == "__main__":
    main()
