kazopert Posted December 6, 2016 Share Posted December 6, 2016 Hey everyone, I'm having an issue with a script not saving correctly. The script is as follows SCN AQquest1END begin gamemode if AQtestNPCREF.getdead 1if GetObjectiveDisplayed AQquest1 10 setstage AQquest1 20 endif end In this script, I'm trying to get it so that when I kill a specific NPC and the quest has reached an objective index of 10, the quest goes to stage 20 and it completes. What am I doing wrong? Link to comment Share on other sites More sharing options...
Mktavish Posted December 6, 2016 Share Posted December 6, 2016 (edited) Your script should look like this ... SCN AQquest1END begin gamemode if AQtestNPCREF.getdead == 1if GetObjectiveDisplayed AQquest1 10 == 1 setstage AQquest1 20 endifendif end Edited December 6, 2016 by Mktavish Link to comment Share on other sites More sharing options...
kazopert Posted December 6, 2016 Author Share Posted December 6, 2016 Well, I've put those extra lines in and the script still fails to save. Edit: It worked, thanks. Link to comment Share on other sites More sharing options...
PushTheWinButton Posted December 6, 2016 Share Posted December 6, 2016 You don't really need the "== 1"s. The only problem with your original script was that you'd put "GetDead 1" (was that meant to be GetDead == 1?), and that you were missing an endif. Indenting helps with that, though I understand you might have just left that out when typing your post. Anyway, here's what I mean: SCN AQquest1END begin GameMode if (AQtestNPCREF.GetDead) if (GetObjectiveDisplayed AQquest1 10) SetStage AQquest1 20 endif endif end Link to comment Share on other sites More sharing options...
Mktavish Posted December 7, 2016 Share Posted December 7, 2016 (edited) You don't really need the "== 1"s. The only problem with your original script was that you'd put "GetDead 1" (was that meant to be GetDead == 1?), and that you were missing an endif. Indenting helps with that, though I understand you might have just left that out when typing your post. Anyway, here's what I mean: SCN AQquest1END begin GameMode if (AQtestNPCREF.GetDead) if (GetObjectiveDisplayed AQquest1 10) SetStage AQquest1 20 endif endif end Both "GetDead" & "GetObjectiveDisplayed" say they return 1 if the specified subject is true.So why wouldn't you need to ask if it == 1 ? That would be out of the norm for most any "Get" function wouldn't it ?Not saying your wrong ... but why these functions ... and how many others ? Edited December 7, 2016 by Mktavish Link to comment Share on other sites More sharing options...
PushTheWinButton Posted December 7, 2016 Share Posted December 7, 2016 (edited) Cipscis explains this in more detail here but essentially when you use an if or while you're setting up some code which will run when an expression is evaluated to true. True is defined as any non-zero value. Hence, if [deadNPC].GetDead ......is true because it will return 1 - a non-zero value.Likewise, if PlayerREF.GetItemCount Stimpak ......is true if the player has any number of Stimpaks.On the other hand, if [deadNPC].GetDead == 1 ......will also return true. Including the == operator simply adds an extra step, as == will only return true if left and right are equal.Basically, the first example is saying "if (1)" - yes, 1 is true so the code runs; and the second example is saying "if (1 == 1)" - yes, 1 equals 1 so true again.Turning it on its head, if [deadNPC].GetDead == 0...is saying "if (1 == 0)" which is false, so the code won't run.It's a minor thing, and I thought the same as you at first, but its useful to know when optimising code. Using more operators will be more performance intensive, especially in large foreach and while loops. Priority means that conditions don't evaluate left to right either, which can be important if you have an && and the function to the right shouldn't be called if the function to the left evaluates to false. I always omit unnecessary operators for these reasons (and I think it looks nicer). Edited December 7, 2016 by PushTheWinButton Link to comment Share on other sites More sharing options...
Mktavish Posted December 8, 2016 Share Posted December 8, 2016 (edited) /snip Ahh ... thanks for the info. By the way ... can you elaborate a bit on this statement , and maybe give an example ? "Priority means that conditions don't evaluate left to right either, which can be important if you have an && and the function to the right shouldn't be called if the function to the left evaluates to false." Edited December 8, 2016 by Mktavish Link to comment Share on other sites More sharing options...
dubiousintent Posted December 9, 2016 Share Posted December 9, 2016 See the GECK "NVSE Expressions" page for the list of operators and their precedence, along with examples. In short: Lower precedence values such as "0" (for instance the assignment operator ":=") get evaluated first, and higher values such as "14" (the parentheses) get evaluated later, no matter what order they appear within a line of code. More than one operator can have the same precedence, in which case "left to right" order of appearance governs. This is so values can be substituted in place of calculations or function calls to then get compared properly, or have a valid mathematical calculation, etc. Scripts are processed by a "parser" which reads in one line at a time, evaluates that line for operators and functions and values, and then proceeds to make substitutions of values in place of those "abstract elements" (operators, functions, and calculations) in order to produce a meaningful result. The parser then repeats this process for the next line of code, which may be determined by the result of the line it just parsed (i.e. the "then" portion of an "if ... then ... else" statement). This "line by line" real-time interpretation is the primary difference between a "script" and compiled code. -Dubious- Link to comment Share on other sites More sharing options...
luthienanarion Posted December 12, 2016 Share Posted December 12, 2016 (edited) It should be noted that the engine actually evaluates ALL expressions in a condition, regardless if one has already evaluated to FALSE. if someVar == 7 && npcRef.GetDead && GetStage VCG01 == 100 ; do stuff endif In that example, if someVar doesn't equal 7, GetDead is still called on npcRef, GetStage is still called on VCG01, and the return value of GetStage is still compared to 100. It's uglier code to nest IF statements, but it's more efficient because of how asinine the compiler is:if someVar == 7 if npcRef.GetDead if GetStage VCG01 == 100 ; do stuff endif endif endif In this rewrite, execution moves to the line after the last ENDIF after only determining that someVar is not 7, skipping the other evaluations.Note that IF statements can only be nested inside each other 10-deep. If you're comparing a variable or function return against 0, it's more efficient to use ELSE than to make the comparison using the == operator:if someRef.GetDisabled else ; do stuff, because the ref isn't disabled endif The scripting engine does a lot of things differently from actual programming languages and compilers. Edited December 12, 2016 by luthienanarion Link to comment Share on other sites More sharing options...
Mktavish Posted December 13, 2016 Share Posted December 13, 2016 (edited) It should be noted that the engine actually evaluates ALL expressions in a condition, regardless if one has already evaluated to FALSE. if someVar == 7 && npcRef.GetDead && GetStage VCG01 == 100 ; do stuff endif In that example, if someVar doesn't equal 7, GetDead is still called on npcRef, GetStage is still called on VCG01, and the return value of GetStage is still compared to 100. It's uglier code to nest IF statements, but it's more efficient because of how asinine the compiler is: if someVar == 7 if npcRef.GetDead if GetStage VCG01 == 100 ; do stuff endif endif endif In this rewrite, execution moves to the line after the last ENDIF after only determining that someVar is not 7, skipping the other evaluations.Note that IF statements can only be nested inside each other 10-deep. If you're comparing a variable or function return against 0, it's more efficient to use ELSE than to make the comparison using the == operator: if someRef.GetDisabled else ; do stuff, because the ref isn't disabled endif The scripting engine does a lot of things differently from actual programming languages and compilers. So in order to get subsequent "If" evaluations bypassed ... you have to step it / make a new line starting with "if" ?Which then needs an "endif" matching each "if" ? ... And so we are clear ... when using the "&&" for up to 10 comparisons ... All of them function behind one "If"Therefore only one "endif" is needed ? Delineating the difference I suppose ? Edited December 13, 2016 by Mktavish Link to comment Share on other sites More sharing options...
Recommended Posts