Jump to content

(geck script) Can someone tell me why this if statement is ignored


hexef

Recommended Posts

Ok, so I've been trying for like 2 hours to get this following statement to work, which checks whether the current player health is smaller than 85% of players base health:

 

if (Player.GetAV Health) <= (85/100 * Player.GetBaseAV Health)
; some code
endif
I just cannot for the life of me figure out why the block inside the if doesn't execute... it is so frustrating that I had to post this here in order to get some help.
Using NVSE function Print, it shows me that Player.GetAV Health is smaller than 85/100 * Player.GetBaseAV Health, if I have for example 35 HP and 135 base health, but still that if statement doesn't execute, what the hell?
Please, does anybody have any idea what is wrong with the code?
Link to comment
Share on other sites

Try putting the entire conditional inside of parenthesis: "((Player.GetAV Health) <= (85/100 * Player.GetBaseAV Health))".

 

And possibly (I'm not sure) assign "Player.GetAV Health" and "Player.GetBaseAV Health" to ref variables, and use the ref variable in the condition instead. I believe "Player.GetAV Health", etc., is a function and those may not work inside a conditional statement. Regardless, using ref variables will be more efficient that two calls to functions inside a conditional.

 

(I'm not a GECK coder.)

 

-Dubious-

Edited by dubiousintent
Link to comment
Share on other sites

Try putting the entire conditional inside of parenthesis: "((Player.GetAV Health) <= (85/100 * Player.GetBaseAV Health))".

 

And possibly (I'm not sure) assign "Player.GetAV Health" to a ref variable, and use the ref variable in the condition instead. I believe "Player.GetAV Health" is a function and those may not work inside a conditional statement.

 

-Dubious-

 

Just tried this, same problem... My guess is that the 85/100 part is rounded to 0 somehow but I don't know how to cast that to float.

Link to comment
Share on other sites

I think you need to assign both of those "Player.Get" function calls to ref variables. And probably the calculation as well to a local variable. Simplify the conditional. See "this" where it talks about "explicit reference syntax".

 

-Dubious-

Thanks for you suggestion, I did it like this using local variables so as not to store those refs and the float into the savefile to prevent save bloating:

Begin MenuMode 1

ref rPlayerBaseHP = Player.GetBaseAV Health
ref rPlayerCurHP = Player.GetAV Health
float healthPct = 85/100 * rPlayerBaseHP 


if rPlayerCurHP <= healthPct 
     ;code
endif


End
Works as intended.
EDIT: One thing that is not clear to me yet is that refs should store a formID right? Like an address to that object, not its value...but it the script above it somehow stores its value... What would be the difference between "ref rPlayerBaseHP = Player.GetBaseAV Health" and "float rPlayerBaseHP = Player.GetBaseAV Health" ? Both variables should have the same value, right? I cannot test it right now. It's kinda confusing (new to Geck scripting as well).
Edited by xqdcss
Link to comment
Share on other sites

While I am familiar with this sort of coding, I am not familiar with GECK syntax. So there is a good chance this is not exactly correct. But as I understand it just from reading that referenced page, first you have to realize that "Form ID" is not the same as "Ref ID". According to the GECK Glossary:

 

A BaseID (or Base ID) is a FormID assigned automatically to an object by the GECK when a new object is created in the Object window. The Form IDs listed in the Object window are Base IDs. A Base ID is only associated with an object template in the editor, never with an instanced object in-game.

 

and

A Reference Editor ID is a name given to a specific instance (Reference) of an object placed in the Render Window by a user. Reference Editor IDs are used in scripts to execute commands that affect only that instance of an object.

 

 

 

So I interpret that as both a "Base ID" and a "Form ID" are references to a "template" object. A "Ref ID" references a specific instance of a "Form ID" (object) within the game world, a particular copy of the "template". So when you are editing a script, "Ref IDs" do not exist because you are not "in-game". The "references" are place-holders in the form of "Form IDs". Thus you need "ref" variables as surrogates for the "Ref ID".

 

Now when you look at the description of "Variables" on the "Scripting for Beginners" page, you see they store different types of values. A "ref" variable is storing what I think of as a "pointer" to a "Form ID", which is a surrogate for the "Ref ID". Sort of "placeholder waiting for the 'Ref ID' instance of 'this Form ID' to appear in the game context". Whereas, "float" variable is getting the "value" (in the form of a decimal point number) of that referenced instance. Not the same value: one is a pointer to where the value resides, and the other will contain the value returned from that pointer.

 

Edit: In the specific instance of "ref rPlayerBaseHP = Player.GetBaseAV Health", the type of variable determines what is returned by the function call "Player.GetBaseAV Health". Because the result is being assigned to a "ref" variable, it returns a reference. When the result is being assigned to a "float" (or integer / long / short) variable, it returns a value. The variable type drives the type of return.

 

And I certainly hope someone who actually knows the GECK will correct me.

 

-Dubious-

Edited by dubiousintent
Link to comment
Share on other sites

Reference variables are meant to hold references or base objects. I was not aware that you could assign floating point values to reference variables, but I would not recommend doing it. Use a float variable as GetAV returns a number and you need the precision of a floating point. And even if we were to go with the assumption that using a ref variable doesn't cause any issues down the line, it is semantically incorrect.

Edited by Ladez
Link to comment
Share on other sites

Reference variables are meant to hold references or base objects. I was not aware that you could assign floating point values to reference variables, but I would not recommend doing it. Use a float variable as GetAV returns a number and you need the precision of a floating point. And even if we were to go with the assumption that using a ref variable doesn't cause any issues down the line, it is semantically incorrect.

 

You are right about that mistake, it worked for me on another version of the script, which I didn't notice that I was using it.

 

So for those who are interested, this is the correct way to take value of a float variable in GECK:

 

float fPlayerBaseHP
let fPlayerBaseHP := Player.GetBaseAV Health 
float fPlayerCurHP
let fPlayerCurHP := Player.GetAV Health
float fHealthPct
let fHealthPct := 85/100 * fPlayerBaseHP 

if fPlayerCurHP <= fHealthPct ; check if current player HP is smaller than 85% of players base HP
    ;some code
endif

Having ref instead of float as variable type wouldn't return the float value of the actor values.

 

Also, thank you dubiousintent for your very informative post.

Edited by xqdcss
Link to comment
Share on other sites

So just using "GetHealthPercentage" wouldn't work ?

 

http://geck.bethsoft.com/index.php?title=GetHealthPercentage

 

~~~~~~~~~~~

 

If Player.GetHealthPercentage <= .85

 

; some code

 

endif

 

Well that's the best way around it I suppose. I didn't know about that function unfortunately. On the other hand, if I've had known about GetHealthPercentage int the first place, I wouldn't have learned so much about GECK scripting to be fair...

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...