BurningTimesAi/공유/기획/FirstRising/맵/tools/shot_spots.py

41 lines
2.0 KiB
Python

# -*- coding: utf-8 -*-
# 맵마다 새 소품(FRProp_)이 모인 자리를 골라 촬영 자리 목록을 만든다 — 빌더가 남긴 소품 기록(_props.json)을 읽는다.
# python shot_spots.py <맵 이름> [자리 수] → 한 줄에 "번호 x z 가까운 새 소품들"
# 숲(로비) 맵은 이름을 Forest 로 주면 Logs/bt_forest_props.txt 에서 읽는다.
import io, json, math, os, re, sys
root = r"C:\BurningTimes\FirstRising"
name = sys.argv[1]
want = int(sys.argv[2]) if len(sys.argv) > 2 else 5
pts = []
if name == "Forest":
for line in io.open(os.path.join(root, "Logs", "bt_forest_props.txt"), encoding="utf-8"):
m = re.match(r"\s+(\w+) \((-?[\d.]+), (-?[\d.]+)\) 높이", line)
if m:
pts.append((m.group(1), float(m.group(2)), float(m.group(3))))
else:
rec = json.loads(io.open(os.path.join(root, "Logs", "bt_map_%s_props.json" % name.lower()), encoding="utf-8-sig").read())
items = (rec.get("props") or rec.get("items")) if isinstance(rec, dict) else rec
for it in items:
if it["name"].startswith("FRProp_"):
pts.append((it["name"].split("_", 2)[2], it["x"], it["z"]))
left = list(pts)
out = []
while left and len(out) < want:
# 둘레 9 m 안에 새 소품이 가장 많은 것을 고른다
best, score = None, -1
for p in left:
near = [q for q in left if math.hypot(q[1] - p[1], q[2] - p[2]) < 9.0]
kinds = len({q[0] for q in near})
s = len(near) + kinds * 1.5
if s > score:
best, score = p, s
near = [q for q in left if math.hypot(q[1] - best[1], q[2] - best[2]) < 9.0]
cx = sum(q[1] for q in near) / len(near)
cz = sum(q[2] for q in near) / len(near)
# 카메라는 +z 쪽에서 내려다본다 — 소품이 화면 가운데보다 조금 위에 오게 선 자리를 +z 로 2.5 m 당긴다
out.append((cx, cz + 2.5, sorted({q[0] for q in near})))
left = [q for q in left if math.hypot(q[1] - cx, q[2] - cz) >= 16.0]
for i, (x, z, names) in enumerate(out):
print("%d %.1f %.1f %s" % (i + 1, x, z, ",".join(names)))