Simple Expression: Difference between revisions

From Bohemia Interactive Community
Jump to navigation Jump to search
m (Text replacement - "y[ _]*\|[ _]*(arma[0-9]+)[ _]*\|[ _]+" to "y|$1|")
m (Text replacement - "{{Feature|Informative|" to "{{Feature|informative|")
 
(7 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{GameCategory|arma1|Editing}}
{{GameCategory|arma2|Editing}}
{{GameCategory|arma3|Editing}}
{{TOC|side}}
{{TOC|side}}
 
{{Feature|informative|Simple expressions are not as flexible as normal scripts, but they are compiled for a very efficient execution.}}
{{Feature|Informative|Simple expressions are not as flexible as normal scripts, but they are compiled for a very efficient execution.}}
 
== Available Operators ==
== Available Operators ==


{|class="wikitable"
{| class="wikitable"
| randomGen a || random value from 0 to ''a'' (randomGen 5)
| randomGen a || random value from 0 to ''a'' (randomGen 5)
|-
|-
| randomGen expr || random value from 0 to expression value (randomGen daylight)
| randomGen expr || random value from 0 to expression value (randomGen daylight)
|-
|-
| ''a'' factor [''x'',''y''] || <tt>factor</tt> is the same as <tt>interpolate</tt> only output range is fixed and capped to 0...1 (or 1...0 if input range is reversed)
| ''a'' factor [''x'',''y''] || {{hl|factor}} is the same as {{hl|interpolate}} only output range is fixed and capped to 0...1 (or 1...0 if input range is reversed)
<br>''a''<=''x'': 0<br>''a''>=''y'': 1<br>''x''<=''a''<=''y'': ratio between ''x'' and ''y''
<br>if ''x''<''y'' then ''a''<''x'': 0, ''a''>''y'': 1<br>if  ''x''>''y'' then ''a''>''x'': 0, ''a''<''y'': 1
 
Note: works fine even for ''x''>''y'' (calculated as 1-''a'' factor [''y'',''x''])
|-
|-
| ''a'' interpolate [''xFrom'',''xTo'',''resFrom'',''resTo''] || Introduced in Arma 2 1.05. interpolate result based on input value.
| ''a'' interpolate [''xFrom'',''xTo'',''resFrom'',''resTo''] || Introduced in Arma 2 1.05. interpolate result based on input value.
Line 36: Line 28:
| abs ''a'' || see [[abs|abs]] (introduced in Arma 3 patch 1.68)
| abs ''a'' || see [[abs|abs]] (introduced in Arma 3 patch 1.68)
|-
|-
| x envelope [a,b,c,d] || trapezoid envelope with output <0;1> (substitution for "(v factor(a,b))*(v factor(d,c))" (Since Arma 3 1.67) <br><br> [[Image:envelope.jpg|left|thumb|envelope graph]]  
| x envelope [a,b,c,d] || trapezoid envelope with output <0;1> (substitution for "(v factor(a,b))*(v factor(d,c))" (Since Arma 3 1.67) <br><br> [[File:envelope.jpg|left|thumb|envelope graph]]
|-
| ''a'' > ''b'' || see [[a_greater_b|a > b]]. Returns 1 and 0 rather than true and false.
|-
| ''a'' < ''b'' || see [[a_less_b|a < b]]. Returns 1 and 0 rather than true and false.
|-
| ''a'' >= ''b'' || see [[a_greater=_b|a >= b]]. Returns 1 and 0 rather than true and false.
|-
| ''a'' <= ''b'' || see [[a_less=_b|a <= b]]. Returns 1 and 0 rather than true and false.
|}
|}


Line 47: Line 47:
* pow(v, a) - power
* pow(v, a) - power


== SQF Equivalent of <tt>factor</tt> ==
== SQF Equivalent of {{hl|factor}} ==


SQF_fnc_factor =  
<sqf>
{
SQF_fnc_factor =  
[[private]] _fnc_interpolateCommon =  
{
{
private _fnc_interpolateCommon =  
[[params]] ["_c", "_cMin", "_cMax", "_vMin", "_vMax"];
{
params ["_c", "_cMin", "_cMax", "_vMin", "_vMax"];
[[if]] (_c < _cMin) [[exitWith]] { _vMin };
[[if]] (_c > _cMax) [[exitWith]] { _vMax };
if (_c < _cMin) exitWith { _vMin };
if (_c > _cMax) exitWith { _vMax };
(_c - _cMin) * (1 / (_cMax - _cMin)) * (_vMax - _vMin) + _vMin
};
(_c - _cMin) * (1 / (_cMax - _cMin)) * (_vMax - _vMin) + _vMin
};
[[params]] ["_c", "_cMin", "_cMax"];
params ["_c", "_cMin", "_cMax"];
[[if]] (_cMin < _cMax) [[then]]
{
if (_cMin < _cMax) then
[_c, _cMin, _cMax, 0, 1] [[call]] _fnc_interpolateCommon
{
}
[_c, _cMin, _cMax, 0, 1] call _fnc_interpolateCommon
[[else]]
}
{
else
[_c, _cMax, _cMin, 1, 0] [[call]] _fnc_interpolateCommon
{
};
[_c, _cMax, _cMin, 1, 0] call _fnc_interpolateCommon
};
};
};
</sqf>


Example: <code>[0.2, 0.1, 0.7] [[call]] SQF_fnc_factor; // 0.166667</code>
Example: <sqf>[0.2, 0.1, 0.7] call SQF_fnc_factor; // 0.166667</sqf>


== SQF Equivalent of <tt>interpolate</tt> ==
== SQF Equivalent of {{hl|interpolate}} ==


SQF_fnc_interpolate =  
<sqf>
{
SQF_fnc_interpolate =  
[[private]] _fnc_interpolateCommon =  
{
{
private _fnc_interpolateCommon =  
[[params]] ["_c", "_cMin", "_cMax", "_vMin", "_vMax"];
{
params ["_c", "_cMin", "_cMax", "_vMin", "_vMax"];
[[if]] (_c < _cMin) [[exitWith]] { _vMin };
[[if]] (_c > _cMax) [[exitWith]] { _vMax };
if (_c < _cMin) exitWith { _vMin };
if (_c > _cMax) exitWith { _vMax };
(_c - _cMin) * (1 / (_cMax - _cMin)) * (_vMax - _vMin) + _vMin
};
(_c - _cMin) * (1 / (_cMax - _cMin)) * (_vMax - _vMin) + _vMin
};
[[params]] ["_c", "_cMin", "_cMax", "_vMin", "_vMax"];
params ["_c", "_cMin", "_cMax", "_vMin", "_vMax"];
[[if]] (_cMin < _cMax) [[then]]
{
if (_cMin < _cMax) then
[_c, _cMin, _cMax, _vMin, _vMax] [[call]] _fnc_interpolateCommon
{
}
[_c, _cMin, _cMax, _vMin, _vMax] call _fnc_interpolateCommon
[[else]]
}
{
else
[_c, _cMax, _cMin, _vMax, _vMin] [[call]] _fnc_interpolateCommon
{
};
[_c, _cMax, _cMin, _vMax, _vMin] call _fnc_interpolateCommon
};
};
};
</sqf>


Example: <code>[0.2, 0.1, 0.7, 0, 100] [[call]] SQF_fnc_interpolate; // 16.6667</code>
Example: <sqf>[0.2, 0.1, 0.7, 0, 100] call SQF_fnc_interpolate; // 16.6667</sqf>


== SQF Equivalent of <tt>envelope</tt> ==


SQF_fnc_envelope =  
== SQF Equivalent of {{hl|envelope}} ==
{
 
[[private]] _fnc_interpolateCommon =  
<sqf>
{
SQF_fnc_envelope =  
[[params]] ["_c", "_cMin", "_cMax", "_vMin", "_vMax"];
{
private _fnc_interpolateCommon =  
[[if]] (_c < _cMin) [[exitWith]] { _vMin };
{
[[if]] (_c > _cMax) [[exitWith]] { _vMax };
params ["_c", "_cMin", "_cMax", "_vMin", "_vMax"];
(_c - _cMin) * (1 / (_cMax - _cMin)) * (_vMax - _vMin) + _vMin
if (_c < _cMin) exitWith { _vMin };
};
if (_c > _cMax) exitWith { _vMax };
[[params]] ["_x", "_a", "_b", "_c", "_d"];
(_c - _cMin) * (1 / (_cMax - _cMin)) * (_vMax - _vMin) + _vMin
};
[[private]] _ret = 0;
params ["_x", "_a", "_b", "_c", "_d"];
[[if]] (_x > _a && _x < _d) [[then]]
 
{
private _ret = 0;
[[private]] _v = [_x, _a, _b, 0, 1] [[call]] _fnc_interpolateCommon;
if (_x > _a && _x < _d) then
[[if]] (_v > 0) [[then]] { _ret = _v * ([_x, _c, _d, 1, 0] [[call]] _fnc_interpolateCommon) };
{
};
private _v = [_x, _a, _b, 0, 1] call _fnc_interpolateCommon;
_ret
if (_v > 0) then { _ret = _v * ([_x, _c, _d, 1, 0] call _fnc_interpolateCommon) };
};
};
_ret
};
</sqf>
 
Example: <sqf>[0.5, 0.1, 0.3, 0.7, 0.9] call SQF_fnc_envelope; // 1</sqf>


Example: <code>[0.5, 0.1, 0.3, 0.7, 0.9] [[call]] SQF_fnc_envelope; // 1</code>


== Simple Expressions -  How do they work? ==
== Simple Expressions -  How do they work? ==


'''The following is an example taken from the [[Eden Editor: Entity Context Menu]].'''
'''The following is an example taken from the [[Eden Editor: Entity Context Menu]].'''


'''Example:'''
'''Example:'''
<code>conditionShow = "hoverObjectCanFly * (1 - hoverObjectFlying)";</code>
<syntaxhighlight lang="cpp">conditionShow = "hoverObjectCanFly * (1 - hoverObjectFlying)";</syntaxhighlight>
Entry will only show if the object you are hovering over can fly and the object isn't flying.
Entry will only show if the object you are hovering over can fly and the object isn't flying.


Line 147: Line 154:


If hoverObjectCanFly is [[true]] (1) and hoverObjectFlying is [[false]] (0) the resulting equation looks like this:
If hoverObjectCanFly is [[true]] (1) and hoverObjectFlying is [[false]] (0) the resulting equation looks like this:
<code>1 * (1-0) = x
1 * (1-0) = x
1 * 1 = x
1 * 1 = x
x = 1
x = 1
</code>
The result will be [[true]] (1), therefore the entry will be shown.
The result will be [[true]] (1), therefore the entry will be shown.
{{GameCategory|arma1|Editing}}
{{GameCategory|arma2|Editing}}
{{GameCategory|arma3|Editing}}

Latest revision as of 00:25, 2 February 2024

Simple expressions are not as flexible as normal scripts, but they are compiled for a very efficient execution.

Available Operators

randomGen a random value from 0 to a (randomGen 5)
randomGen expr random value from 0 to expression value (randomGen daylight)
a factor [x,y] factor is the same as interpolate only output range is fixed and capped to 0...1 (or 1...0 if input range is reversed)


if x<y then a<x: 0, a>y: 1
if x>y then a>x: 0, a<y: 1

a interpolate [xFrom,xTo,resFrom,resTo] Introduced in Arma 2 1.05. interpolate result based on input value.

Equivalent to x factor [xFrom,xTo] * (resTo-resFrom) + resFrom

a min b see min
a max b see max
a - b see a-b
a + b see a+b
a * b see a*b
a / b see a/b (for A3, not sure if others)
abs a see abs (introduced in Arma 3 patch 1.68)
x envelope [a,b,c,d] trapezoid envelope with output <0;1> (substitution for "(v factor(a,b))*(v factor(d,c))" (Since Arma 3 1.67)

envelope graph
a > b see a > b. Returns 1 and 0 rather than true and false.
a < b see a < b. Returns 1 and 0 rather than true and false.
a >= b see a >= b. Returns 1 and 0 rather than true and false.
a <= b see a <= b. Returns 1 and 0 rather than true and false.

Description: a,b can be any simple expression. x,y can be a constant expression only (i.e. expression with a type Number).

Since Arma 3 1.67 the following operators are also available (v ... controller value):

  • abs(v) - absolute value
  • sqr(v) - square value
  • sqrt(v) - square root value
  • pow(v, a) - power

SQF Equivalent of factor

SQF_fnc_factor = { private _fnc_interpolateCommon = { params ["_c", "_cMin", "_cMax", "_vMin", "_vMax"]; if (_c < _cMin) exitWith { _vMin }; if (_c > _cMax) exitWith { _vMax }; (_c - _cMin) * (1 / (_cMax - _cMin)) * (_vMax - _vMin) + _vMin }; params ["_c", "_cMin", "_cMax"]; if (_cMin < _cMax) then { [_c, _cMin, _cMax, 0, 1] call _fnc_interpolateCommon } else { [_c, _cMax, _cMin, 1, 0] call _fnc_interpolateCommon }; };

Example:

[0.2, 0.1, 0.7] call SQF_fnc_factor; // 0.166667

SQF Equivalent of interpolate

SQF_fnc_interpolate = { private _fnc_interpolateCommon = { params ["_c", "_cMin", "_cMax", "_vMin", "_vMax"]; if (_c < _cMin) exitWith { _vMin }; if (_c > _cMax) exitWith { _vMax }; (_c - _cMin) * (1 / (_cMax - _cMin)) * (_vMax - _vMin) + _vMin }; params ["_c", "_cMin", "_cMax", "_vMin", "_vMax"]; if (_cMin < _cMax) then { [_c, _cMin, _cMax, _vMin, _vMax] call _fnc_interpolateCommon } else { [_c, _cMax, _cMin, _vMax, _vMin] call _fnc_interpolateCommon }; };

Example:

[0.2, 0.1, 0.7, 0, 100] call SQF_fnc_interpolate; // 16.6667


SQF Equivalent of envelope

SQF_fnc_envelope = { private _fnc_interpolateCommon = { params ["_c", "_cMin", "_cMax", "_vMin", "_vMax"]; if (_c < _cMin) exitWith { _vMin }; if (_c > _cMax) exitWith { _vMax }; (_c - _cMin) * (1 / (_cMax - _cMin)) * (_vMax - _vMin) + _vMin }; params ["_x", "_a", "_b", "_c", "_d"]; private _ret = 0; if (_x > _a && _x < _d) then { private _v = [_x, _a, _b, 0, 1] call _fnc_interpolateCommon; if (_v > 0) then { _ret = _v * ([_x, _c, _d, 1, 0] call _fnc_interpolateCommon) }; }; _ret };

Example:

[0.5, 0.1, 0.3, 0.7, 0.9] call SQF_fnc_envelope; // 1


Simple Expressions - How do they work?

The following is an example taken from the Eden Editor: Entity Context Menu.

Example:

conditionShow = "hoverObjectCanFly * (1 - hoverObjectFlying)";

Entry will only show if the object you are hovering over can fly and the object isn't flying.

Let's take a closer look at the example.

hoverObjectCanFly and hoverObjectFlying are two boolean values, which can either be true (1) or false (0).

If hoverObjectCanFly is true (1) and hoverObjectFlying is false (0) the resulting equation looks like this:

1 * (1-0) = x
1 * 1 = x
x = 1

The result will be true (1), therefore the entry will be shown.