134 lines
2.4 KiB
Plaintext
134 lines
2.4 KiB
Plaintext
|
#!/bin/bash
|
||
|
|
||
|
if [ $# -lt 1 ]; then
|
||
|
echo "Usage: $0 SCENEID" >&2
|
||
|
exit 1
|
||
|
fi
|
||
|
|
||
|
mypath="$( dirname $0 )"
|
||
|
sceneid="$1"
|
||
|
scenepath="$mypath/../scenes/$sceneid"
|
||
|
scene="$( < "$scenepath" )"
|
||
|
|
||
|
spacecont="[Press Space to continue]"
|
||
|
setval="$mypath/setval"
|
||
|
getval="$mypath/getval"
|
||
|
|
||
|
getconf()
|
||
|
{
|
||
|
grep -m 1 "^$1=" <<< "$cdata" \
|
||
|
| cut -d'=' -f2
|
||
|
}
|
||
|
|
||
|
setscene()
|
||
|
{
|
||
|
$setval _scene $1
|
||
|
}
|
||
|
|
||
|
parsevals()
|
||
|
{
|
||
|
local data=$( cat )
|
||
|
local vals=$( grep -o '%[a-zA-Z0-9]\+%' <<< "$data" )
|
||
|
|
||
|
local replace=''
|
||
|
for val in $vals; do
|
||
|
result=$( $getval $( sed 's/^%\|%$//g' <<< "$val" ) 2>/dev/null )
|
||
|
replace="$replace;s/$val/$result/"
|
||
|
done
|
||
|
|
||
|
sed "$replace" <<< "$data"
|
||
|
echo
|
||
|
}
|
||
|
|
||
|
if [ ! -r "$scenepath" ]; then
|
||
|
echo "Scene not found" >&2
|
||
|
exit 2
|
||
|
fi
|
||
|
|
||
|
# all configuration options appear before the first empty line
|
||
|
cdata=$(
|
||
|
awk '/^$/ { stop=1 } { if ( !stop ) print }' \
|
||
|
<<< "$scene"
|
||
|
)
|
||
|
|
||
|
type="$( getconf type )"
|
||
|
nextscene="$( getconf next )"
|
||
|
|
||
|
# clear the screen to prepare to render the scene
|
||
|
clear
|
||
|
|
||
|
# output the story, as identified by the STORY line, using a pager (less) in the
|
||
|
# event that the page is too long for the terminal
|
||
|
awk '/STORY/ {
|
||
|
found=1;
|
||
|
getline
|
||
|
}
|
||
|
{ if ( found ) print }
|
||
|
END { print "" }
|
||
|
' <<< "$scene" \
|
||
|
| parsevals \
|
||
|
| less -EF
|
||
|
|
||
|
inputs=$(
|
||
|
awk '/INPUT/,/^$/ {
|
||
|
if ( ! $0 ) {
|
||
|
print ""
|
||
|
} else {
|
||
|
printf "%s ", $0
|
||
|
}
|
||
|
}
|
||
|
' <<< "$scene"
|
||
|
)
|
||
|
IFS="
|
||
|
"
|
||
|
for inline in $inputs; do
|
||
|
dest="$( cut -d' ' -f2 <<< "$inline" )"
|
||
|
text="$( cut -d' ' -f3- <<< "$inline" )"
|
||
|
|
||
|
echo "$text"
|
||
|
echo
|
||
|
|
||
|
input=''
|
||
|
while [ ! "$input" ]; do
|
||
|
read -p '> ' input
|
||
|
done
|
||
|
|
||
|
$setval "$dest" "$input"
|
||
|
done
|
||
|
|
||
|
# input handling is defined by the scene type
|
||
|
case "$type" in
|
||
|
action)
|
||
|
read -p '> ' input
|
||
|
;;
|
||
|
|
||
|
trans|transition)
|
||
|
read -s -d ' ' -p "$spacecont"
|
||
|
echo
|
||
|
;;
|
||
|
|
||
|
end)
|
||
|
read -s -d ' ' -p '[Press Space to end]'
|
||
|
exit 100
|
||
|
;;
|
||
|
|
||
|
input)
|
||
|
# input should have already been done
|
||
|
;;
|
||
|
|
||
|
*)
|
||
|
echo "WARNING: Unknown scene type: $type" >&2
|
||
|
read -s -d ' '
|
||
|
;;
|
||
|
esac
|
||
|
|
||
|
# if no next scene was provided, then there's nothing we can do
|
||
|
if [ ! "$nextscene" ]; then
|
||
|
setscene err-scene
|
||
|
exit 1
|
||
|
fi
|
||
|
|
||
|
# set the next scene (this is persistent, allowing the user to quit at any time)
|
||
|
setscene "$nextscene"
|
||
|
|