From 6d1ef26ac1a125740a66dc9decd346a1dec8665b Mon Sep 17 00:00:00 2001 From: Spythere Date: Sun, 14 Sep 2025 15:10:48 +0200 Subject: [PATCH] chore: added a display of the timetable max speed in the active train info & tooltip --- src/components/Tooltip/TrainInfoTooltip.vue | 15 +++- src/components/TrainsView/TrainInfo.vue | 58 ++----------- src/mixins/trainInfoMixin.ts | 90 ++++++++++++--------- src/styles/_global.scss | 6 ++ 4 files changed, 78 insertions(+), 91 deletions(-) diff --git a/src/components/Tooltip/TrainInfoTooltip.vue b/src/components/Tooltip/TrainInfoTooltip.vue index ea40ed3..294bba0 100644 --- a/src/components/Tooltip/TrainInfoTooltip.vue +++ b/src/components/Tooltip/TrainInfoTooltip.vue @@ -9,6 +9,17 @@
{{ trainInfo.stockList[0] }} • {{ trainInfo.length }}m • {{ (trainInfo.mass / 1000).toFixed(2) }}t + + • vRJ: + {{ + trainInfo.timetableData?.trainMaxSpeed || + getStockSpeedLimit(trainInfo.stockList, trainInfo.mass) + }}km/h + + + • vMax: + {{ getStockSpeedLimit(trainInfo.stockList, trainInfo.mass) }}km/h +
@@ -46,9 +57,7 @@ export default defineComponent({ return this.mainStore.trainList.find((t) => t.id === this.tooltipStore.content); }, - lastSceneryStatus() { - - } + lastSceneryStatus() {} } }); diff --git a/src/components/TrainsView/TrainInfo.vue b/src/components/TrainsView/TrainInfo.vue index 55b0720..bca5787 100644 --- a/src/components/TrainsView/TrainInfo.vue +++ b/src/components/TrainsView/TrainInfo.vue @@ -135,7 +135,11 @@ speed icon {{ train.speed }} km/h - + + • vRJ: {{ train.timetableData.trainMaxSpeed }} km/h + + + { - const [vehicleName, vehicleCargo] = stockName.split(':'); - - const vehicleData = this.apiStore.vehiclesData?.find((v) => v.name == vehicleName); - - if (!vehicleData) return acc; - - let vehicleSpeed = vehicleData.group.speed; - - if (vehicleData.type == 'wagon-freight') { - isPassenger = false; - - if (vehicleCargo !== undefined && vehicleData.group.speedLoaded) { - vehicleSpeed = vehicleData.group.speedLoaded; - } - } - - return Math.min(vehicleSpeed, acc); - }, Infinity); - - // Check the head vehicle speed limit - const headLocoName = this.train.stockList[0]; - const headLocoVehicleData = this.apiStore.vehiclesData?.find((v) => v.name == headLocoName); - - // Omit speed check for head vehicle if there's no data for it - if (!headLocoName || !headLocoVehicleData || !headLocoVehicleData.group.massSpeeds) - return vehicleMaxSpeed; - - const massSpeeds = - headLocoVehicleData.group.massSpeeds[ - this.train.stockList.length == 1 ? 'none' : isPassenger ? 'passenger' : 'cargo' - ]; - - // Omit speed check if there's no data on mass speeds - if (!massSpeeds) return vehicleMaxSpeed; - - // 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) => this.train.mass >= Number(massKey) - ); - - const massMaxSpeed = massKey ? massSpeeds[massKey] : Infinity; - - return Math.min(massMaxSpeed, vehicleMaxSpeed); + return this.getStockSpeedLimit(this.train.stockList, this.train.mass); }, + journalRouteLocation() { return { path: '/journal/timetables', diff --git a/src/mixins/trainInfoMixin.ts b/src/mixins/trainInfoMixin.ts index ecaae14..bac9a93 100644 --- a/src/mixins/trainInfoMixin.ts +++ b/src/mixins/trainInfoMixin.ts @@ -1,45 +1,10 @@ import { defineComponent } from 'vue'; import { Train, TrainStop } from '../typings/common'; +import { useApiStore } from '../store/apiStore'; export default defineComponent({ data: () => ({ - STATS: { - main: [ - { - name: 'speed', - unit: 'km/h' - }, - { - name: 'length', - unit: 'm' - }, - { - name: 'mass', - unit: 't', - multiplier: 0.001 - } - ], - - position: [ - { - name: 'scenery', - prop: 'currentStationName' - }, - { - name: 'route', - prop: 'connectedTrack' - }, - { - name: 'signal', - prop: 'signal' - }, - { - name: 'distance', - prop: 'distance', - unit: 'm' - } - ] - } + apiStore: useApiStore() }), methods: { @@ -150,6 +115,57 @@ export default defineComponent({ if (distance < 1000) return `${distance}m`; return `${(distance / 1000).toPrecision(2)}km`; + }, + + getStockSpeedLimit(stockList: string[], trainMass: number) { + let isPassenger = true; + + // Check the whole consist speed limit + const vehicleMaxSpeed = stockList.reduce((acc, stockName, i) => { + const [vehicleName, vehicleCargo] = stockName.split(':'); + + const vehicleData = this.apiStore.vehiclesData?.find((v) => v.name == vehicleName); + + if (!vehicleData) return acc; + + let vehicleSpeed = vehicleData.group.speed; + + if (vehicleData.type == 'wagon-freight') { + isPassenger = false; + + if (vehicleCargo !== undefined && vehicleData.group.speedLoaded) { + vehicleSpeed = vehicleData.group.speedLoaded; + } + } + + return Math.min(vehicleSpeed, acc); + }, Infinity); + + // Check the head vehicle speed limit + const headLocoName = stockList[0]; + const headLocoVehicleData = this.apiStore.vehiclesData?.find((v) => v.name == headLocoName); + + // Omit speed check for head vehicle if there's no data for it + if (!headLocoName || !headLocoVehicleData || !headLocoVehicleData.group.massSpeeds) + return vehicleMaxSpeed; + + const massSpeeds = + headLocoVehicleData.group.massSpeeds[ + stockList.length == 1 ? 'none' : isPassenger ? 'passenger' : 'cargo' + ]; + + // Omit speed check if there's no data on mass speeds + if (!massSpeeds) return vehicleMaxSpeed; + + // 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) => trainMass >= Number(massKey)); + + const massMaxSpeed = massKey ? massSpeeds[massKey] : Infinity; + + return Math.min(massMaxSpeed, vehicleMaxSpeed); } } }); diff --git a/src/styles/_global.scss b/src/styles/_global.scss index a9a2d64..da5e6ac 100644 --- a/src/styles/_global.scss +++ b/src/styles/_global.scss @@ -225,6 +225,12 @@ ul { } } +.font { + &--italic { + font-style: italic; + } +} + button, a.a-button { cursor: pointer;