2011-08-22 00:36:27 -04:00
|
|
|
#!/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()
|
|
|
|
{
|
2011-08-22 17:10:10 -04:00
|
|
|
grep -m 1 "^$1 " <<< "$cdata" \
|
|
|
|
| cut -d' ' -f2-
|
2011-08-22 00:36:27 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
setscene()
|
|
|
|
{
|
|
|
|
$setval _scene $1
|
|
|
|
}
|
|
|
|
|
|
|
|
parsevals()
|
|
|
|
{
|
|
|
|
local data=$( cat )
|
|
|
|
local vals=$( grep -o '%[a-zA-Z0-9]\+%' <<< "$data" )
|
2011-08-22 17:34:05 -04:00
|
|
|
local pre=$1
|
|
|
|
local post=$2
|
2011-08-22 00:36:27 -04:00
|
|
|
|
|
|
|
local replace=''
|
|
|
|
for val in $vals; do
|
|
|
|
result=$( $getval $( sed 's/^%\|%$//g' <<< "$val" ) 2>/dev/null )
|
2011-08-22 17:34:05 -04:00
|
|
|
replace="$replace;s/$val/$pre$result$post/"
|
2011-08-22 00:36:27 -04:00
|
|
|
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"
|
|
|
|
)
|
|
|
|
|
2011-08-22 17:10:10 -04:00
|
|
|
type="$( getconf TYPE )"
|
|
|
|
nextscene="$( getconf NEXT )"
|
2011-08-22 00:36:27 -04:00
|
|
|
|
|
|
|
# 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
|
|
|
|
|
2011-08-22 17:34:05 -04:00
|
|
|
|
|
|
|
branches=$( awk '/^BRANCH /' <<< "$scene" | parsevals \" \" )
|
|
|
|
IFS="
|
|
|
|
"
|
|
|
|
for branch in $branches; do
|
|
|
|
dest=$( cut -d' ' -f2 <<< "$branch" )
|
|
|
|
teststr=$( cut -d' ' -f3- <<< "$branch" )
|
|
|
|
|
|
|
|
eval test $teststr && {
|
|
|
|
nextscene="$dest"
|
|
|
|
|
|
|
|
# don't check any other branches
|
|
|
|
break
|
|
|
|
}
|
|
|
|
done
|
|
|
|
|
2011-08-22 00:36:27 -04:00
|
|
|
# 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"
|
|
|
|
|