#!/usr/bin/env bash # Dialog setup: DIALOG_ITEM_HELP="" export DIALOGOPTS='--no-lines --visit-items' # Toby games path export gamePath=~/.local/games/doom # Path where doom wads are stored export doomPath="$(find /usr/share -type d -name "doom" 2> /dev/null | head -1)" # Path to gzdoom or yadoom. if [[ -x "yadoom" ]]; then export gzdoom=$(readlink -f "yadoom") else export gzdoom="$(command -v gzdoom)" fi # Version of the accessibility mod export tobyVersion="7-5" # 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" ) doomGames=( # Toby demo map "TobyAccMod_V${tobyVersion}.pk3 Toby-Demo-Level.wad ${doomAddons[*]}" "Freedoom Toby Demo Map" # Unmodified Doom with accessibility. "TobyAccMod_V${tobyVersion}.pk3 ${doomAddons[*]}" "Freedoom" # Toby accessibility mods "TobyAccMod_V${tobyVersion}.pk3 TobyDoomLevels.wad ${doomAddons[*]}" "Freedoom Toby Delux Map Pack" # OperationMDK "TobyAccMod_V${tobyVersion}.pk3 OpMDK.wad ${doomAddons[*]}" "Freedoom OperationMDK" # Unmodified Heretic with accessibility "TobyAccMod_V${tobyVersion}.pk3 ${hereticAddons[*]}" "Classic Heretic" # Heretic accessibility mods "TobyAccMod_V${tobyVersion}.pk3 TobyHereticLevels.wad ${hereticAddons[*]}" "Toby Heretic" "custom_game" "Custom Game" ) export antiGrepStrings=( '-E' '-v' '-e' '^Resolution:' '-e' '^\[Toby Accessibility Mod\] (INTRO|READMe)([0-9]+).*' ) export grepStrings=( '-E' '-e' '^\[Toby Accessibility Mod\]' '-e' '^[A-Z][0-9a-z]+: .+' '-e' 'is now known as' '-e' '.+ punched .+ to death\.' '-e' 'stood where' '-e' 'was .+ed by' '-e' 'Fraglimit hit\.' '-e' 'chewed on' '-e' 'The maximum' '-e' 'swapped two barrels' '-e' 'MAP[0-9]+' '-e' 'swallowed too much of' '-e' 'exited the level' '-e' 'joined the game' '-e' '^[0-9]+\. ' '-e' '^"cl_run"' '-e' '^Game saved. ' '-e' '^A secret is revealed!$' '-e' '^Player[: ]' '-e' '^Please select a game wad \(or 0 to exit\):' '-e' '^You have no keys in your pocket!$' ) export sedStrings=( '-e' 's/^\[Toby Accessibility Mod\] M_/[Toby Accessibility Mod] /' '-e' 's/^\[Toby Accessibility Mod\] //' '-e' 's/^MessageBoxMenu$/Press Y for yes or N for no/' '-e' 's/"^Mainmenu$/Main menu/' '-e' 's/"^Skillmenu$/Difficulty menu/' '-e' 's/"^NGAME$/New game/' '-e' 's/"^(LOAD|SAVE|QUIT)G$/& game/' '-e' 's/"cl_run" = "true"/run/' '-e' 's/"cl_run" = "false"/walk/' '-e' 's:.*/:Game saved. \(:' ) 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}" } gameOption="$(dialog --backtitle "Select your Doom!" \ --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=$? if [[ -e "${gamePath}/DoomMetalVol7.wad" ]]; then gameOption+=" DoomMetalVol7.wad" elif [[ -e "${gamePath}/DoomMetalVol6.wad" ]]; then gameOption+=" DoomMetalVol6.wad" fi case ${buttonCode} in 1) # Death match setup # Ignore the choice of map made above gameOption="${gamePath}/TobyAccMod_V${tobyVersion}.pk3 ${gamePath}/TobyDeathArena_V1-0.wad ""$gamePath/Addons/TobyV${tobVersion%%-*}_"* ipAddress="$(dialog --backtitle "Deathmatch 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 "Deathmatch" --clear --msgbox "No ip address or URL given." -1 -1 --stdout exit 1 fi flags=('-join' "${ipAddress}") 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") map="$(dialog --backtitle "Select Map" \ --clear \ --no-tags \ --cancel-label "Exit" \ --ok-label "Next" \ --menu "Please select one" 0 0 0 "${maps[@]}" --stdout)" fraglimit="$(dialog --backtitle "Fraglimit" \ --clear \ --ok-label "Next" \ --cancel-label "Exit" \ --rangebox "Select Fraglimit" -1 -1 1 500 20 --stdout)" [[ $? -eq 1 ]] && exit 0 # 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" \ --extra-button \ --extra-label "Bots Only" \ --rangebox "Select difficulty. 1 easiest, 5 hardest." -1 -1 1 5 3 --stdout)" 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 flags=( '-host' "${players}" '-skill' "${skillLevel}" '-deathmatch' '+set' 'sv_cheats' '1' '+fraglimit' "$fraglimit" '+dmflags' '16384' '+dmflags' '4' '+dmflags' '128' '+dmflags' '4096' '+dmflags2' '512' '+dmflags2' '1024' '-extratic' '-dup' '3' '-warp' "$map" ) fi pushd "$doomPath" exec stdbuf -oL ${gzdoom} ${gameOption} "$gamePath/Addons/DOOM/TobyV${tobyVersion%%-*}_"* "${flags[@]}" | while IFS= read -r l ; do echo "$l" | { grep "${grepStrings[@]}" | grep "${antiGrepStrings[@]}" | sed "${sedStrings[@]}" | spd-say -e ${spd_module} ${spd_pitch} ${spd_rate} ${spd_voice} ${spd_volume} --; } ; echo "$l";done ;; 2) # Exit was pressed, so exit. exit 0 ;; 3) # Co-op setup 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 flags=("keyshare-universal.pk3" '-join' "${ipAddress}") 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" \ --rangebox "Select difficulty. 1 easiest, 5 hardest." -1 -1 1 5 3 --stdout)" [[ $? -eq 1 ]] && exit 0 flags=( "keyshare-universal.pk3" '-host' "${players}" '-skill' "${skillLevel}" '+set' 'sv_cheats' '1' '+set' 'sv_weaponsstay' '1' '+set' 'sv_respawnprotect' '1' '+set' 'sv_respawnsuper' '1' '+set' 'alwaysapplydmflags' ''1 '-extratic' '-dup' '3' ) fi pushd "${doomPath}" exec stdbuf -oL ${gzdoom} ${gameOption} "$gamePath/Addons/TobyV${tobyVersion%%-*}_"* "${flags[@]}" | while IFS= read -r l ; do echo "$l" | { grep "${grepStrings[@]}" | grep "${antiGrepStrings[@]}" | sed "${sedStrings[@]}" | spd-say -e ${spd_module} ${spd_pitch} ${spd_rate} ${spd_voice} ${spd_volume} --; } ; echo "$l";done ;; 0) if [[ "${gameOption%% *}" == "custom_game" ]]; then custom_game else pushd "${doomPath}" exec stdbuf -oL ${gzdoom} ${gameOption} | while IFS= read -r l ; do echo "$l" | { grep "${grepStrings[@]}" | grep "${antiGrepStrings[@]}" | sed "${sedStrings[@]}" | spd-say -e ${spd_module} ${spd_pitch} ${spd_rate} ${spd_voice} ${spd_volume} -- > /dev/null 2>&1; }; echo "$l";done fi ;; esac exit 0