Best way to check for multiple conditions?

Post » Fri Jan 27, 2017 8:26 am

Hey guys, I am remaking a mod I made some time ago, because the code was really messy.



I'm now trying to clean up my condition scripts to make it the most efficient and I am kind of stuck



I can't shake the idea that there is a better, more efficient and faster way to check for multiple conditions.



Here is my script:




Spoiler



Function MeleeCheck()
If Main.TurnOff == False
Int InCom = Main.PriorityListCurrent.Find("In combat")
Int Ooc = Main.PriorityListCurrent.Find("Out of combat")
Int HH = Main.PriorityListCurrent.Find("Health")
Int SS = Main.PriorityListCurrent.Find("Stamina")
Int MM = Main.PriorityListCurrent.Find("Magicka")
Int FF = Main.PriorityListCurrent.Find("Melee")

Bool HHB = Main.healthbool
Bool SSB = Main.Staminabool
Bool MMB = Main.Magickabool


If AEoverride.GetValue() == 0
If HHB == True && SSB == True && MMB == True
If FF < HH && FF < SS && FF < MM
If FF < InCom
Main.EquipSet(6)
ElseIf Main.A == 0
Main.EquipSet(6)
EndIf
EndIf



ElseIf HHB == False && SSB == False && MMB == False
If FF < InCom
Main.EquipSet(6)
ElseIf Main.a == 0
Main.EquipSet(6)
EndIf


ElseIf HHB == True && SSB == True && MMB == False
If FF < HH && FF < SS
If FF < InCom
Main.EquipSet(6)
ElseIf Main.a == 0
Main.EquipSet(6)
EndIf
EndIf

ElseIf HHB == True && SSB == False && MMB == False
If FF < HH
If FF < InCom
Main.EquipSet(6)
ElseIf Main.a == 0
Main.EquipSet(6)
EndIf

ElseIf HHB == False && SSB == True && MMB == False
If FF < SS
If FF < InCom
Main.EquipSet(6)
ElseIf Main.a == 0
Main.EquipSet(6)
EndIf
EndIf

ElseIf MMB == True && SSB == True && HHB == False
If FF < MM && FF < SS
If FF < InCom
Main.EquipSet(6)
ElseIf Main.a == 0
Main.EquipSet(6)
EndIf
EndIf

ElseIf MMB == True && SSB == False && HHB == False
If FF < MM
If FF < InCom
Main.EquipSet(6)
ElseIf Main.a == 0
Main.EquipSet(6)
EndIf
EndIf

ElseIf MMB == False && SSB == True && HHB == False
If FF < SS
If FF < InCom
Main.EquipSet(6)
ElseIf Main.a == 0
Main.EquipSet(6)
EndIf
EndIf

ElseIf HHB == True && MMB == True && SSB == False
If FF < HH && FF < MM
If FF < InCom
Main.EquipSet(6)
ElseIf Main.a == 0
Main.EquipSet(6)
EndIf
EndIf

ElseIf HHB == True && MMB == False && SSB == False
If FF < HH
If FF < InCom
Main.EquipSet(6)
ElseIf Main.a == 0
Main.EquipSet(6)
EndIf
EndIf

ElseIf HHB == False && MMB == True && SSB == False
If FF < MM
If FF < InCom
Main.EquipSet(6)
ElseIf Main.a == 0
Main.EquipSet(6)
EndIf
EndIf
EndIf
EndIf
EndIf
Endfunction




Any insights would be very appreciated, thanks! =D

User avatar
Tania Bunic
 
Posts: 3392
Joined: Sun Jun 18, 2006 9:26 am

Post » Fri Jan 27, 2017 6:31 am

That code looks pretty reasonable to me (except that you have it checking a few of the things more than once).



The biggest issue is that you repeatedly access properties of Main which I assume is another object with a different script. Every time you access another object there's overhead related to object locking so you want to avoid that as much as possible. The solution is to effectively move all of this code into the script on the Main object and simply call it from this one (assuming they really are different).



So your script above becomes just:



Function MeleeCheck()
Main.MeleeCheck()
Endfunction

Then you move the code above into the Main script and take away all of the "Main." parts in front of the variables.



Another issue is that you are filling all variables even when you may not need them.



While this will look very different here's the way I would have written all of that code (in the version moved into the script on the Main object).



Function MeleeCheck()
If TurnOff || AEoverride.GetValue() != 0
return
EndIf

Int MeleePriority = PriorityListCurrent.Find("Melee")

If !healthbool || MeleePriority < PriorityListCurrent.Find("Health")
If !Staminabool || MeleePriority < PriorityListCurrent.Find("Stamina")
If !Magickabool || MeleePriority < PriorityListCurrent.Find("Magicka")
If a == 0 || MeleePriority < PriorityListCurrent.Find("In combat")
EquipSet(6)
EndIf
EndIf
EndIf
EndIf
EndFunction
User avatar
Daniel Holgate
 
Posts: 3538
Joined: Tue May 29, 2007 1:02 am

Post » Thu Jan 26, 2017 11:58 pm

That looks so sixy and makes so much sense at the same time.



And yes, keeping them separate was because of the messy code and I can now merge the 2-4 scripts I have which doesn't need to be split up.



Going forward, is there anyway to shorten something like this, where I have to check the same condition a couple of times and the end result is not always the same? This piece repeats it self like 3-4 times with the conditions switched around while always assuming that HHB, SSB and MMB is true at all times.




Spoiler


if HH < SS
if HH < MM
if InCom < HH && A == 1
EquipSet(1)
else
EquipSet(3)
endif
elseif MM < HH
if InCom < MM && A == 1
EquipSet(1)
else
EquipSet(5)
endif
endif
elseif HH < MM
if HH < SS
if InCom < HH && A == 1
EquipSet(1)
else
EquipSet(3)
endif
endif
.....


User avatar
George PUluse
 
Posts: 3486
Joined: Fri Sep 28, 2007 11:20 pm

Post » Fri Jan 27, 2017 7:06 am

There's not a clean way in the generic case, but the one thing to watch is avoiding unreachable code. In that little snippet the second "if HH < SS" can't actually happen because if the condition were true you won't get to the "elseif HH < MM" section.



Simple variable comparisons are really fast operations so if those are really all script variables or properties it won't matter for performance and it's just a matter of whether it looks long.



It looks like what you're really doing is finding the smallest of the HH, SS, and MM variables then seeing if InCom is even smaller than the smallest of those. It that's true there might be value to separating that logic into two stages like this:



int small = HH ; assume HH is smallest
int equipgroup = 3 ; this gets equipped for HH
if MM < small
small = MM
equipgroup = 5 ; this gets equipped for MM
endif
if SS < small
small = SS
equipgroup = 7 ; ? something when SS is smallest?
endif

if InCom < small && A == 1 ; combat overrides equipgroup
EquipSet(1)
else
EquipSet(equipgroup)
endif
User avatar
Jessica Raven
 
Posts: 3409
Joined: Thu Dec 21, 2006 4:33 am


Return to V - Skyrim