If-then-else statements

All about writing scripts for Celestia in Lua and the .cel system
Topic author
Malenfant
Posts: 1412
Joined: 24.08.2005
With us: 19 years 2 months

If-then-else statements

Post #1by Malenfant » 26.10.2005, 18:42

I'm having trouble here.

The code below SHOULD be only going through the indented code if the target is a planet or an asteroid. And it works fine for those bodies. But when I select a star (eg Sol) it prints the type correctly (as expected since that's outside the if statement) and then crashes out because it's trying to get the albedo of a star. What should be happening is that the if statement should spot that it's not a planet or asteroid and skip to the "else" part and not calculate anything, and print that it's not a planet or asteroid.

I can't see any reason why this doesn't work. Why is it still trying to find the albedo of a star here?

And also, can CELX cope with "if... then... else if... then... end" blocks? Or can it only do one if...then...end block at a time?

Code: Select all

KM_PER_LY = 9.46728E12
KM_PER_AU = 149597870.691
camera = celestia:getobserver()
planet = celestia:getselection() -- current selection
camera:center(planet,1)
celestia:select(planet)
type = planet:type()
celestia:flash("target is a "..type)
wait (1)

if type == "planet" or "asteroid" then
   cameraPosition = camera:getposition() -- gets position of observer
   planetPosition = planet:getposition() -- gets position of target
   distance = planetPosition:distanceto(cameraPosition) -- gets distance from  position of target to that of observer
   distAU = distance/KM_PER_AU
   info = planet:getinfo()
   name = planet:name()
   albedo = info.albedo
   radius = planet:radius()
   planmag = -26.74 - (5 * (math.log10(((math.sqrt(albedo))*radius)/149597870.691)))

   celestia:flash( "Target is a " ..type.. " called "..name.. "\n" ..
         "Current distance to target is "..string.format("%.2f",distAU).. " AU\n" ..
         "Target albedo is "..string.format("%.2f",albedo).. "\n" ..
         "Absolute magnitude of target is "..string.format("%.2f",planmag), 5)
else
celestia:flash( "Target is not a planet or asteroid!", 3)
end

maxim
Posts: 1036
Joined: 13.11.2003
With us: 21 years
Location: N?rnberg, Germany

Post #2by maxim » 26.10.2005, 21:03

You should consider writing

Code: Select all

if ((type == "planet") or (type == "asteroid")) then

instead of your construction.

What happens is the following (due to the Lua manual):

Code: Select all

Operator precedence in Lua follows the table below, from lower to higher priority:
or
and
< > <= >= ~= ==
..
+ -
* /
not - (unary)
^

So your line equals to

Code: Select all

if ((type == "planet") or "asteroid") then


The first statement is evaluated like that:

Code: Select all

Equality (==) first compares the type of its operands. If the types are different, then the result
is false. Otherwise, the values of the operands are compared. Numbers and strings are compared
in the usual way. Objects (tables, userdata, threads, and functions) are compared by reference:
Two objects are considered equal only if they are the same object. Every time you create a new
object (a table, userdata, or function), this new object is different from any previously existing
object.

so /"star" == "planet"/ evaluates to /false/. Next the /or/ statement is evaluated:

Code: Select all

The disjunction operator or returns its first argument if this
value is different from nil and false; otherwise, or returns its second argument. Both and and or
use short-cut evaluation, that is, the second operand is evaluated only if necessary.

so /false or "asteroid"/ evaluates to /"asteroid"/. And this means:

Code: Select all

In Lua, both nil and false make a condition false; any other value makes it true.

so /"asteroid"/ evaluates to /true/ and thus your expression will always be true, no matter what type you have.

And also, can CELX cope with "if... then... else if... then... end" blocks? Or can it only do one if...then...end block at a time?

Code: Select all

The control structures if, while, and repeat have the usual meaning and familiar syntax:
stat ! while exp do block end
stat ! repeat block until exp
stat ! if exp then block { elseif exp then block } [ else block ] end


maxim

Topic author
Malenfant
Posts: 1412
Joined: 24.08.2005
With us: 19 years 2 months

Post #3by Malenfant » 26.10.2005, 21:14

Right, OK, thanks - I followed all that. What was weird is that at one point I got it to work fine using the syntax I used but couldn't reproduce that on later editing...

I'll use the brackets and hopefully it should work as intended... Thanks!


Return to “Scripting”