Jump to content
The simFlight Network Forums

Recommended Posts

Posted

Hi,

updating from FSUIPC 6.0.8 to 6.0.9 causes that my LUA script don't press keys in the GSX menu any more. I use the "function TextMenuOpened(mtype, colour, scroll, delay, id, n, msgs)" and then press the right key with "ipc.keypressplus(49)" for example.

The script itself has not modified and works until several month.

Rolling back to 6.0.8 works like a charm. Any idea's?

Regards,
Peter

Posted
6 hours ago, Capt. PERO said:

updating from FSUIPC 6.0.8 to 6.0.9 causes that my LUA script don't press keys in the GSX menu any more. I use the "function TextMenuOpened(mtype, colour, scroll, delay, id, n, msgs)" and then press the right key with "ipc.keypressplus(49)" for example.

I just done some testing with a simply Lua plug-in which uses ipc.keypressplus and cannot make it fail. I'm pretty sure there cannot be anything different with that function (there's been no change), so I think you must have something else going on.

You need to enable key/button logging in FSUIPC's logging tab, and maybe Lua tracing too, so you can see what is happening. You can post the log here (paste into a message, use the <> facility in the editing menu to enclose it). You need to paste in your Lua plug-in too.

Pete

 

Posted

Hi Pete,

after digging deeper in it the problem has to be redescribed:

  • When using 6.0.9 the GSX Menu opens (which is triggered by LUA and a STRG+SHIFT+W "ipc.keypressplus" operation). So it looks like sending keypress with lua is working in general. But when the GSX menu opens I cannot press an option (0-9) nothing happens. Not with my script and not by keyboard - strange.
  • when I uncomment my script to .lua.off (to avoid loading it) I CAN press the GSX options (0-9) with keyboard again So something with my script and the change from 6.0.8 to 6.0.9.

There is the log:

********* FSUIPC6, Version 6.0.9 (26th June 2020) by Pete & John Dowson *********
Prepar3D.exe version = 5.0.31.35253
Running inside Prepar3D v5
Module base=7FFFA36F0000
Windows 10 Home 64 Bit reported as Build 19041, Release ID: 2004 (OS 10.0)
Reading options from "C:\Users\peter\Documents\Prepar3D v5 Add-ons\FSUIPC6\FSUIPC6.ini"
Checking the Registrations now ...
User Name="Peter Rosendahl"
User Addr="obfuscated@peter.de"
FSUIPC6 Key is provided
WideFS7 Key is provided
        0 System time = 12/07/2020 05:22:12
        0 FLT UNC path = "\\FLUSI\C\Users\peter\Documents\Prepar3D v5 Files\"
        0 Using DialogMode
       16 FS UNC path = "\\FLUSI\P\Prepar3D v5\"
       78 ---------------------- Joystick Device Scan -----------------------
       94 Product= VIER IM POTT SIDESTICK 2.0
       94    Manufacturer= Leo Bodnar
       94    Serial Number= B62906
       94    Vendor=1DD2, Product=2109 (Version 1.38)
      109    GUIDs returned for product: VID_1DD2&PID_2109:
      109       GUID= {30E4FE70-34B8-11E7-8001-444553540000}
      109       Details: Btns=32, POVs=(0, 0, 0, 0), Cal=x00000000, Max=R0,U0,V0,X2363,Y2536,Z4095
      109       GUID= {D620D0A0-34B1-11E7-8001-444553540000}
      109       Details: Btns=32, POVs=(0, 0, 0, 0), Cal=x00000000, Max=R0,U0,V0,X2478,Y3001,Z3172
      109 Product= Joy0-0
      109    Manufacturer= Simple Solutions    
      109    Serial Number= 001001001000
      109    Vendor=1690, Product=FE13 (Version 5.101)
      109    GUIDs returned for product: VID_1690&PID_FE13:
      109       GUID= {69FD5C80-0991-11E8-8001-444553540000}
      109       Details: Btns=32, POVs=(0, 0, 0, 0), Cal=x00000000, Max=R3,U0,V0,X3,Y3,Z3
      109 Product= VIER IM POTT SIDESTICK 2.0
      109    Manufacturer= Leo Bodnar
      109    Serial Number= B63191
      109    Vendor=1DD2, Product=2109 (Version 1.38)
      109 Product= Saitek Pro Flight Rudder Pedals
      109    Vendor=06A3, Product=0763 (Version 1.0)
      109    GUIDs returned for product: VID_06A3&PID_0763:
      109       GUID= {4B92CFA0-9043-11E6-8008-444553540000}
      109       Details: Btns=0, POVs=(0, 0, 0, 0), Cal=x00000000, Max=R511,U0,V0,X127,Y127,Z0
      109       GUID= {4B95B5D0-9043-11E6-800D-444553540000}
      109       Details: Btns=0, POVs=(0, 0, 0, 0), Cal=x00000000, Max=R511,U0,V0,X127,Y127,Z0
      109 Product= Saitek Pro Flight Rudder Pedals
      109    Manufacturer= Saitek
      109    Vendor=06A3, Product=0763 (Version 1.1)
      109 -------------------------------------------------------------------
      141 Device acquired for use:
      141    Joystick ID = 1 (Registry okay)
      141    1=VIER IM POTT SIDESTICK 2.0
      141    1.GUID={30E4FE70-34B8-11E7-8001-444553540000}
      141 Device acquired for use:
      141    Joystick ID = 3 (Registry okay)
      141    3=VIER IM POTT SIDESTICK 2.0
      141    3.GUID={D620D0A0-34B1-11E7-8001-444553540000}
      141 Device acquired for use:
      141    Joystick ID = 4 (Registry okay)
      141    4=Joy0-0
      141    4.GUID={69FD5C80-0991-11E8-8001-444553540000}
      141 Device acquired for use:
      141    Joystick ID = 0 (Registry okay)
      141    0=Saitek Pro Flight Rudder Pedals
      141    0.GUID={4B92CFA0-9043-11E6-8008-444553540000}
      141 Device acquired for use:
      141    Joystick ID = 2 (Registry okay)
      141    2=Saitek Pro Flight Rudder Pedals
      141    2.GUID={4B95B5D0-9043-11E6-800D-444553540000}
      141 -------------------------------------------------------------------
      172 Controllers are set to ON, using RawInput within P3D
      172 LogOptions=40000000 00000001
      172 -------------------------------------------------------------------
      172 ### Traffic limited by user parameter to 80 aircraft
      172 SimConnect_Open succeeded: waiting to check version okay
      172 Opened separate AI Traffic client okay
     5219 Running in "Lockheed Martin® Prepar3D® v5", Version: 5.0.31.35253 (SimConnect: 5.0.0.0)
     5234 Initialising SimConnect data requests now
     5234 FSUIPC Menu entry added
     5234 ... Using Prepar3D with Professional License
     5250 \\FLUSI\C\Users\peter\Documents\Prepar3D v5 Files\SIMstarter NG.fxml
     5250 \\FLUSI\P\A320FMGS\Aircraft\A320-214_SL\cfm56_5B4.air
     5266 ### The user object is 'FMGS A320-214 - DLH SL'
     5266 ### Mode is NORMAL
     5563 ### Mode: PAUSE on
    56453 Loading Complete ...
    56469 ### Mode is NORMAL
    56859 User Aircraft ID 2 supplied, now being used
    56859 Aircraft loaded: running normally now ...
    56953 System time = 12/07/2020 05:23:09, Simulator time = 05:06:05 (03:06Z)
    56953 Aircraft="FMGS A320-214 - DLH SL"
    57500 Requested flightplan loading: "C:\Users\peter\Documents\Prepar3D v4 Files\LOWWEDDH01.pln"
    57531 Planned flight from LOWW to EDDH
    57531 \\FLUSI\C\Users\peter\Documents\Prepar3D v4 Files\LOWWEDDH01.pln
    57531 \\FLUSI\C\Users\peter\Documents\Prepar3D v4 Files\LOWWEDDH01.pln
    63938 -------------------- Starting everything now ----------------------
    63938 Starting WideServer now ...
    63938 ASN active function link set
    63938 Ready for ActiveSky WX radar with additional data
    64016 LUA.0: beginning "C:\Users\peter\Documents\Prepar3D v5 Add-ons\FSUIPC6\ipcReady.lua"
    64063 LUA.1: beginning "C:\Users\peter\Documents\Prepar3D v5 Add-ons\FSUIPC6\peroJeeHellExtPWRbyGSX.lua"
    64328 LUA.1: CabinSoundPrefix: Rafi - DE und EN\
    64531 LUA.1: pero | JeeHellExtPWRbyGSX: Running...
    64531 LUA.1: -------------------------------
    64547 LUA.1:       GENERAL SETTINGS
    64547 LUA.1: -------------------------------
    64547 LUA.1: Show Status Messages:     0
    64547 LUA.1: Door handling:            1
    64547 LUA.1: Wait until EXT PWR Conn:  3000
    64547 LUA.1: Poll Interval:            1000
    64547 LUA.1: GSX Handling:             1
    64547 LUA.1: GSXcatering:              1
    64563 LUA.1: GSXdialogKeyShift:        3
    64563 LUA.1: GSXdialogKeyCode:         87
    64563 LUA.1: Cabin Announcement:       1
    64563 LUA.1: -------------------------------
    64563 LUA.1: Time: 05:23:16

------ GSX ENVIRONMENT
DEBOARDING_STATE:     0
BOARDING_STATE:       0
DEPARTURE_STATE:      0
CATERING_STATE:       0
REFUELING_STATE:      0
JETWAY_STATE:         0
External Power:       0
Boarded Pax:          4
Refueling Mode:       1
------ AIRCRAFT STATE
On Ground:            1
Was already Airborne: 0
Parking Brake:        32767
Engine Left Running:  1
Engine Right Running: 1
Departure Altitude:   0
------ CABIN SOUND STATE
Sound:                1
Welcome:              0
Safety:               0
Climb:                0
Cruise:               0
Descent:              0
Final Approach:       0
After Landing:        0
At Gate:              0
Unboarding:           0
------ CPDPL Integration
GSX Automation:       0


    65156 Advanced Weather Interface Enabled
    65359 LUA.1: Time: 05:23:17

------ GSX ENVIRONMENT
DEBOARDING_STATE:     1
BOARDING_STATE:       1
DEPARTURE_STATE:      1
CATERING_STATE:       1
REFUELING_STATE:      1
JETWAY_STATE:         0
External Power:       0
Boarded Pax:          4
Refueling Mode:       1
------ AIRCRAFT STATE
On Ground:            1
Was already Airborne: 0
Parking Brake:        32767
Engine Left Running:  1
Engine Right Running: 1
Departure Altitude:   0
------ CABIN SOUND STATE
Sound:                1
Welcome:              0
Safety:               0
Climb:                0
Cruise:               0
Descent:              0
Final Approach:       0
After Landing:        0
At Gate:              0
Unboarding:           0
------ CPDPL Integration
GSX Automation:       0


    70672 Weather Mode now = Theme
    71641 FSUIPC Control Action: Ctrl=1070, Param=16
    71641 SendKeyToFS(00000010=[(null)], KEYDOWN) ctr=0
    71641 Sending WM_KEYDOWN, Key=16 (Shift) (Scan code 42), Ctr=1
    71672 KEYDOWN: VK=16, Waiting=0, Repeat=N, Shifts=1
    71672 .. Key not programmed -- passed on to FS
    71766 SendKeyToFS(00000010=[(null)], KEYUP) ctr=0
    71781 Sending WM_KEYUP, Key=16 (Shift) (Scan code 42), Ctr=1
    71813 KEYUP: VK=16, Waiting=0, Shifts=0
    72109 FSUIPC Control Action: Ctrl=1070, Param=855
    72109 SendKeyToFS(00060057=[ctl+shft+W], KEYDOWN) ctr=0
    72125 Sending WM_KEYDOWN, Key=16 (Shift) (Scan code 42), Ctr=3
    72125 Sending WM_KEYDOWN, Key=17 (Control) (Scan code 29), Ctr=3
    72125 KEYDOWN: VK=16, Waiting=0, Repeat=N, Shifts=1
    72125 .. Key not programmed -- passed on to FS
    72125 KEYDOWN: VK=17, Waiting=0, Repeat=N, Shifts=3
    72125 .. Key not programmed -- passed on to FS
    72141 Sending WM_KEYDOWN, Key=87 (Scan code 17), Ctr=1
    72156 KEYDOWN: VK=87, Waiting=0, Repeat=N, Shifts=3
    72156 .. Key not programmed -- passed on to FS
    72234 SendKeyToFS(00060057=[ctl+shft+W], KEYUP) ctr=0
    72234 Sending WM_KEYUP, Key=87 (Scan code 17), Ctr=3
    72234 KEYUP: VK=87, Waiting=0, Shifts=3
    72250 Sending WM_KEYUP, Key=17 (Control) (Scan code 29), Ctr=2
    72250 Sending WM_KEYUP, Key=16 (Shift) (Scan code 42), Ctr=2
    72266 LUA.1: pero | JeeHellExtPWRbyGSX: GSX Jetway Requested
    72281 KEYUP: VK=17, Waiting=0, Shifts=1
    72281 KEYUP: VK=16, Waiting=0, Shifts=0
    72281 LUA.1: Time: 05:23:24

------ GSX ENVIRONMENT
DEBOARDING_STATE:     1
BOARDING_STATE:       1
DEPARTURE_STATE:      1
CATERING_STATE:       1
REFUELING_STATE:      1
JETWAY_STATE:         0
External Power:       0
Boarded Pax:          4
Refueling Mode:       1
------ AIRCRAFT STATE
On Ground:            1
Was already Airborne: 0
Parking Brake:        32767
Engine Left Running:  0
Engine Right Running: 0
Departure Altitude:   0
------ CABIN SOUND STATE
Sound:                1
Welcome:              0
Safety:               0
Climb:                0
Cruise:               0
Descent:              0
Final Approach:       0
After Landing:        0
At Gate:              0
Unboarding:           0
------ CPDPL Integration
GSX Automation:       0


    72313 FS Control Sent: Ctrl=66514, Param=0 ATC_MENU_CLOSE
    72313 LUA.1: ----- NEW MENU -----
    72313 LUA.1: GSX - Activate ground services
    72328 LUA.1: Activate ground services
    72328 LUA.1: Request deboarding
    72328 LUA.1: Request catering service
    72328 LUA.1: Request refueling
    72328 LUA.1: Request boarding
    72328 LUA.1: Prepare for push-back and departure
    72328 LUA.1: No jetways here
    72328 LUA.1: Operate stairs
    72344 LUA.1: Customize this parking position
    72344 LUA.1: Reposition aircraft
    72344 LUA.1: ----- END MENU -----
    73531 FSUIPC Control Action: Ctrl=1070, Param=2103
    73531 SendKeyToFS(00000037=[7], KEYDOWN) ctr=0
    73547 Sending WM_KEYDOWN, Key=55 (Scan code 8), Ctr=1
    73578 KEYDOWN: VK=55, Waiting=0, Repeat=N, Shifts=0
    73578 .. Key not programmed -- passed on to FS
    73641 SendKeyToFS(00000037=[7], KEYUP) ctr=0
    73641 Sending WM_KEYUP, Key=55 (Scan code 8), Ctr=1
    73672 KEYUP: VK=55, Waiting=0, Shifts=0
   105797 KEYDOWN: VK=17, Waiting=0, Repeat=N, Shifts=2
   105797 .. Key not programmed -- passed on to FS
   105828 KEYDOWN: VK=16, Waiting=0, Repeat=N, Shifts=3
   105828 .. Key not programmed -- passed on to FS
   106344 KEYDOWN: VK=16, Waiting=0, Repeat=Y, Shifts=3
   106344 .. Key not programmed -- passed on to FS
   106375 KEYDOWN: VK=16, Waiting=0, Repeat=Y, Shifts=3
   106375 .. Key not programmed -- passed on to FS
   106375 KEYDOWN: VK=87, Waiting=0, Repeat=N, Shifts=3
   106375 .. Key not programmed -- passed on to FS
   106484 FS Control Sent: Ctrl=66514, Param=0 ATC_MENU_CLOSE
   106484 LUA.1: ----- NEW MENU -----
   106484 LUA.1: GSX - Activate ground services
   106484 LUA.1: Activate ground services
   106484 LUA.1: Request deboarding
   106484 LUA.1: Request catering service
   106484 LUA.1: Request refueling
   106484 LUA.1: Request boarding
   106484 LUA.1: Prepare for push-back and departure
   106500 LUA.1: No jetways here
   106500 LUA.1: Operate stairs
   106500 LUA.1: Customize this parking position
   106500 LUA.1: Reposition aircraft
   106500 LUA.1: ----- END MENU -----
   106516 KEYUP: VK=17, Waiting=0, Shifts=1
   106547 KEYUP: VK=87, Waiting=0, Shifts=1
   106547 KEYUP: VK=16, Waiting=0, Shifts=0
   108578 KEYDOWN: VK=49, Waiting=0, Repeat=N, Shifts=0
   108578 .. Key not programmed -- passed on to FS
   108750 KEYUP: VK=49, Waiting=0, Shifts=0
   111188 KEYDOWN: VK=49, Waiting=0, Repeat=N, Shifts=0
   111188 .. Key not programmed -- passed on to FS
   111391 KEYUP: VK=49, Waiting=0, Shifts=0
   113578 KEYDOWN: VK=50, Waiting=0, Repeat=N, Shifts=0
   113578 .. Key not programmed -- passed on to FS
   113922 KEYUP: VK=50, Waiting=0, Shifts=0
   120375 KEYDOWN: VK=51, Waiting=0, Repeat=N, Shifts=0
   120375 .. Key not programmed -- passed on to FS
   120516 KEYUP: VK=51, Waiting=0, Shifts=0
   127906 KEYDOWN: VK=18, Waiting=0, Repeat=N, Shifts=4
   127906 .. Key not programmed -- passed on to FS
   128016 KEYDOWN: VK=13, Waiting=0, Repeat=N, Shifts=4
   128016 .. Key not programmed -- passed on to FS
   128172 KEYUP: VK=13, Waiting=0, Shifts=4
   128172 KEYUP: VK=18, Waiting=0, Shifts=0
   137391 LUA.1: EXT PWR = AVAIL
   137406 LUA.1: EXT PWR = AVAIL
   137406 LUA.1: Door: FWD Action: 1 IsValue: 0
   137422 FS Control Sent: Ctrl=66389, Param=1 TOGGLE_AIRCRAFT_EXIT
   137422 LUA.1: Time: 05:24:29

------ GSX ENVIRONMENT
DEBOARDING_STATE:     1
BOARDING_STATE:       1
DEPARTURE_STATE:      1
CATERING_STATE:       1
REFUELING_STATE:      1
JETWAY_STATE:         0
External Power:       1
Boarded Pax:          4
Refueling Mode:       1
------ AIRCRAFT STATE
On Ground:            1
Was already Airborne: 0
Parking Brake:        32767
Engine Left Running:  0
Engine Right Running: 0
Departure Altitude:   0
------ CABIN SOUND STATE
Sound:                1
Welcome:              0
Safety:               0
Climb:                0
Cruise:               0
Descent:              0
Final Approach:       0
After Landing:        0
At Gate:              0
Unboarding:           0
------ CPDPL Integration
GSX Automation:       0


   213500 Sim stopped: average frame rate for last 157 secs = 29.4 fps
   213500    Max AI traffic was 0 aircraft
   213500 -------------------------------------------------------------------
   215281 === Closing session: waiting for DLLStop to be called ...
   223078 === DLLStop called ...
   223078 === Closing external processes we started ...
   224078 === About to kill any Lua plug-ins still running ...
   224234 Lua threads being terminated:
   224234       1 = "C:\Users\peter\Documents\Prepar3D v5 Add-ons\FSUIPC6\peroJeeHellExtPWRbyGSX.lua"
   224406 LUA: "C:\Users\peter\Documents\Prepar3D v5 Add-ons\FSUIPC6\peroJeeHellExtPWRbyGSX.lua": killed
   224406 === Closing global Lua thread
   225422 === About to kill my timers ...
   225625 === Restoring window procs ...
   225625 === Unloading libraries ...
   225625 === stopping other threads ...
   225625 === ... Button scanning ...
   225719 === ... Axis scanning ...
   225813 === Releasing joystick devices ...
   225813 === Freeing macro memory
   225813 === Removing any offset overrides
   225813 === Closing all WideFS threads
   227172 === Clearing any displays left
   227172 === NOTE: not calling SimConnect_Close ...
   227172 === AI slots deleted!
   227172 === Freeing button memory ...
   227172 === Deleting wxstationlist.bin file ...
   227172 === Closing my Windows ...
   227172 === Freeing FS libraries ...
   228172 === Closing devices ...
   228172 === Closing the Log ... Bye Bye! ...
   228172 System time = 12/07/2020 05:26:00, Simulator time = 05:08:41 (03:08Z)
   228172 *** FSUIPC log file being closed
Minimum frame rate was 28.1 fps, Maximum was 29.8 fps
Average frame rate for running time of 157 secs = 29.4 fps
Maximum AI traffic for session was 0 aircraft
Traffic deletions 0 aircraft
Memory managed: 148 Allocs, 147 Freed
********* FSUIPC Log file closed ***********

And that's the script:

---------------------------------------------------------------------------
---------------------------------------------------------------------------
--|                    pero  |  JeeHell Ext PWR by GSX                  |--
--|                     Version 9.13.03 - 19.06.2020                    |--
---------------------------------------------------------------------------
--| This LUA Script is designed to use with FSDT GSX and JeeHell FMGS.  |--
--| If you don't use both this script is useless.                       |--
--|                                                                     |--
--| Developer: Peter Rosendahl (capt_pero@web.de)                       |--
--| FREEWARE. Private use ONLY!                                         |--
--|                                                                     |--
--| GSX States:                                                         |--
--| 1 = service can be called                                           |--
--| 2 = service is not available                                        |--
--| 3 = services has been bypassed                                      |--
--| 4 = service has been requested                                      |--
--| 5 = service is being performed                                      |--
--| 6 = service has been completed                                      |--
--|                                                                     |--
---------------------------------------------------------------------------
--|      Cabin Sounds by Peter Rosendahl                                |--
---------------------------------------------------------------------------
--| Cabin Sounds are inspired by ICA 2.0 of Rainer Kunst                |--
--| https://www.simmershome.de                                          |--
--|                                                                     |--
--| Applause sound by Alterr                                            |--
--| https://freesound.org/people/Alterr/sounds/209792/                  |--
--|                                                                     |--
--| Loop Freesky by bebeto                                              |--
--| https://freesound.org/people/bebeto/sounds/554/                     |--
--|                                                                     |--
--| Cabin Ding Dong by aaronray                                         |--
--| https://freesound.org/people/aaronray/sounds/71996/                 |--
--|                                                                     |--
--| Bad landing Sound by alphatone, Shades and dersuperanton            |--
--| https://freesound.org/people/alphatone/sounds/394798/               |--
--| https://freesound.org/people/Shades/sounds/37242/                   |--
--| https://freesound.org/people/dersuperanton/sounds/437646/           |--
---------------------------------------------------------------------------


--------------------------------------------------------------------------------------------------------
-- DO NOT CHANGE BELOW THIS LINE! -- DO NOT CHANGE BELOW THIS LINE! -- DO NOT CHANGE BELOW THIS LINE! --
--------------------------------------------------------------------------------------------------------
-- DO NOT CHANGE BELOW THIS LINE! -- DO NOT CHANGE BELOW THIS LINE! -- DO NOT CHANGE BELOW THIS LINE! --
--------------------------------------------------------------------------------------------------------
-- DO NOT CHANGE BELOW THIS LINE! -- DO NOT CHANGE BELOW THIS LINE! -- DO NOT CHANGE BELOW THIS LINE! --
--------------------------------------------------------------------------------------------------------


require("peroJeeHellExtPWRbyGSX_config")

-- Init random
math.randomseed(os.time())
math.random(); math.random(); math.random()

-- Set Backlight to 0
ipc.clearbitsUW(0x739A, 1)

-- Variable definition
local ac_allowedATCmodels = {"A318", "A319", "A320", "A321", "A332"} -- Use 4-Letter Code only!

local runScript = 0
local logResult = ""
local logging = tonumber(ipc.get("pero_logging"))
local soundDevice = tonumber(ipc.get("pero_soundDevice"))
local soundVolume = tonumber(ipc.get("pero_soundVolume"))
local soundDevicePNF = tonumber(ipc.get("pero_soundDevicePNF"))
local soundVolumePNF = tonumber(ipc.get("pero_soundVolumePNF"))
local soundDir = tonumber(ipc.get("pero_soundDir"))
local soundDirPNF = tonumber(ipc.get("pero_soundDirPNF"))
local taxiMusicFile = ipc.get("pero_TaxiMusicFile")
local showLandingReport = tonumber(ipc.get("pero_showLandingReport"))
local applausVspeedValue = tonumber(ipc.get("pero_applausVspeedValue"))
local badLandingVspeedValue = tonumber(ipc.get("pero_badLandingVspeedValue"))

local showStatusMessages = tonumber(ipc.get("pero_showStatusMessages"))
local doorHandling = tonumber(ipc.get("pero_doorHandling"))

local GSXhandling = tonumber(ipc.get("pero_GSXhandling"))
local defaultJetwayToggle = tonumber(ipc.get("pero_defaultJetwayToggle"))
local GSXcatering = tonumber(ipc.get("pero_GSXcatering"))
local GSXautomationCounterSetting = tonumber(ipc.get("pero_GSXautomationCounterSetting"))
local GSXfueling = tonumber(ipc.get("pero_GSXfueling"))
local GSXfuelingMode = tonumber(ipc.get("pero_GSXfuelingMode")) -- 0=with, 1=before, 2=after
local GSXdeicing = tonumber(ipc.get("pero_GSXdeicing"))
local GSXv2_randomPaxActive = tonumber(ipc.get("pero_GSXv2_randomPaxActive"))
local GSXv2_MinPax = tonumber(ipc.get("pero_GSXv2_MinPax"))
local GSXv2_MaxPax = tonumber(ipc.get("pero_GSXv2_MaxPax"))
local GSXv2_DisableBoardingDeboardingPilots = tonumber(ipc.get("pero_GSXv2_DisableBoardingDeboardingPilots"))
local GSXv2_DisableBoardingDeboardingCrew = tonumber(ipc.get("pero_GSXv2_DisableBoardingDeboardingCrew"))
local GSXdialogKeyShift = tonumber(ipc.get("pero_GSXdialogKeyShift"))
local GSXdialogKeyCode = tonumber(ipc.get("pero_GSXdialogKeyCode"))

local PNFsoundPlay = tonumber(ipc.get("pero_PNF"))
local CabinSoundPlay = tonumber(ipc.get("pero_CabinSoundinUse"))
local CabinSoundStartSafetyAfterSeconds = tonumber(ipc.get("pero_CabinSoundStartSafetyAfterSeconds")) * 1000
local CabinSoundPlayMusic = tonumber(ipc.get("pero_CabinSoundPlayMusic"))
local CabinSoundClimbDescentAlt = tonumber(ipc.get("pero_CabinSoundClimbDescentAlt"))
local CabinSoundCruiseAlt = tonumber(ipc.get("pero_CabinSoundCruiseAlt"))
local CabinSoundbasePath = ipc.get("pero_CabinSoundbasePath")
local CabinSoundPacks = {}
local CabinSoundSoundPacksCount = 0
local soundPacks = ipc.get("pero_soundPacks")
for s in string.gmatch(soundPacks, "[^;]+") do
	CabinSoundSoundPacksCount = CabinSoundSoundPacksCount + 1
	CabinSoundPacks[CabinSoundSoundPacksCount] = s
end
local CabinSoundPackInUse = ""
local CabinSoundDialogKeyShift = ipc.get("pero_CabinSoundDialogKeyShift")
local CabinSoundDialogKeyCode = ipc.get("pero_CabinSoundDialogKeyCode")
local CabinSoundDialogKeyShiftClear = ipc.get("pero_CabinSoundDialogKeyShiftClear")
local CabinSoundDialogKeyCodeClear = ipc.get("pero_CabinSoundDialogKeyCodeClear")

local PNFSoundDialogKeyShift = ipc.get("pero_PNFSoundDialogKeyShift")
local PNFSoundDialogKeyCode = ipc.get("pero_PNFSoundDialogKeyCode")

local DEBOARDING_STATE=0
local BOARDING_STATE=0
local DEPARTURE_STATE = 0
local CATERING_STATE = 0
local REFUELING_STATE = 0
local REFUELING_STATE_BEFORE = 0
local JETWAY_STATE = 0
local extPWR = 0
local departureTime = 0
local departureAlt = 0
local maxCruiseAlt = 0
local GSXboardedPax = math.random(GSXv2_MinPax, GSXv2_MaxPax)
local GSXoperation = ""
local onGround = ipc.readUW("0366")
local waitUntilExtPWRconnect = 3000
local pollInterval = 1000
local alreadyAirborne = 0
local parkBrakeSet = ipc.readUW("0BC8")
local engineLeftRunning = ipc.readUW("0894")
local engineRightRunning = ipc.readUW("092C")
local engineLeftPreState = 0
local engineRightPreState = 0
local engineLeftN1 = 0
local engineRightN1 = 0
local LMvspeed = 0
local LMbank = 0
local LMpitch = 0
local LMdepICAO = "XXXX"
local LMarrICAO = ""
local LMtimeOFF = ""
local LMtimeON = ""
local LMtimeTO = ""
local LMtimeLD = ""
local LMwind = ""
local applausPlayed = 0
local CabinSoundWelcome = 0
local CabinSoundSafety = 0
local CabinSoundClimb = 0
local CabinSoundCruise = 0
local CabinSoundDescent = 0
local CabinSoundFinal = 0
local CabinSoundAfterLand = 0
local CabinSoundAtGate = 0
local CabinSoundUnboarding = 0
local musicTaxiPlay = 0
local lightLand = 0
local lightTaxi = 0
local lightStrobe = 0
local PNF_70ktsDone = 0
local PNF_100ktsDone = 0
local PNF_ThrustSetDone = 0
local PNF_PosClimbDone = 0
local PNF_V1speed = tonumber(ipc.get("pero_PNF_V1speed"))
local PNF_VRspeed = tonumber(ipc.get("pero_PNF_VRspeed"))
local PNF_V1Done = 0
local PNF_VRDone = 0
local PNF_IcingDetectedDone = 0
local PNF_VspeedTimer = 0
local PNF_VspeedPuffer = ""
local PNF_timerCabinCrewPrepareDeparture = 0
local PNF_timerCabinCrewPrepareLanding = 0
local boardingDone = 0
local boardingDeboardingDone = 0
local deboardingDone = 0
local departureDone = 0
local cateringDone = 0
local cateringStartDone = 0
local jetwayDone = 0
local boardingDeboardingStarted = 0
local boardingRequestedByMenu = 0
local cateringRequestedByMenu = 0
local timeWaitBeforeAction = 0
local timeCallBoardingDeboarding = 0
local timeScriptLoaded = 0
local timeJetwaysRequested = 0
local timeLastSoundPlayed = 0
local blockedSet = 0
local GSXautomationActive = tonumber(ipc.get("pero_GSXautomationActive"))
local GSXautomationCounter = -2
local GSXautomationStop = 0
local GSXjetway1L = 0
local GSXjetway2L = 0
local GSXjetwayFound = 0
local GSXstairsAvailable = 0
local GSXengineStartBeforePushback = tonumber(ipc.get("pero_GSXengineStartBeforePushback"))
local defaultJetwayStopToggle = 0
local icingCurrentValue = 0
local icingLastValue = 0
local icingStartWarningValue = tonumber(ipc.get("pero_icingStartWarningValueActiveSky"))
local icingSetTimeLastChange = 0
local icingClearTimeLastChange = 0
local icingTimeIcingRepeat = 0
local icingTimeWaitToDeactivateOnGround = 0
local flapsRequiredForLandingCallout = 16000
local GSXmenuDoubleClickInUse = ipc.get("pero_GSXmenuDoubleClickInUse")
local GSXmenuDoubleClickDialogKeyShift = ipc.get("pero_GSXmenuDoubleClickDialogKeyShift")
local GSXmenuDoubleClickDialogKeyCode = ipc.get("pero_GSXmenuDoubleClickDialogKeyCode")
local GSXmenuDoubleClickLast = ""
local GSXmenuDoubleClickLastTime = 0
local seatBealtSign = 0
local noSmokingSign = 0

local A330 = 0

ipc.writeUW(0x66D1, 0)
if (PNFsoundPlay==1) then ipc.setbitsUW(0x66D1, 64) end
if (CabinSoundPlay==1) then ipc.setbitsUW(0x66D1, 128) end

--------------------------------------------------------------------------------------------------------
---------------------------------------------------------------- Door and Ext. Power Management
--------------------------------------------------------------------------------------------------

function GSX_DEBOARDING_STATE(varname, value)
	DEBOARDING_STATE = value
end

function GSX_BOARDING_STATE(varname, value)
	BOARDING_STATE = value
end

function GSX_CATERING_STATE(varname, value)
	CATERING_STATE = value
end

function GSX_REFUELING_STATE(varname, value)
	REFUELING_STATE = value
end

function GSX_DEPARTURE_STATE(varname, value)
	DEPARTURE_STATE = value
end

function GSXv2_JETWAY_POWER_STATE(varname, value)
	JETWAY_STATE = value
end

function openDoorsForBoardingDeboarding()
	boardingDeboardingStarted = 1
	extPWR_Avail()
	if (GSXcatering==0 or GSXjetwayFound==1) then doorAction("FWD",1) end
	if (GSXautomationActive==1 and GSXfuelingMode==0) then
		ipc.sleep(1000)
		doorAction("AFT",1)
	end
end

local timeWaitAnnouncement = 0
local timeWaitSafety = 0
local timeWaitPaxSign = 0
local timeDoorsCloseWait = 0
local timeAFTwait = 0

function GSXaction()
	if (runScript==0) then return false end
	if (onGround==1) then
		if (REFUELING_STATE ~= REFUELING_STATE_BEFORE) then
			if (REFUELING_STATE==1 and REFUELING_STATE_BEFORE >= 4 and GSXfuelingMode==1 and GSXfueling==1 and alreadyAirborne==0) then
				setPax()
				GSXoperation = "B"
				if (logging == 1) then ipc.log("pero | JeeHellExtPWRbyGSX: GSX Boarding Requested") end
				ipc.keypressplus(GSXdialogKeyCode, GSXdialogKeyShift, 4)
			end
			REFUELING_STATE_BEFORE = REFUELING_STATE
		end

		if (((BOARDING_STATE >= 4 and boardingDone == 0) or (DEBOARDING_STATE >= 4 and deboardingDone == 0)) and boardingDeboardingDone == 0) then
			blockedSet = 0
			if (GSXcatering==0 or DEBOARDING_STATE>=4) then doorAction("CGO",1) end
			if (GSXautomationActive==0 or GSXfuelingMode > 0) then
				if (timeAFTwait ~=0 and ipc.elapsedtime() > 1000) then
					doorAction("FWD",1)
				end
				if (timeAFTwait ~=0 and ipc.elapsedtime() > timeAFTwait) then
					doorAction("AFT",1)
					boardingDeboardingDone = 1
					timeAFTwait = 0
				elseif (timeAFTwait == 0) then
					timeAFTwait = ipc.elapsedtime() + 3000
				end
			else
				boardingDeboardingDone = 1
			end
			
			if (logging == 1) then
				if (DEBOARDING_STATE >= 4) then
					ipc.log("pero | JeeHellExtPWRbyGSX: GSX Deboarding Ongoing")
				elseif (BOARDING_STATE >= 4) then
					ipc.log("pero | JeeHellExtPWRbyGSX: GSX Boarding Ongoing")
				end
			end
		end

		if (((JETWAY_STATE==5) or ((BOARDING_STATE>=4 or DEBOARDING_STATE>=4) and JETWAY_STATE==0)) and boardingDeboardingStarted==0) then
			if (GSXjetway1L==0 and GSXjetway2L>=1) then
				GSXoperation = "J"
				ipc.keypressplus(GSXdialogKeyCode, GSXdialogKeyShift, 4)
				if (logging == 1) then ipc.log("pero | JeeHellExtPWRbyGSX: GSX Jetway Requested") end
				if (showStatusMessages == 1) then ipc.Display("pero | JeeHellExtPWRbyGSX: GSX Jetway Requested", 3) end
			end
			openDoorsForBoardingDeboarding()
		end
		if (alreadyAirborne==0) then
			if (parkBrakeSet==0 or engineLeftRunning~=0 or engineRightRunning~=0 or GSXautomationActive==1 or blockedSet==1) then
				if (logic.And(ipc.readUW(0x66D1), 2) == 0) then ipc.setbitsUW(0x66D1, 2) end
			else
				if (BOARDING_STATE~=1) then
					if (logic.And(ipc.readUW(0x66D1), 2) == 0) then ipc.setbitsUW(0x66D1, 2) end
				else 
					if (logic.And(ipc.readUW(0x66D1), 2) ~= 0 and GSXhandling==1) then ipc.clearbitsUW(0x66D1, 2) end
				end
			end
		else
			if (parkBrakeSet==0 or engineLeftRunning~=0 or engineRightRunning~=0 or GSXautomationActive==1 or blockedSet==1) then
				if (logic.And(ipc.readUW(0x66D1), 2) == 0) then ipc.setbitsUW(0x66D1, 2) end
			else
				if (DEBOARDING_STATE~=1) then
					if (logic.And(ipc.readUW(0x66D1), 2) == 0) then ipc.setbitsUW(0x66D1, 2) end
				else 
					if (logic.And(ipc.readUW(0x66D1), 2) ~= 0 and GSXhandling==1) then ipc.clearbitsUW(0x66D1, 2) end
				end
			end
		end

		if ((JETWAY_STATE==4 or JETWAY_STATE==1) and extPWR==1 and (BOARDING_STATE==6 or BOARDING_STATE==1)) then
			extPWR_Off()
		end

		if (CATERING_STATE == 5 and cateringStartDone == 0) then
			doorAction("SVC",1)
			cateringStartDone = 1
		end

		if (CATERING_STATE == 6 and cateringDone == 0) then
			doorAction("SVC",0)
			doorAction("CGO",1)
			cateringDone = 1
		end

		if (DEBOARDING_STATE == 6 and deboardingDone == 0) then
			alreadyAirborne = 0
			sound.stop(CabinMusicWav)
			CabinMusicWav = false
			musicTaxiPlay = 0
			ipc.clearbitsUW(0x66D1, 4)
			doorAction("CGO",0)
			doorAction("AFT", 0)
			deboardingDone = 1
			boardingDone = 0
			boardingDeboardingDone = 0
			GSXautomationCounter = -1
			if (GSXv2_randomPaxActive==1 or GSXautomationActive==0) then
				GSXboardedPax = math.random(GSXv2_MinPax, GSXv2_MaxPax)
			end
		end

		if (DEPARTURE_STATE >= 4 and extPWR==1 and (BOARDING_STATE==6 or BOARDING_STATE==1)) then
			extPWR_Off()
		end
			
		if (DEPARTURE_STATE >= 4 and departureDone==0) then
			defaultJetwayStopToggle = 0
			doorAction("CGO",0)
			if (timeDoorsCloseWait==0) then timeDoorsCloseWait = ipc.elapsedtime() end
			if (ipc.elapsedtime() > timeDoorsCloseWait+3000) then doorAction("FWD",0) end
			if (ipc.elapsedtime() > timeDoorsCloseWait+3000+2000) then doorAction("AFT",0) end
			if (ipc.elapsedtime() > timeDoorsCloseWait+3000+2000+1000) then 
				doorAction("SVC",0) 
				if (JETWAY_STATE==0 or JETWAY_STATE==2) then 
					extPWR_Off()
				end
				departureDone = 1
				timeDoorsCloseWait = 0
			end
		end

		if (BOARDING_STATE == 6 and boardingDone==0) then
			if (timeDoorsCloseWait==0) then timeDoorsCloseWait = ipc.elapsedtime() end
			if (ipc.elapsedtime() > timeDoorsCloseWait+8000) then doorAction("CGO",0) end
			if (ipc.elapsedtime() > timeDoorsCloseWait+8000+5000) then doorAction("FWD",0) end
			if (ipc.elapsedtime() > timeDoorsCloseWait+8000+5000+3000) then
				doorAction("AFT",0)
				boardingDone = 1
				if (GSXfuelingMode == 2 and GSXfueling==1) then
					GSXoperation = "F"
					if (logging == 1) then ipc.log("pero | JeeHellExtPWRbyGSX: GSX Refueling Requested") end
					if (showStatusMessages == 1) then
						ipc.Display("pero | JeeHellExtPWRbyGSX: GSX Refueling Requested", 3)
					end
					ipc.keypressplus(GSXdialogKeyCode, GSXdialogKeyShift, 4)
				end
				resetAllValuesBeforeNextLeg()
				timeDoorsCloseWait = 0
			end
		end
		
		if (((boardingDone == 0 and alreadyAirborne == 0 and BOARDING_STATE >= 1) or (deboardingDone == 0 and alreadyAirborne == 1 and DEBOARDING_STATE >= 1)) and DEPARTURE_STATE<4 and ipc.elapsedtime() > timeJetwaysRequested + 60000 and timeJetwaysRequested ~= 0) then
			extPWR_Avail()
			doorAction("FWD",1)
			timeJetwaysRequested = 0
		end
		
		if (DEBOARDING_STATE == 5 and CabinSoundUnboarding == 0 and CabinSoundAtGate == 1) then
			if (CabinSoundPlay==1) then
				if (timeWaitPaxSign==0) then
					timeWaitPaxSign = ipc.elapsedtime() + 3000
					sound.play(CabinSoundbasePath.."Cabin_PaxSign.wav", soundDevice, soundVolume, soundDir)
				end
				if (ipc.elapsedtime() > timeWaitPaxSign and timeWaitPaxSign~=0) then
					CabinSoundUnboarding = 1
					if (showStatusMessages == 1) then
						ipc.Display("pero | JeeHellExtPWRbyGSX: Cabin Sound Unboarding", 3)
					end
					CabinDeboardingWav = sound.play(CabinSoundbasePath..CabinSoundPrefix.."Cabin_Deboarding.wav", soundDevice, soundVolume, soundDir)
					if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath..CabinSoundPrefix.."Cabin_Deboarding.wav >") end
					timeWaitPaxSign = 0
				end
			end
		end
	end
end

function doorAction(door, value)
	-- A320
		-- 	1 / 1	Left FWD
		-- 	2 / 2	Right Cargo (both)
		-- 	3 / 8	Right Service (both)
		-- 	4 / 4	Left AFT

	-- A330
		-- 1 / 1	Left (all)
		-- 2 / 2	Right Service (all)
		-- 3 / 8	Cargo FWD
		-- 4 / 4	Cargo AFT

	if (A330==0) then
		if (door == "FWD") then doorActionHelper(1, value, door) end
		if (door == "CGO") then doorActionHelper(2, value, door) end
		if (door == "AFT") then
			if (GSXstairsAvailable==0 and value==1) then 
			else
				doorActionHelper(4, value, door) 
			end
		end
		if (door == "SVC") then doorActionHelper(8, value, door) end
	else
		if (door == "FWD") then doorActionHelper(1, value, door) end
		if (door == "CGO") then 
			doorActionHelper(4, value, door)
			ipc.sleep(500)
			doorActionHelper(8, value, door)
		end
		if (door == "SVC") then doorActionHelper(2, value, door) end
	end
end

function doorActionHelper(door, value, doorString)
	if (doorHandling == 1) then
		if (engineLeftRunning==1 and engineLeftRunning==1 and value==1) then
			return true
		end

		local doorAction = door

		if (door == 4) then doorAction = 3 end
		if (door == 8) then doorAction = 4 end

		if (value==1) then
			value = door
		else
			value = 0
		end

		local statExits = ipc.readUB("3367")
		if (logging == 1) then
			ipc.log("Door: "..doorString.." Action: "..value.." IsValue: "..logic.And(statExits,door))
		end
		if (logic.And(statExits,door) ~= value) then
			if (door==1 and defaultJetwayToggle==1 and defaultJetwayStopToggle == 0) then
				if (showStatusMessages == 1) then
					ipc.Display("pero | JeeHellExtPWRbyGSX: Toggle Default Jetway", 3)
				end
				ipc.control(66695,0)
			end
			ipc.control(66389,doorAction)
		end
	end
end

function resetAllValuesBeforeNextLeg()
	CabinSoundWelcome = 0
	CabinSoundSafety = 0
	PNF_timerCabinCrewPrepareDeparture = 0
	CabinSoundClimb = 0
	CabinSoundCruise = 0
	CabinSoundDescent = 0
	CabinSoundFinal = 0
	CabinSoundAfterLand = 0
	CabinSoundAtGate = 0
	CabinSoundUnboarding = 0
	maxCruiseAlt = 0
	departureAlt = 0
	-- applausPlayed = 0
	musicTaxiPlay = 0
	timeAFTwait = 0
	if (sound.query(CabinMusicWav) == true) then 
		sound.stop(CabinMusicWav)
		CabinMusicWav = false
	end
	setCabinSoundPack()
end

function showStatus(value)
	if (showStatusMessages == 1) then
		ipc.Display("pero | JeeHellExtPWRbyGSX: EXT PWR = "..value, 3)
	end
	if (logging == 1) then
		ipc.log("EXT PWR = "..value)
	end
	ipc.log("EXT PWR = "..value)
end

function extPWR_Avail()	
	if (extPWR == 0) then
		valPwrAvail = ipc.readUB("7397")
		valPwrOn = ipc.readSW("7398")
		batt1 = ipc.readSW("73BC")
		batt2 = ipc.readSW("73BE")		
		if (logic.And(valPwrAvail,128) == 0) and (logic.And(valPwrOn,1) == 0) then
			if (batt1~=0 and batt2~=0) then
				-- Toggle Connect/Disconnect EXT PWR
				ipc.sleep(waitUntilExtPWRconnect)
				ipc.writeUB("78ED",33)
				showStatus("AVAIL")
				extPWR = 1
			else
				ipc.log("pero | JeeHellExtPWRbyGSX: Can't read BAT1 and BAT2. Either JeeHell FMGS is not running or FSUIPC Connector not installed!")
			end
		end
	end
end

function extPWR_Off()
	valPwrAvail = ipc.readUB("7397")
	valPwrOn = ipc.readUB("7398")
	if (logic.And(valPwrAvail,128) > 0) or (logic.And(valPwrOn,1) > 0) then
		if (logic.And(valPwrOn,1) > 0) then
			-- EXT PWR = ON to EXT PWR = AVAIL
			ipc.writeUB("78EE",79)
		end
		-- Toggle Connect/Disconnect EXT PWR
		ipc.writeUB("78ED",33)
		showStatus("Disconnected")
		extPWR = -1
	end
end


--------------------------------------------------------------------------------------------------------
---------------------------------------------------------------- pero Cabin Sounds
--------------------------------------------------------------------------------------------------------

function CabinSoundsToggle()
	if (GSXautomationCounter > 0) then
		GSXautomationStop = 1
	else
		if (CabinSoundPlay==0) then
			CabinSoundPlay=1
			if (ipc.elapsedtime() > timeScriptLoaded + 5000) then ipc.Display("pero | JeeHellExtPWRbyGSX: Cabin Sound -- ON", 3) end
		else
			CabinSoundPlay=0
			sound.stop(CabinMusicWav)
			CabinMusicWav = false
			if (ipc.elapsedtime() > timeScriptLoaded + 5000) then ipc.Display("pero | JeeHellExtPWRbyGSX: Cabin Sound -- OFF", 3) end
		end
	end
end

function PNFSoundsToggle()
	if (PNFsoundPlay==0) then
		PNFsoundPlay=1
		if (ipc.elapsedtime() > timeScriptLoaded + 5000) then ipc.Display("pero | JeeHellExtPWRbyGSX: Pilot none flying announcements -- ON", 3) end
	else
		PNFsoundPlay=0
		if (ipc.elapsedtime() > timeScriptLoaded + 5000) then ipc.Display("pero | JeeHellExtPWRbyGSX: Pilot none flying announcements -- OFF", 3) end
	end
end

function setCabinSoundPack()
	local newCabinSoundPrefix = ""
	if (CabinSoundSoundPacksCount==1) then CabinSoundPrefix = "" end
	while (newCabinSoundPrefix==CabinSoundPrefix or newCabinSoundPrefix=="") do
		newCabinSoundPrefix = CabinSoundPacks[math.random(1, CabinSoundSoundPacksCount)].."\\"
	end
	CabinSoundPrefix = newCabinSoundPrefix
	if (logging == 1) then ipc.log("CabinSoundPrefix: "..CabinSoundPrefix) end
end

function CabinSoundAction()
	if (runScript==0) then return false end
	local groundSpeed = ipc.readUD("02B4") * 3600 / 1852 / 65536
	
	-- Welcome Onboard
	if (CabinSoundWelcome==0 and boardingDone==1) then
		if (groundSpeed == 0) then
			if (CabinSoundPlay==1) then 
				if (timeWaitPaxSign==0) then
					timeWaitPaxSign = ipc.elapsedtime()
					sound.play(CabinSoundbasePath.."Cabin_PaxSign.wav", soundDevice, soundVolume, soundDir)
				end
				if (ipc.elapsedtime() > timeWaitPaxSign+3000) then
					if (showStatusMessages == 1) then
						ipc.Display("pero | JeeHellExtPWRbyGSX: Cabin Sound Welcome", 3)
					end
					CabinWelcomeWav = sound.play(CabinSoundbasePath..CabinSoundPrefix.."Cabin_Welcome.wav", soundDevice, soundVolume, soundDir)
					if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath..CabinSoundPrefix.."Cabin_Welcome.wav >") end
					musicTaxiPlay = 0
					CabinSoundWelcome = 1
					timeWaitPaxSign = 0
					timeWaitAnnouncement = ipc.elapsedtime()
				end
			end
		end
	end

	-- Safety
	if (CabinSoundSafety==0) then
		if (onGround==1) then		
			if ((groundSpeed > 2 and groundSpeed < 30) or (ipc.elapsedtime() > timeWaitAnnouncement+CabinSoundStartSafetyAfterSeconds and timeWaitAnnouncement~=0 and CabinSoundStartSafetyAfterSeconds~=0)) then				
				if (timeWaitSafety==0) then timeWaitSafety = ipc.elapsedtime() end
				LMtimeOFF = getSimTimeDate()
				if (ipc.elapsedtime() > timeWaitSafety + 15000 and timeWaitSafety~=0) then
					timeWaitSafety = 0
					timeWaitAnnouncement = 0
					-- groundSpeed = ipc.readUD("02B4") * 3600 / 1852 / 65536
					if (groundSpeed < 30) then
						CabinSoundWelcome = 1
						CabinSoundSafety = 2
					end
				end
			end
		end
	elseif (CabinSoundSafety==2) then
		if (sound.query(CabinMusicWav) == true) then 
			sound.stop(CabinMusicWav)
			CabinMusicWav = false
		end
		if (CabinSoundPlay==1) then
			if (timeWaitPaxSign == 0) then timeWaitPaxSign = ipc.elapsedtime() + math.random(1,9) * 1000 end
			if (ipc.elapsedtime() > timeWaitPaxSign and timeWaitPaxSign~=0 and timeWaitAnnouncement==0) then
				sound.play(CabinSoundbasePath.."Cabin_PaxSign.wav", soundDevice, soundVolume, soundDir)
				timeWaitAnnouncement = ipc.elapsedtime() + 3000
			end
			if (ipc.elapsedtime() > timeWaitAnnouncement and timeWaitAnnouncement~=0) then
				hourLocalTime = ipc.readUB("0238")
				if (hourLocalTime>21) or (hourLocalTime<5) then
					if (showStatusMessages == 1) then
						ipc.Display("pero | JeeHellExtPWRbyGSX: Cabin Sound Safety Night", 3)
					end
					CabinSafetyWav = sound.play(CabinSoundbasePath..CabinSoundPrefix.."Cabin_SafetyNight.wav", soundDevice, soundVolume, soundDir)
					if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath..CabinSoundPrefix.."Cabin_SafetyNight.wav >") end
				else
					if (showStatusMessages == 1) then
						ipc.Display("pero | JeeHellExtPWRbyGSX: Cabin Sound Safety", 3)
					end
					CabinSafetyWav = sound.play(CabinSoundbasePath..CabinSoundPrefix.."Cabin_Safety.wav", soundDevice, soundVolume, soundDir)
					if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath..CabinSoundPrefix.."Cabin_Safety.wav >") end
				end
				CabinSoundSafety = 1
				timeWaitAnnouncement = 0
				timeWaitPaxSign = 0
			end
		else
			CabinSoundSafety = 1
		end
	end
	
	-- PNF Cabin Crew prepare for Departure
	if (CabinSoundSafety==1) then
		if ((lightLand==1 or lightStrobe==1) and PNF_timerCabinCrewPrepareDeparture==0) then PNF_timerCabinCrewPrepareDeparture = ipc.elapsedtime() end
		if (ipc.elapsedtime() > PNF_timerCabinCrewPrepareDeparture + 2000 and PNF_timerCabinCrewPrepareDeparture > 0) then
			PNF_timerCabinCrewPrepareDeparture = -1
			if (PNFsoundPlay==1 and onGround==1) then sound.play(CabinSoundbasePath.."PNF_CabinCrewPrepareDeparture.wav", soundDevicePNF, soundVolumePNF, soundDirPNF) end
		end
	end
	
	-- Climb
	if (CabinSoundClimb~=1 and onGround==0) then
		vspeed=ipc.readSW("0842") * -3.28084
		alt=ipc.readUD("0574") * 3.28084
		if (((alt - departureAlt > CabinSoundClimbDescentAlt and vspeed > 1200 and alt > 18300) or (ipc.elapsedtime() > departureTime + 120000 and noSmokingSign==0)) or (CabinSoundClimb==2)) then
			CabinSoundWelcome = 1
			CabinSoundSafety = 1
			if (CabinSoundPlay==1) then
				if (timeWaitPaxSign == 0) then 
					timeWaitPaxSign = ipc.elapsedtime() + 5000
					CabinSoundClimb = 2
				end
				if (ipc.elapsedtime() > timeWaitPaxSign and timeWaitPaxSign~=0 and CabinSoundClimb==2) then				
					sound.play(CabinSoundbasePath.."Cabin_PaxSign.wav", soundDevice, soundVolume, soundDir)
					timeWaitPaxSign = ipc.elapsedtime() + 3000
					CabinSoundClimb = 3
				end
				if (ipc.elapsedtime() > timeWaitPaxSign and timeWaitPaxSign~=0 and CabinSoundClimb==3) then
					if (showStatusMessages == 1) then
						ipc.Display("pero | JeeHellExtPWRbyGSX: Cabin Sound Climb", 3)
					end
					sound.play(CabinSoundbasePath..CabinSoundPrefix.."Cabin_Climb.wav", soundDevice, soundVolume, soundDir)
					if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath..CabinSoundPrefix.."Cabin_Climb.wav >") end
					timeWaitPaxSign = 0
					CabinSoundClimb = 1
				end
			end
		end
	end

	-- Cruise
	if (CabinSoundCruise~=1 and onGround==0) then
		vspeed=ipc.readSW("0842") * -3.28084
		alt=ipc.readUD("0574") * 3.28084
		if (((alt - departureAlt > CabinSoundCruiseAlt and vspeed < 700) or (ipc.elapsedtime() > departureTime + 300000 and seatBealtSign==0)) or (CabinSoundCruise==2)) then
			CabinSoundWelcome = 1
			CabinSoundSafety = 1
			CabinSoundClimb = 1
			if (timeWaitPaxSign == 0) then 
				timeWaitPaxSign = ipc.elapsedtime() + 3000
				if (CabinSoundPlay==1) then sound.play(CabinSoundbasePath.."Cabin_PaxSign.wav", soundDevice, soundVolume, soundDir) end
				CabinSoundCruise = 2
			end
			if (ipc.elapsedtime() > timeWaitPaxSign and timeWaitPaxSign~=0) then
				if (showStatusMessages == 1) then
					ipc.Display("pero | JeeHellExtPWRbyGSX: Cabin Sound Cruise", 3)
				end
				if (CabinSoundPlay==1) then
					sound.play(CabinSoundbasePath..CabinSoundPrefix.."Cabin_Cruise.wav", soundDevice, soundVolume, soundDir)
					if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath..CabinSoundPrefix.."Cabin_Cruise.wav >") end
				end
				timeWaitPaxSign = 0
				CabinSoundCruise = 1
			end
		end
	end

	-- Descent
	if (CabinSoundDescent~=1 and CabinSoundClimb==1 and onGround==0) then
		vspeed = ipc.readSW("0842") * 3.28084
		alt=ipc.readUD("0574") * 3.28084
		if ((alt < maxCruiseAlt-3000 and vspeed > 500 and seatBealtSign==1) or (CabinSoundDescent==2)) then
			CabinSoundWelcome = 1
			CabinSoundSafety = 1
			CabinSoundClimb = 1
			CabinSoundCruise = 1
			
			if (timeWaitPaxSign == 0) then 
				timeWaitPaxSign = ipc.elapsedtime() + 5000
				CabinSoundDescent = 2
			end
			if (ipc.elapsedtime() > timeWaitPaxSign and timeWaitPaxSign~=0 and CabinSoundDescent==2) then
				if (CabinSoundPlay==1) then sound.play(CabinSoundbasePath.."Cabin_PaxSign.wav", soundDevice, soundVolume, soundDir) end
				timeWaitPaxSign = ipc.elapsedtime() + 3000				
				CabinSoundDescent = 3
			end
			if (ipc.elapsedtime() > timeWaitPaxSign and timeWaitPaxSign~=0 and CabinSoundDescent==3) then
				if (showStatusMessages == 1) then
					ipc.Display("pero | JeeHellExtPWRbyGSX: Cabin Sound Descent", 3)
				end
				if (CabinSoundPlay==1) then
					sound.play(CabinSoundbasePath..CabinSoundPrefix.."Cabin_Descent.wav", soundDevice, soundVolume, soundDir)
					if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath..CabinSoundPrefix.."Cabin_Descent.wav >") end
				end
				timeWaitPaxSign = 0
				CabinSoundDescent = 1
				timeLastSoundPlayed = ipc.elapsedtime()
			end
			
		end
	end

	-- Final
	if (CabinSoundFinal~=1) then
		vspeed = ipc.readSW("0842") * 3.28084
		groundalt = ipc.readUD("0020") * 3.28084 / 256
		alt = ipc.readUD("0574") * 3.28084
		altogr = alt - groundalt
		if (((altogr < 3000 and vspeed > 500 and ipc.elapsedtime() > departureTime+240000) or (CabinSoundFinal==2)) and ipc.elapsedtime() > timeLastSoundPlayed+150000) then
			CabinSoundWelcome = 1
			CabinSoundSafety = 1
			CabinSoundClimb = 1
			CabinSoundCruise = 1
			CabinSoundDescent = 1
			
			if (timeWaitPaxSign == 0) then 
				timeWaitPaxSign = ipc.elapsedtime() + 3000
				if (CabinSoundPlay==1) then sound.play(CabinSoundbasePath.."Cabin_PaxSign.wav", soundDevice, soundVolume, soundDir) end
				CabinSoundFinal = 2
			end
			if (ipc.elapsedtime() > timeWaitPaxSign and timeWaitPaxSign~=0) then
				CabinSoundFinal = 1
				PNF_CabinCrewPrepareLanding = 1
				timeWaitPaxSign = 0
				hourLocalTime = ipc.readUB("0238")
				if (hourLocalTime>21 or hourLocalTime<5) then
					if (showStatusMessages == 1) then
						ipc.Display("pero | JeeHellExtPWRbyGSX: Cabin Sound Final Night", 3)
					end
					if (CabinSoundPlay==1) then
						CabinFinalWav = sound.play(CabinSoundbasePath..CabinSoundPrefix.."Cabin_FinalNight.wav", soundDevice, soundVolume, soundDir)
						if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath..CabinSoundPrefix.."Cabin_FinalNight.wav >") end
					end
				else
					if (showStatusMessages == 1) then
						ipc.Display("pero | JeeHellExtPWRbyGSX: Cabin Sound Final", 3)
					end
					if (CabinSoundPlay==1) then
						CabinSafetyWav = sound.play(CabinSoundbasePath..CabinSoundPrefix.."Cabin_Final.wav", soundDevice, soundVolume, soundDir)
						if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath..CabinSoundPrefix.."Cabin_Final.wav >") end
					end
				end
				timeLastSoundPlayed = ipc.elapsedtime()
			end
		end
	end
	
	-- PNF Prepare for landing
	if (CabinSoundFinal==1 and ipc.elapsedtime() > timeLastSoundPlayed+150000 and onGround==0) then
		local currentFlaps = ipc.readUD(0x0BE0)
		if (currentFlaps < 7100) then PNF_timerCabinCrewPrepareLanding = 0 end
		if (logic.And(ipc.readUB("7398"),128) ~= 0) then flapsRequiredForLandingCallout = 9000 end
		if (currentFlaps >= flapsRequiredForLandingCallout and sound.query(CabinFinalWav) == false and PNF_timerCabinCrewPrepareLanding == 0) then 
			PNF_timerCabinCrewPrepareLanding = ipc.elapsedtime()
		end
	end
	
	-- After landing
	if (CabinSoundAfterLand==0 and CabinSoundFinal==1 and onGround==1) then
		if ((ipc.readUD("02B4") * 3600 / 1852 / 65536) <= 40) then
			CabinSoundWelcome = 1
			CabinSoundSafety = 1
			CabinSoundClimb = 1
			CabinSoundCruise = 1
			CabinSoundDescent = 1
			CabinSoundFinal = 1
			
			if (timeWaitPaxSign == 0) then timeWaitPaxSign = ipc.elapsedtime() + 3000 end
			if (ipc.elapsedtime() > timeWaitPaxSign and timeWaitPaxSign~=0 and timeWaitAnnouncement==0) then
				if (CabinSoundPlay==1) then sound.play(CabinSoundbasePath.."Cabin_PaxSign.wav", soundDevice, soundVolume, soundDir) end
				timeWaitAnnouncement = ipc.elapsedtime()+3000
			end
			if (ipc.elapsedtime() > timeWaitAnnouncement and timeWaitAnnouncement~=0) then
				if (showStatusMessages == 1) then
					ipc.Display("pero | JeeHellExtPWRbyGSX: Cabin Sound After Landing", 3)
				end
				if (CabinSoundPlay==1) then 
					CabinAfterLandingWav = sound.play(CabinSoundbasePath..CabinSoundPrefix.."Cabin_AfterLanding.wav", soundDevice, soundVolume, soundDir)
					if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath..CabinSoundPrefix.."Cabin_AfterLanding.wav >") end
				end
				timeWaitPaxSign = 0
				timeWaitAnnouncement = 0
				CabinSoundAfterLand = 1
				CabinSoundDescent = 1
			end
		end
	end

	-- At Gate
	if (CabinSoundAtGate==0 and CabinSoundAfterLand==1 and onGround==1) then
		if (parkBrakeSet>0 and engineLeftRunning==0 and engineRightRunning==0) then
			icao, lat, lon, alt, dist = ipc.readStruct(0x0658, "4STR", "4FLT")
			LMarrICAO = icao
			LMtimeON = getSimTimeDate()
			sound.stop(CabinMusicWav)
			CabinMusicWav = false
			
			if (timeWaitPaxSign == 0) then timeWaitPaxSign = ipc.elapsedtime() + 2000 end
			if (ipc.elapsedtime() > timeWaitPaxSign and timeWaitPaxSign~=0 and timeWaitAnnouncement==0) then
				if (CabinSoundPlay==1) then sound.play(CabinSoundbasePath.."Cabin_PaxSign.wav", soundDevice, soundVolume, soundDir) end
				timeWaitAnnouncement = ipc.elapsedtime()+3000
			end
			if (ipc.elapsedtime() > timeWaitAnnouncement and timeWaitAnnouncement~=0) then
				if (showStatusMessages == 1) then
					ipc.Display("pero | JeeHellExtPWRbyGSX: Cabin Sound At Gate", 3)
				end
				if (CabinSoundPlay==1) then 
					CabinAtGateWav = sound.play(CabinSoundbasePath..CabinSoundPrefix.."Cabin_AtGate.wav", soundDevice, soundVolume, soundDir) 
					if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath..CabinSoundPrefix.."Cabin_AtGate.wav >") end
				end
				musicTaxiPlay = 0
				timeWaitPaxSign = 0
				timeWaitAnnouncement = 0
				CabinSoundAfterLand = 1
				CabinSoundDescent = 1
				CabinSoundAtGate = 1
				if (showLandingReport==1) then
					ipc.Display("pero | JeeHellExtPWRbyGSX: Landing Report\n--------------------------------------------------\nRate: "..LMvspeed.." ft/min\nPitch: "..round(LMpitch,2).." degrees\nBank: "..round(LMbank,2).." degrees\nWind: "..LMwind, 20)
				end
				file = io.open("peroJeeHellExtPWRbyGSX_LandingMonitorLog.txt", "a")
				local landingReport = getDate()..";"..LMdepICAO..";"..LMarrICAO..";"..LMtimeOFF..";"..LMtimeTO..";"..LMtimeLD..";"..LMtimeON..";"..LMvspeed.." ft/min;"..round(LMpitch,2).." degrees;"..round(LMbank,2).." degrees;"..LMwind..";\n"
				file:write(landingReport)
				file:close()
				if (logging==1) then ipc.log("Landing Report added: "..landingReport) end
				LMdepICAO = "XXXX"
			end
		end
	end

	-- Music
	if (groundSpeed > 40 and sound.query(CabinMusicWav) == true and musicTaxiPlay == 1) then
		sound.stop(CabinSafetyWav)
		sound.stop(CabinMusicWav)
		CabinMusicWav = false
		musicTaxiPlay = -1
	end
	if (alreadyAirborne==0) then
		if (CabinSoundPlay==1 and CabinSoundPlayMusic==1 and CabinSoundWelcome == 1 and CabinSoundUnboarding == 0 and sound.query(CabinMusicWav) == false and sound.query(CabinWelcomeWav) == false and sound.query(CabinSafetyWav) == false and lightLand==0 and lightStrobe==0) then
			ipc.sleep(1000)
			if (showStatusMessages == 1) then ipc.Display("pero | JeeHellExtPWRbyGSX: Play Cabin Music", 3) end
			CabinMusicWav = sound.playloop(taxiMusicFile, soundDevice, soundVolume, soundDir)
			if (logging == 1) then ipc.log("Play sound < "..taxiMusicFile.." >") end
			musicTaxiPlay = 1
		end
		if ((lightStrobe == 1 or lightLand == 1) and sound.query(CabinMusicWav) == true and musicTaxiPlay == 1) then 
			sound.stop(CabinMusicWav)
			CabinMusicWav = false
			musicTaxiPlay = 0
		end
	else
		if (CabinSoundPlay==1 and CabinSoundPlayMusic==1 and CabinSoundAfterLand == 1 and sound.query(CabinMusicWav) == false and sound.query(CabinAfterLandingWav) == false and lightTaxi==1 and CabinSoundUnboarding==0) then
			ipc.sleep(1000)
			if (showStatusMessages == 1) then ipc.Display("pero | JeeHellExtPWRbyGSX: Play Cabin Music", 3) end
			CabinMusicWav = sound.playloop(taxiMusicFile, soundDevice, soundVolume, soundDir)
			if (logging == 1) then ipc.log("Play sound < "..taxiMusicFile.." >") end
			musicTaxiPlay = 1
		end
		if (lightTaxi == 0 and musicTaxiPlay == 1 and sound.query(CabinMusicWav) == true and CabinSoundUnboarding==0) then 
			sound.stop(CabinMusicWav)
			CabinMusicWav = false
			musicTaxiPlay = 0
		end
		if (DEBOARDING_STATE == 5 and musicTaxiPlay==0 and sound.query(CabinMusicWav) == false and sound.query(CabinAtGateWav) == false and sound.query(CabinDeboardingWav) == false and CabinSoundUnboarding==1 and CabinSoundPlay==1) then
			ipc.sleep(1000)
			if (showStatusMessages == 1) then ipc.Display("pero | JeeHellExtPWRbyGSX: Play Cabin Music", 3) end
			CabinMusicWav = sound.playloop(taxiMusicFile, soundDevice, soundVolume, soundDir)
			if (logging == 1) then ipc.log("Play sound < "..taxiMusicFile.." >") end
			musicTaxiPlay = 1
		end
	end
end



--------------------------------------------------------------------------------------------------------
---------------------------------------------------------------- Var Changes
--------------------------------------------------------------------------------------------------------

function GSXdialogKeyPress(offset, value)
	if (GSXautomationActive == 1 or GSXv2_randomPaxActive==0) then
		setPax()
	end
end

function verticalSpeedChanged(offset, value)
	if (runScript==0) then return false end
	alt = ipc.readUD("0574") * 3.28084
	if (alt > maxCruiseAlt) then
		maxCruiseAlt = alt
	end
	if (alt > departureAlt + 100 and onGround == 0) then
		alreadyAirborne = 1
		ipc.setbitsUW(0x66D1, 4)
	end
end

function groundStateChanged(offset, value)
	if (runScript==0) then return false end
	onGround = value
	if (onGround==0) then
		departureAlt = ipc.readUD("0574") * 3.28084
		departureTime = ipc.elapsedtime()
		LMtimeTO = getSimTimeDate()
		if (LMdepICAO=="XXXX") then
			icao, lat, lon, alt, dist = ipc.readStruct(0x0658, "4STR", "4FLT")
			LMdepICAO = icao
		end
		icingTimeWaitToDeactivateOnGround = 0
	else
		LMtimeLD = getSimTimeDate()
		applausPlayed = 0
		departureAlt = 0
		if (icingTimeWaitToDeactivateOnGround==0) then icingTimeWaitToDeactivateOnGround = ipc.elapsedtime() end
	end
		
	triggerGSXboardingDeboarding()
	if (sound.query(CabinMusicWav) == true) then sound.stop(CabinMusicWav) end
	extPWR = 0
	boardingDone = 0
	boardingDeboardingDone = 0
	deboardingDone = 0
	departureDone = 0
	cateringDone = 0
	cateringStartDone = 0
	jetwayDone = 0
	boardingDeboardingStarted = 0
	boardingRequestedByMenu = 0
	cateringRequestedByMenu = 0
	musicTaxiPlay = 0
	GSXautomationCounter = -1
	timeCallBoardingDeboarding = 0
	timeLastSoundPlayed = 0

	if (onGround == 1 and ipc.elapsedtime() > departureTime+240000 and departureTime~=0 and applausPlayed==0) then
		local vspeed = ipc.readSD("030C") * 60 * 3.28084 / 256
		LMvspeed = math.floor((vspeed * 10^2) + 0.5) / (10^2)
		LMpitch = ipc.readSD("0578") * 360 / (65536 * 65536)
		LMbank =  ipc.readSD("057C") * 360 / (65536 * 65536)
		local wind = ipc.readUW(0x0E92) * 360 / 65536
		LMwind = round(wind, 0).." @ "..ipc.readUW(0x0E90) .. " kts"
		if (CabinSoundPlay==1) then
			if (applausVspeedValue ~= 0 and LMvspeed >= applausVspeedValue) then 
				applausPlayed = 2
			elseif (badLandingVspeedValue ~= 0 and LMvspeed >=badLandingVspeedValue) then
				applausPlayed = 3
			end
		end
	end
end

function parkingBrakeChanged(offset, value)
	if (runScript==0) then return false end
	parkBrakeSet = value
	triggerGSXboardingDeboarding()
end

function engineLeftRunChanged(offset, value)
	if (runScript==0) then return false end	
	engineLeftPreState = engineLeftRunning
	engineLeftRunning = value	
	if (engineLeftPreState ==0 and engineLeftRunning==1) then resetAllValuesBeforeNextLegbyEngines() end
	if (engineLeftRunning == 1) then extPWR_Off() end
	triggerGSXboardingDeboarding()
end

function engineRightRunChanged(offset, value)
	if (runScript==0) then return false end	
	engineRightPreState = engineRightRunning
	engineRightRunning = value
	if (engineRightPreState == 0 and engineRightRunning==1) then resetAllValuesBeforeNextLegbyEngines() end
	if (engineRightRunning == 1) then extPWR_Off() end
	triggerGSXboardingDeboarding()
end

function resetAllValuesBeforeNextLegbyEngines()
	if (LMdepICAO=="XXXX") then
		icao, lat, lon, alt, dist = ipc.readStruct(0x0658, "4STR", "4FLT")
		LMdepICAO = icao
		if (logging==1) then ipc.log("Departure ICAO set to < "..LMdepICAO.." >") end
	end
	if (CabinSoundAfterLand==1 and engineLeftRunning==1 and engineRightRunning==1) then 
		if (logging==1) then ipc.log("Reset all values before next leg...") end
		resetAllValuesBeforeNextLeg() 
	end		
end

function extLightsChanged(offset, value)
	if (runScript==0) then return false end
	if (logic.And(value,4) ~= 0) then 
		lightLand = 1
	else
		lightLand = 0
	end
	if (logic.And(value,8) ~= 0) then 
		lightTaxi = 1
	else
		lightTaxi = 0
	end
	if (logic.And(value,16) ~= 0) then 
		lightStrobe = 1
	else
		lightStrobe = 0
	end
end

local posClimbTimer = 0
function IASchanged(offset, value)
	if (runScript==0) then return false end
	value = value / 128
		
	if (value > 40) then
		local vspeed = ipc.readSW("0842") * -3.28084
		
		-- PNF Reset
		if (CabinSoundFinal==1 and engineLeftN1 >= 14500 and vspeed>1000 and posClimbTimer==0) then
			posClimbTimer = ipc.elapsedtime()
			PNF_PosClimbDone = 0
		end
		if (ipc.elapsedtime() > posClimbTimer + 240000 and posClimbTimer~=0) then posClimbTimer = 0 end
		
		-- PNF Positive Climb
		if (PNF_PosClimbDone == 0) then
			groundalt = ipc.readUD("0020") * 3.28084 / 256
			alt = ipc.readUD("0574") * 3.28084
			altogr = alt - groundalt
			if (altogr >= 50 and vspeed > 1000) then
				PNF_PosClimbDone = 1
				if (PNFsoundPlay==1) then 
					sound.play(CabinSoundbasePath.."PNF_PosClimb.wav", soundDevicePNF, soundVolumePNF, soundDirPNF) 
					if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath.."PNF_PosClimb.wav >") end
				end
			end
		end

		-- PNF Callout 70 kts after landing
		if (PNF_70ktsDone == 0 and PNF_PosClimbDone==1) then
			if (value < 70) then
				PNF_70ktsDone = 1
				PNF_PosClimbDone = 0
				if (onGround==1 and PNFsoundPlay==1) then
					sound.play(CabinSoundbasePath.."PNF_70kts.wav", soundDevicePNF, soundVolumePNF, soundDirPNF)
					if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath.."PNF_70kts.wav >") end
				end
			end
		end

		-- PNF Callout 100 kts
		if (PNF_100ktsDone == 0) then
			if (value >=100) then
				PNF_100ktsDone = 1
				if (onGround==1 and PNFsoundPlay==1) then
					sound.play(CabinSoundbasePath.."PNF_100kts.wav", soundDevicePNF, soundVolumePNF, soundDirPNF)
					if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath.."PNF_100kts.wav >") end
				end
			end
		end

		-- PNF Callout V1
		if (PNF_V1Done == 0 and PNF_V1speed ~=0) then
			if (value > PNF_V1speed) then
				PNF_V1Done = 1
				if (onGround==1 and PNFsoundPlay==1) then
					V1 = sound.play(CabinSoundbasePath.."PNF_V1.wav", soundDevicePNF, soundVolumePNF, soundDirPNF)
					if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath.."PNF_V1.wav >") end
				end
			end
		end

		-- PNF Callout VR
		if (PNF_VRDone == 0 and PNF_VRspeed ~=0) then
			if (value > PNF_VRspeed) then
				if (sound.query(V1) == false) then
					PNF_VRDone = 1
					if (onGround==1 and PNFsoundPlay==1) then
						sound.play(CabinSoundbasePath.."PNF_VR.wav", soundDevicePNF, soundVolumePNF, soundDirPNF)
						if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath.."PNF_VR.wav >") end
					end
				end
			end
		end
	end
	if (onGround==1) then
		if (engineLeftN1 < 3500) then PNF_ThrustSetDone = 0 end
		if (value < 70) then
			PNF_70ktsDone = 0
			PNF_PosClimbDone = 0
		end
		if (value < 90) then PNF_100ktsDone = 0 end
		if (value < PNF_V1speed-10) then PNF_V1Done = 0 end
		if (value < PNF_VRspeed-10) then PNF_VRDone = 0 end
	end
end

function TextMenuOpened(mtype, colour, scroll, delay, id, n, msgs)
	if (runScript==0) then return false end
	if (n~=0 and onGround==1 and GSXhandling==1) then

		ipc.control(66514, 0)	-- Close ATC Window

		local myMenu = {}
		
		-- Logging GSX Menu
		ipc.log("----- NEW MENU -----")
		for i=1,n do
			myMenu[i] = string.sub(msgs[i], 1, string.len(msgs[i])-1)
			ipc.log(myMenu[i])
		end
		ipc.log("----- END MENU -----")

		ipc.sleep(200)

		if (myMenu[2] == "Activate ground services") then
			ipc.sleep(800)
			setPax()
			if (GSXoperation=="D") then ipc.keypressplus(49) end
			if (GSXoperation=="C") then ipc.keypressplus(50) end
			if (GSXoperation=="F") then ipc.keypressplus(51) end
			if (GSXoperation=="B") then 
				ipc.keypressplus(52) 
				if (showStatusMessages == 1) then
					ipc.Display("pero | JeeHellExtPWRbyGSX: GSX Boarding requested with "..GSXboardedPax.." Passengers", 3)
				end
			end
			if (GSXoperation=="J") then
				GSXstairsAvailable = 1
				if (myMenu[9] == "No stairs available") then
					GSXstairsAvailable = 0
				end
				if (myMenu[8] == "Operate jetway(s)") then
					ipc.keypressplus(54)
					timeJetwaysRequested = ipc.elapsedtime()
					defaultJetwayStopToggle = 1
					GSXjetwayFound = 1
				else					
					if (myMenu[9] == "Operate stairs") then
						ipc.keypressplus(55)
						timeJetwaysRequested = ipc.elapsedtime()
						defaultJetwayStopToggle = 1
						GSXjetwayFound = 1
					else
						ipc.keypressplus(GSXdialogKeyCode, GSXdialogKeyShift, 4)
						defaultJetwayStopToggle = 0
						GSXjetwayFound = 0
					end
					extPWR_Avail()
				end
			end
			if (GSXoperation~="")  then GSXoperation = "" end
			return true
		end
		
		-- Deicing
		if (myMenu[2] == "Ice warning: do you request the de-icing treatment?") then
			if (GSXdeicing==1) then
				ipc.keypressplus(49)
			else
				ipc.keypressplus(50)
			end
			return true
		end
		
		-- Deicing fluid
		if (myMenu[2] == "Select fluid type") then
			ipc.keypressplus(49)
			return true
		end
		
		-- Start Engines before Pushback
		if (myMenu[2] == "Do you want to start engine(s) before Pushback?") then
			if (GSXengineStartBeforePushback==1) then ipc.keypressplus(49) end
			if (GSXengineStartBeforePushback==2) then ipc.keypressplus(50) end
			return true
		end
	
		
		-- Airport handling
		for i=3,n do
			if (string.find(myMenu[i], "GSX default choice") ~= nil) then
				ipc.keypressplus(46+i)
				return true
			end
		end
		
		-- Select jetways
		if (myMenu[2] == "Select jetways") then			
			if (GSXjetway1L == 0 and GSXjetway2L == 0 and A330==1) then
				for i=3,n do
					if (string.find(myMenu[i], "1L") ~= nil) then GSXjetway1L = GSXjetway1L + 1 end
					if (string.find(myMenu[i], "2L") ~= nil) then GSXjetway2L = GSXjetway2L + 1 end
				end
			end
			for i=3,n do
				if (string.find(myMenu[i], "Confirm selection") ~= nil) then
					ipc.keypressplus(46+i)
					return true
				end
			end
		end
		if (myMenu[2] == "Select jetways" and A330==1) then
			for i=3,n do 
				if (GSXjetway1L==2) then
					if (string.find(myMenu[i], "1L") ~= nil or string.find(myMenu[i], "Don't select any jetway") ~= nil) then
						ipc.keypressplus(46+i)
						GSXjetway1L = 0
						return true
					end
				end
				if (GSXjetway2L>=1) then
					if (string.find(myMenu[i], "2L") ~= nil or string.find(myMenu[i], "Don't select any jetway") ~= nil) then
						ipc.keypressplus(46+i)
						GSXjetway2L = 0
						return true
					end
				end
			end
		end
		if (myMenu[2] == "Select jetways") then
			for i=3,n do 
			    -- if ((string.find(myMenu[i], "Undock") == nil) and (string.find(myMenu[i], "*") ~= nil) and (string.find(myMenu[i], "Don't select any jetway") ~= nil) and (string.find(myMenu[i], "1L") ~= nil)) then
				if (contains(myMenu[i], "*") == true) and (contains(myMenu[i], "1L") == true) and (contains(myMenu[i], "Undock") == false) then
					ipc.keypressplus(46+i)
					return true
				end
			end
			for i=3,n do 		
			    -- if (string.find(myMenu[i], "Don't select any jetway") ~= nil) then		
				if contains(myMenu[i], "Don't select any jetway") then
					ipc.keypressplus(46+i)										
					return true
				end				
			end
		end
	end
end

function contains(input, search)
	if (string.find(input, search) == nil) then return false end
	return true
end

function triggerGSXboardingDeboarding()
	if (runScript==0) then return false end
	local offsetGSXtrigger = ipc.readUW(0x66D1)
	if (logic.And(offsetGSXtrigger,64) ~= 0 and PNFsoundPlay==0) then PNFSoundsToggle() end
	if (logic.And(offsetGSXtrigger,64) == 0 and PNFsoundPlay==1) then PNFSoundsToggle() end
	if (logic.And(offsetGSXtrigger,128) ~= 0 and CabinSoundPlay==0) then CabinSoundsToggle() end
	if (logic.And(offsetGSXtrigger,128) == 0 and CabinSoundPlay==1) then CabinSoundsToggle() end

	if (onGround==1 and parkBrakeSet>0 and engineLeftRunning==0 and engineRightRunning==0) then
		timeCallJetway = ipc.elapsedtime()
		if (DEBOARDING_STATE==5) then
			ipc.Display("pero | JeeHellExtPWRbyGSX: Can't call boarding because Deboarding is not completed!", 20)
		else
			if (GSXautomationActive==1) then
				if (GSXautomationCounter==-1) then GSXautomationCounter = GSXautomationCounterSetting end
			else
				if (logic.And(offsetGSXtrigger ,1) ~= 0) then
					GSXcatering = 0
					GSXfueling = 0
					GSXdeicing = 0
					if (logic.And(offsetGSXtrigger,8) ~= 0) then GSXcatering = 1 end
					if (logic.And(offsetGSXtrigger,16) ~= 0) then GSXfueling = 1 end
					if (logic.And(offsetGSXtrigger,32) ~= 0) then GSXdeicing = 1 end
					GSXautomationCounter = 0
					ipc.clearbitsUW(0x66D1, 1)
				end
			end
		end
	else
		timeCallJetway = 0
	end
end

function setPax()
	local paxeFromOffset = ipc.readSW(0x66D2)
	if (paxeFromOffset > 1) then GSXboardedPax = paxeFromOffset end
	if (GSXv2_randomPaxActive==1 or GSXautomationActive==0) then
		ipc.writeLvar("FSDT_GSX_NUMPASSENGERS", GSXboardedPax)
		if (GSXv2_DisableBoardingDeboardingPilots==1) then 
			ipc.writeLvar("FSDT_GSX_PILOTS_NOT_BOARDING", 1)
			ipc.writeLvar("FSDT_GSX_PILOTS_NOT_DEBOARDING", 1)
		end
		if (GSXv2_DisableBoardingDeboardingCrew==1) then 
			ipc.writeLvar("FSDT_GSX_CREW_NOT_BOARDING", 1)
			ipc.writeLvar("FSDT_GSX_CREW_NOT_DEBOARDING", 1)
		end
	end
end

local ac_countLast = -1
function checkReload(offset, ac_count)
	if (ac_count > ac_countLast) then
		if (ac_countLast > -1) then
			sound.stop(CabinMusicWav)
			ipc.macro("Lua peroJeeHellExtPWRbyGSX")
		end
		ac_countLast = ac_count
	end
end

local timeWaitApplause = 0
function TimerChanges()

	if (runScript==0) then return false end
	eTime = ipc.elapsedtime()

	engineLeftN1 = ipc.readUW(0x0898)
	engineRightN1 = ipc.readUW(0x0930)
	
	-- StructIcing gone
	if (icingCurrentValue == 0 and PNF_IcingDetectedDone == 1 and onGround == 0) then		
		if (eTime > icingSetTimeLastChange + 600000 and icingSetTimeLastChange > 0) then -- 10 Minuten
			if (logic.And(ipc.readUB("739B"),1) ~= 0 or logic.And(ipc.readUB("739B"),4) ~= 0 or logic.And(ipc.readUB("739B"),16) ~= 0) then
				if (PNFsoundPlay == 1 and onGround == 0) then
					sound.play(CabinSoundbasePath.."PNF_IcingGone.wav", soundDevicePNF, soundVolumePNF, soundDirPNF)					
					if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath.."PNF_IcingGone.wav >") end
				end			
			end
			ipc.clearbitsUW(0x66D1, 512)
			if (logging == 1) then ipc.log("Icing Indicator off (by time in flight)") end
			icingClearTimeLastChange = eTime
			icingSetTimeLastChange = 0
			PNF_IcingDetectedDone = 0
		end	
	end
	
	-- StructIcing gone on Ground
	if (eTime > icingTimeWaitToDeactivateOnGround + 300000 and icingTimeWaitToDeactivateOnGround > 0 and onGround == 1) then
		ipc.clearbitsUW(0x66D1, 512)
		if (logging == 1) then ipc.log("Icing Indicator off (by time on ground)") end
		icingClearTimeLastChange = 0 -- eTime()
		icingSetTimeLastChange = 0
		PNF_IcingDetectedDone = 0
		icingTimeWaitToDeactivateOnGround = 0
	end

	-- StructIcing
	if (logic.And(ipc.readUB("739B"),1) == 0 and logic.And(ipc.readUB("739B"),4) == 0 and logic.And(ipc.readUB("739B"),16) == 0) then				
		if (eTime > icingClearTimeLastChange + 120000 and icingSetTimeLastChange > 0) then
			if (icingTimeIcingRepeat > 0 and eTime > icingTimeIcingRepeat + 120000) then
				if (onGround == 0) then  -- and logic.And(ipc.readUB(0x66D1), 512) == 0
					ipc.setbitsUW(0x66D1, 512)
					if (logging == 1) then ipc.log("Icing Indicator On (no AntiIcing active)") end
					
					if (PNFsoundPlay==1 and ipc.readUW(0x0264) == 0 and icingLastValue>0) then -- keine Pause  
						sound.play(CabinSoundbasePath.."PNF_IcingDetected.wav", soundDevicePNF, soundVolumePNF, soundDirPNF)
						if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath.."PNF_IcingDetected.wav >") end
					else
						if (icingLastValue == 1) then	
							ipc.Display("Pilot: We have light icing!", 5)
						elseif (icingLastValue == 2) then
							ipc.Display("Pilot: We have moderate icing!", 5)
						elseif (icingLastValue == 3) then
							ipc.Display("Pilot: We have heavy icing!", 5)
						elseif (icingLastValue == 4) then
							ipc.Display("Pilot: We have severe icing!", 5)
						end	
					end	
				end
				PNF_IcingDetectedDone = 1
				icingTimeIcingRepeat = 0
			else
				if (icingTimeIcingRepeat==0) then icingTimeIcingRepeat = eTime end
			end
		end 				
	end
	
	-- PNF Callout Thrust Set
	if (PNF_ThrustSetDone == 0) then
		if (engineLeftN1>13107 and engineRightN1>13107) then -- 80% (16384 = 100%)
			PNF_ThrustSetDone = 1
			if (onGround==1 and PNFsoundPlay==1) then
				sound.play(CabinSoundbasePath.."PNF_ThrustSet.wav", soundDevicePNF, soundVolumePNF, soundDirPNF)
				if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath.."PNF_ThrustSet.wav >") end
			end
		end
	end

	-- Cabin Crew Prepare Landing
	if (eTime >= PNF_timerCabinCrewPrepareLanding + 2500 and PNF_timerCabinCrewPrepareLanding > 0 and onGround==0) then
		PNF_timerCabinCrewPrepareLanding = -1
		if (PNFsoundPlay==1) then 
			sound.play(CabinSoundbasePath.."PNF_CabinCrewPrepareLanding.wav", soundDevicePNF, soundVolumePNF, soundDirPNF) 
			if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath.."PNF_CabinCrewPrepareLanding.wav >") end
		end
	end
	
	if (applausPlayed == 2) then
		if (timeWaitApplause==0) then timeWaitApplause = ipc.elapsedtime() + 5000 end
		if (ipc.elapsedtime() > timeWaitApplause) then
			LandingMonitorWav = sound.play(CabinSoundbasePath.."Cabin_Applause.wav", soundDevice, soundVolume, soundDir)
			if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath.."Cabin_Applause.wav >") end
			applausPlayed = 1
			timeWaitApplause = 0
		end
	elseif (applausPlayed == 3) then
		if (timeWaitApplause==0) then timeWaitApplause = ipc.elapsedtime() + 2000 end
		if (ipc.elapsedtime() > timeWaitApplause) then
			LandingMonitorWav = sound.play(CabinSoundbasePath.."Cabin_BadLanding.wav", soundDevice, soundVolume, soundDir)
			if (logging == 1) then ipc.log("Play sound < "..CabinSoundbasePath.."Cabin_BadLanding.wav >") end
			applausPlayed = 1
			timeWaitApplause = 0
		end
	end
	
	if (eTime > PNF_VspeedTimer + 3000 and PNF_VspeedPuffer~="") then
		PNF_VspeedPuffer = ""
		PNF_VspeedTimer = 0
	end

	if (eTime > GSXmenuDoubleClickLastTime + 1000 and GSXmenuDoubleClickLastTime ~= 0) then
		GSXmenuDoubleClickLastTime = 0
		if (GSXmenuDoubleClickLast == "GSX") then
			-- Single Click
			ipc.keypressplus(GSXdialogKeyCode, GSXdialogKeyShift, 4)
		else
			-- Double Click
			ipc.keypressplus(GSXmenuDoubleClickDialogKeyCode, GSXmenuDoubleClickDialogKeyShift, 4)
		end
		GSXmenuDoubleClickLast = ""
	end
	
	if (onGround==1 and GSXhandling==1) then
		groundSpeed = ipc.readUD("02B4") * 3600 / 1852 / 65536

		-- Start Automation Counter
		if (GSXautomationStop==1) then
			ipc.Display("pero | JeeHellExtPWRbyGSX: GSX Automation canceled by user.", 3)
			GSXautomationStop = 0
			GSXautomationCounter = -1
		end
		if (GSXautomationCounter > 0 and ((boardingDone==0 and BOARDING_STATE==1) or (deboardingDone==0 and DEBOARDING_STATE==1)) and GSXhandling==1) then 
			ipc.Display("pero | JeeHellExtPWRbyGSX: GSX Automation starting in "..GSXautomationCounter.."\nPress "..CabinSoundDialogKeyShiftClear.." + "..CabinSoundDialogKeyCodeClear.." to cancel.", 3)
			GSXautomationCounter = GSXautomationCounter - 1
		end
		if (GSXautomationCounter==0) then
			GSXautomationCounter = -2
			ipc.sleep(1000)
			if (alreadyAirborne==0 and boardingDone==0 and BOARDING_STATE==1 and GSXhandling==1) then
				ipc.setbitsUW(0x66D1, 2)
				blockedSet = 1
				setPax()
				if (GSXfueling==1 and GSXfuelingMode<=1) then
					GSXoperation = "F"
					if (logging == 1) then ipc.log("pero | JeeHellExtPWRbyGSX: GSX Refueling Requested") end
					if (showStatusMessages == 1) then
						ipc.Display("pero | JeeHellExtPWRbyGSX: GSX Refueling Requested", 3)
					end
				else
					local paxeFromOffset = ipc.readSW(0x66D2)
					if (paxeFromOffset > 1) then GSXboardedPax = paxeFromOffset end
					if (GSXcatering==1) then
						GSXoperation = "C"
						if (logging == 1) then ipc.log("pero | JeeHellExtPWRbyGSX: GSX Catering Requested") end
					else
						GSXoperation = "B"
						if (logging == 1) then ipc.log("pero | JeeHellExtPWRbyGSX: GSX Boarding Requested") end
					end
				end
				timeCallBoardingDeboarding = eTime
				if (GSXoperation~="") then ipc.keypressplus(GSXdialogKeyCode, GSXdialogKeyShift, 4) end
			elseif (alreadyAirborne==1 and deboardingDone==0 and DEBOARDING_STATE==1 and GSXhandling==1) then
				ipc.setbitsUW(0x66D1, 2)
				blockedSet = 1
				setPax()
				GSXoperation = "D"
				timeCallBoardingDeboarding = eTime
				ipc.keypressplus(GSXdialogKeyCode, GSXdialogKeyShift, 4)
				if (logging == 1) then ipc.log("pero | JeeHellExtPWRbyGSX: GSX Deboarding Requested") end
				if (showStatusMessages == 1) then ipc.Display("pero | JeeHellExtPWRbyGSX: GSX Deboarding Requested", 3) end
			end
		end

		-- Operate Jetway
		if (eTime > timeCallJetway + GSXautomationCounterSetting and timeCallJetway~=0 and jetwayDone==0 and boardingDone==0 and deboardingDone==0 and GSXautomationActive==0 and BOARDING_STATE==1) then -- and logic.And(ipc.readUW(0x739A), 1) ~= 0) then
			if (alreadyAirborne==0) then
				ipc.writeUB(0x78ED,35)  -- Stow RAT
				ipc.writeUW(0x78EE, 23) -- Taxi Light Off
			end
			ipc.sleep(2000)
			GSXoperation = "J"
			ipc.keypressplus(GSXdialogKeyCode, GSXdialogKeyShift, 4)
			if (logging == 1) then ipc.log("pero | JeeHellExtPWRbyGSX: GSX Jetway Requested") end
			if (showStatusMessages == 1) then ipc.Display("pero | JeeHellExtPWRbyGSX: GSX Jetway Requested", 3) end
			jetwayDone = 1
		end
		
		-- Start other Services
		local timeAddCatering = 5000
		local timeAddBoarding = 8000
		if (DEBOARDING_STATE >= 5) then
			timeAddCatering = 3000
			timeAddBoarding = 6000
		end
		
		timeWaitBeforeAction = timeAddBoarding + timeAddCatering + 2000
		
		if (timeCallBoardingDeboarding~=0 and alreadyAirborne==0 and (BOARDING_STATE>=4 or REFUELING_STATE>=4 or CATERING_STATE>=4)) then
			if (eTime > timeCallBoardingDeboarding + timeAddCatering and GSXcatering==1 and GSXfueling==1 and BOARDING_STATE==1 and cateringRequestedByMenu==0) then
				GSXoperation = "C"
				ipc.keypressplus(GSXdialogKeyCode, GSXdialogKeyShift, 4)
				if (logging == 1) then ipc.log("pero | JeeHellExtPWRbyGSX: GSX Catering Requested") end
				if (showStatusMessages == 1) then ipc.Display("pero | JeeHellExtPWRbyGSX: GSX Catering Requested", 3) end
				cateringRequestedByMenu=1
			end
			if (eTime > timeCallBoardingDeboarding + timeAddBoarding and (GSXfueling==1 or GSXcatering==1) and boardingRequestedByMenu==0) then
				if ((GSXfuelingMode~=1 and (GSXcatering==1 or GSXfueling==1)) or (GSXfuelingMode==1 and GSXcatering==1 and GSXfueling==0)) then
					setPax()
					GSXoperation = "B"
					if (logging == 1) then ipc.log("pero | JeeHellExtPWRbyGSX: GSX Boarding Requested") end
					ipc.keypressplus(GSXdialogKeyCode, GSXdialogKeyShift, 4)
				end
				if (GSXautomationActive==1 and GSXfuelingMode==1 and GSXfueling==1) then
					GSXoperation = "J"
					ipc.keypressplus(GSXdialogKeyCode, GSXdialogKeyShift, 4)
					if (logging == 1) then ipc.log("pero | JeeHellExtPWRbyGSX: GSX Jetway Requested") end
					if (showStatusMessages == 1) then ipc.Display("pero | JeeHellExtPWRbyGSX: GSX Jetway Requested", 3) end
				end
				boardingRequestedByMenu=1
			end
		end
		
		-- Open doors if timer > 60 seconds
		if (eTime > timeCallBoardingDeboarding + 60000 and boardingDeboardingStarted==0 and timeCallBoardingDeboarding~=0) then
			openDoorsForBoardingDeboarding()
			defaultJetwayStopToggle = 0
		end
	end

	-- Call Actions
	CabinSoundAction()
	GSXaction()
	logAll()
end

function GSXkeyPressed(offset, value)
	if (value~=0) then
		if (value >= 1 and value <= 9) then ipc.keypressplus(48+value) end
		if (value == 10) then ipc.keypressplus(48) end
		if (value == 11) then
			if (GSXmenuDoubleClickInUse==0) then
				ipc.keypressplus(GSXdialogKeyCode, GSXdialogKeyShift, 4)
			else
				if (GSXmenuDoubleClickLast == "") then
					GSXmenuDoubleClickLast = "GSX"
					GSXmenuDoubleClickLastTime = ipc.elapsedtime()
				else
					GSXmenuDoubleClickLast = "ATC"
				end
			end
		end
		ipc.writeUW(offset, 0)
		if (PNFsoundPlay==1 and onGround==1) then
			if (value >0 and value<4 and PNF_VspeedTimer == 0) then
				PNF_VspeedTimer = ipc.elapsedtime()
			end
			if (PNF_VspeedTimer ~=0) then
				if (value == 10) then value = 0 end
				PNF_VspeedPuffer = PNF_VspeedPuffer..value
				if (string.len(PNF_VspeedPuffer) == 4 and PNF_VspeedTimer ~= 0) then
					local V = string.sub(PNF_VspeedPuffer, 1,1)
					local Vspeed = string.sub(PNF_VspeedPuffer, 2)
					if (V == "1") then
						if (tonumber(Vspeed)<200 and tonumber(Vspeed)>100) then
							PNF_V1speed = tonumber(Vspeed)
							ipc.Display("Set V1 Speed = "..Vspeed.."\nV1="..PNF_V1speed..",VR="..PNF_VRspeed, 5)
						else
							ipc.Display("Error V1 Speed = "..Vspeed, 5)
						end
					end
					if (V == "2") then
						if (tonumber(Vspeed)<200 and tonumber(Vspeed)>100) then
							PNF_VRspeed = tonumber(Vspeed)
							ipc.Display("Set VR Speed = "..Vspeed.."\nV1="..PNF_V1speed..",VR="..PNF_VRspeed, 5)
						else
							ipc.Display("Error VR Speed = "..Vspeed, 5)
						end
					end
					PNF_VspeedPuffer = ""
					PNF_VspeedTimer = 0
				end
			end
		end
	end
end

function engineFire(offset, value)
	-- Toggles Fire Offset for JeeHell with Fire Offsets of Sim
	if (logic.And(value,16) ~= 0) then
		if (engineLeftRunning==1) then ipc.setbitsUW(0x3366, 1) end
	else
		ipc.clearbitsUW(0x3366, 1)
	end
	if (logic.And(value,32) ~= 0) then 
		if (engineRightRunning==1) then ipc.setbitsUW(0x3366, 2) end
	else
		ipc.clearbitsUW(0x3366, 2)
	end
end

function icingMessage(offset, value)
	icingCurrentValue = value
	-- ipc.Display("Active Sky Icing: Value change from < "..icingLastValue.." > to < "..icingCurrentValue.." >", 10)
	
	-- StructIcing Message
	if (icingLastValue ~= icingCurrentValue and icingStartWarningValue > 0) then
		if (logging == 1) then ipc.log("Active Sky Icing: Value change from < "..icingLastValue.." > to < "..icingCurrentValue.." >") end
		icingLastValue = icingCurrentValue
		if (icingLastValue >= icingStartWarningValue) then
			-- if (onGround==0 and logic.And(ipc.readUB(0x66D1), 512) == 0) then 
			if (onGround==0) then 
				if (icingSetTimeLastChange==0) then icingSetTimeLastChange = ipc.elapsedtime() end	
				ipc.setbitsUW(0x66D1, 512) 
				if (logging == 1) then ipc.log("Icing Indicator On (because Ice Detected)") end
			end
		end
	end
end		

function signStatusChanges(offset, value)
	if (logic.And(value, 8) == 0) then
		seatBealtSign = 0
	else
		seatBealtSign = 1
	end
	if (logic.And(value, 16) == 0) then
		noSmokingSign = 0
	else
		noSmokingSign = 1
	end
	-- ipc.Display(seatBealtSign.."|"..noSmokingSign.."|"..value)	
end	

--------------------------------------------------------------------------------------------------------
---------------------------------------------------------------- General
--------------------------------------------------------------------------------------------------------

function round(value, dP)
	if (dP and dP >0) then
		local mult = 10^dP
		return math.floor(value * mult + 0.5) / mult
	end
	return math.floor(value + 0.5)
end

function getDate(value)
	nowTable = os.date('*t')
	return fillWithZero(nowTable.day).."."..fillWithZero(nowTable.month).."."..nowTable.year
end

function getTime(value)
	nowTable = os.date('*t')
	return fillWithZero(nowTable.hour)..":"..fillWithZero(nowTable.min)..":"..fillWithZero(nowTable.sec)
end

function getSimTimeDate()
	return fillWithZero(ipc.readUB(0x0238))..":"..fillWithZero(ipc.readUB(0x0239))..":"..fillWithZero(ipc.readUB(0x023A)).." "..fillWithZero(ipc.readUB(0x0245)).."."..fillWithZero(ipc.readUB(0x0244)).."."..fillWithZero(ipc.readUW(0x024A))
end

function fillWithZero(input)
	if (string.len(input) == 1) then
		return "0"..input
	end
	return input
end

function logAll()
	if (logging == 1) then
		local logResultNew =         "------ GSX ENVIRONMENT\n"
		logResultNew = logResultNew.."DEBOARDING_STATE:     "..DEBOARDING_STATE.."\n"
		logResultNew = logResultNew.."BOARDING_STATE:       "..BOARDING_STATE.."\n"
		logResultNew = logResultNew.."DEPARTURE_STATE:      "..DEPARTURE_STATE.."\n"
		logResultNew = logResultNew.."CATERING_STATE:       "..CATERING_STATE.."\n"
		logResultNew = logResultNew.."REFUELING_STATE:      "..REFUELING_STATE.."\n"
		logResultNew = logResultNew.."JETWAY_STATE:         "..JETWAY_STATE.."\n"
		logResultNew = logResultNew.."External Power:       "..extPWR.."\n"
		logResultNew = logResultNew.."Boarded Pax:          "..GSXboardedPax.."\n"
		logResultNew = logResultNew.."Refueling Mode:       "..GSXfuelingMode.."\n"
		logResultNew = logResultNew.."------ AIRCRAFT STATE\n"
		logResultNew = logResultNew.."On Ground:            "..onGround.."\n"
		logResultNew = logResultNew.."Was already Airborne: "..alreadyAirborne.."\n"
		logResultNew = logResultNew.."Parking Brake:        "..parkBrakeSet.."\n"
		logResultNew = logResultNew.."Engine Left Running:  "..engineLeftRunning.."\n"
		logResultNew = logResultNew.."Engine Right Running: "..engineRightRunning.."\n"
		logResultNew = logResultNew.."Departure Altitude:   "..departureAlt.."\n"
		logResultNew = logResultNew.."------ CABIN SOUND STATE\n"
		logResultNew = logResultNew.."Sound:                "..CabinSoundPlay.."\n"
		logResultNew = logResultNew.."Welcome:              "..CabinSoundWelcome.."\n"
		logResultNew = logResultNew.."Safety:               "..CabinSoundSafety.."\n"
		logResultNew = logResultNew.."Climb:                "..CabinSoundClimb.."\n"
		logResultNew = logResultNew.."Cruise:               "..CabinSoundCruise.."\n"
		logResultNew = logResultNew.."Descent:              "..CabinSoundDescent.."\n"
		logResultNew = logResultNew.."Final Approach:       "..CabinSoundFinal.."\n"
		logResultNew = logResultNew.."After Landing:        "..CabinSoundAfterLand.."\n"
		logResultNew = logResultNew.."At Gate:              "..CabinSoundAtGate.."\n"
		logResultNew = logResultNew.."Unboarding:           "..CabinSoundUnboarding.."\n"
		logResultNew = logResultNew.."------ CPDPL Integration\n"
		logResultNew = logResultNew.."GSX Automation:       "..GSXautomationActive.."\n\n"
		if (logResult ~= logResultNew) then 
			ipc.log("Time: "..getTime().."\n\n"..logResultNew)
			logResult = logResultNew
		end
	end
end

-- Event Trigger
event.textmenu(2, "TextMenuOpened")

event.offset(0x0366, "UW", "groundStateChanged")
event.offset(0x0BC8, "UW", "parkingBrakeChanged")
event.offset(0x0894, "UW", "engineLeftRunChanged")
event.offset(0x092C, "UW", "engineRightRunChanged")
event.offset(0x0842, "SW", "verticalSpeedChanged")
event.offset(0x0D0C, "UW", "extLightsChanged")
event.offset(0x02BC, "UD", "IASchanged")
event.offset(0x66D1, "UW", "triggerGSXboardingDeboarding")
event.offset(0x66D3, "UW", "GSXkeyPressed")
event.offset(0x32FC, "UW", "checkReload")
event.offset(0x73A4, "UW", "engineFire")
event.offset(0x8601, "UW", "icingMessage")
event.offset(0x73B3, "UB", "signStatusChanges")


event.Lvar("FSDT_GSX_DEBOARDING_STATE", pollInterval, "GSX_DEBOARDING_STATE")
event.Lvar("FSDT_GSX_BOARDING_STATE", pollInterval, "GSX_BOARDING_STATE")
event.Lvar("FSDT_GSX_DEPARTURE_STATE", pollInterval, "GSX_DEPARTURE_STATE")
event.Lvar("FSDT_GSX_CATERING_STATE", pollInterval, "GSX_CATERING_STATE")
event.Lvar("FSDT_GSX_REFUELING_STATE", pollInterval, "GSX_REFUELING_STATE")
event.Lvar("FSDT_GSX_JETWAY_POWER", pollInterval, "GSXv2_JETWAY_POWER_STATE")

event.key(GSXdialogKeyCode, GSXdialogKeyShift, "GSXdialogKeyPress")
event.key(CabinSoundDialogKeyCode, CabinSoundDialogKeyShift, "CabinSoundsToggle")
event.key(PNFSoundDialogKeyCode, PNFSoundDialogKeyShift, "PNFSoundsToggle")

event.timer(pollInterval, "TimerChanges")
setCabinSoundPack()

-- Pax Random
if (GSXv2_randomPaxActive==1 or GSXautomationActive==0) then
	math.random(GSXv2_MinPax, GSXv2_MaxPax)
	setPax()
end

-- Show starting information
local ac_ATCmodel = tostring(ipc.readSTR(0x3500,4))
if (ac_ATCmodel == "A332") then
	A330 = 1
else
	A330 = 0
end

for e=1,table.getn(ac_allowedATCmodels) do
	-- ipc.log(string.len(ac_allowedATCmodels[e]))
	-- ipc.log(string.len(ac_ATCmodel))
	-- ipc.log(ac_allowedATCmodels[e]..ac_ATCmodel)
	if (tostring(ac_ATCmodel) == tostring(ac_allowedATCmodels[e])) then
		-- ipc.log("gefunden")
		runScript = 1
	end
end

local infoText = "pero | JeeHellExtPWRbyGSX: Running"
if (A330==1) then infoText = infoText .. " in A330 Mode" end
if (runScript==0) then infoText = "pero | JeeHellExtPWRbyGSX: Not running because 'atc_model' mismatch" end
ipc.Display(infoText.."...", 5)

if (logging == 1) then
	ipc.log("pero | JeeHellExtPWRbyGSX: Running...")
	ipc.log("-------------------------------")
	ipc.log("      GENERAL SETTINGS")
	ipc.log("-------------------------------")
	ipc.log("Show Status Messages:     "..showStatusMessages)
	ipc.log("Door handling:            "..doorHandling)
	ipc.log("Wait until EXT PWR Conn:  "..waitUntilExtPWRconnect)
	ipc.log("Poll Interval:            "..pollInterval)
	ipc.log("GSX Handling:             "..GSXhandling)
	ipc.log("GSXcatering:              "..GSXcatering)
	ipc.log("GSXdialogKeyShift:        "..GSXdialogKeyShift)
	ipc.log("GSXdialogKeyCode:         "..GSXdialogKeyCode)
	ipc.log("Cabin Announcement:       "..CabinSoundPlay)
	ipc.log("-------------------------------")
end

timeScriptLoaded = ipc.elapsedtime()
logAll()

 

Posted (edited)

I have the same problem with 6.09. But I can't go back to 6.08, because I dont have 6.08 anymore.

Best regards, Thorsten

Edited by Mallinoi
Mistake
Posted

I can't imagine what could possibly have changed between 6.08 and 6.09 which could affect this action.  Maybe John will take a look, as it is his program now and his changes, but I will try to understand.

Thanks for the log and the plug-in, but it is far too complex for me to see what is going on. In fact I can't even see where in your code you are doing what. And although your Lua does a lot of logging of its own, you didn't activate the Lua trace logging option.

So, I need it narrowing down for me please. First can you isolate the lines where the GSX menu is activated, and then the lines where the action is selected. Do this in both the log and in the Lua. Then, in order to analyse what is happening under debugging conditions, I might be able to construct something smaller and simpler to invoke the problem.

I won't have time till tomorrow (Monday) at least, so there's no rush.

Pete

 

Posted

Hi Pete, hi John,

thanks for helping out. I deactivated all "ipc.event" function calls in my script but this doesn't changed it. Even no error reported in the FSUIPC6.log file. What I found out that pressing a key (0-9) in the GSX menu the selected item becomes kind of "selected" but does not "press". If I would press key 1-9 they all would become "light gray background" but no action. The only way I can trigger them is by clicking with the mouse.

See attached pics.

Regards,
Peter

Before Keypress:

beforeKeypress.jpg

After Keypress:

afterKeyPressed.jpg

Posted
4 hours ago, Capt. PERO said:

What I found out that pressing a key (0-9) in the GSX menu the selected item becomes kind of "selected" but does not "press". If I would press key 1-9 they all would become "light gray background" but no action. The only way I can trigger them is by clicking with the mouse.

So it isn't anything to do with FSUIPC, but some problem with the P3D SimConnect menu system?

BTW the two pictures appear identical to me. You must be seeing something very subtle which doesn't show up here.

Have you tried programming the Lua to send the SimConnect Menu controls instead of using keypresses?  I think they were supposed to be fixed in P3D5 HF2 (though I'm not sure about that).

Pete

 

Posted
On 7/12/2020 at 4:33 AM, Capt. PERO said:

after digging deeper in it the problem has to be redescribed:

  • When using 6.0.9 the GSX Menu opens (which is triggered by LUA and a STRG+SHIFT+W "ipc.keypressplus" operation). So it looks like sending keypress with lua is working in general. But when the GSX menu opens I cannot press an option (0-9) nothing happens. Not with my script and not by keyboard - strange.
  • when I uncomment my script to .lua.off (to avoid loading it) I CAN press the GSX options (0-9) with keyboard again So something with my script and the change from 6.0.8 to 6.0.9.

Okay, after constructing a facility to create a menu that I can select from (I don't have anything installed on my Development Pc which creates SimConnect menus), I have finally seen the the problem, and can reproduce it every time.

ipc.keypressplus appears to be changing the keyboard focus away from P3D (not sure where to yet), and it seems impossible to bring it back using mouse clicks on the P3D window. Weird.

I'll investigate what changed here between 6.0.8 and 6.0.9.

Pete

 

  • Thanks 1
Posted
19 hours ago, Pete Dowson said:

Okay, after constructing a facility to create a menu that I can select from (I don't have anything installed on my Development Pc which creates SimConnect menus), I have finally seen the the problem, and can reproduce it every time.

Oddly, today, with nothing in FSUIPC changed, I cannot reproduce any problems at all.

I've been testing on my cockpit PC with the GSX menu, and both ipc.keypress and ipc.keypressplus work well to make selections there. i also tested using ipc.control to send the SimConnect_Menu controls, and they also work. These are:

SIMCONNECT MENU 1                      67136 
SIMCONNECT MENU 2                      67137 
SIMCONNECT MENU 3                      67138 
SIMCONNECT MENU 4                      67139 
SIMCONNECT MENU 5                      67140 
SIMCONNECT MENU 6                      67141 
SIMCONNECT MENU 7                      67142 
SIMCONNECT MENU 8                      67143 
SIMCONNECT MENU 9                      67144 
SIMCONNECT MENU 0                      67145 

What caused the problem for me yesterday, and what is causing it for you, I really have no idea. i have looked carefully at all the changes between 6.0.8 and 6.0.9 and I can see nothing which affects any part of these actions.

So, this is very worrying. What I would like to do is reproduce it using your code and settings, but it looks far too complex. Can you produce a slimline version, just the bare minimum which will still reproduce the problem for you? Please?

Pete

 

Posted

Hi Pete,

I think I nailed it:

local PNFSoundDialogKeyShift = 1
local PNFSoundDialogKeyCode = 88

function PNFSoundsToggle()
	--if (PNFsoundPlay==0) then
	--	PNFsoundPlay=1
	--	if (ipc.elapsedtime() > timeScriptLoaded + 5000) then ipc.Display("pero | JeeHellExtPWRbyGSX: Pilot none flying announcements -- ON", 3) end
	--else
	--	PNFsoundPlay=0
	--	if (ipc.elapsedtime() > timeScriptLoaded + 5000) then ipc.Display("pero | JeeHellExtPWRbyGSX: Pilot none flying announcements -- OFF", 3) end
	--end
end

event.key(PNFSoundDialogKeyCode, PNFSoundDialogKeyShift, "PNFSoundsToggle")

Looks like "event.key" causes the issue.

Posted
15 minutes ago, Capt. PERO said:

Looks like "event.key" causes the issue.

How is this script related to menus and ipc.keypressplus. are you saying that if this script runs whilst a GSX menu is displayed, then you get the key press problems?

Pete

 

Posted
1 minute ago, Pete Dowson said:

How is this script related to menus and ipc.keypressplus. are you saying that if this script runs whilst a GSX menu is displayed, then you get the key press problems?

Pete

Right. It has nothing to do with ipc.keypress but using this LUA causes the problem. Strange...

Posted
2 minutes ago, Capt. PERO said:

Right. It has nothing to do with ipc.keypress but using this LUA causes the problem. Strange...

There was a new facility added regarding detecting key presses in Lua -- the parameter  LuaTrapKeyEvent to stop trappped keypresses also passing through to P3D. Maybe it's something about that change. Good clue.

So i can test here with that script, getting a menu displayed, then pressing Shift X? If that's all i need i'll test now ...

Pete

 

Posted

Right:

1) ipcReady.lua calls "ipc.macro("Lua peroJeeHellExtPWRbyGSX")"

2) peroJeeHellExtPWRbyGSX.lua contains the code above

3) Start the sim (runs ipcReady.lua and peroJeeHellExtPWRbyGSX.lua

4) Open the GSX menu (SHIFT+CTRL+W) and try to press "1" on keyboard

5) Does not work

Posted
1 minute ago, Capt. PERO said:

1) ipcReady.lua calls "ipc.macro("Lua peroJeeHellExtPWRbyGSX")"

Why ipc.macro?  Why not simply ipc.runlua?

Anyway, I'll go ahead and try that now. Thanks!

Pete

 

Posted
2 minutes ago, Pete Dowson said:

Why ipc.macro?  Why not simply ipc.runlua?

[...]

That you can find something on my side for improvement. 😉 *lol*

...I will change that

  • 3 months later...
Posted

@Mallinoi Did you try adding
    LuaTrapKeyEvent=No
To the [General] section of your FSUIPC6.ini in v6.0.10?

This will revert v6.0.10 to the previous behavior (6.0.8)  where keys acted on in lua are also forwarded to the FS.
In v6.0.9 and later, keys handled in lua are masked and not seen by the FS.

John

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.