#!/usr/bin/env bash # 自动生成一个新世界并导出 legends 数据。 # # scripts/make-world.sh [世界大小档位] [历史年数档位] # 世界大小:0=Pocket 1=Smaller 2=Small 3=Medium 4=Large (默认 3 = Medium) # 历史长度:0=5年 1=50年 2=100年 3=250年 4=500年 (默认 3 = 250 年) # # 前置:游戏已启动到标题界面(Dwarf Fortress.exe,DFHack 已通过 dfhooks 注入)。 # 原理:全程用 hack/dfhack-run.exe 从外部驱动,不依赖人工点击: # 1. 文本截图定位按钮(scripts/df-screen.py) # 2. 模拟鼠标点击 / 直接改内存里的世界生成参数 # 3. 用 DFHack 的 open-legends 原语进入 legends 模式 # 4. 点 "Export XML" 导出原生 legends.xml,并跑 exportlegends 导出扩展数据 set -euo pipefail WIN_USER="${WIN_USER:-23518}" DF_DIR="${DF_DIR:-/mnt/c/Users/${WIN_USER}/DwarfFortress}" HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" RUN="$DF_DIR/hack/dfhack-run.exe" WORLD_SIZE="${1:-3}" HISTORY="${2:-3}" [[ -x "$RUN" ]] || { echo "找不到 dfhack-run.exe:$RUN" >&2; exit 1; } cd "$DF_DIR" say() { echo "[$(date +%H:%M:%S)] $*"; } probe() { timeout 30 "$RUN" dfannals/probe >/dev/null 2>&1 || true; head -1 dfannals-probe.txt | cut -d= -f2; } shot() { timeout 60 "$RUN" dfannals/screentext >/dev/null 2>&1; } click_text() { # click_text <文字> [标签] local coord coord=$(python3 "$HERE/scripts/df-screen.py" click ${2:+--label "$2"} --text "$1") say "点击「$1」@ $coord" timeout 30 "$RUN" dfannals/click $coord >/dev/null 2>&1 } say "当前界面:$(probe)" [[ "$(probe)" == title* ]] || { echo "请先把游戏停在标题界面" >&2; exit 1; } say "—— 进入世界创建" shot; click_text "Create new world" sleep 3 say "—— 设定参数:大小档 $WORLD_SIZE / 历史档 $HISTORY" timeout 30 "$RUN" dfannals/setparams "$WORLD_SIZE" "$HISTORY" >/dev/null 2>&1 cat dfannals-params.txt say "—— 开始生成(Medium+250 年实测约 7 分钟)" shot; click_text "Create world" for _ in $(seq 1 60); do sleep 30 shot if ! grep -q "Recounting legends" dfannals-screen.txt && ! grep -q "Generating world" dfannals-screen.txt; then say "地形与历史生成结束" break fi say " 生成中… 年份 $(grep current_year dfannals-probe.txt | cut -d= -f2)" done grep -m1 -oE "year [0-9]+" dfannals-screen.txt || true say "—— 保存世界并回到主菜单" shot; click_text "Keep world and return to main menu" for _ in $(seq 1 30); do sleep 20 [[ "$(probe)" == export_region ]] || break done say "存档完成,当前界面:$(probe)" say "—— 进入 legends 模式" timeout 40 "$RUN" dfannals/legends >/dev/null 2>&1 sleep 4 [[ "$(probe)" == legends* ]] || { echo "未能进入 legends,界面=$(probe)" >&2; exit 1; } say "—— 导出(原生 Export XML + 扩展数据)" shot; click_text "Export XML" for _ in $(seq 1 60); do sleep 20 n=$(ls -1 region*-legends.xml 2>/dev/null | wc -l) if [ "$n" -gt 0 ]; then a=$(stat -c%s "$(ls -1t region*-legends.xml | head -1)" 2>/dev/null || echo 0) sleep 20 b=$(stat -c%s "$(ls -1t region*-legends.xml | head -1)" 2>/dev/null || echo 0) [ "$a" = "$b" ] && { say "legends.xml 已停止增长($b 字节),导出完成"; break; } fi say " 导出中…" done EXPORTS="$HERE/data/exports" mkdir -p "$EXPORTS" cp -v region*-legends.xml region*-world_history.txt region*-world_sites_and_pops.txt "$EXPORTS"/ 2>/dev/null | tail -5 say "导出文件已复制到 $EXPORTS" say "接下来跑:python3 -m dfannals.cli run"