T3RRYT3RR0R

Ampersand Hunters a Batch Arcade Game

May 2nd, 2020
607
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Batch 26.44 KB | None | 0 0
  1. @ECHO OFF
  2. Setlocal EnableExtensions || (Echo Your version of windows does not support this program. Exiting & Timeout & Exit /B)
  3. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4. REM ::: Arcade style Batch Game By T3RRY https://www.youtube.com/channel/UCo3tS26Eg-ITbdNgWhB0MRQ
  5. ::
  6. :: { Game requirements:
  7. :: Windows 10 Version 1511 or newer.
  8. :: Additional downloads required for controller and sounds unless complete version is downloaded
  9. :: }
  10. :: Youtube: https://youtu.be/hMqt4JYzQyY
  11. :: PasteBin: https://pastebin.com/btnZPC5c
  12. :: Complete Version [6.0] : https://drive.google.com/uc?export=download&id=1_CeQFqI4_YtNCDZOxMxZCHLqul4G38GJ
  13. ::: [Version 6.1] For Windows 10
  14. :: - 08 May 2020
  15. ::   Modified Way the ampersand is displayed to Not require "^" escaping
  16. ::   Adjusted Trail coloring to use 24 bit Color with ASCII codes and R G B values %Æ%[38;2;red;green;bluem
  17. ::    - Color gradient scales according to X /Y positions, Escape position also scaled to X/Y Coordinates,
  18. ::      matching the player trail.
  19. ::   Added a Loading bar in the Title
  20. ::: [Version 6.0] For Windows 10
  21. :: - 06 May 2020
  22. ::   Added Theme.Song
  23. ::    - Changed positioning of Call to the Music Stopper and moved movement sound effect to accomadate looping the Theme.Song
  24. ::   Added Sound effects For Escaping; Enemy teleport and Death.
  25. ::   Modified Delay timing to compensate For the time cost of playing the sound effect during each move instead of looping it
  26. ::   Added a loop into the start up component test to ensure all files are downloaded before continuing
  27. ::   Simplified the approach used for displaying player / enemy positions
  28. ::   Corrected Setlocal recursion issue that was resulting in missing operator after ~ 30 wins / losses
  29. ::: [Version 5.0] For Windows 10
  30. :: - 02 May 2020
  31. ::   Support For Direct download of all files added
  32. ::   Support For movement keys extend to cover both cases
  33. ::   Simplified Variable setting For display characters and their Color, Can now be changed from one Location
  34. ::   Built in a speed delay that gets reduced with each level
  35. ::   Converted enemy Generation into array Form Supporting growth in enemy Numbers
  36. ::   Adjusted colors of enemy and player trails to make characters easier to see
  37. ::   Modified the display of the screen For smoother initial Display
  38. ::   Corrected a typo that allowed enemies to spawn at the Players Location
  39. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  40.  
  41. ::: { Define pathways and create subfolders used For self generated component files
  42. ::: - calls subroutines to create component files.
  43. ::: [ Test if All component files were Downloaded
  44.     If Not Exist "%~dp0AmpHunt_Components" (Set "AmpHunt_Components=%TEMP%\AmpHunt_Components") Else (Set "AmpHunt_Components=%~dp0AmpHunt_Components")
  45. ::: ]
  46. ::: [ Make folder in Temp drive to download component files if full version not downloaded
  47.     If not exist "%AmpHunt_Components%" MD "%AmpHunt_Components%"
  48. ::: ]
  49.     If not exist "%AmpHunt_Components%" MD "%AmpHunt_Components%"
  50.     Set "Player=%AmpHunt_Components%\BatchMusicPlayer.bat"
  51.     Set "VBSplayer=%AmpHunt_Components%\playMusic.vbs"
  52.     Set "MusicStopper=%AmpHunt_Components%\StopMusic.bat"
  53.     Set "Monitor=%AmpHunt_Components%\BatchMonitor.vbs"
  54.     Set GetKeys="%AmpHunt_Components%\GetKey.exe"
  55.     Set "GetKeyTest=%AmpHunt_Components%\GetKey.exe"
  56. :::
  57. ::: [ sound by elmasmalo1. Used and shared under Creative Commons License Attribution 3.0 Unported (CC BY 3.0)
  58. ::: - Source: https://freesound.org/people/elmasmalo1/sounds/376968/
  59. ::: - License details: https://creativecommons.org/licenses/by/3.0/legalcode
  60.     Set "Move.Sound=%AmpHunt_Components%\bubble-pop.wav"
  61. ::: ]
  62. ::: [ Theme Song by Kai Engel. "Chant of the Nightblades"
  63. ::: - Used and shared under creative commons Attribution License 4.0
  64. ::: - Source : https://freemusicarchive.org/music/Kai_Engel/Death.Soundless_The_Renaissance/04_-_Chant_Of_Night_Blades
  65. ::: - https://creativecommons.org/licenses/by-nc-sa/4.0/
  66. ::: - License details: https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
  67.     Set "Theme.Song=%AmpHunt_Components%\ChantOfTheNightBlades.mp3"
  68. ::: ]
  69. ::: [ Escape Sound Effect by EVRetro
  70. ::: - Used and shared under creative commons 0 License - Universal Public domain
  71. ::: - Source : https://freesound.org/people/EVRetro/sounds/495005/
  72. ::: - License Details : https://creativecommons.org/publicdomain/zero/1.0/legalcode
  73.     Set "Escape.Sound=%AmpHunt_Components%\Escape.wav"
  74. ::: ]
  75. ::: [ Death.Sound Sound Effect by Fupicat
  76. ::: - Used and shared under creative commons 0 License - Universal Public domain
  77. ::: - Source : https://freesound.org/people/Fupicat/sounds/475347/
  78. ::: - License Details : https://creativecommons.org/publicdomain/zero/1.0/legalcode
  79.     Set "Death.Sound=%AmpHunt_Components%\Death.wav"
  80. ::: ]
  81. ::: [ Teleport Sound by Chinomaker
  82. ::: - Used and shared under creative commons 0 License - Universal Public domain
  83. ::: - Source : https://freesound.org/people/chinomaker/sounds/324644/
  84. ::: - License Details : https://creativecommons.org/publicdomain/zero/1.0/legalcode
  85.     Set "Teleport.Sound=%AmpHunt_Components%\Teleport.wav"
  86. ::: ]
  87.  
  88. ::: - Renew component .bat and .vbs files with each launch in case folder location changes
  89.     Call :make_components
  90. ::: }
  91.  
  92. CHCP 65001
  93. CLS
  94. REM Code page allows For use of non standard characters
  95.  
  96. ::: { Commence vbs monitor to close the vbs scripts when cmd.exe is closed
  97.     start "" "%Monitor%"
  98. ::: }
  99.  
  100. :ReLoad
  101. TITLE ? Verifiying Components
  102. ::: [ Begin playing Theme Song If it's been downloaded
  103.     If Exist "%Theme.Song%" CALL "%Player%" "%Theme.Song%" 40 True
  104. ::: ]
  105.  
  106. ::: { Starting speed enacted using a For /L loop Delay. Decremented to Increase speed in multiples of 50.
  107.     Set "Speed=100"
  108. ::: }
  109.  
  110. :NewGame
  111. ::: { Creates variable Æ = Ascii-27 Escape code.
  112. ::: - http://www.dostips.com/Forum/viewtopic.php?t=1733
  113. ::: - https://stackoverflow.com/a/34923514/12343998
  114. :::
  115. ::: - Æ (Alt 146) can be used  with and without DelayedExpansion.
  116.     Setlocal
  117.     For /F "tokens=2 delims=#" %%a in ('"prompt #$H#$E# & echo on & For %%b in (1) do rem"') do (
  118.         Endlocal
  119.         Set "Æ=%%a"
  120.     )
  121. ::: }
  122.  
  123. ::: { REM Define 'Play Field' Parameters. Allows Play Field Characteristics to be easily Changed. Only Hieght and Width need changing
  124. ::: - Outer Border
  125. REM Hieght Max = 35 Min = 20
  126. REM Width Max = 160 Min =35
  127.     If NOT "%~2" == "" (
  128.         Set "Hieght=%~1"
  129.         Set "Width=%~2"
  130.     ) Else (
  131.         Set "Hieght=30"
  132.         Set "Width=160"
  133.     )
  134.  
  135.     Set /A EndScore=(Hieght * Width)
  136.     Set /A Lines=Hieght+5
  137.     Set /A Columns=Width+0
  138.  
  139. ::: - Establish Screen size. Larger screen sizes will result in slower Load times and Gameplay.
  140.  
  141.     cls & Mode Con cols=%Columns% Lines=%Lines% >nul 2>nul || (Echo.Invalid Params For width and hieght. Value must be an Integer. & Exit /B)
  142.  
  143. ::: - Inner Border
  144.     Set "Axis_mins=2"
  145.     Set /A X_Axis_Boundary=Width - 1,Y_Axis_Boundary=Hieght - 1
  146. :: Move Limits within Borders
  147.     Set /A Limit_Axis_Min=3,Limit_X_Max=X_Axis_Boundary - 1,Limit_Y_Max=Y_Axis_Boundary - 1
  148. ::: }
  149.  
  150. ::: { Game can be modified to function without GetKey.exe, however, PerFormance is Exceptionally enhanced though it's use.
  151. ::: - Test For the existance of Ancillary .Exe required to run this program 'out of the box'
  152. ::: - Provide Option to easily download / Abort Game.
  153.     Set "Components=True"
  154.     For %%A In ("%GetKeyTest%" "%Move.Sound%" "%Theme.Song%" "%Escape.Sound%" "%Death.Sound%" "%Teleport.Sound%") Do  If Not Exist %%A Set "Components=False"
  155.     If /I "%Components%" == "False" (
  156.         PUSHD "%AmpHunt_Components%"
  157.         TITLE Components missing For Ampersand Hunters. Downloads required to continue.
  158.         Echo.%Æ%[33m This Program requires the following components to be downloaded in the folder:
  159.         Echo.%Æ%[32m %AmpHunt_Components%
  160.         Echo.
  161.         If Not Exist "%GetKeyTest%" Echo.%Æ%[32m Getkey.exe must be saved to %Æ%[34m %GetKeys%
  162.         If Not Exist "%Move.Sound%" Echo.%Æ%[32m bubble-pop.wav must be saved to %Æ%[34m %Move.Sound%
  163.         If Not Exist "%Escape.Sound%" Echo.%Æ%[32m win-video-game-sound must be saved to %Æ%[34m %Escape.Sound%
  164.         If Not Exist "%Death.Sound%" Echo.%Æ%[32m Death.Sound.wav must be saved to %Æ%[34m %Death.Sound%     
  165.         If Not Exist "%Theme.Song%" Echo.%Æ%[32m Chant of the NightBlades must be saved to %Æ%[34m %Theme.Song%
  166.         If Not Exist "%Teleport.Sound%" Echo.%Æ%[32m Teleport.wav must be saved to %Æ%[34m %Teleport.Sound%
  167.         Echo.
  168.         Echo.Would You Like to download them Now? %Æ%[33mY/N
  169.         For /F "Usebackq Tokens=* Delims=" %%C in (`"Choice /N /C:YN"`) Do If /I "%%C" == "Y" (
  170.             Echo.%Æ%[91mAmpersand Hunters will Continue once the Download browser is Closed.
  171.             If Not Exist "%GetKeyTest%" start /Wait "" "https://drive.google.com/uc?export=download^&id=1q02Ur2a9Wvjlh-uc_QKgx2c6yaX82lNT"
  172.             If Not Exist "%Move.Sound%" start /Wait "" "https://drive.google.com/uc?export=download^&id=146w6quLBrCxhon5Sk-aaZo2zs_RnGZKt"
  173.             If Not Exist "%Escape.Sound%" start /Wait "" "https://drive.google.com/uc?export=download&id=1okOTyKQa-t1zSL0Zf-LCs33y-zVad4mQ"
  174.             If Not Exist "%Death.Sound%" start /Wait "" "https://drive.google.com/uc?export=download&id=1eZeesi-cRkk8BIySm2JgpZB0-AwHWgHH"
  175.             If Not Exist "%Theme.Song%" start /Wait "" "https://drive.google.com/uc?export=download&id=1yeAYgoFYcxYIcss3IZlF5MW4OT3neKvL"
  176.             If Not Exist "%Teleport.Sound%" start /Wait "" "https://drive.google.com/uc?export=download&id=1HNQrQw0USOecPMGl1tdYpUM9qcDbzqqe"
  177.             POPD
  178.             Pause & CLS & Goto :ReLoad & REM ensure all components are downloaded into the correct folder with the correct name.
  179.         ) Else (
  180.             EXIT
  181.         )
  182.     )
  183. ::: }
  184.  
  185. ::: { Define Base variables used For displaying characters on screen
  186. ::: - Characters and their Color are defined here to allow them to be easily changed from the one Location.
  187.     Set "Player.Trail=•%Æ%[0m" & REM alt 7
  188.     Set "Enemy.Trail=•%Æ%[0m" & REM alt 7
  189. ::: [ FG Set index variable count must match the number of Characters in the set.
  190.     Set "FGSet=╬○ʘ¤" & REM Alt 206 ╬ 9 ○ 664 ʘ 207 ¤
  191.     Set "FGSet[i]=4"
  192. ::: ]
  193.     Set "ESCSYMBOL=☼%Æ%[0m" & REM Alt 15
  194. ::: [ Display character For enemy when escaped.
  195.     Set "space=%Æ%[37m%Æ%[7m %Æ%[0m"
  196. ::: ]
  197. ::: [ Outer and Inner Border Symbols
  198.     Set "BORDER.IN.SYMBOL=%Æ%[7m%Æ%[31m░%Æ%[0m" & rem alt 176
  199.     Set "BORDER.OUT.SYMBOL=%Æ%[7m%Æ%[37m▓%Æ%[0m" & rem alt 178
  200. ::: ]
  201. ::: [ Player character.
  202.     Set "P_C=%Æ%[33m☻%Æ%[0m" & REM Alt 21 § 1 ☺ 2 ☻ 3 ♥ 4 ♦ 5 ♣ 6 ♠ 8 ◘ 10 ◙ 11 ♂ 12 ♀
  203. ::: ]
  204. ::: [ Enemy Character.
  205.     Set "E_C=&"
  206.     Set "ENEMY=%Æ%[31m%E_C%%Æ%[0m"
  207. ::: ]
  208.     Set "Esc=%Æ%[37m^%Æ%[0m"
  209. ::: [ Define Number of Enemies Incements by 1 with each replay. Number is Decreased by one when Eaten
  210.     Set /A Enemies+=1
  211. ::: ]
  212. :: Instruction Line Pos - Line number that inFormation is displayed to the player on
  213.     Set /A Instructions=hieght + 2
  214. ::: }
  215.  
  216. ::: { Define Movement Control Keys
  217.     Set "Up=W"
  218.     Set "Down=S"
  219.     Set "Left=A"
  220.     Set "Right=D"
  221.     Set "Pause=P"
  222.     Set "Keys=%Up% %Left% %Down% %Right%"
  223.     Set "MoveKeys=%Keys%"
  224. ::: }
  225.  
  226. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Macro Definitions {
  227.  
  228. set LF=^
  229.  
  230.  
  231. ::Above 2 blank lines are required - do not remove
  232. set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
  233.  
  234. ::: { Loading bar Macro
  235.     Set "Title.Text=Loading "
  236.     Set @Load.Title=Set Title.Text=!Title.Text!^& TITLE !Title.Text!
  237. ::: }
  238. ::: { Macro For changing enemy color During each loop
  239.     Set @Color.NPC=For %%n in (1 2) do if %%n==2 (%\n%
  240.         For /F "tokens=1 delims=," %%G in ("!Param!") do (%\n%
  241.             Set /A "Rand_Col=!random! * 6 / 32768 + 1" %\n%
  242.             If "!Rand_Col!" == "6" (Set "%%G=%Æ%[31m!E_C!%Æ%[0m") %\n%
  243.             If "!Rand_Col!" == "5" (Set "%%G=%Æ%[93m!E_C!%Æ%[0m") %\n%
  244.             If "!Rand_Col!" == "4" (Set "%%G=%Æ%[35m!E_C!%Æ%[0m") %\n%
  245.             If "!Rand_Col!" == "3" (Set "%%G=%Æ%[37m!E_C!%Æ%[0m") %\n%
  246.             If "!Rand_Col!" == "2" (Set "%%G=%Æ%[34m!E_C!%Æ%[0m") %\n%
  247.             If "!Rand_Col!" == "1" (Set "%%G=%Æ%[91m!E_C!%Æ%[0m") %\n%
  248.         ) %\n%
  249.     ) Else set Param=
  250. ::: }
  251.  
  252. ::: { Display player trail and position.
  253.     Set "@Display.Player=ECHO(%Æ%[!L_Y_Pos!;!L_X_Pos!H%Æ%[38;2;!L_Y_Pos!0;100;!L_X_Pos!0m!Player.Trail!%Æ%[!Y_Pos!;!X_Pos!H!P_C!"
  254. ::: }
  255.  
  256. ::: { Macro For testing player XY pos against NPC's to determine Game State changes
  257.     Set @Test.Positions=For %%n in (1 2) do if %%n==2 (%\n%
  258.         For /F "tokens=1 delims=, " %%G in ("!Param!") do (%\n%
  259.             If "!L_X_Pos!" == "!X_Pos!" If "!L_Y_Pos!" == "!Y_Pos!" ECHO(%Æ%[!Y_Pos!;!X_Pos!H!P_C!%\n%
  260.             For /L %%E in (1,1,!Enemies!) Do (%\n%
  261.                 If "!X_Pos!" == "!AI%%E_X!" If "!Y_Pos!" == "!AI%%E_Y!" (%\n%
  262.                     ECHO(%Æ%[!Y_Pos!;!X_Pos!H%Æ%[31m%Æ%[7mX%Æ%[0m%\n%
  263.                     Set "G_Over=%Æ%[!Instructions!;1H%Æ%[K%Æ%[31mYou were Nommed by an Ampersand" ^& Set "Died=True" ^& Goto :end%\n%
  264.                 ) %\n%
  265.             )%\n%
  266.             If "!X_Pos!" == "!T_X!" If "!Y_Pos!" == "!T_Y!" (%\n%
  267.                 ECHO(%Æ%[!Y_Pos!;!X_Pos!H%Æ%[31m%Æ%[7mX%Æ%[0m%\n%
  268.                 Set "G_Over=%Æ%[!Instructions!;1H%Æ%[K%Æ%[31mYou Hit the Trap" ^& Set "Died=True" ^& Goto :end%\n%
  269.             ) %\n%
  270.             If "!X_Pos!" == "!E_X!" If "!Y_Pos!" == "!E_Y!" (%\n%
  271.                 ECHO(%Æ%[!Y_Pos!;!X_Pos!H%Æ%[36m%Æ%[7m!Esc!%Æ%[0m%\n%
  272.                 For /L %%E in (1,1,!Enemies!) Do ECHO(%Æ%[!AI%%E_Y!;!AI%%E_X!H!space!%\n%
  273.                 Set /A Score+=EndScore%\n%
  274.                 Set "G_Over=%Æ%[!Instructions!;1H%Æ%[K%Æ%[36mYou've Escaped with !Score! points" ^& Goto :end%\n%
  275.             ) %\n%
  276.         ) %\n%
  277.     ) Else set Param=
  278. ::: }
  279.  
  280. ::: { Macro For calculating the Players movement
  281.     Set @Calculate.Move=For %%n in (1 2) do if %%n==2 (%\n%
  282.         For /F "tokens=1 delims=, " %%G in ("!Param!") do (%\n%
  283.             If /I "%%G" == "!Up!" If NOT "!Y_Pos!" == "!Limit_Axis_Min!" (Set /A "Y_Pos-=1" ^>nul)%\n%
  284.             If /I "%%G" == "!Down!" If NOT "!Y_Pos!" == "!Limit_Y_Max!" (Set /A "Y_Pos+=1" ^>nul)%\n%
  285.             If /I "%%G" == "!Left!" If NOT "!X_Pos!" == "!Limit_Axis_Min!" (Set /A "X_Pos-=1" ^>nul)%\n%
  286.             If /I "%%G" == "!Right!" If NOT "!X_Pos!" == "!Limit_X_Max!" (Set /A "X_Pos+=1" ^>nul)%\n%
  287.             If /I "%%G" == "!Pause!" (%\n%
  288.                 TITLE Paused%\n%
  289.                 Pause ^>nul%\n%
  290.             )%\n%
  291.         ) %\n%
  292.     ) Else set Param=
  293. ::: }
  294.  
  295. ::: { Macro's For calculating NPC's Moves
  296.     Set @AI.Move.1=For %%n in (1 2) do if %%n==2 (%\n%
  297.         For /F "tokens=1 delims=, " %%G in ("!Param!") do (%\n%
  298.             If "!%%G_X!" == "!X_Pos!" (%\n%
  299.                 If !%%G_Y! LSS !Y_POS! (Set /A "%%G_Y+=1" ^>nul)%\n%
  300.                 If !%%G_Y! GTR !Y_POS! (Set /A "%%G_Y-=1" ^>nul)%\n%
  301.             ) Else (%\n%
  302.                 If !%%G_X! LSS !X_POS! (Set /A "%%G_X+=1" ^>nul)%\n%
  303.                 If !%%G_X! GTR !X_POS! (Set /A "%%G_X-=1" ^>nul)%\n%
  304.             )%\n%
  305.         ) %\n%
  306.     ) Else set Param=
  307.  
  308.     Set @AI.Move.2=For %%n in (1 2) do if %%n==2 (%\n%
  309.         For /F "tokens=1 delims=, " %%G in ("!Param!") do (%\n%
  310.             If "!%%G_Y!" == "!Y_Pos!" (%\n%
  311.                 If !%%G_X! LSS !X_POS! (Set /A "%%G_X+=1" ^>nul)%\n%
  312.                 If !%%G_X! GTR !X_POS! (Set /A "%%G_X-=1" ^>nul)%\n%
  313.             ) Else (%\n%
  314.                 If !%%G_Y! LSS !Y_POS! (Set /A "%%G_Y+=1" ^>nul)%\n%
  315.                 If !%%G_Y! GTR !Y_POS! (Set /A "%%G_Y-=1" ^>nul)%\n%
  316.             )%\n%
  317.         ) %\n%
  318.     ) Else set Param=
  319.  
  320.     Set @AI.Teleport=For %%n in (1 2) do if %%n==2 (%\n%
  321.         For /F "tokens=1 delims=, " %%G in ("!Param!") do (%\n%
  322.             For %%P in (X Y) Do Set /A "%%G_%%P=!random! %% ( !Limit_%%P_Max! - !Limit_Axis_Min! ) + !Limit_Axis_Min!" ^>nul%\n%
  323.             If "!X_Pos!" == "!%%G_X!" If "!Y_Pos!" == "!%%G_Y!" Set /A "%%G_X=!random! %% ( !Limit_X_Max! - !Limit_Axis_Min! ) + !Limit_Axis_Min!" ^>nul%\n%
  324.         ) %\n%
  325.     ) Else set Param=
  326. ::: }
  327.  
  328. ::: { Macro For updating variables used to show changes in gamestate
  329.     Set @LastPos.Update=For %%n in (1 2) do if %%n==2 (%\n%
  330.         For /F "tokens=1 delims=, " %%G in ("!Param!") do (%\n%
  331.             Set /A %%G+=1 ^>nul%\n%
  332.             For %%P in (X Y) Do For /L %%E in (1,1,!Enemies!) Do Set "L_AI%%E_%%P=!AI%%E_%%P!"%\n%
  333.             Set "L_Y_Pos=!Y_Pos!"%\n%
  334.             Set "L_X_Pos=!X_Pos!"%\n%
  335.         ) %\n%
  336.     ) Else set Param=
  337. ::: }
  338.  
  339. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: End Macro Definitions }
  340.  
  341. ::: { Prepare the environment For Building Arrays and Expanding Macros.
  342.     Setlocal EnableDelayedExpansion
  343. ::: }
  344.     %@Load.Title%
  345. ::: { Define Variables For mapping errorlevel to Key.
  346. ::: - used For mapping Errorlevel to Key - Differs by Case
  347. :::  ** Numbers within the below ranges must not be assigned as other variable Names **
  348.     Set /A Keypos=47 & REM [48 - 57]
  349.     For %%A in (0 1 2 3 4 5 6 7 8 9) Do (
  350.         Set /A Keypos+=1
  351.         Set "!Keypos!=%%A"
  352.     )
  353.     %@Load.Title%
  354.     Set /A Keypos=64 & REM [65 - 90]
  355.     For %%A in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) Do (
  356.         Set /A Keypos+=1
  357.         Set "!Keypos!=%%A"
  358.     )
  359.     %@Load.Title%
  360.     Set /A Keypos=96 & REM [97 - 122]
  361.     For %%A in (a b c d e f g h i j k l m n o p q r s t u v w x y z) Do (
  362.         Set /A Keypos+=1
  363.         Set "!Keypos!=%%A"
  364.     )
  365. ::: }
  366.     %@Load.Title%
  367. ::: { Build screen background using For /L loop to Define each line of the Foreground into an Array
  368. ::: - to display in a smooth manner.
  369.     SETLOCAL ENABLEDELAYEDEXPANSION
  370. :: [ Select random Symbol from defined Foreground Set
  371.     Set /A rndFG=!random! %% !FGSet[i]!
  372.     Set "FGSYMBOL=%Æ%[32m!FGSet:~%rndFG%,1!%Æ%[0m"
  373. :: ]
  374. :: [ Prepare Playfield, inner and outer border variables For display
  375.     For /L %%H IN (%Limit_Axis_Min%,1,%Limit_Y_Max%) DO Set "Play.Field%%H=Echo."
  376.     For %%A in (Inner Outer) Do For %%B in (Vert Hor) Do Set "%%A.Border.%%B=Echo."
  377. :: ]
  378.     %@Load.Title%
  379. :: [ Define the Play Field
  380.     For /L %%A IN (%Limit_Axis_Min%,1,%Limit_X_Max%) DO (
  381.         For /L %%B IN (%Limit_Axis_Min%,1,%Limit_Y_Max%) DO (
  382.             Set "Play.Field%%B=!Play.Field%%B!%Æ%[%%B;%%AH!FGSYMBOL!"
  383.         )
  384.     )
  385. :: ]
  386.     %@Load.Title%
  387. :: [ Build the Vertical and Horizontal Edges of the Inner Border
  388.     For /L %%A IN (%Axis_mins%,1,%Y_Axis_Boundary%) DO (
  389.         For %%B IN (%Axis_mins%,%X_Axis_Boundary%) DO (
  390.             Set "Inner.Border.Vert=!Inner.Border.Vert!%Æ%[%%A;%%BH!BORDER.IN.SYMBOL!"
  391.         )
  392.     )
  393.     %@Load.Title%
  394.     For /L %%A IN (%Axis_mins%,1,%X_Axis_Boundary%) DO (
  395.         For %%B IN (%Axis_mins%,%Y_Axis_Boundary%) DO (
  396.             Set "Inner.Border.Hor=!Inner.Border.Hor!%Æ%[%%B;%%AH!BORDER.IN.SYMBOL!"
  397.         )
  398.     )
  399. :: ]
  400.     %@Load.Title%
  401. :: [ Build the Vertical and Horizontal Edges of the Outer Border
  402.     For /L %%A IN (1,1,%Hieght%) DO Set "Outer.Border.Vert=!Outer.Border.Vert!%Æ%[%%A;1H%BORDER.OUT.SYMBOL%%Æ%[%%A;%Width%H!BORDER.OUT.SYMBOL!"
  403.     For /L %%A IN (1,1,%Width%) DO  Set "Outer.Border.Hor=!Outer.Border.Hor!%Æ%[1;%%AH%BORDER.OUT.SYMBOL%%Æ%[%hieght%!!%%AH!BORDER.OUT.SYMBOL!"
  404. :: ]
  405.     %@Load.Title%
  406. :: [ Display the Borders and the Playfield
  407.     For %%A in (Inner Outer) Do For %%B in (Vert Hor) Do !%%A.Border.%%B!
  408.     For /L %%D in (%Limit_Axis_Min%,1,%Limit_Y_Max%) do !Play.Field%%D!
  409.     ENDLOCAL
  410. :: ]
  411. ::: }
  412. ::: { Define Starting Positions
  413. :startpos
  414.     %@Load.Title%
  415.     For %%P in (X Y) Do (
  416.         Set /A "%%P_Pos=!random! %% ( Limit_%%P_Max - Limit_Axis_Min ) + Limit_Axis_Min"
  417.         Set "L_%%P_Pos=!%%P_Pos!"
  418.     )
  419.     For /L %%E in (1,1,!Enemies!) Do For %%P in (X,Y) Do (
  420.         Set /A "AI%%E_%%P=!random! %% ( Limit_%%P_Max - Limit_Axis_Min ) + Limit_Axis_Min"
  421.         Set "L_AI%%E_%%P=!AI%%E_%%P!"
  422.     )
  423.     For /L %%E In (1,1,!Enemies!) Do If "%X_Pos%" == "!AI%%E_X!" If "%Y_Pos%" == "!AI%%E_Y!" GOTO :startpos
  424.  
  425. ::: - Initialise Teleport properties. Teleport properties are calculated based on starting score, which is Area based
  426.     Set Teleport=0
  427.     Set /A Teleport_Freq=(Hieght * Width) / 100
  428.     Set /A Teleport_Reset=Teleport_Freq * 5
  429.  
  430. ::: [ define win condition 'Escape' and additional Loss condition 'Trap', ensuring values differ and within 'play field'
  431. :Objects
  432.     %@Load.Title%
  433. ::: - %%O Object - %%P positional axis
  434.     For %%O in (E T) Do For %%P in (X,Y) Do Set /A "%%O_%%P=!random! %% ( Limit_%%P_Max - Limit_Axis_Min ) + Limit_Axis_Min"
  435.     For %%O in (E T) Do For %%P in (X,Y) Do If "!%%O_%%P!" == "!%%P_Pos!" GOTO :Objects
  436.     If "%E_X%" == "%T_X%" If "%E_Y%" == "%T_Y%" (GOTO :Objects)
  437.     Set "@Display.Escape=Echo.%Æ%[%E_Y%;%E_X%H%Æ%[48;2;%E_Y%0;100;%E_X%0m!ESCSYMBOL!"
  438. ::: ]
  439. ::: [ Condition a pause and holding value to intiate a choice option to begin gameplay.
  440.     Set "Key=!Pause!"
  441.     Set "Last.Key=NG"
  442. ::: ]
  443. ::: }
  444.  
  445. ::: { Game Loop.
  446. :Move
  447.     TITLE !Enemies! Ampersand Hunters pursue you.
  448.     Set /A Teleport+=1 & REM Increment count until next enemy teleport
  449.     %@Color.NPC% ENEMY
  450. ::: - Display Player and Enemies
  451.     %@Display.Player%
  452.     %@Display.Escape%& REM The escape is refreshed prior to Displaying Enemy Locations so the player can see all enemy locations
  453.     For /L %%E in (1,1,!Enemies!) do ECHO(%Æ%[!L_AI%%E_Y!;!L_AI%%E_X!H%Æ%!!!!!%%E_Y!0;!L_AI%%E_X!m!Enemy.Trail!%Æ%[!AI%%E_Y!;!AI%%E_X!H!ENEMY!
  454.     %@Test.Positions% screen
  455.     %@LastPos.Update% Score
  456.  
  457.     ECHO(%Æ%[%instructions%;1H%Æ%[K%Æ%[37m Escape the Ampersands [%Æ%[33m!MoveKeys!%Æ%[37m]
  458.     ECHO(%Æ%[K %Æ%[33mScore : %Æ%[36m !Score!%Æ%[0m
  459.  
  460. ::: - Pause prior to opening Move.
  461.     If "!Last.Key!" == "NG" (
  462.         TITLE Ampersand Hunters. Level !Enemies! - Select a Move to Start.
  463.         For /F "UsebackQ Tokens=* Delims=" %%K in (`"Choice /N /C:!Up!!Left!!Down!!Right!"`) Do (
  464.             Set "Last.Key=%%K"
  465.             Set "Key=%%K"
  466.         )
  467.     )
  468. ::: [ Movement Move.Sound.
  469.     CALL "%Player%" "%Move.Sound%" 15 false
  470. ::: ]
  471.  
  472. ::: [ If you do not wish to download GetKeys.exe, Enable Choice and REM out indicated lines, and the Download If Conditions.]
  473. ::: - Returns the Key literal instead of the errorlevel.
  474.     If Not Exist "%GetKeyTest%" For /F "Usebackq Tokens=* Delims=" %%K in (`"Choice /T 1 /N /C:0123456789abcdefghijklmnopqrstuvwxyz /D 0"`) Do Set "Key.In=%%K"
  475. ::: - Not used as a macro as the expansion of the choice command within the For Loop is significantly slower than executing the For loop Directly.
  476. ::: - Default switch results in a Free Move For the AI
  477. ::: ] Else :
  478. ::: [ GetKey.exe by Antonio - A.K.A Aacini https://stackoverflow.com/users/778560/aacini
  479. ::: - Can be found at: https://www.dostips.com/Forum/viewtopic.php?f=3&t=3428#p17101
  480.     If Exist "%GetKeyTest%" (
  481.         Set "Key.In="
  482.         %GetKeys% /N & REM out if GetKey.exe is not downloaded
  483. ::: - Assign Errorlevel from Getkey.exe to a variable, test if valid predefined Key.
  484.         Set "Key.In=!Errorlevel!" & REM out if GetKey.exe is not downloaded
  485. ::: - Return the Key literal instead of the errorlevel:
  486.         For %%K in ("!Key.In!") do Set "Key.In=!%%~K!" & REM out if GetKey.exe is not downloaded
  487.     )
  488. ::: ] End of GetKeys
  489. ::: [ Determine  game action dependant on last Key in. Pause handley by Key.In and Key variables
  490. ::: - preserves movement direction when pause has completed.
  491.     For %%K in (!keys! P) Do (If /I "!Key.In!" == "%%K" Set "Key=%%K" & If /I Not "%%K" == "!Pause!" Set Last.Key=%%K)
  492.     %@Calculate.Move% !Key!
  493.     If /I "!Key!" == "!Pause!" Set "Key=!Last.Key!"
  494. ::: ]
  495. ::: [ Use substring modification and ASCII color codes to display last key press
  496.     For %%K in (!Key!) do Set "MoveKeys=!Keys:%%K=%Æ%[35m%%K%Æ%[33m!"
  497. ::: ]
  498. ::: [ expand Selected Macro's to calculate enemies movements.
  499. ::: - Positioned prior to Teleport so an enemy cant teleport to an adjacent cell and Consume you within the same Move.
  500.     For /L %%E in (1,1,!Enemies!) Do (
  501.         Set /A AI%%E_Move=!random! %%2 + 1
  502.         If "!AI%%E_Move!" == "1" %@AI.Move.1% AI%%E
  503.         If "!AI%%E_Move!" == "2" %@AI.Move.2% AI%%E
  504.     )
  505. ::: ]
  506. ::: [ Warp the enemy characters to a new position Only if they are not on the same ? axis at defined intervals
  507.     For /L %%A in (%Teleport_Freq%,%Teleport_Freq%,%Teleport_Reset%) Do (
  508.         If "!Teleport!" == "%%A" (
  509.             CALL "%Player%" "%Teleport.Sound%" 20 false
  510.             For /L %%O in (1,2,!Enemies!) Do If Not "!X_Pos!" == "!AI%%O_X!" %@AI.Teleport% AI%%O
  511.             For /L %%E in (2,2,!Enemies!) Do If Not "!Y_Pos!" == "!AI%%E_Y!" %@AI.Teleport% AI%%E
  512.             If "%%A" == "%Teleport_Reset%" (Set /A "Score+=Teleport_Reset" && Set "Teleport=0")
  513.         )
  514.     )
  515. ::: ]
  516. ::: { Enact Speed Delay
  517.     If !Enemies! LEQ 10 For /L %%A in (0,1,!Speed!) Do > Nul Echo Delay
  518. ::: }
  519. Goto :Move
  520. ::: } End of movement Loop
  521.  
  522. ::: { * Script break * }
  523.  
  524. ::: { Subroutine used to create sound related subporgrams }
  525. :Make_Components
  526. ::: [ creates a companion batch file that's called with arguments For trackpath, volume and loop tf values
  527. ::: Parameters required For Player: [filepath.ext] [0-100] [True-False]
  528.     (
  529.     Echo.@ECHO OFF
  530.     Echo.Set "MusicPath=%%~1"
  531.     Echo.Set "vol=%%~2"
  532.     Echo.Set "Loop_TF=%%~3"
  533. ::: - Change to the Directory you want to create the Music Launcher in.
  534.     Echo.PUSHD "%%AmpHunt_Components%%"
  535. ::: - Ensure no Conflict with the Previous Script.
  536.     Echo.If exist PlayMusic.vbs ^(
  537.     Echo.DEL PlayMusic.vbs
  538.     Echo.^)
  539. ::: - Creates a vbs Script to Launch the music (Occurs without any visual indication or prompting)
  540.     Echo.^( echo Set Sound = CreateObject^("WMPlayer.OCX.7"^^^)
  541.     Echo.echo Sound.URL = "%%MusicPath%%"
  542.     Echo.echo Sound.settings.volume = %%vol%%
  543.     Echo.echo Sound.settings.setMode "loop", %%Loop_TF%%
  544.     Echo.echo Sound.Controls.play
  545.     Echo.echo While Sound.playState ^^^<^^^> 1
  546.     Echo.echo      WScript.Sleep 100
  547.     Echo.echo Wend
  548.     Echo.^)^>PlayMusic.vbs
  549.     Echo.start /min PlayMusic.vbs
  550. ::: -   Return to the Previous Directory
  551.     Echo.POPD
  552. ::: -   Exit the Launcher and return to Previous batch program.
  553.     Echo.Goto :EOF
  554.     )>"%Player%"
  555. ::: ]
  556. ::: [ Monitor checks process status of cmd.exe every 1500 ms and calls StopMusic batch file to taskill all vbs scripts when
  557. ::: - cmd.exe process count is 0. Delay is to reduce CPU usage of the WMI service
  558.     (
  559.     ECHO Set objWMIService = GetObject ("winmgmts:"^)
  560.     ECHO Set proc = objWMIService.ExecQuery("select * from Win32_Process Where Name='cmd.exe'"^)
  561.     ECHO DO while proc.count ^> 0
  562.     ECHO Set proc = objWMIService.ExecQuery("select * from Win32_Process Where Name='cmd.exe'"^)
  563.     ECHO if proc.count ^< 1 then exit do
  564.     ECHO wscript.sleep 2000
  565.     ECHO loop
  566.     ECHO Set WshShell=createobject("wscript.shell"^)
  567.     ECHO WshShell.run "%MusicStopper%", 0, true
  568.     )>"%Monitor%"
  569. ::: ]
  570. ::: [ Simple taskkill script to terminate vbs scripts on program exit
  571.     (
  572.     Echo.@ECHO OFF
  573.     Echo.taskkill /pid WScript.exe /f /t ^>nul 2^>nul
  574.     Echo.Goto :EOF
  575.     )>"%MusicStopper%"
  576.     Timeout 1 >nul
  577. Exit /B
  578. ::: } End of Subroutines
  579.  
  580. ::: { Script exit and cleanup
  581. :end
  582.     If /I "!Died!" == "True" (
  583.         CALL "%Player%" "%Death.Sound%" 80 False
  584.         Set /A Enemies-=1
  585.         If "!Score!" GEQ "!EndScore!" Set /A Score-=EndScore
  586.     )
  587. ::: [ Increase Speed By reducing For /L Loop Iterations
  588.     If /I Not "!Died!" == "True" (
  589.         If "!Speed!" GTR "10" (Set /A Speed-=10)
  590.         CALL "%Player%" "%Escape.Sound%" 60 False
  591.     )
  592. ::: ]
  593.     ECHO(%G_over%
  594.     Set /A Instructions+=1
  595. :ExitMenu
  596.     ECHO(%Æ%[%Instructions%;1H%Æ%[K%Æ%[34m[E]xit [C]onitnue
  597.     For /F "Usebackq Tokens=* Delims=" %%K in (`"Choice /N /C:0123456789abcdefghijklmnopqrstuvwxyz"`) Do (
  598.         If /I "%%K" == "E" (
  599.             CALL "%MusicStopper%"
  600.             Del /Q "%Monitor%"
  601.             Del /Q "%MusicStopper%"
  602.             Del /Q "%Player%"
  603.             Del /Q "%VBSplayer%"
  604.             EXIT
  605.         )
  606.         If /I "%%K" == "C" (
  607.             Endlocal & Set "Score=%Score%" & Set "Enemies=%Enemies%" & Set "Speed=%Speed%"
  608.             GOTO :NewGame
  609.         )
  610.     )
  611. Goto :ExitMenu
  612. ::: }
Add Comment
Please, Sign In to add comment