Jump to content

[LE] If Conditional Operand


Recommended Posts

Hello, i trying to make activator which spawn object on it, everything is working, but only when i do activate, the conditional is must not filled.

this is my code :

 

 

Armor Property WOPshield2 Auto
MiscObject Property WOPSoul Auto
ObjectReference Property WOPshield3 Auto

Event OnActivate(ObjectReference akActionRef)
If (Game.GetPlayer().GetItemCount(WOPshield2) == 0) && (Game.GetPlayer().GetItemCount(WOPSoul) == 0)
Debug.MessageBox("Player has no requirement item on inventory")
Else
Game.GetPlayer().RemoveItem(WOPshield2,1) && Game.GetPlayer().RemoveItem(WOPSoul,1)
WOPshield3.Enable()
Endif
EndEvent

 

when i only have this "Game.GetPlayer().RemoveItem(WOPshield2,1)" the item in my inventory is removed, but "WOPshield3.Enable()" is spawn means the "Else" is working.

but i dont have this "Game.GetPlayer().RemoveItem(WOPSoul,1)". Why the conditional filled and not showing the message box "Debug.MessageBox("Player has no requirement item on inventory")" ?

 

Did my "&&" operand wrong?

 

Thanks

Link to comment
Share on other sites

The && is used for conditions rather than actual function calls.

 

It is used correctly in the IF statement but you cannot use it in the second location.

 

If you want both items to be removed under the same condition, put each RemoveItem function call on a separate line.

 

Your code modified:

 

Armor Property WOPshield2  Auto  
MiscObject Property WOPSoul  Auto  
ObjectReference Property WOPshield3  Auto  

Event OnActivate(ObjectReference akActionRef)
If (Game.GetPlayer().GetItemCount(WOPshield2) == 0) && (Game.GetPlayer().GetItemCount(WOPSoul) == 0)
    Debug.MessageBox("Player has no requirement item on inventory")
Else
   Game.GetPlayer().RemoveItem(WOPshield2,1)
   Game.GetPlayer().RemoveItem(WOPSoul,1)
   WOPshield3.Enable()
Endif
EndEvent

 

 

 

I would make a small adjustment to help speed up the script by not calling out to the game script to get the player information every single time. Get it once, store it in a variable and use that. Thankfully, the OnActivate event already has a parameter containing the one who activated the object. Compare it once to Game.GetPlayer() and as long as it is a match use the akActionRef parameter when you need the player.

 

Your code further adjusted:

 

Armor Property WOPshield2  Auto  
MiscObject Property WOPSoul  Auto  
ObjectReference Property WOPshield3  Auto  

Event OnActivate(ObjectReference akActionRef)
  If akActionRef == Game.GetPlayer()
    If (akActionRef.GetItemCount(WOPshield2) == 0) && (akActionRef.GetItemCount(WOPSoul) == 0)
      Debug.MessageBox("Player has no requirement item on inventory")
    Else
      akActionRef.RemoveItem(WOPshield2,1)
      akActionRef.RemoveItem(WOPSoul,1)
      WOPshield3.Enable()
    EndIf
  Endif
EndEvent

 

 

Link to comment
Share on other sites

Thanks

 

The && is used for conditions rather than actual function calls.

 


 

 

thanks for replying, as you said that "&&" is for conditional, but the condition still run to "else" if I have only one item between WOPshield2 and WOPSoul in my inventory,

when i dont have both item, "debug.messagebox" working,

 

 

this code with AND

    If (akActionRef.GetItemCount(WOPshield2) == 0) && (akActionRef.GetItemCount(WOPSoul) == 0)

has to be coded with OR

    If (akActionRef.GetItemCount(WOPshield2) == 0) || (akActionRef.GetItemCount(WOPSoul) == 0)

to make activation right..

 

I need both item to do "else" not one of them with "or"

Edited by carbondz2010
Link to comment
Share on other sites

You wrote: "I need both item to do 'else' not one of them with 'or'"

 IF ( TRUE)
    ; true condition
 ELSE
   ; false condition
 ENDIF

You don't really understand how multiple if conditions are working !!!

AND

 

IF (TRUE) && (TRUE)                        ; == TRUE
  ; true condition is taken
ELSE
ENDIF

IF (TRUE) && (False)                       ; == False
ELSE
  ; false condition is taken
ENDIF

IF (False) && (TRUE)                       ; == False
ELSE
  ; false condition is taken
ENDIF

IF (False) && (False)                      ; == False
ELSE
  ; false condition is taken
ENDIF

 

 

OR

 

IF (TRUE) || (TRUE)                         ; == TRUE
  ; true condition is taken
ELSE
ENDIF

IF (TRUE) || (False)                        ; == TRUE
  ; true condition is taken
ELSE
ENDIF

IF (False) || (TRUE)                        ; == TRUE
  ; true condition is taken
ELSE
ENDIF

IF (False) || (False)                       ; == False
ELSE
  ; false condition is taken
ENDIF

 

 

Edited by ReDragon2013
Link to comment
Share on other sites

I need both item to do "else" not one of them with "or"

If that's the case, then ReDragon2013 is correct. You could invert it to make it easier to read. e.g.

If (akActionRef.GetItemCount(WOPshield2) > 0) && (akActionRef.GetItemCount(WOPSoul) > 0)  ; need at least 1 of each
    akActionRef.RemoveItem(WOPshield2,1)
    akActionRef.RemoveItem(WOPSoul,1)
    WOPshield3.Enable()
Else
    Debug.MessageBox("Player has no requirement item on inventory")
Endif

When you do the inverse of multiple conditionals, you have to swap AND with OR. e.g.

If (akActionRef.GetItemCount(WOPshield2) <= 0) || (akActionRef.GetItemCount(WOPSoul) <= 0)

; is the opposite of

If (akActionRef.GetItemCount(WOPshield2) > 0) && (akActionRef.GetItemCount(WOPSoul) > 0)
Link to comment
Share on other sites

you may want to get into the habit of storing values that functions return so you dont have to keep calling a function multiple times for the same value needed... depending on your code it can cause a performance imapct... especially if you are doing it in loops. Game.GetPlayer() is not cpu intense but it is better to give your cpu as little work to do as possible... so when you write code that would be cpu intense you are in habit of being economical

 

If (Game.GetPlayer().GetItemCount(WOPshield2) == 0) && (Game.GetPlayer().GetItemCount(WOPSoul) == 0)

 

to

 

Actor p = Game.GetPlayer()

If (p.GetItemCount(WOPshield2) == 0) && (p.GetItemCount(WOPSoul) == 0)

 

like for example would you do this...

 

if a+b < 5 && a + b > 0

 

or...

 

int c = a + b

If c < 5 && c > 0

 

accessing a class with . operator is same as doing addition, you calculate the function address and then have the cpu jump to the function and execute it then it has to return back to where it was

Link to comment
Share on other sites

you may want to get into the habit of storing values that functions return so you dont have to keep calling a function multiple times for the same value needed... depending on your code it can cause a performance imapct... especially if you are doing it in loops. Game.GetPlayer() is not cpu intense but it is better to give your cpu as little work to do as possible... so when you write code that would be cpu intense you are in habit of being economical

 

If (Game.GetPlayer().GetItemCount(WOPshield2) == 0) && (Game.GetPlayer().GetItemCount(WOPSoul) == 0)

 

to

 

Actor p = Game.GetPlayer()

If (p.GetItemCount(WOPshield2) == 0) && (p.GetItemCount(WOPSoul) == 0)

 

like for example would you do this...

 

if a+b < 5 && a + b > 0

 

or...

 

int c = a + b

If c < 5 && c > 0

 

accessing a class with . operator is same as doing addition, you calculate the function address and then have the cpu jump to the function and execute it then it has to return back to where it was

 

Cheyron
Does this also applies for this:
If ( akActionRef == Game.GetPlayer() )
( akActionRef as Actor ).DamageActorValue("Health", ( akActionRef as Actor ).GetActorValue("Health") * 0.50)
Link to comment
Share on other sites

 

you may want to get into the habit of storing values that functions return so you dont have to keep calling a function multiple times for the same value needed... depending on your code it can cause a performance imapct... especially if you are doing it in loops. Game.GetPlayer() is not cpu intense but it is better to give your cpu as little work to do as possible... so when you write code that would be cpu intense you are in habit of being economical

 

If (Game.GetPlayer().GetItemCount(WOPshield2) == 0) && (Game.GetPlayer().GetItemCount(WOPSoul) == 0)

 

to

 

Actor p = Game.GetPlayer()

If (p.GetItemCount(WOPshield2) == 0) && (p.GetItemCount(WOPSoul) == 0)

 

like for example would you do this...

 

if a+b < 5 && a + b > 0

 

or...

 

int c = a + b

If c < 5 && c > 0

 

accessing a class with . operator is same as doing addition, you calculate the function address and then have the cpu jump to the function and execute it then it has to return back to where it was

 

Cheyron
Does this also applies for this:
If ( akActionRef == Game.GetPlayer() )
( akActionRef as Actor ).DamageActorValue("Health", ( akActionRef as Actor ).GetActorValue("Health") * 0.50)

 

 

I think that will just tell the compiler what code to create for the cpu… maybe the compiler creates two variables with same casted value or maybe it knows those values are equal and it only creates one variable for the casted object... im not sure actually, it depends on the compiler... even in your example I would declare a variable to hold this casted value and only do it once. Good code should never have the same thing written twice is what I have heard before... if you write the same code over and over then you should make a function or whatever, etc... I have more experience with languages like c# and the .NET compiler is very smart and you can write bad code and the compiler will fix/optimize it for you when it compiles it... so depends on language and I don't know much about papyrus

 

but I know for most languages the . operator is used to access a class which is the same as addition to a base address and an offset for that property or function... so that means using the dot operator when you don't need to creates more arithmetic for the cpu to compute

 

Game.GetPlayer() is the same as

 

jumpTo gameBase + getPlayerOffset

 

...then cpu has to go wherever that is and it has to keep track of where it is when it jumps so it can return back to the same place... it's just more work... small scripts or what have you... the difference is not comprehendible by humans but it can add up in loops and become noticeable in some cases for example. Video games calculate enough as is so even your tiny scripts you should write optimized and not be sloppy/lazy... not saying that is the case here. Just be in the habit of not telling the cpu to do the same thing twice because skyrim has enough work for the cpu already haha.

Link to comment
Share on other sites

Cheyron


The reason that i'm asking is because i noticed something weird.

To begin with: I do use the "Store Value" to make the script more flexible and faster to execute, especially when it comes to look for the Player Ref.

Example:

If ( akActionRef == Game.GetPlayer() )

SoundFX.Play(akActionRef)

akActionRef.removeItem(MyKey, 1)

... etc


But, in this specific line of codes when i replace the "Game.GetPlayer()" with the "Store Value" i see a noticable delay in the execution as opposed to the execution with "Game.GetPlayer()" which runs as it's suppose to.

Example:

If ( akActionRef == Game.GetPlayer() )

( akActionRef as Actor ).DamageActorValue("Health", ( akActionRef as Actor ).GetActorValue("Health") * 0.50)

( akActionRef as Actor ).DamageActorValue("Magicka", ( akActionRef as Actor ).GetActorValue("Magicka") * 0.50)

( akActionRef as Actor ).DamageActorValue("Stamina", ( akActionRef as Actor ).GetActorValue("Stamina") * 0.50)

... etc




Edit: I forgot to add that this does not compile, if anyone might be wondering.

akActionRef.DamageActorValue("Stamina", akActionRef.GetActorValue("Stamina") * 0.50)

Edited by maxarturo
Link to comment
Share on other sites

  • Recently Browsing   0 members

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