mirror of
https://github.com/Spythere/pojazdownik.git
synced 2026-05-03 05:18:10 +00:00
refactor: calculating stock speed limit
This commit is contained in:
@@ -2,10 +2,7 @@
|
||||
<div class="stock-specs">
|
||||
<div v-if="store.chosenStorageStockName || chosenRealComposition">
|
||||
<b v-if="store.chosenStorageStockName">
|
||||
<span
|
||||
class="text--accent"
|
||||
:title="store.chosenStorageStockName.length > 41 ? store.chosenStorageStockName : ''"
|
||||
>
|
||||
<span class="text--accent" :title="store.chosenStorageStockName.length > 41 ? store.chosenStorageStockName : ''">
|
||||
<BookmarkCheck :size="19" />
|
||||
{{ store.chosenStorageStockName.slice(0, 40) }}
|
||||
{{ store.chosenStorageStockName.length > 41 ? '...' : '' }}
|
||||
@@ -16,11 +13,7 @@
|
||||
|
||||
<b class="real-stock-info" v-if="chosenRealComposition">
|
||||
<span class="text--accent">
|
||||
<img
|
||||
class="real-stock-icon"
|
||||
:src="getIconURL(chosenRealComposition.type)"
|
||||
:alt="chosenRealComposition.type"
|
||||
/>
|
||||
<img class="real-stock-icon" :src="getIconURL(chosenRealComposition.type)" :alt="chosenRealComposition.type" />
|
||||
{{ chosenRealComposition.number }} {{ chosenRealComposition.name }}
|
||||
</span>
|
||||
</b>
|
||||
@@ -30,14 +23,11 @@
|
||||
{{ $t('stocklist.mass') }}
|
||||
<span class="text--accent">{{ (store.totalWeight / 1000).toFixed(1) }}t</span>
|
||||
({{ $t('stocklist.mass-accepted') }}:
|
||||
<span class="text--accent">{{
|
||||
store.acceptableWeight ? `${~~(store.acceptableWeight / 1000)}t` : '-'
|
||||
}}</span
|
||||
<span class="text--accent">{{ store.acceptableWeight ? `${~~(store.acceptableWeight / 1000)}t` : '-' }}</span
|
||||
>) - {{ $t('stocklist.length') }}:
|
||||
<span class="text--accent">{{ store.totalLength }}m</span>
|
||||
- {{ $t('stocklist.vmax') }}
|
||||
<span tabindex="0" :data-tooltip="$t('stocklist.disclaimer')">(?)</span>:
|
||||
<span class="text--accent">{{ store.maxStockSpeed }} km/h</span>
|
||||
- {{ $t('stocklist.vmax') }} <span tabindex="0" :data-tooltip="$t('stocklist.disclaimer')">(?)</span>:
|
||||
<span class="text--accent">{{ isFinite(store.maxStockSpeed) ? store.maxStockSpeed : '--' }} km/h</span>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
{
|
||||
"EU07": {
|
||||
"passenger": {
|
||||
"650000": 125
|
||||
},
|
||||
"cargo": {
|
||||
"2000000": 70
|
||||
},
|
||||
"none": 110
|
||||
},
|
||||
"4E": {
|
||||
"passenger": {
|
||||
"650000": 125
|
||||
},
|
||||
"cargo": {
|
||||
"2000000": 70
|
||||
},
|
||||
"none": 110
|
||||
},
|
||||
"EU07E": {
|
||||
"passenger": {
|
||||
"650000": 125
|
||||
},
|
||||
"cargo": {
|
||||
"2000000": 70
|
||||
},
|
||||
"none": 110
|
||||
},
|
||||
"EP07": {
|
||||
"passenger": {
|
||||
"650000": 125
|
||||
},
|
||||
"cargo": null,
|
||||
"none": 110
|
||||
},
|
||||
"EP08": {
|
||||
"passenger": {
|
||||
"650000": 140
|
||||
},
|
||||
"cargo": null,
|
||||
"none": 110
|
||||
},
|
||||
"EP09": {
|
||||
"passenger": {
|
||||
"650000": 160
|
||||
},
|
||||
"cargo": null,
|
||||
"none": 160
|
||||
},
|
||||
"ET22": {
|
||||
"passenger": {
|
||||
"650000": 125
|
||||
},
|
||||
"cargo": {
|
||||
"1200000": 100,
|
||||
"3100000": 70
|
||||
},
|
||||
"none": 125
|
||||
},
|
||||
"201E": {
|
||||
"passenger": {
|
||||
"650000": 125
|
||||
},
|
||||
"cargo": {
|
||||
"1200000": 100,
|
||||
"3100000": 70
|
||||
},
|
||||
"none": 125
|
||||
},
|
||||
"ET41": {
|
||||
"passenger": {
|
||||
"700000": 125
|
||||
},
|
||||
"cargo": {
|
||||
"4000000": 70
|
||||
},
|
||||
"none": 110
|
||||
},
|
||||
"SM42": {
|
||||
"passenger": {
|
||||
"95000": 90,
|
||||
"200000": 80,
|
||||
"300000": 70,
|
||||
"450000": 60,
|
||||
"750000": 50,
|
||||
"1130000": 40,
|
||||
"1720000": 30,
|
||||
"2400000": 20
|
||||
},
|
||||
"cargo": {
|
||||
"95000": 90,
|
||||
"200000": 80,
|
||||
"300000": 70,
|
||||
"450000": 60,
|
||||
"750000": 50,
|
||||
"1130000": 40,
|
||||
"1720000": 30,
|
||||
"2400000": 20
|
||||
},
|
||||
"none": 90
|
||||
},
|
||||
"M62": {
|
||||
"passenger": {
|
||||
"500000": 100,
|
||||
"800000": 80,
|
||||
"1200000": 60,
|
||||
"2000000": 40,
|
||||
"3000000": 20
|
||||
},
|
||||
"cargo": {
|
||||
"500000": 100,
|
||||
"800000": 80,
|
||||
"1200000": 60,
|
||||
"2000000": 40,
|
||||
"3000000": 20
|
||||
},
|
||||
"none": 100
|
||||
},
|
||||
"ST44": {
|
||||
"passenger": {
|
||||
"500000": 100,
|
||||
"800000": 80,
|
||||
"1200000": 60,
|
||||
"2000000": 40,
|
||||
"3000000": 20
|
||||
},
|
||||
"cargo": {
|
||||
"500000": 100,
|
||||
"800000": 80,
|
||||
"1200000": 60,
|
||||
"2000000": 40,
|
||||
"3000000": 20
|
||||
},
|
||||
"none": 100
|
||||
},
|
||||
"CTLR4C": {
|
||||
"passenger": {
|
||||
"500000": 100,
|
||||
"800000": 80,
|
||||
"1200000": 60,
|
||||
"2000000": 40,
|
||||
"3000000": 20
|
||||
},
|
||||
"cargo": {
|
||||
"500000": 100,
|
||||
"800000": 80,
|
||||
"1200000": 60,
|
||||
"2000000": 40,
|
||||
"3000000": 20
|
||||
},
|
||||
"none": 100
|
||||
}
|
||||
}
|
||||
+1
-3
@@ -25,13 +25,11 @@ import {
|
||||
totalWeight,
|
||||
} from './utils/vehicleUtils';
|
||||
|
||||
import i18n from './i18n-setup';
|
||||
import http from './http';
|
||||
|
||||
import realCompositionsJSON from './data/realCompositions.json';
|
||||
|
||||
export const useStore = defineStore({
|
||||
id: 'store',
|
||||
export const useStore = defineStore('store', {
|
||||
state: () => ({
|
||||
chosenCar: null as ICarWagon | null,
|
||||
chosenLoco: null as ILocomotive | null,
|
||||
|
||||
@@ -28,12 +28,14 @@ export interface ILocomotive {
|
||||
constructionType: string;
|
||||
cabinType: string;
|
||||
maxSpeed: number;
|
||||
maxSpeedLoco: number;
|
||||
weight: number;
|
||||
length: number;
|
||||
coldStart: boolean;
|
||||
doubleManned: boolean;
|
||||
sponsorOnlyTimestamp: number;
|
||||
teamOnly: boolean;
|
||||
massSpeeds: VehicleGroupMassSpeeds | null;
|
||||
}
|
||||
|
||||
export interface ICarWagon {
|
||||
@@ -42,11 +44,13 @@ export interface ICarWagon {
|
||||
constructionType: string;
|
||||
loadable: boolean;
|
||||
maxSpeed: number;
|
||||
maxSpeedLoaded: number;
|
||||
weight: number;
|
||||
length: number;
|
||||
cargoTypes: ICargo[];
|
||||
sponsorOnlyTimestamp: number;
|
||||
teamOnly: boolean;
|
||||
massSpeeds: VehicleGroupMassSpeeds | null;
|
||||
}
|
||||
|
||||
export interface IStock {
|
||||
@@ -83,10 +87,13 @@ export interface IVehicleGroup {
|
||||
id: number;
|
||||
name: string;
|
||||
speed: number;
|
||||
speedLoaded?: number;
|
||||
speedLoco?: number;
|
||||
length: number;
|
||||
weight: number;
|
||||
cargoTypes: IVehicleCargoType[] | null;
|
||||
locoProps: IVehicleLocoProps | null;
|
||||
massSpeeds: VehicleGroupMassSpeeds | null;
|
||||
}
|
||||
|
||||
export interface IVehicleCargoType {
|
||||
@@ -99,9 +106,15 @@ export interface IVehicleLocoProps {
|
||||
doubleManned: boolean;
|
||||
}
|
||||
|
||||
export interface VehicleGroupMassSpeeds {
|
||||
passenger: Record<string, number> | null;
|
||||
cargo: Record<string, number> | null;
|
||||
none: number | null;
|
||||
}
|
||||
|
||||
export interface StorageStockEntry {
|
||||
id: string;
|
||||
createdAt: number;
|
||||
updatedAt?: number;
|
||||
stockString: string;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +1,47 @@
|
||||
import speedLimits from '../constants/speedLimits.json';
|
||||
import massLimits from '../constants/massLimits.json';
|
||||
import { IStock } from '../types/common.types';
|
||||
|
||||
export type SpeedLimitLocoType = keyof typeof speedLimits;
|
||||
export type MassLimitLocoType = keyof typeof massLimits;
|
||||
|
||||
export function calculateSpeedLimit(
|
||||
locoType: SpeedLimitLocoType,
|
||||
stockTotalWeight: number,
|
||||
stockCount: number,
|
||||
isTrainPassenger: boolean
|
||||
) {
|
||||
if (speedLimits[locoType] === undefined) return 0;
|
||||
export function calculateSpeedLimit(stockList: IStock[], isPassenger: boolean, stockMass: number) {
|
||||
// Check the whole consist speed limit
|
||||
const stockMaxSpeed = stockList.reduce((acc, vehicle, i) => {
|
||||
let vehicleSpeed = vehicle.vehicleRef.maxSpeed;
|
||||
|
||||
if (stockCount == 1) return speedLimits[locoType]['none'];
|
||||
if (
|
||||
vehicle.vehicleRef.group == 'wagon-freight' &&
|
||||
vehicle.cargo !== undefined &&
|
||||
vehicle.vehicleRef.maxSpeedLoaded
|
||||
) {
|
||||
vehicleSpeed = vehicle.vehicleRef.maxSpeedLoaded;
|
||||
}
|
||||
|
||||
const stockType = isTrainPassenger ? 'passenger' : 'cargo';
|
||||
const speedTable = speedLimits[locoType][stockType];
|
||||
return Math.min(vehicleSpeed, acc);
|
||||
}, Infinity);
|
||||
|
||||
if (!speedTable) return undefined;
|
||||
// Check the head vehicle speed limit
|
||||
const headVehicle = stockList[0];
|
||||
|
||||
let speedLimit = 0;
|
||||
for (const mass in speedTable)
|
||||
if (stockTotalWeight > Number(mass)) speedLimit = (speedTable as any)[mass];
|
||||
// Omit speed check for head vehicle if there's no data for it
|
||||
if (!headVehicle || !headVehicle.vehicleRef.massSpeeds) return stockMaxSpeed;
|
||||
|
||||
return speedLimit;
|
||||
const massSpeeds =
|
||||
headVehicle.vehicleRef.massSpeeds[
|
||||
stockList.length == 1 ? 'none' : isPassenger ? 'passenger' : 'cargo'
|
||||
];
|
||||
|
||||
// Omit speed check if there's no data on mass speeds
|
||||
if (!massSpeeds) return stockMaxSpeed;
|
||||
|
||||
// Number type for locomotives alone
|
||||
if (typeof massSpeeds === 'number') return massSpeeds;
|
||||
|
||||
// Record type for passenger or cargo, find the closest range
|
||||
const massKey = Object.keys(massSpeeds).findLast((massKey) => stockMass >= Number(massKey));
|
||||
|
||||
const massMaxSpeed = massKey ? massSpeeds[massKey] : Infinity;
|
||||
|
||||
return Math.min(massMaxSpeed, stockMaxSpeed);
|
||||
}
|
||||
|
||||
export function calculateMassLimit(locoType: MassLimitLocoType, isTrainPassenger: boolean) {
|
||||
|
||||
@@ -35,11 +35,14 @@ export function locoDataList(vehiclesData: IVehicleData[] | undefined) {
|
||||
teamOnly: data.restrictions?.teamOnly ?? false,
|
||||
|
||||
maxSpeed: data.group.speed,
|
||||
maxSpeedLoco: data.group.speedLoco ?? data.group.speed,
|
||||
length: data.group.length,
|
||||
weight: data.group.weight,
|
||||
|
||||
coldStart: data.group.locoProps?.coldStart ?? false,
|
||||
doubleManned: data.group.locoProps?.doubleManned ?? false,
|
||||
|
||||
massSpeeds: data.group.massSpeeds,
|
||||
});
|
||||
|
||||
return acc;
|
||||
@@ -63,8 +66,12 @@ export function carDataList(vehiclesData: IVehicleData[] | undefined) {
|
||||
teamOnly: data.restrictions?.teamOnly ?? false,
|
||||
|
||||
maxSpeed: data.group.speed,
|
||||
maxSpeedLoaded: data.group.speedLoaded ?? data.group.speed,
|
||||
|
||||
length: data.group.length,
|
||||
weight: data.group.weight,
|
||||
|
||||
massSpeeds: data.group.massSpeeds,
|
||||
});
|
||||
|
||||
return acc;
|
||||
@@ -83,27 +90,7 @@ export function totalLength(stockList: IStock[]) {
|
||||
}
|
||||
|
||||
export function maxStockSpeed(stockList: IStock[]) {
|
||||
const stockSpeedLimit = stockList.reduce(
|
||||
(acc, stock) => (stock.vehicleRef.maxSpeed < acc || acc == 0 ? stock.vehicleRef.maxSpeed : acc),
|
||||
0
|
||||
);
|
||||
const headingLoco =
|
||||
stockList[0] && isTractionUnit(stockList[0].vehicleRef) ? stockList[0] : undefined;
|
||||
|
||||
if (!headingLoco) return stockSpeedLimit;
|
||||
|
||||
const locoType = headingLoco.vehicleRef.type.split('-')[0];
|
||||
|
||||
if (/^(EN|2EN|SN)/.test(locoType)) return stockSpeedLimit;
|
||||
|
||||
const speedLimitByMass = calculateSpeedLimit(
|
||||
locoType as SpeedLimitLocoType,
|
||||
totalWeight(stockList),
|
||||
stockList.length,
|
||||
isTrainPassenger(stockList)
|
||||
);
|
||||
|
||||
return speedLimitByMass ? Math.min(stockSpeedLimit, speedLimitByMass) : stockSpeedLimit;
|
||||
return calculateSpeedLimit(stockList, isTrainPassenger(stockList), totalWeight(stockList));
|
||||
}
|
||||
|
||||
export function acceptableWeight(stockList: IStock[]) {
|
||||
|
||||
Reference in New Issue
Block a user