Non GSX Fuel setting

This commit is contained in:
Kilian Hofmann 2026-02-12 21:27:12 +01:00
parent 310b5f39dc
commit 122a93461d
31 changed files with 2328 additions and 8267 deletions

6
.clang-format Normal file
View File

@ -0,0 +1,6 @@
---
BasedOnStyle: LLVM
ColumnLimit: 130
IndentCaseLabels: true
AllowShortIfStatementsOnASingleLine: Always
AllowShortLoopsOnASingleLine: true

View File

@ -18,5 +18,8 @@
}, },
"[xml]": { "[xml]": {
"editor.defaultFormatter": "redhat.vscode-xml" "editor.defaultFormatter": "redhat.vscode-xml"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
} }
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "tfdidesign-md11-load-manager", "name": "tfdidesign-md11-load-manager",
"version": "0.1.188", "version": "0.2.8",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"type": "module", "type": "module",

View File

@ -2,7 +2,7 @@ import { FC, useEffect, useState } from 'react';
import { WASMDataF } from '../../types/WASMData'; import { WASMDataF } from '../../types/WASMData';
import { LoadingState, SimBrief } from '../../types/general'; import { LoadingState, SimBrief } from '../../types/general';
import { ImportFlightPlanKH } from '../../utils/TFDISBImport'; import { ImportFlightPlanKH } from '../../utils/TFDISBImport';
import { CoherentCallSBEntryF, inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils'; import { CoherentCallSBEntryF, loadAircraft, unloadAircraft } from '../../utils/utils';
import CGSelect from '../CGSelect/CGSelect'; import CGSelect from '../CGSelect/CGSelect';
import ActionBar from '../actionbar/ActionBar'; import ActionBar from '../actionbar/ActionBar';
import Input from '../input/Input'; import Input from '../input/Input';
@ -16,8 +16,7 @@ interface SBEntryProps {
const SBEntryF: FC<SBEntryProps> = ({ WASMData, loadingState, gsxActive, setLoadingState }) => { const SBEntryF: FC<SBEntryProps> = ({ WASMData, loadingState, gsxActive, setLoadingState }) => {
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.targetPayload.fuel));
const [fuelEnabled, setFuelEnabled] = useState(true);
const [SBInFlight, setSBInFlight] = useState(false); const [SBInFlight, setSBInFlight] = useState(false);
// FROM EFB // FROM EFB
@ -52,6 +51,11 @@ const SBEntryF: FC<SBEntryProps> = ({ WASMData, loadingState, gsxActive, setLoad
} }
}; };
const updateData = (SBPlan?: SimBrief, _fuel?: number) => {
CoherentCallSBEntryF(CGTarget, _fuel ?? fuel, SBPlan);
};
useEffect(() => updateData(), [CGTarget, fuel]);
useEffect(() => { useEffect(() => {
if (!simBrief || gsxActive) return; if (!simBrief || gsxActive) return;
@ -70,12 +74,13 @@ const SBEntryF: FC<SBEntryProps> = ({ WASMData, loadingState, gsxActive, setLoad
return; return;
} }
updateData(undefined, SBResponse.message as SimBrief); const _fuel = parseFloat((SBResponse.message as SimBrief).fuel as unknown as string) ?? 0;
setFuel(parseFloat((SBResponse.message as SimBrief).fuel as unknown as string) ?? 0); updateData(SBResponse.message as SimBrief, _fuel);
setFuel(_fuel);
setSBInFlight(false); setSBInFlight(false);
}, [simBrief, gsxActive]); }, [simBrief, gsxActive]);
useEffect( useEffect(
() => () =>
setFuel((prev) => { setFuel((prev) => {
@ -84,13 +89,6 @@ const SBEntryF: FC<SBEntryProps> = ({ WASMData, loadingState, gsxActive, setLoad
}), }),
[WASMData.userData.isER] [WASMData.userData.isER]
); );
useEffect(() => {
setFuelEnabled((prev) => (!prev ? inRangeOf(Math.round(WASMData.livePayload.fuel), fuel) : prev));
}, [WASMData.livePayload.fuel]);
const updateData = (_CGTarget?: number, SBPlan?: SimBrief) => {
CoherentCallSBEntryF(_CGTarget ?? CGTarget, SBPlan);
};
return ( return (
<> <>
@ -106,22 +104,6 @@ const SBEntryF: FC<SBEntryProps> = ({ WASMData, loadingState, gsxActive, setLoad
onChange={(value) => handleInput(value, WASMData.limits.maxFuel, setFuel)} onChange={(value) => handleInput(value, WASMData.limits.maxFuel, setFuel)}
disabled={loadingState !== 'preview' || gsxActive} 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> </div>
</div> </div>
@ -164,14 +146,12 @@ const SBEntryF: FC<SBEntryProps> = ({ WASMData, loadingState, gsxActive, setLoad
increase={() => increase={() =>
setCGTarget((prev) => { setCGTarget((prev) => {
const _new = prev + 0.1; const _new = prev + 0.1;
updateData(_new);
return _new; return _new;
}) })
} }
decrease={() => decrease={() =>
setCGTarget((prev) => { setCGTarget((prev) => {
const _new = prev - 0.1; const _new = prev - 0.1;
updateData(_new);
return _new; return _new;
}) })
} }

View File

@ -2,7 +2,7 @@ import { FC, useEffect, useState } from 'react';
import { WASMDataPax } from '../../types/WASMData'; import { WASMDataPax } from '../../types/WASMData';
import { LoadingState, SimBrief } from '../../types/general'; import { LoadingState, SimBrief } from '../../types/general';
import { ImportFlightPlanKH } from '../../utils/TFDISBImport'; import { ImportFlightPlanKH } from '../../utils/TFDISBImport';
import { CoherentCallSBEntryPax, inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils'; import { CoherentCallSBEntryPax, loadAircraft, unloadAircraft } from '../../utils/utils';
import CGSelect from '../CGSelect/CGSelect'; import CGSelect from '../CGSelect/CGSelect';
import ActionBar from '../actionbar/ActionBar'; import ActionBar from '../actionbar/ActionBar';
import Input from '../input/Input'; import Input from '../input/Input';
@ -16,7 +16,7 @@ interface SBEntryProps {
const SBEntryPax: FC<SBEntryProps> = ({ WASMData, loadingState, gsxActive, setLoadingState }) => { const SBEntryPax: FC<SBEntryProps> = ({ WASMData, loadingState, gsxActive, setLoadingState }) => {
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.targetPayload.fuel));
const [fuelEnabled, setFuelEnabled] = useState(true); const [fuelEnabled, setFuelEnabled] = useState(true);
const [SBInFlight, setSBInFlight] = useState(false); const [SBInFlight, setSBInFlight] = useState(false);
@ -52,6 +52,10 @@ const SBEntryPax: FC<SBEntryProps> = ({ WASMData, loadingState, gsxActive, setLo
} }
}; };
const updateData = (SBPlan?: SimBrief, _fuel?: number) => {
CoherentCallSBEntryPax(CGTarget, _fuel ?? fuel, SBPlan);
};
useEffect(() => { useEffect(() => {
if (!simBrief || gsxActive) return; if (!simBrief || gsxActive) return;
@ -70,12 +74,17 @@ const SBEntryPax: FC<SBEntryProps> = ({ WASMData, loadingState, gsxActive, setLo
return; return;
} }
updateData(undefined, SBResponse.message as SimBrief); const _fuel = parseFloat((SBResponse.message as SimBrief).fuel as unknown as string) ?? 0;
updateData(SBResponse.message as SimBrief, _fuel);
setFuel(_fuel);
setFuel(parseFloat((SBResponse.message as SimBrief).fuel as unknown as string) ?? 0); setFuel(parseFloat((SBResponse.message as SimBrief).fuel as unknown as string) ?? 0);
setSBInFlight(false); setSBInFlight(false);
}, [simBrief, gsxActive]); }, [simBrief, gsxActive]);
useEffect(() => updateData(), [CGTarget, fuel]);
useEffect( useEffect(
() => () =>
setFuel((prev) => { setFuel((prev) => {
@ -84,13 +93,6 @@ const SBEntryPax: FC<SBEntryProps> = ({ WASMData, loadingState, gsxActive, setLo
}), }),
[WASMData.userData.isER] [WASMData.userData.isER]
); );
useEffect(() => {
setFuelEnabled((prev) => (!prev ? inRangeOf(Math.round(WASMData.livePayload.fuel), fuel) : prev));
}, [WASMData.livePayload.fuel]);
const updateData = (_CGTarget?: number, SBPlan?: SimBrief) => {
CoherentCallSBEntryPax(_CGTarget ?? CGTarget, SBPlan);
};
return ( return (
<> <>
@ -106,22 +108,6 @@ const SBEntryPax: FC<SBEntryProps> = ({ WASMData, loadingState, gsxActive, setLo
onChange={(value) => handleInput(value, WASMData.limits.maxFuel, setFuel)} onChange={(value) => handleInput(value, WASMData.limits.maxFuel, setFuel)}
disabled={loadingState !== 'preview' || gsxActive} 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> </div>
</div> </div>
@ -164,14 +150,12 @@ const SBEntryPax: FC<SBEntryProps> = ({ WASMData, loadingState, gsxActive, setLo
increase={() => increase={() =>
setCGTarget((prev) => { setCGTarget((prev) => {
const _new = prev + 0.1; const _new = prev + 0.1;
updateData(_new);
return _new; return _new;
}) })
} }
decrease={() => decrease={() =>
setCGTarget((prev) => { setCGTarget((prev) => {
const _new = prev - 0.1; const _new = prev - 0.1;
updateData(_new);
return _new; return _new;
}) })
} }

View File

@ -48,7 +48,7 @@ const OptionsF: FC<OptionsFProps> = ({ WASMData, loadingState, gsxActive }) => {
<td className="p-1 px-2">0 {WASMData.userData.isImperial ? 'lbs' : 'kg'}</td> <td className="p-1 px-2">0 {WASMData.userData.isImperial ? 'lbs' : 'kg'}</td>
</tr> </tr>
<tr> <tr>
<td className="p-1 px-2">Empty Weight</td> <td className="p-1 px-2">Empty Weight (inc. crew)</td>
<td className="p-1 px-2">{WASMData.userData.isImperial ? '249537 lbs' : '113188 kg'}</td> <td className="p-1 px-2">{WASMData.userData.isImperial ? '249537 lbs' : '113188 kg'}</td>
</tr> </tr>
<tr> <tr>
@ -84,7 +84,7 @@ const OptionsF: FC<OptionsFProps> = ({ WASMData, loadingState, gsxActive }) => {
<td className="p-1 px-2">0 {WASMData.userData.isImperial ? 'lbs' : 'kg'}</td> <td className="p-1 px-2">0 {WASMData.userData.isImperial ? 'lbs' : 'kg'}</td>
</tr> </tr>
<tr> <tr>
<td className="p-1 px-2">Empty Weight</td> <td className="p-1 px-2">Empty Weight (inc. crew)</td>
<td className="p-1 px-2">{WASMData.userData.isImperial ? '249137 lbs' : '113006 kg'}</td> <td className="p-1 px-2">{WASMData.userData.isImperial ? '249137 lbs' : '113006 kg'}</td>
</tr> </tr>
<tr> <tr>

View File

@ -2,8 +2,8 @@ import { FC, useEffect, useState } from 'react';
import { LoadingState } from '../../types/general'; import { LoadingState } from '../../types/general';
import { WASMDataPax } from '../../types/WASMData'; import { WASMDataPax } from '../../types/WASMData';
import { CoherentCallGSXReset, CoherentCallOptionsSet } from '../../utils/utils'; import { CoherentCallGSXReset, CoherentCallOptionsSet } from '../../utils/utils';
import ToggleComponentKH from '../toggleComponent/ToggleComponent';
import Input from '../input/Input'; import Input from '../input/Input';
import ToggleComponentKH from '../toggleComponent/ToggleComponent';
interface OptionsPaxProps { interface OptionsPaxProps {
WASMData: WASMDataPax; WASMData: WASMDataPax;
@ -105,8 +105,8 @@ const OptionsPax: FC<OptionsPaxProps> = ({ WASMData, loadingState, gsxActive })
</td> </td>
</tr> </tr>
<tr> <tr>
<td className="p-1 px-2">Empty Weight</td> <td className="p-1 px-2">Empty Weight (inc. crew)</td>
<td className="p-1 px-2">{WASMData.userData.isImperial ? '284375 lbs' : '128991 kg'}</td> <td className="p-1 px-2">{WASMData.userData.isImperial ? '286465 lbs' : '129937 kg'}</td>
</tr> </tr>
<tr> <tr>
<td className="p-1 px-2">Max Zero Fuel Weight</td> <td className="p-1 px-2">Max Zero Fuel Weight</td>
@ -145,8 +145,8 @@ const OptionsPax: FC<OptionsPaxProps> = ({ WASMData, loadingState, gsxActive })
</td> </td>
</tr> </tr>
<tr> <tr>
<td className="p-1 px-2">Empty Weight</td> <td className="p-1 px-2">Empty Weight (inc. crew)</td>
<td className="p-1 px-2">{WASMData.userData.isImperial ? '283975 lbs' : '128809 kg'}</td> <td className="p-1 px-2">{WASMData.userData.isImperial ? '286065 lbs' : '129755 kg'}</td>
</tr> </tr>
<tr> <tr>
<td className="p-1 px-2">Max Zero Fuel Weight</td> <td className="p-1 px-2">Max Zero Fuel Weight</td>

View File

@ -1,7 +1,7 @@
import { FC, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { LoadingState } from '../../types/general'; import { LoadingState } from '../../types/general';
import { WASMDataF } from '../../types/WASMData'; import { WASMDataF } from '../../types/WASMData';
import { CoherentCallStationEntryF, inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils'; import { CoherentCallStationEntryF, loadAircraft, unloadAircraft } from '../../utils/utils';
import ActionBar from '../actionbar/ActionBar'; import ActionBar from '../actionbar/ActionBar';
import Input from '../input/Input'; import Input from '../input/Input';
@ -19,8 +19,7 @@ const StationEntryF: FC<StationEntryProps> = ({ WASMData, loadingState, gsxActiv
const [upper4, setUpper4] = useState(WASMData.targetPayload.upper4); const [upper4, setUpper4] = useState(WASMData.targetPayload.upper4);
const [lowerForward, setLowerForward] = useState(WASMData.targetPayload.lowerForward); const [lowerForward, setLowerForward] = useState(WASMData.targetPayload.lowerForward);
const [lowerRear, setLowerRear] = useState(WASMData.targetPayload.lowerRear); const [lowerRear, setLowerRear] = useState(WASMData.targetPayload.lowerRear);
const [fuel, setFuel] = useState(Math.round(WASMData.livePayload.fuel)); const [fuel, setFuel] = useState(Math.round(WASMData.targetPayload.fuel));
const [fuelEnabled, setFuelEnabled] = useState(true);
const ZFW = () => { const ZFW = () => {
if (loadingState !== 'loaded' && !gsxActive) return Math.round(WASMData.targetPayload.total); if (loadingState !== 'loaded' && !gsxActive) return Math.round(WASMData.targetPayload.total);
@ -52,10 +51,10 @@ const StationEntryF: FC<StationEntryProps> = ({ WASMData, loadingState, gsxActiv
}; };
const updateData = () => { const updateData = () => {
CoherentCallStationEntryF(upper1, upper2, upper3, upper4, lowerForward, lowerRear); CoherentCallStationEntryF(upper1, upper2, upper3, upper4, lowerForward, lowerRear, fuel);
}; };
useEffect(() => updateData(), [upper1, upper2, upper3, upper4, lowerForward, lowerRear]); useEffect(() => updateData(), [upper1, upper2, upper3, upper4, lowerForward, lowerRear, fuel]);
useEffect( useEffect(
() => () =>
setFuel((prev) => { setFuel((prev) => {
@ -64,9 +63,6 @@ const StationEntryF: FC<StationEntryProps> = ({ WASMData, loadingState, gsxActiv
}), }),
[WASMData.userData.isER] [WASMData.userData.isER]
); );
useEffect(() => {
setFuelEnabled((prev) => (!prev ? inRangeOf(Math.round(WASMData.livePayload.fuel), fuel) : prev));
}, [WASMData.livePayload.fuel]);
return ( return (
<> <>
@ -82,22 +78,6 @@ const StationEntryF: FC<StationEntryProps> = ({ WASMData, loadingState, gsxActiv
onChange={(value) => handleInput(value, WASMData.limits.maxFuel, setFuel)} onChange={(value) => handleInput(value, WASMData.limits.maxFuel, setFuel)}
disabled={loadingState !== 'preview' || gsxActive} 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> </div>
</div> </div>

View File

@ -1,7 +1,7 @@
import { FC, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { LoadingState } from '../../types/general'; import { LoadingState } from '../../types/general';
import { WASMDataPax } from '../../types/WASMData'; import { WASMDataPax } from '../../types/WASMData';
import { CoherentCallStationEntryPax, inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils'; import { CoherentCallStationEntryPax, loadAircraft, unloadAircraft } from '../../utils/utils';
import ActionBar from '../actionbar/ActionBar'; import ActionBar from '../actionbar/ActionBar';
import Input from '../input/Input'; import Input from '../input/Input';
@ -20,7 +20,6 @@ const StationEntryPax: FC<StationEntryProps> = ({ WASMData, loadingState, gsxAct
const [forwardCargo, setForwardCargo] = useState(WASMData.targetPayload.forwardCargo); const [forwardCargo, setForwardCargo] = useState(WASMData.targetPayload.forwardCargo);
const [rearCargo, setRearCargo] = useState(WASMData.targetPayload.rearCargo); const [rearCargo, setRearCargo] = useState(WASMData.targetPayload.rearCargo);
const [fuel, setFuel] = useState(Math.round(WASMData.livePayload.fuel)); const [fuel, setFuel] = useState(Math.round(WASMData.livePayload.fuel));
const [fuelEnabled, setFuelEnabled] = useState(true);
const ZFW = () => { const ZFW = () => {
if (loadingState !== 'loaded' && !gsxActive) return Math.round(WASMData.targetPayload.total); if (loadingState !== 'loaded' && !gsxActive) return Math.round(WASMData.targetPayload.total);
@ -52,10 +51,10 @@ const StationEntryPax: FC<StationEntryProps> = ({ WASMData, loadingState, gsxAct
}; };
const updateData = () => { const updateData = () => {
CoherentCallStationEntryPax(business1, business2, economy1, economy2, forwardCargo, rearCargo); CoherentCallStationEntryPax(business1, business2, economy1, economy2, forwardCargo, rearCargo, fuel);
}; };
useEffect(() => updateData(), [business1, business2, economy1, economy2, forwardCargo, rearCargo]); useEffect(() => updateData(), [business1, business2, economy1, economy2, forwardCargo, rearCargo, fuel]);
useEffect( useEffect(
() => () =>
setFuel((prev) => { setFuel((prev) => {
@ -64,9 +63,6 @@ const StationEntryPax: FC<StationEntryProps> = ({ WASMData, loadingState, gsxAct
}), }),
[WASMData.userData.isER] [WASMData.userData.isER]
); );
useEffect(() => {
setFuelEnabled((prev) => (!prev ? inRangeOf(Math.round(WASMData.livePayload.fuel), fuel) : prev));
}, [WASMData.livePayload.fuel]);
return ( return (
<> <>
@ -82,22 +78,6 @@ const StationEntryPax: FC<StationEntryProps> = ({ WASMData, loadingState, gsxAct
onChange={(value) => handleInput(value, WASMData.limits.maxFuel, setFuel)} onChange={(value) => handleInput(value, WASMData.limits.maxFuel, setFuel)}
disabled={loadingState !== 'preview' || gsxActive} 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> </div>
</div> </div>

View File

@ -1,7 +1,7 @@
import { FC, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { WASMDataF } from '../../types/WASMData'; import { WASMDataF } from '../../types/WASMData';
import { LoadingState } from '../../types/general'; import { LoadingState } from '../../types/general';
import { CoherentCallZFWEntry, inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils'; import { CoherentCallZFWEntry, loadAircraft, unloadAircraft } from '../../utils/utils';
import CGSelect from '../CGSelect/CGSelect'; import CGSelect from '../CGSelect/CGSelect';
import ActionBar from '../actionbar/ActionBar'; import ActionBar from '../actionbar/ActionBar';
import Input from '../input/Input'; import Input from '../input/Input';
@ -15,9 +15,8 @@ interface ZFWEntryProps {
const ZFWEntryF: FC<ZFWEntryProps> = ({ WASMData, loadingState, gsxActive, setLoadingState }) => { const ZFWEntryF: FC<ZFWEntryProps> = ({ WASMData, loadingState, gsxActive, setLoadingState }) => {
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.targetPayload.fuel));
const [ZFWTarget, setZFWTarget] = useState(Math.round(WASMData.targetPayload.total)); const [ZFWTarget, setZFWTarget] = useState(Math.round(WASMData.targetPayload.total));
const [fuelEnabled, setFuelEnabled] = useState(true);
const ZFW = () => { const ZFW = () => {
if (loadingState !== 'loaded' && !gsxActive) return ZFWTarget; if (loadingState !== 'loaded' && !gsxActive) return ZFWTarget;
@ -55,12 +54,13 @@ const ZFWEntryF: FC<ZFWEntryProps> = ({ WASMData, loadingState, gsxActive, setLo
const converted = parseInt(input); const converted = parseInt(input);
if (converted) { if (converted) {
if (converted < 0) setZFWTarget(Math.round(WASMData.targetPayload.empty + WASMData.targetPayload.crew)); if (converted <= 0) setZFWTarget(Math.round(WASMData.targetPayload.empty + WASMData.targetPayload.crew));
else if (converted > WASMData.limits.maxZFW) setZFWTarget(WASMData.limits.maxZFW); else if (converted > WASMData.limits.maxZFW) setZFWTarget(WASMData.limits.maxZFW);
else setZFWTarget(converted); else setZFWTarget(converted);
} }
}; };
const handleBlur = (input: string) => {
const handleBlurZFW = (input: string) => {
const minZFW = Math.round(WASMData.targetPayload.empty + WASMData.targetPayload.crew); const minZFW = Math.round(WASMData.targetPayload.empty + WASMData.targetPayload.crew);
if (!input) { if (!input) {
@ -74,10 +74,13 @@ const ZFWEntryF: FC<ZFWEntryProps> = ({ WASMData, loadingState, gsxActive, setLo
else if (converted > WASMData.limits.maxZFW) setZFWTarget(WASMData.limits.maxZFW); else if (converted > WASMData.limits.maxZFW) setZFWTarget(WASMData.limits.maxZFW);
else setZFWTarget(converted); else setZFWTarget(converted);
} }
updateData(converted);
}; };
const updateData = () => {
CoherentCallZFWEntry(ZFWTarget, CGTarget, fuel);
};
useEffect(() => updateData(), [ZFWTarget, CGTarget, fuel]);
useEffect( useEffect(
() => () =>
setFuel((prev) => { setFuel((prev) => {
@ -86,13 +89,6 @@ const ZFWEntryF: FC<ZFWEntryProps> = ({ WASMData, loadingState, gsxActive, setLo
}), }),
[WASMData.userData.isER] [WASMData.userData.isER]
); );
useEffect(() => {
setFuelEnabled((prev) => (!prev ? inRangeOf(Math.round(WASMData.livePayload.fuel), fuel) : prev));
}, [WASMData.livePayload.fuel]);
const updateData = (_ZFWTarget?: number, _CGTarget?: number) => {
CoherentCallZFWEntry(_ZFWTarget ?? ZFWTarget, _CGTarget ?? CGTarget);
};
return ( return (
<> <>
@ -108,22 +104,6 @@ const ZFWEntryF: FC<ZFWEntryProps> = ({ WASMData, loadingState, gsxActive, setLo
onChange={(value) => handleInput(value, WASMData.limits.maxFuel, setFuel)} onChange={(value) => handleInput(value, WASMData.limits.maxFuel, setFuel)}
disabled={loadingState !== 'preview' || gsxActive} 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> </div>
</div> </div>
@ -138,7 +118,7 @@ const ZFWEntryF: FC<ZFWEntryProps> = ({ WASMData, loadingState, gsxActive, setLo
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" 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} value={ZFWTarget}
onChange={(value) => handleInputZFW(value)} onChange={(value) => handleInputZFW(value)}
onBlur={(value) => handleBlur(value)} onBlur={(value) => handleBlurZFW(value)}
disabled={loadingState !== 'preview' || gsxActive} disabled={loadingState !== 'preview' || gsxActive}
/> />
</div> </div>
@ -156,14 +136,12 @@ const ZFWEntryF: FC<ZFWEntryProps> = ({ WASMData, loadingState, gsxActive, setLo
increase={() => increase={() =>
setCGTarget((prev) => { setCGTarget((prev) => {
const _new = prev + 0.1; const _new = prev + 0.1;
updateData(undefined, _new);
return _new; return _new;
}) })
} }
decrease={() => decrease={() =>
setCGTarget((prev) => { setCGTarget((prev) => {
const _new = prev - 0.1; const _new = prev - 0.1;
updateData(undefined, _new);
return _new; return _new;
}) })
} }

View File

@ -1,7 +1,7 @@
import { FC, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { WASMDataPax } from '../../types/WASMData'; import { WASMDataPax } from '../../types/WASMData';
import { LoadingState } from '../../types/general'; import { LoadingState } from '../../types/general';
import { CoherentCallZFWEntry, inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils'; import { CoherentCallZFWEntry, loadAircraft, unloadAircraft } from '../../utils/utils';
import CGSelect from '../CGSelect/CGSelect'; import CGSelect from '../CGSelect/CGSelect';
import ActionBar from '../actionbar/ActionBar'; import ActionBar from '../actionbar/ActionBar';
import Input from '../input/Input'; import Input from '../input/Input';
@ -15,9 +15,8 @@ interface ZFWEntryProps {
const ZFWEntryPax: FC<ZFWEntryProps> = ({ WASMData, loadingState, gsxActive, setLoadingState }) => { const ZFWEntryPax: FC<ZFWEntryProps> = ({ WASMData, loadingState, gsxActive, setLoadingState }) => {
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.targetPayload.fuel));
const [ZFWTarget, setZFWTarget] = useState(Math.round(WASMData.targetPayload.total)); const [ZFWTarget, setZFWTarget] = useState(Math.round(WASMData.targetPayload.total));
const [fuelEnabled, setFuelEnabled] = useState(true);
const ZFW = () => { const ZFW = () => {
if (loadingState !== 'loaded' && !gsxActive) return ZFWTarget; if (loadingState !== 'loaded' && !gsxActive) return ZFWTarget;
@ -60,7 +59,8 @@ const ZFWEntryPax: FC<ZFWEntryProps> = ({ WASMData, loadingState, gsxActive, set
else setZFWTarget(converted); else setZFWTarget(converted);
} }
}; };
const handleBlur = (input: string) => {
const handleBlurZFW = (input: string) => {
const minZFW = Math.round(WASMData.targetPayload.empty + WASMData.targetPayload.crew); const minZFW = Math.round(WASMData.targetPayload.empty + WASMData.targetPayload.crew);
if (!input) { if (!input) {
@ -74,10 +74,13 @@ const ZFWEntryPax: FC<ZFWEntryProps> = ({ WASMData, loadingState, gsxActive, set
else if (converted > WASMData.limits.maxZFW) setZFWTarget(WASMData.limits.maxZFW); else if (converted > WASMData.limits.maxZFW) setZFWTarget(WASMData.limits.maxZFW);
else setZFWTarget(converted); else setZFWTarget(converted);
} }
updateData(converted);
}; };
const updateData = () => {
CoherentCallZFWEntry(ZFWTarget, CGTarget, fuel);
};
useEffect(() => updateData(), [ZFWTarget, CGTarget, fuel]);
useEffect( useEffect(
() => () =>
setFuel((prev) => { setFuel((prev) => {
@ -86,13 +89,6 @@ const ZFWEntryPax: FC<ZFWEntryProps> = ({ WASMData, loadingState, gsxActive, set
}), }),
[WASMData.userData.isER] [WASMData.userData.isER]
); );
useEffect(() => {
setFuelEnabled((prev) => (!prev ? inRangeOf(Math.round(WASMData.livePayload.fuel), fuel) : prev));
}, [WASMData.livePayload.fuel]);
const updateData = (_ZFWTarget?: number, _CGTarget?: number) => {
CoherentCallZFWEntry(_ZFWTarget ?? ZFWTarget, _CGTarget ?? CGTarget);
};
return ( return (
<> <>
@ -108,22 +104,6 @@ const ZFWEntryPax: FC<ZFWEntryProps> = ({ WASMData, loadingState, gsxActive, set
onChange={(value) => handleInput(value, WASMData.limits.maxFuel, setFuel)} onChange={(value) => handleInput(value, WASMData.limits.maxFuel, setFuel)}
disabled={loadingState !== 'preview' || gsxActive} 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> </div>
</div> </div>
@ -138,7 +118,7 @@ const ZFWEntryPax: FC<ZFWEntryProps> = ({ WASMData, loadingState, gsxActive, set
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" 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} value={ZFWTarget}
onChange={(value) => handleInputZFW(value)} onChange={(value) => handleInputZFW(value)}
onBlur={(value) => handleBlur(value)} onBlur={(value) => handleBlurZFW(value)}
disabled={loadingState !== 'preview' || gsxActive} disabled={loadingState !== 'preview' || gsxActive}
/> />
</div> </div>
@ -156,14 +136,12 @@ const ZFWEntryPax: FC<ZFWEntryProps> = ({ WASMData, loadingState, gsxActive, set
increase={() => increase={() =>
setCGTarget((prev) => { setCGTarget((prev) => {
const _new = prev + 0.1; const _new = prev + 0.1;
updateData(undefined, _new);
return _new; return _new;
}) })
} }
decrease={() => decrease={() =>
setCGTarget((prev) => { setCGTarget((prev) => {
const _new = prev - 0.1; const _new = prev - 0.1;
updateData(undefined, _new);
return _new; return _new;
}) })
} }

View File

@ -5,6 +5,7 @@ interface WASMData {
sbPlanned: { sbPlanned: {
ZFW: number; ZFW: number;
GW: number; GW: number;
fuel: number;
}; };
loaded: boolean; loaded: boolean;
} }
@ -26,6 +27,7 @@ interface TargetPayload {
ZFWCG: number; ZFWCG: number;
TOCG: number; TOCG: number;
total: number; total: number;
fuel: number;
} }
interface TargetPayloadPax extends TargetPayload { interface TargetPayloadPax extends TargetPayload {
@ -39,9 +41,7 @@ interface TargetPayloadPax extends TargetPayload {
rearCargo: number; rearCargo: number;
} }
interface LivePayloadPax extends TargetPayloadPax { type LivePayloadPax = TargetPayloadPax;
fuel: number;
}
interface TargetPayloadF extends TargetPayload { interface TargetPayloadF extends TargetPayload {
empty: number; empty: number;
@ -54,9 +54,7 @@ interface TargetPayloadF extends TargetPayload {
lowerRear: number; lowerRear: number;
} }
interface LivePayloadF extends TargetPayloadF { type LivePayloadF = TargetPayloadF;
fuel: number;
}
interface GSX { interface GSX {
couatlStarted: boolean; couatlStarted: boolean;

View File

@ -25,7 +25,7 @@ export const inRangeOf = (value: number, target: number, tolerance: number = 10)
return Math.abs(value - target) < tolerance; return Math.abs(value - target) < tolerance;
}; };
export const CoherentCallZFWEntry = (ZFWTarget: number, CGTarget: number) => { export const CoherentCallZFWEntry = (ZFWTarget: number, CGTarget: number, fuelTarget: number) => {
Coherent.call( Coherent.call(
COHERENT_COMM_BUS_WASM_CALL, COHERENT_COMM_BUS_WASM_CALL,
CommBusEvent.UPDATE_TARGET, CommBusEvent.UPDATE_TARGET,
@ -33,6 +33,7 @@ export const CoherentCallZFWEntry = (ZFWTarget: number, CGTarget: number) => {
mode: CallMode.ZFW_SET, mode: CallMode.ZFW_SET,
ZFWTarget: ZFWTarget, ZFWTarget: ZFWTarget,
CGTarget: CGTarget, CGTarget: CGTarget,
fuelTarget: fuelTarget,
}) })
); );
}; };
@ -43,7 +44,8 @@ export const CoherentCallStationEntryPax = (
economy1: number, economy1: number,
economy2: number, economy2: number,
forwardCargo: number, forwardCargo: number,
rearCargo: number rearCargo: number,
fuelTarget: number
) => { ) => {
Coherent.call( Coherent.call(
COHERENT_COMM_BUS_WASM_CALL, COHERENT_COMM_BUS_WASM_CALL,
@ -56,6 +58,7 @@ export const CoherentCallStationEntryPax = (
economy2, economy2,
forwardCargo, forwardCargo,
rearCargo, rearCargo,
fuelTarget,
}) })
); );
}; };
@ -66,7 +69,8 @@ export const CoherentCallStationEntryF = (
upper3: number, upper3: number,
upper4: number, upper4: number,
lowerForward: number, lowerForward: number,
lowerRear: number lowerRear: number,
fuelTarget: number
) => { ) => {
Coherent.call( Coherent.call(
COHERENT_COMM_BUS_WASM_CALL, COHERENT_COMM_BUS_WASM_CALL,
@ -79,11 +83,12 @@ export const CoherentCallStationEntryF = (
upper4, upper4,
lowerForward, lowerForward,
lowerRear, lowerRear,
fuelTarget,
}) })
); );
}; };
export const CoherentCallSBEntryPax = (CGTarget: number, SBPlan?: SimBrief) => { export const CoherentCallSBEntryPax = (CGTarget: number, fuel: number, SBPlan?: SimBrief) => {
Coherent.call( Coherent.call(
COHERENT_COMM_BUS_WASM_CALL, COHERENT_COMM_BUS_WASM_CALL,
CommBusEvent.UPDATE_TARGET, CommBusEvent.UPDATE_TARGET,
@ -94,11 +99,12 @@ export const CoherentCallSBEntryPax = (CGTarget: number, SBPlan?: SimBrief) => {
CGTarget: CGTarget, CGTarget: CGTarget,
plannedZFW: SBPlan?.plannedZFW, plannedZFW: SBPlan?.plannedZFW,
plannedGW: SBPlan?.plannedGW, plannedGW: SBPlan?.plannedGW,
fuel: fuel,
}) })
); );
}; };
export const CoherentCallSBEntryF = (CGTarget: number, SBPlan?: SimBrief) => { export const CoherentCallSBEntryF = (CGTarget: number, fuel: number, SBPlan?: SimBrief) => {
Coherent.call( Coherent.call(
COHERENT_COMM_BUS_WASM_CALL, COHERENT_COMM_BUS_WASM_CALL,
CommBusEvent.UPDATE_TARGET, CommBusEvent.UPDATE_TARGET,
@ -108,6 +114,7 @@ export const CoherentCallSBEntryF = (CGTarget: number, SBPlan?: SimBrief) => {
CGTarget: CGTarget, CGTarget: CGTarget,
plannedZFW: SBPlan?.plannedZFW, plannedZFW: SBPlan?.plannedZFW,
plannedGW: SBPlan?.plannedGW, plannedGW: SBPlan?.plannedGW,
fuel: SBPlan?.fuel,
}) })
); );
}; };

File diff suppressed because it is too large Load Diff

View File

@ -1,306 +1,299 @@
#include "freighter.h" #include "freighter.h"
// ZFW Entry // ZFW Entry
void distribute(fPayloadData_t* const targetPayload, const FuelData_t* const fuel, const double ZFWTarget, const UserData_t* const userData) { void distribute(fPayloadData_t *const targetPayload, const FuelData_t *const fuel, const double ZFWTarget,
// Find payload, num pax and extra cargo const UserData_t *const userData) {
double payload = ZFWTarget - targetPayload->empty - targetPayload->pilot - targetPayload->firstOfficer - targetPayload->engineer - // Find payload, num pax and extra cargo
targetPayload->leftAux - targetPayload->rightAux; double payload = ZFWTarget - targetPayload->empty - targetPayload->pilot - targetPayload->firstOfficer -
unsigned int cargo = round(payload); targetPayload->engineer - targetPayload->leftAux - targetPayload->rightAux;
unsigned int cargo = round(payload);
distribute(targetPayload, fuel, cargo, userData); distribute(targetPayload, fuel, cargo, userData);
} }
// SimBrief Entry // SimBrief Entry
void distribute(fPayloadData_t* const targetPayload, const FuelData_t* const fuel, unsigned int cargo, const UserData_t* const userData) { void distribute(fPayloadData_t *const targetPayload, const FuelData_t *const fuel, unsigned int cargo,
// Clear const UserData_t *const userData) {
targetPayload->stations.upper1 = targetPayload->stations.upper2 = targetPayload->stations.upper3 = targetPayload->stations.upper4 = // Clear
targetPayload->stations.total = 0; targetPayload->stations.upper1 = targetPayload->stations.upper2 = targetPayload->stations.upper3 =
targetPayload->lowerForward = targetPayload->lowerRear = 0; targetPayload->stations.upper4 = targetPayload->stations.total = 0;
targetPayload->lowerForward = targetPayload->lowerRear = 0;
unsigned short _cargo = 0; unsigned short _cargo = 0;
unsigned int count = MAX_UPPER_CARGO(userData->isImperial) * 4 + MAX_FRONT_CARGO(userData->isImperial) + MAX_REAR_CARGO(userData->isImperial, userData->isER); unsigned int count = MAX_UPPER_CARGO(userData->isImperial) * 4 + MAX_FRONT_CARGO(userData->isImperial) +
// Initial distributiob MAX_REAR_CARGO(userData->isImperial, userData->isER);
while (cargo > 0 && count > 0) { // Initial distributiob
if (cargo >= 6) { while (cargo > 0 && count > 0) {
if (targetPayload->stations.upper1 < MAX_UPPER_CARGO(userData->isImperial)) { if (cargo >= 6) {
targetPayload->stations.upper1++; if (targetPayload->stations.upper1 < MAX_UPPER_CARGO(userData->isImperial)) {
_cargo++; targetPayload->stations.upper1++;
} _cargo++;
if (targetPayload->stations.upper2 < MAX_UPPER_CARGO(userData->isImperial)) { }
targetPayload->stations.upper2++; if (targetPayload->stations.upper2 < MAX_UPPER_CARGO(userData->isImperial)) {
_cargo++; targetPayload->stations.upper2++;
} _cargo++;
if (targetPayload->stations.upper3 < MAX_UPPER_CARGO(userData->isImperial)) { }
targetPayload->stations.upper3++; if (targetPayload->stations.upper3 < MAX_UPPER_CARGO(userData->isImperial)) {
_cargo++; targetPayload->stations.upper3++;
} _cargo++;
if (targetPayload->stations.upper4 < MAX_UPPER_CARGO(userData->isImperial)) { }
targetPayload->stations.upper4++; if (targetPayload->stations.upper4 < MAX_UPPER_CARGO(userData->isImperial)) {
_cargo++; targetPayload->stations.upper4++;
} _cargo++;
if (targetPayload->lowerForward < MAX_FRONT_CARGO(userData->isImperial)) { }
targetPayload->lowerForward++; if (targetPayload->lowerForward < MAX_FRONT_CARGO(userData->isImperial)) {
_cargo++; targetPayload->lowerForward++;
} _cargo++;
if (targetPayload->lowerRear < MAX_REAR_CARGO(userData->isImperial, userData->isER)) { }
targetPayload->lowerRear++; if (targetPayload->lowerRear < MAX_REAR_CARGO(userData->isImperial, userData->isER)) {
_cargo++; targetPayload->lowerRear++;
} _cargo++;
} else if (cargo == 5) { }
if (targetPayload->stations.upper1 < MAX_UPPER_CARGO(userData->isImperial)) { } else if (cargo == 5) {
targetPayload->stations.upper1++; if (targetPayload->stations.upper1 < MAX_UPPER_CARGO(userData->isImperial)) {
_cargo++; targetPayload->stations.upper1++;
} _cargo++;
if (targetPayload->stations.upper2 < MAX_UPPER_CARGO(userData->isImperial)) { }
targetPayload->stations.upper2++; if (targetPayload->stations.upper2 < MAX_UPPER_CARGO(userData->isImperial)) {
_cargo++; targetPayload->stations.upper2++;
} _cargo++;
if (targetPayload->stations.upper3 < MAX_UPPER_CARGO(userData->isImperial)) { }
targetPayload->stations.upper3++; if (targetPayload->stations.upper3 < MAX_UPPER_CARGO(userData->isImperial)) {
_cargo++; targetPayload->stations.upper3++;
} _cargo++;
if (targetPayload->stations.upper4 < MAX_UPPER_CARGO(userData->isImperial)) { }
targetPayload->stations.upper4++; if (targetPayload->stations.upper4 < MAX_UPPER_CARGO(userData->isImperial)) {
_cargo++; targetPayload->stations.upper4++;
} _cargo++;
if (targetPayload->lowerForward < MAX_FRONT_CARGO(userData->isImperial)) { }
targetPayload->lowerForward++; if (targetPayload->lowerForward < MAX_FRONT_CARGO(userData->isImperial)) {
_cargo++; targetPayload->lowerForward++;
} _cargo++;
} }
else if (cargo == 4) { } else if (cargo == 4) {
if (targetPayload->stations.upper1 < MAX_UPPER_CARGO(userData->isImperial)) { if (targetPayload->stations.upper1 < MAX_UPPER_CARGO(userData->isImperial)) {
targetPayload->stations.upper1++; targetPayload->stations.upper1++;
_cargo++; _cargo++;
} }
if (targetPayload->stations.upper2 < MAX_UPPER_CARGO(userData->isImperial)) { if (targetPayload->stations.upper2 < MAX_UPPER_CARGO(userData->isImperial)) {
targetPayload->stations.upper2++; targetPayload->stations.upper2++;
_cargo++; _cargo++;
} }
if (targetPayload->stations.upper3 < MAX_UPPER_CARGO(userData->isImperial)) { if (targetPayload->stations.upper3 < MAX_UPPER_CARGO(userData->isImperial)) {
targetPayload->stations.upper3++; targetPayload->stations.upper3++;
_cargo++; _cargo++;
} }
if (targetPayload->stations.upper4 < MAX_UPPER_CARGO(userData->isImperial)) { if (targetPayload->stations.upper4 < MAX_UPPER_CARGO(userData->isImperial)) {
targetPayload->stations.upper4++; targetPayload->stations.upper4++;
_cargo++; _cargo++;
} }
} } else if (cargo == 3) {
else if (cargo == 3) { if (targetPayload->stations.upper1 < MAX_UPPER_CARGO(userData->isImperial)) {
if (targetPayload->stations.upper1 < MAX_UPPER_CARGO(userData->isImperial)) { targetPayload->stations.upper1++;
targetPayload->stations.upper1++; _cargo++;
_cargo++; }
} if (targetPayload->stations.upper2 < MAX_UPPER_CARGO(userData->isImperial)) {
if (targetPayload->stations.upper2 < MAX_UPPER_CARGO(userData->isImperial)) { targetPayload->stations.upper2++;
targetPayload->stations.upper2++; _cargo++;
_cargo++; }
} if (targetPayload->stations.upper3 < MAX_UPPER_CARGO(userData->isImperial)) {
if (targetPayload->stations.upper3 < MAX_UPPER_CARGO(userData->isImperial)) { targetPayload->stations.upper3++;
targetPayload->stations.upper3++; _cargo++;
_cargo++; }
} } else if (cargo == 2) {
} if (targetPayload->stations.upper1 < MAX_UPPER_CARGO(userData->isImperial)) {
else if (cargo == 2) { targetPayload->stations.upper1++;
if (targetPayload->stations.upper1 < MAX_UPPER_CARGO(userData->isImperial)) { _cargo++;
targetPayload->stations.upper1++; }
_cargo++; if (targetPayload->stations.upper2 < MAX_UPPER_CARGO(userData->isImperial)) {
} targetPayload->stations.upper2++;
if (targetPayload->stations.upper2 < MAX_UPPER_CARGO(userData->isImperial)) { _cargo++;
targetPayload->stations.upper2++; }
_cargo++; } else if (cargo == 1) {
} if (targetPayload->stations.upper1 < MAX_UPPER_CARGO(userData->isImperial)) {
} targetPayload->stations.upper1++;
else if (cargo == 1) { _cargo++;
if (targetPayload->stations.upper1 < MAX_UPPER_CARGO(userData->isImperial)) { }
targetPayload->stations.upper1++;
_cargo++;
}
}
cargo -= _cargo;
targetPayload->stations.total += _cargo;
_cargo = 0;
count--;
} }
// Refinement cargo -= _cargo;
count = MAX_UPPER_CARGO(userData->isImperial) * 4 + MAX_FRONT_CARGO(userData->isImperial) + MAX_REAR_CARGO(userData->isImperial, userData->isER); targetPayload->stations.total += _cargo;
while (count > 0) {
generatePayload(targetPayload, userData->isImperial);
calculateCGs(targetPayload, fuel, &targetPayload->ZFWCG, &targetPayload->TOCG, userData->isImperial);
// in front of target _cargo = 0;
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(userData->isImperial)) { count--;
targetPayload->stations.upper4++; }
} // Refinement
else if (targetPayload->stations.upper3 < MAX_UPPER_CARGO(userData->isImperial)) { count = MAX_UPPER_CARGO(userData->isImperial) * 4 + MAX_FRONT_CARGO(userData->isImperial) +
targetPayload->stations.upper3++; MAX_REAR_CARGO(userData->isImperial, userData->isER);
} while (count > 0) {
else if (targetPayload->stations.upper2 < MAX_UPPER_CARGO(userData->isImperial)) { generatePayload(targetPayload, userData->isImperial);
targetPayload->stations.upper2++; calculateCGs(targetPayload, fuel, userData->isImperial);
}
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(userData->isImperial)) { // in front of target
targetPayload->stations.upper1++; if (targetPayload->ZFWCG < targetPayload->CGTarget - CG_TOLERANCE) {
} if (targetPayload->stations.upper1 > 0) {
else if (targetPayload->stations.upper2 < MAX_UPPER_CARGO(userData->isImperial)) { targetPayload->stations.upper1--;
targetPayload->stations.upper2++; } else if (targetPayload->stations.upper2 > 0) {
} targetPayload->stations.upper2--;
else if (targetPayload->stations.upper3 < MAX_UPPER_CARGO(userData->isImperial)) { } else if (targetPayload->stations.upper3 > 0) {
targetPayload->stations.upper3++; targetPayload->stations.upper3--;
} } else {
else { break;
targetPayload->stations.upper4++; }
}
}
else {
break;
}
count--; if (targetPayload->stations.upper4 < MAX_UPPER_CARGO(userData->isImperial)) {
targetPayload->stations.upper4++;
} else if (targetPayload->stations.upper3 < MAX_UPPER_CARGO(userData->isImperial)) {
targetPayload->stations.upper3++;
} else if (targetPayload->stations.upper2 < MAX_UPPER_CARGO(userData->isImperial)) {
targetPayload->stations.upper2++;
} else {
targetPayload->stations.upper1++;
}
} }
// Refinement cargo // behind target
count = MAX_FRONT_CARGO(userData->isImperial) + MAX_REAR_CARGO(userData->isImperial, userData->isER); else if (targetPayload->ZFWCG > targetPayload->CGTarget + CG_TOLERANCE) {
while (count > 0) { if (targetPayload->stations.upper4 > 0) {
generatePayload(targetPayload, userData->isImperial); targetPayload->stations.upper4--;
calculateCGs(targetPayload, fuel, &targetPayload->ZFWCG, &targetPayload->TOCG, userData->isImperial); } else if (targetPayload->stations.upper3 > 0) {
targetPayload->stations.upper3--;
} else if (targetPayload->stations.upper2 > 0) {
targetPayload->stations.upper2--;
} else {
break;
}
// in front of target if (targetPayload->stations.upper1 < MAX_UPPER_CARGO(userData->isImperial)) {
if (targetPayload->ZFWCG < targetPayload->CGTarget - CG_TOLERANCE) { targetPayload->stations.upper1++;
if (targetPayload->lowerForward > 0 && targetPayload->lowerRear < MAX_REAR_CARGO(userData->isImperial, userData->isER)) { } else if (targetPayload->stations.upper2 < MAX_UPPER_CARGO(userData->isImperial)) {
targetPayload->lowerForward--; targetPayload->stations.upper2++;
targetPayload->lowerRear++; } else if (targetPayload->stations.upper3 < MAX_UPPER_CARGO(userData->isImperial)) {
} targetPayload->stations.upper3++;
else { } else {
break; targetPayload->stations.upper4++;
} }
} } else {
// behind target break;
else if (targetPayload->ZFWCG > targetPayload->CGTarget + CG_TOLERANCE) {
if (targetPayload->lowerRear > 0 && targetPayload->lowerForward < MAX_FRONT_CARGO(userData->isImperial)) {
targetPayload->lowerRear--;
targetPayload->lowerForward++;
}
else {
break;
}
}
else {
break;
}
count--;
} }
count--;
}
// Refinement cargo
count = MAX_FRONT_CARGO(userData->isImperial) + MAX_REAR_CARGO(userData->isImperial, userData->isER);
while (count > 0) {
generatePayload(targetPayload, userData->isImperial);
calculateCGs(targetPayload, fuel, userData->isImperial);
// in front of target
if (targetPayload->ZFWCG < targetPayload->CGTarget - CG_TOLERANCE) {
if (targetPayload->lowerForward > 0 && targetPayload->lowerRear < MAX_REAR_CARGO(userData->isImperial, userData->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(userData->isImperial)) {
targetPayload->lowerRear--;
targetPayload->lowerForward++;
} else {
break;
}
} else {
break;
}
count--;
}
} }
// Updates pax stations with their respective weights // Updates pax stations with their respective weights
// Used internally and used for Station Entry (pax only, cargo is set directly) // Used internally and used for Station Entry (pax only, cargo is set directly)
void generatePayload(fPayloadData_t* const targetPayload, const bool isImperial) { void generatePayload(fPayloadData_t *const targetPayload, const bool isImperial) {
targetPayload->upper1Left = targetPayload->upper1Right = (targetPayload->stations.upper1 / 2.0); targetPayload->upper1Left = targetPayload->upper1Right = (targetPayload->stations.upper1 / 2.0);
targetPayload->upper2Left = targetPayload->upper2Right = (targetPayload->stations.upper2 / 2.0); targetPayload->upper2Left = targetPayload->upper2Right = (targetPayload->stations.upper2 / 2.0);
targetPayload->upper3Left = targetPayload->upper3Right = (targetPayload->stations.upper3 / 2.0); targetPayload->upper3Left = targetPayload->upper3Right = (targetPayload->stations.upper3 / 2.0);
targetPayload->upper4Left = targetPayload->upper4Right = (targetPayload->stations.upper4 / 2.0); targetPayload->upper4Left = targetPayload->upper4Right = (targetPayload->stations.upper4 / 2.0);
targetPayload->total = targetPayload->empty + targetPayload->pilot + targetPayload->firstOfficer + targetPayload->engineer + targetPayload->upper1Left + targetPayload->total = targetPayload->empty + targetPayload->pilot + targetPayload->firstOfficer + targetPayload->engineer +
targetPayload->upper1Right + targetPayload->upper2Left + targetPayload->upper2Right + targetPayload->upper3Left + targetPayload->upper1Left + targetPayload->upper1Right + targetPayload->upper2Left +
targetPayload->upper3Right + targetPayload->upper4Left + targetPayload->upper4Right + targetPayload->lowerForward + targetPayload->upper2Right + targetPayload->upper3Left + targetPayload->upper3Right +
targetPayload->lowerRear + targetPayload->leftAux + targetPayload->rightAux; targetPayload->upper4Left + targetPayload->upper4Right + targetPayload->lowerForward +
targetPayload->lowerRear + targetPayload->leftAux + targetPayload->rightAux;
} }
// Normalise to Pounds // Normalise to Pounds
// MANDATORY BEFORE SETTING WEIGHTS // MANDATORY BEFORE SETTING WEIGHTS
// USE ON COPY OF GLOBAL STATE ONLY // USE ON COPY OF GLOBAL STATE ONLY
void normalisePayload(fPayloadData_t* const targetPayload, const bool isImperial) { void normalisePayload(fPayloadData_t *const targetPayload, const bool isImperial) {
targetPayload->empty = TO_POUNDS(isImperial, targetPayload->empty); targetPayload->empty = TO_POUNDS(isImperial, targetPayload->empty);
targetPayload->pilot = TO_POUNDS(isImperial, targetPayload->pilot); targetPayload->pilot = TO_POUNDS(isImperial, targetPayload->pilot);
targetPayload->firstOfficer = TO_POUNDS(isImperial, targetPayload->firstOfficer); targetPayload->firstOfficer = TO_POUNDS(isImperial, targetPayload->firstOfficer);
targetPayload->engineer = TO_POUNDS(isImperial, targetPayload->engineer); targetPayload->engineer = TO_POUNDS(isImperial, targetPayload->engineer);
targetPayload->upper1Left = TO_POUNDS(isImperial, targetPayload->upper1Left); targetPayload->upper1Left = TO_POUNDS(isImperial, targetPayload->upper1Left);
targetPayload->upper1Right = TO_POUNDS(isImperial, targetPayload->upper1Right); targetPayload->upper1Right = TO_POUNDS(isImperial, targetPayload->upper1Right);
targetPayload->upper2Left = TO_POUNDS(isImperial, targetPayload->upper2Left); targetPayload->upper2Left = TO_POUNDS(isImperial, targetPayload->upper2Left);
targetPayload->upper2Right = TO_POUNDS(isImperial, targetPayload->upper2Right); targetPayload->upper2Right = TO_POUNDS(isImperial, targetPayload->upper2Right);
targetPayload->upper3Left = TO_POUNDS(isImperial, targetPayload->upper3Left); targetPayload->upper3Left = TO_POUNDS(isImperial, targetPayload->upper3Left);
targetPayload->upper3Right = TO_POUNDS(isImperial, targetPayload->upper3Right); targetPayload->upper3Right = TO_POUNDS(isImperial, targetPayload->upper3Right);
targetPayload->upper4Left = TO_POUNDS(isImperial, targetPayload->upper4Left); targetPayload->upper4Left = TO_POUNDS(isImperial, targetPayload->upper4Left);
targetPayload->upper4Right = TO_POUNDS(isImperial, targetPayload->upper4Right); targetPayload->upper4Right = TO_POUNDS(isImperial, targetPayload->upper4Right);
targetPayload->lowerForward = TO_POUNDS(isImperial, targetPayload->lowerForward); targetPayload->lowerForward = TO_POUNDS(isImperial, targetPayload->lowerForward);
targetPayload->lowerRear = TO_POUNDS(isImperial, targetPayload->lowerRear); targetPayload->lowerRear = TO_POUNDS(isImperial, targetPayload->lowerRear);
targetPayload->leftAux = TO_POUNDS(isImperial, targetPayload->leftAux); targetPayload->leftAux = TO_POUNDS(isImperial, targetPayload->leftAux);
targetPayload->rightAux = TO_POUNDS(isImperial, targetPayload->rightAux); 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) { void calculateCGs(fPayloadData_t *const targetPayload, const FuelData_t *const fuel, const bool isImperial) {
fPayloadData_t localPayload = {}; fPayloadData_t localPayload = {};
memcpy(&localPayload, targetPayload, sizeof(localPayload)); memcpy(&localPayload, targetPayload, sizeof(localPayload));
normalisePayload(&localPayload, isImperial); normalisePayload(&localPayload, isImperial);
double totalMoment = localPayload.empty * ARM_EMPTY + localPayload.pilot * ARM_PILOT + localPayload.firstOfficer * ARM_FIRST_OFFICER + double totalMoment = localPayload.empty * ARM_EMPTY + localPayload.pilot * ARM_PILOT +
localPayload.engineer * ARM_ENGINEER + localPayload.upper1Left * ARM_F_UPPER1_LEFT + localPayload.upper1Right * ARM_F_UPPER1_RIGHT + localPayload.firstOfficer * ARM_FIRST_OFFICER + localPayload.engineer * ARM_ENGINEER +
localPayload.upper2Left * ARM_F_UPPER2_LEFT + localPayload.upper2Right * ARM_F_UPPER2_RIGHT + localPayload.upper3Left * ARM_F_UPPER3_LEFT + localPayload.upper1Left * ARM_F_UPPER1_LEFT + localPayload.upper1Right * ARM_F_UPPER1_RIGHT +
localPayload.upper3Right * ARM_F_UPPER3_RIGHT + localPayload.upper4Left * ARM_F_UPPER4_LEFT + localPayload.upper4Right * ARM_F_UPPER4_RIGHT + localPayload.upper2Left * ARM_F_UPPER2_LEFT + localPayload.upper2Right * ARM_F_UPPER2_RIGHT +
localPayload.lowerForward * ARM_FORWARD_CARGO + localPayload.lowerRear * ARM_REAR_CARGO + localPayload.leftAux * ARM_LEFT_AUX + localPayload.upper3Left * ARM_F_UPPER3_LEFT + localPayload.upper3Right * ARM_F_UPPER3_RIGHT +
localPayload.rightAux * ARM_RIGHT_AUX; 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 + double totalWeight = localPayload.empty + localPayload.pilot + localPayload.firstOfficer + localPayload.engineer +
localPayload.upper1Right + localPayload.upper2Left + localPayload.upper2Right + localPayload.upper3Left + localPayload.upper3Right + localPayload.upper1Left + localPayload.upper1Right + localPayload.upper2Left + localPayload.upper2Right +
localPayload.upper4Left + localPayload.upper4Right + localPayload.lowerForward + localPayload.lowerRear + localPayload.leftAux + localPayload.upper3Left + localPayload.upper3Right + localPayload.upper4Left + localPayload.upper4Right +
localPayload.rightAux; localPayload.lowerForward + localPayload.lowerRear + localPayload.leftAux + localPayload.rightAux;
*ZFWCG = TO_PERCENT_MAC(totalMoment / totalWeight); targetPayload->ZFWCG = TO_PERCENT_MAC(totalMoment / totalWeight);
totalMoment += fuel->main1 * ARM_MAIN1 + fuel->main3 * ARM_MAIN3 + fuel->main2 * ARM_MAIN2 + fuel->upperAux * ARM_UPPER_AUX + 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->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; fuel->tail * ARM_TAIL + fuel->forwardAux1 * ARM_FORWARD_AUX1 + fuel->forwardAux2 * ARM_FORWARD_AUX2;
totalWeight += fuel->total; totalWeight += fuel->total;
*TOCG = TO_PERCENT_MAC(totalMoment / totalWeight); targetPayload->TOCG = TO_PERCENT_MAC(totalMoment / totalWeight);
} }
void load(const fPayloadData_t* const targetPayload, const HANDLE simConnect, const bool isImperial) { void load(const fPayloadData_t *const targetPayload, const HANDLE simConnect, const bool isImperial) {
fPayloadData_t localPayload = {}; fPayloadData_t localPayload = {};
memcpy(&localPayload, targetPayload, sizeof(localPayload)); memcpy(&localPayload, targetPayload, sizeof(localPayload));
normalisePayload(&localPayload, isImperial); normalisePayload(&localPayload, isImperial);
SimConnect_SetDataOnSimObject(simConnect, DATA_DEFINITION_PAYLOAD_F, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(fPayloadDataSet_t), &localPayload); localPayload._ZFWCG = localPayload.ZFWCG / 100.0;
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) { void unloadF(const HANDLE simConnect, const bool isER) {
fPayloadData_t localPayload = {}; fPayloadData_t localPayload = {};
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_F, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(fPayloadDataSet_t), &localPayload); localPayload._ZFWCG = -1;
SimConnect_SetDataOnSimObject(simConnect, DATA_DEFINITION_PAYLOAD_F, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(fPayloadDataSet_t),
&localPayload);
} }

View File

@ -1,13 +1,13 @@
#pragma once #pragma once
#ifndef __INTELLISENSE__ #ifndef __INTELLISENSE__
# define MODULE_EXPORT __attribute__( ( visibility( "default" ) ) ) #define MODULE_EXPORT __attribute__((visibility("default")))
# define MODULE_WASM_MODNAME(mod) __attribute__((import_module(mod))) #define MODULE_WASM_MODNAME(mod) __attribute__((import_module(mod)))
#else #else
# define MODULE_EXPORT #define MODULE_EXPORT
# define MODULE_WASM_MODNAME(mod) #define MODULE_WASM_MODNAME(mod)
# define __attribute__(x) #define __attribute__(x)
# define __restrict__ #define __restrict__
#endif #endif
/********************************* Headers *********************************/ /********************************* Headers *********************************/
@ -19,10 +19,11 @@
// C++ headers // C++ headers
#include <algorithm> #include <algorithm>
// Own headers // Own headers
#include "fuel.h"
#include "shared.h" #include "shared.h"
/******************************** Constants ********************************/ /******************************** Constants ********************************/
//PMC pallet due to 104in door // PMC pallet due to 104in door
#define MAX_UPPER_CARGO(IS_IMPERIAL) ((IS_IMPERIAL) ? (6.5 * 15000.0) : (6.5 * 6804.0)) #define MAX_UPPER_CARGO(IS_IMPERIAL) ((IS_IMPERIAL) ? (6.5 * 15000.0) : (6.5 * 6804.0))
// Max ZFW // Max ZFW
#define MAX_F_ZFW(IS_IMPERIAL) ((IS_IMPERIAL) ? (451300) : (204706)) #define MAX_F_ZFW(IS_IMPERIAL) ((IS_IMPERIAL) ? (451300) : (204706))
@ -38,74 +39,79 @@
/***************************** Data structures *****************************/ /***************************** Data structures *****************************/
typedef struct { typedef struct {
// SimConnect mapped // SimConnect mapped
double pilot; double pilot;
double firstOfficer; double firstOfficer;
double engineer; double engineer;
double upper1Left; double upper1Left;
double upper1Right; double upper1Right;
double upper2Left; double upper2Left;
double upper2Right; double upper2Right;
double upper3Left; double upper3Left;
double upper3Right; double upper3Right;
double upper4Left; double upper4Left;
double upper4Right; double upper4Right;
double lowerForward; double lowerForward;
double lowerRear; double lowerRear;
double leftAux; double leftAux;
double rightAux; double rightAux;
double _ZFWCG; // DO NOT USE
// Additional properties // Additional properties
double empty; double empty;
double total; double total;
double CGTarget; double CGTarget;
double ZFWCG; double ZFWCG;
double TOCG; double TOCG;
struct stations { struct stations {
unsigned int upper1; unsigned int upper1;
unsigned int upper2; unsigned int upper2;
unsigned int upper3; unsigned int upper3;
unsigned int upper4; unsigned int upper4;
unsigned int total; unsigned int total;
} stations; } stations;
struct sbPlanned { struct sbPlanned {
double ZFW; double ZFW;
double GW; double GW;
unsigned int cargo; double fuel;
} sbPlanned; unsigned int cargo;
} sbPlanned;
} fPayloadData_t; } fPayloadData_t;
typedef struct { typedef struct {
// SimConnect mapped // SimConnect mapped
double pilot; double pilot;
double firstOfficer; double firstOfficer;
double engineer; double engineer;
double upper1Left; double upper1Left;
double upper1Right; double upper1Right;
double upper2Left; double upper2Left;
double upper2Right; double upper2Right;
double upper3Left; double upper3Left;
double upper3Right; double upper3Right;
double upper4Left; double upper4Left;
double upper4Right; double upper4Right;
double lowerForward; double lowerForward;
double lowerRear; double lowerRear;
double leftAux; double leftAux;
double rightAux; double rightAux;
double ZFWCG;
} fPayloadDataSet_t; } fPayloadDataSet_t;
/******************************** Functions ********************************/ /******************************** Functions ********************************/
// ZFW Entry // ZFW Entry
void distribute(fPayloadData_t* const targetPayload, const FuelData_t* const fuel, const double ZFWTarget, const UserData_t* const userData); void distribute(fPayloadData_t *const targetPayload, const FuelData_t *const fuel, const double ZFWTarget,
const UserData_t *const userData);
// SimBrief Entry // SimBrief Entry
void distribute(fPayloadData_t* const targetPayload, const FuelData_t* const fuel, unsigned int cargo, const UserData_t* const userData); void distribute(fPayloadData_t *const targetPayload, const FuelData_t *const fuel, unsigned int cargo,
const UserData_t *const userData);
// Updates pax stations with their respective weights // Updates pax stations with their respective weights
// Used internally and used for Station Entry (pax only, cargo is ste directly) // Used internally and used for Station Entry (pax only, cargo is ste directly)
// STATION WEIGHTS ARE NOT NORMALISED TO POUNDS // STATION WEIGHTS ARE NOT NORMALISED TO POUNDS
void generatePayload(fPayloadData_t* const targetPayload, const bool isImperial); void generatePayload(fPayloadData_t *const targetPayload, const bool isImperial);
// Normalise to Pounds // Normalise to Pounds
// For Station Entry: CALL AFTER `generatePayload` // For Station Entry: CALL AFTER `generatePayload`
void normalisePayload(fPayloadData_t* const targetPayload, const bool isImperial); 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 calculateCGs(fPayloadData_t *const targetPayload, const FuelData_t *const fuel, const bool isImperial);
void load(const fPayloadData_t* const targetPayload, const HANDLE simConnect, const bool isImperial); void load(const fPayloadData_t *const targetPayload, const HANDLE simConnect, const bool isImperial);
void unloadF(const HANDLE simConnect, const bool isER); void unloadF(const HANDLE simConnect, const bool isER);

View File

@ -0,0 +1,135 @@
#include "fuel.h"
// ZFW Entry
void distribute(FuelData_t *const targetFuel, const double fuelTarget, const UserData_t *const userData) {
double fuelLbs = TO_POUNDS(userData->isImperial, fuelTarget);
// Equal mains
if (fuelLbs <= MAX_TANK_1_3_LBS * 3) {
double tanks = fuelLbs / 3;
// Only main
if (tanks <= MAX_TANK_1_3_TIP_LBS) {
targetFuel->main1 = tanks;
targetFuel->main3 = tanks;
targetFuel->main1Tip = 0;
targetFuel->main3Tip = 0;
}
// Tips
else if (tanks <= MAX_TANK_1_3_TIP_LBS * 2) {
double tips = tanks - MAX_TANK_1_3_TIP_LBS;
targetFuel->main1 = MAX_TANK_1_3_TIP_LBS;
targetFuel->main3 = MAX_TANK_1_3_TIP_LBS;
targetFuel->main1Tip = tips;
targetFuel->main3Tip = tips;
}
// Max tip
else {
double mains = tanks - MAX_TANK_1_3_TIP_LBS;
targetFuel->main1 = mains;
targetFuel->main3 = mains;
targetFuel->main1Tip = MAX_TANK_1_3_TIP_LBS;
targetFuel->main3Tip = MAX_TANK_1_3_TIP_LBS;
}
targetFuel->main2 = tanks;
targetFuel->upperAux = 0;
targetFuel->lowerAux = 0;
targetFuel->tail = 0;
targetFuel->forwardAux1 = 0;
targetFuel->forwardAux2 = 0;
}
// No Aux
else if (fuelLbs <= MAX_TANK_1_3_LBS * 2 + MAX_TANK_2_LBS) {
targetFuel->main1 = MAX_TANK_1_3_MAIN_LBS;
targetFuel->main3 = MAX_TANK_1_3_MAIN_LBS;
targetFuel->main1Tip = MAX_TANK_1_3_TIP_LBS;
targetFuel->main3Tip = MAX_TANK_1_3_TIP_LBS;
targetFuel->main2 = fuelLbs - MAX_TANK_1_3_LBS * 2;
targetFuel->upperAux = 0;
targetFuel->lowerAux = 0;
targetFuel->tail = 0;
targetFuel->forwardAux1 = 0;
targetFuel->forwardAux2 = 0;
}
// UPR AUX
else if (fuelLbs <= MAX_TANK_1_3_LBS * 2 + MAX_TANK_2_LBS + MAX_UPR_AUX_LBS) {
targetFuel->main1 = MAX_TANK_1_3_MAIN_LBS;
targetFuel->main3 = MAX_TANK_1_3_MAIN_LBS;
targetFuel->main1Tip = MAX_TANK_1_3_TIP_LBS;
targetFuel->main3Tip = MAX_TANK_1_3_TIP_LBS;
targetFuel->main2 = MAX_TANK_2_LBS;
targetFuel->upperAux = fuelLbs - MAX_TANK_1_3_LBS * 2 - MAX_TANK_2_LBS;
targetFuel->lowerAux = 0;
targetFuel->tail = 0;
targetFuel->forwardAux1 = 0;
targetFuel->forwardAux2 = 0;
}
// LWR AUX
else if (fuelLbs <= MAX_TANK_1_3_LBS * 2 + MAX_TANK_2_LBS + MAX_UPR_AUX_LBS + MAX_LWR_AUX_LBS) {
targetFuel->main1 = MAX_TANK_1_3_MAIN_LBS;
targetFuel->main3 = MAX_TANK_1_3_MAIN_LBS;
targetFuel->main1Tip = MAX_TANK_1_3_TIP_LBS;
targetFuel->main3Tip = MAX_TANK_1_3_TIP_LBS;
targetFuel->main2 = MAX_TANK_2_LBS;
targetFuel->upperAux = MAX_UPR_AUX_LBS;
targetFuel->lowerAux = fuelLbs - MAX_TANK_1_3_LBS * 2 - MAX_TANK_2_LBS - MAX_UPR_AUX_LBS;
targetFuel->tail = 0;
targetFuel->forwardAux1 = 0;
targetFuel->forwardAux2 = 0;
}
// Tail
else if (fuelLbs <= MAX_TANK_1_3_LBS * 2 + MAX_TANK_2_LBS + MAX_UPR_AUX_LBS + MAX_LWR_AUX_LBS + MAX_TAIL_LBS) {
targetFuel->main1 = MAX_TANK_1_3_MAIN_LBS;
targetFuel->main3 = MAX_TANK_1_3_MAIN_LBS;
targetFuel->main1Tip = MAX_TANK_1_3_TIP_LBS;
targetFuel->main3Tip = MAX_TANK_1_3_TIP_LBS;
targetFuel->main2 = MAX_TANK_2_LBS;
targetFuel->upperAux = MAX_UPR_AUX_LBS;
targetFuel->lowerAux = MAX_LWR_AUX_LBS;
targetFuel->tail = fuelLbs - MAX_TANK_1_3_LBS * 2 - MAX_TANK_2_LBS - MAX_UPR_AUX_LBS - MAX_LWR_AUX_LBS;
targetFuel->forwardAux1 = 0;
targetFuel->forwardAux2 = 0;
} else if (userData->isER) {
targetFuel->main1 = MAX_TANK_1_3_MAIN_LBS;
targetFuel->main3 = MAX_TANK_1_3_MAIN_LBS;
targetFuel->main1Tip = MAX_TANK_1_3_TIP_LBS;
targetFuel->main3Tip = MAX_TANK_1_3_TIP_LBS;
targetFuel->main2 = MAX_TANK_2_LBS;
targetFuel->upperAux = MAX_UPR_AUX_LBS;
targetFuel->lowerAux = MAX_LWR_AUX_LBS;
targetFuel->tail = MAX_TAIL_LBS;
fuelLbs = fuelLbs - MAX_TANK_1_3_LBS * 2 - MAX_TANK_2_LBS - MAX_UPR_AUX_LBS - MAX_LWR_AUX_LBS - MAX_TAIL_LBS;
targetFuel->forwardAux1 = min(fuelLbs / 2, MAX_FWD_AUX_LBS);
targetFuel->forwardAux2 = min(fuelLbs / 2, MAX_FWD_AUX_LBS);
}
targetFuel->total = targetFuel->main1 + targetFuel->main3 + targetFuel->main2 + targetFuel->upperAux + targetFuel->lowerAux +
targetFuel->main1Tip + targetFuel->main3Tip + targetFuel->tail + targetFuel->forwardAux1 +
targetFuel->forwardAux2;
}
void fuel(const FuelData_t *const targetFuel, const HANDLE simConnect) {
FuelDataSet_t localFuel = {};
localFuel.main1 = min(MAX_TANK_1_3_GAL, (targetFuel->main1 + targetFuel->main1Tip) / LBS_PER_GAL);
localFuel.main2 = min(MAX_TANK_2_GAL, targetFuel->main2 / LBS_PER_GAL);
localFuel.main3 = min(MAX_TANK_1_3_GAL, (targetFuel->main3 + targetFuel->main3Tip) / LBS_PER_GAL);
localFuel.upperAux = min(MAX_UPR_AUX_GAL, targetFuel->upperAux / LBS_PER_GAL);
localFuel.lowerAux = min(MAX_LWR_AUX_GAL, targetFuel->lowerAux / LBS_PER_GAL);
localFuel.tail = min(MAX_TAIL_GAL, targetFuel->tail / LBS_PER_GAL);
localFuel.forwardAux1 = min(MAX_FWD_AUX_GAL, targetFuel->forwardAux1 / LBS_PER_GAL);
localFuel.forwardAux2 = min(MAX_FWD_AUX_GAL, targetFuel->forwardAux2 / LBS_PER_GAL);
SimConnect_SetDataOnSimObject(simConnect, DATA_DEFINITION_FUEL_SET, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(FuelDataSet_t),
&localFuel);
}

View File

@ -0,0 +1,88 @@
#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
/********************************* Headers *********************************/
// MSFS headers
#include <MSFS/MSFS_WindowsTypes.h>
#include <SimConnect.h>
// C headers
#include <math.h>
// C++ headers
#include <algorithm>
// Own headers
#include "shared.h"
/******************************** Constants ********************************/
#define LBS_PER_GAL 6.699999809
#define MAX_TANK_1_3_MAIN_GAL 5167.907
#define MAX_TANK_1_3_TIP_GAL 874.5
#define MAX_TANK_1_3_GAL (5167.907 + 874.5)
#define MAX_TANK_2_GAL 9556.95
#define MAX_UPR_AUX_GAL 12998.58
#define MAX_LWR_AUX_GAL 1641.82
#define MAX_TAIL_GAL 1957.779
#define MAX_FWD_AUX_GAL 1970.8
#define MAX_TANK_1_3_MAIN_LBS (LBS_PER_GAL * MAX_TANK_1_3_MAIN_GAL)
#define MAX_TANK_1_3_TIP_LBS (LBS_PER_GAL * MAX_TANK_1_3_TIP_GAL)
#define MAX_TANK_1_3_LBS (LBS_PER_GAL * MAX_TANK_1_3_GAL)
#define MAX_TANK_2_LBS (LBS_PER_GAL * MAX_TANK_2_GAL)
#define MAX_UPR_AUX_LBS (LBS_PER_GAL * MAX_UPR_AUX_GAL)
#define MAX_LWR_AUX_LBS (LBS_PER_GAL * MAX_LWR_AUX_GAL)
#define MAX_TAIL_LBS (LBS_PER_GAL * MAX_TAIL_GAL)
#define MAX_FWD_AUX_LBS (LBS_PER_GAL * MAX_FWD_AUX_GAL)
// Max Fuel
#define MAX_FUEL(IS_IMPERIAL) ((IS_IMPERIAL) ? (256207) : (116213))
#define MAX_FUEL_ER(IS_IMPERIAL) ((IS_IMPERIAL) ? (282619) : (128193))
// Arms Fuel
#define ARM_MAIN1 -240.0
#define ARM_MAIN3 -240.0
#define ARM_MAIN2 120.0
#define ARM_UPPER_AUX 0.0
#define ARM_LOWER_AUX 0.0
#define ARM_MAIN1_TIP -468.0
#define ARM_MAIN3_TIP -468.0
#define ARM_TAIL -840.0
#define ARM_FORWARD_AUX1 60.0
#define ARM_FORWARD_AUX2 60.0
/***************************** Data structures *****************************/
typedef struct {
// SimConnect mapped
double main1;
double main3;
double main2;
double upperAux;
double lowerAux;
double main1Tip;
double main3Tip;
double tail;
double forwardAux1;
double forwardAux2;
// Additional properties
double total;
} FuelData_t;
typedef struct {
double main1;
double main3;
double main2;
double upperAux;
double lowerAux;
double tail;
double forwardAux1;
double forwardAux2;
} FuelDataSet_t;
/******************************** Functions ********************************/
void distribute(FuelData_t *const targetFuel, const double fuelTarget, const UserData_t *const userData);
void fuel(const FuelData_t *const targetFuel, const HANDLE simConnect);

View File

@ -1,25 +0,0 @@
// load-manager-cli.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include "../wasm-module/pax.h"
int main()
{
bool isImperial = false;
bool isER = true;
paxPayloadData_t targetPaxPayloadData = paxPayloadData_t();
targetPaxPayloadData.empty = FROM_POUNDS(isImperial, 283975);
targetPaxPayloadData.pilot = PAX_WEIGHT(isImperial);
targetPaxPayloadData.firstOfficer = PAX_WEIGHT(isImperial);
targetPaxPayloadData.engineer = PAX_WEIGHT(isImperial);
targetPaxPayloadData.cabinCrewFront = FRONT_CREW_WEIGHT(isImperial);
targetPaxPayloadData.cabinCrewRear = REAR_CREW_WEIGHT(isImperial);
targetPaxPayloadData.leftAux = isER ? AUX_WEIGHT(isImperial) : 0;
targetPaxPayloadData.rightAux = isER ? AUX_WEIGHT(isImperial) : 0;
FuelData_t liveFuelData = FuelData_t();
distribute(&targetPaxPayloadData, &liveFuelData, 162000.0, 20.5, isImperial);
}

View File

@ -1,109 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{992caf4b-b3f6-4a86-a1c1-663686082c5e}</ProjectGuid>
<RootNamespace>loadmanagercli</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="pax.cpp" />
<ClCompile Include="load-manager-cli.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="pax.h" />
<ClInclude Include="types.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,34 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>
rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="load-manager-cli.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pax.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pax.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="types.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

File diff suppressed because it is too large Load Diff

View File

@ -1,45 +1,47 @@
#pragma once #pragma once
#ifndef __INTELLISENSE__ #ifndef __INTELLISENSE__
# define MODULE_EXPORT __attribute__( ( visibility( "default" ) ) ) #define MODULE_EXPORT __attribute__((visibility("default")))
# define MODULE_WASM_MODNAME(mod) __attribute__((import_module(mod))) #define MODULE_WASM_MODNAME(mod) __attribute__((import_module(mod)))
#else #else
# define MODULE_EXPORT #define MODULE_EXPORT
# define MODULE_WASM_MODNAME(mod) #define MODULE_WASM_MODNAME(mod)
# define __attribute__(x) #define __attribute__(x)
# define __restrict__ #define __restrict__
#endif #endif
/********************************* Headers *********************************/ /********************************* Headers *********************************/
// MSFS headers // MSFS headers
#include "rapidjson/filewritestream.h"
#include <MSFS/Legacy/gauges.h>
#include <MSFS/MSFS.h> #include <MSFS/MSFS.h>
#include <MSFS/MSFS_CommBus.h> #include <MSFS/MSFS_CommBus.h>
#include <MSFS/Legacy/gauges.h> #include <SimConnect.h>
#include <rapidjson/document.h> #include <rapidjson/document.h>
#include <rapidjson/filereadstream.h> #include <rapidjson/filereadstream.h>
#include "rapidjson/filewritestream.h"
#include <rapidjson/writer.h> #include <rapidjson/writer.h>
#include <SimConnect.h>
// C headers // C headers
#include <string.h> #include <string.h>
// C++ headers // C++ headers
#include <ctime> #include <ctime>
// Own headers // Own headers
#include "shared.h"
#include "pax.h"
#include "freighter.h" #include "freighter.h"
#include "fuel.h"
#include "pax.h"
#include "shared.h"
/******************************** Constants ********************************/ /******************************** Constants ********************************/
// Module identification // Module identification
#define MODULE_NAME "[KHOFMANN TFDi MD-11 Load Manager] " #define MODULE_NAME "[KHOFMANN TFDi MD-11 Load Manager] "
#define VERSION_STRING "1.15" #define VERSION_STRING "2.9-beta"
// COMM BUS // COMM BUS
#define COMM_BUS_LIVE_DATA_EVENT "khofmann_tfdi_md-11_load_manager_live_data" #define COMM_BUS_LIVE_DATA_EVENT "khofmann_tfdi_md-11_load_manager_live_data"
#define COMM_BUS_UPDATE_TARGET_EVENT "khofmann_tfdi_md-11_load_manager_update_target" #define COMM_BUS_UPDATE_TARGET_EVENT "khofmann_tfdi_md-11_load_manager_update_target"
/******************************** Functions ********************************/ /******************************** Functions ********************************/
void commBusUpdateTargetCallback(const char* args, unsigned int size, void* ctx); void commBusUpdateTargetCallback(const char *args, unsigned int size, void *ctx);
int receiveData(const char* buf); int receiveData(const char *buf);
void sendData(); void sendData();
void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContext); void CALLBACK MyDispatchProc(SIMCONNECT_RECV *pData, DWORD cbData, void *pContext);
void log(FILE* file, const char* format, void* optionalElement = NULL); void log(FILE *file, const char *format, void *optionalElement = NULL);

View File

@ -5,28 +5,16 @@ VisualStudioVersion = 17.13.36105.23
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "load-manager", "load-manager.vcxproj", "{A5468B35-BBBD-4C55-97ED-81BFE343B0E4}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "load-manager", "load-manager.vcxproj", "{A5468B35-BBBD-4C55-97ED-81BFE343B0E4}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "load-manager-cli", "load-manager-cli.vcxproj", "{992CAF4B-B3F6-4A86-A1C1-663686082C5E}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|MSFS = Debug|MSFS Debug|MSFS = Debug|MSFS
Debug|x64 = Debug|x64
Release|MSFS = Release|MSFS Release|MSFS = Release|MSFS
Release|x64 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A5468B35-BBBD-4C55-97ED-81BFE343B0E4}.Debug|MSFS.ActiveCfg = Debug|MSFS {A5468B35-BBBD-4C55-97ED-81BFE343B0E4}.Debug|MSFS.ActiveCfg = Debug|MSFS
{A5468B35-BBBD-4C55-97ED-81BFE343B0E4}.Debug|MSFS.Build.0 = Debug|MSFS {A5468B35-BBBD-4C55-97ED-81BFE343B0E4}.Debug|MSFS.Build.0 = Debug|MSFS
{A5468B35-BBBD-4C55-97ED-81BFE343B0E4}.Debug|x64.ActiveCfg = Debug|x64
{A5468B35-BBBD-4C55-97ED-81BFE343B0E4}.Release|MSFS.ActiveCfg = Release|MSFS {A5468B35-BBBD-4C55-97ED-81BFE343B0E4}.Release|MSFS.ActiveCfg = Release|MSFS
{A5468B35-BBBD-4C55-97ED-81BFE343B0E4}.Release|MSFS.Build.0 = Release|MSFS {A5468B35-BBBD-4C55-97ED-81BFE343B0E4}.Release|MSFS.Build.0 = Release|MSFS
{A5468B35-BBBD-4C55-97ED-81BFE343B0E4}.Release|x64.ActiveCfg = Release|MSFS
{992CAF4B-B3F6-4A86-A1C1-663686082C5E}.Debug|MSFS.ActiveCfg = Debug|x64
{992CAF4B-B3F6-4A86-A1C1-663686082C5E}.Debug|x64.ActiveCfg = Debug|x64
{992CAF4B-B3F6-4A86-A1C1-663686082C5E}.Debug|x64.Build.0 = Debug|x64
{992CAF4B-B3F6-4A86-A1C1-663686082C5E}.Release|MSFS.ActiveCfg = Release|x64
{992CAF4B-B3F6-4A86-A1C1-663686082C5E}.Release|x64.ActiveCfg = Release|x64
{992CAF4B-B3F6-4A86-A1C1-663686082C5E}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -288,12 +288,14 @@ Powershell.exe -File .\copy-release.ps1</Command>
<ClCompile Include="freighter.cpp" /> <ClCompile Include="freighter.cpp" />
<ClCompile Include="load-manager.cpp" /> <ClCompile Include="load-manager.cpp" />
<ClCompile Include="pax.cpp" /> <ClCompile Include="pax.cpp" />
<ClCompile Include="fuel.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="freighter.h" /> <ClInclude Include="freighter.h" />
<ClInclude Include="load-manager.h" /> <ClInclude Include="load-manager.h" />
<ClInclude Include="pax.h" /> <ClInclude Include="pax.h" />
<ClInclude Include="shared.h" /> <ClInclude Include="shared.h" />
<ClInclude Include="fuel.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

View File

@ -1,329 +1,325 @@
#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 UserData_t* const userData, void distribute(paxPayloadData_t *const targetPayload, const FuelData_t *const fuel, const double ZFWTarget,
const UserOptions_t* const userOptions) { const UserData_t *const userData, const UserOptions_t *const userOptions) {
// 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->cabinCrewFront - targetPayload->cabinCrewRear - targetPayload->leftAux - targetPayload->rightAux; targetPayload->engineer - targetPayload->cabinCrewFront - targetPayload->cabinCrewRear -
unsigned short numPax = max(0.0, min((double)MAX_PAX, floor(payload / (PAX_WEIGHT(userData->isImperial, userOptions) + targetPayload->leftAux - targetPayload->rightAux;
BAG_WEIGHT(userData->isImperial, userOptions))))); unsigned short numPax = max(0.0, min((double)MAX_PAX, floor(payload / (PAX_WEIGHT(userData->isImperial, userOptions) +
unsigned int cargo = round(payload - numPax * PAX_WEIGHT(userData->isImperial, userOptions) - numPax * BAG_WEIGHT(userData->isImperial, userOptions)); BAG_WEIGHT(userData->isImperial, userOptions)))));
unsigned int cargo = round(payload - numPax * PAX_WEIGHT(userData->isImperial, userOptions) -
numPax * BAG_WEIGHT(userData->isImperial, userOptions));
distribute(targetPayload, fuel, numPax, cargo, userData, userOptions); distribute(targetPayload, fuel, numPax, cargo, userData, userOptions);
} }
// 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 UserData_t* const userData, void distribute(paxPayloadData_t *const targetPayload, const FuelData_t *const fuel, unsigned short numPax, unsigned int cargo,
const UserOptions_t* const userOptions) { const UserData_t *const userData, const UserOptions_t *const userOptions) {
// 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.total = 0; targetPayload->paxCount.economy2 = targetPayload->paxCount.total = 0;
targetPayload->forwardCargo = targetPayload->rearCargo = 0; targetPayload->forwardCargo = targetPayload->rearCargo = 0;
unsigned short _numPax = 0; unsigned short _numPax = 0;
unsigned int count = MAX_PAX; unsigned int count = MAX_PAX;
// Initial distribution pax + bags // Initial distribution pax + bags
while (numPax > 0 && count > 0) { while (numPax > 0 && count > 0) {
if (numPax >= 4) { if (numPax >= 4) {
if (targetPayload->paxCount.business1 < MAX_BUSINESS_1) { if (targetPayload->paxCount.business1 < MAX_BUSINESS_1) {
targetPayload->paxCount.business1++; targetPayload->paxCount.business1++;
_numPax++; _numPax++;
} }
if (targetPayload->paxCount.business2 < MAX_BUSINESS_2) { if (targetPayload->paxCount.business2 < MAX_BUSINESS_2) {
targetPayload->paxCount.business2++; targetPayload->paxCount.business2++;
_numPax++; _numPax++;
} }
if (targetPayload->paxCount.economy1 < MAX_ECONOMY_1) { if (targetPayload->paxCount.economy1 < MAX_ECONOMY_1) {
targetPayload->paxCount.economy1++; targetPayload->paxCount.economy1++;
_numPax++; _numPax++;
} }
if (targetPayload->paxCount.economy2 < MAX_ECONOMY_2) { if (targetPayload->paxCount.economy2 < MAX_ECONOMY_2) {
targetPayload->paxCount.economy2++; targetPayload->paxCount.economy2++;
_numPax++; _numPax++;
} }
} } else if (numPax == 3) {
else if (numPax == 3) { if (targetPayload->paxCount.business2 < MAX_BUSINESS_2) {
if (targetPayload->paxCount.business2 < MAX_BUSINESS_2) { targetPayload->paxCount.business2++;
targetPayload->paxCount.business2++; _numPax++;
_numPax++; }
} if (targetPayload->paxCount.economy1 < MAX_ECONOMY_1) {
if (targetPayload->paxCount.economy1 < MAX_ECONOMY_1) { targetPayload->paxCount.economy1++;
targetPayload->paxCount.economy1++; _numPax++;
_numPax++; }
} if (targetPayload->paxCount.economy2 < MAX_ECONOMY_2) {
if (targetPayload->paxCount.economy2 < MAX_ECONOMY_2) { targetPayload->paxCount.economy2++;
targetPayload->paxCount.economy2++; _numPax++;
_numPax++; }
} } else if (numPax == 2) {
} if (targetPayload->paxCount.economy1 < MAX_ECONOMY_1) {
else if (numPax == 2) { targetPayload->paxCount.economy1++;
if (targetPayload->paxCount.economy1 < MAX_ECONOMY_1) { _numPax++;
targetPayload->paxCount.economy1++; }
_numPax++; if (targetPayload->paxCount.economy2 < MAX_ECONOMY_2) {
} targetPayload->paxCount.economy2++;
if (targetPayload->paxCount.economy2 < MAX_ECONOMY_2) { _numPax++;
targetPayload->paxCount.economy2++; }
_numPax++; } else if (numPax == 1) {
} if (targetPayload->paxCount.economy2 < MAX_ECONOMY_2) {
} targetPayload->paxCount.economy2++;
else if (numPax == 1) { _numPax++;
if (targetPayload->paxCount.economy2 < MAX_ECONOMY_2) { }
targetPayload->paxCount.economy2++;
_numPax++;
}
}
numPax -= _numPax;
targetPayload->paxCount.total += _numPax;
if (_numPax % 2 == 0) {
targetPayload->forwardCargo += (_numPax / 2) * BAG_WEIGHT(userData->isImperial, userOptions);
targetPayload->rearCargo += (_numPax / 2) * BAG_WEIGHT(userData->isImperial, userOptions);
}
else {
_numPax--;
targetPayload->forwardCargo += (_numPax / 2 + 1) * BAG_WEIGHT(userData->isImperial, userOptions);
targetPayload->rearCargo += (_numPax / 2) * BAG_WEIGHT(userData->isImperial, userOptions);
}
_numPax = 0;
count--;
} }
count = MAX_FRONT_CARGO(userData->isImperial); numPax -= _numPax;
// Initial distibution of remaining cargo targetPayload->paxCount.total += _numPax;
while (cargo > 0 && count > 0) {
if (targetPayload->forwardCargo < MAX_FRONT_CARGO(userData->isImperial)) {
targetPayload->forwardCargo++;
cargo--;
}
if (targetPayload->rearCargo < MAX_REAR_CARGO(userData->isImperial, userData->isER) && cargo > 0) {
targetPayload->rearCargo++;
cargo--;
}
count--; if (_numPax % 2 == 0) {
targetPayload->forwardCargo += (_numPax / 2) * BAG_WEIGHT(userData->isImperial, userOptions);
targetPayload->rearCargo += (_numPax / 2) * BAG_WEIGHT(userData->isImperial, userOptions);
} else {
_numPax--;
targetPayload->forwardCargo += (_numPax / 2 + 1) * BAG_WEIGHT(userData->isImperial, userOptions);
targetPayload->rearCargo += (_numPax / 2) * BAG_WEIGHT(userData->isImperial, userOptions);
} }
// Refinement pax
count = MAX_PAX;
unsigned char minBusiness1 = round(targetPayload->paxCount.business1 / 3); _numPax = 0;
unsigned char minBusiness2 = round(targetPayload->paxCount.business2 / 3);
unsigned char minEconomy1 = round(targetPayload->paxCount.economy1 / 3);
unsigned char minEconomy2 = round(targetPayload->paxCount.economy2 / 3);
while (count > 0) { count--;
generatePayload(targetPayload, userData->isImperial, userOptions); }
calculateCGs(targetPayload, fuel, &targetPayload->ZFWCG, &targetPayload->TOCG, userData->isImperial); count = MAX_FRONT_CARGO(userData->isImperial);
// Initial distribution of remaining cargo
// in front of target while (cargo > 0 && count > 0) {
if (targetPayload->ZFWCG < targetPayload->CGTarget - CG_TOLERANCE) { if (targetPayload->forwardCargo < MAX_FRONT_CARGO(userData->isImperial)) {
if (targetPayload->paxCount.business1 > minBusiness1) { targetPayload->forwardCargo++;
targetPayload->paxCount.business1--; cargo--;
}
else if (targetPayload->paxCount.business2 > minBusiness2) {
targetPayload->paxCount.business2--;
}
else if (targetPayload->paxCount.economy1 > minEconomy1) {
targetPayload->paxCount.economy1--;
}
else {
break;
}
if (targetPayload->paxCount.economy2 < MAX_ECONOMY_2) {
targetPayload->paxCount.economy2++;
}
else if (targetPayload->paxCount.economy1 < MAX_ECONOMY_1) {
targetPayload->paxCount.economy1++;
}
else if (targetPayload->paxCount.business2 < MAX_BUSINESS_2) {
targetPayload->paxCount.business2++;
}
else {
targetPayload->paxCount.business1++;
}
}
// behind target
else if (targetPayload->ZFWCG > targetPayload->CGTarget + CG_TOLERANCE) {
if (targetPayload->paxCount.economy2 > minEconomy2) {
targetPayload->paxCount.economy2--;
}
else if (targetPayload->paxCount.economy1 > minEconomy1) {
targetPayload->paxCount.economy1--;
}
else if (targetPayload->paxCount.business2 > minBusiness2) {
targetPayload->paxCount.business2--;
}
else {
break;
}
if (targetPayload->paxCount.business1 < MAX_BUSINESS_1) {
targetPayload->paxCount.business1++;
}
else if (targetPayload->paxCount.business2 < MAX_BUSINESS_2) {
targetPayload->paxCount.business2++;
}
else if (targetPayload->paxCount.economy1 < MAX_ECONOMY_1) {
targetPayload->paxCount.economy1++;
}
else {
targetPayload->paxCount.economy2++;
}
}
else {
break;
}
count--;
} }
// Refinement cargo if (targetPayload->rearCargo < MAX_REAR_CARGO(userData->isImperial, userData->isER) && cargo > 0) {
count = MAX_FRONT_CARGO(userData->isImperial) + MAX_REAR_CARGO(userData->isImperial, userData->isER); targetPayload->rearCargo++;
while (count > 0) { cargo--;
generatePayload(targetPayload, userData->isImperial, userOptions);
calculateCGs(targetPayload, fuel, &targetPayload->ZFWCG, &targetPayload->TOCG, userData->isImperial);
// in front of target
if (targetPayload->ZFWCG < targetPayload->CGTarget - CG_TOLERANCE) {
if (targetPayload->forwardCargo > 0 && targetPayload->rearCargo < MAX_REAR_CARGO(userData->isImperial, userData->isER)) {
if (targetPayload->forwardCargo > BAG_WEIGHT(userData->isImperial, userOptions) &&
targetPayload->rearCargo < MAX_FRONT_CARGO(userData->isImperial) - BAG_WEIGHT(userData->isImperial, userOptions)) {
targetPayload->forwardCargo -= BAG_WEIGHT(userData->isImperial, userOptions);
targetPayload->rearCargo += BAG_WEIGHT(userData->isImperial, userOptions);
}
else {
targetPayload->forwardCargo--;
targetPayload->rearCargo++;
}
}
else {
break;
}
}
// behind target
else if (targetPayload->ZFWCG > targetPayload->CGTarget + CG_TOLERANCE) {
if (targetPayload->rearCargo > 0 && targetPayload->forwardCargo < MAX_FRONT_CARGO(userData->isImperial)) {
if (targetPayload->rearCargo > BAG_WEIGHT(userData->isImperial, userOptions) &&
targetPayload->forwardCargo < MAX_REAR_CARGO(userData->isImperial, userData->isER) - BAG_WEIGHT(userData->isImperial, userOptions)) {
targetPayload->rearCargo -= BAG_WEIGHT(userData->isImperial, userOptions);
targetPayload->forwardCargo += BAG_WEIGHT(userData->isImperial, userOptions);
}
else {
targetPayload->rearCargo--;
targetPayload->forwardCargo++;
}
}
else {
break;
}
}
else {
break;
}
count--;
} }
count--;
}
// Refinement pax
count = MAX_PAX;
unsigned char minBusiness1 = round(targetPayload->paxCount.business1 / 3);
unsigned char minBusiness2 = round(targetPayload->paxCount.business2 / 3);
unsigned char minEconomy1 = round(targetPayload->paxCount.economy1 / 3);
unsigned char minEconomy2 = round(targetPayload->paxCount.economy2 / 3);
while (count > 0) {
generatePayload(targetPayload, userData->isImperial, userOptions);
calculateCGs(targetPayload, fuel, userData->isImperial);
// in front of target
if (targetPayload->ZFWCG < targetPayload->CGTarget - CG_TOLERANCE) {
if (targetPayload->paxCount.business1 > minBusiness1) {
targetPayload->paxCount.business1--;
} else if (targetPayload->paxCount.business2 > minBusiness2) {
targetPayload->paxCount.business2--;
} else if (targetPayload->paxCount.economy1 > minEconomy1) {
targetPayload->paxCount.economy1--;
} else {
break;
}
if (targetPayload->paxCount.economy2 < MAX_ECONOMY_2) {
targetPayload->paxCount.economy2++;
} else if (targetPayload->paxCount.economy1 < MAX_ECONOMY_1) {
targetPayload->paxCount.economy1++;
} else if (targetPayload->paxCount.business2 < MAX_BUSINESS_2) {
targetPayload->paxCount.business2++;
} else {
targetPayload->paxCount.business1++;
}
}
// behind target
else if (targetPayload->ZFWCG > targetPayload->CGTarget + CG_TOLERANCE) {
if (targetPayload->paxCount.economy2 > minEconomy2) {
targetPayload->paxCount.economy2--;
} else if (targetPayload->paxCount.economy1 > minEconomy1) {
targetPayload->paxCount.economy1--;
} else if (targetPayload->paxCount.business2 > minBusiness2) {
targetPayload->paxCount.business2--;
} else {
break;
}
if (targetPayload->paxCount.business1 < MAX_BUSINESS_1) {
targetPayload->paxCount.business1++;
} else if (targetPayload->paxCount.business2 < MAX_BUSINESS_2) {
targetPayload->paxCount.business2++;
} else if (targetPayload->paxCount.economy1 < MAX_ECONOMY_1) {
targetPayload->paxCount.economy1++;
} else {
targetPayload->paxCount.economy2++;
}
} else {
break;
}
count--;
}
// Refinement cargo
count = MAX_FRONT_CARGO(userData->isImperial) + MAX_REAR_CARGO(userData->isImperial, userData->isER);
while (count > 0) {
generatePayload(targetPayload, userData->isImperial, userOptions);
calculateCGs(targetPayload, fuel, userData->isImperial);
// in front of target
if (targetPayload->ZFWCG < targetPayload->CGTarget - CG_TOLERANCE) {
if (targetPayload->forwardCargo > 0 && targetPayload->rearCargo < MAX_REAR_CARGO(userData->isImperial, userData->isER)) {
if (targetPayload->forwardCargo > BAG_WEIGHT(userData->isImperial, userOptions) &&
targetPayload->rearCargo < MAX_FRONT_CARGO(userData->isImperial) - BAG_WEIGHT(userData->isImperial, userOptions)) {
targetPayload->forwardCargo -= BAG_WEIGHT(userData->isImperial, userOptions);
targetPayload->rearCargo += BAG_WEIGHT(userData->isImperial, userOptions);
} else {
targetPayload->forwardCargo--;
targetPayload->rearCargo++;
}
} else {
break;
}
}
// behind target
else if (targetPayload->ZFWCG > targetPayload->CGTarget + CG_TOLERANCE) {
if (targetPayload->rearCargo > 0 && targetPayload->forwardCargo < MAX_FRONT_CARGO(userData->isImperial)) {
if (targetPayload->rearCargo > BAG_WEIGHT(userData->isImperial, userOptions) &&
targetPayload->forwardCargo <
MAX_REAR_CARGO(userData->isImperial, userData->isER) - BAG_WEIGHT(userData->isImperial, userOptions)) {
targetPayload->rearCargo -= BAG_WEIGHT(userData->isImperial, userOptions);
targetPayload->forwardCargo += BAG_WEIGHT(userData->isImperial, userOptions);
} else {
targetPayload->rearCargo--;
targetPayload->forwardCargo++;
}
} else {
break;
}
} else {
break;
}
count--;
}
} }
// Updates pax stations with their respective weights // Updates pax stations with their respective weights
// Used internally and used for Station Entry (pax only, cargo is set directly) // Used internally and used for Station Entry (pax only, cargo is set directly)
void generatePayload(paxPayloadData_t* const targetPayload, const bool isImperial, const UserOptions_t* const userOptions) { void generatePayload(paxPayloadData_t *const targetPayload, const bool isImperial, const UserOptions_t *const userOptions) {
targetPayload->business1Left = targetPayload->business1Center = targetPayload->business1Right = (targetPayload->paxCount.business1 / 3.0) * PAX_WEIGHT(isImperial, userOptions); targetPayload->business1Left = targetPayload->business1Center = targetPayload->business1Right =
targetPayload->business2Left = targetPayload->business2Center = targetPayload->business2Right = (targetPayload->paxCount.business2 / 3.0) * PAX_WEIGHT(isImperial, userOptions); (targetPayload->paxCount.business1 / 3.0) * PAX_WEIGHT(isImperial, userOptions);
targetPayload->economy1Left = targetPayload->economy1Center = targetPayload->economy1Right = (targetPayload->paxCount.economy1 / 3.0) * PAX_WEIGHT(isImperial, userOptions); targetPayload->business2Left = targetPayload->business2Center = targetPayload->business2Right =
targetPayload->economy2Left = targetPayload->economy2Center = targetPayload->economy2Right = (targetPayload->paxCount.economy2 / 3.0) * PAX_WEIGHT(isImperial, userOptions); (targetPayload->paxCount.business2 / 3.0) * PAX_WEIGHT(isImperial, userOptions);
targetPayload->total = targetPayload->empty + targetPayload->pilot + targetPayload->firstOfficer + targetPayload->engineer + targetPayload->cabinCrewFront + targetPayload->economy1Left = targetPayload->economy1Center = targetPayload->economy1Right =
targetPayload->business1Left + targetPayload->business1Center + targetPayload->business1Right + targetPayload->business2Left + (targetPayload->paxCount.economy1 / 3.0) * PAX_WEIGHT(isImperial, userOptions);
targetPayload->business2Center + targetPayload->business2Right + targetPayload->economy1Left + targetPayload->economy1Center + targetPayload->economy2Left = targetPayload->economy2Center = targetPayload->economy2Right =
targetPayload->economy1Right + targetPayload->economy2Left + targetPayload->economy2Center + targetPayload->economy2Right + (targetPayload->paxCount.economy2 / 3.0) * PAX_WEIGHT(isImperial, userOptions);
targetPayload->cabinCrewRear + targetPayload->forwardCargo + targetPayload->rearCargo + targetPayload->leftAux + targetPayload->rightAux; targetPayload->total = targetPayload->empty + targetPayload->pilot + targetPayload->firstOfficer + targetPayload->engineer +
targetPayload->cabinCrewFront + targetPayload->business1Left + targetPayload->business1Center +
targetPayload->business1Right + targetPayload->business2Left + targetPayload->business2Center +
targetPayload->business2Right + targetPayload->economy1Left + targetPayload->economy1Center +
targetPayload->economy1Right + targetPayload->economy2Left + targetPayload->economy2Center +
targetPayload->economy2Right + targetPayload->cabinCrewRear + targetPayload->forwardCargo +
targetPayload->rearCargo + targetPayload->leftAux + targetPayload->rightAux;
} }
// Normalise to Pounds // Normalise to Pounds
// MANDATORY BEFORE SETTING WEIGHTS // MANDATORY BEFORE SETTING WEIGHTS
// USE ON COPY OF GLOBAL STATE ONLY // USE ON COPY OF GLOBAL STATE ONLY
void normalisePayload(paxPayloadData_t* const targetPayload, const bool isImperial) { void normalisePayload(paxPayloadData_t *const targetPayload, const bool isImperial) {
targetPayload->empty = TO_POUNDS(isImperial, targetPayload->empty); targetPayload->empty = TO_POUNDS(isImperial, targetPayload->empty);
targetPayload->pilot = TO_POUNDS(isImperial, targetPayload->pilot); targetPayload->pilot = TO_POUNDS(isImperial, targetPayload->pilot);
targetPayload->firstOfficer = TO_POUNDS(isImperial, targetPayload->firstOfficer); targetPayload->firstOfficer = TO_POUNDS(isImperial, targetPayload->firstOfficer);
targetPayload->engineer = TO_POUNDS(isImperial, targetPayload->engineer); targetPayload->engineer = TO_POUNDS(isImperial, targetPayload->engineer);
targetPayload->cabinCrewFront = TO_POUNDS(isImperial, targetPayload->cabinCrewFront); targetPayload->cabinCrewFront = TO_POUNDS(isImperial, targetPayload->cabinCrewFront);
targetPayload->business1Left = TO_POUNDS(isImperial, targetPayload->business1Left); targetPayload->business1Left = TO_POUNDS(isImperial, targetPayload->business1Left);
targetPayload->business1Center = TO_POUNDS(isImperial, targetPayload->business1Center); targetPayload->business1Center = TO_POUNDS(isImperial, targetPayload->business1Center);
targetPayload->business1Right = TO_POUNDS(isImperial, targetPayload->business1Right); targetPayload->business1Right = TO_POUNDS(isImperial, targetPayload->business1Right);
targetPayload->business2Left = TO_POUNDS(isImperial, targetPayload->business2Left); targetPayload->business2Left = TO_POUNDS(isImperial, targetPayload->business2Left);
targetPayload->business2Center = TO_POUNDS(isImperial, targetPayload->business2Center); targetPayload->business2Center = TO_POUNDS(isImperial, targetPayload->business2Center);
targetPayload->business2Right = TO_POUNDS(isImperial, targetPayload->business2Right); targetPayload->business2Right = TO_POUNDS(isImperial, targetPayload->business2Right);
targetPayload->economy1Left = TO_POUNDS(isImperial, targetPayload->economy1Left); targetPayload->economy1Left = TO_POUNDS(isImperial, targetPayload->economy1Left);
targetPayload->economy1Center = TO_POUNDS(isImperial, targetPayload->economy1Center); targetPayload->economy1Center = TO_POUNDS(isImperial, targetPayload->economy1Center);
targetPayload->economy1Right = TO_POUNDS(isImperial, targetPayload->economy1Right); targetPayload->economy1Right = TO_POUNDS(isImperial, targetPayload->economy1Right);
targetPayload->economy2Left = TO_POUNDS(isImperial, targetPayload->economy2Left); targetPayload->economy2Left = TO_POUNDS(isImperial, targetPayload->economy2Left);
targetPayload->economy2Center = TO_POUNDS(isImperial, targetPayload->economy2Center); targetPayload->economy2Center = TO_POUNDS(isImperial, targetPayload->economy2Center);
targetPayload->economy2Right = TO_POUNDS(isImperial, targetPayload->economy2Right); targetPayload->economy2Right = TO_POUNDS(isImperial, targetPayload->economy2Right);
targetPayload->cabinCrewRear = TO_POUNDS(isImperial, targetPayload->cabinCrewRear); targetPayload->cabinCrewRear = TO_POUNDS(isImperial, targetPayload->cabinCrewRear);
targetPayload->forwardCargo = TO_POUNDS(isImperial, targetPayload->forwardCargo); targetPayload->forwardCargo = TO_POUNDS(isImperial, targetPayload->forwardCargo);
targetPayload->rearCargo = TO_POUNDS(isImperial, targetPayload->rearCargo); targetPayload->rearCargo = TO_POUNDS(isImperial, targetPayload->rearCargo);
targetPayload->leftAux = TO_POUNDS(isImperial, targetPayload->leftAux); targetPayload->leftAux = TO_POUNDS(isImperial, targetPayload->leftAux);
targetPayload->rightAux = TO_POUNDS(isImperial, targetPayload->rightAux); targetPayload->rightAux = TO_POUNDS(isImperial, targetPayload->rightAux);
} }
void calculateCGs(const paxPayloadData_t* const targetPayload, const FuelData_t* const fuel, double* const ZFWCG, double* const TOCG, const bool isImperial) { void calculateCGs(paxPayloadData_t *const targetPayload, const FuelData_t *const fuel, const bool isImperial) {
paxPayloadData_t localPayload = {}; paxPayloadData_t localPayload = {};
memcpy(&localPayload, targetPayload, sizeof(localPayload)); memcpy(&localPayload, targetPayload, sizeof(localPayload));
normalisePayload(&localPayload, isImperial); normalisePayload(&localPayload, isImperial);
double totalMoment = localPayload.empty * ARM_EMPTY + localPayload.pilot * ARM_PILOT + localPayload.firstOfficer * ARM_FIRST_OFFICER + double totalMoment =
localPayload.engineer * ARM_ENGINEER + localPayload.cabinCrewFront * ARM_PAX_CABIN_CREW_FRONT + localPayload.empty * ARM_EMPTY + localPayload.pilot * ARM_PILOT + localPayload.firstOfficer * ARM_FIRST_OFFICER +
localPayload.business1Left * ARM_PAX_BUSINESS1_LEFT + localPayload.business1Center * ARM_PAX_BUSINESS1_CENTER + localPayload.engineer * ARM_ENGINEER + localPayload.cabinCrewFront * ARM_PAX_CABIN_CREW_FRONT +
localPayload.business1Right * ARM_PAX_BUSINESS1_RIGHT + localPayload.business2Left * ARM_PAX_BUSINESS2_LEFT + localPayload.business1Left * ARM_PAX_BUSINESS1_LEFT + localPayload.business1Center * ARM_PAX_BUSINESS1_CENTER +
localPayload.business2Center * ARM_PAX_BUSINESS2_CENTER + localPayload.business2Right * ARM_PAX_BUSINESS2_RIGHT + localPayload.business1Right * ARM_PAX_BUSINESS1_RIGHT + localPayload.business2Left * ARM_PAX_BUSINESS2_LEFT +
localPayload.economy1Left * ARM_PAX_ECONOMY1_LEFT + localPayload.economy1Center * ARM_PAX_ECONOMY1_CENTER + localPayload.business2Center * ARM_PAX_BUSINESS2_CENTER + localPayload.business2Right * ARM_PAX_BUSINESS2_RIGHT +
localPayload.economy1Right * ARM_PAX_ECONOMY1_RIGHT + localPayload.economy2Left * ARM_PAX_ECONOMY2_LEFT + localPayload.economy1Left * ARM_PAX_ECONOMY1_LEFT + localPayload.economy1Center * ARM_PAX_ECONOMY1_CENTER +
localPayload.economy2Center * ARM_PAX_ECONOMY2_CENTER + localPayload.economy2Right * ARM_PAX_ECONOMY2_RIGHT + localPayload.economy1Right * ARM_PAX_ECONOMY1_RIGHT + localPayload.economy2Left * ARM_PAX_ECONOMY2_LEFT +
localPayload.cabinCrewRear * ARM_PAX_CABIN_CREW_REAR + localPayload.forwardCargo * ARM_FORWARD_CARGO + localPayload.economy2Center * ARM_PAX_ECONOMY2_CENTER + localPayload.economy2Right * ARM_PAX_ECONOMY2_RIGHT +
localPayload.rearCargo * ARM_REAR_CARGO + localPayload.leftAux * ARM_LEFT_AUX + localPayload.rightAux * ARM_RIGHT_AUX; localPayload.cabinCrewRear * ARM_PAX_CABIN_CREW_REAR + localPayload.forwardCargo * ARM_FORWARD_CARGO +
localPayload.rearCargo * ARM_REAR_CARGO + localPayload.leftAux * ARM_LEFT_AUX + localPayload.rightAux * ARM_RIGHT_AUX;
double totalWeight = localPayload.empty + localPayload.pilot + localPayload.firstOfficer + localPayload.engineer + localPayload.cabinCrewFront + double totalWeight = localPayload.empty + localPayload.pilot + localPayload.firstOfficer + localPayload.engineer +
localPayload.business1Left + localPayload.business1Center + localPayload.business1Right + localPayload.business2Left + localPayload.cabinCrewFront + localPayload.business1Left + localPayload.business1Center +
localPayload.business2Center + localPayload.business2Right + localPayload.economy1Left + localPayload.economy1Center + localPayload.business1Right + localPayload.business2Left + localPayload.business2Center +
localPayload.economy1Right + localPayload.economy2Left + localPayload.economy2Center + localPayload.economy2Right + localPayload.business2Right + localPayload.economy1Left + localPayload.economy1Center +
localPayload.cabinCrewRear + localPayload.forwardCargo + localPayload.rearCargo + localPayload.leftAux + localPayload.rightAux; localPayload.economy1Right + localPayload.economy2Left + localPayload.economy2Center +
localPayload.economy2Right + localPayload.cabinCrewRear + localPayload.forwardCargo +
localPayload.rearCargo + localPayload.leftAux + localPayload.rightAux;
*ZFWCG = TO_PERCENT_MAC(totalMoment / totalWeight); targetPayload->ZFWCG = TO_PERCENT_MAC(totalMoment / totalWeight);
totalMoment += fuel->main1 * ARM_MAIN1 + fuel->main3 * ARM_MAIN3 + fuel->main2 * ARM_MAIN2 + fuel->upperAux * ARM_UPPER_AUX + 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->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; fuel->tail * ARM_TAIL + fuel->forwardAux1 * ARM_FORWARD_AUX1 + fuel->forwardAux2 * ARM_FORWARD_AUX2;
totalWeight += fuel->total; totalWeight += fuel->total;
*TOCG = TO_PERCENT_MAC(totalMoment / totalWeight); targetPayload->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));
normalisePayload(&localPayload, isImperial); normalisePayload(&localPayload, isImperial);
SimConnect_SetDataOnSimObject(simConnect, DATA_DEFINITION_PAYLOAD_PAX, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(paxPayloadDataSet_t), &localPayload); localPayload._ZFWCG = localPayload.ZFWCG / 100.0;
SimConnect_SetDataOnSimObject(simConnect, DATA_DEFINITION_PAYLOAD_PAX, SIMCONNECT_OBJECT_ID_USER, 0, 0,
sizeof(paxPayloadDataSet_t), &localPayload);
} }
void unload(const HANDLE simConnect, const bool isER) { void unload(const HANDLE simConnect, const bool isER) {
paxPayloadDataSet_t localPayload = {}; paxPayloadData_t localPayload = {};
localPayload.cabinCrewFront = FRONT_CREW_WEIGHT(true); localPayload.cabinCrewFront = FRONT_CREW_WEIGHT(true);
localPayload.cabinCrewRear = REAR_CREW_WEIGHT(true); localPayload.cabinCrewRear = REAR_CREW_WEIGHT(true);
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(paxPayloadDataSet_t), &localPayload); localPayload._ZFWCG = -1;
SimConnect_SetDataOnSimObject(simConnect, DATA_DEFINITION_PAYLOAD_PAX, SIMCONNECT_OBJECT_ID_USER, 0, 0,
sizeof(paxPayloadDataSet_t), &localPayload);
} }
const double PAX_WEIGHT(const bool isImperial, const UserOptions_t* const options) { const double PAX_WEIGHT(const bool isImperial, const UserOptions_t *const options) {
return (isImperial) ? (options->paxWeightLBS) : (options->paxWeightKG); return (isImperial) ? (options->paxWeightLBS) : (options->paxWeightKG);
} }
const double BAG_WEIGHT(const bool isImperial, const UserOptions_t* const options) { const double BAG_WEIGHT(const bool isImperial, const UserOptions_t *const options) {
return (isImperial) ? (options->bagWeightLBS) : (options->bagWeightKG); return (isImperial) ? (options->bagWeightLBS) : (options->bagWeightKG);
} }

View File

@ -1,13 +1,13 @@
#pragma once #pragma once
#ifndef __INTELLISENSE__ #ifndef __INTELLISENSE__
# define MODULE_EXPORT __attribute__( ( visibility( "default" ) ) ) #define MODULE_EXPORT __attribute__((visibility("default")))
# define MODULE_WASM_MODNAME(mod) __attribute__((import_module(mod))) #define MODULE_WASM_MODNAME(mod) __attribute__((import_module(mod)))
#else #else
# define MODULE_EXPORT #define MODULE_EXPORT
# define MODULE_WASM_MODNAME(mod) #define MODULE_WASM_MODNAME(mod)
# define __attribute__(x) #define __attribute__(x)
# define __restrict__ #define __restrict__
#endif #endif
/********************************* Headers *********************************/ /********************************* Headers *********************************/
@ -19,6 +19,7 @@
// C++ headers // C++ headers
#include <algorithm> #include <algorithm>
// Own headers // Own headers
#include "fuel.h"
#include "shared.h" #include "shared.h"
/******************************** Constants ********************************/ /******************************** Constants ********************************/
@ -59,92 +60,95 @@
/***************************** Data structures *****************************/ /***************************** Data structures *****************************/
typedef struct { typedef struct {
// SimConnect mapped // SimConnect mapped
double pilot; double pilot;
double firstOfficer; double firstOfficer;
double engineer; double engineer;
double cabinCrewFront; double cabinCrewFront;
double business1Left; double business1Left;
double business1Center; double business1Center;
double business1Right; double business1Right;
double business2Left; double business2Left;
double business2Center; double business2Center;
double business2Right; double business2Right;
double economy1Left; double economy1Left;
double economy1Center; double economy1Center;
double economy1Right; double economy1Right;
double economy2Left; double economy2Left;
double economy2Center; double economy2Center;
double economy2Right; double economy2Right;
double cabinCrewRear; double cabinCrewRear;
double forwardCargo; double forwardCargo;
double rearCargo; double rearCargo;
double leftAux; double leftAux;
double rightAux; double rightAux;
double _ZFWCG; // DO NOT USE
// Additional properties // Additional properties
double empty; double empty;
double total; double total;
double CGTarget; double CGTarget;
double ZFWCG; double ZFWCG;
double TOCG; double TOCG;
struct paxCount { struct paxCount {
unsigned char business1; unsigned char business1;
unsigned char business2; unsigned char business2;
unsigned char economy1; unsigned char economy1;
unsigned char economy2; unsigned char economy2;
unsigned short total; unsigned short total;
} paxCount; } paxCount;
struct sbPlanned { struct sbPlanned {
double ZFW; double ZFW;
double GW; double GW;
unsigned short pax; double fuel;
unsigned int cargo; unsigned short pax;
} sbPlanned; unsigned int cargo;
} sbPlanned;
} paxPayloadData_t; } paxPayloadData_t;
typedef struct { typedef struct {
double pilot; double pilot;
double firstOfficer; double firstOfficer;
double engineer; double engineer;
double cabinCrewFront; double cabinCrewFront;
double business1Left; double business1Left;
double business1Center; double business1Center;
double business1Right; double business1Right;
double business2Left; double business2Left;
double business2Center; double business2Center;
double business2Right; double business2Right;
double economy1Left; double economy1Left;
double economy1Center; double economy1Center;
double economy1Right; double economy1Right;
double economy2Left; double economy2Left;
double economy2Center; double economy2Center;
double economy2Right; double economy2Right;
double cabinCrewRear; double cabinCrewRear;
double forwardCargo; double forwardCargo;
double rearCargo; double rearCargo;
double leftAux; double leftAux;
double rightAux; double rightAux;
double ZFWCG;
} paxPayloadDataSet_t; } paxPayloadDataSet_t;
/******************************** Functions ********************************/ /******************************** Functions ********************************/
//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 UserData_t* const userData, void distribute(paxPayloadData_t *const targetPayload, const FuelData_t *const fuel, const double ZFWTarget,
const UserOptions_t* const userOptions); const UserData_t *const userData, const UserOptions_t *const userOptions);
//SimBrief Entry, SB pax count and total cargo // SimBrief Entry, SB pax count and total cargo
void distribute(paxPayloadData_t* const targetPayload, const FuelData_t* const fuel, unsigned short numPax, unsigned int cargo, const UserData_t* const userData, void distribute(paxPayloadData_t *const targetPayload, const FuelData_t *const fuel, unsigned short numPax, unsigned int cargo,
const UserOptions_t* const userOptions); const UserData_t *const userData, const UserOptions_t *const userOptions);
// Updates pax stations with their respective weights // Updates pax stations with their respective weights
// Used internally and used for Station Entry (pax only, cargo is ste directly) // Used internally and used for Station Entry (pax only, cargo is ste directly)
// STATION WEIGHTS ARE NOT NORMALISED TO POUNDS // STATION WEIGHTS ARE NOT NORMALISED TO POUNDS
void generatePayload(paxPayloadData_t* const targetPayload, const bool isImperial, const UserOptions_t* const userOptions); void generatePayload(paxPayloadData_t *const targetPayload, const bool isImperial, const UserOptions_t *const userOptions);
// Normalise to Pounds // Normalise to Pounds
// For Station Entry: CALL AFTER `generatePayload` // For Station Entry: CALL AFTER `generatePayload`
void normalisePayload(paxPayloadData_t* const targetPayload, const bool isImperial); void normalisePayload(paxPayloadData_t *const targetPayload, const bool isImperial);
void calculateCGs(const paxPayloadData_t* const targetPayload, const FuelData_t* const fuel, double* const ZFWCG, double* const TOCG, const bool isImperial); void calculateCGs(paxPayloadData_t *const targetPayload, const FuelData_t *const fuel, const bool isImperial);
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);
void unload(const HANDLE simConnect, const bool isER); void unload(const HANDLE simConnect, const bool isER);
// Based on ICAO/LH findings // Based on ICAO/LH findings
const double PAX_WEIGHT(const bool isImperial, const UserOptions_t* const options); const double PAX_WEIGHT(const bool isImperial, const UserOptions_t *const options);
// Based on ICAO/LH findings // Based on ICAO/LH findings
const double BAG_WEIGHT(const bool isImperial, const UserOptions_t* const options); const double BAG_WEIGHT(const bool isImperial, const UserOptions_t *const options);

View File

@ -1,13 +1,13 @@
#pragma once #pragma once
#ifndef __INTELLISENSE__ #ifndef __INTELLISENSE__
# define MODULE_EXPORT __attribute__( ( visibility( "default" ) ) ) #define MODULE_EXPORT __attribute__((visibility("default")))
# define MODULE_WASM_MODNAME(mod) __attribute__((import_module(mod))) #define MODULE_WASM_MODNAME(mod) __attribute__((import_module(mod)))
#else #else
# define MODULE_EXPORT #define MODULE_EXPORT
# define MODULE_WASM_MODNAME(mod) #define MODULE_WASM_MODNAME(mod)
# define __attribute__(x) #define __attribute__(x)
# define __restrict__ #define __restrict__
#endif #endif
/******************************** Constants ********************************/ /******************************** Constants ********************************/
@ -15,16 +15,13 @@
#define PILOT_WEIGHT(IS_IMPERIAL) ((IS_IMPERIAL) ? (190.0) : (86.0)) #define PILOT_WEIGHT(IS_IMPERIAL) ((IS_IMPERIAL) ? (190.0) : (86.0))
// 200lbs per tank (one LD3) // 200lbs per tank (one LD3)
#define AUX_WEIGHT(IS_IMPERIAL) ((IS_IMPERIAL) ? (200.0) : (91.0)) #define AUX_WEIGHT(IS_IMPERIAL) ((IS_IMPERIAL) ? (200.0) : (91.0))
//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))
//LD3s due to 70in door, ER option takes up two slots // LD3s due to 70in door, ER option takes up two slots
#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)) #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))
// Max TOW // Max TOW
#define MAX_TOW(IS_IMPERIAL) ((IS_IMPERIAL) ? (625500) : (283722)) #define MAX_TOW(IS_IMPERIAL) ((IS_IMPERIAL) ? (625500) : (283722))
#define MAX_TOW_ER(IS_IMPERIAL) ((IS_IMPERIAL) ? (630500) : (285990)) #define MAX_TOW_ER(IS_IMPERIAL) ((IS_IMPERIAL) ? (630500) : (285990))
// Max Fuel
#define MAX_FUEL(IS_IMPERIAL) ((IS_IMPERIAL) ? (256207) : (116213))
#define MAX_FUEL_ER(IS_IMPERIAL) ((IS_IMPERIAL) ? (282619) : (128193))
// Arms Shared // Arms Shared
#define ARM_EMPTY -120.0 #define ARM_EMPTY -120.0
#define ARM_PILOT 984.0 #define ARM_PILOT 984.0
@ -34,22 +31,11 @@
#define ARM_REAR_CARGO -360.0 #define ARM_REAR_CARGO -360.0
#define ARM_LEFT_AUX 60.0 #define ARM_LEFT_AUX 60.0
#define ARM_RIGHT_AUX 60.0 #define ARM_RIGHT_AUX 60.0
// Arms Fuel
#define ARM_MAIN1 -240.0
#define ARM_MAIN3 -240.0
#define ARM_MAIN2 120.0
#define ARM_UPPER_AUX 0.0
#define ARM_LOWER_AUX 0.0
#define ARM_MAIN1_TIP -468.0
#define ARM_MAIN3_TIP -468.0
#define ARM_TAIL -840.0
#define ARM_FORWARD_AUX1 60.0
#define ARM_FORWARD_AUX2 60.0
// MAC // MAC
#define ROOT_CHORD 34.68 #define ROOT_CHORD 34.68
#define WING_SPAN 170.5 #define WING_SPAN 170.5
#define WING_AREA 3648.0 #define WING_AREA 3648.0
#define QUARTER_MAC -165.0 //aero_center #define QUARTER_MAC -165.0 // aero_center
#define TIP_CHORD ((2.0 * WING_AREA) / WING_SPAN - ROOT_CHORD) #define TIP_CHORD ((2.0 * WING_AREA) / WING_SPAN - ROOT_CHORD)
#define TAPER_RATIO (TIP_CHORD / ROOT_CHORD) #define TAPER_RATIO (TIP_CHORD / ROOT_CHORD)
#define MAC ((2.0 / 3.0) * ROOT_CHORD * ((1.0 + TAPER_RATIO + (TAPER_RATIO * TAPER_RATIO)) / (1.0 + TAPER_RATIO)) * 12.0) #define MAC ((2.0 / 3.0) * ROOT_CHORD * ((1.0 + TAPER_RATIO + (TAPER_RATIO * TAPER_RATIO)) / (1.0 + TAPER_RATIO)) * 12.0)
@ -64,91 +50,75 @@
/********************************* Macros **********************************/ /********************************* Macros **********************************/
// Conversions // Conversions
#define TO_POUNDS(IS_IMPERIAL, VALUE) ((IS_IMPERIAL) ? (VALUE) : (VALUE) * 2.20462262185) #define TO_POUNDS(IS_IMPERIAL, VALUE) ((IS_IMPERIAL) ? (VALUE) : (VALUE)*2.20462262185)
#define FROM_POUNDS(IS_IMPERIAL, VALUE) ((IS_IMPERIAL) ? (VALUE) : (VALUE) * (1.0 / 2.20462262185)) #define FROM_POUNDS(IS_IMPERIAL, VALUE) ((IS_IMPERIAL) ? (VALUE) : (VALUE) * (1.0 / 2.20462262185))
// MAC // MAC
#define TO_PERCENT_MAC(POS) ((((POS) - LEMAC) / MAC) * -100.0) #define TO_PERCENT_MAC(POS) ((((POS)-LEMAC) / MAC) * -100.0)
/********************************** ENUMS **********************************/ /********************************** ENUMS **********************************/
enum DATA_DEFINITIONS { enum DATA_DEFINITIONS {
DATA_DEFINITION_EMPTY_WEIGHT, DATA_DEFINITION_EMPTY_WEIGHT,
DATA_DEFINITION_PAYLOAD_PAX, DATA_DEFINITION_PAYLOAD_PAX,
DATA_DEFINITION_PAYLOAD_F, DATA_DEFINITION_PAYLOAD_F,
DATA_DEFINITION_FUEL, DATA_DEFINITION_FUEL,
DATA_DEFINITION_GSX, DATA_DEFINITION_FUEL_SET,
DATA_DEFINITION_USER_DATA, DATA_DEFINITION_GSX,
DATA_DEFINITION_USER_DATA,
}; };
enum DATA_REQUESTS { enum DATA_REQUESTS {
DATA_REQUEST_EMPTY_WEIGHT, DATA_REQUEST_EMPTY_WEIGHT,
DATA_REQUEST_PAYLOAD_PAX, DATA_REQUEST_PAYLOAD_PAX,
DATA_REQUEST_PAYLOAD_F, DATA_REQUEST_PAYLOAD_F,
DATA_REQUEST_FUEL, DATA_REQUEST_FUEL,
DATA_REQUEST_GSX, DATA_REQUEST_FUEL_SET,
DATA_REQUEST_USER_DATA, DATA_REQUEST_GSX,
DATA_REQUEST_USER_DATA,
}; };
enum LOADING_STATES { enum LOADING_STATES {
LOADING_STATE_IDLE, LOADING_STATE_IDLE,
LOADING_STATE_BOARDING, LOADING_STATE_BOARDING,
LOADING_STATE_BOARDED, LOADING_STATE_BOARDED,
LOADING_STATE_DEBOARDING, LOADING_STATE_DEBOARDING,
LOADING_STATE_DEBOARDED, LOADING_STATE_DEBOARDED,
}; };
enum CALL_MODES { enum CALL_MODES {
CALL_MODE_SB_SET, CALL_MODE_SB_SET,
CALL_MODE_ZFW_SET, CALL_MODE_ZFW_SET,
CALL_MODE_STATION_SET, CALL_MODE_STATION_SET,
CALL_MODE_LOAD_SET, CALL_MODE_LOAD_SET,
CALL_MODE_UNLOAD_SET, CALL_MODE_UNLOAD_SET,
CALL_MODE_OPTIONS_SET, CALL_MODE_OPTIONS_SET,
CALL_MODE_GSX_RESET, CALL_MODE_GSX_RESET,
}; };
/***************************** Data structures *****************************/ /***************************** Data structures *****************************/
typedef struct { typedef struct {
double isCargo; double isCargo;
double isER; double isER;
double isImperial; double isImperial;
} UserData_t; } UserData_t;
typedef struct { typedef struct {
// SimConnect mapped // SimConnect mapped
double couatlStarted; // boolean double couatlStarted; // boolean
double boardingState; // See manual, 5 => active double boardingState; // See manual, 5 => active
double deboardingState; // See manual, 5 => active double deboardingState; // See manual, 5 => active
double passengersBoarded; // Num pax double passengersBoarded; // Num pax
double passengersDeboarded; // Num pax double passengersDeboarded; // Num pax
double cargoBoarded; // In percent double cargoBoarded; // In percent
double cargoDeboarded; // In percent double cargoDeboarded; // In percent
// Additional properties // Additional properties
enum LOADING_STATES loadingState; enum LOADING_STATES loadingState;
} GSXData_t; } GSXData_t;
typedef struct { typedef struct {
// SimConnect mapped bool GSXSync;
double poundsPerGallon; // DO NOT USE double paxWeightKG;
double main1; double bagWeightKG;
double main3; double paxWeightLBS;
double main2; double bagWeightLBS;
double upperAux;
double lowerAux;
double main1Tip;
double main3Tip;
double tail;
double forwardAux1;
double forwardAux2;
// Additional properties
double total;
} FuelData_t;
typedef struct {
bool GSXSync;
double paxWeightKG;
double bagWeightKG;
double paxWeightLBS;
double bagWeightLBS;
} UserOptions_t; } UserOptions_t;

17
TODO.md
View File

@ -1,3 +1,20 @@
Fuel (once implemented) Fuel (once implemented)
ZFWCG for WBS (once implemented) `MD11_EXTCTL_WBS_ZFWCG` ZFWCG for WBS (once implemented) `MD11_EXTCTL_WBS_ZFWCG`
https://discord.com/channels/589851727373795331/1165358675037270066/1469039399961497753 https://discord.com/channels/589851727373795331/1165358675037270066/1469039399961497753
Fuel Schedule
Mains 1/2/3
Upper Aux
Lower Aux
Tail
LEft/Right Forward Aux
Fuel Limits from EFB
GSX Sync
When Fueling is called, fuel progressively using FuelDataSet_t and FUEL_SET enums
Find fueling rate of plane
In JS
Remove Set Fuel
Fuel is set with total load button

View File

@ -6,12 +6,26 @@
], ],
"settings": { "settings": {
"cSpell.words": [ "cSpell.words": [
"AUXLWR",
"AUXUPR",
"bksp", "bksp",
"couatl", "couatl",
"Deboarded",
"DEBOARDED", "DEBOARDED",
"deboarding", "deboarding",
"Deinitialized",
"EXTCTL", "EXTCTL",
"FCOMs",
"FSDT",
"FWDAUXL",
"FWDAUXR",
"HRESULT",
"khofmann", "khofmann",
"LEMAC",
"MSFS",
"NUMPASSENGERS",
"SIMCONNECT",
"SIMOBJECT",
"SIMOBJECTS", "SIMOBJECTS",
"tfdi", "tfdi",
"TFDI", "TFDI",