do_if Equality Check Fails

The place to discuss scripting and game modifications for X4: Foundations.

Moderators: Moderators for English X Forum, Scripting / Modding Moderators

Post Reply
user1679
Posts: 794
Joined: Fri, 20. Jul 18, 23:20

do_if Equality Check Fails

Post by user1679 » Sun, 28. Feb 21, 13:00

I'm not sure why this equality check only works on the first pass. Code snipped below:

Code: Select all

        <cue name="Init">
            <conditions>
                <check_any>
                    <event_game_loaded/>
                    <event_cue_signalled cue="md.Setup.GameStart"/>
                    <event_player_created/>
                </check_any>
            </conditions>
            <delay exact="5s"/>
            <actions>

                <set_value name="$thisStation" exact="null" />
                <set_value name="$cachedStation" exact="null" />

            </actions>
            <cues>

                <cue name="PLAYER_DOCKED" instantiate="true">
                    <conditions>
                        <event_object_docked object="player.entity" />
                    </conditions>
                    <actions>

                        <debug_to_file name="'docking_test.log'" text="'-- cue start: [%s] --'.[this.name]" />

                        <!-- event_object_docked -->
                        <set_value name="$thisStation" exact="event.param" />
                        <debug_to_file  name="'lt.log'" text="'Player docked at [%s]'.[$thisStation.name]" />

                        <do_if value="not $thisStation.name == $cachedStation">
                            <set_value name="$cachedStation" exact="$thisStation" />
                            <debug_to_file name="'lt.log'" text="'cachedStation =  [%s]'.[$cachedStation.]" />
                        </do_if>

                        <do_else>
                            <debug_to_file name="'lt.log'" text="'already cached station:  [%s]'.[$cachedStation.]" />
                        </do_if>
                        
                    </actions>
                </cue>
            </cues>
To test, I start a new game using Young Gun. Since I'm docked, I undock and immediately dock again. When I check my log file, I see this:

Player docked at Argon Equipment Factory
cachedStation = Argon Equipment Factory


Next, I undock and fly to a different station but then this check completely fails: <do_if value="not $thisStation.name == $cachedStation">
and the cached station isn't changed. All I get in the log is the notice that I docked at the station, there is no message that the new station name was cached:

Player docked at Medical Supply Factory I

My variable scope should be fine since the script stays instantiated until the game ends. Also, sometimes the do_else never executes even when the do_if is properly skipped because I dock at the same station I just undocked from.

Any advice?
Last edited by user1679 on Wed, 3. Mar 21, 04:26, edited 3 times in total.

User avatar
euclid
Moderator (Script&Mod)
Moderator (Script&Mod)
Posts: 13296
Joined: Sun, 15. Feb 04, 20:12
x4

Re: do_if Equality Check Fails

Post by euclid » Sun, 28. Feb 21, 17:24

Repeat it (start new game etc.), undock but then fly and dock at a different station. Bet it works ;-)

Cheers Euclid
"In any special doctrine of nature there can be only as much proper science as there is mathematics therein.”
- Immanuel Kant (1724-1804), Metaphysical Foundations of the Science of Nature, 4:470, 1786

user1679
Posts: 794
Joined: Fri, 20. Jul 18, 23:20

Re: do_if Equality Check Fails

Post by user1679 » Mon, 1. Mar 21, 02:57

euclid wrote:
Sun, 28. Feb 21, 17:24
Repeat it (start new game etc.), undock but then fly and dock at a different station. Bet it works ;-)

Cheers Euclid
Thanks for the reply,

What you suggest works because with Young Gun you and your ship are already spawned in a station so the docked event is not triggered. This is why I undock and dock to force the event to trigger. If I undock and fly to a different station, both $theStation and $cachedStation are empty until I dock at the new station and $theStation gets captured by the event.

But in reality this is what is happening:

1. If $theStation.name = "Argon Wharf" and $cachedStation = "null"

do_if value="not $theStation.name == $cachedStation correctly returns TRUE and executes the code block because they are not equal

2. if $theStation.name = "Argon Medical Supply Facility I" and $cachedStation = "Argon Wharf"

do_if value="not $theStation.name == $cachedStation incorrectly returns FALSE and skips the code block when it should be TRUE because they are not equal


I can't find much documentation on scripting syntax, is there some sort of grouping or special handling of spaces in these checks? In other languages I've programmed in, sometimes you have to use a combination of () or ' ' or other escapes to parse string values properly.

SirNukes
Posts: 546
Joined: Sat, 31. Mar 07, 23:44
x4

Re: do_if Equality Check Fails

Post by SirNukes » Mon, 1. Mar 21, 03:24

The operator order can be found here (should be the same between XR and X4):
https://www.egosoft.com:8444/confluence ... dencerules

Notably, in X4 "not" is high precedence, before "==". But in a language like Python "not" is lower than "==", which can throw off your intuition.

So I am thinking the game is doing this, assuming "false" and "null" are encoded as 0:

not $theStation.name == $cachedStation
not "Argon Wharf" == null
false == null
0 == 0
result: true

not $theStation.name == $cachedStation
not "Argon Medical Supply Facility I" == "Argon Wharf"
false == "Argon Wharf"
0 == "Argon Wharf"
result: false

user1679
Posts: 794
Joined: Fri, 20. Jul 18, 23:20

Re: do_if Equality Check Fails

Post by user1679 » Mon, 1. Mar 21, 03:38

SirNukes wrote:
Mon, 1. Mar 21, 03:24
The operator order can be found here (should be the same between XR and X4):
https://www.egosoft.com:8444/confluence ... dencerules

Notably, in X4 "not" is high precedence, before "==". But in a language like Python "not" is lower than "==", which can throw off your intuition.

So I am thinking the game is doing this, assuming "false" and "null" are encoded as 0:

not $theStation.name == $cachedStation
not "Argon Wharf" == null
false == null
0 == 0
result: true

not $theStation.name == $cachedStation
not "Argon Medical Supply Facility I" == "Argon Wharf"
false == "Argon Wharf"
0 == "Argon Wharf"
result: false
Thaks for the link.

After my reply to euclid, I went back to my script and grouped the equation with parenthesis and it worked. I should have remembered order of precedence from my days as a VB6 / C++ developer but I was hung up on the modern day pitfalls of "spaces in strings" because I had recently been doing some batch scripting in Windows.

<do_if value="not ($theStation.name == $cachedStation)"

So my test output is now correct

At game start - undock / dock

--- cue [Arrived_to_theStation] started ---
Player arrived at: [ARG Argon Equipment Dock]
Known name: [ARG Argon Equipment Dock]
Cached station: [null]
New station cached: [ARG Argon Equipment Dock]

Undock / dock at same station as above (notice the correctly omitted "new station cached")

--- cue [Arrived_to_theStation] started ---
Player arrived at: [ARG Argon Equipment Dock]
Known name: [ARG Argon Equipment Dock]
Cached station: [ARG Argon Equipment Dock]

Fly to new station

--- cue [Arrived_to_theStation] started ---
Player arrived at: [ARG Hull Part Factory II]
Known name: [ARG Hull Part Factory II]
Cached station: [ARG Argon Equipment Dock]
New station cached: [ARG Hull Part Factory II]


PS: Yes, I know batch scripting isn't modern day but it seems like it brings new headaches :lol:

DeadAirRT
Posts: 1022
Joined: Fri, 25. Jan 19, 03:26
x4

Re: do_if Equality Check Fails

Post by DeadAirRT » Tue, 2. Mar 21, 16:51

Just curious, why are you comparing station.name to a station object? Now that you have the order of operations fixed, I'm pretty sure that will fire every single time.

user1679
Posts: 794
Joined: Fri, 20. Jul 18, 23:20

Re: do_if Equality Check Fails

Post by user1679 » Wed, 3. Mar 21, 04:10

DeadAirRT wrote:
Tue, 2. Mar 21, 16:51
Just curious, why are you comparing station.name to a station object? Now that you have the order of operations fixed, I'm pretty sure that will fire every single time.
Thanks for the question.

The original code was a typo that I corrected in my release code before SirNukes replied to me, I just didn't go back and edit my original post. What happened was I used Notepad++ to find/replace $Station.name with $theStation and I forgot the .name part in the operation. I saw it after I pasted it into the forums.

I'm actually using this now so the name to name comparison is correct.:

Code: Select all

                        <do_if value="not ($theStation.name == $cachedStation)">

                            <!--Save the station name in case player docks here again without docking somewhere else -->
                            <set_value name="$cachedStation" exact="$theStation.name" />



Post Reply

Return to “X4: Foundations - Scripts and Modding”