2

Alright so I am making a pretty simple game in batch and I decided I wanted to add some abilities to enemies. I tried to make a code that would let them use abilities but it crashes after a set /a statement with nothing wrong with it. My code that is relevant is separated into 4 main parts. I'm going to put the code in order of where they are in my file. These are not the only things in it. All my characters stats like strength, stamina, agility, and intellect are working perfectly fine.


The Initialization of the enemy

This is what is loaded at the start of the battle to give the enemy stats and such.

:bearstart1
set enemytype=beast
set curenemy=Bear
set /a allstat= %strength% + %stamina% + %agility% + %intellect%
set /a randamage= %weapondamage% / (%level% * 2)
set enevasion=1
set /a hitacc= %accuracy% * 10
set /a hitran=%RANDOM% * (1000 - 1 + 1) / 32768 + 1
set enemyaccuracy=1
set /a eneacc= %enemyaccuracy% * 10
set /a enemylevel= %RANDOM% * (2 - 1 + 1) / 32768 + 1
set enemyhealth=75 + (5 * %enemylevel%)
set enemymaxhealth=75 + (5 * %enemylevel%)
set enemyenrgy=30 + (%enemylevel% * 5)
set /a enemyenergy=%enemyenrgy%
set enemymaxenergy=30 + (%enemylevel% * 5)
set enemyenergyregen=2
set enemydefense=17 + %enemylevel%
set /a enemyabilities=1
set enemycurabilityname=Claw
set enemycurabilityID=001
set enemycurabilityslot=1
set enemycurabilitychance=30
set statfixloc=bearstart2
goto :statfixesenemyability
:bearstart2
set enevasion=1
set /a enemydamage=18 + %enemylevel%
set /a ranxpgain=(%RANDOM% * ((10 * %level%) - 1 + 1) / 32768 + 1)
set /a ranxpgain=(%RANDOM% * ((15 * %level%) - 1 + 1) / 32768 + 1)
set /a atkaccuracy= (550 + %hitacc%) - (%enevasion% * 10)
set /a eneaccuracy= (450 + %eneacc%) - (%evasion% * 10)
set enemyattack= %enemydamage% - (%defense% / 2)
set /a realdamage= %damage% - (%enemydefense% / 2)
set /a randamagemax= %realdamage% + randamage
set /a randamagemin= %realdamage% - randamage
set /a randomdamage= %RANDOM% * (%randamagemax% - %randamagemin% + 1) / 32768 + %randamagemin%
set /a enemyrandamage= %enemydamage% / (%enemylevel% * 3)
set /a enemyrealdamage= %enemydamage% - (%defense% / 2) + (%enemylevel% - 1 * 5)
set /a enemyrandamagemax= %enemyrealdamage% + %enemyrandamage%
set /a enemyrandamagemin= %enemyrealdamage% - %enemyrandamage%
set /a enemyrandomdamage= %RANDOM% * (%enemyrandamagemax% - %enemyrandamagemin% + 1) / 32768 + %enemyrandamagemin%

The Fight Screen

This is the menu of which the player can choose options as to what to do in battle and is mainly for a reference as to the order in which these parts of code are in. This is literally a line after the the initialization above.

:fightscreen
set /a health=%health%
set /a enemyhealth=%health%
IF %health% LEQ 0 goto :dead
IF %enemyhealth% LEQ 0 goto :fightend
cls
Echo ######################################
Echo # Enemy:%curenemy%
Echo # Enemy Health: %enemyhealth%/%enemymaxhealth%
Echo # Enemy Energy: %enemyenergy%/%enemymaxenergy%
Echo # Enemy Defense: %enemydefense%
Echo # Enemy Attack: %enemyattack%
Echo ######################################
Echo # %name%
Echo # Level:%level%
Echo # Health:%health%/%maxhealth%
Echo # Damage:%randamagemin%-%randamagemax%
Echo # Defense:%defense%
Echo # XP:%xp%/%maxxp%
Echo # Gold:%gold%
Echo ######################################
Echo #                                    #
Echo #         Decisions              #
Echo ######################################
Echo #                                    #
Echo # 1).Attack                          #
Echo # 2).Use Potion                      #
Echo # 3).Flee                            #
Echo #                                    #
Echo ######################################
IF "%1" == "-debug" (
set fightchoice= 1
goto fightscreenoveride
)
set /p fightchoice= Choose your decision. 
:fightscreenoveride
IF %fightchoice% == 1 goto fightattack
IF %fightchoice% == 2 goto fightpotion
IF %fightchoice% == 3 goto flee
goto fighterror1

The "Scripting" of the fight

This is the main part that is continuously crashing.

:fightdefend
IF "%enemyhealth%" LEQ "0" goto :fightend
cls
set /a abilchecker=%enemyabilities%
:fightenemyability
set /a abilchecker= %abilchecker% - 1
IF %abilchecker% GEQ 0 (
IF "%enemyability1type%"=="1" (
IF "%enemyability1costbool%"=="1" (
IF %enemyenergy% GEQ %enemyability1cost% (
set /a "enemyenergy="%enemyenergy% - %enemyability1cost%"
set /a "enemyability1hitchnc= %RANDOM% * (100 - 1 + 1) / 32768 + 1"
set /a enemyability1hitchanc=%enemyability1hitchnc%
set /a enemyability1hitchance=%enemyability1hitchanc%
IF "%enemyability1choosechance% LEQ "%enemyabilty1hitchance%" 
set /a "enemyability1hitchnc= %RANDOM% * (100 - 1 + 1) / 32768 + 1"
set /a enemyabiltiy1hchance=%enemyability1hitchnc%
IF "%enemyability1chance%" LEQ "%enemyability1hchance%" (
set /a "enemyability1damge= %RANDOM% * (%enemyability1dmgmax% - %enemyability1dmgmin% + 1) / 32768 + %enemyability1dmgmin%"
set /a enemyability1damage=%enemyabiltiy1damge%
set /a "enemyability1truedamge= %enemyability1damge% - (%defense% / 2)"
set /a enemyability1truedamage=%enemyability1truedamge%
IF "%enemyability1truedamage%" LEQ "0" (
set enemyability1truedamage=0
Echo %curenemy% used %enemyability1name% and hit you for %enemyability1truedamage%!
pause >nul
goto :fightscreen
)
set /a "health=%health% - %enemyability1truedamage%"
Echo %curenemy% used %enemyability1name% and hit you for %enemyability1truedamage%!
pause >nuls
goto :fightscreen
) ELSE (
Echo %curenemy% used %enemyability1name%... But %curenemy% missed!
pause >nul
goto fightscreen
)
 )
  goto fightenemyability
  )
 goto :fightenemyability
  ) ELSE (
set /a "enemyability1hitchnc= %RANDOM% * (100 - 1 + 1) / 32768 + 1"
set /a enemyability1hitchance=%enemyability1hitchnc%
IF "%enemyability1choosechance%" LEQ "%enemyabilty1hitchance%" (
set /a "enemyability1hitchnc= %RANDOM% * (100 - 1 + 1) / 32768 + 1"
set /a enemyabiltiy1hchance=%enemyability1hitchnc%
IF "%enemyability1chance%" LEQ "%enemyability1hchance%" (
set /a "enemyability1dmg= %RANDOM% * (%enemyability1dmgmax% - %enemyability1dmgmin% + 1) / 32768 + %enemyability1dmgmin%"
set /a enemyability1damage=%enemyability1dmg%
set /a "enemyability1truedmg= %enemyability1damage% - (%defense% / 2)"
set /a enemyability1truedamage=%enemyability1truedmg%
IF "%enemyability1truedamage%" LEQ "0" (
set enemyability1truedamage=0
Echo %curenemy% used %enemyability1name% and hit you for %enemyability1truedamage%!
pause >nul
goto :fightscreen
)
set /a "health=%health% - %enemyability1truedamage%"
Echo %curenemy% used %enemyability1name% and hit you for %enemyability1truedamage%!
pause >nul
goto :fightscreen
) ELSE (
Echo %curenemy% used %enemyability1name%... But %curenemy% missed!
pause >nul
goto fightscreen
  )
   )
    )
     )
      )
:fightdefendattack
set /a "enemyrandomdamage= %RANDOM% * (%enemyrandamagemax% - %enemyrandamagemin% + 1) / 32768 + %enemyrandamagemin% "
set /a "hitran=%RANDOM% * (1000 - 1 + 1) / 32768 + 1"
if %hitran% LSS %eneaccuracy% goto enemymiss
goto enemyhit

Setting Enemies Abilities

This is where the abilities for the enemy are set. This sends you from :bearstart1 to this then to :bearstart2

:statfixesenemyability
goto :ability%enemycurabilityID%
:ability001
::Claw
set enemyability%enemycurabilityslot%name=%enemycurabilityname%
set /a enemyability%enemycurabilityslot%type=1
set /a enemyability%enemycurabilityslot%costbool=1
set enemyability%enemycurabilityslot%choosechance=%enemycurabilitychance%
set enemyability%enemycurabilityslot%chance=60
set enemyability%enemycurabilityslot%cost=10
set enemyability%enemycurabilityslot%dmgmin=10
set enemyability%enemycurabilityslot%dmgmax=50
set /a enemyability%enemycurabilityslot%effectbool=0
set /a enemyability%enemycurabilityslot%effect=None
set enemyability%enemycurabilityslot%efsfectchance=0
set enemyability%enemycurabilityslot%effectmin=0
set enemyability%enemycurabilityslot%effectmax=0
set enemyability%enemycurabilityslot%effectlastmin=0
set enemyability%enemycurabilityslot%effectlastmax=0
set enemyability%enemycurabilityslot%activated=1
goto :%statfixloc%

So when it first was crashing it was giving this error:

A "/" was unexpected at this time.

So I used a bat debugger I got from searching stackoverflow.

here is the link to it. If you don't want to check it out pretty much it loads your bat file and uses all the code and gotos and checks for errors. However it does use pauses which forces it to stop. I fixed this by adding this to my fightscreen.

IF "%1" == "-debug" (
set fightchoice= 1
goto fightscreenoveride
)

and loaded it using

start logfile.bat tatatat0-batchz-rpg.bat -debug

I found out using that

set /a abilchecker= 1 - 1 

which in the code is

set /a abilchecker= %abilchecker% - 1

Note: I did have abilchecker set to %enemiesabilities% a couple of lines earlier This code been continuously crashing it or at least is the first thing to crash. So I tried to fix it by putting quotation marks around all the set /a parts except that like

set /a "enemyability1hitchnc= %RANDOM% * (100 - 1 + 1) / 32768 + 1"

That didn't really fix it though. All it did was change

A "/" was unexpected at this time.

to

The syntax of the command is incorrect.

That error does not make very much sense as the syntax of set /a abilchecker is fine. This is where I have been stuck for a while and I have no idea how to fix it.


Conclusion

That is all I really have to my problem.
Some help and/or suggestions would be really nice! I've been trying to fix this for days now. :/
If there is any part of what I said you don't understand or if you need more information ask.


Alright I did end up changing my parentheses and quoting in the set /a's in my code to:

(Just a 'portion' of it)

set /a abilchecker=%abilchecker% - 1
IF %abilchecker% GEQ 0 (
IF "%enemyability1type%"=="1" (
IF "%enemyability1costbool%"=="1" (
IF %enemyenergy% GEQ %enemyability1cost% (
set /a enemyenergy=%enemyenergy% - %enemyability1cost%
set /a enemyability1hitchnc=%RANDOM% * (100 - 1 + 1^) / 32768 + 1
set /a enemyability1hitchanc=%enemyability1hitchnc%
set /a enemyability1hitchance=%enemyability1hitchanc%
IF %enemyability1choosechance% LEQ %enemyabilty1hitchance%
set /a enemyability1hitchnc=%RANDOM% * (100 - 1 + 1^) / 32768 + 1
set /a enemyabiltiy1hchance=%enemyability1hitchnc%
IF %enemyability1chance% LEQ %enemyability1hchance% (
set /a enemyability1damge=%RANDOM% * (%enemyability1dmgmax% - %enemyability1dmgmin% + 1^) / 32768 + %enemyability1dmgmin%
set /a enemyability1damage=%enemyabiltiy1damge%
set /a enemyability1truedamge=%enemyability1damge% - (%defense% / 2^)
set /a enemyability1truedamage=%enemyability1truedamge%
IF %enemyability1truedamage% LEQ 0 (
set enemyability1truedamage=0
Echo %curenemy% used %enemyability1name% and hit you for %enemyability1truedamage%!
pause >nul
goto :fightscreen

I've looked it over several times after previous comments and still seem to be getting the same error.

The syntax of the command is incorrect.
set /a abilchecker=%abilchecker% - 1

Community
  • 1
  • 1
tatatat0
  • 437
  • 1
  • 5
  • 11
  • You've got an extra quotation mark in `set /a "enemyenergy="%enemyenergy% - %enemyability1cost%"` – rojo Dec 05 '14 at 14:00
  • Save yourself some future headaches, and remove all spaces surrounding the assignments in `set`. `set %somevar%= someval`, should be `set %somevar%=someval`. The space becomes part of %somevar% otherwise, which means `a` does not match ` a`. – Ken White Dec 05 '14 at 14:07
  • @closers: Twaddle! The problem can be easily reproduced, it's not a typo and the resolution would certainly be of assistance to people encountering a similar problem. I'd agree the amount of data is excessive but when you haven't a clue where the problem is, and it **is** extremely subtle, what do you do? – Magoo Dec 06 '14 at 03:19
  • Many of the problems might quickly go away if you'd use a different (less cryptic) programming language and an Integrated Development Environment, debugger, editor with error detection etc. That is what most other programmers do even for their pet projects...(unless this game is for [1K-batch-script-coding-contest](http://js1k.com/2014-dragons/demos) of course ;) – xmojmr Dec 10 '14 at 20:25

1 Answers1

1
IF "%enemyability1costbool%"=="1" (
IF %enemyenergy% GEQ %enemyability1cost% (
set /a "enemyenergy="%enemyenergy% - %enemyability1cost%"
set /a "enemyability1hitchnc= %RANDOM% * (100 - 1 + 1) / 32768 + 1"

The close-parenthesis on the last line here closes the if %enemyenergy% ... ( block.

You need to escape that close-parenthesis with ^ Thus:

set /a "enemyability1hitchnc= %RANDOM% * (100 - 1 + 1^) / 32768 + 1"

Naturally, there are heaps of such situations in the mountain of code you've shown us.

Next, try set /a for any numeric assignment, and toss out the quoting in numeric assignments. Use set "var=string" to assign strings as the quoting ensures trailing spaces are not included in the value assigned.

And try set /a var=(%random% %% rangemax) + 1 to set a value 1..rangemax

you could even write a subroutine :

:randrange
set /a %1=1+(%random% %% %2)
goto :eof

then any time you want a random number 1..rangemax, simply use

call :randrange nameofvariabletoset rangemax

which will save all that repetitive typing - but I see from your variable-naming scheme you like typing. Hmm - takes all types, I suppose....


Newest response:

The line

    IF %enemyability1choosechance% LEQ %enemyabilty1hitchance%

has a syntax error (missing ()

You do realise that at that time, you've already opened 4 blocks, and that is the fifth? You go on to open 7 blocks in total - and close none. Unless you've censored-off the pile of close-parentheses, that is.

While you're in the area, you've got

set enemyability1truedamage=0

which being a numeric assignment is better off with set /a...

And please learn to indent. It makes block statement much more readable.

Magoo
  • 77,302
  • 8
  • 62
  • 84