This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Strite's profile picture

RPG Dev. Problems! (elseif, arithmetic, function, etc)

Started by Strite, 25 November 2013 - 01:04 PM
Strite #1
Posted 25 November 2013 - 02:04 PM
Hey, ya' all.
First of all, don't mind why this code is for, it's a "beta" for a rpg kinda game that I'm working on, I know there are tons of better ways to this, using tables and stuff, but I don't quite know how to use those, anyways.

Here is the code: pastebin.com/NRqB5Xpy

The error is giving me is: bios:337: [string "battle"]:105: unexpected symbol

And I don't really know why that's happening. I looked up in a bunch of diferent forums, but none of them have a solution for my problem. If any of you could help me, that would be great, and also, this is my first topic, and yes, I read the rules, but if anything is wrong, just tell me.
Any ideas for the code are also very welcome.
Thanks you.
Edited on 30 November 2013 - 10:48 AM
Lyqyd #2
Posted 25 November 2013 - 02:40 PM
You've got a malformed comparison in your elseif statement. Looks like you missed the "mob" variable on the left side there.
Strite #3
Posted 25 November 2013 - 03:14 PM
Ok thanks, it really helped me! Sorry for useless topic.
Strite #4
Posted 25 November 2013 - 03:24 PM
Hey, it's me again.

Sorry for a bothering again, but I got a new problem, and considering that this might help other people's work, I might as well just ask for help, anyways.

Here's the updated code: pastebin.com/JXAWSwcv

The error now is: battle:163: attempt to concatenate nil and string

And sorry, but I have no idea what that is. I looked up in a couple of other topics, but haven't find any that really helped me.

Thanks!
Lyqyd #5
Posted 25 November 2013 - 05:00 PM
Please stick to one topic for all questions about a given piece of code.
Strite #6
Posted 25 November 2013 - 05:02 PM
Oh, sorry, at least now I know.
Any help is more than welcome!
Bomb Bloke #7
Posted 25 November 2013 - 05:05 PM
It's complaining because you're trying to combine nil (the value of "first") with some text.

At a glance, it seems you only define "first" in the FirstCollect() function, but you declare it as local to that function - meaning no other functions get to access it.

I see that the other values you declare there have the same issue. Also note that "read()" always returns strings - you may wish to try "tonumber(read())" for when numerals are needed.
Strite #8
Posted 25 November 2013 - 05:14 PM
Bomb Bloke, is there any way I can make that possible? Make other functions acess other functions information? If not, that's okay, I will figure a solution myself.

Also, I'm not really familiar with this "tonumber(read())", so, I can use it to basicly get an input in form of numerals, insteed of a string? So, something like "local input = tonumber(read())" should work?
Bomb Bloke #9
Posted 25 November 2013 - 05:49 PM
Bomb Bloke, is there any way I can make that possible? Make other functions acess other functions information? If not, that's okay, I will figure a solution myself.
There are a number of ways.

One is to have the function return those values:

local function getStuff()
  local a=read()
  local b=read()
  return a,b
end

local c,d = getStuff()
print( c.." "..d )

Another is to declare the variables as local to the whole script, not just to your function:

local a,b

local function getStuff()
  a=read()
  b=read()
end

getStuff()
print( a.." "..b )

Yet another is to simply not declare the variables as local at all, but this has the side effect of having them remain in RAM when the script ends. Ideally, all variables and functions in your script will be cleared when the script ends.

Also, I'm not really familiar with this "tonumber(read())", so, I can use it to basicly get an input in form of numerals, insteed of a string? So, something like "local input = tonumber(read())" should work?
Yes, that's how it works - the string result of the "read()" function gets passed to the "tonumber()" function, which returns a numerical representation.

Note that if the string can't be converted - say the user typed "cheese" - then "tonumber()" returns nil. Bearing in mind that for the purposes of a conditional test (like for your "if" statements), nil counts as false, you'll typically want to loop until the user co-operates:

local myNumber
repeat
  print("Type a number:")
  myNumber = tonumber(read())
until myNumber
Strite #10
Posted 25 November 2013 - 06:09 PM
Okay, I think I've got it. I'm gonna try some of these in the code right now, thanks a lot!

And the "tonumber(read())", I see, so, basicly, if a string is giving, when you're asking for a numerical value (using the "tonumber(read())" command), the input it's basicly going to return false, insteed of the string itself. I just don't understand a simple thing, what's the basic diference between getting a number (input) using the "read()" command, and the "tonumber(read())", because, for simple things, It's pretty much the same, I'm guessing.

local number = read()
print ("Number: "..number)

Should work, and:

local number = tonumber(read())
print ("Number: "..number)

Should work as well, I think.
Am I wrong?


EDIT: Now I'm also getting the error: battle:302: attempt to perform arithmetic __sub on number and nil, any ideas why?
Here's the updated code: pastebin.com/HTsWZNN6
Edited on 25 November 2013 - 08:30 PM
VaNnOrus #11
Posted 25 November 2013 - 11:51 PM
EDIT: Now I'm also getting the error: battle:302: attempt to perform arithmetic __sub on number and nil, any ideas why?
Here's the updated code: pastebin.com/HTsWZNN6

local BuckleyH = BuckleyH - firstFinalAttack

You are trying to take away some value from non-existent variable
You must declare a variable before operations with it, like that
local a = 2
a = a - 1 -- now a = 1
Edited on 25 November 2013 - 10:51 PM
Bomb Bloke #12
Posted 26 November 2013 - 05:54 AM
Or rather, you DO declare it, but you declare it as local to a different function. That is to say, it's the exact same issue as the one I already told you how to fix.

Anyway, think of a numerical variable as being intended for numerical storage, and strings being intended for storing words (or any given sets of characters). This mostly matters when you come to use these values, as Lua will take their types as ques as to how to treat them.

Let's say you ask someone to type in a number and they type "potato". Say you don't bother to check that a number was handed to you, and go on to try and add one to what you were given. What do you think happens when Lua tries to divide the word "potato"? ;)/>

Lua is actually rather forgiving about the matter, and if you store an actual number as a string, many functions will still "work". You can, for example, store "56" as a string and perform division on it. You cannot, however, store a number as a string and try to pass that to something like rednet.send() for the computer ID (as that will insist on having the ID stored as a number, not as a string).
jay5476 #13
Posted 26 November 2013 - 03:50 PM
Okay, I think I've got it. I'm gonna try some of these in the code right now, thanks a lot!

And the "tonumber(read())", I see, so, basicly, if a string is giving, when you're asking for a numerical value (using the "tonumber(read())" command), the input it's basicly going to return false, insteed of the string itself. I just don't understand a simple thing, what's the basic diference between getting a number (input) using the "read()" command, and the "tonumber(read())", because, for simple things, It's pretty much the same, I'm guessing.

local number = read()
print ("Number: "..number)

Should work, and:

local number = tonumber(read())
print ("Number: "..number)

Should work as well, I think.
Am I wrong?


-snip
The reason you put it as a number is because you can then do maths on it

number = read()
print(number-1)
that will error even if you type a number because its in its string form

number = tonumber(read())
print(number-1)
will not error if you give a valid number but if you don't it returns nil
Bomb Bloke #14
Posted 26 November 2013 - 04:29 PM
that will error even if you type a number because its in its string form
You'd think so, but no.

Still, you'd run into problems with it later down the track with other functions.
Strite #15
Posted 26 November 2013 - 04:42 PM
EDIT: Now I'm also getting the error: battle:302: attempt to perform arithmetic __sub on number and nil, any ideas why?
Here's the updated code: pastebin.com/HTsWZNN6

local BuckleyH = BuckleyH - firstFinalAttack

You are trying to take away some value from non-existent variable
You must declare a variable before operations with it, like that
local a = 2
a = a - 1 -- now a = 1

Hm, I see, I just misspelled "finalFirstAttack" for "firstFinalAttack", ok, but now I that I fixed, it's still giving me the same error! And well, BuckleyH is defined at the very begining, and I made that function return the variable "finalFirstAttack", so it is basicly defined, isn't? From what I understood from Bomb Bloke's explanation, a way to make the script, or another function access other functions information is by adding a "return" plus the name of the variable (information) at the end of the function giving the information, I did that.

That's the new code: pastebin.com/5BeHNasK, it's now that diferent, but, anyways.

And even though I added that return at the end of the function "FirstAttack()", the script still can't understand the line 302, it still gives me the arithmetical error. Oh, and by the way, don't mind the super messy code, I was just trying everything to make this work, and the result was a whole bunch of useless lines that literally don't do nothing , so, don't mind them. I even tried to define BuckleyH again at line 310, but none of that nonsense worked.

EDIT: Sorry Bloke. xD
Edited on 26 November 2013 - 04:03 PM
Bomb Bloke #16
Posted 26 November 2013 - 05:00 PM
Bomber Blake
:|

When you "return" something, you're not so much passing the whole variable back as you're passing the contents of that variable back.

For example, up the top of your script you call "math.random(1,20)". This function returns a number between one and twenty. You're multiplying that value by 350 and storing the result in the "BuckleyS1Dam" variable.

Or perhaps this'll make more sense to you:

local function multiplyByFifty(valuePassedToMe)
  local multipliedByFifty = valuePassedToMe * 50
  return multipliedByFifty
end

local theResult = multiplyByFifty(3)
print(theResult)
Strite #17
Posted 26 November 2013 - 05:56 PM
I think I've got it, I just don't understand that: "multiplyByFifty(3)", what that "(3)" is doing?
Bomb Bloke #18
Posted 26 November 2013 - 06:02 PM
It gets passed to the "multiplyByFifty" function, which stores it in a variable called "valuePassedToMe". That variable is automatically localised to that function, so it (along with the "multipliedByFifty" variable) gets discarded when the function ends.

All that gets returned is the contents of "multipliedByFifty", which gets captured and stored in "theResult" (a new variable).
Strite #19
Posted 26 November 2013 - 07:03 PM
Oh, so it pretty much works like a algebraic function, I see!

Bomb Bloke, you basicly made my day! The code is working! (for now…)

The solution was pretty simple:

First of all, I made this function return "finalFirstAttack".


local function FirstAttack()
print ("Attacker: "..first)
print()
print ("Dice (20): "..d20)
if d10>= 5 then
print ("Dice (10): "..d10)
print ("Critical Hit!")
print ()
local finalFirstAttack = d20p10 * firstATK * crit
print ("Final attack: "..finalFirstAttack)
return finalFirstAttack
else
print ("Dice (10): "..d10)
print ()
local finalFirstAttack = d20p10 * firstATK
print ("Final attack: "..finalFirstAttack)
print ()
return finalFirstAttack
end
end

And at the end, just defined finalFirstAttack as the the result of the FirstAttack function.


local finalFirstAttack = FirstAttack()
local BuckleyH = BuckleyH - finalFirstAttack
print ("Buckley HP: "..BuckleyH)

Thanks Bomb Bloke, and all the others as well, of course.

Oh, and yes, of course, I'll probably continue to use this topic for a couple other difficulties I might have in the future, so, admin, please don't close it. haha'
Strite #20
Posted 28 November 2013 - 02:21 PM
Heyo, I'm back, I'm getting quite a weird error, it's just a visual one, I can run the program and everything will be fine, but for some reason, when the FirstAttack() function is called by the aos() one, the Dice Results (and/or the Critical Hit message) kinda, blinks once or twice.

Here's the updated code: pastebin.com/mDTgNFsW (the FirstAttack() function starts at line 245)

Here's the function's code:


local function FirstAttack()
Head()
print (first.."'s turn!")
print()
sleep(1)
print ("Dice (20): "..d20)
--Critical Hit
for i = 5,9 do
if d10 == i then
print ("Dice (10): "..d10)
print (" ")
sleep(0.5)
print ("Critical Hit!")
print (" ")
sleep(0.3)
local finalFirstAttack = d20p10 * firstATK * crit
print ("Final attack: "..finalFirstAttack)
return finalFirstAttack
--Super Attack
elseif d10 == 10 then
print ("Dice (10): "..d10)
print (" ")
sleep(0.5)
print ("Super attack!")
print (" ")
sleep(0.3)
local finalFirstAttack = d20p10 * firstATK * 5
print ("Mult. 5x!")
print ("Final attack: "..finalFirstAttack)
return finalFirstAttack
elseif d10<=4 then
print ("Dice (10): "..d10)
print (" ")
sleep(0.3)
local finalFirstAttack = d20p10 * firstATK
print ("Final attack: "..finalFirstAttack)
print ()
return finalFirstAttack
end
end
end

If you're going to test this yourself, just put some random information at the player one's application, and just skip the second and third one's pressing Enter repeatedly until it asks you what monster you're figting, type "Buckley", it will ask what you want to do, put "Attack", you'll get the message that blinks.

Thanks!
Bomb Bloke #21
Posted 28 November 2013 - 04:48 PM
At line 405 you call aos(), which calls FirstAttack(). Then at line 407 you call FirstAttack() again.
Strite #22
Posted 28 November 2013 - 05:15 PM
Woah, what a silly mistake, thanks Bomb Bloke!
Edited on 28 November 2013 - 04:31 PM
Strite #23
Posted 28 November 2013 - 05:31 PM
Actually, Bomb Bloke, I just noticed, at line 407, I'm not calling a function, I'm defining a variable, at least I think so.


local finalFirstAttack = FirstAttack()

And even after I take that line away, the same error still occurs.
Edited on 28 November 2013 - 04:31 PM
Bomb Bloke #24
Posted 28 November 2013 - 05:56 PM
You're setting a variable to what your function returns - and in order to return something, the function must be executed. ;)/>

This is why you can use code like this:

while not turtle.forward() do
  turtle.dig()
end

When Lua goes to check if "turtle.forward()" is true or not, it does so by calling it - which makes the turtle attempt to move forward. That function happens to return a value indicating whether the movement was successful or not, hence the code block translates to "try to move forward, dig if you fail, and keep repeating the attempt until it works".
Strite #25
Posted 28 November 2013 - 06:25 PM
Oh, I see… That's not quite I was expecting, I understood it at least. I'm gonna try to fix it, let's see how it goes.
Strite #26
Posted 29 November 2013 - 10:26 PM
Heyo again,

I was wondering, is return the only way to make a function acess another function's information? Because if it is, that's not gonna work for me - I'm gonna have to do a lot of rewriting, and, I don't wanna do that. :l

Thanks.
Lyqyd #27
Posted 29 November 2013 - 10:38 PM
That's the best way to do it, but it's not the only way. You should be designing things so that they can mostly pass information between functions as necessary.
Strite #28
Posted 29 November 2013 - 11:04 PM
I know it's the best way, part of my code is based on that method, but, the problem is, when I define a variable using the returned information, the function is called, I don't want that happening - I want the function to be called separately, and then I'm going to use the variable defined in that function to make math, print and etc.

Basicly, I want to do the following, without needing to call the function two times.


function example()
--whole bunch of code
local a = read()
--whole bunch more
return a
end

example()
local a = example()
print ("Variable: "..a)


Is there a way to do that?
awsmazinggenius #29
Posted 29 November 2013 - 11:13 PM
I would be happy to help, if you indent your code. I'm done doing indentation-duty. Here is the conventional method

hi = 1
hiTwo = 2
--# other code

while true do --# This is a block starting statement, all further code is indented one level (two spaces)
  hiThree = 3
  hellothere = true
  if hellothere == false then --# another block starter (pretty much all if's, for's, while's, repeat's, function definitions, and goto labels are block starters
	print("It's false")
  end --# This is a block ender, so we decrease a level
end --# another block ender

EDIT: Please change your topic title using the full editor on your first post as it no longer makes sense, and people are likley to post an answer to your first issue, as I often do when I see questions that are like "then" expected. I don't look who answered before, I just answer.
Edited on 29 November 2013 - 10:19 PM
Strite #30
Posted 30 November 2013 - 12:37 AM
Ahm, I understand you're trying to help, awsmazinggenius, but you're not really answering my question, not in a way that I can see it, at least. I know the basics about how layers of code work, and how to end them - I'm just asking how to basicly do the code above work, or, if is there a easier method to make functions acess other function's information.

Here's the code: pastebin.com/A0PczYJU

You see the BuckleyHead1() function? I want the BuckleyH variable, to be the returned values given by the FirstAttack() function, but I don't want to call them again, especially because, the FirstAttack() contain the BuckleyHead1(). It's a bit wonky and "complicated" - I hope you undestand the problem.

Thanks ya' all for helping!

EDIT: How do I access the full editor? I really have no idea how.
Edited on 29 November 2013 - 11:57 PM
Bomb Bloke #31
Posted 30 November 2013 - 04:20 AM
You'd be well served by some research into tables at this point, along with perhaps "for"/"while" loops.

I'm not sure I understand what it is you're asking at this point. This post of yours suggests that what I last told you went completely over your head…

example()	    -- This calls the "example()" function, running the code in it. It then discards whatever was returned.
local a = example() -- This calls the "example()" function, running the code in it. It then stores the returned output in "a".

Hence I would simply use "local a = example()" and completely remove the single "example()" line. Why call it twice? There's simply no need.

If it helps, it's also possible to have a function return multiple values. Try running this:

local function getThreeRandomNumbers()
  print("Someone just ran the \"getThreeRandomNumbers()\" function!")
  local aRandomNumber = 4  -- Chosen by fair dice roll. Guaranteed to be random.
  return aRandomNumber, "I'm a random number in disguise! Honest!", math.random(10)
end

local random1,random2,random3 = getThreeRandomNumbers()

print(random1)
print(random2)
print(random3)

When passing tables around between functions things get a bit more interesting (in a way that'd you'd probably like), but I suspect you're not familiar with them so I won't go into details yet.

I don't look who answered before, I just answer.

If you're not going to take the time to read past the first post, what difference does the title make? If answering without heed as to what the current topic of conversation is doesn't strike you as silly, then let me point out to you that answering without heed as to what the current topic of conversation is is silly. ;)/>
Strite #32
Posted 30 November 2013 - 11:25 AM
Bomb Bloke, I really want to start using tables, they just seeing way too complicated for my newbie mind, I don't really see a fair reason to use them, at least for now. And you didn't quite understood my problem. Let's see if I can simplify it.


local monsterHP = 4000
write ("Player's name: ")
local player = read()

function HP()
print ("Monster HP: "..monsterHP())
print ("Monster's ATK: "..monsterATK)
print (player.."'s Turn!")
end

function attack()
HP()
local attack = math.random(1,1000)
print (..player"'s attack!")
local monsterHP = monsterHP - attack
return monsterHP
end

attack()


You see now? I want "monsterHP" to be displayed, but I don't want to call the function again! MonsterHP is going to change a bunch of times, so that's going to require the functions to be called a lot of times, especially because the real code contains three players, not only just one.

Edit: And how do I use the full editor the other guy referenced to? If I can change the name of the topic, I am going to.
Edited on 30 November 2013 - 10:25 AM
awsmazinggenius #33
Posted 30 November 2013 - 11:38 AM
I thought they were complex, but here is a simple rundown:

example = {} --# Use the { +  } characters to define a new table.
example[5] = "hi" --# I am going to number 5 in the table, and making that equal to "hi"
example["hello word"] = example[5] --# I am going to "hello world" in the table, and making that equal to "hi", as I am pointing to example[5]

example2 = {colors.red, colors.blue} --# The Red and Blue colors from the colors API are here, they are in keys 1 and 2 by default.
print(tostring(example2[1]).." "..tostring(example2[2]))

example3 = {["helllllo"]=1, ["hellooooo"]=2} --# Assigning custom keys in the table definition.

for k, v in pairs(example3) do
  print(k.." "..tostring(v)) --# prints all the contents of example3.
end

P.S: To use the full editor, click edit on your post, then click "Use Full Editor".

EDIT: Please indent, like this (I'm doing this again, just this once.):

[CODE]
local monsterHP = 4000
write ("Player's name: ")
local player = read()

function HP()
  print ("Monster HP: "..monsterHP())
  print ("Monster's ATK: "..monsterATK)
  print (player.."'s Turn!")
end

function attack()
  HP()
  local attack = math.random(1,1000)
  print (..player"'s attack!")
  local monsterHP = monsterHP - attack
  return monsterHP
  end
attack()

And could you not print(tostring(monsterHP))?
Edited on 30 November 2013 - 10:41 AM
Strite #34
Posted 30 November 2013 - 11:58 AM
Oh, yeah, Tables are indeed simple, I'm gonna try and use them for now on, thanks. And I also figure the full editor thing out, thanks for that as well.

And, I could print monsterHP, but that would be always 4000, wouldn't? I would like to print the constantly updated monster's HP, so, if it took 300 damage, next time the HP() is called, I want it to show 3700, not 4000. For example:


local monsterHP = 4000
write ("Player's name: ")
local player = read()
function HP()
  print ("Monster HP: "..monsterHP())
  print ("Monster's ATK: "..monsterATK)
  print (player.."'s Turn!")
end
function attack()
  HP()
  local attack = math.random(1,1000)
  print (..player"'s attack!")
  local monsterHP = monsterHP - attack
  return monsterHP
  end
function pressKey()
print ("Press any key to continue")
os.pullEvent("key")
end
function clear()
term.clear()
term.setCursorPos(1,1)
end
repeat
attack()
press()
until monsterHP() <=0 --Being this the constantly updated HP.
print ("Monster is dead.")

I would like something like that, but in a functional way…
Lyqyd #35
Posted 30 November 2013 - 12:13 PM
Here's a really basic example. Note that I just rearranged things into a couple of tables, so you can pass a table reference to the function and have it act upon it as appropriate.


local monster = {
    HP = 4000,
    ATK = 300,
    type = "Monster",
}

local player = {
    HP = 1200,
    ATK = 500,
    name = "",
    type = "Player",
}

write ("Player's name: ")
player.name = read()

function printHealth(obj)
  print (obj.type.." HP: "..obj.HP)
  print (obj.type.."'s ATK: "..obj.ATK)
end

function attack(obj1, obj2)
  printHealth(obj2)
  local attack = math.random(1,100) + obj1.ATK
  print (obj1.type.."'s attack!")
  obj2.HP = obj2.HP - attack
end

function pressKey()
print ("Press any key to continue")
os.pullEvent("key")
end

function clear()
term.clear()
term.setCursorPos(1,1)
end

repeat
    attack(player, monster)
    press()
until monster.HP <=0 --Being this the constantly updated HP.
print ("Monster is dead.")
Strite #36
Posted 30 November 2013 - 12:42 PM
Holy shit, I love that! Now I really see it. I can totally update the code using that, but I have a question, is there a way to change a value there is already in the table, using a function? That's because - I want to implement a skill feature, I added the skill's damage to the table, but I want to create a new boolean in the table, that is "skillNow = false", and that's going to define, inside the function, if the player is going to attack or use the skill.
Is there a way to do that?
Edited on 30 November 2013 - 11:42 AM
Lyqyd #37
Posted 30 November 2013 - 01:06 PM
Note that the attack function is modifying obj2's HP value. You can set values and change existing values in a table, and it will update the actual table. Tables are passed by reference, not value. You could just say obj2.skillWhatever = newvalue and it would work fine. Go try it out!
Strite #38
Posted 30 November 2013 - 01:18 PM
Thanks, I will! Be right back with the results.
Edited on 30 November 2013 - 12:41 PM
Strite #39
Posted 30 November 2013 - 02:05 PM
Real quick question, is there a way to actually add a completely new variable to the table using the code? You gave me that example ("obj2.skillWhatever = newvalue"), would that work even if the table, inicialy didn't have that variable listed in it?
Lyqyd #40
Posted 30 November 2013 - 02:24 PM
Yes, like I said above.
Strite #41
Posted 30 November 2013 - 02:28 PM
Okay, thanks! Back to rewrithing - Be right back.
Strite #42
Posted 30 November 2013 - 02:35 PM
New error, I keep getting this: [string "battle"]:123: attempt to concatenate local 'obj' (a table value), and I have no idea why.
Here's the updated code: pastebin.com/ZzGhD6Fg
Lyqyd #43
Posted 30 November 2013 - 02:43 PM
obj is the whole table, and you're trying to concatenate that with the string " player: " on that line, which won't work. You should figure out what you want to index from the obj table there and use that instead of trying to concatenate the entire table.
Strite #44
Posted 30 November 2013 - 03:08 PM
My objective was to display "First", "Second" and "Third", basicly, I wanted to display the table's names, but I don't know.
Strite #45
Posted 30 November 2013 - 03:33 PM
Fixed it, I just added a "place" variable to the table, and the function displays "obj.place", easy as that.
Strite #46
Posted 30 November 2013 - 10:35 PM
Getting this error now: [string "battle"]:296: unexpected symbol near '.'
Here's the updated code: pastebin.com/vA0mezzJ
Any ideas why that is happening?
Lyqyd #47
Posted 30 November 2013 - 10:39 PM
Don't use local when you're assigning values to table entries.
Strite #48
Posted 30 November 2013 - 10:57 PM
Now, the results of the dice of 10 sides, which are located inside the FirstAttack() function, is repeating itself three or four times, any idea why?
(And, by the way, I'm probably going to post a lot of errors and such, I'm extremely new with tables, so it's likely to erros to happen - I hope that's ok.)
Edited on 30 November 2013 - 10:05 PM
awsmazinggenius #49
Posted 30 November 2013 - 11:42 PM
I usually use table["key"] = "new value" when creating new keys in the table, but that's just my habit. Also, you can now see how user loaded API's work, using the code that Lyqyd showed to you. (I always still use table["key"], because that's my habit.) The OS loads the API into a new table containing the functions and variables, like term.clear()and other functions.

Also, you're welcome. I'm glad you could figure out the tables easily.
Bomb Bloke #50
Posted 01 December 2013 - 04:13 AM
Now, the results of the dice of 10 sides, which are located inside the FirstAttack() function, is repeating itself three or four times, any idea why?
Because it's inside a "for" loop, which you start on line 276. All code inside the loop is executed five times - on the first iteration, "i" is set to 5, on the next it's increased to 6, and so on until it reaches 9.

If you want to know whether d10 is anywhere from 5 to 9, use something like:

if d10 >= 5 and d10 <= 9 then

This translates to "if d10 is more or equal to 5, and d10 is also less or equal to 9, then…".
Strite #51
Posted 01 December 2013 - 09:43 AM
I already tried using "more or equal", and "less or equal" before and it didn't work, I discovered why a couple days ago, just forgot to rewrite it - Thanks Bomb Bloke, for reminding me.

EDIT: Is there a way to do something like, "greater than x but less than y"?
Edited on 01 December 2013 - 08:50 AM
Lyqyd #52
Posted 01 December 2013 - 11:14 AM
if val > x and val < y then
Strite #53
Posted 01 December 2013 - 09:15 PM
Simple question, is there a way to break a loop with a function?
Lyqyd #54
Posted 01 December 2013 - 10:59 PM
http://www.lua.org/pil/4.4.html
Strite #55
Posted 18 December 2013 - 02:36 PM
Heyo, I'm back!
Now I'm getting this error: [string "battle"] :383: attempt to compare number with nil
Here's the code: pastebin.com/nVxKCRj5
Bomb Bloke #56
Posted 18 December 2013 - 04:53 PM
Line 407 is passing a string with the content of "Buckley" to the MainBattle() function. You want it to pass the Buckley object. Remove the quotes.

Alternatively, you could put your "Buckley" and "Angeling" tables inside another table, together:

Spoiler
local mob = {

  Buckley = {
  name = "Buckley",
  HP = 40000,
  ATK = 500,
  skill1Dam = math.random(1,20) * 350,
  skill1Atri = steel,
  skill1Area = false,
  skill1Name = "Silver River",
  skill1Use = false,
  skill2Dam = 3000,
  skill2Atri = steel,
  skill2Area = false,
  skill2Name = "Shining Silver",
  skill2Use = false,
  atri = steel
  },

  Angeling = {
  name = "Angeling",
  HP = 8000,
  ATK = 200,
  skill1Dam = 450,
  skill1Atri = light,
  skill1Area = false,
  skill1Name = LexAeterna,
  skill1Use = false,
  skill2Dam = 600,
  skill2Atri = light,
  skill2Area = true,
  skill2Name = "Kyrie Eleison",
  skill2Use = false,
  skill3Dam = 300,
  skill3Atri = normal,
  skill3Area = false,
  skill3Name = "Tackle",
  skill3Use = false,
  atri = light
  }
}

In this way, you can leave line 407 as it is (for now), then change lines such as 383 to something like:

if mob[obj].HP>0 then

It also allows for easy existence checks, given that for the purposes of conditional statements, variables count as "true" if they exist or "false" if they don't. Say you want to know if a given mob is defined in the table, you can just do:

if mob[obj] then
Strite #57
Posted 18 December 2013 - 11:44 PM
Thanks Bomb Bloke, that was such a noobie mistake, sorry for bothering, I fixed and the code is finaly working again, I still have a lot of work to do though.
I have another question, I was wondering if I could create a table using input from the user inside the program. The example, that obviously will not work, but that gives a bit of the idea should be something like this:


print ("Table's name: ")
local tName = read()
print ("Data 1: ")
local data1 = read()
print ("Data 2: ")
local data2 = read()
--And basicly the table would form with those information.

Possible?
Alice #58
Posted 18 December 2013 - 11:51 PM
let's see..
I think the assert function might help here.
Don't quote me on it :P/>

print ("Table Name: ")
name = read()
assert(name .. " = {}")
print ("Data 1: ")
d1 = read()
assert(name .. "[1] = " .. d1)
I think that's how it works :P/>
Otherwise, look up loadstring on Google.
Strite #59
Posted 19 December 2013 - 12:13 AM
Thanks for trying to help, but, I don't think it's working…
I tried your code, just added a print command, to see if the table was really created, and, the print command doesn't really seems to work:
pastebin.com/ec0Ts51E
Lyqyd #60
Posted 19 December 2013 - 12:49 AM
That's not how you use assert().
Strite #61
Posted 19 December 2013 - 12:56 AM
Hm, sorry then, he was just trying to help anyways. So, it's impossible to do an input based table?
Lyqyd #62
Posted 19 December 2013 - 01:07 AM
You could put them in another table, I suppose:


local inputTables = {}
print("name")
local name = read()
inputTables[name] = {}
print("data key")
local key = read()
print("data value")
local value = read()
inputTables[name][key] = value
Alice #63
Posted 19 December 2013 - 07:41 AM
That's a good idea.

Could you use loadstring() and assert()?
Edited on 19 December 2013 - 06:42 AM
Lyqyd #64
Posted 19 December 2013 - 10:36 AM
Using those wouldn't gain you anything. I'm not sure you understand assert.
Strite #65
Posted 19 December 2013 - 07:25 PM
I'm probably going to implement that later. I have another question. Is there a way to see if a table contain a variable (that is an input in this case)?
Alice #66
Posted 19 December 2013 - 07:29 PM

table = {"Hi" = "string"}
if table["Hi"] == "string") then
print(table["Hi"], "string")
end
Hi and String can be whatever you want, but Hi has to be a string.
Strite #67
Posted 19 December 2013 - 07:55 PM
I don't really want to compare specific parts of the table, I want to do something like:


table = {
  data1 = "1",
  data2 = "2",
}
d1 = read()
-- and then check if d1 exists in the table "table"
-- so, if d1 is equal to data1 or data2 return true

I know this is example is very dull, but is it possible?
Edited on 19 December 2013 - 06:55 PM
Alice #68
Posted 19 December 2013 - 08:12 PM
Okay.

local test = false
--Testing to see if the value is a value for one of the variables in the table
for i=1, #table do
if table[i] == d1 then
test = true
end
end
--OR
--testing to see if value is one of the variables in the table
for i = 1, #table do
if table[d1]~=nil then
test = true
end
end
--This checks it
if test == true then
--todo
end
Edited on 19 December 2013 - 07:13 PM