Batch not checking if variable = 0 - variables

So, I'm making a game using batch coding, and I have a shop within the game that's only supposed to sell one of each item. Unfortunately, when I set the variable for the item to 1, then reduce it to 0, the code doesn't acknowledge that there are no more items to sell.
:ForestHagShop
cls
set WSwrdHag=1
set WShldHag=1
set GldApHag=1
echo "What would you like, my dear?"
echo 1.) Wooden Sword - 50 gold - (+10 Attack)
echo 2.) Wooden Shield - 70 gold - (+30 Max HP)
echo 3.) Shiny Apple - 40 gold - (+30 HP)
echo.
set /p input6=)
if %input6% equ 1 goto BuySwrdHagChk
if %input6% equ 2 goto BuyShldHag
if %input6% equ 3 goto BuyAplHag
:BuySwrdHagChk
echo Checking...
echo.
echo **PRESS A KEY**
Pause >nul
if WSwrdHag LSS 1 goto OutSwordHag
:BuySwrdHag
set /a Gold=Gold-50
set /a Attack=Attack+10
set /a WSwrdHag=WSwrdHag-1
echo You hand over 50 gold for the
echo wooden sword. Your new stats are...
echo Health Points .. .. .. %HP%/%MaxHP%
echo Gold .. .. .. .. .. .. %Gold%
echo Attack Power .. .. .. %Attack%
echo.
echo **PRESS A KEY**
pause >nul
goto ForestHagShop
:OutSwordHag
echo The hag frowns, looking at you like
echo you're stupid.
echo "You already bought my wood sword,
echo idiot!"
echo.
echo **PRESS A KEY**
pause >nul
goto ForestHagShop

Looks like you forgot the % delimiters when checking the variable...
Change
if WSwrdHag LSS 1 goto OutSwordHag
to be
if %WSwrdHag% LSS 1 goto OutSwordHag
and also these
set /a Gold=Gold-50
set /a Attack=Attack+10
set /a WSwrdHag=WSwrdHag-1
to be
set /a Gold=%Gold%-50
set /a Attack=%Attack%+10
set /a WSwrdHag=%WSwrdHag%-1

Related

Batch script to rename files in subfolders

I need a script which rename all files in all sub folders of script's root.
I did search and found something which works and I can modify (I am a little bit newbie/laic)
#echo off
chcp 65001
setlocal enabledelayedexpansion
set filename=image
set /a x=1
>#rename.txt (
for /r %CD% %%f in (*.jpg) do (
echo rename "%%f" "!filename!_!x!.jpg"
rename "%%f" "!filename!_!x!.jpg"
set /a x+=1
)
)
endlocal
pause
But I want this to rename files to random string.
I found a lots of scripts which can generate random strings, but I just can't make them to work inside the FOR brackets.
for now im stuck with
#echo off
chcp 65001
setlocal enabledelayedexpansion
set /a x=%RANDOM%/99
>#rename.txt (
for /r %CD% %%f in (*.jpg) do (
echo "%%f" renamed to "!x!.jpg"
rename "%%f" "!x!.jpg"
set /a x+=%RANDOM%/99
)
)
endlocal
Which works fine, but has his limitations.
Any help will be appreciated
#echo off
chcp 65001
setlocal enableextensions enabledelayedexpansion
set "alphabet=a b c d f g h i j k l m n p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9"
set "size=0"
for %%a in (%alphabet%) do (
set "a.!size!=%%a"
set /a "size+=1"
)
for /r %CD% %%f in (*.jpg) do (
set "k="
for /l %%a in (1 1 64) do (
set /a "r=!random! %% size"
for %%b in (!r!) do set "k=!k!!a.%%b!"
)
rename "%%f" "!k!.jpg"
)
endlocal

batch if loop not able to execute

iam trying to put if loops in batch script but not getting desired result, please look into code ans suggest where iam wrong in if loop
IF %banned% == 1 echo "vvvvv" it not comparing properly
even 1==1 and 1==0 is same for batch script?
call E:\utility\batfiles\DBAEnvProd.cmd
set dbname=UMRdb
set proc=UMRdb.[dbo].[maintenancemode]
call %osqlExeLocation% -E -d%dbname% -S%svr% -w%w% -b -Q"exec %proc%" -o%pathout%%Maintmode.txt
#echo on
set "usrname=Y"
set "banfile=E:\utility\sysout\Maintmode.txt"
find /i "%usrname%" "%banfile%" >nul 2>&1&&set /a banned=1 || set /a banned=0
echo %banned%
echo comparing maintenance
IF %banned% == 1 echo "vvvvv"
(
here banned is 1 then i dont want to execute rest of code it shd
go to endgood
)
else
normal code should be executed
#echo on
REM ********************************************************************************
REM JOB: TCMP_DBA_M_MNT_UMR_ESSENTIAL
REM
REM ********************************************************************************
set job=TCMP_DBA_M_MNT_UMR_ESSENTIAL
set RetCode=0
time /T & date /T
erase %pathout%%job%*.suc > nul
erase %patherr%%job%*.err > nul
REM ********************************************************************************
REM to display date and time
for /F "tokens=1-3 delims=:. " %%A in ('time/T') do set var=%%A%%B%%C%
set timestamp=%date:~4,2%%date:~7,2%%date:~10,4%
set timestamp1=%timestamp%%var%
REM
REM ********************************************************************************
:main
echo --- DB Growth Info
set proc=UMRdb.[dbo].[spCollectDBSpaceInfo]
call %osqlExeLocation% -E -d%dbname% -S%svr% -w%w% -b -Q"exec %proc%" -o%pathout%%job%_spCollectDBSpaceInfo.txt
if errorlevel 1 (
set RetCode=1
goto endbad
)
echo --- Cleanup of output files older than 30 days in sysout folder
call forfiles -p E:\utility\sysout /D -30 /M *.txt /C "cmd /c del #file"
:ENDGOOD
set RetCode=0
ECHO SUCCESS!!! %svr% %job% %proc%
echo %ErrMsg% > %pathout%%job%.SUC
GOTO END
:ENDBAD
set RetCode=1
ECHO ERROR!!! %svr% %job% %proc%
echo SEE %pathout%%job%_%proc%.txt FOR ERRORS > %patherr%%job%.ERR
:END
time /T & date /T
echo %RetCode%
%pathexe%cc.exe %RetCode%
REM EXIT
this is problematic
IF %banned% == 1 echo "vvvvv"
if == performs a string comparision and i'm seeing lots of spaces. if %banned% is 1 here you are comparing " 1" == "1 ". As you set/a banned=1, it would be better do a numeric comparision
IF %banned% EQU 1
or quoted string comparision
If "%banned%" == "1"

Batch- Issues with Changing Variables/Booleans

I am making a Batch RPG and currently I'm trying to create a shop where you can
buy weapons and stuff. I want to make it so that if the player has enough gold (gld) that they can buy the weapon and it changes the weapon's boolean to true and takes away 20 gold from the gld variable. What am I doing wrong? It doesn't subtract the gold or change to boolean to true.
Here is the code:
set /p sword="Enter your selected sword number:"
if %sword%==1 if %gld% GEQ 20 set /a sword1 EQU true
if %sword%==1 if %gld% GEQ 20 set /a gld EQU %gld%-20
if %sword%==1 if %gld% LSS 20 echo You don't have enough gold!
The problem is that you're not using the set command correctly.
set /p sword="Enter your selected sword number:"
if %sword%==1 if %gld% GEQ 20 set sword1=true
if %sword%==1 if %gld% GEQ 20 set /a gld-=20
if %sword%==1 if %gld% LSS 20 echo You don't have enough gold!
You can also make one if else statement to do the same thing
set /p sword="Enter your selected sword number:"
if %sword%==1 if %gld% GEQ 20 (
set sword1=true
set /a gld-=20
) else (
echo You don't have enough gold!
)

Having issues with setting variables in loop

I am trying to use !errorlevel! as a condition inside a loop. I pass error level in a call and then I try and use findstr again to set errorlevel but the condition is not seeing the change.
setlocal EnableDelayedExpansion
for /F %%i in (%Newzips.lst%) do (
echo unzipping %%i >> test.log
wzunzip -o %%i
call :startloop
)
exit /B
:startloop
dir /b *.dat > %Stagedat.lst%
for /F %%l in (%Stagedat.lst%) do (
dir /b E:\NOMADD_FILES\AV\*.dat > %AVdat.lst%
findstr /i /c %%l %AVdat.lst%
echo top error level - !errorlevel!
call :checkdup %%l !errorlevel!
)
exit /B
:checkdup
if !errorlevel! == 0 (
dir /b E:\NOMADD_FILES\AV\*.dat > %AVdat.lst%
findstr /i %1 %AVdat.lst% >> test.log
echo found match so sleep e >> test.log
echo error level - !errorlevel! >> test.log
sleep 3
echo duplicate in AVdat.lst >> test.log
call :checkdup %1 !errorlevel!
)
if !errorlevel! == 1 (
echo copying file %2 >> test.log
move /Y %1 E:\NOMADD_FILES\AV
sleep 5
dir /b E:\NOMADD_FILES\AV\*.dat > %AVdat.lst%
echo moveing AVdat.lst >> test.log
echo error level - !errorlevel! >> test.log
type %AVdat.lst% >> test.log
)
exit /B
:end
So what is happening is after I get down to :checkdup and findstr runs again, !errorlevel! is being updated to 1 but it is still staying inside the top if statement.
This is a sample from the log.
top error level - 0
bcs3_ammo_inv_updates.dat
found match so sleep e
error level - 0
duplicate in AVdat.lst
bcs3_ammo_inv_updates.dat
found match so sleep e
error level - 0
duplicate in AVdat.lst
bcs3_ammo_inv_updates.dat
found match so sleep e
error level - 0
duplicate in AVdat.lst
found match so sleep e
error level - 1
duplicate in AVdat.lst
found match so sleep e
error level - 1
duplicate in AVdat.lst
found match so sleep e
error level - 1
So error level is being set to 1 but it is stuck in the if !errorlevel! == 0 condition. It should go to the other check and continue through the for loop. I've been stuck on this for a couple days now trying many different combinations to get it to work.
Thanks
:checkdup
if !errorlevel! == 0 (
...
echo error level - !errorlevel! >> test.log
sleep 3
rem AND AFTER SLEEP, which is the value of errorlevel?
call :checkdup %1 !errorlevel!
)

Batch file to display directory size

I want to modify this script. I can't get it to accept wildcard charcters:
#echo off
setLocal EnableDelayedExpansion
set /a value=0
set /a sum=0
FOR /R %1 %%I IN (*) DO (
set /a value=%%~zI/1024
set /a sum=!sum!+!value!
)
#echo Size is: !sum! k
It is in a batch file called dirsize and is called like so:
dirsize c:\folder
I want it to check the folder sizes for me. This one here is an example, the cache in firefox:
dirsize C:\users\%username%\AppData\Local\Mozilla\Firefox\*.default\Cache
It returns the value 0.
But if I go
dirsize C:\users\%username%\AppData\Local\Mozilla\Firefox\sr1znnb4.default\Cache
It works and I get the value 55322 returned.
PowerShell makes this easy, of course:
(gci . -Recurse | Measure-Object -Property Length -Sum).Sum
And PowerShell is already installed on Windows 7. Get on the bandwagon! :-)
Also, C:\users\%USERNAME%\AppData\ isn't a reliable way of finding AppData. Try %APPDATA% (or $env:APPDATA in PowerShell).
Ok for a starter, lets say wildcards are not well supported throughout batch files, and specially in for loops.
That's what I came up with:
DirSize.cmd "valid path"
#echo off
rem Args[1]= "Path" or "valid path with wildcard"
set _size=0
set dRaw=%~1
echo %~1|findstr "*"&& set dSource=%~dp1|| (
set dSource=%~1\
if not "%dRaw:~-1%"=="\" set dRaw=%dRaw%\
)
for /f "delims=" %%D in ('dir /ad /b %dRaw%') do call :DirSize "%dSource%%%~D"
set /a size=_size/1024
echo size=%size% k (%_size% bytes)
exit /b 0
:DirSize
call :FileSize "%~1"
for /f "delims=" %%d in ('dir /ad /b "%~1"2^>nul') do call :DirSize "%~1\%%~d"
exit /b 0
:FileSize
for /f "delims=" %%f in ('dir /a-d /b "%~1\"2^>nul') do for %%F in (%1\%%f) do set /a _size+=%%~zF
exit /b 0
___Usage___
Argument: Needs to be a path (not a file) that either contain wildcards or not. Path need top be valid when typing dir path
___Notes___
This script does check for all files and sub-directories, even hidden/system ones.
change the dir /a argument and add -h-s (like /ad-h-s) to remove this behaviour.
I revised the argument checking to my liking now, so I think it is usable.
I hope this helps.
You would need to wrap what you currently have in another for loop which expands the * into a series of directories.
So
#echo off
setLocal EnableDelayedExpansion
set /a sum=0
for /d %%D in (%1) do (
FOR /R %%D %%I IN (*) DO (
set /a value=%%~zI/1024
set /a sum=!sum!+!value!
)
)
echo Size is: !sum! k
might work (untested, though, but should give you the general idea)
If you have a Windows version of grep (you can find one at GNU utilities for Win32) you can do something like this:
dir /s %1 | grep --after-context=1 "Total Files Listed:"
This code will increase directory size limit up to 2,000,000 TB and will display more real size, what would be useful if the folder contains too many files.
rem SET DIR=%1
SET DIR=C:\DIR1\
IF NOT EXIST "%DIR%" (
ECHO Directory "%DIR%" does not exist.
goto END
)
setlocal EnableDelayedExpansion
set GB=
set SIZE=
set exp=000000000
FOR /R "%DIR%" %%F IN (*) DO (
set /a SIZE=!SIZE!+%%~zF
if !SIZE! geq 1!exp! (
set /a GB=!GB!+!SIZE:~0,-9!
for /f "tokens=* delims=0" %%a in ("!SIZE:~-9!") do set SIZE=%%a
)
)
if not defined SIZE set SIZE=0
if not defined GB goto EOS
FOR /L %%N IN (1,1,9) DO (
if "!SIZE:~%%N!" == "" (
set SIZE=!GB!!exp:~%%N!!SIZE!
goto EOS
)
)
:EOS
call :Divide !SIZE! 1024 SIZEKB
echo Size is: !SIZE!B (!SIZEKB!kB)
endlocal
:END
pause
exit
:Divide
set Num1=%~1
set Num2=%~2
set %3=
set Num=
set Number=
IF !Num2! EQU 0 goto :EOF
FOR /L %%N IN (0,1,18) DO (
if "!Num1:~%%N!" == "" goto :EOD
set Number=!Number!!Num1:~%%N,1!
if !Number! geq !Num2! (
set /a quotient=!Number!/!Num2!
set /a Number=!Number!-!quotient!*!Num2!
if !Number! equ 0 set Number=
set Num=!Num!!quotient!
) else (
if defined Num set Num=!Num!0
)
)
:EOD
if not defined Num set Num=0
set %3=%Num%
goto :EOF
10x faster than doing it through FOR.
With the advantage of being able to use any of the permitted parameters of the DIR command (in this case /S)
#ECHO OFF
SET folder="C:\WINDOWS"
call:timer
ECHO Processing, please wait...
CALL :folderSize size %folder% "/S"
CALL :strNumDivide sizeKb %size% 1024
CALL :strNumDivide sizeMb %sizeKb% 1024
CALL :strNumDivide sizeGb %sizeMb% 1024
CALL :formatNumber size %size%
CALL :formatNumber sizeKb %sizeKb%
CALL :formatNumber sizeMb %sizeMb%
CALL :formatNumber sizeGb %sizeGb%
ECHO.
ECHO Size of %folder%:
ECHO.
ECHO %size% bytes
ECHO %sizeKb% Kb
ECHO %sizeMb% Mb
ECHO %sizeGb% Gb
ECHO.
pause
exit /b
:: Function to calculate the size of a directory and its subdirectories
::----------------------------------------------------------------------
:folderSize <returnVariableName> <folder> [DIR parameters]
SetLocal EnableExtensions EnableDelayedExpansion
SET folder=%2
SET params=%~3
IF NOT DEFINED folder SET folder="%CD%"
DIR %params% /W "%folder:"=%" > %TEMP%\folderSize.tmp
FOR /F "tokens=1 delims=:" %%x IN ('findstr /n /e ":" %TEMP%\folderSize.tmp') DO (SET line=%%x)
IF DEFINED line (
SET /A line = !line! + 1
FOR /F "tokens=4 delims= " %%i IN ('findstr /n "bytes" %TEMP%\folderSize.tmp^|findstr "!line!:"') DO (SET size=%%i)
SET size=!size:.=!
) ELSE (
FOR /F "tokens=3 delims= " %%i IN ('findstr /e "bytes" %TEMP%\folderSize.tmp') DO (SET size=%%i)
SET size=!size:.=!
)
DEL %TEMP%\folderSize.tmp > nul
EndLocal & SET "%~1=%size%"
GOTO:EOF
:: Extras functions to convert between different units and to give numerical format
:: --------------------------------------------------------------------------------
:strNumDivide <returnVariableName> <stringNum> <divisor>
SetLocal EnableExtensions EnableDelayedExpansion
SET strNum=%~2
SET divisor=%~3
SET result=
SET number=
IF !divisor! EQU 0 GOTO:EOF
FOR /L %%n IN (0,1,18) DO (
IF NOT "!strNum:~%%n!" == "" (
SET number=!number!!strNum:~%%n,1!
IF !number! GEQ !divisor! (
SET /A quotient=!number! / !divisor!
SET /A number=!number! - !quotient! * !divisor!
IF !number! EQU 0 SET number=
SET result=!result!!quotient!
) ELSE (
IF DEFINED result SET result=!result!0
)
)
)
IF NOT DEFINED result SET "result=0"
EndLocal & SET "%~1=%result%"
GOTO:EOF
:formatNumber <returnVariableName> <number> [separator [group size]]
SetLocal EnableExtensions EnableDelayedExpansion
SET "raw=%~2"
SET "separator=%~3"
SET "group=%~4"
SET "answer="
IF NOT DEFINED raw GOTO :EOF
IF NOT DEFINED separator SET "separator=."
IF NOT DEFINED group SET "group=3"
FOR %%g IN (-%group%) DO (
FOR /F "tokens=1,2 delims=,." %%a IN ("%raw%") DO (
SET int=%%a
SET frac=%%b
FOR /F "delims=:" %%c IN ('^(ECHO;!int!^& Echo.NEXT LINE^)^|FindStr /O "NEXT LINE"') DO (
SET /A length=%%c-3
)
FOR %%c IN (!length!) DO (
SET radix=!raw:~%%c,1!
)
FOR /L %%i IN (!length!, %%g, 1) DO (
SET answer=!int:~%%g!!separator!!answer!
SET int=!int:~0,%%g!
)
)
)
SET answer=%answer: =%
SET answer=%answer:~0,-1%
EndLocal & SET "%~1=%answer%%radix%%frac%"
Goto :EOF
Result output example:
(in the example, the routine took 3 seconds to calculate the size of the C: \ WINDOWS with a size of 28GB)
Processing, please wait...
Size of "C:\WINDOWS":
30.936.389.769 bytes
30.211.318 Kb
29.503 Mb
28 Gb
Elapsed Time: 3 secs