109 lines
3.2 KiB
Bash
Executable File
109 lines
3.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Baut alle Ink-Dialoge zu .ink.json, die das Spiel lesen kann.
|
|
#
|
|
# Für die Autorin: Schreib deine Dialoge als .ink-Dateien in
|
|
# assets/interactions/
|
|
# und führ danach dieses Skript aus:
|
|
# ./tools/build-dialogues.sh
|
|
# Fertig — das Spiel liest die erzeugten .ink.json.
|
|
#
|
|
# Standardmäßig wird nur neu gebaut, was sich seit dem letzten Mal
|
|
# geändert hat. Mit -f / --force wird alles neu gebaut.
|
|
|
|
set -euo pipefail
|
|
|
|
# Repo-Wurzel relativ zum Skript bestimmen — egal, von wo aufgerufen.
|
|
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
root="$(cd "$script_dir/.." && pwd)"
|
|
ink_dir="$root/assets/interactions"
|
|
|
|
force=0
|
|
case "${1:-}" in
|
|
-f|--force) force=1 ;;
|
|
"") ;;
|
|
*) echo "Unbekannte Option: $1 (nur -f/--force)" >&2; exit 2 ;;
|
|
esac
|
|
|
|
# inklecate finden: $INKLECATE → mitgeliefertes tools/inklecate → PATH.
|
|
find_inklecate() {
|
|
if [ -n "${INKLECATE:-}" ] && [ -x "$INKLECATE" ]; then
|
|
echo "$INKLECATE"; return 0
|
|
fi
|
|
if [ -x "$script_dir/inklecate" ]; then
|
|
echo "$script_dir/inklecate"; return 0
|
|
fi
|
|
if command -v inklecate >/dev/null 2>&1; then
|
|
command -v inklecate; return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
if ! inklecate="$(find_inklecate)"; then
|
|
cat >&2 <<'EOF'
|
|
Fehler: inklecate nicht gefunden.
|
|
Lege das Linux-Binary nach tools/inklecate (chmod +x),
|
|
setze $INKLECATE auf den Pfad, oder installiere es in den PATH.
|
|
Quelle: https://github.com/inkle/ink/releases
|
|
EOF
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -d "$ink_dir" ]; then
|
|
echo "Kein Dialog-Ordner: $ink_dir" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Prüft eine .ink-Datei auf Zeichen außerhalb von CP437 und gibt sie aus.
|
|
# Exit-Code 1 wenn Treffer gefunden, sonst 0.
|
|
check_cp437() {
|
|
python3 - "$1" <<'PYEOF'
|
|
import sys
|
|
path = sys.argv[1]
|
|
cp437 = set(bytes(range(256)).decode('cp437', errors='replace'))
|
|
hits = []
|
|
with open(path, encoding='utf-8') as f:
|
|
for lineno, line in enumerate(f, 1):
|
|
for ch in line:
|
|
if ord(ch) > 127 and ch not in cp437:
|
|
hits.append(f' Z.{lineno}: U+{ord(ch):04X} {repr(ch)}')
|
|
for h in hits:
|
|
print(h)
|
|
sys.exit(1 if hits else 0)
|
|
PYEOF
|
|
}
|
|
|
|
built=0 skipped=0 failed=0
|
|
shopt -s nullglob
|
|
for src in "$ink_dir"/*.ink; do
|
|
out="${src%.ink}.ink.json"
|
|
name="$(basename "$src")"
|
|
|
|
# CP437-Warnung: läuft immer, unabhängig vom Build-Status.
|
|
if ! cp437_warn="$(check_cp437 "$src")"; then
|
|
printf ' WARNUNG %s -- Nicht-CP437-Zeichen:\n' "$name"
|
|
printf '%s\n' "$cp437_warn"
|
|
fi
|
|
|
|
# Inkrementell: überspringen, wenn Ausgabe existiert und neuer ist.
|
|
if [ "$force" -eq 0 ] && [ -f "$out" ] && [ "$out" -nt "$src" ]; then
|
|
printf ' aktuell %s\n' "$name"
|
|
skipped=$((skipped + 1))
|
|
continue
|
|
fi
|
|
|
|
# inklecate-Ausgabe einsammeln; nur bei Problemen/Warnungen zeigen.
|
|
if log="$("$inklecate" -o "$out" "$src" 2>&1)"; then
|
|
printf ' gebaut %s\n' "$name"
|
|
built=$((built + 1))
|
|
[ -n "$log" ] && printf '%s\n' "$log" | sed 's/^/ /'
|
|
else
|
|
printf ' FEHLER %s\n' "$name"
|
|
printf '%s\n' "$log" | sed 's/^/ /'
|
|
failed=$((failed + 1))
|
|
fi
|
|
done
|
|
|
|
echo "—— $built gebaut, $skipped aktuell, $failed fehlgeschlagen ——"
|
|
[ "$failed" -eq 0 ]
|