I'm making an RPG game in Batch and I need to make it so that if the player hasn't bought a certain weapon it doesn't show up as an option to use. Currently, I have a battle system in which you press a key to use a weapon you have. However, I don't know how to make it so that if you don't own a certain weapon, you can't use it.
I also want it so that even if the text doesn't show, the user still can't use it if they don't have it. For example, if you don't have a sword but you know that to use it you press s, I don't want it to work unless you have it. That way people can't just cheat.
Please help!
Here is the code:
if %sword1% equ true echo 2-Tachi
set /p e="Weapon to equip:"
pause
I don't want the user to just type 2 and have the Tachi. I want it so that they have to
have the weapon to use it.
#echo off
setlocal enabledelayedexpansion
set w1=sword
set w2=bow
set w3=axe
set w4=machinegun
set w5=warbow
set w1?=true
set w2?=false
set w3?=true
set w4?=false
set w5?=false
:loop
echo ----------
for /L %%i in (1,1,9) do (
if !w%%i?!==true echo %%i - !w%%i!
)
set /p e="Weapon to equip: "
if !w%e%?!==true (
echo you have choosed: !W%e%!
) else (
echo you don't have one.
goto :loop
)
echo now, that you have a !W%e%!, go and fight!
echo Bamm - Wush - Ouch
if %random% lss 10000 (
echo Congratulations, you have found a %w4%.
set "w4?=true"
)
pause
goto :loop
EDIT (explanations to the code)
the first block of set just sets the names of the weapons.
The second block of set sets it they are available to the player. (in gameplay, usually there is only one available in the beginning, others can be found or bought during the game).
The ? in the variable names is nothing special, only a char like any letter. If it confuses you, you can also use something like B (like boolean): set w5B=false
The for-loop is the heart of this code. It displays all available weapons (it tries w1 to w9. You can adapt it to process hundreds or even thousands of items (it starts from 1, increments by 1 until 9))
If it is available (true), it echoes the number (%%i) and the weapon-name.
!w%%i?! is a bit tricky. %%i is the "loop-counter" (1,2,3,...,9), so w%%i? will translate to (for example) w4? (and w%%i to w4.
Because you need the variable with that name, you'll have to put it between %, but as %%i is already part of the variable, the interpreter would get confused. For that, we use delayed expansion (search for it in stackoverflow, there are more findings than you can read) and therefore can use ! instead of %, so the complete variable is named !w%%i?! (remember: the ? is just a letter). (don't be depressed, if you don't get it the first time, just play around with it and it will make sense to you some day).
The if after the set /p e="Weapon to equip: " checks, if the weapon is available (true) if yes, fine, if no then error/try again.
The if %random%... part shows you how to make an item available (true). You can also make one unavailable by setting the flag to false.) Wheather you do that like me as a finding in a fight, or in a shop (buy/sell), the doing is the same.
I'm sure, you already guessed, that you'll have to replace echo Bamm - Wush - Ouch with some code for a fight.
I find it hard to come up to a solution since the user will be able to edit the .bat file anyway? Wouldn't it be better to write it in C++ or C#?
Related
I'm making a sort of text based story game and RPG, and I'm labelling each "section", as I call it, with a tag. A section is basically any directed goto, like :section1. You get to :section1 by having goto section1.
I've assigned each screen with a tag using a system of letters and numbers. What I've done is used a simple save/load code using .sav, and am using the following.
Save:
(
echo %tag%
echo %points%
echo %weapon%
) > savegame.sav
Load:
< savegame.sav (
set /p tag=
set /p points=
set /p weapon=
)
The game is linear, by the way. What I'm trying to attempt is upon load, I gather the tag and go to that screen associated with the tag. For example, if I saved the game at tag 23, I want to be able to load in tag 23 and automatically go into section 23 without having to manually type in if %tag% == 23 goto 23. Is there a way to do this quickly?
echo Save Game Loaded.
IF %tag%==02 goto tag02
IF %tag%==03 goto tag03
:tag02
IF NOT %tag%==02 set tag=02
(your save code goes here)
echo this is tag02
:tag03
IF NOT %tag%==03 set tag=03
(your save code goes here)
echo this is tag03
It tried to keep it simple. But you can do it this way.
You can use the variable as destination:
#echo off
set "tag=213"
goto :%tag%
this line is never reached.
:23
echo reached 23
goto :eof
You can also combine with a fix string goto :Section%tag% and :Section23 as label.
(Note: the colon in goto :destination is optional. I like it for clarity, others don't. Pick your choice)
I'm trying to make a code where I can go to websites without going to my browser I have atop search function which I will change manually I'm fairly new to coding so any advice is helpful here is the code.
#echo off
echo Top searches
echo 1. Faceit
set /p name =
if %name% EQU "1" goto F
if %name% NEQ "1" then goto custom
:F
start "" https://www.faceit.com/en
:custom
echo What website would you like to go to?
set /p x =
start "" https://www.%x%
There's quite a bit going on in your code that is keeping it from working in any meaningful sort of way. Just at an initial glance, I see ten separate things that are either completely wrong or simply violate what could be considered "good programming practices" in batch.
1/2. Whitespace in variable names is significant
For some reason, Microsoft decided to allow whitespace in variable names, so %this is a valid variable name%. Seriously. As a result of this, both of your set /p statements are creating variables that you never use.
Instead of set /p name = and set /p x =, use set /p name= and set /p x=
3/4. Put quotes around set statements
This one is just good programming practice and is arguably not "wrong," but it's a good habit to form early.
Use quotes to avoid the user entering things like & or > and having those break the flow of the script. You can put the quotes to the around the prompt (like set /p variable="Enter text: "), but if you do that with a regular set statement, the quotes will become part of the value. To avoid this, put the first quote to the left of the variable name, like this: set /p "variable=Enter text: "
This also prevents any hidden spaces from getting tacked on at the end of the value by accident.
5. Then is not a keyword in batch
The then in your second if statement if going to give you a syntax error because it's not a valid keyword in batch. Just get rid of it.
if "%name%" NEQ "1" goto custom
6/7. Quotes in comparisons are significant
When you put quotes around one side of a comparison, you need to put quotes on the other side as well. This has the added effect of keeping characters like & and > from breaking the flow of the script.
if "%name%" EQU "1" goto F
if "%name%" NEQ "1" goto custom
8. A missing goto (or exit) will cause :custom to run immediately after :F
Batch scripts run from top to bottom unless acted upon by a goto, call, if, or some other flow control command. In this case, after start "" https://www.faceit.com/en is called, the very next non-whitespace line is :custom.
To avoid :custom from running, kill the script after the first start with exit /b or goto :eof - both of these will stop the script but keep the command prompt open if you ran the script from the command line instead of double-clicking it. Note that if you use goto :eof, you do not need to make a :eof label, since it's built into the command prompt.
9/10. Put colons in front of labels in goto commands
Again, not necessary, just good programming practice. You have to include the colons when you use call to run subroutines anyway, so you might as well be consistent everywhere.
Other notes
When the script is first run, all you see is
Top searches
1. Faceit
and that's it. Nothing to tell the user what to do or to indicate that they can enter another site by typing something other than 1. Unless you plan on being the only person to use the script, I'd recommend putting something somewhat more descriptive in that section.
If you're going to automatically tack on https://www. to the start of a custom URL, put that on the screen so that the user doesn't accidentally end up going to https://www.https://www.google.com or something.
You may want to look into the choice command for future versions of the script to replace the initial set /p command, depending on how many options you want to give the user.
Putting comments in your code wouldn't hurt.
Ultimately, it will look something like this
#echo off
echo Top searches
echo 1. Faceit
echo Enter anything else to go to a different site
set /p "name=Your selection: "
if "%name%" EQU "1" goto :F
if "%name%" NEQ "1" goto :custom
:F
start "" https://www.faceit.com/en
exit /b
:custom
echo What website would you like to go to?
set /p "x=https://www."
start "" https://www.%x%
I would like to extract what users are online based on this text file:
https://minecraft-statistic.net/en/server/167.114.43.185_25565/json/
I will save it as a text file. Inside that there is something:
"players_list":["Raskhol"]["Lukaka"],"map":...etc
I would like to extract all the text between "_list": and ,"map" and set it as a variable. So that when I call the variable %Playerlist%, it would say:
["Raskhol"]["Lukaka"]
similar to #geisterfurz007's answer, this one assumes the you are after the first instance of "players_list": before the first instance of ,"map"
#Echo Off
Set/P var=<some.json
Set var=%var:,"map"=&:%
Set var=%var:*"players_list":=%
Echo=%var%
Timeout -1
Not tested due to beeing on phone.
#echo off
For /f "delims=: tokens=2" %%g in (PathTo\file.txt) do (
Set var=%%g
Goto:next
)
:next
Set var=%var:,map=%
echo %var%
Assumes players are the first to be listed.
Reads the file, takes the part after the first : up to the second one, stores it in var.
Then ,map gets replaces with nothing to result in just the players beeing echoed in the end.
Feel free to ask questions if something is unclear! Might take a while as I am currently mobile though.
In this qustion, Save and Load .bat game I used Mat's answer.
But now I have a problem with "saving" numbers using said answer.
If the variable is not double digits (for example 1 or 0) it will "save" the variable as " " and thus will crash the game whenever you do anything that needs that variable. The game sets the variable fine before that.
For example if I pick up the rag, then type Inv, it will say I'm holding the rag. If I then save and load again, then type Inv, it wont say I'm holding anything!
It also won't echo "Nothing" which it should do if %raghave% = 00
(I also have the save file open in Notepad++ and so can see that set RagHave=)
(Also if I use Mat's code with the spaces, then the variable is set as "set RagHave=1" and so adds a space at the end)
The problem is Mat's solution!
For better understanding I repeat his solution
#echo #ECHO OFF > savegame.cmd
#echo SET ITEMS=%ITEMS% >> savegame.cmd
#echo SET HEALTH=%HEALTH% >> savegame.cmd
#echo SET MONEY=%MONEY% >> savegame.cmd
In my opinion, it has multiple disadvantages.
The # prefix isn't necessaray.
The redirection is repeated for each line (I don't like redundancy).
It needs the spaces, as without spaces you got problems with numbers.
Sample with items=1
#echo set ITEMS=1>>savegame.cmd
This results not in writeing set items=1 it writes set items= to 1>>savegame.cmd 1>> is the standard stream.
You can solve all problems with
(
echo #ECHO OFF
echo SET "ITEMS=%ITEMS%"
echo SET "HEALTH=%HEALTH%"
echo SET "MONEY=%MONEY%"
) > savegame.cmd
The quotes are used to ensure that "hidden" spaces after the set are ignored.
Btw. It's a bad idea to use a construct like if %raghave% = 00, (you need two equal signs), as 00 isn't a normal number you can't count or calculate with it, it's better to use 0 instead.
Then also this should work
set /a items=0
set /a items=items+1
set /a items=items-1
if %items%==0 echo There are no items
I am writing a batch file (I asked a question on SU) to iterate over terminal servers searching for a specific user. So, I got the basic start of what I'm trying to do.
Enter a user name
Iterate terminal servers
Display servers where user is found (they can be found on multiple servers now and again depending on how the connection is lost)
Display a menu of options
Iterating terminal servers I have:
for /f "tokens=1" %%Q in ('query termserver') do (set __TermServers.%%Q)
Now, I am getting the error...
Environment variable __TermServers.SERVER1 not defined
...for each of the terminal servers. This is really the only thing in my batch file at this point. Any idea on why this error is occurring? Obviously, the variable is not defined, but I understood the SET command to do just that.
I'm also thinking that in order to continue working on the iteration (each terminal server), I will need to do something like:
:Search
for /f "tokens=1" %%Q in ('query termserver') do (call Process)
goto Break
:Process
for /f "tokens=1" %%U in ('query user %%username%% /server:%%Q') do (set __UserConnection = %%C)
goto Search
However, there are 2 things that bug me about this:
Is the %%Q value still alive when calling Process?
When I goto Search, will the for-loop be starting over?
I'm doing this with the tools I have at my disposal, so as much as I'd like to hear about PowerShell and other ways to do this, it would be futile. I have notepad and that's it.
Note: I would continue this line of questions on SuperUser, except that it seems to be getting more into programming specifics.
Ok, those are quite a few questions/issues/etc. in one :-)
And I still don't quite get where exactly you're headed with that script.
First of all, the syntax for the set command is
set <variable name>=<value>
If you do just
set <variable name>
then it will list all environment variables starting with <variable name>. If there are none, then it will output the error message you're seeing.
If you want to define a variable without actually caring about its value, you still need to provide a value. I usually use 1 for such flags, since it's then more an on/off switch than an actual variable holding a value:
set Foo=1
In your case you probably want something else, though. There are no arrays per se in batch files, you can mimic them by creating a number of variables and holding a count somewhere. I've written about that once before (a little outdated by now, but still valid).
In your case you want to iterate over a number of servers and for each server over a number of users. You can do that with a nested loop:
for /f "tokens=1" %%Q in ('query termserver') do (
for /f "tokens=1" %%U in ('query user ... /server:%%Q' do (
...
)
)
As for your two questions there:
No, the loop variable is only valid inside the loop, not when calling a subroutine. You can pass it to the subroutine, however:
for ... in (...) do call Process %%Q
You can then access it with %1 in the subroutine. Honestly, though, in most cases I think the nested loops are easier to read.
Yes.
Another error (one that will bite you): As mentioned before, the set syntax is
set variable=value
Note that there is no space around the = sign. If there is, then you have a space at the end of the variable name or at the start of the value:
> set foo = bar
> echo %foo%
%foo%
> echo %foo %
bar