zorrobyte 30 Posted November 24, 2014 (edited) I'd like to use a switch (or any other performance friendly way) to write a function that returns true if A and/or B is true, false if A and B is false. zbe_cacheEvent = { switch (true) do { case (call zbe_nearPlayer): {exitWith { true}; }; case (!((_leader findNearestEnemy _leader) isequalto objNull)): {exitWith { true}; }; default {exitWith false}; }; }; This returns Error missing ; Edited November 24, 2014 by zorrobyte Share this post Link to post Share on other sites
jshock 513 Posted November 24, 2014 If your only comparing two things, a switch is overkill: _testVar = true; if (!A && !B) then { _testVar = false; }; if (A || B) exitWith {_testVar;}; _testVar; Share this post Link to post Share on other sites
zorrobyte 30 Posted November 24, 2014 A function that tests two conditions and returns true of either A and/or B is true otherwise false. Share this post Link to post Share on other sites
Heeeere's johnny! 51 Posted November 24, 2014 How about this? if(!A && {!B}) then { //A and B are false } else { //A and/or B is true } EDIT: Oops, ninja'd. Share this post Link to post Share on other sites
zorrobyte 30 Posted November 24, 2014 How about this? if(!A && {!B}) then { //A and B are false } else { //A and/or B is true } Lazy eval witchcraft! I feel like a noob but what is B is true and A is false? Wouldn't the function still return false? Expected function return: A true B false = true A false B true = true A true B true = true A false B false = false Share this post Link to post Share on other sites
Heeeere's johnny! 51 Posted November 24, 2014 (edited) What if B is true and A is false? Wouldn't the function still return false? Yes. B only gets evaluated if !A is true. So if A is false, then !A is true, so then B will be evaluated. Let's make it a bit more straight forward: If A is true, this whole statement is false, no matter what B is. If A is false and B is true, the statement is still false. If A is false and B is false, the statement is true. Edited November 24, 2014 by Heeeere's Johnny! Share this post Link to post Share on other sites
zorrobyte 30 Posted November 24, 2014 (edited) Yes. B only gets evaluated if !A is true. So if A is false' date=' then [i']!A[/i] is true, so then B will be evaluated. Ah, I need B to be evaluated regardless of A and return true if B is true while A is false. Wait, this is a mindgame - need to think 0_o ---------- Post added at 08:55 PM ---------- Previous post was at 08:48 PM ---------- If A is true, this whole statement is false, no matter what B is.If A is false and B is true, the statement is still false. If A is false and B is false, the statement is true. Sounds like a plan. Edited November 24, 2014 by zorrobyte Share this post Link to post Share on other sites
Larrow 2822 Posted November 24, 2014 zbe_catchEvent = { ( call zbe_nearPlayer ) || !isNull (_leader findNearestEnemy _leader) }; Share this post Link to post Share on other sites
Zriel 12 Posted November 24, 2014 zbe_catchEvent = { ( call zbe_nearPlayer ) || !isNull (_leader findNearestEnemy _leader) }; Yep. https://community.bistudio.com/wiki/or Share this post Link to post Share on other sites
Larrow 2822 Posted November 24, 2014 Then to make it even faster as Jonny was showing, find which ever is the slowest performing of the two, either zbe_nearPlayer or findNearest (as we dont know what your nearPlayer involves) and put it last in the statement and wrap it in braces (lazy eval). So it does not have to do it if the first is true. Hope that makes sense. Share this post Link to post Share on other sites
zorrobyte 30 Posted November 24, 2014 zbe_catchEvent = { ( call zbe_nearPlayer ) || !isNull (_leader findNearestEnemy _leader) }; I'm using a FSM and FSM hates || in condition blocks but defining it this way and putting (call zbe_nearplayer) in the condition block works! I would of done a || immediately to solve the issue in the first place but I didn't think about using a call to work with FSM. Thank you all! Share this post Link to post Share on other sites
KevsNoTrev 44 Posted November 24, 2014 (edited) Zorrobyte, I don't think you need your exitwith in the switch, it naturally exits when the case is true. zbe_cacheEvent = { switch (true) do { case (call zbe_nearPlayer): {true}; case (!((_leader findNearestEnemy _leader) isequalto objNull)): {true}; default {false}; }; }; I have tested with 'placeholder' values for the case conditions, but there must be something not right with those checks. I did a simple param 'one' and 'two' and in the editor for each of the case conditions, then changed these values to true/false, the switch works as intended. In theory this works and will be quick. Hmm, what is _leader? it is not defined in this script, is that the issue? EDIT: Phew, that's a lot of replies, I gotta stop opening so many tabs when reading the forums. Take or leave it, may not actually help now.... Edited November 24, 2014 by KevsnoTrev WoW lots of replies Share this post Link to post Share on other sites
zorrobyte 30 Posted November 24, 2014 (edited) This is slow as snot when multiplied by 144 times and checked every second: ({((_position distance _x) < _distance) } forEach ([] call BIS_fnc_listPlayers)) I need to return true if a player is near in a more performance friendly way. Any ideas? BIS_fnc_codePerformance = 0.0231934ms x 144 = 3.33 Edited November 24, 2014 by zorrobyte Share this post Link to post Share on other sites
Heeeere's johnny! 51 Posted November 24, 2014 (edited) [color=#FF8040][color=#191970][b]if[/b][/color][color=#8B3E2F][b]([/b][/color] [color=#8B3E2F][b]{[/b][/color] [color=#191970][b]if[/b][/color][color=#8B3E2F][b]([/b][/color][color=#191970][b]isPlayer[/b][/color] [color=#000000]_x[/color] [color=#8B3E2F][b]&[/b][/color][color=#8B3E2F][b]&[/b][/color] [color=#8B3E2F][b]{[/b][/color][color=#000000]_x[/color] [color=#191970][b]distance[/b][/color] [color=#000000]player[/color] [color=#8B3E2F][b]<[/b][/color] [color=#1874CD]_distance[/color][color=#8B3E2F][b]}[/b][/color][color=#8B3E2F][b])[/b][/color] [color=#191970][b]exitWith[/b][/color] [color=#8B3E2F][b]{[/b][/color] [color=#000000]true[/color] [color=#8B3E2F][b]}[/b][/color][color=#8B3E2F][b];[/b][/color] [color=#000000]false[/color] [color=#8B3E2F][b]}[/b][/color] [color=#191970][b]count[/b][/color] [color=#191970][b]playableUnits[/b][/color] [color=#191970][b]isEqualTo[/b][/color] [color=#FF0000]1[/color] [color=#8B3E2F][b])[/b][/color] [color=#191970][b]then[/b][/color] [color=#8B3E2F][b]{[/b][/color] [color=#006400][i]//do your business here...[/i][/color] [color=#8B3E2F][b]}[/b][/color][color=#8B3E2F][b];[/b][/color][/color] Kudos to Killzone_Kid for his SQF to BBCode Converter. I think this is about the fastest you can get in that particular problem. Explanation: The count iterates through all playable units on the map. Playable units are either players or AI which has been created with the status "playable". That's why in the if statement inside the count loop, you have to check if isPlayer. Now, if a player is closer than _distance, the count loop exits with true. Now you need to know that a count either expects nothing or a boolean value in the loop. If the return value of the loop is nil or true, the unit will be counted. If it is false, it won't. So if - in this example - a unit is either no player or is further away than _distance, the exitWith block will not be executed, so the loop will continue. And as the return value is false in that case, the unit won't be counted. But IF the exitWith block is executed because the unit is both a player and closer than _distance, the unit will be counted and simultaniously, the count loop will be aborded. So that way, this construction either returns 0 or 1 which is why you can compare using isEqualTo 1. I hope that wasn't too cryptic... Edited November 24, 2014 by Heeeere's Johnny! Added code explanation Share this post Link to post Share on other sites
zorrobyte 30 Posted November 24, 2014 ['({(position player) distance _position < _distance} count playableUnits> 0)'] call BIS_fnc_codePerformance;0.00400391ms Yippie! Share this post Link to post Share on other sites
Heeeere's johnny! 51 Posted November 24, 2014 (edited) But keep in mind that "playableUnits" also returns AI, not only players! And "getPosATL" is faster than "position" or "getPos". Edited November 24, 2014 by Heeeere's Johnny! Share this post Link to post Share on other sites
zorrobyte 30 Posted November 24, 2014 LOVE you guys! This works @ 144 groups at 58/60 CPS/FPS with one second delay: zbe_cacheEvent = {_position = (getPosASL _leader); ({_x distance _position < _distance} count (switchableUnits + playableUnits) > 0) || !isNull (_leader findNearestEnemy _leader) }; Share this post Link to post Share on other sites
Heeeere's johnny! 51 Posted November 25, 2014 Just out of curiosity, are you sure you want to use "getPosASL" (get position above sea level) there? I don't know if you're using this on boats and ships only, but if you use that for land vehicles or units, the distance check could be falsified. And you should defenitely not use that position together with "setPos" or "setPosATL" as the unit would fall to death. Share this post Link to post Share on other sites
zorrobyte 30 Posted November 25, 2014 Just out of curiosity' date=' are you sure you want to use "[i']getPosASL[/i]" (get position above sea level) there? I don't know if you're using this on boats and ships only, but if you use that for land vehicles or units, the distance check could be falsified. And you should defenitely not use that position together with "setPos" or "setPosATL" as the unit would fall to death. You are exactly right! My users reported in my thread that there is some funk using ASL. I was blindly following the Code Optimization Guide to squeeze any available peformance out of the loop. Share this post Link to post Share on other sites