diff --git a/PackageSources/js-bundle/src/components/SBEntry/SBEntryPax.tsx b/PackageSources/js-bundle/src/components/SBEntry/SBEntryPax.tsx index 8d22dd6..e7f5fbc 100644 --- a/PackageSources/js-bundle/src/components/SBEntry/SBEntryPax.tsx +++ b/PackageSources/js-bundle/src/components/SBEntry/SBEntryPax.tsx @@ -1,6 +1,11 @@ import { FC, useEffect, useRef, useState } from 'react'; import { unloadAircraft } from '../../configs/shared'; -import { COHERENT_COMBUS_WASM_CALL, COMM_BUS_UPDATE_TARGET_EVENT } from '../../constants'; +import { + COHERENT_COMBUS_WASM_CALL, + COMM_BUS_UPDATE_TARGET_EVENT, + GSX_SERVICE_CALLED, + GSX_SERVICE_FINISHED, +} from '../../constants'; import { WASMDataPax } from '../../types/WASMData'; import { LoadingState } from '../../types/general'; import { ImportFlightPlan } from '../../utils/TFDISBImport'; @@ -40,6 +45,13 @@ const SBEntryPax: FC = ({ WASMData, loadingState, username, setLoa return GW() <= WASMData.limits.maxTOW; }; + const GSXActive = () => { + return ( + (WASMData.GSX.boardingState >= GSX_SERVICE_CALLED || WASMData.GSX.deboardingState >= GSX_SERVICE_CALLED) && + WASMData.GSX.deboardingState !== GSX_SERVICE_FINISHED + ); + }; + const handleInput = (input: string, maxValue: number, setter: (value: number) => void) => { if (!input) { setter(0); @@ -116,7 +128,7 @@ const SBEntryPax: FC = ({ WASMData, loadingState, username, setLoa className={`w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right`} value={fuel} onChange={(e) => handleInput(e.target.value, WASMData.limits.maxFuel, setFuel)} - disabled={loadingState !== 'preview'} + disabled={loadingState !== 'preview' || GSXActive()} /> @@ -166,7 +178,7 @@ const SBEntryPax: FC = ({ WASMData, loadingState, username, setLoa minCG={WASMData.limits.minCG} maxCG={WASMData.limits.maxCG} value={CGTarget} - disabled={loadingState !== 'preview'} + disabled={loadingState !== 'preview' || GSXActive()} increase={() => setCGTarget((prev) => { const _new = prev + 0.1; @@ -215,6 +227,8 @@ const SBEntryPax: FC = ({ WASMData, loadingState, username, setLoa { setLoadingState('loaded'); diff --git a/PackageSources/js-bundle/src/components/actionbar/ActionBar.tsx b/PackageSources/js-bundle/src/components/actionbar/ActionBar.tsx index b0eb0c8..5406b82 100644 --- a/PackageSources/js-bundle/src/components/actionbar/ActionBar.tsx +++ b/PackageSources/js-bundle/src/components/actionbar/ActionBar.tsx @@ -4,16 +4,17 @@ import { LoadingState } from '../../types/general'; interface ActionBarProps { loadingState: LoadingState; loadDisabled: boolean; + GSXSync: boolean; + GSXActive: boolean; importSB?: () => void; load: () => void; unload: () => void; } -const ActionBar: FC = ({ loadingState, loadDisabled, importSB, load, unload }) => { +const ActionBar: FC = ({ loadingState, loadDisabled, GSXSync, GSXActive, importSB, load, unload }) => { return (
- {/*TODO: HIDE FOR GSX SYNCED */} - {loadingState === 'preview' && ( + {loadingState === 'preview' && !GSXSync && ( )} - {/*TODO: HIDE FOR GSX SYNCED */} - {loadingState === 'loaded' && ( + {loadingState === 'loaded' && !GSXSync && ( diff --git a/PackageSources/js-bundle/src/components/pax/Pax.tsx b/PackageSources/js-bundle/src/components/pax/Pax.tsx index 5f64e6f..d08a6cf 100644 --- a/PackageSources/js-bundle/src/components/pax/Pax.tsx +++ b/PackageSources/js-bundle/src/components/pax/Pax.tsx @@ -1,5 +1,6 @@ import { FC, useState } from 'react'; import { loadAircraft } from '../../configs/shared'; +import { GSX_SERVICE_CALLED, GSX_SERVICE_FINISHED } from '../../constants'; import { LoadingState } from '../../types/general'; import { WASMDataPax } from '../../types/WASMData'; import Profile from '../profile/Profile'; @@ -38,28 +39,35 @@ const Pax: FC = ({ WASMData, username }) => { return WASMData.livePayload.economy2; }; const lower1 = () => { - if (loadingState !== 'loaded') return Math.round(WASMData.targetPayload.forwardCargo); + if (loadingState !== 'loaded' && !GSXActive()) return Math.round(WASMData.targetPayload.forwardCargo); return Math.round(WASMData.livePayload.forwardCargo); }; const lower2 = () => { - if (loadingState !== 'loaded') return Math.round(WASMData.targetPayload.rearCargo); + if (loadingState !== 'loaded' && !GSXActive()) return Math.round(WASMData.targetPayload.rearCargo); return Math.round(WASMData.livePayload.rearCargo); }; const OEW = () => { - if (loadingState !== 'loaded') return Math.round(WASMData.targetPayload.empty); + if (loadingState !== 'loaded' && !GSXActive()) return Math.round(WASMData.targetPayload.empty); return Math.round(WASMData.livePayload.empty); }; const crew = () => { - if (loadingState !== 'loaded') return Math.round(WASMData.targetPayload.crew); + if (loadingState !== 'loaded' && !GSXActive()) return Math.round(WASMData.targetPayload.crew); return Math.round(WASMData.livePayload.crew); }; + const GSXActive = () => { + return ( + (WASMData.GSX.boardingState >= GSX_SERVICE_CALLED || WASMData.GSX.deboardingState >= GSX_SERVICE_CALLED) && + WASMData.GSX.deboardingState !== GSX_SERVICE_FINISHED + ); + }; + const CGs = (): [string, boolean, string, boolean] => { - if (loadingState !== 'loaded') { + if (loadingState !== 'loaded' && !GSXActive()) { return [ WASMData.targetPayload.ZFWCG.toFixed(1), WASMData.targetPayload.ZFWCG < WASMData.limits.minCG || WASMData.targetPayload.ZFWCG > WASMData.limits.maxCG, @@ -81,20 +89,20 @@ const Pax: FC = ({ WASMData, username }) => { = ({ WASMData, loadingState, setLoa return GW() <= WASMData.limits.maxTOW; }; + const GSXActive = () => { + return ( + (WASMData.GSX.boardingState >= GSX_SERVICE_CALLED || WASMData.GSX.deboardingState >= GSX_SERVICE_CALLED) && + WASMData.GSX.deboardingState !== GSX_SERVICE_FINISHED + ); + }; + const handleInput = (input: string, maxValue: number, setter: (value: number) => void) => { if (!input) { setter(0); @@ -91,7 +103,7 @@ const StationEntryPax: FC = ({ WASMData, loadingState, setLoa className={`w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right`} value={fuel} onChange={(e) => handleInput(e.target.value, WASMData.limits.maxFuel, setFuel)} - disabled={loadingState !== 'preview'} + disabled={loadingState !== 'preview' || GSXActive()} /> @@ -121,7 +133,7 @@ const StationEntryPax: FC = ({ WASMData, loadingState, setLoa 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={business1} onChange={(e) => handleInput(e.target.value, WASMData.limits.business1, setBusiness1)} - disabled={loadingState !== 'preview'} + disabled={loadingState !== 'preview' || GSXActive()} />
@@ -132,7 +144,7 @@ const StationEntryPax: FC = ({ WASMData, loadingState, setLoa 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={business2} onChange={(e) => handleInput(e.target.value, WASMData.limits.business2, setBusiness2)} - disabled={loadingState !== 'preview'} + disabled={loadingState !== 'preview' || GSXActive()} />
@@ -143,7 +155,7 @@ const StationEntryPax: FC = ({ WASMData, loadingState, setLoa 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={economy1} onChange={(e) => handleInput(e.target.value, WASMData.limits.economy1, setEconomy1)} - disabled={loadingState !== 'preview'} + disabled={loadingState !== 'preview' || GSXActive()} />
@@ -154,7 +166,7 @@ const StationEntryPax: FC = ({ WASMData, loadingState, setLoa 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={economy2} onChange={(e) => handleInput(e.target.value, WASMData.limits.economy2, setEconomy2)} - disabled={loadingState !== 'preview'} + disabled={loadingState !== 'preview' || GSXActive()} />
@@ -165,7 +177,7 @@ const StationEntryPax: FC = ({ WASMData, loadingState, setLoa 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={forwardCargo} onChange={(e) => handleInput(e.target.value, WASMData.limits.forwardCargo, setForwardCargo)} - disabled={loadingState !== 'preview'} + disabled={loadingState !== 'preview' || GSXActive()} />
@@ -176,7 +188,7 @@ const StationEntryPax: FC = ({ WASMData, loadingState, setLoa 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={rearCargo} onChange={(e) => handleInput(e.target.value, WASMData.limits.rearCargo, setRearCargo)} - disabled={loadingState !== 'preview'} + disabled={loadingState !== 'preview' || GSXActive()} />
@@ -211,6 +223,8 @@ const StationEntryPax: FC = ({ WASMData, loadingState, setLoa { setLoadingState('loaded'); diff --git a/PackageSources/js-bundle/src/components/zfwEntry/ZFWEntryPax.tsx b/PackageSources/js-bundle/src/components/zfwEntry/ZFWEntryPax.tsx index be2aa9d..a02774a 100644 --- a/PackageSources/js-bundle/src/components/zfwEntry/ZFWEntryPax.tsx +++ b/PackageSources/js-bundle/src/components/zfwEntry/ZFWEntryPax.tsx @@ -1,6 +1,11 @@ import { FC, useEffect, useState } from 'react'; import { unloadAircraft } from '../../configs/shared'; -import { COHERENT_COMBUS_WASM_CALL, COMM_BUS_UPDATE_TARGET_EVENT } from '../../constants'; +import { + COHERENT_COMBUS_WASM_CALL, + COMM_BUS_UPDATE_TARGET_EVENT, + GSX_SERVICE_CALLED, + GSX_SERVICE_FINISHED, +} from '../../constants'; import { WASMDataPax } from '../../types/WASMData'; import { LoadingState } from '../../types/general'; import CGSelect from '../CGSelect/CGSelect'; @@ -34,6 +39,13 @@ const ZFWEntryPax: FC = ({ WASMData, loadingState, setLoadingStat return GW() <= WASMData.limits.maxTOW; }; + const GSXActive = () => { + return ( + (WASMData.GSX.boardingState >= GSX_SERVICE_CALLED || WASMData.GSX.deboardingState >= GSX_SERVICE_CALLED) && + WASMData.GSX.deboardingState !== GSX_SERVICE_FINISHED + ); + }; + const handleInput = (input: string, maxValue: number, setter: (value: number) => void) => { if (!input) { setter(0); @@ -110,7 +122,7 @@ const ZFWEntryPax: FC = ({ WASMData, loadingState, setLoadingStat className={`w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right`} value={fuel} onChange={(e) => handleInput(e.target.value, WASMData.limits.maxFuel, setFuel)} - disabled={loadingState !== 'preview'} + disabled={loadingState !== 'preview' || GSXActive()} /> @@ -141,7 +153,7 @@ const ZFWEntryPax: FC = ({ WASMData, loadingState, setLoadingStat value={ZFWTarget} onChange={(e) => handleInputZFW(e.target.value)} onBlur={(e) => handleBlur(e.target.value)} - disabled={loadingState !== 'preview'} + disabled={loadingState !== 'preview' || GSXActive()} />
@@ -152,7 +164,7 @@ const ZFWEntryPax: FC = ({ WASMData, loadingState, setLoadingStat minCG={WASMData.limits.minCG} maxCG={WASMData.limits.maxCG} value={CGTarget} - disabled={loadingState !== 'preview'} + disabled={loadingState !== 'preview' || GSXActive()} increase={() => setCGTarget((prev) => { const _new = prev + 0.1; @@ -201,6 +213,8 @@ const ZFWEntryPax: FC = ({ WASMData, loadingState, setLoadingStat { setLoadingState('loaded'); diff --git a/PackageSources/js-bundle/src/constants.ts b/PackageSources/js-bundle/src/constants.ts index caa4804..9e5a2ef 100644 --- a/PackageSources/js-bundle/src/constants.ts +++ b/PackageSources/js-bundle/src/constants.ts @@ -7,3 +7,7 @@ export const COMM_BUS_LIVE_DATA_EVENT = 'khofmann_tfdi_md-11_load_manager_live_d export const COMM_BUS_UPDATE_TARGET_EVENT = 'khofmann_tfdi_md-11_load_manager_update_target'; export const CG_ADJUST = 0.05; + +export const GSX_SERVICE_CALLED = 4; +export const GSX_SERVICE_ACTIVE = 5; +export const GSX_SERVICE_FINISHED = 6; diff --git a/PackageSources/js-bundle/src/types/WASMData.d.ts b/PackageSources/js-bundle/src/types/WASMData.d.ts index 8c8ac27..eedb64a 100644 --- a/PackageSources/js-bundle/src/types/WASMData.d.ts +++ b/PackageSources/js-bundle/src/types/WASMData.d.ts @@ -4,6 +4,7 @@ export interface WASMDataPax { GSX: GSX; userData: UserData; limits: LimitsPax; + options: Options; } interface TargetPayload { @@ -46,10 +47,6 @@ interface LivePayloadF extends TargetPayloadF { interface GSX { boardingState: number; deboardingState: number; - passengersBoarded: number; - passengersDeboarded: number; - cargoBoarded: number; - cargoDeboarded: number; } interface Limits { @@ -84,3 +81,9 @@ interface UserData { isER: boolean; isImperial: boolean; } + +interface Options { + GSXSync: boolean; + paxWeight: number; + bagWeight: number; +} diff --git a/PackageSources/wasm-module/load-manager.cpp b/PackageSources/wasm-module/load-manager.cpp index d960f21..ff04a2c 100644 --- a/PackageSources/wasm-module/load-manager.cpp +++ b/PackageSources/wasm-module/load-manager.cpp @@ -10,6 +10,7 @@ paxPayloadData_t* targetPaxPayloadData; fPayloadData_t* liveFPayloadData; fPayloadData_t* targetFPayloadData; FuelData_t* liveFuelData; +UserOptions_t* UserOptions; // Operational bool commBusCallbackRegistered; @@ -34,6 +35,7 @@ extern "C" MSFS_CALLBACK void module_init(void) { liveFPayloadData = new fPayloadData_t(); targetFPayloadData = new fPayloadData_t(); liveFuelData = new FuelData_t(); + UserOptions = new UserOptions_t(); targetFPayloadData->CGTarget = targetPaxPayloadData->CGTarget = 21; @@ -392,6 +394,26 @@ extern "C" MSFS_CALLBACK void module_init(void) { log(stdout, MODULE_NAME"CommBus registered.\n"); } + // Options + FILE* optionsFile = fopen("\\work\\options.json", "rb"); + if (optionsFile != NULL) { + char readBuffer[256]; + rapidjson::FileReadStream is(optionsFile, readBuffer, sizeof(readBuffer)); + rapidjson::Document optionsDoc; + optionsDoc.ParseStream(is); + if (optionsDoc.HasMember("GSXSync")) UserOptions->GSXSync = optionsDoc["GSXSync"].GetBool(); + if (optionsDoc.HasMember("paxWeightKG")) UserOptions->paxWeightKG = optionsDoc["paxWeightKG"].GetDouble(); + if (optionsDoc.HasMember("bagWeightKG")) UserOptions->bagWeightKG = optionsDoc["bagWeightKG"].GetDouble(); + if (optionsDoc.HasMember("paxWeightLBS")) UserOptions->paxWeightLBS = optionsDoc["paxWeightLBS"].GetDouble(); + if (optionsDoc.HasMember("bagWeightLBS")) UserOptions->bagWeightLBS = optionsDoc["bagWeightLBS"].GetDouble(); + fclose(optionsFile); + + log(stdout, MODULE_NAME"Options loaded.\n"); + } + else { + log(stdout, MODULE_NAME"Options file not present, skip.\n"); + } + log(stdout, MODULE_NAME"Initialized.\n"); } @@ -403,6 +425,8 @@ extern "C" MSFS_CALLBACK void module_deinit(void) { log(stderr, MODULE_NAME"Failed to close SimConnect.\n"); } + log(stdout, MODULE_NAME"SimConnect closed.\n"); + delete UserData; delete GSXData; delete livePaxPayloadData; @@ -411,7 +435,36 @@ extern "C" MSFS_CALLBACK void module_deinit(void) { delete targetFPayloadData; delete liveFuelData; + log(stdout, MODULE_NAME"Global memory released.\n"); + fsCommBusUnregister(COMM_BUS_UPDATE_TARGET_EVENT, commBusUpdateTargetCallback); + + log(stdout, MODULE_NAME"CommBus unregistered.\n"); + + // Options + rapidjson::Document optionsDoc; + rapidjson::Document::AllocatorType& allocator = optionsDoc.GetAllocator(); + optionsDoc.SetObject(); + optionsDoc.AddMember("GSXSync", UserOptions->GSXSync, allocator); + optionsDoc.AddMember("paxWeightKG", UserOptions->paxWeightKG, allocator); + optionsDoc.AddMember("bagWeightKG", UserOptions->bagWeightKG, allocator); + optionsDoc.AddMember("paxWeightLBS", UserOptions->paxWeightLBS, allocator); + optionsDoc.AddMember("bagWeightLBS", UserOptions->bagWeightLBS, allocator); + FILE* optionsFile = fopen("\\work\\options.json", "wb"); + if (optionsFile != NULL) { + char writeBuffer[256]; + rapidjson::FileWriteStream os(optionsFile, writeBuffer, sizeof(writeBuffer)); + rapidjson::Writer writer(os); + optionsDoc.Accept(writer); + fclose(optionsFile); + + log(stdout, MODULE_NAME"Options written.\n"); + } + else { + log(stdout, MODULE_NAME"Filed to open options file for write, skip.\n"); + } + + log(stdout, MODULE_NAME"Deinitialized.\n"); } // Main loop @@ -455,13 +508,14 @@ int receiveData(const char* buf) { if (UserData->isCargo) { targetPaxPayloadData->CGTarget = CGTarget; + //TODO: F load } else { if (!document.HasMember("numPax")) return -1; unsigned short numPax = document["numPax"].GetInt(); targetPaxPayloadData->CGTarget = CGTarget; - distribute(targetPaxPayloadData, liveFuelData, numPax, cargo, UserData->isImperial); + distribute(targetPaxPayloadData, liveFuelData, numPax, cargo, UserData->isImperial, UserData->isER); } break; } @@ -473,17 +527,18 @@ int receiveData(const char* buf) { if (UserData->isCargo) { targetPaxPayloadData->CGTarget = CGTarget; + //TODO: F load } else { targetPaxPayloadData->CGTarget = CGTarget; - distribute(targetPaxPayloadData, liveFuelData, ZFWTarget, UserData->isImperial); + distribute(targetPaxPayloadData, liveFuelData, ZFWTarget, UserData->isImperial, UserData->isER); } break; } // Station Entry case 2: { if (UserData->isCargo) { - + //TODO: F load } else { if (!document.HasMember("business1") || !document.HasMember("business2") || @@ -503,7 +558,7 @@ int receiveData(const char* buf) { // Trigger load case 3: { if (UserData->isCargo) { - + //TODO: F load } else { load(targetPaxPayloadData, simConnect, UserData->isImperial); @@ -514,10 +569,10 @@ int receiveData(const char* buf) { // Trigger unload case 4: { if (UserData->isCargo) { - + //TODO: F load } else { - unload(simConnect, UserData->isImperial); + unload(simConnect, UserData->isER); } break; @@ -551,6 +606,8 @@ void sendData () { userData.SetObject(); rapidjson::Value limits; limits.SetObject(); + rapidjson::Value options; + options.SetObject(); rapidjson::StringBuffer strbuf; rapidjson::Writer writer(strbuf); @@ -665,14 +722,9 @@ void sendData () { #pragma endregion - //TODO: Evaluate necessity of sending GSX data // GSX GSX.AddMember("boardingState", GSXData->boardingState, allocator); GSX.AddMember("deboardingState", GSXData->deboardingState, allocator); - GSX.AddMember("passengersBoarded", GSXData->passengersBoarded, allocator); - GSX.AddMember("passengersDeboarded", GSXData->passengersDeboarded, allocator); - GSX.AddMember("cargoBoarded", GSXData->cargoBoarded, allocator); - GSX.AddMember("cargoDeboarded", GSXData->cargoDeboarded, allocator); // User Data userData.AddMember("isCargo", UserData->isCargo, allocator); @@ -692,7 +744,7 @@ void sendData () { limits.AddMember("upper3", -1, allocator); limits.AddMember("upper4", -1, allocator); limits.AddMember("lowerForward", MAX_FRONT_CARGO(UserData->isImperial), allocator); - limits.AddMember("lowerRear", MAX_REAR_CARGO(UserData->isImperial), allocator); + limits.AddMember("lowerRear", MAX_REAR_CARGO(UserData->isImperial, UserData->isER), allocator); // TODO: Actual F limit //limits.AddMember("MaxZFW", MAX_F_ZFW, allocator); limits.AddMember("minZFW", targetFPayloadData->empty + targetFPayloadData->leftAux + targetFPayloadData->rightAux, allocator); @@ -704,17 +756,23 @@ void sendData () { limits.AddMember("economy1", MAX_ECONOMY_1, allocator); limits.AddMember("economy2", MAX_ECONOMY_2, allocator); limits.AddMember("forwardCargo", MAX_FRONT_CARGO(UserData->isImperial), allocator); - limits.AddMember("rearCargo", MAX_REAR_CARGO(UserData->isImperial), allocator); + limits.AddMember("rearCargo", MAX_REAR_CARGO(UserData->isImperial, UserData->isER), allocator); limits.AddMember("maxZFW", MAX_PAX_ZFW(UserData->isImperial), allocator); limits.AddMember("minZFW", targetPaxPayloadData->empty + targetPaxPayloadData->leftAux + targetPaxPayloadData->rightAux, allocator); } + // Options + options.AddMember("GSXSync", UserOptions->GSXSync, allocator); + options.AddMember("paxWeight", UserData->isImperial ? UserOptions->paxWeightLBS : UserOptions->paxWeightKG, allocator); + options.AddMember("bagWeight", UserData->isImperial ? UserOptions->bagWeightLBS : UserOptions->bagWeightKG, allocator); + // Construct document document.AddMember("livePayload", livePayload.Move(), allocator); document.AddMember("targetPayload", targetPayload.Move(), allocator); document.AddMember("GSX", GSX.Move(), allocator); document.AddMember("userData", userData.Move(), allocator); document.AddMember("limits", limits.Move(), allocator); + document.AddMember("options", options.Move(), allocator); // Write to CommBus document.Accept(writer); @@ -796,6 +854,59 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContex GSXData_t* data = (GSXData_t*)&pObjData->dwData; memcpy(GSXData, data, sizeof(GSXData_t)); + if (UserOptions->GSXSync) { + if (GSXData->boardingState == GSX_SERVICE_ACTIVE) { + double cargoBoarded = GSXData->cargoBoarded; + if (UserData->isCargo) { + //TODO: Progressive F load + } + else { + double passengersBoarded = GSXData->passengersBoarded; + paxPayloadData_t localPayload = {}; + memcpy(&localPayload, targetPaxPayloadData, sizeof(localPayload)); + + localPayload.paxCount.business1 = min(targetPaxPayloadData->paxCount.business1, passengersBoarded); + passengersBoarded -= localPayload.paxCount.business1; + localPayload.paxCount.business2 = min(targetPaxPayloadData->paxCount.business2, passengersBoarded); + passengersBoarded -= localPayload.paxCount.business2; + localPayload.paxCount.economy1 = min(targetPaxPayloadData->paxCount.economy1, passengersBoarded); + passengersBoarded -= localPayload.paxCount.economy1; + localPayload.paxCount.economy2 = min(targetPaxPayloadData->paxCount.economy2, passengersBoarded); + passengersBoarded -= localPayload.paxCount.economy2; + localPayload.forwardCargo = targetPaxPayloadData->forwardCargo * (cargoBoarded / 100); + localPayload.rearCargo = targetPaxPayloadData->rearCargo * (cargoBoarded / 100); + + generatePayload(&localPayload, UserData->isImperial); + load(&localPayload, simConnect, UserData->isImperial); + } + } + if (GSXData->deboardingState == GSX_SERVICE_ACTIVE) { + double cargoDeboarded = GSXData->cargoDeboarded; + if (UserData->isCargo) { + //TODO: Progressive F unload + } + else { + double passengersDeboarded = GSXData->passengersDeboarded; + paxPayloadData_t localPayload = {}; + memcpy(&localPayload, targetPaxPayloadData, sizeof(localPayload)); + + localPayload.paxCount.business1 -= min(targetPaxPayloadData->paxCount.business1, passengersDeboarded); + passengersDeboarded -= localPayload.paxCount.business1; + localPayload.paxCount.business2 -= min(targetPaxPayloadData->paxCount.business2, passengersDeboarded); + passengersDeboarded -= localPayload.paxCount.business2; + localPayload.paxCount.economy1 -= min(targetPaxPayloadData->paxCount.economy1, passengersDeboarded); + passengersDeboarded -= localPayload.paxCount.economy1; + localPayload.paxCount.economy2 -= min(targetPaxPayloadData->paxCount.economy2, passengersDeboarded); + passengersDeboarded -= localPayload.paxCount.economy2; + localPayload.forwardCargo -= targetPaxPayloadData->forwardCargo * (cargoDeboarded / 100); + localPayload.rearCargo -= targetPaxPayloadData->rearCargo * (cargoDeboarded / 100); + + generatePayload(&localPayload, UserData->isImperial); + load(&localPayload, simConnect, UserData->isImperial); + } + } + } + break; } case DATA_REQUEST_USER_DATA: { diff --git a/PackageSources/wasm-module/load-manager.h b/PackageSources/wasm-module/load-manager.h index 456d459..05d3270 100644 --- a/PackageSources/wasm-module/load-manager.h +++ b/PackageSources/wasm-module/load-manager.h @@ -15,6 +15,8 @@ #include #include +#include +#include "rapidjson/filewritestream.h" #include #include diff --git a/PackageSources/wasm-module/pax.cpp b/PackageSources/wasm-module/pax.cpp index 7b9bbf6..6c042b1 100644 --- a/PackageSources/wasm-module/pax.cpp +++ b/PackageSources/wasm-module/pax.cpp @@ -1,18 +1,18 @@ #include "pax.h" //ZFW Entry, fill pax first (pax+bag), rest is cargo -void distribute(paxPayloadData_t* const targetPayload, const FuelData_t* const fuel, const double ZFWTarget, const bool isImperial) { +void distribute(paxPayloadData_t* const targetPayload, const FuelData_t* const fuel, const double ZFWTarget, const bool isImperial, const bool isER) { // Find payload, num pax and extra cargo double payload = ZFWTarget - targetPayload->empty - targetPayload->pilot - targetPayload->firstOfficer - targetPayload->engineer - targetPayload->cabinCrewFront - targetPayload->cabinCrewRear - targetPayload->leftAux - targetPayload->rightAux; unsigned short numPax = max(0.0, min((double)MAX_PAX, floor(payload / (PAX_WEIGHT(isImperial) + BAG_WEIGHT(isImperial))))); unsigned int cargo = round(payload - numPax * PAX_WEIGHT(isImperial) - numPax * BAG_WEIGHT(isImperial)); - distribute(targetPayload, fuel, numPax, cargo, isImperial); + distribute(targetPayload, fuel, numPax, cargo, isImperial, isER); } //SimBrief Entry, SB pax count and extra cargo -void distribute(paxPayloadData_t* const targetPayload, const FuelData_t* const fuel, unsigned short numPax, unsigned int cargo, const bool isImperial) { +void distribute(paxPayloadData_t* const targetPayload, const FuelData_t* const fuel, unsigned short numPax, unsigned int cargo, const bool isImperial, const bool isER) { // Clear targetPayload->paxCount.business1 = targetPayload->paxCount.business2 = targetPayload->paxCount.economy1 = targetPayload->paxCount.economy2 = targetPayload->paxCount.total = 0; @@ -94,7 +94,7 @@ void distribute(paxPayloadData_t* const targetPayload, const FuelData_t* const f targetPayload->forwardCargo++; cargo--; } - if (targetPayload->rearCargo < MAX_REAR_CARGO(isImperial) && cargo > 0) { + if (targetPayload->rearCargo < MAX_REAR_CARGO(isImperial, isER) && cargo > 0) { targetPayload->rearCargo++; cargo--; } @@ -170,14 +170,14 @@ void distribute(paxPayloadData_t* const targetPayload, const FuelData_t* const f count--; } // Refinement cargo - count = MAX_FRONT_CARGO(isImperial) + MAX_REAR_CARGO(isImperial); + count = MAX_FRONT_CARGO(isImperial) + MAX_REAR_CARGO(isImperial, isER); while (count > 0) { generatePayload(targetPayload, isImperial); calculateCGs(targetPayload, fuel, &targetPayload->ZFWCG, &targetPayload->TOCG, isImperial); // in front of target if (targetPayload->ZFWCG < targetPayload->CGTarget - CG_TOLERANCE) { - if (targetPayload->forwardCargo > 0 && targetPayload->rearCargo < MAX_REAR_CARGO(isImperial)) { + if (targetPayload->forwardCargo > 0 && targetPayload->rearCargo < MAX_REAR_CARGO(isImperial, isER)) { if (targetPayload->forwardCargo > BAG_WEIGHT(isImperial) && targetPayload->rearCargo < MAX_FRONT_CARGO(isImperial) - BAG_WEIGHT(isImperial)) { targetPayload->forwardCargo -= BAG_WEIGHT(isImperial); @@ -196,7 +196,7 @@ void distribute(paxPayloadData_t* const targetPayload, const FuelData_t* const f else if (targetPayload->ZFWCG > targetPayload->CGTarget + CG_TOLERANCE) { if (targetPayload->rearCargo > 0 && targetPayload->forwardCargo < MAX_FRONT_CARGO(isImperial)) { if (targetPayload->rearCargo > BAG_WEIGHT(isImperial) && - targetPayload->forwardCargo < MAX_REAR_CARGO(isImperial) - BAG_WEIGHT(isImperial)) { + targetPayload->forwardCargo < MAX_REAR_CARGO(isImperial, isER) - BAG_WEIGHT(isImperial)) { targetPayload->rearCargo -= BAG_WEIGHT(isImperial); targetPayload->forwardCargo += BAG_WEIGHT(isImperial); } @@ -218,7 +218,7 @@ void distribute(paxPayloadData_t* const targetPayload, const FuelData_t* const f } // 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 set directly) void generatePayload(paxPayloadData_t* const targetPayload, const bool isImperial) { targetPayload->business1Left = targetPayload->business1Center = targetPayload->business1Right = (targetPayload->paxCount.business1 / 3.0) * PAX_WEIGHT(isImperial); targetPayload->business2Left = targetPayload->business2Center = targetPayload->business2Right = (targetPayload->paxCount.business2 / 3.0) * PAX_WEIGHT(isImperial); @@ -255,6 +255,8 @@ void normalisePayload(paxPayloadData_t* const targetPayload, const bool isImperi targetPayload->cabinCrewRear = TO_POUNDS(isImperial, targetPayload->cabinCrewRear); targetPayload->forwardCargo = TO_POUNDS(isImperial, targetPayload->forwardCargo); targetPayload->rearCargo = TO_POUNDS(isImperial, targetPayload->rearCargo); + targetPayload->leftAux = TO_POUNDS(isImperial, targetPayload->leftAux); + 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) { @@ -299,8 +301,13 @@ void load(const paxPayloadData_t* const targetPayload, const HANDLE simConnect, SimConnect_SetDataOnSimObject(simConnect, DATA_DEFINITION_PAYLOAD_PAX, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(paxPayloadDataSet_t), &localPayload); } -void unload(const HANDLE simConnect, const bool isImperial) { +void unload(const HANDLE simConnect, const bool isER) { paxPayloadDataSet_t localPayload = {}; + localPayload.cabinCrewFront = FRONT_CREW_WEIGHT(true); + localPayload.cabinCrewRear = REAR_CREW_WEIGHT(true); + localPayload.leftAux = localPayload.rightAux = isER ? AUX_WEIGHT(true) : 0; + localPayload.pilot = localPayload.firstOfficer = localPayload.engineer = PILOT_WEIGHT(true); + SimConnect_SetDataOnSimObject(simConnect, DATA_DEFINITION_PAYLOAD_PAX, SIMCONNECT_OBJECT_ID_USER, 0, 0, sizeof(localPayload), &localPayload); } diff --git a/PackageSources/wasm-module/pax.h b/PackageSources/wasm-module/pax.h index 332532e..0606f51 100644 --- a/PackageSources/wasm-module/pax.h +++ b/PackageSources/wasm-module/pax.h @@ -21,9 +21,9 @@ #include "types.h" //ZFW Entry, fill pax first (pax+bag), rest is cargo -void distribute(paxPayloadData_t* const targetPayload, const FuelData_t* const fuel, const double ZFWTarget, bool isImperial); +void distribute(paxPayloadData_t* const targetPayload, const FuelData_t* const fuel, const double ZFWTarget, const bool isImperial, const bool isER); //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, bool isImperial); +void distribute(paxPayloadData_t* const targetPayload, const FuelData_t* const fuel, unsigned short numPax, unsigned int cargo, const bool isImperial, const bool isER); // Updates pax stations with their respective weights // Used internally and used for Station Entry (pax only, cargo is ste directly) // STATION WEIGHTS ARE NOT NORMALISED TO POUNDS @@ -33,4 +33,4 @@ void generatePayload(paxPayloadData_t* const targetPayload, const bool isImperia 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 load(const paxPayloadData_t* const targetPayload, const HANDLE simConnect, const bool isImperial); -void unload(const HANDLE simConnect, const bool isImperial); +void unload(const HANDLE simConnect, const bool isER); diff --git a/PackageSources/wasm-module/types.h b/PackageSources/wasm-module/types.h index 67c8625..0086116 100644 --- a/PackageSources/wasm-module/types.h +++ b/PackageSources/wasm-module/types.h @@ -18,7 +18,7 @@ //PMC pallet due to 104in door #define MAX_FRONT_CARGO(IS_IMPERIAL) ((IS_IMPERIAL) ? (6.0 * 15000.0) : (6.0 * 6804.0)) //LD3s due to 70in door -#define MAX_REAR_CARGO(IS_IMPERIAL) ((IS_IMPERIAL) ? (14.0 * 3500.0) : (14.0 * 1588.0)) +#define MAX_REAR_CARGO(IS_IMPERIAL, IS_ER) ((IS_IMPERIAL) ? ((IS_ER ? 14.0 : 2.0) * 3500.0) : ((IS_ER ? 14.0 : 2.0) * 1588.0)) // All actual Business seats #define MAX_BUSINESS_1 30 @@ -101,6 +101,9 @@ #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)) +// GSX States +#define GSX_SERVICE_ACTIVE 5 + // SimConnect ENUMs enum DATA_DEFINITIONS { DATA_DEFINITION_EMPTY_WEIGHT, @@ -259,3 +262,11 @@ typedef struct { // Additional properties double total; } FuelData_t; + +typedef struct { + bool GSXSync; + double paxWeightKG; + double bagWeightKG; + double paxWeightLBS; + double bagWeightLBS; +} UserOptions_t; \ No newline at end of file diff --git a/README.md b/README.md index bab64d5..148a763 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,10 @@ Coherent.call("COMM_BUS_WASM_CALLBACK", "khofmann_tfdi_md-11_load_manager_update TODO: - JS - - GSX State for displaying status fo prog. loading - Persist SB data across page changes - Duplicate Input pages for F + - Options (GSX sync, pax/bag weights) - WASM - - GSX synced setting of payload + - Custom pax/bag weights + - F loading stuff + - TEST GSX synced unload