• Which the release of FS2020 we see an explosition of activity on the forun and of course we are very happy to see this. But having all questions about FS2020 in one forum becomes a bit messy. So therefore we would like to ask you all to use the following guidelines when posting your questions:

    • Tag FS2020 specific questions with the MSFS2020 tag.
    • Questions about making 3D assets can be posted in the 3D asset design forum. Either post them in the subforum of the modelling tool you use or in the general forum if they are general.
    • Questions about aircraft design can be posted in the Aircraft design forum
    • Questions about airport design can be posted in the FS2020 airport design forum. Once airport development tools have been updated for FS2020 you can post tool speciifc questions in the subforums of those tools as well of course.
    • Questions about terrain design can be posted in the FS2020 terrain design forum.
    • Questions about SimConnect can be posted in the SimConnect forum.

    Any other question that is not specific to an aspect of development or tool can be posted in the General chat forum.

    By following these guidelines we make sure that the forums remain easy to read for everybody and also that the right people can find your post to answer it.

AND/OR XML syntax question

Messages
52
Country
scotland
I hope one of you folks who are skilled at XML coding can help fill a gap in my knowledge. I'm trying to create an XML gauge that will read a few conditions and turn on a smoke effect (representing ground dust). All the AND conditions work fine but I am struggling with the OR conditions and I'm sure in my ignorance I'm approaching it wrong.

In essence, I want the dust effect NOT to be triggered on any of the seven specific surface types. The way I currently have it, the effect is "on" no matter what the surface type. I'd be really grateful if someone could help me with the proper structure for the OR code?

Code:
<Element>
    <Select>
     <Value>
(A:SURFACE TYPE,enum) 21 !=;
(A:SURFACE TYPE,enum) 12 !=; ||
(A:SURFACE TYPE,enum) 7 !=; ||
(A:SURFACE TYPE,enum) 6 !=; ||
(A:SURFACE TYPE,enum) 5 !=; ||
(A:SURFACE TYPE,enum) 3 !=; ||
(A:SURFACE TYPE,enum) 1 !=; ||
(A:TURB ENG1 N1,percent) 20 &gt; &amp;&amp; 
(A:GENERAL ENG1 THROTTLE LEVER POSITION,percent) 49 &gt; &amp;&amp;
(A:SIM ON GROUND,bool) 1; &amp;&amp;
(A:GROUND VELOCITY,knots) 50 &lt; &amp;&amp;
(A:AMBIENT PRECIP STATE,mask) 4 &lt; &amp;&amp;
if{ 3 (&gt;K:SMOKE_ON) } els{ 3 (&gt;K:SMOKE_OFF) }
     </Value>
    </Select>
   </Element>
 
Try removing the improper syntax. You have semi-colons in inappropriate locations...

(A:SURFACE TYPE,enum) 21 !=;

The semi-colon will cause the statement to be ignored, and stop the evaluation process completely. I prefer to use "or" instead of "||" and "and" instead of "&amp;&amp" myself, both for clarity and also it's just quicker to type! :D

Code:
   <Element>
    <Select>
     <Value>
		(A:SURFACE TYPE,enum) 21 !=
		(A:SURFACE TYPE,enum) 12 != or
		(A:SURFACE TYPE,enum) 7 != or
		(A:SURFACE TYPE,enum) 6 != or
		(A:SURFACE TYPE,enum) 5 != or
		(A:SURFACE TYPE,enum) 3 != or
		(A:SURFACE TYPE,enum) 1 != or
		(A:TURB ENG1 N1,percent) 20 &gt; and 
		(A:GENERAL ENG1 THROTTLE LEVER POSITION,percent) 49 &gt; and
		(A:SIM ON GROUND,bool) 1; and
		(A:GROUND VELOCITY,knots) 50 &lt; and
		(A:AMBIENT PRECIP STATE,mask) 4 &lt; and
		if{ 3 (&gt;K:SMOKE_ON) } els{ 3 (&gt;K:SMOKE_OFF) }
     </Value>
    </Select>
   </Element>
 
Hmm, even with the new syntax it still doesn't seem to achieve the expected result. I either get it actioning with all surfaces or, if I reverse the OR logic, with no surfaces. Is my actual logic right, or should I be bracketing off all those OR statements, or something?

(I mistakenly also said I'm trying to get the effect not to work on the seven named surfaces, when I should have said the opposite, the intention is in fact for it to work on those surfaces...so it's a "==" argument I'm really using rather than a "!=" argument...oops sorry :o. Shouldn't affect the logic though.)

ALSO...this made me notice something else...the sim seems to know full well when an aircraft is rolling on a non-hard surface. The "dirt" parameter in the aircraft.cfg [effects] section gives that away, and that shows around the wheels whenever an aircraft moves off a hard runway/apron onto any type of grass/sand/dirt surface.

Is that state represented somewhere in the sim by a single variable that I should maybe be using instead? Wondering now if I'm trying to use a sledgehammer to crack a nut here?

Anyway, although I've now turned my one query into two, I would still be very grateful for assistance with either!
 
Unfortunately, not everything is exposed to us via token variables.

Before getting to excited about this though, might I suggest actually testing (A:SURFACE TYPE,enum) for every surface type?

I'm not even confident that the returns are all that accurate. It sure wouldn't be the first time! :eek:
 
Wait! I just noticed another stray semi-colon and another error that would kill the results!

(A:SIM ON GROUND,bool) 1; and

The ; is incorrect and the 1 is unnecessary for a boolean "true" result. If you insist on being explicit, then it should be 1 == and not just 1... ;)

Try this instead:

Code:
   <Element>
    <Select>
     <Value>
		(A:SURFACE TYPE,enum) 21 ==		(A:SURFACE TYPE,enum) 12 != or
		(A:SURFACE TYPE,enum) 7 == or
		(A:SURFACE TYPE,enum) 6 == or
		(A:SURFACE TYPE,enum) 5 == or
		(A:SURFACE TYPE,enum) 3 == or
		(A:SURFACE TYPE,enum) 1 == or
		(A:TURB ENG1 N1,percent) 20 &gt; and 
		(A:GENERAL ENG1 THROTTLE LEVER POSITION,percent) 49 &gt; and
		(A:SIM ON GROUND,bool) and
		(A:GROUND VELOCITY,knots) 50 &lt; and
		(A:AMBIENT PRECIP STATE,mask) 4 &lt; and
		if{ 3 (&gt;K:SMOKE_ON) } els{ 3 (&gt;K:SMOKE_OFF) }
     </Value>
    </Select>
   </Element>
 
Last edited:
SUCCESS!

Many thanks again, Bill.

You were very astute in making me check the surface enumerations. Many of them turned out not to be what they looked like visually in the sim. :rolleyes:

I tested them all and built up a clean new list of surface types, and along with your corrections for my terrible syntax I now have a working effect.

My understanding of XML has improved that little bit more because of your explanations. I'm indebted. :)

Here's how the working version ended up:

Code:
// HIGH SPEED PROPWASH OR JETWASH ON DUSTY GROUND
// ----------------------------------------------
<Element>
    <Select>
     <Value>
        (A:SURFACE TYPE,enum) 22 ==
        (A:SURFACE TYPE,enum) 21 == or
        (A:SURFACE TYPE,enum) 14 == or
        (A:SURFACE TYPE,enum) 13 == or
        (A:SURFACE TYPE,enum) 12 == or
        (A:SURFACE TYPE,enum) 11 == or
        (A:SURFACE TYPE,enum) 10 == or
        (A:SURFACE TYPE,enum) 7 == or
        (A:SURFACE TYPE,enum) 6 == or
        (A:SURFACE TYPE,enum) 5 == or
        (A:SURFACE TYPE,enum) 3 == or
        (A:SURFACE TYPE,enum) 1 == or
        (A:TURB ENG1 N1,percent) 20 &gt; and 
        (A:GENERAL ENG1 THROTTLE LEVER POSITION,percent) 49 &gt; and
        (A:SIM ON GROUND,bool) and
        (A:GROUND VELOCITY,knots) 50 &lt; and
        (A:AMBIENT PRECIP STATE,mask) 4 &lt; and
        if{ 3 (&gt;K:SMOKE_ON) } els{ 3 (&gt;K:SMOKE_OFF) }
     </Value>
    </Select>
   </Element>
 
Hi
Whilst not important ...you could use a macro to simplify the surface type :)
Code:
<Gauge Name="eat my dust" Version="0.1">
<Update Frequency="6"/>
<Macro Name="Loop">
1 3 5 6 7 10 11 12 14 9 l0 case (A:SURFACE TYPE,number) ==  if{ 1 sp1 }
</Macro>
<Element>
<Select>
<Value>
 c
 :0 @Loop l0 ++ s0 10 &lt; if{ g0 }
 l1
(A:ENG1 COMBUSTION,number) 0 &gt;
(A:RADIO HEIGHT,meters) 2 &lt;
&amp;&amp; &amp;&amp; if{ (A:SMOKE ENABLE,bool) ! if{ (>K:SMOKE_ON) } } els{ (A:SMOKE ENABLE,bool) if{ (>K:SMOKE_OFF) } } }</Value>
</Select>
</Element>
</Gauge>

Wozza
 
Except of course you need the right numbers. The number in red is the total number of items in the list. Just before the case statement is l0 (lower case L):

1 3 5 6 7 10 11 12 13 14 21 22 12 l0 case

Then you need to modify the loop statement for the total number of items + 1:

:0 @Loop l0 ++ s0 13 &lt; if{ g0 }
 
Thank you for the clarification Bill (and thank you for the idea Wozza).

As ever, my gratitude to you guys for making the difficult easy! :)
 
Now, just to complete the explanation of the l0 and s0...

The loop calculates a value + 1, the stores the result in register 0 (s0).

The @macro loads the value from register 0 (l0).
 
hang on a goldarn minute....

you mean with labels and goto's you can have a LOOP inside a script ???????

As in

:0
.. do something
.. check condition
if{ g0 }

Is equivalent to

repeat
.. do something
until (not condition)

How did I miss that?? Where I've needed loops my gauges have used the FSX native 'iterative' gauge execution cycle and computed one step through the loop on each gauge update cycle...

so we could also have

:0
.. check condition
if{ g1 }
.. do something
g0
:1

equivalent to
while (not condition)
.. do something

Well I never knew that, even though I've been using labels to jump *forwards*.

So it's possible for a FSX XML gauge to hang in an infinite loop, I didn't know that either. I wonder what happens to FSX then.

Thanks,
B21
 
Yep! Check the default GPS script for multiple examples of "loops" and "gotos"...

Example of goto:

Code:
    :1 (@g:popupMenuHeaderHeight) (@g:popupMenuCurrent) ++ (@g:popupMenuLineHeight) 17 * * + (@g:popupMenuScroll) - (@g:popupMenuHeight) &gt;= if{
    (@g:popupMenuScroll) 17 (@g:popupMenuLineHeight) * + (&gt;@g:popupMenuScroll) g1 }

This will continuously "goto" :1 until the if{ condition is FALSE.

Example of loop*:

Code:
            %{loop}
            %((@c:IcaoSearchCursorPosition) l0 ==)%{if}\{blnk}%{end}%((@c:IcaoSearchCurrentIdent) l0 symb d slen 0 == if{ p '  ' })%!s!\{nr}
            %(l0 ++ s0 l1 &lt;=)
            %{next}
This statement sets up a register s0 and then continues to loop until...

Whatever value is on top of the stack when the %(next) statement is reached is evaluated as a boolean to determine if execution of the loop should continue.

* NOTA BENE: The {loop}...{next} may only be used inside of a FormattedString statement, and should be used instead of the "goto" function.
 
Last edited:
Back
Top