2023-11-05 21:51:14 -05:00
#!/usr/bin/env bash
2024-08-20 01:34:11 -04:00
launch_game( ) {
pushd " ${ doomPath } "
exec stdbuf -oL ${ gzdoom } ${ @ } | speak
popd
}
speak( ) {
startSpeech = 1
while IFS = read -r line; do
echo " $line "
if [ [ $startSpeech -eq 1 ] ] && [ [ " $line " = ~ ^-{ 5,} $ ] ] ; then
startSpeech = 0
continue
fi
if [ [ $startSpeech -eq 0 ] ] ; then
2024-08-26 04:19:50 -04:00
line = $( echo " ${ line } " |
2024-08-20 01:34:11 -04:00
grep " ${ antiGrepStrings [@] } " |
2024-08-26 04:19:50 -04:00
sed " ${ sedStrings [@] } " )
if [ [ " $doomLanguage " != "en" ] ] ; then
line = $( translate_text " $line " )
fi
echo " ${ line } " | spd-say -e ${ spd_module } ${ spd_pitch } ${ spd_rate } ${ spd_voice } ${ spd_volume } -- > /dev/null 2>& 1;
2024-08-20 01:34:11 -04:00
fi
done
}
2023-11-10 01:57:27 -05:00
# Dialog setup:
DIALOG_ITEM_HELP = ""
export DIALOGOPTS = '--no-lines --visit-items'
2023-11-05 21:51:14 -05:00
2023-11-05 21:54:46 -05:00
2024-07-31 02:18:36 -04:00
# Toby games path
2024-08-11 13:39:41 -04:00
export gamePath = ~/.local/games/doom
2023-11-05 21:51:14 -05:00
# Path where doom wads are stored
2024-04-15 20:33:58 -04:00
export doomPath = " $( find /usr/share -type d -name "doom" 2> /dev/null | head -1) "
2023-11-05 21:51:14 -05:00
2024-08-11 19:51:00 -04:00
# Path to gzdoom or yadoom.
if [ [ -x "yadoom" ] ] ; then
export gzdoom = $( readlink -f "yadoom" )
else
export gzdoom = " $( command -v gzdoom) "
fi
2023-11-05 21:51:14 -05:00
# Version of the accessibility mod
2024-08-08 23:59:36 -04:00
export tobyVersion = "7-5"
2023-11-05 21:51:14 -05:00
2024-08-11 13:39:41 -04:00
# Doom Addons
mapfile -t doomAddons < <( find " $gamePath /Addons/DOOM/ " -type f -name " TobyV ${ tobyVersion %%-* } _*.pk3 "
find " $gamePath /Addons/MENU/ " -type f -name " TobyV ${ tobyVersion %%-* } _*.pk3 "
)
# Heretic Addons
mapfile -t hereticAddons < <( find " $gamePath /Addons/HERETIC/ " -type f -name "TobyHeretic*.pk3"
find " $gamePath /Addons/MENU/ " -type f -name " TobyV ${ tobyVersion %%-* } _*.pk3 "
)
2024-04-18 11:23:39 -04:00
doomGames = (
2024-02-07 10:54:29 -05:00
# Toby demo map
2024-08-11 13:39:41 -04:00
" TobyAccMod_V ${ tobyVersion } .pk3 Toby-Demo-Level.wad ${ doomAddons [*] } " "Freedoom Toby Demo Map"
2023-11-05 21:51:14 -05:00
# Unmodified Doom with accessibility.
2024-08-11 13:39:41 -04:00
" TobyAccMod_V ${ tobyVersion } .pk3 ${ doomAddons [*] } " "Freedoom"
2023-11-05 21:51:14 -05:00
# Toby accessibility mods
2024-09-10 16:28:20 -04:00
" TobyAccMod_V ${ tobyVersion } .pk3 TobyDoomLevels.wad Toby-Doom-Level-Music-Renamer.pk3 ${ doomAddons [*] } " "Freedoom Toby Delux Map Pack"
2023-11-05 21:51:14 -05:00
# OperationMDK
2024-08-11 13:39:41 -04:00
" TobyAccMod_V ${ tobyVersion } .pk3 OpMDK.wad ${ doomAddons [*] } " "Freedoom OperationMDK"
2024-08-08 23:59:36 -04:00
# Unmodified Heretic with accessibility
2024-08-11 13:39:41 -04:00
" TobyAccMod_V ${ tobyVersion } .pk3 ${ hereticAddons [*] } " "Classic Heretic"
2024-08-08 23:59:36 -04:00
# Heretic accessibility mods
2024-08-11 13:39:41 -04:00
" TobyAccMod_V ${ tobyVersion } .pk3 TobyHereticLevels.wad ${ hereticAddons [*] } " "Toby Heretic"
2024-04-15 20:33:58 -04:00
"custom_game" "Custom Game"
2023-11-05 21:51:14 -05:00
)
2024-04-15 20:33:58 -04:00
export antiGrepStrings = (
2024-01-22 12:55:20 -05:00
'-E' '-v'
2024-08-26 04:19:50 -04:00
'-e' '^$'
2024-08-20 01:34:11 -04:00
'-e' '^[0-9]'
'-e' '^P_StartScript:'
2024-08-27 23:42:20 -04:00
'-e' '^(Facing |fluidsynth |INTRO|MAP[0-9]+|Music "|Unknown)'
2024-08-20 03:01:03 -04:00
'-e' '^(\[Toby Accessibility Mod\] )?README'
2024-08-20 01:34:11 -04:00
'-e' '^ *TITLEMAP'
2024-08-11 23:12:42 -04:00
'-e' '^\[Toby Accessibility Mod\] (INTRO|READMe)([0-9]+).*'
2024-08-20 01:34:11 -04:00
'-e' 'key card'
2024-08-25 14:06:53 -04:00
'-e' '^New PDA Entry:'
2024-08-26 04:19:50 -04:00
'-e' "^(As |Computer Voice:|Holy|I |I've|Monorail|Sector |Ugh|What|Where)"
2023-11-10 15:28:28 -05:00
)
2024-08-18 03:25:48 -04:00
export sedStrings = ( '-E'
2024-08-09 19:21:05 -04:00
'-e' 's/^\[Toby Accessibility Mod\] M_/[Toby Accessibility Mod] /'
'-e' 's/^\[Toby Accessibility Mod\] //'
2024-08-18 19:31:52 -04:00
'-e' 's/^MessageBoxMenu$/Confirmation menu: Press Y for yes or N for no/'
2024-08-18 03:25:48 -04:00
'-e' 's/^Mainmenu$/Main menu/'
'-e' 's/^Skillmenu$/Difficulty menu/'
'-e' 's/^NGAME$/New game/'
'-e' 's/^(LOAD|SAVE|QUIT)G$/\1 game/'
2023-11-10 15:28:28 -05:00
'-e' 's/"cl_run" = "true"/run/'
'-e' 's/"cl_run" = "false"/walk/'
2024-08-18 03:25:48 -04:00
#'-e' 's:.*/:Game saved. \(:'
2024-08-20 03:01:03 -04:00
'-e' 's/UAC/U A C/'
2024-08-21 03:00:34 -04:00
'-e' 's/^\+//'
2024-08-25 14:06:53 -04:00
'-e' 's/ ?\*+ ?//g'
2023-11-10 15:28:28 -05:00
)
2024-08-26 04:19:50 -04:00
# Translation stuff
doomLanguage = " ${ doomLanguage :- en } "
cache = " ${ cache :- ${ XDG_CACHE_HOME :- $HOME /.cache } /linux-game-manager } "
translationDB = " ${ cache } /doom_ ${ doomLanguage } .sqlite "
# Function to initialize SQLite database
init_translation_db( ) {
mkdir -p " $cache "
if [ [ ! -f " $translationDB " ] ] ; then
sqlite3 " $translationDB " <<EOF
CREATE TABLE translations (
original TEXT PRIMARY KEY,
translated TEXT
) ;
EOF
fi
}
# Function to translate text
translate_text( ) {
local text = " $1 "
local translatedText
# Check if translation exists in database
translatedText = $( sqlite3 " $translationDB " "SELECT translated FROM translations WHERE original = ?;" " $text " )
if [ [ -n " $translatedText " ] ] ; then
echo " $translatedText "
return 0
fi
translatedText = $( trans -b -t " $doomLanguage " " $text " )
# Store new translation in database
sqlite3 " $translationDB " "INSERT INTO translations (original, translated) VALUES (?, ?);" " $text " " $translatedText "
echo " $translatedText "
}
2024-04-15 20:33:58 -04:00
custom_game( ) {
mapfile -t customGames < <( find " ${ 0 %/* } /TobyCustom/ " -type f -iname '*.sh' )
declare -a customMenu
for i in " ${ customGames [@] } " ; do
customMenu += ( " $i " )
title = " ${ i ##*/ } "
title = " ${ title //_/ } "
title = " ${ title %.* } "
customMenu += ( " $title " )
done
customGame = " $( dialog --backtitle "Select your Custom Doom!" \
--clear \
--no-tags \
--menu "Please select one" 0 0 0 " ${ customMenu [@] } " --stdout) "
buttonCode = $?
if [ [ $buttonCode -eq 1 ] ] ; then
exit 0
fi
source " ${ customGame } "
}
2024-08-26 04:19:50 -04:00
if [ [ " $doomLanguage " != "en" ] ] ; then
init_translation_db
fi
2024-04-18 10:49:01 -04:00
gameOption = " $( dialog --backtitle "Select your Doom!" \
2023-11-10 01:57:27 -05:00
--clear \
--no-tags \
--ok-label "Single Player" \
--cancel-label "Death Match" \
--extra-button \
--extra-label "co-op" \
--help-button \
--help-label "Exit" \
--menu "Please select one" 0 0 0 " ${ doomGames [@] } " --stdout) "
buttonCode = $?
2024-07-31 02:18:36 -04:00
if [ [ -e " ${ gamePath } /DoomMetalVol7.wad " ] ] ; then
2024-04-18 16:26:42 -04:00
gameOption += " DoomMetalVol7.wad"
2024-07-31 02:18:36 -04:00
elif [ [ -e " ${ gamePath } /DoomMetalVol6.wad " ] ] ; then
2024-01-21 05:02:41 -05:00
gameOption += " DoomMetalVol6.wad"
2023-11-27 18:47:42 -05:00
fi
2023-11-10 01:57:27 -05:00
case ${ buttonCode } in
1)
# Death match setup
2024-01-21 13:12:55 -05:00
# Ignore the choice of map made above
2024-07-31 02:18:36 -04:00
gameOption = " ${ gamePath } /TobyAccMod_V ${ tobyVersion } .pk3 ${ gamePath } /TobyDeathArena_V1-0.wad " " $gamePath /Addons/TobyV ${ tobVersion %%-* } _ " *
2024-01-21 13:12:55 -05:00
ipAddress = " $( dialog --backtitle "Deathmatch Options" \
2023-11-10 15:28:28 -05:00
--clear \
2024-01-21 13:12:55 -05:00
--no-tags \
--ok-label "Join" \
--cancel-label "Exit" \
--extra-button \
--extra-label "Host" \
--inputbox "Enter ip or URL, required for join." -1 -1 --stdout) "
buttonCode = $?
[ [ $buttonCode -eq 1 ] ] && exit 0
if [ [ $buttonCode -eq 0 ] ] ; then
if [ [ " ${# ipAddress } " -lt 3 ] ] ; then
dialog --backtitle "Deathmatch" --clear --msgbox "No ip address or URL given." -1 -1 --stdout
exit 1
fi
2024-01-22 15:25:37 -05:00
flags = ( '-join' " ${ ipAddress } " )
2024-01-21 13:12:55 -05:00
else
# List of maps included:
maps = (
"1" "Com Station (2-4 players)"
"2" "Warehouse (2-4 players)"
"3" "Sector 3 (2-4 players)"
"4" "Dungeon of Doom (2-4 players)"
"5" "Ocean Fortress (2-4 players)"
"6" "Water Treatment Facility (2-4 players)"
"7" "Phobos Base Site 4 (2-4 players)"
"8" "Hangar Bay 18 (2-4 players)" )
# Array of how many players a given map supports in dialog rangebox syntax
declare -a mapPlayers = (
[ 1] = "2 4"
[ 2] = "2 4"
[ 3] = "2 4"
[ 4] = "2 4"
[ 5] = "2 4"
[ 6] = "2 4"
[ 7] = "2 4"
[ 8] = "2 4" )
2024-01-21 13:48:58 -05:00
map = " $( dialog --backtitle "Select Map" \
--clear \
--no-tags \
--cancel-label "Exit" \
2024-01-22 00:52:44 -05:00
--ok-label "Next" \
2024-01-21 13:48:58 -05:00
--menu "Please select one" 0 0 0 " ${ maps [@] } " --stdout) "
fraglimit = " $( dialog --backtitle "Fraglimit" \
--clear \
--ok-label "Next" \
--cancel-label "Exit" \
2024-01-21 23:21:02 -05:00
--rangebox "Select Fraglimit" -1 -1 1 500 20 --stdout) "
2024-01-21 13:48:58 -05:00
[ [ $? -eq 1 ] ] && exit 0
2024-01-21 13:12:55 -05:00
# Get ip address
yourIpAddress = " $( curl -4s https://icanhazip.com) "
players = " $( dialog --backtitle "Host Deathmatch Game" \
--clear \
--ok-label "Next" \
--cancel-label "Exit" \
--rangebox " Select number of players. Remember to give them your IP address: ${ yourIpAddress } " -1 -1 ${ mapPlayers [ $map ] } --stdout) "
[ [ $? -eq 1 ] ] && exit 0
skillLevel = " $( dialog --backtitle "Host Deathmatch Game" \
--clear \
--ok-label "Start" \
--cancel-label "Exit" \
2024-01-21 23:21:02 -05:00
--extra-button \
--extra-label "Bots Only" \
2024-01-21 13:12:55 -05:00
--rangebox "Select difficulty. 1 easiest, 5 hardest." -1 -1 1 5 3 --stdout) "
2024-01-21 23:21:02 -05:00
code = $?
[ [ $code -eq 1 ] ] && exit 0
if [ [ $code -eq 3 ] ] ; then
players = 1
dialog --backtitle "Preparing to Launch" \
--msgbox "When the game starts, press \` to open the console. Type addbot, press enter. Repeat addbot for as many bots as you would like. Press \` again to close the console." -1 -1 --stdout
fi
2024-01-21 13:12:55 -05:00
flags = (
'-host' " ${ players } "
'-skill' " ${ skillLevel } "
'-deathmatch'
'+set' 'sv_cheats' '1'
2024-01-21 13:17:54 -05:00
'+fraglimit' " $fraglimit "
2024-01-21 13:12:55 -05:00
'+dmflags' '16384' '+dmflags' '4' '+dmflags' '128' '+dmflags' '4096'
2024-02-10 18:14:20 -05:00
'+dmflags2' '512' '+dmflags2' '1024'
2024-01-21 13:12:55 -05:00
'-extratic' '-dup' '3'
'-warp' " $map "
)
fi
2024-08-20 01:34:11 -04:00
launch_game ${ gameOption } " ${ flags [@] } "
2023-11-10 01:57:27 -05:00
; ;
2)
# Exit was pressed, so exit.
exit 0
; ;
3)
# Co-op setup
2023-11-10 15:28:28 -05:00
ipAddress = " $( dialog --backtitle "Co-op Options" \
--clear \
--no-tags \
--ok-label "Join" \
--cancel-label "Exit" \
--extra-button \
--extra-label "Host" \
--inputbox "Enter ip or URL, required for join." -1 -1 --stdout) "
buttonCode = $?
[ [ $buttonCode -eq 1 ] ] && exit 0
if [ [ $buttonCode -eq 0 ] ] ; then
if [ [ " ${# ipAddress } " -lt 3 ] ] ; then
dialog --backtitle "Co-op" --clear --msgbox "No ip address or URL given." -1 -1 --stdout
exit 1
fi
2024-01-21 05:02:41 -05:00
flags = ( "keyshare-universal.pk3" '-join' " ${ ipAddress } " )
2023-11-10 15:28:28 -05:00
else
# Get ip address
yourIpAddress = " $( curl -4s https://icanhazip.com) "
players = " $( dialog --backtitle "Host Co-op Game" \
--clear \
--ok-label "Next" \
--cancel-label "Exit" \
--rangebox " Select number of players. Remember to give them your IP address: ${ yourIpAddress } " -1 -1 2 10 --stdout) "
[ [ $? -eq 1 ] ] && exit 0
skillLevel = " $( dialog --backtitle "Host Co-op Game" \
--clear \
--ok-label "Start" \
--cancel-label "Exit" \
2023-11-10 16:12:59 -05:00
--rangebox "Select difficulty. 1 easiest, 5 hardest." -1 -1 1 5 3 --stdout) "
2023-11-10 15:28:28 -05:00
[ [ $? -eq 1 ] ] && exit 0
flags = (
2024-01-21 05:02:41 -05:00
"keyshare-universal.pk3"
2023-11-10 15:28:28 -05:00
'-host' " ${ players } "
'-skill' " ${ skillLevel } "
2023-11-10 15:58:58 -05:00
'+set' 'sv_cheats' '1'
'+set' 'sv_weaponsstay' '1'
'+set' 'sv_respawnprotect' '1'
2023-11-10 17:48:43 -05:00
'+set' 'sv_respawnsuper' '1'
'+set' 'alwaysapplydmflags' '' 1
2023-11-10 15:58:58 -05:00
'-extratic' '-dup' '3'
2023-11-10 15:28:28 -05:00
)
fi
2024-01-21 04:34:06 -05:00
pushd " ${ doomPath } "
2024-08-20 01:34:11 -04:00
launch_game ${ gameOption } " ${ flags [@] } "
2023-11-10 01:57:27 -05:00
; ;
0)
2024-04-15 20:33:58 -04:00
if [ [ " ${ gameOption %% * } " = = "custom_game" ] ] ; then
custom_game
fi
2024-08-20 01:34:11 -04:00
launch_game ${ gameOption [@] } " ${ flags [@] } "
2023-11-10 01:57:27 -05:00
; ;
esac
2023-11-05 21:51:14 -05:00
exit 0