6f8b599629
- execution_parser.py: 解析关卡执行案Markdown提取区域/结构体/布景/边界/光照 - asset_expander.py: BSP资产建议展开+绝对坐标计算+旋转推断 - guide_writer.py: 生成精确匹配build_guide_parser格式的搭建指南 - composite_writer.py: 组合资产清单+JSON模板生成 - converter.py: 主入口CLI工具 - 更新level-execution-template.md: 移除交互物/收集品章节,新增组合资产标记 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
119 lines
3.9 KiB
Python
119 lines
3.9 KiB
Python
"""执行案 → 搭建指南 转换器(主入口)。
|
||
|
||
用法:
|
||
python -m execution_to_guide.converter -i <执行案.md> [-o <搭建指南.md>]
|
||
|
||
示例:
|
||
python converter.py -i docs/design/关卡-v01-城郊小街-执行案.md -o docs/technical/关卡-v01-搭建指南.md
|
||
python converter.py -i docs/design/关卡-v01-城郊小街-执行案.md # 自动推断输出路径
|
||
"""
|
||
|
||
import argparse
|
||
import logging
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
from execution_parser import ExecutionPlanParser
|
||
from guide_writer import GuideWriter
|
||
|
||
logging.basicConfig(
|
||
level=logging.INFO,
|
||
format="%(name)s: %(message)s",
|
||
)
|
||
logger = logging.getLogger("execution_to_guide")
|
||
|
||
|
||
def convert(input_path: str, output_path: str = None) -> str:
|
||
"""将执行案转换为搭建指南。
|
||
|
||
Args:
|
||
input_path: 执行案 Markdown 文件路径
|
||
output_path: 搭建指南输出路径(可选,默认自动推断)
|
||
|
||
Returns:
|
||
生成的搭建指南 Markdown 内容
|
||
"""
|
||
# 解析执行案
|
||
logger.info(f"解析执行案: {input_path}")
|
||
parser = ExecutionPlanParser()
|
||
plan_data = parser.parse_file(input_path)
|
||
|
||
logger.info(f"场景: {plan_data.scene_name} v{plan_data.version}")
|
||
logger.info(f"尺寸: {plan_data.scene_size[0]}×{plan_data.scene_size[1]}cm")
|
||
logger.info(f"区域: {len(plan_data.zones)} 个")
|
||
logger.info(f"结构体: {sum(len(v) for v in plan_data.zone_structures.values())} 条")
|
||
logger.info(f"布景物: {sum(len(v) for v in plan_data.zone_props.values())} 条")
|
||
logger.info(f"组合资产: {sum(len(v) for v in plan_data.zone_composites.values())} 条")
|
||
logger.info(f"全局物件: {len(plan_data.global_objects)} 条")
|
||
logger.info(f"边界: {len(plan_data.boundaries)} 段")
|
||
|
||
# 生成搭建指南
|
||
writer = GuideWriter(plan_data)
|
||
content = writer.generate()
|
||
|
||
# 输出文件
|
||
if output_path is None:
|
||
# 自动推断:docs/design/关卡-v01-xxx-执行案.md → docs/technical/关卡-v01-搭建指南.md
|
||
in_path = Path(input_path)
|
||
version = plan_data.version
|
||
out_dir = in_path.parent.parent / "technical"
|
||
out_dir.mkdir(parents=True, exist_ok=True)
|
||
output_path = str(out_dir / f"关卡-{version}-搭建指南.md")
|
||
|
||
writer.write_to_file(output_path)
|
||
logger.info(f"搭建指南已输出: {output_path}")
|
||
|
||
# 统计
|
||
total_actors = len(writer.all_actors)
|
||
unique_assets = len(writer.asset_refs)
|
||
logger.info(f"生成 Actor: {total_actors} 个,使用资产: {unique_assets} 种")
|
||
|
||
# 如果有组合资产,提示
|
||
total_composites = sum(len(v) for v in plan_data.zone_composites.values())
|
||
if total_composites > 0:
|
||
logger.warning(f"⚠️ 发现 {total_composites} 个组合资产需要手动展开或确认拼搭方案")
|
||
|
||
return content
|
||
|
||
|
||
def main():
|
||
parser = argparse.ArgumentParser(
|
||
description="关卡执行案 → 搭建指南 转换器",
|
||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||
epilog="""
|
||
示例:
|
||
python -m execution_to_guide.converter -i docs/design/关卡-v01-城郊小街-执行案.md
|
||
python converter.py -i docs/design/关卡-v01-城郊小街-执行案.md -o output/指南.md
|
||
""",
|
||
)
|
||
parser.add_argument(
|
||
"-i", "--input", required=True,
|
||
help="关卡执行案 Markdown 文件路径"
|
||
)
|
||
parser.add_argument(
|
||
"-o", "--output", default=None,
|
||
help="搭建指南输出路径(默认自动推断到 docs/technical/)"
|
||
)
|
||
parser.add_argument(
|
||
"-v", "--verbose", action="store_true",
|
||
help="显示详细日志"
|
||
)
|
||
|
||
args = parser.parse_args()
|
||
|
||
if args.verbose:
|
||
logging.getLogger().setLevel(logging.DEBUG)
|
||
|
||
try:
|
||
convert(args.input, args.output)
|
||
except FileNotFoundError as e:
|
||
logger.error(f"文件未找到: {e}")
|
||
sys.exit(1)
|
||
except Exception as e:
|
||
logger.error(f"转换失败: {e}")
|
||
raise
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|