Moved GSX state machine into WASM

This commit is contained in:
Kilian Hofmann 2025-09-09 14:53:41 +02:00
parent dee5447bed
commit 04e5ec4251
9 changed files with 218 additions and 154 deletions

View File

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

View File

@ -1,7 +1,6 @@
import { FC, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { GSX_SERVICE_CALLED, GSX_SERVICE_FINISHED } from '../../constants';
import { LoadingState } from '../../types/general'; import { LoadingState } from '../../types/general';
import { WASMDataF } from '../../types/WASMData'; import { GSXLoadingState, WASMDataF } from '../../types/WASMData';
import OptionsF from '../options/OptionsF'; import OptionsF from '../options/OptionsF';
import Profile from '../profile/Profile'; import Profile from '../profile/Profile';
import SBEntryF from '../SBEntry/SBEntryF'; import SBEntryF from '../SBEntry/SBEntryF';
@ -17,21 +16,6 @@ interface FreighterProps {
const Freighter: FC<FreighterProps> = ({ WASMData, username }) => { const Freighter: FC<FreighterProps> = ({ WASMData, username }) => {
const [selectedTab, setSelectedTab] = useState(0); const [selectedTab, setSelectedTab] = useState(0);
const [loadingState, setLoadingState] = useState<LoadingState>('preview'); const [loadingState, setLoadingState] = useState<LoadingState>('preview');
const [boardingState, setBoardingState] = useState(1);
const [deboardingState, setDeboardingState] = useState(1);
useEffect(() => {
if (WASMData.GSX.boardingState < GSX_SERVICE_CALLED) return;
setBoardingState(WASMData.GSX.boardingState);
setDeboardingState(1);
}, [WASMData.GSX.boardingState]);
useEffect(() => {
if (WASMData.GSX.deboardingState < GSX_SERVICE_CALLED) return;
setBoardingState(1);
setDeboardingState(WASMData.GSX.deboardingState);
}, [WASMData.GSX.deboardingState]);
const upper1 = (overrideState: LoadingState = loadingState) => { const upper1 = (overrideState: LoadingState = loadingState) => {
if (overrideState !== 'loaded') return Math.round(WASMData.targetPayload.upper1); if (overrideState !== 'loaded') return Math.round(WASMData.targetPayload.upper1);
@ -75,17 +59,10 @@ const Freighter: FC<FreighterProps> = ({ WASMData, username }) => {
}; };
const GSXActive = () => { const GSXActive = () => {
// Cases when active:
// BOARDING called, running or done
// DEBOARDING called, running or done
// Cases when not active:
// BOARDING not called, disabled
// DEBOARDING not called, disabled
// BOTH done
return ( return (
(boardingState >= GSX_SERVICE_CALLED || deboardingState >= GSX_SERVICE_CALLED) && WASMData.GSX.couatlStarted &&
deboardingState !== GSX_SERVICE_FINISHED WASMData.GSX.loadingState !== GSXLoadingState.IDLE &&
WASMData.GSX.loadingState !== GSXLoadingState.DEBOARDED
); );
}; };
@ -99,7 +76,7 @@ const Freighter: FC<FreighterProps> = ({ WASMData, username }) => {
]; ];
} }
if (WASMData.options.GSXSync && GSXActive() && boardingState !== GSX_SERVICE_FINISHED) { if (WASMData.options.GSXSync && GSXActive() && WASMData.GSX.loadingState === GSXLoadingState.BOARDING) {
return [ return [
WASMData.targetPayload.ZFWCG.toFixed(1), WASMData.targetPayload.ZFWCG.toFixed(1),
WASMData.targetPayload.ZFWCG < WASMData.limits.minCG || WASMData.targetPayload.ZFWCG > WASMData.limits.maxCG, WASMData.targetPayload.ZFWCG < WASMData.limits.minCG || WASMData.targetPayload.ZFWCG > WASMData.limits.maxCG,
@ -137,9 +114,7 @@ const Freighter: FC<FreighterProps> = ({ WASMData, username }) => {
inPreview={loadingState !== 'loaded' && !GSXActive()} inPreview={loadingState !== 'loaded' && !GSXActive()}
CGs={CGs()} CGs={CGs()}
done={ done={
WASMData.options.GSXSync WASMData.options.GSXSync ? WASMData.GSX.loadingState === GSXLoadingState.BOARDED : loadingState !== 'preview'
? boardingState === GSX_SERVICE_FINISHED && deboardingState !== GSX_SERVICE_FINISHED
: loadingState !== 'preview'
} }
/> />
<Tabbar <Tabbar

View File

@ -1,7 +1,6 @@
import { FC, useEffect, useMemo, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { GSX_SERVICE_CALLED, GSX_SERVICE_FINISHED } from '../../constants';
import { LoadingState } from '../../types/general'; import { LoadingState } from '../../types/general';
import { WASMDataPax } from '../../types/WASMData'; import { GSXLoadingState, WASMDataPax } from '../../types/WASMData';
import OptionsPax from '../options/OptionsPax'; import OptionsPax from '../options/OptionsPax';
import Profile from '../profile/Profile'; import Profile from '../profile/Profile';
import SBEntryPax from '../SBEntry/SBEntryPax'; import SBEntryPax from '../SBEntry/SBEntryPax';
@ -17,21 +16,6 @@ interface PaxProps {
const Pax: FC<PaxProps> = ({ WASMData, username }) => { const Pax: FC<PaxProps> = ({ WASMData, username }) => {
const [selectedTab, setSelectedTab] = useState(0); const [selectedTab, setSelectedTab] = useState(0);
const [loadingState, setLoadingState] = useState<LoadingState>('preview'); const [loadingState, setLoadingState] = useState<LoadingState>('preview');
const [boardingState, setBoardingState] = useState(1);
const [deboardingState, setDeboardingState] = useState(1);
useEffect(() => {
if (WASMData.GSX.boardingState > 1 && WASMData.GSX.boardingState < GSX_SERVICE_CALLED) return;
setBoardingState(WASMData.GSX.boardingState);
setDeboardingState(1);
}, [WASMData.GSX.boardingState]);
useEffect(() => {
if (WASMData.GSX.deboardingState > 1 && WASMData.GSX.deboardingState < GSX_SERVICE_CALLED) return;
setBoardingState(1);
setDeboardingState(WASMData.GSX.deboardingState);
}, [WASMData.GSX.deboardingState]);
const upper1 = (overrideState: LoadingState = loadingState) => { const upper1 = (overrideState: LoadingState = loadingState) => {
if (overrideState !== 'loaded') return WASMData.targetPayload.business1; if (overrideState !== 'loaded') return WASMData.targetPayload.business1;
@ -54,43 +38,36 @@ const Pax: FC<PaxProps> = ({ WASMData, username }) => {
return WASMData.livePayload.economy2; return WASMData.livePayload.economy2;
}; };
const lower1 = () => { const lower1 = () => {
if (loadingState !== 'loaded' && !GSXActive) return Math.round(WASMData.targetPayload.forwardCargo); if (loadingState !== 'loaded' && !GSXActive()) return Math.round(WASMData.targetPayload.forwardCargo);
return Math.round(WASMData.livePayload.forwardCargo); return Math.round(WASMData.livePayload.forwardCargo);
}; };
const lower2 = () => { const lower2 = () => {
if (loadingState !== 'loaded' && !GSXActive) return Math.round(WASMData.targetPayload.rearCargo); if (loadingState !== 'loaded' && !GSXActive()) return Math.round(WASMData.targetPayload.rearCargo);
return Math.round(WASMData.livePayload.rearCargo); return Math.round(WASMData.livePayload.rearCargo);
}; };
const OEW = () => { const OEW = () => {
if (loadingState !== 'loaded' && !GSXActive) return Math.round(WASMData.targetPayload.empty); if (loadingState !== 'loaded' && !GSXActive()) return Math.round(WASMData.targetPayload.empty);
return Math.round(WASMData.livePayload.empty); return Math.round(WASMData.livePayload.empty);
}; };
const crew = () => { const crew = () => {
if (loadingState !== 'loaded' && !GSXActive) return Math.round(WASMData.targetPayload.crew); if (loadingState !== 'loaded' && !GSXActive()) return Math.round(WASMData.targetPayload.crew);
return Math.round(WASMData.livePayload.crew); return Math.round(WASMData.livePayload.crew);
}; };
const GSXActive = useMemo(() => { const GSXActive = () => {
// Cases when active:
// BOARDING called, running or done
// DEBOARDING called, running or done
// Cases when not active:
// BOARDING not called, disabled
// DEBOARDING not called, disabled
// BOTH done
return ( return (
(boardingState >= GSX_SERVICE_CALLED || deboardingState >= GSX_SERVICE_CALLED) && WASMData.GSX.couatlStarted &&
deboardingState !== GSX_SERVICE_FINISHED WASMData.GSX.loadingState !== GSXLoadingState.IDLE &&
WASMData.GSX.loadingState !== GSXLoadingState.DEBOARDED
); );
}, [boardingState, deboardingState]); };
const CGs = (): [string, boolean, string, boolean] => { const CGs = (): [string, boolean, string, boolean] => {
if (loadingState !== 'loaded' && !GSXActive) { if (loadingState !== 'loaded' && !GSXActive()) {
return [ return [
WASMData.targetPayload.ZFWCG.toFixed(1), WASMData.targetPayload.ZFWCG.toFixed(1),
WASMData.targetPayload.ZFWCG < WASMData.limits.minCG || WASMData.targetPayload.ZFWCG > WASMData.limits.maxCG, WASMData.targetPayload.ZFWCG < WASMData.limits.minCG || WASMData.targetPayload.ZFWCG > WASMData.limits.maxCG,
@ -99,7 +76,7 @@ const Pax: FC<PaxProps> = ({ WASMData, username }) => {
]; ];
} }
if (WASMData.options.GSXSync && GSXActive && boardingState !== GSX_SERVICE_FINISHED) { if (WASMData.options.GSXSync && GSXActive() && WASMData.GSX.loadingState === GSXLoadingState.BOARDING) {
return [ return [
WASMData.targetPayload.ZFWCG.toFixed(1), WASMData.targetPayload.ZFWCG.toFixed(1),
WASMData.targetPayload.ZFWCG < WASMData.limits.minCG || WASMData.targetPayload.ZFWCG > WASMData.limits.maxCG, WASMData.targetPayload.ZFWCG < WASMData.limits.minCG || WASMData.targetPayload.ZFWCG > WASMData.limits.maxCG,
@ -125,25 +102,23 @@ const Pax: FC<PaxProps> = ({ WASMData, username }) => {
<Profile <Profile
type="PAX" type="PAX"
isER={WASMData.userData.isER} isER={WASMData.userData.isER}
upper1={`${upper1(GSXActive ? 'loaded' : loadingState)}`} upper1={`${upper1(GSXActive() ? 'loaded' : loadingState)}`}
upper1max={loadingState === 'loaded' || GSXActive ? `${upper1('preview')}` : `${WASMData.limits.business1}`} upper1max={loadingState === 'loaded' || GSXActive() ? `${upper1('preview')}` : `${WASMData.limits.business1}`}
upper2={`${upper2(GSXActive ? 'loaded' : loadingState)}`} upper2={`${upper2(GSXActive() ? 'loaded' : loadingState)}`}
upper2max={loadingState === 'loaded' || GSXActive ? `${upper2('preview')}` : `${WASMData.limits.business2}`} upper2max={loadingState === 'loaded' || GSXActive() ? `${upper2('preview')}` : `${WASMData.limits.business2}`}
upper3={`${upper3(GSXActive ? 'loaded' : loadingState)}`} upper3={`${upper3(GSXActive() ? 'loaded' : loadingState)}`}
upper3max={loadingState === 'loaded' || GSXActive ? `${upper3('preview')}` : `${WASMData.limits.economy1}`} upper3max={loadingState === 'loaded' || GSXActive() ? `${upper3('preview')}` : `${WASMData.limits.economy1}`}
upper4={`${upper4(GSXActive ? 'loaded' : loadingState)}`} upper4={`${upper4(GSXActive() ? 'loaded' : loadingState)}`}
upper4max={loadingState === 'loaded' || GSXActive ? `${upper4('preview')}` : `${WASMData.limits.economy2}`} upper4max={loadingState === 'loaded' || GSXActive() ? `${upper4('preview')}` : `${WASMData.limits.economy2}`}
lower1={`${lower1()}`} lower1={`${lower1()}`}
lower2={`${lower2()}`} lower2={`${lower2()}`}
OEW={`${OEW()}`} OEW={`${OEW()}`}
crew={`${crew()}`} crew={`${crew()}`}
unit={WASMData.userData.isImperial ? 'LBS' : 'KG'} unit={WASMData.userData.isImperial ? 'LBS' : 'KG'}
inPreview={loadingState !== 'loaded' && !GSXActive} inPreview={loadingState !== 'loaded' && !GSXActive()}
CGs={CGs()} CGs={CGs()}
done={ done={
WASMData.options.GSXSync WASMData.options.GSXSync ? WASMData.GSX.loadingState === GSXLoadingState.BOARDED : loadingState !== 'preview'
? boardingState === GSX_SERVICE_FINISHED && deboardingState !== GSX_SERVICE_FINISHED
: loadingState !== 'preview'
} }
/> />
<Tabbar <Tabbar
@ -158,7 +133,7 @@ const Pax: FC<PaxProps> = ({ WASMData, username }) => {
WASMData={WASMData} WASMData={WASMData}
loadingState={loadingState} loadingState={loadingState}
setLoadingState={setLoadingState} setLoadingState={setLoadingState}
gsxActive={GSXActive} gsxActive={GSXActive()}
/> />
)} )}
{((username && selectedTab === 1) || (!username && selectedTab === 0)) && ( {((username && selectedTab === 1) || (!username && selectedTab === 0)) && (
@ -166,7 +141,7 @@ const Pax: FC<PaxProps> = ({ WASMData, username }) => {
WASMData={WASMData} WASMData={WASMData}
loadingState={loadingState} loadingState={loadingState}
setLoadingState={setLoadingState} setLoadingState={setLoadingState}
gsxActive={GSXActive} gsxActive={GSXActive()}
/> />
)} )}
{((username && selectedTab === 2) || (!username && selectedTab === 1)) && ( {((username && selectedTab === 2) || (!username && selectedTab === 1)) && (
@ -174,11 +149,11 @@ const Pax: FC<PaxProps> = ({ WASMData, username }) => {
WASMData={WASMData} WASMData={WASMData}
loadingState={loadingState} loadingState={loadingState}
setLoadingState={setLoadingState} setLoadingState={setLoadingState}
gsxActive={GSXActive} gsxActive={GSXActive()}
/> />
)} )}
{((username && selectedTab === 3) || (!username && selectedTab === 2)) && ( {((username && selectedTab === 3) || (!username && selectedTab === 2)) && (
<OptionsPax WASMData={WASMData} loadingState={loadingState} gsxActive={GSXActive} /> <OptionsPax WASMData={WASMData} loadingState={loadingState} gsxActive={GSXActive()} />
)} )}
</> </>
); );

View File

@ -8,10 +8,6 @@ export const COMM_BUS_UPDATE_TARGET_EVENT = 'khofmann_tfdi_md-11_load_manager_up
export const CG_ADJUST = 0.05; export const CG_ADJUST = 0.05;
export const GSX_SERVICE_CALLED = 4;
export const GSX_SERVICE_ACTIVE = 5;
export const GSX_SERVICE_FINISHED = 6;
export const MODE_SB_SET = 0; export const MODE_SB_SET = 0;
export const MODE_ZFW_SET = 1; export const MODE_ZFW_SET = 1;
export const MODE_STATION_SET = 2; export const MODE_STATION_SET = 2;

View File

@ -59,8 +59,8 @@ interface LivePayloadF extends TargetPayloadF {
} }
interface GSX { interface GSX {
boardingState: number; couatlStarted: boolean;
deboardingState: number; loadingState: GSXLoadingState;
} }
interface Limits { interface Limits {
@ -101,3 +101,11 @@ interface Options {
paxWeight: number; paxWeight: number;
bagWeight: number; bagWeight: number;
} }
export enum GSXLoadingState {
IDLE = 0,
BOARDING = 1,
BOARDED = 2,
DEBOARDING = 3,
DEBOARDED = 4,
}

View File

@ -17,6 +17,8 @@ HANDLE simConnect;
FILE* logFile; FILE* logFile;
MODULE_VAR tick18 = { TICK18 }; MODULE_VAR tick18 = { TICK18 };
#pragma region Module callbacks
// Init // Init
extern "C" MSFS_CALLBACK void module_init(void) { extern "C" MSFS_CALLBACK void module_init(void) {
log(stdout, "Starting init.\n"); log(stdout, "Starting init.\n");
@ -299,6 +301,11 @@ extern "C" MSFS_CALLBACK void module_init(void) {
return; return;
} }
// GSX LVars // GSX LVars
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_GSX, "L:FSDT_GSX_COUATL_STARTED", "number", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) {
log(stderr, "Could not add L:FSDT_GSX_COUATL_STARTED to data definition, terminating.\n");
return;
}
hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_GSX, "L:FSDT_GSX_BOARDING_STATE", "number", SIMCONNECT_DATATYPE_FLOAT64); hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_GSX, "L:FSDT_GSX_BOARDING_STATE", "number", SIMCONNECT_DATATYPE_FLOAT64);
if (hr != S_OK) { if (hr != S_OK) {
log(stderr, "Could not add L:FSDT_GSX_BOARDING_STATE to data definition, terminating.\n"); log(stderr, "Could not add L:FSDT_GSX_BOARDING_STATE to data definition, terminating.\n");
@ -489,6 +496,8 @@ extern "C" MSFS_CALLBACK bool Load_Manager_gauge_callback(FsContext ctx, int ser
return true; return true;
} }
#pragma endregion
// CommBus // CommBus
void commBusUpdateTargetCallback(const char* args, unsigned int size, void* ctx) { void commBusUpdateTargetCallback(const char* args, unsigned int size, void* ctx) {
int hr = receiveData(args); int hr = receiveData(args);
@ -795,8 +804,8 @@ void sendData () {
#pragma endregion #pragma endregion
// GSX // GSX
GSX.AddMember("boardingState", GSXData->boardingState, allocator); GSX.AddMember<bool>("couatlStarted", GSXData->couatlStarted, allocator);
GSX.AddMember("deboardingState", GSXData->deboardingState, allocator); GSX.AddMember("loadingState", GSXData->loadingState, allocator);
// User Data // User Data
userData.AddMember<bool>("isCargo", UserData->isCargo, allocator); userData.AddMember<bool>("isCargo", UserData->isCargo, allocator);
@ -954,79 +963,157 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContex
} }
case DATA_REQUEST_GSX: { case DATA_REQUEST_GSX: {
GSXData_t* data = (GSXData_t*)&pObjData->dwData; GSXData_t* data = (GSXData_t*)&pObjData->dwData;
memcpy(GSXData, data, sizeof(GSXData_t)); GSXData->couatlStarted = data->couatlStarted;
GSXData->boardingState = data->boardingState;
GSXData->deboardingState = data->deboardingState;
GSXData->passengersBoarded = data->passengersBoarded;
GSXData->passengersDeboarded = data->passengersDeboarded;
GSXData->cargoBoarded = data->cargoBoarded;
GSXData->cargoDeboarded = data->cargoDeboarded;
if (UserOptions->GSXSync) { if (UserOptions->GSXSync && GSXData->couatlStarted == 1) {
if (GSXData->boardingState == GSX_SERVICE_ACTIVE) { switch ((char)GSXData->boardingState) {
double cargoBoarded = GSXData->cargoBoarded; case GSX_SERVICE_ACTIVE: {
if (UserData->isCargo) { GSXData->loadingState = LOADING_STATE_BOARDING;
fPayloadData_t localPayload = {};
memcpy(&localPayload, targetFPayloadData, sizeof(localPayload));
localPayload.stations.upper1 = targetFPayloadData->stations.upper1 * (cargoBoarded / 100); double cargoBoarded = GSXData->cargoBoarded;
localPayload.stations.upper2 = targetFPayloadData->stations.upper2 * (cargoBoarded / 100); if (UserData->isCargo) {
localPayload.stations.upper3 = targetFPayloadData->stations.upper3 * (cargoBoarded / 100); fPayloadData_t localPayload = {};
localPayload.stations.upper4 = targetFPayloadData->stations.upper4 * (cargoBoarded / 100); memcpy(&localPayload, targetFPayloadData, sizeof(localPayload));
localPayload.lowerForward = targetFPayloadData->lowerForward * (cargoBoarded / 100);
localPayload.lowerRear = targetFPayloadData->lowerRear * (cargoBoarded / 100);
generatePayload(&localPayload, UserData->isImperial); localPayload.stations.upper1 = targetFPayloadData->stations.upper1 * (cargoBoarded / 100);
load(&localPayload, simConnect, UserData->isImperial); localPayload.stations.upper2 = targetFPayloadData->stations.upper2 * (cargoBoarded / 100);
localPayload.stations.upper3 = targetFPayloadData->stations.upper3 * (cargoBoarded / 100);
localPayload.stations.upper4 = targetFPayloadData->stations.upper4 * (cargoBoarded / 100);
localPayload.lowerForward = targetFPayloadData->lowerForward * (cargoBoarded / 100);
localPayload.lowerRear = targetFPayloadData->lowerRear * (cargoBoarded / 100);
generatePayload(&localPayload, UserData->isImperial);
load(&localPayload, simConnect, UserData->isImperial);
}
else {
double passengersBoarded = GSXData->passengersBoarded;
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, UserOptions);
load(&localPayload, simConnect, UserData->isImperial);
}
break;
} }
else { case GSX_SERVICE_FINISHED: {
double passengersBoarded = GSXData->passengersBoarded; GSXData->loadingState = LOADING_STATE_BOARDED;
paxPayloadData_t localPayload = {};
memcpy(&localPayload, targetPaxPayloadData, sizeof(localPayload));
localPayload.paxCount.business1 = min(targetPaxPayloadData->paxCount.business1, passengersBoarded); if (UserData->isCargo) {
passengersBoarded -= localPayload.paxCount.business1; fPayloadData_t localPayload = {};
localPayload.paxCount.business2 = min(targetPaxPayloadData->paxCount.business2, passengersBoarded); memcpy(&localPayload, targetFPayloadData, sizeof(localPayload));
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, UserOptions); generatePayload(&localPayload, UserData->isImperial);
load(&localPayload, simConnect, UserData->isImperial); load(&localPayload, simConnect, UserData->isImperial);
}
else {
paxPayloadData_t localPayload = {};
memcpy(&localPayload, targetPaxPayloadData, sizeof(localPayload));
generatePayload(&localPayload, UserData->isImperial, UserOptions);
load(&localPayload, simConnect, UserData->isImperial);
}
break;
} }
} }
if (GSXData->deboardingState == GSX_SERVICE_ACTIVE) { switch ((char)GSXData->deboardingState) {
double cargoDeboarded = GSXData->cargoDeboarded; case GSX_SERVICE_ACTIVE: {
if (UserData->isCargo) { // Exit if not boarded
fPayloadData_t localPayload = {}; if (GSXData->loadingState != LOADING_STATE_BOARDED) break;
memcpy(&localPayload, targetFPayloadData, sizeof(localPayload));
localPayload.stations.upper1 -= targetFPayloadData->stations.upper1 * (cargoDeboarded / 100); GSXData->loadingState = LOADING_STATE_DEBOARDING;
localPayload.stations.upper2 -= targetFPayloadData->stations.upper2 * (cargoDeboarded / 100);
localPayload.stations.upper3 -= targetFPayloadData->stations.upper3 * (cargoDeboarded / 100);
localPayload.stations.upper4 -= targetFPayloadData->stations.upper4 * (cargoDeboarded / 100);
localPayload.lowerForward -= targetFPayloadData->lowerForward * (cargoDeboarded / 100);
localPayload.lowerRear -= targetFPayloadData->lowerRear * (cargoDeboarded / 100);
generatePayload(&localPayload, UserData->isImperial); double cargoDeboarded = GSXData->cargoDeboarded;
load(&localPayload, simConnect, UserData->isImperial); if (UserData->isCargo) {
fPayloadData_t localPayload = {};
memcpy(&localPayload, targetFPayloadData, sizeof(localPayload));
localPayload.stations.upper1 -= targetFPayloadData->stations.upper1 * (cargoDeboarded / 100);
localPayload.stations.upper2 -= targetFPayloadData->stations.upper2 * (cargoDeboarded / 100);
localPayload.stations.upper3 -= targetFPayloadData->stations.upper3 * (cargoDeboarded / 100);
localPayload.stations.upper4 -= targetFPayloadData->stations.upper4 * (cargoDeboarded / 100);
localPayload.lowerForward -= targetFPayloadData->lowerForward * (cargoDeboarded / 100);
localPayload.lowerRear -= targetFPayloadData->lowerRear * (cargoDeboarded / 100);
generatePayload(&localPayload, UserData->isImperial);
load(&localPayload, simConnect, UserData->isImperial);
}
else {
double passengersDeboarded = GSXData->passengersDeboarded;
paxPayloadData_t localPayload = {};
memcpy(&localPayload, targetPaxPayloadData, sizeof(localPayload));
localPayload.paxCount.business1 -= min(targetPaxPayloadData->paxCount.business1, passengersDeboarded);
passengersDeboarded -= targetPaxPayloadData->paxCount.business1 - localPayload.paxCount.business1;
localPayload.paxCount.business2 -= min(targetPaxPayloadData->paxCount.business2, passengersDeboarded);
passengersDeboarded -= targetPaxPayloadData->paxCount.business2 - localPayload.paxCount.business2;
localPayload.paxCount.economy1 -= min(targetPaxPayloadData->paxCount.economy1, passengersDeboarded);
passengersDeboarded -= targetPaxPayloadData->paxCount.economy1 - localPayload.paxCount.economy1;
localPayload.paxCount.economy2 -= min(targetPaxPayloadData->paxCount.economy2, passengersDeboarded);
passengersDeboarded -= targetPaxPayloadData->paxCount.economy2 - localPayload.paxCount.economy2;
localPayload.forwardCargo -= targetPaxPayloadData->forwardCargo * (cargoDeboarded / 100);
localPayload.rearCargo -= targetPaxPayloadData->rearCargo * (cargoDeboarded / 100);
generatePayload(&localPayload, UserData->isImperial, UserOptions);
load(&localPayload, simConnect, UserData->isImperial);
}
break;
} }
else { case GSX_SERVICE_FINISHED: {
double passengersDeboarded = GSXData->passengersDeboarded; // Exit if not deboarding
paxPayloadData_t localPayload = {}; if (GSXData->loadingState != LOADING_STATE_DEBOARDING) break;
memcpy(&localPayload, targetPaxPayloadData, sizeof(localPayload));
localPayload.paxCount.business1 -= min(targetPaxPayloadData->paxCount.business1, passengersDeboarded); GSXData->loadingState = LOADING_STATE_DEBOARDED;
passengersDeboarded -= targetPaxPayloadData->paxCount.business1 - localPayload.paxCount.business1;
localPayload.paxCount.business2 -= min(targetPaxPayloadData->paxCount.business2, passengersDeboarded);
passengersDeboarded -= targetPaxPayloadData->paxCount.business2 - localPayload.paxCount.business2;
localPayload.paxCount.economy1 -= min(targetPaxPayloadData->paxCount.economy1, passengersDeboarded);
passengersDeboarded -= targetPaxPayloadData->paxCount.economy1 - localPayload.paxCount.economy1;
localPayload.paxCount.economy2 -= min(targetPaxPayloadData->paxCount.economy2, passengersDeboarded);
passengersDeboarded -= targetPaxPayloadData->paxCount.economy2 - localPayload.paxCount.economy2;
localPayload.forwardCargo -= targetPaxPayloadData->forwardCargo * (cargoDeboarded / 100);
localPayload.rearCargo -= targetPaxPayloadData->rearCargo * (cargoDeboarded / 100);
generatePayload(&localPayload, UserData->isImperial, UserOptions); if (UserData->isCargo) {
load(&localPayload, simConnect, UserData->isImperial); fPayloadData_t localPayload = {};
memcpy(&localPayload, targetFPayloadData, sizeof(localPayload));
localPayload.stations.upper1 = 0;
localPayload.stations.upper2 = 0;
localPayload.stations.upper3 = 0;
localPayload.stations.upper4 = 0;
localPayload.lowerForward = 0;
localPayload.lowerRear = 0;
generatePayload(&localPayload, UserData->isImperial);
load(&localPayload, simConnect, UserData->isImperial);
}
else {
paxPayloadData_t localPayload = {};
memcpy(&localPayload, targetPaxPayloadData, sizeof(localPayload));
localPayload.paxCount.business1 = 0;
localPayload.paxCount.business2 = 0;
localPayload.paxCount.economy1 = 0;
localPayload.paxCount.economy2 = 0;
localPayload.forwardCargo = 0;
localPayload.rearCargo = 0;
generatePayload(&localPayload, UserData->isImperial, UserOptions);
load(&localPayload, simConnect, UserData->isImperial);
}
break;
} }
} }
} }

View File

@ -32,7 +32,7 @@
/******************************** 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.1" #define VERSION_STRING "1.3"
// 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"

View File

@ -60,6 +60,7 @@
#define CG_TOLERANCE 0.05 #define CG_TOLERANCE 0.05
// GSX States // GSX States
#define GSX_SERVICE_ACTIVE 5 #define GSX_SERVICE_ACTIVE 5
#define GSX_SERVICE_FINISHED 6
/********************************* Macros **********************************/ /********************************* Macros **********************************/
// Conversions // Conversions
@ -87,6 +88,14 @@ enum DATA_REQUESTS {
DATA_REQUEST_USER_DATA, DATA_REQUEST_USER_DATA,
}; };
enum LOADING_STATES {
LOADING_STATE_IDLE,
LOADING_STATE_BOARDING,
LOADING_STATE_BOARDED,
LOADING_STATE_DEBOARDING,
LOADING_STATE_DEBOARDED,
};
/***************************** Data structures *****************************/ /***************************** Data structures *****************************/
typedef struct { typedef struct {
double isCargo; double isCargo;
@ -95,12 +104,17 @@ typedef struct {
} UserData_t; } UserData_t;
typedef struct { typedef struct {
// SimConnect mapped
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
enum LOADING_STATES loadingState;
} GSXData_t; } GSXData_t;
typedef struct { typedef struct {

View File

@ -5,6 +5,15 @@
} }
], ],
"settings": { "settings": {
"cSpell.words": ["deboarding", "khofmann", "tfdi", "TFDI", "TOCG", "ZFWCG"] "cSpell.words": [
"couatl",
"DEBOARDED",
"deboarding",
"khofmann",
"tfdi",
"TFDI",
"TOCG",
"ZFWCG"
]
} }
} }