Talk:Statement Reference
Lazy evaluation of expressions?[edit source]
Does Papyrus use it?
e.g.: Given two functions "A" and "B". Both return Bool. Assuming Lazy Evaluation. In the following code example function B would not be executed if function A returned TRUE.
If ( A() || B() )
; some code
EndIf
ref: Lazy Evaluation --Jbezorg (talk) 13:16, 4 November 2012 (EST)
- Yes, Papyrus does do this. Here's the generated assembly for something like the code you've given (with "Return True" inside the conditional statement):
.function Foo .userFlags 0 .docString "" .return Bool .paramTable .endParamTable .localTable .local ::temp0 bool .local ::temp1 bool .endLocalTable .code CALLMETHOD A self ::temp0 ;@line 11 CAST ::temp0 ::temp0 ;@line 11 JUMPT ::temp0 label1 ;@line 11 CALLMETHOD B self ::temp1 ;@line 11 CAST ::temp0 ::temp1 ;@line 11 label1: JUMPF ::temp0 label2 ;@line 11 RETURN True ;@line 12 JUMP label0 label2: label0: .endCode .endFunction
- And yes, those CAST instructions are superfluous. There are a lot of optimisations that *could* be done in the compilation process that aren't done.
- The && operator also uses lazy evaluation:
Function Bar()
Bool Foobar = 0 && 3
EndFunction
.function Bar .userFlags 0 .docString "" .return NONE .paramTable .endParamTable .localTable .local ::temp0 bool .local Foobar Bool .endLocalTable .code CAST ::temp0 0 ;@line 4 JUMPF ::temp0 label0 ;@line 4 CAST ::temp0 3 ;@line 4 label0: ASSIGN Foobar ::temp0 ;@line 4 .endCode .endFunction
- Note that it is entirely possible to write your own functions in Papyrus assembly and assemble them directly, or edit the assembly by hand if you want to optimise it further than the compiler does.
Is it possible to use "and" with "if"? I've created separate neutral guards for Whiterun Hold that are replaced during A Message To Whiterun. ATM, I'm trying to incorporate them into MQ301 in the place of Imperials/Stormcloaks. Basically, this is how the script I want to edit looks ATM:
; create soldiers for the dragon attack scene if Alias_Jarl.GetActorRef().IsInFaction(GovImperial) == 1 ; create Whiterun soldiers Alias_Soldier1.ForceRefTo(Alias_Soldier1StartMarker.GetRef().PlaceAtMe(ImperialSoldier)) Alias_Soldier2.ForceRefTo(Alias_Soldier2StartMarker.GetRef().PlaceAtMe(ImperialSoldier)) Alias_Soldier3.ForceRefTo(Alias_Soldier3StartMarker.GetRef().PlaceAtMe(ImperialSoldier)) else ; create stormcloaks Alias_Soldier1.ForceRefTo(Alias_Soldier1StartMarker.GetRef().PlaceAtMe(SonsSoldier)) Alias_Soldier2.ForceRefTo(Alias_Soldier2StartMarker.GetRef().PlaceAtMe(SonsSoldier)) Alias_Soldier3.ForceRefTo(Alias_Soldier3StartMarker.GetRef().PlaceAtMe(SonsSoldier)) endif
I need neutral guards to be generated instead of guards of the other two factions if A Message to Whiterun isn't complete, but I obviously still need guards from the other two factions to spawn if A Message to Whiterun is complete AND that respective faction controls Whiterun. Is it possible? GetTheJojDone (talk) 2014-08-21T10:43:23 (EDT)
If I understand this correctly, you want and If &&(and) statement in the first line. Yes it is possible.
Example: if Alias_Jarl.GetActorRef().IsInFaction(GovImperial) == 1 && ;code here && code here
Also you can do nested IF statments to have a similar logic(but the first IF has to be true or false depending on how your logic, or the next IFs wont run, and so on). --Terra Nova2 (talk) 2014-08-21T12:35:55 (EDT)
Yeah, that's exactly what I wanted. So, this should work fine, correct?
if Alias_Jarl.GetActorRef().IsInFaction(GovImperial) == 1 && CW03.IsCompleted() ; create Whiterun soldiers Alias_Soldier1.ForceRefTo(Alias_Soldier1StartMarker.GetRef().PlaceAtMe(ImperialSoldier)) Alias_Soldier2.ForceRefTo(Alias_Soldier2StartMarker.GetRef().PlaceAtMe(ImperialSoldier)) Alias_Soldier3.ForceRefTo(Alias_Soldier3StartMarker.GetRef().PlaceAtMe(ImperialSoldier)) elseif Alias_Jarl.GetActorRef().IsInFaction(GovSons) == 1 ; create stormcloaks Alias_Soldier1.ForceRefTo(Alias_Soldier1StartMarker.GetRef().PlaceAtMe(SonsSoldier)) Alias_Soldier2.ForceRefTo(Alias_Soldier2StartMarker.GetRef().PlaceAtMe(SonsSoldier)) Alias_Soldier3.ForceRefTo(Alias_Soldier3StartMarker.GetRef().PlaceAtMe(SonsSoldier)) else ; create whiterun guard Alias_Soldier1.ForceRefTo(Alias_Soldier1StartMarker.GetRef().PlaceAtMe(NeutralSoldier)) Alias_Soldier2.ForceRefTo(Alias_Soldier2StartMarker.GetRef().PlaceAtMe(NeutralSoldier)) Alias_Soldier3.ForceRefTo(Alias_Soldier3StartMarker.GetRef().PlaceAtMe(NeutralSoldier)) endif
It's compiled just fine, at any rate. GetTheJojDone (talk) 2014-08-21T13:17:24 (EDT)
Yeah however statements using AND are a little more strict. If the expression on the left is false, the right expression wont be checked.--Terra Nova2 (talk) 2014-08-21T14:13:38 (EDT)