# -*- coding: utf-8 -*-
"""Mede o tempo de respawn no oficial cruzando o fio com os postes do client.

A discriminacao e esta: quem NASCE aparece em cima do poste (as coordenadas exatas do
arquivo .npc); quem so entra no campo de visao aparece onde quer que estivesse a andar.
Assim da para separar um respawn de um reencontro sem ter de decifrar o pacote de morte.
"""
import sys, os, glob, re, struct, collections, math
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', 'server'))
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import data_files as D
from ler_hook import pacotes

MAPAS = r"C:\Games\Karos\ResUnpak\Map"
BLOCO, COLUNAS = 5120.0, 64
PERTO_DO_POSTE = 3.0        # unidades


def postes(prefixo='erneo'):
    D.carregar()
    cat = {int(r["npc_id"]): r for r in D.tabela("Npc")}
    saida = []
    for cam in glob.glob(os.path.join(MAPAS, "**", "*.npc"), recursive=True):
        base = os.path.basename(cam)[:-4]
        if prefixo not in base:
            continue
        m = re.match(r"(.+?)(\d+)$", base)
        if not m:
            continue
        bloco = int(m.group(2))
        d = open(cam, 'rb').read()
        o = 0
        while o < len(d) - 40:
            v = struct.unpack_from('<I', d, o)[0]
            if v in cat:
                x = struct.unpack_from('<f', d, o+4)[0]
                alt = struct.unpack_from('<f', d, o+8)[0]
                y = struct.unpack_from('<f', d, o+12)[0]
                if 0 <= x <= BLOCO*1.2 and 0 <= y <= BLOCO*1.2 and 0 < alt < 5000:
                    saida.append((v, (bloco % COLUNAS)*BLOCO + x, (bloco // COLUNAS)*BLOCO + y))
                    o += 4
                    continue
            o += 1
    return saida


def eventos(caminho):
    """(t, tipo, ent, npc, x, y) -- 'nasce/aparece' pelos 04 02 e 'anda' pelos 04 01."""
    ap, mv = [], []
    for t, op, c in pacotes(caminho):
        if op == b'\x04\x02' and len(c) >= 74:
            x, y, z = struct.unpack_from('<3f', c, 12)
            ap.append((t, struct.unpack_from('<I', c, 8)[0],
                       struct.unpack_from('<I', c, 70)[0], x, y))
        elif op == b'\x04\x01' and len(c) >= 24:
            mv.append((t, struct.unpack_from('>I', c, 8)[0]))
    return ap, mv
