Freighter
This commit is contained in:
parent
cbd7d4e0ae
commit
9da2abdad7
4
.gitignore
vendored
4
.gitignore
vendored
@ -8,4 +8,6 @@ PackageSources/wasm-module/.vs
|
|||||||
PackageSources/wasm-module/MSFS
|
PackageSources/wasm-module/MSFS
|
||||||
PackageSources/wasm-module/x64
|
PackageSources/wasm-module/x64
|
||||||
|
|
||||||
*.blend1
|
*.blend1
|
||||||
|
|
||||||
|
PackageSources/SimObjects/Airplanes/**/panel/*.wasm
|
||||||
@ -35,17 +35,6 @@
|
|||||||
<AssetDir>PackageSources\load-manager-panel\</AssetDir>
|
<AssetDir>PackageSources\load-manager-panel\</AssetDir>
|
||||||
<OutputDir>InGamePanels\</OutputDir>
|
<OutputDir>InGamePanels\</OutputDir>
|
||||||
</AssetGroup>
|
</AssetGroup>
|
||||||
<AssetGroup Name="md-11-load-manager-wasm-pw-pax">
|
|
||||||
<Type>Copy</Type>
|
|
||||||
<Flags>
|
|
||||||
<FSXCompatibility>false</FSXCompatibility>
|
|
||||||
</Flags>
|
|
||||||
<AssetDir>PackageSources\wasm-module\MSFS\Debug\</AssetDir>
|
|
||||||
<OutputDir>SimObjects\Airplanes\TFDi_Design_MD-11_PW\panel\</OutputDir>
|
|
||||||
<Config>
|
|
||||||
<Include>*.wasm</Include>
|
|
||||||
</Config>
|
|
||||||
</AssetGroup>
|
|
||||||
<AssetGroup Name="md-11-panel-config">
|
<AssetGroup Name="md-11-panel-config">
|
||||||
<Type>Copy</Type>
|
<Type>Copy</Type>
|
||||||
<Flags>
|
<Flags>
|
||||||
|
|||||||
@ -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
|
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
|
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
|
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]
|
[VIEWS]
|
||||||
VIEW_FORWARD_DIR=2.000, 0.000, 0.000
|
VIEW_FORWARD_DIR=2.000, 0.000, 0.000
|
||||||
|
|||||||
@ -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
|
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
|
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
|
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]
|
[VIEWS]
|
||||||
VIEW_FORWARD_DIR=2.000, 0.000, 0.000
|
VIEW_FORWARD_DIR=2.000, 0.000, 0.000
|
||||||
|
|||||||
@ -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
|
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
|
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
|
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]
|
[VIEWS]
|
||||||
VIEW_FORWARD_DIR=2.000, 0.000, 0.000
|
VIEW_FORWARD_DIR=2.000, 0.000, 0.000
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "tfdidesign-md11-load-manager",
|
"name": "tfdidesign-md11-load-manager",
|
||||||
"version": "0.1.17",
|
"version": "0.1.21",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@ -13,7 +13,9 @@
|
|||||||
"dev": "npx rollup -c -w",
|
"dev": "npx rollup -c -w",
|
||||||
"clean": "rimraf ../html_ui/InGamePanels/tfdidesign-md11-load-manager-panel/ && rimraf .rollup.cache",
|
"clean": "rimraf ../html_ui/InGamePanels/tfdidesign-md11-load-manager-panel/ && rimraf .rollup.cache",
|
||||||
"build": "npm version patch && npx rollup -c",
|
"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": {
|
"engines": {
|
||||||
"node": ">=22"
|
"node": ">=22"
|
||||||
|
|||||||
@ -27,6 +27,15 @@ export default {
|
|||||||
dir: panelDirBase,
|
dir: panelDirBase,
|
||||||
format: 'es',
|
format: 'es',
|
||||||
sourcemap: targetEnv !== 'production',
|
sourcemap: targetEnv !== 'production',
|
||||||
|
manualChunks: process.env.SPLIT
|
||||||
|
? (id) => {
|
||||||
|
if (id.includes('node_modules')) {
|
||||||
|
return 'vendor';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
replace({
|
replace({
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { FC, useCallback, useEffect, useState } from 'react';
|
import { FC, useCallback, useEffect, useState } from 'react';
|
||||||
|
import Freighter from './components/freighter/Freighter';
|
||||||
import Pax from './components/pax/Pax';
|
import Pax from './components/pax/Pax';
|
||||||
import {
|
import {
|
||||||
COHERENT_COMM_BUS_WASM_CALL,
|
COHERENT_COMM_BUS_WASM_CALL,
|
||||||
@ -6,7 +7,7 @@ import {
|
|||||||
TFDI_SIMBRIEF_USERNAME_CALL,
|
TFDI_SIMBRIEF_USERNAME_CALL,
|
||||||
TFDI_SIMBRIEF_USERNAME_EVENT,
|
TFDI_SIMBRIEF_USERNAME_EVENT,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
import { WASMDataPax } from './types/WASMData';
|
import { WASMDataF, WASMDataPax } from './types/WASMData';
|
||||||
|
|
||||||
interface IAppProps {
|
interface IAppProps {
|
||||||
commBus: ViewListener.ViewListener;
|
commBus: ViewListener.ViewListener;
|
||||||
@ -14,7 +15,7 @@ interface IAppProps {
|
|||||||
|
|
||||||
const App: FC<IAppProps> = ({ commBus }) => {
|
const App: FC<IAppProps> = ({ commBus }) => {
|
||||||
const [SBUsername, setSBUsername] = useState<string>();
|
const [SBUsername, setSBUsername] = useState<string>();
|
||||||
const [WASMData, setWASMData] = useState<WASMDataPax>();
|
const [WASMData, setWASMData] = useState<WASMDataPax | WASMDataF>();
|
||||||
const [isReady, setIsReady] = useState(false);
|
const [isReady, setIsReady] = useState(false);
|
||||||
|
|
||||||
// CommBus
|
// CommBus
|
||||||
@ -46,9 +47,9 @@ const App: FC<IAppProps> = ({ commBus }) => {
|
|||||||
<div className="flex w-3/4 flex-col items-center">
|
<div className="flex w-3/4 flex-col items-center">
|
||||||
{isReady && WASMData ? (
|
{isReady && WASMData ? (
|
||||||
WASMData.userData.isCargo ? (
|
WASMData.userData.isCargo ? (
|
||||||
<>Not yet Implemented</>
|
<Freighter WASMData={WASMData as WASMDataF} username={SBUsername} />
|
||||||
) : (
|
) : (
|
||||||
<Pax WASMData={WASMData} username={SBUsername} />
|
<Pax WASMData={WASMData as WASMDataPax} username={SBUsername} />
|
||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
<h1 className="text-sm font-medium">LOADING</h1>
|
<h1 className="text-sm font-medium">LOADING</h1>
|
||||||
|
|||||||
@ -1,44 +1,40 @@
|
|||||||
| Department | Related to | Name | License period | Material not material | License type | Link | Remote version | Installed version | Defined version | Author |
|
| 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 | react | perpetual | material | MIT | git+https://github.com/facebook/react.git | 19.1.0 | 19.1.0 | ^19.1.0 | n/a |
|
||||||
| 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 | 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 | @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 | uuid | perpetual | material | MIT | git+https://github.com/uuidjs/uuid.git | 11.1.0 | 11.1.0 | ^11.1.0 | n/a |
|
||||||
| 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 | @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 | @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 <richard.a.harris@gmail.com> |
|
| 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 <richard.a.harris@gmail.com> |
|
||||||
| 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-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 | 15.3.1 | 15.3.1 | ^15.1.0 | Rich Harris <richard.a.harris@gmail.com> |
|
| 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 <richard.a.harris@gmail.com> |
|
||||||
| 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 <richard.a.harris@gmail.com> |
|
| 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 <richard.a.harris@gmail.com> |
|
||||||
| 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 <peter.placzek1996@gmail.com> |
|
| 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 <peter.placzek1996@gmail.com> |
|
||||||
| 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 | @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 | 18.3.23 | 18.3.23 | ^18.2.8 | n/a |
|
| 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 | 18.3.7 | 18.3.7 | ^18.2.4 | 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 | 9.0.8 | 9.0.8 | ^9.0.7 | 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.10.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.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.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.14 | Andrey Sitnik <andrey@sitnik.ru> |
|
| kessler | stuff | autoprefixer | perpetual | material | MIT | git+https://github.com/postcss/autoprefixer.git | 10.4.21 | 10.4.21 | ^10.4.21 | Andrey Sitnik <andrey@sitnik.ru> |
|
||||||
| 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 <me@kentcdodds.com> (https://kentcdodds.com) |
|
| 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 <me@kentcdodds.com> (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 <nicholas+npm@nczconsulting.com> |
|
| 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 <nicholas+npm@nczconsulting.com> |
|
||||||
| 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 <me@benmosher.com> |
|
| 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 <me@benmosher.com> |
|
||||||
| 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 <yannick.croissant+npm@gmail.com> |
|
| 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 <yannick.croissant+npm@gmail.com> |
|
||||||
| 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 | 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.7.2 | 6.7.2 | ^6.5.0 | Yaniv Kessler |
|
| 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.4 | 8.5.4 | ^8.4.24 | Andrey Sitnik <andrey@sitnik.ru> |
|
| kessler | stuff | postcss | perpetual | material | MIT | git+https://github.com/postcss/postcss.git | 8.5.5 | 8.5.4 | ^8.5.4 | Andrey Sitnik <andrey@sitnik.ru> |
|
||||||
| 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 | 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-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 | prettier | perpetual | material | MIT | git+https://github.com/prettier/prettier.git | 3.5.3 | 3.5.3 | ^3.5.3 | James Long |
|
||||||
| kessler | stuff | rimraf | perpetual | material | ISC | git://github.com/isaacs/rimraf.git | 5.0.10 | 5.0.10 | ^5.0.1 | Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/) |
|
| 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 | rollup | perpetual | material | MIT | git+https://github.com/rollup/rollup.git | 4.41.1 | 4.41.1 | ^4.3.1 | Rich Harris |
|
| kessler | stuff | rimraf | perpetual | material | ISC | git://github.com/isaacs/rimraf.git | 6.0.1 | 6.0.1 | ^6.0.1 | Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/) |
|
||||||
| 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 <vlad.shcherbin@gmail.com> |
|
| 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 <vlad.shcherbin@gmail.com> |
|
||||||
| 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-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-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 <david.j.houseknecht@gmail.com> |
|
| 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 <david.j.houseknecht@gmail.com> |
|
||||||
| 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 <benboba@gmail.com> |
|
| 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 <benboba@gmail.com> |
|
||||||
| 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 | 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 | 7.1.4 | 7.1.4 | ^7.1.0 | Spencer Miskoviak <smiskoviak@gmail.com> |
|
| 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 <smiskoviak@gmail.com> |
|
||||||
| 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 | typescript | perpetual | material | Apache-2.0 | git+https://github.com/microsoft/TypeScript.git | 5.8.3 | 5.8.3 | 5.8.3 | Microsoft Corp. |
|
||||||
|
|
||||||
|
|||||||
247
PackageSources/js-bundle/src/components/SBEntry/SBEntryF.tsx
Normal file
247
PackageSources/js-bundle/src/components/SBEntry/SBEntryF.tsx
Normal file
@ -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<SBEntryProps> = ({ 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<any>();
|
||||||
|
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 (
|
||||||
|
<>
|
||||||
|
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
|
||||||
|
<div className="relative flex w-full items-center justify-between rounded-md bg-zinc-600 p-2 px-4">
|
||||||
|
<label>Fuel ({WASMData.userData.isImperial ? 'lbs' : 'kg'})</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder=""
|
||||||
|
className={`w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right`}
|
||||||
|
value={fuel}
|
||||||
|
onChange={(e) => handleInput(e.target.value, WASMData.limits.maxFuel, setFuel)}
|
||||||
|
disabled={loadingState !== 'preview' || GSXActive()}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
className="middle none center rounded-lg bg-green-600 px-6 py-3 font-sans text-xs font-bold uppercase text-white shadow-md shadow-green-500/20 transition-all hover:shadow-lg hover:shadow-green-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
|
||||||
|
data-ripple-light="true"
|
||||||
|
onClick={() => {
|
||||||
|
SimVar.SetSimVarValue(
|
||||||
|
'L:MD11_EFB_PAYLOAD_FUEL',
|
||||||
|
'lbs',
|
||||||
|
WASMData.userData.isImperial ? fuel : fuel * 2.20462262185
|
||||||
|
);
|
||||||
|
SimVar.SetSimVarValue('L:MD11_EFB_READ_READY', 'bool', true);
|
||||||
|
setFuelEnabled(WASMData.livePayload.fuel === fuel);
|
||||||
|
}}
|
||||||
|
disabled={loadingState !== 'preview' || !fuelEnabled || GSXActive()}
|
||||||
|
>
|
||||||
|
Load Fuel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
|
||||||
|
<div className="relative flex w-full items-center justify-between rounded-t-md bg-zinc-600 p-2 px-4">
|
||||||
|
<label>Planned ZFW ({WASMData.userData.isImperial ? 'lbs' : 'kg'})</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder=""
|
||||||
|
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
|
||||||
|
value={SBPlan?.plannedZFW ?? 0}
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="relative flex w-full items-center justify-between bg-zinc-700 p-2 px-4">
|
||||||
|
<label>Planned GW ({WASMData.userData.isImperial ? 'lbs' : 'kg'})</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder=""
|
||||||
|
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
|
||||||
|
value={SBPlan?.plannedGW ?? 0}
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="relative flex w-full items-center justify-between rounded-b-md bg-zinc-600 p-2 px-4">
|
||||||
|
<label>
|
||||||
|
Target ZFWCG ({WASMData.limits.minCG} - {WASMData.limits.maxCG})
|
||||||
|
</label>
|
||||||
|
<CGSelect
|
||||||
|
minCG={WASMData.limits.minCG}
|
||||||
|
maxCG={WASMData.limits.maxCG}
|
||||||
|
value={CGTarget}
|
||||||
|
disabled={loadingState !== 'preview' || GSXActive()}
|
||||||
|
increase={() =>
|
||||||
|
setCGTarget((prev) => {
|
||||||
|
const _new = prev + 0.1;
|
||||||
|
updateData(_new);
|
||||||
|
return _new;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
decrease={() =>
|
||||||
|
setCGTarget((prev) => {
|
||||||
|
const _new = prev - 0.1;
|
||||||
|
updateData(_new);
|
||||||
|
return _new;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
|
||||||
|
<div className="relative flex w-full items-center justify-between rounded-t-md bg-zinc-600 p-2 px-4">
|
||||||
|
<label>
|
||||||
|
{loadingState !== 'loaded' && !GSXActive() ? 'Expected' : 'Actual'} ZFW (
|
||||||
|
{WASMData.userData.isImperial ? 'lbs' : 'kg'})
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder=""
|
||||||
|
className={`w-1/2 rounded-lg border ${ZFWValid() ? 'border-white' : 'border-red-500 text-red-500'} bg-zinc-700 px-3 py-2 text-right`}
|
||||||
|
disabled
|
||||||
|
value={ZFW()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="relative flex w-full items-center justify-between rounded-b-md bg-zinc-700 p-2 px-4">
|
||||||
|
<label>
|
||||||
|
{loadingState !== 'loaded' && !GSXActive() ? 'Expected' : 'Actual'} GW (
|
||||||
|
{WASMData.userData.isImperial ? 'lbs' : 'kg'})
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder=""
|
||||||
|
className={`w-1/2 rounded-lg border ${GWValid() ? 'border-white' : 'border-red-500 text-red-500'} bg-zinc-700 px-3 py-2 text-right`}
|
||||||
|
disabled
|
||||||
|
value={GW()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ActionBar
|
||||||
|
loadingState={loadingState}
|
||||||
|
loadDisabled={!GWValid() || SBInFlight}
|
||||||
|
GSXSync={WASMData.options.GSXSync}
|
||||||
|
GSXActive={GSXActive()}
|
||||||
|
importSB={handleSB}
|
||||||
|
load={() => {
|
||||||
|
setLoadingState('loaded');
|
||||||
|
|
||||||
|
loadAircraft();
|
||||||
|
}}
|
||||||
|
unload={() => {
|
||||||
|
setLoadingState('preview');
|
||||||
|
|
||||||
|
unloadAircraft();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SBEntryF;
|
||||||
@ -23,6 +23,7 @@ const SBEntryPax: FC<SBEntryProps> = ({ WASMData, loadingState, username, setLoa
|
|||||||
const [CGTarget, setCGTarget] = useState(WASMData.targetPayload.CGTarget);
|
const [CGTarget, setCGTarget] = useState(WASMData.targetPayload.CGTarget);
|
||||||
const [fuel, setFuel] = useState(Math.round(WASMData.livePayload.fuel));
|
const [fuel, setFuel] = useState(Math.round(WASMData.livePayload.fuel));
|
||||||
const [fuelEnabled, setFuelEnabled] = useState(true);
|
const [fuelEnabled, setFuelEnabled] = useState(true);
|
||||||
|
//eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const [SBPlan, setSBPlan] = useState<any>();
|
const [SBPlan, setSBPlan] = useState<any>();
|
||||||
const [SBInFlight, setSBInFlight] = useState(false);
|
const [SBInFlight, setSBInFlight] = useState(false);
|
||||||
|
|
||||||
@ -139,7 +140,7 @@ const SBEntryPax: FC<SBEntryProps> = ({ WASMData, loadingState, username, setLoa
|
|||||||
WASMData.userData.isImperial ? fuel : fuel * 2.20462262185
|
WASMData.userData.isImperial ? fuel : fuel * 2.20462262185
|
||||||
);
|
);
|
||||||
SimVar.SetSimVarValue('L:MD11_EFB_READ_READY', 'bool', true);
|
SimVar.SetSimVarValue('L:MD11_EFB_READ_READY', 'bool', true);
|
||||||
setFuelEnabled(false);
|
setFuelEnabled(WASMData.livePayload.fuel === fuel);
|
||||||
}}
|
}}
|
||||||
disabled={loadingState !== 'preview' || !fuelEnabled || GSXActive()}
|
disabled={loadingState !== 'preview' || !fuelEnabled || GSXActive()}
|
||||||
>
|
>
|
||||||
@ -160,7 +161,7 @@ const SBEntryPax: FC<SBEntryProps> = ({ WASMData, loadingState, username, setLoa
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative flex w-full items-center justify-between bg-zinc-700 p-2 px-4">
|
<div className="relative flex w-full items-center justify-between bg-zinc-700 p-2 px-4">
|
||||||
<label>Planned ZFW ({WASMData.userData.isImperial ? 'lbs' : 'kg'})</label>
|
<label>Planned GW ({WASMData.userData.isImperial ? 'lbs' : 'kg'})</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder=""
|
placeholder=""
|
||||||
|
|||||||
128
PackageSources/js-bundle/src/components/freighter/Freighter.tsx
Normal file
128
PackageSources/js-bundle/src/components/freighter/Freighter.tsx
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
import { FC, useState } from 'react';
|
||||||
|
import { GSX_SERVICE_CALLED, GSX_SERVICE_FINISHED } from '../../constants';
|
||||||
|
import { LoadingState } from '../../types/general';
|
||||||
|
import { WASMDataF } from '../../types/WASMData';
|
||||||
|
import Profile from '../profile/Profile';
|
||||||
|
import SBEntryF from '../SBEntry/SBEntryF';
|
||||||
|
import StationEntryF from '../stationEntry/StationEntryF';
|
||||||
|
import Tabbar from '../tabbar/Tabbar';
|
||||||
|
import ZFWEntryF from '../zfwEntry/ZFWEntryF';
|
||||||
|
|
||||||
|
interface FreighterProps {
|
||||||
|
WASMData: WASMDataF;
|
||||||
|
username?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Freighter: FC<FreighterProps> = ({ WASMData, username }) => {
|
||||||
|
const [selectedTab, setSelectedTab] = useState(0);
|
||||||
|
const [loadingState, setLoadingState] = useState<LoadingState>('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 (
|
||||||
|
<>
|
||||||
|
<Profile
|
||||||
|
type="PAX"
|
||||||
|
isER={WASMData.userData.isER}
|
||||||
|
upper1={`${upper1(GSXActive() ? 'loaded' : loadingState)}`}
|
||||||
|
upper2={`${upper2(GSXActive() ? 'loaded' : loadingState)}`}
|
||||||
|
upper3={`${upper3(GSXActive() ? 'loaded' : loadingState)}`}
|
||||||
|
upper4={`${upper4(GSXActive() ? 'loaded' : loadingState)}`}
|
||||||
|
lower1={`${lower1()}`}
|
||||||
|
lower2={`${lower2()}`}
|
||||||
|
OEW={`${OEW()}`}
|
||||||
|
crew={`${crew()}`}
|
||||||
|
unit={WASMData.userData.isImperial ? 'LBS' : 'KG'}
|
||||||
|
inPreview={loadingState !== 'loaded' && !GSXActive()}
|
||||||
|
CGs={CGs()}
|
||||||
|
/>
|
||||||
|
<Tabbar
|
||||||
|
tabs={
|
||||||
|
username ? ['Simbrief', 'ZFW', 'Passengers & Cargo', 'Options'] : ['ZFW', 'Passengers & Cargo', 'Options']
|
||||||
|
}
|
||||||
|
selectedTab={selectedTab}
|
||||||
|
setSelectedTab={setSelectedTab}
|
||||||
|
/>
|
||||||
|
{username && selectedTab === 0 && (
|
||||||
|
<SBEntryF
|
||||||
|
WASMData={WASMData}
|
||||||
|
loadingState={loadingState}
|
||||||
|
username={username}
|
||||||
|
setLoadingState={setLoadingState}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{((username && selectedTab === 1) || (!username && selectedTab === 0)) && (
|
||||||
|
<ZFWEntryF WASMData={WASMData} loadingState={loadingState} setLoadingState={setLoadingState} />
|
||||||
|
)}
|
||||||
|
{((username && selectedTab === 2) || (!username && selectedTab === 1)) && (
|
||||||
|
<StationEntryF WASMData={WASMData} loadingState={loadingState} setLoadingState={setLoadingState} />
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Freighter;
|
||||||
@ -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<StationEntryProps> = ({ 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 (
|
||||||
|
<>
|
||||||
|
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
|
||||||
|
<div className="relative flex w-full items-center justify-between rounded-md bg-zinc-600 p-2 px-4">
|
||||||
|
<label>Fuel ({WASMData.userData.isImperial ? 'lbs' : 'kg'})</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder=""
|
||||||
|
className={`w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right`}
|
||||||
|
value={fuel}
|
||||||
|
onChange={(e) => handleInput(e.target.value, WASMData.limits.maxFuel, setFuel)}
|
||||||
|
disabled={loadingState !== 'preview' || GSXActive()}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
className="middle none center rounded-lg bg-green-600 px-6 py-3 font-sans text-xs font-bold uppercase text-white shadow-md shadow-green-500/20 transition-all hover:shadow-lg hover:shadow-green-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
|
||||||
|
data-ripple-light="true"
|
||||||
|
onClick={() => {
|
||||||
|
SimVar.SetSimVarValue(
|
||||||
|
'L:MD11_EFB_PAYLOAD_FUEL',
|
||||||
|
'lbs',
|
||||||
|
WASMData.userData.isImperial ? fuel : fuel * 2.20462262185
|
||||||
|
);
|
||||||
|
SimVar.SetSimVarValue('L:MD11_EFB_READ_READY', 'bool', true);
|
||||||
|
setFuelEnabled(WASMData.livePayload.fuel === fuel);
|
||||||
|
}}
|
||||||
|
disabled={loadingState !== 'preview' || !fuelEnabled || GSXActive()}
|
||||||
|
>
|
||||||
|
Load Fuel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
|
||||||
|
<div className="relative flex w-full items-center justify-between rounded-t-md bg-zinc-600 p-2 px-4">
|
||||||
|
<label>Upper 1</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder=""
|
||||||
|
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
|
||||||
|
value={upper1}
|
||||||
|
onChange={(e) => handleInput(e.target.value, WASMData.limits.upper1, setUpper1)}
|
||||||
|
disabled={loadingState !== 'preview' || GSXActive()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="relative flex w-full items-center justify-between bg-zinc-700 p-2 px-4">
|
||||||
|
<label>Upper 2</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder=""
|
||||||
|
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
|
||||||
|
value={upper2}
|
||||||
|
onChange={(e) => handleInput(e.target.value, WASMData.limits.upper2, setUpper2)}
|
||||||
|
disabled={loadingState !== 'preview' || GSXActive()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="relative flex w-full items-center justify-between bg-zinc-600 p-2 px-4">
|
||||||
|
<label>Upper 3</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder=""
|
||||||
|
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
|
||||||
|
value={upper3}
|
||||||
|
onChange={(e) => handleInput(e.target.value, WASMData.limits.upper3, setUpper3)}
|
||||||
|
disabled={loadingState !== 'preview' || GSXActive()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="relative flex w-full items-center justify-between bg-zinc-700 p-2 px-4">
|
||||||
|
<label>Upper 4</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder=""
|
||||||
|
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
|
||||||
|
value={upper4}
|
||||||
|
onChange={(e) => handleInput(e.target.value, WASMData.limits.upper4, setUpper4)}
|
||||||
|
disabled={loadingState !== 'preview' || GSXActive()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="relative flex w-full items-center justify-between bg-zinc-600 p-2 px-4">
|
||||||
|
<label>Forward Cargo ({WASMData.userData.isImperial ? 'lbs' : 'kg'})</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder=""
|
||||||
|
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
|
||||||
|
value={lowerForward}
|
||||||
|
onChange={(e) => handleInput(e.target.value, WASMData.limits.lowerForward, setLowerForward)}
|
||||||
|
disabled={loadingState !== 'preview' || GSXActive()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="relative flex w-full items-center justify-between rounded-b-md bg-zinc-700 p-2 px-4">
|
||||||
|
<label>Aft Cargo ({WASMData.userData.isImperial ? 'lbs' : 'kg'})</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder=""
|
||||||
|
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
|
||||||
|
value={lowerRear}
|
||||||
|
onChange={(e) => handleInput(e.target.value, WASMData.limits.lowerRear, setLowerRear)}
|
||||||
|
disabled={loadingState !== 'preview' || GSXActive()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
|
||||||
|
<div className="relative flex w-full items-center justify-between rounded-t-md bg-zinc-600 p-2 px-4">
|
||||||
|
<label>
|
||||||
|
{loadingState !== 'loaded' && !GSXActive() ? 'Expected' : 'Actual'} ZFW (
|
||||||
|
{WASMData.userData.isImperial ? 'lbs' : 'kg'})
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder=""
|
||||||
|
className={`w-1/2 rounded-lg border ${ZFWValid() ? 'border-white' : 'border-red-500 text-red-500'} bg-zinc-700 px-3 py-2 text-right`}
|
||||||
|
disabled
|
||||||
|
value={ZFW()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="relative flex w-full items-center justify-between rounded-b-md bg-zinc-700 p-2 px-4">
|
||||||
|
<label>
|
||||||
|
{loadingState !== 'loaded' && !GSXActive() ? 'Expected' : 'Actual'} GW (
|
||||||
|
{WASMData.userData.isImperial ? 'lbs' : 'kg'})
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder=""
|
||||||
|
className={`w-1/2 rounded-lg border ${GWValid() ? 'border-white' : 'border-red-500 text-red-500'} bg-zinc-700 px-3 py-2 text-right`}
|
||||||
|
disabled
|
||||||
|
value={GW()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ActionBar
|
||||||
|
loadingState={loadingState}
|
||||||
|
loadDisabled={!ZFWValid() || !GWValid()}
|
||||||
|
GSXSync={WASMData.options.GSXSync}
|
||||||
|
GSXActive={GSXActive()}
|
||||||
|
load={() => {
|
||||||
|
setLoadingState('loaded');
|
||||||
|
|
||||||
|
loadAircraft();
|
||||||
|
}}
|
||||||
|
unload={() => {
|
||||||
|
setLoadingState('preview');
|
||||||
|
|
||||||
|
unloadAircraft();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default StationEntryF;
|
||||||
@ -114,7 +114,7 @@ const StationEntryPax: FC<StationEntryProps> = ({ WASMData, loadingState, setLoa
|
|||||||
WASMData.userData.isImperial ? fuel : fuel * 2.20462262185
|
WASMData.userData.isImperial ? fuel : fuel * 2.20462262185
|
||||||
);
|
);
|
||||||
SimVar.SetSimVarValue('L:MD11_EFB_READ_READY', 'bool', true);
|
SimVar.SetSimVarValue('L:MD11_EFB_READ_READY', 'bool', true);
|
||||||
setFuelEnabled(false);
|
setFuelEnabled(WASMData.livePayload.fuel === fuel);
|
||||||
}}
|
}}
|
||||||
disabled={loadingState !== 'preview' || !fuelEnabled || GSXActive()}
|
disabled={loadingState !== 'preview' || !fuelEnabled || GSXActive()}
|
||||||
>
|
>
|
||||||
|
|||||||
234
PackageSources/js-bundle/src/components/zfwEntry/ZFWEntryF.tsx
Normal file
234
PackageSources/js-bundle/src/components/zfwEntry/ZFWEntryF.tsx
Normal file
@ -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<ZFWEntryProps> = ({ 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 (
|
||||||
|
<>
|
||||||
|
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
|
||||||
|
<div className="relative flex w-full items-center justify-between rounded-md bg-zinc-600 p-2 px-4">
|
||||||
|
<label>Fuel ({WASMData.userData.isImperial ? 'lbs' : 'kg'})</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder=""
|
||||||
|
className={`w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right`}
|
||||||
|
value={fuel}
|
||||||
|
onChange={(e) => handleInput(e.target.value, WASMData.limits.maxFuel, setFuel)}
|
||||||
|
disabled={loadingState !== 'preview' || GSXActive()}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
className="middle none center rounded-lg bg-green-600 px-6 py-3 font-sans text-xs font-bold uppercase text-white shadow-md shadow-green-500/20 transition-all hover:shadow-lg hover:shadow-green-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
|
||||||
|
data-ripple-light="true"
|
||||||
|
onClick={() => {
|
||||||
|
SimVar.SetSimVarValue(
|
||||||
|
'L:MD11_EFB_PAYLOAD_FUEL',
|
||||||
|
'lbs',
|
||||||
|
WASMData.userData.isImperial ? fuel : fuel * 2.20462262185
|
||||||
|
);
|
||||||
|
SimVar.SetSimVarValue('L:MD11_EFB_READ_READY', 'bool', true);
|
||||||
|
setFuelEnabled(WASMData.livePayload.fuel === fuel);
|
||||||
|
}}
|
||||||
|
disabled={loadingState !== 'preview' || !fuelEnabled || GSXActive()}
|
||||||
|
>
|
||||||
|
Load Fuel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
|
||||||
|
<div className="relative flex w-full items-center justify-between rounded-t-md bg-zinc-600 p-2 px-4">
|
||||||
|
<label>Target ZFW ({WASMData.userData.isImperial ? 'lbs' : 'kg'})</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder=""
|
||||||
|
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
|
||||||
|
value={ZFWTarget}
|
||||||
|
onChange={(e) => handleInputZFW(e.target.value)}
|
||||||
|
onBlur={(e) => handleBlur(e.target.value)}
|
||||||
|
disabled={loadingState !== 'preview' || GSXActive()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="relative flex w-full items-center justify-between rounded-b-md bg-zinc-700 p-2 px-4">
|
||||||
|
<label>
|
||||||
|
Target ZFWCG ({WASMData.limits.minCG} - {WASMData.limits.maxCG})
|
||||||
|
</label>
|
||||||
|
<CGSelect
|
||||||
|
minCG={WASMData.limits.minCG}
|
||||||
|
maxCG={WASMData.limits.maxCG}
|
||||||
|
value={CGTarget}
|
||||||
|
disabled={loadingState !== 'preview' || GSXActive()}
|
||||||
|
increase={() =>
|
||||||
|
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;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
|
||||||
|
<div className="relative flex w-full items-center justify-between rounded-t-md bg-zinc-600 p-2 px-4">
|
||||||
|
<label>
|
||||||
|
{loadingState !== 'loaded' && !GSXActive() ? 'Expected' : 'Actual'} ZFW (
|
||||||
|
{WASMData.userData.isImperial ? 'lbs' : 'kg'})
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder=""
|
||||||
|
className={`w-1/2 rounded-lg border ${ZFWValid() ? 'border-white' : 'border-red-500 text-red-500'} bg-zinc-700 px-3 py-2 text-right`}
|
||||||
|
disabled
|
||||||
|
value={ZFW()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="relative flex w-full items-center justify-between rounded-b-md bg-zinc-700 p-2 px-4">
|
||||||
|
<label>
|
||||||
|
{loadingState !== 'loaded' && !GSXActive() ? 'Expected' : 'Actual'} GW (
|
||||||
|
{WASMData.userData.isImperial ? 'lbs' : 'kg'})
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder=""
|
||||||
|
className={`w-1/2 rounded-lg border ${GWValid() ? 'border-white' : 'border-red-500 text-red-500'} bg-zinc-700 px-3 py-2 text-right`}
|
||||||
|
disabled
|
||||||
|
value={GW()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ActionBar
|
||||||
|
loadingState={loadingState}
|
||||||
|
loadDisabled={!GWValid()}
|
||||||
|
GSXSync={WASMData.options.GSXSync}
|
||||||
|
GSXActive={GSXActive()}
|
||||||
|
load={() => {
|
||||||
|
setLoadingState('loaded');
|
||||||
|
|
||||||
|
loadAircraft();
|
||||||
|
}}
|
||||||
|
unload={() => {
|
||||||
|
setLoadingState('preview');
|
||||||
|
|
||||||
|
unloadAircraft();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ZFWEntryF;
|
||||||
@ -133,7 +133,7 @@ const ZFWEntryPax: FC<ZFWEntryProps> = ({ WASMData, loadingState, setLoadingStat
|
|||||||
WASMData.userData.isImperial ? fuel : fuel * 2.20462262185
|
WASMData.userData.isImperial ? fuel : fuel * 2.20462262185
|
||||||
);
|
);
|
||||||
SimVar.SetSimVarValue('L:MD11_EFB_READ_READY', 'bool', true);
|
SimVar.SetSimVarValue('L:MD11_EFB_READ_READY', 'bool', true);
|
||||||
setFuelEnabled(false);
|
setFuelEnabled(WASMData.livePayload.fuel === fuel);
|
||||||
}}
|
}}
|
||||||
disabled={loadingState !== 'preview' || !fuelEnabled || GSXActive()}
|
disabled={loadingState !== 'preview' || !fuelEnabled || GSXActive()}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -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;
|
|
||||||
};
|
|
||||||
@ -7,6 +7,15 @@ export interface WASMDataPax {
|
|||||||
options: Options;
|
options: Options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface WASMDataF {
|
||||||
|
livePayload: LivePayloadF;
|
||||||
|
targetPayload: TargetPayloadF;
|
||||||
|
GSX: GSX;
|
||||||
|
userData: UserData;
|
||||||
|
limits: LimitsF;
|
||||||
|
options: Options;
|
||||||
|
}
|
||||||
|
|
||||||
interface TargetPayload {
|
interface TargetPayload {
|
||||||
CGTarget: number;
|
CGTarget: number;
|
||||||
ZFWCG: number;
|
ZFWCG: number;
|
||||||
@ -5,6 +5,7 @@ const getSimBriefFlightPlan = async (simBriefUsername: string) => {
|
|||||||
try {
|
try {
|
||||||
response = await fetch(flightPlanURL);
|
response = await fetch(flightPlanURL);
|
||||||
success = true;
|
success = true;
|
||||||
|
//eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
response = e.response;
|
response = e.response;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,5 +21,5 @@ export const unloadAircraft = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const inRangeOf = (value: number, target: number, tolerance: number = 10) => {
|
export const inRangeOf = (value: number, target: number, tolerance: number = 10) => {
|
||||||
return Math.abs(value - target) < 10;
|
return Math.abs(value - target) < tolerance;
|
||||||
};
|
};
|
||||||
|
|||||||
306
PackageSources/wasm-module/freighter.cpp
Normal file
306
PackageSources/wasm-module/freighter.cpp
Normal file
@ -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);
|
||||||
|
}
|
||||||
36
PackageSources/wasm-module/freighter.h
Normal file
36
PackageSources/wasm-module/freighter.h
Normal file
@ -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 <MSFS/MSFS_WindowsTypes.h>
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <SimConnect.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
@ -342,27 +342,27 @@ extern "C" MSFS_CALLBACK void module_init(void) {
|
|||||||
log(stdout, MODULE_NAME"Data definitions created\n");
|
log(stdout, MODULE_NAME"Data definitions created\n");
|
||||||
|
|
||||||
// SimConnect Requests
|
// 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) {
|
if (hr != S_OK) {
|
||||||
log(stderr, MODULE_NAME"Could not request empty weight, terminating.\n");
|
log(stderr, MODULE_NAME"Could not request empty weight, terminating.\n");
|
||||||
return;
|
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) {
|
if (hr != S_OK) {
|
||||||
log(stderr, MODULE_NAME"Could not request payload pax, terminating.\n");
|
log(stderr, MODULE_NAME"Could not request payload pax, terminating.\n");
|
||||||
return;
|
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) {
|
if (hr != S_OK) {
|
||||||
log(stderr, MODULE_NAME"Could not request payload f, terminating.\n");
|
log(stderr, MODULE_NAME"Could not request payload f, terminating.\n");
|
||||||
return;
|
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) {
|
if (hr != S_OK) {
|
||||||
log(stderr, MODULE_NAME"Could not request fuel, terminating.\n");
|
log(stderr, MODULE_NAME"Could not request fuel, terminating.\n");
|
||||||
return;
|
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) {
|
if (hr != S_OK) {
|
||||||
log(stderr, MODULE_NAME"Could not request GSX, terminating.\n");
|
log(stderr, MODULE_NAME"Could not request GSX, terminating.\n");
|
||||||
return;
|
return;
|
||||||
@ -507,8 +507,9 @@ int receiveData(const char* buf) {
|
|||||||
double CGTarget = document["CGTarget"].GetDouble();
|
double CGTarget = document["CGTarget"].GetDouble();
|
||||||
|
|
||||||
if (UserData->isCargo) {
|
if (UserData->isCargo) {
|
||||||
targetPaxPayloadData->CGTarget = CGTarget;
|
targetFPayloadData->CGTarget = CGTarget;
|
||||||
//TODO: F load
|
|
||||||
|
distribute(targetFPayloadData, liveFuelData, cargo, UserData->isImperial, UserData->isER);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!document.HasMember("numPax")) return -1;
|
if (!document.HasMember("numPax")) return -1;
|
||||||
@ -526,8 +527,8 @@ int receiveData(const char* buf) {
|
|||||||
double CGTarget = document["CGTarget"].GetDouble();
|
double CGTarget = document["CGTarget"].GetDouble();
|
||||||
|
|
||||||
if (UserData->isCargo) {
|
if (UserData->isCargo) {
|
||||||
targetPaxPayloadData->CGTarget = CGTarget;
|
targetFPayloadData->CGTarget = CGTarget;
|
||||||
//TODO: F load
|
distribute(targetFPayloadData, liveFuelData, ZFWTarget, UserData->isImperial, UserData->isER);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
targetPaxPayloadData->CGTarget = CGTarget;
|
targetPaxPayloadData->CGTarget = CGTarget;
|
||||||
@ -538,7 +539,17 @@ int receiveData(const char* buf) {
|
|||||||
// Station Entry
|
// Station Entry
|
||||||
case 2: {
|
case 2: {
|
||||||
if (UserData->isCargo) {
|
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 {
|
else {
|
||||||
if (!document.HasMember("business1") || !document.HasMember("business2") ||
|
if (!document.HasMember("business1") || !document.HasMember("business2") ||
|
||||||
@ -558,7 +569,7 @@ int receiveData(const char* buf) {
|
|||||||
// Trigger load
|
// Trigger load
|
||||||
case 3: {
|
case 3: {
|
||||||
if (UserData->isCargo) {
|
if (UserData->isCargo) {
|
||||||
//TODO: F load
|
load(targetFPayloadData, simConnect, UserData->isImperial);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
load(targetPaxPayloadData, simConnect, UserData->isImperial);
|
load(targetPaxPayloadData, simConnect, UserData->isImperial);
|
||||||
@ -569,7 +580,7 @@ int receiveData(const char* buf) {
|
|||||||
// Trigger unload
|
// Trigger unload
|
||||||
case 4: {
|
case 4: {
|
||||||
if (UserData->isCargo) {
|
if (UserData->isCargo) {
|
||||||
//TODO: F load
|
unloadF(simConnect, UserData->isER);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unload(simConnect, UserData->isER);
|
unload(simConnect, UserData->isER);
|
||||||
@ -635,8 +646,7 @@ void sendData () {
|
|||||||
livePayload.AddMember("lowerRear", FROM_POUNDS(UserData->isImperial, liveFPayloadData->lowerRear), allocator);
|
livePayload.AddMember("lowerRear", FROM_POUNDS(UserData->isImperial, liveFPayloadData->lowerRear), allocator);
|
||||||
livePayload.AddMember("total", FROM_POUNDS(UserData->isImperial, liveFPayloadData->total), allocator);
|
livePayload.AddMember("total", FROM_POUNDS(UserData->isImperial, liveFPayloadData->total), allocator);
|
||||||
// CGs
|
// 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("ZFWCG", liveFPayloadData->ZFWCG, allocator);
|
||||||
livePayload.AddMember("TOCG", liveFPayloadData->TOCG, allocator);
|
livePayload.AddMember("TOCG", liveFPayloadData->TOCG, allocator);
|
||||||
}
|
}
|
||||||
@ -695,8 +705,7 @@ void sendData () {
|
|||||||
targetPayload.AddMember("total", targetFPayloadData->total, allocator);
|
targetPayload.AddMember("total", targetFPayloadData->total, allocator);
|
||||||
targetPayload.AddMember("CGTarget", targetFPayloadData->CGTarget, allocator);
|
targetPayload.AddMember("CGTarget", targetFPayloadData->CGTarget, allocator);
|
||||||
// CGs
|
// 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("ZFWCG", targetFPayloadData->ZFWCG, allocator);
|
||||||
targetPayload.AddMember("TOCG", targetFPayloadData->TOCG, 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("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);
|
limits.AddMember("maxTOW", UserData->isER ? MAX_TOW_ER(UserData->isImperial) : MAX_TOW(UserData->isImperial), allocator);
|
||||||
// Cargo Only
|
// Cargo Only
|
||||||
// TODO: Actual F limits
|
|
||||||
if (UserData->isCargo) {
|
if (UserData->isCargo) {
|
||||||
limits.AddMember("upper1", -1, allocator);
|
limits.AddMember("upper1", MAX_UPPER_CARGO(UserData->isImperial), allocator);
|
||||||
limits.AddMember("upper2", -1, allocator);
|
limits.AddMember("upper2", MAX_UPPER_CARGO(UserData->isImperial), allocator);
|
||||||
limits.AddMember("upper3", -1, allocator);
|
limits.AddMember("upper3", MAX_UPPER_CARGO(UserData->isImperial), allocator);
|
||||||
limits.AddMember("upper4", -1, allocator);
|
limits.AddMember("upper4", MAX_UPPER_CARGO(UserData->isImperial), allocator);
|
||||||
limits.AddMember("lowerForward", MAX_FRONT_CARGO(UserData->isImperial), allocator);
|
limits.AddMember("lowerForward", MAX_FRONT_CARGO(UserData->isImperial), allocator);
|
||||||
limits.AddMember("lowerRear", MAX_REAR_CARGO(UserData->isImperial, UserData->isER), allocator);
|
limits.AddMember("lowerRear", MAX_REAR_CARGO(UserData->isImperial, UserData->isER), allocator);
|
||||||
// TODO: Actual F limit
|
limits.AddMember("maxZFW", MAX_F_ZFW(UserData->isImperial), allocator);
|
||||||
//limits.AddMember("MaxZFW", MAX_F_ZFW, allocator);
|
|
||||||
limits.AddMember("minZFW", targetFPayloadData->empty + targetFPayloadData->leftAux + targetFPayloadData->rightAux, allocator);
|
limits.AddMember("minZFW", targetFPayloadData->empty + targetFPayloadData->leftAux + targetFPayloadData->rightAux, allocator);
|
||||||
}
|
}
|
||||||
// Pax only
|
// Pax only
|
||||||
@ -858,7 +865,18 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContex
|
|||||||
if (GSXData->boardingState == GSX_SERVICE_ACTIVE) {
|
if (GSXData->boardingState == GSX_SERVICE_ACTIVE) {
|
||||||
double cargoBoarded = GSXData->cargoBoarded;
|
double cargoBoarded = GSXData->cargoBoarded;
|
||||||
if (UserData->isCargo) {
|
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 {
|
else {
|
||||||
double passengersBoarded = GSXData->passengersBoarded;
|
double passengersBoarded = GSXData->passengersBoarded;
|
||||||
@ -883,7 +901,18 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContex
|
|||||||
if (GSXData->deboardingState == GSX_SERVICE_ACTIVE) {
|
if (GSXData->deboardingState == GSX_SERVICE_ACTIVE) {
|
||||||
double cargoDeboarded = GSXData->cargoDeboarded;
|
double cargoDeboarded = GSXData->cargoDeboarded;
|
||||||
if (UserData->isCargo) {
|
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 {
|
else {
|
||||||
double passengersDeboarded = GSXData->passengersDeboarded;
|
double passengersDeboarded = GSXData->passengersDeboarded;
|
||||||
|
|||||||
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "pax.h"
|
#include "pax.h"
|
||||||
|
#include "freighter.h"
|
||||||
|
|
||||||
#define MODULE_NAME "[KHOFMANN TFDi MD-11 Load Manager] "
|
#define MODULE_NAME "[KHOFMANN TFDi MD-11 Load Manager] "
|
||||||
|
|
||||||
|
|||||||
@ -283,10 +283,12 @@
|
|||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="freighter.cpp" />
|
||||||
<ClCompile Include="load-manager.cpp" />
|
<ClCompile Include="load-manager.cpp" />
|
||||||
<ClCompile Include="pax.cpp" />
|
<ClCompile Include="pax.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="freighter.h" />
|
||||||
<ClInclude Include="load-manager.h" />
|
<ClInclude Include="load-manager.h" />
|
||||||
<ClInclude Include="pax.h" />
|
<ClInclude Include="pax.h" />
|
||||||
<ClInclude Include="types.h" />
|
<ClInclude Include="types.h" />
|
||||||
|
|||||||
@ -7,6 +7,9 @@
|
|||||||
<ClCompile Include="pax.cpp">
|
<ClCompile Include="pax.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="freighter.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="pax.h">
|
<ClInclude Include="pax.h">
|
||||||
@ -18,6 +21,9 @@
|
|||||||
<ClInclude Include="types.h">
|
<ClInclude Include="types.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="freighter.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="Header Files">
|
<Filter Include="Header Files">
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#include "pax.h"
|
#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) {
|
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
|
// Find payload, num pax and extra cargo
|
||||||
double payload = ZFWTarget - targetPayload->empty - targetPayload->pilot - targetPayload->firstOfficer - targetPayload->engineer -
|
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);
|
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) {
|
void distribute(paxPayloadData_t* const targetPayload, const FuelData_t* const fuel, unsigned short numPax, unsigned int cargo, const bool isImperial, const bool isER) {
|
||||||
// Clear
|
// Clear
|
||||||
targetPayload->paxCount.business1 = targetPayload->paxCount.business2 = targetPayload->paxCount.economy1 = targetPayload->paxCount.economy2 =
|
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);
|
*TOCG = TO_PERCENT_MAC(totalMoment / totalWeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void load(const paxPayloadData_t* const targetPayload, const HANDLE simConnect, const bool isImperial) {
|
void load(const paxPayloadData_t* const targetPayload, const HANDLE simConnect, const bool isImperial) {
|
||||||
paxPayloadData_t localPayload = {};
|
paxPayloadData_t localPayload = {};
|
||||||
memcpy(&localPayload, targetPayload, sizeof(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.leftAux = localPayload.rightAux = isER ? AUX_WEIGHT(true) : 0;
|
||||||
localPayload.pilot = localPayload.firstOfficer = localPayload.engineer = PILOT_WEIGHT(true);
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,8 +17,9 @@
|
|||||||
|
|
||||||
//PMC pallet due to 104in door
|
//PMC pallet due to 104in door
|
||||||
#define MAX_FRONT_CARGO(IS_IMPERIAL) ((IS_IMPERIAL) ? (6.0 * 15000.0) : (6.0 * 6804.0))
|
#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
|
//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
|
// All actual Business seats
|
||||||
#define MAX_BUSINESS_1 30
|
#define MAX_BUSINESS_1 30
|
||||||
@ -33,6 +34,7 @@
|
|||||||
|
|
||||||
// Max ZFW
|
// Max ZFW
|
||||||
#define MAX_PAX_ZFW(IS_IMPERIAL) ((IS_IMPERIAL) ? (400000) : (181437))
|
#define MAX_PAX_ZFW(IS_IMPERIAL) ((IS_IMPERIAL) ? (400000) : (181437))
|
||||||
|
#define MAX_F_ZFW(IS_IMPERIAL) ((IS_IMPERIAL) ? (451300) : (204706))
|
||||||
|
|
||||||
// Max TOW
|
// Max TOW
|
||||||
#define MAX_TOW(IS_IMPERIAL) ((IS_IMPERIAL) ? (625500) : (283722))
|
#define MAX_TOW(IS_IMPERIAL) ((IS_IMPERIAL) ? (625500) : (283722))
|
||||||
@ -63,6 +65,15 @@
|
|||||||
#define ARM_PAX_ECONOMY2_CENTER -600.0
|
#define ARM_PAX_ECONOMY2_CENTER -600.0
|
||||||
#define ARM_PAX_ECONOMY2_RIGHT -600.0
|
#define ARM_PAX_ECONOMY2_RIGHT -600.0
|
||||||
#define ARM_PAX_CABIN_CREW_REAR -660.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
|
// Shared part 2
|
||||||
#define ARM_FORWARD_CARGO 360.0
|
#define ARM_FORWARD_CARGO 360.0
|
||||||
#define ARM_REAR_CARGO -360.0
|
#define ARM_REAR_CARGO -360.0
|
||||||
@ -225,6 +236,13 @@ typedef struct {
|
|||||||
double CGTarget;
|
double CGTarget;
|
||||||
double ZFWCG;
|
double ZFWCG;
|
||||||
double TOCG;
|
double TOCG;
|
||||||
|
struct stations {
|
||||||
|
unsigned int upper1;
|
||||||
|
unsigned int upper2;
|
||||||
|
unsigned int upper3;
|
||||||
|
unsigned int upper4;
|
||||||
|
unsigned int total;
|
||||||
|
} stations;
|
||||||
} fPayloadData_t;
|
} fPayloadData_t;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// SimConnect mapped
|
// SimConnect mapped
|
||||||
|
|||||||
13
README.md
13
README.md
@ -1,3 +1,7 @@
|
|||||||
|
# How to build
|
||||||
|
|
||||||
|
After building WASM, run `copy-debug` or `copy-release` to copy WASM module.
|
||||||
|
|
||||||
# Sources
|
# Sources
|
||||||
|
|
||||||
- https://www.boeing.com/content/dam/boeing/boeingdotcom/company/about_bca/startup/pdf/freighters/MD11BCF.pdf
|
- https://www.boeing.com/content/dam/boeing/boeingdotcom/company/about_bca/startup/pdf/freighters/MD11BCF.pdf
|
||||||
@ -7,10 +11,15 @@
|
|||||||
|
|
||||||
TODO:
|
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
|
- JS
|
||||||
- Persist SB data across page changes
|
- Persist SB data across page changes
|
||||||
- Duplicate Input pages for F
|
|
||||||
- Options (GSX sync, pax/bag weights)
|
- Options (GSX sync, pax/bag weights)
|
||||||
|
- Types for SB plan (only what I need)
|
||||||
- WASM
|
- WASM
|
||||||
- Custom pax/bag weights
|
- Custom pax/bag weights
|
||||||
- F loading stuff
|
|
||||||
|
|||||||
4
copy-debug.ps1
Normal file
4
copy-debug.ps1
Normal file
@ -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
|
||||||
4
copy-release.ps1
Normal file
4
copy-release.ps1
Normal file
@ -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
|
||||||
Loading…
x
Reference in New Issue
Block a user