Hard Light Productions Forums
Modding, Mission Design, and Coding => The Scripting Workshop => Topic started by: Admiral MS on April 30, 2012, 11:19:35 am
-
While giving my script a way to return information to the user that is actually usable in Fred and not depending on potentially buggy script-eval-num/script-eval-string I stumbled on this problem:
Why does
local var = mn.SEXPVariables['name']
if (cf.fileExists(filename,path_shipsave) and type(var.Value) == "number") then
var.Value = 1
else
var.Value = 0
end
work and
local var = mn.SEXPVariables['name'].Value
if (cf.fileExists(filename,path_shipsave) and type(var) == "number") then
var = 1
else
var = 0
end
not work at all?
I have the feeling there is a simple reason but I don't get it cause I have no real idea how variables/handles are organised in that respect... :banghead:
-
The first example works because you are effectively manipulating a pointer to the sexp variable.
The simple reason why the second example doesn't work is that you are copying the contents of the sexp variable into a lua variable, change the lua variable, and then forget to write the new value back to the sexp variable :P
-
Uh well... :ick:
Never had a proper programming course or something like it where someone told me the basics.
Another question:
Would
local var = mn.SEXPVariables['name']
if(type(var.Value) == "number") then
and
local var = mn.SEXPVariables['name']
if(var.Type == SEXPVAR_TYPE_NUMBER) then
have the same result?
-
This is not behaviour you can rely on. Always use var.Type comparisons instead of doing the type() call. For one, it's faster, and second, it's reliable.
-
Now I'm stuck at getting the syntax of var.Type == ... right. So how do I have to use this?
-
What kind of error are you getting?
-
No error, the condition always returns false no matter what. The variable is defined as number in Fred so it should return true and does so for type(var) == "number".
I tried both if(var.Type == SEXPVAR_TYPE_NUMBER) then
if(var.Type == "SEXPVAR_TYPE_NUMBER") then
as I'm not sure how its right. Seems like both are wrong :confused:
-
You need to use var.Type.enumeration == SEXPVAR_TYPE_NUMBER
-
I'm unable to see how I should know this by looking into scripting.html - and this time when using var.Type.enumeration == SEXPVAR_TYPE_NUMBER I get an error:
Could not find index 'enumeration' in type 'enumeration'
------------------------------------------------------------------
ADE Debug:
------------------------------------------------------------------
Name: (null)
Name of: (null)
Function type: (null)
Defined on: 0
Upvalues: 0
Source: (null)
Short source:
Current line: 0
- Function line: 0
------------------------------------------------------------------
------------------------------------------------------------------
LUA Stack:
------------------------------------------------------------------
1: Userdata [enumeration]
2: String [enumeration]
------------------------------------------------------------------
-
Hrm.
Seems I read the documentation wrong. Sorry.
m|m, nuke, any insight here?
-
Type should return an enumeration handle so doing var == SEXPVAR_TYPE_NUMBER should work as intended.
-
yea, the var.Type field is an enumeration. so you should be able to compare it with the appropriate enumeration. var.Type does not contain a .eneumeration key at all, that is only in reference to tell you what kind of datatype the Type value is. this reply brought to you my insomnia. making nuke see purple unicorns everywhere since 2003.
-
A lot of try and error later I found out that its pretty simple.
local var = mn.SEXPVariables['name']
if (var.Type == SEXPVAR_TYPE_NUMBER) then
This never gets true...
So let's add something:
if (tostring(var.Type) == "SEXPVAR_TYPE_NUMBER") then
This works as intended. Why didn't I try something that simple right at the beginning?
Documentation in scripting.html should be a bit more clear about it - though there are far more serious holes in scripting documentation...
-
That's definitely not how it's supposed to work. A simple == has to take care of the comparison or else it's a bug. I might be mistaken but as enumeration handle lacks a __eq function it will test for actual reference equality when you do enum == enum and it's possible that those two enumerations are not the same object.
-
is an enumeration implemented as userdata or as a number variable?
-
It's a userdata value.
-
i see something fishy
local var = mn.SEXPVariables['name']
if name is a string variable, then you dont need the quotes. using them essentially tries to find an object in the mn.SEXPVariables[] indexer with key 'name'. for example:
local name = "something"
local var = mn.SEXPVariables[name]
also this
type(var.Value)
will only return a string containing the value "number" or "string". the type() function is used to identify the datatype of a variable, not its contents.
also its good practice to call var:isValid() before doing anything with var. the correct way is:
local var = mn.SEXPVariables['name']
if (var:isValid() and cf.fileExists(filename,path_shipsave) and type(var.Value) == "number") then
var.Value = 1
else
var.Value = 0
end
but eliminating the obvious, im starting to think the enumeration system really needs an equality operator to be intuitive. expecting the scripter to convert the enumeration to string kinda goes against the reasoning for having an enumeration object to begin with (like if they were string constants instead).
-
The name is the actual variable name and I want to check whether the Fredder read the readme and created a number variable or not... :D
also its good practice to call var:isValid() before doing anything with var.
I added these conditions pretty early but never posted the complete thing:
if (mn.SEXPVariables['saveexist']:isValid()) then
if (mn.SEXPVariables['filename']:isValid()) then
filename = mn.SEXPVariables['filename'].Value
else
filename = mn.getMissionFilename()
end
local var = mn.SEXPVariables['saveexist']
if (cf.fileExists(filename,path_shipsave) and tostring(var.Type) == "SEXPVAR_TYPE_NUMBER") then
var.Value = 1
else
var.Value = 0
end
end
but eliminating the obvious, im starting to think the enumeration system really needs an equality operator to be intuitive. expecting the scripter to convert the enumeration to string kinda goes against the reasoning for having an enumeration object to begin with (like if they were string constants instead).
Yeah - it would have saved me a lot of work figuring out what I'm doing wrong all the time :yes:
-
Here you go :p
[attachment deleted by a ninja]