Files
44r0n7 0265afa054 chore: bootstrap lean sysadmin-chronicles repo
Import the runnable game code, content, docs, scripts, and repo guidance while leaving local agent state, dependency installs, build output, and backup copies out of the published tree.
2026-05-02 11:49:07 -04:00

98 lines
3.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# Save slot management for Sysadmin Chronicles.
# Source this file; do not execute directly.
SC_SAVE_DIR="${SC_SAVE_DIR:-$HOME/.local/share/sysadmin-chronicles/saves}"
_save_path() { printf '%s/%s.json' "$SC_SAVE_DIR" "$1"; }
_save_active_slot() {
local slot=""
if [ -f "$SC_SAVE_DIR/.active" ]; then
slot="$(cat "$SC_SAVE_DIR/.active")"
fi
printf '%s' "${slot:-autosave}"
}
_save_valid_slot() {
case "$1" in
autosave|slot-1|slot-2|slot-3) return 0 ;;
*) echo " ✗ Invalid slot name: $1 (use autosave, slot-1, slot-2, or slot-3)"; return 1 ;;
esac
}
_new_game_json() {
local slot="$1"
printf '{"slot":"%s","day":1,"trust":50,"questsCompleted":0,"quests":{},"flags":{},"inbox":[],"clock":{"shift":1,"day":1}}\n' \
"$slot"
}
save_list() {
mkdir -p "$SC_SAVE_DIR"
local active
active="$(_save_active_slot)"
printf ' %-14s %-10s %-10s %-10s\n' "Slot" "Day" "Trust" "Quests"
printf ' %-14s %-10s %-10s %-10s\n' "──────────────" "──────────" "──────────" "──────────"
local slot
for slot in autosave slot-1 slot-2 slot-3; do
local path
path="$(_save_path "$slot")"
if [ -f "$path" ]; then
local day trust quests marker=""
day="$( grep -o '"day":[0-9]*' "$path" 2>/dev/null | head -1 | cut -d: -f2 || echo '?')"
trust="$( grep -o '"trust":[0-9]*' "$path" 2>/dev/null | head -1 | cut -d: -f2 || echo '?')"
quests="$( grep -o '"questsCompleted":[0-9]*' "$path" 2>/dev/null | head -1 | cut -d: -f2 || echo '?')"
[ "$slot" = "$active" ] && marker=" [active]"
printf ' %-14s %-10s %-10s %-10s%s\n' "$slot" "Day $day" "T:$trust" "Q:$quests" "$marker"
else
printf ' %-14s %s\n' "$slot" "—empty—"
fi
done
}
save_switch() {
local slot="$1"
_save_valid_slot "$slot" || return 1
[ -f "$(_save_path "$slot")" ] || { echo " ✗ No save in slot: $slot"; return 1; }
printf '%s' "$slot" > "$SC_SAVE_DIR/.active"
echo " ✓ Switched to $slot"
}
save_new() {
local slot="$1"
_save_valid_slot "$slot" || return 1
mkdir -p "$SC_SAVE_DIR"
_new_game_json "$slot" > "$(_save_path "$slot")"
echo " ✓ Created new save: $slot"
}
save_reset() {
local slot="${1:-$(_save_active_slot)}"
_save_valid_slot "$slot" || return 1
mkdir -p "$SC_SAVE_DIR"
_new_game_json "$slot" > "$(_save_path "$slot")"
echo " ✓ Reset $slot to new game state"
}
save_export() {
local slot="$1"
local dest="$2"
_save_valid_slot "$slot" || return 1
[ -f "$(_save_path "$slot")" ] || { echo " ✗ No save in slot: $slot"; return 1; }
[ -n "$dest" ] || { echo " ✗ No destination path given"; return 1; }
cp "$(_save_path "$slot")" "$dest"
echo " ✓ Exported $slot$dest"
}
save_import() {
local src="$1"
local slot="$2"
_save_valid_slot "$slot" || return 1
[ -f "$src" ] || { echo " ✗ File not found: $src"; return 1; }
# Basic JSON sanity check
grep -q '^{' "$src" 2>/dev/null || { echo " ✗ File does not look like a save: $src"; return 1; }
mkdir -p "$SC_SAVE_DIR"
cp "$src" "$(_save_path "$slot")"
echo " ✓ Imported $src$slot"
}