Advertisement
T3RRYT3RR0R

Stacker

Apr 20th, 2023
1,194
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Batch 14.72 KB | None | 0 0
  1. ===================================
  2. @REM Stacker by T3RRY. Save with utf-8 encoding.
  3. @REM Requires windows 10 v10589 or newer. Some features will not work as intended in Windows Terminal.
  4. ===================================
  5. %= Do not modify Thread Launcher =%
  6. @Echo off
  7.     (Title )
  8.     REM execute target threads
  9.     If not "%~1"=="" Goto:%1
  10.  
  11.     Set "ForceQuit="
  12.     For /F "Delims=" %%G in ('Where Powershell.exe')Do If not Defined ForceQuit Set "ForceQuit=%%G -c "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('{TAB}')"
  13.  
  14.     If not defined ForceQuit (
  15.         Call:Error 0x01
  16.         Exit /b
  17.     )
  18.  
  19.     (1>"%~f0:Status" Echo(verify.NTFS) || (
  20.         Call:Error 0x04
  21.         Exit /b
  22.     )
  23.  
  24. for /F %%a in ('Echo(prompt $E^| cmd')Do Set \E=%%a
  25.  
  26. Set "fontsize="
  27. CD /D "%~dp0"
  28. :LoadDefaults
  29. (For /F "UsebackQ delims=" %%G in ("%~n0:defaults")Do Set "%%~G") 2> nul
  30.  
  31. If not defined fontsize (
  32.     (
  33.         Echo("fontSize=16"
  34.         Echo("fontType=Lucida Console"
  35.         Echo("s[1]col=1"
  36.         Echo("FGcol=255"
  37.         Echo("BGi[1]=0"
  38.         Echo("BGi[2]=1"
  39.         Echo("SPi=2"
  40.         Echo("Difficulty=1"
  41.     ) >"%~n0:defaults"
  42.     Goto:LoadDefaults
  43. )
  44.  
  45.     CHCP 65001 > nul
  46.     Set "CharSet= *✚✮-+ΦΞ❦•○Δ✸✹✼✾❀❂❈❣✜✟✠✥✪✫✰▄▬▀█░▒▓▲▼►◄┼═╬❤❥♥♦♣♠◙x"
  47.  
  48. :menu
  49.     Call:Setfont %FontSize% "%fontType%"
  50.     CLS
  51.     Setlocal EnableDelayedExpansion
  52.     Echo( [0]    Start the game
  53.     Echo( [P]    Block      Color: %\E%[5m%\E%[38;5;%s[1]col%m%s[1]col%%\E%[0m
  54.     Echo( [WS]   Block       Char: "!CharSet:~%SPi%,1!"
  55.     Echo( [ED]   Background Char1: "!CharSet:~%BGi[1]%,1!"
  56.     Echo( [RF]   Background Char2: "!CharSet:~%BGi[2]%,1!"
  57.     Echo( [C]    Background Color: %\E%[5m%\E%[38;5;%FGcol%m%\E%[?12h%FGcol%%\E%[?12l%\E%[0m
  58.     Echo( [Z]    Change  Fontsize: !FontSize!
  59.     Echo( [1~9]  Difficulty: !Difficulty!%\E%[1E%\E%7
  60.     Endlocal
  61.     For /F "delims=" %%G in ('%SystemRoot%\System32\Choice.exe /n /C:WPCFR0ZEDS123456789')Do (
  62.         If /i "%%G" == "W" Set /A "SPi=SPi %% 48 + 1"
  63.         If /i "%%G" == "P" Call:GetInt s[1]col "Block color"
  64.         If /i "%%G" == "C" Call:GetInt FGcol "Background color"
  65.         If /i "%%G" == "F" If %BGi[2]% GTR 0 Set /A "BGi[2]-=1"
  66.         If /i "%%G" == "R" Set /A "BGi[2]=BGi[2] %% 48 + 1"
  67.         If /i "%%G" == "0" Goto:Setup
  68.         If /i "%%G" == "Z" Set /a "fontsize=fontsize %%30 + 2"
  69.         If /i "%%G" == "E" Set /A "BGi[1]=BGi[1] %% 48 + 1"
  70.         If /i "%%G" == "D" If %BGi[1]% GTR 0 Set /A "BGi[1]-=1"
  71.         If /i "%%G" == "S" If %SPi% GTR 0 Set /A "SPi-=1"
  72.         2> nul Set /A "1/%%G" && Set "Difficulty=%%G"
  73.     )
  74.     If %fontsize% LSS 10 Set "fontsize=10"
  75.  
  76. Goto:menu
  77.  
  78. ===================================
  79. EXIT & Rem this line never executed
  80.  
  81. ! Error Handling !
  82. Error:1 Powershell not found in %Path%
  83. Error:2 Xcopy not in C:\Windows\System32
  84. Error:3 No write permission
  85. Error:4 Non NTFS system
  86. ===================================
  87.  
  88. :GameInit %= Define any initialization variables / output pre-loop screen =%
  89.  
  90.     Setlocal EnableDelayedExpansion
  91.  
  92. REM some math assigned to key array kKEY to handle directional movement.
  93. REM uses divide by zero error to abort movement if it would take the player OOBounds
  94. REM uses -ve & +ve Modulo to adjust Current X/Y index within Bounds.
  95.  
  96. REM E,W ; A,D ; 4,6
  97.     Set "kD="1/(P[1]x-MaxX)","P[1]x=P[1]x %%MaxX + 1""
  98.     Set "kA="1/(P[1]x-1)","P[1]x=((P[1]x - MaxX) %%MaxX) + (MaxX-1)""
  99.     Set "k6="1/(P[1]x-MaxX)","P[1]x=P[1]x %%MaxX + 1""
  100.     Set "k4="1/(P[1]x-1)","P[1]x=((P[1]x - MaxX) %%MaxX) + (MaxX-1)""
  101.  
  102. REM Initial Delay Interval.
  103. REM If you find this game runs too fast at Difficulty 1, increase the value of ControlSpeed.
  104. REM If you find this game runs too slow at Difficulty 1, decrease the value of ControlSpeed.
  105.     Set "ControlSpeed=75000"
  106.     Set /A "BaseDelay=ControlSpeed-(Difficulty*(ControlSpeed/10))"
  107.  
  108. REM maximum delay interval
  109.     Set "MaxDelay=82500"
  110.     Set /A "ModuloStep=ControlSpeed / 100"
  111. REM Set "ModuloStep=1250"
  112.  
  113. REM 'Delay Time' control key definitions.
  114. REM -ve Modulo constrained to 0 lower limit by 1/Basedelay - Divide by zero error halts execution of line.
  115.     Set "k-="1/BaseDelay","BaseDelay=((BaseDelay - MaxDelay) %%MaxDelay) + (MaxDelay-ModuloStep)""
  116.  
  117. REM +ve Modulo constrained to 80000 [ModuloStep offset is to accomadate -ve modulo.]
  118.     Set "k+="1/(MaxDelay-ModuloStep-BaseDelay)","BaseDelay=BaseDelay %%(MaxDelay-ModuloStep) + ModuloStep""
  119.  
  120. REM Field Dims
  121.     Set /A "MaxX=30","MaxY=24","oMaxX=MaxX"
  122.     mode 31,25
  123.  
  124. REM initial starting pos
  125.     Set /A "P[1]x=MaxX/2","P[1]y=MaxY"
  126.     Set "Tail=!CharSet:~%SPi%,1!!CharSet:~%SPi%,1!!CharSet:~%SPi%,1!!CharSet:~%SPi%,1!!CharSet:~%SPi%,1!!CharSet:~%SPi%,1!!CharSet:~%SPi%,1!"
  127.     Set "p[1]Sprite=%\E%[^!P[1]y^!;^!P[1]x^!H!\E![5m!\E![48;5;!S[1]col!m!\E![38;5;1m^!Tail^!"  
  128.  
  129.      Set "P[1]len=7"
  130. REM :::  Set "null=%tail:@=" &Set /A "P[1]len+=1" & Set "null=%"
  131.  
  132.     Set "screen=%\E%[38;5;%FGcol%m"
  133.     Set "num=0"
  134.     for /l %%y in (1,1,%MaxY%) do (
  135.         for /l %%x in (1,1,%MaxX%) do (
  136.             set /a "num=num %% 2 + 1"
  137.             if !num! equ 2 (
  138.                 Set "screen=!Screen!!CharSet:~%BGi[2]%,1!"
  139.             ) Else Set "screen=!Screen!!CharSet:~%BGi[1]%,1!"
  140.         )
  141.             Set "screen=!screen!!LF!"
  142.         )
  143.  
  144. REM Supress Cursor
  145.     <nul Set /P "=%\E%[?25l"
  146.     Title Place:Space Quit:TAB
  147.  
  148. REM Gameloop
  149. Set /A "MaxX=oMaxX-P[1]len+1"
  150. Set "Tower="
  151. Set "Key=!k6!"
  152. Set "LastKey=!Key!"
  153.     2> nul 1> Con (
  154.         For /L %%. in ()Do (
  155.             %= Read last key press from input buffer without waiting. aka Non blocking input =%
  156.             If not "!Lastkey!"=="Pause" If not "!Lastkey!"=="+" If not "!Lastkey!"=="-" Set "LastKey=!Key!"
  157.             Set "NewKey="
  158.             Set /P "NewKey="
  159.             If "!NewKey!"=="4" Set "Newkey="
  160.             If "!NewKey!"=="6" Set "Newkey="
  161.             If /I "!NewKey!"=="A" Set "Newkey="
  162.             If /I "!NewKey!"=="D" Set "Newkey="
  163.             If !p[1]y! LSS 1 (
  164.                 Set "NewKey=quit"
  165.                 For /L %%i in (-1000000 1 1000000)Do rem game won
  166.                 %ForceQuit%
  167.                 Call:cleanup
  168.                 EXIT
  169.             )
  170.             If not "!NewKey!"=="" (
  171.                 If /I "!NewKey:~-4!" == "quit" (
  172.                     Call:Cleanup
  173.                 )
  174.                 If not "!NewKey:{ENTER}!"=="!NewKey!" (
  175.                     Set "NewKey=!NewKey:~-1!"
  176.                 )Else Set "NewKey={ENTER}"
  177.                 For /f "delims=" %%v in ("!NewKey!")Do (
  178.                     If not "!k%%v!"=="" (
  179.                         %= assign key array item to key =%
  180.                         Set "key=!k%%v!"
  181.                     )
  182.                 )
  183.             )
  184.             %= Implement Control actions. =%
  185.             If not "!Key!"=="" (
  186.                 If "!NewKey!"=="+" (
  187.                 REM Set /A !Key!
  188.                     Set "Key=!LastKey!"
  189.                 )Else If "!NewKey!"=="-" (
  190.                 REM Set /A !Key!
  191.                     Set "Key=!LastKey!"
  192.                 )
  193.                 If "!Key!"=="Pause" (
  194.                     Set "NewKey="
  195.                     If not "!LastDropX!"=="" (
  196.                         Set "oldsprite=%p[1]sprite:[38=[48%"
  197.                         Set /A "TrimLeft=0","trimRight=0","right1=(p[1]x+p[1]len)","right2=(LastDropX+LastDropLen)"
  198.                         If !LastDropX! GTR !p[1]X! (
  199.                             Set /A "TrimLeft=LastDropX-p[1]x","p[1]x=LastDropX","p[1]len-=TrimLeft","MaxX=oMaxX-P[1]len+1"
  200.                         )Else (
  201.                             If !right1! GTR !right2! (
  202.                                 Set /A "TrimRight=Right1-Right2","p[1]len-=TrimRight","MaxX=oMaxX-P[1]len+1"
  203.                             )
  204.                         )
  205.                         If !p[1]len! LSS 1 (
  206.                             <nul Set /p "=!\E![1;1H!screen!!Tower!!oldsprite!%\E%[0m
  207.                             Echo/|Choice /n
  208.                             For /L %%i in (-20000 1 20000)Do (Call )
  209.                             %ForceQuit%
  210.                             Call:cleanup
  211.                             EXIT
  212.                         )
  213.                         REM Set /A "P[1]len=P[1]len-trimLeft-trimRight"
  214.                         If not "!Tail!"=="" For /F "delims=" %%i in ("!P[1]len!")Do Set "Tail=!Tail:~-%%i!"
  215.                         Set "Tower=!Tower!%p[1]Sprite%"
  216.                         Set /A "LastDropX=p[1]x","LastDropLen=p[1]Len"
  217.                     )Else   (
  218.                         Set /A "LastDropX=p[1]x","LastDropLen=p[1]Len"
  219.                         Set "Tower=!Tower!%p[1]Sprite%"
  220.                     )
  221.                     Set /A "NewDir=!Random! %% 2",!k-!
  222.                     If !NewDir! EQU 0 (
  223.                         Set /A "p[1]y-=1","p[1]x=1"
  224.                         Set "Key=!k6!"
  225.                     )Else (
  226.                         Set /A "p[1]y-=1","p[1]x=MaxX"
  227.                         Set "Key=!k4!"
  228.                     )
  229.                 )
  230.             )
  231.             %= bounce horizontally =%
  232.             If "!key!"=="!k4!" If "!P[1]x!"=="1" Set "key=!k6!"
  233.             If "!key!"=="!k6!" If "!P[1]x!"=="!maxX!" Set "key=!k4!"
  234.  
  235.             If not "!key!"=="" Set /A !Key!
  236.             <nul Set /p "=!\E![1;1H!screen!!Tower!%P[1]Sprite%%\E%[0m"
  237.                
  238.             Set /A "Delay=BaseDelay"
  239.             Set /A "Delay=Delay*((MaxX*1000/(MaxY*1000))"
  240.             For /L %%i in (1 1 !Delay!)Do rem we go way to fast without a delay
  241.         )
  242.     )
  243.  
  244.     REM the bellow line should never execute.
  245.     EXIT
  246.  
  247.  
  248. ==========================================================================================================
  249. REM no changes should be made to the below utilities
  250. ==========================================================================================================
  251. :Setup
  252.     (
  253.         Echo("fontSize=%fontSize%"
  254.         Echo("fontType=%fontType%"
  255.         Echo("s[1]col=%s[1]col%"
  256.         Echo("FGcol=%FGcol%"
  257.         Echo("BGi[1]=%BGi[1]%"
  258.         Echo("BGi[2]=%BGi[2]%"
  259.         Echo("SPi=%Spi%"
  260.         Echo("Difficulty=%Difficulty%"
  261.     ) >"%~n0:defaults"
  262.     REM Define essential vars for multithreaded controller
  263.     REM Signal file that the Controller uses to pass keypress to the game via without blocking execution.
  264.     REM - Note - This is modified later to a Lockfile in format: %TEMP%\%~n0_%PID%_Signal.cmd
  265.     Set "SignalFile=%TEMP%\%~n0__Signal.cmd"
  266.  
  267.     REM Control Key Definitions
  268.     Call :createChars || (
  269.         Exit /B 1
  270.     )
  271.     REM QuitKey must be defined prior to starting Multithreaded controller. TAB is recommended
  272.     Set "QUITKEY=%TAB%"
  273.     Set "kP=Pause" & Set "Pause=1" & Set "k =Pause"
  274.  
  275.     (Title %~n0)
  276.  
  277. :GetSession
  278.     REM get session ID to prevent File Read / write error if multiple instances running
  279.     For /F "Skip=2 tokens=2" %%G in ('Tasklist /fi "windowtitle eq %~n0"')Do Set "Lock=%%G"
  280.     CALL Set "SignalFile=%%SignalFile:__=_%Lock%_%%"
  281.     For /F "tokens=2 Delims=:" %%G in ('CHCP')Do >"%TEMP%\%~n0_%Lock%_restore.cmd" Echo(@CHCP %%G ^> nul
  282.     Del "%SignalFile:Signal=Abort%" 2> nul
  283.  
  284.     CHCP 65001 > nul
  285.  
  286.     Start /Wait /B "" "%~F0" XCOPYCONTROLLER 1>"%SignalFile%" 2> nul | "%~F0" GameInit <"%SignalFile%" 2> nul
  287.  
  288.     REM game has resolved; end script.
  289.     DEL "%SignalFile%" 2> nul 1> nul
  290.     Endlocal & Goto:Eof
  291. =========================
  292.  
  293. :createChars
  294.     for /f "Delims=" %%e in ('Echo Prompt $E^|cmd') Do Set "\E=%%e"
  295.     for /f "delims= " %%T in ('robocopy /L . . /njh /njs' )do set "TAB=%%T"
  296.     for /f %%C in ('copy /Z "%~dpf0" nul') do set "CR=%%C"
  297.     for /F "delims=#" %%B in ('"prompt #$H# &echo on &for %%b in (1) do rem"') do Set "BS=%%B"
  298.     Set "BS=%BS:~0,1%"
  299.     del sub.tmp 2> nul
  300.     copy nul sub.tmp /a > nul
  301.     If not exist sub.tmp (
  302.         Call:Error 0x03
  303.         Exit /B 1
  304.     )
  305.     for /F %%a in (sub.tmp) DO (
  306.         set "sub=%%a"
  307.     )
  308.     del sub.tmp
  309.     (Set LF=^
  310.  
  311.  
  312.     )%= Do Not Modify. Linefeed Variable =%
  313.     exit /b
  314.  
  315. :XCOPYCONTROLLER
  316.     If not exist C:\Windows\System32\Xcopy.exe (
  317.         Call:Error 0x02 >"%SignalFile:Signal=Abort%"
  318.         <nul Set /P "=quit"
  319.         EXIT
  320.     )
  321.     Setlocal DISABLEdelayedExpansion
  322.     REM Environment handling allows use of ! key
  323.     For /l %%C in () do (
  324.  
  325.         Set "Key="
  326.         for /f "delims=" %%A in ('C:\Windows\System32\xcopy.exe /w "%~f0" "%~f0" 2^>nul') do If not Defined Key (
  327.             set "key=%%A"
  328.             Setlocal ENABLEdelayedExpansion
  329.             set key=^!KEY:~-1!
  330.             If "!key!" == "!QUITKEY!" (
  331.                 >"%SignalFile:Signal=Abort%" Echo(
  332.                 <nul Set /P "=quit"
  333.                 EXIT
  334.             )
  335.             If not "!Key!" == "%BS%" If not "!Key!" == "!CR!" (%= Echo without Linefeed. Allows output of Key and Space =%
  336.                 1> %~n0txt.tmp (echo(!key!!sub!)
  337.                 copy %~n0txt.tmp /a %~n0txt2.tmp /b > nul
  338.                 type %~n0txt2.tmp
  339.                 del %~n0txt.tmp %~n0txt2.tmp
  340.             )Else (
  341.                 If "!Key!" == "%BS%" <nul Set /p "={BACKSPACE}"
  342.                 If "!Key!" == "!CR!" <nul Set /p "={ENTER}"
  343.             )
  344.             Endlocal
  345.         )
  346.     )
  347.  
  348.  
  349. :Cleanup
  350.     <Nul Set /P "=%\E%[1;1H%\E%[2J%\E%[?25h%\E%[0mGame over. "
  351.     <"%SignalFile:Signal=Abort%" Set /P "XcopyError="
  352.     If Defined XcopyError Echo(!XcopyError!
  353.     CALL "%TEMP%\%~n0_%Lock%_restore.cmd" > nul
  354.     Del %TEMP%\%~n0_%lock%_*.cmd 1> nul 2> nul
  355.     (Title )
  356. EXIT
  357.  
  358. :GetInt <VarName> <"Description Text">
  359.     Set "input="
  360.     Set /p "input=%\E%8%\E%[32m%\E%[0JEnter a value for %~2: %\E%[0m"
  361.     2>nul Set /A "input+=0","1/input" || Goto:GetInt
  362.     If %input% LEQ 0 Goto:GetInt
  363.     If %input% GTR 255 Goto:GetInt
  364.     Set /A "%~1=input"
  365. Exit /b 0
  366.  
  367. :delTemp
  368.     REM this file creates signal files to identify the session and communicate input.
  369.     REM If the game is force closed instead of Quit with TAB key
  370.     REM the files will persist. To remove them, Call this file from the command line with The argument: deltemp
  371.     Del "%TEMP%\%~n0_*_*.cmd"
  372. Goto:Eof
  373.  
  374. :setFont <integerSize> <stringFontName>
  375. REM from the StdLibrary created by IcarusLives
  376. REM https://github.com/IcarusLivesHF/Windows-Batch-Library/tree/8812670566744d2ee14a9a68a06be333a27488cc
  377. if "%~2" equ "" goto :eof
  378. call :init_setfont
  379. %setFont% %~1 %~2
  380. goto :eof
  381.  
  382. :init_setfont DON'T CALL
  383. :: - BRIEF -
  384. ::  Get or set the console font size and font name.
  385. :: - SYNTAX -
  386. ::  %setfont% [fontSize [fontName]]
  387. ::    fontSize   Size of the font. (Can be 0 to preserve the size.)
  388. ::    fontName   Name of the font. (Can be omitted to preserve the name.)
  389. :: - EXAMPLES -
  390. ::  Output the current console font size and font name:
  391. ::    %setfont%
  392. ::  Set the console font size to 14 and the font name to Lucida Console:
  393. ::    %setfont% 14 Lucida Console
  394. setlocal DisableDelayedExpansion
  395. set setfont=for /l %%# in (1 1 2) do if %%#==2 (^
  396. %=% for /f "tokens=1,2*" %%- in ("? ^^!arg^^!") do endlocal^&powershell.exe -nop -ep Bypass -c ^"Add-Type '^
  397. %===% using System;^
  398. %===% using System.Runtime.InteropServices;^
  399. %===% [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)] public struct FontInfo{^
  400. %=====% public int objSize;^
  401. %=====% public int nFont;^
  402. %=====% public short fontSizeX;^
  403. %=====% public short fontSizeY;^
  404. %=====% public int fontFamily;^
  405. %=====% public int fontWeight;^
  406. %=====% [MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)] public string faceName;}^
  407. %===% public class WApi{^
  408. %=====% [DllImport(\"kernel32.dll\")] public static extern IntPtr CreateFile(string name,int acc,int share,IntPtr sec,int how,int flags,IntPtr tmplt);^
  409. %=====% [DllImport(\"kernel32.dll\")] public static extern void GetCurrentConsoleFontEx(IntPtr hOut,int maxWnd,ref FontInfo info);^
  410. %=====% [DllImport(\"kernel32.dll\")] public static extern void SetCurrentConsoleFontEx(IntPtr hOut,int maxWnd,ref FontInfo info);^
  411. %=====% [DllImport(\"kernel32.dll\")] public static extern void CloseHandle(IntPtr handle);}';^
  412. %=% $hOut=[WApi]::CreateFile('CONOUT$',-1073741824,2,[IntPtr]::Zero,3,0,[IntPtr]::Zero);^
  413. %=% $fInf=New-Object FontInfo;^
  414. %=% $fInf.objSize=84;^
  415. %=% [WApi]::GetCurrentConsoleFontEx($hOut,0,[ref]$fInf);^
  416. %=% If('%%~.'){^
  417. %===% $fInf.nFont=0; $fInf.fontSizeX=0; $fInf.fontFamily=0; $fInf.fontWeight=0;^
  418. %===% If([Int16]'%%~.' -gt 0){$fInf.fontSizeY=[Int16]'%%~.'}^
  419. %===% If('%%~/'){$fInf.faceName='%%~/'}^
  420. %===% [WApi]::SetCurrentConsoleFontEx($hOut,0,[ref]$fInf);}^
  421. %=% Else{(''+$fInf.fontSizeY+' '+$fInf.faceName)}^
  422. %=% [WApi]::CloseHandle($hOut);^") else setlocal EnableDelayedExpansion^&set arg=
  423. endlocal &set "setfont=%setfont%"
  424. if !!# neq # set "setfont=%setfont:^^!=!%"
  425. exit /b
  426.  
  427. :Error
  428.     <nul Set /p "=Error:" & CMD /C Set /A %1
  429. Exit /B
  430.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement