# -*- coding: utf-8 -*-
r"""Lista as montarias e a velocidade que cada uma da.

    python tools/extrair_montarias.py  ->  server/Data/Items/Montaria.ini

SAO 100 ITENS, todos com o mesmo feitio: slot 6, categoria 6, tipo 1, e o modelo
`HAM_RIDER_NN._OB`. Trinta modelos diferentes. O mecanismo de montar nao olha ao item -- e
sempre o mesmo `03 02` com o modo 2 -- portanto as cem funcionam com uma implementacao so.

A VELOCIDADE ESTA NO itemAttr, no nono double (indice 8). Todas as 100 tem linha la.

    indice 6   proteccao fisica   entra ao EQUIPAR
    indice 7   proteccao magica   idem
    indice 8   velocidade de movimento, que so entra ao MONTAR

CONFERIDO CONTRA MEDICAO, na Phoenix (48019 e a versao cash 1000008860), que da [6]=70 e
[8]=90:

    equipar   a ficha do oficial mede proteccao fisica +70          bate com o [6]
    montar    o 08 02 passa de 71,5 para 99, e 90 x 1,10 = 99       bate com o [8]

(o +10% sao as botas do fato cash, medidas no mesmo dia; ver a seccao 43 dos achados.)

A DESCRICAO NAO SERVE, e foi por onde se comecou: so 23 das 100 dizem a velocidade, com tres
redaccoes diferentes ("em", "por"), e TRES ESTAO ERRADAS -- os tres dragoes (48010, 48011,
48012) anunciam 80 e a tabela diz 90. O client mostra o que a tabela diz. Uma primeira
versao desta ferramenta lia o texto e teria posto 79 montarias a velocidade base e tres com
o numero errado.

O MODELO TAMBEM NAO SERVE de chave, que era a outra saida obvia: o `HAM_RIDER_02` aparece
com 75 numas e 80 noutras. E por item.
"""
import io
import os
import struct
import sys

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

PASTA = r"C:\Games\Axion\ResUnpak\Interface\IE_Lod"
FIXO, N_STR = 116, 2          # 3 u32 + 13 doubles, e depois duas strings
I_PROT_FIS, I_PROT_MAG, I_VELOCIDADE = 6, 7, 8


def atributos():
    """{item_id: (13 doubles,)} do itemAttr, primeira linha de cada item.

    A entrada e por (item, refino, estrela); guarda-se a primeira, que e o refino zero.
    """
    d = L.decrypt_lod_stream(open(os.path.join(PASTA, "itemAttr.lod_pt"), "rb").read(),
                             pular_zero=False)
    versao, total = struct.unpack_from("<II", d, 0)
    if versao != 20101118:
        raise SystemExit("itemAttr com versao inesperada: %d" % versao)
    saida, pos = {}, 8
    for _ in range(total):
        if pos + FIXO > len(d):
            break
        item_id = struct.unpack_from("<I", d, pos)[0]
        vals = struct.unpack_from("<13d", d, pos + 12)
        pos += FIXO
        for _k in range(N_STR):
            (t,) = struct.unpack_from("<I", d, pos)
            pos += 4 + t
        saida.setdefault(item_id, vals)
    return saida


def main() -> int:
    attr = atributos()
    mont = [l for l in data_files.tabela("Item")
            if "RIDER" in str(l.get("modelo") or "").upper()]
    nl, tb = chr(10), chr(9)
    destino = os.path.join(RAIZ, "server", "Data", "Items", "Montaria.ini")
    sem_linha = 0
    with io.open(destino, "w", encoding="utf-8", newline="") as f:
        f.write("; Montaria -- os itens que se montam com a tecla V." + nl)
        f.write("; Gerado por tools/extrair_montarias.py. A velocidade sai do itemAttr" + nl)
        f.write("; (nono double), NAO do texto da descricao, que so 23 das 100 trazem e" + nl)
        f.write("; que nos tres dragoes esta errado. Ver o cabecalho da ferramenta." + nl)
        f.write("; prot_fis e prot_mag entram ao EQUIPAR; velocidade so ao MONTAR." + nl)
        f.write(tb.join(["//item_id", "velocidade", "prot_fis", "prot_mag",
                         "modelo", "nome"]) + nl)
        for l in sorted(mont, key=lambda x: int(x["item_id"])):
            i = int(l["item_id"])
            v = attr.get(i)
            if v is None:
                sem_linha += 1
                continue
            f.write(tb.join([str(i), "%g" % v[I_VELOCIDADE], "%g" % v[I_PROT_FIS],
                             "%g" % v[I_PROT_MAG], str(l.get("modelo") or ""),
                             str(l.get("nome") or "").replace(tb, " ")]) + nl)
    print("montarias: %d, escritas: %d" % (len(mont), len(mont) - sem_linha))
    if sem_linha:
        print("sem linha no itemAttr: %d" % sem_linha)
    print("escrito em %s" % os.path.normpath(destino))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
