39 lines
2.0 KiB
Python
39 lines
2.0 KiB
Python
# -*- coding: utf-8 -*-
|
||
# 길 중심선에서 가까운 막는 소품을 뽑는다 — 길 폭이 좁아진 까닭을 찾는다.
|
||
# python route_blockers.py <맵 이름> <길 이름에 든 글자> [거리 m]
|
||
import io, json, math, os, sys
|
||
root = r"C:\BurningTimes\FirstRising"
|
||
name, key = sys.argv[1], sys.argv[2]
|
||
lim = float(sys.argv[3]) if len(sys.argv) > 3 else 3.2
|
||
d = json.loads(io.open(os.path.join(root, "Assets/BurningTimes/Maps/%s/%s.map.json" % (name, name)), encoding="utf-8-sig").read())
|
||
items = json.loads(io.open(os.path.join(root, "Logs", "bt_map_%s_props.json" % name.lower()), encoding="utf-8-sig").read())
|
||
items = (items.get("props") or items.get("items")) if isinstance(items, dict) else items
|
||
def seg_rect(ax, az, bx, bz, it, hx, hz):
|
||
best = 1e9
|
||
n = max(2, int(math.hypot(bx - ax, bz - az) / 0.5))
|
||
for t in range(n + 1):
|
||
px, pz = ax + (bx - ax) * t / n, az + (bz - az) * t / n
|
||
dx = max(abs(it["x"] - px) - hx, 0.0); dz = max(abs(it["z"] - pz) - hz, 0.0)
|
||
best = min(best, math.hypot(dx, dz))
|
||
return best
|
||
for r in d["routes"]:
|
||
if key not in r["name"]:
|
||
continue
|
||
pts = r["pts"]
|
||
hits = []
|
||
for it in items:
|
||
how = it.get("how", "")
|
||
if not how.startswith("block"):
|
||
continue
|
||
if how == "block-trunk":
|
||
hx = hz = max(0.28, min(0.7, min(it["sx"], it["sz"]) * 0.12))
|
||
else:
|
||
hx, hz = max(it["sx"] * 0.34, 0.25), max(it["sz"] * 0.34, 0.25)
|
||
best = min(seg_rect(pts[k], pts[k + 1], pts[k + 2], pts[k + 3], it, hx, hz) for k in range(0, len(pts) - 3, 2))
|
||
if best < lim:
|
||
hits.append((best, it))
|
||
hits.sort(key=lambda h: h[0])
|
||
print("길 '%s' 반폭 %.1f — 중심선에서 %.1f m 안의 막는 소품 %d" % (r["name"], r["half"], lim, len(hits)))
|
||
for best, it in hits[:12]:
|
||
print(" %-40s (%.1f, %.1f) 크기 %.1f × %.1f × %.1f · 중심선까지 %.1f m" % (it["name"], it["x"], it["z"], it["sx"], it["sy"], it["sz"], best))
|