function return and a simple if statement

Posted by Gore on Thu 01 Mar 2007 02:46 PM — 21 posts, 78,705 views.

#0
What anyone see what I'm doing incorrectly? This if statement will fire regardless if I'm at max health or not. I've tested the max_hp () max_mp () functions to return 1 or 0 when I'm at max health/mana so I think the issue is with the arguments of the if statement?

if def.vitality == 0 and def.vitality_timer == 1 and max_hp () and max_mp () then
  Send ('vitality')
end

function max_hp ()
  if hp.cur == hp.max then return 1; else return 0; end
end

function max_mp ()
  if mp.cur == mp.max then return 1; else return 0; end
end


Do I need to do if max_hp () == 1 then ?
#1
and also shouldn't I be able to do

if not def.vitality and def.vitality_timer then

if def.vitality and def.vitality_timers only have the values of 0 and 1?
Amended on Thu 01 Mar 2007 03:13 PM by Gore
USA #2
0 is not false in Lua. If you want to return false or true, you should return false or true, not zero or one.
Australia Forum Administrator #3
David is quite right, the Lua manual warns you about that. Also your functions could be written more simply:


function max_hp ()
  return hp.cur >= hp.max
end


You want to return a boolean, so simply do a test and return the result, in one operation.
Australia Forum Administrator #4
Quote:

if not def.vitality and def.vitality_timer then


Sure that will work, providing you store true or false into those fields, not 0 or 1.

Get into the habit of using the boolean values true and false, if that is what you intend. Trying to use numbers is a C way of doing things.
USA #5
You can also remove the extra functions there. Having a function for the simple comparison of hp or mp just adds an extra layer of obscurement in there.

if def.vitality and def.vitality_timer and ( hp.cur >= hp.max ) and ( mp.cur >= mp.max ) then
  Send ('vitality')
end

Is just a bit easier to read. That is assuming that you change def.vitality and def.vitality_timer to booleans instead of integers.
Amended on Thu 01 Mar 2007 09:38 PM by Shaun Biggs
#6
wow, thanks for all the advice I will definately change them to true and false!
#7
(lua newb incoming)

For some reason I'm having some issues with using if statements in the if variable then form.

I have no clue why, can anyone help me?

1: function pronequeue ()
2:   if auto.queue and auto.stand and not aff.sleep then
3:     if aff.prone then Send ("stand") end
4:   end
5: end


line 3 fires whether aff.prone is true, or aff.prone is false? How come?
#8
Compile error
Immediate execution
[string "Timer: "]:1: ')' expected near '<eof>'

Also what might that mean?
USA #9
What is the exact content of aff.prone?

As for the compile error, that means that you left out a closing parenthesis somewhere. Chances are you just need to add it to the end but I'd look more carefully at your code and see if you made another mistake somewhere.
#10
aff= { }
aff=
  {
  prone=true,
  sleep=false,
  }

function sit (n,o,wc)
  auto.stand = false
  Send ("sit")
  ColourNote(color.fg, color.bg, "[ auto.stand: off [stand] to resume ]")
end

function stand (n,o,wc)
  auto.stand = true
  pronequeue ()
  ColourNote(color.fg, color.bg, "[ auto.stand: on ]")
end

function afflict.prone (n,o,wc)
  aff.prone = true
  pronequeue()
end

function cure.prone (n,o,wc)
  aff.prone = false
end

function pronequeue ()
  if auto.queue and auto.stand and not aff.sleep then
    if aff.prone == true then Send ("stand") end
  end
end
Australia Forum Administrator #11
Quote:

if aff.prone == true then Send ("stand") end


This line is OK, although personally I would write it as:


if aff.prone then 
  Send ("stand") 
end -- if prone


How is all this structured? Are you sure aff.prone is really false? Are you sure the "stand" comes from this function? You could add debugging like this:


print ("aff.prone type =", type (aff.prone)) -- make sure boolean
print ("aff.prone =",aff.prone) -- show value
if aff.prone then 
  Send ("stand") 
end -- if prone


If you re-execute the code that does this every time:


aff=
  {
  prone=true,
  sleep=false,
  }


Then naturally aff.prone will always be true. I am hoping this is in a script file. Also if you reload the script file during testing, that will reset it to true.

Quote:

Compile error
Immediate execution
[string "Timer: "]:1: ')' expected near '<eof>'


You need to show your code if you want help on that one.
#12
Ah, thanks I changed aff.prone to initialize as false.

And thanks for the debug, I tried it and it seems that somehow aff.prone is a number :/

You have recovered equilibrium.
aff.prone type = number
aff.prone = 0
1374(81)h, 1477(93)m, 1580(100)e, 10p elrx-
You stand straight up.
1374(81)h, 1477(93)m, 1580(100)e, 10p elrx-


I have no clue where it would get the idea that it was a number.

Ahhh, I feel silly. When I updated all of my variables to boolean, I missed one important thing, in my prompt function I have this:

if string.find (defs, "p") ~= nil then aff.prone = 1 else aff.prone = 0 end
if string.find (defs, "x") ~= nil then bal.bal = 1 else bal.bal = 0 end
if string.find (defs, "e") ~= nil then bal.eq = 1 else bal.eq = 0 end
if string.find (defs, "l") ~= nil then bal.la = 1 else bal.la = 0 end
if string.find (defs, "r") ~= nil then bal.ra = 1 else bal.ra = 0 end


I'm assuming all will be fine after I fix that.

Amended on Sun 04 Mar 2007 01:30 AM by Gore
#13
1374(81)h, 1477(93)m, 1580(100)e, 10p elrx-
You sit yourself down.
aff.prone type = boolean
aff.prone = true
1374(81)h, 1477(93)m, 1580(100)e, 10p elrxp-
You stand up and stretch your arms out wide.
1374(81)h, 1477(93)m, 1580(100)e, 10p elrx-


Looks like everything is in check, sorry about that, but thank you for your help.

Just to confirm

if not variable then

will execute if the variable is false

if variable then

will execute if the variable is true, will either of those execute if the value of variable is ANY other value? Like .5 or "hi" etc? Or will if variable then consider variable true because it's not false or nil?
USA #14
variable is true whenever variable is not false, and not nil. not variable is true whenever variable is false, i.e. not variable is true when variable is false or nil.
Australia Forum Administrator #15
Quote:

if string.find (defs, "p") ~= nil then aff.prone = 1 else aff.prone = 0 end


Apart from the problem with 0 and 1, you can rewrite that more neatly:


aff.prone = string.find (defs, "p") ~= nil

#16
I'm assuming that it sets the variable to true or false, but how exactly does it work?
USA #17
The first thing that happens is figuring out the value of the following:

string.find (defs, "p") ~= nil

For simplicity's sake, let's call the result of string.find "result".

If result is equal to nil, then result == nil is true, so result ~= nil is false. Therefore, the whole expression is false, so we put false into aff.prone.

However if result is not nil, then result == nil is false so result ~= nil is true. So the expression is true, and aff.prone becomes true.


In general, you have:
variable = expression

So, you first figure out the value of expression, and you put it into variable.

Personally I would have written:

aff.prone = (string.find (defs, "p") ~= nil)

To me, adding in the parentheses makes the assignment clearer.
#18
I thought that was what was happening, but I didn't want to assume.

That's a very neat shortcut, thanks a lot -g-
I wonder what other shortcuts are nice to use. Lua is amazing!
USA #19
Actually it's a fairly common trick across languages. Almost all languages assign an expression to a value (in some, the assignment itself is an expression!). Then, any kind of expression is fair game.

Syntactically, the number "4" alone is an expression, and so is, say, "4+2". But, you can also have relational operators: things that compare two values and return true if the values are in that relation. You could have, say in C++:

bool b = 1 < 2;

This would be always true.

Once you accept this, it's just one small step to allow for function calls as parts of that expression. And then you can have things like what Nick showed you, or arbitrarily complicated expressions the value of which will be assigned to a variable.

Consider this, in C(++):

int i;
int j;

i = (j = (5>3 ? 24 : 5));


This is somewhat contrived, but what this means is this:

If 5>3, assign 24 to j; otherwise assign 5.
Assign to i the value of j's assignment. (In other words, assign j to i.)

One common thing to see is something like this:

char * p;
if ( (p = get_the_pointer()) != NULL ) {
// do something interesting with p
}


In this case, we first get a value for p. Then, we check p's value against NULL; if it's not null, we do whatever's inside the if block, with a value already assigned to p. It is shorter than, but basically the same as, the following:


if ( get_the_pointer() != NULL ) {
  char * p = get_the_pointer();
  // do something interesting with p
}


(It's not the same thing when the function get_the_pointer has side effects.)
#20
Sweet, thanks a bunch :>