mirror of
https://github.com/Spythere/pojazdownik.git
synced 2026-05-03 11:45:34 +00:00
162 lines
4.9 KiB
TypeScript
162 lines
4.9 KiB
TypeScript
import { EVehicleUseType } from '../enums/EVehicleUseType';
|
|
import { ICarWagon, ILocomotive, IStore, TStockInfoKey } from '../types';
|
|
import { LocoType, calculateSpeedLimit } from './speedLimitUtils';
|
|
|
|
export function isLocomotive(vehicle: ILocomotive | ICarWagon): vehicle is ILocomotive {
|
|
return (vehicle as ILocomotive).power !== undefined;
|
|
}
|
|
|
|
export function locoDataList(state: IStore) {
|
|
if (!state.stockData) return [];
|
|
|
|
const stockData = state.stockData;
|
|
|
|
return Object.keys(stockData.info).reduce((acc, vehiclePower) => {
|
|
if (!vehiclePower.startsWith('loco')) return acc;
|
|
|
|
const locoVehiclesData = stockData.info[vehiclePower as 'loco-e' | 'loco-s' | 'loco-ezt' | 'loco-szt'];
|
|
|
|
locoVehiclesData.forEach((loco) => {
|
|
if (state.showSupporter && !loco[4]) return;
|
|
|
|
const [type, constructionType, cabinType, maxSpeed, supportersOnly] = loco;
|
|
const locoProps = stockData.props.find((prop) => constructionType == prop.type);
|
|
|
|
acc.push({
|
|
power: vehiclePower,
|
|
type,
|
|
constructionType,
|
|
cabinType,
|
|
maxSpeed: Number(maxSpeed),
|
|
supportersOnly,
|
|
imageSrc: '',
|
|
|
|
length: locoProps?.length && type.startsWith('2EN') ? locoProps.length * 2 : locoProps?.length || 0,
|
|
mass: locoProps?.mass && type.startsWith('2EN') ? 253 : locoProps?.mass || 0,
|
|
});
|
|
});
|
|
|
|
return acc;
|
|
}, [] as ILocomotive[]);
|
|
}
|
|
|
|
export function carDataList(state: IStore) {
|
|
if (!state.stockData) return [];
|
|
|
|
const stockData = state.stockData;
|
|
|
|
return Object.keys(stockData.info).reduce((acc, vehicleUseType) => {
|
|
if (!vehicleUseType.startsWith('car')) return acc;
|
|
|
|
const carVehiclesData = stockData.info[vehicleUseType as 'car-passenger' | 'car-cargo'];
|
|
|
|
carVehiclesData.forEach((car) => {
|
|
if (state.showSupporter && !car[3]) return;
|
|
|
|
const carPropsData = stockData.props.find((v) => car[0].toString().startsWith(v.type));
|
|
|
|
acc.push({
|
|
useType: vehicleUseType as 'car-passenger' | 'car-cargo',
|
|
type: car[0],
|
|
constructionType: car[1],
|
|
loadable: car[2],
|
|
supportersOnly: car[3],
|
|
maxSpeed: Number(car[4]),
|
|
imageSrc: '',
|
|
cargoList:
|
|
!carPropsData || carPropsData.cargo === null
|
|
? []
|
|
: carPropsData.cargo.split(';').map((cargo) => ({
|
|
id: cargo.split(':')[0],
|
|
totalMass: Number(cargo.split(':')[1]),
|
|
})),
|
|
|
|
mass: carPropsData?.mass || 0,
|
|
length: carPropsData?.length || 0,
|
|
});
|
|
});
|
|
|
|
return acc;
|
|
}, [] as ICarWagon[]);
|
|
}
|
|
|
|
export function totalMass(state: IStore) {
|
|
return ~~state.stockList.reduce(
|
|
(acc, stock) => acc + (stock.cargo ? stock.cargo.totalMass : stock.mass) * stock.count,
|
|
0
|
|
);
|
|
}
|
|
|
|
export function totalLength(state: IStore) {
|
|
return state.stockList.reduce((acc, stock) => acc + stock.length * stock.count, 0);
|
|
}
|
|
|
|
export function maxStockSpeed(state: IStore) {
|
|
const stockSpeedLimit = state.stockList.reduce(
|
|
(acc, stock) => (stock.maxSpeed < acc || acc == 0 ? stock.maxSpeed : acc),
|
|
0
|
|
);
|
|
const headingLoco = state.stockList[0]?.isLoco ? state.stockList[0] : undefined;
|
|
|
|
if (!headingLoco) return stockSpeedLimit;
|
|
|
|
const locoType = headingLoco.type.split('-')[0];
|
|
|
|
if (/^(EN|2EN|SN)/.test(locoType)) return stockSpeedLimit;
|
|
|
|
const stockMass = totalMass(state);
|
|
|
|
const speedLimitByMass = calculateSpeedLimit(locoType as LocoType, stockMass, isTrainPassenger(state));
|
|
|
|
return speedLimitByMass ? Math.min(stockSpeedLimit, speedLimitByMass) : stockSpeedLimit;
|
|
}
|
|
|
|
export function acceptableMass(state: IStore) {
|
|
if (state.stockList.length == 0 || !state.stockList[0].isLoco) return 0;
|
|
const activeLocomotiveType = state.stockList[0].type;
|
|
|
|
if (/^SM/.test(activeLocomotiveType)) return 2400;
|
|
|
|
// Elektryczne EU07 / EP07 / EP08 / ET41
|
|
|
|
// Pasażerski elektr.
|
|
if (isTrainPassenger(state)) {
|
|
if (/^(EU|EP)/.test(activeLocomotiveType)) return 650;
|
|
if (/^ET/.test(activeLocomotiveType)) return 700;
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Towarowy / inny elektr.
|
|
if (/^EU/.test(activeLocomotiveType)) return 2000;
|
|
if (/^ET/.test(activeLocomotiveType)) return 4000;
|
|
if (/^EP/.test(activeLocomotiveType)) return 650;
|
|
|
|
return 0;
|
|
}
|
|
|
|
export function isTrainPassenger(state: IStore) {
|
|
if (state.stockList.length == 0) return false;
|
|
if (state.stockList.every((stock) => stock.isLoco)) return false;
|
|
|
|
return state.stockList
|
|
.filter((stock) => !stock.isLoco)
|
|
.every((stock) => stock.useType === EVehicleUseType.CAR_PASSENGER);
|
|
}
|
|
|
|
export function chosenRealStock(state: IStore) {
|
|
const currentStockString = state.stockList
|
|
.reduce((acc, stock) => {
|
|
for (let i = 0; i < stock.count; i++) acc.push(stock.type);
|
|
return acc;
|
|
}, [] as string[])
|
|
.join(';');
|
|
|
|
const realStockObj = state.readyStockList.find((readyStock) => readyStock.stockString == currentStockString);
|
|
|
|
state.chosenRealStockName = realStockObj?.stockId ?? undefined;
|
|
|
|
return realStockObj;
|
|
}
|
|
|