diff --git a/.gitignore b/.gitignore index 5525477..64bcb0b 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,6 @@ PackageSources/wasm-module/.vs PackageSources/wasm-module/MSFS PackageSources/wasm-module/x64 -*.blend1 \ No newline at end of file +*.blend1 + +PackageSources/SimObjects/Airplanes/**/panel/*.wasm \ No newline at end of file diff --git a/PackageDefinitions/xkhofmann-tfdidesign-md11-load-manager.xml b/PackageDefinitions/xkhofmann-tfdidesign-md11-load-manager.xml index e534452..62d19eb 100644 --- a/PackageDefinitions/xkhofmann-tfdidesign-md11-load-manager.xml +++ b/PackageDefinitions/xkhofmann-tfdidesign-md11-load-manager.xml @@ -35,17 +35,6 @@ PackageSources\load-manager-panel\ InGamePanels\ - - Copy - - false - - PackageSources\wasm-module\MSFS\Debug\ - SimObjects\Airplanes\TFDi_Design_MD-11_PW\panel\ - - *.wasm - - Copy diff --git a/PackageSources/SimObjects/Airplanes/TFDi_Design_MD-11F_GE/panel/PANEL.CFG b/PackageSources/SimObjects/Airplanes/TFDi_Design_MD-11F_GE/panel/PANEL.CFG index 5b0a99f..5c8333b 100644 --- a/PackageSources/SimObjects/Airplanes/TFDi_Design_MD-11F_GE/panel/PANEL.CFG +++ b/PackageSources/SimObjects/Airplanes/TFDi_Design_MD-11F_GE/panel/PANEL.CFG @@ -18,6 +18,8 @@ htmlgauge07=WasmInstrument/WasmInstrument.html?wasm_module=md11host.wasm&wasm_ga htmlgauge08=WasmInstrument/WasmInstrument.html?wasm_module=md11host.wasm&wasm_gauge=RMCDU,0,1386,334,288 htmlgauge09=WasmInstrument/WasmInstrument.html?wasm_module=md11host.wasm&wasm_gauge=CMCDU,0,1728,333,285 htmlgauge10=WasmInstrument/WasmInstrument.html?wasm_module=md11host.wasm&wasm_gauge=ISFD,1032,519,544,505 +//KH new gauge +htmlgauge11=WasmInstrument/WasmInstrument.html?wasm_module=load-manager.wasm&wasm_gauge=Load_Manager,0,0,509,510 [VIEWS] VIEW_FORWARD_DIR=2.000, 0.000, 0.000 diff --git a/PackageSources/SimObjects/Airplanes/TFDi_Design_MD-11F_PW/panel/PANEL.CFG b/PackageSources/SimObjects/Airplanes/TFDi_Design_MD-11F_PW/panel/PANEL.CFG index 52c0a24..1e6a804 100644 --- a/PackageSources/SimObjects/Airplanes/TFDi_Design_MD-11F_PW/panel/PANEL.CFG +++ b/PackageSources/SimObjects/Airplanes/TFDi_Design_MD-11F_PW/panel/PANEL.CFG @@ -18,6 +18,8 @@ htmlgauge07=WasmInstrument/WasmInstrument.html?wasm_module=md11host.wasm&wasm_ga htmlgauge08=WasmInstrument/WasmInstrument.html?wasm_module=md11host.wasm&wasm_gauge=RMCDU,0,1386,334,288 htmlgauge09=WasmInstrument/WasmInstrument.html?wasm_module=md11host.wasm&wasm_gauge=CMCDU,0,1728,333,285 htmlgauge10=WasmInstrument/WasmInstrument.html?wasm_module=md11host.wasm&wasm_gauge=ISFD,1032,519,544,505 +//KH new gauge +htmlgauge11=WasmInstrument/WasmInstrument.html?wasm_module=load-manager.wasm&wasm_gauge=Load_Manager,0,0,509,510 [VIEWS] VIEW_FORWARD_DIR=2.000, 0.000, 0.000 diff --git a/PackageSources/SimObjects/Airplanes/TFDi_Design_MD-11_GE/panel/PANEL.CFG b/PackageSources/SimObjects/Airplanes/TFDi_Design_MD-11_GE/panel/PANEL.CFG index 5b0a99f..5c8333b 100644 --- a/PackageSources/SimObjects/Airplanes/TFDi_Design_MD-11_GE/panel/PANEL.CFG +++ b/PackageSources/SimObjects/Airplanes/TFDi_Design_MD-11_GE/panel/PANEL.CFG @@ -18,6 +18,8 @@ htmlgauge07=WasmInstrument/WasmInstrument.html?wasm_module=md11host.wasm&wasm_ga htmlgauge08=WasmInstrument/WasmInstrument.html?wasm_module=md11host.wasm&wasm_gauge=RMCDU,0,1386,334,288 htmlgauge09=WasmInstrument/WasmInstrument.html?wasm_module=md11host.wasm&wasm_gauge=CMCDU,0,1728,333,285 htmlgauge10=WasmInstrument/WasmInstrument.html?wasm_module=md11host.wasm&wasm_gauge=ISFD,1032,519,544,505 +//KH new gauge +htmlgauge11=WasmInstrument/WasmInstrument.html?wasm_module=load-manager.wasm&wasm_gauge=Load_Manager,0,0,509,510 [VIEWS] VIEW_FORWARD_DIR=2.000, 0.000, 0.000 diff --git a/PackageSources/js-bundle/package.json b/PackageSources/js-bundle/package.json index 60c2bcc..c1081ee 100644 --- a/PackageSources/js-bundle/package.json +++ b/PackageSources/js-bundle/package.json @@ -1,6 +1,6 @@ { "name": "tfdidesign-md11-load-manager", - "version": "0.1.17", + "version": "0.1.21", "description": "", "main": "index.js", "type": "module", @@ -13,7 +13,9 @@ "dev": "npx rollup -c -w", "clean": "rimraf ../html_ui/InGamePanels/tfdidesign-md11-load-manager-panel/ && rimraf .rollup.cache", "build": "npm version patch && npx rollup -c", - "release": "pnpm types && pnpm lint && pnpm run licenses && pnpm clean && npm version patch && cross-env NODE_ENV=production npx rollup -c" + "build-efb": "npm version patch && cross-env SPLIT=true npx rollup -c", + "release": "pnpm types && pnpm lint && pnpm run licenses && pnpm clean && npm version patch && cross-env NODE_ENV=production npx rollup -c", + "release-efb": "pnpm types && pnpm lint && pnpm run licenses && pnpm clean && npm version patch && cross-env NODE_ENV=production SPLIT=true npx rollup -c" }, "engines": { "node": ">=22" diff --git a/PackageSources/js-bundle/rollup.config.js b/PackageSources/js-bundle/rollup.config.js index c9ab8ac..b9f13ab 100644 --- a/PackageSources/js-bundle/rollup.config.js +++ b/PackageSources/js-bundle/rollup.config.js @@ -27,6 +27,15 @@ export default { dir: panelDirBase, format: 'es', sourcemap: targetEnv !== 'production', + manualChunks: process.env.SPLIT + ? (id) => { + if (id.includes('node_modules')) { + return 'vendor'; + } + + return null; + } + : undefined, }, plugins: [ replace({ diff --git a/PackageSources/js-bundle/src/App.tsx b/PackageSources/js-bundle/src/App.tsx index fd72d3a..3f5bff0 100644 --- a/PackageSources/js-bundle/src/App.tsx +++ b/PackageSources/js-bundle/src/App.tsx @@ -1,4 +1,5 @@ import { FC, useCallback, useEffect, useState } from 'react'; +import Freighter from './components/freighter/Freighter'; import Pax from './components/pax/Pax'; import { COHERENT_COMM_BUS_WASM_CALL, @@ -6,7 +7,7 @@ import { TFDI_SIMBRIEF_USERNAME_CALL, TFDI_SIMBRIEF_USERNAME_EVENT, } from './constants'; -import { WASMDataPax } from './types/WASMData'; +import { WASMDataF, WASMDataPax } from './types/WASMData'; interface IAppProps { commBus: ViewListener.ViewListener; @@ -14,7 +15,7 @@ interface IAppProps { const App: FC = ({ commBus }) => { const [SBUsername, setSBUsername] = useState(); - const [WASMData, setWASMData] = useState(); + const [WASMData, setWASMData] = useState(); const [isReady, setIsReady] = useState(false); // CommBus @@ -46,9 +47,9 @@ const App: FC = ({ commBus }) => {
{isReady && WASMData ? ( WASMData.userData.isCargo ? ( - <>Not yet Implemented + ) : ( - + ) ) : (

LOADING

diff --git a/PackageSources/js-bundle/src/assets/licenses_node.md b/PackageSources/js-bundle/src/assets/licenses_node.md index be7b708..28a9816 100644 --- a/PackageSources/js-bundle/src/assets/licenses_node.md +++ b/PackageSources/js-bundle/src/assets/licenses_node.md @@ -1,44 +1,40 @@ | Department | Related to | Name | License period | Material not material | License type | Link | Remote version | Installed version | Defined version | Author | | :--------- | :--------- | :------------------------------- | :------------- | :-------------------- | :----------- | :------------------------------------------------------------------------ | :------------- | :---------------- | :-------------- | :---------------------------------------------------------- | -| kessler | stuff | @emotion/react | perpetual | material | MIT | git+https://github.com/emotion-js/emotion.git#main | 11.14.0 | 11.14.0 | ^11.11.1 | Emotion Contributors | -| kessler | stuff | @emotion/styled | perpetual | material | MIT | git+https://github.com/emotion-js/emotion.git#main | 11.14.0 | 11.14.0 | ^11.11.0 | n/a | -| kessler | stuff | @mui/icons-material | perpetual | material | MIT | git+https://github.com/mui/material-ui.git | 5.17.1 | 5.17.1 | ^5.14.16 | MUI Team | -| kessler | stuff | @mui/material | perpetual | material | MIT | git+https://github.com/mui/material-ui.git | 5.17.1 | 5.17.1 | ^5.14.17 | MUI Team | -| kessler | stuff | postcss-import | perpetual | material | MIT | git+https://github.com/postcss/postcss-import.git | 15.1.0 | 15.1.0 | ^15.1.0 | Maxime Thirouin | -| kessler | stuff | react | perpetual | material | MIT | git+https://github.com/facebook/react.git | 18.3.1 | 18.3.1 | ^18.2.0 | n/a | -| kessler | stuff | react-dom | perpetual | material | MIT | git+https://github.com/facebook/react.git | 18.3.1 | 18.3.1 | ^18.2.0 | n/a | -| kessler | stuff | uuid | perpetual | material | MIT | git+https://github.com/uuidjs/uuid.git | 9.0.1 | 9.0.1 | ^9.0.1 | n/a | +| kessler | stuff | react | perpetual | material | MIT | git+https://github.com/facebook/react.git | 19.1.0 | 19.1.0 | ^19.1.0 | n/a | +| kessler | stuff | react-dom | perpetual | material | MIT | git+https://github.com/facebook/react.git | 19.1.0 | 19.1.0 | ^19.1.0 | n/a | +| kessler | stuff | uuid | perpetual | material | MIT | git+https://github.com/uuidjs/uuid.git | 11.1.0 | 11.1.0 | ^11.1.0 | n/a | | kessler | stuff | @microsoft/msfs-types | perpetual | material | MIT | git+https://github.com/microsoft/msfs-avionics-mirror.git | 1.14.6 | 1.14.6 | ^1.14.6 | Asobo Studio / Working Title Simulations | -| kessler | stuff | @rollup/plugin-commonjs | perpetual | material | MIT | git+https://github.com/rollup/plugins.git | 25.0.8 | 25.0.8 | ^25.0.0 | Rich Harris | -| kessler | stuff | @rollup/plugin-json | perpetual | material | MIT | git+https://github.com/rollup/plugins.git | 6.1.0 | 6.1.0 | ^6.0.0 | rollup | -| kessler | stuff | @rollup/plugin-node-resolve | perpetual | material | MIT | git+https://github.com/rollup/plugins.git | 15.3.1 | 15.3.1 | ^15.1.0 | Rich Harris | +| kessler | stuff | @rollup/plugin-commonjs | perpetual | material | MIT | git+https://github.com/rollup/plugins.git | 28.0.5 | 28.0.3 | ^28.0.3 | Rich Harris | +| kessler | stuff | @rollup/plugin-json | perpetual | material | MIT | git+https://github.com/rollup/plugins.git | 6.1.0 | 6.1.0 | ^6.1.0 | rollup | +| kessler | stuff | @rollup/plugin-node-resolve | perpetual | material | MIT | git+https://github.com/rollup/plugins.git | 16.0.1 | 16.0.1 | ^16.0.1 | Rich Harris | | kessler | stuff | @rollup/plugin-replace | perpetual | material | MIT | git+https://github.com/rollup/plugins.git | 6.0.2 | 6.0.2 | ^6.0.2 | Rich Harris | -| kessler | stuff | @rollup/plugin-terser | perpetual | material | MIT | git+https://github.com/rollup/plugins.git | 0.4.4 | 0.4.4 | ^0.4.3 | Peter Placzek | -| kessler | stuff | @rollup/plugin-typescript | perpetual | material | MIT | git+https://github.com/rollup/plugins.git | 11.1.6 | 11.1.6 | ^11.1.1 | Oskar Segersvärd | -| kessler | stuff | @types/react | perpetual | material | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped.git | 18.3.23 | 18.3.23 | ^18.2.8 | n/a | -| kessler | stuff | @types/react-dom | perpetual | material | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped.git | 18.3.7 | 18.3.7 | ^18.2.4 | n/a | -| kessler | stuff | @types/uuid | perpetual | material | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped.git | 9.0.8 | 9.0.8 | ^9.0.7 | n/a | -| kessler | stuff | @typescript-eslint/eslint-plugin | perpetual | material | MIT | git+https://github.com/typescript-eslint/typescript-eslint.git | 6.21.0 | 6.21.0 | ^6.10.0 | n/a | -| kessler | stuff | @typescript-eslint/parser | perpetual | material | BSD-2-Clause | git+https://github.com/typescript-eslint/typescript-eslint.git | 6.21.0 | 6.21.0 | ^6.10.0 | n/a | -| kessler | stuff | autoprefixer | perpetual | material | MIT | git+https://github.com/postcss/autoprefixer.git | 10.4.21 | 10.4.21 | ^10.4.14 | Andrey Sitnik | +| kessler | stuff | @rollup/plugin-terser | perpetual | material | MIT | git+https://github.com/rollup/plugins.git | 0.4.4 | 0.4.4 | ^0.4.4 | Peter Placzek | +| kessler | stuff | @rollup/plugin-typescript | perpetual | material | MIT | git+https://github.com/rollup/plugins.git | 12.1.2 | 12.1.2 | ^12.1.2 | Oskar Segersvärd | +| kessler | stuff | @types/react | perpetual | material | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped.git | 19.1.8 | 19.1.6 | ^19.1.6 | n/a | +| kessler | stuff | @types/react-dom | perpetual | material | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped.git | 19.1.6 | 19.1.6 | ^19.1.6 | n/a | +| kessler | stuff | @types/uuid | perpetual | material | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped.git | 10.0.0 | 10.0.0 | ^10.0.0 | n/a | +| kessler | stuff | @typescript-eslint/eslint-plugin | perpetual | material | MIT | git+https://github.com/typescript-eslint/typescript-eslint.git | 6.21.0 | 6.21.0 | ^6.21.0 | n/a | +| kessler | stuff | @typescript-eslint/parser | perpetual | material | BSD-2-Clause | git+https://github.com/typescript-eslint/typescript-eslint.git | 6.21.0 | 6.21.0 | ^6.21.0 | n/a | +| kessler | stuff | autoprefixer | perpetual | material | MIT | git+https://github.com/postcss/autoprefixer.git | 10.4.21 | 10.4.21 | ^10.4.21 | Andrey Sitnik | | kessler | stuff | cross-env | perpetual | material | MIT | git+https://github.com/kentcdodds/cross-env.git | 7.0.3 | 7.0.3 | ^7.0.3 | Kent C. Dodds (https://kentcdodds.com) | -| kessler | stuff | eslint | perpetual | material | MIT | git+https://github.com/eslint/eslint.git | 8.57.1 | 8.57.1 | ^8.42.0 | Nicholas C. Zakas | -| kessler | stuff | eslint-plugin-import | perpetual | material | MIT | git+https://github.com/import-js/eslint-plugin-import.git | 2.31.0 | 2.31.0 | ^2.27.5 | Ben Mosher | -| kessler | stuff | eslint-plugin-react | perpetual | material | MIT | git+https://github.com/jsx-eslint/eslint-plugin-react.git | 7.37.5 | 7.37.5 | ^7.32.2 | Yannick Croissant | -| kessler | stuff | eslint-plugin-react-hooks | perpetual | material | MIT | git+https://github.com/facebook/react.git | 4.6.2 | 4.6.2 | ^4.6.0 | n/a | -| kessler | stuff | license-report | perpetual | material | MIT | git+https://github.com/kessler/license-report.git | 6.7.2 | 6.7.2 | ^6.5.0 | Yaniv Kessler | -| kessler | stuff | postcss | perpetual | material | MIT | git+https://github.com/postcss/postcss.git | 8.5.4 | 8.5.4 | ^8.4.24 | Andrey Sitnik | -| kessler | stuff | prettier | perpetual | material | MIT | git+https://github.com/prettier/prettier.git | 3.5.3 | 3.5.3 | ^3.0.3 | James Long | -| kessler | stuff | prettier-plugin-organize-imports | perpetual | material | MIT | git+https://github.com/simonhaenisch/prettier-plugin-organize-imports.git | 3.2.4 | 3.2.4 | ^3.2.4 | Simon Haenisch (https://github.com/simonhaenisch) | -| kessler | stuff | rimraf | perpetual | material | ISC | git://github.com/isaacs/rimraf.git | 5.0.10 | 5.0.10 | ^5.0.1 | Isaac Z. Schlueter (http://blog.izs.me/) | -| kessler | stuff | rollup | perpetual | material | MIT | git+https://github.com/rollup/rollup.git | 4.41.1 | 4.41.1 | ^4.3.1 | Rich Harris | -| kessler | stuff | rollup-plugin-copy | perpetual | material | MIT | git+https://github.com/vladshcherbin/rollup-plugin-copy.git | 3.5.0 | 3.5.0 | ^3.4.0 | Vlad Shcherbin | +| kessler | stuff | eslint | perpetual | material | MIT | git+https://github.com/eslint/eslint.git | 8.57.1 | 8.57.1 | ^8.57.1 | Nicholas C. Zakas | +| kessler | stuff | eslint-plugin-import | perpetual | material | MIT | git+https://github.com/import-js/eslint-plugin-import.git | 2.31.0 | 2.31.0 | ^2.31.0 | Ben Mosher | +| kessler | stuff | eslint-plugin-react | perpetual | material | MIT | git+https://github.com/jsx-eslint/eslint-plugin-react.git | 7.37.5 | 7.37.5 | ^7.37.5 | Yannick Croissant | +| kessler | stuff | eslint-plugin-react-hooks | perpetual | material | MIT | git+https://github.com/facebook/react.git | 4.6.2 | 4.6.2 | ^4.6.2 | n/a | +| kessler | stuff | license-report | perpetual | material | MIT | git+https://github.com/kessler/license-report.git | 6.8.0 | 6.7.2 | ^6.7.2 | Yaniv Kessler | +| kessler | stuff | postcss | perpetual | material | MIT | git+https://github.com/postcss/postcss.git | 8.5.5 | 8.5.4 | ^8.5.4 | Andrey Sitnik | +| kessler | stuff | postcss-import | perpetual | material | MIT | git+https://github.com/postcss/postcss-import.git | 16.1.0 | 16.1.0 | ^16.1.0 | Maxime Thirouin | +| kessler | stuff | prettier | perpetual | material | MIT | git+https://github.com/prettier/prettier.git | 3.5.3 | 3.5.3 | ^3.5.3 | James Long | +| kessler | stuff | prettier-plugin-organize-imports | perpetual | material | MIT | git+https://github.com/simonhaenisch/prettier-plugin-organize-imports.git | 4.1.0 | 4.1.0 | ^4.1.0 | Simon Haenisch (https://github.com/simonhaenisch) | +| kessler | stuff | rimraf | perpetual | material | ISC | git://github.com/isaacs/rimraf.git | 6.0.1 | 6.0.1 | ^6.0.1 | Isaac Z. Schlueter (http://blog.izs.me/) | +| kessler | stuff | rollup | perpetual | material | MIT | git+https://github.com/rollup/rollup.git | 4.43.0 | 4.42.0 | ^4.42.0 | Rich Harris | +| kessler | stuff | rollup-plugin-copy | perpetual | material | MIT | git+https://github.com/vladshcherbin/rollup-plugin-copy.git | 3.5.0 | 3.5.0 | ^3.5.0 | Vlad Shcherbin | | kessler | stuff | rollup-plugin-postcss | perpetual | material | MIT | git+https://github.com/egoist/rollup-plugin-postcss.git | 4.0.2 | 4.0.2 | ^4.0.2 | EGOIST <0x142857@gmail.com> | | kessler | stuff | rollup-plugin-react-svg | perpetual | material | MIT | git+https://github.com/boopathi/react-svg-loader.git | 3.0.3 | 3.0.3 | ^3.0.3 | boopathi | | kessler | stuff | rollup-plugin-version-injector | perpetual | material | ISC | git+https://github.com/djhouseknecht/rollup-plugin-version-injector.git | 1.3.3 | 1.3.3 | ^1.3.3 | David Houseknecht | -| kessler | stuff | sass | perpetual | material | MIT | git+https://github.com/sass/dart-sass.git | 1.89.1 | 1.89.1 | ^1.89.1 | Natalie Weizenbaum nweiz@google.com https://github.com/nex3 | +| kessler | stuff | sass | perpetual | material | MIT | git+https://github.com/sass/dart-sass.git | 1.89.2 | 1.89.1 | ^1.89.1 | Natalie Weizenbaum nweiz@google.com https://github.com/nex3 | | kessler | stuff | svg-slim | perpetual | material | MIT | git+https://github.com/benboba/svg-slim.git | 2.0.5 | 2.0.5 | ^2.0.5 | Wang Feng | -| kessler | stuff | tslib | perpetual | material | 0BSD | git+https://github.com/Microsoft/tslib.git | 2.8.1 | 2.8.1 | ^2.5.3 | Microsoft Corp. | -| kessler | stuff | typed-scss-modules | perpetual | material | MIT | git+https://github.com/skovy/typed-scss-modules.git | 7.1.4 | 7.1.4 | ^7.1.0 | Spencer Miskoviak | -| kessler | stuff | typescript | perpetual | material | Apache-2.0 | git+https://github.com/Microsoft/TypeScript.git | 5.2.2 | 5.2.2 | 5.2.2 | Microsoft Corp. | +| kessler | stuff | tslib | perpetual | material | 0BSD | git+https://github.com/Microsoft/tslib.git | 2.8.1 | 2.8.1 | ^2.8.1 | Microsoft Corp. | +| kessler | stuff | typed-scss-modules | perpetual | material | MIT | git+https://github.com/skovy/typed-scss-modules.git | 8.1.1 | 8.1.1 | ^8.1.1 | Spencer Miskoviak | +| kessler | stuff | typescript | perpetual | material | Apache-2.0 | git+https://github.com/microsoft/TypeScript.git | 5.8.3 | 5.8.3 | 5.8.3 | Microsoft Corp. | diff --git a/PackageSources/js-bundle/src/components/SBEntry/SBEntryF.tsx b/PackageSources/js-bundle/src/components/SBEntry/SBEntryF.tsx new file mode 100644 index 0000000..c1ad670 --- /dev/null +++ b/PackageSources/js-bundle/src/components/SBEntry/SBEntryF.tsx @@ -0,0 +1,247 @@ +import { FC, useEffect, useRef, useState } from 'react'; +import { + COHERENT_COMM_BUS_WASM_CALL, + COMM_BUS_UPDATE_TARGET_EVENT, + GSX_SERVICE_CALLED, + GSX_SERVICE_FINISHED, +} from '../../constants'; +import { WASMDataF } from '../../types/WASMData'; +import { LoadingState } from '../../types/general'; +import { ImportFlightPlan } from '../../utils/TFDISBImport'; +import { inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils'; +import CGSelect from '../CGSelect/CGSelect'; +import ActionBar from '../actionbar/ActionBar'; + +interface SBEntryProps { + WASMData: WASMDataF; + loadingState: LoadingState; + username: string; + setLoadingState: (newState: LoadingState) => void; +} + +const SBEntryF: FC = ({ WASMData, loadingState, username, setLoadingState }) => { + const [CGTarget, setCGTarget] = useState(WASMData.targetPayload.CGTarget); + const [fuel, setFuel] = useState(Math.round(WASMData.livePayload.fuel)); + const [fuelEnabled, setFuelEnabled] = useState(true); + //eslint-disable-next-line @typescript-eslint/no-explicit-any + const [SBPlan, setSBPlan] = useState(); + const [SBInFlight, setSBInFlight] = useState(false); + + const cargo = useRef(0); + + const ZFW = () => { + if (loadingState !== 'loaded' && !GSXActive()) return Math.round(WASMData.targetPayload.total); + + return Math.round(WASMData.livePayload.total); + }; + const ZFWValid = () => { + return ZFW() <= WASMData.limits.maxZFW; + }; + const GW = () => { + return fuel + ZFW(); + }; + const GWValid = () => { + return GW() <= WASMData.limits.maxTOW; + }; + + const GSXActive = () => { + return ( + (WASMData.GSX.boardingState >= GSX_SERVICE_CALLED || WASMData.GSX.deboardingState >= GSX_SERVICE_CALLED) && + WASMData.GSX.deboardingState !== GSX_SERVICE_FINISHED + ); + }; + + const handleInput = (input: string, maxValue: number, setter: (value: number) => void) => { + if (!input) { + setter(0); + return; + } + + const converted = parseInt(input); + if (converted) { + if (converted < 0) setter(0); + else if (converted > maxValue) setter(maxValue); + else setter(converted); + } + }; + + const handleSB = async () => { + setSBInFlight(true); + + const SBResponse = await ImportFlightPlan( + username, + WASMData.limits.maxZFW, + WASMData.limits.maxTOW, + WASMData.limits.maxFuel, + WASMData.userData.isImperial + ); + if (SBResponse.type === 'error') { + console.error('TODO: ERROR', SBResponse.message); + setSBInFlight(false); + return; + } + + cargo.current = parseFloat(SBResponse.message.cargo) ?? 0; + + updateData(); + + setSBPlan(SBResponse.message); + setFuel(parseFloat(SBResponse.message.fuel) ?? 0); + setSBInFlight(false); + }; + + useEffect( + () => + setFuel((prev) => { + if (prev > WASMData.limits.maxFuel) return WASMData.limits.maxFuel; + return prev; + }), + [WASMData.userData.isER] + ); + useEffect(() => { + setFuelEnabled(inRangeOf(Math.round(WASMData.livePayload.fuel), fuel)); + }, [WASMData.livePayload.fuel]); + + const updateData = (_CGTarget?: number) => { + Coherent.call( + COHERENT_COMM_BUS_WASM_CALL, + COMM_BUS_UPDATE_TARGET_EVENT, + JSON.stringify({ + mode: 0, + cargo: cargo.current ?? 0, + CGTarget: _CGTarget ?? CGTarget, + }) + ); + }; + + return ( + <> +
+
+ + handleInput(e.target.value, WASMData.limits.maxFuel, setFuel)} + disabled={loadingState !== 'preview' || GSXActive()} + /> + +
+
+ +
+
+ + +
+
+ + +
+
+ + + setCGTarget((prev) => { + const _new = prev + 0.1; + updateData(_new); + return _new; + }) + } + decrease={() => + setCGTarget((prev) => { + const _new = prev - 0.1; + updateData(_new); + return _new; + }) + } + /> +
+
+ +
+
+ + +
+
+ + +
+
+ + { + setLoadingState('loaded'); + + loadAircraft(); + }} + unload={() => { + setLoadingState('preview'); + + unloadAircraft(); + }} + /> + + ); +}; + +export default SBEntryF; diff --git a/PackageSources/js-bundle/src/components/SBEntry/SBEntryPax.tsx b/PackageSources/js-bundle/src/components/SBEntry/SBEntryPax.tsx index 3cccc5a..5d755df 100644 --- a/PackageSources/js-bundle/src/components/SBEntry/SBEntryPax.tsx +++ b/PackageSources/js-bundle/src/components/SBEntry/SBEntryPax.tsx @@ -23,6 +23,7 @@ const SBEntryPax: FC = ({ WASMData, loadingState, username, setLoa const [CGTarget, setCGTarget] = useState(WASMData.targetPayload.CGTarget); const [fuel, setFuel] = useState(Math.round(WASMData.livePayload.fuel)); const [fuelEnabled, setFuelEnabled] = useState(true); + //eslint-disable-next-line @typescript-eslint/no-explicit-any const [SBPlan, setSBPlan] = useState(); const [SBInFlight, setSBInFlight] = useState(false); @@ -139,7 +140,7 @@ const SBEntryPax: FC = ({ WASMData, loadingState, username, setLoa WASMData.userData.isImperial ? fuel : fuel * 2.20462262185 ); SimVar.SetSimVarValue('L:MD11_EFB_READ_READY', 'bool', true); - setFuelEnabled(false); + setFuelEnabled(WASMData.livePayload.fuel === fuel); }} disabled={loadingState !== 'preview' || !fuelEnabled || GSXActive()} > @@ -160,7 +161,7 @@ const SBEntryPax: FC = ({ WASMData, loadingState, username, setLoa />
- + = ({ WASMData, username }) => { + const [selectedTab, setSelectedTab] = useState(0); + const [loadingState, setLoadingState] = useState('preview'); + + const upper1 = (overrideState: LoadingState = loadingState) => { + if (overrideState !== 'loaded') return Math.round(WASMData.targetPayload.upper1); + + return Math.round(WASMData.livePayload.upper1); + }; + const upper2 = (overrideState: LoadingState = loadingState) => { + if (overrideState !== 'loaded') return Math.round(WASMData.targetPayload.upper2); + + return Math.round(WASMData.livePayload.upper2); + }; + const upper3 = (overrideState: LoadingState = loadingState) => { + if (overrideState !== 'loaded') return Math.round(WASMData.targetPayload.upper3); + + return Math.round(WASMData.livePayload.upper3); + }; + const upper4 = (overrideState: LoadingState = loadingState) => { + if (overrideState !== 'loaded') return Math.round(WASMData.targetPayload.upper4); + + return Math.round(WASMData.livePayload.upper4); + }; + const lower1 = () => { + if (loadingState !== 'loaded' && !GSXActive()) return Math.round(WASMData.targetPayload.lowerForward); + + return Math.round(WASMData.livePayload.lowerForward); + }; + const lower2 = () => { + if (loadingState !== 'loaded' && !GSXActive()) return Math.round(WASMData.targetPayload.lowerRear); + + return Math.round(WASMData.livePayload.lowerRear); + }; + const OEW = () => { + if (loadingState !== 'loaded' && !GSXActive()) return Math.round(WASMData.targetPayload.empty); + + return Math.round(WASMData.livePayload.empty); + }; + const crew = () => { + if (loadingState !== 'loaded' && !GSXActive()) return Math.round(WASMData.targetPayload.crew); + + return Math.round(WASMData.livePayload.crew); + }; + + const GSXActive = () => { + return ( + (WASMData.GSX.boardingState >= GSX_SERVICE_CALLED || WASMData.GSX.deboardingState >= GSX_SERVICE_CALLED) && + WASMData.GSX.deboardingState !== GSX_SERVICE_FINISHED + ); + }; + + const CGs = (): [string, boolean, string, boolean] => { + if (loadingState !== 'loaded' && !GSXActive()) { + return [ + WASMData.targetPayload.ZFWCG.toFixed(1), + WASMData.targetPayload.ZFWCG < WASMData.limits.minCG || WASMData.targetPayload.ZFWCG > WASMData.limits.maxCG, + WASMData.targetPayload.TOCG.toFixed(1), + WASMData.targetPayload.TOCG < WASMData.limits.minCG || WASMData.targetPayload.TOCG > WASMData.limits.maxCG, + ]; + } + + return [ + WASMData.livePayload.ZFWCG.toFixed(1), + WASMData.livePayload.ZFWCG < WASMData.limits.minCG || WASMData.livePayload.ZFWCG > WASMData.limits.maxCG, + WASMData.livePayload.TOCG.toFixed(1), + WASMData.livePayload.TOCG < WASMData.limits.minCG || WASMData.livePayload.TOCG > WASMData.limits.maxCG, + ]; + }; + + return ( + <> + + + {username && selectedTab === 0 && ( + + )} + {((username && selectedTab === 1) || (!username && selectedTab === 0)) && ( + + )} + {((username && selectedTab === 2) || (!username && selectedTab === 1)) && ( + + )} + + ); +}; + +export default Freighter; diff --git a/PackageSources/js-bundle/src/components/stationEntry/StationEntryF.tsx b/PackageSources/js-bundle/src/components/stationEntry/StationEntryF.tsx new file mode 100644 index 0000000..8fbff4c --- /dev/null +++ b/PackageSources/js-bundle/src/components/stationEntry/StationEntryF.tsx @@ -0,0 +1,244 @@ +import { FC, useEffect, useState } from 'react'; +import { + COHERENT_COMM_BUS_WASM_CALL, + COMM_BUS_UPDATE_TARGET_EVENT, + GSX_SERVICE_CALLED, + GSX_SERVICE_FINISHED, +} from '../../constants'; +import { LoadingState } from '../../types/general'; +import { WASMDataF } from '../../types/WASMData'; +import { inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils'; +import ActionBar from '../actionbar/ActionBar'; + +interface StationEntryProps { + WASMData: WASMDataF; + loadingState: LoadingState; + setLoadingState: (newState: LoadingState) => void; +} + +const StationEntryF: FC = ({ WASMData, loadingState, setLoadingState }) => { + const [upper1, setUpper1] = useState(WASMData.targetPayload.upper1); + const [upper2, setUpper2] = useState(WASMData.targetPayload.upper2); + const [upper3, setUpper3] = useState(WASMData.targetPayload.upper3); + const [upper4, setUpper4] = useState(WASMData.targetPayload.upper4); + const [lowerForward, setLowerForward] = useState(WASMData.targetPayload.lowerForward); + const [lowerRear, setLowerRear] = useState(WASMData.targetPayload.lowerRear); + const [fuel, setFuel] = useState(Math.round(WASMData.livePayload.fuel)); + const [fuelEnabled, setFuelEnabled] = useState(true); + + const ZFW = () => { + if (loadingState !== 'loaded' && !GSXActive()) return Math.round(WASMData.targetPayload.total); + + return Math.round(WASMData.livePayload.total); + }; + const ZFWValid = () => { + return ZFW() <= WASMData.limits.maxZFW; + }; + const GW = () => { + return fuel + ZFW(); + }; + const GWValid = () => { + return GW() <= WASMData.limits.maxTOW; + }; + + const GSXActive = () => { + return ( + (WASMData.GSX.boardingState >= GSX_SERVICE_CALLED || WASMData.GSX.deboardingState >= GSX_SERVICE_CALLED) && + WASMData.GSX.deboardingState !== GSX_SERVICE_FINISHED + ); + }; + + const handleInput = (input: string, maxValue: number, setter: (value: number) => void) => { + if (!input) { + setter(0); + return; + } + + const converted = parseInt(input); + if (converted) { + if (converted < 0) setter(0); + else if (converted > maxValue) setter(maxValue); + else setter(converted); + } + }; + + useEffect(() => updateData(), [upper1, upper2, upper3, upper4, lowerForward, lowerRear]); + useEffect( + () => + setFuel((prev) => { + if (prev > WASMData.limits.maxFuel) return WASMData.limits.maxFuel; + return prev; + }), + [WASMData.userData.isER] + ); + useEffect(() => { + setFuelEnabled(inRangeOf(Math.round(WASMData.livePayload.fuel), fuel)); + }, [WASMData.livePayload.fuel]); + + const updateData = () => { + Coherent.call( + COHERENT_COMM_BUS_WASM_CALL, + COMM_BUS_UPDATE_TARGET_EVENT, + JSON.stringify({ + mode: 2, + business1: upper1, + business2: upper2, + economy1: upper3, + economy2: upper4, + forwardCargo: lowerForward, + rearCargo: lowerRear, + }) + ); + }; + + return ( + <> +
+
+ + handleInput(e.target.value, WASMData.limits.maxFuel, setFuel)} + disabled={loadingState !== 'preview' || GSXActive()} + /> + +
+
+ +
+
+ + handleInput(e.target.value, WASMData.limits.upper1, setUpper1)} + disabled={loadingState !== 'preview' || GSXActive()} + /> +
+
+ + handleInput(e.target.value, WASMData.limits.upper2, setUpper2)} + disabled={loadingState !== 'preview' || GSXActive()} + /> +
+
+ + handleInput(e.target.value, WASMData.limits.upper3, setUpper3)} + disabled={loadingState !== 'preview' || GSXActive()} + /> +
+
+ + handleInput(e.target.value, WASMData.limits.upper4, setUpper4)} + disabled={loadingState !== 'preview' || GSXActive()} + /> +
+
+ + handleInput(e.target.value, WASMData.limits.lowerForward, setLowerForward)} + disabled={loadingState !== 'preview' || GSXActive()} + /> +
+
+ + handleInput(e.target.value, WASMData.limits.lowerRear, setLowerRear)} + disabled={loadingState !== 'preview' || GSXActive()} + /> +
+
+ +
+
+ + +
+
+ + +
+
+ + { + setLoadingState('loaded'); + + loadAircraft(); + }} + unload={() => { + setLoadingState('preview'); + + unloadAircraft(); + }} + /> + + ); +}; + +export default StationEntryF; diff --git a/PackageSources/js-bundle/src/components/stationEntry/StationEntryPax.tsx b/PackageSources/js-bundle/src/components/stationEntry/StationEntryPax.tsx index 631ea3e..7f9bcae 100644 --- a/PackageSources/js-bundle/src/components/stationEntry/StationEntryPax.tsx +++ b/PackageSources/js-bundle/src/components/stationEntry/StationEntryPax.tsx @@ -114,7 +114,7 @@ const StationEntryPax: FC = ({ WASMData, loadingState, setLoa WASMData.userData.isImperial ? fuel : fuel * 2.20462262185 ); SimVar.SetSimVarValue('L:MD11_EFB_READ_READY', 'bool', true); - setFuelEnabled(false); + setFuelEnabled(WASMData.livePayload.fuel === fuel); }} disabled={loadingState !== 'preview' || !fuelEnabled || GSXActive()} > diff --git a/PackageSources/js-bundle/src/components/zfwEntry/ZFWEntryF.tsx b/PackageSources/js-bundle/src/components/zfwEntry/ZFWEntryF.tsx new file mode 100644 index 0000000..da2c435 --- /dev/null +++ b/PackageSources/js-bundle/src/components/zfwEntry/ZFWEntryF.tsx @@ -0,0 +1,234 @@ +import { FC, useEffect, useState } from 'react'; +import { + COHERENT_COMM_BUS_WASM_CALL, + COMM_BUS_UPDATE_TARGET_EVENT, + GSX_SERVICE_CALLED, + GSX_SERVICE_FINISHED, +} from '../../constants'; +import { WASMDataF } from '../../types/WASMData'; +import { LoadingState } from '../../types/general'; +import { inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils'; +import CGSelect from '../CGSelect/CGSelect'; +import ActionBar from '../actionbar/ActionBar'; + +interface ZFWEntryProps { + WASMData: WASMDataF; + loadingState: LoadingState; + setLoadingState: (newState: LoadingState) => void; +} + +const ZFWEntryF: FC = ({ WASMData, loadingState, setLoadingState }) => { + const [CGTarget, setCGTarget] = useState(WASMData.targetPayload.CGTarget); + const [fuel, setFuel] = useState(Math.round(WASMData.livePayload.fuel)); + const [ZFWTarget, setZFWTarget] = useState(Math.round(WASMData.targetPayload.total)); + const [fuelEnabled, setFuelEnabled] = useState(true); + + const ZFW = () => { + if (loadingState !== 'loaded' && !GSXActive()) return ZFWTarget; + + return Math.round(WASMData.livePayload.total); + }; + const ZFWValid = () => { + return ZFW() <= WASMData.limits.maxZFW; + }; + const GW = () => { + return fuel + ZFW(); + }; + const GWValid = () => { + return GW() <= WASMData.limits.maxTOW; + }; + + const GSXActive = () => { + return ( + (WASMData.GSX.boardingState >= GSX_SERVICE_CALLED || WASMData.GSX.deboardingState >= GSX_SERVICE_CALLED) && + WASMData.GSX.deboardingState !== GSX_SERVICE_FINISHED + ); + }; + + const handleInput = (input: string, maxValue: number, setter: (value: number) => void) => { + if (!input) { + setter(0); + return; + } + + const converted = parseInt(input); + if (converted) { + if (converted < 0) setter(0); + else if (converted > maxValue) setter(maxValue); + else setter(converted); + } + }; + const handleInputZFW = (input: string) => { + if (!input) return; + + const converted = parseInt(input); + if (converted) { + if (converted < 0) setZFWTarget(Math.round(WASMData.targetPayload.empty + WASMData.targetPayload.crew)); + else if (converted > WASMData.limits.maxZFW) setZFWTarget(WASMData.limits.maxZFW); + else setZFWTarget(converted); + } + }; + const handleBlur = (input: string) => { + const minZFW = Math.round(WASMData.targetPayload.empty + WASMData.targetPayload.crew); + + if (!input) { + setZFWTarget(minZFW); + return; + } + + const converted = parseInt(input); + if (converted) { + if (converted < minZFW) setZFWTarget(minZFW); + else if (converted > WASMData.limits.maxZFW) setZFWTarget(WASMData.limits.maxZFW); + else setZFWTarget(converted); + } + + updateData(converted); + }; + + useEffect( + () => + setFuel((prev) => { + if (prev > WASMData.limits.maxFuel) return WASMData.limits.maxFuel; + return prev; + }), + [WASMData.userData.isER] + ); + useEffect(() => { + setFuelEnabled(inRangeOf(Math.round(WASMData.livePayload.fuel), fuel)); + }, [WASMData.livePayload.fuel]); + + const updateData = (_ZFWTarget?: number, _CGTarget?: number) => { + Coherent.call( + COHERENT_COMM_BUS_WASM_CALL, + COMM_BUS_UPDATE_TARGET_EVENT, + JSON.stringify({ + mode: 1, + ZFWTarget: _ZFWTarget ?? ZFWTarget, + CGTarget: _CGTarget ?? CGTarget, + }) + ); + }; + + return ( + <> +
+
+ + handleInput(e.target.value, WASMData.limits.maxFuel, setFuel)} + disabled={loadingState !== 'preview' || GSXActive()} + /> + +
+
+ +
+
+ + handleInputZFW(e.target.value)} + onBlur={(e) => handleBlur(e.target.value)} + disabled={loadingState !== 'preview' || GSXActive()} + /> +
+
+ + + setCGTarget((prev) => { + const _new = prev + 0.1; + updateData(undefined, _new); + return _new; + }) + } + decrease={() => + setCGTarget((prev) => { + const _new = prev - 0.1; + updateData(undefined, _new); + return _new; + }) + } + /> +
+
+ +
+
+ + +
+
+ + +
+
+ + { + setLoadingState('loaded'); + + loadAircraft(); + }} + unload={() => { + setLoadingState('preview'); + + unloadAircraft(); + }} + /> + + ); +}; + +export default ZFWEntryF; diff --git a/PackageSources/js-bundle/src/components/zfwEntry/ZFWEntryPax.tsx b/PackageSources/js-bundle/src/components/zfwEntry/ZFWEntryPax.tsx index b16ff1d..e80e045 100644 --- a/PackageSources/js-bundle/src/components/zfwEntry/ZFWEntryPax.tsx +++ b/PackageSources/js-bundle/src/components/zfwEntry/ZFWEntryPax.tsx @@ -133,7 +133,7 @@ const ZFWEntryPax: FC = ({ WASMData, loadingState, setLoadingStat WASMData.userData.isImperial ? fuel : fuel * 2.20462262185 ); SimVar.SetSimVarValue('L:MD11_EFB_READ_READY', 'bool', true); - setFuelEnabled(false); + setFuelEnabled(WASMData.livePayload.fuel === fuel); }} disabled={loadingState !== 'preview' || !fuelEnabled || GSXActive()} > diff --git a/PackageSources/js-bundle/src/configs/freighter.ts b/PackageSources/js-bundle/src/configs/freighter.ts deleted file mode 100644 index 6e5ee07..0000000 --- a/PackageSources/js-bundle/src/configs/freighter.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { ArmsFuel, Fuel, toPercentMAC } from './shared'; - -// TODO: Extract from CFG at runtime. -const ArmsFreight = { - empty: -159.6, - pilot: 984, - firstOfficer: 984, - engineer: 960, - upper1Left: 660, - upper1Right: 660, - upper2Left: 240, - upper2Right: 240, - upper3Left: -240, - upper3Right: -240, - upper4Left: -600, - upper4Right: -600, - lowerForward: 360, - lowerRear: -360, - leftAuxF: 60, - rightAuxF: 60, -}; - -export interface PayloadFreight { - empty: number; - pilot: number; - firstOfficer: number; - engineer: number; - upper1Left: number; - upper1Right: number; - upper2Left: number; - upper2Right: number; - upper3Left: number; - upper3Right: number; - upper4Left: number; - upper4Right: number; - lowerForward: number; - lowerRear: number; - leftAuxF: number; - rightAuxF: number; -} - -//PMC pallet -export const maxUpperStationWeight = { - lbs: (26 / 8) * 15000, - kg: (26 / 8) * 6804, -}; - -export const baseWeightFreight = { - pilot: { - lbs: 190, - kg: 86, - }, - firstOfficer: { - lbs: 190, - kg: 86, - }, -}; - -export const maxZFWFreight = { - lbs: 451300, - kg: 204706, -}; - -export const calculateCGsFreight = (payload: PayloadFreight, fuel: Fuel): [number, number] => { - let totalMoment = - payload.empty * ArmsFreight.empty + - payload.pilot * ArmsFreight.pilot + - payload.firstOfficer * ArmsFreight.firstOfficer + - payload.engineer * ArmsFreight.engineer + - payload.upper1Left * ArmsFreight.upper1Left + - payload.upper1Right * ArmsFreight.upper1Right + - payload.upper2Left * ArmsFreight.upper2Left + - payload.upper2Right * ArmsFreight.upper2Right + - payload.upper3Left * ArmsFreight.upper3Left + - payload.upper3Right * ArmsFreight.upper3Right + - payload.upper4Left * ArmsFreight.upper4Left + - payload.upper4Right * ArmsFreight.upper4Right + - payload.lowerForward * ArmsFreight.lowerForward + - payload.lowerRear * ArmsFreight.lowerRear + - payload.leftAuxF * ArmsFreight.leftAuxF + - payload.rightAuxF * ArmsFreight.rightAuxF; - - let totalWeight = - payload.empty + - payload.pilot + - payload.firstOfficer + - payload.engineer + - payload.upper1Left + - payload.upper1Right + - payload.upper2Left + - payload.upper2Right + - payload.upper3Left + - payload.upper3Right + - payload.upper4Left + - payload.upper4Right + - payload.lowerForward + - payload.lowerRear + - payload.leftAuxF + - payload.rightAuxF; - - const ZFWCG = toPercentMAC(totalMoment / totalWeight); - - totalMoment += - fuel.main1 * ArmsFuel.main1 + - fuel.main3 * ArmsFuel.main3 + - fuel.main2 * ArmsFuel.main2 + - fuel.upperAux * ArmsFuel.upperAux + - fuel.lowerAux * ArmsFuel.lowerAux + - fuel.main1Tip * ArmsFuel.main1Tip + - fuel.main3Tip * ArmsFuel.main3Tip + - fuel.tail * ArmsFuel.tail + - fuel.forwardAux1 * ArmsFuel.forwardAux1 + - fuel.forwardAux2 * ArmsFuel.forwardAux2; - - totalWeight += - fuel.main1 + - fuel.main3 + - fuel.main2 + - fuel.upperAux + - fuel.lowerAux + - fuel.main1Tip + - fuel.main3Tip + - fuel.tail + - fuel.forwardAux1 + - fuel.forwardAux2; - - const TOCG = toPercentMAC(totalMoment / totalWeight); - - return [ZFWCG, TOCG]; -}; - -export const getWeightsFreight = (unit: 'kg' | 'lbs') => { - const payload: PayloadFreight = { - empty: SimVar.GetSimVarValue('EMPTY WEIGHT', unit), - pilot: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:1', unit), - firstOfficer: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:2', unit), - engineer: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:3', unit), - upper1Left: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:4', unit), - upper1Right: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:5', unit), - upper2Left: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:6', unit), - upper2Right: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:7', unit), - upper3Left: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:8', unit), - upper3Right: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:9', unit), - upper4Left: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:10', unit), - upper4Right: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:11', unit), - lowerForward: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:12', unit), - lowerRear: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:13', unit), - leftAuxF: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:14', unit), - rightAuxF: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:15', unit), - }; - - return payload; -}; diff --git a/PackageSources/js-bundle/src/types/WASMData.d.ts b/PackageSources/js-bundle/src/types/WASMData.ts similarity index 90% rename from PackageSources/js-bundle/src/types/WASMData.d.ts rename to PackageSources/js-bundle/src/types/WASMData.ts index eedb64a..6b3bba8 100644 --- a/PackageSources/js-bundle/src/types/WASMData.d.ts +++ b/PackageSources/js-bundle/src/types/WASMData.ts @@ -7,6 +7,15 @@ export interface WASMDataPax { options: Options; } +export interface WASMDataF { + livePayload: LivePayloadF; + targetPayload: TargetPayloadF; + GSX: GSX; + userData: UserData; + limits: LimitsF; + options: Options; +} + interface TargetPayload { CGTarget: number; ZFWCG: number; diff --git a/PackageSources/js-bundle/src/types/general.d.ts b/PackageSources/js-bundle/src/types/general.ts similarity index 100% rename from PackageSources/js-bundle/src/types/general.d.ts rename to PackageSources/js-bundle/src/types/general.ts diff --git a/PackageSources/js-bundle/src/utils/TFDISBImport.ts b/PackageSources/js-bundle/src/utils/TFDISBImport.ts index 205a9cf..02d7ff0 100644 --- a/PackageSources/js-bundle/src/utils/TFDISBImport.ts +++ b/PackageSources/js-bundle/src/utils/TFDISBImport.ts @@ -5,6 +5,7 @@ const getSimBriefFlightPlan = async (simBriefUsername: string) => { try { response = await fetch(flightPlanURL); success = true; + //eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (e: any) { response = e.response; } diff --git a/PackageSources/js-bundle/src/utils/utils.ts b/PackageSources/js-bundle/src/utils/utils.ts index 1fa77a0..fd2d72c 100644 --- a/PackageSources/js-bundle/src/utils/utils.ts +++ b/PackageSources/js-bundle/src/utils/utils.ts @@ -21,5 +21,5 @@ export const unloadAircraft = () => { }; export const inRangeOf = (value: number, target: number, tolerance: number = 10) => { - return Math.abs(value - target) < 10; + return Math.abs(value - target) < tolerance; }; diff --git a/PackageSources/wasm-module/freighter.cpp b/PackageSources/wasm-module/freighter.cpp new file mode 100644 index 0000000..b574602 --- /dev/null +++ b/PackageSources/wasm-module/freighter.cpp @@ -0,0 +1,306 @@ +#include "freighter.h" + +// ZFW Entry +void distribute(fPayloadData_t* const targetPayload, const FuelData_t* const fuel, const double ZFWTarget, const bool isImperial, const bool isER) { + // Find payload, num pax and extra cargo + double payload = ZFWTarget - targetPayload->empty - targetPayload->pilot - targetPayload->firstOfficer - targetPayload->engineer - + targetPayload->leftAux - targetPayload->rightAux; + unsigned int cargo = round(payload); + + distribute(targetPayload, fuel, cargo, isImperial, isER); +} + +// SimBrief Entry +void distribute(fPayloadData_t* const targetPayload, const FuelData_t* const fuel, unsigned int cargo, const bool isImperial, const bool isER) { + // Clear + targetPayload->stations.upper1 = targetPayload->stations.upper2 = targetPayload->stations.upper3 = targetPayload->stations.upper4 = + targetPayload->stations.total = 0; + targetPayload->lowerForward = targetPayload->lowerRear = 0; + + unsigned short _cargo = 0; + unsigned int count = MAX_UPPER_CARGO(isImperial) * 4 + MAX_FRONT_CARGO(isImperial) + MAX_REAR_CARGO(isImperial, isER); + // Initial distributiob + while (cargo > 0 && count > 0) { + if (cargo >= 6) { + if (targetPayload->stations.upper1 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper1++; + _cargo++; + } + if (targetPayload->stations.upper2 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper2++; + _cargo++; + } + if (targetPayload->stations.upper3 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper3++; + _cargo++; + } + if (targetPayload->stations.upper4 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper4++; + _cargo++; + } + if (targetPayload->lowerForward < MAX_FRONT_CARGO(isImperial)) { + targetPayload->lowerForward++; + _cargo++; + } + if (targetPayload->lowerRear < MAX_REAR_CARGO(isImperial, isER)) { + targetPayload->lowerRear++; + _cargo++; + } + } else if (cargo == 5) { + if (targetPayload->stations.upper1 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper1++; + _cargo++; + } + if (targetPayload->stations.upper2 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper2++; + _cargo++; + } + if (targetPayload->stations.upper3 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper3++; + _cargo++; + } + if (targetPayload->stations.upper4 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper4++; + _cargo++; + } + if (targetPayload->lowerForward < MAX_FRONT_CARGO(isImperial)) { + targetPayload->lowerForward++; + _cargo++; + } + } + else if (cargo == 4) { + if (targetPayload->stations.upper1 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper1++; + _cargo++; + } + if (targetPayload->stations.upper2 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper2++; + _cargo++; + } + if (targetPayload->stations.upper3 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper3++; + _cargo++; + } + if (targetPayload->stations.upper4 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper4++; + _cargo++; + } + } + else if (cargo == 3) { + if (targetPayload->stations.upper1 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper1++; + _cargo++; + } + if (targetPayload->stations.upper2 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper2++; + _cargo++; + } + if (targetPayload->stations.upper3 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper3++; + _cargo++; + } + } + else if (cargo == 2) { + if (targetPayload->stations.upper1 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper1++; + _cargo++; + } + if (targetPayload->stations.upper2 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper2++; + _cargo++; + } + } + else if (cargo == 1) { + if (targetPayload->stations.upper1 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper1++; + _cargo++; + } + } + cargo -= _cargo; + targetPayload->stations.total += _cargo; + + _cargo = 0; + + count--; + } + // Refinement + count = MAX_UPPER_CARGO(isImperial) * 4 + MAX_FRONT_CARGO(isImperial) + MAX_REAR_CARGO(isImperial, isER); + while (count > 0) { + generatePayload(targetPayload, isImperial); + calculateCGs(targetPayload, fuel, &targetPayload->ZFWCG, &targetPayload->TOCG, isImperial); + + // in front of target + if (targetPayload->ZFWCG < targetPayload->CGTarget - CG_TOLERANCE) { + if (targetPayload->stations.upper1 > 0) { + targetPayload->stations.upper1--; + } + else if (targetPayload->stations.upper2 > 0) { + targetPayload->stations.upper2--; + } + else if (targetPayload->stations.upper3 > 0) { + targetPayload->stations.upper3--; + } + else { + break; + } + + if (targetPayload->stations.upper4 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper4++; + } + else if (targetPayload->stations.upper3 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper3++; + } + else if (targetPayload->stations.upper2 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper2++; + } + else { + targetPayload->stations.upper1++; + } + } + // behind target + else if (targetPayload->ZFWCG > targetPayload->CGTarget + CG_TOLERANCE) { + if (targetPayload->stations.upper4 > 0) { + targetPayload->stations.upper4--; + } + else if (targetPayload->stations.upper3 > 0) { + targetPayload->stations.upper3--; + } + else if (targetPayload->stations.upper2 > 0) { + targetPayload->stations.upper2--; + } + else { + break; + } + + if (targetPayload->stations.upper1 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper1++; + } + else if (targetPayload->stations.upper2 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper2++; + } + else if (targetPayload->stations.upper3 < MAX_UPPER_CARGO(isImperial)) { + targetPayload->stations.upper3++; + } + else { + targetPayload->stations.upper4++; + } + } + else { + break; + } + + count--; + } + // Refinement cargo + count = MAX_FRONT_CARGO(isImperial) + MAX_REAR_CARGO(isImperial, isER); + while (count > 0) { + generatePayload(targetPayload, isImperial); + calculateCGs(targetPayload, fuel, &targetPayload->ZFWCG, &targetPayload->TOCG, isImperial); + + // in front of target + if (targetPayload->ZFWCG < targetPayload->CGTarget - CG_TOLERANCE) { + if (targetPayload->lowerForward > 0 && targetPayload->lowerRear < MAX_REAR_CARGO(isImperial, isER)) { + targetPayload->lowerForward--; + targetPayload->lowerRear++; + } + else { + break; + } + } + // behind target + else if (targetPayload->ZFWCG > targetPayload->CGTarget + CG_TOLERANCE) { + if (targetPayload->lowerRear > 0 && targetPayload->lowerForward < MAX_FRONT_CARGO(isImperial)) { + targetPayload->lowerRear--; + targetPayload->lowerForward++; + } + else { + break; + } + } + else { + break; + } + + count--; + } +} + +// Updates pax stations with their respective weights +// Used internally and used for Station Entry (pax only, cargo is set directly) +void generatePayload(fPayloadData_t* const targetPayload, const bool isImperial) { + targetPayload->upper1Left = targetPayload->upper1Right = (targetPayload->stations.upper1 / 2.0); + targetPayload->upper2Left = targetPayload->upper2Right = (targetPayload->stations.upper2 / 2.0); + targetPayload->upper3Left = targetPayload->upper3Right = (targetPayload->stations.upper3 / 2.0); + targetPayload->upper4Left = targetPayload->upper4Right = (targetPayload->stations.upper4 / 2.0); + targetPayload->total = targetPayload->empty + targetPayload->pilot + targetPayload->firstOfficer + targetPayload->engineer + targetPayload->upper1Left + + targetPayload->upper1Right + targetPayload->upper2Left + targetPayload->upper2Right + targetPayload->upper3Left + + targetPayload->upper3Right + targetPayload->upper4Left + targetPayload->upper4Right + targetPayload->lowerForward + + targetPayload->lowerRear + targetPayload->leftAux + targetPayload->rightAux; +} + +// Normalise to Pounds +// MANDATORY BEFORE SETTING WEIGHTS +// USE ON COPY OF GLOBAL STATE ONLY +void normalisePayload(fPayloadData_t* const targetPayload, const bool isImperial) { + targetPayload->empty = TO_POUNDS(isImperial, targetPayload->empty); + targetPayload->pilot = TO_POUNDS(isImperial, targetPayload->pilot); + targetPayload->firstOfficer = TO_POUNDS(isImperial, targetPayload->firstOfficer); + targetPayload->engineer = TO_POUNDS(isImperial, targetPayload->engineer); + targetPayload->upper1Left = TO_POUNDS(isImperial, targetPayload->upper1Left); + targetPayload->upper1Right = TO_POUNDS(isImperial, targetPayload->upper1Right); + targetPayload->upper2Left = TO_POUNDS(isImperial, targetPayload->upper2Left); + targetPayload->upper2Right = TO_POUNDS(isImperial, targetPayload->upper2Right); + targetPayload->upper3Left = TO_POUNDS(isImperial, targetPayload->upper3Left); + targetPayload->upper3Right = TO_POUNDS(isImperial, targetPayload->upper3Right); + targetPayload->upper4Left = TO_POUNDS(isImperial, targetPayload->upper4Left); + targetPayload->upper4Right = TO_POUNDS(isImperial, targetPayload->upper4Right); + targetPayload->lowerForward = TO_POUNDS(isImperial, targetPayload->lowerForward); + targetPayload->lowerRear = TO_POUNDS(isImperial, targetPayload->lowerRear); + targetPayload->leftAux = TO_POUNDS(isImperial, targetPayload->leftAux); + targetPayload->rightAux = TO_POUNDS(isImperial, targetPayload->rightAux); +} + +void calculateCGs(const fPayloadData_t* const targetPayload, const FuelData_t* const fuel, double* const ZFWCG, double* const TOCG, const bool isImperial) { + fPayloadData_t localPayload = {}; + memcpy(&localPayload, targetPayload, sizeof(localPayload)); + normalisePayload(&localPayload, isImperial); + + double totalMoment = localPayload.empty * ARM_EMPTY + localPayload.pilot * ARM_PILOT + localPayload.firstOfficer * ARM_FIRST_OFFICER + + localPayload.engineer * ARM_ENGINEER + localPayload.upper1Left * ARM_F_UPPER1_LEFT + localPayload.upper1Right * ARM_F_UPPER1_RIGHT + + localPayload.upper2Left * ARM_F_UPPER2_LEFT + localPayload.upper2Right * ARM_F_UPPER2_RIGHT + localPayload.upper3Left * ARM_F_UPPER3_LEFT + + localPayload.upper3Right * ARM_F_UPPER3_RIGHT + localPayload.upper4Left * ARM_F_UPPER4_LEFT + localPayload.upper4Right * ARM_F_UPPER4_RIGHT + + localPayload.lowerForward * ARM_FORWARD_CARGO + localPayload.lowerRear * ARM_REAR_CARGO + localPayload.leftAux * ARM_LEFT_AUX + + localPayload.rightAux * ARM_RIGHT_AUX; + + double totalWeight = localPayload.empty + localPayload.pilot + localPayload.firstOfficer + localPayload.engineer + localPayload.upper1Left + + localPayload.upper1Right + localPayload.upper2Left + localPayload.upper2Right + localPayload.upper3Left + localPayload.upper3Right + + localPayload.upper4Left + localPayload.upper4Right + localPayload.lowerForward + localPayload.lowerRear + localPayload.leftAux + + localPayload.rightAux; + + *ZFWCG = TO_PERCENT_MAC(totalMoment / totalWeight); + + totalMoment += fuel->main1 * ARM_MAIN1 + fuel->main3 * ARM_MAIN3 + fuel->main2 * ARM_MAIN2 + fuel->upperAux * ARM_UPPER_AUX + + fuel->lowerAux * ARM_LOWER_AUX + fuel->main1Tip * ARM_MAIN1_TIP + fuel->main3Tip * ARM_MAIN3_TIP + + fuel->tail * ARM_TAIL + fuel->forwardAux1 * ARM_FORWARD_AUX1 + fuel->forwardAux2 * ARM_FORWARD_AUX2; + + totalWeight += fuel->total; + + *TOCG = TO_PERCENT_MAC(totalMoment / totalWeight); +} + +void load(const fPayloadData_t* const targetPayload, const HANDLE simConnect, const bool isImperial) { + fPayloadData_t localPayload = {}; + memcpy(&localPayload, targetPayload, sizeof(localPayload)); + normalisePayload(&localPayload, isImperial); + + SimConnect_SetDataOnSimObject(simConnect, DATA_DEFINITION_PAYLOAD_F, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(fPayloadDataSet_t), &localPayload); +} + +void unloadF(const HANDLE simConnect, const bool isER) { + fPayloadData_t localPayload = {}; + + localPayload.leftAux = localPayload.rightAux = isER ? AUX_WEIGHT(true) : 0; + localPayload.pilot = localPayload.firstOfficer = localPayload.engineer = PILOT_WEIGHT(true); + + SimConnect_SetDataOnSimObject(simConnect, DATA_DEFINITION_PAYLOAD_F, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(fPayloadDataSet_t), &localPayload); +} diff --git a/PackageSources/wasm-module/freighter.h b/PackageSources/wasm-module/freighter.h new file mode 100644 index 0000000..26d99f1 --- /dev/null +++ b/PackageSources/wasm-module/freighter.h @@ -0,0 +1,36 @@ +#pragma once + +#ifndef __INTELLISENSE__ +# define MODULE_EXPORT __attribute__( ( visibility( "default" ) ) ) +# define MODULE_WASM_MODNAME(mod) __attribute__((import_module(mod))) +#else +# define MODULE_EXPORT +# define MODULE_WASM_MODNAME(mod) +# define __attribute__(x) +# define __restrict__ +#endif + +#include + +#include + +#include + +#include + +#include "types.h" + +// ZFW Entry +void distribute(fPayloadData_t* const targetPayload, const FuelData_t* const fuel, const double ZFWTarget, const bool isImperial, const bool isER); +// SimBrief Entry +void distribute(fPayloadData_t* const targetPayload, const FuelData_t* const fuel, unsigned int cargo, const bool isImperial, const bool isER); +// Updates pax stations with their respective weights +// Used internally and used for Station Entry (pax only, cargo is ste directly) +// STATION WEIGHTS ARE NOT NORMALISED TO POUNDS +void generatePayload(fPayloadData_t* const targetPayload, const bool isImperial); +// Normalise to Pounds +// For Station Entry: CALL AFTER `generatePayload` +void normalisePayload(fPayloadData_t* const targetPayload, const bool isImperial); +void calculateCGs(const fPayloadData_t* const targetPayload, const FuelData_t* const fuel, double* const ZFWCG, double* const TOCG, const bool isImperial); +void load(const fPayloadData_t* const targetPayload, const HANDLE simConnect, const bool isImperial); +void unloadF(const HANDLE simConnect, const bool isER); diff --git a/PackageSources/wasm-module/load-manager.cpp b/PackageSources/wasm-module/load-manager.cpp index 7bd4a1a..e63667f 100644 --- a/PackageSources/wasm-module/load-manager.cpp +++ b/PackageSources/wasm-module/load-manager.cpp @@ -342,27 +342,27 @@ extern "C" MSFS_CALLBACK void module_init(void) { log(stdout, MODULE_NAME"Data definitions created\n"); // SimConnect Requests - hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_EMPTY_WEIGHT, DATA_DEFINITION_EMPTY_WEIGHT, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND); + hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_EMPTY_WEIGHT, DATA_DEFINITION_EMPTY_WEIGHT, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not request empty weight, terminating.\n"); return; } - hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_PAYLOAD_PAX, DATA_DEFINITION_PAYLOAD_PAX, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND); + hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_PAYLOAD_PAX, DATA_DEFINITION_PAYLOAD_PAX, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not request payload pax, terminating.\n"); return; } - hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_PAYLOAD_F, DATA_DEFINITION_PAYLOAD_F, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND); + hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_PAYLOAD_F, DATA_DEFINITION_PAYLOAD_F, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not request payload f, terminating.\n"); return; } - hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_FUEL, DATA_DEFINITION_FUEL, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND); + hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_FUEL, DATA_DEFINITION_FUEL, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not request fuel, terminating.\n"); return; } - hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_GSX, DATA_DEFINITION_GSX, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND); + hr = SimConnect_RequestDataOnSimObject(simConnect, DATA_REQUEST_GSX, DATA_DEFINITION_GSX, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME); if (hr != S_OK) { log(stderr, MODULE_NAME"Could not request GSX, terminating.\n"); return; @@ -507,8 +507,9 @@ int receiveData(const char* buf) { double CGTarget = document["CGTarget"].GetDouble(); if (UserData->isCargo) { - targetPaxPayloadData->CGTarget = CGTarget; - //TODO: F load + targetFPayloadData->CGTarget = CGTarget; + + distribute(targetFPayloadData, liveFuelData, cargo, UserData->isImperial, UserData->isER); } else { if (!document.HasMember("numPax")) return -1; @@ -526,8 +527,8 @@ int receiveData(const char* buf) { double CGTarget = document["CGTarget"].GetDouble(); if (UserData->isCargo) { - targetPaxPayloadData->CGTarget = CGTarget; - //TODO: F load + targetFPayloadData->CGTarget = CGTarget; + distribute(targetFPayloadData, liveFuelData, ZFWTarget, UserData->isImperial, UserData->isER); } else { targetPaxPayloadData->CGTarget = CGTarget; @@ -538,7 +539,17 @@ int receiveData(const char* buf) { // Station Entry case 2: { if (UserData->isCargo) { - //TODO: F load + if (!document.HasMember("upper1") || !document.HasMember("upper2") || + !document.HasMember("upper3") || !document.HasMember("upper4") || + !document.HasMember("lowerForward") || !document.HasMember("lowerRear")) return -1; + targetFPayloadData->stations.upper1 = document["upper1"].GetInt(); + targetFPayloadData->stations.upper2 = document["upper2"].GetInt(); + targetFPayloadData->stations.upper3 = document["upper3"].GetInt(); + targetFPayloadData->stations.upper4 = document["upper4"].GetInt(); + targetFPayloadData->lowerForward = document["lowerForward"].GetDouble(); + targetFPayloadData->lowerRear = document["lowerRear"].GetDouble(); + + generatePayload(targetFPayloadData, UserData->isImperial); } else { if (!document.HasMember("business1") || !document.HasMember("business2") || @@ -558,7 +569,7 @@ int receiveData(const char* buf) { // Trigger load case 3: { if (UserData->isCargo) { - //TODO: F load + load(targetFPayloadData, simConnect, UserData->isImperial); } else { load(targetPaxPayloadData, simConnect, UserData->isImperial); @@ -569,7 +580,7 @@ int receiveData(const char* buf) { // Trigger unload case 4: { if (UserData->isCargo) { - //TODO: F load + unloadF(simConnect, UserData->isER); } else { unload(simConnect, UserData->isER); @@ -635,8 +646,7 @@ void sendData () { livePayload.AddMember("lowerRear", FROM_POUNDS(UserData->isImperial, liveFPayloadData->lowerRear), allocator); livePayload.AddMember("total", FROM_POUNDS(UserData->isImperial, liveFPayloadData->total), allocator); // CGs - //TODO: Enable for F - //calculateCGs(liveFPayloadData, liveFuelData, &liveFPayloadData->ZFWCG, &liveFPayloadData->TOCG, true); + calculateCGs(liveFPayloadData, liveFuelData, &liveFPayloadData->ZFWCG, &liveFPayloadData->TOCG, true); livePayload.AddMember("ZFWCG", liveFPayloadData->ZFWCG, allocator); livePayload.AddMember("TOCG", liveFPayloadData->TOCG, allocator); } @@ -695,8 +705,7 @@ void sendData () { targetPayload.AddMember("total", targetFPayloadData->total, allocator); targetPayload.AddMember("CGTarget", targetFPayloadData->CGTarget, allocator); // CGs - //TODO: Enable for F - //calculateCGs(targetFPayloadData, liveFuelData, &targetFPayloadData->ZFWCG, &targetFPayloadData->TOCG, UserData->isImperial); + calculateCGs(targetFPayloadData, liveFuelData, &targetFPayloadData->ZFWCG, &targetFPayloadData->TOCG, UserData->isImperial); targetPayload.AddMember("ZFWCG", targetFPayloadData->ZFWCG, allocator); targetPayload.AddMember("TOCG", targetFPayloadData->TOCG, allocator); } @@ -737,16 +746,14 @@ void sendData () { limits.AddMember("maxFuel", UserData->isER ? MAX_FUEL_ER(UserData->isImperial) : MAX_FUEL(UserData->isImperial), allocator); limits.AddMember("maxTOW", UserData->isER ? MAX_TOW_ER(UserData->isImperial) : MAX_TOW(UserData->isImperial), allocator); // Cargo Only - // TODO: Actual F limits if (UserData->isCargo) { - limits.AddMember("upper1", -1, allocator); - limits.AddMember("upper2", -1, allocator); - limits.AddMember("upper3", -1, allocator); - limits.AddMember("upper4", -1, allocator); + limits.AddMember("upper1", MAX_UPPER_CARGO(UserData->isImperial), allocator); + limits.AddMember("upper2", MAX_UPPER_CARGO(UserData->isImperial), allocator); + limits.AddMember("upper3", MAX_UPPER_CARGO(UserData->isImperial), allocator); + limits.AddMember("upper4", MAX_UPPER_CARGO(UserData->isImperial), allocator); limits.AddMember("lowerForward", MAX_FRONT_CARGO(UserData->isImperial), allocator); limits.AddMember("lowerRear", MAX_REAR_CARGO(UserData->isImperial, UserData->isER), allocator); - // TODO: Actual F limit - //limits.AddMember("MaxZFW", MAX_F_ZFW, allocator); + limits.AddMember("maxZFW", MAX_F_ZFW(UserData->isImperial), allocator); limits.AddMember("minZFW", targetFPayloadData->empty + targetFPayloadData->leftAux + targetFPayloadData->rightAux, allocator); } // Pax only @@ -858,7 +865,18 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContex if (GSXData->boardingState == GSX_SERVICE_ACTIVE) { double cargoBoarded = GSXData->cargoBoarded; if (UserData->isCargo) { - //TODO: Progressive F load + fPayloadData_t localPayload = {}; + memcpy(&localPayload, targetFPayloadData, sizeof(localPayload)); + + localPayload.stations.upper1 = targetFPayloadData->stations.upper1 * (cargoBoarded / 100); + localPayload.stations.upper2 = targetFPayloadData->stations.upper2 * (cargoBoarded / 100); + localPayload.stations.upper3 = targetFPayloadData->stations.upper3 * (cargoBoarded / 100); + localPayload.stations.upper4 = targetFPayloadData->stations.upper4 * (cargoBoarded / 100); + localPayload.lowerForward = targetFPayloadData->lowerForward * (cargoBoarded / 100); + localPayload.lowerRear = targetFPayloadData->lowerRear * (cargoBoarded / 100); + + generatePayload(&localPayload, UserData->isImperial); + load(&localPayload, simConnect, UserData->isImperial); } else { double passengersBoarded = GSXData->passengersBoarded; @@ -883,7 +901,18 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContex if (GSXData->deboardingState == GSX_SERVICE_ACTIVE) { double cargoDeboarded = GSXData->cargoDeboarded; if (UserData->isCargo) { - //TODO: Progressive F unload + fPayloadData_t localPayload = {}; + memcpy(&localPayload, targetFPayloadData, sizeof(localPayload)); + + localPayload.stations.upper1 -= targetFPayloadData->stations.upper1 * (cargoDeboarded / 100); + localPayload.stations.upper2 -= targetFPayloadData->stations.upper2 * (cargoDeboarded / 100); + localPayload.stations.upper3 -= targetFPayloadData->stations.upper3 * (cargoDeboarded / 100); + localPayload.stations.upper4 -= targetFPayloadData->stations.upper4 * (cargoDeboarded / 100); + localPayload.lowerForward -= targetFPayloadData->lowerForward * (cargoDeboarded / 100); + localPayload.lowerRear -= targetFPayloadData->lowerRear * (cargoDeboarded / 100); + + generatePayload(&localPayload, UserData->isImperial); + load(&localPayload, simConnect, UserData->isImperial); } else { double passengersDeboarded = GSXData->passengersDeboarded; diff --git a/PackageSources/wasm-module/load-manager.h b/PackageSources/wasm-module/load-manager.h index 05d3270..96aab99 100644 --- a/PackageSources/wasm-module/load-manager.h +++ b/PackageSources/wasm-module/load-manager.h @@ -23,6 +23,7 @@ #include "types.h" #include "pax.h" +#include "freighter.h" #define MODULE_NAME "[KHOFMANN TFDi MD-11 Load Manager] " diff --git a/PackageSources/wasm-module/load-manager.vcxproj b/PackageSources/wasm-module/load-manager.vcxproj index f928def..80c0d49 100644 --- a/PackageSources/wasm-module/load-manager.vcxproj +++ b/PackageSources/wasm-module/load-manager.vcxproj @@ -283,10 +283,12 @@ + + diff --git a/PackageSources/wasm-module/load-manager.vcxproj.filters b/PackageSources/wasm-module/load-manager.vcxproj.filters index 7ccbd12..1ab3033 100644 --- a/PackageSources/wasm-module/load-manager.vcxproj.filters +++ b/PackageSources/wasm-module/load-manager.vcxproj.filters @@ -7,6 +7,9 @@ Source Files + + Source Files + @@ -18,6 +21,9 @@ Header Files + + Header Files + diff --git a/PackageSources/wasm-module/pax.cpp b/PackageSources/wasm-module/pax.cpp index 6c042b1..f4691c7 100644 --- a/PackageSources/wasm-module/pax.cpp +++ b/PackageSources/wasm-module/pax.cpp @@ -1,6 +1,6 @@ #include "pax.h" -//ZFW Entry, fill pax first (pax+bag), rest is cargo +// ZFW Entry, fill pax first (pax+bag), rest is cargo void distribute(paxPayloadData_t* const targetPayload, const FuelData_t* const fuel, const double ZFWTarget, const bool isImperial, const bool isER) { // Find payload, num pax and extra cargo double payload = ZFWTarget - targetPayload->empty - targetPayload->pilot - targetPayload->firstOfficer - targetPayload->engineer - @@ -11,7 +11,7 @@ void distribute(paxPayloadData_t* const targetPayload, const FuelData_t* const f distribute(targetPayload, fuel, numPax, cargo, isImperial, isER); } -//SimBrief Entry, SB pax count and extra cargo +// SimBrief Entry, SB pax count and extra cargo void distribute(paxPayloadData_t* const targetPayload, const FuelData_t* const fuel, unsigned short numPax, unsigned int cargo, const bool isImperial, const bool isER) { // Clear targetPayload->paxCount.business1 = targetPayload->paxCount.business2 = targetPayload->paxCount.economy1 = targetPayload->paxCount.economy2 = @@ -292,7 +292,6 @@ void calculateCGs(const paxPayloadData_t* const targetPayload, const FuelData_t* *TOCG = TO_PERCENT_MAC(totalMoment / totalWeight); } - void load(const paxPayloadData_t* const targetPayload, const HANDLE simConnect, const bool isImperial) { paxPayloadData_t localPayload = {}; memcpy(&localPayload, targetPayload, sizeof(localPayload)); @@ -309,5 +308,5 @@ void unload(const HANDLE simConnect, const bool isER) { localPayload.leftAux = localPayload.rightAux = isER ? AUX_WEIGHT(true) : 0; localPayload.pilot = localPayload.firstOfficer = localPayload.engineer = PILOT_WEIGHT(true); - SimConnect_SetDataOnSimObject(simConnect, DATA_DEFINITION_PAYLOAD_PAX, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(localPayload), &localPayload); + SimConnect_SetDataOnSimObject(simConnect, DATA_DEFINITION_PAYLOAD_PAX, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(paxPayloadDataSet_t), &localPayload); } diff --git a/PackageSources/wasm-module/types.h b/PackageSources/wasm-module/types.h index 0086116..068e0d7 100644 --- a/PackageSources/wasm-module/types.h +++ b/PackageSources/wasm-module/types.h @@ -17,8 +17,9 @@ //PMC pallet due to 104in door #define MAX_FRONT_CARGO(IS_IMPERIAL) ((IS_IMPERIAL) ? (6.0 * 15000.0) : (6.0 * 6804.0)) +#define MAX_UPPER_CARGO(IS_IMPERIAL) ((IS_IMPERIAL) ? (6.5 * 15000.0) : (6.5 * 6804.0)) //LD3s due to 70in door -#define MAX_REAR_CARGO(IS_IMPERIAL, IS_ER) ((IS_IMPERIAL) ? ((IS_ER ? 14.0 : 2.0) * 3500.0) : ((IS_ER ? 14.0 : 2.0) * 1588.0)) +#define MAX_REAR_CARGO(IS_IMPERIAL, IS_ER) ((IS_IMPERIAL) ? ((IS_ER ? 12.0 : 14.0) * 3500.0) : ((IS_ER ? 12.0 : 14.0) * 1588.0)) // All actual Business seats #define MAX_BUSINESS_1 30 @@ -33,6 +34,7 @@ // Max ZFW #define MAX_PAX_ZFW(IS_IMPERIAL) ((IS_IMPERIAL) ? (400000) : (181437)) +#define MAX_F_ZFW(IS_IMPERIAL) ((IS_IMPERIAL) ? (451300) : (204706)) // Max TOW #define MAX_TOW(IS_IMPERIAL) ((IS_IMPERIAL) ? (625500) : (283722)) @@ -63,6 +65,15 @@ #define ARM_PAX_ECONOMY2_CENTER -600.0 #define ARM_PAX_ECONOMY2_RIGHT -600.0 #define ARM_PAX_CABIN_CREW_REAR -660.0 +// Cargo only +#define ARM_F_UPPER1_LEFT 660 +#define ARM_F_UPPER1_RIGHT 660 +#define ARM_F_UPPER2_LEFT 240 +#define ARM_F_UPPER2_RIGHT 240 +#define ARM_F_UPPER3_LEFT -240 +#define ARM_F_UPPER3_RIGHT -240 +#define ARM_F_UPPER4_LEFT -600 +#define ARM_F_UPPER4_RIGHT -600 // Shared part 2 #define ARM_FORWARD_CARGO 360.0 #define ARM_REAR_CARGO -360.0 @@ -225,6 +236,13 @@ typedef struct { double CGTarget; double ZFWCG; double TOCG; + struct stations { + unsigned int upper1; + unsigned int upper2; + unsigned int upper3; + unsigned int upper4; + unsigned int total; + } stations; } fPayloadData_t; typedef struct { // SimConnect mapped diff --git a/README.md b/README.md index ad6e985..210ac73 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +# How to build + +After building WASM, run `copy-debug` or `copy-release` to copy WASM module. + # Sources - https://www.boeing.com/content/dam/boeing/boeingdotcom/company/about_bca/startup/pdf/freighters/MD11BCF.pdf @@ -7,10 +11,15 @@ TODO: +- EFB integration (BRANCH) + - Check if including bundle is getting loaded + - Add to bundle global scoped react "import" + - Automate this? + - Add to EFB.js and EFB.html + - Automate this? - JS - Persist SB data across page changes - - Duplicate Input pages for F - Options (GSX sync, pax/bag weights) + - Types for SB plan (only what I need) - WASM - Custom pax/bag weights - - F loading stuff diff --git a/copy-debug.ps1 b/copy-debug.ps1 new file mode 100644 index 0000000..7609b5b --- /dev/null +++ b/copy-debug.ps1 @@ -0,0 +1,4 @@ +Copy-Item .\PackageSources\wasm-module\MSFS\Debug\load-manager.wasm .\PackageSources\SimObjects\Airplanes\TFDi_Design_MD-11_GE\panel +Copy-Item .\PackageSources\wasm-module\MSFS\Debug\load-manager.wasm .\PackageSources\SimObjects\Airplanes\TFDi_Design_MD-11_PW\panel +Copy-Item .\PackageSources\wasm-module\MSFS\Debug\load-manager.wasm .\PackageSources\SimObjects\Airplanes\TFDi_Design_MD-11F_GE\panel +Copy-Item .\PackageSources\wasm-module\MSFS\Debug\load-manager.wasm .\PackageSources\SimObjects\Airplanes\TFDi_Design_MD-11F_PW\panel \ No newline at end of file diff --git a/copy-release.ps1 b/copy-release.ps1 new file mode 100644 index 0000000..1a8ece3 --- /dev/null +++ b/copy-release.ps1 @@ -0,0 +1,4 @@ +Copy-Item .\PackageSources\wasm-module\MSFS\Release\load-manager.wasm .\PackageSources\SimObjects\Airplanes\TFDi_Design_MD-11_GE\panel +Copy-Item .\PackageSources\wasm-module\MSFS\Release\load-manager.wasm .\PackageSources\SimObjects\Airplanes\TFDi_Design_MD-11_PW\panel +Copy-Item .\PackageSources\wasm-module\MSFS\Release\load-manager.wasm .\PackageSources\SimObjects\Airplanes\TFDi_Design_MD-11F_GE\panel +Copy-Item .\PackageSources\wasm-module\MSFS\Release\load-manager.wasm .\PackageSources\SimObjects\Airplanes\TFDi_Design_MD-11F_PW\panel \ No newline at end of file